c62d2810 |
1 | /* FCE Ultra - NES/Famicom Emulator |
2 | * |
3 | * Copyright notice for this file: |
92764e62 |
4 | * Copyright (C) 2002 Xodnizel |
c62d2810 |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; either version 2 of the License, or |
9 | * (at your option) any later version. |
10 | * |
11 | * This program is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU General Public License |
17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ |
20 | |
13624c8f |
21 | #define _GNU_SOURCE // for asprintf |
92764e62 |
22 | #include <stdio.h> |
c62d2810 |
23 | #include <stdlib.h> |
24 | #include <string.h> |
92764e62 |
25 | #include <stdarg.h> |
26 | |
27 | #include <sys/types.h> |
28 | #include <sys/stat.h> |
29 | #include <unistd.h> |
c62d2810 |
30 | |
31 | #include "types.h" |
92764e62 |
32 | #include "fce.h" |
c62d2810 |
33 | |
34 | #include "general.h" |
35 | #include "state.h" |
92764e62 |
36 | #include "movie.h" |
37 | |
c62d2810 |
38 | #include "driver.h" |
39 | |
92764e62 |
40 | #include "md5.h" |
41 | #include "svga.h" |
c62d2810 |
42 | |
43 | static char BaseDirectory[2048]; |
92764e62 |
44 | char FileBase[2048]; |
45 | static char FileExt[2048]; /* Includes the . character, as in ".nes" */ |
46 | |
c62d2810 |
47 | static char FileBaseDirectory[2048]; |
48 | |
49 | void FCEUI_SetBaseDirectory(char *dir) |
50 | { |
51 | strncpy(BaseDirectory,dir,2047); |
52 | BaseDirectory[2047]=0; |
53 | } |
54 | |
55 | static char *odirs[FCEUIOD__COUNT]={0,0,0,0,0}; // odirs, odors. ^_^ |
56 | |
57 | void FCEUI_SetDirOverride(int which, char *n) |
58 | { |
92764e62 |
59 | // FCEU_PrintError("odirs[%d]=%s->%s", which, odirs[which], n); |
60 | if(which < FCEUIOD__COUNT) |
c62d2810 |
61 | odirs[which]=n; |
92764e62 |
62 | |
63 | #if 0 |
64 | if(FCEUGameInfo) /* Rebuild cache of present states/movies. */ |
65 | { |
66 | if(which==FCEUIOD_STATE) |
67 | FCEUSS_CheckStates(); |
68 | else if(which == FCEUIOD_MISC) |
69 | FCEUMOV_CheckMovies(); |
70 | } |
71 | #endif |
72 | } |
73 | |
74 | #ifndef HAVE_ASPRINTF |
75 | static int asprintf(char **strp, const char *fmt, ...) |
76 | { |
77 | va_list ap; |
78 | int ret; |
79 | |
80 | va_start(ap,fmt); |
81 | if(!(*strp=malloc(2048))) |
82 | return(0); |
83 | ret=vsnprintf(*strp,2048,fmt,ap); |
84 | va_end(ap); |
85 | return(ret); |
86 | } |
87 | #endif |
88 | |
89 | char* FCEU_GetPath(int type) |
90 | { |
91 | char *ret=0; |
92 | switch(type) |
93 | { |
94 | case FCEUMKF_STATE:if(odirs[FCEUIOD_STATE]) |
95 | ret=strdup(odirs[FCEUIOD_STATE]); |
96 | else |
97 | asprintf(&ret,"%s"PSS"movie",BaseDirectory); |
98 | break; |
99 | case FCEUMKF_MOVIE:if(odirs[FCEUIOD_MISC]) |
100 | ret=strdup(odirs[FCEUIOD_MISC]); |
101 | else |
102 | asprintf(&ret,"%s"PSS"movie",BaseDirectory); |
103 | break; |
104 | } |
105 | return(ret); |
106 | } |
107 | |
108 | char *FCEU_MakePath(int type, const char* filebase) |
109 | { |
110 | char *ret=0; |
111 | |
112 | switch(type) |
113 | { |
114 | case FCEUMKF_MOVIE:if(odirs[FCEUIOD_MISC]) |
115 | asprintf(&ret,"%s"PSS"%s",odirs[FCEUIOD_MISC],filebase); |
116 | else |
117 | asprintf(&ret,"%s"PSS"movie"PSS"%s",BaseDirectory,filebase); |
118 | break; |
119 | } |
120 | return(ret); |
c62d2810 |
121 | } |
122 | |
c62d2810 |
123 | char *FCEU_MakeFName(int type, int id1, char *cd1) |
124 | { |
92764e62 |
125 | char *ret=0; |
126 | struct stat tmpstat; |
c62d2810 |
127 | |
c62d2810 |
128 | switch(type) |
129 | { |
92764e62 |
130 | case FCEUMKF_NPTEMP: asprintf(&ret,"%s"PSS"m590plqd94fo.tmp",BaseDirectory);break; |
131 | case FCEUMKF_MOVIE:if(id1>=0) |
132 | { |
133 | if(odirs[FCEUIOD_MISC]) |
134 | asprintf(&ret,"%s"PSS"%s.%d.fcm",odirs[FCEUIOD_MISC],FileBase,id1); |
135 | else |
136 | asprintf(&ret,"%s"PSS"movie"PSS"%s.%d.fcm",BaseDirectory,FileBase,id1); |
137 | if(stat(ret,&tmpstat)==-1) |
138 | { |
139 | if(odirs[FCEUIOD_MISC]) |
140 | asprintf(&ret,"%s"PSS"%s.%d.fcm",odirs[FCEUIOD_MISC],FileBase,id1); |
141 | else |
142 | asprintf(&ret,"%s"PSS"movie"PSS"%s.%d.fcm",BaseDirectory,FileBase,id1); |
143 | } |
144 | } |
145 | else |
146 | { |
147 | if(odirs[FCEUIOD_MISC]) |
148 | asprintf(&ret,"%s"PSS"%s.fcm",odirs[FCEUIOD_MISC],FileBase); |
149 | else |
150 | asprintf(&ret,"%s"PSS"movie"PSS"%s.fcm",BaseDirectory,FileBase); |
151 | } |
152 | break; |
c62d2810 |
153 | case FCEUMKF_STATE:if(odirs[FCEUIOD_STATE]) |
92764e62 |
154 | { |
155 | asprintf(&ret,"%s"PSS"%s.fc%d",odirs[FCEUIOD_STATE],FileBase,id1); |
156 | // FCEU_PrintError("A"); |
157 | } |
c62d2810 |
158 | else |
92764e62 |
159 | { |
160 | asprintf(&ret,"%s"PSS"fcs"PSS"%s.fc%d",BaseDirectory,FileBase,id1); |
161 | // FCEU_PrintError("B"); |
162 | } |
163 | if(stat(ret,&tmpstat)==-1) |
164 | { |
165 | if(odirs[FCEUIOD_STATE]) |
166 | { |
167 | asprintf(&ret,"%s"PSS"%s.fc%d",odirs[FCEUIOD_STATE],FileBase,id1); |
168 | // FCEU_PrintError("C"); |
169 | } |
170 | else |
171 | { |
172 | asprintf(&ret,"%s"PSS"fcs"PSS"%s.fc%d",BaseDirectory,FileBase,id1); |
173 | // FCEU_PrintError("D"); |
174 | } |
175 | } |
c62d2810 |
176 | break; |
177 | case FCEUMKF_SNAP: |
178 | if(FSettings.SnapName) |
179 | { |
180 | if(odirs[FCEUIOD_SNAPS]) |
92764e62 |
181 | asprintf(&ret,"%s"PSS"%s-%d.%s",odirs[FCEUIOD_SNAPS],FileBase,id1,cd1); |
c62d2810 |
182 | else |
92764e62 |
183 | asprintf(&ret,"%s"PSS"snaps"PSS"%s-%d.%s",BaseDirectory,FileBase,id1,cd1); |
c62d2810 |
184 | } |
185 | else |
186 | { |
187 | if(odirs[FCEUIOD_SNAPS]) |
92764e62 |
188 | asprintf(&ret,"%s"PSS"%d.%s",odirs[FCEUIOD_SNAPS],id1,cd1); |
c62d2810 |
189 | else |
92764e62 |
190 | asprintf(&ret,"%s"PSS"snaps"PSS"%d.%s",BaseDirectory,id1,cd1); |
c62d2810 |
191 | } |
192 | break; |
d97315ac |
193 | case FCEUMKF_FDS:if(odirs[FCEUIOD_NV]) |
92764e62 |
194 | asprintf(&ret,"%s"PSS"%s.fds",odirs[FCEUIOD_NV],FileBase); |
d97315ac |
195 | else |
92764e62 |
196 | asprintf(&ret,"%s"PSS"sav"PSS"%s.fds",BaseDirectory,FileBase); |
d97315ac |
197 | break; |
c62d2810 |
198 | case FCEUMKF_SAV:if(odirs[FCEUIOD_NV]) |
92764e62 |
199 | asprintf(&ret,"%s"PSS"%s.%s",odirs[FCEUIOD_NV],FileBase,cd1); |
c62d2810 |
200 | else |
92764e62 |
201 | asprintf(&ret,"%s"PSS"sav"PSS"%s.%s",BaseDirectory,FileBase,cd1); |
202 | if(stat(ret,&tmpstat)==-1) |
c62d2810 |
203 | { |
92764e62 |
204 | if(odirs[FCEUIOD_NV]) |
205 | asprintf(&ret,"%s"PSS"%s.%s",odirs[FCEUIOD_NV],FileBase,cd1); |
c62d2810 |
206 | else |
92764e62 |
207 | asprintf(&ret,"%s"PSS"sav"PSS"%s.%s",BaseDirectory,FileBase,cd1); |
c62d2810 |
208 | } |
209 | break; |
210 | case FCEUMKF_CHEAT: |
211 | if(odirs[FCEUIOD_CHEATS]) |
92764e62 |
212 | asprintf(&ret,"%s"PSS"%s.cht",odirs[FCEUIOD_CHEATS],FileBase); |
c62d2810 |
213 | else |
92764e62 |
214 | asprintf(&ret,"%s"PSS"cheats"PSS"%s.cht",BaseDirectory,FileBase); |
215 | break; |
216 | case FCEUMKF_IPS: asprintf(&ret,"%s"PSS"%s%s.ips",FileBaseDirectory,FileBase,FileExt); |
c62d2810 |
217 | break; |
92764e62 |
218 | case FCEUMKF_GGROM:asprintf(&ret,"%s"PSS"gg.rom",BaseDirectory);break; |
219 | case FCEUMKF_FDSROM:asprintf(&ret,"%s"PSS"disksys.rom",BaseDirectory);break; |
c62d2810 |
220 | case FCEUMKF_PALETTE: |
221 | if(odirs[FCEUIOD_MISC]) |
92764e62 |
222 | asprintf(&ret,"%s"PSS"%s.pal",odirs[FCEUIOD_MISC],FileBase); |
c62d2810 |
223 | else |
92764e62 |
224 | asprintf(&ret,"%s"PSS"%s.pal",BaseDirectory,FileBase); |
c62d2810 |
225 | break; |
92764e62 |
226 | case FCEUMKF_MOVIEGLOB: |
227 | if(odirs[FCEUIOD_MISC]) |
228 | // asprintf(&ret,"%s"PSS"%s*.fcm",odirs[FCEUIOD_MISC],FileBase); |
229 | asprintf(&ret,"%s"PSS"*.???",odirs[FCEUIOD_MISC]); |
230 | else |
231 | // asprintf(&ret,"%s"PSS"fcs"PSS"%s*.fcm",BaseDirectory,FileBase); |
232 | asprintf(&ret,"%s"PSS"movie"PSS"*.???",BaseDirectory); |
233 | break; |
234 | case FCEUMKF_MOVIEGLOB2: |
235 | asprintf(&ret,"%s"PSS"*.???",BaseDirectory); |
236 | break; |
237 | case FCEUMKF_STATEGLOB: |
238 | if(odirs[FCEUIOD_STATE]) |
239 | asprintf(&ret,"%s"PSS"%s*.fc?",odirs[FCEUIOD_STATE],FileBase); |
240 | else |
241 | asprintf(&ret,"%s"PSS"fcs"PSS"%s*.fc?",BaseDirectory,FileBase); |
242 | break; |
c62d2810 |
243 | } |
92764e62 |
244 | return(ret); |
c62d2810 |
245 | } |
246 | |
92764e62 |
247 | void GetFileBase(const char *f) |
c62d2810 |
248 | { |
92764e62 |
249 | const char *tp1,*tp3; |
c62d2810 |
250 | |
251 | #if PSS_STYLE==4 |
252 | tp1=((char *)strrchr(f,':')); |
253 | #elif PSS_STYLE==1 |
254 | tp1=((char *)strrchr(f,'/')); |
255 | #else |
256 | tp1=((char *)strrchr(f,'\\')); |
257 | #if PSS_STYLE!=3 |
258 | tp3=((char *)strrchr(f,'/')); |
259 | if(tp1<tp3) tp1=tp3; |
260 | #endif |
261 | #endif |
262 | if(!tp1) |
263 | { |
264 | tp1=f; |
265 | strcpy(FileBaseDirectory,"."); |
266 | } |
267 | else |
268 | { |
269 | memcpy(FileBaseDirectory,f,tp1-f); |
270 | FileBaseDirectory[tp1-f]=0; |
271 | tp1++; |
272 | } |
273 | |
92764e62 |
274 | if(((tp3=strrchr(f,'.'))!=NULL) && (tp3>tp1)) |
c62d2810 |
275 | { |
276 | memcpy(FileBase,tp1,tp3-tp1); |
277 | FileBase[tp3-tp1]=0; |
92764e62 |
278 | strcpy(FileExt,tp3); |
c62d2810 |
279 | } |
280 | else |
281 | { |
282 | strcpy(FileBase,tp1); |
283 | FileExt[0]=0; |
284 | } |
285 | } |
286 | |
287 | uint32 uppow2(uint32 n) |
288 | { |
289 | int x; |
290 | |
291 | for(x=31;x>=0;x--) |
292 | if(n&(1<<x)) |
293 | { |
294 | if((1<<x)!=n) |
295 | return(1<<(x+1)); |
296 | break; |
297 | } |
298 | return n; |
299 | } |
300 | |