aboutsummaryrefslogtreecommitdiff
path: root/engines/drascula/graphics.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/drascula/graphics.cpp')
-rw-r--r--engines/drascula/graphics.cpp201
1 files changed, 90 insertions, 111 deletions
diff --git a/engines/drascula/graphics.cpp b/engines/drascula/graphics.cpp
index 67993bfb6c..de35de5ab2 100644
--- a/engines/drascula/graphics.cpp
+++ b/engines/drascula/graphics.cpp
@@ -47,6 +47,10 @@ void DrasculaEngine::allocMemory() {
assert(tableSurface);
extraSurface = (byte *)malloc(64000);
assert(extraSurface);
+ crosshairCursor = (byte *)malloc(40 * 25);
+ assert(crosshairCursor);
+ mouseCursor = (byte *)malloc(OBJWIDTH * OBJHEIGHT);
+ assert(mouseCursor);
}
void DrasculaEngine::freeMemory() {
@@ -58,10 +62,12 @@ void DrasculaEngine::freeMemory() {
free(drawSurface3);
free(extraSurface);
free(frontSurface);
+ free(crosshairCursor);
+ free(mouseCursor);
}
void DrasculaEngine::moveCursor() {
- copyBackground(0, 0, 0, 0, 320, 200, bgSurface, screenSurface);
+ copyBackground();
updateRefresh_pre();
moveCharacters();
@@ -78,14 +84,6 @@ void DrasculaEngine::moveCursor() {
showMenu();
else if (menuBar == 1)
clearMenu();
-
- int cursorPos[6] = { 0, 0, mouseX - 20, mouseY - 17, OBJWIDTH, OBJHEIGHT };
- copyRectClip(cursorPos, drawSurface3, screenSurface);
-}
-
-void DrasculaEngine::setCursorTable() {
- int cursorPos[6] = { 225, 56, mouseX - 20, mouseY - 12, 40, 25 };
- copyRectClip(cursorPos, tableSurface, screenSurface);
}
void DrasculaEngine::loadPic(const char *NamePcc, byte *targetSurface, int colorCount) {
@@ -148,7 +146,15 @@ void DrasculaEngine::copyBackground(int xorg, int yorg, int xdes, int ydes, int
int height, byte *src, byte *dest) {
dest += xdes + ydes * 320;
src += xorg + yorg * 320;
+ /* Unoptimized code
for (int x = 0; x < height; x++) {
+ memcpy(dest + 320 * x, src + 320 * x, width);
+ } */
+
+ // A bit more optimized code, thanks to Fingolfin
+ // Uses 2 less registers and performs 2 less multiplications
+ int x = height;
+ while (x--) {
memcpy(dest, src, width);
dest += 320;
src += 320;
@@ -159,24 +165,7 @@ void DrasculaEngine::copyRect(int xorg, int yorg, int xdes, int ydes, int width,
int height, byte *src, byte *dest) {
int y, x;
- dest += xdes + ydes * 320;
- src += xorg + yorg * 320;
-
- for (y = 0; y < height; y++)
- for (x = 0; x < width; x++)
- if (src[x + y * 320] != 255)
- dest[x + y * 320] = src[x + y * 320];
-}
-
-void DrasculaEngine::copyRectClip(int *Array, byte *src, byte *dest) {
- int y, x;
- int xorg = Array[0];
- int yorg = Array[1];
- int xdes = Array[2];
- int ydes = Array[3];
- int width = Array[4];
- int height = Array[5];
-
+ //
if (ydes < 0) {
yorg += -ydes;
height += ydes;
@@ -191,6 +180,7 @@ void DrasculaEngine::copyRectClip(int *Array, byte *src, byte *dest) {
width -= (xdes + width) - 320;
if ((ydes + height) > 199)
height -= (ydes + height) - 200;
+ //
dest += xdes + ydes * 320;
src += xorg + yorg * 320;
@@ -202,16 +192,7 @@ void DrasculaEngine::copyRectClip(int *Array, byte *src, byte *dest) {
}
void DrasculaEngine::updateScreen(int xorg, int yorg, int xdes, int ydes, int width, int height, byte *buffer) {
- byte *ptr = VGA;
-
- ptr += xdes + ydes * 320;
- buffer += xorg + yorg * 320;
- for (int x = 0; x < height; x++) {
- memcpy(ptr, buffer, width);
- ptr += 320;
- buffer += 320;
- }
-
+ copyBackground(xorg, yorg, xdes, ydes, width, height, buffer, VGA);
_system->copyRectToScreen((const byte *)VGA, 320, 0, 0, 320, 200);
_system->updateScreen();
}
@@ -229,22 +210,22 @@ void DrasculaEngine::print_abc(const char *said, int screenX, int screenY) {
letterX = _charMap[i].mappedChar;
switch (_charMap[i].charType) {
- case 0: // letters
- letterY = (_lang == kSpanish) ? 149 : 158;
- break;
- case 1: // signs
- letterY = (_lang == kSpanish) ? 160 : 169;
- break;
- case 2: // accented
- letterY = 180;
- break;
+ case 0: // letters
+ letterY = (_lang == kSpanish) ? 149 : 158;
+ break;
+ case 1: // signs
+ letterY = (_lang == kSpanish) ? 160 : 169;
+ break;
+ case 2: // accented
+ letterY = 180;
+ break;
} // switch
break;
} // if
} // for
- int textPos[6] = { letterX, letterY, screenX, screenY, CHAR_WIDTH, CHAR_HEIGHT };
- copyRectClip(textPos, textSurface, screenSurface);
+ copyRect(letterX, letterY, screenX, screenY,
+ CHAR_WIDTH, CHAR_HEIGHT, tableSurface, screenSurface);
screenX = screenX + CHAR_WIDTH;
if (screenX > 317) {
@@ -254,10 +235,12 @@ void DrasculaEngine::print_abc(const char *said, int screenX, int screenY) {
} // for
}
-void DrasculaEngine::print_abc_opc(const char *said, int screenX, int screenY, int game) {
+void DrasculaEngine::print_abc_opc(const char *said, int screenY, int game) {
int signY, letterY, letterX = 0;
uint len = strlen(said);
+ int screenX = 1;
+
for (uint h = 0; h < len; h++) {
if (game == 1) {
letterY = 6;
@@ -293,76 +276,70 @@ void DrasculaEngine::print_abc_opc(const char *said, int screenX, int screenY, i
} // if
} // for
- int textPos[6] = { letterX, letterY, screenX, screenY, CHAR_WIDTH_OPC, CHAR_HEIGHT_OPC };
- copyRectClip(textPos, backSurface, screenSurface);
+ copyRect(letterX, letterY, screenX, screenY,
+ CHAR_WIDTH_OPC, CHAR_HEIGHT_OPC, backSurface, screenSurface);
screenX = screenX + CHAR_WIDTH_OPC;
}
}
-void DrasculaEngine::centerText(const char *message, int textX, int textY) {
- char bb[200], m2[200], m1[200], mb[10][50];
- char m3[200];
- int h, fil, textX3, textX2, textX1, conta_f = 0, ya = 0;
-
- strcpy(m1, " ");
- strcpy(m2, " ");
- strcpy(m3, " ");
- strcpy(bb, " ");
-
- for (h = 0; h < 10; h++)
- strcpy(mb[h], " ");
-
- if (textX > 160)
- ya = 1;
-
- strcpy(m1, message);
- textX = CLIP<int>(textX, 60, 255);
-
- textX1 = textX;
-
- if (ya == 1)
- textX1 = 315 - textX;
-
- textX2 = (strlen(m1) / 2) * CHAR_WIDTH;
-
- while (true) {
- strcpy(bb, m1);
- scumm_strrev(bb);
-
- if (textX1 < textX2) {
- strcpy(m3, strrchr(m1, ' '));
- strcpy(m1, strstr(bb, " "));
- scumm_strrev(m1);
- m1[strlen(m1) - 1] = '\0';
- strcat(m3, m2);
- strcpy(m2, m3);
- };
-
- textX2 = (strlen(m1) / 2) * CHAR_WIDTH;
-
- if (textX1 < textX2)
- continue;
+bool DrasculaEngine::textFitsCentered(char *text, int x) {
+ int len = strlen(text);
+ int tmp = CLIP<int>(x - len * CHAR_WIDTH / 2, 60, 255);
+ return (tmp + len * CHAR_WIDTH) <= 320;
+}
- strcpy(mb[conta_f], m1);
+void DrasculaEngine::centerText(const char *message, int textX, int textY) {
+ char msg[200];
+ char messageLine[200];
+ char tmpMessageLine[200];
+ *messageLine = 0;
+ *tmpMessageLine = 0;
+ char *curWord;
+ int curLine = 0;
+ int x = 0;
+ // original starts printing 4 lines above textY
+ int y = CLIP<int>(textY - (4 * CHAR_HEIGHT), 0, 320);
- if (!strcmp(m2, ""))
- break;
+ strcpy(msg, message);
- scumm_strrev(m2);
- m2[strlen(m2) - 1] = '\0';
- scumm_strrev(m2);
- strcpy(m1, m2);
- strcpy(m2, "");
- conta_f++;
+ // If the message fits on screen as-is, just print it here
+ if (textFitsCentered(msg, textX)) {
+ x = CLIP<int>(textX - strlen(msg) * CHAR_WIDTH / 2, 60, 255);
+ print_abc(msg, x, y);
+ return;
}
- fil = textY - (((conta_f + 3) * CHAR_HEIGHT));
+ // Message doesn't fit on screen, split it
+
+ // Get a word from the message
+ curWord = strtok(msg, " ");
+ while (curWord != NULL) {
+ // Check if the word and the current line fit on screen
+ if (strlen(tmpMessageLine) > 0)
+ strcat(tmpMessageLine, " ");
+ strcat(tmpMessageLine, curWord);
+ if (textFitsCentered(tmpMessageLine, textX)) {
+ // Line fits, so add the word to the current message line
+ strcpy(messageLine, tmpMessageLine);
+ } else {
+ // Line doesn't fit, so show the current line on screen and
+ // create a new one
+ // If it goes off screen, print_abc will adjust it
+ x = CLIP<int>(textX - strlen(messageLine) * CHAR_WIDTH / 2, 60, 255);
+ print_abc(messageLine, x, y + curLine * CHAR_HEIGHT);
+ strcpy(messageLine, curWord);
+ strcpy(tmpMessageLine, curWord);
+ curLine++;
+ }
+
+ // Get next word
+ curWord = strtok(NULL, " ");
- for (h = 0; h < conta_f + 1; h++) {
- textX3 = strlen(mb[h]) / 2;
- print_abc(mb[h], ((textX) - textX3 * CHAR_WIDTH) - 1, fil);
- fil = fil + CHAR_HEIGHT + 2;
+ if (curWord == NULL) {
+ x = CLIP<int>(textX - strlen(messageLine) * CHAR_WIDTH / 2, 60, 255);
+ print_abc(messageLine, x, y + curLine * CHAR_HEIGHT);
+ }
}
}
@@ -375,6 +352,8 @@ void DrasculaEngine::screenSaver() {
int tempLine[320];
int tempRow[200];
+ hideCursor();
+
clearRoom();
loadPic("sv.alg", bgSurface, HALF_PAL);
@@ -463,6 +442,7 @@ void DrasculaEngine::screenSaver() {
free(ghost);
loadPic(roomNumber, bgSurface, HALF_PAL);
+ showCursor();
}
void DrasculaEngine::playFLI(const char *filefli, int vel) {
@@ -621,12 +601,11 @@ void DrasculaEngine::decodeRLE(byte* srcPtr, byte* dstPtr) {
pixel = *srcPtr++;
}
for (uint j = 0; j < repeat; j++) {
- curByte++;
- if (curByte > 64000) {
+ *dstPtr++ = pixel;
+ if (++curByte >= 64000) {
stopProcessing = true;
break;
}
- *dstPtr++ = pixel;
}
}
}