SDL  2.0
SDL_render_psp.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2020 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 #define PSP_SCREEN_WIDTH 480
46 #define PSP_SCREEN_HEIGHT 272
47 
48 #define PSP_FRAME_BUFFER_WIDTH 512
49 #define PSP_FRAME_BUFFER_SIZE (PSP_FRAME_BUFFER_WIDTH*PSP_SCREEN_HEIGHT)
50 
51 static unsigned int __attribute__((aligned(16))) DisplayList[262144];
52 
53 
54 #define COL5650(r,g,b,a) ((r>>3) | ((g>>2)<<5) | ((b>>3)<<11))
55 #define COL5551(r,g,b,a) ((r>>3) | ((g>>3)<<5) | ((b>>3)<<10) | (a>0?0x7000:0))
56 #define COL4444(r,g,b,a) ((r>>4) | ((g>>4)<<4) | ((b>>4)<<8) | ((a>>4)<<12))
57 #define COL8888(r,g,b,a) ((r) | ((g)<<8) | ((b)<<16) | ((a)<<24))
58 
59 
60 typedef struct
61 {
62  void* frontbuffer ;
63  void* backbuffer ;
64  SDL_bool initialized ;
65  SDL_bool displayListAvail ;
66  unsigned int psm ;
67  unsigned int bpp ;
68 
69  SDL_bool vsync;
70  unsigned int currentColor;
71  int currentBlendMode;
72 
73 } PSP_RenderData;
74 
75 
76 typedef struct
77 {
78  void *data; /**< Image data. */
79  unsigned int size; /**< Size of data in bytes. */
80  unsigned int width; /**< Image width. */
81  unsigned int height; /**< Image height. */
82  unsigned int textureWidth; /**< Texture width (power of two). */
83  unsigned int textureHeight; /**< Texture height (power of two). */
84  unsigned int bits; /**< Image bits per pixel. */
85  unsigned int format; /**< Image format - one of ::pgePixelFormat. */
86  unsigned int pitch;
87  SDL_bool swizzled; /**< Is image swizzled. */
88 
89 } PSP_TextureData;
90 
91 typedef struct
92 {
93  float x, y, z;
94 } VertV;
95 
96 
97 typedef struct
98 {
99  float u, v;
100  float x, y, z;
101 
102 } VertTV;
103 
104 #define PI 3.14159265358979f
105 
106 #define radToDeg(x) ((x)*180.f/PI)
107 #define degToRad(x) ((x)*PI/180.f)
108 
109 float MathAbs(float x)
110 {
111  float result;
112 
113  __asm__ volatile (
114  "mtv %1, S000\n"
115  "vabs.s S000, S000\n"
116  "mfv %0, S000\n"
117  : "=r"(result) : "r"(x));
118 
119  return result;
120 }
121 
122 void MathSincos(float r, float *s, float *c)
123 {
124  __asm__ volatile (
125  "mtv %2, S002\n"
126  "vcst.s S003, VFPU_2_PI\n"
127  "vmul.s S002, S002, S003\n"
128  "vrot.p C000, S002, [s, c]\n"
129  "mfv %0, S000\n"
130  "mfv %1, S001\n"
131  : "=r"(*s), "=r"(*c): "r"(r));
132 }
133 
134 void Swap(float *a, float *b)
135 {
136  float n=*a;
137  *a = *b;
138  *b = n;
139 }
140 
141 /* Return next power of 2 */
142 static int
143 TextureNextPow2(unsigned int w)
144 {
145  if(w == 0)
146  return 0;
147 
148  unsigned int n = 2;
149 
150  while(w > n)
151  n <<= 1;
152 
153  return n;
154 }
155 
156 
157 static int
158 PixelFormatToPSPFMT(Uint32 format)
159 {
160  switch (format) {
162  return GU_PSM_5650;
164  return GU_PSM_5551;
166  return GU_PSM_4444;
168  return GU_PSM_8888;
169  default:
170  return GU_PSM_8888;
171  }
172 }
173 
174 void
175 StartDrawing(SDL_Renderer * renderer)
176 {
177  PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata;
178  if(data->displayListAvail)
179  return;
180 
181  sceGuStart(GU_DIRECT, DisplayList);
182  data->displayListAvail = SDL_TRUE;
183 }
184 
185 
186 int
187 TextureSwizzle(PSP_TextureData *psp_texture)
188 {
189  if(psp_texture->swizzled)
190  return 1;
191 
192  int bytewidth = psp_texture->textureWidth*(psp_texture->bits>>3);
193  int height = psp_texture->size / bytewidth;
194 
195  int rowblocks = (bytewidth>>4);
196  int rowblocksadd = (rowblocks-1)<<7;
197  unsigned int blockaddress = 0;
198  unsigned int *src = (unsigned int*) psp_texture->data;
199 
200  unsigned char *data = NULL;
201  data = malloc(psp_texture->size);
202 
203  int j;
204 
205  for(j = 0; j < height; j++, blockaddress += 16)
206  {
207  unsigned int *block;
208 
209  block = (unsigned int*)&data[blockaddress];
210 
211  int i;
212 
213  for(i = 0; i < rowblocks; i++)
214  {
215  *block++ = *src++;
216  *block++ = *src++;
217  *block++ = *src++;
218  *block++ = *src++;
219  block += 28;
220  }
221 
222  if((j & 0x7) == 0x7)
223  blockaddress += rowblocksadd;
224  }
225 
226  free(psp_texture->data);
227  psp_texture->data = data;
228  psp_texture->swizzled = SDL_TRUE;
229 
230  return 1;
231 }
232 int TextureUnswizzle(PSP_TextureData *psp_texture)
233 {
234  if(!psp_texture->swizzled)
235  return 1;
236 
237  int blockx, blocky;
238 
239  int bytewidth = psp_texture->textureWidth*(psp_texture->bits>>3);
240  int height = psp_texture->size / bytewidth;
241 
242  int widthblocks = bytewidth/16;
243  int heightblocks = height/8;
244 
245  int dstpitch = (bytewidth - 16)/4;
246  int dstrow = bytewidth * 8;
247 
248  unsigned int *src = (unsigned int*) psp_texture->data;
249 
250  unsigned char *data = NULL;
251 
252  data = malloc(psp_texture->size);
253 
254  if(!data)
255  return 0;
256 
257  sceKernelDcacheWritebackAll();
258 
259  int j;
260 
261  unsigned char *ydst = (unsigned char *)data;
262 
263  for(blocky = 0; blocky < heightblocks; ++blocky)
264  {
265  unsigned char *xdst = ydst;
266 
267  for(blockx = 0; blockx < widthblocks; ++blockx)
268  {
269  unsigned int *block;
270 
271  block = (unsigned int*)xdst;
272 
273  for(j = 0; j < 8; ++j)
274  {
275  *(block++) = *(src++);
276  *(block++) = *(src++);
277  *(block++) = *(src++);
278  *(block++) = *(src++);
279  block += dstpitch;
280  }
281 
282  xdst += 16;
283  }
284 
285  ydst += dstrow;
286  }
287 
288  free(psp_texture->data);
289 
290  psp_texture->data = data;
291 
292  psp_texture->swizzled = SDL_FALSE;
293 
294  return 1;
295 }
296 
297 static void
298 PSP_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
299 {
300 }
301 
302 
303 static int
304 PSP_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
305 {
306 /* PSP_RenderData *renderdata = (PSP_RenderData *) renderer->driverdata; */
307  PSP_TextureData* psp_texture = (PSP_TextureData*) SDL_calloc(1, sizeof(*psp_texture));
308 
309  if(!psp_texture)
310  return -1;
311 
312  psp_texture->swizzled = SDL_FALSE;
313  psp_texture->width = texture->w;
314  psp_texture->height = texture->h;
315  psp_texture->textureHeight = TextureNextPow2(texture->h);
316  psp_texture->textureWidth = TextureNextPow2(texture->w);
317  psp_texture->format = PixelFormatToPSPFMT(texture->format);
318 
319  switch(psp_texture->format)
320  {
321  case GU_PSM_5650:
322  case GU_PSM_5551:
323  case GU_PSM_4444:
324  psp_texture->bits = 16;
325  break;
326 
327  case GU_PSM_8888:
328  psp_texture->bits = 32;
329  break;
330 
331  default:
332  return -1;
333  }
334 
335  psp_texture->pitch = psp_texture->textureWidth * SDL_BYTESPERPIXEL(texture->format);
336  psp_texture->size = psp_texture->textureHeight*psp_texture->pitch;
337  psp_texture->data = SDL_calloc(1, psp_texture->size);
338 
339  if(!psp_texture->data)
340  {
341  SDL_free(psp_texture);
342  return SDL_OutOfMemory();
343  }
344  texture->driverdata = psp_texture;
345 
346  return 0;
347 }
348 
349 static int
350 PSP_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture)
351 {
352  return SDL_Unsupported();
353 }
354 
355 void
356 TextureActivate(SDL_Texture * texture)
357 {
358  PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata;
359  int scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? GU_NEAREST : GU_LINEAR;
360 
361  /* Swizzling is useless with small textures. */
362  if (texture->w >= 16 || texture->h >= 16)
363  {
364  TextureSwizzle(psp_texture);
365  }
366 
367  sceGuEnable(GU_TEXTURE_2D);
368  sceGuTexWrap(GU_REPEAT, GU_REPEAT);
369  sceGuTexMode(psp_texture->format, 0, 0, psp_texture->swizzled);
370  sceGuTexFilter(scaleMode, scaleMode); /* GU_NEAREST good for tile-map */
371  /* GU_LINEAR good for scaling */
372  sceGuTexImage(0, psp_texture->textureWidth, psp_texture->textureHeight, psp_texture->textureWidth, psp_texture->data);
373  sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
374 }
375 
376 
377 static int
378 PSP_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
379  const SDL_Rect * rect, const void *pixels, int pitch)
380 {
381 /* PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata; */
382  const Uint8 *src;
383  Uint8 *dst;
384  int row, length,dpitch;
385  src = pixels;
386 
387  PSP_LockTexture(renderer, texture,rect,(void **)&dst, &dpitch);
388  length = rect->w * SDL_BYTESPERPIXEL(texture->format);
389  if (length == pitch && length == dpitch) {
391  } else {
392  for (row = 0; row < rect->h; ++row) {
394  src += pitch;
395  dst += dpitch;
396  }
397  }
398 
399  sceKernelDcacheWritebackAll();
400  return 0;
401 }
402 
403 static int
404 PSP_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
405  const SDL_Rect * rect, void **pixels, int *pitch)
406 {
407  PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata;
408 
409  *pixels =
410  (void *) ((Uint8 *) psp_texture->data + rect->y * psp_texture->pitch +
411  rect->x * SDL_BYTESPERPIXEL(texture->format));
412  *pitch = psp_texture->pitch;
413  return 0;
414 }
415 
416 static void
417 PSP_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
418 {
419  PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata;
420  SDL_Rect rect;
421 
422  /* We do whole texture updates, at least for now */
423  rect.x = 0;
424  rect.y = 0;
425  rect.w = texture->w;
426  rect.h = texture->h;
427  PSP_UpdateTexture(renderer, texture, &rect, psp_texture->data, psp_texture->pitch);
428 }
429 
430 static void
431 PSP_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_ScaleMode scaleMode)
432 {
433  /* Nothing to do because TextureActivate takes care of it */
434 }
435 
436 static int
437 PSP_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
438 {
439  return 0;
440 }
441 
442 static int
443 PSP_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd)
444 {
445  return 0; /* nothing to do in this backend. */
446 }
447 
448 static int
449 PSP_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
450 {
451  VertV *verts = (VertV *) SDL_AllocateRenderVertices(renderer, count * sizeof (VertV), 4, &cmd->data.draw.first);
452  int i;
453 
454  if (!verts) {
455  return -1;
456  }
457 
458  cmd->data.draw.count = count;
459 
460  for (i = 0; i < count; i++, verts++, points++) {
461  verts->x = points->x;
462  verts->y = points->y;
463  verts->z = 0.0f;
464  }
465 
466  return 0;
467 }
468 
469 static int
470 PSP_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count)
471 {
472  VertV *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * 2 * sizeof (VertV), 4, &cmd->data.draw.first);
473  int i;
474 
475  if (!verts) {
476  return -1;
477  }
478 
479  cmd->data.draw.count = count;
480  for (i = 0; i < count; i++, rects++) {
481  const SDL_FRect *rect = &rects[i];
482  verts->x = rect->x;
483  verts->y = rect->y;
484  verts->z = 0.0f;
485  verts++;
486 
487  verts->x = rect->x + rect->w;
488  verts->y = rect->y + rect->h;
489  verts->z = 0.0f;
490  verts++;
491  }
492 
493  return 0;
494 }
495 
496 static int
498  const SDL_Rect * srcrect, const SDL_FRect * dstrect)
499 {
500  VertTV *verts;
501  const float x = dstrect->x;
502  const float y = dstrect->y;
503  const float width = dstrect->w;
504  const float height = dstrect->h;
505 
506  const float u0 = srcrect->x;
507  const float v0 = srcrect->y;
508  const float u1 = srcrect->x + srcrect->w;
509  const float v1 = srcrect->y + srcrect->h;
510 
511  if((MathAbs(u1) - MathAbs(u0)) < 64.0f)
512  {
513  verts = (VertTV *) SDL_AllocateRenderVertices(renderer, 2 * sizeof (VertTV), 4, &cmd->data.draw.first);
514  if (!verts) {
515  return -1;
516  }
517 
518  cmd->data.draw.count = 1;
519 
520  verts->u = u0;
521  verts->v = v0;
522  verts->x = x;
523  verts->y = y;
524  verts->z = 0;
525  verts++;
526 
527  verts->u = u1;
528  verts->v = v1;
529  verts->x = x + width;
530  verts->y = y + height;
531  verts->z = 0;
532  verts++;
533  }
534  else
535  {
536  float start, end;
537  float curU = u0;
538  float curX = x;
539  const float endX = x + width;
540  const float slice = 64.0f;
541  const size_t count = SDL_ceilf(width / slice);
542  size_t i;
543  float ustep = (u1 - u0)/width * slice;
544 
545  if(ustep < 0.0f)
546  ustep = -ustep;
547 
548  cmd->data.draw.count = count;
549 
550  verts = (VertTV *) SDL_AllocateRenderVertices(renderer, count * sizeof (VertTV), 4, &cmd->data.draw.first);
551  if (!verts) {
552  return -1;
553  }
554 
555 
556  for(i = 0, start = 0, end = width; i < count; i++, start += slice)
557  {
558  const float polyWidth = ((curX + slice) > endX) ? (endX - curX) : slice;
559  const float sourceWidth = ((curU + ustep) > u1) ? (u1 - curU) : ustep;
560 
561  SDL_assert(start < end);
562 
563  verts->u = curU;
564  verts->v = v0;
565  verts->x = curX;
566  verts->y = y;
567  verts->z = 0;
568 
569  curU += sourceWidth;
570  curX += polyWidth;
571 
572  verts->u = curU;
573  verts->v = v1;
574  verts->x = curX;
575  verts->y = (y + height);
576  verts->z = 0;
577  }
578  }
579 
580  return 0;
581 }
582 
583 static int
584 PSP_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
585  const SDL_Rect * srcrect, const SDL_FRect * dstrect,
586  const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
587 {
588  VertTV *verts = (VertTV *) SDL_AllocateRenderVertices(renderer, 4 * sizeof (VertTV), 4, &cmd->data.draw.first);
589  const float centerx = center->x;
590  const float centery = center->y;
591  const float x = dstrect->x + centerx;
592  const float y = dstrect->y + centery;
593  const float width = dstrect->w - centerx;
594  const float height = dstrect->h - centery;
595  float s, c;
596 
597  float u0 = srcrect->x;
598  float v0 = srcrect->y;
599  float u1 = srcrect->x + srcrect->w;
600  float v1 = srcrect->y + srcrect->h;
601 
602 
603  if (!verts) {
604  return -1;
605  }
606 
607  cmd->data.draw.count = 1;
608 
609  MathSincos(degToRad(angle), &s, &c);
610 
611  const float cw = c * width;
612  const float sw = s * width;
613  const float ch = c * height;
614  const float sh = s * height;
615 
616  if (flip & SDL_FLIP_VERTICAL) {
617  Swap(&v0, &v1);
618  }
619 
620  if (flip & SDL_FLIP_HORIZONTAL) {
621  Swap(&u0, &u1);
622  }
623 
624  verts->u = u0;
625  verts->v = v0;
626  verts->x = x - cw + sh;
627  verts->y = y - sw - ch;
628  verts->z = 0;
629  verts++;
630 
631  verts->u = u0;
632  verts->v = v1;
633  verts->x = x - cw - sh;
634  verts->y = y - sw + ch;
635  verts->z = 0;
636  verts++;
637 
638  verts->u = u1;
639  verts->v = v1;
640  verts->x = x + cw - sh;
641  verts->y = y + sw + ch;
642  verts->z = 0;
643  verts++;
644 
645  verts->u = u1;
646  verts->v = v0;
647  verts->x = x + cw + sh;
648  verts->y = y + sw - ch;
649  verts->z = 0;
650  verts++;
651 
652  return 0;
653 }
654 
655 static void
656 PSP_SetBlendMode(SDL_Renderer * renderer, int blendMode)
657 {
658  PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata;
659  if (blendMode != data-> currentBlendMode) {
660  switch (blendMode) {
661  case SDL_BLENDMODE_NONE:
662  sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
663  sceGuDisable(GU_BLEND);
664  break;
665  case SDL_BLENDMODE_BLEND:
666  sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
667  sceGuEnable(GU_BLEND);
668  sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0 );
669  break;
670  case SDL_BLENDMODE_ADD:
671  sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
672  sceGuEnable(GU_BLEND);
673  sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_FIX, 0, 0x00FFFFFF );
674  break;
675  case SDL_BLENDMODE_MOD:
676  sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
677  sceGuEnable(GU_BLEND);
678  sceGuBlendFunc(GU_ADD, GU_FIX, GU_SRC_COLOR, 0, 0);
679  break;
680  case SDL_BLENDMODE_MUL:
681  sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
682  sceGuEnable(GU_BLEND);
683  sceGuBlendFunc(GU_ADD, GU_DST_COLOR, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
684  break;
685  }
686  data->currentBlendMode = blendMode;
687  }
688 }
689 
690 static int
691 PSP_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
692 {
693  PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata;
694  size_t i;
695 
696  StartDrawing(renderer);
697 
698  /* note that before the renderer interface change, this would do extrememly small
699  batches with sceGuGetMemory()--a few vertices at a time--and it's not clear that
700  this won't fail if you try to push 100,000 draw calls in a single batch.
701  I don't know what the limits on PSP hardware are. It might be useful to have
702  rendering backends report a reasonable maximum, so the higher level can flush
703  if we appear to be exceeding that. */
704  Uint8 *gpumem = (Uint8 *) sceGuGetMemory(vertsize);
705  if (!gpumem) {
706  return SDL_SetError("Couldn't obtain a %d-byte vertex buffer!", (int) vertsize);
707  }
708  SDL_memcpy(gpumem, vertices, vertsize);
709 
710  while (cmd) {
711  switch (cmd->command) {
713  break; /* !!! FIXME: we could cache drawstate like color */
714  }
715 
717  SDL_Rect *viewport = &data->drawstate.viewport;
718  if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)) != 0) {
719  SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect));
720  data->drawstate.viewport_dirty = SDL_TRUE;
721  }
722  break;
723  }
724 
726  const SDL_Rect *rect = &cmd->data.cliprect.rect;
727  if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) {
728  data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled;
729  data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
730  }
731  if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) {
732  SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect));
733  data->drawstate.cliprect_dirty = SDL_TRUE;
734  }
735  break;
736  }
737 
738  case SDL_RENDERCMD_CLEAR: {
739  const Uint8 r = cmd->data.color.r;
740  const Uint8 g = cmd->data.color.g;
741  const Uint8 b = cmd->data.color.b;
742  const Uint8 a = cmd->data.color.a;
743  const Uint32 color = ((a << 24) | (b << 16) | (g << 8) | r);
744  /* !!! FIXME: we could cache drawstate like clear color */
745  sceGuClearColor(color);
746  sceGuClearDepth(0);
747  sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT|GU_FAST_CLEAR_BIT);
748  break;
749  }
750 
752  const size_t count = cmd->data.draw.count;
753  const VertV *verts = (VertV *) (gpumem + cmd->data.draw.first);
754  const Uint8 r = cmd->data.draw.r;
755  const Uint8 g = cmd->data.draw.g;
756  const Uint8 b = cmd->data.draw.b;
757  const Uint8 a = cmd->data.draw.a;
758  const Uint32 color = ((a << 24) | (b << 16) | (g << 8) | r);
759  /* !!! FIXME: we could cache draw state like color, texturing, etc */
760  sceGuColor(color);
761  sceGuDisable(GU_TEXTURE_2D);
762  sceGuShadeModel(GU_FLAT);
763  sceGuDrawArray(GU_POINTS, GU_VERTEX_32BITF|GU_TRANSFORM_2D, count, 0, verts);
764  sceGuShadeModel(GU_SMOOTH);
765  sceGuEnable(GU_TEXTURE_2D);
766  break;
767  }
768 
770  const size_t count = cmd->data.draw.count;
771  const VertV *verts = (VertV *) (gpumem + cmd->data.draw.first);
772  const Uint8 r = cmd->data.draw.r;
773  const Uint8 g = cmd->data.draw.g;
774  const Uint8 b = cmd->data.draw.b;
775  const Uint8 a = cmd->data.draw.a;
776  const Uint32 color = ((a << 24) | (b << 16) | (g << 8) | r);
777  /* !!! FIXME: we could cache draw state like color, texturing, etc */
778  sceGuColor(color);
779  sceGuDisable(GU_TEXTURE_2D);
780  sceGuShadeModel(GU_FLAT);
781  sceGuDrawArray(GU_LINE_STRIP, GU_VERTEX_32BITF|GU_TRANSFORM_2D, count, 0, verts);
782  sceGuShadeModel(GU_SMOOTH);
783  sceGuEnable(GU_TEXTURE_2D);
784  break;
785  }
786 
788  const size_t count = cmd->data.draw.count;
789  const VertV *verts = (VertV *) (gpumem + cmd->data.draw.first);
790  const Uint8 r = cmd->data.draw.r;
791  const Uint8 g = cmd->data.draw.g;
792  const Uint8 b = cmd->data.draw.b;
793  const Uint8 a = cmd->data.draw.a;
794  const Uint32 color = ((a << 24) | (b << 16) | (g << 8) | r);
795  /* !!! FIXME: we could cache draw state like color, texturing, etc */
796  sceGuColor(color);
797  sceGuDisable(GU_TEXTURE_2D);
798  sceGuShadeModel(GU_FLAT);
799  sceGuDrawArray(GU_SPRITES, GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2 * count, 0, verts);
800  sceGuShadeModel(GU_SMOOTH);
801  sceGuEnable(GU_TEXTURE_2D);
802  break;
803  }
804 
805  case SDL_RENDERCMD_COPY: {
806  const size_t count = cmd->data.draw.count;
807  const VertTV *verts = (VertTV *) (gpumem + cmd->data.draw.first);
808  const Uint8 alpha = cmd->data.draw.a;
809  TextureActivate(cmd->data.draw.texture);
810  PSP_SetBlendMode(renderer, cmd->data.draw.blend);
811 
812  if(alpha != 255) { /* !!! FIXME: is this right? */
813  sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
814  sceGuColor(GU_RGBA(255, 255, 255, alpha));
815  } else {
816  sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
817  sceGuColor(0xFFFFFFFF);
818  }
819 
820  sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2 * count, 0, verts);
821 
822  if(alpha != 255) {
823  sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
824  }
825  break;
826  }
827 
828  case SDL_RENDERCMD_COPY_EX: {
829  const VertTV *verts = (VertTV *) (gpumem + cmd->data.draw.first);
830  const Uint8 alpha = cmd->data.draw.a;
831  TextureActivate(cmd->data.draw.texture);
832  PSP_SetBlendMode(renderer, cmd->data.draw.blend);
833 
834  if(alpha != 255) { /* !!! FIXME: is this right? */
835  sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
836  sceGuColor(GU_RGBA(255, 255, 255, alpha));
837  } else {
838  sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
839  sceGuColor(0xFFFFFFFF);
840  }
841 
842  sceGuDrawArray(GU_TRIANGLE_FAN, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 4, 0, verts);
843 
844  if(alpha != 255) {
845  sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
846  }
847  break;
848  }
849 
850  case SDL_RENDERCMD_NO_OP:
851  break;
852  }
853 
854  cmd = cmd->next;
855  }
856 
857  return 0;
858 }
859 
860 static int
861 PSP_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
862  Uint32 pixel_format, void * pixels, int pitch)
863 {
864  return SDL_Unsupported();
865 }
866 
867 static void
868 PSP_RenderPresent(SDL_Renderer * renderer)
869 {
870  PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata;
871  if(!data->displayListAvail)
872  return;
873 
874  data->displayListAvail = SDL_FALSE;
875  sceGuFinish();
876  sceGuSync(0,0);
877 
878 /* if(data->vsync) */
879  sceDisplayWaitVblankStart();
880 
881  data->backbuffer = data->frontbuffer;
882  data->frontbuffer = vabsptr(sceGuSwapBuffers());
883 
884 }
885 
886 static void
887 PSP_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
888 {
889  PSP_RenderData *renderdata = (PSP_RenderData *) renderer->driverdata;
890  PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata;
891 
892  if (renderdata == 0)
893  return;
894 
895  if(psp_texture == 0)
896  return;
897 
898  SDL_free(psp_texture->data);
899  SDL_free(psp_texture);
900  texture->driverdata = NULL;
901 }
902 
903 static void
904 PSP_DestroyRenderer(SDL_Renderer * renderer)
905 {
906  PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata;
907  if (data) {
908  if (!data->initialized)
909  return;
910 
911  StartDrawing(renderer);
912 
913  sceGuTerm();
914 /* vfree(data->backbuffer); */
915 /* vfree(data->frontbuffer); */
916 
917  data->initialized = SDL_FALSE;
918  data->displayListAvail = SDL_FALSE;
919  SDL_free(data);
920  }
922 }
923 
924 SDL_Renderer *
925 PSP_CreateRenderer(SDL_Window * window, Uint32 flags)
926 {
927 
929  PSP_RenderData *data;
930  int pixelformat;
931  renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
932  if (!renderer) {
933  SDL_OutOfMemory();
934  return NULL;
935  }
936 
937  data = (PSP_RenderData *) SDL_calloc(1, sizeof(*data));
938  if (!data) {
939  PSP_DestroyRenderer(renderer);
940  SDL_OutOfMemory();
941  return NULL;
942  }
943 
944 
945  renderer->WindowEvent = PSP_WindowEvent;
946  renderer->CreateTexture = PSP_CreateTexture;
947  renderer->SetTextureColorMod = PSP_SetTextureColorMod;
948  renderer->UpdateTexture = PSP_UpdateTexture;
949  renderer->LockTexture = PSP_LockTexture;
950  renderer->UnlockTexture = PSP_UnlockTexture;
951  renderer->SetTextureScaleMode = PSP_SetTextureScaleMode;
952  renderer->SetRenderTarget = PSP_SetRenderTarget;
953  renderer->QueueSetViewport = PSP_QueueSetViewport;
954  renderer->QueueSetDrawColor = PSP_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */
955  renderer->QueueDrawPoints = PSP_QueueDrawPoints;
956  renderer->QueueDrawLines = PSP_QueueDrawPoints; /* lines and points queue vertices the same way. */
957  renderer->QueueFillRects = PSP_QueueFillRects;
958  renderer->QueueCopy = PSP_QueueCopy;
959  renderer->QueueCopyEx = PSP_QueueCopyEx;
960  renderer->RunCommandQueue = PSP_RunCommandQueue;
961  renderer->RenderReadPixels = PSP_RenderReadPixels;
962  renderer->RenderPresent = PSP_RenderPresent;
963  renderer->DestroyTexture = PSP_DestroyTexture;
964  renderer->DestroyRenderer = PSP_DestroyRenderer;
969 
970  if (data->initialized != SDL_FALSE)
971  return 0;
972  data->initialized = SDL_TRUE;
973 
975  data->vsync = SDL_TRUE;
976  } else {
977  data->vsync = SDL_FALSE;
978  }
979 
980  pixelformat=PixelFormatToPSPFMT(SDL_GetWindowPixelFormat(window));
981  switch(pixelformat)
982  {
983  case GU_PSM_4444:
984  case GU_PSM_5650:
985  case GU_PSM_5551:
986  data->frontbuffer = (unsigned int *)(PSP_FRAME_BUFFER_SIZE<<1);
987  data->backbuffer = (unsigned int *)(0);
988  data->bpp = 2;
989  data->psm = pixelformat;
990  break;
991  default:
992  data->frontbuffer = (unsigned int *)(PSP_FRAME_BUFFER_SIZE<<2);
993  data->backbuffer = (unsigned int *)(0);
994  data->bpp = 4;
995  data->psm = GU_PSM_8888;
996  break;
997  }
998 
999  sceGuInit();
1000  /* setup GU */
1001  sceGuStart(GU_DIRECT, DisplayList);
1002  sceGuDrawBuffer(data->psm, data->frontbuffer, PSP_FRAME_BUFFER_WIDTH);
1003  sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, data->backbuffer, PSP_FRAME_BUFFER_WIDTH);
1004 
1005 
1006  sceGuOffset(2048 - (PSP_SCREEN_WIDTH>>1), 2048 - (PSP_SCREEN_HEIGHT>>1));
1007  sceGuViewport(2048, 2048, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
1008 
1009  data->frontbuffer = vabsptr(data->frontbuffer);
1010  data->backbuffer = vabsptr(data->backbuffer);
1011 
1012  /* Scissoring */
1013  sceGuScissor(0, 0, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
1014  sceGuEnable(GU_SCISSOR_TEST);
1015 
1016  /* Backface culling */
1017  sceGuFrontFace(GU_CCW);
1018  sceGuEnable(GU_CULL_FACE);
1019 
1020  /* Texturing */
1021  sceGuEnable(GU_TEXTURE_2D);
1022  sceGuShadeModel(GU_SMOOTH);
1023  sceGuTexWrap(GU_REPEAT, GU_REPEAT);
1024 
1025  /* Blending */
1026  sceGuEnable(GU_BLEND);
1027  sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
1028 
1029  sceGuTexFilter(GU_LINEAR,GU_LINEAR);
1030 
1031  sceGuFinish();
1032  sceGuSync(0,0);
1033  sceDisplayWaitVblankStartCB();
1034  sceGuDisplay(GU_TRUE);
1035 
1036  return renderer;
1037 }
1038 
1040  .CreateRenderer = PSP_CreateRenderer,
1041  .info = {
1042  .name = "PSP",
1044  .num_texture_formats = 4,
1045  .texture_formats = { [0] = SDL_PIXELFORMAT_BGR565,
1049  },
1050  .max_texture_width = 512,
1051  .max_texture_height = 512,
1052  }
1053 };
1054 
1055 #endif /* SDL_VIDEO_RENDER_PSP */
1056 
1057 /* vi: set ts=4 sw=4 expandtab: */
1058 
#define SDL_assert(condition)
Definition: SDL_assert.h:171
@ SDL_BLENDMODE_NONE
Definition: SDL_blendmode.h:42
@ SDL_BLENDMODE_ADD
Definition: SDL_blendmode.h:47
@ SDL_BLENDMODE_BLEND
Definition: SDL_blendmode.h:44
@ SDL_BLENDMODE_MUL
Definition: SDL_blendmode.h:53
@ SDL_BLENDMODE_MOD
Definition: SDL_blendmode.h:50
#define SDL_SetError
#define SDL_GetWindowPixelFormat
#define SDL_ceilf
#define SDL_free
#define SDL_memcmp
#define SDL_memcpy
#define SDL_calloc
#define SDL_OutOfMemory()
Definition: SDL_error.h:88
#define SDL_Unsupported()
Definition: SDL_error.h:89
SDL_EventEntry * free
Definition: SDL_events.c:89
int uint32_t uint32_t uint32_t pixel_format
Definition: SDL_kmsdrmsym.h:52
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
float GLfloat
Definition: SDL_opengl.h:187
GLuint GLuint end
Definition: SDL_opengl.h:1571
const GLdouble * v
Definition: SDL_opengl.h:2064
GLuint GLuint GLsizei count
Definition: SDL_opengl.h:1571
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: SDL_opengl.h:1572
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
GLint GLint GLsizei width
Definition: SDL_opengl.h:1572
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1572
GLuint start
Definition: SDL_opengl.h:1571
GLdouble s
Definition: SDL_opengl.h:2063
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1572
GLboolean GLboolean GLboolean b
struct _cl_event * event
GLfixed GLfixed GLint GLint GLfixed points
GLenum src
GLfixed u1
GLuint64EXT * result
GLuint color
GLboolean GLboolean GLboolean GLboolean a
const GLubyte * c
GLenum GLenum dst
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
GLdouble GLdouble z
GLenum GLenum void * row
GLboolean GLboolean g
GLfloat angle
GLsizeiptr size
GLfloat v0
GLbitfield flags
GLfloat GLfloat v1
GLenum GLenum GLuint texture
GLuint GLsizei GLsizei * length
GLfloat GLfloat GLfloat alpha
GLdouble n
GLubyte GLubyte GLubyte GLubyte w
#define SDL_BYTESPERPIXEL(X)
Definition: SDL_pixels.h:128
@ SDL_PIXELFORMAT_BGR565
Definition: SDL_pixels.h:234
@ SDL_PIXELFORMAT_ABGR4444
Definition: SDL_pixels.h:213
@ SDL_PIXELFORMAT_ABGR8888
Definition: SDL_pixels.h:263
@ SDL_PIXELFORMAT_ABGR1555
Definition: SDL_pixels.h:225
#define malloc
Definition: SDL_qsort.c:46
void * SDL_AllocateRenderVertices(SDL_Renderer *renderer, const size_t numbytes, const size_t alignment, size_t *offset)
Definition: SDL_render.c:262
@ SDL_RENDERER_ACCELERATED
Definition: SDL_render.h:67
@ SDL_RENDERER_PRESENTVSYNC
Definition: SDL_render.h:69
@ SDL_RENDERER_TARGETTEXTURE
Definition: SDL_render.h:71
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
Definition: SDL_render.h:122
@ SDL_FLIP_VERTICAL
Definition: SDL_render.h:125
@ SDL_FLIP_HORIZONTAL
Definition: SDL_render.h:124
SDL_ScaleMode
The scaling mode for a texture.
Definition: SDL_render.h:92
@ SDL_ScaleModeNearest
Definition: SDL_render.h:93
SDL_bool
Definition: SDL_stdinc.h:168
@ SDL_TRUE
Definition: SDL_stdinc.h:170
@ SDL_FALSE
Definition: SDL_stdinc.h:169
uint8_t Uint8
Definition: SDL_stdinc.h:185
uint32_t Uint32
Definition: SDL_stdinc.h:209
SDL_RenderDriver PSP_RenderDriver
@ SDL_RENDERCMD_SETCLIPRECT
Definition: SDL_sysrender.h:70
@ SDL_RENDERCMD_DRAW_LINES
Definition: SDL_sysrender.h:74
@ SDL_RENDERCMD_SETVIEWPORT
Definition: SDL_sysrender.h:69
@ SDL_RENDERCMD_DRAW_POINTS
Definition: SDL_sysrender.h:73
@ SDL_RENDERCMD_NO_OP
Definition: SDL_sysrender.h:68
@ SDL_RENDERCMD_FILL_RECTS
Definition: SDL_sysrender.h:75
@ SDL_RENDERCMD_COPY
Definition: SDL_sysrender.h:76
@ SDL_RENDERCMD_CLEAR
Definition: SDL_sysrender.h:72
@ SDL_RENDERCMD_SETDRAWCOLOR
Definition: SDL_sysrender.h:71
@ SDL_RENDERCMD_COPY_EX
Definition: SDL_sysrender.h:77
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
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
#define NULL
Definition: begin_code.h:163
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
EGLSurface EGLint * rects
Definition: eglext.h:282
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 &reg2 endm macro vzip8 reg2 vzip d d &reg2 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 skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
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
The structure that defines a point (floating point)
Definition: SDL_rect.h:61
float x
Definition: SDL_rect.h:62
float y
Definition: SDL_rect.h:63
A rectangle, with the origin at the upper left (floating point).
Definition: SDL_rect.h:88
float h
Definition: SDL_rect.h:92
float x
Definition: SDL_rect.h:89
float w
Definition: SDL_rect.h:91
float y
Definition: SDL_rect.h:90
A rectangle, with the origin at the upper left (integer).
Definition: SDL_rect.h:78
int h
Definition: SDL_rect.h:80
int w
Definition: SDL_rect.h:80
int y
Definition: SDL_rect.h:79
int x
Definition: SDL_rect.h:79
struct SDL_RenderCommand::@38::@42 color
struct SDL_RenderCommand * next
struct SDL_RenderCommand::@38::@39 viewport
struct SDL_RenderCommand::@38::@41 draw
SDL_RenderCommandType command
Definition: SDL_sysrender.h:82
union SDL_RenderCommand::@38 data
struct SDL_RenderCommand::@38::@40 cliprect
SDL_RendererInfo info
SDL_Renderer *(* CreateRenderer)(SDL_Window *window, Uint32 flags)
int(* QueueCopy)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
SDL_Window * window
int(* QueueDrawLines)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
void(* SetTextureScaleMode)(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode)
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
void(* DestroyRenderer)(SDL_Renderer *renderer)
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
void(* RenderPresent)(SDL_Renderer *renderer)
int(* RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
int(* QueueDrawPoints)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
int(* QueueFillRects)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FRect *rects, int count)
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
int(* RunCommandQueue)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
int(* QueueCopyEx)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const SDL_Rect *srcquad, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* QueueSetViewport)(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
SDL_RendererInfo info
void * driverdata
int(* QueueSetDrawColor)(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
const char * name
Definition: SDL_render.h:80
Window state change event data (event.window.*)
Definition: SDL_events.h:202
The type used to identify a window.
Definition: SDL_sysvideo.h:75
static SDL_Renderer * renderer
static SDL_BlendMode blendMode
Definition: testdraw2.c:34
SDL_Rect rect
Definition: testrelative.c:27
static SDL_Rect viewport
Definition: testviewport.c:28