fixed win32
[riven-wahrk.git] / src / Stack.cpp
blobf4db8a4b05bb6df65526d76d27eb0835dcb23917
2 /*
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/>.
22 #include <stdio.h>
23 #include <string.h>
25 #ifdef __WIN32__
26 #include <windows.h>
27 #endif
29 #ifdef __linux__
30 #include <gtkmm.h>
31 #include <gtk/gtk.h>
32 #endif
34 #include "Stack.h"
35 #include "File.h"
36 #include "Name.h"
37 #include "Game.h"
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);
52 delete game->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);
60 return;
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);
72 mohawk2 = NULL;
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);
81 Stack::~Stack () {
82 delete mohawk1;
83 if (mohawk2)
84 delete mohawk2;
87 std::string Stack::getFileLoc (uint32_t type, int id, uint32_t &offset) {
88 offset = mohawk1->getFileLoc (type, id);
89 if (offset)
90 return mohawk1->fileName;
91 if (mohawk2->getFileLoc (type, id)) {
92 offset = mohawk2->getFileLoc (type, id);
93 if (offset)
94 return mohawk2->fileName;
96 offset = 0;
97 return "";
100 void Set::scanDisks () {
101 // delete all disks
102 std::list<Set>::iterator iter;
103 for (iter = sets.begin(); iter != sets.end(); iter++) {
104 iter->disks.clear ();
106 #ifdef __linux__
107 char drive[256];
108 char crap[256];
109 int intCrap;
110 FILE *mtab;
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)))
116 break;
119 fclose (mtab);
121 #endif
123 #ifdef __WIN32__
126 char drive[512];
127 SetErrorMode (SEM_FAILCRITICALERRORS);
128 GetLogicalDriveStrings (512, drive);
129 char *path = 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)))
134 break;
137 path += strlen (path) + 1;
140 //for (iter = sets.begin(); iter != sets.end(); iter++)
141 // if (iter->diskBelong (string ("D:\\")))
142 // break;
144 #endif
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++) {
151 bool found = true;
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]);
159 if (found) {
160 // yay, we have a disk that matches
161 std::cout << "found a disk: " << (const char*) (*config)["disks"][i]["name"]
162 << std::endl;
163 Disk temp;
164 temp.path = path;
165 temp.disk = &((*config)["disks"][i]);
166 disks.push_back (temp);
167 return true;
170 return false;
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;
185 return "";
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"];
193 return "FIXME";
196 Set::Disk *Set::findDisk (const std::string &id) {
198 scanDisks ();
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)
202 return &*iter;
204 std::cout << "disk " << id << " is not inserted\n";
205 return NULL;
208 Set::Set (Setting *con) {
209 config = con;
212 void Set::init (Setting *setsConfig) {
214 sets.clear ();
216 for (int i=0; i<setsConfig->getLength(); i++) {
217 sets.push_back (Set (&(*setsConfig)[i]));
219 scanDisks ();
222 Stack *Set::loadStack (Stack::Name name) {
224 std::string id = getDiskId (name);
225 Disk *disk;
227 while ((disk = findDisk (id)) == NULL) {
228 #ifdef __linux__
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 ();
234 #endif
236 #ifdef __WIN32__
238 // FIXME get a better prompt
239 std::string temp = "Please insert " + getName (id);
240 MessageBox (NULL, temp.c_str (), "Riven-Wahrk", MB_ICONERROR);
242 #endif
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]);
250 else
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";
256 return NULL;
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;
266 return NULL;