Merge pull request #111 from GabrielRavier/portableAddImprovedErrorHandlingBackends
Added improved error handling to Backend code
This commit is contained in:
commit
063ec2a92a
17 changed files with 3747 additions and 754 deletions
962
external/glad/include/glad/glad.h
vendored
962
external/glad/include/glad/glad.h
vendored
File diff suppressed because it is too large
Load diff
2906
external/glad/src/glad.c
vendored
2906
external/glad/src/glad.c
vendored
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,15 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
/// Include file for portable usage of __attribute__
|
||||||
|
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
#define ATTRIBUTE_FORMAT_PRINTF(stringIndex, firstToCheck) __attribute__((format(__MINGW_PRINTF_FORMAT, stringIndex, firstToCheck)))
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#define ATTRIBUTE_FORMAT_PRINTF(stringIndex, firstToCheck) __attribute__((format(printf, stringIndex, firstToCheck)))
|
||||||
|
#else
|
||||||
|
#define ATTRIBUTE_FORMAT_PRINTF(stringIndex, firstToCheck)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
|
||||||
#define ATTRIBUTE_HOT __attribute__((hot))
|
#define ATTRIBUTE_HOT __attribute__((hot))
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
|
|
||||||
|
@ -64,16 +65,18 @@ static void Callback(void *user_data, Uint8 *stream_uint8, int len)
|
||||||
|
|
||||||
BOOL AudioBackend_Init(void)
|
BOOL AudioBackend_Init(void)
|
||||||
{
|
{
|
||||||
|
Backend_PrintInfo("Initializing SDL2 audio backend...");
|
||||||
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
|
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
|
||||||
{
|
{
|
||||||
Backend_ShowMessageBox("Fatal error (SDL2 audio backend)", "'SDL_InitSubSystem(SDL_INIT_AUDIO)' failed");
|
std::string errorMessage = std::string("'SDL_InitSubSystem(SDL_INIT_AUDIO)' failed: ") + SDL_GetError();
|
||||||
|
Backend_ShowMessageBox("Fatal error (SDL2 audio backend)", errorMessage.c_str());
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
puts("Available SDL2 audio drivers:");
|
Backend_PrintInfo("Available SDL audio drivers:");
|
||||||
|
|
||||||
for (int i = 0; i < SDL_GetNumAudioDrivers(); ++i)
|
for (int i = 0; i < SDL_GetNumAudioDrivers(); ++i)
|
||||||
puts(SDL_GetAudioDriver(i));
|
Backend_PrintInfo("%s", SDL_GetAudioDriver(i));
|
||||||
|
|
||||||
SDL_AudioSpec specification;
|
SDL_AudioSpec specification;
|
||||||
specification.freq = 48000;
|
specification.freq = 48000;
|
||||||
|
@ -85,27 +88,31 @@ BOOL AudioBackend_Init(void)
|
||||||
|
|
||||||
SDL_AudioSpec obtained_specification;
|
SDL_AudioSpec obtained_specification;
|
||||||
device_id = SDL_OpenAudioDevice(NULL, 0, &specification, &obtained_specification, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
|
device_id = SDL_OpenAudioDevice(NULL, 0, &specification, &obtained_specification, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
|
||||||
output_frequency = obtained_specification.freq;
|
|
||||||
Mixer_Init(obtained_specification.freq);
|
|
||||||
|
|
||||||
if (device_id == 0)
|
if (device_id == 0)
|
||||||
{
|
{
|
||||||
Backend_ShowMessageBox("Fatal error (SDL2 audio backend)", "'SDL_OpenAudioDevice' failed");
|
std::string error_message = std::string("'SDL_OpenAudioDevice' failed: ") + SDL_GetError();
|
||||||
|
Backend_ShowMessageBox("Fatal error (SDL2 audio backend)", error_message.c_str());
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
output_frequency = obtained_specification.freq;
|
||||||
|
Mixer_Init(obtained_specification.freq);
|
||||||
|
|
||||||
SDL_PauseAudioDevice(device_id, 0);
|
SDL_PauseAudioDevice(device_id, 0);
|
||||||
|
|
||||||
printf("Selected SDL2 audio driver: %s\n", SDL_GetCurrentAudioDriver());
|
Backend_PrintInfo("Selected SDL audio driver: %s", SDL_GetCurrentAudioDriver());
|
||||||
|
|
||||||
|
Backend_PrintInfo("Succesfully initialized SDL2 audio backend");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioBackend_Deinit(void)
|
void AudioBackend_Deinit(void)
|
||||||
{
|
{
|
||||||
|
Backend_PrintInfo("De-initializing SDL2 audio backend...");
|
||||||
SDL_CloseAudioDevice(device_id);
|
SDL_CloseAudioDevice(device_id);
|
||||||
|
|
||||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||||
|
Backend_PrintInfo("Finished de-initializing SDL2 audio backend");
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioBackend_Sound* AudioBackend_CreateSound(unsigned int frequency, const unsigned char *samples, size_t length)
|
AudioBackend_Sound* AudioBackend_CreateSound(unsigned int frequency, const unsigned char *samples, size_t length)
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include "../../Organya.h"
|
#include "../../Organya.h"
|
||||||
#include "../../WindowsWrapper.h"
|
#include "../../WindowsWrapper.h"
|
||||||
|
#include "../Misc.h"
|
||||||
|
|
||||||
#include "SoftwareMixer.h"
|
#include "SoftwareMixer.h"
|
||||||
|
|
||||||
|
@ -72,6 +73,7 @@ static void Callback(ma_device *device, void *output_stream, const void *input_s
|
||||||
|
|
||||||
BOOL AudioBackend_Init(void)
|
BOOL AudioBackend_Init(void)
|
||||||
{
|
{
|
||||||
|
Backend_PrintInfo("Initializing miniaudio audio backend...");
|
||||||
ma_device_config config = ma_device_config_init(ma_device_type_playback);
|
ma_device_config config = ma_device_config_init(ma_device_type_playback);
|
||||||
config.playback.pDeviceID = NULL;
|
config.playback.pDeviceID = NULL;
|
||||||
config.playback.format = ma_format_f32;
|
config.playback.format = ma_format_f32;
|
||||||
|
@ -80,42 +82,72 @@ BOOL AudioBackend_Init(void)
|
||||||
config.dataCallback = Callback;
|
config.dataCallback = Callback;
|
||||||
config.pUserData = NULL;
|
config.pUserData = NULL;
|
||||||
|
|
||||||
if (ma_device_init(NULL, &config, &device) == MA_SUCCESS)
|
ma_result return_value;
|
||||||
|
|
||||||
|
return_value = ma_device_init(NULL, &config, &device);
|
||||||
|
if (return_value == MA_SUCCESS)
|
||||||
{
|
{
|
||||||
if (ma_mutex_init(device.pContext, &mutex) == MA_SUCCESS)
|
return_value = ma_mutex_init(device.pContext, &mutex);
|
||||||
|
if (return_value == MA_SUCCESS)
|
||||||
{
|
{
|
||||||
if (ma_mutex_init(device.pContext, &organya_mutex) == MA_SUCCESS)
|
return_value = ma_mutex_init(device.pContext, &organya_mutex);
|
||||||
|
if (return_value == MA_SUCCESS)
|
||||||
{
|
{
|
||||||
if (ma_device_start(&device) == MA_SUCCESS)
|
return_value = ma_device_start(&device);
|
||||||
|
if (return_value == MA_SUCCESS)
|
||||||
{
|
{
|
||||||
output_frequency = device.sampleRate;
|
output_frequency = device.sampleRate;
|
||||||
|
|
||||||
Mixer_Init(device.sampleRate);
|
Mixer_Init(device.sampleRate);
|
||||||
|
|
||||||
|
Backend_PrintInfo("Successfully initialized miniaudio audio backend");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Backend_PrintError("Failed to start playback device: %s", ma_result_description(return_value));
|
||||||
|
}
|
||||||
|
|
||||||
ma_mutex_uninit(&organya_mutex);
|
ma_mutex_uninit(&organya_mutex);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Backend_PrintError("Failed to create organya mutex: %s", ma_result_description(return_value));
|
||||||
|
}
|
||||||
|
|
||||||
ma_mutex_uninit(&mutex);
|
ma_mutex_uninit(&mutex);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Backend_PrintError("Failed to create mutex: %s", ma_result_description(return_value));
|
||||||
|
}
|
||||||
|
|
||||||
ma_device_uninit(&device);
|
ma_device_uninit(&device);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Backend_PrintError("Failed to initialize playback device: %s", ma_result_description(return_value));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioBackend_Deinit(void)
|
void AudioBackend_Deinit(void)
|
||||||
{
|
{
|
||||||
ma_device_stop(&device);
|
Backend_PrintInfo("De-initializing miniaudio audio backend...");
|
||||||
|
ma_result return_value;
|
||||||
|
return_value = ma_device_stop(&device);
|
||||||
|
|
||||||
|
if (return_value != MA_SUCCESS)
|
||||||
|
Backend_PrintError("Failed to stop playback device: %s", ma_result_description(return_value));
|
||||||
|
|
||||||
ma_mutex_uninit(&organya_mutex);
|
ma_mutex_uninit(&organya_mutex);
|
||||||
|
|
||||||
ma_mutex_uninit(&mutex);
|
ma_mutex_uninit(&mutex);
|
||||||
|
|
||||||
ma_device_uninit(&device);
|
ma_device_uninit(&device);
|
||||||
|
Backend_PrintInfo("Finished de-initializing miniaudio audio backend...");
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioBackend_Sound* AudioBackend_CreateSound(unsigned int frequency, const unsigned char *samples, size_t length)
|
AudioBackend_Sound* AudioBackend_CreateSound(unsigned int frequency, const unsigned char *samples, size_t length)
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include "../../WindowsWrapper.h"
|
#include "../../WindowsWrapper.h"
|
||||||
|
#include "../Misc.h"
|
||||||
|
|
||||||
#define DEADZONE (10000.0f / 32767.0f)
|
#define DEADZONE (10000.0f / 32767.0f)
|
||||||
|
|
||||||
|
@ -21,7 +22,7 @@ static void JoystickCallback(int joystick_id, int event)
|
||||||
switch (event)
|
switch (event)
|
||||||
{
|
{
|
||||||
case GLFW_CONNECTED:
|
case GLFW_CONNECTED:
|
||||||
printf("Joystick #%d connected - %s\n", joystick_id, glfwGetJoystickName(joystick_id));
|
Backend_PrintInfo("Joystick #%d connected - %s", joystick_id, glfwGetJoystickName(joystick_id));
|
||||||
|
|
||||||
if (!joystick_connected)
|
if (!joystick_connected)
|
||||||
{
|
{
|
||||||
|
@ -44,8 +45,11 @@ static void JoystickCallback(int joystick_id, int event)
|
||||||
// Set up neutral axes
|
// Set up neutral axes
|
||||||
axis_neutrals = (float*)malloc(sizeof(float) * total_axes);
|
axis_neutrals = (float*)malloc(sizeof(float) * total_axes);
|
||||||
|
|
||||||
for (int i = 0; i < total_axes; ++i)
|
if (axis_neutrals != NULL)
|
||||||
axis_neutrals[i] = axes[i];
|
for (int i = 0; i < total_axes; ++i)
|
||||||
|
axis_neutrals[i] = axes[i];
|
||||||
|
else
|
||||||
|
Backend_PrintError("Couldn't allocate memory for axis");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,7 +59,7 @@ static void JoystickCallback(int joystick_id, int event)
|
||||||
case GLFW_DISCONNECTED:
|
case GLFW_DISCONNECTED:
|
||||||
if (joystick_connected && joystick_id == connected_joystick_id)
|
if (joystick_connected && joystick_id == connected_joystick_id)
|
||||||
{
|
{
|
||||||
printf("Joystick #%d disconnected\n", connected_joystick_id);
|
Backend_PrintInfo("Joystick #%d disconnected", connected_joystick_id);
|
||||||
joystick_connected = FALSE;
|
joystick_connected = FALSE;
|
||||||
|
|
||||||
free(axis_neutrals);
|
free(axis_neutrals);
|
||||||
|
@ -67,6 +71,7 @@ static void JoystickCallback(int joystick_id, int event)
|
||||||
|
|
||||||
BOOL ControllerBackend_Init(void)
|
BOOL ControllerBackend_Init(void)
|
||||||
{
|
{
|
||||||
|
Backend_PrintInfo("Initializing GLFW controller backend...");
|
||||||
// Connect joysticks that are already plugged-in
|
// Connect joysticks that are already plugged-in
|
||||||
for (int i = GLFW_JOYSTICK_1; i < GLFW_JOYSTICK_LAST; ++i)
|
for (int i = GLFW_JOYSTICK_1; i < GLFW_JOYSTICK_LAST; ++i)
|
||||||
if (glfwJoystickPresent(i) == GLFW_TRUE)
|
if (glfwJoystickPresent(i) == GLFW_TRUE)
|
||||||
|
@ -75,11 +80,13 @@ BOOL ControllerBackend_Init(void)
|
||||||
// Set-up the callback for future (dis)connections
|
// Set-up the callback for future (dis)connections
|
||||||
glfwSetJoystickCallback(JoystickCallback);
|
glfwSetJoystickCallback(JoystickCallback);
|
||||||
|
|
||||||
|
Backend_PrintInfo("Sucessfully initialized GLFW controller backend");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControllerBackend_Deinit(void)
|
void ControllerBackend_Deinit(void)
|
||||||
{
|
{
|
||||||
|
Backend_PrintInfo("De-initializing GLFW controller backend...");
|
||||||
glfwSetJoystickCallback(NULL);
|
glfwSetJoystickCallback(NULL);
|
||||||
|
|
||||||
joystick_connected = FALSE;
|
joystick_connected = FALSE;
|
||||||
|
@ -87,6 +94,7 @@ void ControllerBackend_Deinit(void)
|
||||||
|
|
||||||
free(axis_neutrals);
|
free(axis_neutrals);
|
||||||
axis_neutrals = NULL;
|
axis_neutrals = NULL;
|
||||||
|
Backend_PrintInfo("Finished de-initializing GLFW controller backend");
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL ControllerBackend_GetJoystickStatus(JOYSTICK_STATUS *status)
|
BOOL ControllerBackend_GetJoystickStatus(JOYSTICK_STATUS *status)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "../Misc.h"
|
#include "../Misc.h"
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -17,6 +18,7 @@
|
||||||
#include "../../Organya.h"
|
#include "../../Organya.h"
|
||||||
#include "../../Profile.h"
|
#include "../../Profile.h"
|
||||||
#include "../../Resource.h"
|
#include "../../Resource.h"
|
||||||
|
#include "../../Attributes.h"
|
||||||
|
|
||||||
#define DO_KEY(GLFW_KEY, BACKEND_KEY) \
|
#define DO_KEY(GLFW_KEY, BACKEND_KEY) \
|
||||||
case GLFW_KEY: \
|
case GLFW_KEY: \
|
||||||
|
@ -150,10 +152,21 @@ static void DragAndDropCallback(GLFWwindow *window, int count, const char **path
|
||||||
LoadProfile(paths[0]);
|
LoadProfile(paths[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ErrorCallback(int code, const char *description)
|
||||||
|
{
|
||||||
|
Backend_PrintError("GLFW error received (%d): %s", code, description);
|
||||||
|
}
|
||||||
|
|
||||||
BOOL Backend_Init(void)
|
BOOL Backend_Init(void)
|
||||||
{
|
{
|
||||||
|
Backend_PrintInfo("Initializing GLFW platform backend...");
|
||||||
|
glfwSetErrorCallback(ErrorCallback);
|
||||||
|
|
||||||
if (glfwInit() == GL_TRUE)
|
if (glfwInit() == GL_TRUE)
|
||||||
|
{
|
||||||
|
Backend_PrintInfo("Successfully initialized GLFW platform backend");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
Backend_ShowMessageBox("Fatal error", "Could not initialise GLFW3");
|
Backend_ShowMessageBox("Fatal error", "Could not initialise GLFW3");
|
||||||
|
|
||||||
|
@ -162,10 +175,12 @@ BOOL Backend_Init(void)
|
||||||
|
|
||||||
void Backend_Deinit(void)
|
void Backend_Deinit(void)
|
||||||
{
|
{
|
||||||
|
Backend_PrintInfo("De-initializing GLFW platform backend...");
|
||||||
if (cursor != NULL)
|
if (cursor != NULL)
|
||||||
glfwDestroyCursor(cursor);
|
glfwDestroyCursor(cursor);
|
||||||
|
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
|
Backend_PrintInfo("Finished de-initializing GLFW platform backend ");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Backend_PostWindowCreation(void)
|
void Backend_PostWindowCreation(void)
|
||||||
|
@ -290,6 +305,26 @@ void Backend_ShowMessageBox(const char *title, const char *message)
|
||||||
printf("ShowMessageBox - '%s' - '%s'\n", title, message);
|
printf("ShowMessageBox - '%s' - '%s'\n", title, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ATTRIBUTE_FORMAT_PRINTF(1, 2) void Backend_PrintError(const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list argumentList;
|
||||||
|
va_start(argumentList, format);
|
||||||
|
fputs("ERROR: ", stderr);
|
||||||
|
vfprintf(stderr, format, argumentList);
|
||||||
|
fputc('\n', stderr);
|
||||||
|
va_end(argumentList);
|
||||||
|
}
|
||||||
|
|
||||||
|
ATTRIBUTE_FORMAT_PRINTF(1, 2) void Backend_PrintInfo(const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list argumentList;
|
||||||
|
va_start(argumentList, format);
|
||||||
|
fputs("INFO: ", stdout);
|
||||||
|
vprintf(format, argumentList);
|
||||||
|
putchar('\n');
|
||||||
|
va_end(argumentList);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned long Backend_GetTicks(void)
|
unsigned long Backend_GetTicks(void)
|
||||||
{
|
{
|
||||||
return (unsigned long)(glfwGetTime() * 1000.0);
|
return (unsigned long)(glfwGetTime() * 1000.0);
|
||||||
|
|
|
@ -71,7 +71,7 @@ BOOL WindowBackend_OpenGL_CreateWindow(const char *window_title, int *screen_wid
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Backend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Could not load OpenGL functions");
|
Backend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Could not initialize OpenGL context");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../WindowsWrapper.h"
|
#include "../WindowsWrapper.h"
|
||||||
|
#include "../Attributes.h"
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -96,5 +97,7 @@ void PlaybackBackend_EnableDragAndDrop(void);
|
||||||
BOOL Backend_SystemTask(void);
|
BOOL Backend_SystemTask(void);
|
||||||
void Backend_GetKeyboardState(BOOL *keyboard_state);
|
void Backend_GetKeyboardState(BOOL *keyboard_state);
|
||||||
void Backend_ShowMessageBox(const char *title, const char *message);
|
void Backend_ShowMessageBox(const char *title, const char *message);
|
||||||
|
ATTRIBUTE_FORMAT_PRINTF(1, 2) void Backend_PrintError(const char *format, ...);
|
||||||
|
ATTRIBUTE_FORMAT_PRINTF(1, 2) void Backend_PrintInfo(const char *format, ...);
|
||||||
unsigned long Backend_GetTicks(void);
|
unsigned long Backend_GetTicks(void);
|
||||||
void Backend_Delay(unsigned int ticks);
|
void Backend_Delay(unsigned int ticks);
|
||||||
|
|
|
@ -252,7 +252,7 @@ static void GLAPIENTRY MessageCallback(GLenum source, GLenum type, GLuint id, GL
|
||||||
(void)userParam;
|
(void)userParam;
|
||||||
|
|
||||||
if (severity != GL_DEBUG_SEVERITY_NOTIFICATION)
|
if (severity != GL_DEBUG_SEVERITY_NOTIFICATION)
|
||||||
printf("OpenGL debug: %s\n", message);
|
Backend_PrintInfo("OpenGL debug: %s", message);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
// ====================
|
// ====================
|
||||||
|
@ -289,7 +289,7 @@ static GLuint CompileShader(const char *vertex_shader_source, const char *fragme
|
||||||
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &shader_status);
|
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &shader_status);
|
||||||
if (shader_status != GL_TRUE)
|
if (shader_status != GL_TRUE)
|
||||||
{
|
{
|
||||||
char buffer[0x200];
|
char buffer[0x400];
|
||||||
glGetShaderInfoLog(fragment_shader, sizeof(buffer), NULL, buffer);
|
glGetShaderInfoLog(fragment_shader, sizeof(buffer), NULL, buffer);
|
||||||
Backend_ShowMessageBox("Fragment shader error", buffer);
|
Backend_ShowMessageBox("Fragment shader error", buffer);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -306,7 +306,7 @@ static GLuint CompileShader(const char *vertex_shader_source, const char *fragme
|
||||||
glGetProgramiv(program_id, GL_LINK_STATUS, &shader_status);
|
glGetProgramiv(program_id, GL_LINK_STATUS, &shader_status);
|
||||||
if (shader_status != GL_TRUE)
|
if (shader_status != GL_TRUE)
|
||||||
{
|
{
|
||||||
char buffer[0x200];
|
char buffer[0x400];
|
||||||
glGetProgramInfoLog(program_id, sizeof(buffer), NULL, buffer);
|
glGetProgramInfoLog(program_id, sizeof(buffer), NULL, buffer);
|
||||||
Backend_ShowMessageBox("Shader linker error", buffer);
|
Backend_ShowMessageBox("Shader linker error", buffer);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -329,7 +329,16 @@ static VertexBufferSlot* GetVertexBufferSlot(unsigned int slots_needed)
|
||||||
while (current_vertex_buffer_slot + slots_needed > local_vertex_buffer_size)
|
while (current_vertex_buffer_slot + slots_needed > local_vertex_buffer_size)
|
||||||
local_vertex_buffer_size <<= 1;
|
local_vertex_buffer_size <<= 1;
|
||||||
|
|
||||||
local_vertex_buffer = (VertexBufferSlot*)realloc(local_vertex_buffer, local_vertex_buffer_size * sizeof(VertexBufferSlot));
|
VertexBufferSlot *reallocResult = (VertexBufferSlot *)realloc(local_vertex_buffer, local_vertex_buffer_size * sizeof(VertexBufferSlot));
|
||||||
|
if (reallocResult != NULL)
|
||||||
|
{
|
||||||
|
local_vertex_buffer = reallocResult;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Backend_PrintError("Couldn't expand vertex buffer");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
current_vertex_buffer_slot += slots_needed;
|
current_vertex_buffer_slot += slots_needed;
|
||||||
|
@ -513,20 +522,82 @@ static void GlyphBatch_DestroyTexture(SPRITEBATCH_U64 texture_id, void *udata)
|
||||||
glDeleteTextures(1, &gl_texture_id);
|
glDeleteTextures(1, &gl_texture_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef USE_OPENGLES2
|
||||||
|
|
||||||
|
static const char *GetOpenGLErrorCodeDescription(GLenum error_code)
|
||||||
|
{
|
||||||
|
switch (error_code)
|
||||||
|
{
|
||||||
|
case GL_NO_ERROR:
|
||||||
|
return "No error";
|
||||||
|
|
||||||
|
case GL_INVALID_ENUM:
|
||||||
|
return "An unacceptable value was specified for enumerated argument";
|
||||||
|
|
||||||
|
case GL_INVALID_VALUE:
|
||||||
|
return "A numeric argument is out of range";
|
||||||
|
|
||||||
|
case GL_INVALID_OPERATION:
|
||||||
|
return "The specified operation is not allowed in the current state";
|
||||||
|
|
||||||
|
case GL_INVALID_FRAMEBUFFER_OPERATION:
|
||||||
|
return "The framebuffer object is not complete";
|
||||||
|
|
||||||
|
case GL_OUT_OF_MEMORY:
|
||||||
|
return "There is not enough memory left to execute the command";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For some reason glad does not define these even though they are there in OpenGL 3.2
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
case GL_STACK_UNDERFLOW:
|
||||||
|
return "An attempt has been made to perform an operation that would cause an internal stack to underflow";
|
||||||
|
|
||||||
|
case GL_STACK_OVERFLOW:
|
||||||
|
return "An attempt has been made to perform an operation that would cause an internal stack to overflow";
|
||||||
|
*/
|
||||||
|
|
||||||
|
default:
|
||||||
|
return "Unknown error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PostGLCallCallback(const char *name, void *function_pointer, int length_arguments, ...)
|
||||||
|
{
|
||||||
|
(void)function_pointer;
|
||||||
|
(void)length_arguments;
|
||||||
|
|
||||||
|
GLenum error_code = glad_glGetError(); // Manually use glad_glGetError. Otherwise, glad_debug_glGetError would be called and we'd get infinite recursion into this function
|
||||||
|
|
||||||
|
if (error_code != GL_NO_ERROR)
|
||||||
|
Backend_PrintError("Error %d in %s: %s", error_code, name, GetOpenGLErrorCodeDescription(error_code));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// ====================
|
// ====================
|
||||||
// Render-backend initialisation
|
// Render-backend initialisation
|
||||||
// ====================
|
// ====================
|
||||||
|
|
||||||
RenderBackend_Surface* RenderBackend_Init(const char *window_title, int screen_width, int screen_height, BOOL fullscreen)
|
RenderBackend_Surface* RenderBackend_Init(const char *window_title, int screen_width, int screen_height, BOOL fullscreen)
|
||||||
{
|
{
|
||||||
|
#ifndef USE_OPENGLES2
|
||||||
|
Backend_PrintInfo("Initializing OpenGL3 rendering backend...");
|
||||||
|
glad_set_post_callback(PostGLCallCallback);
|
||||||
|
#else
|
||||||
|
Backend_PrintInfo("Initializing OpenGLES2 rendering backend...");
|
||||||
|
#endif
|
||||||
|
|
||||||
actual_screen_width = screen_width;
|
actual_screen_width = screen_width;
|
||||||
actual_screen_height = screen_height;
|
actual_screen_height = screen_height;
|
||||||
|
|
||||||
if (WindowBackend_OpenGL_CreateWindow(window_title, &actual_screen_width, &actual_screen_height, fullscreen))
|
if (WindowBackend_OpenGL_CreateWindow(window_title, &actual_screen_width, &actual_screen_height, fullscreen))
|
||||||
{
|
{
|
||||||
printf("GL_VENDOR = %s\n", glGetString(GL_VENDOR));
|
Backend_PrintInfo("GL_VENDOR = %s", glGetString(GL_VENDOR));
|
||||||
printf("GL_RENDERER = %s\n", glGetString(GL_RENDERER));
|
Backend_PrintInfo("GL_RENDERER = %s", glGetString(GL_RENDERER));
|
||||||
printf("GL_VERSION = %s\n", glGetString(GL_VERSION));
|
Backend_PrintInfo("GL_VERSION = %s", glGetString(GL_VERSION));
|
||||||
|
Backend_PrintInfo("GL_SHADING_LANGUAGE_VERSION = %s", glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||||
|
|
||||||
// Set up blending (only used for font-rendering)
|
// Set up blending (only used for font-rendering)
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
@ -600,6 +671,12 @@ RenderBackend_Surface* RenderBackend_Init(const char *window_title, int screen_w
|
||||||
config.delete_texture_callback = GlyphBatch_DestroyTexture;
|
config.delete_texture_callback = GlyphBatch_DestroyTexture;
|
||||||
spritebatch_init(&glyph_batcher, &config, NULL);
|
spritebatch_init(&glyph_batcher, &config, NULL);
|
||||||
|
|
||||||
|
#ifndef USE_OPENGLES2
|
||||||
|
Backend_PrintInfo("Successfully initialized OpenGL3 rendering backend");
|
||||||
|
#else
|
||||||
|
Backend_PrintInfo("Successfully initialized OpenGLES2 rendering backend");
|
||||||
|
#endif
|
||||||
|
|
||||||
return &framebuffer;
|
return &framebuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -626,6 +703,11 @@ RenderBackend_Surface* RenderBackend_Init(const char *window_title, int screen_w
|
||||||
|
|
||||||
void RenderBackend_Deinit(void)
|
void RenderBackend_Deinit(void)
|
||||||
{
|
{
|
||||||
|
#ifndef USE_OPENGLES2
|
||||||
|
Backend_PrintInfo("De-initializing OpenGL3 rendering backend...");
|
||||||
|
#else
|
||||||
|
Backend_PrintInfo("De-initializing OpenGLES2 rendering backend...");
|
||||||
|
#endif
|
||||||
free(local_vertex_buffer);
|
free(local_vertex_buffer);
|
||||||
|
|
||||||
spritebatch_term(&glyph_batcher);
|
spritebatch_term(&glyph_batcher);
|
||||||
|
@ -642,6 +724,12 @@ void RenderBackend_Deinit(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
WindowBackend_OpenGL_DestroyWindow();
|
WindowBackend_OpenGL_DestroyWindow();
|
||||||
|
|
||||||
|
#ifndef USE_OPENGLES2
|
||||||
|
Backend_PrintInfo("Finished de-initializing OpenGL3 rendering backend");
|
||||||
|
#else
|
||||||
|
Backend_PrintInfo("Finished de-initializing OpenGLES2 rendering backend");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderBackend_DrawScreen(void)
|
void RenderBackend_DrawScreen(void)
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
|
|
||||||
|
@ -46,33 +47,45 @@ static void RectToSDLRect(const RECT *rect, SDL_Rect *sdl_rect)
|
||||||
|
|
||||||
RenderBackend_Surface* RenderBackend_Init(const char *window_title, int screen_width, int screen_height, BOOL fullscreen)
|
RenderBackend_Surface* RenderBackend_Init(const char *window_title, int screen_width, int screen_height, BOOL fullscreen)
|
||||||
{
|
{
|
||||||
|
Backend_PrintInfo("Initializing SDLSurface rendering backend...");
|
||||||
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, 0);
|
||||||
|
|
||||||
if (window != NULL)
|
if (window != NULL)
|
||||||
{
|
{
|
||||||
if (fullscreen)
|
if (fullscreen)
|
||||||
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
|
{
|
||||||
|
if (SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN) < 0)
|
||||||
|
Backend_PrintError("Could not set window to fullscreen: %s", SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
window_sdlsurface = SDL_GetWindowSurface(window);
|
window_sdlsurface = SDL_GetWindowSurface(window);
|
||||||
|
if (window_sdlsurface != NULL)
|
||||||
framebuffer.sdlsurface = SDL_CreateRGBSurfaceWithFormat(0, window_sdlsurface->w, window_sdlsurface->h, 0, SDL_PIXELFORMAT_RGB24);
|
|
||||||
|
|
||||||
if (framebuffer.sdlsurface != NULL)
|
|
||||||
{
|
{
|
||||||
Backend_PostWindowCreation();
|
framebuffer.sdlsurface = SDL_CreateRGBSurfaceWithFormat(0, window_sdlsurface->w, window_sdlsurface->h, 0, SDL_PIXELFORMAT_RGB24);
|
||||||
|
|
||||||
return &framebuffer;
|
if (framebuffer.sdlsurface != NULL)
|
||||||
|
{
|
||||||
|
Backend_PostWindowCreation();
|
||||||
|
|
||||||
|
Backend_PrintInfo("Successfully initialized SDLSurface rendering backend");
|
||||||
|
return &framebuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string error_message = std::string("Could not create framebuffer surface: ") + SDL_GetError();
|
||||||
|
Backend_ShowMessageBox("Fatal error (SDLSurface rendering backend)", error_message.c_str());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Backend_ShowMessageBox("Fatal error (SDLSurface rendering backend)", "Could not create framebuffer surface");
|
std::string error_message = std::string("Could not get SDL surface of the window: ") + SDL_GetError();
|
||||||
|
Backend_ShowMessageBox("Fatal error (SDLSurface rendering backend)", error_message.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_DestroyWindow(window);
|
SDL_DestroyWindow(window);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Backend_ShowMessageBox("Fatal error (SDLSurface rendering backend)", "Could not create window");
|
std::string error_message = std::string("Could not create window: ") + SDL_GetError();
|
||||||
|
Backend_ShowMessageBox("Fatal error (SDLSurface rendering backend)", error_message.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -80,14 +93,19 @@ RenderBackend_Surface* RenderBackend_Init(const char *window_title, int screen_w
|
||||||
|
|
||||||
void RenderBackend_Deinit(void)
|
void RenderBackend_Deinit(void)
|
||||||
{
|
{
|
||||||
|
Backend_PrintInfo("De-initializing SDLSurface rendering backend...");
|
||||||
SDL_FreeSurface(framebuffer.sdlsurface);
|
SDL_FreeSurface(framebuffer.sdlsurface);
|
||||||
SDL_DestroyWindow(window);
|
SDL_DestroyWindow(window);
|
||||||
|
Backend_PrintInfo("Finished de-initializing SDLSurface rendering backend");
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderBackend_DrawScreen(void)
|
void RenderBackend_DrawScreen(void)
|
||||||
{
|
{
|
||||||
SDL_BlitSurface(framebuffer.sdlsurface, NULL, window_sdlsurface, NULL);
|
if (SDL_BlitSurface(framebuffer.sdlsurface, NULL, window_sdlsurface, NULL) < 0)
|
||||||
SDL_UpdateWindowSurface(window);
|
Backend_PrintError("Couldn't blit framebuffer surface to window surface: %s", SDL_GetError());
|
||||||
|
|
||||||
|
if (SDL_UpdateWindowSurface(window) < 0)
|
||||||
|
Backend_PrintError("Couldn't put window surface on screen: %s", SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderBackend_Surface* RenderBackend_CreateSurface(unsigned int width, unsigned int height)
|
RenderBackend_Surface* RenderBackend_CreateSurface(unsigned int width, unsigned int height)
|
||||||
|
@ -162,9 +180,12 @@ void RenderBackend_Blit(RenderBackend_Surface *source_surface, const RECT *rect,
|
||||||
destination_rect.w = source_rect.w;
|
destination_rect.w = source_rect.w;
|
||||||
destination_rect.h = source_rect.h;
|
destination_rect.h = source_rect.h;
|
||||||
|
|
||||||
SDL_SetColorKey(source_surface->sdlsurface, colour_key ? SDL_TRUE : SDL_FALSE, SDL_MapRGB(source_surface->sdlsurface->format, 0, 0, 0)); // Assumes the colour key will always be #000000 (black)
|
// Assumes the colour key will always be #000000 (black)
|
||||||
|
if (SDL_SetColorKey(source_surface->sdlsurface, colour_key ? SDL_TRUE : SDL_FALSE, SDL_MapRGB(source_surface->sdlsurface->format, 0, 0, 0)) < 0)
|
||||||
|
Backend_PrintError("Couldn't set color key of surface: %s", SDL_GetError());
|
||||||
|
|
||||||
SDL_BlitSurface(source_surface->sdlsurface, &source_rect, destination_surface->sdlsurface, &destination_rect);
|
if (SDL_BlitSurface(source_surface->sdlsurface, &source_rect, destination_surface->sdlsurface, &destination_rect) < 0)
|
||||||
|
Backend_PrintError("Couldn't blit surface: %s", SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderBackend_ColourFill(RenderBackend_Surface *surface, const RECT *rect, unsigned char red, unsigned char green, unsigned char blue)
|
void RenderBackend_ColourFill(RenderBackend_Surface *surface, const RECT *rect, unsigned char red, unsigned char green, unsigned char blue)
|
||||||
|
@ -175,7 +196,8 @@ void RenderBackend_ColourFill(RenderBackend_Surface *surface, const RECT *rect,
|
||||||
SDL_Rect destination_rect;
|
SDL_Rect destination_rect;
|
||||||
RectToSDLRect(rect, &destination_rect);
|
RectToSDLRect(rect, &destination_rect);
|
||||||
|
|
||||||
SDL_FillRect(surface->sdlsurface, &destination_rect, SDL_MapRGB(surface->sdlsurface->format, red, green, blue));
|
if (SDL_FillRect(surface->sdlsurface, &destination_rect, SDL_MapRGB(surface->sdlsurface->format, red, green, blue)) < 0)
|
||||||
|
Backend_PrintError("Couldn't fill rectangle with color: %s", SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderBackend_Glyph* RenderBackend_LoadGlyph(const unsigned char *pixels, unsigned int width, unsigned int height, int pitch)
|
RenderBackend_Glyph* RenderBackend_LoadGlyph(const unsigned char *pixels, unsigned int width, unsigned int height, int pitch)
|
||||||
|
@ -189,6 +211,7 @@ RenderBackend_Glyph* RenderBackend_LoadGlyph(const unsigned char *pixels, unsign
|
||||||
|
|
||||||
if (glyph->sdlsurface == NULL)
|
if (glyph->sdlsurface == NULL)
|
||||||
{
|
{
|
||||||
|
Backend_PrintError("Couldn't create RBG surface: %s", SDL_GetError());
|
||||||
free(glyph);
|
free(glyph);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -240,9 +263,11 @@ void RenderBackend_DrawGlyph(RenderBackend_Glyph *glyph, long x, long y)
|
||||||
rect.w = glyph->sdlsurface->w;
|
rect.w = glyph->sdlsurface->w;
|
||||||
rect.h = glyph->sdlsurface->h;
|
rect.h = glyph->sdlsurface->h;
|
||||||
|
|
||||||
SDL_SetSurfaceColorMod(glyph->sdlsurface, glyph_colour_channels[0], glyph_colour_channels[1], glyph_colour_channels[2]);
|
if (SDL_SetSurfaceColorMod(glyph->sdlsurface, glyph_colour_channels[0], glyph_colour_channels[1], glyph_colour_channels[2]) < 0)
|
||||||
|
Backend_PrintError("Couldn't set color value: %s", SDL_GetError());
|
||||||
|
|
||||||
SDL_BlitSurface(glyph->sdlsurface, NULL, glyph_destination_sdlsurface, &rect);
|
if (SDL_BlitSurface(glyph->sdlsurface, NULL, glyph_destination_sdlsurface, &rect) < 0)
|
||||||
|
Backend_PrintError("Couldn't blit glyph indivual surface to final glyph surface: %s", SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderBackend_FlushGlyphs(void)
|
void RenderBackend_FlushGlyphs(void)
|
||||||
|
@ -263,4 +288,7 @@ void RenderBackend_HandleWindowResize(unsigned int width, unsigned int height)
|
||||||
// https://wiki.libsdl.org/SDL_GetWindowSurface
|
// https://wiki.libsdl.org/SDL_GetWindowSurface
|
||||||
// We need to fetch a new surface pointer
|
// We need to fetch a new surface pointer
|
||||||
window_sdlsurface = SDL_GetWindowSurface(window);
|
window_sdlsurface = SDL_GetWindowSurface(window);
|
||||||
|
|
||||||
|
if (window_sdlsurface == NULL)
|
||||||
|
Backend_PrintError("Couldn't get SDL surface for window after resize: %s", SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
|
|
||||||
|
@ -73,8 +74,11 @@ static void GlyphBatch_Draw(spritebatch_sprite_t *sprites, int count, int textur
|
||||||
|
|
||||||
// The SDL_Texture side of things uses alpha, not a colour-key, so the bug where the font is blended
|
// The SDL_Texture side of things uses alpha, not a colour-key, so the bug where the font is blended
|
||||||
// with the colour key doesn't occur.
|
// with the colour key doesn't occur.
|
||||||
SDL_SetTextureColorMod(texture_atlas, glyph_colour_channels[0], glyph_colour_channels[1], glyph_colour_channels[2]);
|
if (SDL_SetTextureColorMod(texture_atlas, glyph_colour_channels[0], glyph_colour_channels[1], glyph_colour_channels[2]) < 0)
|
||||||
SDL_SetTextureBlendMode(texture_atlas, SDL_BLENDMODE_BLEND);
|
Backend_PrintError("Couldn't set additional color value: %s", SDL_GetError());
|
||||||
|
|
||||||
|
if (SDL_SetTextureBlendMode(texture_atlas, SDL_BLENDMODE_BLEND) < 0)
|
||||||
|
Backend_PrintError("Couldn't set texture blend mode: %s", SDL_GetError());
|
||||||
|
|
||||||
for (int i = 0; i < count; ++i)
|
for (int i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
|
@ -83,7 +87,8 @@ static void GlyphBatch_Draw(spritebatch_sprite_t *sprites, int count, int textur
|
||||||
SDL_Rect source_rect = {(int)(texture_w * sprites[i].minx), (int)(texture_h * sprites[i].maxy), (int)glyph->width, (int)glyph->height};
|
SDL_Rect source_rect = {(int)(texture_w * sprites[i].minx), (int)(texture_h * sprites[i].maxy), (int)glyph->width, (int)glyph->height};
|
||||||
SDL_Rect destination_rect = {(int)sprites[i].x, (int)sprites[i].y, (int)glyph->width, (int)glyph->height};
|
SDL_Rect destination_rect = {(int)sprites[i].x, (int)sprites[i].y, (int)glyph->width, (int)glyph->height};
|
||||||
|
|
||||||
SDL_RenderCopy(renderer, texture_atlas, &source_rect, &destination_rect);
|
if (SDL_RenderCopy(renderer, texture_atlas, &source_rect, &destination_rect) < 0)
|
||||||
|
Backend_PrintError("Couldn't copy glyph texture portion to renderer: %s", SDL_GetError());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +109,11 @@ static SPRITEBATCH_U64 GlyphBatch_CreateTexture(void *pixels, int w, int h, void
|
||||||
|
|
||||||
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, w, h);
|
SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, w, h);
|
||||||
|
|
||||||
SDL_UpdateTexture(texture, NULL, pixels, w * 4);
|
if (texture == NULL)
|
||||||
|
Backend_PrintError("Couldn't create texture for renderer: %s", SDL_GetError());
|
||||||
|
|
||||||
|
if (SDL_UpdateTexture(texture, NULL, pixels, w * 4) < 0)
|
||||||
|
Backend_PrintError("Couldn't update texture: %s", SDL_GetError());
|
||||||
|
|
||||||
return (SPRITEBATCH_U64)texture;
|
return (SPRITEBATCH_U64)texture;
|
||||||
}
|
}
|
||||||
|
@ -119,13 +128,16 @@ static void GlyphBatch_DestroyTexture(SPRITEBATCH_U64 texture_id, void *udata)
|
||||||
|
|
||||||
RenderBackend_Surface* RenderBackend_Init(const char *window_title, int screen_width, int screen_height, BOOL fullscreen)
|
RenderBackend_Surface* RenderBackend_Init(const char *window_title, int screen_width, int screen_height, BOOL fullscreen)
|
||||||
{
|
{
|
||||||
puts("Available SDL2 render drivers:");
|
Backend_PrintInfo("Initializing SDLTexture rendering backend...");
|
||||||
|
Backend_PrintInfo("Available SDL render drivers:");
|
||||||
|
|
||||||
for (int i = 0; i < SDL_GetNumRenderDrivers(); ++i)
|
for (int i = 0; i < SDL_GetNumRenderDrivers(); ++i)
|
||||||
{
|
{
|
||||||
SDL_RendererInfo info;
|
SDL_RendererInfo info;
|
||||||
SDL_GetRenderDriverInfo(i, &info);
|
if (SDL_GetRenderDriverInfo(i, &info) < 0)
|
||||||
puts(info.name);
|
Backend_PrintError("Couldn't get render driver information: %s", SDL_GetError());
|
||||||
|
else
|
||||||
|
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, 0);
|
||||||
|
@ -133,7 +145,10 @@ RenderBackend_Surface* RenderBackend_Init(const char *window_title, int screen_w
|
||||||
if (window != NULL)
|
if (window != NULL)
|
||||||
{
|
{
|
||||||
if (fullscreen)
|
if (fullscreen)
|
||||||
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
|
{
|
||||||
|
if (SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN) < 0)
|
||||||
|
Backend_PrintError("Couldn't set window to fullscreen: %s", SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
#if SDL_VERSION_ATLEAST(2,0,10)
|
#if SDL_VERSION_ATLEAST(2,0,10)
|
||||||
SDL_SetHint(SDL_HINT_RENDER_BATCHING, "1"); // We never interfere with the renderer, so don't let SDL implicitly disable batching
|
SDL_SetHint(SDL_HINT_RENDER_BATCHING, "1"); // We never interfere with the renderer, so don't let SDL implicitly disable batching
|
||||||
|
@ -144,8 +159,10 @@ RenderBackend_Surface* RenderBackend_Init(const char *window_title, int screen_w
|
||||||
if (renderer != NULL)
|
if (renderer != NULL)
|
||||||
{
|
{
|
||||||
SDL_RendererInfo info;
|
SDL_RendererInfo info;
|
||||||
SDL_GetRendererInfo(renderer, &info);
|
if (SDL_GetRendererInfo(renderer, &info) < 0)
|
||||||
printf("Selected SDL2 render driver: %s\n", info.name);
|
Backend_PrintError("Couldn't get selected render driver information: %s", SDL_GetError());
|
||||||
|
else
|
||||||
|
Backend_PrintInfo("Selected SDL render driver: %s", info.name);
|
||||||
|
|
||||||
framebuffer.texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_TARGET, screen_width, screen_height);
|
framebuffer.texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_TARGET, screen_width, screen_height);
|
||||||
|
|
||||||
|
@ -165,22 +182,30 @@ RenderBackend_Surface* RenderBackend_Init(const char *window_title, int screen_w
|
||||||
config.get_pixels_callback = GlyphBatch_GetPixels;
|
config.get_pixels_callback = GlyphBatch_GetPixels;
|
||||||
config.generate_texture_callback = GlyphBatch_CreateTexture;
|
config.generate_texture_callback = GlyphBatch_CreateTexture;
|
||||||
config.delete_texture_callback = GlyphBatch_DestroyTexture;
|
config.delete_texture_callback = GlyphBatch_DestroyTexture;
|
||||||
spritebatch_init(&glyph_batcher, &config, NULL);
|
if (spritebatch_init(&glyph_batcher, &config, NULL) == 0)
|
||||||
|
{
|
||||||
|
Backend_PostWindowCreation();
|
||||||
|
|
||||||
Backend_PostWindowCreation();
|
Backend_PrintInfo("Successfully initialized SDLTexture rendering backend");
|
||||||
|
return &framebuffer;
|
||||||
return &framebuffer;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Backend_ShowMessageBox("Fatal error (SDLTexture rendering backend)", "Failed to initialize spritebatch");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Backend_ShowMessageBox("Fatal error (SDLTexture rendering backend)", "Could not create framebuffer");
|
std::string error_message = std::string("Could not create framebuffer: ") + SDL_GetError();
|
||||||
|
Backend_ShowMessageBox("Fatal error (SDLTexture rendering backend)", error_message.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_DestroyRenderer(renderer);
|
SDL_DestroyRenderer(renderer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Backend_ShowMessageBox("Fatal error (SDLTexture rendering backend)", "Could not create renderer");
|
std::string error_message = std::string("Could not create renderer: ") + SDL_GetError();
|
||||||
|
Backend_ShowMessageBox("Fatal error (SDLTexture rendering backend)", error_message.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -188,7 +213,8 @@ RenderBackend_Surface* RenderBackend_Init(const char *window_title, int screen_w
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Backend_ShowMessageBox("Fatal error (SDLTexture rendering backend)", "Could not create window");
|
std::string error_message = std::string("Could not create window: ") + SDL_GetError();
|
||||||
|
Backend_ShowMessageBox("Fatal error (SDLTexture rendering backend)", error_message.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -196,18 +222,24 @@ RenderBackend_Surface* RenderBackend_Init(const char *window_title, int screen_w
|
||||||
|
|
||||||
void RenderBackend_Deinit(void)
|
void RenderBackend_Deinit(void)
|
||||||
{
|
{
|
||||||
|
Backend_PrintInfo("De-initializing SDLTexture rendering backend...");
|
||||||
spritebatch_term(&glyph_batcher);
|
spritebatch_term(&glyph_batcher);
|
||||||
SDL_DestroyTexture(framebuffer.texture);
|
SDL_DestroyTexture(framebuffer.texture);
|
||||||
SDL_DestroyRenderer(renderer);
|
SDL_DestroyRenderer(renderer);
|
||||||
SDL_DestroyWindow(window);
|
SDL_DestroyWindow(window);
|
||||||
|
Backend_PrintInfo("Finished de-initializing SDLTexture rendering backend...");
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderBackend_DrawScreen(void)
|
void RenderBackend_DrawScreen(void)
|
||||||
{
|
{
|
||||||
spritebatch_tick(&glyph_batcher);
|
spritebatch_tick(&glyph_batcher);
|
||||||
|
|
||||||
SDL_SetRenderTarget(renderer, NULL);
|
if (SDL_SetRenderTarget(renderer, NULL) < 0)
|
||||||
SDL_RenderCopy(renderer, framebuffer.texture, NULL, NULL);
|
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());
|
||||||
|
|
||||||
SDL_RenderPresent(renderer);
|
SDL_RenderPresent(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,6 +316,13 @@ void RenderBackend_UnlockSurface(RenderBackend_Surface *surface, unsigned int wi
|
||||||
return;
|
return;
|
||||||
|
|
||||||
unsigned char *buffer = (unsigned char*)malloc(width * height * 4);
|
unsigned char *buffer = (unsigned char*)malloc(width * height * 4);
|
||||||
|
|
||||||
|
if (buffer == NULL)
|
||||||
|
{
|
||||||
|
Backend_PrintError("Couldn't allocate memory for surface buffer: %s", SDL_GetError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const unsigned char *src_pixel = surface->pixels;
|
const unsigned char *src_pixel = surface->pixels;
|
||||||
|
|
||||||
// Convert the SDL_Surface's colour-keyed pixels to RGBA32
|
// Convert the SDL_Surface's colour-keyed pixels to RGBA32
|
||||||
|
@ -309,7 +348,8 @@ void RenderBackend_UnlockSurface(RenderBackend_Surface *surface, unsigned int wi
|
||||||
free(surface->pixels);
|
free(surface->pixels);
|
||||||
|
|
||||||
SDL_Rect rect = {0, 0, (int)width, (int)height};
|
SDL_Rect rect = {0, 0, (int)width, (int)height};
|
||||||
SDL_UpdateTexture(surface->texture, &rect, buffer, width * 4);
|
if (SDL_UpdateTexture(surface->texture, &rect, buffer, width * 4) < 0)
|
||||||
|
Backend_PrintError("Couldn't update part of texture: %s", SDL_GetError());
|
||||||
|
|
||||||
free(buffer);
|
free(buffer);
|
||||||
}
|
}
|
||||||
|
@ -325,9 +365,14 @@ void RenderBackend_Blit(RenderBackend_Surface *source_surface, const RECT *rect,
|
||||||
SDL_Rect destination_rect = {(int)x, (int)y, source_rect.w, source_rect.h};
|
SDL_Rect destination_rect = {(int)x, (int)y, source_rect.w, source_rect.h};
|
||||||
|
|
||||||
// Blit the texture
|
// Blit the texture
|
||||||
SDL_SetTextureBlendMode(source_surface->texture, colour_key ? SDL_BLENDMODE_BLEND : SDL_BLENDMODE_NONE);
|
if (SDL_SetTextureBlendMode(source_surface->texture, colour_key ? SDL_BLENDMODE_BLEND : SDL_BLENDMODE_NONE) < 0)
|
||||||
SDL_SetRenderTarget(renderer, destination_surface->texture);
|
Backend_PrintError("Couldn't set texture blend mode: %s", SDL_GetError());
|
||||||
SDL_RenderCopy(renderer, source_surface->texture, &source_rect, &destination_rect);
|
|
||||||
|
if (SDL_SetRenderTarget(renderer, destination_surface->texture) < 0)
|
||||||
|
Backend_PrintError("Couldn't set current rendering target: %s", SDL_GetError());
|
||||||
|
|
||||||
|
if (SDL_RenderCopy(renderer, source_surface->texture, &source_rect, &destination_rect) < 0)
|
||||||
|
Backend_PrintError("Couldn't copy part of texture to rendering target: %s", SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderBackend_ColourFill(RenderBackend_Surface *surface, const RECT *rect, unsigned char red, unsigned char green, unsigned char blue)
|
void RenderBackend_ColourFill(RenderBackend_Surface *surface, const RECT *rect, unsigned char red, unsigned char green, unsigned char blue)
|
||||||
|
@ -338,17 +383,27 @@ void RenderBackend_ColourFill(RenderBackend_Surface *surface, const RECT *rect,
|
||||||
SDL_Rect sdl_rect;
|
SDL_Rect sdl_rect;
|
||||||
RectToSDLRect(rect, &sdl_rect);
|
RectToSDLRect(rect, &sdl_rect);
|
||||||
|
|
||||||
|
Uint8 alpha = SDL_ALPHA_OPAQUE;
|
||||||
|
|
||||||
// Check colour-key
|
// Check colour-key
|
||||||
if (red == 0 && green == 0 && blue == 0)
|
if (red == 0 && green == 0 && blue == 0)
|
||||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
alpha = 0;
|
||||||
else
|
|
||||||
SDL_SetRenderDrawColor(renderer, red, green, blue, SDL_ALPHA_OPAQUE);
|
if (SDL_SetRenderDrawColor(renderer, red, green, blue, alpha) < 0)
|
||||||
|
Backend_PrintError("Couldn't set color for drawing operations: %s", SDL_GetError());
|
||||||
|
|
||||||
// Draw colour
|
// Draw colour
|
||||||
SDL_SetRenderTarget(renderer, surface->texture);
|
if (SDL_SetRenderTarget(renderer, surface->texture) < 0)
|
||||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
|
Backend_PrintError("Couldn't set texture current rendering target: %s", SDL_GetError());
|
||||||
SDL_RenderFillRect(renderer, &sdl_rect);
|
|
||||||
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
|
if (SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE) < 0)
|
||||||
|
Backend_PrintError("Couldn't disable blending for drawing operations: %s", SDL_GetError());
|
||||||
|
|
||||||
|
if (SDL_RenderFillRect(renderer, &sdl_rect) < 0)
|
||||||
|
Backend_PrintError("Couldn't fill rectangle on current rendering target: %s", SDL_GetError());
|
||||||
|
|
||||||
|
if (SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND) < 0)
|
||||||
|
Backend_PrintError("Couldn't enable alpha blending for drawing operations: %s", SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderBackend_Glyph* RenderBackend_LoadGlyph(const unsigned char *pixels, unsigned int width, unsigned int height, int pitch)
|
RenderBackend_Glyph* RenderBackend_LoadGlyph(const unsigned char *pixels, unsigned int width, unsigned int height, int pitch)
|
||||||
|
@ -401,19 +456,23 @@ void RenderBackend_PrepareToDrawGlyphs(RenderBackend_Surface *destination_surfac
|
||||||
if (destination_surface == NULL)
|
if (destination_surface == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SDL_SetRenderTarget(renderer, destination_surface->texture);
|
if (SDL_SetRenderTarget(renderer, destination_surface->texture) < 0)
|
||||||
|
Backend_PrintError("Couldn't set texture as current rendering target: %s", SDL_GetError());
|
||||||
|
|
||||||
memcpy(glyph_colour_channels, colour_channels, sizeof(glyph_colour_channels));
|
memcpy(glyph_colour_channels, colour_channels, sizeof(glyph_colour_channels));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderBackend_DrawGlyph(RenderBackend_Glyph *glyph, long x, long y)
|
void RenderBackend_DrawGlyph(RenderBackend_Glyph *glyph, long x, long y)
|
||||||
{
|
{
|
||||||
spritebatch_push(&glyph_batcher, (SPRITEBATCH_U64)glyph, glyph->width, glyph->height, x, y, 1.0f, 1.0f, 0.0f, 0.0f, 0);
|
if (spritebatch_push(&glyph_batcher, (SPRITEBATCH_U64)glyph, glyph->width, glyph->height, x, y, 1.0f, 1.0f, 0.0f, 0.0f, 0) != 1)
|
||||||
|
Backend_PrintError("Failed to push glyph to batcher");
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderBackend_FlushGlyphs(void)
|
void RenderBackend_FlushGlyphs(void)
|
||||||
{
|
{
|
||||||
spritebatch_defrag(&glyph_batcher);
|
if (spritebatch_defrag(&glyph_batcher) != 1)
|
||||||
|
Backend_PrintError("Couldn't defrag textures");
|
||||||
|
|
||||||
spritebatch_flush(&glyph_batcher);
|
spritebatch_flush(&glyph_batcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,18 +35,29 @@ static RenderBackend_Surface *glyph_destination_surface;
|
||||||
|
|
||||||
RenderBackend_Surface* RenderBackend_Init(const char *window_title, int screen_width, int screen_height, BOOL fullscreen)
|
RenderBackend_Surface* RenderBackend_Init(const char *window_title, int screen_width, int screen_height, BOOL fullscreen)
|
||||||
{
|
{
|
||||||
|
Backend_PrintInfo("Initializing Software rendering backend...");
|
||||||
size_t pitch;
|
size_t pitch;
|
||||||
framebuffer.pixels = WindowBackend_Software_CreateWindow(window_title, screen_width, screen_height, fullscreen, &pitch);
|
framebuffer.pixels = WindowBackend_Software_CreateWindow(window_title, screen_width, screen_height, fullscreen, &pitch);
|
||||||
framebuffer.width = screen_width;
|
framebuffer.width = screen_width;
|
||||||
framebuffer.height = screen_height;
|
framebuffer.height = screen_height;
|
||||||
framebuffer.pitch = pitch;
|
framebuffer.pitch = pitch;
|
||||||
|
|
||||||
return &framebuffer;
|
if (framebuffer.pixels)
|
||||||
|
{
|
||||||
|
Backend_PrintInfo("Successfully initialized Software rendering backend");
|
||||||
|
return &framebuffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Backend_PrintError("Failed to create window");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderBackend_Deinit(void)
|
void RenderBackend_Deinit(void)
|
||||||
{
|
{
|
||||||
|
Backend_PrintInfo("De-initializing Software rendering backend...");
|
||||||
WindowBackend_Software_DestroyWindow();
|
WindowBackend_Software_DestroyWindow();
|
||||||
|
Backend_PrintInfo("Finished de-initializing Software rendering backend");
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderBackend_DrawScreen(void)
|
void RenderBackend_DrawScreen(void)
|
||||||
|
|
|
@ -7,8 +7,9 @@
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
|
|
||||||
#include "../../WindowsWrapper.h"
|
#include "../../WindowsWrapper.h"
|
||||||
|
#include "../Misc.h"
|
||||||
|
|
||||||
#define DEADZONE 10000;
|
#define DEADZONE 10000
|
||||||
|
|
||||||
static SDL_Joystick *joystick;
|
static SDL_Joystick *joystick;
|
||||||
|
|
||||||
|
@ -16,13 +17,20 @@ static Sint16 *axis_neutrals;
|
||||||
|
|
||||||
BOOL ControllerBackend_Init(void)
|
BOOL ControllerBackend_Init(void)
|
||||||
{
|
{
|
||||||
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
|
Backend_PrintInfo("Initializing SDL2 controller backend...");
|
||||||
|
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0)
|
||||||
|
{
|
||||||
|
Backend_PrintError("Couldn't initialise joystick SDL subsystem: %s", SDL_GetError());
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Backend_PrintInfo("Successfully initialized SDL2 controller backend");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControllerBackend_Deinit(void)
|
void ControllerBackend_Deinit(void)
|
||||||
{
|
{
|
||||||
|
Backend_PrintInfo("De-initializing SDL2 controller backend...");
|
||||||
if (joystick != NULL)
|
if (joystick != NULL)
|
||||||
{
|
{
|
||||||
SDL_JoystickClose(joystick);
|
SDL_JoystickClose(joystick);
|
||||||
|
@ -30,6 +38,7 @@ void ControllerBackend_Deinit(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||||
|
Backend_PrintInfo("Finished de-initializing SDL2 controller backend");
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL ControllerBackend_GetJoystickStatus(JOYSTICK_STATUS *status)
|
BOOL ControllerBackend_GetJoystickStatus(JOYSTICK_STATUS *status)
|
||||||
|
@ -41,7 +50,12 @@ BOOL ControllerBackend_GetJoystickStatus(JOYSTICK_STATUS *status)
|
||||||
|
|
||||||
// Handle directional inputs
|
// Handle directional inputs
|
||||||
const Sint16 joystick_x = SDL_JoystickGetAxis(joystick, 0);
|
const Sint16 joystick_x = SDL_JoystickGetAxis(joystick, 0);
|
||||||
|
if (joystick_x == 0)
|
||||||
|
Backend_PrintError("Failed to get current state of X axis control on joystick: %s", SDL_GetError());
|
||||||
|
|
||||||
const Sint16 joystick_y = SDL_JoystickGetAxis(joystick, 1);
|
const Sint16 joystick_y = SDL_JoystickGetAxis(joystick, 1);
|
||||||
|
if (joystick_y == 0)
|
||||||
|
Backend_PrintError("Failed to get current state of Y axis control on joystick: %s", SDL_GetError());
|
||||||
|
|
||||||
status->bLeft = joystick_x < axis_neutrals[0] - DEADZONE;
|
status->bLeft = joystick_x < axis_neutrals[0] - DEADZONE;
|
||||||
status->bRight = joystick_x > axis_neutrals[0] + DEADZONE;
|
status->bRight = joystick_x > axis_neutrals[0] + DEADZONE;
|
||||||
|
@ -50,8 +64,16 @@ BOOL ControllerBackend_GetJoystickStatus(JOYSTICK_STATUS *status)
|
||||||
|
|
||||||
// Handle button inputs
|
// Handle button inputs
|
||||||
int total_buttons = SDL_JoystickNumButtons(joystick);
|
int total_buttons = SDL_JoystickNumButtons(joystick);
|
||||||
|
if (total_buttons < 0)
|
||||||
|
Backend_PrintError("Failed to get number of buttons on joystick: %s", SDL_GetError());
|
||||||
|
|
||||||
int total_axes = SDL_JoystickNumAxes(joystick);
|
int total_axes = SDL_JoystickNumAxes(joystick);
|
||||||
|
if (total_axes < 0)
|
||||||
|
Backend_PrintError("Failed to get number of general axis controls on joystick: %s", SDL_GetError());
|
||||||
|
|
||||||
int total_hats = SDL_JoystickNumHats(joystick);
|
int total_hats = SDL_JoystickNumHats(joystick);
|
||||||
|
if (total_hats < 0)
|
||||||
|
Backend_PrintError("Failed to get number of POV hats on joystick: %s", SDL_GetError());
|
||||||
|
|
||||||
unsigned int buttons_done = 0;
|
unsigned int buttons_done = 0;
|
||||||
|
|
||||||
|
@ -123,7 +145,16 @@ BOOL ControllerBackend_ResetJoystickStatus(void)
|
||||||
|
|
||||||
void ControllerBackend_JoystickConnect(Sint32 joystick_id)
|
void ControllerBackend_JoystickConnect(Sint32 joystick_id)
|
||||||
{
|
{
|
||||||
printf("Joystick #%d connected - %s\n", joystick_id, SDL_JoystickNameForIndex(joystick_id));
|
const char *joystick_name = SDL_JoystickNameForIndex(joystick_id);
|
||||||
|
if (joystick_name != NULL)
|
||||||
|
{
|
||||||
|
Backend_PrintInfo("Joystick #%d connected - %s", joystick_id, joystick_name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Backend_PrintError("Couldn't get joystick name: %s", SDL_GetError());
|
||||||
|
Backend_PrintInfo("Joystick #%d connected - Name unknown", joystick_id);
|
||||||
|
}
|
||||||
|
|
||||||
if (joystick == NULL)
|
if (joystick == NULL)
|
||||||
{
|
{
|
||||||
|
@ -132,17 +163,24 @@ void ControllerBackend_JoystickConnect(Sint32 joystick_id)
|
||||||
if (joystick != NULL)
|
if (joystick != NULL)
|
||||||
{
|
{
|
||||||
int total_axes = SDL_JoystickNumAxes(joystick);
|
int total_axes = SDL_JoystickNumAxes(joystick);
|
||||||
|
if (total_axes < 0)
|
||||||
|
Backend_PrintError("Couldn't get number of general axis control on connected joystick: %s", SDL_GetError());
|
||||||
|
|
||||||
int total_buttons = SDL_JoystickNumButtons(joystick);
|
int total_buttons = SDL_JoystickNumButtons(joystick);
|
||||||
|
if (total_buttons < 0)
|
||||||
|
Backend_PrintError("Couldn't get number of buttons on connected joystick: %s", SDL_GetError());
|
||||||
|
|
||||||
if (total_axes >= 2 && total_buttons >= 6)
|
if (total_axes >= 2 && total_buttons >= 6)
|
||||||
{
|
{
|
||||||
printf("Joystick #%d selected\n", joystick_id);
|
Backend_PrintInfo("Joystick #%d selected", joystick_id);
|
||||||
|
|
||||||
// Set up neutral axes
|
// Set up neutral axes
|
||||||
axis_neutrals = (Sint16*)malloc(sizeof(Sint16) * total_axes);
|
axis_neutrals = (Sint16*)malloc(sizeof(Sint16) * total_axes);
|
||||||
|
if (axis_neutrals != NULL)
|
||||||
for (int i = 0; i < total_axes; ++i)
|
for (int i = 0; i < total_axes; ++i)
|
||||||
axis_neutrals[i] = SDL_JoystickGetAxis(joystick, i);
|
axis_neutrals[i] = SDL_JoystickGetAxis(joystick, i);
|
||||||
|
else
|
||||||
|
Backend_PrintError("Couldn't allocate memory for neutral axes");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -150,14 +188,22 @@ void ControllerBackend_JoystickConnect(Sint32 joystick_id)
|
||||||
joystick = NULL;
|
joystick = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Backend_PrintError("Couldn't open joystick for use: %s", SDL_GetError());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControllerBackend_JoystickDisconnect(Sint32 joystick_id)
|
void ControllerBackend_JoystickDisconnect(Sint32 joystick_id)
|
||||||
{
|
{
|
||||||
if (joystick_id == SDL_JoystickInstanceID(joystick))
|
SDL_JoystickID current_joystick_id = SDL_JoystickInstanceID(joystick);
|
||||||
|
if (current_joystick_id < 0)
|
||||||
|
Backend_PrintError("Couldn't get instance ID for current joystick: %s", SDL_GetError());
|
||||||
|
|
||||||
|
if (joystick_id == current_joystick_id)
|
||||||
{
|
{
|
||||||
printf("Joystick #%d disconnected\n", joystick_id);
|
Backend_PrintInfo("Joystick #%d disconnected", joystick_id);
|
||||||
SDL_JoystickClose(joystick);
|
SDL_JoystickClose(joystick);
|
||||||
joystick = NULL;
|
joystick = NULL;
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
|
|
||||||
|
@ -32,35 +33,43 @@ static SDL_Cursor *cursor;
|
||||||
|
|
||||||
BOOL Backend_Init(void)
|
BOOL Backend_Init(void)
|
||||||
{
|
{
|
||||||
|
Backend_PrintInfo("Initializing SDL2 platform backend...");
|
||||||
if (SDL_Init(SDL_INIT_EVENTS) == 0)
|
if (SDL_Init(SDL_INIT_EVENTS) == 0)
|
||||||
{
|
{
|
||||||
if (SDL_InitSubSystem(SDL_INIT_VIDEO) == 0)
|
if (SDL_InitSubSystem(SDL_INIT_VIDEO) == 0)
|
||||||
{
|
{
|
||||||
puts("Available SDL2 video drivers:");
|
Backend_PrintInfo("Available SDL video drivers:");
|
||||||
|
|
||||||
for (int i = 0; i < SDL_GetNumVideoDrivers(); ++i)
|
for (int i = 0; i < SDL_GetNumVideoDrivers(); ++i)
|
||||||
puts(SDL_GetVideoDriver(i));
|
Backend_PrintInfo("%s", SDL_GetVideoDriver(i));
|
||||||
|
|
||||||
const char *driver = SDL_GetCurrentVideoDriver();
|
const char *driver = SDL_GetCurrentVideoDriver();
|
||||||
|
|
||||||
if (driver != NULL)
|
if (driver != NULL)
|
||||||
printf("Selected SDL2 video driver: %s\n", driver);
|
Backend_PrintInfo("Selected SDL video driver: %s", driver);
|
||||||
|
else
|
||||||
|
Backend_PrintError("No SDL video driver initialized !");
|
||||||
|
|
||||||
|
Backend_PrintInfo("Successfully initialized SDL2 platform backend");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Backend_ShowMessageBox("Fatal error", "Could not initialise SDL2 video subsystem");
|
std::string error_message = std::string("Could not initialise SDL video subsystem: ") + SDL_GetError();
|
||||||
|
Backend_ShowMessageBox("Fatal error", error_message.c_str());
|
||||||
|
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Backend_ShowMessageBox("Fatal error", "Could not initialise SDL2");
|
std::string error_message = std::string("Could not initialise SDL: ") + SDL_GetError();
|
||||||
|
Backend_ShowMessageBox("Fatal error", error_message.c_str());
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Backend_Deinit(void)
|
void Backend_Deinit(void)
|
||||||
{
|
{
|
||||||
|
Backend_PrintInfo("De-initializing SDL2 platform backend...");
|
||||||
if (cursor != NULL)
|
if (cursor != NULL)
|
||||||
SDL_FreeCursor(cursor);
|
SDL_FreeCursor(cursor);
|
||||||
|
|
||||||
|
@ -70,6 +79,7 @@ void Backend_Deinit(void)
|
||||||
free(cursor_surface_pixels);
|
free(cursor_surface_pixels);
|
||||||
|
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
Backend_PrintInfo("Finished de-initializing SDL2 platform backend...");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Backend_PostWindowCreation(void)
|
void Backend_PostWindowCreation(void)
|
||||||
|
@ -80,6 +90,9 @@ void Backend_PostWindowCreation(void)
|
||||||
BOOL Backend_GetBasePath(char *string_buffer)
|
BOOL Backend_GetBasePath(char *string_buffer)
|
||||||
{
|
{
|
||||||
char *base_path = SDL_GetBasePath();
|
char *base_path = SDL_GetBasePath();
|
||||||
|
if (base_path == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
// Trim the trailing '/'
|
// Trim the trailing '/'
|
||||||
size_t base_path_length = strlen(base_path);
|
size_t base_path_length = strlen(base_path);
|
||||||
base_path[base_path_length - 1] = '\0';
|
base_path[base_path_length - 1] = '\0';
|
||||||
|
@ -103,6 +116,10 @@ void Backend_SetWindowIcon(const unsigned char *rgb_pixels, unsigned int width,
|
||||||
SDL_SetWindowIcon(window, surface);
|
SDL_SetWindowIcon(window, surface);
|
||||||
SDL_FreeSurface(surface);
|
SDL_FreeSurface(surface);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Backend_PrintError("Couldn't create RGB surface for window icon: %s", SDL_GetError());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Backend_SetCursor(const unsigned char *rgb_pixels, unsigned int width, unsigned int height)
|
void Backend_SetCursor(const unsigned char *rgb_pixels, unsigned int width, unsigned int height)
|
||||||
|
@ -126,6 +143,10 @@ void Backend_SetCursor(const unsigned char *rgb_pixels, unsigned int width, unsi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Backend_PrintError("Failed to allocate memory for cursor surface");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlaybackBackend_EnableDragAndDrop(void)
|
void PlaybackBackend_EnableDragAndDrop(void)
|
||||||
|
@ -283,8 +304,29 @@ void Backend_GetKeyboardState(BOOL *out_keyboard_state)
|
||||||
|
|
||||||
void Backend_ShowMessageBox(const char *title, const char *message)
|
void Backend_ShowMessageBox(const char *title, const char *message)
|
||||||
{
|
{
|
||||||
printf("ShowMessageBox - '%s' - '%s'\n", title, message);
|
fprintf(stderr, "ShowMessageBox - '%s' - '%s'\n", title, message);
|
||||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title, message, window);
|
if (SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title, message, window) != 0)
|
||||||
|
Backend_PrintError("Was also unable to display a message box containing the error: %s", SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
ATTRIBUTE_FORMAT_PRINTF(1, 2) void Backend_PrintError(const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list argumentList;
|
||||||
|
va_start(argumentList, format);
|
||||||
|
fputs("ERROR: ", stderr);
|
||||||
|
vfprintf(stderr, format, argumentList);
|
||||||
|
fputc('\n', stderr);
|
||||||
|
va_end(argumentList);
|
||||||
|
}
|
||||||
|
|
||||||
|
ATTRIBUTE_FORMAT_PRINTF(1, 2) void Backend_PrintInfo(const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list argumentList;
|
||||||
|
va_start(argumentList, format);
|
||||||
|
fputs("INFO: ", stdout);
|
||||||
|
vprintf(format, argumentList);
|
||||||
|
putchar('\n');
|
||||||
|
va_end(argumentList);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long Backend_GetTicks(void)
|
unsigned long Backend_GetTicks(void)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#ifdef USE_OPENGLES2
|
#ifdef USE_OPENGLES2
|
||||||
#include <GLES2/gl2.h>
|
#include <GLES2/gl2.h>
|
||||||
|
@ -22,15 +23,29 @@ static SDL_GLContext context;
|
||||||
BOOL WindowBackend_OpenGL_CreateWindow(const char *window_title, int *screen_width, int *screen_height, BOOL fullscreen)
|
BOOL WindowBackend_OpenGL_CreateWindow(const char *window_title, int *screen_width, int *screen_height, BOOL fullscreen)
|
||||||
{
|
{
|
||||||
#ifdef USE_OPENGLES2
|
#ifdef USE_OPENGLES2
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES) < 0)
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
|
Backend_PrintError("Couldn't set OpenGL context type to ES: %s", SDL_GetError());
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0) < 0)
|
||||||
|
Backend_PrintError("Couldn't set OpenGL context flags to 0: %s", SDL_GetError());
|
||||||
|
|
||||||
|
if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2) < 0)
|
||||||
|
Backend_PrintError("Couldn't set OpenGL major version to 2: %s", SDL_GetError());
|
||||||
|
|
||||||
|
if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0) < 0)
|
||||||
|
Backend_PrintError("Couldn't set OpenGL minor version to 0: %s", SDL_GetError());
|
||||||
#else
|
#else
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE) < 0)
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
|
Backend_PrintError("Couldn't set OpenGL context type to core: %s", SDL_GetError());
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
|
if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG) < 0)
|
||||||
|
Backend_PrintError("Couldn't set OpenGL forward compatibility: %s", SDL_GetError());
|
||||||
|
|
||||||
|
if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3) < 0)
|
||||||
|
Backend_PrintError("Couldn't set OpenGL major version to 3: %s", SDL_GetError());
|
||||||
|
|
||||||
|
if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2) < 0)
|
||||||
|
Backend_PrintError("Couldn't set OpenGL minor verison to 2: %s", SDL_GetError());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, *screen_width, *screen_height, SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL | (fullscreen ? SDL_WINDOW_FULLSCREEN : 0));
|
window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, *screen_width, *screen_height, SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL | (fullscreen ? SDL_WINDOW_FULLSCREEN : 0));
|
||||||
|
@ -62,12 +77,13 @@ BOOL WindowBackend_OpenGL_CreateWindow(const char *window_title, int *screen_wid
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Backend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Could not load OpenGL functions");
|
Backend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Couldn't load OpenGL functions");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
std::string error_message = std::string("Couldn't setup OpenGL context for rendering: ") + SDL_GetError();
|
||||||
Backend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "SDL_GL_MakeCurrent failed");
|
Backend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "SDL_GL_MakeCurrent failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +91,7 @@ BOOL WindowBackend_OpenGL_CreateWindow(const char *window_title, int *screen_wid
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
std::string error_message = std::string("Couldn't create OpenGL context: %s", SDL_GetError());
|
||||||
Backend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Could not create OpenGL context");
|
Backend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Could not create OpenGL context");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +99,8 @@ BOOL WindowBackend_OpenGL_CreateWindow(const char *window_title, int *screen_wid
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Backend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Could not create window");
|
std::string error_message = std::string("Could not create window: ") + SDL_GetError();
|
||||||
|
Backend_ShowMessageBox("Fatal error (OpenGL rendering backend)", error_message.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
|
|
||||||
|
@ -22,30 +23,41 @@ unsigned char* WindowBackend_Software_CreateWindow(const char *window_title, int
|
||||||
if (window != NULL)
|
if (window != NULL)
|
||||||
{
|
{
|
||||||
if (fullscreen)
|
if (fullscreen)
|
||||||
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
|
if (SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN) < 0)
|
||||||
|
Backend_PrintError("Couldn't set window to fullscree: %s", SDL_GetError());
|
||||||
|
|
||||||
window_sdlsurface = SDL_GetWindowSurface(window);
|
window_sdlsurface = SDL_GetWindowSurface(window);
|
||||||
|
|
||||||
framebuffer_sdlsurface = SDL_CreateRGBSurfaceWithFormat(0, window_sdlsurface->w, window_sdlsurface->h, 0, SDL_PIXELFORMAT_RGB24);
|
if (window_sdlsurface != NULL)
|
||||||
|
|
||||||
if (framebuffer_sdlsurface != NULL)
|
|
||||||
{
|
{
|
||||||
*pitch = framebuffer_sdlsurface->pitch;
|
|
||||||
|
|
||||||
Backend_PostWindowCreation();
|
framebuffer_sdlsurface = SDL_CreateRGBSurfaceWithFormat(0, window_sdlsurface->w, window_sdlsurface->h, 0, SDL_PIXELFORMAT_RGB24);
|
||||||
|
|
||||||
return (unsigned char*)framebuffer_sdlsurface->pixels;
|
if (framebuffer_sdlsurface != NULL)
|
||||||
|
{
|
||||||
|
*pitch = framebuffer_sdlsurface->pitch;
|
||||||
|
|
||||||
|
Backend_PostWindowCreation();
|
||||||
|
|
||||||
|
return (unsigned char*)framebuffer_sdlsurface->pixels;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::string error_message = std::string("Couldn't create framebuffer surface: ") + SDL_GetError();
|
||||||
|
Backend_ShowMessageBox("Fatal error (software rendering backend)", error_message.c_str());
|
||||||
|
SDL_DestroyWindow(window);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Backend_ShowMessageBox("Fatal error (software rendering backend)", "Could not create framebuffer surface");
|
std::string error_message = std::string("Couldn't get SDL surface associated with window: ") + SDL_GetError();
|
||||||
|
Backend_ShowMessageBox("Fatal error (software rendering backend)", error_message.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_DestroyWindow(window);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Backend_ShowMessageBox("Fatal error (software rendering backend)", "Could not create window");
|
std::string error_message = std::string("Couldn't create window: ") + SDL_GetError();
|
||||||
|
Backend_ShowMessageBox("Fatal error (software rendering backend)", error_message.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -59,8 +71,11 @@ void WindowBackend_Software_DestroyWindow(void)
|
||||||
|
|
||||||
void WindowBackend_Software_Display(void)
|
void WindowBackend_Software_Display(void)
|
||||||
{
|
{
|
||||||
SDL_BlitSurface(framebuffer_sdlsurface, NULL, window_sdlsurface, NULL);
|
if (SDL_BlitSurface(framebuffer_sdlsurface, NULL, window_sdlsurface, NULL) < 0)
|
||||||
SDL_UpdateWindowSurface(window);
|
Backend_PrintError("Couldn't blit framebuffer surface to window surface: %s", SDL_GetError());
|
||||||
|
|
||||||
|
if (SDL_UpdateWindowSurface(window) < 0)
|
||||||
|
Backend_PrintError("Couldn't copy window surface to the screen: %s", SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowBackend_Software_HandleWindowResize(unsigned int width, unsigned int height)
|
void WindowBackend_Software_HandleWindowResize(unsigned int width, unsigned int height)
|
||||||
|
@ -71,4 +86,7 @@ void WindowBackend_Software_HandleWindowResize(unsigned int width, unsigned int
|
||||||
// https://wiki.libsdl.org/SDL_GetWindowSurface
|
// https://wiki.libsdl.org/SDL_GetWindowSurface
|
||||||
// We need to fetch a new surface pointer
|
// We need to fetch a new surface pointer
|
||||||
window_sdlsurface = SDL_GetWindowSurface(window);
|
window_sdlsurface = SDL_GetWindowSurface(window);
|
||||||
|
|
||||||
|
if (window_sdlsurface == NULL)
|
||||||
|
Backend_PrintError("Couldn't get SDL surface associated with window: %s", SDL_GetError());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue