1 /*
2  * Holotz's Castle
3  * Copyright (C) 2004 Juan Carlos Seijo P�rez
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the Free
7  * Software Foundation; either version 2 of the License, or (at your option)
8  * any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc., 59
17  * Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Juan Carlos Seijo P�rez
20  * jacob@mainreactor.net
21  */
22 
23 /** Theme for Holotz's castle. Loads several resources as floors
24  * breaks, ladders and bars.
25  * @file    HCTheme.cpp
26  * @author  Juan Carlos Seijo P�rez
27  * @date    01/06/2004
28  * @version 0.0.1 - 01/06/2004 - First version.
29  */
30 
31 #include <HCTheme.h>
32 
33 #ifndef HC_DATA_DIR
34 #define HC_DATA_DIR "res/"
35 #endif
36 
HCTheme()37 HCTheme::HCTheme() : 	imgFloor(0), numFloors(0), imgContFloor(0), numContFloors(0), sprBreak(0), numBreaks(0),
38 											sprObject(0), numObjects(0), imgBar(0), numBars(0), imgLadder(0), numLadders(0), imgRope(0),
39 											numRopes(0), sprMain(0), numMains(0), sprGuest(0), numGuests(0), sprBall(0), numBalls(0),
40 											sprRandom(0), numRandoms(0), sprStatic(0), numStatics(0), sprMaker(0), numMakers(0),
41 											sprChaser(0), numChasers(0), imgDialog(0), numDialogs(0), imgNarrative(0), numNarratives(0)
42 
43 {
44 	memset(name, 0, sizeof(name));
45 }
46 
CountDirs()47 s32 HCTheme::CountDirs()
48 {
49 	char str[256];
50 	s32 num = 0;
51 	bool cont = true;
52 
53 	char cwd[2048];
54 	getcwd(cwd, 2048);
55 
56 	do
57 	{
58 		sprintf(str, "%d", num + 1);
59 		if (JFile::Exists(str))
60 		{
61 			++num;
62 		}
63 		else
64 		{
65 			cont = false;
66 		}
67 	} while (cont);
68 
69 	return num;
70 }
71 
LoadFloors()72 bool HCTheme::LoadFloors()
73 {
74 	if (0 != chdir("floor"))
75 	{
76 		return false;
77 	}
78 
79 	numFloors = CountDirs();
80 	if (0 == numFloors)
81 	{
82 		return false;
83 	}
84 
85 	char strDir[5];
86 	memset(strDir, 0, sizeof(strDir));
87 	s32 i = 1;
88 	bool ret = true;
89 
90 	// Creates the array
91 	imgFloor = new JImage[numFloors];
92 
93 	for (i = 1; ret && i <= numFloors; ++i)
94 	{
95 		sprintf(strDir, "%d", i);
96 
97 		if (0 == chdir(strDir))
98 		{
99 			if (!imgFloor[i-1].Load("floor.tga"))
100 			{
101 				fprintf(stderr, "HCTheme: Couldn't load floor.\n");
102 
103 				ret = false;
104 			}
105 
106 			chdir("..");
107 		}
108 	}
109 
110 	chdir("..");
111 
112   return ret;
113 }
114 
LoadContFloors()115 bool HCTheme::LoadContFloors()
116 {
117 	if (0 != chdir("contfloor"))
118 	{
119 		return false;
120 	}
121 
122 	numContFloors = CountDirs();
123 	if (0 == numContFloors)
124 	{
125 		return false;
126 	}
127 
128 	char strDir[5];
129 	memset(strDir, 0, sizeof(strDir));
130 	s32 i = 1;
131 	bool ret = true;
132 
133 	// Creates the array
134 	imgContFloor = new JImage* [numContFloors];
135 
136 	for (s32 c = 0; c < numContFloors; ++c)
137 	{
138 		imgContFloor[c] = new JImage[HCFDT_COUNT];
139 	}
140 
141 	for (i = 1; ret && i <= numContFloors; ++i)
142 	{
143 		sprintf(strDir, "%d", i);
144 
145 		if (0 == chdir(strDir))
146 		{
147 			// Load floor resources
148 			if (!imgContFloor[i-1][HCFDT_C].Load("c.tga") ||
149 					!imgContFloor[i-1][HCFDT_C1].Load("c1.tga") ||
150 					!imgContFloor[i-1][HCFDT_C1DL].Load("cdl.tga") ||
151 					!imgContFloor[i-1][HCFDT_C3].Load("c3.tga") ||
152 					!imgContFloor[i-1][HCFDT_C3DR].Load("cdr.tga") ||
153 					!imgContFloor[i-1][HCFDT_C7].Load("c7.tga") ||
154 					!imgContFloor[i-1][HCFDT_C7UL].Load("cul.tga") ||
155 					!imgContFloor[i-1][HCFDT_C9].Load("c9.tga") ||
156 					!imgContFloor[i-1][HCFDT_C9UR].Load("cur.tga") ||
157 					!imgContFloor[i-1][HCFDT_CU].Load("cu.tga") ||
158 					!imgContFloor[i-1][HCFDT_CD].Load("cd.tga") ||
159 					!imgContFloor[i-1][HCFDT_CL].Load("cl.tga") ||
160 					!imgContFloor[i-1][HCFDT_CR].Load("cr.tga") ||
161 					!imgContFloor[i-1][HCFDT_S2].Load("s2.tga") ||
162 					!imgContFloor[i-1][HCFDT_S4].Load("s4.tga") ||
163 					!imgContFloor[i-1][HCFDT_S6].Load("s6.tga") ||
164 					!imgContFloor[i-1][HCFDT_S8].Load("s8.tga") ||
165 					!imgContFloor[i-1][HCFDT_SH].Load("sh.tga") ||
166 					!imgContFloor[i-1][HCFDT_SV].Load("sv.tga") ||
167 					!imgContFloor[i-1][HCFDT_I].Load("i.tga"))
168 			{
169 				fprintf(stderr, "HCTheme: Couldn't load continuous floor.\n");
170 				ret = false;
171 			}
172 
173 			chdir("..");
174 		}
175 		else
176 		{
177 			fprintf(stderr, "HCTheme: Couldn't load continuous floor.\n");
178 		}
179 	}
180 
181 	chdir("..");
182 
183 	return ret;
184 }
185 
LoadBreaks()186 bool HCTheme::LoadBreaks()
187 {
188 	if (0 != chdir("break"))
189 	{
190 		return false;
191 	}
192 
193 	numBreaks = CountDirs();
194 	if (0 == numBreaks)
195 	{
196 		return false;
197 	}
198 
199 	JRW f;
200 	char strDir[5];
201 	memset(strDir, 0, sizeof(strDir));
202 	s32 i = 1;
203 	bool ret = true;
204 
205 	// Creates the array
206 	sprBreak = new JImageSprite*[numBreaks];
207 
208 	for (int c = 0; c < numBreaks; ++c)
209 	{
210 		sprBreak[c] = new JImageSprite[HCBDT_COUNT];
211 	}
212 
213 	for (i = 1; ret && i <= numBreaks; ++i)
214 	{
215 		sprintf(strDir, "%d", i);
216 
217 		if (0 == chdir(strDir))
218 		{
219 			if (!f.Create("normal.spr","rb") || (0 != sprBreak[i-1][HCBDT_NORMAL].Load(f)) ||
220 					!f.Create("breaking.spr","rb") || (0 != sprBreak[i-1][HCBDT_BREAKING].Load(f)) ||
221 					!f.Create("broken.spr","rb") || (0 != sprBreak[i-1][HCBDT_BROKEN].Load(f)))
222 			{
223 				fprintf(stderr, "HCTheme: Couldn't load break.\n");
224 				ret = false;
225 			}
226 
227 			chdir("..");
228 		}
229 	}
230 
231 	chdir("..");
232 
233   return ret;
234 }
235 
LoadBars()236 bool HCTheme::LoadBars()
237 {
238 	if (0 != chdir("bar"))
239 	{
240 		return false;
241 	}
242 
243 	numBars = CountDirs();
244 	if (0 == numBars)
245 	{
246 		return false;
247 	}
248 
249 	char strDir[5];
250 	memset(strDir, 0, sizeof(strDir));
251 	s32 i = 1;
252 	bool ret = true;
253 
254 	// Creates the array
255 	imgBar = new JImage[numBars];
256 
257 	for (i = 1; ret && i <= numBars; ++i)
258 	{
259 		sprintf(strDir, "%d", i);
260 
261 		if (0 == chdir(strDir))
262 		{
263 			if (!imgBar[i-1].Load("bar.tga"))
264 			{
265 				fprintf(stderr, "HCTheme: Couldn't load bar.\n");
266 				ret = false;
267 			}
268 
269 			chdir("..");
270 		}
271 	}
272 
273 	chdir("..");
274 
275   return ret;
276 }
277 
LoadLadders()278 bool HCTheme::LoadLadders()
279 {
280 	if (0 != chdir("ladder"))
281 	{
282 		return false;
283 	}
284 
285 	numLadders = CountDirs();
286 	if (0 == numLadders)
287 	{
288 		return false;
289 	}
290 
291 	char strDir[5];
292 	memset(strDir, 0, sizeof(strDir));
293 	s32 i = 1;
294 	bool ret = true;
295 
296 	// Creates the array
297 	imgLadder = new JImage[numLadders];
298 
299 	for (i = 1; ret && i <= numLadders; ++i)
300 	{
301 		sprintf(strDir, "%d", i);
302 
303 		if (0 == chdir(strDir))
304 		{
305 			if (!imgLadder[i-1].Load("ladder.tga"))
306 			{
307 				fprintf(stderr, "HCTheme: Couldn't load ladder.\n");
308 				ret = false;
309 			}
310 
311 			chdir("..");
312 		}
313 	}
314 
315 	chdir("..");
316 
317 	return ret;
318 }
319 
LoadDecos()320 bool HCTheme::LoadDecos()
321 {
322   /**< @todo: load several decos */
323 
324   return true;
325 }
326 
LoadObjects()327 bool HCTheme::LoadObjects()
328 {
329 	if (0 != chdir("object"))
330 	{
331 		return false;
332 	}
333 
334 	numObjects = CountDirs();
335 	if (0 == numObjects)
336 	{
337 		return false;
338 	}
339 
340 	JRW f;
341 	char strDir[5];
342 	memset(strDir, 0, sizeof(strDir));
343 	s32 i = 1;
344 	bool ret = true;
345 
346 	// Creates the array
347 	sprObject = new JImageSprite*[numObjects];
348 
349 	for (int c = 0; c < numObjects; ++c)
350 	{
351 		sprObject[c] = new JImageSprite[HCODT_COUNT];
352 	}
353 
354 	for (i = 1; ret && i <= numObjects; ++i)
355 	{
356 		sprintf(strDir, "%d", i);
357 
358 		if (0 == chdir(strDir))
359 		{
360 			if (!f.Create("normal.spr","rb") || 0 != sprObject[i-1][HCODT_NORMAL].Load(f) ||
361 					!f.Create("acquired.spr","rb") || 0 != sprObject[i-1][HCODT_ACQUIRED].Load(f))
362 			{
363 				fprintf(stderr, "HCTheme: Couldn't load object.\n");
364 				ret = false;
365 			}
366 
367 			chdir("..");
368 		}
369 	}
370 
371 	chdir("..");
372 
373   return ret;
374 }
375 
LoadRopes()376 bool HCTheme::LoadRopes()
377 {
378 	if (0 != chdir("rope"))
379 	{
380 		return false;
381 	}
382 
383 	numRopes = CountDirs();
384 	if (0 == numRopes)
385 	{
386 		return false;
387 	}
388 
389 	char strDir[5];
390 	memset(strDir, 0, sizeof(strDir));
391 	s32 i = 1;
392 	bool ret = true;
393 
394 	// Creates the array
395 	imgRope = new JImage*[numRopes];
396 
397 	for (int c = 0; c < numRopes; ++c)
398 	{
399 		imgRope[c] = new JImage[HCRDT_COUNT];
400 	}
401 
402 	for (i = 1; ret && i <= numRopes; ++i)
403 	{
404 		sprintf(strDir, "%d", i);
405 
406 		if (0 == chdir(strDir))
407 		{
408 			if (!imgRope[i-1][HCRDT_EDGE].Load("edge.tga") ||
409 					!imgRope[i-1][HCRDT_TOP].Load("top.tga") ||
410 					!imgRope[i-1][HCRDT_MIDDLE].Load("middle.tga"))
411 			{
412 				fprintf(stderr, "HCTheme: Couldn't load rope.\n");
413 				ret = false;
414 			}
415 
416 			chdir("..");
417 		}
418 	}
419 
420 	chdir("..");
421 
422   return ret;
423 }
424 
LoadChar(const char * directory,JImageSprite ** & sprArr,s32 & num)425 bool HCTheme::LoadChar(const char *directory, JImageSprite ** &sprArr, s32 &num)
426 {
427 	if (0 != chdir(directory))
428 	{
429 		return false;
430 	}
431 
432 	const char *files[] = {"stop.spr",
433 												 "right.spr",
434 												 "left.spr",
435 												 "up.spr",
436 												 "down.spr",
437 												 "slide.spr",
438 												 "jump.spr",
439 												 "jumpleft.spr",
440 												 "jumpright.spr",
441 												 "fall.spr",
442 												 "dead.spr",
443 												 "hang.spr"};
444 
445 	JRW f;
446 	num = CountDirs();
447 
448 	if (0 == num)
449 	{
450 		return false;
451 	}
452 
453 	char strDir[5];
454 	memset(strDir, 0, sizeof(strDir));
455 	s32 i = 1;
456 	bool ret = true;
457 
458 	// Creates the array
459 	sprArr = new JImageSprite*[num];
460 
461 	for (s32 c = 0; c < num; ++c)
462 	{
463 		sprArr[c] = new JImageSprite[HCCDT_COUNT];
464 	}
465 
466 	// For each numbered dir loads each character's state
467 	for (s32 k = 1; ret && k <= num; ++k)
468 	{
469 		sprintf(strDir, "%d", k);
470 
471 		if (0 == chdir(strDir))
472 		{
473 			for (i = 0; i < HCCDT_COUNT; ++i)
474 			{
475 				if (JFile::Exists(files[i]))
476 				{
477 					if (f.Create(files[i],"rb"))
478 					{
479 						if (0 != sprArr[k - 1][i].Load(f))
480 						{
481 							fprintf(stderr, "Error loading character sprite file %s\n", files[i]);
482 							return false;
483 						}
484 					}
485 				} // if res/char exists
486 				else
487 				{
488 					fprintf(stderr, "File %s does not exist.\n", files[i]);
489 				}
490 			} // for every state
491 
492 			chdir("..");
493 		} // if chdir()
494 	}
495 
496 	chdir("../..");
497 
498 	return true;
499 }
500 
LoadCharacters()501 bool HCTheme::LoadCharacters()
502 {
503 	if (LoadChar("char/main", sprMain, numMains) &&
504 			LoadChar("char/ball", sprBall, numBalls) &&
505 			LoadChar("char/random", sprRandom, numRandoms) &&
506 			LoadChar("char/static", sprStatic, numStatics) &&
507 			LoadChar("char/maker", sprMaker, numMakers) &&
508 			LoadChar("char/chaser", sprChaser, numChasers) &&
509 			LoadChar("char/guest", sprGuest, numGuests))
510 	{
511 		return true;
512 	}
513 
514 	return false;
515 }
516 
LoadDialogs()517 bool HCTheme::LoadDialogs()
518 {
519 	if (0 != chdir("dialog"))
520 	{
521 		return false;
522 	}
523 
524 	numDialogs = CountDirs();
525 	if (0 == numDialogs)
526 	{
527 		return false;
528 	}
529 
530 	char strDir[5];
531 	memset(strDir, 0, sizeof(strDir));
532 	s32 i = 1;
533 	bool ret = true;
534 
535 	// Creates the array
536 	imgDialog = new JImage* [numDialogs];
537 
538 	for (s32 k = 0; k < numDialogs; ++k)
539 	{
540 		imgDialog[k] = new JImage[11];
541 	}
542 
543 	for (i = 1; ret && i <= numDialogs; ++i)
544 	{
545 		sprintf(strDir, "%d", i);
546 
547 		if (0 == chdir(strDir))
548 		{
549 			if (!imgDialog[i-1][HCTDT_1].Load("1.tga") ||
550 					!imgDialog[i-1][HCTDT_2].Load("2.tga") ||
551 					!imgDialog[i-1][HCTDT_3].Load("3.tga") ||
552 					!imgDialog[i-1][HCTDT_4].Load("4.tga") ||
553 					!imgDialog[i-1][HCTDT_5].Load("5.tga") ||
554 					!imgDialog[i-1][HCTDT_6].Load("6.tga") ||
555 					!imgDialog[i-1][HCTDT_7].Load("7.tga") ||
556 					!imgDialog[i-1][HCTDT_8].Load("8.tga") ||
557 					!imgDialog[i-1][HCTDT_9].Load("9.tga") ||
558 					!imgDialog[i-1][HCTDT_LEFT].Load("left.tga") ||
559 					!imgDialog[i-1][HCTDT_RIGHT].Load("right.tga"))
560 			{
561         char strcwd[256];
562         getcwd(strcwd, 256);
563         perror("error");
564 				fprintf(stderr, "HCTheme: Couldn't load dialog. %s en dir %s\n", SDL_GetError(), strcwd);
565 				ret = false;
566 			}
567 
568 			chdir("..");
569 		}
570 	}
571 
572 	chdir("..");
573 
574   return ret;
575 }
576 
LoadNarratives()577 bool HCTheme::LoadNarratives()
578 {
579 	if (0 != chdir("narrative"))
580 	{
581 		return false;
582 	}
583 
584 	numNarratives = CountDirs();
585 	if (0 == numNarratives)
586 	{
587 		return false;
588 	}
589 
590 	char strDir[5];
591 	memset(strDir, 0, sizeof(strDir));
592 	s32 i = 1;
593 	bool ret = true;
594 
595 	// Creates the array
596 	imgNarrative = new JImage *[numNarratives];
597 
598 	for (s32 k = 0; k < numNarratives; ++k)
599 	{
600 		imgNarrative[k] = new JImage[9];
601 	}
602 
603 	for (i = 1; ret && i <= numNarratives; ++i)
604 	{
605 		sprintf(strDir, "%d", i);
606 
607 		if (0 == chdir(strDir))
608 		{
609 			if (!imgNarrative[i-1][HCTDT_1].Load("1.tga") ||
610 					!imgNarrative[i-1][HCTDT_2].Load("2.tga") ||
611 					!imgNarrative[i-1][HCTDT_3].Load("3.tga") ||
612 					!imgNarrative[i-1][HCTDT_4].Load("4.tga") ||
613 					!imgNarrative[i-1][HCTDT_5].Load("5.tga") ||
614 					!imgNarrative[i-1][HCTDT_6].Load("6.tga") ||
615 					!imgNarrative[i-1][HCTDT_7].Load("7.tga") ||
616 					!imgNarrative[i-1][HCTDT_8].Load("8.tga") ||
617 					!imgNarrative[i-1][HCTDT_9].Load("9.tga"))
618 			{
619 				fprintf(stderr, "HCTheme: Couldn't load narrative.\n");
620 				ret = false;
621 			}
622 
623 			chdir("..");
624 		}
625 	}
626 
627 	chdir("..");
628 
629   return ret;
630 }
631 
Load(const char * themeName)632 bool HCTheme::Load(const char *themeName)
633 {
634 	Destroy();
635 
636 	char themeDir[PATH_MAX];
637 	char curDir[PATH_MAX];
638 	getcwd(curDir, PATH_MAX);
639 
640 	// Checks for the theme in any of:
641 	// - installation directory
642 	// - current directory
643 	// - home directory
644 	strncpy(name, themeName, sizeof(name));
645 	snprintf(themeDir, sizeof(themeDir), "theme/%s", name);
646 
647 	if (!HCUtil::FindFile(themeDir))
648 	{
649 		fprintf(stderr, "Couldn't find the theme %s\n", themeDir);
650 		return false;
651 	}
652 
653 	if (0 != chdir(HCUtil::File()))
654 	{
655 		fprintf(stderr, "Couldn't find the theme %s\n", HCUtil::File());
656 	}
657 
658 	if (!LoadFloors() ||
659 			!LoadContFloors() ||
660 			!LoadDecos() ||
661 			!LoadBars() ||
662 			!LoadBreaks() ||
663 			!LoadLadders() ||
664 			!LoadObjects() ||
665 			!LoadRopes() ||
666 			!LoadCharacters() ||
667 			!LoadDialogs() ||
668 			!LoadNarratives())
669 	{
670 		fprintf(stderr, "HCTheme: Couldn't load resources.\n");
671 
672 		chdir(curDir);
673 
674 		return false;
675 	}
676 
677 	chdir(curDir);
678 
679 	return true;
680 }
681 
Destroy()682 void HCTheme::Destroy()
683 {
684 	JDELETE_ARRAY(imgFloor);
685 	JDELETE_ARRAY_ARRAY(imgContFloor, numContFloors);
686 	JDELETE_ARRAY_ARRAY(sprBreak, numBreaks);
687 	JDELETE_ARRAY(imgBar);
688 	JDELETE_ARRAY(imgLadder);
689 	JDELETE_ARRAY_ARRAY(sprObject, numObjects);
690 	JDELETE_ARRAY_ARRAY(imgRope, numRopes);
691 	JDELETE_ARRAY_ARRAY(sprMain, numMains);
692 	JDELETE_ARRAY_ARRAY(sprBall, numBalls);
693 	JDELETE_ARRAY_ARRAY(sprRandom, numRandoms);
694 	JDELETE_ARRAY_ARRAY(sprStatic, numStatics);
695 	JDELETE_ARRAY_ARRAY(sprMaker, numMakers);
696 	JDELETE_ARRAY_ARRAY(sprChaser, numChasers);
697 	JDELETE_ARRAY_ARRAY(sprGuest, numGuests);
698 	JDELETE_ARRAY_ARRAY(imgDialog, numDialogs);
699 	JDELETE_ARRAY_ARRAY(imgNarrative, numNarratives);
700 }
701