MADS: More work implementing scene info loading
This commit is contained in:
parent
c49d7196fc
commit
badb8d9744
13 changed files with 256 additions and 295 deletions
|
@ -67,7 +67,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Destructor
|
* Destructor
|
||||||
*/
|
*/
|
||||||
~Dialog();
|
virtual ~Dialog();
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -145,7 +145,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Destructor
|
* Destructor
|
||||||
*/
|
*/
|
||||||
~TextDialog();
|
virtual ~TextDialog();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draw the dialog
|
* Draw the dialog
|
||||||
|
@ -162,6 +162,8 @@ class MessageDialog: protected TextDialog {
|
||||||
public:
|
public:
|
||||||
MessageDialog(MADSEngine *vm, int lines, ...);
|
MessageDialog(MADSEngine *vm, int lines, ...);
|
||||||
|
|
||||||
|
virtual ~MessageDialog() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the dialog, and wait until a key or mouse press.
|
* Show the dialog, and wait until a key or mouse press.
|
||||||
*/
|
*/
|
||||||
|
@ -184,6 +186,8 @@ public:
|
||||||
Common::Point _defaultPosition;
|
Common::Point _defaultPosition;
|
||||||
DialogId _pendingDialog;
|
DialogId _pendingDialog;
|
||||||
|
|
||||||
|
virtual ~Dialogs() {}
|
||||||
|
|
||||||
virtual void showDialog() = 0;
|
virtual void showDialog() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -160,7 +160,7 @@ void Game::sectionLoop() {
|
||||||
_vm->_palette->initGamePalette();
|
_vm->_palette->initGamePalette();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Further palette init
|
_vm->_palette->_paletteUsage.load(3, 0xF0, 0xF1, 0xF2);
|
||||||
|
|
||||||
_scene.loadScene(_scene._nextSceneId, _aaName, 0);
|
_scene.loadScene(_scene._nextSceneId, _aaName, 0);
|
||||||
_vm->_sound->pauseNewCommands();
|
_vm->_sound->pauseNewCommands();
|
||||||
|
|
|
@ -249,219 +249,14 @@ void MSurface::copyFrom(MSurface *src, const Common::Rect &srcBounds,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MSurface::translate(RGBList *list, bool isTransparent) {
|
void MSurface::translate(Common::Array<RGB6> &palette) {
|
||||||
byte *p = getBasePtr(0, 0);
|
for (int y = 0; y < this->h; ++y) {
|
||||||
byte *palIndexes = list->palIndexes();
|
byte *pDest = getBasePtr(0, y);
|
||||||
|
|
||||||
for (int i = 0; i < getWidth() * getHeight(); ++i, ++p) {
|
for (int x = 0; x < this->w; ++x, ++pDest) {
|
||||||
if (!isTransparent || (*p != 0)) {
|
*pDest = palette[*pDest].palIndex;
|
||||||
assert(*p < list->size());
|
|
||||||
*p = palIndexes[*p];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/*
|
|
||||||
void MSurfaceMADS::loadBackground(int roomNumber, RGBList **palData) {
|
|
||||||
// clear previous data
|
|
||||||
empty();
|
|
||||||
|
|
||||||
// Get a MadsPack reference to the tile set and mapping
|
|
||||||
char resourceName[20];
|
|
||||||
int i;
|
|
||||||
|
|
||||||
// Uncompressed tile map resource
|
|
||||||
sprintf(resourceName, "rm%d.mm", roomNumber);
|
|
||||||
MadsPack tileMapFile(resourceName, _vm);
|
|
||||||
Common::SeekableReadStream *mapStream = tileMapFile.getItemStream(0);
|
|
||||||
|
|
||||||
// Get the details of the tiles and map
|
|
||||||
mapStream->readUint32LE();
|
|
||||||
int tileCountX = mapStream->readUint16LE();
|
|
||||||
int tileCountY = mapStream->readUint16LE();
|
|
||||||
int tileWidthMap = mapStream->readUint16LE();
|
|
||||||
int tileHeightMap = mapStream->readUint16LE();
|
|
||||||
int screenWidth = mapStream->readUint16LE();
|
|
||||||
int screenHeight = mapStream->readUint16LE();
|
|
||||||
int tileCountMap = tileCountX * tileCountY;
|
|
||||||
delete mapStream;
|
|
||||||
|
|
||||||
// Obtain tile map information
|
|
||||||
typedef Common::List<Common::SharedPtr<MSurface> > TileSetList;
|
|
||||||
typedef TileSetList::iterator TileSetIterator;
|
|
||||||
TileSetList tileSet;
|
|
||||||
uint16 *tileMap = new uint16[tileCountMap];
|
|
||||||
mapStream = tileMapFile.getItemStream(1);
|
|
||||||
for (i = 0; i < tileCountMap; ++i)
|
|
||||||
tileMap[i] = mapStream->readUint16LE();
|
|
||||||
delete mapStream;
|
|
||||||
|
|
||||||
// _vm->_resources->toss(resourceName);
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Tile map data, which needs to be kept compressed, as the tile offsets refer to
|
|
||||||
// the compressed data. Each tile is then uncompressed separately
|
|
||||||
sprintf(resourceName, "rm%d.tt", roomNumber);
|
|
||||||
Common::SeekableReadStream *tileDataComp = nullptr; //_vm->_resources->get(resourceName);
|
|
||||||
MadsPack tileData(tileDataComp);
|
|
||||||
Common::SeekableReadStream *tileDataUncomp = tileData.getItemStream(0);
|
|
||||||
|
|
||||||
// Validate that the data matches between the tiles and tile map file and is valid
|
|
||||||
int tileCount = tileDataUncomp->readUint16LE();
|
|
||||||
int tileWidth = tileDataUncomp->readUint16LE();
|
|
||||||
int tileHeight = tileDataUncomp->readUint16LE();
|
|
||||||
delete tileDataUncomp;
|
|
||||||
assert(tileCountMap == tileCount);
|
|
||||||
assert(tileWidth == tileWidthMap);
|
|
||||||
assert(tileHeight == tileHeightMap);
|
|
||||||
assert(screenWidth == _vm->_screen->getWidth());
|
|
||||||
assert(screenHeight <= _vm->_screen->getHeight());
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Get the palette to use
|
|
||||||
tileDataUncomp = tileData.getItemStream(2);
|
|
||||||
// Set palette
|
|
||||||
if (!palData) {
|
|
||||||
_vm->_palette->loadPalette(tileDataUncomp, 4);
|
|
||||||
} else {
|
|
||||||
int numColors;
|
|
||||||
byte *rgbList = _vm->_palette->decodePalette(tileDataUncomp, &numColors);
|
|
||||||
*palData = new RGBList(numColors, rgbList, true);
|
|
||||||
}
|
|
||||||
delete tileDataUncomp;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Get tile data
|
|
||||||
|
|
||||||
tileDataUncomp = tileData.getItemStream(1);
|
|
||||||
FabDecompressor fab;
|
|
||||||
uint32 compressedTileDataSize = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < tileCount; i++) {
|
|
||||||
tileDataUncomp->seek(i * 4, SEEK_SET);
|
|
||||||
uint32 tileOfs = tileDataUncomp->readUint32LE();
|
|
||||||
MSurface *newTile = new MSurface(tileWidth, tileHeight);
|
|
||||||
|
|
||||||
if (i == tileCount - 1)
|
|
||||||
compressedTileDataSize = tileDataComp->size() - tileOfs;
|
|
||||||
else
|
|
||||||
compressedTileDataSize = tileDataUncomp->readUint32LE() - tileOfs;
|
|
||||||
|
|
||||||
//printf("Tile: %i, compressed size: %i\n", i, compressedTileDataSize);
|
|
||||||
|
|
||||||
newTile->empty();
|
|
||||||
|
|
||||||
byte *compressedTileData = new byte[compressedTileDataSize];
|
|
||||||
|
|
||||||
tileDataComp->seek(tileData.getDataOffset() + tileOfs, SEEK_SET);
|
|
||||||
tileDataComp->read(compressedTileData, compressedTileDataSize);
|
|
||||||
|
|
||||||
fab.decompress(compressedTileData, compressedTileDataSize, newTile->getData(),
|
|
||||||
tileWidth * tileHeight);
|
|
||||||
tileSet.push_back(TileSetList::value_type(newTile));
|
|
||||||
delete[] compressedTileData;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete tileDataUncomp;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Loop through the mapping data to place the tiles on the screen
|
|
||||||
|
|
||||||
uint16 *tIndex = &tileMap[0];
|
|
||||||
for (int y = 0; y < tileCountY; y++) {
|
|
||||||
for (int x = 0; x < tileCountX; x++) {
|
|
||||||
int tileIndex = *tIndex++;
|
|
||||||
assert(tileIndex < tileCount);
|
|
||||||
TileSetIterator tile = tileSet.begin();
|
|
||||||
for (i = 0; i < tileIndex; i++)
|
|
||||||
++tile;
|
|
||||||
((*tile).get())->copyTo(this, Common::Point(x * tileWidth, y * tileHeight));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tileSet.clear();
|
|
||||||
// _vm->_resources->toss(resourceName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MSurfaceMADS::loadInterface(int index, RGBList **palData) {
|
|
||||||
char resourceName[20];
|
|
||||||
sprintf(resourceName, "i%d.int", index);
|
|
||||||
MadsPack intFile(resourceName, _vm);
|
|
||||||
byte *palette = new byte[16 * 3];
|
|
||||||
|
|
||||||
// Chunk 0, palette
|
|
||||||
Common::SeekableReadStream *intStream = intFile.getItemStream(0);
|
|
||||||
|
|
||||||
for (int i = 0; i < 16; i++) {
|
|
||||||
palette[i * 3] = intStream->readByte() << 2;
|
|
||||||
palette[i * 3 + 1] = intStream->readByte() << 2;
|
|
||||||
palette[i * 3 + 2] = intStream->readByte() << 2;
|
|
||||||
intStream->skip(3);
|
|
||||||
}
|
|
||||||
*palData = new RGBList(16, palette, true);
|
|
||||||
delete intStream;
|
|
||||||
|
|
||||||
// Chunk 1, data
|
|
||||||
intStream = intFile.getItemStream(1);
|
|
||||||
setSize(MADS_SCREEN_WIDTH, MADS_INTERFACE_HEIGHT);
|
|
||||||
intStream->read(pixels, MADS_SCREEN_WIDTH * MADS_INTERFACE_HEIGHT);
|
|
||||||
delete intStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void MSurfaceNebular::loadBackground(int roomNumber, RGBList **palData) {
|
|
||||||
// clear previous data
|
|
||||||
empty();
|
|
||||||
|
|
||||||
Common::String resourceName = Common::String::format("rm%d.art", roomNumber);
|
|
||||||
Common::SeekableReadStream *stream = nullptr; //_vm->_resources->get(resourceName);
|
|
||||||
loadBackgroundStream(stream, palData);
|
|
||||||
|
|
||||||
// _vm->_resources->toss(resourceName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MSurfaceNebular::loadBackgroundStream(Common::SeekableReadStream *source, RGBList **palData) {
|
|
||||||
MadsPack packData(source);
|
|
||||||
Common::MemoryReadStream *sourceUnc = packData.getItemStream(0);
|
|
||||||
|
|
||||||
int sceneWidth = sourceUnc->readUint16LE();
|
|
||||||
int sceneHeight = sourceUnc->readUint16LE();
|
|
||||||
int sceneSize = sceneWidth * sceneHeight;
|
|
||||||
if (sceneWidth > this->getWidth()) {
|
|
||||||
warning("Background width is %i, too large to fit in screen. Setting it to %i", sceneWidth, getWidth());
|
|
||||||
sceneWidth = this->getWidth();
|
|
||||||
sceneSize = sceneWidth * sceneHeight;
|
|
||||||
}
|
|
||||||
if (sceneHeight > getHeight()) {
|
|
||||||
warning("Background height is %i, too large to fit in screen.Setting it to %i", sceneHeight, getHeight());
|
|
||||||
sceneHeight = getHeight();
|
|
||||||
sceneSize = sceneWidth * sceneHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set palette
|
|
||||||
if (!palData) {
|
|
||||||
_vm->_palette->loadPalette(sourceUnc, 4);
|
|
||||||
} else {
|
|
||||||
int numColors;
|
|
||||||
byte *rgbList = _vm->_palette->decodePalette(sourceUnc, &numColors);
|
|
||||||
*palData = new RGBList(numColors, rgbList, true);
|
|
||||||
}
|
|
||||||
delete sourceUnc;
|
|
||||||
|
|
||||||
// Get the raw data for the background
|
|
||||||
sourceUnc = packData.getItemStream(1);
|
|
||||||
assert((int)sourceUnc->size() >= sceneSize);
|
|
||||||
|
|
||||||
byte *pData = (byte *)pixels;
|
|
||||||
sourceUnc->read(pData, sceneSize);
|
|
||||||
|
|
||||||
delete sourceUnc;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
} // End of namespace MADS
|
} // End of namespace MADS
|
||||||
|
|
|
@ -169,9 +169,9 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translates the data of a surface using a specified RGBList translation matrix.
|
* Translates the pixels of an image used the passed palette with RGB mapping
|
||||||
*/
|
*/
|
||||||
void translate(RGBList *list, bool isTransparent = false);
|
void translate(Common::Array<RGB6> &palette);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End of namespace MADS
|
} // End of namespace MADS
|
||||||
|
|
|
@ -300,10 +300,10 @@ byte *ASound::loadData(int offset, int size) {
|
||||||
|
|
||||||
void ASound::playSound(int offset, int size) {
|
void ASound::playSound(int offset, int size) {
|
||||||
// Load the specified data block
|
// Load the specified data block
|
||||||
playSound(loadData(offset, size));
|
playSoundData(loadData(offset, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ASound::playSound(byte *pData, int startingChannel) {
|
void ASound::playSoundData(byte *pData, int startingChannel) {
|
||||||
// Scan for a high level free channel
|
// Scan for a high level free channel
|
||||||
for (int i = startingChannel; i < ADLIB_CHANNEL_COUNT; ++i) {
|
for (int i = startingChannel; i < ADLIB_CHANNEL_COUNT; ++i) {
|
||||||
if (!_channels[i]._activeCount) {
|
if (!_channels[i]._activeCount) {
|
||||||
|
@ -1020,7 +1020,7 @@ int ASound1::command19() {
|
||||||
int ASound1::command20() {
|
int ASound1::command20() {
|
||||||
byte *pData = loadData(0xD18, 28);
|
byte *pData = loadData(0xD18, 28);
|
||||||
if (!isSoundActive(pData))
|
if (!isSoundActive(pData))
|
||||||
playSound(pData);
|
playSoundData(pData);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1034,7 +1034,7 @@ int ASound1::command22() {
|
||||||
pData[6] = (getRandomNumber() & 7) + 85;
|
pData[6] = (getRandomNumber() & 7) + 85;
|
||||||
|
|
||||||
if (!isSoundActive(pData))
|
if (!isSoundActive(pData))
|
||||||
playSound(pData);
|
playSoundData(pData);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1055,7 +1055,7 @@ int ASound1::command24() {
|
||||||
int ASound1::command25() {
|
int ASound1::command25() {
|
||||||
byte *pData = loadData(0xD82, 16);
|
byte *pData = loadData(0xD82, 16);
|
||||||
if (!isSoundActive(pData))
|
if (!isSoundActive(pData))
|
||||||
playSound(pData);
|
playSoundData(pData);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1091,7 +1091,7 @@ int ASound1::command29() {
|
||||||
pData[7] = pData[13] = pData[21] = pData[27] = v;
|
pData[7] = pData[13] = pData[21] = pData[27] = v;
|
||||||
|
|
||||||
if (!isSoundActive(pData))
|
if (!isSoundActive(pData))
|
||||||
playSound(pData, 0);
|
playSoundData(pData, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1101,7 +1101,7 @@ int ASound1::command30() {
|
||||||
pData[7] = (command2627293032() + 0x40) & 0xFF;
|
pData[7] = (command2627293032() + 0x40) & 0xFF;
|
||||||
|
|
||||||
if (!isSoundActive(pData))
|
if (!isSoundActive(pData))
|
||||||
playSound(pData, 0);
|
playSoundData(pData, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1109,7 +1109,7 @@ int ASound1::command30() {
|
||||||
int ASound1::command31() {
|
int ASound1::command31() {
|
||||||
byte *pData = loadData(0xDAE, 14);
|
byte *pData = loadData(0xDAE, 14);
|
||||||
if (!isSoundActive(pData))
|
if (!isSoundActive(pData))
|
||||||
playSound(pData);
|
playSoundData(pData);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1121,7 +1121,7 @@ int ASound1::command32() {
|
||||||
pData[11] = pData[19] = pData[27] = pData[35] = v >> 8;
|
pData[11] = pData[19] = pData[27] = pData[35] = v >> 8;
|
||||||
|
|
||||||
if (!isSoundActive(pData))
|
if (!isSoundActive(pData))
|
||||||
playSound(pData, 0);
|
playSoundData(pData, 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1139,7 +1139,7 @@ int ASound1::command34() {
|
||||||
|
|
||||||
byte *pData = loadData(0xDD0, 22);
|
byte *pData = loadData(0xDD0, 22);
|
||||||
pData[8] = pData[15] = v;
|
pData[8] = pData[15] = v;
|
||||||
playSound(pData);
|
playSoundData(pData);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -228,7 +228,7 @@ protected:
|
||||||
* @param pData Pointer to data block containing sound data
|
* @param pData Pointer to data block containing sound data
|
||||||
* @param startingChannel Channel to start scan from
|
* @param startingChannel Channel to start scan from
|
||||||
*/
|
*/
|
||||||
void playSound(byte *pData, int startingChannel = ADLIB_CHANNEL_COUNT);
|
void playSoundData(byte *pData, int startingChannel = ADLIB_CHANNEL_MIDWAY);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks to see whether the given block of data is already loaded into a channel.
|
* Checks to see whether the given block of data is already loaded into a channel.
|
||||||
|
@ -312,7 +312,7 @@ public:
|
||||||
* @param commandId Player ommand to execute.
|
* @param commandId Player ommand to execute.
|
||||||
* @param param Optional parameter used by a few commands
|
* @param param Optional parameter used by a few commands
|
||||||
*/
|
*/
|
||||||
virtual int command(int commandId, int param = 0) = 0;
|
virtual int command(int commandId, int param) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop all currently playing sounds
|
* Stop all currently playing sounds
|
||||||
|
@ -402,7 +402,7 @@ private:
|
||||||
public:
|
public:
|
||||||
ASound1(Audio::Mixer *mixer);
|
ASound1(Audio::Mixer *mixer);
|
||||||
|
|
||||||
virtual int command(int commandId, int param = 0);
|
virtual int command(int commandId, int param);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End of namespace Nebular
|
} // End of namespace Nebular
|
||||||
|
|
|
@ -28,6 +28,15 @@
|
||||||
|
|
||||||
namespace MADS {
|
namespace MADS {
|
||||||
|
|
||||||
|
void RGB6::load(Common::SeekableReadStream *f) {
|
||||||
|
r = f->readByte();
|
||||||
|
g = f->readByte();
|
||||||
|
b = f->readByte();
|
||||||
|
palIndex = f->readByte();
|
||||||
|
u2 = f->readByte();
|
||||||
|
flags = f->readByte();
|
||||||
|
}
|
||||||
|
|
||||||
RGBList::RGBList(int numEntries, byte *srcData, bool freeData) {
|
RGBList::RGBList(int numEntries, byte *srcData, bool freeData) {
|
||||||
_size = numEntries;
|
_size = numEntries;
|
||||||
assert(numEntries <= PALETTE_COUNT);
|
assert(numEntries <= PALETTE_COUNT);
|
||||||
|
@ -52,6 +61,111 @@ RGBList::~RGBList() {
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
PaletteUsage::PaletteUsage() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaletteUsage::load(int count, ...) {
|
||||||
|
va_list va;
|
||||||
|
va_start(va, count);
|
||||||
|
|
||||||
|
_data.clear();
|
||||||
|
for (int i = 0; i < count; ++i)
|
||||||
|
_data.push_back(va_arg(va, int));
|
||||||
|
|
||||||
|
va_end(va);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PaletteUsage::getKeyEntries(Common::Array<RGB6> &palette) {
|
||||||
|
_data.clear();
|
||||||
|
|
||||||
|
for (uint i = 0; i < palette.size(); ++i) {
|
||||||
|
byte *uPtr = &palette[i].flags;
|
||||||
|
if ((*uPtr & 0x10) && _data.size() < 3) {
|
||||||
|
_data.push_back(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaletteUsage::prioritize(Common::Array<RGB6> &palette) {
|
||||||
|
int lst[3];
|
||||||
|
|
||||||
|
for (uint i = 0; i < _data.size(); ++i) {
|
||||||
|
RGB6 &palEntry = palette[_data[i]];
|
||||||
|
lst[i] = rgbMerge(palEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
prioritizeFromList(lst);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PaletteUsage::rgbMerge(RGB6 &palEntry) {
|
||||||
|
return palEntry.r * 38 + palEntry.g * 76 + palEntry.b * 14;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaletteUsage::prioritizeFromList(int lst[3]) {
|
||||||
|
int idx1 = _data.size() - 1;
|
||||||
|
bool continueFlag;
|
||||||
|
int count2;
|
||||||
|
|
||||||
|
do {
|
||||||
|
continueFlag = false;
|
||||||
|
count2 = 0;
|
||||||
|
|
||||||
|
if (idx1 > 0) {
|
||||||
|
int numEntries = _data.size() - 1;
|
||||||
|
int usageIndex = 0, lstIndex = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (lst[lstIndex] < lst[lstIndex + 1]) {
|
||||||
|
int lstVal = lst[lstIndex];
|
||||||
|
int usageVal = _data[usageIndex];
|
||||||
|
|
||||||
|
if (numEntries > 0) {
|
||||||
|
Common::copy(&lst[lstIndex + 1], &lst[lstIndex + numEntries], &lst[lstIndex]);
|
||||||
|
_data.remove_at(usageIndex);
|
||||||
|
_data.push_back(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int newIdx = 0;
|
||||||
|
if (idx1 > 0 && !continueFlag) {
|
||||||
|
for (newIdx = 0; newIdx <= idx1; ++newIdx) {
|
||||||
|
if (lst[newIdx] > lstVal)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
continueFlag = true;
|
||||||
|
int idxDiff = _data.size() - newIdx - 1;
|
||||||
|
if (idxDiff > 0) {
|
||||||
|
Common::copy_backward(&lst[0], &lst[2], &lst[1]);
|
||||||
|
_data.remove_at(2);
|
||||||
|
_data.insert_at(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
lst[newIdx] = lstVal;
|
||||||
|
_data[newIdx] = usageVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
++usageIndex;
|
||||||
|
--numEntries;
|
||||||
|
++lstIndex;
|
||||||
|
++count2;
|
||||||
|
} while (count2 > idx1 && !continueFlag);
|
||||||
|
}
|
||||||
|
} while (continueFlag);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define VGA_COLOR_TRANS(x) (x == 0x3f ? 255 : x << 2)
|
#define VGA_COLOR_TRANS(x) (x == 0x3f ? 255 : x << 2)
|
||||||
|
|
||||||
Palette::Palette(MADSEngine *vm) : _vm(vm) {
|
Palette::Palette(MADSEngine *vm) : _vm(vm) {
|
||||||
|
|
|
@ -37,6 +37,17 @@ struct RGB4 {
|
||||||
byte u;
|
byte u;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RGB6 {
|
||||||
|
byte r;
|
||||||
|
byte g;
|
||||||
|
byte b;
|
||||||
|
byte palIndex;
|
||||||
|
byte u2;
|
||||||
|
byte flags;
|
||||||
|
|
||||||
|
void load(Common::SeekableReadStream *f);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to store a list of RGB values
|
* Used to store a list of RGB values
|
||||||
*/
|
*/
|
||||||
|
@ -73,6 +84,44 @@ public:
|
||||||
int size() const { return _size; }
|
int size() const { return _size; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PaletteUsage {
|
||||||
|
private:
|
||||||
|
Common::Array<int> _data;
|
||||||
|
|
||||||
|
int rgbMerge(RGB6 &palEntry);
|
||||||
|
|
||||||
|
void prioritizeFromList(int lst[3]);
|
||||||
|
public:
|
||||||
|
PaletteUsage();
|
||||||
|
|
||||||
|
void load(int count, ...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the usage list is empty
|
||||||
|
*/
|
||||||
|
bool empty() const { return _data.size() == 0; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets key entries from the passed palette
|
||||||
|
* @param palette 6-bit per entry read in palette
|
||||||
|
*/
|
||||||
|
void getKeyEntries(Common::Array<RGB6> &palette);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prioritizes the palette index list based on the intensity of the
|
||||||
|
* RGB values of the palette entries that they refer to
|
||||||
|
*/
|
||||||
|
void prioritize(Common::Array<RGB6> &palette);
|
||||||
|
|
||||||
|
bool process(Common::Array<RGB6> &palette, int v) {
|
||||||
|
warning("TODO: PaletteUsage::process");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void transform(Common::Array<RGB6> &palette);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#define PALETTE_COUNT 256
|
#define PALETTE_COUNT 256
|
||||||
#define PALETTE_SIZE (256 * 3)
|
#define PALETTE_SIZE (256 * 3)
|
||||||
|
|
||||||
|
@ -95,6 +144,7 @@ protected:
|
||||||
public:
|
public:
|
||||||
byte _mainPalette[PALETTE_SIZE];
|
byte _mainPalette[PALETTE_SIZE];
|
||||||
RGB4 _gamePalette[PALETTE_COUNT];
|
RGB4 _gamePalette[PALETTE_COUNT];
|
||||||
|
PaletteUsage _paletteUsage;
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
|
|
@ -305,7 +305,7 @@ Common::String Resources::formatName(RESPREFIX resType, int id, const Common::St
|
||||||
|
|
||||||
Common::String Resources::formatResource(const Common::String &resName,
|
Common::String Resources::formatResource(const Common::String &resName,
|
||||||
const Common::String &hagFilename) {
|
const Common::String &hagFilename) {
|
||||||
int v1 = 0, v2 = 0;
|
// int v1 = 0, v2 = 0;
|
||||||
|
|
||||||
if (resName.hasPrefix("*")) {
|
if (resName.hasPrefix("*")) {
|
||||||
// Resource file specified
|
// Resource file specified
|
||||||
|
|
|
@ -34,7 +34,6 @@ Scene::Scene(MADSEngine *vm): _vm(vm), _spriteSlots(vm) {
|
||||||
_vocabBuffer = nullptr;
|
_vocabBuffer = nullptr;
|
||||||
_sceneLogic = nullptr;
|
_sceneLogic = nullptr;
|
||||||
_sceneInfo = nullptr;
|
_sceneInfo = nullptr;
|
||||||
_scenePalette = nullptr;
|
|
||||||
|
|
||||||
_verbList.push_back(VerbInit(VERB_LOOK, 2, 0));
|
_verbList.push_back(VerbInit(VERB_LOOK, 2, 0));
|
||||||
_verbList.push_back(VerbInit(VERB_TAKE, 2, 0));
|
_verbList.push_back(VerbInit(VERB_TAKE, 2, 0));
|
||||||
|
@ -46,7 +45,6 @@ Scene::Scene(MADSEngine *vm): _vm(vm), _spriteSlots(vm) {
|
||||||
_verbList.push_back(VerbInit(VERB_PULL, 2, 0));
|
_verbList.push_back(VerbInit(VERB_PULL, 2, 0));
|
||||||
_verbList.push_back(VerbInit(VERB_CLOSE, 2, 0));
|
_verbList.push_back(VerbInit(VERB_CLOSE, 2, 0));
|
||||||
_verbList.push_back(VerbInit(VERB_THROW, 1, 2));
|
_verbList.push_back(VerbInit(VERB_THROW, 1, 2));
|
||||||
Common::fill((byte *)&_nullPalette[0], (byte *)&_nullPalette[3], 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene::~Scene() {
|
Scene::~Scene() {
|
||||||
|
@ -121,7 +119,7 @@ void Scene::loadScene(int sceneId, const Common::String &prefix, bool palFlag) {
|
||||||
_sequences.clear();
|
_sequences.clear();
|
||||||
_messages.clear();
|
_messages.clear();
|
||||||
|
|
||||||
setPalette(_nullPalette);
|
// TODO: palletteUsage reset? setPalette(_nullPalette);
|
||||||
_sceneInfo = SceneInfo::load(_vm, _currentSceneId, _v1, Common::String(), _vm->_game->_v2 ? 17 : 16,
|
_sceneInfo = SceneInfo::load(_vm, _currentSceneId, _v1, Common::String(), _vm->_game->_v2 ? 17 : 16,
|
||||||
_depthSurface, _backgroundSurface);
|
_depthSurface, _backgroundSurface);
|
||||||
}
|
}
|
||||||
|
@ -178,8 +176,4 @@ void Scene::free() {
|
||||||
warning("TODO: Scene::free");
|
warning("TODO: Scene::free");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::setPalette(RGB4 *p) {
|
|
||||||
// _scenePalette = p;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // End of namespace MADS
|
} // End of namespace MADS
|
||||||
|
|
|
@ -70,8 +70,6 @@ public:
|
||||||
int _textSpacing;
|
int _textSpacing;
|
||||||
Common::Array<Hotspot> _hotspots;
|
Common::Array<Hotspot> _hotspots;
|
||||||
ScreenObjects _screenObjects;
|
ScreenObjects _screenObjects;
|
||||||
ScenePalette *_scenePalette;
|
|
||||||
RGB4 _nullPalette[2];
|
|
||||||
int _v1;
|
int _v1;
|
||||||
SceneInfo *_sceneInfo;
|
SceneInfo *_sceneInfo;
|
||||||
MSurface _backgroundSurface;
|
MSurface _backgroundSurface;
|
||||||
|
@ -134,12 +132,6 @@ public:
|
||||||
* Loads the vocab list
|
* Loads the vocab list
|
||||||
*/
|
*/
|
||||||
void loadVocab();
|
void loadVocab();
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the scene palette
|
|
||||||
*/
|
|
||||||
void setPalette(RGB4 *p);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear the data for the scene
|
* Clear the data for the scene
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "common/scummsys.h"
|
#include "common/scummsys.h"
|
||||||
#include "mads/scene_data.h"
|
#include "mads/scene_data.h"
|
||||||
#include "mads/mads.h"
|
#include "mads/mads.h"
|
||||||
|
#include "mads/compression.h"
|
||||||
#include "mads/resources.h"
|
#include "mads/resources.h"
|
||||||
#include "mads/nebular/nebular_scenes.h"
|
#include "mads/nebular/nebular_scenes.h"
|
||||||
|
|
||||||
|
@ -126,7 +127,6 @@ KernelMessage::KernelMessage() {
|
||||||
_asciiChar = '\0';
|
_asciiChar = '\0';
|
||||||
_asciiChar2 = '\0';
|
_asciiChar2 = '\0';
|
||||||
_colors = 0;
|
_colors = 0;
|
||||||
Common::Point _posiition;
|
|
||||||
_msgOffset = 0;
|
_msgOffset = 0;
|
||||||
_numTicks = 0;
|
_numTicks = 0;
|
||||||
_frameTimer2 = 0;
|
_frameTimer2 = 0;
|
||||||
|
@ -164,28 +164,28 @@ Hotspot::Hotspot(Common::SeekableReadStream &f) {
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void ARTHeader::load(Common::SeekableReadStream &f) {
|
void ARTHeader::load(Common::SeekableReadStream *f) {
|
||||||
_width = f.readUint16LE();
|
// Read in dimensions of image
|
||||||
_height = f.readUint16LE();
|
_width = f->readUint16LE();
|
||||||
|
_height = f->readUint16LE();
|
||||||
|
|
||||||
_palCount = f.readUint16LE();
|
// Read in palette information
|
||||||
for (int i = 0; i < 256; ++i) {
|
int palCount = f->readUint16LE();
|
||||||
|
for (int i = 0; i < palCount; ++i) {
|
||||||
RGB6 rgb;
|
RGB6 rgb;
|
||||||
rgb.r = f.readByte();
|
rgb.load(f);
|
||||||
rgb.g = f.readByte();
|
|
||||||
rgb.b = f.readByte();
|
|
||||||
f.read(&rgb.unused[0], 3);
|
|
||||||
|
|
||||||
_palette.push_back(rgb);
|
_palette.push_back(rgb);
|
||||||
}
|
}
|
||||||
|
f->skip(6 * (256 - palCount));
|
||||||
|
|
||||||
int palCount = f.readUint16LE();
|
// Read unknown???
|
||||||
|
palCount = f->readUint16LE();
|
||||||
for (int i = 0; i < palCount; ++i) {
|
for (int i = 0; i < palCount; ++i) {
|
||||||
RGB4 rgb;
|
RGB4 rgb;
|
||||||
rgb.r = f.readByte();
|
rgb.r = f->readByte();
|
||||||
rgb.g = f.readByte();
|
rgb.g = f->readByte();
|
||||||
rgb.b = f.readByte();
|
rgb.b = f->readByte();
|
||||||
rgb.u = f.readByte();
|
rgb.u = f->readByte();
|
||||||
|
|
||||||
_palData.push_back(rgb);
|
_palData.push_back(rgb);
|
||||||
}
|
}
|
||||||
|
@ -203,12 +203,9 @@ SceneInfo::SceneInfo(MADSEngine *vm, int sceneId, int v1, const Common::String &
|
||||||
bool flag = true;
|
bool flag = true;
|
||||||
bool sceneFlag = sceneId >= 0;
|
bool sceneFlag = sceneId >= 0;
|
||||||
bool ssFlag = false, wsFlag = false;
|
bool ssFlag = false, wsFlag = false;
|
||||||
int handle = 0;
|
|
||||||
|
|
||||||
SpriteAsset *spriteSets[10];
|
Common::Array<SpriteAsset *> spriteSets;
|
||||||
int xpList[10];
|
Common::Array<int> xpList;
|
||||||
Common::fill(&spriteSets[0], &spriteSets[10], (SpriteAsset *)nullptr);
|
|
||||||
Common::fill(&xpList[0], &xpList[10], -1);
|
|
||||||
|
|
||||||
// Figure out the resource to use
|
// Figure out the resource to use
|
||||||
Common::String resourceName;
|
Common::String resourceName;
|
||||||
|
@ -281,21 +278,53 @@ SceneInfo::SceneInfo(MADSEngine *vm, int sceneId, int v1, const Common::String &
|
||||||
|
|
||||||
// Load in the ART header and palette
|
// Load in the ART header and palette
|
||||||
File artFile(resourceName);
|
File artFile(resourceName);
|
||||||
|
MadsPack artResource(&artFile);
|
||||||
|
Common::SeekableReadStream *stream = artResource.getItemStream(0);
|
||||||
|
|
||||||
ARTHeader artHeader;
|
ARTHeader artHeader;
|
||||||
artHeader.load(artFile);
|
artHeader.load(stream);
|
||||||
artFile.close();
|
artFile.close();
|
||||||
|
|
||||||
// Copy out the palette data
|
// Copy out the palette data
|
||||||
for (int i = 0; i < artHeader._palData.size(); ++i)
|
for (uint i = 0; i < artHeader._palData.size(); ++i)
|
||||||
_palette.push_back(artHeader._palData[i]);
|
_palette.push_back(artHeader._palData[i]);
|
||||||
/*
|
|
||||||
if (!(flags & 1)) {
|
if (!(flags & 1)) {
|
||||||
if (_vm->_game->_scene->_scenePalette) {
|
if (!_vm->_palette->_paletteUsage.empty()) {
|
||||||
//_vm->_game->_scene->_scenePalette->clean(&artHeader._palCount);
|
_vm->_palette->_paletteUsage.getKeyEntries(artHeader._palette);
|
||||||
//_vm->_game->_scene->_scenePalette->process(&artHeader._palCount)
|
_vm->_palette->_paletteUsage.prioritize(artHeader._palette);
|
||||||
|
}
|
||||||
|
|
||||||
|
_field4C = _vm->_palette->_paletteUsage.process(artHeader._palette, 0xF800);
|
||||||
|
if (_field4C > 0) {
|
||||||
|
_vm->_palette->_paletteUsage.transform(artHeader._palette);
|
||||||
|
|
||||||
|
for (uint i = 0; i < _palette.size(); ++i) {
|
||||||
|
byte g = _palette[i].g;
|
||||||
|
_palette[g].b = artHeader._palette[g].palIndex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
// Read in the background surface data
|
||||||
|
assert(_width == bgSurface.w && _height == bgSurface.h);
|
||||||
|
stream->read(bgSurface.getPixels(), bgSurface.w * bgSurface.h);
|
||||||
|
|
||||||
|
if (flags & 1) {
|
||||||
|
for (uint i = 0; i < _setNames.size(); ++i) {
|
||||||
|
Common::String setResName;
|
||||||
|
if (sceneFlag || resName.hasPrefix("*"))
|
||||||
|
setResName += "*";
|
||||||
|
setResName += _setNames[i];
|
||||||
|
|
||||||
|
SpriteAsset *sprites = new SpriteAsset(_vm, setResName, flags);
|
||||||
|
spriteSets.push_back(sprites);
|
||||||
|
xpList.push_back(-1); // TODO:: sprites->_field6
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
warning("TODO");
|
warning("TODO");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,12 +355,4 @@ void SceneInfo::loadCodes(MSurface &depthSurface) {
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void ScenePalette::clean(int *palCount) {
|
|
||||||
warning("TODO: ScenePalette::clean");
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScenePalette::process(int *palCount) {
|
|
||||||
warning("TODO: ScenePalette::process");
|
|
||||||
}
|
|
||||||
|
|
||||||
} // End of namespace MADS
|
} // End of namespace MADS
|
||||||
|
|
|
@ -214,6 +214,11 @@ public:
|
||||||
*/
|
*/
|
||||||
SceneLogic(Scene *scene): _scene(scene) {}
|
SceneLogic(Scene *scene): _scene(scene) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor
|
||||||
|
*/
|
||||||
|
virtual ~SceneLogic() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called to initially setup a scene
|
* Called to initially setup a scene
|
||||||
*/
|
*/
|
||||||
|
@ -245,21 +250,13 @@ public:
|
||||||
virtual void postActions() = 0;
|
virtual void postActions() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RGB6 {
|
|
||||||
byte r;
|
|
||||||
byte g;
|
|
||||||
byte b;
|
|
||||||
byte unused[3];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ARTHeader {
|
struct ARTHeader {
|
||||||
int _width;
|
int _width;
|
||||||
int _height;
|
int _height;
|
||||||
int _palCount;
|
|
||||||
Common::Array<RGB6> _palette;
|
Common::Array<RGB6> _palette;
|
||||||
Common::Array<RGB4> _palData;
|
Common::Array<RGB4> _palData;
|
||||||
|
|
||||||
void load(Common::SeekableReadStream &f);
|
void load(Common::SeekableReadStream *f);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -303,12 +300,6 @@ public:
|
||||||
const Common::String &resName, int v3, MSurface &depthSurface, MSurface &bgSurface);
|
const Common::String &resName, int v3, MSurface &depthSurface, MSurface &bgSurface);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ScenePalette {
|
|
||||||
public:
|
|
||||||
void clean(int *palCount);
|
|
||||||
void process(int *palCount);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // End of namespace MADS
|
} // End of namespace MADS
|
||||||
|
|
||||||
#endif /* MADS_SCENE_DATA_H */
|
#endif /* MADS_SCENE_DATA_H */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue