23 #if SDL_VIDEO_RENDER_PSP
26 #include "../SDL_sysrender.h"
28 #include <pspkernel.h>
29 #include <pspdisplay.h>
81 static void PSP_DestroyRenderer(
SDL_Renderer * renderer);
100 .num_texture_formats = 4,
106 .max_texture_width = 512,
107 .max_texture_height = 512,
111 #define PSP_SCREEN_WIDTH 480
112 #define PSP_SCREEN_HEIGHT 272
114 #define PSP_FRAME_BUFFER_WIDTH 512
115 #define PSP_FRAME_BUFFER_SIZE (PSP_FRAME_BUFFER_WIDTH*PSP_SCREEN_HEIGHT)
117 static unsigned int __attribute__((aligned(16))) DisplayList[262144];
120 #define COL5650(r,g,b,a) ((r>>3) | ((g>>2)<<5) | ((b>>3)<<11))
121 #define COL5551(r,g,b,a) ((r>>3) | ((g>>3)<<5) | ((b>>3)<<10) | (a>0?0x7000:0))
122 #define COL4444(r,g,b,a) ((r>>4) | ((g>>4)<<4) | ((b>>4)<<8) | ((a>>4)<<12))
123 #define COL8888(r,g,b,a) ((r) | ((g)<<8) | ((b)<<16) | ((a)<<24))
136 unsigned int currentColor;
137 int currentBlendMode;
148 unsigned int textureWidth;
149 unsigned int textureHeight;
173 TextureNextPow2(
unsigned int w)
192 if (!hint || *hint ==
'0' ||
SDL_strcasecmp(hint,
"nearest") == 0) {
220 if(data->displayListAvail)
223 sceGuStart(GU_DIRECT, DisplayList);
229 TextureSwizzle(PSP_TextureData *psp_texture)
231 if(psp_texture->swizzled)
234 int bytewidth = psp_texture->textureWidth*(psp_texture->bits>>3);
235 int height = psp_texture->size / bytewidth;
237 int rowblocks = (bytewidth>>4);
238 int rowblocksadd = (rowblocks-1)<<7;
239 unsigned int blockaddress = 0;
240 unsigned int *
src = (
unsigned int*) psp_texture->data;
247 for(j = 0; j <
height; j++, blockaddress += 16)
251 block = (
unsigned int*)&
data[blockaddress];
255 for(i = 0; i < rowblocks; i++)
265 blockaddress += rowblocksadd;
268 free(psp_texture->data);
269 psp_texture->data =
data;
274 int TextureUnswizzle(PSP_TextureData *psp_texture)
276 if(!psp_texture->swizzled)
281 int bytewidth = psp_texture->textureWidth*(psp_texture->bits>>3);
282 int height = psp_texture->size / bytewidth;
284 int widthblocks = bytewidth/16;
285 int heightblocks = height/8;
287 int dstpitch = (bytewidth - 16)/4;
288 int dstrow = bytewidth * 8;
290 unsigned int *src = (
unsigned int*) psp_texture->data;
299 sceKernelDcacheWritebackAll();
303 unsigned char *ydst = (
unsigned char *)
data;
305 for(blocky = 0; blocky < heightblocks; ++blocky)
307 unsigned char *xdst = ydst;
309 for(blockx = 0; blockx < widthblocks; ++blockx)
313 block = (
unsigned int*)xdst;
315 for(j = 0; j < 8; ++
j)
317 *(block++) = *(src++);
318 *(block++) = *(src++);
319 *(block++) = *(src++);
320 *(block++) = *(src++);
330 free(psp_texture->data);
332 psp_texture->data =
data;
344 PSP_RenderData *
data;
352 data = (PSP_RenderData *)
SDL_calloc(1,
sizeof(*data));
354 PSP_DestroyRenderer(renderer);
377 renderer->
info = PSP_RenderDriver.
info;
380 renderer->
window = window;
398 data->frontbuffer = (
unsigned int *)(PSP_FRAME_BUFFER_SIZE<<1);
399 data->backbuffer = (
unsigned int *)(0);
401 data->psm = pixelformat;
404 data->frontbuffer = (
unsigned int *)(PSP_FRAME_BUFFER_SIZE<<2);
405 data->backbuffer = (
unsigned int *)(0);
407 data->psm = GU_PSM_8888;
413 sceGuStart(GU_DIRECT, DisplayList);
414 sceGuDrawBuffer(data->psm, data->frontbuffer, PSP_FRAME_BUFFER_WIDTH);
415 sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, data->backbuffer, PSP_FRAME_BUFFER_WIDTH);
418 sceGuOffset(2048 - (PSP_SCREEN_WIDTH>>1), 2048 - (PSP_SCREEN_HEIGHT>>1));
419 sceGuViewport(2048, 2048, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
421 data->frontbuffer = vabsptr(data->frontbuffer);
422 data->backbuffer = vabsptr(data->backbuffer);
425 sceGuScissor(0, 0, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
426 sceGuEnable(GU_SCISSOR_TEST);
429 sceGuFrontFace(GU_CCW);
430 sceGuEnable(GU_CULL_FACE);
433 sceGuEnable(GU_TEXTURE_2D);
434 sceGuShadeModel(GU_SMOOTH);
435 sceGuTexWrap(GU_REPEAT, GU_REPEAT);
438 sceGuEnable(GU_BLEND);
439 sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
441 sceGuTexFilter(GU_LINEAR,GU_LINEAR);
445 sceDisplayWaitVblankStartCB();
446 sceGuDisplay(GU_TRUE);
462 PSP_TextureData* psp_texture = (PSP_TextureData*)
SDL_calloc(1,
sizeof(*psp_texture));;
468 psp_texture->width = texture->
w;
469 psp_texture->height = texture->
h;
470 psp_texture->textureHeight = TextureNextPow2(texture->
h);
471 psp_texture->textureWidth = TextureNextPow2(texture->
w);
472 psp_texture->format = PixelFormatToPSPFMT(texture->
format);
474 switch(psp_texture->format)
479 psp_texture->bits = 16;
483 psp_texture->bits = 32;
491 psp_texture->size = psp_texture->textureHeight*psp_texture->pitch;
492 psp_texture->data =
SDL_calloc(1, psp_texture->size);
494 if(!psp_texture->data)
508 PSP_TextureData *psp_texture = (PSP_TextureData *) texture->
driverdata;
512 if (texture->
w >= 16 || texture->
h >= 16)
514 TextureSwizzle(psp_texture);
517 sceGuEnable(GU_TEXTURE_2D);
518 sceGuTexWrap(GU_REPEAT, GU_REPEAT);
519 sceGuTexMode(psp_texture->format, 0, 0, psp_texture->swizzled);
520 sceGuTexFilter(scaleMode, scaleMode);
522 sceGuTexImage(0, psp_texture->textureWidth, psp_texture->textureHeight, psp_texture->textureWidth, psp_texture->data);
523 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
537 PSP_LockTexture(renderer, texture,rect,(
void **)&dst, &dpitch);
539 if (length == pitch && length == dpitch) {
542 for (row = 0; row < rect->
h; ++
row) {
549 sceKernelDcacheWritebackAll();
555 const SDL_Rect * rect,
void **pixels,
int *pitch)
557 PSP_TextureData *psp_texture = (PSP_TextureData *) texture->
driverdata;
560 (
void *) ((
Uint8 *) psp_texture->data + rect->
y * psp_texture->pitch +
562 *pitch = psp_texture->pitch;
569 PSP_TextureData *psp_texture = (PSP_TextureData *) texture->
driverdata;
577 PSP_UpdateTexture(renderer, texture, &rect, psp_texture->data, psp_texture->pitch);
596 PSP_SetBlendMode(
SDL_Renderer * renderer,
int blendMode)
598 PSP_RenderData *data = (PSP_RenderData *) renderer->
driverdata;
599 if (blendMode != data-> currentBlendMode) {
602 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
603 sceGuDisable(GU_BLEND);
606 sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
607 sceGuEnable(GU_BLEND);
608 sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0 );
611 sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
612 sceGuEnable(GU_BLEND);
613 sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_FIX, 0, 0x00FFFFFF );
616 sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
617 sceGuEnable(GU_BLEND);
618 sceGuBlendFunc( GU_ADD, GU_FIX, GU_SRC_COLOR, 0, 0);
621 data->currentBlendMode = blendMode;
631 StartDrawing(renderer);
632 int color = renderer->
a << 24 | renderer->
b << 16 | renderer->
g << 8 | renderer->
r;
633 sceGuClearColor(color);
635 sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT|GU_FAST_CLEAR_BIT);
644 int color = renderer->
a << 24 | renderer->
b << 16 | renderer->
g << 8 | renderer->
r;
646 StartDrawing(renderer);
647 VertV*
vertices = (VertV*)sceGuGetMemory(count*
sizeof(VertV));
649 for (i = 0; i <
count; ++
i) {
650 vertices[
i].x = points[
i].
x;
651 vertices[
i].y = points[
i].
y;
652 vertices[
i].z = 0.0f;
654 sceGuDisable(GU_TEXTURE_2D);
656 sceGuShadeModel(GU_FLAT);
657 sceGuDrawArray(GU_POINTS, GU_VERTEX_32BITF|GU_TRANSFORM_2D, count, 0, vertices);
658 sceGuShadeModel(GU_SMOOTH);
659 sceGuEnable(GU_TEXTURE_2D);
668 int color = renderer->
a << 24 | renderer->
b << 16 | renderer->
g << 8 | renderer->
r;
670 StartDrawing(renderer);
671 VertV* vertices = (VertV*)sceGuGetMemory(count*
sizeof(VertV));
673 for (i = 0; i <
count; ++
i) {
674 vertices[
i].x = points[
i].
x;
675 vertices[
i].y = points[
i].
y;
676 vertices[
i].z = 0.0f;
679 sceGuDisable(GU_TEXTURE_2D);
681 sceGuShadeModel(GU_FLAT);
682 sceGuDrawArray(GU_LINE_STRIP, GU_VERTEX_32BITF|GU_TRANSFORM_2D, count, 0, vertices);
683 sceGuShadeModel(GU_SMOOTH);
684 sceGuEnable(GU_TEXTURE_2D);
693 int color = renderer->
a << 24 | renderer->
b << 16 | renderer->
g << 8 | renderer->
r;
695 StartDrawing(renderer);
697 for (i = 0; i <
count; ++
i) {
699 VertV* vertices = (VertV*)sceGuGetMemory((
sizeof(VertV)<<1));
700 vertices[0].
x = rect->
x;
701 vertices[0].y = rect->
y;
702 vertices[0].z = 0.0f;
704 vertices[1].x = rect->
x + rect->
w;
705 vertices[1].y = rect->
y + rect->
h;
706 vertices[1].z = 0.0f;
708 sceGuDisable(GU_TEXTURE_2D);
710 sceGuShadeModel(GU_FLAT);
711 sceGuDrawArray(GU_SPRITES, GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
712 sceGuShadeModel(GU_SMOOTH);
713 sceGuEnable(GU_TEXTURE_2D);
720 #define PI 3.14159265358979f
722 #define radToDeg(x) ((x)*180.f/PI)
723 #define degToRad(x) ((x)*PI/180.f)
725 float MathAbs(
float x)
731 "vabs.s S000, S000\n"
738 void MathSincos(
float r,
float *
s,
float *
c)
742 "vcst.s S003, VFPU_2_PI\n"
743 "vmul.s S002, S002, S003\n"
744 "vrot.p C000, S002, [s, c]\n"
747 :
"=r"(*s),
"=r"(*c):
"r"(
r));
750 void Swap(
float *
a,
float *
b)
772 u1 = srcrect->
x + srcrect->
w;
773 v1 = srcrect->
y + srcrect->
h;
777 StartDrawing(renderer);
778 TextureActivate(texture);
779 PSP_SetBlendMode(renderer, renderer->
blendMode);
783 sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
784 sceGuColor(GU_RGBA(255, 255, 255, alpha));
786 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
787 sceGuColor(0xFFFFFFFF);
790 if((MathAbs(u1) - MathAbs(u0)) < 64.0
f)
792 VertTV* vertices = (VertTV*)sceGuGetMemory((
sizeof(VertTV))<<1);
802 vertices[1].x = x +
width;
803 vertices[1].y = y +
height;
806 sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
813 float endX = x +
width;
815 float ustep = (u1 - u0)/width * slice;
820 for(start = 0, end = width; start <
end; start += slice)
822 VertTV* vertices = (VertTV*)sceGuGetMemory((
sizeof(VertTV))<<1);
824 float polyWidth = ((curX + slice) > endX) ? (endX - curX) : slice;
825 float sourceWidth = ((curU + ustep) > u1) ? (u1 - curU) : ustep;
827 vertices[0].u = curU;
829 vertices[0].x = curX;
836 vertices[1].u = curU;
838 vertices[1].x = curX;
839 vertices[1].y = (y +
height);
842 sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
847 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
853 Uint32 pixel_format,
void * pixels,
int pitch)
868 float centerx, centery;
877 u1 = srcrect->
x + srcrect->
w;
878 v1 = srcrect->
y + srcrect->
h;
885 StartDrawing(renderer);
886 TextureActivate(texture);
887 PSP_SetBlendMode(renderer, renderer->
blendMode);
891 sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
892 sceGuColor(GU_RGBA(255, 255, 255, alpha));
894 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
895 sceGuColor(0xFFFFFFFF);
905 MathSincos(degToRad(angle), &s, &c);
918 VertTV* vertices = (VertTV*)sceGuGetMemory(
sizeof(VertTV)<<2);
922 vertices[0].x = x - cw + sh;
923 vertices[0].y = y - sw - ch;
928 vertices[1].x = x - cw - sh;
929 vertices[1].y = y - sw + ch;
934 vertices[2].x = x + cw - sh;
935 vertices[2].y = y + sw + ch;
940 vertices[3].x = x + cw + sh;
941 vertices[3].y = y + sw - ch;
945 Swap(&vertices[0].
v, &vertices[2].v);
946 Swap(&vertices[1].
v, &vertices[3].v);
949 Swap(&vertices[0].
u, &vertices[2].u);
950 Swap(&vertices[1].
u, &vertices[3].u);
953 sceGuDrawArray(GU_TRIANGLE_FAN, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 4, 0, vertices);
956 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
963 PSP_RenderData *data = (PSP_RenderData *) renderer->
driverdata;
964 if(!data->displayListAvail)
972 sceDisplayWaitVblankStart();
974 data->backbuffer = data->frontbuffer;
975 data->frontbuffer = vabsptr(sceGuSwapBuffers());
982 PSP_RenderData *renderdata = (PSP_RenderData *) renderer->
driverdata;
983 PSP_TextureData *psp_texture = (PSP_TextureData *) texture->
driverdata;
999 PSP_RenderData *data = (PSP_RenderData *) renderer->
driverdata;
1001 if (!data->initialized)
1004 StartDrawing(renderer);
DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size)
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
int(* RenderClear)(SDL_Renderer *renderer)
int(* RenderDrawPoints)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
#define SDL_HINT_RENDER_SCALE_QUALITY
A variable controlling the scaling quality.
SDL_Renderer *(* CreateRenderer)(SDL_Window *window, Uint32 flags)
DECLSPEC void SDLCALL SDL_free(void *mem)
EGLSurface EGLint EGLint EGLint EGLint height
GLboolean GLboolean GLboolean GLboolean a
#define SDL_BYTESPERPIXEL(X)
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
uint32_t Uint32
An unsigned 32-bit integer type.
DECLSPEC Uint32 SDLCALL SDL_GetWindowPixelFormat(SDL_Window *window)
Get the pixel format associated with the window.
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
GLenum GLenum GLvoid * row
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
int SDL_RecreateWindow(SDL_Window *window, Uint32 flags)
EGLSurface EGLint EGLint EGLint width
static int GetScaleQuality(void)
int(* RenderDrawLines)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum format
GLclampf GLclampf GLclampf alpha
DECLSPEC const char *SDLCALL SDL_GetHint(const char *name)
Get a hint.
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* RenderCopy)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
Window state change event data (event.window.*)
EGLSurface EGLint EGLint y
#define SDL_OutOfMemory()
GLenum GLenum GLuint texture
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
int(* RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
DECLSPEC void *SDLCALL SDL_memcpy(void *dst, const void *src, size_t len)
GLenum GLsizei GLsizei GLsizei GLsizei GLbitfield flags
int(* RenderFillRects)(SDL_Renderer *renderer, const SDL_FRect *rects, int count)
uint8_t Uint8
An unsigned 8-bit integer type.
GLdouble GLdouble GLdouble r
GLdouble GLdouble GLdouble b
GLint GLint GLint GLint z
GLint GLint GLint GLint GLint w
int(* UpdateViewport)(SDL_Renderer *renderer)
GLuint GLdouble GLdouble GLint GLint const GLdouble * points
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)
void(* RenderPresent)(SDL_Renderer *renderer)
void(* DestroyRenderer)(SDL_Renderer *renderer)
DECLSPEC int SDLCALL SDL_strcasecmp(const char *str1, const char *str2)
A rectangle, with the origin at the upper left.