Initial commit
This commit is contained in:
416
engines/efh/graphics.cpp
Normal file
416
engines/efh/graphics.cpp
Normal file
@@ -0,0 +1,416 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "graphics/paletteman.h"
|
||||
#include "common/system.h"
|
||||
#include "efh/efh.h"
|
||||
|
||||
namespace Efh {
|
||||
|
||||
void EfhEngine::initPalette() {
|
||||
// Strangerke - values from a tool I wrote in 2008. I can't remember if it's guess work or not.
|
||||
static const uint8 pal[3 * 16] = {
|
||||
0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xAA,
|
||||
0x00, 0xAA, 0x00,
|
||||
0x00, 0xAA, 0xAA,
|
||||
0xAA, 0x00, 0x00,
|
||||
0xAA, 0x00, 0xAA,
|
||||
0xAA, 0x55, 0x00,
|
||||
0xAA, 0xAA, 0xAA,
|
||||
0x55, 0x55, 0x55,
|
||||
0x55, 0x55, 0xFF,
|
||||
0x01, 0x01, 0x01, // Color 0xA is for transparency
|
||||
0x55, 0xFF, 0xFF,
|
||||
0xFF, 0x55, 0x55,
|
||||
0xFF, 0x55, 0xFF,
|
||||
0xFF, 0xFF, 0x55,
|
||||
0xFF, 0xFF, 0xFF
|
||||
};
|
||||
|
||||
debugC(1, kDebugGraphics, "initPalette");
|
||||
_system->getPaletteManager()->setPalette(pal, 0, 16);
|
||||
_system->updateScreen();
|
||||
}
|
||||
|
||||
void EfhEngine::drawLeftCenterBox() {
|
||||
debugC(1, kDebugGraphics, "drawLeftCenterBox");
|
||||
drawColoredRect(16, 8, 111, 135, 0);
|
||||
}
|
||||
|
||||
void EfhEngine::displayNextAnimFrame() {
|
||||
debugC(6, kDebugGraphics, "displayNextAnimFrame");
|
||||
|
||||
if (++_unkAnimRelatedIndex >= 15)
|
||||
_unkAnimRelatedIndex = 0;
|
||||
|
||||
displayAnimFrame();
|
||||
}
|
||||
|
||||
void EfhEngine::displayAnimFrame() {
|
||||
debugC(1, kDebugGraphics, "displayAnimFrame");
|
||||
// The original had a parameter. As it was always equal to zero, it was removed in ScummVM
|
||||
|
||||
if (_animImageSetId == 0xFF)
|
||||
return;
|
||||
|
||||
if (_animImageSetId == 0xFE) {
|
||||
displayRawDataAtPos(_portraitSubFilesArray[0], 16, 8);
|
||||
return;
|
||||
}
|
||||
|
||||
displayRawDataAtPos(_portraitSubFilesArray[0], 16, 8);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
int8 var2 = _animInfo[_animImageSetId]._frameList[_unkAnimRelatedIndex]._subFileId[i];
|
||||
if (var2 == -1)
|
||||
continue;
|
||||
displayRawDataAtPos(_portraitSubFilesArray[var2 + 1], _animInfo[_animImageSetId]._posX[var2] + 16, _animInfo[_animImageSetId]._posY[var2] + 8);
|
||||
}
|
||||
}
|
||||
|
||||
void EfhEngine::displayAnimFrames(int16 animId, bool displayMenuBoxFl) {
|
||||
debugC(1, kDebugGraphics, "displayAnimFrames %d %s", animId, displayMenuBoxFl ? "True" : "False");
|
||||
if (animId == 0xFF)
|
||||
return;
|
||||
|
||||
_animImageSetId = animId;
|
||||
if (_animImageSetId == 0xFE)
|
||||
loadNewPortrait();
|
||||
else
|
||||
loadAnimImageSet();
|
||||
|
||||
if (!displayMenuBoxFl)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
drawLeftCenterBox();
|
||||
displayAnimFrame();
|
||||
|
||||
if (i == 0)
|
||||
displayFctFullScreen();
|
||||
}
|
||||
}
|
||||
|
||||
void EfhEngine::displayFctFullScreen() {
|
||||
debugC(1, kDebugGraphics, "displayFctFullScreen");
|
||||
|
||||
// CHECKME: 319 is in the original but looks suspicious.
|
||||
// copyDirtyRect(0, 0, 319, 200);
|
||||
|
||||
_system->copyRectToScreen((uint8 *)_mainSurface->getPixels(), 320, 0, 0, 320, 200);
|
||||
_system->updateScreen();
|
||||
}
|
||||
|
||||
void EfhEngine::copyDirtyRect(int16 minX, int16 minY, int16 maxX, int16 maxY) {
|
||||
_graphicsStruct->copy(_vgaGraphicsStruct2);
|
||||
_initRect = Common::Rect(minX, minY, maxX, maxY);
|
||||
copyGraphicBufferFromTo(_vgaGraphicsStruct2, _vgaGraphicsStruct1, _initRect, minX, minY);
|
||||
}
|
||||
|
||||
void EfhEngine::copyGraphicBufferFromTo(EfhGraphicsStruct *efh_graphics_struct, EfhGraphicsStruct *efh_graphics_struct1, const Common::Rect &rect, int16 min_x, int16 min_y) {
|
||||
warning("STUB - copyGraphicBufferFromTo");
|
||||
}
|
||||
|
||||
void EfhEngine::displayBufferBmAtPos(BufferBM *bufferBM, int16 posX, int16 posY) {
|
||||
debugC(1, kDebugGraphics, "displayBufferBmAtPos %d %d", posX, posY);
|
||||
// CHECKME: Quick code to display stuff, may require to really reverse the actual function
|
||||
uint8 *destPtr = (uint8 *)_mainSurface->getBasePtr(posX, posY);
|
||||
int counter = 0;
|
||||
for (int line = 0; line < bufferBM->_height; ++line) {
|
||||
for (int col = 0; col < bufferBM->_lineDataSize; ++col) { // _lineDataSize = _width / 2
|
||||
if (bufferBM->_dataPtr[counter] >> 4 != 0xA)
|
||||
destPtr[320 * line + 2 * col] = bufferBM->_dataPtr[counter] >> 4;
|
||||
if ((bufferBM->_dataPtr[counter] & 0xF) != 0xA)
|
||||
destPtr[320 * line + 2 * col + 1] = bufferBM->_dataPtr[counter] & 0xF;
|
||||
++counter;
|
||||
}
|
||||
}
|
||||
|
||||
// _system->copyRectToScreen((uint8 *)_mainSurface->getPixels(), 320, 0, 0, 320, 200);
|
||||
// _system->updateScreen();
|
||||
}
|
||||
|
||||
void EfhEngine::drawRect(int16 minX, int16 minY, int16 maxX, int16 maxY) {
|
||||
debugC(1, kDebugGraphics, "drawRect %d-%d %d-%d", minX, minY, maxX, maxY);
|
||||
|
||||
if (minY > maxY)
|
||||
SWAP(minY, maxY);
|
||||
|
||||
if (minX > maxX)
|
||||
SWAP(minX, maxX);
|
||||
|
||||
minX = CLIP<int16>(minX, 0, 319);
|
||||
maxX = CLIP<int16>(maxX, 0, 319);
|
||||
minY = CLIP<int16>(minY, 0, 199);
|
||||
maxY = CLIP<int16>(maxY, 0, 199);
|
||||
|
||||
int deltaY = 1 + maxY - minY;
|
||||
int deltaX = 1 + maxX - minX;
|
||||
|
||||
uint8 color = _defaultBoxColor & 0xF;
|
||||
bool xorColor = (_defaultBoxColor & 0x40) != 0;
|
||||
uint8 *destPtr = (uint8 *)_mainSurface->getBasePtr(minX, minY);
|
||||
|
||||
for (int line = 0; line < deltaY; ++line) {
|
||||
for (int col = 0; col < deltaX; ++col) {
|
||||
if (xorColor)
|
||||
destPtr[320 * line + col] ^= color;
|
||||
else
|
||||
destPtr[320 * line + col] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EfhEngine::drawColoredRect(int16 minX, int16 minY, int16 maxX, int16 maxY, int16 color) {
|
||||
debugC(1, kDebugGraphics, "drawColoredRect %d-%d %d-%d %d", minX, minY, maxX, maxY, color);
|
||||
|
||||
uint8 oldValue = _defaultBoxColor;
|
||||
_defaultBoxColor = color;
|
||||
drawRect(minX, minY, maxX, maxY);
|
||||
_defaultBoxColor = oldValue;
|
||||
}
|
||||
|
||||
void EfhEngine::clearScreen(int16 color) {
|
||||
debugC(1, kDebugGraphics, "clearScreen %d", color);
|
||||
drawColoredRect(0, 0, 320, 200, color);
|
||||
}
|
||||
|
||||
void EfhEngine::displayRawDataAtPos(uint8 *imagePtr, int16 posX, int16 posY) {
|
||||
debugC(1, kDebugGraphics, "displayRawDataAtPos %d %d", posX, posY);
|
||||
uint16 height = READ_LE_INT16(imagePtr);
|
||||
uint16 width = READ_LE_INT16(imagePtr + 2);
|
||||
uint8 *imageData = imagePtr + 4;
|
||||
|
||||
_imageDataPtr._lineDataSize = width;
|
||||
_imageDataPtr._dataPtr = imageData;
|
||||
_imageDataPtr._height = height;
|
||||
_imageDataPtr._width = width * 2; // 2 pixels per byte
|
||||
_imageDataPtr._startX = _imageDataPtr._startY = 0;
|
||||
|
||||
displayBufferBmAtPos(&_imageDataPtr, posX, posY);
|
||||
}
|
||||
|
||||
void EfhEngine::drawString(const Common::String &str, int16 startX, int16 startY, uint16 textColor) {
|
||||
debugC(1, kDebugGraphics, "drawString %s %d %d %d", str.c_str(), startX, startY, textColor);
|
||||
const uint8 *curPtr = (const uint8 *)str.c_str();
|
||||
uint16 lineHeight = _fontDescr._charHeight + _fontDescr._extraVerticalSpace;
|
||||
int16 minX = startX;
|
||||
|
||||
if (textColor & 0x8000) {
|
||||
warning("STUB - drawString - 0x8000");
|
||||
// int16 minY = startY; // Used in case 0x8000
|
||||
// int16 var6 = _fontDescr._extraLines[0] + startY - 1; // Used in case 0x8000
|
||||
}
|
||||
|
||||
for (uint curChar = *curPtr++; curChar != 0; curChar = *curPtr++) {
|
||||
if (curChar == 0x0A) {
|
||||
startX = minX;
|
||||
startY += lineHeight;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (curChar < 0x20)
|
||||
continue;
|
||||
|
||||
uint16 characterId = (curChar + 0xE0) & 0xFF;
|
||||
uint8 charWidth = _fontDescr._widthArray[characterId];
|
||||
|
||||
if (startX + charWidth >= 319) {
|
||||
startX = minX;
|
||||
startY += lineHeight;
|
||||
}
|
||||
|
||||
uint8 varC = _fontDescr._extraLines[characterId];
|
||||
drawChar(curChar, startX, startY + varC);
|
||||
startX += charWidth + _fontDescr._extraHorizontalSpace;
|
||||
}
|
||||
}
|
||||
|
||||
void EfhEngine::displayCenteredString(const Common::String &str, int16 minX, int16 maxX, int16 posY) {
|
||||
debugC(1, kDebugGraphics, "displayCenteredString %s %d-%d %d", str.c_str(), minX, maxX, posY);
|
||||
uint16 length = getStringWidth(str);
|
||||
int16 startCenteredDisplayX = minX + (maxX - minX - length) / 2;
|
||||
drawString(str, startCenteredDisplayX, posY, _textColor);
|
||||
}
|
||||
|
||||
void EfhEngine::displayMenuAnswerString(const Common::String &str, int16 minX, int16 maxX, int16 posY) {
|
||||
debugC(1, kDebugGraphics, "displayMenuAnswerString %s %d-%d %d", str.c_str(), minX, maxX, posY);
|
||||
displayCenteredString(str, minX, maxX, posY);
|
||||
displayFctFullScreen();
|
||||
displayCenteredString(str, minX, maxX, posY);
|
||||
}
|
||||
|
||||
void EfhEngine::drawMapWindow() {
|
||||
debugC(1, kDebugGraphics, "drawMapWindow");
|
||||
drawColoredRect(128, 8, 303, 135, 0);
|
||||
}
|
||||
|
||||
void EfhEngine::displayGameScreen() {
|
||||
debugC(1, kDebugGraphics, "displayGameScreen");
|
||||
clearScreen(0);
|
||||
drawUpperLeftBorders();
|
||||
drawUpperRightBorders();
|
||||
drawBottomBorders();
|
||||
displayAnimFrame();
|
||||
displayLowStatusScreen(false);
|
||||
}
|
||||
|
||||
void EfhEngine::drawUpperLeftBorders() {
|
||||
debugC(1, kDebugGraphics, "drawUpperLeftBorders");
|
||||
displayRawDataAtPos(_circleImageSubFileArray[0], 0, 0);
|
||||
displayRawDataAtPos(_circleImageSubFileArray[1], 112, 0);
|
||||
displayRawDataAtPos(_circleImageSubFileArray[3], 16, 0);
|
||||
}
|
||||
|
||||
void EfhEngine::drawUpperRightBorders() {
|
||||
debugC(1, kDebugGraphics, "drawUpperRightBorders");
|
||||
displayRawDataAtPos(_circleImageSubFileArray[2], 304, 0);
|
||||
displayRawDataAtPos(_circleImageSubFileArray[4], 128, 0);
|
||||
}
|
||||
|
||||
void EfhEngine::drawBottomBorders() {
|
||||
debugC(1, kDebugGraphics, "drawBottomBorders");
|
||||
displayRawDataAtPos(_circleImageSubFileArray[7], 16, 136);
|
||||
displayRawDataAtPos(_circleImageSubFileArray[8], 16, 192);
|
||||
displayRawDataAtPos(_circleImageSubFileArray[5], 0, 136);
|
||||
displayRawDataAtPos(_circleImageSubFileArray[6], 304, 136);
|
||||
}
|
||||
|
||||
void EfhEngine::drawChar(uint8 curChar, int16 posX, int16 posY) {
|
||||
debugC(1, kDebugGraphics, "drawChar %c %d %d", curChar, posX, posY);
|
||||
|
||||
// CHECKME: Quick hacked display, may require rework
|
||||
|
||||
// Note: The original is making of a variable which is set to _textColor & 0x3FFF
|
||||
// It seems _textColor is always set to a small value and thus this variable
|
||||
// has been removed.
|
||||
|
||||
uint8 *destPtr = (uint8 *)_mainSurface->getBasePtr(posX, posY);
|
||||
|
||||
int16 charId = curChar - 0x20;
|
||||
uint8 width = _fontDescr._widthArray[charId];
|
||||
|
||||
for (uint line = 0; line < 8; ++line) {
|
||||
int16 x = 0;
|
||||
for (int i = 7; i >= 7 - width; --i) {
|
||||
if (_fontDescr._fontData[charId]._lines[line] & (1 << i))
|
||||
destPtr[320 * line + x] = _textColor;
|
||||
++x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EfhEngine::setTextColorWhite() {
|
||||
debugC(1, kDebugGraphics, "setTextColorWhite");
|
||||
|
||||
if (_videoMode == 8) // CGA
|
||||
_textColor = 0x3;
|
||||
else
|
||||
_textColor = 0xF;
|
||||
}
|
||||
|
||||
void EfhEngine::setTextColorRed() {
|
||||
debugC(1, kDebugGraphics, "setTextColorRed");
|
||||
|
||||
if (_videoMode == 8) // CGA
|
||||
_textColor = 0x2;
|
||||
else
|
||||
_textColor = 0xC;
|
||||
}
|
||||
|
||||
void EfhEngine::setTextColorGrey() {
|
||||
debugC(1, kDebugGraphics, "setTextColorGrey");
|
||||
|
||||
if (_videoMode == 8) // CGA
|
||||
_textColor = 0x1;
|
||||
else
|
||||
_textColor = 0x8;
|
||||
}
|
||||
|
||||
void EfhEngine::displayStringAtTextPos(const Common::String &message) {
|
||||
debugC(1, kDebugGraphics, "displayStringAtTextPos %s", message.c_str());
|
||||
|
||||
drawString(message, _textPosX, _textPosY, _textColor);
|
||||
_textPosX += getStringWidth(message) + 1;
|
||||
setNextCharacterPos();
|
||||
}
|
||||
|
||||
void EfhEngine::clearBottomTextZone(int16 color) {
|
||||
debugC(1, kDebugGraphics, "clearBottomTextZone %d", color);
|
||||
|
||||
drawColoredRect(16, 152, 302, 189, color);
|
||||
}
|
||||
|
||||
void EfhEngine::clearBottomTextZone_2(int16 color) {
|
||||
debugC(1, kDebugGraphics, "clearBottomTextZone_2 %d", color);
|
||||
|
||||
displayColoredMenuBox(16, 152, 302, 189, color);
|
||||
}
|
||||
|
||||
void EfhEngine::setNextCharacterPos() {
|
||||
debugC(1, kDebugGraphics, "setNextCharacterPos");
|
||||
|
||||
if (_textPosX <= 311)
|
||||
return;
|
||||
|
||||
_textPosX = 0;
|
||||
_textPosY += 8;
|
||||
|
||||
if (_textPosY > 191)
|
||||
_textPosY = 0;
|
||||
}
|
||||
|
||||
void EfhEngine::displayCharAtTextPos(char character) {
|
||||
debugC(1, kDebugGraphics, "displayCharAtTextPos %c", character);
|
||||
|
||||
char buffer[2];
|
||||
buffer[0] = character;
|
||||
buffer[1] = 0;
|
||||
|
||||
drawString(buffer, _textPosX, _textPosY, _textColor);
|
||||
_textPosX += getStringWidth(buffer) + 1;
|
||||
setNextCharacterPos();
|
||||
}
|
||||
|
||||
void EfhEngine::displayWindow(uint8 *buffer, int16 posX, int16 posY, uint8 *dest) {
|
||||
debugC(1, kDebugGraphics, "displayWindow %d %d", posX, posY);
|
||||
|
||||
if (buffer == nullptr) {
|
||||
warning("Target Buffer Not Defined...DCImage!"); // That's the original message... And yes, it's wrong: it's checking the source buffer :)
|
||||
return;
|
||||
}
|
||||
|
||||
// Only MCGA handled, the rest is skipped
|
||||
uncompressBuffer(buffer, dest);
|
||||
displayRawDataAtPos(dest, posX, posY);
|
||||
displayFctFullScreen();
|
||||
displayRawDataAtPos(dest, posX, posY);
|
||||
}
|
||||
|
||||
void EfhEngine::displayColoredMenuBox(int16 minX, int16 minY, int16 maxX, int16 maxY, int16 color) {
|
||||
debugC(1, kDebugGraphics, "displayColoredMenuBox %d %d -> %d %d %d", minX, minY, maxX, maxY, color);
|
||||
|
||||
drawColoredRect(minX, minY, maxX, maxY, color);
|
||||
displayFctFullScreen();
|
||||
drawColoredRect(minX, minY, maxX, maxY, color);
|
||||
}
|
||||
|
||||
} // End of namespace Efh
|
||||
Reference in New Issue
Block a user