Advertisement
Guest User

Untitled

a guest
Jun 24th, 2017
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 15.55 KB | None | 0 0
  1. // gLib2D by Geecko - A simple, fast, light-weight 2D graphics library.
  2. //
  3. // This work is licensed under the Creative Commons BY-SA 3.0 Unported License.
  4. // See LICENSE for more details.
  5.  
  6. #include "glib2d.h"
  7.  
  8. #include <pspkernel.h>
  9. #include <pspdebug.h>
  10. #include <pspdisplay.h>
  11. #include <pspgu.h>
  12. #include <malloc.h>
  13. #include <string.h>
  14. #include <math.h>
  15.  
  16. #ifdef USE_PNG
  17. #include <png.h>
  18. #endif
  19.  
  20. #define PSP_LINE_SIZE       (512)
  21. #define PIXEL_SIZE          (4)
  22. #define FRAMEBUFFER_SIZE    (PSP_LINE_SIZE*G_SCR_H*PIXEL_SIZE)
  23. #define MALLOC_STEP         (10)
  24. #define TRANSFORM_STACK_MAX (64)
  25.  
  26. #define DEFAULT_SIDE       (10)
  27. #define DEFAULT_COORD_MODE (G_UP_LEFT)
  28. #define DEFAULT_X          (0.f)
  29. #define DEFAULT_Y          (0.f)
  30. #define DEFAULT_Z          (0.f)
  31. #define DEFAULT_COLOR      (WHITE)
  32. #define DEFAULT_ALPHA      (0xFF)
  33.  
  34. #define CURRENT_OBJ obj_list[obj_list_size]
  35. #define CURRENT_TRANSFORM transform_stack[transform_stack_size]
  36. #define I_OBJ obj_list[i]
  37.  
  38. typedef struct
  39. {
  40.   float x, y, z;
  41.   float rot, rot_sin, rot_cos;
  42. } Transform;
  43.  
  44. typedef struct
  45. {
  46.   float x, y, z;
  47.   float rot_x, rot_y;
  48.   float rot_sin, rot_cos;
  49.   int crop_x, crop_y;
  50.   int crop_w, crop_h;
  51.   int scale_w, scale_h;
  52.   gColor color;
  53. } Obj_Properties;
  54.  
  55. // * Main vars *
  56. static unsigned int __attribute__((aligned(16))) gu_list[262144];
  57. bool init = G_FALSE, start = G_FALSE, zclear = G_TRUE;
  58. Transform transform_stack[TRANSFORM_STACK_MAX];
  59. int transform_stack_size;
  60. // * Object vars *
  61. Obj_Properties* obj_list = NULL;
  62. int obj_list_size, obj_list_size_malloc; // Real & malloc'ed size
  63. bool obj_begin = G_FALSE;
  64. bool obj_use_z, obj_use_vert_color, obj_use_blend, obj_use_rot, obj_use_tex;
  65. // * Coord vars *
  66. gEnum obj_coord_mode;
  67. float obj_x, obj_y, obj_z;
  68. // * Crop vars *
  69. int obj_crop_x, obj_crop_y;
  70. int obj_crop_w, obj_crop_h;
  71. // * Scale vars *
  72. float obj_scale_w, obj_scale_h;
  73. // * Color & alpha vars *
  74. gColor obj_color;
  75. gAlpha obj_alpha;
  76. bool obj_colors_count, obj_alpha_count;
  77. // * Rotation vars *
  78. float obj_rot, obj_rot_sin, obj_rot_cos;
  79. // * Texture vars *
  80. gImage* obj_tex;
  81.  
  82. // * Internal functions *
  83.  
  84. void _gInit()
  85. {
  86.   // Init & setup GU
  87.   sceGuInit();
  88.   sceGuStart(GU_DIRECT,gu_list);
  89.  
  90.   sceGuDrawBuffer(GU_PSM_8888,(void*)FRAMEBUFFER_SIZE,PSP_LINE_SIZE);
  91.   sceGuDispBuffer(G_SCR_W,G_SCR_H,(void*)0,PSP_LINE_SIZE);
  92.   sceGuDepthBuffer((void*)(FRAMEBUFFER_SIZE*2),PSP_LINE_SIZE);
  93.   sceGuOffset(2048-(G_SCR_W/2),2048-(G_SCR_H/2));
  94.   sceGuViewport(2048,2048,G_SCR_W,G_SCR_H);
  95.  
  96.   sceGuScissor(0,0,G_SCR_W,G_SCR_H);
  97.   sceGuDepthRange(65535,0);
  98.   sceGuClearDepth(65535);
  99.   sceGuAlphaFunc(GU_GREATER,0,0xff);
  100.   sceGuDepthFunc(GU_LEQUAL);
  101.   sceGuBlendFunc(GU_ADD,GU_SRC_ALPHA,GU_ONE_MINUS_SRC_ALPHA,0,0);
  102.   sceGuTexFunc(GU_TFX_MODULATE,GU_TCC_RGBA);
  103.   sceGuTexFilter(GU_LINEAR,GU_LINEAR);
  104.   sceGuShadeModel(GU_FLAT);
  105.  
  106.   sceGuDisable(GU_CULL_FACE);
  107.   sceGuDisable(GU_CLIP_PLANES);
  108.   sceGuDisable(GU_DITHER);
  109.   sceGuEnable(GU_ALPHA_TEST);
  110.   sceGuEnable(GU_SCISSOR_TEST);
  111.  
  112.   sceGuFinish();
  113.   sceGuSync(0,0);
  114.   sceDisplayWaitVblankStart();
  115.   sceGuDisplay(GU_TRUE);
  116.  
  117.   init = G_TRUE;
  118. }
  119.  
  120.  
  121. void _gStart()
  122. {
  123.   if (!init) _gInit();
  124.  
  125.   sceKernelDcacheWritebackAll();
  126.   sceGuStart(GU_DIRECT,gu_list);
  127.   start = G_TRUE;
  128. }
  129.  
  130.  
  131. void _gCoordInit()
  132. {
  133.   gResetCoord();
  134.   obj_use_z = G_FALSE;
  135. }
  136.  
  137.  
  138. void _gScaleInit()
  139. {
  140.   gResetScale();
  141. }
  142.  
  143.  
  144. void _gColorInit()
  145. {
  146.   gResetColor();
  147.   obj_colors_count = 0;
  148.   obj_use_vert_color = G_FALSE;
  149. }
  150.  
  151.  
  152. void _gAlphaInit()
  153. {
  154.   gResetAlpha();
  155.   obj_use_blend = G_FALSE;
  156. }
  157.  
  158.  
  159. void _gRotationInit()
  160. {
  161.   gResetRotation();
  162.   obj_use_rot = G_FALSE;
  163. }
  164.  
  165.  
  166. void _gCropInit()
  167. {
  168.   gResetCrop();
  169. }
  170.  
  171. // Vertex order: [texture uv] [color] [vertex]
  172. void* _gSetVertex(void* v, int i, bool x, bool y)
  173. {
  174.   short* v_p_short = v;
  175.   gColor* v_p_color;
  176.   float* v_p_float = v;
  177.  
  178.   // Texture
  179.   if (obj_use_tex)
  180.   {
  181.     *(v_p_short++) = I_OBJ.crop_x + (x ? I_OBJ.crop_w : 0);
  182.     *(v_p_short++) = I_OBJ.crop_y + (y ? I_OBJ.crop_h : 0);
  183.   }
  184.   // Color
  185.   v_p_color = (gColor*)v_p_short;
  186.   if (obj_use_vert_color) *(v_p_color++) = I_OBJ.color;
  187.   // Coord
  188.   v_p_float = (float*)v_p_color;
  189.   v_p_float[0] = I_OBJ.x + (x ? I_OBJ.scale_w : 0);
  190.   v_p_float[1] = I_OBJ.y + (y ? I_OBJ.scale_h : 0);
  191.   v_p_float[2] = I_OBJ.z;
  192.   if (obj_use_rot) // Apply the rotation
  193.   {
  194.     float tx = v_p_float[0]-I_OBJ.rot_x, ty = v_p_float[1]-I_OBJ.rot_y;
  195.     v_p_float[0] = I_OBJ.rot_x - I_OBJ.rot_sin*ty + I_OBJ.rot_cos*tx,
  196.     v_p_float[1] = I_OBJ.rot_y + I_OBJ.rot_cos*ty + I_OBJ.rot_sin*tx;
  197.   }
  198.   v_p_float += 3;
  199.  
  200.   return (void*)v_p_float;
  201. }
  202.  
  203.  
  204. // Insertion sort, because it is a fast and _stable_ sort.
  205. void _gVertexSort()
  206. {
  207.   int i, j;
  208.   Obj_Properties obj_tmp;
  209.   for (i=1; i<obj_list_size; i++)
  210.   {
  211.     j = i;
  212.     memcpy(&obj_tmp,obj_list+j,sizeof(Obj_Properties));
  213.     while (j>0 && obj_list[j-1].z < obj_tmp.z)
  214.     {
  215.       memcpy(obj_list+j,obj_list+j-1,sizeof(Obj_Properties));
  216.       j--;
  217.     }
  218.     memcpy(obj_list+j,&obj_tmp,sizeof(Obj_Properties));
  219.   }
  220. }
  221.  
  222. // * Main functions *
  223.  
  224. void gClear(gColor color)
  225. {
  226.   if (!start) _gStart();
  227.  
  228.   sceGuClearColor(color);
  229.   sceGuClear(GU_COLOR_BUFFER_BIT | GU_FAST_CLEAR_BIT
  230.              | (zclear ? GU_DEPTH_BUFFER_BIT : 0));
  231.   zclear = G_FALSE;
  232. }
  233.  
  234.  
  235. void gClearZ()
  236. {
  237.   sceGuClear(GU_DEPTH_BUFFER_BIT | GU_FAST_CLEAR_BIT);
  238.   zclear = G_TRUE;
  239. }
  240.  
  241.  
  242. void gBegin(gImage* tex, bool use_tex_blend)
  243. {
  244.   if (obj_begin) return;
  245.   if (!start) _gStart();
  246.  
  247.   obj_list_size = 0;
  248.   obj_list_size_malloc = MALLOC_STEP;
  249.   obj_list = realloc(obj_list,obj_list_size_malloc * sizeof(Obj_Properties));
  250.  
  251.   if (tex == NULL) obj_use_tex = G_FALSE;
  252.   else
  253.   {
  254.     obj_use_tex = G_TRUE;
  255.     obj_tex = tex;
  256.     _gCropInit();
  257.     if (use_tex_blend) obj_use_blend = G_TRUE;
  258.   }
  259.  
  260.   _gCoordInit();
  261.   _gScaleInit();
  262.   _gColorInit();
  263.   _gAlphaInit();
  264.   _gRotationInit();
  265.  
  266.   obj_begin = G_TRUE;
  267. }
  268.  
  269.  
  270. void gEnd()
  271. {
  272.   if (!obj_begin || obj_list_size <= 0) return;
  273.  
  274.   // Horror : we need to sort the vertices.
  275.   if (obj_use_z && obj_use_blend) _gVertexSort();
  276.  
  277.   int prim = (obj_use_rot) ? GU_TRIANGLES : GU_SPRITES,
  278.       v_obj_nbr = (obj_use_rot) ? 6 : 2,
  279.       v_nbr = v_obj_nbr * obj_list_size,
  280.       v_coord_size = 3,
  281.       v_tex_size = (obj_use_tex) ? 2 : 0,
  282.       v_color_size = (obj_use_vert_color) ? 1 : 0,
  283.       v_size = v_tex_size * sizeof(short) +
  284.                v_color_size * sizeof(gColor) +
  285.                v_coord_size * sizeof(float),
  286.       v_type = GU_VERTEX_32BITF | GU_TRANSFORM_2D,
  287.       i;
  288.  
  289.   if (obj_use_tex)        v_type |= GU_TEXTURE_16BIT;
  290.   if (obj_use_vert_color) v_type |= GU_COLOR_8888;
  291.  
  292.   void *v = sceGuGetMemory(v_nbr * v_size), *vi = v;
  293.  
  294.   for (i=0; i!=obj_list_size; i++)
  295.   {
  296.     if (!obj_use_rot)
  297.     {
  298.       vi = _gSetVertex(vi,i,0,0);
  299.       vi = _gSetVertex(vi,i,1,1);
  300.     }
  301.     else // Draw 2 triangles per obj
  302.     {
  303.       vi = _gSetVertex(vi,i,0,0);
  304.       vi = _gSetVertex(vi,i,1,0);
  305.       vi = _gSetVertex(vi,i,0,1);
  306.       vi = _gSetVertex(vi,i,0,1);
  307.       vi = _gSetVertex(vi,i,1,0);
  308.       vi = _gSetVertex(vi,i,1,1);
  309.     }
  310.   }
  311.  
  312.   if (obj_use_z)          sceGuEnable(GU_DEPTH_TEST);
  313.   else                    sceGuDisable(GU_DEPTH_TEST);
  314.   if (obj_use_blend)      sceGuEnable(GU_BLEND);
  315.   else                    sceGuDisable(GU_BLEND);
  316.   if (obj_use_vert_color) sceGuColor(WHITE);
  317.   else                    sceGuColor(obj_color);
  318.   if (obj_use_tex)        sceGuEnable(GU_TEXTURE_2D);
  319.   else                    sceGuDisable(GU_TEXTURE_2D);
  320.  
  321.   if (obj_use_tex)
  322.   {
  323.     sceGuTexMode(GU_PSM_8888,0,0,0/*TODO swizzling*/);
  324.     sceGuTexImage(0,obj_tex->tw,obj_tex->th,obj_tex->tw,obj_tex->data);
  325.   }
  326.  
  327.   sceGuDrawArray(prim,v_type,v_nbr,NULL,v);
  328.  
  329.   obj_begin = G_FALSE;
  330.   if (obj_use_z) zclear = G_TRUE;
  331. }
  332.  
  333.  
  334. void gReset()
  335. {
  336.   gResetCoord();
  337.   gResetScale();
  338.   gResetColor();
  339.   gResetAlpha();
  340.   gResetRotation();
  341. }
  342.  
  343.  
  344. void gFlip(bool vsync)
  345. {
  346.   sceGuFinish();
  347.   sceGuSync(0,0);
  348.   if (vsync) sceDisplayWaitVblankStart();
  349.   sceGuSwapBuffers();
  350.   start = G_FALSE;
  351. }
  352.  
  353.  
  354. void gAdd()
  355. {
  356.   if (!obj_begin) return;
  357.  
  358.   if (obj_list_size >= obj_list_size_malloc)
  359.   {
  360.     obj_list_size_malloc += MALLOC_STEP;
  361.     obj_list = realloc(obj_list,obj_list_size_malloc * sizeof(Obj_Properties));
  362.   }
  363.  
  364.   CURRENT_OBJ.x = obj_x;
  365.   CURRENT_OBJ.y = obj_y;
  366.   CURRENT_OBJ.z = obj_z;
  367.   CURRENT_OBJ.crop_x = obj_crop_x;
  368.   CURRENT_OBJ.crop_y = obj_crop_y;
  369.   CURRENT_OBJ.crop_w = obj_crop_w;
  370.   CURRENT_OBJ.crop_h = obj_crop_h;
  371.   CURRENT_OBJ.scale_w = obj_scale_w;
  372.   CURRENT_OBJ.scale_h = obj_scale_h;
  373.   CURRENT_OBJ.color = obj_color;
  374.   CURRENT_OBJ.rot_x = obj_x;
  375.   CURRENT_OBJ.rot_y = obj_y;
  376.   CURRENT_OBJ.rot_sin = obj_rot_sin;
  377.   CURRENT_OBJ.rot_cos = obj_rot_cos;
  378.  
  379.   // Coord mode stuff
  380.   CURRENT_OBJ.x -= (obj_coord_mode == G_UP_RIGHT ||
  381.                     obj_coord_mode == G_DOWN_RIGHT) ?
  382.                     CURRENT_OBJ.scale_w :
  383.                    (obj_coord_mode == G_CENTER) ?
  384.                     CURRENT_OBJ.scale_w/2 : 0;
  385.   CURRENT_OBJ.y -= (obj_coord_mode == G_DOWN_LEFT ||
  386.                     obj_coord_mode == G_DOWN_RIGHT) ?
  387.                     CURRENT_OBJ.scale_h :
  388.                    (obj_coord_mode == G_CENTER) ?
  389.                     CURRENT_OBJ.scale_h/2 : 0;                  
  390.   // Alpha stuff
  391.   CURRENT_OBJ.color = G_MODULATE(CURRENT_OBJ.color,255,obj_alpha);
  392.  
  393.   obj_list_size++;
  394. }
  395.  
  396.  
  397. void gPush()
  398. {
  399.   if (transform_stack_size >= TRANSFORM_STACK_MAX) return;
  400.   CURRENT_TRANSFORM.x = obj_x;
  401.   CURRENT_TRANSFORM.y = obj_y;
  402.   CURRENT_TRANSFORM.z = obj_z;
  403.   CURRENT_TRANSFORM.rot = obj_rot;
  404.   CURRENT_TRANSFORM.rot_sin = obj_rot_sin;
  405.   CURRENT_TRANSFORM.rot_cos = obj_rot_cos;
  406.   transform_stack_size++;
  407. }
  408.  
  409.  
  410. void gPop()
  411. {
  412.   if (transform_stack_size <= 0) return;
  413.   transform_stack_size--;
  414.   obj_x = CURRENT_TRANSFORM.x;
  415.   obj_y = CURRENT_TRANSFORM.y;
  416.   obj_z = CURRENT_TRANSFORM.z;
  417.   obj_rot = CURRENT_TRANSFORM.rot;
  418.   obj_rot_sin = CURRENT_TRANSFORM.rot_sin;
  419.   obj_rot_cos = CURRENT_TRANSFORM.rot_cos;
  420. }
  421.  
  422. // * Coord functions *
  423.  
  424. void gResetCoord()
  425. {
  426.   obj_coord_mode = DEFAULT_COORD_MODE;
  427.   obj_x = DEFAULT_X;
  428.   obj_y = DEFAULT_Y;
  429.   obj_z = DEFAULT_Z;
  430. }
  431.  
  432.  
  433. void gSetCoordMode(gEnum mode)
  434. {
  435.   if (mode < G_UP_LEFT || mode > G_CENTER) return;
  436.   obj_coord_mode = mode;
  437. }
  438.  
  439.  
  440. void gSetCoordXY(float x, float y)
  441. {
  442.   obj_x = x;
  443.   obj_y = y;
  444.   obj_z = 0;
  445. }
  446.  
  447.  
  448. void gSetCoordXYZ(float x, float y, float z)
  449. {
  450.   obj_x = x;
  451.   obj_y = y;
  452.   obj_z = z;
  453.   obj_use_z = G_TRUE;
  454. }
  455.  
  456.  
  457. void gSetCoordXYRelative(float x, float y, bool use_rot)
  458. {
  459.   if (!use_rot) gSetCoordXY(obj_x + x, obj_y + y);
  460.   else          gSetCoordXY(obj_x - obj_rot_sin*y + obj_rot_cos*x,
  461.                             obj_y + obj_rot_cos*y + obj_rot_sin*x);
  462. }
  463.  
  464.  
  465. void gSetCoordXYZRelative(float x, float y, float z, bool use_rot)
  466. {
  467.   if (!use_rot) gSetCoordXYZ(obj_x + x, obj_y + y,obj_z + z);
  468.   else          gSetCoordXYZ(obj_x - obj_rot_sin*y + obj_rot_cos*x,
  469.                              obj_y + obj_rot_cos*y + obj_rot_sin*x,
  470.                              obj_z + z);
  471. }
  472.  
  473. // * Scale functions *
  474.  
  475. void gResetScale()
  476. {
  477.   if (!obj_use_tex)
  478.   {
  479.     obj_scale_w = DEFAULT_SIDE;
  480.     obj_scale_h = DEFAULT_SIDE;
  481.   }
  482.   else
  483.   {
  484.     obj_scale_w = obj_tex->w;
  485.     obj_scale_h = obj_tex->h;
  486.   }
  487. }
  488.  
  489.  
  490. void gSetScale(float w, float h)
  491. {
  492.   gSetScaleRelative(w,h);
  493. }
  494.  
  495.  
  496. void gSetScaleWH(int w, int h)
  497. {
  498.   obj_scale_w = w;
  499.   obj_scale_h = h;
  500. }
  501.  
  502.  
  503. void gSetScaleRelative(float w, float h)
  504. {
  505.   obj_scale_w *= w;
  506.   obj_scale_h *= h;
  507. }
  508.  
  509.  
  510. void gSetScaleWHRelative(int w, int h)
  511. {
  512.   obj_scale_w += w;
  513.   obj_scale_h += h;
  514. }
  515.  
  516. // * Color functions *
  517.  
  518. void gResetColor()
  519. {
  520.   obj_color = DEFAULT_COLOR;
  521. }
  522.  
  523.  
  524. void gResetAlpha()
  525. {
  526.   obj_alpha = DEFAULT_ALPHA;
  527. }
  528.  
  529.  
  530. void gSetColor(gColor color)
  531. {
  532.   obj_color = color;
  533.   if (++obj_colors_count > 1) obj_use_vert_color = G_TRUE;
  534.   if (G_GET_A(obj_color) < 255) obj_use_blend = G_TRUE;
  535. }
  536.  
  537.  
  538. void gSetAlpha(gAlpha alpha)
  539. {
  540.   obj_alpha = alpha;
  541.   if (obj_alpha > 255) obj_alpha = 255;
  542.   else if (obj_alpha < 0) obj_alpha = 0;
  543.   if (++obj_alpha_count > 1) obj_use_vert_color = G_TRUE;
  544.   if (obj_alpha < 255) obj_use_blend = G_TRUE;
  545. }
  546.  
  547.  
  548. void gSetAlphaRelative(gAlpha alpha)
  549. {
  550.   gSetAlpha(obj_alpha + alpha);
  551. }
  552.  
  553. // * Rotations functions *
  554.  
  555. void gResetRotation()
  556. {
  557.   obj_rot = 0.f;
  558.   obj_rot_sin = 0.f;
  559.   obj_rot_cos = 1.f;
  560. }
  561.  
  562.  
  563. void gSetRotationRad(float radians)
  564. {
  565.   if (radians == obj_rot) return;
  566.   obj_rot = radians;
  567.   obj_rot_sin = sinf(radians);
  568.   obj_rot_cos = cosf(radians);
  569.   obj_use_rot = G_TRUE;
  570. }
  571.  
  572.  
  573. void gSetRotation(float degrees)
  574. {
  575.   gSetRotationRad(degrees * GU_PI / 180.f);
  576. }
  577.  
  578.  
  579. void gSetRotationRadRelative(float radians)
  580. {
  581.   gSetRotationRad(obj_rot + radians);
  582. }
  583.  
  584.  
  585. void gSetRotationRelative(float degrees)
  586. {
  587.   gSetRotationRadRelative(degrees * GU_PI / 180.f);
  588. }
  589.  
  590. // * Crop functions *
  591.  
  592. void gResetCrop()
  593. {
  594.   if (!obj_use_tex) return;
  595.   obj_crop_x = 0;
  596.   obj_crop_y = 0;
  597.   obj_crop_w = obj_tex->w;
  598.   obj_crop_h = obj_tex->h;
  599. }
  600.  
  601. // TODO limits
  602.  
  603. void gSetCropXY(int x, int y)
  604. {
  605.   obj_crop_x = x;
  606.   obj_crop_y = y;
  607. }
  608.  
  609.  
  610. void gSetCropWH(int w, int h)
  611. {
  612.   obj_crop_w = w;
  613.   obj_crop_h = h;
  614. }
  615.  
  616.  
  617. void gSetCropXYRelative(int x, int y)
  618. {
  619.   gSetCropXY(obj_crop_x + x, obj_crop_y + y);
  620. }
  621.  
  622.  
  623. void gSetCropWHRelative(int w, int h)
  624. {
  625.   gSetCropWH(obj_crop_w + w, obj_crop_h + h);
  626. }
  627.  
  628. // * Texture functions *
  629.  
  630. int _getNextPower2(int n)
  631. {
  632.   int p=1;
  633.   while ((p <<= 1) < n);
  634.   return 128;
  635. }
  636.  
  637.  
  638. gImage* gTexLoad(char path[], bool swizzle)
  639. {
  640.   png_structp png_ptr;
  641.   png_infop info_ptr;
  642.   unsigned int sig_read = 0;
  643.   png_uint_32 width, height;
  644.   int bit_depth, color_type, interlace_type, x, y;
  645.   u32* line;
  646.   FILE *fp;
  647.  
  648.   // Open & allocate memory
  649.   if ((fp = fopen(path,"rb")) == NULL) return NULL;
  650.   gImage* image = malloc(sizeof(gImage));
  651.   if (!image) return NULL;
  652.   // Init & read image infos
  653.   png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
  654.   png_set_error_fn(png_ptr,NULL,NULL,NULL);
  655.   info_ptr = png_create_info_struct(png_ptr);
  656.   png_init_io(png_ptr,fp);
  657.   png_set_sig_bytes(png_ptr,sig_read);
  658.   png_read_info(png_ptr,info_ptr);
  659.   png_get_IHDR(png_ptr,info_ptr,&width,&height,&bit_depth,&color_type,
  660.                                 &interlace_type,NULL,NULL);
  661.   png_set_strip_16(png_ptr);
  662.   png_set_packing(png_ptr);
  663.   if (color_type == PNG_COLOR_TYPE_PALETTE)
  664.     png_set_palette_to_rgb(png_ptr);
  665.   if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
  666.     png_set_gray_1_2_4_to_8(png_ptr);
  667.   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
  668.     png_set_tRNS_to_alpha(png_ptr);
  669.   png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
  670.   // Image is too big for the PSP, abort
  671.   if (width > 512 || height > 512)
  672.   {
  673.     free(image);
  674.     fclose(fp);
  675.     png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
  676.     return NULL;
  677.   }
  678.   image->w = width;
  679.   image->h = height;
  680.   image->tw = _getNextPower2(width);
  681.   image->th = _getNextPower2(height);
  682.   image->ratio = (float)width / height;
  683.   // Get image data
  684.   image->data = memalign(16, image->tw * image->th * sizeof(gColor));
  685.   line = malloc(width * 4);
  686.   for (y = 0; y < height; y++) {
  687.     png_read_row(png_ptr, (u8*) line, png_bytep_NULL);
  688.     for (x = 0; x < width; x++) {
  689.       u32 color = line[x];
  690.       image->data[x + y * image->tw] =  color;
  691.     }
  692.   }
  693.   // Free
  694.   free(line);
  695.   png_read_end(png_ptr, info_ptr);
  696.   png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
  697.   fclose(fp);
  698.   // Writeback cache to ram
  699.   sceKernelDcacheWritebackAll();
  700.  
  701.   return image;
  702. }
  703.  
  704. // EOF
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement