mirror of
https://github.com/yawut/SDL.git
synced 2026-09-14 20:16:32 -05:00
Merge pull request #2 from yawut/wiiu-noframebuffer
render: Avoid using framebuffer, other tweaks
This commit is contained in:
@@ -37,6 +37,7 @@
|
||||
#include <gx2/clear.h>
|
||||
#include <gx2/mem.h>
|
||||
#include <gx2/event.h>
|
||||
#include <gx2r/surface.h>
|
||||
#include <gx2r/buffer.h>
|
||||
#include <gx2r/draw.h>
|
||||
|
||||
@@ -53,44 +54,76 @@ int WIIU_SDL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
{
|
||||
WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata;
|
||||
WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata;
|
||||
float *a_position = WIIU_AllocRenderData(data, sizeof(float) * 8);
|
||||
float *a_texCoord = WIIU_AllocRenderData(data, sizeof(float) * 8);
|
||||
float *u_mod = WIIU_AllocRenderData(data, sizeof(float) * 4);
|
||||
GX2RBuffer *a_position, *a_texCoord;
|
||||
WIIUVec2 *a_position_vals, *a_texCoord_vals;
|
||||
float x_min, y_min, x_max, y_max;
|
||||
|
||||
if (texture->access & SDL_TEXTUREACCESS_TARGET) {
|
||||
GX2RInvalidateSurface(&tdata->texture.surface, 0, 0);
|
||||
}
|
||||
|
||||
/* Update texture rendering state */
|
||||
WIIU_TextureStartRendering(data, tdata);
|
||||
|
||||
/* 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),
|
||||
.elemCount = 4, // 4 corners
|
||||
});
|
||||
|
||||
/* Compute vertex points */
|
||||
float x_min = renderer->viewport.x + dstrect->x;
|
||||
float y_min = renderer->viewport.y + dstrect->y;
|
||||
float x_max = renderer->viewport.x + dstrect->x + dstrect->w;
|
||||
float y_max = renderer->viewport.y + dstrect->y + dstrect->h;
|
||||
a_position[0] = x_min; a_position[1] = y_min;
|
||||
a_position[2] = x_max; a_position[3] = y_min;
|
||||
a_position[4] = x_max; a_position[5] = y_max;
|
||||
a_position[6] = x_min; a_position[7] = y_max;
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, a_position, sizeof(float) * 8);
|
||||
x_min = renderer->viewport.x + dstrect->x;
|
||||
y_min = renderer->viewport.y + dstrect->y;
|
||||
x_max = renderer->viewport.x + dstrect->x + dstrect->w;
|
||||
y_max = renderer->viewport.y + dstrect->y + dstrect->h;
|
||||
|
||||
/* Save them */
|
||||
a_position_vals = GX2RLockBufferEx(a_position, 0);
|
||||
a_position_vals[0] = (WIIUVec2){.x = x_min, .y = y_min};
|
||||
a_position_vals[1] = (WIIUVec2){.x = x_max, .y = y_min};
|
||||
a_position_vals[2] = (WIIUVec2){.x = x_max, .y = y_max};
|
||||
a_position_vals[3] = (WIIUVec2){.x = x_min, .y = y_max};
|
||||
GX2RUnlockBufferEx(a_position, 0);
|
||||
|
||||
/* Compute texture coords */
|
||||
a_texCoord[0] = srcrect->x; a_texCoord[1] = srcrect->y + srcrect->h;
|
||||
a_texCoord[2] = srcrect->x + srcrect->w; a_texCoord[3] = srcrect->y + srcrect->h;
|
||||
a_texCoord[4] = srcrect->x + srcrect->w; a_texCoord[5] = srcrect->y;
|
||||
a_texCoord[6] = srcrect->x; a_texCoord[7] = srcrect->y;
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, a_texCoord, sizeof(float) * 8);
|
||||
|
||||
/* Compute color/alpha mod */
|
||||
u_mod[0] = (float)texture->r / 255.0f;
|
||||
u_mod[1] = (float)texture->g / 255.0f;
|
||||
u_mod[2] = (float)texture->b / 255.0f;
|
||||
u_mod[3] = (float)texture->a / 255.0f;
|
||||
a_texCoord_vals = GX2RLockBufferEx(a_texCoord, 0);
|
||||
a_texCoord_vals[0] = (WIIUVec2) {
|
||||
.x = srcrect->x,
|
||||
.y = srcrect->y + srcrect->h,
|
||||
};
|
||||
a_texCoord_vals[1] = (WIIUVec2) {
|
||||
.x = srcrect->x + srcrect->w,
|
||||
.y = srcrect->y + srcrect->h,
|
||||
};
|
||||
a_texCoord_vals[2] = (WIIUVec2) {
|
||||
.x = srcrect->x + srcrect->w,
|
||||
.y = srcrect->y,
|
||||
};
|
||||
a_texCoord_vals[3] = (WIIUVec2) {
|
||||
.x = srcrect->x,
|
||||
.y = srcrect->y,
|
||||
};
|
||||
GX2RUnlockBufferEx(a_texCoord, 0);
|
||||
|
||||
/* Render */
|
||||
GX2SetContextState(data->ctx);
|
||||
wiiuSetTextureShader();
|
||||
GX2SetPixelTexture(&tdata->texture, 0);
|
||||
GX2SetPixelSampler(&tdata->sampler, 0);
|
||||
GX2SetAttribBuffer(0, sizeof(float) * 8, sizeof(float) * 2, a_position);
|
||||
GX2SetAttribBuffer(1, sizeof(float) * 8, sizeof(float) * 2, a_texCoord);
|
||||
GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)data->u_viewSize);
|
||||
GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[1].offset, 4, (uint32_t *)tdata->u_texSize);
|
||||
GX2SetPixelUniformReg(wiiuTextureShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)u_mod);
|
||||
GX2RSetAttributeBuffer(a_position, 0, a_position->elemSize, 0);
|
||||
GX2RSetAttributeBuffer(a_texCoord, 1, a_texCoord->elemSize, 0);
|
||||
GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)&data->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);
|
||||
WIIU_SDL_SetGX2BlendMode(texture->blendMode);
|
||||
GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);
|
||||
|
||||
@@ -104,9 +137,8 @@ int WIIU_SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
{
|
||||
WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata;
|
||||
WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata;
|
||||
float *a_position = WIIU_AllocRenderData(data, sizeof(float) * 8);
|
||||
float *a_texCoord = WIIU_AllocRenderData(data, sizeof(float) * 8);
|
||||
float *u_mod = WIIU_AllocRenderData(data, sizeof(float) * 4);
|
||||
GX2RBuffer *a_position, *a_texCoord;
|
||||
WIIUVec2 *a_position_vals, *a_texCoord_vals;
|
||||
|
||||
/* Compute real vertex points */
|
||||
float x_min = renderer->viewport.x + dstrect->x;
|
||||
@@ -116,41 +148,87 @@ int WIIU_SDL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
float cx = x_min + center->x;
|
||||
float cy = y_min + center->y;
|
||||
double r = angle * (M_PI / 180.0);
|
||||
float rvb[8] = {
|
||||
(flip & SDL_FLIP_HORIZONTAL) ? x_max : x_min, (flip & SDL_FLIP_VERTICAL) ? y_max : y_min,
|
||||
(flip & SDL_FLIP_HORIZONTAL) ? x_min : x_max, (flip & SDL_FLIP_VERTICAL) ? y_max : y_min,
|
||||
(flip & SDL_FLIP_HORIZONTAL) ? x_min : x_max, (flip & SDL_FLIP_VERTICAL) ? y_min : y_max,
|
||||
(flip & SDL_FLIP_HORIZONTAL) ? x_max : x_min, (flip & SDL_FLIP_VERTICAL) ? y_min : y_max,
|
||||
WIIUVec2 rvb[4] = {
|
||||
{
|
||||
.x = (flip & SDL_FLIP_HORIZONTAL) ? x_max : x_min,
|
||||
.y = (flip & SDL_FLIP_VERTICAL) ? y_max : y_min,
|
||||
},
|
||||
{
|
||||
.x = (flip & SDL_FLIP_HORIZONTAL) ? x_min : x_max,
|
||||
.y = (flip & SDL_FLIP_VERTICAL) ? y_max : y_min,
|
||||
},
|
||||
{
|
||||
.x = (flip & SDL_FLIP_HORIZONTAL) ? x_min : x_max,
|
||||
.y = (flip & SDL_FLIP_VERTICAL) ? y_min : y_max,
|
||||
},
|
||||
{
|
||||
.x = (flip & SDL_FLIP_HORIZONTAL) ? x_max : x_min,
|
||||
.y = (flip & SDL_FLIP_VERTICAL) ? y_min : y_max,
|
||||
},
|
||||
};
|
||||
for (int i = 0; i < 8; i += 2) {
|
||||
a_position[i+0] = cx + (SDL_cos(r) * (rvb[i+0] - cx) - SDL_sin(r) * (rvb[i+1] - cy));
|
||||
a_position[i+1] = cy + (SDL_cos(r) * (rvb[i+1] - cy) + SDL_sin(r) * (rvb[i+0] - cx));
|
||||
|
||||
if (texture->access & SDL_TEXTUREACCESS_TARGET) {
|
||||
GX2RInvalidateSurface(&tdata->texture.surface, 0, 0);
|
||||
}
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, a_position, sizeof(float) * 8);
|
||||
|
||||
/* Update texture rendering state */
|
||||
WIIU_TextureStartRendering(data, tdata);
|
||||
|
||||
/* 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
|
||||
});
|
||||
|
||||
/* Save vertex points */
|
||||
a_position_vals = GX2RLockBufferEx(a_position, 0);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
a_position_vals[i] = (WIIUVec2) {
|
||||
.x = cx + (SDL_cos(r) * (rvb[i].x - cx) - SDL_sin(r) * (rvb[i].y - cy)),
|
||||
.y = cy + (SDL_cos(r) * (rvb[i].y - cy) + SDL_sin(r) * (rvb[i].x - cx)),
|
||||
};
|
||||
}
|
||||
GX2RUnlockBufferEx(a_position, 0);
|
||||
|
||||
/* Compute texture coords */
|
||||
a_texCoord[0] = srcrect->x; a_texCoord[1] = srcrect->y + srcrect->h;
|
||||
a_texCoord[2] = srcrect->x + srcrect->w; a_texCoord[3] = srcrect->y + srcrect->h;
|
||||
a_texCoord[4] = srcrect->x + srcrect->w; a_texCoord[5] = srcrect->y;
|
||||
a_texCoord[6] = srcrect->x; a_texCoord[7] = srcrect->y;
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, a_texCoord, sizeof(float) * 8);
|
||||
|
||||
/* Compute color/alpha mod */
|
||||
u_mod[0] = (float)texture->r / 255.0f;
|
||||
u_mod[1] = (float)texture->g / 255.0f;
|
||||
u_mod[2] = (float)texture->b / 255.0f;
|
||||
u_mod[3] = (float)texture->a / 255.0f;
|
||||
a_texCoord_vals = GX2RLockBufferEx(a_texCoord, 0);
|
||||
a_texCoord_vals[0] = (WIIUVec2) {
|
||||
.x = srcrect->x,
|
||||
.y = srcrect->y + srcrect->h,
|
||||
};
|
||||
a_texCoord_vals[1] = (WIIUVec2) {
|
||||
.x = srcrect->x + srcrect->w,
|
||||
.y = srcrect->y + srcrect->h,
|
||||
};
|
||||
a_texCoord_vals[2] = (WIIUVec2) {
|
||||
.x = srcrect->x + srcrect->w,
|
||||
.y = srcrect->y,
|
||||
};
|
||||
a_texCoord_vals[3] = (WIIUVec2) {
|
||||
.x = srcrect->x,
|
||||
.y = srcrect->y,
|
||||
};
|
||||
GX2RUnlockBufferEx(a_texCoord, 0);
|
||||
|
||||
/* Render */
|
||||
GX2SetContextState(data->ctx);
|
||||
wiiuSetTextureShader();
|
||||
GX2SetPixelTexture(&tdata->texture, 0);
|
||||
GX2SetPixelSampler(&tdata->sampler, 0);
|
||||
GX2SetAttribBuffer(0, sizeof(float) * 8, sizeof(float) * 2, a_position);
|
||||
GX2SetAttribBuffer(1, sizeof(float) * 8, sizeof(float) * 2, a_texCoord);
|
||||
GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)data->u_viewSize);
|
||||
GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[1].offset, 4, (uint32_t *)tdata->u_texSize);
|
||||
GX2SetPixelUniformReg(wiiuTextureShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)u_mod);
|
||||
GX2RSetAttributeBuffer(a_position, 0, a_position->elemSize, 0);
|
||||
GX2RSetAttributeBuffer(a_texCoord, 1, a_texCoord->elemSize, 0);
|
||||
GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)&data->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);
|
||||
WIIU_SDL_SetGX2BlendMode(texture->blendMode);
|
||||
GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);
|
||||
|
||||
@@ -161,27 +239,41 @@ int WIIU_SDL_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points
|
||||
int count)
|
||||
{
|
||||
WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata;
|
||||
GX2RBuffer *a_position;
|
||||
WIIUVec2 *a_position_vals;
|
||||
|
||||
/* Compute colors */
|
||||
float u_color[4] = {(float)renderer->r / 255.0f,
|
||||
(float)renderer->g / 255.0f,
|
||||
(float)renderer->b / 255.0f,
|
||||
(float)renderer->a / 255.0f};
|
||||
/* Compute colours */
|
||||
WIIUVec4 u_colour = {
|
||||
.r = (float)renderer->r / 255.0f,
|
||||
.g = (float)renderer->g / 255.0f,
|
||||
.b = (float)renderer->b / 255.0f,
|
||||
.a = (float)renderer->a / 255.0f,
|
||||
};
|
||||
|
||||
/* Compute vertex pos */
|
||||
float *a_position = WIIU_AllocRenderData(data, sizeof(float) * 2 * count);
|
||||
/* 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 point */
|
||||
.elemCount = count,
|
||||
});
|
||||
|
||||
/* Compute vertex positions */
|
||||
a_position_vals = GX2RLockBufferEx(a_position, 0);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
a_position[i*2+0] = (float)renderer->viewport.x + points[i].x;
|
||||
a_position[i*2+1] = (float)renderer->viewport.y + points[i].y;
|
||||
a_position_vals[i] = (WIIUVec2) {
|
||||
.x = (float)renderer->viewport.x + points[i].x,
|
||||
.y = (float)renderer->viewport.y + points[i].y,
|
||||
};
|
||||
}
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, a_position, sizeof(float) * 2 * count);
|
||||
GX2RUnlockBufferEx(a_position, 0);
|
||||
|
||||
/* Render points */
|
||||
GX2SetContextState(data->ctx);
|
||||
wiiuSetColorShader();
|
||||
GX2SetAttribBuffer(0, sizeof(float) * 2 * count, sizeof(float) * 2, a_position);
|
||||
GX2SetVertexUniformReg(wiiuColorShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)data->u_viewSize);
|
||||
GX2SetPixelUniformReg(wiiuColorShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)u_color);
|
||||
GX2RSetAttributeBuffer(a_position, 0, a_position->elemSize, 0);
|
||||
GX2SetVertexUniformReg(wiiuColorShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)&data->u_viewSize);
|
||||
GX2SetPixelUniformReg(wiiuColorShader.pixelShader->uniformVars[0].offset, 4, (uint32_t *)&u_colour);
|
||||
WIIU_SDL_SetGX2BlendMode(renderer->blendMode);
|
||||
GX2DrawEx(GX2_PRIMITIVE_MODE_POINTS, count, 0, 1);
|
||||
|
||||
@@ -193,27 +285,41 @@ int WIIU_SDL_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points,
|
||||
int count)
|
||||
{
|
||||
WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata;
|
||||
GX2RBuffer *a_position;
|
||||
WIIUVec2 *a_position_vals;
|
||||
|
||||
/* Compute colors */
|
||||
float u_color[4] = {(float)renderer->r / 255.0f,
|
||||
(float)renderer->g / 255.0f,
|
||||
(float)renderer->b / 255.0f,
|
||||
(float)renderer->a / 255.0f};
|
||||
/* Compute colours */
|
||||
WIIUVec4 u_colour = {
|
||||
.r = (float)renderer->r / 255.0f,
|
||||
.g = (float)renderer->g / 255.0f,
|
||||
.b = (float)renderer->b / 255.0f,
|
||||
.a = (float)renderer->a / 255.0f,
|
||||
};
|
||||
|
||||
/* Compute vertex pos */
|
||||
float *a_position = WIIU_AllocRenderData(data, sizeof(float) * 2 * count);
|
||||
/* 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 point */
|
||||
.elemCount = count,
|
||||
});
|
||||
|
||||
/* Compute vertex positions */
|
||||
a_position_vals = GX2RLockBufferEx(a_position, 0);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
a_position[i*2+0] = (float)renderer->viewport.x + points[i].x;
|
||||
a_position[i*2+1] = (float)renderer->viewport.y + points[i].y;
|
||||
a_position_vals[i] = (WIIUVec2) {
|
||||
.x = (float)renderer->viewport.x + points[i].x,
|
||||
.y = (float)renderer->viewport.y + points[i].y,
|
||||
};
|
||||
}
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, a_position, sizeof(float) * 2 * count);
|
||||
GX2RUnlockBufferEx(a_position, 0);
|
||||
|
||||
/* Render lines */
|
||||
GX2SetContextState(data->ctx);
|
||||
wiiuSetColorShader();
|
||||
GX2SetAttribBuffer(0, sizeof(float) * 2 * count, sizeof(float) * 2, a_position);
|
||||
GX2SetVertexUniformReg(wiiuColorShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)data->u_viewSize);
|
||||
GX2SetPixelUniformReg(wiiuColorShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)u_color);
|
||||
GX2RSetAttributeBuffer(a_position, 0, a_position->elemSize, 0);
|
||||
GX2SetVertexUniformReg(wiiuColorShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)&data->u_viewSize);
|
||||
GX2SetPixelUniformReg(wiiuColorShader.pixelShader->uniformVars[0].offset, 4, (uint32_t *)&u_colour);
|
||||
WIIU_SDL_SetGX2BlendMode(renderer->blendMode);
|
||||
GX2DrawEx(GX2_PRIMITIVE_MODE_LINE_STRIP, count, 0, 1);
|
||||
|
||||
@@ -223,66 +329,78 @@ int WIIU_SDL_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points,
|
||||
int WIIU_SDL_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int count)
|
||||
{
|
||||
WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata;
|
||||
GX2RBuffer *a_position;
|
||||
WIIUVec2 *a_position_vals;
|
||||
|
||||
/* Compute colors */
|
||||
float u_color[4] = {(float)renderer->r / 255.0f,
|
||||
(float)renderer->g / 255.0f,
|
||||
(float)renderer->b / 255.0f,
|
||||
(float)renderer->a / 255.0f};
|
||||
/* Compute colours */
|
||||
WIIUVec4 u_colour = {
|
||||
.r = (float)renderer->r / 255.0f,
|
||||
.g = (float)renderer->g / 255.0f,
|
||||
.b = (float)renderer->b / 255.0f,
|
||||
.a = (float)renderer->a / 255.0f,
|
||||
};
|
||||
|
||||
/* Compute vertex pos */
|
||||
float vx = (float)renderer->viewport.x;
|
||||
float vy = (float)renderer->viewport.y;
|
||||
|
||||
float *a_position = WIIU_AllocRenderData(data, sizeof(float) * 8 * count);
|
||||
/* Allocate attribute buffers */
|
||||
a_position = WIIU_AllocRenderData(data, (GX2RBuffer) {
|
||||
.flags =
|
||||
GX2R_RESOURCE_BIND_VERTEX_BUFFER |
|
||||
GX2R_RESOURCE_USAGE_CPU_WRITE,
|
||||
.elemSize = sizeof(WIIUVec2), // x/y float per corner
|
||||
.elemCount = 4 * count, // 4 corners per square
|
||||
});
|
||||
|
||||
/* Compute vertex positions */
|
||||
a_position_vals = GX2RLockBufferEx(a_position, 0);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
a_position[i*8+0] = vx + rects[i].x;
|
||||
a_position[i*8+1] = vy + rects[i].y;
|
||||
a_position[i*8+2] = vx + rects[i].x + rects[i].w;
|
||||
a_position[i*8+3] = vy + rects[i].y;
|
||||
a_position[i*8+4] = vx + rects[i].x + rects[i].w;
|
||||
a_position[i*8+5] = vy + rects[i].y + rects[i].h;
|
||||
a_position[i*8+6] = vx + rects[i].x;
|
||||
a_position[i*8+7] = vy + rects[i].y + rects[i].h;
|
||||
a_position_vals[i*4 + 0] = (WIIUVec2) {
|
||||
.x = vx + rects[i].x,
|
||||
.y = vy + rects[i].y,
|
||||
};
|
||||
a_position_vals[i*4 + 1] = (WIIUVec2) {
|
||||
.x = vx + rects[i].x + rects[i].w,
|
||||
.y = vy + rects[i].y,
|
||||
};
|
||||
a_position_vals[i*4 + 2] = (WIIUVec2) {
|
||||
.x = vx + rects[i].x + rects[i].w,
|
||||
.y = vy + rects[i].y + rects[i].h,
|
||||
};
|
||||
a_position_vals[i*4 + 3] = (WIIUVec2) {
|
||||
.x = vx + rects[i].x,
|
||||
.y = vy + rects[i].y + rects[i].h,
|
||||
};
|
||||
}
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_ATTRIBUTE_BUFFER, a_position, sizeof(float) * 8 * count);
|
||||
GX2RUnlockBufferEx(a_position, 0);
|
||||
|
||||
/* Render rects */
|
||||
GX2SetContextState(data->ctx);
|
||||
wiiuSetColorShader();
|
||||
GX2SetAttribBuffer(0, sizeof(float) * 8 * count, sizeof(float) * 2, a_position);
|
||||
GX2SetVertexUniformReg(wiiuColorShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)data->u_viewSize);
|
||||
GX2SetPixelUniformReg(wiiuColorShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)u_color);
|
||||
GX2RSetAttributeBuffer(a_position, 0, a_position->elemSize, 0);
|
||||
GX2SetVertexUniformReg(wiiuColorShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)&data->u_viewSize);
|
||||
GX2SetPixelUniformReg(wiiuColorShader.pixelShader->uniformVars[0].offset, 4, (uint32_t *)&u_colour);
|
||||
WIIU_SDL_SetGX2BlendMode(renderer->blendMode);
|
||||
GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4 * count, 0, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WIIU_SDL_RenderPresent(SDL_Renderer * renderer)
|
||||
{
|
||||
WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata;
|
||||
SDL_Window *window = renderer->window;
|
||||
|
||||
GX2Flush();
|
||||
GX2DrawDone();
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, data->cbuf.surface.image, data->cbuf.surface.imageSize);
|
||||
|
||||
if (window) {
|
||||
SDL_UpdateWindowSurface(window);
|
||||
}
|
||||
|
||||
WIIU_FreeRenderData(data);
|
||||
}
|
||||
|
||||
int WIIU_SDL_RenderClear(SDL_Renderer * renderer)
|
||||
{
|
||||
WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata;
|
||||
GX2ClearColor(&data->cbuf,
|
||||
WIIU_RenderData* data = (WIIU_RenderData*) renderer->driverdata;
|
||||
SDL_Texture* target = WIIU_GetRenderTarget(renderer);
|
||||
WIIU_TextureData* tdata = (WIIU_TextureData*) target->driverdata;
|
||||
|
||||
GX2ClearColor(&tdata->cbuf,
|
||||
(float)renderer->r / 255.0f,
|
||||
(float)renderer->g / 255.0f,
|
||||
(float)renderer->b / 255.0f,
|
||||
(float)renderer->a / 255.0f);
|
||||
|
||||
/* Restore SDL context state */
|
||||
GX2SetContextState(data->ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -320,7 +438,7 @@ static void WIIU_SDL_SetGX2BlendMode(SDL_BlendMode mode)
|
||||
/* A = [srcA * 0] + [dstA * 1] */
|
||||
GX2_BLEND_MODE_ZERO, GX2_BLEND_MODE_ONE,
|
||||
GX2_BLEND_COMBINE_MODE_ADD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif //SDL_VIDEO_RENDER_WIIU
|
||||
#endif /* SDL_VIDEO_RENDER_WIIU */
|
||||
|
||||
@@ -1,7 +1,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) 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
|
||||
@@ -26,31 +26,20 @@
|
||||
#include "../../video/wiiu/SDL_wiiuvideo.h"
|
||||
#include "../../video/wiiu/wiiu_shaders.h"
|
||||
#include "../SDL_sysrender.h"
|
||||
#include "SDL_hints.h"
|
||||
#include "SDL_render_wiiu.h"
|
||||
|
||||
#include <gx2/registers.h>
|
||||
#include <gx2r/surface.h>
|
||||
|
||||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
SDL_RenderDriver WIIU_RenderDriver;
|
||||
|
||||
SDL_Renderer *WIIU_SDL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
{
|
||||
SDL_Surface *surface;
|
||||
SDL_Renderer *renderer;
|
||||
WIIU_RenderData *data;
|
||||
|
||||
surface = SDL_GetWindowSurface(window);
|
||||
if (!surface) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
|
||||
if (!renderer) {
|
||||
SDL_OutOfMemory();
|
||||
@@ -64,14 +53,12 @@ SDL_Renderer *WIIU_SDL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// See sdl_render_wiiu.h for explanations of commented-out functions
|
||||
|
||||
/* Setup renderer functions */
|
||||
renderer->WindowEvent = WIIU_SDL_WindowEvent;
|
||||
renderer->GetOutputSize = WIIU_SDL_GetOutputSize;
|
||||
renderer->CreateTexture = WIIU_SDL_CreateTexture;
|
||||
//renderer->SetTextureColorMod = WIIU_SDL_SetTextureColorMod;
|
||||
//renderer->SetTextureAlphaMod = WIIU_SDL_SetTextureAlphaMod;
|
||||
//renderer->SetTextureBlendMode = WIIU_SDL_SetTextureBlendMode;
|
||||
renderer->SetTextureColorMod = WIIU_SDL_SetTextureColorMod;
|
||||
renderer->SetTextureAlphaMod = WIIU_SDL_SetTextureAlphaMod;
|
||||
renderer->UpdateTexture = WIIU_SDL_UpdateTexture;
|
||||
renderer->LockTexture = WIIU_SDL_LockTexture;
|
||||
renderer->UnlockTexture = WIIU_SDL_UnlockTexture;
|
||||
@@ -92,68 +79,83 @@ SDL_Renderer *WIIU_SDL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
renderer->driverdata = data;
|
||||
renderer->window = window;
|
||||
|
||||
// Prepare shaders
|
||||
/* Prepare shaders */
|
||||
wiiuInitTextureShader();
|
||||
wiiuInitColorShader();
|
||||
|
||||
// List of attibutes to free after render
|
||||
/* List of attibutes to free after render */
|
||||
data->listfree = NULL;
|
||||
|
||||
// Setup line and point size
|
||||
/* Setup line and point size */
|
||||
GX2SetLineWidth(1.0f);
|
||||
GX2SetPointSize(1.0f, 1.0f);
|
||||
|
||||
// Create a fresh context state
|
||||
/* Create a fresh context state */
|
||||
data->ctx = (GX2ContextState *) memalign(GX2_CONTEXT_STATE_ALIGNMENT, sizeof(GX2ContextState));
|
||||
memset(data->ctx, 0, sizeof(GX2ContextState));
|
||||
SDL_memset(data->ctx, 0, sizeof(GX2ContextState));
|
||||
GX2SetupContextStateEx(data->ctx, TRUE);
|
||||
GX2SetContextState(data->ctx);
|
||||
|
||||
// Setup colour buffer, rendering to the window
|
||||
/* Setup some context state options */
|
||||
GX2SetAlphaTest(TRUE, GX2_COMPARE_FUNC_GREATER, 0.0f);
|
||||
GX2SetDepthOnlyControl(FALSE, FALSE, GX2_COMPARE_FUNC_NEVER);
|
||||
GX2SetCullOnlyControl(GX2_FRONT_FACE_CCW, FALSE, FALSE);
|
||||
|
||||
/* Make a texture for the window */
|
||||
WIIU_SDL_CreateWindowTex(renderer, window);
|
||||
|
||||
/* Setup colour buffer, rendering to the window */
|
||||
WIIU_SDL_SetRenderTarget(renderer, NULL);
|
||||
|
||||
return renderer;
|
||||
}
|
||||
|
||||
void WIIU_SDL_CreateWindowTex(SDL_Renderer * renderer, SDL_Window * window)
|
||||
{
|
||||
WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata;
|
||||
|
||||
if (data->windowTex.driverdata) {
|
||||
WIIU_SDL_DestroyTexture(renderer, &data->windowTex);
|
||||
data->windowTex = (SDL_Texture) {0};
|
||||
}
|
||||
|
||||
/* Allocate a buffer for the window */
|
||||
data->windowTex = (SDL_Texture) {
|
||||
.format = SDL_PIXELFORMAT_RGBA8888,
|
||||
.r = 255, .g = 255, .b = 255, .a = 255,
|
||||
};
|
||||
|
||||
SDL_GetWindowSize(window, &data->windowTex.w, &data->windowTex.h);
|
||||
|
||||
/* Setup texture and color buffer for the window */
|
||||
WIIU_SDL_CreateTexture(renderer, &data->windowTex);
|
||||
}
|
||||
|
||||
int WIIU_SDL_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
{
|
||||
WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata;
|
||||
|
||||
GX2Surface *target;
|
||||
/* Set window or texture as target */
|
||||
WIIU_TextureData *tdata = (WIIU_TextureData *)((texture) ? texture->driverdata
|
||||
: data->windowTex.driverdata);
|
||||
|
||||
if (texture) {
|
||||
// Set texture as target
|
||||
WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata;
|
||||
target = &tdata->texture.surface;
|
||||
} else {
|
||||
// Set window texture as target
|
||||
WIIU_WindowData *wdata = (WIIU_WindowData *) SDL_GetWindowData(renderer->window, WIIU_WINDOW_DATA);
|
||||
target = &wdata->texture.surface;
|
||||
}
|
||||
/* Wait for the texture rendering to finish */
|
||||
WIIU_TextureCheckWaitRendering(data, tdata);
|
||||
|
||||
// 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 u_viewSize */
|
||||
data->u_viewSize = (WIIUVec4) {
|
||||
.x = (float)tdata->cbuf.surface.width,
|
||||
.y = (float)tdata->cbuf.surface.height,
|
||||
};
|
||||
|
||||
// Update u_viewSize
|
||||
data->u_viewSize[0] = data->cbuf.surface.width;
|
||||
data->u_viewSize[1] = data->cbuf.surface.height;
|
||||
/* Update context state */
|
||||
GX2SetColorBuffer(&tdata->cbuf, GX2_RENDER_TARGET_0);
|
||||
|
||||
// Update context state
|
||||
GX2SetContextState(data->ctx);
|
||||
GX2SetColorBuffer(&data->cbuf, GX2_RENDER_TARGET_0);
|
||||
// These may be unnecessary - see SDL_render.c: SDL_SetRenderTarget's calls
|
||||
// to UpdateViewport and UpdateClipRect. TODO for once the render is
|
||||
// basically working.
|
||||
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);
|
||||
|
||||
GX2SetAlphaTest(TRUE, GX2_COMPARE_FUNC_GREATER, 0.0f);
|
||||
GX2SetDepthOnlyControl(FALSE, FALSE, GX2_COMPARE_FUNC_NEVER);
|
||||
GX2SetColorControl(GX2_LOGIC_OP_COPY, 0xFF, FALSE, TRUE);
|
||||
GX2SetCullOnlyControl(GX2_FRONT_FACE_CCW, FALSE, FALSE);
|
||||
/* These may be unnecessary - see SDL_render.c: SDL_SetRenderTarget's calls
|
||||
to UpdateViewport and UpdateClipRect. TODO for once the render is
|
||||
basically working */
|
||||
GX2SetViewport(0, 0, (float)tdata->cbuf.surface.width, (float)tdata->cbuf.surface.height, 0.0f, 1.0f);
|
||||
GX2SetScissor(0, 0, (float)tdata->cbuf.surface.width, (float)tdata->cbuf.surface.height);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -162,11 +164,7 @@ void WIIU_SDL_DestroyRenderer(SDL_Renderer * renderer)
|
||||
{
|
||||
WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata;
|
||||
|
||||
while (data->listfree) {
|
||||
void *ptr = data->listfree;
|
||||
data->listfree = data->listfree->next;
|
||||
SDL_free(ptr);
|
||||
}
|
||||
WIIU_FreeRenderData(data);
|
||||
|
||||
free(data->ctx);
|
||||
|
||||
@@ -180,31 +178,35 @@ void WIIU_SDL_DestroyRenderer(SDL_Renderer * renderer)
|
||||
int WIIU_SDL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
|
||||
Uint32 format, void * pixels, int pitch)
|
||||
{
|
||||
WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata;
|
||||
Uint32 src_format;
|
||||
void *src_pixels;
|
||||
SDL_Texture* target = WIIU_GetRenderTarget(renderer);
|
||||
WIIU_TextureData* tdata = (WIIU_TextureData*) target->driverdata;
|
||||
Uint8 *src_image;
|
||||
int ret;
|
||||
|
||||
/* NOTE: The rect is already adjusted according to the viewport by
|
||||
* SDL_RenderReadPixels.
|
||||
*/
|
||||
SDL_RenderReadPixels */
|
||||
|
||||
if (rect->x < 0 || rect->x+rect->w > data->cbuf.surface.width ||
|
||||
rect->y < 0 || rect->y+rect->h > data->cbuf.surface.height) {
|
||||
if (rect->x < 0 || rect->x+rect->w > tdata->cbuf.surface.width ||
|
||||
rect->y < 0 || rect->y+rect->h > tdata->cbuf.surface.height) {
|
||||
return SDL_SetError("Tried to read outside of surface bounds");
|
||||
}
|
||||
|
||||
src_format = SDL_PIXELFORMAT_RGBA8888; // TODO once working: other formats/checks
|
||||
src_pixels = (void*)((Uint8 *) data->cbuf.surface.image +
|
||||
rect->y * data->cbuf.surface.pitch +
|
||||
rect->x * 4);
|
||||
src_image = GX2RLockSurfaceEx(&tdata->cbuf.surface, 0, GX2R_RESOURCE_LOCKED_READ_ONLY);
|
||||
|
||||
return SDL_ConvertPixels(rect->w, rect->h,
|
||||
src_format, src_pixels, data->cbuf.surface.pitch,
|
||||
format, pixels, pitch);
|
||||
/* Convert and copy the pixels to target buffer */
|
||||
ret = SDL_ConvertPixels(rect->w, rect->h, target->format,
|
||||
src_image + rect->y * tdata->cbuf.surface.pitch + rect->x * 4,
|
||||
tdata->cbuf.surface.pitch,
|
||||
format, pixels, pitch);
|
||||
|
||||
GX2RUnlockSurfaceEx(&tdata->cbuf.surface, 0, GX2R_RESOURCE_LOCKED_READ_ONLY);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
SDL_RenderDriver WIIU_RenderDriver = {
|
||||
SDL_RenderDriver WIIU_RenderDriver =
|
||||
{
|
||||
.CreateRenderer = WIIU_SDL_CreateRenderer,
|
||||
.info = {
|
||||
.name = "WiiU GX2",
|
||||
|
||||
@@ -1,7 +1,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) 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
|
||||
@@ -19,7 +19,6 @@
|
||||
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_render_wiiu_h
|
||||
@@ -27,60 +26,91 @@
|
||||
|
||||
#include "../SDL_sysrender.h"
|
||||
#include "SDL_pixels.h"
|
||||
#include <gx2r/buffer.h>
|
||||
#include <gx2/context.h>
|
||||
#include <gx2/sampler.h>
|
||||
#include <gx2/texture.h>
|
||||
#include <gx2/surface.h>
|
||||
#include <gx2/event.h>
|
||||
|
||||
typedef struct
|
||||
/* Driver internal data structures */
|
||||
typedef struct WIIUVec2 WIIUVec2;
|
||||
typedef struct WIIUVec3 WIIUVec3;
|
||||
typedef struct WIIUVec4 WIIUVec4;
|
||||
typedef struct WIIUPixFmt WIIUPixFmt;
|
||||
typedef struct WIIU_RenderAllocData WIIU_RenderAllocData;
|
||||
typedef struct WIIU_TextureDrawData WIIU_TextureDrawData;
|
||||
typedef struct WIIU_RenderData WIIU_RenderData;
|
||||
typedef struct WIIU_TextureData WIIU_TextureData;
|
||||
|
||||
struct WIIUVec2
|
||||
{
|
||||
union { float x, r; };
|
||||
union { float y, g; };
|
||||
};
|
||||
|
||||
struct WIIUVec3
|
||||
{
|
||||
union { float x, r; };
|
||||
union { float y, g; };
|
||||
union { float z, b; };
|
||||
};
|
||||
|
||||
struct WIIUVec4
|
||||
{
|
||||
union { float x, r; };
|
||||
union { float y, g; };
|
||||
union { float z, b; };
|
||||
union { float w, a; };
|
||||
};
|
||||
|
||||
struct WIIUPixFmt
|
||||
{
|
||||
GX2SurfaceFormat fmt;
|
||||
uint32_t compMap;
|
||||
};
|
||||
|
||||
struct WIIU_RenderAllocData
|
||||
{
|
||||
void *next;
|
||||
int ptr[];
|
||||
} WIIU_RenderAllocData;
|
||||
GX2RBuffer buffer;
|
||||
};
|
||||
|
||||
//Driver internal data structures
|
||||
typedef struct
|
||||
struct WIIU_TextureDrawData
|
||||
{
|
||||
void *next;
|
||||
WIIU_TextureData *texdata;
|
||||
};
|
||||
|
||||
struct WIIU_RenderData
|
||||
{
|
||||
GX2ColorBuffer cbuf;
|
||||
GX2ContextState *ctx;
|
||||
WIIU_RenderAllocData *listfree;
|
||||
float u_viewSize[4];
|
||||
} WIIU_RenderData;
|
||||
WIIU_TextureDrawData *listdraw;
|
||||
WIIUVec4 u_viewSize;
|
||||
SDL_Texture windowTex;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
struct WIIU_TextureData
|
||||
{
|
||||
GX2Sampler sampler;
|
||||
GX2Texture texture;
|
||||
float u_texSize[4];
|
||||
} WIIU_TextureData;
|
||||
GX2ColorBuffer cbuf;
|
||||
WIIUVec4 u_texSize;
|
||||
WIIUVec4 u_mod;
|
||||
int isRendering;
|
||||
};
|
||||
|
||||
static inline void *WIIU_AllocRenderData(WIIU_RenderData *r, size_t size) {
|
||||
WIIU_RenderAllocData *rdata = SDL_malloc(sizeof(WIIU_RenderAllocData) + size);
|
||||
rdata->next = r->listfree;
|
||||
r->listfree = rdata;
|
||||
return (void *)rdata->ptr;
|
||||
}
|
||||
|
||||
static inline void WIIU_FreeRenderData(WIIU_RenderData *r) {
|
||||
while (r->listfree) {
|
||||
void *ptr = r->listfree;
|
||||
r->listfree = r->listfree->next;
|
||||
SDL_free(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
//SDL_render API implementation
|
||||
/* SDL_render API implementation */
|
||||
SDL_Renderer *WIIU_SDL_CreateRenderer(SDL_Window * window, Uint32 flags);
|
||||
void WIIU_SDL_WindowEvent(SDL_Renderer * renderer,
|
||||
const SDL_WindowEvent *event);
|
||||
int WIIU_SDL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h);
|
||||
int WIIU_SDL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
|
||||
// SDL changes colour/alpha/blend values internally, this is just to notify us.
|
||||
// We don't care yet. TODO: could update GX2RBuffers less frequently with these?
|
||||
/*int WIIU_SDL_SetTextureColorMod(SDL_Renderer * renderer,
|
||||
int WIIU_SDL_SetTextureColorMod(SDL_Renderer * renderer,
|
||||
SDL_Texture * texture);
|
||||
int WIIU_SDL_SetTextureAlphaMod(SDL_Renderer * renderer,
|
||||
SDL_Texture * texture);
|
||||
int WIIU_SDL_SetTextureBlendMode(SDL_Renderer * renderer,
|
||||
SDL_Texture * texture);*/
|
||||
int WIIU_SDL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
const SDL_Rect * rect, const void *pixels,
|
||||
int pitch);
|
||||
@@ -108,28 +138,87 @@ void WIIU_SDL_RenderPresent(SDL_Renderer * renderer);
|
||||
void WIIU_SDL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture);
|
||||
void WIIU_SDL_DestroyRenderer(SDL_Renderer * renderer);
|
||||
|
||||
//Utility/helper functions
|
||||
static inline Uint32 TextureNextPow2(Uint32 w) {
|
||||
Uint32 n = 2;
|
||||
if(w == 0)
|
||||
/* Driver internal functions */
|
||||
void WIIU_SDL_CreateWindowTex(SDL_Renderer * renderer, SDL_Window * window);
|
||||
|
||||
/* Utility/helper functions */
|
||||
static inline GX2RBuffer * WIIU_AllocRenderData(WIIU_RenderData *r, GX2RBuffer buffer)
|
||||
{
|
||||
WIIU_RenderAllocData *rdata = SDL_malloc(sizeof(WIIU_RenderAllocData));
|
||||
|
||||
rdata->buffer = buffer;
|
||||
if (!GX2RCreateBuffer(&rdata->buffer)) {
|
||||
SDL_free(rdata);
|
||||
return 0;
|
||||
while(w > n)
|
||||
n <<= 1;
|
||||
return n;
|
||||
}
|
||||
|
||||
rdata->next = r->listfree;
|
||||
r->listfree = rdata;
|
||||
return &rdata->buffer;
|
||||
}
|
||||
|
||||
typedef struct WIIUPixFmt {
|
||||
GX2SurfaceFormat fmt;
|
||||
uint32_t compMap;
|
||||
} WIIUPixFmt;
|
||||
static inline void WIIU_FreeRenderData(WIIU_RenderData *r)
|
||||
{
|
||||
while (r->listfree) {
|
||||
WIIU_RenderAllocData *ptr = r->listfree;
|
||||
r->listfree = r->listfree->next;
|
||||
GX2RDestroyBufferEx(&ptr->buffer, 0);
|
||||
SDL_free(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
static inline WIIUPixFmt SDLFormatToWIIUFormat(Uint32 format) {
|
||||
static inline void WIIU_TextureStartRendering(WIIU_RenderData *r, WIIU_TextureData *t)
|
||||
{
|
||||
WIIU_TextureDrawData *d = SDL_malloc(sizeof(WIIU_TextureDrawData));
|
||||
t->isRendering = 1;
|
||||
d->texdata = t;
|
||||
d->next = r->listdraw;
|
||||
r->listdraw = d;
|
||||
}
|
||||
|
||||
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;
|
||||
SDL_free(d);
|
||||
}
|
||||
}
|
||||
|
||||
/* If the texture is currently being rendered and we change the content
|
||||
before the rendering is finished, the GPU will end up partially drawing
|
||||
the new data, so we wait for the GPU to finish rendering before
|
||||
updating the texture */
|
||||
static inline void WIIU_TextureCheckWaitRendering(WIIU_RenderData *r, WIIU_TextureData *t)
|
||||
{
|
||||
if (t->isRendering)
|
||||
{
|
||||
GX2DrawDone();
|
||||
WIIU_TextureDoneRendering(r);
|
||||
}
|
||||
}
|
||||
|
||||
static inline SDL_Texture * WIIU_GetRenderTarget(SDL_Renderer* renderer)
|
||||
{
|
||||
WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata;
|
||||
|
||||
if (renderer->target) {
|
||||
return renderer->target;
|
||||
}
|
||||
|
||||
return &data->windowTex;
|
||||
}
|
||||
|
||||
static inline WIIUPixFmt SDLFormatToWIIUFormat(Uint32 format)
|
||||
{
|
||||
WIIUPixFmt outFmt = { /* sane defaults? */
|
||||
.fmt = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8,
|
||||
.compMap = 0x00010203,
|
||||
};
|
||||
|
||||
switch (format) {
|
||||
/* packed16 formats: 4 bits/channel */
|
||||
/* packed16 formats: 4 bits/channel */
|
||||
case SDL_PIXELFORMAT_RGB444: /* aka XRGB4444 */
|
||||
case SDL_PIXELFORMAT_ARGB4444: {
|
||||
outFmt.fmt = GX2_SURFACE_FORMAT_UNORM_R4_G4_B4_A4;
|
||||
@@ -152,7 +241,7 @@ static inline WIIUPixFmt SDLFormatToWIIUFormat(Uint32 format) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* packed16 formats: 5 bits/channel */
|
||||
/* packed16 formats: 5 bits/channel */
|
||||
case SDL_PIXELFORMAT_RGB555: /* aka XRGB1555 */
|
||||
case SDL_PIXELFORMAT_ARGB1555: {
|
||||
outFmt.fmt = GX2_SURFACE_FORMAT_UNORM_R5_G5_B5_A1;
|
||||
@@ -176,7 +265,7 @@ static inline WIIUPixFmt SDLFormatToWIIUFormat(Uint32 format) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* packed16 formats: 565 */
|
||||
/* packed16 formats: 565 */
|
||||
case SDL_PIXELFORMAT_RGB565: {
|
||||
outFmt.fmt = GX2_SURFACE_FORMAT_UNORM_R5_G6_B5;
|
||||
outFmt.compMap = 0x00010203;
|
||||
@@ -188,7 +277,7 @@ static inline WIIUPixFmt SDLFormatToWIIUFormat(Uint32 format) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* packed32 formats */
|
||||
/* packed32 formats */
|
||||
case SDL_PIXELFORMAT_RGBA8888:
|
||||
case SDL_PIXELFORMAT_RGBX8888: {
|
||||
outFmt.fmt = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
|
||||
@@ -218,7 +307,7 @@ static inline WIIUPixFmt SDLFormatToWIIUFormat(Uint32 format) {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
/* TODO return an error */
|
||||
/* TODO return an error */
|
||||
printf("SDL: WiiU format not recognised (SDL: %08X)\n", format);
|
||||
break;
|
||||
}
|
||||
|
||||
154
src/render/wiiu/SDL_rpresent_wiiu.c
Normal file
154
src/render/wiiu/SDL_rpresent_wiiu.c
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
/* Restore SDL context state */
|
||||
GX2SetContextState(data->ctx);
|
||||
}
|
||||
|
||||
#endif /* SDL_VIDEO_RENDER_WIIU */
|
||||
@@ -1,7 +1,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) 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
|
||||
@@ -23,42 +23,45 @@
|
||||
|
||||
#if SDL_VIDEO_RENDER_WIIU
|
||||
|
||||
#include "../../video/wiiu/SDL_wiiuvideo.h"
|
||||
#include "../SDL_sysrender.h"
|
||||
#include "SDL_hints.h"
|
||||
#include "SDL_render_wiiu.h"
|
||||
|
||||
#include <gx2/context.h>
|
||||
#include <gx2/texture.h>
|
||||
#include <gx2/sampler.h>
|
||||
#include <gx2/mem.h>
|
||||
#include <gx2r/surface.h>
|
||||
#include <gx2r/resource.h>
|
||||
|
||||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
int WIIU_SDL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
{
|
||||
WIIUPixFmt gx2_fmt;
|
||||
BOOL res;
|
||||
WIIU_TextureData *tdata = (WIIU_TextureData *) SDL_calloc(1, sizeof(*tdata));
|
||||
if (!tdata)
|
||||
if (!tdata) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
/* Setup sampler */
|
||||
if (texture->scaleMode == SDL_ScaleModeNearest) {
|
||||
GX2InitSampler(&tdata->sampler, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_POINT);
|
||||
} else {
|
||||
GX2InitSampler(&tdata->sampler, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_LINEAR);
|
||||
}
|
||||
|
||||
// Setup sampler
|
||||
GX2InitSampler(&tdata->sampler, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_LINEAR);
|
||||
|
||||
gx2_fmt = SDLFormatToWIIUFormat(texture->format);
|
||||
|
||||
/* Setup GX2Texture */
|
||||
tdata->texture.surface.width = texture->w;
|
||||
tdata->texture.surface.height = texture->h;
|
||||
tdata->texture.surface.format = gx2_fmt.fmt;
|
||||
tdata->texture.surface.depth = 1; //?
|
||||
tdata->texture.surface.depth = 1;
|
||||
tdata->texture.surface.dim = GX2_SURFACE_DIM_TEXTURE_2D;
|
||||
tdata->texture.surface.tileMode = GX2_TILE_MODE_LINEAR_ALIGNED;
|
||||
tdata->texture.surface.use = GX2_SURFACE_USE_TEXTURE;
|
||||
tdata->texture.surface.mipLevels = 1;
|
||||
tdata->texture.viewNumMips = 1;
|
||||
tdata->texture.viewNumSlices = 1;
|
||||
@@ -66,82 +69,145 @@ int WIIU_SDL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
GX2CalcSurfaceSizeAndAlignment(&tdata->texture.surface);
|
||||
GX2InitTextureRegs(&tdata->texture);
|
||||
|
||||
tdata->texture.surface.image = memalign(tdata->texture.surface.alignment, tdata->texture.surface.imageSize);
|
||||
if(!tdata->texture.surface.image)
|
||||
{
|
||||
/* Setup GX2ColorBuffer */
|
||||
tdata->cbuf.surface = tdata->texture.surface;
|
||||
tdata->cbuf.viewNumSlices = 1;
|
||||
GX2InitColorBufferRegs(&tdata->cbuf);
|
||||
|
||||
/* Allocate the texture's surface */
|
||||
res = GX2RCreateSurface(
|
||||
&tdata->texture.surface,
|
||||
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
|
||||
);
|
||||
if (!res) {
|
||||
SDL_free(tdata);
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
tdata->u_texSize[0] = texture->w;
|
||||
tdata->u_texSize[1] = texture->h;
|
||||
/* Allocate a colour buffer, using the same backing buffer */
|
||||
res = GX2RCreateSurfaceUserMemory(
|
||||
&tdata->cbuf.surface,
|
||||
tdata->texture.surface.image,
|
||||
tdata->texture.surface.mipmaps,
|
||||
tdata->texture.surface.resourceFlags
|
||||
);
|
||||
if (!res) {
|
||||
GX2RDestroySurfaceEx(&tdata->texture.surface, 0);
|
||||
SDL_free(tdata);
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
/* Initialize texture size uniform */
|
||||
tdata->u_texSize = (WIIUVec4) {
|
||||
.x = texture->w,
|
||||
.y = texture->h,
|
||||
};
|
||||
|
||||
/* Initialize color modifier uniform */
|
||||
tdata->u_mod = (WIIUVec4) {
|
||||
.r = (float)texture->r / 255.0f,
|
||||
.g = (float)texture->g / 255.0f,
|
||||
.b = (float)texture->b / 255.0f,
|
||||
.a = (float)texture->a / 255.0f,
|
||||
};
|
||||
|
||||
/* Setup texture driver data */
|
||||
texture->driverdata = tdata;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Somewhat adapted from SDL_render.c: SDL_LockTextureNative
|
||||
// The app basically wants a pointer to a particular rectangle as well as
|
||||
// write access to it. We can do that without any special graphics code
|
||||
/* Somewhat adapted from SDL_render.c: SDL_LockTextureNative
|
||||
The app basically wants a pointer to a particular rectangle as well as
|
||||
write access to it. Easy GX2R! */
|
||||
int WIIU_SDL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
const SDL_Rect * rect, void **pixels, int *pitch)
|
||||
{
|
||||
WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata;
|
||||
WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata;
|
||||
Uint32 BytesPerPixel = SDL_BYTESPERPIXEL(texture->format);
|
||||
void* pixel_buffer;
|
||||
|
||||
// Calculate pointer to first pixel in rect
|
||||
*pixels = (void *) ((Uint8 *) tdata->texture.surface.image +
|
||||
/* Wait for the texture rendering to finish */
|
||||
WIIU_TextureCheckWaitRendering(data, tdata);
|
||||
|
||||
pixel_buffer = GX2RLockSurfaceEx(&tdata->texture.surface, 0, 0);
|
||||
|
||||
/* Calculate pointer to first pixel in rect */
|
||||
*pixels = (void *) ((Uint8 *) pixel_buffer +
|
||||
rect->y * (tdata->texture.surface.pitch * BytesPerPixel) +
|
||||
rect->x * BytesPerPixel);
|
||||
*pitch = (tdata->texture.surface.pitch * BytesPerPixel);
|
||||
|
||||
// Not sure we even need to bother keeping track of this
|
||||
/* Not sure we even need to bother keeping track of this */
|
||||
texture->locked_rect = *rect;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WIIU_SDL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
{
|
||||
WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata;
|
||||
// TODO check this is actually needed
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE,
|
||||
tdata->texture.surface.image, tdata->texture.surface.imageSize);
|
||||
GX2RUnlockSurfaceEx(&tdata->texture.surface, 0, 0);
|
||||
}
|
||||
|
||||
int WIIU_SDL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
const SDL_Rect * rect, const void *pixels, int pitch)
|
||||
{
|
||||
WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata;
|
||||
Uint32 BytesPerPixel;
|
||||
Uint8 *src, *dst;
|
||||
int row;
|
||||
size_t length;
|
||||
Uint32 BytesPerPixel = SDL_BYTESPERPIXEL(texture->format);
|
||||
size_t length = rect->w * BytesPerPixel;
|
||||
Uint8 *src = (Uint8 *) pixels, *dst;
|
||||
int row, dst_pitch;
|
||||
|
||||
/* We write the rules, and we say all textures are streaming */
|
||||
WIIU_SDL_LockTexture(renderer, texture, rect, (void**)&dst, &dst_pitch);
|
||||
|
||||
BytesPerPixel = SDL_BYTESPERPIXEL(texture->format);
|
||||
src = (Uint8 *) pixels;
|
||||
dst = (Uint8 *) tdata->texture.surface.image +
|
||||
rect->y * (tdata->texture.surface.pitch * BytesPerPixel) +
|
||||
rect->x * BytesPerPixel;
|
||||
length = rect->w * BytesPerPixel;
|
||||
for (row = 0; row < rect->h; ++row) {
|
||||
SDL_memcpy(dst, src, length);
|
||||
src += pitch;
|
||||
dst += (tdata->texture.surface.pitch * BytesPerPixel);
|
||||
dst += dst_pitch;
|
||||
}
|
||||
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE,
|
||||
tdata->texture.surface.image, tdata->texture.surface.imageSize);
|
||||
WIIU_SDL_UnlockTexture(renderer, texture);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WIIU_SDL_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
{
|
||||
WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata;
|
||||
|
||||
/* Compute color mod */
|
||||
tdata->u_mod.r = (float)texture->r / 255.0f;
|
||||
tdata->u_mod.g = (float)texture->g / 255.0f;
|
||||
tdata->u_mod.b = (float)texture->b / 255.0f;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WIIU_SDL_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
{
|
||||
WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata;
|
||||
|
||||
/* Compute alpha mod */
|
||||
tdata->u_mod.a = (float)texture->a / 255.0f;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WIIU_SDL_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
{
|
||||
WIIU_TextureData *tdata;
|
||||
if (texture == NULL || texture->driverdata == NULL) return;
|
||||
tdata = (WIIU_TextureData *) texture->driverdata;
|
||||
free(tdata->texture.surface.image);
|
||||
WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata;
|
||||
WIIU_TextureData *tdata = (WIIU_TextureData *) texture->driverdata;
|
||||
|
||||
/* Wait for the texture rendering to finish */
|
||||
WIIU_TextureCheckWaitRendering(data, tdata);
|
||||
|
||||
GX2RDestroySurfaceEx(&tdata->cbuf.surface, 0);
|
||||
GX2RDestroySurfaceEx(&tdata->texture.surface, 0);
|
||||
|
||||
SDL_free(tdata);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,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) 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
|
||||
@@ -19,49 +19,44 @@
|
||||
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/SDL_wiiuvideo.h"
|
||||
#include "../SDL_sysrender.h"
|
||||
#include "SDL_hints.h"
|
||||
#include "SDL_render_wiiu.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
void WIIU_SDL_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
|
||||
{
|
||||
if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
|
||||
// Re-init the colour buffer etc. for new window size
|
||||
// TODO check: what if we're rendering to a texture when this happens?
|
||||
// SDL may handle this already, see SDL_render.c: SDL_RendererEventWatch
|
||||
/* Re-init the colour buffer etc. for new window size
|
||||
TODO check: what if we're rendering to a texture when this happens?
|
||||
SDL may handle this already, see SDL_render.c: SDL_RendererEventWatch */
|
||||
WIIU_SDL_CreateWindowTex(renderer, renderer->window);
|
||||
WIIU_SDL_SetRenderTarget(renderer, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// We always output at whatever res the window is.
|
||||
// This may need to change if SDL_wiiuvideo is ever folded into SDL_render -
|
||||
// see SDL_*WindowTexture from SDL_video.c for how this could be done
|
||||
int WIIU_SDL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h) {
|
||||
/* We always output at whatever res the window is.
|
||||
This may need to change if SDL_wiiuvideo is ever folded into SDL_render -
|
||||
see SDL_*WindowTexture from SDL_video.c for how this could be done */
|
||||
int WIIU_SDL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h)
|
||||
{
|
||||
SDL_GetWindowSize(renderer->window, w, h);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We handle all viewport changes in the render functions and shaders, so we
|
||||
// don't actually have to do anything here. SDL still requires we implement it.
|
||||
int WIIU_SDL_UpdateViewport(SDL_Renderer * renderer) {
|
||||
/* We handle all viewport changes in the render functions and shaders, so we
|
||||
don't actually have to do anything here. SDL still requires we implement it. */
|
||||
int WIIU_SDL_UpdateViewport(SDL_Renderer * renderer)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Ideally this should change the GX2SetScissor values, but SetRenderTarget
|
||||
// needs refactoring first or these get overwritten.
|
||||
int WIIU_SDL_UpdateClipRect(SDL_Renderer * renderer) {
|
||||
/* Ideally this should change the GX2SetScissor values, but SetRenderTarget
|
||||
needs refactoring first or these get overwritten. */
|
||||
int WIIU_SDL_UpdateClipRect(SDL_Renderer * renderer)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,13 @@
|
||||
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
|
||||
@@ -34,16 +41,8 @@
|
||||
#include "../../events/SDL_keyboard_c.h"
|
||||
#include "SDL_wiiuvideo.h"
|
||||
|
||||
#include <gfd.h>
|
||||
#include <gx2/draw.h>
|
||||
#include <gx2/shaders.h>
|
||||
#include <gx2/mem.h>
|
||||
#include <gx2/registers.h>
|
||||
#include <gx2r/draw.h>
|
||||
#include <gx2r/buffer.h>
|
||||
#include <whb/proc.h>
|
||||
#include <whb/gfx.h>
|
||||
#include <coreinit/memdefaultheap.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -53,46 +52,13 @@ 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);
|
||||
static int WIIU_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch);
|
||||
static int WIIU_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects);
|
||||
static void WIIU_DestroyWindowFramebuffer(_THIS, SDL_Window *window);
|
||||
|
||||
#define SCREEN_WIDTH 1280
|
||||
#define SCREEN_HEIGHT 720
|
||||
|
||||
static const float u_viewSize[4] = {(float)SCREEN_WIDTH, (float)SCREEN_HEIGHT};
|
||||
static const float u_texSize[4] = {(float)SCREEN_WIDTH, (float)SCREEN_HEIGHT};
|
||||
static const float u_mod[4] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
|
||||
static const float tex_coord_vb[] =
|
||||
{
|
||||
0.0f, (float)SCREEN_HEIGHT,
|
||||
(float)SCREEN_WIDTH, (float)SCREEN_HEIGHT,
|
||||
(float)SCREEN_WIDTH, 0.0f,
|
||||
0.0f, 0.0f,
|
||||
};
|
||||
|
||||
static GX2RBuffer tex_coord_buffer = {
|
||||
GX2R_RESOURCE_BIND_VERTEX_BUFFER |
|
||||
GX2R_RESOURCE_USAGE_CPU_READ |
|
||||
GX2R_RESOURCE_USAGE_CPU_WRITE |
|
||||
GX2R_RESOURCE_USAGE_GPU_READ,
|
||||
2 * sizeof(float), 4, NULL
|
||||
};
|
||||
static GX2RBuffer position_buffer = {
|
||||
GX2R_RESOURCE_BIND_VERTEX_BUFFER |
|
||||
GX2R_RESOURCE_USAGE_CPU_READ |
|
||||
GX2R_RESOURCE_USAGE_CPU_WRITE |
|
||||
GX2R_RESOURCE_USAGE_GPU_READ,
|
||||
2 * sizeof(float), 4, NULL
|
||||
};
|
||||
|
||||
static GX2Sampler sampler = {0};
|
||||
|
||||
static int WIIU_VideoInit(_THIS)
|
||||
{
|
||||
SDL_DisplayMode mode;
|
||||
void *buffer = NULL;
|
||||
|
||||
WHBProcInit();
|
||||
WHBGfxInit();
|
||||
@@ -100,20 +66,6 @@ static int WIIU_VideoInit(_THIS)
|
||||
// setup shader
|
||||
wiiuInitTextureShader();
|
||||
|
||||
// setup vertex position attribute
|
||||
GX2RCreateBuffer(&position_buffer);
|
||||
|
||||
// setup vertex texture coordinates attribute
|
||||
GX2RCreateBuffer(&tex_coord_buffer);
|
||||
buffer = GX2RLockBufferEx(&tex_coord_buffer, 0);
|
||||
if (buffer) {
|
||||
memcpy(buffer, tex_coord_vb, tex_coord_buffer.elemSize * tex_coord_buffer.elemCount);
|
||||
}
|
||||
GX2RUnlockBufferEx(&tex_coord_buffer, 0);
|
||||
|
||||
// initialize a sampler
|
||||
GX2InitSampler(&sampler, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_LINEAR);
|
||||
|
||||
// add default mode (1280x720)
|
||||
mode.format = SDL_PIXELFORMAT_RGBA8888;
|
||||
mode.w = SCREEN_WIDTH;
|
||||
@@ -130,121 +82,80 @@ static int WIIU_VideoInit(_THIS)
|
||||
|
||||
static void WIIU_VideoQuit(_THIS)
|
||||
{
|
||||
GX2RDestroyBufferEx(&position_buffer, 0);
|
||||
GX2RDestroyBufferEx(&tex_coord_buffer, 0);
|
||||
wiiuFreeTextureShader();
|
||||
WHBGfxShutdown();
|
||||
WHBProcShutdown();
|
||||
}
|
||||
|
||||
static int WIIU_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, void **pixels, int *pitch)
|
||||
{
|
||||
WIIU_WindowData *data;
|
||||
static int WIIU_CreateSDLWindow(_THIS, SDL_Window *window) {
|
||||
WIIU_VideoDeviceData* ddata = (WIIU_VideoDeviceData*) _this->driverdata;
|
||||
|
||||
// hold a pointer to our stuff
|
||||
data = SDL_calloc(1, sizeof(WIIU_WindowData));
|
||||
/* If this window wants to be mirrored (no _ONLY flags) */
|
||||
if (!(window->flags &
|
||||
(SDL_WINDOW_WIIU_TV_ONLY | SDL_WINDOW_WIIU_GAMEPAD_ONLY))) {
|
||||
/* Only one window can exist in this state */
|
||||
if (ddata->drc_window_exists ||
|
||||
ddata->tv_window_exists ||
|
||||
ddata->mirrored_window_exists) {
|
||||
return SDL_SetError(
|
||||
"WiiU only supports one window when mirroring the TV and "
|
||||
"Gamepad. https://github.com/yawut/SDL/wiki/Custom-Window-Flags"
|
||||
);
|
||||
}
|
||||
|
||||
// create a gx2 texture
|
||||
data->texture.surface.use = GX2_SURFACE_USE_TEXTURE;
|
||||
data->texture.surface.width = window->w;
|
||||
data->texture.surface.height = window->h;
|
||||
data->texture.surface.dim = GX2_SURFACE_DIM_TEXTURE_2D;
|
||||
data->texture.surface.depth = 1;
|
||||
data->texture.surface.mipLevels = 1;
|
||||
data->texture.surface.format = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
|
||||
data->texture.surface.tileMode = GX2_TILE_MODE_LINEAR_ALIGNED;
|
||||
data->texture.viewNumSlices = 1;
|
||||
data->texture.viewNumMips = 1;
|
||||
data->texture.compMap = 0x00010203;
|
||||
GX2CalcSurfaceSizeAndAlignment(&data->texture.surface);
|
||||
GX2InitTextureRegs(&data->texture);
|
||||
/* Okay! */
|
||||
ddata->mirrored_window_exists = SDL_TRUE;
|
||||
|
||||
data->texture.surface.image = MEMAllocFromDefaultHeapEx(data->texture.surface.imageSize, data->texture.surface.alignment);
|
||||
/* If this window wants the TV */
|
||||
} else if (window->flags & SDL_WINDOW_WIIU_TV_ONLY) {
|
||||
/* Check if a TV window already exists */
|
||||
if (ddata->tv_window_exists) {
|
||||
return SDL_SetError(
|
||||
"WiiU only supports one window on the TV. "
|
||||
"https://github.com/yawut/SDL/wiki/Custom-Window-Flags"
|
||||
);
|
||||
/* Check if a mirrored window exists */
|
||||
} else if (ddata->mirrored_window_exists) {
|
||||
return SDL_SetError(
|
||||
"WiiU only supports one window when mirroring the TV and "
|
||||
"Gamepad. https://github.com/yawut/SDL/wiki/Custom-Window-Flags"
|
||||
);
|
||||
}
|
||||
|
||||
// create sdl surface framebuffer
|
||||
data->surface = SDL_CreateRGBSurfaceWithFormatFrom(
|
||||
data->texture.surface.image, // pixels
|
||||
window->w, window->h, // width, height
|
||||
32, window->w * 4, // depth, pitch
|
||||
SDL_PIXELFORMAT_RGBA8888 // format
|
||||
);
|
||||
ddata->tv_window_exists = SDL_TRUE;
|
||||
|
||||
*format = SDL_PIXELFORMAT_RGBA8888;
|
||||
*pixels = data->surface->pixels;
|
||||
*pitch = data->surface->pitch;
|
||||
/* If this window wants the Gamepad */
|
||||
} else if (window->flags & SDL_WINDOW_WIIU_GAMEPAD_ONLY) {
|
||||
/* Check if a TV window already exists */
|
||||
if (ddata->drc_window_exists) {
|
||||
return SDL_SetError(
|
||||
"WiiU only supports one window on the Gamepad. "
|
||||
"https://github.com/yawut/SDL/wiki/Custom-Window-Flags"
|
||||
);
|
||||
/* Check if a mirrored window exists */
|
||||
} else if (ddata->mirrored_window_exists) {
|
||||
return SDL_SetError(
|
||||
"WiiU only supports one window when mirroring the TV and "
|
||||
"Gamepad. https://github.com/yawut/SDL/wiki/Custom-Window-Flags"
|
||||
);
|
||||
}
|
||||
|
||||
SDL_SetWindowData(window, WIIU_WINDOW_DATA, data);
|
||||
|
||||
// inform SDL we're ready to accept inputs
|
||||
ddata->drc_window_exists = SDL_TRUE;
|
||||
}
|
||||
SDL_SetKeyboardFocus(window);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void render_scene(WIIU_WindowData *data) {
|
||||
WHBGfxClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
wiiuSetTextureShader();
|
||||
static void WIIU_DestroyWindow(_THIS, SDL_Window * window) {
|
||||
WIIU_VideoDeviceData* ddata = (WIIU_VideoDeviceData*) _this->driverdata;
|
||||
|
||||
GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[0].offset, 4, (uint32_t *)u_viewSize);
|
||||
GX2SetVertexUniformReg(wiiuTextureShader.vertexShader->uniformVars[1].offset, 4, (uint32_t *)u_texSize);
|
||||
GX2SetPixelUniformReg(wiiuTextureShader.pixelShader->uniformVars[0].offset, 4, (uint32_t*)u_mod);
|
||||
GX2RSetAttributeBuffer(&position_buffer, 0, position_buffer.elemSize, 0);
|
||||
GX2RSetAttributeBuffer(&tex_coord_buffer, 1, tex_coord_buffer.elemSize, 0);
|
||||
|
||||
GX2SetPixelTexture(&data->texture, wiiuTextureShader.pixelShader->samplerVars[0].location);
|
||||
GX2SetPixelSampler(&sampler, wiiuTextureShader.pixelShader->samplerVars[0].location);
|
||||
|
||||
GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);
|
||||
}
|
||||
|
||||
static int WIIU_UpdateWindowFramebuffer(_THIS, SDL_Window *window, const SDL_Rect *rects, int numrects)
|
||||
{
|
||||
WIIU_WindowData *data = (WIIU_WindowData *) SDL_GetWindowData(window, WIIU_WINDOW_DATA);
|
||||
Uint32 flags = SDL_GetWindowFlags(window);
|
||||
float a_position[8];
|
||||
float* buffer;
|
||||
int x, y, w, h;
|
||||
|
||||
SDL_GetWindowPosition(window, &x, &y);
|
||||
SDL_GetWindowSize(window, &w, &h);
|
||||
a_position[0] = (float)x; a_position[1] = (float)y;
|
||||
a_position[2] = (float)(x + w); a_position[3] = (float)y;
|
||||
a_position[4] = (float)(x + w); a_position[5] = (float)(y + h);
|
||||
a_position[6] = (float)x; a_position[7] = (float)(y + h);
|
||||
|
||||
buffer = GX2RLockBufferEx(&position_buffer, 0);
|
||||
if (buffer) {
|
||||
memcpy(buffer, a_position, position_buffer.elemSize * position_buffer.elemCount);
|
||||
if (window->flags & SDL_WINDOW_WIIU_TV_ONLY) {
|
||||
ddata->tv_window_exists = SDL_FALSE;
|
||||
} else if (window->flags & SDL_WINDOW_WIIU_GAMEPAD_ONLY) {
|
||||
ddata->drc_window_exists = SDL_FALSE;
|
||||
} else {
|
||||
ddata->mirrored_window_exists = SDL_FALSE;
|
||||
}
|
||||
GX2RUnlockBufferEx(&position_buffer, 0);
|
||||
|
||||
GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, data->texture.surface.image, data->texture.surface.imageSize);
|
||||
|
||||
WHBGfxBeginRender();
|
||||
|
||||
if (!(flags & SDL_WINDOW_WIIU_GAMEPAD_ONLY)) {
|
||||
WHBGfxBeginRenderTV();
|
||||
render_scene(data);
|
||||
WHBGfxFinishRenderTV();
|
||||
}
|
||||
|
||||
if (!(flags & SDL_WINDOW_WIIU_TV_ONLY)) {
|
||||
WHBGfxBeginRenderDRC();
|
||||
render_scene(data);
|
||||
WHBGfxFinishRenderDRC();
|
||||
}
|
||||
|
||||
WHBGfxFinishRender();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void WIIU_DestroyWindowFramebuffer(_THIS, SDL_Window *window)
|
||||
{
|
||||
WIIU_WindowData *data = (WIIU_WindowData*) SDL_GetWindowData(window, WIIU_WINDOW_DATA);
|
||||
SDL_FreeSurface(data->surface);
|
||||
MEMFreeToDefaultHeap(data->texture.surface.image);
|
||||
SDL_free(data);
|
||||
}
|
||||
|
||||
static int WIIU_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
|
||||
@@ -263,6 +174,7 @@ static int WIIU_Available(void)
|
||||
|
||||
static void WIIU_DeleteDevice(SDL_VideoDevice *device)
|
||||
{
|
||||
SDL_free(device->driverdata);
|
||||
SDL_free(device);
|
||||
}
|
||||
|
||||
@@ -276,13 +188,19 @@ static SDL_VideoDevice *WIIU_CreateDevice(int devindex)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
device->driverdata = (void*) SDL_calloc(1, sizeof(WIIU_VideoDeviceData));
|
||||
if (!device->driverdata) {
|
||||
SDL_OutOfMemory();
|
||||
SDL_free(device);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
device->VideoInit = WIIU_VideoInit;
|
||||
device->VideoQuit = WIIU_VideoQuit;
|
||||
device->SetDisplayMode = WIIU_SetDisplayMode;
|
||||
device->PumpEvents = WIIU_PumpEvents;
|
||||
device->CreateWindowFramebuffer = WIIU_CreateWindowFramebuffer;
|
||||
device->UpdateWindowFramebuffer = WIIU_UpdateWindowFramebuffer;
|
||||
device->DestroyWindowFramebuffer = WIIU_DestroyWindowFramebuffer;
|
||||
device->CreateSDLWindow = WIIU_CreateSDLWindow;
|
||||
device->DestroyWindow = WIIU_DestroyWindow;
|
||||
|
||||
device->free = WIIU_DeleteDevice;
|
||||
|
||||
|
||||
@@ -35,4 +35,11 @@ typedef struct
|
||||
GX2Texture texture;
|
||||
} WIIU_WindowData;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SDL_bool tv_window_exists;
|
||||
SDL_bool drc_window_exists;
|
||||
SDL_bool mirrored_window_exists;
|
||||
} WIIU_VideoDeviceData;
|
||||
|
||||
#endif //SDL_wiiuvideo_h
|
||||
|
||||
Reference in New Issue
Block a user