diff --git a/src/render/ps2/SDL_render_ps2.c b/src/render/ps2/SDL_render_ps2.c index 0455f1b3a..273983fab 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 +#include +#include +#include +#include -/* 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) + 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_DrawLines(surface, verts, count, (r | (g << 8) | (b << 16) | (a << 24))); - break; - } - - case SDL_RENDERCMD_FILL_RECTS: { - 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_Rect *verts = (SDL_Rect *) (((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_FillRects(surface, verts, count, (r | (g << 8) | (b << 16) | (a << 24))); - - break; - } - - case SDL_RENDERCMD_COPY: { - SDL_Rect *verts = (SDL_Rect *) (((Uint8 *) vertices) + cmd->data.draw.first); - const SDL_Rect *srcrect = verts; - SDL_Rect *dstrect = verts + 1; - SDL_Texture *texture = cmd->data.draw.texture; - SDL_Surface *src = (SDL_Surface *) texture->driverdata; - - SetDrawState(surface, &drawstate); - - PrepTextureForCopy(cmd); - - /* Apply viewport */ - if (drawstate.viewport->x || drawstate.viewport->y) { - dstrect->x += drawstate.viewport->x; - dstrect->y += drawstate.viewport->y; - } - - if ( srcrect->w == dstrect->w && srcrect->h == dstrect->h ) { - SDL_BlitSurface(src, srcrect, surface, dstrect); - } else { - /* If scaling is ever done, permanently disable RLE (which doesn't support scaling) - * to avoid potentially frequent RLE encoding/decoding. - */ - SDL_SetSurfaceRLE(surface, 0); - - /* Prevent to do scaling + clipping on viewport boundaries as it may lose proportion */ - if (dstrect->x < 0 || dstrect->y < 0 || dstrect->x + dstrect->w > surface->w || dstrect->y + dstrect->h > surface->h) { - SDL_Surface *tmp = SDL_CreateRGBSurfaceWithFormat(0, dstrect->w, dstrect->h, 0, src->format->format); - /* Scale to an intermediate surface, then blit */ - if (tmp) { - SDL_Rect r; - SDL_BlendMode blendmode; - Uint8 alphaMod, rMod, gMod, bMod; - - SDL_GetSurfaceBlendMode(src, &blendmode); - SDL_GetSurfaceAlphaMod(src, &alphaMod); - SDL_GetSurfaceColorMod(src, &rMod, &gMod, &bMod); - - r.x = 0; - r.y = 0; - r.w = dstrect->w; - r.h = dstrect->h; - - SDL_SetSurfaceBlendMode(src, SDL_BLENDMODE_NONE); - SDL_SetSurfaceColorMod(src, 255, 255, 255); - SDL_SetSurfaceAlphaMod(src, 255); - - SDL_PrivateUpperBlitScaled(src, srcrect, tmp, &r, texture->scaleMode); - - SDL_SetSurfaceColorMod(tmp, rMod, gMod, bMod); - SDL_SetSurfaceAlphaMod(tmp, alphaMod); - SDL_SetSurfaceBlendMode(tmp, blendmode); - - SDL_BlitSurface(tmp, NULL, surface, dstrect); - SDL_FreeSurface(tmp); - /* No need to set back r/g/b/a/blendmode to 'src' since it's done in PrepTextureForCopy() */ - } - } else{ - SDL_PrivateUpperBlitScaled(src, srcrect, surface, dstrect, texture->scaleMode); - } - } - break; - } - - case SDL_RENDERCMD_COPY_EX: { - CopyExData *copydata = (CopyExData *) (((Uint8 *) vertices) + cmd->data.draw.first); - SetDrawState(surface, &drawstate); - PrepTextureForCopy(cmd); - - /* Apply viewport */ - if (drawstate.viewport->x || drawstate.viewport->y) { - copydata->dstrect.x += drawstate.viewport->x; - copydata->dstrect.y += drawstate.viewport->y; - } - - PS2_RenderCopyEx(renderer, surface, cmd->data.draw.texture, ©data->srcrect, - ©data->dstrect, copydata->angle, ©data->center, copydata->flip, - copydata->scale_x, copydata->scale_y); - break; - } - - case SDL_RENDERCMD_GEOMETRY: { - int i; - SDL_Rect *verts = (SDL_Rect *) (((Uint8 *) vertices) + cmd->data.draw.first); - const int count = (int) cmd->data.draw.count; - SDL_Texture *texture = cmd->data.draw.texture; - const SDL_BlendMode blend = cmd->data.draw.blend; - - SetDrawState(surface, &drawstate); - - if (texture) { - SDL_Surface *src = (SDL_Surface *) texture->driverdata; - - GeometryCopyData *ptr = (GeometryCopyData *) verts; - - PrepTextureForCopy(cmd); - - /* Apply viewport */ - if (drawstate.viewport->x || drawstate.viewport->y) { - SDL_Point vp; - vp.x = drawstate.viewport->x; - vp.y = drawstate.viewport->y; - trianglepoint_2_fixedpoint(&vp); - for (i = 0; i < count; i++) { - ptr[i].dst.x += vp.x; - ptr[i].dst.y += vp.y; - } - } - - GSTEXTURE* tex = cmd->data.draw.texture->driverdata; - - for (i = 0; i < count; i += 3, ptr += 3) { - float x1 = ptr[0].dst.x; - float y1 = ptr[0].dst.y; - - float x2 = ptr[1].dst.x; - float y2 = ptr[1].dst.y; - - float x3 = ptr[2].dst.x; - float y3 = ptr[2].dst.y; - - Uint32 c1 = (ptr[0].color.r | (ptr[0].color.g << 8) | (ptr[0].color.b << 16) | (ptr[0].color.a << 24)); - Uint32 c2 = (ptr[1].color.r | (ptr[1].color.g << 8) | (ptr[1].color.b << 16) | (ptr[1].color.a << 24)); - Uint32 c3 = (ptr[0].color.r | (ptr[2].color.g << 8) | (ptr[2].color.b << 16) | (ptr[2].color.a << 24)); - - if (tex->Delayed == true) { - gsKit_TexManager_bind(gsGlobal, tex); - } - //It still need some works to make texture render on-screen - gsKit_prim_triangle_goraud_texture(gsGlobal, tex, x1, y1, 0, 0, x2, y2, 0, 1, x3, y3, 1, 0, 1, c1, c2, c3); - } - } else { - GeometryFillData *ptr = (GeometryFillData *) verts; - - /* Apply viewport */ - if (drawstate.viewport->x || drawstate.viewport->y) { - SDL_Point vp; - vp.x = drawstate.viewport->x; - vp.y = drawstate.viewport->y; - trianglepoint_2_fixedpoint(&vp); - for (i = 0; i < count; i++) { - ptr[i].dst.x += vp.x; - ptr[i].dst.y += vp.y; - } - } - - for (i = 0; i < count; i += 3, ptr += 3) { //These for loops need to be in a separated function - float x1 = ptr[0].dst.x; - float y1 = ptr[0].dst.y; - - float x2 = ptr[1].dst.x; - float y2 = ptr[1].dst.y; - - float x3 = ptr[2].dst.x; - float y3 = ptr[2].dst.y; - - Uint32 c1 = (ptr[0].color.r | (ptr[0].color.g << 8) | (ptr[0].color.b << 16) | (ptr[0].color.a << 24)); - Uint32 c2 = (ptr[1].color.r | (ptr[1].color.g << 8) | (ptr[1].color.b << 16) | (ptr[1].color.a << 24)); - Uint32 c3 = (ptr[0].color.r | (ptr[2].color.g << 8) | (ptr[2].color.b << 16) | (ptr[2].color.a << 24)); - - gsKit_prim_triangle_gouraud(gsGlobal, x1, y1, x2, y2, x3, y3, 1, c1, c2, c3); - } - } - break; - } - - case SDL_RENDERCMD_NO_OP: - break; - } - - cmd = cmd->next; - } - return 0; } @@ -1178,51 +217,30 @@ static int PS2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 format, void * pixels, int pitch) { - SDL_Surface *surface = PS2_ActivateRenderer(renderer); - Uint32 src_format; - void *src_pixels; - - if (!surface) { - return -1; - } - - /* NOTE: The rect is already adjusted according to the viewport by - * SDL_RenderReadPixels. - */ - - if (rect->x < 0 || rect->x+rect->w > surface->w || - rect->y < 0 || rect->y+rect->h > surface->h) { - return SDL_SetError("Tried to read outside of surface bounds"); - } - - src_format = surface->format->format; - src_pixels = (void*)((Uint8 *) surface->pixels + - rect->y * surface->pitch + - rect->x * surface->format->BytesPerPixel); - - return SDL_ConvertPixels(rect->w, rect->h, - src_format, src_pixels, surface->pitch, - format, pixels, pitch); + return 0; } static void PS2_RenderPresent(SDL_Renderer * renderer) { SDL_Window *window = renderer->window; + PS2_RenderData *data = (PS2_RenderData *) renderer->driverdata; if (window) { SDL_UpdateWindowSurface(window); } - if (gsGlobal->DoubleBuffering == GS_SETTING_OFF) { - gsKit_sync(gsGlobal); - gsKit_queue_exec(gsGlobal); + if (data->gsGlobal->DoubleBuffering == GS_SETTING_OFF) { + if (data->vsync) + gsKit_sync(data->gsGlobal); + gsKit_queue_exec(data->gsGlobal); } else { - gsKit_queue_exec(gsGlobal); + gsKit_queue_exec(data->gsGlobal); gsKit_finish(); - gsKit_sync(gsGlobal); - gsKit_flip(gsGlobal); + if (data->vsync) + gsKit_sync(data->gsGlobal); + gsKit_flip(data->gsGlobal); } - gsKit_TexManager_nextFrame(gsGlobal); + gsKit_TexManager_nextFrame(data->gsGlobal); } static void @@ -1238,20 +256,35 @@ PS2_DestroyRenderer(SDL_Renderer * renderer) { PS2_RenderData *data = (PS2_RenderData *) renderer->driverdata; - SDL_free(data); + if (data) { + gsKit_clear(data->gsGlobal, GS_BLACK); + gsKit_vram_clear(data->gsGlobal); + gsKit_deinit_global(data->gsGlobal); + gsKit_remove_vsync_handler(data->vsync_callback_id); + + SDL_free(data); + } + + if (vsync_sema_id >= 0) + DeleteSema(vsync_sema_id); + SDL_free(renderer); } -SDL_Renderer * -PS2_CreateRendererForSurface(SDL_Surface * surface) +static int +PS2_SetVSync(SDL_Renderer * renderer, const int vsync) +{ + PS2_RenderData *data = renderer->driverdata; + data->vsync = vsync; + return 0; +} + +static SDL_Renderer * +PS2_CreateRenderer(SDL_Window * window, Uint32 flags) { SDL_Renderer *renderer; PS2_RenderData *data; - - if (!surface) { - SDL_InvalidParamError("surface"); - return NULL; - } + ee_sema_t sema; renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); if (!renderer) { @@ -1265,71 +298,14 @@ PS2_CreateRendererForSurface(SDL_Surface * surface) SDL_OutOfMemory(); return NULL; } - data->surface = surface; - data->window = surface; - renderer->WindowEvent = PS2_WindowEvent; - renderer->GetOutputSize = PS2_GetOutputSize; - renderer->CreateTexture = PS2_CreateTexture; - renderer->UpdateTexture = PS2_UpdateTexture; - renderer->LockTexture = PS2_LockTexture; - renderer->UnlockTexture = PS2_UnlockTexture; - renderer->SetTextureScaleMode = PS2_SetTextureScaleMode; - renderer->SetRenderTarget = PS2_SetRenderTarget; - renderer->QueueSetViewport = PS2_QueueSetViewport; - renderer->QueueSetDrawColor = PS2_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */ - renderer->QueueDrawPoints = PS2_QueueDrawPoints; - renderer->QueueDrawLines = PS2_QueueDrawPoints; /* lines and points queue vertices the same way. */ - renderer->QueueFillRects = PS2_QueueFillRects; - renderer->QueueCopy = PS2_QueueCopy; - renderer->QueueCopyEx = PS2_QueueCopyEx; - renderer->QueueGeometry = PS2_QueueGeometry; - renderer->RunCommandQueue = PS2_RunCommandQueue; - renderer->RenderReadPixels = PS2_RenderReadPixels; - renderer->RenderPresent = PS2_RenderPresent; - renderer->DestroyTexture = PS2_DestroyTexture; - renderer->DestroyRenderer = PS2_DestroyRenderer; - renderer->info = PS2_RenderDriver.info; - renderer->driverdata = data; - - PS2_ActivateRenderer(renderer); - - return renderer; -} - -static SDL_Renderer * -PS2_CreateRenderer(SDL_Window * window, Uint32 flags) -{ - const char *hint; - SDL_Surface *surface; - SDL_bool no_hint_set; - - /* Set the vsync hint based on our flags, if it's not already set */ - hint = SDL_GetHint(SDL_HINT_RENDER_VSYNC); - if (!hint || !*hint) { - no_hint_set = SDL_TRUE; - } else { - no_hint_set = SDL_FALSE; - } - - if (no_hint_set) { - SDL_SetHint(SDL_HINT_RENDER_VSYNC, (flags & SDL_RENDERER_PRESENTVSYNC) ? "1" : "0"); - } - - surface = SDL_GetWindowSurface(window); - - /* Reset the vsync hint if we set it above */ - if (no_hint_set) { - SDL_SetHint(SDL_HINT_RENDER_VSYNC, ""); - } - - ee_sema_t sema; + /* Specific gsKit init */ sema.init_count = 0; sema.max_count = 1; sema.option = 0; vsync_sema_id = CreateSema(&sema); - gsGlobal = gsKit_init_global(); + GSGLOBAL *gsGlobal = gsKit_init_global(); gsGlobal->Mode = gsKit_check_rom(); if (gsGlobal->Mode == GS_MODE_PAL){ @@ -1358,29 +334,45 @@ PS2_CreateRenderer(SDL_Window * window, Uint32 flags) gsKit_TexManager_init(gsGlobal); - gsKit_add_vsync_handler(vsync_handler); + data->vsync_callback_id = gsKit_add_vsync_handler(vsync_handler); gsKit_mode_switch(gsGlobal, GS_ONESHOT); - gsKit_clear(gsGlobal, GS_SETREG_RGBAQ(0x80,0x00,0x00,0x80,0x00)); + gsKit_clear(gsGlobal, GS_SETREG_RGBAQ(0x80,0x00,0x00,0x80,0x00)); - if (gsGlobal->DoubleBuffering == GS_SETTING_OFF) { - gsKit_sync(gsGlobal); - gsKit_queue_exec(gsGlobal); + data->gsGlobal = gsGlobal; + if (flags & SDL_RENDERER_PRESENTVSYNC) { + data->vsync = SDL_TRUE; } else { - gsKit_queue_exec(gsGlobal); - gsKit_finish(); - gsKit_sync(gsGlobal); - gsKit_flip(gsGlobal); - } - gsKit_TexManager_nextFrame(gsGlobal); + data->vsync = SDL_FALSE; + } - surface->userdata = gsGlobal; + renderer->WindowEvent = PS2_WindowEvent; + renderer->CreateTexture = PS2_CreateTexture; + renderer->UpdateTexture = PS2_UpdateTexture; + renderer->LockTexture = PS2_LockTexture; + renderer->UnlockTexture = PS2_UnlockTexture; + renderer->SetTextureScaleMode = PS2_SetTextureScaleMode; + renderer->SetRenderTarget = PS2_SetRenderTarget; + renderer->QueueSetViewport = PS2_QueueSetViewport; + renderer->QueueSetDrawColor = PS2_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */ + renderer->QueueDrawPoints = PS2_QueueDrawPoints; + renderer->QueueDrawLines = PS2_QueueDrawPoints; /* lines and points queue vertices the same way. */ + renderer->QueueFillRects = PS2_QueueFillRects; + renderer->QueueCopy = PS2_QueueCopy; + renderer->QueueCopyEx = PS2_QueueCopyEx; + renderer->QueueGeometry = PS2_QueueGeometry; + renderer->RunCommandQueue = PS2_RunCommandQueue; + renderer->RenderReadPixels = PS2_RenderReadPixels; + renderer->RenderPresent = PS2_RenderPresent; + renderer->DestroyTexture = PS2_DestroyTexture; + renderer->DestroyRenderer = PS2_DestroyRenderer; + renderer->SetVSync = PS2_SetVSync; + renderer->info = PS2_RenderDriver.info; + renderer->driverdata = data; + renderer->window = window; - if (!surface) { - return NULL; - } - return PS2_CreateRendererForSurface(surface); + return renderer; } SDL_RenderDriver PS2_RenderDriver = { diff --git a/src/render/ps2/SDL_render_ps2.h b/src/render/ps2/SDL_render_ps2.h deleted file mode 100644 index a9eecd6f5..000000000 --- a/src/render/ps2/SDL_render_ps2.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga - - 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. -*/ - -#ifndef SDL_render_ps2_h_ -#define SDL_render_ps2_h_ - -#include - -#include -#include - -#include -#include - -extern SDL_Renderer * PS2_CreateRendererForSurface(SDL_Surface * surface); - -#endif /* SDL_render_ps2_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/ps2/SDL_rotate.c b/src/render/ps2/SDL_rotate.c deleted file mode 100644 index 4676887e8..000000000 --- a/src/render/ps2/SDL_rotate.c +++ /dev/null @@ -1,577 +0,0 @@ -/* - -SDL_rotate.c: rotates 32bit or 8bit surfaces - -Shamelessly stolen from SDL_gfx by Andreas Schiffler. Original copyright follows: - -Copyright (C) 2001-2011 Andreas Schiffler - -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. - -Andreas Schiffler -- aschiffler at ferzkopp dot net - -*/ -#include "../../SDL_internal.h" - -#if SDL_VIDEO_RENDER_PS2 && !SDL_RENDER_DISABLED - -#if defined(__WIN32__) || defined(__GDK__) -#include "../../core/windows/SDL_windows.h" -#endif - -#include -#include - -#include "SDL.h" -#include "SDL_rotate.h" - -/* ---- Internally used structures */ - -/* ! -\brief A 32 bit RGBA pixel. -*/ -typedef struct tColorRGBA { - Uint8 r; - Uint8 g; - Uint8 b; - Uint8 a; -} tColorRGBA; - -/* ! -\brief A 8bit Y/palette pixel. -*/ -typedef struct tColorY { - Uint8 y; -} tColorY; - -/* ! -\brief Number of guard rows added to destination surfaces. - -This is a simple but effective workaround for observed issues. -These rows allocate extra memory and are then hidden from the surface. -Rows are added to the end of destination surfaces when they are allocated. -This catches any potential overflows which seem to happen with -just the right src image dimensions and scale/rotation and can lead -to a situation where the program can segfault. -*/ -#define GUARD_ROWS (2) - -/* ! -\brief Returns colorkey info for a surface -*/ -static Uint32 -get_colorkey(SDL_Surface *src) -{ - Uint32 key = 0; - if (SDL_HasColorKey(src)) { - SDL_GetColorKey(src, &key); - } - return key; -} - -/* rotate (sx, sy) by (angle, center) into (dx, dy) */ -static void -rotate(double sx, double sy, double sinangle, double cosangle, const SDL_FPoint *center, double *dx, double *dy) { - sx -= center->x; - sy -= center->y; - - *dx = cosangle * sx - sinangle * sy; - *dy = sinangle * sx + cosangle * sy; - - *dx += center->x; - *dy += center->y; -} - -/* ! -\brief Internal target surface sizing function for rotations with trig result return. - -\param width The source surface width. -\param height The source surface height. -\param angle The angle to rotate in degrees. -\param dstwidth The calculated width of the destination surface. -\param dstheight The calculated height of the destination surface. -\param cangle The sine of the angle -\param sangle The cosine of the angle - -*/ -void -SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle, const SDL_FPoint *center, - SDL_Rect *rect_dest, double *cangle, double *sangle) -{ - int minx, maxx, miny, maxy; - double radangle; - double x0, x1, x2, x3; - double y0, y1, y2, y3; - double sinangle; - double cosangle; - - radangle = angle * (M_PI / 180.0); - sinangle = SDL_sin(radangle); - cosangle = SDL_cos(radangle); - - /* - * Determine destination width and height by rotating a source box, at pixel center - */ - rotate(0.5, 0.5, sinangle, cosangle, center, &x0, &y0); - rotate(width - 0.5, 0.5, sinangle, cosangle, center, &x1, &y1); - rotate(0.5, height - 0.5, sinangle, cosangle, center, &x2, &y2); - rotate(width - 0.5, height - 0.5, sinangle, cosangle, center, &x3, &y3); - - minx = (int)SDL_floor( SDL_min( SDL_min(x0, x1), SDL_min(x2, x3) ) ); - maxx = (int)SDL_ceil( SDL_max( SDL_max(x0, x1), SDL_max(x2, x3) ) ); - - miny = (int)SDL_floor( SDL_min( SDL_min(y0, y1), SDL_min(y2, y3) ) ); - maxy = (int)SDL_ceil( SDL_max( SDL_max(y0, y1), SDL_max(y2, y3) ) ); - - rect_dest->w = maxx - minx; - rect_dest->h = maxy - miny; - rect_dest->x = minx; - rect_dest->y = miny; - - /* reverse the angle because our rotations are clockwise */ - *sangle = -sinangle; - *cangle = cosangle; - - { - /* The trig code below gets the wrong size (due to FP inaccuracy?) when angle is a multiple of 90 degrees */ - int angle90 = (int)(angle/90); - if(angle90 == angle/90) { /* if the angle is a multiple of 90 degrees */ - angle90 %= 4; - if(angle90 < 0) angle90 += 4; /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */ - if(angle90 & 1) { - rect_dest->w = height; - rect_dest->h = width; - *cangle = 0; - *sangle = angle90 == 1 ? -1 : 1; /* reversed because our rotations are clockwise */ - } else { - rect_dest->w = width; - rect_dest->h = height; - *cangle = angle90 == 0 ? 1 : -1; - *sangle = 0; - } - } - } -} - -/* Computes source pointer X/Y increments for a rotation that's a multiple of 90 degrees. */ -static void -computeSourceIncrements90(SDL_Surface * src, int bpp, int angle, int flipx, int flipy, - int *sincx, int *sincy, int *signx, int *signy) -{ - int pitch = flipy ? -src->pitch : src->pitch; - if (flipx) { - bpp = -bpp; - } - switch (angle) { /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */ - case 0: *sincx = bpp; *sincy = pitch - src->w * *sincx; *signx = *signy = 1; break; - case 1: *sincx = -pitch; *sincy = bpp - *sincx * src->h; *signx = 1; *signy = -1; break; - case 2: *sincx = -bpp; *sincy = -src->w * *sincx - pitch; *signx = *signy = -1; break; - case 3: default: *sincx = pitch; *sincy = -*sincx * src->h - bpp; *signx = -1; *signy = 1; break; - } - if (flipx) { - *signx = -*signx; - } - if (flipy) { - *signy = -*signy; - } -} - -/* Performs a relatively fast rotation/flip when the angle is a multiple of 90 degrees. */ -#define TRANSFORM_SURFACE_90(pixelType) \ - int dy, dincy = dst->pitch - dst->w*sizeof(pixelType), sincx, sincy, signx, signy; \ - Uint8 *sp = (Uint8*)src->pixels, *dp = (Uint8*)dst->pixels, *de; \ - \ - computeSourceIncrements90(src, sizeof(pixelType), angle, flipx, flipy, &sincx, &sincy, &signx, &signy); \ - if (signx < 0) sp += (src->w-1)*sizeof(pixelType); \ - if (signy < 0) sp += (src->h-1)*src->pitch; \ - \ - for (dy = 0; dy < dst->h; sp += sincy, dp += dincy, dy++) { \ - if (sincx == sizeof(pixelType)) { /* if advancing src and dest equally, use SDL_memcpy */ \ - SDL_memcpy(dp, sp, dst->w*sizeof(pixelType)); \ - sp += dst->w*sizeof(pixelType); \ - dp += dst->w*sizeof(pixelType); \ - } else { \ - for (de = dp + dst->w*sizeof(pixelType); dp != de; sp += sincx, dp += sizeof(pixelType)) { \ - *(pixelType*)dp = *(pixelType*)sp; \ - } \ - } \ - } - -static void -transformSurfaceRGBA90(SDL_Surface * src, SDL_Surface * dst, int angle, int flipx, int flipy) -{ - TRANSFORM_SURFACE_90(tColorRGBA); -} - -static void -transformSurfaceY90(SDL_Surface * src, SDL_Surface * dst, int angle, int flipx, int flipy) -{ - TRANSFORM_SURFACE_90(tColorY); -} - -#undef TRANSFORM_SURFACE_90 - -/* ! -\brief Internal 32 bit rotozoomer with optional anti-aliasing. - -Rotates and zooms 32 bit RGBA/ABGR 'src' surface to 'dst' surface based on the control -parameters by scanning the destination surface and applying optionally anti-aliasing -by bilinear interpolation. -Assumes src and dst surfaces are of 32 bit depth. -Assumes dst surface was allocated with the correct dimensions. - -\param src Source surface. -\param dst Destination surface. -\param isin Integer version of sine of angle. -\param icos Integer version of cosine of angle. -\param flipx Flag indicating horizontal mirroring should be applied. -\param flipy Flag indicating vertical mirroring should be applied. -\param smooth Flag indicating anti-aliasing should be used. -\param dst_rect destination coordinates -\param center true center. -*/ -static void -transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int isin, int icos, - int flipx, int flipy, int smooth, - const SDL_Rect *rect_dest, - const SDL_FPoint *center) -{ - int sw, sh; - int cx, cy; - tColorRGBA c00, c01, c10, c11, cswap; - tColorRGBA *pc, *sp; - int gap; - const int fp_half = (1<<15); - - /* - * Variable setup - */ - sw = src->w - 1; - sh = src->h - 1; - pc = (tColorRGBA*) dst->pixels; - gap = dst->pitch - dst->w * 4; - cx = (int)(center->x * 65536.0); - cy = (int)(center->y * 65536.0); - - /* - * Switch between interpolating and non-interpolating code - */ - if (smooth) { - int y; - for (y = 0; y < dst->h; y++) { - int x; - double src_x = (rect_dest->x + 0 + 0.5 - center->x); - double src_y = (rect_dest->y + y + 0.5 - center->y); - int sdx = (int)((icos * src_x - isin * src_y) + cx - fp_half); - int sdy = (int)((isin * src_x + icos * src_y) + cy - fp_half); - for (x = 0; x < dst->w; x++) { - int dx = (sdx >> 16); - int dy = (sdy >> 16); - if (flipx) dx = sw - dx; - if (flipy) dy = sh - dy; - if ((dx > -1) && (dy > -1) && (dx < (src->w-1)) && (dy < (src->h-1))) { - int ex, ey; - int t1, t2; - sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy) + dx; - c00 = *sp; - sp += 1; - c01 = *sp; - sp += (src->pitch/4); - c11 = *sp; - sp -= 1; - c10 = *sp; - if (flipx) { - cswap = c00; c00=c01; c01=cswap; - cswap = c10; c10=c11; c11=cswap; - } - if (flipy) { - cswap = c00; c00=c10; c10=cswap; - cswap = c01; c01=c11; c11=cswap; - } - /* - * Interpolate colors - */ - ex = (sdx & 0xffff); - ey = (sdy & 0xffff); - t1 = ((((c01.r - c00.r) * ex) >> 16) + c00.r) & 0xff; - t2 = ((((c11.r - c10.r) * ex) >> 16) + c10.r) & 0xff; - pc->r = (((t2 - t1) * ey) >> 16) + t1; - t1 = ((((c01.g - c00.g) * ex) >> 16) + c00.g) & 0xff; - t2 = ((((c11.g - c10.g) * ex) >> 16) + c10.g) & 0xff; - pc->g = (((t2 - t1) * ey) >> 16) + t1; - t1 = ((((c01.b - c00.b) * ex) >> 16) + c00.b) & 0xff; - t2 = ((((c11.b - c10.b) * ex) >> 16) + c10.b) & 0xff; - pc->b = (((t2 - t1) * ey) >> 16) + t1; - t1 = ((((c01.a - c00.a) * ex) >> 16) + c00.a) & 0xff; - t2 = ((((c11.a - c10.a) * ex) >> 16) + c10.a) & 0xff; - pc->a = (((t2 - t1) * ey) >> 16) + t1; - } - sdx += icos; - sdy += isin; - pc++; - } - pc = (tColorRGBA *) ((Uint8 *) pc + gap); - } - } else { - int y; - for (y = 0; y < dst->h; y++) { - int x; - double src_x = (rect_dest->x + 0 + 0.5 - center->x); - double src_y = (rect_dest->y + y + 0.5 - center->y); - int sdx = (int)((icos * src_x - isin * src_y) + cx - fp_half); - int sdy = (int)((isin * src_x + icos * src_y) + cy - fp_half); - for (x = 0; x < dst->w; x++) { - int dx = (sdx >> 16); - int dy = (sdy >> 16); - if ((unsigned)dx < (unsigned)src->w && (unsigned)dy < (unsigned)src->h) { - if(flipx) dx = sw - dx; - if(flipy) dy = sh - dy; - *pc = *((tColorRGBA *)((Uint8 *)src->pixels + src->pitch * dy) + dx); - } - sdx += icos; - sdy += isin; - pc++; - } - pc = (tColorRGBA *) ((Uint8 *) pc + gap); - } - } -} - -/* ! - -\brief Rotates and zooms 8 bit palette/Y 'src' surface to 'dst' surface without smoothing. - -Rotates and zooms 8 bit RGBA/ABGR 'src' surface to 'dst' surface based on the control -parameters by scanning the destination surface. -Assumes src and dst surfaces are of 8 bit depth. -Assumes dst surface was allocated with the correct dimensions. - -\param src Source surface. -\param dst Destination surface. -\param isin Integer version of sine of angle. -\param icos Integer version of cosine of angle. -\param flipx Flag indicating horizontal mirroring should be applied. -\param flipy Flag indicating vertical mirroring should be applied. -\param dst_rect destination coordinates -\param center true center. -*/ -static void -transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int isin, int icos, int flipx, int flipy, - const SDL_Rect *rect_dest, - const SDL_FPoint *center) -{ - int sw, sh; - int cx, cy; - tColorY *pc; - int gap; - const int fp_half = (1<<15); - int y; - - /* - * Variable setup - */ - sw = src->w - 1; - sh = src->h - 1; - pc = (tColorY*) dst->pixels; - gap = dst->pitch - dst->w; - cx = (int)(center->x * 65536.0); - cy = (int)(center->y * 65536.0); - - /* - * Clear surface to colorkey - */ - SDL_memset(pc, (int)(get_colorkey(src) & 0xff), dst->pitch * dst->h); - /* - * Iterate through destination surface - */ - for (y = 0; y < dst->h; y++) { - int x; - double src_x = (rect_dest->x + 0 + 0.5 - center->x); - double src_y = (rect_dest->y + y + 0.5 - center->y); - int sdx = (int)((icos * src_x - isin * src_y) + cx - fp_half); - int sdy = (int)((isin * src_x + icos * src_y) + cy - fp_half); - for (x = 0; x < dst->w; x++) { - int dx = (sdx >> 16); - int dy = (sdy >> 16); - if ((unsigned)dx < (unsigned)src->w && (unsigned)dy < (unsigned)src->h) { - if (flipx) dx = sw - dx; - if (flipy) dy = sh- dy; - *pc = *((tColorY *)src->pixels + src->pitch * dy + dx); - } - sdx += icos; - sdy += isin; - pc++; - } - pc += gap; - } -} - - -/* ! -\brief Rotates and zooms a surface with different horizontal and vertival scaling factors and optional anti-aliasing. - -Rotates a 32-bit or 8-bit 'src' surface to newly created 'dst' surface. -'angle' is the rotation in degrees, 'center' the rotation center. If 'smooth' is set -then the destination 32-bit surface is anti-aliased. 8-bit surfaces must have a colorkey. 32-bit -surfaces must have a 8888 layout with red, green, blue and alpha masks (any ordering goes). -The blend mode of the 'src' surface has some effects on generation of the 'dst' surface: The NONE -mode will set the BLEND mode on the 'dst' surface. The MOD mode either generates a white 'dst' -surface and sets the colorkey or fills the it with the colorkey before copying the pixels. -When using the NONE and MOD modes, color and alpha modulation must be applied before using this function. - -\param src The surface to rotozoom. -\param angle The angle to rotate in degrees. -\param zoomy The vertical coordinate of the center of rotation -\param smooth Antialiasing flag; set to SMOOTHING_ON to enable. -\param flipx Set to 1 to flip the image horizontally -\param flipy Set to 1 to flip the image vertically -\param rect_dest The destination rect bounding box -\param cangle The angle cosine -\param sangle The angle sine -\param center The true coordinate of the center of rotation -\return The new rotated surface. - -*/ - -SDL_Surface * -SDLgfx_rotateSurface(SDL_Surface * src, double angle, int smooth, int flipx, int flipy, - const SDL_Rect *rect_dest, double cangle, double sangle, const SDL_FPoint *center) -{ - SDL_Surface *rz_dst; - int is8bit, angle90; - int i; - SDL_BlendMode blendmode; - Uint32 colorkey = 0; - int colorKeyAvailable = SDL_FALSE; - double sangleinv, cangleinv; - - /* Sanity check */ - if (src == NULL) - return NULL; - - if (SDL_HasColorKey(src)) { - if (SDL_GetColorKey(src, &colorkey) == 0) { - colorKeyAvailable = SDL_TRUE; - } - } - /* This function requires a 32-bit surface or 8-bit surface with a colorkey */ - is8bit = src->format->BitsPerPixel == 8 && colorKeyAvailable; - if (!(is8bit || (src->format->BitsPerPixel == 32 && src->format->Amask))) - return NULL; - - /* Calculate target factors from sine/cosine and zoom */ - sangleinv = sangle*65536.0; - cangleinv = cangle*65536.0; - - /* Alloc space to completely contain the rotated surface */ - rz_dst = NULL; - if (is8bit) { - /* Target surface is 8 bit */ - rz_dst = SDL_CreateRGBSurfaceWithFormat(0, rect_dest->w, rect_dest->h + GUARD_ROWS, 8, src->format->format); - if (rz_dst != NULL) { - if (src->format->palette) { - for (i = 0; i < src->format->palette->ncolors; i++) { - rz_dst->format->palette->colors[i] = src->format->palette->colors[i]; - } - rz_dst->format->palette->ncolors = src->format->palette->ncolors; - } - } - } else { - /* Target surface is 32 bit with source RGBA ordering */ - rz_dst = SDL_CreateRGBSurface(0, rect_dest->w, rect_dest->h + GUARD_ROWS, 32, - src->format->Rmask, src->format->Gmask, - src->format->Bmask, src->format->Amask); - } - - /* Check target */ - if (rz_dst == NULL) - return NULL; - - /* Adjust for guard rows */ - rz_dst->h = rect_dest->h; - - SDL_GetSurfaceBlendMode(src, &blendmode); - - if (colorKeyAvailable == SDL_TRUE) { - /* If available, the colorkey will be used to discard the pixels that are outside of the rotated area. */ - SDL_SetColorKey(rz_dst, SDL_TRUE, colorkey); - SDL_FillRect(rz_dst, NULL, colorkey); - } else if (blendmode == SDL_BLENDMODE_NONE) { - blendmode = SDL_BLENDMODE_BLEND; - } else if (blendmode == SDL_BLENDMODE_MOD || blendmode == SDL_BLENDMODE_MUL) { - /* Without a colorkey, the target texture has to be white for the MOD and MUL blend mode so - * that the pixels outside the rotated area don't affect the destination surface. - */ - colorkey = SDL_MapRGBA(rz_dst->format, 255, 255, 255, 0); - SDL_FillRect(rz_dst, NULL, colorkey); - /* Setting a white colorkey for the destination surface makes the final blit discard - * all pixels outside of the rotated area. This doesn't interfere with anything because - * white pixels are already a no-op and the MOD blend mode does not interact with alpha. - */ - SDL_SetColorKey(rz_dst, SDL_TRUE, colorkey); - } - - SDL_SetSurfaceBlendMode(rz_dst, blendmode); - - /* Lock source surface */ - if (SDL_MUSTLOCK(src)) { - SDL_LockSurface(src); - } - - /* check if the rotation is a multiple of 90 degrees so we can take a fast path and also somewhat reduce - * the off-by-one problem in transformSurfaceRGBA that expresses itself when the rotation is near - * multiples of 90 degrees. - */ - angle90 = (int)(angle/90); - if (angle90 == angle/90) { - angle90 %= 4; - if (angle90 < 0) angle90 += 4; /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */ - } else { - angle90 = -1; - } - - if (is8bit) { - /* Call the 8-bit transformation routine to do the rotation */ - if(angle90 >= 0) { - transformSurfaceY90(src, rz_dst, angle90, flipx, flipy); - } else { - transformSurfaceY(src, rz_dst, (int)sangleinv, (int)cangleinv, - flipx, flipy, rect_dest, center); - } - } else { - /* Call the 32-bit transformation routine to do the rotation */ - if (angle90 >= 0) { - transformSurfaceRGBA90(src, rz_dst, angle90, flipx, flipy); - } else { - transformSurfaceRGBA(src, rz_dst, (int)sangleinv, (int)cangleinv, - flipx, flipy, smooth, rect_dest, center); - } - } - - /* Unlock source surface */ - if (SDL_MUSTLOCK(src)) { - SDL_UnlockSurface(src); - } - - /* Return rotated surface */ - return rz_dst; -} - -#endif /* SDL_VIDEO_RENDER_PS2 && !SDL_RENDER_DISABLED */ diff --git a/src/render/ps2/SDL_rotate.h b/src/render/ps2/SDL_rotate.h deleted file mode 100644 index 8d7ec9d28..000000000 --- a/src/render/ps2/SDL_rotate.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga - - 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. -*/ - -#ifndef SDL_rotate_h_ -#define SDL_rotate_h_ - -extern SDL_Surface *SDLgfx_rotateSurface(SDL_Surface * src, double angle, int smooth, int flipx, int flipy, - const SDL_Rect *rect_dest, double cangle, double sangle, const SDL_FPoint *center); -extern void SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle, const SDL_FPoint *center, - SDL_Rect *rect_dest, double *cangle, double *sangle); - -#endif /* SDL_rotate_h_ */ diff --git a/src/render/ps2/SDL_triangle.c b/src/render/ps2/SDL_triangle.c deleted file mode 100644 index 1dc073cd9..000000000 --- a/src/render/ps2/SDL_triangle.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga - - 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_PS2 && !SDL_RENDER_DISABLED - -#include "SDL_surface.h" -#include "SDL_triangle.h" - -#include "../../video/SDL_blit.h" - -/* fixed points bits precision - * Set to 1, so that it can start rendering wth middle of a pixel precision. - * It doesn't need to be increased. - * But, if increased too much, it overflows (srcx, srcy) coordinates used for filling with texture. - * (which could be turned to int64). - */ -#define FP_BITS 1 - - -void PS2_trianglepoint_2_fixedpoint(SDL_Point *a) { - a->x <<= FP_BITS; - a->y <<= FP_BITS; -} - -/* bounding rect of three points (in fixed point) */ -static void bounding_rect_fixedpoint(const SDL_Point *a, const SDL_Point *b, const SDL_Point *c, SDL_Rect *r) -{ - int min_x = SDL_min(a->x, SDL_min(b->x, c->x)); - int max_x = SDL_max(a->x, SDL_max(b->x, c->x)); - int min_y = SDL_min(a->y, SDL_min(b->y, c->y)); - int max_y = SDL_max(a->y, SDL_max(b->y, c->y)); - /* points are in fixed point, shift back */ - r->x = min_x >> FP_BITS; - r->y = min_y >> FP_BITS; - r->w = (max_x - min_x) >> FP_BITS; - r->h = (max_y - min_y) >> FP_BITS; -} - -/* bounding rect of three points */ -static void bounding_rect(const SDL_Point *a, const SDL_Point *b, const SDL_Point *c, SDL_Rect *r) -{ - int min_x = SDL_min(a->x, SDL_min(b->x, c->x)); - int max_x = SDL_max(a->x, SDL_max(b->x, c->x)); - int min_y = SDL_min(a->y, SDL_min(b->y, c->y)); - int max_y = SDL_max(a->y, SDL_max(b->y, c->y)); - r->x = min_x; - r->y = min_y; - r->w = (max_x - min_x); - r->h = (max_y - min_y); -} - - -/* Triangle rendering, using Barycentric coordinates (w0, w1, w2) - * - * The cross product isn't computed from scratch at each iteration, - * but optimized using constant step increments - * - */ - -#define TRIANGLE_BEGIN_LOOP \ - { \ - int x, y; \ - for (y = 0; y < dstrect.h; y++) { \ - /* y start */ \ - int w0 = w0_row; \ - int w1 = w1_row; \ - int w2 = w2_row; \ - for (x = 0; x < dstrect.w; x++) { \ - /* In triangle */ \ - if (w0 + bias_w0 >= 0 && w1 + bias_w1 >= 0 && w2 + bias_w2 >= 0) { \ - Uint8 *dptr = (Uint8 *) dst_ptr + x * dstbpp; \ - - -/* Use 64 bits precision to prevent overflow when interpolating color / texture with wide triangles */ -#define TRIANGLE_GET_TEXTCOORD \ - int srcx = (int)(((Sint64)w0 * s2s0_x + (Sint64)w1 * s2s1_x + s2_x_area.x) / area); \ - int srcy = (int)(((Sint64)w0 * s2s0_y + (Sint64)w1 * s2s1_y + s2_x_area.y) / area); \ - -#define TRIANGLE_GET_MAPPED_COLOR \ - int r = (int)(((Sint64)w0 * c0.r + (Sint64)w1 * c1.r + (Sint64)w2 * c2.r) / area); \ - int g = (int)(((Sint64)w0 * c0.g + (Sint64)w1 * c1.g + (Sint64)w2 * c2.g) / area); \ - int b = (int)(((Sint64)w0 * c0.b + (Sint64)w1 * c1.b + (Sint64)w2 * c2.b) / area); \ - int a = (int)(((Sint64)w0 * c0.a + (Sint64)w1 * c1.a + (Sint64)w2 * c2.a) / area); \ - int color = SDL_MapRGBA(format, r, g, b, a); \ - -#define TRIANGLE_GET_COLOR \ - int r = (int)(((Sint64)w0 * c0.r + (Sint64)w1 * c1.r + (Sint64)w2 * c2.r) / area); \ - int g = (int)(((Sint64)w0 * c0.g + (Sint64)w1 * c1.g + (Sint64)w2 * c2.g) / area); \ - int b = (int)(((Sint64)w0 * c0.b + (Sint64)w1 * c1.b + (Sint64)w2 * c2.b) / area); \ - int a = (int)(((Sint64)w0 * c0.a + (Sint64)w1 * c1.a + (Sint64)w2 * c2.a) / area); \ - - -#define TRIANGLE_END_LOOP \ - } \ - /* x += 1 */ \ - w0 += d2d1_y; \ - w1 += d0d2_y; \ - w2 += d1d0_y; \ - } \ - /* y += 1 */ \ - w0_row += d1d2_x; \ - w1_row += d2d0_x; \ - w2_row += d0d1_x; \ - dst_ptr += dst_pitch; \ - } \ - } \ - -#endif /* SDL_VIDEO_RENDER_PS2 && !SDL_RENDER_DISABLED */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/render/ps2/SDL_triangle.h b/src/render/ps2/SDL_triangle.h deleted file mode 100644 index 39f4b5abc..000000000 --- a/src/render/ps2/SDL_triangle.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2022 Sam Lantinga - - 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. -*/ - -#ifndef SDL_triangle_h_ -#define SDL_triangle_h_ - -#include "../../SDL_internal.h" - -extern int SDL_PS2_FillTriangle(SDL_Surface *dst, - SDL_Point *d0, SDL_Point *d1, SDL_Point *d2, - SDL_BlendMode blend, SDL_Color c0, SDL_Color c1, SDL_Color c2); - -extern int SDL_PS2_BlitTriangle( - SDL_Surface *src, - SDL_Point *s0, SDL_Point *s1, SDL_Point *s2, - SDL_Surface *dst, - SDL_Point *d0, SDL_Point *d1, SDL_Point *d2, - SDL_Color c0, SDL_Color c1, SDL_Color c2); - -extern void PS2_trianglepoint_2_fixedpoint(SDL_Point *a); - -#endif /* SDL_triangle_h_ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/ps2/SDL_ps2framebuffer.c b/src/video/ps2/SDL_ps2framebuffer.c index 34d6771cc..47b08a209 100644 --- a/src/video/ps2/SDL_ps2framebuffer.c +++ b/src/video/ps2/SDL_ps2framebuffer.c @@ -31,7 +31,7 @@ int SDL_PS2_CreateWindowFramebuffer(_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch) { SDL_Surface *surface; - const Uint32 surface_format = SDL_PIXELFORMAT_RGB888; + const Uint32 surface_format = SDL_PIXELFORMAT_ABGR8888; int w, h; /* Free the old framebuffer surface */ diff --git a/src/video/ps2/SDL_ps2video.c b/src/video/ps2/SDL_ps2video.c index c0ca5b2a1..65d51c6bb 100644 --- a/src/video/ps2/SDL_ps2video.c +++ b/src/video/ps2/SDL_ps2video.c @@ -48,23 +48,57 @@ #include "SDL_ps2framebuffer_c.h" #include "SDL_hints.h" -#define PS2VID_DRIVER_NAME "ps2" - -/* Initialization/Query functions */ -static int PS2_VideoInit(_THIS); -static int PS2_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode); -static void PS2_VideoQuit(_THIS); - /* PS2 driver bootstrap functions */ -static void -PS2_DeleteDevice(SDL_VideoDevice * device) +static int PS2_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) +{ + return 0; +} + +static void PS2_DeleteDevice(SDL_VideoDevice * device) { SDL_free(device); } -static SDL_VideoDevice * -PS2_CreateDevice(int devindex) +static int PS2_VideoInit(_THIS) +{ + SDL_VideoDisplay display; + SDL_DisplayMode current_mode; + + SDL_zero(current_mode); + + current_mode.w = 640; + current_mode.h = 480; + current_mode.refresh_rate = 60; + + /* 32 bpp for default */ + current_mode.format = SDL_PIXELFORMAT_ABGR8888; + current_mode.driverdata = NULL; + + SDL_zero(display); + display.desktop_mode = current_mode; + display.current_mode = current_mode; + display.driverdata = NULL; + SDL_AddDisplayMode(&display, ¤t_mode); + + /* 16 bpp secondary mode */ + current_mode.format = SDL_PIXELFORMAT_ABGR1555; + display.desktop_mode = current_mode; + display.current_mode = current_mode; + SDL_AddDisplayMode(&display, ¤t_mode); + + + SDL_AddVideoDisplay(&display, SDL_FALSE); + + return 1; +} + +static void PS2_VideoQuit(_THIS) +{ + /*gsKit_deinit_global(gsGlobal);*/ +} + +static SDL_VideoDevice *PS2_CreateDevice(int devindex) { SDL_VideoDevice *device; @@ -74,7 +108,6 @@ PS2_CreateDevice(int devindex) SDL_OutOfMemory(); return (0); } - device->is_dummy = SDL_TRUE; /* Set the function pointers */ device->VideoInit = PS2_VideoInit; @@ -91,121 +124,11 @@ PS2_CreateDevice(int devindex) } VideoBootStrap PS2_bootstrap = { - PS2VID_DRIVER_NAME, "SDL PS2 video driver", + "PS2", + "PS2 Video Driver", PS2_CreateDevice }; -int -PS2_VideoInit(_THIS) -{ - /* - ee_sema_t sema; - sema.init_count = 0; - sema.max_count = 1; - sema.option = 0; - vsync_sema_id = CreateSema(&sema); - - gsGlobal = gsKit_init_global(); - - gsGlobal->Mode = gsKit_check_rom(); - if (gsGlobal->Mode == GS_MODE_PAL){ - gsGlobal->Height = 512; - } else { - gsGlobal->Height = 448; - } - - gsGlobal->PSM = GS_PSM_CT24; - gsGlobal->PSMZ = GS_PSMZ_16S; - gsGlobal->ZBuffering = GS_SETTING_OFF; - gsGlobal->DoubleBuffering = GS_SETTING_ON; - gsGlobal->PrimAlphaEnable = GS_SETTING_ON; - gsGlobal->Dithering = GS_SETTING_OFF; - - gsKit_set_primalpha(gsGlobal, GS_SETREG_ALPHA(0, 1, 0, 1, 0), 0); - - dmaKit_init(D_CTRL_RELE_OFF, D_CTRL_MFD_OFF, D_CTRL_STS_UNSPEC, D_CTRL_STD_OFF, D_CTRL_RCYC_8, 1 << DMA_CHANNEL_GIF); - dmaKit_chan_init(DMA_CHANNEL_GIF); - - printf("\nGraphics: created %ix%i video surface\n", - gsGlobal->Width, gsGlobal->Height); - - gsKit_set_clamp(gsGlobal, GS_CMODE_REPEAT); - - gsKit_vram_clear(gsGlobal); - - gsKit_init_screen(gsGlobal); - - gsKit_TexManager_init(gsGlobal); - - gsKit_add_vsync_handler(vsync_handler); - - gsKit_mode_switch(gsGlobal, GS_ONESHOT); - - gsKit_clear(gsGlobal, GS_SETREG_RGBAQ(0x80,0x00,0x00,0x80,0x00)); - - if (gsGlobal->DoubleBuffering == GS_SETTING_OFF) { - gsKit_sync(gsGlobal); - gsKit_queue_exec(gsGlobal); - } else { - gsKit_queue_exec(gsGlobal); - gsKit_finish(); - gsKit_sync(gsGlobal); - gsKit_flip(gsGlobal); - } - gsKit_TexManager_nextFrame(gsGlobal); - */ - - SDL_DisplayMode mode; - - /* Use a fake 32-bpp desktop mode */ - SDL_zero(mode); - mode.format = SDL_PIXELFORMAT_RGBA8888; - mode.w = 640; - /*if (gsGlobal->Mode == GS_MODE_PAL){ - mode.h = 512; - } else { - mode.h = 448; - }*/ - mode.h = 448; - mode.refresh_rate = 60; - mode.driverdata = NULL; - if (SDL_AddBasicVideoDisplay(&mode) < 0) { - return -1; - } - - SDL_AddDisplayMode(&_this->displays[0], &mode); - - /* We're done! */ - return 0; -} - -static int -SDL_to_PS2_PFM(Uint32 format) -{ - switch (format) { - case SDL_PIXELFORMAT_RGBA5551: - return GS_PSM_CT16S; - case SDL_PIXELFORMAT_RGB24: - return GS_PSM_CT24; - case SDL_PIXELFORMAT_ABGR32: - return GS_PSM_CT32; - default: - return GS_PSM_CT24; - } -} - -static int -PS2_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) -{ - return 0; -} - -void -PS2_VideoQuit(_THIS) -{ - /*gsKit_deinit_global(gsGlobal);*/ -} - #endif /* SDL_VIDEO_DRIVER_PS2 */ /* vi: set ts=4 sw=4 expandtab: */