1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 
5 #include "System.h"
6 #include "NLS.h"
7 #include "Util.h"
8 #include "gba/Flash.h"
9 #include "gba/GBA.h"
10 #include "gba/Globals.h"
11 #include "gba/RTC.h"
12 #include "common/Port.h"
13 
14 #include "gba/gbafilter.h"
15 #include "gb/gbGlobals.h"
16 
17 #ifndef _MSC_VER
18 #include <strings.h>
19 #define _stricmp strcasecmp
20 #endif // ! _MSC_VER
21 
22 extern int systemColorDepth;
23 extern int systemRedShift;
24 extern int systemGreenShift;
25 extern int systemBlueShift;
26 
27 extern uint16_t systemColorMap16[0x10000];
28 extern uint32_t systemColorMap32[0x10000];
29 
utilWritePNGFile(const char * fileName,int w,int h,uint8_t * pix)30 bool utilWritePNGFile(const char *fileName, int w, int h, uint8_t *pix)
31 {
32    return false;
33 }
34 
utilPutDword(u8 * p,u32 value)35 void utilPutDword(u8 *p, u32 value)
36 {
37   *p++ = value & 255;
38   *p++ = (value >> 8) & 255;
39   *p++ = (value >> 16) & 255;
40   *p = (value >> 24) & 255;
41 }
42 
utilPutWord(uint8_t * p,uint16_t value)43 void utilPutWord(uint8_t *p, uint16_t value)
44 {
45   *p++ = value & 255;
46   *p = (value >> 8) & 255;
47 }
48 
utilWriteBMPFile(const char * fileName,int w,int h,uint8_t * pix)49 bool utilWriteBMPFile(const char *fileName, int w, int h, uint8_t *pix)
50 {
51    return false;
52 }
53 
54 extern bool cpuIsMultiBoot;
55 
utilIsGBAImage(const char * file)56 bool utilIsGBAImage(const char * file)
57 {
58   cpuIsMultiBoot = false;
59   if(strlen(file) > 4) {
60     const char * p = strrchr(file,'.');
61 
62     if(p != NULL) {
63       if((_stricmp(p, ".agb") == 0) ||
64          (_stricmp(p, ".gba") == 0) ||
65          (_stricmp(p, ".bin") == 0) ||
66          (_stricmp(p, ".elf") == 0))
67         return true;
68       if(_stricmp(p, ".mb") == 0) {
69         cpuIsMultiBoot = true;
70         return true;
71       }
72     }
73   }
74 
75   return false;
76 }
77 
utilIsGBImage(const char * file)78 bool utilIsGBImage(const char * file)
79 {
80   if(strlen(file) > 4) {
81     const char * p = strrchr(file,'.');
82 
83     if(p != NULL) {
84       if((_stricmp(p, ".dmg") == 0) ||
85          (_stricmp(p, ".gb") == 0) ||
86          (_stricmp(p, ".gbc") == 0) ||
87          (_stricmp(p, ".cgb") == 0) ||
88          (_stricmp(p, ".sgb") == 0))
89         return true;
90     }
91   }
92 
93   return false;
94 }
95 
96 // strip .gz or .z off end
utilStripDoubleExtension(const char * file,char * buffer)97 void utilStripDoubleExtension(const char *file, char *buffer)
98 {
99   if(buffer != file) // allows conversion in place
100     strcpy(buffer, file);
101 }
102 
utilIsImage(const char * file)103 static bool utilIsImage(const char *file)
104 {
105 	return utilIsGBAImage(file) || utilIsGBImage(file);
106 }
107 
utilFindType(const char * file)108 IMAGE_TYPE utilFindType(const char *file)
109 {
110 	char buffer [2048];
111 	if ( !utilIsImage( file ) ) // TODO: utilIsArchive() instead?
112 	{
113       return IMAGE_UNKNOWN;
114 	}
115 	return utilIsGBAImage(file) ? IMAGE_GBA : IMAGE_GB;
116 }
117 
utilGetSize(int size)118 static int utilGetSize(int size)
119 {
120   int res = 1;
121   while(res < size)
122     res <<= 1;
123   return res;
124 }
125 
utilLoad(const char * file,bool (* accept)(const char *),uint8_t * data,int & size)126 uint8_t *utilLoad(const char *file, bool (*accept)(const char *), uint8_t *data, int &size)
127 {
128 	FILE *fp = NULL;
129 	char *buf = NULL;
130 
131 	fp = fopen(file,"rb");
132 	fseek(fp, 0, SEEK_END); //go to end
133 	size = ftell(fp); // get position at end (length)
134 	rewind(fp);
135 
136 	uint8_t *image = data;
137 	if(image == NULL)
138 	{
139 		//allocate buffer memory if none was passed to the function
140 		image = (uint8_t *)malloc(utilGetSize(size));
141 		if(image == NULL)
142 		{
143 			systemMessage(MSG_OUT_OF_MEMORY, N_("Failed to allocate memory for %s"),
144 					"data");
145 			return NULL;
146 		}
147 	}
148 
149    fread(image, 1, size, fp); // read into buffer
150 	fclose(fp);
151 	return image;
152 }
153 
utilGBAFindSave(const uint8_t * data,const int size)154 void utilGBAFindSave(const uint8_t *data, const int size)
155 {
156   uint32_t *p = (uint32_t *)data;
157   uint32_t *end = (uint32_t *)(data + size);
158   int saveType = 0;
159   int flashSize = 0x10000;
160   bool rtcFound = false;
161 
162   while(p  < end) {
163     uint32_t d = READ32LE(p);
164 
165     if(d == 0x52504545) {
166       if(memcmp(p, "EEPROM_", 7) == 0) {
167         if(saveType == 0)
168           saveType = 3;
169       }
170     } else if (d == 0x4D415253) {
171       if(memcmp(p, "SRAM_", 5) == 0) {
172         if(saveType == 0)
173           saveType = 1;
174       }
175     } else if (d == 0x53414C46) {
176       if(memcmp(p, "FLASH1M_", 8) == 0) {
177         if(saveType == 0) {
178           saveType = 2;
179           flashSize = 0x20000;
180         }
181       } else if(memcmp(p, "FLASH", 5) == 0) {
182         if(saveType == 0) {
183           saveType = 2;
184           flashSize = 0x10000;
185         }
186       }
187     } else if (d == 0x52494953) {
188       if(memcmp(p, "SIIRTC_V", 8) == 0)
189         rtcFound = true;
190     }
191     p++;
192   }
193   // if no matches found, then set it to NONE
194   if(saveType == 0) {
195     saveType = 5;
196   }
197 
198   rtcEnable(rtcFound);
199   cpuSaveType = saveType;
200   flashSetSize(flashSize);
201 }
202 
utilUpdateSystemColorMaps(bool lcd)203 void utilUpdateSystemColorMaps(bool lcd)
204 {
205   switch(systemColorDepth) {
206   case 16:
207     {
208       for(int i = 0; i < 0x10000; i++) {
209         systemColorMap16[i] = ((i & 0x1f) << systemRedShift) |
210           (((i & 0x3e0) >> 5) << systemGreenShift) |
211           (((i & 0x7c00) >> 10) << systemBlueShift);
212       }
213       if (lcd) gbafilter_pal(systemColorMap16, 0x10000);
214     }
215     break;
216   case 24:
217   case 32:
218     {
219       for(int i = 0; i < 0x10000; i++) {
220         systemColorMap32[i] = ((i & 0x1f) << systemRedShift) |
221           (((i & 0x3e0) >> 5) << systemGreenShift) |
222           (((i & 0x7c00) >> 10) << systemBlueShift);
223       }
224       if (lcd) gbafilter_pal32(systemColorMap32, 0x10000);
225     }
226     break;
227   }
228 }
229 
230 // Check for existence of file.
utilFileExists(const char * filename)231 bool utilFileExists( const char *filename )
232 {
233 	FILE *f = fopen( filename, "r" );
234 	if( f == NULL ) {
235 		return false;
236 	} else {
237 		fclose( f );
238 		return true;
239 	}
240 }
241 
242 // Not endian safe, but VBA itself doesn't seem to care, so hey <_<
utilWriteIntMem(uint8_t * & data,int val)243 void utilWriteIntMem(uint8_t *& data, int val)
244 {
245    memcpy(data, &val, sizeof(int));
246    data += sizeof(int);
247 }
248 
utilWriteMem(uint8_t * & data,const void * in_data,unsigned size)249 void utilWriteMem(uint8_t *& data, const void *in_data, unsigned size)
250 {
251    memcpy(data, in_data, size);
252    data += size;
253 }
254 
utilWriteDataMem(uint8_t * & data,variable_desc * desc)255 void utilWriteDataMem(uint8_t *& data, variable_desc *desc)
256 {
257    while (desc->address)
258    {
259       utilWriteMem(data, desc->address, desc->size);
260       desc++;
261    }
262 }
263 
utilReadIntMem(const uint8_t * & data)264 int utilReadIntMem(const uint8_t *& data)
265 {
266    int res;
267    memcpy(&res, data, sizeof(int));
268    data += sizeof(int);
269    return res;
270 }
271 
utilReadMem(void * buf,const uint8_t * & data,unsigned size)272 void utilReadMem(void *buf, const uint8_t *& data, unsigned size)
273 {
274    memcpy(buf, data, size);
275    data += size;
276 }
277 
utilReadDataMem(const uint8_t * & data,variable_desc * desc)278 void utilReadDataMem(const uint8_t *& data, variable_desc *desc)
279 {
280    while (desc->address)
281    {
282       utilReadMem(desc->address, data, desc->size);
283       desc++;
284    }
285 }
286