diff --git a/cfgfile.cpp b/cfgfile.cpp index d7746244..b06b9439 100644 --- a/cfgfile.cpp +++ b/cfgfile.cpp @@ -1296,7 +1296,9 @@ static void write_filesys_config (struct uae_prefs *p, struct zfile *f) if (ci->type == UAEDEV_DIR) { _stprintf (tmp, _T("%s,%s:%s:%s,%d"), ci->readonly ? _T("ro") : _T("rw"), ci->devname ? ci->devname : _T(""), ci->volname, str1c, bp); - cfgfile_write_str (f, _T("filesystem2"), tmp); + if (p->got_fs2_hdf2 >= 0) { + cfgfile_write_str (f, _T("filesystem2"), tmp); + } _tcscpy (tmp3, tmp); #if 0 _stprintf (tmp2, _T("filesystem=%s,%s:%s"), uci->readonly ? _T("ro") : _T("rw"), @@ -1377,8 +1379,9 @@ static void write_filesys_config (struct uae_prefs *p, struct zfile *f) _tcscat(tmp3, _T(",identity")); } - if (ci->type == UAEDEV_HDF) + if (ci->type == UAEDEV_HDF && p->got_fs2_hdf2 >= 0) { cfgfile_write_str (f, _T("hardfile2"), tmp); + } #if 0 _stprintf (tmp2, _T("hardfile=%s,%d,%d,%d,%d,%s"), uci->readonly ? "ro" : "rw", uci->sectors, @@ -5316,7 +5319,7 @@ static int cfgfile_parse_newfilesys (struct uae_prefs *p, int nr, int type, TCHA _tcscpy (uci.devname, devname); if (! getintval (&tmpp, &uci.bootpri, 0)) goto empty_fs; - } else if (type == 1 || ((type == 2 || type == 3) && uaehfentry)) { + } else if (type == 1 || ((type == 2 || type == 3 || type == 4) && uaehfentry)) { tmpp = _tcschr (value, ':'); if (tmpp == 0) goto invalid_fs; @@ -5340,6 +5343,16 @@ static int cfgfile_parse_newfilesys (struct uae_prefs *p, int nr, int type, TCHA *tmpp++ = 0; _tcscpy (uci.rootdir, tmpp2); } + if (type == 4) { + const TCHAR *tmppr = tmpp; + const TCHAR *tmppr2 = tmpp; + TCHAR *root2 = getnextentry(&tmppr, ','); + if (root2) { + _tcscat(uci.rootdir, root2); + xfree(root2); + } + tmpp += tmppr - tmppr2; + } if (uci.rootdir[0] != ':') get_hd_geometry (&uci); _tcscpy (uci.devname, devname); @@ -5474,6 +5487,9 @@ static int cfgfile_parse_filesys (struct uae_prefs *p, const TCHAR *option, TCHA TCHAR tmp[100]; _stprintf (tmp, _T("uaehf%d"), i); if (!_tcscmp (option, tmp)) { + if (!p->got_fs2_hdf2) { + p->got_fs2_hdf2 = -1; + } for (;;) { int type = -1; int unit = -1; @@ -5482,9 +5498,12 @@ static int cfgfile_parse_filesys (struct uae_prefs *p, const TCHAR *option, TCHA return 1; *tmpp++ = 0; if (_tcsicmp (value, _T("hdf")) == 0) { - type = 1; - cfgfile_parse_partial_newfilesys (p, -1, type, tmpp, unit, true); - return 1; + if (p->got_fs2_hdf2 > 0) { + type = 1; + cfgfile_parse_partial_newfilesys (p, -1, type, tmpp, unit, true); + return 1; + } + type = 4; } else if (_tcsnicmp (value, _T("cd"), 2) == 0 && (value[2] == 0 || value[3] == 0)) { unit = 0; if (value[2] > 0) @@ -5499,9 +5518,11 @@ static int cfgfile_parse_filesys (struct uae_prefs *p, const TCHAR *option, TCHA if (unit >= 0 && unit <= MAX_TOTAL_SCSI_DEVICES) { type = 3; } - } else if (_tcsicmp (value, _T("dir")) != 0) { + } else if (_tcsicmp (value, _T("dir")) == 0) { + if (p->got_fs2_hdf2 > 0) { + return 1; + } type = 0; - return 1; /* ignore for now */ } if (type >= 0) cfgfile_parse_newfilesys (p, -1, type, tmpp, unit, true); @@ -5594,10 +5615,14 @@ static int cfgfile_parse_filesys (struct uae_prefs *p, const TCHAR *option, TCHA } - if (_tcscmp (option, _T("filesystem2")) == 0) + if (_tcscmp (option, _T("filesystem2")) == 0) { + p->got_fs2_hdf2 = 1; return cfgfile_parse_newfilesys (p, -1, 0, value, -1, false); - if (_tcscmp (option, _T("hardfile2")) == 0) + } + if (_tcscmp (option, _T("hardfile2")) == 0) { + p->got_fs2_hdf2 = 1; return cfgfile_parse_newfilesys (p, -1, 1, value, -1, false); + } if (_tcscmp (option, _T("filesystem_extra")) == 0) { int idx = 0; TCHAR *s = value; @@ -8412,6 +8437,7 @@ void default_prefs (struct uae_prefs *p, bool reset, int type) p->gfx_scandoubler = false; p->start_gui = true; p->start_debugger = false; + p->got_fs2_hdf2 = 0; p->all_lines = 0; /* Note to porters: please don't change any of these options! UAE is supposed diff --git a/custom.cpp b/custom.cpp index 21dbf040..b2aee33e 100644 --- a/custom.cpp +++ b/custom.cpp @@ -128,7 +128,7 @@ static struct rgabuf rga_pipe[RGA_SLOT_TOTAL + 1]; struct denise_rga rga_denise[DENISE_RGA_SLOT_TOTAL]; static struct linestate *current_line_state; static struct linestate lines[MAX_SCANDOUBLED_LINES][2]; -static int rga_denise_cycle, rga_denise_cycle_start, rga_denise_cycle_start_prev, rga_denise_cycle_count; +static int rga_denise_cycle, rga_denise_cycle_start, rga_denise_cycle_count; static int rga_denise_cycle_line = 1; static struct pipeline_reg preg; static struct pipeline_func pfunc[MAX_PIPELINE_REG]; @@ -2263,7 +2263,7 @@ static int GETHPOS(void) if (islightpentriggered()) { return hpos_lpen; } - if (!eventtab[ev_sync].active) { + if (!eventtab[ev_sync].active || syncs_stopped) { return agnus_hpos; } evt_t c = get_cycles(); @@ -10177,7 +10177,6 @@ static int wclks_prev; static void next_denise_rga(void) { - rga_denise_cycle_start_prev = rga_denise_cycle_start; rga_denise_cycle_start = rga_denise_cycle; rga_denise_cycle_count = 0; rga_denise[(rga_denise_cycle - 1) & DENISE_RGA_SLOT_MASK].line++; @@ -10206,6 +10205,7 @@ static void decide_line_end(void) static int getlinetype(void) { int type; + if (agnus_vb_active) { type = LINETYPE_BLANK; } else if (vdiwstate == diw_states::DIW_waiting_start || GET_PLANES(bplcon0) == 0 || !dmaen(DMA_BITPLANE)) { @@ -10431,7 +10431,7 @@ static void draw_line(void) int cslen = 10; draw_denise_line(dvp, nextline_how, rga_denise_cycle_line, rga_denise_cycle_start, rga_denise_cycle_count, display_hstart_cyclewait_skip, display_hstart_cyclewait_skip2, - wclks, cs, cslen); + wclks, cs, cslen, lol); } static void dmal_fast(void) @@ -10607,10 +10607,12 @@ static void quick_denise_rga(void) for (int i = 0; i < rga_denise_cycle_count; i++) { int off = i + rga_denise_cycle_start; struct denise_rga *rd = &rga_denise[off & DENISE_RGA_SLOT_MASK]; - if (rd->line == rga_denise_cycle_line && rd->rga != 0x1fe) { + if (rd->line == rga_denise_cycle_line && rd->rga != 0x1fe && (rd->rga < 0x38 || rd->rga >= 0x40)) { denise_update_reg(rd->rga, rd->v); } } + uae_u16 strobe = get_strobe_reg(0); + denise_handle_quick_strobe(strobe, display_hstart_fastmode); } static void do_draw_line(void) @@ -10683,6 +10685,7 @@ static int can_fast_custom(void) } compute_spcflag_copper(); if (copper_enabled_thisline) { + #if 0 // if copper is waiting, wake up is inside blank/border and // it is followed by only writes to color registers: @@ -11958,7 +11961,7 @@ static void fast_strobe(void) if (prev_strobe == 0x3c && str != 0x3c) { INTREQ_INT(5, 0); } - denise_handle_quick_strobe(str); + denise_handle_quick_strobe(str, display_hstart_fastmode); prev_strobe = str; } @@ -12015,6 +12018,9 @@ static void sync_equalline_handler(void) custom_trigger_start(); + int dvp = calculate_linetype(linear_display_vpos); + denise_set_line(dvp); + if (eventtab[ev_sync].active) { check_extra(); do_imm_dmal(); diff --git a/debug.cpp b/debug.cpp index af2f366e..3b592019 100644 --- a/debug.cpp +++ b/debug.cpp @@ -7731,6 +7731,7 @@ void debug (void) uae_ppc_pause(0); #endif setmouseactive(0, wasactive ? 2 : 0); + target_inputdevice_acquire(); last_cycles1 = get_cycles(); last_vpos1 = vpos; diff --git a/drawing.cpp b/drawing.cpp index 5f7abf74..c67fa65d 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -316,6 +316,7 @@ static uae_u8 pixx0, pixx1, pixx2, pixx3; static uae_u32 debug_buf[256 * 2 * 4], debug_bufx[256 * 2 * 4]; static uae_u32 *hbstrt_ptr1, *hbstrt_ptr2; static uae_u32 *hbstop_ptr1, *hbstop_ptr2; +static bool no_denise_lol; void set_inhibit_frame(int monid, int bit) { @@ -1874,8 +1875,6 @@ void vsync_handle_redraw(int long_field, int lof_changed, uae_u16 bplcon0p, uae_ if (ad->framecnt == 0) { init_drawing_frame(); - } else if (currprefs.cpu_memory_cycle_exact) { - //init_hardware_for_drawing_frame(); } } else { #if 0 @@ -1888,23 +1887,6 @@ void vsync_handle_redraw(int long_field, int lof_changed, uae_u16 bplcon0p, uae_ gui_flicker_led (-1, 0, 0); } - -static void dummy_flush_line(struct vidbuf_description *gfxinfo, struct vidbuffer *vb, int line_no) -{ -} - -static void dummy_flush_block(struct vidbuf_description *gfxinfo, struct vidbuffer *vb, int first_line, int last_line) -{ -} - -static void dummy_flush_screen(struct vidbuf_description *gfxinfo, struct vidbuffer *vb, int first_line, int last_line) -{ -} - -static void dummy_flush_clear_screen(struct vidbuf_description *gfxinfo, struct vidbuffer *vb) -{ -} - static int dummy_lock(struct vidbuf_description *gfxinfo, struct vidbuffer *vb) { return 1; @@ -1917,12 +1899,8 @@ static void dummy_unlock(struct vidbuf_description *gfxinfo, struct vidbuffer *v static void gfxbuffer_reset(int monid) { struct vidbuf_description *vidinfo = &adisplays[monid].gfxvidinfo; - vidinfo->drawbuffer.flush_line = dummy_flush_line; - vidinfo->drawbuffer.flush_block = dummy_flush_block; - vidinfo->drawbuffer.flush_screen = dummy_flush_screen; - vidinfo->drawbuffer.flush_clear_screen = dummy_flush_clear_screen; - vidinfo->drawbuffer.lockscr = dummy_lock; - vidinfo->drawbuffer.unlockscr = dummy_unlock; + vidinfo->drawbuffer.lockscr = dummy_lock; + vidinfo->drawbuffer.unlockscr = dummy_unlock; } void notice_resolution_seen (int res, bool lace) @@ -2060,6 +2038,7 @@ void reset_drawing(void) if (currprefs.gfx_overscanmode < OVERSCANMODE_OVERSCAN) { denise_vblank_extra = (OVERSCANMODE_OVERSCAN - currprefs.gfx_overscanmode) * 5; } + no_denise_lol = !currprefs.cpu_memory_cycle_exact && !currprefs.chipset_hr; } static void gen_direct_drawing_table(void) @@ -3010,6 +2989,10 @@ static void expand_clxcon2(uae_u16 v) static void set_strlong(void) { + if (no_denise_lol) { + denise_strlong = false; + return; + } denise_strlong = true; if (!strlong_emulation) { write_log("STRLONG strobe emulation activated.\n"); @@ -3496,6 +3479,9 @@ static void expand_drga(struct denise_rga *rd) } if ((rd->flags & DENISE_RGA_FLAG_LOL)) { agnus_lol = (rd->flags & DENISE_RGA_FLAG_LOL_ON) != 0; + if (no_denise_lol) { + agnus_lol = false; + } if (!agnus_lol && !denise_lol_shift_prev) { int add = 1 << hresolution; buf1 += add; @@ -4229,11 +4215,15 @@ static void do_hstop_ecs(int cnt) #endif } -void denise_handle_quick_strobe(uae_u16 strobe) +// fix strobe position after fast mode +void denise_handle_quick_strobe(uae_u16 strobe, int offset) { struct denise_rga rd = { 0 }; rd.rga = strobe; handle_strobes(&rd); + // 3 = refresh offset, 2 = pipeline delay + denise_hcounter_new = (offset - 3 - 2) * 2 + 2; + denise_hcounter = denise_hcounter_new; } void denise_handle_quick_disable_hblank(void) { @@ -4800,11 +4790,20 @@ static void lts_null(void) } } +static int prevline; + +// set highest line, used in fast mode emulation +void denise_set_line(int gfx_ypos) +{ + if (gfx_ypos < prevline) { + prevline = gfx_ypos; + } +} + static void get_line(int gfx_ypos, enum nln_how how) { struct vidbuf_description *vidinfo = &adisplays[0].gfxvidinfo; struct vidbuffer *vb = &vidinfo->drawbuffer; - static int prevline; xlinebuffer = NULL; xlinebuffer2 = NULL; @@ -4919,7 +4918,7 @@ static void denise_draw_update(void) denise_max_odd_even = denise_odd_even; } -void draw_denise_line(int gfx_ypos, enum nln_how how, uae_u32 linecnt, int startpos, int total, int skip, int skip2, int dtotal, int calib_start, int calib_len) +void draw_denise_line(int gfx_ypos, enum nln_how how, uae_u32 linecnt, int startpos, int total, int skip, int skip2, int dtotal, int calib_start, int calib_len, bool lol) { bool fullline = false; // currprefs.chipset_hr; @@ -4942,6 +4941,9 @@ void draw_denise_line(int gfx_ypos, enum nln_how how, uae_u32 linecnt, int start get_line(gfx_ypos, how); hbstrt_ptr1 = NULL; + hbstrt_ptr2 = NULL; + hbstop_ptr1 = NULL; + hbstop_ptr2 = NULL; if (denise_pixtotal_max == -0x7fffffff || ((linear_vpos >= denise_vblank_extra_vbstop || linear_vpos < denise_vblank_extra_vbstrt) && currprefs.gfx_overscanmode < OVERSCANMODE_ULTRA)) { @@ -5024,7 +5026,7 @@ void draw_denise_line(int gfx_ypos, enum nln_how how, uae_u32 linecnt, int start #endif // blank last pixel row if normal overscan mode, it might have NTSC artifacts - if (denise_pixtotal_max != -0x7fffffff && hbstrt_ptr1 && currprefs.gfx_overscanmode <= OVERSCANMODE_OVERSCAN) { + if (denise_pixtotal_max != -0x7fffffff && hbstrt_ptr1 && currprefs.gfx_overscanmode <= OVERSCANMODE_OVERSCAN && !ecs_denise) { int add = 1 << hresolution; uae_u32 *p1 = hbstrt_ptr1 - denise_lol_shift_prev; uae_u32 *p2 = hbstrt_ptr2 - denise_lol_shift_prev; @@ -5033,8 +5035,17 @@ void draw_denise_line(int gfx_ypos, enum nln_how how, uae_u32 linecnt, int start *p2++ = 0x000000; } } - + if (no_denise_lol && denise_pixtotal_max != -0x7fffffff && hbstrt_ptr1 && !lol) { + int add = 1 << hresolution; + uae_u32 *p1 = hbstrt_ptr1 - denise_lol_shift_prev * 2; + uae_u32 *p2 = hbstrt_ptr2 - denise_lol_shift_prev * 2; + for (int i = 0; i < add * 2; i++) { + *p1++ = 0x000000; + *p2++ = 0x000000; + } + } if (currprefs.gfx_overscanmode < OVERSCANMODE_OVERSCAN) { + int add = 1 << hresolution; int w = (OVERSCANMODE_OVERSCAN - currprefs.gfx_overscanmode) * 8; if (currprefs.gfx_overscanmode == 0) { w -= 4; @@ -5042,34 +5053,44 @@ void draw_denise_line(int gfx_ypos, enum nln_how how, uae_u32 linecnt, int start w <<= hresolution; for (int i = 0; i < 4; i++) { uae_u32 *ptr, *ptr2; + int lolshift = 0; switch (i) { case 0: ptr = hbstrt_ptr1; ptr2 = buf1t; + lolshift = lol ? -add : 0; break; case 1: ptr = hbstrt_ptr2; ptr2 = buf2t; + lolshift = lol ? -add : 0; break; case 2: ptr = hbstop_ptr1; ptr2 = buf1t; + lolshift = lol ? add : 0; break; case 3: ptr = hbstop_ptr2; ptr2 = buf2t; + lolshift = lol ? add : 0; break; - } if (ptr) { - uae_u32 *p1 = ptr - denise_lol_shift_prev; - memset(p1, 0, w * sizeof(uae_u32)); - memset(p1 - w, 0, w * sizeof(uae_u32)); + uae_u32 *p1 = ptr - lolshift; + if (i >= 2) { + memset(p1, 0, w * sizeof(uae_u32)); + } else { + memset(p1 - w, 0, w * sizeof(uae_u32)); + } if (bufg) { uae_u16 *gp1 = (p1 - ptr2) + bufg; - memset(gp1, 0xff, w * sizeof(uae_u16)); - memset(gp1 - w, 0xff, w * sizeof(uae_u16)); + if (i >= 2) { + memset(gp1, 0xff, w * sizeof(uae_u16)); + } else { + memset(gp1 - w, 0xff, w * sizeof(uae_u16)); + } } } } @@ -5608,7 +5629,7 @@ static void lts_unaligned_ecs(int cnt, int cnt_next, int h) // bitplane and sprite merge & output if (!dpixcnt && buf1 && denise_pixtotal >= 0 && denise_pixtotal < denise_pixtotal_max) { - uae_u32 t = dtbuf[h ^ lol][ipix]; + uae_u32 t = dtbuf[h ^ lol][ipix]; #ifdef DEBUGGER if (decode_specials_debug) { diff --git a/include/drawing.h b/include/drawing.h index e5e79659..ecfecc32 100644 --- a/include/drawing.h +++ b/include/drawing.h @@ -165,7 +165,7 @@ void clear_inhibit_frame(int monid, int bit); void toggle_inhibit_frame(int monid, int bit); extern struct color_entry denise_colors; -void draw_denise_line(int gfx_ypos, nln_how how, uae_u32 linecnt, int startpos, int total, int skip, int skip2, int dtotal, int calib_start, int calib_len); +void draw_denise_line(int gfx_ypos, nln_how how, uae_u32 linecnt, int startpos, int total, int skip, int skip2, int dtotal, int calib_start, int calib_len, bool lol); bool draw_denise_line_fast(uae_u8 *bplpt[8], int bplstart, int bpllen, int gfx_ypos, enum nln_how how, int total, int dstart, int dtotal, bool vblank, struct denise_fastsprite *dfs); bool start_draw_denise(void); void end_draw_denise(void); @@ -174,8 +174,8 @@ void denise_reset(bool); bool denise_update_reg_queued(uae_u16 reg, uae_u16 v, uae_u32 cycle); void denise_store_registers(void); void denise_restore_registers(void); - +void denise_set_line(int gfx_ypos); void denise_handle_quick_disable_hblank(void); -void denise_handle_quick_strobe(uae_u16 strobe); +void denise_handle_quick_strobe(uae_u16 strobe, int offset); #endif /* UAE_DRAWING_H */ diff --git a/include/options.h b/include/options.h index 4a380f4a..cb76c596 100644 --- a/include/options.h +++ b/include/options.h @@ -519,6 +519,7 @@ struct uae_prefs { TCHAR config_all_path[MAX_DPATH]; TCHAR config_path[MAX_DPATH]; TCHAR config_window_title[256]; + int got_fs2_hdf2; bool illegal_mem; bool debug_mem; diff --git a/include/xwin.h b/include/xwin.h index b726001f..84d0b9a5 100644 --- a/include/xwin.h +++ b/include/xwin.h @@ -96,10 +96,6 @@ extern float getvsyncrate(int monid, float hz, int *mult); struct vidbuffer { /* Function implemented by graphics driver */ - void (*flush_line) (struct vidbuf_description *gfxinfo, struct vidbuffer *vb, int line_no); - void (*flush_block) (struct vidbuf_description *gfxinfo, struct vidbuffer *vb, int first_line, int end_line); - void (*flush_screen) (struct vidbuf_description *gfxinfo, struct vidbuffer *vb, int first_line, int end_line); - void (*flush_clear_screen) (struct vidbuf_description *gfxinfo, struct vidbuffer *vb); int (*lockscr) (struct vidbuf_description *gfxinfo, struct vidbuffer *vb); void (*unlockscr) (struct vidbuf_description *gfxinfo, struct vidbuffer *vb); uae_u8 *linemem; diff --git a/od-win32/win32.h b/od-win32/win32.h index 2bdda881..a099b60b 100644 --- a/od-win32/win32.h +++ b/od-win32/win32.h @@ -20,12 +20,12 @@ #define LANG_DLL_FULL_VERSION_MATCH 1 #if WINUAEPUBLICBETA -#define WINUAEBETA _T("8") +#define WINUAEBETA _T("9") #else #define WINUAEBETA _T("") #endif -#define WINUAEDATE MAKEBD(2025, 2, 15) +#define WINUAEDATE MAKEBD(2025, 2, 16) //#define WINUAEEXTRA _T("AmiKit Preview") //#define WINUAEEXTRA _T("Amiga Forever Edition") diff --git a/od-win32/winuaechangelog.txt b/od-win32/winuaechangelog.txt index b2992b46..c0980ac7 100644 --- a/od-win32/winuaechangelog.txt +++ b/od-win32/winuaechangelog.txt @@ -1,4 +1,13 @@ + +Beta 9: + +- Fixed b8 optimization glitch fixes, first bitplane line had horizontal offset in some situations (for example Pinball Dreams), Denise horizontal counter was not reset to correct "past" position and in some situations top part of screen was filled with black. +- If config file only has uaehfx config entries (No much older filesystem2 or hardfile2 entries before first uaehfx line), uaehfx entries are now fully loaded. uaehfx was added long time ago as a replacement for fs2/hf2 but they were only used to load extended information for previously loaded hardfile2 entry if it was real harddrive. When saving config loaded without filesystem2/hardfile2, only newer uaehfx entries are now written to config file. +- b8 when exiting debugger, restore focus back to previously active window now also works when log window is not initially open. +- Genlock misdetection (and hang) was still possible in some configs randomly. +- NTSC + optimized mode long/short line toggle caused glitches. This is not easy to work around so now NTSC does not do Denise side long/short line emulation unless at least memory cycle exact is enabled. (Which only means extremely weird programs that abuse STRLONG strobe can only work in cycle exact modes). There is still edge NTSC glitches visible, will be fixed later. + Beta 8: - More optimizations, now also uses line based emulation if scanline has bitplanes but it has not changed since last frame and line has no copper activity and no sprites. This restores performance compared to previous WinUAE versions when mostly static native display is visible (like WB or SysInfo screen :)) in non-cycle exact modes (including basic A500/A1200 + approximate CPU without CE). The less changing lines/copper activity the faster it becomes, almost static native screens are most likely faster than in old versions. Not perfect yet, some glitches can happen. Also more optimizations to do. This is more or less best of both worlds solution: chipset timing is accurate in all CPU modes (excluding blitter) but scanlines that have nothing interesting happening are emulated line based for best performance. Changed/non-changed line ratio logging is still active. Chipset panel subpixel emulation checkbox still disables this optimization. diff --git a/od-win32/writelog.cpp b/od-win32/writelog.cpp index 7e34b4dc..9fef5642 100644 --- a/od-win32/writelog.cpp +++ b/od-win32/writelog.cpp @@ -145,15 +145,23 @@ void deactivate_console(void) void activate_console(void) { - previousactivewindow = NULL; - if (!consoleopen) + if (!consoleopen) { + previousactivewindow = NULL; return; - previousactivewindow = GetForegroundWindow(); - SetForegroundWindow(GetConsoleWindow()); + } + HWND w = GetForegroundWindow(); + HWND cw = GetConsoleWindow(); + if (cw != w) { + previousactivewindow = w; + } + SetForegroundWindow(cw); } static void open_console_window (void) { + if (!consoleopen) { + previousactivewindow = GetForegroundWindow(); + } AllocConsole (); getconsole (); consoleopen = -1;