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