mirror of
https://github.com/cxong/cdogs-sdl.git
synced 2025-07-23 07:23:01 +02:00
Draw tiles for loading screen #325
This commit is contained in:
@@ -26,6 +26,7 @@ set(CDOGS_SDL_SOURCES
|
||||
game.c
|
||||
game_loop.c
|
||||
hiscores.c
|
||||
loading_screens.c
|
||||
mainmenu.c
|
||||
menu.c
|
||||
menu_utils.c
|
||||
@@ -45,6 +46,7 @@ set(CDOGS_SDL_HEADERS
|
||||
game.h
|
||||
game_loop.h
|
||||
hiscores.h
|
||||
loading_screens.h
|
||||
mainmenu.h
|
||||
menu.h
|
||||
menu_utils.h
|
||||
|
35
src/cdogs.c
35
src/cdogs.c
@@ -22,7 +22,7 @@
|
||||
This file incorporates work covered by the following copyright and
|
||||
permission notice:
|
||||
|
||||
Copyright (c) 2013-2017, 2019-2021 Cong Xu
|
||||
Copyright (c) 2013-2017, 2019-2022 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -87,6 +87,7 @@
|
||||
#include "briefing_screens.h"
|
||||
#include "command_line.h"
|
||||
#include "credits.h"
|
||||
#include "loading_screens.h"
|
||||
#include "mainmenu.h"
|
||||
#include "prep.h"
|
||||
|
||||
@@ -182,20 +183,21 @@ int main(int argc, char *argv[])
|
||||
goto bail;
|
||||
}
|
||||
FontLoadFromJSON(&gFont, "graphics/font.png", "graphics/font.json");
|
||||
DrawGameLoadingScreen(&gGraphicsDevice, "Loading graphics...");
|
||||
LoadingScreenInit(&gLoadingScreen, &gGraphicsDevice);
|
||||
LoadingScreenDraw(&gLoadingScreen, "Loading graphics...");
|
||||
PicManagerLoad(&gPicManager);
|
||||
|
||||
GetDataFilePath(buf, "");
|
||||
LOG(LM_MAIN, LL_INFO, "data dir(%s)", buf);
|
||||
LOG(LM_MAIN, LL_INFO, "config dir(%s)", GetConfigFilePath(""));
|
||||
|
||||
DrawGameLoadingScreen(&gGraphicsDevice, "Loading autosaves...");
|
||||
LoadingScreenDraw(&gLoadingScreen, "Loading autosaves...");
|
||||
AutosaveInit(&gAutosave);
|
||||
#ifndef __EMSCRIPTEN__
|
||||
AutosaveLoad(&gAutosave, GetConfigFilePath(AUTOSAVE_FILE));
|
||||
#endif
|
||||
|
||||
DrawGameLoadingScreen(&gGraphicsDevice, "Initializing network client...");
|
||||
LoadingScreenDraw(&gLoadingScreen, "Initializing network client...");
|
||||
#ifndef __EMSCRIPTEN__
|
||||
if (enet_initialize() != 0)
|
||||
{
|
||||
@@ -206,7 +208,7 @@ int main(int argc, char *argv[])
|
||||
NetClientInit(&gNetClient);
|
||||
#endif
|
||||
|
||||
DrawGameLoadingScreen(&gGraphicsDevice, "Initializing sound device...");
|
||||
LoadingScreenDraw(&gLoadingScreen, "Initializing sound device...");
|
||||
SoundInitialize(&gSoundDevice, "sounds");
|
||||
if (!gSoundDevice.isInitialised)
|
||||
{
|
||||
@@ -216,36 +218,35 @@ int main(int argc, char *argv[])
|
||||
EventInit(&gEventHandlers);
|
||||
gEventHandlers.DemoQuitTimer = demoQuitTimer;
|
||||
NetServerInit(&gNetServer);
|
||||
TileClassesInit(&gTileClasses);
|
||||
DrawGameLoadingScreen(&gGraphicsDevice, "Loading character sprites...");
|
||||
LoadingScreenDraw(&gLoadingScreen, "Loading character sprites...");
|
||||
CharSpriteClassesInit(&gCharSpriteClasses);
|
||||
|
||||
DrawGameLoadingScreen(&gGraphicsDevice, "Loading particles...");
|
||||
LoadingScreenDraw(&gLoadingScreen, "Loading particles...");
|
||||
ParticleClassesInit(&gParticleClasses, "data/particles.json");
|
||||
DrawGameLoadingScreen(&gGraphicsDevice, "Loading ammo...");
|
||||
LoadingScreenDraw(&gLoadingScreen, "Loading ammo...");
|
||||
AmmoInitialize(&gAmmo, "data/ammo.json");
|
||||
DrawGameLoadingScreen(&gGraphicsDevice, "Loading bullets and weapons...");
|
||||
LoadingScreenDraw(&gLoadingScreen, "Loading bullets and weapons...");
|
||||
BulletAndWeaponInitialize(
|
||||
&gBulletClasses, &gWeaponClasses, "data/bullets.json",
|
||||
"data/guns.json");
|
||||
DrawGameLoadingScreen(&gGraphicsDevice, "Loading character classes...");
|
||||
LoadingScreenDraw(&gLoadingScreen, "Loading character classes...");
|
||||
CharacterClassesInitialize(
|
||||
&gCharacterClasses, "data/character_classes.json");
|
||||
#ifndef __EMSCRIPTEN__
|
||||
DrawGameLoadingScreen(&gGraphicsDevice, "Loading player templates...");
|
||||
LoadingScreenDraw(&gLoadingScreen, "Loading player templates...");
|
||||
PlayerTemplatesLoad(&gPlayerTemplates, &gCharacterClasses);
|
||||
#endif
|
||||
DrawGameLoadingScreen(&gGraphicsDevice, "Loading pickups...");
|
||||
LoadingScreenDraw(&gLoadingScreen, "Loading pickups...");
|
||||
PickupClassesInit(
|
||||
&gPickupClasses, "data/pickups.json", &gAmmo, &gWeaponClasses);
|
||||
DrawGameLoadingScreen(&gGraphicsDevice, "Loading map objects...");
|
||||
LoadingScreenDraw(&gLoadingScreen, "Loading map objects...");
|
||||
MapObjectsInit(
|
||||
&gMapObjects, "data/map_objects.json", &gAmmo, &gWeaponClasses);
|
||||
CollisionSystemInit(&gCollisionSystem);
|
||||
CampaignInit(&gCampaign);
|
||||
PlayerDataInit(&gPlayerDatas);
|
||||
|
||||
DrawGameLoadingScreen(&gGraphicsDevice, "Loading main menu...");
|
||||
LoadingScreenDraw(&gLoadingScreen, "Loading main menu...");
|
||||
LoopRunner l = LoopRunnerNew(NULL);
|
||||
LoopRunnerPush(&l, MainMenu(&gGraphicsDevice, &l));
|
||||
if (connectAddr.host != 0)
|
||||
@@ -293,6 +294,8 @@ int main(int argc, char *argv[])
|
||||
LoopRunnerTerminate(&l);
|
||||
|
||||
bail:
|
||||
LoadingScreenReload(&gLoadingScreen);
|
||||
LoadingScreenDraw(&gLoadingScreen, "Quitting...");
|
||||
NetServerTerminate(&gNetServer);
|
||||
PlayerDataTerminate(&gPlayerDatas);
|
||||
MapObjectsTerminate(&gMapObjects);
|
||||
@@ -311,7 +314,6 @@ bail:
|
||||
CollisionSystemTerminate(&gCollisionSystem);
|
||||
|
||||
CharSpriteClassesTerminate(&gCharSpriteClasses);
|
||||
TileClassesTerminate(&gTileClasses);
|
||||
PicManagerTerminate(&gPicManager);
|
||||
FontTerminate(&gFont);
|
||||
GraphicsTerminate(&gGraphicsDevice);
|
||||
@@ -321,6 +323,7 @@ bail:
|
||||
SoundTerminate(&gSoundDevice, true);
|
||||
ConfigDestroy(&gConfig);
|
||||
LogTerminate();
|
||||
LoadingScreenTerminate(&gLoadingScreen);
|
||||
|
||||
SDLJBN_Quit();
|
||||
SDL_Quit();
|
||||
|
@@ -418,7 +418,10 @@ static void DoBuffer(
|
||||
{
|
||||
DrawBufferFix(b);
|
||||
}
|
||||
DrawBufferDraw(b, offset, NULL);
|
||||
DrawBufferArgs args;
|
||||
memset(&args, 0, sizeof args);
|
||||
args.HUD = ConfigGetBool(&gConfig, "Graphics.ShowHUD");
|
||||
DrawBufferDraw(b, offset, &args);
|
||||
}
|
||||
|
||||
void CameraDrawMode(const Camera *camera)
|
||||
|
@@ -88,7 +88,6 @@ void CampaignSettingTerminateAll(CampaignSetting *setting)
|
||||
// Unload previous custom data
|
||||
SoundClear(gSoundDevice.customSounds);
|
||||
PicManagerClearCustom(&gPicManager);
|
||||
TileClassesClearCustom(&gTileClasses);
|
||||
ParticleClassesClear(&gParticleClasses.CustomClasses);
|
||||
AmmoClassesClear(&gAmmo.CustomAmmo);
|
||||
PlayerTemplatesClear(&gPlayerTemplates.CustomClasses);
|
||||
|
@@ -149,9 +149,9 @@ struct vec2i MapAddDoorGroup(
|
||||
char doorClassName[CDOGS_FILENAME_MAX];
|
||||
const DoorType type = GetDoorType(isHorizontal, i, doorGroupCount);
|
||||
DoorGetClassName(doorClassName, door, doorKey, type);
|
||||
const TileClass *doorClass = StrTileClass(doorClassName);
|
||||
const TileClass *doorClass = StrTileClass(mb->Map->TileClasses, doorClassName);
|
||||
DoorGetClassName(doorClassName, door, "open", type);
|
||||
const TileClass *doorClassOpen = StrTileClass(doorClassName);
|
||||
const TileClass *doorClassOpen = StrTileClass(mb->Map->TileClasses, doorClassName);
|
||||
const struct vec2i vI = svec2i_add(v, svec2i_scale(dv, (float)i));
|
||||
Tile *tile = MapGetTile(mb->Map, vI);
|
||||
tile->Door.Class = doorClass;
|
||||
@@ -168,6 +168,7 @@ struct vec2i MapAddDoorGroup(
|
||||
{
|
||||
// Change the tile below to shadow, cast by this door
|
||||
tileB->Class = TileClassesGetMaskedTile(
|
||||
mb->Map->TileClasses,
|
||||
tileB->Class, tileB->Class->Style, "shadow",
|
||||
tileB->Class->Mask, tileB->Class->MaskAlt);
|
||||
}
|
||||
@@ -177,7 +178,7 @@ struct vec2i MapAddDoorGroup(
|
||||
{
|
||||
// special door cavity picture
|
||||
DoorGetClassName(doorClassName, door, "wall", type);
|
||||
tile->Door.Class2 = StrTileClass(doorClassName);
|
||||
tile->Door.Class2 = StrTileClass(mb->Map->TileClasses, doorClassName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -493,7 +494,7 @@ static void DoorGetClassName(
|
||||
TileClassGetName(buf, door, door->Style, type, mask, maskAlt);
|
||||
}
|
||||
void DoorAddClass(
|
||||
TileClasses *c, PicManager *pm, const TileClass *base, const char *key,
|
||||
map_t c, PicManager *pm, const TileClass *base, const char *key,
|
||||
const DoorType type)
|
||||
{
|
||||
char buf[CDOGS_FILENAME_MAX];
|
||||
|
@@ -68,7 +68,7 @@ struct vec2i MapAddDoorGroup(
|
||||
MapBuilder *mb, const struct vec2i v, const int keyFlags);
|
||||
|
||||
void DoorAddClass(
|
||||
TileClasses *c, PicManager *pm, const TileClass *base, const char *key,
|
||||
map_t c, PicManager *pm, const TileClass *base, const char *key,
|
||||
const DoorType type);
|
||||
|
||||
// Legacy door style int to str
|
||||
|
@@ -170,9 +170,9 @@ static void DrawChatters(
|
||||
DrawBuffer *b, const struct vec2i offset, const Tile *t,
|
||||
const struct vec2i pos, const bool useFog);
|
||||
static void DrawExtra(
|
||||
DrawBuffer *b, struct vec2i offset, GrafxDrawExtra *extra);
|
||||
DrawBuffer *b, struct vec2i offset, const DrawBufferArgs *args);
|
||||
|
||||
void DrawBufferDraw(DrawBuffer *b, struct vec2i offset, GrafxDrawExtra *extra)
|
||||
void DrawBufferDraw(DrawBuffer *b, struct vec2i offset, const DrawBufferArgs *args)
|
||||
{
|
||||
// First draw the floor tiles (which do not obstruct anything)
|
||||
DrawTiles(b, offset, DrawFloor);
|
||||
@@ -182,7 +182,7 @@ void DrawBufferDraw(DrawBuffer *b, struct vec2i offset, GrafxDrawExtra *extra)
|
||||
DrawTiles(b, offset, DrawWallsAndThings);
|
||||
// Draw things that are above everything
|
||||
DrawTiles(b, offset, DrawThingsAbove);
|
||||
if (ConfigGetBool(&gConfig, "Graphics.ShowHUD"))
|
||||
if (args->HUD)
|
||||
{
|
||||
// Draw objective highlights, for visible and always-visible objectives
|
||||
DrawTiles(b, offset, DrawObjectiveHighlights);
|
||||
@@ -190,10 +190,7 @@ void DrawBufferDraw(DrawBuffer *b, struct vec2i offset, GrafxDrawExtra *extra)
|
||||
DrawTiles(b, offset, DrawChatters);
|
||||
}
|
||||
// Draw editor-only things
|
||||
if (extra)
|
||||
{
|
||||
DrawExtra(b, offset, extra);
|
||||
}
|
||||
DrawExtra(b, offset, args);
|
||||
}
|
||||
|
||||
static void DrawFloor(
|
||||
@@ -457,17 +454,20 @@ static void DrawGuideImage(
|
||||
const DrawBuffer *b, const Pic *guideImage, const uint8_t alpha);
|
||||
static void DrawObjectNames(DrawBuffer *b, const struct vec2i offset);
|
||||
static void DrawExtra(
|
||||
DrawBuffer *b, struct vec2i offset, GrafxDrawExtra *extra)
|
||||
DrawBuffer *b, struct vec2i offset, const DrawBufferArgs *args)
|
||||
{
|
||||
// Draw guide image
|
||||
if (!PicIsNone(extra->guideImage) && extra->guideImageAlpha > 0)
|
||||
if (args->GuideImage && !PicIsNone(args->GuideImage) && args->GuideImageAlpha > 0)
|
||||
{
|
||||
DrawGuideImage(b, extra->guideImage, extra->guideImageAlpha);
|
||||
DrawGuideImage(b, args->GuideImage, args->GuideImageAlpha);
|
||||
}
|
||||
if (args->Editor)
|
||||
{
|
||||
// Draw pickups, in case they are obscured by walls
|
||||
DrawPickups(b, &gMap, offset);
|
||||
DrawEditorTiles(b, &gMap, offset);
|
||||
DrawObjectNames(b, offset);
|
||||
}
|
||||
// Draw pickups, in case they are obscured by walls
|
||||
DrawPickups(b, &gMap, offset);
|
||||
DrawEditorTiles(b, &gMap, offset);
|
||||
DrawObjectNames(b, offset);
|
||||
}
|
||||
|
||||
static void DrawPickups(
|
||||
|
@@ -48,10 +48,9 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "draw/draw_buffer.h"
|
||||
#include "gamedata.h"
|
||||
#include "grafx_bg.h"
|
||||
|
||||
#define WALL_OFFSET_Y (-12)
|
||||
|
||||
void DrawBufferDraw(DrawBuffer *b, struct vec2i offset, GrafxDrawExtra *extra);
|
||||
void DrawBufferDraw(DrawBuffer *b, struct vec2i offset, const DrawBufferArgs *args);
|
||||
|
@@ -22,7 +22,7 @@
|
||||
This file incorporates work covered by the following copyright and
|
||||
permission notice:
|
||||
|
||||
Copyright (c) 2013-2014, 2018-2019 Cong Xu
|
||||
Copyright (c) 2013-2014, 2018-2019, 2022 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -58,12 +58,7 @@
|
||||
void DrawBufferInit(DrawBuffer *b, struct vec2i size, GraphicsDevice *g)
|
||||
{
|
||||
b->OrigSize = size;
|
||||
CArrayInit(&b->tiles, sizeof(Tile *));
|
||||
for (int i = 0; i < size.x * size.y; i++)
|
||||
{
|
||||
const Tile *t = NULL;
|
||||
CArrayPushBack(&b->tiles, &t);
|
||||
}
|
||||
CArrayInitFillZero(&b->tiles, sizeof(Tile *), size.x * size.y);
|
||||
b->g = g;
|
||||
CArrayInit(&b->displaylist, sizeof(const Thing *));
|
||||
CArrayReserve(&b->displaylist, 32);
|
||||
|
@@ -44,27 +44,27 @@
|
||||
static void DrawBackgroundWithRenderer(
|
||||
GraphicsDevice *g, WindowContext *wc, SDL_Texture *target,
|
||||
SDL_Texture *src, DrawBuffer *buffer, const HSV tint,
|
||||
const struct vec2 pos, GrafxDrawExtra *extra);
|
||||
const struct vec2 pos, const DrawBufferArgs *args);
|
||||
void GrafxDrawBackground(
|
||||
GraphicsDevice *g, DrawBuffer *buffer, const HSV tint,
|
||||
const struct vec2 pos, GrafxDrawExtra *extra)
|
||||
const struct vec2 pos, const DrawBufferArgs *args)
|
||||
{
|
||||
DrawBackgroundWithRenderer(
|
||||
g, &g->gameWindow, g->bkgTgt, g->bkg, buffer, tint, pos, extra);
|
||||
g, &g->gameWindow, g->bkgTgt, g->bkg, buffer, tint, pos, args);
|
||||
if (g->cachedConfig.SecondWindow)
|
||||
{
|
||||
DrawBackgroundWithRenderer(
|
||||
g, &g->secondWindow, g->bkgTgt2, g->bkg2, buffer, tint, pos,
|
||||
extra);
|
||||
args);
|
||||
}
|
||||
}
|
||||
static void DrawBackground(
|
||||
GraphicsDevice *g, SDL_Texture *t, DrawBuffer *buffer, Map *map,
|
||||
const struct vec2 pos, GrafxDrawExtra *extra);
|
||||
const struct vec2 pos, const DrawBufferArgs *args);
|
||||
static void DrawBackgroundWithRenderer(
|
||||
GraphicsDevice *g, WindowContext *wc, SDL_Texture *target,
|
||||
SDL_Texture *src, DrawBuffer *buffer, const HSV tint,
|
||||
const struct vec2 pos, GrafxDrawExtra *extra)
|
||||
const struct vec2 pos, const DrawBufferArgs *args)
|
||||
{
|
||||
SDL_RendererInfo ri;
|
||||
if (SDL_GetRendererInfo(wc->renderer, &ri) != 0)
|
||||
@@ -84,7 +84,7 @@ static void DrawBackgroundWithRenderer(
|
||||
LOG(LM_GFX, LL_ERROR, "cannot set render target: %s", SDL_GetError());
|
||||
}
|
||||
wc->bkgMask = ColorTint(colorWhite, tint);
|
||||
DrawBackground(g, src, buffer, &gMap, pos, extra);
|
||||
DrawBackground(g, src, buffer, &gMap, pos, args);
|
||||
if (SDL_SetRenderTarget(wc->renderer, NULL) != 0)
|
||||
{
|
||||
LOG(LM_GFX, LL_ERROR, "cannot set render target: %s", SDL_GetError());
|
||||
@@ -92,11 +92,11 @@ static void DrawBackgroundWithRenderer(
|
||||
}
|
||||
static void DrawBackground(
|
||||
GraphicsDevice *g, SDL_Texture *t, DrawBuffer *buffer, Map *map,
|
||||
const struct vec2 pos, GrafxDrawExtra *extra)
|
||||
const struct vec2 pos, const DrawBufferArgs *args)
|
||||
{
|
||||
BlitClearBuf(g);
|
||||
DrawBufferSetFromMap(buffer, map, pos, X_TILES);
|
||||
DrawBufferDraw(buffer, svec2i_zero(), extra);
|
||||
DrawBufferDraw(buffer, svec2i_zero(), args);
|
||||
BlitUpdateFromBuf(g, t);
|
||||
BlitClearBuf(g);
|
||||
}
|
||||
@@ -107,18 +107,20 @@ void GrafxRedrawBackground(GraphicsDevice *g, const struct vec2 pos)
|
||||
DrawBuffer buffer;
|
||||
DrawBufferInit(&buffer, svec2i(X_TILES, Y_TILES), g);
|
||||
const HSV tint = {rand() * 360.0 / RAND_MAX, rand() * 1.0 / RAND_MAX, 0.5};
|
||||
GrafxDrawBackground(g, &buffer, tint, pos, NULL);
|
||||
DrawBufferArgs args;
|
||||
memset(&args, 0, sizeof args);
|
||||
GrafxDrawBackground(g, &buffer, tint, pos, &args);
|
||||
DrawBufferTerminate(&buffer);
|
||||
}
|
||||
|
||||
void GrafxMakeBackground(
|
||||
GraphicsDevice *device, DrawBuffer *buffer, Campaign *co,
|
||||
struct MissionOptions *mo, Map *map, HSV tint, const bool isEditor,
|
||||
struct vec2 pos, GrafxDrawExtra *extra)
|
||||
struct vec2 pos, const DrawBufferArgs *args)
|
||||
{
|
||||
CampaignAndMissionSetup(co, mo);
|
||||
GameEventsInit(&gGameEvents);
|
||||
MapBuild(map, mo->missionData, co, mo->index);
|
||||
MapBuild(map, mo->missionData, true, mo->index, GAME_MODE_NORMAL, &co->Setting.characters);
|
||||
InitializeBadGuys();
|
||||
CreateEnemies();
|
||||
MapMarkAllAsVisited(map);
|
||||
@@ -135,6 +137,6 @@ void GrafxMakeBackground(
|
||||
}
|
||||
// Process the events that place dynamic objects
|
||||
HandleGameEvents(&gGameEvents, NULL, NULL, NULL, NULL);
|
||||
GrafxDrawBackground(device, buffer, tint, pos, extra);
|
||||
GrafxDrawBackground(device, buffer, tint, pos, args);
|
||||
GameEventsTerminate(&gGameEvents);
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
C-Dogs SDL
|
||||
A port of the legendary (and fun) action/arcade cdogs.
|
||||
Copyright (c) 2013-2014, 2016-2017, 2020 Cong Xu
|
||||
Copyright (c) 2013-2014, 2016-2017, 2020, 2022 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -33,15 +33,17 @@
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const Pic *guideImage;
|
||||
uint8_t guideImageAlpha;
|
||||
} GrafxDrawExtra;
|
||||
bool Editor;
|
||||
const Pic *GuideImage;
|
||||
uint8_t GuideImageAlpha;
|
||||
bool HUD;
|
||||
} DrawBufferArgs;
|
||||
|
||||
void GrafxDrawBackground(
|
||||
GraphicsDevice *g, DrawBuffer *buffer, const HSV tint,
|
||||
const struct vec2 pos, GrafxDrawExtra *extra);
|
||||
const struct vec2 pos, const DrawBufferArgs *args);
|
||||
void GrafxRedrawBackground(GraphicsDevice *g, const struct vec2 pos);
|
||||
void GrafxMakeBackground(
|
||||
GraphicsDevice *device, DrawBuffer *buffer, Campaign *co,
|
||||
struct MissionOptions *mo, Map *map, HSV tint, const bool isEditor,
|
||||
struct vec2 pos, GrafxDrawExtra *extra);
|
||||
struct vec2 pos, const DrawBufferArgs *args);
|
||||
|
@@ -85,9 +85,9 @@ static void HandleGameEvent(
|
||||
LOG(LM_MAP, LL_DEBUG, "set tile %s/%s/%s pos(%d, %d) x%d",
|
||||
e.u.TileSet.ClassName, e.u.TileSet.DoorClassName,
|
||||
e.u.TileSet.DoorClass2Name, pos.x, pos.y, e.u.TileSet.RunLength);
|
||||
const TileClass *tileClass = StrTileClass(e.u.TileSet.ClassName);
|
||||
const TileClass *doorClass = StrTileClass(e.u.TileSet.DoorClassName);
|
||||
const TileClass *doorClass2 = StrTileClass(e.u.TileSet.DoorClass2Name);
|
||||
const TileClass *tileClass = StrTileClass(gMap.TileClasses, e.u.TileSet.ClassName);
|
||||
const TileClass *doorClass = StrTileClass(gMap.TileClasses, e.u.TileSet.DoorClassName);
|
||||
const TileClass *doorClass2 = StrTileClass(gMap.TileClasses, e.u.TileSet.DoorClass2Name);
|
||||
for (int i = 0; i <= e.u.TileSet.RunLength; i++)
|
||||
{
|
||||
Tile *t = MapGetTile(&gMap, pos);
|
||||
|
@@ -272,9 +272,9 @@ void MapShowExitArea(Map *map, const int i)
|
||||
const int bottom = top + exit->R.Size.y;
|
||||
|
||||
const TileClass *exitClass = TileClassesGetExit(
|
||||
&gTileClasses, &gPicManager, gMission.missionData->ExitStyle, false);
|
||||
map->TileClasses, &gPicManager, gMission.missionData->ExitStyle, false);
|
||||
const TileClass *exitShadowClass = TileClassesGetExit(
|
||||
&gTileClasses, &gPicManager, gMission.missionData->ExitStyle, true);
|
||||
map->TileClasses, &gPicManager, gMission.missionData->ExitStyle, true);
|
||||
|
||||
struct vec2i v;
|
||||
v.y = top;
|
||||
@@ -478,6 +478,7 @@ void MapTerminate(Map *map)
|
||||
}
|
||||
}
|
||||
CArrayTerminate(&map->Tiles);
|
||||
TileClassesTerminate(map->TileClasses);
|
||||
LOSTerminate(&map->LOS);
|
||||
CArrayTerminate(&map->access);
|
||||
PathCacheTerminate(&gPathCache);
|
||||
@@ -489,6 +490,7 @@ void MapInit(Map *map, const struct vec2i size)
|
||||
|
||||
// Init map
|
||||
memset(map, 0, sizeof *map);
|
||||
map->TileClasses = TileClassesNew();
|
||||
CArrayInit(&map->Tiles, sizeof(Tile));
|
||||
map->Size = size;
|
||||
LOSInit(map);
|
||||
|
@@ -97,6 +97,7 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
map_t TileClasses;
|
||||
CArray Tiles; // of Tile
|
||||
struct vec2i Size;
|
||||
|
||||
|
@@ -22,7 +22,7 @@
|
||||
This file incorporates work covered by the following copyright and
|
||||
permission notice:
|
||||
|
||||
Copyright (c) 2013-2014, 2017-2021 Cong Xu
|
||||
Copyright (c) 2013-2014, 2017-2022 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -69,15 +69,12 @@ static void MapSetupDoors(MapBuilder *mb);
|
||||
static void MapAddDrains(MapBuilder *mb);
|
||||
static void MapGenerateRandomExitArea(Map *map, const int mission);
|
||||
void MapBuild(
|
||||
Map *m, const Mission *mission, const Campaign *co, const int missionIndex)
|
||||
Map *m, const Mission *mission, const bool loadDynamic, const int missionIndex, const GameMode mode, const CharacterStore *characters)
|
||||
{
|
||||
MapBuilder mb;
|
||||
MapBuilderInit(&mb, m, mission, co);
|
||||
MapBuilderInit(&mb, m, mission, mode, characters);
|
||||
MapInit(mb.Map, mb.mission->Size);
|
||||
|
||||
// Re-seed RNG so results are consistent
|
||||
CampaignSeedRandom(co);
|
||||
|
||||
switch (mb.mission->Type)
|
||||
{
|
||||
case MAPTYPE_CLASSIC:
|
||||
@@ -142,14 +139,14 @@ void MapBuild(
|
||||
}
|
||||
}
|
||||
|
||||
if (!co->IsClient)
|
||||
if (loadDynamic)
|
||||
{
|
||||
MapLoadDynamic(&mb);
|
||||
ActorsPilotVehicles();
|
||||
}
|
||||
MapBuilderTerminate(&mb);
|
||||
}
|
||||
void SetupWallTileClasses(PicManager *pm, const TileClass *base)
|
||||
void SetupWallTileClasses(Map *m, PicManager *pm, const TileClass *base)
|
||||
{
|
||||
for (int i = 0; i < WALL_TYPE_COUNT; i++)
|
||||
{
|
||||
@@ -157,11 +154,11 @@ void SetupWallTileClasses(PicManager *pm, const TileClass *base)
|
||||
pm, "wall", base->Style, IntWallType(i), base->Mask, base->MaskAlt,
|
||||
false);
|
||||
TileClassesAdd(
|
||||
&gTileClasses, pm, base, base->Style, IntWallType(i), base->Mask,
|
||||
m->TileClasses, pm, base, base->Style, IntWallType(i), base->Mask,
|
||||
base->MaskAlt);
|
||||
}
|
||||
}
|
||||
void SetupFloorTileClasses(PicManager *pm, const TileClass *base)
|
||||
void SetupFloorTileClasses(Map *m, PicManager *pm, const TileClass *base)
|
||||
{
|
||||
for (int i = 0; i < FLOOR_TYPES; i++)
|
||||
{
|
||||
@@ -169,11 +166,11 @@ void SetupFloorTileClasses(PicManager *pm, const TileClass *base)
|
||||
pm, "tile", base->Style, IntTileType(i), base->Mask, base->MaskAlt,
|
||||
false);
|
||||
TileClassesAdd(
|
||||
&gTileClasses, pm, base, base->Style, IntTileType(i), base->Mask,
|
||||
m->TileClasses, pm, base, base->Style, IntTileType(i), base->Mask,
|
||||
base->MaskAlt);
|
||||
}
|
||||
}
|
||||
void SetupDoorTileClasses(PicManager *pm, const TileClass *base)
|
||||
void SetupDoorTileClasses(Map *m, PicManager *pm, const TileClass *base)
|
||||
{
|
||||
const char *doorStyles[] = {"yellow", "green", "blue", "red",
|
||||
"open", "wall", "normal"};
|
||||
@@ -181,7 +178,7 @@ void SetupDoorTileClasses(PicManager *pm, const TileClass *base)
|
||||
{
|
||||
for (DoorType type = DOORTYPE_H; type < DOORTYPE_COUNT; type++)
|
||||
{
|
||||
DoorAddClass(&gTileClasses, pm, base, doorStyles[i], type);
|
||||
DoorAddClass(m->TileClasses, pm, base, doorStyles[i], type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -233,12 +230,13 @@ static int MapGetAccessFlags(const MapBuilder *mb, const struct vec2i v)
|
||||
}
|
||||
|
||||
void MapBuilderInit(
|
||||
MapBuilder *mb, Map *m, const Mission *mission, const Campaign *co)
|
||||
MapBuilder *mb, Map *m, const Mission *mission, const GameMode mode, const CharacterStore *characters)
|
||||
{
|
||||
memset(mb, 0, sizeof *mb);
|
||||
mb->Map = m;
|
||||
mb->mission = mission;
|
||||
mb->co = co;
|
||||
mb->mode = mode;
|
||||
mb->characters = characters;
|
||||
|
||||
const int mapSize = mission->Size.x * mission->Size.y;
|
||||
CArrayInitFillZero(&mb->access, sizeof(uint16_t), mapSize);
|
||||
@@ -648,6 +646,7 @@ static void MapSetupTilesAndWalls(MapBuilder *mb)
|
||||
{
|
||||
Tile *t = MapGetTile(mb->Map, pos);
|
||||
t->Class = TileClassesGetMaskedTile(
|
||||
mb->Map->TileClasses,
|
||||
t->Class, t->Class->Style, "alt1", t->Class->Mask,
|
||||
t->Class->MaskAlt);
|
||||
}
|
||||
@@ -659,6 +658,7 @@ static void MapSetupTilesAndWalls(MapBuilder *mb)
|
||||
{
|
||||
Tile *t = MapGetTile(mb->Map, pos);
|
||||
t->Class = TileClassesGetMaskedTile(
|
||||
mb->Map->TileClasses,
|
||||
t->Class, t->Class->Style, "alt2", t->Class->Mask,
|
||||
t->Class->MaskAlt);
|
||||
}
|
||||
@@ -682,17 +682,20 @@ static void MapSetupTile(MapBuilder *mb, const struct vec2i pos)
|
||||
if (tc->Type == TILE_CLASS_FLOOR)
|
||||
{
|
||||
t->Class = TileClassesGetMaskedTile(
|
||||
mb->Map->TileClasses,
|
||||
tc, tc->Style, canSeeTileAbove ? "normal" : "shadow", tc->Mask,
|
||||
tc->MaskAlt);
|
||||
}
|
||||
else if (tc->Type == TILE_CLASS_WALL)
|
||||
{
|
||||
t->Class = TileClassesGetMaskedTile(
|
||||
mb->Map->TileClasses,
|
||||
tc, tc->Style, MapGetWallPic(mb, pos), tc->Mask, tc->MaskAlt);
|
||||
}
|
||||
else if (tc->Type == TILE_CLASS_DOOR)
|
||||
{
|
||||
t->Class = TileClassesGetMaskedTile(
|
||||
mb->Map->TileClasses,
|
||||
tc, tc->Style, "normal_h", tc->Mask, tc->MaskAlt);
|
||||
}
|
||||
else if (tc->Type == TILE_CLASS_NOTHING)
|
||||
@@ -1500,6 +1503,10 @@ static void MapAddDrains(MapBuilder *mb)
|
||||
// Randomly add drainage tiles for classic map type;
|
||||
// For other map types drains are regular map objects
|
||||
const MapObject *drain = StrMapObject("drain0");
|
||||
if (drain == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < mb->Map->Size.x * mb->Map->Size.y / 45; i++)
|
||||
{
|
||||
// Make sure drain tiles aren't next to each other
|
||||
|
@@ -22,7 +22,7 @@
|
||||
This file incorporates work covered by the following copyright and
|
||||
permission notice:
|
||||
|
||||
Copyright (c) 2013-2015, 2017-2021 Cong Xu
|
||||
Copyright (c) 2013-2015, 2017-2022 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -48,7 +48,7 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "campaigns.h"
|
||||
#include "game_mode.h"
|
||||
#include "map.h"
|
||||
#include "mission.h"
|
||||
|
||||
@@ -56,7 +56,8 @@ typedef struct
|
||||
{
|
||||
Map *Map;
|
||||
const Mission *mission;
|
||||
const Campaign *co;
|
||||
GameMode mode;
|
||||
const CharacterStore *characters;
|
||||
|
||||
// internal data structures to help build the map
|
||||
CArray access; // of uint16_t
|
||||
@@ -65,10 +66,9 @@ typedef struct
|
||||
} MapBuilder;
|
||||
|
||||
void MapBuild(
|
||||
Map *m, const Mission *mission, const Campaign *co,
|
||||
const int missionIndex);
|
||||
Map *m, const Mission *mission, const bool loadDynamic, const int missionIndex, const GameMode mode, const CharacterStore *characters);
|
||||
void MapBuilderInit(
|
||||
MapBuilder *mb, Map *m, const Mission *mission, const Campaign *co);
|
||||
MapBuilder *mb, Map *m, const Mission *mission, const GameMode mode, const CharacterStore *characters);
|
||||
void MapBuilderTerminate(MapBuilder *mb);
|
||||
|
||||
void MapLoadDynamic(MapBuilder *mb);
|
||||
@@ -139,6 +139,6 @@ void MapBuildTile(
|
||||
|
||||
uint16_t GenerateAccessMask(int *accessLevel);
|
||||
|
||||
void SetupWallTileClasses(PicManager *pm, const TileClass *base);
|
||||
void SetupFloorTileClasses(PicManager *pm, const TileClass *base);
|
||||
void SetupDoorTileClasses(PicManager *pm, const TileClass *base);
|
||||
void SetupWallTileClasses(Map *m, PicManager *pm, const TileClass *base);
|
||||
void SetupFloorTileClasses(Map *m, PicManager *pm, const TileClass *base);
|
||||
void SetupDoorTileClasses(Map *m, PicManager *pm, const TileClass *base);
|
||||
|
@@ -39,7 +39,7 @@ static void PlaceRooms(MapBuilder *mb);
|
||||
void MapCaveLoad(MapBuilder *mb)
|
||||
{
|
||||
// TODO: multiple tile types
|
||||
MissionSetupTileClasses(&gPicManager, &mb->mission->u.Cave.TileClasses);
|
||||
MissionSetupTileClasses(mb->Map, &gPicManager, &mb->mission->u.Cave.TileClasses);
|
||||
|
||||
// Randomly set a percentage of the tiles as walls
|
||||
for (int i = 0; i < mb->mission->u.Cave.FillPercent * mb->Map->Size.x *
|
||||
@@ -464,7 +464,7 @@ static void PlaceRooms(MapBuilder *mb)
|
||||
room.Size.x, room.Size.y);
|
||||
}
|
||||
// Set keys for rooms
|
||||
if (AreKeysAllowed(gCampaign.Entry.Mode) &&
|
||||
if (AreKeysAllowed(mb->mode) &&
|
||||
mb->mission->u.Cave.DoorsEnabled)
|
||||
{
|
||||
while (rooms.size > 0)
|
||||
|
@@ -80,7 +80,7 @@ void MapClassicLoad(MapBuilder *mb)
|
||||
// create inaccessible areas on the map.
|
||||
|
||||
// TODO: multiple tile types
|
||||
MissionSetupTileClasses(&gPicManager, &mb->mission->u.Classic.TileClasses);
|
||||
MissionSetupTileClasses(mb->Map, &gPicManager, &mb->mission->u.Classic.TileClasses);
|
||||
|
||||
MapFillRect(
|
||||
mb, Rect2iNew(svec2i_zero(), mb->mission->Size),
|
||||
@@ -119,7 +119,7 @@ void MapClassicLoad(MapBuilder *mb)
|
||||
}
|
||||
MapBuildRoom(
|
||||
mb, v, size, doorMin, doorMax,
|
||||
AreKeysAllowed(gCampaign.Entry.Mode), isOverlapRoom,
|
||||
AreKeysAllowed(mb->mode), isOverlapRoom,
|
||||
overlapAccess);
|
||||
count++;
|
||||
}
|
||||
|
@@ -141,7 +141,7 @@ void MapInteriorLoad(MapBuilder *mb, const int missionIndex)
|
||||
{
|
||||
// TODO: multiple tile types
|
||||
MissionSetupTileClasses(
|
||||
&gPicManager, &mb->mission->u.Interior.TileClasses);
|
||||
mb->Map, &gPicManager, &mb->mission->u.Interior.TileClasses);
|
||||
|
||||
CArray areas;
|
||||
CArrayInit(&areas, sizeof(BSPArea));
|
||||
|
@@ -42,7 +42,7 @@ void MapStaticLoad(MapBuilder *mb)
|
||||
{
|
||||
// Tile classes
|
||||
if (hashmap_iterate(
|
||||
mb->mission->u.Static.TileClasses, AddTileClass, NULL) != MAP_OK)
|
||||
mb->mission->u.Static.TileClasses, AddTileClass, mb->Map) != MAP_OK)
|
||||
{
|
||||
CASSERT(false, "failed to add static tile classes");
|
||||
}
|
||||
@@ -59,23 +59,23 @@ void MapStaticLoad(MapBuilder *mb)
|
||||
}
|
||||
static int AddTileClass(any_t data, any_t item)
|
||||
{
|
||||
UNUSED(data);
|
||||
Map *m = data;
|
||||
TileClass *t = item;
|
||||
// Attach base style to tile class for convenience in editors etc
|
||||
CSTRDUP(t->StyleType, TileClassBaseStyleType(t->Type));
|
||||
TileClassesAdd(
|
||||
&gTileClasses, &gPicManager, t, t->Style, t->StyleType, t->Mask,
|
||||
m->TileClasses, &gPicManager, t, t->Style, t->StyleType, t->Mask,
|
||||
t->MaskAlt);
|
||||
switch (t->Type)
|
||||
{
|
||||
case TILE_CLASS_DOOR:
|
||||
SetupDoorTileClasses(&gPicManager, t);
|
||||
SetupDoorTileClasses(m, &gPicManager, t);
|
||||
break;
|
||||
case TILE_CLASS_WALL:
|
||||
SetupWallTileClasses(&gPicManager, t);
|
||||
SetupWallTileClasses(m, &gPicManager, t);
|
||||
break;
|
||||
case TILE_CLASS_FLOOR:
|
||||
SetupFloorTileClasses(&gPicManager, t);
|
||||
SetupFloorTileClasses(m, &gPicManager, t);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -90,7 +90,7 @@ void MapStaticLoadTile(MapBuilder *mb, const struct vec2i v)
|
||||
const int idx = v.y * mb->Map->Size.x + v.x;
|
||||
uint16_t tileAccess =
|
||||
*(uint16_t *)CArrayGet(&mb->mission->u.Static.Access, idx);
|
||||
if (!AreKeysAllowed(gCampaign.Entry.Mode))
|
||||
if (!AreKeysAllowed(mb->mode))
|
||||
{
|
||||
tileAccess = 0;
|
||||
}
|
||||
@@ -100,7 +100,7 @@ void MapStaticLoadTile(MapBuilder *mb, const struct vec2i v)
|
||||
MapBuildSetAccess(mb, v, tileAccess);
|
||||
}
|
||||
|
||||
static void AddCharacters(const CArray *characters);
|
||||
static void AddCharacters(const MapBuilder *mb, const CArray *characters);
|
||||
static void AddObjectives(MapBuilder *mb, const CArray *objectives);
|
||||
static void AddKeys(MapBuilder *mb, const CArray *keys);
|
||||
static void AddPickups(const CArray *pickups);
|
||||
@@ -115,17 +115,17 @@ void MapStaticLoadDynamic(MapBuilder *mb)
|
||||
}
|
||||
CA_FOREACH_END()
|
||||
|
||||
if (ModeHasNPCs(gCampaign.Entry.Mode))
|
||||
if (ModeHasNPCs(mb->mode))
|
||||
{
|
||||
AddCharacters(&mb->mission->u.Static.Characters);
|
||||
AddCharacters(mb, &mb->mission->u.Static.Characters);
|
||||
}
|
||||
|
||||
if (HasObjectives(gCampaign.Entry.Mode))
|
||||
if (HasObjectives(mb->mode))
|
||||
{
|
||||
AddObjectives(mb, &mb->mission->u.Static.Objectives);
|
||||
}
|
||||
|
||||
if (AreKeysAllowed(gCampaign.Entry.Mode))
|
||||
if (AreKeysAllowed(mb->mode))
|
||||
{
|
||||
AddKeys(mb, &mb->mission->u.Static.Keys);
|
||||
}
|
||||
@@ -135,17 +135,18 @@ void MapStaticLoadDynamic(MapBuilder *mb)
|
||||
// Process the events to place dynamic objects
|
||||
HandleGameEvents(&gGameEvents, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
static void AddCharacter(const CharacterPlaces *cps);
|
||||
static void AddCharacters(const CArray *characters)
|
||||
static void AddCharacter(const MapBuilder *mb, const CharacterPlaces *cps);
|
||||
static void AddCharacters(const MapBuilder *mb, const CArray *characters)
|
||||
{
|
||||
CA_FOREACH(const CharacterPlaces, cps, *characters)
|
||||
AddCharacter(cps);
|
||||
AddCharacter(mb, cps);
|
||||
CA_FOREACH_END()
|
||||
}
|
||||
static void AddCharacter(const CharacterPlaces *cps)
|
||||
static void AddCharacter(const MapBuilder *mb, const CharacterPlaces *cps)
|
||||
{
|
||||
CASSERT(mb->characters != NULL, "cannot add characters");
|
||||
const Character *c = CArrayGet(
|
||||
&gCampaign.Setting.characters.OtherChars, cps->Index);
|
||||
&mb->characters->OtherChars, cps->Index);
|
||||
CA_FOREACH(const CharacterPlace, cp, cps->Places)
|
||||
GameEvent e = GameEventNewActorAdd(Vec2CenterOfTile(cp->Pos), c, true);
|
||||
e.u.ActorAdd.CharId = cps->Index;
|
||||
@@ -180,9 +181,10 @@ static void AddObjective(MapBuilder *mb, const ObjectivePositions *op)
|
||||
switch (o->Type)
|
||||
{
|
||||
case OBJECTIVE_KILL: {
|
||||
const int charId = CharacterStoreGetSpecialId(&mb->co->Setting.characters, pi->Index);
|
||||
CASSERT(mb->characters != NULL, "cannot add kill objective");
|
||||
const int charId = CharacterStoreGetSpecialId(mb->characters, pi->Index);
|
||||
const Character *c = CArrayGet(
|
||||
&gCampaign.Setting.characters.OtherChars, charId);
|
||||
&mb->characters->OtherChars, charId);
|
||||
GameEvent e = GameEventNewActorAdd(pos, c, true);
|
||||
e.u.ActorAdd.CharId = charId;
|
||||
e.u.ActorAdd.ThingFlags = ObjectiveToThing(op->Index);
|
||||
@@ -198,10 +200,11 @@ static void AddObjective(MapBuilder *mb, const ObjectivePositions *op)
|
||||
false);
|
||||
break;
|
||||
case OBJECTIVE_RESCUE: {
|
||||
CASSERT(mb->characters != NULL, "cannot add rescue objective");
|
||||
const int charId = CharacterStoreGetPrisonerId(
|
||||
&mb->co->Setting.characters, pi->Index);
|
||||
mb->characters, pi->Index);
|
||||
const Character *c = CArrayGet(
|
||||
&gCampaign.Setting.characters.OtherChars, charId);
|
||||
&mb->characters->OtherChars, charId);
|
||||
GameEvent e = GameEventNewActorAdd(pos, c, true);
|
||||
e.u.ActorAdd.CharId = charId;
|
||||
e.u.ActorAdd.ThingFlags = ObjectiveToThing(op->Index);
|
||||
|
@@ -357,12 +357,12 @@ void SetupMission(Mission *m, struct MissionOptions *mo, int missionIndex)
|
||||
SetupBadguysForMission(m);
|
||||
SetupWeapons(&mo->Weapons, &m->Weapons);
|
||||
}
|
||||
void MissionSetupTileClasses(PicManager *pm, const MissionTileClasses *mtc)
|
||||
void MissionSetupTileClasses(Map *m, PicManager *pm, const MissionTileClasses *mtc)
|
||||
{
|
||||
SetupWallTileClasses(pm, &mtc->Wall);
|
||||
SetupFloorTileClasses(pm, &mtc->Floor);
|
||||
SetupFloorTileClasses(pm, &mtc->Room);
|
||||
SetupDoorTileClasses(pm, &mtc->Door);
|
||||
SetupWallTileClasses(m, pm, &mtc->Wall);
|
||||
SetupFloorTileClasses(m, pm, &mtc->Floor);
|
||||
SetupFloorTileClasses(m, pm, &mtc->Room);
|
||||
SetupDoorTileClasses(m, pm, &mtc->Door);
|
||||
}
|
||||
void MissionTileClassesInitDefault(MissionTileClasses *mtc)
|
||||
{
|
||||
|
@@ -228,7 +228,7 @@ void MissionTerminate(Mission *m);
|
||||
MissionTileClasses *MissionGetTileClasses(Mission *m);
|
||||
|
||||
void SetupMission(Mission *m, struct MissionOptions *mo, int missionIndex);
|
||||
void MissionSetupTileClasses(PicManager *pm, const MissionTileClasses *mtc);
|
||||
void MissionSetupTileClasses(Map *m, PicManager *pm, const MissionTileClasses *mtc);
|
||||
void MissionTileClassesInitDefault(MissionTileClasses *mtc);
|
||||
void MissionTileClassesCopy(
|
||||
MissionTileClasses *dst, const MissionTileClasses *src);
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
C-Dogs SDL
|
||||
A port of the legendary (and fun) action/arcade cdogs.
|
||||
Copyright (c) 2018-2021 Cong Xu
|
||||
Copyright (c) 2018-2022 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -33,7 +33,6 @@
|
||||
#include "sys_config.h"
|
||||
|
||||
|
||||
TileClasses gTileClasses;
|
||||
TileClass gTileFloor = {
|
||||
"tile", NULL, NULL, NULL, { 255, 255, 255, 255 }, { 255, 255, 255, 255 },
|
||||
true, false, false, false, TILE_CLASS_FLOOR, NULL,
|
||||
@@ -80,20 +79,13 @@ TileClassType StrTileClassType(const char *s)
|
||||
return TILE_CLASS_NOTHING;
|
||||
}
|
||||
|
||||
void TileClassesInit(TileClasses *c)
|
||||
map_t TileClassesNew(void)
|
||||
{
|
||||
c->classes = hashmap_new();
|
||||
c->customClasses = hashmap_new();
|
||||
return hashmap_new();
|
||||
}
|
||||
void TileClassesClearCustom(TileClasses *c)
|
||||
void TileClassesTerminate(map_t c)
|
||||
{
|
||||
TileClassesTerminate(c);
|
||||
TileClassesInit(c);
|
||||
}
|
||||
void TileClassesTerminate(TileClasses *c)
|
||||
{
|
||||
hashmap_destroy(c->classes, TileClassDestroy);
|
||||
hashmap_destroy(c->customClasses, TileClassDestroy);
|
||||
hashmap_destroy(c, TileClassDestroy);
|
||||
}
|
||||
void TileClassDestroy(any_t data)
|
||||
{
|
||||
@@ -167,7 +159,7 @@ void TileClassCopy(TileClass *dst, const TileClass *src)
|
||||
if (src->StyleType) CSTRDUP(dst->StyleType, TileClassBaseStyleType(src->Type));
|
||||
if (src->DamageBullet) CSTRDUP(dst->DamageBullet, src->DamageBullet);
|
||||
}
|
||||
const TileClass *StrTileClass(const char *name)
|
||||
const TileClass *StrTileClass(map_t c, const char *name)
|
||||
{
|
||||
if (name == NULL || strlen(name) == 0)
|
||||
{
|
||||
@@ -175,12 +167,7 @@ const TileClass *StrTileClass(const char *name)
|
||||
}
|
||||
LOG(LM_MAIN, LL_TRACE, "get tile class %s", name);
|
||||
TileClass *t;
|
||||
int error = hashmap_get(gTileClasses.customClasses, name, (any_t *)&t);
|
||||
if (error == MAP_OK)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
error = hashmap_get(gTileClasses.classes, name, (any_t *)&t);
|
||||
const int error = hashmap_get(c, name, (any_t *)&t);
|
||||
if (error == MAP_OK)
|
||||
{
|
||||
return t;
|
||||
@@ -256,15 +243,15 @@ void TileClassReloadPic(TileClass *t, PicManager *pm)
|
||||
}
|
||||
}
|
||||
const TileClass *TileClassesGetMaskedTile(
|
||||
const TileClass *baseClass, const char *style, const char *type,
|
||||
map_t c, const TileClass *baseClass, const char *style, const char *type,
|
||||
const color_t mask, const color_t maskAlt)
|
||||
{
|
||||
char buf[256];
|
||||
TileClassGetName(buf, baseClass, style, type, mask, maskAlt);
|
||||
return StrTileClass(buf);
|
||||
return StrTileClass(c, buf);
|
||||
}
|
||||
TileClass *TileClassesAdd(
|
||||
TileClasses *c, PicManager *pm, const TileClass *baseClass,
|
||||
map_t c, PicManager *pm, const TileClass *baseClass,
|
||||
const char *style, const char *type,
|
||||
const color_t mask, const color_t maskAlt)
|
||||
{
|
||||
@@ -274,7 +261,7 @@ TileClass *TileClassesAdd(
|
||||
|
||||
char buf[CDOGS_PATH_MAX];
|
||||
TileClassGetName(buf, t, style, type, mask, maskAlt);
|
||||
const int error = hashmap_put(c->customClasses, buf, t);
|
||||
const int error = hashmap_put(c, buf, t);
|
||||
if (error != MAP_OK)
|
||||
{
|
||||
LOG(LM_MAIN, LL_ERROR, "failed to add tile class %s: %d", buf, error);
|
||||
@@ -318,12 +305,12 @@ const Pic *TileClassGetPic(const PicManager *pm, const TileClass *tc)
|
||||
}
|
||||
|
||||
const TileClass *TileClassesGetExit(
|
||||
TileClasses *c, PicManager *pm, const char *style, const bool isShadow)
|
||||
map_t c, PicManager *pm, const char *style, const bool isShadow)
|
||||
{
|
||||
char buf[256];
|
||||
const char *type = isShadow ? "shadow" : "normal";
|
||||
TileClassGetName(buf, &gTileExit, style, type, colorWhite, colorWhite);
|
||||
const TileClass *t = StrTileClass(buf);
|
||||
const TileClass *t = StrTileClass(c, buf);
|
||||
if (t != &gTileNothing)
|
||||
{
|
||||
return t;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
C-Dogs SDL
|
||||
A port of the legendary (and fun) action/arcade cdogs.
|
||||
Copyright (c) 2018-2021 Cong Xu
|
||||
Copyright (c) 2018-2022 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -72,12 +72,6 @@ typedef struct
|
||||
char *DamageBullet;
|
||||
} TileClass;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
map_t classes; // of TileClass *
|
||||
map_t customClasses; // of TileClass *
|
||||
} TileClasses;
|
||||
extern TileClasses gTileClasses;
|
||||
extern TileClass gTileFloor;
|
||||
extern TileClass gTileRoom;
|
||||
extern TileClass gTileWall;
|
||||
@@ -85,9 +79,8 @@ extern TileClass gTileNothing;
|
||||
extern TileClass gTileExit;
|
||||
extern TileClass gTileDoor;
|
||||
|
||||
void TileClassesInit(TileClasses *c);
|
||||
void TileClassesClearCustom(TileClasses *c);
|
||||
void TileClassesTerminate(TileClasses *c);
|
||||
map_t TileClassesNew(void);
|
||||
void TileClassesTerminate(map_t c);
|
||||
void TileClassDestroy(any_t data);
|
||||
void TileClassTerminate(TileClass *tc);
|
||||
void TileClassLoadJSON(TileClass *tc, json_t *node);
|
||||
@@ -103,12 +96,12 @@ void TileClassInitDefault(
|
||||
void TileClassReloadPic(TileClass *t, PicManager *pm);
|
||||
const char *TileClassBaseStyleType(const TileClassType type);
|
||||
void TileClassCopy(TileClass *dst, const TileClass *src);
|
||||
const TileClass *StrTileClass(const char *name);
|
||||
const TileClass *StrTileClass(map_t c, const char *name);
|
||||
const TileClass *TileClassesGetMaskedTile(
|
||||
const TileClass *baseClass, const char *style, const char *type,
|
||||
map_t c, const TileClass *baseClass, const char *style, const char *type,
|
||||
const color_t mask, const color_t maskAlt);
|
||||
TileClass *TileClassesAdd(
|
||||
TileClasses *c, PicManager *pm, const TileClass *baseClass,
|
||||
map_t c, PicManager *pm, const TileClass *baseClass,
|
||||
const char *style, const char *type,
|
||||
const color_t mask, const color_t maskAlt);
|
||||
const Pic *TileClassGetPic(const PicManager *pm, const TileClass *tc);
|
||||
@@ -117,4 +110,4 @@ void TileClassGetName(
|
||||
const color_t mask, const color_t maskAlt);
|
||||
void TileClassGetBaseName(char *buf, const TileClass *tc);
|
||||
const TileClass *TileClassesGetExit(
|
||||
TileClasses *c, PicManager *pm, const char *style, const bool isShadow);
|
||||
map_t c, PicManager *pm, const char *style, const bool isShadow);
|
||||
|
@@ -151,9 +151,11 @@ static void MakeBackground(const bool changedMission)
|
||||
ec.camera = Vec2CenterOfTile(focusTile);
|
||||
}
|
||||
|
||||
GrafxDrawExtra extra;
|
||||
extra.guideImage = &brush.GuideImagePic;
|
||||
extra.guideImageAlpha = brush.GuideImageAlpha;
|
||||
DrawBufferArgs args;
|
||||
memset(&args, 0, sizeof args);
|
||||
args.Editor = true;
|
||||
args.GuideImage = &brush.GuideImagePic;
|
||||
args.GuideImageAlpha = brush.GuideImageAlpha;
|
||||
|
||||
DrawBufferTerminate(&sDrawBuffer);
|
||||
ClearScreen(ec.g);
|
||||
@@ -190,10 +192,12 @@ static void Display(HandleInputResult result)
|
||||
MakeBackground(false);
|
||||
}
|
||||
|
||||
GrafxDrawExtra extra;
|
||||
extra.guideImage = &brush.GuideImagePic;
|
||||
extra.guideImageAlpha = brush.GuideImageAlpha;
|
||||
GrafxDrawBackground(ec.g, &sDrawBuffer, tintNone, ec.camera, &extra);
|
||||
DrawBufferArgs args;
|
||||
memset(&args, 0, sizeof args);
|
||||
args.Editor = true;
|
||||
args.GuideImage = &brush.GuideImagePic;
|
||||
args.GuideImageAlpha = brush.GuideImageAlpha;
|
||||
GrafxDrawBackground(ec.g, &sDrawBuffer, tintNone, ec.camera, &args);
|
||||
BlitClearBuf(ec.g);
|
||||
|
||||
// Draw brush highlight tiles
|
||||
@@ -1259,7 +1263,6 @@ int main(int argc, char *argv[])
|
||||
|
||||
gConfig = ConfigLoad(GetConfigFilePath(CONFIG_FILE));
|
||||
PicManagerInit(&gPicManager);
|
||||
TileClassesInit(&gTileClasses);
|
||||
// Hardcode config settings
|
||||
ConfigGet(&gConfig, "Graphics.ScaleFactor")->u.Int.Value = 2;
|
||||
ConfigGet(&gConfig, "Graphics.ScaleMode")->u.Enum.Value = SCALE_MODE_NN;
|
||||
|
@@ -227,7 +227,7 @@ static void EditorBrushPaintTilesAt(void *data, struct vec2i pos)
|
||||
EditorBrush *b = paintData->brush;
|
||||
Mission *m = paintData->mission;
|
||||
MapBuilder mb;
|
||||
MapBuilderInit(&mb, &gMap, m, NULL);
|
||||
MapBuilderInit(&mb, &gMap, m, NULL, GAME_MODE_NORMAL, NULL);
|
||||
for (v.y = 0; v.y < b->BrushSize; v.y++)
|
||||
{
|
||||
for (v.x = 0; v.x < b->BrushSize; v.x++)
|
||||
@@ -323,7 +323,7 @@ EditorResult EditorBrushStartPainting(EditorBrush *b, Mission *m, int isMain)
|
||||
data.Fill = MissionFillTile;
|
||||
data.IsSame = MissionIsTileSame;
|
||||
PaintFloodFillData pData;
|
||||
MapBuilderInit(&pData.mb, &gMap, m, NULL);
|
||||
MapBuilderInit(&pData.mb, &gMap, m, NULL, GAME_MODE_NORMAL, NULL);
|
||||
pData.m = m;
|
||||
pData.fromType = tile;
|
||||
pData.toType = b->PaintType;
|
||||
|
@@ -286,7 +286,7 @@ static void MissionDrawExitStyle(
|
||||
const int idx = PicManagerGetExitStyleIndex(&gPicManager, m->ExitStyle);
|
||||
DrawStyleArea(
|
||||
svec2i_add(pos, o->Pos), "Exit",
|
||||
TileClassesGetExit(&gTileClasses, &gPicManager, m->ExitStyle, false)
|
||||
TileClassesGetExit(gMap.TileClasses, &gPicManager, m->ExitStyle, false)
|
||||
->Pic,
|
||||
idx, (int)gPicManager.exitStyleNames.size, UIObjectIsHighlighted(o));
|
||||
}
|
||||
@@ -515,7 +515,8 @@ static EditorResult MissionChangeType(void *data, int d)
|
||||
memset(&map, 0, sizeof map);
|
||||
MissionOptionsTerminate(&gMission);
|
||||
CampaignAndMissionSetup(mct->C, &gMission);
|
||||
MapBuild(&map, gMission.missionData, mct->C, gMission.index);
|
||||
CampaignSeedRandom(mct->C);
|
||||
MapBuild(&map, gMission.missionData, true, gMission.index, GAME_MODE_NORMAL, &mct->C->Setting.characters);
|
||||
MissionConvertToType(gMission.missionData, &map, mct->Type);
|
||||
MapTerminate(&map);
|
||||
return EDITOR_RESULT_CHANGED;
|
||||
|
@@ -106,7 +106,7 @@ static int FloorStyleIndex(const char *style);
|
||||
static int WallStyleIndex(const char *style);
|
||||
static int DoorStyleIndex(const char *style);
|
||||
static const TileClass *GetOrAddTileClass(
|
||||
const TileClass *base, PicManager *pm, const char *style,
|
||||
map_t c, const TileClass *base, PicManager *pm, const char *style,
|
||||
const color_t mask, const color_t maskAlt);
|
||||
static bool Draw(SDL_Window *win, struct nk_context *ctx, void *data);
|
||||
EditorResult TileBrush(
|
||||
@@ -150,21 +150,21 @@ EditorResult TileBrush(
|
||||
CA_FOREACH(const GLuint, texid, data.texIdsFloorStyles)
|
||||
const char *style = *(char **)CArrayGet(&pm->tileStyleNames, _ca_index);
|
||||
const TileClass *styleClass = GetOrAddTileClass(
|
||||
&gTileFloor, pm, style, colorBattleshipGrey, colorOfficeGreen);
|
||||
gMap.TileClasses, &gTileFloor, pm, style, colorBattleshipGrey, colorOfficeGreen);
|
||||
LoadTexFromPic(*texid, styleClass->Pic);
|
||||
CA_FOREACH_END()
|
||||
TexArrayInit(&data.texIdsWallStyles, pm->wallStyleNames.size);
|
||||
CA_FOREACH(const GLuint, texid, data.texIdsWallStyles)
|
||||
const char *style = *(char **)CArrayGet(&pm->wallStyleNames, _ca_index);
|
||||
const TileClass *styleClass = GetOrAddTileClass(
|
||||
&gTileWall, pm, style, colorGravel, colorOfficeGreen);
|
||||
gMap.TileClasses, &gTileWall, pm, style, colorGravel, colorOfficeGreen);
|
||||
LoadTexFromPic(*texid, styleClass->Pic);
|
||||
CA_FOREACH_END()
|
||||
TexArrayInit(&data.texIdsDoorStyles, pm->doorStyleNames.size);
|
||||
CA_FOREACH(const GLuint, texid, data.texIdsDoorStyles)
|
||||
const char *style = *(char **)CArrayGet(&pm->doorStyleNames, _ca_index);
|
||||
const TileClass *styleClass =
|
||||
GetOrAddTileClass(&gTileDoor, pm, style, colorWhite, colorOfficeGreen);
|
||||
GetOrAddTileClass(gMap.TileClasses, &gTileDoor, pm, style, colorWhite, colorOfficeGreen);
|
||||
LoadTexFromPic(*texid, styleClass->Pic);
|
||||
CA_FOREACH_END()
|
||||
|
||||
@@ -568,15 +568,15 @@ static int DoorStyleIndex(const char *style)
|
||||
}
|
||||
|
||||
static const TileClass *GetOrAddTileClass(
|
||||
const TileClass *base, PicManager *pm, const char *style,
|
||||
map_t c, const TileClass *base, PicManager *pm, const char *style,
|
||||
const color_t mask, const color_t maskAlt)
|
||||
{
|
||||
const TileClass *styleClass = TileClassesGetMaskedTile(
|
||||
base, style, TileClassBaseStyleType(base->Type), mask, maskAlt);
|
||||
c, base, style, TileClassBaseStyleType(base->Type), mask, maskAlt);
|
||||
if (styleClass == &gTileNothing)
|
||||
{
|
||||
styleClass = TileClassesAdd(
|
||||
&gTileClasses, pm, base, style, TileClassBaseStyleType(base->Type),
|
||||
c, pm, base, style, TileClassBaseStyleType(base->Type),
|
||||
mask, maskAlt);
|
||||
}
|
||||
return styleClass;
|
||||
|
10
src/game.c
10
src/game.c
@@ -22,7 +22,7 @@
|
||||
This file incorporates work covered by the following copyright and
|
||||
permission notice:
|
||||
|
||||
Copyright (c) 2013-2021 Cong Xu
|
||||
Copyright (c) 2013-2022 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -70,6 +70,7 @@
|
||||
|
||||
#include "briefing_screens.h"
|
||||
#include "hiscores.h"
|
||||
#include "loading_screens.h"
|
||||
#include "prep.h"
|
||||
#include "screens_end.h"
|
||||
|
||||
@@ -143,13 +144,14 @@ static void RunGameTerminate(GameLoopData *data)
|
||||
}
|
||||
static void RunGameOnEnter(GameLoopData *data)
|
||||
{
|
||||
DrawGameLoadingScreen(&gGraphicsDevice, "Starting game...");
|
||||
LoadingScreenDraw(&gLoadingScreen, "Starting game...");
|
||||
|
||||
RunGameData *rData = data->Data;
|
||||
|
||||
RunGameReset(rData);
|
||||
|
||||
MapBuild(rData->map, rData->m->missionData, rData->co, rData->m->index);
|
||||
CampaignSeedRandom(rData->co);
|
||||
MapBuild(rData->map, rData->m->missionData, !rData->co->IsClient, rData->m->index, rData->co->Entry.Mode, &rData->co->Setting.characters);
|
||||
|
||||
// Seed random if PVP mode (otherwise players will always spawn in same
|
||||
// position)
|
||||
@@ -258,6 +260,8 @@ static void RunGameOnExit(GameLoopData *data)
|
||||
|
||||
LOG(LM_MAIN, LL_INFO, "Game finished");
|
||||
|
||||
LoadingScreenDraw(&gLoadingScreen, "Debriefing...");
|
||||
|
||||
// Flush events
|
||||
HandleGameEvents(&gGameEvents, NULL, NULL, NULL, NULL);
|
||||
|
||||
|
@@ -177,7 +177,6 @@ void LoopRunnerTerminate(LoopRunner *l)
|
||||
|
||||
static void GameLoopOnEnter(GameLoopData *data);
|
||||
static void GameLoopOnExit(GameLoopData *data);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GameLoopResult Result;
|
||||
|
128
src/loading_screens.c
Normal file
128
src/loading_screens.c
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
C-Dogs SDL
|
||||
A port of the legendary (and fun) action/arcade cdogs.
|
||||
Copyright (c) 2022 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "loading_screens.h"
|
||||
|
||||
#include <cdogs/draw/draw.h>
|
||||
#include <cdogs/files.h>
|
||||
#include <cdogs/font.h>
|
||||
#include <cdogs/map_build.h>
|
||||
#include <cdogs/pic_manager.h>
|
||||
#include <cdogs/pics.h>
|
||||
#include <cdogs/tile_class.h>
|
||||
|
||||
LoadingScreen gLoadingScreen;
|
||||
|
||||
void LoadingScreenInit(LoadingScreen *l, GraphicsDevice *g)
|
||||
{
|
||||
memset(l, 0, sizeof *l);
|
||||
l->g = g;
|
||||
}
|
||||
void LoadingScreenTerminate(LoadingScreen *l)
|
||||
{
|
||||
MapTerminate(&l->m);
|
||||
DrawBufferTerminate(&l->db);
|
||||
}
|
||||
|
||||
static void LazyLoad(LoadingScreen *l)
|
||||
{
|
||||
if (l->logo == NULL)
|
||||
{
|
||||
l->logo = PicManagerGetPic(&gPicManager, "logo");
|
||||
}
|
||||
// Create map large enough to cover the entire screen
|
||||
const struct vec2i mapSize = svec2i(X_TILES, Y_TILES);
|
||||
if (gPicManager.tileStyleNames.size > 0 &&
|
||||
(l->m.Size.x < mapSize.x || l->m.Size.y < mapSize.y))
|
||||
{
|
||||
// Map with floors only
|
||||
Mission m;
|
||||
MissionInit(&m);
|
||||
m.Type = MAPTYPE_CLASSIC;
|
||||
m.Size = mapSize;
|
||||
TileClassInit(
|
||||
&m.u.Classic.TileClasses.Floor, &gPicManager, &gTileFloor,
|
||||
IntFloorStyle(rand() % FLOOR_STYLE_COUNT),
|
||||
TileClassBaseStyleType(TILE_CLASS_FLOOR),
|
||||
RangeToColor(rand() % COLORRANGE_COUNT),
|
||||
RangeToColor(rand() % COLORRANGE_COUNT));
|
||||
m.u.Classic.ExitEnabled = false;
|
||||
MapBuild(&l->m, &m, false, 0, GAME_MODE_NORMAL, NULL);
|
||||
MapMarkAllAsVisited(&l->m);
|
||||
DrawBufferInit(&l->db, mapSize, l->g);
|
||||
}
|
||||
}
|
||||
|
||||
static int ReloadTileClass(any_t data, any_t item)
|
||||
{
|
||||
PicManager *pm = data;
|
||||
TileClass *t = item;
|
||||
TileClassReloadPic(t, pm);
|
||||
return MAP_OK;
|
||||
}
|
||||
void LoadingScreenReload(LoadingScreen *l)
|
||||
{
|
||||
if (hashmap_iterate(l->m.TileClasses, ReloadTileClass, &gPicManager) != MAP_OK)
|
||||
{
|
||||
CASSERT(false, "failed to reload tile classes");
|
||||
}
|
||||
}
|
||||
|
||||
void LoadingScreenDraw(LoadingScreen *l, const char *loadingText)
|
||||
{
|
||||
WindowContextPreRender(&l->g->gameWindow);
|
||||
|
||||
LazyLoad(l);
|
||||
|
||||
if (!svec2i_is_zero(l->m.Size))
|
||||
{
|
||||
DrawBufferSetFromMap(&l->db, &l->m, Vec2CenterOfTile(svec2i_scale_divide(l->m.Size, 2)), X_TILES);
|
||||
DrawBufferArgs args;
|
||||
memset(&args, 0, sizeof args);
|
||||
DrawBufferDraw(&l->db, svec2i_zero(), &args);
|
||||
}
|
||||
|
||||
if (l->logo)
|
||||
{
|
||||
const struct vec2i pos = svec2i(
|
||||
CENTER_X(svec2i_zero(), l->g->cachedConfig.Res, l->logo->size.x),
|
||||
CENTER_Y(
|
||||
svec2i_zero(), svec2i_scale_divide(l->g->cachedConfig.Res, 2),
|
||||
l->logo->size.y));
|
||||
PicRender(
|
||||
l->logo, l->g->gameWindow.renderer, pos, colorWhite, 0, svec2_one(),
|
||||
SDL_FLIP_NONE, Rect2iZero());
|
||||
}
|
||||
|
||||
FontOpts opts = FontOptsNew();
|
||||
opts.HAlign = ALIGN_CENTER;
|
||||
opts.VAlign = ALIGN_CENTER;
|
||||
opts.Area = svec2i(l->g->cachedConfig.Res.x, l->g->cachedConfig.Res.y / 2);
|
||||
FontStrOpt(loadingText, svec2i(0, l->g->cachedConfig.Res.y / 2), opts);
|
||||
|
||||
WindowContextPostRender(&l->g->gameWindow);
|
||||
}
|
49
src/loading_screens.h
Normal file
49
src/loading_screens.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
C-Dogs SDL
|
||||
A port of the legendary (and fun) action/arcade cdogs.
|
||||
Copyright (c) 2022 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <cdogs/draw/draw_buffer.h>
|
||||
#include <cdogs/grafx.h>
|
||||
#include <cdogs/map.h>
|
||||
#include <cdogs/pic.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const Pic *logo;
|
||||
GraphicsDevice *g;
|
||||
Map m;
|
||||
DrawBuffer db;
|
||||
} LoadingScreen;
|
||||
|
||||
extern LoadingScreen gLoadingScreen;
|
||||
|
||||
void LoadingScreenInit(LoadingScreen *l, GraphicsDevice *g);
|
||||
void LoadingScreenTerminate(LoadingScreen *l);
|
||||
|
||||
void LoadingScreenReload(LoadingScreen *l);
|
||||
void LoadingScreenDraw(LoadingScreen *l, const char *loadingText);
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2013-2021 Cong Xu
|
||||
Copyright (c) 2013-2022 Cong Xu
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "autosave.h"
|
||||
#include "briefing_screens.h"
|
||||
#include "game.h"
|
||||
#include "loading_screens.h"
|
||||
#include "menu.h"
|
||||
#include "prep.h"
|
||||
|
||||
@@ -100,7 +101,7 @@ static void GenerateLiveBackground(MainMenuData *data)
|
||||
GameEventsInit(&gGameEvents);
|
||||
gCampaign.MissionIndex = 0;
|
||||
|
||||
MapBuild(&gMap, gMission.missionData, &gCampaign, gMission.index);
|
||||
MapBuild(&gMap, gMission.missionData, true, gMission.index, GAME_MODE_NORMAL, &gCampaign.Setting.characters);
|
||||
|
||||
// Add AI player
|
||||
GameEvent e = GameEventNew(GAME_EVENT_PLAYER_DATA);
|
||||
@@ -243,8 +244,10 @@ static void MainMenuDraw(GameLoopData *data)
|
||||
MenuDraw(&mData->ms);
|
||||
const struct vec2 pos =
|
||||
Vec2CenterOfTile(svec2i_scale_divide(gMap.Size, 2));
|
||||
DrawBufferArgs args;
|
||||
memset(&args, 0, sizeof args);
|
||||
GrafxDrawBackground(
|
||||
mData->graphics, &mData->buffer, mData->bgTint, pos, NULL);
|
||||
mData->graphics, &mData->buffer, mData->bgTint, pos, &args);
|
||||
}
|
||||
|
||||
static menu_t *MenuCreateStart(
|
||||
@@ -351,7 +354,8 @@ static menu_t *CreateStartGameMode(
|
||||
}
|
||||
static void StartGameMode(menu_t *menu, void *data)
|
||||
{
|
||||
DrawGameLoadingScreen(&gGraphicsDevice, "Loading game...");
|
||||
LoadingScreenReload(&gLoadingScreen);
|
||||
LoadingScreenDraw(&gLoadingScreen, "Loading game...");
|
||||
UNUSED(menu);
|
||||
StartGameModeData *mData = data;
|
||||
gCampaign.Entry.Mode = mData->GameMode;
|
||||
|
29
src/prep.c
29
src/prep.c
@@ -75,36 +75,11 @@
|
||||
|
||||
#include "briefing_screens.h"
|
||||
#include "game.h"
|
||||
#include "loading_screens.h"
|
||||
#include "namegen.h"
|
||||
#include "password.h"
|
||||
#include "player_select_menus.h"
|
||||
|
||||
void DrawGameLoadingScreen(GraphicsDevice *g, const char *loadingText)
|
||||
{
|
||||
WindowContextPreRender(&g->gameWindow);
|
||||
|
||||
const Pic *logo = PicManagerGetPic(&gPicManager, "logo");
|
||||
if (logo)
|
||||
{
|
||||
const struct vec2i pos = svec2i(
|
||||
CENTER_X(svec2i_zero(), g->cachedConfig.Res, logo->size.x),
|
||||
CENTER_Y(
|
||||
svec2i_zero(), svec2i_scale_divide(g->cachedConfig.Res, 2),
|
||||
logo->size.y));
|
||||
PicRender(
|
||||
logo, g->gameWindow.renderer, pos, colorWhite, 0, svec2_one(),
|
||||
SDL_FLIP_NONE, Rect2iZero());
|
||||
}
|
||||
|
||||
FontOpts opts = FontOptsNew();
|
||||
opts.HAlign = ALIGN_CENTER;
|
||||
opts.VAlign = ALIGN_CENTER;
|
||||
opts.Area = svec2i(g->cachedConfig.Res.x, g->cachedConfig.Res.y / 2);
|
||||
FontStrOpt(loadingText, svec2i(0, g->cachedConfig.Res.y / 2), opts);
|
||||
|
||||
WindowContextPostRender(&g->gameWindow);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MenuSystem ms;
|
||||
@@ -233,7 +208,7 @@ static void NumPlayersTerminate(GameLoopData *data)
|
||||
static void NumPlayersOnEnter(GameLoopData *data)
|
||||
{
|
||||
UNUSED(data);
|
||||
DrawGameLoadingScreen(&gGraphicsDevice, "Loading...");
|
||||
LoadingScreenDraw(&gLoadingScreen, "Loading...");
|
||||
MusicPlayFromChunk(
|
||||
&gSoundDevice.music, MUSIC_BRIEFING,
|
||||
&gCampaign.Setting.CustomSongs[MUSIC_BRIEFING]);
|
||||
|
@@ -54,8 +54,6 @@
|
||||
|
||||
#include "game_loop.h"
|
||||
|
||||
void DrawGameLoadingScreen(GraphicsDevice *g, const char *loadingText);
|
||||
|
||||
// Wait for the server to send us the current campaign
|
||||
GameLoopData *ScreenWaitForCampaignDef(void);
|
||||
|
||||
|
Reference in New Issue
Block a user