TINSEL: Implement DECINVMAIN libcall

DECINVMAIN does not hail the loadingscreen scene yet because playing
it produces an incorrect corotine stack.
This commit is contained in:
Jakob Wagner 2022-04-20 12:46:30 +02:00 committed by Filippos Karapetis
parent b71545857b
commit 99c1ea5ea0
6 changed files with 94 additions and 22 deletions

View File

@ -321,15 +321,19 @@ void Cursor::SetAuxCursor(SCNHANDLE hFilm) {
DelAuxCursor(); // Get rid of previous
// WORKAROUND: There's no palette when loading a DW1 savegame with a held item, so exit if so
if (!_vm->_bg->BgPal())
return;
// Noir does not use palettes
if (TinselVersion < 3) {
// WORKAROUND: There's no palette when loading a DW1 savegame with a held item, so exit if so
if (!_vm->_bg->BgPal())
return;
assert(_vm->_bg->BgPal()); // no background palette
PokeInPalette(pmi);
}
GetCursorXY(&x, &y, false); // Note: also waits for cursor to appear
pim = _vm->_handle->GetImage(READ_32(pFrame)); // Get pointer to auxillary cursor's image
assert(_vm->_bg->BgPal()); // no background palette
PokeInPalette(pmi);
_auxCursorOffsetX = (short)(pim->imgWidth / 2 - ((int16) pim->anioffX));
_auxCursorOffsetY = (short)((pim->imgHeight & ~C16_FLAG_MASK) / 2 -

View File

@ -57,6 +57,7 @@
#include "tinsel/tinlib.h"
#include "tinsel/tinsel.h" // For engine access
#include "tinsel/token.h"
#include "tinsel/noir/sysreel.h"
#include "common/textconsole.h"
@ -1161,7 +1162,18 @@ void Dialogs::InventoryIconCursor(bool bNewItem) {
if (TinselVersion >= 2) {
if (bNewItem) {
int objIndex = GetObjectIndex(_heldItem);
_heldFilm = _invFilms[objIndex];
if (TinselVersion == 3) {
INV_OBJECT *invObj = GetInvObject(_heldItem);
if (invObj->attribute & V3ATTR_X200) {
_heldFilm = _vm->_systemReel->Get(objIndex);
} else {
_heldFilm = _invFilms[objIndex];
}
} else {
_heldFilm = _invFilms[objIndex];
}
}
_vm->_cursor->SetAuxCursor(_heldFilm);
} else {
@ -5214,6 +5226,28 @@ void Dialogs::idec_inv2(SCNHANDLE text, int MaxContents,
100, 100, true);
}
/**
* Called from Glitter functions: dec_invMain
* - Declare inventories 1,3 and 4 and hail the loadingscreen(?) scene.
*/
void Dialogs::idec_invMain(SCNHANDLE text, int MaxContents) {
idec_inv(INV_1, text, MaxContents,3, 2, 3, 2, 3, 2, 39,
72, false);
idec_inv(INV_MENU, 0, 3, 2, 2, 2, 1, 3, 1, 100, 100,
false);
idec_inv(INV_4, text, MaxContents,3, 2, 3, 2, 3, 2, 39,
72, false);
warning("TODO: idec_invMain: implement language scene playback");
// This is not yet actived because playing the loadsceen scene
// currently produces an invalid corountine stack.
#if 0
const char *fileName = _vm->getSceneFile(TextLanguage());
SCNHANDLE sceneHandle = _vm->_handle->FindLanguageSceneHandle(fileName);
DoHailScene(sceneHandle);
#endif
}
/**
* Called from Glitter function 'GetInvLimit()'
*/

View File

@ -42,19 +42,30 @@ struct FILM;
struct CONFINIT;
enum {
INV_OPEN = -1, // DW1 only
INV_CONV = 0,
INV_1 = 1,
INV_2 = 2,
INV_CONF = 3,
INV_MENU = 3, // DW2 constant
NUM_INV = 4,
INV_OPEN = -1, // DW1 only
INV_CONV = 0,
INV_1 = 1,
INV_2 = 2,
INV_CONF = 3,
INV_MENU = 3, // DW2 constant
NUM_INV_V0 = 4,
// Discworld 2 constants
DW2_INV_OPEN = 5,
INV_DEFAULT = 6
DW2_INV_OPEN = 5,
INV_DEFAULT = 6,
// Noir constants
INV_4 = 4,
NUM_INV_V3 = 5,
INV_7NOINV = 7,
INV_8NOINV = 8,
INV_NOTEBOOK = 9,
MAX_NUM_INV = NUM_INV_V3 // For determination of _invD array size
};
#define NUM_INV ((TinselVersion == 3) ? NUM_INV_V3 : NUM_INV_V0)
enum {
NOOBJECT = -1,
INV_NOICON_V0 = -1,
@ -302,6 +313,9 @@ public:
void idec_inv2(SCNHANDLE text, int MaxContents, int MinWidth, int MinHeight,
int StartWidth, int StartHeight, int MaxWidth, int MaxHeight);
// Noir
void idec_invMain(SCNHANDLE text, int MaxContents);
bool InventoryActive();
void PermaConvIcon(int icon, bool bEnd = false);
@ -448,7 +462,7 @@ private:
SCNHANDLE _flagFilm; // Window members and cursors' graphic data
SCNHANDLE _configStrings[20];
INV_DEF _invD[NUM_INV]; // Conversation + 2 inventories + ...
INV_DEF _invD[MAX_NUM_INV]; // Conversation + 2 inventories + ...
int _activeInv; // Which inventory is currently active
INV_OBJECT *_invObjects; // Inventory objects' data
int _numObjects; // Number of inventory objects

View File

@ -59,7 +59,8 @@ enum {
fSound = 0x04000000L, ///< sound data
fGraphic = 0x08000000L, ///< graphic data
fCompressed = 0x10000000L, ///< compressed data
fLoaded = 0x20000000L ///< set when file data has been loaded
fLoaded = 0x20000000L, ///< set when file data has been loaded
fUnknown = 0x40000000L ///< v3 specific
};
#define FSIZE_MASK ((TinselVersion == 3) ? 0xFFFFFFFFL : 0x00FFFFFFL) //!< mask to isolate the filesize
#define MEMFLAGS(x) ((TinselVersion == 3) ? x->flags2 : x->filesize)

View File

@ -33,9 +33,11 @@ namespace Tinsel {
// internal allocation flags
#define DWM_USED 0x0001 ///< the objects memory block is in use
#define DWM_DISCARDED 0x0002 ///< the objects memory block has been discarded
#define DWM_LOCKED 0x0004 ///< the objects memory block is locked
#define DWM_LOCKED ((TinselVersion == 3) ? 0x0200 : 0x0004) ///< the objects memory block is locked
#define DWM_SENTINEL 0x0008 ///< the objects memory block is a sentinel
// Noir
#define DWM_V3X20 0x0020 ///< unknown
#define DWM_V3X4 0x0004 ///< unknown
struct MEM_NODE {
MEM_NODE *pNext; // link to the next node in the list

View File

@ -979,6 +979,18 @@ static void DecInv2(SCNHANDLE text, int MaxContents,
StartWidth, StartHeight, MaxWidth, MaxHeight);
}
/**
* Declare parameters of inventories 1, 3 and 4.
* Display loadingscreen (?).
* Takes 8 parameter, but uses only 2.
*/
static void DecInvMain(SCNHANDLE text, int MaxContents,
int MinWidth, int MinHeight,
int StartWidth, int StartHeight,
int MaxWidth, int MaxHeight) {
_vm->_dialogs->idec_invMain(text, MaxContents);
}
/**
* Declare the bits that the inventory windows are constructed from.
*/
@ -4662,8 +4674,11 @@ NoirMapping translateNoirLibCode(int libCode, int32 *pp) {
pp -= mapping.numArgs - 1;
debug(7, "%s(%d)", mapping.name, pp[0]);
break;
case 90: // play anim based on item
error("Unsupported libCode %d", libCode);
case 90: // 2 parameters, play anim based on item
mapping = NoirMapping{"INVPLAY", ZZZZZZ, 2};
pp -= mapping.numArgs - 1;
debug(7, "%s(%d, %d)", mapping.name, pp[0], pp[1]);
break;
case 91:
mapping = NoirMapping{"INWHICHINV", INWHICHINV, 0};
debug(7, "%s()", mapping.name);
@ -5630,7 +5645,9 @@ int CallLibraryRoutine(CORO_PARAM, int operand, int32 *pp, const INT_CONTEXT *pi
return -8;
case DECINVMAIN:
warning("TODO: Implement DECINVMAIN");
pp -= 7; // 8 parameters
DecInvMain(pp[0], pp[1], pp[2], pp[3],
pp[4], pp[5], pp[6], pp[7]);
return -8;
case DECINVW: