diff --git a/src/device/isapnp.c b/src/device/isapnp.c index 0139eeb23..470147953 100644 --- a/src/device/isapnp.c +++ b/src/device/isapnp.c @@ -137,6 +137,8 @@ isapnp_device_config_changed(isapnp_card_t *card, isapnp_device_t *ld) card->config.mem[i].size = (ld->regs[reg_base + 3] << 16) | (ld->regs[reg_base + 4] << 8); if (ld->regs[reg_base + 2] & 0x01) /* upper limit */ card->config.mem[i].size -= card->config.mem[i].base; + else + card->config.mem[i].size = (card->config.mem[i].size | 0xff) ^ 0xffffffff; } for (uint8_t i = 0; i < 4; i++) { reg_base = (i == 0) ? 0x76 : (0x80 + (16 * i)); @@ -789,10 +791,25 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size) break; } - isapnp_log("ISAPnP: >>%s Memory range %d with %d bytes at %06X-%06X, align %d", - in_df ? ">" : "", mem_range, - *((uint16_t *) &card->rom[i + 10]) << 8, *((uint16_t *) &card->rom[i + 4]) << 8, ((card->rom[i + 3] & 0x4) ? 0 : (*((uint16_t *) &card->rom[i + 4]) << 8)) + (*((uint16_t *) &card->rom[i + 6]) << 8), - (*((uint16_t *) &card->rom[i + 8]) + 1) << 16); + isapnp_log("ISAPnP: >>%s Memory range %d with %d bytes at %06X-%06X to %06X-%06X, align %d", + /* %s */ in_df ? ">" : "", + /* %d */ mem_range, + /* %d */ *((uint16_t *) &card->rom[i + 8]), + /* %06X */ *((uint16_t *) &card->rom[i + 4]) << 8, + /* %06X */ ((card->rom[i + 3] & 0x4) ? + /* High address. */ + (*((uint16_t *) &card->rom[i + 10]) << 8) : + /* Range. */ + (*((uint16_t *) &card->rom[i + 4]) << 8)) + + (*((uint16_t *) &card->rom[i + 10]) << 8), + /* %06X */ *((uint16_t *) &card->rom[i + 6]) << 8, + /* %06X */ ((card->rom[i + 3] & 0x4) ? + /* High address. */ + (*((uint16_t *) &card->rom[i + 10]) << 8) : + /* Range. */ + (*((uint16_t *) &card->rom[i + 6]) << 8)) + + (*((uint16_t *) &card->rom[i + 10]) << 8), + /* %d */ *((uint16_t *) &card->rom[i + 8])); res = 1 << mem_range; mem_range++; } else { @@ -806,9 +823,25 @@ isapnp_update_card_rom(void *priv, uint8_t *rom, uint16_t rom_size) break; } - isapnp_log("ISAPnP: >>%s 32-bit memory range %d with %d bytes at %08X-%08X, align %d", in_df ? ">" : "", mem_range_32, - *((uint32_t *) &card->rom[i + 16]) << 8, *((uint32_t *) &card->rom[i + 4]) << 8, ((card->rom[i + 3] & 0x4) ? 0 : (*((uint32_t *) &card->rom[i + 4]) << 8)) + (*((uint32_t *) &card->rom[i + 8]) << 8), - *((uint32_t *) &card->rom[i + 12])); + isapnp_log("ISAPnP: >>%s 32-bit memory range %d with %d bytes at %08X-%08X, align %d", + /* %s */ in_df ? ">" : "", + /* %d */ mem_range_32, + /* %d */ *((uint32_t *) &card->rom[i + 12]), + /* %08X */ *((uint32_t *) &card->rom[i + 4]), + /* %08X */ ((card->rom[i + 3] & 0x4) ? + /* High address. */ + *((uint32_t *) &card->rom[i + 16]) : + /* Range. */ + *((uint32_t *) &card->rom[i + 4])) + + *((uint32_t *) &card->rom[i + 16]), + /* %08X */ *((uint32_t *) &card->rom[i + 8]), + /* %08X */ ((card->rom[i + 3] & 0x4) ? + /* High address. */ + *((uint32_t *) &card->rom[i + 16]) : + /* Range. */ + *((uint32_t *) &card->rom[i + 8])) + + *((uint32_t *) &card->rom[i + 16]), + /* %d */ *((uint32_t *) &card->rom[i + 12])); res = 1 << (4 + mem_range_32); mem_range_32++; } diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index 3a0b03a9b..a381f67f1 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -294,7 +294,7 @@ fdd_type_invert_densel(int type) int ret; if (drive_types[type].flags & FLAG_PS2) - ret = !!strstr(machine_getname(), "PS/"); + ret = (!!strstr(machine_getname(), "PS/1")) || (!!strstr(machine_getname(), "PS/2")); else ret = drive_types[type].flags & FLAG_INVERT_DENSEL; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 468ac6c63..1b64d7d0d 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -460,6 +460,7 @@ extern int machine_at_mr286_init(const machine_t *); extern int machine_at_neat_init(const machine_t *); extern int machine_at_neat_ami_init(const machine_t *); +extern int machine_at_ataripc4_init(const machine_t *); extern int machine_at_quadt386sx_init(const machine_t *); @@ -926,6 +927,7 @@ extern int machine_xt86_init(const machine_t *); extern int machine_xt_americxt_init(const machine_t *); extern int machine_xt_amixt_init(const machine_t *); +extern int machine_xt_ataripc3_init(const machine_t *); extern int machine_xt_dtk_init(const machine_t *); extern int machine_xt_jukopc_init(const machine_t *); extern int machine_xt_openxt_init(const machine_t *); diff --git a/src/include/86box/vid_voodoo_codegen_x86-64.h b/src/include/86box/vid_voodoo_codegen_x86-64.h index dc0ebce72..e8b7299f2 100644 --- a/src/include/86box/vid_voodoo_codegen_x86-64.h +++ b/src/include/86box/vid_voodoo_codegen_x86-64.h @@ -2157,6 +2157,12 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0xc2); } + addbyte(0xf3); /*MOVQ XMM15(colbfog), XMM0 */ + addbyte(0x44); + addbyte(0x0f); + addbyte(0x7e); + addbyte(0xf8); + if (params->fogMode & FOG_ENABLE) { if (params->fogMode & FOG_CONSTANT) { addbyte(0x66); /*MOVD XMM3, params->fogColor[ESI]*/ @@ -2580,17 +2586,17 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0xef); addbyte(0xe4); break; - case AFUNC_ASATURATE: - addbyte(0x66); /*PMULLW XMM4, XMM11(minus_254)*/ + case AFUNC_ACOLORBEFOREFOG: + addbyte(0x66); /*PMULLW XMM4, XMM15(colbfog)*/ addbyte(0x41); addbyte(0x0f); addbyte(0xd5); - addbyte(0xe3); + addbyte(0xe7); addbyte(0xf3); /*MOVQ XMM5, XMM4*/ addbyte(0x0f); addbyte(0x7e); addbyte(0xec); - addbyte(0x66); /*PADDW XMM4, alookup[1*8]*/ + addbyte(0x66); /*PADDW XMM4, R10(alookup)[1*8]*/ addbyte(0x41); addbyte(0x0f); addbyte(0xfd); @@ -2610,6 +2616,7 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0x71); addbyte(0xd4); addbyte(8); + break; } switch (src_afunc) { @@ -2762,7 +2769,36 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0xef); addbyte(0xc0); break; - case AFUNC_ACOLORBEFOREFOG: + case AFUNC_ASATURATE: + addbyte(0x66); /*PMULLW XMM0, XMM11(minus_254)*/ + addbyte(0x41); + addbyte(0x0f); + addbyte(0xd5); + addbyte(0xc3); + addbyte(0xf3); /*MOVQ XMM5, XMM0*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0xe8); + addbyte(0x66); /*PADDW XMM0, 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; } diff --git a/src/include/86box/vid_voodoo_render.h b/src/include/86box/vid_voodoo_render.h index cd1962430..e88d21dd5 100644 --- a/src/include/86box/vid_voodoo_render.h +++ b/src/include/86box/vid_voodoo_render.h @@ -210,11 +210,10 @@ void voodoo_codegen_close(voodoo_t *voodoo); newdest_g = (dest_g * (255 - dest_a)) / 255; \ newdest_b = (dest_b * (255 - dest_a)) / 255; \ break; \ - case AFUNC_ASATURATE: \ - _a = MIN(src_a, 1 - dest_a); \ - newdest_r = (dest_r * _a) / 255; \ - newdest_g = (dest_g * _a) / 255; \ - newdest_b = (dest_b * _a) / 255; \ + case AFUNC_ACOLORBEFOREFOG: \ + newdest_r = (dest_r * colbfog_r) / 255; \ + newdest_g = (dest_g * colbfog_g) / 255; \ + newdest_b = (dest_b * colbfog_b) / 255; \ break; \ } \ \ @@ -254,8 +253,11 @@ void voodoo_codegen_close(voodoo_t *voodoo); src_g = (src_g * (255 - dest_a)) / 255; \ src_b = (src_b * (255 - dest_a)) / 255; \ break; \ - case AFUNC_ACOLORBEFOREFOG: \ - fatal("AFUNC_ACOLORBEFOREFOG\n"); \ + case AFUNC_ASATURATE: \ + _a = MIN(src_a, 255 - dest_a); \ + src_r = (dest_r * _a) / 255; \ + src_g = (dest_g * _a) / 255; \ + src_b = (dest_b * _a) / 255; \ break; \ } \ \ diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index 36629658f..9c1eb817b 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -212,6 +212,37 @@ machine_at_neat_ami_init(const machine_t *model) return ret; } +// TODO +// Onboard Paradise PVGA1A-JK VGA Graphics +// Data Technology Corporation DTC7187 RLL Controller +int +machine_at_ataripc4_init(const machine_t *model) +{ + int ret; + + ret = bios_load_interleaved("roms/machines/ataripc4/AMI_PC4X_1.7_EVEN.BIN", + "roms/machines/ataripc4/AMI_PC4X_1.7_ODD.BIN", +#if 0 + ret = bios_load_interleaved("roms/machines/ataripc4/ami_pc4x_1.7_even.bin", + "roms/machines/ataripc4/ami_pc4x_1.7_odd.bin", +#endif + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&neat_device); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&keyboard_at_ami_device); + + return ret; +} + int machine_at_px286_init(const machine_t *model) { diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 008acbff2..62466bf91 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -212,6 +212,30 @@ machine_xt_amixt_init(const machine_t *model) return ret; } +// TODO +// Onboard EGA Graphics (NSI Logic EVC315-S on early boards STMicroelectronics EGA on later revisions) +// Adaptec ACB-2072 RLL Controller Card (Optional) +// Atari PCM1 Mouse Support +int +machine_xt_ataripc3_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/ataripc3/AWARD_ATARI_PC_BIOS_3.08.BIN", + 0x000f8000, 32768, 0); +#if 0 + ret = bios_load_linear("roms/machines/ataripc3/c101701-004 308.u61", + 0x000f8000, 0x8000, 0); +#endif + + if (bios_only || !ret) + return ret; + + machine_xt_clone_init(model, 0); + + return ret; +} + int machine_xt_znic_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index f5a0a9d1c..b60d35fd7 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -484,6 +484,45 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + { + .name = "[8088] Atari PC 3", + .internal_name = "ataripc3", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_ataripc3_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_8088, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_FDC, + .ram = { + .min = 64, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .kbc_device = &keyboard_xtclone_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, //&fdc_xt_device, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, { .name = "[8088] Bondwell BW230", .internal_name = "bw230", @@ -3405,6 +3444,45 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + { + .name = "[NEAT] Atari PC 4", + .internal_name = "ataripc4", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_NEAT, + .init = machine_at_ataripc4_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_286, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FDC, + .ram = { + .min = 512, + .max = 8192, + .step = 128 + }, + .nvrmask = 127, + .kbc_device = &keyboard_at_ami_device, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, //&fdc_at_device, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* This has "AMI KEYBOARD BIOS", most likely 'F'. */ { .name = "[NEAT] DataExpert 286", diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index c24f9f8ba..f77370574 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -144,6 +144,54 @@ keyboard_getkeymap() } } +void +win_keyboard_handle(uint32_t scancode, int up, int e0, int e1) +{ + /* If it's not a scan code that starts with 0xE1 */ + if (e1) { + if (scancode == 0x1D) { + scancode = scancode_map[0x100]; /* Translate E1 1D to 0x100 (which would + otherwise be E0 00 but that is invalid + anyway). + Also, take a potential mapping into + account. */ + } else + scancode = 0xFFFF; + if (scancode != 0xFFFF) + keyboard_input(!up, scancode); + } else { + if (e0) + scancode |= 0x100; + + /* Translate the scan code to 9-bit */ + scancode = convert_scan_code(scancode); + + /* Remap it according to the list from the Registry */ + if ((scancode < (sizeof(scancode_map) / sizeof(scancode_map[0]))) && (scancode != scancode_map[scancode])) { + // pclog("Scan code remap: %03X -> %03X\n", scancode, scancode_map[scancode]); + scancode = scancode_map[scancode]; + } + + /* If it's not 0xFFFF, send it to the emulated + keyboard. + We use scan code 0xFFFF to mean a mapping that + has a prefix other than E0 and that is not E1 1D, + which is, for our purposes, invalid. */ + + /* Translate right CTRL to left ALT if the user has so + chosen. */ + if ((scancode == 0x11d) && rctrl_is_lalt) + scancode = 0x038; + + /* Normal scan code pass through, pass it through as is if + it's not an invalid scan code. */ + if (scancode != 0xFFFF) + keyboard_input(!up, scancode); + + main_window->checkFullscreenHotkey(); + } +} + static LRESULT CALLBACK emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { @@ -151,6 +199,9 @@ emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) /* Checks if CTRL was pressed. */ BOOL bCtrlDown = GetAsyncKeyState (VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1); BOOL is_over_window = (GetForegroundWindow() == ((HWND) main_window->winId())); + BOOL ret = TRUE; + + static int last = 0; if (show_second_monitors) for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) { const auto &secondaryRenderer = main_window->renderers[monitor_index]; @@ -158,30 +209,52 @@ emu_LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) (GetForegroundWindow() == ((HWND) secondaryRenderer->winId()))); } - if ((nCode < 0) || (nCode != HC_ACTION)/* || (!mouse_capture && !video_fullscreen)*/ || !is_over_window) + if ((nCode < 0) || (nCode != HC_ACTION) || !is_over_window) return CallNextHookEx(NULL, nCode, wParam, lParam); else if ((lpKdhs->scanCode == 0x01) && (lpKdhs->flags & LLKHF_ALTDOWN) && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) - return TRUE; + ret = TRUE; else if ((lpKdhs->scanCode == 0x01) && bCtrlDown && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) - return TRUE; + ret = TRUE; else if ((lpKdhs->scanCode == 0x0f) && (lpKdhs->flags & LLKHF_ALTDOWN) && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) - return TRUE; + ret = TRUE; else if ((lpKdhs->scanCode == 0x0f) && bCtrlDown && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) - return TRUE; + ret = TRUE; else if ((lpKdhs->scanCode == 0x39) && (lpKdhs->flags & LLKHF_ALTDOWN) && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) - return TRUE; + ret = TRUE; else if ((lpKdhs->scanCode == 0x3e) && (lpKdhs->flags & LLKHF_ALTDOWN) && !(lpKdhs->flags & (LLKHF_UP | LLKHF_EXTENDED))) - return TRUE; + ret = TRUE; else if ((lpKdhs->scanCode == 0x49) && bCtrlDown && !(lpKdhs->flags & LLKHF_UP)) - return TRUE; + ret = TRUE; else if ((lpKdhs->scanCode >= 0x5b) && (lpKdhs->scanCode <= 0x5d) && (lpKdhs->flags & LLKHF_EXTENDED)) - return TRUE; + ret = TRUE; else - return CallNextHookEx(NULL, nCode, wParam, lParam); + ret = CallNextHookEx(NULL, nCode, wParam, lParam); + + if (lpKdhs->scanCode == 0x00000045) { + if ((lpKdhs->flags & LLKHF_EXTENDED) && (lpKdhs->vkCode == 0x00000090)) { + /* NumLock. */ + lpKdhs->flags &= ~LLKHF_EXTENDED; + } else if (!(lpKdhs->flags & LLKHF_EXTENDED) && (lpKdhs->vkCode == 0x00000013)) { + /* Pause - send E1 1D. */ + win_keyboard_handle(0xe1, 0, 0, 0); + win_keyboard_handle(0x1d, LLKHF_UP, 0, 0); + } + } else if (!last && (lpKdhs->scanCode == 0x00000036)) + /* Non-fake right shift. */ + lpKdhs->flags &= ~LLKHF_EXTENDED; + + if (lpKdhs->scanCode == 0x00000236) + last = 1; + else if (last && (lpKdhs->scanCode == 0x00000036)) + last = 0; + + win_keyboard_handle(lpKdhs->scanCode, lpKdhs->flags & LLKHF_UP, lpKdhs->flags & LLKHF_EXTENDED, 0); + + return ret; } #endif @@ -455,6 +528,15 @@ main(int argc, char *argv[]) hook_enabled = 0; } + if (hook_enabled) { + /* Yes, low-level hooks *DO* work with raw input, at least global ones. */ + llhook = SetWindowsHookEx(WH_KEYBOARD_LL, emu_LowLevelKeyboardProc, NULL, 0); + atexit([] () -> void { + if (llhook) + UnhookWindowsHookEx(llhook); + }); + } + /* Setup raw input */ auto rawInputFilter = WindowsRawInputFilter::Register(main_window); if (rawInputFilter) { @@ -507,7 +589,6 @@ main(int argc, char *argv[]) /* Initialize the rendering window, or fullscreen. */ QTimer::singleShot(0, &app, [] { pc_reset_hard_init(); - main_thread = new std::thread(main_thread_fn); /* Set the PAUSE mode depending on the renderer. */ #ifdef USE_VNC @@ -516,18 +597,9 @@ main(int argc, char *argv[]) else #endif plat_pause(0); - }); -#ifdef Q_OS_WINDOWS - if (hook_enabled) { - /* Yes, low-level hooks *DO* work with raw input, at least global ones. */ - llhook = SetWindowsHookEx(WH_KEYBOARD_LL, emu_LowLevelKeyboardProc, NULL, 0); - atexit([] () -> void { - if (llhook) - UnhookWindowsHookEx(llhook); - }); - } -#endif + main_thread = new std::thread(main_thread_fn); + }); const auto ret = app.exec(); cpu_thread_run = 0; diff --git a/src/qt/qt_mediahistorymanager.cpp b/src/qt/qt_mediahistorymanager.cpp index 2acdc8e5b..d548c0779 100644 --- a/src/qt/qt_mediahistorymanager.cpp +++ b/src/qt/qt_mediahistorymanager.cpp @@ -336,16 +336,20 @@ MediaHistoryManager::removeMissingImages(device_index_list_t &device_history) continue; } - char temp[MAX_IMAGE_PATH_LEN -1] = { 0 }; + char temp[MAX_IMAGE_PATH_LEN * 2] = { 0 }; if (path_abs(checked_path.toUtf8().data())) { if (checked_path.length() > (MAX_IMAGE_PATH_LEN - 1)) - fatal("removeMissingImages(): checked_path.length() > 2047\n"); + fatal("removeMissingImages(): checked_path.length() > %i\n", MAX_IMAGE_PATH_LEN - 1); else snprintf(temp, (MAX_IMAGE_PATH_LEN - 1), "%s", checked_path.toUtf8().constData()); - } else - snprintf(temp, (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path, - path_get_slash(usr_path), checked_path.toUtf8().constData()); + } else { + if ((strlen(usr_path) + strlen(path_get_slash(usr_path)) + checked_path.length()) > (MAX_IMAGE_PATH_LEN - 1)) + fatal("removeMissingImages(): Combined absolute path length > %i\n", MAX_IMAGE_PATH_LEN - 1); + else + snprintf(temp, (MAX_IMAGE_PATH_LEN - 1), "%s%s%s", usr_path, + path_get_slash(usr_path), checked_path.toUtf8().constData()); + } path_normalize(temp); QString qstr = QString::fromUtf8(temp); diff --git a/src/qt/qt_winrawinputfilter.cpp b/src/qt/qt_winrawinputfilter.cpp index 2c11a068a..a1da0af61 100644 --- a/src/qt/qt_winrawinputfilter.cpp +++ b/src/qt/qt_winrawinputfilter.cpp @@ -44,6 +44,8 @@ #include <86box/plat.h> #include <86box/86box.h> +extern void win_keyboard_handle(uint32_t scancode, int up, int e0, int e1); + #include #include @@ -64,7 +66,9 @@ WindowsRawInputFilter::Register(MainWindow *window) .hwndTarget = nullptr} }; - if (RegisterRawInputDevices(rid, 2, sizeof(rid[0])) == FALSE) + if (hook_enabled && (RegisterRawInputDevices(&(rid[1]), 1, sizeof(rid[0])) == FALSE)) + return std::unique_ptr(nullptr); + else if (!hook_enabled && (RegisterRawInputDevices(rid, 2, sizeof(rid[0])) == FALSE)) return std::unique_ptr(nullptr); std::unique_ptr inputfilter(new WindowsRawInputFilter(window)); @@ -95,7 +99,10 @@ WindowsRawInputFilter::~WindowsRawInputFilter() .hwndTarget = NULL} }; - RegisterRawInputDevices(rid, 2, sizeof(rid[0])); + if (hook_enabled) + RegisterRawInputDevices(&(rid[1]), 1, sizeof(rid[0])); + else + RegisterRawInputDevices(rid, 2, sizeof(rid[0])); } bool @@ -153,10 +160,8 @@ WindowsRawInputFilter::handle_input(HRAWINPUT input) mouse_handle(raw); break; case RIM_TYPEHID: - { - win_joystick_handle(raw); - break; - } + win_joystick_handle(raw); + break; } } } @@ -166,54 +171,10 @@ WindowsRawInputFilter::handle_input(HRAWINPUT input) void WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) { - USHORT scancode; - RAWKEYBOARD rawKB = raw->data.keyboard; - scancode = rawKB.MakeCode; - /* If it's not a scan code that starts with 0xE1 */ - if ((rawKB.Flags & RI_KEY_E1)) { - if (rawKB.MakeCode == 0x1D) { - scancode = scancode_map[0x100]; /* Translate E1 1D to 0x100 (which would - otherwise be E0 00 but that is invalid - anyway). - Also, take a potential mapping into - account. */ - } else - scancode = 0xFFFF; - if (scancode != 0xFFFF) - keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode); - } else { - if (rawKB.Flags & RI_KEY_E0) - scancode |= 0x100; - - /* Translate the scan code to 9-bit */ - scancode = convert_scan_code(scancode); - - /* Remap it according to the list from the Registry */ - if ((scancode < (sizeof(scancode_map) / sizeof(scancode_map[0]))) && (scancode != scancode_map[scancode])) { - // pclog("Scan code remap: %03X -> %03X\n", scancode, scancode_map[scancode]); - scancode = scancode_map[scancode]; - } - - /* If it's not 0xFFFF, send it to the emulated - keyboard. - We use scan code 0xFFFF to mean a mapping that - has a prefix other than E0 and that is not E1 1D, - which is, for our purposes, invalid. */ - - /* Translate right CTRL to left ALT if the user has so - chosen. */ - if ((scancode == 0x11d) && rctrl_is_lalt) - scancode = 0x038; - - /* Normal scan code pass through, pass it through as is if - it's not an invalid scan code. */ - if (scancode != 0xFFFF) - keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode); - - window->checkFullscreenHotkey(); - } + win_keyboard_handle(rawKB.MakeCode, (rawKB.Flags & RI_KEY_BREAK), + (rawKB.Flags & RI_KEY_E0), (rawKB.Flags & RI_KEY_E1)); } void diff --git a/src/scsi/scsi_aha154x.c b/src/scsi/scsi_aha154x.c index e3f38c4e5..58779e7ac 100644 --- a/src/scsi/scsi_aha154x.c +++ b/src/scsi/scsi_aha154x.c @@ -678,6 +678,7 @@ aha_pnp_config_changed(uint8_t ld, isapnp_device_config_t *config, void *priv) aha_eeprom_save(dev); dev->rom_addr = config->mem[0].base; + aha_log("Base = %08X, Size = %08X\n", config->mem[0].base, config->mem[0].size); if (dev->rom_addr) { mem_mapping_enable(&dev->bios.mapping); aha_log("SCSI BIOS set to: %08X-%08X\n", dev->rom_addr, dev->rom_addr + config->mem[0].size - 1); @@ -869,13 +870,12 @@ aha_setmcode(x54x_t *dev) } aha1542cp_pnp_rom = (uint8_t *) malloc(dev->pnp_len + 7); fseek(fp, dev->pnp_offset, SEEK_SET); - (void) !fread(aha1542cp_pnp_rom, dev->pnp_len, 1, fp); + (void) !fread(aha1542cp_pnp_rom, 4, 1, fp); memset(&(aha1542cp_pnp_rom[4]), 0x00, 5); fseek(fp, dev->pnp_offset + 4, SEEK_SET); (void) !fread(&(aha1542cp_pnp_rom[9]), dev->pnp_len - 4, 1, fp); - /* Even the real AHA-1542CP microcode seem to be flipping bit - 4 to not erroneously indicate there is a range length. */ - aha1542cp_pnp_rom[0x87] |= 0x04; + /* Patch determined from Dizzy's AHA-1542CP PNP ROM dump. */ + aha1542cp_pnp_rom[0x26] = 0x03; /* Insert the terminator and the checksum byte that will later be filled in by the isapnp code. */ aha1542cp_pnp_rom[dev->pnp_len + 5] = 0x79; diff --git a/src/sio/sio_pc87307.c b/src/sio/sio_pc87307.c index 63e19c03d..cb772aa5b 100644 --- a/src/sio/sio_pc87307.c +++ b/src/sio/sio_pc87307.c @@ -34,6 +34,7 @@ #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/sio.h> +#include <86box/plat_fallthrough.h> typedef struct pc87307_t { uint8_t id; @@ -323,8 +324,12 @@ pc87307_write(uint16_t port, uint8_t val, void *priv) } break; case 0x60: + if (dev->regs[0x07] == 0x04) { + val &= 0x03; + } + fallthrough; case 0x62: - dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val & 0x07; + dev->ld_regs[dev->regs[0x07]][dev->cur_reg - 0x30] = val; if ((dev->cur_reg == 0x62) && (dev->regs[0x07] != 0x07)) break; switch (dev->regs[0x07]) { diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index c4f1c2f90..07add5062 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -423,9 +423,9 @@ es1370_calc_sample_rate(es137x_t *dev) dev->calc_sample_rate = 5512; } - dev->calc_sample_rate_synth = 44100 / (1 << ((dev->int_ctrl >> 12) & 3)); - dev->interp_factor_synth = 1. / (double) (1 << ((dev->int_ctrl >> 12) & 3)); - dev->interp_step_synth = (1 << ((dev->int_ctrl >> 12) & 3)); + dev->calc_sample_rate_synth = 44100 / (1 << (((dev->int_ctrl >> 12) & 3) ^ 3)); + dev->interp_factor_synth = 1. / (double) ((1 << ((dev->int_ctrl >> 12) & 3) ^ 3)); + dev->interp_step_synth = (1 << (((dev->int_ctrl >> 12) & 3) ^ 3)); } static void @@ -446,11 +446,13 @@ es137x_reset(void *priv) /* Interrupt/Chip Select Status Register, Address 04H Addressable as longword only */ - if (dev->type >= AUDIOPCI_CT5880) + if (dev->type == AUDIOPCI_ES1370) + dev->int_status = 0x00000060; + else if (dev->type == AUDIOPCI_CT5880) dev->int_status = 0x52080ec0; - else if ((dev->type >= AUDIOPCI_ES1373) && (dev->type != AUDIOPCI_ES1370)) + else if (dev->type == AUDIOPCI_ES1373) dev->int_status = 0x7f080ec0; - else + else /* AUDIOPCI_ES1371 */ dev->int_status = 0x7ffffec0; /* UART Status Register, Address 09H @@ -784,7 +786,7 @@ es137x_inb(uint16_t port, void *priv) break; case 0x03: ret = dev->int_ctrl >> 24; - if ((dev->type < AUDIOPCI_ES1373) && (dev->type != AUDIOPCI_ES1370)) + if (dev->type == AUDIOPCI_ES1371) ret |= 0xfc; break; @@ -857,19 +859,19 @@ es137x_inb(uint16_t port, void *priv) /* S/PDIF Channel Status Control Register, Address 1CH Addressable as byte, word, longword */ case 0x1c: - if ((dev->type >= AUDIOPCI_ES1373) && (dev->type != AUDIOPCI_ES1370)) + if ((dev->type == AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_CT5880)) ret = dev->spdif_chstatus & 0xff; break; case 0x1d: - if ((dev->type >= AUDIOPCI_ES1373) && (dev->type != AUDIOPCI_ES1370)) + if ((dev->type == AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_CT5880)) ret = dev->spdif_chstatus >> 8; break; case 0x1e: - if ((dev->type >= AUDIOPCI_ES1373) && (dev->type != AUDIOPCI_ES1370)) + if ((dev->type == AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_CT5880)) ret = dev->spdif_chstatus >> 16; break; case 0x1f: - if ((dev->type >= AUDIOPCI_ES1373) && (dev->type != AUDIOPCI_ES1370)) + if ((dev->type == AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_CT5880)) ret = dev->spdif_chstatus >> 24; break; @@ -882,10 +884,15 @@ es137x_inb(uint16_t port, void *priv) ret = dev->si_cr >> 8; break; case 0x22: - ret = (dev->si_cr >> 16) | 0x80; + ret = dev->si_cr >> 16; + if (dev->type != AUDIOPCI_ES1370) + ret |= 0x80; break; case 0x23: - ret = 0xff; + if (dev->type == AUDIOPCI_ES1370) + ret = 0x00; + else + ret = 0xff; break; default: @@ -910,7 +917,7 @@ es137x_inw(uint16_t port, void *priv) break; case 0x02: ret = (dev->int_ctrl >> 16) & 0xff0f; - if ((dev->type < AUDIOPCI_ES1373) && (dev->type != AUDIOPCI_ES1370)) + if (dev->type == AUDIOPCI_ES1371) ret |= 0xfc00; break; @@ -935,11 +942,11 @@ es137x_inw(uint16_t port, void *priv) /* S/PDIF Channel Status Control Register, Address 1CH Addressable as byte, word, longword */ case 0x1c: - if ((dev->type >= AUDIOPCI_ES1373) && (dev->type != AUDIOPCI_ES1370)) + if ((dev->type == AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_CT5880)) ret = dev->spdif_chstatus & 0xffff; break; case 0x1e: - if ((dev->type >= AUDIOPCI_ES1373) && (dev->type != AUDIOPCI_ES1370)) + if ((dev->type == AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_CT5880)) ret = dev->spdif_chstatus >> 16; break; @@ -949,7 +956,9 @@ es137x_inw(uint16_t port, void *priv) ret = dev->si_cr & 0xffff; break; case 0x22: - ret = (dev->si_cr >> 16) | 0xff80; + ret = dev->si_cr >> 16; + if (dev->type != AUDIOPCI_ES1370) + ret |= 0xff80; break; /* DAC1 Channel Sample Count Register, Address 24H @@ -1056,14 +1065,16 @@ es137x_inl(uint16_t port, void *priv) /* S/PDIF Channel Status Control Register, Address 1CH Addressable as byte, word, longword */ case 0x1c: - if ((dev->type >= AUDIOPCI_ES1373) || (dev->type != AUDIOPCI_ES1370)) + if ((dev->type == AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_CT5880)) ret = dev->spdif_chstatus; break; /* Serial Interface Control Register, Address 20H Addressable as byte, word, longword */ case 0x20: - ret = dev->si_cr | 0xff800000; + ret = dev->si_cr; + if (dev->type != AUDIOPCI_ES1370) + ret |= 0xff800000; break; /* DAC1 Channel Sample Count Register, Address 24H @@ -1148,11 +1159,11 @@ es137x_outb(uint16_t port, uint8_t val, void *priv) Addressable as longword only, but PCem implements byte access, which must be for a reason */ case 0x06: - if ((dev->type >= AUDIOPCI_ES1373) || (dev->type != AUDIOPCI_ES1370)) + if ((dev->type == AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_CT5880)) dev->int_status = (dev->int_status & 0xff08ffff) | (val << 16); break; case 0x07: - if ((dev->type >= AUDIOPCI_CT5880) || (dev->type != AUDIOPCI_ES1370)) + if (dev->type == AUDIOPCI_CT5880) dev->int_status = (dev->int_status & 0xd2ffffff) | (val << 24); break; @@ -1235,18 +1246,28 @@ es137x_outb(uint16_t port, uint8_t val, void *priv) /* Serial Interface Control Register, Address 20H Addressable as byte, word, longword */ case 0x20: - dev->si_cr = (dev->si_cr & 0xffffff00) | val; + if (dev->type == AUDIOPCI_ES1370) + dev->si_cr = (dev->si_cr & 0xffff00) | val; + else + dev->si_cr = (dev->si_cr & 0xffffff00) | val; break; case 0x21: - dev->si_cr = (dev->si_cr & 0xffff00ff) | (val << 8); + if (dev->type == AUDIOPCI_ES1370) + dev->si_cr = (dev->si_cr & 0xff00ff) | (val << 8); + else + dev->si_cr = (dev->si_cr & 0xffff00ff) | (val << 8); if (!(dev->si_cr & SI_P1_INTR_EN)) dev->int_status &= ~INT_STATUS_DAC1; if (!(dev->si_cr & SI_P2_INTR_EN)) dev->int_status &= ~INT_STATUS_DAC2; + es137x_update_irqs(dev); break; case 0x22: - dev->si_cr = (dev->si_cr & 0xff80ffff) | ((val & 0x7f) << 16); + if (dev->type == AUDIOPCI_ES1370) + dev->si_cr = (dev->si_cr & 0xc0ffff) | ((val & 0x3f) << 16); + else + dev->si_cr = (dev->si_cr & 0xff80ffff) | ((val & 0x7f) << 16); break; default: @@ -1334,7 +1355,11 @@ es137x_outw(uint16_t port, uint16_t val, void *priv) /* Serial Interface Control Register, Address 20H Addressable as byte, word, longword */ case 0x20: - dev->si_cr = (dev->si_cr & 0xffff0000) | val; + if (dev->type == AUDIOPCI_ES1370) + dev->si_cr = (dev->si_cr & 0xff0000) | val; + else + dev->si_cr = (dev->si_cr & 0xffff0000) | val; + if (!(dev->si_cr & SI_P1_INTR_EN)) dev->int_status &= ~INT_STATUS_DAC1; if (!(dev->si_cr & SI_P2_INTR_EN)) @@ -1342,7 +1367,10 @@ es137x_outw(uint16_t port, uint16_t val, void *priv) es137x_update_irqs(dev); break; case 0x22: - dev->si_cr = (dev->si_cr & 0xff80ffff) | ((val & 0x007f) << 16); + if (dev->type == AUDIOPCI_ES1370) + dev->si_cr = (dev->si_cr & 0xc0ffff) | ((val & 0x3f) << 16); + else + dev->si_cr = (dev->si_cr & 0xff80ffff) | ((val & 0x007f) << 16); break; /* DAC1 Channel Sample Count Register, Address 24H @@ -1417,9 +1445,9 @@ es137x_outl(uint16_t port, uint32_t val, void *priv) Addressable as longword only */ case 0x04: audiopci_log("[W] STATUS = %08X\n", val); - if (dev->type >= AUDIOPCI_CT5880) + if (dev->type == AUDIOPCI_CT5880) dev->int_status = (dev->int_status & 0xd208ffff) | (val & 0x2df70000); - else if ((dev->type >= AUDIOPCI_ES1373) && (dev->type != AUDIOPCI_ES1370)) + else if (dev->type == AUDIOPCI_ES1373) dev->int_status = (dev->int_status & 0xff08ffff) | (val & 0x00f70000); break; @@ -1523,7 +1551,10 @@ es137x_outl(uint16_t port, uint32_t val, void *priv) /* Serial Interface Control Register, Address 20H Addressable as byte, word, longword */ case 0x20: - dev->si_cr = (val & 0x007fffff) | 0xff800000; + if (dev->type == AUDIOPCI_ES1370) + dev->si_cr = val & 0x3fffff; + else + dev->si_cr = (val & 0x007fffff) | 0xff800000; if (!(dev->si_cr & SI_P1_INTR_EN)) dev->int_status &= ~INT_STATUS_DAC1; if (!(dev->si_cr & SI_P2_INTR_EN)) @@ -2032,7 +2063,7 @@ es1371_pci_read(int func, int addr, void *priv) return 0x80; /* Maximum latency */ case 0x40: - if ((dev->type >= AUDIOPCI_ES1373) && (dev->type != AUDIOPCI_ES1370)) + if ((dev->type == AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_CT5880)) return dev->subsys_lock; break; @@ -2163,7 +2194,7 @@ es1371_pci_write(int func, int addr, uint8_t val, void *priv) break; case 0x40: - if ((dev->type >= AUDIOPCI_ES1373) && (dev->type != AUDIOPCI_ES1370)) + if ((dev->type == AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_CT5880)) dev->subsys_lock = val; break; @@ -2386,7 +2417,7 @@ es137x_poll(void *priv) es137x_update(dev); if (dev->int_ctrl & INT_DAC1_EN) { - if (((dev->type >= AUDIOPCI_ES1373) && (dev->int_ctrl & INT_DAC1_BYPASS)) || (dev->type == AUDIOPCI_ES1370)) { + if ((((dev->type == AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_CT5880)) && (dev->int_ctrl & INT_DAC1_BYPASS)) || (dev->type == AUDIOPCI_ES1370)) { if ((dev->calc_sample_rate_synth != 44100) && (dev->type == AUDIOPCI_ES1370)) { if ((dev->dac[0].buffer_pos - dev->dac[0].buffer_pos_end) >= 0 && dev->step_synth >= dev->interp_step_synth) es137x_fetch(dev, 0); @@ -2444,7 +2475,7 @@ dac0_count: } if (dev->int_ctrl & INT_DAC2_EN) { - if (((dev->type >= AUDIOPCI_ES1373) && (dev->int_ctrl & INT_DAC2_BYPASS)) || (dev->type == AUDIOPCI_ES1370)) { + if ((((dev->type == AUDIOPCI_ES1373) || (dev->type == AUDIOPCI_CT5880)) && (dev->int_ctrl & INT_DAC2_BYPASS)) || (dev->type == AUDIOPCI_ES1370)) { if ((dev->calc_sample_rate != 44100) && (dev->type == AUDIOPCI_ES1370)) { if ((dev->dac[1].buffer_pos - dev->dac[1].buffer_pos_end) >= 0 && dev->step_pcm >= dev->interp_step) es137x_fetch(dev, 1); @@ -2797,6 +2828,10 @@ static const device_config_t ct5880_config[] = { .description = "SigmaTel STAC9721T (stereo)", .value = AC97_CODEC_STAC9721 }, + { + .description = "TriTech TR28023 / Creative CT1297", + .value = AC97_CODEC_TR28023 + }, { .description = "" } }, .default_int = AC97_CODEC_STAC9708 diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 5054bd8e7..6a91713fb 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -628,6 +628,8 @@ svga_recalctimings(svga_t *svga) int hsyncstart; int hsyncend; #endif + int old_monitor_overscan_x = svga->monitor->mon_overscan_x; + int old_monitor_overscan_y = svga->monitor->mon_overscan_y; svga->vtotal = svga->crtc[6]; svga->dispend = svga->crtc[0x12]; @@ -1009,6 +1011,9 @@ svga_recalctimings(svga_t *svga) svga->dpms_ui = 0; ui_sb_set_text_w(NULL); } + + if (enable_overscan && (svga->monitor->mon_overscan_x != old_monitor_overscan_x || svga->monitor->mon_overscan_y != old_monitor_overscan_y)) + video_force_resize_set_monitor(1, svga->monitor_index); } static void diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index 0c5e5f7bb..4fa27e2e4 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -1095,7 +1095,7 @@ banshee_status(banshee_t *banshee) int fifo_entries = FIFO_ENTRIES; int swap_count = voodoo->swap_count; int written = voodoo->cmd_written + voodoo->cmd_written_fifo; - int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) || voodoo->render_voodoo_busy[0] || voodoo->render_voodoo_busy[1] || voodoo->render_voodoo_busy[2] || voodoo->render_voodoo_busy[3] || voodoo->voodoo_busy; + int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) || (voodoo->cmdfifo_depth_rd_2 != voodoo->cmdfifo_depth_wr_2) || voodoo->render_voodoo_busy[0] || voodoo->render_voodoo_busy[1] || voodoo->render_voodoo_busy[2] || voodoo->render_voodoo_busy[3] || voodoo->voodoo_busy; uint32_t ret = 0; if (fifo_entries < 0x20) @@ -1117,6 +1117,9 @@ banshee_status(banshee_t *banshee) if (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) ret |= (1 << 11); + if (voodoo->cmdfifo_depth_rd_2 != voodoo->cmdfifo_depth_wr_2) + ret |= (1 << 12); + if (!voodoo->voodoo_busy) voodoo_wake_fifo_thread(voodoo); diff --git a/src/video/vid_voodoo_fb.c b/src/video/vid_voodoo_fb.c index 5ae26b4c5..ddf68360f 100644 --- a/src/video/vid_voodoo_fb.c +++ b/src/video/vid_voodoo_fb.c @@ -252,6 +252,9 @@ voodoo_fb_writew(uint32_t addr, uint16_t val, void *priv) { rgba8_t write_data = colour_data; uint16_t new_depth = depth_data; + int colbfog_r = 0; + int colbfog_g = 0; + int colbfog_b = 0; if (params->fbzMode & FBZ_DEPTH_ENABLE) { uint16_t old_depth = *(uint16_t *) (&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]); @@ -262,6 +265,10 @@ voodoo_fb_writew(uint32_t addr, uint16_t val, void *priv) if ((params->fbzMode & FBZ_CHROMAKEY) && write_data.r == params->chromaKey_r && write_data.g == params->chromaKey_g && write_data.b == params->chromaKey_b) goto skip_pixel; + colbfog_r = write_data.r; + colbfog_g = write_data.g; + colbfog_b = write_data.b; + if (params->fogMode & FOG_ENABLE) { int32_t z = new_depth << 12; int64_t w_depth = (int64_t) (int32_t) new_depth; @@ -438,6 +445,9 @@ voodoo_fb_writel(uint32_t addr, uint32_t val, void *priv) for (int c = 0; c < count; c++) { rgba8_t write_data = colour_data[c]; uint16_t new_depth = depth_data[c]; + int colbfog_r = 0; + int colbfog_g = 0; + int colbfog_b = 0; if (params->fbzMode & FBZ_DEPTH_ENABLE) { uint16_t old_depth = *(uint16_t *) (&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]); @@ -448,6 +458,10 @@ voodoo_fb_writel(uint32_t addr, uint32_t val, void *priv) if ((params->fbzMode & FBZ_CHROMAKEY) && write_data.r == params->chromaKey_r && write_data.g == params->chromaKey_g && write_data.b == params->chromaKey_b) goto skip_pixel; + colbfog_r = write_data.r; + colbfog_g = write_data.g; + colbfog_b = write_data.b; + if (params->fogMode & FOG_ENABLE) { int32_t z = new_depth << 12; int64_t w_depth = new_depth; diff --git a/src/video/vid_voodoo_render.c b/src/video/vid_voodoo_render.c index 0f31fbc9f..d8f812f7f 100644 --- a/src/video/vid_voodoo_render.c +++ b/src/video/vid_voodoo_render.c @@ -967,6 +967,9 @@ voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t * int src_g = 0; int src_b = 0; int src_a = 0; + int colbfog_r = 0; + int colbfog_g = 0; + int colbfog_b = 0; int msel_r; int msel_g; int msel_b; @@ -1263,6 +1266,10 @@ voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t * if (cca_invert_output) src_a ^= 0xff; + colbfog_r = src_r; + colbfog_g = src_g; + colbfog_b = src_b; + if (params->fogMode & FOG_ENABLE) APPLY_FOG(src_r, src_g, src_b, state->z, state->ia, state->w);