diff --git a/src/include/86box/vid_voodoo_codegen_x86-64.h b/src/include/86box/vid_voodoo_codegen_x86-64.h index 8aba3e5b5..67a5cae2c 100644 --- a/src/include/86box/vid_voodoo_codegen_x86-64.h +++ b/src/include/86box/vid_voodoo_codegen_x86-64.h @@ -2407,6 +2407,27 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, } if (params->alphaMode & (1 << 4)) { + if (params->fbzMode & FBZ_ALPHA_ENABLE) { + addbyte(0x8b); /*MOV EBX, state->x[EDI]*/ + addbyte(0x9f); + if (params->aux_tiled) + addlong(offsetof(voodoo_state_t, x_tiled)); + else + addlong(offsetof(voodoo_state_t, x)); + addbyte(0x48); /*MOV RCX, aux_mem[RDI]*/ + addbyte(0x8b); + addbyte(0x8f); + addlong(offsetof(voodoo_state_t, aux_mem)); + addbyte(0x0f); /*MOVZX EBX, [ECX+EBX*2]*/ + addbyte(0xb7); + addbyte(0x1c); + addbyte(0x59); + } else { + addbyte(0x48); /*MOV RBX, 0xff*/ + addbyte(0xc7); + addbyte(0xc3); + addlong(0xff); + } addbyte(0x49); /*MOV R8, rgb565*/ addbyte(0xb8); addquad((uintptr_t) rgb565); @@ -2422,6 +2443,8 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addlong(offsetof(voodoo_state_t, fb_mem)); addbyte(0x01); /*ADD EDX, EDX*/ addbyte(0xd2); + addbyte(0x01); /*ADD EBX, EBX*/ + addbyte(0xdb); addbyte(0x0f); /*MOVZX EAX, [RBP+RAX*2]*/ addbyte(0xb7); addbyte(0x44); @@ -2516,6 +2539,36 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(8); break; case AFUNC_ADST_ALPHA: + addbyte(0x66); /*PMULLW XMM4, R10(alookup)[EBX*8]*/ + addbyte(0x41); + addbyte(0x0f); + addbyte(0xd5); + addbyte(0x24); + addbyte(0xda); + addbyte(0xf3); /*MOVQ XMM5, XMM4*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0xec); + addbyte(0x66); /*PADDW XMM4, R10(alookup)[1*8]*/ + addbyte(0x41); + addbyte(0x0f); + addbyte(0xfd); + addbyte(0x62); + addbyte(8 * 2); + addbyte(0x66); /*PSRLW XMM5, 8*/ + addbyte(0x0f); + addbyte(0x71); + addbyte(0xd5); + addbyte(8); + addbyte(0x66); /*PADDW XMM4, XMM5*/ + addbyte(0x0f); + addbyte(0xfd); + addbyte(0xe5); + addbyte(0x66); /*PSRLW XMM4, 8*/ + addbyte(0x0f); + addbyte(0x71); + addbyte(0xd4); + addbyte(8); break; case AFUNC_AONE: break; @@ -2591,10 +2644,36 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(8); break; case AFUNC_AOMDST_ALPHA: - addbyte(0x66); /*PXOR XMM4, XMM4*/ + addbyte(0x66); /*PMULLW XMM4, R11(aminuslookup)[EBX*8]*/ + addbyte(0x41); addbyte(0x0f); - addbyte(0xef); - addbyte(0xe4); + addbyte(0xd5); + addbyte(0x24); + addbyte(0xdb); + addbyte(0xf3); /*MOVQ XMM5, XMM4*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0xec); + addbyte(0x66); /*PADDW XMM4, R10(alookup)[1*8]*/ + addbyte(0x41); + addbyte(0x0f); + addbyte(0xfd); + addbyte(0x62); + addbyte(8 * 2); + addbyte(0x66); /*PSRLW XMM5, 8*/ + addbyte(0x0f); + addbyte(0x71); + addbyte(0xd5); + addbyte(8); + addbyte(0x66); /*PADDW XMM4, XMM5*/ + addbyte(0x0f); + addbyte(0xfd); + addbyte(0xe5); + addbyte(0x66); /*PSRLW XMM4, 8*/ + addbyte(0x0f); + addbyte(0x71); + addbyte(0xd4); + addbyte(8); break; case AFUNC_ACOLORBEFOREFOG: addbyte(0x66); /*PMULLW XMM4, XMM15(colbfog)*/ @@ -2699,6 +2778,36 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(8); break; case AFUNC_ADST_ALPHA: + addbyte(0x66); /*PMULLW XMM0, R10(alookup)[EBX*8]*/ + addbyte(0x41); + addbyte(0x0f); + addbyte(0xd5); + addbyte(0x04); + addbyte(0xda); + addbyte(0xf3); /*MOVQ XMM5, XMM0*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0xe8); + addbyte(0x66); /*PADDW XMM0, R10(alookup)[1*8]*/ + addbyte(0x41); + addbyte(0x0f); + addbyte(0xfd); + addbyte(0x42); + addbyte(8 * 2); + addbyte(0x66); /*PSRLW XMM5, 8*/ + addbyte(0x0f); + addbyte(0x71); + addbyte(0xd5); + addbyte(8); + addbyte(0x66); /*PADDW XMM0, XMM5*/ + addbyte(0x0f); + addbyte(0xfd); + addbyte(0xc5); + addbyte(0x66); /*PSRLW XMM0, 8*/ + addbyte(0x0f); + addbyte(0x71); + addbyte(0xd0); + addbyte(8); break; case AFUNC_AONE: break; @@ -2774,17 +2883,12 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(8); break; case AFUNC_AOMDST_ALPHA: - addbyte(0x66); /*PXOR XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0xef); - addbyte(0xc0); - break; - case AFUNC_ASATURATE: - addbyte(0x66); /*PMULLW XMM0, XMM11(minus_254)*/ + addbyte(0x66); /*PMULLW XMM0, R11(aminuslookup)[EBX*8]*/ addbyte(0x41); addbyte(0x0f); addbyte(0xd5); - addbyte(0xc3); + addbyte(0x04); + addbyte(0xdb); addbyte(0xf3); /*MOVQ XMM5, XMM0*/ addbyte(0x0f); addbyte(0x7e); @@ -2810,6 +2914,51 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0xd0); addbyte(8); break; + case AFUNC_ASATURATE: + addbyte(0x89); /* MOV EAX, EBX */ + addbyte(0xd8); + addbyte(0xd1); /* SHR EAX, 1 */ + addbyte(0xe8); + addbyte(0x34); /* XOR AL, 0xFF */ + addbyte(0xFF); + addbyte(0xd1); /* SHL EAX, 1 */ + addbyte(0xe0); + addbyte(0x39); /* CMP EDX, EAX */ + addbyte(0xc2); + addbyte(0x0f); /* CMOVB EAX, EDX */ + addbyte(0x42); + addbyte(0xc2); + addbyte(0x66); /*PMULLW XMM0, R10(alookup)[EAX*8]*/ + addbyte(0x41); + addbyte(0x0f); + addbyte(0xd5); + addbyte(0x04); + addbyte(0xc2); + addbyte(0xf3); /*MOVQ XMM5, XMM0*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0xe8); + addbyte(0x66); /*PADDW XMM0, R10(alookup)[1*8]*/ + addbyte(0x41); + addbyte(0x0f); + addbyte(0xfd); + addbyte(0x42); + addbyte(8 * 2); + addbyte(0x66); /*PSRLW XMM5, 8*/ + addbyte(0x0f); + addbyte(0x71); + addbyte(0xd5); + addbyte(8); + addbyte(0x66); /*PADDW XMM0, XMM5*/ + addbyte(0x0f); + addbyte(0xfd); + addbyte(0xc5); + addbyte(0x66); /*PSRLW XMM0, 8*/ + addbyte(0x0f); + addbyte(0x71); + addbyte(0xd0); + addbyte(8); + break; } addbyte(0x66); /*PADDW XMM0, XMM4*/ @@ -2821,6 +2970,48 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0x0f); addbyte(0x67); addbyte(0xc0); + + addbyte(0x31); /*XOR EAX, EAX */ + addbyte(0xc0); + + if (dest_aafunc == 4) { + addbyte(0xc1); /*SHL EBX, 0x7*/ + addbyte(0xe3); + addbyte(0x07); + addbyte(0x01); /*ADD EAX, EBX*/ + addbyte(0xd8); + } + + if (src_aafunc == 4) { + addbyte(0xc1); /*SHL EDX, 0x7*/ + addbyte(0xe2); + addbyte(0x07); + addbyte(0x01); /*ADD EAX, EDX*/ + addbyte(0xd0); + } + + addbyte(0xc1); /* SHR EAX, 8 */ + addbyte(0xc8); + addbyte(0x08); + addbyte(0x89); /* MOV EDX, EAX */ + addbyte(0xC2); + } + + if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_ALPHA_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_ALPHA_ENABLE)) { + addbyte(0x8b); /*MOV EAX, state->x[EDI]*/ + addbyte(0x87); + if (params->aux_tiled) + addlong(offsetof(voodoo_state_t, x_tiled)); + else + addlong(offsetof(voodoo_state_t, x)); + addbyte(0x48); /*MOV RSI, aux_mem*/ + addbyte(0x8b); + addbyte(0xb7); + addlong(offsetof(voodoo_state_t, aux_mem)); + addbyte(0x66); /*MOV [ESI+EAX*2], DX*/ + addbyte(0x89); + addbyte(0x14); + addbyte(0x46); } addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ @@ -2969,7 +3160,8 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0x56); } - if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) { + + if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE) && !(params->fbzMode & FBZ_ALPHA_ENABLE)) { addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ addbyte(0x97); if (params->aux_tiled) @@ -3237,12 +3429,6 @@ voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *stat voodoo_x86_data_t *voodoo_x86_data = voodoo->codegen_data; voodoo_x86_data_t *data; - if (params->fbzMode & FBZ_ALPHA_ENABLE) { - // Lands of Lore III relies on the alpha buffer functionality to create its transparent textures. - // Fallback to interpreter. - return NULL; - } - for (uint8_t c = 0; c < 8; c++) { data = &voodoo_x86_data[odd_even + c * 4]; //&voodoo_x86_data[odd_even][b]; diff --git a/src/qt/qt_vmmanager_main.cpp b/src/qt/qt_vmmanager_main.cpp index f4b1984dc..86c2cf904 100644 --- a/src/qt/qt_vmmanager_main.cpp +++ b/src/qt/qt_vmmanager_main.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -404,7 +405,12 @@ illegal_chars: ui->listView->setCurrentIndex(first_index); } - connect(ui->listView, &QListView::activated, this, &VMManagerMain::startButtonPressed); + // Connect double-click to start VM + connect(ui->listView, &QListView::doubleClicked, this, &VMManagerMain::startButtonPressed); + + // Connect Enter key to start VM + auto enterShortcut = new QShortcut(QKeySequence(Qt::Key_Return), ui->listView); + connect(enterShortcut, &QShortcut::activated, this, &VMManagerMain::startButtonPressed); // Load and apply settings loadSettings();