|
@@ -23,6 +23,7 @@
|
|
|
#if SDL_VIDEO_RENDER_PSP
|
|
|
|
|
|
#include "SDL_hints.h"
|
|
|
+#include "SDL_assert.h"
|
|
|
#include "../SDL_sysrender.h"
|
|
|
|
|
|
#include <pspkernel.h>
|
|
@@ -42,74 +43,6 @@
|
|
|
|
|
|
/* PSP renderer implementation, based on the PGE */
|
|
|
|
|
|
-
|
|
|
-extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags);
|
|
|
-
|
|
|
-
|
|
|
-static SDL_Renderer *PSP_CreateRenderer(SDL_Window * window, Uint32 flags);
|
|
|
-static void PSP_WindowEvent(SDL_Renderer * renderer,
|
|
|
- const SDL_WindowEvent *event);
|
|
|
-static int PSP_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
|
|
|
-static int PSP_SetTextureColorMod(SDL_Renderer * renderer,
|
|
|
- SDL_Texture * texture);
|
|
|
-static int PSP_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
|
|
- const SDL_Rect * rect, const void *pixels,
|
|
|
- int pitch);
|
|
|
-static int PSP_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
|
|
- const SDL_Rect * rect, void **pixels, int *pitch);
|
|
|
-static void PSP_UnlockTexture(SDL_Renderer * renderer,
|
|
|
- SDL_Texture * texture);
|
|
|
-static int PSP_SetRenderTarget(SDL_Renderer * renderer,
|
|
|
- SDL_Texture * texture);
|
|
|
-static int PSP_UpdateViewport(SDL_Renderer * renderer);
|
|
|
-static int PSP_RenderClear(SDL_Renderer * renderer);
|
|
|
-static int PSP_RenderDrawPoints(SDL_Renderer * renderer,
|
|
|
- const SDL_FPoint * points, int count);
|
|
|
-static int PSP_RenderDrawLines(SDL_Renderer * renderer,
|
|
|
- const SDL_FPoint * points, int count);
|
|
|
-static int PSP_RenderFillRects(SDL_Renderer * renderer,
|
|
|
- const SDL_FRect * rects, int count);
|
|
|
-static int PSP_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
|
|
|
- const SDL_Rect * srcrect,
|
|
|
- const SDL_FRect * dstrect);
|
|
|
-static int PSP_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
|
|
|
- Uint32 pixel_format, void * pixels, int pitch);
|
|
|
-static int PSP_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 void PSP_RenderPresent(SDL_Renderer * renderer);
|
|
|
-static void PSP_DestroyTexture(SDL_Renderer * renderer,
|
|
|
- SDL_Texture * texture);
|
|
|
-static void PSP_DestroyRenderer(SDL_Renderer * renderer);
|
|
|
-
|
|
|
-/*
|
|
|
-SDL_RenderDriver PSP_RenderDriver = {
|
|
|
- PSP_CreateRenderer,
|
|
|
- {
|
|
|
- "PSP",
|
|
|
- (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE),
|
|
|
- 1,
|
|
|
- {SDL_PIXELFORMAT_ABGR8888},
|
|
|
- 0,
|
|
|
- 0}
|
|
|
-};
|
|
|
-*/
|
|
|
-SDL_RenderDriver PSP_RenderDriver = {
|
|
|
- .CreateRenderer = PSP_CreateRenderer,
|
|
|
- .info = {
|
|
|
- .name = "PSP",
|
|
|
- .flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE,
|
|
|
- .num_texture_formats = 4,
|
|
|
- .texture_formats = { [0] = SDL_PIXELFORMAT_BGR565,
|
|
|
- [1] = SDL_PIXELFORMAT_ABGR1555,
|
|
|
- [2] = SDL_PIXELFORMAT_ABGR4444,
|
|
|
- [3] = SDL_PIXELFORMAT_ABGR8888,
|
|
|
- },
|
|
|
- .max_texture_width = 512,
|
|
|
- .max_texture_height = 512,
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
#define PSP_SCREEN_WIDTH 480
|
|
|
#define PSP_SCREEN_HEIGHT 272
|
|
|
|
|
@@ -169,6 +102,42 @@ typedef struct
|
|
|
|
|
|
} VertTV;
|
|
|
|
|
|
+#define PI 3.14159265358979f
|
|
|
+
|
|
|
+#define radToDeg(x) ((x)*180.f/PI)
|
|
|
+#define degToRad(x) ((x)*PI/180.f)
|
|
|
+
|
|
|
+float MathAbs(float x)
|
|
|
+{
|
|
|
+ float result;
|
|
|
+
|
|
|
+ __asm__ volatile (
|
|
|
+ "mtv %1, S000\n"
|
|
|
+ "vabs.s S000, S000\n"
|
|
|
+ "mfv %0, S000\n"
|
|
|
+ : "=r"(result) : "r"(x));
|
|
|
+
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+void MathSincos(float r, float *s, float *c)
|
|
|
+{
|
|
|
+ __asm__ volatile (
|
|
|
+ "mtv %2, S002\n"
|
|
|
+ "vcst.s S003, VFPU_2_PI\n"
|
|
|
+ "vmul.s S002, S002, S003\n"
|
|
|
+ "vrot.p C000, S002, [s, c]\n"
|
|
|
+ "mfv %0, S000\n"
|
|
|
+ "mfv %1, S001\n"
|
|
|
+ : "=r"(*s), "=r"(*c): "r"(r));
|
|
|
+}
|
|
|
+
|
|
|
+void Swap(float *a, float *b)
|
|
|
+{
|
|
|
+ float n=*a;
|
|
|
+ *a = *b;
|
|
|
+ *b = n;
|
|
|
+}
|
|
|
|
|
|
/* Return next power of 2 */
|
|
|
static int
|
|
@@ -326,123 +295,9 @@ int TextureUnswizzle(PSP_TextureData *psp_texture)
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
-SDL_Renderer *
|
|
|
-PSP_CreateRenderer(SDL_Window * window, Uint32 flags)
|
|
|
-{
|
|
|
-
|
|
|
- SDL_Renderer *renderer;
|
|
|
- PSP_RenderData *data;
|
|
|
- int pixelformat;
|
|
|
- renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
|
|
|
- if (!renderer) {
|
|
|
- SDL_OutOfMemory();
|
|
|
- return NULL;
|
|
|
- }
|
|
|
-
|
|
|
- data = (PSP_RenderData *) SDL_calloc(1, sizeof(*data));
|
|
|
- if (!data) {
|
|
|
- PSP_DestroyRenderer(renderer);
|
|
|
- SDL_OutOfMemory();
|
|
|
- return NULL;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- renderer->WindowEvent = PSP_WindowEvent;
|
|
|
- renderer->CreateTexture = PSP_CreateTexture;
|
|
|
- renderer->SetTextureColorMod = PSP_SetTextureColorMod;
|
|
|
- renderer->UpdateTexture = PSP_UpdateTexture;
|
|
|
- renderer->LockTexture = PSP_LockTexture;
|
|
|
- renderer->UnlockTexture = PSP_UnlockTexture;
|
|
|
- renderer->SetRenderTarget = PSP_SetRenderTarget;
|
|
|
- renderer->UpdateViewport = PSP_UpdateViewport;
|
|
|
- renderer->RenderClear = PSP_RenderClear;
|
|
|
- renderer->RenderDrawPoints = PSP_RenderDrawPoints;
|
|
|
- renderer->RenderDrawLines = PSP_RenderDrawLines;
|
|
|
- renderer->RenderFillRects = PSP_RenderFillRects;
|
|
|
- renderer->RenderCopy = PSP_RenderCopy;
|
|
|
- renderer->RenderReadPixels = PSP_RenderReadPixels;
|
|
|
- renderer->RenderCopyEx = PSP_RenderCopyEx;
|
|
|
- renderer->RenderPresent = PSP_RenderPresent;
|
|
|
- renderer->DestroyTexture = PSP_DestroyTexture;
|
|
|
- renderer->DestroyRenderer = PSP_DestroyRenderer;
|
|
|
- renderer->info = PSP_RenderDriver.info;
|
|
|
- renderer->info.flags = (SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
|
|
|
- renderer->driverdata = data;
|
|
|
- renderer->window = window;
|
|
|
-
|
|
|
- if (data->initialized != SDL_FALSE)
|
|
|
- return 0;
|
|
|
- data->initialized = SDL_TRUE;
|
|
|
-
|
|
|
- if (flags & SDL_RENDERER_PRESENTVSYNC) {
|
|
|
- data->vsync = SDL_TRUE;
|
|
|
- } else {
|
|
|
- data->vsync = SDL_FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- pixelformat=PixelFormatToPSPFMT(SDL_GetWindowPixelFormat(window));
|
|
|
- switch(pixelformat)
|
|
|
- {
|
|
|
- case GU_PSM_4444:
|
|
|
- case GU_PSM_5650:
|
|
|
- case GU_PSM_5551:
|
|
|
- data->frontbuffer = (unsigned int *)(PSP_FRAME_BUFFER_SIZE<<1);
|
|
|
- data->backbuffer = (unsigned int *)(0);
|
|
|
- data->bpp = 2;
|
|
|
- data->psm = pixelformat;
|
|
|
- break;
|
|
|
- default:
|
|
|
- data->frontbuffer = (unsigned int *)(PSP_FRAME_BUFFER_SIZE<<2);
|
|
|
- data->backbuffer = (unsigned int *)(0);
|
|
|
- data->bpp = 4;
|
|
|
- data->psm = GU_PSM_8888;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- sceGuInit();
|
|
|
- /* setup GU */
|
|
|
- sceGuStart(GU_DIRECT, DisplayList);
|
|
|
- sceGuDrawBuffer(data->psm, data->frontbuffer, PSP_FRAME_BUFFER_WIDTH);
|
|
|
- sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, data->backbuffer, PSP_FRAME_BUFFER_WIDTH);
|
|
|
-
|
|
|
-
|
|
|
- sceGuOffset(2048 - (PSP_SCREEN_WIDTH>>1), 2048 - (PSP_SCREEN_HEIGHT>>1));
|
|
|
- sceGuViewport(2048, 2048, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
|
|
|
-
|
|
|
- data->frontbuffer = vabsptr(data->frontbuffer);
|
|
|
- data->backbuffer = vabsptr(data->backbuffer);
|
|
|
-
|
|
|
- /* Scissoring */
|
|
|
- sceGuScissor(0, 0, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
|
|
|
- sceGuEnable(GU_SCISSOR_TEST);
|
|
|
-
|
|
|
- /* Backface culling */
|
|
|
- sceGuFrontFace(GU_CCW);
|
|
|
- sceGuEnable(GU_CULL_FACE);
|
|
|
-
|
|
|
- /* Texturing */
|
|
|
- sceGuEnable(GU_TEXTURE_2D);
|
|
|
- sceGuShadeModel(GU_SMOOTH);
|
|
|
- sceGuTexWrap(GU_REPEAT, GU_REPEAT);
|
|
|
-
|
|
|
- /* Blending */
|
|
|
- sceGuEnable(GU_BLEND);
|
|
|
- sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
|
|
|
-
|
|
|
- sceGuTexFilter(GU_LINEAR,GU_LINEAR);
|
|
|
-
|
|
|
- sceGuFinish();
|
|
|
- sceGuSync(0,0);
|
|
|
- sceDisplayWaitVblankStartCB();
|
|
|
- sceGuDisplay(GU_TRUE);
|
|
|
-
|
|
|
- return renderer;
|
|
|
-}
|
|
|
-
|
|
|
static void
|
|
|
PSP_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
|
|
|
{
|
|
|
-
|
|
|
}
|
|
|
|
|
|
|
|
@@ -576,383 +431,429 @@ PSP_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
|
|
static int
|
|
|
PSP_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
|
|
|
{
|
|
|
-
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
static int
|
|
|
-PSP_UpdateViewport(SDL_Renderer * renderer)
|
|
|
+PSP_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd)
|
|
|
{
|
|
|
-
|
|
|
- return 0;
|
|
|
+ return 0; /* nothing to do in this backend. */
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-static void
|
|
|
-PSP_SetBlendMode(SDL_Renderer * renderer, int blendMode)
|
|
|
-{
|
|
|
- PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata;
|
|
|
- if (blendMode != data-> currentBlendMode) {
|
|
|
- switch (blendMode) {
|
|
|
- case SDL_BLENDMODE_NONE:
|
|
|
- sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
|
|
|
- sceGuDisable(GU_BLEND);
|
|
|
- break;
|
|
|
- case SDL_BLENDMODE_BLEND:
|
|
|
- sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
|
|
|
- sceGuEnable(GU_BLEND);
|
|
|
- sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0 );
|
|
|
- break;
|
|
|
- case SDL_BLENDMODE_ADD:
|
|
|
- sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
|
|
|
- sceGuEnable(GU_BLEND);
|
|
|
- sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_FIX, 0, 0x00FFFFFF );
|
|
|
- break;
|
|
|
- case SDL_BLENDMODE_MOD:
|
|
|
- sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
|
|
|
- sceGuEnable(GU_BLEND);
|
|
|
- sceGuBlendFunc( GU_ADD, GU_FIX, GU_SRC_COLOR, 0, 0);
|
|
|
- break;
|
|
|
- }
|
|
|
- data->currentBlendMode = blendMode;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
static int
|
|
|
-PSP_RenderClear(SDL_Renderer * renderer)
|
|
|
+PSP_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
|
|
|
{
|
|
|
- /* start list */
|
|
|
- StartDrawing(renderer);
|
|
|
- int color = renderer->a << 24 | renderer->b << 16 | renderer->g << 8 | renderer->r;
|
|
|
- sceGuClearColor(color);
|
|
|
- sceGuClearDepth(0);
|
|
|
- sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT|GU_FAST_CLEAR_BIT);
|
|
|
+ VertV *verts = (VertV *) SDL_AllocateRenderVertices(renderer, count * sizeof (VertV), 4, &cmd->data.draw.first);
|
|
|
+ size_t i;
|
|
|
|
|
|
- return 0;
|
|
|
-}
|
|
|
+ if (!verts) {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
|
|
|
-static int
|
|
|
-PSP_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points,
|
|
|
- int count)
|
|
|
-{
|
|
|
- int color = renderer->a << 24 | renderer->b << 16 | renderer->g << 8 | renderer->r;
|
|
|
- int i;
|
|
|
- StartDrawing(renderer);
|
|
|
- VertV* vertices = (VertV*)sceGuGetMemory(count*sizeof(VertV));
|
|
|
+ cmd->data.draw.count = count;
|
|
|
|
|
|
- for (i = 0; i < count; ++i) {
|
|
|
- vertices[i].x = points[i].x;
|
|
|
- vertices[i].y = points[i].y;
|
|
|
- vertices[i].z = 0.0f;
|
|
|
+ for (i = 0; i < count; i++, verts++, points++) {
|
|
|
+ verts->x = points->x;
|
|
|
+ verts->y = points->y;
|
|
|
+ verts->z = 0.0f;
|
|
|
}
|
|
|
- sceGuDisable(GU_TEXTURE_2D);
|
|
|
- sceGuColor(color);
|
|
|
- sceGuShadeModel(GU_FLAT);
|
|
|
- sceGuDrawArray(GU_POINTS, GU_VERTEX_32BITF|GU_TRANSFORM_2D, count, 0, vertices);
|
|
|
- sceGuShadeModel(GU_SMOOTH);
|
|
|
- sceGuEnable(GU_TEXTURE_2D);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
static int
|
|
|
-PSP_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points,
|
|
|
- int count)
|
|
|
+PSP_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count)
|
|
|
{
|
|
|
- int color = renderer->a << 24 | renderer->b << 16 | renderer->g << 8 | renderer->r;
|
|
|
- int i;
|
|
|
- StartDrawing(renderer);
|
|
|
- VertV* vertices = (VertV*)sceGuGetMemory(count*sizeof(VertV));
|
|
|
+ VertV *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * 2 * sizeof (VertV), 4, &cmd->data.draw.first);
|
|
|
+ size_t i;
|
|
|
|
|
|
- for (i = 0; i < count; ++i) {
|
|
|
- vertices[i].x = points[i].x;
|
|
|
- vertices[i].y = points[i].y;
|
|
|
- vertices[i].z = 0.0f;
|
|
|
+ if (!verts) {
|
|
|
+ return -1;
|
|
|
}
|
|
|
|
|
|
- sceGuDisable(GU_TEXTURE_2D);
|
|
|
- sceGuColor(color);
|
|
|
- sceGuShadeModel(GU_FLAT);
|
|
|
- sceGuDrawArray(GU_LINE_STRIP, GU_VERTEX_32BITF|GU_TRANSFORM_2D, count, 0, vertices);
|
|
|
- sceGuShadeModel(GU_SMOOTH);
|
|
|
- sceGuEnable(GU_TEXTURE_2D);
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static int
|
|
|
-PSP_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects,
|
|
|
- int count)
|
|
|
-{
|
|
|
- int color = renderer->a << 24 | renderer->b << 16 | renderer->g << 8 | renderer->r;
|
|
|
- int i;
|
|
|
- StartDrawing(renderer);
|
|
|
-
|
|
|
- for (i = 0; i < count; ++i) {
|
|
|
+ cmd->data.draw.count = count;
|
|
|
+ for (i = 0; i < count; i++, rects++) {
|
|
|
const SDL_FRect *rect = &rects[i];
|
|
|
- VertV* vertices = (VertV*)sceGuGetMemory((sizeof(VertV)<<1));
|
|
|
- vertices[0].x = rect->x;
|
|
|
- vertices[0].y = rect->y;
|
|
|
- vertices[0].z = 0.0f;
|
|
|
-
|
|
|
- vertices[1].x = rect->x + rect->w;
|
|
|
- vertices[1].y = rect->y + rect->h;
|
|
|
- vertices[1].z = 0.0f;
|
|
|
-
|
|
|
- sceGuDisable(GU_TEXTURE_2D);
|
|
|
- sceGuColor(color);
|
|
|
- sceGuShadeModel(GU_FLAT);
|
|
|
- sceGuDrawArray(GU_SPRITES, GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
|
|
|
- sceGuShadeModel(GU_SMOOTH);
|
|
|
- sceGuEnable(GU_TEXTURE_2D);
|
|
|
+ verts->x = rect->x;
|
|
|
+ verts->y = rect->y;
|
|
|
+ verts->z = 0.0f;
|
|
|
+ verts++;
|
|
|
+
|
|
|
+ verts->x = rect->x + rect->w;
|
|
|
+ verts->y = rect->y + rect->h;
|
|
|
+ verts->z = 0.0f;
|
|
|
+ verts++;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-#define PI 3.14159265358979f
|
|
|
-
|
|
|
-#define radToDeg(x) ((x)*180.f/PI)
|
|
|
-#define degToRad(x) ((x)*PI/180.f)
|
|
|
-
|
|
|
-float MathAbs(float x)
|
|
|
-{
|
|
|
- float result;
|
|
|
-
|
|
|
- __asm__ volatile (
|
|
|
- "mtv %1, S000\n"
|
|
|
- "vabs.s S000, S000\n"
|
|
|
- "mfv %0, S000\n"
|
|
|
- : "=r"(result) : "r"(x));
|
|
|
-
|
|
|
- return result;
|
|
|
-}
|
|
|
-
|
|
|
-void MathSincos(float r, float *s, float *c)
|
|
|
-{
|
|
|
- __asm__ volatile (
|
|
|
- "mtv %2, S002\n"
|
|
|
- "vcst.s S003, VFPU_2_PI\n"
|
|
|
- "vmul.s S002, S002, S003\n"
|
|
|
- "vrot.p C000, S002, [s, c]\n"
|
|
|
- "mfv %0, S000\n"
|
|
|
- "mfv %1, S001\n"
|
|
|
- : "=r"(*s), "=r"(*c): "r"(r));
|
|
|
-}
|
|
|
-
|
|
|
-void Swap(float *a, float *b)
|
|
|
-{
|
|
|
- float n=*a;
|
|
|
- *a = *b;
|
|
|
- *b = n;
|
|
|
-}
|
|
|
-
|
|
|
static int
|
|
|
-PSP_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
|
|
|
- const SDL_Rect * srcrect, const SDL_FRect * dstrect)
|
|
|
+PSP_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
|
|
|
+ const SDL_Rect * srcrect, const SDL_FRect * dstrect)
|
|
|
{
|
|
|
- float x, y, width, height;
|
|
|
- float u0, v0, u1, v1;
|
|
|
- unsigned char alpha;
|
|
|
-
|
|
|
- x = dstrect->x;
|
|
|
- y = dstrect->y;
|
|
|
- width = dstrect->w;
|
|
|
- height = dstrect->h;
|
|
|
-
|
|
|
- u0 = srcrect->x;
|
|
|
- v0 = srcrect->y;
|
|
|
- u1 = srcrect->x + srcrect->w;
|
|
|
- v1 = srcrect->y + srcrect->h;
|
|
|
-
|
|
|
- alpha = texture->a;
|
|
|
+ VertTV *verts;
|
|
|
+ const float x = dstrect->x;
|
|
|
+ const float y = dstrect->y;
|
|
|
+ const float width = dstrect->w;
|
|
|
+ const float height = dstrect->h;
|
|
|
|
|
|
- StartDrawing(renderer);
|
|
|
- TextureActivate(texture);
|
|
|
- PSP_SetBlendMode(renderer, renderer->blendMode);
|
|
|
-
|
|
|
- if(alpha != 255)
|
|
|
- {
|
|
|
- sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
|
|
|
- sceGuColor(GU_RGBA(255, 255, 255, alpha));
|
|
|
- }else{
|
|
|
- sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
|
|
|
- sceGuColor(0xFFFFFFFF);
|
|
|
- }
|
|
|
+ const float u0 = srcrect->x;
|
|
|
+ const float v0 = srcrect->y;
|
|
|
+ const float u1 = srcrect->x + srcrect->w;
|
|
|
+ const float v1 = srcrect->y + srcrect->h;
|
|
|
|
|
|
if((MathAbs(u1) - MathAbs(u0)) < 64.0f)
|
|
|
{
|
|
|
- VertTV* vertices = (VertTV*)sceGuGetMemory((sizeof(VertTV))<<1);
|
|
|
-
|
|
|
- vertices[0].u = u0;
|
|
|
- vertices[0].v = v0;
|
|
|
- vertices[0].x = x;
|
|
|
- vertices[0].y = y;
|
|
|
- vertices[0].z = 0;
|
|
|
-
|
|
|
- vertices[1].u = u1;
|
|
|
- vertices[1].v = v1;
|
|
|
- vertices[1].x = x + width;
|
|
|
- vertices[1].y = y + height;
|
|
|
- vertices[1].z = 0;
|
|
|
+ verts = (VertTV *) SDL_AllocateRenderVertices(renderer, 2 * sizeof (VertTV), 4, &cmd->data.draw.first);
|
|
|
+ if (!verts) {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
|
|
|
- sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
|
|
|
+ cmd->data.draw.count = 1;
|
|
|
+
|
|
|
+ verts->u = u0;
|
|
|
+ verts->v = v0;
|
|
|
+ verts->x = x;
|
|
|
+ verts->y = y;
|
|
|
+ verts->z = 0;
|
|
|
+ verts++;
|
|
|
+
|
|
|
+ verts->u = u1;
|
|
|
+ verts->v = v1;
|
|
|
+ verts->x = x + width;
|
|
|
+ verts->y = y + height;
|
|
|
+ verts->z = 0;
|
|
|
+ verts++;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
float start, end;
|
|
|
float curU = u0;
|
|
|
float curX = x;
|
|
|
- float endX = x + width;
|
|
|
- float slice = 64.0f;
|
|
|
+ const float endX = x + width;
|
|
|
+ const float slice = 64.0f;
|
|
|
+ const size_t count = SDL_ceilf(width / slice);
|
|
|
+ size_t i;
|
|
|
float ustep = (u1 - u0)/width * slice;
|
|
|
|
|
|
if(ustep < 0.0f)
|
|
|
ustep = -ustep;
|
|
|
|
|
|
- for(start = 0, end = width; start < end; start += slice)
|
|
|
+ cmd->data.draw.count = count;
|
|
|
+
|
|
|
+ verts = (VertTV *) SDL_AllocateRenderVertices(renderer, count * sizeof (VertTV), 4, &cmd->data.draw.first);
|
|
|
+ if (!verts) {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ for(i = 0, start = 0, end = width; i < count; i++, start += slice)
|
|
|
{
|
|
|
- VertTV* vertices = (VertTV*)sceGuGetMemory((sizeof(VertTV))<<1);
|
|
|
+ const float polyWidth = ((curX + slice) > endX) ? (endX - curX) : slice;
|
|
|
+ const float sourceWidth = ((curU + ustep) > u1) ? (u1 - curU) : ustep;
|
|
|
|
|
|
- float polyWidth = ((curX + slice) > endX) ? (endX - curX) : slice;
|
|
|
- float sourceWidth = ((curU + ustep) > u1) ? (u1 - curU) : ustep;
|
|
|
+ SDL_assert(start < end);
|
|
|
|
|
|
- vertices[0].u = curU;
|
|
|
- vertices[0].v = v0;
|
|
|
- vertices[0].x = curX;
|
|
|
- vertices[0].y = y;
|
|
|
- vertices[0].z = 0;
|
|
|
+ verts->u = curU;
|
|
|
+ verts->v = v0;
|
|
|
+ verts->x = curX;
|
|
|
+ verts->y = y;
|
|
|
+ verts->z = 0;
|
|
|
|
|
|
curU += sourceWidth;
|
|
|
curX += polyWidth;
|
|
|
|
|
|
- vertices[1].u = curU;
|
|
|
- vertices[1].v = v1;
|
|
|
- vertices[1].x = curX;
|
|
|
- vertices[1].y = (y + height);
|
|
|
- vertices[1].z = 0;
|
|
|
-
|
|
|
- sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
|
|
|
+ verts->u = curU;
|
|
|
+ verts->v = v1;
|
|
|
+ verts->x = curX;
|
|
|
+ verts->y = (y + height);
|
|
|
+ verts->z = 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if(alpha != 255)
|
|
|
- sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
static int
|
|
|
-PSP_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
|
|
|
- Uint32 pixel_format, void * pixels, int pitch)
|
|
|
-
|
|
|
+PSP_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
|
|
|
+ const SDL_Rect * srcrect, const SDL_FRect * dstrect,
|
|
|
+ const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
|
|
|
{
|
|
|
- return SDL_Unsupported();
|
|
|
-}
|
|
|
+ VertTV *verts = (VertTV *) SDL_AllocateRenderVertices(renderer, 4 * sizeof (VertTV), 4, &cmd->data.draw.first);
|
|
|
+ const float centerx = center->x;
|
|
|
+ const float centery = center->y;
|
|
|
+ const float x = dstrect->x + centerx;
|
|
|
+ const float y = dstrect->y + centery;
|
|
|
+ const float width = dstrect->w - centerx;
|
|
|
+ const float height = dstrect->h - centery;
|
|
|
+ float s, c;
|
|
|
+
|
|
|
+ float u0 = srcrect->x;
|
|
|
+ float v0 = srcrect->y;
|
|
|
+ float u1 = srcrect->x + srcrect->w;
|
|
|
+ float v1 = srcrect->y + srcrect->h;
|
|
|
+
|
|
|
+
|
|
|
+ if (!verts) {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
|
|
|
+ cmd->data.draw.count = 1;
|
|
|
|
|
|
-static int
|
|
|
-PSP_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)
|
|
|
-{
|
|
|
- float x, y, width, height;
|
|
|
- float u0, v0, u1, v1;
|
|
|
- unsigned char alpha;
|
|
|
- float centerx, centery;
|
|
|
+ MathSincos(degToRad(angle), &s, &c);
|
|
|
|
|
|
- x = dstrect->x;
|
|
|
- y = dstrect->y;
|
|
|
- width = dstrect->w;
|
|
|
- height = dstrect->h;
|
|
|
+ const float cw = c * width;
|
|
|
+ const float sw = s * width;
|
|
|
+ const float ch = c * height;
|
|
|
+ const float sh = s * height;
|
|
|
|
|
|
- u0 = srcrect->x;
|
|
|
- v0 = srcrect->y;
|
|
|
- u1 = srcrect->x + srcrect->w;
|
|
|
- v1 = srcrect->y + srcrect->h;
|
|
|
+ if (flip & SDL_FLIP_VERTICAL) {
|
|
|
+ Swap(&v0, &v1);
|
|
|
+ }
|
|
|
|
|
|
- centerx = center->x;
|
|
|
- centery = center->y;
|
|
|
+ if (flip & SDL_FLIP_HORIZONTAL) {
|
|
|
+ Swap(&u0, &u1);
|
|
|
+ }
|
|
|
|
|
|
- alpha = texture->a;
|
|
|
+ verts->u = u0;
|
|
|
+ verts->v = v0;
|
|
|
+ verts->x = x - cw + sh;
|
|
|
+ verts->y = y - sw - ch;
|
|
|
+ verts->z = 0;
|
|
|
+ verts++;
|
|
|
+
|
|
|
+ verts->u = u0;
|
|
|
+ verts->v = v1;
|
|
|
+ verts->x = x - cw - sh;
|
|
|
+ verts->y = y - sw + ch;
|
|
|
+ verts->z = 0;
|
|
|
+ verts++;
|
|
|
+
|
|
|
+ verts->u = u1;
|
|
|
+ verts->v = v1;
|
|
|
+ verts->x = x + cw - sh;
|
|
|
+ verts->y = y + sw + ch;
|
|
|
+ verts->z = 0;
|
|
|
+ verts++;
|
|
|
+
|
|
|
+ verts->u = u1;
|
|
|
+ verts->v = v0;
|
|
|
+ verts->x = x + cw + sh;
|
|
|
+ verts->y = y + sw - ch;
|
|
|
+ verts->z = 0;
|
|
|
+ verts++;
|
|
|
|
|
|
- StartDrawing(renderer);
|
|
|
- TextureActivate(texture);
|
|
|
- PSP_SetBlendMode(renderer, renderer->blendMode);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
|
|
|
- if(alpha != 255)
|
|
|
- {
|
|
|
- sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
|
|
|
- sceGuColor(GU_RGBA(255, 255, 255, alpha));
|
|
|
- }else{
|
|
|
- sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
|
|
|
- sceGuColor(0xFFFFFFFF);
|
|
|
+static void
|
|
|
+PSP_SetBlendMode(SDL_Renderer * renderer, int blendMode)
|
|
|
+{
|
|
|
+ PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata;
|
|
|
+ if (blendMode != data-> currentBlendMode) {
|
|
|
+ switch (blendMode) {
|
|
|
+ case SDL_BLENDMODE_NONE:
|
|
|
+ sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
|
|
|
+ sceGuDisable(GU_BLEND);
|
|
|
+ break;
|
|
|
+ case SDL_BLENDMODE_BLEND:
|
|
|
+ sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
|
|
|
+ sceGuEnable(GU_BLEND);
|
|
|
+ sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0 );
|
|
|
+ break;
|
|
|
+ case SDL_BLENDMODE_ADD:
|
|
|
+ sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
|
|
|
+ sceGuEnable(GU_BLEND);
|
|
|
+ sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_FIX, 0, 0x00FFFFFF );
|
|
|
+ break;
|
|
|
+ case SDL_BLENDMODE_MOD:
|
|
|
+ sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
|
|
|
+ sceGuEnable(GU_BLEND);
|
|
|
+ sceGuBlendFunc( GU_ADD, GU_FIX, GU_SRC_COLOR, 0, 0);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ data->currentBlendMode = blendMode;
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
-/* x += width * 0.5f; */
|
|
|
-/* y += height * 0.5f; */
|
|
|
- x += centerx;
|
|
|
- y += centery;
|
|
|
+static int
|
|
|
+PSP_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
|
|
|
+{
|
|
|
+ PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata;
|
|
|
+ size_t i;
|
|
|
|
|
|
- float c, s;
|
|
|
+ StartDrawing(renderer);
|
|
|
|
|
|
- MathSincos(degToRad(angle), &s, &c);
|
|
|
+ /* note that before the renderer interface change, this would do extrememly small
|
|
|
+ batches with sceGuGetMemory()--a few vertices at a time--and it's not clear that
|
|
|
+ this won't fail if you try to push 100,000 draw calls in a single batch.
|
|
|
+ I don't know what the limits on PSP hardware are. It might be useful to have
|
|
|
+ rendering backends report a reasonable maximum, so the higher level can flush
|
|
|
+ if we appear to be exceeding that. */
|
|
|
+ Uint8 *gpumem = (Uint8 *) sceGuGetMemory(vertsize);
|
|
|
+ if (!gpumem) {
|
|
|
+ return SDL_SetError("Couldn't obtain a %d-byte vertex buffer!", (int) vertsize);
|
|
|
+ }
|
|
|
+ SDL_memcpy(gpumem, vertices, vertsize);
|
|
|
|
|
|
-/* width *= 0.5f; */
|
|
|
-/* height *= 0.5f; */
|
|
|
- width -= centerx;
|
|
|
- height -= centery;
|
|
|
+ while (cmd) {
|
|
|
+ switch (cmd->command) {
|
|
|
+ case SDL_RENDERCMD_SETDRAWCOLOR: {
|
|
|
+ break; /* !!! FIXME: we could cache drawstate like color */
|
|
|
+ }
|
|
|
|
|
|
+ case SDL_RENDERCMD_SETVIEWPORT: {
|
|
|
+ SDL_Rect *viewport = &data->drawstate.viewport;
|
|
|
+ if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)) != 0) {
|
|
|
+ SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect));
|
|
|
+ data->drawstate.viewport_dirty = SDL_TRUE;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- float cw = c*width;
|
|
|
- float sw = s*width;
|
|
|
- float ch = c*height;
|
|
|
- float sh = s*height;
|
|
|
+ case SDL_RENDERCMD_SETCLIPRECT: {
|
|
|
+ const SDL_Rect *rect = &cmd->data.cliprect.rect;
|
|
|
+ if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) {
|
|
|
+ data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled;
|
|
|
+ data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
|
|
|
+ }
|
|
|
+ if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) {
|
|
|
+ SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect));
|
|
|
+ data->drawstate.cliprect_dirty = SDL_TRUE;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- VertTV* vertices = (VertTV*)sceGuGetMemory(sizeof(VertTV)<<2);
|
|
|
+ case SDL_RENDERCMD_CLEAR: {
|
|
|
+ const Uint8 r = cmd->data.color.r;
|
|
|
+ const Uint8 g = cmd->data.color.g;
|
|
|
+ const Uint8 b = cmd->data.color.b;
|
|
|
+ const Uint8 a = cmd->data.color.a;
|
|
|
+ const Uint32 color = ((a << 24) | (b << 16) | (g << 8) | r);
|
|
|
+ /* !!! FIXME: we could cache drawstate like clear color */
|
|
|
+ sceGuClearColor(color);
|
|
|
+ sceGuClearDepth(0);
|
|
|
+ sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT|GU_FAST_CLEAR_BIT);
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- vertices[0].u = u0;
|
|
|
- vertices[0].v = v0;
|
|
|
- vertices[0].x = x - cw + sh;
|
|
|
- vertices[0].y = y - sw - ch;
|
|
|
- vertices[0].z = 0;
|
|
|
+ case SDL_RENDERCMD_DRAW_POINTS: {
|
|
|
+ const size_t count = cmd->data.draw.count;
|
|
|
+ const VertV *verts = (VertV *) (gpumem + cmd->data.draw.first);
|
|
|
+ const Uint8 r = cmd->data.color.r;
|
|
|
+ const Uint8 g = cmd->data.color.g;
|
|
|
+ const Uint8 b = cmd->data.color.b;
|
|
|
+ const Uint8 a = cmd->data.color.a;
|
|
|
+ const Uint32 color = ((a << 24) | (b << 16) | (g << 8) | r);
|
|
|
+ /* !!! FIXME: we could cache draw state like color, texturing, etc */
|
|
|
+ sceGuColor(color);
|
|
|
+ sceGuDisable(GU_TEXTURE_2D);
|
|
|
+ sceGuShadeModel(GU_FLAT);
|
|
|
+ sceGuDrawArray(GU_POINTS, GU_VERTEX_32BITF|GU_TRANSFORM_2D, count, 0, verts);
|
|
|
+ sceGuShadeModel(GU_SMOOTH);
|
|
|
+ sceGuEnable(GU_TEXTURE_2D);
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- vertices[1].u = u0;
|
|
|
- vertices[1].v = v1;
|
|
|
- vertices[1].x = x - cw - sh;
|
|
|
- vertices[1].y = y - sw + ch;
|
|
|
- vertices[1].z = 0;
|
|
|
+ case SDL_RENDERCMD_DRAW_LINES: {
|
|
|
+ const size_t count = cmd->data.draw.count;
|
|
|
+ const VertV *verts = (VertV *) (gpumem + cmd->data.draw.first);
|
|
|
+ const Uint8 r = cmd->data.color.r;
|
|
|
+ const Uint8 g = cmd->data.color.g;
|
|
|
+ const Uint8 b = cmd->data.color.b;
|
|
|
+ const Uint8 a = cmd->data.color.a;
|
|
|
+ const Uint32 color = ((a << 24) | (b << 16) | (g << 8) | r);
|
|
|
+ /* !!! FIXME: we could cache draw state like color, texturing, etc */
|
|
|
+ sceGuColor(color);
|
|
|
+ sceGuDisable(GU_TEXTURE_2D);
|
|
|
+ sceGuShadeModel(GU_FLAT);
|
|
|
+ sceGuDrawArray(GU_LINE_STRIP, GU_VERTEX_32BITF|GU_TRANSFORM_2D, count, 0, verts);
|
|
|
+ sceGuShadeModel(GU_SMOOTH);
|
|
|
+ sceGuEnable(GU_TEXTURE_2D);
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- vertices[2].u = u1;
|
|
|
- vertices[2].v = v1;
|
|
|
- vertices[2].x = x + cw - sh;
|
|
|
- vertices[2].y = y + sw + ch;
|
|
|
- vertices[2].z = 0;
|
|
|
+ case SDL_RENDERCMD_FILL_RECTS: {
|
|
|
+ const size_t count = cmd->data.draw.count;
|
|
|
+ const VertV *verts = (VertV *) (gpumem + cmd->data.draw.first);
|
|
|
+ const Uint8 r = cmd->data.color.r;
|
|
|
+ const Uint8 g = cmd->data.color.g;
|
|
|
+ const Uint8 b = cmd->data.color.b;
|
|
|
+ const Uint8 a = cmd->data.color.a;
|
|
|
+ const Uint32 color = ((a << 24) | (b << 16) | (g << 8) | r);
|
|
|
+ /* !!! FIXME: we could cache draw state like color, texturing, etc */
|
|
|
+ sceGuColor(color);
|
|
|
+ sceGuDisable(GU_TEXTURE_2D);
|
|
|
+ sceGuShadeModel(GU_FLAT);
|
|
|
+ sceGuDrawArray(GU_SPRITES, GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2 * count, 0, verts);
|
|
|
+ sceGuShadeModel(GU_SMOOTH);
|
|
|
+ sceGuEnable(GU_TEXTURE_2D);
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- vertices[3].u = u1;
|
|
|
- vertices[3].v = v0;
|
|
|
- vertices[3].x = x + cw + sh;
|
|
|
- vertices[3].y = y + sw - ch;
|
|
|
- vertices[3].z = 0;
|
|
|
+ case SDL_RENDERCMD_COPY: {
|
|
|
+ const size_t count = cmd->data.draw.count;
|
|
|
+ const VertTV *verts = (VertTV *) (gpumem + cmd->data.draw.first);
|
|
|
+ const Uint8 alpha = cmd->data.draw.a;
|
|
|
+ TextureActivate(cmd->data.draw.texture);
|
|
|
+ PSP_SetBlendMode(renderer, cmd->data.draw.blend);
|
|
|
+
|
|
|
+ if(alpha != 255) { /* !!! FIXME: is this right? */
|
|
|
+ sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
|
|
|
+ sceGuColor(GU_RGBA(255, 255, 255, alpha));
|
|
|
+ } else {
|
|
|
+ sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
|
|
|
+ sceGuColor(0xFFFFFFFF);
|
|
|
+ }
|
|
|
+
|
|
|
+ sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2 * count, 0, verts);
|
|
|
+
|
|
|
+ if(alpha != 255) {
|
|
|
+ sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- if (flip & SDL_FLIP_VERTICAL) {
|
|
|
- Swap(&vertices[0].v, &vertices[2].v);
|
|
|
- Swap(&vertices[1].v, &vertices[3].v);
|
|
|
- }
|
|
|
- if (flip & SDL_FLIP_HORIZONTAL) {
|
|
|
- Swap(&vertices[0].u, &vertices[2].u);
|
|
|
- Swap(&vertices[1].u, &vertices[3].u);
|
|
|
- }
|
|
|
+ case SDL_RENDERCMD_COPY_EX: {
|
|
|
+ const VertTV *verts = (VertTV *) (gpumem + cmd->data.draw.first);
|
|
|
+ const Uint8 alpha = cmd->data.draw.a;
|
|
|
+ TextureActivate(cmd->data.draw.texture);
|
|
|
+ PSP_SetBlendMode(renderer, cmd->data.draw.blend);
|
|
|
+
|
|
|
+ if(alpha != 255) { /* !!! FIXME: is this right? */
|
|
|
+ sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
|
|
|
+ sceGuColor(GU_RGBA(255, 255, 255, alpha));
|
|
|
+ } else {
|
|
|
+ sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
|
|
|
+ sceGuColor(0xFFFFFFFF);
|
|
|
+ }
|
|
|
+
|
|
|
+ sceGuDrawArray(GU_TRIANGLE_FAN, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 4, 0, verts);
|
|
|
+
|
|
|
+ if(alpha != 255) {
|
|
|
+ sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ case SDL_RENDERCMD_NO_OP:
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- sceGuDrawArray(GU_TRIANGLE_FAN, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 4, 0, vertices);
|
|
|
+ cmd = cmd->next;
|
|
|
+ }
|
|
|
|
|
|
- if(alpha != 255)
|
|
|
- sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int
|
|
|
+PSP_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
|
|
|
+ Uint32 pixel_format, void * pixels, int pitch)
|
|
|
+{
|
|
|
+ return SDL_Unsupported();
|
|
|
+}
|
|
|
+
|
|
|
static void
|
|
|
PSP_RenderPresent(SDL_Renderer * renderer)
|
|
|
{
|
|
@@ -1010,6 +911,136 @@ PSP_DestroyRenderer(SDL_Renderer * renderer)
|
|
|
SDL_free(renderer);
|
|
|
}
|
|
|
|
|
|
+SDL_Renderer *
|
|
|
+PSP_CreateRenderer(SDL_Window * window, Uint32 flags)
|
|
|
+{
|
|
|
+
|
|
|
+ SDL_Renderer *renderer;
|
|
|
+ PSP_RenderData *data;
|
|
|
+ int pixelformat;
|
|
|
+ renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
|
|
|
+ if (!renderer) {
|
|
|
+ SDL_OutOfMemory();
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ data = (PSP_RenderData *) SDL_calloc(1, sizeof(*data));
|
|
|
+ if (!data) {
|
|
|
+ PSP_DestroyRenderer(renderer);
|
|
|
+ SDL_OutOfMemory();
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ renderer->WindowEvent = PSP_WindowEvent;
|
|
|
+ renderer->CreateTexture = PSP_CreateTexture;
|
|
|
+ renderer->SetTextureColorMod = PSP_SetTextureColorMod;
|
|
|
+ renderer->UpdateTexture = PSP_UpdateTexture;
|
|
|
+ renderer->LockTexture = PSP_LockTexture;
|
|
|
+ renderer->UnlockTexture = PSP_UnlockTexture;
|
|
|
+ renderer->SetRenderTarget = PSP_SetRenderTarget;
|
|
|
+ renderer->QueueSetViewport = PSP_QueueSetViewport;
|
|
|
+ renderer->QueueSetDrawColor = PSP_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */
|
|
|
+ renderer->QueueDrawPoints = PSP_QueueDrawPoints;
|
|
|
+ renderer->QueueDrawLines = PSP_QueueDrawPoints; /* lines and points queue vertices the same way. */
|
|
|
+ renderer->QueueFillRects = PSP_QueueFillRects;
|
|
|
+ renderer->QueueCopy = PSP_QueueCopy;
|
|
|
+ renderer->QueueCopyEx = PSP_QueueCopyEx;
|
|
|
+ renderer->RunCommandQueue = PSP_RunCommandQueue;
|
|
|
+ renderer->RenderReadPixels = PSP_RenderReadPixels;
|
|
|
+ renderer->RenderPresent = PSP_RenderPresent;
|
|
|
+ renderer->DestroyTexture = PSP_DestroyTexture;
|
|
|
+ renderer->DestroyRenderer = PSP_DestroyRenderer;
|
|
|
+ renderer->info = PSP_RenderDriver.info;
|
|
|
+ renderer->info.flags = (SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
|
|
|
+ renderer->driverdata = data;
|
|
|
+ renderer->window = window;
|
|
|
+
|
|
|
+ if (data->initialized != SDL_FALSE)
|
|
|
+ return 0;
|
|
|
+ data->initialized = SDL_TRUE;
|
|
|
+
|
|
|
+ if (flags & SDL_RENDERER_PRESENTVSYNC) {
|
|
|
+ data->vsync = SDL_TRUE;
|
|
|
+ } else {
|
|
|
+ data->vsync = SDL_FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ pixelformat=PixelFormatToPSPFMT(SDL_GetWindowPixelFormat(window));
|
|
|
+ switch(pixelformat)
|
|
|
+ {
|
|
|
+ case GU_PSM_4444:
|
|
|
+ case GU_PSM_5650:
|
|
|
+ case GU_PSM_5551:
|
|
|
+ data->frontbuffer = (unsigned int *)(PSP_FRAME_BUFFER_SIZE<<1);
|
|
|
+ data->backbuffer = (unsigned int *)(0);
|
|
|
+ data->bpp = 2;
|
|
|
+ data->psm = pixelformat;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ data->frontbuffer = (unsigned int *)(PSP_FRAME_BUFFER_SIZE<<2);
|
|
|
+ data->backbuffer = (unsigned int *)(0);
|
|
|
+ data->bpp = 4;
|
|
|
+ data->psm = GU_PSM_8888;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ sceGuInit();
|
|
|
+ /* setup GU */
|
|
|
+ sceGuStart(GU_DIRECT, DisplayList);
|
|
|
+ sceGuDrawBuffer(data->psm, data->frontbuffer, PSP_FRAME_BUFFER_WIDTH);
|
|
|
+ sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, data->backbuffer, PSP_FRAME_BUFFER_WIDTH);
|
|
|
+
|
|
|
+
|
|
|
+ sceGuOffset(2048 - (PSP_SCREEN_WIDTH>>1), 2048 - (PSP_SCREEN_HEIGHT>>1));
|
|
|
+ sceGuViewport(2048, 2048, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
|
|
|
+
|
|
|
+ data->frontbuffer = vabsptr(data->frontbuffer);
|
|
|
+ data->backbuffer = vabsptr(data->backbuffer);
|
|
|
+
|
|
|
+ /* Scissoring */
|
|
|
+ sceGuScissor(0, 0, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
|
|
|
+ sceGuEnable(GU_SCISSOR_TEST);
|
|
|
+
|
|
|
+ /* Backface culling */
|
|
|
+ sceGuFrontFace(GU_CCW);
|
|
|
+ sceGuEnable(GU_CULL_FACE);
|
|
|
+
|
|
|
+ /* Texturing */
|
|
|
+ sceGuEnable(GU_TEXTURE_2D);
|
|
|
+ sceGuShadeModel(GU_SMOOTH);
|
|
|
+ sceGuTexWrap(GU_REPEAT, GU_REPEAT);
|
|
|
+
|
|
|
+ /* Blending */
|
|
|
+ sceGuEnable(GU_BLEND);
|
|
|
+ sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
|
|
|
+
|
|
|
+ sceGuTexFilter(GU_LINEAR,GU_LINEAR);
|
|
|
+
|
|
|
+ sceGuFinish();
|
|
|
+ sceGuSync(0,0);
|
|
|
+ sceDisplayWaitVblankStartCB();
|
|
|
+ sceGuDisplay(GU_TRUE);
|
|
|
+
|
|
|
+ return renderer;
|
|
|
+}
|
|
|
+
|
|
|
+SDL_RenderDriver PSP_RenderDriver = {
|
|
|
+ .CreateRenderer = PSP_CreateRenderer,
|
|
|
+ .info = {
|
|
|
+ .name = "PSP",
|
|
|
+ .flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE,
|
|
|
+ .num_texture_formats = 4,
|
|
|
+ .texture_formats = { [0] = SDL_PIXELFORMAT_BGR565,
|
|
|
+ [1] = SDL_PIXELFORMAT_ABGR1555,
|
|
|
+ [2] = SDL_PIXELFORMAT_ABGR4444,
|
|
|
+ [3] = SDL_PIXELFORMAT_ABGR8888,
|
|
|
+ },
|
|
|
+ .max_texture_width = 512,
|
|
|
+ .max_texture_height = 512,
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
#endif /* SDL_VIDEO_RENDER_PSP */
|
|
|
|
|
|
/* vi: set ts=4 sw=4 expandtab: */
|