00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "vlib.h"
00027
00028
00029
00030
00031
00032 static int getPow2 ( int value ) {
00033 int b = value;
00034 int n;
00035
00036 for ( n = 0; b != 0; n++ )
00037 b >>= 1;
00038
00039 b = 1 << n;
00040
00041 if ( b == 2 * value )
00042 b >>= 1;
00043
00044 return b;
00045 }
00046
00047 static void load_png ( const char *filename, Image *img ) {
00048
00049 FILE *fp;
00050
00051 if ( ( fp = fopen ( filename, "rb" ) ) == NULL )
00052 return;
00053
00054 png_structp png_ptr;
00055 png_infop info_ptr;
00056 unsigned int sig_read = 0;
00057 png_uint_32 width, height;
00058 int bit_depth, color_type, interlace_type, x, y;
00059
00060 png_ptr = png_create_read_struct ( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL );
00061 info_ptr = png_create_info_struct ( png_ptr );
00062 png_init_io ( png_ptr, fp );
00063 png_set_sig_bytes ( png_ptr, sig_read );
00064 png_read_info ( png_ptr, info_ptr );
00065 png_get_IHDR ( png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, int_p_NULL, int_p_NULL );
00066
00067 img->initWidth = width;
00068 img->initHeight = height;
00069 img->width = width;
00070 img->height = height;
00071 img->realWidth = getPow2 ( width );
00072 img->realHeight = getPow2 ( height );
00073
00074 img->totalSize = img->realWidth * img->realHeight * sizeof ( u32 );
00075
00076 png_set_strip_16 ( png_ptr );
00077 png_set_packing ( png_ptr );
00078
00079 if ( color_type == PNG_COLOR_TYPE_PALETTE )
00080 png_set_palette_to_rgb ( png_ptr );
00081
00082 if ( color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8 )
00083 png_set_gray_1_2_4_to_8 ( png_ptr );
00084
00085 if ( png_get_valid ( png_ptr, info_ptr, PNG_INFO_tRNS ) )
00086 png_set_tRNS_to_alpha ( png_ptr );
00087
00088 png_set_filler ( png_ptr, 0xff, PNG_FILLER_AFTER );
00089
00090 img->data = ( u32* ) malloc ( img->totalSize );
00091
00092 u32* line = ( u32* ) malloc ( width * 4 );
00093
00094 for ( y = 0; y < ( int ) height; y++ ) {
00095 png_read_row ( png_ptr, ( u8* ) line, png_bytep_NULL );
00096 for ( x = 0; x < ( int ) width; x++ ) {
00097 u32 color = line[x];
00098 img->data[x + y * ( int ) img->realWidth] = color;
00099 }
00100 }
00101
00102 free ( line );
00103
00104 png_read_end ( png_ptr, info_ptr );
00105 png_destroy_read_struct ( &png_ptr, &info_ptr, png_infopp_NULL );
00106
00107
00108 fclose ( fp );
00109 }
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 static void load_tga ( const char *filename, Image *img ) {
00241
00242 FILE *fp;
00243
00244 if ( ( fp = fopen ( filename, "rb" ) ) == NULL )
00245 return;
00246
00247 unsigned char ucharBad;
00248
00249 short int sintBad;
00250
00251 int colorMode;
00252
00253 long imageIdx;
00254
00255 unsigned char colorSwap;
00256
00257 unsigned char imageTypeCode;
00258
00259 unsigned char bitCount;
00260
00261
00262 fread ( &ucharBad, sizeof ( unsigned char ), 1, fp );
00263
00264 fread ( &ucharBad, sizeof ( unsigned char ), 1, fp );
00265
00266
00267 fread ( &imageTypeCode, sizeof ( unsigned char ), 1, fp );
00268
00269
00270 if ( ( imageTypeCode != 2 ) && ( imageTypeCode != 3 ) ) {
00271 fclose ( fp );
00272 return;
00273 }
00274
00275
00276 fread ( &sintBad, sizeof ( short int ), 1, fp );
00277
00278 fread ( &sintBad, sizeof ( short int ), 1, fp );
00279
00280 fread ( &ucharBad, sizeof ( unsigned char ), 1, fp );
00281
00282 fread ( &sintBad, sizeof ( short int ), 1, fp );
00283
00284 fread ( &sintBad, sizeof ( short int ), 1, fp );
00285
00286
00287 fread ( &img->initWidth, sizeof ( short int ), 1, fp );
00288
00289 fread ( &img->initHeight, sizeof ( short int ), 1, fp );
00290
00291 img->width = img->initWidth;
00292
00293 img->height = img->initHeight;
00294
00295 img->realWidth = getPow2 ( img->initWidth );
00296
00297 img->realHeight = getPow2 ( img->initHeight );
00298
00299
00300 fread ( &bitCount, sizeof ( unsigned char ), 1, fp );
00301
00302
00303 fread ( &ucharBad, sizeof ( unsigned char ), 1, fp );
00304
00305
00306 colorMode = bitCount / 8;
00307
00308 img->totalSize = img->realWidth * img->realHeight * colorMode;
00309
00310
00311 img->data = ( u32* ) malloc ( sizeof ( u32 ) * img->totalSize );
00312
00313
00314 fread ( img->data, sizeof ( u32 ), img->totalSize, fp );
00315
00316
00317 for ( imageIdx = 0; imageIdx < img->totalSize; imageIdx += colorMode ) {
00318 colorSwap = img->data[imageIdx];
00319 img->data[imageIdx] = img->data[imageIdx+2];
00320 img->data[imageIdx + 2] = colorSwap;
00321 }
00322
00323
00324 fclose ( fp );
00325 }
00326
00327
00328
00329 static void load_jpg ( const char *filename, Image *img ) {
00330
00331 struct jpeg_decompress_struct cinfo;
00332
00333
00334 FILE *fp;
00335
00336 if ( ( fp = fopen ( filename, "rb" ) ) == NULL )
00337 return;
00338
00339 pspDebugScreenPrintf ( "Blah" );
00340
00341 sceKernelDelayThread ( 10000 );
00342
00343
00344
00345 struct jpeg_error_mgr jerr;
00346
00347
00348 cinfo.err = jpeg_std_error ( &jerr );
00349
00350
00351 jpeg_create_decompress ( &cinfo );
00352
00353
00354 jpeg_stdio_src ( &cinfo, fp );
00355
00356
00357 jpeg_read_header ( &cinfo, TRUE );
00358
00359
00360 jpeg_start_decompress ( &cinfo );
00361
00362
00363 int rowSpan = cinfo.image_width * cinfo.num_components;
00364
00365 img->initWidth = cinfo.image_width;
00366
00367 img->initHeight = cinfo.image_height;
00368
00369 img->realWidth = getPow2 ( cinfo.image_width );
00370
00371 img->realHeight = getPow2 ( cinfo.image_height );
00372
00373 img->totalSize = img->initWidth * img->initHeight * sizeof ( u32 );
00374
00375
00376 img->data = ( u32* ) malloc ( img->totalSize );
00377
00378
00379 u32* rowPtr = ( u32* ) malloc ( img->realHeight * sizeof ( u32 ) );
00380
00381 int i;
00382
00383 for ( i = 0; i < img->realHeight; i++ )
00384 rowPtr[i] = ( unsigned char ) img->data[i * rowSpan];
00385
00386
00387 int rowsRead = 0;
00388
00389 while ( cinfo.output_scanline < cinfo.output_height )
00390
00391 rowsRead += jpeg_read_scanlines ( &cinfo, ( JSAMPARRAY ) & rowPtr[rowsRead], cinfo.output_height - rowsRead );
00392
00393 free ( rowPtr );
00394
00395
00396 jpeg_finish_decompress ( &cinfo );
00397
00398
00399 jpeg_destroy_decompress ( &cinfo );
00400
00401 fclose ( fp );
00402 }
00403
00404 static void swizzle_image ( Image *img ) {
00405
00406 int rowblocks = ( ( img->realWidth * 4 ) / 16 );
00407 int rowblocks_add = ( rowblocks - 1 ) * 128;
00408 unsigned int block_address = 0;
00409 unsigned int *src = ( unsigned int* ) img->data;
00410
00411 static u8 *t_data;
00412 t_data = ( u8* ) malloc ( img->totalSize );
00413
00414 int j;
00415 for ( j = 0; j < img->realHeight; j++, block_address += 16 ) {
00416 unsigned int *block = ( unsigned int* ) ( ( unsigned int ) & t_data[block_address] | 0x40000000 );
00417 int i;
00418
00419 for ( i = 0; i < rowblocks; i++ ) {
00420 *block++ = *src++;
00421 *block++ = *src++;
00422 *block++ = *src++;
00423 *block++ = *src++;
00424 block += 28;
00425 }
00426
00427 if ( ( j&0x7 ) == 0x7 )
00428 block_address += rowblocks_add;
00429 }
00430
00431 free ( img->data );
00432
00433 if ( img->location )
00434 img->data = ( u32* ) valloc ( img->totalSize );
00435 else
00436 img->data = ( u32* ) malloc ( img->totalSize );
00437
00438
00439 memcpy ( img->data, t_data, img->totalSize );
00440
00441 free ( t_data );
00442
00443 sceKernelDcacheWritebackAll();
00444 }
00445
00446 Image *load_image ( const char *filename, int location ) {
00447
00448 Image *img = ( Image* ) malloc ( sizeof ( Image ) );
00449 img->location = location;
00450
00451
00452
00453 const char *suffix = strrchr ( filename, '.' );
00454
00455
00456 if ( strcmp ( suffix, ".png" ) == 0 )
00457 load_png ( filename, img );
00458
00459
00460
00461 else if ( strcmp ( suffix, ".tga" ) == 0 )
00462 load_tga ( filename, img );
00463 else if ( strcmp ( suffix, ".jpg" ) == 0 )
00464 load_jpg ( filename, img );
00465
00466 sceKernelDcacheWritebackAll();
00467
00468
00469 swizzle_image ( img );
00470
00471 img->x = 0.0f;
00472 img->y = 0.0f;
00473 img->startX = 0.0f;
00474 img->startY = 0.0f;
00475 img->endX = img->width;
00476 img->endY = img->height;
00477 img->angle = 0.0f;
00478 img->centerX = 0.0f;
00479 img->centerY = 0.0f;
00480
00481
00482 sceKernelDcacheWritebackAll();
00483
00484 return img;
00485 }
00486
00487 void unload_image ( Image *img ) {
00488 if ( img->location )
00489 vfree ( img->data );
00490 else
00491 free ( img->data );
00492
00493 free ( img );
00494 }
00495
00496 void draw_image ( Image *img ) {
00497 if ( !img->width || !img->endX )
00498 return;
00499
00500 float u_end = img->endX - img->startX;
00501 float u_width = img->endX / ( img->width / 64.0f );
00502 float cur_u = img->startX;
00503 float cur_x = 0.0f;
00504
00505
00506 vfpu_identity_m ( &m_ortho_view );
00507 vfpu_translate_m ( &m_ortho_view, img->x, img->y, 0.0f );
00508
00509 vfpu_identity_m ( &m_ortho_model );
00510 vfpu_rotateZ_m ( &m_ortho_model, img->angle );
00511 vfpu_translate_m ( &m_ortho_model, img->centerX, img->centerY, 0.0f );
00512
00513 sceGuSetMatrix ( GU_PROJECTION, &m_ortho );
00514 sceGuSetMatrix ( GU_VIEW, &m_ortho_view );
00515 sceGuSetMatrix ( GU_MODEL, &m_ortho_model );
00516
00517 float u = 1.0f / ( ( float ) img->initWidth );
00518 float v = 1.0f / ( ( float ) img->initHeight );
00519 sceGuTexScale ( u, v );
00520
00521
00522 sceGuTexImage ( 0, img->realWidth, img->realHeight, img->realWidth, ( void* ) img->data );
00523
00524 while ( cur_x != img->width ) {
00525 TP_Vertex_3D* vertices = ( TP_Vertex_3D* ) sceGuGetMemory ( 4 * sizeof ( TP_Vertex_3D ) );
00526
00527 vertices[0].u = cur_u;
00528 vertices[0].v = img->startY;
00529 vertices[0].x = cur_x;
00530 vertices[0].y = 0.0f;
00531 vertices[0].z = 0.0f;
00532
00533 vertices[2].u = cur_u;
00534 vertices[2].v = img->endY;
00535 vertices[2].x = cur_x;
00536 vertices[2].y = img->height;
00537 vertices[2].z = 0.0f;
00538
00539 cur_u += u_width;
00540 cur_x += 64.0f;
00541
00542 if ( cur_x > img->width ) {
00543 cur_x = img->width;
00544 cur_u = u_end;
00545 }
00546
00547 vertices[1].u = cur_u;
00548 vertices[1].v = img->startY;
00549 vertices[1].x = cur_x;
00550 vertices[1].y = 0.0f;
00551 vertices[1].z = 0.0f;
00552
00553 vertices[3].u = cur_u;
00554 vertices[3].v = img->endY;
00555 vertices[3].x = cur_x;
00556 vertices[3].y = img->height;
00557 vertices[3].z = 0.0f;
00558
00559 sceGuDrawArray ( GU_TRIANGLE_STRIP, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_3D, 4, 0, vertices );
00560 }
00561 sceGuTexScale ( 1.0f, 1.0f );
00562 }
00563
00564 void set_linear_filter ( short state ) {
00565 if ( drawingStarted ) {
00566 sceGuTexFilter ( state, state );
00567 return;
00568 }
00569
00570 sceGuStart ( GU_DIRECT, DList );
00571 sceGuTexFilter ( state, state );
00572 sceGuFinish();
00573 sceGuSync ( 0, 0 );
00574 }