4 * Riven-Wahrk - a reimplementation of the game Riven, by Cyan
5 * Copyright (C) 2009 Tyler Genter <tylergenter@gmail.com>
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
40 std::list
<Set
> Set::sets
;
43 void ChangeStack::handle (Game
*game
) {
45 std::string stackName
;
47 Name
name (game
->getStack (), 5);
48 std::cout
<< "going to stack " << name
.getString (stack
) << std::endl
;
49 stackName
= name
.getString (stack
);
53 game
->stack
= game
->set
->loadStack (stackName
[0]);
55 File
rmap (game
->stack
, Resource::RMAP
, 1);
57 for (int i
=0; i
< rmap
.getSize(); i
+=4) {
58 if (rmap
.readULong (i
) == ((hi
<< 16) + lo
)) {
59 game
->card
= new Card (game
, i
/4);
63 std::cout
<< "failed to load card" << std::endl
;
69 Stack::Stack (const std::string
&fileName
) {
70 std::cout
<< "opening file " << fileName
<< std::endl
;
71 mohawk1
= new Mohawk (fileName
);
75 Stack::Stack (const std::string
&file1
, const std::string
&file2
) {
76 std::cout
<< "opening file " << file1
<< " " << file2
<< std::endl
;
77 mohawk1
= new Mohawk (file1
);
78 mohawk2
= new Mohawk (file2
);
87 std::string
Stack::getFileLoc (uint32_t type
, int id
, uint32_t &offset
) {
88 offset
= mohawk1
->getFileLoc (type
, id
);
90 return mohawk1
->fileName
;
91 if (mohawk2
->getFileLoc (type
, id
)) {
92 offset
= mohawk2
->getFileLoc (type
, id
);
94 return mohawk2
->fileName
;
100 void Set::scanDisks () {
102 std::list
<Set
>::iterator iter
;
103 for (iter
= sets
.begin(); iter
!= sets
.end(); iter
++) {
104 iter
->disks
.clear ();
112 mtab
= fopen ("/etc/mtab", "r");
113 while (fscanf (mtab
, "%s %s %s %s %d %d\n", crap
, drive
, crap
, crap
, &intCrap
, &intCrap
) != EOF
) {
114 for (iter
= sets
.begin(); iter
!= sets
.end(); iter
++) {
115 if (iter
->diskBelong (std::string (drive
)))
127 SetErrorMode (SEM_FAILCRITICALERRORS
);
128 GetLogicalDriveStrings (512, drive
);
130 while (path
[0] != 0) {
131 if (GetDriveType (path
) == DRIVE_CDROM
) {
132 for (iter
= sets
.begin(); iter
!= sets
.end(); iter
++) {
133 if (iter
->diskBelong (std::string (path
)))
137 path
+= strlen (path
) + 1;
140 //for (iter = sets.begin(); iter != sets.end(); iter++)
141 // if (iter->diskBelong (string ("D:\\")))
148 // returns true if the disk at path belongs to this set
149 bool Set::diskBelong (const std::string
&path
) {
150 for (int i
=0; i
<(*config
)["disks"].getLength(); i
++) {
152 for (int j
=0; (j
<(*config
)["disks"][i
]["files"].getLength()) && found
; j
++) {
153 for (int k
=1; (k
< // first element is letter representing the stack
154 (*config
)["disks"][i
]["files"][j
].getLength()) && found
; k
++) {
155 found
= Common::isFilePresent (path
,
156 (*config
)["disks"][i
]["files"][j
][k
]);
160 // yay, we have a disk that matches
161 std::cout
<< "found a disk: " << (const char*) (*config
)["disks"][i
]["name"]
165 temp
.disk
= &((*config
)["disks"][i
]);
166 disks
.push_back (temp
);
173 // corresponds to Stack::Name
174 static std::string StackChar
[8] = {"a", "b", "g", "j", "o", "p", "r", "t"};
176 std::string
Set::getDiskId (Stack::Name stack
) {
178 for (int i
=0; i
<(*config
)["disks"].getLength(); i
++) {
179 for (int j
=0; j
<(*config
)["disks"][i
]["files"].getLength(); j
++) {
180 if (StackChar
[stack
].compare ( (const char*) (*config
)["disks"][i
]["files"][j
][0]) == 0)
181 return (*config
)["disks"][i
]["id"];
184 std::cout
<< "stack " << StackChar
[stack
] << " was not in set " << (const char*) (*config
)["name"] << std::endl
;
188 std::string
Set::getName (const std::string
&id
) {
189 for (int i
=0; i
<(*config
)["disks"].getLength(); i
++) {
190 if (id
.compare ( (const char*) (*config
)["disks"]["id"]) == 0)
191 return (*config
)["disks"][i
]["name"];
196 Set::Disk
*Set::findDisk (const std::string
&id
) {
199 std::list
<Disk
>::iterator iter
;
200 for (iter
= disks
.begin(); iter
!= disks
.end(); iter
++) {
201 if (id
.compare ( (const char*) (*iter
->disk
)["id"]) == 0)
204 std::cout
<< "disk " << id
<< " is not inserted\n";
208 Set::Set (Setting
*con
) {
212 void Set::init (Setting
*setsConfig
) {
216 for (int i
=0; i
<setsConfig
->getLength(); i
++) {
217 sets
.push_back (Set (&(*setsConfig
)[i
]));
222 Stack
*Set::loadStack (Stack::Name name
) {
224 std::string id
= getDiskId (name
);
227 while ((disk
= findDisk (id
)) == NULL
) {
229 // gdk_threads_enter ();
230 // Gtk::MessageDialog dialog ( "hello", false, Gtk::MESSAGE_QUESTION,
231 // Gtk::BUTTONS_OK_CANCEL);
232 // int result = dialog.run ();
233 // gdk_threads_leave ();
238 // FIXME get a better prompt
239 std::string temp
= "Please insert " + getName (id
);
240 MessageBox (NULL
, temp
.c_str (), "Riven-Wahrk", MB_ICONERROR
);
246 for (int i
=0; i
<(*disk
->disk
)["files"].getLength(); i
++) {
247 if (StackChar
[name
].compare ( (const char*) (*disk
->disk
)["files"][i
][0]) == 0) {
248 if ((*disk
->disk
)["files"][i
].getLength() == 2)
249 return new Stack (disk
->path
+ "/" + (const char*) (*disk
->disk
)["files"][i
][1]);
251 return new Stack (disk
->path
+ "/" + (const char*) (*disk
->disk
)["files"][i
][1],
252 disk
->path
+ "/" + (const char*) (*disk
->disk
)["files"][i
][2]);
255 std::cout
<< "shouldn't get here. failed to load stack\n";
260 Stack
*Set::loadStack (char name
) {
261 for (uint32_t i
=0; i
<sizeof (StackChar
); i
++) {
262 if (StackChar
[i
][0] == name
)
263 return loadStack ((Stack::Name
) i
);
265 std::cout
<< "failed to find stack " << name
<< std::endl
;