mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-13 15:40:57 +00:00
SCI32: Add bitmap segment and remove GC option from hunk segment
This commit is contained in:
parent
4e31c9aaf4
commit
2071196f42
@ -1984,7 +1984,7 @@ bool Console::cmdShowSavedBits(int argc, const char **argv) {
|
||||
|
||||
byte bakMask = GFX_SCREEN_MASK_VISUAL | GFX_SCREEN_MASK_PRIORITY | GFX_SCREEN_MASK_CONTROL;
|
||||
int bakSize = _engine->_gfxScreen->bitsGetDataSize(rect, bakMask);
|
||||
reg_t bakScreen = segman->allocateHunkEntry("show_saved_bits backup", bakSize, true);
|
||||
reg_t bakScreen = segman->allocateHunkEntry("show_saved_bits backup", bakSize);
|
||||
byte* bakMemory = segman->getHunkPointer(bakScreen);
|
||||
assert(bakMemory);
|
||||
_engine->_gfxScreen->bitsSave(rect, bakMask, bakMemory);
|
||||
@ -2080,6 +2080,10 @@ bool Console::cmdPrintSegmentTable(int argc, const char **argv) {
|
||||
case SEG_TYPE_STRING:
|
||||
debugPrintf("T SCI32 strings (%d)", (*(StringTable *)mobj).entries_used);
|
||||
break;
|
||||
|
||||
case SEG_TYPE_BITMAP:
|
||||
debugPrintf("T SCI32 bitmaps (%d)", (*(BitmapTable *)mobj).entries_used);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
@ -2214,6 +2218,9 @@ bool Console::segmentInfo(int nr) {
|
||||
case SEG_TYPE_ARRAY:
|
||||
debugPrintf("SCI32 arrays\n");
|
||||
break;
|
||||
case SEG_TYPE_BITMAP:
|
||||
debugPrintf("SCI32 bitmaps\n");
|
||||
break;
|
||||
#endif
|
||||
|
||||
default :
|
||||
@ -2815,6 +2822,12 @@ bool Console::cmdViewReference(int argc, const char **argv) {
|
||||
hexDumpReg(array->getRawData(), array->getSize(), 4, 0, true);
|
||||
break;
|
||||
}
|
||||
case SEG_TYPE_BITMAP: {
|
||||
debugPrintf("SCI32 bitmap:\n");
|
||||
const SciBitmap *bitmap = _engine->_gamestate->_segMan->lookupBitmap(reg);
|
||||
Common::hexdump((const byte *) bitmap->getRawData(), bitmap->getRawSize(), 16, 0);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default: {
|
||||
const SegmentRef block = _engine->_gamestate->_segMan->dereference(reg);
|
||||
|
@ -154,16 +154,18 @@ AddrSet *findAllActiveReferences(EngineState *s) {
|
||||
}
|
||||
}
|
||||
|
||||
// Init: Explicitly opted-out hunks
|
||||
else if (heap[i]->getType() == SEG_TYPE_HUNK) {
|
||||
HunkTable *ht = static_cast<HunkTable *>(heap[i]);
|
||||
#ifdef ENABLE_SCI32
|
||||
// Init: Explicitly opted-out bitmaps
|
||||
else if (heap[i]->getType() == SEG_TYPE_BITMAP) {
|
||||
BitmapTable *bt = static_cast<BitmapTable *>(heap[i]);
|
||||
|
||||
for (uint j = 0; j < ht->_table.size(); j++) {
|
||||
if (!ht->_table[j].data.gc) {
|
||||
for (uint j = 0; j < bt->_table.size(); j++) {
|
||||
if (!bt->_table[j].data.getShouldGC()) {
|
||||
wm.push(make_reg(i, j));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -408,6 +408,7 @@ uint16 Kernel::findRegType(reg_t reg) {
|
||||
#ifdef ENABLE_SCI32
|
||||
case SEG_TYPE_ARRAY:
|
||||
case SEG_TYPE_STRING:
|
||||
case SEG_TYPE_BITMAP:
|
||||
#endif
|
||||
result |= SIG_TYPE_REFERENCE;
|
||||
break;
|
||||
|
@ -536,13 +536,14 @@ reg_t kBitmapCreate(EngineState *s, int argc, reg_t *argv) {
|
||||
int16 scaledHeight = argc > 5 ? argv[5].toSint16() : g_sci->_gfxText32->_scaledHeight;
|
||||
bool useRemap = argc > 6 ? argv[6].toSint16() : false;
|
||||
|
||||
BitmapResource bitmap(s->_segMan, width, height, skipColor, 0, 0, scaledWidth, scaledHeight, 0, useRemap, true);
|
||||
reg_t bitmapId;
|
||||
SciBitmap &bitmap = *s->_segMan->allocateBitmap(&bitmapId, width, height, skipColor, 0, 0, scaledWidth, scaledHeight, 0, useRemap, true);
|
||||
memset(bitmap.getPixels(), backColor, width * height);
|
||||
return bitmap.getObject();
|
||||
return bitmapId;
|
||||
}
|
||||
|
||||
reg_t kBitmapDestroy(EngineState *s, int argc, reg_t *argv) {
|
||||
s->_segMan->freeHunkEntry(argv[0]);
|
||||
s->_segMan->freeBitmap(argv[0]);
|
||||
return s->r_acc;
|
||||
}
|
||||
|
||||
@ -552,7 +553,7 @@ reg_t kBitmapDrawLine(EngineState *s, int argc, reg_t *argv) {
|
||||
}
|
||||
|
||||
reg_t kBitmapDrawView(EngineState *s, int argc, reg_t *argv) {
|
||||
BitmapResource bitmap(argv[0]);
|
||||
SciBitmap &bitmap = *s->_segMan->lookupBitmap(argv[0]);
|
||||
CelObjView view(argv[1].toUint16(), argv[2].toSint16(), argv[3].toSint16());
|
||||
|
||||
const int16 x = argc > 4 ? argv[4].toSint16() : 0;
|
||||
@ -582,7 +583,7 @@ reg_t kBitmapDrawView(EngineState *s, int argc, reg_t *argv) {
|
||||
reg_t kBitmapDrawText(EngineState *s, int argc, reg_t *argv) {
|
||||
// called e.g. from TextButton::createBitmap() in Torin's Passage, script 64894
|
||||
|
||||
BitmapResource bitmap(argv[0]);
|
||||
SciBitmap &bitmap = *s->_segMan->lookupBitmap(argv[0]);
|
||||
Common::String text = s->_segMan->getString(argv[1]);
|
||||
Common::Rect textRect(
|
||||
argv[2].toSint16(),
|
||||
@ -609,7 +610,7 @@ reg_t kBitmapDrawText(EngineState *s, int argc, reg_t *argv) {
|
||||
reg_t textBitmapObject = g_sci->_gfxText32->createFontBitmap(textRect.width(), textRect.height(), Common::Rect(textRect.width(), textRect.height()), text, foreColor, backColor, skipColor, fontId, alignment, borderColor, dimmed, false, false);
|
||||
CelObjMem textCel(textBitmapObject);
|
||||
textCel.draw(bitmap.getBuffer(), textRect, Common::Point(textRect.left, textRect.top), false);
|
||||
s->_segMan->freeHunkEntry(textBitmapObject);
|
||||
s->_segMan->freeBitmap(textBitmapObject);
|
||||
|
||||
return s->r_acc;
|
||||
}
|
||||
@ -617,7 +618,7 @@ reg_t kBitmapDrawText(EngineState *s, int argc, reg_t *argv) {
|
||||
reg_t kBitmapDrawColor(EngineState *s, int argc, reg_t *argv) {
|
||||
// called e.g. from TextView::init() and TextView::draw() in Torin's Passage, script 64890
|
||||
|
||||
BitmapResource bitmap(argv[0]);
|
||||
SciBitmap &bitmap = *s->_segMan->lookupBitmap(argv[0]);
|
||||
Common::Rect fillRect(
|
||||
argv[1].toSint16(),
|
||||
argv[2].toSint16(),
|
||||
@ -642,7 +643,7 @@ reg_t kBitmapInvert(EngineState *s, int argc, reg_t *argv) {
|
||||
}
|
||||
|
||||
reg_t kBitmapSetDisplace(EngineState *s, int argc, reg_t *argv) {
|
||||
BitmapResource bitmap(argv[0]);
|
||||
SciBitmap &bitmap = *s->_segMan->lookupBitmap(argv[0]);
|
||||
bitmap.setDisplace(Common::Point(argv[1].toSint16(), argv[2].toSint16()));
|
||||
return s->r_acc;
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ reg_t kLoad(EngineState *s, int argc, reg_t *argv) {
|
||||
|
||||
// Request to dynamically allocate hunk memory for later use
|
||||
if (restype == kResourceTypeMemory)
|
||||
return s->_segMan->allocateHunkEntry("kLoad()", resnr, true);
|
||||
return s->_segMan->allocateHunkEntry("kLoad()", resnr);
|
||||
|
||||
return make_reg(0, ((restype << 11) | resnr)); // Return the resource identifier as handle
|
||||
}
|
||||
|
@ -158,6 +158,18 @@ void syncWithSerializer(Common::Serializer &s, SciString &obj) {
|
||||
obj.setValue(i, value);
|
||||
}
|
||||
}
|
||||
|
||||
void syncWithSerializer(Common::Serializer &s, SciBitmap &obj) {
|
||||
debug("TODO: Sync bitmap");
|
||||
|
||||
// if (s.isSaving()) {
|
||||
// size = obj.getSize();
|
||||
// s.syncAsUint32LE(size);
|
||||
// } else {
|
||||
// s.syncAsUint32LE(size);
|
||||
// obj.setSize(size);
|
||||
// }
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma mark -
|
||||
@ -273,6 +285,8 @@ void SegManager::saveLoadWithSerializer(Common::Serializer &s) {
|
||||
} else if (type == SEG_TYPE_STRING) {
|
||||
// Set the correct segment for SCI32 strings
|
||||
_stringSegId = i;
|
||||
} else if (s.getVersion() >= 36 && type == SEG_TYPE_BITMAP) {
|
||||
_bitmapSegId = i;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -687,6 +701,14 @@ void StringTable::saveLoadWithSerializer(Common::Serializer &ser) {
|
||||
|
||||
sync_Table<StringTable>(ser, *this);
|
||||
}
|
||||
|
||||
void BitmapTable::saveLoadWithSerializer(Common::Serializer &ser) {
|
||||
if (ser.getVersion() < 36)
|
||||
return;
|
||||
|
||||
// TODO: Should only include bitmaps with gc = true
|
||||
sync_Table(ser, *this);
|
||||
}
|
||||
#endif
|
||||
|
||||
void GfxPalette::palVarySaveLoadPalette(Common::Serializer &s, Palette *palette) {
|
||||
|
@ -37,6 +37,7 @@ struct EngineState;
|
||||
*
|
||||
* Version - new/changed feature
|
||||
* =============================
|
||||
* 36 - SCI32 bitmap segment
|
||||
* 35 - SCI32 remap
|
||||
* 34 - SCI32 palettes, and store play time in ticks
|
||||
* 33 - new overridePriority flag in MusicEntry
|
||||
@ -60,7 +61,7 @@ struct EngineState;
|
||||
*/
|
||||
|
||||
enum {
|
||||
CURRENT_SAVEGAME_VERSION = 35,
|
||||
CURRENT_SAVEGAME_VERSION = 36,
|
||||
MINIMUM_SAVEGAME_VERSION = 14
|
||||
};
|
||||
|
||||
|
@ -43,6 +43,7 @@ SegManager::SegManager(ResourceManager *resMan, ScriptPatcher *scriptPatcher)
|
||||
#ifdef ENABLE_SCI32
|
||||
_arraysSegId = 0;
|
||||
_stringSegId = 0;
|
||||
_bitmapSegId = 0;
|
||||
#endif
|
||||
|
||||
createClassTable();
|
||||
@ -72,6 +73,7 @@ void SegManager::resetSegMan() {
|
||||
#ifdef ENABLE_SCI32
|
||||
_arraysSegId = 0;
|
||||
_stringSegId = 0;
|
||||
_bitmapSegId = 0;
|
||||
#endif
|
||||
|
||||
// Reinitialize class table
|
||||
@ -393,7 +395,7 @@ void SegManager::freeHunkEntry(reg_t addr) {
|
||||
ht->freeEntryContents(addr.getOffset());
|
||||
}
|
||||
|
||||
reg_t SegManager::allocateHunkEntry(const char *hunk_type, int size, bool gc) {
|
||||
reg_t SegManager::allocateHunkEntry(const char *hunk_type, int size) {
|
||||
HunkTable *table;
|
||||
int offset;
|
||||
|
||||
@ -412,7 +414,6 @@ reg_t SegManager::allocateHunkEntry(const char *hunk_type, int size, bool gc) {
|
||||
h->mem = malloc(size);
|
||||
h->size = size;
|
||||
h->type = hunk_type;
|
||||
h->gc = gc;
|
||||
|
||||
return addr;
|
||||
}
|
||||
@ -942,6 +943,60 @@ void SegManager::freeString(reg_t addr) {
|
||||
stringTable.freeEntry(addr.getOffset());
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Bitmaps
|
||||
|
||||
SciBitmap *SegManager::allocateBitmap(reg_t *addr, const int16 width, const int16 height, const uint8 skipColor, const int16 displaceX, const int16 displaceY, const int16 scaledWidth, const int16 scaledHeight, const uint32 paletteSize, const bool remap, const bool gc) {
|
||||
BitmapTable *table;
|
||||
int offset;
|
||||
|
||||
if (!_bitmapSegId) {
|
||||
table = (BitmapTable *)allocSegment(new BitmapTable(), &(_bitmapSegId));
|
||||
} else {
|
||||
table = (BitmapTable *)_heap[_bitmapSegId];
|
||||
}
|
||||
|
||||
offset = table->allocEntry();
|
||||
|
||||
*addr = make_reg(_bitmapSegId, offset);
|
||||
SciBitmap *bitmap = &table->at(offset);
|
||||
|
||||
if (bitmap == nullptr) {
|
||||
*addr = NULL_REG;
|
||||
}
|
||||
|
||||
bitmap->create(width, height, skipColor, displaceX, displaceY, scaledWidth, scaledHeight, paletteSize, remap, gc);
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
SciBitmap *SegManager::lookupBitmap(const reg_t addr) {
|
||||
if (_heap[addr.getSegment()]->getType() != SEG_TYPE_BITMAP)
|
||||
error("Attempt to use non-bitmap %04x:%04x as bitmap", PRINT_REG(addr));
|
||||
|
||||
BitmapTable &bitmapTable = *(BitmapTable *)_heap[addr.getSegment()];
|
||||
|
||||
if (!bitmapTable.isValidEntry(addr.getOffset()))
|
||||
error("Attempt to use non-bitmap %04x:%04x as bitmap", PRINT_REG(addr));
|
||||
|
||||
return &(bitmapTable.at(addr.getOffset()));
|
||||
}
|
||||
|
||||
void SegManager::freeBitmap(const reg_t addr) {
|
||||
if (_heap[addr.getSegment()]->getType() != SEG_TYPE_BITMAP)
|
||||
error("Attempt to use non-bitmap %04x:%04x as bitmap", PRINT_REG(addr));
|
||||
|
||||
BitmapTable &bitmapTable = *(BitmapTable *)_heap[addr.getSegment()];
|
||||
|
||||
if (!bitmapTable.isValidEntry(addr.getOffset()))
|
||||
error("Attempt to use non-bitmap %04x:%04x as bitmap", PRINT_REG(addr));
|
||||
|
||||
bitmapTable.at(addr.getOffset()).destroy();
|
||||
bitmapTable.freeEntry(addr.getOffset());
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
#endif
|
||||
|
||||
void SegManager::createClassTable() {
|
||||
|
@ -29,6 +29,10 @@
|
||||
#include "sci/engine/vm.h"
|
||||
#include "sci/engine/vm_types.h"
|
||||
#include "sci/engine/segment.h"
|
||||
#ifdef ENABLE_SCI32
|
||||
// TODO: Baaaad?
|
||||
#include "sci/graphics/celobj32.h"
|
||||
#endif
|
||||
|
||||
namespace Sci {
|
||||
|
||||
@ -225,11 +229,9 @@ public:
|
||||
* @param[in] size Number of bytes to allocate for the hunk entry
|
||||
* @param[in] hunk_type A descriptive string for the hunk entry, for
|
||||
* debugging purposes
|
||||
* @param[in] gc Whether to make the hunk eligible for garbage
|
||||
* collection
|
||||
* @return The offset of the freshly allocated hunk entry
|
||||
*/
|
||||
reg_t allocateHunkEntry(const char *hunk_type, int size, bool gc);
|
||||
reg_t allocateHunkEntry(const char *hunk_type, int size);
|
||||
|
||||
/**
|
||||
* Deallocates a hunk entry
|
||||
@ -435,10 +437,15 @@ public:
|
||||
SciArray<reg_t> *allocateArray(reg_t *addr);
|
||||
SciArray<reg_t> *lookupArray(reg_t addr);
|
||||
void freeArray(reg_t addr);
|
||||
|
||||
SciString *allocateString(reg_t *addr);
|
||||
SciString *lookupString(reg_t addr);
|
||||
void freeString(reg_t addr);
|
||||
SegmentId getStringSegmentId() { return _stringSegId; }
|
||||
|
||||
SciBitmap *allocateBitmap(reg_t *addr, const int16 width, const int16 height, const uint8 skipColor = kDefaultSkipColor, const int16 displaceX = 0, const int16 displaceY = 0, const int16 scaledWidth = kLowResX, const int16 scaledHeight = kLowResY, const uint32 paletteSize = 0, const bool remap = false, const bool gc = true);
|
||||
SciBitmap *lookupBitmap(reg_t addr);
|
||||
void freeBitmap(reg_t addr);
|
||||
#endif
|
||||
|
||||
const Common::Array<SegmentObj *> &getSegments() const { return _heap; }
|
||||
@ -464,6 +471,7 @@ private:
|
||||
#ifdef ENABLE_SCI32
|
||||
SegmentId _arraysSegId;
|
||||
SegmentId _stringSegId;
|
||||
SegmentId _bitmapSegId;
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
@ -70,6 +70,9 @@ SegmentObj *SegmentObj::createSegmentObj(SegmentType type) {
|
||||
case SEG_TYPE_STRING:
|
||||
mem = new StringTable();
|
||||
break;
|
||||
case SEG_TYPE_BITMAP:
|
||||
mem = new BitmapTable();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
error("Unknown SegmentObj type %d", type);
|
||||
@ -310,6 +313,17 @@ SegmentRef StringTable::dereference(reg_t pointer) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Bitmaps
|
||||
|
||||
SegmentRef BitmapTable::dereference(reg_t pointer) {
|
||||
SegmentRef ret;
|
||||
ret.isRaw = true;
|
||||
ret.maxSize = at(pointer.getOffset()).getRawSize();
|
||||
ret.raw = at(pointer.getOffset()).getRawData();
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // End of namespace Sci
|
||||
|
@ -71,6 +71,7 @@ enum SegmentType {
|
||||
#ifdef ENABLE_SCI32
|
||||
SEG_TYPE_ARRAY = 11,
|
||||
SEG_TYPE_STRING = 12,
|
||||
SEG_TYPE_BITMAP = 13,
|
||||
#endif
|
||||
|
||||
SEG_TYPE_MAX // For sanity checking
|
||||
@ -205,7 +206,6 @@ struct Hunk {
|
||||
void *mem;
|
||||
uint32 size;
|
||||
const char *type;
|
||||
bool gc;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@ -520,6 +520,244 @@ struct StringTable : public SegmentObjTable<SciString> {
|
||||
SegmentRef dereference(reg_t pointer);
|
||||
};
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Bitmaps
|
||||
|
||||
enum {
|
||||
kDefaultSkipColor = 250
|
||||
};
|
||||
|
||||
#define BITMAP_PROPERTY(size, property, offset)\
|
||||
inline uint##size get##property() const {\
|
||||
return READ_SCI11ENDIAN_UINT##size(_data + (offset));\
|
||||
}\
|
||||
inline void set##property(uint##size value) {\
|
||||
WRITE_SCI11ENDIAN_UINT##size(_data + (offset), (value));\
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience class for creating and modifying in-memory
|
||||
* bitmaps.
|
||||
*/
|
||||
class SciBitmap {
|
||||
byte *_data;
|
||||
int _dataSize;
|
||||
Buffer _buffer;
|
||||
bool _gc;
|
||||
|
||||
public:
|
||||
enum BitmapFlags {
|
||||
kBitmapRemap = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the size of the bitmap header for the current
|
||||
* engine version.
|
||||
*/
|
||||
static inline uint16 getBitmapHeaderSize() {
|
||||
// TODO: These values are accurate for each engine, but there may be no reason
|
||||
// to not simply just always use size 40, since SCI2.1mid does not seem to
|
||||
// actually store any data above byte 40, and SCI2 did not allow bitmaps with
|
||||
// scaling resolutions other than the default (320x200). Perhaps SCI3 used
|
||||
// the extra bytes, or there is some reason why they tried to align the header
|
||||
// size with other headers like pic headers?
|
||||
// uint32 bitmapHeaderSize;
|
||||
// if (getSciVersion() >= SCI_VERSION_2_1_MIDDLE) {
|
||||
// bitmapHeaderSize = 46;
|
||||
// } else if (getSciVersion() == SCI_VERSION_2_1_EARLY) {
|
||||
// bitmapHeaderSize = 40;
|
||||
// } else {
|
||||
// bitmapHeaderSize = 36;
|
||||
// }
|
||||
// return bitmapHeaderSize;
|
||||
return 46;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the byte size of a bitmap with the given width
|
||||
* and height.
|
||||
*/
|
||||
static inline uint32 getBitmapSize(const uint16 width, const uint16 height) {
|
||||
return width * height + getBitmapHeaderSize();
|
||||
}
|
||||
|
||||
inline SciBitmap() : _data(nullptr), _dataSize(0), _gc(true) {}
|
||||
|
||||
/**
|
||||
* Allocates and initialises a new bitmap.
|
||||
*/
|
||||
inline void create(const int16 width, const int16 height, const uint8 skipColor, const int16 displaceX, const int16 displaceY, const int16 scaledWidth, const int16 scaledHeight, const uint32 paletteSize, const bool remap, const bool gc) {
|
||||
|
||||
_dataSize = getBitmapSize(width, height) + paletteSize;
|
||||
_data = (byte *)realloc(_data, _dataSize);
|
||||
_gc = gc;
|
||||
|
||||
const uint16 bitmapHeaderSize = getBitmapHeaderSize();
|
||||
|
||||
setWidth(width);
|
||||
setHeight(height);
|
||||
setDisplace(Common::Point(displaceX, displaceY));
|
||||
setSkipColor(skipColor);
|
||||
_data[9] = 0;
|
||||
WRITE_SCI11ENDIAN_UINT16(_data + 10, 0);
|
||||
setRemap(remap);
|
||||
setDataSize(width * height);
|
||||
WRITE_SCI11ENDIAN_UINT32(_data + 16, 0);
|
||||
setHunkPaletteOffset(paletteSize > 0 ? (width * height) : 0);
|
||||
setDataOffset(bitmapHeaderSize);
|
||||
setUncompressedDataOffset(bitmapHeaderSize);
|
||||
setControlOffset(0);
|
||||
setScaledWidth(scaledWidth);
|
||||
setScaledHeight(scaledHeight);
|
||||
|
||||
_buffer = Buffer(getWidth(), getHeight(), getPixels());
|
||||
}
|
||||
|
||||
inline void destroy() {
|
||||
free(_data);
|
||||
_data = nullptr;
|
||||
_dataSize = 0;
|
||||
}
|
||||
|
||||
inline int getRawSize() const {
|
||||
return _dataSize;
|
||||
}
|
||||
|
||||
inline byte *getRawData() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
inline Buffer &getBuffer() {
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
inline bool getShouldGC() const {
|
||||
return _gc;
|
||||
}
|
||||
|
||||
inline void enableGC() {
|
||||
_gc = true;
|
||||
}
|
||||
|
||||
inline void disableGC() {
|
||||
_gc = false;
|
||||
}
|
||||
|
||||
BITMAP_PROPERTY(16, Width, 0);
|
||||
BITMAP_PROPERTY(16, Height, 2);
|
||||
|
||||
inline Common::Point getDisplace() const {
|
||||
return Common::Point(
|
||||
(int16)READ_SCI11ENDIAN_UINT16(_data + 4),
|
||||
(int16)READ_SCI11ENDIAN_UINT16(_data + 6)
|
||||
);
|
||||
}
|
||||
|
||||
inline void setDisplace(const Common::Point &displace) {
|
||||
WRITE_SCI11ENDIAN_UINT16(_data + 4, (uint16)displace.x);
|
||||
WRITE_SCI11ENDIAN_UINT16(_data + 6, (uint16)displace.y);
|
||||
}
|
||||
|
||||
inline uint8 getSkipColor() const {
|
||||
return _data[8];
|
||||
}
|
||||
|
||||
inline void setSkipColor(const uint8 skipColor) {
|
||||
_data[8] = skipColor;
|
||||
}
|
||||
|
||||
inline bool getRemap() const {
|
||||
return READ_SCI11ENDIAN_UINT16(_data + 10) & kBitmapRemap;
|
||||
}
|
||||
|
||||
inline void setRemap(const bool remap) {
|
||||
uint16 flags = READ_SCI11ENDIAN_UINT16(_data + 10);
|
||||
if (remap) {
|
||||
flags |= kBitmapRemap;
|
||||
} else {
|
||||
flags &= ~kBitmapRemap;
|
||||
}
|
||||
WRITE_SCI11ENDIAN_UINT16(_data + 10, flags);
|
||||
}
|
||||
|
||||
BITMAP_PROPERTY(32, DataSize, 12);
|
||||
|
||||
inline uint32 getHunkPaletteOffset() const {
|
||||
return READ_SCI11ENDIAN_UINT32(_data + 20);
|
||||
}
|
||||
|
||||
inline void setHunkPaletteOffset(uint32 hunkPaletteOffset) {
|
||||
if (hunkPaletteOffset) {
|
||||
hunkPaletteOffset += getBitmapHeaderSize();
|
||||
}
|
||||
|
||||
WRITE_SCI11ENDIAN_UINT32(_data + 20, hunkPaletteOffset);
|
||||
}
|
||||
|
||||
BITMAP_PROPERTY(32, DataOffset, 24);
|
||||
|
||||
// NOTE: This property is used as a "magic number" for
|
||||
// validating that a block of memory is a valid bitmap,
|
||||
// and so is always set to the size of the header.
|
||||
BITMAP_PROPERTY(32, UncompressedDataOffset, 28);
|
||||
|
||||
// NOTE: This property always seems to be zero
|
||||
BITMAP_PROPERTY(32, ControlOffset, 32);
|
||||
|
||||
inline uint16 getScaledWidth() const {
|
||||
if (getDataOffset() >= 40) {
|
||||
return READ_SCI11ENDIAN_UINT16(_data + 36);
|
||||
}
|
||||
|
||||
// SCI2 bitmaps did not have scaling ability
|
||||
return 320;
|
||||
}
|
||||
|
||||
inline void setScaledWidth(uint16 scaledWidth) {
|
||||
if (getDataOffset() >= 40) {
|
||||
WRITE_SCI11ENDIAN_UINT16(_data + 36, scaledWidth);
|
||||
}
|
||||
}
|
||||
|
||||
inline uint16 getScaledHeight() const {
|
||||
if (getDataOffset() >= 40) {
|
||||
return READ_SCI11ENDIAN_UINT16(_data + 38);
|
||||
}
|
||||
|
||||
// SCI2 bitmaps did not have scaling ability
|
||||
return 200;
|
||||
}
|
||||
|
||||
inline void setScaledHeight(uint16 scaledHeight) {
|
||||
if (getDataOffset() >= 40) {
|
||||
WRITE_SCI11ENDIAN_UINT16(_data + 38, scaledHeight);
|
||||
}
|
||||
}
|
||||
|
||||
inline byte *getPixels() {
|
||||
return _data + getUncompressedDataOffset();
|
||||
}
|
||||
|
||||
inline byte *getHunkPalette() {
|
||||
if (getHunkPaletteOffset() == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
return _data + getHunkPaletteOffset();
|
||||
}
|
||||
};
|
||||
|
||||
struct BitmapTable : public SegmentObjTable<SciBitmap> {
|
||||
BitmapTable() : SegmentObjTable<SciBitmap>(SEG_TYPE_BITMAP) {}
|
||||
|
||||
virtual void freeAtAddress(SegManager *segMan, reg_t sub_addr) {
|
||||
at(sub_addr.getOffset()).destroy();
|
||||
freeEntry(sub_addr.getOffset());
|
||||
}
|
||||
|
||||
void saveLoadWithSerializer(Common::Serializer &ser);
|
||||
SegmentRef dereference(reg_t pointer);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -1088,7 +1088,7 @@ CelObjMem::CelObjMem(const reg_t bitmapObject) {
|
||||
_celHeaderOffset = 0;
|
||||
_transparent = true;
|
||||
|
||||
BitmapResource bitmap(bitmapObject);
|
||||
SciBitmap &bitmap = *g_sci->getEngineState()->_segMan->lookupBitmap(bitmapObject);
|
||||
_width = bitmap.getWidth();
|
||||
_height = bitmap.getHeight();
|
||||
_displace = bitmap.getDisplace();
|
||||
@ -1104,7 +1104,7 @@ CelObjMem *CelObjMem::duplicate() const {
|
||||
}
|
||||
|
||||
byte *CelObjMem::getResPointer() const {
|
||||
return g_sci->getEngineState()->_segMan->getHunkPointer(_info.bitmap);
|
||||
return g_sci->getEngineState()->_segMan->lookupBitmap(_info.bitmap)->getRawData();
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
@ -309,7 +309,7 @@ reg_t GfxControls32::kernelEditText(const reg_t controlObject) {
|
||||
g_sci->_gfxFrameout->frameOut(true);
|
||||
}
|
||||
|
||||
_segMan->freeHunkEntry(editor.bitmap);
|
||||
_segMan->freeBitmap(editor.bitmap);
|
||||
|
||||
if (textChanged) {
|
||||
editor.text.trim();
|
||||
@ -419,7 +419,7 @@ ScrollWindow::ScrollWindow(SegManager *segMan, const Common::Rect &gameRect, con
|
||||
}
|
||||
|
||||
ScrollWindow::~ScrollWindow() {
|
||||
_segMan->freeHunkEntry(_bitmap);
|
||||
_segMan->freeBitmap(_bitmap);
|
||||
// _screenItem will be deleted by GfxFrameout
|
||||
}
|
||||
|
||||
|
@ -334,7 +334,7 @@ reg_t GfxPaint16::bitsSave(const Common::Rect &rect, byte screenMask) {
|
||||
// now actually ask _screen how much space it will need for saving
|
||||
size = _screen->bitsGetDataSize(workerRect, screenMask);
|
||||
|
||||
memoryId = _segMan->allocateHunkEntry("SaveBits()", size, true);
|
||||
memoryId = _segMan->allocateHunkEntry("SaveBits()", size);
|
||||
memoryPtr = _segMan->getHunkPointer(memoryId);
|
||||
if (memoryPtr)
|
||||
_screen->bitsSave(workerRect, screenMask, memoryPtr);
|
||||
|
@ -37,11 +37,12 @@ reg_t GfxPaint32::kernelAddLine(const reg_t planeObject, const Common::Point &st
|
||||
}
|
||||
|
||||
Common::Rect gameRect;
|
||||
BitmapResource bitmap = makeLineBitmap(startPoint, endPoint, priority, color, style, pattern, thickness, gameRect);
|
||||
reg_t bitmapId = makeLineBitmap(startPoint, endPoint, priority, color, style, pattern, thickness, gameRect);
|
||||
SciBitmap &bitmap = *_segMan->lookupBitmap(bitmapId);
|
||||
|
||||
CelInfo32 celInfo;
|
||||
celInfo.type = kCelTypeMem;
|
||||
celInfo.bitmap = bitmap.getObject();
|
||||
celInfo.bitmap = bitmapId;
|
||||
// SSCI stores the line color on `celInfo`, even though
|
||||
// this is not a `kCelTypeColor`, as a hack so that
|
||||
// `kUpdateLine` can get the originally used color
|
||||
@ -59,10 +60,10 @@ reg_t GfxPaint32::kernelAddLine(const reg_t planeObject, const Common::Point &st
|
||||
void GfxPaint32::kernelUpdateLine(ScreenItem *screenItem, Plane *plane, const Common::Point &startPoint, const Common::Point &endPoint, const int16 priority, const uint8 color, const LineStyle style, const uint16 pattern, const uint8 thickness) {
|
||||
|
||||
Common::Rect gameRect;
|
||||
BitmapResource bitmap = makeLineBitmap(startPoint, endPoint, priority, color, style, pattern, thickness, gameRect);
|
||||
reg_t bitmapId = makeLineBitmap(startPoint, endPoint, priority, color, style, pattern, thickness, gameRect);
|
||||
|
||||
_segMan->freeHunkEntry(screenItem->_celInfo.bitmap);
|
||||
screenItem->_celInfo.bitmap = bitmap.getObject();
|
||||
_segMan->freeBitmap(screenItem->_celInfo.bitmap);
|
||||
screenItem->_celInfo.bitmap = bitmapId;
|
||||
screenItem->_celInfo.color = color;
|
||||
screenItem->_position = startPoint;
|
||||
screenItem->_priority = priority;
|
||||
@ -80,7 +81,7 @@ void GfxPaint32::kernelDeleteLine(const reg_t screenItemObject, const reg_t plan
|
||||
return;
|
||||
}
|
||||
|
||||
_segMan->freeHunkEntry(screenItem->_celInfo.bitmap);
|
||||
_segMan->freeBitmap(screenItem->_celInfo.bitmap);
|
||||
g_sci->_gfxFrameout->deleteScreenItem(*screenItem, *plane);
|
||||
}
|
||||
|
||||
@ -116,7 +117,7 @@ void GfxPaint32::plotter(int x, int y, int color, void *data) {
|
||||
}
|
||||
}
|
||||
|
||||
BitmapResource GfxPaint32::makeLineBitmap(const Common::Point &startPoint, const Common::Point &endPoint, const int16 priority, const uint8 color, const LineStyle style, uint16 pattern, uint8 thickness, Common::Rect &outRect) {
|
||||
reg_t GfxPaint32::makeLineBitmap(const Common::Point &startPoint, const Common::Point &endPoint, const int16 priority, const uint8 color, const LineStyle style, uint16 pattern, uint8 thickness, Common::Rect &outRect) {
|
||||
const uint8 skipColor = color != kDefaultSkipColor ? kDefaultSkipColor : 0;
|
||||
|
||||
// Thickness is expected to be 2n+1
|
||||
@ -128,7 +129,8 @@ BitmapResource GfxPaint32::makeLineBitmap(const Common::Point &startPoint, const
|
||||
outRect.right = (startPoint.x > endPoint.x ? startPoint.x : endPoint.x) + halfThickness + 1;
|
||||
outRect.bottom = (startPoint.y > endPoint.y ? startPoint.y : endPoint.y) + halfThickness + 1;
|
||||
|
||||
BitmapResource bitmap(_segMan, outRect.width(), outRect.height(), skipColor, 0, 0, g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth, g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight, 0, false, true);
|
||||
reg_t bitmapId;
|
||||
SciBitmap &bitmap = *_segMan->allocateBitmap(&bitmapId, outRect.width(), outRect.height(), skipColor, 0, 0, g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth, g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight, 0, false, true);
|
||||
|
||||
byte *pixels = bitmap.getPixels();
|
||||
memset(pixels, skipColor, bitmap.getWidth() * bitmap.getHeight());
|
||||
@ -174,7 +176,7 @@ BitmapResource GfxPaint32::makeLineBitmap(const Common::Point &startPoint, const
|
||||
Graphics::drawThickLine2(drawRect.left, drawRect.top, drawRect.right, drawRect.bottom, thickness, color, plotter, &properties);
|
||||
}
|
||||
|
||||
return bitmap;
|
||||
return bitmapId;
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,8 +24,8 @@
|
||||
#define SCI_GRAPHICS_PAINT32_H
|
||||
|
||||
namespace Sci {
|
||||
class BitmapResource;
|
||||
class Plane;
|
||||
class SciBitmap;
|
||||
class ScreenItem;
|
||||
class SegManager;
|
||||
|
||||
@ -54,7 +54,7 @@ public:
|
||||
|
||||
private:
|
||||
typedef struct {
|
||||
BitmapResource *bitmap;
|
||||
SciBitmap *bitmap;
|
||||
bool pattern[16];
|
||||
uint8 patternIndex;
|
||||
bool solid;
|
||||
@ -64,7 +64,7 @@ private:
|
||||
|
||||
static void plotter(int x, int y, int color, void *data);
|
||||
|
||||
BitmapResource makeLineBitmap(const Common::Point &startPoint, const Common::Point &endPoint, const int16 priority, const uint8 color, const LineStyle style, const uint16 pattern, const uint8 thickness, Common::Rect &outRect);
|
||||
reg_t makeLineBitmap(const Common::Point &startPoint, const Common::Point &endPoint, const int16 priority, const uint8 color, const LineStyle style, const uint16 pattern, const uint8 thickness, Common::Rect &outRect);
|
||||
};
|
||||
|
||||
} // End of namespace Sci
|
||||
|
@ -626,7 +626,7 @@ void GfxPalette::kernelAnimateSet() {
|
||||
|
||||
reg_t GfxPalette::kernelSave() {
|
||||
SegManager *segMan = g_sci->getEngineState()->_segMan;
|
||||
reg_t memoryId = segMan->allocateHunkEntry("kPalette(save)", 1024, true);
|
||||
reg_t memoryId = segMan->allocateHunkEntry("kPalette(save)", 1024);
|
||||
byte *memoryPtr = segMan->getHunkPointer(memoryId);
|
||||
if (memoryPtr) {
|
||||
for (int colorNr = 0; colorNr < 256; colorNr++) {
|
||||
|
@ -96,8 +96,7 @@ reg_t GfxText32::createFontBitmap(int16 width, int16 height, const Common::Rect
|
||||
_textRect = Common::Rect();
|
||||
}
|
||||
|
||||
BitmapResource bitmap(_segMan, _width, _height, _skipColor, 0, 0, _scaledWidth, _scaledHeight, 0, false, gc);
|
||||
_bitmap = bitmap.getObject();
|
||||
_segMan->allocateBitmap(&_bitmap, _width, _height, _skipColor, 0, 0, _scaledWidth, _scaledHeight, 0, false, gc);
|
||||
|
||||
erase(bitmapRect, false);
|
||||
|
||||
@ -135,8 +134,7 @@ reg_t GfxText32::createFontBitmap(const CelInfo32 &celInfo, const Common::Rect &
|
||||
_textRect = Common::Rect();
|
||||
}
|
||||
|
||||
BitmapResource bitmap(_segMan, _width, _height, _skipColor, 0, 0, _scaledWidth, _scaledHeight, 0, false, gc);
|
||||
_bitmap = bitmap.getObject();
|
||||
SciBitmap &bitmap = *_segMan->allocateBitmap(&_bitmap, _width, _height, _skipColor, 0, 0, _scaledWidth, _scaledHeight, 0, false, gc);
|
||||
|
||||
// NOTE: The engine filled the bitmap pixels with 11 here, which is silly
|
||||
// because then it just erased the bitmap using the skip color. So we don't
|
||||
@ -180,8 +178,8 @@ void GfxText32::setFont(const GuiResourceId fontId) {
|
||||
void GfxText32::drawFrame(const Common::Rect &rect, const int16 size, const uint8 color, const bool doScaling) {
|
||||
Common::Rect targetRect = doScaling ? scaleRect(rect) : rect;
|
||||
|
||||
byte *bitmap = _segMan->getHunkPointer(_bitmap);
|
||||
byte *pixels = bitmap + READ_SCI11ENDIAN_UINT32(bitmap + 28) + rect.top * _width + rect.left;
|
||||
SciBitmap &bitmap = *_segMan->lookupBitmap(_bitmap);
|
||||
byte *pixels = bitmap.getPixels() + rect.top * _width + rect.left;
|
||||
|
||||
// NOTE: Not fully disassembled, but this should be right
|
||||
int16 rectWidth = targetRect.width();
|
||||
@ -210,8 +208,8 @@ void GfxText32::drawFrame(const Common::Rect &rect, const int16 size, const uint
|
||||
}
|
||||
|
||||
void GfxText32::drawChar(const char charIndex) {
|
||||
byte *bitmap = _segMan->getHunkPointer(_bitmap);
|
||||
byte *pixels = bitmap + READ_SCI11ENDIAN_UINT32(bitmap + 28);
|
||||
SciBitmap &bitmap = *_segMan->lookupBitmap(_bitmap);
|
||||
byte *pixels = bitmap.getPixels();
|
||||
|
||||
_font->drawToBuffer(charIndex, _drawPosition.y, _drawPosition.x, _foreColor, _dimmed, pixels, _width, _height);
|
||||
_drawPosition.x += _font->getCharWidth(charIndex);
|
||||
@ -328,14 +326,14 @@ void GfxText32::drawText(const uint index, uint length) {
|
||||
}
|
||||
}
|
||||
|
||||
void GfxText32::invertRect(const reg_t bitmap, int16 bitmapStride, const Common::Rect &rect, const uint8 foreColor, const uint8 backColor, const bool doScaling) {
|
||||
void GfxText32::invertRect(const reg_t bitmapId, int16 bitmapStride, const Common::Rect &rect, const uint8 foreColor, const uint8 backColor, const bool doScaling) {
|
||||
Common::Rect targetRect = rect;
|
||||
if (doScaling) {
|
||||
bitmapStride = bitmapStride * _scaledWidth / g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
|
||||
targetRect = scaleRect(rect);
|
||||
}
|
||||
|
||||
byte *bitmapData = _segMan->getHunkPointer(bitmap);
|
||||
SciBitmap &bitmap = *_segMan->lookupBitmap(bitmapId);
|
||||
|
||||
// NOTE: SCI code is super weird here; it seems to be trying to look at the
|
||||
// entire size of the bitmap including the header, instead of just the pixel
|
||||
@ -345,14 +343,14 @@ void GfxText32::invertRect(const reg_t bitmap, int16 bitmapStride, const Common:
|
||||
// function was never updated to match? Or maybe they exploit the
|
||||
// configurable stride length somewhere else to do stair stepping inverts...
|
||||
uint32 invertSize = targetRect.height() * bitmapStride + targetRect.width();
|
||||
uint32 bitmapSize = READ_SCI11ENDIAN_UINT32(bitmapData + 12);
|
||||
uint32 bitmapSize = bitmap.getDataSize();
|
||||
|
||||
if (invertSize >= bitmapSize) {
|
||||
error("InvertRect too big: %u >= %u", invertSize, bitmapSize);
|
||||
}
|
||||
|
||||
// NOTE: Actual engine just added the bitmap header size hardcoded here
|
||||
byte *pixel = bitmapData + READ_SCI11ENDIAN_UINT32(bitmapData + 28) + bitmapStride * targetRect.top + targetRect.left;
|
||||
byte *pixel = bitmap.getPixels() + bitmapStride * targetRect.top + targetRect.left;
|
||||
|
||||
int16 stride = bitmapStride - targetRect.width();
|
||||
int16 targetHeight = targetRect.height();
|
||||
@ -615,7 +613,7 @@ Common::Rect GfxText32::getTextSize(const Common::String &text, int16 maxWidth,
|
||||
void GfxText32::erase(const Common::Rect &rect, const bool doScaling) {
|
||||
Common::Rect targetRect = doScaling ? scaleRect(rect) : rect;
|
||||
|
||||
BitmapResource bitmap(_bitmap);
|
||||
SciBitmap &bitmap = *_segMan->lookupBitmap(_bitmap);
|
||||
bitmap.getBuffer().fillRect(targetRect, _backColor);
|
||||
}
|
||||
|
||||
@ -652,7 +650,7 @@ int16 GfxText32::getTextCount(const Common::String &text, const uint index, cons
|
||||
}
|
||||
|
||||
void GfxText32::scrollLine(const Common::String &lineText, int numLines, uint8 color, TextAlign align, GuiResourceId fontId, ScrollDirection dir) {
|
||||
BitmapResource bmr(_bitmap);
|
||||
SciBitmap &bmr = *_segMan->lookupBitmap(_bitmap);
|
||||
byte *pixels = bmr.getPixels();
|
||||
|
||||
int h = _font->getHeight();
|
||||
|
@ -42,210 +42,6 @@ enum ScrollDirection {
|
||||
kScrollDown
|
||||
};
|
||||
|
||||
enum BitmapFlags {
|
||||
kBitmapRemap = 2
|
||||
};
|
||||
|
||||
enum {
|
||||
kDefaultSkipColor = 250
|
||||
};
|
||||
|
||||
#define BITMAP_PROPERTY(size, property, offset)\
|
||||
inline uint##size get##property() const {\
|
||||
return READ_SCI11ENDIAN_UINT##size(_bitmap + (offset));\
|
||||
}\
|
||||
inline void set##property(uint##size value) {\
|
||||
WRITE_SCI11ENDIAN_UINT##size(_bitmap + (offset), (value));\
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience class for creating and modifying in-memory
|
||||
* bitmaps.
|
||||
*/
|
||||
class BitmapResource {
|
||||
byte *_bitmap;
|
||||
reg_t _object;
|
||||
Buffer _buffer;
|
||||
|
||||
/**
|
||||
* Gets the size of the bitmap header for the current
|
||||
* engine version.
|
||||
*/
|
||||
static inline uint16 getBitmapHeaderSize() {
|
||||
// TODO: These values are accurate for each engine, but there may be no reason
|
||||
// to not simply just always use size 40, since SCI2.1mid does not seem to
|
||||
// actually store any data above byte 40, and SCI2 did not allow bitmaps with
|
||||
// scaling resolutions other than the default (320x200). Perhaps SCI3 used
|
||||
// the extra bytes, or there is some reason why they tried to align the header
|
||||
// size with other headers like pic headers?
|
||||
// uint32 bitmapHeaderSize;
|
||||
// if (getSciVersion() >= SCI_VERSION_2_1_MIDDLE) {
|
||||
// bitmapHeaderSize = 46;
|
||||
// } else if (getSciVersion() == SCI_VERSION_2_1_EARLY) {
|
||||
// bitmapHeaderSize = 40;
|
||||
// } else {
|
||||
// bitmapHeaderSize = 36;
|
||||
// }
|
||||
// return bitmapHeaderSize;
|
||||
return 46;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the byte size of a bitmap with the given width
|
||||
* and height.
|
||||
*/
|
||||
static inline uint32 getBitmapSize(const uint16 width, const uint16 height) {
|
||||
return width * height + getBitmapHeaderSize();
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* Create a bitmap resource for an existing bitmap.
|
||||
* Ownership of the bitmap is retained by the caller.
|
||||
*/
|
||||
inline BitmapResource(reg_t bitmap) :
|
||||
_bitmap(g_sci->getEngineState()->_segMan->getHunkPointer(bitmap)),
|
||||
_object(bitmap) {
|
||||
if (_bitmap == nullptr || getUncompressedDataOffset() != getBitmapHeaderSize()) {
|
||||
error("Invalid Text bitmap %04x:%04x", PRINT_REG(bitmap));
|
||||
}
|
||||
|
||||
_buffer = Buffer(getWidth(), getHeight(), getPixels());
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates and initialises a new bitmap in the given
|
||||
* segment manager.
|
||||
*/
|
||||
inline BitmapResource(SegManager *segMan, const int16 width, const int16 height, const uint8 skipColor, const int16 displaceX, const int16 displaceY, const int16 scaledWidth, const int16 scaledHeight, const uint32 paletteSize, const bool remap, const bool gc) {
|
||||
_object = segMan->allocateHunkEntry("Bitmap()", getBitmapSize(width, height) + paletteSize, gc);
|
||||
_bitmap = segMan->getHunkPointer(_object);
|
||||
|
||||
const uint16 bitmapHeaderSize = getBitmapHeaderSize();
|
||||
|
||||
setWidth(width);
|
||||
setHeight(height);
|
||||
setDisplace(Common::Point(displaceX, displaceY));
|
||||
setSkipColor(skipColor);
|
||||
_bitmap[9] = 0;
|
||||
WRITE_SCI11ENDIAN_UINT16(_bitmap + 10, 0);
|
||||
setRemap(remap);
|
||||
setDataSize(width * height);
|
||||
WRITE_SCI11ENDIAN_UINT32(_bitmap + 16, 0);
|
||||
setHunkPaletteOffset(paletteSize > 0 ? (width * height) : 0);
|
||||
setDataOffset(bitmapHeaderSize);
|
||||
setUncompressedDataOffset(bitmapHeaderSize);
|
||||
setControlOffset(0);
|
||||
setScaledWidth(scaledWidth);
|
||||
setScaledHeight(scaledHeight);
|
||||
|
||||
_buffer = Buffer(getWidth(), getHeight(), getPixels());
|
||||
}
|
||||
|
||||
inline reg_t getObject() const {
|
||||
return _object;
|
||||
}
|
||||
|
||||
inline Buffer &getBuffer() {
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
BITMAP_PROPERTY(16, Width, 0);
|
||||
BITMAP_PROPERTY(16, Height, 2);
|
||||
|
||||
inline Common::Point getDisplace() const {
|
||||
return Common::Point(
|
||||
(int16)READ_SCI11ENDIAN_UINT16(_bitmap + 4),
|
||||
(int16)READ_SCI11ENDIAN_UINT16(_bitmap + 6)
|
||||
);
|
||||
}
|
||||
|
||||
inline void setDisplace(const Common::Point &displace) {
|
||||
WRITE_SCI11ENDIAN_UINT16(_bitmap + 4, (uint16)displace.x);
|
||||
WRITE_SCI11ENDIAN_UINT16(_bitmap + 6, (uint16)displace.y);
|
||||
}
|
||||
|
||||
inline uint8 getSkipColor() const {
|
||||
return _bitmap[8];
|
||||
}
|
||||
|
||||
inline void setSkipColor(const uint8 skipColor) {
|
||||
_bitmap[8] = skipColor;
|
||||
}
|
||||
|
||||
inline bool getRemap() const {
|
||||
return READ_SCI11ENDIAN_UINT16(_bitmap + 10) & kBitmapRemap;
|
||||
}
|
||||
|
||||
inline void setRemap(const bool remap) {
|
||||
uint16 flags = READ_SCI11ENDIAN_UINT16(_bitmap + 10);
|
||||
if (remap) {
|
||||
flags |= kBitmapRemap;
|
||||
} else {
|
||||
flags &= ~kBitmapRemap;
|
||||
}
|
||||
WRITE_SCI11ENDIAN_UINT16(_bitmap + 10, flags);
|
||||
}
|
||||
|
||||
BITMAP_PROPERTY(32, DataSize, 12);
|
||||
|
||||
inline uint32 getHunkPaletteOffset() const {
|
||||
return READ_SCI11ENDIAN_UINT32(_bitmap + 20);
|
||||
}
|
||||
|
||||
inline void setHunkPaletteOffset(uint32 hunkPaletteOffset) {
|
||||
if (hunkPaletteOffset) {
|
||||
hunkPaletteOffset += getBitmapHeaderSize();
|
||||
}
|
||||
|
||||
WRITE_SCI11ENDIAN_UINT32(_bitmap + 20, hunkPaletteOffset);
|
||||
}
|
||||
|
||||
BITMAP_PROPERTY(32, DataOffset, 24);
|
||||
|
||||
// NOTE: This property is used as a "magic number" for
|
||||
// validating that a block of memory is a valid bitmap,
|
||||
// and so is always set to the size of the header.
|
||||
BITMAP_PROPERTY(32, UncompressedDataOffset, 28);
|
||||
|
||||
// NOTE: This property always seems to be zero
|
||||
BITMAP_PROPERTY(32, ControlOffset, 32);
|
||||
|
||||
inline uint16 getScaledWidth() const {
|
||||
if (getDataOffset() >= 40) {
|
||||
return READ_SCI11ENDIAN_UINT16(_bitmap + 36);
|
||||
}
|
||||
|
||||
// SCI2 bitmaps did not have scaling ability
|
||||
return 320;
|
||||
}
|
||||
|
||||
inline void setScaledWidth(uint16 scaledWidth) {
|
||||
if (getDataOffset() >= 40) {
|
||||
WRITE_SCI11ENDIAN_UINT16(_bitmap + 36, scaledWidth);
|
||||
}
|
||||
}
|
||||
|
||||
inline uint16 getScaledHeight() const {
|
||||
if (getDataOffset() >= 40) {
|
||||
return READ_SCI11ENDIAN_UINT16(_bitmap + 38);
|
||||
}
|
||||
|
||||
// SCI2 bitmaps did not have scaling ability
|
||||
return 200;
|
||||
}
|
||||
|
||||
inline void setScaledHeight(uint16 scaledHeight) {
|
||||
if (getDataOffset() >= 40) {
|
||||
WRITE_SCI11ENDIAN_UINT16(_bitmap + 38, scaledHeight);
|
||||
}
|
||||
}
|
||||
|
||||
inline byte *getPixels() {
|
||||
return _bitmap + getUncompressedDataOffset();
|
||||
}
|
||||
};
|
||||
|
||||
class GfxFont;
|
||||
|
||||
/**
|
||||
|
@ -362,7 +362,7 @@ ShowStyleList::iterator GfxTransitions32::deleteShowStyle(const ShowStyleList::i
|
||||
case kShowStyleDissolveNoMorph:
|
||||
case kShowStyleDissolve:
|
||||
if (getSciVersion() <= SCI_VERSION_2_1_EARLY) {
|
||||
_segMan->freeHunkEntry(showStyle->bitmap);
|
||||
_segMan->freeBitmap(showStyle->bitmap);
|
||||
g_sci->_gfxFrameout->deleteScreenItem(*showStyle->bitmapScreenItem);
|
||||
}
|
||||
break;
|
||||
@ -459,9 +459,10 @@ void GfxTransitions32::configure21EarlyIris(PlaneShowStyle &showStyle, const int
|
||||
|
||||
void GfxTransitions32::configure21EarlyDissolve(PlaneShowStyle &showStyle, const int16 priority, const Common::Rect &gameRect) {
|
||||
|
||||
BitmapResource bitmap(_segMan, showStyle.width, showStyle.height, kDefaultSkipColor, 0, 0, kLowResX, kLowResY, 0, false, false);
|
||||
reg_t bitmapId;
|
||||
SciBitmap &bitmap = *_segMan->allocateBitmap(&bitmapId, showStyle.width, showStyle.height, kDefaultSkipColor, 0, 0, kLowResX, kLowResY, 0, false, false);
|
||||
|
||||
showStyle.bitmap = bitmap.getObject();
|
||||
showStyle.bitmap = bitmapId;
|
||||
|
||||
const Buffer &source = g_sci->_gfxFrameout->getCurrentBuffer();
|
||||
Buffer target(showStyle.width, showStyle.height, bitmap.getPixels());
|
||||
@ -471,7 +472,7 @@ void GfxTransitions32::configure21EarlyDissolve(PlaneShowStyle &showStyle, const
|
||||
|
||||
CelInfo32 celInfo;
|
||||
celInfo.type = kCelTypeMem;
|
||||
celInfo.bitmap = bitmap.getObject();
|
||||
celInfo.bitmap = bitmapId;
|
||||
|
||||
showStyle.bitmapScreenItem = new ScreenItem(showStyle.plane, celInfo, Common::Point(0, 0), ScaleInfo());
|
||||
showStyle.bitmapScreenItem->_priority = priority;
|
||||
@ -608,7 +609,7 @@ bool GfxTransitions32::processPixelDissolve(PlaneShowStyle &showStyle) {
|
||||
bool GfxTransitions32::processPixelDissolve21Early(PlaneShowStyle &showStyle) {
|
||||
bool unchanged = true;
|
||||
|
||||
BitmapResource bitmap(showStyle.bitmap);
|
||||
SciBitmap &bitmap = *_segMan->lookupBitmap(showStyle.bitmap);
|
||||
Buffer buffer(showStyle.width, showStyle.height, bitmap.getPixels());
|
||||
|
||||
uint32 numPixels = showStyle.width * showStyle.height;
|
||||
|
@ -117,7 +117,7 @@ VMDPlayer::IOStatus VMDPlayer::close() {
|
||||
|
||||
if (!_planeIsOwned && _screenItem != nullptr) {
|
||||
g_sci->_gfxFrameout->deleteScreenItem(*_screenItem);
|
||||
g_sci->getEngineState()->_segMan->freeHunkEntry(_screenItem->_celInfo.bitmap);
|
||||
g_sci->getEngineState()->_segMan->freeBitmap(_screenItem->_celInfo.bitmap);
|
||||
_screenItem = nullptr;
|
||||
} else if (_plane != nullptr) {
|
||||
g_sci->_gfxFrameout->deletePlane(*_plane);
|
||||
@ -232,14 +232,15 @@ VMDPlayer::EventFlags VMDPlayer::playUntilEvent(const EventFlags flags) {
|
||||
const int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth;
|
||||
const int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight;
|
||||
|
||||
BitmapResource vmdBitmap(_segMan, vmdRect.width(), vmdRect.height(), 255, 0, 0, screenWidth, screenHeight, 0, false, false);
|
||||
reg_t bitmapId;
|
||||
SciBitmap &vmdBitmap = *_segMan->allocateBitmap(&bitmapId, vmdRect.width(), vmdRect.height(), 255, 0, 0, screenWidth, screenHeight, 0, false, false);
|
||||
|
||||
if (screenWidth != scriptWidth || screenHeight != scriptHeight) {
|
||||
mulru(vmdRect, Ratio(scriptWidth, screenWidth), Ratio(scriptHeight, screenHeight), 1);
|
||||
}
|
||||
|
||||
CelInfo32 vmdCelInfo;
|
||||
vmdCelInfo.bitmap = vmdBitmap.getObject();
|
||||
vmdCelInfo.bitmap = bitmapId;
|
||||
_decoder->setSurfaceMemory(vmdBitmap.getPixels(), vmdBitmap.getWidth(), vmdBitmap.getHeight(), 1);
|
||||
|
||||
if (_planeIsOwned) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user