1 /*
2 
3    Copyright 2021, dettus@dettus.net
4 
5    Redistribution and use in source and binary forms, with or without modification,
6    are permitted provided that the following conditions are met:
7 
8    1. Redistributions of source code must retain the above copyright notice, this
9    list of conditions and the following disclaimer.
10 
11    2. Redistributions in binary form must reproduce the above copyright notice,
12    this list of conditions and the following disclaimer in the documentation
13    and/or other materials provided with the distribution.
14 
15    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
26 
27  */
28 
29 // the purpose of this file is to figure out what kind of binaries the
30 // user has. is it the .mag/.gfx one? or is it the original MS-DOS version?
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include "configuration.h"
35 #include "vm68k_macros.h"
36 #include "loader_msdos.h"
37 #include "loader_mw.h"
38 #include "loader_d64.h"
39 #include "loader_dsk.h"
40 #include "loader_archimedes.h"
41 #include "loader_atarixl.h"
42 #include "loader_appleii.h"
43 
44 
45 typedef	enum _eBinType
46 {
47 	BINTYPE_NONE,
48 	BINTYPE_MAGGFX,
49 	BINTYPE_MSDOS,
50 	BINTYPE_TWORSC,
51 	BINTYPE_D64,
52 	BINTYPE_AMSTRADCPC,
53 	BINTYPE_SPECTRUM,
54 	BINTYPE_ARCHIMEDES,
55 	BINTYPE_ATARIXL,
56 	BINTYPE_APPLEII
57 } eBinType;
loader_init(int argc,char ** argv,FILE * f_inifile,char * magbuf,int * magsize,char * gfxbuf,int * gfxsize)58 int loader_init(int argc,char** argv,FILE *f_inifile,
59 		char *magbuf,int* magsize,
60 		char* gfxbuf,int* gfxsize)
61 {
62 	FILE *f;
63 	char magfilename[1024];
64 	char gfxfilename[1024];
65 	char binname[1024];
66 	eBinType binType;
67 
68 	int gamenamegiven;
69 	int n;
70 	int retval;
71 
72 	binType=BINTYPE_NONE;
73 
74 	retval=0;
75 	magfilename[0]=gfxfilename[0]=binname[0]=0;
76 	gamenamegiven=0;
77 	if ((retrievefromcommandline(argc,argv,"pawn",NULL,0))
78 			|| (retrievefromcommandline(argc,argv,"guild",NULL,0))
79 			|| (retrievefromcommandline(argc,argv,"jinxter",NULL,0))
80 			|| (retrievefromcommandline(argc,argv,"corruption",NULL,0))
81 			|| (retrievefromcommandline(argc,argv,"fish",NULL,0))
82 			|| (retrievefromcommandline(argc,argv,"myth",NULL,0))
83 			|| (retrievefromcommandline(argc,argv,"wonderland",NULL,0))
84 			|| (retrievefromcommandline(argc,argv,"wonder",NULL,0)))
85 	{
86 		gamenamegiven=1;
87 	}
88 	if (!f_inifile && gamenamegiven)
89 	{
90 		fprintf(stderr,"Game name was given, but no suitable .ini file found\n");
91 		fprintf(stderr,"please run %s -helpini for more help\n",argv[0]);
92 		return 1;
93 	}
94 	{
95 		int i;
96 		char* gameprefix[]={"pawn","guild","jinxter","corruption","fish","myth","wonderland","wonder"};
97 		char magname[32];
98 		char gfxname[32];
99 		char tworscname[32];
100 		char msdosname[32];
101 		char d64name[32];
102 		char amstradcpcname[32];
103 		char spectrumname[32];
104 		char archimedesname[32];
105 		char atarixlname[32];
106 		char appleiiname[32];
107 		for (i=0;i<8;i++)
108 		{
109 			snprintf(magname,32,"%smag",gameprefix[i]);
110 			snprintf(gfxname,32,"%sgfx",gameprefix[i]);
111 			snprintf(tworscname,32,"%stworsc",gameprefix[i]);
112 			snprintf(msdosname,32,"%smsdos",gameprefix[i]);
113 			snprintf(d64name,32,"%sd64",gameprefix[i]);
114 			snprintf(amstradcpcname,32,"%samstradcpc",gameprefix[i]);
115 			snprintf(spectrumname,32,"%sspectrum",gameprefix[i]);
116 			snprintf(archimedesname,32,"%sarchimedes",gameprefix[i]);
117 			snprintf(atarixlname,32,"%satarixl",gameprefix[i]);
118 			snprintf(appleiiname,32,"%sappleii",gameprefix[i]);
119 
120 			if (retrievefromcommandline(argc,argv,gameprefix[i],NULL,0))
121 			{
122 				magfilename[0]=gfxfilename[0]=0;
123 				if (retrievefromini(f_inifile,"[FILES]",magname,magfilename,sizeof(magfilename))&&
124 						retrievefromini(f_inifile,"[FILES]",gfxname,gfxfilename,sizeof(gfxfilename)))
125 				{
126 					binType=BINTYPE_MAGGFX;
127 				}
128 				else if (retrievefromini(f_inifile,"[FILES]",tworscname,binname,sizeof(binname)))
129 				{
130 					binType=BINTYPE_TWORSC;
131 				}
132 				else if (retrievefromini(f_inifile,"[FILES]",msdosname,binname,sizeof(binname)))
133 				{
134 					binType=BINTYPE_MSDOS;
135 				}
136 				else if (retrievefromini(f_inifile,"[FILES]",d64name,binname,sizeof(binname)))
137 				{
138 					binType=BINTYPE_D64;
139 				}
140 				else if (retrievefromini(f_inifile,"[FILES]",amstradcpcname,binname,sizeof(binname)))
141 				{
142 					binType=BINTYPE_AMSTRADCPC;
143 				}
144 				else if (retrievefromini(f_inifile,"[FILES]",spectrumname,binname,sizeof(binname)))
145 				{
146 					binType=BINTYPE_SPECTRUM;
147 				}
148 				else if (retrievefromini(f_inifile,"[FILES]",archimedesname,binname,sizeof(binname)))
149 				{
150 					binType=BINTYPE_ARCHIMEDES;
151 				}
152 				else if (retrievefromini(f_inifile,"[FILES]",atarixlname,binname,sizeof(binname)))
153 				{
154 					binType=BINTYPE_ATARIXL;
155 				}
156 				else if (retrievefromini(f_inifile,"[FILES]",appleiiname,binname,sizeof(binname)))
157 				{
158 					binType=BINTYPE_APPLEII;
159 				}
160 			}
161 		}
162 	}
163 	if (retrievefromcommandline(argc,argv,"-mag",magfilename,sizeof(magfilename)))
164 	{
165 		gfxfilename[0]=0;
166 		binname[0]=0;
167 		binType=BINTYPE_MAGGFX;
168 	}
169 	if (retrievefromcommandline(argc,argv,"-gfx",gfxfilename,sizeof(gfxfilename)))
170 	{
171 		binname[0]=0;
172 		binType=BINTYPE_MAGGFX;
173 	}
174 	if (retrievefromcommandline(argc,argv,"-msdosdir",binname,sizeof(binname)))
175 	{
176 		binType=BINTYPE_MSDOS;
177 	}
178 	if (retrievefromcommandline(argc,argv,"-tworsc",binname,sizeof(binname)))
179 	{
180 		binType=BINTYPE_TWORSC;
181 	}
182 	if (retrievefromcommandline(argc,argv,"-d64",binname,sizeof(binname)))
183 	{
184 		binType=BINTYPE_D64;
185 	}
186 	if (retrievefromcommandline(argc,argv,"-amstradcpc",binname,sizeof(binname)))
187 	{
188 		binType=BINTYPE_AMSTRADCPC;
189 	}
190 	if (retrievefromcommandline(argc,argv,"-spectrum",binname,sizeof(binname)))
191 	{
192 		binType=BINTYPE_SPECTRUM;
193 	}
194 	if (retrievefromcommandline(argc,argv,"-archimedes",binname,sizeof(binname)))
195 	{
196 		binType=BINTYPE_ARCHIMEDES;
197 	}
198 	if (retrievefromcommandline(argc,argv,"-atarixl",binname,sizeof(binname)))
199 	{
200 		binType=BINTYPE_ATARIXL;
201 	}
202 	if (retrievefromcommandline(argc,argv,"-appleii",binname,sizeof(binname)))
203 	{
204 		binType=BINTYPE_APPLEII;
205 	}
206 	switch (binType)
207 	{
208 		case BINTYPE_NONE:		fprintf(stderr,"Please provide the game binaries\n");return -1;break;
209 		case BINTYPE_TWORSC:		retval=loader_magneticwindows(binname,magbuf,magsize,gfxbuf,gfxsize);break;
210 		case BINTYPE_D64:		retval=loader_d64(binname,magbuf,magsize,gfxbuf,gfxsize);break;
211 		case BINTYPE_AMSTRADCPC:	retval=loader_dsk(binname,magbuf,magsize,gfxbuf,gfxsize,0);	break;
212 		case BINTYPE_SPECTRUM:		retval=loader_dsk(binname,magbuf,magsize,gfxbuf,gfxsize,1);break;
213 		case BINTYPE_ARCHIMEDES:	retval=loader_archimedes(binname,magbuf,magsize,gfxbuf,gfxsize); break;
214 		case BINTYPE_ATARIXL:		retval=loader_atarixl(binname,magbuf,magsize,gfxbuf,gfxsize); break;
215 		case BINTYPE_APPLEII:		retval=loader_appleii(binname,magbuf,magsize,gfxbuf,gfxsize); break;
216 		case BINTYPE_MSDOS:		retval=loader_msdos(binname,magbuf,magsize,gfxbuf,gfxsize);	break;
217 		case BINTYPE_MAGGFX:
218 			retval=0;
219 			if (magfilename[0] && !gfxfilename[0])
220 			{
221 				// deducing the name of the gfx file from the mag file
222 				int l;
223 				int found;
224 				found=0;
225 				l=strlen(magfilename);
226 				fprintf(stderr,"Warning! -mag given, but not -gfx. Deducing filename\n");
227 				if (l>=4)
228 				{
229 					if (strncmp(&magfilename[l-4],".mag",4)==0)
230 					{
231 						memcpy(gfxfilename,magfilename,l+1);
232 						found=1;
233 						gfxfilename[l-4]='.';
234 						gfxfilename[l-3]='g';
235 						gfxfilename[l-2]='f';
236 						gfxfilename[l-1]='x';
237 					}
238 				}
239 				if (!found)
240 				{
241 					fprintf(stderr,"filename did not end in .mag (lower case)\n");
242 					return 0;
243 				}
244 			}
245 			if (!magfilename[0] && gfxfilename[0])
246 			{
247 				// deducing the name of the mag from the gfx
248 				int l;
249 				int found;
250 				found=0;
251 				l=strlen(gfxfilename);
252 				fprintf(stderr,"warning! -gfx given, but not -mag. Deducing filename\n");
253 				if (l>=4)
254 				{
255 					if (strncmp(&gfxfilename[l-4],".gfx",4)==0)
256 					{
257 						memcpy(magfilename,gfxfilename,l+1);
258 						found=1;
259 						magfilename[l-4]='.';
260 						magfilename[l-3]='m';
261 						magfilename[l-2]='a';
262 						magfilename[l-1]='g';
263 					}
264 				}
265 				if (!found)
266 				{
267 					fprintf(stderr,"filename did not end in .gfx (lower case)\n");
268 					return 0;
269 				}
270 			}
271 			if ((!magfilename[0] || !gfxfilename[0]))
272 			{
273 				return 1;
274 			}
275 			f=fopen(magfilename,"rb");
276 			if (f==NULL)
277 			{
278 				fprintf(stderr,"ERROR: unable to open [%s]\n",magfilename);
279 				fprintf(stderr,"This interpreter needs a the game's binaries in the .mag and .gfx\n");
280 				fprintf(stderr,"format from the Magnetic Scrolls Memorial website. For details, \n");
281 				fprintf(stderr,"see https://msmemorial.if-legends.org/memorial.php\n");
282 				return -2;
283 			}
284 			n=fread(magbuf,sizeof(char),*magsize,f);
285 			fclose(f);
286 			*magsize=n;
287 			f=fopen(gfxfilename,"rb");
288 			if (f==NULL)
289 			{
290 				fprintf(stderr,"ERROR: unable to open [%s]\n",gfxfilename);
291 				fprintf(stderr,"This interpreter needs a the game's binaries in the .mag and .gfx\n");
292 				fprintf(stderr,"format from the Magnetic Scrolls Memorial website. For details, \n");
293 				fprintf(stderr,"see https://msmemorial.if-legends.org/memorial.php\n");
294 				return -2;
295 			}
296 			n=fread(gfxbuf,sizeof(char),*gfxsize,f);
297 			*gfxsize=n;
298 			fclose(f);
299 			break;
300 	}
301 	// at this point, they are stored in magbuf and gfxbuf.
302 	{
303 		FILE *f;
304 		int finish;
305 		finish=0;
306 		if (retrievefromcommandline(argc,argv,"-dumpmag",magfilename,sizeof(magfilename)))
307 		{
308 			finish=1;
309 			printf("Writing new .mag file [%s]\n",magfilename);
310 			f=fopen(magfilename,"wb");
311 			if (!f)
312 			{
313 				fprintf(stderr,"unable to open [%s]\n",magfilename);
314 			}
315 			fwrite(magbuf,sizeof(char),*magsize,f);
316 			fclose(f);
317 		}
318 		if (retrievefromcommandline(argc,argv,"-dumpgfx",gfxfilename,sizeof(gfxfilename)))
319 		{
320 			finish=1;
321 			printf("Writing new .gfx file [%s]\n",gfxfilename);
322 			f=fopen(gfxfilename,"wb");
323 			if (!f)
324 			{
325 				fprintf(stderr,"unable to open [%s]\n",gfxfilename);
326 			}
327 			fwrite(gfxbuf,sizeof(char),*gfxsize,f);
328 			fclose(f);
329 		}
330 		if (finish)
331 		{
332 			printf("finishing now\n");
333 			exit(0);
334 		}
335 	}
336 	return retval;
337 
338 
339 }
340