diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 71f38c139..b6dc66333 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -48,7 +48,11 @@ if(NOT WIN32 OR PTHREAD) target_sources(86Box PRIVATE thread.c) if(WIN32 AND VCPKG_TOOLCHAIN) find_package(pthreads REQUIRED) - target_link_libraries(86Box pthreads) + if (PThreads4W_FOUND) + target_link_libraries(86Box PThreads4W::PThreads4W) + else() + target_link_libraries(86Box pthreads) + endif() else() set(THREADS_PREFER_PTHREAD_FLAG TRUE) find_package(Threads REQUIRED) diff --git a/src/config.c b/src/config.c index 995bb801a..68f7b16c7 100644 --- a/src/config.c +++ b/src/config.c @@ -505,7 +505,7 @@ load_general(void) video_fullscreen_scale = config_get_int(cat, "video_fullscreen_scale", 0); - video_fullscreen_first = config_get_int(cat, "video_fullscreen_first", 1); + video_fullscreen_first = config_get_int(cat, "video_fullscreen_first", 0); video_filter_method = config_get_int(cat, "video_filter_method", 1); @@ -524,7 +524,10 @@ load_general(void) update_icons = config_get_int(cat, "update_icons", 1); window_remember = config_get_int(cat, "window_remember", 0); - if (window_remember) { + if (window_remember || (vid_resize & 2)) { + if (!window_remember) + config_delete_var(cat, "window_remember"); + p = config_get_string(cat, "window_coordinates", NULL); if (p == NULL) p = "0, 0, 0, 0"; @@ -2162,8 +2165,11 @@ save_general(void) else config_set_int(cat, "update_icons", update_icons); - if (window_remember) { - config_set_int(cat, "window_remember", window_remember); + if (window_remember || (vid_resize & 2)) { + if (window_remember) + config_set_int(cat, "window_remember", window_remember); + else + config_delete_var(cat, "window_remember"); sprintf(temp, "%i, %i, %i, %i", window_w, window_h, window_x, window_y); config_set_string(cat, "window_coordinates", temp); diff --git a/src/scsi/scsi_ncr5380.c b/src/scsi/scsi_ncr5380.c index c48af0ae5..2413c30a5 100644 --- a/src/scsi/scsi_ncr5380.c +++ b/src/scsi/scsi_ncr5380.c @@ -1362,7 +1362,7 @@ t128_read(uint32_t addr, void *priv) if (ncr_dev->t128.host_pos == MIN(512, dev->buffer_length)) { ncr_dev->t128.status &= ~0x04; ncr_log("Transfer busy read, status = %02x, period = %lf\n", ncr_dev->t128.status, ncr_dev->period); - if (ncr_dev->period == 0.2) + if (ncr_dev->period == 0.2 || ncr_dev->period == 0.02) timer_on_auto(&ncr_dev->timer, 40.2); } } diff --git a/src/thread.c b/src/thread.c index 916132fb2..b5151e573 100644 --- a/src/thread.c +++ b/src/thread.c @@ -2,8 +2,13 @@ #include #include #include +#ifndef _MSC_VER #include #include +#endif +#ifdef _WIN32 +#include +#endif #include #include <86box/86box.h> #include <86box/plat.h> @@ -103,6 +108,17 @@ thread_wait_event(event_t *handle, int timeout) event_pthread_t *event = (event_pthread_t *)handle; struct timespec abstime; +#ifdef _MSC_VER + /* Taken from https://stackoverflow.com/a/31335254 with some modifications. */ + FILETIME systime; + uint64_t systimeint = 0; + GetSystemTimeAsFileTime(&systime); + systimeint |= systime.dwLowDateTime; + systimeint |= (uint64_t)systime.dwHighDateTime << 32i64; + systimeint -= 116444736000000000i64; + abstime.tv_sec = systimeint / 10000000i64; + abstime.tv_nsec = systimeint % 10000000i64 * 100; +#else clock_gettime(CLOCK_REALTIME, &abstime); abstime.tv_nsec += (timeout % 1000) * 1000000; abstime.tv_sec += (timeout / 1000); @@ -110,6 +126,7 @@ thread_wait_event(event_t *handle, int timeout) abstime.tv_nsec -= 1000000000; abstime.tv_sec++; } +#endif pthread_mutex_lock(&event->mutex); if (timeout == -1) { @@ -138,7 +155,11 @@ thread_destroy_event(event_t *handle) void thread_sleep(int t) { +#ifdef _WIN32 + Sleep(t); +#else usleep(t * 1000); +#endif } diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index a1e52e02e..f13fbf980 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -386,6 +386,38 @@ static uint32_t s3_accel_in_l(uint16_t port, void *p); static uint8_t s3_pci_read(int func, int addr, void *p); static void s3_pci_write(int func, int addr, uint8_t val, void *p); +/*Remap address for chain-4/doubleword style layout*/ +static __inline uint32_t +dword_remap(svga_t *svga, uint32_t in_addr) +{ + if (svga->packed_chain4) + return in_addr; + + return ((in_addr << 2) & 0x3fff0) | + ((in_addr >> 14) & 0xc) | + (in_addr & ~0x3fffc); +} +static __inline uint32_t +dword_remap_w(svga_t *svga, uint32_t in_addr) +{ + if (svga->packed_chain4) + return in_addr; + + return ((in_addr << 2) & 0x1fff8) | + ((in_addr >> 14) & 0x6) | + (in_addr & ~0x1fffe); +} +static __inline uint32_t +dword_remap_l(svga_t *svga, uint32_t in_addr) +{ + if (svga->packed_chain4) + return in_addr; + + return ((in_addr << 2) & 0xfffc) | + ((in_addr >> 14) & 0x3) | + (in_addr & ~0xffff); +} + static void s3_update_irqs(s3_t *s3) { @@ -1742,6 +1774,7 @@ s3_hwcursor_draw(svga_t *svga, int displine) int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; uint32_t fg, bg; uint32_t real_addr; + uint32_t remapped_addr; switch (svga->bpp) { @@ -1806,8 +1839,10 @@ s3_hwcursor_draw(svga_t *svga, int displine) for (x = 0; x < 64; x += 16) { - dat[0] = (svga->vram[real_addr & s3->vram_mask] << 8) | svga->vram[(real_addr + 1) & s3->vram_mask]; - dat[1] = (svga->vram[(real_addr + 2) & s3->vram_mask] << 8) | svga->vram[(real_addr + 3) & s3->vram_mask]; + remapped_addr = dword_remap(svga, real_addr); + + dat[0] = (svga->vram[remapped_addr & s3->vram_mask] << 8) | svga->vram[(remapped_addr + 1) & s3->vram_mask]; + dat[1] = (svga->vram[(remapped_addr + 2) & s3->vram_mask] << 8) | svga->vram[(remapped_addr + 3) & s3->vram_mask]; if (svga->crtc[0x55] & 0x10) { /*X11*/ @@ -2420,6 +2455,8 @@ s3_out(uint16_t addr, uint8_t val, void *p) { case 0x31: s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4); + if (!svga->packed_chain4) + svga->force_dword_mode = val & 0x08; break; case 0x32: if ((svga->crtc[0x31] & 0x30) && (svga->crtc[0x51] & 0x01) && (val & 0x40)) @@ -2804,16 +2841,6 @@ static void s3_recalctimings(svga_t *svga) s3->width = 1024; } } - - if (s3->chip != S3_TRIO64 && s3->chip != S3_TRIO32) { - if (svga->crtc[0x31] & 0x08) {/*This would typically force dword mode, but we are encountering accel bugs with it, so force byte mode instead*/ - if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) - svga->force_byte_mode = 0; - else - svga->force_byte_mode = 1; - } else - svga->force_byte_mode = 0; - } if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { switch (svga->bpp) { @@ -3205,14 +3232,17 @@ s3_updatemapping(s3_t *s3) svga->banked_mask = 0xffff; } } else { - if (s3->chip >= S3_TRIO64V) + if (s3->chip >= S3_TRIO64V) { s3->linear_base &= 0xfc000000; - else if (s3->chip == S3_VISION968 || s3->chip == S3_VISION868) + svga->fb_only = 1; + } else if (s3->chip == S3_VISION968 || s3->chip == S3_VISION868) s3->linear_base &= 0xfe000000; mem_mapping_set_addr(&s3->linear_mapping, s3->linear_base, s3->linear_size); } } else { mem_mapping_disable(&s3->linear_mapping); + if (s3->chip >= S3_TRIO64V) + svga->fb_only = 0; } /* Memory mapped I/O. */ @@ -4215,10 +4245,10 @@ polygon_setup(s3_t *s3) } } -#define READ(addr, dat) if (s3->bpp == 0) dat = svga->vram[(addr) & s3->vram_mask]; \ - else if (s3->bpp == 1) dat = vram_w[(addr) & (s3->vram_mask >> 1)]; \ - else if (s3->bpp == 2) dat = svga->vram[(addr) & s3->vram_mask]; \ - else dat = vram_l[(addr) & (s3->vram_mask >> 2)]; +#define READ(addr, dat) if (s3->bpp == 0) dat = svga->vram[dword_remap(svga, addr) & s3->vram_mask]; \ + else if (s3->bpp == 1) dat = vram_w[dword_remap_w(svga, addr) & (s3->vram_mask >> 1)]; \ + else if (s3->bpp == 2) dat = svga->vram[dword_remap(svga, addr) & s3->vram_mask]; \ + else dat = vram_l[dword_remap_l(svga, addr) & (s3->vram_mask >> 2)]; #define MIX_READ { \ switch ((mix_dat & mix_mask) ? (s3->accel.frgd_mix & 0xf) : (s3->accel.bkgd_mix & 0xf)) \ @@ -4523,23 +4553,23 @@ polygon_setup(s3_t *s3) #define WRITE(addr, dat) if (s3->bpp == 0) \ { \ - svga->vram[(addr) & s3->vram_mask] = dat; \ - svga->changedvram[((addr) & s3->vram_mask) >> 12] = changeframecount; \ + svga->vram[dword_remap(svga, addr) & s3->vram_mask] = dat; \ + svga->changedvram[(dword_remap(svga, addr) & s3->vram_mask) >> 12] = changeframecount; \ } \ else if (s3->bpp == 1) \ { \ - vram_w[(addr) & (s3->vram_mask >> 1)] = dat; \ - svga->changedvram[((addr) & (s3->vram_mask >> 1)) >> 11] = changeframecount; \ + vram_w[dword_remap_w(svga, addr) & (s3->vram_mask >> 1)] = dat; \ + svga->changedvram[(dword_remap_w(svga, addr) & (s3->vram_mask >> 1)) >> 11] = changeframecount; \ } \ else if (s3->bpp == 2) \ { \ - svga->vram[(addr) & s3->vram_mask] = dat; \ - svga->changedvram[((addr) & s3->vram_mask) >> 12] = changeframecount; \ + svga->vram[dword_remap(svga, addr) & s3->vram_mask] = dat; \ + svga->changedvram[(dword_remap(svga, addr) & s3->vram_mask) >> 12] = changeframecount; \ } \ else \ { \ - vram_l[(addr) & (s3->vram_mask >> 2)] = dat; \ - svga->changedvram[((addr) & (s3->vram_mask >> 2)) >> 10] = changeframecount; \ + vram_l[dword_remap_l(svga, addr) & (s3->vram_mask >> 2)] = dat; \ + svga->changedvram[(dword_remap_l(svga, addr) & (s3->vram_mask >> 2)) >> 10] = changeframecount; \ } @@ -6983,13 +7013,14 @@ static void *s3_init(const device_t *info) return NULL; } + if (s3->chip >= S3_TRIO64V) + svga->packed_chain4 = 1; + if (s3->pci) s3->card = pci_add_card(PCI_ADD_VIDEO, s3_pci_read, s3_pci_write, s3); s3->i2c = i2c_gpio_init("ddc_s3"); s3->ddc = ddc_init(i2c_gpio_get_bus(s3->i2c)); - - svga->packed_chain4 = 1; return s3; } diff --git a/src/win/win.c b/src/win/win.c index 615d9a022..6f0a43ca3 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -1048,10 +1048,10 @@ plat_setfullscreen(int on) int dpi = win_get_dpi(hwndMain); /* Are we changing from the same state to the same state? */ - if ((!!on) == (!!video_fullscreen)) + if ((!!(on & 1)) == (!!video_fullscreen)) return; - if (on && video_fullscreen_first) { + if (on && (start_in_fullscreen || video_fullscreen_first)) { video_fullscreen |= 2; if (ui_msgbox_header(MBX_INFO | MBX_DONTASK, (wchar_t *) IDS_2134, (wchar_t *) IDS_2052) == 10) { video_fullscreen_first = 0; @@ -1061,13 +1061,14 @@ plat_setfullscreen(int on) } /* OK, claim the video. */ - win_mouse_close(); + if (!(on & 2)) + win_mouse_close(); /* Close the current mode, and open the new one. */ - video_fullscreen = on | 2; + video_fullscreen = (on & 1) | 2; if (vid_apis[vid_api].set_fs) - vid_apis[vid_api].set_fs(on); - if (!on) { + vid_apis[vid_api].set_fs(on & 1); + if (!(on & 1)) { plat_resize(scrnsz_x, scrnsz_y); if (vid_resize) { /* scale the screen base on DPI */ @@ -1115,26 +1116,31 @@ plat_setfullscreen(int on) } video_fullscreen &= 1; video_force_resize_set(1); - if (!on) + if (!(on & 1)) doresize = 1; win_mouse_init(); - /* Release video and make it redraw the screen. */ - device_force_redraw(); + if (!(on & 2)) { + /* Release video and make it redraw the screen. */ + device_force_redraw(); - /* Send a CTRL break code so CTRL does not get stuck. */ - keyboard_input(0, 0x01D); + /* Send a CTRL break code so CTRL does not get stuck. */ + keyboard_input(0, 0x01D); + } /* Finally, handle the host's mouse cursor. */ /* win_log("%s full screen, %s cursor\n", on ? "enter" : "leave", on ? "hide" : "show"); */ show_cursor(video_fullscreen ? 0 : -1); - /* This is needed for OpenGL. */ - plat_vidapi_enable(0); - plat_vidapi_enable(1); + if (!(on & 2)) { + /* This is needed for OpenGL. */ + plat_vidapi_enable(0); + plat_vidapi_enable(1); + } } + void plat_vid_reload_options(void) { diff --git a/src/win/win_sdl.c b/src/win/win_sdl.c index 303fb5f69..ffd589ce0 100644 --- a/src/win/win_sdl.c +++ b/src/win/win_sdl.c @@ -234,7 +234,7 @@ sdl_blit(int x, int y, int w, int h) SDL_Rect r_src; int ret; - if (!sdl_enabled || (h <= 0) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL)) { + if (!sdl_enabled || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL)) { video_blit_complete(); return; } @@ -277,6 +277,11 @@ sdl_destroy_window(void) static void sdl_destroy_texture(void) { + if (sdl_tex != NULL) { + SDL_DestroyTexture(sdl_tex); + sdl_tex = NULL; + } + /* SDL_DestroyRenderer also automatically destroys all associated textures. */ if (sdl_render != NULL) { SDL_DestroyRenderer(sdl_render); @@ -339,13 +344,8 @@ sdl_select_best_hw_driver(void) static void -sdl_reinit_texture(void) +sdl_init_texture(void) { - if (sdl_flags == -1) - return; - - sdl_destroy_texture(); - if (sdl_flags & RENDERER_HARDWARE) { sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_ACCELERATED); SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_filter_method ? "1" : "0"); @@ -357,6 +357,17 @@ sdl_reinit_texture(void) } +static void +sdl_reinit_texture(void) +{ + if (sdl_flags == -1) + return; + + sdl_destroy_texture(); + sdl_init_texture(); +} + + void sdl_set_fs(int fs) { @@ -365,7 +376,6 @@ sdl_set_fs(int fs) SDL_LockMutex(sdl_mutex); sdl_enabled = 0; - sdl_destroy_texture(); if (fs) { ShowWindow(sdl_parent_hwnd, TRUE); @@ -408,7 +418,7 @@ sdl_set_fs(int fs) else sdl_flags &= ~RENDERER_FULL_SCREEN; - sdl_reinit_texture(); + // sdl_reinit_texture(); sdl_enabled = 1; SDL_UnlockMutex(sdl_mutex); } @@ -456,6 +466,7 @@ sdl_init_common(int flags) } sdl_win = SDL_CreateWindowFrom((void *)hwndRender); + sdl_init_texture(); sdl_set_fs(video_fullscreen & 1); /* Make sure we get a clean exit. */ @@ -554,16 +565,16 @@ sdl_enable(int enable) SDL_UnlockMutex(sdl_mutex); } + void sdl_reload(void) { - if (sdl_flags & RENDERER_HARDWARE) - { - SDL_LockMutex(sdl_mutex); + if (sdl_flags & RENDERER_HARDWARE) { + SDL_LockMutex(sdl_mutex); - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_filter_method ? "1" : "0"); - sdl_reinit_texture(); + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_filter_method ? "1" : "0"); + sdl_reinit_texture(); - SDL_UnlockMutex(sdl_mutex); - } -} \ No newline at end of file + SDL_UnlockMutex(sdl_mutex); + } +} diff --git a/src/win/win_ui.c b/src/win/win_ui.c index 79cc3a121..a778d60e7 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -1427,7 +1427,8 @@ ui_init(int nCmdShow) } /* Initialize the mouse module. */ - win_mouse_init(); + if (!start_in_fullscreen && !video_fullscreen_first) + win_mouse_init(); /* * Before we can create the Render window, we first have @@ -1457,16 +1458,16 @@ ui_init(int nCmdShow) else plat_resize(scrnsz_x, scrnsz_y); + /* Initialize the rendering window, or fullscreen. */ + if (start_in_fullscreen || video_fullscreen_first) + plat_setfullscreen(3); + /* Fire up the machine. */ pc_reset_hard_init(); /* Set the PAUSE mode depending on the renderer. */ plat_pause(0); - /* Initialize the rendering window, or fullscreen. */ - if (start_in_fullscreen) - plat_setfullscreen(1); - /* If so requested via the command line, inform the * application that started us of our HWND, using the * the hWnd and unique ID the application has given