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