Atlas - testsprite.c

Home / ext / SDL / test Lines: 1 | Size: 22114 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/* 2 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 3 4 This software is provided 'as-is', without any express or implied 5 warranty. In no event will the authors be held liable for any damages 6 arising from the use of this software. 7 8 Permission is granted to anyone to use this software for any purpose, 9 including commercial applications, and to alter it and redistribute it 10 freely. 11*/ 12/* Simple program: Move N sprites around on the screen as fast as possible */ 13 14#define SDL_MAIN_USE_CALLBACKS 1 15#include <SDL3/SDL_test.h> 16#include <SDL3/SDL_test_common.h> 17#include <SDL3/SDL_main.h> 18#include "testutils.h" 19 20#define NUM_SPRITES 100 21#define MAX_SPEED 1 22 23static SDLTest_CommonState *state; 24static const char *icon = "icon.png"; 25static int num_sprites; 26static SDL_Texture **sprites; 27static bool cycle_color; 28static bool cycle_alpha; 29static int cycle_direction = 1; 30static int current_alpha = 0; 31static int current_color = 0; 32static SDL_FRect *positions; 33static SDL_FRect *velocities; 34static float sprite_w, sprite_h; 35static SDL_BlendMode blendMode = SDL_BLENDMODE_BLEND; 36static Uint64 next_fps_check; 37static Uint32 frames; 38static const int fps_check_delay = 5000; 39static int use_rendergeometry = 0; 40static bool suspend_when_occluded; 41 42/* Number of iterations to move sprites - used for visual tests. */ 43/* -1: infinite random moves (default); >=0: enables N deterministic moves */ 44static int iterations = -1; 45 46void SDL_AppQuit(void *appstate, SDL_AppResult result) 47{ 48 SDL_free(sprites); 49 SDL_free(positions); 50 SDL_free(velocities); 51 SDLTest_CommonQuit(state); 52} 53 54static bool LoadSprite(const char *file) 55{ 56 int i; 57 58 for (i = 0; i < state->num_windows; ++i) { 59 /* This does the SDL_LoadPNG step repeatedly, but that's OK for test code. */ 60 if (sprites[i]) { 61 SDL_DestroyTexture(sprites[i]); 62 } 63 sprites[i] = LoadTexture(state->renderers[i], file, true); 64 if (sprites[i]) { 65 sprite_w = (float)sprites[i]->w; 66 sprite_h = (float)sprites[i]->h; 67 } 68 if (!sprites[i]) { 69 return false; 70 } 71 if (!SDL_SetTextureBlendMode(sprites[i], blendMode)) { 72 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't set blend mode: %s", SDL_GetError()); 73 SDL_DestroyTexture(sprites[i]); 74 return false; 75 } 76 } 77 78 /* We're ready to roll. :) */ 79 return true; 80} 81 82static void MoveSprites(SDL_Renderer *renderer, SDL_Texture *sprite) 83{ 84 int i; 85 SDL_Rect viewport; 86 SDL_FRect temp; 87 SDL_FRect *position, *velocity; 88 89 /* Query the sizes */ 90 SDL_SetRenderViewport(renderer, NULL); 91 SDL_GetRenderSafeArea(renderer, &viewport); 92 SDL_SetRenderViewport(renderer, &viewport); 93 94 /* Cycle the color and alpha, if desired */ 95 if (cycle_color) { 96 current_color += cycle_direction; 97 if (current_color < 0) { 98 current_color = 0; 99 cycle_direction = -cycle_direction; 100 } 101 if (current_color > 255) { 102 current_color = 255; 103 cycle_direction = -cycle_direction; 104 } 105 SDL_SetTextureColorMod(sprite, 255, (Uint8)current_color, 106 (Uint8)current_color); 107 } 108 if (cycle_alpha) { 109 current_alpha += cycle_direction; 110 if (current_alpha < 0) { 111 current_alpha = 0; 112 cycle_direction = -cycle_direction; 113 } 114 if (current_alpha > 255) { 115 current_alpha = 255; 116 cycle_direction = -cycle_direction; 117 } 118 SDL_SetTextureAlphaMod(sprite, (Uint8)current_alpha); 119 } 120 121 /* Draw a gray background */ 122 if (SDL_GetWindowFlags(SDL_GetRenderWindow(renderer)) & SDL_WINDOW_TRANSPARENT) { 123 SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, SDL_ALPHA_TRANSPARENT); 124 } else { 125 SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, SDL_ALPHA_OPAQUE); 126 } 127 SDL_RenderClear(renderer); 128 129 /* Test points */ 130 SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0x00, 0xFF); 131 SDL_RenderPoint(renderer, 0.0f, 0.0f); 132 SDL_RenderPoint(renderer, (float)(viewport.w - 1), 0.0f); 133 SDL_RenderPoint(renderer, 0.0f, (float)(viewport.h - 1)); 134 SDL_RenderPoint(renderer, (float)(viewport.w - 1), (float)(viewport.h - 1)); 135 136 /* Test horizontal and vertical lines */ 137 SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0x00, 0xFF); 138 SDL_RenderLine(renderer, 1.0f, 0.0f, (float)(viewport.w - 2), 0.0f); 139 SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0x00, 0xFF); 140 SDL_RenderLine(renderer, 1.0f, (float)(viewport.h - 1), (float)(viewport.w - 2), (float)(viewport.h - 1)); 141 SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0xFF, 0xFF); 142 SDL_RenderLine(renderer, 0.0f, 1.0f, 0.0f, (float)(viewport.h - 2)); 143 SDL_RenderLine(renderer, (float)(viewport.w - 1), 1.0f, (float)(viewport.w - 1), (float)(viewport.h - 2)); 144 145 /* Test fill and copy */ 146 SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF); 147 temp.x = 1.0f; 148 temp.y = 1.0f; 149 temp.w = sprite_w; 150 temp.h = sprite_h; 151 if (use_rendergeometry == 0) { 152 SDL_RenderFillRect(renderer, &temp); 153 } else { 154 /* Draw two triangles, filled, uniform */ 155 SDL_FColor color; 156 SDL_Vertex verts[3]; 157 SDL_zeroa(verts); 158 color.r = 1.0f; 159 color.g = 1.0f; 160 color.b = 1.0f; 161 color.a = 1.0f; 162 163 verts[0].position.x = temp.x; 164 verts[0].position.y = temp.y; 165 verts[0].color = color; 166 167 verts[1].position.x = temp.x + temp.w; 168 verts[1].position.y = temp.y; 169 verts[1].color = color; 170 171 verts[2].position.x = temp.x + temp.w; 172 verts[2].position.y = temp.y + temp.h; 173 verts[2].color = color; 174 175 SDL_RenderGeometry(renderer, NULL, verts, 3, NULL, 0); 176 177 verts[1].position.x = temp.x; 178 verts[1].position.y = temp.y + temp.h; 179 verts[1].color = color; 180 181 SDL_RenderGeometry(renderer, NULL, verts, 3, NULL, 0); 182 } 183 SDL_RenderTexture(renderer, sprite, NULL, &temp); 184 temp.x = viewport.w - sprite_w - 1; 185 temp.y = 1.0f; 186 temp.w = sprite_w; 187 temp.h = sprite_h; 188 SDL_RenderFillRect(renderer, &temp); 189 SDL_RenderTexture(renderer, sprite, NULL, &temp); 190 temp.x = 1.0f; 191 temp.y = viewport.h - sprite_h - 1; 192 temp.w = sprite_w; 193 temp.h = sprite_h; 194 SDL_RenderFillRect(renderer, &temp); 195 SDL_RenderTexture(renderer, sprite, NULL, &temp); 196 temp.x = viewport.w - sprite_w - 1; 197 temp.y = viewport.h - sprite_h - 1; 198 temp.w = sprite_w; 199 temp.h = sprite_h; 200 SDL_RenderFillRect(renderer, &temp); 201 SDL_RenderTexture(renderer, sprite, NULL, &temp); 202 203 /* Test diagonal lines */ 204 SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0x00, 0xFF); 205 SDL_RenderLine(renderer, sprite_w, sprite_h, 206 viewport.w - sprite_w - 2, viewport.h - sprite_h - 2); 207 SDL_RenderLine(renderer, viewport.w - sprite_w - 2, sprite_h, 208 sprite_w, viewport.h - sprite_h - 2); 209 210 /* Conditionally move the sprites, bounce at the wall */ 211 if (iterations == -1 || iterations > 0) { 212 for (i = 0; i < num_sprites; ++i) { 213 position = &positions[i]; 214 velocity = &velocities[i]; 215 position->x += velocity->x; 216 if ((position->x < 0) || (position->x >= (viewport.w - sprite_w))) { 217 velocity->x = -velocity->x; 218 position->x += velocity->x; 219 } 220 position->y += velocity->y; 221 if ((position->y < 0) || (position->y >= (viewport.h - sprite_h))) { 222 velocity->y = -velocity->y; 223 position->y += velocity->y; 224 } 225 } 226 227 /* Countdown sprite-move iterations and disable color changes at iteration end - used for visual tests. */ 228 if (iterations > 0) { 229 iterations--; 230 if (iterations == 0) { 231 cycle_alpha = false; 232 cycle_color = false; 233 } 234 } 235 } 236 237 /* Draw sprites */ 238 if (use_rendergeometry == 0) { 239 for (i = 0; i < num_sprites; ++i) { 240 position = &positions[i]; 241 242 /* Blit the sprite onto the screen */ 243 SDL_RenderTexture(renderer, sprite, NULL, position); 244 } 245 } else if (use_rendergeometry == 1) { 246 /* 247 * 0--1 248 * | /| 249 * |/ | 250 * 3--2 251 * 252 * Draw sprite2 as triangles that can be recombined as rect by software renderer 253 */ 254 SDL_Vertex *verts = (SDL_Vertex *)SDL_malloc(num_sprites * sizeof(SDL_Vertex) * 6); 255 SDL_Vertex *verts2 = verts; 256 if (verts) { 257 SDL_FColor color; 258 SDL_GetTextureColorModFloat(sprite, &color.r, &color.g, &color.b); 259 SDL_GetTextureAlphaModFloat(sprite, &color.a); 260 for (i = 0; i < num_sprites; ++i) { 261 position = &positions[i]; 262 /* 0 */ 263 verts->position.x = position->x; 264 verts->position.y = position->y; 265 verts->color = color; 266 verts->tex_coord.x = 0.0f; 267 verts->tex_coord.y = 0.0f; 268 verts++; 269 /* 1 */ 270 verts->position.x = position->x + position->w; 271 verts->position.y = position->y; 272 verts->color = color; 273 verts->tex_coord.x = 1.0f; 274 verts->tex_coord.y = 0.0f; 275 verts++; 276 /* 2 */ 277 verts->position.x = position->x + position->w; 278 verts->position.y = position->y + position->h; 279 verts->color = color; 280 verts->tex_coord.x = 1.0f; 281 verts->tex_coord.y = 1.0f; 282 verts++; 283 /* 0 */ 284 verts->position.x = position->x; 285 verts->position.y = position->y; 286 verts->color = color; 287 verts->tex_coord.x = 0.0f; 288 verts->tex_coord.y = 0.0f; 289 verts++; 290 /* 2 */ 291 verts->position.x = position->x + position->w; 292 verts->position.y = position->y + position->h; 293 verts->color = color; 294 verts->tex_coord.x = 1.0f; 295 verts->tex_coord.y = 1.0f; 296 verts++; 297 /* 3 */ 298 verts->position.x = position->x; 299 verts->position.y = position->y + position->h; 300 verts->color = color; 301 verts->tex_coord.x = 0.0f; 302 verts->tex_coord.y = 1.0f; 303 verts++; 304 } 305 306 /* Blit sprites as triangles onto the screen */ 307 SDL_RenderGeometry(renderer, sprite, verts2, num_sprites * 6, NULL, 0); 308 SDL_free(verts2); 309 } 310 } else if (use_rendergeometry == 2) { 311 /* 0-----1 312 * |\ A /| 313 * | \ / | 314 * |D 2 B| 315 * | / \ | 316 * |/ C \| 317 * 3-----4 318 * 319 * Draw sprite2 as triangles that can *not* be recombined as rect by software renderer 320 * Use an 'indices' array 321 */ 322 SDL_Vertex *verts = (SDL_Vertex *)SDL_malloc(num_sprites * sizeof(SDL_Vertex) * 5); 323 SDL_Vertex *verts2 = verts; 324 int *indices = (int *)SDL_malloc(num_sprites * sizeof(int) * 4 * 3); 325 int *indices2 = indices; 326 if (verts && indices) { 327 int pos = 0; 328 SDL_FColor color; 329 SDL_GetTextureColorModFloat(sprite, &color.r, &color.g, &color.b); 330 SDL_GetTextureAlphaModFloat(sprite, &color.a); 331 for (i = 0; i < num_sprites; ++i) { 332 position = &positions[i]; 333 /* 0 */ 334 verts->position.x = position->x; 335 verts->position.y = position->y; 336 verts->color = color; 337 verts->tex_coord.x = 0.0f; 338 verts->tex_coord.y = 0.0f; 339 verts++; 340 /* 1 */ 341 verts->position.x = position->x + position->w; 342 verts->position.y = position->y; 343 verts->color = color; 344 verts->tex_coord.x = 1.0f; 345 verts->tex_coord.y = 0.0f; 346 verts++; 347 /* 2 */ 348 verts->position.x = position->x + position->w / 2.0f; 349 verts->position.y = position->y + position->h / 2.0f; 350 verts->color = color; 351 verts->tex_coord.x = 0.5f; 352 verts->tex_coord.y = 0.5f; 353 verts++; 354 /* 3 */ 355 verts->position.x = position->x; 356 verts->position.y = position->y + position->h; 357 verts->color = color; 358 verts->tex_coord.x = 0.0f; 359 verts->tex_coord.y = 1.0f; 360 verts++; 361 /* 4 */ 362 verts->position.x = position->x + position->w; 363 verts->position.y = position->y + position->h; 364 verts->color = color; 365 verts->tex_coord.x = 1.0f; 366 verts->tex_coord.y = 1.0f; 367 verts++; 368 /* A */ 369 *indices++ = pos + 0; 370 *indices++ = pos + 1; 371 *indices++ = pos + 2; 372 /* B */ 373 *indices++ = pos + 1; 374 *indices++ = pos + 2; 375 *indices++ = pos + 4; 376 /* C */ 377 *indices++ = pos + 3; 378 *indices++ = pos + 2; 379 *indices++ = pos + 4; 380 /* D */ 381 *indices++ = pos + 3; 382 *indices++ = pos + 2; 383 *indices++ = pos + 0; 384 pos += 5; 385 } 386 } 387 388 /* Blit sprites as triangles onto the screen */ 389 SDL_RenderGeometry(renderer, sprite, verts2, num_sprites * 5, indices2, num_sprites * 4 * 3); 390 SDL_free(verts2); 391 SDL_free(indices2); 392 } 393 394 /* Update the screen! */ 395 SDL_RenderPresent(renderer); 396} 397 398SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[]) 399{ 400 SDL_Rect safe_area; 401 int i; 402 Uint64 seed; 403 404 /* Initialize parameters */ 405 num_sprites = NUM_SPRITES; 406 407 /* Initialize test framework */ 408 state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO); 409 if (!state) { 410 return SDL_APP_FAILURE; 411 } 412 413 for (i = 1; i < argc;) { 414 int consumed; 415 416 consumed = SDLTest_CommonArg(state, i); 417 if (consumed == 0) { 418 consumed = -1; 419 if (SDL_strcasecmp(argv[i], "--blend") == 0) { 420 if (argv[i + 1]) { 421 if (SDL_strcasecmp(argv[i + 1], "none") == 0) { 422 blendMode = SDL_BLENDMODE_NONE; 423 consumed = 2; 424 } else if (SDL_strcasecmp(argv[i + 1], "blend") == 0) { 425 blendMode = SDL_BLENDMODE_BLEND; 426 consumed = 2; 427 } else if (SDL_strcasecmp(argv[i + 1], "blend_premultiplied") == 0) { 428 blendMode = SDL_BLENDMODE_BLEND_PREMULTIPLIED; 429 consumed = 2; 430 } else if (SDL_strcasecmp(argv[i + 1], "add") == 0) { 431 blendMode = SDL_BLENDMODE_ADD; 432 consumed = 2; 433 } else if (SDL_strcasecmp(argv[i + 1], "add_premultiplied") == 0) { 434 blendMode = SDL_BLENDMODE_ADD_PREMULTIPLIED; 435 consumed = 2; 436 } else if (SDL_strcasecmp(argv[i + 1], "mod") == 0) { 437 blendMode = SDL_BLENDMODE_MOD; 438 consumed = 2; 439 } else if (SDL_strcasecmp(argv[i + 1], "mul") == 0) { 440 blendMode = SDL_BLENDMODE_MUL; 441 consumed = 2; 442 } else if (SDL_strcasecmp(argv[i + 1], "sub") == 0) { 443 blendMode = SDL_ComposeCustomBlendMode(SDL_BLENDFACTOR_SRC_ALPHA, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_SUBTRACT, SDL_BLENDFACTOR_ZERO, SDL_BLENDFACTOR_ONE, SDL_BLENDOPERATION_SUBTRACT); 444 consumed = 2; 445 } 446 } 447 } else if (SDL_strcasecmp(argv[i], "--iterations") == 0) { 448 if (argv[i + 1]) { 449 iterations = SDL_atoi(argv[i + 1]); 450 if (iterations < -1) { 451 iterations = -1; 452 } 453 consumed = 2; 454 } 455 } else if (SDL_strcasecmp(argv[i], "--cyclecolor") == 0) { 456 cycle_color = true; 457 consumed = 1; 458 } else if (SDL_strcasecmp(argv[i], "--cyclealpha") == 0) { 459 cycle_alpha = true; 460 consumed = 1; 461 } else if (SDL_strcasecmp(argv[i], "--suspend-when-occluded") == 0) { 462 suspend_when_occluded = true; 463 consumed = 1; 464 } else if (SDL_strcasecmp(argv[i], "--use-rendergeometry") == 0) { 465 if (argv[i + 1]) { 466 if (SDL_strcasecmp(argv[i + 1], "mode1") == 0) { 467 /* Draw sprite2 as triangles that can be recombined as rect by software renderer */ 468 use_rendergeometry = 1; 469 } else if (SDL_strcasecmp(argv[i + 1], "mode2") == 0) { 470 /* Draw sprite2 as triangles that can *not* be recombined as rect by software renderer 471 * Use an 'indices' array */ 472 use_rendergeometry = 2; 473 } else { 474 return SDL_APP_FAILURE; 475 } 476 } 477 consumed = 2; 478 } else if (SDL_isdigit(*argv[i])) { 479 num_sprites = SDL_atoi(argv[i]); 480 consumed = 1; 481 } else if (argv[i][0] != '-') { 482 icon = argv[i]; 483 consumed = 1; 484 } 485 } 486 if (consumed < 0) { 487 static const char *options[] = { 488 "[--blend none|blend|blend_premultiplied|add|add_premultiplied|mod|mul|sub]", 489 "[--cyclecolor]", 490 "[--cyclealpha]", 491 "[--suspend-when-occluded]", 492 "[--iterations N]", 493 "[--use-rendergeometry mode1|mode2]", 494 "[num_sprites]", 495 "[icon.png]", 496 NULL 497 }; 498 SDLTest_CommonLogUsage(state, argv[0], options); 499 return SDL_APP_FAILURE; 500 } 501 i += consumed; 502 } 503 if (!SDLTest_CommonInit(state)) { 504 return SDL_APP_FAILURE; 505 } 506 507 /* Create the windows, initialize the renderers, and load the textures */ 508 sprites = 509 (SDL_Texture **)SDL_calloc(state->num_windows, sizeof(*sprites)); 510 if (!sprites) { 511 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!"); 512 return SDL_APP_FAILURE; 513 } 514 for (i = 0; i < state->num_windows; ++i) { 515 SDL_Renderer *renderer = state->renderers[i]; 516 SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF); 517 SDL_RenderClear(renderer); 518 } 519 if (!LoadSprite(icon)) { 520 return SDL_APP_FAILURE; 521 } 522 523 /* Allocate memory for the sprite info */ 524 positions = (SDL_FRect *)SDL_malloc(num_sprites * sizeof(*positions)); 525 velocities = (SDL_FRect *)SDL_malloc(num_sprites * sizeof(*velocities)); 526 if (!positions || !velocities) { 527 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!"); 528 return SDL_APP_FAILURE; 529 } 530 531 /* Position sprites and set their velocities using the fuzzer */ 532 /* Really we should be using per-window safe area, but this is fine for a simple test */ 533 SDL_GetRenderSafeArea(state->renderers[0], &safe_area); 534 if (iterations >= 0) { 535 /* Deterministic seed - used for visual tests */ 536 seed = (Uint64)iterations; 537 } else { 538 /* Pseudo-random seed generated from the time */ 539 seed = SDL_GetPerformanceCounter(); 540 } 541 SDLTest_FuzzerInit(seed); 542 for (i = 0; i < num_sprites; ++i) { 543 positions[i].x = (float)SDLTest_RandomIntegerInRange(0, (int)(safe_area.w - sprite_w)); 544 positions[i].y = (float)SDLTest_RandomIntegerInRange(0, (int)(safe_area.h - sprite_h)); 545 positions[i].w = sprite_w; 546 positions[i].h = sprite_h; 547 velocities[i].x = 0; 548 velocities[i].y = 0; 549 while (velocities[i].x == 0.f && velocities[i].y == 0.f) { 550 velocities[i].x = (float)SDLTest_RandomIntegerInRange(-MAX_SPEED, MAX_SPEED); 551 velocities[i].y = (float)SDLTest_RandomIntegerInRange(-MAX_SPEED, MAX_SPEED); 552 } 553 } 554 555 /* Main render loop in SDL_AppIterate will begin when this function returns. */ 556 frames = 0; 557 next_fps_check = SDL_GetTicks() + fps_check_delay; 558 559 return SDL_APP_CONTINUE; 560} 561 562 563SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) 564{ 565 if (event->type == SDL_EVENT_RENDER_DEVICE_RESET) { 566 LoadSprite(icon); 567 } 568 return SDLTest_CommonEventMainCallbacks(state, event); 569} 570 571SDL_AppResult SDL_AppIterate(void *appstate) 572{ 573 Uint64 now; 574 int i; 575 int active_windows = 0; 576 577 for (i = 0; i < state->num_windows; ++i) { 578 if (state->windows[i] == NULL || 579 (suspend_when_occluded && (SDL_GetWindowFlags(state->windows[i]) & SDL_WINDOW_OCCLUDED))) { 580 continue; 581 } 582 ++active_windows; 583 MoveSprites(state->renderers[i], sprites[i]); 584 } 585 586 /* If all windows are occluded, throttle the event polling to 15hz. */ 587 if (!active_windows) { 588 SDL_DelayNS(SDL_NS_PER_SECOND / 15); 589 } 590 591 frames++; 592 now = SDL_GetTicks(); 593 if (now >= next_fps_check) { 594 /* Print out some timing information */ 595 const Uint64 then = next_fps_check - fps_check_delay; 596 const double fps = ((double)frames * 1000) / (now - then); 597 SDL_Log("%2.2f frames per second", fps); 598 next_fps_check = now + fps_check_delay; 599 frames = 0; 600 } 601 602 return SDL_APP_CONTINUE; 603} 604
[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.