diff options
Diffstat (limited to 'engines/dm')
-rw-r--r-- | engines/dm/TODOs/methodtree.txt | 12 | ||||
-rw-r--r-- | engines/dm/TODOs/todo.txt | 1 | ||||
-rw-r--r-- | engines/dm/champion.h | 2 | ||||
-rw-r--r-- | engines/dm/dm.cpp | 1 | ||||
-rw-r--r-- | engines/dm/dungeonman.cpp | 7 | ||||
-rw-r--r-- | engines/dm/dungeonman.h | 32 | ||||
-rw-r--r-- | engines/dm/gfx.cpp | 24 | ||||
-rw-r--r-- | engines/dm/gfx.h | 6 | ||||
-rw-r--r-- | engines/dm/inventory.cpp | 142 | ||||
-rw-r--r-- | engines/dm/inventory.h | 1 | ||||
-rw-r--r-- | engines/dm/objectman.cpp | 119 | ||||
-rw-r--r-- | engines/dm/objectman.h | 6 |
12 files changed, 274 insertions, 79 deletions
diff --git a/engines/dm/TODOs/methodtree.txt b/engines/dm/TODOs/methodtree.txt index 65b79bbc38..fb7021e64f 100644 --- a/engines/dm/TODOs/methodtree.txt +++ b/engines/dm/TODOs/methodtree.txt @@ -47,7 +47,7 @@ F0280_CHAMPION_AddCandidateChampionToParty // done, so-so G0037_s_Graphic562_Box_Poisoned // done F0351_INVENTORY_DrawChampionSkillsAndStatistics // skip ----------------- F0347_INVENTORY_DrawPanel // done - F0342_INVENTORY_DrawPanel_Object + F0342_INVENTORY_DrawPanel_Object // done F0341_INVENTORY_DrawPanel_Scroll // done F0340_INVENTORY_DrawPanel_ScrollTextLine // done F0333_INVENTORY_OpenAndDrawChest // done @@ -58,11 +58,11 @@ F0280_CHAMPION_AddCandidateChampionToParty // done, so-so G0421_i_ObjectDescriptionTextX // done G0422_i_ObjectDescriptionTextY // done F0339_INVENTORY_DrawPanel_ArrowOrEye // done - G0430_apc_DirectionNames - G0034_s_Graphic562_Box_ObjectDescriptionCircle - G0032_s_Graphic562_Box_Panel - G0352_apc_ObjectNames - G0237_as_Graphic559_ObjectInfo + G0430_apc_DirectionNames // done + G0034_s_Graphic562_Box_ObjectDescriptionCircle // done + G0032_s_Graphic562_Box_Panel // done + G0352_apc_ObjectNames // done + G0237_as_Graphic559_ObjectInfo // done G0422_i_ObjectDescriptionTextY // done F0346_INVENTORY_DrawPanel_ResurrectReincarnate // done diff --git a/engines/dm/TODOs/todo.txt b/engines/dm/TODOs/todo.txt index 558fc8a3e2..196d68f27c 100644 --- a/engines/dm/TODOs/todo.txt +++ b/engines/dm/TODOs/todo.txt @@ -16,6 +16,7 @@ Todo: I forgot to add localization warnings Attend to Arnaud's notes on github Double check enums with hex literals, I think I screwed the regex when processing them + Double check strcat, strstr usages, I might have messed them up in many places Missing functions: Add missing F0163_DUNGEON_LinkThingToList in MovesensMan::sensorIsTriggeredByClickOnWall (I don't think it's safe yet) diff --git a/engines/dm/champion.h b/engines/dm/champion.h index 86425b48c7..8ea8a6d0a3 100644 --- a/engines/dm/champion.h +++ b/engines/dm/champion.h @@ -430,7 +430,6 @@ 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 @@ -457,6 +456,7 @@ public: void drawSlot(uint16 champIndex, ChampionSlot slotIndex); // @ F0291_CHAMPION_DrawSlot void renameChampion(Champion* champ); // @ F0281_CHAMPION_Rename uint16 getSkillLevel(ChampionIndex champIndex, ChampionSkill skillIndex);// @ F0303_CHAMPION_GetSkillLevel + Common::String getStringFromInteger(uint16 val, bool padding, uint16 paddingCharCount); // @ F0288_CHAMPION_GetStringFromInteger }; diff --git a/engines/dm/dm.cpp b/engines/dm/dm.cpp index a3479d258a..138e7b8777 100644 --- a/engines/dm/dm.cpp +++ b/engines/dm/dm.cpp @@ -132,6 +132,7 @@ void DMEngine::initializeGame() { _displayMan->loadFloorSet(kFloorSetStone); _displayMan->loadWallSet(kWallSetStone); + _objectMan->loadObjectNames(); startGame(); warning("MISSING CODE: F0267_MOVE_GetMoveResult_CPSCE (if newGame)"); diff --git a/engines/dm/dungeonman.cpp b/engines/dm/dungeonman.cpp index 6d5a54069d..899e7911ad 100644 --- a/engines/dm/dungeonman.cpp +++ b/engines/dm/dungeonman.cpp @@ -1218,13 +1218,6 @@ uint16 DungeonMan::getObjectWeight(Thing thing) { return 0; // dummy } -/* Object info */ -#define kObjectInfoIndexFirstScroll 0 // @ C000_OBJECT_INFO_INDEX_FIRST_SCROLL -#define kObjectInfoIndexFirstContainer 1 // @ C001_OBJECT_INFO_INDEX_FIRST_CONTAINER -#define kObjectInfoIndexFirstPotion 2 // @ C002_OBJECT_INFO_INDEX_FIRST_POTION -#define kObjectInfoIndexFirstWeapon 23 // @ C023_OBJECT_INFO_INDEX_FIRST_WEAPON -#define kObjectInfoIndexFirstArmour 69 // @ C069_OBJECT_INFO_INDEX_FIRST_ARMOUR -#define kObjectInfoIndexFirstJunk 127 // @ C127_OBJECT_INFO_INDEX_FIRST_JUNK int16 DungeonMan::getObjectInfoIndex(Thing thing) { uint16 *rawType = getThingData(thing); diff --git a/engines/dm/dungeonman.h b/engines/dm/dungeonman.h index 767044e9af..69746acff2 100644 --- a/engines/dm/dungeonman.h +++ b/engines/dm/dungeonman.h @@ -34,6 +34,14 @@ namespace DM { +/* Object info */ +#define kObjectInfoIndexFirstScroll 0 // @ C000_OBJECT_INFO_INDEX_FIRST_SCROLL +#define kObjectInfoIndexFirstContainer 1 // @ C001_OBJECT_INFO_INDEX_FIRST_CONTAINER +#define kObjectInfoIndexFirstPotion 2 // @ C002_OBJECT_INFO_INDEX_FIRST_POTION +#define kObjectInfoIndexFirstWeapon 23 // @ C023_OBJECT_INFO_INDEX_FIRST_WEAPON +#define kObjectInfoIndexFirstArmour 69 // @ C069_OBJECT_INFO_INDEX_FIRST_ARMOUR +#define kObjectInfoIndexFirstJunk 127 // @ C127_OBJECT_INFO_INDEX_FIRST_JUNK + #define kMapXNotOnASquare -1 // @ CM1_MAPX_NOT_ON_A_SQUARE enum ElementType { @@ -89,7 +97,7 @@ public: }; // @ OBJECT_INFO extern ObjectInfo gObjectInfo[180]; - + enum ArmourAttribute { kArmourAttributeIsAShield = 0x0080, // @ MASK0x0080_IS_A_SHIELD kArmourAttributeSharpDefense = 0x0007 // @ MASK0x0007_SHARP_DEFENSE @@ -129,18 +137,18 @@ extern ArmourInfo gArmourInfo[58]; class WeaponInfo { public: - uint16 _weight; - uint16 _class; - uint16 _strength; - uint16 _kineticEnergy; + uint16 _weight; + uint16 _class; + uint16 _strength; + uint16 _kineticEnergy; private: uint16 _attributes; /* Bits 15-13 Unreferenced */ public: - WeaponInfo(uint16 weight, uint16 wClass, uint16 strength, uint16 kineticEnergy, uint16 attributes) - : _weight(weight), _class(wClass), _strength(strength), _kineticEnergy(kineticEnergy), _attributes(attributes) {} + WeaponInfo(uint16 weight, uint16 wClass, uint16 strength, uint16 kineticEnergy, uint16 attributes) + : _weight(weight), _class(wClass), _strength(strength), _kineticEnergy(kineticEnergy), _attributes(attributes) {} - uint16 getShootAttack() {return _attributes & 0xFF;} // @ M65_SHOOT_ATTACK - uint16 getProjectileAspectOrdinal() {return (_attributes >> 8) & 0x1F;} // @ M66_PROJECTILE_ASPECT_ORDINAL + uint16 getShootAttack() { return _attributes & 0xFF; } // @ M65_SHOOT_ATTACK + uint16 getProjectileAspectOrdinal() { return (_attributes >> 8) & 0x1F; } // @ M66_PROJECTILE_ASPECT_ORDINAL }; // @ WEAPON_INFO extern WeaponInfo gWeaponInfo[46]; @@ -359,6 +367,9 @@ public: bool isLit() { return (_desc >> 15) & 1; } uint16 getChargeCount() { return (_desc >> 10) & 0xF; } Thing getNextThing() { return _nextThing; } + uint16 getCursed() { return (_desc >> 8) & 1; } + uint16 getPoisoned() { return (_desc >> 9) & 1; } + uint16 getBroken() { return (_desc >> 14) & 1; } }; // @ WEAPON enum ArmourType { @@ -376,6 +387,8 @@ public: ArmourType getType() { return (ArmourType)(_attributes & 0x7F); } Thing getNextThing() { return _nextThing; } + uint16 getCursed() { return (_attributes >> 8) & 1; } + uint16 getBroken() { return (_attributes >> 13) & 1; } }; // @ ARMOUR class Scroll { @@ -416,6 +429,7 @@ public: PotionType getType() { return (PotionType)((_attributes >> 8) & 0x7F); } void setType(PotionType val) { _attributes = (_attributes & ~(0x7F << 8)) | ((val & 0x7F) << 8); } Thing getNextThing() { return _nextThing; } + uint16 getPower() { return _attributes & 0xFF; } }; // @ POTION class Container { diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp index 7466cb424a..b1c5c6a700 100644 --- a/engines/dm/gfx.cpp +++ b/engines/dm/gfx.cpp @@ -731,8 +731,7 @@ void DisplayMan::unpackGraphics() { loadFNT1intoBitmap(kFontGraphicIndice, _bitmaps[kFontGraphicIndice]); } -void DisplayMan::loadFNT1intoBitmap(uint16 index, byte* destBitmap) -{ +void DisplayMan::loadFNT1intoBitmap(uint16 index, byte* destBitmap) { uint8 *data = _packedBitmaps + _packedItemPos[index]; for (uint16 i = 0; i < 6; i++) { for (uint16 w = 0; w < 128; ++w) { @@ -817,12 +816,11 @@ void DisplayMan::blitToBitmap(byte *srcBitmap, uint16 srcWidth, uint16 srcX, uin } } - void DisplayMan::blitToBitmap(byte* srcBitmap, uint16 srcWidth, uint16 srcX, uint16 srcY, byte* destBitmap, uint16 destWidth, Box& box, Color transparent, Viewport& viewport) - { - blitToBitmap(srcBitmap, srcWidth, srcX, srcY, destBitmap, destWidth, box._x1, box._x2, box._y1, box._y2, transparent, viewport); - } +void DisplayMan::blitToBitmap(byte* srcBitmap, uint16 srcWidth, uint16 srcX, uint16 srcY, byte* destBitmap, uint16 destWidth, Box& box, Color transparent, Viewport& viewport) { + blitToBitmap(srcBitmap, srcWidth, srcX, srcY, destBitmap, destWidth, box._x1, box._x2, box._y1, box._y2, transparent, viewport); +} - void DisplayMan::blitToScreen(byte *srcBitmap, uint16 srcWidth, uint16 srcX, uint16 srcY, +void DisplayMan::blitToScreen(byte *srcBitmap, uint16 srcWidth, uint16 srcX, uint16 srcY, uint16 destFromX, uint16 destToX, uint16 destFromY, uint16 destToY, Color transparent, Viewport &viewport) { blitToBitmap(srcBitmap, srcWidth, srcX, srcY, @@ -1581,6 +1579,14 @@ byte* DisplayMan::getBitmap(uint16 index) { return _bitmaps[index]; } +Common::MemoryReadStream DisplayMan::getCompressedData(uint16 index) { + return Common::MemoryReadStream(_packedBitmaps + _packedItemPos[index], getCompressedDataSize(index), DisposeAfterUse::NO); +} + +uint32 DisplayMan::getCompressedDataSize(uint16 index) { + return _packedItemPos[index + 1] - _packedItemPos[index]; +} + void DisplayMan::clearScreenBox(Color color, Box &box, Viewport &viewport) { uint16 width = box._x2 - box._x1; for (int y = box._y1 + viewport._posY; y < box._y2 + viewport._posY; ++y) @@ -1588,8 +1594,8 @@ void DisplayMan::clearScreenBox(Color color, Box &box, Viewport &viewport) { } void DisplayMan::blitToScreen(byte *srcBitmap, uint16 srcWidth, uint16 srcX, uint16 srcY, - Box &box, - Color transparent, Viewport &viewport) { + Box &box, + Color transparent, Viewport &viewport) { blitToScreen(srcBitmap, srcWidth, srcX, srcY, box._x1, box._x2, box._y1, box._y2, transparent, viewport); } diff --git a/engines/dm/gfx.h b/engines/dm/gfx.h index e4fe12ac68..b6a32c5065 100644 --- a/engines/dm/gfx.h +++ b/engines/dm/gfx.h @@ -30,6 +30,7 @@ #include "common/scummsys.h" #include "common/rect.h" +#include "common/memstream.h" #include "dm.h" namespace DM { @@ -78,7 +79,8 @@ enum GraphicIndice { kPanelOpenScrollIndice = 23, // @ C023_GRAPHIC_PANEL_OPEN_SCROLL kPanelOpenChestIndice = 25, // @ C025_GRAPHIC_PANEL_OPEN_CHEST kEyeForObjectDescriptionIndice = 19, // @ C019_GRAPHIC_EYE_FOR_OBJECT_DESCRIPTION - kArrowForChestContentIndice = 18 // @ C018_GRAPHIC_ARROW_FOR_CHEST_CONTENT + kArrowForChestContentIndice = 18, // @ C018_GRAPHIC_ARROW_FOR_CHEST_CONTENT + kObjectDescCircleIndice = 29 // @ C029_GRAPHIC_OBJECT_DESCRIPTION_CIRCLE }; extern uint16 gPalSwoosh[16]; @@ -364,6 +366,8 @@ public: void drawDungeon(direction dir, int16 posX, int16 posY); // @ F0128_DUNGEONVIEW_Draw_CPSF void updateScreen(); byte* getBitmap(uint16 index); + Common::MemoryReadStream getCompressedData(uint16 index); + uint32 getCompressedDataSize(uint16 index); int16 _championPortraitOrdinal; // @ G0289_i_DungeonView_ChampionPortraitOrdinal int16 _currMapAlcoveOrnIndices[kAlcoveOrnCount]; // @ G0267_ai_CurrentMapAlcoveOrnamentIndices diff --git a/engines/dm/inventory.cpp b/engines/dm/inventory.cpp index 9724d83ab6..4e3d0d31bc 100644 --- a/engines/dm/inventory.cpp +++ b/engines/dm/inventory.cpp @@ -205,7 +205,7 @@ void InventoryMan::drawPanel() { if (thing == Thing::_thingNone) { drawPanelFoodWaterPoisoned(); } else { - warning("MISSING CODE: F0342_INVENTORY_DrawPanel_Object(L1075_T_Thing, C0_FALSE);"); + drawPanelObject(thing, false); } } @@ -414,4 +414,144 @@ void InventoryMan::drawPanelArrowOrEye(bool pressingEye) { 16, 0, 0, gBoxArrowOrEye, kColorRed, gDungeonViewport); } + +Box gBoxObjectDescCircle = Box(105, 136, 53, 79); // @ G0034_s_Graphic562_Box_ObjectDescriptionCircle + +#define kDescriptionMaskConsumable 0x0001 // @ MASK0x0001_DESCRIPTION_CONSUMABLE +#define kDescriptionMaskPoisoned 0x0002 // @ MASK0x0002_DESCRIPTION_POISONED +#define kDescriptionMaskBroken 0x0004 // @ MASK0x0004_DESCRIPTION_BROKEN +#define kDescriptionMaskCursed 0x0008 // @ MASK0x0008_DESCRIPTION_CURSED + +void InventoryMan::drawPanelObject(Thing thingToDraw, bool pressingEye) { + DungeonMan &dunMan = *_vm->_dungeonMan; + ObjectMan &objMan = *_vm->_objectMan; + DisplayMan &dispMan = *_vm->_displayMan; + ChampionMan &champMan = *_vm->_championMan; + TextMan &textMan = *_vm->_textMan; + + if (_vm->_pressingEye || _vm->_pressingMouth) { + warning("BUG0_48 The contents of a chest are reorganized when an object with a statistic modifier is placed or removed on a champion"); + closeChest(); + } + + uint16 *rawThingPtr = dunMan.getThingData(thingToDraw); + drawPanelObjectDescriptionString("\f"); // form feed + ThingType thingType = thingToDraw.getType(); + if (thingType == kScrollThingType) { + drawPanelScroll((Scroll*)rawThingPtr); + } else if (thingType == kContainerThingType) { + openAndDrawChest(thingToDraw, (Container*)rawThingPtr, pressingEye); + } else { + IconIndice iconIndex = objMan.getIconIndex(thingToDraw); + dispMan.blitToScreen(dispMan.getBitmap(kPanelEmptyIndice), 144, 0, 0, gBoxPanel, kColorRed, gDungeonViewport); + dispMan.blitToScreen(dispMan.getBitmap(kObjectDescCircleIndice), 32, 0, 0, gBoxObjectDescCircle, kColorDarkestGray, gDungeonViewport); + + char *descString = nullptr; + char str[40]; + if (iconIndex == kIconIndiceJunkChampionBones) { + strcpy(str, champMan._champions[((Junk*)rawThingPtr)->getChargeCount()]._name); // TODO: localization + strcat(str, " "); // TODO: localization + strcat(str, objMan._objectNames[iconIndex]); // TODO: localization + + descString = str; + } else if ((thingType == kPotionThingType) + && (iconIndex != kIconIndicePotionWaterFlask) + && (champMan.getSkillLevel((ChampionIndex)_vm->ordinalToIndex(_inventoryChampionOrdinal), kChampionSkillPriest) > 1)) { + str[0] = '_' + ((Potion*)rawThingPtr)->getPower() / 40; + str[1] = ' '; + str[2] = '\0'; + strcat(str, objMan._objectNames[iconIndex]); + descString = str; + } else { + descString = objMan._objectNames[iconIndex]; + } + + textMan.printToViewport(134, 68, kColorLightestGray, descString); + drawIconToViewport(iconIndex, 111, 59); + + char *attribString[4] = {"CONSUMABLE", "POISONED", "BROKEN", "CURSED"}; // TODO: localization + + _objDescTextYpos = 87; + + uint16 potentialAttribMask; + uint16 actualAttribMask; + switch (thingType) { + case kWeaponThingType: { + potentialAttribMask = kDescriptionMaskCursed | kDescriptionMaskPoisoned | kDescriptionMaskBroken; + Weapon *weapon = (Weapon*)rawThingPtr; + actualAttribMask = (weapon->getCursed() << 3) | (weapon->getPoisoned() << 1) | (weapon->getBroken() << 2); + if ((iconIndex >= kIconIndiceWeaponTorchUnlit) + && (iconIndex <= kIconIndiceWeaponTorchLit) + && (weapon->getChargeCount() == 0)) { + drawPanelObjectDescriptionString("(BURNT OUT)"); // TODO: localization + } + break; + } + case kArmourThingType: { + potentialAttribMask = kDescriptionMaskCursed | kDescriptionMaskBroken; + Armour *armour = (Armour*)rawThingPtr; + actualAttribMask = (armour->getCursed() << 3) | (armour->getBroken() << 2); + break; + } + case kPotionThingType: { + actualAttribMask = kDescriptionMaskConsumable; + Potion *potion = (Potion*)rawThingPtr; + actualAttribMask = gObjectInfo[kObjectInfoIndexFirstPotion + potion->getType()].getAllowedSlots(); + break; + } + case kJunkThingType: { + Junk *junk = (Junk*)rawThingPtr; + if ((iconIndex >= kIconIndiceJunkWater) && (iconIndex <= kIconIndiceJunkWaterSkin)) { + potentialAttribMask = 0; + switch (junk->getChargeCount()) { + case 0: + descString = "(EMPTY)"; // TODO: localization + break; + case 1: + descString = "(ALMOST EMPTY)"; // TODO: localization + break; + case 2: + descString = "(ALMOST FULL)"; // TODO: localization + break; + case 3: + descString = "(FULL)"; // TODO: localization + break; + } + drawPanelObjectDescriptionString(descString); + } else if ((iconIndex >= kIconIndiceJunkCompassNorth) && (iconIndex <= kIconIndiceJunkCompassWest)) { + potentialAttribMask = 0; + strcpy(str, "PARTY FACING "); // TODO: localization + static char* directionName[4] = {"NORTH", "EAST", "SOUTH", "WEST"}; // G0430_apc_DirectionNames // TODO: localization + strcat(str, directionName[iconIndex]); + drawPanelObjectDescriptionString(str); + } else { + potentialAttribMask = kDescriptionMaskConsumable; + actualAttribMask = gObjectInfo[kObjectInfoIndexFirstJunk + junk->getType()].getAllowedSlots(); + } + break; + } + } // end of switch + + if (potentialAttribMask) { + buildObjectAttributeString(potentialAttribMask, actualAttribMask, attribString, str, "(", ")"); + drawPanelObjectDescriptionString(str); + } + + strcpy(str, "WEIGHS "); // TODO: localization + + uint16 weight = dunMan.getObjectWeight(thingToDraw); + strcat(str, champMan.getStringFromInteger(weight / 10, false, 3).c_str()); + + strcat(str, "."); // TODO: localization + + weight -= (weight / 10) * 10; + strcat(str, champMan.getStringFromInteger(weight, false, 1).c_str()); + + strcat(str, " KG."); // TODO: localization + + drawPanelObjectDescriptionString(str); + } + drawPanelArrowOrEye(pressingEye); + +} } diff --git a/engines/dm/inventory.h b/engines/dm/inventory.h index 8868a53800..952511d9e8 100644 --- a/engines/dm/inventory.h +++ b/engines/dm/inventory.h @@ -77,6 +77,7 @@ public: char *destString, char *prefixString, char *suffixString); // @ F0336_INVENTORY_DrawPanel_BuildObjectAttributesString void drawPanelObjectDescriptionString(char *descString); // @ F0335_INVENTORY_DrawPanel_ObjectDescriptionString void drawPanelArrowOrEye(bool pressingEye); // @ F0339_INVENTORY_DrawPanel_ArrowOrEye + void drawPanelObject(Thing thingToDraw, bool pressingEye); // @ F0342_INVENTORY_DrawPanel_Object }; diff --git a/engines/dm/objectman.cpp b/engines/dm/objectman.cpp index c92427bf4b..c83c16c9f6 100644 --- a/engines/dm/objectman.cpp +++ b/engines/dm/objectman.cpp @@ -43,52 +43,81 @@ int16 gIconGraphicFirstIndex[7] = { // G0026_ai_Graphic562_IconGraphicFirstIconI ObjectMan::ObjectMan(DMEngine *vm) : _vm(vm) { /* 8 for champion hands in status boxes, 30 for champion inventory, 8 for chest */ - _slotBoxes[0] = SlotBox(4, 10, 0); /* Champion Status Box 0 Ready Hand */ - _slotBoxes[1] = SlotBox(24, 10, 0); /* Champion Status Box 0 Action Hand */ - _slotBoxes[2] = SlotBox(73, 10, 0); /* Champion Status Box 1 Ready Hand */ - _slotBoxes[3] = SlotBox(93, 10, 0); /* Champion Status Box 1 Action Hand */ - _slotBoxes[4] = SlotBox(142, 10, 0); /* Champion Status Box 2 Ready Hand */ - _slotBoxes[5] = SlotBox(162, 10, 0); /* Champion Status Box 2 Action Hand */ - _slotBoxes[6] = SlotBox(211, 10, 0); /* Champion Status Box 3 Ready Hand */ - _slotBoxes[7] = SlotBox(231, 10, 0); /* Champion Status Box 3 Action Hand */ - _slotBoxes[8] = SlotBox(6, 53, 0); /* Ready Hand */ - _slotBoxes[9] = SlotBox(62, 53, 0); /* Action Hand */ - _slotBoxes[10] = SlotBox(34, 26, 0); /* Head */ - _slotBoxes[11] = SlotBox(34, 46, 0); /* Torso */ - _slotBoxes[12] = SlotBox(34, 66, 0); /* Legs */ - _slotBoxes[13] = SlotBox(34, 86, 0); /* Feet */ - _slotBoxes[14] = SlotBox(6, 90, 0); /* Pouch 2 */ - _slotBoxes[15] = SlotBox(79, 73, 0); /* Quiver Line2 1 */ - _slotBoxes[16] = SlotBox(62, 90, 0); /* Quiver Line1 2 */ - _slotBoxes[17] = SlotBox(79, 90, 0); /* Quiver Line2 2 */ - _slotBoxes[18] = SlotBox(6, 33, 0); /* Neck */ - _slotBoxes[19] = SlotBox(6, 73, 0); /* Pouch 1 */ - _slotBoxes[20] = SlotBox(62, 73, 0); /* Quiver Line1 1 */ - _slotBoxes[21] = SlotBox(66, 33, 0); /* Backpack Line1 1 */ - _slotBoxes[22] = SlotBox(83, 16, 0); /* Backpack Line2 2 */ - _slotBoxes[23] = SlotBox(100, 16, 0); /* Backpack Line2 3 */ - _slotBoxes[24] = SlotBox(117, 16, 0); /* Backpack Line2 4 */ - _slotBoxes[25] = SlotBox(134, 16, 0); /* Backpack Line2 5 */ - _slotBoxes[26] = SlotBox(151, 16, 0); /* Backpack Line2 6 */ - _slotBoxes[27] = SlotBox(168, 16, 0); /* Backpack Line2 7 */ - _slotBoxes[28] = SlotBox(185, 16, 0); /* Backpack Line2 8 */ - _slotBoxes[29] = SlotBox(202, 16, 0); /* Backpack Line2 9 */ - _slotBoxes[30] = SlotBox(83, 33, 0); /* Backpack Line1 2 */ - _slotBoxes[31] = SlotBox(100, 33, 0); /* Backpack Line1 3 */ - _slotBoxes[32] = SlotBox(117, 33, 0); /* Backpack Line1 4 */ - _slotBoxes[33] = SlotBox(134, 33, 0); /* Backpack Line1 5 */ - _slotBoxes[34] = SlotBox(151, 33, 0); /* Backpack Line1 6 */ - _slotBoxes[35] = SlotBox(168, 33, 0); /* Backpack Line1 7 */ - _slotBoxes[36] = SlotBox(185, 33, 0); /* Backpack Line1 8 */ - _slotBoxes[37] = SlotBox(202, 33, 0); /* Backpack Line1 9 */ - _slotBoxes[38] = SlotBox(117, 59, 0); /* Chest 1 */ - _slotBoxes[39] = SlotBox(106, 76, 0); /* Chest 2 */ - _slotBoxes[40] = SlotBox(111, 93, 0); /* Chest 3 */ - _slotBoxes[41] = SlotBox(128, 98, 0); /* Chest 4 */ + _slotBoxes[0] = SlotBox(4, 10, 0); /* Champion Status Box 0 Ready Hand */ + _slotBoxes[1] = SlotBox(24, 10, 0); /* Champion Status Box 0 Action Hand */ + _slotBoxes[2] = SlotBox(73, 10, 0); /* Champion Status Box 1 Ready Hand */ + _slotBoxes[3] = SlotBox(93, 10, 0); /* Champion Status Box 1 Action Hand */ + _slotBoxes[4] = SlotBox(142, 10, 0); /* Champion Status Box 2 Ready Hand */ + _slotBoxes[5] = SlotBox(162, 10, 0); /* Champion Status Box 2 Action Hand */ + _slotBoxes[6] = SlotBox(211, 10, 0); /* Champion Status Box 3 Ready Hand */ + _slotBoxes[7] = SlotBox(231, 10, 0); /* Champion Status Box 3 Action Hand */ + _slotBoxes[8] = SlotBox(6, 53, 0); /* Ready Hand */ + _slotBoxes[9] = SlotBox(62, 53, 0); /* Action Hand */ + _slotBoxes[10] = SlotBox(34, 26, 0); /* Head */ + _slotBoxes[11] = SlotBox(34, 46, 0); /* Torso */ + _slotBoxes[12] = SlotBox(34, 66, 0); /* Legs */ + _slotBoxes[13] = SlotBox(34, 86, 0); /* Feet */ + _slotBoxes[14] = SlotBox(6, 90, 0); /* Pouch 2 */ + _slotBoxes[15] = SlotBox(79, 73, 0); /* Quiver Line2 1 */ + _slotBoxes[16] = SlotBox(62, 90, 0); /* Quiver Line1 2 */ + _slotBoxes[17] = SlotBox(79, 90, 0); /* Quiver Line2 2 */ + _slotBoxes[18] = SlotBox(6, 33, 0); /* Neck */ + _slotBoxes[19] = SlotBox(6, 73, 0); /* Pouch 1 */ + _slotBoxes[20] = SlotBox(62, 73, 0); /* Quiver Line1 1 */ + _slotBoxes[21] = SlotBox(66, 33, 0); /* Backpack Line1 1 */ + _slotBoxes[22] = SlotBox(83, 16, 0); /* Backpack Line2 2 */ + _slotBoxes[23] = SlotBox(100, 16, 0); /* Backpack Line2 3 */ + _slotBoxes[24] = SlotBox(117, 16, 0); /* Backpack Line2 4 */ + _slotBoxes[25] = SlotBox(134, 16, 0); /* Backpack Line2 5 */ + _slotBoxes[26] = SlotBox(151, 16, 0); /* Backpack Line2 6 */ + _slotBoxes[27] = SlotBox(168, 16, 0); /* Backpack Line2 7 */ + _slotBoxes[28] = SlotBox(185, 16, 0); /* Backpack Line2 8 */ + _slotBoxes[29] = SlotBox(202, 16, 0); /* Backpack Line2 9 */ + _slotBoxes[30] = SlotBox(83, 33, 0); /* Backpack Line1 2 */ + _slotBoxes[31] = SlotBox(100, 33, 0); /* Backpack Line1 3 */ + _slotBoxes[32] = SlotBox(117, 33, 0); /* Backpack Line1 4 */ + _slotBoxes[33] = SlotBox(134, 33, 0); /* Backpack Line1 5 */ + _slotBoxes[34] = SlotBox(151, 33, 0); /* Backpack Line1 6 */ + _slotBoxes[35] = SlotBox(168, 33, 0); /* Backpack Line1 7 */ + _slotBoxes[36] = SlotBox(185, 33, 0); /* Backpack Line1 8 */ + _slotBoxes[37] = SlotBox(202, 33, 0); /* Backpack Line1 9 */ + _slotBoxes[38] = SlotBox(117, 59, 0); /* Chest 1 */ + _slotBoxes[39] = SlotBox(106, 76, 0); /* Chest 2 */ + _slotBoxes[40] = SlotBox(111, 93, 0); /* Chest 3 */ + _slotBoxes[41] = SlotBox(128, 98, 0); /* Chest 4 */ _slotBoxes[42] = SlotBox(145, 101, 0); /* Chest 5 */ _slotBoxes[43] = SlotBox(162, 103, 0); /* Chest 6 */ _slotBoxes[44] = SlotBox(179, 104, 0); /* Chest 7 */ _slotBoxes[45] = SlotBox(196, 105, 0); /* Chest 8 */ + + _objectIconForMousePointer = nullptr; +} + +ObjectMan::~ObjectMan() { + delete[] _objectIconForMousePointer; + delete[] _objectNames[0]; +} + +#define kObjectNamesGraphicIndice 556 // @ C556_GRAPHIC_OBJECT_NAMES + +void ObjectMan::loadObjectNames() { + DisplayMan &dispMan = *_vm->_displayMan; + + _objectIconForMousePointer = new byte[16 * 16]; + + char *objectNames = new char[dispMan.getCompressedDataSize(kObjectNamesGraphicIndice) + kObjectNameCount]; + Common::MemoryReadStream stream = dispMan.getCompressedData(kObjectNamesGraphicIndice); + + for (uint16 objNameIndex = 0; objNameIndex < kObjectNameCount; ++objNameIndex) { + _objectNames[objNameIndex] = objectNames; + + byte tmpByte; + for (tmpByte = stream.readByte(); !(tmpByte & 0x80); tmpByte = stream.readByte()) // last char of object name has 7th bit on + *objectNames++ = tmpByte; // write while not last char + + *objectNames++ = tmpByte & 0x7F; // write without the 7th bit + *objectNames++ = '\0'; // terminate string + } } IconIndice ObjectMan::getObjectType(Thing thing) { @@ -109,7 +138,7 @@ IconIndice ObjectMan::getIconIndex(Thing thing) { if ((iconIndex != kIconIndiceNone) && (((iconIndex < kIconIndiceWeaponDagger) && (iconIndex >= kIconIndiceJunkCompassNorth)) || // < instead of <= is no error - ((iconIndex >= kIconIndicePotionMaPotionMonPotion) && (iconIndex <= kIconIndicePotionWaterFlask)) || + ((iconIndex >= kIconIndicePotionMaPotionMonPotion) && (iconIndex <= kIconIndicePotionWaterFlask)) || (iconIndex == kIconIndicePotionEmptyFlask)) ) { uint16 *rawType = _vm->_dungeonMan->getThingData(thing); @@ -178,9 +207,9 @@ void ObjectMan::drawIconInSlotBox(uint16 slotBoxIndex, int16 iconIndex) { Box box; box._x1 = slotBox->_x; box._y1 = slotBox->_y; - box._x2 = box._x1 + 15 + 1; + box._x2 = box._x1 + 15 + 1; box._y2 = box._y1 + 15 + 1; - + uint16 iconGraphicIndex; for (iconGraphicIndex = 0; iconGraphicIndex < 7; ++iconGraphicIndex) { if (gIconGraphicFirstIndex[iconGraphicIndex] > iconIndex) { diff --git a/engines/dm/objectman.h b/engines/dm/objectman.h index 1dbba692bf..e01d06404e 100644 --- a/engines/dm/objectman.h +++ b/engines/dm/objectman.h @@ -35,6 +35,8 @@ namespace DM { #define kSlotBoxInventoryActionHand 9 // @ C09_SLOT_BOX_INVENTORY_ACTION_HAND #define kSlotBoxChestFirstSlot 38 // @ C38_SLOT_BOX_CHEST_FIRST_SLOT +#define kObjectNameCount 199 // @ C199_OBJECT_NAME_COUNT + class SlotBox { public: int16 _x; @@ -49,8 +51,12 @@ class ObjectMan { public: explicit ObjectMan(DMEngine *vm); + ~ObjectMan(); + void loadObjectNames(); // @ F0031_OBJECT_LoadNames SlotBox _slotBoxes[46]; // @ G0030_as_Graphic562_SlotBoxes; + char *_objectNames[kObjectNameCount]; // @ G0352_apc_ObjectNames + byte *_objectIconForMousePointer; // @ G0412_puc_Bitmap_ObjectIconForMousePointer IconIndice getObjectType(Thing thing); // @ F0032_OBJECT_GetType IconIndice getIconIndex(Thing thing); // @ F0033_OBJECT_GetIconIndex |