Merge commit 'dec0d4ec4153bf9fc2b78ae6c2df45b6ea8dde7a' as 'external/sdl/SDL'

This commit is contained in:
2023-07-25 22:27:55 +02:00
1663 changed files with 627495 additions and 0 deletions

View File

@ -0,0 +1,132 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#if (defined(SDL_VIDEO_RENDER_D3D) || defined(SDL_VIDEO_RENDER_D3D11) || defined(SDL_VIDEO_RENDER_D3D12)) && !defined(SDL_RENDER_DISABLED)
#include "SDL_d3dmath.h"
/* Direct3D matrix math functions */
Float4X4 MatrixIdentity()
{
Float4X4 m;
SDL_zero(m);
m.v._11 = 1.0f;
m.v._22 = 1.0f;
m.v._33 = 1.0f;
m.v._44 = 1.0f;
return m;
}
Float4X4 MatrixMultiply(Float4X4 M1, Float4X4 M2)
{
Float4X4 m;
m.v._11 = M1.v._11 * M2.v._11 + M1.v._12 * M2.v._21 + M1.v._13 * M2.v._31 + M1.v._14 * M2.v._41;
m.v._12 = M1.v._11 * M2.v._12 + M1.v._12 * M2.v._22 + M1.v._13 * M2.v._32 + M1.v._14 * M2.v._42;
m.v._13 = M1.v._11 * M2.v._13 + M1.v._12 * M2.v._23 + M1.v._13 * M2.v._33 + M1.v._14 * M2.v._43;
m.v._14 = M1.v._11 * M2.v._14 + M1.v._12 * M2.v._24 + M1.v._13 * M2.v._34 + M1.v._14 * M2.v._44;
m.v._21 = M1.v._21 * M2.v._11 + M1.v._22 * M2.v._21 + M1.v._23 * M2.v._31 + M1.v._24 * M2.v._41;
m.v._22 = M1.v._21 * M2.v._12 + M1.v._22 * M2.v._22 + M1.v._23 * M2.v._32 + M1.v._24 * M2.v._42;
m.v._23 = M1.v._21 * M2.v._13 + M1.v._22 * M2.v._23 + M1.v._23 * M2.v._33 + M1.v._24 * M2.v._43;
m.v._24 = M1.v._21 * M2.v._14 + M1.v._22 * M2.v._24 + M1.v._23 * M2.v._34 + M1.v._24 * M2.v._44;
m.v._31 = M1.v._31 * M2.v._11 + M1.v._32 * M2.v._21 + M1.v._33 * M2.v._31 + M1.v._34 * M2.v._41;
m.v._32 = M1.v._31 * M2.v._12 + M1.v._32 * M2.v._22 + M1.v._33 * M2.v._32 + M1.v._34 * M2.v._42;
m.v._33 = M1.v._31 * M2.v._13 + M1.v._32 * M2.v._23 + M1.v._33 * M2.v._33 + M1.v._34 * M2.v._43;
m.v._34 = M1.v._31 * M2.v._14 + M1.v._32 * M2.v._24 + M1.v._33 * M2.v._34 + M1.v._34 * M2.v._44;
m.v._41 = M1.v._41 * M2.v._11 + M1.v._42 * M2.v._21 + M1.v._43 * M2.v._31 + M1.v._44 * M2.v._41;
m.v._42 = M1.v._41 * M2.v._12 + M1.v._42 * M2.v._22 + M1.v._43 * M2.v._32 + M1.v._44 * M2.v._42;
m.v._43 = M1.v._41 * M2.v._13 + M1.v._42 * M2.v._23 + M1.v._43 * M2.v._33 + M1.v._44 * M2.v._43;
m.v._44 = M1.v._41 * M2.v._14 + M1.v._42 * M2.v._24 + M1.v._43 * M2.v._34 + M1.v._44 * M2.v._44;
return m;
}
Float4X4 MatrixScaling(float x, float y, float z)
{
Float4X4 m;
SDL_zero(m);
m.v._11 = x;
m.v._22 = y;
m.v._33 = z;
m.v._44 = 1.0f;
return m;
}
Float4X4 MatrixTranslation(float x, float y, float z)
{
Float4X4 m;
SDL_zero(m);
m.v._11 = 1.0f;
m.v._22 = 1.0f;
m.v._33 = 1.0f;
m.v._44 = 1.0f;
m.v._41 = x;
m.v._42 = y;
m.v._43 = z;
return m;
}
Float4X4 MatrixRotationX(float r)
{
float sinR = SDL_sinf(r);
float cosR = SDL_cosf(r);
Float4X4 m;
SDL_zero(m);
m.v._11 = 1.0f;
m.v._22 = cosR;
m.v._23 = sinR;
m.v._32 = -sinR;
m.v._33 = cosR;
m.v._44 = 1.0f;
return m;
}
Float4X4 MatrixRotationY(float r)
{
float sinR = SDL_sinf(r);
float cosR = SDL_cosf(r);
Float4X4 m;
SDL_zero(m);
m.v._11 = cosR;
m.v._13 = -sinR;
m.v._22 = 1.0f;
m.v._31 = sinR;
m.v._33 = cosR;
m.v._44 = 1.0f;
return m;
}
Float4X4 MatrixRotationZ(float r)
{
float sinR = SDL_sinf(r);
float cosR = SDL_cosf(r);
Float4X4 m;
SDL_zero(m);
m.v._11 = cosR;
m.v._12 = sinR;
m.v._21 = -sinR;
m.v._22 = cosR;
m.v._33 = 1.0f;
m.v._44 = 1.0f;
return m;
}
#endif /* (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11 || SDL_VIDEO_RENDER_D3D12) && !defined(SDL_RENDER_DISABLED) */

View File

@ -0,0 +1,81 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#if (defined(SDL_VIDEO_RENDER_D3D) || defined(SDL_VIDEO_RENDER_D3D11) || defined(SDL_VIDEO_RENDER_D3D12)) && !defined(SDL_RENDER_DISABLED)
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/* Direct3D matrix math functions */
typedef struct
{
float x;
float y;
} Float2;
typedef struct
{
float x;
float y;
float z;
} Float3;
typedef struct
{
float x;
float y;
float z;
float w;
} Float4;
typedef struct
{
union
{
struct
{
float _11, _12, _13, _14;
float _21, _22, _23, _24;
float _31, _32, _33, _34;
float _41, _42, _43, _44;
} v;
float m[4][4];
};
} Float4X4;
Float4X4 MatrixIdentity();
Float4X4 MatrixMultiply(Float4X4 M1, Float4X4 M2);
Float4X4 MatrixScaling(float x, float y, float z);
Float4X4 MatrixTranslation(float x, float y, float z);
Float4X4 MatrixRotationX(float r);
Float4X4 MatrixRotationY(float r);
Float4X4 MatrixRotationZ(float r);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#endif /* (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11 || SDL_VIDEO_RENDER_D3D12) && !defined(SDL_RENDER_DISABLED) */

4315
external/sdl/SDL/src/render/SDL_render.c vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,318 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifndef SDL_sysrender_h_
#define SDL_sysrender_h_
#include "SDL_yuv_sw_c.h"
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/**
* A rectangle, with the origin at the upper left (double precision).
*/
typedef struct SDL_DRect
{
double x;
double y;
double w;
double h;
} SDL_DRect;
/* The SDL 2D rendering system */
typedef struct SDL_RenderDriver SDL_RenderDriver;
/* Rendering view state */
typedef struct SDL_RenderViewState
{
int pixel_w;
int pixel_h;
SDL_Rect viewport;
SDL_Rect clip_rect;
SDL_bool clipping_enabled;
SDL_FPoint scale;
} SDL_RenderViewState;
/* Define the SDL texture structure */
struct SDL_Texture
{
const void *magic;
Uint32 format; /**< The pixel format of the texture */
int access; /**< SDL_TextureAccess */
int w; /**< The width of the texture */
int h; /**< The height of the texture */
int modMode; /**< The texture modulation mode */
SDL_BlendMode blendMode; /**< The texture blend mode */
SDL_ScaleMode scaleMode; /**< The texture scale mode */
SDL_Color color; /**< Texture modulation values */
SDL_RenderViewState view; /**< Target texture view state */
SDL_Renderer *renderer;
/* Support for formats not supported directly by the renderer */
SDL_Texture *native;
SDL_SW_YUVTexture *yuv;
void *pixels;
int pitch;
SDL_Rect locked_rect;
SDL_Surface *locked_surface; /**< Locked region exposed as a SDL surface */
Uint32 last_command_generation; /* last command queue generation this texture was in. */
void *driverdata; /**< Driver specific texture representation */
void *userdata;
SDL_Texture *prev;
SDL_Texture *next;
};
typedef enum
{
SDL_RENDERCMD_NO_OP,
SDL_RENDERCMD_SETVIEWPORT,
SDL_RENDERCMD_SETCLIPRECT,
SDL_RENDERCMD_SETDRAWCOLOR,
SDL_RENDERCMD_CLEAR,
SDL_RENDERCMD_DRAW_POINTS,
SDL_RENDERCMD_DRAW_LINES,
SDL_RENDERCMD_FILL_RECTS,
SDL_RENDERCMD_COPY,
SDL_RENDERCMD_COPY_EX,
SDL_RENDERCMD_GEOMETRY
} SDL_RenderCommandType;
typedef struct SDL_RenderCommand
{
SDL_RenderCommandType command;
union
{
struct
{
size_t first;
SDL_Rect rect;
} viewport;
struct
{
SDL_bool enabled;
SDL_Rect rect;
} cliprect;
struct
{
size_t first;
size_t count;
Uint8 r, g, b, a;
SDL_BlendMode blend;
SDL_Texture *texture;
} draw;
struct
{
size_t first;
Uint8 r, g, b, a;
} color;
} data;
struct SDL_RenderCommand *next;
} SDL_RenderCommand;
typedef struct SDL_VertexSolid
{
SDL_FPoint position;
SDL_Color color;
} SDL_VertexSolid;
typedef enum
{
SDL_RENDERLINEMETHOD_POINTS,
SDL_RENDERLINEMETHOD_LINES,
SDL_RENDERLINEMETHOD_GEOMETRY,
} SDL_RenderLineMethod;
/* Define the SDL renderer structure */
struct SDL_Renderer
{
const void *magic;
void (*WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event);
int (*GetOutputSize)(SDL_Renderer *renderer, int *w, int *h);
SDL_bool (*SupportsBlendMode)(SDL_Renderer *renderer, SDL_BlendMode blendMode);
int (*CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture);
int (*QueueSetViewport)(SDL_Renderer *renderer, SDL_RenderCommand *cmd);
int (*QueueSetDrawColor)(SDL_Renderer *renderer, SDL_RenderCommand *cmd);
int (*QueueDrawPoints)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points,
int count);
int (*QueueDrawLines)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points,
int count);
int (*QueueFillRects)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FRect *rects,
int count);
int (*QueueCopy)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
const SDL_FRect *srcrect, const SDL_FRect *dstrect);
int (*QueueCopyEx)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
const SDL_FRect *srcquad, const SDL_FRect *dstrect,
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, float scale_x, float scale_y);
int (*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 (*RunCommandQueue)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize);
int (*UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture,
const SDL_Rect *rect, const void *pixels,
int pitch);
#if SDL_HAVE_YUV
int (*UpdateTextureYUV)(SDL_Renderer *renderer, SDL_Texture *texture,
const SDL_Rect *rect,
const Uint8 *Yplane, int Ypitch,
const Uint8 *Uplane, int Upitch,
const Uint8 *Vplane, int Vpitch);
int (*UpdateTextureNV)(SDL_Renderer *renderer, SDL_Texture *texture,
const SDL_Rect *rect,
const Uint8 *Yplane, int Ypitch,
const Uint8 *UVplane, int UVpitch);
#endif
int (*LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture,
const SDL_Rect *rect, void **pixels, int *pitch);
void (*UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture);
void (*SetTextureScaleMode)(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode);
int (*SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture);
int (*RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect,
Uint32 format, void *pixels, int pitch);
int (*RenderPresent)(SDL_Renderer *renderer);
void (*DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture);
void (*DestroyRenderer)(SDL_Renderer *renderer);
int (*SetVSync)(SDL_Renderer *renderer, int vsync);
int (*GL_BindTexture)(SDL_Renderer *renderer, SDL_Texture *texture, float *texw, float *texh);
int (*GL_UnbindTexture)(SDL_Renderer *renderer, SDL_Texture *texture);
void *(*GetMetalLayer)(SDL_Renderer *renderer);
void *(*GetMetalCommandEncoder)(SDL_Renderer *renderer);
/* The current renderer info */
SDL_RendererInfo info;
/* The window associated with the renderer */
SDL_Window *window;
SDL_bool hidden;
/* Whether we should simulate vsync */
SDL_bool wanted_vsync;
SDL_bool simulate_vsync;
Uint64 simulate_vsync_interval_ns;
Uint64 last_present;
/* Support for logical output coordinates */
SDL_Texture *logical_target;
SDL_RendererLogicalPresentation logical_presentation_mode;
SDL_ScaleMode logical_scale_mode;
SDL_FRect logical_src_rect;
SDL_FRect logical_dst_rect;
SDL_RenderViewState *view;
SDL_RenderViewState main_view;
/* The window pixel to point coordinate scale */
SDL_FPoint dpi_scale;
/* The method of drawing lines */
SDL_RenderLineMethod line_method;
/* List of triangle indices to draw rects */
int rect_index_order[6];
/* The list of textures */
SDL_Texture *textures;
SDL_Texture *target;
SDL_Mutex *target_mutex;
SDL_Color color; /**< Color for drawing operations values */
SDL_BlendMode blendMode; /**< The drawing blend mode */
SDL_bool always_batch;
SDL_bool batching;
SDL_RenderCommand *render_commands;
SDL_RenderCommand *render_commands_tail;
SDL_RenderCommand *render_commands_pool;
Uint32 render_command_generation;
Uint32 last_queued_color;
SDL_Rect last_queued_viewport;
SDL_Rect last_queued_cliprect;
SDL_bool last_queued_cliprect_enabled;
SDL_bool color_queued;
SDL_bool viewport_queued;
SDL_bool cliprect_queued;
void *vertex_data;
size_t vertex_data_used;
size_t vertex_data_allocation;
void *driverdata;
};
/* Define the SDL render driver structure */
struct SDL_RenderDriver
{
SDL_Renderer *(*CreateRenderer)(SDL_Window *window, Uint32 flags);
/* Info about the renderer capabilities */
SDL_RendererInfo info;
};
/* Not all of these are available in a given build. Use #ifdefs, etc. */
extern SDL_RenderDriver D3D_RenderDriver;
extern SDL_RenderDriver D3D11_RenderDriver;
extern SDL_RenderDriver D3D12_RenderDriver;
extern SDL_RenderDriver GL_RenderDriver;
extern SDL_RenderDriver GLES2_RenderDriver;
extern SDL_RenderDriver METAL_RenderDriver;
extern SDL_RenderDriver PS2_RenderDriver;
extern SDL_RenderDriver PSP_RenderDriver;
extern SDL_RenderDriver SW_RenderDriver;
extern SDL_RenderDriver VITA_GXM_RenderDriver;
/* Blend mode functions */
extern SDL_BlendFactor SDL_GetBlendModeSrcColorFactor(SDL_BlendMode blendMode);
extern SDL_BlendFactor SDL_GetBlendModeDstColorFactor(SDL_BlendMode blendMode);
extern SDL_BlendOperation SDL_GetBlendModeColorOperation(SDL_BlendMode blendMode);
extern SDL_BlendFactor SDL_GetBlendModeSrcAlphaFactor(SDL_BlendMode blendMode);
extern SDL_BlendFactor SDL_GetBlendModeDstAlphaFactor(SDL_BlendMode blendMode);
extern SDL_BlendOperation SDL_GetBlendModeAlphaOperation(SDL_BlendMode blendMode);
/* drivers call this during their Queue*() methods to make space in a array that are used
for a vertex buffer during RunCommandQueue(). Pointers returned here are only valid until
the next call, because it might be in an array that gets realloc()'d. */
extern void *SDL_AllocateRenderVertices(SDL_Renderer *renderer, const size_t numbytes, const size_t alignment, size_t *offset);
extern int SDL_PrivateBlitSurfaceUncheckedScaled(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, const SDL_Rect *dstrect, SDL_ScaleMode scaleMode);
extern int SDL_PrivateBlitSurfaceScaled(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect, SDL_ScaleMode scaleMode);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#endif /* SDL_sysrender_h_ */

403
external/sdl/SDL/src/render/SDL_yuv_sw.c vendored Normal file
View File

@ -0,0 +1,403 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
/* This is the software implementation of the YUV texture support */
#if SDL_HAVE_YUV
#include "SDL_yuv_sw_c.h"
#include "../video/SDL_yuv_c.h"
SDL_SW_YUVTexture *SDL_SW_CreateYUVTexture(Uint32 format, int w, int h)
{
SDL_SW_YUVTexture *swdata;
switch (format) {
case SDL_PIXELFORMAT_YV12:
case SDL_PIXELFORMAT_IYUV:
case SDL_PIXELFORMAT_YUY2:
case SDL_PIXELFORMAT_UYVY:
case SDL_PIXELFORMAT_YVYU:
case SDL_PIXELFORMAT_NV12:
case SDL_PIXELFORMAT_NV21:
break;
default:
SDL_SetError("Unsupported YUV format");
return NULL;
}
swdata = (SDL_SW_YUVTexture *)SDL_calloc(1, sizeof(*swdata));
if (swdata == NULL) {
SDL_OutOfMemory();
return NULL;
}
swdata->format = format;
swdata->target_format = SDL_PIXELFORMAT_UNKNOWN;
swdata->w = w;
swdata->h = h;
{
size_t dst_size;
if (SDL_CalculateYUVSize(format, w, h, &dst_size, NULL) < 0) {
SDL_SW_DestroyYUVTexture(swdata);
SDL_OutOfMemory();
return NULL;
}
swdata->pixels = (Uint8 *)SDL_aligned_alloc(SDL_SIMDGetAlignment(), dst_size);
if (!swdata->pixels) {
SDL_SW_DestroyYUVTexture(swdata);
SDL_OutOfMemory();
return NULL;
}
}
/* Find the pitch and offset values for the texture */
switch (format) {
case SDL_PIXELFORMAT_YV12:
case SDL_PIXELFORMAT_IYUV:
swdata->pitches[0] = w;
swdata->pitches[1] = (swdata->pitches[0] + 1) / 2;
swdata->pitches[2] = (swdata->pitches[0] + 1) / 2;
swdata->planes[0] = swdata->pixels;
swdata->planes[1] = swdata->planes[0] + swdata->pitches[0] * h;
swdata->planes[2] = swdata->planes[1] + swdata->pitches[1] * ((h + 1) / 2);
break;
case SDL_PIXELFORMAT_YUY2:
case SDL_PIXELFORMAT_UYVY:
case SDL_PIXELFORMAT_YVYU:
swdata->pitches[0] = ((w + 1) / 2) * 4;
swdata->planes[0] = swdata->pixels;
break;
case SDL_PIXELFORMAT_NV12:
case SDL_PIXELFORMAT_NV21:
swdata->pitches[0] = w;
swdata->pitches[1] = 2 * ((swdata->pitches[0] + 1) / 2);
swdata->planes[0] = swdata->pixels;
swdata->planes[1] = swdata->planes[0] + swdata->pitches[0] * h;
break;
default:
SDL_assert(0 && "We should never get here (caught above)");
break;
}
/* We're all done.. */
return swdata;
}
int SDL_SW_QueryYUVTexturePixels(SDL_SW_YUVTexture *swdata, void **pixels,
int *pitch)
{
*pixels = swdata->planes[0];
*pitch = swdata->pitches[0];
return 0;
}
int SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect,
const void *pixels, int pitch)
{
switch (swdata->format) {
case SDL_PIXELFORMAT_YV12:
case SDL_PIXELFORMAT_IYUV:
if (rect->x == 0 && rect->y == 0 &&
rect->w == swdata->w && rect->h == swdata->h) {
SDL_memcpy(swdata->pixels, pixels,
(size_t)(swdata->h * swdata->w) + 2 * ((swdata->h + 1) / 2) * ((swdata->w + 1) / 2));
} else {
Uint8 *src, *dst;
int row;
size_t length;
/* Copy the Y plane */
src = (Uint8 *)pixels;
dst = swdata->pixels + rect->y * swdata->w + rect->x;
length = rect->w;
for (row = 0; row < rect->h; ++row) {
SDL_memcpy(dst, src, length);
src += pitch;
dst += swdata->w;
}
/* Copy the next plane */
src = (Uint8 *)pixels + rect->h * pitch;
dst = swdata->pixels + swdata->h * swdata->w;
dst += rect->y / 2 * ((swdata->w + 1) / 2) + rect->x / 2;
length = (rect->w + 1) / 2;
for (row = 0; row < (rect->h + 1) / 2; ++row) {
SDL_memcpy(dst, src, length);
src += (pitch + 1) / 2;
dst += (swdata->w + 1) / 2;
}
/* Copy the next plane */
src = (Uint8 *)pixels + rect->h * pitch + ((rect->h + 1) / 2) * ((pitch + 1) / 2);
dst = swdata->pixels + swdata->h * swdata->w +
((swdata->h + 1) / 2) * ((swdata->w + 1) / 2);
dst += rect->y / 2 * ((swdata->w + 1) / 2) + rect->x / 2;
length = (rect->w + 1) / 2;
for (row = 0; row < (rect->h + 1) / 2; ++row) {
SDL_memcpy(dst, src, length);
src += (pitch + 1) / 2;
dst += (swdata->w + 1) / 2;
}
}
break;
case SDL_PIXELFORMAT_YUY2:
case SDL_PIXELFORMAT_UYVY:
case SDL_PIXELFORMAT_YVYU:
{
Uint8 *src, *dst;
int row;
size_t length;
src = (Uint8 *)pixels;
dst =
swdata->planes[0] + rect->y * swdata->pitches[0] +
rect->x * 2;
length = 4 * (((size_t)rect->w + 1) / 2);
for (row = 0; row < rect->h; ++row) {
SDL_memcpy(dst, src, length);
src += pitch;
dst += swdata->pitches[0];
}
} break;
case SDL_PIXELFORMAT_NV12:
case SDL_PIXELFORMAT_NV21:
{
if (rect->x == 0 && rect->y == 0 && rect->w == swdata->w && rect->h == swdata->h) {
SDL_memcpy(swdata->pixels, pixels,
(size_t)(swdata->h * swdata->w) + 2 * ((swdata->h + 1) / 2) * ((swdata->w + 1) / 2));
} else {
Uint8 *src, *dst;
int row;
size_t length;
/* Copy the Y plane */
src = (Uint8 *)pixels;
dst = swdata->pixels + rect->y * swdata->w + rect->x;
length = rect->w;
for (row = 0; row < rect->h; ++row) {
SDL_memcpy(dst, src, length);
src += pitch;
dst += swdata->w;
}
/* Copy the next plane */
src = (Uint8 *)pixels + rect->h * pitch;
dst = swdata->pixels + swdata->h * swdata->w;
dst += 2 * ((rect->y + 1) / 2) * ((swdata->w + 1) / 2) + 2 * (rect->x / 2);
length = 2 * (((size_t)rect->w + 1) / 2);
for (row = 0; row < (rect->h + 1) / 2; ++row) {
SDL_memcpy(dst, src, length);
src += 2 * ((pitch + 1) / 2);
dst += 2 * ((swdata->w + 1) / 2);
}
}
}
}
return 0;
}
int SDL_SW_UpdateYUVTexturePlanar(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect,
const Uint8 *Yplane, int Ypitch,
const Uint8 *Uplane, int Upitch,
const Uint8 *Vplane, int Vpitch)
{
const Uint8 *src;
Uint8 *dst;
int row;
size_t length;
/* Copy the Y plane */
src = Yplane;
dst = swdata->pixels + rect->y * swdata->w + rect->x;
length = rect->w;
for (row = 0; row < rect->h; ++row) {
SDL_memcpy(dst, src, length);
src += Ypitch;
dst += swdata->w;
}
/* Copy the U plane */
src = Uplane;
if (swdata->format == SDL_PIXELFORMAT_IYUV) {
dst = swdata->pixels + swdata->h * swdata->w;
} else {
dst = swdata->pixels + swdata->h * swdata->w +
((swdata->h + 1) / 2) * ((swdata->w + 1) / 2);
}
dst += rect->y / 2 * ((swdata->w + 1) / 2) + rect->x / 2;
length = (rect->w + 1) / 2;
for (row = 0; row < (rect->h + 1) / 2; ++row) {
SDL_memcpy(dst, src, length);
src += Upitch;
dst += (swdata->w + 1) / 2;
}
/* Copy the V plane */
src = Vplane;
if (swdata->format == SDL_PIXELFORMAT_YV12) {
dst = swdata->pixels + swdata->h * swdata->w;
} else {
dst = swdata->pixels + swdata->h * swdata->w +
((swdata->h + 1) / 2) * ((swdata->w + 1) / 2);
}
dst += rect->y / 2 * ((swdata->w + 1) / 2) + rect->x / 2;
length = (rect->w + 1) / 2;
for (row = 0; row < (rect->h + 1) / 2; ++row) {
SDL_memcpy(dst, src, length);
src += Vpitch;
dst += (swdata->w + 1) / 2;
}
return 0;
}
int SDL_SW_UpdateNVTexturePlanar(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect,
const Uint8 *Yplane, int Ypitch,
const Uint8 *UVplane, int UVpitch)
{
const Uint8 *src;
Uint8 *dst;
int row;
size_t length;
/* Copy the Y plane */
src = Yplane;
dst = swdata->pixels + rect->y * swdata->w + rect->x;
length = rect->w;
for (row = 0; row < rect->h; ++row) {
SDL_memcpy(dst, src, length);
src += Ypitch;
dst += swdata->w;
}
/* Copy the UV or VU plane */
src = UVplane;
dst = swdata->pixels + swdata->h * swdata->w;
dst += rect->y * ((swdata->w + 1) / 2) + rect->x;
length = (rect->w + 1) / 2;
length *= 2;
for (row = 0; row < (rect->h + 1) / 2; ++row) {
SDL_memcpy(dst, src, length);
src += UVpitch;
dst += 2 * ((swdata->w + 1) / 2);
}
return 0;
}
int SDL_SW_LockYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect,
void **pixels, int *pitch)
{
switch (swdata->format) {
case SDL_PIXELFORMAT_YV12:
case SDL_PIXELFORMAT_IYUV:
case SDL_PIXELFORMAT_NV12:
case SDL_PIXELFORMAT_NV21:
if (rect && (rect->x != 0 || rect->y != 0 || rect->w != swdata->w || rect->h != swdata->h)) {
return SDL_SetError("YV12, IYUV, NV12, NV21 textures only support full surface locks");
}
break;
}
if (rect) {
*pixels = swdata->planes[0] + rect->y * swdata->pitches[0] + rect->x * 2;
} else {
*pixels = swdata->planes[0];
}
*pitch = swdata->pitches[0];
return 0;
}
void SDL_SW_UnlockYUVTexture(SDL_SW_YUVTexture *swdata)
{
}
int SDL_SW_CopyYUVToRGB(SDL_SW_YUVTexture *swdata, const SDL_Rect *srcrect,
Uint32 target_format, int w, int h, void *pixels,
int pitch)
{
int stretch;
/* Make sure we're set up to display in the desired format */
if (target_format != swdata->target_format && swdata->display) {
SDL_DestroySurface(swdata->display);
swdata->display = NULL;
}
stretch = 0;
if (srcrect->x || srcrect->y || srcrect->w < swdata->w || srcrect->h < swdata->h) {
/* The source rectangle has been clipped.
Using a scratch surface is easier than adding clipped
source support to all the blitters, plus that would
slow them down in the general unclipped case.
*/
stretch = 1;
} else if ((srcrect->w != w) || (srcrect->h != h)) {
stretch = 1;
}
if (stretch) {
if (swdata->display) {
swdata->display->w = w;
swdata->display->h = h;
swdata->display->pixels = pixels;
swdata->display->pitch = pitch;
} else {
swdata->display = SDL_CreateSurfaceFrom(pixels, w, h, pitch, target_format);
if (!swdata->display) {
return -1;
}
}
if (!swdata->stretch) {
swdata->stretch = SDL_CreateSurface(swdata->w, swdata->h, target_format);
if (!swdata->stretch) {
return -1;
}
}
pixels = swdata->stretch->pixels;
pitch = swdata->stretch->pitch;
}
if (SDL_ConvertPixels(swdata->w, swdata->h, swdata->format,
swdata->planes[0], swdata->pitches[0],
target_format, pixels, pitch) < 0) {
return -1;
}
if (stretch) {
SDL_Rect rect = *srcrect;
SDL_SoftStretch(swdata->stretch, &rect, swdata->display, NULL);
}
return 0;
}
void SDL_SW_DestroyYUVTexture(SDL_SW_YUVTexture *swdata)
{
if (swdata) {
SDL_aligned_free(swdata->pixels);
SDL_DestroySurface(swdata->stretch);
SDL_DestroySurface(swdata->display);
SDL_free(swdata);
}
}
#endif /* SDL_HAVE_YUV */

View File

@ -0,0 +1,67 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_yuv_sw_c_h_
#define SDL_yuv_sw_c_h_
#include "SDL_internal.h"
/* This is the software implementation of the YUV texture support */
struct SDL_SW_YUVTexture
{
Uint32 format;
Uint32 target_format;
int w, h;
Uint8 *pixels;
/* These are just so we don't have to allocate them separately */
int pitches[3];
Uint8 *planes[3];
/* This is a temporary surface in case we have to stretch copy */
SDL_Surface *stretch;
SDL_Surface *display;
};
typedef struct SDL_SW_YUVTexture SDL_SW_YUVTexture;
SDL_SW_YUVTexture *SDL_SW_CreateYUVTexture(Uint32 format, int w, int h);
int SDL_SW_QueryYUVTexturePixels(SDL_SW_YUVTexture *swdata, void **pixels,
int *pitch);
int SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect,
const void *pixels, int pitch);
int SDL_SW_UpdateYUVTexturePlanar(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect,
const Uint8 *Yplane, int Ypitch,
const Uint8 *Uplane, int Upitch,
const Uint8 *Vplane, int Vpitch);
int SDL_SW_UpdateNVTexturePlanar(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect,
const Uint8 *Yplane, int Ypitch,
const Uint8 *UVplane, int UVpitch);
int SDL_SW_LockYUVTexture(SDL_SW_YUVTexture *swdata, const SDL_Rect *rect,
void **pixels, int *pitch);
void SDL_SW_UnlockYUVTexture(SDL_SW_YUVTexture *swdata);
int SDL_SW_CopyYUVToRGB(SDL_SW_YUVTexture *swdata, const SDL_Rect *srcrect,
Uint32 target_format, int w, int h, void *pixels,
int pitch);
void SDL_SW_DestroyYUVTexture(SDL_SW_YUVTexture *swdata);
#endif /* SDL_yuv_sw_c_h_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,268 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#if defined(SDL_VIDEO_RENDER_D3D) && !defined(SDL_RENDER_DISABLED)
#include "../../core/windows/SDL_windows.h"
#include <d3d9.h>
#include "SDL_shaders_d3d.h"
/* The shaders here were compiled with:
fxc /T ps_2_0 /Fo"<OUTPUT FILE>" "<INPUT FILE>"
Shader object code was converted to a list of DWORDs via the following
*nix style command (available separately from Windows + MSVC):
hexdump -v -e '6/4 "0x%08.8x, " "\n"' <FILE>
*/
/* --- D3D9_PixelShader_YUV_JPEG.hlsl ---
Texture2D theTextureY : register(t0);
Texture2D theTextureU : register(t1);
Texture2D theTextureV : register(t2);
SamplerState theSampler = sampler_state
{
addressU = Clamp;
addressV = Clamp;
mipfilter = NONE;
minfilter = LINEAR;
magfilter = LINEAR;
};
struct PixelShaderInput
{
float4 pos : SV_POSITION;
float2 tex : TEXCOORD0;
float4 color : COLOR0;
};
float4 main(PixelShaderInput input) : SV_TARGET
{
const float3 offset = {0.0, -0.501960814, -0.501960814};
const float3 Rcoeff = {1.0000, 0.0000, 1.4020};
const float3 Gcoeff = {1.0000, -0.3441, -0.7141};
const float3 Bcoeff = {1.0000, 1.7720, 0.0000};
float4 Output;
float3 yuv;
yuv.x = theTextureY.Sample(theSampler, input.tex).r;
yuv.y = theTextureU.Sample(theSampler, input.tex).r;
yuv.z = theTextureV.Sample(theSampler, input.tex).r;
yuv += offset;
Output.r = dot(yuv, Rcoeff);
Output.g = dot(yuv, Gcoeff);
Output.b = dot(yuv, Bcoeff);
Output.a = 1.0f;
return Output * input.color;
}
*/
static const DWORD D3D9_PixelShader_YUV_JPEG[] = {
0xffff0200, 0x0044fffe, 0x42415443, 0x0000001c, 0x000000d7, 0xffff0200,
0x00000003, 0x0000001c, 0x00000100, 0x000000d0, 0x00000058, 0x00010003,
0x00000001, 0x00000070, 0x00000000, 0x00000080, 0x00020003, 0x00000001,
0x00000098, 0x00000000, 0x000000a8, 0x00000003, 0x00000001, 0x000000c0,
0x00000000, 0x53656874, 0x6c706d61, 0x742b7265, 0x65546568, 0x72757478,
0xab005565, 0x00070004, 0x00040001, 0x00000001, 0x00000000, 0x53656874,
0x6c706d61, 0x742b7265, 0x65546568, 0x72757478, 0xab005665, 0x00070004,
0x00040001, 0x00000001, 0x00000000, 0x53656874, 0x6c706d61, 0x742b7265,
0x65546568, 0x72757478, 0xab005965, 0x00070004, 0x00040001, 0x00000001,
0x00000000, 0x325f7370, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820,
0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e362072,
0x36392e33, 0x312e3030, 0x34383336, 0xababab00, 0x05000051, 0xa00f0000,
0x00000000, 0xbf008081, 0xbf008081, 0x3f800000, 0x05000051, 0xa00f0001,
0x3f800000, 0x00000000, 0x3fb374bc, 0x00000000, 0x05000051, 0xa00f0002,
0x3f800000, 0xbeb02de0, 0xbf36cf42, 0x00000000, 0x05000051, 0xa00f0003,
0x3f800000, 0x3fe2d0e5, 0x00000000, 0x00000000, 0x0200001f, 0x80000000,
0xb0030000, 0x0200001f, 0x80000000, 0x900f0000, 0x0200001f, 0x90000000,
0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, 0x0200001f, 0x90000000,
0xa00f0802, 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000042,
0x800f0001, 0xb0e40000, 0xa0e40801, 0x03000042, 0x800f0002, 0xb0e40000,
0xa0e40802, 0x02000001, 0x80020000, 0x80000001, 0x02000001, 0x80040000,
0x80000002, 0x03000002, 0x80070000, 0x80e40000, 0xa0e40000, 0x03000008,
0x80010001, 0x80e40000, 0xa0e40001, 0x03000008, 0x80020001, 0x80e40000,
0xa0e40002, 0x0400005a, 0x80040001, 0x80e40000, 0xa0e40003, 0xa0aa0003,
0x02000001, 0x80080001, 0xa0ff0000, 0x03000005, 0x800f0000, 0x80e40001,
0x90e40000, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff
};
/* --- D3D9_PixelShader_YUV_BT601.hlsl ---
Texture2D theTextureY : register(t0);
Texture2D theTextureU : register(t1);
Texture2D theTextureV : register(t2);
SamplerState theSampler = sampler_state
{
addressU = Clamp;
addressV = Clamp;
mipfilter = NONE;
minfilter = LINEAR;
magfilter = LINEAR;
};
struct PixelShaderInput
{
float4 pos : SV_POSITION;
float2 tex : TEXCOORD0;
float4 color : COLOR0;
};
float4 main(PixelShaderInput input) : SV_TARGET
{
const float3 offset = {-0.0627451017, -0.501960814, -0.501960814};
const float3 Rcoeff = {1.1644, 0.0000, 1.5960};
const float3 Gcoeff = {1.1644, -0.3918, -0.8130};
const float3 Bcoeff = {1.1644, 2.0172, 0.0000};
float4 Output;
float3 yuv;
yuv.x = theTextureY.Sample(theSampler, input.tex).r;
yuv.y = theTextureU.Sample(theSampler, input.tex).r;
yuv.z = theTextureV.Sample(theSampler, input.tex).r;
yuv += offset;
Output.r = dot(yuv, Rcoeff);
Output.g = dot(yuv, Gcoeff);
Output.b = dot(yuv, Bcoeff);
Output.a = 1.0f;
return Output * input.color;
}
*/
static const DWORD D3D9_PixelShader_YUV_BT601[] = {
0xffff0200, 0x0044fffe, 0x42415443, 0x0000001c, 0x000000d7, 0xffff0200,
0x00000003, 0x0000001c, 0x00000100, 0x000000d0, 0x00000058, 0x00010003,
0x00000001, 0x00000070, 0x00000000, 0x00000080, 0x00020003, 0x00000001,
0x00000098, 0x00000000, 0x000000a8, 0x00000003, 0x00000001, 0x000000c0,
0x00000000, 0x53656874, 0x6c706d61, 0x742b7265, 0x65546568, 0x72757478,
0xab005565, 0x00070004, 0x00040001, 0x00000001, 0x00000000, 0x53656874,
0x6c706d61, 0x742b7265, 0x65546568, 0x72757478, 0xab005665, 0x00070004,
0x00040001, 0x00000001, 0x00000000, 0x53656874, 0x6c706d61, 0x742b7265,
0x65546568, 0x72757478, 0xab005965, 0x00070004, 0x00040001, 0x00000001,
0x00000000, 0x325f7370, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820,
0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e362072,
0x36392e33, 0x312e3030, 0x34383336, 0xababab00, 0x05000051, 0xa00f0000,
0xbd808081, 0xbf008081, 0xbf008081, 0x3f800000, 0x05000051, 0xa00f0001,
0x3f950b0f, 0x00000000, 0x3fcc49ba, 0x00000000, 0x05000051, 0xa00f0002,
0x3f950b0f, 0xbec89a02, 0xbf5020c5, 0x00000000, 0x05000051, 0xa00f0003,
0x3f950b0f, 0x400119ce, 0x00000000, 0x00000000, 0x0200001f, 0x80000000,
0xb0030000, 0x0200001f, 0x80000000, 0x900f0000, 0x0200001f, 0x90000000,
0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, 0x0200001f, 0x90000000,
0xa00f0802, 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000042,
0x800f0001, 0xb0e40000, 0xa0e40801, 0x03000042, 0x800f0002, 0xb0e40000,
0xa0e40802, 0x02000001, 0x80020000, 0x80000001, 0x02000001, 0x80040000,
0x80000002, 0x03000002, 0x80070000, 0x80e40000, 0xa0e40000, 0x03000008,
0x80010001, 0x80e40000, 0xa0e40001, 0x03000008, 0x80020001, 0x80e40000,
0xa0e40002, 0x0400005a, 0x80040001, 0x80e40000, 0xa0e40003, 0xa0aa0003,
0x02000001, 0x80080001, 0xa0ff0000, 0x03000005, 0x800f0000, 0x80e40001,
0x90e40000, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff
};
/* --- D3D9_PixelShader_YUV_BT709.hlsl ---
Texture2D theTextureY : register(t0);
Texture2D theTextureU : register(t1);
Texture2D theTextureV : register(t2);
SamplerState theSampler = sampler_state
{
addressU = Clamp;
addressV = Clamp;
mipfilter = NONE;
minfilter = LINEAR;
magfilter = LINEAR;
};
struct PixelShaderInput
{
float4 pos : SV_POSITION;
float2 tex : TEXCOORD0;
float4 color : COLOR0;
};
float4 main(PixelShaderInput input) : SV_TARGET
{
const float3 offset = {-0.0627451017, -0.501960814, -0.501960814};
const float3 Rcoeff = {1.1644, 0.0000, 1.7927};
const float3 Gcoeff = {1.1644, -0.2132, -0.5329};
const float3 Bcoeff = {1.1644, 2.1124, 0.0000};
float4 Output;
float3 yuv;
yuv.x = theTextureY.Sample(theSampler, input.tex).r;
yuv.y = theTextureU.Sample(theSampler, input.tex).r;
yuv.z = theTextureV.Sample(theSampler, input.tex).r;
yuv += offset;
Output.r = dot(yuv, Rcoeff);
Output.g = dot(yuv, Gcoeff);
Output.b = dot(yuv, Bcoeff);
Output.a = 1.0f;
return Output * input.color;
}
*/
static const DWORD D3D9_PixelShader_YUV_BT709[] = {
0xffff0200, 0x0044fffe, 0x42415443, 0x0000001c, 0x000000d7, 0xffff0200,
0x00000003, 0x0000001c, 0x00000100, 0x000000d0, 0x00000058, 0x00010003,
0x00000001, 0x00000070, 0x00000000, 0x00000080, 0x00020003, 0x00000001,
0x00000098, 0x00000000, 0x000000a8, 0x00000003, 0x00000001, 0x000000c0,
0x00000000, 0x53656874, 0x6c706d61, 0x742b7265, 0x65546568, 0x72757478,
0xab005565, 0x00070004, 0x00040001, 0x00000001, 0x00000000, 0x53656874,
0x6c706d61, 0x742b7265, 0x65546568, 0x72757478, 0xab005665, 0x00070004,
0x00040001, 0x00000001, 0x00000000, 0x53656874, 0x6c706d61, 0x742b7265,
0x65546568, 0x72757478, 0xab005965, 0x00070004, 0x00040001, 0x00000001,
0x00000000, 0x325f7370, 0x4d00305f, 0x6f726369, 0x74666f73, 0x29522820,
0x534c4820, 0x6853204c, 0x72656461, 0x6d6f4320, 0x656c6970, 0x2e362072,
0x36392e33, 0x312e3030, 0x34383336, 0xababab00, 0x05000051, 0xa00f0000,
0xbd808081, 0xbf008081, 0xbf008081, 0x3f800000, 0x05000051, 0xa00f0001,
0x3f950b0f, 0x00000000, 0x3fe57732, 0x00000000, 0x05000051, 0xa00f0002,
0x3f950b0f, 0xbe5a511a, 0xbf086c22, 0x00000000, 0x05000051, 0xa00f0003,
0x3f950b0f, 0x40073190, 0x00000000, 0x00000000, 0x0200001f, 0x80000000,
0xb0030000, 0x0200001f, 0x80000000, 0x900f0000, 0x0200001f, 0x90000000,
0xa00f0800, 0x0200001f, 0x90000000, 0xa00f0801, 0x0200001f, 0x90000000,
0xa00f0802, 0x03000042, 0x800f0000, 0xb0e40000, 0xa0e40800, 0x03000042,
0x800f0001, 0xb0e40000, 0xa0e40801, 0x03000042, 0x800f0002, 0xb0e40000,
0xa0e40802, 0x02000001, 0x80020000, 0x80000001, 0x02000001, 0x80040000,
0x80000002, 0x03000002, 0x80070000, 0x80e40000, 0xa0e40000, 0x03000008,
0x80010001, 0x80e40000, 0xa0e40001, 0x03000008, 0x80020001, 0x80e40000,
0xa0e40002, 0x0400005a, 0x80040001, 0x80e40000, 0xa0e40003, 0xa0aa0003,
0x02000001, 0x80080001, 0xa0ff0000, 0x03000005, 0x800f0000, 0x80e40001,
0x90e40000, 0x02000001, 0x800f0800, 0x80e40000, 0x0000ffff
};
static const DWORD *D3D9_shaders[] = {
D3D9_PixelShader_YUV_JPEG,
D3D9_PixelShader_YUV_BT601,
D3D9_PixelShader_YUV_BT709,
};
HRESULT D3D9_CreatePixelShader(IDirect3DDevice9 *d3dDevice, D3D9_Shader shader, IDirect3DPixelShader9 **pixelShader)
{
return IDirect3DDevice9_CreatePixelShader(d3dDevice, D3D9_shaders[shader], pixelShader);
}
#endif /* SDL_VIDEO_RENDER_D3D && !SDL_RENDER_DISABLED */

View File

@ -0,0 +1,33 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
/* D3D9 shader implementation */
typedef enum
{
SHADER_YUV_JPEG,
SHADER_YUV_BT601,
SHADER_YUV_BT709,
NUM_SHADERS
} D3D9_Shader;
extern HRESULT D3D9_CreatePixelShader(IDirect3DDevice9 *d3dDevice, D3D9_Shader shader, IDirect3DPixelShader9 **pixelShader);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,114 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#if defined(SDL_VIDEO_RENDER_D3D11) && !defined(SDL_RENDER_DISABLED)
#include "../../video/winrt/SDL_winrtvideo_cpp.h"
extern "C" {
#include "../SDL_sysrender.h"
}
#include <windows.ui.core.h>
#include <windows.graphics.display.h>
#if WINAPI_FAMILY == WINAPI_FAMILY_APP
#include <windows.ui.xaml.media.dxinterop.h>
#endif
using namespace Windows::UI::Core;
using namespace Windows::Graphics::Display;
#include <DXGI.h>
#include <SDL3/SDL_syswm.h>
#include "SDL_render_winrt.h"
extern "C" void *
D3D11_GetCoreWindowFromSDLRenderer(SDL_Renderer *renderer)
{
SDL_Window *sdlWindow = renderer->window;
if (renderer->window == NULL) {
return NULL;
}
SDL_SysWMinfo sdlWindowInfo;
if (SDL_GetWindowWMInfo(sdlWindow, &sdlWindowInfo, SDL_SYSWM_CURRENT_VERSION) < 0 ||
sdlWindowInfo.subsystem != SDL_SYSWM_WINRT) {
SDL_SetError("Couldn't get window handle");
return NULL;
}
if (sdlWindowInfo.subsystem != SDL_SYSWM_WINRT) {
return NULL;
}
if (!sdlWindowInfo.info.winrt.window) {
return NULL;
}
ABI::Windows::UI::Core::ICoreWindow *coreWindow = NULL;
if (FAILED(sdlWindowInfo.info.winrt.window->QueryInterface(&coreWindow))) {
return NULL;
}
IUnknown *coreWindowAsIUnknown = NULL;
coreWindow->QueryInterface(&coreWindowAsIUnknown);
coreWindow->Release();
return coreWindowAsIUnknown;
}
extern "C" DXGI_MODE_ROTATION
D3D11_GetCurrentRotation()
{
const DisplayOrientations currentOrientation = WINRT_DISPLAY_PROPERTY(CurrentOrientation);
switch (currentOrientation) {
#if SDL_WINAPI_FAMILY_PHONE
/* Windows Phone rotations */
case DisplayOrientations::Landscape:
return DXGI_MODE_ROTATION_ROTATE90;
case DisplayOrientations::Portrait:
return DXGI_MODE_ROTATION_IDENTITY;
case DisplayOrientations::LandscapeFlipped:
return DXGI_MODE_ROTATION_ROTATE270;
case DisplayOrientations::PortraitFlipped:
return DXGI_MODE_ROTATION_ROTATE180;
#else
/* Non-Windows-Phone rotations (ex: Windows 8, Windows RT) */
case DisplayOrientations::Landscape:
return DXGI_MODE_ROTATION_IDENTITY;
case DisplayOrientations::Portrait:
return DXGI_MODE_ROTATION_ROTATE270;
case DisplayOrientations::LandscapeFlipped:
return DXGI_MODE_ROTATION_ROTATE180;
case DisplayOrientations::PortraitFlipped:
return DXGI_MODE_ROTATION_ROTATE90;
#endif /* SDL_WINAPI_FAMILY_PHONE */
}
return DXGI_MODE_ROTATION_IDENTITY;
}
#endif /* SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED */

View File

@ -0,0 +1,36 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#if defined(SDL_VIDEO_RENDER_D3D11) && !defined(SDL_RENDER_DISABLED)
#ifdef __cplusplus
extern "C" {
#endif
void *D3D11_GetCoreWindowFromSDLRenderer(SDL_Renderer *renderer);
DXGI_MODE_ROTATION D3D11_GetCurrentRotation();
#ifdef __cplusplus
}
#endif
#endif /* SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,44 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
/* D3D11 shader implementation */
typedef enum
{
SHADER_SOLID,
SHADER_RGB,
#if SDL_HAVE_YUV
SHADER_YUV_JPEG,
SHADER_YUV_BT601,
SHADER_YUV_BT709,
SHADER_NV12_JPEG,
SHADER_NV12_BT601,
SHADER_NV12_BT709,
SHADER_NV21_JPEG,
SHADER_NV21_BT601,
SHADER_NV21_BT709,
#endif
NUM_SHADERS
} D3D11_Shader;
extern int D3D11_CreateVertexShader(ID3D11Device1 *d3dDevice, ID3D11VertexShader **vertexShader, ID3D11InputLayout **inputLayout);
extern int D3D11_CreatePixelShader(ID3D11Device1 *d3dDevice, D3D11_Shader shader, ID3D11PixelShader **pixelShader);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,27 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#if defined(SDL_VIDEO_RENDER_D3D12) && !defined(SDL_RENDER_DISABLED) && (defined(__XBOXONE__) || defined(__XBOXSERIES__))
#include "SDL_render_d3d12_xbox.h"
#error "This is a placeholder Xbox file, as the real one is under NDA. See README-gdk.md for more info."
#endif

View File

@ -0,0 +1,22 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#error "This is a placeholder Xbox file, as the real one is under NDA. See README-gdk.md for more info."

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,67 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
/* D3D12 shader implementation */
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
typedef enum
{
SHADER_SOLID,
SHADER_RGB,
#if SDL_HAVE_YUV
SHADER_YUV_JPEG,
SHADER_YUV_BT601,
SHADER_YUV_BT709,
SHADER_NV12_JPEG,
SHADER_NV12_BT601,
SHADER_NV12_BT709,
SHADER_NV21_JPEG,
SHADER_NV21_BT601,
SHADER_NV21_BT709,
#endif
NUM_SHADERS
} D3D12_Shader;
typedef enum
{
ROOTSIG_COLOR,
ROOTSIG_TEXTURE,
#if SDL_HAVE_YUV
ROOTSIG_YUV,
ROOTSIG_NV,
#endif
NUM_ROOTSIGS
} D3D12_RootSignature;
extern void D3D12_GetVertexShader(D3D12_Shader shader, D3D12_SHADER_BYTECODE *outBytecode);
extern void D3D12_GetPixelShader(D3D12_Shader shader, D3D12_SHADER_BYTECODE *outBytecode);
extern D3D12_RootSignature D3D12_GetRootSignatureType(D3D12_Shader shader);
extern void D3D12_GetRootSignatureData(D3D12_RootSignature rootSig, D3D12_SHADER_BYTECODE *outBytecode);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,27 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#if defined(SDL_VIDEO_RENDER_D3D12) && !defined(SDL_RENDER_DISABLED) && defined(__XBOXONE__)
#error "This is a placeholder Xbox file, as the real one is under NDA. See README-gdk.md for more info."
#endif /* SDL_VIDEO_RENDER_D3D12 && !SDL_RENDER_DISABLED && defined(__XBOXONE__) */

View File

@ -0,0 +1,27 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#if defined(SDL_VIDEO_RENDER_D3D12) && !defined(SDL_RENDER_DISABLED) && defined(__XBOXSERIES__)
#error "This is a placeholder Xbox file, as the real one is under NDA. See README-gdk.md for more info."
#endif /* SDL_VIDEO_RENDER_D3D12 && !SDL_RENDER_DISABLED && defined(__XBOXSERIES__) */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,120 @@
#include <metal_texture>
#include <metal_matrix>
using namespace metal;
struct SolidVertexInput
{
float2 position [[attribute(0)]];
float4 color [[attribute(1)]];
};
struct SolidVertexOutput
{
float4 position [[position]];
float4 color;
float pointSize [[point_size]];
};
vertex SolidVertexOutput SDL_Solid_vertex(SolidVertexInput in [[stage_in]],
constant float4x4 &projection [[buffer(2)]],
constant float4x4 &transform [[buffer(3)]])
{
SolidVertexOutput v;
v.position = (projection * transform) * float4(in.position, 0.0f, 1.0f);
v.color = in.color;
v.pointSize = 1.0f;
return v;
}
fragment float4 SDL_Solid_fragment(SolidVertexInput in [[stage_in]])
{
return in.color;
}
struct CopyVertexInput
{
float2 position [[attribute(0)]];
float4 color [[attribute(1)]];
float2 texcoord [[attribute(2)]];
};
struct CopyVertexOutput
{
float4 position [[position]];
float4 color;
float2 texcoord;
};
vertex CopyVertexOutput SDL_Copy_vertex(CopyVertexInput in [[stage_in]],
constant float4x4 &projection [[buffer(2)]],
constant float4x4 &transform [[buffer(3)]])
{
CopyVertexOutput v;
v.position = (projection * transform) * float4(in.position, 0.0f, 1.0f);
v.color = in.color;
v.texcoord = in.texcoord;
return v;
}
fragment float4 SDL_Copy_fragment(CopyVertexOutput vert [[stage_in]],
texture2d<float> tex [[texture(0)]],
sampler s [[sampler(0)]])
{
return tex.sample(s, vert.texcoord) * vert.color;
}
struct YUVDecode
{
float3 offset;
float3 Rcoeff;
float3 Gcoeff;
float3 Bcoeff;
};
fragment float4 SDL_YUV_fragment(CopyVertexOutput vert [[stage_in]],
constant YUVDecode &decode [[buffer(1)]],
texture2d<float> texY [[texture(0)]],
texture2d_array<float> texUV [[texture(1)]],
sampler s [[sampler(0)]])
{
float3 yuv;
yuv.x = texY.sample(s, vert.texcoord).r;
yuv.y = texUV.sample(s, vert.texcoord, 0).r;
yuv.z = texUV.sample(s, vert.texcoord, 1).r;
yuv += decode.offset;
return vert.color * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0);
}
fragment float4 SDL_NV12_fragment(CopyVertexOutput vert [[stage_in]],
constant YUVDecode &decode [[buffer(1)]],
texture2d<float> texY [[texture(0)]],
texture2d<float> texUV [[texture(1)]],
sampler s [[sampler(0)]])
{
float3 yuv;
yuv.x = texY.sample(s, vert.texcoord).r;
yuv.yz = texUV.sample(s, vert.texcoord).rg;
yuv += decode.offset;
return vert.color * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0);
}
fragment float4 SDL_NV21_fragment(CopyVertexOutput vert [[stage_in]],
constant YUVDecode &decode [[buffer(1)]],
texture2d<float> texY [[texture(0)]],
texture2d<float> texUV [[texture(1)]],
sampler s [[sampler(0)]])
{
float3 yuv;
yuv.x = texY.sample(s, vert.texcoord).r;
yuv.yz = texUV.sample(s, vert.texcoord).gr;
yuv += decode.offset;
return vert.color * float4(dot(yuv, decode.Rcoeff), dot(yuv, decode.Gcoeff), dot(yuv, decode.Bcoeff), 1.0);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,24 @@
#!/bin/bash
set -x
set -e
cd `dirname "$0"`
generate_shaders()
{
fileplatform=$1
compileplatform=$2
sdkplatform=$3
minversion=$4
xcrun -sdk $sdkplatform metal -c -std=$compileplatform-metal1.1 -m$sdkplatform-version-min=$minversion -Wall -O3 -o ./sdl.air ./SDL_shaders_metal.metal || exit $?
xcrun -sdk $sdkplatform metal-ar rc sdl.metalar sdl.air || exit $?
xcrun -sdk $sdkplatform metallib -o sdl.metallib sdl.metalar || exit $?
xxd -i sdl.metallib | perl -w -p -e 's/\Aunsigned /const unsigned /;' >./SDL_shaders_metal_$fileplatform.h
rm -f sdl.air sdl.metalar sdl.metallib
}
generate_shaders macos macos macosx 10.11
generate_shaders ios ios iphoneos 8.0
generate_shaders iphonesimulator ios iphonesimulator 8.0
generate_shaders tvos ios appletvos 9.0
generate_shaders tvsimulator ios appletvsimulator 9.0

View File

@ -0,0 +1,476 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/* list of OpenGL functions sorted alphabetically
If you need to use a GL function from the SDL video subsystem,
change its entry from SDL_PROC_UNUSED to SDL_PROC and rebuild.
*/
#define SDL_PROC_UNUSED(ret, func, params)
SDL_PROC_UNUSED(void, glAccum, (GLenum, GLfloat))
SDL_PROC_UNUSED(void, glAlphaFunc, (GLenum, GLclampf))
SDL_PROC_UNUSED(GLboolean, glAreTexturesResident,
(GLsizei, const GLuint *, GLboolean *))
SDL_PROC_UNUSED(void, glArrayElement, (GLint))
SDL_PROC(void, glBegin, (GLenum))
SDL_PROC(void, glBindTexture, (GLenum, GLuint))
SDL_PROC_UNUSED(void, glBitmap,
(GLsizei, GLsizei, GLfloat, GLfloat, GLfloat, GLfloat,
const GLubyte *))
SDL_PROC(void, glBlendEquation, (GLenum))
SDL_PROC_UNUSED(void, glBlendFunc, (GLenum, GLenum))
SDL_PROC(void, glBlendFuncSeparate, (GLenum, GLenum, GLenum, GLenum))
SDL_PROC_UNUSED(void, glCallList, (GLuint))
SDL_PROC_UNUSED(void, glCallLists, (GLsizei, GLenum, const GLvoid *))
SDL_PROC(void, glClear, (GLbitfield))
SDL_PROC_UNUSED(void, glClearAccum, (GLfloat, GLfloat, GLfloat, GLfloat))
SDL_PROC(void, glClearColor, (GLclampf, GLclampf, GLclampf, GLclampf))
SDL_PROC_UNUSED(void, glClearDepth, (GLclampd))
SDL_PROC_UNUSED(void, glClearIndex, (GLfloat))
SDL_PROC_UNUSED(void, glClearStencil, (GLint))
SDL_PROC_UNUSED(void, glClipPlane, (GLenum, const GLdouble *))
SDL_PROC_UNUSED(void, glColor3b, (GLbyte, GLbyte, GLbyte))
SDL_PROC_UNUSED(void, glColor3bv, (const GLbyte *))
SDL_PROC_UNUSED(void, glColor3d, (GLdouble, GLdouble, GLdouble))
SDL_PROC_UNUSED(void, glColor3dv, (const GLdouble *))
SDL_PROC_UNUSED(void, glColor3f, (GLfloat, GLfloat, GLfloat))
SDL_PROC(void, glColor3fv, (const GLfloat *))
SDL_PROC_UNUSED(void, glColor3i, (GLint, GLint, GLint))
SDL_PROC_UNUSED(void, glColor3iv, (const GLint *))
SDL_PROC_UNUSED(void, glColor3s, (GLshort, GLshort, GLshort))
SDL_PROC_UNUSED(void, glColor3sv, (const GLshort *))
SDL_PROC_UNUSED(void, glColor3ub, (GLubyte, GLubyte, GLubyte))
SDL_PROC_UNUSED(void, glColor3ubv, (const GLubyte *))
SDL_PROC_UNUSED(void, glColor3ui, (GLuint, GLuint, GLuint))
SDL_PROC_UNUSED(void, glColor3uiv, (const GLuint *))
SDL_PROC_UNUSED(void, glColor3us, (GLushort, GLushort, GLushort))
SDL_PROC_UNUSED(void, glColor3usv, (const GLushort *))
SDL_PROC_UNUSED(void, glColor4b, (GLbyte, GLbyte, GLbyte, GLbyte))
SDL_PROC_UNUSED(void, glColor4bv, (const GLbyte *))
SDL_PROC_UNUSED(void, glColor4d, (GLdouble, GLdouble, GLdouble, GLdouble))
SDL_PROC_UNUSED(void, glColor4dv, (const GLdouble *))
SDL_PROC(void, glColor4f, (GLfloat, GLfloat, GLfloat, GLfloat))
SDL_PROC_UNUSED(void, glColor4fv, (const GLfloat *))
SDL_PROC_UNUSED(void, glColor4i, (GLint, GLint, GLint, GLint))
SDL_PROC_UNUSED(void, glColor4iv, (const GLint *))
SDL_PROC_UNUSED(void, glColor4s, (GLshort, GLshort, GLshort, GLshort))
SDL_PROC_UNUSED(void, glColor4sv, (const GLshort *))
SDL_PROC(void, glColor4ub,
(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha))
SDL_PROC_UNUSED(void, glColor4ubv, (const GLubyte *v))
SDL_PROC_UNUSED(void, glColor4ui,
(GLuint red, GLuint green, GLuint blue, GLuint alpha))
SDL_PROC_UNUSED(void, glColor4uiv, (const GLuint *v))
SDL_PROC_UNUSED(void, glColor4us,
(GLushort red, GLushort green, GLushort blue, GLushort alpha))
SDL_PROC_UNUSED(void, glColor4usv, (const GLushort *v))
SDL_PROC_UNUSED(void, glColorMask,
(GLboolean red, GLboolean green, GLboolean blue,
GLboolean alpha))
SDL_PROC_UNUSED(void, glColorMaterial, (GLenum face, GLenum mode))
SDL_PROC(void, glColorPointer,
(GLint size, GLenum type, GLsizei stride,
const GLvoid *pointer))
SDL_PROC_UNUSED(void, glCopyPixels,
(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum type))
SDL_PROC_UNUSED(void, glCopyTexImage1D,
(GLenum target, GLint level, GLenum internalFormat, GLint x,
GLint y, GLsizei width, GLint border))
SDL_PROC_UNUSED(void, glCopyTexImage2D,
(GLenum target, GLint level, GLenum internalFormat, GLint x,
GLint y, GLsizei width, GLsizei height, GLint border))
SDL_PROC_UNUSED(void, glCopyTexSubImage1D,
(GLenum target, GLint level, GLint xoffset, GLint x, GLint y,
GLsizei width))
SDL_PROC_UNUSED(void, glCopyTexSubImage2D,
(GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLint x, GLint y, GLsizei width, GLsizei height))
SDL_PROC_UNUSED(void, glCullFace, (GLenum mode))
SDL_PROC_UNUSED(void, glDeleteLists, (GLuint list, GLsizei range))
SDL_PROC(void, glDeleteTextures, (GLsizei n, const GLuint *textures))
SDL_PROC(void, glDepthFunc, (GLenum func))
SDL_PROC_UNUSED(void, glDepthMask, (GLboolean flag))
SDL_PROC_UNUSED(void, glDepthRange, (GLclampd zNear, GLclampd zFar))
SDL_PROC(void, glDisable, (GLenum cap))
SDL_PROC(void, glDisableClientState, (GLenum array))
SDL_PROC(void, glDrawArrays, (GLenum mode, GLint first, GLsizei count))
SDL_PROC_UNUSED(void, glDrawBuffer, (GLenum mode))
SDL_PROC_UNUSED(void, glDrawElements,
(GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices))
SDL_PROC(void, glDrawPixels,
(GLsizei width, GLsizei height, GLenum format, GLenum type,
const GLvoid *pixels))
SDL_PROC_UNUSED(void, glEdgeFlag, (GLboolean flag))
SDL_PROC_UNUSED(void, glEdgeFlagPointer,
(GLsizei stride, const GLvoid *pointer))
SDL_PROC_UNUSED(void, glEdgeFlagv, (const GLboolean *flag))
SDL_PROC(void, glEnable, (GLenum cap))
SDL_PROC(void, glEnableClientState, (GLenum array))
SDL_PROC(void, glEnd, (void))
SDL_PROC_UNUSED(void, glEndList, (void))
SDL_PROC_UNUSED(void, glEvalCoord1d, (GLdouble u))
SDL_PROC_UNUSED(void, glEvalCoord1dv, (const GLdouble *u))
SDL_PROC_UNUSED(void, glEvalCoord1f, (GLfloat u))
SDL_PROC_UNUSED(void, glEvalCoord1fv, (const GLfloat *u))
SDL_PROC_UNUSED(void, glEvalCoord2d, (GLdouble u, GLdouble v))
SDL_PROC_UNUSED(void, glEvalCoord2dv, (const GLdouble *u))
SDL_PROC_UNUSED(void, glEvalCoord2f, (GLfloat u, GLfloat v))
SDL_PROC_UNUSED(void, glEvalCoord2fv, (const GLfloat *u))
SDL_PROC_UNUSED(void, glEvalMesh1, (GLenum mode, GLint i1, GLint i2))
SDL_PROC_UNUSED(void, glEvalMesh2,
(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2))
SDL_PROC_UNUSED(void, glEvalPoint1, (GLint i))
SDL_PROC_UNUSED(void, glEvalPoint2, (GLint i, GLint j))
SDL_PROC_UNUSED(void, glFeedbackBuffer,
(GLsizei size, GLenum type, GLfloat *buffer))
SDL_PROC_UNUSED(void, glFinish, (void))
SDL_PROC_UNUSED(void, glFlush, (void))
SDL_PROC_UNUSED(void, glFogf, (GLenum pname, GLfloat param))
SDL_PROC_UNUSED(void, glFogfv, (GLenum pname, const GLfloat *params))
SDL_PROC_UNUSED(void, glFogi, (GLenum pname, GLint param))
SDL_PROC_UNUSED(void, glFogiv, (GLenum pname, const GLint *params))
SDL_PROC_UNUSED(void, glFrontFace, (GLenum mode))
SDL_PROC_UNUSED(void, glFrustum,
(GLdouble left, GLdouble right, GLdouble bottom,
GLdouble top, GLdouble zNear, GLdouble zFar))
SDL_PROC_UNUSED(GLuint, glGenLists, (GLsizei range))
SDL_PROC(void, glGenTextures, (GLsizei n, GLuint *textures))
SDL_PROC_UNUSED(void, glGetBooleanv, (GLenum pname, GLboolean *params))
SDL_PROC_UNUSED(void, glGetClipPlane, (GLenum plane, GLdouble *equation))
SDL_PROC_UNUSED(void, glGetDoublev, (GLenum pname, GLdouble *params))
SDL_PROC(GLenum, glGetError, (void))
SDL_PROC(void, glGetFloatv, (GLenum pname, GLfloat *params))
SDL_PROC(void, glGetIntegerv, (GLenum pname, GLint *params))
SDL_PROC_UNUSED(void, glGetLightfv,
(GLenum light, GLenum pname, GLfloat *params))
SDL_PROC_UNUSED(void, glGetLightiv,
(GLenum light, GLenum pname, GLint *params))
SDL_PROC_UNUSED(void, glGetMapdv, (GLenum target, GLenum query, GLdouble *v))
SDL_PROC_UNUSED(void, glGetMapfv, (GLenum target, GLenum query, GLfloat *v))
SDL_PROC_UNUSED(void, glGetMapiv, (GLenum target, GLenum query, GLint *v))
SDL_PROC_UNUSED(void, glGetMaterialfv,
(GLenum face, GLenum pname, GLfloat *params))
SDL_PROC_UNUSED(void, glGetMaterialiv,
(GLenum face, GLenum pname, GLint *params))
SDL_PROC_UNUSED(void, glGetPixelMapfv, (GLenum map, GLfloat *values))
SDL_PROC_UNUSED(void, glGetPixelMapuiv, (GLenum map, GLuint *values))
SDL_PROC_UNUSED(void, glGetPixelMapusv, (GLenum map, GLushort *values))
SDL_PROC(void, glGetPointerv, (GLenum pname, GLvoid **params))
SDL_PROC_UNUSED(void, glGetPolygonStipple, (GLubyte * mask))
SDL_PROC(const GLubyte *, glGetString, (GLenum name))
SDL_PROC_UNUSED(void, glGetTexEnvfv,
(GLenum target, GLenum pname, GLfloat *params))
SDL_PROC_UNUSED(void, glGetTexEnviv,
(GLenum target, GLenum pname, GLint *params))
SDL_PROC_UNUSED(void, glGetTexGendv,
(GLenum coord, GLenum pname, GLdouble *params))
SDL_PROC_UNUSED(void, glGetTexGenfv,
(GLenum coord, GLenum pname, GLfloat *params))
SDL_PROC_UNUSED(void, glGetTexGeniv,
(GLenum coord, GLenum pname, GLint *params))
SDL_PROC_UNUSED(void, glGetTexImage,
(GLenum target, GLint level, GLenum format, GLenum type,
GLvoid *pixels))
SDL_PROC_UNUSED(void, glGetTexLevelParameterfv,
(GLenum target, GLint level, GLenum pname, GLfloat *params))
SDL_PROC_UNUSED(void, glGetTexLevelParameteriv,
(GLenum target, GLint level, GLenum pname, GLint *params))
SDL_PROC_UNUSED(void, glGetTexParameterfv,
(GLenum target, GLenum pname, GLfloat *params))
SDL_PROC_UNUSED(void, glGetTexParameteriv,
(GLenum target, GLenum pname, GLint *params))
SDL_PROC_UNUSED(void, glHint, (GLenum target, GLenum mode))
SDL_PROC_UNUSED(void, glIndexMask, (GLuint mask))
SDL_PROC_UNUSED(void, glIndexPointer,
(GLenum type, GLsizei stride, const GLvoid *pointer))
SDL_PROC_UNUSED(void, glIndexd, (GLdouble c))
SDL_PROC_UNUSED(void, glIndexdv, (const GLdouble *c))
SDL_PROC_UNUSED(void, glIndexf, (GLfloat c))
SDL_PROC_UNUSED(void, glIndexfv, (const GLfloat *c))
SDL_PROC_UNUSED(void, glIndexi, (GLint c))
SDL_PROC_UNUSED(void, glIndexiv, (const GLint *c))
SDL_PROC_UNUSED(void, glIndexs, (GLshort c))
SDL_PROC_UNUSED(void, glIndexsv, (const GLshort *c))
SDL_PROC_UNUSED(void, glIndexub, (GLubyte c))
SDL_PROC_UNUSED(void, glIndexubv, (const GLubyte *c))
SDL_PROC_UNUSED(void, glInitNames, (void))
SDL_PROC_UNUSED(void, glInterleavedArrays,
(GLenum format, GLsizei stride, const GLvoid *pointer))
SDL_PROC_UNUSED(GLboolean, glIsEnabled, (GLenum cap))
SDL_PROC_UNUSED(GLboolean, glIsList, (GLuint list))
SDL_PROC_UNUSED(GLboolean, glIsTexture, (GLuint texture))
SDL_PROC_UNUSED(void, glLightModelf, (GLenum pname, GLfloat param))
SDL_PROC_UNUSED(void, glLightModelfv, (GLenum pname, const GLfloat *params))
SDL_PROC_UNUSED(void, glLightModeli, (GLenum pname, GLint param))
SDL_PROC_UNUSED(void, glLightModeliv, (GLenum pname, const GLint *params))
SDL_PROC_UNUSED(void, glLightf, (GLenum light, GLenum pname, GLfloat param))
SDL_PROC_UNUSED(void, glLightfv,
(GLenum light, GLenum pname, const GLfloat *params))
SDL_PROC_UNUSED(void, glLighti, (GLenum light, GLenum pname, GLint param))
SDL_PROC_UNUSED(void, glLightiv,
(GLenum light, GLenum pname, const GLint *params))
SDL_PROC_UNUSED(void, glLineStipple, (GLint factor, GLushort pattern))
SDL_PROC(void, glLineWidth, (GLfloat width))
SDL_PROC_UNUSED(void, glListBase, (GLuint base))
SDL_PROC(void, glLoadIdentity, (void))
SDL_PROC_UNUSED(void, glLoadMatrixd, (const GLdouble *m))
SDL_PROC_UNUSED(void, glLoadMatrixf, (const GLfloat *m))
SDL_PROC_UNUSED(void, glLoadName, (GLuint name))
SDL_PROC_UNUSED(void, glLogicOp, (GLenum opcode))
SDL_PROC_UNUSED(void, glMap1d,
(GLenum target, GLdouble u1, GLdouble u2, GLint stride,
GLint order, const GLdouble *points))
SDL_PROC_UNUSED(void, glMap1f,
(GLenum target, GLfloat u1, GLfloat u2, GLint stride,
GLint order, const GLfloat *points))
SDL_PROC_UNUSED(void, glMap2d,
(GLenum target, GLdouble u1, GLdouble u2, GLint ustride,
GLint uorder, GLdouble v1, GLdouble v2, GLint vstride,
GLint vorder, const GLdouble *points))
SDL_PROC_UNUSED(void, glMap2f,
(GLenum target, GLfloat u1, GLfloat u2, GLint ustride,
GLint uorder, GLfloat v1, GLfloat v2, GLint vstride,
GLint vorder, const GLfloat *points))
SDL_PROC_UNUSED(void, glMapGrid1d, (GLint un, GLdouble u1, GLdouble u2))
SDL_PROC_UNUSED(void, glMapGrid1f, (GLint un, GLfloat u1, GLfloat u2))
SDL_PROC_UNUSED(void, glMapGrid2d,
(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1,
GLdouble v2))
SDL_PROC_UNUSED(void, glMapGrid2f,
(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1,
GLfloat v2))
SDL_PROC_UNUSED(void, glMaterialf, (GLenum face, GLenum pname, GLfloat param))
SDL_PROC_UNUSED(void, glMaterialfv,
(GLenum face, GLenum pname, const GLfloat *params))
SDL_PROC_UNUSED(void, glMateriali, (GLenum face, GLenum pname, GLint param))
SDL_PROC_UNUSED(void, glMaterialiv,
(GLenum face, GLenum pname, const GLint *params))
SDL_PROC(void, glMatrixMode, (GLenum mode))
SDL_PROC_UNUSED(void, glMultMatrixd, (const GLdouble *m))
SDL_PROC_UNUSED(void, glMultMatrixf, (const GLfloat *m))
SDL_PROC_UNUSED(void, glNewList, (GLuint list, GLenum mode))
SDL_PROC_UNUSED(void, glNormal3b, (GLbyte nx, GLbyte ny, GLbyte nz))
SDL_PROC_UNUSED(void, glNormal3bv, (const GLbyte *v))
SDL_PROC_UNUSED(void, glNormal3d, (GLdouble nx, GLdouble ny, GLdouble nz))
SDL_PROC_UNUSED(void, glNormal3dv, (const GLdouble *v))
SDL_PROC_UNUSED(void, glNormal3f, (GLfloat nx, GLfloat ny, GLfloat nz))
SDL_PROC_UNUSED(void, glNormal3fv, (const GLfloat *v))
SDL_PROC_UNUSED(void, glNormal3i, (GLint nx, GLint ny, GLint nz))
SDL_PROC_UNUSED(void, glNormal3iv, (const GLint *v))
SDL_PROC_UNUSED(void, glNormal3s, (GLshort nx, GLshort ny, GLshort nz))
SDL_PROC_UNUSED(void, glNormal3sv, (const GLshort *v))
SDL_PROC_UNUSED(void, glNormalPointer,
(GLenum type, GLsizei stride, const GLvoid *pointer))
SDL_PROC(void, glOrtho,
(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top,
GLdouble zNear, GLdouble zFar))
SDL_PROC_UNUSED(void, glPassThrough, (GLfloat token))
SDL_PROC_UNUSED(void, glPixelMapfv,
(GLenum map, GLsizei mapsize, const GLfloat *values))
SDL_PROC_UNUSED(void, glPixelMapuiv,
(GLenum map, GLsizei mapsize, const GLuint *values))
SDL_PROC_UNUSED(void, glPixelMapusv,
(GLenum map, GLsizei mapsize, const GLushort *values))
SDL_PROC_UNUSED(void, glPixelStoref, (GLenum pname, GLfloat param))
SDL_PROC(void, glPixelStorei, (GLenum pname, GLint param))
SDL_PROC_UNUSED(void, glPixelTransferf, (GLenum pname, GLfloat param))
SDL_PROC_UNUSED(void, glPixelTransferi, (GLenum pname, GLint param))
SDL_PROC_UNUSED(void, glPixelZoom, (GLfloat xfactor, GLfloat yfactor))
SDL_PROC(void, glPointSize, (GLfloat size))
SDL_PROC_UNUSED(void, glPolygonMode, (GLenum face, GLenum mode))
SDL_PROC_UNUSED(void, glPolygonOffset, (GLfloat factor, GLfloat units))
SDL_PROC_UNUSED(void, glPolygonStipple, (const GLubyte *mask))
SDL_PROC_UNUSED(void, glPopAttrib, (void))
SDL_PROC_UNUSED(void, glPopClientAttrib, (void))
SDL_PROC_UNUSED(void, glPopMatrix, (void))
SDL_PROC_UNUSED(void, glPopName, (void))
SDL_PROC_UNUSED(void, glPrioritizeTextures,
(GLsizei n, const GLuint *textures,
const GLclampf *priorities))
SDL_PROC_UNUSED(void, glPushAttrib, (GLbitfield mask))
SDL_PROC_UNUSED(void, glPushClientAttrib, (GLbitfield mask))
SDL_PROC_UNUSED(void, glPushMatrix, (void))
SDL_PROC_UNUSED(void, glPushName, (GLuint name))
SDL_PROC_UNUSED(void, glRasterPos2d, (GLdouble x, GLdouble y))
SDL_PROC_UNUSED(void, glRasterPos2dv, (const GLdouble *v))
SDL_PROC_UNUSED(void, glRasterPos2f, (GLfloat x, GLfloat y))
SDL_PROC_UNUSED(void, glRasterPos2fv, (const GLfloat *v))
SDL_PROC(void, glRasterPos2i, (GLint x, GLint y))
SDL_PROC_UNUSED(void, glRasterPos2iv, (const GLint *v))
SDL_PROC_UNUSED(void, glRasterPos2s, (GLshort x, GLshort y))
SDL_PROC_UNUSED(void, glRasterPos2sv, (const GLshort *v))
SDL_PROC_UNUSED(void, glRasterPos3d, (GLdouble x, GLdouble y, GLdouble z))
SDL_PROC_UNUSED(void, glRasterPos3dv, (const GLdouble *v))
SDL_PROC_UNUSED(void, glRasterPos3f, (GLfloat x, GLfloat y, GLfloat z))
SDL_PROC_UNUSED(void, glRasterPos3fv, (const GLfloat *v))
SDL_PROC_UNUSED(void, glRasterPos3i, (GLint x, GLint y, GLint z))
SDL_PROC_UNUSED(void, glRasterPos3iv, (const GLint *v))
SDL_PROC_UNUSED(void, glRasterPos3s, (GLshort x, GLshort y, GLshort z))
SDL_PROC_UNUSED(void, glRasterPos3sv, (const GLshort *v))
SDL_PROC_UNUSED(void, glRasterPos4d,
(GLdouble x, GLdouble y, GLdouble z, GLdouble w))
SDL_PROC_UNUSED(void, glRasterPos4dv, (const GLdouble *v))
SDL_PROC_UNUSED(void, glRasterPos4f,
(GLfloat x, GLfloat y, GLfloat z, GLfloat w))
SDL_PROC_UNUSED(void, glRasterPos4fv, (const GLfloat *v))
SDL_PROC_UNUSED(void, glRasterPos4i, (GLint x, GLint y, GLint z, GLint w))
SDL_PROC_UNUSED(void, glRasterPos4iv, (const GLint *v))
SDL_PROC_UNUSED(void, glRasterPos4s,
(GLshort x, GLshort y, GLshort z, GLshort w))
SDL_PROC_UNUSED(void, glRasterPos4sv, (const GLshort *v))
SDL_PROC(void, glReadBuffer, (GLenum mode))
SDL_PROC(void, glReadPixels,
(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, GLvoid *pixels))
SDL_PROC_UNUSED(void, glRectd,
(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2))
SDL_PROC_UNUSED(void, glRectdv, (const GLdouble *v1, const GLdouble *v2))
SDL_PROC(void, glRectf,
(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2))
SDL_PROC_UNUSED(void, glRectfv, (const GLfloat *v1, const GLfloat *v2))
SDL_PROC_UNUSED(void, glRecti, (GLint x1, GLint y1, GLint x2, GLint y2))
SDL_PROC_UNUSED(void, glRectiv, (const GLint *v1, const GLint *v2))
SDL_PROC_UNUSED(void, glRects,
(GLshort x1, GLshort y1, GLshort x2, GLshort y2))
SDL_PROC_UNUSED(void, glRectsv, (const GLshort *v1, const GLshort *v2))
SDL_PROC_UNUSED(GLint, glRenderMode, (GLenum mode))
SDL_PROC_UNUSED(void, glRotated,
(GLdouble angle, GLdouble x, GLdouble y, GLdouble z))
SDL_PROC(void, glRotatef,
(GLfloat angle, GLfloat x, GLfloat y, GLfloat z))
SDL_PROC_UNUSED(void, glScaled, (GLdouble x, GLdouble y, GLdouble z))
SDL_PROC_UNUSED(void, glScalef, (GLfloat x, GLfloat y, GLfloat z))
SDL_PROC(void, glScissor, (GLint x, GLint y, GLsizei width, GLsizei height))
SDL_PROC_UNUSED(void, glSelectBuffer, (GLsizei size, GLuint *buffer))
SDL_PROC(void, glShadeModel, (GLenum mode))
SDL_PROC_UNUSED(void, glStencilFunc, (GLenum func, GLint ref, GLuint mask))
SDL_PROC_UNUSED(void, glStencilMask, (GLuint mask))
SDL_PROC_UNUSED(void, glStencilOp, (GLenum fail, GLenum zfail, GLenum zpass))
SDL_PROC_UNUSED(void, glTexCoord1d, (GLdouble s))
SDL_PROC_UNUSED(void, glTexCoord1dv, (const GLdouble *v))
SDL_PROC_UNUSED(void, glTexCoord1f, (GLfloat s))
SDL_PROC_UNUSED(void, glTexCoord1fv, (const GLfloat *v))
SDL_PROC_UNUSED(void, glTexCoord1i, (GLint s))
SDL_PROC_UNUSED(void, glTexCoord1iv, (const GLint *v))
SDL_PROC_UNUSED(void, glTexCoord1s, (GLshort s))
SDL_PROC_UNUSED(void, glTexCoord1sv, (const GLshort *v))
SDL_PROC_UNUSED(void, glTexCoord2d, (GLdouble s, GLdouble t))
SDL_PROC_UNUSED(void, glTexCoord2dv, (const GLdouble *v))
SDL_PROC(void, glTexCoord2f, (GLfloat s, GLfloat t))
SDL_PROC_UNUSED(void, glTexCoord2fv, (const GLfloat *v))
SDL_PROC_UNUSED(void, glTexCoord2i, (GLint s, GLint t))
SDL_PROC_UNUSED(void, glTexCoord2iv, (const GLint *v))
SDL_PROC_UNUSED(void, glTexCoord2s, (GLshort s, GLshort t))
SDL_PROC_UNUSED(void, glTexCoord2sv, (const GLshort *v))
SDL_PROC_UNUSED(void, glTexCoord3d, (GLdouble s, GLdouble t, GLdouble r))
SDL_PROC_UNUSED(void, glTexCoord3dv, (const GLdouble *v))
SDL_PROC_UNUSED(void, glTexCoord3f, (GLfloat s, GLfloat t, GLfloat r))
SDL_PROC_UNUSED(void, glTexCoord3fv, (const GLfloat *v))
SDL_PROC_UNUSED(void, glTexCoord3i, (GLint s, GLint t, GLint r))
SDL_PROC_UNUSED(void, glTexCoord3iv, (const GLint *v))
SDL_PROC_UNUSED(void, glTexCoord3s, (GLshort s, GLshort t, GLshort r))
SDL_PROC_UNUSED(void, glTexCoord3sv, (const GLshort *v))
SDL_PROC_UNUSED(void, glTexCoord4d,
(GLdouble s, GLdouble t, GLdouble r, GLdouble q))
SDL_PROC_UNUSED(void, glTexCoord4dv, (const GLdouble *v))
SDL_PROC_UNUSED(void, glTexCoord4f,
(GLfloat s, GLfloat t, GLfloat r, GLfloat q))
SDL_PROC_UNUSED(void, glTexCoord4fv, (const GLfloat *v))
SDL_PROC_UNUSED(void, glTexCoord4i, (GLint s, GLint t, GLint r, GLint q))
SDL_PROC_UNUSED(void, glTexCoord4iv, (const GLint *v))
SDL_PROC_UNUSED(void, glTexCoord4s,
(GLshort s, GLshort t, GLshort r, GLshort q))
SDL_PROC_UNUSED(void, glTexCoord4sv, (const GLshort *v))
SDL_PROC(void, glTexCoordPointer,
(GLint size, GLenum type, GLsizei stride,
const GLvoid *pointer))
SDL_PROC(void, glTexEnvf, (GLenum target, GLenum pname, GLfloat param))
SDL_PROC_UNUSED(void, glTexEnvfv,
(GLenum target, GLenum pname, const GLfloat *params))
SDL_PROC_UNUSED(void, glTexEnvi, (GLenum target, GLenum pname, GLint param))
SDL_PROC_UNUSED(void, glTexEnviv,
(GLenum target, GLenum pname, const GLint *params))
SDL_PROC_UNUSED(void, glTexGend, (GLenum coord, GLenum pname, GLdouble param))
SDL_PROC_UNUSED(void, glTexGendv,
(GLenum coord, GLenum pname, const GLdouble *params))
SDL_PROC_UNUSED(void, glTexGenf, (GLenum coord, GLenum pname, GLfloat param))
SDL_PROC_UNUSED(void, glTexGenfv,
(GLenum coord, GLenum pname, const GLfloat *params))
SDL_PROC_UNUSED(void, glTexGeni, (GLenum coord, GLenum pname, GLint param))
SDL_PROC_UNUSED(void, glTexGeniv,
(GLenum coord, GLenum pname, const GLint *params))
SDL_PROC_UNUSED(void, glTexImage1D,
(GLenum target, GLint level, GLint internalformat,
GLsizei width, GLint border, GLenum format, GLenum type,
const GLvoid *pixels))
SDL_PROC(void, glTexImage2D,
(GLenum target, GLint level, GLint internalformat, GLsizei width,
GLsizei height, GLint border, GLenum format, GLenum type,
const GLvoid *pixels))
SDL_PROC_UNUSED(void, glTexParameterf,
(GLenum target, GLenum pname, GLfloat param))
SDL_PROC_UNUSED(void, glTexParameterfv,
(GLenum target, GLenum pname, const GLfloat *params))
SDL_PROC(void, glTexParameteri, (GLenum target, GLenum pname, GLint param))
SDL_PROC_UNUSED(void, glTexParameteriv,
(GLenum target, GLenum pname, const GLint *params))
SDL_PROC_UNUSED(void, glTexSubImage1D,
(GLenum target, GLint level, GLint xoffset, GLsizei width,
GLenum format, GLenum type, const GLvoid *pixels))
SDL_PROC(void, glTexSubImage2D,
(GLenum target, GLint level, GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height, GLenum format, GLenum type,
const GLvoid *pixels))
SDL_PROC_UNUSED(void, glTranslated, (GLdouble x, GLdouble y, GLdouble z))
SDL_PROC_UNUSED(void, glTranslatef, (GLfloat x, GLfloat y, GLfloat z))
SDL_PROC_UNUSED(void, glVertex2d, (GLdouble x, GLdouble y))
SDL_PROC_UNUSED(void, glVertex2dv, (const GLdouble *v))
SDL_PROC(void, glVertex2f, (GLfloat x, GLfloat y))
SDL_PROC_UNUSED(void, glVertex2fv, (const GLfloat *v))
SDL_PROC_UNUSED(void, glVertex2i, (GLint x, GLint y))
SDL_PROC_UNUSED(void, glVertex2iv, (const GLint *v))
SDL_PROC_UNUSED(void, glVertex2s, (GLshort x, GLshort y))
SDL_PROC_UNUSED(void, glVertex2sv, (const GLshort *v))
SDL_PROC_UNUSED(void, glVertex3d, (GLdouble x, GLdouble y, GLdouble z))
SDL_PROC_UNUSED(void, glVertex3dv, (const GLdouble *v))
SDL_PROC_UNUSED(void, glVertex3f, (GLfloat x, GLfloat y, GLfloat z))
SDL_PROC(void, glVertex3fv, (const GLfloat *v))
SDL_PROC_UNUSED(void, glVertex3i, (GLint x, GLint y, GLint z))
SDL_PROC_UNUSED(void, glVertex3iv, (const GLint *v))
SDL_PROC_UNUSED(void, glVertex3s, (GLshort x, GLshort y, GLshort z))
SDL_PROC_UNUSED(void, glVertex3sv, (const GLshort *v))
SDL_PROC_UNUSED(void, glVertex4d,
(GLdouble x, GLdouble y, GLdouble z, GLdouble w))
SDL_PROC_UNUSED(void, glVertex4dv, (const GLdouble *v))
SDL_PROC_UNUSED(void, glVertex4f,
(GLfloat x, GLfloat y, GLfloat z, GLfloat w))
SDL_PROC_UNUSED(void, glVertex4fv, (const GLfloat *v))
SDL_PROC_UNUSED(void, glVertex4i, (GLint x, GLint y, GLint z, GLint w))
SDL_PROC_UNUSED(void, glVertex4iv, (const GLint *v))
SDL_PROC_UNUSED(void, glVertex4s,
(GLshort x, GLshort y, GLshort z, GLshort w))
SDL_PROC_UNUSED(void, glVertex4sv, (const GLshort *v))
SDL_PROC(void, glVertexPointer,
(GLint size, GLenum type, GLsizei stride,
const GLvoid *pointer))
SDL_PROC(void, glViewport, (GLint x, GLint y, GLsizei width, GLsizei height))

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,578 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#if defined(SDL_VIDEO_RENDER_OGL) && !defined(SDL_RENDER_DISABLED)
#include <SDL3/SDL_opengl.h>
#include "SDL_shaders_gl.h"
/* OpenGL shader implementation */
/* #define DEBUG_SHADERS */
typedef struct
{
GLhandleARB program;
GLhandleARB vert_shader;
GLhandleARB frag_shader;
} GL_ShaderData;
struct GL_ShaderContext
{
GLenum (*glGetError)(void);
PFNGLATTACHOBJECTARBPROC glAttachObjectARB;
PFNGLCOMPILESHADERARBPROC glCompileShaderARB;
PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB;
PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB;
PFNGLDELETEOBJECTARBPROC glDeleteObjectARB;
PFNGLGETINFOLOGARBPROC glGetInfoLogARB;
PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB;
PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB;
PFNGLLINKPROGRAMARBPROC glLinkProgramARB;
PFNGLSHADERSOURCEARBPROC glShaderSourceARB;
PFNGLUNIFORM1IARBPROC glUniform1iARB;
PFNGLUNIFORM1FARBPROC glUniform1fARB;
PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB;
SDL_bool GL_ARB_texture_rectangle_supported;
GL_ShaderData shaders[NUM_SHADERS];
};
/* *INDENT-OFF* */ /* clang-format off */
#define COLOR_VERTEX_SHADER \
"varying vec4 v_color;\n" \
"\n" \
"void main()\n" \
"{\n" \
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" \
" v_color = gl_Color;\n" \
"}" \
#define TEXTURE_VERTEX_SHADER \
"varying vec4 v_color;\n" \
"varying vec2 v_texCoord;\n" \
"\n" \
"void main()\n" \
"{\n" \
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" \
" v_color = gl_Color;\n" \
" v_texCoord = vec2(gl_MultiTexCoord0);\n" \
"}" \
#define JPEG_SHADER_CONSTANTS \
"// YUV offset \n" \
"const vec3 offset = vec3(0, -0.501960814, -0.501960814);\n" \
"\n" \
"// RGB coefficients \n" \
"const vec3 Rcoeff = vec3(1, 0.000, 1.402);\n" \
"const vec3 Gcoeff = vec3(1, -0.3441, -0.7141);\n" \
"const vec3 Bcoeff = vec3(1, 1.772, 0.000);\n" \
#define BT601_SHADER_CONSTANTS \
"// YUV offset \n" \
"const vec3 offset = vec3(-0.0627451017, -0.501960814, -0.501960814);\n" \
"\n" \
"// RGB coefficients \n" \
"const vec3 Rcoeff = vec3(1.1644, 0.000, 1.596);\n" \
"const vec3 Gcoeff = vec3(1.1644, -0.3918, -0.813);\n" \
"const vec3 Bcoeff = vec3(1.1644, 2.0172, 0.000);\n" \
#define BT709_SHADER_CONSTANTS \
"// YUV offset \n" \
"const vec3 offset = vec3(-0.0627451017, -0.501960814, -0.501960814);\n" \
"\n" \
"// RGB coefficients \n" \
"const vec3 Rcoeff = vec3(1.1644, 0.000, 1.7927);\n" \
"const vec3 Gcoeff = vec3(1.1644, -0.2132, -0.5329);\n" \
"const vec3 Bcoeff = vec3(1.1644, 2.1124, 0.000);\n" \
#define YUV_SHADER_PROLOGUE \
"varying vec4 v_color;\n" \
"varying vec2 v_texCoord;\n" \
"uniform sampler2D tex0; // Y \n" \
"uniform sampler2D tex1; // U \n" \
"uniform sampler2D tex2; // V \n" \
"\n" \
#define YUV_SHADER_BODY \
"\n" \
"void main()\n" \
"{\n" \
" vec2 tcoord;\n" \
" vec3 yuv, rgb;\n" \
"\n" \
" // Get the Y value \n" \
" tcoord = v_texCoord;\n" \
" yuv.x = texture2D(tex0, tcoord).r;\n" \
"\n" \
" // Get the U and V values \n" \
" tcoord *= UVCoordScale;\n" \
" yuv.y = texture2D(tex1, tcoord).r;\n" \
" yuv.z = texture2D(tex2, tcoord).r;\n" \
"\n" \
" // Do the color transform \n" \
" yuv += offset;\n" \
" rgb.r = dot(yuv, Rcoeff);\n" \
" rgb.g = dot(yuv, Gcoeff);\n" \
" rgb.b = dot(yuv, Bcoeff);\n" \
"\n" \
" // That was easy. :) \n" \
" gl_FragColor = vec4(rgb, 1.0) * v_color;\n" \
"}" \
#define NV12_SHADER_PROLOGUE \
"varying vec4 v_color;\n" \
"varying vec2 v_texCoord;\n" \
"uniform sampler2D tex0; // Y \n" \
"uniform sampler2D tex1; // U/V \n" \
"\n" \
#define NV12_RA_SHADER_BODY \
"\n" \
"void main()\n" \
"{\n" \
" vec2 tcoord;\n" \
" vec3 yuv, rgb;\n" \
"\n" \
" // Get the Y value \n" \
" tcoord = v_texCoord;\n" \
" yuv.x = texture2D(tex0, tcoord).r;\n" \
"\n" \
" // Get the U and V values \n" \
" tcoord *= UVCoordScale;\n" \
" yuv.yz = texture2D(tex1, tcoord).ra;\n" \
"\n" \
" // Do the color transform \n" \
" yuv += offset;\n" \
" rgb.r = dot(yuv, Rcoeff);\n" \
" rgb.g = dot(yuv, Gcoeff);\n" \
" rgb.b = dot(yuv, Bcoeff);\n" \
"\n" \
" // That was easy. :) \n" \
" gl_FragColor = vec4(rgb, 1.0) * v_color;\n" \
"}" \
#define NV12_RG_SHADER_BODY \
"\n" \
"void main()\n" \
"{\n" \
" vec2 tcoord;\n" \
" vec3 yuv, rgb;\n" \
"\n" \
" // Get the Y value \n" \
" tcoord = v_texCoord;\n" \
" yuv.x = texture2D(tex0, tcoord).r;\n" \
"\n" \
" // Get the U and V values \n" \
" tcoord *= UVCoordScale;\n" \
" yuv.yz = texture2D(tex1, tcoord).rg;\n" \
"\n" \
" // Do the color transform \n" \
" yuv += offset;\n" \
" rgb.r = dot(yuv, Rcoeff);\n" \
" rgb.g = dot(yuv, Gcoeff);\n" \
" rgb.b = dot(yuv, Bcoeff);\n" \
"\n" \
" // That was easy. :) \n" \
" gl_FragColor = vec4(rgb, 1.0) * v_color;\n" \
"}" \
#define NV21_SHADER_PROLOGUE \
"varying vec4 v_color;\n" \
"varying vec2 v_texCoord;\n" \
"uniform sampler2D tex0; // Y \n" \
"uniform sampler2D tex1; // U/V \n" \
"\n" \
#define NV21_SHADER_BODY \
"\n" \
"void main()\n" \
"{\n" \
" vec2 tcoord;\n" \
" vec3 yuv, rgb;\n" \
"\n" \
" // Get the Y value \n" \
" tcoord = v_texCoord;\n" \
" yuv.x = texture2D(tex0, tcoord).r;\n" \
"\n" \
" // Get the U and V values \n" \
" tcoord *= UVCoordScale;\n" \
" yuv.yz = texture2D(tex1, tcoord).ar;\n" \
"\n" \
" // Do the color transform \n" \
" yuv += offset;\n" \
" rgb.r = dot(yuv, Rcoeff);\n" \
" rgb.g = dot(yuv, Gcoeff);\n" \
" rgb.b = dot(yuv, Bcoeff);\n" \
"\n" \
" // That was easy. :) \n" \
" gl_FragColor = vec4(rgb, 1.0) * v_color;\n" \
"}" \
/*
* NOTE: Always use sampler2D, etc here. We'll #define them to the
* texture_rectangle versions if we choose to use that extension.
*/
static const char *shader_source[NUM_SHADERS][2] = {
/* SHADER_NONE */
{ NULL, NULL },
/* SHADER_SOLID */
{
/* vertex shader */
COLOR_VERTEX_SHADER,
/* fragment shader */
"varying vec4 v_color;\n"
"\n"
"void main()\n"
"{\n"
" gl_FragColor = v_color;\n"
"}"
},
/* SHADER_RGB */
{
/* vertex shader */
TEXTURE_VERTEX_SHADER,
/* fragment shader */
"varying vec4 v_color;\n"
"varying vec2 v_texCoord;\n"
"uniform sampler2D tex0;\n"
"\n"
"void main()\n"
"{\n"
" gl_FragColor = texture2D(tex0, v_texCoord);\n"
" gl_FragColor.a = 1.0;\n"
" gl_FragColor *= v_color;\n"
"}"
},
/* SHADER_RGBA */
{
/* vertex shader */
TEXTURE_VERTEX_SHADER,
/* fragment shader */
"varying vec4 v_color;\n"
"varying vec2 v_texCoord;\n"
"uniform sampler2D tex0;\n"
"\n"
"void main()\n"
"{\n"
" gl_FragColor = texture2D(tex0, v_texCoord) * v_color;\n"
"}"
},
#if SDL_HAVE_YUV
/* SHADER_YUV_JPEG */
{
/* vertex shader */
TEXTURE_VERTEX_SHADER,
/* fragment shader */
YUV_SHADER_PROLOGUE
JPEG_SHADER_CONSTANTS
YUV_SHADER_BODY
},
/* SHADER_YUV_BT601 */
{
/* vertex shader */
TEXTURE_VERTEX_SHADER,
/* fragment shader */
YUV_SHADER_PROLOGUE
BT601_SHADER_CONSTANTS
YUV_SHADER_BODY
},
/* SHADER_YUV_BT709 */
{
/* vertex shader */
TEXTURE_VERTEX_SHADER,
/* fragment shader */
YUV_SHADER_PROLOGUE
BT709_SHADER_CONSTANTS
YUV_SHADER_BODY
},
/* SHADER_NV12_JPEG */
{
/* vertex shader */
TEXTURE_VERTEX_SHADER,
/* fragment shader */
NV12_SHADER_PROLOGUE
JPEG_SHADER_CONSTANTS
NV12_RA_SHADER_BODY
},
/* SHADER_NV12_RA_BT601 */
{
/* vertex shader */
TEXTURE_VERTEX_SHADER,
/* fragment shader */
NV12_SHADER_PROLOGUE
BT601_SHADER_CONSTANTS
NV12_RA_SHADER_BODY
},
/* SHADER_NV12_RG_BT601 */
{
/* vertex shader */
TEXTURE_VERTEX_SHADER,
/* fragment shader */
NV12_SHADER_PROLOGUE
BT601_SHADER_CONSTANTS
NV12_RG_SHADER_BODY
},
/* SHADER_NV12_RA_BT709 */
{
/* vertex shader */
TEXTURE_VERTEX_SHADER,
/* fragment shader */
NV12_SHADER_PROLOGUE
BT709_SHADER_CONSTANTS
NV12_RA_SHADER_BODY
},
/* SHADER_NV12_RG_BT709 */
{
/* vertex shader */
TEXTURE_VERTEX_SHADER,
/* fragment shader */
NV12_SHADER_PROLOGUE
BT709_SHADER_CONSTANTS
NV12_RG_SHADER_BODY
},
/* SHADER_NV21_JPEG */
{
/* vertex shader */
TEXTURE_VERTEX_SHADER,
/* fragment shader */
NV21_SHADER_PROLOGUE
JPEG_SHADER_CONSTANTS
NV21_SHADER_BODY
},
/* SHADER_NV21_BT601 */
{
/* vertex shader */
TEXTURE_VERTEX_SHADER,
/* fragment shader */
NV21_SHADER_PROLOGUE
BT601_SHADER_CONSTANTS
NV21_SHADER_BODY
},
/* SHADER_NV21_BT709 */
{
/* vertex shader */
TEXTURE_VERTEX_SHADER,
/* fragment shader */
NV21_SHADER_PROLOGUE
BT709_SHADER_CONSTANTS
NV21_SHADER_BODY
},
#endif /* SDL_HAVE_YUV */
};
/* *INDENT-ON* */ /* clang-format on */
static SDL_bool CompileShader(GL_ShaderContext *ctx, GLhandleARB shader, const char *defines, const char *source)
{
GLint status;
const char *sources[2];
sources[0] = defines;
sources[1] = source;
ctx->glShaderSourceARB(shader, SDL_arraysize(sources), sources, NULL);
ctx->glCompileShaderARB(shader);
ctx->glGetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, &status);
if (status == 0) {
SDL_bool isstack;
GLint length;
char *info;
ctx->glGetObjectParameterivARB(shader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length);
info = SDL_small_alloc(char, length + 1, &isstack);
ctx->glGetInfoLogARB(shader, length, NULL, info);
SDL_LogError(SDL_LOG_CATEGORY_RENDER,
"Failed to compile shader:\n%s%s\n%s", defines, source, info);
#ifdef DEBUG_SHADERS
fprintf(stderr,
"Failed to compile shader:\n%s%s\n%s", defines, source, info);
#endif
SDL_small_free(info, isstack);
return SDL_FALSE;
} else {
return SDL_TRUE;
}
}
static SDL_bool CompileShaderProgram(GL_ShaderContext *ctx, int index, GL_ShaderData *data)
{
const int num_tmus_bound = 4;
const char *vert_defines = "";
const char *frag_defines = "";
int i;
GLint location;
if (index == SHADER_NONE) {
return SDL_TRUE;
}
ctx->glGetError();
/* Make sure we use the correct sampler type for our texture type */
if (ctx->GL_ARB_texture_rectangle_supported) {
frag_defines =
"#define sampler2D sampler2DRect\n"
"#define texture2D texture2DRect\n"
"#define UVCoordScale 0.5\n";
} else {
frag_defines =
"#define UVCoordScale 1.0\n";
}
/* Create one program object to rule them all */
data->program = ctx->glCreateProgramObjectARB();
/* Create the vertex shader */
data->vert_shader = ctx->glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
if (!CompileShader(ctx, data->vert_shader, vert_defines, shader_source[index][0])) {
return SDL_FALSE;
}
/* Create the fragment shader */
data->frag_shader = ctx->glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
if (!CompileShader(ctx, data->frag_shader, frag_defines, shader_source[index][1])) {
return SDL_FALSE;
}
/* ... and in the darkness bind them */
ctx->glAttachObjectARB(data->program, data->vert_shader);
ctx->glAttachObjectARB(data->program, data->frag_shader);
ctx->glLinkProgramARB(data->program);
/* Set up some uniform variables */
ctx->glUseProgramObjectARB(data->program);
for (i = 0; i < num_tmus_bound; ++i) {
char tex_name[10];
(void)SDL_snprintf(tex_name, SDL_arraysize(tex_name), "tex%d", i);
location = ctx->glGetUniformLocationARB(data->program, tex_name);
if (location >= 0) {
ctx->glUniform1iARB(location, i);
}
}
ctx->glUseProgramObjectARB(0);
return ctx->glGetError() == GL_NO_ERROR;
}
static void DestroyShaderProgram(GL_ShaderContext *ctx, GL_ShaderData *data)
{
ctx->glDeleteObjectARB(data->vert_shader);
ctx->glDeleteObjectARB(data->frag_shader);
ctx->glDeleteObjectARB(data->program);
}
GL_ShaderContext *GL_CreateShaderContext(void)
{
GL_ShaderContext *ctx;
SDL_bool shaders_supported;
int i;
ctx = (GL_ShaderContext *)SDL_calloc(1, sizeof(*ctx));
if (ctx == NULL) {
return NULL;
}
if (!SDL_GL_ExtensionSupported("GL_ARB_texture_non_power_of_two") &&
(SDL_GL_ExtensionSupported("GL_ARB_texture_rectangle") ||
SDL_GL_ExtensionSupported("GL_EXT_texture_rectangle"))) {
ctx->GL_ARB_texture_rectangle_supported = SDL_TRUE;
}
/* Check for shader support */
shaders_supported = SDL_FALSE;
if (SDL_GL_ExtensionSupported("GL_ARB_shader_objects") &&
SDL_GL_ExtensionSupported("GL_ARB_shading_language_100") &&
SDL_GL_ExtensionSupported("GL_ARB_vertex_shader") &&
SDL_GL_ExtensionSupported("GL_ARB_fragment_shader")) {
ctx->glGetError = (GLenum(*)(void))SDL_GL_GetProcAddress("glGetError");
ctx->glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)SDL_GL_GetProcAddress("glAttachObjectARB");
ctx->glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)SDL_GL_GetProcAddress("glCompileShaderARB");
ctx->glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)SDL_GL_GetProcAddress("glCreateProgramObjectARB");
ctx->glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)SDL_GL_GetProcAddress("glCreateShaderObjectARB");
ctx->glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC)SDL_GL_GetProcAddress("glDeleteObjectARB");
ctx->glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)SDL_GL_GetProcAddress("glGetInfoLogARB");
ctx->glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)SDL_GL_GetProcAddress("glGetObjectParameterivARB");
ctx->glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC)SDL_GL_GetProcAddress("glGetUniformLocationARB");
ctx->glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)SDL_GL_GetProcAddress("glLinkProgramARB");
ctx->glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)SDL_GL_GetProcAddress("glShaderSourceARB");
ctx->glUniform1iARB = (PFNGLUNIFORM1IARBPROC)SDL_GL_GetProcAddress("glUniform1iARB");
ctx->glUniform1fARB = (PFNGLUNIFORM1FARBPROC)SDL_GL_GetProcAddress("glUniform1fARB");
ctx->glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)SDL_GL_GetProcAddress("glUseProgramObjectARB");
if (ctx->glGetError &&
ctx->glAttachObjectARB &&
ctx->glCompileShaderARB &&
ctx->glCreateProgramObjectARB &&
ctx->glCreateShaderObjectARB &&
ctx->glDeleteObjectARB &&
ctx->glGetInfoLogARB &&
ctx->glGetObjectParameterivARB &&
ctx->glGetUniformLocationARB &&
ctx->glLinkProgramARB &&
ctx->glShaderSourceARB &&
ctx->glUniform1iARB &&
ctx->glUniform1fARB &&
ctx->glUseProgramObjectARB) {
shaders_supported = SDL_TRUE;
}
}
if (!shaders_supported) {
SDL_free(ctx);
return NULL;
}
/* Compile all the shaders */
for (i = 0; i < NUM_SHADERS; ++i) {
if (!CompileShaderProgram(ctx, i, &ctx->shaders[i])) {
GL_DestroyShaderContext(ctx);
return NULL;
}
}
/* We're done! */
return ctx;
}
void GL_SelectShader(GL_ShaderContext *ctx, GL_Shader shader)
{
ctx->glUseProgramObjectARB(ctx->shaders[shader].program);
}
void GL_DestroyShaderContext(GL_ShaderContext *ctx)
{
int i;
for (i = 0; i < NUM_SHADERS; ++i) {
DestroyShaderProgram(ctx, &ctx->shaders[i]);
}
SDL_free(ctx);
}
#endif /* SDL_VIDEO_RENDER_OGL && !SDL_RENDER_DISABLED */

View File

@ -0,0 +1,58 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_shaders_gl_h_
#define SDL_shaders_gl_h_
#include "SDL_internal.h"
/* OpenGL shader implementation */
typedef enum
{
SHADER_INVALID = -1,
SHADER_NONE,
SHADER_SOLID,
SHADER_RGB,
SHADER_RGBA,
#if SDL_HAVE_YUV
SHADER_YUV_JPEG,
SHADER_YUV_BT601,
SHADER_YUV_BT709,
SHADER_NV12_JPEG,
SHADER_NV12_RA_BT601,
SHADER_NV12_RG_BT601,
SHADER_NV12_RA_BT709,
SHADER_NV12_RG_BT709,
SHADER_NV21_JPEG,
SHADER_NV21_BT601,
SHADER_NV21_BT709,
#endif
NUM_SHADERS
} GL_Shader;
typedef struct GL_ShaderContext GL_ShaderContext;
extern GL_ShaderContext *GL_CreateShaderContext(void);
extern void GL_SelectShader(GL_ShaderContext *ctx, GL_Shader shader);
extern void GL_DestroyShaderContext(GL_ShaderContext *ctx);
#endif /* SDL_shaders_gl_h_ */

View File

@ -0,0 +1,76 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
SDL_PROC(void, glActiveTexture, (GLenum))
SDL_PROC(void, glAttachShader, (GLuint, GLuint))
SDL_PROC(void, glBindAttribLocation, (GLuint, GLuint, const char *))
SDL_PROC(void, glBindTexture, (GLenum, GLuint))
SDL_PROC(void, glBlendEquationSeparate, (GLenum, GLenum))
SDL_PROC(void, glBlendFuncSeparate, (GLenum, GLenum, GLenum, GLenum))
SDL_PROC(void, glClear, (GLbitfield))
SDL_PROC(void, glClearColor, (GLclampf, GLclampf, GLclampf, GLclampf))
SDL_PROC(void, glCompileShader, (GLuint))
SDL_PROC(GLuint, glCreateProgram, (void))
SDL_PROC(GLuint, glCreateShader, (GLenum))
SDL_PROC(void, glDeleteProgram, (GLuint))
SDL_PROC(void, glDeleteShader, (GLuint))
SDL_PROC(void, glDeleteTextures, (GLsizei, const GLuint *))
SDL_PROC(void, glDisable, (GLenum))
SDL_PROC(void, glDisableVertexAttribArray, (GLuint))
SDL_PROC(void, glDrawArrays, (GLenum, GLint, GLsizei))
SDL_PROC(void, glEnable, (GLenum))
SDL_PROC(void, glEnableVertexAttribArray, (GLuint))
SDL_PROC(void, glFinish, (void))
SDL_PROC(void, glGenFramebuffers, (GLsizei, GLuint *))
SDL_PROC(void, glGenTextures, (GLsizei, GLuint *))
SDL_PROC(const GLubyte *, glGetString, (GLenum))
SDL_PROC(GLenum, glGetError, (void))
SDL_PROC(void, glGetIntegerv, (GLenum, GLint *))
SDL_PROC(void, glGetProgramiv, (GLuint, GLenum, GLint *))
SDL_PROC(void, glGetShaderInfoLog, (GLuint, GLsizei, GLsizei *, char *))
SDL_PROC(void, glGetShaderiv, (GLuint, GLenum, GLint *))
SDL_PROC(GLint, glGetUniformLocation, (GLuint, const char *))
SDL_PROC(void, glLinkProgram, (GLuint))
SDL_PROC(void, glPixelStorei, (GLenum, GLint))
SDL_PROC(void, glReadPixels, (GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid *))
SDL_PROC(void, glScissor, (GLint, GLint, GLsizei, GLsizei))
SDL_PROC(void, glShaderBinary, (GLsizei, const GLuint *, GLenum, const void *, GLsizei))
SDL_PROC(void, glShaderSource, (GLuint, GLsizei, const GLchar *const *, const GLint *))
SDL_PROC(void, glTexImage2D, (GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const void *))
SDL_PROC(void, glTexParameteri, (GLenum, GLenum, GLint))
SDL_PROC(void, glTexSubImage2D, (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *))
SDL_PROC(void, glUniform1i, (GLint, GLint))
SDL_PROC(void, glUniform4f, (GLint, GLfloat, GLfloat, GLfloat, GLfloat))
SDL_PROC(void, glUniformMatrix4fv, (GLint, GLsizei, GLboolean, const GLfloat *))
SDL_PROC(void, glUseProgram, (GLuint))
SDL_PROC(void, glVertexAttribPointer, (GLuint, GLint, GLenum, GLboolean, GLsizei, const void *))
SDL_PROC(void, glViewport, (GLint, GLint, GLsizei, GLsizei))
SDL_PROC(void, glBindFramebuffer, (GLenum, GLuint))
SDL_PROC(void, glFramebufferTexture2D, (GLenum, GLenum, GLenum, GLuint, GLint))
SDL_PROC(GLenum, glCheckFramebufferStatus, (GLenum))
SDL_PROC(void, glDeleteFramebuffers, (GLsizei, const GLuint *))
SDL_PROC(GLint, glGetAttribLocation, (GLuint, const GLchar *))
SDL_PROC(void, glGetProgramInfoLog, (GLuint, GLsizei, GLsizei *, GLchar *))
SDL_PROC(void, glGenBuffers, (GLsizei, GLuint *))
SDL_PROC(void, glDeleteBuffers, (GLsizei, const GLuint *))
SDL_PROC(void, glBindBuffer, (GLenum, GLuint))
SDL_PROC(void, glBufferData, (GLenum, GLsizeiptr, const GLvoid *, GLenum))
SDL_PROC(void, glBufferSubData, (GLenum, GLintptr, GLsizeiptr, const GLvoid *))

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,444 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#if defined(SDL_VIDEO_RENDER_OGL_ES2) && !defined(SDL_RENDER_DISABLED)
#include <SDL3/SDL_opengles2.h>
#include "SDL_shaders_gles2.h"
/* *INDENT-OFF* */ /* clang-format off */
/*************************************************************************************************
* Vertex/fragment shader source *
*************************************************************************************************/
static const char GLES2_Fragment_Include_Best_Texture_Precision[] = \
"#ifdef GL_FRAGMENT_PRECISION_HIGH\n" \
"#define SDL_TEXCOORD_PRECISION highp\n" \
"#else\n" \
"#define SDL_TEXCOORD_PRECISION mediump\n" \
"#endif\n" \
"\n" \
"precision mediump float;\n" \
"\n" \
;
static const char GLES2_Fragment_Include_Medium_Texture_Precision[] = \
"#define SDL_TEXCOORD_PRECISION mediump\n" \
"precision mediump float;\n" \
"\n" \
;
static const char GLES2_Fragment_Include_High_Texture_Precision[] = \
"#define SDL_TEXCOORD_PRECISION highp\n" \
"precision mediump float;\n" \
"\n" \
;
static const char GLES2_Fragment_Include_Undef_Precision[] = \
"#define mediump\n" \
"#define highp\n" \
"#define lowp\n" \
"#define SDL_TEXCOORD_PRECISION\n" \
"\n" \
;
static const char GLES2_Vertex_Default[] = \
"uniform mat4 u_projection;\n" \
"attribute vec2 a_position;\n" \
"attribute vec4 a_color;\n" \
"attribute vec2 a_texCoord;\n" \
"varying vec2 v_texCoord;\n" \
"varying vec4 v_color;\n" \
"\n" \
"void main()\n" \
"{\n" \
" v_texCoord = a_texCoord;\n" \
" gl_Position = u_projection * vec4(a_position, 0.0, 1.0);\n" \
" gl_PointSize = 1.0;\n" \
" v_color = a_color;\n" \
"}\n" \
;
static const char GLES2_Fragment_Solid[] = \
"varying mediump vec4 v_color;\n" \
"\n" \
"void main()\n" \
"{\n" \
" gl_FragColor = v_color;\n" \
"}\n" \
;
static const char GLES2_Fragment_TextureABGR[] = \
"uniform sampler2D u_texture;\n" \
"varying mediump vec4 v_color;\n" \
"varying SDL_TEXCOORD_PRECISION vec2 v_texCoord;\n" \
"\n" \
"void main()\n" \
"{\n" \
" gl_FragColor = texture2D(u_texture, v_texCoord);\n" \
" gl_FragColor *= v_color;\n" \
"}\n" \
;
/* ARGB to ABGR conversion */
static const char GLES2_Fragment_TextureARGB[] = \
"uniform sampler2D u_texture;\n" \
"varying mediump vec4 v_color;\n" \
"varying SDL_TEXCOORD_PRECISION vec2 v_texCoord;\n" \
"\n" \
"void main()\n" \
"{\n" \
" mediump vec4 abgr = texture2D(u_texture, v_texCoord);\n" \
" gl_FragColor = abgr;\n" \
" gl_FragColor.r = abgr.b;\n" \
" gl_FragColor.b = abgr.r;\n" \
" gl_FragColor *= v_color;\n" \
"}\n" \
;
/* RGB to ABGR conversion */
static const char GLES2_Fragment_TextureRGB[] = \
"uniform sampler2D u_texture;\n" \
"varying mediump vec4 v_color;\n" \
"varying SDL_TEXCOORD_PRECISION vec2 v_texCoord;\n" \
"\n" \
"void main()\n" \
"{\n" \
" mediump vec4 abgr = texture2D(u_texture, v_texCoord);\n" \
" gl_FragColor = abgr;\n" \
" gl_FragColor.r = abgr.b;\n" \
" gl_FragColor.b = abgr.r;\n" \
" gl_FragColor.a = 1.0;\n" \
" gl_FragColor *= v_color;\n" \
"}\n" \
;
/* BGR to ABGR conversion */
static const char GLES2_Fragment_TextureBGR[] = \
"uniform sampler2D u_texture;\n" \
"varying mediump vec4 v_color;\n" \
"varying SDL_TEXCOORD_PRECISION vec2 v_texCoord;\n" \
"\n" \
"void main()\n" \
"{\n" \
" mediump vec4 abgr = texture2D(u_texture, v_texCoord);\n" \
" gl_FragColor = abgr;\n" \
" gl_FragColor.a = 1.0;\n" \
" gl_FragColor *= v_color;\n" \
"}\n" \
;
#if SDL_HAVE_YUV
#define JPEG_SHADER_CONSTANTS \
"// YUV offset \n" \
"const vec3 offset = vec3(0, -0.501960814, -0.501960814);\n" \
"\n" \
"// RGB coefficients \n" \
"const mat3 matrix = mat3( 1, 1, 1,\n" \
" 0, -0.3441, 1.772,\n" \
" 1.402, -0.7141, 0);\n" \
"\n" \
#define BT601_SHADER_CONSTANTS \
"// YUV offset \n" \
"const vec3 offset = vec3(-0.0627451017, -0.501960814, -0.501960814);\n" \
"\n" \
"// RGB coefficients \n" \
"const mat3 matrix = mat3( 1.1644, 1.1644, 1.1644,\n" \
" 0, -0.3918, 2.0172,\n" \
" 1.596, -0.813, 0);\n" \
"\n" \
#define BT709_SHADER_CONSTANTS \
"// YUV offset \n" \
"const vec3 offset = vec3(-0.0627451017, -0.501960814, -0.501960814);\n" \
"\n" \
"// RGB coefficients \n" \
"const mat3 matrix = mat3( 1.1644, 1.1644, 1.1644,\n" \
" 0, -0.2132, 2.1124,\n" \
" 1.7927, -0.5329, 0);\n" \
"\n" \
#define YUV_SHADER_PROLOGUE \
"uniform sampler2D u_texture;\n" \
"uniform sampler2D u_texture_u;\n" \
"uniform sampler2D u_texture_v;\n" \
"varying mediump vec4 v_color;\n" \
"varying SDL_TEXCOORD_PRECISION vec2 v_texCoord;\n" \
"\n" \
#define YUV_SHADER_BODY \
"void main()\n" \
"{\n" \
" mediump vec3 yuv;\n" \
" lowp vec3 rgb;\n" \
"\n" \
" // Get the YUV values \n" \
" yuv.x = texture2D(u_texture, v_texCoord).r;\n" \
" yuv.y = texture2D(u_texture_u, v_texCoord).r;\n" \
" yuv.z = texture2D(u_texture_v, v_texCoord).r;\n" \
"\n" \
" // Do the color transform \n" \
" yuv += offset;\n" \
" rgb = matrix * yuv;\n" \
"\n" \
" // That was easy. :) \n" \
" gl_FragColor = vec4(rgb, 1);\n" \
" gl_FragColor *= v_color;\n" \
"}" \
#define NV12_RA_SHADER_BODY \
"void main()\n" \
"{\n" \
" mediump vec3 yuv;\n" \
" lowp vec3 rgb;\n" \
"\n" \
" // Get the YUV values \n" \
" yuv.x = texture2D(u_texture, v_texCoord).r;\n" \
" yuv.yz = texture2D(u_texture_u, v_texCoord).ra;\n" \
"\n" \
" // Do the color transform \n" \
" yuv += offset;\n" \
" rgb = matrix * yuv;\n" \
"\n" \
" // That was easy. :) \n" \
" gl_FragColor = vec4(rgb, 1);\n" \
" gl_FragColor *= v_color;\n" \
"}" \
#define NV12_RG_SHADER_BODY \
"void main()\n" \
"{\n" \
" mediump vec3 yuv;\n" \
" lowp vec3 rgb;\n" \
"\n" \
" // Get the YUV values \n" \
" yuv.x = texture2D(u_texture, v_texCoord).r;\n" \
" yuv.yz = texture2D(u_texture_u, v_texCoord).rg;\n" \
"\n" \
" // Do the color transform \n" \
" yuv += offset;\n" \
" rgb = matrix * yuv;\n" \
"\n" \
" // That was easy. :) \n" \
" gl_FragColor = vec4(rgb, 1);\n" \
" gl_FragColor *= v_color;\n" \
"}" \
#define NV21_SHADER_BODY \
"void main()\n" \
"{\n" \
" mediump vec3 yuv;\n" \
" lowp vec3 rgb;\n" \
"\n" \
" // Get the YUV values \n" \
" yuv.x = texture2D(u_texture, v_texCoord).r;\n" \
" yuv.yz = texture2D(u_texture_u, v_texCoord).ar;\n" \
"\n" \
" // Do the color transform \n" \
" yuv += offset;\n" \
" rgb = matrix * yuv;\n" \
"\n" \
" // That was easy. :) \n" \
" gl_FragColor = vec4(rgb, 1);\n" \
" gl_FragColor *= v_color;\n" \
"}" \
/* YUV to ABGR conversion */
static const char GLES2_Fragment_TextureYUVJPEG[] = \
YUV_SHADER_PROLOGUE \
JPEG_SHADER_CONSTANTS \
YUV_SHADER_BODY \
;
static const char GLES2_Fragment_TextureYUVBT601[] = \
YUV_SHADER_PROLOGUE \
BT601_SHADER_CONSTANTS \
YUV_SHADER_BODY \
;
static const char GLES2_Fragment_TextureYUVBT709[] = \
YUV_SHADER_PROLOGUE \
BT709_SHADER_CONSTANTS \
YUV_SHADER_BODY \
;
/* NV12 to ABGR conversion */
static const char GLES2_Fragment_TextureNV12JPEG[] = \
YUV_SHADER_PROLOGUE \
JPEG_SHADER_CONSTANTS \
NV12_RA_SHADER_BODY \
;
static const char GLES2_Fragment_TextureNV12BT601_RA[] = \
YUV_SHADER_PROLOGUE \
BT601_SHADER_CONSTANTS \
NV12_RA_SHADER_BODY \
;
static const char GLES2_Fragment_TextureNV12BT601_RG[] = \
YUV_SHADER_PROLOGUE \
BT601_SHADER_CONSTANTS \
NV12_RG_SHADER_BODY \
;
static const char GLES2_Fragment_TextureNV12BT709_RA[] = \
YUV_SHADER_PROLOGUE \
BT709_SHADER_CONSTANTS \
NV12_RA_SHADER_BODY \
;
static const char GLES2_Fragment_TextureNV12BT709_RG[] = \
YUV_SHADER_PROLOGUE \
BT709_SHADER_CONSTANTS \
NV12_RG_SHADER_BODY \
;
/* NV21 to ABGR conversion */
static const char GLES2_Fragment_TextureNV21JPEG[] = \
YUV_SHADER_PROLOGUE \
JPEG_SHADER_CONSTANTS \
NV21_SHADER_BODY \
;
static const char GLES2_Fragment_TextureNV21BT601[] = \
YUV_SHADER_PROLOGUE \
BT601_SHADER_CONSTANTS \
NV21_SHADER_BODY \
;
static const char GLES2_Fragment_TextureNV21BT709[] = \
YUV_SHADER_PROLOGUE \
BT709_SHADER_CONSTANTS \
NV21_SHADER_BODY \
;
#endif
/* Custom Android video format texture */
static const char GLES2_Fragment_TextureExternalOES_Prologue[] = \
"#extension GL_OES_EGL_image_external : require\n" \
"\n" \
;
static const char GLES2_Fragment_TextureExternalOES[] = \
"uniform samplerExternalOES u_texture;\n" \
"varying mediump vec4 v_color;\n" \
"varying SDL_TEXCOORD_PRECISION vec2 v_texCoord;\n" \
"\n" \
"void main()\n" \
"{\n" \
" gl_FragColor = texture2D(u_texture, v_texCoord);\n" \
" gl_FragColor *= v_color;\n" \
"}\n" \
;
/* *INDENT-ON* */ /* clang-format on */
/*************************************************************************************************
* Shader selector *
*************************************************************************************************/
const char *GLES2_GetShaderPrologue(GLES2_ShaderType type)
{
switch (type) {
case GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES:
return GLES2_Fragment_TextureExternalOES_Prologue;
default:
return "";
}
}
const char *GLES2_GetShaderInclude(GLES2_ShaderIncludeType type)
{
switch (type) {
case GLES2_SHADER_FRAGMENT_INCLUDE_UNDEF_PRECISION:
return GLES2_Fragment_Include_Undef_Precision;
case GLES2_SHADER_FRAGMENT_INCLUDE_BEST_TEXCOORD_PRECISION:
return GLES2_Fragment_Include_Best_Texture_Precision;
case GLES2_SHADER_FRAGMENT_INCLUDE_MEDIUM_TEXCOORD_PRECISION:
return GLES2_Fragment_Include_Medium_Texture_Precision;
case GLES2_SHADER_FRAGMENT_INCLUDE_HIGH_TEXCOORD_PRECISION:
return GLES2_Fragment_Include_High_Texture_Precision;
default:
return "";
}
}
GLES2_ShaderIncludeType GLES2_GetTexCoordPrecisionEnumFromHint(void)
{
const char *texcoord_hint = SDL_GetHint("SDL_RENDER_OPENGLES2_TEXCOORD_PRECISION");
GLES2_ShaderIncludeType value = GLES2_SHADER_FRAGMENT_INCLUDE_BEST_TEXCOORD_PRECISION;
if (texcoord_hint) {
if (SDL_strcmp(texcoord_hint, "undefined") == 0) {
return GLES2_SHADER_FRAGMENT_INCLUDE_UNDEF_PRECISION;
}
if (SDL_strcmp(texcoord_hint, "high") == 0) {
return GLES2_SHADER_FRAGMENT_INCLUDE_HIGH_TEXCOORD_PRECISION;
}
if (SDL_strcmp(texcoord_hint, "medium") == 0) {
return GLES2_SHADER_FRAGMENT_INCLUDE_MEDIUM_TEXCOORD_PRECISION;
}
}
return value;
}
const char *GLES2_GetShader(GLES2_ShaderType type)
{
switch (type) {
case GLES2_SHADER_VERTEX_DEFAULT:
return GLES2_Vertex_Default;
case GLES2_SHADER_FRAGMENT_SOLID:
return GLES2_Fragment_Solid;
case GLES2_SHADER_FRAGMENT_TEXTURE_ABGR:
return GLES2_Fragment_TextureABGR;
case GLES2_SHADER_FRAGMENT_TEXTURE_ARGB:
return GLES2_Fragment_TextureARGB;
case GLES2_SHADER_FRAGMENT_TEXTURE_RGB:
return GLES2_Fragment_TextureRGB;
case GLES2_SHADER_FRAGMENT_TEXTURE_BGR:
return GLES2_Fragment_TextureBGR;
#if SDL_HAVE_YUV
case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG:
return GLES2_Fragment_TextureYUVJPEG;
case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601:
return GLES2_Fragment_TextureYUVBT601;
case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709:
return GLES2_Fragment_TextureYUVBT709;
case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG:
return GLES2_Fragment_TextureNV12JPEG;
case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT601:
return GLES2_Fragment_TextureNV12BT601_RA;
case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT601:
return GLES2_Fragment_TextureNV12BT601_RG;
case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT709:
return GLES2_Fragment_TextureNV12BT709_RA;
case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT709:
return GLES2_Fragment_TextureNV12BT709_RG;
case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG:
return GLES2_Fragment_TextureNV21JPEG;
case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601:
return GLES2_Fragment_TextureNV21BT601;
case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709:
return GLES2_Fragment_TextureNV21BT709;
#endif
case GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES:
return GLES2_Fragment_TextureExternalOES;
default:
return NULL;
}
}
#endif /* SDL_VIDEO_RENDER_OGL_ES2 && !SDL_RENDER_DISABLED */

View File

@ -0,0 +1,71 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifndef SDL_shaders_gles2_h_
#define SDL_shaders_gles2_h_
#ifdef SDL_VIDEO_RENDER_OGL_ES2
typedef enum
{
GLES2_SHADER_FRAGMENT_INCLUDE_NONE = 0,
GLES2_SHADER_FRAGMENT_INCLUDE_BEST_TEXCOORD_PRECISION,
GLES2_SHADER_FRAGMENT_INCLUDE_MEDIUM_TEXCOORD_PRECISION,
GLES2_SHADER_FRAGMENT_INCLUDE_HIGH_TEXCOORD_PRECISION,
GLES2_SHADER_FRAGMENT_INCLUDE_UNDEF_PRECISION,
GLES2_SHADER_FRAGMENT_INCLUDE_COUNT
} GLES2_ShaderIncludeType;
typedef enum
{
GLES2_SHADER_VERTEX_DEFAULT = 0,
GLES2_SHADER_FRAGMENT_SOLID,
GLES2_SHADER_FRAGMENT_TEXTURE_ABGR,
GLES2_SHADER_FRAGMENT_TEXTURE_ARGB,
GLES2_SHADER_FRAGMENT_TEXTURE_BGR,
GLES2_SHADER_FRAGMENT_TEXTURE_RGB,
#if SDL_HAVE_YUV
GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG,
GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601,
GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709,
GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG,
GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT601,
GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT601,
GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RA_BT709,
GLES2_SHADER_FRAGMENT_TEXTURE_NV12_RG_BT709,
GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG,
GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601,
GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709,
#endif
/* Shaders beyond this point are optional and not cached at render creation */
GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES,
GLES2_SHADER_COUNT
} GLES2_ShaderType;
extern const char *GLES2_GetShaderPrologue(GLES2_ShaderType type);
extern const char *GLES2_GetShaderInclude(GLES2_ShaderIncludeType type);
extern const char *GLES2_GetShader(GLES2_ShaderType type);
extern GLES2_ShaderIncludeType GLES2_GetTexCoordPrecisionEnumFromHint(void);
#endif /* SDL_VIDEO_RENDER_OGL_ES2 */
#endif /* SDL_shaders_gles2_h_ */

View File

@ -0,0 +1,679 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_VIDEO_RENDER_PS2
#include "../SDL_sysrender.h"
#include <kernel.h>
#include <malloc.h>
#include <gsKit.h>
#include <dmaKit.h>
#include <gsToolkit.h>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeclaration-after-statement"
#include <gsInline.h>
#pragma GCC diagnostic pop
/* turn black GS Screen */
#define GS_BLACK GS_SETREG_RGBA(0x00, 0x00, 0x00, 0x80)
/* Size of Persistent drawbuffer (Single Buffered) */
#define RENDER_QUEUE_PER_POOLSIZE 1024 * 256 // 256K of persistent renderqueue
/* Size of Oneshot drawbuffer (Double Buffered, so it uses this size * 2) */
#define RENDER_QUEUE_OS_POOLSIZE 1024 * 1024 * 2 // 2048K of oneshot renderqueue
typedef struct
{
GSGLOBAL *gsGlobal;
uint64_t drawColor;
int32_t vsync_callback_id;
uint8_t vsync; /* 0 (Disabled), 1 (Enabled), 2 (Dynamic) */
} PS2_RenderData;
static int vsync_sema_id = 0;
/* PRIVATE METHODS */
static int vsync_handler()
{
iSignalSema(vsync_sema_id);
ExitHandler();
return 0;
}
/* Copy of gsKit_sync_flip, but without the 'flip' */
static void gsKit_sync(GSGLOBAL *gsGlobal)
{
if (!gsGlobal->FirstFrame) {
WaitSema(vsync_sema_id);
}
while (PollSema(vsync_sema_id) >= 0)
;
}
/* Copy of gsKit_sync_flip, but without the 'sync' */
static void gsKit_flip(GSGLOBAL *gsGlobal)
{
if (!gsGlobal->FirstFrame) {
if (gsGlobal->DoubleBuffering == GS_SETTING_ON) {
GS_SET_DISPFB2(gsGlobal->ScreenBuffer[gsGlobal->ActiveBuffer & 1] / 8192,
gsGlobal->Width / 64, gsGlobal->PSM, 0, 0);
gsGlobal->ActiveBuffer ^= 1;
}
}
gsKit_setactive(gsGlobal);
}
static int PixelFormatToPS2PSM(Uint32 format)
{
switch (format) {
case SDL_PIXELFORMAT_ABGR1555:
return GS_PSM_CT16;
default:
return GS_PSM_CT32;
}
}
static void PS2_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event)
{
}
static int PS2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
{
GSTEXTURE *ps2_tex = (GSTEXTURE *)SDL_calloc(1, sizeof(GSTEXTURE));
if (ps2_tex == NULL) {
return SDL_OutOfMemory();
}
ps2_tex->Width = texture->w;
ps2_tex->Height = texture->h;
ps2_tex->PSM = PixelFormatToPS2PSM(texture->format);
ps2_tex->Mem = SDL_aligned_alloc(128, gsKit_texture_size_ee(ps2_tex->Width, ps2_tex->Height, ps2_tex->PSM));
if (!ps2_tex->Mem) {
SDL_free(ps2_tex);
return SDL_OutOfMemory();
}
texture->driverdata = ps2_tex;
return 0;
}
static int PS2_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
const SDL_Rect *rect, void **pixels, int *pitch)
{
GSTEXTURE *ps2_texture = (GSTEXTURE *)texture->driverdata;
*pixels =
(void *)((Uint8 *)ps2_texture->Mem + rect->y * ps2_texture->Width * SDL_BYTESPERPIXEL(texture->format) +
rect->x * SDL_BYTESPERPIXEL(texture->format));
*pitch = ps2_texture->Width * SDL_BYTESPERPIXEL(texture->format);
return 0;
}
static void PS2_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture)
{
GSTEXTURE *ps2_texture = (GSTEXTURE *)texture->driverdata;
PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata;
gsKit_TexManager_invalidate(data->gsGlobal, ps2_texture);
}
static int PS2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture,
const SDL_Rect *rect, const void *pixels, int pitch)
{
const Uint8 *src;
Uint8 *dst;
int row, length, dpitch;
src = pixels;
PS2_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch);
length = rect->w * SDL_BYTESPERPIXEL(texture->format);
if (length == pitch && length == dpitch) {
SDL_memcpy(dst, src, length * rect->h);
} else {
for (row = 0; row < rect->h; ++row) {
SDL_memcpy(dst, src, length);
src += pitch;
dst += dpitch;
}
}
PS2_UnlockTexture(renderer, texture);
return 0;
}
static void PS2_SetTextureScaleMode(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode)
{
GSTEXTURE *ps2_texture = (GSTEXTURE *)texture->driverdata;
/*
set texture filtering according to scaleMode
supported hint values are nearest (0, default) or linear (1)
gskit scale mode is either GS_FILTER_NEAREST (good for tile-map)
or GS_FILTER_LINEAR (good for scaling)
*/
uint32_t gsKitScaleMode = (scaleMode == SDL_SCALEMODE_NEAREST
? GS_FILTER_NEAREST
: GS_FILTER_LINEAR);
ps2_texture->Filter = gsKitScaleMode;
}
static int PS2_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
{
return 0;
}
static int PS2_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
{
return 0; /* nothing to do in this backend. */
}
static int PS2_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
{
PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata;
GSPRIMPOINT *vertices = (GSPRIMPOINT *)SDL_AllocateRenderVertices(renderer, count * sizeof(GSPRIMPOINT), 4, &cmd->data.draw.first);
uint8_t colorR, colorG, colorB, colorA;
gs_rgbaq rgbaq;
int i;
if (vertices == NULL) {
return -1;
}
cmd->data.draw.count = count;
colorR = cmd->data.draw.r >> 1;
colorG = cmd->data.draw.g >> 1;
colorB = cmd->data.draw.b >> 1;
colorA = cmd->data.draw.a >> 1;
rgbaq = color_to_RGBAQ(colorR, colorG, colorB, colorA, 0.0f);
for (i = 0; i < count; i++, vertices++, points++) {
vertices->xyz2 = vertex_to_XYZ2(data->gsGlobal, points->x, points->y, 0);
vertices->rgbaq = rgbaq;
}
return 0;
}
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;
PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata;
cmd->data.draw.count = count;
size_indices = indices ? size_indices : 0;
if (texture) {
GSPRIMUVPOINT *vertices = (GSPRIMUVPOINT *) SDL_AllocateRenderVertices(renderer, count * sizeof(GSPRIMUVPOINT), 4, &cmd->data.draw.first);
GSTEXTURE *ps2_tex = (GSTEXTURE *) texture->driverdata;
if (vertices == NULL) {
return -1;
}
for (i = 0; i < count; i++) {
int j;
float *xy_;
float *uv_;
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);
uv_ = (float *)((char *)uv + j * uv_stride);
vertices->xyz2 = vertex_to_XYZ2(data->gsGlobal, xy_[0] * scale_x, xy_[1] * scale_y, 0);
vertices->rgbaq = color_to_RGBAQ(col_.r >> 1, col_.g >> 1, col_.b >> 1, col_.a >> 1, 0);
vertices->uv = vertex_to_UV(ps2_tex, uv_[0] * ps2_tex->Width, uv_[1] * ps2_tex->Height);
vertices++;
}
} else {
GSPRIMPOINT *vertices = (GSPRIMPOINT *)SDL_AllocateRenderVertices(renderer, count * sizeof(GSPRIMPOINT), 4, &cmd->data.draw.first);
if (vertices == NULL) {
return -1;
}
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);
vertices->xyz2 = vertex_to_XYZ2(data->gsGlobal, xy_[0] * scale_x, xy_[1] * scale_y, 0);
vertices->rgbaq = color_to_RGBAQ(col_.r >> 1, col_.g >> 1, col_.b >> 1, col_.a >> 1, 0.0f);
vertices++;
}
}
return 0;
}
static int PS2_RenderSetViewPort(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
{
PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata;
const SDL_Rect *viewport = &cmd->data.viewport.rect;
gsKit_set_display_offset(data->gsGlobal, viewport->x, viewport->y);
gsKit_set_scissor(data->gsGlobal, GS_SETREG_SCISSOR(viewport->x, viewport->y, viewport->w, viewport->h));
return 0;
}
static int PS2_RenderSetClipRect(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
{
PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata;
const SDL_Rect *rect = &cmd->data.cliprect.rect;
if (cmd->data.cliprect.enabled) {
gsKit_set_scissor(data->gsGlobal, GS_SETREG_SCISSOR(rect->x, rect->y, rect->w, rect->h));
} else {
gsKit_set_scissor(data->gsGlobal, GS_SCISSOR_RESET);
}
return 0;
}
static int PS2_RenderSetDrawColor(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
{
int colorR, colorG, colorB, colorA;
PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata;
colorR = (cmd->data.color.r) >> 1;
colorG = (cmd->data.color.g) >> 1;
colorB = (cmd->data.color.b) >> 1;
colorA = (cmd->data.color.a) >> 1;
data->drawColor = GS_SETREG_RGBAQ(colorR, colorG, colorB, colorA, 0x00);
return 0;
}
static int PS2_RenderClear(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
{
int colorR, colorG, colorB, colorA;
PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata;
colorR = (cmd->data.color.r) >> 1;
colorG = (cmd->data.color.g) >> 1;
colorB = (cmd->data.color.b) >> 1;
colorA = (cmd->data.color.a) >> 1;
gsKit_clear(data->gsGlobal, GS_SETREG_RGBAQ(colorR, colorG, colorB, colorA, 0x00));
return 0;
}
static void PS2_SetBlendMode(PS2_RenderData *data, int blendMode)
{
#define A_COLOR_SOURCE 0
#define A_COLOR_DEST 1
#define A_COLOR_NULL 2
#define A_ALPHA_SOURCE 0
#define A_ALPHA_DEST 1
#define A_ALPHA_FIX 2
switch (blendMode) {
case SDL_BLENDMODE_NONE:
{
data->gsGlobal->PrimAlphaEnable = GS_SETTING_OFF;
break;
}
case SDL_BLENDMODE_BLEND:
{
gsKit_set_primalpha(data->gsGlobal, GS_SETREG_ALPHA(A_COLOR_SOURCE, A_COLOR_DEST, A_ALPHA_SOURCE, A_COLOR_DEST, 0), 0);
data->gsGlobal->PrimAlphaEnable = GS_SETTING_ON;
break;
}
case SDL_BLENDMODE_ADD:
{
gsKit_set_primalpha(data->gsGlobal, GS_SETREG_ALPHA(A_COLOR_SOURCE, A_COLOR_NULL, A_ALPHA_FIX, A_COLOR_DEST, 0x80), 0);
data->gsGlobal->PrimAlphaEnable = GS_SETTING_ON;
break;
}
case SDL_BLENDMODE_MUL:
case SDL_BLENDMODE_MOD:
{
/* We don't fully support MOD and MUL, however this is the best we can do */
gsKit_set_primalpha(data->gsGlobal, GS_SETREG_ALPHA(A_COLOR_DEST, A_COLOR_NULL, A_ALPHA_SOURCE, A_COLOR_SOURCE, 0x80), 0);
data->gsGlobal->PrimAlphaEnable = GS_SETTING_ON;
break;
}
}
}
static int PS2_RenderGeometry(SDL_Renderer *renderer, void *vertices, SDL_RenderCommand *cmd)
{
PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata;
const size_t count = cmd->data.draw.count;
PS2_SetBlendMode(data, cmd->data.draw.blend);
if (cmd->data.draw.texture) {
const GSPRIMUVPOINT *verts = (GSPRIMUVPOINT *) (vertices + cmd->data.draw.first);
GSTEXTURE *ps2_tex = (GSTEXTURE *)cmd->data.draw.texture->driverdata;
gsKit_TexManager_bind(data->gsGlobal, ps2_tex);
gsKit_prim_list_triangle_goraud_texture_uv_3d(data->gsGlobal, ps2_tex, count, verts);
} else {
const GSPRIMPOINT *verts = (GSPRIMPOINT *)(vertices + cmd->data.draw.first);
gsKit_prim_list_triangle_gouraud_3d(data->gsGlobal, count, verts);
}
return 0;
}
int PS2_RenderLines(SDL_Renderer *renderer, void *vertices, SDL_RenderCommand *cmd)
{
PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata;
const size_t count = cmd->data.draw.count;
const GSPRIMPOINT *verts = (GSPRIMPOINT *)(vertices + cmd->data.draw.first);
PS2_SetBlendMode(data, cmd->data.draw.blend);
gsKit_prim_list_line_goraud_3d(data->gsGlobal, count, verts);
/* We're done! */
return 0;
}
int PS2_RenderPoints(SDL_Renderer *renderer, void *vertices, SDL_RenderCommand *cmd)
{
PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata;
const size_t count = cmd->data.draw.count;
const GSPRIMPOINT *verts = (GSPRIMPOINT *)(vertices + cmd->data.draw.first);
PS2_SetBlendMode(data, cmd->data.draw.blend);
gsKit_prim_list_points(data->gsGlobal, count, verts);
/* We're done! */
return 0;
}
static int PS2_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
{
while (cmd) {
switch (cmd->command) {
case SDL_RENDERCMD_SETVIEWPORT:
{
PS2_RenderSetViewPort(renderer, cmd);
break;
}
case SDL_RENDERCMD_SETCLIPRECT:
{
PS2_RenderSetClipRect(renderer, cmd);
break;
}
case SDL_RENDERCMD_SETDRAWCOLOR:
{
PS2_RenderSetDrawColor(renderer, cmd);
break;
}
case SDL_RENDERCMD_CLEAR:
{
PS2_RenderClear(renderer, cmd);
break;
}
case SDL_RENDERCMD_DRAW_POINTS:
{
PS2_RenderPoints(renderer, vertices, cmd);
break;
}
case SDL_RENDERCMD_DRAW_LINES:
{
PS2_RenderLines(renderer, vertices, cmd);
break;
}
case SDL_RENDERCMD_FILL_RECTS: /* unused */
break;
case SDL_RENDERCMD_COPY: /* unused */
break;
case SDL_RENDERCMD_COPY_EX: /* unused */
break;
case SDL_RENDERCMD_GEOMETRY:
{
PS2_RenderGeometry(renderer, vertices, cmd);
break;
}
case SDL_RENDERCMD_NO_OP:
break;
}
cmd = cmd->next;
}
return 0;
}
static int PS2_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect,
Uint32 format, void *pixels, int pitch)
{
return SDL_Unsupported();
}
static int PS2_RenderPresent(SDL_Renderer *renderer)
{
PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata;
if (data->gsGlobal->DoubleBuffering == GS_SETTING_OFF) {
if (data->vsync == 2) { // Dynamic
gsKit_sync(data->gsGlobal);
} else if (data->vsync == 1) {
gsKit_vsync_wait();
}
gsKit_queue_exec(data->gsGlobal);
} else {
gsKit_queue_exec(data->gsGlobal);
gsKit_finish();
if (data->vsync == 2) { // Dynamic
gsKit_sync(data->gsGlobal);
} else if (data->vsync == 1) {
gsKit_vsync_wait();
}
gsKit_flip(data->gsGlobal);
}
gsKit_TexManager_nextFrame(data->gsGlobal);
gsKit_clear(data->gsGlobal, GS_BLACK);
return 0;
}
static void PS2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture)
{
GSTEXTURE *ps2_texture = (GSTEXTURE *)texture->driverdata;
PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata;
if (data == NULL) {
return;
}
if (ps2_texture == NULL) {
return;
}
// Free from vram
gsKit_TexManager_free(data->gsGlobal, ps2_texture);
SDL_aligned_free(ps2_texture->Mem);
SDL_free(ps2_texture);
texture->driverdata = NULL;
}
static void PS2_DestroyRenderer(SDL_Renderer *renderer)
{
PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata;
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);
}
static int PS2_SetVSync(SDL_Renderer *renderer, const int vsync)
{
PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata;
SDL_bool dynamicVsync = SDL_GetHintBoolean(SDL_HINT_PS2_DYNAMIC_VSYNC, SDL_FALSE);
data->vsync = vsync ? (dynamicVsync ? 2 : 1) : 0;
return 0;
}
static SDL_Renderer *PS2_CreateRenderer(SDL_Window *window, Uint32 flags)
{
SDL_Renderer *renderer;
PS2_RenderData *data;
GSGLOBAL *gsGlobal;
ee_sema_t sema;
SDL_bool dynamicVsync;
renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(*renderer));
if (renderer == NULL) {
SDL_OutOfMemory();
return NULL;
}
data = (PS2_RenderData *)SDL_calloc(1, sizeof(*data));
if (data == NULL) {
PS2_DestroyRenderer(renderer);
SDL_OutOfMemory();
return NULL;
}
/* Specific gsKit init */
sema.init_count = 0;
sema.max_count = 1;
sema.option = 0;
vsync_sema_id = CreateSema(&sema);
gsGlobal = gsKit_init_global_custom(RENDER_QUEUE_OS_POOLSIZE, RENDER_QUEUE_PER_POOLSIZE);
gsGlobal->Mode = GS_MODE_NTSC;
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);
gsKit_set_clamp(gsGlobal, GS_CMODE_REPEAT);
gsKit_vram_clear(gsGlobal);
gsKit_init_screen(gsGlobal);
gsKit_TexManager_init(gsGlobal);
data->vsync_callback_id = gsKit_add_vsync_handler(vsync_handler);
gsKit_mode_switch(gsGlobal, GS_ONESHOT);
gsKit_clear(gsGlobal, GS_BLACK);
data->gsGlobal = gsGlobal;
dynamicVsync = SDL_GetHintBoolean(SDL_HINT_PS2_DYNAMIC_VSYNC, SDL_FALSE);
data->vsync = flags & SDL_RENDERER_PRESENTVSYNC ? (dynamicVsync ? 2 : 1) : 0;
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;
renderer->QueueDrawPoints = PS2_QueueDrawPoints;
renderer->QueueDrawLines = PS2_QueueDrawPoints;
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;
return renderer;
}
SDL_RenderDriver PS2_RenderDriver = {
.CreateRenderer = PS2_CreateRenderer,
.info = {
.name = "PS2 gsKit",
.flags = (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC),
.num_texture_formats = 2,
.texture_formats = {
[0] = SDL_PIXELFORMAT_ABGR1555,
[1] = SDL_PIXELFORMAT_ABGR8888,
},
.max_texture_width = 1024,
.max_texture_height = 1024,
}
};
#endif /* SDL_VIDEO_RENDER_PS2 */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,346 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#if SDL_VIDEO_RENDER_SW && !defined(SDL_RENDER_DISABLED)
#include "SDL_draw.h"
#include "SDL_blendfillrect.h"
static int SDL_BlendFillRect_RGB555(SDL_Surface *dst, const SDL_Rect *rect,
SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
unsigned inva = 0xff - a;
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB555);
break;
case SDL_BLENDMODE_ADD:
FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB555);
break;
case SDL_BLENDMODE_MOD:
FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB555);
break;
case SDL_BLENDMODE_MUL:
FILLRECT(Uint16, DRAW_SETPIXEL_MUL_RGB555);
break;
default:
FILLRECT(Uint16, DRAW_SETPIXEL_RGB555);
break;
}
return 0;
}
static int SDL_BlendFillRect_RGB565(SDL_Surface *dst, const SDL_Rect *rect,
SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
unsigned inva = 0xff - a;
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB565);
break;
case SDL_BLENDMODE_ADD:
FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB565);
break;
case SDL_BLENDMODE_MOD:
FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB565);
break;
case SDL_BLENDMODE_MUL:
FILLRECT(Uint16, DRAW_SETPIXEL_MUL_RGB565);
break;
default:
FILLRECT(Uint16, DRAW_SETPIXEL_RGB565);
break;
}
return 0;
}
static int SDL_BlendFillRect_XRGB8888(SDL_Surface *dst, const SDL_Rect *rect,
SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
unsigned inva = 0xff - a;
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_XRGB8888);
break;
case SDL_BLENDMODE_ADD:
FILLRECT(Uint32, DRAW_SETPIXEL_ADD_XRGB8888);
break;
case SDL_BLENDMODE_MOD:
FILLRECT(Uint32, DRAW_SETPIXEL_MOD_XRGB8888);
break;
case SDL_BLENDMODE_MUL:
FILLRECT(Uint32, DRAW_SETPIXEL_MUL_XRGB8888);
break;
default:
FILLRECT(Uint32, DRAW_SETPIXEL_XRGB8888);
break;
}
return 0;
}
static int SDL_BlendFillRect_ARGB8888(SDL_Surface *dst, const SDL_Rect *rect,
SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
unsigned inva = 0xff - a;
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888);
break;
case SDL_BLENDMODE_ADD:
FILLRECT(Uint32, DRAW_SETPIXEL_ADD_ARGB8888);
break;
case SDL_BLENDMODE_MOD:
FILLRECT(Uint32, DRAW_SETPIXEL_MOD_ARGB8888);
break;
case SDL_BLENDMODE_MUL:
FILLRECT(Uint32, DRAW_SETPIXEL_MUL_ARGB8888);
break;
default:
FILLRECT(Uint32, DRAW_SETPIXEL_ARGB8888);
break;
}
return 0;
}
static int SDL_BlendFillRect_RGB(SDL_Surface *dst, const SDL_Rect *rect,
SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
SDL_PixelFormat *fmt = dst->format;
unsigned inva = 0xff - a;
switch (fmt->BytesPerPixel) {
case 2:
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
FILLRECT(Uint16, DRAW_SETPIXEL_BLEND_RGB);
break;
case SDL_BLENDMODE_ADD:
FILLRECT(Uint16, DRAW_SETPIXEL_ADD_RGB);
break;
case SDL_BLENDMODE_MOD:
FILLRECT(Uint16, DRAW_SETPIXEL_MOD_RGB);
break;
case SDL_BLENDMODE_MUL:
FILLRECT(Uint16, DRAW_SETPIXEL_MUL_RGB);
break;
default:
FILLRECT(Uint16, DRAW_SETPIXEL_RGB);
break;
}
return 0;
case 4:
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGB);
break;
case SDL_BLENDMODE_ADD:
FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGB);
break;
case SDL_BLENDMODE_MOD:
FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGB);
break;
case SDL_BLENDMODE_MUL:
FILLRECT(Uint32, DRAW_SETPIXEL_MUL_RGB);
break;
default:
FILLRECT(Uint32, DRAW_SETPIXEL_RGB);
break;
}
return 0;
default:
return SDL_Unsupported();
}
}
static int SDL_BlendFillRect_RGBA(SDL_Surface *dst, const SDL_Rect *rect,
SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
SDL_PixelFormat *fmt = dst->format;
unsigned inva = 0xff - a;
switch (fmt->BytesPerPixel) {
case 4:
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
FILLRECT(Uint32, DRAW_SETPIXEL_BLEND_RGBA);
break;
case SDL_BLENDMODE_ADD:
FILLRECT(Uint32, DRAW_SETPIXEL_ADD_RGBA);
break;
case SDL_BLENDMODE_MOD:
FILLRECT(Uint32, DRAW_SETPIXEL_MOD_RGBA);
break;
case SDL_BLENDMODE_MUL:
FILLRECT(Uint32, DRAW_SETPIXEL_MUL_RGBA);
break;
default:
FILLRECT(Uint32, DRAW_SETPIXEL_RGBA);
break;
}
return 0;
default:
return SDL_Unsupported();
}
}
int SDL_BlendFillRect(SDL_Surface *dst, const SDL_Rect *rect,
SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
SDL_Rect clipped;
if (dst == NULL) {
return SDL_InvalidParamError("SDL_BlendFillRect(): dst");
}
/* This function doesn't work on surfaces < 8 bpp */
if (dst->format->BitsPerPixel < 8) {
return SDL_SetError("SDL_BlendFillRect(): Unsupported surface format");
}
/* If 'rect' == NULL, then fill the whole surface */
if (rect) {
/* Perform clipping */
if (!SDL_GetRectIntersection(rect, &dst->clip_rect, &clipped)) {
return 0;
}
rect = &clipped;
} else {
rect = &dst->clip_rect;
}
if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
r = DRAW_MUL(r, a);
g = DRAW_MUL(g, a);
b = DRAW_MUL(b, a);
}
switch (dst->format->BitsPerPixel) {
case 15:
switch (dst->format->Rmask) {
case 0x7C00:
return SDL_BlendFillRect_RGB555(dst, rect, blendMode, r, g, b, a);
}
break;
case 16:
switch (dst->format->Rmask) {
case 0xF800:
return SDL_BlendFillRect_RGB565(dst, rect, blendMode, r, g, b, a);
}
break;
case 32:
switch (dst->format->Rmask) {
case 0x00FF0000:
if (!dst->format->Amask) {
return SDL_BlendFillRect_XRGB8888(dst, rect, blendMode, r, g, b, a);
} else {
return SDL_BlendFillRect_ARGB8888(dst, rect, blendMode, r, g, b, a);
}
/* break; -Wunreachable-code-break */
}
break;
default:
break;
}
if (!dst->format->Amask) {
return SDL_BlendFillRect_RGB(dst, rect, blendMode, r, g, b, a);
} else {
return SDL_BlendFillRect_RGBA(dst, rect, blendMode, r, g, b, a);
}
}
int SDL_BlendFillRects(SDL_Surface *dst, const SDL_Rect *rects, int count,
SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
SDL_Rect rect;
int i;
int (*func)(SDL_Surface * dst, const SDL_Rect *rect,
SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) = NULL;
int status = 0;
if (dst == NULL) {
return SDL_InvalidParamError("SDL_BlendFillRects(): dst");
}
/* This function doesn't work on surfaces < 8 bpp */
if (dst->format->BitsPerPixel < 8) {
return SDL_SetError("SDL_BlendFillRects(): Unsupported surface format");
}
if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
r = DRAW_MUL(r, a);
g = DRAW_MUL(g, a);
b = DRAW_MUL(b, a);
}
/* FIXME: Does this function pointer slow things down significantly? */
switch (dst->format->BitsPerPixel) {
case 15:
switch (dst->format->Rmask) {
case 0x7C00:
func = SDL_BlendFillRect_RGB555;
}
break;
case 16:
switch (dst->format->Rmask) {
case 0xF800:
func = SDL_BlendFillRect_RGB565;
}
break;
case 32:
switch (dst->format->Rmask) {
case 0x00FF0000:
if (!dst->format->Amask) {
func = SDL_BlendFillRect_XRGB8888;
} else {
func = SDL_BlendFillRect_ARGB8888;
}
break;
}
break;
default:
break;
}
if (func == NULL) {
if (!dst->format->Amask) {
func = SDL_BlendFillRect_RGB;
} else {
func = SDL_BlendFillRect_RGBA;
}
}
for (i = 0; i < count; ++i) {
/* Perform clipping */
if (!SDL_GetRectIntersection(&rects[i], &dst->clip_rect, &rect)) {
continue;
}
status = func(dst, &rect, blendMode, r, g, b, a);
}
return status;
}
#endif /* SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED */

View File

@ -0,0 +1,30 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_blendfillrect_h_
#define SDL_blendfillrect_h_
#include "SDL_internal.h"
extern int SDL_BlendFillRect(SDL_Surface *dst, const SDL_Rect *rect, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
extern int SDL_BlendFillRects(SDL_Surface *dst, const SDL_Rect *rects, int count, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
#endif /* SDL_blendfillrect_h_ */

View File

@ -0,0 +1,862 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#if SDL_VIDEO_RENDER_SW && !defined(SDL_RENDER_DISABLED)
#include "SDL_draw.h"
#include "SDL_blendline.h"
#include "SDL_blendpoint.h"
static void SDL_BlendLine_RGB2(SDL_Surface *dst, int x1, int y1, int x2, int y2,
SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
SDL_bool draw_end)
{
const SDL_PixelFormat *fmt = dst->format;
unsigned r, g, b, a, inva;
if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
r = DRAW_MUL(_r, _a);
g = DRAW_MUL(_g, _a);
b = DRAW_MUL(_b, _a);
a = _a;
} else {
r = _r;
g = _g;
b = _b;
a = _a;
}
inva = (a ^ 0xff);
if (y1 == y2) {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
HLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB, draw_end);
break;
case SDL_BLENDMODE_ADD:
HLINE(Uint16, DRAW_SETPIXEL_ADD_RGB, draw_end);
break;
case SDL_BLENDMODE_MOD:
HLINE(Uint16, DRAW_SETPIXEL_MOD_RGB, draw_end);
break;
case SDL_BLENDMODE_MUL:
HLINE(Uint16, DRAW_SETPIXEL_MUL_RGB, draw_end);
break;
default:
HLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end);
break;
}
} else if (x1 == x2) {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
VLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB, draw_end);
break;
case SDL_BLENDMODE_ADD:
VLINE(Uint16, DRAW_SETPIXEL_ADD_RGB, draw_end);
break;
case SDL_BLENDMODE_MOD:
VLINE(Uint16, DRAW_SETPIXEL_MOD_RGB, draw_end);
break;
case SDL_BLENDMODE_MUL:
VLINE(Uint16, DRAW_SETPIXEL_MUL_RGB, draw_end);
break;
default:
VLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end);
break;
}
} else if (ABS(x1 - x2) == ABS(y1 - y2)) {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
DLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB, draw_end);
break;
case SDL_BLENDMODE_ADD:
DLINE(Uint16, DRAW_SETPIXEL_ADD_RGB, draw_end);
break;
case SDL_BLENDMODE_MOD:
DLINE(Uint16, DRAW_SETPIXEL_MOD_RGB, draw_end);
break;
case SDL_BLENDMODE_MUL:
DLINE(Uint16, DRAW_SETPIXEL_MUL_RGB, draw_end);
break;
default:
DLINE(Uint16, DRAW_SETPIXEL_RGB, draw_end);
break;
}
} else {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY2_BLEND_RGB, DRAW_SETPIXELXY2_BLEND_RGB,
draw_end);
break;
case SDL_BLENDMODE_ADD:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY2_ADD_RGB, DRAW_SETPIXELXY2_ADD_RGB,
draw_end);
break;
case SDL_BLENDMODE_MOD:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY2_MOD_RGB, DRAW_SETPIXELXY2_MOD_RGB,
draw_end);
break;
case SDL_BLENDMODE_MUL:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY2_MUL_RGB, DRAW_SETPIXELXY2_MUL_RGB,
draw_end);
break;
default:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY2_RGB, DRAW_SETPIXELXY2_BLEND_RGB,
draw_end);
break;
}
}
}
static void SDL_BlendLine_RGB555(SDL_Surface *dst, int x1, int y1, int x2, int y2,
SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
SDL_bool draw_end)
{
unsigned r, g, b, a, inva;
if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
r = DRAW_MUL(_r, _a);
g = DRAW_MUL(_g, _a);
b = DRAW_MUL(_b, _a);
a = _a;
} else {
r = _r;
g = _g;
b = _b;
a = _a;
}
inva = (a ^ 0xff);
if (y1 == y2) {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
HLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB555, draw_end);
break;
case SDL_BLENDMODE_ADD:
HLINE(Uint16, DRAW_SETPIXEL_ADD_RGB555, draw_end);
break;
case SDL_BLENDMODE_MOD:
HLINE(Uint16, DRAW_SETPIXEL_MOD_RGB555, draw_end);
break;
case SDL_BLENDMODE_MUL:
HLINE(Uint16, DRAW_SETPIXEL_MUL_RGB555, draw_end);
break;
default:
HLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end);
break;
}
} else if (x1 == x2) {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
VLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB555, draw_end);
break;
case SDL_BLENDMODE_ADD:
VLINE(Uint16, DRAW_SETPIXEL_ADD_RGB555, draw_end);
break;
case SDL_BLENDMODE_MOD:
VLINE(Uint16, DRAW_SETPIXEL_MOD_RGB555, draw_end);
break;
case SDL_BLENDMODE_MUL:
VLINE(Uint16, DRAW_SETPIXEL_MUL_RGB555, draw_end);
break;
default:
VLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end);
break;
}
} else if (ABS(x1 - x2) == ABS(y1 - y2)) {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
DLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB555, draw_end);
break;
case SDL_BLENDMODE_ADD:
DLINE(Uint16, DRAW_SETPIXEL_ADD_RGB555, draw_end);
break;
case SDL_BLENDMODE_MOD:
DLINE(Uint16, DRAW_SETPIXEL_MOD_RGB555, draw_end);
break;
case SDL_BLENDMODE_MUL:
DLINE(Uint16, DRAW_SETPIXEL_MUL_RGB555, draw_end);
break;
default:
DLINE(Uint16, DRAW_SETPIXEL_RGB555, draw_end);
break;
}
} else {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_BLEND_RGB555, DRAW_SETPIXELXY_BLEND_RGB555,
draw_end);
break;
case SDL_BLENDMODE_ADD:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_ADD_RGB555, DRAW_SETPIXELXY_ADD_RGB555,
draw_end);
break;
case SDL_BLENDMODE_MOD:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_MOD_RGB555, DRAW_SETPIXELXY_MOD_RGB555,
draw_end);
break;
case SDL_BLENDMODE_MUL:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_MUL_RGB555, DRAW_SETPIXELXY_MUL_RGB555,
draw_end);
break;
default:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_RGB555, DRAW_SETPIXELXY_BLEND_RGB555,
draw_end);
break;
}
}
}
static void SDL_BlendLine_RGB565(SDL_Surface *dst, int x1, int y1, int x2, int y2,
SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
SDL_bool draw_end)
{
unsigned r, g, b, a, inva;
if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
r = DRAW_MUL(_r, _a);
g = DRAW_MUL(_g, _a);
b = DRAW_MUL(_b, _a);
a = _a;
} else {
r = _r;
g = _g;
b = _b;
a = _a;
}
inva = (a ^ 0xff);
if (y1 == y2) {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
HLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB565, draw_end);
break;
case SDL_BLENDMODE_ADD:
HLINE(Uint16, DRAW_SETPIXEL_ADD_RGB565, draw_end);
break;
case SDL_BLENDMODE_MOD:
HLINE(Uint16, DRAW_SETPIXEL_MOD_RGB565, draw_end);
break;
case SDL_BLENDMODE_MUL:
HLINE(Uint16, DRAW_SETPIXEL_MUL_RGB565, draw_end);
break;
default:
HLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end);
break;
}
} else if (x1 == x2) {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
VLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB565, draw_end);
break;
case SDL_BLENDMODE_ADD:
VLINE(Uint16, DRAW_SETPIXEL_ADD_RGB565, draw_end);
break;
case SDL_BLENDMODE_MOD:
VLINE(Uint16, DRAW_SETPIXEL_MOD_RGB565, draw_end);
break;
case SDL_BLENDMODE_MUL:
VLINE(Uint16, DRAW_SETPIXEL_MUL_RGB565, draw_end);
break;
default:
VLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end);
break;
}
} else if (ABS(x1 - x2) == ABS(y1 - y2)) {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
DLINE(Uint16, DRAW_SETPIXEL_BLEND_RGB565, draw_end);
break;
case SDL_BLENDMODE_ADD:
DLINE(Uint16, DRAW_SETPIXEL_ADD_RGB565, draw_end);
break;
case SDL_BLENDMODE_MOD:
DLINE(Uint16, DRAW_SETPIXEL_MOD_RGB565, draw_end);
break;
case SDL_BLENDMODE_MUL:
DLINE(Uint16, DRAW_SETPIXEL_MUL_RGB565, draw_end);
break;
default:
DLINE(Uint16, DRAW_SETPIXEL_RGB565, draw_end);
break;
}
} else {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_BLEND_RGB565, DRAW_SETPIXELXY_BLEND_RGB565,
draw_end);
break;
case SDL_BLENDMODE_ADD:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_ADD_RGB565, DRAW_SETPIXELXY_ADD_RGB565,
draw_end);
break;
case SDL_BLENDMODE_MOD:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_MOD_RGB565, DRAW_SETPIXELXY_MOD_RGB565,
draw_end);
break;
case SDL_BLENDMODE_MUL:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_MUL_RGB565, DRAW_SETPIXELXY_MUL_RGB565,
draw_end);
break;
default:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_RGB565, DRAW_SETPIXELXY_BLEND_RGB565,
draw_end);
break;
}
}
}
static void SDL_BlendLine_RGB4(SDL_Surface *dst, int x1, int y1, int x2, int y2,
SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
SDL_bool draw_end)
{
const SDL_PixelFormat *fmt = dst->format;
unsigned r, g, b, a, inva;
if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
r = DRAW_MUL(_r, _a);
g = DRAW_MUL(_g, _a);
b = DRAW_MUL(_b, _a);
a = _a;
} else {
r = _r;
g = _g;
b = _b;
a = _a;
}
inva = (a ^ 0xff);
if (y1 == y2) {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
HLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB, draw_end);
break;
case SDL_BLENDMODE_ADD:
HLINE(Uint32, DRAW_SETPIXEL_ADD_RGB, draw_end);
break;
case SDL_BLENDMODE_MOD:
HLINE(Uint32, DRAW_SETPIXEL_MOD_RGB, draw_end);
break;
case SDL_BLENDMODE_MUL:
HLINE(Uint32, DRAW_SETPIXEL_MUL_RGB, draw_end);
break;
default:
HLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end);
break;
}
} else if (x1 == x2) {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
VLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB, draw_end);
break;
case SDL_BLENDMODE_ADD:
VLINE(Uint32, DRAW_SETPIXEL_ADD_RGB, draw_end);
break;
case SDL_BLENDMODE_MOD:
VLINE(Uint32, DRAW_SETPIXEL_MOD_RGB, draw_end);
break;
case SDL_BLENDMODE_MUL:
VLINE(Uint32, DRAW_SETPIXEL_MUL_RGB, draw_end);
break;
default:
VLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end);
break;
}
} else if (ABS(x1 - x2) == ABS(y1 - y2)) {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
DLINE(Uint32, DRAW_SETPIXEL_BLEND_RGB, draw_end);
break;
case SDL_BLENDMODE_ADD:
DLINE(Uint32, DRAW_SETPIXEL_ADD_RGB, draw_end);
break;
case SDL_BLENDMODE_MOD:
DLINE(Uint32, DRAW_SETPIXEL_MOD_RGB, draw_end);
break;
case SDL_BLENDMODE_MUL:
DLINE(Uint32, DRAW_SETPIXEL_MUL_RGB, draw_end);
break;
default:
DLINE(Uint32, DRAW_SETPIXEL_RGB, draw_end);
break;
}
} else {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY4_BLEND_RGB, DRAW_SETPIXELXY4_BLEND_RGB,
draw_end);
break;
case SDL_BLENDMODE_ADD:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY4_ADD_RGB, DRAW_SETPIXELXY4_ADD_RGB,
draw_end);
break;
case SDL_BLENDMODE_MOD:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY4_MOD_RGB, DRAW_SETPIXELXY4_MOD_RGB,
draw_end);
break;
case SDL_BLENDMODE_MUL:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY4_MUL_RGB, DRAW_SETPIXELXY4_MUL_RGB,
draw_end);
break;
default:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY4_RGB, DRAW_SETPIXELXY4_BLEND_RGB,
draw_end);
break;
}
}
}
static void SDL_BlendLine_RGBA4(SDL_Surface *dst, int x1, int y1, int x2, int y2,
SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
SDL_bool draw_end)
{
const SDL_PixelFormat *fmt = dst->format;
unsigned r, g, b, a, inva;
if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
r = DRAW_MUL(_r, _a);
g = DRAW_MUL(_g, _a);
b = DRAW_MUL(_b, _a);
a = _a;
} else {
r = _r;
g = _g;
b = _b;
a = _a;
}
inva = (a ^ 0xff);
if (y1 == y2) {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
HLINE(Uint32, DRAW_SETPIXEL_BLEND_RGBA, draw_end);
break;
case SDL_BLENDMODE_ADD:
HLINE(Uint32, DRAW_SETPIXEL_ADD_RGBA, draw_end);
break;
case SDL_BLENDMODE_MOD:
HLINE(Uint32, DRAW_SETPIXEL_MOD_RGBA, draw_end);
break;
case SDL_BLENDMODE_MUL:
HLINE(Uint32, DRAW_SETPIXEL_MUL_RGBA, draw_end);
break;
default:
HLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end);
break;
}
} else if (x1 == x2) {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
VLINE(Uint32, DRAW_SETPIXEL_BLEND_RGBA, draw_end);
break;
case SDL_BLENDMODE_ADD:
VLINE(Uint32, DRAW_SETPIXEL_ADD_RGBA, draw_end);
break;
case SDL_BLENDMODE_MOD:
VLINE(Uint32, DRAW_SETPIXEL_MOD_RGBA, draw_end);
break;
case SDL_BLENDMODE_MUL:
VLINE(Uint32, DRAW_SETPIXEL_MUL_RGBA, draw_end);
break;
default:
VLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end);
break;
}
} else if (ABS(x1 - x2) == ABS(y1 - y2)) {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
DLINE(Uint32, DRAW_SETPIXEL_BLEND_RGBA, draw_end);
break;
case SDL_BLENDMODE_ADD:
DLINE(Uint32, DRAW_SETPIXEL_ADD_RGBA, draw_end);
break;
case SDL_BLENDMODE_MOD:
DLINE(Uint32, DRAW_SETPIXEL_MOD_RGBA, draw_end);
break;
case SDL_BLENDMODE_MUL:
DLINE(Uint32, DRAW_SETPIXEL_MUL_RGBA, draw_end);
break;
default:
DLINE(Uint32, DRAW_SETPIXEL_RGBA, draw_end);
break;
}
} else {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY4_BLEND_RGBA, DRAW_SETPIXELXY4_BLEND_RGBA,
draw_end);
break;
case SDL_BLENDMODE_ADD:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY4_ADD_RGBA, DRAW_SETPIXELXY4_ADD_RGBA,
draw_end);
break;
case SDL_BLENDMODE_MOD:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY4_MOD_RGBA, DRAW_SETPIXELXY4_MOD_RGBA,
draw_end);
break;
case SDL_BLENDMODE_MUL:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY4_MUL_RGBA, DRAW_SETPIXELXY4_MUL_RGBA,
draw_end);
break;
default:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY4_RGBA, DRAW_SETPIXELXY4_BLEND_RGBA,
draw_end);
break;
}
}
}
static void SDL_BlendLine_XRGB8888(SDL_Surface *dst, int x1, int y1, int x2, int y2,
SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
SDL_bool draw_end)
{
unsigned r, g, b, a, inva;
if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
r = DRAW_MUL(_r, _a);
g = DRAW_MUL(_g, _a);
b = DRAW_MUL(_b, _a);
a = _a;
} else {
r = _r;
g = _g;
b = _b;
a = _a;
}
inva = (a ^ 0xff);
if (y1 == y2) {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
HLINE(Uint32, DRAW_SETPIXEL_BLEND_XRGB8888, draw_end);
break;
case SDL_BLENDMODE_ADD:
HLINE(Uint32, DRAW_SETPIXEL_ADD_XRGB8888, draw_end);
break;
case SDL_BLENDMODE_MOD:
HLINE(Uint32, DRAW_SETPIXEL_MOD_XRGB8888, draw_end);
break;
case SDL_BLENDMODE_MUL:
HLINE(Uint32, DRAW_SETPIXEL_MUL_XRGB8888, draw_end);
break;
default:
HLINE(Uint32, DRAW_SETPIXEL_XRGB8888, draw_end);
break;
}
} else if (x1 == x2) {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
VLINE(Uint32, DRAW_SETPIXEL_BLEND_XRGB8888, draw_end);
break;
case SDL_BLENDMODE_ADD:
VLINE(Uint32, DRAW_SETPIXEL_ADD_XRGB8888, draw_end);
break;
case SDL_BLENDMODE_MOD:
VLINE(Uint32, DRAW_SETPIXEL_MOD_XRGB8888, draw_end);
break;
case SDL_BLENDMODE_MUL:
VLINE(Uint32, DRAW_SETPIXEL_MUL_XRGB8888, draw_end);
break;
default:
VLINE(Uint32, DRAW_SETPIXEL_XRGB8888, draw_end);
break;
}
} else if (ABS(x1 - x2) == ABS(y1 - y2)) {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
DLINE(Uint32, DRAW_SETPIXEL_BLEND_XRGB8888, draw_end);
break;
case SDL_BLENDMODE_ADD:
DLINE(Uint32, DRAW_SETPIXEL_ADD_XRGB8888, draw_end);
break;
case SDL_BLENDMODE_MOD:
DLINE(Uint32, DRAW_SETPIXEL_MOD_XRGB8888, draw_end);
break;
case SDL_BLENDMODE_MUL:
DLINE(Uint32, DRAW_SETPIXEL_MUL_XRGB8888, draw_end);
break;
default:
DLINE(Uint32, DRAW_SETPIXEL_XRGB8888, draw_end);
break;
}
} else {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_BLEND_XRGB8888, DRAW_SETPIXELXY_BLEND_XRGB8888,
draw_end);
break;
case SDL_BLENDMODE_ADD:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_ADD_XRGB8888, DRAW_SETPIXELXY_ADD_XRGB8888,
draw_end);
break;
case SDL_BLENDMODE_MOD:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_MOD_XRGB8888, DRAW_SETPIXELXY_MOD_XRGB8888,
draw_end);
break;
case SDL_BLENDMODE_MUL:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_MUL_XRGB8888, DRAW_SETPIXELXY_MUL_XRGB8888,
draw_end);
break;
default:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_XRGB8888, DRAW_SETPIXELXY_BLEND_XRGB8888,
draw_end);
break;
}
}
}
static void SDL_BlendLine_ARGB8888(SDL_Surface *dst, int x1, int y1, int x2, int y2,
SDL_BlendMode blendMode, Uint8 _r, Uint8 _g, Uint8 _b, Uint8 _a,
SDL_bool draw_end)
{
unsigned r, g, b, a, inva;
if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
r = DRAW_MUL(_r, _a);
g = DRAW_MUL(_g, _a);
b = DRAW_MUL(_b, _a);
a = _a;
} else {
r = _r;
g = _g;
b = _b;
a = _a;
}
inva = (a ^ 0xff);
if (y1 == y2) {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
HLINE(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end);
break;
case SDL_BLENDMODE_ADD:
HLINE(Uint32, DRAW_SETPIXEL_ADD_ARGB8888, draw_end);
break;
case SDL_BLENDMODE_MOD:
HLINE(Uint32, DRAW_SETPIXEL_MOD_ARGB8888, draw_end);
break;
case SDL_BLENDMODE_MUL:
HLINE(Uint32, DRAW_SETPIXEL_MUL_ARGB8888, draw_end);
break;
default:
HLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end);
break;
}
} else if (x1 == x2) {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
VLINE(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end);
break;
case SDL_BLENDMODE_ADD:
VLINE(Uint32, DRAW_SETPIXEL_ADD_ARGB8888, draw_end);
break;
case SDL_BLENDMODE_MOD:
VLINE(Uint32, DRAW_SETPIXEL_MOD_ARGB8888, draw_end);
break;
case SDL_BLENDMODE_MUL:
VLINE(Uint32, DRAW_SETPIXEL_MUL_ARGB8888, draw_end);
break;
default:
VLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end);
break;
}
} else if (ABS(x1 - x2) == ABS(y1 - y2)) {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
DLINE(Uint32, DRAW_SETPIXEL_BLEND_ARGB8888, draw_end);
break;
case SDL_BLENDMODE_ADD:
DLINE(Uint32, DRAW_SETPIXEL_ADD_ARGB8888, draw_end);
break;
case SDL_BLENDMODE_MOD:
DLINE(Uint32, DRAW_SETPIXEL_MOD_ARGB8888, draw_end);
break;
case SDL_BLENDMODE_MUL:
DLINE(Uint32, DRAW_SETPIXEL_MUL_ARGB8888, draw_end);
break;
default:
DLINE(Uint32, DRAW_SETPIXEL_ARGB8888, draw_end);
break;
}
} else {
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_BLEND_ARGB8888, DRAW_SETPIXELXY_BLEND_ARGB8888,
draw_end);
break;
case SDL_BLENDMODE_ADD:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_ADD_ARGB8888, DRAW_SETPIXELXY_ADD_ARGB8888,
draw_end);
break;
case SDL_BLENDMODE_MOD:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_MOD_ARGB8888, DRAW_SETPIXELXY_MOD_ARGB8888,
draw_end);
break;
case SDL_BLENDMODE_MUL:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_MUL_ARGB8888, DRAW_SETPIXELXY_MUL_ARGB8888,
draw_end);
break;
default:
AALINE(x1, y1, x2, y2,
DRAW_SETPIXELXY_ARGB8888, DRAW_SETPIXELXY_BLEND_ARGB8888,
draw_end);
break;
}
}
}
typedef void (*BlendLineFunc)(SDL_Surface *dst,
int x1, int y1, int x2, int y2,
SDL_BlendMode blendMode,
Uint8 r, Uint8 g, Uint8 b, Uint8 a,
SDL_bool draw_end);
static BlendLineFunc SDL_CalculateBlendLineFunc(const SDL_PixelFormat *fmt)
{
switch (fmt->BytesPerPixel) {
case 2:
if (fmt->Rmask == 0x7C00) {
return SDL_BlendLine_RGB555;
} else if (fmt->Rmask == 0xF800) {
return SDL_BlendLine_RGB565;
} else {
return SDL_BlendLine_RGB2;
}
/* break; -Wunreachable-code-break */
case 4:
if (fmt->Rmask == 0x00FF0000) {
if (fmt->Amask) {
return SDL_BlendLine_ARGB8888;
} else {
return SDL_BlendLine_XRGB8888;
}
} else {
if (fmt->Amask) {
return SDL_BlendLine_RGBA4;
} else {
return SDL_BlendLine_RGB4;
}
}
}
return NULL;
}
int SDL_BlendLine(SDL_Surface *dst, int x1, int y1, int x2, int y2,
SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
BlendLineFunc func;
if (dst == NULL) {
return SDL_InvalidParamError("SDL_BlendLine(): dst");
}
func = SDL_CalculateBlendLineFunc(dst->format);
if (func == NULL) {
return SDL_SetError("SDL_BlendLine(): Unsupported surface format");
}
/* Perform clipping */
/* FIXME: We don't actually want to clip, as it may change line slope */
if (!SDL_GetRectAndLineIntersection(&dst->clip_rect, &x1, &y1, &x2, &y2)) {
return 0;
}
func(dst, x1, y1, x2, y2, blendMode, r, g, b, a, SDL_TRUE);
return 0;
}
int SDL_BlendLines(SDL_Surface *dst, const SDL_Point *points, int count,
SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
int i;
int x1, y1;
int x2, y2;
SDL_bool draw_end;
BlendLineFunc func;
if (dst == NULL) {
return SDL_SetError("SDL_BlendLines(): Passed NULL destination surface");
}
func = SDL_CalculateBlendLineFunc(dst->format);
if (func == NULL) {
return SDL_SetError("SDL_BlendLines(): Unsupported surface format");
}
for (i = 1; i < count; ++i) {
x1 = points[i - 1].x;
y1 = points[i - 1].y;
x2 = points[i].x;
y2 = points[i].y;
/* Perform clipping */
/* FIXME: We don't actually want to clip, as it may change line slope */
if (!SDL_GetRectAndLineIntersection(&dst->clip_rect, &x1, &y1, &x2, &y2)) {
continue;
}
/* Draw the end if it was clipped */
draw_end = (x2 != points[i].x || y2 != points[i].y);
func(dst, x1, y1, x2, y2, blendMode, r, g, b, a, draw_end);
}
if (points[0].x != points[count - 1].x || points[0].y != points[count - 1].y) {
SDL_BlendPoint(dst, points[count - 1].x, points[count - 1].y,
blendMode, r, g, b, a);
}
return 0;
}
#endif /* SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED */

View File

@ -0,0 +1,30 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_blendline_h_
#define SDL_blendline_h_
#include "SDL_internal.h"
extern int SDL_BlendLine(SDL_Surface *dst, int x1, int y1, int x2, int y2, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
extern int SDL_BlendLines(SDL_Surface *dst, const SDL_Point *points, int count, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
#endif /* SDL_blendline_h_ */

View File

@ -0,0 +1,351 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#if SDL_VIDEO_RENDER_SW && !defined(SDL_RENDER_DISABLED)
#include "SDL_draw.h"
#include "SDL_blendpoint.h"
static int SDL_BlendPoint_RGB555(SDL_Surface *dst, int x, int y, SDL_BlendMode blendMode, Uint8 r,
Uint8 g, Uint8 b, Uint8 a)
{
unsigned inva = 0xff - a;
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
DRAW_SETPIXELXY_BLEND_RGB555(x, y);
break;
case SDL_BLENDMODE_ADD:
DRAW_SETPIXELXY_ADD_RGB555(x, y);
break;
case SDL_BLENDMODE_MOD:
DRAW_SETPIXELXY_MOD_RGB555(x, y);
break;
case SDL_BLENDMODE_MUL:
DRAW_SETPIXELXY_MUL_RGB555(x, y);
break;
default:
DRAW_SETPIXELXY_RGB555(x, y);
break;
}
return 0;
}
static int SDL_BlendPoint_RGB565(SDL_Surface *dst, int x, int y, SDL_BlendMode blendMode, Uint8 r,
Uint8 g, Uint8 b, Uint8 a)
{
unsigned inva = 0xff - a;
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
DRAW_SETPIXELXY_BLEND_RGB565(x, y);
break;
case SDL_BLENDMODE_ADD:
DRAW_SETPIXELXY_ADD_RGB565(x, y);
break;
case SDL_BLENDMODE_MOD:
DRAW_SETPIXELXY_MOD_RGB565(x, y);
break;
case SDL_BLENDMODE_MUL:
DRAW_SETPIXELXY_MUL_RGB565(x, y);
break;
default:
DRAW_SETPIXELXY_RGB565(x, y);
break;
}
return 0;
}
static int SDL_BlendPoint_XRGB8888(SDL_Surface *dst, int x, int y, SDL_BlendMode blendMode, Uint8 r,
Uint8 g, Uint8 b, Uint8 a)
{
unsigned inva = 0xff - a;
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
DRAW_SETPIXELXY_BLEND_XRGB8888(x, y);
break;
case SDL_BLENDMODE_ADD:
DRAW_SETPIXELXY_ADD_XRGB8888(x, y);
break;
case SDL_BLENDMODE_MOD:
DRAW_SETPIXELXY_MOD_XRGB8888(x, y);
break;
case SDL_BLENDMODE_MUL:
DRAW_SETPIXELXY_MUL_XRGB8888(x, y);
break;
default:
DRAW_SETPIXELXY_XRGB8888(x, y);
break;
}
return 0;
}
static int SDL_BlendPoint_ARGB8888(SDL_Surface *dst, int x, int y, SDL_BlendMode blendMode,
Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
unsigned inva = 0xff - a;
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
DRAW_SETPIXELXY_BLEND_ARGB8888(x, y);
break;
case SDL_BLENDMODE_ADD:
DRAW_SETPIXELXY_ADD_ARGB8888(x, y);
break;
case SDL_BLENDMODE_MOD:
DRAW_SETPIXELXY_MOD_ARGB8888(x, y);
break;
case SDL_BLENDMODE_MUL:
DRAW_SETPIXELXY_MUL_ARGB8888(x, y);
break;
default:
DRAW_SETPIXELXY_ARGB8888(x, y);
break;
}
return 0;
}
static int SDL_BlendPoint_RGB(SDL_Surface *dst, int x, int y, SDL_BlendMode blendMode, Uint8 r,
Uint8 g, Uint8 b, Uint8 a)
{
SDL_PixelFormat *fmt = dst->format;
unsigned inva = 0xff - a;
switch (fmt->BytesPerPixel) {
case 2:
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
DRAW_SETPIXELXY2_BLEND_RGB(x, y);
break;
case SDL_BLENDMODE_ADD:
DRAW_SETPIXELXY2_ADD_RGB(x, y);
break;
case SDL_BLENDMODE_MOD:
DRAW_SETPIXELXY2_MOD_RGB(x, y);
break;
case SDL_BLENDMODE_MUL:
DRAW_SETPIXELXY2_MUL_RGB(x, y);
break;
default:
DRAW_SETPIXELXY2_RGB(x, y);
break;
}
return 0;
case 4:
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
DRAW_SETPIXELXY4_BLEND_RGB(x, y);
break;
case SDL_BLENDMODE_ADD:
DRAW_SETPIXELXY4_ADD_RGB(x, y);
break;
case SDL_BLENDMODE_MOD:
DRAW_SETPIXELXY4_MOD_RGB(x, y);
break;
case SDL_BLENDMODE_MUL:
DRAW_SETPIXELXY4_MUL_RGB(x, y);
break;
default:
DRAW_SETPIXELXY4_RGB(x, y);
break;
}
return 0;
default:
return SDL_Unsupported();
}
}
static int SDL_BlendPoint_RGBA(SDL_Surface *dst, int x, int y, SDL_BlendMode blendMode, Uint8 r,
Uint8 g, Uint8 b, Uint8 a)
{
SDL_PixelFormat *fmt = dst->format;
unsigned inva = 0xff - a;
switch (fmt->BytesPerPixel) {
case 4:
switch (blendMode) {
case SDL_BLENDMODE_BLEND:
DRAW_SETPIXELXY4_BLEND_RGBA(x, y);
break;
case SDL_BLENDMODE_ADD:
DRAW_SETPIXELXY4_ADD_RGBA(x, y);
break;
case SDL_BLENDMODE_MOD:
DRAW_SETPIXELXY4_MOD_RGBA(x, y);
break;
case SDL_BLENDMODE_MUL:
DRAW_SETPIXELXY4_MUL_RGBA(x, y);
break;
default:
DRAW_SETPIXELXY4_RGBA(x, y);
break;
}
return 0;
default:
return SDL_Unsupported();
}
}
int SDL_BlendPoint(SDL_Surface *dst, int x, int y, SDL_BlendMode blendMode, Uint8 r,
Uint8 g, Uint8 b, Uint8 a)
{
if (dst == NULL) {
return SDL_InvalidParamError("SDL_BlendPoint(): dst");
}
/* This function doesn't work on surfaces < 8 bpp */
if (dst->format->BitsPerPixel < 8) {
return SDL_SetError("SDL_BlendPoint(): Unsupported surface format");
}
/* Perform clipping */
if (x < dst->clip_rect.x || y < dst->clip_rect.y ||
x >= (dst->clip_rect.x + dst->clip_rect.w) ||
y >= (dst->clip_rect.y + dst->clip_rect.h)) {
return 0;
}
if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
r = DRAW_MUL(r, a);
g = DRAW_MUL(g, a);
b = DRAW_MUL(b, a);
}
switch (dst->format->BitsPerPixel) {
case 15:
switch (dst->format->Rmask) {
case 0x7C00:
return SDL_BlendPoint_RGB555(dst, x, y, blendMode, r, g, b, a);
}
break;
case 16:
switch (dst->format->Rmask) {
case 0xF800:
return SDL_BlendPoint_RGB565(dst, x, y, blendMode, r, g, b, a);
}
break;
case 32:
switch (dst->format->Rmask) {
case 0x00FF0000:
if (!dst->format->Amask) {
return SDL_BlendPoint_XRGB8888(dst, x, y, blendMode, r, g, b, a);
} else {
return SDL_BlendPoint_ARGB8888(dst, x, y, blendMode, r, g, b, a);
}
/* break; -Wunreachable-code-break */
}
break;
default:
break;
}
if (!dst->format->Amask) {
return SDL_BlendPoint_RGB(dst, x, y, blendMode, r, g, b, a);
} else {
return SDL_BlendPoint_RGBA(dst, x, y, blendMode, r, g, b, a);
}
}
int SDL_BlendPoints(SDL_Surface *dst, const SDL_Point *points, int count,
SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
int minx, miny;
int maxx, maxy;
int i;
int x, y;
int (*func)(SDL_Surface * dst, int x, int y,
SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) = NULL;
int status = 0;
if (dst == NULL) {
return SDL_InvalidParamError("SDL_BlendPoints(): dst");
}
/* This function doesn't work on surfaces < 8 bpp */
if (dst->format->BitsPerPixel < 8) {
return SDL_SetError("SDL_BlendPoints(): Unsupported surface format");
}
if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
r = DRAW_MUL(r, a);
g = DRAW_MUL(g, a);
b = DRAW_MUL(b, a);
}
/* FIXME: Does this function pointer slow things down significantly? */
switch (dst->format->BitsPerPixel) {
case 15:
switch (dst->format->Rmask) {
case 0x7C00:
func = SDL_BlendPoint_RGB555;
break;
}
break;
case 16:
switch (dst->format->Rmask) {
case 0xF800:
func = SDL_BlendPoint_RGB565;
break;
}
break;
case 32:
switch (dst->format->Rmask) {
case 0x00FF0000:
if (!dst->format->Amask) {
func = SDL_BlendPoint_XRGB8888;
} else {
func = SDL_BlendPoint_ARGB8888;
}
break;
}
break;
default:
break;
}
if (func == NULL) {
if (!dst->format->Amask) {
func = SDL_BlendPoint_RGB;
} else {
func = SDL_BlendPoint_RGBA;
}
}
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;
}
status = func(dst, x, y, blendMode, r, g, b, a);
}
return status;
}
#endif /* SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED */

View File

@ -0,0 +1,30 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_blendpoint_h_
#define SDL_blendpoint_h_
#include "SDL_internal.h"
extern int SDL_BlendPoint(SDL_Surface *dst, int x, int y, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
extern int SDL_BlendPoints(SDL_Surface *dst, const SDL_Point *points, int count, SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
#endif /* SDL_blendpoint_h_ */

View File

@ -0,0 +1,659 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#include "../../video/SDL_blit.h"
/* This code assumes that r, g, b, a are the source color,
* and in the blend and add case, the RGB values are premultiplied by a.
*/
#define DRAW_MUL(_a, _b) (((unsigned)(_a) * (_b)) / 255)
#define DRAW_FASTSETPIXEL(type) \
*pixel = (type)color
#define DRAW_FASTSETPIXEL1 DRAW_FASTSETPIXEL(Uint8)
#define DRAW_FASTSETPIXEL2 DRAW_FASTSETPIXEL(Uint16)
#define DRAW_FASTSETPIXEL4 DRAW_FASTSETPIXEL(Uint32)
#define DRAW_FASTSETPIXELXY(x, y, type, bpp, color) \
*(type *)((Uint8 *)dst->pixels + (y)*dst->pitch + (x)*bpp) = (type)color
#define DRAW_FASTSETPIXELXY1(x, y) DRAW_FASTSETPIXELXY(x, y, Uint8, 1, color)
#define DRAW_FASTSETPIXELXY2(x, y) DRAW_FASTSETPIXELXY(x, y, Uint16, 2, color)
#define DRAW_FASTSETPIXELXY4(x, y) DRAW_FASTSETPIXELXY(x, y, Uint32, 4, color)
#define DRAW_SETPIXEL(setpixel) \
do { \
unsigned sr = r, sg = g, sb = b, sa = a; \
(void)sa; \
setpixel; \
} while (0)
#define DRAW_SETPIXEL_BLEND(getpixel, setpixel) \
do { \
unsigned sr, sg, sb, sa = 0xFF; \
getpixel; \
sr = DRAW_MUL(inva, sr) + r; \
sg = DRAW_MUL(inva, sg) + g; \
sb = DRAW_MUL(inva, sb) + b; \
sa = DRAW_MUL(inva, sa) + a; \
setpixel; \
} while (0)
#define DRAW_SETPIXEL_ADD(getpixel, setpixel) \
do { \
unsigned sr, sg, sb, sa; \
(void)sa; \
getpixel; \
sr += r; \
if (sr > 0xff) \
sr = 0xff; \
sg += g; \
if (sg > 0xff) \
sg = 0xff; \
sb += b; \
if (sb > 0xff) \
sb = 0xff; \
setpixel; \
} while (0)
#define DRAW_SETPIXEL_MOD(getpixel, setpixel) \
do { \
unsigned sr, sg, sb, sa; \
(void)sa; \
getpixel; \
sr = DRAW_MUL(sr, r); \
sg = DRAW_MUL(sg, g); \
sb = DRAW_MUL(sb, b); \
setpixel; \
} while (0)
#define DRAW_SETPIXEL_MUL(getpixel, setpixel) \
do { \
unsigned sr, sg, sb, sa; \
(void)sa; \
getpixel; \
sr = DRAW_MUL(sr, r) + DRAW_MUL(inva, sr); \
if (sr > 0xff) \
sr = 0xff; \
sg = DRAW_MUL(sg, g) + DRAW_MUL(inva, sg); \
if (sg > 0xff) \
sg = 0xff; \
sb = DRAW_MUL(sb, b) + DRAW_MUL(inva, sb); \
if (sb > 0xff) \
sb = 0xff; \
setpixel; \
} while (0)
#define DRAW_SETPIXELXY(x, y, type, bpp, op) \
do { \
type *pixel = (type *)((Uint8 *)dst->pixels + (y)*dst->pitch + (x)*bpp); \
op; \
} while (0)
/*
* Define draw operators for RGB555
*/
#define DRAW_SETPIXEL_RGB555 \
DRAW_SETPIXEL(RGB555_FROM_RGB(*pixel, sr, sg, sb))
#define DRAW_SETPIXEL_BLEND_RGB555 \
DRAW_SETPIXEL_BLEND(RGB_FROM_RGB555(*pixel, sr, sg, sb), \
RGB555_FROM_RGB(*pixel, sr, sg, sb))
#define DRAW_SETPIXEL_ADD_RGB555 \
DRAW_SETPIXEL_ADD(RGB_FROM_RGB555(*pixel, sr, sg, sb), \
RGB555_FROM_RGB(*pixel, sr, sg, sb))
#define DRAW_SETPIXEL_MOD_RGB555 \
DRAW_SETPIXEL_MOD(RGB_FROM_RGB555(*pixel, sr, sg, sb), \
RGB555_FROM_RGB(*pixel, sr, sg, sb))
#define DRAW_SETPIXEL_MUL_RGB555 \
DRAW_SETPIXEL_MUL(RGB_FROM_RGB555(*pixel, sr, sg, sb), \
RGB555_FROM_RGB(*pixel, sr, sg, sb))
#define DRAW_SETPIXELXY_RGB555(x, y) \
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_RGB555)
#define DRAW_SETPIXELXY_BLEND_RGB555(x, y) \
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_BLEND_RGB555)
#define DRAW_SETPIXELXY_ADD_RGB555(x, y) \
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_ADD_RGB555)
#define DRAW_SETPIXELXY_MOD_RGB555(x, y) \
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_MOD_RGB555)
#define DRAW_SETPIXELXY_MUL_RGB555(x, y) \
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_MUL_RGB555)
/*
* Define draw operators for RGB565
*/
#define DRAW_SETPIXEL_RGB565 \
DRAW_SETPIXEL(RGB565_FROM_RGB(*pixel, sr, sg, sb))
#define DRAW_SETPIXEL_BLEND_RGB565 \
DRAW_SETPIXEL_BLEND(RGB_FROM_RGB565(*pixel, sr, sg, sb), \
RGB565_FROM_RGB(*pixel, sr, sg, sb))
#define DRAW_SETPIXEL_ADD_RGB565 \
DRAW_SETPIXEL_ADD(RGB_FROM_RGB565(*pixel, sr, sg, sb), \
RGB565_FROM_RGB(*pixel, sr, sg, sb))
#define DRAW_SETPIXEL_MOD_RGB565 \
DRAW_SETPIXEL_MOD(RGB_FROM_RGB565(*pixel, sr, sg, sb), \
RGB565_FROM_RGB(*pixel, sr, sg, sb))
#define DRAW_SETPIXEL_MUL_RGB565 \
DRAW_SETPIXEL_MUL(RGB_FROM_RGB565(*pixel, sr, sg, sb), \
RGB565_FROM_RGB(*pixel, sr, sg, sb))
#define DRAW_SETPIXELXY_RGB565(x, y) \
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_RGB565)
#define DRAW_SETPIXELXY_BLEND_RGB565(x, y) \
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_BLEND_RGB565)
#define DRAW_SETPIXELXY_ADD_RGB565(x, y) \
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_ADD_RGB565)
#define DRAW_SETPIXELXY_MOD_RGB565(x, y) \
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_MOD_RGB565)
#define DRAW_SETPIXELXY_MUL_RGB565(x, y) \
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_MUL_RGB565)
/*
* Define draw operators for RGB888
*/
#define DRAW_SETPIXEL_XRGB8888 \
DRAW_SETPIXEL(XRGB8888_FROM_RGB(*pixel, sr, sg, sb))
#define DRAW_SETPIXEL_BLEND_XRGB8888 \
DRAW_SETPIXEL_BLEND(RGB_FROM_XRGB8888(*pixel, sr, sg, sb), \
XRGB8888_FROM_RGB(*pixel, sr, sg, sb))
#define DRAW_SETPIXEL_ADD_XRGB8888 \
DRAW_SETPIXEL_ADD(RGB_FROM_XRGB8888(*pixel, sr, sg, sb), \
XRGB8888_FROM_RGB(*pixel, sr, sg, sb))
#define DRAW_SETPIXEL_MOD_XRGB8888 \
DRAW_SETPIXEL_MOD(RGB_FROM_XRGB8888(*pixel, sr, sg, sb), \
XRGB8888_FROM_RGB(*pixel, sr, sg, sb))
#define DRAW_SETPIXEL_MUL_XRGB8888 \
DRAW_SETPIXEL_MUL(RGB_FROM_XRGB8888(*pixel, sr, sg, sb), \
XRGB8888_FROM_RGB(*pixel, sr, sg, sb))
#define DRAW_SETPIXELXY_XRGB8888(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_XRGB8888)
#define DRAW_SETPIXELXY_BLEND_XRGB8888(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_BLEND_XRGB8888)
#define DRAW_SETPIXELXY_ADD_XRGB8888(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_ADD_XRGB8888)
#define DRAW_SETPIXELXY_MOD_XRGB8888(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MOD_XRGB8888)
#define DRAW_SETPIXELXY_MUL_XRGB8888(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MUL_XRGB8888)
/*
* Define draw operators for ARGB8888
*/
#define DRAW_SETPIXEL_ARGB8888 \
DRAW_SETPIXEL(ARGB8888_FROM_RGBA(*pixel, sr, sg, sb, sa))
#define DRAW_SETPIXEL_BLEND_ARGB8888 \
DRAW_SETPIXEL_BLEND(RGBA_FROM_ARGB8888(*pixel, sr, sg, sb, sa), \
ARGB8888_FROM_RGBA(*pixel, sr, sg, sb, sa))
#define DRAW_SETPIXEL_ADD_ARGB8888 \
DRAW_SETPIXEL_ADD(RGBA_FROM_ARGB8888(*pixel, sr, sg, sb, sa), \
ARGB8888_FROM_RGBA(*pixel, sr, sg, sb, sa))
#define DRAW_SETPIXEL_MOD_ARGB8888 \
DRAW_SETPIXEL_MOD(RGBA_FROM_ARGB8888(*pixel, sr, sg, sb, sa), \
ARGB8888_FROM_RGBA(*pixel, sr, sg, sb, sa))
#define DRAW_SETPIXEL_MUL_ARGB8888 \
DRAW_SETPIXEL_MUL(RGBA_FROM_ARGB8888(*pixel, sr, sg, sb, sa), \
ARGB8888_FROM_RGBA(*pixel, sr, sg, sb, sa))
#define DRAW_SETPIXELXY_ARGB8888(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_ARGB8888)
#define DRAW_SETPIXELXY_BLEND_ARGB8888(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_BLEND_ARGB8888)
#define DRAW_SETPIXELXY_ADD_ARGB8888(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_ADD_ARGB8888)
#define DRAW_SETPIXELXY_MOD_ARGB8888(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MOD_ARGB8888)
#define DRAW_SETPIXELXY_MUL_ARGB8888(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MUL_ARGB8888)
/*
* Define draw operators for general RGB
*/
#define DRAW_SETPIXEL_RGB \
DRAW_SETPIXEL(PIXEL_FROM_RGB(*pixel, fmt, sr, sg, sb))
#define DRAW_SETPIXEL_BLEND_RGB \
DRAW_SETPIXEL_BLEND(RGB_FROM_PIXEL(*pixel, fmt, sr, sg, sb), \
PIXEL_FROM_RGB(*pixel, fmt, sr, sg, sb))
#define DRAW_SETPIXEL_ADD_RGB \
DRAW_SETPIXEL_ADD(RGB_FROM_PIXEL(*pixel, fmt, sr, sg, sb), \
PIXEL_FROM_RGB(*pixel, fmt, sr, sg, sb))
#define DRAW_SETPIXEL_MOD_RGB \
DRAW_SETPIXEL_MOD(RGB_FROM_PIXEL(*pixel, fmt, sr, sg, sb), \
PIXEL_FROM_RGB(*pixel, fmt, sr, sg, sb))
#define DRAW_SETPIXEL_MUL_RGB \
DRAW_SETPIXEL_MUL(RGB_FROM_PIXEL(*pixel, fmt, sr, sg, sb), \
PIXEL_FROM_RGB(*pixel, fmt, sr, sg, sb))
#define DRAW_SETPIXELXY2_RGB(x, y) \
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_RGB)
#define DRAW_SETPIXELXY4_RGB(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_RGB)
#define DRAW_SETPIXELXY2_BLEND_RGB(x, y) \
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_BLEND_RGB)
#define DRAW_SETPIXELXY4_BLEND_RGB(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_BLEND_RGB)
#define DRAW_SETPIXELXY2_ADD_RGB(x, y) \
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_ADD_RGB)
#define DRAW_SETPIXELXY4_ADD_RGB(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_ADD_RGB)
#define DRAW_SETPIXELXY2_MOD_RGB(x, y) \
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_MOD_RGB)
#define DRAW_SETPIXELXY4_MOD_RGB(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MOD_RGB)
#define DRAW_SETPIXELXY2_MUL_RGB(x, y) \
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_MUL_RGB)
#define DRAW_SETPIXELXY4_MUL_RGB(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MUL_RGB)
/*
* Define draw operators for general RGBA
*/
#define DRAW_SETPIXEL_RGBA \
DRAW_SETPIXEL(PIXEL_FROM_RGBA(*pixel, fmt, sr, sg, sb, sa))
#define DRAW_SETPIXEL_BLEND_RGBA \
DRAW_SETPIXEL_BLEND(RGBA_FROM_PIXEL(*pixel, fmt, sr, sg, sb, sa), \
PIXEL_FROM_RGBA(*pixel, fmt, sr, sg, sb, sa))
#define DRAW_SETPIXEL_ADD_RGBA \
DRAW_SETPIXEL_ADD(RGBA_FROM_PIXEL(*pixel, fmt, sr, sg, sb, sa), \
PIXEL_FROM_RGBA(*pixel, fmt, sr, sg, sb, sa))
#define DRAW_SETPIXEL_MOD_RGBA \
DRAW_SETPIXEL_MOD(RGBA_FROM_PIXEL(*pixel, fmt, sr, sg, sb, sa), \
PIXEL_FROM_RGBA(*pixel, fmt, sr, sg, sb, sa))
#define DRAW_SETPIXEL_MUL_RGBA \
DRAW_SETPIXEL_MUL(RGBA_FROM_PIXEL(*pixel, fmt, sr, sg, sb, sa), \
PIXEL_FROM_RGBA(*pixel, fmt, sr, sg, sb, sa))
#define DRAW_SETPIXELXY4_RGBA(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_RGBA)
#define DRAW_SETPIXELXY4_BLEND_RGBA(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_BLEND_RGBA)
#define DRAW_SETPIXELXY4_ADD_RGBA(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_ADD_RGBA)
#define DRAW_SETPIXELXY4_MOD_RGBA(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MOD_RGBA)
#define DRAW_SETPIXELXY4_MUL_RGBA(x, y) \
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MUL_RGBA)
/*
* Define line drawing macro
*/
#define ABS(_x) ((_x) < 0 ? -(_x) : (_x))
/* Horizontal line */
#define HLINE(type, op, draw_end) \
{ \
int length; \
int pitch = (dst->pitch / dst->format->BytesPerPixel); \
type *pixel; \
if (x1 <= x2) { \
pixel = (type *)dst->pixels + y1 * pitch + x1; \
length = draw_end ? (x2 - x1 + 1) : (x2 - x1); \
} else { \
pixel = (type *)dst->pixels + y1 * pitch + x2; \
if (!draw_end) { \
++pixel; \
} \
length = draw_end ? (x1 - x2 + 1) : (x1 - x2); \
} \
while (length--) { \
op; \
++pixel; \
} \
}
/* Vertical line */
#define VLINE(type, op, draw_end) \
{ \
int length; \
int pitch = (dst->pitch / dst->format->BytesPerPixel); \
type *pixel; \
if (y1 <= y2) { \
pixel = (type *)dst->pixels + y1 * pitch + x1; \
length = draw_end ? (y2 - y1 + 1) : (y2 - y1); \
} else { \
pixel = (type *)dst->pixels + y2 * pitch + x1; \
if (!draw_end) { \
pixel += pitch; \
} \
length = draw_end ? (y1 - y2 + 1) : (y1 - y2); \
} \
while (length--) { \
op; \
pixel += pitch; \
} \
}
/* Diagonal line */
#define DLINE(type, op, draw_end) \
{ \
int length; \
int pitch = (dst->pitch / dst->format->BytesPerPixel); \
type *pixel; \
if (y1 <= y2) { \
pixel = (type *)dst->pixels + y1 * pitch + x1; \
if (x1 <= x2) { \
++pitch; \
} else { \
--pitch; \
} \
length = (y2 - y1); \
} else { \
pixel = (type *)dst->pixels + y2 * pitch + x2; \
if (x2 <= x1) { \
++pitch; \
} else { \
--pitch; \
} \
if (!draw_end) { \
pixel += pitch; \
} \
length = (y1 - y2); \
} \
if (draw_end) { \
++length; \
} \
while (length--) { \
op; \
pixel += pitch; \
} \
}
/* Bresenham's line algorithm */
#define BLINE(x1, y1, x2, y2, op, draw_end) \
{ \
int i, deltax, deltay, numpixels; \
int d, dinc1, dinc2; \
int x, xinc1, xinc2; \
int y, yinc1, yinc2; \
\
deltax = ABS(x2 - x1); \
deltay = ABS(y2 - y1); \
\
if (deltax >= deltay) { \
numpixels = deltax + 1; \
d = (2 * deltay) - deltax; \
dinc1 = deltay * 2; \
dinc2 = (deltay - deltax) * 2; \
xinc1 = 1; \
xinc2 = 1; \
yinc1 = 0; \
yinc2 = 1; \
} else { \
numpixels = deltay + 1; \
d = (2 * deltax) - deltay; \
dinc1 = deltax * 2; \
dinc2 = (deltax - deltay) * 2; \
xinc1 = 0; \
xinc2 = 1; \
yinc1 = 1; \
yinc2 = 1; \
} \
\
if (x1 > x2) { \
xinc1 = -xinc1; \
xinc2 = -xinc2; \
} \
if (y1 > y2) { \
yinc1 = -yinc1; \
yinc2 = -yinc2; \
} \
\
x = x1; \
y = y1; \
\
if (!draw_end) { \
--numpixels; \
} \
for (i = 0; i < numpixels; ++i) { \
op(x, y); \
if (d < 0) { \
d += dinc1; \
x += xinc1; \
y += yinc1; \
} else { \
d += dinc2; \
x += xinc2; \
y += yinc2; \
} \
} \
}
/* Xiaolin Wu's line algorithm, based on Michael Abrash's implementation */
#define WULINE(x1, y1, x2, y2, opaque_op, blend_op, draw_end) \
{ \
Uint16 ErrorAdj, ErrorAcc; \
Uint16 ErrorAccTemp, Weighting; \
int DeltaX, DeltaY, Temp, XDir; \
unsigned r, g, b, a, inva; \
\
/* Draw the initial pixel, which is always exactly intersected by \
the line and so needs no weighting */ \
opaque_op(x1, y1); \
\
/* Draw the final pixel, which is always exactly intersected by the line \
and so needs no weighting */ \
if (draw_end) { \
opaque_op(x2, y2); \
} \
\
/* Make sure the line runs top to bottom */ \
if (y1 > y2) { \
Temp = y1; \
y1 = y2; \
y2 = Temp; \
Temp = x1; \
x1 = x2; \
x2 = Temp; \
} \
DeltaY = y2 - y1; \
\
if ((DeltaX = x2 - x1) >= 0) { \
XDir = 1; \
} else { \
XDir = -1; \
DeltaX = -DeltaX; /* make DeltaX positive */ \
} \
\
/* line is not horizontal, diagonal, or vertical */ \
ErrorAcc = 0; /* initialize the line error accumulator to 0 */ \
\
/* Is this an X-major or Y-major line? */ \
if (DeltaY > DeltaX) { \
/* Y-major line; calculate 16-bit fixed-point fractional part of a \
pixel that X advances each time Y advances 1 pixel, truncating the \
result so that we won't overrun the endpoint along the X axis */ \
ErrorAdj = ((unsigned long)DeltaX << 16) / (unsigned long)DeltaY; \
/* Draw all pixels other than the first and last */ \
while (--DeltaY) { \
ErrorAccTemp = ErrorAcc; /* remember current accumulated error */ \
ErrorAcc += ErrorAdj; /* calculate error for next pixel */ \
if (ErrorAcc <= ErrorAccTemp) { \
/* The error accumulator turned over, so advance the X coord */ \
x1 += XDir; \
} \
y1++; /* Y-major, so always advance Y */ \
/* The IntensityBits most significant bits of ErrorAcc give us the \
intensity weighting for this pixel, and the complement of the \
weighting for the paired pixel */ \
Weighting = ErrorAcc >> 8; \
{ \
a = DRAW_MUL(_a, (Weighting ^ 255)); \
r = DRAW_MUL(_r, a); \
g = DRAW_MUL(_g, a); \
b = DRAW_MUL(_b, a); \
inva = (a ^ 0xFF); \
blend_op(x1, y1); \
} \
{ \
a = DRAW_MUL(_a, Weighting); \
r = DRAW_MUL(_r, a); \
g = DRAW_MUL(_g, a); \
b = DRAW_MUL(_b, a); \
inva = (a ^ 0xFF); \
blend_op(x1 + XDir, y1); \
} \
} \
} else { \
/* X-major line; calculate 16-bit fixed-point fractional part of a \
pixel that Y advances each time X advances 1 pixel, truncating the \
result to avoid overrunning the endpoint along the X axis */ \
ErrorAdj = ((unsigned long)DeltaY << 16) / (unsigned long)DeltaX; \
/* Draw all pixels other than the first and last */ \
while (--DeltaX) { \
ErrorAccTemp = ErrorAcc; /* remember current accumulated error */ \
ErrorAcc += ErrorAdj; /* calculate error for next pixel */ \
if (ErrorAcc <= ErrorAccTemp) { \
/* The error accumulator turned over, so advance the Y coord */ \
y1++; \
} \
x1 += XDir; /* X-major, so always advance X */ \
/* The IntensityBits most significant bits of ErrorAcc give us the \
intensity weighting for this pixel, and the complement of the \
weighting for the paired pixel */ \
Weighting = ErrorAcc >> 8; \
{ \
a = DRAW_MUL(_a, (Weighting ^ 255)); \
r = DRAW_MUL(_r, a); \
g = DRAW_MUL(_g, a); \
b = DRAW_MUL(_b, a); \
inva = (a ^ 0xFF); \
blend_op(x1, y1); \
} \
{ \
a = DRAW_MUL(_a, Weighting); \
r = DRAW_MUL(_r, a); \
g = DRAW_MUL(_g, a); \
b = DRAW_MUL(_b, a); \
inva = (a ^ 0xFF); \
blend_op(x1, y1 + 1); \
} \
} \
} \
}
#ifdef AA_LINES
#define AALINE(x1, y1, x2, y2, opaque_op, blend_op, draw_end) \
WULINE(x1, y1, x2, y2, opaque_op, blend_op, draw_end)
#else
#define AALINE(x1, y1, x2, y2, opaque_op, blend_op, draw_end) \
BLINE(x1, y1, x2, y2, opaque_op, draw_end)
#endif
/*
* Define fill rect macro
*/
#define FILLRECT(type, op) \
do { \
int width = rect->w; \
int height = rect->h; \
int pitch = (dst->pitch / dst->format->BytesPerPixel); \
int skip = pitch - width; \
type *pixel = (type *)dst->pixels + rect->y * pitch + rect->x; \
while (height--) { \
{ \
int n = (width + 3) / 4; \
switch (width & 3) { \
case 0: \
do { \
op; \
pixel++; \
SDL_FALLTHROUGH; \
case 3: \
op; \
pixel++; \
SDL_FALLTHROUGH; \
case 2: \
op; \
pixel++; \
SDL_FALLTHROUGH; \
case 1: \
op; \
pixel++; \
} while (--n > 0); \
} \
} \
pixel += skip; \
} \
} while (0)

View File

@ -0,0 +1,200 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#if SDL_VIDEO_RENDER_SW && !defined(SDL_RENDER_DISABLED)
#include "SDL_draw.h"
#include "SDL_drawline.h"
#include "SDL_drawpoint.h"
static void SDL_DrawLine1(SDL_Surface *dst, int x1, int y1, int x2, int y2, Uint32 color,
SDL_bool draw_end)
{
if (y1 == y2) {
int length;
int pitch = (dst->pitch / dst->format->BytesPerPixel);
Uint8 *pixel;
if (x1 <= x2) {
pixel = (Uint8 *)dst->pixels + y1 * pitch + x1;
length = draw_end ? (x2 - x1 + 1) : (x2 - x1);
} else {
pixel = (Uint8 *)dst->pixels + y1 * pitch + x2;
if (!draw_end) {
++pixel;
}
length = draw_end ? (x1 - x2 + 1) : (x1 - x2);
}
SDL_memset(pixel, color, length);
} else if (x1 == x2) {
VLINE(Uint8, DRAW_FASTSETPIXEL1, draw_end);
} else if (ABS(x1 - x2) == ABS(y1 - y2)) {
DLINE(Uint8, DRAW_FASTSETPIXEL1, draw_end);
} else {
BLINE(x1, y1, x2, y2, DRAW_FASTSETPIXELXY1, draw_end);
}
}
static void SDL_DrawLine2(SDL_Surface *dst, int x1, int y1, int x2, int y2, Uint32 color,
SDL_bool draw_end)
{
if (y1 == y2) {
HLINE(Uint16, DRAW_FASTSETPIXEL2, draw_end);
} else if (x1 == x2) {
VLINE(Uint16, DRAW_FASTSETPIXEL2, draw_end);
} else if (ABS(x1 - x2) == ABS(y1 - y2)) {
DLINE(Uint16, DRAW_FASTSETPIXEL2, draw_end);
} else {
Uint8 _r, _g, _b, _a;
const SDL_PixelFormat *fmt = dst->format;
SDL_GetRGBA(color, fmt, &_r, &_g, &_b, &_a);
if (fmt->Rmask == 0x7C00) {
AALINE(x1, y1, x2, y2,
DRAW_FASTSETPIXELXY2, DRAW_SETPIXELXY_BLEND_RGB555,
draw_end);
} else if (fmt->Rmask == 0xF800) {
AALINE(x1, y1, x2, y2,
DRAW_FASTSETPIXELXY2, DRAW_SETPIXELXY_BLEND_RGB565,
draw_end);
} else {
AALINE(x1, y1, x2, y2,
DRAW_FASTSETPIXELXY2, DRAW_SETPIXELXY2_BLEND_RGB,
draw_end);
}
}
}
static void SDL_DrawLine4(SDL_Surface *dst, int x1, int y1, int x2, int y2, Uint32 color,
SDL_bool draw_end)
{
if (y1 == y2) {
HLINE(Uint32, DRAW_FASTSETPIXEL4, draw_end);
} else if (x1 == x2) {
VLINE(Uint32, DRAW_FASTSETPIXEL4, draw_end);
} else if (ABS(x1 - x2) == ABS(y1 - y2)) {
DLINE(Uint32, DRAW_FASTSETPIXEL4, draw_end);
} else {
Uint8 _r, _g, _b, _a;
const SDL_PixelFormat *fmt = dst->format;
SDL_GetRGBA(color, fmt, &_r, &_g, &_b, &_a);
if (fmt->Rmask == 0x00FF0000) {
if (!fmt->Amask) {
AALINE(x1, y1, x2, y2,
DRAW_FASTSETPIXELXY4, DRAW_SETPIXELXY_BLEND_XRGB8888,
draw_end);
} else {
AALINE(x1, y1, x2, y2,
DRAW_FASTSETPIXELXY4, DRAW_SETPIXELXY_BLEND_ARGB8888,
draw_end);
}
} else {
AALINE(x1, y1, x2, y2,
DRAW_FASTSETPIXELXY4, DRAW_SETPIXELXY4_BLEND_RGB,
draw_end);
}
}
}
typedef void (*DrawLineFunc)(SDL_Surface *dst,
int x1, int y1, int x2, int y2,
Uint32 color, SDL_bool draw_end);
static DrawLineFunc SDL_CalculateDrawLineFunc(const SDL_PixelFormat *fmt)
{
switch (fmt->BytesPerPixel) {
case 1:
if (fmt->BitsPerPixel < 8) {
break;
}
return SDL_DrawLine1;
case 2:
return SDL_DrawLine2;
case 4:
return SDL_DrawLine4;
}
return NULL;
}
int SDL_DrawLine(SDL_Surface *dst, int x1, int y1, int x2, int y2, Uint32 color)
{
DrawLineFunc func;
if (dst == NULL) {
return SDL_InvalidParamError("SDL_DrawLine(): dst");
}
func = SDL_CalculateDrawLineFunc(dst->format);
if (func == NULL) {
return SDL_SetError("SDL_DrawLine(): Unsupported surface format");
}
/* Perform clipping */
/* FIXME: We don't actually want to clip, as it may change line slope */
if (!SDL_GetRectAndLineIntersection(&dst->clip_rect, &x1, &y1, &x2, &y2)) {
return 0;
}
func(dst, x1, y1, x2, y2, color, SDL_TRUE);
return 0;
}
int SDL_DrawLines(SDL_Surface *dst, const SDL_Point *points, int count,
Uint32 color)
{
int i;
int x1, y1;
int x2, y2;
SDL_bool draw_end;
DrawLineFunc func;
if (dst == NULL) {
return SDL_InvalidParamError("SDL_DrawLines(): dst");
}
func = SDL_CalculateDrawLineFunc(dst->format);
if (func == NULL) {
return SDL_SetError("SDL_DrawLines(): Unsupported surface format");
}
for (i = 1; i < count; ++i) {
x1 = points[i - 1].x;
y1 = points[i - 1].y;
x2 = points[i].x;
y2 = points[i].y;
/* Perform clipping */
/* FIXME: We don't actually want to clip, as it may change line slope */
if (!SDL_GetRectAndLineIntersection(&dst->clip_rect, &x1, &y1, &x2, &y2)) {
continue;
}
/* Draw the end if the whole line is a single point or it was clipped */
draw_end = ((x1 == x2) && (y1 == y2)) || (x2 != points[i].x || y2 != points[i].y);
func(dst, x1, y1, x2, y2, color, draw_end);
}
if (points[0].x != points[count - 1].x || points[0].y != points[count - 1].y) {
SDL_DrawPoint(dst, points[count - 1].x, points[count - 1].y, color);
}
return 0;
}
#endif /* SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED */

View File

@ -0,0 +1,30 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_drawline_h_
#define SDL_drawline_h_
#include "SDL_internal.h"
extern int SDL_DrawLine(SDL_Surface *dst, int x1, int y1, int x2, int y2, Uint32 color);
extern int SDL_DrawLines(SDL_Surface *dst, const SDL_Point *points, int count, Uint32 color);
#endif /* SDL_drawline_h_ */

View File

@ -0,0 +1,109 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#if SDL_VIDEO_RENDER_SW && !defined(SDL_RENDER_DISABLED)
#include "SDL_draw.h"
#include "SDL_drawpoint.h"
int SDL_DrawPoint(SDL_Surface *dst, int x, int y, Uint32 color)
{
if (dst == NULL) {
return SDL_InvalidParamError("SDL_DrawPoint(): dst");
}
/* This function doesn't work on surfaces < 8 bpp */
if (dst->format->BitsPerPixel < 8) {
return SDL_SetError("SDL_DrawPoint(): Unsupported surface format");
}
/* Perform clipping */
if (x < dst->clip_rect.x || y < dst->clip_rect.y ||
x >= (dst->clip_rect.x + dst->clip_rect.w) ||
y >= (dst->clip_rect.y + dst->clip_rect.h)) {
return 0;
}
switch (dst->format->BytesPerPixel) {
case 1:
DRAW_FASTSETPIXELXY1(x, y);
break;
case 2:
DRAW_FASTSETPIXELXY2(x, y);
break;
case 3:
return SDL_Unsupported();
case 4:
DRAW_FASTSETPIXELXY4(x, y);
break;
}
return 0;
}
int SDL_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 == NULL) {
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;
}
switch (dst->format->BytesPerPixel) {
case 1:
DRAW_FASTSETPIXELXY1(x, y);
break;
case 2:
DRAW_FASTSETPIXELXY2(x, y);
break;
case 3:
return SDL_Unsupported();
case 4:
DRAW_FASTSETPIXELXY4(x, y);
break;
}
}
return 0;
}
#endif /* SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED */

View File

@ -0,0 +1,30 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_drawpoint_h_
#define SDL_drawpoint_h_
#include "SDL_internal.h"
extern int SDL_DrawPoint(SDL_Surface *dst, int x, int y, Uint32 color);
extern int SDL_DrawPoints(SDL_Surface *dst, const SDL_Point *points, int count, Uint32 color);
#endif /* SDL_drawpoint_h_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,27 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_render_sw_c_h_
#define SDL_render_sw_c_h_
extern SDL_Renderer *SW_CreateRendererForSurface(SDL_Surface *surface);
#endif /* SDL_render_sw_c_h_ */

View File

@ -0,0 +1,616 @@
/*
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_SW && !defined(SDL_RENDER_DISABLED)
#if defined(__WIN32__) || defined(__GDK__)
#include "../../core/windows/SDL_windows.h"
#endif
#include <stdlib.h>
#include <string.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_SurfaceHasColorKey(src)) {
SDL_GetSurfaceColorKey(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 center The center of ratation
\param rect_dest Bounding box of rotated rectangle
\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 * (SDL_PI_D / 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 rect_dest 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 = (Uint8)((((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 = (Uint8)((((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 = (Uint8)((((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 = (Uint8)((((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 rect_dest 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), (size_t)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 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_SurfaceHasColorKey(src)) {
if (SDL_GetSurfaceColorKey(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_CreateSurface(rect_dest->w, rect_dest->h + GUARD_ROWS, 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_CreateSurface(rect_dest->w, rect_dest->h + GUARD_ROWS, src->format->format);
}
/* 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_SetSurfaceColorKey(rz_dst, SDL_TRUE, colorkey);
SDL_FillSurfaceRect(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_FillSurfaceRect(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_SetSurfaceColorKey(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_SW && !SDL_RENDER_DISABLED */

View File

@ -0,0 +1,30 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#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_ */

View File

@ -0,0 +1,887 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#if SDL_VIDEO_RENDER_SW && !defined(SDL_RENDER_DISABLED)
#include "SDL_triangle.h"
#include "../../video/SDL_blit.h"
/* fixed points bits precision
* Set to 1, so that it can start rendering with 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
#define COLOR_EQ(c1, c2) ((c1).r == (c2).r && (c1).g == (c2).g && (c1).b == (c2).b && (c1).a == (c2).a)
static void SDL_BlitTriangle_Slow(SDL_BlitInfo *info,
SDL_Point s2_x_area, SDL_Rect dstrect, int area, int bias_w0, int bias_w1, int bias_w2,
int d2d1_y, int d1d2_x, int d0d2_y, int d2d0_x, int d1d0_y, int d0d1_x,
int s2s0_x, int s2s1_x, int s2s0_y, int s2s1_y, int w0_row, int w1_row, int w2_row,
SDL_Color c0, SDL_Color c1, SDL_Color c2, int is_uniform);
#if 0
int SDL_BlitTriangle(SDL_Surface *src, const SDL_Point srcpoints[3], SDL_Surface *dst, const SDL_Point dstpoints[3])
{
int i;
SDL_Point points[6];
if (src == NULL || dst == NULL) {
return -1;
}
for (i = 0; i < 3; i++) {
if (srcpoints[i].x < 0 || srcpoints[i].y < 0 || srcpoints[i].x >= src->w || srcpoints[i].y >= src->h) {
return SDL_SetError("Values of 'srcpoints' out of bounds");
}
}
points[0] = srcpoints[0];
points[1] = dstpoints[0];
points[2] = srcpoints[1];
points[3] = dstpoints[1];
points[4] = srcpoints[2];
points[5] = dstpoints[2];
for (i = 0; i < 3; i++) {
trianglepoint_2_fixedpoint(&points[2 * i + 1]);
}
return SDL_SW_BlitTriangle(src, dst, points);
}
int SDL_FillTriangle(SDL_Surface *dst, const SDL_Point points[3], Uint32 color)
{
int i;
SDL_Point points_tmp[3];
if (dst == NULL) {
return -1;
}
for (i = 0; i < 3; i++) {
points_tmp[i] = points[i];
trianglepoint_2_fixedpoint(&points_tmp[i]);
}
return SDL_SW_FillTriangle(dst, points_tmp, SDL_BLENDMODE_NONE, color);
}
#endif
/* cross product AB x AC */
static int cross_product(const SDL_Point *a, const SDL_Point *b, int c_x, int c_y)
{
return (b->x - a->x) * (c_y - a->y) - (b->y - a->y) * (c_x - a->x);
}
/* check for top left rules */
static int is_top_left(const SDL_Point *a, const SDL_Point *b, int is_clockwise)
{
if (is_clockwise) {
if (a->y == b->y && a->x < b->x) {
return 1;
}
if (b->y < a->y) {
return 1;
}
} else {
if (a->y == b->y && b->x < a->x) {
return 1;
}
if (a->y < b->y) {
return 1;
}
}
return 0;
}
void 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 \
Uint8 r = (Uint8)(((Sint64)w0 * c0.r + (Sint64)w1 * c1.r + (Sint64)w2 * c2.r) / area); \
Uint8 g = (Uint8)(((Sint64)w0 * c0.g + (Sint64)w1 * c1.g + (Sint64)w2 * c2.g) / area); \
Uint8 b = (Uint8)(((Sint64)w0 * c0.b + (Sint64)w1 * c1.b + (Sint64)w2 * c2.b) / area); \
Uint8 a = (Uint8)(((Sint64)w0 * c0.a + (Sint64)w1 * c1.a + (Sint64)w2 * c2.a) / area); \
Uint32 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; \
} \
}
int SDL_SW_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)
{
int ret = 0;
int dst_locked = 0;
SDL_Rect dstrect;
int dstbpp;
Uint8 *dst_ptr;
int dst_pitch;
int area, is_clockwise;
int d2d1_y, d1d2_x, d0d2_y, d2d0_x, d1d0_y, d0d1_x;
int w0_row, w1_row, w2_row;
int bias_w0, bias_w1, bias_w2;
int is_uniform;
SDL_Surface *tmp = NULL;
if (dst == NULL) {
return -1;
}
area = cross_product(d0, d1, d2->x, d2->y);
is_uniform = COLOR_EQ(c0, c1) && COLOR_EQ(c1, c2);
/* Flat triangle */
if (area == 0) {
return 0;
}
/* Lock the destination, if needed */
if (SDL_MUSTLOCK(dst)) {
if (SDL_LockSurface(dst) < 0) {
ret = -1;
goto end;
} else {
dst_locked = 1;
}
}
bounding_rect_fixedpoint(d0, d1, d2, &dstrect);
{
/* Clip triangle rect with surface rect */
SDL_Rect rect;
rect.x = 0;
rect.y = 0;
rect.w = dst->w;
rect.h = dst->h;
SDL_GetRectIntersection(&dstrect, &rect, &dstrect);
}
{
/* Clip triangle with surface clip rect */
SDL_Rect rect;
SDL_GetSurfaceClipRect(dst, &rect);
SDL_GetRectIntersection(&dstrect, &rect, &dstrect);
}
if (blend != SDL_BLENDMODE_NONE) {
int format = dst->format->format;
/* need an alpha format */
if (!dst->format->Amask) {
format = SDL_PIXELFORMAT_ARGB8888;
}
/* Use an intermediate surface */
tmp = SDL_CreateSurface(dstrect.w, dstrect.h, format);
if (tmp == NULL) {
ret = -1;
goto end;
}
if (blend == SDL_BLENDMODE_MOD) {
Uint32 c = SDL_MapRGBA(tmp->format, 255, 255, 255, 255);
SDL_FillSurfaceRect(tmp, NULL, c);
}
SDL_SetSurfaceBlendMode(tmp, blend);
dstbpp = tmp->format->BytesPerPixel;
dst_ptr = tmp->pixels;
dst_pitch = tmp->pitch;
} else {
/* Write directly to destination surface */
dstbpp = dst->format->BytesPerPixel;
dst_ptr = (Uint8 *)dst->pixels + dstrect.x * dstbpp + dstrect.y * dst->pitch;
dst_pitch = dst->pitch;
}
is_clockwise = area > 0;
area = SDL_abs(area);
d2d1_y = (d1->y - d2->y) << FP_BITS;
d0d2_y = (d2->y - d0->y) << FP_BITS;
d1d0_y = (d0->y - d1->y) << FP_BITS;
d1d2_x = (d2->x - d1->x) << FP_BITS;
d2d0_x = (d0->x - d2->x) << FP_BITS;
d0d1_x = (d1->x - d0->x) << FP_BITS;
/* Starting point for rendering, at the middle of a pixel */
{
SDL_Point p;
p.x = dstrect.x;
p.y = dstrect.y;
trianglepoint_2_fixedpoint(&p);
p.x += (1 << FP_BITS) / 2;
p.y += (1 << FP_BITS) / 2;
w0_row = cross_product(d1, d2, p.x, p.y);
w1_row = cross_product(d2, d0, p.x, p.y);
w2_row = cross_product(d0, d1, p.x, p.y);
}
/* Handle anti-clockwise triangles */
if (!is_clockwise) {
d2d1_y *= -1;
d0d2_y *= -1;
d1d0_y *= -1;
d1d2_x *= -1;
d2d0_x *= -1;
d0d1_x *= -1;
w0_row *= -1;
w1_row *= -1;
w2_row *= -1;
}
/* Add a bias to respect top-left rasterization rule */
bias_w0 = (is_top_left(d1, d2, is_clockwise) ? 0 : -1);
bias_w1 = (is_top_left(d2, d0, is_clockwise) ? 0 : -1);
bias_w2 = (is_top_left(d0, d1, is_clockwise) ? 0 : -1);
if (is_uniform) {
Uint32 color;
if (tmp) {
if (dst->format->Amask) {
color = SDL_MapRGBA(tmp->format, c0.r, c0.g, c0.b, c0.a);
} else {
// color = SDL_MapRGB(tmp->format, c0.r, c0.g, c0.b);
color = SDL_MapRGBA(tmp->format, c0.r, c0.g, c0.b, c0.a);
}
} else {
color = SDL_MapRGBA(dst->format, c0.r, c0.g, c0.b, c0.a);
}
if (dstbpp == 4) {
TRIANGLE_BEGIN_LOOP
{
*(Uint32 *)dptr = color;
}
TRIANGLE_END_LOOP
} else if (dstbpp == 3) {
TRIANGLE_BEGIN_LOOP
{
Uint8 *s = (Uint8 *)&color;
dptr[0] = s[0];
dptr[1] = s[1];
dptr[2] = s[2];
}
TRIANGLE_END_LOOP
} else if (dstbpp == 2) {
TRIANGLE_BEGIN_LOOP
{
*(Uint16 *)dptr = (Uint16)color;
}
TRIANGLE_END_LOOP
} else if (dstbpp == 1) {
TRIANGLE_BEGIN_LOOP
{
*dptr = (Uint8)color;
}
TRIANGLE_END_LOOP
}
} else {
SDL_PixelFormat *format = dst->format;
if (tmp) {
format = tmp->format;
}
if (dstbpp == 4) {
TRIANGLE_BEGIN_LOOP
{
TRIANGLE_GET_MAPPED_COLOR
*(Uint32 *)dptr = color;
}
TRIANGLE_END_LOOP
} else if (dstbpp == 3) {
TRIANGLE_BEGIN_LOOP
{
TRIANGLE_GET_MAPPED_COLOR
Uint8 *s = (Uint8 *)&color;
dptr[0] = s[0];
dptr[1] = s[1];
dptr[2] = s[2];
}
TRIANGLE_END_LOOP
} else if (dstbpp == 2) {
TRIANGLE_BEGIN_LOOP
{
TRIANGLE_GET_MAPPED_COLOR
*(Uint16 *)dptr = (Uint16)color;
}
TRIANGLE_END_LOOP
} else if (dstbpp == 1) {
TRIANGLE_BEGIN_LOOP
{
TRIANGLE_GET_MAPPED_COLOR
*dptr = (Uint8)color;
}
TRIANGLE_END_LOOP
}
}
if (tmp) {
SDL_BlitSurface(tmp, NULL, dst, &dstrect);
SDL_DestroySurface(tmp);
}
end:
if (dst_locked) {
SDL_UnlockSurface(dst);
}
return ret;
}
int SDL_SW_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)
{
int ret = 0;
int src_locked = 0;
int dst_locked = 0;
SDL_BlendMode blend;
SDL_Rect dstrect;
SDL_Point s2_x_area;
int dstbpp;
Uint8 *dst_ptr;
int dst_pitch;
int *src_ptr;
int src_pitch;
int area, is_clockwise;
int d2d1_y, d1d2_x, d0d2_y, d2d0_x, d1d0_y, d0d1_x;
int s2s0_x, s2s1_x, s2s0_y, s2s1_y;
int w0_row, w1_row, w2_row;
int bias_w0, bias_w1, bias_w2;
int is_uniform;
int has_modulation;
if (src == NULL || dst == NULL) {
return -1;
}
area = cross_product(d0, d1, d2->x, d2->y);
/* Flat triangle */
if (area == 0) {
return 0;
}
/* Lock the destination, if needed */
if (SDL_MUSTLOCK(dst)) {
if (SDL_LockSurface(dst) < 0) {
ret = -1;
goto end;
} else {
dst_locked = 1;
}
}
/* Lock the source, if needed */
if (SDL_MUSTLOCK(src)) {
if (SDL_LockSurface(src) < 0) {
ret = -1;
goto end;
} else {
src_locked = 1;
}
}
is_uniform = COLOR_EQ(c0, c1) && COLOR_EQ(c1, c2);
bounding_rect_fixedpoint(d0, d1, d2, &dstrect);
SDL_GetSurfaceBlendMode(src, &blend);
/* TRIANGLE_GET_TEXTCOORD interpolates up to the max values included, so reduce by 1 */
{
SDL_Rect srcrect;
int maxx, maxy;
bounding_rect(s0, s1, s2, &srcrect);
maxx = srcrect.x + srcrect.w;
maxy = srcrect.y + srcrect.h;
if (srcrect.w > 0) {
if (s0->x == maxx) {
s0->x--;
}
if (s1->x == maxx) {
s1->x--;
}
if (s2->x == maxx) {
s2->x--;
}
}
if (srcrect.h > 0) {
if (s0->y == maxy) {
s0->y--;
}
if (s1->y == maxy) {
s1->y--;
}
if (s2->y == maxy) {
s2->y--;
}
}
}
if (is_uniform) {
// SDL_GetSurfaceColorMod(src, &r, &g, &b);
has_modulation = c0.r != 255 || c0.g != 255 || c0.b != 255 || c0.a != 255;
} else {
has_modulation = SDL_TRUE;
}
{
/* Clip triangle rect with surface rect */
SDL_Rect rect;
rect.x = 0;
rect.y = 0;
rect.w = dst->w;
rect.h = dst->h;
SDL_GetRectIntersection(&dstrect, &rect, &dstrect);
}
{
/* Clip triangle with surface clip rect */
SDL_Rect rect;
SDL_GetSurfaceClipRect(dst, &rect);
SDL_GetRectIntersection(&dstrect, &rect, &dstrect);
}
/* Set destination pointer */
dstbpp = dst->format->BytesPerPixel;
dst_ptr = (Uint8 *)dst->pixels + dstrect.x * dstbpp + dstrect.y * dst->pitch;
dst_pitch = dst->pitch;
/* Set source pointer */
src_ptr = src->pixels;
src_pitch = src->pitch;
is_clockwise = area > 0;
area = SDL_abs(area);
d2d1_y = (d1->y - d2->y) << FP_BITS;
d0d2_y = (d2->y - d0->y) << FP_BITS;
d1d0_y = (d0->y - d1->y) << FP_BITS;
d1d2_x = (d2->x - d1->x) << FP_BITS;
d2d0_x = (d0->x - d2->x) << FP_BITS;
d0d1_x = (d1->x - d0->x) << FP_BITS;
s2s0_x = s0->x - s2->x;
s2s1_x = s1->x - s2->x;
s2s0_y = s0->y - s2->y;
s2s1_y = s1->y - s2->y;
/* Starting point for rendering, at the middle of a pixel */
{
SDL_Point p;
p.x = dstrect.x;
p.y = dstrect.y;
trianglepoint_2_fixedpoint(&p);
p.x += (1 << FP_BITS) / 2;
p.y += (1 << FP_BITS) / 2;
w0_row = cross_product(d1, d2, p.x, p.y);
w1_row = cross_product(d2, d0, p.x, p.y);
w2_row = cross_product(d0, d1, p.x, p.y);
}
/* Handle anti-clockwise triangles */
if (!is_clockwise) {
d2d1_y *= -1;
d0d2_y *= -1;
d1d0_y *= -1;
d1d2_x *= -1;
d2d0_x *= -1;
d0d1_x *= -1;
w0_row *= -1;
w1_row *= -1;
w2_row *= -1;
}
/* Add a bias to respect top-left rasterization rule */
bias_w0 = (is_top_left(d1, d2, is_clockwise) ? 0 : -1);
bias_w1 = (is_top_left(d2, d0, is_clockwise) ? 0 : -1);
bias_w2 = (is_top_left(d0, d1, is_clockwise) ? 0 : -1);
/* precompute constant 's2->x * area' used in TRIANGLE_GET_TEXTCOORD */
s2_x_area.x = s2->x * area;
s2_x_area.y = s2->y * area;
if (blend != SDL_BLENDMODE_NONE || src->format->format != dst->format->format || has_modulation || !is_uniform) {
/* Use SDL_BlitTriangle_Slow */
SDL_BlitInfo *info = &src->map->info;
SDL_BlitInfo tmp_info;
SDL_zero(tmp_info);
tmp_info.src_fmt = src->format;
tmp_info.dst_fmt = dst->format;
tmp_info.flags = info->flags;
/*
tmp_info.r = info->r;
tmp_info.g = info->g;
tmp_info.b = info->b;
tmp_info.a = info->a;
*/
tmp_info.r = c0.r;
tmp_info.g = c0.g;
tmp_info.b = c0.b;
tmp_info.a = c0.a;
tmp_info.flags &= ~(SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA);
if (c0.r != 255 || c1.r != 255 || c2.r != 255 ||
c0.g != 255 || c1.g != 255 || c2.g != 255 ||
c0.b != 255 || c1.b != 255 || c2.b != 255) {
tmp_info.flags |= SDL_COPY_MODULATE_COLOR;
}
if (c0.a != 255 || c1.a != 255 || c2.a != 255) {
tmp_info.flags |= SDL_COPY_MODULATE_ALPHA;
}
tmp_info.colorkey = info->colorkey;
/* src */
tmp_info.src = (Uint8 *)src_ptr;
tmp_info.src_pitch = src_pitch;
/* dst */
tmp_info.dst = dst_ptr;
tmp_info.dst_pitch = dst_pitch;
SDL_BlitTriangle_Slow(&tmp_info, s2_x_area, dstrect, area, bias_w0, bias_w1, bias_w2,
d2d1_y, d1d2_x, d0d2_y, d2d0_x, d1d0_y, d0d1_x,
s2s0_x, s2s1_x, s2s0_y, s2s1_y, w0_row, w1_row, w2_row,
c0, c1, c2, is_uniform);
goto end;
}
if (dstbpp == 4) {
TRIANGLE_BEGIN_LOOP
{
TRIANGLE_GET_TEXTCOORD
Uint32 *sptr = (Uint32 *)((Uint8 *)src_ptr + srcy * src_pitch);
*(Uint32 *)dptr = sptr[srcx];
}
TRIANGLE_END_LOOP
} else if (dstbpp == 3) {
TRIANGLE_BEGIN_LOOP
{
TRIANGLE_GET_TEXTCOORD
Uint8 *sptr = (Uint8 *)src_ptr + srcy * src_pitch;
dptr[0] = sptr[3 * srcx];
dptr[1] = sptr[3 * srcx + 1];
dptr[2] = sptr[3 * srcx + 2];
}
TRIANGLE_END_LOOP
} else if (dstbpp == 2) {
TRIANGLE_BEGIN_LOOP
{
TRIANGLE_GET_TEXTCOORD
Uint16 *sptr = (Uint16 *)((Uint8 *)src_ptr + srcy * src_pitch);
*(Uint16 *)dptr = sptr[srcx];
}
TRIANGLE_END_LOOP
} else if (dstbpp == 1) {
TRIANGLE_BEGIN_LOOP
{
TRIANGLE_GET_TEXTCOORD
Uint8 *sptr = (Uint8 *)src_ptr + srcy * src_pitch;
*dptr = sptr[srcx];
}
TRIANGLE_END_LOOP
}
end:
if (dst_locked) {
SDL_UnlockSurface(dst);
}
if (src_locked) {
SDL_UnlockSurface(src);
}
return ret;
}
#define FORMAT_ALPHA 0
#define FORMAT_NO_ALPHA -1
#define FORMAT_2101010 1
#define FORMAT_HAS_ALPHA(format) format == 0
#define FORMAT_HAS_NO_ALPHA(format) format < 0
static int detect_format(SDL_PixelFormat *pf)
{
if (pf->format == SDL_PIXELFORMAT_ARGB2101010) {
return FORMAT_2101010;
} else if (pf->Amask) {
return FORMAT_ALPHA;
} else {
return FORMAT_NO_ALPHA;
}
}
static void SDL_BlitTriangle_Slow(SDL_BlitInfo *info,
SDL_Point s2_x_area, SDL_Rect dstrect, int area, int bias_w0, int bias_w1, int bias_w2,
int d2d1_y, int d1d2_x, int d0d2_y, int d2d0_x, int d1d0_y, int d0d1_x,
int s2s0_x, int s2s1_x, int s2s0_y, int s2s1_y, int w0_row, int w1_row, int w2_row,
SDL_Color c0, SDL_Color c1, SDL_Color c2, int is_uniform)
{
const int flags = info->flags;
Uint32 modulateR = info->r;
Uint32 modulateG = info->g;
Uint32 modulateB = info->b;
Uint32 modulateA = info->a;
Uint32 srcpixel;
Uint32 srcR, srcG, srcB, srcA;
Uint32 dstpixel;
Uint32 dstR, dstG, dstB, dstA;
SDL_PixelFormat *src_fmt = info->src_fmt;
SDL_PixelFormat *dst_fmt = info->dst_fmt;
int srcbpp = src_fmt->BytesPerPixel;
int dstbpp = dst_fmt->BytesPerPixel;
int srcfmt_val;
int dstfmt_val;
Uint32 rgbmask = ~src_fmt->Amask;
Uint32 ckey = info->colorkey & rgbmask;
Uint8 *dst_ptr = info->dst;
int dst_pitch = info->dst_pitch;
srcfmt_val = detect_format(src_fmt);
dstfmt_val = detect_format(dst_fmt);
TRIANGLE_BEGIN_LOOP
{
Uint8 *src;
Uint8 *dst = dptr;
TRIANGLE_GET_TEXTCOORD
src = (info->src + (srcy * info->src_pitch) + (srcx * srcbpp));
if (FORMAT_HAS_ALPHA(srcfmt_val)) {
DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG, srcB, srcA);
} else if (FORMAT_HAS_NO_ALPHA(srcfmt_val)) {
DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG, srcB);
srcA = 0xFF;
} else {
/* SDL_PIXELFORMAT_ARGB2101010 */
srcpixel = *((Uint32 *)(src));
RGBA_FROM_ARGB2101010(srcpixel, srcR, srcG, srcB, srcA);
}
if (flags & SDL_COPY_COLORKEY) {
/* srcpixel isn't set for 24 bpp */
if (srcbpp == 3) {
srcpixel = (srcR << src_fmt->Rshift) |
(srcG << src_fmt->Gshift) | (srcB << src_fmt->Bshift);
}
if ((srcpixel & rgbmask) == ckey) {
continue;
}
}
if (FORMAT_HAS_ALPHA(dstfmt_val)) {
DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB, dstA);
} else if (FORMAT_HAS_NO_ALPHA(dstfmt_val)) {
DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB);
dstA = 0xFF;
} else {
/* SDL_PIXELFORMAT_ARGB2101010 */
dstpixel = *((Uint32 *)(dst));
RGBA_FROM_ARGB2101010(dstpixel, dstR, dstG, dstB, dstA);
}
if (!is_uniform) {
TRIANGLE_GET_COLOR
modulateR = r;
modulateG = g;
modulateB = b;
modulateA = a;
}
if (flags & SDL_COPY_MODULATE_COLOR) {
srcR = (srcR * modulateR) / 255;
srcG = (srcG * modulateG) / 255;
srcB = (srcB * modulateB) / 255;
}
if (flags & SDL_COPY_MODULATE_ALPHA) {
srcA = (srcA * modulateA) / 255;
}
if (flags & (SDL_COPY_BLEND | SDL_COPY_ADD)) {
/* This goes away if we ever use premultiplied alpha */
if (srcA < 255) {
srcR = (srcR * srcA) / 255;
srcG = (srcG * srcA) / 255;
srcB = (srcB * srcA) / 255;
}
}
switch (flags & (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD | SDL_COPY_MUL)) {
case 0:
dstR = srcR;
dstG = srcG;
dstB = srcB;
dstA = srcA;
break;
case SDL_COPY_BLEND:
dstR = srcR + ((255 - srcA) * dstR) / 255;
dstG = srcG + ((255 - srcA) * dstG) / 255;
dstB = srcB + ((255 - srcA) * dstB) / 255;
dstA = srcA + ((255 - srcA) * dstA) / 255;
break;
case SDL_COPY_ADD:
dstR = srcR + dstR;
if (dstR > 255) {
dstR = 255;
}
dstG = srcG + dstG;
if (dstG > 255) {
dstG = 255;
}
dstB = srcB + dstB;
if (dstB > 255) {
dstB = 255;
}
break;
case SDL_COPY_MOD:
dstR = (srcR * dstR) / 255;
dstG = (srcG * dstG) / 255;
dstB = (srcB * dstB) / 255;
break;
case SDL_COPY_MUL:
dstR = ((srcR * dstR) + (dstR * (255 - srcA))) / 255;
if (dstR > 255) {
dstR = 255;
}
dstG = ((srcG * dstG) + (dstG * (255 - srcA))) / 255;
if (dstG > 255) {
dstG = 255;
}
dstB = ((srcB * dstB) + (dstB * (255 - srcA))) / 255;
if (dstB > 255) {
dstB = 255;
}
break;
}
if (FORMAT_HAS_ALPHA(dstfmt_val)) {
ASSEMBLE_RGBA(dst, dstbpp, dst_fmt, dstR, dstG, dstB, dstA);
} else if (FORMAT_HAS_NO_ALPHA(dstfmt_val)) {
ASSEMBLE_RGB(dst, dstbpp, dst_fmt, dstR, dstG, dstB);
} else {
/* SDL_PIXELFORMAT_ARGB2101010 */
Uint32 pixel;
ARGB2101010_FROM_RGBA(pixel, dstR, dstG, dstB, dstA);
*(Uint32 *)dst = pixel;
}
}
TRIANGLE_END_LOOP
}
#endif /* SDL_VIDEO_RENDER_SW && !SDL_RENDER_DISABLED */

View File

@ -0,0 +1,40 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_triangle_h_
#define SDL_triangle_h_
#include "SDL_internal.h"
extern int SDL_SW_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_SW_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 trianglepoint_2_fixedpoint(SDL_Point *a);
#endif /* SDL_triangle_h_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,177 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_VIDEO_RENDER_VITA_GXM
#include "SDL_render_vita_gxm_memory.h"
void *vita_mem_alloc(unsigned int type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid)
{
void *mem;
if (type == SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW) {
size = ALIGN(size, 256 * 1024);
} else {
size = ALIGN(size, 4 * 1024);
}
*uid = sceKernelAllocMemBlock("gpu_mem", type, size, NULL);
if (*uid < 0) {
return NULL;
}
if (sceKernelGetMemBlockBase(*uid, &mem) < 0) {
return NULL;
}
if (sceGxmMapMemory(mem, size, attribs) < 0) {
return NULL;
}
return mem;
}
void vita_mem_free(SceUID uid)
{
void *mem = NULL;
if (sceKernelGetMemBlockBase(uid, &mem) < 0) {
return;
}
sceGxmUnmapMemory(mem);
sceKernelFreeMemBlock(uid);
}
void *vita_gpu_mem_alloc(VITA_GXM_RenderData *data, unsigned int size)
{
void *mem;
if (data->texturePool == NULL) {
int poolsize;
int ret;
SceKernelFreeMemorySizeInfo info;
info.size = sizeof(SceKernelFreeMemorySizeInfo);
sceKernelGetFreeMemorySize(&info);
poolsize = ALIGN(info.size_cdram, 256 * 1024);
if (poolsize > info.size_cdram) {
poolsize = ALIGN(info.size_cdram - 256 * 1024, 256 * 1024);
}
data->texturePoolUID = sceKernelAllocMemBlock("gpu_texture_pool", SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, poolsize, NULL);
if (data->texturePoolUID < 0) {
return NULL;
}
ret = sceKernelGetMemBlockBase(data->texturePoolUID, &mem);
if (ret < 0) {
return NULL;
}
data->texturePool = sceClibMspaceCreate(mem, poolsize);
if (data->texturePool == NULL) {
return NULL;
}
ret = sceGxmMapMemory(mem, poolsize, SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE);
if (ret < 0) {
return NULL;
}
}
return sceClibMspaceMemalign(data->texturePool, SCE_GXM_TEXTURE_ALIGNMENT, size);
}
void vita_gpu_mem_free(VITA_GXM_RenderData *data, void *ptr)
{
if (data->texturePool != NULL) {
sceClibMspaceFree(data->texturePool, ptr);
}
}
void vita_gpu_mem_destroy(VITA_GXM_RenderData *data)
{
void *mem = NULL;
if (data->texturePool != NULL) {
sceClibMspaceDestroy(data->texturePool);
data->texturePool = NULL;
if (sceKernelGetMemBlockBase(data->texturePoolUID, &mem) < 0) {
return;
}
sceGxmUnmapMemory(mem);
sceKernelFreeMemBlock(data->texturePoolUID);
}
}
void *vita_mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset)
{
void *mem = NULL;
size = ALIGN(size, 4096);
*uid = sceKernelAllocMemBlock("vertex_usse", SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, size, NULL);
if (sceKernelGetMemBlockBase(*uid, &mem) < 0) {
return NULL;
}
if (sceGxmMapVertexUsseMemory(mem, size, usse_offset) < 0) {
return NULL;
}
return mem;
}
void vita_mem_vertex_usse_free(SceUID uid)
{
void *mem = NULL;
if (sceKernelGetMemBlockBase(uid, &mem) < 0) {
return;
}
sceGxmUnmapVertexUsseMemory(mem);
sceKernelFreeMemBlock(uid);
}
void *vita_mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset)
{
void *mem = NULL;
size = ALIGN(size, 4096);
*uid = sceKernelAllocMemBlock("fragment_usse", SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, size, NULL);
if (sceKernelGetMemBlockBase(*uid, &mem) < 0) {
return NULL;
}
if (sceGxmMapFragmentUsseMemory(mem, size, usse_offset) < 0) {
return NULL;
}
return mem;
}
void vita_mem_fragment_usse_free(SceUID uid)
{
void *mem = NULL;
if (sceKernelGetMemBlockBase(uid, &mem) < 0) {
return;
}
sceGxmUnmapFragmentUsseMemory(mem);
sceKernelFreeMemBlock(uid);
}
#endif /* SDL_VIDEO_RENDER_VITA_GXM */

View File

@ -0,0 +1,42 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_RENDER_VITA_GXM_MEMORY_H
#define SDL_RENDER_VITA_GXM_MEMORY_H
#include <psp2/gxm.h>
#include <psp2/types.h>
#include <psp2/kernel/sysmem.h>
#include "SDL_render_vita_gxm_types.h"
#define ALIGN(x, a) (((x) + ((a)-1)) & ~((a)-1))
void *vita_mem_alloc(unsigned int type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid);
void vita_mem_free(SceUID uid);
void *vita_gpu_mem_alloc(VITA_GXM_RenderData *data, unsigned int size);
void vita_gpu_mem_free(VITA_GXM_RenderData *data, void *ptr);
void vita_gpu_mem_destroy(VITA_GXM_RenderData *data);
void *vita_mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset);
void vita_mem_vertex_usse_free(SceUID uid);
void *vita_mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset);
void vita_mem_fragment_usse_free(SceUID uid);
#endif /* SDL_RENDER_VITA_GXM_MEMORY_H */

View File

@ -0,0 +1,282 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_RENDER_VITA_GXM_SHADERS_H
#define SDL_RENDER_VITA_GXM_SHADERS_H
#include <psp2/gxm.h>
/* *INDENT-OFF* */ /* clang-format off */
#define gxm_shader_clear_f_size 232
static const unsigned char gxm_shader_clear_f[gxm_shader_clear_f_size] = {
0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03,
0xe8, 0x00, 0x00, 0x00, 0xa2, 0x55, 0x22, 0x3e,
0xc6, 0x7e, 0x77, 0xf1, 0x01, 0x00, 0x18, 0x00,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0xa4, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,
0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x68, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x5c, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04,
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x07, 0x44, 0xfa, 0x02, 0x80, 0x19, 0xf0,
0x7e, 0x0d, 0x80, 0x40, 0x0e, 0x00, 0x00, 0x00,
0x00, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00,
0x01, 0xe4, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x75, 0x43, 0x6c, 0x65,
0x61, 0x72, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00,
};
#define gxm_shader_clear_v_size 252
static const unsigned char gxm_shader_clear_v[gxm_shader_clear_v_size] = {
0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03,
0xfa, 0x00, 0x00, 0x00, 0xdc, 0x25, 0x34, 0x74,
0x53, 0x4a, 0x7a, 0x5b, 0x04, 0x00, 0x19, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0xb8, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x74, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x78, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x04,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, 0xfa,
0x01, 0x00, 0x04, 0x90, 0x85, 0x11, 0xa5, 0x08,
0x01, 0x80, 0x56, 0x90, 0x81, 0x11, 0x83, 0x08,
0x00, 0x00, 0x20, 0xa0, 0x00, 0x50, 0x27, 0xfb,
0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x61, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f,
0x6e, 0x00, 0x00, 0x00,
};
#define gxm_shader_color_f_size 212
static const unsigned char gxm_shader_color_f[gxm_shader_color_f_size] = {
0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03,
0xd4, 0x00, 0x00, 0x00, 0x9c, 0xd6, 0x9b, 0xf7,
0x78, 0x00, 0x5d, 0x31, 0x01, 0x10, 0x18, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xac, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,
0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x78, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x6c, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04,
0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x0f, 0xa0, 0xd0, 0x0e, 0x00, 0x00, 0x00, 0x00,
0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x07, 0x44, 0xfa, 0x02, 0x80, 0x19, 0xa0,
0x7e, 0x0d, 0x80, 0x40,
};
#define gxm_shader_color_v_size 368
static const unsigned char gxm_shader_color_v[gxm_shader_color_v_size] = {
0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03,
0x6d, 0x01, 0x00, 0x00, 0x09, 0xce, 0x4e, 0xc2,
0xe1, 0xcd, 0x24, 0xbc, 0x00, 0x00, 0x19, 0x00,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
0x08, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00,
0x98, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x74, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0xb8, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x06, 0x43, 0x00, 0x61,
0x86, 0x81, 0xa2, 0x00, 0x07, 0x53, 0x40, 0x61,
0x86, 0x81, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x01, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, 0xfa,
0x80, 0x00, 0x08, 0x83, 0x21, 0x1d, 0x80, 0x38,
0x00, 0x00, 0xf0, 0x83, 0x20, 0x0d, 0x80, 0x38,
0x0a, 0x84, 0xb9, 0xff, 0xbc, 0x0d, 0xc0, 0x40,
0x02, 0x11, 0x45, 0xcf, 0x80, 0x8f, 0xb1, 0x18,
0x00, 0x11, 0x01, 0xc0, 0x81, 0x81, 0xb1, 0x18,
0x01, 0xd1, 0x42, 0xc0, 0x81, 0x81, 0xb1, 0x18,
0x40, 0x00, 0x10, 0x41, 0x09, 0x05, 0x82, 0x38,
0x00, 0x00, 0x20, 0xa0, 0x00, 0x50, 0x27, 0xfb,
0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
0x30, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x2a, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x21, 0x00, 0x00, 0x00, 0x01, 0xe4, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x61, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f,
0x6e, 0x00, 0x61, 0x43, 0x6f, 0x6c, 0x6f, 0x72,
0x00, 0x77, 0x76, 0x70, 0x00, 0x00, 0x00, 0x00,
};
#define gxm_shader_texture_f_size 288
static const unsigned char gxm_shader_texture_f[gxm_shader_texture_f_size] = {
0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03,
0x20, 0x01, 0x00, 0x00, 0xeb, 0x4f, 0xb5, 0xba,
0x60, 0xb2, 0xd0, 0x8d, 0x05, 0x18, 0x18, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0xc4, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00,
0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x78, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x84, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00,
0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04,
0x01, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00,
0x00, 0xa9, 0xd0, 0x0e, 0x00, 0x00, 0x00, 0x00,
0xf0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x07, 0x44, 0xfa, 0x00, 0x00, 0x00, 0x00,
0x40, 0x09, 0x00, 0xf8, 0x02, 0x80, 0x99, 0xaf,
0xbc, 0x0d, 0xc0, 0x40, 0x06, 0x82, 0xb9, 0xaf,
0xbc, 0x0d, 0x80, 0x40, 0x7c, 0x0f, 0x04, 0x00,
0x86, 0x47, 0xa4, 0x10, 0x30, 0x00, 0x00, 0x00,
0x02, 0x04, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x00,
};
#define gxm_shader_texture_v_size 400
static const unsigned char gxm_shader_texture_v[gxm_shader_texture_v_size] = {
0x47, 0x58, 0x50, 0x00, 0x01, 0x05, 0x50, 0x03,
0x8f, 0x01, 0x00, 0x00, 0x60, 0x1e, 0x69, 0x97,
0x82, 0x7e, 0x0c, 0xac, 0x00, 0x00, 0x19, 0x00,
0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x08, 0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
0x0c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00,
0x98, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x74, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0xc0, 0x00, 0x00, 0x00, 0xc0, 0x3d, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x33, 0x0f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x0a,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x06, 0x43, 0x00, 0x61,
0x86, 0x81, 0xa2, 0x00, 0x07, 0x53, 0x40, 0x61,
0x86, 0x81, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x01, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x44, 0xfa,
0x01, 0x0e, 0x01, 0x01, 0x02, 0x00, 0x10, 0xfa,
0x80, 0x00, 0x08, 0x83, 0x21, 0x25, 0x80, 0x38,
0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x14, 0xfa,
0x00, 0x00, 0xf0, 0x83, 0x20, 0x0d, 0x80, 0x38,
0x0a, 0x84, 0xb9, 0xff, 0xbc, 0x0d, 0xc0, 0x40,
0x02, 0x11, 0x45, 0xcf, 0x80, 0x8f, 0xb1, 0x18,
0x00, 0x11, 0x01, 0xc0, 0x81, 0x81, 0xb1, 0x18,
0x01, 0xd1, 0x42, 0xc0, 0x81, 0x81, 0xb1, 0x18,
0x00, 0x00, 0x20, 0xa0, 0x00, 0x50, 0x27, 0xfb,
0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
0x40, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3a, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x34, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x2b, 0x00, 0x00, 0x00, 0x01, 0xe4, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x61, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f,
0x6e, 0x00, 0x61, 0x54, 0x65, 0x78, 0x63, 0x6f,
0x6f, 0x72, 0x64, 0x00, 0x61, 0x43, 0x6f, 0x6c,
0x6f, 0x72, 0x00, 0x77, 0x76, 0x70, 0x00, 0x00,
};
/* *INDENT-ON* */ /* clang-format on */
static const SceGxmProgram *const clearVertexProgramGxp = (const SceGxmProgram *)gxm_shader_clear_v;
static const SceGxmProgram *const clearFragmentProgramGxp = (const SceGxmProgram *)gxm_shader_clear_f;
static const SceGxmProgram *const colorVertexProgramGxp = (const SceGxmProgram *)gxm_shader_color_v;
static const SceGxmProgram *const colorFragmentProgramGxp = (const SceGxmProgram *)gxm_shader_color_f;
static const SceGxmProgram *const textureVertexProgramGxp = (const SceGxmProgram *)gxm_shader_texture_v;
static const SceGxmProgram *const textureFragmentProgramGxp = (const SceGxmProgram *)gxm_shader_texture_f;
#endif // SDL_RENDER_VITA_GXM_SHADERS_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,63 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_RENDER_VITA_GXM_TOOLS_H
#define SDL_RENDER_VITA_GXM_TOOLS_H
#include "SDL_internal.h"
#include "../SDL_sysrender.h"
#include <psp2/kernel/processmgr.h>
#include <psp2/appmgr.h>
#include <psp2/display.h>
#include <psp2/gxm.h>
#include <psp2/types.h>
#include <psp2/kernel/sysmem.h>
#include "SDL_render_vita_gxm_types.h"
void init_orthographic_matrix(float *m, float left, float right, float bottom, float top, float near, float far);
void *pool_malloc(VITA_GXM_RenderData *data, unsigned int size);
void *pool_memalign(VITA_GXM_RenderData *data, unsigned int size, unsigned int alignment);
void set_clip_rectangle(VITA_GXM_RenderData *data, int x_min, int y_min, int x_max, int y_max);
void unset_clip_rectangle(VITA_GXM_RenderData *data);
int gxm_init(SDL_Renderer *renderer);
void gxm_finish(SDL_Renderer *renderer);
gxm_texture *create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget, unsigned int *return_w, unsigned int *return_h, unsigned int *return_pitch, float *return_wscale);
void free_gxm_texture(VITA_GXM_RenderData *data, gxm_texture *texture);
void gxm_texture_set_filters(gxm_texture *texture, SceGxmTextureFilter min_filter, SceGxmTextureFilter mag_filter);
SceGxmTextureFormat gxm_texture_get_format(const gxm_texture *texture);
void *gxm_texture_get_datap(const gxm_texture *texture);
void gxm_minimal_init_for_common_dialog(void);
void gxm_minimal_term_for_common_dialog(void);
void gxm_init_for_common_dialog(void);
void gxm_swap_for_common_dialog(void);
void gxm_term_for_common_dialog(void);
#endif /* SDL_RENDER_VITA_GXM_TOOLS_H */

View File

@ -0,0 +1,211 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_RENDER_VITA_GXM_TYPES_H
#define SDL_RENDER_VITA_GXM_TYPES_H
#include "SDL_internal.h"
#include "../SDL_sysrender.h"
#include <psp2/kernel/processmgr.h>
#include <psp2/appmgr.h>
#include <psp2/display.h>
#include <psp2/gxm.h>
#include <psp2/types.h>
#include <psp2/kernel/sysmem.h>
#include <psp2/kernel/clib.h>
#include <string.h>
#define VITA_GXM_SCREEN_WIDTH 960
#define VITA_GXM_SCREEN_HEIGHT 544
#define VITA_GXM_SCREEN_STRIDE 960
#define VITA_GXM_COLOR_FORMAT SCE_GXM_COLOR_FORMAT_A8B8G8R8
#define VITA_GXM_PIXEL_FORMAT SCE_DISPLAY_PIXELFORMAT_A8B8G8R8
#define VITA_GXM_BUFFERS 3
#define VITA_GXM_PENDING_SWAPS 2
#define VITA_GXM_POOL_SIZE 2 * 1024 * 1024
typedef struct
{
void *address;
Uint8 wait_vblank;
} VITA_GXM_DisplayData;
typedef struct clear_vertex
{
float x;
float y;
} clear_vertex;
typedef struct color_vertex
{
float x;
float y;
SDL_Color color;
} color_vertex;
typedef struct texture_vertex
{
float x;
float y;
float u;
float v;
SDL_Color color;
} texture_vertex;
typedef struct gxm_texture
{
SceGxmTexture gxm_tex;
SceUID data_UID;
SceGxmRenderTarget *gxm_rendertarget;
SceGxmColorSurface gxm_colorsurface;
SceGxmDepthStencilSurface gxm_depthstencil;
SceUID depth_UID;
SDL_bool cdram;
} gxm_texture;
typedef struct fragment_programs
{
SceGxmFragmentProgram *color;
SceGxmFragmentProgram *texture;
} fragment_programs;
typedef struct blend_fragment_programs
{
fragment_programs blend_mode_none;
fragment_programs blend_mode_blend;
fragment_programs blend_mode_add;
fragment_programs blend_mode_mod;
fragment_programs blend_mode_mul;
} blend_fragment_programs;
typedef struct
{
SDL_Rect viewport;
SDL_bool viewport_dirty;
SDL_Texture *texture;
SDL_Texture *target;
SDL_Color color;
SceGxmFragmentProgram *fragment_program;
SceGxmVertexProgram *vertex_program;
int last_command;
SDL_bool cliprect_enabled_dirty;
SDL_bool cliprect_enabled;
SDL_bool cliprect_dirty;
SDL_Rect cliprect;
SDL_bool texturing;
SDL_Color clear_color;
int drawablew;
int drawableh;
} gxm_drawstate_cache;
typedef struct
{
SDL_bool initialized;
SDL_bool drawing;
unsigned int psm;
unsigned int bpp;
int currentBlendMode;
VITA_GXM_DisplayData displayData;
SceUID vdmRingBufferUid;
SceUID vertexRingBufferUid;
SceUID fragmentRingBufferUid;
SceUID fragmentUsseRingBufferUid;
SceGxmContextParams contextParams;
SceGxmContext *gxm_context;
SceGxmRenderTarget *renderTarget;
SceUID displayBufferUid[VITA_GXM_BUFFERS];
void *displayBufferData[VITA_GXM_BUFFERS];
SceGxmColorSurface displaySurface[VITA_GXM_BUFFERS];
SceGxmSyncObject *displayBufferSync[VITA_GXM_BUFFERS];
SceUID depthBufferUid;
SceUID stencilBufferUid;
SceGxmDepthStencilSurface depthSurface;
void *depthBufferData;
void *stencilBufferData;
unsigned int backBufferIndex;
unsigned int frontBufferIndex;
void *pool_addr[2];
SceUID poolUid[2];
unsigned int pool_index;
unsigned int current_pool;
float ortho_matrix[4 * 4];
SceGxmVertexProgram *colorVertexProgram;
SceGxmFragmentProgram *colorFragmentProgram;
SceGxmVertexProgram *textureVertexProgram;
SceGxmFragmentProgram *textureFragmentProgram;
SceGxmProgramParameter *clearClearColorParam;
SceGxmProgramParameter *colorWvpParam;
SceGxmProgramParameter *textureWvpParam;
SceGxmShaderPatcher *shaderPatcher;
SceGxmVertexProgram *clearVertexProgram;
SceGxmFragmentProgram *clearFragmentProgram;
SceGxmShaderPatcherId clearVertexProgramId;
SceGxmShaderPatcherId clearFragmentProgramId;
SceGxmShaderPatcherId colorVertexProgramId;
SceGxmShaderPatcherId colorFragmentProgramId;
SceGxmShaderPatcherId textureVertexProgramId;
SceGxmShaderPatcherId textureFragmentProgramId;
SceUID patcherBufferUid;
SceUID patcherVertexUsseUid;
SceUID patcherFragmentUsseUid;
SceUID clearVerticesUid;
SceUID linearIndicesUid;
clear_vertex *clearVertices;
uint16_t *linearIndices;
blend_fragment_programs blendFragmentPrograms;
gxm_drawstate_cache drawstate;
SceClibMspace texturePool;
SceUID texturePoolUID;
} VITA_GXM_RenderData;
typedef struct
{
gxm_texture *tex;
unsigned int pitch;
unsigned int w;
unsigned int h;
float wscale;
SDL_bool yuv;
SDL_bool nv12;
} VITA_GXM_TextureData;
#endif /* SDL_RENDER_VITA_GXM_TYPES_H */

View File

@ -0,0 +1,4 @@
float4 main( uniform float4 uClearColor) : COLOR
{
return uClearColor;
}

View File

@ -0,0 +1,4 @@
float4 main(float2 aPosition) : POSITION
{
return float4(aPosition, 1.f, 1.f);
}

View File

@ -0,0 +1,4 @@
float4 main(float4 vColor : COLOR)
{
return vColor;
}

View File

@ -0,0 +1,13 @@
void main(
float2 aPosition,
float4 aColor,
uniform float4x4 wvp,
out float4 vPosition : POSITION,
out float4 vColor : COLOR,
out float pSize : PSIZE
)
{
vPosition = mul(float4(aPosition, 1.f, 0.5f), wvp);
vColor = aColor;
pSize = 1.f;
}

View File

@ -0,0 +1,4 @@
float4 main(float2 vTexcoord : TEXCOORD0, float4 vColor : COLOR, uniform sampler2D tex)
{
return tex2D(tex, vTexcoord) * vColor;
}

View File

@ -0,0 +1,14 @@
void main(
float2 aPosition,
float2 aTexcoord,
float4 aColor,
uniform float4x4 wvp,
out float4 vPosition : POSITION,
out float4 vColor : COLOR,
out float2 vTexcoord : TEXCOORD0
)
{
vPosition = mul(float4(aPosition, 1.f, 0.5f), wvp);
vTexcoord = aTexcoord;
vColor = aColor;
}