- Moved kernel_lookup_text inside the Kernel class
- Added a pointer to the segment manager from within the Kernel class, thus simplifying the calls to it svn-id: r49076
This commit is contained in:
parent
75f4791a4a
commit
46af5a5162
7 changed files with 65 additions and 68 deletions
|
@ -1834,7 +1834,7 @@ bool Console::cmdValueType(int argc, const char **argv) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int t = g_sci->getKernel()->findRegType(_engine->_gamestate->_segMan, val);
|
int t = g_sci->getKernel()->findRegType(val);
|
||||||
|
|
||||||
switch (t) {
|
switch (t) {
|
||||||
case KSIG_LIST:
|
case KSIG_LIST:
|
||||||
|
@ -1903,7 +1903,7 @@ bool Console::cmdViewReference(int argc, const char **argv) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int type_mask = g_sci->getKernel()->findRegType(_engine->_gamestate->_segMan, reg);
|
int type_mask = g_sci->getKernel()->findRegType(reg);
|
||||||
int filter;
|
int filter;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
|
|
||||||
|
|
|
@ -391,7 +391,7 @@ SciKernelFunction kfunct_mappers[] = {
|
||||||
{NULL, NULL, NULL} // Terminator
|
{NULL, NULL, NULL} // Terminator
|
||||||
};
|
};
|
||||||
|
|
||||||
Kernel::Kernel(ResourceManager *resMan) : _resMan(resMan) {
|
Kernel::Kernel(ResourceManager *resMan, SegManager *segMan) : _resMan(resMan), _segMan(segMan) {
|
||||||
loadSelectorNames();
|
loadSelectorNames();
|
||||||
mapSelectors(); // Map a few special selectors for later use
|
mapSelectors(); // Map a few special selectors for later use
|
||||||
}
|
}
|
||||||
|
@ -642,13 +642,13 @@ void Kernel::mapFunctions() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Kernel::findRegType(SegManager *segMan, reg_t reg) {
|
int Kernel::findRegType(reg_t reg) {
|
||||||
// No segment? Must be arithmetic
|
// No segment? Must be arithmetic
|
||||||
if (!reg.segment)
|
if (!reg.segment)
|
||||||
return reg.offset ? KSIG_ARITHMETIC : KSIG_ARITHMETIC | KSIG_NULL;
|
return reg.offset ? KSIG_ARITHMETIC : KSIG_ARITHMETIC | KSIG_NULL;
|
||||||
|
|
||||||
// Otherwise it's an object
|
// Otherwise it's an object
|
||||||
SegmentObj *mobj = segMan->getSegmentObj(reg.segment);
|
SegmentObj *mobj = _segMan->getSegmentObj(reg.segment);
|
||||||
if (!mobj)
|
if (!mobj)
|
||||||
return 0; // Invalid
|
return 0; // Invalid
|
||||||
|
|
||||||
|
@ -684,14 +684,14 @@ int Kernel::findRegType(SegManager *segMan, reg_t reg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Kernel::signatureMatch(SegManager *segMan, const char *sig, int argc, const reg_t *argv) {
|
bool Kernel::signatureMatch(const char *sig, int argc, const reg_t *argv) {
|
||||||
// Always "match" if no signature is given
|
// Always "match" if no signature is given
|
||||||
if (!sig)
|
if (!sig)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
while (*sig && argc) {
|
while (*sig && argc) {
|
||||||
if ((*sig & KSIG_ANY) != KSIG_ANY) {
|
if ((*sig & KSIG_ANY) != KSIG_ANY) {
|
||||||
int type = findRegType(segMan, *argv);
|
int type = findRegType(*argv);
|
||||||
|
|
||||||
if (!type) {
|
if (!type) {
|
||||||
warning("[KERN] Could not determine type of ref %04x:%04x; failing signature check", PRINT_REG(*argv));
|
warning("[KERN] Could not determine type of ref %04x:%04x; failing signature check", PRINT_REG(*argv));
|
||||||
|
@ -792,4 +792,37 @@ bool Kernel::loadKernelNames(Common::String gameId) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Common::String Kernel::lookupText(reg_t address, int index) {
|
||||||
|
char *seeker;
|
||||||
|
Resource *textres;
|
||||||
|
|
||||||
|
if (address.segment)
|
||||||
|
return _segMan->getString(address);
|
||||||
|
else {
|
||||||
|
int textlen;
|
||||||
|
int _index = index;
|
||||||
|
textres = _resMan->findResource(ResourceId(kResourceTypeText, address.offset), 0);
|
||||||
|
|
||||||
|
if (!textres) {
|
||||||
|
error("text.%03d not found", address.offset);
|
||||||
|
return NULL; /* Will probably segfault */
|
||||||
|
}
|
||||||
|
|
||||||
|
textlen = textres->size;
|
||||||
|
seeker = (char *) textres->data;
|
||||||
|
|
||||||
|
while (index--)
|
||||||
|
while ((textlen--) && (*seeker++))
|
||||||
|
;
|
||||||
|
|
||||||
|
if (textlen)
|
||||||
|
return seeker;
|
||||||
|
else {
|
||||||
|
error("Index %d out of bounds in text.%03d", _index, address.offset);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // End of namespace Sci
|
} // End of namespace Sci
|
||||||
|
|
|
@ -146,7 +146,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Initializes the SCI kernel
|
* Initializes the SCI kernel
|
||||||
*/
|
*/
|
||||||
Kernel(ResourceManager *resMan);
|
Kernel(ResourceManager *resMan, SegManager *segMan);
|
||||||
~Kernel();
|
~Kernel();
|
||||||
|
|
||||||
uint getSelectorNamesSize() const;
|
uint getSelectorNamesSize() const;
|
||||||
|
@ -193,17 +193,30 @@ public:
|
||||||
* @param argv argument list
|
* @param argv argument list
|
||||||
* @return true if the signature was matched, false otherwise
|
* @return true if the signature was matched, false otherwise
|
||||||
*/
|
*/
|
||||||
bool signatureMatch(SegManager *segMan, const char *sig, int argc, const reg_t *argv);
|
bool signatureMatch(const char *sig, int argc, const reg_t *argv);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines the type of the object indicated by reg.
|
* Determines the type of the object indicated by reg.
|
||||||
* @param segMan the Segment manager
|
|
||||||
* @param reg register to check
|
* @param reg register to check
|
||||||
* @return one of KSIG_* below KSIG_NULL.
|
* @return one of KSIG_* below KSIG_NULL.
|
||||||
* KSIG_INVALID set if the type of reg can be determined, but is invalid.
|
* KSIG_INVALID set if the type of reg can be determined, but is invalid.
|
||||||
* 0 on error.
|
* 0 on error.
|
||||||
*/
|
*/
|
||||||
int findRegType(SegManager *segMan, reg_t reg);
|
int findRegType(reg_t reg);
|
||||||
|
|
||||||
|
/******************** Text functionality ********************/
|
||||||
|
/**
|
||||||
|
* Looks up text referenced by scripts
|
||||||
|
* SCI uses two values to reference to text: An address, and an index. The address
|
||||||
|
* determines whether the text should be read from a resource file, or from the heap,
|
||||||
|
* while the index either refers to the number of the string in the specified source,
|
||||||
|
* or to a relative position inside the text.
|
||||||
|
*
|
||||||
|
* @param address The address to look up
|
||||||
|
* @param index The relative index
|
||||||
|
* @return The referenced text, or empty string on error.
|
||||||
|
*/
|
||||||
|
Common::String lookupText(reg_t address, int index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
@ -245,6 +258,7 @@ private:
|
||||||
void mapFunctions();
|
void mapFunctions();
|
||||||
|
|
||||||
ResourceManager *_resMan;
|
ResourceManager *_resMan;
|
||||||
|
SegManager *_segMan;
|
||||||
uint32 features;
|
uint32 features;
|
||||||
|
|
||||||
// Kernel-related lists
|
// Kernel-related lists
|
||||||
|
@ -252,22 +266,6 @@ private:
|
||||||
Common::StringArray _kernelNames;
|
Common::StringArray _kernelNames;
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************** Text functionality ********************/
|
|
||||||
/**
|
|
||||||
* Looks up text referenced by scripts
|
|
||||||
* SCI uses two values to reference to text: An address, and an index. The address
|
|
||||||
* determines whether the text should be read from a resource file, or from the heap,
|
|
||||||
* while the index either refers to the number of the string in the specified source,
|
|
||||||
* or to a relative position inside the text.
|
|
||||||
*
|
|
||||||
* @param s The current state
|
|
||||||
* @param address The address to look up
|
|
||||||
* @param index The relative index
|
|
||||||
* @return The referenced text, or empty string on error.
|
|
||||||
*/
|
|
||||||
Common::String kernel_lookup_text(EngineState *s, reg_t address, int index);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_OLD_MUSIC_FUNCTIONS
|
#ifdef USE_OLD_MUSIC_FUNCTIONS
|
||||||
/******************** Misc functions ********************/
|
/******************** Misc functions ********************/
|
||||||
|
|
||||||
|
|
|
@ -1071,7 +1071,7 @@ reg_t kDisplay(EngineState *s, int argc, reg_t *argv) {
|
||||||
text = s->_segMan->getString(textp);
|
text = s->_segMan->getString(textp);
|
||||||
} else {
|
} else {
|
||||||
argc--; argc--; argv++; argv++;
|
argc--; argc--; argv++; argv++;
|
||||||
text = kernel_lookup_text(s, textp, index);
|
text = g_sci->getKernel()->lookupText(textp, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
return g_sci->_gfxPaint16->kernelDisplay(g_sci->strSplit(text.c_str()).c_str(), argc, argv);
|
return g_sci->_gfxPaint16->kernelDisplay(g_sci->strSplit(text.c_str()).c_str(), argc, argv);
|
||||||
|
|
|
@ -33,40 +33,6 @@
|
||||||
|
|
||||||
namespace Sci {
|
namespace Sci {
|
||||||
|
|
||||||
/* Returns the string the script intended to address */
|
|
||||||
Common::String kernel_lookup_text(EngineState *s, reg_t address, int index) {
|
|
||||||
char *seeker;
|
|
||||||
Resource *textres;
|
|
||||||
|
|
||||||
if (address.segment)
|
|
||||||
return s->_segMan->getString(address);
|
|
||||||
else {
|
|
||||||
int textlen;
|
|
||||||
int _index = index;
|
|
||||||
textres = g_sci->getResMan()->findResource(ResourceId(kResourceTypeText, address.offset), 0);
|
|
||||||
|
|
||||||
if (!textres) {
|
|
||||||
error("text.%03d not found", address.offset);
|
|
||||||
return NULL; /* Will probably segfault */
|
|
||||||
}
|
|
||||||
|
|
||||||
textlen = textres->size;
|
|
||||||
seeker = (char *) textres->data;
|
|
||||||
|
|
||||||
while (index--)
|
|
||||||
while ((textlen--) && (*seeker++))
|
|
||||||
;
|
|
||||||
|
|
||||||
if (textlen)
|
|
||||||
return seeker;
|
|
||||||
else {
|
|
||||||
error("Index %d out of bounds in text.%03d", _index, address.offset);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
reg_t kStrEnd(EngineState *s, int argc, reg_t *argv) {
|
reg_t kStrEnd(EngineState *s, int argc, reg_t *argv) {
|
||||||
reg_t address = argv[0];
|
reg_t address = argv[0];
|
||||||
address.offset += s->_segMan->strlen(address);
|
address.offset += s->_segMan->strlen(address);
|
||||||
|
@ -211,7 +177,7 @@ reg_t kFormat(EngineState *s, int argc, reg_t *argv) {
|
||||||
else
|
else
|
||||||
startarg = 3; /* First parameter to use for formatting */
|
startarg = 3; /* First parameter to use for formatting */
|
||||||
|
|
||||||
Common::String source_str = kernel_lookup_text(s, position, index);
|
Common::String source_str = g_sci->getKernel()->lookupText(position, index);
|
||||||
const char* source = source_str.c_str();
|
const char* source = source_str.c_str();
|
||||||
|
|
||||||
debugC(2, kDebugLevelStrings, "Formatting \"%s\"", source);
|
debugC(2, kDebugLevelStrings, "Formatting \"%s\"", source);
|
||||||
|
@ -278,7 +244,7 @@ reg_t kFormat(EngineState *s, int argc, reg_t *argv) {
|
||||||
reg = GET_SEL32(s->_segMan, reg, SELECTOR(data));
|
reg = GET_SEL32(s->_segMan, reg, SELECTOR(data));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Common::String tempsource = (reg == NULL_REG) ? "" : kernel_lookup_text(s, reg,
|
Common::String tempsource = (reg == NULL_REG) ? "" : g_sci->getKernel()->lookupText(reg,
|
||||||
arguments[paramindex + 1]);
|
arguments[paramindex + 1]);
|
||||||
int slen = strlen(tempsource.c_str());
|
int slen = strlen(tempsource.c_str());
|
||||||
int extralen = str_leng - slen;
|
int extralen = str_leng - slen;
|
||||||
|
|
|
@ -563,7 +563,7 @@ static void callKernelFunc(EngineState *s, int kernelFuncNum, int argc) {
|
||||||
const KernelFuncWithSignature &kernelFunc = g_sci->getKernel()->_kernelFuncs[kernelFuncNum];
|
const KernelFuncWithSignature &kernelFunc = g_sci->getKernel()->_kernelFuncs[kernelFuncNum];
|
||||||
|
|
||||||
if (kernelFunc.signature
|
if (kernelFunc.signature
|
||||||
&& !g_sci->getKernel()->signatureMatch(s->_segMan, kernelFunc.signature, argc, scriptState.xs->sp + 1)) {
|
&& !g_sci->getKernel()->signatureMatch(kernelFunc.signature, argc, scriptState.xs->sp + 1)) {
|
||||||
error("[VM] Invalid arguments to kernel call %x", kernelFuncNum);
|
error("[VM] Invalid arguments to kernel call %x", kernelFuncNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,6 +140,8 @@ Common::Error SciEngine::run() {
|
||||||
return Common::kNoGameDataFoundError;
|
return Common::kNoGameDataFoundError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SegManager *segMan = new SegManager(_resMan);
|
||||||
|
|
||||||
// Scale the screen, if needed
|
// Scale the screen, if needed
|
||||||
int upscaledHires = GFX_SCREEN_UPSCALED_DISABLED;
|
int upscaledHires = GFX_SCREEN_UPSCALED_DISABLED;
|
||||||
|
|
||||||
|
@ -175,13 +177,11 @@ Common::Error SciEngine::run() {
|
||||||
// Create debugger console. It requires GFX to be initialized
|
// Create debugger console. It requires GFX to be initialized
|
||||||
_console = new Console(this);
|
_console = new Console(this);
|
||||||
|
|
||||||
_kernel = new Kernel(_resMan);
|
_kernel = new Kernel(_resMan, segMan);
|
||||||
// Only SCI0 and SCI01 games used a parser
|
// Only SCI0 and SCI01 games used a parser
|
||||||
_vocabulary = (getSciVersion() <= SCI_VERSION_1_EGA) ? new Vocabulary(_resMan) : NULL;
|
_vocabulary = (getSciVersion() <= SCI_VERSION_1_EGA) ? new Vocabulary(_resMan) : NULL;
|
||||||
_audio = new AudioPlayer(_resMan);
|
_audio = new AudioPlayer(_resMan);
|
||||||
|
|
||||||
SegManager *segMan = new SegManager(_resMan);
|
|
||||||
|
|
||||||
_features = new GameFeatures(segMan, _kernel);
|
_features = new GameFeatures(segMan, _kernel);
|
||||||
|
|
||||||
_gamestate = new EngineState(_vocabulary, segMan);
|
_gamestate = new EngineState(_vocabulary, segMan);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue