Atlas - SDL_render_ngage.c
Home / ext / SDL / src / render / ngage Lines: 1 | Size: 18189 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20*/ 21#include "SDL_internal.h" 22 23#ifdef SDL_VIDEO_RENDER_NGAGE 24 25#ifndef M_PI 26#define M_PI 3.14159265358979323846 27#endif 28 29#ifndef Int2Fix 30#define Int2Fix(i) ((i) << 16) 31#endif 32 33#ifndef Fix2Int 34#define Fix2Int(i) ((((unsigned int)(i) > 0xFFFF0000) ? 0 : ((i) >> 16))) 35#endif 36 37#ifndef Fix2Real 38#define Fix2Real(i) ((i) / 65536.0) 39#endif 40 41#ifndef Real2Fix 42#define Real2Fix(i) ((int)((i) * 65536.0)) 43#endif 44 45#include "../SDL_sysrender.h" 46#include "SDL_render_ngage_c.h" 47 48static void NGAGE_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event); 49static bool NGAGE_GetOutputSize(SDL_Renderer *renderer, int *w, int *h); 50static bool NGAGE_SupportsBlendMode(SDL_Renderer *renderer, SDL_BlendMode blendMode); 51static bool NGAGE_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_PropertiesID create_props); 52static bool NGAGE_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd); 53static bool NGAGE_QueueSetDrawColor(SDL_Renderer *renderer, SDL_RenderCommand *cmd); 54static bool NGAGE_QueueDrawVertices(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count); 55static bool NGAGE_QueueFillRects(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FRect *rects, int count); 56static bool NGAGE_QueueCopy(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const SDL_FRect *srcrect, const SDL_FRect *dstrect); 57static bool NGAGE_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_FlipMode flip, float scale_x, float scale_y); 58static bool NGAGE_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const float *xy, int xy_stride, const SDL_FColor *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); 59 60static void NGAGE_InvalidateCachedState(SDL_Renderer *renderer); 61static bool NGAGE_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize); 62static bool NGAGE_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch); 63 64static bool NGAGE_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch); 65static void NGAGE_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture); 66static bool NGAGE_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture); 67static SDL_Surface *NGAGE_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect); 68static bool NGAGE_RenderPresent(SDL_Renderer *renderer); 69static void NGAGE_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture); 70 71static void NGAGE_DestroyRenderer(SDL_Renderer *renderer); 72 73static bool NGAGE_SetVSync(SDL_Renderer *renderer, int vsync); 74 75static bool NGAGE_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_PropertiesID create_props) 76{ 77 SDL_SetupRendererColorspace(renderer, create_props); 78 79 if (renderer->output_colorspace != SDL_COLORSPACE_RGB_DEFAULT) { 80 return SDL_SetError("Unsupported output colorspace"); 81 } 82 83 NGAGE_RendererData *phdata = SDL_calloc(1, sizeof(NGAGE_RendererData)); 84 if (!phdata) { 85 SDL_OutOfMemory(); 86 return false; 87 } 88 89 renderer->WindowEvent = NGAGE_WindowEvent; 90 renderer->GetOutputSize = NGAGE_GetOutputSize; 91 renderer->SupportsBlendMode = NGAGE_SupportsBlendMode; 92 renderer->CreateTexture = NGAGE_CreateTexture; 93 renderer->QueueSetViewport = NGAGE_QueueSetViewport; 94 renderer->QueueSetDrawColor = NGAGE_QueueSetDrawColor; 95 renderer->QueueDrawPoints = NGAGE_QueueDrawVertices; 96 renderer->QueueDrawLines = NGAGE_QueueDrawVertices; 97 renderer->QueueFillRects = NGAGE_QueueFillRects; 98 renderer->QueueCopy = NGAGE_QueueCopy; 99 renderer->QueueCopyEx = NGAGE_QueueCopyEx; 100 renderer->QueueGeometry = NGAGE_QueueGeometry; 101 renderer->InvalidateCachedState = NGAGE_InvalidateCachedState; 102 renderer->RunCommandQueue = NGAGE_RunCommandQueue; 103 renderer->UpdateTexture = NGAGE_UpdateTexture; 104 renderer->LockTexture = NGAGE_LockTexture; 105 renderer->UnlockTexture = NGAGE_UnlockTexture; 106 renderer->SetRenderTarget = NGAGE_SetRenderTarget; 107 renderer->RenderReadPixels = NGAGE_RenderReadPixels; 108 renderer->RenderPresent = NGAGE_RenderPresent; 109 renderer->DestroyTexture = NGAGE_DestroyTexture; 110 renderer->DestroyRenderer = NGAGE_DestroyRenderer; 111 renderer->SetVSync = NGAGE_SetVSync; 112 113 renderer->name = NGAGE_RenderDriver.name; 114 renderer->window = window; 115 renderer->internal = phdata; 116 renderer->npot_texture_wrap_unsupported = true; 117 118 SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_XRGB4444); 119 SDL_SetNumberProperty(SDL_GetRendererProperties(renderer), SDL_PROP_RENDERER_MAX_TEXTURE_SIZE_NUMBER, 1024); 120 SDL_SetHintWithPriority(SDL_HINT_RENDER_LINE_METHOD, "2", SDL_HINT_OVERRIDE); 121 122 return true; 123} 124 125SDL_RenderDriver NGAGE_RenderDriver = { 126 NGAGE_CreateRenderer, 127 "N-Gage" 128}; 129 130static void NGAGE_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event) 131{ 132 return; 133} 134 135static bool NGAGE_GetOutputSize(SDL_Renderer *renderer, int *w, int *h) 136{ 137 return true; 138} 139 140static bool NGAGE_SupportsBlendMode(SDL_Renderer *renderer, SDL_BlendMode blendMode) 141{ 142 switch (blendMode) { 143 case SDL_BLENDMODE_NONE: 144 case SDL_BLENDMODE_MOD: 145 return true; 146 default: 147 return false; 148 } 149} 150 151static bool NGAGE_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_PropertiesID create_props) 152{ 153 NGAGE_TextureData *data = (NGAGE_TextureData *)SDL_calloc(1, sizeof(*data)); 154 if (!data) { 155 return false; 156 } 157 158 if (!NGAGE_CreateTextureData(data, texture->w, texture->h)) { 159 SDL_free(data); 160 return false; 161 } 162 163 SDL_Surface *surface = SDL_CreateSurface(texture->w, texture->h, texture->format); 164 if (!surface) { 165 SDL_free(data); 166 return false; 167 } 168 169 data->surface = surface; 170 texture->internal = data; 171 172 return true; 173} 174 175static bool NGAGE_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd) 176{ 177 if (!cmd->data.viewport.rect.w && !cmd->data.viewport.rect.h) { 178 SDL_Rect viewport = { 0, 0, NGAGE_SCREEN_WIDTH, NGAGE_SCREEN_HEIGHT }; 179 SDL_SetRenderViewport(renderer, &viewport); 180 } 181 182 return true; 183} 184 185static bool NGAGE_QueueSetDrawColor(SDL_Renderer *renderer, SDL_RenderCommand *cmd) 186{ 187 return true; 188} 189 190static bool NGAGE_QueueDrawVertices(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count) 191{ 192 NGAGE_Vertex *verts = (NGAGE_Vertex *)SDL_AllocateRenderVertices(renderer, count * sizeof(NGAGE_Vertex), 0, &cmd->data.draw.first); 193 if (!verts) { 194 return false; 195 } 196 197 cmd->data.draw.count = count; 198 199 for (int i = 0; i < count; i++, points++) { 200 int fixed_x = Real2Fix(points->x); 201 int fixed_y = Real2Fix(points->y); 202 203 verts[i].x = Fix2Int(fixed_x); 204 verts[i].y = Fix2Int(fixed_y); 205 206 Uint32 color = NGAGE_ConvertColor(cmd->data.draw.color.r, cmd->data.draw.color.g, cmd->data.draw.color.b, cmd->data.draw.color.a, cmd->data.draw.color_scale); 207 208 verts[i].color.a = (Uint8)(color >> 24); 209 verts[i].color.b = (Uint8)(color >> 16); 210 verts[i].color.g = (Uint8)(color >> 8); 211 verts[i].color.r = (Uint8)color; 212 } 213 214 return true; 215} 216 217static bool NGAGE_QueueFillRects(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FRect *rects, int count) 218{ 219 NGAGE_Vertex *verts = (NGAGE_Vertex *)SDL_AllocateRenderVertices(renderer, count * 2 * sizeof(NGAGE_Vertex), 0, &cmd->data.draw.first); 220 if (!verts) { 221 return false; 222 } 223 224 cmd->data.draw.count = count; 225 226 for (int i = 0; i < count; i++, rects++) { 227 verts[i * 2].x = Real2Fix(rects->x); 228 verts[i * 2].y = Real2Fix(rects->y); 229 verts[i * 2 + 1].x = Real2Fix(rects->w); 230 verts[i * 2 + 1].y = Real2Fix(rects->h); 231 232 verts[i * 2].x = Fix2Int(verts[i * 2].x); 233 verts[i * 2].y = Fix2Int(verts[i * 2].y); 234 verts[i * 2 + 1].x = Fix2Int(verts[i * 2 + 1].x); 235 verts[i * 2 + 1].y = Fix2Int(verts[i * 2 + 1].y); 236 237 Uint32 color = NGAGE_ConvertColor(cmd->data.draw.color.r, cmd->data.draw.color.g, cmd->data.draw.color.b, cmd->data.draw.color.a, cmd->data.draw.color_scale); 238 239 verts[i * 2].color.a = (Uint8)(color >> 24); 240 verts[i * 2].color.b = (Uint8)(color >> 16); 241 verts[i * 2].color.g = (Uint8)(color >> 8); 242 verts[i * 2].color.r = (Uint8)color; 243 } 244 245 return true; 246} 247 248static bool NGAGE_QueueCopy(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const SDL_FRect *srcrect, const SDL_FRect *dstrect) 249{ 250 SDL_Rect *verts = (SDL_Rect *)SDL_AllocateRenderVertices(renderer, 2 * sizeof(SDL_Rect), 0, &cmd->data.draw.first); 251 252 if (!verts) { 253 return false; 254 } 255 256 cmd->data.draw.count = 1; 257 258 verts->x = (int)srcrect->x; 259 verts->y = (int)srcrect->y; 260 verts->w = (int)srcrect->w; 261 verts->h = (int)srcrect->h; 262 263 verts++; 264 265 verts->x = (int)dstrect->x; 266 verts->y = (int)dstrect->y; 267 verts->w = (int)dstrect->w; 268 verts->h = (int)dstrect->h; 269 270 return true; 271} 272 273static bool NGAGE_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_FlipMode flip, float scale_x, float scale_y) 274{ 275 NGAGE_CopyExData *verts = (NGAGE_CopyExData *)SDL_AllocateRenderVertices(renderer, sizeof(NGAGE_CopyExData), 0, &cmd->data.draw.first); 276 277 if (!verts) { 278 return false; 279 } 280 281 cmd->data.draw.count = 1; 282 283 verts->srcrect.x = (int)srcquad->x; 284 verts->srcrect.y = (int)srcquad->y; 285 verts->srcrect.w = (int)srcquad->w; 286 verts->srcrect.h = (int)srcquad->h; 287 verts->dstrect.x = (int)dstrect->x; 288 verts->dstrect.y = (int)dstrect->y; 289 verts->dstrect.w = (int)dstrect->w; 290 verts->dstrect.h = (int)dstrect->h; 291 292 verts->angle = Real2Fix(angle); 293 verts->center.x = Real2Fix(center->x); 294 verts->center.y = Real2Fix(center->y); 295 verts->scale_x = Real2Fix(scale_x); 296 verts->scale_y = Real2Fix(scale_y); 297 298 verts->flip = flip; 299 300 return true; 301} 302 303static bool NGAGE_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const float *xy, int xy_stride, const SDL_FColor *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) 304{ 305 return true; 306} 307 308static void NGAGE_InvalidateCachedState(SDL_Renderer *renderer) 309{ 310 return; 311} 312 313static bool NGAGE_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize) 314{ 315 NGAGE_RendererData *phdata = (NGAGE_RendererData *)renderer->internal; 316 if (!phdata) { 317 return false; 318 } 319 phdata->viewport = 0; 320 321 while (cmd) { 322 switch (cmd->command) { 323 case SDL_RENDERCMD_NO_OP: 324 break; 325 case SDL_RENDERCMD_SETVIEWPORT: 326 phdata->viewport = &cmd->data.viewport.rect; 327 break; 328 329 case SDL_RENDERCMD_SETCLIPRECT: 330 { 331 const SDL_Rect *rect = &cmd->data.cliprect.rect; 332 333 if (cmd->data.cliprect.enabled) { 334 NGAGE_SetClipRect(rect); 335 } 336 337 break; 338 } 339 340 case SDL_RENDERCMD_SETDRAWCOLOR: 341 { 342 break; 343 } 344 345 case SDL_RENDERCMD_CLEAR: 346 { 347 Uint32 color = NGAGE_ConvertColor(cmd->data.color.color.r, cmd->data.color.color.g, cmd->data.color.color.b, cmd->data.color.color.a, cmd->data.color.color_scale); 348 349 NGAGE_Clear(color); 350 break; 351 } 352 353 case SDL_RENDERCMD_DRAW_POINTS: 354 { 355 NGAGE_Vertex *verts = (NGAGE_Vertex *)(((Uint8 *)vertices) + cmd->data.draw.first); 356 const int count = cmd->data.draw.count; 357 358 // Apply viewport. 359 if (phdata->viewport && (phdata->viewport->x || phdata->viewport->y)) { 360 for (int i = 0; i < count; i++) { 361 verts[i].x += phdata->viewport->x; 362 verts[i].y += phdata->viewport->y; 363 } 364 } 365 366 NGAGE_DrawPoints(verts, count); 367 break; 368 } 369 case SDL_RENDERCMD_DRAW_LINES: 370 { 371 NGAGE_Vertex *verts = (NGAGE_Vertex *)(((Uint8 *)vertices) + cmd->data.draw.first); 372 const int count = cmd->data.draw.count; 373 374 // Apply viewport. 375 if (phdata->viewport && (phdata->viewport->x || phdata->viewport->y)) { 376 for (int i = 0; i < count; i++) { 377 verts[i].x += phdata->viewport->x; 378 verts[i].y += phdata->viewport->y; 379 } 380 } 381 382 NGAGE_DrawLines(verts, count); 383 break; 384 } 385 386 case SDL_RENDERCMD_FILL_RECTS: 387 { 388 NGAGE_Vertex *verts = (NGAGE_Vertex *)(((Uint8 *)vertices) + cmd->data.draw.first); 389 const int count = cmd->data.draw.count; 390 391 // Apply viewport. 392 if (phdata->viewport && (phdata->viewport->x || phdata->viewport->y)) { 393 for (int i = 0; i < count; i++) { 394 verts[i].x += phdata->viewport->x; 395 verts[i].y += phdata->viewport->y; 396 } 397 } 398 399 NGAGE_FillRects(verts, count); 400 break; 401 } 402 403 case SDL_RENDERCMD_COPY: 404 { 405 SDL_Rect *verts = (SDL_Rect *)(((Uint8 *)vertices) + cmd->data.draw.first); 406 SDL_Rect *srcrect = verts; 407 SDL_Rect *dstrect = verts + 1; 408 SDL_Texture *texture = cmd->data.draw.texture; 409 410 // Apply viewport. 411 if (phdata->viewport && (phdata->viewport->x || phdata->viewport->y)) { 412 dstrect->x += phdata->viewport->x; 413 dstrect->y += phdata->viewport->y; 414 } 415 416 NGAGE_Copy(renderer, texture, srcrect, dstrect); 417 break; 418 } 419 420 case SDL_RENDERCMD_COPY_EX: 421 { 422 NGAGE_CopyExData *copydata = (NGAGE_CopyExData *)(((Uint8 *)vertices) + cmd->data.draw.first); 423 SDL_Texture *texture = cmd->data.draw.texture; 424 425 // Apply viewport. 426 if (phdata->viewport && (phdata->viewport->x || phdata->viewport->y)) { 427 copydata->dstrect.x += phdata->viewport->x; 428 copydata->dstrect.y += phdata->viewport->y; 429 } 430 431 NGAGE_CopyEx(renderer, texture, copydata); 432 break; 433 } 434 435 case SDL_RENDERCMD_GEOMETRY: 436 { 437 break; 438 } 439 } 440 cmd = cmd->next; 441 } 442 443 return true; 444} 445 446static bool NGAGE_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch) 447{ 448 NGAGE_TextureData *phdata = (NGAGE_TextureData *)texture->internal; 449 450 SDL_Surface *surface = phdata->surface; 451 Uint8 *src, *dst; 452 int row; 453 size_t length; 454 455 if (SDL_MUSTLOCK(surface)) { 456 if (!SDL_LockSurface(surface)) { 457 return false; 458 } 459 } 460 src = (Uint8 *)pixels; 461 dst = (Uint8 *)surface->pixels + 462 rect->y * surface->pitch + 463 rect->x * surface->fmt->bytes_per_pixel; 464 465 length = (size_t)rect->w * surface->fmt->bytes_per_pixel; 466 for (row = 0; row < rect->h; ++row) { 467 SDL_memcpy(dst, src, length); 468 src += pitch; 469 dst += surface->pitch; 470 } 471 if (SDL_MUSTLOCK(surface)) { 472 SDL_UnlockSurface(surface); 473 } 474 475 return true; 476} 477 478static bool NGAGE_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch) 479{ 480 NGAGE_TextureData *phdata = (NGAGE_TextureData *)texture->internal; 481 SDL_Surface *surface = phdata->surface; 482 483 *pixels = 484 (void *)((Uint8 *)surface->pixels + rect->y * surface->pitch + 485 rect->x * surface->fmt->bytes_per_pixel); 486 *pitch = surface->pitch; 487 return true; 488} 489 490static void NGAGE_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture) 491{ 492} 493 494static bool NGAGE_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture) 495{ 496 return true; 497} 498 499static SDL_Surface *NGAGE_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rect *rect) 500{ 501 return (SDL_Surface *)0; 502} 503 504static bool NGAGE_RenderPresent(SDL_Renderer *renderer) 505{ 506 NGAGE_Flip(); 507 508 return true; 509} 510 511static void NGAGE_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture) 512{ 513 NGAGE_TextureData *data = (NGAGE_TextureData *)texture->internal; 514 if (data) { 515 SDL_DestroySurface(data->surface); 516 NGAGE_DestroyTextureData(data); 517 SDL_free(data); 518 texture->internal = 0; 519 } 520} 521 522static void NGAGE_DestroyRenderer(SDL_Renderer *renderer) 523{ 524 NGAGE_RendererData *phdata = (NGAGE_RendererData *)renderer->internal; 525 if (phdata) { 526 SDL_free(phdata); 527 renderer->internal = 0; 528 } 529} 530 531static bool NGAGE_SetVSync(SDL_Renderer *renderer, int vsync) 532{ 533 return true; 534} 535 536#endif // SDL_VIDEO_RENDER_NGAGE 537[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.