Make Wii U software renderer support any res
This commit is contained in:
parent
31cd840297
commit
a12e971509
1 changed files with 64 additions and 5 deletions
|
@ -8,7 +8,9 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <gx2/display.h>
|
||||||
#include <gx2/draw.h>
|
#include <gx2/draw.h>
|
||||||
|
#include <gx2/registers.h>
|
||||||
#include <gx2/sampler.h>
|
#include <gx2/sampler.h>
|
||||||
#include <gx2/texture.h>
|
#include <gx2/texture.h>
|
||||||
#include <gx2r/buffer.h>
|
#include <gx2r/buffer.h>
|
||||||
|
@ -21,6 +23,14 @@
|
||||||
|
|
||||||
#include "shaders/texture.gsh.h"
|
#include "shaders/texture.gsh.h"
|
||||||
|
|
||||||
|
typedef struct Viewport
|
||||||
|
{
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float width;
|
||||||
|
float height;
|
||||||
|
} Viewport;
|
||||||
|
|
||||||
static unsigned char *fake_framebuffer;
|
static unsigned char *fake_framebuffer;
|
||||||
|
|
||||||
static size_t fake_framebuffer_width;
|
static size_t fake_framebuffer_width;
|
||||||
|
@ -35,6 +45,29 @@ static GX2Sampler sampler;
|
||||||
|
|
||||||
static GX2Texture screen_texture;
|
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)
|
bool WindowBackend_Software_CreateWindow(const char *window_title, int screen_width, int screen_height, bool fullscreen)
|
||||||
{
|
{
|
||||||
(void)window_title;
|
(void)window_title;
|
||||||
|
@ -57,10 +90,10 @@ bool WindowBackend_Software_CreateWindow(const char *window_title, int screen_wi
|
||||||
|
|
||||||
// Initialise vertex position buffer
|
// Initialise vertex position buffer
|
||||||
const float vertex_positions[4][2] = {
|
const float vertex_positions[4][2] = {
|
||||||
{-640.0f / 854.0f, 1.0f},
|
{-1.0f, 1.0f},
|
||||||
{ 640.0f / 854.0f, 1.0f},
|
{ 1.0f, 1.0f},
|
||||||
{ 640.0f / 854.0f, -1.0f},
|
{ 1.0f, -1.0f},
|
||||||
{-640.0f / 854.0f, -1.0f}
|
{-1.0f, -1.0f}
|
||||||
};
|
};
|
||||||
|
|
||||||
vertex_position_buffer.flags = (GX2RResourceFlags)(GX2R_RESOURCE_BIND_VERTEX_BUFFER |
|
vertex_position_buffer.flags = (GX2RResourceFlags)(GX2R_RESOURCE_BIND_VERTEX_BUFFER |
|
||||||
|
@ -118,6 +151,29 @@ bool WindowBackend_Software_CreateWindow(const char *window_title, int screen_wi
|
||||||
GX2RSetAttributeBuffer(&vertex_position_buffer, 0, vertex_position_buffer.elemSize, 0);
|
GX2RSetAttributeBuffer(&vertex_position_buffer, 0, vertex_position_buffer.elemSize, 0);
|
||||||
GX2RSetAttributeBuffer(&texture_coordinate_buffer, 1, texture_coordinate_buffer.elemSize, 0);
|
GX2RSetAttributeBuffer(&texture_coordinate_buffer, 1, texture_coordinate_buffer.elemSize, 0);
|
||||||
|
|
||||||
|
// Calculate centred viewports
|
||||||
|
switch (GX2GetSystemTVScanMode())
|
||||||
|
{
|
||||||
|
case GX2_TV_SCAN_MODE_NONE: // lolwut
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GX2_TV_SCAN_MODE_480I:
|
||||||
|
case GX2_TV_SCAN_MODE_480P:
|
||||||
|
CalculateViewport(854, 480, &tv_viewport);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GX2_TV_SCAN_MODE_720P:
|
||||||
|
CalculateViewport(1280, 720, &tv_viewport);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GX2_TV_SCAN_MODE_1080I:
|
||||||
|
case GX2_TV_SCAN_MODE_1080P:
|
||||||
|
CalculateViewport(1920, 1080, &tv_viewport);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
CalculateViewport(854, 480, &drc_viewport);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,10 +218,11 @@ ATTRIBUTE_HOT void WindowBackend_Software_Display(void)
|
||||||
unsigned char *framebuffer = (unsigned char*)GX2RLockSurfaceEx(&screen_texture.surface, 0, (GX2RResourceFlags)0);
|
unsigned char *framebuffer = (unsigned char*)GX2RLockSurfaceEx(&screen_texture.surface, 0, (GX2RResourceFlags)0);
|
||||||
|
|
||||||
const unsigned char *in_pointer = fake_framebuffer;
|
const unsigned char *in_pointer = fake_framebuffer;
|
||||||
unsigned char *out_pointer = framebuffer;
|
|
||||||
|
|
||||||
for (size_t y = 0; y < fake_framebuffer_height; ++y)
|
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)
|
for (size_t x = 0; x < fake_framebuffer_width; ++x)
|
||||||
{
|
{
|
||||||
*out_pointer++ = *in_pointer++;
|
*out_pointer++ = *in_pointer++;
|
||||||
|
@ -181,6 +238,7 @@ ATTRIBUTE_HOT void WindowBackend_Software_Display(void)
|
||||||
|
|
||||||
// Draw to the TV
|
// Draw to the TV
|
||||||
WHBGfxBeginRenderTV();
|
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);
|
WHBGfxClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
GX2SetFetchShader(&shader_group.fetchShader);
|
GX2SetFetchShader(&shader_group.fetchShader);
|
||||||
GX2SetVertexShader(shader_group.vertexShader);
|
GX2SetVertexShader(shader_group.vertexShader);
|
||||||
|
@ -190,6 +248,7 @@ ATTRIBUTE_HOT void WindowBackend_Software_Display(void)
|
||||||
|
|
||||||
// Draw to the gamepad
|
// Draw to the gamepad
|
||||||
WHBGfxBeginRenderDRC();
|
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);
|
WHBGfxClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
GX2SetFetchShader(&shader_group.fetchShader);
|
GX2SetFetchShader(&shader_group.fetchShader);
|
||||||
GX2SetVertexShader(shader_group.vertexShader);
|
GX2SetVertexShader(shader_group.vertexShader);
|
||||||
|
|
Loading…
Add table
Reference in a new issue