aboutsummaryrefslogtreecommitdiff
path: root/engines/mads/palette.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/mads/palette.cpp')
-rw-r--r--engines/mads/palette.cpp257
1 files changed, 247 insertions, 10 deletions
diff --git a/engines/mads/palette.cpp b/engines/mads/palette.cpp
index a0e58ca54b..da59707a91 100644
--- a/engines/mads/palette.cpp
+++ b/engines/mads/palette.cpp
@@ -32,14 +32,15 @@ void RGB6::load(Common::SeekableReadStream *f) {
r = f->readByte();
g = f->readByte();
b = f->readByte();
- palIndex = f->readByte();
- u2 = f->readByte();
- flags = f->readByte();
+ _palIndex = f->readByte();
+ _u2 = f->readByte();
+ _flags = f->readByte();
}
/*------------------------------------------------------------------------*/
-PaletteUsage::PaletteUsage() {
+PaletteUsage::PaletteUsage(MADSEngine *vm) {
+ _vm = vm;
}
void PaletteUsage::load(int count, ...) {
@@ -58,7 +59,7 @@ void PaletteUsage::getKeyEntries(Common::Array<RGB6> &palette) {
_data.clear();
for (uint i = 0; i < palette.size(); ++i) {
- byte *uPtr = &palette[i].flags;
+ byte *uPtr = &palette[i]._flags;
if ((*uPtr & 0x10) && _data.size() < 3) {
_data.push_back(i);
}
@@ -76,6 +77,124 @@ void PaletteUsage::prioritize(Common::Array<RGB6> &palette) {
prioritizeFromList(lst);
}
+int PaletteUsage::process(Common::Array<RGB6> &palette, int v) {
+ byte *palette1 = nullptr, *palette2 = nullptr;
+ int palLow;
+ int palHigh = (v & 0x800) ? 0x100 : 0xC;
+ int palIdx;
+ assert(v >= 0);
+
+ if (v & 0x4000) {
+ palLow = 0;
+ palIdx = palHigh;
+ } else {
+ palLow = _vm->_palette->_lowRange;
+ if ((PALETTE_COUNT - _vm->_palette->_highRange) > palHigh) {
+ palIdx = palHigh;
+ } else {
+ palIdx = PALETTE_COUNT - _vm->_palette->_highRange;
+ }
+ }
+
+ int rgbIndex = _vm->_palette->_rgbList.scan();
+ uint32 rgbMask = 1 << rgbIndex;
+ int varA = v & 0x8000;
+ bool hasUsage = !_vm->_palette->_paletteUsage.empty();
+ bool flag1 = false;
+
+ if (hasUsage) {
+ if (varA || !_vm->_palette->_paletteUsage[0])
+ hasUsage = false;
+
+ if (varA && _vm->_palette->_paletteUsage[0])
+ flag1 = true;
+ }
+
+ if (hasUsage) {
+ getKeyEntries(palette);
+ prioritize(palette);
+ }
+
+ int freeIndex;
+ int palCount = getGamePalFreeIndex(&freeIndex);
+ byte *pal1 = new byte[PALETTE_COUNT];
+ byte *pal2 = new byte[PALETTE_COUNT];
+
+ for (uint palIndex = 0; palIndex < palette.size(); ++palIndex) {
+ pal2[palIndex] = palIndex;
+ pal1[palIndex] = 0;
+
+ if (!(palette[palIndex]._flags & 0x80)) {
+ pal1[palIndex] = 0x40;
+ }
+ if (!(palette[palIndex]._flags & 0x60)) {
+ pal1[palIndex] |= 0x20;
+ }
+ }
+
+ _vm->_palette->processLists(palette.size(), pal1, pal2);
+
+ int var3A = (v & 0x4000) ? 0xffff : 0xfffe;
+
+ for (uint palIndex = 0; palIndex < palette.size(); ++palIndex) {
+ bool var48 = false;
+ int var4 = 0xffff;
+ int v1 = pal1[palIndex];
+
+ if (palette[v1]._flags & 8) {
+ var48 = true;
+ var4 = 0xFD;
+ }
+
+ if (hasUsage && palette[v1]._flags & 0x10) {
+ for (uint usageIndex = 0; usageIndex < _data.size() && !var48; ++usageIndex) {
+ if (_data[usageIndex] == palIndex) {
+ var48 = true;
+ int dataIndex = MIN(usageIndex, _data.size() - 1);
+ var4 = _data[dataIndex];
+ }
+ }
+ }
+
+ if (flag1 && palette[palIndex]._flags & 0x10) {
+ for (uint usageIndex = 0; usageIndex < _data.size() && !var48; ++usageIndex) {
+ if (_data[usageIndex] == palIndex) {
+ var48 = true;
+ var4 = 0xF0 + usageIndex;
+
+ // Copy data into the high end of the main palette
+ RGB6 &pSrc = palette[palIndex];
+ byte *pDest = &_vm->_palette->_mainPalette[var4 * 3];
+ pDest[0] = pSrc.r;
+ pDest[1] = pSrc.g;
+ pDest[2] = pSrc.b;
+ }
+ }
+ }
+
+ if (!var48 && !varA) {
+ int var2 = !(palette[palIndex]._flags & 0x20) && (
+ ((v & 0x2000) && !(palette[palIndex]._flags & 0x40)) ||
+ ((v & 0x1000) && (palCount > 0))
+ ) ? 1 : 0x7fff;
+ int var36 = (palette[palIndex]._flags & 0x80) ? 0 : 2;
+
+ for (int idx = palLow; idx < palIdx; ++idx) {
+ // TODO
+ }
+ }
+ //TODO
+ }
+
+ _vm->_palette->_rgbList[rgbIndex] = 0xffff;
+
+ delete[] pal1;
+ delete[] pal2;
+
+ return rgbIndex;
+}
+
+
int PaletteUsage::rgbMerge(RGB6 &palEntry) {
return palEntry.r * 38 + palEntry.g * 76 + palEntry.b * 14;
}
@@ -137,19 +256,56 @@ void PaletteUsage::transform(Common::Array<RGB6> &palette) {
if (!empty()) {
for (uint i = 0; i < _data.size(); ++i) {
int palIndex = _data[i];
- _data[i] = palette[palIndex].palIndex;
+ _data[i] = palette[palIndex]._palIndex;
+ }
+ }
+}
+
+int PaletteUsage::getGamePalFreeIndex(int *palIndex) {
+ *palIndex = -1;
+ int count = 0;
+
+ for (int i = 0; i < PALETTE_COUNT; ++i) {
+ RGB4 &r = _vm->_palette->_gamePalette[i];
+ if (!(r.r | r.g | r.b | r.u)) {
+ ++count;
+ if (*palIndex < 0)
+ *palIndex = i;
}
}
+
+ return count;
+}
+
+/*------------------------------------------------------------------------*/
+
+void RGBList::clear() {
+ Common::fill(&_data[0], &_data[32], 0);
+}
+
+void RGBList::reset() {
+ Common::fill(&_data[2], &_data[32], 0);
+}
+
+int RGBList::scan() {
+ for (int i = 0; i < 32; ++i) {
+ if (!_data[i])
+ return i;
+ }
+
+ error("List was full");
}
/*------------------------------------------------------------------------*/
#define VGA_COLOR_TRANS(x) (x == 0x3f ? 255 : x << 2)
-Palette::Palette(MADSEngine *vm) : _vm(vm) {
+Palette::Palette(MADSEngine *vm) : _vm(vm), _paletteUsage(vm) {
reset();
- _fading_in_progress = false;
- Common::fill(&_usageCount[0], &_usageCount[PALETTE_COUNT], 0);
+
+ _v1 = 0;
+ _lowRange = 0;
+ _highRange = 0;
Common::fill(&_mainPalette[0], &_mainPalette[PALETTE_SIZE], 0);
}
@@ -228,6 +384,49 @@ void Palette::setGradient(byte *palette, int start, int count, int rgbValue1, in
}
}
+void Palette::processLists(int count, byte *pal1, byte *pal2) {
+ bool continueFlag;
+ int endIndex = count - 1;
+
+ do {
+ continueFlag = false;
+
+ for (int palIndex = 0; palIndex < endIndex && !continueFlag; ++palIndex) {
+ byte *palP = &pal1[palIndex];
+ byte *pal2P = &pal2[palIndex];
+
+ if (palP[1] < palP[0]) {
+ int v1 = palP[0];
+ int v2 = pal2P[0];
+
+ int size = count - palIndex - 1;
+ if (size > 0) {
+ Common::copy(palP + 1, palP + size + 1, palP);
+ Common::copy(pal2P + 1, pal2P + size + 1, pal2P);
+ }
+
+ int idx;
+ for (idx = 0; idx < endIndex && !continueFlag; ++idx) {
+ if (pal1[idx] > v1)
+ continueFlag = true;
+ }
+ continueFlag = true;
+
+ int size2 = count - idx - 1;
+ if (size2 > 0) {
+ Common::copy(palP + idx, palP + idx + size2 + 1, palP);
+ Common::copy(pal2P + idx, pal2P + idx + size2 + 1, pal2P);
+ }
+
+ pal1[idx] = v1;
+ pal2[idx] = v2;
+ }
+ }
+
+ } while (continueFlag);
+}
+
+
byte *Palette::decodePalette(Common::SeekableReadStream *palStream, int *numColors) {
*numColors = palStream->readUint16LE();
assert(*numColors <= 252);
@@ -288,10 +487,43 @@ void Palette::resetGamePalette(int lowRange, int highRange) {
Common::fill(&_gamePalette[255 - highRange], &_gamePalette[254], _gamePalette[255]);
}
+
+ _rgbList.clear();
+ _v1 = 0;
+ _lowRange = lowRange;
+ _highRange = highRange;
}
void Palette::initGamePalette() {
- // TODO
+ RGB4 rgb;
+ rgb.r = 1;
+
+ if (_vm->_game->_player._spritesLoaded && _vm->_game->_player._numSprites) {
+
+ for (int idx = 0; idx < _vm->_game->_player._numSprites; ++idx) {
+ SpriteAsset *asset = _vm->_game->_scene._sprites[
+ _vm->_game->_player._spritesStart + idx];
+
+ uint32 mask = 1;
+ if (asset->_field6)
+ mask <<= asset->_field6;
+
+ rgb.r = mask & 0xff;
+ rgb.g = (mask >> 8) & 0xff;
+ rgb.b = (mask >> 16) & 0xff;
+ rgb.u = (mask >> 24) & 0xff;
+ }
+ }
+
+ for (int idx = 0; idx < PALETTE_COUNT; ++idx) {
+ _gamePalette[idx].r &= rgb.r;
+ _gamePalette[idx].g &= rgb.g;
+ _gamePalette[idx].b &= rgb.b;
+ _gamePalette[idx].u &= rgb.u;
+ }
+
+ _v1 = 0;
+ _rgbList.reset();
}
void Palette::initRange(byte *palette) {
@@ -337,4 +569,9 @@ void Palette::setLowRange() {
_vm->_palette->setPalette(_mainPalette, 0, 4);
}
+void Palette::fadeOut(byte palette[PALETTE_SIZE], int v1, int v2, int v3, int v4, int v5, int v6) {
+
+}
+
+
} // End of namespace MADS