SCI/newgui: support for amiga palette, amiga picture support, cleanup

svn-id: r44685
This commit is contained in:
Martin Kiewitz
2009-10-06 06:50:31 +00:00
parent 36c2625f07
commit 8d762cf0f0
4 changed files with 123 additions and 102 deletions
+32 -10
View File
@@ -88,14 +88,14 @@ void SciGuiGfx::initPalette() {
_sysPalette.colors[255].r = 255;
_sysPalette.colors[255].g = 255;
_sysPalette.colors[255].b = 255;
//if (g_sci->getPlatform() == Common::kPlatformAmiga)
// setAmigaPalette();
//else
// Load default palette from resource 999
if (!SetResPalette(999, 2)) {
// if not found, we set EGA palette
SetEGApalette();
// if not found, we try to set amiga palette
if (!SetAmigaPalette()) {
// if that also doesnt work out, set EGA palette
SetEGApalette();
}
};
// Init _clrPowers used in MatchColor
@@ -121,8 +121,27 @@ GuiPort *SciGuiGfx::mallocPort() {
return newPort;
}
#define SCI_PAL_FORMAT_CONSTANT 1
#define SCI_PAL_FORMAT_VARIABLE 0
// Will try to set amiga palette by using "spal" file. If not found, we return false
bool SciGuiGfx::SetAmigaPalette() {
Common::File file;
int curColor, byte1, byte2;
if (file.open("spal")) {
for (curColor = 0; curColor < 32; curColor++) {
byte1 = file.readByte();
byte2 = file.readByte();
if ((byte1 == EOF) || (byte2 == EOF))
error("Amiga palette file ends prematurely");
_sysPalette.colors[curColor].used = 1;
_sysPalette.colors[curColor].r = (byte1 & 0x0F) * 0x11;
_sysPalette.colors[curColor].g = ((byte2 & 0xF0) >> 4) * 0x11;
_sysPalette.colors[curColor].b = (byte2 & 0x0F) * 0x11;
}
file.close();
return true;
}
return false;
}
void SciGuiGfx::SetEGApalette() {
int i;
@@ -151,6 +170,9 @@ void SciGuiGfx::SetEGApalette() {
setScreenPalette(&_sysPalette);
}
#define SCI_PAL_FORMAT_CONSTANT 1
#define SCI_PAL_FORMAT_VARIABLE 0
void SciGuiGfx::CreatePaletteFromData(byte *data, GuiPalette *paletteOut) {
int palFormat = 0;
int palOffset = 0;
@@ -225,7 +247,7 @@ void SciGuiGfx::MergePalettes(GuiPalette *pFrom, GuiPalette *pTo, uint16 flag) {
if (!pFrom->colors[i].used)// color is not used - so skip it
continue;
// forced palette merging or dest color is not used yet
if (flag == 2 || (!pTo->colors[i].used)) {
if (flag == 2 || (!pTo->colors[i].used)) {
pTo->colors[i].used = pFrom->colors[i].used;
pTo->colors[i].r = pFrom->colors[i].r;
pTo->colors[i].g = pFrom->colors[i].g;
@@ -841,7 +863,7 @@ GuiMemoryHandle SciGuiGfx::SaveBits(const Common::Rect &rect, byte screenMask) {
GuiMemoryHandle memoryId;
byte *memoryPtr;
int size;
Common::Rect r(rect.left, rect.top, rect.right, rect.bottom);
r.clip(_curPort->rect);
if (r.isEmpty()) // nothing to save
@@ -1038,7 +1060,7 @@ const bool pattern_Textures[32 * 8 * 2] = {
false, false, true, false, false, true, false, false, // 0x24
false, false, true, false, false, false, false, // 0x04 (last bit is not mentioned cause original interpreter also ignores that bit)
};
// Bit offsets into pattern_textures
const byte pattern_TextureOffset[128] = {
0x00, 0x18, 0x30, 0xc4, 0xdc, 0x65, 0xeb, 0x48,
+1
View File
@@ -51,6 +51,7 @@ public:
GuiPort *mallocPort ();
byte *GetSegment(byte seg);
void ResetScreen();
bool SetAmigaPalette();
void SetEGApalette();
void CreatePaletteFromData(byte *paletteData, GuiPalette *paletteOut);
bool SetResPalette(int16 resourceNo, int16 flag);
+89 -87
View File
@@ -52,10 +52,6 @@ GuiResourceId SciGuiPicture::getResourceId() {
return _resourceId;
}
#define PALETTE_SIZE 1284
#define CEL_HEADER_SIZE 7
#define EXTRA_MAGIC_SIZE 15
void SciGuiPicture::draw(uint16 style, bool addToFlag, int16 EGApaletteNo) {
_style = style;
_addToFlag = addToFlag;
@@ -64,11 +60,10 @@ void SciGuiPicture::draw(uint16 style, bool addToFlag, int16 EGApaletteNo) {
_priority = 0;
if (READ_LE_UINT16(_resource->data) == 0x26) {
// SCI 1.1 picture
draw11();
// SCI 1.1 VGA picture
drawSci11Vga();
} else {
// Just directly draw the vector data
_gfx->SetEGApalette();
// EGA or Amiga vector data
drawVectorData(_resource->data, _resource->size);
}
}
@@ -82,7 +77,7 @@ void SciGuiPicture::reset() {
}
}
void SciGuiPicture::draw11() {
void SciGuiPicture::drawSci11Vga() {
byte *inbuffer = _resource->data;
int size = _resource->size;
int has_view = READ_LE_UINT16(inbuffer + 4);
@@ -111,7 +106,6 @@ void SciGuiPicture::draw11() {
}
// process vector data
// ?? if we process vector data first some things in sq4 dont seem right, but this way we wont get _priority set
drawVectorData(inbuffer + vector_data_ptr, vector_size);
}
@@ -152,90 +146,83 @@ void SciGuiPicture::drawCel(int16 x, int16 y, byte *pdata, int size) {
signed char dx = *(pdata + 4);
signed char dy = *(pdata + 5);
byte priority = _addToFlag ? _priority : 0;
byte clr = *(pdata + 6);
byte clearColor = *(pdata + 6);
if (dx || dy || width != 320)
debug("Warning: embedded picture cel has width=%d dx=%d dy=%d", width, dx, dy);
warning("embedded picture cel has width=%d dx=%d dy=%d", width, dx, dy);
byte *ptr = pdata + 8; // offset to data
byte byte, runLength;
uint16 lasty;
y += _curPort->top;
uint16 lasty = MIN<int16>(height + y, _curPort->rect.bottom) + _curPort->top;
byte b, brun;
lasty = MIN<int16>(height + y, _curPort->rect.bottom) + _curPort->top;
while (y < lasty && ptr < pend) {
b = *ptr++;
brun = b & 0x3F; // bytes run length on this step
switch (b & 0xC0) {
case 0: // copy bytes as-is but skip transparent ones
while (brun-- && y < lasty && ptr < pend) {
if ((b = *ptr++) != clr && priority >= _screen->getPriority(x, y)) {
_screen->putPixel(x, y, 3, b, priority, 0);
switch (_s->resMan->getViewType()) {
case kViewVga:
case kViewVga11:
while (y < lasty && ptr < pend) {
byte = *ptr++;
runLength = byte & 0x3F; // bytes run length on this step
switch (byte & 0xC0) {
case 0: // copy bytes as-is but skip transparent ones
while (runLength-- && y < lasty && ptr < pend) {
if ((byte = *ptr++) != clearColor && priority >= _screen->getPriority(x, y))
_screen->putPixel(x, y, 3, byte, priority, 0);
x++;
if (x >= _screen->_width) {
x -= _screen->_width; y++;
}
}
x++;
break;
case 0x80: // fill with color
byte = *ptr++;
while (runLength-- && y < lasty) {
if (priority >= _screen->getPriority(x, y)) {
_screen->putPixel(x, y, 3, byte, priority, 0);
}
x++;
if (x >= _screen->_width) {
x -= _screen->_width; y++;
}
}
break;
case 0xC0: // fill with transparent - skip
x += runLength;
if (x >= _screen->_width) {
x -= _screen->_width; y++;
}
}
break;
case 0x80: // fill with color
b = *ptr++;
while (brun-- && y < lasty) {
if (priority >= _screen->getPriority(x, y)) {
_screen->putPixel(x, y, 3, b, priority, 0);
}
x++;
if (x >= _screen->_width) {
x -= _screen->_width; y++;
}
}
break;
case 0xC0: // fill with transparent - skip
x += brun;
if (x >= _screen->_width) {
x -= _screen->_width; y++;
}
break;
}
}
}
void SciGuiPicture::drawCelAmiga(int16 x, int16 y, byte *pdata, int size) {
byte* pend = pdata + size;
uint16 width = READ_LE_UINT16(pdata + 0);
uint16 height = READ_LE_UINT16(pdata + 2);
signed char dx = *(pdata + 4);
signed char dy = *(pdata + 5);
byte priority = _addToFlag ? _priority : 0;
//byte clr = *(pdata + 8);
if (dx || dy || width != 320)
debug("Warning : cel have w=%d dx=%d dy=%d", width, dx, dy);
byte *ptr = pdata + 8; // offset to data
y += _curPort->top;
uint16 lasty = MIN<int16>(height + y, _curPort->rect.bottom) + _curPort->top;
byte op, col, bytes;
while (y < lasty && ptr < pend) {
op = *ptr++;
if (op & 0x07) {
bytes = op & 0x07;
col = op >> 3;
while (bytes-- && y < lasty) {
if (priority >= _screen->getPriority(x, y)) {
_screen->putPixel(x, y, 3, col, priority, 0);
}
x++;
if (x >= _screen->_width) {
x -= _screen->_width; y++;
}
}
} else {
bytes = op >> 3;
x += bytes;
if (x >= _screen->_width) {
x -= _screen->_width; y++;
break;
}
}
break;
case kViewAmiga:
while (y < lasty && ptr < pend) {
byte = *ptr++;
if (byte & 0x07) {
runLength = byte & 0x07;
byte = byte >> 3;
while (runLength-- && y < lasty) {
if (priority >= _screen->getPriority(x, y)) {
_screen->putPixel(x, y, 3, byte, priority, 0);
}
x++;
if (x >= _screen->_width) {
x -= _screen->_width; y++;
}
}
} else {
runLength = byte >> 3;
x += runLength;
if (x >= _screen->_width) {
x -= _screen->_width; y++;
}
}
}
break;
default:
error("Unsupported picture viewtype");
}
}
@@ -282,6 +269,7 @@ enum {
#define PIC_EGAPALETTE_COUNT 4
#define PIC_EGAPALETTE_SIZE 40
#define PIC_EGAPALETTE_TOTALSIZE PIC_EGAPALETTE_COUNT*PIC_EGAPALETTE_SIZE
#define PIC_EGAPRIORITY_SIZE PIC_EGAPALETTE_SIZE
static const byte vector_defaultEGApalette[PIC_EGAPALETTE_SIZE] = {
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
@@ -291,12 +279,21 @@ static const byte vector_defaultEGApalette[PIC_EGAPALETTE_SIZE] = {
0x08, 0x91, 0x2a, 0x3b, 0x4c, 0x5d, 0x6e, 0x88
};
static const byte vector_defaultEGApriority[PIC_EGAPRIORITY_SIZE] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
};
void SciGuiPicture::drawVectorData(byte *data, int dataSize) {
byte pic_op;
byte pic_color = 0, pic_priority = 0x0F, pic_control = 0x0F;
int16 x = 0, y = 0, oldx, oldy;
byte EGApalettes[PIC_EGAPALETTE_TOTALSIZE] = {0};
byte *EGApalette = &EGApalettes[_EGApaletteNo];
byte EGApriority[PIC_EGAPRIORITY_SIZE] = {0};
bool isEGA = false;
int curPos = 0;
uint16 size;
@@ -310,11 +307,13 @@ void SciGuiPicture::drawVectorData(byte *data, int dataSize) {
if (_EGApaletteNo >= PIC_EGAPALETTE_COUNT)
_EGApaletteNo = 0;
if (!_s->resMan->isVGA())
if (_s->resMan->getViewType() == kViewEga) {
isEGA = true;
for (i = 0; i < PIC_EGAPALETTE_TOTALSIZE; i += PIC_EGAPALETTE_SIZE)
memcpy(&EGApalettes[i], &vector_defaultEGApalette, sizeof(vector_defaultEGApalette));
// setup default mapping tables
for (i = 0; i < PIC_EGAPALETTE_TOTALSIZE; i += PIC_EGAPALETTE_SIZE)
memcpy(&EGApalettes[i], &vector_defaultEGApalette, sizeof(vector_defaultEGApalette));
memcpy(&EGApriority, &vector_defaultEGApriority, sizeof(vector_defaultEGApriority));
}
// Drawing
while (curPos < dataSize) {
@@ -333,6 +332,9 @@ void SciGuiPicture::drawVectorData(byte *data, int dataSize) {
case PIC_OP_SET_PRIORITY:
pic_priority = data[curPos++];
if (isEGA) {
pic_priority = EGApriority[pic_color];
}
break;
case PIC_OP_DISABLE_PRIORITY:
pic_priority = 255;
@@ -488,7 +490,7 @@ void SciGuiPicture::drawVectorData(byte *data, int dataSize) {
case PIC_OPX_VGA_PRIORITY_TABLE_EQDIST:
//FIXME
//g_sci->InitPri(READ_LE_UINT16(ptr), READ_LE_UINT16(ptr + 2));
debug(5, "DrawPic::InitPri %d %d",
debug(5, "DrawPic::InitPri %d %d",
READ_LE_UINT16(data + curPos), READ_LE_UINT16(data + curPos + 2));
curPos += 4;
break;
+1 -5
View File
@@ -28,9 +28,6 @@
namespace Sci {
#define SCI_PAL_FORMAT_VARIABLE_FLAGS 0
#define SCI_PAL_FORMAT_CONSTANT_FLAGS 1
#define PIC_STYLE_MIRRORED 0x4000
class SciGuiPicture {
@@ -44,10 +41,9 @@ public:
private:
void initData(GuiResourceId resourceId);
void reset();
void draw11();
void drawSci11Vga();
void decodeRLE(byte *rledata, byte *pixeldata, byte *outbuffer, int size);
void drawCel(int16 x, int16 y, byte *pdata, int size);
void drawCelAmiga(int16 x, int16 y, byte *pdata, int size);
void drawVectorData(byte *data, int size);
bool vectorIsNonOpcode(byte byte);
void vectorGetAbsCoords(byte *data, int &curPos, int16 &x, int16 &y);