1 /**
2 * @file init.cpp
3 *
4 * Implementation of routines for initializing the environment, disable screen saver, load MPQ.
5 */
6 #include <string>
7 #include <vector>
8
9 #include "all.h"
10 #include "paths.h"
11 #include "../3rdParty/Storm/Source/storm.h"
12 #include "../DiabloUI/diabloui.h"
13 #include <SDL.h>
14 #include <config.h>
15
16 #ifdef __vita__
17 // increase default allowed heap size on Vita
18 int _newlib_heap_size_user = 100 * 1024 * 1024;
19 #endif
20
21 DEVILUTION_BEGIN_NAMESPACE
22
23 _SNETVERSIONDATA fileinfo;
24 /** True if the game is the current active window */
25 int gbActive;
26 /** A handle to an hellfire.mpq archive. */
27 HANDLE hellfire_mpq;
28 /** The current input handler function */
29 WNDPROC CurrentProc;
30 /** A handle to the spawn.mpq archive. */
31 HANDLE spawn_mpq;
32 /** A handle to the diabdat.mpq archive. */
33 HANDLE diabdat_mpq;
34 /** A handle to the patch_rt.mpq archive. */
35 HANDLE patch_rt_mpq;
36 /** Indicate if we only have access to demo data */
37 bool gbIsSpawn;
38 /** Indicate if we have loaded the Hellfire expansion data */
39 bool gbIsHellfire;
40 /** Indicate if we want vanilla savefiles */
41 bool gbVanilla;
42 HANDLE hfmonk_mpq;
43 HANDLE hfbard_mpq;
44 HANDLE hfbarb_mpq;
45 HANDLE hfmusic_mpq;
46 HANDLE hfvoice_mpq;
47 HANDLE hfopt1_mpq;
48 HANDLE hfopt2_mpq;
49 HANDLE devilutionx_mpq;
50
51 namespace {
52
init_test_access(const std::vector<std::string> & paths,const char * mpq_name,const char * reg_loc,int dwPriority,int fs)53 HANDLE init_test_access(const std::vector<std::string> &paths, const char *mpq_name, const char *reg_loc, int dwPriority, int fs)
54 {
55 HANDLE archive;
56 std::string mpq_abspath;
57 DWORD mpq_flags = 0;
58 #if !defined(__SWITCH__) && !defined(__AMIGA__) && !defined(__vita__)
59 mpq_flags |= MPQ_FLAG_READ_ONLY;
60 #endif
61 for (int i = 0; i < paths.size(); i++) {
62 mpq_abspath = paths[i] + mpq_name;
63 if (SFileOpenArchive(mpq_abspath.c_str(), dwPriority, mpq_flags, &archive)) {
64 SFileSetBasePath(paths[i].c_str());
65 return archive;
66 }
67 }
68
69 return NULL;
70 }
71
72 } // namespace
73
74 /* data */
75
76 char gszVersionNumber[64] = "internal version unknown";
77 char gszProductName[64] = "DevilutionX vUnknown";
78
init_cleanup()79 void init_cleanup()
80 {
81 if (gbIsMultiplayer && gbRunGame) {
82 pfile_write_hero();
83 }
84 pfile_flush_W();
85
86 if (spawn_mpq) {
87 SFileCloseArchive(spawn_mpq);
88 spawn_mpq = NULL;
89 }
90 if (diabdat_mpq) {
91 SFileCloseArchive(diabdat_mpq);
92 diabdat_mpq = NULL;
93 }
94 if (patch_rt_mpq) {
95 SFileCloseArchive(patch_rt_mpq);
96 patch_rt_mpq = NULL;
97 }
98 if (hellfire_mpq) {
99 SFileCloseArchive(hellfire_mpq);
100 hellfire_mpq = NULL;
101 }
102 if (hfmonk_mpq) {
103 SFileCloseArchive(hfmonk_mpq);
104 hfmonk_mpq = NULL;
105 }
106 if (hfbard_mpq) {
107 SFileCloseArchive(hfbard_mpq);
108 hfbard_mpq = NULL;
109 }
110 if (hfbarb_mpq) {
111 SFileCloseArchive(hfbarb_mpq);
112 hfbarb_mpq = NULL;
113 }
114 if (hfmusic_mpq) {
115 SFileCloseArchive(hfmusic_mpq);
116 hfmusic_mpq = NULL;
117 }
118 if (hfvoice_mpq) {
119 SFileCloseArchive(hfvoice_mpq);
120 hfvoice_mpq = NULL;
121 }
122 if (hfopt1_mpq) {
123 SFileCloseArchive(hfopt1_mpq);
124 hfopt1_mpq = NULL;
125 }
126 if (hfopt2_mpq) {
127 SFileCloseArchive(hfopt2_mpq);
128 hfopt2_mpq = NULL;
129 }
130 if (devilutionx_mpq) {
131 SFileCloseArchive(patch_rt_mpq);
132 patch_rt_mpq = NULL;
133 }
134
135 NetClose();
136 }
137
init_get_file_info()138 static void init_get_file_info()
139 {
140 snprintf(gszProductName, sizeof(gszProductName) / sizeof(char), "%s v%s", PROJECT_NAME, PROJECT_VERSION);
141 snprintf(gszVersionNumber, sizeof(gszVersionNumber) / sizeof(char), "version %s", PROJECT_VERSION);
142 }
143
init_archives()144 void init_archives()
145 {
146 HANDLE fh = NULL;
147 memset(&fileinfo, 0, sizeof(fileinfo));
148 fileinfo.size = sizeof(fileinfo);
149 fileinfo.versionstring = gszVersionNumber;
150 init_get_file_info();
151
152 std::vector<std::string> paths;
153 paths.reserve(5);
154 paths.push_back(GetBasePath());
155 paths.push_back(GetPrefPath());
156 if (paths[0] == paths[1])
157 paths.pop_back();
158
159 #ifdef __linux__
160 paths.push_back("/usr/share/diasurgical/devilutionx/");
161 paths.push_back("/usr/local/share/diasurgical/devilutionx/");
162 #endif
163
164 paths.push_back(""); // PWD
165
166 diabdat_mpq = init_test_access(paths, "DIABDAT.MPQ", "DiabloCD", 1000, FS_CD);
167 if (diabdat_mpq == NULL) {
168 // DIABDAT.MPQ is uppercase on the original CD and the GOG version.
169 diabdat_mpq = init_test_access(paths, "diabdat.mpq", "DiabloCD", 1000, FS_CD);
170 }
171
172 if (diabdat_mpq == NULL) {
173 spawn_mpq = init_test_access(paths, "spawn.mpq", "DiabloSpawn", 1000, FS_PC);
174 if (spawn_mpq != NULL)
175 gbIsSpawn = true;
176 }
177 if (!SFileOpenFile("ui_art\\title.pcx", &fh))
178 InsertCDDlg();
179 SFileCloseFile(fh);
180
181 patch_rt_mpq = init_test_access(paths, "patch_rt.mpq", "DiabloInstall", 2000, FS_PC);
182 if (patch_rt_mpq == NULL)
183 patch_rt_mpq = init_test_access(paths, "patch_sh.mpq", "DiabloSpawn", 2000, FS_PC);
184
185 hellfire_mpq = init_test_access(paths, "hellfire.mpq", "DiabloInstall", 8000, FS_PC);
186 if (hellfire_mpq != NULL)
187 gbIsHellfire = true;
188 hfmonk_mpq = init_test_access(paths, "hfmonk.mpq", "DiabloInstall", 8100, FS_PC);
189 hfbard_mpq = init_test_access(paths, "hfbard.mpq", "DiabloInstall", 8110, FS_PC);
190 if (hfbard_mpq != NULL)
191 gbBard = true;
192 hfbarb_mpq = init_test_access(paths, "hfbarb.mpq", "DiabloInstall", 8120, FS_PC);
193 if (hfbarb_mpq != NULL)
194 gbBarbarian = true;
195 hfmusic_mpq = init_test_access(paths, "hfmusic.mpq", "DiabloInstall", 8200, FS_PC);
196 hfvoice_mpq = init_test_access(paths, "hfvoice.mpq", "DiabloInstall", 8500, FS_PC);
197 hfopt1_mpq = init_test_access(paths, "hfopt1.mpq", "DiabloInstall", 8600, FS_PC);
198 hfopt2_mpq = init_test_access(paths, "hfopt2.mpq", "DiabloInstall", 8610, FS_PC);
199
200 if (gbIsHellfire && (hfmonk_mpq == NULL || hfmusic_mpq == NULL || hfvoice_mpq == NULL)) {
201 UiErrorOkDialog("Some Hellfire MPQs are missing", "Not all Hellfire MPQs were found.\nPlease copy all the hf*.mpq files.");
202 app_fatal(NULL);
203 }
204
205 devilutionx_mpq = init_test_access(paths, "devilutionx.mpq", "DiabloInstall", 9000, FS_PC);
206 }
207
init_create_window()208 void init_create_window()
209 {
210 if (!SpawnWindow(PROJECT_NAME))
211 app_fatal("Unable to create main window");
212 dx_init();
213 gbActive = true;
214 SDL_DisableScreenSaver();
215 }
216
MainWndProc(UINT Msg,WPARAM wParam,LPARAM lParam)217 void MainWndProc(UINT Msg, WPARAM wParam, LPARAM lParam)
218 {
219 switch (Msg) {
220 case DVL_WM_PAINT:
221 force_redraw = 255;
222 break;
223 case DVL_WM_QUERYENDSESSION:
224 diablo_quit(0);
225 break;
226 }
227 }
228
SetWindowProc(WNDPROC NewProc)229 WNDPROC SetWindowProc(WNDPROC NewProc)
230 {
231 WNDPROC OldProc;
232
233 OldProc = CurrentProc;
234 CurrentProc = NewProc;
235 return OldProc;
236 }
237
238 DEVILUTION_END_NAMESPACE
239