21 #include "../../SDL_internal.h" 23 #if SDL_VIDEO_RENDER_PSP 26 #include "../SDL_sysrender.h" 28 #include <pspkernel.h> 29 #include <pspdisplay.h> 102 .num_texture_formats = 4,
108 .max_texture_width = 512,
109 .max_texture_height = 512,
113 #define PSP_SCREEN_WIDTH 480 114 #define PSP_SCREEN_HEIGHT 272 116 #define PSP_FRAME_BUFFER_WIDTH 512 117 #define PSP_FRAME_BUFFER_SIZE (PSP_FRAME_BUFFER_WIDTH*PSP_SCREEN_HEIGHT) 119 static unsigned int __attribute__((aligned(16))) DisplayList[262144];
122 #define COL5650(r,g,b,a) ((r>>3) | ((g>>2)<<5) | ((b>>3)<<11)) 123 #define COL5551(r,g,b,a) ((r>>3) | ((g>>3)<<5) | ((b>>3)<<10) | (a>0?0x7000:0)) 124 #define COL4444(r,g,b,a) ((r>>4) | ((g>>4)<<4) | ((b>>4)<<8) | ((a>>4)<<12)) 125 #define COL8888(r,g,b,a) ((r) | ((g)<<8) | ((b)<<16) | ((a)<<24)) 138 unsigned int currentColor;
139 int currentBlendMode;
150 unsigned int textureWidth;
151 unsigned int textureHeight;
175 TextureNextPow2(
unsigned int w)
210 if(data->displayListAvail)
213 sceGuStart(GU_DIRECT, DisplayList);
219 TextureSwizzle(PSP_TextureData *psp_texture)
221 if(psp_texture->swizzled)
224 int bytewidth = psp_texture->textureWidth*(psp_texture->bits>>3);
225 int height = psp_texture->size / bytewidth;
227 int rowblocks = (bytewidth>>4);
228 int rowblocksadd = (rowblocks-1)<<7;
229 unsigned int blockaddress = 0;
230 unsigned int *
src = (
unsigned int*) psp_texture->data;
237 for(j = 0; j <
height; j++, blockaddress += 16)
241 block = (
unsigned int*)&
data[blockaddress];
245 for(i = 0; i < rowblocks; i++)
255 blockaddress += rowblocksadd;
258 free(psp_texture->data);
259 psp_texture->data =
data;
264 int TextureUnswizzle(PSP_TextureData *psp_texture)
266 if(!psp_texture->swizzled)
271 int bytewidth = psp_texture->textureWidth*(psp_texture->bits>>3);
272 int height = psp_texture->size / bytewidth;
274 int widthblocks = bytewidth/16;
275 int heightblocks = height/8;
277 int dstpitch = (bytewidth - 16)/4;
278 int dstrow = bytewidth * 8;
280 unsigned int *src = (
unsigned int*) psp_texture->data;
289 sceKernelDcacheWritebackAll();
293 unsigned char *ydst = (
unsigned char *)
data;
295 for(blocky = 0; blocky < heightblocks; ++blocky)
297 unsigned char *xdst = ydst;
299 for(blockx = 0; blockx < widthblocks; ++blockx)
303 block = (
unsigned int*)xdst;
305 for(j = 0; j < 8; ++
j)
307 *(block++) = *(src++);
308 *(block++) = *(src++);
309 *(block++) = *(src++);
310 *(block++) = *(src++);
320 free(psp_texture->data);
322 psp_texture->data =
data;
334 PSP_RenderData *
data;
342 data = (PSP_RenderData *)
SDL_calloc(1,
sizeof(*data));
344 PSP_DestroyRenderer(renderer);
368 renderer->
info = PSP_RenderDriver.
info;
389 data->frontbuffer = (
unsigned int *)(PSP_FRAME_BUFFER_SIZE<<1);
390 data->backbuffer = (
unsigned int *)(0);
392 data->psm = pixelformat;
395 data->frontbuffer = (
unsigned int *)(PSP_FRAME_BUFFER_SIZE<<2);
396 data->backbuffer = (
unsigned int *)(0);
398 data->psm = GU_PSM_8888;
404 sceGuStart(GU_DIRECT, DisplayList);
405 sceGuDrawBuffer(data->psm, data->frontbuffer, PSP_FRAME_BUFFER_WIDTH);
406 sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, data->backbuffer, PSP_FRAME_BUFFER_WIDTH);
409 sceGuOffset(2048 - (PSP_SCREEN_WIDTH>>1), 2048 - (PSP_SCREEN_HEIGHT>>1));
410 sceGuViewport(2048, 2048, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
412 data->frontbuffer = vabsptr(data->frontbuffer);
413 data->backbuffer = vabsptr(data->backbuffer);
416 sceGuScissor(0, 0, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
417 sceGuEnable(GU_SCISSOR_TEST);
420 sceGuFrontFace(GU_CCW);
421 sceGuEnable(GU_CULL_FACE);
424 sceGuEnable(GU_TEXTURE_2D);
425 sceGuShadeModel(GU_SMOOTH);
426 sceGuTexWrap(GU_REPEAT, GU_REPEAT);
429 sceGuEnable(GU_BLEND);
430 sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
432 sceGuTexFilter(GU_LINEAR,GU_LINEAR);
436 sceDisplayWaitVblankStartCB();
437 sceGuDisplay(GU_TRUE);
453 PSP_TextureData* psp_texture = (PSP_TextureData*)
SDL_calloc(1,
sizeof(*psp_texture));
459 psp_texture->width = texture->
w;
460 psp_texture->height = texture->
h;
461 psp_texture->textureHeight = TextureNextPow2(texture->
h);
462 psp_texture->textureWidth = TextureNextPow2(texture->
w);
463 psp_texture->format = PixelFormatToPSPFMT(texture->
format);
465 switch(psp_texture->format)
470 psp_texture->bits = 16;
474 psp_texture->bits = 32;
482 psp_texture->size = psp_texture->textureHeight*psp_texture->pitch;
483 psp_texture->data =
SDL_calloc(1, psp_texture->size);
485 if(!psp_texture->data)
504 PSP_TextureData *psp_texture = (PSP_TextureData *) texture->
driverdata;
508 if (texture->
w >= 16 || texture->
h >= 16)
510 TextureSwizzle(psp_texture);
513 sceGuEnable(GU_TEXTURE_2D);
514 sceGuTexWrap(GU_REPEAT, GU_REPEAT);
515 sceGuTexMode(psp_texture->format, 0, 0, psp_texture->swizzled);
516 sceGuTexFilter(scaleMode, scaleMode);
518 sceGuTexImage(0, psp_texture->textureWidth, psp_texture->textureHeight, psp_texture->textureWidth, psp_texture->data);
519 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
533 PSP_LockTexture(renderer, texture,rect,(
void **)&dst, &dpitch);
535 if (length == pitch && length == dpitch) {
538 for (row = 0; row < rect->
h; ++
row) {
545 sceKernelDcacheWritebackAll();
551 const SDL_Rect * rect,
void **pixels,
int *pitch)
553 PSP_TextureData *psp_texture = (PSP_TextureData *) texture->
driverdata;
556 (
void *) ((
Uint8 *) psp_texture->data + rect->
y * psp_texture->pitch +
558 *pitch = psp_texture->pitch;
565 PSP_TextureData *psp_texture = (PSP_TextureData *) texture->
driverdata;
573 PSP_UpdateTexture(renderer, texture, &rect, psp_texture->data, psp_texture->pitch);
594 PSP_RenderData *data = (PSP_RenderData *) renderer->
driverdata;
595 if (blendMode != data-> currentBlendMode) {
598 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
599 sceGuDisable(GU_BLEND);
602 sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
603 sceGuEnable(GU_BLEND);
604 sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0 );
607 sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
608 sceGuEnable(GU_BLEND);
609 sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_FIX, 0, 0x00FFFFFF );
612 sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
613 sceGuEnable(GU_BLEND);
614 sceGuBlendFunc( GU_ADD, GU_FIX, GU_SRC_COLOR, 0, 0);
627 StartDrawing(renderer);
628 int color = renderer->
a << 24 | renderer->
b << 16 | renderer->
g << 8 | renderer->
r;
629 sceGuClearColor(color);
631 sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT|GU_FAST_CLEAR_BIT);
640 int color = renderer->
a << 24 | renderer->
b << 16 | renderer->
g << 8 | renderer->
r;
642 StartDrawing(renderer);
643 VertV* vertices = (VertV*)sceGuGetMemory(count*
sizeof(VertV));
645 for (i = 0; i <
count; ++
i) {
646 vertices[
i].x = points[
i].
x;
647 vertices[
i].y = points[
i].
y;
648 vertices[
i].z = 0.0f;
650 sceGuDisable(GU_TEXTURE_2D);
652 sceGuShadeModel(GU_FLAT);
653 sceGuDrawArray(GU_POINTS, GU_VERTEX_32BITF|GU_TRANSFORM_2D, count, 0, vertices);
654 sceGuShadeModel(GU_SMOOTH);
655 sceGuEnable(GU_TEXTURE_2D);
664 int color = renderer->
a << 24 | renderer->
b << 16 | renderer->
g << 8 | renderer->
r;
666 StartDrawing(renderer);
667 VertV* vertices = (VertV*)sceGuGetMemory(count*
sizeof(VertV));
669 for (i = 0; i <
count; ++
i) {
670 vertices[
i].x = points[
i].
x;
671 vertices[
i].y = points[
i].
y;
672 vertices[
i].z = 0.0f;
675 sceGuDisable(GU_TEXTURE_2D);
677 sceGuShadeModel(GU_FLAT);
678 sceGuDrawArray(GU_LINE_STRIP, GU_VERTEX_32BITF|GU_TRANSFORM_2D, count, 0, vertices);
679 sceGuShadeModel(GU_SMOOTH);
680 sceGuEnable(GU_TEXTURE_2D);
689 int color = renderer->
a << 24 | renderer->
b << 16 | renderer->
g << 8 | renderer->
r;
691 StartDrawing(renderer);
693 for (i = 0; i <
count; ++
i) {
695 VertV* vertices = (VertV*)sceGuGetMemory((
sizeof(VertV)<<1));
696 vertices[0].
x = rect->
x;
697 vertices[0].y = rect->
y;
698 vertices[0].z = 0.0f;
700 vertices[1].x = rect->
x + rect->
w;
701 vertices[1].y = rect->
y + rect->
h;
702 vertices[1].z = 0.0f;
704 sceGuDisable(GU_TEXTURE_2D);
706 sceGuShadeModel(GU_FLAT);
707 sceGuDrawArray(GU_SPRITES, GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
708 sceGuShadeModel(GU_SMOOTH);
709 sceGuEnable(GU_TEXTURE_2D);
716 #define PI 3.14159265358979f 718 #define radToDeg(x) ((x)*180.f/PI) 719 #define degToRad(x) ((x)*PI/180.f) 721 float MathAbs(
float x)
727 "vabs.s S000, S000\n" 734 void MathSincos(
float r,
float *
s,
float *
c)
738 "vcst.s S003, VFPU_2_PI\n" 739 "vmul.s S002, S002, S003\n" 740 "vrot.p C000, S002, [s, c]\n" 743 :
"=r"(*s),
"=r"(*c):
"r"(
r));
746 void Swap(
float *
a,
float *
b)
768 u1 = srcrect->
x + srcrect->
w;
769 v1 = srcrect->
y + srcrect->
h;
773 StartDrawing(renderer);
774 TextureActivate(texture);
775 PSP_SetBlendMode(renderer, renderer->
blendMode);
779 sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
780 sceGuColor(GU_RGBA(255, 255, 255, alpha));
782 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
783 sceGuColor(0xFFFFFFFF);
786 if((MathAbs(u1) - MathAbs(u0)) < 64.0
f)
788 VertTV* vertices = (VertTV*)sceGuGetMemory((
sizeof(VertTV))<<1);
798 vertices[1].x = x +
width;
799 vertices[1].y = y +
height;
802 sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
809 float endX = x +
width;
811 float ustep = (u1 - u0)/width * slice;
816 for(start = 0, end = width; start <
end; start += slice)
818 VertTV* vertices = (VertTV*)sceGuGetMemory((
sizeof(VertTV))<<1);
820 float polyWidth = ((curX + slice) > endX) ? (endX - curX) : slice;
821 float sourceWidth = ((curU + ustep) > u1) ? (u1 - curU) : ustep;
823 vertices[0].u = curU;
825 vertices[0].x = curX;
832 vertices[1].u = curU;
834 vertices[1].x = curX;
835 vertices[1].y = (y +
height);
838 sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
843 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
849 Uint32 pixel_format,
void * pixels,
int pitch)
864 float centerx, centery;
873 u1 = srcrect->
x + srcrect->
w;
874 v1 = srcrect->
y + srcrect->
h;
881 StartDrawing(renderer);
882 TextureActivate(texture);
883 PSP_SetBlendMode(renderer, renderer->
blendMode);
887 sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
888 sceGuColor(GU_RGBA(255, 255, 255, alpha));
890 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
891 sceGuColor(0xFFFFFFFF);
901 MathSincos(degToRad(angle), &s, &c);
914 VertTV* vertices = (VertTV*)sceGuGetMemory(
sizeof(VertTV)<<2);
918 vertices[0].x = x - cw + sh;
919 vertices[0].y = y - sw - ch;
924 vertices[1].x = x - cw - sh;
925 vertices[1].y = y - sw + ch;
930 vertices[2].x = x + cw - sh;
931 vertices[2].y = y + sw + ch;
936 vertices[3].x = x + cw + sh;
937 vertices[3].y = y + sw - ch;
941 Swap(&vertices[0].
v, &vertices[2].v);
942 Swap(&vertices[1].
v, &vertices[3].v);
945 Swap(&vertices[0].u, &vertices[2].u);
946 Swap(&vertices[1].u, &vertices[3].u);
949 sceGuDrawArray(GU_TRIANGLE_FAN, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 4, 0, vertices);
952 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
959 PSP_RenderData *data = (PSP_RenderData *) renderer->
driverdata;
960 if(!data->displayListAvail)
968 sceDisplayWaitVblankStart();
970 data->backbuffer = data->frontbuffer;
971 data->frontbuffer = vabsptr(sceGuSwapBuffers());
978 PSP_RenderData *renderdata = (PSP_RenderData *) renderer->
driverdata;
979 PSP_TextureData *psp_texture = (PSP_TextureData *) texture->
driverdata;
995 PSP_RenderData *data = (PSP_RenderData *) renderer->
driverdata;
997 if (!data->initialized)
1000 StartDrawing(renderer);
int(* RenderDrawLines)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
GLdouble GLdouble GLdouble r
int(* RenderDrawPoints)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
int(* RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
GLint GLint GLint GLint GLint x
GLuint GLuint GLsizei count
SDL_RenderDriver PSP_RenderDriver
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d ®2 endm macro vzip8 reg2 vzip d d ®2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld [DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp local skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
#define SDL_BYTESPERPIXEL(X)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
int(* RenderFillRects)(SDL_Renderer *renderer, const SDL_FRect *rects, int count)
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp
int(* RenderClear)(SDL_Renderer *renderer)
GLfloat GLfloat GLfloat alpha
void(* DestroyRenderer)(SDL_Renderer *renderer)
GLint GLint GLsizei width
GLfixed GLfixed GLint GLint GLfixed points
static SDL_BlendMode blendMode
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
int(* SetTextureColorMod)(SDL_Renderer *renderer, SDL_Texture *texture)
GLenum GLenum GLuint texture
int SDL_RecreateWindow(SDL_Window *window, Uint32 flags)
static SDL_Renderer * renderer
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)
GLubyte GLubyte GLubyte GLubyte w
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
SDL_Renderer *(* CreateRenderer)(SDL_Window *window, Uint32 flags)
GLint GLint GLint GLint GLint GLint y
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* UpdateViewport)(SDL_Renderer *renderer)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
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)
int(* RenderCopy)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
Window state change event data (event.window.*)
#define SDL_OutOfMemory()
GLint GLint GLsizei GLsizei height
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)
EGLSurface EGLNativeWindowType * window
The type used to identify a window.
#define SDL_GetWindowPixelFormat
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
void(* RenderPresent)(SDL_Renderer *renderer)
EGLSurface EGLint * rects
GLuint GLsizei GLsizei * length
GLboolean GLboolean GLboolean GLboolean a
GLboolean GLboolean GLboolean b
#define SDL_Unsupported()
A rectangle, with the origin at the upper left.