From c472b8dd455939ad107f9f3a85d470280d2d1648 Mon Sep 17 00:00:00 2001
From: Francisco Javier Trujillo Mata <[EMAIL REDACTED]>
Date: Mon, 4 Jul 2022 13:23:06 +0200
Subject: [PATCH] Whole clean around render and video driver
---
src/render/ps2/SDL_render_ps2.c | 1188 +++-------------------------
src/render/ps2/SDL_render_ps2.h | 37 -
src/render/ps2/SDL_rotate.c | 577 --------------
src/render/ps2/SDL_rotate.h | 30 -
src/render/ps2/SDL_triangle.c | 129 ---
src/render/ps2/SDL_triangle.h | 42 -
src/video/ps2/SDL_ps2framebuffer.c | 2 +-
src/video/ps2/SDL_ps2video.c | 171 ++--
8 files changed, 138 insertions(+), 2038 deletions(-)
delete mode 100644 src/render/ps2/SDL_render_ps2.h
delete mode 100644 src/render/ps2/SDL_rotate.c
delete mode 100644 src/render/ps2/SDL_rotate.h
delete mode 100644 src/render/ps2/SDL_triangle.c
delete mode 100644 src/render/ps2/SDL_triangle.h
diff --git a/src/render/ps2/SDL_render_ps2.c b/src/render/ps2/SDL_render_ps2.c
index 0455f1b3a23..273983fab25 100644
--- a/src/render/ps2/SDL_render_ps2.c
+++ b/src/render/ps2/SDL_render_ps2.c
@@ -20,36 +20,30 @@
*/
#include "../../SDL_internal.h"
-#if SDL_VIDEO_RENDER_PS2 && !SDL_RENDER_DISABLED
+#if SDL_VIDEO_RENDER_PS2
#include "../SDL_sysrender.h"
-#include "SDL_render_ps2.h"
#include "SDL_hints.h"
-#include "SDL_draw.h"
-#include "SDL_rotate.h"
-#include "SDL_triangle.h"
+#include <kernel.h>
+#include <gsKit.h>
+#include <dmaKit.h>
+#include <gsToolkit.h>
+#include <gsInline.h>
-/* SDL surface based renderer implementation */
+/* turn black GS Screen */
+#define GS_BLACK GS_SETREG_RGBA(0x00, 0x00, 0x00, 0x80)
typedef struct
{
- const SDL_Rect *viewport;
- const SDL_Rect *cliprect;
- SDL_bool surface_cliprect_dirty;
-} PS2_DrawStateCache;
-
-typedef struct
-{
- SDL_Surface *surface;
- SDL_Surface *window;
+ GSGLOBAL *gsGlobal;
+ int32_t vsync_callback_id;
+ SDL_bool vsync; /* wether we do vsync */
} PS2_RenderData;
-static GSGLOBAL *gsGlobal = NULL;
static int vsync_sema_id = 0;
-
/* PRIVATE METHODS */
static int vsync_handler()
{
@@ -86,187 +80,7 @@ static void gsKit_flip(GSGLOBAL *gsGlobal)
gsKit_setactive(gsGlobal);
}
-
-int
-PS2_DrawPoints(SDL_Surface * dst, const SDL_Point * points, int count,
- Uint32 color)
-{
- int minx, miny;
- int maxx, maxy;
- int i;
- int x, y;
-
- if (!dst) {
- return SDL_InvalidParamError("SDL_DrawPoints(): dst");
- }
-
- /* This function doesn't work on surfaces < 8 bpp */
- if (dst->format->BitsPerPixel < 8) {
- return SDL_SetError("SDL_DrawPoints(): Unsupported surface format");
- }
-
- minx = dst->clip_rect.x;
- maxx = dst->clip_rect.x + dst->clip_rect.w - 1;
- miny = dst->clip_rect.y;
- maxy = dst->clip_rect.y + dst->clip_rect.h - 1;
-
- for (i = 0; i < count; ++i) {
- x = points[i].x;
- y = points[i].y;
-
- if (x < minx || x > maxx || y < miny || y > maxy) {
- continue;
- }
-
- gsKit_prim_point(gsGlobal, x, y, 1, color);
- }
- return 0;
-}
-
-int
-PS2_DrawLines(SDL_Surface * dst, const SDL_Point * points, int count,
- Uint32 color)
-{
- int i;
- int x1, y1;
- int x2, y2;
-
- if (!dst) {
- return SDL_InvalidParamError("SDL_DrawLines(): dst");
- }
-
- for (i = 1; i < count; ++i) {
- x1 = points[i-1].x;
- y1 = points[i-1].y;
- x2 = points[i].x;
- y2 = points[i].y;
-
- gsKit_prim_line(gsGlobal, x1, y1, x2, y2, 1, color);
- }
- if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) {
- PS2_DrawPoints(dst, points, 1, color);
- }
- return 0;
-}
-
-
-int
-PS2_FillRects(SDL_Surface * dst, const SDL_Rect * rects, int count,
- Uint32 color)
-{
- SDL_Rect clipped;
- Uint8 *pixels;
- const SDL_Rect* rect;
- int i;
-
- if (!dst) {
- return SDL_InvalidParamError("SDL_FillRects(): dst");
- }
-
- /* Nothing to do */
- if (dst->w == 0 || dst->h == 0) {
- return 0;
- }
-
- /* Perform software fill */
- if (!dst->pixels) {
- return SDL_SetError("SDL_FillRects(): You must lock the surface");
- }
-
- if (!rects) {
- return SDL_InvalidParamError("SDL_FillRects(): rects");
- }
-
- /* This function doesn't usually work on surfaces < 8 bpp
- * Except: support for 4bits, when filling full size.
- */
- if (dst->format->BitsPerPixel < 8) {
- if (count == 1) {
- const SDL_Rect *r = &rects[0];
- if (r->x == 0 && r->y == 0 && r->w == dst->w && r->w == dst->h) {
- if (dst->format->BitsPerPixel == 4) {
- Uint8 b = (((Uint8) color << 4) | (Uint8) color);
- SDL_memset(dst->pixels, b, dst->h * dst->pitch);
- return 1;
- }
- }
- }
- return SDL_SetError("SDL_FillRects(): Unsupported surface format");
- }
-
-
- for (i = 0; i < count; ++i) {
- rect = &rects[i];
- /* Perform clipping */
- if (!SDL_IntersectRect(rect, &dst->clip_rect, &clipped)) {
- continue;
- }
- rect = &clipped;
-
- gsKit_prim_sprite(gsGlobal, rect->x, rect->y, rect->w, rect->h, 1, color);
-
- }
-
- /* We're done! */
- return 0;
-}
-
-
-
-
-static SDL_Surface *
-PS2_ActivateRenderer(SDL_Renderer * renderer)
-{
- PS2_RenderData *data = (PS2_RenderData *) renderer->driverdata;
-
- if (!data->surface) {
- data->surface = data->window;
- }
- if (!data->surface) {
- SDL_Surface *surface = SDL_GetWindowSurface(renderer->window);
- if (surface) {
- data->surface = data->window = surface;
- }
- }
- return data->surface;
-}
-
-static void
-PS2_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
-{
- PS2_RenderData *data = (PS2_RenderData *) renderer->driverdata;
-
- if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
- data->surface = NULL;
- data->window = NULL;
- }
-}
-
-static int
-PS2_GetOutputSize(SDL_Renderer * renderer, int *w, int *h)
-{
- PS2_RenderData *data = (PS2_RenderData *) renderer->driverdata;
-
- if (data->surface) {
- if (w) {
- *w = data->surface->w;
- }
- if (h) {
- *h = data->surface->h;
- }
- return 0;
- }
-
- if (renderer->window) {
- SDL_GetWindowSize(renderer->window, w, h);
- return 0;
- }
-
- return SDL_SetError("Software renderer doesn't have an output surface");
-}
-
-static int
-PixelFormatToPS2PSM(Uint32 format)
+static int PixelFormatToPS2PSM(Uint32 format)
{
switch (format) {
case SDL_PIXELFORMAT_ABGR1555:
@@ -280,60 +94,34 @@ PixelFormatToPS2PSM(Uint32 format)
}
}
+static void
+PS2_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
+{
+
+}
+
static int
PS2_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
{
int bpp;
Uint32 Rmask, Gmask, Bmask, Amask;
GSTEXTURE* ps2_tex = (GSTEXTURE*) SDL_calloc(1, sizeof(GSTEXTURE));
+ PS2_RenderData *data = (PS2_RenderData *) renderer->driverdata;
- if(!ps2_tex)
+ if (!ps2_tex)
return SDL_OutOfMemory();
- ps2_tex->Delayed = true;
ps2_tex->Width = texture->w;
ps2_tex->Height = texture->h;
ps2_tex->PSM = PixelFormatToPS2PSM(texture->format);
ps2_tex->Mem = memalign(128, gsKit_texture_size_ee(ps2_tex->Width, ps2_tex->Height, ps2_tex->PSM));
- if(!ps2_tex->Mem)
+ if (!ps2_tex->Mem)
{
SDL_free(ps2_tex);
return SDL_OutOfMemory();
}
- if(!ps2_tex->Delayed)
- {
- ps2_tex->Vram = gsKit_vram_alloc(gsGlobal, gsKit_texture_size(ps2_tex->Width, ps2_tex->Height, ps2_tex->PSM), GSKIT_ALLOC_USERBUFFER);
- if(ps2_tex->Vram == GSKIT_ALLOC_ERROR) {
- printf("VRAM Allocation Failed. Will not upload texture.\n");
- return -1;
- }
-
- if(ps2_tex->Clut != NULL) {
- if(ps2_tex->PSM == GS_PSM_T4)
- ps2_tex->VramClut = gsKit_vram_alloc(gsGlobal, gsKit_texture_size(8, 2, GS_PSM_CT32), GSKIT_ALLOC_USERBUFFER);
- else
- ps2_tex->VramClut = gsKit_vram_alloc(gsGlobal, gsKit_texture_size(16, 16, GS_PSM_CT32), GSKIT_ALLOC_USERBUFFER);
-
- if(ps2_tex->VramClut == GSKIT_ALLOC_ERROR)
- {
- printf("VRAM CLUT Allocation Failed. Will not upload texture.\n");
- return -1;
- }
- }
-
- gsKit_texture_upload(gsGlobal, ps2_tex);
- free(ps2_tex->Mem);
- ps2_tex->Mem = NULL;
- if(ps2_tex->Clut != NULL) {
- free(ps2_tex->Clut);
- ps2_tex->Clut = NULL;
- }
- } else {
- gsKit_setup_tbw(ps2_tex);
- }
-
texture->driverdata = ps2_tex;
return 0;
@@ -343,25 +131,6 @@ static int
PS2_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, const void *pixels, int pitch)
{
- SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
- Uint8 *src, *dst;
- int row;
- size_t length;
-
- if(SDL_MUSTLOCK(surface))
- SDL_LockSurface(surface);
- src = (Uint8 *) pixels;
- dst = (Uint8 *) surface->pixels +
- rect->y * surface->pitch +
- rect->x * surface->format->BytesPerPixel;
- length = rect->w * surface->format->BytesPerPixel;
- for (row = 0; row < rect->h; ++row) {
- SDL_memcpy(dst, src, length);
- src += pitch;
- dst += surface->pitch;
- }
- if(SDL_MUSTLOCK(surface))
- SDL_UnlockSurface(surface);
return 0;
}
@@ -369,12 +138,6 @@ static int
PS2_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
const SDL_Rect * rect, void **pixels, int *pitch)
{
- GSTEXTURE *surface = (GSTEXTURE *) texture->driverdata;
-
- *pixels =
- (void *) ((Uint8 *) surface->Mem +
- gsKit_texture_size_ee(surface->Width, surface->Height, surface->PSM));
- //*pitch = surface->pitch;
return 0;
}
@@ -391,13 +154,6 @@ PS2_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture, SDL_Scal
static int
PS2_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
{
- PS2_RenderData *data = (PS2_RenderData *) renderer->driverdata;
-
- if (texture) {
- data->surface = (SDL_Surface *) texture->driverdata;
- } else {
- data->surface = data->window;
- }
return 0;
}
@@ -410,42 +166,12 @@ PS2_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd)
static int
PS2_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
{
- SDL_Point *verts = (SDL_Point *) SDL_AllocateRenderVertices(renderer, count * sizeof (SDL_Point), 0, &cmd->data.draw.first);
- int i;
-
- if (!verts) {
- return -1;
- }
-
- cmd->data.draw.count = count;
-
- for (i = 0; i < count; i++, verts++, points++) {
- verts->x = (int)points->x;
- verts->y = (int)points->y;
- }
-
return 0;
}
static int
PS2_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count)
{
- SDL_Rect *verts = (SDL_Rect *) SDL_AllocateRenderVertices(renderer, count * sizeof (SDL_Rect), 0, &cmd->data.draw.first);
- int i;
-
- if (!verts) {
- return -1;
- }
-
- cmd->data.draw.count = count;
-
- for (i = 0; i < count; i++, verts++, rects++) {
- verts->x = (int)rects->x;
- verts->y = (int)rects->y;
- verts->w = SDL_max((int)rects->w, 1);
- verts->h = SDL_max((int)rects->h, 1);
- }
-
return 0;
}
@@ -453,724 +179,37 @@ static int
PS2_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_FRect * dstrect)
{
- SDL_Rect *verts = (SDL_Rect *) SDL_AllocateRenderVertices(renderer, 2 * sizeof (SDL_Rect), 0, &cmd->data.draw.first);
-
- if (!verts) {
- return -1;
- }
-
- cmd->data.draw.count = 1;
-
- SDL_copyp(verts, srcrect);
- verts++;
-
- verts->x = (int)dstrect->x;
- verts->y = (int)dstrect->y;
- verts->w = (int)dstrect->w;
- verts->h = (int)dstrect->h;
-
return 0;
}
-typedef struct CopyExData
-{
- SDL_Rect srcrect;
- SDL_Rect dstrect;
- double angle;
- SDL_FPoint center;
- SDL_RendererFlip flip;
- float scale_x;
- float scale_y;
-} CopyExData;
-
static int
PS2_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_FRect * dstrect,
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, float scale_x, float scale_y)
{
- CopyExData *verts = (CopyExData *) SDL_AllocateRenderVertices(renderer, sizeof (CopyExData), 0, &cmd->data.draw.first);
-
- if (!verts) {
- return -1;
- }
-
- cmd->data.draw.count = 1;
-
- SDL_copyp(&verts->srcrect, srcrect);
-
- verts->dstrect.x = (int)dstrect->x;
- verts->dstrect.y = (int)dstrect->y;
- verts->dstrect.w = (int)dstrect->w;
- verts->dstrect.h = (int)dstrect->h;
- verts->angle = angle;
- SDL_copyp(&verts->center, center);
- verts->flip = flip;
- verts->scale_x = scale_x;
- verts->scale_y = scale_y;
-
return 0;
}
-static int
-Blit_to_Screen(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *surface, SDL_Rect *dstrect,
- float scale_x, float scale_y, SDL_ScaleMode scaleMode)
-{
- int retval;
- /* Renderer scaling, if needed */
- if (scale_x != 1.0f || scale_y != 1.0f) {
- SDL_Rect r;
- r.x = (int)((float) dstrect->x * scale_x);
- r.y = (int)((float) dstrect->y * scale_y);
- r.w = (int)((float) dstrect->w * scale_x);
- r.h = (int)((float) dstrect->h * scale_y);
- retval = SDL_PrivateUpperBlitScaled(src, srcrect, surface, &r, scaleMode);
- } else {
- retval = SDL_BlitSurface(src, srcrect, surface, dstrect);
- }
- return retval;
-}
-
static int
PS2_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * texture,
const SDL_Rect * srcrect, const SDL_Rect * final_rect,
const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip, float scale_x, float scale_y)
{
- SDL_Surface *src = (SDL_Surface *) texture->driverdata;
- SDL_Rect tmp_rect;
- SDL_Surface *src_clone, *src_rotated, *src_scaled;
- SDL_Surface *mask = NULL, *mask_rotated = NULL;
- int retval = 0;
- SDL_BlendMode blendmode;
- Uint8 alphaMod, rMod, gMod, bMod;
- int applyModulation = SDL_FALSE;
- int blitRequired = SDL_FALSE;
- int isOpaque = SDL_FALSE;
-
- if (!surface) {
- return -1;
- }
-
- tmp_rect.x = 0;
- tmp_rect.y = 0;
- tmp_rect.w = final_rect->w;
- tmp_rect.h = final_rect->h;
-
- /* It is possible to encounter an RLE encoded surface here and locking it is
- * necessary because this code is going to access the pixel buffer directly.
- */
- if (SDL_MUSTLOCK(src)) {
- SDL_LockSurface(src);
- }
-
- /* Clone the source surface but use its pixel buffer directly.
- * The original source surface must be treated as read-only.
- */
- src_clone = SDL_CreateRGBSurfaceFrom(src->pixels, src->w, src->h, src->format->BitsPerPixel, src->pitch,
- src->format->Rmask, src->format->Gmask,
- src->format->Bmask, src->format->Amask);
- if (src_clone == NULL) {
- if (SDL_MUSTLOCK(src)) {
- SDL_UnlockSurface(src);
- }
- return -1;
- }
-
- SDL_GetSurfaceBlendMode(src, &blendmode);
- SDL_GetSurfaceAlphaMod(src, &alphaMod);
- SDL_GetSurfaceColorMod(src, &rMod, &gMod, &bMod);
-
- /* SDLgfx_rotateSurface only accepts 32-bit surfaces with a 8888 layout. Everything else has to be converted. */
- if (src->format->BitsPerPixel != 32 || SDL_PIXELLAYOUT(src->format->format) != SDL_PACKEDLAYOUT_8888 || !src->format->Amask) {
- blitRequired = SDL_TRUE;
- }
-
- /* If scaling and cropping is necessary, it has to be taken care of before the rotation. */
- if (!(srcrect->w == final_rect->w && srcrect->h == final_rect->h && srcrect->x == 0 && srcrect->y == 0)) {
- blitRequired = SDL_TRUE;
- }
-
- /* srcrect is not selecting the whole src surface, so cropping is needed */
- if (!(srcrect->w == src->w && srcrect->h == src->h && srcrect->x == 0 && srcrect->y == 0)) {
- blitRequired = SDL_TRUE;
- }
-
- /* The color and alpha modulation has to be applied before the rotation when using the NONE, MOD or MUL blend modes. */
- if ((blendmode == SDL_BLENDMODE_NONE || blendmode == SDL_BLENDMODE_MOD || blendmode == SDL_BLENDMODE_MUL) && (alphaMod & rMod & gMod & bMod) != 255) {
- applyModulation = SDL_TRUE;
- SDL_SetSurfaceAlphaMod(src_clone, alphaMod);
- SDL_SetSurfaceColorMod(src_clone, rMod, gMod, bMod);
- }
-
- /* Opaque surfaces are much easier to handle with the NONE blend mode. */
- if (blendmode == SDL_BLENDMODE_NONE && !src->format->Amask && alphaMod == 255) {
- isOpaque = SDL_TRUE;
- }
-
- /* The NONE blend mode requires a mask for non-opaque surfaces. This mask will be used
- * to clear the pixels in the destination surface. The other steps are explained below.
- */
- if (blendmode == SDL_BLENDMODE_NONE && !isOpaque) {
- mask = SDL_CreateRGBSurface(0, final_rect->w, final_rect->h, 32,
- 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
- if (mask == NULL) {
- retval = -1;
- } else {
- SDL_SetSurfaceBlendMode(mask, SDL_BLENDMODE_MOD);
- }
- }
-
- /* Create a new surface should there be a format mismatch or if scaling, cropping,
- * or modulation is required. It's possible to use the source surface directly otherwise.
- */
- if (!retval && (blitRequired || applyModulation)) {
- SDL_Rect scale_rect = tmp_rect;
- src_scaled = SDL_CreateRGBSurface(0, final_rect->w, final_rect->h, 32,
- 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
- if (src_scaled == NULL) {
- retval = -1;
- } else {
- SDL_SetSurfaceBlendMode(src_clone, SDL_BLENDMODE_NONE);
- retval = SDL_PrivateUpperBlitScaled(src_clone, srcrect, src_scaled, &scale_rect, texture->scaleMode);
- SDL_FreeSurface(src_clone);
- src_clone = src_scaled;
- src_scaled = NULL;
- }
- }
-
- /* SDLgfx_rotateSurface is going to make decisions depending on the blend mode. */
- SDL_SetSurfaceBlendMode(src_clone, blendmode);
-
- if (!retval) {
- SDL_Rect rect_dest;
- double cangle, sangle;
-
- SDLgfx_rotozoomSurfaceSizeTrig(tmp_rect.w, tmp_rect.h, angle, center,
- &rect_dest, &cangle, &sangle);
- src_rotated = SDLgfx_rotateSurface(src_clone, angle,
- (texture->scaleMode == SDL_ScaleModeNearest) ? 0 : 1, flip & SDL_FLIP_HORIZONTAL, flip & SDL_FLIP_VERTICAL,
- &rect_dest, cangle, sangle, center);
- if (src_rotated == NULL) {
- retval = -1;
- }
- if (!retval && mask != NULL) {
- /* The mask needed for the NONE blend mode gets rotated with the same parameters. */
- mask_rotated = SDLgfx_rotateSurface(mask, angle,
- SDL_FALSE, 0, 0,
- &rect_dest, cangle, sangle, center);
- if (mask_rotated == NULL) {
- retval = -1;
- }
- }
- if (!retval) {
-
- tmp_rect.x = final_rect->x + rect_dest.x;
- tmp_rect.y = final_rect->y + rect_dest.y;
- tmp_rect.w = rect_dest.w;
- tmp_rect.h = rect_dest.h;
-
- /* The NONE blend mode needs some special care with non-opaque surfaces.
- * Other blend modes or opaque surfaces can be blitted directly.
- */
- if (blendmode != SDL_BLENDMODE_NONE || isOpaque) {
- if (applyModulation == SDL_FALSE) {
- /* If the modulation wasn't already applied, make it happen now. */
- SDL_SetSurfaceAlphaMod(src_rotated, alphaMod);
- SDL_SetSurfaceColorMod(src_rotated, rMod, gMod, bMod);
- }
- /* Renderer scaling, if needed */
- retval = Blit_to_Screen(src_rotated, NULL, surface, &tmp_rect, scale_x, scale_y, texture->scaleMode);
- } else {
- /* The NONE blend mode requires three steps to get the pixels onto the destination surface.
- * First, the area where the rotated pixels will be blitted to get set to zero.
- * This is accomplished by simply blitting a mask with the NONE blend mode.
- * The colorkey set by the rotate function will discard the correct pixels.
- */
- SDL_Rect mask_rect = tmp_rect;
- SDL_SetSurfaceBlendMode(mask_rotated, SDL_BLENDMODE_NONE);
- /* Renderer scaling, if needed */
- retval = Blit_to_Screen(mask_rotated, NULL, surface, &mask_rect, scale_x, scale_y, texture->scaleMode);
- if (!retval) {
- /* The next step copies the alpha value. This is done with the BLEND blend mode and
- * by modulating the source colors with 0. Since the destination is all zeros, this
- * will effectively set the destination alpha to the source alpha.
- */
- SDL_SetSurfaceColorMod(src_rotated, 0, 0, 0);
- mask_rect = tmp_rect;
- /* Renderer scaling, if needed */
- retval = Blit_to_Screen(src_rotated, NULL, surface, &mask_rect, scale_x, scale_y, texture->scaleMode);
- if (!retval) {
- /* The last step gets the color values in place. The ADD blend mode simply adds them to
- * the destination (where the color values are all zero). However, because the ADD blend
- * mode modulates the colors with the alpha channel, a surface without an alpha mask needs
- * to be created. This makes all source pixels opaque and the colors get copied correctly.
- */
- SDL_Surface *src_rotated_rgb;
- src_rotated_rgb = SDL_CreateRGBSurfaceFrom(src_rotated->pixels, src_rotated->w, src_rotated->h,
- src_rotated->format->BitsPerPixel, src_rotated->pitch,
- src_rotated->format->Rmask, src_rotated->format->Gmask,
- src_rotated->format->Bmask, 0);
- if (src_rotated_rgb == NULL) {
- retval = -1;
- } else {
- SDL_SetSurfaceBlendMode(src_rotated_rgb, SDL_BLENDMODE_ADD);
- /* Renderer scaling, if needed */
- retval = Blit_to_Screen(src_rotated_rgb, NULL, surface, &tmp_rect, scale_x, scale_y, texture->scaleMode);
- SDL_FreeSurface(src_rotated_rgb);
- }
- }
- }
- SDL_FreeSurface(mask_rotated);
- }
- if (src_rotated != NULL) {
- SDL_FreeSurface(src_rotated);
- }
- }
- }
-
- if (SDL_MUSTLOCK(src)) {
- SDL_UnlockSurface(src);
- }
- if (mask != NULL) {
- SDL_FreeSurface(mask);
- }
- if (src_clone != NULL) {
- SDL_FreeSurface(src_clone);
- }
- return retval;
+ return 0;
}
-
-typedef struct GeometryFillData
-{
- SDL_Point dst;
- SDL_Color color;
-} GeometryFillData;
-
-typedef struct GeometryCopyData
-{
- SDL_Point src;
- SDL_Point dst;
- SDL_Color color;
-} GeometryCopyData;
-
static int
PS2_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride,
int num_vertices, const void *indices, int num_indices, int size_indices,
float scale_x, float scale_y)
{
- int i;
- int count = indices ? num_indices : num_vertices;
- void *verts;
- int sz = texture ? sizeof (GeometryCopyData) : sizeof (GeometryFillData);
-
- verts = (void *) SDL_AllocateRenderVertices(renderer, count * sz, 0, &cmd->data.draw.first);
- if (!verts) {
- return -1;
- }
-
- cmd->data.draw.count = count;
- size_indices = indices ? size_indices : 0;
-
- if (texture) {
- GeometryCopyData *ptr = (GeometryCopyData *) verts;
- for (i = 0; i < count; i++) {
- int j;
- float *xy_;
- SDL_Color col_;
- float *uv_;
- if (size_indices == 4) {
- j = ((const Uint32 *)indices)[i];
- } else if (size_indices == 2) {
- j = ((const Uint16 *)indices)[i];
- } else if (size_indices == 1) {
- j = ((const Uint8 *)indices)[i];
- } else {
- j = i;
- }
-
- xy_ = (float *)((char*)xy + j * xy_stride);
- col_ = *(SDL_Color *)((char*)color + j * color_stride);
-
- uv_ = (float *)((char*)uv + j * uv_stride);
-
- ptr->src.x = (int)(uv_[0] * texture->w);
- ptr->src.y = (int)(uv_[1] * texture->h);
-
- ptr->dst.x = (int)(xy_[0] * scale_x);
- ptr->dst.y = (int)(xy_[1] * scale_y);
- trianglepoint_2_fixedpoint(&ptr->dst);
-
- ptr->color = col_;
-
- ptr++;
- }
- } else {
- GeometryFillData *ptr = (GeometryFillData *) verts;
-
- for (i = 0; i < count; i++) {
- int j;
- float *xy_;
- SDL_Color col_;
- if (size_indices == 4) {
- j = ((const Uint32 *)indices)[i];
- } else if (size_indices == 2) {
- j = ((const Uint16 *)indices)[i];
- } else if (size_indices == 1) {
- j = ((const Uint8 *)indices)[i];
- } else {
- j = i;
- }
-
- xy_ = (float *)((char*)xy + j * xy_stride);
- col_ = *(SDL_Color *)((char*)color + j * color_stride);
-
- ptr->dst.x = (int)(xy_[0] * scale_x);
- ptr->dst.y = (int)(xy_[1] * scale_y);
- trianglepoint_2_fixedpoint(&ptr->dst);
-
- ptr->color = col_;
-
- ptr++;
- }
- }
return 0;
}
-static void
-PrepTextureForCopy(const SDL_RenderCommand *cmd)
-{
- const Uint8 r = cmd->data.draw.r;
- const Uint8 g = cmd->data.draw.g;
- const Uint8 b = cmd->data.draw.b;
- const Uint8 a = cmd->data.draw.a;
- const SDL_BlendMode blend = cmd->data.draw.blend;
- SDL_Texture *texture = cmd->data.draw.texture;
- SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
- const SDL_bool colormod = ((r & g & b) != 0xFF);
- const SDL_bool alphamod = (a != 0xFF);
- const SDL_bool blending = ((blend == SDL_BLENDMODE_ADD) || (blend == SDL_BLENDMODE_MOD) || (blend == SDL_BLENDMODE_MUL));
-
- if (colormod || alphamod || blending) {
- SDL_SetSurfaceRLE(surface, 0);
- }
-
- /* !!! FIXME: we can probably avoid some of these calls. */
- SDL_SetSurfaceColorMod(surface, r, g, b);
- SDL_SetSurfaceAlphaMod(surface, a);
- SDL_SetSurfaceBlendMode(surface, blend);
-}
-
-static void
-SetDrawState(SDL_Surface *surface, PS2_DrawStateCache *drawstate)
-{
- if (drawstate->surface_cliprect_dirty) {
- const SDL_Rect *viewport = drawstate->viewport;
- const SDL_Rect *cliprect = drawstate->cliprect;
- SDL_assert(viewport != NULL); /* the higher level should have forced a SDL_RENDERCMD_SETVIEWPORT */
-
- if (cliprect != NULL) {
- SDL_Rect clip_rect;
- clip_rect.x = cliprect->x + viewport->x;
- clip_rect.y = cliprect->y + viewport->y;
- clip_rect.w = cliprect->w;
- clip_rect.h = cliprect->h;
- SDL_IntersectRect(viewport, &clip_rect, &clip_rect);
- SDL_SetClipRect(surface, &clip_rect);
- } else {
- SDL_SetClipRect(surface, drawstate->viewport);
- }
- drawstate->surface_cliprect_dirty = SDL_FALSE;
- }
-}
-
static int
PS2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
{
- SDL_Surface *surface = PS2_ActivateRenderer(renderer);
- PS2_DrawStateCache drawstate;
-
- if (!surface) {
- return -1;
- }
-
- drawstate.viewport = NULL;
- drawstate.cliprect = NULL;
- drawstate.surface_cliprect_dirty = SDL_TRUE;
-
- while (cmd) {
- switch (cmd->command) {
- case SDL_RENDERCMD_SETDRAWCOLOR: {
- break; /* Not used in this backend. */
- }
-
- case SDL_RENDERCMD_SETVIEWPORT: {
- drawstate.viewport = &cmd->data.viewport.rect;
- drawstate.surface_cliprect_dirty = SDL_TRUE;
- break;
- }
-
- case SDL_RENDERCMD_SETCLIPRECT: {
- drawstate.cliprect = cmd->data.cliprect.enabled ? &cmd->data.cliprect.rect : NULL;
- drawstate.surface_cliprect_dirty = SDL_TRUE;
- break;
- }
-
- case SDL_RENDERCMD_CLEAR: {
- const Uint8 r = cmd->data.color.r;
- const Uint8 g = cmd->data.color.g;
- const Uint8 b = cmd->data.color.b;
- const Uint8 a = cmd->data.color.a;
- gsKit_clear(gsGlobal, GS_SETREG_RGBAQ(r,g,b,a/2,0x00));
- renderer->line_method = SDL_RENDERLINEMETHOD_LINES;
- drawstate.surface_cliprect_dirty = SDL_TRUE;
- break;
- }
-
- case SDL_RENDERCMD_DRAW_POINTS: {
- const Uint8 r = cmd->data.draw.r;
- const Uint8 g = cmd->data.draw.g;
- const Uint8 b = cmd->data.draw.b;
- const Uint8 a = cmd->data.draw.a;
- const int count = (int) cmd->data.draw.count;
- SDL_Point *verts = (SDL_Point *) (((Uint8 *) vertices) + cmd->data.draw.first);
- const SDL_BlendMode blend = cmd->data.draw.blend;
- SetDrawState(surface, &drawstate);
-
- /* Apply viewport */
- if (drawstate.viewport->x || drawstate.viewport->y) {
- int i;
- for (i = 0; i < count; i++) {
- verts[i].x += drawstate.viewport->x;
- verts[i].y += drawstate.viewport->y;
- }
- }
-
- PS2_DrawPoints(surface, verts, count, (r | (g << 8) | (b << 16) | (a << 24)));
-
- break;
- }
-
- case SDL_RENDERCMD_DRAW_LINES: {
- const Uint8 r = cmd->data.draw.r;
- const Uint8 g = cmd->data.draw.g;
- const Uint8 b = cmd->data.draw.b;
- const Uint8 a = cmd->data.draw.a;
- const int count = (int) cmd->data.draw.count;
- SDL_Point *verts = (SDL_Point *) (((Uint8 *) vertices) +
(Patch may be truncated, please check the link at the top of this post.)