Skip to content

Commit

Permalink
KYRA: (EOB) - complete CGA graphics mode implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
athrxx committed Feb 21, 2012
1 parent 86a817b commit 151d314
Show file tree
Hide file tree
Showing 16 changed files with 519 additions and 333 deletions.
5 changes: 3 additions & 2 deletions engines/kyra/eob.cpp
Expand Up @@ -55,7 +55,8 @@ Common::Error EoBEngine::init() {

initStaticResource();

_itemsOverlay = _res->fileData((_configRenderMode == Common::kRenderEGA || _configRenderMode == Common::kRenderCGA) ? "ITEMRMP.EGA" : "ITEMRMP.VGA", 0);
if (_configRenderMode != Common::kRenderCGA)
_itemsOverlay = _res->fileData((_configRenderMode == Common::kRenderEGA) ? "ITEMRMP.EGA" : "ITEMRMP.VGA", 0);

_screen->modifyScreenDim(7, 0x01, 0xB3, 0x22, 0x12);
_screen->modifyScreenDim(9, 0x01, 0x7D, 0x26, 0x3F);
Expand Down Expand Up @@ -553,7 +554,7 @@ void EoBEngine::healParty() {
}

const KyraRpgGUISettings *EoBEngine::guiSettings() {
return &_guiSettings;
return (_configRenderMode == Common::kRenderCGA || _configRenderMode == Common::kRenderEGA) ? &_guiSettingsEGA : &_guiSettingsVGA;
}

} // End of namespace Kyra
Expand Down
3 changes: 2 additions & 1 deletion engines/kyra/eob.h
Expand Up @@ -108,7 +108,8 @@ friend class EoBIntroPlayer;

const KyraRpgGUISettings *guiSettings();

static const KyraRpgGUISettings _guiSettings;
static const KyraRpgGUISettings _guiSettingsVGA;
static const KyraRpgGUISettings _guiSettingsEGA;
static const uint8 _egaDefaultPalette[];
};

Expand Down
34 changes: 13 additions & 21 deletions engines/kyra/eobcommon.cpp
Expand Up @@ -65,7 +65,6 @@ EoBCoreEngine::EoBCoreEngine(OSystem *system, const GameFlags &flags)
_itemIconShapes = _wallOfForceShapes = _teleporterShapes = _sparkShapes = _compassShapes = 0;
_redSplatShape = _greenSplatShape = _deadCharShape = _disabledCharGrid = 0;
_blackBoxSmallGrid = _weaponSlotGrid = _blackBoxWideGrid = _lightningColumnShape = 0;
_tempIconShape = 0;

_monsterDustStrings = 0;
_enemyMageSpellList = 0;
Expand Down Expand Up @@ -93,7 +92,7 @@ EoBCoreEngine::EoBCoreEngine(OSystem *system, const GameFlags &flags)
_doorSwitches = 0;
_monsterProps = 0;
_monsterDecorations = 0;
_monsterOvl1 = _monsterOvl2 = 0;
_monsterFlashOverlay = _monsterStoneOverlay = 0;
_monsters = 0;
_dstMonsterIndex = 0;
_preventMonsterFlash = false;
Expand Down Expand Up @@ -214,7 +213,7 @@ EoBCoreEngine::EoBCoreEngine(OSystem *system, const GameFlags &flags)
_mnNumWord = _numSpells = _mageSpellListSize = _spellLevelsMageSize = _spellLevelsClericSize = 0;
_inventorySlotsX = _slotValidationFlags = _encodeMonsterShpTable = 0;
_cgaMappingDefault = _cgaMappingAlt = _cgaMappingInv = _cgaLevelMappingIndex = _cgaMappingItemsL = _cgaMappingItemsS = _cgaMappingThrown = _cgaMappingIcons = _cgaMappingDeco = 0;
memset(_cgaMappingLevel, 0, sizeof(_cgaMappingLevel));
memset(_cgaMappingLevel, 0, sizeof(_cgaMappingLevel));
memset(_expRequirementTables, 0, sizeof(_expRequirementTables));
memset(_saveThrowTables, 0, sizeof(_saveThrowTables));
memset(_doorType, 0, sizeof(_doorType));
Expand Down Expand Up @@ -271,8 +270,8 @@ EoBCoreEngine::~EoBCoreEngine() {
delete[] _itemNames;
delete[] _flyingObjects;

delete[] _monsterOvl1;
delete[] _monsterOvl2;
delete[] _monsterFlashOverlay;
delete[] _monsterStoneOverlay;
delete[] _monsters;

if (_monsterDecorations) {
Expand Down Expand Up @@ -483,11 +482,11 @@ Common::Error EoBCoreEngine::init() {
_doorSwitches = new SpriteDecoration[6];
memset(_doorSwitches, 0, 6 * sizeof(SpriteDecoration));

_monsterOvl1 = new uint8[16];
_monsterOvl2 = new uint8[16];
memset(_monsterOvl1, 15, 16 * sizeof(uint8));
memset(_monsterOvl2, 13, 16 * sizeof(uint8));
_monsterOvl1[0] = _monsterOvl2[0] = 0;
_monsterFlashOverlay = new uint8[16];
_monsterStoneOverlay = new uint8[16];
memset(_monsterFlashOverlay, (_configRenderMode == Common::kRenderCGA) ? 0xff : 0x0f, 16 * sizeof(uint8));
memset(_monsterStoneOverlay, 0x0d, 16 * sizeof(uint8));
_monsterFlashOverlay[0] = _monsterStoneOverlay[0] = 0;

// Prevent autosave on game startup
_lastAutosave = _system->getMillis();
Expand Down Expand Up @@ -700,7 +699,6 @@ void EoBCoreEngine::loadItemsAndDecorationsShapes() {
_itemIconShapes = new const uint8*[_numItemIconShapes];
for (int i = 0; i < _numItemIconShapes; i++)
_itemIconShapes[i] = _screen->encodeShape((i % 0x14) << 1, (i / 0x14) << 4, 2, 0x10, false, _cgaMappingIcons);
_tempIconShape = new uint8[300];

_screen->loadShapeSetBitmap("DECORATE", 5, 3);

Expand Down Expand Up @@ -774,7 +772,6 @@ void EoBCoreEngine::releaseItemsAndDecorationsShapes() {
}
delete[] _itemIconShapes;
}
delete[] _tempIconShape;

if (_sparkShapes) {
for (int i = 0; i < 3; i++) {
Expand Down Expand Up @@ -838,18 +835,13 @@ void EoBCoreEngine::setHandItem(Item itemIndex) {
_itemInHand = itemIndex;
int icon = _items[_itemInHand].icon;
const uint8 *shp = _itemIconShapes[icon];
const uint8 *ovl = 0;

if (icon && (_items[_itemInHand].flags & 0x80) && (_partyEffectFlags & 2)) {
memcpy(_tempIconShape, shp, shp[1] * shp[2] * 4 + 20);
if (_flags.gameID == GI_EOB1)
_screen->replaceShapePalette(_tempIconShape, &_itemsOverlay[icon << 4]);
else
_screen->applyShapeOverlay(_tempIconShape, 3);
shp = _tempIconShape;
}
if (icon && (_items[_itemInHand].flags & 0x80) && (_partyEffectFlags & 2))
ovl = _flags.gameID == GI_EOB1 ? ((_configRenderMode == Common::kRenderCGA) ? _itemsOverlayCGA : &_itemsOverlay[icon << 4]) : _screen->generateShapeOverlay(shp, 3);

int mouseOffs = itemIndex ? 8 : 0;
_screen->setMouseCursor(mouseOffs, mouseOffs, shp);
_screen->setMouseCursor(mouseOffs, mouseOffs, shp, ovl);
}

int EoBCoreEngine::getDexterityArmorClassModifier(int dexterity) {
Expand Down
6 changes: 3 additions & 3 deletions engines/kyra/eobcommon.h
Expand Up @@ -302,8 +302,8 @@ friend class TransferPartyWiz;
const uint8 *_blackBoxWideGrid;
const uint8 *_lightningColumnShape;

uint8 *_tempIconShape;
uint8 *_itemsOverlay;
static const uint8 _itemsOverlayCGA[];

static const uint8 _teleporterShapeDefs[];
static const uint8 _wallOfForceShapeDefs[];
Expand Down Expand Up @@ -528,8 +528,8 @@ friend class TransferPartyWiz;
void updateMonstersSpellStatus(EoBMonsterInPlay *m);
void setBlockMonsterDirection(int block, int dir);

uint8 *_monsterOvl1;
uint8 *_monsterOvl2;
uint8 *_monsterFlashOverlay;
uint8 *_monsterStoneOverlay;

SpriteDecoration *_monsterDecorations;
EoBMonsterProperty *_monsterProps;
Expand Down
89 changes: 58 additions & 31 deletions engines/kyra/gui_eob.cpp
Expand Up @@ -116,7 +116,7 @@ void EoBCoreEngine::gui_drawCharPortraitWithStats(int index) {
if (c->damageTaken > 0) {
_screen->drawShape(2, _redSplatShape, x2 + 13, y2 + 30, 0);
Common::String tmpStr = Common::String::format("%d", c->damageTaken);
_screen->printText(tmpStr.c_str(), x2 + 34 - tmpStr.size() * 3, y2 + 42, 15, 0);
_screen->printText(tmpStr.c_str(), x2 + 34 - tmpStr.size() * 3, y2 + 42, (_configRenderMode == Common::kRenderCGA) ? 12 : 15, 0);
}

_screen->setCurPage(cp);
Expand Down Expand Up @@ -256,10 +256,8 @@ void EoBCoreEngine::gui_drawFaceShape(int index) {
if (c->hitPointsCur < 1)
_screen->drawShape(_screen->_curPage, _disabledCharGrid, x, y, 0);

//if ((c->flags & 2) || (c->flags & 8) || (c->effectFlags & 0x140)) {
_screen->setFadeTableIndex(4);
_screen->setShapeFadeMode(1, false);
//}
_screen->setFadeTableIndex(4);
_screen->setShapeFadeMode(1, false);
}

void EoBCoreEngine::gui_drawWeaponSlot(int charIndex, int slot) {
Expand Down Expand Up @@ -323,11 +321,13 @@ void EoBCoreEngine::gui_drawWeaponSlotStatus(int x, int y, int status) {
break;
}

int textColor= (_configRenderMode == Common::kRenderCGA) ? 2 : 15;

if (!tmpStr2.empty()) {
_screen->printText(tmpStr.c_str(), x + (16 - tmpStr.size() * 3), y + 2, 15, 0);
_screen->printText(tmpStr2.c_str(), x + (16 - tmpStr.size() * 3), y + 9, 15, 0);
_screen->printText(tmpStr.c_str(), x + (16 - tmpStr.size() * 3), y + 2, textColor, 0);
_screen->printText(tmpStr2.c_str(), x + (16 - tmpStr.size() * 3), y + 9, textColor, 0);
} else {
_screen->printText(tmpStr.c_str(), x + (16 - tmpStr.size() * 3), y + 5, 15, 0);
_screen->printText(tmpStr.c_str(), x + (16 - tmpStr.size() * 3), y + 5, textColor, 0);
}
}

Expand Down Expand Up @@ -408,12 +408,13 @@ void EoBCoreEngine::gui_drawHorizontalBarGraph(int x, int y, int w, int h, int32
}

void EoBCoreEngine::gui_drawCharPortraitStatusFrame(int index) {
uint8 redGreenColor = (_partyEffectFlags & 0x20000) ? 4 : 6;
uint8 redGreenColor = (_partyEffectFlags & 0x20000) ? 4 : ((_configRenderMode == Common::kRenderCGA) ? 3 : 6);

static const uint8 xCoords[] = { 8, 80 };
static const uint8 yCoords[] = { 2, 54, 106 };
int x = xCoords[index & 1];
int y = yCoords[index >> 1];
int xOffset = (_configRenderMode == Common::kRenderCGA) ? 0 : 1;

if (!_screen->_curPage)
x += 176;
Expand Down Expand Up @@ -467,7 +468,7 @@ void EoBCoreEngine::gui_drawCharPortraitStatusFrame(int index) {
} else {
_screen->drawClippedLine(x, y, x + 62, y, guiSettings()->colors.frame2);
_screen->drawClippedLine(x, y + 49, x + 62, y + 49, guiSettings()->colors.frame1);
_screen->drawClippedLine(x - 1, y, x - 1, y + 50, 12);
_screen->drawClippedLine(x - xOffset, y, x - xOffset, y + 50, 12);
_screen->drawClippedLine(x + 63, y, x + 63, y + 50, 12);
}
}
Expand All @@ -481,7 +482,15 @@ void EoBCoreEngine::gui_drawInventoryItem(int slot, int special, int pageNum) {

if (special) {
int wh = (slot == 25 || slot == 26) ? 10 : 18;
gui_drawBox(x - 1, y - 1, wh, wh, guiSettings()->colors.frame1, guiSettings()->colors.frame2, slot == 16 ? -1 : guiSettings()->colors.fill);

uint8 col1 = guiSettings()->colors.frame1;
uint8 col2 = guiSettings()->colors.frame2;
if (_configRenderMode == Common::kRenderCGA ) {
col1 = 1;
col2 = 3;
}

gui_drawBox(x - 1, y - 1, wh, wh, col1, col2, slot == 16 ? -1 : guiSettings()->colors.fill);

if (slot == 16) {
_screen->fillRect(227, 65, 238, 69, 12);
Expand Down Expand Up @@ -528,14 +537,26 @@ void EoBCoreEngine::gui_drawSpellbook() {
_screen->copyRegion(64, 121, 64, 121, 112, 56, 0, 2, Screen::CR_NO_P_CHECK);

for (int i = 0; i < numTab; i++) {
int col1 = guiSettings()->colors.inactiveTabFrame1;
int col2 = guiSettings()->colors.inactiveTabFrame2;
int col3 = guiSettings()->colors.inactiveTabFill;

if (i == _openBookSpellLevel) {
col1 = guiSettings()->colors.frame1;
col2 = guiSettings()->colors.frame2;
col3 = guiSettings()->colors.fill;
int col1 = 0;
int col2 = 1;
int col3 = 2;

if (_configRenderMode == Common::kRenderCGA) {
if (i == _openBookSpellLevel) {
col1 = 1;
col2 = 2;
col3 = 3;
}
} else {
col1 = guiSettings()->colors.inactiveTabFrame1;
col2 = guiSettings()->colors.inactiveTabFrame2;
col3 = guiSettings()->colors.inactiveTabFill;

if (i == _openBookSpellLevel) {
col1 = guiSettings()->colors.frame1;
col2 = guiSettings()->colors.frame2;
col3 = guiSettings()->colors.fill;
}
}

if (_flags.gameID == GI_EOB1) {
Expand All @@ -558,19 +579,21 @@ void EoBCoreEngine::gui_drawSpellbook() {
gui_drawSpellbookScrollArrow(165, 169, 1);
}

int textCol1 = 15;
int textCol1 = (_configRenderMode == Common::kRenderCGA) ? 3 : 15;
int textCol2 = 8;
int textXa = 74;
int textXs = 71;
int textY = 170;
int col3 = guiSettings()->colors.fill;
int col3 = (_configRenderMode == Common::kRenderCGA) ? 2 : guiSettings()->colors.fill;
int col4 = guiSettings()->colors.extraFill;
int col5 = 12;

if (_flags.gameID == GI_EOB1) {
textCol2 = 11;
textCol2 = (_configRenderMode == Common::kRenderCGA) ? 12 : 11;
textXa = textXs = 73;
textY = 168;
col4 = guiSettings()->colors.fill;
col4 = col3;
col5 = textCol1;
}

for (int i = 0; i < 7; i++) {
Expand All @@ -587,7 +610,7 @@ void EoBCoreEngine::gui_drawSpellbook() {
if (d >= 0 && i < 6 && (i + _openBookSpellListOffset) < 9)
_screen->printText(_openBookSpellList[d], textXs, 132 + 6 * i, textCol1, col3);
else
_screen->printText(_magicStrings1[0], textXa, textY, 12, col4);
_screen->printText(_magicStrings1[0], textXa, textY, col5, col4);
}
}

Expand Down Expand Up @@ -2704,13 +2727,14 @@ bool GUI_EoB::runSaveMenu(int x, int y) {

int GUI_EoB::selectSaveSlotDialogue(int x, int y, int id) {
_saveSlotX = _saveSlotY = 0;
int col1 = (_vm->_configRenderMode == Common::kRenderCGA) ? 1 : 15;
_screen->setCurPage(2);

_savegameOffset = 0;

drawMenuButtonBox(0, 0, 176, 144, false, false);
const char *title = (id < 2) ? _vm->_saveLoadStrings[2 + id] : _vm->_transferStringsScummVM[id - 1];
_screen->printShadedText(title, 52, 5, 15, 0);
_screen->printShadedText(title, 52, 5, col1, 0);

_screen->copyRegion(0, 0, x, y, 176, 144, 2, 0, Screen::CR_NO_P_CHECK);
_screen->setCurPage(0);
Expand Down Expand Up @@ -2783,12 +2807,12 @@ int GUI_EoB::selectSaveSlotDialogue(int x, int y, int id) {
lastHighlight = -1;
setupSaveMenuSlots();
for (int i = 0; i < 7; i++)
drawSaveSlotButton(i, 1, 15);
drawSaveSlotButton(i, 1, col1);
lastOffset = _savegameOffset;
}

if (lastHighlight != newHighlight) {
drawSaveSlotButton(lastHighlight, 0, 15);
drawSaveSlotButton(lastHighlight, 0, col1);
drawSaveSlotButton(newHighlight, 0, 6);

// Display highlighted slot index in the bottom left corner to avoid people getting lost with the 990 save slots
Expand Down Expand Up @@ -3797,10 +3821,12 @@ void GUI_EoB::drawMenuButton(Button *b, bool clicked, bool highlight, bool noFil
yOffs = (b->height - 7) >> 1;
}

int col1 = (_vm->_configRenderMode == Common::kRenderCGA) ? 1 : 15;

if (noFill || clicked)
_screen->printText(s, b->x + xOffs, b->y + yOffs, highlight ? 6 : 15, 0);
_screen->printText(s, b->x + xOffs, b->y + yOffs, highlight ? 6 : col1, 0);
else
_screen->printShadedText(s, b->x + xOffs, b->y + yOffs, highlight ? 6 : 15, 0);
_screen->printShadedText(s, b->x + xOffs, b->y + yOffs, highlight ? 6 : col1, 0);
}
}

Expand Down Expand Up @@ -3862,13 +3888,14 @@ void GUI_EoB::memorizePrayMenuPrintString(int spellId, int bookPageIndex, int sp
return;

int y = bookPageIndex * 9 + 50;
int col1 = (_vm->_configRenderMode == Common::kRenderCGA) ? 1 : 15;

if (spellId) {
Common::String s(Common::String::format(_vm->_menuStringsMgc[0], spellType ? _vm->_clericSpellList[spellId] : _vm->_mageSpellList[spellId], _numAssignedSpellsOfType[spellId * 2 - 2]));
if (noFill)
_screen->printText(s.c_str(), 8, y, highLight ? 6 : 15, 0);
_screen->printText(s.c_str(), 8, y, highLight ? 6 : col1, 0);
else
_screen->printShadedText(s.c_str(), 8, y, highLight ? 6 : 15, _vm->guiSettings()->colors.fill);
_screen->printShadedText(s.c_str(), 8, y, highLight ? 6 : col1, _vm->guiSettings()->colors.fill);

} else {
_screen->fillRect(6, y, 168, y + 8, _vm->guiSettings()->colors.fill);
Expand Down
9 changes: 4 additions & 5 deletions engines/kyra/items_eob.cpp
Expand Up @@ -462,19 +462,18 @@ void EoBCoreEngine::identifyQueuedItems(Item itemQueue) {
void EoBCoreEngine::drawItemIconShape(int pageNum, Item itemId, int x, int y) {
int icn = _items[itemId].icon;
bool applyBluePal = ((_partyEffectFlags & 2) && (_items[itemId].flags & 0x80)) ? true : false;

memcpy(_tempIconShape, _itemIconShapes[icn], _itemIconShapes[icn][1] * _itemIconShapes[icn][2] * 4 + 20);
const uint8 *ovl = 0;

if (applyBluePal) {
if (_flags.gameID == GI_EOB1) {
_screen->replaceShapePalette(_tempIconShape, &_itemsOverlay[icn << 4]);
if (_flags.gameID == GI_EOB1) {
ovl = (_configRenderMode == Common::kRenderCGA) ? _itemsOverlayCGA : &_itemsOverlay[icn << 4];
} else {
_screen->setFadeTableIndex(3);
_screen->setShapeFadeMode(1, true);
}
}

_screen->drawShape(pageNum, _tempIconShape, x, y, 0);
_screen->drawShape(pageNum, _itemIconShapes[icn], x, y, 0, ovl ? 2 : 0, ovl);

if (applyBluePal) {
_screen->setFadeTableIndex(4);
Expand Down
2 changes: 2 additions & 0 deletions engines/kyra/kyra_rpg.cpp
Expand Up @@ -44,6 +44,7 @@ KyraRpgEngine::KyraRpgEngine(OSystem *system, const GameFlags &flags) : KyraEngi
_vmpPtr = 0;
_vcnBlocks = 0;
_vcfBlocks = 0;
_vcnTransitionMask = 0;
_vcnShift = 0;
_vcnColTable = 0;
_vmpPtr = 0;
Expand Down Expand Up @@ -126,6 +127,7 @@ KyraRpgEngine::~KyraRpgEngine() {
delete[] _vcnColTable;
delete[] _vcnBlocks;
delete[] _vcfBlocks;
delete[] _vcnTransitionMask;
delete[] _vcnShift;
delete[] _blockDrawingBuffer;
delete[] _sceneWindowBuffer;
Expand Down

0 comments on commit 151d314

Please sign in to comment.