mirror of
https://github.com/yawut/SDL.git
synced 2026-04-25 07:52:57 -05:00
157 lines
5.4 KiB
C
157 lines
5.4 KiB
C
/*
|
|
Simple DirectMedia Layer
|
|
Copyright (C) 2018-2019 Ash Logan <ash@heyquark.com>
|
|
Copyright (C) 2018-2019 Roberto Van Eeden <r.r.qwertyuiop.r.r@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_RENDER_WIIU
|
|
|
|
#include "../../video/wiiu/wiiu_shaders.h"
|
|
#include "../SDL_sysrender.h"
|
|
#include "SDL_render_wiiu.h"
|
|
|
|
#include <whb/gfx.h>
|
|
#include <gx2/registers.h>
|
|
#include <gx2/state.h>
|
|
#include <gx2/draw.h>
|
|
#include <gx2r/buffer.h>
|
|
#include <gx2r/draw.h>
|
|
|
|
#define SCREEN_WIDTH 1280
|
|
#define SCREEN_HEIGHT 720
|
|
|
|
static const WIIUVec4 u_viewSize = {.x = (float)SCREEN_WIDTH, .y = (float)SCREEN_HEIGHT};
|
|
|
|
static void render_scene(SDL_Renderer * renderer)
|
|
{
|
|
WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata;
|
|
WIIU_TextureData *tdata = (WIIU_TextureData *) data->windowTex.driverdata;
|
|
|
|
float tex_w = tdata->u_texSize.x;
|
|
float tex_h = tdata->u_texSize.y;
|
|
int win_x, win_y, win_w, win_h;
|
|
GX2RBuffer *a_position, *a_texCoord;
|
|
WIIUVec2 *a_position_vals, *a_texCoord_vals;
|
|
|
|
/* Allocate attribute buffers */
|
|
a_position = WIIU_AllocRenderData(data, (GX2RBuffer) {
|
|
.flags =
|
|
GX2R_RESOURCE_BIND_VERTEX_BUFFER |
|
|
GX2R_RESOURCE_USAGE_CPU_WRITE,
|
|
.elemSize = sizeof(WIIUVec2), /* float x/y for each corner */
|
|
.elemCount = 4, /* 4 corners */
|
|
});
|
|
a_texCoord = WIIU_AllocRenderData(data, (GX2RBuffer) {
|
|
.flags =
|
|
GX2R_RESOURCE_BIND_VERTEX_BUFFER |
|
|
GX2R_RESOURCE_USAGE_CPU_WRITE,
|
|
.elemSize = sizeof(WIIUVec2), // float x/y for each corner
|
|
.elemCount = 4, // 4 corners
|
|
});
|
|
|
|
/* Calculate and save positions */
|
|
if (SDL_GetWindowFlags(renderer->window) & 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;
|
|
}
|
|
|
|
a_position_vals = GX2RLockBufferEx(a_position, 0);
|
|
a_position_vals[0] = (WIIUVec2) {
|
|
.x = win_x, .y = win_y
|
|
};
|
|
a_position_vals[1] = (WIIUVec2) {
|
|
.x = win_x + win_w, .y = win_y
|
|
};
|
|
a_position_vals[2] = (WIIUVec2) {
|
|
.x = win_x + win_w, .y = win_y + win_h
|
|
};
|
|
a_position_vals[3] = (WIIUVec2) {
|
|
.x = win_x, .y = win_y + win_h
|
|
};
|
|
GX2RUnlockBufferEx(a_position, 0);
|
|
|
|
/* Compute texture coords */
|
|
a_texCoord_vals = GX2RLockBufferEx(a_texCoord, 0);
|
|
a_texCoord_vals[0] = (WIIUVec2) {.x = 0.0f, .y = tex_h};
|
|
a_texCoord_vals[1] = (WIIUVec2) {.x = tex_w, .y = tex_h};
|
|
a_texCoord_vals[2] = (WIIUVec2) {.x = tex_w, .y = 0.0f};
|
|
a_texCoord_vals[3] = (WIIUVec2) {.x = 0.0f, .y = 0.0f};
|
|
GX2RUnlockBufferEx(a_texCoord, 0);
|
|
|
|
/* Render the window */
|
|
WHBGfxClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
|
wiiuSetTextureShader();
|
|
|
|
GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)&u_viewSize);
|
|
GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[1].offset, 4, (uint32_t *)&tdata->u_texSize);
|
|
GX2SetPixelUniformReg(wiiuTextureShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)&tdata->u_mod);
|
|
|
|
GX2RSetAttributeBuffer(a_position, 0, a_position->elemSize, 0);
|
|
GX2RSetAttributeBuffer(a_texCoord, 1, a_texCoord->elemSize, 0);
|
|
|
|
GX2SetPixelTexture(&tdata->texture, wiiuTextureShader.pixelShader->samplerVars[0].location);
|
|
GX2SetPixelSampler(&tdata->sampler, wiiuTextureShader.pixelShader->samplerVars[0].location);
|
|
|
|
GX2SetColorControl(GX2_LOGIC_OP_COPY, 0x00, FALSE, TRUE);
|
|
|
|
GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);
|
|
}
|
|
|
|
void WIIU_SDL_RenderPresent(SDL_Renderer * renderer)
|
|
{
|
|
WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata;
|
|
Uint32 flags = SDL_GetWindowFlags(renderer->window);
|
|
|
|
if (renderer->info.flags & SDL_RENDERER_PRESENTVSYNC) {
|
|
/* NOTE watch libwhb's source to ensure this call only does vsync */
|
|
WHBGfxBeginRender();
|
|
}
|
|
|
|
/* Only render to TV if the window is *not* drc-only */
|
|
if (!(flags & SDL_WINDOW_WIIU_GAMEPAD_ONLY)) {
|
|
WHBGfxBeginRenderTV();
|
|
render_scene(renderer);
|
|
WHBGfxFinishRenderTV();
|
|
}
|
|
|
|
if (!(flags & SDL_WINDOW_WIIU_TV_ONLY)) {
|
|
WHBGfxBeginRenderDRC();
|
|
render_scene(renderer);
|
|
WHBGfxFinishRenderDRC();
|
|
}
|
|
|
|
WHBGfxFinishRender();
|
|
|
|
/* Free the list of render and draw data */
|
|
WIIU_FreeRenderData(data);
|
|
WIIU_TextureDoneRendering(data);
|
|
|
|
/* SDL context state will be restored in next RunCommandQueue call */
|
|
}
|
|
|
|
#endif /* SDL_VIDEO_RENDER_WIIU */
|