diff --git a/src/MiniFB_internal.c b/src/MiniFB_internal.c index c44623d..bc65b2b 100644 --- a/src/MiniFB_internal.c +++ b/src/MiniFB_internal.c @@ -4,6 +4,7 @@ //#define kUseBilinearInterpolation #if defined(kUseBilinearInterpolation) +//------------------------------------- static uint32_t interpolate(uint32_t *srcImage, uint32_t x, uint32_t y, uint32_t srcOffsetX, uint32_t srcOffsetY, uint32_t srcWidth, uint32_t srcHeight, uint32_t srcPitch) { uint32_t incX = x + 1 < srcWidth ? 1 : 0; @@ -39,6 +40,7 @@ interpolate(uint32_t *srcImage, uint32_t x, uint32_t y, uint32_t srcOffsetX, uin #endif // Only for 32 bits images +//------------------------------------- void stretch_image(uint32_t *srcImage, uint32_t srcX, uint32_t srcY, uint32_t srcWidth, uint32_t srcHeight, uint32_t srcPitch, uint32_t *dstImage, uint32_t dstX, uint32_t dstY, uint32_t dstWidth, uint32_t dstHeight, uint32_t dstPitch) { @@ -75,3 +77,28 @@ stretch_image(uint32_t *srcImage, uint32_t srcX, uint32_t srcY, uint32_t srcWidt dstImage += dstPitch; } } + +//------------------------------------- +void +calc_dst_factor(SWindowData *window_data, uint32_t width, uint32_t height) { + if (window_data->dst_width == 0) { + window_data->dst_width = width; + } + window_data->factor_x = (float) window_data->dst_offset_x / (float) width; + window_data->factor_width = (float) window_data->dst_width / (float) width; + + if (window_data->dst_height == 0) { + window_data->dst_height = height; + } + window_data->factor_y = (float) window_data->dst_offset_y / (float) height; + window_data->factor_height = (float) window_data->dst_height / (float) height; +} + +//------------------------------------- +void +resize_dst(SWindowData *window_data, uint32_t width, uint32_t height) { + window_data->dst_offset_x = width * window_data->factor_x; + window_data->dst_offset_y = height * window_data->factor_y; + window_data->dst_width = width * window_data->factor_width; + window_data->dst_height = height * window_data->factor_height; +} diff --git a/src/MiniFB_internal.h b/src/MiniFB_internal.h index c0c3192..b2d9185 100755 --- a/src/MiniFB_internal.h +++ b/src/MiniFB_internal.h @@ -1,7 +1,7 @@ #pragma once -#include "MiniFB.h" -#include "MiniFB_enums.h" +#include +#include "WindowData.h" #define kCall(func, ...) if(window_data && window_data->func) window_data->func((struct mfb_window *) window_data, __VA_ARGS__); #define kUnused(var) (void) var; @@ -12,14 +12,15 @@ typedef struct mfb_timer { uint64_t time; } mfb_timer; - #if defined(__cplusplus) extern "C" { #endif - extern short int g_keycodes[512]; void keyboard_default(struct mfb_window *window, mfb_key key, mfb_key_mod mod, bool isPressed); + void calc_dst_factor(SWindowData *window_data, uint32_t width, uint32_t height); + void resize_dst(SWindowData *window_data, uint32_t width, uint32_t height); + #if defined(__cplusplus) } #endif diff --git a/src/WindowData.h b/src/WindowData.h index 983086d..da2ee8c 100644 --- a/src/WindowData.h +++ b/src/WindowData.h @@ -4,6 +4,7 @@ #include #include +//------------------------------------- typedef struct { void *specific; void *user_data; @@ -23,6 +24,10 @@ typedef struct { uint32_t dst_offset_y; uint32_t dst_width; uint32_t dst_height; + float factor_x; + float factor_y; + float factor_width; + float factor_height; void *draw_buffer; uint32_t buffer_width; diff --git a/src/ios/iOSViewDelegate.m b/src/ios/iOSViewDelegate.m index cee6825..ff01a4f 100644 --- a/src/ios/iOSViewDelegate.m +++ b/src/ios/iOSViewDelegate.m @@ -243,6 +243,7 @@ NSString *g_shader_src = kShader( // Respond to drawable size or orientation changes here window_data->window_width = size.width; window_data->window_height = size.height; + resize_dst(window_data, size.width, size.height); kCall(resize_func, size.width, size.height); } diff --git a/src/macosx/MacMiniFB.m b/src/macosx/MacMiniFB.m index 105c485..2998027 100644 --- a/src/macosx/MacMiniFB.m +++ b/src/macosx/MacMiniFB.m @@ -249,14 +249,6 @@ mfb_update_ex(struct mfb_window *window, void *buffer, unsigned width, unsigned memcpy(window_data->draw_buffer, buffer, window_data->buffer_stride * window_data->buffer_height); #else if(window_data->buffer_width != width || window_data->buffer_height != height) { - float deltaX = (float) width / (float) window_data->buffer_width; - float deltaY = (float) height / (float) window_data->buffer_height; - - window_data->dst_offset_x *= deltaX; - window_data->dst_offset_y *= deltaY; - window_data->dst_width *= deltaX; - window_data->dst_height *= deltaY; - window_data->buffer_width = width; window_data->buffer_stride = width * 4; window_data->buffer_height = height; diff --git a/src/macosx/OSXWindow.m b/src/macosx/OSXWindow.m index d8c6ffd..b1eaf02 100644 --- a/src/macosx/OSXWindow.m +++ b/src/macosx/OSXWindow.m @@ -306,6 +306,7 @@ window_data->window_width = size.width; window_data->window_height = size.height; + resize_dst(window_data, size.width, size.height); kCall(resize_func, size.width, size.height); } diff --git a/src/wayland/WaylandMiniFB.c b/src/wayland/WaylandMiniFB.c index 1d038cb..7fa2eab 100644 --- a/src/wayland/WaylandMiniFB.c +++ b/src/wayland/WaylandMiniFB.c @@ -739,16 +739,18 @@ mfb_update_ex(struct mfb_window *window, void *buffer, unsigned width, unsigned window_data->buffer_height = height; window_data->buffer_stride = width * sizeof(uint32_t); - float deltaX = (float) width / (float) window_data->buffer_width; - float deltaY = (float) height / (float) window_data->buffer_height; + // This must be in the resize event but we don't have it for Wayland :( + resize_dst(window_data, width, height); + // float deltaX = (float) width / (float) window_data->buffer_width; + // float deltaY = (float) height / (float) window_data->buffer_height; - window_data->dst_offset_x *= deltaX; - window_data->dst_offset_y *= deltaY; - window_data->dst_width *= deltaX; - window_data->dst_height *= deltaY; + // window_data->dst_offset_x *= deltaX; + // window_data->dst_offset_y *= deltaY; + // window_data->dst_width *= deltaX; + // window_data->dst_height *= deltaY; wl_buffer_destroy(window_data->draw_buffer); - window_data->draw_buffer = wl_shm_pool_create_buffer(window_data_way->shm_pool, 0, + window_data->draw_buffer = wl_shm_pool_create_buffer(window_data_way->shm_pool, 0, window_data->buffer_width, window_data->buffer_height, window_data->buffer_stride, window_data_way->shm_format); } diff --git a/src/windows/WinMiniFB.c b/src/windows/WinMiniFB.c index be31151..00d5fd4 100644 --- a/src/windows/WinMiniFB.c +++ b/src/windows/WinMiniFB.c @@ -184,12 +184,9 @@ WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { case WM_SIZE: if (window_data) { - window_data->dst_offset_x = 0; - window_data->dst_offset_y = 0; - window_data->dst_width = LOWORD(lParam); - window_data->dst_height = HIWORD(lParam); - window_data->window_width = window_data->dst_width; - window_data->window_height = window_data->dst_height; + window_data->window_width = LOWORD(lParam); + window_data->window_height = HIWORD(lParam); + resize_dst(window_data, LOWORD(lParam), HIWORD(lParam)); BitBlt(window_data_win->hdc, 0, 0, window_data->window_width, window_data->window_height, 0, 0, 0, BLACKNESS); kCall(resize_func, window_data->dst_width, window_data->dst_height); } @@ -311,12 +308,8 @@ mfb_open_ex(const char *title, unsigned width, unsigned height, unsigned flags) window_data_win->wc.lpszClassName = title; RegisterClass(&window_data_win->wc); - if (window_data->dst_width == 0) - window_data->dst_width = width; - - if (window_data->dst_height == 0) - window_data->dst_height = height; - + calc_dst_factor(window_data, width, height); + window_data->window_width = rect.right; window_data->window_height = rect.bottom; @@ -692,7 +685,12 @@ translate_key(unsigned int wParam, unsigned long lParam) { bool mfb_set_viewport(struct mfb_window *window, unsigned offset_x, unsigned offset_y, unsigned width, unsigned height) { - SWindowData *window_data = (SWindowData *) window; + SWindowData *window_data = (SWindowData *) window; + SWindowData_Win *window_data_win = 0x0; + + if(window_data == 0x0) { + return false; + } if (offset_x + width > window_data->window_width) { return false; @@ -704,8 +702,13 @@ mfb_set_viewport(struct mfb_window *window, unsigned offset_x, unsigned offset_y window_data->dst_offset_x = offset_x; window_data->dst_offset_y = offset_y; - window_data->dst_width = width; - window_data->dst_height = height; + window_data->dst_width = width; + window_data->dst_height = height; + + calc_dst_factor(window_data, window_data->window_width, window_data->window_height); + + window_data_win = (SWindowData_Win *) window_data->specific; + BitBlt(window_data_win->hdc, 0, 0, window_data->window_width, window_data->window_height, 0, 0, 0, BLACKNESS); return true; } diff --git a/src/x11/X11MiniFB.c b/src/x11/X11MiniFB.c index df548c4..8e9ef25 100644 --- a/src/x11/X11MiniFB.c +++ b/src/x11/X11MiniFB.c @@ -262,10 +262,7 @@ processEvent(SWindowData *window_data, XEvent *event) { { window_data->window_width = event->xconfigure.width; window_data->window_height = event->xconfigure.height; - window_data->dst_offset_x = 0; - window_data->dst_offset_y = 0; - window_data->dst_width = window_data->window_width; - window_data->dst_height = window_data->window_height; + resize_dst(window_data, event->xconfigure.width, event->xconfigure.height); SWindowData_X11 *window_data_x11 = (SWindowData_X11 *) window_data->specific; if(window_data_x11->image_scaler != 0x0) { @@ -336,14 +333,6 @@ mfb_update_ex(struct mfb_window *window, void *buffer, unsigned width, unsigned SWindowData_X11 *window_data_x11 = (SWindowData_X11 *) window_data->specific; if(window_data->buffer_width != width || window_data->buffer_height != height) { - float deltaX = (float) width / (float) window_data->buffer_width; - float deltaY = (float) height / (float) window_data->buffer_height; - - window_data->dst_offset_x *= deltaX; - window_data->dst_offset_y *= deltaY; - window_data->dst_width *= deltaX; - window_data->dst_height *= deltaY; - window_data->buffer_width = width; window_data->buffer_stride = width * 4; window_data->buffer_height = height; diff --git a/tests/noise.c b/tests/noise.c index 4fba5a3..e25421a 100644 --- a/tests/noise.c +++ b/tests/noise.c @@ -30,6 +30,9 @@ main() g_buffer = (uint32_t *) malloc(g_width * g_height * 4); mfb_set_resize_callback(window, resize); + mfb_set_viewport(window, 50, 50, g_width - 50 - 50, g_height - 50 - 50); + resize(window, g_width - 100, g_height - 100); // to resize buffer + mfb_update_state state; do { for (i = 0; i < g_width * g_height; ++i) {