Import 0.4.7
This commit is contained in:
parent
2dc61ca627
commit
bc1337da63
|
@ -1,3 +1,7 @@
|
|||
* release 0.4.7
|
||||
- added detection for Macintosh CD version
|
||||
- restored some content from MEMO cutscene
|
||||
|
||||
* release 0.4.6
|
||||
- added rewind to automatic saves
|
||||
- fixed passwords and protection codes input
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
REminiscence README
|
||||
Release version: 0.4.6
|
||||
Release version: 0.4.7
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
|
|
@ -332,7 +332,7 @@ int Game::col_detectHitCallback4(LivePGE *pge1, LivePGE *pge2, int16_t unk1, int
|
|||
if (pge1->init_PGE->object_type == unk2) {
|
||||
if ((pge1->flags & 1) != (pge2->flags & 1)) {
|
||||
if (col_detectHitCallbackHelper(pge1, unk1) == 0) {
|
||||
pge_updateGroup(pge2->index, pge1->index, unk1);
|
||||
pge_sendMessage(pge2->index, pge1->index, unk1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -346,7 +346,7 @@ int Game::col_detectHitCallback5(LivePGE *pge1, LivePGE *pge2, int16_t unk1, int
|
|||
if (pge1->init_PGE->object_type == unk2) {
|
||||
if ((pge1->flags & 1) == (pge2->flags & 1)) {
|
||||
if (col_detectHitCallbackHelper(pge1, unk1) == 0) {
|
||||
pge_updateGroup(pge2->index, pge1->index, unk1);
|
||||
pge_sendMessage(pge2->index, pge1->index, unk1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -355,33 +355,33 @@ int Game::col_detectHitCallback5(LivePGE *pge1, LivePGE *pge2, int16_t unk1, int
|
|||
return 0;
|
||||
}
|
||||
|
||||
int Game::col_detectHitCallbackHelper(LivePGE *pge, int16_t groupId) {
|
||||
int Game::col_detectHitCallbackHelper(LivePGE *pge, int16_t msgNum) {
|
||||
InitPGE *init_pge = pge->init_PGE;
|
||||
assert(init_pge->obj_node_number < _res._numObjectNodes);
|
||||
ObjectNode *on = _res._objectNodesMap[init_pge->obj_node_number];
|
||||
Object *obj = &on->objects[pge->first_obj_number];
|
||||
int i = pge->first_obj_number;
|
||||
while (pge->obj_type == obj->type && on->last_obj_number > i) {
|
||||
if (obj->opcode2 == 0x6B) { // pge_op_isInGroupSlice
|
||||
if (obj->opcode2 == 0x6B) { // pge_isToggleable
|
||||
if (obj->opcode_arg2 == 0) {
|
||||
if (groupId == 1 || groupId == 2) return 0xFFFF;
|
||||
if (msgNum == 1 || msgNum == 2) return 0xFFFF;
|
||||
}
|
||||
if (obj->opcode_arg2 == 1) {
|
||||
if (groupId == 3 || groupId == 4) return 0xFFFF;
|
||||
if (msgNum == 3 || msgNum == 4) return 0xFFFF;
|
||||
}
|
||||
} else if (obj->opcode2 == 0x22) { // pge_op_isInGroup
|
||||
if (obj->opcode_arg2 == groupId) return 0xFFFF;
|
||||
} else if (obj->opcode2 == 0x22) { // pge_hasPiegeSentMessage
|
||||
if (obj->opcode_arg2 == msgNum) return 0xFFFF;
|
||||
}
|
||||
|
||||
if (obj->opcode1 == 0x6B) { // pge_op_isInGroupSlice
|
||||
if (obj->opcode1 == 0x6B) { // pge_isToggleable
|
||||
if (obj->opcode_arg1 == 0) {
|
||||
if (groupId == 1 || groupId == 2) return 0xFFFF;
|
||||
if (msgNum == 1 || msgNum == 2) return 0xFFFF;
|
||||
}
|
||||
if (obj->opcode_arg1 == 1) {
|
||||
if (groupId == 3 || groupId == 4) return 0xFFFF;
|
||||
if (msgNum == 3 || msgNum == 4) return 0xFFFF;
|
||||
}
|
||||
} else if (obj->opcode1 == 0x22) { // pge_op_isInGroup
|
||||
if (obj->opcode_arg1 == groupId) return 0xFFFF;
|
||||
} else if (obj->opcode1 == 0x22) { // pge_hasPiegeSentMessage
|
||||
if (obj->opcode_arg1 == msgNum) return 0xFFFF;
|
||||
}
|
||||
++obj;
|
||||
++i;
|
||||
|
@ -415,7 +415,7 @@ int Game::col_detectGunHitCallback2(LivePGE *pge1, LivePGE *pge2, int16_t arg4,
|
|||
}
|
||||
}
|
||||
if (col_detectHitCallbackHelper(pge1, id) != 0) {
|
||||
pge_updateGroup(pge2->index, pge1->index, id);
|
||||
pge_sendMessage(pge2->index, pge1->index, id);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -439,10 +439,9 @@ int Game::col_detectGunHitCallback3(LivePGE *pge1, LivePGE *pge2, int16_t arg4,
|
|||
}
|
||||
}
|
||||
if (col_detectHitCallbackHelper(pge1, id) != 0) {
|
||||
pge_updateGroup(pge2->index, pge1->index, id);
|
||||
pge_sendMessage(pge2->index, pge1->index, id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
166
cutscene.cpp
166
cutscene.cpp
|
@ -71,11 +71,11 @@ void Cutscene::updatePalette() {
|
|||
}
|
||||
}
|
||||
|
||||
void Cutscene::setPalette() {
|
||||
void Cutscene::updateScreen() {
|
||||
sync();
|
||||
updatePalette();
|
||||
SWAP(_page0, _page1);
|
||||
_stub->copyRect(0, 0, _vid->_w, _vid->_h, _page0, _vid->_w);
|
||||
SWAP(_frontPage, _backPage);
|
||||
_stub->copyRect(0, 0, _vid->_w, _vid->_h, _frontPage, _vid->_w);
|
||||
_stub->updateScreen(0);
|
||||
}
|
||||
|
||||
|
@ -187,11 +187,11 @@ void Cutscene::drawText(int16_t x, int16_t y, const uint8_t *p, uint16_t color,
|
|||
}
|
||||
}
|
||||
|
||||
void Cutscene::swapLayers() {
|
||||
void Cutscene::clearBackPage() {
|
||||
if (_clearScreen == 0) {
|
||||
memcpy(_page1, _pageC, _vid->_layerSize);
|
||||
memcpy(_backPage, _auxPage, _vid->_layerSize);
|
||||
} else {
|
||||
memset(_page1, 0xC0, _vid->_layerSize);
|
||||
memset(_backPage, 0xC0, _vid->_layerSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,7 +230,7 @@ void Cutscene::drawCreditsText() {
|
|||
} else {
|
||||
_creditsTextCounter -= 10;
|
||||
}
|
||||
drawText((_creditsTextPosX - 1) * 8, _creditsTextPosY * 8, _textBuf, 0xEF, _page1, kTextJustifyLeft);
|
||||
drawText((_creditsTextPosX - 1) * 8, _creditsTextPosY * 8, _textBuf, 0xEF, _backPage, kTextJustifyLeft);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -274,8 +274,8 @@ void Cutscene::op_markCurPos() {
|
|||
_cmdPtrBak = _cmdPtr;
|
||||
drawCreditsText();
|
||||
_frameDelay = 5;
|
||||
setPalette();
|
||||
swapLayers();
|
||||
updateScreen();
|
||||
clearBackPage();
|
||||
_creditsSlowText = 0;
|
||||
}
|
||||
|
||||
|
@ -283,7 +283,7 @@ void Cutscene::op_refreshScreen() {
|
|||
debug(DBG_CUT, "Cutscene::op_refreshScreen()");
|
||||
_clearScreen = fetchNextCmdByte();
|
||||
if (_clearScreen != 0) {
|
||||
swapLayers();
|
||||
clearBackPage();
|
||||
_creditsSlowText = 0;
|
||||
}
|
||||
}
|
||||
|
@ -298,11 +298,11 @@ void Cutscene::op_waitForSync() {
|
|||
if (_textBuf == _textCurBuf) {
|
||||
_creditsTextCounter = _res->isAmiga() ? 60 : 20;
|
||||
}
|
||||
memcpy(_page1, _page0, _vid->_layerSize);
|
||||
memcpy(_backPage, _frontPage, _vid->_layerSize);
|
||||
drawCreditsText();
|
||||
setPalette();
|
||||
updateScreen();
|
||||
} while (--n);
|
||||
swapLayers();
|
||||
clearBackPage();
|
||||
_creditsSlowText = 0;
|
||||
} else {
|
||||
_frameDelay = fetchNextCmdByte() * 4;
|
||||
|
@ -312,7 +312,7 @@ void Cutscene::op_waitForSync() {
|
|||
|
||||
void Cutscene::drawShape(const uint8_t *data, int16_t x, int16_t y) {
|
||||
debug(DBG_CUT, "Cutscene::drawShape()");
|
||||
_gfx.setLayer(_page1, _vid->_w);
|
||||
_gfx.setLayer(_backPage, _vid->_w);
|
||||
uint8_t numVertices = *data++;
|
||||
if (numVertices & 0x80) {
|
||||
Point pt;
|
||||
|
@ -393,10 +393,12 @@ void Cutscene::op_drawShape() {
|
|||
drawShape(primitiveVertices, x + dx, y + dy);
|
||||
}
|
||||
if (_clearScreen != 0) {
|
||||
memcpy(_pageC, _page1, _vid->_layerSize);
|
||||
memcpy(_auxPage, _backPage, _vid->_layerSize);
|
||||
}
|
||||
}
|
||||
|
||||
static int _paletteNum = -1;
|
||||
|
||||
void Cutscene::op_setPalette() {
|
||||
debug(DBG_CUT, "Cutscene::op_setPalette()");
|
||||
uint8_t num = fetchNextCmdByte();
|
||||
|
@ -408,6 +410,7 @@ void Cutscene::op_setPalette() {
|
|||
_palBuf[0x20] = 0x0F;
|
||||
_palBuf[0x21] = 0xFF;
|
||||
}
|
||||
_paletteNum = num;
|
||||
}
|
||||
|
||||
void Cutscene::op_drawCaptionText() {
|
||||
|
@ -419,7 +422,7 @@ void Cutscene::op_drawCaptionText() {
|
|||
if (_id == 0x39 && strId == 0xFFFF) {
|
||||
if ((_res->isDOS() && (_cmdPtr - _cmdPtrBak) == 0x10) || (_res->isAmiga() && (_cmdPtr - getCommandData()) == 0x9F3)) {
|
||||
_frameDelay = 100;
|
||||
setPalette();
|
||||
updateScreen();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -427,14 +430,14 @@ void Cutscene::op_drawCaptionText() {
|
|||
const int h = 45 * _vid->_layerScale;
|
||||
const int y = Video::GAMESCREEN_H * _vid->_layerScale - h;
|
||||
|
||||
memset(_pageC + y * _vid->_w, 0xC0, h * _vid->_w);
|
||||
memset(_page1 + y * _vid->_w, 0xC0, h * _vid->_w);
|
||||
memset(_page0 + y * _vid->_w, 0xC0, h * _vid->_w);
|
||||
memset(_auxPage + y * _vid->_w, 0xC0, h * _vid->_w);
|
||||
memset(_backPage + y * _vid->_w, 0xC0, h * _vid->_w);
|
||||
memset(_frontPage + y * _vid->_w, 0xC0, h * _vid->_w);
|
||||
if (strId != 0xFFFF) {
|
||||
const uint8_t *str = _res->getCineString(strId);
|
||||
if (str) {
|
||||
drawText(0, 129, str, 0xEF, _page1, kTextJustifyAlign);
|
||||
drawText(0, 129, str, 0xEF, _pageC, kTextJustifyAlign);
|
||||
drawText(0, 129, str, 0xEF, _backPage, kTextJustifyAlign);
|
||||
drawText(0, 129, str, 0xEF, _auxPage, kTextJustifyAlign);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -452,15 +455,15 @@ void Cutscene::op_skip3() {
|
|||
void Cutscene::op_refreshAll() {
|
||||
debug(DBG_CUT, "Cutscene::op_refreshAll()");
|
||||
_frameDelay = 5;
|
||||
setPalette();
|
||||
swapLayers();
|
||||
updateScreen();
|
||||
clearBackPage();
|
||||
_creditsSlowText = 0xFF;
|
||||
op_handleKeys();
|
||||
}
|
||||
|
||||
void Cutscene::drawShapeScale(const uint8_t *data, int16_t zoom, int16_t b, int16_t c, int16_t d, int16_t e, int16_t f, int16_t g) {
|
||||
debug(DBG_CUT, "Cutscene::drawShapeScale(%d, %d, %d, %d, %d, %d, %d)", zoom, b, c, d, e, f, g);
|
||||
_gfx.setLayer(_page1, _vid->_w);
|
||||
_gfx.setLayer(_backPage, _vid->_w);
|
||||
uint8_t numVertices = *data++;
|
||||
if (numVertices & 0x80) {
|
||||
int16_t x, y;
|
||||
|
@ -631,7 +634,7 @@ void Cutscene::op_drawShapeScale() {
|
|||
_hasAlphaColor = (verticesOffset & 0x4000) != 0;
|
||||
uint8_t color = *shapeData++;
|
||||
if (_clearScreen == 0) {
|
||||
color += 0x10; // 2nd pal buf
|
||||
color += 0x10; // 2nd paletter buffer
|
||||
}
|
||||
_primitiveColor = 0xC0 + color;
|
||||
drawShapeScale(p, zoom, dx, dy, x, y, 0, 0);
|
||||
|
@ -642,7 +645,7 @@ void Cutscene::op_drawShapeScale() {
|
|||
|
||||
void Cutscene::drawShapeScaleRotate(const uint8_t *data, int16_t zoom, int16_t b, int16_t c, int16_t d, int16_t e, int16_t f, int16_t g) {
|
||||
debug(DBG_CUT, "Cutscene::drawShapeScaleRotate(%d, %d, %d, %d, %d, %d, %d)", zoom, b, c, d, e, f, g);
|
||||
_gfx.setLayer(_page1, _vid->_w);
|
||||
_gfx.setLayer(_backPage, _vid->_w);
|
||||
uint8_t numVertices = *data++;
|
||||
if (numVertices & 0x80) {
|
||||
int16_t x, y, ix, iy;
|
||||
|
@ -724,7 +727,7 @@ void Cutscene::drawShapeScaleRotate(const uint8_t *data, int16_t zoom, int16_t b
|
|||
_gfx.drawPoint(_primitiveColor, &pt);
|
||||
} else {
|
||||
int16_t x, y, a, shape_last_x, shape_last_y;
|
||||
Point tempVertices[40];
|
||||
Point tempVertices[MAX_VERTICES];
|
||||
_shape_cur_x = b + READ_BE_UINT16(data); data += 2;
|
||||
x = _shape_cur_x;
|
||||
_shape_cur_y = c + READ_BE_UINT16(data); data += 2;
|
||||
|
@ -856,7 +859,7 @@ void Cutscene::op_drawShapeScaleRotate() {
|
|||
_hasAlphaColor = (verticesOffset & 0x4000) != 0;
|
||||
uint8_t color = *shapeData++;
|
||||
if (_clearScreen == 0) {
|
||||
color += 0x10; // 2nd pal buf
|
||||
color += 0x10; // 2nd palette buffer
|
||||
}
|
||||
_primitiveColor = 0xC0 + color;
|
||||
drawShapeScaleRotate(p, zoom, dx, dy, x, y, 0, 0);
|
||||
|
@ -864,19 +867,86 @@ void Cutscene::op_drawShapeScaleRotate() {
|
|||
}
|
||||
}
|
||||
|
||||
void Cutscene::op_drawCreditsText() {
|
||||
debug(DBG_CUT, "Cutscene::op_drawCreditsText()");
|
||||
static const uint16_t memoSetPos[] = {
|
||||
2, 0xffca, 0x0010, 2, 0xffcb, 0x000f, 2, 0xffcd, 0x000e, 2, 0xffd0, 0x000d, 2, 0xffd3, 0x000c, 2, 0xffd7, 0x000b,
|
||||
2, 0xffd9, 0x000a, 2, 0xffdb, 0x0009, 2, 0xffdd, 0x0008, 2, 0xffdd, 0x0008, 2, 0xffdd, 0x0008, 2, 0xffdd, 0x0008,
|
||||
2, 0xffdd, 0x0008, 2, 0xffdd, 0x0008, 2, 0xffdd, 0x0008, 2, 0xffdd, 0x0008, 4, 0xffe2, 0xfffe, 2, 0xffdd, 0x0008,
|
||||
4, 0xffe2, 0xfffe, 2, 0xffdd, 0x0008, 4, 0xffe2, 0xfffe, 2, 0xffdd, 0x0008, 4, 0xffe2, 0xfffe, 2, 0xffdd, 0x0008,
|
||||
2, 0xffdd, 0x0008, 2, 0xffdd, 0x0008, 2, 0xffdd, 0x0008, 2, 0xffdd, 0x0008, 2, 0xffdd, 0x0008, 2, 0xffdd, 0x0008,
|
||||
2, 0xffdc, 0x0008, 2, 0xffda, 0x0008, 2, 0xffd6, 0x0009, 2, 0xffd2, 0x000b, 2, 0xffce, 0x000e, 2, 0xffc9, 0x0010,
|
||||
2, 0xffc7, 0x0012, 2, 0xffc8, 0x0013, 2, 0xffca, 0x0015, 2, 0xffce, 0x0014, 2, 0xffd1, 0x0013, 2, 0xffd4, 0x0012,
|
||||
2, 0xffd6, 0x0011, 2, 0xffd8, 0x0011, 2, 0xffd8, 0x0011, 2, 0xffd8, 0x0011, 2, 0xffd8, 0x0011, 2, 0xffd8, 0x0011,
|
||||
2, 0xffd8, 0x0011, 2, 0xffd8, 0x0011, 4, 0xffdc, 0x0009, 2, 0xffd8, 0x0011, 4, 0xffdc, 0x0009, 2, 0xffd8, 0x0011,
|
||||
4, 0xffdc, 0x0009, 2, 0xffd8, 0x0011, 2, 0xffd8, 0x0011, 2, 0xffd8, 0x0011, 2, 0xffd8, 0x0011, 2, 0xffd8, 0x0011,
|
||||
2, 0xffd8, 0x0011, 2, 0xffd7, 0x0011, 2, 0xffd6, 0x0011, 2, 0xffd3, 0x0011, 2, 0xffcd, 0x0012, 2, 0xffc7, 0x0014,
|
||||
2, 0xffc1, 0x0016
|
||||
};
|
||||
|
||||
static bool _drawMemoSetShapes;
|
||||
static uint32_t _memoSetOffset;
|
||||
|
||||
static void readSetPalette(const uint8_t *p, uint16_t offset, uint16_t *palette);
|
||||
|
||||
static int findSetPaletteColor(const uint16_t color, const uint16_t *paletteBuffer) {
|
||||
int index = -1;
|
||||
int currentSum = 0;
|
||||
for (int l = 0; l < 32; ++l) {
|
||||
if (color == paletteBuffer[l]) {
|
||||
return l;
|
||||
}
|
||||
const int dr = ((color >> 8) & 15) - ((paletteBuffer[l] >> 8) & 15);
|
||||
const int dg = ((color >> 4) & 15) - ((paletteBuffer[l] >> 4) & 15);
|
||||
const int db = (color & 15) - (paletteBuffer[l] & 15);
|
||||
const int sum = dr * dr + dg * dg + db * db;
|
||||
if (index < 0 || sum < currentSum) {
|
||||
currentSum = sum;
|
||||
index = l;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
void Cutscene::op_copyScreen() {
|
||||
debug(DBG_CUT, "Cutscene::op_copyScreen()");
|
||||
_creditsSlowText = 0xFF;
|
||||
if (_textCurBuf == _textBuf) {
|
||||
++_creditsTextCounter;
|
||||
}
|
||||
memcpy(_page1, _page0, _vid->_layerSize);
|
||||
memcpy(_backPage, _frontPage, _vid->_layerSize);
|
||||
_frameDelay = 10;
|
||||
setPalette();
|
||||
|
||||
const bool drawMemoShapes = _drawMemoSetShapes && (_paletteNum == 19 || _paletteNum == 23) && (_memoSetOffset + 3) <= sizeof(memoSetPos);
|
||||
if (drawMemoShapes) {
|
||||
uint16_t paletteBuffer[32];
|
||||
for (int i = 0; i < 32; ++i) {
|
||||
paletteBuffer[i] = READ_BE_UINT16(_palBuf + i * 2);
|
||||
}
|
||||
uint16_t tempPalette[16];
|
||||
readSetPalette(_memoSetShape2Data, 0x462, tempPalette);
|
||||
uint8_t paletteLut[32];
|
||||
for (int k = 0; k < 16; ++k) {
|
||||
const int index = findSetPaletteColor(tempPalette[k], paletteBuffer);
|
||||
paletteLut[k] = 0xC0 + index;
|
||||
}
|
||||
|
||||
_gfx.setLayer(_backPage, _vid->_w);
|
||||
drawSetShape(_memoSetShape2Data, 0, (int16_t)memoSetPos[_memoSetOffset + 1], (int16_t)memoSetPos[_memoSetOffset + 2], paletteLut);
|
||||
_memoSetOffset += 3;
|
||||
if (memoSetPos[_memoSetOffset] == 4) {
|
||||
drawSetShape(_memoSetShape4Data, 0, (int16_t)memoSetPos[_memoSetOffset + 1], (int16_t)memoSetPos[_memoSetOffset + 2], paletteLut);
|
||||
_memoSetOffset += 3;
|
||||
}
|
||||
}
|
||||
|
||||
updateScreen();
|
||||
|
||||
if (drawMemoShapes) {
|
||||
SWAP(_frontPage, _backPage);
|
||||
}
|
||||
}
|
||||
|
||||
void Cutscene::op_drawStringAtPos() {
|
||||
debug(DBG_CUT, "Cutscene::op_drawStringAtPos()");
|
||||
void Cutscene::op_drawTextAtPos() {
|
||||
debug(DBG_CUT, "Cutscene::op_drawTextAtPos()");
|
||||
uint16_t strId = fetchNextCmdWord();
|
||||
if (strId != 0xFFFF) {
|
||||
int16_t x = (int8_t)fetchNextCmdByte() * 8;
|
||||
|
@ -885,12 +955,12 @@ void Cutscene::op_drawStringAtPos() {
|
|||
const uint8_t *str = _res->getCineString(strId & 0xFFF);
|
||||
if (str) {
|
||||
uint8_t color = 0xD0 + (strId >> 0xC);
|
||||
drawText(x, y, str, color, _page1, kTextJustifyCenter);
|
||||
drawText(x, y, str, color, _backPage, kTextJustifyCenter);
|
||||
}
|
||||
// 'voyage' - cutscene script redraws the string to refresh the screen
|
||||
if (_id == 0x34 && (strId & 0xFFF) == 0x45) {
|
||||
if ((_cmdPtr - _cmdPtrBak) == 0xA) {
|
||||
_stub->copyRect(0, 0, _vid->_w, _vid->_h, _page1, _vid->_w);
|
||||
_stub->copyRect(0, 0, _vid->_w, _vid->_h, _backPage, _vid->_w);
|
||||
_stub->updateScreen(0);
|
||||
} else {
|
||||
_stub->sleep(15);
|
||||
|
@ -995,6 +1065,10 @@ void Cutscene::mainLoop(uint16_t num) {
|
|||
_polPtr = getPolygonData();
|
||||
debug(DBG_CUT, "_baseOffset = %d offset = %d", _baseOffset, offset);
|
||||
|
||||
_paletteNum = -1;
|
||||
_drawMemoSetShapes = (_id == kCineMemo && g_options.restore_memo_cutscene);
|
||||
_memoSetOffset = 0;
|
||||
|
||||
while (!_stub->_pi.quit && !_interrupted && !_stop) {
|
||||
uint8_t op = fetchNextCmdByte();
|
||||
debug(DBG_CUT, "Cutscene::play() opcode = 0x%X (%d)", op, (op >> 2));
|
||||
|
@ -1071,9 +1145,9 @@ void Cutscene::unload() {
|
|||
}
|
||||
|
||||
void Cutscene::prepare() {
|
||||
_page0 = _vid->_frontLayer;
|
||||
_page1 = _vid->_tempLayer;
|
||||
_pageC = _vid->_tempLayer2;
|
||||
_frontPage = _vid->_frontLayer;
|
||||
_backPage = _vid->_tempLayer;
|
||||
_auxPage = _vid->_tempLayer2;
|
||||
_stub->_pi.dirMask = 0;
|
||||
_stub->_pi.enter = false;
|
||||
_stub->_pi.space = false;
|
||||
|
@ -1138,9 +1212,9 @@ void Cutscene::playText(const char *str) {
|
|||
}
|
||||
}
|
||||
const int y = (128 - lines * 8) / 2;
|
||||
memset(_page1, 0xC0, _vid->_layerSize);
|
||||
drawText(0, y, (const uint8_t *)str, 0xC1, _page1, kTextJustifyAlign);
|
||||
_stub->copyRect(0, 0, _vid->_w, _vid->_h, _page1, _vid->_w);
|
||||
memset(_backPage, 0xC0, _vid->_layerSize);
|
||||
drawText(0, y, (const uint8_t *)str, 0xC1, _backPage, kTextJustifyAlign);
|
||||
_stub->copyRect(0, 0, _vid->_w, _vid->_h, _backPage, _vid->_w);
|
||||
_stub->updateScreen(0);
|
||||
|
||||
while (!_stub->_pi.quit) {
|
||||
|
@ -1236,7 +1310,7 @@ static void readSetPalette(const uint8_t *p, uint16_t offset, uint16_t *palette)
|
|||
}
|
||||
}
|
||||
|
||||
void Cutscene::drawSetShape(const uint8_t *p, uint16_t offset, int x, int y, uint8_t *paletteLut) {
|
||||
void Cutscene::drawSetShape(const uint8_t *p, uint16_t offset, int x, int y, const uint8_t *paletteLut) {
|
||||
const int count = READ_BE_UINT16(p + offset); offset += 2;
|
||||
for (int i = 0; i < count - 1; ++i) {
|
||||
offset += 5; // shape_marker
|
||||
|
@ -1303,14 +1377,14 @@ void Cutscene::playSet(const uint8_t *p, int offset) {
|
|||
}
|
||||
|
||||
prepare();
|
||||
_gfx.setLayer(_page1, _vid->_w);
|
||||
_gfx.setLayer(_backPage, _vid->_w);
|
||||
|
||||
offset = 10;
|
||||
const int frames = READ_BE_UINT16(p + offset); offset += 2;
|
||||
for (int i = 0; i < frames && !_stub->_pi.quit && !_interrupted; ++i) {
|
||||
const uint32_t timestamp = _stub->getTimeStamp();
|
||||
|
||||
memset(_page1, 0xC0, _vid->_layerSize);
|
||||
memset(_backPage, 0xC0, _vid->_layerSize);
|
||||
|
||||
const int shapeBg = READ_BE_UINT16(p + offset); offset += 2;
|
||||
const int count = READ_BE_UINT16(p + offset); offset += 2;
|
||||
|
@ -1357,7 +1431,7 @@ void Cutscene::playSet(const uint8_t *p, int offset) {
|
|||
_stub->setPaletteEntry(0xC0 + j, &c);
|
||||
}
|
||||
|
||||
_stub->copyRect(0, 0, _vid->_w, _vid->_h, _page1, _vid->_w);
|
||||
_stub->copyRect(0, 0, _vid->_w, _vid->_h, _backPage, _vid->_w);
|
||||
_stub->updateScreen(0);
|
||||
const int diff = 6 * TIMER_SLICE - (_stub->getTimeStamp() - timestamp);
|
||||
_stub->sleep((diff < 16) ? 16 : diff);
|
||||
|
|
21
cutscene.h
21
cutscene.h
|
@ -18,6 +18,7 @@ struct Cutscene {
|
|||
typedef void (Cutscene::*OpcodeStub)();
|
||||
|
||||
enum {
|
||||
MAX_VERTICES = 128,
|
||||
NUM_OPCODES = 15,
|
||||
TIMER_SLICE = 15
|
||||
};
|
||||
|
@ -28,6 +29,10 @@ struct Cutscene {
|
|||
kTextJustifyCenter = 2,
|
||||
};
|
||||
|
||||
enum {
|
||||
kCineMemo = 48
|
||||
};
|
||||
|
||||
struct SetShape {
|
||||
uint16_t offset;
|
||||
uint16_t size;
|
||||
|
@ -54,6 +59,8 @@ struct Cutscene {
|
|||
static const Text _frTextsTable[];
|
||||
static const Text _enTextsTable[];
|
||||
static const uint8_t _caillouSetData[];
|
||||
static const uint8_t _memoSetShape2Data[];
|
||||
static const uint8_t _memoSetShape4Data[];
|
||||
|
||||
Graphics _gfx;
|
||||
Resource *_res;
|
||||
|
@ -77,7 +84,7 @@ struct Cutscene {
|
|||
uint32_t _rotMat[4];
|
||||
uint8_t _primitiveColor;
|
||||
uint8_t _clearScreen;
|
||||
Point _vertices[0x80];
|
||||
Point _vertices[MAX_VERTICES];
|
||||
bool _hasAlphaColor;
|
||||
uint8_t _varKey;
|
||||
int16_t _shape_ix;
|
||||
|
@ -102,7 +109,7 @@ struct Cutscene {
|
|||
uint8_t _creditsTextPosX;
|
||||
uint8_t _creditsTextPosY;
|
||||
int16_t _creditsTextCounter;
|
||||
uint8_t *_page0, *_page1, *_pageC;
|
||||
uint8_t *_frontPage, *_backPage, *_auxPage;
|
||||
|
||||
Cutscene(Resource *res, SystemStub *stub, Video *vid);
|
||||
|
||||
|
@ -112,11 +119,11 @@ struct Cutscene {
|
|||
void sync();
|
||||
void copyPalette(const uint8_t *pal, uint16_t num);
|
||||
void updatePalette();
|
||||
void setPalette();
|
||||
void updateScreen();
|
||||
void setRotationTransform(uint16_t a, uint16_t b, uint16_t c);
|
||||
uint16_t findTextSeparators(const uint8_t *p, int len);
|
||||
void drawText(int16_t x, int16_t y, const uint8_t *p, uint16_t color, uint8_t *page, int textJustify);
|
||||
void swapLayers();
|
||||
void clearBackPage();
|
||||
void drawCreditsText();
|
||||
void drawProtectionShape(uint8_t shapeNum, int16_t zoom);
|
||||
void drawShape(const uint8_t *data, int16_t x, int16_t y);
|
||||
|
@ -134,8 +141,8 @@ struct Cutscene {
|
|||
void op_refreshAll();
|
||||
void op_drawShapeScale();
|
||||
void op_drawShapeScaleRotate();
|
||||
void op_drawCreditsText();
|
||||
void op_drawStringAtPos();
|
||||
void op_copyScreen();
|
||||
void op_drawTextAtPos();
|
||||
void op_handleKeys();
|
||||
|
||||
uint8_t fetchNextCmdByte();
|
||||
|
@ -148,7 +155,7 @@ struct Cutscene {
|
|||
void playText(const char *str);
|
||||
void play();
|
||||
|
||||
void drawSetShape(const uint8_t *p, uint16_t offset, int x, int y, uint8_t *paletteLut);
|
||||
void drawSetShape(const uint8_t *p, uint16_t offset, int x, int y, const uint8_t *paletteLut);
|
||||
void playSet(const uint8_t *p, int offset);
|
||||
};
|
||||
|
||||
|
|
11
game.cpp
11
game.cpp
|
@ -365,7 +365,7 @@ void Game::resetGameState() {
|
|||
_deathCutsceneCounter = 0;
|
||||
_saveStateCompleted = false;
|
||||
_loadMap = true;
|
||||
pge_resetGroups();
|
||||
pge_resetMessages();
|
||||
_blinkingConradCounter = 0;
|
||||
_pge_processOBJ = false;
|
||||
_pge_opTempVar1 = 0;
|
||||
|
@ -1699,9 +1699,6 @@ void Game::loadLevelData() {
|
|||
}
|
||||
|
||||
_cut._id = lvl->cutscene_id;
|
||||
if (_res._isDemo && _currentLevel == 5) { // PC demo does not include TELEPORT.*
|
||||
_cut._id = 0xFFFF;
|
||||
}
|
||||
|
||||
_curMonsterNum = 0xFFFF;
|
||||
_curMonsterFrame = 0;
|
||||
|
@ -1741,7 +1738,7 @@ void Game::loadLevelData() {
|
|||
_pge_liveTable1[pge->room_location] = pge;
|
||||
}
|
||||
}
|
||||
pge_resetGroups();
|
||||
pge_resetMessages();
|
||||
_validSaveState = false;
|
||||
|
||||
_mix.playMusic(Mixer::MUSIC_TRACK + lvl->track);
|
||||
|
@ -1811,8 +1808,10 @@ void Game::playSound(uint8_t num, uint8_t softVol) {
|
|||
} else if (num >= 68 && num <= 75) {
|
||||
// in-game music
|
||||
_mix.playMusic(num);
|
||||
} else if (num == 76) {
|
||||
// metro
|
||||
} else if (num == 77) {
|
||||
// triggered when Conrad reaches a platform
|
||||
// triggered when Conrad draw his gun
|
||||
} else {
|
||||
warning("Unknown sound num %d", num);
|
||||
}
|
||||
|
|
36
game.h
36
game.h
|
@ -145,9 +145,9 @@ struct Game {
|
|||
|
||||
// pieges
|
||||
bool _pge_playAnimSound;
|
||||
GroupPGE _pge_groups[256];
|
||||
GroupPGE *_pge_groupsTable[256];
|
||||
GroupPGE *_pge_nextFreeGroup;
|
||||
MessagePGE _pge_messages[256];
|
||||
MessagePGE *_pge_messagesTable[256]; // indexed by pge number
|
||||
MessagePGE *_pge_nextFreeMessage;
|
||||
LivePGE *_pge_liveTable2[256]; // active pieges list (index = pge number)
|
||||
LivePGE *_pge_liveTable1[256]; // pieges list by room (index = room)
|
||||
LivePGE _pgeLive[256];
|
||||
|
@ -160,12 +160,12 @@ struct Game {
|
|||
uint16_t _pge_compareVar1;
|
||||
uint16_t _pge_compareVar2;
|
||||
|
||||
void pge_resetGroups();
|
||||
void pge_removeFromGroup(uint8_t idx);
|
||||
int pge_isInGroup(LivePGE *pge_dst, uint16_t group_id, uint16_t counter);
|
||||
void pge_resetMessages();
|
||||
void pge_clearMessages(uint8_t pge_index);
|
||||
int pge_hasMessageData(LivePGE *pge, uint16_t msg_num, uint16_t counter) const;
|
||||
void pge_loadForCurrentLevel(uint16_t idx);
|
||||
void pge_process(LivePGE *pge);
|
||||
void pge_setupNextAnimFrame(LivePGE *pge, GroupPGE *le);
|
||||
void pge_setupNextAnimFrame(LivePGE *pge, MessagePGE *le);
|
||||
void pge_playAnimSound(LivePGE *pge, uint16_t arg2);
|
||||
void pge_setupAnim(LivePGE *pge);
|
||||
int pge_execute(LivePGE *live_pge, InitPGE *init_pge, const Object *obj);
|
||||
|
@ -208,11 +208,11 @@ struct Game {
|
|||
int pge_op_collides0o0u(ObjectOpcodeArgs *args);
|
||||
int pge_op_collides2o2u(ObjectOpcodeArgs *args);
|
||||
int pge_op_collides2u2o(ObjectOpcodeArgs *args);
|
||||
int pge_op_isInGroup(ObjectOpcodeArgs *args);
|
||||
int pge_op_updateGroup0(ObjectOpcodeArgs *args);
|
||||
int pge_op_updateGroup1(ObjectOpcodeArgs *args);
|
||||
int pge_op_updateGroup2(ObjectOpcodeArgs *args);
|
||||
int pge_op_updateGroup3(ObjectOpcodeArgs *args);
|
||||
int pge_hasPiegeSentMessage(ObjectOpcodeArgs *args);
|
||||
int pge_op_sendMessageData0(ObjectOpcodeArgs *args);
|
||||
int pge_op_sendMessageData1(ObjectOpcodeArgs *args);
|
||||
int pge_op_sendMessageData2(ObjectOpcodeArgs *args);
|
||||
int pge_op_sendMessageData3(ObjectOpcodeArgs *args);
|
||||
int pge_op_isPiegeDead(ObjectOpcodeArgs *args);
|
||||
int pge_op_collides1u2o(ObjectOpcodeArgs *args);
|
||||
int pge_op_collides1u1o(ObjectOpcodeArgs *args);
|
||||
|
@ -230,10 +230,10 @@ struct Game {
|
|||
int pge_op_isInpMod(ObjectOpcodeArgs *args);
|
||||
int pge_op_setCollisionState1(ObjectOpcodeArgs *args);
|
||||
int pge_op_setCollisionState0(ObjectOpcodeArgs *args);
|
||||
int pge_op_isInGroup1(ObjectOpcodeArgs *args);
|
||||
int pge_op_isInGroup2(ObjectOpcodeArgs *args);
|
||||
int pge_op_isInGroup3(ObjectOpcodeArgs *args);
|
||||
int pge_op_isInGroup4(ObjectOpcodeArgs *args);
|
||||
int pge_hasMessageData0(ObjectOpcodeArgs *args);
|
||||
int pge_hasMessageData1(ObjectOpcodeArgs *args);
|
||||
int pge_hasMessageData2(ObjectOpcodeArgs *args);
|
||||
int pge_hasMessageData3(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x3C(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x3D(ObjectOpcodeArgs *args);
|
||||
int pge_op_setPiegeCounter(ObjectOpcodeArgs *args);
|
||||
|
@ -280,7 +280,7 @@ struct Game {
|
|||
int pge_op_setCollisionState2(ObjectOpcodeArgs *args);
|
||||
int pge_op_saveState(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x6A(ObjectOpcodeArgs *args);
|
||||
int pge_op_isInGroupSlice(ObjectOpcodeArgs *args);
|
||||
int pge_isToggleable(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x6C(ObjectOpcodeArgs *args);
|
||||
int pge_op_isCollidingObject(ObjectOpcodeArgs *args);
|
||||
int pge_o_unk0x6E(ObjectOpcodeArgs *args);
|
||||
|
@ -319,7 +319,7 @@ struct Game {
|
|||
void pge_addToInventory(LivePGE *pge1, LivePGE *pge2, LivePGE *pge3);
|
||||
int pge_updateCollisionState(LivePGE *pge, int16_t pge_dy, uint8_t var8);
|
||||
int pge_ZOrder(LivePGE *pge, int16_t num, pge_ZOrderCallback compare, uint16_t unk);
|
||||
void pge_updateGroup(uint8_t idx, uint8_t unk1, int16_t unk2);
|
||||
void pge_sendMessage(uint8_t src_pge_index, uint8_t dst_pge_index, int16_t num);
|
||||
void pge_removeFromInventory(LivePGE *pge1, LivePGE *pge2, LivePGE *pge3);
|
||||
int pge_ZOrderByAnimY(LivePGE *pge1, LivePGE *pge2, uint8_t comp, uint8_t comp2);
|
||||
int pge_ZOrderByAnimYIfType(LivePGE *pge1, LivePGE *pge2, uint8_t comp, uint8_t comp2);
|
||||
|
|
13
intern.h
13
intern.h
|
@ -136,6 +136,7 @@ struct Options {
|
|||
bool play_serrure_cutscene;
|
||||
bool play_carte_cutscene;
|
||||
bool play_gamesaved_sound;
|
||||
bool restore_memo_cutscene;
|
||||
};
|
||||
|
||||
struct Color {
|
||||
|
@ -171,7 +172,7 @@ struct InitPGE {
|
|||
int16_t pos_y;
|
||||
uint16_t obj_node_number;
|
||||
uint16_t life;
|
||||
int16_t counter_values[4]; // messages
|
||||
int16_t counter_values[4]; // data
|
||||
uint8_t object_type;
|
||||
uint8_t init_room;
|
||||
uint8_t room_location;
|
||||
|
@ -181,7 +182,7 @@ struct InitPGE {
|
|||
uint8_t object_id;
|
||||
uint8_t skill;
|
||||
uint8_t mirror_x;
|
||||
uint8_t flags;
|
||||
uint8_t flags; // 1:xflip 4:active
|
||||
uint8_t unk1C; // collidable, collision_data_len
|
||||
uint16_t text_num;
|
||||
};
|
||||
|
@ -206,10 +207,10 @@ struct LivePGE {
|
|||
InitPGE *init_PGE;
|
||||
};
|
||||
|
||||
struct GroupPGE {
|
||||
GroupPGE *next_entry;
|
||||
uint16_t index;
|
||||
uint16_t group_id;
|
||||
struct MessagePGE {
|
||||
MessagePGE *next_entry;
|
||||
uint16_t index; // src_pge
|
||||
uint16_t msg_num;
|
||||
};
|
||||
|
||||
struct Object {
|
||||
|
|
2
main.cpp
2
main.cpp
|
@ -99,6 +99,7 @@ static void initOptions() {
|
|||
g_options.play_serrure_cutscene = false;
|
||||
g_options.play_carte_cutscene = false;
|
||||
g_options.play_gamesaved_sound = false;
|
||||
g_options.restore_memo_cutscene = true;
|
||||
// read configuration file
|
||||
struct {
|
||||
const char *name;
|
||||
|
@ -119,6 +120,7 @@ static void initOptions() {
|
|||
{ "play_serrure_cutscene", &g_options.play_serrure_cutscene },
|
||||
{ "play_carte_cutscene", &g_options.play_carte_cutscene },
|
||||
{ "play_gamesaved_sound", &g_options.play_gamesaved_sound },
|
||||
{ "restore_memo_cutscene", &g_options.restore_memo_cutscene },
|
||||
{ 0, 0 }
|
||||
};
|
||||
static const char *filename = "rs.cfg";
|
||||
|
|
|
@ -91,7 +91,7 @@ void Mixer::playMusic(int num) {
|
|||
debug(DBG_SND, "Mixer::playMusic(%d)", num);
|
||||
if (num > MUSIC_TRACK && num != _musicTrack) {
|
||||
if (_ogg.playTrack(num - MUSIC_TRACK)) {
|
||||
_musicType = MT_OGG;
|
||||
_backgroundMusicType = _musicType = MT_OGG;
|
||||
_musicTrack = num;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ struct ModPlayer_impl {
|
|||
if (data) {
|
||||
f->read(data, size);
|
||||
_mf = ModPlug_Load(data, size);
|
||||
free(data);
|
||||
}
|
||||
return _mf != 0;
|
||||
}
|
||||
|
|
200
piege.cpp
200
piege.cpp
|
@ -10,46 +10,47 @@
|
|||
#include "systemstub.h"
|
||||
#include "util.h"
|
||||
|
||||
void Game::pge_resetGroups() {
|
||||
memset(_pge_groupsTable, 0, sizeof(_pge_groupsTable));
|
||||
GroupPGE *le = &_pge_groups[0];
|
||||
_pge_nextFreeGroup = le;
|
||||
void Game::pge_resetMessages() {
|
||||
memset(_pge_messagesTable, 0, sizeof(_pge_messagesTable));
|
||||
MessagePGE *le = &_pge_messages[0];
|
||||
_pge_nextFreeMessage = le;
|
||||
int n = 0xFF;
|
||||
while (n--) {
|
||||
le->next_entry = le + 1;
|
||||
le->index = 0;
|
||||
le->group_id = 0;
|
||||
le->msg_num = 0;
|
||||
++le;
|
||||
}
|
||||
le->next_entry = 0;
|
||||
le->index = 0;
|
||||
le->group_id = 0;
|
||||
le->msg_num = 0;
|
||||
}
|
||||
|
||||
void Game::pge_removeFromGroup(uint8_t idx) {
|
||||
GroupPGE *le = _pge_groupsTable[idx];
|
||||
void Game::pge_clearMessages(uint8_t pge_index) {
|
||||
MessagePGE *le = _pge_messagesTable[pge_index];
|
||||
if (le) {
|
||||
_pge_groupsTable[idx] = 0;
|
||||
GroupPGE *next = _pge_nextFreeGroup;
|
||||
_pge_messagesTable[pge_index] = 0;
|
||||
MessagePGE *next = _pge_nextFreeMessage;
|
||||
while (le) {
|
||||
GroupPGE *cur = le->next_entry;
|
||||
MessagePGE *cur = le->next_entry;
|
||||
le->next_entry = next;
|
||||
le->index = 0;
|
||||
le->group_id = 0;
|
||||
le->msg_num = 0;
|
||||
next = le;
|
||||
le = cur;
|
||||
}
|
||||
_pge_nextFreeGroup = next;
|
||||
_pge_nextFreeMessage = next;
|
||||
}
|
||||
}
|
||||
|
||||
int Game::pge_isInGroup(LivePGE *pge_dst, uint16_t group_id, uint16_t counter) {
|
||||
int Game::pge_hasMessageData(LivePGE *pge, uint16_t msg_num, uint16_t counter) const {
|
||||
assert(counter >= 1 && counter <= 4);
|
||||
uint16_t c = pge_dst->init_PGE->counter_values[counter - 1];
|
||||
GroupPGE *le = _pge_groupsTable[pge_dst->index];
|
||||
uint16_t pge_src_index = pge->init_PGE->counter_values[counter - 1];
|
||||
const MessagePGE *le = _pge_messagesTable[pge->index];
|
||||
while (le) {
|
||||
if (le->group_id == group_id && le->index == c)
|
||||
if (le->msg_num == msg_num && le->index == pge_src_index) {
|
||||
return 1;
|
||||
}
|
||||
le = le->next_entry;
|
||||
}
|
||||
return 0;
|
||||
|
@ -117,7 +118,7 @@ void Game::pge_process(LivePGE *pge) {
|
|||
_pge_playAnimSound = true;
|
||||
_pge_currentPiegeFacingDir = (pge->flags & 1) != 0;
|
||||
_pge_currentPiegeRoom = pge->room_location;
|
||||
GroupPGE *le = _pge_groupsTable[pge->index];
|
||||
MessagePGE *le = _pge_messagesTable[pge->index];
|
||||
if (le) {
|
||||
pge_setupNextAnimFrame(pge, le);
|
||||
}
|
||||
|
@ -129,7 +130,7 @@ void Game::pge_process(LivePGE *pge) {
|
|||
Object *obj = &on->objects[pge->first_obj_number];
|
||||
while (1) {
|
||||
if (obj->type != pge->obj_type) {
|
||||
pge_removeFromGroup(pge->index);
|
||||
pge_clearMessages(pge->index);
|
||||
return;
|
||||
}
|
||||
uint16_t _ax = pge_execute(pge, init_pge, obj);
|
||||
|
@ -137,7 +138,7 @@ void Game::pge_process(LivePGE *pge) {
|
|||
if (_currentLevel == 6 && (_currentRoom == 50 || _currentRoom == 51)) {
|
||||
if (pge->index == 79 && _ax == 0xFFFF && obj->opcode1 == 0x60 && obj->opcode2 == 0 && obj->opcode3 == 0) {
|
||||
if (col_getGridPos(&_pgeLive[79], 0) == col_getGridPos(&_pgeLive[0], 0)) {
|
||||
pge_updateGroup(79, 0, 4);
|
||||
pge_sendMessage(79, 0, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -156,37 +157,37 @@ void Game::pge_process(LivePGE *pge) {
|
|||
}
|
||||
pge_setupAnim(pge);
|
||||
++pge->anim_seq;
|
||||
pge_removeFromGroup(pge->index);
|
||||
pge_clearMessages(pge->index);
|
||||
}
|
||||
|
||||
void Game::pge_setupNextAnimFrame(LivePGE *pge, GroupPGE *le) {
|
||||
void Game::pge_setupNextAnimFrame(LivePGE *pge, MessagePGE *le) {
|
||||
InitPGE *init_pge = pge->init_PGE;
|
||||
assert(init_pge->obj_node_number < _res._numObjectNodes);
|
||||
ObjectNode *on = _res._objectNodesMap[init_pge->obj_node_number];
|
||||
Object *obj = &on->objects[pge->first_obj_number];
|
||||
int i = pge->first_obj_number;
|
||||
while (i < on->last_obj_number && pge->obj_type == obj->type) {
|
||||
GroupPGE *next_le = le;
|
||||
MessagePGE *next_le = le;
|
||||
while (next_le) {
|
||||
uint16_t groupId = next_le->group_id;
|
||||
if (obj->opcode2 == 0x6B) { // pge_op_isInGroupSlice
|
||||
uint16_t msgNum = next_le->msg_num;
|
||||
if (obj->opcode2 == 0x6B) { // pge_isToggleable
|
||||
if (obj->opcode_arg2 == 0) {
|
||||
if (groupId == 1 || groupId == 2) goto set_anim;
|
||||
if (msgNum == 1 || msgNum == 2) goto set_anim;
|
||||
}
|
||||
if (obj->opcode_arg2 == 1) {
|
||||
if (groupId == 3 || groupId == 4) goto set_anim;
|
||||
if (msgNum == 3 || msgNum == 4) goto set_anim;
|
||||
}
|
||||
} else if (groupId == obj->opcode_arg2) {
|
||||
} else if (msgNum == obj->opcode_arg2) {
|
||||
if (obj->opcode2 == 0x22 || obj->opcode2 == 0x6F) goto set_anim;
|
||||
}
|
||||
if (obj->opcode1 == 0x6B) { // pge_op_isInGroupSlice
|
||||
if (obj->opcode1 == 0x6B) { // pge_isToggleable
|
||||
if (obj->opcode_arg1 == 0) {
|
||||
if (groupId == 1 || groupId == 2) goto set_anim;
|
||||
if (msgNum == 1 || msgNum == 2) goto set_anim;
|
||||
}
|
||||
if (obj->opcode_arg1 == 1) {
|
||||
if (groupId == 3 || groupId == 4) goto set_anim;
|
||||
if (msgNum == 3 || msgNum == 4) goto set_anim;
|
||||
}
|
||||
} else if (groupId == obj->opcode_arg1) {
|
||||
} else if (msgNum == obj->opcode_arg1) {
|
||||
if (obj->opcode1 == 0x22 || obj->opcode1 == 0x6F) goto set_anim;
|
||||
}
|
||||
next_le = next_le->next_entry;
|
||||
|
@ -796,10 +797,10 @@ int Game::pge_op_collides2u2o(ObjectOpcodeArgs *args) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int Game::pge_op_isInGroup(ObjectOpcodeArgs *args) {
|
||||
GroupPGE *le = _pge_groupsTable[args->pge->index];
|
||||
int Game::pge_hasPiegeSentMessage(ObjectOpcodeArgs *args) {
|
||||
MessagePGE *le = _pge_messagesTable[args->pge->index];
|
||||
while (le) {
|
||||
if (le->group_id == args->a) {
|
||||
if (le->msg_num == args->a) {
|
||||
return 0xFFFF;
|
||||
}
|
||||
le = le->next_entry;
|
||||
|
@ -807,27 +808,27 @@ int Game::pge_op_isInGroup(ObjectOpcodeArgs *args) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int Game::pge_op_updateGroup0(ObjectOpcodeArgs *args) {
|
||||
int Game::pge_op_sendMessageData0(ObjectOpcodeArgs *args) {
|
||||
LivePGE *pge = args->pge;
|
||||
pge_updateGroup(pge->index, pge->init_PGE->counter_values[0], args->a);
|
||||
pge_sendMessage(pge->index, pge->init_PGE->counter_values[0], args->a);
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
int Game::pge_op_updateGroup1(ObjectOpcodeArgs *args) {
|
||||
int Game::pge_op_sendMessageData1(ObjectOpcodeArgs *args) {
|
||||
LivePGE *pge = args->pge;
|
||||
pge_updateGroup(pge->index, pge->init_PGE->counter_values[1], args->a);
|
||||
pge_sendMessage(pge->index, pge->init_PGE->counter_values[1], args->a);
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
int Game::pge_op_updateGroup2(ObjectOpcodeArgs *args) {
|
||||
int Game::pge_op_sendMessageData2(ObjectOpcodeArgs *args) {
|
||||
LivePGE *pge = args->pge;
|
||||
pge_updateGroup(pge->index, pge->init_PGE->counter_values[2], args->a);
|
||||
pge_sendMessage(pge->index, pge->init_PGE->counter_values[2], args->a);
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
int Game::pge_op_updateGroup3(ObjectOpcodeArgs *args) {
|
||||
int Game::pge_op_sendMessageData3(ObjectOpcodeArgs *args) {
|
||||
LivePGE *pge = args->pge;
|
||||
pge_updateGroup(pge->index, pge->init_PGE->counter_values[3], args->a);
|
||||
pge_sendMessage(pge->index, pge->init_PGE->counter_values[3], args->a);
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
|
@ -888,7 +889,7 @@ int Game::pge_op_nop(ObjectOpcodeArgs *args) {
|
|||
int Game::pge_op_pickupObject(ObjectOpcodeArgs *args) {
|
||||
LivePGE *pge = col_findPiege(args->pge, 3);
|
||||
if (pge) {
|
||||
pge_updateGroup(args->pge->index, pge->index, args->a);
|
||||
pge_sendMessage(args->pge->index, pge->index, args->a);
|
||||
return 0xFFFF;
|
||||
}
|
||||
return 0;
|
||||
|
@ -908,7 +909,7 @@ int Game::pge_op_copyPiege(ObjectOpcodeArgs *args) {
|
|||
dst->pos_y = src->pos_y;
|
||||
dst->room_location = src->room_location;
|
||||
|
||||
dst->flags &= 0xFE;
|
||||
dst->flags &= ~1;
|
||||
if (src->flags & 1) {
|
||||
dst->flags |= 1;
|
||||
}
|
||||
|
@ -918,7 +919,7 @@ int Game::pge_op_copyPiege(ObjectOpcodeArgs *args) {
|
|||
|
||||
int Game::pge_op_removeItemFromInventory(ObjectOpcodeArgs *args) {
|
||||
if (args->pge->current_inventory_PGE != 0xFF) {
|
||||
pge_updateGroup(args->pge->index, args->pge->current_inventory_PGE, args->a);
|
||||
pge_sendMessage(args->pge->index, args->pge->current_inventory_PGE, args->a);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -960,20 +961,20 @@ int Game::pge_op_setCollisionState0(ObjectOpcodeArgs *args) {
|
|||
return pge_updateCollisionState(args->pge, args->a, 0);
|
||||
}
|
||||
|
||||
int Game::pge_op_isInGroup1(ObjectOpcodeArgs *args) {
|
||||
return pge_isInGroup(args->pge, args->a, 1);
|
||||
int Game::pge_hasMessageData0(ObjectOpcodeArgs *args) {
|
||||
return pge_hasMessageData(args->pge, args->a, 1);
|
||||
}
|
||||
|
||||
int Game::pge_op_isInGroup2(ObjectOpcodeArgs *args) {
|
||||
return pge_isInGroup(args->pge, args->a, 2);
|
||||
int Game::pge_hasMessageData1(ObjectOpcodeArgs *args) {
|
||||
return pge_hasMessageData(args->pge, args->a, 2);
|
||||
}
|
||||
|
||||
int Game::pge_op_isInGroup3(ObjectOpcodeArgs *args) {
|
||||
return pge_isInGroup(args->pge, args->a, 3);
|
||||
int Game::pge_hasMessageData2(ObjectOpcodeArgs *args) {
|
||||
return pge_hasMessageData(args->pge, args->a, 3);
|
||||
}
|
||||
|
||||
int Game::pge_op_isInGroup4(ObjectOpcodeArgs *args) {
|
||||
return pge_isInGroup(args->pge, args->a, 4);
|
||||
int Game::pge_hasMessageData3(ObjectOpcodeArgs *args) {
|
||||
return pge_hasMessageData(args->pge, args->a, 4);
|
||||
}
|
||||
|
||||
int Game::pge_o_unk0x3C(ObjectOpcodeArgs *args) {
|
||||
|
@ -1170,7 +1171,7 @@ int Game::pge_o_unk0x47(ObjectOpcodeArgs *args) {
|
|||
int Game::pge_o_unk0x48(ObjectOpcodeArgs *args) {
|
||||
LivePGE *pge = col_findPiege(&_pgeLive[0], args->pge->init_PGE->counter_values[0]);
|
||||
if (pge && pge->life == args->pge->life) {
|
||||
pge_updateGroup(args->pge->index, pge->index, args->a);
|
||||
pge_sendMessage(args->pge->index, pge->index, args->a);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -1364,9 +1365,9 @@ int Game::pge_o_unk0x5F(ObjectOpcodeArgs *args) {
|
|||
}
|
||||
|
||||
int Game::pge_op_findAndCopyPiege(ObjectOpcodeArgs *args) {
|
||||
GroupPGE *le = _pge_groupsTable[args->pge->index];
|
||||
MessagePGE *le = _pge_messagesTable[args->pge->index];
|
||||
while (le) {
|
||||
if (le->group_id == args->a) {
|
||||
if (le->msg_num == args->a) {
|
||||
args->a = le->index;
|
||||
args->b = 0;
|
||||
pge_op_copyPiege(args);
|
||||
|
@ -1429,7 +1430,7 @@ int Game::pge_op_setCollisionState2(ObjectOpcodeArgs *args) {
|
|||
int Game::pge_op_saveState(ObjectOpcodeArgs *args) {
|
||||
_saveStateCompleted = true;
|
||||
_validSaveState = saveGameState(kIngameSaveSlot);
|
||||
if (_validSaveState and g_options.play_gamesaved_sound) {
|
||||
if (_validSaveState && g_options.play_gamesaved_sound) {
|
||||
_mix.play(Resource::_gameSavedSoundData, Resource::_gameSavedSoundLen, 8000, Mixer::MAX_VOLUME);
|
||||
}
|
||||
return 0xFFFF;
|
||||
|
@ -1544,20 +1545,20 @@ loc_0_15446:
|
|||
return 0;
|
||||
}
|
||||
|
||||
int Game::pge_op_isInGroupSlice(ObjectOpcodeArgs *args) {
|
||||
int Game::pge_isToggleable(ObjectOpcodeArgs *args) {
|
||||
LivePGE *pge = args->pge;
|
||||
GroupPGE *le = _pge_groupsTable[pge->index];
|
||||
MessagePGE *le = _pge_messagesTable[pge->index];
|
||||
if (le) {
|
||||
if (args->a == 0) {
|
||||
do {
|
||||
if (le->group_id == 1 || le->group_id == 2) {
|
||||
if (le->msg_num == 1 || le->msg_num == 2) {
|
||||
return 1;
|
||||
}
|
||||
le = le->next_entry;
|
||||
} while (le);
|
||||
} else {
|
||||
do {
|
||||
if (le->group_id == 3 || le->group_id == 4) {
|
||||
if (le->msg_num == 3 || le->msg_num == 4) {
|
||||
return 1;
|
||||
}
|
||||
le = le->next_entry;
|
||||
|
@ -1571,7 +1572,7 @@ int Game::pge_o_unk0x6C(ObjectOpcodeArgs *args) {
|
|||
LivePGE *pge = col_findPiege(&_pgeLive[0], args->pge->init_PGE->counter_values[0]);
|
||||
if (pge) {
|
||||
if (pge->life <= args->pge->life) {
|
||||
pge_updateGroup(args->pge->index, pge->index, args->a);
|
||||
pge_sendMessage(args->pge->index, pge->index, args->a);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -1589,9 +1590,9 @@ int Game::pge_op_isCollidingObject(ObjectOpcodeArgs *args) {
|
|||
|
||||
// elevator
|
||||
int Game::pge_o_unk0x6E(ObjectOpcodeArgs *args) {
|
||||
GroupPGE *le = _pge_groupsTable[args->pge->index];
|
||||
MessagePGE *le = _pge_messagesTable[args->pge->index];
|
||||
while (le) {
|
||||
if (args->a == le->group_id) {
|
||||
if (args->a == le->msg_num) {
|
||||
pge_updateInventory(&_pgeLive[le->index], args->pge);
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
@ -1603,10 +1604,10 @@ int Game::pge_o_unk0x6E(ObjectOpcodeArgs *args) {
|
|||
|
||||
int Game::pge_o_unk0x6F(ObjectOpcodeArgs *args) {
|
||||
LivePGE *pge = args->pge;
|
||||
GroupPGE *le = _pge_groupsTable[pge->index];
|
||||
MessagePGE *le = _pge_messagesTable[pge->index];
|
||||
while (le) {
|
||||
if (args->a == le->group_id) {
|
||||
pge_updateGroup(pge->index, le->index, 0xC);
|
||||
if (args->a == le->msg_num) {
|
||||
pge_sendMessage(pge->index, le->index, 0xC);
|
||||
return 1;
|
||||
}
|
||||
le = le->next_entry;
|
||||
|
@ -1617,7 +1618,7 @@ int Game::pge_o_unk0x6F(ObjectOpcodeArgs *args) {
|
|||
int Game::pge_o_unk0x70(ObjectOpcodeArgs *args) {
|
||||
uint8_t pge_num = args->pge->current_inventory_PGE;
|
||||
while (pge_num != 0xFF) {
|
||||
pge_updateGroup(args->pge->index, _pgeLive[pge_num].index, args->a);
|
||||
pge_sendMessage(args->pge->index, _pgeLive[pge_num].index, args->a);
|
||||
pge_num = _pgeLive[pge_num].next_inventory_PGE;
|
||||
}
|
||||
return 1;
|
||||
|
@ -1626,9 +1627,9 @@ int Game::pge_o_unk0x70(ObjectOpcodeArgs *args) {
|
|||
// elevator
|
||||
int Game::pge_o_unk0x71(ObjectOpcodeArgs *args) {
|
||||
LivePGE *pge = args->pge;
|
||||
GroupPGE *le = _pge_groupsTable[pge->index];
|
||||
MessagePGE *le = _pge_messagesTable[pge->index];
|
||||
while (le) {
|
||||
if (le->group_id == args->a) {
|
||||
if (le->msg_num == args->a) {
|
||||
pge_reorderInventory(args->pge);
|
||||
return 1;
|
||||
}
|
||||
|
@ -1785,7 +1786,6 @@ int Game::pge_op_isFacingConrad(ObjectOpcodeArgs *args) {
|
|||
return 0xFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -1817,7 +1817,7 @@ int Game::pge_o_unk0x7C(ObjectOpcodeArgs *args) {
|
|||
}
|
||||
}
|
||||
if (pge != 0) {
|
||||
pge_updateGroup(args->pge->index, pge->index, args->a);
|
||||
pge_sendMessage(args->pge->index, pge->index, args->a);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1876,13 +1876,21 @@ int Game::pge_op_setPiegePosModX(ObjectOpcodeArgs *args) {
|
|||
return 0xFFFF;
|
||||
}
|
||||
|
||||
// taxi, level4
|
||||
// taxi and teleporter
|
||||
int Game::pge_op_changeRoom(ObjectOpcodeArgs *args) {
|
||||
InitPGE *init_pge_1 = args->pge->init_PGE;
|
||||
assert(args->a >= 0 && args->a < 3);
|
||||
const int16_t _ax = init_pge_1->counter_values[args->a];
|
||||
if (_ax == 0 && !g_options.bypass_protection) {
|
||||
warning("pge_op_changeRoom(): protection check");
|
||||
if (_ax == 0 && !g_options.bypass_protection && !g_options.use_words_protection && !_res.isMac()) {
|
||||
if (!handleProtectionScreenShape()) {
|
||||
warning("Game::pge_op_changeRoom() protection check failed");
|
||||
// when protection check fails, the changeRoom opcode is disabled,
|
||||
// rendering the teleporter unusable.
|
||||
//
|
||||
// _pge_opcodeTable[0x82] = &Game::pge_op_nop;
|
||||
// _pge_opTempVar1 = 0xFFFF;
|
||||
// return;
|
||||
}
|
||||
}
|
||||
const int16_t _bx = init_pge_1->counter_values[args->a + 1];
|
||||
LivePGE *live_pge_1 = &_pgeLive[_bx];
|
||||
|
@ -1897,7 +1905,7 @@ int Game::pge_op_changeRoom(ObjectOpcodeArgs *args) {
|
|||
InitPGE *init_pge_2 = live_pge_2->init_PGE;
|
||||
init_pge_1 = live_pge_1->init_PGE;
|
||||
if (init_pge_2->obj_node_number == init_pge_1->obj_node_number) {
|
||||
live_pge_2->flags &= 0xFE;
|
||||
live_pge_2->flags &= ~1;
|
||||
if (live_pge_1->flags & 1) {
|
||||
live_pge_2->flags |= 1;
|
||||
}
|
||||
|
@ -2061,7 +2069,6 @@ int Game::pge_updateCollisionState(LivePGE *pge, int16_t pge_dy, uint8_t var8) {
|
|||
|
||||
CollisionSlot2 *slot1 = _col_slots2Next;
|
||||
int16_t i = 255;
|
||||
pge_pos_x = i;
|
||||
if (_pge_currentPiegeFacingDir) {
|
||||
i = pge_unk1C - 1;
|
||||
grid_data -= i;
|
||||
|
@ -2071,7 +2078,6 @@ int Game::pge_updateCollisionState(LivePGE *pge, int16_t pge_dy, uint8_t var8) {
|
|||
slot1->data_size = pge_unk1C - 1;
|
||||
assert(pge_unk1C < 0x70);
|
||||
memset(grid_data, var8, pge_unk1C);
|
||||
grid_data += pge_unk1C;
|
||||
return 1;
|
||||
} else {
|
||||
++i;
|
||||
|
@ -2126,36 +2132,36 @@ int Game::pge_ZOrder(LivePGE *pge, int16_t num, pge_ZOrderCallback compare, uint
|
|||
return 0;
|
||||
}
|
||||
|
||||
void Game::pge_updateGroup(uint8_t idx, uint8_t unk1, int16_t unk2) {
|
||||
debug(DBG_GAME, "Game::pge_updateGroup() idx=0x%X unk1=0x%X unk2=0x%X", idx, unk1, unk2);
|
||||
LivePGE *pge = &_pgeLive[unk1];
|
||||
void Game::pge_sendMessage(uint8_t src_pge_index, uint8_t dst_pge_index, int16_t num) {
|
||||
debug(DBG_GAME, "Game::pge_sendMessage() src=0x%X dst=0x%X num=0x%X", src_pge_index, dst_pge_index, num);
|
||||
LivePGE *pge = &_pgeLive[dst_pge_index];
|
||||
if (!(pge->flags & 4)) {
|
||||
if (!(pge->init_PGE->flags & 1)) {
|
||||
return;
|
||||
}
|
||||
pge->flags |= 4;
|
||||
_pge_liveTable2[unk1] = pge;
|
||||
_pge_liveTable2[dst_pge_index] = pge;
|
||||
}
|
||||
if (unk2 <= 4) {
|
||||
if (num <= 4) {
|
||||
uint8_t pge_room = pge->room_location;
|
||||
pge = &_pgeLive[idx];
|
||||
pge = &_pgeLive[src_pge_index];
|
||||
if (pge_room != pge->room_location) {
|
||||
return;
|
||||
}
|
||||
if (unk1 == 0 && _blinkingConradCounter != 0) {
|
||||
if (dst_pge_index == 0 && _blinkingConradCounter != 0) {
|
||||
return;
|
||||
}
|
||||
// XXX
|
||||
}
|
||||
GroupPGE *le = _pge_nextFreeGroup;
|
||||
MessagePGE *le = _pge_nextFreeMessage;
|
||||
if (le) {
|
||||
// append to the list
|
||||
_pge_nextFreeGroup = le->next_entry;
|
||||
GroupPGE *_ax = _pge_groupsTable[unk1];
|
||||
_pge_groupsTable[unk1] = le;
|
||||
le->next_entry = _ax;
|
||||
le->index = idx;
|
||||
le->group_id = unk2;
|
||||
_pge_nextFreeMessage = le->next_entry;
|
||||
MessagePGE *next = _pge_messagesTable[dst_pge_index];
|
||||
_pge_messagesTable[dst_pge_index] = le;
|
||||
le->next_entry = next;
|
||||
le->index = src_pge_index;
|
||||
le->msg_num = num;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2190,7 +2196,7 @@ int Game::pge_ZOrderByAnimYIfType(LivePGE *pge1, LivePGE *pge2, uint8_t comp, ui
|
|||
|
||||
int Game::pge_ZOrderIfIndex(LivePGE *pge1, LivePGE *pge2, uint8_t comp, uint8_t comp2) {
|
||||
if (pge1->index != comp2) {
|
||||
pge_updateGroup(pge2->index, pge1->index, comp);
|
||||
pge_sendMessage(pge2->index, pge1->index, comp);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -2198,7 +2204,7 @@ int Game::pge_ZOrderIfIndex(LivePGE *pge1, LivePGE *pge2, uint8_t comp, uint8_t
|
|||
|
||||
int Game::pge_ZOrderByIndex(LivePGE *pge1, LivePGE *pge2, uint8_t comp, uint8_t comp2) {
|
||||
if (pge1 != pge2) {
|
||||
pge_updateGroup(pge2->index, pge1->index, comp);
|
||||
pge_sendMessage(pge2->index, pge1->index, comp);
|
||||
_pge_compareVar1 = 0xFFFF;
|
||||
}
|
||||
return 0;
|
||||
|
@ -2221,7 +2227,7 @@ int Game::pge_ZOrderIfDifferentDirection(LivePGE *pge1, LivePGE *pge2, uint8_t c
|
|||
if (pge1 != pge2) {
|
||||
if ((pge1->flags & 1) != (pge2->flags & 1)) {
|
||||
_pge_compareVar1 = 1;
|
||||
pge_updateGroup(pge2->index, pge1->index, comp);
|
||||
pge_sendMessage(pge2->index, pge1->index, comp);
|
||||
if (pge2->index == 0) {
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
@ -2234,7 +2240,7 @@ int Game::pge_ZOrderIfSameDirection(LivePGE *pge1, LivePGE *pge2, uint8_t comp,
|
|||
if (pge1 != pge2) {
|
||||
if ((pge1->flags & 1) == (pge2->flags & 1)) {
|
||||
_pge_compareVar2 = 1;
|
||||
pge_updateGroup(pge2->index, pge1->index, comp);
|
||||
pge_sendMessage(pge2->index, pge1->index, comp);
|
||||
if (pge2->index == 0) {
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
|
37
resource.cpp
37
resource.cpp
|
@ -66,8 +66,7 @@ void Resource::init() {
|
|||
_aba = new ResourceAba(_fs);
|
||||
_aba->readEntries();
|
||||
_isDemo = true;
|
||||
}
|
||||
if (!fileExists("LEVEL1.MAP")) { // fbdemofr (no cutscenes)
|
||||
} else if (!fileExists("LEVEL2.MAP")) { // fbdemofr (no cutscenes)
|
||||
_isDemo = true;
|
||||
}
|
||||
break;
|
||||
|
@ -742,6 +741,7 @@ void Resource::load(const char *objName, int objType, const char *ext) {
|
|||
switch (objType) {
|
||||
case OT_CMD:
|
||||
case OT_POL:
|
||||
case OT_CMP:
|
||||
warning("Unable to load '%s' type %d", _entryName, objType);
|
||||
return;
|
||||
}
|
||||
|
@ -1425,6 +1425,22 @@ uint8_t *Resource::loadBankData(uint16_t num) {
|
|||
return bankData;
|
||||
}
|
||||
|
||||
uint8_t *Resource::decodeResourceMacText(const char *name, const char *suffix) {
|
||||
char buf[256];
|
||||
snprintf(buf, sizeof(buf), "%s %s", name, suffix);
|
||||
const ResourceMacEntry *entry = _mac->findEntry(buf);
|
||||
if (entry) {
|
||||
return decodeResourceMacData(buf, false);
|
||||
} else { // CD version
|
||||
if (strcmp(name, "Flashback") == 0) {
|
||||
name = "Game";
|
||||
}
|
||||
const char *language = (_lang == LANG_FR) ? "French" : "English";
|
||||
snprintf(buf, sizeof(buf), "%s %s %s", name, suffix, language);
|
||||
return decodeResourceMacData(buf, false);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t *Resource::decodeResourceMacData(const char *name, bool decompressLzss) {
|
||||
_resourceMacDataSize = 0;
|
||||
uint8_t *data = 0;
|
||||
|
@ -1600,10 +1616,10 @@ void Resource::MAC_loadLevelData(int level) {
|
|||
snprintf(name, sizeof(name), "Objects %c", _macLevelNumbers[level][0]);
|
||||
_spc = decodeResourceMacData(name, true);
|
||||
// .TBN
|
||||
snprintf(name, sizeof(name), "Level %s names", _macLevelNumbers[level]);
|
||||
_tbn = decodeResourceMacData(name, false);
|
||||
snprintf(name, sizeof(name), "Level %s", _macLevelNumbers[level]);
|
||||
_tbn = decodeResourceMacText(name, "names");
|
||||
|
||||
_str = decodeResourceMacData("Flashback strings", false);
|
||||
_str = decodeResourceMacText("Flashback", "strings");
|
||||
}
|
||||
|
||||
void Resource::MAC_loadLevelRoom(int level, int i, DecodeBuffer *dst) {
|
||||
|
@ -1700,12 +1716,12 @@ void Resource::MAC_loadCutscene(const char *cutscene) {
|
|||
}
|
||||
|
||||
void Resource::MAC_loadCutsceneText() {
|
||||
_cine_txt = decodeResourceMacData("Movie strings", false);
|
||||
_cine_txt = decodeResourceMacText("Movie", "strings");
|
||||
_cine_off = 0; // offsets are prepended to _cine_txt
|
||||
}
|
||||
|
||||
void Resource::MAC_loadCreditsText() {
|
||||
_credits = decodeResourceMacData("Credit strings", false);
|
||||
_credits = decodeResourceMacText("Credit", "strings");
|
||||
}
|
||||
|
||||
void Resource::MAC_loadSounds() {
|
||||
|
@ -1722,12 +1738,13 @@ void Resource::MAC_loadSounds() {
|
|||
return;
|
||||
}
|
||||
static const int kHeaderSize = 0x24;
|
||||
static const int kSoundType = 4;
|
||||
const int soundType = _mac->_sndIndex;
|
||||
assert(soundType != -1);
|
||||
for (int i = 0; i < NUM_SFXS; ++i) {
|
||||
const int num = table[i];
|
||||
if (num != -1) {
|
||||
assert(num >= 0 && num < _mac->_types[kSoundType].count);
|
||||
const ResourceMacEntry *entry = &_mac->_entries[kSoundType][num];
|
||||
assert(num >= 0 && num < _mac->_types[soundType].count);
|
||||
const ResourceMacEntry *entry = &_mac->_entries[soundType][num];
|
||||
_mac->_f.seek(_mac->_dataOffset + entry->dataOffset);
|
||||
int dataSize = _mac->_f.readUint32BE();
|
||||
assert(dataSize > kHeaderSize);
|
||||
|
|
|
@ -318,6 +318,7 @@ struct Resource {
|
|||
uint8_t *findBankData(uint16_t num);
|
||||
uint8_t *loadBankData(uint16_t num);
|
||||
|
||||
uint8_t *decodeResourceMacText(const char *name, const char *suffix);
|
||||
uint8_t *decodeResourceMacData(const char *name, bool decompressLzss);
|
||||
void MAC_decodeImageData(const uint8_t *ptr, int i, DecodeBuffer *dst);
|
||||
void MAC_decodeDataCLUT(const uint8_t *ptr);
|
||||
|
|
|
@ -10,7 +10,7 @@ const char *ResourceMac::FILENAME1 = "Flashback.bin";
|
|||
const char *ResourceMac::FILENAME2 = "Flashback.rsrc";
|
||||
|
||||
ResourceMac::ResourceMac(const char *filePath, FileSystem *fs)
|
||||
: _dataOffset(0), _types(0), _entries(0) {
|
||||
: _dataOffset(0), _types(0), _entries(0), _sndIndex(-1) {
|
||||
memset(&_map, 0, sizeof(_map));
|
||||
_f.open(filePath, "rb", fs);
|
||||
}
|
||||
|
@ -66,6 +66,9 @@ void ResourceMac::loadResourceFork(uint32_t resourceOffset, uint32_t dataSize) {
|
|||
_f.read(_types[i].id, 4);
|
||||
_types[i].count = _f.readUint16BE() + 1;
|
||||
_types[i].startOffset = _f.readUint16BE();
|
||||
if (_sndIndex < 0 && memcmp(_types[i].id, "snd ", 4) == 0) {
|
||||
_sndIndex = i;
|
||||
}
|
||||
}
|
||||
_entries = (ResourceMacEntry **)calloc(_map.typesCount, sizeof(ResourceMacEntry *));
|
||||
for (int i = 0; i < _map.typesCount; ++i) {
|
||||
|
|
|
@ -39,6 +39,7 @@ struct ResourceMac {
|
|||
ResourceMacMap _map;
|
||||
ResourceMacType *_types;
|
||||
ResourceMacEntry **_entries;
|
||||
int _sndIndex;
|
||||
|
||||
ResourceMac(const char *filePath, FileSystem *);
|
||||
~ResourceMac();
|
||||
|
|
3
rs.cfg
3
rs.cfg
|
@ -42,3 +42,6 @@ play_serrure_cutscene=true
|
|||
|
||||
# play 'Game saved' sample when saving with level checkpoints (as in the 3DO version)
|
||||
play_gamesaved_sound=true
|
||||
|
||||
# restore content from 'MEMO' cutscene
|
||||
restore_memo_cutscene=true
|
||||
|
|
|
@ -2,39 +2,28 @@
|
|||
#include "screenshot.h"
|
||||
#include "file.h"
|
||||
|
||||
static void TO_LE16(uint8_t *dst, uint16_t value) {
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
dst[i] = value & 255;
|
||||
value >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
#define kTgaImageTypeUncompressedTrueColor 2
|
||||
#define kTgaImageTypeRunLengthEncodedTrueColor 10
|
||||
#define kTgaDirectionTop (1 << 5)
|
||||
|
||||
static const int TGA_HEADER_SIZE = 18;
|
||||
|
||||
void saveTGA(const char *filename, const uint8_t *rgba, int w, int h) {
|
||||
|
||||
static const uint8_t kImageType = kTgaImageTypeRunLengthEncodedTrueColor;
|
||||
uint8_t buffer[TGA_HEADER_SIZE];
|
||||
buffer[0] = 0; // ID Length
|
||||
buffer[1] = 0; // ColorMap Type
|
||||
buffer[2] = kImageType;
|
||||
TO_LE16(buffer + 3, 0); // ColorMap Start
|
||||
TO_LE16(buffer + 5, 0); // ColorMap Length
|
||||
buffer[7] = 0; // ColorMap Bits
|
||||
TO_LE16(buffer + 8, 0); // X-origin
|
||||
TO_LE16(buffer + 10, 0); // Y-origin
|
||||
TO_LE16(buffer + 12, w); // Image Width
|
||||
TO_LE16(buffer + 14, h); // Image Height
|
||||
buffer[16] = 24; // Pixel Depth
|
||||
buffer[17] = kTgaDirectionTop; // Descriptor
|
||||
|
||||
File f;
|
||||
if (f.open(filename, "wb", ".")) {
|
||||
f.write(buffer, sizeof(buffer));
|
||||
|
||||
f.writeByte(0); // ID Length
|
||||
f.writeByte(0); // ColorMap Type
|
||||
f.writeByte(kImageType);
|
||||
f.writeUint16LE(0); // ColorMap Start
|
||||
f.writeUint16LE(0); // ColorMap Length
|
||||
f.writeByte(0); // ColorMap Bits
|
||||
f.writeUint16LE(0); // X-origin
|
||||
f.writeUint16LE(0); // Y-origin
|
||||
f.writeUint16LE(w); // Image Width
|
||||
f.writeUint16LE(h); // Image Height
|
||||
f.writeByte(24); // Pixel Depth
|
||||
f.writeByte(kTgaDirectionTop); // Descriptor
|
||||
|
||||
if (kImageType == kTgaImageTypeUncompressedTrueColor) {
|
||||
for (int i = 0; i < w * h; ++i) {
|
||||
f.writeByte(rgba[0]);
|
||||
|
|
107
staticres.cpp
107
staticres.cpp
|
@ -25,8 +25,8 @@ const Cutscene::OpcodeStub Cutscene::_opcodeTable[] = {
|
|||
&Cutscene::op_drawShapeScale,
|
||||
&Cutscene::op_drawShapeScaleRotate,
|
||||
/* 0x0C */
|
||||
&Cutscene::op_drawCreditsText,
|
||||
&Cutscene::op_drawStringAtPos,
|
||||
&Cutscene::op_copyScreen,
|
||||
&Cutscene::op_drawTextAtPos,
|
||||
&Cutscene::op_handleKeys
|
||||
};
|
||||
|
||||
|
@ -3535,12 +3535,12 @@ const Game::pge_OpcodeProc Game::_pge_opcodeTable[] = {
|
|||
/* 0x20 */
|
||||
&Game::pge_op_collides2o2u,
|
||||
&Game::pge_op_collides2u2o,
|
||||
&Game::pge_op_isInGroup,
|
||||
&Game::pge_op_updateGroup0,
|
||||
&Game::pge_hasPiegeSentMessage,
|
||||
&Game::pge_op_sendMessageData0,
|
||||
/* 0x24 */
|
||||
&Game::pge_op_updateGroup1,
|
||||
&Game::pge_op_updateGroup2,
|
||||
&Game::pge_op_updateGroup3,
|
||||
&Game::pge_op_sendMessageData1,
|
||||
&Game::pge_op_sendMessageData2,
|
||||
&Game::pge_op_sendMessageData3,
|
||||
&Game::pge_op_isPiegeDead,
|
||||
/* 0x28 */
|
||||
&Game::pge_op_collides1u2o,
|
||||
|
@ -3563,10 +3563,10 @@ const Game::pge_OpcodeProc Game::_pge_opcodeTable[] = {
|
|||
&Game::pge_op_setCollisionState1,
|
||||
&Game::pge_op_setCollisionState0,
|
||||
/* 0x38 */
|
||||
&Game::pge_op_isInGroup1,
|
||||
&Game::pge_op_isInGroup2,
|
||||
&Game::pge_op_isInGroup3,
|
||||
&Game::pge_op_isInGroup4,
|
||||
&Game::pge_hasMessageData0,
|
||||
&Game::pge_hasMessageData1,
|
||||
&Game::pge_hasMessageData2,
|
||||
&Game::pge_hasMessageData3,
|
||||
/* 0x3C */
|
||||
&Game::pge_o_unk0x3C,
|
||||
&Game::pge_o_unk0x3D,
|
||||
|
@ -3626,7 +3626,7 @@ const Game::pge_OpcodeProc Game::_pge_opcodeTable[] = {
|
|||
&Game::pge_op_setCollisionState2,
|
||||
&Game::pge_op_saveState,
|
||||
&Game::pge_o_unk0x6A,
|
||||
&Game::pge_op_isInGroupSlice,
|
||||
&Game::pge_isToggleable,
|
||||
/* 0x6C */
|
||||
&Game::pge_o_unk0x6C,
|
||||
&Game::pge_op_isCollidingObject,
|
||||
|
@ -6187,6 +6187,89 @@ const uint8_t Cutscene::_caillouSetData[] = {
|
|||
0x06, 0x66, 0x04, 0x44, 0x02, 0x22, 0x04, 0x66, 0x00
|
||||
};
|
||||
|
||||
const uint8_t Cutscene::_memoSetShape2Data[] = {
|
||||
0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x41, 0x00, 0x27, 0x0c, 0x0c, 0x00, 0x69,
|
||||
0x00, 0x22, 0x00, 0x7c, 0x00, 0x31, 0x00, 0x7c, 0x00, 0x34, 0x00, 0x78, 0x00, 0x36, 0x00, 0x72,
|
||||
0x00, 0x36, 0x00, 0x67, 0x00, 0x32, 0x00, 0x5d, 0x00, 0x20, 0x00, 0x64, 0x00, 0x20, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x10, 0x00, 0x92, 0x00, 0x23, 0x0c, 0x0c, 0x00, 0x75, 0x00, 0x4f, 0x00, 0x77,
|
||||
0x00, 0x55, 0x00, 0x77, 0x00, 0x5a, 0x00, 0x74, 0x00, 0x70, 0x00, 0x47, 0x00, 0x70, 0x00, 0x32,
|
||||
0x00, 0x4c, 0x00, 0x33, 0x00, 0x47, 0x00, 0x37, 0x00, 0x40, 0x00, 0x37, 0x00, 0x3a, 0x00, 0x39,
|
||||
0x00, 0x35, 0x00, 0x4a, 0x00, 0x24, 0x00, 0x51, 0x00, 0x23, 0x00, 0x55, 0x00, 0x1a, 0x00, 0x5a,
|
||||
0x00, 0x1a, 0x00, 0x5f, 0x00, 0x23, 0x00, 0x61, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0a,
|
||||
0x00, 0xb5, 0x00, 0x2d, 0x0d, 0x0d, 0x00, 0x4d, 0x00, 0x27, 0x00, 0x4f, 0x00, 0x2e, 0x00, 0x53,
|
||||
0x00, 0x3a, 0x00, 0x54, 0x00, 0x41, 0x00, 0x54, 0x00, 0x4f, 0x00, 0x50, 0x00, 0x3b, 0x00, 0x4c,
|
||||
0x00, 0x31, 0x00, 0x4b, 0x00, 0x28, 0x00, 0x4c, 0x00, 0x24, 0x00, 0x4d, 0x00, 0x24, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x07, 0x00, 0x42, 0x00, 0x34, 0x0d, 0x0d, 0x00, 0x76, 0x00, 0x36, 0x00, 0x79,
|
||||
0x00, 0x36, 0x00, 0x7b, 0x00, 0x35, 0x00, 0x79, 0x00, 0x37, 0x00, 0x73, 0x00, 0x37, 0x00, 0x63,
|
||||
0x00, 0x2f, 0x00, 0x65, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x8e, 0x00, 0x36,
|
||||
0x0c, 0x0c, 0x00, 0x7a, 0x00, 0x3f, 0x00, 0x7b, 0x00, 0x40, 0x00, 0x7b, 0x00, 0x42, 0x00, 0x79,
|
||||
0x00, 0x45, 0x00, 0x74, 0x00, 0x46, 0x00, 0x65, 0x00, 0x3f, 0x00, 0x63, 0x00, 0x2d, 0x00, 0x6f,
|
||||
0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0xa1, 0x00, 0x20, 0x0c, 0x0c, 0x00, 0x5e,
|
||||
0x00, 0x23, 0x00, 0x68, 0x00, 0x3b, 0x00, 0x56, 0x00, 0x40, 0x00, 0x4e, 0x00, 0x26, 0x00, 0x4e,
|
||||
0x00, 0x1c, 0x00, 0x51, 0x00, 0x18, 0x00, 0x55, 0x00, 0x17, 0x00, 0x59, 0x00, 0x19, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x0c, 0x00, 0x73, 0x00, 0x37, 0x0d, 0x0d, 0x00, 0x3d, 0x00, 0x41, 0x00, 0x41,
|
||||
0x00, 0x4d, 0x00, 0x4a, 0x00, 0x62, 0x00, 0x40, 0x00, 0x5d, 0x00, 0x39, 0x00, 0x49, 0x00, 0x37,
|
||||
0x00, 0x43, 0x00, 0x37, 0x00, 0x3b, 0x00, 0x38, 0x00, 0x36, 0x00, 0x3e, 0x00, 0x30, 0x00, 0x3b,
|
||||
0x00, 0x35, 0x00, 0x3b, 0x00, 0x3a, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
|
||||
0x00, 0x54, 0x00, 0x27, 0x0d, 0x0d, 0x00, 0x64, 0x00, 0x32, 0x00, 0x5e, 0x00, 0x20, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x02, 0x00, 0x52, 0x00, 0x39, 0x0d, 0x0d, 0x00, 0x6b, 0x00, 0x40, 0x00, 0x64,
|
||||
0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x63, 0x00, 0x2b, 0x0d, 0x0d, 0x00, 0x55,
|
||||
0x00, 0x24, 0x00, 0x5a, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x68, 0x00, 0x2b,
|
||||
0x0d, 0x0d, 0x00, 0x51, 0x00, 0x26, 0x00, 0x55, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
|
||||
0x00, 0x6c, 0x00, 0x27, 0x0d, 0x0d, 0x00, 0x4f, 0x00, 0x20, 0x00, 0x51, 0x00, 0x26, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x02, 0x00, 0x6e, 0x00, 0x24, 0x0d, 0x0d, 0x00, 0x4f, 0x00, 0x1d, 0x00, 0x4f,
|
||||
0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x5f, 0x00, 0x35, 0x0d, 0x0d, 0x00, 0x56,
|
||||
0x00, 0x2e, 0x00, 0x5e, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x5e, 0x00, 0x35,
|
||||
0x0d, 0x0d, 0x00, 0x5f, 0x00, 0x30, 0x00, 0x56, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x05,
|
||||
0x00, 0x4d, 0x00, 0x5a, 0x0c, 0x0c, 0x00, 0x4d, 0x00, 0x8c, 0x00, 0x47, 0x00, 0x70, 0x00, 0x73,
|
||||
0x00, 0x67, 0x00, 0x77, 0x00, 0x75, 0x00, 0x83, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0a,
|
||||
0x00, 0x6a, 0x00, 0x4c, 0x0d, 0x0d, 0x00, 0x53, 0x00, 0x8c, 0x00, 0x4c, 0x00, 0x8c, 0x00, 0x47,
|
||||
0x00, 0x72, 0x00, 0x33, 0x00, 0x50, 0x00, 0x31, 0x00, 0x49, 0x00, 0x34, 0x00, 0x45, 0x00, 0x34,
|
||||
0x00, 0x4b, 0x00, 0x37, 0x00, 0x4f, 0x00, 0x40, 0x00, 0x57, 0x00, 0x4f, 0x00, 0x76, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x04, 0x00, 0x53, 0x00, 0x34, 0x0d, 0x0d, 0x00, 0x63, 0x00, 0x2d, 0x00, 0x66,
|
||||
0x00, 0x2d, 0x00, 0x6a, 0x00, 0x31, 0x00, 0x64, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04,
|
||||
0x00, 0x56, 0x00, 0x30, 0x0d, 0x0d, 0x00, 0x67, 0x00, 0x2d, 0x00, 0x65, 0x00, 0x2c, 0x00, 0x66,
|
||||
0x00, 0x2c, 0x00, 0x67, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x4a, 0x00, 0x45,
|
||||
0x0d, 0x0d, 0x00, 0x73, 0x00, 0x4b, 0x00, 0x6a, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03,
|
||||
0x00, 0x51, 0x00, 0x40, 0x0d, 0x0d, 0x00, 0x69, 0x00, 0x3b, 0x00, 0x6c, 0x00, 0x39, 0x00, 0x6a,
|
||||
0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x42, 0x00, 0x47, 0x0d, 0x0d, 0x00, 0x7b,
|
||||
0x00, 0x43, 0x00, 0x77, 0x00, 0x46, 0x00, 0x73, 0x00, 0x46, 0x00, 0x70, 0x00, 0x45, 0x00, 0x6c,
|
||||
0x00, 0x40, 0x00, 0x73, 0x00, 0x44, 0x00, 0x77, 0x00, 0x44, 0x00, 0x7b, 0x00, 0x42, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x05, 0x00, 0x51, 0x00, 0x5f, 0x0d, 0x0d, 0x00, 0x77, 0x00, 0x75, 0x00, 0x7f,
|
||||
0x00, 0x84, 0x00, 0x75, 0x00, 0x7a, 0x00, 0x73, 0x00, 0x75, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x03, 0x00, 0x6d, 0x00, 0x3d, 0x0d, 0x0d, 0x00, 0x4f, 0x00, 0x37, 0x00, 0x49,
|
||||
0x00, 0x37, 0x00, 0x4c, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x6d, 0x00, 0x40,
|
||||
0x0d, 0x0d, 0x00, 0x4f, 0x00, 0x37, 0x00, 0x4b, 0x00, 0x39, 0x00, 0x4e, 0x00, 0x37, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x05, 0x00, 0x56, 0x00, 0x38, 0x0c, 0x0c, 0x00, 0x7a, 0x00, 0x4e, 0x00, 0x7a,
|
||||
0x00, 0x52, 0x00, 0x79, 0x00, 0x53, 0x00, 0x6d, 0x00, 0x52, 0x00, 0x6a, 0x00, 0x45, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x02, 0x00, 0x5b, 0x00, 0x3b, 0x0d, 0x0d, 0x00, 0x75, 0x00, 0x4c, 0x00, 0x71,
|
||||
0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x58, 0x00, 0x46, 0x0d, 0x0d, 0x00, 0x78,
|
||||
0x00, 0x55, 0x00, 0x78, 0x00, 0x53, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x58, 0x00, 0x3f,
|
||||
0x0d, 0x0d, 0x00, 0x78, 0x00, 0x54, 0x00, 0x75, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x05,
|
||||
0x00, 0x55, 0x00, 0x42, 0x0d, 0x0d, 0x00, 0x7b, 0x00, 0x51, 0x00, 0x79, 0x00, 0x53, 0x00, 0x77,
|
||||
0x00, 0x51, 0x00, 0x7a, 0x00, 0x51, 0x00, 0x7b, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04,
|
||||
0x00, 0x1a, 0x00, 0x34, 0x05, 0x05, 0x00, 0x50, 0x00, 0x34, 0x00, 0x53, 0x00, 0x40, 0x00, 0x2b,
|
||||
0x00, 0x45, 0x00, 0x1a, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x66, 0x00, 0x34,
|
||||
0x05, 0x05, 0x00, 0x66, 0x00, 0x34, 0x00, 0x85, 0x00, 0x34, 0x00, 0x87, 0x00, 0x37, 0x00, 0x6a,
|
||||
0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x25, 0x00, 0x41, 0x04, 0x04, 0x00, 0x2a,
|
||||
0x00, 0x46, 0x00, 0x52, 0x00, 0x41, 0x00, 0x52, 0x00, 0x44, 0x00, 0x25, 0x00, 0x4b, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x04, 0x00, 0x14, 0x00, 0x34, 0x04, 0x04, 0x00, 0x19, 0x00, 0x34, 0x00, 0x2a,
|
||||
0x00, 0x45, 0x00, 0x26, 0x00, 0x4b, 0x00, 0x14, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04,
|
||||
0x00, 0x6a, 0x00, 0x37, 0x04, 0x04, 0x00, 0x6a, 0x00, 0x3c, 0x00, 0x87, 0x00, 0x37, 0x00, 0x87,
|
||||
0x00, 0x38, 0x00, 0x6c, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x34, 0x00, 0x34,
|
||||
0x03, 0x03, 0x00, 0x34, 0x00, 0x34, 0x00, 0x4c, 0x00, 0x34, 0x00, 0x4e, 0x00, 0x39, 0x00, 0x3b,
|
||||
0x00, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
|
||||
0x0e, 0xa8, 0x00, 0x00, 0x02, 0x22, 0x04, 0x44, 0x06, 0x66, 0x08, 0x88, 0x0a, 0xaa, 0x00, 0x40,
|
||||
0x00, 0x80, 0x00, 0xa0, 0x06, 0x42, 0x0c, 0x86, 0x0a, 0x64, 0x00, 0xe0, 0x0e, 0xe0, 0x00
|
||||
};
|
||||
|
||||
const uint8_t Cutscene::_memoSetShape4Data[] = {
|
||||
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x00, 0x8f, 0x00, 0x3d, 0x0e, 0x0e, 0x00, 0x0a,
|
||||
0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
|
||||
0x0a, 0xa0, 0x00, 0x00, 0x02, 0x22, 0x04, 0x44, 0x06, 0x66, 0x08, 0x88, 0x0a, 0xaa, 0x00, 0x40,
|
||||
0x00, 0x80, 0x00, 0xa0, 0x06, 0x42, 0x0c, 0x86, 0x0a, 0x64, 0x00, 0xe0, 0x0f, 0xf0, 0x00
|
||||
};
|
||||
|
||||
const uint8_t Menu::_flagEn16x12[] = {
|
||||
0x73, 0x00, 0x19, 0x8e, 0x00, 0x00, 0x82, 0x91, 0x9d, 0x4e, 0x4f, 0xad, 0x00, 0x00, 0x89, 0x00,
|
||||
0x00, 0x89, 0x82, 0x91, 0x9d, 0x8e, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x82, 0x91, 0x9d, 0x00, 0x00,
|
||||
|
|
|
@ -996,7 +996,7 @@ void SystemStub_SDL::cleanupGraphics() {
|
|||
}
|
||||
|
||||
void SystemStub_SDL::changeGraphics(bool fullscreen, int scaleFactor) {
|
||||
int factor = CLIP(scaleFactor, _scaler->factorMin, _scaler->factorMax);
|
||||
const int factor = _scaler ? CLIP(scaleFactor, _scaler->factorMin, _scaler->factorMax) : scaleFactor;
|
||||
if (fullscreen == _fullscreen && factor == _scaleFactor) {
|
||||
// no change
|
||||
return;
|
||||
|
|
10
util.h
10
util.h
|
@ -28,8 +28,12 @@ enum {
|
|||
|
||||
extern uint16_t g_debugMask;
|
||||
|
||||
extern void debug(uint16_t cm, const char *msg, ...); // __attribute__((__format__(__printf__, 2, 3)))
|
||||
extern void error(const char *msg, ...); // __attribute__((__format__(__printf__, 1, 2)))
|
||||
extern void warning(const char *msg, ...); // __attribute__((__format__(__printf__, 1, 2)))
|
||||
extern void debug(uint16_t cm, const char *msg, ...);
|
||||
extern void error(const char *msg, ...);
|
||||
extern void warning(const char *msg, ...);
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define debug(x, ...)
|
||||
#endif
|
||||
|
||||
#endif // UTIL_H__
|
||||
|
|
Loading…
Reference in New Issue