diff --git a/PS1BSP.vcxproj b/PS1BSP.vcxproj index b0f337a..63d6887 100644 --- a/PS1BSP.vcxproj +++ b/PS1BSP.vcxproj @@ -144,6 +144,7 @@ + @@ -158,6 +159,12 @@ + + + + + Document + diff --git a/PS1BSP.vcxproj.filters b/PS1BSP.vcxproj.filters index 18876d9..01b64a5 100644 --- a/PS1BSP.vcxproj.filters +++ b/PS1BSP.vcxproj.filters @@ -21,11 +21,14 @@ Source Files - - Header Files + + Source Files - Header Files + Source Files + + + Source Files @@ -65,5 +68,13 @@ Header Files + + Header Files + + + + + Resource Files + \ No newline at end of file diff --git a/palette.lmp b/palette.lmp new file mode 100644 index 0000000..7eefda1 Binary files /dev/null and b/palette.lmp differ diff --git a/tim.cpp b/tim.cpp new file mode 100644 index 0000000..e1edea2 --- /dev/null +++ b/tim.cpp @@ -0,0 +1,99 @@ +#include "tim.h" + + +int tim::ExportFile(const char* fileName, tim::PARAM *param) { + + FILE *fp; + + fopen_s(&fp, fileName, "wb"); + if (!fp) { + return(-1); + } + + + tim::HEADER fileHead={{0}}; + tim::CLUT_HEAD clutHead={0}; + tim::IMG_HEAD imgHead={0}; + + + // Prepare header + fileHead.id.id = 0x10; + fileHead.id.ver = 0; + fileHead.flags.pmode = param->format; + + + // Prepare CLUT data block if image is 8-bit or less and that the pointer to the CLUT data is not NULL + if ((param->format <= 1) && (param->clutData != NULL)) { + fileHead.flags.clut = 1; + clutHead.cw = param->clutWidth; + clutHead.ch = param->clutHeight; + clutHead.cx = param->clutXoffs; + clutHead.cy = param->clutYoffs; + clutHead.len = ((2*param->clutWidth)*param->clutHeight); + clutHead.len += sizeof(clutHead); + } + + + // Prepare image data block + imgHead.w = param->imgWidth; + imgHead.h = param->imgHeight; + imgHead.x = param->imgXoffs; + imgHead.y = param->imgYoffs; + + // Calculate final size of image based on its color depth + switch(param->format) { + case 0: // 4-bit with 16-color CLUT + imgHead.len = param->imgWidth/2; + imgHead.w /= 4; + break; + case 1: // 8-bit with 256-color CLUT + imgHead.len = param->imgWidth; + imgHead.w /= 2; + break; + case 2: // 16-bit RGB5I1 + imgHead.len = param->imgWidth*2; + break; + case 3: // 24-bit RGB8 + imgHead.len = (param->imgWidth*3); + imgHead.w = (u_short)ceil((double)imgHead.w*1.5f); + break; + } + + // Calculate size of image data block + imgHead.len *= param->imgHeight; + imgHead.len += sizeof(imgHead); + + + // Write the header + fwrite(&fileHead, 1, sizeof(fileHead), fp); + + // Write the CLUT data block + if ((param->format <= 1) && (param->clutData != NULL)) { + fwrite(&clutHead, 1, sizeof(clutHead), fp); + fwrite(param->clutData, 1, clutHead.len-sizeof(clutHead), fp); + } + + // Write the image data block + fwrite(&imgHead, 1, sizeof(imgHead), fp); + fwrite(param->imgData, 1, imgHead.len-sizeof(imgHead), fp); + + // Close and return + fclose(fp); + return(0); + +} + + +void tim::FreeParam(tim::PARAM *param) { + + if (param->imgData != NULL) { + free(param->imgData); + param->imgData = NULL; + } + + if (param->clutData != NULL) { + free(param->clutData); + param->clutData = NULL; + } + +} diff --git a/tim.h b/tim.h new file mode 100644 index 0000000..9f9b8f4 --- /dev/null +++ b/tim.h @@ -0,0 +1,98 @@ +#ifndef _TIM_H +#define _TIM_H + +#include +#ifdef _WIN32 +#include +#endif +#include + +#define TIM_OUTPUT_CLUT4 0 +#define TIM_OUTPUT_CLUT8 1 +#define TIM_OUTPUT_RGB5 2 +#define TIM_OUTPUT_RGB24 3 + +namespace tim { + + + // TIM header struct + typedef struct { + + // ID sub-struct + struct HEADER_ID { + u_int id:8; // Always 0x10 + u_int ver:8; // Always 0 + u_int pad:16; // Useless padding + } id; + + // Flags sub-struct + struct HEADER_FLAGS { + u_int pmode:3; // Pixel mode (0: 4-bit, 1: 8-bit, 2:16-bit, 3:24-bit) + u_int clut:1; + u_int pad:24; + } flags; + + } HEADER; + + + // CLUT header struct + typedef struct { + u_int len; + u_short cx,cy; + u_short cw,ch; + } CLUT_HEAD; + + + // Image data block header + typedef struct { + u_int len; + u_short x,y; + u_short w,h; + } IMG_HEAD; + + + typedef struct { + // 0: 4-bit CLUT, 1: 8-bit CLUT, 2:16-bit, 3:24-bit + int format; + // Image data params + void *imgData; + u_short imgWidth,imgHeight; + u_short imgXoffs,imgYoffs; + // CLUT data params + void *clutData; + u_short clutWidth,clutHeight; + u_short clutXoffs,clutYoffs; + } PARAM; + + + // RGB5A1 pixel format struct + typedef struct { + u_short r:5; + u_short g:5; + u_short b:5; + u_short i:1; + } PIX_RGB5; + + typedef struct { + u_char r; + u_char g; + u_char b; + } PIX_RGB24; + + + /*! tim::ExportFile() + * + * /param[in] fileName - Name of TIM file. + * /param[in] *param - tim::PARAM object of TIM export parameters. + * + * /returns Zero if the TIM file was written successfully, otherwise an error occured. + * + */ + int ExportFile(const char* fileName, tim::PARAM *param); + + void FreeParam(tim::PARAM *param); + +}; + + +#endif // _TIM_H