From 1546e74e49bf55659a9bdeb5b3af99da5e2f035d Mon Sep 17 00:00:00 2001 From: Cong Date: Mon, 29 Apr 2024 21:52:12 +1000 Subject: [PATCH] Draw smaller automap to fit screen (fixes #782) --- src/cdogs/automap.c | 38 +++++++++++++-------- src/cdogs/automap.h | 54 +++++++++++++++--------------- src/cdogsed/cdogsed.c | 78 +++++++++++++++++++++++++------------------ src/game.c | 6 ++-- 4 files changed, 100 insertions(+), 76 deletions(-) diff --git a/src/cdogs/automap.c b/src/cdogs/automap.c index 0222b9562..43d54f043 100644 --- a/src/cdogs/automap.c +++ b/src/cdogs/automap.c @@ -22,7 +22,7 @@ This file incorporates work covered by the following copyright and permission notice: - Copyright (c) 2013-2014, 2016, 2018-2020 Cong Xu + Copyright (c) 2013-2014, 2016, 2018-2020, 2024 Cong Xu All rights reserved. Redistribution and use in source and binary forms, with or without @@ -64,7 +64,7 @@ #include "pic_manager.h" #include "pickup.h" -#define MAP_FACTOR 2 +#define MAP_SCALE_DEFAULT 2 #define MASK_ALPHA 128; color_t colorWall = {72, 152, 72, 255}; @@ -286,35 +286,47 @@ static void DrawThing( } } -void AutomapDraw(SDL_Renderer *renderer, const int flags, const bool showExit) +void AutomapDraw( + GraphicsDevice *g, SDL_Renderer *renderer, const int flags, + const bool showExit) { - struct vec2i mapCenter = svec2i( - gGraphicsDevice.cachedConfig.Res.x / 2, - gGraphicsDevice.cachedConfig.Res.y / 2); + if (renderer == NULL) + { + renderer = g->gameWindow.renderer; + } + struct vec2i mapCenter = + svec2i(g->cachedConfig.Res.x / 2, g->cachedConfig.Res.y / 2); struct vec2i centerOn = svec2i(gMap.Size.x / 2, gMap.Size.y / 2); + // Set the map scale to fit on screen + int mapScale = MAP_SCALE_DEFAULT; + // TODO: allow fractional scales for really big maps / really small screens + if (gMap.Size.x * mapScale > g->cachedConfig.Res.x || + gMap.Size.y * mapScale > g->cachedConfig.Res.y) + { + mapScale--; + } struct vec2i pos = - svec2i_add(mapCenter, svec2i_scale(centerOn, -MAP_FACTOR)); + svec2i_add(mapCenter, svec2i_scale(centerOn, -(float)mapScale)); // Draw faded green overlay const color_t mask = {0, 128, 0, 128}; - DrawRectangle( - &gGraphicsDevice, svec2i_zero(), gGraphicsDevice.cachedConfig.Res, + DrawRectangle(g, svec2i_zero(), g->cachedConfig.Res, mask, true); - DrawMap(&gMap, mapCenter, centerOn, gMap.Size, MAP_FACTOR, flags); - DrawObjectivesAndKeys(&gMap, pos, MAP_FACTOR, flags); + DrawMap(&gMap, mapCenter, centerOn, gMap.Size, mapScale, flags); + DrawObjectivesAndKeys(&gMap, pos, mapScale, flags); CA_FOREACH(const PlayerData, p, gPlayerDatas) if (!IsPlayerAlive(p)) { continue; } - DisplayPlayer(renderer, ActorGetByUID(p->ActorUID), pos, MAP_FACTOR); + DisplayPlayer(renderer, ActorGetByUID(p->ActorUID), pos, mapScale); CA_FOREACH_END() if (showExit) { - DisplayExits(&gMap, pos, MAP_FACTOR, flags); + DisplayExits(&gMap, pos, mapScale, flags); } DisplaySummary(); } diff --git a/src/cdogs/automap.h b/src/cdogs/automap.h index d5238ffce..8417bf8d5 100644 --- a/src/cdogs/automap.h +++ b/src/cdogs/automap.h @@ -1,29 +1,29 @@ /* - C-Dogs SDL - A port of the legendary (and fun) action/arcade cdogs. - Copyright (c) 2013-2014, 2018 Cong Xu - All rights reserved. + C-Dogs SDL + A port of the legendary (and fun) action/arcade cdogs. + Copyright (c) 2013-2014, 2018, 2024 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: + 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. + 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. + 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 @@ -34,8 +34,10 @@ #define AUTOMAP_FLAGS_SHOWALL 0x01 #define AUTOMAP_FLAGS_MASK 0x02 -void AutomapDraw(SDL_Renderer *renderer, const int flags, const bool showExit); +void AutomapDraw( + GraphicsDevice *g, SDL_Renderer *renderer, const int flags, + const bool showExit); void AutomapDrawRegion( - SDL_Renderer *renderer, Map *map, - struct vec2i pos, const struct vec2i size, const struct vec2i mapCenter, - const int flags, const bool showExit); + SDL_Renderer *renderer, Map *map, struct vec2i pos, + const struct vec2i size, const struct vec2i mapCenter, const int flags, + const bool showExit); diff --git a/src/cdogsed/cdogsed.c b/src/cdogsed/cdogsed.c index a104784e5..201627fb9 100644 --- a/src/cdogsed/cdogsed.c +++ b/src/cdogsed/cdogsed.c @@ -225,7 +225,8 @@ static void Display(HandleInputResult result) } FontStr( - "Press " KMOD_CMD_NAME "+E to edit characters", svec2i(20, h - 20 - FontH() * 2)); + "Press " KMOD_CMD_NAME "+E to edit characters", + svec2i(20, h - 20 - FontH() * 2)); FontStr("Press F1 for help", svec2i(20, h - 20 - FontH())); UIObjectDraw( @@ -234,8 +235,7 @@ static void Display(HandleInputResult result) if (result.WillDisplayAutomap && mission) { - AutomapDraw( - gGraphicsDevice.gameWindow.renderer, AUTOMAP_FLAGS_SHOWALL, true); + AutomapDraw(&gGraphicsDevice, NULL, AUTOMAP_FLAGS_SHOWALL, true); } else { @@ -372,14 +372,13 @@ static void AdjustXC(int yc, int *xc) *xc, 0, (int)mission->MapObjectDensities.size - 1); } break; - + case YC_PICKUPS: - if (mission && mission->PickupCounts.size > 0) - { - *xc = CLAMP_OPPOSITE( - *xc, 0, (int)mission->PickupCounts.size - 1); - } - break; + if (mission && mission->PickupCounts.size > 0) + { + *xc = CLAMP_OPPOSITE(*xc, 0, (int)mission->PickupCounts.size - 1); + } + break; default: break; @@ -491,7 +490,7 @@ static void Save(void) char dirname[CDOGS_PATH_MAX]; PathGetDirname(dirname, lastFile); char buf[CDOGS_PATH_MAX]; - if (TrySaveFile(buf, &gEventHandlers,dirname, PathGetBasename(lastFile))) + if (TrySaveFile(buf, &gEventHandlers, dirname, PathGetBasename(lastFile))) { WindowContextPreRender(&gGraphicsDevice.gameWindow); ClearScreen(&gGraphicsDevice); @@ -524,19 +523,20 @@ static void HelpScreen(void) "Common commands\n" "===============\n" "left/right click, page up/down: Increase/decrease value\n" - "shift + left/right click: Increase/decrease number of items\n" + "shift + left/right click: Increase/decrease number of " + "items\n" "insert: Add new item\n" "delete: Delete selected item\n" "arrow keys: Move camera\n" "\n" "Other commands\n" "==============\n" - "Escape: Back or quit\n" - KMOD_CMD_NAME "+E: Go to character editor\n" - KMOD_CMD_NAME"+N: New mission\n" - KMOD_CMD_NAME"+O: Open file\n" - KMOD_CMD_NAME"+S: Save file\n" - KMOD_CMD_NAME"+X, C, V: Cut/copy/paste\n" + "Escape: Back or quit\n" KMOD_CMD_NAME + "+E: Go to character editor\n" KMOD_CMD_NAME + "+N: New mission\n" KMOD_CMD_NAME + "+O: Open file\n" KMOD_CMD_NAME + "+S: Save file\n" KMOD_CMD_NAME + "+X, C, V: Cut/copy/paste\n" "tab: Preview automap\n" "F1: This screen\n"; WindowContextPreRender(&gGraphicsDevice.gameWindow); @@ -574,7 +574,7 @@ static void Delete(int xc, int yc) case YC_ITEMS: DeleteItem(mission, xc); break; - + case YC_PICKUPS: DeletePickup(mission, xc); break; @@ -607,7 +607,10 @@ static void Delete(int xc, int yc) Setup(changedMission); } -static UIObject *OnUIInput(HandleInputResult *result, const EventHandlers *event, const int m, int *xc, int *yc, int *xcOld, int *ycOld, SDL_Scancode *sc, const Mission *mission); +static UIObject *OnUIInput( + HandleInputResult *result, const EventHandlers *event, const int m, + int *xc, int *yc, int *xcOld, int *ycOld, SDL_Scancode *sc, + const Mission *mission); static void InputInsert(int *xc, const int yc, Mission *mission); static void InputDelete(const int xc, const int yc); static HandleInputResult HandleInput( @@ -667,7 +670,8 @@ static HandleInputResult HandleInput( if (m && (m == SDL_BUTTON_LEFT || m == SDL_BUTTON_RIGHT || MouseWheel(&gEventHandlers.mouse).y != 0)) { - o = OnUIInput(&result, &gEventHandlers, m, xc, yc, xcOld, ycOld, &sc, mission); + o = OnUIInput( + &result, &gEventHandlers, m, xc, yc, xcOld, ycOld, &sc, mission); } if (!brush.IsActive) { @@ -823,7 +827,9 @@ static HandleInputResult HandleInput( case 'c': MissionTerminate(scrap); MissionCopy(scrap, mission); - SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "Editor", "Mission copied", gGraphicsDevice.gameWindow.window); + SDL_ShowSimpleMessageBox( + SDL_MESSAGEBOX_INFORMATION, "Editor", "Mission copied", + gGraphicsDevice.gameWindow.window); break; case 'v': @@ -929,7 +935,9 @@ static HandleInputResult HandleInput( case SDL_SCANCODE_GRAVE: ToggleCollapse(sObjs->Data, 0); - OnUIInput(&result, &gEventHandlers, m, xc, yc, xcOld, ycOld, &sc, mission); + OnUIInput( + &result, &gEventHandlers, m, xc, yc, xcOld, ycOld, &sc, + mission); break; case SDL_SCANCODE_BACKSPACE: @@ -949,7 +957,7 @@ static HandleInputResult HandleInput( InputDelete(*xc, *yc); } break; - + case SDL_SCANCODE_TAB: result.WillDisplayAutomap = true; break; @@ -1016,7 +1024,10 @@ static HandleInputResult HandleInput( } return result; } -UIObject *OnUIInput(HandleInputResult *result, const EventHandlers *event, const int m, int *xc, int *yc, int *xcOld, int *ycOld, SDL_Scancode *sc, const Mission *mission) +UIObject *OnUIInput( + HandleInputResult *result, const EventHandlers *event, const int m, + int *xc, int *yc, int *xcOld, int *ycOld, SDL_Scancode *sc, + const Mission *mission) { result->Redraw = true; UIObject *o = NULL; @@ -1123,15 +1134,15 @@ static void InputInsert(int *xc, const int yc, Mission *mission) *xc = (int)(mission->MapObjectDensities.size - 1); } break; - + case YC_PICKUPS: { PickupCount pc; pc.P = PickupClassGetById(&gPickupClasses, 0); pc.Count = 1; - CArrayPushBack(&mission->PickupCounts, &pc); - *xc = (int)(mission->PickupCounts.size - 1); - } - break; + CArrayPushBack(&mission->PickupCounts, &pc); + *xc = (int)(mission->PickupCounts.size - 1); + } + break; default: if (yc >= YC_OBJECTIVES) @@ -1218,9 +1229,10 @@ int main(int argc, char *argv[]) // Print command line char buf[CDOGS_PATH_MAX]; - struct option longopts[] = {{"log", required_argument, NULL, 1000}, - {"logfile", required_argument, NULL, 1001}, - {0, 0, NULL, 0}}; + struct option longopts[] = { + {"log", required_argument, NULL, 1000}, + {"logfile", required_argument, NULL, 1001}, + {0, 0, NULL, 0}}; int opt = 0; int idx = 0; while ((opt = getopt_long(argc, argv, "\0:\0", longopts, &idx)) != -1) diff --git a/src/game.c b/src/game.c index 2625b3d4e..ec5a41c0e 100644 --- a/src/game.c +++ b/src/game.c @@ -665,9 +665,7 @@ static void RunGameDraw(GameLoopData *data) // Draw automap if enabled if (rData->isMap) { - AutomapDraw( - gGraphicsDevice.gameWindow.renderer, 0, - rData->Camera.HUD.showExit); + AutomapDraw(&gGraphicsDevice, NULL, 0, rData->Camera.HUD.showExit); } BlitUpdateFromBuf(&gGraphicsDevice, gGraphicsDevice.hud); @@ -677,7 +675,7 @@ static void RunGameDraw(GameLoopData *data) if (IsAutoMapEnabled(gCampaign.Entry.Mode)) { AutomapDraw( - gGraphicsDevice.secondWindow.renderer, 0, + &gGraphicsDevice, gGraphicsDevice.secondWindow.renderer, 0, rData->Camera.HUD.showExit); } BlitUpdateFromBuf(&gGraphicsDevice, gGraphicsDevice.hud2);