Enable window-resizing in the SDLTexture renderer
Previously, the window was a fixed size just like the original. This change highlights a weird issue in CSE2: this doesn't exactly match the behaviour of the original game, so why did I change it? Simple: monitors had much lower pixel-densities back in the early 2000s, meaning that 320x240 and 640x480 weren't as laughably small as they are today. I like to think of CSE2's portable branch as Cave Story's equivalent to Chocolate Doom: the point isn't to replicate the game's behaviour 100% - that's the accurate branch's job - no, the point of the portable branch is to replicate the *experience* of the game, as it was back in 2004. This means no commically-small windows. This is the same reason font anti-aliasing is disabled, even in versions of Windows later than XP. Sidenote: the OpenGL3/OpenGLES2 renderers already had this feature, but they used linear-filtering, causing the screen to be extremely blurry in 320x240 mode. This renderer uses a better method, which does apply slight blurring at the edges of pixels at resolutions that aren't an exact multiple of 320x240/640x480, but otherwise it resembles nearest-neighbour. This is way nicer to look at, and fits the game's aesthetic. This feature will be ported to the other renderers soon.
This commit is contained in:
parent
aa3cd55b43
commit
7bc028f5d8
1 changed files with 53 additions and 6 deletions
|
@ -12,6 +12,9 @@
|
|||
#include "../Misc.h"
|
||||
#include "../Shared/SDL2.h"
|
||||
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
typedef struct RenderBackend_Surface
|
||||
{
|
||||
SDL_Texture *texture;
|
||||
|
@ -34,6 +37,9 @@ SDL_Window *window;
|
|||
static SDL_Renderer *renderer;
|
||||
|
||||
static RenderBackend_Surface framebuffer;
|
||||
static RenderBackend_Surface upscaled_framebuffer;
|
||||
|
||||
static SDL_Rect upscaled_framebuffer_rect;
|
||||
|
||||
static RenderBackend_Surface *surface_list_head;
|
||||
|
||||
|
@ -64,7 +70,7 @@ RenderBackend_Surface* RenderBackend_Init(const char *window_title, size_t scree
|
|||
Backend_PrintInfo("%s", info.name);
|
||||
}
|
||||
|
||||
window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, screen_width, screen_height, 0);
|
||||
window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, screen_width, screen_height, SDL_WINDOW_RESIZABLE);
|
||||
|
||||
if (window != NULL)
|
||||
{
|
||||
|
@ -93,6 +99,8 @@ RenderBackend_Surface* RenderBackend_Init(const char *window_title, size_t scree
|
|||
framebuffer.width = screen_width;
|
||||
framebuffer.height = screen_height;
|
||||
|
||||
RenderBackend_HandleWindowResize(screen_width, screen_height);
|
||||
|
||||
Backend_PostWindowCreation();
|
||||
|
||||
return &framebuffer;
|
||||
|
@ -132,11 +140,22 @@ void RenderBackend_Deinit(void)
|
|||
|
||||
void RenderBackend_DrawScreen(void)
|
||||
{
|
||||
if (SDL_SetRenderTarget(renderer, upscaled_framebuffer.texture) < 0)
|
||||
Backend_PrintError("Couldn't set upscaled framebuffer as the current rendering target: %s", SDL_GetError());
|
||||
|
||||
if (SDL_RenderCopy(renderer, framebuffer.texture, NULL, NULL) < 0)
|
||||
Backend_PrintError("Failed to copy framebuffer texture to upscaled framebuffer: %s", SDL_GetError());
|
||||
|
||||
if (SDL_SetRenderTarget(renderer, NULL) < 0)
|
||||
Backend_PrintError("Couldn't set default render target as the current rendering target: %s", SDL_GetError());
|
||||
|
||||
if (SDL_RenderCopy(renderer, framebuffer.texture, NULL, NULL) < 0)
|
||||
Backend_PrintError("Failed to copy framebuffer texture to default render target: %s", SDL_GetError());
|
||||
if (SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xFF) < 0)
|
||||
Backend_PrintError("Couldn't set color for drawing operations: %s", SDL_GetError());
|
||||
|
||||
SDL_RenderClear(renderer);
|
||||
|
||||
if (SDL_RenderCopy(renderer, upscaled_framebuffer.texture, NULL, &upscaled_framebuffer_rect) < 0)
|
||||
Backend_PrintError("Failed to copy upscaled framebuffer texture to default render target: %s", SDL_GetError());
|
||||
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
@ -418,8 +437,36 @@ void RenderBackend_HandleRenderTargetLoss(void)
|
|||
|
||||
void RenderBackend_HandleWindowResize(size_t width, size_t height)
|
||||
{
|
||||
(void)width;
|
||||
(void)height;
|
||||
size_t upscale_factor = MAX(1, MIN((width + framebuffer.width / 2) / framebuffer.width, (height + framebuffer.height / 2) / framebuffer.height));
|
||||
|
||||
// No problem for us
|
||||
upscaled_framebuffer.width = framebuffer.width * upscale_factor;
|
||||
upscaled_framebuffer.height = framebuffer.height * upscale_factor;
|
||||
|
||||
if (upscaled_framebuffer.texture != NULL)
|
||||
SDL_DestroyTexture(upscaled_framebuffer.texture);
|
||||
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
|
||||
upscaled_framebuffer.texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_TARGET, upscaled_framebuffer.width, upscaled_framebuffer.height * upscale_factor);
|
||||
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "nearest");
|
||||
|
||||
if (upscaled_framebuffer.texture == NULL)
|
||||
Backend_PrintError("Couldn't regenerate upscaled framebuffer");
|
||||
|
||||
// Create rect that forces 4:3 no matter what size the window is
|
||||
float window_ratio = (float)width / height;
|
||||
float framebuffer_ratio = (float)upscaled_framebuffer.width / upscaled_framebuffer.height;
|
||||
|
||||
if (window_ratio >= framebuffer_ratio)
|
||||
{
|
||||
upscaled_framebuffer_rect.w = height * framebuffer_ratio;
|
||||
upscaled_framebuffer_rect.h = height;
|
||||
}
|
||||
else
|
||||
{
|
||||
upscaled_framebuffer_rect.w = width;
|
||||
upscaled_framebuffer_rect.h = width / framebuffer_ratio;
|
||||
}
|
||||
|
||||
upscaled_framebuffer_rect.x = (width - upscaled_framebuffer_rect.w) / 2;
|
||||
upscaled_framebuffer_rect.y = (height - upscaled_framebuffer_rect.h) / 2;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue