aboutsummaryrefslogtreecommitdiff
path: root/engines/hugo/display.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/hugo/display.cpp')
-rw-r--r--engines/hugo/display.cpp188
1 files changed, 133 insertions, 55 deletions
diff --git a/engines/hugo/display.cpp b/engines/hugo/display.cpp
index 3a8d0d4e89..f7975df693 100644
--- a/engines/hugo/display.cpp
+++ b/engines/hugo/display.cpp
@@ -40,7 +40,6 @@
namespace Hugo {
-#define NUM_COLORS 16 // Num colors to save in palette
#define DMAX 16 // Size of add/restore rect lists
#define BMAX (DMAX * 2) // Size of dirty rect blit list
@@ -48,8 +47,11 @@ namespace Hugo {
#define INY(Y, B) (Y >= B->y && Y <= B->y + B->dy)
#define OVERLAP(A, B) ((INX(A->x, B) || INX(A->x + A->dx, B) || INX(B->x, A) || INX(B->x + B->dx, A)) && (INY(A->y, B) || INY(A->y + A->dy, B) || INY(B->y, A) || INY(B->y + B->dy, A)))
-Screen::Screen(HugoEngine &vm) : _vm(vm) {
-
+Screen::Screen(HugoEngine *vm) : _vm(vm), _palette(0) {
+ for (int j = 0; j < NUM_FONTS; j++) {
+ _arrayFont[j] = 0;
+ fontLoadedFl[j] = false;
+ }
}
Screen::~Screen() {
@@ -58,16 +60,20 @@ Screen::~Screen() {
void Screen::createPal() {
debugC(1, kDebugDisplay, "createPal");
- g_system->setPalette(_vm._palette, 0, NUM_COLORS);
+ g_system->setPalette(_palette, 0, NUM_COLORS);
}
+/**
+* Create logical palette
+*/
void Screen::initDisplay() {
debugC(1, kDebugDisplay, "initDisplay");
- // Create logical palette
createPal();
}
-// Move an image from source to destination
+/**
+* Move an image from source to destination
+*/
void Screen::moveImage(image_pt srcImage, uint16 x1, uint16 y1, uint16 dx, uint16 dy, uint16 width1, image_pt dstImage, uint16 x2, uint16 y2, uint16 width2) {
debugC(3, kDebugDisplay, "moveImage(srcImage, %d, %d, %d, %d, %d, dstImage, %d, %d, %d)", x1, y1, dx, dy, width1, x2, y2, width2);
@@ -91,51 +97,65 @@ void Screen::displayBackground() {
g_system->copyRectToScreen(_frontBuffer, 320, 0, 0, 320, 200);
}
-// Blit the supplied rectangle from _frontBuffer to the screen
+/**
+* Blit the supplied rectangle from _frontBuffer to the screen
+*/
void Screen::displayRect(int16 x, int16 y, int16 dx, int16 dy) {
debugC(3, kDebugDisplay, "displayRect(%d, %d, %d, %d)", x, y, dx, dy);
g_system->copyRectToScreen(&_frontBuffer[x + y * 320], 320, x, y, dx, dy);
}
+/**
+* Change a color by remapping supplied palette index with new index
+*/
void Screen::remapPal(uint16 oldIndex, uint16 newIndex) {
-// Change a color by remapping supplied palette index with new index
debugC(1, kDebugDisplay, "Remap_pal(%d, %d)", oldIndex, newIndex);
- warning("STUB: Remap_pal()");
- //bminfo.bmiColors[oldIndex] = ctab[newIndex];
+ byte pal[4];
+
+ pal[0] = _palette[newIndex * 4 + 0];
+ pal[1] = _palette[newIndex * 4 + 1];
+ pal[2] = _palette[newIndex * 4 + 2];
+ pal[3] = _palette[newIndex * 4 + 3];
+
+ g_system->setPalette(pal, oldIndex, 1);
}
void Screen::savePal(Common::WriteStream *f) {
debugC(1, kDebugDisplay, "savePal");
- warning("STUB: savePal()");
- //fwrite(bminfo.bmiColors, sizeof(bminfo.bmiColors), 1, f);
+ for (int i = 0; i < _paletteSize; i++)
+ f->writeByte(_palette[i]);
}
void Screen::restorePal(Common::SeekableReadStream *f) {
debugC(1, kDebugDisplay, "restorePal");
- warning("STUB: restorePal()");
- //fread(bminfo.bmiColors, sizeof(bminfo.bmiColors), 1, f);
+ for (int i = 0; i < _paletteSize; i++)
+ _palette[i] = f->readByte();
}
-// Set the new background color
+/**
+* Set the new background color
+*/
void Screen::setBackgroundColor(long color) {
debugC(1, kDebugDisplay, "setBackgroundColor(%ld)", color);
// How??? Translate existing pixels in dib before objects rendered?
}
-// Return the overlay state (Foreground/Background) of the currently
-// processed object by looking down the current column for an overlay
-// base bit set (in which case the object is foreground).
+/**
+* Return the overlay state (Foreground/Background) of the currently
+* processed object by looking down the current column for an overlay
+* base bit set (in which case the object is foreground).
+*/
overlayState_t Screen::findOvl(seq_t *seq_p, image_pt dst_p, uint16 y) {
debugC(4, kDebugDisplay, "findOvl");
for (; y < seq_p->lines; y++) { // Each line in object
- image_pt ovb_p = _vm.getBaseBoundaryOverlay() + ((uint16)(dst_p - _frontBuffer) >> 3); // Ptr into overlay bits
+ image_pt ovb_p = _vm->getBaseBoundaryOverlay() + ((uint16)(dst_p - _frontBuffer) >> 3); // Ptr into overlay bits
if (*ovb_p & (0x80 >> ((uint16)(dst_p - _frontBuffer) & 7))) // Overlay bit is set
return FG; // Found a bit - must be foreground
dst_p += XPIX;
@@ -144,14 +164,16 @@ overlayState_t Screen::findOvl(seq_t *seq_p, image_pt dst_p, uint16 y) {
return BG; // No bits set, must be background
}
-// Merge an object frame into _frontBuffer at sx, sy and update rectangle list.
-// If fore TRUE, force object above any overlay
+/**
+* Merge an object frame into _frontBuffer at sx, sy and update rectangle list.
+* If fore TRUE, force object above any overlay
+*/
void Screen::displayFrame(int sx, int sy, seq_t *seq, bool foreFl) {
debugC(3, kDebugDisplay, "displayFrame(%d, %d, seq, %d)", sx, sy, (foreFl) ? 1 : 0);
image_pt image = seq->imagePtr; // Ptr to object image data
image_pt subFrontBuffer = &_frontBuffer[sy * XPIX + sx]; // Ptr to offset in _frontBuffer
- image_pt overlay = &_vm.getFirstOverlay()[(sy * XPIX + sx) >> 3]; // Ptr to overlay data
+ image_pt overlay = &_vm->getFirstOverlay()[(sy * XPIX + sx) >> 3]; // Ptr to overlay data
int16 frontBufferwrap = XPIX - seq->x2 - 1; // Wraps dest_p after each line
int16 imageWrap = seq->bytesPerLine8 - seq->x2 - 1;
@@ -159,7 +181,7 @@ void Screen::displayFrame(int sx, int sy, seq_t *seq, bool foreFl) {
for (uint16 y = 0; y < seq->lines; y++) { // Each line in object
for (uint16 x = 0; x <= seq->x2; x++) {
if (*image) { // Non-transparent
- overlay = _vm.getFirstOverlay() + ((uint16)(subFrontBuffer - _frontBuffer) >> 3); // Ptr into overlay bits
+ overlay = _vm->getFirstOverlay() + ((uint16)(subFrontBuffer - _frontBuffer) >> 3); // Ptr into overlay bits
if (*overlay & (0x80 >> ((uint16)(subFrontBuffer - _frontBuffer) & 7))) { // Overlay bit is set
if (overlayState == UNDEF) // Overlay defined yet?
overlayState = findOvl(seq, subFrontBuffer, y);// No, find it.
@@ -180,7 +202,9 @@ void Screen::displayFrame(int sx, int sy, seq_t *seq, bool foreFl) {
displayList(D_ADD, sx, sy, seq->x2 + 1, seq->lines);
}
-// Merge rectangles A,B leaving result in B
+/**
+* Merge rectangles A,B leaving result in B
+*/
void Screen::merge(rect_t *rectA, rect_t *rectB) {
debugC(6, kDebugDisplay, "merge");
@@ -195,10 +219,12 @@ void Screen::merge(rect_t *rectA, rect_t *rectB) {
rectB->dy = MAX(ya, yb) - rectB->y;
}
-// Coalesce the rectangles in the restore/add list into one unified
-// blist. len is the sizes of alist or rlist. blen is current length
-// of blist. bmax is the max size of the blist. Note that blist can
-// have holes, in which case dx = 0. Returns used length of blist.
+/**
+* Coalesce the rectangles in the restore/add list into one unified
+* blist. len is the sizes of alist or rlist. blen is current length
+* of blist. bmax is the max size of the blist. Note that blist can
+* have holes, in which case dx = 0. Returns used length of blist.
+*/
int16 Screen::mergeLists(rect_t *list, rect_t *blist, int16 len, int16 blen, int16 bmax) {
debugC(4, kDebugDisplay, "mergeLists");
@@ -213,7 +239,7 @@ int16 Screen::mergeLists(rect_t *list, rect_t *blist, int16 len, int16 blen, int
if (OVERLAP(list, bp))
coalesce[c++] = b;
}
-
+
// Any overlapping blit rects?
if (c == 0) { // None, add a new entry
blist[blen++] = *list;
@@ -233,8 +259,10 @@ int16 Screen::mergeLists(rect_t *list, rect_t *blist, int16 len, int16 blen, int
return blen;
}
-// Process the display list
-// Trailing args are int16 x,y,dx,dy for the D_ADD operation
+/**
+* Process the display list
+* Trailing args are int16 x,y,dx,dy for the D_ADD operation
+*/
void Screen::displayList(dupdate_t update, ...) {
debugC(6, kDebugDisplay, "displayList");
@@ -253,7 +281,7 @@ void Screen::displayList(dupdate_t update, ...) {
break;
case D_ADD: // Add a rectangle to list
if (addIndex >= DMAX) {
- Utils::Warn("%s", "Display list exceeded");
+ warning("Display list exceeded");
return;
}
va_start(marker, update); // Initialize variable arguments
@@ -269,8 +297,8 @@ void Screen::displayList(dupdate_t update, ...) {
// Don't blit if newscreen just loaded because _frontBuffer will
// get blitted via InvalidateRect() at end of this cycle
// and blitting here causes objects to appear too soon.
- if (_vm.getGameStatus().newScreenFl) {
- _vm.getGameStatus().newScreenFl = false;
+ if (_vm->getGameStatus().newScreenFl) {
+ _vm->getGameStatus().newScreenFl = false;
break;
}
@@ -295,13 +323,14 @@ void Screen::displayList(dupdate_t update, ...) {
}
}
+/**
+* Write supplied character (font data) at sx,sy in supplied color
+* Font data as follows:
+* *(fontdata+1) = Font Height (pixels)
+* *(fontdata+1) = Font Width (pixels)
+* *(fontdata+x) = Font Bitmap (monochrome)
+*/
void Screen::writeChr(int sx, int sy, byte color, char *local_fontdata) {
-// Write supplied character (font data) at sx,sy in supplied color
-// Font data as follows:
-//
-// *(fontdata+1) = Font Height (pixels)
-// *(fontdata+1) = Font Width (pixels)
-// *(fontdata+x) = Font Bitmap (monochrome)
debugC(2, kDebugDisplay, "writeChr(%d, %d, %d, %d)", sx, sy, color, local_fontdata[0]);
byte height = local_fontdata[0];
@@ -320,7 +349,9 @@ void Screen::writeChr(int sx, int sy, byte color, char *local_fontdata) {
}
}
-// Returns height of characters in current font
+/**
+* Returns height of characters in current font
+*/
int16 Screen::fontHeight() {
debugC(2, kDebugDisplay, "fontHeight");
@@ -328,8 +359,9 @@ int16 Screen::fontHeight() {
return height[_fnt - FIRST_FONT];
}
-
-// Returns length of supplied string in pixels
+/**
+* Returns length of supplied string in pixels
+*/
int16 Screen::stringLength(const char *s) {
debugC(2, kDebugDisplay, "stringLength(%s)", s);
@@ -341,15 +373,19 @@ int16 Screen::stringLength(const char *s) {
return sum;
}
-// Return x which would center supplied string
+/**
+* Return x which would center supplied string
+*/
int16 Screen::center(const char *s) {
debugC(1, kDebugDisplay, "center(%s)", s);
return (int16)((XPIX - stringLength(s)) >> 1);
}
-// Write string at sx,sy in supplied color in current font
-// If sx == CENTER, center it
+/**
+* Write string at sx,sy in supplied color in current font
+* If sx == CENTER, center it
+*/
void Screen::writeStr(int16 sx, int16 sy, const char *s, byte color) {
debugC(2, kDebugDisplay, "writeStr(%d, %d, %s, %d)", sx, sy, s, color);
@@ -363,7 +399,9 @@ void Screen::writeStr(int16 sx, int16 sy, const char *s, byte color) {
}
}
-// Shadowed version of writestr
+/**
+* Shadowed version of writestr
+*/
void Screen::shadowStr(int16 sx, int16 sy, const char *s, byte color) {
debugC(1, kDebugDisplay, "shadowStr(%d, %d, %s, %d)", sx, sy, s, color);
@@ -374,10 +412,11 @@ void Screen::shadowStr(int16 sx, int16 sy, const char *s, byte color) {
writeStr(sx, sy, s, color);
}
+/** Introduce user to the game
+* DOS versions Only
+*/
void Screen::userHelp() {
-// Introduce user to the game
-// DOS versions Only
- Utils::Box(BOX_ANY , "%s",
+ Utils::Box(BOX_ANY , "%s",
"F1 - Press F1 again\n"
" for instructions\n"
"F2 - Sound on/off\n"
@@ -394,18 +433,18 @@ void Screen::drawStatusText() {
debugC(4, kDebugDisplay, "drawStatusText");
loadFont(U_FONT8);
- uint16 sdx = stringLength(_vm._statusLine);
+ uint16 sdx = stringLength(_vm->_statusLine);
uint16 sdy = fontHeight() + 1; // + 1 for shadow
uint16 posX = 0;
uint16 posY = YPIX - sdy;
// Display the string and add rect to display list
- writeStr(posX, posY, _vm._statusLine, _TLIGHTYELLOW);
+ writeStr(posX, posY, _vm->_statusLine, _TLIGHTYELLOW);
displayList(D_ADD, posX, posY, sdx, sdy);
- sdx = stringLength(_vm._scoreLine);
+ sdx = stringLength(_vm->_scoreLine);
posY = 0;
- writeStr(posX, posY, _vm._scoreLine, _TCYAN);
+ writeStr(posX, posY, _vm->_scoreLine, _TCYAN);
displayList(D_ADD, posX, posY, sdx, sdy);
}
@@ -421,7 +460,7 @@ void Screen::drawShape(int x, int y, int color1, int color2) {
_backBuffer[320 * (y + (2 * shapeSize - 1) - i) + (x + shapeSize + j)] = color2;
_frontBuffer[320 * (y + (2 * shapeSize - 1) - i) + (x + shapeSize + j)] = color2;
}
- }
+ }
}
void Screen::drawRectangle(bool filledFl, uint16 x1, uint16 y1, uint16 x2, uint16 y2, int color) {
@@ -440,5 +479,44 @@ void Screen::drawRectangle(bool filledFl, uint16 x1, uint16 y1, uint16 x2, uint1
}
}
+/**
+* Initialize screen components and display results
+*/
+void Screen::initNewScreenDisplay() {
+ displayList(D_INIT);
+ setBackgroundColor(_TBLACK);
+ displayBackground();
+
+ // Stop premature object display in Display_list(D_DISPLAY)
+ _vm->getGameStatus().newScreenFl = true;
+}
+
+/**
+* Load palette from Hugo.dat
+*/
+void Screen::loadPalette(Common::File &in) {
+ // Read palette
+ _paletteSize = in.readUint16BE();
+ _palette = (byte *)malloc(sizeof(byte) * _paletteSize);
+ for (int i = 0; i < _paletteSize; i++)
+ _palette[i] = in.readByte();
+}
+
+/**
+* Free palette
+*/
+void Screen::freePalette() {
+ free(_palette);
+}
+
+/**
+* Free fonts
+*/
+void Screen::freeFonts() {
+ for (int i = 0; i < NUM_FONTS; i++) {
+ if (_arrayFont[i])
+ free(_arrayFont[i]);
+ }
+}
} // End of namespace Hugo