2020-01-01 21:29:24 +01:00
|
|
|
#include "Screen.h"
|
|
|
|
|
2021-02-27 19:44:01 +01:00
|
|
|
#include <SDL.h>
|
2020-07-19 21:43:29 +02:00
|
|
|
|
2020-01-01 21:29:24 +01:00
|
|
|
#include "FileSystemUtils.h"
|
2021-04-23 01:19:20 +02:00
|
|
|
#include "Game.h"
|
2020-01-01 21:29:24 +01:00
|
|
|
#include "GraphicsUtil.h"
|
2021-02-24 00:21:29 +01:00
|
|
|
#include "Vlogging.h"
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
// Used to create the window icon
|
|
|
|
extern "C"
|
|
|
|
{
|
|
|
|
extern unsigned lodepng_decode24(
|
|
|
|
unsigned char** out,
|
|
|
|
unsigned* w,
|
|
|
|
unsigned* h,
|
|
|
|
const unsigned char* in,
|
|
|
|
size_t insize
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
ScreenSettings::ScreenSettings(void)
|
2020-11-13 01:29:11 +01:00
|
|
|
{
|
|
|
|
windowWidth = 320;
|
|
|
|
windowHeight = 240;
|
|
|
|
fullscreen = false;
|
2021-08-31 21:08:46 +02:00
|
|
|
useVsync = true; // Now that uncapped is the default...
|
2020-11-13 01:29:11 +01:00
|
|
|
stretch = 0;
|
|
|
|
linearFilter = false;
|
|
|
|
badSignal = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Screen::init(const ScreenSettings& settings)
|
|
|
|
{
|
2020-04-02 22:28:12 +02:00
|
|
|
m_window = NULL;
|
|
|
|
m_renderer = NULL;
|
|
|
|
m_screenTexture = NULL;
|
|
|
|
m_screen = NULL;
|
2020-11-13 01:29:11 +01:00
|
|
|
isWindowed = !settings.fullscreen;
|
|
|
|
stretchMode = settings.stretch;
|
|
|
|
isFiltered = settings.linearFilter;
|
|
|
|
vsync = settings.useVsync;
|
2020-04-02 22:28:12 +02:00
|
|
|
filterSubrect.x = 1;
|
|
|
|
filterSubrect.y = 1;
|
|
|
|
filterSubrect.w = 318;
|
|
|
|
filterSubrect.h = 238;
|
2020-07-09 03:42:57 +02:00
|
|
|
|
|
|
|
SDL_SetHintWithPriority(
|
|
|
|
SDL_HINT_RENDER_SCALE_QUALITY,
|
|
|
|
isFiltered ? "linear" : "nearest",
|
|
|
|
SDL_HINT_OVERRIDE
|
|
|
|
);
|
|
|
|
SDL_SetHintWithPriority(
|
|
|
|
SDL_HINT_RENDER_VSYNC,
|
|
|
|
vsync ? "1" : "0",
|
|
|
|
SDL_HINT_OVERRIDE
|
|
|
|
);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
// Uncomment this next line when you need to debug -flibit
|
|
|
|
// SDL_SetHintWithPriority(SDL_HINT_RENDER_DRIVER, "software", SDL_HINT_OVERRIDE);
|
2021-02-16 02:47:48 +01:00
|
|
|
// FIXME: m_renderer is also created in resetRendererWorkaround()!
|
2020-01-01 21:29:24 +01:00
|
|
|
SDL_CreateWindowAndRenderer(
|
|
|
|
640,
|
|
|
|
480,
|
2021-01-01 02:55:57 +01:00
|
|
|
SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI,
|
2020-01-01 21:29:24 +01:00
|
|
|
&m_window,
|
|
|
|
&m_renderer
|
|
|
|
);
|
|
|
|
SDL_SetWindowTitle(m_window, "VVVVVV");
|
|
|
|
|
2020-11-01 04:25:27 +01:00
|
|
|
LoadIcon();
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
// FIXME: This surface should be the actual backbuffer! -flibit
|
|
|
|
m_screen = SDL_CreateRGBSurface(
|
|
|
|
0,
|
|
|
|
320,
|
|
|
|
240,
|
|
|
|
32,
|
|
|
|
0x00FF0000,
|
|
|
|
0x0000FF00,
|
|
|
|
0x000000FF,
|
|
|
|
0xFF000000
|
|
|
|
);
|
2021-02-16 02:47:48 +01:00
|
|
|
// ALSO FIXME: This SDL_CreateTexture() is duplicated twice in this file!
|
2020-01-01 21:29:24 +01:00
|
|
|
m_screenTexture = SDL_CreateTexture(
|
|
|
|
m_renderer,
|
|
|
|
SDL_PIXELFORMAT_ARGB8888,
|
|
|
|
SDL_TEXTUREACCESS_STREAMING,
|
|
|
|
320,
|
|
|
|
240
|
|
|
|
);
|
|
|
|
|
2020-11-13 01:29:11 +01:00
|
|
|
badSignalEffect = settings.badSignal;
|
2020-07-08 20:30:57 +02:00
|
|
|
|
2020-11-13 01:29:11 +01:00
|
|
|
ResizeScreen(settings.windowWidth, settings.windowHeight);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void Screen::destroy(void)
|
2021-02-16 02:47:11 +01:00
|
|
|
{
|
|
|
|
#define X(CLEANUP, POINTER) \
|
|
|
|
CLEANUP(POINTER); \
|
|
|
|
POINTER = NULL;
|
|
|
|
|
|
|
|
/* Order matters! */
|
|
|
|
X(SDL_DestroyTexture, m_screenTexture);
|
|
|
|
X(SDL_FreeSurface, m_screen);
|
|
|
|
X(SDL_DestroyRenderer, m_renderer);
|
|
|
|
X(SDL_DestroyWindow, m_window);
|
|
|
|
|
|
|
|
#undef X
|
|
|
|
}
|
|
|
|
|
2020-12-22 01:34:16 +01:00
|
|
|
void Screen::GetSettings(ScreenSettings* settings)
|
|
|
|
{
|
|
|
|
int width, height;
|
|
|
|
GetWindowSize(&width, &height);
|
|
|
|
|
|
|
|
settings->windowWidth = width;
|
|
|
|
settings->windowHeight = height;
|
|
|
|
|
|
|
|
settings->fullscreen = !isWindowed;
|
|
|
|
settings->useVsync = vsync;
|
|
|
|
settings->stretch = stretchMode;
|
|
|
|
settings->linearFilter = isFiltered;
|
|
|
|
settings->badSignal = badSignalEffect;
|
|
|
|
}
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void Screen::LoadIcon(void)
|
2020-11-01 04:25:27 +01:00
|
|
|
{
|
2021-03-31 08:50:38 +02:00
|
|
|
#ifndef __APPLE__
|
Transfer param init responsibility to loadFileToMemory
So, the codebase was kind of undecided about who is responsible for
initializing the parameters passed to FILESYSTEM_loadFileToMemory() - is
it the caller? Is it FILESYSTEM_loadFileToMemory()? Sometimes callers
would initialize one variable but not the other, and it was always a
toss-up whether or not FILESYSTEM_loadFileToMemory() would end up
initializing everything in the end.
All of this is to say that the game dereferences an uninitialized
pointer if it can't load a sound effect. Which is bad. Now, I could
either fix that single case, or fix every case. Judging by the title of
this commit, you can infer that I decided to fix every case - fixing
every case means not just all cases that currently exist (which, as far
as I know, is only the sound effect one), but all cases that could exist
in the future.
So, FILESYSTEM_loadFileToMemory() is now guaranteed to initialize its
parameters even if the file fails to be loaded. This is better than
passing the responsibility to the caller anyway, because if the caller
initialized it, then that would be wasted work if the file succeeds
anyway because FILESYSTEM_loadFileToMemory() will overwrite it, and if
the file fails to load, well that's when the variables get initialized
anyway.
2021-04-18 19:35:36 +02:00
|
|
|
unsigned char *fileIn;
|
|
|
|
size_t length;
|
2020-11-01 04:25:27 +01:00
|
|
|
unsigned char *data;
|
|
|
|
unsigned int width, height;
|
2021-04-05 09:54:32 +02:00
|
|
|
FILESYSTEM_loadAssetToMemory("VVVVVV.png", &fileIn, &length, false);
|
2020-11-01 04:25:27 +01:00
|
|
|
lodepng_decode24(&data, &width, &height, fileIn, length);
|
|
|
|
FILESYSTEM_freeMemory(&fileIn);
|
|
|
|
SDL_Surface *icon = SDL_CreateRGBSurfaceFrom(
|
|
|
|
data,
|
|
|
|
width,
|
|
|
|
height,
|
|
|
|
24,
|
|
|
|
width * 3,
|
|
|
|
0x000000FF,
|
|
|
|
0x0000FF00,
|
|
|
|
0x00FF0000,
|
|
|
|
0x00000000
|
|
|
|
);
|
|
|
|
SDL_SetWindowIcon(m_window, icon);
|
|
|
|
SDL_FreeSurface(icon);
|
Reduce dependency on libc functions
During 2.3 development, there's been a gradual shift to using SDL stdlib
functions instead of libc functions, but there are still some libc
functions (or the same libc function but from the STL) in the code.
Well, this patch replaces all the rest of them in one fell swoop.
SDL's stdlib can replace most of these, but its SDL_min() and SDL_max()
are inadequate - they aren't really functions, they're more like macros
with a nasty penchant for double-evaluation. So I just made my own
VVV_min() and VVV_max() functions and placed them in Maths.h instead,
then replaced all the previous usages of min(), max(), std::min(),
std::max(), SDL_min(), and SDL_max() with VVV_min() and VVV_max().
Additionally, there's no SDL_isxdigit(), so I just implemented my own
VVV_isxdigit().
SDL has SDL_malloc() and SDL_free(), but they have some refcounting
built in to them, so in order to use them with LodePNG, I have to
replace the malloc() and free() that LodePNG uses. Which isn't too hard,
I did it in a new file called ThirdPartyDeps.c, and LodePNG is now
compiled with the LODEPNG_NO_COMPILE_ALLOCATORS definition.
Lastly, I also refactored the awful strcpy() and strcat() usages in
PLATFORM_migrateSaveData() to use SDL_snprintf() instead. I know save
migration is getting axed in 2.4, but it still bothers me to have
something like that in the codebase otherwise.
Without further ado, here is the full list of functions that the
codebase now uses:
- SDL_strlcpy() instead of strcpy()
- SDL_strlcat() instead of strcat()
- SDL_snprintf() instead of sprintf(), strcpy(), or strcat() (see above)
- VVV_min() instead of min(), std::min(), or SDL_min()
- VVV_max() instead of max(), std::max(), or SDL_max()
- VVV_isxdigit() instead of isxdigit()
- SDL_strcmp() instead of strcmp()
- SDL_strcasecmp() instead of strcasecmp() or Win32 strcmpi()
- SDL_strstr() instead of strstr()
- SDL_strlen() instead of strlen()
- SDL_sscanf() instead of sscanf()
- SDL_getenv() instead of getenv()
- SDL_malloc() instead of malloc() (replacing in LodePNG as well)
- SDL_free() instead of free() (replacing in LodePNG as well)
2021-01-12 01:17:45 +01:00
|
|
|
SDL_free(data);
|
2021-03-31 08:50:38 +02:00
|
|
|
#endif /* __APPLE__ */
|
2020-11-01 04:25:27 +01:00
|
|
|
}
|
|
|
|
|
2020-03-13 23:22:37 +01:00
|
|
|
void Screen::ResizeScreen(int x, int y)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
static int resX = 320;
|
|
|
|
static int resY = 240;
|
|
|
|
if (x != -1 && y != -1)
|
|
|
|
{
|
|
|
|
// This is a user resize!
|
|
|
|
resX = x;
|
|
|
|
resY = y;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!isWindowed)
|
|
|
|
{
|
2020-03-13 23:22:37 +01:00
|
|
|
int result = SDL_SetWindowFullscreen(m_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
|
|
|
if (result != 0)
|
|
|
|
{
|
2021-02-24 00:21:29 +01:00
|
|
|
vlog_error("Error: could not set the game to fullscreen mode: %s", SDL_GetError());
|
2020-03-13 23:22:37 +01:00
|
|
|
return;
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-03-13 23:22:37 +01:00
|
|
|
int result = SDL_SetWindowFullscreen(m_window, 0);
|
|
|
|
if (result != 0)
|
|
|
|
{
|
2021-02-24 00:21:29 +01:00
|
|
|
vlog_error("Error: could not set the game to windowed mode: %s", SDL_GetError());
|
2020-03-13 23:22:37 +01:00
|
|
|
return;
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
if (x != -1 && y != -1)
|
|
|
|
{
|
|
|
|
SDL_SetWindowSize(m_window, resX, resY);
|
|
|
|
SDL_SetWindowPosition(m_window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (stretchMode == 1)
|
|
|
|
{
|
|
|
|
int winX, winY;
|
2021-01-01 03:12:30 +01:00
|
|
|
GetWindowSize(&winX, &winY);
|
2020-03-13 23:22:37 +01:00
|
|
|
int result = SDL_RenderSetLogicalSize(m_renderer, winX, winY);
|
|
|
|
if (result != 0)
|
|
|
|
{
|
2021-02-24 00:21:29 +01:00
|
|
|
vlog_error("Error: could not set logical size: %s", SDL_GetError());
|
2020-03-13 23:22:37 +01:00
|
|
|
return;
|
|
|
|
}
|
Don't print useless false error message when toggling fullscreen
Whenever you would press Alt+Enter, or Alt+F, or on macOS Command+Enter,
or on macOS Command+F, or F11, the game would print this useless error
message to console, every single time: "Error: failed: " and it would
concatenate SDL_GetError() after it, but most of the time SDL_GetError()
is blank, so it would print just that.
Instead, what the fullscreen shortcut will now do is check the result of
the relevant SDL functions, BEFORE it decides to print an error message.
And when it DOES print an error message, it will be less vague and will
say instead "Error: toggling fullscreen failed: <output of
SDL_GetError()>".
This means Screen::ResizeScreen() and Screen::toggleFullScreen() are now
int-returning functions. Ideally, every function interfacing with SDL
would return an error code, but that's too much for this simple patch.
Additionally, I took the opportunity to clean up the surrounding
formatting of the code a bit, most notably dedenting the
keypress-clearing stuff by one tab level, converting the
shortcut-handling code to spaces, and removing commented-out code.
2020-03-13 08:23:48 +01:00
|
|
|
result = SDL_RenderSetIntegerScale(m_renderer, SDL_FALSE);
|
2020-03-13 23:22:37 +01:00
|
|
|
if (result != 0)
|
|
|
|
{
|
2021-02-24 00:21:29 +01:00
|
|
|
vlog_error("Error: could not set scale: %s", SDL_GetError());
|
2020-03-13 23:22:37 +01:00
|
|
|
return;
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SDL_RenderSetLogicalSize(m_renderer, 320, 240);
|
2020-03-13 23:22:37 +01:00
|
|
|
int result = SDL_RenderSetIntegerScale(m_renderer, (SDL_bool) (stretchMode == 2));
|
|
|
|
if (result != 0)
|
|
|
|
{
|
2021-02-24 00:21:29 +01:00
|
|
|
vlog_error("Error: could not set scale: %s", SDL_GetError());
|
2020-03-13 23:22:37 +01:00
|
|
|
return;
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
SDL_ShowWindow(m_window);
|
|
|
|
}
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void Screen::ResizeToNearestMultiple(void)
|
Add "resize to nearest" graphics option
If you want your game window to simply be exactly 320x240, or 640x480,
or 960x720 etc. then it's really annoying that there's no easy way to do
this (to clarify, this is different from integer mode, which controls
the size of the game INSIDE the window). The easiest way would be having
to close the game, go into unlock.vvv, and edit the window size
manually. VCE has a 1x/2x/3x/4x graphics option to solve this, although
it does not account for actual monitor size (those 1x/2x/3x/4x modes are
all you get, whether or not you have a monitor too small for some of
them or too big for any of them to be what you want).
I discussed this with flibit, and he said that VCE's approach (if it
accounted for monitor size) wouldn't work on high-retina displays or
high DPIs, because getting the actual multiplier to account for those
monitors is kind of a pain. So the next best thing would be to add an
option that resizes to the nearest perfect multiple of 320x240. That way
you could simply resize the window and let the game correct any
imperfect dimensions automatically.
2020-06-30 07:02:21 +02:00
|
|
|
{
|
|
|
|
int w, h;
|
|
|
|
GetWindowSize(&w, &h);
|
|
|
|
|
|
|
|
// Check aspect ratio first
|
|
|
|
bool using_width;
|
|
|
|
int usethisdimension, usethisratio;
|
|
|
|
|
|
|
|
if ((float) w / (float) h > 4.0 / 3.0)
|
|
|
|
{
|
|
|
|
// Width is bigger, so it's limited by height
|
|
|
|
usethisdimension = h;
|
|
|
|
usethisratio = 240;
|
|
|
|
using_width = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Height is bigger, so it's limited by width. Or we're exactly 4:3 already
|
|
|
|
usethisdimension = w;
|
|
|
|
usethisratio = 320;
|
|
|
|
using_width = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
int floor = (usethisdimension / usethisratio) * usethisratio;
|
|
|
|
int ceiling = floor + usethisratio;
|
|
|
|
|
|
|
|
int final_dimension;
|
|
|
|
|
|
|
|
if (usethisdimension - floor < ceiling - usethisdimension)
|
|
|
|
{
|
|
|
|
// Floor is nearest
|
|
|
|
final_dimension = floor;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Ceiling is nearest. Or we're exactly on a multiple already
|
|
|
|
final_dimension = ceiling;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (final_dimension == 0)
|
|
|
|
{
|
|
|
|
// We're way too small!
|
|
|
|
ResizeScreen(320, 240);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (using_width)
|
|
|
|
{
|
|
|
|
ResizeScreen(final_dimension, final_dimension / 4 * 3);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ResizeScreen(final_dimension * 4 / 3, final_dimension);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-01 21:29:24 +01:00
|
|
|
void Screen::GetWindowSize(int* x, int* y)
|
|
|
|
{
|
2021-01-01 03:00:20 +01:00
|
|
|
SDL_GetRendererOutputSize(m_renderer, x, y);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void Screen::UpdateScreen(SDL_Surface* buffer, SDL_Rect* rect )
|
|
|
|
{
|
2020-04-02 22:28:12 +02:00
|
|
|
if((buffer == NULL) && (m_screen == NULL) )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2020-04-02 22:28:12 +02:00
|
|
|
if(badSignalEffect)
|
|
|
|
{
|
|
|
|
buffer = ApplyFilter(buffer);
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
|
2021-02-26 00:37:03 +01:00
|
|
|
ClearSurface(m_screen);
|
2020-04-02 22:28:12 +02:00
|
|
|
BlitSurfaceStandard(buffer,NULL,m_screen,rect);
|
2020-01-01 21:29:24 +01:00
|
|
|
|
2020-04-02 22:28:12 +02:00
|
|
|
if(badSignalEffect)
|
|
|
|
{
|
|
|
|
SDL_FreeSurface(buffer);
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
const SDL_PixelFormat* Screen::GetFormat(void)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
2020-04-02 22:28:12 +02:00
|
|
|
return m_screen->format;
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void Screen::FlipScreen(void)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
SDL_UpdateTexture(
|
|
|
|
m_screenTexture,
|
|
|
|
NULL,
|
|
|
|
m_screen->pixels,
|
|
|
|
m_screen->pitch
|
|
|
|
);
|
|
|
|
SDL_RenderCopy(
|
|
|
|
m_renderer,
|
|
|
|
m_screenTexture,
|
|
|
|
isFiltered ? &filterSubrect : NULL,
|
|
|
|
NULL
|
|
|
|
);
|
|
|
|
SDL_RenderPresent(m_renderer);
|
|
|
|
SDL_RenderClear(m_renderer);
|
2021-02-26 00:37:03 +01:00
|
|
|
ClearSurface(m_screen);
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void Screen::toggleFullScreen(void)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
isWindowed = !isWindowed;
|
2020-03-13 23:22:37 +01:00
|
|
|
ResizeScreen(-1, -1);
|
2021-04-23 01:19:20 +02:00
|
|
|
|
|
|
|
if (game.currentmenuname == Menu::graphicoptions)
|
|
|
|
{
|
|
|
|
/* Recreate menu to update "resize to nearest" */
|
|
|
|
game.createmenu(game.currentmenuname, true);
|
|
|
|
}
|
2020-01-01 21:29:24 +01:00
|
|
|
}
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void Screen::toggleStretchMode(void)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
stretchMode = (stretchMode + 1) % 3;
|
|
|
|
ResizeScreen(-1, -1);
|
|
|
|
}
|
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void Screen::toggleLinearFilter(void)
|
2020-01-01 21:29:24 +01:00
|
|
|
{
|
|
|
|
isFiltered = !isFiltered;
|
2020-07-09 03:42:57 +02:00
|
|
|
SDL_SetHintWithPriority(
|
|
|
|
SDL_HINT_RENDER_SCALE_QUALITY,
|
|
|
|
isFiltered ? "linear" : "nearest",
|
|
|
|
SDL_HINT_OVERRIDE
|
|
|
|
);
|
2020-01-01 21:29:24 +01:00
|
|
|
SDL_DestroyTexture(m_screenTexture);
|
|
|
|
m_screenTexture = SDL_CreateTexture(
|
|
|
|
m_renderer,
|
|
|
|
SDL_PIXELFORMAT_ARGB8888,
|
|
|
|
SDL_TEXTUREACCESS_STREAMING,
|
|
|
|
320,
|
|
|
|
240
|
|
|
|
);
|
|
|
|
}
|
2020-07-02 06:19:40 +02:00
|
|
|
|
Explicitly declare void for all void parameter functions (#628)
Apparently in C, if you have `void test();`, it's completely okay to do
`test(2);`. The function will take in the argument, but just discard it
and throw it away. It's like a trash can, and a rude one at that. If you
declare it like `void test(void);`, this is prevented.
This is not a problem in C++ - doing `void test();` and `test(2);` is
guaranteed to result in a compile error (this also means that right now,
at least in all `.cpp` files, nobody is ever calling a void parameter
function with arguments and having their arguments be thrown away).
However, we may not be using C++ in the future, so I just want to lay
down the precedent that if a function takes in no arguments, you must
explicitly declare it as such.
I would've added `-Wstrict-prototypes`, but it produces an annoying
warning message saying it doesn't work in C++ mode if you're compiling
in C++ mode. So it can be added later.
2021-02-25 23:23:59 +01:00
|
|
|
void Screen::resetRendererWorkaround(void)
|
2020-07-02 06:19:40 +02:00
|
|
|
{
|
|
|
|
SDL_SetHintWithPriority(
|
|
|
|
SDL_HINT_RENDER_VSYNC,
|
|
|
|
vsync ? "1" : "0",
|
|
|
|
SDL_HINT_OVERRIDE
|
|
|
|
);
|
|
|
|
|
|
|
|
/* FIXME: This exists because SDL_HINT_RENDER_VSYNC is not dynamic!
|
|
|
|
* As a result, our only workaround is to tear down the renderer
|
|
|
|
* and recreate everything so that it can process the variable.
|
|
|
|
* -flibit
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (m_renderer == NULL)
|
|
|
|
{
|
|
|
|
/* We haven't made it to init yet, don't worry about it */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
SDL_RendererInfo renderInfo;
|
|
|
|
SDL_GetRendererInfo(m_renderer, &renderInfo);
|
|
|
|
bool curVsync = (renderInfo.flags & SDL_RENDERER_PRESENTVSYNC) != 0;
|
|
|
|
if (vsync == curVsync)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
SDL_DestroyTexture(m_screenTexture);
|
|
|
|
SDL_DestroyRenderer(m_renderer);
|
|
|
|
|
|
|
|
m_renderer = SDL_CreateRenderer(m_window, -1, 0);
|
|
|
|
m_screenTexture = SDL_CreateTexture(
|
|
|
|
m_renderer,
|
|
|
|
SDL_PIXELFORMAT_ARGB8888,
|
|
|
|
SDL_TEXTUREACCESS_STREAMING,
|
|
|
|
320,
|
|
|
|
240
|
|
|
|
);
|
|
|
|
|
|
|
|
/* Ugh, have to make sure to re-apply graphics options after doing the
|
|
|
|
* above, otherwise letterbox/integer won't be applied...
|
|
|
|
*/
|
|
|
|
ResizeScreen(-1, -1);
|
|
|
|
}
|