PCem

changeset 45:f85939140905

Added fullscreen mode. Some code tidying.
author TomW
date Sat Dec 07 13:43:06 2013 +0000
parents 64fa8cf6ba95
children f9ec91752d3e
files src/Makefile.mingw src/ibm.h src/pc.c src/pc.rc src/plat-mouse.h src/resources.h src/video.c src/video.h src/win-d3d-fs.cc src/win-d3d-fs.h src/win-ddraw-fs.cc src/win-ddraw-fs.h src/win-ddraw.cc src/win-ddraw.h src/win-keyboard.cc src/win-mouse.cc src/win.c src/win.h
diffstat 18 files changed, 1060 insertions(+), 116 deletions(-) [+]
line diff
     1.1 --- a/src/Makefile.mingw	Mon Dec 02 21:00:26 2013 +0000
     1.2 +++ b/src/Makefile.mingw	Sat Dec 07 13:43:06 2013 +0000
     1.3 @@ -18,7 +18,7 @@
     1.4  	vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o vid_s3.o \
     1.5  	vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o vid_svga_render.o \
     1.6  	vid_tandy.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o \
     1.7 -	vid_voodoo.o video.o wd76c10.o win.o win-d3d.o win-ddraw.o win-keyboard.o win-midi.o \
     1.8 +	vid_voodoo.o video.o wd76c10.o win.o win-d3d.o win-d3d-fs.o win-ddraw.o win-ddraw-fs.o win-keyboard.o win-midi.o \
     1.9  	win-mouse.o win-timer.o win-video.o x86seg.o x87.o xtide.o pc.res
    1.10  FMOBJ = fmopl.o ymf262.o
    1.11  
     2.1 --- a/src/ibm.h	Mon Dec 02 21:00:26 2013 +0000
     2.2 +++ b/src/ibm.h	Sat Dec 07 13:43:06 2013 +0000
     2.3 @@ -443,7 +443,6 @@
     2.4  
     2.5  /*Keyboard*/
     2.6  int keybsenddelay;
     2.7 -extern int kb_win;
     2.8  
     2.9  
    2.10  /*CD-ROM*/
     3.1 --- a/src/pc.c	Mon Dec 02 21:00:26 2013 +0000
     3.2 +++ b/src/pc.c	Sat Dec 07 13:43:06 2013 +0000
     3.3 @@ -34,7 +34,6 @@
     3.4  
     3.5  int cdrom_enabled;
     3.6  int CPUID;
     3.7 -int kb_win;
     3.8  int vid_resize, vid_api;
     3.9  
    3.10  int cycles_lost = 0;
    3.11 @@ -461,9 +460,10 @@
    3.12          cache = get_config_int(NULL, "cache", 3);
    3.13          cga_comp = get_config_int(NULL, "cga_composite", 0);
    3.14          
    3.15 -        kb_win = get_config_int(NULL, "kb_win", 0);
    3.16          vid_resize = get_config_int(NULL, "vid_resize", 0);
    3.17          vid_api = get_config_int(NULL, "vid_api", 0);
    3.18 +        video_fullscreen_scale = get_config_int(NULL, "video_fullscreen_scale", 0);
    3.19 +        video_fullscreen_first = get_config_int(NULL, "video_fullscreen_first", 1);
    3.20  
    3.21          hdc[0].spt = get_config_int(NULL, "hdc_sectors", 0);
    3.22          hdc[0].hpc = get_config_int(NULL, "hdc_heads", 0);
    3.23 @@ -502,9 +502,10 @@
    3.24          set_config_int(NULL, "mem_size", mem_size);
    3.25          set_config_int(NULL, "cdrom_drive", cdrom_drive);
    3.26          set_config_int(NULL, "cdrom_enabled", cdrom_enabled);
    3.27 -        set_config_int(NULL, "kb_win", kb_win);
    3.28          set_config_int(NULL, "vid_resize", vid_resize);
    3.29          set_config_int(NULL, "vid_api", vid_api);
    3.30 +        set_config_int(NULL, "video_fullscreen_scale", video_fullscreen_scale);
    3.31 +        set_config_int(NULL, "video_fullscreen_first", video_fullscreen_first);
    3.32          
    3.33          set_config_int(NULL, "hdc_sectors", hdc[0].spt);
    3.34          set_config_int(NULL, "hdc_heads", hdc[0].hpc);
     4.1 --- a/src/pc.rc	Mon Dec 02 21:00:26 2013 +0000
     4.2 +++ b/src/pc.rc	Sat Dec 07 13:43:06 2013 +0000
     4.3 @@ -30,6 +30,15 @@
     4.4                          MENUITEM SEPARATOR
     4.5                          MENUITEM "&DirectDraw", IDM_VID_DDRAW
     4.6                          MENUITEM "Direct&3D",   IDM_VID_D3D
     4.7 +                        MENUITEM SEPARATOR
     4.8 +                        MENUITEM "&Fullscreen", IDM_VID_FULLSCREEN
     4.9 +                        POPUP "Fullscreen &stretch mode"
    4.10 +                        BEGIN
    4.11 +                                MENUITEM "&Full screen stretch", IDM_VID_FS_FULL
    4.12 +                                MENUITEM "&4:3", IDM_VID_FS_43
    4.13 +                                MENUITEM "&Square pixels", IDM_VID_FS_SQ
    4.14 +                                MENUITEM "&Integer scale", IDM_VID_FS_INT
    4.15 +                        END
    4.16                  END
    4.17          END
    4.18          POPUP "&Misc"
     5.1 --- a/src/plat-mouse.h	Mon Dec 02 21:00:26 2013 +0000
     5.2 +++ b/src/plat-mouse.h	Sat Dec 07 13:43:06 2013 +0000
     5.3 @@ -2,7 +2,7 @@
     5.4  extern "C" {
     5.5  #endif
     5.6          void mouse_init();
     5.7 -        void mouse_remove();
     5.8 +        void mouse_close();
     5.9          extern int mouse_b;
    5.10          void poll_mouse();
    5.11          void position_mouse(int x, int y);
     6.1 --- a/src/resources.h	Mon Dec 02 21:00:26 2013 +0000
     6.2 +++ b/src/resources.h	Sat Dec 07 13:43:06 2013 +0000
     6.3 @@ -1,20 +1,23 @@
     6.4 -#define IDM_FILE_RESET  40000
     6.5 -#define IDM_FILE_HRESET 40001
     6.6 -#define IDM_FILE_EXIT   40002
     6.7 -#define IDM_DISC_A      40010
     6.8 -#define IDM_DISC_B      40011
     6.9 -#define IDM_EJECT_A     40012
    6.10 -#define IDM_EJECT_B     40013
    6.11 -#define IDM_HDCONF      40014
    6.12 -#define IDM_CONFIG      40020
    6.13 -#define IDM_STATUS      40030
    6.14 -#define IDM_KEY_ALLEGRO 40040
    6.15 -#define IDM_KEY_WINDOWS 40041
    6.16 -#define IDM_VID_RESIZE  40050
    6.17 -#define IDM_VID_DDRAW   40060
    6.18 -#define IDM_VID_D3D     40061
    6.19 -#define IDM_CDROM_EMPTY 40100
    6.20 -#define IDM_CDROM_REAL  40100
    6.21 +#define IDM_FILE_RESET     40000
    6.22 +#define IDM_FILE_HRESET    40001
    6.23 +#define IDM_FILE_EXIT      40002
    6.24 +#define IDM_DISC_A         40010
    6.25 +#define IDM_DISC_B         40011
    6.26 +#define IDM_EJECT_A        40012
    6.27 +#define IDM_EJECT_B        40013
    6.28 +#define IDM_HDCONF         40014
    6.29 +#define IDM_CONFIG         40020
    6.30 +#define IDM_STATUS         40030
    6.31 +#define IDM_VID_RESIZE     40050
    6.32 +#define IDM_VID_DDRAW      40060
    6.33 +#define IDM_VID_D3D        40061
    6.34 +#define IDM_VID_FULLSCREEN 40070
    6.35 +#define IDM_VID_FS_FULL    40071
    6.36 +#define IDM_VID_FS_43      40072
    6.37 +#define IDM_VID_FS_SQ      40073
    6.38 +#define IDM_VID_FS_INT     40074
    6.39 +#define IDM_CDROM_EMPTY    40100
    6.40 +#define IDM_CDROM_REAL     40100
    6.41  #define IDM_CDROM_DISABLED 40200
    6.42  
    6.43  #define IDC_COMBO1 1000
    6.44 @@ -61,3 +64,4 @@
    6.45  #define IDC_STEXT_DEVICE 1108
    6.46  
    6.47  #define WM_RESETD3D WM_USER
    6.48 +#define WM_LEAVEFULLSCREEN WM_USER + 1
     7.1 --- a/src/video.c	Mon Dec 02 21:00:26 2013 +0000
     7.2 +++ b/src/video.c	Sat Dec 07 13:43:06 2013 +0000
     7.3 @@ -108,6 +108,7 @@
     7.4          return video_cards[card].legacy_id;
     7.5  }
     7.6  
     7.7 +int video_fullscreen = 0, video_fullscreen_scale, video_fullscreen_first;
     7.8  uint32_t *video_15to32, *video_16to32;
     7.9  
    7.10  int egareads=0,egawrites=0;
     8.1 --- a/src/video.h	Mon Dec 02 21:00:26 2013 +0000
     8.2 +++ b/src/video.h	Sat Dec 07 13:43:06 2013 +0000
     8.3 @@ -4,6 +4,16 @@
     8.4  int video_old_to_new(int card);
     8.5  int video_new_to_old(int card);
     8.6  
     8.7 +extern int video_fullscreen, video_fullscreen_scale, video_fullscreen_first;
     8.8 +
     8.9 +enum
    8.10 +{
    8.11 +        FULLSCR_SCALE_FULL = 0,
    8.12 +        FULLSCR_SCALE_43,
    8.13 +        FULLSCR_SCALE_SQ,
    8.14 +        FULLSCR_SCALE_INT
    8.15 +};
    8.16 +
    8.17  extern int egareads,egawrites;
    8.18  
    8.19  extern int fullchange;
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/src/win-d3d-fs.cc	Sat Dec 07 13:43:06 2013 +0000
     9.3 @@ -0,0 +1,484 @@
     9.4 +#include <stdint.h>
     9.5 +#define BITMAP WINDOWS_BITMAP
     9.6 +#include <d3d9.h>
     9.7 +#undef BITMAP
     9.8 +#include "resources.h"
     9.9 +#include "video.h"
    9.10 +#include "win-d3d-fs.h"
    9.11 +#include "win.h"
    9.12 +
    9.13 +extern "C" void fatal(const char *format, ...);
    9.14 +extern "C" void pclog(const char *format, ...);
    9.15 +
    9.16 +extern "C" void device_force_redraw();
    9.17 +
    9.18 +static void d3d_fs_init_objects();
    9.19 +static void d3d_fs_close_objects();
    9.20 +static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h);
    9.21 +static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h);
    9.22 +
    9.23 +static LPDIRECT3D9             d3d        = NULL;
    9.24 +static LPDIRECT3DDEVICE9       d3ddev     = NULL; 
    9.25 +static LPDIRECT3DVERTEXBUFFER9 v_buffer   = NULL;
    9.26 +static LPDIRECT3DTEXTURE9      d3dTexture = NULL;
    9.27 +static D3DPRESENT_PARAMETERS d3dpp;
    9.28 +
    9.29 +static HWND d3d_hwnd;
    9.30 +static HWND d3d_device_window;
    9.31 +
    9.32 +static int d3d_fs_w, d3d_fs_h;
    9.33 +
    9.34 +struct CUSTOMVERTEX
    9.35 +{
    9.36 +     FLOAT x, y, z, rhw;    // from the D3DFVF_XYZRHW flag
    9.37 +     FLOAT tu, tv;
    9.38 +};
    9.39 +
    9.40 +static PALETTE cgapal=
    9.41 +{
    9.42 +        {0,0,0},{0,42,0},{42,0,0},{42,21,0},
    9.43 +        {0,0,0},{0,42,42},{42,0,42},{42,42,42},
    9.44 +        {0,0,0},{21,63,21},{63,21,21},{63,63,21},
    9.45 +        {0,0,0},{21,63,63},{63,21,63},{63,63,63},
    9.46 +
    9.47 +        {0,0,0},{0,0,42},{0,42,0},{0,42,42},
    9.48 +        {42,0,0},{42,0,42},{42,21,00},{42,42,42},
    9.49 +        {21,21,21},{21,21,63},{21,63,21},{21,63,63},
    9.50 +        {63,21,21},{63,21,63},{63,63,21},{63,63,63},
    9.51 +
    9.52 +        {0,0,0},{0,21,0},{0,0,42},{0,42,42},
    9.53 +        {42,0,21},{21,10,21},{42,0,42},{42,0,63},
    9.54 +        {21,21,21},{21,63,21},{42,21,42},{21,63,63},
    9.55 +        {63,0,0},{42,42,0},{63,21,42},{41,41,41},
    9.56 +        
    9.57 +        {0,0,0},{0,42,42},{42,0,0},{42,42,42},
    9.58 +        {0,0,0},{0,42,42},{42,0,0},{42,42,42},
    9.59 +        {0,0,0},{0,63,63},{63,0,0},{63,63,63},
    9.60 +        {0,0,0},{0,63,63},{63,0,0},{63,63,63},
    9.61 +};
    9.62 +
    9.63 +static uint32_t pal_lookup[256];
    9.64 +
    9.65 +static CUSTOMVERTEX d3d_verts[] =
    9.66 +{
    9.67 +     {   0.0f,    0.0f, 1.0f, 1.0f, 0.0f, 0.0f},
    9.68 +     {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f},
    9.69 +     {   0.0f, 2048.0f, 1.0f, 1.0f, 0.0f, 1.0f},
    9.70 +
    9.71 +     {   0.0f,    0.0f, 1.0f, 1.0f, 0.0f, 0.0f},
    9.72 +     {2048.0f,    0.0f, 1.0f, 1.0f, 1.0f, 0.0f},
    9.73 +     {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f},
    9.74 +};
    9.75 +  
    9.76 +void d3d_fs_init(HWND h)
    9.77 +{
    9.78 +        int c;
    9.79 +        HRESULT hr;
    9.80 +
    9.81 +        d3d_fs_w = GetSystemMetrics(SM_CXSCREEN);
    9.82 +        d3d_fs_h = GetSystemMetrics(SM_CYSCREEN);
    9.83 +        
    9.84 +        for (c = 0; c < 256; c++)
    9.85 +            pal_lookup[c] = makecol(cgapal[c].r << 2, cgapal[c].g << 2, cgapal[c].b << 2);
    9.86 +
    9.87 +        d3d_hwnd = h;
    9.88 +
    9.89 +        d3d_device_window = CreateWindowEx (
    9.90 +                0,
    9.91 +                szSubClassName,
    9.92 +                "PCem v0.7",
    9.93 +                WS_POPUP,
    9.94 +                CW_USEDEFAULT,
    9.95 +                CW_USEDEFAULT,
    9.96 +                640,
    9.97 +                480,
    9.98 +                HWND_DESKTOP,
    9.99 +                NULL,
   9.100 +                NULL,
   9.101 +                NULL 
   9.102 +        );
   9.103 +        
   9.104 +        d3d = Direct3DCreate9(D3D_SDK_VERSION);
   9.105 +
   9.106 +        memset(&d3dpp, 0, sizeof(d3dpp));      
   9.107 +
   9.108 +        d3dpp.Flags                  = 0;
   9.109 +        d3dpp.SwapEffect             = D3DSWAPEFFECT_DISCARD;
   9.110 +        d3dpp.hDeviceWindow          = d3d_device_window;
   9.111 +        d3dpp.BackBufferCount        = 1;
   9.112 +        d3dpp.MultiSampleType        = D3DMULTISAMPLE_NONE;
   9.113 +        d3dpp.MultiSampleQuality     = 0;
   9.114 +        d3dpp.EnableAutoDepthStencil = false;
   9.115 +        d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
   9.116 +        d3dpp.PresentationInterval   = D3DPRESENT_INTERVAL_IMMEDIATE;
   9.117 +        d3dpp.Windowed               = false;
   9.118 +        d3dpp.BackBufferFormat       = D3DFMT_X8R8G8B8;
   9.119 +        d3dpp.BackBufferWidth        = d3d_fs_w;
   9.120 +        d3dpp.BackBufferHeight       = d3d_fs_h;
   9.121 +
   9.122 +        hr = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);
   9.123 +        
   9.124 +        d3d_fs_init_objects();
   9.125 +        
   9.126 +        video_blit_memtoscreen   = d3d_fs_blit_memtoscreen;
   9.127 +        video_blit_memtoscreen_8 = d3d_fs_blit_memtoscreen_8;
   9.128 +}
   9.129 +
   9.130 +static void d3d_fs_close_objects()
   9.131 +{
   9.132 +        if (d3dTexture)
   9.133 +        {
   9.134 +                d3dTexture->Release();
   9.135 +                d3dTexture = NULL;
   9.136 +        }
   9.137 +        if (v_buffer)
   9.138 +        {
   9.139 +                v_buffer->Release();
   9.140 +                v_buffer = NULL;
   9.141 +        }
   9.142 +}
   9.143 +
   9.144 +static void d3d_fs_init_objects()
   9.145 +{
   9.146 +        HRESULT hr;
   9.147 +        D3DLOCKED_RECT dr;
   9.148 +        int y;
   9.149 +        RECT r;
   9.150 +
   9.151 +        hr = d3ddev->CreateVertexBuffer(6*sizeof(CUSTOMVERTEX),
   9.152 +                                   0,
   9.153 +                                   D3DFVF_XYZRHW | D3DFVF_TEX1,
   9.154 +                                   D3DPOOL_MANAGED,
   9.155 +                                   &v_buffer,
   9.156 +                                   NULL);
   9.157 +
   9.158 +        d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL);
   9.159 +     
   9.160 +        r.top    = r.left  = 0;
   9.161 +        r.bottom = r.right = 2047;
   9.162 +
   9.163 +        if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0)))
   9.164 +           fatal("LockRect failed\n");
   9.165 +        
   9.166 +        for (y = 0; y < 2048; y++)
   9.167 +        {
   9.168 +                uint32_t *p = (uint32_t *)(dr.pBits + (y * dr.Pitch));
   9.169 +                memset(p, 0, 2048 * 4);
   9.170 +        }
   9.171 +
   9.172 +        d3dTexture->UnlockRect(0);
   9.173 +
   9.174 +        d3ddev->SetTextureStageState(0,D3DTSS_COLOROP,   D3DTOP_SELECTARG1);
   9.175 +        d3ddev->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE);
   9.176 +        d3ddev->SetTextureStageState(0,D3DTSS_ALPHAOP,   D3DTOP_DISABLE);
   9.177 +
   9.178 +        d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
   9.179 +        d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
   9.180 +}
   9.181 +
   9.182 +/*void d3d_resize(int x, int y)
   9.183 +{
   9.184 +        HRESULT hr;
   9.185 +
   9.186 +        d3dpp.BackBufferWidth  = x;
   9.187 +        d3dpp.BackBufferHeight = y;
   9.188 +
   9.189 +        d3d_reset();
   9.190 +}*/
   9.191 +        
   9.192 +void d3d_fs_reset()
   9.193 +{
   9.194 +        HRESULT hr;
   9.195 +
   9.196 +        memset(&d3dpp, 0, sizeof(d3dpp));      
   9.197 +
   9.198 +        d3dpp.Flags                  = 0;
   9.199 +        d3dpp.SwapEffect             = D3DSWAPEFFECT_DISCARD;
   9.200 +        d3dpp.hDeviceWindow          = d3d_device_window;
   9.201 +        d3dpp.BackBufferCount        = 1;
   9.202 +        d3dpp.MultiSampleType        = D3DMULTISAMPLE_NONE;
   9.203 +        d3dpp.MultiSampleQuality     = 0;
   9.204 +        d3dpp.EnableAutoDepthStencil = false;
   9.205 +        d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
   9.206 +        d3dpp.PresentationInterval   = D3DPRESENT_INTERVAL_IMMEDIATE;
   9.207 +        d3dpp.Windowed               = false;
   9.208 +        d3dpp.BackBufferFormat       = D3DFMT_X8R8G8B8;
   9.209 +        d3dpp.BackBufferWidth        = d3d_fs_w;
   9.210 +        d3dpp.BackBufferHeight       = d3d_fs_h;
   9.211 +
   9.212 +        hr = d3ddev->Reset(&d3dpp);
   9.213 +
   9.214 +        if (hr == D3DERR_DEVICELOST)
   9.215 +                return;
   9.216 +
   9.217 +        d3ddev->SetTextureStageState(0,D3DTSS_COLOROP,   D3DTOP_SELECTARG1);
   9.218 +        d3ddev->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE);
   9.219 +        d3ddev->SetTextureStageState(0,D3DTSS_ALPHAOP,   D3DTOP_DISABLE);
   9.220 +
   9.221 +        d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
   9.222 +        d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
   9.223 +
   9.224 +        device_force_redraw();
   9.225 +}
   9.226 +
   9.227 +void d3d_fs_close()
   9.228 +{       
   9.229 +        if (d3dTexture)
   9.230 +        {
   9.231 +                d3dTexture->Release();
   9.232 +                d3dTexture = NULL;
   9.233 +        }
   9.234 +        if (v_buffer)
   9.235 +        {
   9.236 +                v_buffer->Release();
   9.237 +                v_buffer = NULL;
   9.238 +        }
   9.239 +        if (d3ddev)
   9.240 +        {
   9.241 +                d3ddev->Release();
   9.242 +                d3ddev = NULL;
   9.243 +        }
   9.244 +        if (d3d)
   9.245 +        {
   9.246 +                d3d->Release();
   9.247 +                d3d = NULL;
   9.248 +        }
   9.249 +        DestroyWindow(d3d_device_window);
   9.250 +}
   9.251 +
   9.252 +static void d3d_fs_size(RECT window_rect, double *l, double *t, double *r, double *b, int w, int h)
   9.253 +{
   9.254 +        int ratio_w, ratio_h;
   9.255 +        switch (video_fullscreen_scale)
   9.256 +        {
   9.257 +                case FULLSCR_SCALE_FULL:
   9.258 +                *l = -0.5;
   9.259 +                *t = -0.5;
   9.260 +                *r = (window_rect.right  - window_rect.left) - 0.5;
   9.261 +                *b = (window_rect.bottom - window_rect.top) - 0.5;
   9.262 +                break;
   9.263 +                case FULLSCR_SCALE_43:
   9.264 +                *t = -0.5;
   9.265 +                *b = (window_rect.bottom - window_rect.top) - 0.5;
   9.266 +                *l = ((window_rect.right  - window_rect.left) / 2) - (((window_rect.bottom - window_rect.top) * 4) / (3 * 2)) - 0.5;
   9.267 +                *r = ((window_rect.right  - window_rect.left) / 2) + (((window_rect.bottom - window_rect.top) * 4) / (3 * 2)) - 0.5;
   9.268 +                if (*l < -0.5)
   9.269 +                {
   9.270 +                        *l = -0.5;
   9.271 +                        *r = (window_rect.right  - window_rect.left) - 0.5;
   9.272 +                        *t = ((window_rect.bottom - window_rect.top) / 2) - (((window_rect.right - window_rect.left) * 3) / (4 * 2)) - 0.5;
   9.273 +                        *b = ((window_rect.bottom - window_rect.top) / 2) + (((window_rect.right - window_rect.left) * 3) / (4 * 2)) - 0.5;
   9.274 +                }
   9.275 +                break;
   9.276 +                case FULLSCR_SCALE_SQ:
   9.277 +                *t = -0.5;
   9.278 +                *b = (window_rect.bottom - window_rect.top) - 0.5;
   9.279 +                *l = ((window_rect.right  - window_rect.left) / 2) - (((window_rect.bottom - window_rect.top) * w) / (h * 2)) - 0.5;
   9.280 +                *r = ((window_rect.right  - window_rect.left) / 2) + (((window_rect.bottom - window_rect.top) * w) / (h * 2)) - 0.5;
   9.281 +                if (*l < -0.5)
   9.282 +                {
   9.283 +                        *l = -0.5;
   9.284 +                        *r = (window_rect.right  - window_rect.left) - 0.5;
   9.285 +                        *t = ((window_rect.bottom - window_rect.top) / 2) - (((window_rect.right - window_rect.left) * h) / (w * 2)) - 0.5;
   9.286 +                        *b = ((window_rect.bottom - window_rect.top) / 2) + (((window_rect.right - window_rect.left) * h) / (w * 2)) - 0.5;
   9.287 +                }
   9.288 +                break;
   9.289 +                case FULLSCR_SCALE_INT:
   9.290 +                ratio_w = (window_rect.right  - window_rect.left) / w;
   9.291 +                ratio_h = (window_rect.bottom - window_rect.top)  / h;
   9.292 +                if (ratio_h < ratio_w)
   9.293 +                        ratio_w = ratio_h;
   9.294 +                *l = ((window_rect.right  - window_rect.left) / 2) - ((w * ratio_w) / 2) - 0.5;
   9.295 +                *r = ((window_rect.right  - window_rect.left) / 2) + ((w * ratio_w) / 2) - 0.5;
   9.296 +                *t = ((window_rect.bottom - window_rect.top)  / 2) - ((h * ratio_w) / 2) - 0.5;
   9.297 +                *b = ((window_rect.bottom - window_rect.top)  / 2) + ((h * ratio_w) / 2) - 0.5;
   9.298 +                break;
   9.299 +        }
   9.300 +}
   9.301 +
   9.302 +static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h)
   9.303 +{
   9.304 +        HRESULT hr = D3D_OK;
   9.305 +        VOID* pVoid;
   9.306 +        D3DLOCKED_RECT dr;
   9.307 +        RECT window_rect;
   9.308 +        uint32_t *p, *src;
   9.309 +        int yy;
   9.310 +        double l, t, r, b;
   9.311 +
   9.312 +        d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;
   9.313 +        d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;
   9.314 +        d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0;
   9.315 +        d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0;
   9.316 +
   9.317 +        GetClientRect(d3d_device_window, &window_rect);
   9.318 +        d3d_fs_size(window_rect, &l, &t, &r, &b, w, h);
   9.319 +        
   9.320 +        d3d_verts[0].x = l;
   9.321 +        d3d_verts[0].y = t;
   9.322 +        d3d_verts[1].x = r;
   9.323 +        d3d_verts[1].y = b;
   9.324 +        d3d_verts[2].x = l;
   9.325 +        d3d_verts[2].y = b;
   9.326 +        d3d_verts[3].x = l;
   9.327 +        d3d_verts[3].y = t;
   9.328 +        d3d_verts[4].x = r;
   9.329 +        d3d_verts[4].y = t;
   9.330 +        d3d_verts[5].x = r;
   9.331 +        d3d_verts[5].y = b;
   9.332 +
   9.333 +        if (hr == D3D_OK)
   9.334 +                hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0);
   9.335 +        if (hr == D3D_OK)
   9.336 +                memcpy(pVoid, d3d_verts, sizeof(d3d_verts));
   9.337 +        if (hr == D3D_OK)
   9.338 +                hr = v_buffer->Unlock();
   9.339 +
   9.340 +        if (hr == D3D_OK && !(y1 == 0 && y2 == 0))
   9.341 +        {
   9.342 +                RECT lock_rect;
   9.343 +                
   9.344 +                lock_rect.top    = y1;
   9.345 +                lock_rect.left   = 0;
   9.346 +                lock_rect.bottom = y2;
   9.347 +                lock_rect.right  = 2047;
   9.348 +
   9.349 +                if (FAILED(d3dTexture->LockRect(0, &dr, &lock_rect, 0)))
   9.350 +                   fatal("LockRect failed\n");
   9.351 +        
   9.352 +                for (yy = y1; yy < y2; yy++)
   9.353 +                        memcpy(dr.pBits + ((yy - y1) * dr.Pitch), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4);
   9.354 +
   9.355 +                d3dTexture->UnlockRect(0);
   9.356 +        }
   9.357 +
   9.358 +        if (hr == D3D_OK)        
   9.359 +                hr = d3ddev->BeginScene();
   9.360 +
   9.361 +        if (hr == D3D_OK)
   9.362 +        {
   9.363 +                if (hr == D3D_OK)
   9.364 +                        d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0, 0);
   9.365 +
   9.366 +                if (hr == D3D_OK)
   9.367 +                        hr = d3ddev->SetTexture(0, d3dTexture);
   9.368 +
   9.369 +                if (hr == D3D_OK)
   9.370 +                        hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
   9.371 +
   9.372 +                if (hr == D3D_OK)
   9.373 +                        hr = d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));
   9.374 +
   9.375 +                if (hr == D3D_OK)
   9.376 +                        hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
   9.377 +
   9.378 +                if (hr == D3D_OK)
   9.379 +                        hr = d3ddev->SetTexture(0, NULL);
   9.380 +
   9.381 +                if (hr == D3D_OK)
   9.382 +                        hr = d3ddev->EndScene();
   9.383 +        }
   9.384 +
   9.385 +        if (hr == D3D_OK)
   9.386 +                hr = d3ddev->Present(NULL, NULL, d3d_device_window, NULL);
   9.387 +        
   9.388 +        if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL)
   9.389 +                PostMessage(ghwnd, WM_RESETD3D, 0, 0);
   9.390 +}
   9.391 +
   9.392 +static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h)
   9.393 +{
   9.394 +        HRESULT hr = D3D_OK;
   9.395 +        VOID* pVoid;
   9.396 +        D3DLOCKED_RECT dr;
   9.397 +        RECT window_rect;
   9.398 +        uint32_t *p, *src;
   9.399 +        int xx, yy;
   9.400 +        double l, t, r, b;
   9.401 +
   9.402 +        d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;
   9.403 +        d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;
   9.404 +        d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0;
   9.405 +        d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0;
   9.406 +
   9.407 +        GetClientRect(d3d_device_window, &window_rect);
   9.408 +        d3d_fs_size(window_rect, &l, &t, &r, &b, w, h);
   9.409 +        
   9.410 +        d3d_verts[0].x = l;
   9.411 +        d3d_verts[0].y = t;
   9.412 +        d3d_verts[1].x = r;
   9.413 +        d3d_verts[1].y = b;
   9.414 +        d3d_verts[2].x = l;
   9.415 +        d3d_verts[2].y = b;
   9.416 +        d3d_verts[3].x = l;
   9.417 +        d3d_verts[3].y = t;
   9.418 +        d3d_verts[4].x = r;
   9.419 +        d3d_verts[4].y = t;
   9.420 +        d3d_verts[5].x = r;
   9.421 +        d3d_verts[5].y = b;
   9.422 +
   9.423 +        if (hr == D3D_OK)
   9.424 +                hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0);
   9.425 +        if (hr == D3D_OK)
   9.426 +                memcpy(pVoid, d3d_verts, sizeof(d3d_verts));
   9.427 +        if (hr == D3D_OK)
   9.428 +                hr = v_buffer->Unlock();
   9.429 +
   9.430 +        if (hr == D3D_OK)
   9.431 +        {
   9.432 +                RECT lock_rect;
   9.433 +                
   9.434 +                lock_rect.top    = 0;
   9.435 +                lock_rect.left   = 0;
   9.436 +                lock_rect.bottom = 2047;
   9.437 +                lock_rect.right  = 2047;
   9.438 +
   9.439 +                if (FAILED(d3dTexture->LockRect(0, &dr, &lock_rect, 0)))
   9.440 +                        fatal("LockRect failed\n");
   9.441 +        
   9.442 +                for (yy = 0; yy < h; yy++)
   9.443 +                {
   9.444 +                        uint32_t *p = (uint32_t *)(dr.pBits + (yy * dr.Pitch));
   9.445 +                        if ((y + yy) >= 0 && (y + yy) < buffer->h)
   9.446 +                        {
   9.447 +                                for (xx = 0; xx < w; xx++)
   9.448 +                                        p[xx] = pal_lookup[buffer->line[y + yy][x + xx]];
   9.449 +                        }
   9.450 +                }
   9.451 +
   9.452 +                d3dTexture->UnlockRect(0);
   9.453 +        }
   9.454 +      
   9.455 +        if (hr == D3D_OK)        
   9.456 +                hr = d3ddev->BeginScene();
   9.457 +
   9.458 +        if (hr == D3D_OK)
   9.459 +        {
   9.460 +                if (hr == D3D_OK)
   9.461 +                        d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0, 0);
   9.462 +
   9.463 +                if (hr == D3D_OK)
   9.464 +                        hr = d3ddev->SetTexture(0, d3dTexture);
   9.465 +
   9.466 +                if (hr == D3D_OK)
   9.467 +                        hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
   9.468 +
   9.469 +                if (hr == D3D_OK)
   9.470 +                        hr = d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));
   9.471 +
   9.472 +                if (hr == D3D_OK)
   9.473 +                        hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
   9.474 +
   9.475 +                if (hr == D3D_OK)
   9.476 +                        hr = d3ddev->SetTexture(0, NULL);
   9.477 +
   9.478 +                if (hr == D3D_OK)
   9.479 +                        hr = d3ddev->EndScene();
   9.480 +        }
   9.481 +
   9.482 +        if (hr == D3D_OK)
   9.483 +                hr = d3ddev->Present(NULL, NULL, d3d_device_window, NULL);
   9.484 +        
   9.485 +        if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL)
   9.486 +                PostMessage(ghwnd, WM_RESETD3D, 0, 0);
   9.487 +}
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/src/win-d3d-fs.h	Sat Dec 07 13:43:06 2013 +0000
    10.3 @@ -0,0 +1,10 @@
    10.4 +#ifdef __cplusplus
    10.5 +extern "C" {
    10.6 +#endif
    10.7 +        void d3d_fs_init(HWND h);
    10.8 +        void d3d_fs_close();
    10.9 +        void d3d_fs_reset();
   10.10 +        void d3d_fs_resize(int x, int y);
   10.11 +#ifdef __cplusplus
   10.12 +}
   10.13 +#endif
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/src/win-ddraw-fs.cc	Sat Dec 07 13:43:06 2013 +0000
    11.3 @@ -0,0 +1,324 @@
    11.4 +#include <stdint.h>
    11.5 +#define BITMAP WINDOWS_BITMAP
    11.6 +#include <ddraw.h>
    11.7 +#undef BITMAP
    11.8 +#include "win-ddraw-fs.h"
    11.9 +#include "video.h"
   11.10 +
   11.11 +extern "C" void fatal(const char *format, ...);
   11.12 +extern "C" void pclog(const char *format, ...);
   11.13 +
   11.14 +extern "C" void device_force_redraw();
   11.15 +
   11.16 +extern "C" void ddraw_fs_init(HWND h);
   11.17 +extern "C" void ddraw_fs_close();
   11.18 +
   11.19 +static void ddraw_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h);
   11.20 +static void ddraw_fs_blit_memtoscreen_8(int x, int y, int w, int h);
   11.21 +
   11.22 +static LPDIRECTDRAW  lpdd  = NULL;
   11.23 +static LPDIRECTDRAW4 lpdd4 = NULL;
   11.24 +static LPDIRECTDRAWSURFACE4 lpdds_pri = NULL;
   11.25 +static LPDIRECTDRAWSURFACE4 lpdds_back = NULL;
   11.26 +static LPDIRECTDRAWSURFACE4 lpdds_back2 = NULL;
   11.27 +static LPDIRECTDRAWCLIPPER lpdd_clipper = NULL;
   11.28 +static DDSURFACEDESC2 ddsd;
   11.29 +
   11.30 +static HWND ddraw_hwnd;
   11.31 +static int ddraw_w, ddraw_h;
   11.32 +
   11.33 +static PALETTE cgapal =
   11.34 +{
   11.35 +        {0,0,0},{0,42,0},{42,0,0},{42,21,0},
   11.36 +        {0,0,0},{0,42,42},{42,0,42},{42,42,42},
   11.37 +        {0,0,0},{21,63,21},{63,21,21},{63,63,21},
   11.38 +        {0,0,0},{21,63,63},{63,21,63},{63,63,63},
   11.39 +
   11.40 +        {0,0,0},{0,0,42},{0,42,0},{0,42,42},
   11.41 +        {42,0,0},{42,0,42},{42,21,00},{42,42,42},
   11.42 +        {21,21,21},{21,21,63},{21,63,21},{21,63,63},
   11.43 +        {63,21,21},{63,21,63},{63,63,21},{63,63,63},
   11.44 +
   11.45 +        {0,0,0},{0,21,0},{0,0,42},{0,42,42},
   11.46 +        {42,0,21},{21,10,21},{42,0,42},{42,0,63},
   11.47 +        {21,21,21},{21,63,21},{42,21,42},{21,63,63},
   11.48 +        {63,0,0},{42,42,0},{63,21,42},{41,41,41},
   11.49 +        
   11.50 +        {0,0,0},{0,42,42},{42,0,0},{42,42,42},
   11.51 +        {0,0,0},{0,42,42},{42,0,0},{42,42,42},
   11.52 +        {0,0,0},{0,63,63},{63,0,0},{63,63,63},
   11.53 +        {0,0,0},{0,63,63},{63,0,0},{63,63,63},
   11.54 +};
   11.55 +
   11.56 +static uint32_t pal_lookup[256];
   11.57 +        
   11.58 +void ddraw_fs_init(HWND h)
   11.59 +{
   11.60 +        int c;
   11.61 +        
   11.62 +        ddraw_w = GetSystemMetrics(SM_CXSCREEN);
   11.63 +        ddraw_h = GetSystemMetrics(SM_CYSCREEN);
   11.64 +        
   11.65 +        for (c = 0; c < 256; c++)
   11.66 +            pal_lookup[c] = makecol(cgapal[c].r << 2, cgapal[c].g << 2, cgapal[c].b << 2);
   11.67 +
   11.68 +        if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL)))
   11.69 +           fatal("DirectDrawCreate failed\n");
   11.70 +        
   11.71 +        if (FAILED(lpdd->QueryInterface(IID_IDirectDraw4, (LPVOID *)&lpdd4)))
   11.72 +           fatal("QueryInterface failed\n");
   11.73 +
   11.74 +        lpdd->Release();
   11.75 +        lpdd = NULL;
   11.76 +        
   11.77 +        atexit(ddraw_fs_close);
   11.78 +
   11.79 +        if (FAILED(lpdd4->SetCooperativeLevel(h, DDSCL_SETFOCUSWINDOW |  
   11.80 +        DDSCL_CREATEDEVICEWINDOW | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT)))
   11.81 +           fatal("SetCooperativeLevel failed\n");
   11.82 +
   11.83 +        if (FAILED(lpdd4->SetDisplayMode(ddraw_w, ddraw_h, 32, 0 ,0)))
   11.84 +                fatal("SetDisplayMode failed\n");
   11.85 +           
   11.86 +        memset(&ddsd, 0, sizeof(ddsd));
   11.87 +        ddsd.dwSize = sizeof(ddsd);
   11.88 +        
   11.89 +        ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
   11.90 +        ddsd.dwBackBufferCount = 1;
   11.91 +        ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
   11.92 +        if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_pri, NULL)))
   11.93 +           fatal("CreateSurface failed\n");
   11.94 +        
   11.95 +        ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
   11.96 +        if (FAILED(lpdds_pri->GetAttachedSurface(&ddsd.ddsCaps, &lpdds_back2)))
   11.97 +           fatal("CreateSurface back failed\n");
   11.98 +        
   11.99 +        memset(&ddsd, 0, sizeof(ddsd));
  11.100 +        ddsd.dwSize = sizeof(ddsd);
  11.101 +        
  11.102 +        ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
  11.103 +        ddsd.dwWidth  = 2048;
  11.104 +        ddsd.dwHeight = 2048;
  11.105 +        ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
  11.106 +        if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_back, NULL)))
  11.107 +           fatal("CreateSurface back failed\n");
  11.108 +           
  11.109 +        pclog("DDRAW_INIT complete\n");
  11.110 +        ddraw_hwnd = h;
  11.111 +        video_blit_memtoscreen   = ddraw_fs_blit_memtoscreen;
  11.112 +        video_blit_memtoscreen_8 = ddraw_fs_blit_memtoscreen_8;
  11.113 +}
  11.114 +
  11.115 +void ddraw_fs_close()
  11.116 +{
  11.117 +        if (lpdds_back2)
  11.118 +        {
  11.119 +                lpdds_back2->Release();
  11.120 +                lpdds_back2 = NULL;
  11.121 +        }
  11.122 +        if (lpdds_back)
  11.123 +        {
  11.124 +                lpdds_back->Release();
  11.125 +                lpdds_back = NULL;
  11.126 +        }
  11.127 +        if (lpdds_pri)
  11.128 +        {
  11.129 +                lpdds_pri->Release();
  11.130 +                lpdds_pri = NULL;
  11.131 +        }
  11.132 +        if (lpdd_clipper)
  11.133 +        {
  11.134 +                lpdd_clipper->Release();
  11.135 +                lpdd_clipper = NULL;
  11.136 +        }
  11.137 +        if (lpdd4)
  11.138 +        {
  11.139 +                lpdd4->Release();
  11.140 +                lpdd4 = NULL;
  11.141 +        }
  11.142 +}
  11.143 +
  11.144 +static void ddraw_fs_size(RECT window_rect, RECT *r_dest, int w, int h)
  11.145 +{
  11.146 +        int ratio_w, ratio_h;
  11.147 +        switch (video_fullscreen_scale)
  11.148 +        {
  11.149 +                case FULLSCR_SCALE_FULL:
  11.150 +                r_dest->left   = 0;
  11.151 +                r_dest->top    = 0;
  11.152 +                r_dest->right  = (window_rect.right  - window_rect.left) - 1;
  11.153 +                r_dest->bottom = (window_rect.bottom - window_rect.top) - 1;
  11.154 +                break;
  11.155 +                case FULLSCR_SCALE_43:
  11.156 +                r_dest->top    = 0;
  11.157 +                r_dest->bottom = (window_rect.bottom - window_rect.top) - 1;
  11.158 +                r_dest->left   = ((window_rect.right  - window_rect.left) / 2) - (((window_rect.bottom - window_rect.top) * 4) / (3 * 2));
  11.159 +                r_dest->right  = ((window_rect.right  - window_rect.left) / 2) + (((window_rect.bottom - window_rect.top) * 4) / (3 * 2)) - 1;
  11.160 +                if (r_dest->left < 0)
  11.161 +                {
  11.162 +                        r_dest->left   = 0;
  11.163 +                        r_dest->right  = (window_rect.right  - window_rect.left) - 1;
  11.164 +                        r_dest->top    = ((window_rect.bottom - window_rect.top) / 2) - (((window_rect.right - window_rect.left) * 3) / (4 * 2));
  11.165 +                        r_dest->bottom = ((window_rect.bottom - window_rect.top) / 2) + (((window_rect.right - window_rect.left) * 3) / (4 * 2)) - 1;
  11.166 +                }
  11.167 +                break;
  11.168 +                case FULLSCR_SCALE_SQ:
  11.169 +                r_dest->top    = 0;
  11.170 +                r_dest->bottom = (window_rect.bottom - window_rect.top) - 1;
  11.171 +                r_dest->left   = ((window_rect.right  - window_rect.left) / 2) - (((window_rect.bottom - window_rect.top) * w) / (h * 2));
  11.172 +                r_dest->right  = ((window_rect.right  - window_rect.left) / 2) + (((window_rect.bottom - window_rect.top) * w) / (h * 2)) - 1;
  11.173 +                if (r_dest->left < 0)
  11.174 +                {
  11.175 +                        r_dest->left   = 0;
  11.176 +                        r_dest->right  = (window_rect.right  - window_rect.left) - 1;
  11.177 +                        r_dest->top    = ((window_rect.bottom - window_rect.top) / 2) - (((window_rect.right - window_rect.left) * h) / (w * 2));
  11.178 +                        r_dest->bottom = ((window_rect.bottom - window_rect.top) / 2) + (((window_rect.right - window_rect.left) * h) / (w * 2)) - 1;
  11.179 +                }
  11.180 +                break;
  11.181 +                case FULLSCR_SCALE_INT:
  11.182 +                ratio_w = (window_rect.right  - window_rect.left) / w;
  11.183 +                ratio_h = (window_rect.bottom - window_rect.top)  / h;
  11.184 +                if (ratio_h < ratio_w)
  11.185 +                        ratio_w = ratio_h;
  11.186 +                r_dest->left   = ((window_rect.right  - window_rect.left) / 2) - ((w * ratio_w) / 2);
  11.187 +                r_dest->right  = ((window_rect.right  - window_rect.left) / 2) + ((w * ratio_w) / 2) - 1;
  11.188 +                r_dest->top    = ((window_rect.bottom - window_rect.top)  / 2) - ((h * ratio_w) / 2);
  11.189 +                r_dest->bottom = ((window_rect.bottom - window_rect.top)  / 2) + ((h * ratio_w) / 2) - 1;
  11.190 +                break;
  11.191 +        }
  11.192 +}
  11.193 +
  11.194 +static void ddraw_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h)
  11.195 +{
  11.196 +        RECT r_src;
  11.197 +        RECT r_dest;
  11.198 +        RECT window_rect;
  11.199 +        int yy;
  11.200 +        HRESULT hr;
  11.201 +        DDBLTFX ddbltfx;
  11.202 +                
  11.203 +        memset(&ddsd, 0, sizeof(ddsd));
  11.204 +        ddsd.dwSize = sizeof(ddsd);
  11.205 +
  11.206 +        hr = lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
  11.207 +        if (hr == DDERR_SURFACELOST)
  11.208 +        {
  11.209 +                lpdds_back->Restore();
  11.210 +                lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
  11.211 +                device_force_redraw();
  11.212 +        }
  11.213 +        if (!ddsd.lpSurface) return;
  11.214 +        for (yy = y1; yy < y2; yy++)
  11.215 +            memcpy(ddsd.lpSurface + (yy * ddsd.lPitch), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4);
  11.216 +        lpdds_back->Unlock(NULL);
  11.217 +        
  11.218 +        window_rect.left = 0;
  11.219 +        window_rect.top = 0;
  11.220 +        window_rect.right = ddraw_w;
  11.221 +        window_rect.bottom = ddraw_h;
  11.222 +        ddraw_fs_size(window_rect, &r_dest, w, h);
  11.223 +        
  11.224 +        r_src.left   = 0;
  11.225 +        r_src.top    = 0;       
  11.226 +        r_src.right  = w;
  11.227 +        r_src.bottom = h;
  11.228 +
  11.229 +        ddbltfx.dwSize = sizeof(ddbltfx);
  11.230 +        ddbltfx.dwFillColor = 0;
  11.231 +        
  11.232 +        lpdds_back2->Blt(&window_rect, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx);
  11.233 +        
  11.234 +        hr = lpdds_back2->Blt(&r_dest, lpdds_back, &r_src, DDBLT_WAIT, NULL);
  11.235 +        if (hr == DDERR_SURFACELOST)
  11.236 +        {
  11.237 +                lpdds_back2->Restore();
  11.238 +                lpdds_back2->Blt(&r_dest, lpdds_back, &r_src, DDBLT_WAIT, NULL);
  11.239 +        }
  11.240 +        
  11.241 +        if (readflash)
  11.242 +        {
  11.243 +                RECT r;
  11.244 +                r.left   = window_rect.right - 40;
  11.245 +                r.right  = window_rect.right - 8;
  11.246 +                r.top    = 8;
  11.247 +                r.bottom = 14;
  11.248 +                ddbltfx.dwFillColor = 0xffffff;
  11.249 +                lpdds_back2->Blt(&r, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx);
  11.250 +        }
  11.251 +        
  11.252 +        hr = lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC);        
  11.253 +        if (hr == DDERR_SURFACELOST)
  11.254 +        {
  11.255 +                lpdds_pri->Restore();
  11.256 +                lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC);
  11.257 +        }
  11.258 +}
  11.259 +
  11.260 +static void ddraw_fs_blit_memtoscreen_8(int x, int y, int w, int h)
  11.261 +{
  11.262 +        RECT r_src;
  11.263 +        RECT r_dest;
  11.264 +        RECT window_rect;
  11.265 +        int xx, yy;
  11.266 +        HRESULT hr;
  11.267 +        DDBLTFX ddbltfx;
  11.268 +
  11.269 +        memset(&ddsd, 0, sizeof(ddsd));
  11.270 +        ddsd.dwSize = sizeof(ddsd);
  11.271 +
  11.272 +        hr = lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
  11.273 +
  11.274 +        if (hr == DDERR_SURFACELOST)
  11.275 +        {
  11.276 +                lpdds_back->Restore();
  11.277 +                lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
  11.278 +                device_force_redraw();
  11.279 +        }
  11.280 +        if (!ddsd.lpSurface) return;
  11.281 +        for (yy = 0; yy < h; yy++)
  11.282 +        {
  11.283 +                if ((y + yy) >= 0 && (y + yy) < buffer->h)
  11.284 +                {
  11.285 +                        uint32_t *p = (uint32_t *)(ddsd.lpSurface + (yy * ddsd.lPitch));
  11.286 +                        for (xx = 0; xx < w; xx++)
  11.287 +                            p[xx] = pal_lookup[buffer->line[y + yy][x + xx]];
  11.288 +                }
  11.289 +        }
  11.290 +        lpdds_back->Unlock(NULL);
  11.291 +
  11.292 +        window_rect.left = 0;
  11.293 +        window_rect.top = 0;
  11.294 +        window_rect.right = ddraw_w;
  11.295 +        window_rect.bottom = ddraw_h;
  11.296 +        ddraw_fs_size(window_rect, &r_dest, w, h);
  11.297 +        
  11.298 +        r_src.left   = 0;
  11.299 +        r_src.top    = 0;       
  11.300 +        r_src.right  = w;
  11.301 +        r_src.bottom = h;
  11.302 +
  11.303 +        ddbltfx.dwSize = sizeof(ddbltfx);
  11.304 +        ddbltfx.dwFillColor = 0;
  11.305 +        
  11.306 +        lpdds_back2->Blt(&window_rect, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx);
  11.307 +        
  11.308 +        hr = lpdds_back2->Blt(&r_dest, lpdds_back, &r_src, DDBLT_WAIT, NULL);
  11.309 +        if (hr == DDERR_SURFACELOST)
  11.310 +        {
  11.311 +                lpdds_back2->Restore();
  11.312 +                lpdds_back2->Blt(&r_dest, lpdds_back, &r_src, DDBLT_WAIT, NULL);
  11.313 +        }
  11.314 +        
  11.315 +        if (readflash)
  11.316 +        {
  11.317 +                RECT r;
  11.318 +                r.left   = window_rect.right - 40;
  11.319 +                r.right  = window_rect.right - 8;
  11.320 +                r.top    = 8;
  11.321 +                r.bottom = 14;
  11.322 +                ddbltfx.dwFillColor = 0xffffff;
  11.323 +                lpdds_back2->Blt(&r, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx);
  11.324 +        }
  11.325 +        
  11.326 +        lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC);        
  11.327 +}
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/src/win-ddraw-fs.h	Sat Dec 07 13:43:06 2013 +0000
    12.3 @@ -0,0 +1,8 @@
    12.4 +#ifdef __cplusplus
    12.5 +extern "C" {
    12.6 +#endif
    12.7 +        void ddraw_fs_init(HWND h);
    12.8 +        void ddraw_fs_close();
    12.9 +#ifdef __cplusplus
   12.10 +}
   12.11 +#endif
    13.1 --- a/src/win-ddraw.cc	Mon Dec 02 21:00:26 2013 +0000
    13.2 +++ b/src/win-ddraw.cc	Sat Dec 07 13:43:06 2013 +0000
    13.3 @@ -12,17 +12,19 @@
    13.4  
    13.5  extern "C" void ddraw_init(HWND h);
    13.6  extern "C" void ddraw_close();
    13.7 -extern "C" void ddraw_draw();
    13.8  
    13.9 -LPDIRECTDRAW  lpdd  = NULL;
   13.10 -LPDIRECTDRAW4 lpdd4 = NULL;
   13.11 -LPDIRECTDRAWSURFACE4 lpdds_pri = NULL;
   13.12 -LPDIRECTDRAWSURFACE4 lpdds_back = NULL;
   13.13 -LPDIRECTDRAWSURFACE4 lpdds_back2 = NULL;
   13.14 -LPDIRECTDRAWCLIPPER lpdd_clipper = NULL;
   13.15 -DDSURFACEDESC2 ddsd;
   13.16 +static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h);
   13.17 +static void ddraw_blit_memtoscreen_8(int x, int y, int w, int h);
   13.18  
   13.19 -HWND ddraw_hwnd;
   13.20 +static LPDIRECTDRAW  lpdd  = NULL;
   13.21 +static LPDIRECTDRAW4 lpdd4 = NULL;
   13.22 +static LPDIRECTDRAWSURFACE4 lpdds_pri = NULL;
   13.23 +static LPDIRECTDRAWSURFACE4 lpdds_back = NULL;
   13.24 +static LPDIRECTDRAWSURFACE4 lpdds_back2 = NULL;
   13.25 +static LPDIRECTDRAWCLIPPER lpdd_clipper = NULL;
   13.26 +static DDSURFACEDESC2 ddsd;
   13.27 +
   13.28 +static HWND ddraw_hwnd;
   13.29  
   13.30  static PALETTE cgapal=
   13.31  {
   13.32 @@ -140,7 +142,7 @@
   13.33          }
   13.34  }
   13.35  
   13.36 -void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h)
   13.37 +static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h)
   13.38  {
   13.39          RECT r_src;
   13.40          RECT r_dest;
   13.41 @@ -171,7 +173,7 @@
   13.42          ClientToScreen(ddraw_hwnd, &po);
   13.43          GetClientRect(ddraw_hwnd, &r_dest);
   13.44          OffsetRect(&r_dest, po.x, po.y);        
   13.45 -
   13.46 +        
   13.47          r_src.left   = 0;
   13.48          r_src.top    = 0;       
   13.49          r_src.right  = w;
   13.50 @@ -213,7 +215,7 @@
   13.51          }
   13.52  }
   13.53  
   13.54 -void ddraw_blit_memtoscreen_8(int x, int y, int w, int h)
   13.55 +static void ddraw_blit_memtoscreen_8(int x, int y, int w, int h)
   13.56  {
   13.57          RECT r_src;
   13.58          RECT r_dest;
    14.1 --- a/src/win-ddraw.h	Mon Dec 02 21:00:26 2013 +0000
    14.2 +++ b/src/win-ddraw.h	Sat Dec 07 13:43:06 2013 +0000
    14.3 @@ -3,9 +3,6 @@
    14.4  #endif
    14.5          void ddraw_init(HWND h);
    14.6          void ddraw_close();
    14.7 -        
    14.8 -        void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h);
    14.9 -        void ddraw_blit_memtoscreen_8(int x, int y, int w, int h);
   14.10  #ifdef __cplusplus
   14.11  }
   14.12  #endif
    15.1 --- a/src/win-keyboard.cc	Mon Dec 02 21:00:26 2013 +0000
    15.2 +++ b/src/win-keyboard.cc	Sat Dec 07 13:43:06 2013 +0000
    15.3 @@ -2,9 +2,12 @@
    15.4  #include <string.h>
    15.5  #include <stdint.h>
    15.6  #define DIRECTINPUT_VERSION	0x0700
    15.7 +#define BITMAP WINDOWS_BITMAP
    15.8  #include <dinput.h>
    15.9 +#undef BITMAP
   15.10  #include "plat-keyboard.h"
   15.11  #include "win.h"
   15.12 +#include "video.h"
   15.13  
   15.14  extern "C" int key[256];
   15.15  uint8_t dinput_key[256];
   15.16 @@ -106,4 +109,9 @@
   15.17  //                        if (key[c]) pclog("Key down %i %02X  %i %02X\n", c, c, keyboard_lookup[c], keyboard_lookup[c]);
   15.18                  }
   15.19          }
   15.20 +        if (((dinput_key[DIK_LCONTROL] | dinput_key[DIK_RCONTROL]) & 0x80) && 
   15.21 +            ((dinput_key[DIK_LMENU]    | dinput_key[DIK_RMENU])    & 0x80) && 
   15.22 +             (dinput_key[DIK_NEXT] & 0x80) &&
   15.23 +            video_fullscreen)
   15.24 +                leave_fullscreen();
   15.25  }
    16.1 --- a/src/win-mouse.cc	Mon Dec 02 21:00:26 2013 +0000
    16.2 +++ b/src/win-mouse.cc	Sat Dec 07 13:43:06 2013 +0000
    16.3 @@ -3,6 +3,8 @@
    16.4  #include "plat-dinput.h"
    16.5  #include "win.h"
    16.6  
    16.7 +extern "C" int video_fullscreen;
    16.8 +
    16.9  extern "C" void fatal(const char *format, ...);
   16.10  extern "C" void pclog(const char *format, ...);
   16.11  
   16.12 @@ -23,7 +25,7 @@
   16.13          
   16.14          if (FAILED(lpdi->CreateDevice(GUID_SysMouse, &lpdi_mouse, NULL)))
   16.15             fatal("mouse_init : CreateDevice failed\n");
   16.16 -        if (FAILED(lpdi_mouse->SetCooperativeLevel(ghwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
   16.17 +        if (FAILED(lpdi_mouse->SetCooperativeLevel(ghwnd, DISCL_FOREGROUND | (video_fullscreen ? DISCL_EXCLUSIVE : DISCL_NONEXCLUSIVE))))
   16.18             fatal("mouse_init : SetCooperativeLevel failed\n");
   16.19          if (FAILED(lpdi_mouse->SetDataFormat(&c_dfDIMouse)))
   16.20             fatal("mouse_init : SetDataFormat failed\n");
   16.21 @@ -56,7 +58,7 @@
   16.22             mouse_b |= 4;
   16.23          mouse_x += mousestate.lX;
   16.24          mouse_y += mousestate.lY;        
   16.25 -        if (!mousecapture)
   16.26 +        if (!mousecapture && !video_fullscreen)
   16.27             mouse_x = mouse_y = mouse_b = 0;
   16.28  }
   16.29  
    17.1 --- a/src/win.c	Mon Dec 02 21:00:26 2013 +0000
    17.2 +++ b/src/win.c	Sat Dec 07 13:43:06 2013 +0000
    17.3 @@ -21,8 +21,11 @@
    17.4  #include "plat-midi.h"
    17.5  #include "plat-keyboard.h"
    17.6  
    17.7 +#include "win.h"
    17.8  #include "win-ddraw.h"
    17.9 +#include "win-ddraw-fs.h"
   17.10  #include "win-d3d.h"
   17.11 +#include "win-d3d-fs.h"
   17.12  //#include "win-opengl.h"
   17.13  
   17.14  static struct
   17.15 @@ -30,10 +33,16 @@
   17.16          void (*init)(HWND h);
   17.17          void (*close)();
   17.18          void (*resize)(int x, int y);
   17.19 -} vid_apis[] =
   17.20 +} vid_apis[2][2] =
   17.21  {
   17.22 -        ddraw_init, ddraw_close, NULL,
   17.23 -        d3d_init, d3d_close, d3d_resize
   17.24 +        {
   17.25 +                ddraw_init, ddraw_close, NULL,
   17.26 +                d3d_init, d3d_close, d3d_resize
   17.27 +        },
   17.28 +        {
   17.29 +                ddraw_fs_init, ddraw_fs_close, NULL,
   17.30 +                d3d_fs_init, d3d_fs_close, NULL
   17.31 +        },
   17.32  };
   17.33  
   17.34  #define TIMER_1SEC 1
   17.35 @@ -80,10 +89,8 @@
   17.36  int mousecapture=0;
   17.37  int drawit;
   17.38  /*  Declare Windows procedure  */
   17.39 -LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
   17.40 -
   17.41 -/*  Make the class name into a global variable  */
   17.42 -char szClassName[ ] = "WindowsApp";
   17.43 +LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
   17.44 +LRESULT CALLBACK subWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
   17.45  
   17.46  HWND ghwnd;
   17.47  static int win_doresize = 0;
   17.48 @@ -130,6 +137,12 @@
   17.49          LeaveCriticalSection(&cs);
   17.50  }
   17.51  
   17.52 +static int leave_fullscreen_flag = 0;
   17.53 +void leave_fullscreen()
   17.54 +{
   17.55 +        leave_fullscreen_flag = 1;
   17.56 +}
   17.57 +
   17.58  int mainthreadon=0;
   17.59  
   17.60  /*static HANDLE blitobject;
   17.61 @@ -189,20 +202,24 @@
   17.62                          }
   17.63                  }
   17.64                  else
   17.65 -                {
   17.66                          Sleep(1);
   17.67 -                }
   17.68  
   17.69 -                if (win_doresize)
   17.70 +                if (!video_fullscreen && win_doresize)
   17.71                  {
   17.72                          RECT r;
   17.73                          GetWindowRect(ghwnd, &r);
   17.74                          MoveWindow(ghwnd, r.left, r.top,
   17.75 -                                   winsizex + (GetSystemMetrics(SM_CXFIXEDFRAME) * 2),
   17.76 -                                   winsizey + (GetSystemMetrics(SM_CYFIXEDFRAME) * 2) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 1,
   17.77 -                                   TRUE);
   17.78 +                                winsizex + (GetSystemMetrics(SM_CXFIXEDFRAME) * 2),
   17.79 +                                winsizey + (GetSystemMetrics(SM_CYFIXEDFRAME) * 2) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 1,
   17.80 +                                TRUE);
   17.81                          win_doresize = 0;
   17.82                  }
   17.83 +
   17.84 +                if (leave_fullscreen_flag)
   17.85 +                {
   17.86 +                        leave_fullscreen_flag = 0;
   17.87 +                        SendMessage(ghwnd, WM_LEAVEFULLSCREEN, 0, 0);
   17.88 +                }
   17.89          }
   17.90          mainthreadon=0;
   17.91  }
   17.92 @@ -239,6 +256,8 @@
   17.93  
   17.94  void set_window_title(char *s)
   17.95  {
   17.96 +        if (video_fullscreen)
   17.97 +                return;
   17.98          SetWindowText(ghwnd, s);
   17.99  }
  17.100  
  17.101 @@ -248,51 +267,57 @@
  17.102                      int nFunsterStil)
  17.103  
  17.104  {
  17.105 -    HWND hwnd;               /* This is the handle for our window */
  17.106 -    MSG messages;            /* Here messages to the application are saved */
  17.107 -    WNDCLASSEX wincl;        /* Data structure for the windowclass */
  17.108 -    int c, d;
  17.109 +        HWND hwnd;               /* This is the handle for our window */
  17.110 +        MSG messages;            /* Here messages to the application are saved */
  17.111 +        WNDCLASSEX wincl;        /* Data structure for the windowclass */
  17.112 +        int c, d;
  17.113  
  17.114          hinstance=hThisInstance;
  17.115 -    /* The Window structure */
  17.116 -    wincl.hInstance = hThisInstance;
  17.117 -    wincl.lpszClassName = szClassName;
  17.118 -    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
  17.119 -    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
  17.120 -    wincl.cbSize = sizeof (WNDCLASSEX);
  17.121 +        /* The Window structure */
  17.122 +        wincl.hInstance = hThisInstance;
  17.123 +        wincl.lpszClassName = szClassName;
  17.124 +        wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
  17.125 +        wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
  17.126 +        wincl.cbSize = sizeof (WNDCLASSEX);
  17.127  
  17.128 -    /* Use default icon and mouse-pointer */
  17.129 -    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
  17.130 -    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
  17.131 -    wincl.hCursor = NULL;//LoadCursor (NULL, IDC_ARROW);
  17.132 -    wincl.lpszMenuName = NULL;                 /* No menu */
  17.133 -    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
  17.134 -    wincl.cbWndExtra = 0;                      /* structure or the window instance */
  17.135 -    /* Use Windows's default color as the background of the window */
  17.136 -    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
  17.137 +        /* Use default icon and mouse-pointer */
  17.138 +        wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
  17.139 +        wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
  17.140 +        wincl.hCursor = NULL;//LoadCursor (NULL, IDC_ARROW);
  17.141 +        wincl.lpszMenuName = NULL;                 /* No menu */
  17.142 +        wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
  17.143 +        wincl.cbWndExtra = 0;                      /* structure or the window instance */
  17.144 +        /* Use Windows's default color as the background of the window */
  17.145 +        wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
  17.146  
  17.147 -    /* Register the window class, and if it fails quit the program */
  17.148 -    if (!RegisterClassEx (&wincl))
  17.149 -        return 0;
  17.150 +        /* Register the window class, and if it fails quit the program */
  17.151 +        if (!RegisterClassEx(&wincl))
  17.152 +                return 0;
  17.153  
  17.154 -        menu=LoadMenu(hThisInstance,TEXT("MainMenu"));
  17.155 +        wincl.lpszClassName = szSubClassName;
  17.156 +        wincl.lpfnWndProc = subWindowProcedure;      /* This function is called by windows */
  17.157 +
  17.158 +        if (!RegisterClassEx(&wincl))
  17.159 +                return 0;
  17.160 +
  17.161 +        menu = LoadMenu(hThisInstance, TEXT("MainMenu"));
  17.162          initmenu();
  17.163          
  17.164 -    /* The class is registered, let's create the program*/
  17.165 -    hwnd = CreateWindowEx (
  17.166 -           0,                   /* Extended possibilites for variation */
  17.167 -           szClassName,         /* Classname */
  17.168 -           "PCem v0.7",         /* Title Text */
  17.169 -           WS_OVERLAPPEDWINDOW&~WS_SIZEBOX, /* default window */
  17.170 -           CW_USEDEFAULT,       /* Windows decides the position */
  17.171 -           CW_USEDEFAULT,       /* where the window ends up on the screen */
  17.172 -           640+(GetSystemMetrics(SM_CXFIXEDFRAME)*2),                 /* The programs width */
  17.173 -           480+(GetSystemMetrics(SM_CYFIXEDFRAME)*2)+GetSystemMetrics(SM_CYMENUSIZE)+GetSystemMetrics(SM_CYCAPTION)+1,                 /* and height in pixels */
  17.174 -           HWND_DESKTOP,        /* The window is a child-window to desktop */
  17.175 -           menu,                /* Menu */
  17.176 -           hThisInstance,       /* Program Instance handler */
  17.177 -           NULL                 /* No Window Creation data */
  17.178 -           );
  17.179 +        /* The class is registered, let's create the program*/
  17.180 +        hwnd = CreateWindowEx (
  17.181 +                0,                   /* Extended possibilites for variation */
  17.182 +                szClassName,         /* Classname */
  17.183 +                "PCem v0.7",         /* Title Text */
  17.184 +                WS_OVERLAPPEDWINDOW&~WS_SIZEBOX, /* default window */
  17.185 +                CW_USEDEFAULT,       /* Windows decides the position */
  17.186 +                CW_USEDEFAULT,       /* where the window ends up on the screen */
  17.187 +                640+(GetSystemMetrics(SM_CXFIXEDFRAME)*2),                 /* The programs width */
  17.188 +                480+(GetSystemMetrics(SM_CYFIXEDFRAME)*2)+GetSystemMetrics(SM_CYMENUSIZE)+GetSystemMetrics(SM_CYCAPTION)+1,                 /* and height in pixels */
  17.189 +                HWND_DESKTOP,        /* The window is a child-window to desktop */
  17.190 +                menu,                /* Menu */
  17.191 +                hThisInstance,       /* Program Instance handler */
  17.192 +                NULL                 /* No Window Creation data */
  17.193 +        );
  17.194  
  17.195          /* Make the window visible on the screen */
  17.196          ShowWindow (hwnd, nFunsterStil);
  17.197 @@ -306,7 +331,7 @@
  17.198          
  17.199          initpc();
  17.200          
  17.201 -        vid_apis[vid_api].init(ghwnd);
  17.202 +        vid_apis[0][vid_api].init(ghwnd);
  17.203  
  17.204          if (vid_resize) SetWindowLong(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW|WS_VISIBLE);
  17.205          else            SetWindowLong(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_THICKFRAME&~WS_MAXIMIZEBOX)|WS_VISIBLE);
  17.206 @@ -315,9 +340,9 @@
  17.207             CheckMenuItem(menu, IDM_CDROM_DISABLED, MF_CHECKED);
  17.208          else           
  17.209             CheckMenuItem(menu, IDM_CDROM_REAL + cdrom_drive, MF_CHECKED);
  17.210 -        CheckMenuItem(menu, IDM_KEY_ALLEGRO + kb_win, MF_CHECKED);
  17.211          if (vid_resize) CheckMenuItem(menu, IDM_VID_RESIZE, MF_CHECKED);
  17.212 -        CheckMenuItem(menu, IDM_VID_DDRAW + vid_api, MF_CHECKED);        
  17.213 +        CheckMenuItem(menu, IDM_VID_DDRAW + vid_api, MF_CHECKED);
  17.214 +        CheckMenuItem(menu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_CHECKED);
  17.215  //        set_display_switch_mode(SWITCH_BACKGROUND);
  17.216          
  17.217          d=romset;
  17.218 @@ -439,12 +464,12 @@
  17.219                          if (messages.message==WM_QUIT) quited=1;
  17.220                          TranslateMessage(&messages);
  17.221                          DispatchMessage(&messages);                        
  17.222 -                                if ((key[KEY_LCONTROL] || key[KEY_RCONTROL]) && key[KEY_END] && mousecapture)
  17.223 -                                {
  17.224 -                                        ClipCursor(&oldclip);
  17.225 -                                        ShowCursor(TRUE);
  17.226 -                                        mousecapture=0;
  17.227 -                                }
  17.228 +                        if ((key[KEY_LCONTROL] || key[KEY_RCONTROL]) && key[KEY_END] && mousecapture)
  17.229 +                        {
  17.230 +                                ClipCursor(&oldclip);
  17.231 +                                ShowCursor(TRUE);
  17.232 +                                mousecapture=0;
  17.233 +                        }
  17.234                  }
  17.235  
  17.236                  quited=1;
  17.237 @@ -463,7 +488,7 @@
  17.238          closepc();
  17.239  //        pclog("dumpregs\n");
  17.240  
  17.241 -        vid_apis[vid_api].close();
  17.242 +        vid_apis[video_fullscreen][vid_api].close();
  17.243          
  17.244          timeEndPeriod(1);
  17.245  //        endsoundthread();
  17.246 @@ -473,6 +498,10 @@
  17.247                  ClipCursor(&oldclip);
  17.248                  ShowCursor(TRUE);
  17.249          }
  17.250 +        
  17.251 +        UnregisterClass(szSubClassName, hinstance);
  17.252 +        UnregisterClass(szClassName, hinstance);
  17.253 +
  17.254  //        pclog("Ending! %i %i\n",messages.wParam,quited);
  17.255          return messages.wParam;
  17.256  }
  17.257 @@ -1398,12 +1427,13 @@
  17.258  
  17.259  LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam )
  17.260  {
  17.261 -    if (nCode < 0 || nCode != HC_ACTION || !mousecapture) return CallNextHookEx( hKeyboardHook, nCode, wParam, lParam); 
  17.262 +        if (nCode < 0 || nCode != HC_ACTION || (!mousecapture && !video_fullscreen))
  17.263 +                return CallNextHookEx( hKeyboardHook, nCode, wParam, lParam); 
  17.264  	
  17.265  	KBDLLHOOKSTRUCT* p = (KBDLLHOOKSTRUCT*)lParam;
  17.266  
  17.267 -    if(p->vkCode==VK_TAB && p->flags & LLKHF_ALTDOWN) return 1; //disable alt-tab
  17.268 -    if(p->vkCode==VK_SPACE && p->flags & LLKHF_ALTDOWN) return 1; //disable alt-tab    
  17.269 +        if (p->vkCode == VK_TAB && p->flags & LLKHF_ALTDOWN) return 1; //disable alt-tab
  17.270 +        if (p->vkCode == VK_SPACE && p->flags & LLKHF_ALTDOWN) return 1; //disable alt-tab    
  17.271  	if((p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN)) return 1;//disable windows keys
  17.272  	if (p->vkCode == VK_ESCAPE && p->flags & LLKHF_ALTDOWN) return 1;//disable alt-escape
  17.273  	BOOL bControlKeyDown = GetAsyncKeyState (VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1);//checks ctrl key pressed
  17.274 @@ -1496,21 +1526,39 @@
  17.275                          case IDM_VID_DDRAW: case IDM_VID_D3D:
  17.276                          startblit();
  17.277                          CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_UNCHECKED);
  17.278 -                        vid_apis[vid_api].close();
  17.279 +                        vid_apis[0][vid_api].close();
  17.280                          vid_api = LOWORD(wParam) - IDM_VID_DDRAW;
  17.281                          CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_CHECKED);
  17.282 -                        vid_apis[vid_api].init(ghwnd);
  17.283 +                        vid_apis[0][vid_api].init(ghwnd);
  17.284                          endblit();
  17.285                          saveconfig();
  17.286                          device_force_redraw();
  17.287                          break;
  17.288  
  17.289 -                        case IDM_KEY_ALLEGRO: case IDM_KEY_WINDOWS:
  17.290 -                        CheckMenuItem(hmenu,LOWORD(wParam),MF_CHECKED);
  17.291 -                        CheckMenuItem(hmenu,LOWORD(wParam)^1,MF_UNCHECKED);
  17.292 -//                        if (kb_win && LOWORD(wParam)==IDM_KEY_ALLEGRO) install_keyboard();
  17.293 -//                        if (!kb_win && LOWORD(wParam)==IDM_KEY_WINDOWS) remove_keyboard();
  17.294 -                        kb_win=LOWORD(wParam)-IDM_KEY_ALLEGRO;
  17.295 +                        case IDM_VID_FULLSCREEN:
  17.296 +                        if (video_fullscreen_first)
  17.297 +                        {
  17.298 +                                video_fullscreen_first = 0;
  17.299 +                                MessageBox(hwnd, "Use CTRL + ALT + PAGE DOWN to return to windowed mode", "PCem", MB_OK);
  17.300 +                        }
  17.301 +                        startblit();
  17.302 +                        mouse_close();
  17.303 +                        vid_apis[0][vid_api].close();
  17.304 +                        video_fullscreen = 1;
  17.305 +                        vid_apis[1][vid_api].init(ghwnd);
  17.306 +                        mouse_init();
  17.307 +                        endblit();
  17.308 +                        device_force_redraw();
  17.309 +                        break;
  17.310 +
  17.311 +                        case IDM_VID_FS_FULL:
  17.312 +                        case IDM_VID_FS_43:
  17.313 +                        case IDM_VID_FS_SQ:                                
  17.314 +                        case IDM_VID_FS_INT:
  17.315 +                        CheckMenuItem(hmenu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_UNCHECKED);
  17.316 +                        video_fullscreen_scale = LOWORD(wParam) - IDM_VID_FS_FULL;
  17.317 +                        CheckMenuItem(hmenu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_CHECKED);
  17.318 +                        saveconfig();
  17.319                          break;
  17.320                          
  17.321                          case IDM_CDROM_DISABLED:
  17.322 @@ -1597,7 +1645,7 @@
  17.323                  break;
  17.324  
  17.325                  case WM_LBUTTONUP:
  17.326 -                if (!mousecapture)
  17.327 +                if (!mousecapture && !video_fullscreen)
  17.328                  {
  17.329                          RECT pcclip;
  17.330  
  17.331 @@ -1621,10 +1669,10 @@
  17.332                  winsizex=lParam&0xFFFF;
  17.333                  winsizey=lParam>>16;
  17.334  
  17.335 -                if (vid_apis[vid_api].resize)
  17.336 +                if (vid_apis[video_fullscreen][vid_api].resize)
  17.337                  {
  17.338                          startblit();
  17.339 -                        vid_apis[vid_api].resize(winsizex, winsizey);
  17.340 +                        vid_apis[video_fullscreen][vid_api].resize(winsizex, winsizey);
  17.341                          endblit();
  17.342                  }
  17.343  
  17.344 @@ -1648,9 +1696,23 @@
  17.345                  
  17.346                  case WM_RESETD3D:
  17.347                  startblit();
  17.348 -                d3d_reset();
  17.349 +                if (video_fullscreen)
  17.350 +                        d3d_fs_reset();
  17.351 +                else
  17.352 +                        d3d_reset();
  17.353                  endblit();
  17.354                  break;
  17.355 +                
  17.356 +                case WM_LEAVEFULLSCREEN:
  17.357 +                startblit();
  17.358 +                mouse_close();
  17.359 +                vid_apis[1][vid_api].close();
  17.360 +                video_fullscreen = 0;
  17.361 +                vid_apis[0][vid_api].init(ghwnd);
  17.362 +                mouse_init();
  17.363 +                endblit();
  17.364 +                device_force_redraw();
  17.365 +                break;
  17.366  
  17.367                  case WM_KEYDOWN:
  17.368                  case WM_SYSKEYDOWN:
  17.369 @@ -1671,3 +1733,13 @@
  17.370          }
  17.371          return 0;
  17.372  }
  17.373 +
  17.374 +LRESULT CALLBACK subWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  17.375 +{
  17.376 +        switch (message)
  17.377 +        {
  17.378 +                default:
  17.379 +                return DefWindowProc(hwnd, message, wParam, lParam);
  17.380 +        }
  17.381 +        return 0;
  17.382 +}
    18.1 --- a/src/win.h	Mon Dec 02 21:00:26 2013 +0000
    18.2 +++ b/src/win.h	Sat Dec 07 13:43:06 2013 +0000
    18.3 @@ -1,3 +1,16 @@
    18.4  extern HINSTANCE hinstance;
    18.5  extern HWND ghwnd;
    18.6  extern int mousecapture;
    18.7 +
    18.8 +#ifdef __cplusplus
    18.9 +extern "C" {
   18.10 +#endif
   18.11 +
   18.12 +#define szClassName "PCemMainWnd"
   18.13 +#define szSubClassName "PCemSubWnd"
   18.14 +
   18.15 +void leave_fullscreen();
   18.16 +
   18.17 +#ifdef __cplusplus
   18.18 +}
   18.19 +#endif