ref: e93ee47728f4cfb7888ecf4fd8634d18bc27222b
parent: dacd34072ad8bda281cc55136484e1962a3daa3c
author: Clownacy <Clownacy@users.noreply.github.com>
date: Wed May 6 19:02:08 EDT 2020
More backend rearranging The Window stuff isn't meant for the user, so hide it a bit more
--- /dev/null
+++ b/src/Backends/Rendering/Window/OpenGL.h
@@ -1,0 +1,5 @@
+#pragma once
+
+bool WindowBackend_OpenGL_CreateWindow(const char *window_title, int *screen_width, int *screen_height, bool fullscreen);
+void WindowBackend_OpenGL_DestroyWindow(void);
+void WindowBackend_OpenGL_Display(void);
--- /dev/null
+++ b/src/Backends/Rendering/Window/OpenGL3/GLFW3.cpp
@@ -1,0 +1,94 @@
+#include "../Window-OpenGL.h"
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#ifdef USE_OPENGLES2
+#include <GLES2/gl2.h>
+#else
+#include <glad/glad.h>
+#endif
+#include <GLFW/glfw3.h>
+
+#include "../Misc.h"
+#include "../Shared/GLFW3.h"
+
+GLFWwindow *window;
+
+bool WindowBackend_OpenGL_CreateWindow(const char *window_title, int *screen_width, int *screen_height, bool fullscreen)
+{
+#ifdef USE_OPENGLES2
+ glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
+#else
+ glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
+ glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
+ glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
+#endif
+
+ GLFWmonitor *monitor = NULL;
+
+ if (fullscreen)
+ {
+ monitor = glfwGetPrimaryMonitor();
+
+ if (monitor != NULL)
+ {
+ const GLFWvidmode *mode = glfwGetVideoMode(monitor);
+
+ *screen_width = mode->width;
+ *screen_height = mode->height;
+ }
+ }
+
+ window = glfwCreateWindow(*screen_width, *screen_height, window_title, monitor, NULL);
+
+ if (window != NULL)
+ {
+ glfwMakeContextCurrent(window);
+
+ #ifndef USE_OPENGLES2
+ if (gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
+ {
+ // Check if the platform supports OpenGL 3.2
+ if (GLAD_GL_VERSION_3_2)
+ {
+ #endif
+ Backend_PostWindowCreation();
+
+ return true;
+ #ifndef USE_OPENGLES2
+ }
+ else
+ {
+ Backend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Your system does not support OpenGL 3.2");
+ }
+ }
+ else
+ {
+ Backend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Could not initialize OpenGL context");
+ }
+ #endif
+
+ glfwDestroyWindow(window);
+ }
+ else
+ {
+ Backend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Could not create window");
+ }
+
+ return false;
+}
+
+void WindowBackend_OpenGL_DestroyWindow(void)
+{
+ glfwDestroyWindow(window);
+}
+
+void WindowBackend_OpenGL_Display(void)
+{
+ glfwSwapBuffers(window);
+}
--- /dev/null
+++ b/src/Backends/Rendering/Window/OpenGL3/SDL2.cpp
@@ -1,0 +1,116 @@
+#include "../Window-OpenGL.h"
+
+#include <stddef.h>
+#include <string>
+
+#ifdef USE_OPENGLES2
+#include <GLES2/gl2.h>
+#else
+#include <glad/glad.h>
+#endif
+#include "SDL.h"
+
+#include "../Misc.h"
+#include "../Shared/SDL2.h"
+#include "../../Resource.h"
+
+SDL_Window *window;
+
+static SDL_GLContext context;
+
+bool WindowBackend_OpenGL_CreateWindow(const char *window_title, int *screen_width, int *screen_height, bool fullscreen)
+{
+#ifdef USE_OPENGLES2
+ if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES) < 0)
+ Backend_PrintError("Couldn't set OpenGL context type to ES: %s", SDL_GetError());
+
+ 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
+ if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE) < 0)
+ Backend_PrintError("Couldn't set OpenGL context type to core: %s", SDL_GetError());
+
+ 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
+
+ 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));
+
+ if (window != NULL)
+ {
+ context = SDL_GL_CreateContext(window);
+
+ if (context != NULL)
+ {
+ if (SDL_GL_MakeCurrent(window, context) == 0)
+ {
+ #ifndef USE_OPENGLES2
+ if (gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress))
+ {
+ // Check if the platform supports OpenGL 3.2
+ if (GLAD_GL_VERSION_3_2)
+ {
+ #endif
+ Backend_PostWindowCreation();
+
+ return true;
+ #ifndef USE_OPENGLES2
+ }
+ else
+ {
+ Backend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Your system does not support OpenGL 3.2");
+ }
+ }
+ else
+ {
+ Backend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Couldn't load OpenGL functions");
+ }
+ #endif
+ }
+ 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");
+ }
+
+ SDL_GL_DeleteContext(context);
+ }
+ 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");
+ }
+
+ SDL_DestroyWindow(window);
+ }
+ else
+ {
+ 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;
+}
+
+void WindowBackend_OpenGL_DestroyWindow(void)
+{
+ SDL_GL_DeleteContext(context);
+ SDL_DestroyWindow(window);
+}
+
+void WindowBackend_OpenGL_Display(void)
+{
+ SDL_GL_SwapWindow(window);
+}
--- /dev/null
+++ b/src/Backends/Rendering/Window/OpenGLES2/GLFW3.cpp
@@ -1,0 +1,2 @@
+#define USE_OPENGLES2
+#include "Window-OpenGL3.cpp"
--- /dev/null
+++ b/src/Backends/Rendering/Window/OpenGLES2/SDL2.cpp
@@ -1,0 +1,2 @@
+#define USE_OPENGLES2
+#include "Window-OpenGL3.cpp"
--- /dev/null
+++ b/src/Backends/Rendering/Window/Software.h
@@ -1,0 +1,9 @@
+#pragma once
+
+#include <stddef.h>
+
+bool WindowBackend_Software_CreateWindow(const char *window_title, int screen_width, int screen_height, bool fullscreen);
+void WindowBackend_Software_DestroyWindow(void);
+unsigned char* WindowBackend_Software_GetFramebuffer(size_t *pitch);
+void WindowBackend_Software_Display(void);
+void WindowBackend_Software_HandleWindowResize(unsigned int width, unsigned int height);
--- /dev/null
+++ b/src/Backends/Rendering/Window/Software/GLFW3.cpp
@@ -1,0 +1,156 @@
+#include "../Window-Software.h"
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#if defined(__APPLE__)
+ #include <OpenGL/gl.h>
+#else
+ #include <GL/gl.h>
+#endif
+#include <GLFW/glfw3.h>
+
+#include "../Misc.h"
+#include "../Shared/GLFW3.h"
+
+GLFWwindow *window;
+
+static unsigned char *framebuffer;
+static int framebuffer_width;
+static int framebuffer_height;
+
+static float framebuffer_x_ratio;
+static float framebuffer_y_ratio;
+
+static GLuint screen_texture_id;
+
+bool WindowBackend_Software_CreateWindow(const char *window_title, int screen_width, int screen_height, bool fullscreen)
+{
+ glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 1);
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
+
+ framebuffer_width = screen_width;
+ framebuffer_height = screen_height;
+
+ GLFWmonitor *monitor = NULL;
+
+ if (fullscreen)
+ {
+ monitor = glfwGetPrimaryMonitor();
+
+ if (monitor != NULL)
+ {
+ const GLFWvidmode *mode = glfwGetVideoMode(monitor);
+
+ screen_width = mode->width;
+ screen_height = mode->height;
+ }
+ }
+
+ window = glfwCreateWindow(screen_width, screen_height, window_title, monitor, NULL);
+
+ if (window != NULL)
+ {
+ glfwMakeContextCurrent(window);
+
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+
+ glEnable(GL_TEXTURE_2D);
+
+ WindowBackend_Software_HandleWindowResize(screen_width, screen_height);
+
+ // Create screen texture
+ glGenTextures(1, &screen_texture_id);
+ glBindTexture(GL_TEXTURE_2D, screen_texture_id);
+
+ int framebuffer_texture_width = 1;
+ while (framebuffer_texture_width < framebuffer_width)
+ framebuffer_texture_width <<= 1;
+
+ int framebuffer_texture_height = 1;
+ while (framebuffer_texture_height < framebuffer_height)
+ framebuffer_texture_height <<= 1;
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, framebuffer_texture_width, framebuffer_texture_height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ framebuffer_x_ratio = (float)framebuffer_width / framebuffer_texture_width;
+ framebuffer_y_ratio = (float)framebuffer_height / framebuffer_texture_height;
+
+ framebuffer = (unsigned char*)malloc(framebuffer_width * framebuffer_height * 3);
+
+ Backend_PostWindowCreation();
+
+ return true;
+ }
+ else
+ {
+ Backend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Could not create window");
+ }
+
+ return false;
+}
+
+void WindowBackend_Software_DestroyWindow(void)
+{
+ free(framebuffer);
+ glDeleteTextures(1, &screen_texture_id);
+ glfwDestroyWindow(window);
+}
+
+unsigned char* WindowBackend_Software_GetFramebuffer(size_t *pitch)
+{
+ *pitch = framebuffer_width * 3;
+
+ return framebuffer;
+}
+
+void WindowBackend_Software_Display(void)
+{
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, framebuffer_width, framebuffer_height, GL_RGB, GL_UNSIGNED_BYTE, framebuffer);
+
+ glBegin(GL_TRIANGLE_STRIP);
+ glTexCoord2f(0.0f, framebuffer_y_ratio);
+ glVertex2f(-1.0f, -1.0f);
+ glTexCoord2f(framebuffer_x_ratio, framebuffer_y_ratio);
+ glVertex2f(1.0f, -1.0f);
+ glTexCoord2f(0.0f, 0.0f);
+ glVertex2f(-1.0f, 1.0f);
+ glTexCoord2f(framebuffer_x_ratio, 0.0f);
+ glVertex2f(1.0f, 1.0f);
+ glEnd();
+
+ glfwSwapBuffers(window);
+}
+
+void WindowBackend_Software_HandleWindowResize(unsigned int width, unsigned int height)
+{
+ // Do some viewport trickery, to fit the framebuffer in the center of the screen
+ GLint viewport_x;
+ GLint viewport_y;
+ GLsizei viewport_width;
+ GLsizei viewport_height;
+
+ if ((float)width / (float)height > (float)framebuffer_width / (float)framebuffer_height)
+ {
+ viewport_y = 0;
+ viewport_height = height;
+
+ viewport_width = framebuffer_width * ((float)height / (float)framebuffer_height);
+ viewport_x = (width - viewport_width) / 2;
+ }
+ else
+ {
+ viewport_x = 0;
+ viewport_width = width;
+
+ viewport_height = framebuffer_height * ((float)width / (float)framebuffer_width);
+ viewport_y = (height - viewport_height) / 2;
+ }
+
+ glViewport(viewport_x, viewport_y, viewport_width, viewport_height);
+}
--- /dev/null
+++ b/src/Backends/Rendering/Window/Software/Null.cpp
@@ -1,0 +1,39 @@
+#include "../Window-Software.h"
+
+#include <stddef.h>
+#include <stdlib.h>
+
+static unsigned char *framebuffer;
+
+unsigned char* WindowBackend_Software_CreateWindow(const char *window_title, int screen_width, int screen_height, bool fullscreen, size_t *pitch)
+{
+ (void)window_title;
+ (void)fullscreen;
+
+ framebuffer = (unsigned char*)malloc(screen_width * screen_height * 3);
+
+ if (framebuffer != NULL)
+ {
+ *pitch = screen_width * 3;
+
+ return framebuffer;
+ }
+
+ return NULL;
+}
+
+void WindowBackend_Software_DestroyWindow(void)
+{
+ free(framebuffer);
+}
+
+void WindowBackend_Software_Display(void)
+{
+
+}
+
+void WindowBackend_Software_HandleWindowResize(unsigned int width, unsigned int height)
+{
+ (void)width;
+ (void)height;
+}
--- /dev/null
+++ b/src/Backends/Rendering/Window/Software/SDL2.cpp
@@ -1,0 +1,95 @@
+#include "../Window-Software.h"
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string>
+
+#include "SDL.h"
+
+#include "../Misc.h"
+#include "../Shared/SDL2.h"
+
+SDL_Window *window;
+
+static SDL_Surface *window_sdlsurface;
+static SDL_Surface *framebuffer_sdlsurface;
+
+bool WindowBackend_Software_CreateWindow(const char *window_title, int screen_width, int screen_height, bool fullscreen)
+{
+ window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, screen_width, screen_height, 0);
+
+ if (window != NULL)
+ {
+ if (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);
+
+ 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();
+
+ return true;
+ }
+ 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
+ {
+ 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());
+ }
+ }
+ else
+ {
+ std::string error_message = std::string("Couldn't create window: ") + SDL_GetError();
+ Backend_ShowMessageBox("Fatal error (software rendering backend)", error_message.c_str());
+ }
+
+ return false;
+}
+
+void WindowBackend_Software_DestroyWindow(void)
+{
+ SDL_FreeSurface(framebuffer_sdlsurface);
+ SDL_DestroyWindow(window);
+}
+
+unsigned char* WindowBackend_Software_GetFramebuffer(size_t *pitch)
+{
+ *pitch = framebuffer_sdlsurface->pitch;
+
+ return (unsigned char*)framebuffer_sdlsurface->pixels;
+}
+
+void WindowBackend_Software_Display(void)
+{
+ if (SDL_BlitSurface(framebuffer_sdlsurface, NULL, window_sdlsurface, NULL) < 0)
+ 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)width;
+ (void)height;
+
+ // https://wiki.libsdl.org/SDL_GetWindowSurface
+ // We need to fetch a new surface pointer
+ window_sdlsurface = SDL_GetWindowSurface(window);
+
+ if (window_sdlsurface == NULL)
+ Backend_PrintError("Couldn't get SDL surface associated with window: %s", SDL_GetError());
+}
--- /dev/null
+++ b/src/Backends/Rendering/Window/Software/WiiU.cpp
@@ -1,0 +1,269 @@
+// Sexy new backend that bounces the software-rendered frame to the GPU,
+// eliminating V-tearing, and gaining support for rendering to the TV for
+// free!
+
+#include "../Window-Software.h"
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <gx2/display.h>
+#include <gx2/draw.h>
+#include <gx2/registers.h>
+#include <gx2/sampler.h>
+#include <gx2/texture.h>
+#include <gx2r/buffer.h>
+#include <gx2r/draw.h>
+#include <gx2r/resource.h>
+#include <gx2r/surface.h>
+#include <whb/gfx.h>
+
+#include "../../Attributes.h"
+
+#include "WiiUShaders/texture.gsh.h"
+
+typedef struct Viewport
+{
+ float x;
+ float y;
+ float width;
+ float height;
+} Viewport;
+
+static unsigned char *fake_framebuffer;
+
+static size_t fake_framebuffer_width;
+static size_t fake_framebuffer_height;
+
+static WHBGfxShaderGroup shader_group;
+
+static GX2RBuffer vertex_position_buffer;
+static GX2RBuffer texture_coordinate_buffer;
+
+static GX2Sampler sampler;
+
+static GX2Texture screen_texture;
+
+static Viewport tv_viewport;
+static Viewport drc_viewport;
+
+static void CalculateViewport(unsigned int actual_screen_width, unsigned int actual_screen_height, Viewport *viewport)
+{
+ if ((float)actual_screen_width / (float)actual_screen_height > (float)fake_framebuffer_width / (float)fake_framebuffer_height)
+ {
+ viewport->y = 0.0f;
+ viewport->height = actual_screen_height;
+
+ viewport->width = fake_framebuffer_width * ((float)actual_screen_height / (float)fake_framebuffer_height);
+ viewport->x = (actual_screen_width - viewport->width) / 2;
+ }
+ else
+ {
+ viewport->x = 0.0f;
+ viewport->width = actual_screen_width;
+
+ viewport->height = fake_framebuffer_height * ((float)actual_screen_width / (float)fake_framebuffer_width);
+ viewport->y = (actual_screen_height - viewport->height) / 2;
+ }
+}
+
+bool WindowBackend_Software_CreateWindow(const char *window_title, int screen_width, int screen_height, bool fullscreen)
+{
+ (void)window_title;
+ (void)fullscreen;
+
+ fake_framebuffer_width = screen_width;
+ fake_framebuffer_height = screen_height;
+
+ fake_framebuffer = (unsigned char*)malloc(fake_framebuffer_width * fake_framebuffer_height * 3);
+
+ if (fake_framebuffer != NULL)
+ {
+ WHBGfxInit();
+
+ if (WHBGfxLoadGFDShaderGroup(&shader_group, 0, rtexture))
+ {
+ WHBGfxInitShaderAttribute(&shader_group, "input_vertex_coordinates", 0, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32);
+ WHBGfxInitShaderAttribute(&shader_group, "input_texture_coordinates", 1, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32);
+ WHBGfxInitFetchShader(&shader_group);
+
+ // Initialise vertex position buffer
+ const float vertex_positions[4][2] = {
+ {-1.0f, 1.0f},
+ { 1.0f, 1.0f},
+ { 1.0f, -1.0f},
+ {-1.0f, -1.0f}
+ };
+
+ vertex_position_buffer.flags = (GX2RResourceFlags)(GX2R_RESOURCE_BIND_VERTEX_BUFFER |
+ GX2R_RESOURCE_USAGE_CPU_READ |
+ GX2R_RESOURCE_USAGE_CPU_WRITE |
+ GX2R_RESOURCE_USAGE_GPU_READ);
+ vertex_position_buffer.elemSize = sizeof(vertex_positions[0]);
+ vertex_position_buffer.elemCount = sizeof(vertex_positions) / sizeof(vertex_positions[0]);
+ GX2RCreateBuffer(&vertex_position_buffer);
+ memcpy(GX2RLockBufferEx(&vertex_position_buffer, (GX2RResourceFlags)0), vertex_positions, sizeof(vertex_positions));
+ GX2RUnlockBufferEx(&vertex_position_buffer, (GX2RResourceFlags)0);
+
+ // Initialise texture coordinate buffer
+ const float texture_coordinates[4][2] = {
+ {0.0f, 0.0f},
+ {1.0f, 0.0f},
+ {1.0f, 1.0f},
+ {0.0f, 1.0f}
+ };
+
+ texture_coordinate_buffer.flags = (GX2RResourceFlags)(GX2R_RESOURCE_BIND_VERTEX_BUFFER |
+ GX2R_RESOURCE_USAGE_CPU_READ |
+ GX2R_RESOURCE_USAGE_CPU_WRITE |
+ GX2R_RESOURCE_USAGE_GPU_READ);
+ texture_coordinate_buffer.elemSize = sizeof(texture_coordinates[0]);
+ texture_coordinate_buffer.elemCount = sizeof(texture_coordinates) / sizeof(texture_coordinates[0]);
+ GX2RCreateBuffer(&texture_coordinate_buffer);
+ memcpy(GX2RLockBufferEx(&texture_coordinate_buffer, (GX2RResourceFlags)0), texture_coordinates, sizeof(texture_coordinates));
+ GX2RUnlockBufferEx(&texture_coordinate_buffer, (GX2RResourceFlags)0);
+
+ // Initialise sampler
+ GX2InitSampler(&sampler, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_POINT);
+
+ // Initialise screen texture
+ screen_texture.surface.width = fake_framebuffer_width;
+ screen_texture.surface.height = fake_framebuffer_height;
+ screen_texture.surface.format = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
+ screen_texture.surface.depth = 1;
+ screen_texture.surface.dim = GX2_SURFACE_DIM_TEXTURE_2D;
+ screen_texture.surface.tileMode = GX2_TILE_MODE_LINEAR_ALIGNED;
+ screen_texture.surface.mipLevels = 1;
+ screen_texture.viewNumMips = 1;
+ screen_texture.viewNumSlices = 1;
+ screen_texture.compMap = 0x00010203;
+ GX2CalcSurfaceSizeAndAlignment(&screen_texture.surface);
+ GX2InitTextureRegs(&screen_texture);
+
+ if (GX2RCreateSurface(&screen_texture.surface, (GX2RResourceFlags)(GX2R_RESOURCE_BIND_TEXTURE | GX2R_RESOURCE_BIND_COLOR_BUFFER |
+ GX2R_RESOURCE_USAGE_CPU_WRITE | GX2R_RESOURCE_USAGE_CPU_READ |
+ GX2R_RESOURCE_USAGE_GPU_WRITE | GX2R_RESOURCE_USAGE_GPU_READ)))
+ {
+ // Do some binding
+ GX2SetPixelSampler(&sampler, shader_group.pixelShader->samplerVars[0].location);
+ GX2SetPixelTexture(&screen_texture, shader_group.pixelShader->samplerVars[0].location);
+ GX2RSetAttributeBuffer(&vertex_position_buffer, 0, vertex_position_buffer.elemSize, 0);
+ GX2RSetAttributeBuffer(&texture_coordinate_buffer, 1, texture_coordinate_buffer.elemSize, 0);
+
+ // Calculate centred viewports
+ switch (GX2GetSystemTVScanMode())
+ {
+ // For now, we have to match WUT's broken behaviour (its `GX2TVScanMode`
+ // enum is missing values, and the rest are off-by-one)
+ //case GX2_TV_SCAN_MODE_576I:
+ case GX2_TV_SCAN_MODE_480I: // Actually 576i
+ case GX2_TV_SCAN_MODE_480P: // Actually 480i
+ CalculateViewport(854, 480, &tv_viewport);
+ break;
+
+ case GX2_TV_SCAN_MODE_720P: // Actually 480p
+ default: // Funnel the *real* 1080p into this
+ CalculateViewport(1280, 720, &tv_viewport);
+ break;
+
+ case GX2_TV_SCAN_MODE_1080I: // Actually invalid
+ case GX2_TV_SCAN_MODE_1080P: // Actually 1080i
+ CalculateViewport(1920, 1080, &tv_viewport);
+ break;
+ }
+
+ CalculateViewport(854, 480, &drc_viewport);
+
+ return true;
+ }
+
+ GX2RDestroyBufferEx(&texture_coordinate_buffer, (GX2RResourceFlags)0);
+ GX2RDestroyBufferEx(&vertex_position_buffer, (GX2RResourceFlags)0);
+
+ WHBGfxFreeShaderGroup(&shader_group);
+ }
+
+ WHBGfxShutdown();
+
+ free(fake_framebuffer);
+ }
+
+ return false;
+}
+
+void WindowBackend_Software_DestroyWindow(void)
+{
+ GX2RDestroySurfaceEx(&screen_texture.surface, (GX2RResourceFlags)0);
+
+ GX2RDestroyBufferEx(&texture_coordinate_buffer, (GX2RResourceFlags)0);
+ GX2RDestroyBufferEx(&vertex_position_buffer, (GX2RResourceFlags)0);
+
+ WHBGfxFreeShaderGroup(&shader_group);
+
+ WHBGfxShutdown();
+
+ free(fake_framebuffer);
+}
+
+unsigned char* WindowBackend_Software_GetFramebuffer(size_t *pitch)
+{
+ *pitch = fake_framebuffer_width * 3;
+
+ return fake_framebuffer;
+}
+
+ATTRIBUTE_HOT void WindowBackend_Software_Display(void)
+{
+ // Convert frame from RGB24 to RGBA32, and upload it to the GPU texture
+ unsigned char *framebuffer = (unsigned char*)GX2RLockSurfaceEx(&screen_texture.surface, 0, (GX2RResourceFlags)0);
+
+ const unsigned char *in_pointer = fake_framebuffer;
+
+ for (size_t y = 0; y < fake_framebuffer_height; ++y)
+ {
+ unsigned char *out_pointer = &framebuffer[screen_texture.surface.pitch * 4 * y];
+
+ for (size_t x = 0; x < fake_framebuffer_width; ++x)
+ {
+ *out_pointer++ = *in_pointer++;
+ *out_pointer++ = *in_pointer++;
+ *out_pointer++ = *in_pointer++;
+ *out_pointer++ = 0;
+ }
+ }
+
+ GX2RUnlockSurfaceEx(&screen_texture.surface, 0, (GX2RResourceFlags)0);
+
+ WHBGfxBeginRender();
+
+ // Draw to the TV
+ WHBGfxBeginRenderTV();
+ GX2SetViewport(tv_viewport.x, tv_viewport.y, tv_viewport.width, tv_viewport.height, 0.0f, 1.0f);
+ WHBGfxClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ GX2SetFetchShader(&shader_group.fetchShader);
+ GX2SetVertexShader(shader_group.vertexShader);
+ GX2SetPixelShader(shader_group.pixelShader);
+ GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);
+ WHBGfxFinishRenderTV();
+
+ // Draw to the gamepad
+ WHBGfxBeginRenderDRC();
+ GX2SetViewport(drc_viewport.x, drc_viewport.y, drc_viewport.width, drc_viewport.height, 0.0f, 1.0f);
+ WHBGfxClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ GX2SetFetchShader(&shader_group.fetchShader);
+ GX2SetVertexShader(shader_group.vertexShader);
+ GX2SetPixelShader(shader_group.pixelShader);
+ GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);
+ WHBGfxFinishRenderDRC();
+
+ WHBGfxFinishRender();
+}
+
+void WindowBackend_Software_HandleWindowResize(unsigned int width, unsigned int height)
+{
+ (void)width;
+ (void)height;
+
+ // The window doesn't resize on the Wii U
+}
--- a/src/Backends/Window-OpenGL.h
+++ /dev/null
@@ -1,5 +1,0 @@
-#pragma once
-
-bool WindowBackend_OpenGL_CreateWindow(const char *window_title, int *screen_width, int *screen_height, bool fullscreen);
-void WindowBackend_OpenGL_DestroyWindow(void);
-void WindowBackend_OpenGL_Display(void);
--- a/src/Backends/Window-Software.h
+++ /dev/null
@@ -1,9 +1,0 @@
-#pragma once
-
-#include <stddef.h>
-
-bool WindowBackend_Software_CreateWindow(const char *window_title, int screen_width, int screen_height, bool fullscreen);
-void WindowBackend_Software_DestroyWindow(void);
-unsigned char* WindowBackend_Software_GetFramebuffer(size_t *pitch);
-void WindowBackend_Software_Display(void);
-void WindowBackend_Software_HandleWindowResize(unsigned int width, unsigned int height);
--- a/src/Backends/Window/GLFW3-OpenGL3.cpp
+++ /dev/null
@@ -1,94 +1,0 @@
-#include "../Window-OpenGL.h"
-
-#include <stddef.h>
-#include <stdlib.h>
-
-#ifdef USE_OPENGLES2
-#include <GLES2/gl2.h>
-#else
-#include <glad/glad.h>
-#endif
-#include <GLFW/glfw3.h>
-
-#include "../Misc.h"
-#include "../Shared/GLFW3.h"
-
-GLFWwindow *window;
-
-bool WindowBackend_OpenGL_CreateWindow(const char *window_title, int *screen_width, int *screen_height, bool fullscreen)
-{
-#ifdef USE_OPENGLES2
- glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
-#else
- glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
- glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
- glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
-#endif
-
- GLFWmonitor *monitor = NULL;
-
- if (fullscreen)
- {
- monitor = glfwGetPrimaryMonitor();
-
- if (monitor != NULL)
- {
- const GLFWvidmode *mode = glfwGetVideoMode(monitor);
-
- *screen_width = mode->width;
- *screen_height = mode->height;
- }
- }
-
- window = glfwCreateWindow(*screen_width, *screen_height, window_title, monitor, NULL);
-
- if (window != NULL)
- {
- glfwMakeContextCurrent(window);
-
- #ifndef USE_OPENGLES2
- if (gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
- {
- // Check if the platform supports OpenGL 3.2
- if (GLAD_GL_VERSION_3_2)
- {
- #endif
- Backend_PostWindowCreation();
-
- return true;
- #ifndef USE_OPENGLES2
- }
- else
- {
- Backend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Your system does not support OpenGL 3.2");
- }
- }
- else
- {
- Backend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Could not initialize OpenGL context");
- }
- #endif
-
- glfwDestroyWindow(window);
- }
- else
- {
- Backend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Could not create window");
- }
-
- return false;
-}
-
-void WindowBackend_OpenGL_DestroyWindow(void)
-{
- glfwDestroyWindow(window);
-}
-
-void WindowBackend_OpenGL_Display(void)
-{
- glfwSwapBuffers(window);
-}
--- a/src/Backends/Window/GLFW3-OpenGLES2.cpp
+++ /dev/null
@@ -1,2 +1,0 @@
-#define USE_OPENGLES2
-#include "Window-OpenGL3.cpp"
--- a/src/Backends/Window/GLFW3-Software.cpp
+++ /dev/null
@@ -1,156 +1,0 @@
-#include "../Window-Software.h"
-
-#include <stddef.h>
-#include <stdlib.h>
-
-#if defined(__APPLE__)
- #include <OpenGL/gl.h>
-#else
- #include <GL/gl.h>
-#endif
-#include <GLFW/glfw3.h>
-
-#include "../Misc.h"
-#include "../Shared/GLFW3.h"
-
-GLFWwindow *window;
-
-static unsigned char *framebuffer;
-static int framebuffer_width;
-static int framebuffer_height;
-
-static float framebuffer_x_ratio;
-static float framebuffer_y_ratio;
-
-static GLuint screen_texture_id;
-
-bool WindowBackend_Software_CreateWindow(const char *window_title, int screen_width, int screen_height, bool fullscreen)
-{
- glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 1);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
-
- framebuffer_width = screen_width;
- framebuffer_height = screen_height;
-
- GLFWmonitor *monitor = NULL;
-
- if (fullscreen)
- {
- monitor = glfwGetPrimaryMonitor();
-
- if (monitor != NULL)
- {
- const GLFWvidmode *mode = glfwGetVideoMode(monitor);
-
- screen_width = mode->width;
- screen_height = mode->height;
- }
- }
-
- window = glfwCreateWindow(screen_width, screen_height, window_title, monitor, NULL);
-
- if (window != NULL)
- {
- glfwMakeContextCurrent(window);
-
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
-
- glEnable(GL_TEXTURE_2D);
-
- WindowBackend_Software_HandleWindowResize(screen_width, screen_height);
-
- // Create screen texture
- glGenTextures(1, &screen_texture_id);
- glBindTexture(GL_TEXTURE_2D, screen_texture_id);
-
- int framebuffer_texture_width = 1;
- while (framebuffer_texture_width < framebuffer_width)
- framebuffer_texture_width <<= 1;
-
- int framebuffer_texture_height = 1;
- while (framebuffer_texture_height < framebuffer_height)
- framebuffer_texture_height <<= 1;
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, framebuffer_texture_width, framebuffer_texture_height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- framebuffer_x_ratio = (float)framebuffer_width / framebuffer_texture_width;
- framebuffer_y_ratio = (float)framebuffer_height / framebuffer_texture_height;
-
- framebuffer = (unsigned char*)malloc(framebuffer_width * framebuffer_height * 3);
-
- Backend_PostWindowCreation();
-
- return true;
- }
- else
- {
- Backend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Could not create window");
- }
-
- return false;
-}
-
-void WindowBackend_Software_DestroyWindow(void)
-{
- free(framebuffer);
- glDeleteTextures(1, &screen_texture_id);
- glfwDestroyWindow(window);
-}
-
-unsigned char* WindowBackend_Software_GetFramebuffer(size_t *pitch)
-{
- *pitch = framebuffer_width * 3;
-
- return framebuffer;
-}
-
-void WindowBackend_Software_Display(void)
-{
- glClear(GL_COLOR_BUFFER_BIT);
-
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, framebuffer_width, framebuffer_height, GL_RGB, GL_UNSIGNED_BYTE, framebuffer);
-
- glBegin(GL_TRIANGLE_STRIP);
- glTexCoord2f(0.0f, framebuffer_y_ratio);
- glVertex2f(-1.0f, -1.0f);
- glTexCoord2f(framebuffer_x_ratio, framebuffer_y_ratio);
- glVertex2f(1.0f, -1.0f);
- glTexCoord2f(0.0f, 0.0f);
- glVertex2f(-1.0f, 1.0f);
- glTexCoord2f(framebuffer_x_ratio, 0.0f);
- glVertex2f(1.0f, 1.0f);
- glEnd();
-
- glfwSwapBuffers(window);
-}
-
-void WindowBackend_Software_HandleWindowResize(unsigned int width, unsigned int height)
-{
- // Do some viewport trickery, to fit the framebuffer in the center of the screen
- GLint viewport_x;
- GLint viewport_y;
- GLsizei viewport_width;
- GLsizei viewport_height;
-
- if ((float)width / (float)height > (float)framebuffer_width / (float)framebuffer_height)
- {
- viewport_y = 0;
- viewport_height = height;
-
- viewport_width = framebuffer_width * ((float)height / (float)framebuffer_height);
- viewport_x = (width - viewport_width) / 2;
- }
- else
- {
- viewport_x = 0;
- viewport_width = width;
-
- viewport_height = framebuffer_height * ((float)width / (float)framebuffer_width);
- viewport_y = (height - viewport_height) / 2;
- }
-
- glViewport(viewport_x, viewport_y, viewport_width, viewport_height);
-}
--- a/src/Backends/Window/Null-Software.cpp
+++ /dev/null
@@ -1,39 +1,0 @@
-#include "../Window-Software.h"
-
-#include <stddef.h>
-#include <stdlib.h>
-
-static unsigned char *framebuffer;
-
-unsigned char* WindowBackend_Software_CreateWindow(const char *window_title, int screen_width, int screen_height, bool fullscreen, size_t *pitch)
-{
- (void)window_title;
- (void)fullscreen;
-
- framebuffer = (unsigned char*)malloc(screen_width * screen_height * 3);
-
- if (framebuffer != NULL)
- {
- *pitch = screen_width * 3;
-
- return framebuffer;
- }
-
- return NULL;
-}
-
-void WindowBackend_Software_DestroyWindow(void)
-{
- free(framebuffer);
-}
-
-void WindowBackend_Software_Display(void)
-{
-
-}
-
-void WindowBackend_Software_HandleWindowResize(unsigned int width, unsigned int height)
-{
- (void)width;
- (void)height;
-}
--- a/src/Backends/Window/SDL2-OpenGL3.cpp
+++ /dev/null
@@ -1,116 +1,0 @@
-#include "../Window-OpenGL.h"
-
-#include <stddef.h>
-#include <string>
-
-#ifdef USE_OPENGLES2
-#include <GLES2/gl2.h>
-#else
-#include <glad/glad.h>
-#endif
-#include "SDL.h"
-
-#include "../Misc.h"
-#include "../Shared/SDL2.h"
-#include "../../Resource.h"
-
-SDL_Window *window;
-
-static SDL_GLContext context;
-
-bool WindowBackend_OpenGL_CreateWindow(const char *window_title, int *screen_width, int *screen_height, bool fullscreen)
-{
-#ifdef USE_OPENGLES2
- if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES) < 0)
- Backend_PrintError("Couldn't set OpenGL context type to ES: %s", SDL_GetError());
-
- 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
- if (SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE) < 0)
- Backend_PrintError("Couldn't set OpenGL context type to core: %s", SDL_GetError());
-
- 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
-
- 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));
-
- if (window != NULL)
- {
- context = SDL_GL_CreateContext(window);
-
- if (context != NULL)
- {
- if (SDL_GL_MakeCurrent(window, context) == 0)
- {
- #ifndef USE_OPENGLES2
- if (gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress))
- {
- // Check if the platform supports OpenGL 3.2
- if (GLAD_GL_VERSION_3_2)
- {
- #endif
- Backend_PostWindowCreation();
-
- return true;
- #ifndef USE_OPENGLES2
- }
- else
- {
- Backend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Your system does not support OpenGL 3.2");
- }
- }
- else
- {
- Backend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Couldn't load OpenGL functions");
- }
- #endif
- }
- 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");
- }
-
- SDL_GL_DeleteContext(context);
- }
- 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");
- }
-
- SDL_DestroyWindow(window);
- }
- else
- {
- 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;
-}
-
-void WindowBackend_OpenGL_DestroyWindow(void)
-{
- SDL_GL_DeleteContext(context);
- SDL_DestroyWindow(window);
-}
-
-void WindowBackend_OpenGL_Display(void)
-{
- SDL_GL_SwapWindow(window);
-}
--- a/src/Backends/Window/SDL2-OpenGLES2.cpp
+++ /dev/null
@@ -1,2 +1,0 @@
-#define USE_OPENGLES2
-#include "Window-OpenGL3.cpp"
--- a/src/Backends/Window/SDL2-Software.cpp
+++ /dev/null
@@ -1,95 +1,0 @@
-#include "../Window-Software.h"
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <string>
-
-#include "SDL.h"
-
-#include "../Misc.h"
-#include "../Shared/SDL2.h"
-
-SDL_Window *window;
-
-static SDL_Surface *window_sdlsurface;
-static SDL_Surface *framebuffer_sdlsurface;
-
-bool WindowBackend_Software_CreateWindow(const char *window_title, int screen_width, int screen_height, bool fullscreen)
-{
- window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, screen_width, screen_height, 0);
-
- if (window != NULL)
- {
- if (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);
-
- 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();
-
- return true;
- }
- 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
- {
- 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());
- }
- }
- else
- {
- std::string error_message = std::string("Couldn't create window: ") + SDL_GetError();
- Backend_ShowMessageBox("Fatal error (software rendering backend)", error_message.c_str());
- }
-
- return false;
-}
-
-void WindowBackend_Software_DestroyWindow(void)
-{
- SDL_FreeSurface(framebuffer_sdlsurface);
- SDL_DestroyWindow(window);
-}
-
-unsigned char* WindowBackend_Software_GetFramebuffer(size_t *pitch)
-{
- *pitch = framebuffer_sdlsurface->pitch;
-
- return (unsigned char*)framebuffer_sdlsurface->pixels;
-}
-
-void WindowBackend_Software_Display(void)
-{
- if (SDL_BlitSurface(framebuffer_sdlsurface, NULL, window_sdlsurface, NULL) < 0)
- 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)width;
- (void)height;
-
- // https://wiki.libsdl.org/SDL_GetWindowSurface
- // We need to fetch a new surface pointer
- window_sdlsurface = SDL_GetWindowSurface(window);
-
- if (window_sdlsurface == NULL)
- Backend_PrintError("Couldn't get SDL surface associated with window: %s", SDL_GetError());
-}
--- a/src/Backends/Window/WiiU-Software.cpp
+++ /dev/null
@@ -1,269 +1,0 @@
-// Sexy new backend that bounces the software-rendered frame to the GPU,
-// eliminating V-tearing, and gaining support for rendering to the TV for
-// free!
-
-#include "../Window-Software.h"
-
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <gx2/display.h>
-#include <gx2/draw.h>
-#include <gx2/registers.h>
-#include <gx2/sampler.h>
-#include <gx2/texture.h>
-#include <gx2r/buffer.h>
-#include <gx2r/draw.h>
-#include <gx2r/resource.h>
-#include <gx2r/surface.h>
-#include <whb/gfx.h>
-
-#include "../../Attributes.h"
-
-#include "WiiUShaders/texture.gsh.h"
-
-typedef struct Viewport
-{
- float x;
- float y;
- float width;
- float height;
-} Viewport;
-
-static unsigned char *fake_framebuffer;
-
-static size_t fake_framebuffer_width;
-static size_t fake_framebuffer_height;
-
-static WHBGfxShaderGroup shader_group;
-
-static GX2RBuffer vertex_position_buffer;
-static GX2RBuffer texture_coordinate_buffer;
-
-static GX2Sampler sampler;
-
-static GX2Texture screen_texture;
-
-static Viewport tv_viewport;
-static Viewport drc_viewport;
-
-static void CalculateViewport(unsigned int actual_screen_width, unsigned int actual_screen_height, Viewport *viewport)
-{
- if ((float)actual_screen_width / (float)actual_screen_height > (float)fake_framebuffer_width / (float)fake_framebuffer_height)
- {
- viewport->y = 0.0f;
- viewport->height = actual_screen_height;
-
- viewport->width = fake_framebuffer_width * ((float)actual_screen_height / (float)fake_framebuffer_height);
- viewport->x = (actual_screen_width - viewport->width) / 2;
- }
- else
- {
- viewport->x = 0.0f;
- viewport->width = actual_screen_width;
-
- viewport->height = fake_framebuffer_height * ((float)actual_screen_width / (float)fake_framebuffer_width);
- viewport->y = (actual_screen_height - viewport->height) / 2;
- }
-}
-
-bool WindowBackend_Software_CreateWindow(const char *window_title, int screen_width, int screen_height, bool fullscreen)
-{
- (void)window_title;
- (void)fullscreen;
-
- fake_framebuffer_width = screen_width;
- fake_framebuffer_height = screen_height;
-
- fake_framebuffer = (unsigned char*)malloc(fake_framebuffer_width * fake_framebuffer_height * 3);
-
- if (fake_framebuffer != NULL)
- {
- WHBGfxInit();
-
- if (WHBGfxLoadGFDShaderGroup(&shader_group, 0, rtexture))
- {
- WHBGfxInitShaderAttribute(&shader_group, "input_vertex_coordinates", 0, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32);
- WHBGfxInitShaderAttribute(&shader_group, "input_texture_coordinates", 1, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32);
- WHBGfxInitFetchShader(&shader_group);
-
- // Initialise vertex position buffer
- const float vertex_positions[4][2] = {
- {-1.0f, 1.0f},
- { 1.0f, 1.0f},
- { 1.0f, -1.0f},
- {-1.0f, -1.0f}
- };
-
- vertex_position_buffer.flags = (GX2RResourceFlags)(GX2R_RESOURCE_BIND_VERTEX_BUFFER |
- GX2R_RESOURCE_USAGE_CPU_READ |
- GX2R_RESOURCE_USAGE_CPU_WRITE |
- GX2R_RESOURCE_USAGE_GPU_READ);
- vertex_position_buffer.elemSize = sizeof(vertex_positions[0]);
- vertex_position_buffer.elemCount = sizeof(vertex_positions) / sizeof(vertex_positions[0]);
- GX2RCreateBuffer(&vertex_position_buffer);
- memcpy(GX2RLockBufferEx(&vertex_position_buffer, (GX2RResourceFlags)0), vertex_positions, sizeof(vertex_positions));
- GX2RUnlockBufferEx(&vertex_position_buffer, (GX2RResourceFlags)0);
-
- // Initialise texture coordinate buffer
- const float texture_coordinates[4][2] = {
- {0.0f, 0.0f},
- {1.0f, 0.0f},
- {1.0f, 1.0f},
- {0.0f, 1.0f}
- };
-
- texture_coordinate_buffer.flags = (GX2RResourceFlags)(GX2R_RESOURCE_BIND_VERTEX_BUFFER |
- GX2R_RESOURCE_USAGE_CPU_READ |
- GX2R_RESOURCE_USAGE_CPU_WRITE |
- GX2R_RESOURCE_USAGE_GPU_READ);
- texture_coordinate_buffer.elemSize = sizeof(texture_coordinates[0]);
- texture_coordinate_buffer.elemCount = sizeof(texture_coordinates) / sizeof(texture_coordinates[0]);
- GX2RCreateBuffer(&texture_coordinate_buffer);
- memcpy(GX2RLockBufferEx(&texture_coordinate_buffer, (GX2RResourceFlags)0), texture_coordinates, sizeof(texture_coordinates));
- GX2RUnlockBufferEx(&texture_coordinate_buffer, (GX2RResourceFlags)0);
-
- // Initialise sampler
- GX2InitSampler(&sampler, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_POINT);
-
- // Initialise screen texture
- screen_texture.surface.width = fake_framebuffer_width;
- screen_texture.surface.height = fake_framebuffer_height;
- screen_texture.surface.format = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
- screen_texture.surface.depth = 1;
- screen_texture.surface.dim = GX2_SURFACE_DIM_TEXTURE_2D;
- screen_texture.surface.tileMode = GX2_TILE_MODE_LINEAR_ALIGNED;
- screen_texture.surface.mipLevels = 1;
- screen_texture.viewNumMips = 1;
- screen_texture.viewNumSlices = 1;
- screen_texture.compMap = 0x00010203;
- GX2CalcSurfaceSizeAndAlignment(&screen_texture.surface);
- GX2InitTextureRegs(&screen_texture);
-
- if (GX2RCreateSurface(&screen_texture.surface, (GX2RResourceFlags)(GX2R_RESOURCE_BIND_TEXTURE | GX2R_RESOURCE_BIND_COLOR_BUFFER |
- GX2R_RESOURCE_USAGE_CPU_WRITE | GX2R_RESOURCE_USAGE_CPU_READ |
- GX2R_RESOURCE_USAGE_GPU_WRITE | GX2R_RESOURCE_USAGE_GPU_READ)))
- {
- // Do some binding
- GX2SetPixelSampler(&sampler, shader_group.pixelShader->samplerVars[0].location);
- GX2SetPixelTexture(&screen_texture, shader_group.pixelShader->samplerVars[0].location);
- GX2RSetAttributeBuffer(&vertex_position_buffer, 0, vertex_position_buffer.elemSize, 0);
- GX2RSetAttributeBuffer(&texture_coordinate_buffer, 1, texture_coordinate_buffer.elemSize, 0);
-
- // Calculate centred viewports
- switch (GX2GetSystemTVScanMode())
- {
- // For now, we have to match WUT's broken behaviour (its `GX2TVScanMode`
- // enum is missing values, and the rest are off-by-one)
- //case GX2_TV_SCAN_MODE_576I:
- case GX2_TV_SCAN_MODE_480I: // Actually 576i
- case GX2_TV_SCAN_MODE_480P: // Actually 480i
- CalculateViewport(854, 480, &tv_viewport);
- break;
-
- case GX2_TV_SCAN_MODE_720P: // Actually 480p
- default: // Funnel the *real* 1080p into this
- CalculateViewport(1280, 720, &tv_viewport);
- break;
-
- case GX2_TV_SCAN_MODE_1080I: // Actually invalid
- case GX2_TV_SCAN_MODE_1080P: // Actually 1080i
- CalculateViewport(1920, 1080, &tv_viewport);
- break;
- }
-
- CalculateViewport(854, 480, &drc_viewport);
-
- return true;
- }
-
- GX2RDestroyBufferEx(&texture_coordinate_buffer, (GX2RResourceFlags)0);
- GX2RDestroyBufferEx(&vertex_position_buffer, (GX2RResourceFlags)0);
-
- WHBGfxFreeShaderGroup(&shader_group);
- }
-
- WHBGfxShutdown();
-
- free(fake_framebuffer);
- }
-
- return false;
-}
-
-void WindowBackend_Software_DestroyWindow(void)
-{
- GX2RDestroySurfaceEx(&screen_texture.surface, (GX2RResourceFlags)0);
-
- GX2RDestroyBufferEx(&texture_coordinate_buffer, (GX2RResourceFlags)0);
- GX2RDestroyBufferEx(&vertex_position_buffer, (GX2RResourceFlags)0);
-
- WHBGfxFreeShaderGroup(&shader_group);
-
- WHBGfxShutdown();
-
- free(fake_framebuffer);
-}
-
-unsigned char* WindowBackend_Software_GetFramebuffer(size_t *pitch)
-{
- *pitch = fake_framebuffer_width * 3;
-
- return fake_framebuffer;
-}
-
-ATTRIBUTE_HOT void WindowBackend_Software_Display(void)
-{
- // Convert frame from RGB24 to RGBA32, and upload it to the GPU texture
- unsigned char *framebuffer = (unsigned char*)GX2RLockSurfaceEx(&screen_texture.surface, 0, (GX2RResourceFlags)0);
-
- const unsigned char *in_pointer = fake_framebuffer;
-
- for (size_t y = 0; y < fake_framebuffer_height; ++y)
- {
- unsigned char *out_pointer = &framebuffer[screen_texture.surface.pitch * 4 * y];
-
- for (size_t x = 0; x < fake_framebuffer_width; ++x)
- {
- *out_pointer++ = *in_pointer++;
- *out_pointer++ = *in_pointer++;
- *out_pointer++ = *in_pointer++;
- *out_pointer++ = 0;
- }
- }
-
- GX2RUnlockSurfaceEx(&screen_texture.surface, 0, (GX2RResourceFlags)0);
-
- WHBGfxBeginRender();
-
- // Draw to the TV
- WHBGfxBeginRenderTV();
- GX2SetViewport(tv_viewport.x, tv_viewport.y, tv_viewport.width, tv_viewport.height, 0.0f, 1.0f);
- WHBGfxClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- GX2SetFetchShader(&shader_group.fetchShader);
- GX2SetVertexShader(shader_group.vertexShader);
- GX2SetPixelShader(shader_group.pixelShader);
- GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);
- WHBGfxFinishRenderTV();
-
- // Draw to the gamepad
- WHBGfxBeginRenderDRC();
- GX2SetViewport(drc_viewport.x, drc_viewport.y, drc_viewport.width, drc_viewport.height, 0.0f, 1.0f);
- WHBGfxClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- GX2SetFetchShader(&shader_group.fetchShader);
- GX2SetVertexShader(shader_group.vertexShader);
- GX2SetPixelShader(shader_group.pixelShader);
- GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);
- WHBGfxFinishRenderDRC();
-
- WHBGfxFinishRender();
-}
-
-void WindowBackend_Software_HandleWindowResize(unsigned int width, unsigned int height)
-{
- (void)width;
- (void)height;
-
- // The window doesn't resize on the Wii U
-}