1 #include "include/usbld.h"
2 #include "include/textures.h"
3 #include "include/util.h"
4 #include "include/ioman.h"
8 extern void *load0_png
;
9 extern void *load1_png
;
10 extern void *load2_png
;
11 extern void *load3_png
;
12 extern void *load4_png
;
13 extern void *load5_png
;
14 extern void *load6_png
;
15 extern void *load7_png
;
21 extern void *cross_png
;
22 extern void *triangle_png
;
23 extern void *circle_png
;
24 extern void *square_png
;
25 extern void *select_png
;
26 extern void *start_png
;
27 extern void *left_png
;
28 extern void *right_png
;
30 extern void *down_png
;
36 extern void *logo_png
;
38 // Not related to screen size, just to limit at some point
39 static int maxWidth
= 640;
40 static int maxHeight
= 512;
48 static texture_t internalDefault
[TEXTURES_COUNT
] = {
49 { LOAD0_ICON
, "load0", &load0_png
},
50 { LOAD1_ICON
, "load1", &load1_png
},
51 { LOAD2_ICON
, "load2", &load2_png
},
52 { LOAD3_ICON
, "load3", &load3_png
},
53 { LOAD4_ICON
, "load4", &load4_png
},
54 { LOAD5_ICON
, "load5", &load5_png
},
55 { LOAD6_ICON
, "load6", &load6_png
},
56 { LOAD7_ICON
, "load7", &load7_png
},
57 { USB_ICON
, "usb", &usb_png
},
58 { HDD_ICON
, "hdd", &hdd_png
},
59 { ETH_ICON
, "eth", ð_png
},
60 { APP_ICON
, "app", &app_png
},
61 { LEFT_ICON
, "left", &left_png
},
62 { RIGHT_ICON
, "right", &right_png
},
63 { UP_ICON
, "up", &up_png
},
64 { DOWN_ICON
, "down", &down_png
},
65 { CROSS_ICON
, "cross", &cross_png
},
66 { TRIANGLE_ICON
, "triangle", &triangle_png
},
67 { CIRCLE_ICON
, "circle", &circle_png
},
68 { SQUARE_ICON
, "square", &square_png
},
69 { SELECT_ICON
, "select", &select_png
},
70 { START_ICON
, "start", &start_png
},
71 { L1_ICON
, "L1", &L1_png
},
72 { L2_ICON
, "L2", &L2_png
},
73 { R1_ICON
, "R1", &R1_png
},
74 { R2_ICON
, "R2", &R2_png
},
75 { LOGO_PICTURE
, "logo", &logo_png
},
78 static void texUpdate(GSTEXTURE
* texture
, int width
, int height
) {
79 texture
->Width
= width
;
80 texture
->Height
= height
;
83 void texPrepare(GSTEXTURE
* texture
, short psm
) {
86 texture
->Filter
= GS_FILTER_LINEAR
;
89 texture
->VramClut
= 0;
91 //gsKit_setup_tbw(texture); already done in gsKit_texture_upload
94 int texDiscoverLoad(GSTEXTURE
* texture
, char* path
, int texId
, short psm
) {
95 int rc
= texPngLoad(texture
, path
, texId
, psm
);
100 scr_printf("PNG EXIT CODE: %d\n", rc);
106 else if (psm
== GS_PSM_CT24
)
107 return texJpgLoad(texture
, path
, texId
, psm
);
112 /// PNG SUPPORT ///////////////////////////////////////////////////////////////////////////////////////
115 static int texPngEnd(png_structp pngPtr
, png_infop infoPtr
, FILE* file
, int status
) {
120 png_destroy_read_struct(&pngPtr
, &infoPtr
, (png_infopp
) NULL
);
125 static void texPngReadFunction(png_structp pngPtr
, png_bytep data
, png_size_t length
)
127 FILE* File
= (FILE*) pngPtr
->io_ptr
;
128 if(fread(data
, length
, 1, File
) <= 0)
130 png_error(pngPtr
, "Error reading via fread\n");
135 static void texPngReadMemFunction(png_structp pngPtr
, png_bytep data
, png_size_t length
)
137 u8
* memBuffer
= (u8
*) pngPtr
->io_ptr
;
138 memcpy(data
, memBuffer
, length
);
139 pngPtr
->io_ptr
= memBuffer
+ length
;
143 static void texPngReadPixels24(GSTEXTURE
* texture
, png_bytep
* rowPointers
) {
144 struct pixel3
{ unsigned char r
,g
,b
; };
145 struct pixel3
*Pixels
= (struct pixel3
*) texture
->Mem
;
148 for (i
= 0; i
< texture
->Height
; i
++) {
149 for (j
= 0; j
< texture
->Width
; j
++) {
150 memcpy(&Pixels
[k
++], &rowPointers
[i
][4 * j
], 3);
155 static void texPngReadPixels32(GSTEXTURE
* texture
, png_bytep
* rowPointers
) {
156 struct pixel
{ unsigned char r
,g
,b
,a
; };
157 struct pixel
*Pixels
= (struct pixel
*) texture
->Mem
;
160 for (i
= 0; i
< texture
->Height
; i
++) {
161 for (j
= 0; j
< texture
->Width
; j
++) {
162 memcpy(&Pixels
[k
], &rowPointers
[i
][4 * j
], 3);
163 Pixels
[k
++].a
= rowPointers
[i
][4 * j
+ 3] >> 1;
168 static void texPngReadData(GSTEXTURE
* texture
, png_structp pngPtr
, png_infop infoPtr
,
169 void (*texPngReadPixels
)(GSTEXTURE
* texture
, png_bytep
*rowPointers
)) {
170 int row
, rowBytes
= png_get_rowbytes(pngPtr
, infoPtr
);
171 size_t size
= gsKit_texture_size_ee(texture
->Width
, texture
->Height
, texture
->PSM
);
172 texture
->Mem
= memalign(128, size
);
176 LOG("TEXTURES PngReadData: Failed to allocate %d bytes\n", size
);
180 png_bytep
*rowPointers
= calloc(texture
->Height
, sizeof(png_bytep
));
181 for (row
= 0; row
< texture
->Height
; row
++) {
182 rowPointers
[row
] = malloc(rowBytes
);
184 png_read_image(pngPtr
, rowPointers
);
186 texPngReadPixels(texture
, rowPointers
);
188 for (row
= 0; row
< texture
->Height
; row
++)
189 free(rowPointers
[row
]);
193 png_read_end(pngPtr
, NULL
);
196 int texPngLoad(GSTEXTURE
* texture
, char* path
, int texId
, short psm
) {
197 texPrepare(texture
, psm
);
198 png_structp pngPtr
= NULL
;
199 png_infop infoPtr
= NULL
;
200 png_voidp readData
= NULL
;
201 png_rw_ptr readFunction
= NULL
;
207 snprintf(filePath
, 255, "%s%s.png", path
, internalDefault
[texId
].name
);
209 snprintf(filePath
, 255, "%s.png", path
);
211 file
= fopen(filePath
, "r");
216 readFunction
= &texPngReadFunction
;
219 readData
= internalDefault
[texId
].texture
;
223 readFunction
= &texPngReadMemFunction
;
226 pngPtr
= png_create_read_struct(PNG_LIBPNG_VER_STRING
, (png_voidp
) NULL
, NULL
, NULL
);
228 return texPngEnd(pngPtr
, infoPtr
, file
, ERR_READ_STRUCT
);
230 infoPtr
= png_create_info_struct(pngPtr
);
232 return texPngEnd(pngPtr
, infoPtr
, file
, ERR_INFO_STRUCT
);
234 if(setjmp(pngPtr
->jmpbuf
))
235 return texPngEnd(pngPtr
, infoPtr
, file
, ERR_SET_JMP
);
237 png_set_read_fn(pngPtr
, readData
, readFunction
);
238 unsigned int sigRead
= 0;
239 png_set_sig_bytes(pngPtr
, sigRead
);
240 png_read_info(pngPtr
, infoPtr
);
242 png_uint_32 pngWidth
, pngHeight
;
243 int bitDepth
, colorType
, interlaceType
;
244 png_get_IHDR(pngPtr
, infoPtr
, &pngWidth
, &pngHeight
, &bitDepth
, &colorType
, &interlaceType
, NULL
, NULL
);
245 if (pngWidth
> maxWidth
|| pngHeight
> maxHeight
)
246 return texPngEnd(pngPtr
, infoPtr
, file
, ERR_BAD_DIMENSION
);
247 texUpdate(texture
, pngWidth
, pngHeight
);
249 void (*texPngReadPixels
)(GSTEXTURE
* texture
, png_bytep
*rowPointers
);
250 if(pngPtr
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
252 // if PNG have alpha, then it fits for every case (even if we only wanted RGB)
253 texture
->PSM
= GS_PSM_CT32
;
254 texPngReadPixels
= &texPngReadPixels32
;
256 else if(pngPtr
->color_type
== PNG_COLOR_TYPE_RGB
)
258 if (psm
!= GS_PSM_CT24
)
259 return texPngEnd(pngPtr
, infoPtr
, file
, ERR_MISSING_ALPHA
);
261 texPngReadPixels
= &texPngReadPixels24
;
264 return texPngEnd(pngPtr
, infoPtr
, file
, ERR_BAD_DEPTH
);
266 png_set_strip_16(pngPtr
);
268 if (colorType
== PNG_COLOR_TYPE_PALETTE
)
269 png_set_expand(pngPtr
);
271 if (colorType
== PNG_COLOR_TYPE_GRAY
&& bitDepth
< 8)
272 png_set_expand(pngPtr
);
274 if (png_get_valid(pngPtr
, infoPtr
, PNG_INFO_tRNS
))
275 png_set_tRNS_to_alpha(pngPtr
);
277 png_set_filler(pngPtr
, 0xff, PNG_FILLER_AFTER
);
278 png_read_update_info(pngPtr
, infoPtr
);
279 texPngReadData(texture
, pngPtr
, infoPtr
, texPngReadPixels
);
281 return texPngEnd(pngPtr
, infoPtr
, file
, 0);
285 /// JPG SUPPORT ///////////////////////////////////////////////////////////////////////////////////////
288 int texJpgLoad(GSTEXTURE
* texture
, char* path
, int texId
, short psm
) {
289 texPrepare(texture
, GS_PSM_CT24
);
290 int result
= ERR_BAD_FILE
;
295 snprintf(filePath
, 255, "%s%s.jpg", path
, internalDefault
[texId
].name
);
297 snprintf(filePath
, 255, "%s.jpg", path
);
298 FILE* file
= fopen(filePath
, "r");
300 jpg
= jpgOpenFILE(file
, JPG_NORMAL
);
302 if (jpg
->width
> maxWidth
|| jpg
->height
> maxHeight
)
303 return ERR_BAD_DIMENSION
;
305 size_t size
= gsKit_texture_size_ee(jpg
->width
, jpg
->height
, psm
);
306 texture
->Mem
= memalign(128, size
);
310 LOG("TEXTURES JpgLoad: Failed to allocate %d bytes\n", size
);
313 texUpdate(texture
, jpg
->width
, jpg
->height
);
315 jpgReadImage(jpg
, (void*) texture
->Mem
);