Skip to content

Commit debe52c

Browse files
committed
Added scalable window, mouse controls.
1 parent 1c5256a commit debe52c

11 files changed

+200
-73
lines changed

SpaceCadetPinball/SpaceCadetPinball.rc

+4
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ BEGIN
9595
MENUITEM "&800 x 600", Menu1_800x600
9696
MENUITEM "&1024 x 768", Menu1_1024x768
9797
END
98+
POPUP "&Window"
99+
BEGIN
100+
MENUITEM "&Uniform Scaling", Menu1_WindowUniformScale
101+
END
98102
END
99103
POPUP "&Help"
100104
BEGIN

SpaceCadetPinball/fullscrn.cpp

+52-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include "pch.h"
22
#include "fullscrn.h"
33

4+
5+
#include "options.h"
46
#include "pb.h"
57
#include "render.h"
68
#include "winmain.h"
@@ -24,6 +26,10 @@ const resolution_info fullscrn::resolution_array[3] =
2426
{800, 600, 752, 520, 502},
2527
{1024, 768, 960, 666, 503},
2628
};
29+
float fullscrn::ScaleX = 1;
30+
float fullscrn::ScaleY = 1;
31+
float fullscrn::OffsetX = 0;
32+
float fullscrn::OffsetY = 0;
2733

2834
void fullscrn::init(int width, int height, int isFullscreen, HWND winHandle, HMENU menuHandle, int changeDisplay)
2935
{
@@ -46,15 +52,21 @@ void fullscrn::init(int width, int height, int isFullscreen, HWND winHandle, HME
4652
WindowRect2.right = (WindowRect1.right - WindowRect1.left - widht2) / 2 - 2 + widht2 + 4;
4753
WindowRect2.left = (WindowRect1.right - WindowRect1.left - widht2) / 2 - 2;
4854
WindowRect2.top = borderHeight / 2 - (captionHeight + menuHeight) - 2;
55+
56+
/*RECT client{0,0,width,height};
57+
AdjustWindowRect(&client, winmain::WndStyle, true);*/
4958
MoveWindow(
5059
hWnd,
5160
(WindowRect1.right - WindowRect1.left - widht2) / 2 - 2,
5261
WindowRect2.top,
53-
widht2 + 4 + 10,
62+
WindowRect2.right - WindowRect2.left + 10,
5463
WindowRect2.bottom - WindowRect2.top + 10,
5564
0);
5665
// Todo: WH + 10 hack: original request 640x480 window but somehow receives 650x490, even thought spyxx says it is 640x480
5766
fullscrn_flag1 = 0;
67+
68+
window_size_changed();
69+
assertm(ScaleX == 1 && ScaleY == 1, "Wrong default client size");
5870
}
5971

6072
void fullscrn::shutdown()
@@ -94,13 +106,13 @@ int fullscrn::set_screen_mode(int isFullscreen)
94106
int fullscrn::disableWindowFlagsDisDlg()
95107
{
96108
long style = GetWindowLongA(hWnd, -16);
97-
return SetWindowLongA(hWnd, -16, style & 0xFF3FFFFF);
109+
return SetWindowLongA(hWnd, -16, style & ~(WS_CAPTION | WS_THICKFRAME));
98110
}
99111

100112
int fullscrn::setWindowFlagsDisDlg()
101113
{
102114
int style = GetWindowLongA(hWnd, -16);
103-
return SetWindowLongA(hWnd, -16, style | 0xC00000);
115+
return SetWindowLongA(hWnd, -16, style | WS_CAPTION | WS_THICKFRAME);
104116
}
105117

106118
int fullscrn::enableFullscreen()
@@ -339,10 +351,12 @@ unsigned fullscrn::convert_mouse_pos(unsigned int mouseXY)
339351

340352
void fullscrn::getminmaxinfo(MINMAXINFO* maxMin)
341353
{
342-
maxMin->ptMaxSize.x = WindowRect2.right - WindowRect2.left;
343-
maxMin->ptMaxSize.y = WindowRect2.bottom - WindowRect2.top;
344-
maxMin->ptMaxPosition.x = WindowRect2.left;
345-
maxMin->ptMaxPosition.y = WindowRect2.top;
354+
/*Block down-scaling lower than min resolution*/
355+
maxMin->ptMinTrackSize = POINT
356+
{
357+
resolution_array[0].ScreenWidth / 2,
358+
resolution_array[0].ScreenHeight / 2
359+
};
346360
}
347361

348362
void fullscrn::paint()
@@ -419,3 +433,34 @@ int fullscrn::get_screen_resolution()
419433
auto height = static_cast<unsigned __int16>(GetSystemMetrics(SM_CYSCREEN));
420434
return static_cast<unsigned __int16>(GetSystemMetrics(SM_CXSCREEN)) | (height << 16);
421435
}
436+
437+
void fullscrn::window_size_changed()
438+
{
439+
/*No scaling in fullscreen mode*/
440+
if (display_changed)
441+
{
442+
ScaleY = ScaleX = 1;
443+
OffsetX = OffsetY = 0;
444+
return;
445+
}
446+
447+
RECT client{};
448+
GetClientRect(hWnd, &client);
449+
auto res = &resolution_array[resolution];
450+
ScaleX = static_cast<float>(client.right) / res->TableWidth;
451+
ScaleY = static_cast<float>(client.bottom) / res->TableHeight;
452+
OffsetX = OffsetY = 0;
453+
454+
if (options::Options.UniformScaling)
455+
{
456+
ScaleY = ScaleX = min(ScaleX, ScaleY);
457+
OffsetX = floor((client.right - res->TableWidth * ScaleX) / 2);
458+
OffsetY = floor((client.bottom - res->TableHeight * ScaleY) / 2);
459+
auto dc = GetDC(hWnd);
460+
if (dc)
461+
{
462+
BitBlt(dc, 0, 0, client.right, client.bottom, dc, 0, 0, BLACKNESS);
463+
ReleaseDC(hWnd, dc);
464+
}
465+
}
466+
}

SpaceCadetPinball/fullscrn.h

+5
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ class fullscrn
2828
static int ChangeDisplay, SmthFullScrnFlag2;
2929
static int trick;
3030
static const resolution_info resolution_array[3];
31+
static float ScaleX;
32+
static float ScaleY;
33+
static float OffsetX;
34+
static float OffsetY;
3135

3236
static void init(int width, int height, int isFullscreen, HWND winHandle, HMENU menuHandle, int changeDisplay);
3337
static void shutdown();
@@ -46,6 +50,7 @@ class fullscrn
4650
static void SetMaxResolution(int resolution);
4751
static int get_max_supported_resolution();
4852
static int get_screen_resolution();
53+
static void window_size_changed();
4954
private :
5055
static int MenuEnabled;
5156
static HMENU MenuHandle;

SpaceCadetPinball/gdrv.cpp

+61-17
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "pch.h"
22
#include "gdrv.h"
3+
4+
#include "fullscrn.h"
35
#include "memory.h"
46
#include "pinball.h"
57
#include "winmain.h"
@@ -252,19 +254,20 @@ int gdrv::destroy_bitmap(gdrv_bitmap8* bmp)
252254
return 0;
253255
}
254256

255-
UINT gdrv::start_blit_sequence()
257+
void gdrv::start_blit_sequence()
256258
{
257259
HDC dc = winmain::_GetDC(hwnd);
258260
sequence_handle = 0;
259261
sequence_hdc = dc;
260262
SelectPalette(dc, palette_handle, 0);
261-
return RealizePalette(sequence_hdc);
263+
RealizePalette(sequence_hdc);
264+
SetStretchBltMode(dc, stretchMode);
262265
}
263266

264267
void gdrv::blit_sequence(gdrv_bitmap8* bmp, int xSrc, int ySrcOff, int xDest, int yDest, int DestWidth, int DestHeight)
265268
{
266269
if (!use_wing)
267-
StretchDIBits(
270+
StretchDIBitsScaled(
268271
sequence_hdc,
269272
xDest,
270273
yDest,
@@ -274,10 +277,10 @@ void gdrv::blit_sequence(gdrv_bitmap8* bmp, int xSrc, int ySrcOff, int xDest, in
274277
bmp->Height - ySrcOff - DestHeight,
275278
DestWidth,
276279
DestHeight,
277-
bmp->BmpBufPtr1,
278-
bmp->Dib,
279-
1u,
280-
SRCCOPY);
280+
bmp,
281+
DIB_PAL_COLORS,
282+
SRCCOPY
283+
);
281284
}
282285

283286

@@ -289,12 +292,13 @@ void gdrv::end_blit_sequence()
289292
void gdrv::blit(gdrv_bitmap8* bmp, int xSrc, int ySrcOff, int xDest, int yDest, int DestWidth, int DestHeight)
290293
{
291294
HDC dc = winmain::_GetDC(hwnd);
295+
SetStretchBltMode(dc, stretchMode);
292296
if (dc)
293297
{
294298
SelectPalette(dc, palette_handle, 0);
295299
RealizePalette(dc);
296300
if (!use_wing)
297-
StretchDIBits(
301+
StretchDIBitsScaled(
298302
dc,
299303
xDest,
300304
yDest,
@@ -304,10 +308,10 @@ void gdrv::blit(gdrv_bitmap8* bmp, int xSrc, int ySrcOff, int xDest, int yDest,
304308
bmp->Height - ySrcOff - DestHeight,
305309
DestWidth,
306310
DestHeight,
307-
bmp->BmpBufPtr1,
308-
bmp->Dib,
309-
1u,
310-
SRCCOPY);
311+
bmp,
312+
DIB_PAL_COLORS,
313+
SRCCOPY
314+
);
311315
ReleaseDC(hwnd, dc);
312316
}
313317
}
@@ -317,8 +321,9 @@ void gdrv::blat(gdrv_bitmap8* bmp, int xDest, int yDest)
317321
HDC dc = winmain::_GetDC(hwnd);
318322
SelectPalette(dc, palette_handle, 0);
319323
RealizePalette(dc);
324+
SetStretchBltMode(dc, stretchMode);
320325
if (!use_wing)
321-
StretchDIBits(
326+
StretchDIBitsScaled(
322327
dc,
323328
xDest,
324329
yDest,
@@ -328,10 +333,10 @@ void gdrv::blat(gdrv_bitmap8* bmp, int xDest, int yDest)
328333
0,
329334
bmp->Width,
330335
bmp->Height,
331-
bmp->BmpBufPtr1,
332-
bmp->Dib,
333-
1u,
334-
SRCCOPY);
336+
bmp,
337+
DIB_PAL_COLORS,
338+
SRCCOPY
339+
);
335340
ReleaseDC(hwnd, dc);
336341
}
337342

@@ -416,3 +421,42 @@ void gdrv::grtext_draw_ttext_in_box(LPCSTR text, int xOff, int yOff, int width,
416421
SetTextColor(dc, color);
417422
ReleaseDC(hwnd, dc);
418423
}
424+
425+
int gdrv::StretchDIBitsScaled(HDC hdc, int xDest, int yDest, int DestWidth, int DestHeight, int xSrc, int ySrc,
426+
int SrcWidth, int SrcHeight, gdrv_bitmap8* bmp, UINT iUsage,
427+
DWORD rop)
428+
{
429+
/*Scaled partial updates may leave 1px border artifacts around update area.
430+
* Pad update area to compensate.*/
431+
const int pad = 1, padX2 = pad * 2;
432+
if (fullscrn::ScaleX > 1 && xSrc > pad && xSrc + pad < bmp->Width)
433+
{
434+
xSrc -= pad;
435+
xDest -= pad;
436+
SrcWidth += padX2;
437+
DestWidth += padX2;
438+
}
439+
440+
if (fullscrn::ScaleY > 1 && ySrc > pad && ySrc + pad < bmp->Height)
441+
{
442+
ySrc -= pad;
443+
yDest -= pad;
444+
SrcHeight += padX2;
445+
DestHeight += padX2;
446+
}
447+
448+
return StretchDIBits(
449+
hdc,
450+
static_cast<int>(round(xDest * fullscrn::ScaleX + fullscrn::OffsetX)),
451+
static_cast<int>(round(yDest * fullscrn::ScaleY + fullscrn::OffsetY)),
452+
static_cast<int>(round(DestWidth * fullscrn::ScaleX)),
453+
static_cast<int>(round(DestHeight * fullscrn::ScaleY)),
454+
xSrc,
455+
ySrc,
456+
SrcWidth,
457+
SrcHeight,
458+
bmp->BmpBufPtr1,
459+
bmp->Dib,
460+
iUsage,
461+
rop);
462+
}

SpaceCadetPinball/gdrv.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class gdrv
5353
static int create_spliced_bitmap(gdrv_bitmap8* bmp, int width, int height, int size);
5454
static int destroy_bitmap(gdrv_bitmap8* bmp);
5555
static int display_palette(PALETTEENTRY* plt);
56-
static UINT start_blit_sequence();
56+
static void start_blit_sequence();
5757
static void blit_sequence(gdrv_bitmap8* bmp, int xSrc, int ySrcOff, int xDest, int yDest, int DestWidth,
5858
int DestHeight);
5959
static void end_blit_sequence();
@@ -66,9 +66,15 @@ class gdrv
6666
gdrv_bitmap8* srcBmp, int srcXOff, int srcYOff);
6767
static void grtext_draw_ttext_in_box(LPCSTR text, int xOff, int yOff, int width, int height, int a6);
6868
private:
69+
/*COLORONCOLOR or HALFTONE*/
70+
static const int stretchMode = COLORONCOLOR;
6971
static HWND hwnd;
7072
static HINSTANCE hinst;
7173
static int grtext_blue;
7274
static int grtext_green;
7375
static int grtext_red;
76+
77+
static int StretchDIBitsScaled(HDC hdc, int xDest, int yDest, int DestWidth, int DestHeight, int xSrc, int ySrc,
78+
int SrcWidth, int SrcHeight, gdrv_bitmap8* bmp, UINT iUsage,
79+
DWORD rop);
7480
};

SpaceCadetPinball/options.cpp

+13-5
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
LPCSTR options::OptionsRegPath;
1313
LPSTR options::OptionsRegPathCur;
1414
HMENU options::MenuHandle;
15-
optionsStruct options::Options;
15+
optionsStruct options::Options{};
1616

1717
winhelp_entry options::keymap_help[18]
1818
{
@@ -107,6 +107,7 @@ void options::init(HMENU menuHandle)
107107
Options.LeftTableBumpKey = get_int(nullptr, "Left Table Bump key", Options.LeftTableBumpKey);
108108
Options.RightTableBumpKey = get_int(nullptr, "Right Table Bump key", Options.RightTableBumpKey);
109109
Options.BottomTableBumpKey = get_int(nullptr, "Bottom Table Bump key", Options.BottomTableBumpKey);
110+
Options.UniformScaling = get_int(nullptr, "Uniform scaling", true);
110111
menu_check(Menu1_Sounds, Options.Sounds);
111112
Sound::Enable(0, 7, Options.Sounds);
112113
menu_check(Menu1_Music, Options.Music);
@@ -115,6 +116,7 @@ void options::init(HMENU menuHandle)
115116
menu_check(Menu1_2Players, Options.Players == 2);
116117
menu_check(Menu1_3Players, Options.Players == 3);
117118
menu_check(Menu1_4Players, Options.Players == 4);
119+
menu_check(Menu1_WindowUniformScale, Options.UniformScaling);
118120
auto tmpBuf = memory::allocate(0x1F4u);
119121
if (tmpBuf)
120122
{
@@ -146,6 +148,7 @@ void options::uninit()
146148
set_int(nullptr, "Right Table Bump key", Options.RightTableBumpKey);
147149
set_int(nullptr, "Bottom Table Bump key", Options.BottomTableBumpKey);
148150
set_int(nullptr, "Screen Resolution", Options.Resolution);
151+
set_int(nullptr, "Uniform scaling", Options.UniformScaling);
149152
}
150153

151154
void options::path_init(LPCSTR regPath)
@@ -315,10 +318,9 @@ void options::toggle(UINT uIDCheckItem)
315318
case Menu1_800x600:
316319
case Menu1_1024x768:
317320
{
318-
menu_check(500u, uIDCheckItem == 500);
319-
menu_check(501u, uIDCheckItem == 501);
320-
menu_check(502u, uIDCheckItem == 502);
321-
menu_check(503u, uIDCheckItem == 503);
321+
for (unsigned i = Menu1_MaximumResolution; i <= Menu1_1024x768; ++i)
322+
menu_check(i, i == uIDCheckItem);
323+
322324
int newResolution = uIDCheckItem - Menu1_640x480;
323325
if (uIDCheckItem == Menu1_MaximumResolution)
324326
{
@@ -333,6 +335,12 @@ void options::toggle(UINT uIDCheckItem)
333335
}
334336
break;
335337
}
338+
case Menu1_WindowUniformScale:
339+
Options.UniformScaling ^= true;
340+
menu_check(Menu1_WindowUniformScale, Options.UniformScaling);
341+
fullscrn::window_size_changed();
342+
fullscrn::paint();
343+
break;
336344
default:
337345
break;
338346
}

SpaceCadetPinball/options.h

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ struct optionsStruct
2222
int RightTableBumpKeyDft;
2323
int BottomTableBumpKeyDft;
2424
int Resolution;
25+
bool UniformScaling;
2526
};
2627

2728

0 commit comments

Comments
 (0)