aboutsummaryrefslogtreecommitdiff
path: root/engines/dm
diff options
context:
space:
mode:
authorBendegúz Nagy2016-08-26 22:35:29 +0200
committerBendegúz Nagy2016-08-26 23:02:22 +0200
commit9d7cfe5cd8cc5ba12b544c0da2e8d3d1f84133fa (patch)
treea0325987a546a2b4e442302eda5d067921249142 /engines/dm
parent204853952295bf6504921979db32d6c10909131a (diff)
downloadscummvm-rg350-9d7cfe5cd8cc5ba12b544c0da2e8d3d1f84133fa.tar.gz
scummvm-rg350-9d7cfe5cd8cc5ba12b544c0da2e8d3d1f84133fa.tar.bz2
scummvm-rg350-9d7cfe5cd8cc5ba12b544c0da2e8d3d1f84133fa.zip
DM: Add several functions realted to text display
Add F0290_CHAMPION_DrawHealthStaminaManaValues, F0289_CHAMPION_DrawHealthOrStaminaOrManaValue, F0288_CHAMPION_GetStringFromInteger, F0052_TEXT_PrintToViewport, swap warning for real code, expand viewport fields with width, height, remove self-inclusion in dungeonman.h, remove extra black line when loading fonts, fix alignment error in TextMan::printTextToBitmap
Diffstat (limited to 'engines/dm')
-rw-r--r--engines/dm/champion.cpp1101
-rw-r--r--engines/dm/champion.h5
-rw-r--r--engines/dm/dungeonman.cpp1
-rw-r--r--engines/dm/dungeonman.h1
-rw-r--r--engines/dm/gfx.cpp8
-rw-r--r--engines/dm/gfx.h4
-rw-r--r--engines/dm/inventory.cpp7
-rw-r--r--engines/dm/text.cpp26
-rw-r--r--engines/dm/text.h5
9 files changed, 598 insertions, 560 deletions
diff --git a/engines/dm/champion.cpp b/engines/dm/champion.cpp
index ff3e5f700e..79f4267c7d 100644
--- a/engines/dm/champion.cpp
+++ b/engines/dm/champion.cpp
@@ -1,538 +1,563 @@
-#include "champion.h"
-#include "dungeonman.h"
-#include "eventman.h"
-#include "menus.h"
-#include "inventory.h"
-#include "objectman.h"
-
-
-namespace DM {
-
-Box gBoxMouth = Box(55, 72, 12, 29); // @ G0048_s_Graphic562_Box_Mouth
-Box gBoxEye = Box(11, 28, 12, 29); // @ G0049_s_Graphic562_Box_Eye
-Box gBoxChampionIcons[4] = { // @ G0054_ai_Graphic562_Box_ChampionIcons
- Box(281, 299, 0, 13),
- Box(301, 319, 0, 13),
- Box(301, 319, 15, 28),
- Box(281, 299, 15, 28)};
-Color gChampionColor[4] = {(Color)7, (Color)11, (Color)8, (Color)14}; // @ G0046_auc_Graphic562_ChampionColor
-
-uint16 gSlotMasks[38] = { // @ G0038_ai_Graphic562_SlotMasks
- /* 30 for champion inventory, 8 for chest */
- 0xFFFF, /* Ready Hand Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
- 0xFFFF, /* Action Hand Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
- 0x0002, /* Head Head */
- 0x0008, /* Torso Torso */
- 0x0010, /* Legs Legs */
- 0x0020, /* Feet Feet */
- 0x0100, /* Pouch 2 Pouch */
- 0x0080, /* Quiver Line2 1 Quiver 2 */
- 0x0080, /* Quiver Line1 2 Quiver 2 */
- 0x0080, /* Quiver Line2 2 Quiver 2 */
- 0x0004, /* Neck Neck */
- 0x0100, /* Pouch 1 Pouch */
- 0x0040, /* Quiver Line1 1 Quiver 1 */
- 0xFFFF, /* Backpack Line1 1 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
- 0xFFFF, /* Backpack Line2 2 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
- 0xFFFF, /* Backpack Line2 3 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
- 0xFFFF, /* Backpack Line2 4 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
- 0xFFFF, /* Backpack Line2 5 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
- 0xFFFF, /* Backpack Line2 6 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
- 0xFFFF, /* Backpack Line2 7 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
- 0xFFFF, /* Backpack Line2 8 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
- 0xFFFF, /* Backpack Line2 9 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
- 0xFFFF, /* Backpack Line1 2 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
- 0xFFFF, /* Backpack Line1 3 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
- 0xFFFF, /* Backpack Line1 4 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
- 0xFFFF, /* Backpack Line1 5 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
- 0xFFFF, /* Backpack Line1 6 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
- 0xFFFF, /* Backpack Line1 7 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
- 0xFFFF, /* Backpack Line1 8 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
- 0xFFFF, /* Backpack Line1 9 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
- 0x0400, /* Chest 1 Chest */
- 0x0400, /* Chest 2 Chest */
- 0x0400, /* Chest 3 Chest */
- 0x0400, /* Chest 4 Chest */
- 0x0400, /* Chest 5 Chest */
- 0x0400, /* Chest 6 Chest */
- 0x0400, /* Chest 7 Chest */
- 0x0400}; /* Chest 8 Chest */
-
-Box gBoxChampionPortrait = Box(0, 31, 0, 28); // @ G0047_s_Graphic562_Box_ChampionPortrait
-
-ChampionMan::ChampionMan(DMEngine *vm) : _vm(vm) {
- _leaderIndex = kChampionNone;
-
- _partyDead = false;
- _partyIsSleeping = false;
- _leaderHandObjectIconIndex = kIconIndiceNone;
- _leaderEmptyHanded = true;
-}
-
-uint16 ChampionMan::getChampionPortraitX(uint16 index) {
- return ((index) & 0x7) << 5;
-}
-
-uint16 ChampionMan::getChampionPortraitY(uint16 index) {
- return ((index) >> 3) * 29;
-}
-
-int16 ChampionMan::getDecodedValue(char *string, uint16 characterCount) {
- int val = 0;
- for (uint16 i = 0; i < characterCount; ++i) {
- val = (val << 4) + (string[i] - 'A');
- }
- return val;
-}
-
-ChampionIndex ChampionMan::getIndexInCell(ViewCell cell) {
- for (uint16 i = 0; i < _partyChampionCount; ++i) {
- if ((_champions[i]._cell == cell) && _champions[i]._currHealth)
- return (ChampionIndex)i;
- }
-
- return kChampionNone;
-}
-
-void ChampionMan::resetDataToStartGame() {
- if (!_vm->_dungeonMan->_messages._newGame) {
- warning("MISSING CODE: stuff for resetting for loaded games");
- assert(false);
- }
-
- _leaderHand = Thing::_thingNone;
- _leaderHandObjectIconIndex = kIconIndiceNone;
- _leaderEmptyHanded = true;
-}
-
-
-void ChampionMan::addCandidateChampionToParty(uint16 championPortraitIndex) {
- DisplayMan &dispMan = *_vm->_displayMan;
- DungeonMan &dunMan = *_vm->_dungeonMan;
-
- if (!_leaderEmptyHanded || _partyChampionCount == 4)
- return;
-
- uint16 prevChampCount = _partyChampionCount;
- Champion *champ = &_champions[prevChampCount];
- champ->resetToZero();
- dispMan._useByteBoxCoordinates = true;
- { // limit destBox scope
- Box &destBox = gBoxChampionPortrait;
- dispMan.blitToBitmap(dispMan.getBitmap(kChampionPortraitsIndice), 256, getChampionPortraitX(championPortraitIndex), getChampionPortraitY(championPortraitIndex),
- champ->_portrait, 32, destBox._x1, destBox._x2, destBox._y1, destBox._y2, kColorNoTransparency);
- }
-
- champ->_actionIndex = kChampionActionNone;
- champ->_enableActionEventIndex = -1;
- champ->_hideDamageReceivedIndex = -1;
- champ->_dir = dunMan._currMap._partyDir;
- ViewCell AL_0_viewCell = kViewCellFronLeft;
- while (getIndexInCell((ViewCell)((AL_0_viewCell + dunMan._currMap._partyDir) & 3)) != kChampionNone)
- AL_0_viewCell = (ViewCell)(AL_0_viewCell + 1);
- champ->_cell = (ViewCell)((AL_0_viewCell + dunMan._currMap._partyDir) & 3);
- champ->clearAttributes(kChampionAttributeIcon);
- champ->_directionMaximumDamageReceived = dunMan._currMap._partyDir;
- champ->_food = 1500 + _vm->_rnd->getRandomNumber(256);
- champ->_water = 1500 + _vm->_rnd->getRandomNumber(256);
- int16 AL_0_slotIndex_Red;
- for (AL_0_slotIndex_Red = kChampionSlotReadyHand; AL_0_slotIndex_Red < kChampionSlotChest_1; ++AL_0_slotIndex_Red) {
- champ->setSlot((ChampionSlot)AL_0_slotIndex_Red, Thing::_thingNone);
- }
- Thing thing = dunMan.getSquareFirstThing(dunMan._currMap._partyPosX, dunMan._currMap._partyPosY);
- while (thing.getType() != kTextstringType) {
- thing = dunMan.getNextThing(thing);
- }
- char decodedChampionText[77];
- char* character_Green = decodedChampionText;
- dunMan.decodeText(character_Green, thing, (TextType)(kTextTypeScroll | kDecodeEvenIfInvisible));
- int16 AL_0_characterIndex = 0;
- uint16 AL_2_character;
- while ((AL_2_character = *character_Green++) != '\n') {
- champ->_name[AL_0_characterIndex++] = AL_2_character;
- }
- champ->_name[AL_0_characterIndex] = '\0';
- AL_0_characterIndex = 0;
- bool AL_4_champTitleCopied = false;
- for (;;) { // infinite
- AL_2_character = *character_Green++;
- if (AL_2_character == '\n') {
- if (AL_4_champTitleCopied)
- break;
- AL_4_champTitleCopied = true;
- } else {
- champ->_title[AL_0_characterIndex++] = AL_2_character;
- }
- }
- champ->_title[AL_0_characterIndex] = '\0';
- if (*character_Green++ == 'M') {
- champ->setAttributeFlag(kChampionAttributeMale, true);
- }
- character_Green++;
- champ->_currHealth = champ->_maxHealth = getDecodedValue(character_Green, 4);
- character_Green += 4;
- champ->_currStamina = champ->_maxStamina = getDecodedValue(character_Green, 4);
- character_Green += 4;
- champ->_currMana = champ->_maxMana = getDecodedValue(character_Green, 4);
- character_Green += 4;
- character_Green++;
-
- int16 AL_0_statisticIndex;
- for (AL_0_statisticIndex = kChampionStatLuck; AL_0_statisticIndex <= kChampionStatAntifire; ++AL_0_statisticIndex) {
- champ->setStatistic((ChampionStatisticType)AL_0_statisticIndex, kChampionStatMinimum, 30);
- uint16 currMaxVal = getDecodedValue(character_Green, 2);
- champ->setStatistic((ChampionStatisticType)AL_0_statisticIndex, kChampionStatCurrent, currMaxVal);
- champ->setStatistic((ChampionStatisticType)AL_0_statisticIndex, kChampionStatMaximum, currMaxVal);
- character_Green += 2;
- }
-
- champ->setStatistic(kChampionStatLuck, kChampionStatMinimum, 10);
- character_Green++;
-
- int16 AL_0_skillIndex;
- int16 AL_2_skillValue;
- for (AL_0_skillIndex = kChampionSkillSwing; AL_0_skillIndex <= kChampionSkillWater; AL_0_skillIndex++) {
- if ((AL_2_skillValue = *character_Green++ - 'A') > 0) {
- champ->setSkillExp((ChampionSkill)AL_0_skillIndex, 125L << AL_2_skillValue);
- }
- }
-
- for (AL_0_skillIndex = kChampionSkillFighter; AL_0_skillIndex <= kChampionSkillWizard; ++AL_0_skillIndex) {
- int32 baseSkillExp = 0;
- int16 hiddenSkillIndex = (AL_0_skillIndex + 1) << 2;
- for (uint16 AL_4_hiddenSkillCounter = 0; AL_4_hiddenSkillCounter < 4; ++AL_4_hiddenSkillCounter) {
- baseSkillExp += champ->getSkill((ChampionSkill)(hiddenSkillIndex + AL_4_hiddenSkillCounter))._experience;
- }
- champ->setSkillExp((ChampionSkill)AL_0_skillIndex, baseSkillExp);
- }
-
- _candidateChampionOrdinal = prevChampCount + 1;
- if (++_partyChampionCount == 1) {
- _vm->_eventMan->commandSetLeader(kChampionFirst);
- _vm->_menuMan->_shouldRefreshActionArea = true;
- } else {
- _vm->_menuMan->clearActingChampion();
- _vm->_menuMan->drawActionIcon((ChampionIndex)(_partyChampionCount - 1));
- }
-
- int16 mapX = _vm->_dungeonMan->_currMap._partyPosX;
- int16 mapY = _vm->_dungeonMan->_currMap._partyPosY;
-
- uint16 championObjectsCell = returnOppositeDir((direction)(dunMan._currMap._partyDir));
- mapX += _dirIntoStepCountEast[dunMan._currMap._partyDir];
- mapY += _dirIntoStepCountNorth[dunMan._currMap._partyDir];
- thing = dunMan.getSquareFirstThing(mapX, mapY);
- AL_0_slotIndex_Red = kChampionSlotBackpackLine_1_1;
- uint16 slotIndex_Green;
- while (thing != Thing::_thingEndOfList) {
- ThingType AL_2_thingType = thing.getType();
- if ((AL_2_thingType > kSensorThingType) && (thing.getCell() == championObjectsCell)) {
- int16 objectAllowedSlots = gObjectInfo[dunMan.getObjectInfoIndex(thing)].getAllowedSlots();
- switch (AL_2_thingType) {
- case kArmourThingType:
- for (slotIndex_Green = kChampionSlotHead; slotIndex_Green <= kChampionSlotFeet; slotIndex_Green++) {
- if (objectAllowedSlots & gSlotMasks[slotIndex_Green])
- goto T0280048;
- }
- if ((objectAllowedSlots & gSlotMasks[kChampionSlotNeck]) && (champ->getSlot(kChampionSlotNeck) == Thing::_thingNone)) {
- slotIndex_Green = kChampionSlotNeck;
- } else {
- goto T0280046;
- }
- break;
- case kWeaponThingType:
- if (champ->getSlot(kChampionSlotActionHand) == Thing::_thingNone) {
- slotIndex_Green = kChampionSlotActionHand;
- } else {
- goto T0280046;
- }
- break;
- case kScrollThingType:
- case kPotionThingType:
- if (champ->getSlot(kChampionSlotPouch_1) == Thing::_thingNone) {
- slotIndex_Green = kChampionSlotPouch_1;
- } else if (champ->getSlot(kChampionSlotPouch_2) == Thing::_thingNone) {
- slotIndex_Green = kChampionSlotPouch_2;
- } else {
- goto T0280046;
- }
- break;
- case kContainerThingType:
- case kJunkThingType:
-T0280046:
- if ((objectAllowedSlots & gSlotMasks[kChampionSlotNeck]) && (champ->getSlot(kChampionSlotNeck) == Thing::_thingNone)) {
- slotIndex_Green = kChampionSlotNeck;
- } else {
- slotIndex_Green = AL_0_slotIndex_Red++;
- }
- break;
- }
-T0280048:
- if (champ->getSlot((ChampionSlot)slotIndex_Green) != Thing::_thingNone) {
- goto T0280046;
- }
- warning("MISSING CODE: F0301_CHAMPION_AddObjectInSlot");
- }
- thing = dunMan.getNextThing(thing);
- }
-
- _vm->_inventoryMan->toggleInventory((ChampionIndex)prevChampCount);
- _vm->_menuMan->drawDisabledMenu();
-}
-
-void ChampionMan::drawChampionBarGraphs(ChampionIndex champIndex) {
-
- Champion *curChampion = &_champions[champIndex];
- int16 barGraphIndex = 0;
- int16 barGraphHeightArray[3];
-
- if (curChampion->_currHealth > 0) {
- uint32 barGraphHeight = (((uint32)(curChampion->_currHealth) << 10) * 25) / curChampion->_maxHealth;
- if (barGraphHeight & 0x3FF) {
- barGraphHeightArray[barGraphIndex++] = (barGraphHeight >> 10) + 1;
- } else {
- barGraphHeightArray[barGraphIndex++] = (barGraphHeight >> 10);
- }
- } else {
- barGraphHeightArray[barGraphIndex++] = 0;
- }
-
- if (curChampion->_currStamina > 0) {
- uint32 barGraphHeight = (((uint32)(curChampion->_currStamina) << 10) * 25) / curChampion->_maxStamina;
- if (barGraphHeight & 0x3FF) {
- barGraphHeightArray[barGraphIndex++] = (barGraphHeight >> 10) + 1;
- } else {
- barGraphHeightArray[barGraphIndex++] = (barGraphHeight >> 10);
- }
- } else {
- barGraphHeightArray[barGraphIndex++] = 0;
- }
-
- if (curChampion->_currMana > 0) {
- uint32 barGraphHeight = (((uint32)(curChampion->_currMana) << 10) * 25) / curChampion->_maxMana;
- if (barGraphHeight & 0x3FF) {
- barGraphHeightArray[barGraphIndex++] = (barGraphHeight >> 10) + 1;
- } else {
- barGraphHeightArray[barGraphIndex++] = (barGraphHeight >> 10);
- }
- } else {
- barGraphHeightArray[barGraphIndex++] = 0;
- }
- warning("MISSING CODE: F0077_MOUSE_HidePointer_CPSE");
-
- Box box;
- box._x1 = champIndex * kChampionStatusBoxSpacing + 46;
- box._x2 = box._x1 + 3 + 1;
- box._y1 = 2;
- box._y2 = 26 + 1;
-
- for (int16 AL_0_barGraphIndex = 0; AL_0_barGraphIndex < 3; AL_0_barGraphIndex++) {
- int16 barGraphHeight = barGraphHeightArray[AL_0_barGraphIndex];
- if (barGraphHeight < 25) {
- box._y1 = 2;
- box._y1 = 27 - barGraphHeight + 1;
- _vm->_displayMan->clearScreenBox(gChampionColor[champIndex], box);
- }
- if (barGraphHeight) {
- box._y1 = 27 - barGraphHeight;
- box._y2 = 26 + 1;
- _vm->_displayMan->clearScreenBox(gChampionColor[champIndex], box);
- }
- box._x1 += 7;
- box._x2 += 7;
- }
- warning("MISSING CODE: F0078_MOUSE_ShowPointer");
-}
-
-
-uint16 ChampionMan::getStaminaAdjustedValue(Champion *champ, int16 val) {
- int16 currStamina = champ->_currStamina;
- int16 halfMaxStamina = champ->_maxStamina / 2;
- if (currStamina < halfMaxStamina) {
- warning("Possible undefined behavior in the original code");
- val /= 2;
- return val + ((uint32)val * (uint32)currStamina) / halfMaxStamina;
- }
- return val;
-}
-
-uint16 ChampionMan::getMaximumLoad(Champion *champ) {
- uint16 maximumLoad = champ->getStatistic(kChampionStatStrength, kChampionStatCurrent) * 8 + 100;
- maximumLoad = getStaminaAdjustedValue(champ, maximumLoad);
- int16 wounds = champ->getWounds();
- if (wounds) {
- maximumLoad -= maximumLoad >> (champ->getWoundsFlag(kChampionWoundLegs) ? 2 : 3);
- }
- if (_vm->_objectMan->getIconIndex(champ->getSlot(kChampionSlotFeet)) == kIconIndiceArmourElvenBoots) {
- maximumLoad += maximumLoad * 16;
- }
- maximumLoad += 9;
- maximumLoad -= maximumLoad % 10;
- return maximumLoad;
-}
-
-void ChampionMan::drawChampionState(ChampionIndex champIndex) {
- InventoryMan &invMan = *_vm->_inventoryMan;
- DisplayMan &dispMan = *_vm->_displayMan;
- MenuMan &menuMan = *_vm->_menuMan;
- EventManager &eventMan = *_vm->_eventMan;
-
- Box box;
- int16 champStatusBoxX = champIndex * kChampionStatusBoxSpacing;
- Champion *champ = &_champions[champIndex];
- uint16 champAttributes = champ->getAttributes();
- if (!((champAttributes) & (kChampionAttributeNameTitle | kChampionAttributeStatistics | kChampionAttributeLoad | kChampionAttributeIcon |
- kChampionAttributePanel | kChampionAttributeStatusBox | kChampionAttributeWounds | kChampionAttributeViewport |
- kChampionAttributeActionHand))) {
- return;
- }
- bool isInventoryChamp = (indexToOrdinal(champIndex) == invMan._inventoryChampionOrdinal);
- dispMan._useByteBoxCoordinates = false;
- if (champAttributes & kChampionAttributeStatusBox) {
- box._y1 = 0;
- box._y2 = 28 + 1;
- box._x1 = champStatusBoxX;
- box._x2 = box._x1 + 66 + 1;
- if (champ->_currHealth) {
- dispMan.clearScreenBox(kColorDarkestGray, box);
- int16 nativeBitmapIndices[3];
- for (int16 i = 0; i < 3; ++i)
- nativeBitmapIndices[i] = 0;
- int16 AL_0_borderCount = 0;
- if (_party._fireShieldDefense > 0)
- nativeBitmapIndices[AL_0_borderCount++] = kBorderPartyFireshieldIndice;
- if (_party._spellShieldDefense > 0)
- nativeBitmapIndices[AL_0_borderCount++] = kBorderPartySpellshieldIndice;
- if (_party._shieldDefense > 0)
- nativeBitmapIndices[AL_0_borderCount++] = kBorderPartyShieldIndice;
- while (AL_0_borderCount--) {
- dispMan.blitToScreen(dispMan.getBitmap(nativeBitmapIndices[AL_0_borderCount]), 80, 0, 0, box, kColorFlesh);
- }
- if (isInventoryChamp) {
- invMan.drawStatusBoxPortrait(champIndex);
- champAttributes |= kChampionAttributeStatistics;
- } else {
- champAttributes |= (kChampionAttributeNameTitle | kChampionAttributeStatistics | kChampionAttributeWounds | kChampionAttributeActionHand);
- }
- } else {
- dispMan.blitToScreen(dispMan.getBitmap(kStatusBoxDeadChampion), 80, 0, 0, box, kColorNoTransparency);
- warning("MISSING CODE: F0053_TEXT_PrintToLogicalScreen");
- menuMan.drawActionIcon(champIndex);
- goto T0292042_green;
- }
- }
-
- if (!champ->_currHealth)
- goto T0292042_green;
-
- if(champAttributes & kChampionAttributeNameTitle) {
- int16 AL_0_colorIndex = (champIndex == _leaderIndex) ? kColorGold : kColorLightestGray; // unused because of missing functions
- if(isInventoryChamp) {
- char *champName = champ->_name;
- warning("MISSING CODE: F0052_TEXT_PrintToViewport");
- int16 champTitleX = 6 * strlen(champName) + 3;
- char champTitleFirstChar = champ->_title[0];
- if ((champTitleFirstChar != ',') && (champTitleFirstChar != ';') && (champTitleFirstChar != '-')) {
- champTitleX += 6;
- }
- warning("MISSING CODE: F0052_TEXT_PrintToViewport");
- champAttributes |= kChampionAttributeViewport;
- } else {
- box._y1 = 0;
- box._y2 = 6 + 1;
- box._x1 = champStatusBoxX;
- box._x2 = box._x1 + 42 + 1;
- dispMan.clearScreenBox(kColorDarkGary, box);
- warning("MISSING CODE: F0053_TEXT_PrintToLogicalScreen");
- }
- }
-
- if (champAttributes & kChampionAttributeStatistics) {
- drawChampionBarGraphs(champIndex);
- if (isInventoryChamp) {
- warning("MISSING CODE: F0290_CHAMPION_DrawHealthStaminaManaValues");
- int16 AL_2_nativeBitmapIndex;
- if ((champ->_food < 0) || (champ->_water < 0) || (champ->_poisonEventCount)) {
- AL_2_nativeBitmapIndex = kSlotBoxWoundedIndice;
- } else {
- AL_2_nativeBitmapIndex = kSlotBoxNormalIndice;
- }
- dispMan.blitToScreen(dispMan.getBitmap(AL_2_nativeBitmapIndex), 32, 0, 0, gBoxMouth, kColorDarkestGray, gDungeonViewport);
- AL_2_nativeBitmapIndex = kSlotBoxNormalIndice;
- for (int16 AL_0_statisticIndex = kChampionStatStrength; AL_0_statisticIndex <= kChampionStatAntifire; AL_0_statisticIndex++) {
- if (champ->getStatistic((ChampionStatisticType)AL_0_statisticIndex, kChampionStatCurrent)
- < champ->getStatistic((ChampionStatisticType)AL_0_statisticIndex, kChampionStatMaximum)) {
- AL_2_nativeBitmapIndex = kSlotBoxWoundedIndice;
- break;
- }
- }
- dispMan.blitToScreen(dispMan.getBitmap(AL_2_nativeBitmapIndex), 32, 0, 0, gBoxEye, kColorDarkestGray, gDungeonViewport);
- champAttributes |= kChampionAttributeViewport;
- }
- }
-
- if (champAttributes & kChampionAttributeWounds) {
- for (int16 AL_0_slotIndex = isInventoryChamp ? kChampionSlotFeet : kChampionSlotActionHand; AL_0_slotIndex >= kChampionSlotReadyHand; AL_0_slotIndex--) {
- warning("MISSING CODE: F0291_CHAMPION_DrawSlot");
- }
- if (isInventoryChamp) {
- champAttributes |= kChampionAttributeViewport;
- }
- }
-
- if (champAttributes & kChampionAttributeLoad) {
- warning("MISSING CODE: whole if branch, many F0052_TEXT_PrintToViewport-s");
-
-
-
- champAttributes |= kChampionAttributeViewport;
- }
-
- { // block so goto won't skip AL_0_championIconIndex initialization
- int16 AL_0_championIconIndex = championIconIndex(champ->_cell, _vm->_dungeonMan->_currMap._partyDir);
-
- if ((champAttributes & kChampionIcons) && (eventMan._useChampionIconOrdinalAsMousePointerBitmap != indexToOrdinal(AL_0_championIconIndex))) {
- dispMan.clearScreenBox(gChampionColor[champIndex], gBoxChampionIcons[AL_0_championIconIndex]);
- dispMan.blitToScreen(dispMan.getBitmap(kChampionIcons), 80, championIconIndex(champ->_dir, _vm->_dungeonMan->_currMap._partyDir) * 19, 0,
- gBoxChampionIcons[AL_0_championIconIndex], kColorDarkestGray);
- }
- }
-
- if ((champAttributes & kChampionAttributePanel) && isInventoryChamp) {
- if (_vm->_pressingMouth) {
- invMan.drawPanelFoodWaterPoisoned();
- } else if (_vm->_pressingEye) {
- if (_leaderEmptyHanded) {
- warning("MISSING CODE: F0351_INVENTORY_DrawChampionSkillsAndStatistics");
- }
- } else {
- invMan.drawPanel();
- }
- champAttributes |= kChampionAttributeViewport;
- }
-
- if (champAttributes & kChampionAttributeActionHand) {
- warning("MISSING CODE: F0291_CHAMPION_DrawSlot");
- menuMan.drawActionIcon(champIndex);
- if (isInventoryChamp) {
- champAttributes |= kChampionAttributeViewport;
- }
- }
-
- if (champAttributes & kChampionAttributeViewport) {
- warning("MISSGIN CODE: F0097_DUNGEONVIEW_DrawViewport");
- }
-
-
-T0292042_green:
- champ->setAttributeFlag((ChampionAttribute)(kChampionAttributeNameTitle | kChampionAttributeStatistics | kChampionAttributeLoad | kChampionAttributeIcon |
- kChampionAttributePanel | kChampionAttributeStatusBox | kChampionAttributeWounds | kChampionAttributeViewport |
- kChampionAttributeActionHand), false);
- warning("MISSING CODE: F0078_MOUSE_ShowPointer");
-}
-
-uint16 ChampionMan::championIconIndex(int16 val, direction dir) {
- return ((val + 4 - dir) & 0x3);
-}
-
-}
+#include "champion.h"
+#include "dungeonman.h"
+#include "eventman.h"
+#include "menus.h"
+#include "inventory.h"
+#include "objectman.h"
+#include "text.h"
+
+
+namespace DM {
+
+Box gBoxMouth = Box(55, 72, 12, 29); // @ G0048_s_Graphic562_Box_Mouth
+Box gBoxEye = Box(11, 28, 12, 29); // @ G0049_s_Graphic562_Box_Eye
+Box gBoxChampionIcons[4] = { // @ G0054_ai_Graphic562_Box_ChampionIcons
+ Box(281, 299, 0, 13),
+ Box(301, 319, 0, 13),
+ Box(301, 319, 15, 28),
+ Box(281, 299, 15, 28)};
+Color gChampionColor[4] = {(Color)7, (Color)11, (Color)8, (Color)14}; // @ G0046_auc_Graphic562_ChampionColor
+
+uint16 gSlotMasks[38] = { // @ G0038_ai_Graphic562_SlotMasks
+ /* 30 for champion inventory, 8 for chest */
+ 0xFFFF, /* Ready Hand Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Action Hand Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0x0002, /* Head Head */
+ 0x0008, /* Torso Torso */
+ 0x0010, /* Legs Legs */
+ 0x0020, /* Feet Feet */
+ 0x0100, /* Pouch 2 Pouch */
+ 0x0080, /* Quiver Line2 1 Quiver 2 */
+ 0x0080, /* Quiver Line1 2 Quiver 2 */
+ 0x0080, /* Quiver Line2 2 Quiver 2 */
+ 0x0004, /* Neck Neck */
+ 0x0100, /* Pouch 1 Pouch */
+ 0x0040, /* Quiver Line1 1 Quiver 1 */
+ 0xFFFF, /* Backpack Line1 1 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line2 2 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line2 3 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line2 4 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line2 5 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line2 6 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line2 7 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line2 8 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line2 9 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line1 2 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line1 3 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line1 4 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line1 5 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line1 6 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line1 7 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line1 8 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0xFFFF, /* Backpack Line1 9 Mouth/Head/Neck/Torso/Legs/Feet/Quiver 1/Quiver 2/Pouch/Hands/Chest */
+ 0x0400, /* Chest 1 Chest */
+ 0x0400, /* Chest 2 Chest */
+ 0x0400, /* Chest 3 Chest */
+ 0x0400, /* Chest 4 Chest */
+ 0x0400, /* Chest 5 Chest */
+ 0x0400, /* Chest 6 Chest */
+ 0x0400, /* Chest 7 Chest */
+ 0x0400}; /* Chest 8 Chest */
+
+Box gBoxChampionPortrait = Box(0, 31, 0, 28); // @ G0047_s_Graphic562_Box_ChampionPortrait
+
+ChampionMan::ChampionMan(DMEngine *vm) : _vm(vm) {
+ _leaderIndex = kChampionNone;
+
+ _partyDead = false;
+ _partyIsSleeping = false;
+ _leaderHandObjectIconIndex = kIconIndiceNone;
+ _leaderEmptyHanded = true;
+}
+
+uint16 ChampionMan::getChampionPortraitX(uint16 index) {
+ return ((index) & 0x7) << 5;
+}
+
+uint16 ChampionMan::getChampionPortraitY(uint16 index) {
+ return ((index) >> 3) * 29;
+}
+
+int16 ChampionMan::getDecodedValue(char *string, uint16 characterCount) {
+ int val = 0;
+ for (uint16 i = 0; i < characterCount; ++i) {
+ val = (val << 4) + (string[i] - 'A');
+ }
+ return val;
+}
+
+void ChampionMan::drawHealthOrStaminaOrManaValue(int16 posY, int16 currVal, int16 maxVal) {
+ Common::String tmp = getStringFromInteger(currVal, true, 3).c_str();
+ _vm->_textMan->printToViewport(55, posY, kColorLightestGray, tmp.c_str());
+ _vm->_textMan->printToViewport(73, posY, kColorLightestGray, "/");
+ tmp = getStringFromInteger(maxVal, true, 3);
+ _vm->_textMan->printToViewport(79, posY, kColorLightestGray, tmp.c_str());
+}
+
+Common::String ChampionMan::getStringFromInteger(uint16 val, bool padding, uint16 paddingCharCount) {
+ using namespace Common;
+ String valToStr = String::format("%d", val);
+ String result;
+ for (int16 i = 0, end = paddingCharCount - valToStr.size(); i < end; ++i)
+ result += ' ';
+
+ return result += valToStr;
+}
+
+ChampionIndex ChampionMan::getIndexInCell(ViewCell cell) {
+ for (uint16 i = 0; i < _partyChampionCount; ++i) {
+ if ((_champions[i]._cell == cell) && _champions[i]._currHealth)
+ return (ChampionIndex)i;
+ }
+
+ return kChampionNone;
+}
+
+void ChampionMan::resetDataToStartGame() {
+ if (!_vm->_dungeonMan->_messages._newGame) {
+ warning("MISSING CODE: stuff for resetting for loaded games");
+ assert(false);
+ }
+
+ _leaderHand = Thing::_thingNone;
+ _leaderHandObjectIconIndex = kIconIndiceNone;
+ _leaderEmptyHanded = true;
+}
+
+
+void ChampionMan::addCandidateChampionToParty(uint16 championPortraitIndex) {
+ DisplayMan &dispMan = *_vm->_displayMan;
+ DungeonMan &dunMan = *_vm->_dungeonMan;
+
+ if (!_leaderEmptyHanded || _partyChampionCount == 4)
+ return;
+
+ uint16 prevChampCount = _partyChampionCount;
+ Champion *champ = &_champions[prevChampCount];
+ champ->resetToZero();
+ dispMan._useByteBoxCoordinates = true;
+ { // limit destBox scope
+ Box &destBox = gBoxChampionPortrait;
+ dispMan.blitToBitmap(dispMan.getBitmap(kChampionPortraitsIndice), 256, getChampionPortraitX(championPortraitIndex), getChampionPortraitY(championPortraitIndex),
+ champ->_portrait, 32, destBox._x1, destBox._x2, destBox._y1, destBox._y2, kColorNoTransparency);
+ }
+
+ champ->_actionIndex = kChampionActionNone;
+ champ->_enableActionEventIndex = -1;
+ champ->_hideDamageReceivedIndex = -1;
+ champ->_dir = dunMan._currMap._partyDir;
+ ViewCell AL_0_viewCell = kViewCellFronLeft;
+ while (getIndexInCell((ViewCell)((AL_0_viewCell + dunMan._currMap._partyDir) & 3)) != kChampionNone)
+ AL_0_viewCell = (ViewCell)(AL_0_viewCell + 1);
+ champ->_cell = (ViewCell)((AL_0_viewCell + dunMan._currMap._partyDir) & 3);
+ champ->clearAttributes(kChampionAttributeIcon);
+ champ->_directionMaximumDamageReceived = dunMan._currMap._partyDir;
+ champ->_food = 1500 + _vm->_rnd->getRandomNumber(256);
+ champ->_water = 1500 + _vm->_rnd->getRandomNumber(256);
+ int16 AL_0_slotIndex_Red;
+ for (AL_0_slotIndex_Red = kChampionSlotReadyHand; AL_0_slotIndex_Red < kChampionSlotChest_1; ++AL_0_slotIndex_Red) {
+ champ->setSlot((ChampionSlot)AL_0_slotIndex_Red, Thing::_thingNone);
+ }
+ Thing thing = dunMan.getSquareFirstThing(dunMan._currMap._partyPosX, dunMan._currMap._partyPosY);
+ while (thing.getType() != kTextstringType) {
+ thing = dunMan.getNextThing(thing);
+ }
+ char decodedChampionText[77];
+ char* character_Green = decodedChampionText;
+ dunMan.decodeText(character_Green, thing, (TextType)(kTextTypeScroll | kDecodeEvenIfInvisible));
+ int16 AL_0_characterIndex = 0;
+ uint16 AL_2_character;
+ while ((AL_2_character = *character_Green++) != '\n') {
+ champ->_name[AL_0_characterIndex++] = AL_2_character;
+ }
+ champ->_name[AL_0_characterIndex] = '\0';
+ AL_0_characterIndex = 0;
+ bool AL_4_champTitleCopied = false;
+ for (;;) { // infinite
+ AL_2_character = *character_Green++;
+ if (AL_2_character == '\n') {
+ if (AL_4_champTitleCopied)
+ break;
+ AL_4_champTitleCopied = true;
+ } else {
+ champ->_title[AL_0_characterIndex++] = AL_2_character;
+ }
+ }
+ champ->_title[AL_0_characterIndex] = '\0';
+ if (*character_Green++ == 'M') {
+ champ->setAttributeFlag(kChampionAttributeMale, true);
+ }
+ character_Green++;
+ champ->_currHealth = champ->_maxHealth = getDecodedValue(character_Green, 4);
+ character_Green += 4;
+ champ->_currStamina = champ->_maxStamina = getDecodedValue(character_Green, 4);
+ character_Green += 4;
+ champ->_currMana = champ->_maxMana = getDecodedValue(character_Green, 4);
+ character_Green += 4;
+ character_Green++;
+
+ int16 AL_0_statisticIndex;
+ for (AL_0_statisticIndex = kChampionStatLuck; AL_0_statisticIndex <= kChampionStatAntifire; ++AL_0_statisticIndex) {
+ champ->setStatistic((ChampionStatisticType)AL_0_statisticIndex, kChampionStatMinimum, 30);
+ uint16 currMaxVal = getDecodedValue(character_Green, 2);
+ champ->setStatistic((ChampionStatisticType)AL_0_statisticIndex, kChampionStatCurrent, currMaxVal);
+ champ->setStatistic((ChampionStatisticType)AL_0_statisticIndex, kChampionStatMaximum, currMaxVal);
+ character_Green += 2;
+ }
+
+ champ->setStatistic(kChampionStatLuck, kChampionStatMinimum, 10);
+ character_Green++;
+
+ int16 AL_0_skillIndex;
+ int16 AL_2_skillValue;
+ for (AL_0_skillIndex = kChampionSkillSwing; AL_0_skillIndex <= kChampionSkillWater; AL_0_skillIndex++) {
+ if ((AL_2_skillValue = *character_Green++ - 'A') > 0) {
+ champ->setSkillExp((ChampionSkill)AL_0_skillIndex, 125L << AL_2_skillValue);
+ }
+ }
+
+ for (AL_0_skillIndex = kChampionSkillFighter; AL_0_skillIndex <= kChampionSkillWizard; ++AL_0_skillIndex) {
+ int32 baseSkillExp = 0;
+ int16 hiddenSkillIndex = (AL_0_skillIndex + 1) << 2;
+ for (uint16 AL_4_hiddenSkillCounter = 0; AL_4_hiddenSkillCounter < 4; ++AL_4_hiddenSkillCounter) {
+ baseSkillExp += champ->getSkill((ChampionSkill)(hiddenSkillIndex + AL_4_hiddenSkillCounter))._experience;
+ }
+ champ->setSkillExp((ChampionSkill)AL_0_skillIndex, baseSkillExp);
+ }
+
+ _candidateChampionOrdinal = prevChampCount + 1;
+ if (++_partyChampionCount == 1) {
+ _vm->_eventMan->commandSetLeader(kChampionFirst);
+ _vm->_menuMan->_shouldRefreshActionArea = true;
+ } else {
+ _vm->_menuMan->clearActingChampion();
+ _vm->_menuMan->drawActionIcon((ChampionIndex)(_partyChampionCount - 1));
+ }
+
+ int16 mapX = _vm->_dungeonMan->_currMap._partyPosX;
+ int16 mapY = _vm->_dungeonMan->_currMap._partyPosY;
+
+ uint16 championObjectsCell = returnOppositeDir((direction)(dunMan._currMap._partyDir));
+ mapX += _dirIntoStepCountEast[dunMan._currMap._partyDir];
+ mapY += _dirIntoStepCountNorth[dunMan._currMap._partyDir];
+ thing = dunMan.getSquareFirstThing(mapX, mapY);
+ AL_0_slotIndex_Red = kChampionSlotBackpackLine_1_1;
+ uint16 slotIndex_Green;
+ while (thing != Thing::_thingEndOfList) {
+ ThingType AL_2_thingType = thing.getType();
+ if ((AL_2_thingType > kSensorThingType) && (thing.getCell() == championObjectsCell)) {
+ int16 objectAllowedSlots = gObjectInfo[dunMan.getObjectInfoIndex(thing)].getAllowedSlots();
+ switch (AL_2_thingType) {
+ case kArmourThingType:
+ for (slotIndex_Green = kChampionSlotHead; slotIndex_Green <= kChampionSlotFeet; slotIndex_Green++) {
+ if (objectAllowedSlots & gSlotMasks[slotIndex_Green])
+ goto T0280048;
+ }
+ if ((objectAllowedSlots & gSlotMasks[kChampionSlotNeck]) && (champ->getSlot(kChampionSlotNeck) == Thing::_thingNone)) {
+ slotIndex_Green = kChampionSlotNeck;
+ } else {
+ goto T0280046;
+ }
+ break;
+ case kWeaponThingType:
+ if (champ->getSlot(kChampionSlotActionHand) == Thing::_thingNone) {
+ slotIndex_Green = kChampionSlotActionHand;
+ } else {
+ goto T0280046;
+ }
+ break;
+ case kScrollThingType:
+ case kPotionThingType:
+ if (champ->getSlot(kChampionSlotPouch_1) == Thing::_thingNone) {
+ slotIndex_Green = kChampionSlotPouch_1;
+ } else if (champ->getSlot(kChampionSlotPouch_2) == Thing::_thingNone) {
+ slotIndex_Green = kChampionSlotPouch_2;
+ } else {
+ goto T0280046;
+ }
+ break;
+ case kContainerThingType:
+ case kJunkThingType:
+T0280046:
+ if ((objectAllowedSlots & gSlotMasks[kChampionSlotNeck]) && (champ->getSlot(kChampionSlotNeck) == Thing::_thingNone)) {
+ slotIndex_Green = kChampionSlotNeck;
+ } else {
+ slotIndex_Green = AL_0_slotIndex_Red++;
+ }
+ break;
+ }
+T0280048:
+ if (champ->getSlot((ChampionSlot)slotIndex_Green) != Thing::_thingNone) {
+ goto T0280046;
+ }
+ warning("MISSING CODE: F0301_CHAMPION_AddObjectInSlot");
+ }
+ thing = dunMan.getNextThing(thing);
+ }
+
+ _vm->_inventoryMan->toggleInventory((ChampionIndex)prevChampCount);
+ _vm->_menuMan->drawDisabledMenu();
+}
+
+void ChampionMan::drawChampionBarGraphs(ChampionIndex champIndex) {
+
+ Champion *curChampion = &_champions[champIndex];
+ int16 barGraphIndex = 0;
+ int16 barGraphHeightArray[3];
+
+ if (curChampion->_currHealth > 0) {
+ uint32 barGraphHeight = (((uint32)(curChampion->_currHealth) << 10) * 25) / curChampion->_maxHealth;
+ if (barGraphHeight & 0x3FF) {
+ barGraphHeightArray[barGraphIndex++] = (barGraphHeight >> 10) + 1;
+ } else {
+ barGraphHeightArray[barGraphIndex++] = (barGraphHeight >> 10);
+ }
+ } else {
+ barGraphHeightArray[barGraphIndex++] = 0;
+ }
+
+ if (curChampion->_currStamina > 0) {
+ uint32 barGraphHeight = (((uint32)(curChampion->_currStamina) << 10) * 25) / curChampion->_maxStamina;
+ if (barGraphHeight & 0x3FF) {
+ barGraphHeightArray[barGraphIndex++] = (barGraphHeight >> 10) + 1;
+ } else {
+ barGraphHeightArray[barGraphIndex++] = (barGraphHeight >> 10);
+ }
+ } else {
+ barGraphHeightArray[barGraphIndex++] = 0;
+ }
+
+ if (curChampion->_currMana > 0) {
+ uint32 barGraphHeight = (((uint32)(curChampion->_currMana) << 10) * 25) / curChampion->_maxMana;
+ if (barGraphHeight & 0x3FF) {
+ barGraphHeightArray[barGraphIndex++] = (barGraphHeight >> 10) + 1;
+ } else {
+ barGraphHeightArray[barGraphIndex++] = (barGraphHeight >> 10);
+ }
+ } else {
+ barGraphHeightArray[barGraphIndex++] = 0;
+ }
+ warning("MISSING CODE: F0077_MOUSE_HidePointer_CPSE");
+
+ Box box;
+ box._x1 = champIndex * kChampionStatusBoxSpacing + 46;
+ box._x2 = box._x1 + 3 + 1;
+ box._y1 = 2;
+ box._y2 = 26 + 1;
+
+ for (int16 AL_0_barGraphIndex = 0; AL_0_barGraphIndex < 3; AL_0_barGraphIndex++) {
+ int16 barGraphHeight = barGraphHeightArray[AL_0_barGraphIndex];
+ if (barGraphHeight < 25) {
+ box._y1 = 2;
+ box._y1 = 27 - barGraphHeight + 1;
+ _vm->_displayMan->clearScreenBox(gChampionColor[champIndex], box);
+ }
+ if (barGraphHeight) {
+ box._y1 = 27 - barGraphHeight;
+ box._y2 = 26 + 1;
+ _vm->_displayMan->clearScreenBox(gChampionColor[champIndex], box);
+ }
+ box._x1 += 7;
+ box._x2 += 7;
+ }
+ warning("MISSING CODE: F0078_MOUSE_ShowPointer");
+}
+
+
+uint16 ChampionMan::getStaminaAdjustedValue(Champion *champ, int16 val) {
+ int16 currStamina = champ->_currStamina;
+ int16 halfMaxStamina = champ->_maxStamina / 2;
+ if (currStamina < halfMaxStamina) {
+ warning("Possible undefined behavior in the original code");
+ val /= 2;
+ return val + ((uint32)val * (uint32)currStamina) / halfMaxStamina;
+ }
+ return val;
+}
+
+uint16 ChampionMan::getMaximumLoad(Champion *champ) {
+ uint16 maximumLoad = champ->getStatistic(kChampionStatStrength, kChampionStatCurrent) * 8 + 100;
+ maximumLoad = getStaminaAdjustedValue(champ, maximumLoad);
+ int16 wounds = champ->getWounds();
+ if (wounds) {
+ maximumLoad -= maximumLoad >> (champ->getWoundsFlag(kChampionWoundLegs) ? 2 : 3);
+ }
+ if (_vm->_objectMan->getIconIndex(champ->getSlot(kChampionSlotFeet)) == kIconIndiceArmourElvenBoots) {
+ maximumLoad += maximumLoad * 16;
+ }
+ maximumLoad += 9;
+ maximumLoad -= maximumLoad % 10;
+ return maximumLoad;
+}
+
+void ChampionMan::drawChampionState(ChampionIndex champIndex) {
+ InventoryMan &invMan = *_vm->_inventoryMan;
+ DisplayMan &dispMan = *_vm->_displayMan;
+ MenuMan &menuMan = *_vm->_menuMan;
+ EventManager &eventMan = *_vm->_eventMan;
+
+ Box box;
+ int16 champStatusBoxX = champIndex * kChampionStatusBoxSpacing;
+ Champion *champ = &_champions[champIndex];
+ uint16 champAttributes = champ->getAttributes();
+ if (!((champAttributes) & (kChampionAttributeNameTitle | kChampionAttributeStatistics | kChampionAttributeLoad | kChampionAttributeIcon |
+ kChampionAttributePanel | kChampionAttributeStatusBox | kChampionAttributeWounds | kChampionAttributeViewport |
+ kChampionAttributeActionHand))) {
+ return;
+ }
+ bool isInventoryChamp = (indexToOrdinal(champIndex) == invMan._inventoryChampionOrdinal);
+ dispMan._useByteBoxCoordinates = false;
+ if (champAttributes & kChampionAttributeStatusBox) {
+ box._y1 = 0;
+ box._y2 = 28 + 1;
+ box._x1 = champStatusBoxX;
+ box._x2 = box._x1 + 66 + 1;
+ if (champ->_currHealth) {
+ dispMan.clearScreenBox(kColorDarkestGray, box);
+ int16 nativeBitmapIndices[3];
+ for (int16 i = 0; i < 3; ++i)
+ nativeBitmapIndices[i] = 0;
+ int16 AL_0_borderCount = 0;
+ if (_party._fireShieldDefense > 0)
+ nativeBitmapIndices[AL_0_borderCount++] = kBorderPartyFireshieldIndice;
+ if (_party._spellShieldDefense > 0)
+ nativeBitmapIndices[AL_0_borderCount++] = kBorderPartySpellshieldIndice;
+ if (_party._shieldDefense > 0)
+ nativeBitmapIndices[AL_0_borderCount++] = kBorderPartyShieldIndice;
+ while (AL_0_borderCount--) {
+ dispMan.blitToScreen(dispMan.getBitmap(nativeBitmapIndices[AL_0_borderCount]), 80, 0, 0, box, kColorFlesh);
+ }
+ if (isInventoryChamp) {
+ invMan.drawStatusBoxPortrait(champIndex);
+ champAttributes |= kChampionAttributeStatistics;
+ } else {
+ champAttributes |= (kChampionAttributeNameTitle | kChampionAttributeStatistics | kChampionAttributeWounds | kChampionAttributeActionHand);
+ }
+ } else {
+ dispMan.blitToScreen(dispMan.getBitmap(kStatusBoxDeadChampion), 80, 0, 0, box, kColorNoTransparency);
+ _vm->_textMan->printTextToScreen(champStatusBoxX + 1, 5, kColorLightestGray, kColorDarkGary, champ->_name);
+ menuMan.drawActionIcon(champIndex);
+ goto T0292042_green;
+ }
+ }
+
+ if (!champ->_currHealth)
+ goto T0292042_green;
+
+ if (champAttributes & kChampionAttributeNameTitle) {
+ Color AL_0_colorIndex = (champIndex == _leaderIndex) ? kColorGold : kColorLightestGray; // unused because of missing functions
+ if (isInventoryChamp) {
+ char *champName = champ->_name;
+ _vm->_textMan->printToViewport(3, 7, AL_0_colorIndex, champName);
+ int16 champTitleX = 6 * strlen(champName) + 3;
+ char champTitleFirstChar = champ->_title[0];
+ if ((champTitleFirstChar != ',') && (champTitleFirstChar != ';') && (champTitleFirstChar != '-')) {
+ champTitleX += 6;
+ }
+ _vm->_textMan->printToViewport(champTitleX, 7, AL_0_colorIndex, champ->_title);
+ champAttributes |= kChampionAttributeViewport;
+ } else {
+ box._y1 = 0;
+ box._y2 = 6 + 1;
+ box._x1 = champStatusBoxX;
+ box._x2 = box._x1 + 42 + 1;
+ dispMan.clearScreenBox(kColorDarkGary, box);
+ _vm->_textMan->printTextToScreen(champStatusBoxX + 1, 5, AL_0_colorIndex, kColorDarkGary, champ->_name);
+ }
+ }
+
+ if (champAttributes & kChampionAttributeStatistics) {
+ drawChampionBarGraphs(champIndex);
+ if (isInventoryChamp) {
+ drawHealthStaminaManaValues(champ);
+ int16 AL_2_nativeBitmapIndex;
+ if ((champ->_food < 0) || (champ->_water < 0) || (champ->_poisonEventCount)) {
+ AL_2_nativeBitmapIndex = kSlotBoxWoundedIndice;
+ } else {
+ AL_2_nativeBitmapIndex = kSlotBoxNormalIndice;
+ }
+ dispMan.blitToScreen(dispMan.getBitmap(AL_2_nativeBitmapIndex), 32, 0, 0, gBoxMouth, kColorDarkestGray, gDungeonViewport);
+ AL_2_nativeBitmapIndex = kSlotBoxNormalIndice;
+ for (int16 AL_0_statisticIndex = kChampionStatStrength; AL_0_statisticIndex <= kChampionStatAntifire; AL_0_statisticIndex++) {
+ if (champ->getStatistic((ChampionStatisticType)AL_0_statisticIndex, kChampionStatCurrent)
+ < champ->getStatistic((ChampionStatisticType)AL_0_statisticIndex, kChampionStatMaximum)) {
+ AL_2_nativeBitmapIndex = kSlotBoxWoundedIndice;
+ break;
+ }
+ }
+ dispMan.blitToScreen(dispMan.getBitmap(AL_2_nativeBitmapIndex), 32, 0, 0, gBoxEye, kColorDarkestGray, gDungeonViewport);
+ champAttributes |= kChampionAttributeViewport;
+ }
+ }
+
+ if (champAttributes & kChampionAttributeWounds) {
+ for (int16 AL_0_slotIndex = isInventoryChamp ? kChampionSlotFeet : kChampionSlotActionHand; AL_0_slotIndex >= kChampionSlotReadyHand; AL_0_slotIndex--) {
+ warning("MISSING CODE: F0291_CHAMPION_DrawSlot");
+ }
+ if (isInventoryChamp) {
+ champAttributes |= kChampionAttributeViewport;
+ }
+ }
+
+ if (champAttributes & kChampionAttributeLoad) {
+ warning("MISSING CODE: whole if branch, many F0052_TEXT_PrintToViewport-s");
+
+
+
+ champAttributes |= kChampionAttributeViewport;
+ }
+
+ { // block so goto won't skip AL_0_championIconIndex initialization
+ int16 AL_0_championIconIndex = championIconIndex(champ->_cell, _vm->_dungeonMan->_currMap._partyDir);
+
+ if ((champAttributes & kChampionIcons) && (eventMan._useChampionIconOrdinalAsMousePointerBitmap != indexToOrdinal(AL_0_championIconIndex))) {
+ dispMan.clearScreenBox(gChampionColor[champIndex], gBoxChampionIcons[AL_0_championIconIndex]);
+ dispMan.blitToScreen(dispMan.getBitmap(kChampionIcons), 80, championIconIndex(champ->_dir, _vm->_dungeonMan->_currMap._partyDir) * 19, 0,
+ gBoxChampionIcons[AL_0_championIconIndex], kColorDarkestGray);
+ }
+ }
+
+ if ((champAttributes & kChampionAttributePanel) && isInventoryChamp) {
+ if (_vm->_pressingMouth) {
+ invMan.drawPanelFoodWaterPoisoned();
+ } else if (_vm->_pressingEye) {
+ if (_leaderEmptyHanded) {
+ warning("MISSING CODE: F0351_INVENTORY_DrawChampionSkillsAndStatistics");
+ }
+ } else {
+ invMan.drawPanel();
+ }
+ champAttributes |= kChampionAttributeViewport;
+ }
+
+ if (champAttributes & kChampionAttributeActionHand) {
+ warning("MISSING CODE: F0291_CHAMPION_DrawSlot");
+ menuMan.drawActionIcon(champIndex);
+ if (isInventoryChamp) {
+ champAttributes |= kChampionAttributeViewport;
+ }
+ }
+
+ if (champAttributes & kChampionAttributeViewport) {
+ warning("MISSGIN CODE: F0097_DUNGEONVIEW_DrawViewport");
+ }
+
+
+T0292042_green:
+ champ->setAttributeFlag((ChampionAttribute)(kChampionAttributeNameTitle | kChampionAttributeStatistics | kChampionAttributeLoad | kChampionAttributeIcon |
+ kChampionAttributePanel | kChampionAttributeStatusBox | kChampionAttributeWounds | kChampionAttributeViewport |
+ kChampionAttributeActionHand), false);
+ warning("MISSING CODE: F0078_MOUSE_ShowPointer");
+}
+
+uint16 ChampionMan::championIconIndex(int16 val, direction dir) {
+ return ((val + 4 - dir) & 0x3);
+}
+
+void ChampionMan::drawHealthStaminaManaValues(Champion* champ) {
+ drawHealthOrStaminaOrManaValue(116, champ->_currHealth, champ->_maxHealth);
+ drawHealthOrStaminaOrManaValue(124, champ->_currStamina, champ->_maxStamina);
+ drawHealthOrStaminaOrManaValue(132, champ->_currMana, champ->_maxMana);
+}
+
+}
diff --git a/engines/dm/champion.h b/engines/dm/champion.h
index 4e9e29d9c7..4cc32c51f4 100644
--- a/engines/dm/champion.h
+++ b/engines/dm/champion.h
@@ -1,6 +1,8 @@
#ifndef DM_CHAMPION_H
#define DM_CHAMPION_H
+#include "common/str.h"
+
#include "dm.h"
#include "gfx.h"
@@ -390,6 +392,8 @@ class ChampionMan {
ChampionIndex getIndexInCell(ViewCell cell); // @ F0285_CHAMPION_GetIndexInCell
int16 getDecodedValue(char *string, uint16 characterCount); // @ F0279_CHAMPION_GetDecodedValue
+ void drawHealthOrStaminaOrManaValue(int16 posy, int16 currVal, int16 maxVal); // @ F0289_CHAMPION_DrawHealthOrStaminaOrManaValue
+ Common::String getStringFromInteger(uint16 val, bool padding, uint16 paddingCharCount); // @ F0288_CHAMPION_GetStringFromInteger
public:
Champion _champions[4];
uint16 _partyChampionCount; // @ G0305_ui_PartyChampionCount
@@ -411,6 +415,7 @@ public:
uint16 getMaximumLoad(Champion *champ); // @ F0309_CHAMPION_GetMaximumLoad
void drawChampionState(ChampionIndex champIndex); // @ F0292_CHAMPION_DrawState
uint16 championIconIndex(int16 val, direction dir); // @ M26_CHAMPION_ICON_INDEX
+ void drawHealthStaminaManaValues(Champion *champ); // @ F0290_CHAMPION_DrawHealthStaminaManaValues
};
diff --git a/engines/dm/dungeonman.cpp b/engines/dm/dungeonman.cpp
index bbf0c7ddd1..6ff8b7a58e 100644
--- a/engines/dm/dungeonman.cpp
+++ b/engines/dm/dungeonman.cpp
@@ -1,5 +1,6 @@
#include "common/file.h"
#include "common/memstream.h"
+
#include "dungeonman.h"
diff --git a/engines/dm/dungeonman.h b/engines/dm/dungeonman.h
index c5c356e888..59e1a821c5 100644
--- a/engines/dm/dungeonman.h
+++ b/engines/dm/dungeonman.h
@@ -2,7 +2,6 @@
#define DUNGEONMAN_H
#include "dm.h"
-#include "dungeonman.h"
#include "gfx.h"
diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp
index e2713a2536..18aaebe957 100644
--- a/engines/dm/gfx.cpp
+++ b/engines/dm/gfx.cpp
@@ -544,9 +544,9 @@ byte gPalChangesCreature_D2[16] = {0, 10, 20, 30, 40, 30, 60, 70, 50, 0, 0, 110,
-Viewport gDefultViewPort = {0, 0};
+Viewport gDefultViewPort = {0, 0, 320, 200};
// TODO: I guessed the numbers
-Viewport gDungeonViewport = {0, 33}; // @ G0296_puc_Bitmap_Viewport
+Viewport gDungeonViewport = {0, 33, 224, 126}; // @ G0296_puc_Bitmap_Viewport
byte gPalChangesNoChanges[16] = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150}; // @ G0017_auc_Graphic562_PaletteChanges_NoChanges
@@ -684,7 +684,7 @@ void DisplayMan::unpackGraphics() {
unpackedBitmapsSize += getWidth(i) * getHeight(i);
for (uint16 i = 22; i <= 532; ++i)
unpackedBitmapsSize += getWidth(i) * getHeight(i);
- unpackedBitmapsSize += (5 + 1) * (6 + 1) * 128; // 5 x 6 characters, 128 of them, +1 for convenience padding
+ unpackedBitmapsSize += (5 + 1) * 6 * 128; // 5 x 6 characters, 128 of them, +1 for convenience padding
// graphics items go from 0-20 and 22-532 inclusive, _unpackedItemPos 21 and 22 are there for indexing convenience
if (_bitmaps) {
delete[] _bitmaps[0];
@@ -719,8 +719,6 @@ void DisplayMan::loadFNT1intoBitmap(uint16 index, byte* destBitmap)
}
}
}
- memset(data, 0, 128);
- data += 128;
}
void DisplayMan::loadPalette(uint16 *palette) {
diff --git a/engines/dm/gfx.h b/engines/dm/gfx.h
index e2f30f339c..ed246de912 100644
--- a/engines/dm/gfx.h
+++ b/engines/dm/gfx.h
@@ -7,6 +7,7 @@
namespace DM {
+
enum ViewCell {
kViewCellFronLeft = 0, // @ C00_VIEW_CELL_FRONT_LEFT
kViewCellFrontRight = 1, // @ C01_VIEW_CELL_FRONT_RIGHT
@@ -144,9 +145,10 @@ enum Color {
kColorWhite = 15
};
+
struct Viewport {
- // TODO: should probably add width and height, seems redundant right meow
uint16 _posX, _posY;
+ uint16 _width, _height;
};
struct CreatureAspect {
diff --git a/engines/dm/inventory.cpp b/engines/dm/inventory.cpp
index a67d308e68..271fd3b879 100644
--- a/engines/dm/inventory.cpp
+++ b/engines/dm/inventory.cpp
@@ -3,6 +3,7 @@
#include "eventman.h"
#include "menus.h"
#include "gfx.h"
+#include "text.h"
@@ -68,9 +69,9 @@ void InventoryMan::toggleInventory(ChampionIndex championIndex) {
if (cm._candidateChampionOrdinal) {
dm.clearScreenBox(kColorDarkestGray, gBoxFloppyZzzCross, gDungeonViewport);
}
- warning("MISSING CODE: F0052_TEXT_PrintToViewport -> HEALTH");
- warning("MISSING CODE: F0052_TEXT_PrintToViewport -> STAMINA");
- warning("MISSING CODE: F0052_TEXT_PrintToViewport -> MANA");
+ _vm->_textMan->printToViewport(5, 116, kColorLightestGray, "HEALTH");
+ _vm->_textMan->printToViewport(5, 124, kColorLightestGray, "STAMINA");
+ _vm->_textMan->printToViewport(5, 132, kColorLightestGray, "MANA");
warning("MISSING CODE: F0291_CHAMPION_DrawSlot in LOOOOOOOOOOOOP");
diff --git a/engines/dm/text.cpp b/engines/dm/text.cpp
index d6d005fed4..5ad2ac7b6a 100644
--- a/engines/dm/text.cpp
+++ b/engines/dm/text.cpp
@@ -8,36 +8,42 @@ TextMan::TextMan(DMEngine* vm) : _vm(vm) {}
#define kLetterWidth 5
#define kLetterHeight 6
-void TextMan::printTextToBitmap(byte* destBitmap, uint16 destPixelWidth, uint16 destX, uint16 destY, Color textColor, Color bgColor, char* text, uint16 destHeight, Viewport &viewport) {
+void TextMan::printTextToBitmap(byte* destBitmap, uint16 destPixelWidth, uint16 destX, uint16 destY,
+ Color textColor, Color bgColor, const char* text, uint16 destHeight, Viewport &viewport) {
+ destX -= 1; // fixes missalignment, to be checked
+ destY -= 4; // fixes missalignment, to be checked
+
uint16 textLength = strlen(text);
uint16 nextX = destX;
uint16 nextY = destY;
byte *srcBitmap = _vm->_displayMan->getBitmap(kFontGraphicIndice);
byte *tmp = _vm->_displayMan->_tmpBitmap;
- for (uint16 i = 0; i < (kLetterWidth + 1) * (kLetterHeight + 1) * 128; ++i) {
+ for (uint16 i = 0; i < (kLetterWidth + 1) * kLetterHeight * 128; ++i) {
tmp[i] = srcBitmap[i] ? textColor : bgColor;
}
srcBitmap = tmp;
-
- for (char *begin = text, *end = text + textLength; begin != end; ++begin) {
- // Note: this does no wraps in the middle of words
- if (nextX + kLetterWidth + 1 > destPixelWidth || (*begin == '\n')) {
+ for (const char *begin = text, *end = text + textLength; begin != end; ++begin) {
+ if (nextX + kLetterWidth + 1 >= (viewport._posX + viewport._width) || (*begin == '\n')) {
nextX = destX;
nextY += kLetterHeight + 1;
}
- if (nextY + kLetterHeight + 1 > destHeight)
+ if (nextY + kLetterHeight >= (viewport._posY + viewport._height))
break;
uint16 srcX = (1 + 5) * toupper(*begin); // 1 + 5 is not the letter width, arbitrary choice of the unpacking code
- _vm->_displayMan->blitToBitmap(srcBitmap, 6 * 128, srcX, 0, destBitmap, destPixelWidth,
- nextX, nextX + kLetterWidth + 1, nextY, nextY + kLetterHeight + 1, kColorNoTransparency, viewport);
+ _vm->_displayMan->blitToBitmap(srcBitmap, 6 * 128, (nextX == destX) ? (srcX + 1) : srcX, 0, destBitmap, destPixelWidth,
+ (nextX == destX) ? (nextX + 1) : nextX, nextX + kLetterWidth + 1, nextY, nextY + kLetterHeight, kColorNoTransparency, viewport);
nextX += kLetterWidth + 1;
}
}
-void TextMan::printTextToScreen(uint16 destX, uint16 destY, Color textColor, Color bgColor, char* text, Viewport &viewport) {
+void TextMan::printTextToScreen(uint16 destX, uint16 destY, Color textColor, Color bgColor, const char* text, Viewport &viewport) {
printTextToBitmap(_vm->_displayMan->_vgaBuffer, _vm->_displayMan->_screenWidth, destX, destY, textColor, bgColor, text, _vm->_displayMan->_screenHeight, viewport);
}
+void TextMan::printToViewport(int16 posX, int16 posY, Color textColor, const char* text) {
+ printTextToScreen(posX, posY, textColor, kColorDarkestGray, text, gDungeonViewport);
+}
+
}
diff --git a/engines/dm/text.h b/engines/dm/text.h
index 7f57525012..baf9b72851 100644
--- a/engines/dm/text.h
+++ b/engines/dm/text.h
@@ -11,8 +11,9 @@ class TextMan {
public:
TextMan(DMEngine *vm);
void printTextToBitmap(byte *destBitmap, uint16 destPixelWidth, uint16 destX, uint16 destY,
- Color textColor, Color bgColor, char *text, uint16 destHeight, Viewport &viewport = gDefultViewPort); // @ F0040_TEXT_Print
- void printTextToScreen(uint16 destX, uint16 destY, Color textColor, Color bgColor, char *text, Viewport &viewport = gDefultViewPort);
+ Color textColor, Color bgColor, const char *text, uint16 destHeight, Viewport &viewport = gDefultViewPort); // @ F0040_TEXT_Print
+ void printTextToScreen(uint16 destX, uint16 destY, Color textColor, Color bgColor, const char *text, Viewport &viewport = gDefultViewPort); // @ F0053_TEXT_PrintToLogicalScreen
+ void printToViewport(int16 posX, int16 posY, Color textColor, const char *text); // @ F0052_TEXT_PrintToViewport
};
}