/* * System Interface Library for games * Copyright (c) 2007-2020 Andrew Church * Released under the GNU GPL version 3 or later; NO WARRANTY is provided. * See the file COPYING.txt for details. * * src/test/graphics/texture.c: Tests for the high-level texture * manipulation routines. */ /* * This file does not include tests for texture_set_repeat() and * texture_set_antialias() (other than invalid-argument tests); those are * tested as part of the primitive rendering tests in graphics/primitive.c. */ #include "src/base.h" #include "src/graphics.h" #include "src/math.h" #include "src/memory.h" #include "src/sysdep.h" #include "src/test/base.h" #include "src/test/graphics/internal.h" #include "src/texture.h" /*************************************************************************/ /******************************* Test data *******************************/ /*************************************************************************/ /* Texture ID guaranteed to be invalid across all tests. */ #define INVALID_TEXTURE 10000 /*-----------------------------------------------------------------------*/ /* Raw RGBA data for 4x4 textures. */ static const uint8_t rgba_4x4[] = { 0, 0, 0, 0, 4, 0, 4, 16, 8, 0, 8, 32, 12, 0, 12, 48, 0, 64, 64, 64, 4, 64, 68, 80, 8, 64, 72, 96, 12, 64, 76,112, 0,128,128,128, 4,128,132,144, 8,128,136,160, 12,128,140,176, 0,192,192,192, 4,192,196,208, 8,192,200,224, 12,192,204,240, }; /* Opaque bitmap data, as converted to RGB by texture_lock_readonly(). */ static const uint8_t opaque_pixels[] = { 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,255,255,255, 255,255,255,255, 0, 0, 0, 0,255,255,255,255, 0, 0, 0, 0, 255,255,255,255,255,255,255,255, 0, 0, 0, 0, 0, 0, 0, 0, }; /* Raw RGBA data for textures of different formats. */ static const uint8_t rgba_4x4_rgb565[] = { 0, 0, 0,255, 8, 0, 8,255, 25, 0, 25,255, 41, 0, 41,255, 0, 65, 66,255, 8, 65, 74,255, 25, 65, 91,255, 41, 65,107,255, 0,130,132,255, 8,130,140,255, 25,130,157,255, 41,130,173,255, 0,195,198,255, 8,195,206,255, 25,195,223,255, 41,195,239,255, }; static const uint8_t rgba_4x4_rgba5551[] = { 0, 0, 0, 0, 8, 0, 8,255, 25, 0, 25, 0, 41, 0, 41,255, 0, 66, 66, 0, 8, 66, 74, 0, 25, 66, 91,255, 41, 66,107,255, 0,132,132,255, 8,132,140, 0, 25,132,157,255, 41,132,173, 0, 0,198,198,255, 8,198,206,255, 25,198,223, 0, 41,198,239, 0, }; static const uint8_t rgba_4x4_rgba4444[] = { 0, 0, 0, 0, 17, 0, 17,136, 34, 0, 34, 68, 51, 0, 51,204, 0, 68, 68, 34, 17, 68, 85,170, 34, 68,102,102, 51, 68,119,238, 0,136,136, 17, 17,136,153,153, 34,136,170, 85, 51,136,187,221, 0,204,204, 51, 17,204,221,187, 34,204,238,119, 51,204,255,255, }; static const uint8_t rgba_4x4_alpha[] = { 255,255,255, 0,255,255,255, 16,255,255,255, 32,255,255,255, 48, 255,255,255, 64,255,255,255, 80,255,255,255, 96,255,255,255,112, 255,255,255,128,255,255,255,144,255,255,255,160,255,255,255,176, 255,255,255,192,255,255,255,208,255,255,255,224,255,255,255,240, }; static const uint8_t rgba_4x4_luminance[] = { 0, 0, 0,255, 16, 16, 16,255, 32, 32, 32,255, 48, 48, 48,255, 64, 64, 64,255, 80, 80, 80,255, 96, 96, 96,255,112,112,112,255, 128,128,128,255,144,144,144,255,160,160,160,255,176,176,176,255, 192,192,192,255,208,208,208,255,224,224,224,255,240,240,240,255, }; static const uint8_t rgba_8x16_psp[] = { 0, 0, 0, 0, 4, 0, 4, 16, 8, 0, 8, 32, 12, 0, 12, 48, 128, 0, 0, 0,132, 0, 4, 16,136, 0, 8, 32,140, 0, 12, 48, 0, 64, 64, 64, 4, 64, 68, 80, 8, 64, 72, 96, 12, 64, 76,112, 128, 64, 64, 64,132, 64, 68, 80,136, 64, 72, 96,140, 64, 76,112, 0,128,128,128, 4,128,132,144, 8,128,136,160, 12,128,140,176, 128,128,128,128,132,128,132,144,136,128,136,160,140,128,140,176, 0,192,192,192, 4,192,196,208, 8,192,200,224, 12,192,204,240, 128,192,192,192,132,192,196,208,136,192,200,224,140,192,204,240, 1, 0, 0, 0, 5, 0, 4, 16, 9, 0, 8, 32, 13, 0, 12, 48, 129, 0, 0, 0,133, 0, 4, 16,137, 0, 8, 32,141, 0, 12, 48, 1, 64, 64, 64, 5, 64, 68, 80, 9, 64, 72, 96, 13, 64, 76,112, 129, 64, 64, 64,133, 64, 68, 80,137, 64, 72, 96,141, 64, 76,112, 1,128,128,128, 5,128,132,144, 9,128,136,160, 13,128,140,176, 129,128,128,128,133,128,132,144,137,128,136,160,141,128,140,176, 1,192,192,192, 5,192,196,208, 9,192,200,224, 13,192,204,240, 129,192,192,192,133,192,196,208,137,192,200,224,141,192,204,240, 2, 0, 0, 0, 6, 0, 4, 16, 10, 0, 8, 32, 14, 0, 12, 48, 130, 0, 0, 0,134, 0, 4, 16,138, 0, 8, 32,142, 0, 12, 48, 2, 64, 64, 64, 6, 64, 68, 80, 10, 64, 72, 96, 14, 64, 76,112, 130, 64, 64, 64,134, 64, 68, 80,138, 64, 72, 96,142, 64, 76,112, 2,128,128,128, 6,128,132,144, 10,128,136,160, 14,128,140,176, 130,128,128,128,134,128,132,144,138,128,136,160,142,128,140,176, 2,192,192,192, 6,192,196,208, 10,192,200,224, 14,192,204,240, 130,192,192,192,134,192,196,208,138,192,200,224,142,192,204,240, 3, 0, 0, 0, 7, 0, 4, 16, 11, 0, 8, 32, 15, 0, 12, 48, 131, 0, 0, 0,135, 0, 4, 16,139, 0, 8, 32,143, 0, 12, 48, 3, 64, 64, 64, 7, 64, 68, 80, 11, 64, 72, 96, 15, 64, 76,112, 131, 64, 64, 64,135, 64, 68, 80,139, 64, 72, 96,143, 64, 76,112, 3,128,128,128, 7,128,132,144, 11,128,136,160, 15,128,140,176, 131,128,128,128,135,128,132,144,139,128,136,160,143,128,140,176, 3,192,192,192, 7,192,196,208, 11,192,200,224, 15,192,204,240, 131,192,192,192,135,192,196,208,139,192,200,224,143,192,204,240, }; static const uint8_t rgba_32x8_psp[] = { 0, 0, 0, 0, 4, 0, 4, 16, 8, 0, 8, 32, 12, 0, 12, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 64, 64, 4, 64, 68, 80, 8, 64, 72, 96, 12, 64, 76,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,128,128, 4,128,132,144, 8,128,136,160, 12,128,140,176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192,192,192, 4,192,196,208, 8,192,200,224, 12,192,204,240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const uint8_t rgba_16x8_psp_rgb565[] = { 0, 0, 0,255, 8, 0, 8,255, 25, 0, 25,255, 41, 0, 41,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 65, 66,255, 8, 65, 74,255, 25, 65, 91,255, 41, 65,107,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0,130,132,255, 8,130,140,255, 25,130,157,255, 41,130,173,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0,195,198,255, 8,195,206,255, 25,195,223,255, 41,195,239,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, }; static const uint8_t rgba_16x8_psp_rgba5551[] = { 0, 0, 0, 0, 8, 0, 8,255, 25, 0, 25, 0, 41, 0, 41,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 66, 0, 8, 66, 74, 0, 25, 66, 91,255, 41, 66,107,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,132,132,255, 8,132,140, 0, 25,132,157,255, 41,132,173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,198,198,255, 8,198,206,255, 25,198,223, 0, 41,198,239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const uint8_t rgba_16x8_psp_rgba4444[] = { 0, 0, 0, 0, 17, 0, 17,136, 34, 0, 34, 68, 51, 0, 51,204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 68, 34, 17, 68, 85,170, 34, 68,102,102, 51, 68,119,238, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,136,136, 17, 17,136,153,153, 34,136,170, 85, 51,136,187,221, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,204,204, 51, 17,204,221,187, 34,204,238,119, 51,204,255,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const uint8_t rgba_32x8_psp_alpha[] = { 255,255,255, 0,255,255,255, 16,255,255,255, 32,255,255,255, 48, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 64,255,255,255, 80,255,255,255, 96,255,255,255,112, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255,128,255,255,255,144,255,255,255,160,255,255,255,176, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255,192,255,255,255,208,255,255,255,224,255,255,255,240, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, 255,255,255, 0,255,255,255, 0,255,255,255, 0,255,255,255, 0, }; static const uint8_t rgba_32x8_psp_luminance[] = { 0, 0, 0,255, 16, 16, 16,255, 32, 32, 32,255, 48, 48, 48,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 64, 64, 64,255, 80, 80, 80,255, 96, 96, 96,255,112,112,112,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 128,128,128,255,144,144,144,255,160,160,160,255,176,176,176,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 192,192,192,255,208,208,208,255,224,224,224,255,240,240,240,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, 0, 0, 0,255, }; static const uint8_t rgba_4x4_dxt1[] = { 8, 0, 0,255, 8, 0, 0,255, 8, 0, 0,255, 8, 0, 0,255, 8, 68, 73,255, 8, 68, 73,255, 8, 68, 73,255, 8, 68, 73,255, 8,130,140,255, 8,130,140,255, 8,130,140,255, 8,130,140,255, 8,199,214,255, 8,199,214,255, 8,199,214,255, 8,199,214,255, }; static const uint8_t rgba_4x4_dxt3[] = { 8, 0, 0, 0, 8, 0, 0, 17, 8, 0, 0, 34, 8, 0, 0, 51, 8, 68, 73, 68, 8, 68, 73, 85, 8, 68, 73,102, 8, 68, 73,119, 8,130,140,136, 8,130,140,153, 8,130,140,170, 8,130,140,187, 8,199,214,204, 8,199,214,221, 8,199,214,238, 8,199,214,255, }; static const uint8_t rgba_4x4_dxt5[] = { 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 34, 8, 0, 0, 34, 8, 68, 73, 68, 8, 68, 73, 68, 8, 68, 73,102, 8, 68, 73,102, 8,130,140,137, 8,130,140,137, 8,130,140,171, 8,130,140,171, 8,199,214,205, 8,199,214,205, 8,199,214,240, 8,199,214,240, }; static const uint8_t rgba_16x16_pvrtc2[] = { 8,181,202,255, 16, 5, 26,255, 8,181,202,255, 16, 7, 30,255, 8,181,202,255, 16, 7, 30,255, 8,181,202,255, 16, 5, 26,255, 8,181,202,255, 16, 3, 22,255, 8,181,202,255, 16, 1, 18,255, 8,181,202,255, 16, 1, 18,255, 8,181,202,255, 16, 3, 22,255, 16, 6, 28,255, 7,180,199,255, 16, 9, 35,255, 5,178,193,255, 16, 12, 41,255, 5,178,193,255, 16, 9, 35,255, 7,180,199,255, 16, 6, 28,255, 9,182,204,255, 16, 3, 22,255, 11,184,209,255, 16, 0, 16,255, 11,184,209,255, 16, 3, 22,255, 9,182,204,255, 16, 8, 33,255, 6,179,196,255, 4,177,191,255, 2,175,186,255, 0,173,181,255, 2,175,186,255, 4,177,191,255, 6,179,196,255, 16, 8, 33,255, 10,183,207,255, 12,185,212,255, 14,187,217,255, 16,189,222,255, 14,187,217,255, 12,185,212,255, 10,183,207,255, 16, 6, 28,255, 16, 7, 31,255, 16, 9, 35,255, 16, 10, 38,255, 16, 12, 41,255, 16, 10, 38,255, 16, 9, 35,255, 16, 7, 31,255, 16, 6, 28,255, 16, 4, 25,255, 16, 3, 22,255, 16, 1, 19,255, 16, 0, 16,255, 16, 1, 19,255, 16, 3, 22,255, 16, 4, 25,255, 8,181,202,255, 16, 5, 26,255, 8,181,202,255, 16, 7, 30,255, 8,181,202,255, 16, 7, 30,255, 8,181,202,255, 16, 5, 26,255, 16, 4, 24,255, 14, 47, 67,255, 13, 69, 88,255, 13, 68, 87,255, 13, 67, 85,255, 13, 68, 87,255, 13, 69, 88,255, 12, 92,112,255, 16, 2, 20,255, 9,182,204,255, 16, 3, 22,255, 11,184,209,255, 16, 4, 24,255, 11,184,209,255, 16, 3, 22,255, 9,182,204,255, 12, 91,111,255, 10,112,131,255, 9,112,129,255, 9,111,127,255, 8,110,125,255, 9,111,127,255, 9,112,129,255, 10,112,131,255, 16, 0, 16,255, 10,183,207,255, 12,185,212,255, 14,187,217,255, 16,189,222,255, 14,187,217,255, 12,185,212,255, 10,183,207,255, 11,113,132,255, 11, 89,106,255, 4,177,191,255, 7,109,122,255, 0,173,181,255, 7,109,122,255, 4,177,191,255, 12, 67, 83,255, 16, 2, 20,255, 16, 2, 21,255, 16, 3, 22,255, 16, 3, 23,255, 16, 4, 24,255, 16, 3, 23,255, 16, 3, 22,255, 16, 2, 21,255, 13, 69, 88,255, 16, 1, 19,255, 11, 90,107,255, 16, 0, 17,255, 10, 88,103,255, 16, 0, 17,255, 11, 90,107,255, 16, 1, 19,255, 8,181,202,255, 16, 5, 26,255, 8,181,202,255, 16, 7, 30,255, 8,181,202,255, 16, 7, 30,255, 8,181,202,255, 16, 5, 26,255, 8,181,202,255, 16, 3, 22,255, 8,181,202,255, 16, 1, 18,255, 8,181,202,255, 16, 1, 18,255, 8,181,202,255, 16, 3, 22,255, 16, 6, 28,255, 7,180,199,255, 16, 9, 35,255, 5,178,193,255, 16, 12, 41,255, 5,178,193,255, 16, 9, 35,255, 7,180,199,255, 16, 6, 28,255, 9,182,204,255, 16, 3, 22,255, 11,184,209,255, 16, 0, 16,255, 11,184,209,255, 16, 3, 22,255, 9,182,204,255, 16, 8, 33,255, 6,179,196,255, 4,177,191,255, 2,175,186,255, 0,173,181,255, 2,175,186,255, 4,177,191,255, 6,179,196,255, 16, 8, 33,255, 10,183,207,255, 12,185,212,255, 14,187,217,255, 16,189,222,255, 14,187,217,255, 12,185,212,255, 10,183,207,255, 16, 6, 28,255, 16, 7, 31,255, 16, 9, 35,255, 16, 10, 38,255, 16, 12, 41,255, 16, 10, 38,255, 16, 9, 35,255, 16, 7, 31,255, 16, 6, 28,255, 16, 4, 25,255, 16, 3, 22,255, 16, 1, 19,255, 16, 0, 16,255, 16, 1, 19,255, 16, 3, 22,255, 16, 4, 25,255, 8,181,202,255, 16, 5, 26,255, 8,181,202,255, 16, 7, 30,255, 8,181,202,255, 16, 7, 30,255, 8,181,202,255, 16, 5, 26,255, 16, 4, 24,255, 14, 47, 67,255, 13, 69, 88,255, 13, 68, 87,255, 13, 67, 85,255, 13, 68, 87,255, 13, 69, 88,255, 12, 92,112,255, 16, 2, 20,255, 9,182,204,255, 16, 3, 22,255, 11,184,209,255, 16, 4, 24,255, 11,184,209,255, 16, 3, 22,255, 9,182,204,255, 12, 91,111,255, 10,112,131,255, 9,112,129,255, 9,111,127,255, 8,110,125,255, 9,111,127,255, 9,112,129,255, 10,112,131,255, 16, 0, 16,255, 10,183,207,255, 12,185,212,255, 14,187,217,255, 16,189,222,255, 14,187,217,255, 12,185,212,255, 10,183,207,255, 11,113,132,255, 11, 89,106,255, 4,177,191,255, 7,109,122,255, 0,173,181,255, 7,109,122,255, 4,177,191,255, 12, 67, 83,255, 16, 2, 20,255, 16, 2, 21,255, 16, 3, 22,255, 16, 3, 23,255, 16, 4, 24,255, 16, 3, 23,255, 16, 3, 22,255, 16, 2, 21,255, 13, 69, 88,255, 16, 1, 19,255, 11, 90,107,255, 16, 0, 17,255, 10, 88,103,255, 16, 0, 17,255, 11, 90,107,255, 16, 1, 19,255, }; static const uint8_t rgba_8x8_pvrtc4[] = { 12, 0, 8, 25, 10, 0, 4, 21, 8, 0, 0, 17, 10, 0, 4, 21, 12, 0, 8, 25, 14, 0, 12, 29, 16, 0, 16, 34, 14, 0, 12, 29, 12, 73, 82, 94, 10, 74, 81, 92, 8, 75, 81, 90, 10, 74, 81, 92, 12, 73, 82, 94, 14, 72, 82, 95, 16, 70, 82, 97, 14, 72, 82, 95, 13,123,133,144, 11,126,136,146, 10,128,138,148, 11,126,136,146, 13,123,133,144, 14,120,131,141, 16,118,128,140, 14,120,131,141, 16,195,212,216, 16,199,215,223, 16,202,218,229, 16,199,215,223, 16,195,212,216, 16,192,209,210, 16,189,206,204, 16,192,209,210, 12, 0, 8, 25, 10, 0, 4, 21, 8, 0, 0, 17, 10, 0, 4, 21, 12, 0, 8, 25, 14, 0, 12, 29, 16, 0, 16, 34, 14, 0, 12, 29, 14, 71, 85, 96, 14, 72, 82, 95, 13, 72, 78, 95, 14, 72, 82, 95, 14, 71, 85, 96, 15, 71, 88, 96, 16, 70, 92, 97, 15, 71, 88, 96, 16,118,134,140, 16,118,131,140, 16,118,128,140, 16,118,131,140, 16,118,134,140, 16,118,137,140, 16,118,141,140, 16,118,137,140, 16,191,208,208, 16,192,209,210, 16,193,210,212, 16,192,209,210, 16,191,208,208, 16,190,207,206, 16,189,206,204, 16,190,207,206, }; static const uint8_t rgba_8x8_pvrtc4_noalpha[] = { 12, 0, 8,255, 10, 0, 4,255, 8, 0, 0,255, 10, 0, 4,255, 12, 0, 8,255, 14, 0, 12,255, 16, 0, 16,255, 14, 0, 12,255, 12, 73, 82,255, 10, 74, 81,255, 8, 75, 81,255, 10, 74, 81,255, 12, 73, 82,255, 14, 72, 82,255, 16, 70, 82,255, 14, 72, 82,255, 13,123,133,255, 11,126,136,255, 10,128,138,255, 11,126,136,255, 13,123,133,255, 14,120,131,255, 16,118,128,255, 14,120,131,255, 16,195,212,255, 16,199,215,255, 16,202,218,255, 16,199,215,255, 16,195,212,255, 16,192,209,255, 16,189,206,255, 16,192,209,255, 12, 0, 8,255, 10, 0, 4,255, 8, 0, 0,255, 10, 0, 4,255, 12, 0, 8,255, 14, 0, 12,255, 16, 0, 16,255, 14, 0, 12,255, 14, 71, 85,255, 14, 72, 82,255, 13, 72, 78,255, 14, 72, 82,255, 14, 71, 85,255, 15, 71, 88,255, 16, 70, 92,255, 15, 71, 88,255, 16,118,134,255, 16,118,131,255, 16,118,128,255, 16,118,131,255, 16,118,134,255, 16,118,137,255, 16,118,141,255, 16,118,137,255, 16,191,208,255, 16,192,209,255, 16,193,210,255, 16,192,209,255, 16,191,208,255, 16,190,207,255, 16,189,206,255, 16,190,207,255, }; /*-----------------------------------------------------------------------*/ static const ALIGNED(4) uint8_t tex_4x4[] = { 'T','E','X', 10, 2, 0, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 16, 8, 0, 8, 32, 12, 0, 12, 48, 0, 64, 64, 64, 4, 64, 68, 80, 8, 64, 72, 96, 12, 64, 76,112, 0,128,128,128, 4,128,132,144, 8,128,136,160, 12,128,140,176, 0,192,192,192, 4,192,196,208, 8,192,200,224, 12,192,204,240, }; static const ALIGNED(4) uint8_t tex_4x4_unaligned[] = { 'T','E','X', 10, 2, 0, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 33, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 16, 8, 0, 8, 32, 12, 0, 12, 48, 0, 64, 64, 64, 4, 64, 68, 80, 8, 64, 72, 96, 12, 64, 76,112, 0,128,128,128, 4,128,132,144, 8,128,136,160, 12,128,140,176, 0,192,192,192, 4,192,196,208, 8,192,200,224, 12,192,204,240, }; static const ALIGNED(4) uint8_t tex_4x4_mipmaps[] = { 'T','E','X', 10, 2, 0, 2, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 32, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 16, 8, 0, 8, 32, 12, 0, 12, 48, 0, 64, 64, 64, 4, 64, 68, 80, 8, 64, 72, 96, 12, 64, 76,112, 0,128,128,128, 4,128,132,144, 8,128,136,160, 12,128,140,176, 0,192,192,192, 4,192,196,208, 8,192,200,224, 12,192,204,240, 2, 32, 34, 40, 10, 32, 42, 72, 2,160,162,168, 10,160,170,200, 6, 96,102,120, }; static const ALIGNED(4) uint8_t tex_4x4_scale_half[] = { 'T','E','X', 10, 2, 0, 0, 0, 0, 4, 0, 4, 0, 0,128, 0, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 16, 8, 0, 8, 32, 12, 0, 12, 48, 0, 64, 64, 64, 4, 64, 68, 80, 8, 64, 72, 96, 12, 64, 76,112, 0,128,128,128, 4,128,132,144, 8,128,136,160, 12,128,140,176, 0,192,192,192, 4,192,196,208, 8,192,200,224, 12,192,204,240, }; static const ALIGNED(4) uint8_t tex_4x4_opaque[] = { 'T','E','X', 10, 2, 0, 0, 1, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 96, 0, 0, 0, 4, 0, 0, 0, 0, 4, 0, 4, 16, 8, 0, 8, 32, 12, 0, 12, 48, 0, 64, 64, 64, 4, 64, 68, 80, 8, 64, 72, 96, 12, 64, 76,112, 0,128,128,128, 4,128,132,144, 8,128,136,160, 12,128,140,176, 0,192,192,192, 4,192,196,208, 8,192,200,224, 12,192,204,240, 10, 12, 5, 3, }; static const ALIGNED(4) uint8_t tex_16x1_opaque[] = { 'T','E','X', 10, 2, 0, 0, 1, 0, 16, 0, 1, 0, 1, 0, 0, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 96, 0, 0, 0, 2, 0, 0, 0, 0, 4, 0, 4, 16, 8, 0, 8, 32, 12, 0, 12, 48, 0, 64, 64, 64, 4, 64, 68, 80, 8, 64, 72, 96, 12, 64, 76,112, 0,128,128,128, 4,128,132,144, 8,128,136,160, 12,128,140,176, 0,192,192,192, 4,192,196,208, 8,192,200,224, 12,192,204,240, 202,53, }; static const ALIGNED(4) uint8_t tex_4x4_rgb565[] = { 'T','E','X', 10, 2, 1, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, #ifdef IS_LITTLE_ENDIAN 0, 0, 1, 8, 3, 24, 5, 40, 0, 66, 1, 74, 3, 90, 5,106, 0,132, 1,140, 3,156, 5,172, 0,198, 1,206, 3,222, 5,238, #else // big endian 0, 0, 8, 1, 24, 3, 40, 5, 66, 0, 74, 1, 90, 3,106, 5, 132, 0,140, 1,156, 3,172, 5,198, 0,206, 1,222, 3,238, 5, #endif }; static const ALIGNED(4) uint8_t tex_4x4_rgb565_unaligned[] = { 'T','E','X', 10, 2, 1, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 33, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, #ifdef IS_LITTLE_ENDIAN 0, 0, 1, 8, 3, 24, 5, 40, 0, 66, 1, 74, 3, 90, 5,106, 0,132, 1,140, 3,156, 5,172, 0,198, 1,206, 3,222, 5,238, #else // big endian 0, 0, 8, 1, 24, 3, 40, 5, 66, 0, 74, 1, 90, 3,106, 5, 132, 0,140, 1,156, 3,172, 5,198, 0,206, 1,222, 3,238, 5, #endif }; static const ALIGNED(4) uint8_t tex_4x4_rgba5551[] = { 'T','E','X', 10, 2, 2, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, #ifdef IS_LITTLE_ENDIAN 0, 0, 1,132, 3, 12, 5,148, 0, 33, 1, 37, 3,173, 5,181, 0,194, 1, 70, 3,206, 5, 86, 0,227, 1,231, 3,111, 5,119, #else // big endian 0, 0,132, 1, 12, 3,148, 5, 33, 0, 37, 1,173, 3,181, 5, 194, 0, 70, 1,206, 3, 86, 5,227, 0,231, 1,111, 3,119, 5, #endif }; static const ALIGNED(4) uint8_t tex_4x4_rgba4444[] = { 'T','E','X', 10, 2, 3, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, #ifdef IS_LITTLE_ENDIAN 0, 0, 1,129, 2, 66, 3,195, 64, 36, 65,165, 66,102, 67,231, 128, 24,129,153,130, 90,131,219,192, 60,193,189,194,126,195,255, #else // big endian 0, 0,129, 1, 66, 2,195, 3, 36, 64,165, 65,102, 66,231, 67, 24,128,153,129, 90,130,219,131, 60,192,189,193,126,194,255,195, #endif }; static const ALIGNED(4) uint8_t tex_4x4_bgra[] = { 'T','E','X', 10, 2, 8, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 16, 8, 0, 8, 32, 12, 0, 12, 48, 64, 64, 0, 64, 68, 64, 4, 80, 72, 64, 8, 96, 76, 64, 12,112, 128,128, 0,128,132,128, 4,144,136,128, 8,160,140,128, 12,176, 192,192, 0,192,196,192, 4,208,200,192, 8,224,204,192, 12,240, }; static const ALIGNED(4) uint8_t tex_4x4_bgr565[] = { 'T','E','X', 10, 2, 9, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, #ifdef IS_LITTLE_ENDIAN 0, 0, 1, 8, 3, 24, 5, 40, 8, 2, 9, 10, 11, 26, 13, 42, 16, 4, 17, 12, 19, 28, 21, 44, 24, 6, 25, 14, 27, 30, 29, 46, #else // big endian 0, 0, 8, 1, 24, 3, 40, 5, 2, 8, 10, 9, 26, 11, 42, 13, 4, 16, 12, 17, 28, 19, 44, 21, 6, 24, 14, 25, 30, 27, 46, 29, #endif }; static const ALIGNED(4) uint8_t tex_4x4_bgra5551[] = { 'T','E','X', 10, 2, 10, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, #ifdef IS_LITTLE_ENDIAN 0, 0, 1,132, 3, 12, 5,148, 8, 1, 9, 5, 11,141, 13,149, 16,130, 17, 6, 19,142, 21, 22, 24,131, 25,135, 27, 15, 29, 23, #else // big endian 0, 0,132, 1, 12, 3,148, 5, 1, 8, 5, 9,141, 11,149, 13, 130, 16, 6, 17,142, 19, 22, 21,131, 24,135, 25, 15, 27, 23, 29, #endif }; static const ALIGNED(4) uint8_t tex_4x4_bgra4444[] = { 'T','E','X', 10, 2, 11, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, #ifdef IS_LITTLE_ENDIAN 0, 0, 1,129, 2, 66, 3,195, 68, 32, 69,161, 70, 98, 71,227, 136, 16,137,145,138, 82,139,211,204, 48,205,177,206,114,207,243, #else // big endian 0, 0,129, 1, 66, 2,195, 3, 32, 68,161, 69, 98, 70,227, 71, 16,136,145,137, 82,138,211,139, 48,204,177,205,114,206,243,207, #endif }; static const ALIGNED(4) uint8_t tex_4x4_alpha[] = { 'T','E','X', 10, 2, 64, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 32, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 32, 48, 64, 80, 96,112,128,144,160,176,192,208,224,240, }; static const ALIGNED(4) uint8_t tex_4x4_luminance[] = { 'T','E','X', 10, 2, 65, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 32, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 32, 48, 64, 80, 96,112,128,144,160,176,192,208,224,240, }; static const ALIGNED(4) uint8_t tex_4x4_psp_rgba8888[] = { 'T','E','X', 10, 2,112, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 16, 8, 0, 8, 32, 12, 0, 12, 48, 0, 64, 64, 64, 4, 64, 68, 80, 8, 64, 72, 96, 12, 64, 76,112, 0,128,128,128, 4,128,132,144, 8,128,136,160, 12,128,140,176, 0,192,192,192, 4,192,196,208, 8,192,200,224, 12,192,204,240, }; static const ALIGNED(4) uint8_t tex_4x4_psp_rgb565[] = { 'T','E','X', 10, 2,113, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, 3, 24, 5, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 1, 74, 3, 90, 5,106, 0, 0, 0, 0, 0, 0, 0, 0, 0,132, 1,140, 3,156, 5,172, 0, 0, 0, 0, 0, 0, 0, 0, 0,198, 1,206, 3,222, 5,238, 0, 0, 0, 0, 0, 0, 0, 0, }; static const ALIGNED(4) uint8_t tex_4x4_psp_rgba5551[] = { 'T','E','X', 10, 2,114, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,132, 3, 12, 5,148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 1, 37, 3,173, 5,181, 0, 0, 0, 0, 0, 0, 0, 0, 0,194, 1, 70, 3,206, 5, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0,227, 1,231, 3,111, 5,119, 0, 0, 0, 0, 0, 0, 0, 0, }; static const ALIGNED(4) uint8_t tex_4x4_psp_rgba4444[] = { 'T','E','X', 10, 2,115, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,129, 2, 66, 3,195, 0, 0, 0, 0, 0, 0, 0, 0, 64, 36, 65,165, 66,102, 67,231, 0, 0, 0, 0, 0, 0, 0, 0, 128, 24,129,153,130, 90,131,219, 0, 0, 0, 0, 0, 0, 0, 0, 192, 60,193,189,194,126,195,255, 0, 0, 0, 0, 0, 0, 0, 0, }; static const ALIGNED(4) uint8_t tex_4x4_psp_alpha[] = { 'T','E','X', 10, 2,116, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 32, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 80, 96,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128,144,160,176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192,208,224,240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const ALIGNED(4) uint8_t tex_4x4_psp_luminance[] = { 'T','E','X', 10, 2,118, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 32, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 80, 96,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128,144,160,176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192,208,224,240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const ALIGNED(4) uint8_t tex_4x4_psp_palette8_rgba8888[] = { 'T','E','X', 10, 2,117, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 64, 0, 0, 4, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 16, 8, 0, 8, 32, 12, 0, 12, 48, 0, 64, 64, 64, 4, 64, 68, 80, 8, 64, 72, 96, 12, 64, 76,112, 0,128,128,128, 4,128,132,144, 8,128,136,160, 12,128,140,176, 0,192,192,192, 4,192,196,208, 8,192,200,224, 12,192,204,240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const ALIGNED(4) uint8_t tex_8x16_psp_rgba8888_swizzled[] = { 'T','E','X', 10, 2,120, 0, 0, 0, 8, 0, 16, 0, 1, 0, 0, 0, 0, 0, 64, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 16, 8, 0, 8, 32, 12, 0, 12, 48, 0, 64, 64, 64, 4, 64, 68, 80, 8, 64, 72, 96, 12, 64, 76,112, 0,128,128,128, 4,128,132,144, 8,128,136,160, 12,128,140,176, 0,192,192,192, 4,192,196,208, 8,192,200,224, 12,192,204,240, 1, 0, 0, 0, 5, 0, 4, 16, 9, 0, 8, 32, 13, 0, 12, 48, 1, 64, 64, 64, 5, 64, 68, 80, 9, 64, 72, 96, 13, 64, 76,112, 1,128,128,128, 5,128,132,144, 9,128,136,160, 13,128,140,176, 1,192,192,192, 5,192,196,208, 9,192,200,224, 13,192,204,240, 128, 0, 0, 0,132, 0, 4, 16,136, 0, 8, 32,140, 0, 12, 48, 128, 64, 64, 64,132, 64, 68, 80,136, 64, 72, 96,140, 64, 76,112, 128,128,128,128,132,128,132,144,136,128,136,160,140,128,140,176, 128,192,192,192,132,192,196,208,136,192,200,224,140,192,204,240, 129, 0, 0, 0,133, 0, 4, 16,137, 0, 8, 32,141, 0, 12, 48, 129, 64, 64, 64,133, 64, 68, 80,137, 64, 72, 96,141, 64, 76,112, 129,128,128,128,133,128,132,144,137,128,136,160,141,128,140,176, 129,192,192,192,133,192,196,208,137,192,200,224,141,192,204,240, 2, 0, 0, 0, 6, 0, 4, 16, 10, 0, 8, 32, 14, 0, 12, 48, 2, 64, 64, 64, 6, 64, 68, 80, 10, 64, 72, 96, 14, 64, 76,112, 2,128,128,128, 6,128,132,144, 10,128,136,160, 14,128,140,176, 2,192,192,192, 6,192,196,208, 10,192,200,224, 14,192,204,240, 3, 0, 0, 0, 7, 0, 4, 16, 11, 0, 8, 32, 15, 0, 12, 48, 3, 64, 64, 64, 7, 64, 68, 80, 11, 64, 72, 96, 15, 64, 76,112, 3,128,128,128, 7,128,132,144, 11,128,136,160, 15,128,140,176, 3,192,192,192, 7,192,196,208, 11,192,200,224, 15,192,204,240, 130, 0, 0, 0,134, 0, 4, 16,138, 0, 8, 32,142, 0, 12, 48, 130, 64, 64, 64,134, 64, 68, 80,138, 64, 72, 96,142, 64, 76,112, 130,128,128,128,134,128,132,144,138,128,136,160,142,128,140,176, 130,192,192,192,134,192,196,208,138,192,200,224,142,192,204,240, 131, 0, 0, 0,135, 0, 4, 16,139, 0, 8, 32,143, 0, 12, 48, 131, 64, 64, 64,135, 64, 68, 80,139, 64, 72, 96,143, 64, 76,112, 131,128,128,128,135,128,132,144,139,128,136,160,143,128,140,176, 131,192,192,192,135,192,196,208,139,192,200,224,143,192,204,240, }; static const ALIGNED(4) uint8_t tex_16x8_psp_rgb565_swizzled[] = { 'T','E','X', 10, 2,121, 0, 0, 0, 16, 0, 8, 0, 1, 0, 0, 0, 0, 0, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, 3, 24, 5, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 1, 74, 3, 90, 5,106, 0, 0, 0, 0, 0, 0, 0, 0, 0,132, 1,140, 3,156, 5,172, 0, 0, 0, 0, 0, 0, 0, 0, 0,198, 1,206, 3,222, 5,238, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const ALIGNED(4) uint8_t tex_16x8_psp_rgba5551_swizzled[] = { 'T','E','X', 10, 2,122, 0, 0, 0, 16, 0, 8, 0, 1, 0, 0, 0, 0, 0, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,132, 3, 12, 5,148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 1, 37, 3,173, 5,181, 0, 0, 0, 0, 0, 0, 0, 0, 0,194, 1, 70, 3,206, 5, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0,227, 1,231, 3,111, 5,119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const ALIGNED(4) uint8_t tex_16x8_psp_rgba4444_swizzled[] = { 'T','E','X', 10, 2,123, 0, 0, 0, 16, 0, 8, 0, 1, 0, 0, 0, 0, 0, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,129, 2, 66, 3,195, 0, 0, 0, 0, 0, 0, 0, 0, 64, 36, 65,165, 66,102, 67,231, 0, 0, 0, 0, 0, 0, 0, 0, 128, 24,129,153,130, 90,131,219, 0, 0, 0, 0, 0, 0, 0, 0, 192, 60,193,189,194,126,195,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const ALIGNED(4) uint8_t tex_32x8_psp_alpha_swizzled[] = { 'T','E','X', 10, 2,124, 0, 0, 0, 32, 0, 8, 0, 1, 0, 0, 0, 0, 0, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 32, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 80, 96,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128,144,160,176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192,208,224,240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const ALIGNED(4) uint8_t tex_32x8_psp_luminance_swizzled[] = { 'T','E','X', 10, 2,126, 0, 0, 0, 32, 0, 8, 0, 1, 0, 0, 0, 0, 0, 64, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 32, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 80, 96,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128,144,160,176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192,208,224,240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const ALIGNED(4) uint8_t tex_32x8_psp_palette8_rgba8888_swizzled[] = { 'T','E','X', 10, 2,125, 0, 0, 0, 32, 0, 8, 0, 1, 0, 0, 0, 0, 0, 64, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 16, 8, 0, 8, 32, 12, 0, 12, 48, 0, 64, 64, 64, 4, 64, 68, 80, 8, 64, 72, 96, 12, 64, 76,112, 0,128,128,128, 4,128,132,144, 8,128,136,160, 12,128,140,176, 0,192,192,192, 4,192,196,208, 8,192,200,224, 12,192,204,240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 1, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 3, 4, 5, 6, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 8, 9, 10, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 11, 12, 13, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, }; static const ALIGNED(4) uint8_t tex_4x4_palette[] = { 'T','E','X', 10, 2,128, 2, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 32, 0, 0, 4, 21, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 16, 8, 0, 8, 32, 12, 0, 12, 48, 0, 64, 64, 64, 4, 64, 68, 80, 8, 64, 72, 96, 12, 64, 76,112, 0,128,128,128, 4,128,132,144, 8,128,136,160, 12,128,140,176, 0,192,192,192, 4,192,196,208, 8,192,200,224, 12,192,204,240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 15, 15 }; static const ALIGNED(4) uint8_t tex_4x4_dxt1[] = { 'T','E','X', 10, 2,129, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 32, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 58, 14, 0, 8, 85,255,170, 0, }; static const ALIGNED(4) uint8_t tex_4x4_dxt3[] = { 'T','E','X', 10, 2,130, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 32, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 16, 50, 84,118,152,186,220,254, 58, 14, 0, 8, 85,255,170, 0, }; static const ALIGNED(4) uint8_t tex_4x4_dxt5[] = { 'T','E','X', 10, 2,131, 0, 0, 0, 4, 0, 4, 0, 1, 0, 0, 0, 0, 0, 32, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 240, 0,201,111,183,228, 38, 1, 58, 14, 0, 8, 85,255,170, 0, }; static const ALIGNED(4) uint8_t tex_16x16_pvrtc2[] = { 'T','E','X', 10, 2,132, 0, 0, 0, 16, 0, 16, 0, 1, 0, 0, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 170, 85, 1,255,170, 16, 19, 97,170, 85, 1,255,188, 17, 1, 97, 170, 85, 1,255,188, 17, 1, 97,170, 85, 1,255,171, 0, 1, 97, 170, 85, 1,255,170, 16, 19, 97,170, 85, 1,255,188, 17, 1, 97, 170, 85, 1,255,188, 17, 1, 97,170, 85, 1,255,171, 0, 1, 97, }; static const ALIGNED(4) uint8_t tex_16x16_pvrtc2_noalpha[] = { 'T','E','X', 10, 2,134, 0, 0, 0, 16, 0, 16, 0, 1, 0, 0, 0, 0, 0, 32, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 170, 85, 1,255,170, 16, 19, 97,170, 85, 1,255,188, 17, 1, 97, 170, 85, 1,255,188, 17, 1, 97,170, 85, 1,255,171, 0, 1, 97, 170, 85, 1,255,170, 16, 19, 97,170, 85, 1,255,188, 17, 1, 97, 170, 85, 1,255,188, 17, 1, 97,170, 85, 1,255,171, 0, 1, 97, }; static const ALIGNED(4) uint8_t tex_8x8_pvrtc4[] = { 'T','E','X', 10, 2,133, 0, 0, 0, 8, 0, 8, 0, 1, 0, 0, 0, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85,170,255, 0, 0,205,113, 0, 85,170,255, 0, 17,188, 97, 0, 85,170,255, 0, 17,188, 97, 0, 85,170,255, 2, 17,188, 97, }; static const ALIGNED(4) uint8_t tex_8x8_pvrtc4_noalpha[] = { 'T','E','X', 10, 2,135, 0, 0, 0, 8, 0, 8, 0, 1, 0, 0, 0, 0, 0, 32, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85,170,255, 0, 0,205,113, 0, 85,170,255, 0, 17,188, 97, 0, 85,170,255, 0, 17,188, 97, 0, 85,170,255, 2, 17,188, 97, }; /*-----------------------------------------------------------------------*/ static const uint8_t dds_4x4[] = { 'D','D','S',' ',124, 0, 0, 0, 7, 16, 8, 0, 4, 0, 0, 0, 4, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0,255, 0, 0, 0, 0,255, 0, 0, 0, 0,255, 0, 0, 0, 0,255, 0, 16, 0, 0, 0, 0, 0, 0,'D','D','S','X',255,255,255,255,255,255,255,255, 0, 0, 0, 0, 4, 0, 4, 16, 8, 0, 8, 32, 12, 0, 12, 48, 0, 64, 64, 64, 4, 64, 68, 80, 8, 64, 72, 96, 12, 64, 76,112, 0,128,128,128, 4,128,132,144, 8,128,136,160, 12,128,140,176, 0,192,192,192, 4,192,196,208, 8,192,200,224, 12,192,204,240, }; static const uint8_t dds_4x4_stride_mipmaps[] = { 'D','D','S',' ',124, 0, 0, 0, 15, 16, 2, 0, 4, 0, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0,255, 0, 0, 0, 0,255, 0, 0, 0, 0,255, 0, 0, 0, 0,255, 0, 16, 0, 0, 0, 0, 0, 0,'D','D','S','X',255,255,255,255,255,255,255,255, 0, 0, 0, 0, 4, 0, 4, 16, 8, 0, 8, 32, 12, 0, 12, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 64, 64, 4, 64, 68, 80, 8, 64, 72, 96, 12, 64, 76,112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,128,128,128, 4,128,132,144, 8,128,136,160, 12,128,140,176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,192,192,192, 4,192,196,208, 8,192,200,224, 12,192,204,240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 32, 34, 40, 10, 32, 42, 72, 0, 0, 0, 0, 0, 0, 0, 0, 2,160,162,168, 10,160,170,200, 0, 0, 0, 0, 0, 0, 0, 0, 6, 96,102,120, 0, 0, 0, 0, }; /*-----------------------------------------------------------------------*/ static const uint8_t png_4x4[] = { 137,'P','N','G', 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 4, 0, 0, 0, 4, 8, 6, 0, 0, 0,169,241,158, 126, 0, 0, 0, 29, 73, 68, 65, 84, 8,215, 99,100, 96, 96, 96, 96, 97, 96, 17, 64, 96, 7, 7, 7, 6, 6, 22, 1, 24, 38, 44, 0, 0,103,108, 3, 74,112,245,207,221, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130, }; /*************************************************************************/ /**************************** Helper routines ****************************/ /*************************************************************************/ /** * CHECK_TEXTURE_MEMORY_FAILURES: Wrapper around the CHECK_MEMORY_FAILRES() * macro which calls graphics_flush_resources() on failure to ensure all * resources are actually deleted. */ #define CHECK_TEXTURE_MEMORY_FAILURES(expr) \ CHECK_MEMORY_FAILURES((expr) || (graphics_flush_resources(), 0)) /*-----------------------------------------------------------------------*/ /** * format_supported: Return whether the given texture format is supported * by sys_texture_create(). * * [Parameters] * format: Format to check. * [Return value] * True if textures of the given format can be created, false if not. */ static int format_supported(int format) { switch (format) { case TEX_FORMAT_RGBA8888: case TEX_FORMAT_RGB565: case TEX_FORMAT_RGBA5551: case TEX_FORMAT_RGBA4444: case TEX_FORMAT_A8: case TEX_FORMAT_L8: case TEX_FORMAT_PALETTE8_RGBA8888: return 1; case TEX_FORMAT_BGRA8888: case TEX_FORMAT_BGR565: case TEX_FORMAT_BGRA5551: case TEX_FORMAT_BGRA4444: #ifdef SIL_PLATFORM_PSP return 0; #else /* Default to returning "supported" so we don't forget to test on * new systems. */ return 1; #endif case TEX_FORMAT_PSP_RGBA8888: case TEX_FORMAT_PSP_RGB565: case TEX_FORMAT_PSP_RGBA5551: case TEX_FORMAT_PSP_RGBA4444: case TEX_FORMAT_PSP_A8: case TEX_FORMAT_PSP_L8: case TEX_FORMAT_PSP_PALETTE8_RGBA8888: case TEX_FORMAT_PSP_RGBA8888_SWIZZLED: case TEX_FORMAT_PSP_RGB565_SWIZZLED: case TEX_FORMAT_PSP_RGBA5551_SWIZZLED: case TEX_FORMAT_PSP_RGBA4444_SWIZZLED: case TEX_FORMAT_PSP_A8_SWIZZLED: case TEX_FORMAT_PSP_L8_SWIZZLED: case TEX_FORMAT_PSP_PALETTE8_RGBA8888_SWIZZLED: #ifdef SIL_PLATFORM_PSP return 1; #else return 0; // Supported only on PSP, by definition. #endif case TEX_FORMAT_S3TC_DXT1: case TEX_FORMAT_S3TC_DXT3: case TEX_FORMAT_S3TC_DXT5: #ifdef USES_GL return opengl_has_formats(OPENGL_FORMAT_S3TC); #elif defined(SIL_PLATFORM_PSP) return 0; #else return 1; #endif case TEX_FORMAT_PVRTC2_RGBA: case TEX_FORMAT_PVRTC4_RGBA: case TEX_FORMAT_PVRTC2_RGB: case TEX_FORMAT_PVRTC4_RGB: #ifdef USES_GL return opengl_has_formats(OPENGL_FORMAT_PVRTC); #elif defined(SIL_PLATFORM_PSP) return 0; #else return 1; #endif } return 0; // Invalid format. } /*************************************************************************/ /****************************** Test runner ******************************/ /*************************************************************************/ static int do_test_graphics_texture(void); int test_graphics_texture(void) { return run_tests_in_window(do_test_graphics_texture); } DEFINE_GENERIC_TEST_RUNNER(do_test_graphics_texture) TEST_INIT(init) { graphics_start_frame(); return 1; } TEST_CLEANUP(cleanup) { graphics_finish_frame(); /* Clean up memory to prove there are no leaks. */ graphics_flush_resources(); return 1; } /*************************************************************************/ /**************** Basic texture creation/management tests ****************/ /*************************************************************************/ TEST(test_basic) { int texture; CHECK_TRUE(texture = texture_create(4, 2, 0, 0)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 2); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_create_clear) { int texture; CHECK_TRUE(texture = texture_create(4, 2, MEM_ALLOC_CLEAR, 0)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 2); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); const uint8_t *pixels; CHECK_TRUE(pixels = texture_lock_readonly(texture)); for (int i = 0; i < 4*2*4; i++) { CHECK_INTEQUAL(pixels[i], 0); } texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_create_clear_mipmaps) { int texture; CHECK_TRUE(texture = texture_create(4, 2, MEM_ALLOC_CLEAR, 1)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 2); CHECK_FLOATEQUAL(texture_scale(texture), 1); if (auto_mipmaps_supported()) { CHECK_TRUE(texture_has_mipmaps(texture)); } else { CHECK_FALSE(texture_has_mipmaps(texture)); } const uint8_t *pixels; CHECK_TRUE(pixels = texture_lock_readonly(texture)); for (int i = 0; i < 4*2*4; i++) { CHECK_INTEQUAL(pixels[i], 0); } texture_unlock(texture); /* We can't read the lower mipmap layers of the texture directly, so * we test indirectly by drawing with the texture in * primitive.c:test_texture_alloc_clear_with_mipmaps(). */ texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_id_reuse) { int texture1, texture2; CHECK_TRUE(texture1 = texture_create(4, 2, 0, 0)); CHECK_TRUE(texture2 = texture_create(2, 4, 0, 0)); texture_destroy(texture1); CHECK_INTEQUAL(texture_create(4, 2, 0, 0), texture1); texture_destroy(texture1); texture_destroy(texture2); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_create_data) { int texture; CHECK_TRUE(texture = texture_create_with_data( 4, 4, rgba_4x4, TEX_FORMAT_RGBA8888, 4, 0, 0)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 4); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); const uint8_t *pixels; CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_create_data_stride) { int texture; CHECK_TRUE(texture = texture_create_with_data( 2, 4, rgba_4x4, TEX_FORMAT_RGBA8888, 4, 0, 0)); CHECK_INTEQUAL(texture_width(texture), 2); CHECK_INTEQUAL(texture_height(texture), 4); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); const uint8_t *pixels; CHECK_TRUE(pixels = texture_lock_readonly(texture)); for (int y = 0; y < 4; y++) { CHECK_MEMEQUAL(&pixels[(y*2)*4], &rgba_4x4[(y*4)*4], 2*4); } texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_create_data_stride_short) { int texture; CHECK_TRUE(texture = texture_create_with_data( 2, 4, rgba_4x4, TEX_FORMAT_RGBA8888, 1, 0, 0)); CHECK_INTEQUAL(texture_width(texture), 2); CHECK_INTEQUAL(texture_height(texture), 4); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); const uint8_t *pixels; CHECK_TRUE(pixels = texture_lock_readonly(texture)); for (int y = 0; y < 4; y++) { CHECK_MEMEQUAL(&pixels[(y*2)*4], &rgba_4x4[(y*4)*1], 2*4); } texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_create_data_16bpp) { #ifdef USES_GL if (!opengl_has_features(OPENGL_FEATURE_GETTEXIMAGE)) { SKIP("Can't read non-RGBA8888 texture data"); } #endif int texture; CHECK_TRUE(texture = texture_create_with_data( 4, 4, tex_4x4_rgb565 + 32, TEX_FORMAT_RGB565, 4, 0, 0)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 4); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); const uint8_t *pixels; CHECK_TRUE(pixels = texture_lock_readonly(texture)); /* Allow slight differences between the expected and actual RGBA output * to account for differing renderer behaviors in 16->32bpp conversion. */ for (int i = 0; i < 4*4; i++) { const int r = rgba_4x4_rgb565[i*4+0]; const int g = rgba_4x4_rgb565[i*4+1]; const int b = rgba_4x4_rgb565[i*4+2]; const int a = rgba_4x4_rgb565[i*4+3]; CHECK_PIXEL_NEAR(&pixels[i*4], r,g,b,a, 4, i%4, i/4); } texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_create_data_16bpp_stride) { #ifdef USES_GL if (!opengl_has_features(OPENGL_FEATURE_GETTEXIMAGE)) { SKIP("Can't read non-RGBA8888 texture data"); } #endif int texture; CHECK_TRUE(texture = texture_create_with_data( 2, 4, tex_4x4_rgb565 + 32, TEX_FORMAT_RGB565, 4, 0, 0)); CHECK_INTEQUAL(texture_width(texture), 2); CHECK_INTEQUAL(texture_height(texture), 4); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); const uint8_t *pixels; CHECK_TRUE(pixels = texture_lock_readonly(texture)); /* Allow slight differences between the expected and actual RGBA output * to account for differing renderer behaviors in 16->32bpp conversion. */ for (int i = 0; i < 2*4; i++) { const int x = i%2; const int y = i/2; const int r = rgba_4x4_rgb565[(y*4+x)*4+0]; const int g = rgba_4x4_rgb565[(y*4+x)*4+1]; const int b = rgba_4x4_rgb565[(y*4+x)*4+2]; const int a = rgba_4x4_rgb565[(y*4+x)*4+3]; CHECK_PIXEL_NEAR(&pixels[i*4], r,g,b,a, 4, x, y); } texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_create_memory_failure) { int texture; CHECK_TEXTURE_MEMORY_FAILURES(texture = texture_create(4, 2, 0, 0)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 2); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_create_data_memory_failure) { int texture; CHECK_TEXTURE_MEMORY_FAILURES(texture = texture_create_with_data( 4, 4, rgba_4x4, TEX_FORMAT_RGBA8888, 4, 0, 0)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 4); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); const uint8_t *pixels; CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_create_mipmaps_memory_failure) { int texture; CHECK_TEXTURE_MEMORY_FAILURES(texture = texture_create(4, 2, 0, 1)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 2); CHECK_FLOATEQUAL(texture_scale(texture), 1); if (auto_mipmaps_supported()) { CHECK_TRUE(texture_has_mipmaps(texture)); } else { CHECK_FALSE(texture_has_mipmaps(texture)); } texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_create_clear_mipmaps_memory_failure) { int texture; CHECK_TEXTURE_MEMORY_FAILURES( texture = texture_create(4, 2, MEM_ALLOC_CLEAR, 1)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 2); CHECK_FLOATEQUAL(texture_scale(texture), 1); if (auto_mipmaps_supported()) { CHECK_TRUE(texture_has_mipmaps(texture)); } else { CHECK_FALSE(texture_has_mipmaps(texture)); } texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_create_invalid) { CHECK_FALSE(texture_create(0, 2, 0, 0)); CHECK_FALSE(texture_create(4, 0, 0, 0)); CHECK_FALSE(texture_create_with_data( 0, 4, rgba_4x4, TEX_FORMAT_RGBA8888, 4, 0, 0)); CHECK_FALSE(texture_create_with_data( 4, 0, rgba_4x4, TEX_FORMAT_RGBA8888, 4, 0, 0)); CHECK_FALSE(texture_create_with_data( 4, 4, NULL, TEX_FORMAT_RGBA8888, 4, 0, 0)); CHECK_FALSE(texture_create_with_data( 4, 4, rgba_4x4, (TextureFormat)-1, 4, 0, 0)); CHECK_FALSE(texture_create_with_data( 4, 4, rgba_4x4, TEX_FORMAT_RGBA8888, -1, 0, 0)); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_create_invalid_stride) { CHECK_FALSE(texture_create_with_data( 2, 4, rgba_4x4, TEX_FORMAT_PSP_RGBA8888, 2, 0, 0)); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_destroy_locked) { int texture; CHECK_TRUE(texture = texture_create(4, 2, 0, 0)); CHECK_TRUE(texture_lock_readonly(texture)); texture_destroy(texture); // Should automatically unlock the texture. return 1; } /*-----------------------------------------------------------------------*/ TEST(test_destroy_invalid) { int texture; CHECK_TRUE(texture = texture_create(4, 2, 0, 0)); texture_destroy(texture); texture_destroy(texture); // Should log an error but not crash. texture_destroy(INVALID_TEXTURE); // Should log an error but not crash. texture_destroy(0); // Should not crash (defined as a no-op). texture_destroy(-1); // Should log an error but not crash. return 1; } /*-----------------------------------------------------------------------*/ TEST(test_width_invalid) { int texture; CHECK_TRUE(texture = texture_create(4, 2, 0, 0)); texture_destroy(texture); CHECK_INTEQUAL(texture_width(0), 0); CHECK_INTEQUAL(texture_width(texture), 0); CHECK_INTEQUAL(texture_width(INVALID_TEXTURE), 0); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_height_invalid) { int texture; CHECK_TRUE(texture = texture_create(4, 2, 0, 0)); texture_destroy(texture); CHECK_INTEQUAL(texture_height(0), 0); CHECK_INTEQUAL(texture_height(texture), 0); CHECK_INTEQUAL(texture_height(INVALID_TEXTURE), 0); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_scale_invalid) { int texture; CHECK_TRUE(texture = texture_create(4, 2, 0, 0)); texture_destroy(texture); CHECK_FLOATEQUAL(texture_scale(0), 1); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FLOATEQUAL(texture_scale(INVALID_TEXTURE), 1); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_has_mipmaps_invalid) { int texture; CHECK_TRUE(texture = texture_create(4, 2, 0, 0)); texture_destroy(texture); CHECK_FALSE(texture_has_mipmaps(0)); CHECK_FALSE(texture_has_mipmaps(texture)); CHECK_FALSE(texture_has_mipmaps(INVALID_TEXTURE)); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_texture_array_hole) { int texture1, texture2, texture3; const uint8_t *pixels; CHECK_TRUE(texture1 = texture_create(2, 2, 0, 0)); /* Safe to de-const the input buffer since we're not reusing it. */ CHECK_TRUE(texture2 = texture_parse((void *)tex_4x4, sizeof(tex_4x4), 0, 0, 0)); CHECK_TRUE(texture2 > texture1); texture_destroy(texture1); CHECK_INTEQUAL(texture_parse((void *)tex_4x4, sizeof(tex_4x4), 0, 0, 0), texture1); CHECK_TRUE(texture3 = texture_parse((void *)tex_4x4_scale_half, sizeof(tex_4x4_scale_half), 0, 0, 0)); CHECK_TRUE(texture3 > texture2); CHECK_INTEQUAL(texture_width(texture1), 4); CHECK_INTEQUAL(texture_height(texture1), 4); CHECK_FLOATEQUAL(texture_scale(texture1), 1); CHECK_FALSE(texture_has_mipmaps(texture1)); CHECK_TRUE(pixels = texture_lock_readonly(texture1)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); CHECK_INTEQUAL(texture_width(texture2), 4); CHECK_INTEQUAL(texture_height(texture2), 4); CHECK_FLOATEQUAL(texture_scale(texture2), 1); CHECK_FALSE(texture_has_mipmaps(texture2)); CHECK_TRUE(pixels = texture_lock_readonly(texture2)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); CHECK_INTEQUAL(texture_width(texture3), 4); CHECK_INTEQUAL(texture_height(texture3), 4); CHECK_FLOATEQUAL(texture_scale(texture3), 0.5); CHECK_FALSE(texture_has_mipmaps(texture3)); CHECK_TRUE(pixels = texture_lock_readonly(texture3)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_destroy(texture1); texture_destroy(texture2); texture_destroy(texture3); return 1; } /*************************************************************************/ /********************** Texture file parsing tests ***********************/ /*************************************************************************/ TEST(test_parse_tex) { int texture; const uint8_t *pixels; CHECK_TRUE(texture = texture_parse((void *)tex_4x4, sizeof(tex_4x4), 0, 0, 0)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 4); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_tex_mipmaps) { int texture; const uint8_t *pixels; CHECK_TRUE(texture = texture_parse((void *)tex_4x4_mipmaps, sizeof(tex_4x4_mipmaps), 0, 1, 0)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 4); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_TRUE(texture_has_mipmaps(texture)); CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_tex_scale_half) { int texture; const uint8_t *pixels; CHECK_TRUE(texture = texture_parse((void *)tex_4x4_scale_half, sizeof(tex_4x4_scale_half), 0, 0, 0)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 4); CHECK_FLOATEQUAL(texture_scale(texture), 0.5); CHECK_FALSE(texture_has_mipmaps(texture)); CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_tex_reuse) { void *buffer; int texture; const uint8_t *pixels; ASSERT(buffer = mem_alloc(sizeof(tex_4x4), 0, 0)); memcpy(buffer, tex_4x4, sizeof(tex_4x4)); CHECK_TRUE(texture = texture_parse(buffer, sizeof(tex_4x4), 0, 0, 1)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 4); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_tex_reuse_unaligned) { void *buffer; int texture; const uint8_t *pixels; ASSERT(buffer = mem_alloc(sizeof(tex_4x4_unaligned), 0, 0)); memcpy(buffer, tex_4x4_unaligned, sizeof(tex_4x4_unaligned)); CHECK_TRUE(texture = texture_parse(buffer, sizeof(tex_4x4_unaligned), 0, 0, 1)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 4); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_tex_reuse_unaligned_16bpp) { #ifdef USES_GL if (!opengl_has_features(OPENGL_FEATURE_GETTEXIMAGE)) { SKIP("Can't read non-RGBA8888 texture data"); } #endif void *buffer; int texture; const uint8_t *pixels; ASSERT(buffer = mem_alloc(sizeof(tex_4x4_rgb565_unaligned), 0, 0)); memcpy(buffer, tex_4x4_rgb565_unaligned, sizeof(tex_4x4_rgb565_unaligned)); CHECK_TRUE(texture = texture_parse( buffer, sizeof(tex_4x4_rgb565_unaligned), 0, 0, 1)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 4); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); CHECK_TRUE(pixels = texture_lock_readonly(texture)); for (int i = 0; i < 4*4; i++) { const int r = rgba_4x4_rgb565[i*4+0]; const int g = rgba_4x4_rgb565[i*4+1]; const int b = rgba_4x4_rgb565[i*4+2]; const int a = rgba_4x4_rgb565[i*4+3]; CHECK_PIXEL_NEAR(&pixels[i*4], r,g,b,a, 4, i%4, i/4); } texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_dds) { int texture; const uint8_t *pixels; CHECK_TRUE(texture = texture_parse((void *)dds_4x4, sizeof(dds_4x4), 0, 0, 0)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 4); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_dds_stride_mipmaps) { int texture; const uint8_t *pixels; CHECK_TRUE(texture = texture_parse((void *)dds_4x4_stride_mipmaps, sizeof(dds_4x4_stride_mipmaps), 0, 1, 0)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 4); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_TRUE(texture_has_mipmaps(texture)); CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_dds_reuse) { void *buffer; int texture; const uint8_t *pixels; ASSERT(buffer = mem_alloc(sizeof(dds_4x4), 0, 0)); memcpy(buffer, dds_4x4, sizeof(dds_4x4)); CHECK_TRUE(texture = texture_parse(buffer, sizeof(dds_4x4), 0, 0, 1)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 4); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_dds_stride_mipmaps_reuse) { void *buffer; int texture; const uint8_t *pixels; ASSERT(buffer = mem_alloc(sizeof(dds_4x4_stride_mipmaps), 0, 0)); memcpy(buffer, dds_4x4_stride_mipmaps, sizeof(dds_4x4_stride_mipmaps)); CHECK_TRUE(texture = texture_parse(buffer, sizeof(dds_4x4_stride_mipmaps), 0, 1, 1)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 4); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_TRUE(texture_has_mipmaps(texture)); CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_png) { #ifdef SIL_UTILITY_INCLUDE_PNG int texture; const uint8_t *pixels; CHECK_TRUE(texture = texture_parse((void *)png_4x4, sizeof(png_4x4), 0, 0, 0)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 4); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); texture_destroy(texture); #else CHECK_FALSE(texture_parse((void *)png_4x4, sizeof(png_4x4), 0, 0, 0)); #endif return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_png_mipmaps) { #ifdef SIL_UTILITY_INCLUDE_PNG int texture; CHECK_TRUE(texture = texture_parse((void *)png_4x4, sizeof(png_4x4), 0, 1, 0)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 4); if (auto_mipmaps_supported()) { CHECK_TRUE(texture_has_mipmaps(texture)); } else { CHECK_FALSE(texture_has_mipmaps(texture)); } texture_destroy(texture); #else CHECK_FALSE(texture_parse((void *)png_4x4, sizeof(png_4x4), 0, 1, 0)); #endif return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_png_reuse) { void *buffer; ASSERT(buffer = mem_alloc(sizeof(png_4x4), 0, 0)); memcpy(buffer, png_4x4, sizeof(png_4x4)); #ifdef SIL_UTILITY_INCLUDE_PNG int texture; const uint8_t *pixels; CHECK_TRUE(texture = texture_parse(buffer, sizeof(png_4x4), 0, 0, 1)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 4); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); texture_destroy(texture); #else CHECK_FALSE(texture_parse(buffer, sizeof(png_4x4), 0, 0, 1)); #endif return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_memory_failure) { int texture; const uint8_t *pixels; CHECK_TEXTURE_MEMORY_FAILURES( texture = texture_parse((void *)tex_4x4, sizeof(tex_4x4), 0, 0, 0)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 4); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); texture_destroy(texture); #ifdef SIL_UTILITY_INCLUDE_PNG /* PNG makes extra allocations for decoding, so test that failure path * as well. */ CHECK_TEXTURE_MEMORY_FAILURES( texture = texture_parse((void *)png_4x4, sizeof(png_4x4), 0, 0, 0)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 4); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); texture_destroy(texture); #endif return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_tex_reuse_memory_failure) { void *buffer; int texture; const uint8_t *pixels; CHECK_TEXTURE_MEMORY_FAILURES( (buffer = mem_alloc(sizeof(tex_4x4), 0, 0)) && (memcpy(buffer, tex_4x4, sizeof(tex_4x4)), texture = texture_parse(buffer, sizeof(tex_4x4), 0, 0, 1))); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 4); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_dds_reuse_memory_failure) { void *buffer; int texture; const uint8_t *pixels; CHECK_TEXTURE_MEMORY_FAILURES( (buffer = mem_alloc(sizeof(dds_4x4), 0, 0)) && (memcpy(buffer, dds_4x4, sizeof(dds_4x4)), texture = texture_parse(buffer, sizeof(dds_4x4), 0, 0, 1))); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 4); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_png_reuse_memory_failure) { #ifdef SIL_UTILITY_INCLUDE_PNG void *buffer; int texture; const uint8_t *pixels; CHECK_TEXTURE_MEMORY_FAILURES( (buffer = mem_alloc(sizeof(png_4x4), 0, 0)) && (memcpy(buffer, png_4x4, sizeof(png_4x4)), texture = texture_parse(buffer, sizeof(png_4x4), 0, 0, 1))); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 4); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); texture_destroy(texture); #endif return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_invalid) { CHECK_FALSE(texture_parse(NULL, 1, 0, 0, 0)); CHECK_FALSE(texture_parse((void *)"", 0, 0, 0, 0)); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_bad_data) { CHECK_FALSE(texture_parse((void *)"a", 1, 0, 0, 0)); CHECK_FALSE(texture_parse((void *)"ABCDEFGHIJKLMNOP", 16, 0, 0, 0)); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_truncated) { CHECK_FALSE(texture_parse((void *)"TEX\x0A\2\0\0\0", 8, 0, 0, 0)); CHECK_FALSE(texture_parse((void *)("TEX\x0A\2\0\2\0\0\4\0\4\0\1\0\0" "\0\0\0\x20\0\0\0\4\0\0\0\0\0\0\0\0" "\0\0\0\0"), 36, 0, 1, 0)); CHECK_FALSE(texture_parse((void *)"DDS \x7C\0\0\0", 8, 0, 0, 0)); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_tex_size_zero) { CHECK_FALSE(texture_parse((void *)("TEX\x0A\2\0\0\0\0\0\0\1\0\1\0\0" "\0\0\0\x20\0\0\0\4\0\0\0\0\0\0\0\0" "\0\0\0\0"), 36, 0, 0, 0)); CHECK_FALSE(texture_parse((void *)("TEX\x0A\2\0\0\0\0\1\0\0\0\1\0\0" "\0\0\0\x20\0\0\0\4\0\0\0\0\0\0\0\0" "\0\0\0\0"), 36, 0, 0, 0)); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_tex_scale_zero) { CHECK_FALSE(texture_parse((void *)("TEX\x0A\2\0\0\0\0\1\0\1\0\0\0\0" "\0\0\0\x20\0\0\0\4\0\0\0\0\0\0\0\0" "\0\0\0\0"), 36, 0, 0, 0)); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_tex_invalid_format) { CHECK_FALSE(texture_parse((void *)("TEX\x0A\2\xFF\0\0\0\1\0\1\0\1\0\0" "\0\0\0\x20\0\0\0\4\0\0\0\0\0\0\0\0" "\0\0\0\0"), 36, 0, 0, 0)); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_tex_short_pixel_data) { CHECK_FALSE(texture_parse((void *)("TEX\x0A\2\0\0\0\0\1\0\1\0\1\0\0" "\0\0\0\x20\0\0\0\3\0\0\0\0\0\0\0\0" "\0\0\0"), 35, 0, 0, 0)); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_tex_short_paletted_pixel_data) { /* This is a special case to check that palette handling (0x400 bytes) * doesn't cause invalid accesses for paletted textures with short data. */ CHECK_FALSE(texture_parse((void *)("TEX\x0A\2\x80\0\0\0\1\0\1\0\1\0\0" "\0\0\0\x20\0\0\0\4\0\0\0\0\0\0\0\0" "\0\0\0\0"), 36, 0, 0, 0)); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_bad_data_reuse) { const int64_t used_before = mem_debug_bytes_allocated(); char *data; ASSERT(data = mem_strdup("a", 0)); CHECK_FALSE(texture_parse(data, 1, 0, 0, 1)); const int64_t used_after = mem_debug_bytes_allocated(); if (used_after > used_before) { FAIL("texture_parse(reuse=1) did not free input data on failure"); } return 1; } /*************************************************************************/ /************************* Texture locking tests *************************/ /*************************************************************************/ TEST(test_lock) { int texture; uint8_t *pixels; CHECK_TRUE(texture = texture_parse((void *)tex_4x4, sizeof(tex_4x4), 0, 0, 0)); CHECK_TRUE(pixels = texture_lock(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); memset(pixels, 0xAA, 4*4*4); texture_unlock(texture); CHECK_TRUE(pixels = (uint8_t *)texture_lock_readonly(texture)); for (int i = 0; i < 4*4*4; i++) { CHECK_INTEQUAL(pixels[i], 0xAA); } texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_lock_memory_failure) { int texture; uint8_t *pixels; CHECK_TRUE(texture = texture_parse((void *)tex_4x4, sizeof(tex_4x4), 0, 0, 0)); CHECK_TEXTURE_MEMORY_FAILURES(pixels = texture_lock(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_lock_invalid) { int texture; CHECK_TRUE(texture = texture_create(4, 2, 0, 0)); CHECK_TRUE(texture_lock(texture)); CHECK_FALSE(texture_lock(texture)); texture_destroy(texture); CHECK_FALSE(texture_lock(0)); CHECK_FALSE(texture_lock(texture)); CHECK_FALSE(texture_lock(INVALID_TEXTURE)); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_lock_readonly) { int texture; const uint8_t *pixels; CHECK_TRUE(texture = texture_parse((void *)tex_4x4, sizeof(tex_4x4), 0, 0, 0)); CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); memset((uint8_t *)pixels, 0xAA, 4*4*4); texture_unlock(texture); // This should _not_ update the texture. CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_lock_readonly_memory_failure) { int texture; const uint8_t *pixels; CHECK_TRUE(texture = texture_parse((void *)tex_4x4, sizeof(tex_4x4), 0, 0, 0)); CHECK_TEXTURE_MEMORY_FAILURES(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_lock_readonly_invalid) { int texture; CHECK_TRUE(texture = texture_create(4, 2, 0, 0)); CHECK_TRUE(texture_lock_readonly(texture)); CHECK_FALSE(texture_lock_readonly(texture)); texture_destroy(texture); CHECK_FALSE(texture_lock_readonly(0)); CHECK_FALSE(texture_lock_readonly(texture)); CHECK_FALSE(texture_lock_readonly(INVALID_TEXTURE)); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_lock_readonly_partial) { int texture; const uint8_t *pixels; CHECK_TRUE(texture = texture_parse((void *)tex_4x4, sizeof(tex_4x4), 0, 0, 0)); CHECK_TRUE(pixels = texture_lock_readonly_partial(texture, 1, 1, 2, 2)); for (int y = 0; y < 2; y++) { for (int x = 0; x < 2; x++) { for (int i = 0; i < 4; i++) { CHECK_INTEQUAL(pixels[(y*2+x)*4+i], rgba_4x4[((y+1)*4+(x+1))*4+i]); } } } memset((uint8_t *)pixels, 0xAA, 2*2*4); texture_unlock(texture); // This should _not_ update the texture. CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_lock_readonly_partial_height) { int texture; const uint8_t *pixels; CHECK_TRUE(texture = texture_parse((void *)tex_4x4, sizeof(tex_4x4), 0, 0, 0)); CHECK_TRUE(pixels = texture_lock_readonly_partial(texture, 0, 1, 4, 2)); for (int y = 0; y < 2; y++) { for (int x = 0; x < 4; x++) { for (int i = 0; i < 4; i++) { CHECK_INTEQUAL(pixels[(y*4+x)*4+i], rgba_4x4[((y+1)*4+x)*4+i]); } } } memset((uint8_t *)pixels, 0xAA, 2*4*4); texture_unlock(texture); // This should _not_ update the texture. CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_lock_readonly_partial_memory_failure) { int texture; const uint8_t *pixels; CHECK_TRUE(texture = texture_parse((void *)tex_4x4, sizeof(tex_4x4), 0, 0, 0)); CHECK_TEXTURE_MEMORY_FAILURES( pixels = texture_lock_readonly_partial(texture, 1, 1, 2, 2)); for (int y = 0; y < 2; y++) { for (int x = 0; x < 2; x++) { for (int i = 0; i < 4; i++) { CHECK_INTEQUAL(pixels[(y*2+x)*4+i], rgba_4x4[((y+1)*4+(x+1))*4+i]); } } } texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_lock_readonly_partial_invalid) { int texture; CHECK_TRUE(texture = texture_create(4, 2, 0, 0)); CHECK_FALSE(texture_lock_readonly_partial(texture, -1, 0, 1, 1)); CHECK_FALSE(texture_lock_readonly_partial(texture, 4, 0, 1, 1)); CHECK_FALSE(texture_lock_readonly_partial(texture, 0, -1, 1, 1)); CHECK_FALSE(texture_lock_readonly_partial(texture, 0, 2, 1, 1)); CHECK_FALSE(texture_lock_readonly_partial(texture, 0, 0, 0, 1)); CHECK_FALSE(texture_lock_readonly_partial(texture, 0, 0, -1, 1)); CHECK_FALSE(texture_lock_readonly_partial(texture, 0, 0, 5, 1)); CHECK_FALSE(texture_lock_readonly_partial(texture, 0, 0, 1, 0)); CHECK_FALSE(texture_lock_readonly_partial(texture, 0, 0, 1, -1)); CHECK_FALSE(texture_lock_readonly_partial(texture, 0, 0, 1, 3)); /* Check for proper handling of integer overflow. We assume the * (signed) int type uses two's-complement representation. */ const int int_max = (int)((~(unsigned int)0 ^ (~(unsigned int)0 >> 1)) - 1); CHECK_FALSE(texture_lock_readonly_partial(texture, 3, 1, int_max, 1)); CHECK_FALSE(texture_lock_readonly_partial(texture, 3, 1, 1, int_max)); CHECK_FALSE(texture_lock_readonly_partial(texture, 3, 1, int_max, int_max)); CHECK_TRUE(texture_lock_readonly_partial(texture, 0, 0, 1, 1)); CHECK_FALSE(texture_lock_readonly_partial(texture, 0, 0, 1, 1)); texture_destroy(texture); CHECK_FALSE(texture_lock_readonly_partial(0, 0, 0, 1, 1)); CHECK_FALSE(texture_lock_readonly_partial(texture, 0, 0, 1, 1)); CHECK_FALSE(texture_lock_readonly_partial(INVALID_TEXTURE, 0, 0, 1, 1)); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_lock_writeonly) { int texture; uint8_t *pixels; CHECK_TRUE(texture = texture_parse((void *)tex_4x4, sizeof(tex_4x4), 0, 0, 0)); CHECK_TRUE(pixels = texture_lock_writeonly(texture)); memset(pixels, 0xAA, 4*4*4); texture_unlock(texture); CHECK_TRUE(pixels = (uint8_t *)texture_lock_readonly(texture)); for (int i = 0; i < 4*4*4; i++) { CHECK_INTEQUAL(pixels[i], 0xAA); } texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_lock_writeonly_memory_failure) { int texture; uint8_t *pixels; CHECK_TRUE(texture = texture_parse((void *)tex_4x4, sizeof(tex_4x4), 0, 0, 0)); CHECK_TEXTURE_MEMORY_FAILURES(pixels = texture_lock_writeonly(texture)); memset(pixels, 0xAA, 4*4*4); texture_unlock(texture); CHECK_TRUE(pixels = (uint8_t *)texture_lock_readonly(texture)); for (int i = 0; i < 4*4*4; i++) { CHECK_INTEQUAL(pixels[i], 0xAA); } texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_lock_writeonly_invalid) { int texture; CHECK_TRUE(texture = texture_create(4, 2, 0, 0)); CHECK_TRUE(texture_lock_writeonly(texture)); CHECK_FALSE(texture_lock_writeonly(texture)); texture_destroy(texture); CHECK_FALSE(texture_lock_writeonly(0)); CHECK_FALSE(texture_lock_writeonly(texture)); CHECK_FALSE(texture_lock_writeonly(INVALID_TEXTURE)); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_lock_raw_invalid) { /* We checked texture_lock_raw() as part of the texture_import() test, * so just ensure that invalid calls are properly handled. */ int texture; CHECK_TRUE(texture = texture_create(4, 2, 0, 0)); CHECK_TRUE(texture_lock_raw(texture)); CHECK_FALSE(texture_lock_raw(texture)); texture_destroy(texture); CHECK_FALSE(texture_lock_raw(0)); CHECK_FALSE(texture_lock_raw(texture)); CHECK_FALSE(texture_lock_raw(INVALID_TEXTURE)); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_lock_unlock_invalid) { /* We checked texture_unlock() as part of the various tests above, * so just ensure that invalid calls are properly handled (i.e., don't * crash). */ int texture; CHECK_TRUE(texture = texture_create(4, 2, 0, 0)); texture_unlock(texture); texture_destroy(texture); texture_unlock(0); texture_unlock(texture); texture_unlock(INVALID_TEXTURE); return 1; } /*************************************************************************/ /********************* Opaque bitmap handling tests **********************/ /*************************************************************************/ TEST(test_parse_tex_opaque) { int texture; const uint8_t *pixels; CHECK_TRUE(texture = texture_parse((void *)tex_16x1_opaque, sizeof(tex_16x1_opaque), 0, 0, 0)); CHECK_INTEQUAL(texture_width(texture), 16); CHECK_INTEQUAL(texture_height(texture), 1); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, opaque_pixels, sizeof(opaque_pixels)); texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_tex_opaque_memory_failure) { int texture; const uint8_t *pixels; CHECK_TEXTURE_MEMORY_FAILURES(texture = texture_parse( (void *)tex_16x1_opaque, sizeof(tex_16x1_opaque), 0, 0, 0)); CHECK_INTEQUAL(texture_width(texture), 16); CHECK_INTEQUAL(texture_height(texture), 1); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, opaque_pixels, sizeof(opaque_pixels)); texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_tex_opaque_unaligned_width) { int texture; const uint8_t *pixels; CHECK_TRUE(texture = texture_parse((void *)tex_4x4_opaque, sizeof(tex_4x4_opaque), 0, 0, 0)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 4); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, opaque_pixels, sizeof(opaque_pixels)); texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_parse_tex_opaque_short_data) { uint8_t data[sizeof(tex_4x4_opaque)]; memcpy(data, tex_4x4_opaque, sizeof(tex_4x4_opaque)); data[31]--; // Make the bitmap 1 byte short. CHECK_FALSE(texture_parse(data, sizeof(tex_4x4_opaque), 0, 0, 0)); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_lock_opaque_memory_failure) { int texture; const uint8_t *pixels; CHECK_TRUE(texture = texture_parse((void *)tex_16x1_opaque, sizeof(tex_16x1_opaque), 0, 0, 0)); CHECK_TEXTURE_MEMORY_FAILURES(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, opaque_pixels, sizeof(opaque_pixels)); texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_lock_opaque_unaligned_start) { int texture; const uint8_t *pixels; CHECK_TRUE(texture = texture_parse((void *)tex_16x1_opaque, sizeof(tex_16x1_opaque), 0, 0, 0)); CHECK_TRUE(pixels = texture_lock_readonly_partial(texture, 1, 0, 15, 1)); CHECK_MEMEQUAL(pixels, opaque_pixels+1*4, 15*4); texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_lock_opaque_unaligned_end) { int texture; const uint8_t *pixels; CHECK_TRUE(texture = texture_parse((void *)tex_16x1_opaque, sizeof(tex_16x1_opaque), 0, 0, 0)); CHECK_TRUE(pixels = texture_lock_readonly_partial(texture, 0, 0, 15, 1)); CHECK_MEMEQUAL(pixels, opaque_pixels, 15*4); texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_lock_opaque_single_byte) { int texture; const uint8_t *pixels; CHECK_TRUE(texture = texture_parse((void *)tex_16x1_opaque, sizeof(tex_16x1_opaque), 0, 0, 0)); CHECK_TRUE(pixels = texture_lock_readonly_partial(texture, 0, 0, 8, 1)); CHECK_MEMEQUAL(pixels, opaque_pixels, 8*4); texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_lock_opaque_single_byte_unaligned_start) { int texture; const uint8_t *pixels; CHECK_TRUE(texture = texture_parse((void *)tex_16x1_opaque, sizeof(tex_16x1_opaque), 0, 0, 0)); CHECK_TRUE(pixels = texture_lock_readonly_partial(texture, 1, 0, 7, 1)); CHECK_MEMEQUAL(pixels, opaque_pixels+1*4, 7*4); texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_lock_opaque_single_byte_unaligned_end) { int texture; const uint8_t *pixels; CHECK_TRUE(texture = texture_parse((void *)tex_16x1_opaque, sizeof(tex_16x1_opaque), 0, 0, 0)); CHECK_TRUE(pixels = texture_lock_readonly_partial(texture, 0, 0, 7, 1)); CHECK_MEMEQUAL(pixels, opaque_pixels, 7*4); texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_lock_opaque_single_byte_unaligned_start_and_end) { int texture; const uint8_t *pixels; CHECK_TRUE(texture = texture_parse((void *)tex_16x1_opaque, sizeof(tex_16x1_opaque), 0, 0, 0)); CHECK_TRUE(pixels = texture_lock_readonly_partial(texture, 1, 0, 6, 1)); CHECK_MEMEQUAL(pixels, opaque_pixels+1*4, 6*4); texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_lock_opaque_readwrite_failure) { int texture; CHECK_TRUE(texture = texture_parse((void *)tex_4x4_opaque, sizeof(tex_4x4_opaque), 0, 0, 0)); CHECK_FALSE(texture_lock(texture)); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_lock_opaque_discard) { int texture; uint8_t *pixels; CHECK_TRUE(texture = texture_parse((void *)tex_4x4_opaque, sizeof(tex_4x4_opaque), 0, 0, 0)); CHECK_TRUE(pixels = texture_lock_writeonly(texture)); memcpy(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); CHECK_TRUE(pixels = (uint8_t *)texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); texture_destroy(texture); return 1; } /*************************************************************************/ /********************* Display-related texture tests *********************/ /*************************************************************************/ TEST(test_create_from_display) { const int width = graphics_display_width(); const int height = graphics_display_height(); int texture; const uint8_t *pixels; graphics_clear(0.2, 0.4, 0.6, 0, 1, 0); CHECK_TRUE( texture = texture_create_from_display(0, 0, width, height, 1, 0, 0)); CHECK_INTEQUAL(texture_width(texture), width); CHECK_INTEQUAL(texture_height(texture), height); CHECK_TRUE(pixels = texture_lock_readonly(texture)); for (int i = 0; i < width*height*4; i += 4) { CHECK_PIXEL(&pixels[i], 51,102,153,255, (i/4) % width, (i/4) / width); } texture_destroy(texture); /* Note that we cannot yet test whether the pixel order in the returned * texture is correct (for example, it might be vertically inverted if * the system does not account for framebuffer pixel storage order). * That functionality is tested in misc.c. */ return 1; } /*-----------------------------------------------------------------------*/ TEST(test_create_from_display_memory_failure) { const int width = graphics_display_width(); const int height = graphics_display_height(); int texture; const uint8_t *pixels; graphics_clear(0.2, 0.4, 0.6, 0, 1, 0); CHECK_TEXTURE_MEMORY_FAILURES( texture = texture_create_from_display(0, 0, width, height, 1, 0, 0)); CHECK_INTEQUAL(texture_width(texture), width); CHECK_INTEQUAL(texture_height(texture), height); CHECK_TRUE(pixels = texture_lock_readonly(texture)); for (int i = 0; i < width*height*4; i += 4) { CHECK_PIXEL(&pixels[i], 51,102,153,255, (i/4) % width, (i/4) / width); } texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_create_from_display_mipmaps_memory_failure) { const int width = 8; // Force powers of 2 so we're guaranteed GL mipmaps. const int height = 8; int texture; const uint8_t *pixels; graphics_clear(0.2, 0.4, 0.6, 0, 1, 0); CHECK_TEXTURE_MEMORY_FAILURES( texture = texture_create_from_display(0, 0, width, height, 1, 0, 1)); CHECK_INTEQUAL(texture_width(texture), width); CHECK_INTEQUAL(texture_height(texture), height); CHECK_TRUE(pixels = texture_lock_readonly(texture)); for (int i = 0; i < width*height*4; i += 4) { CHECK_PIXEL(&pixels[i], 51,102,153,255, (i/4) % width, (i/4) / width); } texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_create_from_display_bounds_negative) { int texture; const uint8_t *pixels; graphics_clear(0.2, 0.4, 0.6, 0, 1, 0); CHECK_TRUE(texture = texture_create_from_display(-2, -6, 8, 8, 1, 0, 0)); CHECK_INTEQUAL(texture_width(texture), 8); CHECK_INTEQUAL(texture_height(texture), 8); CHECK_TRUE(pixels = texture_lock_readonly(texture)); for (int i = 0; i < 8*8*4; i += 4) { const int x = (i/4) % 8; const int y = (i/4) / 8; if (x >= 2 && y >= 6) { CHECK_PIXEL(&pixels[i], 51,102,153,255, x, y); } } texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_create_from_display_bounds_negative_2) { int texture; graphics_clear(0.2, 0.4, 0.6, 0, 1, 0); /* Just check that the calls succeed, since the data is undefined. */ CHECK_TRUE(texture = texture_create_from_display(-8, -6, 8, 8, 1, 0, 0)); CHECK_INTEQUAL(texture_width(texture), 8); CHECK_INTEQUAL(texture_height(texture), 8); texture_destroy(texture); CHECK_TRUE(texture = texture_create_from_display(-6, -8, 8, 8, 1, 0, 0)); CHECK_INTEQUAL(texture_width(texture), 8); CHECK_INTEQUAL(texture_height(texture), 8); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_create_from_display_bounds_positive) { const int width = graphics_display_width(); const int height = graphics_display_height(); int texture; const uint8_t *pixels; graphics_clear(0.2, 0.4, 0.6, 0, 1, 0); CHECK_TRUE(texture = texture_create_from_display( width-2, height-6, 8, 8, 1, 0, 0)); CHECK_TRUE(pixels = texture_lock_readonly(texture)); for (int i = 0; i < 8*8*4; i += 4) { const int x = (i/4) % 8; const int y = (i/4) / 8; if (x < 2 && y < 6) { CHECK_PIXEL(&pixels[i], 51,102,153,255, x, y); } } texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_create_from_display_bounds_positive_2) { const int width = graphics_display_width(); const int height = graphics_display_height(); int texture; graphics_clear(0.2, 0.4, 0.6, 0, 1, 0); /* Just check that the calls succeed, since the data is undefined. */ CHECK_TRUE( texture = texture_create_from_display(width, 0, 8, 8, 1, 0, 0)); CHECK_INTEQUAL(texture_width(texture), 8); CHECK_INTEQUAL(texture_height(texture), 8); texture_destroy(texture); CHECK_TRUE( texture = texture_create_from_display(0, height+4, 8, 8, 1, 0, 0)); CHECK_INTEQUAL(texture_width(texture), 8); CHECK_INTEQUAL(texture_height(texture), 8); texture_destroy(texture); CHECK_TRUE( texture = texture_create_from_display(width, height+4, 8, 8, 1, 0, 0)); CHECK_INTEQUAL(texture_width(texture), 8); CHECK_INTEQUAL(texture_height(texture), 8); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_create_from_display_invalid) { CHECK_FALSE(texture_create_from_display(0, 0, 0, 1, 0, 0, 0)); CHECK_FALSE(texture_create_from_display(0, 0, 1, 0, 0, 0, 0)); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_set_repeat_invalid) { int texture; CHECK_TRUE(texture = texture_create(4, 2, 0, 0)); texture_destroy(texture); /* No return value, so just make sure they don't crash. */ texture_set_repeat(0, 0, 0); texture_set_repeat(texture, 0, 0); texture_set_repeat(INVALID_TEXTURE, 0, 0); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_set_antialias_invalid) { int texture; CHECK_TRUE(texture = texture_create(4, 2, 0, 0)); texture_destroy(texture); /* No return value, so just make sure they don't crash. */ texture_set_antialias(0, 0); texture_set_antialias(texture, 0); texture_set_antialias(INVALID_TEXTURE, 0); return 1; } /*************************************************************************/ /******************** SysTexture import/lookup tests *********************/ /*************************************************************************/ TEST(test_import) { SysTexture *systex; /* Safe to de-const the input buffer since we're not reusing it. */ CHECK_TRUE(systex = sys_texture_create( 4, 2, TEX_FORMAT_RGBA8888, 1, (void *)rgba_4x4, 4, (int32_t[]){0}, (int32_t[]){sizeof(rgba_4x4)}, 0, 0, 0)); int texture; CHECK_TRUE(texture = texture_import(systex, 0)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 2); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); CHECK_PTREQUAL(texture_lock_raw(texture), systex); texture_unlock(texture); /* Some systems complain about overly tiny framebuffers, so (now that we * know texture_width() and texture_height() return the proper values) * use a 4x4 instead of 4x2 texture to check pixel readback. */ texture_destroy(texture); CHECK_TRUE(systex = sys_texture_create( 4, 4, TEX_FORMAT_RGBA8888, 1, (void *)rgba_4x4, 4, (int32_t[]){0}, (int32_t[]){sizeof(rgba_4x4)}, 0, 0, 0)); CHECK_TRUE(texture = texture_import(systex, 0)); const uint8_t *pixels; CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_import_memory_failure) { SysTexture *systex; /* Safe to de-const the input buffer since we're not reusing it. */ CHECK_TRUE(systex = sys_texture_create( 4, 4, TEX_FORMAT_RGBA8888, 1, (void *)rgba_4x4, 4, (int32_t[]){0}, (int32_t[]){sizeof(rgba_4x4)}, 0, 0, 0)); int texture; CHECK_TEXTURE_MEMORY_FAILURES(texture = texture_import(systex, 0)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 4); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); CHECK_PTREQUAL(texture_lock_raw(texture), systex); texture_unlock(texture); const uint8_t *pixels; CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_import_invalid) { CHECK_FALSE(texture_import(NULL, 0)); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_readonly_import_forget) { SysTexture *systex; /* Safe to de-const the input buffer since we're not reusing it. */ CHECK_TRUE(systex = sys_texture_create( 4, 2, TEX_FORMAT_RGBA8888, 1, (void *)rgba_4x4, 4, (int32_t[]){0}, (int32_t[]){sizeof(rgba_4x4)}, 0, 0, 0)); int texture; CHECK_TRUE(texture = texture_import_readonly(systex)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 2); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); CHECK_PTREQUAL(texture_lock_raw(texture), systex); texture_unlock(texture); /* Use a 4x4 instead of 4x2 texture to check pixel readback, as in the * texture_import() test. */ texture_forget_readonly(texture); sys_texture_destroy(systex); CHECK_TRUE(systex = sys_texture_create( 4, 4, TEX_FORMAT_RGBA8888, 1, (void *)rgba_4x4, 4, (int32_t[]){0}, (int32_t[]){sizeof(rgba_4x4)}, 0, 0, 0)); CHECK_TRUE(texture = texture_import_readonly(systex)); const uint8_t *pixels; CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); texture_forget_readonly(texture); sys_texture_destroy(systex); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_readonly_import_memory_failure) { SysTexture *systex; /* Safe to de-const the input buffer since we're not reusing it. */ CHECK_TRUE(systex = sys_texture_create( 4, 4, TEX_FORMAT_RGBA8888, 1, (void *)rgba_4x4, 4, (int32_t[]){0}, (int32_t[]){sizeof(rgba_4x4)}, 0, 0, 0)); int texture; CHECK_MEMORY_FAILURES(texture = texture_import_readonly(systex)); CHECK_INTEQUAL(texture_width(texture), 4); CHECK_INTEQUAL(texture_height(texture), 4); CHECK_FLOATEQUAL(texture_scale(texture), 1); CHECK_FALSE(texture_has_mipmaps(texture)); const uint8_t *pixels; CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); texture_forget_readonly(texture); sys_texture_destroy(systex); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_import_readonly_invalid) { CHECK_FALSE(texture_import_readonly(NULL)); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_forget_readonly_locked) { SysTexture *systex; CHECK_TRUE(systex = sys_texture_create(4, 4, TEX_FORMAT_RGBA8888, 0, NULL, 0, NULL, NULL, 0, 0, 0)); int texture; CHECK_TRUE(texture = texture_import_readonly(systex)); const uint8_t *pixels; CHECK_TRUE(pixels = texture_lock_readonly(texture)); texture_forget_readonly(texture); sys_texture_destroy(systex); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_forget_readonly_locked_raw) { SysTexture *systex; CHECK_TRUE(systex = sys_texture_create(4, 4, TEX_FORMAT_RGBA8888, 0, NULL, 0, NULL, NULL, 0, 0, 0)); int texture; CHECK_TRUE(texture = texture_import_readonly(systex)); CHECK_PTREQUAL(texture_lock_raw(texture), systex); texture_forget_readonly(texture); sys_texture_destroy(systex); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_forget_readonly_non_readonly) { int texture; CHECK_TRUE(texture = texture_create_with_data( 4, 4, rgba_4x4, TEX_FORMAT_RGBA8888, 4, 0, 0)); /* This should fail. */ texture_forget_readonly(texture); const uint8_t *pixels; CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_forget_readonly_invalid) { int texture; SysTexture *systex; CHECK_TRUE(systex = sys_texture_create(4, 4, TEX_FORMAT_RGBA8888, 0, NULL, 0, NULL, NULL, 0, 0, 0)); CHECK_TRUE(texture = texture_import_readonly(systex)); texture_forget_readonly(texture); sys_texture_destroy(systex); texture_forget_readonly(texture); // Should log an error but not crash. texture_forget_readonly(INVALID_TEXTURE); // Same. texture_forget_readonly(0); // Should not crash (defined as a no-op). texture_forget_readonly(-1); // Should log an error but not crash. return 1; } /*-----------------------------------------------------------------------*/ TEST(test_readonly_destroy) { SysTexture *systex; /* Safe to de-const the input buffer since we're not reusing it. */ CHECK_TRUE(systex = sys_texture_create( 4, 4, TEX_FORMAT_RGBA8888, 1, (void *)rgba_4x4, 4, (int32_t[]){0}, (int32_t[]){sizeof(rgba_4x4)}, 0, 0, 0)); int texture; CHECK_TRUE(texture = texture_import_readonly(systex)); /* This should fail. */ texture_destroy(texture); const uint8_t *pixels; CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); texture_forget_readonly(texture); sys_texture_destroy(systex); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_readonly_lock_write) { SysTexture *systex; /* Safe to de-const rgba_4x4 since we don't try to reuse it. */ CHECK_TRUE(systex = sys_texture_create( 4, 4, TEX_FORMAT_RGBA8888, 1, (void *)rgba_4x4, 4, (int32_t[]){0}, (int32_t[]){sizeof(rgba_4x4)}, 0, 0, 0)); int texture; CHECK_TRUE(texture = texture_import_readonly(systex)); /* Any lock operation that could modify the texture should fail. */ CHECK_FALSE(texture_lock(texture)); CHECK_FALSE(texture_lock_writeonly(texture)); /* We should still be able to lock read-only because the preceding * lock operations failed. */ const uint8_t *pixels; CHECK_TRUE(pixels = texture_lock_readonly(texture)); CHECK_MEMEQUAL(pixels, rgba_4x4, sizeof(rgba_4x4)); texture_unlock(texture); texture_forget_readonly(texture); sys_texture_destroy(systex); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_apply_invalid) { int texture; CHECK_TRUE(texture = texture_create(4, 2, 0, 0)); /* No return value, so just make sure they don't crash. */ texture_apply(-1, texture); texture_destroy(texture); texture_apply(0, texture); texture_apply(0, INVALID_TEXTURE); texture_apply(0, -1); return 1; } /*-----------------------------------------------------------------------*/ TEST(test_num_units) { CHECK_TRUE(texture_num_units() >= 1); return 1; } /*************************************************************************/ /***************** Texture format tests (run separately) *****************/ /*************************************************************************/ typedef struct TextureTest TextureTest; struct TextureTest { TextureFormat format; const char *format_name; const uint8_t *tex_data; int32_t tex_size; const uint8_t *rgba_data; int width, height, stride; int reuse_alignment; // Alignment required to reuse data, 0 if not possible }; static const TextureTest tests[] = { #define FORMAT_TEST(format,width,height,stride,can_reuse,tex,rgba) \ {TEX_FORMAT_##format, #format, tex_##tex, sizeof(tex_##tex), \ rgba_##rgba, width, height, stride, can_reuse} FORMAT_TEST(RGBA8888, 4, 4, 4, 0, 4x4, 4x4), FORMAT_TEST(RGB565, 4, 4, 4, 0, 4x4_rgb565, 4x4_rgb565), FORMAT_TEST(RGBA5551, 4, 4, 4, 0, 4x4_rgba5551, 4x4_rgba5551), FORMAT_TEST(RGBA4444, 4, 4, 4, 0, 4x4_rgba4444, 4x4_rgba4444), FORMAT_TEST(BGRA8888, 4, 4, 4, 0, 4x4_bgra, 4x4), FORMAT_TEST(BGR565, 4, 4, 4, 0, 4x4_bgr565, 4x4_rgb565), FORMAT_TEST(BGRA5551, 4, 4, 4, 0, 4x4_bgra5551, 4x4_rgba5551), FORMAT_TEST(BGRA4444, 4, 4, 4, 0, 4x4_bgra4444, 4x4_rgba4444), FORMAT_TEST(A8, 4, 4, 4, 0, 4x4_alpha, 4x4_alpha), FORMAT_TEST(L8, 4, 4, 4, 0, 4x4_luminance, 4x4_luminance), FORMAT_TEST(PSP_RGBA8888, 4, 4, 4, 64, 4x4_psp_rgba8888, 4x4), FORMAT_TEST(PSP_RGB565, 4, 4, 8, 64, 4x4_psp_rgb565, 4x4_rgb565), FORMAT_TEST(PSP_RGBA5551, 4, 4, 8, 64, 4x4_psp_rgba5551, 4x4_rgba5551), FORMAT_TEST(PSP_RGBA4444, 4, 4, 8, 64, 4x4_psp_rgba4444, 4x4_rgba4444), FORMAT_TEST(PSP_A8, 4, 4, 16, 64, 4x4_psp_alpha, 4x4_alpha), FORMAT_TEST(PSP_L8, 4, 4, 16, 64, 4x4_psp_luminance, 4x4_luminance), FORMAT_TEST(PSP_PALETTE8_RGBA8888, 4, 4, 16, 64, 4x4_psp_palette8_rgba8888, 4x4), FORMAT_TEST(PSP_RGBA8888_SWIZZLED, 8, 16, 8, 64, 8x16_psp_rgba8888_swizzled, 8x16_psp), FORMAT_TEST(PSP_RGB565_SWIZZLED, 16, 8, 16, 64, 16x8_psp_rgb565_swizzled, 16x8_psp_rgb565), FORMAT_TEST(PSP_RGBA5551_SWIZZLED, 16, 8, 16, 64, 16x8_psp_rgba5551_swizzled, 16x8_psp_rgba5551), FORMAT_TEST(PSP_RGBA4444_SWIZZLED, 16, 8, 16, 64, 16x8_psp_rgba4444_swizzled, 16x8_psp_rgba4444), FORMAT_TEST(PSP_A8_SWIZZLED, 32, 8, 32, 64, 32x8_psp_alpha_swizzled, 32x8_psp_alpha), FORMAT_TEST(PSP_L8_SWIZZLED, 32, 8, 32, 64, 32x8_psp_luminance_swizzled, 32x8_psp_luminance), FORMAT_TEST(PSP_PALETTE8_RGBA8888_SWIZZLED, 32, 8, 32, 64, 32x8_psp_palette8_rgba8888_swizzled, 32x8_psp), FORMAT_TEST(PALETTE8_RGBA8888, 4, 4, 4, 0, 4x4_palette, 4x4), FORMAT_TEST(S3TC_DXT1, 4, 4, 4, 0, 4x4_dxt1, 4x4_dxt1), FORMAT_TEST(S3TC_DXT3, 4, 4, 4, 0, 4x4_dxt3, 4x4_dxt3), FORMAT_TEST(S3TC_DXT5, 4, 4, 4, 0, 4x4_dxt5, 4x4_dxt5), FORMAT_TEST(PVRTC2_RGB, 16, 16, 16, 0, 16x16_pvrtc2_noalpha, 16x16_pvrtc2), FORMAT_TEST(PVRTC2_RGBA, 16, 16, 16, 0, 16x16_pvrtc2, 16x16_pvrtc2), FORMAT_TEST(PVRTC4_RGB, 8, 8, 8, 0, 8x8_pvrtc4_noalpha, 8x8_pvrtc4_noalpha), FORMAT_TEST(PVRTC4_RGBA, 8, 8, 8, 0, 8x8_pvrtc4, 8x8_pvrtc4), #undef FORMAT_TEST }; /*-----------------------------------------------------------------------*/ static int test_one_texture_format(const TextureTest *test, int raw) { void *data = NULL; int texture; if (raw) { const int offset = test->tex_data[16] << 24 | test->tex_data[17] << 16 | test->tex_data[18] << 8 | test->tex_data[19] << 0; texture = texture_create_with_data( test->width, test->height, (void *)(test->tex_data + offset), test->format, test->stride, 0, 0); } else if (test->reuse_alignment) { ASSERT(data = mem_alloc(test->tex_size, test->reuse_alignment, 0)); memcpy(data, test->tex_data, test->tex_size); texture = texture_parse(data, test->tex_size, 0, 0, 1); } else { texture = texture_parse((void *)test->tex_data, test->tex_size, 0, 0, 0); } if (!texture) { /* If the parse failed when it should have succeeded, fail the test. * If it succeeded when it should have failed, keep going (but fail * if the data doesn't match up, as usual). */ if (format_supported(test->format)) { FAIL("Format %s (%s): failed to parse texture", test->format_name, raw ? "raw" : "parsed"); } return 1; } if (!raw && test->reuse_alignment) { SysTexture *systex = texture_lock_raw(texture); CHECK_PTREQUAL(systex, data); texture_unlock(texture); } const int w = texture_width(texture); const int h = texture_height(texture); const uint8_t * pixels = texture_lock_readonly(texture); int from_display = 0; int display_tex = 0; if (!pixels) { /* Try blitting it to the display and grabbing it from there. */ graphics_set_viewport(0, 0, w, h); graphics_set_blend(GRAPHICS_BLEND_ADD, 1, 0); if (test->format == TEX_FORMAT_A8) { graphics_set_fixed_color(&(Vector4f){0,0,0,1}); texture_apply(0, 0); graphics_begin_primitive(GRAPHICS_PRIMITIVE_QUADS); graphics_add_vertex(&(Vector3f){-1,-1,0}, NULL, NULL); graphics_add_vertex(&(Vector3f){-1,+1,0}, NULL, NULL); graphics_add_vertex(&(Vector3f){+1,+1,0}, NULL, NULL); graphics_add_vertex(&(Vector3f){+1,-1,0}, NULL, NULL); graphics_end_and_draw_primitive(); graphics_set_blend(GRAPHICS_BLEND_ADD, GRAPHICS_BLEND_SRC_ALPHA, GRAPHICS_BLEND_INV_SRC_ALPHA); } graphics_set_fixed_color(&(Vector4f){1,1,1,1}); texture_set_antialias(texture, 0); texture_set_repeat(texture, 0, 0); texture_apply(0, texture); graphics_begin_primitive(GRAPHICS_PRIMITIVE_QUADS); graphics_add_vertex(&(Vector3f){-1,-1,0}, &(Vector2f){0,0}, NULL); graphics_add_vertex(&(Vector3f){-1,+1,0}, &(Vector2f){0,1}, NULL); graphics_add_vertex(&(Vector3f){+1,+1,0}, &(Vector2f){1,1}, NULL); graphics_add_vertex(&(Vector3f){+1,-1,0}, &(Vector2f){1,0}, NULL); graphics_end_and_draw_primitive(); texture_apply(0, 0); CHECK_TRUE( display_tex = texture_create_from_display(0, 0, w, h, 1, 0, 0)); CHECK_TRUE(pixels = texture_lock_readonly(display_tex)); from_display = 1; } const uint8_t *expect = test->rgba_data; /* * 5/6-bit to 8-bit color component conversion behavior varies between * renderers: some fill the low bits with 0, some use simple shift-based * rounding (e.g. r<<3 | r>>2), some use proper rounding (r/31.0*255.0). * To account for these, we store the maximum acceptable R/G/B values * in rgba_4x4_{rgb565,argb1555} and accept anything down to the * zero-filled-low-bits value; for example, a component value of 66 for * a 5-bit value would accept 64, 65, or 66 (but not 67 or greater). * * Similarly, different renderers may process compressed pixel data * differently (particularly for widely-supported formats like S3TC), * so we allow a slight difference in each component. */ const int is_16bpp = (test->format == TEX_FORMAT_RGB565 || test->format == TEX_FORMAT_RGBA5551 || test->format == TEX_FORMAT_RGBA4444 || test->format == TEX_FORMAT_BGR565 || test->format == TEX_FORMAT_BGRA5551 || test->format == TEX_FORMAT_BGRA4444 || test->format == TEX_FORMAT_PSP_RGB565 || test->format == TEX_FORMAT_PSP_RGBA5551 || test->format == TEX_FORMAT_PSP_RGBA4444 || test->format == TEX_FORMAT_PSP_RGB565_SWIZZLED || test->format == TEX_FORMAT_PSP_RGBA5551_SWIZZLED || test->format == TEX_FORMAT_PSP_RGBA4444_SWIZZLED); const int is_565 = (test->format == TEX_FORMAT_RGB565 || test->format == TEX_FORMAT_BGR565 || test->format == TEX_FORMAT_PSP_RGB565 || test->format == TEX_FORMAT_PSP_RGB565_SWIZZLED); const int is_4444 = (test->format == TEX_FORMAT_RGBA4444 || test->format == TEX_FORMAT_BGRA4444 || test->format == TEX_FORMAT_PSP_RGBA4444 || test->format == TEX_FORMAT_PSP_RGBA4444_SWIZZLED); const int is_s3tc = (test->format == TEX_FORMAT_S3TC_DXT1 || test->format == TEX_FORMAT_S3TC_DXT3 || test->format == TEX_FORMAT_S3TC_DXT5); const int is_alpha = (test->format == TEX_FORMAT_A8 || test->format == TEX_FORMAT_PSP_A8 || test->format == TEX_FORMAT_PSP_A8_SWIZZLED); for (int i = 0; i < w*h; i++, pixels += 4, expect += 4) { const int x = i % w; const int y = i / w; const uint8_t expect_r = expect[from_display && is_alpha ? 3 : 0]; const uint8_t expect_g = expect[from_display && is_alpha ? 3 : 1]; const uint8_t expect_b = expect[from_display && is_alpha ? 3 : 2]; const uint8_t expect_a = from_display ? 255 : expect[3]; int ok = (pixels[0] == expect_r && pixels[1] == expect_g && pixels[2] == expect_b && pixels[3] == expect_a); if (!ok && is_16bpp) { const uint8_t r_min = expect_r & (is_4444 ? 0xF0 : 0xF8); const uint8_t g_min = expect_g & (is_4444 ? 0xF0 : is_565 ? 0xFC : 0xF8); const uint8_t b_min = expect_b & (is_4444 ? 0xF0 : 0xF8); if ((pixels[0] >= r_min && pixels[0] <= expect_r) && (pixels[1] >= g_min && pixels[1] <= expect_g) && (pixels[2] >= b_min && pixels[2] <= expect_b)) { ok = 1; } } if (!ok && is_s3tc) { const uint8_t r_min = lbound(expect_r - 7, 0); const uint8_t r_max = ubound(expect_r + 7, 255); const uint8_t g_min = lbound(expect_g - 7, 0); const uint8_t g_max = ubound(expect_g + 7, 255); const uint8_t b_min = lbound(expect_b - 7, 0); const uint8_t b_max = ubound(expect_b + 7, 255); const uint8_t a_min = lbound(expect_a - 7, 0); const uint8_t a_max = ubound(expect_a + 7, 255); if ((pixels[0] >= r_min && pixels[0] <= r_max) && (pixels[1] >= g_min && pixels[1] <= g_max) && (pixels[2] >= b_min && pixels[2] <= b_max) && (pixels[3] >= a_min && pixels[3] <= a_max)) { ok = 1; } } if (!ok) { FAIL("Format %s (%s): Pixel (%d,%d) was RGBA (%u,%u,%u,%u)" " but should have been (%u,%u,%u,%u)", test->format_name, raw ? "raw" : "parsed", x, y, pixels[0], pixels[1], pixels[2], pixels[3], expect_r, expect_g, expect_b, expect_a); break; } } texture_unlock(texture); pixels = texture_lock_readonly_partial(texture, 1, 1, w-1, h-1); if (pixels) { expect = test->rgba_data; for (int i = 0; i < w*h; i++, pixels += 4, expect += 4) { const int x = i % w; const int y = i / w; if (x == 0 || y == 0) { pixels -= 4; // Don't advance for this iteration. continue; } const uint8_t expect_r = expect[0]; const uint8_t expect_g = expect[1]; const uint8_t expect_b = expect[2]; const uint8_t expect_a = expect[3]; int ok = (pixels[0] == expect_r && pixels[1] == expect_g && pixels[2] == expect_b && pixels[3] == expect_a); if (!ok && is_16bpp) { const uint8_t r_min = expect_r & (is_4444 ? 0xF0 : 0xF8); const uint8_t g_min = expect_g & (is_4444 ? 0xF0 : is_565 ? 0xFC : 0xF8); const uint8_t b_min = expect_b & (is_4444 ? 0xF0 : 0xF8); if ((pixels[0] >= r_min && pixels[0] <= expect_r) && (pixels[1] >= g_min && pixels[1] <= expect_g) && (pixels[2] >= b_min && pixels[2] <= expect_b)) { ok = 1; } } if (!ok && is_s3tc) { const uint8_t r_min = lbound(expect_r - 7, 0); const uint8_t r_max = ubound(expect_r + 7, 255); const uint8_t g_min = lbound(expect_g - 7, 0); const uint8_t g_max = ubound(expect_g + 7, 255); const uint8_t b_min = lbound(expect_b - 7, 0); const uint8_t b_max = ubound(expect_b + 7, 255); const uint8_t a_min = lbound(expect_a - 7, 0); const uint8_t a_max = ubound(expect_a + 7, 255); if ((pixels[0] >= r_min && pixels[0] <= r_max) && (pixels[1] >= g_min && pixels[1] <= g_max) && (pixels[2] >= b_min && pixels[2] <= b_max) && (pixels[3] >= a_min && pixels[3] <= a_max)) { ok = 1; } } if (!ok) { FAIL("Format %s (%s): Pixel (%d,%d) was RGBA (%u,%u,%u,%u)" " but should have been (%u,%u,%u,%u)", test->format_name, raw ? "raw" : "parsed", x, y, pixels[0], pixels[1], pixels[2], pixels[3], expect_r, expect_g, expect_b, expect_a); break; } } texture_unlock(texture); } // if (pixels) texture_destroy(display_tex); texture_destroy(texture); return 1; } /*-----------------------------------------------------------------------*/ static int do_test_graphics_texture_formats(void) { graphics_start_frame(); int ok = 1; for (int test = 0; test < lenof(tests); test++) { for (int raw = 0; raw <= 1; raw++) { ok &= test_one_texture_format(&tests[test], raw); } } graphics_finish_frame(); graphics_flush_resources(); return ok; } /*-----------------------------------------------------------------------*/ int test_graphics_texture_formats(void) { return run_tests_in_window(do_test_graphics_texture_formats); } /*************************************************************************/ /*************************************************************************/