Skip to content

Commit

Permalink
Window resizing support
Browse files Browse the repository at this point in the history
  • Loading branch information
makuke1234 committed Jan 15, 2022
1 parent 0ca042c commit 940f66e
Show file tree
Hide file tree
Showing 8 changed files with 202 additions and 16 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# PongD2D

![Release version](https://img.shields.io/badge/release-v1.3.0-green.svg)
![Release version](https://img.shields.io/badge/release-v1.3.1-green.svg)
![C version](https://img.shields.io/badge/version-C20-blue.svg)
![C++ version](https://img.shields.io/badge/version-C++20-blue.svg)

Expand All @@ -26,6 +26,9 @@ Windows binaries can be downloaded [here](https://github.com/makuke1234/PongD2D/

# Changelog

* 1.3.1
* Add window resizing support

* 1.3.0
* Make scoring more engaging, points are given for whole game instead of the number
of bounces, game ends at 10 points
Expand Down
15 changes: 15 additions & 0 deletions src/d2dwrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,21 @@ D2D1_MATRIX_3X2_F dxD2D1Matrix3x2FIdentity()
return D2D1::Matrix3x2F::Identity();
}

D2D1_MATRIX_3X2_F dxD2D1Matrix3x2FScale(D2D1_SIZE_F size, D2D1_POINT_2F center)
{
return D2D1::Matrix3x2F::Scale(size, center);
}

D2D1_MATRIX_3X2_F dxD2D1Matrix3x2FTranslation(D2D1_SIZE_F size)
{
return D2D1::Matrix3x2F::Translation(size);
}

D2D1_MATRIX_3X2_F dxD2D1Matrix3x2FMultiply(D2D1_MATRIX_3X2_F m1, D2D1_MATRIX_3X2_F m2)
{
return m1 * m2;
}


void dxFactoryGetDesktopDpi(ID2D1Factory * This, FLOAT * dpiX, FLOAT * dpiY)
{
Expand Down
27 changes: 27 additions & 0 deletions src/d2dwrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,33 @@ D2D1_PIXEL_FORMAT dxD2D1PixelFormat(
*/
D2D1_MATRIX_3X2_F dxD2D1Matrix3x2FIdentity();

/**
* @brief Creates a scale transformation that has the specified scale factors
* and center point.
*
* @param size The x-axis and y-axis scale factors of the scale transformation
* @param center The point about which the scale is performed
* @return D2D1_MATIRX_3X2_F The new scale transformation
*/
D2D1_MATRIX_3X2_F dxD2D1Matrix3x2FScale(D2D1_SIZE_F size, D2D1_POINT_2F center);

/**
* @brief Creates a translation transformation that has the specified x and y displacements
*
* @param size The distance to translate from the x-axis and the y-axis
* @return D2D1_MATRIX_3X2_F The new translation transformation
*/
D2D1_MATRIX_3X2_F dxD2D1Matrix3x2FTranslation(D2D1_SIZE_F size);

/**
* @brief Multiplies 2 transformation matrixes
*
* @param m1 First operand
* @param m2 Second operand
* @return D2D1_MATRIX_3X2_F Transformation multiplication result
*/
D2D1_MATRIX_3X2_F dxD2D1Matrix3x2FMultiply(D2D1_MATRIX_3X2_F m1, D2D1_MATRIX_3X2_F m2);

/**
* @brief Get desktop DPI settings from D2D factory
*
Expand Down
4 changes: 2 additions & 2 deletions src/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@

#define PONG_WALL_MAX ((PONG_MINH - PONG_WALL_Y) / 2.0f)

#define VERSION_STR "1.3.0"
#define VERSION_SEQ 1,3,0
#define VERSION_STR "1.3.1"
#define VERSION_SEQ 1,3,1


#endif
15 changes: 15 additions & 0 deletions src/winapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,18 @@ LARGE_INTEGER w32_getTime()
return time;
}
}

bool w32_getScreenSize(HWND window, SIZE * pscreen)
{
HMONITOR monitor = MonitorFromWindow(window, MONITOR_DEFAULTTONEAREST);
MONITORINFO miw = { .cbSize = sizeof miw };
if (GetMonitorInfoW(monitor, &miw) == FALSE)
{
return false;
}

pscreen->cx = miw.rcMonitor.right - miw.rcMonitor.left;
pscreen->cy = miw.rcMonitor.bottom - miw.rcMonitor.top;

return true;
}
9 changes: 9 additions & 0 deletions src/winapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,14 @@ bool w32_regClass(
*/
LARGE_INTEGER w32_getTime();

/**
* @brief Get current monitor screen size in pixels, by window
*
* @param window Window handle
* @param pscreen Address to SIZE structure
* @return true On success
* @return false On failure
*/
bool w32_getScreenSize(HWND window, SIZE * pscreen);

#endif
121 changes: 109 additions & 12 deletions src/window.c
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ bool PongWnd_create(PongWnd_t * restrict pong, HINSTANCE hInst, PWSTR lpCmdArgs,
0,
PONG_CLASSNAME,
PONG_APPNAME,
WS_OVERLAPPEDWINDOW ^ (WS_MAXIMIZEBOX | WS_SIZEBOX),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
Expand Down Expand Up @@ -441,6 +441,72 @@ void PongWnd_calcDpiSpecific(PongWnd_t * restrict pong)
pong->minSize.cy = (LONG)PongWnd_dipy(pong, PONG_MINH) + pong->border.cy + 1;
}

void PongWnd_calcPositions(PongWnd_t * restrict pong)
{
FLOAT x = PongWnd_dipx(pong, PONG_MINW), y = PongWnd_dipy(pong, PONG_MINH);

float factX = (float)pong->size.cx / x;
float factY = (float)pong->size.cy / y;

pong->factor = factX < factY ? factX : factY;
pong->offsetX = PongWnd_dpix(pong, ((float)pong->size.cx - x * pong->factor) / 2.0f);
pong->offsetY = PongWnd_dpiy(pong, ((float)pong->size.cy - y * pong->factor) / 2.0f);
}

void PongWnd_toggleFullScreen(PongWnd_t * restrict pong)
{
// Toggle fullscreen flag
pong->isFullscreen ^= 1;

if (pong->isFullscreen)
{
pong->oldSize = (SIZE){
.cx = pong->size.cx,
.cy = pong->size.cy
};
RECT r;
GetWindowRect(pong->hwnd, &r);
pong->oldPos = (SIZE){
.cx = r.left,
.cy = r.top
};
pong->oldStyle = (DWORD)SetWindowLongPtrW(
pong->hwnd,
GWL_STYLE,
WS_SYSMENU | WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE
);

// Get screen size
SIZE screen;
w32_getScreenSize(pong->hwnd, &screen);
MoveWindow(pong->hwnd, 0, 0, screen.cx, screen.cy, TRUE);
}
else
{
RECT r = {
.left = 0,
.top = 0,
.right = pong->oldSize.cx,
.bottom = pong->oldSize.cy
};
SetWindowLongPtrW(
pong->hwnd,
GWL_STYLE,
pong->oldStyle
);
AdjustWindowRect(&r, pong->oldStyle, FALSE);
MoveWindow(
pong->hwnd,
pong->oldPos.cx,
pong->oldPos.cy,
r.right - r.left,
r.bottom - r.top,
TRUE
);
PongWnd_calcDpiSpecific(pong);
}
}

LRESULT CALLBACK PongWnd_winProcHub(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
PongWnd_t * self = NULL;
Expand Down Expand Up @@ -491,7 +557,7 @@ LRESULT PongWnd_winProc(PongWnd_t * pong, HWND hwnd, UINT msg, WPARAM wp, LPARAM
PongWnd_onSizing(pong, wp, lp);
break;
case WM_SIZE:
PongWnd_onSize(pong, lp);
PongWnd_onSize(pong);
break;
case WM_DPICHANGED:
PongWnd_onDpiChanged(pong, lp);
Expand Down Expand Up @@ -521,11 +587,31 @@ void PongWnd_onRender(PongWnd_t * restrict pong)
}

dxRTBeginDraw((ID2D1RenderTarget *)pong->dx.pRT);
dxRTSetTransform((ID2D1RenderTarget *)pong->dx.pRT, dxD2D1Matrix3x2FIdentity());

D2D1_MATRIX_3X2_F scale = dxD2D1Matrix3x2FScale(
(D2D1_SIZE_F){
.width = pong->factor,
.height = pong->factor
},
(D2D1_POINT_2F){
.x = 0.0f,
.y = 0.0f
}
);
D2D1_MATRIX_3X2_F translate = dxD2D1Matrix3x2FTranslation(
(D2D1_SIZE_F){
.width = pong->offsetX,
.height = pong->offsetY
}
);

dxRTSetTransform(
(ID2D1RenderTarget *)pong->dx.pRT,
dxD2D1Matrix3x2FMultiply(scale, translate)
);
// Draw black background
dxRTClear((ID2D1RenderTarget *)pong->dx.pRT, (D2D1_COLOR_F){ .r = 0.0f, .g = 0.0f, .b = 0.0f, .a = 1.0f });


// Draw line in the center
dxRTDrawLine(
(ID2D1RenderTarget *)pong->dx.pRT,
Expand Down Expand Up @@ -742,20 +828,24 @@ void PongWnd_onRender(PongWnd_t * restrict pong)
PongWnd_freeAssets(pong);
}
}
void PongWnd_onSize(PongWnd_t * restrict pong, LPARAM lp)
void PongWnd_onSize(PongWnd_t * restrict pong)
{
if (pong->dx.pRT == NULL)
{
return;
}
pong->size.cx = LOWORD(lp);
pong->size.cy = HIWORD(lp);
RECT r;
GetClientRect(pong->hwnd, &r);
pong->size.cx = r.right - r.left;
pong->size.cy = r.bottom - r.top;

dxHwndRTResize(pong->dx.pRT, (D2D1_SIZE_U){ .width = (UINT32)pong->size.cx, .height = (UINT32)pong->size.cy });

// Recreate assets
PongWnd_freeAssets(pong);
PongWnd_createAssets(pong);
dxHwndRTResize(
pong->dx.pRT, (D2D1_SIZE_U){
.width = (UINT32)pong->size.cx,
.height = (UINT32)pong->size.cy
}
);
PongWnd_calcPositions(pong);
}
void PongWnd_onSizing(PongWnd_t * restrict pong, WPARAM wp, LPARAM lp)
{
Expand Down Expand Up @@ -842,6 +932,13 @@ void PongWnd_onKeyPress(PongWnd_t * restrict pong, WPARAM wp, LPARAM lp)
PongLogic_reset(&pong->logic);
}
break;
case VK_F11:
// Act only if key was just pressed down, prevents spamming
if ((lp & 0x40000000) == 0)
{
PongWnd_toggleFullScreen(pong);
}
break;
}
}
void PongWnd_onKeyRelease(PongWnd_t * restrict pong, WPARAM wp, LPARAM lp)
Expand Down
22 changes: 21 additions & 1 deletion src/window.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,16 @@ typedef struct PongWnd
SIZE minSize, border;
SIZE size;

bool isFullscreen;
DWORD oldStyle;
SIZE oldSize, oldPos;
HWND hwnd;
LPWSTR wndTitle;

FLOAT dpiX, dpiY;

FLOAT factor, offsetX, offsetY;

DxBoilerPlate_t dx;

PongLogic_t logic;
Expand Down Expand Up @@ -139,6 +145,20 @@ FLOAT PongWnd_dpiy(const PongWnd_t * restrict pong, FLOAT y);
*/
void PongWnd_calcDpiSpecific(PongWnd_t * restrict pong);

/**
* @brief Calculates all size-correlated factors
*
* @param pong Pointer to PongWnd_t object
*/
void PongWnd_calcPositions(PongWnd_t * restrict pong);

/**
* @brief Toggle fullscreen
*
* @param pong Pointer to PongWnd_t object
*/
void PongWnd_toggleFullScreen(PongWnd_t * restrict pong);

/**
* @brief Win32 window procedure "hub" that deals with all incoming messages
* for all windows of one windows class
Expand All @@ -158,7 +178,7 @@ void PongWnd_onRender(PongWnd_t * restrict pong);
/**
* @brief Size sub-method, WM_SIZE msg
*/
void PongWnd_onSize(PongWnd_t * restrict pong, LPARAM lp);
void PongWnd_onSize(PongWnd_t * restrict pong);
/**
* @brief Active-resizing sub-method, WM_SIZING msg
*/
Expand Down

0 comments on commit 940f66e

Please sign in to comment.