Atlas - SDL_render_psp.c

Home / ext / SDL2 / src / render / psp Lines: 10 | Size: 28172 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2018 Sam Lantinga <[email protected]> 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 46extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags); 47 48 49static SDL_Renderer *PSP_CreateRenderer(SDL_Window * window, Uint32 flags); 50static void PSP_WindowEvent(SDL_Renderer * renderer, 51 const SDL_WindowEvent *event); 52static int PSP_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture); 53static int PSP_SetTextureColorMod(SDL_Renderer * renderer, 54 SDL_Texture * texture); 55static int PSP_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, 56 const SDL_Rect * rect, const void *pixels, 57 int pitch); 58static int PSP_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, 59 const SDL_Rect * rect, void **pixels, int *pitch); 60static void PSP_UnlockTexture(SDL_Renderer * renderer, 61 SDL_Texture * texture); 62static int PSP_SetRenderTarget(SDL_Renderer * renderer, 63 SDL_Texture * texture); 64static int PSP_UpdateViewport(SDL_Renderer * renderer); 65static int PSP_RenderClear(SDL_Renderer * renderer); 66static int PSP_RenderDrawPoints(SDL_Renderer * renderer, 67 const SDL_FPoint * points, int count); 68static int PSP_RenderDrawLines(SDL_Renderer * renderer, 69 const SDL_FPoint * points, int count); 70static int PSP_RenderFillRects(SDL_Renderer * renderer, 71 const SDL_FRect * rects, int count); 72static int PSP_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, 73 const SDL_Rect * srcrect, 74 const SDL_FRect * dstrect); 75static int PSP_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, 76 Uint32 pixel_format, void * pixels, int pitch); 77static 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); 80static void PSP_RenderPresent(SDL_Renderer * renderer); 81static void PSP_DestroyTexture(SDL_Renderer * renderer, 82 SDL_Texture * texture); 83static void PSP_DestroyRenderer(SDL_Renderer * renderer); 84 85/* 86SDL_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*/ 97SDL_RenderDriver PSP_RenderDriver = { 98 .CreateRenderer = PSP_CreateRenderer, 99 .info = { 100 .name = "PSP", 101 .flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE, 102 .num_texture_formats = 4, 103 .texture_formats = { [0] = SDL_PIXELFORMAT_BGR565, 104 [1] = SDL_PIXELFORMAT_ABGR1555, 105 [2] = SDL_PIXELFORMAT_ABGR4444, 106 [3] = SDL_PIXELFORMAT_ABGR8888, 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 119static 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 128typedef 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 144typedef 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 159typedef struct 160{ 161 float x, y, z; 162} VertV; 163 164 165typedef struct 166{ 167 float u, v; 168 float x, y, z; 169 170} VertTV; 171 172 173/* Return next power of 2 */ 174static int 175TextureNextPow2(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 189static int 190PixelFormatToPSPFMT(Uint32 format) 191{ 192 switch (format) { 193 case SDL_PIXELFORMAT_BGR565: 194 return GU_PSM_5650; 195 case SDL_PIXELFORMAT_ABGR1555: 196 return GU_PSM_5551; 197 case SDL_PIXELFORMAT_ABGR4444: 198 return GU_PSM_4444; 199 case SDL_PIXELFORMAT_ABGR8888: 200 return GU_PSM_8888; 201 default: 202 return GU_PSM_8888; 203 } 204} 205 206void 207StartDrawing(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 218int 219TextureSwizzle(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} 264int 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 329SDL_Renderer * 330PSP_CreateRenderer(SDL_Window * window, Uint32 flags) 331{ 332 333 SDL_Renderer *renderer; 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; 368 renderer->info = PSP_RenderDriver.info; 369 renderer->info.flags = (SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE); 370 renderer->driverdata = data; 371 renderer->window = window; 372 373 if (data->initialized != SDL_FALSE) 374 return 0; 375 data->initialized = SDL_TRUE; 376 377 if (flags & SDL_RENDERER_PRESENTVSYNC) { 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 442static void 443PSP_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) 444{ 445 446} 447 448 449static int 450PSP_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 495static int 496PSP_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture) 497{ 498 return SDL_Unsupported(); 499} 500 501void 502TextureActivate(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 523static int 524PSP_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) { 536 SDL_memcpy(dst, src, length*rect->h); 537 } else { 538 for (row = 0; row < rect->h; ++row) { 539 SDL_memcpy(dst, src, length); 540 src += pitch; 541 dst += dpitch; 542 } 543 } 544 545 sceKernelDcacheWritebackAll(); 546 return 0; 547} 548 549static int 550PSP_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 562static void 563PSP_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 576static int 577PSP_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) 578{ 579 580 return 0; 581} 582 583static int 584PSP_UpdateViewport(SDL_Renderer * renderer) 585{ 586 587 return 0; 588} 589 590 591static void 592PSP_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 623static int 624PSP_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 636static int 637PSP_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 660static int 661PSP_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 685static int 686PSP_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 721float 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 734void 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 746void Swap(float *a, float *b) 747{ 748 float n=*a; 749 *a = *b; 750 *b = n; 751} 752 753static int 754PSP_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 847static int 848PSP_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 856static int 857PSP_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 956static void 957PSP_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 975static void 976PSP_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 992static void 993PSP_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 1017
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.