From ee60f5ccde2facf0ec8df0a6b031019b66a5fe84 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 13 May 2012 14:01:28 +0300 Subject: [PATCH] 2420b1 --- akiko.cpp | 249 ++++++++++++-------- cfgfile.cpp | 2 +- custom.cpp | 145 ++++++++---- drawing.cpp | 260 +++++++++++++-------- genlinetoscr.cpp | 51 ++-- hardfile.cpp | 12 +- include/drawing.h | 1 + include/gui.h | 3 +- include/options.h | 3 +- od-win32/direct3d.cpp | 5 +- od-win32/fsdb_mywin32.cpp | 7 +- od-win32/resources/resource | 5 +- od-win32/resources/winuae.rc | 44 ++-- od-win32/resources/winuae_minimal.rc | 29 ++- od-win32/win32.cpp | 10 +- od-win32/win32.h | 8 +- od-win32/win32_scaler.cpp | 38 ++- od-win32/win32gfx.cpp | 131 ++++++++--- od-win32/win32gui.cpp | 49 ++-- od-win32/winuae_msvc10/winuae_msvc.vcxproj | 8 +- od-win32/winuaechangelog.txt | 32 ++- statusline.cpp | 2 +- 22 files changed, 711 insertions(+), 383 deletions(-) diff --git a/akiko.cpp b/akiko.cpp index 8da30cdb..5610b396 100644 --- a/akiko.cpp +++ b/akiko.cpp @@ -444,6 +444,7 @@ static uae_u32 cdrom_pbx; static uae_u8 cdcomtxinx; /* 0x19 */ static uae_u8 cdcomrxinx; /* 0x1a */ static uae_u8 cdcomtxcmp; /* 0x1d */ +static uae_u8 cdcomrxcmp; /* 0x1f */ static uae_u8 cdrom_result_buffer[32]; static uae_u8 cdrom_command_buffer[32]; static uae_u8 cdrom_command; @@ -456,7 +457,7 @@ static uae_u8 qcode_buf[SUBQ_SIZE]; static int qcode_valid; static int cdrom_disk, cdrom_paused, cdrom_playing, cdrom_audiostatus; -static int cdrom_command_active, cdrom_command_startdelay, cdrom_command_idle; +static int cdrom_command_active, cdrom_command_idle; static int cdrom_command_length; static int cdrom_checksum_error, cdrom_unknown_command; static int cdrom_data_offset, cdrom_speed, cdrom_sector_counter; @@ -464,10 +465,10 @@ static int cdrom_current_sector, cdrom_seek_delay; static int cdrom_data_end; static int cdrom_audiotimeout; static int cdrom_led; -static int cdrom_dosomething; -static int cdrom_receive_started; +static int cdrom_receive_length, cdrom_receive_offset; static int cdrom_muted; static int cd_initialized; +static int cdrom_tx_dma_delay; static uae_u8 *sector_buffer_1, *sector_buffer_2; static int sector_buffer_sector_1, sector_buffer_sector_2; @@ -572,7 +573,7 @@ static int statusfunc (int status) cdrom_playing = 1; cdrom_audiotimeout = 1; } - if (cdrom_playing && status != AUDIO_STATUS_IN_PROGRESS && status != AUDIO_STATUS_PAUSED) { + if (cdrom_playing && status != AUDIO_STATUS_IN_PROGRESS && status != AUDIO_STATUS_PAUSED && status != AUDIO_STATUS_NOT_SUPPORTED) { cdrom_audiotimeout = -1; } } @@ -770,48 +771,76 @@ static void sys_cddev_close (void) } -static int command_lengths[] = { 1,2,1,1,12,2,1,1,4,1,-1,-1,-1,-1,-1,-1 }; +static int command_lengths[] = { 1,2,1,1,12,2,1,1,4,1,2,-1,-1,-1,-1,-1 }; static int cdrom_start_return_data (int len) { - if (cdrom_receive_started > 0) + if (cdrom_receive_length > 0) return 0; if (len <= 0) return -1; - cdrom_receive_started = len; + cdrom_receive_length = len; + cdrom_receive_offset = -1; return 1; } +/* + RX DMA channel writes bytes to memory if DMA enabled, cdcomrxinx != cdcomrxcmp + and there is data available from CDROM firmware code. + + Triggers CDINTERRUPT_RXDMADONE and stops transfer (even if there is + more data available) when cdcomrxinx matches cdcomrxcmp +*/ + static void cdrom_return_data (void) { uae_u32 cmd_buf = cdrx_address; int i; uae_u8 checksum; - int len = cdrom_receive_started; - if (!len) + if (!cdrom_receive_length) return; if (!(cdrom_flags & CDFLAG_RXD)) return; + if (cdcomrxinx == cdcomrxcmp) + return; + + #if AKIKO_DEBUG_IO_CMD + write_log (_T("OUT IDX=0x%02X-0x%02X LEN=%d:"), cdcomrxinx, cdcomrxcmp, cdrom_receive_length); + #endif + + if (cdrom_receive_offset < 0) { + checksum = 0xff; + for (i = 0; i < cdrom_receive_length; i++) { + checksum -= cdrom_result_buffer[i]; + #if AKIKO_DEBUG_IO_CMD + write_log (_T("%02X "), cdrom_result_buffer[i]); + #endif + } #if AKIKO_DEBUG_IO_CMD - write_log (_T("OUT:")); + write_log (_T("(%02X)\n"), checksum); #endif - checksum = 0xff; - for (i = 0; i < len; i++) { - checksum -= cdrom_result_buffer[i]; - put_byte (cmd_buf + ((cdcomrxinx + i) & 0xff), cdrom_result_buffer[i]); + cdrom_result_buffer[cdrom_receive_length++] = checksum; + cdrom_receive_offset = 0; + } else { #if AKIKO_DEBUG_IO_CMD - write_log (_T("%02X "), cdrom_result_buffer[i]); + write_log (_T("\n")); #endif } - put_byte (cmd_buf + ((cdcomrxinx + len) & 0xff), checksum); + while (cdrom_receive_offset < cdrom_receive_length && cdcomrxinx != cdcomrxcmp) { + put_byte (cmd_buf + cdcomrxinx, cdrom_result_buffer[cdrom_receive_offset]); + cdcomrxinx++; + cdrom_receive_offset++; + } + if (cdcomrxinx == cdcomrxcmp) { + set_status (CDINTERRUPT_RXDMADONE); #if AKIKO_DEBUG_IO_CMD - write_log (_T("(%02X)\n"), checksum); + write_log (L"RXDMADONE %d/%d\n", cdrom_receive_offset, cdrom_receive_length); #endif - cdcomrxinx += len + 1; - cdcomrxinx &= 0xff; - set_status (CDINTERRUPT_RXDMADONE); - cdrom_receive_started = 0; + } + + if (cdrom_receive_offset == cdrom_receive_length) + cdrom_receive_length = 0; } static int cdrom_command_led (void) @@ -858,18 +887,22 @@ static int cdrom_command_status (void) return 20; } -/* return one TOC entry */ +/* return one TOC entry, each TOC entry repeats 3 times */ +#define TOC_REPEAT 3 static int cdrom_return_toc_entry (void) { cdrom_result_buffer[0] = 6; +#if AKIKO_DEBUG_IO_CMD + write_log (_T("CD32: TOC entry %d/%d\n"), cdrom_toc_counter / TOC_REPEAT, cdrom_toc_cd_buffer.points); +#endif if (cdrom_toc_cd_buffer.points == 0) { cdrom_result_buffer[1] = CDS_ERROR; return 15; } cdrom_result_buffer[1] = 0; - memcpy (cdrom_result_buffer + 2, cdrom_toc_buffer + cdrom_toc_counter * 13, 13); + memcpy (cdrom_result_buffer + 2, cdrom_toc_buffer + (cdrom_toc_counter / TOC_REPEAT) * 13, 13); cdrom_toc_counter++; - if (cdrom_toc_counter >= cdrom_toc_cd_buffer.points) + if (cdrom_toc_counter / TOC_REPEAT >= cdrom_toc_cd_buffer.points) cdrom_toc_counter = -1; return 15; } @@ -1016,6 +1049,14 @@ static int cdrom_command_subq (void) return 15; } +/* + TX DMA reads bytes from memory and sends them to + CDROM hardware if TX DMA enabled, CDROM data transfer + DMA not enabled and cdcomtxinx != cdcomtx. + + CDINTERRUPT_TXDMADONE triggered when cdromtxinx matches cdcomtx. +*/ + static void cdrom_run_command (void) { int i, cmd_len; @@ -1024,73 +1065,93 @@ static void cdrom_run_command (void) if (!(cdrom_flags & CDFLAG_TXD)) return; - if (cdrom_command_startdelay) + if ((cdrom_flags & CDFLAG_ENABLE)) return; - for (;;) { - if (cdrom_command_active) - return; - if (cdcomtxinx == cdcomtxcmp) - return; - cdrom_command = get_byte (cdtx_address + cdcomtxinx); -#if 1 - if ((cdrom_command & 0xf0) == 0) { - cdcomtxinx = (cdcomtxinx + 1) & 0xff; - return; - } -#endif - cdrom_checksum_error = 0; - cdrom_unknown_command = 0; + if (cdrom_command_active) + return; + if (cdrom_receive_length) + return; + if (cdcomtxinx == cdcomtxcmp) + return; + if (cdrom_tx_dma_delay > 0) + return; + + cdrom_command = get_byte (cdtx_address + cdcomtxinx); + + if (cdrom_command == 0) { + cdcomtxinx++; + return; + } - cmd_len = command_lengths[cdrom_command & 0x0f]; - if (cmd_len < 0) { + cdrom_checksum_error = 0; + cdrom_unknown_command = 0; + + cmd_len = command_lengths[cdrom_command & 0x0f]; + if (cmd_len < 0) { #if AKIKO_DEBUG_IO_CMD - write_log (_T("unknown command %x\n"), cdrom_command & 0x0f); + write_log (_T("unknown command %x\n"), cdrom_command & 0x0f); #endif - cdrom_unknown_command = 1; - cdrom_command_active = 1; - cdrom_command_length = 1; - set_status (CDINTERRUPT_TXDMADONE); - return; - } + cdrom_unknown_command = 1; + cdrom_command_active = 1; + cdrom_command_length = 1; + set_status (CDINTERRUPT_TXDMADONE); + return; + } #if AKIKO_DEBUG_IO_CMD - write_log (_T("IN:")); + write_log (_T("IN CMD=%02X IDX=0x%02X-0x%02X LEN=%d:"), cdrom_command & 0x0f, cdcomtxinx, cdcomtxcmp, cmd_len); #endif - checksum = 0; - for (i = 0; i < cmd_len + 1; i++) { - cdrom_command_buffer[i] = get_byte (cdtx_address + ((cdcomtxinx + i) & 0xff)); - checksum += cdrom_command_buffer[i]; + checksum = 0; + for (i = 0; i < cmd_len + 1; i++) { + cdrom_command_buffer[i] = get_byte (cdtx_address + ((cdcomtxinx + i) & 0xff)); + checksum += cdrom_command_buffer[i]; #if AKIKO_DEBUG_IO_CMD - if (i == cmd_len) - write_log (_T("(%02X) "), cdrom_command_buffer[i]); // checksum - else - write_log (_T("%02X "), cdrom_command_buffer[i]); + if (i == cmd_len) + write_log (_T("(%02X) "), cdrom_command_buffer[i]); // checksum + else + write_log (_T("%02X "), cdrom_command_buffer[i]); #endif - } - if (checksum != 0xff) { + } + if (checksum != 0xff) { #if AKIKO_DEBUG_IO_CMD - write_log (_T(" checksum error")); + write_log (_T(" checksum error")); #endif - cdrom_checksum_error = 1; - } + cdrom_checksum_error = 1; + //activate_debugger (); + } #if AKIKO_DEBUG_IO_CMD - write_log (_T("\n")); + write_log (_T("\n")); #endif - cdrom_command_active = 1; - cdrom_command_length = cmd_len; - set_status (CDINTERRUPT_TXDMADONE); - return; - } + cdrom_command_active = 1; + cdrom_command_length = cmd_len; + set_status (CDINTERRUPT_TXDMADONE); } static void cdrom_run_command_run (void) { int len; - cdcomtxinx = (cdcomtxinx + cdrom_command_length + 1) & 0xff; + cdcomtxinx = cdcomtxinx + cdrom_command_length + 1; memset (cdrom_result_buffer, 0, sizeof (cdrom_result_buffer)); + + if (cdrom_checksum_error || cdrom_unknown_command) { + cdrom_result_buffer[0] = (cdrom_command & 0xf0) | 5; + if (cdrom_checksum_error) + cdrom_result_buffer[1] |= CH_ERR_CHECKSUM; + else if (cdrom_unknown_command) + cdrom_result_buffer[1] |= CH_ERR_BADCOMMAND; + len = 2; + cdrom_start_return_data (len); + return; + } + + switch (cdrom_command & 0x0f) { + case 0: + len = 1; + cdrom_result_buffer[0] = cdrom_command; + break; case 1: len = cdrom_command_stop (); break; @@ -1104,7 +1165,6 @@ static void cdrom_run_command_run (void) len = cdrom_command_multi (); break; case 5: - cdrom_dosomething = 1; // this is a hack len = cdrom_command_led (); break; case 6: @@ -1119,8 +1179,6 @@ static void cdrom_run_command_run (void) } if (len == 0) return; - if (cdrom_checksum_error || cdrom_unknown_command) - cdrom_result_buffer[1] |= 0x80; cdrom_start_return_data (len); } @@ -1174,8 +1232,8 @@ static void cdrom_run_read (void) if (sector_buffer_info_1[sec] != 0xff) sector_buffer_info_1[sec]--; #if AKIKO_DEBUG_IO_CMD - write_log (_T("read sector=%d, scnt=%d -> %d. %d %08X\n"), - cdrom_data_offset, cdrom_sector_counter, sector, seccnt, cdrom_addressdata + seccnt * 4096); + write_log (_T("pbx=%04x sec=%d, scnt=%d -> %d. %d (%04x) %08X\n"), + cdrom_pbx, cdrom_data_offset, cdrom_sector_counter, sector, seccnt, 1 << seccnt, cdrom_addressdata + seccnt * 4096); #endif } else { inc = 0; @@ -1186,11 +1244,11 @@ static void cdrom_run_read (void) static int lastmediastate = 0; -static void akiko_handler (void) +static void akiko_handler (bool framesync) { if (unitnum < 0) return; - if (!cd_initialized || cdrom_receive_started) + if (!cd_initialized || cdrom_receive_length) return; if (mediachanged) { @@ -1207,7 +1265,7 @@ static void akiko_handler (void) cdrom_audiotimeout--; if (cdrom_audiotimeout == 1) { // play start cdrom_playing = 1; - cdrom_start_return_data (cdrom_playend_notify (0)); + ;//cdrom_start_return_data (cdrom_playend_notify (0)); cdrom_audiotimeout = 0; } if (cdrom_audiotimeout == -1) { // play finished (or disk end) @@ -1228,10 +1286,11 @@ static void akiko_handler (void) cdrom_audiotimeout = 0; } - if (cdrom_toc_counter >= 0 && !cdrom_command_active && cdrom_dosomething) { - cdrom_start_return_data (cdrom_return_toc_entry ()); - cdrom_dosomething--; - return; + /* one toc entry / frame */ + if (cdrom_toc_counter >= 0 && !cdrom_command_active) { + if (cdrom_start_return_data (-1)) { + cdrom_start_return_data (cdrom_return_toc_entry ()); + } } } @@ -1259,13 +1318,11 @@ static void akiko_internal (void) void AKIKO_hsync_handler (void) { + bool framesync = false; + if (!currprefs.cs_cd32cd || !akiko_inited) return; - if (cdrom_command_startdelay > 0) { - cdrom_command_startdelay--; - } - static float framecounter; framecounter--; if (framecounter <= 0) { @@ -1275,8 +1332,12 @@ void AKIKO_hsync_handler (void) cdrom_seek_delay--; } framecounter += (float)maxvpos * vblank_hz / (75.0 * cdrom_speed); + framesync = true; } + if (cdrom_tx_dma_delay > 0) + cdrom_tx_dma_delay--; + subcodecounter--; if (subcodecounter <= 0) { if ((cdrom_flags & CDFLAG_SUBCODE) && cdrom_playing && subcodebufferoffset != subcodebufferoffsetw) { @@ -1296,7 +1357,7 @@ void AKIKO_hsync_handler (void) if (subcodebufferoffset >= MAX_SUBCODEBUFFER) subcodebufferoffset -= MAX_SUBCODEBUFFER; set_status (CDINTERRUPT_SUBCODE); - write_log (_T("*")); + //write_log (_T("*")); } uae_sem_post (&sub_sem); } @@ -1309,7 +1370,7 @@ void AKIKO_hsync_handler (void) mediacheckcounter--; akiko_internal (); - akiko_handler (); + akiko_handler (framesync); } /* cdrom data buffering thread */ @@ -1502,6 +1563,9 @@ static uae_u32 akiko_bget2 (uaecptr addr, int msg) case 0x1a: v = cdcomrxinx; break; + case 0x1f: + v = cdcomrxcmp; + break; case 0x20: case 0x21: v = akiko_get_long (cdrom_pbx, addr - 0x20 + 2); @@ -1637,11 +1701,11 @@ static void akiko_bput2 (uaecptr addr, uae_u32 v, int msg) case 0x1d: cdrom_intreq &= ~CDINTERRUPT_TXDMADONE; cdcomtxcmp = v; - if (cdrom_command_active == 0) - cdrom_command_startdelay = 2; + cdrom_tx_dma_delay = 5; break; case 0x1f: cdrom_intreq &= ~CDINTERRUPT_RXDMADONE; + cdcomrxcmp = v; break; case 0x20: case 0x21: @@ -1751,7 +1815,8 @@ void akiko_reset (void) lastmediastate = -1; } cdrom_led = 0; - cdrom_receive_started = 0; + cdrom_receive_length = 0; + cdrom_receive_offset = 0; cd_initialized = 0; if (akiko_thread_running > 0) { @@ -1830,7 +1895,7 @@ uae_u8 *save_akiko (int *len, uae_u8 *dstptr) save_u8 (0); save_u8 (cdcomtxcmp); save_u8 (0); - save_u8 (0); + save_u8 (cdcomrxcmp); save_u16 ((uae_u16)cdrom_pbx); save_u16 (0); save_u32 (cdrom_flags); @@ -1892,7 +1957,7 @@ uae_u8 *restore_akiko (uae_u8 *src) restore_u8 (); cdcomtxcmp = restore_u8 (); restore_u8 (); - restore_u8 (); + cdcomrxcmp = restore_u8 (); cdrom_pbx = restore_u16 (); restore_u16 (); cdrom_flags = restore_u32 (); diff --git a/cfgfile.cpp b/cfgfile.cpp index 8e74abb4..d45f1d13 100644 --- a/cfgfile.cpp +++ b/cfgfile.cpp @@ -169,7 +169,7 @@ static const TCHAR *maxhoriz[] = { _T("lores"), _T("hires"), _T("superhires"), 0 static const TCHAR *maxvert[] = { _T("nointerlace"), _T("interlace"), 0 }; static const TCHAR *abspointers[] = { _T("none"), _T("mousehack"), _T("tablet"), 0 }; static const TCHAR *magiccursors[] = { _T("both"), _T("native"), _T("host"), 0 }; -static const TCHAR *autoscale[] = { _T("none"), _T("auto"), _T("standard"), _T("max"), _T("scale"), _T("resize"), _T("center"), _T("manual"), _T("integer"), 0 }; +static const TCHAR *autoscale[] = { _T("none"), _T("auto"), _T("standard"), _T("max"), _T("scale"), _T("resize"), _T("center"), _T("manual"), _T("integer"), _T("integer_auto"), 0 }; static const TCHAR *joyportmodes[] = { _T(""), _T("mouse"), _T("djoy"), _T("gamepad"), _T("ajoy"), _T("cdtvjoy"), _T("cd32joy"), _T("lightpen"), 0 }; static const TCHAR *joyaf[] = { _T("none"), _T("normal"), _T("toggle"), 0 }; static const TCHAR *epsonprinter[] = { _T("none"), _T("ascii"), _T("epson_matrix_9pin"), _T("epson_matrix_24pin"), _T("epson_matrix_48pin"), 0 }; diff --git a/custom.cpp b/custom.cpp index 79dde56e..2b8abd26 100644 --- a/custom.cpp +++ b/custom.cpp @@ -2840,8 +2840,8 @@ void compute_framesync (void) if (!picasso_on) { if (isvsync_chipset ()) { if (cr->index == CHIPSET_REFRESH_PAL || cr->index == CHIPSET_REFRESH_NTSC) { - if ((abs (vblank_hz - 50) < 1 || abs (vblank_hz - 60) < 1) && currprefs.gfx_apmode[0].gfx_vsync == 2 && currprefs.gfx_apmode[0].gfx_fullscreen > 0) { - vsync_switchmode (vblank_hz > 55 ? 60 : 50); + if ((abs (vblank_hz - 50) < 1 || abs (vblank_hz - 60) < 1 || abs (vblank_hz - 100) < 1 || abs (vblank_hz - 120) < 1) && currprefs.gfx_apmode[0].gfx_vsync == 2 && currprefs.gfx_apmode[0].gfx_fullscreen > 0) { + vsync_switchmode (vblank_hz); } } if (isvsync_chipset () < 0) { @@ -5208,42 +5208,80 @@ static void rtg_vsynccheck (void) } } -static void framewait (void) +extern int log_vsync; +static bool framewait (void) { frame_time_t curr_time; frame_time_t start; int vs = isvsync_chipset (); int frameskipt; + bool ok = true; frameskipt = frameskiptime; frameskiptime = 0; + /* note to anyone reading this: below ugly uae_s64 averaging stuff will be replaced with + * something more optimal after vsync timing works correctly enough + */ + is_syncline = 0; + static uae_s64 frameskipt64; + static int frameskipt64cnt; + + frameskipt64cnt++; + if (frameskipt > frameskipt64 / frameskipt64cnt) + frameskipt64 = (uae_s64)frameskipt * frameskipt64cnt; + else + frameskipt64 += frameskipt; + if (vs > 0) { + static frame_time_t vsync_time; + static uae_s64 legacy64; + static int legacy64cnt; int t; + curr_time = read_processor_time (); vsyncwaittime = vsyncmaxtime = curr_time + vsynctimebase; if (!frame_rendered && !picasso_on) frame_rendered = render_screen (false); + + start = read_processor_time (); + t = 0; + if ((int)start - (int)vsync_time >= 0 && (int)start - (int)vsync_time < vsynctimebase) + t += (int)start - (int)vsync_time; + if (!frame_shown) show_screen (); - t = read_processor_time () - curr_time; - if (t < 0) - t = 0; - t += frameskipt; - if (t > vsynctimebase / 2) - t = vsynctimebase / 2; + + legacy64cnt++; + if (t > legacy64 / legacy64cnt) + legacy64 = (uae_s64)t * legacy64cnt; + else + legacy64 += t; + + t = legacy64 / legacy64cnt; + + vsync_time = read_processor_time (); + if (t > vsynctimebase * 2 / 3) + t = vsynctimebase * 2 / 3; + if (currprefs.m68k_speed < 0) { vsynctimeperline = (vsynctimebase - t * 2) / (maxvpos_nom + 1); } else { - vsynctimeperline = (vsynctimebase - t * 2) / 3; + vsynctimeperline = (vsynctimebase - t) / 3; } + if (vsynctimeperline < 1) vsynctimeperline = 1; + + if (0 || (log_vsync & 2)) { + write_log (L"%06d %06d/%06d\n", t, vsynctimeperline, vsynctimebase); + } + frame_shown = true; - return; + return ok; } else if (vs < 0) { @@ -5251,14 +5289,16 @@ static void framewait (void) extern int extraframewait; if (!vblank_hz_state) - return; + return ok; if (vs == -2 || vs == -3) { // fastest possible static int skipcnt; - int max, adjust, flipdelay; + int max, adjust, flipdelay, val; frame_time_t now; + static uae_s64 skipcnt64, adjust64; + static int llvsynccnt; if (!frame_rendered && !picasso_on) { frame_time_t start, end; @@ -5269,17 +5309,15 @@ static void framewait (void) } curr_time = vsync_busywait_end (&flipdelay); // vsync time - vsync_busywait_do (NULL, (bplcon0 & 4) != 0 && !lof_changed && !lof_changing, lof_store != 0); + ok = vsync_busywait_do (NULL, (bplcon0 & 4) != 0 && !lof_changed && !lof_changing, lof_store != 0); vsync_busywait_start (); - if (flipdelay > skipcnt) - skipcnt = flipdelay; - else - skipcnt -= vsynctimebase / (4 * (maxvpos_nom + 1)); - if (skipcnt > 0) - skipcnt--; + llvsynccnt++; + + if (flipdelay > skipcnt64 / llvsynccnt) + skipcnt64 = (uae_s64)flipdelay * llvsynccnt; else - skipcnt = 0; + skipcnt64 += flipdelay; now = read_processor_time (); // current time adjust = (int)now - (int)curr_time; @@ -5287,20 +5325,24 @@ static void framewait (void) if (adjust < 0) adjust = 0; if (adjust > vsynctimebase * 2 / 3) - adjust = 0; + adjust = vsynctimebase * 2 / 3; + adjust64 += adjust; + //write_log (_T("%d "), adjust); + val = adjust64 / llvsynccnt; + if (currprefs.gfx_apmode[0].gfx_vflip == 0) { - adjust += skipcnt; + val += skipcnt64 / llvsynccnt; //write_log (_T("%d "), skipcnt); } - adjust += frameskipt; + val += frameskipt64 / frameskipt64cnt; //write_log (_T("%d "), adjust); - if (adjust > vsynctimebase / 2) - adjust = vsynctimebase / 2; + if (val > vsynctimebase * 2 / 3) + val = vsynctimebase * 2 / 3; - max = (vsynctimebase - adjust) * (1000 + currprefs.m68k_speed_throttle) / 1000; + max = (vsynctimebase - val) * (1000 + currprefs.m68k_speed_throttle) / 1000; if (max < 1) max = 1; @@ -5312,18 +5354,24 @@ static void framewait (void) vsynctimeperline = 1; vsyncmaxtime = now + max; + if (0 || (log_vsync & 2)) { + write_log (L"%05d:%05d:%05d=%05d:%05d/%05d\n", (int)(adjust64 / llvsynccnt), (int)(frameskipt64 / frameskipt64cnt), (int)(skipcnt64 / llvsynccnt), val, vsynctimeperline, vsynctimebase); + } + } else { static int skipcnt; int max, adjust, flipdelay; + static uae_s64 skipcnt64; + static int llvsynccnt; frame_time_t now; flipdelay = 0; if (!frame_rendered && !picasso_on) frame_rendered = render_screen (false); - vsync_busywait_do (&freetime, (bplcon0 & 4) != 0 && !lof_changed && !lof_changing, lof_store != 0); + ok = vsync_busywait_do (&freetime, (bplcon0 & 4) != 0 && !lof_changed && !lof_changing, lof_store != 0); curr_time = vsync_busywait_end (&flipdelay); - if (extraframewait) + if (extraframewait && !currprefs.turbo_emulation) sleep_millis_main (extraframewait); now = read_processor_time (); adjust = (int)now - (int)curr_time; @@ -5339,29 +5387,29 @@ static void framewait (void) vsyncwaittime = curr_time + vsynctimebase; if (currprefs.gfx_apmode[0].gfx_vflip == 0) { - if (flipdelay > skipcnt) - skipcnt = flipdelay; - else - skipcnt -= vsynctimebase / (4 * (maxvpos_nom + 1)); - if (skipcnt > 0) - skipcnt--; + llvsynccnt++; + if (flipdelay > skipcnt64 / llvsynccnt) + skipcnt64 = (uae_s64)flipdelay * llvsynccnt; else - skipcnt = 0; + skipcnt64 += flipdelay; } else { - skipcnt = 0; + skipcnt64 = 0; + llvsynccnt = 1; } - vsynctimeperline = (max - skipcnt * 2) / 3; + vsynctimeperline = (max - (skipcnt64 / llvsynccnt) * 2) / 3; if (vsynctimeperline < 1) vsynctimeperline = 1; vsyncmaxtime = now + max; - //write_log (_T("%d:%d:%d "), adjust, skipcnt, vsynctimeperline); + if (0 || (log_vsync & 2)) { + write_log (L"%06d:%06d:%06d:%06d/%06d\n", (int)(frameskipt64 / frameskipt64cnt), (int)(skipcnt64 / llvsynccnt), adjust, vsynctimeperline, vsynctimebase); + } frame_shown = true; } - return; + return ok; } if (currprefs.m68k_speed < 0) { @@ -5410,7 +5458,7 @@ static void framewait (void) frame_rendered = render_screen (false); t = read_processor_time () - start; } - for (;;) { + while (!currprefs.turbo_emulation) { double v = rpt_vsync () / (syncbase / 1000.0); if (v >= -4) break; @@ -5437,8 +5485,10 @@ static void framewait (void) frame_shown = true; } + return ok; } + static frame_time_t frametime2; void fpscounter_reset (void) @@ -5450,7 +5500,7 @@ void fpscounter_reset (void) idletime = 0; } -static void fpscounter (void) +static void fpscounter (bool frameok) { frame_time_t now, last; int mcnt = 10; @@ -5480,7 +5530,7 @@ static void fpscounter (void) } if (currprefs.turbo_emulation && idle < 100 * 10) idle = 100 * 10; - gui_fps (fps, (int)idle); + gui_fps (fps, (int)idle, frameok ? 0 : 1); frametime2 = 0; idletime = 0; } @@ -5530,7 +5580,7 @@ static void vsync_handler_pre (void) frameskiptime += end - start; } - framewait (); + bool frameok = framewait (); if (!picasso_on) { if (!frame_rendered && vblank_hz_state) { @@ -5541,8 +5591,7 @@ static void vsync_handler_pre (void) } } - fpscounter (); - + fpscounter (frameok); vsync_rendered = false; frame_shown = false; @@ -6056,7 +6105,7 @@ static void hsync_handler_post (bool onvsync) vsyncmintime += vsynctimeperline; linecounter++; is_syncline = 0; - if (!vblank_found_chipset) { + if (!vblank_found_chipset && !currprefs.turbo_emulation) { if ((int)vsyncmaxtime - (int)vsyncmintime > 0) { if ((int)vsyncwaittime - (int)vsyncmintime > 0) { frame_time_t rpt = read_processor_time (); @@ -6082,7 +6131,7 @@ static void hsync_handler_post (bool onvsync) } } } else { - if (vpos + 1 < maxvpos + lof_store && (vpos == maxvpos_nom * 1 / 3 || vpos == maxvpos_nom * 2 / 3)) { + if (!currprefs.turbo_emulation && (vpos + 1 < maxvpos + lof_store && (vpos == maxvpos_nom * 1 / 3 || vpos == maxvpos_nom * 2 / 3))) { frame_time_t rpt = read_processor_time (); vsyncmintime += vsynctimeperline; // sleep if more than 2ms "free" time diff --git a/drawing.cpp b/drawing.cpp index e083800d..b3072ece 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -171,7 +171,7 @@ static uae_u8 row_tmp[MAX_PIXELS_PER_LINE * 32 / 8]; static int max_drawn_amiga_line; /* line_draw_funcs: pfield_do_linetoscr, pfield_do_fill_line, decode_ham */ -typedef void (*line_draw_func)(int, int); +typedef void (*line_draw_func)(int, int, bool); #define LINE_UNDECIDED 1 #define LINE_DECIDED 2 @@ -192,6 +192,10 @@ static int min_diwstart, max_diwstop; /* The visible window: VISIBLE_LEFT_BORDER contains the left border of the visible area, VISIBLE_RIGHT_BORDER the right border. These are in window coordinates. */ int visible_left_border, visible_right_border; +/* Pixels outside of visible_start and visible_stop are always black */ +static int visible_left_start, visible_right_stop; +static int visible_top_start, visible_bottom_stop; + static int linetoscr_x_adjust_bytes; static int thisframe_y_adjust; static int thisframe_y_adjust_real, max_ypos_thisframe, min_ypos_for_screen; @@ -354,6 +358,32 @@ static void reset_custom_limits (void) gclow = gcloh = gclox = gcloy = 0; } +void set_custom_limits (int w, int h, int dx, int dy) +{ + int vls = visible_left_start; + int vrs = visible_right_stop; + int vts = visible_top_start; + int vbs = visible_bottom_stop; + + if (w <= 0 || dx < 0) { + visible_left_start = 0; + visible_right_stop = 1 << 30; + } else { + visible_left_start = visible_left_border + dx; + visible_right_stop = visible_left_start + w; + } + if (h <= 0 || dy < 0) { + visible_top_start = 0; + visible_bottom_stop = 1 << 30; + } else { + visible_top_start = min_ypos_for_screen + dy; + visible_bottom_stop = visible_top_start + h; + } + if (vls != visible_left_start || vrs != visible_right_stop || + vts != visible_top_start || vbs != visible_bottom_stop) + notice_screen_contents_lost (); +} + int get_custom_limits (int *pw, int *ph, int *pdx, int *pdy) { int w, h, dx, dy, y1, y2, dbl1, dbl2; @@ -721,10 +751,12 @@ STATIC_INLINE uae_u32 merge_2pixel32 (uae_u32 p1, uae_u32 p2) return v; } -STATIC_INLINE xcolnr getbgc (void) +STATIC_INLINE xcolnr getbgc (bool blank) { #if 0 - if (hposblank == 1) + if (blank) + return xcolors[0x088]; + else if (hposblank == 1) return xcolors[0xf00]; else if (hposblank == 2) return xcolors[0x0f0]; @@ -732,16 +764,17 @@ STATIC_INLINE xcolnr getbgc (void) return xcolors[0x00f]; else if (brdblank) return xcolors[0x880]; + return xcolors[0xf0f]; #endif - return (brdblank || hposblank) ? 0 : colors_for_drawing.acolors[0]; + return (blank || brdblank || hposblank) ? 0 : colors_for_drawing.acolors[0]; } -static void fill_line_16 (uae_u8 *buf, unsigned int start, unsigned int stop) +STATIC_INLINE void fill_line_16 (uae_u8 *buf, int start, int stop, bool blank) { uae_u16 *b = (uae_u16 *)buf; unsigned int i; unsigned int rem = 0; - xcolnr col = getbgc (); + xcolnr col = getbgc (blank); if (((long)&b[start]) & 1) b[start++] = (uae_u16) col; if (start >= stop) @@ -758,23 +791,38 @@ static void fill_line_16 (uae_u8 *buf, unsigned int start, unsigned int stop) b[stop] = (uae_u16)col; } -static void fill_line_32 (uae_u8 *buf, unsigned int start, unsigned int stop) +STATIC_INLINE void fill_line_32 (uae_u8 *buf, int start, int stop, bool blank) { uae_u32 *b = (uae_u32 *)buf; unsigned int i; - xcolnr col = getbgc (); + xcolnr col = getbgc (blank); for (i = start; i < stop; i++) b[i] = col; } - -static void pfield_do_fill_line (int start, int stop) +static void pfield_do_fill_line2 (int start, int stop, bool blank) { - xlinecheck(start, stop); switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: fill_line_16 (xlinebuffer, start, stop); break; - case 4: fill_line_32 (xlinebuffer, start, stop); break; + case 2: fill_line_16 (xlinebuffer, start, stop, blank); break; + case 4: fill_line_32 (xlinebuffer, start, stop, blank); break; } } +static void pfield_do_fill_line (int start, int stop, bool blank) +{ + xlinecheck(start, stop); + if (!blank) { + if (start < visible_left_start) { + pfield_do_fill_line2 (start, visible_left_start, true); + start = visible_left_start; + } + if (stop > visible_right_stop) { + pfield_do_fill_line2 (start, visible_right_stop, false); + blank = true; + start = visible_right_stop; + } + } + pfield_do_fill_line2 (start, stop, blank); +} + STATIC_INLINE void fill_line2 (int startpos, int len) { @@ -793,7 +841,7 @@ STATIC_INLINE void fill_line2 (int startpos, int len) nrem = nints & 7; nints &= ~7; start = (int *)(((uae_u8*)xlinebuffer) + (startpos << shift)); - val = getbgc (); + val = getbgc (false); for (; nints > 0; nints -= 8, start += 8) { *start = val; *(start+1) = val; @@ -910,9 +958,13 @@ STATIC_INLINE uae_u8 render_sprites (int pos, int dualpf, uae_u8 apixel, int aga #include "linetoscr.cpp" +#define LTPARMS src_pixel, start, stop + #ifdef ECS_DENISE /* ECS SuperHires special cases */ +#define PUTBPIX(x) buf[dpix] = (x); + STATIC_INLINE uae_u32 shsprite (int dpix, uae_u32 spix_val, uae_u32 v, int spr) { uae_u8 sprcol; @@ -941,11 +993,11 @@ static int NOINLINE linetoscr_16_sh (int spix, int dpix, int stoppos, int spr) off = ((spix_val2 & 3) * 4) + (spix_val1 & 3) + ((spix_val1 | spix_val2) & 16); v = (colors_for_drawing.color_regs_ecs[off] & 0xccc) << 0; v |= v >> 2; - buf[dpix] = shsprite (dpix, spix_val1, xcolors[v], spr); + PUTBPIX(shsprite (dpix, spix_val1, xcolors[v], spr)); dpix++; v = (colors_for_drawing.color_regs_ecs[off] & 0x333) << 2; v |= v >> 2; - buf[dpix] = shsprite (dpix, spix_val2, xcolors[v], spr); + PUTBPIX(shsprite (dpix, spix_val2, xcolors[v], spr)); dpix++; } return spix; @@ -963,11 +1015,11 @@ static int NOINLINE linetoscr_32_sh (int spix, int dpix, int stoppos, int spr) off = ((spix_val2 & 3) * 4) + (spix_val1 & 3) + ((spix_val1 | spix_val2) & 16); v = (colors_for_drawing.color_regs_ecs[off] & 0xccc) << 0; v |= v >> 2; - buf[dpix] = shsprite (dpix, spix_val1, xcolors[v], spr); + PUTBPIX(shsprite (dpix, spix_val1, xcolors[v], spr)); dpix++; v = (colors_for_drawing.color_regs_ecs[off] & 0x333) << 2; v |= v >> 2; - buf[dpix] = shsprite (dpix, spix_val2, xcolors[v], spr); + PUTBPIX(shsprite (dpix, spix_val2, xcolors[v], spr)); dpix++; } return spix; @@ -985,7 +1037,7 @@ static int NOINLINE linetoscr_32_shrink1_sh (int spix, int dpix, int stoppos, in off = ((spix_val2 & 3) * 4) + (spix_val1 & 3) + ((spix_val1 | spix_val2) & 16); v = (colors_for_drawing.color_regs_ecs[off] & 0xccc) << 0; v |= v >> 2; - buf[dpix] = shsprite (dpix, spix_val1, xcolors[v], spr); + PUTBPIX(shsprite (dpix, spix_val1, xcolors[v], spr)); dpix++; } return spix; @@ -1007,7 +1059,7 @@ static int NOINLINE linetoscr_32_shrink1f_sh (int spix, int dpix, int stoppos, i v = (colors_for_drawing.color_regs_ecs[off] & 0x333) << 2; v |= v >> 2; dpix_val2 = xcolors[v]; - buf[dpix] = shsprite (dpix, spix_val1, merge_2pixel32 (dpix_val1, dpix_val2), spr); + PUTBPIX(shsprite (dpix, spix_val1, merge_2pixel32 (dpix_val1, dpix_val2), spr)); dpix++; } return spix; @@ -1025,7 +1077,7 @@ static int NOINLINE linetoscr_16_shrink1_sh (int spix, int dpix, int stoppos, in off = ((spix_val2 & 3) * 4) + (spix_val1 & 3) + ((spix_val1 | spix_val2) & 16); v = (colors_for_drawing.color_regs_ecs[off] & 0xccc) << 0; v |= v >> 2; - buf[dpix] = shsprite (dpix, spix_val1, xcolors[v], spr); + PUTBPIX(shsprite (dpix, spix_val1, xcolors[v], spr)); dpix++; } return spix; @@ -1047,7 +1099,7 @@ static int NOINLINE linetoscr_16_shrink1f_sh (int spix, int dpix, int stoppos, i v = (colors_for_drawing.color_regs_ecs[off] & 0x333) << 2; v |= v >> 2; dpix_val2 = xcolors[v]; - buf[dpix] = shsprite (dpix, spix_val1, merge_2pixel16 (dpix_val1, dpix_val2), spr); + PUTBPIX(shsprite (dpix, spix_val1, merge_2pixel16 (dpix_val1, dpix_val2), spr)); dpix++; } return spix; @@ -1068,7 +1120,7 @@ static int NOINLINE linetoscr_32_shrink2_sh (int spix, int dpix, int stoppos, in off = ((spix_val2 & 3) * 4) + (spix_val1 & 3) + ((spix_val1 | spix_val2) & 16); v = (colors_for_drawing.color_regs_ecs[off] & 0xccc) << 0; v |= v >> 2; - buf[dpix] = shsprite (dpix, spix_val1, xcolors[v], spr); + PUTBPIX(shsprite (dpix, spix_val1, xcolors[v], spr)); spix+=2; dpix++; } @@ -1102,7 +1154,7 @@ static int NOINLINE linetoscr_32_shrink2f_sh (int spix, int dpix, int stoppos, i v |= v >> 2; dpix_val2 = xcolors[v]; dpix_val4 = merge_2pixel32 (dpix_val1, dpix_val2); - buf[dpix] = shsprite (dpix, spix_val1, merge_2pixel32 (dpix_val3, dpix_val4), spr); + PUTBPIX(shsprite (dpix, spix_val1, merge_2pixel32 (dpix_val3, dpix_val4), spr)); dpix++; } return spix; @@ -1120,7 +1172,7 @@ static int NOINLINE linetoscr_16_shrink2_sh (int spix, int dpix, int stoppos, in off = ((spix_val2 & 3) * 4) + (spix_val1 & 3) + ((spix_val1 | spix_val2) & 16); v = (colors_for_drawing.color_regs_ecs[off] & 0xccc) << 0; v |= v >> 2; - buf[dpix] = shsprite (dpix, spix_val1, xcolors[v], spr); + PUTBPIX(shsprite (dpix, spix_val1, xcolors[v], spr)); spix+=2; dpix++; } @@ -1154,54 +1206,54 @@ static int NOINLINE linetoscr_16_shrink2f_sh (int spix, int dpix, int stoppos, i v |= v >> 2; dpix_val2 = xcolors[v]; dpix_val4 = merge_2pixel32 (dpix_val1, dpix_val2); - buf[dpix] = shsprite (dpix, spix_val1, merge_2pixel16 (dpix_val3, dpix_val4), spr); + PUTBPIX(shsprite (dpix, spix_val1, merge_2pixel16 (dpix_val3, dpix_val4), spr)); dpix++; } return spix; } #endif -static void pfield_do_linetoscr (int start, int stop) +static void pfield_do_linetoscr (int start, int stop, bool blank) { xlinecheck(start, stop); if (issprites && (currprefs.chipset_mask & CSMASK_AGA)) { if (res_shift == 0) { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_aga_spr (src_pixel, start, stop); break; - case 4: src_pixel = linetoscr_32_aga_spr (src_pixel, start, stop); break; + case 2: src_pixel = linetoscr_16_aga_spr (LTPARMS); break; + case 4: src_pixel = linetoscr_32_aga_spr (LTPARMS); break; } } else if (res_shift == 2) { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_stretch2_aga_spr (src_pixel, start, stop); break; - case 4: src_pixel = linetoscr_32_stretch2_aga_spr (src_pixel, start, stop); break; + case 2: src_pixel = linetoscr_16_stretch2_aga_spr (LTPARMS); break; + case 4: src_pixel = linetoscr_32_stretch2_aga_spr (LTPARMS); break; } } else if (res_shift == 1) { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_stretch1_aga_spr (src_pixel, start, stop); break; - case 4: src_pixel = linetoscr_32_stretch1_aga_spr (src_pixel, start, stop); break; + case 2: src_pixel = linetoscr_16_stretch1_aga_spr (LTPARMS); break; + case 4: src_pixel = linetoscr_32_stretch1_aga_spr (LTPARMS); break; } } else if (res_shift == -1) { if (currprefs.gfx_lores_mode) { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_shrink1f_aga_spr (src_pixel, start, stop); break; - case 4: src_pixel = linetoscr_32_shrink1f_aga_spr (src_pixel, start, stop); break; + case 2: src_pixel = linetoscr_16_shrink1f_aga_spr (LTPARMS); break; + case 4: src_pixel = linetoscr_32_shrink1f_aga_spr (LTPARMS); break; } } else { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_shrink1_aga_spr (src_pixel, start, stop); break; - case 4: src_pixel = linetoscr_32_shrink1_aga_spr (src_pixel, start, stop); break; + case 2: src_pixel = linetoscr_16_shrink1_aga_spr (LTPARMS); break; + case 4: src_pixel = linetoscr_32_shrink1_aga_spr (LTPARMS); break; } } } else if (res_shift == -2) { if (currprefs.gfx_lores_mode) { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_shrink2f_aga_spr (src_pixel, start, stop); break; - case 4: src_pixel = linetoscr_32_shrink2f_aga_spr (src_pixel, start, stop); break; + case 2: src_pixel = linetoscr_16_shrink2f_aga_spr (LTPARMS); break; + case 4: src_pixel = linetoscr_32_shrink2f_aga_spr (LTPARMS); break; } } else { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_shrink2_aga_spr (src_pixel, start, stop); break; - case 4: src_pixel = linetoscr_32_shrink2_aga_spr (src_pixel, start, stop); break; + case 2: src_pixel = linetoscr_16_shrink2_aga_spr (LTPARMS); break; + case 4: src_pixel = linetoscr_32_shrink2_aga_spr (LTPARMS); break; } } } @@ -1210,41 +1262,41 @@ static void pfield_do_linetoscr (int start, int stop) if (currprefs.chipset_mask & CSMASK_AGA) { if (res_shift == 0) { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_aga (src_pixel, start, stop); break; - case 4: src_pixel = linetoscr_32_aga (src_pixel, start, stop); break; + case 2: src_pixel = linetoscr_16_aga (LTPARMS); break; + case 4: src_pixel = linetoscr_32_aga (LTPARMS); break; } } else if (res_shift == 2) { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_stretch2_aga (src_pixel, start, stop); break; - case 4: src_pixel = linetoscr_32_stretch2_aga (src_pixel, start, stop); break; + case 2: src_pixel = linetoscr_16_stretch2_aga (LTPARMS); break; + case 4: src_pixel = linetoscr_32_stretch2_aga (LTPARMS); break; } } else if (res_shift == 1) { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_stretch1_aga (src_pixel, start, stop); break; - case 4: src_pixel = linetoscr_32_stretch1_aga (src_pixel, start, stop); break; + case 2: src_pixel = linetoscr_16_stretch1_aga (LTPARMS); break; + case 4: src_pixel = linetoscr_32_stretch1_aga (LTPARMS); break; } } else if (res_shift == -1) { if (currprefs.gfx_lores_mode) { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_shrink1f_aga (src_pixel, start, stop); break; - case 4: src_pixel = linetoscr_32_shrink1f_aga (src_pixel, start, stop); break; + case 2: src_pixel = linetoscr_16_shrink1f_aga (LTPARMS); break; + case 4: src_pixel = linetoscr_32_shrink1f_aga (LTPARMS); break; } } else { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_shrink1_aga (src_pixel, start, stop); break; - case 4: src_pixel = linetoscr_32_shrink1_aga (src_pixel, start, stop); break; + case 2: src_pixel = linetoscr_16_shrink1_aga (LTPARMS); break; + case 4: src_pixel = linetoscr_32_shrink1_aga (LTPARMS); break; } } } else if (res_shift == -2) { if (currprefs.gfx_lores_mode) { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_shrink2f_aga (src_pixel, start, stop); break; - case 4: src_pixel = linetoscr_32_shrink2f_aga (src_pixel, start, stop); break; + case 2: src_pixel = linetoscr_16_shrink2f_aga (LTPARMS); break; + case 4: src_pixel = linetoscr_32_shrink2f_aga (LTPARMS); break; } } else { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_shrink2_aga (src_pixel, start, stop); break; - case 4: src_pixel = linetoscr_32_shrink2_aga (src_pixel, start, stop); break; + case 2: src_pixel = linetoscr_16_shrink2_aga (LTPARMS); break; + case 4: src_pixel = linetoscr_32_shrink2_aga (LTPARMS); break; } } } @@ -1254,31 +1306,31 @@ static void pfield_do_linetoscr (int start, int stop) if (ecsshres) { if (res_shift == 0) { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_sh (src_pixel, start, stop, issprites); break; - case 4: src_pixel = linetoscr_32_sh (src_pixel, start, stop, issprites); break; + case 2: src_pixel = linetoscr_16_sh (LTPARMS, issprites); break; + case 4: src_pixel = linetoscr_32_sh (LTPARMS, issprites); break; } } else if (res_shift == -1) { if (currprefs.gfx_lores_mode) { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_shrink1f_sh (src_pixel, start, stop, issprites); break; - case 4: src_pixel = linetoscr_32_shrink1f_sh (src_pixel, start, stop, issprites); break; + case 2: src_pixel = linetoscr_16_shrink1f_sh (LTPARMS, issprites); break; + case 4: src_pixel = linetoscr_32_shrink1f_sh (LTPARMS, issprites); break; } } else { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_shrink1_sh (src_pixel, start, stop, issprites); break; - case 4: src_pixel = linetoscr_32_shrink1_sh (src_pixel, start, stop, issprites); break; + case 2: src_pixel = linetoscr_16_shrink1_sh (LTPARMS, issprites); break; + case 4: src_pixel = linetoscr_32_shrink1_sh (LTPARMS, issprites); break; } } } else if (res_shift == -2) { if (currprefs.gfx_lores_mode) { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_shrink2f_sh (src_pixel, start, stop, issprites); break; - case 4: src_pixel = linetoscr_32_shrink2f_sh (src_pixel, start, stop, issprites); break; + case 2: src_pixel = linetoscr_16_shrink2f_sh (LTPARMS, issprites); break; + case 4: src_pixel = linetoscr_32_shrink2f_sh (LTPARMS, issprites); break; } } else { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_shrink2_sh (src_pixel, start, stop, issprites); break; - case 4: src_pixel = linetoscr_32_shrink2_sh (src_pixel, start, stop, issprites); break; + case 2: src_pixel = linetoscr_16_shrink2_sh (LTPARMS, issprites); break; + case 4: src_pixel = linetoscr_32_shrink2_sh (LTPARMS, issprites); break; } } } @@ -1287,58 +1339,58 @@ static void pfield_do_linetoscr (int start, int stop) if (issprites) { if (res_shift == 0) { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_spr (src_pixel, start, stop); break; - case 4: src_pixel = linetoscr_32_spr (src_pixel, start, stop); break; + case 2: src_pixel = linetoscr_16_spr (LTPARMS); break; + case 4: src_pixel = linetoscr_32_spr (LTPARMS); break; } } else if (res_shift == 2) { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_stretch2_spr (src_pixel, start, stop); break; - case 4: src_pixel = linetoscr_32_stretch2_spr (src_pixel, start, stop); break; + case 2: src_pixel = linetoscr_16_stretch2_spr (LTPARMS); break; + case 4: src_pixel = linetoscr_32_stretch2_spr (LTPARMS); break; } } else if (res_shift == 1) { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_stretch1_spr (src_pixel, start, stop); break; - case 4: src_pixel = linetoscr_32_stretch1_spr (src_pixel, start, stop); break; + case 2: src_pixel = linetoscr_16_stretch1_spr (LTPARMS); break; + case 4: src_pixel = linetoscr_32_stretch1_spr (LTPARMS); break; } } else if (res_shift == -1) { if (currprefs.gfx_lores_mode) { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_shrink1f_spr (src_pixel, start, stop); break; - case 4: src_pixel = linetoscr_32_shrink1f_spr (src_pixel, start, stop); break; + case 2: src_pixel = linetoscr_16_shrink1f_spr (LTPARMS); break; + case 4: src_pixel = linetoscr_32_shrink1f_spr (LTPARMS); break; } } else { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_shrink1_spr (src_pixel, start, stop); break; - case 4: src_pixel = linetoscr_32_shrink1_spr (src_pixel, start, stop); break; + case 2: src_pixel = linetoscr_16_shrink1_spr (LTPARMS); break; + case 4: src_pixel = linetoscr_32_shrink1_spr (LTPARMS); break; } } } } else { if (res_shift == 0) { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16 (src_pixel, start, stop); break; - case 4: src_pixel = linetoscr_32 (src_pixel, start, stop); break; + case 2: src_pixel = linetoscr_16 (LTPARMS); break; + case 4: src_pixel = linetoscr_32 (LTPARMS); break; } } else if (res_shift == 2) { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_stretch2 (src_pixel, start, stop); break; - case 4: src_pixel = linetoscr_32_stretch2 (src_pixel, start, stop); break; + case 2: src_pixel = linetoscr_16_stretch2 (LTPARMS); break; + case 4: src_pixel = linetoscr_32_stretch2 (LTPARMS); break; } } else if (res_shift == 1) { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_stretch1 (src_pixel, start, stop); break; - case 4: src_pixel = linetoscr_32_stretch1 (src_pixel, start, stop); break; + case 2: src_pixel = linetoscr_16_stretch1 (LTPARMS); break; + case 4: src_pixel = linetoscr_32_stretch1 (LTPARMS); break; } } else if (res_shift == -1) { if (currprefs.gfx_lores_mode) { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_shrink1f (src_pixel, start, stop); break; - case 4: src_pixel = linetoscr_32_shrink1f (src_pixel, start, stop); break; + case 2: src_pixel = linetoscr_16_shrink1f (LTPARMS); break; + case 4: src_pixel = linetoscr_32_shrink1f (LTPARMS); break; } } else { switch (gfxvidinfo.drawbuffer.pixbytes) { - case 2: src_pixel = linetoscr_16_shrink1 (src_pixel, start, stop); break; - case 4: src_pixel = linetoscr_32_shrink1 (src_pixel, start, stop); break; + case 2: src_pixel = linetoscr_16_shrink1 (LTPARMS); break; + case 4: src_pixel = linetoscr_32_shrink1 (LTPARMS); break; } } } @@ -1346,7 +1398,7 @@ static void pfield_do_linetoscr (int start, int stop) } -static void dummy_worker (int start, int stop) +static void dummy_worker (int start, int stop, bool blank) { } @@ -1416,7 +1468,7 @@ static void init_ham_decoding (void) } } -static void decode_ham (int pix, int stoppos) +static void decode_ham (int pix, int stoppos, bool blank) { int todraw_amiga = res_shift_from_window (stoppos - pix); @@ -1983,7 +2035,7 @@ static void adjust_drawing_colors (int ctable, int need_full) } } -STATIC_INLINE void do_color_changes (line_draw_func worker_border, line_draw_func worker_pfield) +static void do_color_changes (line_draw_func worker_border, line_draw_func worker_pfield, int vp) { int i; int lastpos = visible_left_border; @@ -2006,22 +2058,28 @@ STATIC_INLINE void do_color_changes (line_draw_func worker_border, line_draw_fun if (nextpos_in_range > lastpos) { if (lastpos < playfield_start) { int t = nextpos_in_range <= playfield_start ? nextpos_in_range : playfield_start; - (*worker_border) (lastpos, t); + (*worker_border) (lastpos, t, false); lastpos = t; } } if (nextpos_in_range > lastpos) { if (lastpos >= playfield_start && lastpos < playfield_end) { int t = nextpos_in_range <= playfield_end ? nextpos_in_range : playfield_end; - (*worker_pfield) (lastpos, t); + (*worker_pfield) (lastpos, t, false); + /* blank start and end that shouldn't be visible */ + if (lastpos < visible_left_start) + (*worker_border) (lastpos, visible_left_start, true); + if (t > visible_right_stop) + (*worker_border) (visible_right_stop, endpos, true); lastpos = t; } } if (nextpos_in_range > lastpos) { if (lastpos >= playfield_end) - (*worker_border) (lastpos, nextpos_in_range); + (*worker_border) (lastpos, nextpos_in_range, false); lastpos = nextpos_in_range; } + if (regno >= 0x1000) { pfield_expand_dp_bplconx (regno, value); } else if (regno >= 0) { @@ -2031,6 +2089,13 @@ STATIC_INLINE void do_color_changes (line_draw_func worker_border, line_draw_fun if (lastpos >= endpos) break; } + if (vp < visible_top_start || vp >= visible_bottom_stop) { + // outside of visible area + // Just overwrite with black. Above code needs to run because of custom registers, + // not worth the trouble for separate code path just for max 10 lines or so + (*worker_border) (visible_left_border, visible_left_border + gfxvidinfo.drawbuffer.inwidth, true); + } + } enum double_how { dh_buf, @@ -2114,9 +2179,9 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in if (dip_for_drawing->nr_color_changes == 0) { /* The easy case: need to do HAM decoding only once for the * full line. */ - decode_ham (visible_left_border, visible_right_border); + decode_ham (visible_left_border, visible_right_border, false); } else /* Argh. */ { - do_color_changes (dummy_worker, decode_ham); + do_color_changes (dummy_worker, decode_ham, lineno); adjust_drawing_colors (dp_for_drawing->ctable, dp_for_drawing->ham_seen || bplehb); } bplham = dp_for_drawing->ham_at_start; @@ -2141,7 +2206,7 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in } } - do_color_changes (pfield_do_fill_line, pfield_do_linetoscr); + do_color_changes (pfield_do_fill_line, pfield_do_linetoscr, lineno); if (dh == dh_emerg) memcpy (row_map[gfx_ypos], xlinebuffer + linetoscr_x_adjust_bytes, gfxvidinfo.drawbuffer.pixbytes * gfxvidinfo.drawbuffer.inwidth); @@ -2194,14 +2259,14 @@ static void pfield_draw_line (struct vidbuffer *vb, int lineno, int gfx_ypos, in uae_u16 oxor = bplxor; memset (pixdata.apixels, 0, sizeof pixdata); bplxor = 0; - do_color_changes (pfield_do_fill_line, pfield_do_linetoscr); + do_color_changes (pfield_do_fill_line, pfield_do_linetoscr, lineno); bplxor = oxor; } else { playfield_start = visible_right_border; playfield_end = visible_right_border; - do_color_changes (pfield_do_fill_line, pfield_do_fill_line); + do_color_changes (pfield_do_fill_line, pfield_do_fill_line, lineno); } @@ -2319,6 +2384,9 @@ static void center_image (void) gfxvidinfo.drawbuffer.xoffset = (DISPLAY_LEFT_SHIFT << RES_MAX) + (visible_left_border << (RES_MAX - currprefs.gfx_resolution)); gfxvidinfo.drawbuffer.yoffset = thisframe_y_adjust << VRES_MAX; + + visible_left_start = visible_left_border; + visible_right_stop = visible_left_start + gfxvidinfo.drawbuffer.inwidth;; } #define FRAMES_UNTIL_RES_SWITCH 1 diff --git a/genlinetoscr.cpp b/genlinetoscr.cpp index 8bf90db7..c33e8be0 100644 --- a/genlinetoscr.cpp +++ b/genlinetoscr.cpp @@ -116,7 +116,7 @@ void outlnf (const char *s, ...) static void out_linetoscr_decl (DEPTH_T bpp, HMODE_T hmode, int aga, int spr) { - outlnf ("static int NOINLINE linetoscr_%s%s%s%s (int spix, int dpix, int stoppos)", + outlnf ("static int NOINLINE linetoscr_%s%s%s%s (int spix, int dpix, int dpix_end)", get_depth_str (bpp), get_hmode_str (hmode), aga ? "_aga" : "", spr ? "_spr" : ""); } @@ -210,6 +210,12 @@ static void out_linetoscr_do_incspix (DEPTH_T bpp, HMODE_T hmode, int aga, CMODE } } + +static void put_dpix (const char *var) +{ + outlnf (" buf[dpix++] = %s;", var); +} + static void out_sprite (DEPTH_T bpp, HMODE_T hmode, CMODE_T cmode, int aga, int cnt) { if (aga) { @@ -219,7 +225,7 @@ static void out_sprite (DEPTH_T bpp, HMODE_T hmode, CMODE_T cmode, int aga, int outlnf ( " if (sprcol)"); outlnf ( " out_val = colors_for_drawing.acolors[sprcol];"); outlnf ( " }"); - outlnf ( " buf[dpix++] = out_val;"); + put_dpix ("out_val"); } else if (cnt == 2) { outlnf ( " {"); outlnf ( " uae_u32 out_val1 = out_val;"); @@ -234,8 +240,8 @@ static void out_sprite (DEPTH_T bpp, HMODE_T hmode, CMODE_T cmode, int aga, int outlnf ( " if (sprcol)"); outlnf ( " out_val2 = colors_for_drawing.acolors[sprcol];"); outlnf ( " }"); - outlnf ( " buf[dpix++] = out_val1;"); - outlnf ( " buf[dpix++] = out_val2;"); + put_dpix ("out_val1"); + put_dpix ("out_val2"); outlnf ( " }"); } else if (cnt == 4) { outlnf ( " {"); @@ -263,10 +269,10 @@ static void out_sprite (DEPTH_T bpp, HMODE_T hmode, CMODE_T cmode, int aga, int outlnf ( " if (sprcol)"); outlnf ( " out_val4 = colors_for_drawing.acolors[sprcol];"); outlnf ( " }"); - outlnf ( " buf[dpix++] = out_val1;"); - outlnf ( " buf[dpix++] = out_val2;"); - outlnf ( " buf[dpix++] = out_val3;"); - outlnf ( " buf[dpix++] = out_val4;"); + put_dpix ("out_val1"); + put_dpix ("out_val2"); + put_dpix ("out_val3"); + put_dpix ("out_val4"); outlnf ( " }"); } } else { @@ -278,10 +284,11 @@ static void out_sprite (DEPTH_T bpp, HMODE_T hmode, CMODE_T cmode, int aga, int outlnf ( " }"); outlnf ( " }"); while (cnt-- > 0) - outlnf ( " buf[dpix++] = out_val;"); + put_dpix ("out_val"); } } + static void out_linetoscr_mode (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, CMODE_T cmode) { int old_indent = set_indent (8); @@ -305,17 +312,17 @@ static void out_linetoscr_mode (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, CM out_linetoscr_do_dstpix (bpp, hmode, aga, cmode, spr); out_linetoscr_do_incspix (bpp, hmode, aga, cmode, spr); - outln ( " buf[dpix++] = dpix_val;"); + put_dpix ("dpix_val"); outln ( "}"); - outln ( "if (dpix >= stoppos)"); + outln ( "if (dpix >= dpix_end)"); outln ( " return spix;"); - outln ( "rem = (((long)&buf[stoppos]) & 2);"); + outln ( "rem = (((long)&buf[dpix_end]) & 2);"); outln ( "if (rem)"); - outln ( " stoppos--;"); + outln ( " dpix_end--;"); } - outln ( "while (dpix < stoppos) {"); + outln ( "while (dpix < dpix_end) {"); if (spr) outln ( " uae_u32 sprpix_val;"); outln ( " uae_u32 spix_val;"); @@ -355,8 +362,8 @@ static void out_linetoscr_mode (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, CM if (spr) { out_sprite (bpp, hmode, cmode, aga, 2); } else { - outln ( " buf[dpix++] = out_val;"); - outln ( " buf[dpix++] = out_val;"); + put_dpix ("out_val"); + put_dpix ("out_val"); } } } else if (hmode == HMODE_DOUBLE2X) { @@ -376,10 +383,10 @@ static void out_linetoscr_mode (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, CM if (spr) { out_sprite (bpp, hmode, cmode, aga, 4); } else { - outln ( " buf[dpix++] = out_val;"); - outln ( " buf[dpix++] = out_val;"); - outln ( " buf[dpix++] = out_val;"); - outln ( " buf[dpix++] = out_val;"); + put_dpix ("out_val"); + put_dpix ("out_val"); + put_dpix ("out_val"); + put_dpix ("out_val"); } } } else { @@ -394,7 +401,7 @@ static void out_linetoscr_mode (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, CM if (spr) { out_sprite (bpp, hmode, cmode, aga, 1); } else { - outln ( " buf[dpix++] = out_val;"); + put_dpix ("out_val"); } } } @@ -411,7 +418,7 @@ static void out_linetoscr_mode (DEPTH_T bpp, HMODE_T hmode, int aga, int spr, CM out_linetoscr_do_dstpix (bpp, hmode, aga, cmode, spr); out_linetoscr_do_incspix (bpp, hmode, aga, cmode, spr); - outln ( " buf[dpix++] = dpix_val;"); + put_dpix ("dpix_val"); outln ( "}"); } diff --git a/hardfile.cpp b/hardfile.cpp index d9ef11e6..1c708c24 100644 --- a/hardfile.cpp +++ b/hardfile.cpp @@ -988,7 +988,7 @@ static uae_u64 cmd_readx (struct hardfiledata *hfd, uae_u8 *dataptr, uae_u64 off static uae_u64 cmd_read (struct hardfiledata *hfd, uaecptr dataptr, uae_u64 offset, uae_u64 len) { addrbank *bank_data = &get_mem_bank (dataptr); - if (!bank_data || !bank_data->check (dataptr, len)) + if (!len || !bank_data || !bank_data->check (dataptr, len)) return 0; return cmd_readx (hfd, bank_data->xlateaddr (dataptr), offset, len); } @@ -1003,7 +1003,7 @@ static uae_u64 cmd_writex (struct hardfiledata *hfd, uae_u8 *dataptr, uae_u64 of static uae_u64 cmd_write (struct hardfiledata *hfd, uaecptr dataptr, uae_u64 offset, uae_u64 len) { addrbank *bank_data = &get_mem_bank (dataptr); - if (!bank_data || !bank_data->check (dataptr, len)) + if (!len || !bank_data || !bank_data->check (dataptr, len)) return 0; return cmd_writex (hfd, bank_data->xlateaddr (dataptr), offset, len); } @@ -1623,7 +1623,7 @@ static uae_u32 hardfile_do_io (struct hardfiledata *hfd, struct hardfileprivdata goto no_disk; offset = get_long (request + 44); len = get_long (request + 36); /* io_Length */ - if ((offset & bmask) || dataptr == 0) { + if (offset & bmask) { unaligned (cmd, offset, len, hfd->blocksize); goto bad_command; } @@ -1644,7 +1644,7 @@ static uae_u32 hardfile_do_io (struct hardfiledata *hfd, struct hardfileprivdata goto no_disk; offset64 = get_long (request + 44) | ((uae_u64)get_long (request + 32) << 32); len = get_long (request + 36); /* io_Length */ - if ((offset64 & bmask) || dataptr == 0) { + if (offset64 & bmask) { unaligned (cmd, offset64, len, hfd->blocksize); goto bad_command; } @@ -1668,7 +1668,7 @@ static uae_u32 hardfile_do_io (struct hardfiledata *hfd, struct hardfileprivdata } else { offset = get_long (request + 44); len = get_long (request + 36); /* io_Length */ - if ((offset & bmask) || dataptr == 0) { + if (offset & bmask) { unaligned (cmd, offset, len, hfd->blocksize); goto bad_command; } @@ -1695,7 +1695,7 @@ static uae_u32 hardfile_do_io (struct hardfiledata *hfd, struct hardfileprivdata } else { offset64 = get_long (request + 44) | ((uae_u64)get_long (request + 32) << 32); len = get_long (request + 36); /* io_Length */ - if ((offset64 & bmask) || dataptr == 0) { + if (offset64 & bmask) { unaligned (cmd, offset64, len, hfd->blocksize); goto bad_command; } diff --git a/include/drawing.h b/include/drawing.h index f0eb1dfd..aacbdd2d 100644 --- a/include/drawing.h +++ b/include/drawing.h @@ -281,6 +281,7 @@ extern void notice_resolution_seen (int, bool); extern void frame_drawn (void); extern void redraw_frame (void); extern int get_custom_limits (int *pw, int *ph, int *pdx, int *pdy); +extern void set_custom_limits (int w, int h, int dx, int dy); extern void get_custom_topedge (int *x, int *y); extern void putpixel (uae_u8 *buf, int bpp, int x, xcolnr c8, int opaq); diff --git a/include/gui.h b/include/gui.h index be9c9ed6..403c3c5f 100644 --- a/include/gui.h +++ b/include/gui.h @@ -12,7 +12,7 @@ extern void gui_exit (void); extern void gui_led (int, int); extern void gui_handle_events (void); extern void gui_filename (int, const TCHAR *); -extern void gui_fps (int fps, int idle); +extern void gui_fps (int fps, int idle, int color); extern void gui_changesettings (void); extern void gui_lock (void); extern void gui_unlock (void); @@ -56,6 +56,7 @@ struct gui_info uae_u8 cd; /* CD */ uae_u8 md; /* CD32 or CDTV internal storage */ int fps, idle; + int fps_color; int sndbuf, sndbuf_status; TCHAR df[4][256]; /* inserted image */ uae_u32 crc32[4]; /* crc32 of image */ diff --git a/include/options.h b/include/options.h index f4668a08..fa3f7701 100644 --- a/include/options.h +++ b/include/options.h @@ -9,7 +9,7 @@ #define UAEMAJOR 2 #define UAEMINOR 4 -#define UAESUBREV 1 +#define UAESUBREV 2 typedef enum { KBD_LANG_US, KBD_LANG_DK, KBD_LANG_DE, KBD_LANG_SE, KBD_LANG_FR, KBD_LANG_IT, KBD_LANG_ES } KbdLang; @@ -141,6 +141,7 @@ enum { CP_GENERIC = 1, CP_CDTV, CP_CD32, CP_A500, CP_A500P, CP_A600, CP_A1000, #define AUTOSCALE_CENTER 6 #define AUTOSCALE_MANUAL 7 // use gfx_xcenter_pos and gfx_ycenter_pos #define AUTOSCALE_INTEGER 8 +#define AUTOSCALE_INTEGER_AUTOSCALE 9 #define MONITOREMU_NONE 0 #define MONITOREMU_AUTO 1 diff --git a/od-win32/direct3d.cpp b/od-win32/direct3d.cpp index 0c822c08..7f1bef3b 100644 --- a/od-win32/direct3d.cpp +++ b/od-win32/direct3d.cpp @@ -2295,7 +2295,8 @@ const TCHAR *D3D_init (HWND ahwnd, int w_w, int w_h, int depth, int mmult) write_log (_T("%s: CreateQuery(D3DQUERYTYPE_EVENT) failed: %s\n"), D3DHEAD, D3D_ErrorString (hr)); } if (d3ddevex) { - hr = d3ddevex->SetMaximumFrameLatency (vsync < 0 && ap->gfx_vflip <= 0 ? 1 : 0); + //hr = d3ddevex->SetMaximumFrameLatency (vsync < 0 && ap->gfx_vflip <= 0 ? 1 : (vsync ? 2 : 0)); + hr = d3ddevex->SetMaximumFrameLatency (vsync ? 1 : 0); if (FAILED (hr)) write_log (_T("%s: SetMaximumFrameLatency() failed: %s\n"), D3DHEAD, D3D_ErrorString (hr)); } @@ -2800,6 +2801,8 @@ uae_u8 *D3D_locktexture (int *pitch, bool fullupdate) static void flushgpu (bool wait) { + if (currprefs.turbo_emulation) + return; if (query) { HRESULT hr = query->Issue (D3DISSUE_END); if (SUCCEEDED (hr)) { diff --git a/od-win32/fsdb_mywin32.cpp b/od-win32/fsdb_mywin32.cpp index e087da4a..ea7527fb 100644 --- a/od-win32/fsdb_mywin32.cpp +++ b/od-win32/fsdb_mywin32.cpp @@ -353,9 +353,14 @@ int dos_errno (void) case ERROR_BAD_UNIT: case ERROR_REQUEST_ABORTED: case ERROR_INVALID_HANDLE: - case ERROR_BAD_NETPATH: case ERROR_DEV_NOT_EXIST: case ERROR_INVALID_PARAMETER: + case ERROR_NETNAME_DELETED: + case ERROR_NETWORK_ACCESS_DENIED: + case ERROR_BAD_NET_NAME: + case ERROR_BAD_NETPATH: + case ERROR_NETWORK_BUSY: + case ERROR_SEM_TIMEOUT: return ERROR_OBJECT_NOT_AROUND; case ERROR_HANDLE_DISK_FULL: diff --git a/od-win32/resources/resource b/od-win32/resources/resource index 465d454e..d4509d77 100644 --- a/od-win32/resources/resource +++ b/od-win32/resources/resource @@ -357,8 +357,8 @@ #define IDS_SCREEN_VSYNC2 377 #define IDS_SCREEN_VSYNC_NONE 378 #define IDS_FILTEROVERLAYTYPE_MASKS 379 -#define IDS_STRING380 380 #define IDS_FILTEROVERLAYTYPE_OVERLAYS 380 +#define IDS_AUTOSCALE_INTEGER_AUTOSCALE 381 #define IDS_QS_MODELS 1000 #define IDS_QS_MODEL_A500 1001 #define IDS_QS_MODEL_A500P 1002 @@ -1082,6 +1082,7 @@ #define IDC_CD_TYPE 1806 #define IDC_CD_SELECT 1807 #define IDC_FASTMEMAUTOCONFIG 1808 +#define IDC_RTG_DISPLAYSELECT 1809 #define ID__FLOPPYDRIVES 40004 #define ID_FLOPPYDRIVES_DF0 40005 #define ID_ST_CONFIGURATION 40010 @@ -1132,7 +1133,7 @@ #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 370 #define _APS_NEXT_COMMAND_VALUE 40050 -#define _APS_NEXT_CONTROL_VALUE 1809 +#define _APS_NEXT_CONTROL_VALUE 1810 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/od-win32/resources/winuae.rc b/od-win32/resources/winuae.rc index af7b3862..628bbc45 100644 --- a/od-win32/resources/winuae.rc +++ b/od-win32/resources/winuae.rc @@ -234,7 +234,7 @@ BEGIN CONTROL "Constant jump",IDC_CONSTJUMP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,100,208,63,10 CONTROL "FPU support",IDC_JITFPU,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,100,222,62,10 CONTROL "Indirect",IDC_TRUST1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,235,208,52,10 - EDITTEXT IDC_CACHETEXT2,265,175,30,12,ES_CENTER | ES_READONLY + EDITTEXT IDC_CACHETEXT,259,166,30,12,ES_CENTER | ES_READONLY CTEXT "CPU Speed",IDC_STATIC,93,76,43,9,SS_CENTERIMAGE END @@ -1004,14 +1004,14 @@ BEGIN CTEXT "Enter address",IDC_DBG_ADDRINPUTTXT,20,1,100,10,SS_CENTERIMAGE | WS_TABSTOP END -IDD_EXPANSION DIALOGEX 0, 0, 300, 206 +IDD_EXPANSION DIALOGEX 0, 0, 300, 230 STYLE DS_LOCALEDIT | DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD FONT 8, "MS Sans Serif", 0, 0, 0x1 BEGIN RTEXT "Memory: [] Graphics card memory. Required for RTG (Picasso96) emulation.",IDC_GFXCARDTEXT,25,35,53,10,SS_NOTIFY | SS_CENTERIMAGE CONTROL "",IDC_P96MEM,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,88,31,60,20 EDITTEXT IDC_P96RAM,152,34,34,12,ES_CENTER | ES_READONLY - GROUPBOX "RTG Graphics Card",IDC_STATIC,5,1,291,124 + GROUPBOX "RTG Graphics Card",IDC_STATIC,5,1,291,145 CONTROL "Scale if smaller than display size setting",IDC_RTG_SCALE, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,25,65,162,10 CONTROL "Match host and RTG color depth if possible",IDC_RTG_MATCH_DEPTH, @@ -1022,26 +1022,27 @@ BEGIN COMBOBOX IDC_RTG_32BIT,211,66,68,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP CONTROL "Always scale in windowed mode",IDC_RTG_SCALE_ALLOW, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,25,77,162,10 - COMBOBOX IDC_RTG_SCALE_ASPECTRATIO,211,108,68,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP - CTEXT "Aspect ratio:",IDC_STATIC,215,95,60,10,SS_CENTERIMAGE - CTEXT "Refresh rate:",IDC_STATIC,28,95,64,10,SS_CENTERIMAGE - COMBOBOX IDC_RTG_VBLANKRATE,24,108,68,150,CBS_DROPDOWN | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_RTG_SCALE_ASPECTRATIO,211,126,68,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP + CTEXT "Aspect ratio:",IDC_STATIC,215,113,60,10,SS_CENTERIMAGE + CTEXT "Refresh rate:",IDC_STATIC,28,113,64,10,SS_CENTERIMAGE + COMBOBOX IDC_RTG_VBLANKRATE,21,128,68,150,CBS_DROPDOWN | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP CONTROL "bsdsocket.library [] bsdsocket network library emulation.",IDC_SOCKETS, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,142,148,120,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,142,171,120,10 CONTROL "uaenet.device [] Sana 2 compatible network device emulation. WinPcap required.",IDC_SANA2, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,142,160,77,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,142,183,77,10 CONTROL "A2065 Z2 [] A2065 Ethernet Zorro II card emulation. WinPcap required.",IDC_A2065, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,233,160,57,10 - GROUPBOX "Network",IDC_STATIC,126,130,169,66 - COMBOBOX IDC_NETDEVICE,132,176,156,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "uaescsi.device",IDC_SCSIDEVICE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,160,102,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,233,183,57,10 + GROUPBOX "Network",IDC_STATIC,126,153,169,66 + COMBOBOX IDC_NETDEVICE,132,199,156,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "uaescsi.device",IDC_SCSIDEVICE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,183,102,10 CONTROL "Catweasel Z2 emulation [] Catweasel MK2 Zorro II card emulation. Physical Windows compatible Catweasel card and drivers required.",IDC_CATWEASEL, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,148,101,10 - GROUPBOX "Miscellaneous Expansions",IDC_STATIC,5,130,117,66 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,171,101,10 + GROUPBOX "Miscellaneous Expansions",IDC_STATIC,5,153,117,66 COMBOBOX IDC_RTG_Z2Z3,26,14,68,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP - CTEXT "Buffer mode:",IDC_STATIC,112,95,81,10,SS_CENTERIMAGE - COMBOBOX IDC_RTG_BUFFERCNT,111,108,84,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP + CTEXT "Buffer mode:",IDC_STATIC,112,113,81,10,SS_CENTERIMAGE + COMBOBOX IDC_RTG_BUFFERCNT,111,126,84,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP CTEXT "Color modes:",IDC_STATIC,215,9,62,10,SS_CENTERIMAGE + COMBOBOX IDC_RTG_DISPLAYSELECT,11,94,279,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP END IDD_INPUTMAP DIALOGEX 0, 0, 300, 240 @@ -1071,8 +1072,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,4,1,0 - PRODUCTVERSION 2,4,1,0 + FILEVERSION 2,4,2,0 + PRODUCTVERSION 2,4,2,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -1088,12 +1089,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "WinUAE" - VALUE "FileVersion", "2.4.1.0" + VALUE "FileVersion", "2.4.2.0" VALUE "InternalName", "WinUAE" VALUE "LegalCopyright", "© 1996-2012 under the GNU Public License (GPL)" VALUE "OriginalFilename", "WinUAE.exe" VALUE "ProductName", "WinUAE" - VALUE "ProductVersion", "2.4.1.0" + VALUE "ProductVersion", "2.4.2.0" END END BLOCK "VarFileInfo" @@ -1709,6 +1710,7 @@ BEGIN IDS_SCREEN_VSYNC_NONE "-" IDS_FILTEROVERLAYTYPE_MASKS "Masks" IDS_FILTEROVERLAYTYPE_OVERLAYS "Overlays" + IDS_AUTOSCALE_INTEGER_AUTOSCALE "Auto Integer scaling" END STRINGTABLE diff --git a/od-win32/resources/winuae_minimal.rc b/od-win32/resources/winuae_minimal.rc index b4f2f408..f617481d 100644 --- a/od-win32/resources/winuae_minimal.rc +++ b/od-win32/resources/winuae_minimal.rc @@ -214,17 +214,12 @@ BEGIN CONTROL "More compatible [] More compatible but slower FPU emulation.",IDC_COMPATIBLE_FPU, "Button",BS_AUTOCHECKBOX | BS_LEFT | WS_GROUP | WS_TABSTOP,9,221,73,10 GROUPBOX "CPU Emulation Speed",IDC_STATIC,90,3,205,92 - CONTROL "Fastest possible, but maintain chipset timing",IDC_CS_HOST, - "Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_GROUP | WS_TABSTOP,95,18,195,10 - CONTROL "Approximate A500 or A500/A1200 cycle-exact",IDC_CS_68000, + CONTROL "Fastest possible",IDC_CS_HOST,"Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_GROUP | WS_TABSTOP,95,18,195,10 + CONTROL "Approximate A500/A1200 or cycle-exact",IDC_CS_68000, "Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_TABSTOP,95,32,195,10 - CONTROL "Adjustable between CPU and chipset",IDC_CS_ADJUSTABLE, - "Button",BS_AUTORADIOBUTTON | BS_LEFT | WS_TABSTOP,95,46,195,10 - RTEXT "CPU",IDC_STATIC,96,77,17,10,SS_CENTERIMAGE - CONTROL "Slider1",IDC_SPEED,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,114,71,67,20 - RTEXT "Chipset",IDC_STATIC,182,77,26,9,SS_CENTERIMAGE + CONTROL "Slider1",IDC_SPEED,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,96,51,192,20 CONTROL "",IDC_CPUIDLE,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,219,71,69,20 - RTEXT "CPU Idle",IDC_STATIC,231,60,47,9,SS_CENTERIMAGE + CTEXT "CPU Idle",IDC_STATIC,179,76,35,9,SS_CENTERIMAGE GROUPBOX "Cycle-exact CPU Emulation Speed",IDC_STATIC,90,99,205,46 RTEXT "CPU Frequency",IDC_STATIC,105,119,51,10,SS_CENTERIMAGE COMBOBOX IDC_CPU_FREQUENCY,165,118,46,75,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP @@ -232,13 +227,15 @@ BEGIN GROUPBOX "Advanced JIT Settings",IDC_STATIC,90,147,205,91 RTEXT "Cache size:",IDC_STATIC,95,167,42,10,SS_CENTERIMAGE CONTROL "Slider1",IDC_CACHE,"msctls_trackbar32",TBS_AUTOTICKS | TBS_TOP | WS_TABSTOP,140,161,115,20 - EDITTEXT IDC_CACHETEXT,255,166,30,12,ES_CENTER | ES_READONLY + EDITTEXT IDC_CPUTEXT,144,75,30,12,ES_CENTER | ES_READONLY CONTROL "Hard flush",IDC_HARDFLUSH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,100,194,63,10 CONTROL "No flags",IDC_NOFLAGS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,168,194,62,10 CONTROL "Direct",IDC_TRUST0,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,235,194,52,10 CONTROL "Constant jump",IDC_CONSTJUMP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,100,208,63,10 CONTROL "FPU support",IDC_JITFPU,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,100,222,62,10 CONTROL "Indirect",IDC_TRUST1,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,235,208,52,10 + EDITTEXT IDC_CACHETEXT2,265,175,30,12,ES_CENTER | ES_READONLY + CTEXT "CPU Speed",IDC_STATIC,93,76,43,9,SS_CENTERIMAGE END IDD_FLOPPY DIALOGEX 0, 0, 300, 240 @@ -775,7 +772,7 @@ BEGIN EDITTEXT IDC_FILTERXLV,253,176,34,12,ES_CENTER | ES_READONLY COMBOBOX IDC_FILTERSLR,253,151,33,150,CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP GROUPBOX "Presets",-1,0,203,296,36 - COMBOBOX IDC_FILTERPRESETS,8,217,119,150,CBS_DROPDOWN | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_FILTERPRESETS,8,217,119,150,CBS_DROPDOWN | CBS_SORT | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "Load",IDC_FILTERPRESETLOAD,132,216,47,14 PUSHBUTTON "Save",IDC_FILTERPRESETSAVE,184,216,47,14 PUSHBUTTON "Delete",IDC_FILTERPRESETDELETE,236,216,47,14 @@ -1074,8 +1071,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,4,0,0 - PRODUCTVERSION 2,4,0,0 + FILEVERSION 2,4,1,0 + PRODUCTVERSION 2,4,1,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -1091,12 +1088,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "WinUAE" - VALUE "FileVersion", "2.4.0.0" + VALUE "FileVersion", "2.4.1.0" VALUE "InternalName", "WinUAE" VALUE "LegalCopyright", "© 1996-2012 under the GNU Public License (GPL)" VALUE "OriginalFilename", "WinUAE.exe" VALUE "ProductName", "WinUAE" - VALUE "ProductVersion", "2.4.0.0" + VALUE "ProductVersion", "2.4.1.0" END END BLOCK "VarFileInfo" @@ -1690,6 +1687,8 @@ BEGIN IDS_SCREEN_VSYNC2_AUTOSWITCH "Low latency VS, 50/60Hz" IDS_SCREEN_VSYNC2 "Low latency VSync" IDS_SCREEN_VSYNC_NONE "-" + IDS_FILTEROVERLAYTYPE_MASKS "Masks" + IDS_FILTEROVERLAYTYPE_OVERLAYS "Overlays" END STRINGTABLE diff --git a/od-win32/win32.cpp b/od-win32/win32.cpp index 00a708d7..9e67ddc4 100644 --- a/od-win32/win32.cpp +++ b/od-win32/win32.cpp @@ -1869,7 +1869,7 @@ void handle_events (void) setpaused (pause_emulation); was_paused = pause_emulation; manual_painting_needed++; - gui_fps (0, 0); + gui_fps (0, 0, 0); } while (PeekMessage (&msg, 0, 0, 0, PM_REMOVE)) { TranslateMessage (&msg); @@ -4734,8 +4734,12 @@ static int parseargs (const TCHAR *argx, const TCHAR *np, const TCHAR *np2) log_uaeserial = 1; return 1; } - if (!_tcscmp (arg, _T("vsynclog"))) { - log_vsync = 1; + if (!_tcscmp (arg, _T("vsynclog")) || !_tcscmp (arg, _T("vsynclog1"))) { + log_vsync |= 1; + return 1; + } + if (!_tcscmp (arg, _T("vsynclog2"))) { + log_vsync |= 2; return 1; } if (!_tcscmp (arg, _T("clipboarddebug"))) { diff --git a/od-win32/win32.h b/od-win32/win32.h index 0bb8ee2f..f9a063be 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -15,12 +15,12 @@ #define GETBDM(x) (((x) - ((x / 10000) * 10000)) / 100) #define GETBDD(x) ((x) % 100) -#define WINUAEPUBLICBETA 0 +#define WINUAEPUBLICBETA 1 #define LANG_DLL 1 -#define WINUAEBETA _T("") -//#define WINUAEBETA _T("14") -#define WINUAEDATE MAKEBD(2012, 5, 9) +//#define WINUAEBETA _T("") +#define WINUAEBETA _T("1") +#define WINUAEDATE MAKEBD(2012, 5, 13) #define WINUAEEXTRA _T("") //#define WINUAEEXTRA _T("AmiKit Preview") #define WINUAEREV _T("") diff --git a/od-win32/win32_scaler.cpp b/od-win32/win32_scaler.cpp index 9d04ee84..a5774283 100644 --- a/od-win32/win32_scaler.cpp +++ b/od-win32/win32_scaler.cpp @@ -229,6 +229,8 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height } } + set_custom_limits (-1, -1, -1, -1); + if (scalemode) { int cw, ch, cx, cy, cv; static int oxmult, oymult; @@ -236,7 +238,7 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height filterxmult = 1000 / scale; filterymult = 1000 / scale; - if (scalemode == AUTOSCALE_STATIC_MAX || scalemode == AUTOSCALE_STATIC_NOMINAL || scalemode == AUTOSCALE_INTEGER) { + if (scalemode == AUTOSCALE_STATIC_MAX || scalemode == AUTOSCALE_STATIC_NOMINAL || scalemode == AUTOSCALE_INTEGER || scalemode == AUTOSCALE_INTEGER_AUTOSCALE) { if (specialmode) { cx = 0; @@ -255,12 +257,14 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height cw -= 40 << currprefs.gfx_resolution; ch -= 25 << currprefs.gfx_vresolution; } + set_custom_limits (cw, ch, cx, cy); } - if (scalemode == AUTOSCALE_INTEGER) { + if (scalemode == AUTOSCALE_INTEGER || scalemode == AUTOSCALE_INTEGER_AUTOSCALE) { int maxw = currprefs.gfx_size.width; int maxh = currprefs.gfx_size.height; int mult = 1; + bool ok = true; if (currprefs.gfx_xcenter_pos >= 0 || currprefs.gfx_ycenter_pos >= 0) { changed_prefs.gfx_filter_horiz_offset = currprefs.gfx_filter_horiz_offset = 0; @@ -270,16 +274,31 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height get_custom_topedge (&cx, &cy); } - getmanualpos (&cx, &cy, &cw, &ch); - - if (cw > maxw || ch > maxh) { - while (cw / mult > maxw || ch / mult > maxh) + if (scalemode == AUTOSCALE_INTEGER_AUTOSCALE) + ok = get_custom_limits (&cw, &ch, &cx, &cy); + if (scalemode == AUTOSCALE_INTEGER || ok == false) + getmanualpos (&cx, &cy, &cw, &ch); + + int cw2 = cw + filter_horiz_zoom; + int ch2 = ch + filter_vert_zoom; + + extraw = 0; + extrah = 0; + xmult = 1000.0; + ymult = 1000.0; + filter_horiz_zoom = 0; + filter_vert_zoom = 0; + filter_horiz_zoom_mult = 1000.0; + filter_vert_zoom_mult = 1000.0; + + if (cw2 > maxw || ch2 > maxh) { + while (cw2 / mult > maxw || ch2 / mult > maxh) mult *= 2; maxw = maxw * mult; maxh = maxh * mult; } else { - while (cw * (mult * 2) <= maxw && ch * (mult * 2) <= maxh) - mult *= 2; + while (cw2 * (mult + 1) <= maxw && ch2 * (mult + 1) <= maxh) + mult++; maxw = (maxw + mult - 1) / mult; maxh = (maxh + mult - 1) / mult; } @@ -301,6 +320,7 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height //write_log (_T("%dx%d %dx%d\n"), cx, cy, currprefs.gfx_resolution, currprefs.gfx_vresolution); getmanualpos (&cx, &cy, &cw, &ch); + set_custom_limits (cw, ch, cx, cy); //write_log (_T("%dx%d %dx%d %dx%d\n"), currprefs.gfx_xcenter_pos, currprefs.gfx_ycenter_pos, cx, cy, cw, ch); @@ -309,6 +329,8 @@ void getfilterrect2 (RECT *sr, RECT *dr, RECT *zr, int dst_width, int dst_height } else { cv = get_custom_limits (&cw, &ch, &cx, &cy); + if (cv) + set_custom_limits (cw, ch, cx, cy); } diff --git a/od-win32/win32gfx.cpp b/od-win32/win32gfx.cpp index 235b26d2..57651dd8 100644 --- a/od-win32/win32gfx.cpp +++ b/od-win32/win32gfx.cpp @@ -654,7 +654,7 @@ static BOOL CALLBACK monitorEnumProc (HMONITOR h, HDC hdc, LPRECT rect, LPARAM d MONITORINFOEX lpmi; lpmi.cbSize = sizeof lpmi; GetMonitorInfo(h, (LPMONITORINFO)&lpmi); - while (md - Displays < MAX_DISPLAYS && md->monitorid[0]) { + while (md - Displays < MAX_DISPLAYS && md->monitorid) { if (!_tcscmp (md->adapterid, lpmi.szDevice)) { TCHAR tmp[1000]; md->rect = lpmi.rcMonitor; @@ -1445,7 +1445,7 @@ static int open_windows (int full) setmouseactive (-1); for (i = 0; i < NUM_LEDS; i++) gui_led (i, 0); - gui_fps (0, 0); + gui_fps (0, 0, 0); inputdevice_acquire (TRUE); return ret; @@ -1954,20 +1954,35 @@ bool vsync_switchmode (int hz) struct MultiDisplay *md = getdisplay (&currprefs); struct PicassoResolution *found; int newh, i, cnt; + bool preferdouble = 0; + + if (currprefs.gfx_apmode[0].gfx_refreshrate > 85) { + preferdouble = 1; + } + + if (hz >= 55) + hz = 60; + else + hz = 50; newh = h * (currprefs.ntscmode ? 60 : 50) / hz; found = NULL; for (cnt = 0; cnt <= abs (newh - h) + 1 && !found; cnt++) { - for (i = 0; md->DisplayModes[i].depth >= 0 && !found; i++) { - struct PicassoResolution *r = &md->DisplayModes[i]; - if (r->res.width == w && (r->res.height == newh + cnt || r->res.height == newh - cnt) && r->depth == d) { - int j; - for (j = 0; r->refresh[j] > 0; j++) { - if (r->refresh[j] == hz || r->refresh[j] == hz * 2) { - found = r; - hz = r->refresh[j]; - break; + for (int dbl = 0; dbl < 2 && !found; dbl++) { + bool doublecheck = (dbl == 0 && preferdouble) || (dbl == 1 && !preferdouble); + for (int extra = 1; extra >= -1 && !found; extra--) { + for (i = 0; md->DisplayModes[i].depth >= 0 && !found; i++) { + struct PicassoResolution *r = &md->DisplayModes[i]; + if (r->res.width == w && (r->res.height == newh + cnt || r->res.height == newh - cnt) && r->depth == d) { + int j; + for (j = 0; r->refresh[j] > 0; j++) { + if ((!doublecheck && r->refresh[j] == hz + extra) || (doublecheck && r->refresh[j] == hz * 2 + extra)) { + found = r; + hz = r->refresh[j]; + break; + } + } } } } @@ -2660,7 +2675,6 @@ static unsigned int __stdcall vblankthread (void *dummy) vblank_found_chipset = true; if (!ap->gfx_vflip) { while (!render_ok) { - sleep_millis (1); if (read_processor_time () - t > vblankbasefull) break; } @@ -2720,26 +2734,31 @@ static bool isthreadedvsync (void) frame_time_t vsync_busywait_end (int *flipdelay) { if (isthreadedvsync ()) { - frame_time_t prev; - for (;;) { - int v = vblankthread_mode; - if (v != VBLANKTH_ACTIVE_START && v != VBLANKTH_ACTIVE_SKIPFRAME && v != VBLANKTH_ACTIVE_SKIPFRAME2) - break; - sleep_millis_main (1); - } - prev = vblank_prev_time; - if (!dooddevenskip) { - int delay = 10; - frame_time_t t = read_processor_time (); - while (delay-- > 0) { - if (WaitForSingleObject (vblankwaitevent, 10) != WAIT_TIMEOUT) + + if (!currprefs.turbo_emulation) { + for (;;) { + int v = vblankthread_mode; + if (v != VBLANKTH_ACTIVE_START && v != VBLANKTH_ACTIVE_SKIPFRAME && v != VBLANKTH_ACTIVE_SKIPFRAME2) break; + sleep_millis_main (1); + } + prev = vblank_prev_time; + if (!dooddevenskip) { + int delay = 10; + frame_time_t t = read_processor_time (); + while (delay-- > 0) { + if (WaitForSingleObject (vblankwaitevent, 10) != WAIT_TIMEOUT) + break; + } + idletime += read_processor_time () - t; } - idletime += read_processor_time () - t; + if (flipdelay) + *flipdelay = vblank_found_flipdelay; + } else { + show_screen (); + prev = read_processor_time (); } - if (flipdelay) - *flipdelay = vblank_found_flipdelay; changevblankthreadmode_fast (VBLANKTH_ACTIVE_WAIT); return prev + vblankbasefull; } else { @@ -2751,7 +2770,9 @@ frame_time_t vsync_busywait_end (int *flipdelay) void vsync_busywait_start (void) { - if (vblankthread_mode != VBLANKTH_ACTIVE_WAIT) + if (vblankthread_mode < 0) + write_log (L"low latency threaded mode but thread is not running!?\n"); + else if (vblankthread_mode != VBLANKTH_ACTIVE_WAIT) write_log (L"low latency vsync state mismatch %d\n", vblankthread_mode); changevblankthreadmode_fast (VBLANKTH_ACTIVE_START); } @@ -2784,16 +2805,12 @@ bool vsync_busywait_do (int *freetime, bool lace, bool oddeven) return true; } - if (0 || log_vsync) { + if (log_vsync & 1) { console_out_f(_T("F:%8d M:%8d E:%8d %3d%% (%3d%%) %10d\r"), frame_counted, frame_missed, frame_errors, frame_usage, frame_usage_avg, (t - vblank_prev_time) - vblankbasefull); } if (freetime) *freetime = 0; - if (currprefs.turbo_emulation) { - frame_missed++; - return true; - } frame_usage = (t - prevtime) * 100 / vblankbasefull; if (frame_usage > 99) @@ -2828,6 +2845,12 @@ bool vsync_busywait_do (int *freetime, bool lace, bool oddeven) dooddevenskip = true; } + if (currprefs.turbo_emulation) { + show_screen (); + vblank_prev_time = read_processor_time (); + return true; + } + if (!doskip) { int vp; while (!framelost && read_processor_time () - prevtime < vblankbasewait1) { @@ -2910,6 +2933,18 @@ double vblank_calibrate (double approx_vblank, bool waitonly) rate = ap->gfx_refreshrate; mode = isfullscreen (); + + // clear remembered modes if restarting and start thread again. + if (vblankthread_mode <= 0) { + rv = vsyncmemory; + while (rv) { + struct remembered_vsync *rvo = rv->next; + xfree (rv); + rv = rvo; + } + vsyncmemory = NULL; + } + rv = vsyncmemory; while (rv) { if (rv->width == width && rv->height == height && rv->depth == depth && rv->rate == rate && rv->mode == mode && rv->rtg == picasso_on) { @@ -2939,6 +2974,7 @@ double vblank_calibrate (double approx_vblank, bool waitonly) flipevent2 = CreateEvent (NULL, FALSE, FALSE, NULL); vblankwaitevent = CreateEvent (NULL, FALSE, FALSE, NULL); _beginthreadex (NULL, 0, flipthread, 0, 0, &th); + write_log (_T("Low latency vsync thread started\n")); } else { changevblankthreadmode (VBLANKTH_CALIBRATE); } @@ -2998,8 +3034,9 @@ double vblank_calibrate (double approx_vblank, bool waitonly) if (cnt >= total) break; } + changevblankthreadmode (VBLANKTH_IDLE); - SetThreadPriority (th, oldpri); + if (maxcnt >= maxtotal) { tsum = tsum2 / tcnt2; write_log (_T("Unstable vsync reporting, using average value\n")); @@ -3007,6 +3044,30 @@ double vblank_calibrate (double approx_vblank, bool waitonly) tsum /= total; } + if (ap->gfx_vflip == 0) { + int vsdetect = 0; + int detectcnt = 6; + for (cnt = 0; cnt < detectcnt; cnt++) { + render_screen (true); + show_screen (); + sleep_millis (1); + frame_time_t t = read_processor_time () + 1 * (syncbase / tsum); + for (int cnt2 = 0; cnt2 < 4; cnt2++) { + render_ok = true; + show_screen (); + } + int diff = (int)read_processor_time () - (int)t; + if (diff >= 0) + vsdetect++; + } + if (vsdetect >= detectcnt / 2) { + write_log (L"Forced vsync detected, switching to double buffered\n"); + changed_prefs.gfx_apmode[0].gfx_backbuffers = 1; + } + } + + SetThreadPriority (th, oldpri); + if (waitonly) tsum = approx_vblank; skip: diff --git a/od-win32/win32gui.cpp b/od-win32/win32gui.cpp index b0fee77a..6ec61cf5 100644 --- a/od-win32/win32gui.cpp +++ b/od-win32/win32gui.cpp @@ -5842,49 +5842,51 @@ static void init_resolution_combo (HWND hDlg) } } -static void init_displays_combo (HWND hDlg) +static void init_displays_combo (HWND hDlg, bool rtg) { TCHAR *adapter = _T(""); struct MultiDisplay *md = Displays; int cnt = 0, cnt2 = 0; int displaynum; int idx = 0; + int id = rtg ? IDC_RTG_DISPLAYSELECT : IDC_DISPLAYSELECT; - displaynum = workprefs.gfx_apmode[APMODE_NATIVE].gfx_display - 1; + displaynum = workprefs.gfx_apmode[rtg ? APMODE_RTG : APMODE_NATIVE].gfx_display - 1; + SendDlgItemMessage (hDlg, id, CB_RESETCONTENT, 0, 0); if (displaynum < 0) displaynum = 0; - SendDlgItemMessage (hDlg, IDC_DISPLAYSELECT, CB_RESETCONTENT, 0, 0); while (md->monitorname) { if (_tcscmp (md->adapterkey, adapter) != 0) { - SendDlgItemMessage (hDlg, IDC_DISPLAYSELECT, CB_ADDSTRING, 0, (LPARAM)md->adaptername); + SendDlgItemMessage (hDlg, id, CB_ADDSTRING, 0, (LPARAM)md->adaptername); adapter = md->adapterkey; cnt++; } TCHAR buf[MAX_DPATH]; _stprintf (buf, _T(" %s"), md->fullname); - SendDlgItemMessage (hDlg, IDC_DISPLAYSELECT, CB_ADDSTRING, 0, (LPARAM)buf); + SendDlgItemMessage (hDlg, id, CB_ADDSTRING, 0, (LPARAM)buf); if (displaynum == cnt2) idx = cnt; md++; cnt2++; cnt++; } - SendDlgItemMessage (hDlg, IDC_DISPLAYSELECT, CB_SETCURSEL, idx, 0); + SendDlgItemMessage (hDlg, id, CB_SETCURSEL, idx, 0); } -static void get_displays_combo (HWND hDlg) +static bool get_displays_combo (HWND hDlg, bool rtg) { struct MultiDisplay *md = Displays; LRESULT posn; TCHAR *adapter = _T(""); int cnt = 0, cnt2 = 0; int displaynum; + int id = rtg ? IDC_RTG_DISPLAYSELECT : IDC_DISPLAYSELECT; - posn = SendDlgItemMessage (hDlg, IDC_DISPLAYSELECT, CB_GETCURSEL, 0, 0); + posn = SendDlgItemMessage (hDlg, id, CB_GETCURSEL, 0, 0); if (posn == CB_ERR) - return; + return false; - displaynum = workprefs.gfx_apmode[APMODE_NATIVE].gfx_display - 1; + displaynum = workprefs.gfx_apmode[rtg ? APMODE_RTG : APMODE_NATIVE].gfx_display - 1; if (displaynum < 0) displaynum = 0; while (md->monitorname) { @@ -5899,18 +5901,16 @@ static void get_displays_combo (HWND hDlg) foundnum = cnt2; if (foundnum >= 0) { if (foundnum == displaynum) - return; - workprefs.gfx_apmode[APMODE_NATIVE].gfx_display = foundnum + 1; - workprefs.gfx_apmode[APMODE_RTG].gfx_display = foundnum + 1; - init_displays_combo (hDlg); - init_resolution_combo (hDlg); - init_display_mode (hDlg); - return; + return false; + workprefs.gfx_apmode[rtg ? APMODE_RTG : APMODE_NATIVE].gfx_display = foundnum + 1; + init_displays_combo (hDlg, rtg); + return true; } cnt++; cnt2++; md++; } + return false; } static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) @@ -6046,7 +6046,9 @@ static void values_from_displaydlg (HWND hDlg, UINT msg, WPARAM wParam, LPARAM l if (msg == WM_COMMAND && HIWORD (wParam) == CBN_SELCHANGE) { if (LOWORD (wParam) == IDC_DISPLAYSELECT) { - get_displays_combo (hDlg); + get_displays_combo (hDlg, false); + init_resolution_combo (hDlg); + init_display_mode (hDlg); return; } else if (LOWORD (wParam) == IDC_LORES) { posn = SendDlgItemMessage (hDlg, IDC_LORES, CB_GETCURSEL, 0, 0); @@ -6110,7 +6112,7 @@ static INT_PTR CALLBACK DisplayDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LPAR SendDlgItemMessage (hDlg, IDC_FRAMERATE2, TBM_SETPAGESIZE, 0, 1); SendDlgItemMessage (hDlg, IDC_FRAMERATE2, TBM_SETRANGE, TRUE, MAKELONG (1, 99)); recursive++; - init_displays_combo (hDlg); + init_displays_combo (hDlg, false); init_resolution_combo (hDlg); init_da (hDlg); recursive--; @@ -6936,6 +6938,7 @@ static INT_PTR CALLBACK ExpansionDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP enumerated = 1; } expansion_net (hDlg); + init_displays_combo (hDlg, true); SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_RESETCONTENT, 0, 0); SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_ADDSTRING, 0, (LPARAM)_T("Zorro II")); SendDlgItemMessage (hDlg, IDC_RTG_Z2Z3, CB_ADDSTRING, 0, (LPARAM)_T("Zorro III (*)")); @@ -7049,6 +7052,9 @@ static INT_PTR CALLBACK ExpansionDlgProc (HWND hDlg, UINT msg, WPARAM wParam, LP uae_u32 mask = workprefs.picasso96_modeflags; switch (LOWORD (wParam)) { + case IDC_RTG_DISPLAYSELECT: + get_displays_combo (hDlg, true); + break; case IDC_RTG_BUFFERCNT: v = SendDlgItemMessage (hDlg, IDC_RTG_BUFFERCNT, CB_GETCURSEL, 0, 0L); if (v != CB_ERR) { @@ -12673,6 +12679,8 @@ static void values_to_hw3ddlg (HWND hDlg) SendDlgItemMessage (hDlg, IDC_FILTERAUTOSCALE, CB_ADDSTRING, 0, (LPARAM)txt); WIN32GUI_LoadUIString (IDS_AUTOSCALE_INTEGER, txt, sizeof (txt) / sizeof (TCHAR)); SendDlgItemMessage (hDlg, IDC_FILTERAUTOSCALE, CB_ADDSTRING, 0, (LPARAM)txt); + WIN32GUI_LoadUIString (IDS_AUTOSCALE_INTEGER_AUTOSCALE, txt, sizeof (txt) / sizeof (TCHAR)); + SendDlgItemMessage (hDlg, IDC_FILTERAUTOSCALE, CB_ADDSTRING, 0, (LPARAM)txt); SendDlgItemMessage (hDlg, IDC_FILTERAUTOSCALE, CB_SETCURSEL, workprefs.gfx_filter_autoscale, 0); int range1 = workprefs.gfx_filter_autoscale == AUTOSCALE_MANUAL ? -1 : -999; @@ -14887,10 +14895,11 @@ void gui_flicker_led (int led, int unitnum, int status) } } -void gui_fps (int fps, int idle) +void gui_fps (int fps, int idle, int color) { gui_data.fps = fps; gui_data.idle = idle; + gui_data.fps_color = color; gui_led (LED_FPS, 0); gui_led (LED_CPU, 0); gui_led (LED_SND, (gui_data.sndbuf_status > 1 || gui_data.sndbuf_status < 0) ? 0 : 1); diff --git a/od-win32/winuae_msvc10/winuae_msvc.vcxproj b/od-win32/winuae_msvc10/winuae_msvc.vcxproj index 22e4c2dc..2ba9e3bd 100644 --- a/od-win32/winuae_msvc10/winuae_msvc.vcxproj +++ b/od-win32/winuae_msvc10/winuae_msvc.vcxproj @@ -219,7 +219,7 @@ 0x0409 - ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;packet.lib;wpcap.lib;openal32.lib;libpng.lib;lglcd.lib;wtsapi32.lib;wntab32x.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;avrt.lib;hid.lib;%(AdditionalDependencies) + ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;packet.lib;wpcap.lib;openal32.lib;libpng15.lib;lglcd.lib;wtsapi32.lib;wntab32x.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;avrt.lib;hid.lib;%(AdditionalDependencies) $(OutDir)$(TargetName)$(TargetExt) true %(IgnoreSpecificDefaultLibraries) @@ -235,6 +235,8 @@ MachineX64 %(AdditionalLibraryDirectories);$(SolutionDir)\..\lib\ + + ..\resources\winuae64.exe.manifest;%(AdditionalManifestFiles) @@ -359,7 +361,7 @@ 0x0409 - ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;packet.lib;wpcap.lib;openal32.lib;libpng.lib;lglcd.lib;wtsapi32.lib;wntab32x.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;avrt.lib;hid.lib;%(AdditionalDependencies) + ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;packet.lib;wpcap.lib;openal32.lib;libpng15.lib;lglcd.lib;wtsapi32.lib;wntab32x.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;avrt.lib;hid.lib;%(AdditionalDependencies) NotSet $(OutDir)$(TargetName)$(TargetExt) true @@ -503,7 +505,7 @@ 0x0409 - ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;packet.lib;wpcap.lib;openal32.lib;libpng.lib;lglcd.lib;wtsapi32.lib;wntab32x.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;avrt.lib;hid.lib;%(AdditionalDependencies) + ws2_32.lib;ddraw.lib;dxguid.lib;winmm.lib;comctl32.lib;version.lib;vfw32.lib;msacm32.lib;dsound.lib;dinput8.lib;d3d9.lib;d3dx9.lib;setupapi.lib;wininet.lib;dxerr.lib;shlwapi.lib;zlibstat.lib;portaudio_x64.lib;packet.lib;wpcap.lib;openal32.lib;libpng15.lib;lglcd.lib;wtsapi32.lib;wntab32x.lib;enet_x64.lib;prowizard_x64.lib;lzmalib.lib;libFLAC_static.lib;avrt.lib;hid.lib;%(AdditionalDependencies) NotSet $(OutDir)$(TargetName)$(TargetExt) true diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index 37678178..789cf981 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -2,8 +2,36 @@ - restore only single input target to default. - hdd from command line - no-buffer tearing updates -- 50/60 autoswitch: support also 100/120 -- cd32 cda problems (universe, rnc loader) + + +- Autovsync 50/60Hz also accepts 100/120Hz modes if available, supports also refresh rates +-1 from nominal. +- CD32: CD command receive DMA emulation correctly emulated, TOC read hack removed. +- CD32: Repeat each CD TOC packet 3 times (same as real CD TOC format) (Universe title screen CDA) +- CD32: CD audio stopped if multiple play requests were sent very quickly (Universe in-game CDA) +- GUI RTG monitor selection implemented. +- Low latency vsync + fastest possible CPU auto adjustment updates. +- Legacy vsync automatic adjustment implemented, hopefully improves stability. (Remember that legacy + vsync is only compatible with approximate/ce CPU modes) +- FPS led background flashes yellow if frame was missed in vsync modes. +- Detect display driver forced vsync, switch to double buffered mode if low latency no buffer mode. +- Always call D3D SetMaximumFrameLatency(1) if vsync mode (any vsync) to reduce latency, previously + was only called when low latency no buffer mode used. (SetMaximumFrameLatency only available on + Vista and later) Usually display driver control panel can be also used to override this value. +- Added auto scale integer scaling method, uses autoscale display size instead of max overscan. +- Integer scale mode filter horizontal and vertical zoom sliders value is now added to native screen + size before calculating integer scaling value. (Negative values reduce size of screen = scale to + higher multiplier earlier) +- Integer scaling supports non-power of 2 integer upscaling ratios now, downscaling still only supports + 1/2, 1/4 and so on to prevent scaling artifacts or blurriness. +- Warp mode now works properly in all vsync modes. +- Most filter modes (autoscale etc..) now fill "invisible" borders with black, for example this removes + ugly extra border(s) in autoscale fullscreen or full-window mode when using non-4:3 displays. + (In other words anything outside of 4:3 sized window are now blanked in non-4:3 screen/window sizes) +- Low latency vsync displayed blank screen if emulation was restarted using GUI Restart button. +- JIT GUI cache size box was broken. +- Do not return error code if uaehf.device read or write io command has null data pointer and length + is also zero. +- Added more Windows error codes to directory filesystem to AmigaDOS error conversion table. 2.4.1 diff --git a/statusline.cpp b/statusline.cpp index 7da39a5e..a0037c24 100644 --- a/statusline.cpp +++ b/statusline.cpp @@ -146,7 +146,7 @@ void draw_status_line_single (uae_u8 *buf, int bpp, int y, int totalwidth, uae_u int fps = (gui_data.fps + 5) / 10; pos = 2; on_rgb = 0x000000; - off_rgb = 0x000000; + off_rgb = gui_data.fps_color ? 0xcccc00 : 0x000000; if (fps > 999) fps = 999; num1 = fps / 100; -- 2.47.3