aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2015-01-03 19:08:30 -0500
committerPaul Gilbert2015-01-03 19:08:30 -0500
commitf9316bf14107c3ac46bd8bb53da9665c3652c381 (patch)
treeeae46a4026a85457428873933adf57b5371ee4d7
parent97cd5a7e6961be52d545e3c131a85cd90c582441 (diff)
downloadscummvm-rg350-f9316bf14107c3ac46bd8bb53da9665c3652c381.tar.gz
scummvm-rg350-f9316bf14107c3ac46bd8bb53da9665c3652c381.tar.bz2
scummvm-rg350-f9316bf14107c3ac46bd8bb53da9665c3652c381.zip
XEEN: Implemented charIconsPrint
-rw-r--r--engines/xeen/interface.cpp115
-rw-r--r--engines/xeen/interface.h11
-rw-r--r--engines/xeen/party.cpp75
-rw-r--r--engines/xeen/party.h42
-rw-r--r--engines/xeen/resources.cpp47
-rw-r--r--engines/xeen/resources.h22
-rw-r--r--engines/xeen/screen.cpp16
-rw-r--r--engines/xeen/screen.h19
-rw-r--r--engines/xeen/xeen.h7
9 files changed, 284 insertions, 70 deletions
diff --git a/engines/xeen/interface.cpp b/engines/xeen/interface.cpp
index cdb9204537..3a07cecec6 100644
--- a/engines/xeen/interface.cpp
+++ b/engines/xeen/interface.cpp
@@ -39,6 +39,13 @@ Interface::Interface(XeenEngine *vm) : ButtonContainer(), _vm(vm) {
_heroismUIFrame = 0;
_isEarlyGame = false;
_buttonsLoaded = false;
+ _hiliteChar = -1;
+ Common::fill(&_combatCharIds[0], &_combatCharIds[8], 0);
+
+ _faceDrawStructs[0] = DrawStruct(nullptr, 0, 0, 0);
+ _faceDrawStructs[1] = DrawStruct(nullptr, 0, 101, 0);
+ _faceDrawStructs[2] = DrawStruct(nullptr, 0, 0, 43);
+ _faceDrawStructs[3] = DrawStruct(nullptr, 0, 101, 43);
loadSprites();
}
@@ -49,9 +56,12 @@ void Interface::loadSprites() {
_spellFxSprites.load("spellfx.icn");
_fecpSprites.load("fecp.brd");
_blessSprites.load("bless.icn");
+ _restoreSprites.load("restorex.icn");
+ _hpSprites.load("hpbars.icn");
}
void Interface::setup(bool soundPlayed) {
+ Screen &screen = *_vm->_screen;
SpriteResource uiSprites("inn.icn");
// Get mappings to the active characters in the party
@@ -88,6 +98,7 @@ void Interface::setup(bool soundPlayed) {
}
// Add in buttons for the UI
+ _interfaceText = "";
_buttonsLoaded = true;
addButton(Common::Rect(16, 100, 40, 120), 242, &uiSprites, true);
addButton(Common::Rect(52, 100, 76, 120), 243, &uiSprites, true);
@@ -102,6 +113,11 @@ void Interface::setup(bool soundPlayed) {
addButton(Common::Rect(117, 59, 149, 81), 52, &uiSprites, false);
setupBackground();
+ screen._windows[11].open();
+ setupFaces(0, xeenSideChars, 0);
+ screen._windows[11].writeString(_interfaceText);
+
+ // TODO
}
}
@@ -228,4 +244,103 @@ void Interface::assembleBorder() {
screen._windows[12].frame();
}
+void Interface::setupFaces(int charIndex, Common::Array<int> xeenSideChars, int v3) {
+ Common::String playerNames[4];
+ Common::String playerRaces[4];
+ Common::String playerSex[4];
+ Common::String playerClass[4];
+ int posIndex;
+ int charId;
+
+ for (posIndex = 0; posIndex < 4; ++posIndex) {
+ int charId = xeenSideChars[charIndex];
+ bool isInParty = _vm->_party.isInParty(charId);
+
+ if (charId == 0xff) {
+ while ((int)_buttons.size() > (7 + posIndex))
+ _buttons.remove_at(_buttons.size() - 1);
+ break;
+ }
+
+ Common::Rect &b = _buttons[7 + posIndex]._bounds;
+ b.moveTo((posIndex & 1) ? 117 : 16, b.top);
+ PlayerStruct &ps = _vm->_roster[xeenSideChars[charIndex + posIndex]];
+ playerNames[posIndex] = isInParty ? IN_PARTY : ps._name;
+ playerRaces[posIndex] = RACE_NAMES[ps._race];
+ playerSex[posIndex] = SEX_NAMES[ps._sex];
+ playerClass[posIndex] = CLASS_NAMES[ps._class];
+ }
+
+ charIconsPrint(v3);
+
+ // Set up the sprite set to use for each face
+ charId = xeenSideChars[charIndex];
+ _faceDrawStructs[0]._sprites = (charId == 0xff) ? (SpriteResource *)nullptr : &_charFaces[charId];
+ charId = xeenSideChars[charIndex + 1];
+ _faceDrawStructs[1]._sprites = (charId == 0xff) ? (SpriteResource *)nullptr : &_charFaces[charId];
+ charId = xeenSideChars[charIndex + 2];
+ _faceDrawStructs[2]._sprites = (charId == 0xff) ? (SpriteResource *)nullptr : &_charFaces[charId];
+ charId = xeenSideChars[charIndex + 3];
+ _faceDrawStructs[3]._sprites = (charId == 0xff) ? (SpriteResource *)nullptr : &_charFaces[charId];
+
+ _interfaceText = Common::String::format(PARTY_DETAILS,
+ playerNames[0].c_str(), playerRaces[0].c_str(), playerSex[0].c_str(), playerClass[0].c_str(),
+ playerNames[1].c_str(), playerRaces[1].c_str(), playerSex[1].c_str(), playerClass[1].c_str(),
+ playerNames[2].c_str(), playerRaces[2].c_str(), playerSex[2].c_str(), playerClass[2].c_str(),
+ playerNames[3].c_str(), playerRaces[3].c_str(), playerSex[3].c_str(), playerClass[3].c_str()
+ );
+}
+
+void Interface::charIconsPrint(bool updateFlag) {
+ Screen &screen = *_vm->_screen;
+ bool stateFlag = _vm->_mode == MODE_2;
+ _restoreSprites.draw(screen, 0, Common::Point(8, 149));
+
+ // Handle drawing the party faces
+ for (int idx = 0; idx < (stateFlag ? _vm->_party._combatPartyCount :
+ _vm->_party._partyCount); ++idx) {
+ int charIndex = stateFlag ? _combatCharIds[idx] : idx;
+ PlayerStruct &ps = *_vm->_party._activeParty[charIndex];
+ Condition charCondition = ps.findCondition();
+ int charFrame = FACE_CONDITION_FRAMES[charCondition];
+
+ SpriteResource *sprites = (charFrame > 4 && !_charFaces[0].empty()) ?
+ &_dseFace : _partyFaces[charIndex];
+ if (charFrame > 4)
+ charFrame -= 5;
+
+ sprites->draw(screen, charFrame, Common::Point(CHAR_FACES_X[idx], 150));
+ }
+
+ if (!_hpSprites.empty()) {
+ for (int idx = 0; idx < (stateFlag ? _vm->_party._combatPartyCount :
+ _vm->_party._partyCount); ++idx) {
+ int charIndex = stateFlag ? _combatCharIds[idx] : idx;
+ PlayerStruct &ps = *_vm->_party._activeParty[charIndex];
+
+ // Draw the Hp bar
+ int maxHp = ps.getMaxHp();
+ int frame;
+ if (ps._currentHp < 1)
+ frame = 4;
+ else if (ps._currentHp > maxHp)
+ frame = 3;
+ else if (ps._currentHp == maxHp)
+ frame = 0;
+ else if (ps._currentHp < (maxHp / 4))
+ frame = 2;
+ else
+ frame = 1;
+
+ _hpSprites.draw(screen, frame, Common::Point(HP_BARS_X[idx], 182));
+ }
+ }
+
+ if (_hiliteChar != -1)
+ _globalSprites.draw(screen, 8, Common::Point(CHAR_FACES_X[_hiliteChar] - 1, 149));
+
+ if (updateFlag)
+ screen._windows[33].update();
+}
+
} // End of namespace Xeen
diff --git a/engines/xeen/interface.h b/engines/xeen/interface.h
index 565fe84273..3ceb08239e 100644
--- a/engines/xeen/interface.h
+++ b/engines/xeen/interface.h
@@ -26,6 +26,7 @@
#include "common/scummsys.h"
#include "xeen/dialogs.h"
#include "xeen/party.h"
+#include "xeen/screen.h"
namespace Xeen {
@@ -40,8 +41,12 @@ private:
SpriteResource _spellFxSprites;
SpriteResource _fecpSprites;
SpriteResource _blessSprites;
+ SpriteResource _restoreSprites;
+ SpriteResource _hpSprites;
SpriteResource _charFaces[TOTAL_CHARACTERS];
SpriteResource *_partyFaces[MAX_ACTIVE_PARTY];
+ DrawStruct _faceDrawStructs[4];
+ int _combatCharIds[8];
int _batUIFrame;
int _spotDoorsUIFrame;
@@ -54,6 +59,8 @@ private:
int _heroismUIFrame;
bool _isEarlyGame;
bool _buttonsLoaded;
+ Common::String _interfaceText;
+ int _hiliteChar;
void loadSprites();
@@ -62,6 +69,10 @@ private:
void assembleBorder();
void setupBackground();
+
+ void setupFaces(int charIndex, Common::Array<int> xeenSideChars, int v3);
+
+ void charIconsPrint(bool updateFlag);
public:
Interface(XeenEngine *vm);
diff --git a/engines/xeen/party.cpp b/engines/xeen/party.cpp
index 97b4a768cd..25366d52ed 100644
--- a/engines/xeen/party.cpp
+++ b/engines/xeen/party.cpp
@@ -40,46 +40,6 @@ void AttributePair::synchronize(Common::Serializer &s) {
/*------------------------------------------------------------------------*/
-Conditions::Conditions() {
- _cursed = 0;
- _heartBroken = 0;
- _weak = 0;
- _poisoned = 0;
- _diseased = 0;
- _insane = 0;
- _inLove = 0;
- _drunk = 0;
- _asleep = 0;
- _depressed = 0;
- _confused = 0;
- _paralyzed = 0;
- _unconscious = 0;
- _dead = 0;
- _stoned = 0;
- _eradicated = 0;
-}
-
-void Conditions::synchronize(Common::Serializer &s) {
- s.syncAsByte(_cursed);
- s.syncAsByte(_heartBroken);
- s.syncAsByte(_weak);
- s.syncAsByte(_poisoned);
- s.syncAsByte(_diseased);
- s.syncAsByte(_insane);
- s.syncAsByte(_inLove);
- s.syncAsByte(_drunk);
- s.syncAsByte(_asleep);
- s.syncAsByte(_depressed);
- s.syncAsByte(_confused);
- s.syncAsByte(_paralyzed);
- s.syncAsByte(_unconscious);
- s.syncAsByte(_dead);
- s.syncAsByte(_stoned);
- s.syncAsByte(_eradicated);
-}
-
-/*------------------------------------------------------------------------*/
-
PlayerStruct::PlayerStruct() {
_sex = MALE;
_race = HUMAN;
@@ -96,6 +56,7 @@ PlayerStruct::PlayerStruct() {
_currentSpell = 0;
_quickOption = 0;
_lloydSide = 0;
+ Common::fill(&_conditions[0], &_conditions[16], 0);
_townUnknown = 0;
_unknown2 = 0;
_currentHp = 0;
@@ -161,7 +122,8 @@ void PlayerStruct::synchronize(Common::Serializer &s) {
_energyResistence.synchronize(s);
_magicResistence.synchronize(s);
- _conditions.synchronize(s);
+ for (int i = 0; i < 16; ++i)
+ s.syncAsByte(_conditions[i]);
s.syncAsUint16LE(_townUnknown);
s.syncAsByte(_unknown2);
@@ -173,6 +135,26 @@ void PlayerStruct::synchronize(Common::Serializer &s) {
s.syncAsByte(_currentCombatSpell);
}
+Condition PlayerStruct::findCondition() const {
+ for (int cond = ERADICATED; cond >= CURSED; --cond) {
+ if (_conditions[cond])
+ return (Condition)cond;
+ }
+
+ return NO_CONDITION;
+}
+
+int PlayerStruct::getYear(int partyYear, bool ignoreTemp) {
+ int year = MIN(partyYear - _ybDay, 254);
+
+ return ignoreTemp ? year : year + _tempAge;
+}
+
+int PlayerStruct::getMaxHp() {
+ warning("TODO: getMaxHp");
+ return 20;
+}
+
/*------------------------------------------------------------------------*/
void Roster::synchronize(Common::Serializer &s) {
@@ -232,6 +214,8 @@ Party::Party() {
for (int i = 0; i < TOTAL_CHARACTERS; ++i)
Common::fill(&_characterFlags[i][0], &_characterFlags[i][24], false);
+
+ _combatPartyCount = 0;
}
void Party::synchronize(Common::Serializer &s) {
@@ -342,4 +326,13 @@ bool Party::checkSkill(Skill skillId) {
}
}
+bool Party::isInParty(int charId) {
+ for (int i = 0; i < 8; ++i) {
+ if (_partyMembers[i] == charId)
+ return true;
+ }
+
+ return false;
+}
+
} // End of namespace Xeen
diff --git a/engines/xeen/party.h b/engines/xeen/party.h
index d52153739d..7e5010427f 100644
--- a/engines/xeen/party.h
+++ b/engines/xeen/party.h
@@ -50,9 +50,11 @@ enum Skill { THIEVERY = 0, ARMS_MASTER = 1, ASTROLOGER = 2, BODYBUILDER = 3,
SPOT_DOORS = 16, DANGER_SENSE = 17
};
-enum ConditionType { CURSED = 0, HEART_BROKEN = 1, WEAK = 2, POISONED = 3,
+enum Condition { CURSED = 0, HEART_BROKEN = 1, WEAK = 2, POISONED = 3,
DISEASED = 4, INSANE = 5, IN_LOVE = 6, DRUNK = 7, SLEEP = 8,
- DEPRESSED = 9, CONFUSED = 10, PARALYZED = 11
+ DEPRESSED = 9, CONFUSED = 10, PARALYZED = 11, UNCONSCIOUS = 12,
+ DEAD = 13, STONED = 14, ERADICATED = 15,
+ NO_CONDITION = 16
};
#define ITEMS_COUNT 36
@@ -71,29 +73,6 @@ public:
void synchronize(Common::Serializer &s);
};
-class Conditions {
- byte _cursed;
- byte _heartBroken;
- byte _weak;
- byte _poisoned;
- byte _diseased;
- byte _insane;
- byte _inLove;
- byte _drunk;
- byte _asleep;
- byte _depressed;
- byte _confused;
- byte _paralyzed;
- byte _unconscious;
- byte _dead;
- byte _stoned;
- byte _eradicated;
-public:
- Conditions();
-
- void synchronize(Common::Serializer &s);
-};
-
class PlayerStruct {
public:
Common::String _name;
@@ -131,7 +110,7 @@ public:
AttributePair _poisonResistence;
AttributePair _energyResistence;
AttributePair _magicResistence;
- Conditions _conditions;
+ int _conditions[16];
int _townUnknown;
int _unknown2;
int _currentHp;
@@ -143,6 +122,12 @@ public:
public:
PlayerStruct();
void synchronize(Common::Serializer &s);
+
+ Condition findCondition() const;
+
+ int getYear(int partyYear, bool ignoreTemp);
+
+ int getMaxHp();
};
class Roster: public Common::Array<PlayerStruct> {
@@ -154,6 +139,7 @@ public:
class Party {
public:
+ // Dynamic data that's saved
int _partyCount;
int _realPartyCount;
int _partyMembers[8];
@@ -208,13 +194,17 @@ public:
XeenItem _blacksmithMisc2[ITEMS_COUNT];
bool _characterFlags[30][24];
public:
+ // Other party related runtime data
Common::Array<PlayerStruct *> _activeParty;
+ int _combatPartyCount;
public:
Party();
void synchronize(Common::Serializer &s);
bool checkSkill(Skill skillId);
+
+ bool isInParty(int charId);
};
} // End of namespace Xeen
diff --git a/engines/xeen/resources.cpp b/engines/xeen/resources.cpp
index d7d3fccf98..79e8ba183c 100644
--- a/engines/xeen/resources.cpp
+++ b/engines/xeen/resources.cpp
@@ -232,6 +232,51 @@ const byte TEXT_COLORS[40][4] = {
{ 0x00, 0xDB, 0xDB, 0xDB },
};
-const char *DIRECTION_TEXT[4] = { "NORTH", "EAST", "SOUTH", "WEST" };
+const char *const DIRECTION_TEXT[4] = { "NORTH", "EAST", "SOUTH", "WEST" };
+
+const char *const RACE_NAMES[5] = { "Human", "Elf", "Dwarf", "Gnome", "H-Orc" };
+
+const char *const ALIGNMENT_NAMES[3] = { "Good", "Neutral", "Evil" };
+
+const char *const SEX_NAMES[2] = { "Male", "Female" };
+
+const char *const CLASS_NAMES[11] = {
+ "Knight", "Paladin", "Archer", "Cleric", "Sorcerer", "Robber",
+ "Ninja", "Barbarian", "Druid", "Ranger", nullptr
+};
+
+const char *const CONDITION_NAMES[18] = {
+ nullptr, "Cursed", "Heart Broken", "Weak", "Poisoned", "Diseased",
+ "Insane", "In Love", "Drunk", "Asleep", "Depressed", "Confused",
+ "Paralyzed", "Unconscious", "Dead", "Stone", "Eradicated", "Good"
+};
+
+const char *const IN_PARTY = "\014""15In Party\014""d";
+
+const char *const PARTY_DETAILS = "\015\003l\002\014""00"
+ "\013""001""\011""035%s"
+ "\013""009""\011""035%s"
+ "\013""017""\011""035%s"
+ "\013""025""\011""035%s"
+ "\013""001""\011""136%s"
+ "\013""009""\011""136%s"
+ "\013""017""\011""136%s"
+ "\013""025""\011""136%s"
+ "\013""044""\011""035%s"
+ "\013""052""\011""035%s"
+ "\013""060""\011""035%s"
+ "\013""068""\011""035%s"
+ "\013""044""\011""136%s"
+ "\013""052""\011""136%s"
+ "\013""060""\011""136%s"
+ "\013""068""\011""136%s";
+
+const int FACE_CONDITION_FRAMES[17] = {
+ 2, 2, 2, 1, 1, 4, 4, 4, 3, 2, 4, 3, 3, 5, 6, 7, 0
+};
+
+const int CHAR_FACES_X[6] = { 10, 45, 81, 117, 153, 189 };
+
+const int HP_BARS_X[6] = { 13, 50, 86, 122, 158, 194 };
} // End of namespace Xeen
diff --git a/engines/xeen/resources.h b/engines/xeen/resources.h
index cf4207b814..80febec9b4 100644
--- a/engines/xeen/resources.h
+++ b/engines/xeen/resources.h
@@ -36,7 +36,27 @@ extern const byte SYMBOLS[20][64];
extern const byte TEXT_COLORS[40][4];
-extern const char *DIRECTION_TEXT[4];
+extern const char *const DIRECTION_TEXT[4];
+
+extern const char *const RACE_NAMES[5];
+
+extern const char *const CLASS_NAMES[11];
+
+extern const char *const ALIGNMENT_NAMES[3];
+
+extern const char *const SEX_NAMES[2];
+
+extern const char *const CONDITION_NAMES[18];
+
+extern const char *const IN_PARTY;
+
+extern const char *const PARTY_DETAILS;
+
+extern const int FACE_CONDITION_FRAMES[17];
+
+extern const int CHAR_FACES_X[6];
+
+extern const int HP_BARS_X[6];
} // End of namespace Xeen
diff --git a/engines/xeen/screen.cpp b/engines/xeen/screen.cpp
index f3cbabcfdd..ba2c97b267 100644
--- a/engines/xeen/screen.cpp
+++ b/engines/xeen/screen.cpp
@@ -166,6 +166,22 @@ void Window::writeString(const Common::String &s) {
_vm->_screen->writeString(s, _innerBounds);
}
+void Window::drawList(DrawStruct *items) {
+ Screen &screen = *_vm->_screen;
+
+ for (; items->_sprites != nullptr; ++items) {
+ if (items->_frame == -1 || items->_scale == -1)
+ continue;
+
+ Common::Rect bounds = _innerBounds;
+ bounds.translate(items->_x, items->_y);
+
+ // TODO: There are two sprite calls in this method. Figure out why
+ items->_sprites->draw(screen, items->_frame,
+ Common::Point(items->_x, items->_y));
+ }
+}
+
/*------------------------------------------------------------------------*/
/**
diff --git a/engines/xeen/screen.h b/engines/xeen/screen.h
index d62191e501..ae38ec3a03 100644
--- a/engines/xeen/screen.h
+++ b/engines/xeen/screen.h
@@ -28,6 +28,7 @@
#include "common/array.h"
#include "common/rect.h"
#include "xeen/font.h"
+#include "xeen/sprites.h"
#include "xeen/xsurface.h"
namespace Xeen {
@@ -41,6 +42,19 @@ namespace Xeen {
class XeenEngine;
class Screen;
+struct DrawStruct {
+ SpriteResource *_sprites;
+ int _frame;
+ int _x;
+ int _y;
+ int _scale;
+ int _flags;
+
+ DrawStruct(SpriteResource *sprites, int frame, int x, int y, int scale = 0, int flags = 0) :
+ _sprites(sprites), _frame(frame), _x(x), _y(y), _scale(scale), _flags(flags) {}
+ DrawStruct(): _sprites(nullptr), _frame(0), _x(0), _y(0), _scale(0), _flags(0) {}
+};
+
class Window: public XSurface {
private:
XeenEngine *_vm;
@@ -74,7 +88,10 @@ public:
void fill();
- void writeString(const Common::String &s);};
+ void writeString(const Common::String &s);
+
+ void drawList(DrawStruct *items);
+};
class Screen: public FontSurface {
private:
diff --git a/engines/xeen/xeen.h b/engines/xeen/xeen.h
index a549c15df4..a7210ca871 100644
--- a/engines/xeen/xeen.h
+++ b/engines/xeen/xeen.h
@@ -70,6 +70,13 @@ enum XeenDebugChannels {
enum Mode {
MODE_0 = 0,
MODE_1 = 1,
+ MODE_2 = 2,
+ MODE_3 = 3,
+ MODE_4 = 4,
+ MODE_5 = 5,
+ MODE_6 = 6,
+ MODE_7 = 7,
+ MODE_8 = 8,
MODE_9 = 9
};