Skip to content

Commit cf24b91

Browse files
libsiedler2
1 parent eeda003 commit cf24b91

33 files changed

Lines changed: 1767 additions & 2706 deletions

CGame.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ CGame::CGame(Extent GameResolution_, bool fullscreen_)
3737
: GameResolution(GameResolution_), fullscreen(fullscreen_), Running(true), showLoadScreen(true),
3838
lastFps("", Position{0, 0}, FontSize::Medium)
3939
{
40-
global::bmpArray.resize(MAXBOBBMP);
41-
global::shadowArray.resize(MAXBOBSHADOW);
4240
global::s2 = this;
4341
}
4442

CGame.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#pragma once
77

88
#include "CIO/CFont.h"
9+
#include "SdlSurface.h"
910
#include "Texture.h"
1011
#include <boost/filesystem/path.hpp>
1112
#include <Point.h>

CGame_Event.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,7 @@ void CGame::EventHandling(SDL_Event* Event)
7979
// if (SDL_GetModState() == (KMOD_LCTRL | KMOD_LALT))
8080
callback::debugger(INITIALIZING_CALL);
8181
break;
82-
case SDLK_F4: // if CTRL and ALT are pressed
83-
// if (SDL_GetModState() == (KMOD_LCTRL | KMOD_LALT))
84-
callback::viewer(INITIALIZING_CALL);
85-
break;
82+
8683
#endif
8784
// F5 - F7 is ZOOM, F5 = zoom in, F6 = normal view, F7 = zoom out
8885
case SDLK_F5:

CGame_Init.cpp

Lines changed: 127 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
1111
#include "callbacks.h"
1212
#include "globals.h"
1313
#include "lua/GameDataLoader.h"
14+
#include <libsiedler2/Archiv.h>
15+
#include <libsiedler2/ArchivItem_Bitmap.h>
16+
#include <libsiedler2/ArchivItem_Palette.h>
17+
#include <libsiedler2/ErrorCodes.h>
18+
#include <libsiedler2/libsiedler2.h>
1419
#include <glad/glad.h>
1520
#include <iostream>
1621

@@ -138,8 +143,6 @@ bool CGame::Init()
138143
std::cout << "failure";
139144
return false;
140145
}
141-
CFile::init();
142-
143146
/*NOTE: its important to load a palette at first,
144147
* otherwise all images will be black (in exception of the LBM-Files, they have their own palette).
145148
* if its necessary to load pictures from a
@@ -153,20 +156,25 @@ bool CGame::Init()
153156
// load some pictures (after all the splash-screens)
154157
// at first GFX/PICS/SETUP997.LBM, cause this is the S2-loading picture
155158
std::cout << "\nLoading file: GFX/PICS/SETUP997.LBM...";
156-
if(!CFile::open_file(global::gameDataFilePath / "GFX/PICS/SETUP997.LBM", LBM))
159+
if(!global::loadArchive(ArchiveID::SETUP997, global::gameDataFilePath / "GFX/PICS/SETUP997.LBM", nullptr))
157160
{
158161
std::cout << "failure";
159162
// if SETUP997.LBM doesn't exist, it's probably settlers2+mission cd and there we have SETUP998.LBM instead
160163
std::cout << "\nTry to load file: GFX/PICS/SETUP998.LBM instead...";
161-
if(!CFile::open_file(global::gameDataFilePath / "GFX/PICS/SETUP998.LBM", LBM))
164+
if(!global::loadArchive(ArchiveID::SETUP997, global::gameDataFilePath / "GFX/PICS/SETUP998.LBM", nullptr))
162165
{
163166
std::cout << "failure";
164167
return false;
165168
}
166169
}
167170

168171
// Create texture for splash background
169-
splashBg_.load(global::bmpArray[SPLASHSCREEN_LOADING_S2SCREEN].surface.get(), true);
172+
{
173+
auto& archiv = global::typedArchives[ArchiveID::SETUP997];
174+
auto* bmp = dynamic_cast<const libsiedler2::baseArchivItem_Bitmap*>(archiv.get(0));
175+
if(bmp)
176+
splashBg_.load(*bmp, true);
177+
}
170178

171179
// std::cout << "\nShow loading screen...";
172180
showLoadScreen = true;
@@ -182,125 +190,157 @@ bool CGame::Init()
182190
}
183191

184192
// continue loading pictures
185-
for(const std::string file :
186-
{"GFX/PICS/SETUP000.LBM", "GFX/PICS/SETUP010.LBM", "GFX/PICS/SETUP011.LBM", "GFX/PICS/SETUP012.LBM",
187-
"GFX/PICS/SETUP013.LBM", "GFX/PICS/SETUP014.LBM", "GFX/PICS/SETUP015.LBM"})
193+
const struct
188194
{
189-
std::cout << "\nLoading file: " << file << "...";
190-
if(!CFile::open_file(global::gameDataFilePath / file, LBM))
195+
ArchiveID id;
196+
const char* path;
197+
} setupFiles[] = {
198+
{ArchiveID::SETUP000, "GFX/PICS/SETUP000.LBM"}, {ArchiveID::SETUP010, "GFX/PICS/SETUP010.LBM"},
199+
{ArchiveID::SETUP011, "GFX/PICS/SETUP011.LBM"}, {ArchiveID::SETUP012, "GFX/PICS/SETUP012.LBM"},
200+
{ArchiveID::SETUP013, "GFX/PICS/SETUP013.LBM"}, {ArchiveID::SETUP014, "GFX/PICS/SETUP014.LBM"},
201+
{ArchiveID::SETUP015, "GFX/PICS/SETUP015.LBM"},
202+
};
203+
for(const auto& sf : setupFiles)
204+
{
205+
std::cout << "\nLoading file: " << sf.path << "...";
206+
if(!global::loadArchive(sf.id, global::gameDataFilePath / sf.path, nullptr))
191207
{
192208
std::cout << "failure";
193209
// if it doesn't exist, it's probably settlers2+missioncd and we simply load SETUP010.LBM instead
194210
std::cout << "\nLoading file: GFX/PICS/SETUP010.LBM instead...";
195-
if(!CFile::open_file(global::gameDataFilePath / "GFX/PICS/SETUP010.LBM", LBM))
211+
if(!global::loadArchive(ArchiveID::SETUP010, global::gameDataFilePath / "GFX/PICS/SETUP010.LBM", nullptr))
196212
{
197213
std::cout << "failure";
198214
return false;
199215
}
200216
}
201217
}
202218

203-
for(const std::string file :
204-
{"GFX/PICS/SETUP666.LBM", "GFX/PICS/SETUP667.LBM", "GFX/PICS/SETUP801.LBM", "GFX/PICS/SETUP802.LBM",
205-
"GFX/PICS/SETUP803.LBM", "GFX/PICS/SETUP804.LBM", "GFX/PICS/SETUP805.LBM", "GFX/PICS/SETUP806.LBM",
206-
"GFX/PICS/SETUP810.LBM", "GFX/PICS/SETUP811.LBM", "GFX/PICS/SETUP895.LBM", "GFX/PICS/SETUP896.LBM"})
207-
{
208-
std::cout << "\nLoading file: " << file << "...";
209-
if(!CFile::open_file(global::gameDataFilePath / file, LBM))
219+
{ // batch 2: SETUP666-896
220+
const struct
210221
{
211-
std::cout << "failure";
212-
return false;
213-
}
214-
}
215-
216-
for(const std::string file : {"GFX/PICS/SETUP897.LBM", "GFX/PICS/SETUP898.LBM"})
217-
{
218-
std::cout << "\nLoading file: " << file << "...";
219-
if(!CFile::open_file(global::gameDataFilePath / file, LBM))
222+
ArchiveID id;
223+
const char* path;
224+
} files[] = {
225+
{ArchiveID::SETUP666, "GFX/PICS/SETUP666.LBM"}, {ArchiveID::SETUP667, "GFX/PICS/SETUP667.LBM"},
226+
{ArchiveID::SETUP801, "GFX/PICS/SETUP801.LBM"}, {ArchiveID::SETUP802, "GFX/PICS/SETUP802.LBM"},
227+
{ArchiveID::SETUP803, "GFX/PICS/SETUP803.LBM"}, {ArchiveID::SETUP804, "GFX/PICS/SETUP804.LBM"},
228+
{ArchiveID::SETUP805, "GFX/PICS/SETUP805.LBM"}, {ArchiveID::SETUP806, "GFX/PICS/SETUP806.LBM"},
229+
{ArchiveID::SETUP810, "GFX/PICS/SETUP810.LBM"}, {ArchiveID::SETUP811, "GFX/PICS/SETUP811.LBM"},
230+
{ArchiveID::SETUP895, "GFX/PICS/SETUP895.LBM"}, {ArchiveID::SETUP896, "GFX/PICS/SETUP896.LBM"},
231+
};
232+
for(const auto& f : files)
220233
{
221-
std::cout << "failure";
222-
// if it doesn't exist, it's probably settlers2+missioncd and we simply load SETUP896.LBM instead
223-
std::cout << "\nLoading file: GFX/PICS/SETUP896.LBM instead...";
224-
if(!CFile::open_file(global::gameDataFilePath / "GFX/PICS/SETUP896.LBM", LBM))
234+
std::cout << "\nLoading file: " << f.path << "...";
235+
if(!global::loadArchive(f.id, global::gameDataFilePath / f.path, nullptr))
225236
{
226237
std::cout << "failure";
227238
return false;
228239
}
229240
}
230241
}
231242

232-
for(const std::string file :
233-
{"GFX/PICS/SETUP899.LBM", "GFX/PICS/SETUP990.LBM", "GFX/PICS/WORLD.LBM", "GFX/PICS/WORLDMSK.LBM"})
234-
{
235-
std::cout << "\nLoading file: " << file << "...";
236-
if(!CFile::open_file(global::gameDataFilePath / file, LBM))
243+
{ // batch 3: SETUP897-898 with fallback to SETUP896
244+
const struct
237245
{
238-
std::cout << "failure";
239-
return false;
246+
ArchiveID id;
247+
const char* path;
248+
} files[] = {
249+
{ArchiveID::SETUP897, "GFX/PICS/SETUP897.LBM"},
250+
{ArchiveID::SETUP898, "GFX/PICS/SETUP898.LBM"},
251+
};
252+
for(const auto& f : files)
253+
{
254+
std::cout << "\nLoading file: " << f.path << "...";
255+
if(!global::loadArchive(f.id, global::gameDataFilePath / f.path, nullptr))
256+
{
257+
std::cout << "failure";
258+
std::cout << "\nLoading file: GFX/PICS/SETUP896.LBM instead...";
259+
if(!global::loadArchive(f.id, global::gameDataFilePath / "GFX/PICS/SETUP896.LBM", nullptr))
260+
{
261+
std::cout << "failure";
262+
return false;
263+
}
264+
}
240265
}
241266
}
242267

243-
// load gouraud data
244-
for(const std::string file : {"DATA/TEXTURES/GOU5.DAT", "DATA/TEXTURES/GOU6.DAT", "DATA/TEXTURES/GOU7.DAT"})
245-
{
246-
std::cout << "\nLoading file: " << file << "...";
247-
if(!CFile::open_file(global::gameDataFilePath / file, GOU))
268+
{ // batch 4: remaining loading screens
269+
const struct
248270
{
249-
std::cout << "failure";
250-
return false;
271+
ArchiveID id;
272+
const char* path;
273+
} files[] = {
274+
{ArchiveID::SETUP899, "GFX/PICS/SETUP899.LBM"},
275+
{ArchiveID::SETUP990, "GFX/PICS/SETUP990.LBM"},
276+
{ArchiveID::WORLD_LBM, "GFX/PICS/WORLD.LBM"},
277+
{ArchiveID::WORLDMSK_LBM, "GFX/PICS/WORLDMSK.LBM"},
278+
};
279+
for(const auto& f : files)
280+
{
281+
std::cout << "\nLoading file: " << f.path << "...";
282+
if(!global::loadArchive(f.id, global::gameDataFilePath / f.path, nullptr))
283+
{
284+
std::cout << "failure";
285+
return false;
286+
}
251287
}
252288
}
253289

254-
// load only the palette at this time from editres.idx
255-
std::cout << "\nLoading palette from file: DATA/EDITRES.IDX...";
256-
if(!CFile::open_file(global::gameDataFilePath / "DATA/EDITRES.IDX", IDX, true))
290+
// Load the default palette first so all subsequent loads have it available
291+
std::cout << "\nLoading default palette from file: GFX/PALETTE/PAL5.BBM...";
292+
if(!global::loadPalette(global::gameDataFilePath / "GFX/PALETTE/PAL5.BBM"))
257293
{
258294
std::cout << "failure";
259295
return false;
260296
}
261-
// set the right palette
262-
CFile::set_palActual(CFile::get_palArray() - 1);
263-
std::cout << "\nLoading file: DATA/EDITRES.IDX...";
264-
if(!CFile::open_file(global::gameDataFilePath / "DATA/EDITRES.IDX", IDX))
265-
{
266-
std::cout << "failure";
267-
return false;
268-
}
269-
// set back palette
270-
CFile::set_palActual(CFile::get_palArray());
271-
// load only the palette at this time from editio.idx
272-
std::cout << "\nLoading palette from file: DATA/IO/EDITIO.IDX...";
273-
if(!CFile::open_file(global::gameDataFilePath / "DATA/IO/EDITIO.IDX", IDX, true))
297+
298+
// Load EDITRES.IDX as a complete bundle in typedArchives
274299
{
275-
std::cout << "failure";
276-
return false;
300+
libsiedler2::Archiv editres;
301+
int ec = libsiedler2::Load(global::gameDataFilePath / "DATA/EDITRES.IDX", editres, global::currentPalette);
302+
if(ec)
303+
{
304+
std::cout << "\nError loading EDITRES.IDX: " << libsiedler2::getErrorString(ec) << std::endl;
305+
return false;
306+
}
307+
// The palette in EDITRES (item 1) may override the default
308+
auto* pal = dynamic_cast<libsiedler2::ArchivItem_Palette*>(editres.get(1));
309+
if(pal)
310+
global::currentPalette = pal;
311+
// Store the complete Archiv in typedArchives — fonts stay inside for CFont to read directly
312+
// Indices match file positions: 0=Font, 1=Palette, 2=Font, 3=Font, 4-56=Bitmaps
313+
global::typedArchives[ArchiveID::EDITRES] = std::move(editres);
277314
}
278-
// set the right palette
279-
CFile::set_palActual(CFile::get_palArray() - 1);
315+
280316
std::cout << "\nLoading file: DATA/IO/EDITIO.IDX...";
281-
if(!CFile::open_file(global::gameDataFilePath / "DATA/IO/EDITIO.IDX", IDX))
317+
if(!global::loadArchive(ArchiveID::EDITIO, global::gameDataFilePath / "DATA/IO/EDITIO.IDX", global::currentPalette))
282318
{
283319
std::cout << "failure";
284320
return false;
285321
}
286-
// set back palette
287-
CFile::set_palActual(CFile::get_palArray());
322+
std::cout << "done";
323+
288324
std::cout << "\nLoading file: DATA/EDITBOB.LST...";
289-
if(!CFile::open_file(global::gameDataFilePath / "DATA/EDITBOB.LST", LST))
325+
if(!global::loadArchive(ArchiveID::EDITBOB, global::gameDataFilePath / "DATA/EDITBOB.LST", global::currentPalette))
290326
{
291327
std::cout << "failure";
292328
return false;
293329
}
330+
std::cout << "done";
294331

295332
// texture tilesets
296-
for(const std::string file : {"GFX/TEXTURES/TEX5.LBM", "GFX/TEXTURES/TEX6.LBM", "GFX/TEXTURES/TEX7.LBM"})
333+
const ArchiveID texArchives[3] = {ArchiveID::TEX5, ArchiveID::TEX6, ArchiveID::TEX7};
334+
const std::string texFiles[3] = {"GFX/TEXTURES/TEX5.LBM", "GFX/TEXTURES/TEX6.LBM", "GFX/TEXTURES/TEX7.LBM"};
335+
for(unsigned ti = 0; ti < 3; ti++)
297336
{
298-
std::cout << "\nLoading file: " << file << "...";
299-
if(!CFile::open_file(global::gameDataFilePath / file, LBM))
337+
std::cout << "\nLoading file: " << texFiles[ti] << "...";
338+
if(!global::loadTileset(texArchives[ti], ti, global::gameDataFilePath / texFiles[ti]))
300339
{
301340
std::cout << "failure";
302341
return false;
303342
}
343+
std::cout << "done";
304344
}
305345

306346
/*
@@ -313,11 +353,14 @@ bool CGame::Init()
313353
*/
314354

315355
// EVERY MISSION-FILE SHOULD BE LOADED SEPARATLY IF THE SPECIFIED MISSION GOES ON -- SO THIS IS TEMPORARY
316-
for(const std::string file : {"DATA/MIS0BOBS.LST", "DATA/MIS1BOBS.LST", "DATA/MIS2BOBS.LST", "DATA/MIS3BOBS.LST",
317-
"DATA/MIS4BOBS.LST", "DATA/MIS5BOBS.LST"})
356+
const ArchiveID misArchives[] = {ArchiveID::MIS0BOBS, ArchiveID::MIS1BOBS, ArchiveID::MIS2BOBS,
357+
ArchiveID::MIS3BOBS, ArchiveID::MIS4BOBS, ArchiveID::MIS5BOBS};
358+
const std::string misFiles[] = {"DATA/MIS0BOBS.LST", "DATA/MIS1BOBS.LST", "DATA/MIS2BOBS.LST",
359+
"DATA/MIS3BOBS.LST", "DATA/MIS4BOBS.LST", "DATA/MIS5BOBS.LST"};
360+
for(unsigned mi = 0; mi < 6; mi++)
318361
{
319-
std::cout << "\nLoading file: " << file << "...";
320-
if(!CFile::open_file(global::gameDataFilePath / file, LST))
362+
std::cout << "\nLoading file: " << misFiles[mi] << "...";
363+
if(!global::loadArchive(misArchives[mi], global::gameDataFilePath / misFiles[mi], global::currentPalette))
321364
{
322365
std::cout << "failure";
323366
return false;
@@ -327,10 +370,14 @@ bool CGame::Init()
327370
// create the mainmenu
328371
callback::mainmenu(INITIALIZING_CALL);
329372

330-
// Create textures for cursor
331-
cursor_.load(global::bmpArray[CURSOR].surface.get());
332-
cursorClicked_.load(global::bmpArray[CURSOR_CLICKED].surface.get());
333-
cross_.load(global::bmpArray[CROSS].surface.get());
373+
// Create textures for cursor (from typed archive)
374+
auto& resArchiv = global::typedArchives[ArchiveID::EDITRES];
375+
if(auto* bmp = dynamic_cast<const libsiedler2::baseArchivItem_Bitmap*>(resArchiv.get(CURSOR)))
376+
cursor_.load(*bmp);
377+
if(auto* bmp = dynamic_cast<const libsiedler2::baseArchivItem_Bitmap*>(resArchiv.get(CURSOR_CLICKED)))
378+
cursorClicked_.load(*bmp);
379+
if(auto* bmp = dynamic_cast<const libsiedler2::baseArchivItem_Bitmap*>(resArchiv.get(CROSS)))
380+
cross_.load(*bmp);
334381

335382
return true;
336383
}

CGame_Render.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,12 @@ void CGame::Render()
7878
std::array<char, 100> textBuffer;
7979
// text for x and y of vertex (shown in upper left corner)
8080
std::snprintf(textBuffer.data(), textBuffer.size(), "%d %d", MapObj->getVertexX(), MapObj->getVertexY());
81-
CFont::draw(textBuffer.data(), Position(20, 20), FontSize::Medium);
81+
CFont::draw(textBuffer.data(), Position(20, 20));
8282
// text for MinReduceHeight and MaxRaiseHeight
8383
std::snprintf(textBuffer.data(), textBuffer.size(),
8484
"min. height: %#04x/0x3C max. height: %#04x/0x3C NormalNull: 0x0A",
8585
MapObj->getMinReduceHeight(), MapObj->getMaxRaiseHeight());
86-
CFont::draw(textBuffer.data(), Position(100, 20), FontSize::Medium);
86+
CFont::draw(textBuffer.data(), Position(100, 20));
8787
// text for MovementLocked
8888
if(MapObj->isHorizontalMovementLocked() && MapObj->isVerticalMovementLocked())
8989
CFont::draw("Movement locked (F9 or F10 to unlock)", Position(20, 40), FontSize::Large, FontColor::Orange);

CIO/CButton.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ void CButton::draw(Position parentOrigin) const
134134
// 4. Draw picture or text centered inside the button
135135
if(button_picture >= 0)
136136
{
137-
auto& picTex = getBmpTexture(button_picture);
137+
auto& picTex = getTexture(ArchiveID::EDITIO, button_picture);
138138
const Position picPos = absPos + size_ / 2 - Position(picTex.getSize()) / 2;
139139
picTex.draw(picPos);
140140
} else if(button_text)

0 commit comments

Comments
 (0)