- 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:
Filippos Karapetis 2010-05-18 12:16:48 +00:00
parent 75f4791a4a
commit 46af5a5162
7 changed files with 65 additions and 68 deletions

View file

@ -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;

View file

@ -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

View file

@ -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 ********************/

View file

@ -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);

View file

@ -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;

View file

@ -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);
} }

View file

@ -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);