[Scummvm-git-logs] scummvm master -> 4dc20b7f941dfa87fff9e74e19f71fba1d702644
athrxx
noreply at scummvm.org
Sun Oct 4 14:24:51 UTC 2026
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
4dc20b7f94 KYRA: (EOB automap feature) - add special hard-coded map spots
Commit: 4dc20b7f941dfa87fff9e74e19f71fba1d702644
https://github.com/scummvm/scummvm/commit/4dc20b7f941dfa87fff9e74e19f71fba1d702644
Author: athrxx (athrxx at scummvm.org)
Date: 2026-10-04T16:11:48+02:00
Commit Message:
KYRA: (EOB automap feature) - add special hard-coded map spots
Added some hardcoded locations on the map, mainly
for level exits that don't have a stairway, teleporter, etc.
(e. g. Temple Darkmoon in the EOBII forest).
Also improved text spacing a bit for lower resolutions.
Changed paths:
engines/kyra/gui/automap_eob.cpp
engines/kyra/gui/automap_eob.h
diff --git a/engines/kyra/gui/automap_eob.cpp b/engines/kyra/gui/automap_eob.cpp
index b8c170146a8..046db0c5bb7 100644
--- a/engines/kyra/gui/automap_eob.cpp
+++ b/engines/kyra/gui/automap_eob.cpp
@@ -30,10 +30,10 @@
namespace Kyra {
-// Automap strings that should be translated to the game's language. Currently, only English is available.
+// Automap strings that should be translated to the game's language.
// TODO: Probably move to KYRA.DAT eventually.
const Automap_EoB::TranslateableStrings Automap_EoB::_stringTable[] = {
- {
+ { // English
{
"- LEGEND -",
"Party",
@@ -65,7 +65,7 @@ const Automap_EoB::TranslateableStrings Automap_EoB::_stringTable[] = {
// The FM-Towns version of EOBII has level names for its autogenerated savegame names
// which are similar to what we do (names based on the graphics/sound files).
{
- {
+ { // EOB I level names
"Upper Sewers",
"Middle Sewers",
"Lower Sewers",
@@ -83,7 +83,7 @@ const Automap_EoB::TranslateableStrings Automap_EoB::_stringTable[] = {
"",
""
},
- {
+ { // EOB II level names
"Catacombs I",
"Catacombs II",
"Catacombs III",
@@ -101,9 +101,20 @@ const Automap_EoB::TranslateableStrings Automap_EoB::_stringTable[] = {
"Crimson Tower I",
"Crimson Tower II"
}
+ },
+ {
+ { // EOB I special markers
+ "",
+ ""
+ },
+ { // EOB II special markers
+ "Temple Darkmoon",
+ "Hidden Stairway",
+ "Forest Exit"
+ }
}
},
- {
+ { // German
{
"- LEGENDE -",
"Gruppe",
@@ -117,7 +128,7 @@ const Automap_EoB::TranslateableStrings Automap_EoB::_stringTable[] = {
"Illusionswand",
"Kraftfeld",
"Schalter",
- "Interaktives Objekt",
+ "Interaktionsobjekt",
"Nische",
"Steinportal"
},
@@ -128,14 +139,8 @@ const Automap_EoB::TranslateableStrings Automap_EoB::_stringTable[] = {
"Esc/Tab", "Beenden"
},
- // Area names for the plaque. The games have no level names in their data and the file
- // names of the graphics and sound data files provide only vague hints. So we hardcode
- // the level names here. The Sega CD version of EOBI has an automap, but it doesn't use
- // level names. The maps are just called "L%d" or "Floor %d" (%d being the level number).
- // The FM-Towns version of EOBII has level names for its autogenerated savegame names
- // which are similar to what we do (names based on the graphics/sound files).
- {
- {
+ {
+ { // EOB I level names
"Kanalisation I",
"Kanalisation II",
"Kanalisation III",
@@ -153,7 +158,7 @@ const Automap_EoB::TranslateableStrings Automap_EoB::_stringTable[] = {
"",
""
},
- {
+ { // EOB II level names
"Katakomben I",
"Katakomben II",
"Katakomben III",
@@ -171,15 +176,34 @@ const Automap_EoB::TranslateableStrings Automap_EoB::_stringTable[] = {
"Purpurturm I",
"Purpurturm II"
}
+ },
+ {
+ { // EOB I special markers
+ "",
+ ""
+ },
+ { // EOB II special markers
+ "Tempel Darkmoon",
+ "Versteckte Treppe",
+ "Ausgang zum Wald"
+ }
}
}
};
+// These are manual map entries for certain location that deserve a marker.
+// Currently, we use them for level exits that would otherwise have no map entry.
+const Automap_EoB::SpecialMarkers Automap_EoB::_specialMarkersEOB2[] = {
+ { 04, 0x14F, kColorSpecial7 }, // Temple Darkmoon
+ { 04, 0x211, kColorSpecial2 }, // Hidden Stairway
+ { 05, 0x12F, kColorSpecial1 } // Forest Exit
+};
+
Automap_EoB::Automap_EoB(OSystem *system, LevelBlockProperty **blockData, const uint8 *wllFlags, const uint8 *specialWallTypes, const int8 *wllShapeMap, /* const uint8 *wllVmpMap,*/ int gameID, int lang, bool featureEnabled) :
_system(system), _blockData(*blockData), _wllWallFlags(wllFlags), _specialWallTypes(specialWallTypes), _wllShapeMap(wllShapeMap), /*_wllVmpMap(wllVmpMap),*/ _enabled(featureEnabled), _visible(false), _background(nullptr),
_frame(nullptr), _specialBlockIDs(nullptr), _levelNames(nullptr), _colors(nullptr), _legendStrings(nullptr), _controlStrings(nullptr), _numLevelNames(gameID == GI_EOB1 ? 12 : (gameID == GI_EOB2 ? 16 : 0)), _l(),
_wallOfForceID(gameID == GI_EOB1 ? 0xFF : 74), _portalParamsLen(0), _portalParams(nullptr), _drawIcon(nullptr), _legendHeadScl(1), _legendBodyScl(1), _levelStrScl(1), _coordStrScl(1), _levelStrY(0), _coordStrY(0),
- _partyIconColor(kColorPartyFrame0), _partyIconColorStep(1) {
+ _partyIconColor(kColorPartyFrame0), _partyIconColorStep(1), _specialMarkers(nullptr), _numSpecialMarkers(0), _specialMarkerStrings(nullptr), _reduceSpace(0) {
_background = new Graphics::Surface();
_frame = new Graphics::Surface();
@@ -202,6 +226,12 @@ Automap_EoB::Automap_EoB(OSystem *system, LevelBlockProperty **blockData, const
_legendStrings = _stringTable[langIndex].legendStrings;
_controlStrings = _stringTable[langIndex].controlStrings;
_levelNames = _stringTable[langIndex].levelNames[gameIndex];
+ _specialMarkerStrings = _stringTable[langIndex].specialMarkerStrings[gameIndex];
+
+ if (gameID == GI_EOB2) {
+ _specialMarkers = _specialMarkersEOB2;
+ _numSpecialMarkers = ARRAYSIZE(_specialMarkersEOB2);
+ }
const uint8 teleporter = gameID == GI_EOB1 ? 52 : 44;
const uint8 illusion1 = gameID == GI_EOB1 ? 67 : 46;
@@ -510,8 +540,17 @@ void Automap_EoB::draw(int level, uint16 partyBlock, int8 partyDirection) {
(this->*_drawIcon)(surf, 0, kIconBigObject, sx, sy, _l.cell, kAlignCenter, 0, 0, -1);
legendFlags |= 0x2000;
} else {
- // Special blocks
-
+ // Hard coded special blocks. Mostly used for level exits that are neither stairs nor teleporters (e. g. Temple Darkmoon in the EOBII forest).
+ for (int i = 0, flc = 0; i < _numSpecialMarkers; ++i) {
+ if (level != _specialMarkers[i].level)
+ continue;
+ if (block == _specialMarkers[i].block) {
+ (this->*_drawIcon)(surf, 0, kIconSpecial, sx, sy, _l.cell, kAlignCenter, 0, 0, _specialMarkers[i].iconColor);
+ legendFlags |= (0x20000 << flc);
+ break;
+ }
+ ++flc;
+ }
/* for (int ii = 0; ii < 4; ++ii) {
if (_wllVmpMap[bp->walls[ii]] != 1)
@@ -523,6 +562,7 @@ void Automap_EoB::draw(int level, uint16 partyBlock, int8 partyDirection) {
}
}*/
+ // stairs, teleporters, pits, plates, etc.
for (int i = 0; i < _numSpecialBlockIDs; ++i) {
uint8 s = _specialBlockIDs[i].wall;
// This is a bit tricky due to glitchy game data. EOBII puts the special wall type on all four walls of a block, but EOBI does not, so we can't
@@ -555,7 +595,7 @@ void Automap_EoB::draw(int level, uint16 partyBlock, int8 partyDirection) {
legendFlags |= (1 << partyDirection);
}
- drawLegend(legendFlags);
+ drawLegend(level, legendFlags);
const Graphics::Font *bigFont = FontMan.getFontByUsage(Graphics::FontManager::kBigGUIFont);
if (bigFont) {
@@ -640,17 +680,35 @@ void Automap_EoB::recalcScaling(int width, int height) {
int fh = bigFont ? bigFont->getFontHeight() : 8;
int scl = CLIP<int>(MIN<int>(width / 320, height / 200), 1, 12);
- _legendHeadScl = fitString(bigFont, _legendStrings[0], _l.plW * 4 / 5, scl);
+ _legendHeadScl = MAX<int>(fitString(bigFont, _legendStrings[0], _l.plW * 4 / 5, scl), 1);
- int isz = 2 * _l.cell + MAX(2, _legendHeadScl * 2);
- int tw = _l.plW - isz;
_legendBodyScl = 12;
- for (int i = 1; i < kNumLegendStrings; ++i)
+ int isz = 2 * fh + MAX(2, _legendHeadScl * 2);
+ int tw = _l.plW - isz;
+
+ for (int i = 1; i < kNumLegendStrings; ++i) {
_legendBodyScl = MIN<int>(_legendBodyScl, fitString(bigFont, _legendStrings[i], tw, _legendBodyScl));
+ if (_legendBodyScl > 1)
+ _legendBodyScl = MIN<int>(_legendBodyScl, fitString(bigFont, _legendStrings[i], tw + (_legendBodyScl - 1) * 2 * fh, _legendBodyScl));
+
+ if (_legendBodyScl == 0) {
+ _legendBodyScl = MIN<int>(_legendBodyScl, fitString(bigFont, _legendStrings[i], tw - MAX(2, _legendHeadScl * 2), _legendBodyScl));
+ _reduceSpace = 1;
+ }
+ }
+ if (_legendBodyScl == 0) {
+ _legendBodyScl = 1;
+ ++_reduceSpace;
+ }
+
for (int i = 2; i < kNumControlStrings; i += 2) {
Common::String str = Common::String::format("%s %s", _controlStrings[i], _controlStrings[i + 1]);
_legendBodyScl = MIN<int>(_legendBodyScl, fitString(bigFont, str, _l.plW, _legendBodyScl));
}
+ if (_legendBodyScl == 0) {
+ _legendBodyScl = 1;
+ ++_reduceSpace;
+ }
int pm = MAX<int>(3, scl * 2);
int innerW = _l.plW - 2 * pm;
@@ -701,6 +759,13 @@ void Automap_EoB::createColorTable() {
{ 0xf0, 0xc8, 0x50 }, // gold
{ 0xb8, 0x92, 0x3a }, // gold dim
{ 0xd8, 0xc8, 0xa8 }, // panel text
+ { 0x33, 0x88, 0x99 }, // special location 1
+ { 0x99, 0x44, 0x44 }, // special location 2
+ { 0x66, 0x66, 0x66 }, // special location 3
+ { 0xff, 0xaa, 0x44 }, // special location 4
+ { 0x33, 0xff, 0xaa }, // special location 5
+ { 0xff, 0x44, 0x44 }, // special location 6
+ { 0x55, 0x55, 0xff }, // special location 7
{ 0xfe, 0x12, 0xfe }, // transparency key
{ 0xa8, 0x28, 0x1c }, // party frame 0
{ 0xff, 0xff, 0xff }, // party frame 1 (placeholder, correct values will be calculated)
@@ -723,7 +788,7 @@ void Automap_EoB::createColorTable() {
// Create color gradient for the party icon frames (we let it blink for better visibility).
float algoBase = 1.25f; // It looks much better with a non-linear gradient.
int div = 0;
- for (int i = 0; i < 10; ++i)
+ for (int i = 0; i < (kNumColors - kColorPartyFrame0); ++i)
div += powf(algoBase, i);
int stepR = (rgbTable[kColorPartyFrame9][0] - rgbTable[kColorPartyFrame0][0]) * 0x10000 / div;
@@ -734,7 +799,7 @@ void Automap_EoB::createColorTable() {
uint32 curG = rgbTable[kColorPartyFrame0][1] * 0x10000;
uint32 curB = rgbTable[kColorPartyFrame0][2] * 0x10000;
- for (int i = 0; i < 10; ++i) {
+ for (int i = 0; i < (kNumColors - kColorPartyFrame0); ++i) {
colors[kColorPartyFrame0 + i] = fmt.RGBToColor(curR >> 16, curG >> 16, curB >> 16);
curR += stepR * powf(algoBase, i);
curG += stepG * powf(algoBase, i);
@@ -895,6 +960,13 @@ void Automap_EoB::createIcons(bool lowResTarget) {
surf.fillRect(Common::Rect(doorWdth, doorLen), colTable[kColorDoor]);
break;
case kIconSpecial:
+ prepSurface(size2full, size2full, -1);
+ for (int i = 0; i < 360; i += 45) {
+ for (int ii = -10; ii < 10; ++ii) {
+ float a = (float)((360 + i + ii) % 360) * M_PI / 180.0f;
+ surf.drawLine(size2half + size2half * cosf(a), size2half + size2half * sinf(a), size2half + (size2half / 3) * cosf(a), size2half + (size2half / 3) * sinf(a), colTable[kColorPartyFrame0]);
+ }
+ }
break;
default:
break;
@@ -1027,7 +1099,7 @@ void Automap_EoB::drawBackground(int width, int height) {
bg.hLine(_l.plX, cyy + 1, _l.plX + _l.plW - 1, _colors[kColorStoneEdge]);
}
-void Automap_EoB::drawLegend(uint flags) {
+void Automap_EoB::drawLegend(int level, uint flags) {
Graphics::Surface &bg = *_frame;
const Graphics::Font *bigFont = FontMan.getFontByUsage(Graphics::FontManager::kBigGUIFont);
int fh = bigFont ? bigFont->getFontHeight() : 8;
@@ -1055,7 +1127,7 @@ void Automap_EoB::drawLegend(uint flags) {
assert(ARRAYSIZE(legendIcons) == kNumLegendStrings + 2); // ignore first string (title), but there is also only one string for the party (regardless of direction)
int lh = fh * _legendBodyScl;
- int isz = 2 * lh + MAX(2, _legendHeadScl * 2);
+ int isz = 2 * lh + (1 - _reduceSpace) * MAX(2, _legendHeadScl * 2);
int tw = _l.plW - isz;
int rowH = lh + MAX(4, _legendBodyScl * 4);
@@ -1080,6 +1152,28 @@ void Automap_EoB::drawLegend(uint flags) {
cyy += rowH;
}
+ // Now, the special locations, if we have any...
+ flags &= ~0x1ffff;
+ for (int i = 0; i < 7; ++i) {
+ if (!(flags & (0x20000 << i)))
+ continue;
+
+ int id = i;
+ for (int ii = 0; ii < _numSpecialMarkers && id >= 0; ++ii) {
+ if (_specialMarkers[ii].level != level)
+ continue;
+ if (id-- == 0) {
+ id = ii;
+ break;
+ }
+ }
+
+ (this->*_drawIcon)(bg, 1, kIconSpecial, _l.plX, cyy, lh, kAlignCenter, 0, 0, _specialMarkers[id].iconColor);
+
+ drawString(bg, bigFont, _specialMarkerStrings[id], tx, cyy, tw, _colors[kColorPanelTxt], _legendBodyScl, Graphics::kTextAlignLeft);
+ cyy += rowH;
+ }
+
cyy += MAX(4, _legendHeadScl * 4);
drawString(bg, bigFont, _controlStrings[0], _l.plX, cyy, _l.plW, _colors[kColorGoldDim], _legendHeadScl);
cyy += fh * _legendHeadScl + MAX(4, _legendHeadScl * 3);
@@ -1091,7 +1185,7 @@ void Automap_EoB::drawLegend(uint flags) {
int maxW = 0;
for (int i = 2; i < kNumControlStrings; i += 2)
- maxW = MAX<int>(maxW, (bigFont ? bigFont->getStringWidth(_controlStrings[i]) * _legendBodyScl : 6 * _legendBodyScl) + chipPad * 2);
+ maxW = MAX<int>(maxW, (bigFont ? bigFont->getStringWidth(_controlStrings[i]) * _legendBodyScl : 6 * _legendBodyScl) + chipPad * 2 - _reduceSpace);
for (int i = 2; i < kNumControlStrings; i += 2) {
int chipW = (bigFont ? bigFont->getStringWidth(_controlStrings[i]) * _legendBodyScl : 6 * _legendBodyScl) + chipPad * 2;
@@ -1163,7 +1257,7 @@ template void Automap_EoB::drawIconImpl<uint32>(Graphics::Surface&, int, int, in
int Automap_EoB::fitString(const Graphics::Font *f, const Common::String &str, int maxW, int maxSc) const {
Common::U32String u32str(str.c_str(), Common::CodePage::kUtf8);
int wdth = f ? f->getStringWidth(u32str) : 0;
- return (wdth == 0) ? 1 : CLIP<int>(maxW / wdth, 1, maxSc);
+ return (wdth == 0) ? 0 : CLIP<int>(maxW / wdth, 0, maxSc);
}
uint16 Automap_EoB::calcNewBlockPosition(uint16 block, int8 dir) const {
diff --git a/engines/kyra/gui/automap_eob.h b/engines/kyra/gui/automap_eob.h
index c79fe3bbf3f..475c8d3508b 100644
--- a/engines/kyra/gui/automap_eob.h
+++ b/engines/kyra/gui/automap_eob.h
@@ -76,6 +76,13 @@ private:
const char *const legendStrings[kNumLegendStrings];
const char *const controlStrings[kNumControlStrings];
const char *const levelNames[2][16];
+ const char *const specialMarkerStrings[2][3];
+ };
+
+ struct SpecialMarkers {
+ int8 level;
+ uint16 block;
+ int8 iconColor;
};
enum IconID : int {
@@ -110,7 +117,7 @@ private:
void createIcons(bool lowResSurface);
void releaseIcons();
void drawBackground(int width, int height);
- void drawLegend(uint flags);
+ void drawLegend(int level, uint flags);
enum IconAlignment : int {
kAlignTopLeft = -1,
@@ -167,11 +174,17 @@ private:
const char *const *_levelNames;
const int _numLevelNames;
+ static const SpecialMarkers _specialMarkersEOB2[];
+ const SpecialMarkers *_specialMarkers;
+ const char *const *_specialMarkerStrings;
+ int _numSpecialMarkers;
+
AutomapLayout _l;
int _levelStrScl;
int _coordStrScl;
int _legendHeadScl;
int _legendBodyScl;
+ int _reduceSpace;
int _levelStrY;
int _coordStrY;
@@ -214,6 +227,13 @@ private:
kColorGold,
kColorGoldDim,
kColorPanelTxt,
+ kColorSpecial1,
+ kColorSpecial2,
+ kColorSpecial3,
+ kColorSpecial4,
+ kColorSpecial5,
+ kColorSpecial6,
+ kColorSpecial7,
kColorTransp,
kColorPartyFrame0,
kColorPartyFrame1,
@@ -228,7 +248,7 @@ private:
kNumColors
};
- const uint32 *_colors;
+ /* const */uint32 *_colors;
int _partyIconColor;
int _partyIconColorStep;
};
More information about the Scummvm-git-logs
mailing list