SDL  2.0
SDL_render_psp.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../../SDL_internal.h"
22 
23 #if SDL_VIDEO_RENDER_PSP
24 
25 #include "SDL_hints.h"
26 #include "../SDL_sysrender.h"
27 
28 #include <pspkernel.h>
29 #include <pspdisplay.h>
30 #include <pspgu.h>
31 #include <pspgum.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <math.h>
35 #include <pspge.h>
36 #include <stdarg.h>
37 #include <stdlib.h>
38 #include <vram.h>
39 
40 
41 
42 
43 /* PSP renderer implementation, based on the PGE */
44 
45 
47 
48 
49 static SDL_Renderer *PSP_CreateRenderer(SDL_Window * window, Uint32 flags);
50 static void PSP_WindowEvent(SDL_Renderer * renderer,
51  const SDL_WindowEvent *event);
52 static int PSP_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
53 static int PSP_SetTextureColorMod(SDL_Renderer * renderer,
55 static int PSP_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
56  const SDL_Rect * rect, const void *pixels,
57  int pitch);
58 static int PSP_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
59  const SDL_Rect * rect, void **pixels, int *pitch);
60 static void PSP_UnlockTexture(SDL_Renderer * renderer,
62 static int PSP_SetRenderTarget(SDL_Renderer * renderer,
64 static int PSP_UpdateViewport(SDL_Renderer * renderer);
65 static int PSP_RenderClear(SDL_Renderer * renderer);
66 static int PSP_RenderDrawPoints(SDL_Renderer * renderer,
67  const SDL_FPoint * points, int count);
68 static int PSP_RenderDrawLines(SDL_Renderer * renderer,
69  const SDL_FPoint * points, int count);
70 static int PSP_RenderFillRects(SDL_Renderer * renderer,
71  const SDL_FRect * rects, int count);
72 static int PSP_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
73  const SDL_Rect * srcrect,
74  const SDL_FRect * dstrect);
75 static int PSP_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
76  Uint32 pixel_format, void * pixels, int pitch);
77 static int PSP_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
78  const SDL_Rect * srcrect, const SDL_FRect * dstrect,
79  const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip);
80 static void PSP_RenderPresent(SDL_Renderer * renderer);
81 static void PSP_DestroyTexture(SDL_Renderer * renderer,
83 static void PSP_DestroyRenderer(SDL_Renderer * renderer);
84 
85 /*
86 SDL_RenderDriver PSP_RenderDriver = {
87  PSP_CreateRenderer,
88  {
89  "PSP",
90  (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE),
91  1,
92  {SDL_PIXELFORMAT_ABGR8888},
93  0,
94  0}
95 };
96 */
98  .CreateRenderer = PSP_CreateRenderer,
99  .info = {
100  .name = "PSP",
102  .num_texture_formats = 4,
103  .texture_formats = { [0] = SDL_PIXELFORMAT_BGR565,
107  },
108  .max_texture_width = 512,
109  .max_texture_height = 512,
110  }
111 };
112 
113 #define PSP_SCREEN_WIDTH 480
114 #define PSP_SCREEN_HEIGHT 272
115 
116 #define PSP_FRAME_BUFFER_WIDTH 512
117 #define PSP_FRAME_BUFFER_SIZE (PSP_FRAME_BUFFER_WIDTH*PSP_SCREEN_HEIGHT)
118 
119 static unsigned int __attribute__((aligned(16))) DisplayList[262144];
120 
121 
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))
126 
127 
128 typedef struct
129 {
130  void* frontbuffer ;
131  void* backbuffer ;
132  SDL_bool initialized ;
133  SDL_bool displayListAvail ;
134  unsigned int psm ;
135  unsigned int bpp ;
136 
137  SDL_bool vsync;
138  unsigned int currentColor;
139  int currentBlendMode;
140 
141 } PSP_RenderData;
142 
143 
144 typedef struct
145 {
146  void *data; /**< Image data. */
147  unsigned int size; /**< Size of data in bytes. */
148  unsigned int width; /**< Image width. */
149  unsigned int height; /**< Image height. */
150  unsigned int textureWidth; /**< Texture width (power of two). */
151  unsigned int textureHeight; /**< Texture height (power of two). */
152  unsigned int bits; /**< Image bits per pixel. */
153  unsigned int format; /**< Image format - one of ::pgePixelFormat. */
154  unsigned int pitch;
155  SDL_bool swizzled; /**< Is image swizzled. */
156 
157 } PSP_TextureData;
158 
159 typedef struct
160 {
161  float x, y, z;
162 } VertV;
163 
164 
165 typedef struct
166 {
167  float u, v;
168  float x, y, z;
169 
170 } VertTV;
171 
172 
173 /* Return next power of 2 */
174 static int
175 TextureNextPow2(unsigned int w)
176 {
177  if(w == 0)
178  return 0;
179 
180  unsigned int n = 2;
181 
182  while(w > n)
183  n <<= 1;
184 
185  return n;
186 }
187 
188 
189 static int
190 PixelFormatToPSPFMT(Uint32 format)
191 {
192  switch (format) {
194  return GU_PSM_5650;
196  return GU_PSM_5551;
198  return GU_PSM_4444;
200  return GU_PSM_8888;
201  default:
202  return GU_PSM_8888;
203  }
204 }
205 
206 void
207 StartDrawing(SDL_Renderer * renderer)
208 {
209  PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata;
210  if(data->displayListAvail)
211  return;
212 
213  sceGuStart(GU_DIRECT, DisplayList);
214  data->displayListAvail = SDL_TRUE;
215 }
216 
217 
218 int
219 TextureSwizzle(PSP_TextureData *psp_texture)
220 {
221  if(psp_texture->swizzled)
222  return 1;
223 
224  int bytewidth = psp_texture->textureWidth*(psp_texture->bits>>3);
225  int height = psp_texture->size / bytewidth;
226 
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;
231 
232  unsigned char *data = NULL;
233  data = malloc(psp_texture->size);
234 
235  int j;
236 
237  for(j = 0; j < height; j++, blockaddress += 16)
238  {
239  unsigned int *block;
240 
241  block = (unsigned int*)&data[blockaddress];
242 
243  int i;
244 
245  for(i = 0; i < rowblocks; i++)
246  {
247  *block++ = *src++;
248  *block++ = *src++;
249  *block++ = *src++;
250  *block++ = *src++;
251  block += 28;
252  }
253 
254  if((j & 0x7) == 0x7)
255  blockaddress += rowblocksadd;
256  }
257 
258  free(psp_texture->data);
259  psp_texture->data = data;
260  psp_texture->swizzled = SDL_TRUE;
261 
262  return 1;
263 }
264 int TextureUnswizzle(PSP_TextureData *psp_texture)
265 {
266  if(!psp_texture->swizzled)
267  return 1;
268 
269  int blockx, blocky;
270 
271  int bytewidth = psp_texture->textureWidth*(psp_texture->bits>>3);
272  int height = psp_texture->size / bytewidth;
273 
274  int widthblocks = bytewidth/16;
275  int heightblocks = height/8;
276 
277  int dstpitch = (bytewidth - 16)/4;
278  int dstrow = bytewidth * 8;
279 
280  unsigned int *src = (unsigned int*) psp_texture->data;
281 
282  unsigned char *data = NULL;
283 
284  data = malloc(psp_texture->size);
285 
286  if(!data)
287  return 0;
288 
289  sceKernelDcacheWritebackAll();
290 
291  int j;
292 
293  unsigned char *ydst = (unsigned char *)data;
294 
295  for(blocky = 0; blocky < heightblocks; ++blocky)
296  {
297  unsigned char *xdst = ydst;
298 
299  for(blockx = 0; blockx < widthblocks; ++blockx)
300  {
301  unsigned int *block;
302 
303  block = (unsigned int*)xdst;
304 
305  for(j = 0; j < 8; ++j)
306  {
307  *(block++) = *(src++);
308  *(block++) = *(src++);
309  *(block++) = *(src++);
310  *(block++) = *(src++);
311  block += dstpitch;
312  }
313 
314  xdst += 16;
315  }
316 
317  ydst += dstrow;
318  }
319 
320  free(psp_texture->data);
321 
322  psp_texture->data = data;
323 
324  psp_texture->swizzled = SDL_FALSE;
325 
326  return 1;
327 }
328 
329 SDL_Renderer *
330 PSP_CreateRenderer(SDL_Window * window, Uint32 flags)
331 {
332 
334  PSP_RenderData *data;
335  int pixelformat;
336  renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
337  if (!renderer) {
338  SDL_OutOfMemory();
339  return NULL;
340  }
341 
342  data = (PSP_RenderData *) SDL_calloc(1, sizeof(*data));
343  if (!data) {
344  PSP_DestroyRenderer(renderer);
345  SDL_OutOfMemory();
346  return NULL;
347  }
348 
349 
350  renderer->WindowEvent = PSP_WindowEvent;
351  renderer->CreateTexture = PSP_CreateTexture;
352  renderer->SetTextureColorMod = PSP_SetTextureColorMod;
353  renderer->UpdateTexture = PSP_UpdateTexture;
354  renderer->LockTexture = PSP_LockTexture;
355  renderer->UnlockTexture = PSP_UnlockTexture;
356  renderer->SetRenderTarget = PSP_SetRenderTarget;
357  renderer->UpdateViewport = PSP_UpdateViewport;
358  renderer->RenderClear = PSP_RenderClear;
359  renderer->RenderDrawPoints = PSP_RenderDrawPoints;
360  renderer->RenderDrawLines = PSP_RenderDrawLines;
361  renderer->RenderFillRects = PSP_RenderFillRects;
362  renderer->RenderCopy = PSP_RenderCopy;
363  renderer->RenderReadPixels = PSP_RenderReadPixels;
364  renderer->RenderCopyEx = PSP_RenderCopyEx;
365  renderer->RenderPresent = PSP_RenderPresent;
366  renderer->DestroyTexture = PSP_DestroyTexture;
367  renderer->DestroyRenderer = PSP_DestroyRenderer;
372 
373  if (data->initialized != SDL_FALSE)
374  return 0;
375  data->initialized = SDL_TRUE;
376 
378  data->vsync = SDL_TRUE;
379  } else {
380  data->vsync = SDL_FALSE;
381  }
382 
383  pixelformat=PixelFormatToPSPFMT(SDL_GetWindowPixelFormat(window));
384  switch(pixelformat)
385  {
386  case GU_PSM_4444:
387  case GU_PSM_5650:
388  case GU_PSM_5551:
389  data->frontbuffer = (unsigned int *)(PSP_FRAME_BUFFER_SIZE<<1);
390  data->backbuffer = (unsigned int *)(0);
391  data->bpp = 2;
392  data->psm = pixelformat;
393  break;
394  default:
395  data->frontbuffer = (unsigned int *)(PSP_FRAME_BUFFER_SIZE<<2);
396  data->backbuffer = (unsigned int *)(0);
397  data->bpp = 4;
398  data->psm = GU_PSM_8888;
399  break;
400  }
401 
402  sceGuInit();
403  /* setup GU */
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);
407 
408 
409  sceGuOffset(2048 - (PSP_SCREEN_WIDTH>>1), 2048 - (PSP_SCREEN_HEIGHT>>1));
410  sceGuViewport(2048, 2048, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
411 
412  data->frontbuffer = vabsptr(data->frontbuffer);
413  data->backbuffer = vabsptr(data->backbuffer);
414 
415  /* Scissoring */
416  sceGuScissor(0, 0, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
417  sceGuEnable(GU_SCISSOR_TEST);
418 
419  /* Backface culling */
420  sceGuFrontFace(GU_CCW);
421  sceGuEnable(GU_CULL_FACE);
422 
423  /* Texturing */
424  sceGuEnable(GU_TEXTURE_2D);
425  sceGuShadeModel(GU_SMOOTH);
426  sceGuTexWrap(GU_REPEAT, GU_REPEAT);
427 
428  /* Blending */
429  sceGuEnable(GU_BLEND);
430  sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
431 
432  sceGuTexFilter(GU_LINEAR,GU_LINEAR);
433 
434  sceGuFinish();
435  sceGuSync(0,0);
436  sceDisplayWaitVblankStartCB();
437  sceGuDisplay(GU_TRUE);
438 
439  return renderer;
440 }
441 
442 static void
443 PSP_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
444 {
445 
446 }
447 
448 
449 static int
450 PSP_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
451 {
452 /* PSP_RenderData *renderdata = (PSP_RenderData *) renderer->driverdata; */
453  PSP_TextureData* psp_texture = (PSP_TextureData*) SDL_calloc(1, sizeof(*psp_texture));
454 
455  if(!psp_texture)
456  return -1;
457 
458  psp_texture->swizzled = SDL_FALSE;
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);
464 
465  switch(psp_texture->format)
466  {
467  case GU_PSM_5650:
468  case GU_PSM_5551:
469  case GU_PSM_4444:
470  psp_texture->bits = 16;
471  break;
472 
473  case GU_PSM_8888:
474  psp_texture->bits = 32;
475  break;
476 
477  default:
478  return -1;
479  }
480 
481  psp_texture->pitch = psp_texture->textureWidth * SDL_BYTESPERPIXEL(texture->format);
482  psp_texture->size = psp_texture->textureHeight*psp_texture->pitch;
483  psp_texture->data = SDL_calloc(1, psp_texture->size);
484 
485  if(!psp_texture->data)
486  {
487  SDL_free(psp_texture);
488  return SDL_OutOfMemory();
489  }
490  texture->driverdata = psp_texture;
491 
492  return 0;
493 }
494 
495 static int
496 PSP_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture)
497 {
498  return SDL_Unsupported();
499 }
500 
501 void
502 TextureActivate(SDL_Texture * texture)
503 {
504  PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata;
505  int scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? GU_NEAREST : GU_LINEAR;
506 
507  /* Swizzling is useless with small textures. */
508  if (texture->w >= 16 || texture->h >= 16)
509  {
510  TextureSwizzle(psp_texture);
511  }
512 
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); /* GU_NEAREST good for tile-map */
517  /* GU_LINEAR good for scaling */
518  sceGuTexImage(0, psp_texture->textureWidth, psp_texture->textureHeight, psp_texture->textureWidth, psp_texture->data);
519  sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
520 }
521 
522 
523 static int
524 PSP_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
525  const SDL_Rect * rect, const void *pixels, int pitch)
526 {
527 /* PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata; */
528  const Uint8 *src;
529  Uint8 *dst;
530  int row, length,dpitch;
531  src = pixels;
532 
533  PSP_LockTexture(renderer, texture,rect,(void **)&dst, &dpitch);
534  length = rect->w * SDL_BYTESPERPIXEL(texture->format);
535  if (length == pitch && length == dpitch) {
537  } else {
538  for (row = 0; row < rect->h; ++row) {
540  src += pitch;
541  dst += dpitch;
542  }
543  }
544 
545  sceKernelDcacheWritebackAll();
546  return 0;
547 }
548 
549 static int
550 PSP_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
551  const SDL_Rect * rect, void **pixels, int *pitch)
552 {
553  PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata;
554 
555  *pixels =
556  (void *) ((Uint8 *) psp_texture->data + rect->y * psp_texture->pitch +
557  rect->x * SDL_BYTESPERPIXEL(texture->format));
558  *pitch = psp_texture->pitch;
559  return 0;
560 }
561 
562 static void
563 PSP_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
564 {
565  PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata;
566  SDL_Rect rect;
567 
568  /* We do whole texture updates, at least for now */
569  rect.x = 0;
570  rect.y = 0;
571  rect.w = texture->w;
572  rect.h = texture->h;
573  PSP_UpdateTexture(renderer, texture, &rect, psp_texture->data, psp_texture->pitch);
574 }
575 
576 static int
577 PSP_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
578 {
579 
580  return 0;
581 }
582 
583 static int
584 PSP_UpdateViewport(SDL_Renderer * renderer)
585 {
586 
587  return 0;
588 }
589 
590 
591 static void
592 PSP_SetBlendMode(SDL_Renderer * renderer, int blendMode)
593 {
594  PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata;
595  if (blendMode != data-> currentBlendMode) {
596  switch (blendMode) {
597  case SDL_BLENDMODE_NONE:
598  sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
599  sceGuDisable(GU_BLEND);
600  break;
601  case SDL_BLENDMODE_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 );
605  break;
606  case SDL_BLENDMODE_ADD:
607  sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
608  sceGuEnable(GU_BLEND);
609  sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_FIX, 0, 0x00FFFFFF );
610  break;
611  case SDL_BLENDMODE_MOD:
612  sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
613  sceGuEnable(GU_BLEND);
614  sceGuBlendFunc( GU_ADD, GU_FIX, GU_SRC_COLOR, 0, 0);
615  break;
616  }
617  data->currentBlendMode = blendMode;
618  }
619 }
620 
621 
622 
623 static int
624 PSP_RenderClear(SDL_Renderer * renderer)
625 {
626  /* start list */
627  StartDrawing(renderer);
628  int color = renderer->a << 24 | renderer->b << 16 | renderer->g << 8 | renderer->r;
629  sceGuClearColor(color);
630  sceGuClearDepth(0);
631  sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT|GU_FAST_CLEAR_BIT);
632 
633  return 0;
634 }
635 
636 static int
637 PSP_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points,
638  int count)
639 {
640  int color = renderer->a << 24 | renderer->b << 16 | renderer->g << 8 | renderer->r;
641  int i;
642  StartDrawing(renderer);
643  VertV* vertices = (VertV*)sceGuGetMemory(count*sizeof(VertV));
644 
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;
649  }
650  sceGuDisable(GU_TEXTURE_2D);
651  sceGuColor(color);
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);
656 
657  return 0;
658 }
659 
660 static int
661 PSP_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points,
662  int count)
663 {
664  int color = renderer->a << 24 | renderer->b << 16 | renderer->g << 8 | renderer->r;
665  int i;
666  StartDrawing(renderer);
667  VertV* vertices = (VertV*)sceGuGetMemory(count*sizeof(VertV));
668 
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;
673  }
674 
675  sceGuDisable(GU_TEXTURE_2D);
676  sceGuColor(color);
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);
681 
682  return 0;
683 }
684 
685 static int
686 PSP_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects,
687  int count)
688 {
689  int color = renderer->a << 24 | renderer->b << 16 | renderer->g << 8 | renderer->r;
690  int i;
691  StartDrawing(renderer);
692 
693  for (i = 0; i < count; ++i) {
694  const SDL_FRect *rect = &rects[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;
699 
700  vertices[1].x = rect->x + rect->w;
701  vertices[1].y = rect->y + rect->h;
702  vertices[1].z = 0.0f;
703 
704  sceGuDisable(GU_TEXTURE_2D);
705  sceGuColor(color);
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);
710  }
711 
712  return 0;
713 }
714 
715 
716 #define PI 3.14159265358979f
717 
718 #define radToDeg(x) ((x)*180.f/PI)
719 #define degToRad(x) ((x)*PI/180.f)
720 
721 float MathAbs(float x)
722 {
723  float result;
724 
725  __asm__ volatile (
726  "mtv %1, S000\n"
727  "vabs.s S000, S000\n"
728  "mfv %0, S000\n"
729  : "=r"(result) : "r"(x));
730 
731  return result;
732 }
733 
734 void MathSincos(float r, float *s, float *c)
735 {
736  __asm__ volatile (
737  "mtv %2, S002\n"
738  "vcst.s S003, VFPU_2_PI\n"
739  "vmul.s S002, S002, S003\n"
740  "vrot.p C000, S002, [s, c]\n"
741  "mfv %0, S000\n"
742  "mfv %1, S001\n"
743  : "=r"(*s), "=r"(*c): "r"(r));
744 }
745 
746 void Swap(float *a, float *b)
747 {
748  float n=*a;
749  *a = *b;
750  *b = n;
751 }
752 
753 static int
754 PSP_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
755  const SDL_Rect * srcrect, const SDL_FRect * dstrect)
756 {
757  float x, y, width, height;
758  float u0, v0, u1, v1;
759  unsigned char alpha;
760 
761  x = dstrect->x;
762  y = dstrect->y;
763  width = dstrect->w;
764  height = dstrect->h;
765 
766  u0 = srcrect->x;
767  v0 = srcrect->y;
768  u1 = srcrect->x + srcrect->w;
769  v1 = srcrect->y + srcrect->h;
770 
771  alpha = texture->a;
772 
773  StartDrawing(renderer);
774  TextureActivate(texture);
775  PSP_SetBlendMode(renderer, renderer->blendMode);
776 
777  if(alpha != 255)
778  {
779  sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
780  sceGuColor(GU_RGBA(255, 255, 255, alpha));
781  }else{
782  sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
783  sceGuColor(0xFFFFFFFF);
784  }
785 
786  if((MathAbs(u1) - MathAbs(u0)) < 64.0f)
787  {
788  VertTV* vertices = (VertTV*)sceGuGetMemory((sizeof(VertTV))<<1);
789 
790  vertices[0].u = u0;
791  vertices[0].v = v0;
792  vertices[0].x = x;
793  vertices[0].y = y;
794  vertices[0].z = 0;
795 
796  vertices[1].u = u1;
797  vertices[1].v = v1;
798  vertices[1].x = x + width;
799  vertices[1].y = y + height;
800  vertices[1].z = 0;
801 
802  sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
803  }
804  else
805  {
806  float start, end;
807  float curU = u0;
808  float curX = x;
809  float endX = x + width;
810  float slice = 64.0f;
811  float ustep = (u1 - u0)/width * slice;
812 
813  if(ustep < 0.0f)
814  ustep = -ustep;
815 
816  for(start = 0, end = width; start < end; start += slice)
817  {
818  VertTV* vertices = (VertTV*)sceGuGetMemory((sizeof(VertTV))<<1);
819 
820  float polyWidth = ((curX + slice) > endX) ? (endX - curX) : slice;
821  float sourceWidth = ((curU + ustep) > u1) ? (u1 - curU) : ustep;
822 
823  vertices[0].u = curU;
824  vertices[0].v = v0;
825  vertices[0].x = curX;
826  vertices[0].y = y;
827  vertices[0].z = 0;
828 
829  curU += sourceWidth;
830  curX += polyWidth;
831 
832  vertices[1].u = curU;
833  vertices[1].v = v1;
834  vertices[1].x = curX;
835  vertices[1].y = (y + height);
836  vertices[1].z = 0;
837 
838  sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
839  }
840  }
841 
842  if(alpha != 255)
843  sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
844  return 0;
845 }
846 
847 static int
848 PSP_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
849  Uint32 pixel_format, void * pixels, int pitch)
850 
851 {
852  return SDL_Unsupported();
853 }
854 
855 
856 static int
857 PSP_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
858  const SDL_Rect * srcrect, const SDL_FRect * dstrect,
859  const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
860 {
861  float x, y, width, height;
862  float u0, v0, u1, v1;
863  unsigned char alpha;
864  float centerx, centery;
865 
866  x = dstrect->x;
867  y = dstrect->y;
868  width = dstrect->w;
869  height = dstrect->h;
870 
871  u0 = srcrect->x;
872  v0 = srcrect->y;
873  u1 = srcrect->x + srcrect->w;
874  v1 = srcrect->y + srcrect->h;
875 
876  centerx = center->x;
877  centery = center->y;
878 
879  alpha = texture->a;
880 
881  StartDrawing(renderer);
882  TextureActivate(texture);
883  PSP_SetBlendMode(renderer, renderer->blendMode);
884 
885  if(alpha != 255)
886  {
887  sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
888  sceGuColor(GU_RGBA(255, 255, 255, alpha));
889  }else{
890  sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
891  sceGuColor(0xFFFFFFFF);
892  }
893 
894 /* x += width * 0.5f; */
895 /* y += height * 0.5f; */
896  x += centerx;
897  y += centery;
898 
899  float c, s;
900 
901  MathSincos(degToRad(angle), &s, &c);
902 
903 /* width *= 0.5f; */
904 /* height *= 0.5f; */
905  width -= centerx;
906  height -= centery;
907 
908 
909  float cw = c*width;
910  float sw = s*width;
911  float ch = c*height;
912  float sh = s*height;
913 
914  VertTV* vertices = (VertTV*)sceGuGetMemory(sizeof(VertTV)<<2);
915 
916  vertices[0].u = u0;
917  vertices[0].v = v0;
918  vertices[0].x = x - cw + sh;
919  vertices[0].y = y - sw - ch;
920  vertices[0].z = 0;
921 
922  vertices[1].u = u0;
923  vertices[1].v = v1;
924  vertices[1].x = x - cw - sh;
925  vertices[1].y = y - sw + ch;
926  vertices[1].z = 0;
927 
928  vertices[2].u = u1;
929  vertices[2].v = v1;
930  vertices[2].x = x + cw - sh;
931  vertices[2].y = y + sw + ch;
932  vertices[2].z = 0;
933 
934  vertices[3].u = u1;
935  vertices[3].v = v0;
936  vertices[3].x = x + cw + sh;
937  vertices[3].y = y + sw - ch;
938  vertices[3].z = 0;
939 
940  if (flip & SDL_FLIP_VERTICAL) {
941  Swap(&vertices[0].v, &vertices[2].v);
942  Swap(&vertices[1].v, &vertices[3].v);
943  }
944  if (flip & SDL_FLIP_HORIZONTAL) {
945  Swap(&vertices[0].u, &vertices[2].u);
946  Swap(&vertices[1].u, &vertices[3].u);
947  }
948 
949  sceGuDrawArray(GU_TRIANGLE_FAN, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 4, 0, vertices);
950 
951  if(alpha != 255)
952  sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
953  return 0;
954 }
955 
956 static void
957 PSP_RenderPresent(SDL_Renderer * renderer)
958 {
959  PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata;
960  if(!data->displayListAvail)
961  return;
962 
963  data->displayListAvail = SDL_FALSE;
964  sceGuFinish();
965  sceGuSync(0,0);
966 
967 /* if(data->vsync) */
968  sceDisplayWaitVblankStart();
969 
970  data->backbuffer = data->frontbuffer;
971  data->frontbuffer = vabsptr(sceGuSwapBuffers());
972 
973 }
974 
975 static void
976 PSP_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
977 {
978  PSP_RenderData *renderdata = (PSP_RenderData *) renderer->driverdata;
979  PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata;
980 
981  if (renderdata == 0)
982  return;
983 
984  if(psp_texture == 0)
985  return;
986 
987  SDL_free(psp_texture->data);
988  SDL_free(psp_texture);
989  texture->driverdata = NULL;
990 }
991 
992 static void
993 PSP_DestroyRenderer(SDL_Renderer * renderer)
994 {
995  PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata;
996  if (data) {
997  if (!data->initialized)
998  return;
999 
1000  StartDrawing(renderer);
1001 
1002  sceGuTerm();
1003 /* vfree(data->backbuffer); */
1004 /* vfree(data->frontbuffer); */
1005 
1006  data->initialized = SDL_FALSE;
1007  data->displayListAvail = SDL_FALSE;
1008  SDL_free(data);
1009  }
1010  SDL_free(renderer);
1011 }
1012 
1013 #endif /* SDL_VIDEO_RENDER_PSP */
1014 
1015 /* vi: set ts=4 sw=4 expandtab: */
1016 
malloc
#define malloc
Definition: SDL_qsort.c:47
SDL_Renderer::blendMode
SDL_BlendMode blendMode
Definition: SDL_sysrender.h:179
format
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1572
points
GLfixed GLfixed GLint GLint GLfixed points
Definition: SDL_opengl_glext.h:4558
Uint8
uint8_t Uint8
Definition: SDL_stdinc.h:179
c
const GLubyte * c
Definition: SDL_opengl_glext.h:11093
blendMode
static SDL_BlendMode blendMode
Definition: testdraw2.c:34
SDL_RecreateWindow
int SDL_RecreateWindow(SDL_Window *window, Uint32 flags)
Definition: SDL_video.c:1617
end
GLuint GLuint end
Definition: SDL_opengl.h:1571
SDL_FPoint::x
float x
Definition: SDL_sysrender.h:44
SDL_FRect::h
float h
Definition: SDL_sysrender.h:53
NULL
#define NULL
Definition: begin_code.h:164
SDL_ScaleModeNearest
@ SDL_ScaleModeNearest
Definition: SDL_sysrender.h:37
b
GLboolean GLboolean GLboolean b
Definition: SDL_opengl_glext.h:1109
SDL_Renderer::SetRenderTarget
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:110
width
GLint GLint GLsizei width
Definition: SDL_opengl.h:1572
SDL_Renderer::g
Uint8 g
Definition: SDL_sysrender.h:178
SDL_BLENDMODE_BLEND
@ SDL_BLENDMODE_BLEND
Definition: SDL_blendmode.h:44
count
GLuint GLuint GLsizei count
Definition: SDL_opengl.h:1571
r
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
z
GLdouble GLdouble z
Definition: SDL_opengl_glext.h:404
SDL_Renderer::RenderFillRects
int(* RenderFillRects)(SDL_Renderer *renderer, const SDL_FRect *rects, int count)
Definition: SDL_sysrender.h:118
SDL_RenderDriver
Definition: SDL_sysrender.h:186
SDL_FRect::x
float x
Definition: SDL_sysrender.h:50
Uint32
uint32_t Uint32
Definition: SDL_stdinc.h:203
SDL_Renderer::UpdateViewport
int(* UpdateViewport)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:111
SDL_Renderer::WindowEvent
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
Definition: SDL_sysrender.h:89
SDL_FPoint::y
float y
Definition: SDL_sysrender.h:45
a
GLboolean GLboolean GLboolean GLboolean a
Definition: SDL_opengl_glext.h:1109
v
const GLdouble * v
Definition: SDL_opengl.h:2064
length
GLuint GLsizei GLsizei * length
Definition: SDL_opengl_glext.h:669
SDL_Rect::x
int x
Definition: SDL_rect.h:66
result
GLuint64EXT * result
Definition: SDL_opengl_glext.h:9432
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
SDL_Rect::w
int w
Definition: SDL_rect.h:67
row
GLenum GLenum void * row
Definition: SDL_opengl_glext.h:3138
SDL_Window
The type used to identify a window.
Definition: SDL_sysvideo.h:74
n
GLdouble n
Definition: SDL_opengl_glext.h:1952
alpha
GLfloat GLfloat GLfloat alpha
Definition: SDL_opengl_glext.h:412
dst
GLenum GLenum dst
Definition: SDL_opengl_glext.h:1737
SDL_RenderDriver::CreateRenderer
SDL_Renderer *(* CreateRenderer)(SDL_Window *window, Uint32 flags)
Definition: SDL_sysrender.h:187
SDL_memcpy
#define SDL_memcpy
Definition: SDL_dynapi_overrides.h:387
event
struct _cl_event * event
Definition: SDL_opengl_glext.h:2649
SDL_Renderer
Definition: SDL_sysrender.h:86
SDL_FPoint
Definition: SDL_sysrender.h:43
SDL_Renderer::driverdata
void * driverdata
Definition: SDL_sysrender.h:181
SDL_FRect::y
float y
Definition: SDL_sysrender.h:51
SDL_Renderer::b
Uint8 b
Definition: SDL_sysrender.h:178
SDL_FRect::w
float w
Definition: SDL_sysrender.h:52
x
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
color
GLuint color
Definition: SDL_opengl_glext.h:1148
window
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
SDL_Renderer::SetTextureColorMod
int(* SetTextureColorMod)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:93
SDL_RendererInfo::flags
Uint32 flags
Definition: SDL_render.h:81
SDL_Rect::y
int y
Definition: SDL_rect.h:66
SDL_Rect::h
int h
Definition: SDL_rect.h:67
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
f
GLfloat f
Definition: SDL_opengl_glext.h:1870
SDL_BLENDMODE_NONE
@ SDL_BLENDMODE_NONE
Definition: SDL_blendmode.h:42
height
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1572
SDL_FLIP_HORIZONTAL
@ SDL_FLIP_HORIZONTAL
Definition: SDL_render.h:114
SDL_RENDERER_PRESENTVSYNC
@ SDL_RENDERER_PRESENTVSYNC
Definition: SDL_render.h:69
rect
SDL_Rect rect
Definition: testrelative.c:27
SDL_Renderer::RenderDrawLines
int(* RenderDrawLines)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
Definition: SDL_sysrender.h:116
SDL_Renderer::RenderClear
int(* RenderClear)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:113
SDL_TRUE
@ SDL_TRUE
Definition: SDL_stdinc.h:164
SDL_Renderer::RenderDrawPoints
int(* RenderDrawPoints)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
Definition: SDL_sysrender.h:114
start
GLuint start
Definition: SDL_opengl.h:1571
pixels
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: SDL_opengl.h:1572
SDL_Renderer::RenderCopy
int(* RenderCopy)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
Definition: SDL_sysrender.h:120
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
v0
GLfloat v0
Definition: SDL_opengl_glext.h:690
SDL_Renderer::CreateTexture
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:92
size
GLsizeiptr size
Definition: SDL_opengl_glext.h:537
y
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
SDL_Renderer::DestroyRenderer
void(* DestroyRenderer)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:130
SDL_Renderer::LockTexture
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
Definition: SDL_sysrender.h:107
SDL_PIXELFORMAT_ABGR4444
@ SDL_PIXELFORMAT_ABGR4444
Definition: SDL_pixels.h:206
SDL_calloc
#define SDL_calloc
Definition: SDL_dynapi_overrides.h:375
SDL_Renderer::RenderReadPixels
int(* RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
Definition: SDL_sysrender.h:125
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:122
src
GLenum src
Definition: SDL_opengl_glext.h:1737
SDL_RendererFlip
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
Definition: SDL_render.h:112
renderer
static SDL_Renderer * renderer
Definition: testaudiocapture.c:21
SDL_FLIP_VERTICAL
@ SDL_FLIP_VERTICAL
Definition: SDL_render.h:115
v1
GLfloat GLfloat v1
Definition: SDL_opengl_glext.h:691
SDL_Renderer::info
SDL_RendererInfo info
Definition: SDL_sysrender.h:139
SDL_RENDERER_TARGETTEXTURE
@ SDL_RENDERER_TARGETTEXTURE
Definition: SDL_render.h:71
SDL_GetWindowPixelFormat
#define SDL_GetWindowPixelFormat
Definition: SDL_dynapi_overrides.h:513
SDL_BYTESPERPIXEL
#define SDL_BYTESPERPIXEL(X)
Definition: SDL_pixels.h:128
SDL_Renderer::RenderPresent
void(* RenderPresent)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:127
s
GLdouble s
Definition: SDL_opengl.h:2063
SDL_Rect
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:65
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:50
SDL_Texture
Definition: SDL_sysrender.h:58
SDL_Renderer::UpdateTexture
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
Definition: SDL_sysrender.h:99
SDL_hints.h
SDL_WindowEvent
Window state change event data (event.window.*)
Definition: SDL_events.h:196
SDL_FRect
Definition: SDL_sysrender.h:49
SDL_RenderDriver::info
SDL_RendererInfo info
Definition: SDL_sysrender.h:190
angle
GLfloat angle
Definition: SDL_opengl_glext.h:6097
SDL_PIXELFORMAT_BGR565
@ SDL_PIXELFORMAT_BGR565
Definition: SDL_pixels.h:227
u1
GLfixed u1
Definition: SDL_opengl_glext.h:4558
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:162
SDL_RendererInfo::name
const char * name
Definition: SDL_render.h:80
bits
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
Definition: SDL_opengl_glext.h:6176
SDL_FALSE
@ SDL_FALSE
Definition: SDL_stdinc.h:163
SDL_Renderer::r
Uint8 r
Definition: SDL_sysrender.h:178
SDL_Unsupported
#define SDL_Unsupported()
Definition: SDL_error.h:53
SDL_Renderer::a
Uint8 a
Definition: SDL_sysrender.h:178
SDL_PIXELFORMAT_ABGR8888
@ SDL_PIXELFORMAT_ABGR8888
Definition: SDL_pixels.h:254
SDL_RENDERER_ACCELERATED
@ SDL_RENDERER_ACCELERATED
Definition: SDL_render.h:67
flags
GLbitfield flags
Definition: SDL_opengl_glext.h:1480
SDL_Renderer::window
SDL_Window * window
Definition: SDL_sysrender.h:142
texture
GLenum GLenum GLuint texture
Definition: SDL_opengl_glext.h:1178
rects
EGLSurface EGLint * rects
Definition: eglext.h:282
SDL_PIXELFORMAT_ABGR1555
@ SDL_PIXELFORMAT_ABGR1555
Definition: SDL_pixels.h:218
free
SDL_EventEntry * free
Definition: SDL_events.c:84
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:50
PSP_RenderDriver
SDL_RenderDriver PSP_RenderDriver
SDL_BLENDMODE_MOD
@ SDL_BLENDMODE_MOD
Definition: SDL_blendmode.h:50
SDL_BLENDMODE_ADD
@ SDL_BLENDMODE_ADD
Definition: SDL_blendmode.h:47
SDL_Renderer::UnlockTexture
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:109
SDL_Renderer::DestroyTexture
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:128
w
GLubyte GLubyte GLubyte GLubyte w
Definition: SDL_opengl_glext.h:731