zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_render_psp.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2013 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_config.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 
46 extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags);
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_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
54  const SDL_Rect * rect, const void *pixels,
55  int pitch);
56 static int PSP_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
57  const SDL_Rect * rect, void **pixels, int *pitch);
58 static void PSP_UnlockTexture(SDL_Renderer * renderer,
60 static int PSP_SetRenderTarget(SDL_Renderer * renderer,
62 static int PSP_UpdateViewport(SDL_Renderer * renderer);
63 static int PSP_RenderClear(SDL_Renderer * renderer);
64 static int PSP_RenderDrawPoints(SDL_Renderer * renderer,
65  const SDL_FPoint * points, int count);
66 static int PSP_RenderDrawLines(SDL_Renderer * renderer,
67  const SDL_FPoint * points, int count);
68 static int PSP_RenderFillRects(SDL_Renderer * renderer,
69  const SDL_FRect * rects, int count);
70 static int PSP_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
71  const SDL_Rect * srcrect,
72  const SDL_FRect * dstrect);
73 static int PSP_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
74  Uint32 pixel_format, void * pixels, int pitch);
75 static int PSP_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
76  const SDL_Rect * srcrect, const SDL_FRect * dstrect,
77  const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip);
78 static void PSP_RenderPresent(SDL_Renderer * renderer);
79 static void PSP_DestroyTexture(SDL_Renderer * renderer,
81 static void PSP_DestroyRenderer(SDL_Renderer * renderer);
82 
83 /*
84 SDL_RenderDriver PSP_RenderDriver = {
85  PSP_CreateRenderer,
86  {
87  "PSP",
88  (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE),
89  1,
90  {SDL_PIXELFORMAT_ABGR8888},
91  0,
92  0}
93 };
94 */
95 SDL_RenderDriver PSP_RenderDriver = {
96  .CreateRenderer = PSP_CreateRenderer,
97  .info = {
98  .name = "PSP",
100  .num_texture_formats = 4,
101  .texture_formats = { [0] = SDL_PIXELFORMAT_BGR565,
105  },
106  .max_texture_width = 512,
107  .max_texture_height = 512,
108  }
109 };
110 
111 #define PSP_SCREEN_WIDTH 480
112 #define PSP_SCREEN_HEIGHT 272
113 
114 #define PSP_FRAME_BUFFER_WIDTH 512
115 #define PSP_FRAME_BUFFER_SIZE (PSP_FRAME_BUFFER_WIDTH*PSP_SCREEN_HEIGHT)
116 
117 static unsigned int __attribute__((aligned(16))) DisplayList[262144];
118 
119 
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))
124 
125 
126 typedef struct
127 {
128  void* frontbuffer ;
129  void* backbuffer ;
130  SDL_bool initialized ;
131  SDL_bool displayListAvail ;
132  unsigned int psm ;
133  unsigned int bpp ;
134 
135  SDL_bool vsync;
136  unsigned int currentColor;
137  int currentBlendMode;
138 
139 } PSP_RenderData;
140 
141 
142 typedef struct
143 {
144  void *data;
145  unsigned int size;
146  unsigned int width;
147  unsigned int height;
148  unsigned int textureWidth;
149  unsigned int textureHeight;
150  unsigned int bits;
151  unsigned int format;
152  unsigned int pitch;
153  SDL_bool swizzled;
155 } PSP_TextureData;
156 
157 typedef struct
158 {
159  float x, y, z;
160 } VertV;
161 
162 
163 typedef struct
164 {
165  float u, v;
166  float x, y, z;
167 
168 } VertTV;
169 
170 
171 /* Return next power of 2 */
172 static int
173 TextureNextPow2(unsigned int w)
174 {
175  if(w == 0)
176  return 0;
177 
178  unsigned int n = 2;
179 
180  while(w > n)
181  n <<= 1;
182 
183  return n;
184 }
185 
186 
187 static int
188 GetScaleQuality(void)
189 {
190  const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
191 
192  if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
193  return GU_NEAREST; /* GU_NEAREST good for tile-map */
194  } else {
195  return GU_LINEAR; /* GU_LINEAR good for scaling */
196  }
197 }
198 
199 static int
200 PixelFormatToPSPFMT(Uint32 format)
201 {
202  switch (format) {
204  return GU_PSM_5650;
206  return GU_PSM_5551;
208  return GU_PSM_4444;
210  return GU_PSM_8888;
211  default:
212  return GU_PSM_8888;
213  }
214 }
215 
216 void
217 StartDrawing(SDL_Renderer * renderer)
218 {
219  PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata;
220  if(data->displayListAvail)
221  return;
222 
223  sceGuStart(GU_DIRECT, DisplayList);
224  data->displayListAvail = SDL_TRUE;
225 }
226 
227 
228 int
229 TextureSwizzle(PSP_TextureData *psp_texture)
230 {
231  if(psp_texture->swizzled)
232  return 1;
233 
234  int bytewidth = psp_texture->textureWidth*(psp_texture->bits>>3);
235  int height = psp_texture->size / bytewidth;
236 
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;
241 
242  unsigned char *data = NULL;
243  data = malloc(psp_texture->size);
244 
245  int j;
246 
247  for(j = 0; j < height; j++, blockaddress += 16)
248  {
249  unsigned int *block;
250 
251  block = (unsigned int*)&data[blockaddress];
252 
253  int i;
254 
255  for(i = 0; i < rowblocks; i++)
256  {
257  *block++ = *src++;
258  *block++ = *src++;
259  *block++ = *src++;
260  *block++ = *src++;
261  block += 28;
262  }
263 
264  if((j & 0x7) == 0x7)
265  blockaddress += rowblocksadd;
266  }
267 
268  free(psp_texture->data);
269  psp_texture->data = data;
270  psp_texture->swizzled = SDL_TRUE;
271 
272  return 1;
273 }
274 int TextureUnswizzle(PSP_TextureData *psp_texture)
275 {
276  if(!psp_texture->swizzled)
277  return 1;
278 
279  int blockx, blocky;
280 
281  int bytewidth = psp_texture->textureWidth*(psp_texture->bits>>3);
282  int height = psp_texture->size / bytewidth;
283 
284  int widthblocks = bytewidth/16;
285  int heightblocks = height/8;
286 
287  int dstpitch = (bytewidth - 16)/4;
288  int dstrow = bytewidth * 8;
289 
290  unsigned int *src = (unsigned int*) psp_texture->data;
291 
292  unsigned char *data = NULL;
293 
294  data = malloc(psp_texture->size);
295 
296  if(!data)
297  return 0;
298 
299  sceKernelDcacheWritebackAll();
300 
301  int j;
302 
303  unsigned char *ydst = (unsigned char *)data;
304 
305  for(blocky = 0; blocky < heightblocks; ++blocky)
306  {
307  unsigned char *xdst = ydst;
308 
309  for(blockx = 0; blockx < widthblocks; ++blockx)
310  {
311  unsigned int *block;
312 
313  block = (unsigned int*)xdst;
314 
315  for(j = 0; j < 8; ++j)
316  {
317  *(block++) = *(src++);
318  *(block++) = *(src++);
319  *(block++) = *(src++);
320  *(block++) = *(src++);
321  block += dstpitch;
322  }
323 
324  xdst += 16;
325  }
326 
327  ydst += dstrow;
328  }
329 
330  free(psp_texture->data);
331 
332  psp_texture->data = data;
333 
334  psp_texture->swizzled = SDL_FALSE;
335 
336  return 1;
337 }
338 
339 SDL_Renderer *
340 PSP_CreateRenderer(SDL_Window * window, Uint32 flags)
341 {
342 
343  SDL_Renderer *renderer;
344  PSP_RenderData *data;
345  int pixelformat;
346  renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
347  if (!renderer) {
348  SDL_OutOfMemory();
349  return NULL;
350  }
351 
352  data = (PSP_RenderData *) SDL_calloc(1, sizeof(*data));
353  if (!data) {
354  PSP_DestroyRenderer(renderer);
355  SDL_OutOfMemory();
356  return NULL;
357  }
358 
359 
360  renderer->WindowEvent = PSP_WindowEvent;
361  renderer->CreateTexture = PSP_CreateTexture;
362  renderer->UpdateTexture = PSP_UpdateTexture;
363  renderer->LockTexture = PSP_LockTexture;
364  renderer->UnlockTexture = PSP_UnlockTexture;
365  renderer->SetRenderTarget = PSP_SetRenderTarget;
366  renderer->UpdateViewport = PSP_UpdateViewport;
367  renderer->RenderClear = PSP_RenderClear;
368  renderer->RenderDrawPoints = PSP_RenderDrawPoints;
369  renderer->RenderDrawLines = PSP_RenderDrawLines;
370  renderer->RenderFillRects = PSP_RenderFillRects;
371  renderer->RenderCopy = PSP_RenderCopy;
372  renderer->RenderReadPixels = PSP_RenderReadPixels;
373  renderer->RenderCopyEx = PSP_RenderCopyEx;
374  renderer->RenderPresent = PSP_RenderPresent;
375  renderer->DestroyTexture = PSP_DestroyTexture;
376  renderer->DestroyRenderer = PSP_DestroyRenderer;
377  renderer->info = PSP_RenderDriver.info;
378  renderer->info.flags = SDL_RENDERER_ACCELERATED;
379  renderer->driverdata = data;
380  renderer->window = window;
381 
382  if (data->initialized != SDL_FALSE)
383  return 0;
384  data->initialized = SDL_TRUE;
385 
386  if (flags & SDL_RENDERER_PRESENTVSYNC) {
387  data->vsync = SDL_TRUE;
388  } else {
389  data->vsync = SDL_FALSE;
390  }
391 
392  pixelformat=PixelFormatToPSPFMT(SDL_GetWindowPixelFormat(window));
393  switch(pixelformat)
394  {
395  case GU_PSM_4444:
396  case GU_PSM_5650:
397  case GU_PSM_5551:
398  data->frontbuffer = (unsigned int *)(PSP_FRAME_BUFFER_SIZE<<1);
399  data->backbuffer = (unsigned int *)(0);
400  data->bpp = 2;
401  data->psm = pixelformat;
402  break;
403  default:
404  data->frontbuffer = (unsigned int *)(PSP_FRAME_BUFFER_SIZE<<2);
405  data->backbuffer = (unsigned int *)(0);
406  data->bpp = 4;
407  data->psm = GU_PSM_8888;
408  break;
409  }
410 
411  sceGuInit();
412  /* setup GU */
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);
416 
417 
418  sceGuOffset(2048 - (PSP_SCREEN_WIDTH>>1), 2048 - (PSP_SCREEN_HEIGHT>>1));
419  sceGuViewport(2048, 2048, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
420 
421  data->frontbuffer = vabsptr(data->frontbuffer);
422  data->backbuffer = vabsptr(data->backbuffer);
423 
424  /* Scissoring */
425  sceGuScissor(0, 0, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
426  sceGuEnable(GU_SCISSOR_TEST);
427 
428  /* Backface culling */
429  sceGuFrontFace(GU_CCW);
430  sceGuEnable(GU_CULL_FACE);
431 
432  /* Texturing */
433  sceGuEnable(GU_TEXTURE_2D);
434  sceGuShadeModel(GU_SMOOTH);
435  sceGuTexWrap(GU_REPEAT, GU_REPEAT);
436 
437  /* Blending */
438  sceGuEnable(GU_BLEND);
439  sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
440 
441  sceGuTexFilter(GU_LINEAR,GU_LINEAR);
442 
443  sceGuFinish();
444  sceGuSync(0,0);
445  sceDisplayWaitVblankStartCB();
446  sceGuDisplay(GU_TRUE);
447 
448  return renderer;
449 }
450 
451 static void
452 PSP_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
453 {
454 
455 }
456 
457 
458 static int
459 PSP_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
460 {
461 /* PSP_RenderData *renderdata = (PSP_RenderData *) renderer->driverdata; */
462  PSP_TextureData* psp_texture = (PSP_TextureData*) SDL_calloc(1, sizeof(*psp_texture));;
463 
464  if(!psp_texture)
465  return -1;
466 
467  psp_texture->swizzled = SDL_FALSE;
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);
473 
474  switch(psp_texture->format)
475  {
476  case GU_PSM_5650:
477  case GU_PSM_5551:
478  case GU_PSM_4444:
479  psp_texture->bits = 16;
480  break;
481 
482  case GU_PSM_8888:
483  psp_texture->bits = 32;
484  break;
485 
486  default:
487  return -1;
488  }
489 
490  psp_texture->pitch = psp_texture->textureWidth * SDL_BYTESPERPIXEL(texture->format);
491  psp_texture->size = psp_texture->textureHeight*psp_texture->pitch;
492  psp_texture->data = SDL_calloc(1, psp_texture->size);
493 
494  if(!psp_texture->data)
495  {
496  SDL_free(psp_texture);
497  return SDL_OutOfMemory();
498  }
499  texture->driverdata = psp_texture;
500 
501  return 0;
502 }
503 
504 
505 void
506 TextureActivate(SDL_Texture * texture)
507 {
508  PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata;
509  int scaleMode = GetScaleQuality();
510 
511  /* Swizzling is useless with small textures. */
512  if (texture->w >= 16 || texture->h >= 16)
513  {
514  TextureSwizzle(psp_texture);
515  }
516 
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); /* GU_NEAREST good for tile-map */
521  /* GU_LINEAR good for scaling */
522  sceGuTexImage(0, psp_texture->textureWidth, psp_texture->textureHeight, psp_texture->textureWidth, psp_texture->data);
523  sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
524 }
525 
526 
527 static int
528 PSP_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
529  const SDL_Rect * rect, const void *pixels, int pitch)
530 {
531 /* PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata; */
532  const Uint8 *src;
533  Uint8 *dst;
534  int row, length,dpitch;
535  src = pixels;
536 
537  PSP_LockTexture(renderer, texture,rect,(void **)&dst, &dpitch);
538  length = rect->w * SDL_BYTESPERPIXEL(texture->format);
539  if (length == pitch && length == dpitch) {
540  SDL_memcpy(dst, src, length*rect->h);
541  } else {
542  for (row = 0; row < rect->h; ++row) {
543  SDL_memcpy(dst, src, length);
544  src += pitch;
545  dst += dpitch;
546  }
547  }
548 
549  sceKernelDcacheWritebackAll();
550  return 0;
551 }
552 
553 static int
554 PSP_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
555  const SDL_Rect * rect, void **pixels, int *pitch)
556 {
557  PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata;
558 
559  *pixels =
560  (void *) ((Uint8 *) psp_texture->data + rect->y * psp_texture->pitch +
561  rect->x * SDL_BYTESPERPIXEL(texture->format));
562  *pitch = psp_texture->pitch;
563  return 0;
564 }
565 
566 static void
567 PSP_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
568 {
569  PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata;
570  SDL_Rect rect;
571 
572  /* We do whole texture updates, at least for now */
573  rect.x = 0;
574  rect.y = 0;
575  rect.w = texture->w;
576  rect.h = texture->h;
577  PSP_UpdateTexture(renderer, texture, &rect, psp_texture->data, psp_texture->pitch);
578 }
579 
580 static int
581 PSP_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
582 {
583 
584  return 0;
585 }
586 
587 static int
588 PSP_UpdateViewport(SDL_Renderer * renderer)
589 {
590 
591  return 0;
592 }
593 
594 
595 static void
596 PSP_SetBlendMode(SDL_Renderer * renderer, int blendMode)
597 {
598  PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata;
599  if (blendMode != data-> currentBlendMode) {
600  switch (blendMode) {
601  case SDL_BLENDMODE_NONE:
602  sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
603  sceGuDisable(GU_BLEND);
604  break;
605  case SDL_BLENDMODE_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 );
609  break;
610  case SDL_BLENDMODE_ADD:
611  sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
612  sceGuEnable(GU_BLEND);
613  sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_FIX, 0, 0x00FFFFFF );
614  break;
615  case SDL_BLENDMODE_MOD:
616  sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
617  sceGuEnable(GU_BLEND);
618  sceGuBlendFunc( GU_ADD, GU_FIX, GU_SRC_COLOR, 0, 0);
619  break;
620  }
621  data->currentBlendMode = blendMode;
622  }
623 }
624 
625 
626 
627 static int
628 PSP_RenderClear(SDL_Renderer * renderer)
629 {
630  /* start list */
631  StartDrawing(renderer);
632  int color = renderer->a << 24 | renderer->b << 16 | renderer->g << 8 | renderer->r;
633  sceGuClearColor(color);
634  sceGuClearDepth(0);
635  sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT|GU_FAST_CLEAR_BIT);
636 
637  return 0;
638 }
639 
640 static int
641 PSP_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points,
642  int count)
643 {
644  int color = renderer->a << 24 | renderer->b << 16 | renderer->g << 8 | renderer->r;
645  int i;
646  StartDrawing(renderer);
647  VertV* vertices = (VertV*)sceGuGetMemory(count*sizeof(VertV));
648 
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;
653  }
654  sceGuDisable(GU_TEXTURE_2D);
655  sceGuColor(color);
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);
660 
661  return 0;
662 }
663 
664 static int
665 PSP_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points,
666  int count)
667 {
668  int color = renderer->a << 24 | renderer->b << 16 | renderer->g << 8 | renderer->r;
669  int i;
670  StartDrawing(renderer);
671  VertV* vertices = (VertV*)sceGuGetMemory(count*sizeof(VertV));
672 
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;
677  }
678 
679  sceGuDisable(GU_TEXTURE_2D);
680  sceGuColor(color);
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);
685 
686  return 0;
687 }
688 
689 static int
690 PSP_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects,
691  int count)
692 {
693  int color = renderer->a << 24 | renderer->b << 16 | renderer->g << 8 | renderer->r;
694  int i;
695  StartDrawing(renderer);
696 
697  for (i = 0; i < count; ++i) {
698  const SDL_FRect *rect = &rects[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;
703 
704  vertices[1].x = rect->x + rect->w;
705  vertices[1].y = rect->y + rect->h;
706  vertices[1].z = 0.0f;
707 
708  sceGuDisable(GU_TEXTURE_2D);
709  sceGuColor(color);
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);
714  }
715 
716  return 0;
717 }
718 
719 
720 #define PI 3.14159265358979f
721 
722 #define radToDeg(x) ((x)*180.f/PI)
723 #define degToRad(x) ((x)*PI/180.f)
724 
725 float MathAbs(float x)
726 {
727  float result;
728 
729  __asm__ volatile (
730  "mtv %1, S000\n"
731  "vabs.s S000, S000\n"
732  "mfv %0, S000\n"
733  : "=r"(result) : "r"(x));
734 
735  return result;
736 }
737 
738 void MathSincos(float r, float *s, float *c)
739 {
740  __asm__ volatile (
741  "mtv %2, S002\n"
742  "vcst.s S003, VFPU_2_PI\n"
743  "vmul.s S002, S002, S003\n"
744  "vrot.p C000, S002, [s, c]\n"
745  "mfv %0, S000\n"
746  "mfv %1, S001\n"
747  : "=r"(*s), "=r"(*c): "r"(r));
748 }
749 
750 void Swap(float *a, float *b)
751 {
752  float n=*a;
753  *a = *b;
754  *b = n;
755 }
756 
757 static int
758 PSP_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
759  const SDL_Rect * srcrect, const SDL_FRect * dstrect)
760 {
761  float x, y, width, height;
762  float u0, v0, u1, v1;
763  unsigned char alpha;
764 
765  x = dstrect->x;
766  y = dstrect->y;
767  width = dstrect->w;
768  height = dstrect->h;
769 
770  u0 = srcrect->x;
771  v0 = srcrect->y;
772  u1 = srcrect->x + srcrect->w;
773  v1 = srcrect->y + srcrect->h;
774 
775  alpha = texture->a;
776 
777  StartDrawing(renderer);
778  TextureActivate(texture);
779  PSP_SetBlendMode(renderer, renderer->blendMode);
780 
781  if(alpha != 255)
782  {
783  sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
784  sceGuColor(GU_RGBA(255, 255, 255, alpha));
785  }else{
786  sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
787  sceGuColor(0xFFFFFFFF);
788  }
789 
790  if((MathAbs(u1) - MathAbs(u0)) < 64.0f)
791  {
792  VertTV* vertices = (VertTV*)sceGuGetMemory((sizeof(VertTV))<<1);
793 
794  vertices[0].u = u0;
795  vertices[0].v = v0;
796  vertices[0].x = x;
797  vertices[0].y = y;
798  vertices[0].z = 0;
799 
800  vertices[1].u = u1;
801  vertices[1].v = v1;
802  vertices[1].x = x + width;
803  vertices[1].y = y + height;
804  vertices[1].z = 0;
805 
806  sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
807  }
808  else
809  {
810  float start, end;
811  float curU = u0;
812  float curX = x;
813  float endX = x + width;
814  float slice = 64.0f;
815  float ustep = (u1 - u0)/width * slice;
816 
817  if(ustep < 0.0f)
818  ustep = -ustep;
819 
820  for(start = 0, end = width; start < end; start += slice)
821  {
822  VertTV* vertices = (VertTV*)sceGuGetMemory((sizeof(VertTV))<<1);
823 
824  float polyWidth = ((curX + slice) > endX) ? (endX - curX) : slice;
825  float sourceWidth = ((curU + ustep) > u1) ? (u1 - curU) : ustep;
826 
827  vertices[0].u = curU;
828  vertices[0].v = v0;
829  vertices[0].x = curX;
830  vertices[0].y = y;
831  vertices[0].z = 0;
832 
833  curU += sourceWidth;
834  curX += polyWidth;
835 
836  vertices[1].u = curU;
837  vertices[1].v = v1;
838  vertices[1].x = curX;
839  vertices[1].y = (y + height);
840  vertices[1].z = 0;
841 
842  sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
843  }
844  }
845 
846  if(alpha != 255)
847  sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
848  return 0;
849 }
850 
851 static int
852 PSP_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
853  Uint32 pixel_format, void * pixels, int pitch)
854 
855 {
856  return 0;
857 }
858 
859 
860 static int
861 PSP_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
862  const SDL_Rect * srcrect, const SDL_FRect * dstrect,
863  const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
864 {
865  float x, y, width, height;
866  float u0, v0, u1, v1;
867  unsigned char alpha;
868  float centerx, centery;
869 
870  x = dstrect->x;
871  y = dstrect->y;
872  width = dstrect->w;
873  height = dstrect->h;
874 
875  u0 = srcrect->x;
876  v0 = srcrect->y;
877  u1 = srcrect->x + srcrect->w;
878  v1 = srcrect->y + srcrect->h;
879 
880  centerx = center->x;
881  centery = center->y;
882 
883  alpha = texture->a;
884 
885  StartDrawing(renderer);
886  TextureActivate(texture);
887  PSP_SetBlendMode(renderer, renderer->blendMode);
888 
889  if(alpha != 255)
890  {
891  sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
892  sceGuColor(GU_RGBA(255, 255, 255, alpha));
893  }else{
894  sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
895  sceGuColor(0xFFFFFFFF);
896  }
897 
898 /* x += width * 0.5f; */
899 /* y += height * 0.5f; */
900  x += centerx;
901  y += centery;
902 
903  float c, s;
904 
905  MathSincos(degToRad(angle), &s, &c);
906 
907 /* width *= 0.5f; */
908 /* height *= 0.5f; */
909  width -= centerx;
910  height -= centery;
911 
912 
913  float cw = c*width;
914  float sw = s*width;
915  float ch = c*height;
916  float sh = s*height;
917 
918  VertTV* vertices = (VertTV*)sceGuGetMemory(sizeof(VertTV)<<2);
919 
920  vertices[0].u = u0;
921  vertices[0].v = v0;
922  vertices[0].x = x - cw + sh;
923  vertices[0].y = y - sw - ch;
924  vertices[0].z = 0;
925 
926  vertices[1].u = u0;
927  vertices[1].v = v1;
928  vertices[1].x = x - cw - sh;
929  vertices[1].y = y - sw + ch;
930  vertices[1].z = 0;
931 
932  vertices[2].u = u1;
933  vertices[2].v = v1;
934  vertices[2].x = x + cw - sh;
935  vertices[2].y = y + sw + ch;
936  vertices[2].z = 0;
937 
938  vertices[3].u = u1;
939  vertices[3].v = v0;
940  vertices[3].x = x + cw + sh;
941  vertices[3].y = y + sw - ch;
942  vertices[3].z = 0;
943 
944  if (flip & SDL_FLIP_HORIZONTAL) {
945  Swap(&vertices[0].v, &vertices[2].v);
946  Swap(&vertices[1].v, &vertices[3].v);
947  }
948  if (flip & SDL_FLIP_VERTICAL) {
949  Swap(&vertices[0].u, &vertices[2].u);
950  Swap(&vertices[1].u, &vertices[3].u);
951  }
952 
953  sceGuDrawArray(GU_TRIANGLE_FAN, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 4, 0, vertices);
954 
955  if(alpha != 255)
956  sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
957  return 0;
958 }
959 
960 static void
961 PSP_RenderPresent(SDL_Renderer * renderer)
962 {
963  PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata;
964  if(!data->displayListAvail)
965  return;
966 
967  data->displayListAvail = SDL_FALSE;
968  sceGuFinish();
969  sceGuSync(0,0);
970 
971 /* if(data->vsync) */
972  sceDisplayWaitVblankStart();
973 
974  data->backbuffer = data->frontbuffer;
975  data->frontbuffer = vabsptr(sceGuSwapBuffers());
976 
977 }
978 
979 static void
980 PSP_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
981 {
982  PSP_RenderData *renderdata = (PSP_RenderData *) renderer->driverdata;
983  PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata;
984 
985  if (renderdata == 0)
986  return;
987 
988  if(psp_texture == 0)
989  return;
990 
991  SDL_free(psp_texture->data);
992  SDL_free(psp_texture);
993  texture->driverdata = NULL;
994 }
995 
996 static void
997 PSP_DestroyRenderer(SDL_Renderer * renderer)
998 {
999  PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata;
1000  if (data) {
1001  if (!data->initialized)
1002  return;
1003 
1004  StartDrawing(renderer);
1005 
1006  sceGuTerm();
1007 /* vfree(data->backbuffer); */
1008 /* vfree(data->frontbuffer); */
1009 
1010  data->initialized = SDL_FALSE;
1011  data->displayListAvail = SDL_FALSE;
1012  SDL_free(data);
1013  }
1014  SDL_free(renderer);
1015 }
1016 
1017 #endif /* SDL_VIDEO_RENDER_PSP */
1018 
1019 /* vi: set ts=4 sw=4 expandtab: */
1020 
GLdouble s
Definition: glew.h:1376
GLfloat GLfloat v1
Definition: glew.h:1838
GLuint GLdouble u1
Definition: glew.h:3337
DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size)
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
Definition: SDL_sysrender.h:80
GLuint color
Definition: glew.h:7185
SDL_RendererInfo info
#define NULL
Definition: ftobjs.h:61
int(* RenderClear)(SDL_Renderer *renderer)
GLuint start
Definition: glew.h:1239
GLclampf f
Definition: glew.h:3390
int(* RenderDrawPoints)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
GLdouble angle
Definition: glew.h:8396
SDL_bool
Definition: SDL_stdinc.h:116
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:82
GLclampd n
Definition: glew.h:7287
#define SDL_HINT_RENDER_SCALE_QUALITY
A variable controlling the scaling quality.
Definition: SDL_hints.h:118
SDL_Renderer *(* CreateRenderer)(SDL_Window *window, Uint32 flags)
void * driverdata
EGLSurface EGLint x
Definition: eglext.h:293
SDL_EventEntry * free
Definition: SDL_events.c:80
DECLSPEC void SDLCALL SDL_free(void *mem)
int32_t j
Definition: e_log.c:102
EGLSurface EGLint EGLint EGLint EGLint height
Definition: eglext.h:293
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:8736
#define SDL_BYTESPERPIXEL(X)
Definition: SDL_pixels.h:123
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:99
#define bits
Definition: infblock.c:15
const char * name
Definition: SDL_render.h:80
if(!yyg->yy_init)
SDL_Window * window
SDL_RendererInfo info
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:145
DECLSPEC Uint32 SDLCALL SDL_GetWindowPixelFormat(SDL_Window *window)
Get the pixel format associated with the window.
Definition: SDL_video.c:1059
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
Definition: SDL_sysrender.h:97
GLenum GLenum GLvoid * row
Definition: glew.h:4447
ALuint u
Definition: alMain.h:58
GLuint64EXT * result
Definition: glew.h:12708
const GLdouble * v
Definition: glew.h:1377
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
Definition: SDL_sysrender.h:89
GLenum GLenum dst
Definition: glew.h:2396
GLsizei GLsizei * length
Definition: gl2ext.h:792
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
int SDL_RecreateWindow(SDL_Window *window, Uint32 flags)
Definition: SDL_video.c:1317
EGLSurface EGLint EGLint EGLint width
Definition: eglext.h:293
static int GetScaleQuality(void)
SDL_BlendMode blendMode
GLint GLsizei count
Definition: gl2ext.h:1011
int(* RenderDrawLines)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
const GLfloat * c
Definition: glew.h:14913
GLfloat v0
Definition: glew.h:1834
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl2ext.h:845
int x
Definition: SDL_rect.h:65
GLclampf GLclampf GLclampf alpha
Definition: glew.h:1506
DECLSPEC const char *SDLCALL SDL_GetHint(const char *name)
Get a hint.
Definition: SDL_hints.c:104
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int w
Definition: SDL_rect.h:66
int(* RenderCopy)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
Definition: SDL_render.h:111
Window state change event data (event.window.*)
Definition: SDL_events.h:160
EGLSurface EGLint EGLint y
Definition: eglext.h:293
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
GLenum GLenum GLuint texture
Definition: gl2ext.h:850
#define malloc
Definition: SDL_malloc.c:635
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: gl2ext.h:845
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)
Definition: SDL_string.c:293
GLenum GLsizei GLsizei GLsizei GLsizei GLbitfield flags
Definition: glew.h:2767
int(* RenderFillRects)(SDL_Renderer *renderer, const SDL_FRect *rects, int count)
int h
Definition: SDL_rect.h:66
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:129
GLdouble GLdouble GLdouble r
Definition: glew.h:1392
GLdouble GLdouble GLdouble b
Definition: glew.h:8383
GLuint GLuint end
Definition: glew.h:1239
GLint GLint GLint GLint z
Definition: gl2ext.h:1214
Uint32 format
Definition: SDL_sysrender.h:52
GLint GLint GLint GLint GLint w
Definition: gl2ext.h:1215
void * driverdata
Definition: SDL_sysrender.h:69
int(* UpdateViewport)(SDL_Renderer *renderer)
GLuint GLdouble GLdouble GLint GLint const GLdouble * points
Definition: glew.h:3337
GLenum src
Definition: glew.h:2396
int i
Definition: pngrutil.c:1377
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)
GLfloat vertices[12]
Definition: modern.h:22
int y
Definition: SDL_rect.h:65
DECLSPEC int SDLCALL SDL_strcasecmp(const char *str1, const char *str2)
Definition: SDL_string.c:946
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:63
cl_event event
Definition: glew.h:3556
GLsizei size
Definition: gl2ext.h:1467