1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * Additional copyright for this file:
8 * Copyright (C) 1994-1998 Revolution Software Ltd.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 */
24
25
26 #include "common/file.h"
27 #include "common/textconsole.h"
28
29 #include "sword2/sword2.h"
30 #include "sword2/defs.h"
31 #include "sword2/header.h"
32 #include "sword2/logic.h"
33 #include "sword2/maketext.h"
34 #include "sword2/memory.h"
35 #include "sword2/resman.h"
36 #include "sword2/router.h"
37 #include "sword2/sound.h"
38
39 namespace Sword2 {
40
initStartMenu()41 bool Sword2Engine::initStartMenu() {
42 // Print out a list of all the start points available.
43 // There should be a linc produced file called startup.txt.
44 // This file should contain ascii numbers of all the resource game
45 // objects that are screen managers.
46 // We query each in turn and setup an array of start structures.
47 // If the file doesn't exist then we say so and return a 0.
48
49 Common::File fp;
50
51 // ok, load in the master screen manager file
52
53 _totalStartups = 0;
54 _totalScreenManagers = 0;
55
56 if (!fp.open("startup.inf")) {
57 warning("Cannot open startup.inf - the debugger won't have a start menu");
58 return false;
59 }
60
61 // The startup.inf file which contains a list of all the files. Now
62 // extract the filenames
63
64 int start_ids[MAX_starts];
65 int lineno = 0;
66
67 while (!fp.eos() && !fp.err()) {
68 Common::String line = fp.readLine();
69
70 // Skip empty lines or, more likely, the end of the stream.
71 if (line.size() == 0)
72 continue;
73
74 char *errptr;
75 int id;
76
77 lineno++;
78 id = strtol(line.c_str(), &errptr, 10);
79
80 if (*errptr) {
81 warning("startup.inf:%d: Invalid string '%s'", lineno, line.c_str());
82 continue;
83 }
84
85 if (!_resman->checkValid(id)) {
86 warning("startup.inf:%d: Invalid resource %d", lineno, id);
87 continue;
88 }
89
90 if (_resman->fetchType(id) != SCREEN_MANAGER) {
91 warning("startup.inf:%d: '%s' (%d) is not a screen manager", lineno, _resman->fetchName(id), id);
92 continue;
93 }
94
95 start_ids[_totalScreenManagers] = id;
96
97 if (++_totalScreenManagers >= MAX_starts) {
98 warning("Too many entries in startup.inf");
99 break;
100 }
101 }
102
103 // An I/O error before EOS? That's bad, but this is not a vital file.
104 if (fp.err() && !fp.eos())
105 warning("I/O error while reading startup.inf");
106
107 fp.close();
108
109 // Using this method the Gode generated resource.inf must have #0d0a
110 // on the last entry
111
112 debug(1, "%d screen manager objects", _totalScreenManagers);
113
114 // Open each object and make a query call. The object must fill in a
115 // startup structure. It may fill in several if it wishes - for
116 // instance a startup could be set for later in the game where
117 // specific vars are set
118
119 for (uint i = 0; i < _totalScreenManagers; i++) {
120 _startRes = start_ids[i];
121
122 debug(2, "Querying screen manager %d", _startRes);
123
124 // Open each one and run through the interpreter. Script 0 is
125 // the query request script. We have already made reasonably
126 // sure the resource is ok.
127
128 _logic->runResScript(_startRes, 0);
129 }
130
131 return 1;
132 }
133
registerStartPoint(int32 key,char * name)134 void Sword2Engine::registerStartPoint(int32 key, char *name) {
135 assert(_totalStartups < MAX_starts);
136
137 _startList[_totalStartups].start_res_id = _startRes;
138 _startList[_totalStartups].key = key;
139
140 strncpy(_startList[_totalStartups].description, name, MAX_description);
141 _startList[_totalStartups].description[MAX_description - 1] = 0;
142
143 _totalStartups++;
144 }
145
runStart(int start)146 void Sword2Engine::runStart(int start) {
147 // Restarting - stop sfx, music & speech!
148
149 _sound->clearFxQueue(true);
150 _logic->fnStopMusic(NULL);
151 _sound->unpauseSpeech();
152 _sound->stopSpeech();
153
154 // Remove all resources from memory, including player object and global
155 // variables
156
157 _resman->removeAll();
158
159 // Reopen global variables resource and player object
160 setupPersistentResources();
161
162 // Free all the route memory blocks from previous game
163 _logic->_router->freeAllRouteMem();
164
165 // If there was speech text, kill the text block
166 if (_logic->_speechTextBlocNo) {
167 _fontRenderer->killTextBloc(_logic->_speechTextBlocNo);
168 _logic->_speechTextBlocNo = 0;
169 }
170
171 _logic->runResObjScript(_startList[start].start_res_id, CUR_PLAYER_ID, _startList[start].key & 0xffff);
172
173 // Make sure there's a mouse, in case restarting while mouse not
174 // available
175 _logic->fnAddHuman(NULL);
176 }
177
178 } // End of namespace Sword2
179