wiiu: replace WhbGfx

This commit is contained in:
GaryOderNichts 2022-08-23 13:05:52 +02:00 committed by Dave Murphy
parent 5b526cc458
commit 4d04202dfc
No known key found for this signature in database
GPG Key ID: F7FD5492264BB9D0
11 changed files with 585 additions and 76 deletions

View File

@ -167,6 +167,13 @@ void WIIU_SDL_CreateWindowTex(SDL_Renderer * renderer, SDL_Window * window)
WIIU_SDL_CreateTexture(renderer, &data->windowTex);
}
void WIIU_SDL_DestroyWindowTex(SDL_Renderer * renderer, SDL_Window * window)
{
WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata;
WIIU_SDL_DestroyTexture(renderer, &data->windowTex);
}
int WIIU_SDL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
{
WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata;
@ -175,6 +182,9 @@ int WIIU_SDL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
WIIU_TextureData *tdata = (WIIU_TextureData *)((texture) ? texture->driverdata
: data->windowTex.driverdata);
/* make sure we're using the correct renderer ctx */
GX2SetContextState(data->ctx);
/* Wait for the texture rendering to finish */
WIIU_TextureCheckWaitRendering(data, tdata);
@ -189,11 +199,14 @@ int WIIU_SDL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
void WIIU_SDL_DestroyRenderer(SDL_Renderer * renderer)
{
WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata;
WIIU_VideoData *videodata = (WIIU_VideoData *) SDL_GetVideoDevice()->driverdata;
GX2DrawDone();
if (videodata->hasForeground) {
GX2DrawDone();
WIIU_FreeRenderData(data);
WIIU_TextureDoneRendering(data);
WIIU_FreeRenderData(data);
WIIU_TextureDoneRendering(data);
}
free(data->ctx);

View File

@ -31,6 +31,9 @@
#include "SDL_pixels.h"
#include "SDL_shaders_wiiu.h"
#include "../../video/SDL_sysvideo.h"
#include "../../video/wiiu/SDL_wiiuvideo.h"
#include <gx2r/buffer.h>
#include <gx2/context.h>
#include <gx2/sampler.h>
@ -99,7 +102,7 @@ struct WIIU_TextureData
GX2Sampler sampler;
GX2Texture texture;
GX2ColorBuffer cbuf;
int isRendering;
SDL_bool isRendering;
};
/* Ask texture driver to allocate texture's memory from MEM1 */
@ -136,6 +139,7 @@ void WIIU_SDL_DestroyRenderer(SDL_Renderer * renderer);
/* Driver internal functions */
void WIIU_SDL_CreateWindowTex(SDL_Renderer * renderer, SDL_Window * window);
void WIIU_SDL_DestroyWindowTex(SDL_Renderer * renderer, SDL_Window * window);
/* Utility/helper functions */
static inline GX2RBuffer * WIIU_AllocRenderData(WIIU_RenderData *r, GX2RBuffer buffer)
@ -166,7 +170,7 @@ static inline void WIIU_FreeRenderData(WIIU_RenderData *r)
static inline void WIIU_TextureStartRendering(WIIU_RenderData *r, WIIU_TextureData *t)
{
WIIU_TextureDrawData *d = SDL_malloc(sizeof(WIIU_TextureDrawData));
t->isRendering = 1;
t->isRendering = SDL_TRUE;
d->texdata = t;
d->next = r->listdraw;
r->listdraw = d;
@ -177,7 +181,7 @@ static inline void WIIU_TextureDoneRendering(WIIU_RenderData *r)
while (r->listdraw) {
WIIU_TextureDrawData *d = r->listdraw;
r->listdraw = r->listdraw->next;
d->texdata->isRendering = 0;
d->texdata->isRendering = SDL_FALSE;
SDL_free(d);
}
}

View File

@ -31,60 +31,63 @@
#include <gx2/registers.h>
#include <gx2/state.h>
#include <gx2/draw.h>
#include <gx2/swap.h>
#include <gx2/display.h>
#include <gx2r/buffer.h>
#include <gx2r/draw.h>
#define SCREEN_WIDTH 1280
#define SCREEN_HEIGHT 720
void WIIU_SDL_RenderPresent(SDL_Renderer * renderer)
{
WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata;
WIIU_TextureData *tdata = (WIIU_TextureData *) data->windowTex.driverdata;
Uint32 flags = SDL_GetWindowFlags(renderer->window);
int win_x, win_y, win_w, win_h;
if (renderer->info.flags & SDL_RENDERER_PRESENTVSYNC) {
/* NOTE watch libwhb's source to ensure this call only does vsync */
WHBGfxBeginRender();
}
/* Calculate and save positions TODO: make use of the window position */
if (flags & SDL_WINDOW_FULLSCREEN) {
win_x = 0;
win_y = 0;
win_w = SCREEN_WIDTH;
win_h = SCREEN_HEIGHT;
} else {
/* Center */
SDL_GetWindowSize(renderer->window, &win_w, &win_h);
win_x = (SCREEN_WIDTH - win_w) / 2;
win_y = (SCREEN_HEIGHT - win_h) / 2;
}
/* Only render to TV if the window is *not* drc-only */
if (!(flags & SDL_WINDOW_WIIU_GAMEPAD_ONLY)) {
WHBGfxBeginRenderTV();
GX2CopySurface(&tdata->texture.surface, 0, 0, &WHBGfxGetTVColourBuffer()->surface, 0, 0);
GX2SetContextState(data->ctx);
WHBGfxFinishRenderTV();
GX2CopyColorBufferToScanBuffer(&tdata->cbuf, GX2_SCAN_TARGET_TV);
}
if (!(flags & SDL_WINDOW_WIIU_TV_ONLY)) {
WHBGfxBeginRenderDRC();
GX2CopySurface(&tdata->texture.surface, 0, 0, &WHBGfxGetDRCColourBuffer()->surface, 0, 0);
GX2SetContextState(data->ctx);
WHBGfxFinishRenderDRC();
GX2CopyColorBufferToScanBuffer(&tdata->cbuf, GX2_SCAN_TARGET_DRC);
}
WHBGfxFinishRender();
/* Swap buffers */
GX2SwapScanBuffers();
GX2Flush();
/* Restore SDL context state */
GX2SetContextState(data->ctx);
/* TV and DRC can now be enabled after the first frame was drawn */
GX2SetTVEnable(TRUE);
GX2SetDRCEnable(TRUE);
/* Wait for vsync */
if (renderer->info.flags & SDL_RENDERER_PRESENTVSYNC) {
uint32_t swap_count, flip_count;
OSTime last_flip, last_vsync;
uint32_t wait_count = 0;
while (true) {
GX2GetSwapStatus(&swap_count, &flip_count, &last_flip, &last_vsync);
if (flip_count >= swap_count) {
break;
}
if (wait_count >= 10) {
/* GPU timed out */
break;
}
wait_count++;
GX2WaitForVsync();
}
}
/* Free the list of render and draw data */
WIIU_FreeRenderData(data);
WIIU_TextureDoneRendering(data);
/* Restore SDL context state */
GX2SetContextState(data->ctx);
}
#endif /* SDL_VIDEO_RENDER_WIIU */

View File

@ -351,12 +351,16 @@ int WIIU_SDL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, vo
{
WIIU_RenderData* data = (WIIU_RenderData*) renderer->driverdata;
/* make sure we're using the correct renderer ctx */
WIIU_SDL_SetRenderTarget(renderer, renderer->target);
data->drawState.target = renderer->target;
if (!data->drawState.target) {
int w, h;
SDL_GL_GetDrawableSize(renderer->window, &w, &h);
if ((w != data->drawState.drawableWidth) || (h != data->drawState.drawableHeight)) {
data->drawState.viewportDirty = SDL_TRUE; // if the window dimensions changed, invalidate the current viewport, etc.
/* if the window dimensions changed, invalidate the current viewport, etc. */
data->drawState.viewportDirty = SDL_TRUE;
data->drawState.cliprectDirty = SDL_TRUE;
data->drawState.drawableWidth = w;
data->drawState.drawableHeight = h;

View File

@ -198,6 +198,13 @@ void WIIU_SDL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
/* Wait for the texture rendering to finish */
WIIU_TextureCheckWaitRendering(data, tdata);
if (data->drawState.texture == texture) {
data->drawState.texture = NULL;
}
if (data->drawState.target == texture) {
data->drawState.target = NULL;
}
GX2RDestroySurfaceEx(&tdata->cbuf.surface, 0);
GX2RDestroySurfaceEx(&tdata->texture.surface, 0);

View File

@ -38,7 +38,7 @@ void WIIU_SDL_CreateShaders(void)
WHBGfxLoadGFDShaderGroup(colorShader, 0, colorShader_gsh);
WHBGfxInitShaderAttribute(colorShader, "a_position", 0, 0, GX2_ATTRIB_FORMAT_FLOAT_32_32);
WHBGfxInitShaderAttribute(colorShader, "a_color", 0, 8, GX2_ATTRIB_FORMAT_FLOAT_32_32_32_32);
WHBGfxInitShaderAttribute(colorShader, "a_color", 0, 8, GX2_ATTRIB_FORMAT_UNORM_8_8_8_8);
WHBGfxInitFetchShader(colorShader);
WHBGfxLoadGFDShaderGroup(textureShader, 0, textureShader_gsh);

View File

@ -2,7 +2,7 @@
; $SPI_VS_OUT_CONFIG.VS_EXPORT_COUNT = 0
; $NUM_SPI_VS_OUT_ID = 1
; vColor
; v_color
; $SPI_VS_OUT_ID[0].SEMANTIC_0 = 0
; C0

View File

@ -0,0 +1,203 @@
/*
Simple DirectMedia Layer
Copyright (c) 2015-present devkitPro, wut Authors
Copyright (C) 2022 GaryOderNichts <garyodernichts@gmail.com>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_WIIU
#include "SDL_wiiu_gfx_heap.h"
#include <stdio.h>
#include <malloc.h>
#include <coreinit/memheap.h>
#include <coreinit/memdefaultheap.h>
#include <coreinit/memexpheap.h>
#include <coreinit/memfrmheap.h>
#define FRM_HEAP_STATE_TAG 0x53444C32 // 'SDL2'
static MEMHeapHandle GfxHeap_MEM1 = NULL;
static MEMHeapHandle GfxHeap_Foreground = NULL;
int WIIU_GfxHeap_MEM1Init(void)
{
MEMHeapHandle heap = MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM1);
uint32_t size;
void *base;
if (!MEMRecordStateForFrmHeap(heap, FRM_HEAP_STATE_TAG)) {
printf("%s: MEMRecordStateForFrmHeap failed\n", __FUNCTION__);
return -1;
}
size = MEMGetAllocatableSizeForFrmHeapEx(heap, 4);
if (!size) {
printf("%s: MEMGetAllocatableSizeForFrmHeapEx == 0\n", __FUNCTION__);
return -1;
}
base = MEMAllocFromFrmHeapEx(heap, size, 4);
if (!base) {
printf("%s: MEMAllocFromFrmHeapEx(heap, 0x%X, 4) failed\n", __FUNCTION__, size);
return -1;
}
GfxHeap_MEM1 = MEMCreateExpHeapEx(base, size, 0);
if (!GfxHeap_MEM1) {
printf("%s: MEMCreateExpHeapEx(%p, 0x%X, 0) failed\n", __FUNCTION__, base, size);
return -1;
}
return 0;
}
int WIIU_GfxHeap_MEM1Destroy(void)
{
MEMHeapHandle heap = MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM1);
if (GfxHeap_MEM1) {
MEMDestroyExpHeap(GfxHeap_MEM1);
GfxHeap_MEM1 = NULL;
}
MEMFreeByStateToFrmHeap(heap, FRM_HEAP_STATE_TAG);
return 0;
}
int WIIU_GfxHeap_ForegroundInit(void)
{
MEMHeapHandle heap = MEMGetBaseHeapHandle(MEM_BASE_HEAP_FG);
uint32_t size;
void *base;
size = MEMGetAllocatableSizeForFrmHeapEx(heap, 4);
if (!size) {
printf("%s: MEMAllocFromFrmHeapEx(heap, 0x%X, 4)\n", __FUNCTION__, size);
return -1;
}
base = MEMAllocFromFrmHeapEx(heap, size, 4);
if (!base) {
printf("%s: MEMGetAllocatableSizeForFrmHeapEx == 0\n", __FUNCTION__);
return -1;
}
GfxHeap_Foreground = MEMCreateExpHeapEx(base, size, 0);
if (!GfxHeap_Foreground) {
printf("%s: MEMCreateExpHeapEx(%p, 0x%X, 0)\n", __FUNCTION__, base, size);
return -1;
}
return 0;
}
int WIIU_GfxHeap_ForegroundDestroy(void)
{
MEMHeapHandle foreground = MEMGetBaseHeapHandle(MEM_BASE_HEAP_FG);
if (GfxHeap_Foreground) {
MEMDestroyExpHeap(GfxHeap_Foreground);
GfxHeap_Foreground = NULL;
}
MEMFreeToFrmHeap(foreground, MEM_FRM_HEAP_FREE_ALL);
return 0;
}
void *WIIU_GfxHeap_MEM1Alloc(uint32_t align, uint32_t size)
{
void *block;
if (!GfxHeap_MEM1) {
return NULL;
}
if (align < 4) {
align = 4;
}
block = MEMAllocFromExpHeapEx(GfxHeap_MEM1, size, align);
return block;
}
void WIIU_GfxHeap_MEM1Free(void *block)
{
if (!GfxHeap_MEM1) {
return;
}
MEMFreeToExpHeap(GfxHeap_MEM1, block);
}
void *WIIU_GfxHeap_ForegroundAlloc(uint32_t align, uint32_t size)
{
void *block;
if (!GfxHeap_Foreground) {
return NULL;
}
if (align < 4) {
align = 4;
}
block = MEMAllocFromExpHeapEx(GfxHeap_Foreground, size, align);
return block;
}
void WIIU_GfxHeap_ForegroundFree(void *block)
{
if (!GfxHeap_Foreground) {
return;
}
MEMFreeToExpHeap(GfxHeap_Foreground, block);
}
void *WIIU_GfxHeap_GX2RAlloc(GX2RResourceFlags flags, uint32_t size, uint32_t alignment)
{
// Color, depth, scan buffers all belong in MEM1
if ((flags & (GX2R_RESOURCE_BIND_COLOR_BUFFER
| GX2R_RESOURCE_BIND_DEPTH_BUFFER
| GX2R_RESOURCE_BIND_SCAN_BUFFER
| GX2R_RESOURCE_USAGE_FORCE_MEM1))
&& !(flags & GX2R_RESOURCE_USAGE_FORCE_MEM2)) {
return WIIU_GfxHeap_MEM1Alloc(alignment, size);
} else {
return memalign(alignment, size);
}
}
void WIIU_GfxHeap_GX2RFree(GX2RResourceFlags flags, void *block)
{
if ((flags & (GX2R_RESOURCE_BIND_COLOR_BUFFER
| GX2R_RESOURCE_BIND_DEPTH_BUFFER
| GX2R_RESOURCE_BIND_SCAN_BUFFER
| GX2R_RESOURCE_USAGE_FORCE_MEM1))
&& !(flags & GX2R_RESOURCE_USAGE_FORCE_MEM2)) {
return WIIU_GfxHeap_MEM1Free(block);
} else {
return free(block);
}
}
#endif /* SDL_VIDEO_DRIVER_WIIU */

View File

@ -0,0 +1,53 @@
/*
Simple DirectMedia Layer
Copyright (c) 2015-present devkitPro, wut Authors
Copyright (C) 2022 GaryOderNichts <garyodernichts@gmail.com>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#ifndef SDL_wiiu_gfx_heap_h
#define SDL_wiiu_gfx_heap_h
#if SDL_VIDEO_DRIVER_WIIU
#include <gx2r/mem.h>
int WIIU_GfxHeap_MEM1Init(void);
int WIIU_GfxHeap_MEM1Destroy(void);
int WIIU_GfxHeap_ForegroundInit(void);
int WIIU_GfxHeap_ForegroundDestroy(void);
void *WIIU_GfxHeap_MEM1Alloc(uint32_t align, uint32_t size);
void WIIU_GfxHeap_MEM1Free(void *block);
void *WIIU_GfxHeap_ForegroundAlloc(uint32_t align, uint32_t size);
void WIIU_GfxHeap_ForegroundFree(void *block);
void *WIIU_GfxHeap_GX2RAlloc(GX2RResourceFlags flags, uint32_t size, uint32_t alignment);
void WIIU_GfxHeap_GX2RFree(GX2RResourceFlags flags, void *block);
#endif /* SDL_VIDEO_DRIVER_WIIU */
#endif /* SDL_wiiu_gfx_heap_h */

View File

@ -2,6 +2,7 @@
Simple DirectMedia Layer
Copyright (C) 2018-2018 Ash Logan <ash@heyquark.com>
Copyright (C) 2018-2018 rw-r-r-0644 <r.r.qwertyuiop.r.r@gmail.com>
Copyright (C) 2022 GaryOderNichts <garyodernichts@gmail.com>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -20,13 +21,6 @@
3. This notice may not be removed or altered from any source distribution.
*/
/* This is basically just a stub at this point - all the magic happens in
* SDL_Render, and the textureframebuffer stuff in SDL_video.c.
* Potentially more could/should be done here, video modes and things.
* Some design work will need to go into the responsibilities of render
* vs video.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_WIIU
@ -37,81 +31,275 @@
#include "SDL_syswm.h"
#include "SDL_loadso.h"
#include "SDL_events.h"
#include "SDL_render.h"
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_keyboard_c.h"
#include "../../events/SDL_events_c.h"
#include "SDL_wiiuvideo.h"
#include "SDL_wiiu_gfx_heap.h"
#include "../../render/wiiu/SDL_render_wiiu.h"
#include <whb/proc.h>
#include <whb/gfx.h>
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <stdint.h>
#include <proc_ui/procui.h>
static int WIIU_VideoInit(_THIS);
static int WIIU_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode);
static void WIIU_VideoQuit(_THIS);
static void WIIU_PumpEvents(_THIS);
#include <gx2/context.h>
#include <gx2/display.h>
#include <gx2/event.h>
#include <gx2/mem.h>
#include <gx2/state.h>
#include <gx2r/mem.h>
#include <gx2r/surface.h>
static int using_whb_proc = 0;
#define DRC_SCREEN_WIDTH 854
#define DRC_SCREEN_HEIGHT 480
#define SCREEN_WIDTH 1280
#define SCREEN_HEIGHT 720
static int WIIU_ForegroundAcquired(_THIS)
{
WIIU_VideoData *videodata = (WIIU_VideoData *) _this->driverdata;
SDL_Window* window = _this->windows;
videodata->hasForeground = SDL_TRUE;
// initialize gfx heaps once in forground
if (WIIU_GfxHeap_ForegroundInit() != 0) {
return -1;
}
if (WIIU_GfxHeap_MEM1Init() != 0) {
return -1;
}
// allocate and set scanbuffers
videodata->tvScanBuffer = WIIU_GfxHeap_ForegroundAlloc(GX2_SCAN_BUFFER_ALIGNMENT, videodata->tvScanBufferSize);
if (!videodata->tvScanBuffer) {
return -1;
}
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, videodata->tvScanBuffer, videodata->tvScanBufferSize);
GX2SetTVBuffer(videodata->tvScanBuffer, videodata->tvScanBufferSize, videodata->tvRenderMode, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8, GX2_BUFFERING_MODE_DOUBLE);
videodata->drcScanBuffer = WIIU_GfxHeap_ForegroundAlloc(GX2_SCAN_BUFFER_ALIGNMENT, videodata->drcScanBufferSize);
if (!videodata->drcScanBuffer) {
return -1;
}
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, videodata->drcScanBuffer, videodata->drcScanBufferSize);
GX2SetDRCBuffer(videodata->drcScanBuffer, videodata->drcScanBufferSize, videodata->drcRenderMode, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8, GX2_BUFFERING_MODE_DOUBLE);
// TODO recreate MEM1 surfaces for all windows
while (window) {
SDL_Renderer* renderer = SDL_GetRenderer(window);
//WIIU_SDL_CreateWindowTex(renderer, window);
window = window->next;
}
return 0;
}
static int WIIU_ForegroundReleased(_THIS)
{
WIIU_VideoData *videodata = (WIIU_VideoData *) _this->driverdata;
SDL_Window* window = _this->windows;
// make sure the GPU is done drawing
GX2DrawDone();
if (videodata->tvScanBuffer) {
WIIU_GfxHeap_ForegroundFree(videodata->tvScanBuffer);
videodata->tvScanBuffer = NULL;
}
if (videodata->drcScanBuffer) {
WIIU_GfxHeap_ForegroundFree(videodata->drcScanBuffer);
videodata->drcScanBuffer = NULL;
}
// TODO destroy MEM1 surfaces for all windows
while (window) {
SDL_Renderer* renderer = SDL_GetRenderer(window);
//WIIU_SDL_DestroyWindowTex(renderer, window);
window = window->next;
}
WIIU_GfxHeap_MEM1Destroy();
WIIU_GfxHeap_ForegroundDestroy();
videodata->hasForeground = SDL_FALSE;
return 0;
}
static int WIIU_VideoInit(_THIS)
{
WIIU_VideoData *videodata = (WIIU_VideoData *) _this->driverdata;
uint32_t unk;
SDL_DisplayMode mode;
uint32_t* initAttribs;
// check if the user already set up procui or if we should handle it
if (!ProcUIIsRunning()) {
WHBProcInit();
using_whb_proc = 1;
videodata->handleProcUI = SDL_TRUE;
}
WHBGfxInit();
// add default mode (1280x720)
mode.format = SDL_PIXELFORMAT_RGBA8888;
mode.w = SCREEN_WIDTH;
mode.h = SCREEN_HEIGHT;
mode.refresh_rate = 60;
mode.driverdata = NULL;
if (SDL_AddBasicVideoDisplay(&mode) < 0) {
return -1;
// allocate command buffer pool
videodata->commandBufferPool = memalign(GX2_COMMAND_BUFFER_ALIGNMENT, GX2_COMMAND_BUFFER_SIZE);
if (!videodata->commandBufferPool) {
return SDL_OutOfMemory();
}
SDL_AddDisplayMode(&_this->displays[0], &mode);
// initialize GX2
initAttribs = (uint32_t[]) {
GX2_INIT_CMD_BUF_BASE, (uintptr_t) videodata->commandBufferPool,
GX2_INIT_CMD_BUF_POOL_SIZE, GX2_COMMAND_BUFFER_SIZE,
GX2_INIT_ARGC, 0,
GX2_INIT_ARGV, 0,
GX2_INIT_END
};
GX2Init(initAttribs);
// figure out the TV render mode and size
switch(GX2GetSystemTVScanMode()) {
case GX2_TV_SCAN_MODE_480I:
case GX2_TV_SCAN_MODE_480P:
videodata->tvRenderMode = GX2_TV_RENDER_MODE_WIDE_480P;
videodata->tvWidth = 854;
videodata->tvHeight = 480;
break;
case GX2_TV_SCAN_MODE_1080I:
case GX2_TV_SCAN_MODE_1080P:
videodata->tvRenderMode = GX2_TV_RENDER_MODE_WIDE_1080P;
videodata->tvWidth = 1920;
videodata->tvHeight = 1080;
break;
case GX2_TV_SCAN_MODE_720P:
default:
videodata->tvRenderMode = GX2_TV_RENDER_MODE_WIDE_720P;
videodata->tvWidth = 1280;
videodata->tvHeight = 720;
break;
}
videodata->drcRenderMode = GX2GetSystemDRCScanMode();
// calculate the scanbuffer sizes
GX2CalcTVSize(videodata->tvRenderMode, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8, GX2_BUFFERING_MODE_DOUBLE, &videodata->tvScanBufferSize, &unk);
GX2CalcDRCSize(videodata->drcRenderMode, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8, GX2_BUFFERING_MODE_DOUBLE, &videodata->drcScanBufferSize, &unk);
// set GX2R allocator for the gfx heap
GX2RSetAllocator(&WIIU_GfxHeap_GX2RAlloc, &WIIU_GfxHeap_GX2RFree);
// register callbacks for acquiring and releasing foreground
ProcUIRegisterCallback(PROCUI_CALLBACK_ACQUIRE, (ProcUICallback) WIIU_ForegroundAcquired, _this, 100);
ProcUIRegisterCallback(PROCUI_CALLBACK_RELEASE, (ProcUICallback) WIIU_ForegroundReleased, _this, 100);
// if this is running, the application is already in foreground so call the callback
if (WIIU_ForegroundAcquired(_this) != 0) {
free(videodata->commandBufferPool);
videodata->commandBufferPool = NULL;
return SDL_OutOfMemory();
}
GX2SetTVScale(videodata->tvWidth, videodata->tvHeight);
GX2SetDRCScale(DRC_SCREEN_WIDTH, DRC_SCREEN_HEIGHT);
// add tv display
SDL_zero(mode);
mode.format = SDL_PIXELFORMAT_RGBA8888;
mode.w = videodata->tvWidth;
mode.h = videodata->tvHeight;
mode.refresh_rate = 60;
SDL_AddBasicVideoDisplay(&mode);
// add drc display
SDL_zero(mode);
mode.format = SDL_PIXELFORMAT_RGBA8888;
mode.w = DRC_SCREEN_WIDTH;
mode.h = DRC_SCREEN_HEIGHT;
mode.refresh_rate = 60;
SDL_AddBasicVideoDisplay(&mode);
return 0;
}
static void WIIU_VideoQuit(_THIS)
{
WHBGfxShutdown();
if (using_whb_proc) WHBProcShutdown();
WIIU_VideoData *videodata = (WIIU_VideoData *) _this->driverdata;
// if we're in foreground, destroy foreground data
if (videodata->hasForeground) {
WIIU_ForegroundReleased(_this);
}
// shutdown GX2 and free command buffer
GX2Shutdown();
if (videodata->commandBufferPool) {
free(videodata->commandBufferPool);
videodata->commandBufferPool = NULL;
}
if (videodata->handleProcUI) {
WHBProcShutdown();
}
}
static int WIIU_CreateSDLWindow(_THIS, SDL_Window *window)
static int WIIU_CreateSDLWindow(_THIS, SDL_Window * window)
{
SDL_SetMouseFocus(window);
SDL_SetKeyboardFocus(window);
// focus the window
SDL_SetMouseFocus(window);
SDL_SetKeyboardFocus(window);
return 0;
}
static int WIIU_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
static void WIIU_SetWindowSize(_THIS, SDL_Window * window)
{
}
static void WIIU_DestroyWindow(_THIS, SDL_Window * window)
{
}
static void WIIU_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
{
// we currently only have one mode per display, which is the current one
SDL_AddDisplayMode(display, &display->current_mode);
}
static int WIIU_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
{
return 0;
}
static void WIIU_PumpEvents(_THIS)
{
WIIU_VideoData *videodata = (WIIU_VideoData *) _this->driverdata;
if (videodata->handleProcUI) {
if (!WHBProcIsRunning()) {
SDL_SendQuit();
}
}
}
static void WIIU_DeleteDevice(SDL_VideoDevice *device)
{
SDL_free(device->driverdata);
SDL_free(device);
}
static SDL_VideoDevice *WIIU_CreateDevice(int devindex)
{
SDL_VideoDevice *device;
WIIU_VideoData *videodata;
device = (SDL_VideoDevice*) SDL_calloc(1, sizeof(SDL_VideoDevice));
if(!device) {
@ -119,11 +307,22 @@ static SDL_VideoDevice *WIIU_CreateDevice(int devindex)
return NULL;
}
videodata = (WIIU_VideoData*) SDL_calloc(1, sizeof(WIIU_VideoData));
if(!videodata) {
SDL_OutOfMemory();
return NULL;
}
device->driverdata = videodata;
device->VideoInit = WIIU_VideoInit;
device->VideoQuit = WIIU_VideoQuit;
device->CreateSDLWindow = WIIU_CreateSDLWindow;
device->SetWindowSize = WIIU_SetWindowSize;
device->DestroyWindow = WIIU_DestroyWindow;
device->GetDisplayModes = WIIU_GetDisplayModes;
device->SetDisplayMode = WIIU_SetDisplayMode;
device->PumpEvents = WIIU_PumpEvents;
device->CreateSDLWindow = WIIU_CreateSDLWindow;
device->free = WIIU_DeleteDevice;

View File

@ -2,6 +2,7 @@
Simple DirectMedia Layer
Copyright (C) 2018-2018 Ash Logan <ash@heyquark.com>
Copyright (C) 2018-2018 Roberto Van Eeden <r.r.qwertyuiop.r.r@gmail.com>
Copyright (C) 2022 GaryOderNichts <garyodernichts@gmail.com>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -27,7 +28,29 @@
#if SDL_VIDEO_DRIVER_WIIU
#include <gx2/surface.h>
typedef struct WIIU_VideoData WIIU_VideoData;
struct WIIU_VideoData
{
// indicate if we're handling procui in SDL's events
SDL_bool handleProcUI;
SDL_bool hasForeground;
void *commandBufferPool;
GX2TVRenderMode tvRenderMode;
uint32_t tvWidth;
uint32_t tvHeight;
void *tvScanBuffer;
uint32_t tvScanBufferSize;
GX2DrcRenderMode drcRenderMode;
void *drcScanBuffer;
uint32_t drcScanBufferSize;
};
#endif /* SDL_VIDEO_DRIVER_WIIU */