aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Schickel2009-09-21 01:15:34 +0000
committerJohannes Schickel2009-09-21 01:15:34 +0000
commitcb41cea6f17ede63f4bf5a5083e2ed97e33c58bd (patch)
treec1a08b4c5ca60d4376fc75bfd0ddf9f0cb87585d
parent756659b00e3c09a8aa958ef5b4e519d3dafcc4f0 (diff)
downloadscummvm-rg350-cb41cea6f17ede63f4bf5a5083e2ed97e33c58bd.tar.gz
scummvm-rg350-cb41cea6f17ede63f4bf5a5083e2ed97e33c58bd.tar.bz2
scummvm-rg350-cb41cea6f17ede63f4bf5a5083e2ed97e33c58bd.zip
Changed AMIGA menu code to closer match the original. (The menu item highlight selection is still wrong though.)
svn-id: r44231
-rw-r--r--engines/cine/gfx.cpp148
-rw-r--r--engines/cine/gfx.h5
-rw-r--r--engines/cine/various.cpp9
3 files changed, 124 insertions, 38 deletions
diff --git a/engines/cine/gfx.cpp b/engines/cine/gfx.cpp
index 9866d86353..61c60bfd17 100644
--- a/engines/cine/gfx.cpp
+++ b/engines/cine/gfx.cpp
@@ -92,7 +92,7 @@ static const byte cursorPalette[] = {
*/
FWRenderer::FWRenderer() : _background(NULL), _backupPal(), _cmd(""),
_cmdY(0), _messageBg(0), _backBuffer(new byte[_screenSize]),
- _activePal(), _changePal(0), _showCollisionPage(false) {
+ _screenBackUp(0), _activePal(), _changePal(0), _showCollisionPage(false) {
assert(_backBuffer);
@@ -105,6 +105,7 @@ FWRenderer::FWRenderer() : _background(NULL), _backupPal(), _cmd(""),
FWRenderer::~FWRenderer() {
delete[] _background;
delete[] _backBuffer;
+ delete[] _screenBackUp;
}
bool FWRenderer::initialize() {
@@ -243,8 +244,13 @@ void FWRenderer::drawMessage(const char *str, int x, int y, int width, int color
int line = 0, words = 0, cw = 0;
int space = 0, extraSpace = 0;
+ const bool isAmiga = (g_cine->getPlatform() == Common::kPlatformAmiga);
+
if (color >= 0) {
- drawPlainBox(x, y, width, 4, color);
+ if (isAmiga)
+ drawTransparentBox(x, y, width, 4);
+ else
+ drawPlainBox(x, y, width, 4, color);
}
tx = x + 4;
ty = str[0] ? y - 5 : y + 4;
@@ -266,7 +272,10 @@ void FWRenderer::drawMessage(const char *str, int x, int y, int width, int color
ty += 9;
if (color >= 0) {
- drawPlainBox(x, ty, width, 9, color);
+ if (isAmiga)
+ drawTransparentBox(x, ty, width, 4);
+ else
+ drawPlainBox(x, ty, width, 9, color);
}
tx = x + 4;
}
@@ -285,8 +294,11 @@ void FWRenderer::drawMessage(const char *str, int x, int y, int width, int color
ty += 9;
if (color >= 0) {
- drawPlainBox(x, ty, width, 4, color);
- drawDoubleBorder(x, y, width, ty - y + 4, g_cine->getPlatform() == Common::kPlatformAmiga ? 18 : 2);
+ if (isAmiga)
+ drawTransparentBox(x, ty, width, 4);
+ else
+ drawPlainBox(x, ty, width, 4, color);
+ drawDoubleBorder(x, y, width, ty - y + 4, isAmiga ? 18 : 2);
}
}
@@ -330,31 +342,42 @@ void FWRenderer::drawPlainBox(int x, int y, int width, int height, byte color) {
Common::Rect screenRect(320, 200);
boxRect.clip(screenRect);
- // Draw the filled rectangle
- //
- // Since the Amiga version uses a transparent boxes we need to decide whether:
- // - we draw a box, that should be the case when both width and height is greater than 1
- // - we draw a line, that should be the case when either width or height is 1
- // When we draw a box and we're running an Amiga version we do use special code to make
- // the boxes transparent.
- // When on the other hand we are drawing a line or are not running an Amiga version, we will
- // always use the code, which simply fills the rect.
- //
- // TODO: Think over whether this is the nicest / best solution we can find for handling
- // the transparency for Amiga boxes.
- if (g_cine->getPlatform() == Common::kPlatformAmiga && width > 1 && height > 1) {
- byte *dest = _backBuffer + boxRect.top * 320 + boxRect.left;
- const int lineAdd = 320 - boxRect.width();
- for (int i = 0; i < boxRect.height(); ++i) {
- for (int j = 0; j < boxRect.width(); ++j)
- *dest++ += 16;
- dest += lineAdd;
- }
- } else {
- byte *dest = _backBuffer + boxRect.top * 320 + boxRect.left;
- for (int i = 0; i < boxRect.height(); i++) {
- memset(dest + i * 320, color, boxRect.width());
+ byte *dest = _backBuffer + boxRect.top * 320 + boxRect.left;
+ for (int i = 0; i < boxRect.height(); i++) {
+ memset(dest + i * 320, color, boxRect.width());
+ }
+}
+
+void FWRenderer::drawTransparentBox(int x, int y, int width, int height) {
+ // Handle horizontally flipped boxes
+ if (width < 0) {
+ width = ABS(width);
+ x -= width;
+ }
+
+ // Handle vertically flipped boxes
+ if (height < 0) {
+ height = ABS(height);
+ y -= height;
+ }
+
+ // Clip the rectangle to screen dimensions
+ Common::Rect boxRect(x, y, x + width, y + height);
+ Common::Rect screenRect(320, 200);
+ boxRect.clip(screenRect);
+
+ byte *dest = _backBuffer + boxRect.top * 320 + boxRect.left;
+ const byte *src = _screenBackUp + boxRect.top * 320 + boxRect.left;
+ const int lineAdd = 320 - boxRect.width();
+ for (int i = 0; i < boxRect.height(); ++i) {
+ for (int j = 0; j < boxRect.width(); ++j) {
+ if (*src < 16)
+ *dest++ = *src++ + 16;
+ else
+ *dest++ = *src++;
}
+ dest += lineAdd;
+ src += lineAdd;
}
}
@@ -770,6 +793,22 @@ void FWRenderer::transformPalette(int first, int last, int r, int g, int b) {
refreshPalette();
}
+void FWRenderer::prepareMenu() {
+ if (g_cine->getPlatform() != Common::kPlatformAmiga)
+ return;
+
+ if (!_screenBackUp) {
+ _screenBackUp = new uint8[_screenSize];
+ assert(_screenBackUp);
+ }
+ memcpy(_screenBackUp, _backBuffer, _screenSize);
+}
+
+void FWRenderer::discardMenu() {
+ delete[] _screenBackUp;
+ _screenBackUp = 0;
+}
+
/*! \brief Draw menu box, one item per line with possible highlight
* \param items Menu items
* \param height Item count
@@ -790,12 +829,28 @@ void FWRenderer::drawMenu(const CommandeType *items, unsigned int height, int x,
y = 199 - th;
}
- drawPlainBox(x, y, width, 4, _messageBg);
+ const bool isAmiga = (g_cine->getPlatform() == Common::kPlatformAmiga);
+
+ if (isAmiga)
+ drawTransparentBox(x, y, width, 4);
+ else
+ drawPlainBox(x, y, width, 4, _messageBg);
ty = y + 4;
for (i = 0; i < height; i++, ty += 9) {
- drawPlainBox(x, ty, width, 9, (int)i == selected ? 0 : _messageBg);
+ if (isAmiga) {
+ // The original Amiga version is using a different highlight color here,
+ // but with our current code it is not possible to change the text color
+ // thus we can not use it, since otherwise the text wouldn't be visible
+ // anymore.
+ if ((int)i == selected)
+ drawPlainBox(x, ty, width, 9, 0/*2*/);
+ else
+ drawTransparentBox(x, ty, width, 9);
+ } else {
+ drawPlainBox(x, ty, width, 9, (int)i == selected ? 0 : _messageBg);
+ }
tx = x + 4;
for (j = 0; items[i][j]; j++) {
@@ -803,8 +858,11 @@ void FWRenderer::drawMenu(const CommandeType *items, unsigned int height, int x,
}
}
- drawPlainBox(x, ty, width, 4, _messageBg);
- drawDoubleBorder(x, y, width, ty - y + 4, g_cine->getPlatform() == Common::kPlatformAmiga ? 18 : 2);
+ if (isAmiga)
+ drawTransparentBox(x, ty, width, 4);
+ else
+ drawPlainBox(x, ty, width, 4, _messageBg);
+ drawDoubleBorder(x, y, width, ty - y + 4, isAmiga ? 18 : 2);
}
/*! \brief Draw text input box
@@ -820,7 +878,12 @@ void FWRenderer::drawInputBox(const char *info, const char *input, int cursor, i
int line = 0, words = 0, cw = 0;
int space = 0, extraSpace = 0;
- drawPlainBox(x, y, width, 4, _messageBg);
+ const bool isAmiga = (g_cine->getPlatform() == Common::kPlatformAmiga);
+
+ if (isAmiga)
+ drawTransparentBox(x, y, width, 4);
+ else
+ drawPlainBox(x, y, width, 4, _messageBg);
tx = x + 4;
ty = info[0] ? y - 5 : y + 4;
tw = width - 8;
@@ -840,7 +903,10 @@ void FWRenderer::drawInputBox(const char *info, const char *input, int cursor, i
}
ty += 9;
- drawPlainBox(x, ty, width, 9, _messageBg);
+ if (isAmiga)
+ drawTransparentBox(x, ty, width, 9);
+ else
+ drawPlainBox(x, ty, width, 9, _messageBg);
tx = x + 4;
}
@@ -858,7 +924,10 @@ void FWRenderer::drawInputBox(const char *info, const char *input, int cursor, i
// input area background
ty += 9;
- drawPlainBox(x, ty, width, 9, _messageBg);
+ if (isAmiga)
+ drawTransparentBox(x, ty, width, 9);
+ else
+ drawPlainBox(x, ty, width, 9, _messageBg);
drawPlainBox(x + 16, ty - 1, width - 32, 9, 0);
tx = x + 20;
@@ -876,8 +945,11 @@ void FWRenderer::drawInputBox(const char *info, const char *input, int cursor, i
}
ty += 9;
- drawPlainBox(x, ty, width, 4, _messageBg);
- drawDoubleBorder(x, y, width, ty - y + 4, g_cine->getPlatform() == Common::kPlatformAmiga ? 18 : 2);
+ if (isAmiga)
+ drawTransparentBox(x, ty, width, 4);
+ else
+ drawPlainBox(x, ty, width, 4, _messageBg);
+ drawDoubleBorder(x, y, width, ty - y + 4, isAmiga ? 18 : 2);
}
/*! \brief Fade to black
diff --git a/engines/cine/gfx.h b/engines/cine/gfx.h
index 87fd92c639..54542f31cd 100644
--- a/engines/cine/gfx.h
+++ b/engines/cine/gfx.h
@@ -80,6 +80,7 @@ protected:
static const int _screenHeight = 200; ///< Screen height
byte *_backBuffer; ///< Screen backbuffer
+ byte *_screenBackUp; ///< Screen backbuffer's backup for the transparent menu code in the Amiga version
Cine::Palette _backupPal; ///< The backup color palette
Cine::Palette _activePal; ///< The active color palette
int _changePal; ///< Load active palette to video backend on next frame
@@ -92,6 +93,7 @@ protected:
void drawCommand();
void drawMessage(const char *str, int x, int y, int width, int color);
void drawPlainBox(int x, int y, int width, int height, byte color);
+ void drawTransparentBox(int x, int y, int width, int height);
void drawBorder(int x, int y, int width, int height, byte color);
void drawDoubleBorder(int x, int y, int width, int height, byte color);
virtual int drawChar(char character, int x, int y);
@@ -142,6 +144,9 @@ public:
virtual void rotatePalette(int a, int b, int c);
virtual void transformPalette(int first, int last, int r, int g, int b);
+ void prepareMenu();
+ void discardMenu();
+
void drawMenu(const CommandeType *items, unsigned int height, int x, int y, int width, int selected);
void drawInputBox(const char *info, const char *input, int cursor, int x, int y, int width);
diff --git a/engines/cine/various.cpp b/engines/cine/various.cpp
index 015ee1dd2f..2fc48f20f0 100644
--- a/engines/cine/various.cpp
+++ b/engines/cine/various.cpp
@@ -492,8 +492,10 @@ void processInventory(int16 x, int16 y) {
if (!listSize)
return;
+ renderer->prepareMenu();
renderer->drawMenu(objectListCommand, listSize, x, y, menuWidth, -1);
renderer->blit();
+ renderer->discardMenu();
do {
manageEvents();
@@ -688,6 +690,7 @@ int16 makeMenuChoice(const CommandeType commandList[], uint16 height, uint16 X,
Y = 199 - paramY;
}
+ renderer->prepareMenu();
renderer->drawMenu(commandList, height, X, Y, width, -1);
renderer->blit();
@@ -766,6 +769,8 @@ int16 makeMenuChoice(const CommandeType commandList[], uint16 height, uint16 X,
} while (!var_A && !g_cine->shouldQuit());
+ renderer->discardMenu();
+
assert(!needMouseSave);
var_4 = button;
@@ -1602,6 +1607,8 @@ bool makeTextEntryMenu(const char *messagePtr, char *inputString, int stringMaxL
int inputLength = strlen(inputString);
int inputPos = inputLength + 1;
+ renderer->prepareMenu();
+
while (!quit) {
if (redraw) {
renderer->drawInputBox(messagePtr, inputString, inputPos, x - 16, y, width + 32);
@@ -1684,6 +1691,8 @@ bool makeTextEntryMenu(const char *messagePtr, char *inputString, int stringMaxL
}
}
+ renderer->discardMenu();
+
if (quit == 2)
return false;