trunk/src/mame/video/chihiro.c
| r242571 | r242572 | |
| 1213 | 1213 | } |
| 1214 | 1214 | } |
| 1215 | 1215 | |
| 1216 | | void nv2a_renderer::write_pixel(int x, int y, UINT32 color) |
| 1216 | void nv2a_renderer::write_pixel(int x, int y, UINT32 color, UINT32 depth) |
| 1217 | 1217 | { |
| 1218 | | void *addr; |
| 1219 | | UINT32 fbcolor; |
| 1218 | UINT32 *addr, *daddr; |
| 1219 | UINT32 fbcolor, deptsten; |
| 1220 | 1220 | UINT32 c[4], fb[4], s[4], d[4], cc[4]; |
| 1221 | UINT32 dep, sten, stenc, stenv; |
| 1222 | bool stencil_passed; |
| 1223 | bool depth_passed; |
| 1221 | 1224 | |
| 1222 | | addr = this->fb.raw_pixptr(y, x); |
| 1223 | | fbcolor = *((UINT32 *)addr); |
| 1225 | addr=rendertarget + (pitch_rendertarget / 4)*y + x; |
| 1226 | fbcolor = *addr; |
| 1227 | daddr=depthbuffer + (pitch_depthbuffer / 4)*y + x; |
| 1228 | deptsten = *daddr; |
| 1224 | 1229 | c[3] = color >> 24; |
| 1225 | 1230 | c[2] = (color >> 16) & 255; |
| 1226 | 1231 | c[1] = (color >> 8) & 255; |
| r242571 | r242572 | |
| 1233 | 1238 | cc[2] = (blend_color >> 16) & 255; |
| 1234 | 1239 | cc[1] = (blend_color >> 8) & 255; |
| 1235 | 1240 | cc[0] = blend_color & 255; |
| 1241 | dep = deptsten >> 8; |
| 1242 | sten = deptsten & 255; |
| 1243 | if (depth > 0xffffff) |
| 1244 | depth = 0xffffff; |
| 1245 | if (depth & 0x80000000) |
| 1246 | depth = 0; |
| 1236 | 1247 | // ownership test and scissor test not done |
| 1237 | 1248 | // alpha test |
| 1238 | 1249 | if (alpha_test_enabled) { |
| 1239 | 1250 | switch (alpha_func) { |
| 1251 | case nv2a_renderer::NEVER: |
| 1252 | return; |
| 1253 | case nv2a_renderer::ALWAYS: |
| 1254 | default: |
| 1255 | break; |
| 1256 | case nv2a_renderer::LESS: |
| 1257 | if (c[3] >= alpha_reference) |
| 1258 | return; |
| 1259 | break; |
| 1260 | case nv2a_renderer::LEQUAL: |
| 1261 | if (c[3] > alpha_reference) |
| 1262 | return; |
| 1263 | break; |
| 1264 | case nv2a_renderer::EQUAL: |
| 1265 | if (c[3] != alpha_reference) |
| 1266 | return; |
| 1267 | break; |
| 1268 | case nv2a_renderer::GEQUAL: |
| 1269 | if (c[3] < alpha_reference) |
| 1270 | return; |
| 1271 | break; |
| 1272 | case nv2a_renderer::GREATER: |
| 1273 | if (c[3] <= alpha_reference) |
| 1274 | return; |
| 1275 | break; |
| 1276 | case nv2a_renderer::NOTEQUAL: |
| 1277 | if (c[3] == alpha_reference) |
| 1278 | return; |
| 1279 | break; |
| 1280 | } |
| 1281 | } |
| 1282 | // stencil test |
| 1283 | stencil_passed = true; |
| 1284 | if (stencil_test_enabled) { |
| 1285 | stenc=stencil_mask & stencil_ref; |
| 1286 | stenv=stencil_mask & sten; |
| 1287 | switch (stencil_func) { |
| 1240 | 1288 | case nv2a_renderer::NEVER: |
| 1241 | | return; |
| 1242 | | case nv2a_renderer::ALWAYS: |
| 1243 | | default: |
| 1289 | stencil_passed = false; |
| 1244 | 1290 | break; |
| 1245 | 1291 | case nv2a_renderer::LESS: |
| 1246 | | if (c[3] >= alpha_reference) |
| 1247 | | return; |
| 1292 | if (stenc >= stenv) |
| 1293 | stencil_passed = false; |
| 1248 | 1294 | break; |
| 1249 | | case nv2a_renderer::LEQUAL: |
| 1250 | | if (c[3] > alpha_reference) |
| 1251 | | return; |
| 1252 | | break; |
| 1253 | 1295 | case nv2a_renderer::EQUAL: |
| 1254 | | if (c[3] != alpha_reference) |
| 1255 | | return; |
| 1296 | if (stenc != stenv) |
| 1297 | stencil_passed = false; |
| 1256 | 1298 | break; |
| 1257 | | case nv2a_renderer::GEQUAL: |
| 1258 | | if (c[3] < alpha_reference) |
| 1259 | | return; |
| 1299 | case nv2a_renderer::LEQUAL: |
| 1300 | if (stenc > stenv) |
| 1301 | stencil_passed = false; |
| 1260 | 1302 | break; |
| 1261 | 1303 | case nv2a_renderer::GREATER: |
| 1262 | | if (c[3] <= alpha_reference) |
| 1263 | | return; |
| 1304 | if (stenc <= stenv) |
| 1305 | stencil_passed = false; |
| 1264 | 1306 | break; |
| 1265 | 1307 | case nv2a_renderer::NOTEQUAL: |
| 1266 | | if (c[3] == alpha_reference) |
| 1267 | | return; |
| 1308 | if (stenc == stenv) |
| 1309 | stencil_passed = false; |
| 1268 | 1310 | break; |
| 1269 | | } |
| 1270 | | } |
| 1271 | | // stencil test not done |
| 1272 | | // depth buffer test not done |
| 1273 | | // blending |
| 1274 | | if (blending_enabled) { |
| 1275 | | switch (blend_function_source) { |
| 1276 | | case nv2a_renderer::ZERO: |
| 1277 | | s[3] = s[2] = s[1] = s[0] = 0; |
| 1311 | case nv2a_renderer::GEQUAL: |
| 1312 | if (stenc < stenv) |
| 1313 | stencil_passed = false; |
| 1278 | 1314 | break; |
| 1279 | | case nv2a_renderer::ONE: |
| 1315 | case nv2a_renderer::ALWAYS: |
| 1280 | 1316 | default: |
| 1281 | | s[3] = s[2] = s[1] = s[0] = 255; |
| 1282 | 1317 | break; |
| 1283 | | case nv2a_renderer::DST_COLOR: |
| 1284 | | s[3] = fb[3]; |
| 1285 | | s[2] = fb[2]; |
| 1286 | | s[1] = fb[1]; |
| 1287 | | s[0] = fb[0]; |
| 1318 | } |
| 1319 | if (stencil_passed == false) { |
| 1320 | switch (stencil_op_fail) { |
| 1321 | case nv2a_renderer::ZEROOP: |
| 1322 | sten = 0; |
| 1323 | break; |
| 1324 | case nv2a_renderer::INVERTOP: |
| 1325 | sten = sten ^ 255; |
| 1326 | break; |
| 1327 | case nv2a_renderer::KEEP: |
| 1328 | default: |
| 1329 | break; |
| 1330 | case nv2a_renderer::REPLACE: |
| 1331 | sten = stencil_ref; |
| 1332 | break; |
| 1333 | case nv2a_renderer::INCR: |
| 1334 | if (sten < 255) |
| 1335 | sten++; |
| 1336 | break; |
| 1337 | case nv2a_renderer::DECR: |
| 1338 | if (sten > 0) |
| 1339 | sten--; |
| 1340 | break; |
| 1341 | case nv2a_renderer::INCR_WRAP: |
| 1342 | if (sten < 255) |
| 1343 | sten++; |
| 1344 | else |
| 1345 | sten = 0; |
| 1346 | break; |
| 1347 | case nv2a_renderer::DECR_WRAP: |
| 1348 | if (sten > 0) |
| 1349 | sten--; |
| 1350 | else |
| 1351 | sten = 255; |
| 1352 | break; |
| 1353 | } |
| 1354 | deptsten = (dep << 8) | sten; |
| 1355 | *daddr = deptsten; |
| 1356 | return; |
| 1357 | } |
| 1358 | } |
| 1359 | // depth buffer test |
| 1360 | depth_passed = true; |
| 1361 | if (depth_test_enabled) { |
| 1362 | switch (depth_function) { |
| 1363 | case nv2a_renderer::NEVER: |
| 1364 | depth_passed = false; |
| 1365 | break; |
| 1366 | case nv2a_renderer::LESS: |
| 1367 | if (depth >= dep) |
| 1368 | depth_passed = false; |
| 1369 | break; |
| 1370 | case nv2a_renderer::EQUAL: |
| 1371 | if (depth != dep) |
| 1372 | depth_passed = false; |
| 1373 | break; |
| 1374 | case nv2a_renderer::LEQUAL: |
| 1375 | if (depth > dep) |
| 1376 | depth_passed = false; |
| 1377 | break; |
| 1378 | case nv2a_renderer::GREATER: |
| 1379 | if (depth <= dep) |
| 1380 | depth_passed = false; |
| 1381 | break; |
| 1382 | case nv2a_renderer::NOTEQUAL: |
| 1383 | if (depth == dep) |
| 1384 | depth_passed = false; |
| 1385 | break; |
| 1386 | case nv2a_renderer::GEQUAL: |
| 1387 | if (depth < dep) |
| 1388 | depth_passed = false; |
| 1389 | break; |
| 1390 | case nv2a_renderer::ALWAYS: |
| 1391 | default: |
| 1392 | break; |
| 1393 | } |
| 1394 | if (depth_passed == false) { |
| 1395 | switch (stencil_op_zfail) { |
| 1396 | case nv2a_renderer::ZEROOP: |
| 1397 | sten = 0; |
| 1398 | break; |
| 1399 | case nv2a_renderer::INVERTOP: |
| 1400 | sten = sten ^ 255; |
| 1401 | break; |
| 1402 | case nv2a_renderer::KEEP: |
| 1403 | default: |
| 1404 | break; |
| 1405 | case nv2a_renderer::REPLACE: |
| 1406 | sten = stencil_ref; |
| 1407 | break; |
| 1408 | case nv2a_renderer::INCR: |
| 1409 | if (sten < 255) |
| 1410 | sten++; |
| 1411 | break; |
| 1412 | case nv2a_renderer::DECR: |
| 1413 | if (sten > 0) |
| 1414 | sten--; |
| 1415 | break; |
| 1416 | case nv2a_renderer::INCR_WRAP: |
| 1417 | if (sten < 255) |
| 1418 | sten++; |
| 1419 | else |
| 1420 | sten = 0; |
| 1421 | break; |
| 1422 | case nv2a_renderer::DECR_WRAP: |
| 1423 | if (sten > 0) |
| 1424 | sten--; |
| 1425 | else |
| 1426 | sten = 255; |
| 1427 | break; |
| 1428 | } |
| 1429 | deptsten = (dep << 8) | sten; |
| 1430 | *daddr = deptsten; |
| 1431 | return; |
| 1432 | } |
| 1433 | switch (stencil_op_zpass) { |
| 1434 | case nv2a_renderer::ZEROOP: |
| 1435 | sten = 0; |
| 1288 | 1436 | break; |
| 1289 | | case nv2a_renderer::ONE_MINUS_DST_COLOR: |
| 1290 | | s[3] = fb[3] ^ 255; |
| 1291 | | s[2] = fb[2] ^ 255; |
| 1292 | | s[1] = fb[1] ^ 255; |
| 1293 | | s[0] = fb[0] ^ 255; |
| 1437 | case nv2a_renderer::INVERTOP: |
| 1438 | sten = sten ^ 255; |
| 1294 | 1439 | break; |
| 1295 | | case nv2a_renderer::SRC_ALPHA: |
| 1296 | | s[3] = s[2] = s[1] = s[0] = c[3]; |
| 1440 | case nv2a_renderer::KEEP: |
| 1441 | default: |
| 1297 | 1442 | break; |
| 1298 | | case nv2a_renderer::ONE_MINUS_SRC_ALPHA: |
| 1299 | | s[3] = s[2] = s[1] = s[0] = c[3] ^ 255; |
| 1443 | case nv2a_renderer::REPLACE: |
| 1444 | sten = stencil_ref; |
| 1300 | 1445 | break; |
| 1301 | | case nv2a_renderer::DST_ALPHA: |
| 1302 | | s[3] = s[2] = s[1] = s[0] = fb[3]; |
| 1446 | case nv2a_renderer::INCR: |
| 1447 | if (sten < 255) |
| 1448 | sten++; |
| 1303 | 1449 | break; |
| 1304 | | case nv2a_renderer::ONE_MINUS_DST_ALPHA: |
| 1305 | | s[3] = s[2] = s[1] = s[0] = fb[3] ^ 255; |
| 1450 | case nv2a_renderer::DECR: |
| 1451 | if (sten > 0) |
| 1452 | sten--; |
| 1306 | 1453 | break; |
| 1307 | | case nv2a_renderer::CONSTANT_COLOR: |
| 1308 | | s[3] = cc[3]; |
| 1309 | | s[2] = cc[2]; |
| 1310 | | s[1] = cc[1]; |
| 1311 | | s[0] = cc[0]; |
| 1454 | case nv2a_renderer::INCR_WRAP: |
| 1455 | if (sten < 255) |
| 1456 | sten++; |
| 1457 | else |
| 1458 | sten = 0; |
| 1312 | 1459 | break; |
| 1313 | | case nv2a_renderer::ONE_MINUS_CONSTANT_COLOR: |
| 1314 | | s[3] = cc[3] ^ 255; |
| 1315 | | s[2] = cc[2] ^ 255; |
| 1316 | | s[1] = cc[1] ^ 255; |
| 1317 | | s[0] = cc[0] ^ 255; |
| 1318 | | break; |
| 1319 | | case nv2a_renderer::CONSTANT_ALPHA: |
| 1320 | | s[3] = s[2] = s[1] = s[0] = cc[3]; |
| 1321 | | break; |
| 1322 | | case nv2a_renderer::ONE_MINUS_CONSTANT_ALPHA: |
| 1323 | | s[3] = s[2] = s[1] = s[0] = cc[3] ^ 255; |
| 1324 | | break; |
| 1325 | | case nv2a_renderer::SRC_ALPHA_SATURATE: |
| 1326 | | s[3] = 255; |
| 1327 | | if (c[3] < (fb[3] ^ 255)) |
| 1328 | | s[2] = c[3]; |
| 1460 | case nv2a_renderer::DECR_WRAP: |
| 1461 | if (sten > 0) |
| 1462 | sten--; |
| 1329 | 1463 | else |
| 1330 | | s[2] = fb[3]; |
| 1331 | | s[1] = s[0] = s[2]; |
| 1464 | sten = 255; |
| 1332 | 1465 | break; |
| 1333 | 1466 | } |
| 1467 | } |
| 1468 | // blending |
| 1469 | if (blending_enabled) { |
| 1470 | switch (blend_function_source) { |
| 1471 | case nv2a_renderer::ZERO: |
| 1472 | s[3] = s[2] = s[1] = s[0] = 0; |
| 1473 | break; |
| 1474 | case nv2a_renderer::ONE: |
| 1475 | default: |
| 1476 | s[3] = s[2] = s[1] = s[0] = 255; |
| 1477 | break; |
| 1478 | case nv2a_renderer::DST_COLOR: |
| 1479 | s[3] = fb[3]; |
| 1480 | s[2] = fb[2]; |
| 1481 | s[1] = fb[1]; |
| 1482 | s[0] = fb[0]; |
| 1483 | break; |
| 1484 | case nv2a_renderer::ONE_MINUS_DST_COLOR: |
| 1485 | s[3] = fb[3] ^ 255; |
| 1486 | s[2] = fb[2] ^ 255; |
| 1487 | s[1] = fb[1] ^ 255; |
| 1488 | s[0] = fb[0] ^ 255; |
| 1489 | break; |
| 1490 | case nv2a_renderer::SRC_ALPHA: |
| 1491 | s[3] = s[2] = s[1] = s[0] = c[3]; |
| 1492 | break; |
| 1493 | case nv2a_renderer::ONE_MINUS_SRC_ALPHA: |
| 1494 | s[3] = s[2] = s[1] = s[0] = c[3] ^ 255; |
| 1495 | break; |
| 1496 | case nv2a_renderer::DST_ALPHA: |
| 1497 | s[3] = s[2] = s[1] = s[0] = fb[3]; |
| 1498 | break; |
| 1499 | case nv2a_renderer::ONE_MINUS_DST_ALPHA: |
| 1500 | s[3] = s[2] = s[1] = s[0] = fb[3] ^ 255; |
| 1501 | break; |
| 1502 | case nv2a_renderer::CONSTANT_COLOR: |
| 1503 | s[3] = cc[3]; |
| 1504 | s[2] = cc[2]; |
| 1505 | s[1] = cc[1]; |
| 1506 | s[0] = cc[0]; |
| 1507 | break; |
| 1508 | case nv2a_renderer::ONE_MINUS_CONSTANT_COLOR: |
| 1509 | s[3] = cc[3] ^ 255; |
| 1510 | s[2] = cc[2] ^ 255; |
| 1511 | s[1] = cc[1] ^ 255; |
| 1512 | s[0] = cc[0] ^ 255; |
| 1513 | break; |
| 1514 | case nv2a_renderer::CONSTANT_ALPHA: |
| 1515 | s[3] = s[2] = s[1] = s[0] = cc[3]; |
| 1516 | break; |
| 1517 | case nv2a_renderer::ONE_MINUS_CONSTANT_ALPHA: |
| 1518 | s[3] = s[2] = s[1] = s[0] = cc[3] ^ 255; |
| 1519 | break; |
| 1520 | case nv2a_renderer::SRC_ALPHA_SATURATE: |
| 1521 | s[3] = 255; |
| 1522 | if (c[3] < (fb[3] ^ 255)) |
| 1523 | s[2] = c[3]; |
| 1524 | else |
| 1525 | s[2] = fb[3]; |
| 1526 | s[1] = s[0] = s[2]; |
| 1527 | break; |
| 1528 | } |
| 1334 | 1529 | switch (blend_function_destination) { |
| 1335 | | case nv2a_renderer::ZERO: |
| 1336 | | default: |
| 1337 | | d[3] = d[2] = d[1] = d[0] = 0; |
| 1338 | | break; |
| 1339 | | case nv2a_renderer::ONE: |
| 1340 | | d[3] = d[2] = d[1] = d[0] = 255; |
| 1341 | | break; |
| 1342 | | case nv2a_renderer::SRC_COLOR: |
| 1343 | | d[3] = c[3]; |
| 1344 | | d[2] = c[2]; |
| 1345 | | d[1] = c[1]; |
| 1346 | | d[0] = c[0]; |
| 1347 | | break; |
| 1348 | | case nv2a_renderer::ONE_MINUS_SRC_COLOR: |
| 1349 | | d[3] = c[3] ^ 255; |
| 1350 | | d[2] = c[2] ^ 255; |
| 1351 | | d[1] = c[1] ^ 255; |
| 1352 | | d[0] = c[0] ^ 255; |
| 1353 | | break; |
| 1354 | | case nv2a_renderer::SRC_ALPHA: |
| 1355 | | d[3] = d[2] = d[1] = d[0] = c[3]; |
| 1356 | | break; |
| 1357 | | case nv2a_renderer::ONE_MINUS_SRC_ALPHA: |
| 1358 | | d[3] = d[2] = d[1] = d[0] = c[3] ^ 255; |
| 1359 | | break; |
| 1360 | | case nv2a_renderer::DST_ALPHA: |
| 1361 | | d[3] = d[2] = d[1] = d[0] = fb[3]; |
| 1362 | | break; |
| 1363 | | case nv2a_renderer::ONE_MINUS_DST_ALPHA: |
| 1364 | | d[3] = d[2] = d[1] = d[0] = fb[3] ^ 255; |
| 1365 | | break; |
| 1366 | | case nv2a_renderer::CONSTANT_COLOR: |
| 1367 | | d[3] = cc[3]; |
| 1368 | | d[2] = cc[2]; |
| 1369 | | d[1] = cc[1]; |
| 1370 | | d[0] = cc[0]; |
| 1371 | | break; |
| 1372 | | case nv2a_renderer::ONE_MINUS_CONSTANT_COLOR: |
| 1373 | | d[3] = cc[3] ^ 255; |
| 1374 | | d[2] = cc[2] ^ 255; |
| 1375 | | d[1] = cc[1] ^ 255; |
| 1376 | | d[0] = cc[0] ^ 255; |
| 1377 | | break; |
| 1378 | | case nv2a_renderer::CONSTANT_ALPHA: |
| 1379 | | d[3] = d[2] = d[1] = d[0] = cc[3]; |
| 1380 | | break; |
| 1381 | | case nv2a_renderer::ONE_MINUS_CONSTANT_ALPHA: |
| 1382 | | d[3] = d[2] = d[1] = d[0] = cc[3] ^ 255; |
| 1383 | | break; |
| 1530 | case nv2a_renderer::ZERO: |
| 1531 | default: |
| 1532 | d[3] = d[2] = d[1] = d[0] = 0; |
| 1533 | break; |
| 1534 | case nv2a_renderer::ONE: |
| 1535 | d[3] = d[2] = d[1] = d[0] = 255; |
| 1536 | break; |
| 1537 | case nv2a_renderer::SRC_COLOR: |
| 1538 | d[3] = c[3]; |
| 1539 | d[2] = c[2]; |
| 1540 | d[1] = c[1]; |
| 1541 | d[0] = c[0]; |
| 1542 | break; |
| 1543 | case nv2a_renderer::ONE_MINUS_SRC_COLOR: |
| 1544 | d[3] = c[3] ^ 255; |
| 1545 | d[2] = c[2] ^ 255; |
| 1546 | d[1] = c[1] ^ 255; |
| 1547 | d[0] = c[0] ^ 255; |
| 1548 | break; |
| 1549 | case nv2a_renderer::SRC_ALPHA: |
| 1550 | d[3] = d[2] = d[1] = d[0] = c[3]; |
| 1551 | break; |
| 1552 | case nv2a_renderer::ONE_MINUS_SRC_ALPHA: |
| 1553 | d[3] = d[2] = d[1] = d[0] = c[3] ^ 255; |
| 1554 | break; |
| 1555 | case nv2a_renderer::DST_ALPHA: |
| 1556 | d[3] = d[2] = d[1] = d[0] = fb[3]; |
| 1557 | break; |
| 1558 | case nv2a_renderer::ONE_MINUS_DST_ALPHA: |
| 1559 | d[3] = d[2] = d[1] = d[0] = fb[3] ^ 255; |
| 1560 | break; |
| 1561 | case nv2a_renderer::CONSTANT_COLOR: |
| 1562 | d[3] = cc[3]; |
| 1563 | d[2] = cc[2]; |
| 1564 | d[1] = cc[1]; |
| 1565 | d[0] = cc[0]; |
| 1566 | break; |
| 1567 | case nv2a_renderer::ONE_MINUS_CONSTANT_COLOR: |
| 1568 | d[3] = cc[3] ^ 255; |
| 1569 | d[2] = cc[2] ^ 255; |
| 1570 | d[1] = cc[1] ^ 255; |
| 1571 | d[0] = cc[0] ^ 255; |
| 1572 | break; |
| 1573 | case nv2a_renderer::CONSTANT_ALPHA: |
| 1574 | d[3] = d[2] = d[1] = d[0] = cc[3]; |
| 1575 | break; |
| 1576 | case nv2a_renderer::ONE_MINUS_CONSTANT_ALPHA: |
| 1577 | d[3] = d[2] = d[1] = d[0] = cc[3] ^ 255; |
| 1578 | break; |
| 1384 | 1579 | } |
| 1385 | 1580 | switch (blend_equation) { |
| 1386 | | case nv2a_renderer::FUNC_ADD: |
| 1387 | | c[3] = (c[3] * s[3] + fb[3] * d[3]) / 255; |
| 1388 | | if (c[3] > 255) |
| 1389 | | c[3] = 255; |
| 1390 | | c[2] = (c[2] * s[2] + fb[2] * d[2]) / 255; |
| 1391 | | if (c[2] > 255) |
| 1392 | | c[2] = 255; |
| 1393 | | c[1] = (c[1] * s[1] + fb[1] * d[1]) / 255; |
| 1394 | | if (c[1] > 255) |
| 1395 | | c[1] = 255; |
| 1396 | | c[0] = (c[0] * s[0] + fb[0] * d[0]) / 255; |
| 1397 | | if (c[0] > 255) |
| 1398 | | c[0] = 255; |
| 1399 | | break; |
| 1400 | | case nv2a_renderer::FUNC_SUBTRACT: |
| 1401 | | c[3] = (c[3] * s[3] - fb[3] * d[3]) / 255; |
| 1402 | | if (c[3] < 0) |
| 1403 | | c[3] = 255; |
| 1404 | | c[2] = (c[2] * s[2] - fb[2] * d[2]) / 255; |
| 1405 | | if (c[2] < 0) |
| 1406 | | c[2] = 255; |
| 1407 | | c[1] = (c[1] * s[1] - fb[1] * d[1]) / 255; |
| 1408 | | if (c[1] < 0) |
| 1409 | | c[1] = 255; |
| 1410 | | c[0] = (c[0] * s[0] - fb[0] * d[0]) / 255; |
| 1411 | | if (c[0] < 0) |
| 1412 | | c[0] = 255; |
| 1413 | | break; |
| 1414 | | case nv2a_renderer::FUNC_REVERSE_SUBTRACT: |
| 1415 | | c[3] = (fb[3] * d[3] - c[3] * s[3]) / 255; |
| 1416 | | if (c[3] < 0) |
| 1417 | | c[3] = 255; |
| 1418 | | c[2] = (fb[2] * d[2] - c[2] * s[2]) / 255; |
| 1419 | | if (c[2] < 0) |
| 1420 | | c[2] = 255; |
| 1421 | | c[1] = (fb[1] * d[1] - c[1] * s[1]) / 255; |
| 1422 | | if (c[1] < 0) |
| 1423 | | c[1] = 255; |
| 1424 | | c[0] = (fb[0] * d[0] - c[0] * s[0]) / 255; |
| 1425 | | if (c[0] < 0) |
| 1426 | | c[0] = 255; |
| 1427 | | break; |
| 1428 | | case nv2a_renderer::MIN: |
| 1429 | | c[3] = s[3]; |
| 1430 | | if (d[3] < c[3]) |
| 1431 | | c[3] = d[3]; |
| 1432 | | c[2] = s[2]; |
| 1433 | | if (d[2] < c[2]) |
| 1434 | | c[2] = d[2]; |
| 1435 | | c[1] = s[1]; |
| 1436 | | if (d[1] < c[1]) |
| 1437 | | c[1] = d[1]; |
| 1438 | | c[0] = s[0]; |
| 1439 | | if (d[0] < c[0]) |
| 1440 | | c[0] = d[0]; |
| 1441 | | break; |
| 1442 | | case nv2a_renderer::MAX: |
| 1443 | | c[3] = s[3]; |
| 1444 | | if (d[3] > c[3]) |
| 1445 | | c[3] = d[3]; |
| 1446 | | c[2] = s[2]; |
| 1447 | | if (d[2] > c[2]) |
| 1448 | | c[2] = d[2]; |
| 1449 | | c[1] = s[1]; |
| 1450 | | if (d[1] > c[1]) |
| 1451 | | c[1] = d[1]; |
| 1452 | | c[0] = s[0]; |
| 1453 | | if (d[0] > c[0]) |
| 1454 | | c[0] = d[0]; |
| 1455 | | break; |
| 1581 | case nv2a_renderer::FUNC_ADD: |
| 1582 | c[3] = (c[3] * s[3] + fb[3] * d[3]) / 255; |
| 1583 | if (c[3] > 255) |
| 1584 | c[3] = 255; |
| 1585 | c[2] = (c[2] * s[2] + fb[2] * d[2]) / 255; |
| 1586 | if (c[2] > 255) |
| 1587 | c[2] = 255; |
| 1588 | c[1] = (c[1] * s[1] + fb[1] * d[1]) / 255; |
| 1589 | if (c[1] > 255) |
| 1590 | c[1] = 255; |
| 1591 | c[0] = (c[0] * s[0] + fb[0] * d[0]) / 255; |
| 1592 | if (c[0] > 255) |
| 1593 | c[0] = 255; |
| 1594 | break; |
| 1595 | case nv2a_renderer::FUNC_SUBTRACT: |
| 1596 | c[3] = (c[3] * s[3] - fb[3] * d[3]) / 255; |
| 1597 | if (c[3] < 0) |
| 1598 | c[3] = 255; |
| 1599 | c[2] = (c[2] * s[2] - fb[2] * d[2]) / 255; |
| 1600 | if (c[2] < 0) |
| 1601 | c[2] = 255; |
| 1602 | c[1] = (c[1] * s[1] - fb[1] * d[1]) / 255; |
| 1603 | if (c[1] < 0) |
| 1604 | c[1] = 255; |
| 1605 | c[0] = (c[0] * s[0] - fb[0] * d[0]) / 255; |
| 1606 | if (c[0] < 0) |
| 1607 | c[0] = 255; |
| 1608 | break; |
| 1609 | case nv2a_renderer::FUNC_REVERSE_SUBTRACT: |
| 1610 | c[3] = (fb[3] * d[3] - c[3] * s[3]) / 255; |
| 1611 | if (c[3] < 0) |
| 1612 | c[3] = 255; |
| 1613 | c[2] = (fb[2] * d[2] - c[2] * s[2]) / 255; |
| 1614 | if (c[2] < 0) |
| 1615 | c[2] = 255; |
| 1616 | c[1] = (fb[1] * d[1] - c[1] * s[1]) / 255; |
| 1617 | if (c[1] < 0) |
| 1618 | c[1] = 255; |
| 1619 | c[0] = (fb[0] * d[0] - c[0] * s[0]) / 255; |
| 1620 | if (c[0] < 0) |
| 1621 | c[0] = 255; |
| 1622 | break; |
| 1623 | case nv2a_renderer::MIN: |
| 1624 | c[3] = s[3]; |
| 1625 | if (d[3] < c[3]) |
| 1626 | c[3] = d[3]; |
| 1627 | c[2] = s[2]; |
| 1628 | if (d[2] < c[2]) |
| 1629 | c[2] = d[2]; |
| 1630 | c[1] = s[1]; |
| 1631 | if (d[1] < c[1]) |
| 1632 | c[1] = d[1]; |
| 1633 | c[0] = s[0]; |
| 1634 | if (d[0] < c[0]) |
| 1635 | c[0] = d[0]; |
| 1636 | break; |
| 1637 | case nv2a_renderer::MAX: |
| 1638 | c[3] = s[3]; |
| 1639 | if (d[3] > c[3]) |
| 1640 | c[3] = d[3]; |
| 1641 | c[2] = s[2]; |
| 1642 | if (d[2] > c[2]) |
| 1643 | c[2] = d[2]; |
| 1644 | c[1] = s[1]; |
| 1645 | if (d[1] > c[1]) |
| 1646 | c[1] = d[1]; |
| 1647 | c[0] = s[0]; |
| 1648 | if (d[0] > c[0]) |
| 1649 | c[0] = d[0]; |
| 1650 | break; |
| 1456 | 1651 | } |
| 1457 | 1652 | } |
| 1458 | 1653 | // dithering not done |
| 1459 | 1654 | // logical operation |
| 1460 | 1655 | if (logical_operation_enabled) { |
| 1461 | 1656 | switch (logical_operation) { |
| 1462 | | case nv2a_renderer::CLEAR: |
| 1463 | | c[3] = 0; |
| 1464 | | c[2] = 0; |
| 1465 | | c[1] = 0; |
| 1466 | | c[0] = 0; |
| 1467 | | break; |
| 1468 | | case nv2a_renderer::AND: |
| 1469 | | c[3] = c[3] & fb[3]; |
| 1470 | | c[2] = c[2] & fb[2]; |
| 1471 | | c[1] = c[1] & fb[1]; |
| 1472 | | c[0] = c[0] & fb[0]; |
| 1473 | | break; |
| 1474 | | case nv2a_renderer::AND_REVERSE: |
| 1475 | | c[3] = c[3] & (fb[3] ^ 255); |
| 1476 | | c[2] = c[2] & (fb[2] ^ 255); |
| 1477 | | c[1] = c[1] & (fb[1] ^ 255); |
| 1478 | | c[0] = c[0] & (fb[0] ^ 255); |
| 1479 | | break; |
| 1480 | | case nv2a_renderer::COPY: |
| 1481 | | default: |
| 1482 | | break; |
| 1483 | | case nv2a_renderer::AND_INVERTED: |
| 1484 | | c[3] = (c[3] ^ 255) & fb[3]; |
| 1485 | | c[2] = (c[2] ^ 255) & fb[2]; |
| 1486 | | c[1] = (c[1] ^ 255) & fb[1]; |
| 1487 | | c[0] = (c[0] ^ 255) & fb[0]; |
| 1488 | | break; |
| 1489 | | case nv2a_renderer::NOOP: |
| 1490 | | c[3] = fb[3]; |
| 1491 | | c[2] = fb[2]; |
| 1492 | | c[1] = fb[1]; |
| 1493 | | c[0] = fb[0]; |
| 1494 | | break; |
| 1495 | | case nv2a_renderer::XOR: |
| 1496 | | c[3] = c[3] ^ fb[3]; |
| 1497 | | c[2] = c[2] ^ fb[2]; |
| 1498 | | c[1] = c[1] ^ fb[1]; |
| 1499 | | c[0] = c[0] ^ fb[0]; |
| 1500 | | break; |
| 1501 | | case nv2a_renderer::OR: |
| 1502 | | c[3] = c[3] | fb[3]; |
| 1503 | | c[2] = c[2] | fb[2]; |
| 1504 | | c[1] = c[1] | fb[1]; |
| 1505 | | c[0] = c[0] | fb[0]; |
| 1506 | | break; |
| 1507 | | case nv2a_renderer::NOR: |
| 1508 | | c[3] = (c[3] | fb[3]) ^ 255; |
| 1509 | | c[2] = (c[2] | fb[2]) ^ 255; |
| 1510 | | c[1] = (c[1] | fb[1]) ^ 255; |
| 1511 | | c[0] = (c[0] | fb[0]) ^ 255; |
| 1512 | | break; |
| 1513 | | case nv2a_renderer::EQUIV: |
| 1514 | | c[3] = (c[3] ^ fb[3]) ^ 255; |
| 1515 | | c[2] = (c[2] ^ fb[2]) ^ 255; |
| 1516 | | c[1] = (c[1] ^ fb[1]) ^ 255; |
| 1517 | | c[0] = (c[0] ^ fb[0]) ^ 255; |
| 1518 | | break; |
| 1519 | | case nv2a_renderer::INVERT: |
| 1520 | | c[3] = fb[3] ^ 255; |
| 1521 | | c[2] = fb[2] ^ 255; |
| 1522 | | c[1] = fb[1] ^ 255; |
| 1523 | | c[0] = fb[0] ^ 255; |
| 1524 | | break; |
| 1525 | | case nv2a_renderer::OR_REVERSE: |
| 1526 | | c[3] = c[3] | (fb[3] ^ 255); |
| 1527 | | c[2] = c[2] | (fb[2] ^ 255); |
| 1528 | | c[1] = c[1] | (fb[1] ^ 255); |
| 1529 | | c[0] = c[0] | (fb[0] ^ 255); |
| 1530 | | break; |
| 1531 | | case nv2a_renderer::COPY_INVERTED: |
| 1532 | | c[3] = c[3] ^ 255; |
| 1533 | | c[2] = c[2] ^ 255; |
| 1534 | | c[1] = c[1] ^ 255; |
| 1535 | | c[0] = c[0] ^ 255; |
| 1536 | | break; |
| 1537 | | case nv2a_renderer::OR_INVERTED: |
| 1538 | | c[3] = (c[3] ^ 255) | fb[3]; |
| 1539 | | c[2] = (c[2] ^ 255) | fb[2]; |
| 1540 | | c[1] = (c[1] ^ 255) | fb[1]; |
| 1541 | | c[0] = (c[0] ^ 255) | fb[0]; |
| 1542 | | break; |
| 1543 | | case nv2a_renderer::NAND: |
| 1544 | | c[3] = (c[3] & fb[3]) ^ 255; |
| 1545 | | c[2] = (c[2] & fb[2]) ^ 255; |
| 1546 | | c[1] = (c[1] & fb[1]) ^ 255; |
| 1547 | | c[0] = (c[0] & fb[0]) ^ 255; |
| 1548 | | break; |
| 1549 | | case nv2a_renderer::SET: |
| 1550 | | c[3] = 255; |
| 1551 | | c[2] = 255; |
| 1552 | | c[1] = 255; |
| 1553 | | c[0] = 255; |
| 1554 | | break; |
| 1657 | case nv2a_renderer::CLEAR: |
| 1658 | c[3] = 0; |
| 1659 | c[2] = 0; |
| 1660 | c[1] = 0; |
| 1661 | c[0] = 0; |
| 1662 | break; |
| 1663 | case nv2a_renderer::AND: |
| 1664 | c[3] = c[3] & fb[3]; |
| 1665 | c[2] = c[2] & fb[2]; |
| 1666 | c[1] = c[1] & fb[1]; |
| 1667 | c[0] = c[0] & fb[0]; |
| 1668 | break; |
| 1669 | case nv2a_renderer::AND_REVERSE: |
| 1670 | c[3] = c[3] & (fb[3] ^ 255); |
| 1671 | c[2] = c[2] & (fb[2] ^ 255); |
| 1672 | c[1] = c[1] & (fb[1] ^ 255); |
| 1673 | c[0] = c[0] & (fb[0] ^ 255); |
| 1674 | break; |
| 1675 | case nv2a_renderer::COPY: |
| 1676 | default: |
| 1677 | break; |
| 1678 | case nv2a_renderer::AND_INVERTED: |
| 1679 | c[3] = (c[3] ^ 255) & fb[3]; |
| 1680 | c[2] = (c[2] ^ 255) & fb[2]; |
| 1681 | c[1] = (c[1] ^ 255) & fb[1]; |
| 1682 | c[0] = (c[0] ^ 255) & fb[0]; |
| 1683 | break; |
| 1684 | case nv2a_renderer::NOOP: |
| 1685 | c[3] = fb[3]; |
| 1686 | c[2] = fb[2]; |
| 1687 | c[1] = fb[1]; |
| 1688 | c[0] = fb[0]; |
| 1689 | break; |
| 1690 | case nv2a_renderer::XOR: |
| 1691 | c[3] = c[3] ^ fb[3]; |
| 1692 | c[2] = c[2] ^ fb[2]; |
| 1693 | c[1] = c[1] ^ fb[1]; |
| 1694 | c[0] = c[0] ^ fb[0]; |
| 1695 | break; |
| 1696 | case nv2a_renderer::OR: |
| 1697 | c[3] = c[3] | fb[3]; |
| 1698 | c[2] = c[2] | fb[2]; |
| 1699 | c[1] = c[1] | fb[1]; |
| 1700 | c[0] = c[0] | fb[0]; |
| 1701 | break; |
| 1702 | case nv2a_renderer::NOR: |
| 1703 | c[3] = (c[3] | fb[3]) ^ 255; |
| 1704 | c[2] = (c[2] | fb[2]) ^ 255; |
| 1705 | c[1] = (c[1] | fb[1]) ^ 255; |
| 1706 | c[0] = (c[0] | fb[0]) ^ 255; |
| 1707 | break; |
| 1708 | case nv2a_renderer::EQUIV: |
| 1709 | c[3] = (c[3] ^ fb[3]) ^ 255; |
| 1710 | c[2] = (c[2] ^ fb[2]) ^ 255; |
| 1711 | c[1] = (c[1] ^ fb[1]) ^ 255; |
| 1712 | c[0] = (c[0] ^ fb[0]) ^ 255; |
| 1713 | break; |
| 1714 | case nv2a_renderer::INVERT: |
| 1715 | c[3] = fb[3] ^ 255; |
| 1716 | c[2] = fb[2] ^ 255; |
| 1717 | c[1] = fb[1] ^ 255; |
| 1718 | c[0] = fb[0] ^ 255; |
| 1719 | break; |
| 1720 | case nv2a_renderer::OR_REVERSE: |
| 1721 | c[3] = c[3] | (fb[3] ^ 255); |
| 1722 | c[2] = c[2] | (fb[2] ^ 255); |
| 1723 | c[1] = c[1] | (fb[1] ^ 255); |
| 1724 | c[0] = c[0] | (fb[0] ^ 255); |
| 1725 | break; |
| 1726 | case nv2a_renderer::COPY_INVERTED: |
| 1727 | c[3] = c[3] ^ 255; |
| 1728 | c[2] = c[2] ^ 255; |
| 1729 | c[1] = c[1] ^ 255; |
| 1730 | c[0] = c[0] ^ 255; |
| 1731 | break; |
| 1732 | case nv2a_renderer::OR_INVERTED: |
| 1733 | c[3] = (c[3] ^ 255) | fb[3]; |
| 1734 | c[2] = (c[2] ^ 255) | fb[2]; |
| 1735 | c[1] = (c[1] ^ 255) | fb[1]; |
| 1736 | c[0] = (c[0] ^ 255) | fb[0]; |
| 1737 | break; |
| 1738 | case nv2a_renderer::NAND: |
| 1739 | c[3] = (c[3] & fb[3]) ^ 255; |
| 1740 | c[2] = (c[2] & fb[2]) ^ 255; |
| 1741 | c[1] = (c[1] & fb[1]) ^ 255; |
| 1742 | c[0] = (c[0] & fb[0]) ^ 255; |
| 1743 | break; |
| 1744 | case nv2a_renderer::SET: |
| 1745 | c[3] = 255; |
| 1746 | c[2] = 255; |
| 1747 | c[1] = 255; |
| 1748 | c[0] = 255; |
| 1749 | break; |
| 1555 | 1750 | } |
| 1556 | 1751 | } |
| 1557 | 1752 | fbcolor = (c[3] << 24) | (c[2] << 16) | (c[1] << 8) | c[0]; |
| 1558 | | *((UINT32 *)addr) = fbcolor; |
| 1753 | *addr = fbcolor; |
| 1754 | if (depth_write_enabled) |
| 1755 | dep = depth; |
| 1756 | deptsten = (dep << 8) | sten; |
| 1757 | *daddr = deptsten; |
| 1559 | 1758 | } |
| 1560 | 1759 | |
| 1561 | 1760 | void nv2a_renderer::render_color(INT32 scanline, const extent_t &extent, const nvidia_object_data &objectdata, int threadid) |
| r242571 | r242572 | |
| 1567 | 1766 | x = extent.stopx - extent.startx - 1; // number of pixels to draw |
| 1568 | 1767 | while (x >= 0) { |
| 1569 | 1768 | UINT32 a8r8g8b8; |
| 1769 | UINT32 z; |
| 1570 | 1770 | int ca, cr, cg, cb; |
| 1571 | 1771 | int xp = extent.startx + x; // x coordinate of current pixel |
| 1572 | 1772 | |
| 1573 | | cb = ((extent.param[0].start + (float)x*extent.param[0].dpdx))*255.0; |
| 1574 | | cg = ((extent.param[1].start + (float)x*extent.param[1].dpdx))*255.0; |
| 1575 | | cr = ((extent.param[2].start + (float)x*extent.param[2].dpdx))*255.0; |
| 1576 | | ca = ((extent.param[3].start + (float)x*extent.param[3].dpdx))*255.0; |
| 1773 | cb = ((extent.param[PARAM_COLOR_B].start + (float)x*extent.param[PARAM_COLOR_B].dpdx))*255.0; |
| 1774 | cg = ((extent.param[PARAM_COLOR_G].start + (float)x*extent.param[PARAM_COLOR_G].dpdx))*255.0; |
| 1775 | cr = ((extent.param[PARAM_COLOR_R].start + (float)x*extent.param[PARAM_COLOR_R].dpdx))*255.0; |
| 1776 | ca = ((extent.param[PARAM_COLOR_A].start + (float)x*extent.param[PARAM_COLOR_A].dpdx))*255.0; |
| 1577 | 1777 | a8r8g8b8 = (ca << 24) + (cr << 16) + (cg << 8) + cb; // pixel color obtained by interpolating the colors of the vertices |
| 1578 | | write_pixel(xp, scanline, a8r8g8b8); |
| 1778 | z = (extent.param[PARAM_Z].start + (float)x*extent.param[PARAM_Z].dpdx); |
| 1779 | write_pixel(xp, scanline, a8r8g8b8, z); |
| 1579 | 1780 | x--; |
| 1580 | 1781 | } |
| 1581 | 1782 | } |
| r242571 | r242572 | |
| 1584 | 1785 | { |
| 1585 | 1786 | int x; |
| 1586 | 1787 | UINT32 a8r8g8b8; |
| 1788 | UINT32 z; |
| 1587 | 1789 | |
| 1588 | 1790 | if (!objectdata.data->texture[0].enabled) { |
| 1589 | 1791 | return; |
| r242571 | r242572 | |
| 1595 | 1797 | int up, vp; |
| 1596 | 1798 | int xp = extent.startx + x; // x coordinate of current pixel |
| 1597 | 1799 | |
| 1598 | | up = (extent.param[4].start + (float)x*extent.param[4].dpdx)*(float)(objectdata.data->texture[0].sizeu - 1); // x coordinate of texel in texture |
| 1599 | | vp = extent.param[5].start*(float)(objectdata.data->texture[0].sizev - 1); // y coordinate of texel in texture |
| 1800 | up = (extent.param[PARAM_TEXTURE0_U].start + (float)x*extent.param[PARAM_TEXTURE0_U].dpdx)*(float)(objectdata.data->texture[0].sizeu - 1); // x coordinate of texel in texture |
| 1801 | vp = (extent.param[PARAM_TEXTURE0_V].start + (float)x*extent.param[PARAM_TEXTURE0_V].dpdx)*(float)(objectdata.data->texture[0].sizev - 1); // y coordinate of texel in texture |
| 1600 | 1802 | a8r8g8b8 = texture_get_texel(0, up, vp); |
| 1601 | | write_pixel(xp, scanline, a8r8g8b8); |
| 1803 | z = (extent.param[PARAM_Z].start + (float)x*extent.param[PARAM_Z].dpdx); |
| 1804 | write_pixel(xp, scanline, a8r8g8b8, z); |
| 1602 | 1805 | x--; |
| 1603 | 1806 | } |
| 1604 | 1807 | } |
| r242571 | r242572 | |
| 1610 | 1813 | int ca, cr, cg, cb; |
| 1611 | 1814 | UINT32 color[6]; |
| 1612 | 1815 | UINT32 a8r8g8b8; |
| 1816 | UINT32 z; |
| 1613 | 1817 | int n;//,m,i,j,k; |
| 1614 | 1818 | |
| 1615 | 1819 | color[0] = color[1] = color[2] = color[3] = color[4] = color[5] = 0; |
| r242571 | r242572 | |
| 1622 | 1826 | xp = extent.startx + x; |
| 1623 | 1827 | // 1: fetch data |
| 1624 | 1828 | // 1.1: interpolated color from vertices |
| 1625 | | cb = ((extent.param[0].start + (float)x*extent.param[0].dpdx))*255.0; |
| 1626 | | cg = ((extent.param[1].start + (float)x*extent.param[1].dpdx))*255.0; |
| 1627 | | cr = ((extent.param[2].start + (float)x*extent.param[2].dpdx))*255.0; |
| 1628 | | ca = ((extent.param[3].start + (float)x*extent.param[3].dpdx))*255.0; |
| 1829 | cb = ((extent.param[PARAM_COLOR_B].start + (float)x*extent.param[PARAM_COLOR_B].dpdx))*255.0; |
| 1830 | cg = ((extent.param[PARAM_COLOR_G].start + (float)x*extent.param[PARAM_COLOR_G].dpdx))*255.0; |
| 1831 | cr = ((extent.param[PARAM_COLOR_R].start + (float)x*extent.param[PARAM_COLOR_R].dpdx))*255.0; |
| 1832 | ca = ((extent.param[PARAM_COLOR_A].start + (float)x*extent.param[PARAM_COLOR_A].dpdx))*255.0; |
| 1629 | 1833 | color[0] = (ca << 24) + (cr << 16) + (cg << 8) + cb; // pixel color obtained by interpolating the colors of the vertices |
| 1630 | 1834 | color[1] = 0; // lighting not yet |
| 1631 | 1835 | // 1.2: color for each of the 4 possible textures |
| 1632 | 1836 | for (n = 0; n < 4; n++) { |
| 1633 | 1837 | if (texture[n].enabled) { |
| 1634 | | up = (extent.param[4 + n * 2].start + (float)x*extent.param[4 + n * 2].dpdx)*(float)(objectdata.data->texture[n].sizeu - 1); |
| 1635 | | vp = extent.param[5 + n * 2].start*(float)(objectdata.data->texture[n].sizev - 1); |
| 1838 | up = (extent.param[PARAM_TEXTURE0_U + n * 2].start + (float)x*extent.param[PARAM_TEXTURE0_U + n * 2].dpdx)*(float)(objectdata.data->texture[n].sizeu - 1); |
| 1839 | vp = extent.param[PARAM_TEXTURE0_V + n * 2].start*(float)(objectdata.data->texture[n].sizev - 1); |
| 1636 | 1840 | color[n + 2] = texture_get_texel(n, up, vp); |
| 1637 | 1841 | } |
| 1638 | 1842 | } |
| r242571 | r242572 | |
| 1657 | 1861 | combiner_final_output(); |
| 1658 | 1862 | a8r8g8b8 = combiner_float_argb8(combiner.output); |
| 1659 | 1863 | // 3: write pixel |
| 1660 | | write_pixel(xp, scanline, a8r8g8b8); |
| 1864 | z = (extent.param[PARAM_Z].start + (float)x*extent.param[PARAM_Z].dpdx); |
| 1865 | write_pixel(xp, scanline, a8r8g8b8, z); |
| 1661 | 1866 | x--; |
| 1662 | 1867 | } |
| 1663 | 1868 | osd_lock_release(combiner.lock); |
| r242571 | r242572 | |
| 1920 | 2125 | |
| 1921 | 2126 | void nv2a_renderer::convert_vertices_poly(vertex_nv *source, vertex_t *destination, int count) |
| 1922 | 2127 | { |
| 2128 | vertex_nv vert[4]; |
| 1923 | 2129 | int m, u; |
| 1924 | 2130 | |
| 1925 | 2131 | // take each vertex with its attributes and obtain data for drawing |
| r242571 | r242572 | |
| 1930 | 2136 | for (m = 0; m < count; m++) { |
| 1931 | 2137 | destination[m].x = source[m].attribute[0].fv[0]; |
| 1932 | 2138 | destination[m].y = source[m].attribute[0].fv[1]; |
| 1933 | | for (u = 0; u < 4; u++) // 0=b 1=g 2=r 3=a |
| 2139 | for (u = PARAM_COLOR_B; u <= PARAM_COLOR_A; u++) // 0=b 1=g 2=r 3=a |
| 1934 | 2140 | destination[m].p[u] = source[m].attribute[3].fv[u]; |
| 1935 | 2141 | for (u = 0; u < 4; u++) { |
| 1936 | | destination[m].p[4 + u * 2] = source[m].attribute[9 + u].fv[0]; |
| 1937 | | destination[m].p[5 + u * 2] = source[m].attribute[9 + u].fv[1]; |
| 2142 | destination[m].p[PARAM_TEXTURE0_U + u * 2] = source[m].attribute[9 + u].fv[0]; |
| 2143 | destination[m].p[PARAM_TEXTURE0_V + u * 2] = source[m].attribute[9 + u].fv[1]; |
| 1938 | 2144 | } |
| 2145 | destination[m].p[PARAM_Z] = 0+0xffffff; |
| 1939 | 2146 | } |
| 1940 | 2147 | } |
| 1941 | 2148 | else { |
| 1942 | 2149 | // vertex program |
| 1943 | | vertex_nv vert[4]; |
| 1944 | 2150 | // run vertex program |
| 1945 | 2151 | vertexprogram.exec.process(vertexprogram.start_instruction, source, vert, count); |
| 1946 | 2152 | // copy data for poly.c |
| 1947 | 2153 | for (m = 0; m < count; m++) { |
| 1948 | 2154 | destination[m].x = vert[m].attribute[0].fv[0]; |
| 1949 | 2155 | destination[m].y = vert[m].attribute[0].fv[1]; |
| 1950 | | for (u = 0; u < 4; u++) // 0=b 1=g 2=r 3=a |
| 2156 | for (u = PARAM_COLOR_B; u <= PARAM_COLOR_A; u++) // 0=b 1=g 2=r 3=a |
| 1951 | 2157 | destination[m].p[u] = vert[m].attribute[3].fv[u]; |
| 1952 | 2158 | for (u = 0; u < 4; u++) { |
| 1953 | | destination[m].p[4 + u * 2] = vert[m].attribute[9 + u].fv[0]; |
| 1954 | | destination[m].p[5 + u * 2] = vert[m].attribute[9 + u].fv[1]; |
| 2159 | destination[m].p[PARAM_TEXTURE0_U + u * 2] = vert[m].attribute[9 + u].fv[0]; |
| 2160 | destination[m].p[PARAM_TEXTURE0_V + u * 2] = vert[m].attribute[9 + u].fv[1]; |
| 1955 | 2161 | } |
| 2162 | destination[m].p[PARAM_Z] = vert[m].attribute[0].fv[2]; |
| 1956 | 2163 | } |
| 1957 | 2164 | } |
| 1958 | 2165 | } |
| r242571 | r242572 | |
| 1998 | 2205 | |
| 1999 | 2206 | read_vertices_0x1810(space, vert, n + offset, 4); |
| 2000 | 2207 | convert_vertices_poly(vert, xy, 4); |
| 2001 | | render_polygon<4>(fb.cliprect(), renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv |
| 2208 | render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv |
| 2002 | 2209 | } |
| 2003 | 2210 | wait(); |
| 2004 | 2211 | } |
| r242571 | r242572 | |
| 2013 | 2220 | for (n = 0; n <= count; n++) { |
| 2014 | 2221 | read_vertices_0x1810(space, vert + ((n + 2) & 3), offset + n, 1); |
| 2015 | 2222 | convert_vertices_poly(vert + ((n + 2) & 3), xy + ((n + 2) & 3), 1); |
| 2016 | | render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[((n & 1) + n) & 3], xy[((~n & 1) + n) & 3], xy[(2 + n) & 3]); |
| 2223 | render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[((n & 1) + n) & 3], xy[((~n & 1) + n) & 3], xy[(2 + n) & 3]); |
| 2017 | 2224 | } |
| 2018 | 2225 | wait(); |
| 2019 | 2226 | } |
| r242571 | r242572 | |
| 2052 | 2259 | address = address + c * 4; |
| 2053 | 2260 | countlen = countlen - c; |
| 2054 | 2261 | convert_vertices_poly(vert, xy, 4); |
| 2055 | | render_polygon<4>(fb.cliprect(), renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv |
| 2262 | render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv |
| 2056 | 2263 | } |
| 2057 | 2264 | while (countlen > 0) { |
| 2058 | 2265 | data = space.read_dword(address); |
| r242571 | r242572 | |
| 2077 | 2284 | address = address + c * 4; |
| 2078 | 2285 | countlen = countlen - c; |
| 2079 | 2286 | convert_vertices_poly(vert, xy, 3); |
| 2080 | | render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[0], xy[1], xy[2]); // 4 rgba, 4 texture units 2 uv |
| 2287 | render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[0], xy[1], xy[2]); // 4 rgba, 4 texture units 2 uv |
| 2081 | 2288 | } |
| 2082 | 2289 | while (countlen > 0) { |
| 2083 | 2290 | data = space.read_dword(address); |
| r242571 | r242572 | |
| 2108 | 2315 | convert_vertices_poly(vert + ((n + 2) & 3), xy + ((n + 2) & 3), 1); |
| 2109 | 2316 | if (xy[(n + 2) & 3].y > 293800000.0) |
| 2110 | 2317 | xy[(n + 2) & 3].y = xy[(n + 2) & 3].y + 1.0; |
| 2111 | | render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[((n & 1) + n) & 3], xy[((~n & 1) + n) & 3], xy[(2 + n) & 3]); |
| 2318 | render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[((n & 1) + n) & 3], xy[((~n & 1) + n) & 3], xy[(2 + n) & 3]); |
| 2112 | 2319 | } |
| 2113 | 2320 | } |
| 2114 | 2321 | while (countlen > 0) { |
| r242571 | r242572 | |
| 2170 | 2377 | } |
| 2171 | 2378 | address = address + c * 4; |
| 2172 | 2379 | convert_vertices_poly(vert + ((n & 1) + 1), xy + ((n & 1) + 1), 1); |
| 2173 | | render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[0], xy[(~n & 1) + 1], xy[(n & 1) + 1]); |
| 2380 | render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[0], xy[(~n & 1) + 1], xy[(n & 1) + 1]); |
| 2174 | 2381 | } |
| 2175 | 2382 | wait(); |
| 2176 | 2383 | } |
| r242571 | r242572 | |
| 2198 | 2405 | break; |
| 2199 | 2406 | } |
| 2200 | 2407 | address = address + c * 4; |
| 2201 | | render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[((n & 1) + n) & 3], xy[((~n & 1) + n) & 3], xy[(2 + n) & 3]); |
| 2408 | render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[((n & 1) + n) & 3], xy[((~n & 1) + n) & 3], xy[(2 + n) & 3]); |
| 2202 | 2409 | } |
| 2203 | 2410 | wait(); |
| 2204 | 2411 | } |
| r242571 | r242572 | |
| 2217 | 2424 | break; |
| 2218 | 2425 | } |
| 2219 | 2426 | address = address + c * 4; |
| 2220 | | render_polygon<4>(fb.cliprect(), renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv |
| 2427 | render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv |
| 2221 | 2428 | } |
| 2222 | 2429 | wait(); |
| 2223 | 2430 | } |
| r242571 | r242572 | |
| 2245 | 2452 | return; |
| 2246 | 2453 | } |
| 2247 | 2454 | address = address + c * 4; |
| 2248 | | render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[n & 3], xy[(n + 1) & 3], xy[(n + 2) & 3]); |
| 2249 | | render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[(n + 2) & 3], xy[(n + 1) & 3], xy[(n + 3) & 3]); |
| 2455 | render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[n & 3], xy[(n + 1) & 3], xy[(n + 2) & 3]); |
| 2456 | render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[(n + 2) & 3], xy[(n + 1) & 3], xy[(n + 3) & 3]); |
| 2250 | 2457 | } |
| 2251 | 2458 | wait(); |
| 2252 | 2459 | } |
| r242571 | r242572 | |
| 2320 | 2527 | space.write_dword(base + offset, data); |
| 2321 | 2528 | countlen--; |
| 2322 | 2529 | } |
| 2530 | if (maddress == 0x1d98) { |
| 2531 | countlen--; |
| 2532 | } |
| 2533 | if (maddress == 0x1d9c) { |
| 2534 | countlen--; |
| 2535 | } |
| 2323 | 2536 | if (maddress == 0x1d94) { |
| 2537 | int m; |
| 2538 | |
| 2539 | m = channel[chanel][subchannel].object.method[0x1d7c / 4]; |
| 2540 | if (channel[chanel][subchannel].object.method[0x0208 / 4] & 0x2000) |
| 2541 | m = 2; |
| 2542 | else |
| 2543 | m = 1; |
| 2324 | 2544 | // possible buffers: color, depth, stencil, and accumulation |
| 2325 | 2545 | // clear framebuffer |
| 2326 | 2546 | if (data & 0xf0) { |
| 2547 | bitmap_rgb32 bm(rendertarget, (limits_rendertarget.right() + 1) * m, (limits_rendertarget.bottom() + 1) * m, pitch_rendertarget / 4); // why *2 ? |
| 2327 | 2548 | // clear colors |
| 2328 | 2549 | UINT32 color = channel[chanel][subchannel].object.method[0x1d90 / 4]; |
| 2329 | | fb.fill(color); |
| 2550 | bm.fill(color); |
| 2330 | 2551 | //printf("clearscreen\n\r"); |
| 2331 | 2552 | } |
| 2332 | | if (data & 0x03) { |
| 2333 | | // clear stencil+zbuffer |
| 2553 | if (data & 0x01) { |
| 2554 | bitmap_rgb32 bm(depthbuffer, (limits_rendertarget.right() + 1) * m, (limits_rendertarget.bottom() + 1) * m, pitch_rendertarget / 4); // why *2 ? |
| 2555 | // clear zbuffer |
| 2556 | UINT32 depth = channel[chanel][subchannel].object.method[0x1d8c / 4]; |
| 2557 | bm.fill(depth); |
| 2334 | 2558 | } |
| 2335 | 2559 | countlen--; |
| 2336 | 2560 | } |
| 2561 | if (maddress == 0x0200) { |
| 2562 | //x = data & 0xffff; |
| 2563 | //w = (data >> 16) & 0xffff; |
| 2564 | limits_rendertarget.setx(0,((data >> 16) & 0xffff)-1); |
| 2565 | } |
| 2566 | if (maddress == 0x0204) { |
| 2567 | //y = data & 0xffff; |
| 2568 | //h = (data >> 16) & 0xffff; |
| 2569 | limits_rendertarget.sety(0,((data >> 16) & 0xffff)-1); |
| 2570 | } |
| 2571 | if (maddress == 0x020c) { |
| 2572 | // line size ? |
| 2573 | pitch_rendertarget=data & 0xffff; |
| 2574 | pitch_depthbuffer=(data >> 16) & 0xffff; |
| 2575 | //printf("Pitch color %04X zbuffer %04X\n\r",pitch_rendertarget,pitch_depthbuffer); |
| 2576 | countlen--; |
| 2577 | } |
| 2578 | if (maddress == 0x0100) { |
| 2579 | // just temporarily |
| 2580 | if ((data & 0x1f) == 1) { |
| 2581 | data = data >> 5; |
| 2582 | data = data & 0x0ffffff0; |
| 2583 | displayedtarget = (UINT32 *)space.get_write_ptr(data); |
| 2584 | } |
| 2585 | } |
| 2337 | 2586 | if (maddress == 0x0210) { |
| 2338 | 2587 | // framebuffer offset ? |
| 2588 | rendertarget = (UINT32 *)space.get_write_ptr(data); |
| 2589 | //printf("Render target at %08X\n\r",data); |
| 2339 | 2590 | countlen--; |
| 2340 | 2591 | } |
| 2341 | 2592 | if (maddress == 0x0214) { |
| 2342 | 2593 | // zbuffer offset ? |
| 2594 | depthbuffer = (UINT32 *)space.get_write_ptr(data); |
| 2595 | //printf("Depth buffer at %08X\n\r",data); |
| 2596 | if ((data == 0) || (data > 0x7ffffffc)) |
| 2597 | depth_write_enabled = false; |
| 2598 | else if (channel[chanel][subchannel].object.method[0x035c / 4] != 0) |
| 2599 | depth_write_enabled = true; |
| 2600 | else |
| 2601 | depth_write_enabled = false; |
| 2343 | 2602 | countlen--; |
| 2344 | 2603 | } |
| 2345 | 2604 | if (maddress == 0x0300) { |
| r242571 | r242572 | |
| 2357 | 2616 | else |
| 2358 | 2617 | blending_enabled = data != 0; |
| 2359 | 2618 | } |
| 2619 | if (maddress == 0x030c) { |
| 2620 | depth_test_enabled = data != 0; |
| 2621 | } |
| 2622 | if (maddress == 0x0354) { |
| 2623 | depth_function = data; |
| 2624 | } |
| 2625 | if (maddress == 0x035c) { |
| 2626 | UINT32 g = channel[chanel][subchannel].object.method[0x0214 / 4]; |
| 2627 | depth_write_enabled = data != 0; |
| 2628 | if ((g == 0) || (g > 0x7ffffffc)) |
| 2629 | depth_write_enabled = false; |
| 2630 | } |
| 2631 | if (maddress == 0x032c) { |
| 2632 | stencil_test_enabled = data != 0; |
| 2633 | } |
| 2634 | if (maddress == 0x0364) { |
| 2635 | stencil_func = data; |
| 2636 | } |
| 2637 | if (maddress == 0x0368) { |
| 2638 | if (data > 255) |
| 2639 | data = 255; |
| 2640 | stencil_ref = data; |
| 2641 | } |
| 2642 | if (maddress == 0x036c) { |
| 2643 | stencil_mask = data; |
| 2644 | } |
| 2645 | if (maddress == 0x0370) { |
| 2646 | stencil_op_fail = data; |
| 2647 | } |
| 2648 | if (maddress == 0x0374) { |
| 2649 | stencil_op_zfail = data; |
| 2650 | } |
| 2651 | if (maddress == 0x0378) { |
| 2652 | stencil_op_zpass = data; |
| 2653 | } |
| 2360 | 2654 | if (maddress == 0x0344) { |
| 2361 | 2655 | blend_function_source = data; |
| 2362 | 2656 | } |
| r242571 | r242572 | |
| 3285 | 3579 | |
| 3286 | 3580 | UINT32 nv2a_renderer::screen_update_callback(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) |
| 3287 | 3581 | { |
| 3288 | | UINT32 *dst = (UINT32 *)bitmap.raw_pixptr(0, 0); |
| 3289 | | UINT32 *src = (UINT32 *)fb.raw_pixptr(0, 0); |
| 3582 | if (displayedtarget != NULL) { |
| 3583 | bitmap_rgb32 bm(displayedtarget, 640, 480, 640); |
| 3584 | UINT32 *dst = (UINT32 *)bitmap.raw_pixptr(0, 0); |
| 3290 | 3585 | |
| 3291 | | //printf("updatescreen\n\r"); |
| 3292 | | memcpy(dst, src, bitmap.rowbytes()*bitmap.height()); |
| 3586 | //printf("updatescreen %08X\n\r",pcrtc[0x800/4]); |
| 3587 | memcpy(dst, displayedtarget, bitmap.rowbytes()*bitmap.height()); |
| 3588 | } |
| 3293 | 3589 | return 0; |
| 3294 | 3590 | } |
| 3295 | 3591 | |
| r242571 | r242572 | |
| 3372 | 3668 | if (e >= (sizeof(pcrtc) / sizeof(UINT32))) |
| 3373 | 3669 | return; |
| 3374 | 3670 | COMBINE_DATA(pcrtc + e); |
| 3671 | if (e == 0x800 / 4) { |
| 3672 | displayedtarget = (UINT32 *)space.get_read_ptr(data); |
| 3673 | //printf("crtc buffer %08X\n\r", data); |
| 3674 | } |
| 3375 | 3675 | //logerror("NV_2A: write PCRTC[%06X]=%08X\n",offset*4-0x00600000,data & mem_mask); |
| 3376 | 3676 | } |
| 3377 | 3677 | else if ((offset >= 0x00000000 / 4) && (offset < 0x00001000 / 4)) { |