mirror of
https://github.com/yawut/SDL.git
synced 2026-07-19 17:32:17 -05:00
wiiu: Start implementing SDL_Renderer
This commit is contained in:
parent
8b9f7b6204
commit
e7d6d8f733
305
src/render/wiiu/SDL_render_wiiu.c
Normal file
305
src/render/wiiu/SDL_render_wiiu.c
Normal file
|
|
@ -0,0 +1,305 @@
|
|||
/*
|
||||
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>
|
||||
|
||||
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 "../SDL_sysrender.h"
|
||||
#include "SDL_hints.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
/* SDL surface based renderer implementation */
|
||||
|
||||
static SDL_Renderer *WIIU_CreateRenderer(SDL_Window * window, Uint32 flags);
|
||||
static void WIIU_WindowEvent(SDL_Renderer * renderer,
|
||||
const SDL_WindowEvent *event);
|
||||
static int WIIU_GetOutputSize(SDL_Renderer * renderer, int *w, int *h);
|
||||
static int WIIU_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
|
||||
static int WIIU_SetTextureColorMod(SDL_Renderer * renderer,
|
||||
SDL_Texture * texture);
|
||||
static int WIIU_SetTextureAlphaMod(SDL_Renderer * renderer,
|
||||
SDL_Texture * texture);
|
||||
static int WIIU_SetTextureBlendMode(SDL_Renderer * renderer,
|
||||
SDL_Texture * texture);
|
||||
static int WIIU_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
const SDL_Rect * rect, const void *pixels,
|
||||
int pitch);
|
||||
static int WIIU_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
const SDL_Rect * rect, void **pixels, int *pitch);
|
||||
static void WIIU_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
|
||||
static int WIIU_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture);
|
||||
static int WIIU_UpdateViewport(SDL_Renderer * renderer);
|
||||
static int WIIU_UpdateClipRect(SDL_Renderer * renderer);
|
||||
static int WIIU_RenderClear(SDL_Renderer * renderer);
|
||||
static int WIIU_RenderDrawPoints(SDL_Renderer * renderer,
|
||||
const SDL_FPoint * points, int count);
|
||||
static int WIIU_RenderDrawLines(SDL_Renderer * renderer,
|
||||
const SDL_FPoint * points, int count);
|
||||
static int WIIU_RenderFillRects(SDL_Renderer * renderer,
|
||||
const SDL_FRect * rects, int count);
|
||||
static int WIIU_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
const SDL_Rect * srcrect, const SDL_FRect * dstrect);
|
||||
static int WIIU_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
const SDL_Rect * srcrect, const SDL_FRect * dstrect,
|
||||
const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip);
|
||||
static int WIIU_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
|
||||
Uint32 format, void * pixels, int pitch);
|
||||
static void WIIU_RenderPresent(SDL_Renderer * renderer);
|
||||
static void WIIU_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture);
|
||||
static void WIIU_DestroyRenderer(SDL_Renderer * renderer);
|
||||
|
||||
SDL_RenderDriver WIIU_RenderDriver = {
|
||||
WIIU_CreateRenderer,
|
||||
{
|
||||
"WiiU GX2",
|
||||
SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE,
|
||||
5,
|
||||
{
|
||||
SDL_PIXELFORMAT_RGBA8888,
|
||||
SDL_PIXELFORMAT_RGBA4444,
|
||||
SDL_PIXELFORMAT_ABGR1555,
|
||||
SDL_PIXELFORMAT_RGBA5551,
|
||||
SDL_PIXELFORMAT_RGB565,
|
||||
},
|
||||
0,
|
||||
0}
|
||||
};
|
||||
|
||||
#define WIIU_WINDOW_DATA "_SDL_WiiUData"
|
||||
typedef struct
|
||||
{
|
||||
SDL_Surface *surface;
|
||||
GX2Texture texture;
|
||||
} WIIU_WindowData;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GX2Sampler sampler;
|
||||
GX2ColorBuffer cbuf;
|
||||
GX2ContextState ctx;
|
||||
} WIIU_RenderData;
|
||||
|
||||
static Uint32
|
||||
TextureNextPow2(Uint32 w)
|
||||
{
|
||||
if(w == 0)
|
||||
return 0;
|
||||
Uint32 n = 2;
|
||||
while(w > n)
|
||||
n <<= 1;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
SDL_Renderer *
|
||||
WIIU_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
{
|
||||
SDL_Surface *surface
|
||||
SDL_Renderer *renderer;
|
||||
WIIU_RenderData *data;
|
||||
WIIU_WindowData *wdata;
|
||||
|
||||
surface = SDL_GetWindowSurface(window);
|
||||
if (!surface) {
|
||||
SDL_SetError("Can't create renderer for NULL surface");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wdata = (WIIU_WindowData *) SDL_GetWindowData(window, WIIU_WINDOW_DATA);
|
||||
if (!surface) {
|
||||
SDL_SetError("Can't access window data");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
|
||||
if (!renderer) {
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data = (WIIU_RenderData *) SDL_calloc(1, sizeof(*data));
|
||||
if (!data) {
|
||||
WIIU_DestroyRenderer(renderer);
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
renderer->WindowEvent = WIIU_WindowEvent;
|
||||
renderer->GetOutputSize = WIIU_GetOutputSize;
|
||||
renderer->CreateTexture = WIIU_CreateTexture;
|
||||
renderer->SetTextureColorMod = WIIU_SetTextureColorMod;
|
||||
renderer->SetTextureAlphaMod = WIIU_SetTextureAlphaMod;
|
||||
renderer->SetTextureBlendMode = WIIU_SetTextureBlendMode;
|
||||
renderer->UpdateTexture = WIIU_UpdateTexture;
|
||||
renderer->LockTexture = WIIU_LockTexture;
|
||||
renderer->UnlockTexture = WIIU_UnlockTexture;
|
||||
renderer->SetRenderTarget = WIIU_SetRenderTarget;
|
||||
renderer->UpdateViewport = WIIU_UpdateViewport;
|
||||
renderer->UpdateClipRect = WIIU_UpdateClipRect;
|
||||
renderer->RenderClear = WIIU_RenderClear;
|
||||
renderer->RenderDrawPoints = WIIU_RenderDrawPoints;
|
||||
renderer->RenderDrawLines = WIIU_RenderDrawLines;
|
||||
renderer->RenderFillRects = WIIU_RenderFillRects;
|
||||
renderer->RenderCopy = WIIU_RenderCopy;
|
||||
renderer->RenderCopyEx = WIIU_RenderCopyEx;
|
||||
renderer->RenderReadPixels = WIIU_RenderReadPixels;
|
||||
renderer->RenderPresent = WIIU_RenderPresent;
|
||||
renderer->DestroyTexture = WIIU_DestroyTexture;
|
||||
renderer->DestroyRenderer = WIIU_DestroyRenderer;
|
||||
renderer->info = WIIU_RenderDriver.info;
|
||||
renderer->driverdata = data;
|
||||
renderer->window = window;
|
||||
|
||||
// Setup sampler
|
||||
GX2InitSampler(&data->sampler, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_LINEAR);
|
||||
|
||||
// Setup color buffer
|
||||
memcpy(&data->cbuf.surface, &wdata->texture.surface, sizeof(GX2Surface));
|
||||
data->cbuf.surface.use = GX2_SURFACE_USE_TEXTURE | GX2_SURFACE_USE_COLOR_BUFFER;
|
||||
data->cbuf.viewNumSlices = 1;
|
||||
GX2InitColorBufferRegs(&data->cbuf);
|
||||
|
||||
// Setup context state
|
||||
GX2SetupContextStateEx(&data->ctx, TRUE);
|
||||
GX2SetContextState(&data->ctx);
|
||||
GX2SetColorBuffer(&data->cbuf, GX2_RENDER_TARGET_0);
|
||||
GX2SetViewport(0, 0, (float)data->cbuf.surface.width, (float)data->cbuf.surface.height, 0.0f, 1.0f);
|
||||
GX2SetScissor(0, 0, (float)data->cbuf.surface.width, (float)data->cbuf.surface.height);
|
||||
|
||||
return renderer;
|
||||
}
|
||||
|
||||
static void
|
||||
WIIU_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
|
||||
{
|
||||
WIIU_RenderData *data = (SW_RenderData *) renderer->driverdata;
|
||||
WIIU_WindowData *wdata = (WIIU_WindowData *) SDL_GetWindowData(renderer->window, WIIU_WINDOW_DATA);
|
||||
|
||||
if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
|
||||
// Update color buffer
|
||||
memset(&data->cbuf, 0, sizeof(data->cbuf));
|
||||
memcpy(&data->cbuf.surface, &wdata->texture.surface, sizeof(GX2Surface));
|
||||
data->cbuf.surface.use = GX2_SURFACE_USE_TEXTURE | GX2_SURFACE_USE_COLOR_BUFFER;
|
||||
data->cbuf.viewNumSlices = 1;
|
||||
GX2InitColorBufferRegs(&data->cbuf);
|
||||
|
||||
// Update context state
|
||||
GX2SetContextState(&data->ctx);
|
||||
GX2SetColorBuffer(&data->cbuf, GX2_RENDER_TARGET_0);
|
||||
GX2SetViewport(0, 0, (float)data->cbuf.surface.width, (float)data->cbuf.surface.height, 0.0f, 1.0f);
|
||||
GX2SetScissor(0, 0, (float)data->cbuf.surface.width, (float)data->cbuf.surface.height);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
GX2SurfaceFormat
|
||||
PixelFormatToWIIUFMT(Uint32 format)
|
||||
{
|
||||
switch (format) {
|
||||
case SDL_PIXELFORMAT_RGBA8888:
|
||||
return GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
|
||||
case SDL_PIXELFORMAT_RGBA4444:
|
||||
return GX2_SURFACE_FORMAT_UNORM_R4_G4_B4_A4;
|
||||
case SDL_PIXELFORMAT_ABGR1555:
|
||||
return GX2_SURFACE_FORMAT_UNORM_A1_B5_G5_R5;
|
||||
case SDL_PIXELFORMAT_RGBA5551:
|
||||
return GX2_SURFACE_FORMAT_UNORM_R5_G5_B5_A1;
|
||||
case SDL_PIXELFORMAT_RGB565:
|
||||
return GX2_SURFACE_FORMAT_UNORM_R5_G6_B5;
|
||||
default:
|
||||
return GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
|
||||
}
|
||||
return GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
|
||||
}
|
||||
|
||||
static int
|
||||
WIIU_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
{
|
||||
GX2Texture *wiiu_tex = (WIIU_TextureData*) SDL_calloc(1, sizeof(*wiiu_tex));
|
||||
if (!wiiu_tex)
|
||||
return -1;
|
||||
|
||||
wiiu_tex->surface.width = TextureNextPow2(texture->w);
|
||||
wiiu_tex->surface.height = TextureNextPow2(texture->h);
|
||||
wiiu_tex->surface.format = PixelFormatToWIIUFMT(texture->format);
|
||||
wiiu_tex->surface.depth = 1; //?
|
||||
wiiu_tex->surface.dim = GX2_SURFACE_DIM_TEXTURE_2D;
|
||||
wiiu_tex->surface.tileMode = GX2_TILE_MODE_LINEAR_ALIGNED;
|
||||
wiiu_tex->surface.use = GX2_SURFACE_USE_TEXTURE;
|
||||
wiiu_tex->surface.mipLevels = 1;
|
||||
wiiu_tex->viewNumMips = 1;
|
||||
wiiu_tex->viewNumSlices = 1;
|
||||
wiiu_tex->compMap = 0x00010203; //comment?
|
||||
|
||||
GX2CalcSurfaceSizeAndAlignment(&wiiu_tex->surface);
|
||||
texture->surface.image = memalign(wiiu_tex->surface.alignment, wiiu_tex->surface.imageSize);
|
||||
if(!texture->surface.image)
|
||||
{
|
||||
SDL_free(wiiu_tex);
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
texture->driverdata = wiiu_tex;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
WIIU_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
{
|
||||
WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata;
|
||||
|
||||
GX2Surface *target;
|
||||
|
||||
if (texture) {
|
||||
// Set texture as target
|
||||
GX2Texture *wiiu_tex = (GX2Texture *) texture->driverdata;
|
||||
target = wiiu_tex->surface;
|
||||
} else {
|
||||
// Set window texture as target
|
||||
WIIU_WindowData *wdata = (WIIU_WindowData *) SDL_GetWindowData(window, WIIU_WINDOW_DATA);
|
||||
target = &wdata->texture.surface;
|
||||
}
|
||||
|
||||
// Update color buffer
|
||||
memset(&data->cbuf, 0, sizeof(data->cbuf));
|
||||
memcpy(&data->cbuf.surface, target, sizeof(GX2Surface));
|
||||
data->cbuf.surface.use = GX2_SURFACE_USE_TEXTURE | GX2_SURFACE_USE_COLOR_BUFFER;
|
||||
data->cbuf.viewNumSlices = 1;
|
||||
GX2InitColorBufferRegs(&data->cbuf);
|
||||
|
||||
// Update context state
|
||||
GX2SetContextState(&data->ctx);
|
||||
GX2SetColorBuffer(&data->cbuf, GX2_RENDER_TARGET_0);
|
||||
GX2SetViewport(0, 0, (float)data->cbuf.surface.width, (float)data->cbuf.surface.height, 0.0f, 1.0f);
|
||||
GX2SetScissor(0, 0, (float)data->cbuf.surface.width, (float)data->cbuf.surface.height);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_RENDER_WIIU */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
Loading…
Reference in New Issue
Block a user