mirror of
https://github.com/joel16/SDL2.git
synced 2024-11-23 11:19:42 +00:00
commit
a75dbad117
16
Makefile.main.psp
Normal file
16
Makefile.main.psp
Normal file
@ -0,0 +1,16 @@
|
||||
TARGET_LIB = libSDL2main.a
|
||||
|
||||
OBJS= src/main/psp/SDL_psp_main.o
|
||||
|
||||
INCDIR = ./include
|
||||
CFLAGS = -g -O2 -G0 -Wall -D__PSP__ -DHAVE_OPENGL
|
||||
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
|
||||
ASFLAGS = $(CFLAGS)
|
||||
|
||||
LIBDIR =
|
||||
LIBS = -lGL -lGLU -lglut -lz \
|
||||
-lpspvfpu -lpsphprm -lpspsdk -lpspctrl -lpspumd -lpsprtc -lpsppower -lpspgum -lpspgu -lpspaudiolib -lpspaudio -lpsphttp -lpspssl -lpspwlan \
|
||||
-lpspnet_adhocmatching -lpspnet_adhoc -lpspnet_adhocctl -lm -lpspvram
|
||||
|
||||
PSPSDK=$(shell psp-config --pspsdk-path)
|
||||
include $(PSPSDK)/lib/build.mak
|
@ -668,6 +668,9 @@ static const char *s_ControllerMappings [] =
|
||||
#endif
|
||||
#if defined(SDL_JOYSTICK_EMSCRIPTEN)
|
||||
"default,Standard Gamepad,a:b0,b:b1,back:b8,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b16,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
|
||||
#endif
|
||||
#if defined(SDL_JOYSTICK_PSP)
|
||||
"505350206275696c74696e206a6f7970,PSP builtin joypad,y:b0,b:b1,a:b2,x:b3,leftshoulder:b4,rightshoulder:b5,dpdown:b6,dpleft:b7,dpup:b8,dpright:b9,back:b10,start:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,",
|
||||
#endif
|
||||
"hidapi,*,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
|
||||
NULL
|
||||
|
@ -24,6 +24,7 @@
|
||||
*/
|
||||
|
||||
PSP_MODULE_INFO("SDL App", 0, 1, 1);
|
||||
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_VFPU | THREAD_ATTR_USER);
|
||||
|
||||
int sdl_psp_exit_callback(int arg1, int arg2, void *common)
|
||||
{
|
||||
|
@ -57,44 +57,19 @@ static unsigned int __attribute__((aligned(16))) DisplayList[262144];
|
||||
#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
|
||||
{
|
||||
SDL_Rect viewport;
|
||||
SDL_bool viewport_dirty;
|
||||
SDL_Texture *texture;
|
||||
SDL_Texture *target;
|
||||
int drawablew;
|
||||
int drawableh;
|
||||
SDL_BlendMode blend;
|
||||
SDL_bool cliprect_enabled_dirty;
|
||||
SDL_bool cliprect_enabled;
|
||||
SDL_bool cliprect_dirty;
|
||||
SDL_Rect cliprect;
|
||||
SDL_bool texturing;
|
||||
Uint32 color;
|
||||
Uint32 clear_color;
|
||||
} PSP_DrawStateCache;
|
||||
|
||||
|
||||
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_DrawStateCache drawstate;
|
||||
|
||||
} PSP_RenderData;
|
||||
|
||||
|
||||
typedef struct
|
||||
//#define LOGGING
|
||||
#ifdef LOGGING
|
||||
#define LOG(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define LOG(...)
|
||||
#endif
|
||||
/**
|
||||
* Holds psp specific texture data
|
||||
*
|
||||
* Part of a hot-list of textures that are used as render targets
|
||||
* When short of vram we spill Least-Recently-Used render targets to system memory
|
||||
*/
|
||||
typedef struct PSP_TextureData
|
||||
{
|
||||
void *data; /**< Image data. */
|
||||
unsigned int size; /**< Size of data in bytes. */
|
||||
@ -106,9 +81,35 @@ typedef struct
|
||||
unsigned int format; /**< Image format - one of ::pgePixelFormat. */
|
||||
unsigned int pitch;
|
||||
SDL_bool swizzled; /**< Is image swizzled. */
|
||||
|
||||
struct PSP_TextureData* prevhotw; /**< More recently used render target */
|
||||
struct PSP_TextureData* nexthotw; /**< Less recently used render target */
|
||||
} PSP_TextureData;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SDL_BlendMode mode;
|
||||
unsigned int color;
|
||||
int shadeModel;
|
||||
SDL_Texture* texture;
|
||||
} PSP_BlendState;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void* frontbuffer; /**< main screen buffer */
|
||||
void* backbuffer; /**< buffer presented to display */
|
||||
SDL_Texture* boundTarget; /**< currently bound rendertarget */
|
||||
SDL_bool initialized; /**< is driver initialized */
|
||||
SDL_bool displayListAvail; /**< is the display list already initialized for this frame */
|
||||
unsigned int psm; /**< format of the display buffers */
|
||||
unsigned int bpp; /**< bits per pixel of the main display */
|
||||
|
||||
SDL_bool vsync; /**< wether we do vsync */
|
||||
PSP_BlendState blendState; /**< current blend mode */
|
||||
PSP_TextureData* most_recent_target; /**< start of render target LRU double linked list */
|
||||
PSP_TextureData* least_recent_target; /**< end of the LRU list */
|
||||
} PSP_RenderData;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float x, y, z;
|
||||
@ -127,7 +128,8 @@ typedef struct
|
||||
#define radToDeg(x) ((x)*180.f/PI)
|
||||
#define degToRad(x) ((x)*PI/180.f)
|
||||
|
||||
float MathAbs(float x)
|
||||
static float
|
||||
MathAbs(float x)
|
||||
{
|
||||
float result;
|
||||
|
||||
@ -140,7 +142,8 @@ float MathAbs(float x)
|
||||
return result;
|
||||
}
|
||||
|
||||
void MathSincos(float r, float *s, float *c)
|
||||
static void
|
||||
MathSincos(float r, float *s, float *c)
|
||||
{
|
||||
__asm__ volatile (
|
||||
"mtv %2, S002\n"
|
||||
@ -152,13 +155,20 @@ void MathSincos(float r, float *s, float *c)
|
||||
: "=r"(*s), "=r"(*c): "r"(r));
|
||||
}
|
||||
|
||||
void Swap(float *a, float *b)
|
||||
static void
|
||||
Swap(float *a, float *b)
|
||||
{
|
||||
float n=*a;
|
||||
*a = *b;
|
||||
*b = n;
|
||||
}
|
||||
|
||||
static inline int
|
||||
InVram(void* data)
|
||||
{
|
||||
return data < (void*)0x04200000;
|
||||
}
|
||||
|
||||
/* Return next power of 2 */
|
||||
static int
|
||||
TextureNextPow2(unsigned int w)
|
||||
@ -192,20 +202,85 @@ PixelFormatToPSPFMT(Uint32 format)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StartDrawing(SDL_Renderer * renderer)
|
||||
{
|
||||
PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata;
|
||||
if(data->displayListAvail)
|
||||
return;
|
||||
|
||||
sceGuStart(GU_DIRECT, DisplayList);
|
||||
data->displayListAvail = SDL_TRUE;
|
||||
///SECTION render target LRU management
|
||||
static void
|
||||
LRUTargetRelink(PSP_TextureData* psp_texture) {
|
||||
if(psp_texture->prevhotw) {
|
||||
psp_texture->prevhotw->nexthotw = psp_texture->nexthotw;
|
||||
}
|
||||
if(psp_texture->nexthotw) {
|
||||
psp_texture->nexthotw->prevhotw = psp_texture->prevhotw;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
LRUTargetPushFront(PSP_RenderData* data, PSP_TextureData* psp_texture) {
|
||||
LOG("Pushing %p (%dKB) front.\n", (void*)psp_texture, psp_texture->size / 1024);
|
||||
psp_texture->nexthotw = data->most_recent_target;
|
||||
if(data->most_recent_target) {
|
||||
data->most_recent_target->prevhotw = psp_texture;
|
||||
}
|
||||
data->most_recent_target = psp_texture;
|
||||
if(!data->least_recent_target) {
|
||||
data->least_recent_target = psp_texture;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
TextureSwizzle(PSP_TextureData *psp_texture)
|
||||
static void
|
||||
LRUTargetRemove(PSP_RenderData* data, PSP_TextureData* psp_texture) {
|
||||
LOG("Removing %p (%dKB).\n", (void*)psp_texture, psp_texture->size/1024);
|
||||
LRUTargetRelink(psp_texture);
|
||||
if(data->most_recent_target == psp_texture) {
|
||||
data->most_recent_target = psp_texture->nexthotw;
|
||||
}
|
||||
if(data->least_recent_target == psp_texture) {
|
||||
data->least_recent_target = psp_texture->prevhotw;
|
||||
}
|
||||
psp_texture->prevhotw = NULL;
|
||||
psp_texture->nexthotw = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
LRUTargetBringFront(PSP_RenderData* data, PSP_TextureData* psp_texture) {
|
||||
//LOG("Bringing %p (%dKB) front.\n", (void*)psp_texture, psp_texture->size/1024);
|
||||
if(data->most_recent_target == psp_texture) {
|
||||
return; //nothing to do
|
||||
}
|
||||
LRUTargetRemove(data, psp_texture);
|
||||
LRUTargetPushFront(data, psp_texture);
|
||||
}
|
||||
|
||||
#ifdef LOGGING
|
||||
static void
|
||||
LRUWalk(PSP_RenderData* data) {
|
||||
PSP_TextureData* tex = data->most_recent_target;
|
||||
LOG("================\nLRU STATE:\n");
|
||||
size_t size = 0;
|
||||
while(tex) {
|
||||
LOG("Tex %p (%dKB)\n", (void*)tex, tex->size/1024);
|
||||
size+= tex->size;
|
||||
if(tex->nexthotw && tex->nexthotw->prevhotw != tex) {
|
||||
LOG("Spurious link!\n");
|
||||
}
|
||||
tex = tex->nexthotw;
|
||||
}
|
||||
LOG("Total Size : %dKB\n", size/1024);
|
||||
size_t latest_size = data->least_recent_target ? data->least_recent_target->size : 0;
|
||||
LOG("Least recent %p (%dKB)\n================\n", data->least_recent_target, latest_size / 1024);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
TextureStorageFree(void* storage) {
|
||||
if(InVram(storage)) {
|
||||
vfree(storage);
|
||||
} else {
|
||||
SDL_free(storage);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
TextureSwizzle(PSP_TextureData *psp_texture, void* dst)
|
||||
{
|
||||
if(psp_texture->swizzled)
|
||||
return 1;
|
||||
@ -218,8 +293,14 @@ TextureSwizzle(PSP_TextureData *psp_texture)
|
||||
unsigned int blockaddress = 0;
|
||||
unsigned int *src = (unsigned int*) psp_texture->data;
|
||||
|
||||
unsigned char *data = NULL;
|
||||
data = malloc(psp_texture->size);
|
||||
unsigned char *data = dst;
|
||||
if(!data) {
|
||||
data = SDL_malloc(psp_texture->size);
|
||||
}
|
||||
|
||||
if(!data) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
int j;
|
||||
|
||||
@ -244,13 +325,16 @@ TextureSwizzle(PSP_TextureData *psp_texture)
|
||||
blockaddress += rowblocksadd;
|
||||
}
|
||||
|
||||
free(psp_texture->data);
|
||||
TextureStorageFree(psp_texture->data);
|
||||
psp_texture->data = data;
|
||||
psp_texture->swizzled = SDL_TRUE;
|
||||
|
||||
sceKernelDcacheWritebackRange(psp_texture->data, psp_texture->size);
|
||||
return 1;
|
||||
}
|
||||
int TextureUnswizzle(PSP_TextureData *psp_texture)
|
||||
|
||||
static int
|
||||
TextureUnswizzle(PSP_TextureData *psp_texture, void* dst)
|
||||
{
|
||||
if(!psp_texture->swizzled)
|
||||
return 1;
|
||||
@ -268,14 +352,14 @@ int TextureUnswizzle(PSP_TextureData *psp_texture)
|
||||
|
||||
unsigned int *src = (unsigned int*) psp_texture->data;
|
||||
|
||||
unsigned char *data = NULL;
|
||||
unsigned char *data = dst;
|
||||
|
||||
data = malloc(psp_texture->size);
|
||||
if(!data) {
|
||||
data = SDL_malloc(psp_texture->size);
|
||||
}
|
||||
|
||||
if(!data)
|
||||
return 0;
|
||||
|
||||
sceKernelDcacheWritebackAll();
|
||||
return SDL_OutOfMemory();
|
||||
|
||||
int j;
|
||||
|
||||
@ -306,15 +390,113 @@ int TextureUnswizzle(PSP_TextureData *psp_texture)
|
||||
ydst += dstrow;
|
||||
}
|
||||
|
||||
free(psp_texture->data);
|
||||
TextureStorageFree(psp_texture->data);
|
||||
|
||||
psp_texture->data = data;
|
||||
|
||||
psp_texture->swizzled = SDL_FALSE;
|
||||
|
||||
sceKernelDcacheWritebackRange(psp_texture->data, psp_texture->size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
TextureSpillToSram(PSP_RenderData* data, PSP_TextureData* psp_texture)
|
||||
{
|
||||
// Assumes the texture is in VRAM
|
||||
if(psp_texture->swizzled) {
|
||||
//Texture was swizzled in vram, just copy to system memory
|
||||
void* data = SDL_malloc(psp_texture->size);
|
||||
if(!data) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
SDL_memcpy(data, psp_texture->data, psp_texture->size);
|
||||
vfree(psp_texture->data);
|
||||
psp_texture->data = data;
|
||||
|
||||
sceKernelDcacheWritebackRange(psp_texture->data, psp_texture->size);
|
||||
return 0;
|
||||
} else {
|
||||
return TextureSwizzle(psp_texture, NULL); //Will realloc in sysram
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
TexturePromoteToVram(PSP_RenderData* data, PSP_TextureData* psp_texture, SDL_bool target)
|
||||
{
|
||||
// Assumes texture in sram and a large enough continuous block in vram
|
||||
void* tdata = valloc(psp_texture->size);
|
||||
if(psp_texture->swizzled && target) {
|
||||
return TextureUnswizzle(psp_texture, tdata);
|
||||
} else {
|
||||
SDL_memcpy(tdata, psp_texture->data, psp_texture->size);
|
||||
SDL_free(psp_texture->data);
|
||||
psp_texture->data = tdata;
|
||||
sceKernelDcacheWritebackRange(psp_texture->data, psp_texture->size);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
TextureSpillLRU(PSP_RenderData* data, size_t wanted) {
|
||||
PSP_TextureData* lru = data->least_recent_target;
|
||||
if(lru) {
|
||||
if(TextureSpillToSram(data, lru) < 0) {
|
||||
return -1;
|
||||
}
|
||||
LOG("Spilled %p (%dKB) to ram\n", (void*)lru, lru->size/1024);
|
||||
LRUTargetRemove(data, lru);
|
||||
#ifdef LOGGING
|
||||
LRUWalk(data);
|
||||
#endif
|
||||
} else {
|
||||
SDL_SetError("Could not spill more VRAM to system memory. VRAM : %dKB,(%dKB), wanted %dKB", vmemavail()/1024, vlargestblock()/1024, wanted/1024);
|
||||
return -1; //Asked to spill but there nothing to spill
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
TextureSpillTargetsForSpace(PSP_RenderData* data, size_t size)
|
||||
{
|
||||
while(vlargestblock() < size) {
|
||||
if(TextureSpillLRU(data, size) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
TextureBindAsTarget(PSP_RenderData* data, PSP_TextureData* psp_texture) {
|
||||
if(!InVram(psp_texture->data)) {
|
||||
// Bring back the texture in vram
|
||||
if(TextureSpillTargetsForSpace(data, psp_texture->size) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if(TexturePromoteToVram(data, psp_texture, SDL_TRUE) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
LRUTargetBringFront(data, psp_texture);
|
||||
//LRUWalk(data);
|
||||
sceGuDrawBufferList(psp_texture->format, vrelptr(psp_texture->data), psp_texture->textureWidth);
|
||||
// Stencil alpha dst hack
|
||||
unsigned int dstFormat = psp_texture->format;
|
||||
if(dstFormat == GU_PSM_5551) {
|
||||
sceGuEnable(GU_STENCIL_TEST);
|
||||
sceGuStencilOp(GU_REPLACE, GU_REPLACE, GU_REPLACE);
|
||||
sceGuStencilFunc(GU_GEQUAL, 0xff, 0xff);
|
||||
sceGuEnable(GU_ALPHA_TEST);
|
||||
sceGuAlphaFunc(GU_GREATER, 0x00, 0xff);
|
||||
} else {
|
||||
sceGuDisable(GU_STENCIL_TEST);
|
||||
sceGuDisable(GU_ALPHA_TEST);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
PSP_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
|
||||
{
|
||||
@ -324,11 +506,11 @@ 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_RenderData *data = renderer->driverdata;
|
||||
PSP_TextureData* psp_texture = (PSP_TextureData*) SDL_calloc(1, sizeof(*psp_texture));
|
||||
|
||||
if(!psp_texture)
|
||||
return -1;
|
||||
return SDL_OutOfMemory();
|
||||
|
||||
psp_texture->swizzled = SDL_FALSE;
|
||||
psp_texture->width = texture->w;
|
||||
@ -355,7 +537,20 @@ PSP_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
|
||||
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(texture->access & SDL_TEXTUREACCESS_TARGET) {
|
||||
if(TextureSpillTargetsForSpace(renderer->driverdata, psp_texture->size) < 0){
|
||||
return -1;
|
||||
}
|
||||
psp_texture->data = valloc(psp_texture->size);
|
||||
if(psp_texture->data) {
|
||||
LRUTargetPushFront(data, psp_texture);
|
||||
#ifdef LOGGING
|
||||
LRUWalk(data);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
psp_texture->data = SDL_calloc(1, psp_texture->size);
|
||||
}
|
||||
|
||||
if(!psp_texture->data)
|
||||
{
|
||||
@ -373,25 +568,32 @@ PSP_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
return SDL_Unsupported();
|
||||
}*/
|
||||
|
||||
void
|
||||
|
||||
|
||||
static int
|
||||
TextureShouldSwizzle(PSP_TextureData* psp_texture, SDL_Texture *texture)
|
||||
{
|
||||
return !((texture->access == SDL_TEXTUREACCESS_TARGET) && InVram(psp_texture->data))
|
||||
&& (texture->w >= 16 || texture->h >= 16);
|
||||
}
|
||||
|
||||
static void
|
||||
TextureActivate(SDL_Texture * texture)
|
||||
{
|
||||
PSP_TextureData *psp_texture = (PSP_TextureData *) texture->driverdata;
|
||||
int scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? GU_NEAREST : GU_LINEAR;
|
||||
|
||||
/* Swizzling is useless with small textures. */
|
||||
if (texture->w >= 16 || texture->h >= 16)
|
||||
if (TextureShouldSwizzle(psp_texture, texture))
|
||||
{
|
||||
TextureSwizzle(psp_texture);
|
||||
TextureSwizzle(psp_texture, NULL);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@ -568,7 +770,7 @@ PSP_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * tex
|
||||
|
||||
cmd->data.draw.count = count;
|
||||
|
||||
verts = (VertTV *) SDL_AllocateRenderVertices(renderer, count * sizeof (VertTV), 4, &cmd->data.draw.first);
|
||||
verts = (VertTV *) SDL_AllocateRenderVertices(renderer, count * 2 * sizeof (VertTV), 4, &cmd->data.draw.first);
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
@ -586,6 +788,7 @@ PSP_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * tex
|
||||
verts->x = curX;
|
||||
verts->y = y;
|
||||
verts->z = 0;
|
||||
verts++;
|
||||
|
||||
curU += sourceWidth;
|
||||
curX += polyWidth;
|
||||
@ -595,6 +798,7 @@ PSP_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * tex
|
||||
verts->x = curX;
|
||||
verts->y = (y + height);
|
||||
verts->z = 0;
|
||||
verts++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -674,38 +878,98 @@ PSP_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * t
|
||||
}
|
||||
|
||||
static void
|
||||
PSP_SetBlendMode(SDL_Renderer * renderer, int blendMode)
|
||||
ResetBlendState(PSP_BlendState* state) {
|
||||
sceGuColor(0xffffffff);
|
||||
state->color = 0xffffffff;
|
||||
state->mode = SDL_BLENDMODE_INVALID;
|
||||
state->texture = NULL;
|
||||
sceGuDisable(GU_TEXTURE_2D);
|
||||
sceGuShadeModel(GU_SMOOTH);
|
||||
state->shadeModel = GU_SMOOTH;
|
||||
}
|
||||
|
||||
static void
|
||||
StartDrawing(SDL_Renderer * renderer)
|
||||
{
|
||||
PSP_RenderData *data = (PSP_RenderData *) renderer->driverdata;
|
||||
if (blendMode != data-> currentBlendMode) {
|
||||
switch (blendMode) {
|
||||
|
||||
// Check if we need to start GU displaylist
|
||||
if(!data->displayListAvail) {
|
||||
sceGuStart(GU_DIRECT, DisplayList);
|
||||
data->displayListAvail = SDL_TRUE;
|
||||
//ResetBlendState(&data->blendState);
|
||||
}
|
||||
|
||||
// Check if we need a draw buffer change
|
||||
if(renderer->target != data->boundTarget) {
|
||||
SDL_Texture* texture = renderer->target;
|
||||
if(texture) {
|
||||
PSP_TextureData* psp_texture = (PSP_TextureData*) texture->driverdata;
|
||||
// Set target, registering LRU
|
||||
TextureBindAsTarget(data, psp_texture);
|
||||
} else {
|
||||
// Set target back to screen
|
||||
sceGuDrawBufferList(data->psm, vrelptr(data->frontbuffer), PSP_FRAME_BUFFER_WIDTH);
|
||||
}
|
||||
data->boundTarget = texture;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
PSP_SetBlendState(PSP_RenderData* data, PSP_BlendState* state)
|
||||
{
|
||||
PSP_BlendState* current = &data->blendState;
|
||||
|
||||
if (state->mode != current->mode) {
|
||||
switch (state->mode) {
|
||||
case SDL_BLENDMODE_NONE:
|
||||
sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
|
||||
sceGuDisable(GU_BLEND);
|
||||
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 );
|
||||
sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
|
||||
sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0 );
|
||||
sceGuEnable(GU_BLEND);
|
||||
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 );
|
||||
sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
|
||||
sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_FIX, 0, 0x00FFFFFF );
|
||||
sceGuEnable(GU_BLEND);
|
||||
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);
|
||||
sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
|
||||
sceGuBlendFunc(GU_ADD, GU_FIX, GU_SRC_COLOR, 0, 0);
|
||||
sceGuEnable(GU_BLEND);
|
||||
break;
|
||||
case SDL_BLENDMODE_MUL:
|
||||
sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
|
||||
sceGuEnable(GU_BLEND);
|
||||
sceGuBlendFunc(GU_ADD, GU_DST_COLOR, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
|
||||
sceGuTexFunc(GU_TFX_MODULATE , GU_TCC_RGBA);
|
||||
sceGuBlendFunc(GU_ADD, GU_DST_COLOR, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
|
||||
sceGuEnable(GU_BLEND);
|
||||
break;
|
||||
case SDL_BLENDMODE_INVALID:
|
||||
break;
|
||||
}
|
||||
data->currentBlendMode = blendMode;
|
||||
}
|
||||
|
||||
if(state->color != current->color) {
|
||||
sceGuColor(state->color);
|
||||
}
|
||||
|
||||
if(state->shadeModel != current->shadeModel) {
|
||||
sceGuShadeModel(state->shadeModel);
|
||||
}
|
||||
|
||||
if(state->texture != current->texture) {
|
||||
if(state->texture != NULL) {
|
||||
TextureActivate(state->texture);
|
||||
sceGuEnable(GU_TEXTURE_2D);
|
||||
} else {
|
||||
sceGuDisable(GU_TEXTURE_2D);
|
||||
}
|
||||
}
|
||||
|
||||
*current = *state;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -734,23 +998,20 @@ PSP_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_SETVIEWPORT: {
|
||||
SDL_Rect *viewport = &data->drawstate.viewport;
|
||||
if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)) != 0) {
|
||||
SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect));
|
||||
data->drawstate.viewport_dirty = SDL_TRUE;
|
||||
}
|
||||
SDL_Rect *viewport = &cmd->data.viewport.rect;
|
||||
sceGuOffset(2048 - (viewport->w >> 1), 2048 - (viewport->h >> 1));
|
||||
sceGuViewport(2048, 2048, viewport->w, viewport->h);
|
||||
sceGuScissor(viewport->x, viewport->y, viewport->w, viewport->h);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_SETCLIPRECT: {
|
||||
const SDL_Rect *rect = &cmd->data.cliprect.rect;
|
||||
if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) {
|
||||
data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled;
|
||||
data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
|
||||
}
|
||||
if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) {
|
||||
SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect));
|
||||
data->drawstate.cliprect_dirty = SDL_TRUE;
|
||||
if(cmd->data.cliprect.enabled){
|
||||
sceGuEnable(GU_SCISSOR_TEST);
|
||||
sceGuScissor(rect->x, rect->y, rect->w, rect->h);
|
||||
} else {
|
||||
sceGuDisable(GU_SCISSOR_TEST);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -760,11 +1021,9 @@ PSP_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti
|
||||
const Uint8 g = cmd->data.color.g;
|
||||
const Uint8 b = cmd->data.color.b;
|
||||
const Uint8 a = cmd->data.color.a;
|
||||
const Uint32 color = ((a << 24) | (b << 16) | (g << 8) | r);
|
||||
/* !!! FIXME: we could cache drawstate like clear color */
|
||||
sceGuClearColor(color);
|
||||
sceGuClearDepth(0);
|
||||
sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT|GU_FAST_CLEAR_BIT);
|
||||
sceGuClearColor(GU_RGBA(r,g,b,a));
|
||||
sceGuClearStencil(a);
|
||||
sceGuClear(GU_COLOR_BUFFER_BIT | GU_STENCIL_BUFFER_BIT);//|GU_FAST_CLEAR_BIT);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -775,14 +1034,15 @@ PSP_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti
|
||||
const Uint8 g = cmd->data.draw.g;
|
||||
const Uint8 b = cmd->data.draw.b;
|
||||
const Uint8 a = cmd->data.draw.a;
|
||||
const Uint32 color = ((a << 24) | (b << 16) | (g << 8) | r);
|
||||
/* !!! FIXME: we could cache draw state like color, texturing, etc */
|
||||
sceGuColor(color);
|
||||
sceGuDisable(GU_TEXTURE_2D);
|
||||
sceGuShadeModel(GU_FLAT);
|
||||
|
||||
PSP_BlendState state = {
|
||||
.color = GU_RGBA(r,g,b,a),
|
||||
.texture = NULL,
|
||||
.mode = cmd->data.draw.blend,
|
||||
.shadeModel = GU_FLAT
|
||||
};
|
||||
PSP_SetBlendState(data, &state);
|
||||
sceGuDrawArray(GU_POINTS, GU_VERTEX_32BITF|GU_TRANSFORM_2D, count, 0, verts);
|
||||
sceGuShadeModel(GU_SMOOTH);
|
||||
sceGuEnable(GU_TEXTURE_2D);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -793,14 +1053,14 @@ PSP_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti
|
||||
const Uint8 g = cmd->data.draw.g;
|
||||
const Uint8 b = cmd->data.draw.b;
|
||||
const Uint8 a = cmd->data.draw.a;
|
||||
const Uint32 color = ((a << 24) | (b << 16) | (g << 8) | r);
|
||||
/* !!! FIXME: we could cache draw state like color, texturing, etc */
|
||||
sceGuColor(color);
|
||||
sceGuDisable(GU_TEXTURE_2D);
|
||||
sceGuShadeModel(GU_FLAT);
|
||||
PSP_BlendState state = {
|
||||
.color = GU_RGBA(r,g,b,a),
|
||||
.texture = NULL,
|
||||
.mode = cmd->data.draw.blend,
|
||||
.shadeModel = GU_FLAT
|
||||
};
|
||||
PSP_SetBlendState(data, &state);
|
||||
sceGuDrawArray(GU_LINE_STRIP, GU_VERTEX_32BITF|GU_TRANSFORM_2D, count, 0, verts);
|
||||
sceGuShadeModel(GU_SMOOTH);
|
||||
sceGuEnable(GU_TEXTURE_2D);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -811,59 +1071,49 @@ PSP_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti
|
||||
const Uint8 g = cmd->data.draw.g;
|
||||
const Uint8 b = cmd->data.draw.b;
|
||||
const Uint8 a = cmd->data.draw.a;
|
||||
const Uint32 color = ((a << 24) | (b << 16) | (g << 8) | r);
|
||||
/* !!! FIXME: we could cache draw state like color, texturing, etc */
|
||||
sceGuColor(color);
|
||||
sceGuDisable(GU_TEXTURE_2D);
|
||||
sceGuShadeModel(GU_FLAT);
|
||||
PSP_BlendState state = {
|
||||
.color = GU_RGBA(r,g,b,a),
|
||||
.texture = NULL,
|
||||
.mode = cmd->data.draw.blend,
|
||||
.shadeModel = GU_FLAT
|
||||
};
|
||||
PSP_SetBlendState(data, &state);
|
||||
sceGuDrawArray(GU_SPRITES, GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2 * count, 0, verts);
|
||||
sceGuShadeModel(GU_SMOOTH);
|
||||
sceGuEnable(GU_TEXTURE_2D);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_COPY: {
|
||||
const size_t count = cmd->data.draw.count;
|
||||
const VertTV *verts = (VertTV *) (gpumem + cmd->data.draw.first);
|
||||
const Uint8 alpha = cmd->data.draw.a;
|
||||
TextureActivate(cmd->data.draw.texture);
|
||||
PSP_SetBlendMode(renderer, cmd->data.draw.blend);
|
||||
|
||||
if(alpha != 255) { /* !!! FIXME: is this right? */
|
||||
sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
|
||||
sceGuColor(GU_RGBA(255, 255, 255, alpha));
|
||||
} else {
|
||||
sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
|
||||
sceGuColor(0xFFFFFFFF);
|
||||
}
|
||||
|
||||
const Uint8 a = cmd->data.draw.a;
|
||||
const Uint8 r = cmd->data.draw.r;
|
||||
const Uint8 g = cmd->data.draw.g;
|
||||
const Uint8 b = cmd->data.draw.b;
|
||||
PSP_BlendState state = {
|
||||
.color = GU_RGBA(r,g,b,a),
|
||||
.texture = cmd->data.draw.texture,
|
||||
.mode = cmd->data.draw.blend,
|
||||
.shadeModel = GU_SMOOTH
|
||||
};
|
||||
PSP_SetBlendState(data, &state);
|
||||
sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2 * count, 0, verts);
|
||||
|
||||
if(alpha != 255) {
|
||||
sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_COPY_EX: {
|
||||
const VertTV *verts = (VertTV *) (gpumem + cmd->data.draw.first);
|
||||
const Uint8 alpha = cmd->data.draw.a;
|
||||
TextureActivate(cmd->data.draw.texture);
|
||||
PSP_SetBlendMode(renderer, cmd->data.draw.blend);
|
||||
|
||||
if(alpha != 255) { /* !!! FIXME: is this right? */
|
||||
sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
|
||||
sceGuColor(GU_RGBA(255, 255, 255, alpha));
|
||||
} else {
|
||||
sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
|
||||
sceGuColor(0xFFFFFFFF);
|
||||
}
|
||||
|
||||
const Uint8 a = cmd->data.draw.a;
|
||||
const Uint8 r = cmd->data.draw.r;
|
||||
const Uint8 g = cmd->data.draw.g;
|
||||
const Uint8 b = cmd->data.draw.b;
|
||||
PSP_BlendState state = {
|
||||
.color = GU_RGBA(r,g,b,a),
|
||||
.texture = cmd->data.draw.texture,
|
||||
.mode = cmd->data.draw.blend,
|
||||
.shadeModel = GU_SMOOTH
|
||||
};
|
||||
PSP_SetBlendState(data, &state);
|
||||
sceGuDrawArray(GU_TRIANGLE_FAN, GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 4, 0, verts);
|
||||
|
||||
if(alpha != 255) {
|
||||
sceGuTexFunc(GU_TFX_REPLACE, GU_TCC_RGBA);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -915,7 +1165,8 @@ PSP_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
if(psp_texture == 0)
|
||||
return;
|
||||
|
||||
SDL_free(psp_texture->data);
|
||||
LRUTargetRemove(renderdata, psp_texture);
|
||||
TextureStorageFree(psp_texture->data);
|
||||
SDL_free(psp_texture);
|
||||
texture->driverdata = NULL;
|
||||
}
|
||||
@ -931,8 +1182,8 @@ PSP_DestroyRenderer(SDL_Renderer * renderer)
|
||||
StartDrawing(renderer);
|
||||
|
||||
sceGuTerm();
|
||||
/* vfree(data->backbuffer); */
|
||||
/* vfree(data->frontbuffer); */
|
||||
vfree(data->backbuffer);
|
||||
vfree(data->frontbuffer);
|
||||
|
||||
data->initialized = SDL_FALSE;
|
||||
data->displayListAvail = SDL_FALSE;
|
||||
@ -991,6 +1242,9 @@ PSP_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
return 0;
|
||||
data->initialized = SDL_TRUE;
|
||||
|
||||
data->most_recent_target = NULL;
|
||||
data->least_recent_target = NULL;
|
||||
|
||||
if (flags & SDL_RENDERER_PRESENTVSYNC) {
|
||||
data->vsync = SDL_TRUE;
|
||||
} else {
|
||||
@ -1003,31 +1257,31 @@ PSP_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
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;
|
||||
}
|
||||
|
||||
void* doublebuffer = valloc(PSP_FRAME_BUFFER_SIZE*data->bpp*2);
|
||||
data->backbuffer = doublebuffer;
|
||||
data->frontbuffer = ((uint8_t*)doublebuffer)+PSP_FRAME_BUFFER_SIZE*data->bpp;
|
||||
|
||||
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);
|
||||
sceGuDrawBuffer(data->psm, vrelptr(data->frontbuffer), PSP_FRAME_BUFFER_WIDTH);
|
||||
sceGuDispBuffer(PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT, vrelptr(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);
|
||||
|
||||
sceGuDisable(GU_DEPTH_TEST);
|
||||
|
||||
/* Scissoring */
|
||||
sceGuScissor(0, 0, PSP_SCREEN_WIDTH, PSP_SCREEN_HEIGHT);
|
||||
@ -1037,16 +1291,8 @@ PSP_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
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);
|
||||
//Setup initial blend state
|
||||
ResetBlendState(&data->blendState);
|
||||
|
||||
sceGuFinish();
|
||||
sceGuSync(0,0);
|
||||
|
@ -173,7 +173,6 @@ PSP_VideoInit(_THIS)
|
||||
current_mode.refresh_rate = 60;
|
||||
/* 32 bpp for default */
|
||||
current_mode.format = SDL_PIXELFORMAT_ABGR8888;
|
||||
|
||||
current_mode.driverdata = NULL;
|
||||
|
||||
SDL_zero(display);
|
||||
@ -181,8 +180,15 @@ PSP_VideoInit(_THIS)
|
||||
display.current_mode = current_mode;
|
||||
display.driverdata = NULL;
|
||||
|
||||
SDL_AddVideoDisplay(&display);
|
||||
SDL_AddDisplayMode(&display, ¤t_mode);
|
||||
|
||||
/* 16 bpp secondary mode */
|
||||
current_mode.format = SDL_PIXELFORMAT_BGR565;
|
||||
display.desktop_mode = current_mode;
|
||||
display.current_mode = current_mode;
|
||||
SDL_AddDisplayMode(&display, ¤t_mode);
|
||||
|
||||
SDL_AddVideoDisplay(&display);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -229,6 +235,7 @@ PSP_CreateWindow(_THIS, SDL_Window * window)
|
||||
/* Setup driver data for this window */
|
||||
window->driverdata = wdata;
|
||||
|
||||
SDL_SetKeyboardFocus(window);
|
||||
|
||||
/* Window has been successfully created */
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user