SDL_render_psp.c
Go to the documentation of this file.
/*
Simple DirectMedia Layer
Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
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_PSP
#include "SDL_hints.h"
#include "../SDL_sysrender.h"
#include <pspkernel.h>
#include <pspdisplay.h>
#include <pspgu.h>
#include <pspgum.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <pspge.h>
#include <stdarg.h>
#include <stdlib.h>
#include <vram.h>
/* 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_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
#define PSP_FRAME_BUFFER_WIDTH 512
#define PSP_FRAME_BUFFER_SIZE (PSP_FRAME_BUFFER_WIDTH*PSP_SCREEN_HEIGHT)
static unsigned int __attribute__((aligned(16))) DisplayList[262144];
#define COL5650(r,g,b,a) ((r>>3) | ((g>>2)<<5) | ((b>>3)<<11))
#define COL5551(r,g,b,a) ((r>>3) | ((g>>3)<<5) | ((b>>3)<<10) | (a>0?0x7000:0))
#define COL4444(r,g,b,a) ((r>>4) | ((g>>4)<<4) | ((b>>4)<<8) | ((a>>4)<<12))
#define COL8888(r,g,b,a) ((r) | ((g)<<8) | ((b)<<16) | ((a)<<24))
typedef struct
{
void* frontbuffer ;
void* backbuffer ;
SDL_bool initialized ;
SDL_bool displayListAvail ;
unsigned int psm ;
unsigned int bpp ;
SDL_bool vsync;
unsigned int currentColor;
int currentBlendMode;
} PSP_RenderData;
typedef struct
{
void *data; /**< Image data. */
unsigned int size; /**< Size of data in bytes. */
unsigned int width; /**< Image width. */
unsigned int height; /**< Image height. */
unsigned int textureWidth; /**< Texture width (power of two). */
unsigned int textureHeight; /**< Texture height (power of two). */
unsigned int bits; /**< Image bits per pixel. */
unsigned int format; /**< Image format - one of ::pgePixelFormat. */
unsigned int pitch;
SDL_bool swizzled; /**< Is image swizzled. */
} PSP_TextureData;
typedef struct
{
float x, y, z;
} VertV;
typedef struct
{
float u, v;
float x, y, z;
} VertTV;
/* Return next power of 2 */
static int
TextureNextPow2(unsigned int w)
{
if(w == 0)
return 0;
unsigned int n = 2;
while(w > n)
n <<= 1;
return n;
}
static int
GetScaleQuality(void)
{
const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
return GU_NEAREST; /* GU_NEAREST good for tile-map */
} else {
return GU_LINEAR; /* GU_LINEAR good for scaling */
}
}
static int
PixelFormatToPSPFMT(Uint32 format)
{
switch (format) {
case SDL_PIXELFORMAT_BGR565:
return GU_PSM_5650;
case SDL_PIXELFORMAT_ABGR1555:
return GU_PSM_5551;
case SDL_PIXELFORMAT_ABGR4444:
return GU_PSM_4444;
case SDL_PIXELFORMAT_ABGR8888:
return GU_PSM_8888;
default:
return GU_PSM_8888;
}
}
void
StartDrawing(SDL_Renderer * renderer)
{
PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata;
if(data->displayListAvail)
return;
sceGuStart(GU_DIRECT, DisplayList);
data->displayListAvail = SDL_TRUE;
}
int
TextureSwizzle(PSP_TextureData *psp_texture)
{
if(psp_texture->swizzled)
return 1;
int bytewidth = psp_texture->textureWidth*(psp_texture->bits>>3);
int height = psp_texture->size / bytewidth;
int rowblocks = (bytewidth>>4);
int rowblocksadd = (rowblocks-1)<<7;
unsigned int blockaddress = 0;
unsigned int *src = (unsigned int*) psp_texture->data;
unsigned char *data = NULL;
data = malloc(psp_texture->size);
int j;
for(j = 0; j < height; j++, blockaddress += 16)
{
unsigned int *block;
block = (unsigned int*)&data[blockaddress];
int i;
for(i = 0; i < rowblocks; i++)
{
*block++ = *src++;
*block++ = *src++;
*block++ = *src++;
*block++ = *src++;
block += 28;
}
if((j & 0x7) == 0x7)
blockaddress += rowblocksadd;
}
free(psp_texture->data);
psp_texture->data = data;
psp_texture->swizzled = SDL_TRUE;
return 1;
}
int TextureUnswizzle(PSP_TextureData *psp_texture)
{
if(!psp_texture->swizzled)
return 1;
int blockx, blocky;
int bytewidth = psp_texture->textureWidth*(psp_texture->bits>>3);
int height = psp_texture->size / bytewidth;
int widthblocks = bytewidth/16;
int heightblocks = height/8;
int dstpitch = (bytewidth - 16)/4;
int dstrow = bytewidth * 8;
unsigned int *src = (unsigned int*) psp_texture->data;
unsigned char *data = NULL;
data = malloc(psp_texture->size);
if(!data)
return 0;
sceKernelDcacheWritebackAll();
int j;
unsigned char *ydst = (unsigned char *)data;
for(blocky = 0; blocky < heightblocks; ++blocky)
{
unsigned char *xdst = ydst;
for(blockx = 0; blockx < widthblocks; ++blockx)
{
unsigned int *block;
block = (unsigned int*)xdst;
for(j = 0; j < 8; ++j)
{
*(block++) = *(src++);
*(block++) = *(src++);
*(block++) = *(src++);
*(block++) = *(src++);
block += dstpitch;
}
xdst += 16;
}
ydst += dstrow;
}
free(psp_texture->data);
psp_texture->data = data;
psp_texture->swizzled = SDL_FALSE;
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->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)
{
}
static int
PSP_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
/* PSP_RenderData *renderdata = (PSP_RenderData *) renderer->driverdata; */
PSP_TextureData* psp_texture = (PSP_TextureData*) SDL_calloc(1, sizeof(*psp_texture));
if(!psp_texture)
return -1;
psp_texture->swizzled = SDL_FALSE;
psp_texture->width = texture->w;
psp_texture->height = texture->h;
psp_texture->textureHeight = TextureNextPow2(texture->h);
psp_texture->textureWidth = TextureNextPow2(texture->w);
psp_texture->format = PixelFormatToPSPFMT(texture->format);
switch(psp_texture->format)
{
case GU_PSM_5650:
case GU_PSM_5551:
case GU_PSM_4444:
psp_texture->bits = 16;
break;
case GU_PSM_8888:
psp_texture->bits = 32;
break;
default:
return -1;
}
psp_texture->pitch = psp_texture->textureWidth * SDL_BYTESPERPIXEL(texture->format);
psp_texture->size = psp_texture->textureHeight*psp_texture->pitch;
psp_texture->data = SDL_calloc(1, psp_texture->size);
if(!psp_texture->data)
{
SDL_free(psp_texture);
return SDL_OutOfMemory();
}
texture->driverdata = psp_texture;
return 0;
}
void
TextureActivate(SDL_Texture * texture)
{
PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata;
int scaleMode = GetScaleQuality();
/* Swizzling is useless with small textures. */
if (texture->w >= 16 || texture->h >= 16)
{
TextureSwizzle(psp_texture);
}
sceGuEnable(GU_TEXTURE_2D);
sceGuTexWrap(GU_REPEAT, GU_REPEAT);
sceGuTexMode(psp_texture->format, 0, 0, psp_texture->swizzled);
sceGuTexFilter(scaleMode, scaleMode); /* GU_NEAREST good for tile-map */
/* GU_LINEAR good for scaling */
sceGuTexImage(0, psp_texture->textureWidth, psp_texture->textureHeight, psp_texture->textureWidth, psp_texture->data);
sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
}
static int
PSP_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, const void *pixels, int pitch)
{
/* PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata; */
const Uint8 *src;
Uint8 *dst;
int row, length,dpitch;
src = pixels;
PSP_LockTexture(renderer, texture,rect,(void **)&dst, &dpitch);
length = rect->w * SDL_BYTESPERPIXEL(texture->format);
if (length == pitch && length == dpitch) {
SDL_memcpy(dst, src, length*rect->h);
} else {
for (row = 0; row < rect->h; ++row) {
SDL_memcpy(dst, src, length);
src += pitch;
dst += dpitch;
}
}
sceKernelDcacheWritebackAll();
return 0;
}
static int
PSP_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, void **pixels, int *pitch)
{
PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata;
*pixels =
(void *) ((Uint8 *) psp_texture->data + rect->y * psp_texture->pitch +
rect->x * SDL_BYTESPERPIXEL(texture->format));
*pitch = psp_texture->pitch;
return 0;
}
static void
PSP_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata;
SDL_Rect rect;
/* We do whole texture updates, at least for now */
rect.x = 0;
rect.y = 0;
rect.w = texture->w;
rect.h = texture->h;
PSP_UpdateTexture(renderer, texture, &rect, psp_texture->data, psp_texture->pitch);
}
static int
PSP_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
{
return 0;
}
static int
PSP_UpdateViewport(SDL_Renderer * renderer)
{
return 0;
}
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)
{
/* 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);
return 0;
}
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));
for (i = 0; i < count; ++i) {
vertices[i].x = points[i].x;
vertices[i].y = points[i].y;
vertices[i].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)
{
int color = renderer->a << 24 | renderer->b << 16 | renderer->g << 8 | renderer->r;
int i;
StartDrawing(renderer);
VertV* vertices = (VertV*)sceGuGetMemory(count*sizeof(VertV));
for (i = 0; i < count; ++i) {
vertices[i].x = points[i].x;
vertices[i].y = points[i].y;
vertices[i].z = 0.0f;
}
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) {
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);
}
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)
{
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;
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);
}
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;
sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
}
else
{
float start, end;
float curU = u0;
float curX = x;
float endX = x + width;
float slice = 64.0f;
float ustep = (u1 - u0)/width * slice;
if(ustep < 0.0f)
ustep = -ustep;
for(start = 0, end = width; start < end; start += slice)
{
VertTV* vertices = (VertTV*)sceGuGetMemory((sizeof(VertTV))<<1);
float polyWidth = ((curX + slice) > endX) ? (endX - curX) : slice;
float sourceWidth = ((curU + ustep) > u1) ? (u1 - curU) : ustep;
vertices[0].u = curU;
vertices[0].v = v0;
vertices[0].x = curX;
vertices[0].y = y;
vertices[0].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);
}
}
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 0;
}
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;
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;
centerx = center->x;
centery = center->y;
alpha = texture->a;
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);
}
/* x += width * 0.5f; */
/* y += height * 0.5f; */
x += centerx;
y += centery;
float c, s;
MathSincos(degToRad(angle), &s, &c);
/* width *= 0.5f; */
/* height *= 0.5f; */
width -= centerx;
height -= centery;
float cw = c*width;
float sw = s*width;
float ch = c*height;
float sh = s*height;
VertTV* vertices = (VertTV*)sceGuGetMemory(sizeof(VertTV)<<2);
vertices[0].u = u0;
vertices[0].v = v0;
vertices[0].x = x - cw + sh;
vertices[0].y = y - sw - ch;
vertices[0].z = 0;
vertices[1].u = u0;
vertices[1].v = v1;
vertices[1].x = x - cw - sh;
vertices[1].y = y - sw + ch;
vertices[1].z = 0;
vertices[2].u = u1;
vertices[2].v = v1;
vertices[2].x = x + cw - sh;
vertices[2].y = y + sw + ch;
vertices[2].z = 0;
vertices[3].u = u1;
vertices[3].v = v0;
vertices[3].x = x + cw + sh;
vertices[3].y = y + sw - ch;
vertices[3].z = 0;
if (flip & SDL_FLIP_HORIZONTAL) {
Swap(&vertices[0].v, &vertices[2].v);
Swap(&vertices[1].v, &vertices[3].v);
}
if (flip & SDL_FLIP_VERTICAL) {
Swap(&vertices[0].u, &vertices[2].u);
Swap(&vertices[1].u, &vertices[3].u);
}
sceGuDrawArray(GU_TRIANGLE_FAN, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 4, 0, vertices);
if(alpha != 255)
sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
return 0;
}
static void
PSP_RenderPresent(SDL_Renderer * renderer)
{
PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata;
if(!data->displayListAvail)
return;
data->displayListAvail = SDL_FALSE;
sceGuFinish();
sceGuSync(0,0);
/* if(data->vsync) */
sceDisplayWaitVblankStart();
data->backbuffer = data->frontbuffer;
data->frontbuffer = vabsptr(sceGuSwapBuffers());
}
static void
PSP_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
PSP_RenderData *renderdata = (PSP_RenderData *) renderer->driverdata;
PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata;
if (renderdata == 0)
return;
if(psp_texture == 0)
return;
SDL_free(psp_texture->data);
SDL_free(psp_texture);
texture->driverdata = NULL;
}
static void
PSP_DestroyRenderer(SDL_Renderer * renderer)
{
PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata;
if (data) {
if (!data->initialized)
return;
StartDrawing(renderer);
sceGuTerm();
/* vfree(data->backbuffer); */
/* vfree(data->frontbuffer); */
data->initialized = SDL_FALSE;
data->displayListAvail = SDL_FALSE;
SDL_free(data);
}
SDL_free(renderer);
}
#endif /* SDL_VIDEO_RENDER_PSP */
/* vi: set ts=4 sw=4 expandtab: */
SDL_Renderer::RenderDrawLines
int(* RenderDrawLines)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
Definition: SDL_sysrender.h:106
dst
GLenum GLenum dst
Definition: SDL_opengl_glext.h:1737
SDL_FRect::w
float w
Definition: SDL_sysrender.h:44
format
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1565
SDL_Renderer::RenderDrawPoints
int(* RenderDrawPoints)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
Definition: SDL_sysrender.h:104
SDL_Renderer::LockTexture
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
Definition: SDL_sysrender.h:97
SDL_FLIP_HORIZONTAL
Definition: SDL_render.h:114
r
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2072
result
GLuint64EXT * result
Definition: SDL_opengl_glext.h:9432
s
GLdouble s
Definition: SDL_opengl.h:2056
width
GLint GLint GLsizei width
Definition: SDL_opengl.h:1565
n
GLdouble n
Definition: SDL_opengl_glext.h:1952
SDL_RENDERER_ACCELERATED
Definition: SDL_render.h:67
Uint32
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:157
SDL_Renderer::RenderReadPixels
int(* RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
Definition: SDL_sysrender.h:115
SDL_Renderer::info
SDL_RendererInfo info
Definition: SDL_sysrender.h:126
SDL_RENDERER_TARGETTEXTURE
Definition: SDL_render.h:71
SDL_RendererInfo::flags
Uint32 flags
Definition: SDL_render.h:81
SDL_BLENDMODE_NONE
Definition: SDL_blendmode.h:42
x
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1567
count
GLuint GLuint GLsizei count
Definition: SDL_opengl.h:1564
rect
SDL_Rect rect
Definition: testrelative.c:27
window
SDL_Window * window
Definition: testautomation_render.c:26
SDL_HINT_RENDER_SCALE_QUALITY
#define SDL_HINT_RENDER_SCALE_QUALITY
A variable controlling the scaling quality.
Definition: SDL_hints.h:131
end
GLuint GLuint end
Definition: SDL_opengl.h:1564
texture
GLenum GLenum GLuint texture
Definition: SDL_opengl_glext.h:1178
SDL_RENDERER_PRESENTVSYNC
Definition: SDL_render.h:69
SDL_Renderer::driverdata
void * driverdata
Definition: SDL_sysrender.h:161
free
SDL_EventEntry * free
Definition: SDL_events.c:81
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1967
SDL_GetHint
#define SDL_GetHint
Definition: SDL_dynapi_overrides.h:197
SDL_Renderer
Definition: SDL_sysrender.h:76
SDL_FLIP_VERTICAL
Definition: SDL_render.h:115
u1
GLfixed u1
Definition: SDL_opengl_glext.h:4558
f
GLfloat f
Definition: SDL_opengl_glext.h:1870
SDL_BYTESPERPIXEL
#define SDL_BYTESPERPIXEL(X)
Definition: SDL_pixels.h:127
start
GLuint start
Definition: SDL_opengl.h:1564
SDL_Renderer::RenderFillRects
int(* RenderFillRects)(SDL_Renderer *renderer, const SDL_FRect *rects, int count)
Definition: SDL_sysrender.h:108
pixels
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: SDL_opengl.h:1565
bits
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
Definition: SDL_opengl_glext.h:6176
SDL_strcasecmp
#define SDL_strcasecmp
Definition: SDL_dynapi_overrides.h:425
height
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1565
SDL_RendererInfo::name
const char * name
Definition: SDL_render.h:80
SDL_FRect::y
float y
Definition: SDL_sysrender.h:43
size
GLsizeiptr size
Definition: SDL_opengl_glext.h:537
SDL_Renderer::window
SDL_Window * window
Definition: SDL_sysrender.h:129
SDL_RenderDriver::info
SDL_RendererInfo info
Definition: SDL_sysrender.h:170
SDL_Renderer::RenderClear
int(* RenderClear)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:103
SDL_Texture::a
Uint8 a
Definition: SDL_sysrender.h:58
alpha
GLfloat GLfloat GLfloat alpha
Definition: SDL_opengl_glext.h:412
SDL_Renderer::DestroyRenderer
void(* DestroyRenderer)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:120
points
GLfixed GLfixed GLint GLint GLfixed points
Definition: SDL_opengl_glext.h:4558
SDL_Texture
Definition: SDL_sysrender.h:49
SDL_BLENDMODE_MOD
Definition: SDL_blendmode.h:50
blendMode
static SDL_BlendMode blendMode
Definition: testdraw2.c:34
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:126
v
const GLdouble * v
Definition: SDL_opengl.h:2057
SDL_Renderer::UpdateTexture
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
Definition: SDL_sysrender.h:89
renderer
SDL_Renderer * renderer
Definition: testautomation_render.c:27
SDL_memcpy
#define SDL_memcpy
Definition: SDL_dynapi_overrides.h:393
SDL_calloc
void * SDL_calloc(size_t nmemb, size_t size)
__attribute__
Definition: mmx.h:46
y
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1567
SDL_Renderer::g
Uint8 g
Definition: SDL_sysrender.h:158
SDL_PIXELFORMAT_ABGR8888
Definition: SDL_pixels.h:253
SDL_RecreateWindow
int SDL_RecreateWindow(SDL_Window *window, Uint32 flags)
Definition: SDL_video.c:1469
GetScaleQuality
static int GetScaleQuality(void)
Definition: SDL_render_sw.c:583
Uint8
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:139
event
struct _cl_event * event
Definition: SDL_opengl_glext.h:2649
SDL_Renderer::blendMode
SDL_BlendMode blendMode
Definition: SDL_sysrender.h:159
SDL_free
void SDL_free(void *mem)
SDL_PIXELFORMAT_ABGR4444
Definition: SDL_pixels.h:205
SDL_Renderer::b
Uint8 b
Definition: SDL_sysrender.h:158
c
const GLubyte * c
Definition: SDL_opengl_glext.h:11093
SDL_hints.h
SDL_Texture::w
int w
Definition: SDL_sysrender.h:54
SDL_Renderer::UnlockTexture
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:99
SDL_RenderDriver::CreateRenderer
SDL_Renderer *(* CreateRenderer)(SDL_Window *window, Uint32 flags)
Definition: SDL_sysrender.h:167
SDL_Rect::x
int x
Definition: SDL_rect.h:66
SDL_Renderer::SetRenderTarget
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:100
SDL_Renderer::UpdateViewport
int(* UpdateViewport)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:101
SDL_TRUE
Definition: SDL_stdinc.h:129
SDL_Rect::w
int w
Definition: SDL_rect.h:67
SDL_FRect::h
float h
Definition: SDL_sysrender.h:45
SDL_RendererFlip
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
Definition: SDL_render.h:111
SDL_Renderer::RenderCopy
int(* RenderCopy)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
Definition: SDL_sysrender.h:110
SDL_WindowEvent
Window state change event data (event.window.*)
Definition: SDL_events.h:171
i
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:42
NULL
#define NULL
Definition: begin_code.h:143
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
malloc
#define malloc
Definition: SDL_malloc.c:641
z
GLdouble GLdouble z
Definition: SDL_opengl_glext.h:404
SDL_RenderDriver
Definition: SDL_sysrender.h:165
SDL_Renderer::RenderCopyEx
int(* RenderCopyEx)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcquad, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
Definition: SDL_sysrender.h:112
SDL_Rect::h
int h
Definition: SDL_rect.h:67
v1
GLfloat GLfloat v1
Definition: SDL_opengl_glext.h:691
SDL_Window
The type used to identify a window.
Definition: SDL_sysvideo.h:71
rects
SDL_Rect rects[MAX_RECTS]
Definition: testintersections.c:129
SDL_GetWindowPixelFormat
#define SDL_GetWindowPixelFormat
Definition: SDL_dynapi_overrides.h:517
SDL_BLENDMODE_ADD
Definition: SDL_blendmode.h:47
color
GLuint color
Definition: SDL_opengl_glext.h:1148
SDL_FALSE
Definition: SDL_stdinc.h:128
SDL_Renderer::WindowEvent
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
Definition: SDL_sysrender.h:80
v0
GLfloat v0
Definition: SDL_opengl_glext.h:690
angle
GLfloat angle
Definition: SDL_opengl_glext.h:6097
pixel_format
Uint32 pixel_format
Definition: testoverlay2.c:152
SDL_Texture::format
Uint32 format
Definition: SDL_sysrender.h:52
SDL_Texture::driverdata
void * driverdata
Definition: SDL_sysrender.h:69
flags
GLbitfield flags
Definition: SDL_opengl_glext.h:1480
w
GLubyte GLubyte GLubyte GLubyte w
Definition: SDL_opengl_glext.h:731
SDL_Renderer::DestroyTexture
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:118
SDL_Renderer::CreateTexture
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:82
SDL_Renderer::RenderPresent
void(* RenderPresent)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:117
SDL_Renderer::r
Uint8 r
Definition: SDL_sysrender.h:158
SDL_FRect::x
float x
Definition: SDL_sysrender.h:42
length
GLuint GLsizei GLsizei * length
Definition: SDL_opengl_glext.h:669
SDL_PIXELFORMAT_ABGR1555
Definition: SDL_pixels.h:217
SDL_Renderer::a
Uint8 a
Definition: SDL_sysrender.h:158
a
GLboolean GLboolean GLboolean GLboolean a
Definition: SDL_opengl_glext.h:1109
src
GLenum src
Definition: SDL_opengl_glext.h:1737
b
GLboolean GLboolean GLboolean b
Definition: SDL_opengl_glext.h:1109
row
GLenum GLenum void * row
Definition: SDL_opengl_glext.h:3138
SDL_Rect::y
int y
Definition: SDL_rect.h:66
SDL_FPoint::x
float x
Definition: SDL_sysrender.h:36
SDL_FRect
Definition: SDL_sysrender.h:40
SDL_FPoint
Definition: SDL_sysrender.h:34
SDL_Rect
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:64
SDL_BLENDMODE_BLEND
Definition: SDL_blendmode.h:44
SDL_PIXELFORMAT_BGR565
Definition: SDL_pixels.h:226
SDL_Texture::h
int h
Definition: SDL_sysrender.h:55
j
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int in j)
Definition: SDL_x11sym.h:42
SDL_FPoint::y
float y
Definition: SDL_sysrender.h:37