mirror of
https://github.com/TerryCavanagh/VVVVVV.git
synced 2024-12-22 17:49:43 +01:00
Do not close game if custom level has assets issues
It's quite rude to close the game entirely if there is trouble with assets. Instead, just unload the assets and gracefully return to the title screen.
This commit is contained in:
parent
ed9cb4ca6d
commit
8dc5d69ef3
12 changed files with 118 additions and 46 deletions
|
@ -473,7 +473,9 @@ void FILESYSTEM_loadZip(const char* filename)
|
|||
}
|
||||
}
|
||||
|
||||
void FILESYSTEM_mountAssets(const char* path)
|
||||
void FILESYSTEM_unmountAssets(void);
|
||||
|
||||
bool FILESYSTEM_mountAssets(const char* path)
|
||||
{
|
||||
char filename[MAX_PATH];
|
||||
char zip_data[MAX_PATH];
|
||||
|
@ -504,10 +506,10 @@ void FILESYSTEM_mountAssets(const char* path)
|
|||
|
||||
if (!FILESYSTEM_mountAssetsFrom(zip_data))
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
graphics.reloadresources();
|
||||
MAYBE_FAIL(graphics.reloadresources());
|
||||
}
|
||||
else if (zip_normal != NULL && endsWith(zip_normal, ".zip"))
|
||||
{
|
||||
|
@ -515,10 +517,10 @@ void FILESYSTEM_mountAssets(const char* path)
|
|||
|
||||
if (!FILESYSTEM_mountAssetsFrom(zip_normal))
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
graphics.reloadresources();
|
||||
MAYBE_FAIL(graphics.reloadresources());
|
||||
}
|
||||
else if (FILESYSTEM_exists(dir))
|
||||
{
|
||||
|
@ -526,15 +528,21 @@ void FILESYSTEM_mountAssets(const char* path)
|
|||
|
||||
if (!FILESYSTEM_mountAssetsFrom(dir))
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
graphics.reloadresources();
|
||||
MAYBE_FAIL(graphics.reloadresources());
|
||||
}
|
||||
else
|
||||
{
|
||||
puts("Custom asset directory does not exist");
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
fail:
|
||||
FILESYSTEM_unmountAssets();
|
||||
return false;
|
||||
}
|
||||
|
||||
void FILESYSTEM_unmountAssets(void)
|
||||
|
|
|
@ -19,7 +19,7 @@ bool FILESYSTEM_isFile(const char* filename);
|
|||
bool FILESYSTEM_isMounted(const char* filename);
|
||||
|
||||
void FILESYSTEM_loadZip(const char* filename);
|
||||
void FILESYSTEM_mountAssets(const char *path);
|
||||
bool FILESYSTEM_mountAssets(const char *path);
|
||||
void FILESYSTEM_unmountAssets(void);
|
||||
bool FILESYSTEM_isAssetMounted(const char* filename);
|
||||
|
||||
|
|
|
@ -6477,6 +6477,9 @@ void Game::createmenu( enum Menu::MenuName t, bool samemenu/*= false*/ )
|
|||
option("silence");
|
||||
menuyoff = 10;
|
||||
break;
|
||||
case Menu::errorloadinglevel:
|
||||
option("ok");
|
||||
break;
|
||||
}
|
||||
|
||||
// Automatically center the menu. We must check the width of the menu with the initial horizontal spacing.
|
||||
|
|
|
@ -35,6 +35,7 @@ namespace Menu
|
|||
youwannaquit,
|
||||
errornostart,
|
||||
errorsavingsettings,
|
||||
errorloadinglevel,
|
||||
graphicoptions,
|
||||
ed_settings,
|
||||
ed_desc,
|
||||
|
|
|
@ -151,6 +151,9 @@ void Graphics::init(void)
|
|||
tiles2_mounted = false;
|
||||
minimap_mounted = false;
|
||||
#endif
|
||||
|
||||
SDL_zeroa(error);
|
||||
SDL_zeroa(error_title);
|
||||
}
|
||||
|
||||
void Graphics::destroy(void)
|
||||
|
@ -314,24 +317,15 @@ void Graphics::updatetitlecolours(void)
|
|||
else if (grphx.im_##tilesheet->w % tile_square != 0 \
|
||||
|| grphx.im_##tilesheet->h % tile_square != 0) \
|
||||
{ \
|
||||
const char* error = "Error: %s.png dimensions not exact multiples of %i!"; \
|
||||
char message[128]; \
|
||||
const char* error_title = "Error with %s.png"; \
|
||||
char message_title[128]; \
|
||||
static const char error_fmt[] = "%s.png dimensions not exact multiples of %i!"; \
|
||||
static const char error_title_fmt[] = "Error with %s.png"; \
|
||||
\
|
||||
SDL_snprintf(message, sizeof(message), error, #tilesheet, tile_square); \
|
||||
SDL_snprintf(message_title, sizeof(message_title), error_title, #tilesheet); \
|
||||
SDL_snprintf(error, sizeof(error), error_fmt, #tilesheet, tile_square); \
|
||||
SDL_snprintf(error_title, sizeof(error_title), error_title_fmt, #tilesheet); \
|
||||
\
|
||||
puts(message); \
|
||||
puts(error); \
|
||||
\
|
||||
SDL_ShowSimpleMessageBox( \
|
||||
SDL_MESSAGEBOX_ERROR, \
|
||||
message_title, \
|
||||
message, \
|
||||
NULL \
|
||||
); \
|
||||
\
|
||||
VVV_exit(1); \
|
||||
return false; \
|
||||
}
|
||||
|
||||
#define PROCESS_TILESHEET_RENAME(tilesheet, vector, tile_square, extra_code) \
|
||||
|
@ -363,7 +357,7 @@ void Graphics::updatetitlecolours(void)
|
|||
#define PROCESS_TILESHEET(tilesheet, tile_square, extra_code) \
|
||||
PROCESS_TILESHEET_RENAME(tilesheet, tilesheet, tile_square, extra_code)
|
||||
|
||||
void Graphics::Makebfont(void)
|
||||
bool Graphics::Makebfont(void)
|
||||
{
|
||||
PROCESS_TILESHEET(bfont, 8,
|
||||
{
|
||||
|
@ -391,6 +385,8 @@ void Graphics::Makebfont(void)
|
|||
{
|
||||
font_positions.clear();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int Graphics::bfontlen(uint32_t ch)
|
||||
|
@ -405,23 +401,29 @@ int Graphics::bfontlen(uint32_t ch)
|
|||
}
|
||||
}
|
||||
|
||||
void Graphics::MakeTileArray(void)
|
||||
bool Graphics::MakeTileArray(void)
|
||||
{
|
||||
PROCESS_TILESHEET(tiles, 8, {})
|
||||
PROCESS_TILESHEET(tiles2, 8, {})
|
||||
PROCESS_TILESHEET(tiles3, 8, {})
|
||||
PROCESS_TILESHEET(entcolours, 8, {})
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Graphics::maketelearray(void)
|
||||
bool Graphics::maketelearray(void)
|
||||
{
|
||||
PROCESS_TILESHEET_RENAME(teleporter, tele, 96, {})
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Graphics::MakeSpriteArray(void)
|
||||
bool Graphics::MakeSpriteArray(void)
|
||||
{
|
||||
PROCESS_TILESHEET(sprites, 32, {})
|
||||
PROCESS_TILESHEET(flipsprites, 32, {})
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#undef PROCESS_TILESHEET
|
||||
|
@ -3486,17 +3488,17 @@ bool Graphics::onscreen(int t)
|
|||
return (t >= -40 && t <= 280);
|
||||
}
|
||||
|
||||
void Graphics::reloadresources(void)
|
||||
bool Graphics::reloadresources(void)
|
||||
{
|
||||
grphx.destroy();
|
||||
grphx.init();
|
||||
|
||||
destroy();
|
||||
|
||||
MakeTileArray();
|
||||
MakeSpriteArray();
|
||||
maketelearray();
|
||||
Makebfont();
|
||||
MAYBE_FAIL(MakeTileArray());
|
||||
MAYBE_FAIL(MakeSpriteArray());
|
||||
MAYBE_FAIL(maketelearray());
|
||||
MAYBE_FAIL(Makebfont());
|
||||
|
||||
images.clear();
|
||||
|
||||
|
@ -3528,6 +3530,11 @@ void Graphics::reloadresources(void)
|
|||
tiles2_mounted = FILESYSTEM_isAssetMounted("graphics/tiles2.png");
|
||||
minimap_mounted = FILESYSTEM_isAssetMounted("graphics/minimap.png");
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
||||
fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
Uint32 Graphics::crewcolourreal(int t)
|
||||
|
|
|
@ -26,7 +26,7 @@ public:
|
|||
int bfontlen(uint32_t ch);
|
||||
int font_idx(uint32_t ch);
|
||||
|
||||
void Makebfont(void);
|
||||
bool Makebfont(void);
|
||||
|
||||
void drawhuetile(int x, int y, int t);
|
||||
void huetilesetcol(int t);
|
||||
|
@ -34,11 +34,11 @@ public:
|
|||
|
||||
void drawgravityline(int t);
|
||||
|
||||
void MakeTileArray(void);
|
||||
bool MakeTileArray(void);
|
||||
|
||||
void MakeSpriteArray(void);
|
||||
bool MakeSpriteArray(void);
|
||||
|
||||
void maketelearray(void);
|
||||
bool maketelearray(void);
|
||||
|
||||
void drawcoloredtile(int x, int y, int t, int r, int g, int b);
|
||||
|
||||
|
@ -222,7 +222,7 @@ public:
|
|||
|
||||
bool onscreen(int t);
|
||||
|
||||
void reloadresources(void);
|
||||
bool reloadresources(void);
|
||||
#ifndef NO_CUSTOM_LEVELS
|
||||
bool tiles1_mounted;
|
||||
bool tiles2_mounted;
|
||||
|
@ -357,6 +357,9 @@ public:
|
|||
bool kludgeswnlinewidth;
|
||||
|
||||
Uint32 crewcolourreal(int t);
|
||||
|
||||
char error[128];
|
||||
char error_title[128]; /* for SDL_ShowSimpleMessageBox */
|
||||
};
|
||||
|
||||
#ifndef GRAPHICS_DEFINITION
|
||||
|
|
|
@ -1727,6 +1727,11 @@ static void menuactionpress(void)
|
|||
game.returnmenu();
|
||||
map.nexttowercolour();
|
||||
break;
|
||||
case Menu::errorloadinglevel:
|
||||
music.playef(11);
|
||||
game.returnmenu();
|
||||
map.nexttowercolour();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1387,6 +1387,10 @@ static void menurender(void)
|
|||
case Menu::errorsavingsettings:
|
||||
graphics.Print( -1, 95, "ERROR: Could not save settings file!", tr, tg, tb, true);
|
||||
break;
|
||||
case Menu::errorloadinglevel:
|
||||
graphics.bigprint(-1, 45, "ERROR", tr, tg, tb, true);
|
||||
graphics.PrintWrap(-1, 65, graphics.error, tr, tg, tb, true, 10, 304);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -2634,6 +2634,14 @@ void scriptclass::resetgametomenu(void)
|
|||
game.createmenu(Menu::gameover);
|
||||
}
|
||||
|
||||
static void gotoerrorloadinglevel(void)
|
||||
{
|
||||
game.createmenu(Menu::errorloadinglevel);
|
||||
graphics.fademode = 4; /* start fade in */
|
||||
music.currentsong = -1; /* otherwise music.play won't work */
|
||||
music.play(6); /* title screen music */
|
||||
}
|
||||
|
||||
void scriptclass::startgamemode( int t )
|
||||
{
|
||||
switch(t)
|
||||
|
@ -3152,7 +3160,11 @@ void scriptclass::startgamemode( int t )
|
|||
//Initilise the level
|
||||
//First up, find the start point
|
||||
std::string filename = std::string(ed.ListOfMetaData[game.playcustomlevel].filename);
|
||||
ed.load(filename);
|
||||
if (!ed.load(filename))
|
||||
{
|
||||
gotoerrorloadinglevel();
|
||||
break;
|
||||
}
|
||||
ed.findstartpoint();
|
||||
|
||||
game.gamestate = GAMEMODE;
|
||||
|
@ -3190,7 +3202,11 @@ void scriptclass::startgamemode( int t )
|
|||
//Initilise the level
|
||||
//First up, find the start point
|
||||
std::string filename = std::string(ed.ListOfMetaData[game.playcustomlevel].filename);
|
||||
ed.load(filename);
|
||||
if (!ed.load(filename))
|
||||
{
|
||||
gotoerrorloadinglevel();
|
||||
break;
|
||||
}
|
||||
ed.findstartpoint();
|
||||
|
||||
game.gamestate = GAMEMODE;
|
||||
|
|
|
@ -78,6 +78,15 @@ void _VVV_between(
|
|||
# define VVV_fallthrough do { } while (false) /* fallthrough */
|
||||
#endif
|
||||
|
||||
#define MAYBE_FAIL(expr) \
|
||||
do \
|
||||
{ \
|
||||
if (!expr) \
|
||||
{ \
|
||||
goto fail; \
|
||||
} \
|
||||
} \
|
||||
while (false)
|
||||
|
||||
//helperClass
|
||||
class UtilityClass
|
||||
|
|
|
@ -1748,6 +1748,11 @@ void editorclass::switch_enemy(const bool reversed /*= false*/)
|
|||
|
||||
bool editorclass::load(std::string& _path)
|
||||
{
|
||||
tinyxml2::XMLDocument doc;
|
||||
tinyxml2::XMLHandle hDoc(&doc);
|
||||
tinyxml2::XMLElement* pElem;
|
||||
tinyxml2::XMLHandle hRoot(NULL);
|
||||
|
||||
reset();
|
||||
|
||||
static const char *levelDir = "levels/";
|
||||
|
@ -1759,14 +1764,13 @@ bool editorclass::load(std::string& _path)
|
|||
FILESYSTEM_unmountAssets();
|
||||
if (game.cliplaytest && game.playassets != "")
|
||||
{
|
||||
FILESYSTEM_mountAssets(game.playassets.c_str());
|
||||
MAYBE_FAIL(FILESYSTEM_mountAssets(game.playassets.c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
FILESYSTEM_mountAssets(_path.c_str());
|
||||
MAYBE_FAIL(FILESYSTEM_mountAssets(_path.c_str()));
|
||||
}
|
||||
|
||||
tinyxml2::XMLDocument doc;
|
||||
if (!FILESYSTEM_loadTiXml2Document(_path.c_str(), doc))
|
||||
{
|
||||
printf("No level %s to load :(\n", _path.c_str());
|
||||
|
@ -1775,9 +1779,6 @@ bool editorclass::load(std::string& _path)
|
|||
|
||||
loaded_filepath = _path;
|
||||
|
||||
tinyxml2::XMLHandle hDoc(&doc);
|
||||
tinyxml2::XMLElement* pElem;
|
||||
tinyxml2::XMLHandle hRoot(NULL);
|
||||
version = 0;
|
||||
|
||||
{
|
||||
|
@ -2040,6 +2041,9 @@ next:
|
|||
version=2;
|
||||
|
||||
return true;
|
||||
|
||||
fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool editorclass::save(std::string& _path)
|
||||
|
|
|
@ -483,7 +483,19 @@ int main(int argc, char *argv[])
|
|||
game.init();
|
||||
|
||||
// This loads music too...
|
||||
graphics.reloadresources();
|
||||
if (!graphics.reloadresources())
|
||||
{
|
||||
/* Something wrong with the default assets? We can't use them to
|
||||
* display the error message, and we have to bail. */
|
||||
SDL_ShowSimpleMessageBox(
|
||||
SDL_MESSAGEBOX_ERROR,
|
||||
graphics.error_title,
|
||||
graphics.error,
|
||||
NULL
|
||||
);
|
||||
|
||||
VVV_exit(1);
|
||||
}
|
||||
|
||||
game.gamestate = PRELOADER;
|
||||
|
||||
|
|
Loading…
Reference in a new issue