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)
194 if (!hint || *hint ==
'0' ||
SDL_strcasecmp(hint,
"nearest") == 0) {
222 if(data->displayListAvail)
225 sceGuStart(GU_DIRECT, DisplayList);
231 TextureSwizzle(PSP_TextureData *psp_texture)
233 if(psp_texture->swizzled)
236 int bytewidth = psp_texture->textureWidth*(psp_texture->bits>>3);
237 int height = psp_texture->size / bytewidth;
239 int rowblocks = (bytewidth>>4);
240 int rowblocksadd = (rowblocks-1)<<7;
241 unsigned int blockaddress = 0;
242 unsigned int *
src = (
unsigned int*) psp_texture->data;
249 for(j = 0; j <
height; j++, blockaddress += 16)
253 block = (
unsigned int*)&
data[blockaddress];
257 for(i = 0; i < rowblocks; i++)
267 blockaddress += rowblocksadd;
270 free(psp_texture->data);
271 psp_texture->data =
data;
276 int TextureUnswizzle(PSP_TextureData *psp_texture)
278 if(!psp_texture->swizzled)
283 int bytewidth = psp_texture->textureWidth*(psp_texture->bits>>3);
284 int height = psp_texture->size / bytewidth;
286 int widthblocks = bytewidth/16;
287 int heightblocks = height/8;
289 int dstpitch = (bytewidth - 16)/4;
290 int dstrow = bytewidth * 8;
292 unsigned int *src = (
unsigned int*) psp_texture->data;
301 sceKernelDcacheWritebackAll();
305 unsigned char *ydst = (
unsigned char *)
data;
307 for(blocky = 0; blocky < heightblocks; ++blocky)
309 unsigned char *xdst = ydst;
311 for(blockx = 0; blockx < widthblocks; ++blockx)
315 block = (
unsigned int*)xdst;
317 for(j = 0; j < 8; ++
j)
319 *(block++) = *(src++);
320 *(block++) = *(src++);
321 *(block++) = *(src++);
322 *(block++) = *(src++);
332 free(psp_texture->data);
334 psp_texture->data =
data;
346 PSP_RenderData *
data;
354 data = (PSP_RenderData *)
SDL_calloc(1,
sizeof(*data));
356 PSP_DestroyRenderer(renderer);
380 renderer->
info = PSP_RenderDriver.
info;
401 data->frontbuffer = (
unsigned int *)(PSP_FRAME_BUFFER_SIZE<<1);
402 data->backbuffer = (
unsigned int *)(0);
404 data->psm = pixelformat;
407 data->frontbuffer = (
unsigned int *)(PSP_FRAME_BUFFER_SIZE<<2);
408 data->backbuffer = (
unsigned int *)(0);
410 data->psm = GU_PSM_8888;
416 sceGuStart(GU_DIRECT, DisplayList);
417 sceGuDrawBuffer(data->psm, data->frontbuffer, PSP_FRAME_BUFFER_WIDTH);
418 sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, data->backbuffer, PSP_FRAME_BUFFER_WIDTH);
421 sceGuOffset(2048 - (PSP_SCREEN_WIDTH>>1), 2048 - (PSP_SCREEN_HEIGHT>>1));
422 sceGuViewport(2048, 2048, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
424 data->frontbuffer = vabsptr(data->frontbuffer);
425 data->backbuffer = vabsptr(data->backbuffer);
428 sceGuScissor(0, 0, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
429 sceGuEnable(GU_SCISSOR_TEST);
432 sceGuFrontFace(GU_CCW);
433 sceGuEnable(GU_CULL_FACE);
436 sceGuEnable(GU_TEXTURE_2D);
437 sceGuShadeModel(GU_SMOOTH);
438 sceGuTexWrap(GU_REPEAT, GU_REPEAT);
441 sceGuEnable(GU_BLEND);
442 sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
444 sceGuTexFilter(GU_LINEAR,GU_LINEAR);
448 sceDisplayWaitVblankStartCB();
449 sceGuDisplay(GU_TRUE);
465 PSP_TextureData* psp_texture = (PSP_TextureData*)
SDL_calloc(1,
sizeof(*psp_texture));
471 psp_texture->width = texture->
w;
472 psp_texture->height = texture->
h;
473 psp_texture->textureHeight = TextureNextPow2(texture->
h);
474 psp_texture->textureWidth = TextureNextPow2(texture->
w);
475 psp_texture->format = PixelFormatToPSPFMT(texture->
format);
477 switch(psp_texture->format)
482 psp_texture->bits = 16;
486 psp_texture->bits = 32;
494 psp_texture->size = psp_texture->textureHeight*psp_texture->pitch;
495 psp_texture->data =
SDL_calloc(1, psp_texture->size);
497 if(!psp_texture->data)
516 PSP_TextureData *psp_texture = (PSP_TextureData *) texture->
driverdata;
520 if (texture->
w >= 16 || texture->
h >= 16)
522 TextureSwizzle(psp_texture);
525 sceGuEnable(GU_TEXTURE_2D);
526 sceGuTexWrap(GU_REPEAT, GU_REPEAT);
527 sceGuTexMode(psp_texture->format, 0, 0, psp_texture->swizzled);
528 sceGuTexFilter(scaleMode, scaleMode);
530 sceGuTexImage(0, psp_texture->textureWidth, psp_texture->textureHeight, psp_texture->textureWidth, psp_texture->data);
531 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
545 PSP_LockTexture(renderer, texture,rect,(
void **)&dst, &dpitch);
547 if (length == pitch && length == dpitch) {
550 for (row = 0; row < rect->
h; ++
row) {
557 sceKernelDcacheWritebackAll();
563 const SDL_Rect * rect,
void **pixels,
int *pitch)
565 PSP_TextureData *psp_texture = (PSP_TextureData *) texture->
driverdata;
568 (
void *) ((
Uint8 *) psp_texture->data + rect->
y * psp_texture->pitch +
570 *pitch = psp_texture->pitch;
577 PSP_TextureData *psp_texture = (PSP_TextureData *) texture->
driverdata;
585 PSP_UpdateTexture(renderer, texture, &rect, psp_texture->data, psp_texture->pitch);
606 PSP_RenderData *data = (PSP_RenderData *) renderer->
driverdata;
607 if (blendMode != data-> currentBlendMode) {
610 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
611 sceGuDisable(GU_BLEND);
614 sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
615 sceGuEnable(GU_BLEND);
616 sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0 );
619 sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
620 sceGuEnable(GU_BLEND);
621 sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_FIX, 0, 0x00FFFFFF );
624 sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
625 sceGuEnable(GU_BLEND);
626 sceGuBlendFunc( GU_ADD, GU_FIX, GU_SRC_COLOR, 0, 0);
639 StartDrawing(renderer);
640 int color = renderer->
a << 24 | renderer->
b << 16 | renderer->
g << 8 | renderer->
r;
641 sceGuClearColor(color);
643 sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT|GU_FAST_CLEAR_BIT);
652 int color = renderer->
a << 24 | renderer->
b << 16 | renderer->
g << 8 | renderer->
r;
654 StartDrawing(renderer);
655 VertV* vertices = (VertV*)sceGuGetMemory(count*
sizeof(VertV));
657 for (i = 0; i <
count; ++
i) {
658 vertices[
i].x = points[
i].
x;
659 vertices[
i].y = points[
i].
y;
660 vertices[
i].z = 0.0f;
662 sceGuDisable(GU_TEXTURE_2D);
664 sceGuShadeModel(GU_FLAT);
665 sceGuDrawArray(GU_POINTS, GU_VERTEX_32BITF|GU_TRANSFORM_2D, count, 0, vertices);
666 sceGuShadeModel(GU_SMOOTH);
667 sceGuEnable(GU_TEXTURE_2D);
676 int color = renderer->
a << 24 | renderer->
b << 16 | renderer->
g << 8 | renderer->
r;
678 StartDrawing(renderer);
679 VertV* vertices = (VertV*)sceGuGetMemory(count*
sizeof(VertV));
681 for (i = 0; i <
count; ++
i) {
682 vertices[
i].x = points[
i].
x;
683 vertices[
i].y = points[
i].
y;
684 vertices[
i].z = 0.0f;
687 sceGuDisable(GU_TEXTURE_2D);
689 sceGuShadeModel(GU_FLAT);
690 sceGuDrawArray(GU_LINE_STRIP, GU_VERTEX_32BITF|GU_TRANSFORM_2D, count, 0, vertices);
691 sceGuShadeModel(GU_SMOOTH);
692 sceGuEnable(GU_TEXTURE_2D);
701 int color = renderer->
a << 24 | renderer->
b << 16 | renderer->
g << 8 | renderer->
r;
703 StartDrawing(renderer);
705 for (i = 0; i <
count; ++
i) {
707 VertV* vertices = (VertV*)sceGuGetMemory((
sizeof(VertV)<<1));
708 vertices[0].
x = rect->
x;
709 vertices[0].y = rect->
y;
710 vertices[0].z = 0.0f;
712 vertices[1].x = rect->
x + rect->
w;
713 vertices[1].y = rect->
y + rect->
h;
714 vertices[1].z = 0.0f;
716 sceGuDisable(GU_TEXTURE_2D);
718 sceGuShadeModel(GU_FLAT);
719 sceGuDrawArray(GU_SPRITES, GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
720 sceGuShadeModel(GU_SMOOTH);
721 sceGuEnable(GU_TEXTURE_2D);
728 #define PI 3.14159265358979f 730 #define radToDeg(x) ((x)*180.f/PI) 731 #define degToRad(x) ((x)*PI/180.f) 733 float MathAbs(
float x)
739 "vabs.s S000, S000\n" 746 void MathSincos(
float r,
float *
s,
float *
c)
750 "vcst.s S003, VFPU_2_PI\n" 751 "vmul.s S002, S002, S003\n" 752 "vrot.p C000, S002, [s, c]\n" 755 :
"=r"(*s),
"=r"(*c):
"r"(
r));
758 void Swap(
float *
a,
float *
b)
780 u1 = srcrect->
x + srcrect->
w;
781 v1 = srcrect->
y + srcrect->
h;
785 StartDrawing(renderer);
786 TextureActivate(texture);
787 PSP_SetBlendMode(renderer, renderer->
blendMode);
791 sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
792 sceGuColor(GU_RGBA(255, 255, 255, alpha));
794 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
795 sceGuColor(0xFFFFFFFF);
798 if((MathAbs(u1) - MathAbs(u0)) < 64.0
f)
800 VertTV* vertices = (VertTV*)sceGuGetMemory((
sizeof(VertTV))<<1);
810 vertices[1].x = x +
width;
811 vertices[1].y = y +
height;
814 sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
821 float endX = x +
width;
823 float ustep = (u1 - u0)/width * slice;
828 for(start = 0, end = width; start <
end; start += slice)
830 VertTV* vertices = (VertTV*)sceGuGetMemory((
sizeof(VertTV))<<1);
832 float polyWidth = ((curX + slice) > endX) ? (endX - curX) : slice;
833 float sourceWidth = ((curU + ustep) > u1) ? (u1 - curU) : ustep;
835 vertices[0].u = curU;
837 vertices[0].x = curX;
844 vertices[1].u = curU;
846 vertices[1].x = curX;
847 vertices[1].y = (y +
height);
850 sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
855 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
876 float centerx, centery;
885 u1 = srcrect->
x + srcrect->
w;
886 v1 = srcrect->
y + srcrect->
h;
893 StartDrawing(renderer);
894 TextureActivate(texture);
895 PSP_SetBlendMode(renderer, renderer->
blendMode);
899 sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
900 sceGuColor(GU_RGBA(255, 255, 255, alpha));
902 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
903 sceGuColor(0xFFFFFFFF);
913 MathSincos(degToRad(angle), &s, &c);
926 VertTV* vertices = (VertTV*)sceGuGetMemory(
sizeof(VertTV)<<2);
930 vertices[0].x = x - cw + sh;
931 vertices[0].y = y - sw - ch;
936 vertices[1].x = x - cw - sh;
937 vertices[1].y = y - sw + ch;
942 vertices[2].x = x + cw - sh;
943 vertices[2].y = y + sw + ch;
948 vertices[3].x = x + cw + sh;
949 vertices[3].y = y + sw - ch;
953 Swap(&vertices[0].
v, &vertices[2].v);
954 Swap(&vertices[1].
v, &vertices[3].v);
957 Swap(&vertices[0].u, &vertices[2].u);
958 Swap(&vertices[1].u, &vertices[3].u);
961 sceGuDrawArray(GU_TRIANGLE_FAN, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 4, 0, vertices);
964 sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
971 PSP_RenderData *data = (PSP_RenderData *) renderer->
driverdata;
972 if(!data->displayListAvail)
980 sceDisplayWaitVblankStart();
982 data->backbuffer = data->frontbuffer;
983 data->frontbuffer = vabsptr(sceGuSwapBuffers());
990 PSP_RenderData *renderdata = (PSP_RenderData *) renderer->
driverdata;
991 PSP_TextureData *psp_texture = (PSP_TextureData *) texture->
driverdata;
1007 PSP_RenderData *data = (PSP_RenderData *) renderer->
driverdata;
1009 if (!data->initialized)
1012 StartDrawing(renderer);
int(* RenderDrawLines)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
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)
GLdouble GLdouble GLdouble r
GLint GLint GLsizei width
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
#define SDL_HINT_RENDER_SCALE_QUALITY
A variable controlling the scaling quality.
static SDL_Window * window
GLenum GLenum GLuint texture
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
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)
int(* RenderFillRects)(SDL_Renderer *renderer, const SDL_FRect *rects, int count)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
uint32_t Uint32
An unsigned 32-bit integer type.
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
GLint GLint GLsizei GLsizei height
int(* RenderClear)(SDL_Renderer *renderer)
GLfloat GLfloat GLfloat alpha
void(* DestroyRenderer)(SDL_Renderer *renderer)
GLfixed GLfixed GLint GLint GLfixed points
static SDL_BlendMode blendMode
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)
void * SDL_calloc(size_t nmemb, size_t size)
GLint GLint GLint GLint GLint GLint y
int SDL_RecreateWindow(SDL_Window *window, Uint32 flags)
static int GetScaleQuality(void)
static SDL_Renderer * renderer
uint8_t Uint8
An unsigned 8-bit integer type.
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)
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
SDL_Renderer *(* CreateRenderer)(SDL_Window *window, Uint32 flags)
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* UpdateViewport)(SDL_Renderer *renderer)
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()
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)
The type used to identify a window.
SDL_Rect rects[MAX_RECTS]
#define SDL_GetWindowPixelFormat
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
GLubyte GLubyte GLubyte GLubyte w
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
void(* RenderPresent)(SDL_Renderer *renderer)
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.