/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"

#if SDL_VIDEO_RENDER_PSP

#include "SDL_hints.h"
#include "../SDL_sysrender.h"

#include <pspkernel.h>
#include <pspdisplay.h>
#include <pspgu.h>
#include <pspgum.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <pspge.h>
#include <stdarg.h>
#include <stdlib.h>
#include <vram.h>




/* PSP renderer implementation, based on the PGE  */


extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags);


static SDL_Renderer *PSP_CreateRenderer(SDL_Window * window, Uint32 flags);
static void PSP_WindowEvent(SDL_Renderer * renderer,
                             const SDL_WindowEvent *event);
static int PSP_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
static int PSP_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
                              const SDL_Rect * rect, const void *pixels,
                              int pitch);
static int PSP_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
                            const SDL_Rect * rect, void **pixels, int *pitch);
static void PSP_UnlockTexture(SDL_Renderer * renderer,
                               SDL_Texture * texture);
static int PSP_SetRenderTarget(SDL_Renderer * renderer,
                                 SDL_Texture * texture);
static int PSP_UpdateViewport(SDL_Renderer * renderer);
static int PSP_RenderClear(SDL_Renderer * renderer);
static int PSP_RenderDrawPoints(SDL_Renderer * renderer,
                                 const SDL_FPoint * points, int count);
static int PSP_RenderDrawLines(SDL_Renderer * renderer,
                                const SDL_FPoint * points, int count);
static int PSP_RenderFillRects(SDL_Renderer * renderer,
                                const SDL_FRect * rects, int count);
static int PSP_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
                           const SDL_Rect * srcrect,
                           const SDL_FRect * dstrect);
static int PSP_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
                    Uint32 pixel_format, void * pixels, int pitch);
static int PSP_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
                         const SDL_Rect * srcrect, const SDL_FRect * dstrect,
                         const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip);
static void PSP_RenderPresent(SDL_Renderer * renderer);
static void PSP_DestroyTexture(SDL_Renderer * renderer,
                                SDL_Texture * texture);
static void PSP_DestroyRenderer(SDL_Renderer * renderer);

/*
SDL_RenderDriver PSP_RenderDriver = {
    PSP_CreateRenderer,
    {
     "PSP",
     (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE),
     1,
     {SDL_PIXELFORMAT_ABGR8888},
     0,
     0}
};
*/
SDL_RenderDriver PSP_RenderDriver = {
    .CreateRenderer = PSP_CreateRenderer,
    .info = {
        .name = "PSP",
        .flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE,
        .num_texture_formats = 4,
        .texture_formats = { [0] = SDL_PIXELFORMAT_BGR565,
                                                 [1] = SDL_PIXELFORMAT_ABGR1555,
                                                 [2] = SDL_PIXELFORMAT_ABGR4444,
                                                 [3] = SDL_PIXELFORMAT_ABGR8888,
        },
        .max_texture_width = 512,
        .max_texture_height = 512,
     }
};

#define PSP_SCREEN_WIDTH    480
#define PSP_SCREEN_HEIGHT   272

#define PSP_FRAME_BUFFER_WIDTH  512
#define PSP_FRAME_BUFFER_SIZE   (PSP_FRAME_BUFFER_WIDTH*PSP_SCREEN_HEIGHT)

static unsigned int __attribute__((aligned(16))) DisplayList[262144];


#define COL5650(r,g,b,a)    ((r>>3) | ((g>>2)<<5) | ((b>>3)<<11))
#define COL5551(r,g,b,a)    ((r>>3) | ((g>>3)<<5) | ((b>>3)<<10) | (a>0?0x7000:0))
#define COL4444(r,g,b,a)    ((r>>4) | ((g>>4)<<4) | ((b>>4)<<8) | ((a>>4)<<12))
#define COL8888(r,g,b,a)    ((r) | ((g)<<8) | ((b)<<16) | ((a)<<24))


typedef struct
{
    void*           frontbuffer ;
    void*           backbuffer ;
    SDL_bool        initialized ;
    SDL_bool        displayListAvail ;
    unsigned int    psm ;
    unsigned int    bpp ;

    SDL_bool        vsync;
    unsigned int    currentColor;
    int             currentBlendMode;

} PSP_RenderData;


typedef struct
{
    void                *data;                              /**< Image data. */
    unsigned int        size;                               /**< Size of data in bytes. */
    unsigned int        width;                              /**< Image width. */
    unsigned int        height;                             /**< Image height. */
    unsigned int        textureWidth;                       /**< Texture width (power of two). */
    unsigned int        textureHeight;                      /**< Texture height (power of two). */
    unsigned int        bits;                               /**< Image bits per pixel. */
    unsigned int        format;                             /**< Image format - one of ::pgePixelFormat. */
    unsigned int        pitch;
    SDL_bool            swizzled;                           /**< Is image swizzled. */

} PSP_TextureData;

typedef struct
{
    float   x, y, z;
} VertV;


typedef struct
{
    float   u, v;
    float   x, y, z;

} VertTV;


/* Return next power of 2 */
static int
TextureNextPow2(unsigned int w)
{
    if(w == 0)
        return 0;

    unsigned int n = 2;

    while(w > n)
        n <<= 1;

    return n;
}


static int
GetScaleQuality(void)
{
    const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);

    if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
        return GU_NEAREST; /* GU_NEAREST good for tile-map */
    } else {
        return GU_LINEAR; /* GU_LINEAR good for scaling */
    }
}

static int
PixelFormatToPSPFMT(Uint32 format)
{
    switch (format) {
    case SDL_PIXELFORMAT_BGR565:
        return GU_PSM_5650;
    case SDL_PIXELFORMAT_ABGR1555:
        return GU_PSM_5551;
    case SDL_PIXELFORMAT_ABGR4444:
        return GU_PSM_4444;
    case SDL_PIXELFORMAT_ABGR8888:
        return GU_PSM_8888;
    default:
        return GU_PSM_8888;
    }
}

void
StartDrawing(SDL_Renderer * renderer)
{
    PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata;
    if(data->displayListAvail)
        return;

    sceGuStart(GU_DIRECT, DisplayList);
    data->displayListAvail = SDL_TRUE;
}


int
TextureSwizzle(PSP_TextureData *psp_texture)
{
    if(psp_texture->swizzled)
        return 1;

    int bytewidth = psp_texture->textureWidth*(psp_texture->bits>>3);
    int height = psp_texture->size / bytewidth;

    int rowblocks = (bytewidth>>4);
    int rowblocksadd = (rowblocks-1)<<7;
    unsigned int blockaddress = 0;
    unsigned int *src = (unsigned int*) psp_texture->data;

    unsigned char *data = NULL;
    data = malloc(psp_texture->size);

    int j;

    for(j = 0; j < height; j++, blockaddress += 16)
    {
        unsigned int *block;

        block = (unsigned int*)&data[blockaddress];

        int i;

        for(i = 0; i < rowblocks; i++)
        {
            *block++ = *src++;
            *block++ = *src++;
            *block++ = *src++;
            *block++ = *src++;
            block += 28;
        }

        if((j & 0x7) == 0x7)
            blockaddress += rowblocksadd;
    }

    free(psp_texture->data);
    psp_texture->data = data;
    psp_texture->swizzled = SDL_TRUE;

    return 1;
}
int TextureUnswizzle(PSP_TextureData *psp_texture)
{
    if(!psp_texture->swizzled)
        return 1;

    int blockx, blocky;

    int bytewidth = psp_texture->textureWidth*(psp_texture->bits>>3);
    int height = psp_texture->size / bytewidth;

    int widthblocks = bytewidth/16;
    int heightblocks = height/8;

    int dstpitch = (bytewidth - 16)/4;
    int dstrow = bytewidth * 8;

    unsigned int *src = (unsigned int*) psp_texture->data;

    unsigned char *data = NULL;

    data = malloc(psp_texture->size);

    if(!data)
        return 0;

    sceKernelDcacheWritebackAll();

    int j;

    unsigned char *ydst = (unsigned char *)data;

    for(blocky = 0; blocky < heightblocks; ++blocky)
    {
        unsigned char *xdst = ydst;

        for(blockx = 0; blockx < widthblocks; ++blockx)
        {
            unsigned int *block;

            block = (unsigned int*)xdst;

            for(j = 0; j < 8; ++j)
            {
                *(block++) = *(src++);
                *(block++) = *(src++);
                *(block++) = *(src++);
                *(block++) = *(src++);
                block += dstpitch;
            }

            xdst += 16;
        }

        ydst += dstrow;
    }

    free(psp_texture->data);

    psp_texture->data = data;

    psp_texture->swizzled = SDL_FALSE;

    return 1;
}

SDL_Renderer *
PSP_CreateRenderer(SDL_Window * window, Uint32 flags)
{

    SDL_Renderer *renderer;
    PSP_RenderData *data;
        int pixelformat;
    renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
    if (!renderer) {
        SDL_OutOfMemory();
        return NULL;
    }

    data = (PSP_RenderData *) SDL_calloc(1, sizeof(*data));
    if (!data) {
        PSP_DestroyRenderer(renderer);
        SDL_OutOfMemory();
        return NULL;
    }


    renderer->WindowEvent = PSP_WindowEvent;
    renderer->CreateTexture = PSP_CreateTexture;
    renderer->UpdateTexture = PSP_UpdateTexture;
    renderer->LockTexture = PSP_LockTexture;
    renderer->UnlockTexture = PSP_UnlockTexture;
    renderer->SetRenderTarget = PSP_SetRenderTarget;
    renderer->UpdateViewport = PSP_UpdateViewport;
    renderer->RenderClear = PSP_RenderClear;
    renderer->RenderDrawPoints = PSP_RenderDrawPoints;
    renderer->RenderDrawLines = PSP_RenderDrawLines;
    renderer->RenderFillRects = PSP_RenderFillRects;
    renderer->RenderCopy = PSP_RenderCopy;
    renderer->RenderReadPixels = PSP_RenderReadPixels;
    renderer->RenderCopyEx = PSP_RenderCopyEx;
    renderer->RenderPresent = PSP_RenderPresent;
    renderer->DestroyTexture = PSP_DestroyTexture;
    renderer->DestroyRenderer = PSP_DestroyRenderer;
    renderer->info = PSP_RenderDriver.info;
    renderer->info.flags = SDL_RENDERER_ACCELERATED;
    renderer->driverdata = data;
    renderer->window = window;

    if (data->initialized != SDL_FALSE)
        return 0;
    data->initialized = SDL_TRUE;

    if (flags & SDL_RENDERER_PRESENTVSYNC) {
        data->vsync = SDL_TRUE;
    } else {
        data->vsync = SDL_FALSE;
    }

    pixelformat=PixelFormatToPSPFMT(SDL_GetWindowPixelFormat(window));
    switch(pixelformat)
    {
        case GU_PSM_4444:
        case GU_PSM_5650:
        case GU_PSM_5551:
            data->frontbuffer = (unsigned int *)(PSP_FRAME_BUFFER_SIZE<<1);
            data->backbuffer =  (unsigned int *)(0);
            data->bpp = 2;
            data->psm = pixelformat;
            break;
        default:
            data->frontbuffer = (unsigned int *)(PSP_FRAME_BUFFER_SIZE<<2);
            data->backbuffer =  (unsigned int *)(0);
            data->bpp = 4;
            data->psm = GU_PSM_8888;
            break;
    }

    sceGuInit();
    /* setup GU */
    sceGuStart(GU_DIRECT, DisplayList);
    sceGuDrawBuffer(data->psm, data->frontbuffer, PSP_FRAME_BUFFER_WIDTH);
    sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, data->backbuffer, PSP_FRAME_BUFFER_WIDTH);


    sceGuOffset(2048 - (PSP_SCREEN_WIDTH>>1), 2048 - (PSP_SCREEN_HEIGHT>>1));
    sceGuViewport(2048, 2048, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);

    data->frontbuffer = vabsptr(data->frontbuffer);
    data->backbuffer = vabsptr(data->backbuffer);

    /* Scissoring */
    sceGuScissor(0, 0, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
    sceGuEnable(GU_SCISSOR_TEST);

    /* Backface culling */
    sceGuFrontFace(GU_CCW);
    sceGuEnable(GU_CULL_FACE);

    /* Texturing */
    sceGuEnable(GU_TEXTURE_2D);
    sceGuShadeModel(GU_SMOOTH);
    sceGuTexWrap(GU_REPEAT, GU_REPEAT);

    /* Blending */
    sceGuEnable(GU_BLEND);
    sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);

    sceGuTexFilter(GU_LINEAR,GU_LINEAR);

    sceGuFinish();
    sceGuSync(0,0);
    sceDisplayWaitVblankStartCB();
    sceGuDisplay(GU_TRUE);

    return renderer;
}

static void
PSP_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
{

}


static int
PSP_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
/*      PSP_RenderData *renderdata = (PSP_RenderData *) renderer->driverdata; */
    PSP_TextureData* psp_texture = (PSP_TextureData*) SDL_calloc(1, sizeof(*psp_texture));;

    if(!psp_texture)
        return -1;

    psp_texture->swizzled = SDL_FALSE;
    psp_texture->width = texture->w;
    psp_texture->height = texture->h;
    psp_texture->textureHeight = TextureNextPow2(texture->h);
    psp_texture->textureWidth = TextureNextPow2(texture->w);
    psp_texture->format = PixelFormatToPSPFMT(texture->format);

    switch(psp_texture->format)
    {
        case GU_PSM_5650:
        case GU_PSM_5551:
        case GU_PSM_4444:
            psp_texture->bits = 16;
            break;

        case GU_PSM_8888:
            psp_texture->bits = 32;
            break;

        default:
            return -1;
    }

    psp_texture->pitch = psp_texture->textureWidth * SDL_BYTESPERPIXEL(texture->format);
    psp_texture->size = psp_texture->textureHeight*psp_texture->pitch;
    psp_texture->data = SDL_calloc(1, psp_texture->size);

    if(!psp_texture->data)
    {
        SDL_free(psp_texture);
        return SDL_OutOfMemory();
    }
    texture->driverdata = psp_texture;

    return 0;
}


void
TextureActivate(SDL_Texture * texture)
{
    PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata;
    int scaleMode = GetScaleQuality();

    /* Swizzling is useless with small textures. */
    if (texture->w >= 16 || texture->h >= 16)
    {
        TextureSwizzle(psp_texture);
    }

    sceGuEnable(GU_TEXTURE_2D);
    sceGuTexWrap(GU_REPEAT, GU_REPEAT);
    sceGuTexMode(psp_texture->format, 0, 0, psp_texture->swizzled);
    sceGuTexFilter(scaleMode, scaleMode); /* GU_NEAREST good for tile-map */
                                          /* GU_LINEAR good for scaling */
    sceGuTexImage(0, psp_texture->textureWidth, psp_texture->textureHeight, psp_texture->textureWidth, psp_texture->data);
    sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
}


static int
PSP_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
                   const SDL_Rect * rect, const void *pixels, int pitch)
{
/*  PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata; */
    const Uint8 *src;
    Uint8 *dst;
    int row, length,dpitch;
    src = pixels;

    PSP_LockTexture(renderer, texture,rect,(void **)&dst, &dpitch);
    length = rect->w * SDL_BYTESPERPIXEL(texture->format);
    if (length == pitch && length == dpitch) {
        SDL_memcpy(dst, src, length*rect->h);
    } else {
        for (row = 0; row < rect->h; ++row) {
            SDL_memcpy(dst, src, length);
            src += pitch;
            dst += dpitch;
        }
    }

    sceKernelDcacheWritebackAll();
    return 0;
}

static int
PSP_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
                 const SDL_Rect * rect, void **pixels, int *pitch)
{
    PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata;

    *pixels =
        (void *) ((Uint8 *) psp_texture->data + rect->y * psp_texture->pitch +
                  rect->x * SDL_BYTESPERPIXEL(texture->format));
    *pitch = psp_texture->pitch;
    return 0;
}

static void
PSP_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
    PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata;
    SDL_Rect rect;

    /* We do whole texture updates, at least for now */
    rect.x = 0;
    rect.y = 0;
    rect.w = texture->w;
    rect.h = texture->h;
    PSP_UpdateTexture(renderer, texture, &rect, psp_texture->data, psp_texture->pitch);
}

static int
PSP_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
{

    return 0;
}

static int
PSP_UpdateViewport(SDL_Renderer * renderer)
{

    return 0;
}


static void
PSP_SetBlendMode(SDL_Renderer * renderer, int blendMode)
{
    PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata;
    if (blendMode != data-> currentBlendMode) {
        switch (blendMode) {
        case SDL_BLENDMODE_NONE:
                sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
                sceGuDisable(GU_BLEND);
            break;
        case SDL_BLENDMODE_BLEND:
                sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
                sceGuEnable(GU_BLEND);
                sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0 );
            break;
        case SDL_BLENDMODE_ADD:
                sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
                sceGuEnable(GU_BLEND);
                sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_FIX, 0, 0x00FFFFFF );
            break;
        case SDL_BLENDMODE_MOD:
                sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
                sceGuEnable(GU_BLEND);
                sceGuBlendFunc( GU_ADD, GU_FIX, GU_SRC_COLOR, 0, 0);
            break;
        }
        data->currentBlendMode = blendMode;
    }
}



static int
PSP_RenderClear(SDL_Renderer * renderer)
{
    /* start list */
    StartDrawing(renderer);
    int color = renderer->a << 24 | renderer->b << 16 | renderer->g << 8 | renderer->r;
    sceGuClearColor(color);
    sceGuClearDepth(0);
    sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT|GU_FAST_CLEAR_BIT);

    return 0;
}

static int
PSP_RenderDrawPoints(SDL_Renderer * renderer, const SDL_FPoint * points,
                      int count)
{
    int color = renderer->a << 24 | renderer->b << 16 | renderer->g << 8 | renderer->r;
    int i;
    StartDrawing(renderer);
    VertV* vertices = (VertV*)sceGuGetMemory(count*sizeof(VertV));

    for (i = 0; i < count; ++i) {
            vertices[i].x = points[i].x;
            vertices[i].y = points[i].y;
            vertices[i].z = 0.0f;
    }
    sceGuDisable(GU_TEXTURE_2D);
    sceGuColor(color);
    sceGuShadeModel(GU_FLAT);
    sceGuDrawArray(GU_POINTS, GU_VERTEX_32BITF|GU_TRANSFORM_2D, count, 0, vertices);
    sceGuShadeModel(GU_SMOOTH);
    sceGuEnable(GU_TEXTURE_2D);

    return 0;
}

static int
PSP_RenderDrawLines(SDL_Renderer * renderer, const SDL_FPoint * points,
                     int count)
{
    int color = renderer->a << 24 | renderer->b << 16 | renderer->g << 8 | renderer->r;
    int i;
    StartDrawing(renderer);
    VertV* vertices = (VertV*)sceGuGetMemory(count*sizeof(VertV));

    for (i = 0; i < count; ++i) {
            vertices[i].x = points[i].x;
            vertices[i].y = points[i].y;
            vertices[i].z = 0.0f;
    }

    sceGuDisable(GU_TEXTURE_2D);
    sceGuColor(color);
    sceGuShadeModel(GU_FLAT);
    sceGuDrawArray(GU_LINE_STRIP, GU_VERTEX_32BITF|GU_TRANSFORM_2D, count, 0, vertices);
    sceGuShadeModel(GU_SMOOTH);
    sceGuEnable(GU_TEXTURE_2D);

    return 0;
}

static int
PSP_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects,
                     int count)
{
    int color = renderer->a << 24 | renderer->b << 16 | renderer->g << 8 | renderer->r;
    int i;
    StartDrawing(renderer);

    for (i = 0; i < count; ++i) {
        const SDL_FRect *rect = &rects[i];
        VertV* vertices = (VertV*)sceGuGetMemory((sizeof(VertV)<<1));
        vertices[0].x = rect->x;
        vertices[0].y = rect->y;
        vertices[0].z = 0.0f;

        vertices[1].x = rect->x + rect->w;
        vertices[1].y = rect->y + rect->h;
        vertices[1].z = 0.0f;

        sceGuDisable(GU_TEXTURE_2D);
        sceGuColor(color);
        sceGuShadeModel(GU_FLAT);
        sceGuDrawArray(GU_SPRITES, GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
        sceGuShadeModel(GU_SMOOTH);
        sceGuEnable(GU_TEXTURE_2D);
    }

    return 0;
}


#define PI   3.14159265358979f

#define radToDeg(x) ((x)*180.f/PI)
#define degToRad(x) ((x)*PI/180.f)

float MathAbs(float x)
{
    float result;

    __asm__ volatile (
        "mtv      %1, S000\n"
        "vabs.s   S000, S000\n"
        "mfv      %0, S000\n"
    : "=r"(result) : "r"(x));

    return result;
}

void MathSincos(float r, float *s, float *c)
{
    __asm__ volatile (
        "mtv      %2, S002\n"
        "vcst.s   S003, VFPU_2_PI\n"
        "vmul.s   S002, S002, S003\n"
        "vrot.p   C000, S002, [s, c]\n"
        "mfv      %0, S000\n"
        "mfv      %1, S001\n"
    : "=r"(*s), "=r"(*c): "r"(r));
}

void Swap(float *a, float *b)
{
    float n=*a;
    *a = *b;
    *b = n;
}

static int
PSP_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
                const SDL_Rect * srcrect, const SDL_FRect * dstrect)
{
    float x, y, width, height;
    float u0, v0, u1, v1;
    unsigned char alpha;

    x = dstrect->x;
    y = dstrect->y;
    width = dstrect->w;
    height = dstrect->h;

    u0 = srcrect->x;
    v0 = srcrect->y;
    u1 = srcrect->x + srcrect->w;
    v1 = srcrect->y + srcrect->h;

    alpha = texture->a;

    StartDrawing(renderer);
    TextureActivate(texture);
    PSP_SetBlendMode(renderer, renderer->blendMode);

    if(alpha != 255)
    {
        sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
        sceGuColor(GU_RGBA(255, 255, 255, alpha));
    }else{
        sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
        sceGuColor(0xFFFFFFFF);
    }

    if((MathAbs(u1) - MathAbs(u0)) < 64.0f)
    {
        VertTV* vertices = (VertTV*)sceGuGetMemory((sizeof(VertTV))<<1);

        vertices[0].u = u0;
        vertices[0].v = v0;
        vertices[0].x = x;
        vertices[0].y = y;
        vertices[0].z = 0;

        vertices[1].u = u1;
        vertices[1].v = v1;
        vertices[1].x = x + width;
        vertices[1].y = y + height;
        vertices[1].z = 0;

        sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
    }
    else
    {
        float start, end;
        float curU = u0;
        float curX = x;
        float endX = x + width;
        float slice = 64.0f;
        float ustep = (u1 - u0)/width * slice;

        if(ustep < 0.0f)
            ustep = -ustep;

        for(start = 0, end = width; start < end; start += slice)
        {
            VertTV* vertices = (VertTV*)sceGuGetMemory((sizeof(VertTV))<<1);

            float polyWidth = ((curX + slice) > endX) ? (endX - curX) : slice;
            float sourceWidth = ((curU + ustep) > u1) ? (u1 - curU) : ustep;

            vertices[0].u = curU;
            vertices[0].v = v0;
            vertices[0].x = curX;
            vertices[0].y = y;
            vertices[0].z = 0;

            curU += sourceWidth;
            curX += polyWidth;

            vertices[1].u = curU;
            vertices[1].v = v1;
            vertices[1].x = curX;
            vertices[1].y = (y + height);
            vertices[1].z = 0;

            sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
        }
    }

    if(alpha != 255)
        sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
    return 0;
}

static int
PSP_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
                    Uint32 pixel_format, void * pixels, int pitch)

{
        return 0;
}


static int
PSP_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
                const SDL_Rect * srcrect, const SDL_FRect * dstrect,
                const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
{
    float x, y, width, height;
    float u0, v0, u1, v1;
    unsigned char alpha;
    float centerx, centery;

    x = dstrect->x;
    y = dstrect->y;
    width = dstrect->w;
    height = dstrect->h;

    u0 = srcrect->x;
    v0 = srcrect->y;
    u1 = srcrect->x + srcrect->w;
    v1 = srcrect->y + srcrect->h;

    centerx = center->x;
    centery = center->y;

    alpha = texture->a;

    StartDrawing(renderer);
    TextureActivate(texture);
    PSP_SetBlendMode(renderer, renderer->blendMode);

    if(alpha != 255)
    {
        sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
        sceGuColor(GU_RGBA(255, 255, 255, alpha));
    }else{
        sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
        sceGuColor(0xFFFFFFFF);
    }

/*      x += width * 0.5f; */
/*      y += height * 0.5f; */
    x += centerx;
    y += centery;

    float c, s;

    MathSincos(degToRad(angle), &s, &c);

/*      width *= 0.5f; */
/*      height *= 0.5f; */
    width  -= centerx;
    height -= centery;


    float cw = c*width;
    float sw = s*width;
    float ch = c*height;
    float sh = s*height;

    VertTV* vertices = (VertTV*)sceGuGetMemory(sizeof(VertTV)<<2);

    vertices[0].u = u0;
    vertices[0].v = v0;
    vertices[0].x = x - cw + sh;
    vertices[0].y = y - sw - ch;
    vertices[0].z = 0;

    vertices[1].u = u0;
    vertices[1].v = v1;
    vertices[1].x = x - cw - sh;
    vertices[1].y = y - sw + ch;
    vertices[1].z = 0;

    vertices[2].u = u1;
    vertices[2].v = v1;
    vertices[2].x = x + cw - sh;
    vertices[2].y = y + sw + ch;
    vertices[2].z = 0;

    vertices[3].u = u1;
    vertices[3].v = v0;
    vertices[3].x = x + cw + sh;
    vertices[3].y = y + sw - ch;
    vertices[3].z = 0;

    if (flip & SDL_FLIP_HORIZONTAL) {
                Swap(&vertices[0].v, &vertices[2].v);
                Swap(&vertices[1].v, &vertices[3].v);
    }
    if (flip & SDL_FLIP_VERTICAL) {
                Swap(&vertices[0].u, &vertices[2].u);
                Swap(&vertices[1].u, &vertices[3].u);
    }

    sceGuDrawArray(GU_TRIANGLE_FAN, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 4, 0, vertices);

    if(alpha != 255)
        sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
    return 0;
}

static void
PSP_RenderPresent(SDL_Renderer * renderer)
{
    PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata;
    if(!data->displayListAvail)
        return;

    data->displayListAvail = SDL_FALSE;
    sceGuFinish();
    sceGuSync(0,0);

/*  if(data->vsync) */
        sceDisplayWaitVblankStart();

    data->backbuffer = data->frontbuffer;
    data->frontbuffer = vabsptr(sceGuSwapBuffers());

}

static void
PSP_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
    PSP_RenderData *renderdata = (PSP_RenderData *) renderer->driverdata;
    PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata;

    if (renderdata == 0)
        return;

    if(psp_texture == 0)
        return;

    SDL_free(psp_texture->data);
    SDL_free(psp_texture);
    texture->driverdata = NULL;
}

static void
PSP_DestroyRenderer(SDL_Renderer * renderer)
{
    PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata;
    if (data) {
        if (!data->initialized)
            return;

        StartDrawing(renderer);

        sceGuTerm();
/*      vfree(data->backbuffer); */
/*      vfree(data->frontbuffer); */

        data->initialized = SDL_FALSE;
        data->displayListAvail = SDL_FALSE;
        SDL_free(data);
    }
    SDL_free(renderer);
}

#endif /* SDL_VIDEO_RENDER_PSP */

/* vi: set ts=4 sw=4 expandtab: */

