2009-02-17 15:02:16 +00:00
|
|
|
/* ScummVM - Graphic Adventure Engine
|
|
|
|
*
|
|
|
|
* ScummVM is the legal property of its developers, whose names
|
|
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
|
|
* file distributed with this source distribution.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
* $URL$
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
*/
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
/* String and parser handling */
|
|
|
|
|
2009-05-15 14:07:45 +00:00
|
|
|
#include "sci/resource.h"
|
2009-02-27 02:23:40 +00:00
|
|
|
#include "sci/engine/state.h"
|
2009-02-15 08:34:13 +00:00
|
|
|
#include "sci/engine/message.h"
|
2009-02-24 05:51:55 +00:00
|
|
|
#include "sci/engine/kernel.h"
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-21 10:23:36 +00:00
|
|
|
namespace Sci {
|
|
|
|
|
2009-02-15 22:28:12 +00:00
|
|
|
/* Returns the string the script intended to address */
|
2009-09-27 01:50:26 +00:00
|
|
|
Common::String kernel_lookup_text(EngineState *s, reg_t address, int index) {
|
2009-02-15 06:10:59 +00:00
|
|
|
char *seeker;
|
2009-02-28 21:59:49 +00:00
|
|
|
Resource *textres;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
if (address.segment)
|
2009-10-04 18:38:18 +00:00
|
|
|
return s->_segMan->getString(address);
|
2009-02-15 06:10:59 +00:00
|
|
|
else {
|
|
|
|
int textlen;
|
|
|
|
int _index = index;
|
2009-09-02 12:02:37 +00:00
|
|
|
textres = s->resMan->findResource(ResourceId(kResourceTypeText, address.offset), 0);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
if (!textres) {
|
2009-05-18 11:53:04 +00:00
|
|
|
error("text.%03d not found", address.offset);
|
2009-02-15 06:10:59 +00:00
|
|
|
return NULL; /* Will probably segfault */
|
|
|
|
}
|
|
|
|
|
|
|
|
textlen = textres->size;
|
|
|
|
seeker = (char *) textres->data;
|
|
|
|
|
|
|
|
while (index--)
|
2009-02-21 03:25:23 +00:00
|
|
|
while ((textlen--) && (*seeker++))
|
|
|
|
;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
if (textlen)
|
|
|
|
return seeker;
|
|
|
|
else {
|
2009-05-18 11:53:04 +00:00
|
|
|
error("Index %d out of bounds in text.%03d", _index, address.offset);
|
2009-02-15 06:10:59 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************/
|
|
|
|
/* Parser */
|
|
|
|
/**********/
|
|
|
|
|
|
|
|
|
- Changed the unimplemented debug SCI kernel functions (InspectObj, ShowSends, ShowObjs, ShowFree, StackUsage and Profiler) to be dummy functions - we have our own debugger, and don't use these functions for debugging
- Removed the function number parameter from all kernel functions, as it's no longer needed, and removed the FAKE_FUNCT_NR hack
- Removed kUnknown() and kStub()
- Dummy/unknown kernel functions are no longer invoked, and a warning is shown instead, with the paremeters passed to them
Note: there is an evil hack used for debugging scripts in invoke_selector(), which probably no longer works now
svn-id: r44461
2009-09-29 14:24:07 +00:00
|
|
|
reg_t kSaid(EngineState *s, int argc, reg_t *argv) {
|
2009-02-15 06:10:59 +00:00
|
|
|
reg_t heap_said_block = argv[0];
|
|
|
|
byte *said_block;
|
|
|
|
int new_lastmatch;
|
2009-10-01 17:30:10 +00:00
|
|
|
#ifdef DEBUG_PARSER
|
|
|
|
const int debug_parser = 1;
|
|
|
|
#else
|
|
|
|
const int debug_parser = 0;
|
|
|
|
#endif
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
if (!heap_said_block.segment)
|
|
|
|
return NULL_REG;
|
|
|
|
|
2009-10-04 18:38:18 +00:00
|
|
|
said_block = (byte *)s->_segMan->derefBulkPtr(heap_said_block, 0);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
if (!said_block) {
|
2009-05-21 17:18:46 +00:00
|
|
|
warning("Said on non-string, pointer %04x:%04x", PRINT_REG(heap_said_block));
|
2009-02-15 06:10:59 +00:00
|
|
|
return NULL_REG;
|
|
|
|
}
|
|
|
|
|
2009-05-30 15:40:49 +00:00
|
|
|
#ifdef DEBUG_PARSER
|
|
|
|
debugC(2, kDebugLevelParser, "Said block:", 0);
|
2009-09-30 12:17:38 +00:00
|
|
|
s->_voc->decipherSaidBlock(said_block);
|
2009-05-30 15:40:49 +00:00
|
|
|
#endif
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-10-18 19:42:56 +00:00
|
|
|
if (s->parser_event.isNull() || (GET_SEL32V(s->_segMan, s->parser_event, claimed))) {
|
2009-02-15 06:10:59 +00:00
|
|
|
return NULL_REG;
|
|
|
|
}
|
|
|
|
|
2009-10-01 17:30:10 +00:00
|
|
|
new_lastmatch = said(s, said_block, debug_parser);
|
2009-05-18 15:07:51 +00:00
|
|
|
if (new_lastmatch != SAID_NO_MATCH) { /* Build and possibly display a parse tree */
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-05-30 15:40:49 +00:00
|
|
|
#ifdef DEBUG_PARSER
|
2009-07-06 10:39:22 +00:00
|
|
|
printf("kSaid: Match.\n");
|
2009-05-30 15:40:49 +00:00
|
|
|
#endif
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
s->r_acc = make_reg(0, 1);
|
|
|
|
|
|
|
|
if (new_lastmatch != SAID_PARTIAL_MATCH)
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(s->_segMan, s->parser_event, claimed, 1);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
} else {
|
|
|
|
return NULL_REG;
|
|
|
|
}
|
|
|
|
return s->r_acc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
- Changed the unimplemented debug SCI kernel functions (InspectObj, ShowSends, ShowObjs, ShowFree, StackUsage and Profiler) to be dummy functions - we have our own debugger, and don't use these functions for debugging
- Removed the function number parameter from all kernel functions, as it's no longer needed, and removed the FAKE_FUNCT_NR hack
- Removed kUnknown() and kStub()
- Dummy/unknown kernel functions are no longer invoked, and a warning is shown instead, with the paremeters passed to them
Note: there is an evil hack used for debugging scripts in invoke_selector(), which probably no longer works now
svn-id: r44461
2009-09-29 14:24:07 +00:00
|
|
|
reg_t kSetSynonyms(EngineState *s, int argc, reg_t *argv) {
|
2009-10-04 18:38:18 +00:00
|
|
|
SegManager *segMan = s->_segMan;
|
2009-02-15 06:10:59 +00:00
|
|
|
reg_t object = argv[0];
|
2009-02-28 11:12:59 +00:00
|
|
|
List *list;
|
|
|
|
Node *node;
|
2009-02-15 06:10:59 +00:00
|
|
|
int script;
|
2009-09-30 12:17:38 +00:00
|
|
|
int numSynonyms = 0;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-09-30 12:17:38 +00:00
|
|
|
s->_voc->clearSynonyms();
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-10-18 19:42:56 +00:00
|
|
|
list = s->_segMan->lookupList(GET_SEL32(segMan, object, elements));
|
2009-10-07 23:34:24 +00:00
|
|
|
node = s->_segMan->lookupNode(list->first);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
while (node) {
|
|
|
|
reg_t objpos = node->value;
|
|
|
|
int seg;
|
|
|
|
|
2009-10-18 19:42:56 +00:00
|
|
|
script = GET_SEL32V(segMan, objpos, number);
|
2009-10-04 18:38:18 +00:00
|
|
|
seg = s->_segMan->getScriptSegment(script);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-09-17 00:46:01 +00:00
|
|
|
if (seg > 0)
|
2009-10-04 18:38:18 +00:00
|
|
|
numSynonyms = s->_segMan->getScript(seg)->getSynonymsNr();
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-09-30 12:17:38 +00:00
|
|
|
if (numSynonyms) {
|
2009-10-04 18:38:18 +00:00
|
|
|
byte *synonyms = s->_segMan->getScript(seg)->getSynonyms();
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
if (synonyms) {
|
2009-05-30 15:40:49 +00:00
|
|
|
debugC(2, kDebugLevelParser, "Setting %d synonyms for script.%d\n",
|
2009-09-30 12:17:38 +00:00
|
|
|
numSynonyms, script);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-09-30 12:17:38 +00:00
|
|
|
if (numSynonyms > 16384) {
|
2009-05-31 10:02:16 +00:00
|
|
|
error("Segtable corruption: script.%03d has %d synonyms",
|
2009-09-30 12:17:38 +00:00
|
|
|
script, numSynonyms);
|
2009-02-15 06:10:59 +00:00
|
|
|
/* We used to reset the corrupted value here. I really don't think it's appropriate.
|
|
|
|
* Lars */
|
|
|
|
} else
|
2009-09-30 12:17:38 +00:00
|
|
|
for (int i = 0; i < numSynonyms; i++) {
|
2009-03-24 17:41:26 +00:00
|
|
|
synonym_t tmp;
|
|
|
|
tmp.replaceant = (int16)READ_LE_UINT16(synonyms + i * 4);
|
|
|
|
tmp.replacement = (int16)READ_LE_UINT16(synonyms + i * 4 + 2);
|
2009-09-30 12:17:38 +00:00
|
|
|
s->_voc->addSynonym(tmp);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
2009-02-21 03:25:23 +00:00
|
|
|
} else
|
|
|
|
warning("Synonyms of script.%03d were requested, but script is not available", script);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-15 22:28:12 +00:00
|
|
|
}
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-10-07 23:34:24 +00:00
|
|
|
node = s->_segMan->lookupNode(node->succ);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
2009-09-30 12:17:38 +00:00
|
|
|
debugC(2, kDebugLevelParser, "A total of %d synonyms are active now.\n", numSynonyms);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
return s->r_acc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
- Changed the unimplemented debug SCI kernel functions (InspectObj, ShowSends, ShowObjs, ShowFree, StackUsage and Profiler) to be dummy functions - we have our own debugger, and don't use these functions for debugging
- Removed the function number parameter from all kernel functions, as it's no longer needed, and removed the FAKE_FUNCT_NR hack
- Removed kUnknown() and kStub()
- Dummy/unknown kernel functions are no longer invoked, and a warning is shown instead, with the paremeters passed to them
Note: there is an evil hack used for debugging scripts in invoke_selector(), which probably no longer works now
svn-id: r44461
2009-09-29 14:24:07 +00:00
|
|
|
reg_t kParse(EngineState *s, int argc, reg_t *argv) {
|
2009-10-04 18:38:18 +00:00
|
|
|
SegManager *segMan = s->_segMan;
|
2009-02-15 06:10:59 +00:00
|
|
|
reg_t stringpos = argv[0];
|
2009-10-04 18:38:18 +00:00
|
|
|
Common::String string = s->_segMan->getString(stringpos);
|
2009-02-15 06:10:59 +00:00
|
|
|
char *error;
|
2009-03-09 22:25:33 +00:00
|
|
|
ResultWordList words;
|
2009-02-15 06:10:59 +00:00
|
|
|
reg_t event = argv[1];
|
2009-09-30 12:17:38 +00:00
|
|
|
Vocabulary *voc = s->_voc;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
s->parser_event = event;
|
|
|
|
|
2009-09-27 01:50:26 +00:00
|
|
|
bool res = voc->tokenizeString(words, string.c_str(), &error);
|
2009-09-30 12:17:38 +00:00
|
|
|
s->parserIsValid = false; /* not valid */
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-03-25 10:04:45 +00:00
|
|
|
if (res && !words.empty()) {
|
2009-09-30 12:17:38 +00:00
|
|
|
s->_voc->synonymizeTokens(words);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
s->r_acc = make_reg(0, 1);
|
|
|
|
|
2009-05-30 15:40:49 +00:00
|
|
|
#ifdef DEBUG_PARSER
|
|
|
|
debugC(2, kDebugLevelParser, "Parsed to the following blocks:\n", 0);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-03-09 22:25:33 +00:00
|
|
|
for (ResultWordList::const_iterator i = words.begin(); i != words.end(); ++i)
|
2009-05-30 15:40:49 +00:00
|
|
|
debugC(2, kDebugLevelParser, " Type[%04x] Group[%04x]\n", i->_class, i->_group);
|
|
|
|
#endif
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-09-30 12:17:38 +00:00
|
|
|
int syntax_fail = voc->parseGNF(words);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
if (syntax_fail) {
|
|
|
|
s->r_acc = make_reg(0, 1);
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, event, claimed, 1);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-10-18 19:43:27 +00:00
|
|
|
invoke_selector(INV_SEL(s->_gameObj, syntaxFail, kStopOnInvalidSelector), 2, s->parser_base, stringpos);
|
2009-02-15 06:10:59 +00:00
|
|
|
/* Issue warning */
|
|
|
|
|
2009-05-30 15:40:49 +00:00
|
|
|
debugC(2, kDebugLevelParser, "Tree building failed\n");
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
} else {
|
2009-09-30 12:17:38 +00:00
|
|
|
s->parserIsValid = true;
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, event, claimed, 0);
|
2009-05-30 15:40:49 +00:00
|
|
|
|
|
|
|
#ifdef DEBUG_PARSER
|
2009-09-30 12:17:38 +00:00
|
|
|
s->_voc->dumpParseTree();
|
2009-05-30 15:40:49 +00:00
|
|
|
#endif
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
s->r_acc = make_reg(0, 0);
|
2009-10-18 19:42:56 +00:00
|
|
|
PUT_SEL32V(segMan, event, claimed, 1);
|
2009-02-15 06:10:59 +00:00
|
|
|
if (error) {
|
2009-10-04 18:38:18 +00:00
|
|
|
s->_segMan->strcpy(s->parser_base, error);
|
2009-05-30 15:40:49 +00:00
|
|
|
debugC(2, kDebugLevelParser, "Word unknown: %s\n", error);
|
2009-02-15 06:10:59 +00:00
|
|
|
/* Issue warning: */
|
|
|
|
|
2009-10-18 19:43:27 +00:00
|
|
|
invoke_selector(INV_SEL(s->_gameObj, wordFail, kStopOnInvalidSelector), 2, s->parser_base, stringpos);
|
2009-02-15 06:10:59 +00:00
|
|
|
free(error);
|
|
|
|
return make_reg(0, 1); /* Tell them that it dind't work */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return s->r_acc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
- Changed the unimplemented debug SCI kernel functions (InspectObj, ShowSends, ShowObjs, ShowFree, StackUsage and Profiler) to be dummy functions - we have our own debugger, and don't use these functions for debugging
- Removed the function number parameter from all kernel functions, as it's no longer needed, and removed the FAKE_FUNCT_NR hack
- Removed kUnknown() and kStub()
- Dummy/unknown kernel functions are no longer invoked, and a warning is shown instead, with the paremeters passed to them
Note: there is an evil hack used for debugging scripts in invoke_selector(), which probably no longer works now
svn-id: r44461
2009-09-29 14:24:07 +00:00
|
|
|
reg_t kStrEnd(EngineState *s, int argc, reg_t *argv) {
|
2009-02-15 06:10:59 +00:00
|
|
|
reg_t address = argv[0];
|
2009-10-04 18:38:18 +00:00
|
|
|
address.offset += s->_segMan->strlen(address);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
return address;
|
|
|
|
}
|
|
|
|
|
- Changed the unimplemented debug SCI kernel functions (InspectObj, ShowSends, ShowObjs, ShowFree, StackUsage and Profiler) to be dummy functions - we have our own debugger, and don't use these functions for debugging
- Removed the function number parameter from all kernel functions, as it's no longer needed, and removed the FAKE_FUNCT_NR hack
- Removed kUnknown() and kStub()
- Dummy/unknown kernel functions are no longer invoked, and a warning is shown instead, with the paremeters passed to them
Note: there is an evil hack used for debugging scripts in invoke_selector(), which probably no longer works now
svn-id: r44461
2009-09-29 14:24:07 +00:00
|
|
|
reg_t kStrCat(EngineState *s, int argc, reg_t *argv) {
|
2009-10-04 18:38:18 +00:00
|
|
|
Common::String s1 = s->_segMan->getString(argv[0]);
|
|
|
|
Common::String s2 = s->_segMan->getString(argv[1]);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-09-27 01:50:26 +00:00
|
|
|
s1 += s2;
|
2009-10-04 18:38:18 +00:00
|
|
|
s->_segMan->strcpy(argv[0], s1.c_str());
|
2009-02-15 06:10:59 +00:00
|
|
|
return argv[0];
|
|
|
|
}
|
|
|
|
|
- Changed the unimplemented debug SCI kernel functions (InspectObj, ShowSends, ShowObjs, ShowFree, StackUsage and Profiler) to be dummy functions - we have our own debugger, and don't use these functions for debugging
- Removed the function number parameter from all kernel functions, as it's no longer needed, and removed the FAKE_FUNCT_NR hack
- Removed kUnknown() and kStub()
- Dummy/unknown kernel functions are no longer invoked, and a warning is shown instead, with the paremeters passed to them
Note: there is an evil hack used for debugging scripts in invoke_selector(), which probably no longer works now
svn-id: r44461
2009-09-29 14:24:07 +00:00
|
|
|
reg_t kStrCmp(EngineState *s, int argc, reg_t *argv) {
|
2009-10-04 18:38:18 +00:00
|
|
|
Common::String s1 = s->_segMan->getString(argv[0]);
|
|
|
|
Common::String s2 = s->_segMan->getString(argv[1]);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
if (argc > 2)
|
2009-09-27 01:50:26 +00:00
|
|
|
return make_reg(0, strncmp(s1.c_str(), s2.c_str(), argv[2].toUint16()));
|
2009-02-15 06:10:59 +00:00
|
|
|
else
|
2009-09-27 01:50:26 +00:00
|
|
|
return make_reg(0, strcmp(s1.c_str(), s2.c_str()));
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
- Changed the unimplemented debug SCI kernel functions (InspectObj, ShowSends, ShowObjs, ShowFree, StackUsage and Profiler) to be dummy functions - we have our own debugger, and don't use these functions for debugging
- Removed the function number parameter from all kernel functions, as it's no longer needed, and removed the FAKE_FUNCT_NR hack
- Removed kUnknown() and kStub()
- Dummy/unknown kernel functions are no longer invoked, and a warning is shown instead, with the paremeters passed to them
Note: there is an evil hack used for debugging scripts in invoke_selector(), which probably no longer works now
svn-id: r44461
2009-09-29 14:24:07 +00:00
|
|
|
reg_t kStrCpy(EngineState *s, int argc, reg_t *argv) {
|
2009-02-15 22:28:12 +00:00
|
|
|
if (argc > 2) {
|
2009-06-07 15:53:30 +00:00
|
|
|
int length = argv[2].toSint16();
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-15 22:28:12 +00:00
|
|
|
if (length >= 0)
|
2009-10-04 18:38:18 +00:00
|
|
|
s->_segMan->strncpy(argv[0], argv[1], length);
|
2009-09-27 01:50:26 +00:00
|
|
|
else
|
2009-10-04 18:38:18 +00:00
|
|
|
s->_segMan->memcpy(argv[0], argv[1], -length);
|
2009-02-15 22:28:12 +00:00
|
|
|
} else
|
2009-10-04 18:38:18 +00:00
|
|
|
s->_segMan->strcpy(argv[0], argv[1]);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
return argv[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
- Changed the unimplemented debug SCI kernel functions (InspectObj, ShowSends, ShowObjs, ShowFree, StackUsage and Profiler) to be dummy functions - we have our own debugger, and don't use these functions for debugging
- Removed the function number parameter from all kernel functions, as it's no longer needed, and removed the FAKE_FUNCT_NR hack
- Removed kUnknown() and kStub()
- Dummy/unknown kernel functions are no longer invoked, and a warning is shown instead, with the paremeters passed to them
Note: there is an evil hack used for debugging scripts in invoke_selector(), which probably no longer works now
svn-id: r44461
2009-09-29 14:24:07 +00:00
|
|
|
reg_t kStrAt(EngineState *s, int argc, reg_t *argv) {
|
2009-10-18 10:39:10 +00:00
|
|
|
if (argv[0] == SIGNAL_REG) {
|
|
|
|
warning("Attempt to perform kStrAt() on a signal reg");
|
|
|
|
return NULL_REG;
|
|
|
|
}
|
|
|
|
|
2009-10-04 18:38:18 +00:00
|
|
|
SegmentRef dest_r = s->_segMan->dereference(argv[0]);
|
2009-09-27 01:50:26 +00:00
|
|
|
if (!dest_r.raw) {
|
2009-05-21 17:18:46 +00:00
|
|
|
warning("Attempt to StrAt at invalid pointer %04x:%04x", PRINT_REG(argv[0]));
|
2009-02-15 06:10:59 +00:00
|
|
|
return NULL_REG;
|
|
|
|
}
|
|
|
|
|
2009-09-27 11:14:01 +00:00
|
|
|
byte value;
|
|
|
|
byte newvalue = 0;
|
|
|
|
unsigned int offset = argv[1].toUint16();
|
|
|
|
if (argc > 2)
|
|
|
|
newvalue = argv[2].toSint16();
|
2009-09-27 01:50:26 +00:00
|
|
|
|
2009-10-30 14:22:22 +00:00
|
|
|
// in kq5 this here gets called with offset 0xFFFF
|
|
|
|
// (in the desert wheng getting the staff)
|
|
|
|
if ((int)offset >= dest_r.maxSize) {
|
|
|
|
warning("kStrAt offset %X exceeds maxSize", offset);
|
|
|
|
return s->r_acc;
|
|
|
|
}
|
|
|
|
|
2009-09-27 01:50:26 +00:00
|
|
|
if (dest_r.isRaw) {
|
2009-09-27 11:14:01 +00:00
|
|
|
value = dest_r.raw[offset];
|
|
|
|
if (argc > 2) /* Request to modify this char */
|
|
|
|
dest_r.raw[offset] = newvalue;
|
2009-09-27 01:50:26 +00:00
|
|
|
} else {
|
2009-09-27 11:14:01 +00:00
|
|
|
reg_t &tmp = dest_r.reg[offset / 2];
|
|
|
|
if (!(offset & 1)) {
|
|
|
|
value = tmp.offset & 0x00ff;
|
|
|
|
if (argc > 2) { /* Request to modify this char */
|
|
|
|
tmp.offset &= 0xff00;
|
|
|
|
tmp.offset |= newvalue;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
value = tmp.offset >> 8;
|
|
|
|
if (argc > 2) { /* Request to modify this char */
|
|
|
|
tmp.offset &= 0x00ff;
|
|
|
|
tmp.offset |= newvalue << 8;
|
|
|
|
}
|
|
|
|
}
|
2009-09-27 01:50:26 +00:00
|
|
|
}
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-09-27 11:14:01 +00:00
|
|
|
s->r_acc = make_reg(0, value);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
return s->r_acc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
- Changed the unimplemented debug SCI kernel functions (InspectObj, ShowSends, ShowObjs, ShowFree, StackUsage and Profiler) to be dummy functions - we have our own debugger, and don't use these functions for debugging
- Removed the function number parameter from all kernel functions, as it's no longer needed, and removed the FAKE_FUNCT_NR hack
- Removed kUnknown() and kStub()
- Dummy/unknown kernel functions are no longer invoked, and a warning is shown instead, with the paremeters passed to them
Note: there is an evil hack used for debugging scripts in invoke_selector(), which probably no longer works now
svn-id: r44461
2009-09-29 14:24:07 +00:00
|
|
|
reg_t kReadNumber(EngineState *s, int argc, reg_t *argv) {
|
2009-10-04 18:38:18 +00:00
|
|
|
Common::String source_str = s->_segMan->getString(argv[0]);
|
2009-09-27 01:50:26 +00:00
|
|
|
const char *source = source_str.c_str();
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-10-04 11:05:38 +00:00
|
|
|
while (isspace((unsigned char)*source))
|
2009-02-15 06:10:59 +00:00
|
|
|
source++; /* Skip whitespace */
|
|
|
|
|
|
|
|
if (*source == '$') /* SCI uses this for hex numbers */
|
2009-02-21 21:16:41 +00:00
|
|
|
return make_reg(0, (int16)strtol(source + 1, NULL, 16)); /* Hex */
|
2009-02-15 06:10:59 +00:00
|
|
|
else
|
2009-02-21 21:16:41 +00:00
|
|
|
return make_reg(0, (int16)strtol(source, NULL, 10)); /* Force decimal */
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#define ALIGN_NONE 0
|
|
|
|
#define ALIGN_RIGHT 1
|
|
|
|
#define ALIGN_LEFT -1
|
|
|
|
#define ALIGN_CENTRE 2
|
|
|
|
|
2009-11-04 09:31:35 +00:00
|
|
|
#define CHECK_OVERFLOW1(pt, size, rv) \
|
|
|
|
if (((pt) - (targetbuf)) + (size) > maxsize) { \
|
|
|
|
error("String expansion exceeded heap boundaries"); \
|
|
|
|
return rv;\
|
|
|
|
}
|
|
|
|
|
2009-02-15 06:10:59 +00:00
|
|
|
/* Format(targ_address, textresnr, index_inside_res, ...)
|
|
|
|
** or
|
|
|
|
** Format(targ_address, heap_text_addr, ...)
|
|
|
|
** Formats the text from text.textresnr (offset index_inside_res) or heap_text_addr according to
|
|
|
|
** the supplied parameters and writes it to the targ_address.
|
|
|
|
*/
|
- Changed the unimplemented debug SCI kernel functions (InspectObj, ShowSends, ShowObjs, ShowFree, StackUsage and Profiler) to be dummy functions - we have our own debugger, and don't use these functions for debugging
- Removed the function number parameter from all kernel functions, as it's no longer needed, and removed the FAKE_FUNCT_NR hack
- Removed kUnknown() and kStub()
- Dummy/unknown kernel functions are no longer invoked, and a warning is shown instead, with the paremeters passed to them
Note: there is an evil hack used for debugging scripts in invoke_selector(), which probably no longer works now
svn-id: r44461
2009-09-29 14:24:07 +00:00
|
|
|
reg_t kFormat(EngineState *s, int argc, reg_t *argv) {
|
2009-09-27 19:24:18 +00:00
|
|
|
uint16 *arguments;
|
2009-02-15 06:10:59 +00:00
|
|
|
reg_t dest = argv[0];
|
2009-10-07 16:47:06 +00:00
|
|
|
int maxsize = 4096; /* Arbitrary... */
|
|
|
|
char targetbuf[4096];
|
2009-09-27 01:50:26 +00:00
|
|
|
char *target = targetbuf;
|
2009-02-15 06:10:59 +00:00
|
|
|
reg_t position = argv[1]; /* source */
|
2009-06-07 15:53:30 +00:00
|
|
|
int index = argv[2].toUint16();
|
2009-02-15 06:10:59 +00:00
|
|
|
int mode = 0;
|
|
|
|
int paramindex = 0; /* Next parameter to evaluate */
|
|
|
|
char xfer;
|
|
|
|
int i;
|
|
|
|
int startarg;
|
|
|
|
int str_leng = 0; /* Used for stuff like "%13s" */
|
|
|
|
int unsigned_var = 0;
|
|
|
|
|
|
|
|
if (position.segment)
|
|
|
|
startarg = 2;
|
|
|
|
else
|
|
|
|
startarg = 3; /* First parameter to use for formatting */
|
|
|
|
|
2009-09-27 01:50:26 +00:00
|
|
|
Common::String source_str = kernel_lookup_text(s, position, index);
|
|
|
|
const char* source = source_str.c_str();
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-05-30 15:40:49 +00:00
|
|
|
debugC(2, kDebugLevelStrings, "Formatting \"%s\"\n", source);
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
|
2009-09-27 19:24:18 +00:00
|
|
|
arguments = (uint16 *)malloc(sizeof(uint16) * argc);
|
2009-02-15 06:10:59 +00:00
|
|
|
#ifdef SATISFY_PURIFY
|
2009-09-27 19:24:18 +00:00
|
|
|
memset(arguments, 0, sizeof(uint16) * argc);
|
2009-02-15 06:10:59 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
for (i = startarg; i < argc; i++)
|
2009-06-07 15:53:30 +00:00
|
|
|
arguments[i-startarg] = argv[i].toUint16(); /* Parameters are copied to prevent overwriting */
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
while ((xfer = *source++)) {
|
|
|
|
if (xfer == '%') {
|
|
|
|
if (mode == 1) {
|
|
|
|
CHECK_OVERFLOW1(target, 2, NULL_REG);
|
|
|
|
*target++ = '%'; /* Literal % by using "%%" */
|
|
|
|
mode = 0;
|
|
|
|
} else {
|
|
|
|
mode = 1;
|
|
|
|
str_leng = 0;
|
|
|
|
}
|
|
|
|
} else if (mode == 1) { /* xfer != '%' */
|
|
|
|
char fillchar = ' ';
|
|
|
|
int align = ALIGN_NONE;
|
|
|
|
|
|
|
|
char *writestart = target; /* Start of the written string, used after the switch */
|
|
|
|
|
|
|
|
/* int writelength; -- unused atm */
|
|
|
|
|
|
|
|
if (xfer && (isdigit(xfer) || xfer == '-' || xfer == '=')) {
|
|
|
|
char *destp;
|
|
|
|
|
|
|
|
if (xfer == '0')
|
2009-02-15 22:28:12 +00:00
|
|
|
fillchar = '0';
|
|
|
|
else
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-15 22:28:12 +00:00
|
|
|
if (xfer == '=') {
|
|
|
|
align = ALIGN_CENTRE;
|
|
|
|
source++;
|
|
|
|
} else
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-15 22:28:12 +00:00
|
|
|
if (isdigit(xfer))
|
|
|
|
source--; /* Stepped over length argument */
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
str_leng = strtol(source, &destp, 10);
|
|
|
|
|
|
|
|
if (destp > source)
|
|
|
|
source = destp;
|
|
|
|
|
|
|
|
if (str_leng < 0) {
|
|
|
|
align = ALIGN_LEFT;
|
|
|
|
str_leng = -str_leng;
|
|
|
|
} else if (align != ALIGN_CENTRE)
|
|
|
|
align = ALIGN_RIGHT;
|
|
|
|
|
|
|
|
xfer = *source++;
|
|
|
|
} else
|
|
|
|
str_leng = 0;
|
|
|
|
|
|
|
|
CHECK_OVERFLOW1(target, str_leng + 1, NULL_REG);
|
|
|
|
|
|
|
|
switch (xfer) {
|
|
|
|
case 's': { /* Copy string */
|
|
|
|
reg_t reg = argv[startarg + paramindex];
|
2009-09-30 13:09:18 +00:00
|
|
|
Common::String tempsource = (reg == NULL_REG) ? "" : kernel_lookup_text(s, reg,
|
2009-09-27 01:50:26 +00:00
|
|
|
arguments[paramindex + 1]);
|
|
|
|
int slen = strlen(tempsource.c_str());
|
2009-02-15 06:10:59 +00:00
|
|
|
int extralen = str_leng - slen;
|
|
|
|
CHECK_OVERFLOW1(target, extralen, NULL_REG);
|
|
|
|
if (extralen < 0)
|
|
|
|
extralen = 0;
|
|
|
|
|
|
|
|
if (reg.segment) /* Heap address? */
|
|
|
|
paramindex++;
|
|
|
|
else
|
|
|
|
paramindex += 2; /* No, text resource address */
|
|
|
|
|
|
|
|
switch (align) {
|
|
|
|
|
|
|
|
case ALIGN_NONE:
|
|
|
|
case ALIGN_RIGHT:
|
|
|
|
while (extralen-- > 0)
|
|
|
|
*target++ = ' '; /* Format into the text */
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ALIGN_CENTRE: {
|
|
|
|
int half_extralen = extralen >> 1;
|
|
|
|
while (half_extralen-- > 0)
|
|
|
|
*target++ = ' '; /* Format into the text */
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-15 22:28:12 +00:00
|
|
|
default:
|
|
|
|
break;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2009-09-27 01:50:26 +00:00
|
|
|
strcpy(target, tempsource.c_str());
|
2009-02-15 06:10:59 +00:00
|
|
|
target += slen;
|
|
|
|
|
|
|
|
switch (align) {
|
|
|
|
|
|
|
|
case ALIGN_CENTRE: {
|
|
|
|
int half_extralen;
|
|
|
|
align = 0;
|
|
|
|
half_extralen = extralen - (extralen >> 1);
|
|
|
|
while (half_extralen-- > 0)
|
|
|
|
*target++ = ' '; /* Format into the text */
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
|
|
|
}
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-02-15 22:28:12 +00:00
|
|
|
default:
|
|
|
|
break;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
mode = 0;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
case 'c': { /* insert character */
|
|
|
|
CHECK_OVERFLOW1(target, 2, NULL_REG);
|
|
|
|
if (align >= 0)
|
|
|
|
while (str_leng-- > 1)
|
|
|
|
*target++ = ' '; /* Format into the text */
|
|
|
|
|
|
|
|
*target++ = arguments[paramindex++];
|
|
|
|
mode = 0;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
case 'x':
|
2009-02-15 22:28:12 +00:00
|
|
|
case 'u':
|
|
|
|
unsigned_var = 1;
|
2009-02-15 06:10:59 +00:00
|
|
|
case 'd': { /* Copy decimal */
|
|
|
|
/* int templen; -- unused atm */
|
|
|
|
const char *format_string = "%d";
|
|
|
|
|
|
|
|
if (xfer == 'x')
|
|
|
|
format_string = "%x";
|
|
|
|
|
2009-09-27 19:24:18 +00:00
|
|
|
int val = arguments[paramindex];
|
2009-02-15 06:10:59 +00:00
|
|
|
if (!unsigned_var)
|
2009-09-27 19:24:18 +00:00
|
|
|
val = (int16)arguments[paramindex];
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-09-27 19:24:18 +00:00
|
|
|
target += sprintf(target, format_string, val);
|
2009-09-30 15:21:44 +00:00
|
|
|
paramindex++;
|
2009-02-15 06:10:59 +00:00
|
|
|
CHECK_OVERFLOW1(target, 0, NULL_REG);
|
|
|
|
|
|
|
|
unsigned_var = 0;
|
|
|
|
|
|
|
|
mode = 0;
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
break;
|
2009-02-15 06:10:59 +00:00
|
|
|
default:
|
|
|
|
*target = '%';
|
|
|
|
target++;
|
|
|
|
*target = xfer;
|
|
|
|
target++;
|
|
|
|
mode = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (align) {
|
|
|
|
int written = target - writestart;
|
|
|
|
int padding = str_leng - written;
|
|
|
|
|
|
|
|
if (padding > 0) {
|
|
|
|
if (align > 0) {
|
|
|
|
memmove(writestart + padding,
|
2009-02-15 22:28:12 +00:00
|
|
|
writestart, written);
|
2009-02-15 06:10:59 +00:00
|
|
|
memset(writestart, fillchar, padding);
|
|
|
|
} else {
|
|
|
|
memset(target, ' ', padding);
|
|
|
|
}
|
|
|
|
target += padding;
|
|
|
|
}
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
} else { /* mode != 1 */
|
2009-02-15 06:10:59 +00:00
|
|
|
*target = xfer;
|
|
|
|
target++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
free(arguments);
|
|
|
|
|
|
|
|
*target = 0; /* Terminate string */
|
2009-09-27 01:50:26 +00:00
|
|
|
|
2009-10-04 18:38:18 +00:00
|
|
|
s->_segMan->strcpy(dest, targetbuf);
|
2009-09-27 01:50:26 +00:00
|
|
|
|
2009-02-15 06:10:59 +00:00
|
|
|
return dest; /* Return target addr */
|
|
|
|
}
|
|
|
|
|
2009-11-04 09:31:35 +00:00
|
|
|
#undef CHECK_OVERFLOW1
|
2009-02-15 06:10:59 +00:00
|
|
|
|
- Changed the unimplemented debug SCI kernel functions (InspectObj, ShowSends, ShowObjs, ShowFree, StackUsage and Profiler) to be dummy functions - we have our own debugger, and don't use these functions for debugging
- Removed the function number parameter from all kernel functions, as it's no longer needed, and removed the FAKE_FUNCT_NR hack
- Removed kUnknown() and kStub()
- Dummy/unknown kernel functions are no longer invoked, and a warning is shown instead, with the paremeters passed to them
Note: there is an evil hack used for debugging scripts in invoke_selector(), which probably no longer works now
svn-id: r44461
2009-09-29 14:24:07 +00:00
|
|
|
reg_t kStrLen(EngineState *s, int argc, reg_t *argv) {
|
2009-10-04 18:38:18 +00:00
|
|
|
return make_reg(0, s->_segMan->strlen(argv[0]));
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
- Changed the unimplemented debug SCI kernel functions (InspectObj, ShowSends, ShowObjs, ShowFree, StackUsage and Profiler) to be dummy functions - we have our own debugger, and don't use these functions for debugging
- Removed the function number parameter from all kernel functions, as it's no longer needed, and removed the FAKE_FUNCT_NR hack
- Removed kUnknown() and kStub()
- Dummy/unknown kernel functions are no longer invoked, and a warning is shown instead, with the paremeters passed to them
Note: there is an evil hack used for debugging scripts in invoke_selector(), which probably no longer works now
svn-id: r44461
2009-09-29 14:24:07 +00:00
|
|
|
reg_t kGetFarText(EngineState *s, int argc, reg_t *argv) {
|
2009-09-02 12:02:37 +00:00
|
|
|
Resource *textres = s->resMan->findResource(ResourceId(kResourceTypeText, argv[0].toUint16()), 0);
|
2009-02-15 06:10:59 +00:00
|
|
|
char *seeker;
|
2009-06-07 15:53:30 +00:00
|
|
|
int counter = argv[1].toUint16();
|
2009-02-15 06:10:59 +00:00
|
|
|
|
|
|
|
|
|
|
|
if (!textres) {
|
2009-06-07 15:53:30 +00:00
|
|
|
error("text.%d does not exist", argv[0].toUint16());
|
2009-02-15 06:10:59 +00:00
|
|
|
return NULL_REG;
|
|
|
|
}
|
|
|
|
|
|
|
|
seeker = (char *) textres->data;
|
|
|
|
|
2009-05-14 23:09:04 +00:00
|
|
|
while (counter--) {
|
|
|
|
while (*seeker++)
|
|
|
|
;
|
|
|
|
}
|
2009-02-15 06:10:59 +00:00
|
|
|
/* The second parameter (counter) determines the number of the string inside the text
|
|
|
|
** resource.
|
|
|
|
*/
|
|
|
|
|
2009-10-04 18:38:18 +00:00
|
|
|
s->_segMan->strcpy(argv[2], seeker); /* Copy the string and get return value */
|
2009-02-15 06:10:59 +00:00
|
|
|
return argv[2];
|
|
|
|
}
|
|
|
|
|
2009-05-13 19:03:12 +00:00
|
|
|
#define DUMMY_MESSAGE "Message not found!"
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-05-13 19:03:12 +00:00
|
|
|
enum kMessageFunc {
|
|
|
|
K_MESSAGE_GET,
|
|
|
|
K_MESSAGE_NEXT,
|
|
|
|
K_MESSAGE_SIZE,
|
|
|
|
K_MESSAGE_REFCOND,
|
|
|
|
K_MESSAGE_REFVERB,
|
|
|
|
K_MESSAGE_REFNOUN,
|
|
|
|
K_MESSAGE_PUSH,
|
|
|
|
K_MESSAGE_POP,
|
|
|
|
K_MESSAGE_LASTMESSAGE
|
|
|
|
};
|
|
|
|
|
2009-10-10 02:16:23 +00:00
|
|
|
reg_t kGetMessage(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
MessageTuple tuple = MessageTuple(argv[0].toUint16(), argv[2].toUint16());
|
2009-05-12 12:31:09 +00:00
|
|
|
|
2009-10-10 02:16:23 +00:00
|
|
|
s->_msgState->getMessage(argv[1].toUint16(), tuple, argv[3]);
|
2009-05-10 13:47:38 +00:00
|
|
|
|
2009-10-10 02:16:23 +00:00
|
|
|
return argv[3];
|
|
|
|
}
|
2009-05-10 22:25:43 +00:00
|
|
|
|
2009-10-10 02:16:23 +00:00
|
|
|
reg_t kMessage(EngineState *s, int argc, reg_t *argv) {
|
|
|
|
uint func = argv[0].toUint16();
|
2009-05-10 22:25:43 +00:00
|
|
|
|
2009-10-10 02:16:23 +00:00
|
|
|
if ((func != K_MESSAGE_NEXT) && (argc < 2)) {
|
|
|
|
warning("Message: not enough arguments passed to subfunction %d", func);
|
|
|
|
return NULL_REG;
|
|
|
|
}
|
2009-05-13 19:03:12 +00:00
|
|
|
|
2009-10-10 02:16:23 +00:00
|
|
|
MessageTuple tuple;
|
2009-05-10 22:25:43 +00:00
|
|
|
|
2009-10-10 02:16:23 +00:00
|
|
|
if (argc >= 6)
|
|
|
|
tuple = MessageTuple(argv[2].toUint16(), argv[3].toUint16(), argv[4].toUint16(), argv[5].toUint16());
|
2009-05-10 22:25:43 +00:00
|
|
|
|
2009-10-10 02:16:23 +00:00
|
|
|
switch (func) {
|
|
|
|
case K_MESSAGE_GET:
|
|
|
|
return make_reg(0, s->_msgState->getMessage(argv[1].toUint16(), tuple, (argc == 7 ? argv[6] : NULL_REG)));
|
|
|
|
case K_MESSAGE_NEXT:
|
|
|
|
return make_reg(0, s->_msgState->nextMessage((argc == 2 ? argv[1] : NULL_REG)));
|
|
|
|
case K_MESSAGE_SIZE:
|
|
|
|
return make_reg(0, s->_msgState->messageSize(argv[1].toUint16(), tuple));
|
2009-05-13 19:03:12 +00:00
|
|
|
case K_MESSAGE_REFCOND:
|
|
|
|
case K_MESSAGE_REFVERB:
|
|
|
|
case K_MESSAGE_REFNOUN: {
|
2009-10-10 02:16:23 +00:00
|
|
|
MessageTuple t;
|
2009-02-15 06:10:59 +00:00
|
|
|
|
2009-10-10 02:16:23 +00:00
|
|
|
if (s->_msgState->messageRef(argv[1].toUint16(), tuple, t)) {
|
2009-05-13 19:03:12 +00:00
|
|
|
switch (func) {
|
|
|
|
case K_MESSAGE_REFCOND:
|
|
|
|
return make_reg(0, t.cond);
|
|
|
|
case K_MESSAGE_REFVERB:
|
|
|
|
return make_reg(0, t.verb);
|
|
|
|
case K_MESSAGE_REFNOUN:
|
|
|
|
return make_reg(0, t.noun);
|
|
|
|
}
|
|
|
|
}
|
2009-05-12 11:28:15 +00:00
|
|
|
|
2009-10-10 10:46:11 +00:00
|
|
|
return SIGNAL_REG;
|
2009-05-13 19:03:12 +00:00
|
|
|
}
|
|
|
|
case K_MESSAGE_LASTMESSAGE: {
|
2009-10-10 02:16:23 +00:00
|
|
|
MessageTuple msg;
|
|
|
|
int module;
|
|
|
|
|
|
|
|
s->_msgState->lastQuery(module, msg);
|
|
|
|
|
2009-10-15 11:57:36 +00:00
|
|
|
bool ok = false;
|
|
|
|
|
|
|
|
if (s->_segMan->dereference(argv[1]).isRaw) {
|
|
|
|
byte *buffer = s->_segMan->derefBulkPtr(argv[1], 10);
|
|
|
|
|
|
|
|
if (buffer) {
|
|
|
|
ok = true;
|
|
|
|
WRITE_LE_UINT16(buffer, module);
|
|
|
|
WRITE_LE_UINT16(buffer + 2, msg.noun);
|
|
|
|
WRITE_LE_UINT16(buffer + 4, msg.verb);
|
|
|
|
WRITE_LE_UINT16(buffer + 6, msg.cond);
|
|
|
|
WRITE_LE_UINT16(buffer + 8, msg.seq);
|
|
|
|
}
|
2009-02-15 22:28:12 +00:00
|
|
|
} else {
|
2009-10-15 11:57:36 +00:00
|
|
|
reg_t *buffer = s->_segMan->derefRegPtr(argv[1], 5);
|
|
|
|
|
|
|
|
if (buffer) {
|
|
|
|
ok = true;
|
|
|
|
buffer[0] = make_reg(0, module);
|
|
|
|
buffer[1] = make_reg(0, msg.noun);
|
|
|
|
buffer[2] = make_reg(0, msg.verb);
|
|
|
|
buffer[3] = make_reg(0, msg.cond);
|
|
|
|
buffer[4] = make_reg(0, msg.seq);
|
|
|
|
}
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
2009-05-12 11:28:15 +00:00
|
|
|
|
2009-10-15 11:57:36 +00:00
|
|
|
if (!ok)
|
|
|
|
warning("Message: buffer %04x:%04x invalid or too small to hold the tuple", PRINT_REG(argv[1]));
|
|
|
|
|
2009-05-13 19:03:12 +00:00
|
|
|
return NULL_REG;
|
2009-05-12 11:28:15 +00:00
|
|
|
}
|
2009-05-10 22:25:43 +00:00
|
|
|
default:
|
2009-05-13 19:03:12 +00:00
|
|
|
warning("Message: subfunction %i invoked (not implemented)", func);
|
2009-02-15 06:10:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL_REG;
|
|
|
|
}
|
2009-02-21 10:23:36 +00:00
|
|
|
|
- Changed the unimplemented debug SCI kernel functions (InspectObj, ShowSends, ShowObjs, ShowFree, StackUsage and Profiler) to be dummy functions - we have our own debugger, and don't use these functions for debugging
- Removed the function number parameter from all kernel functions, as it's no longer needed, and removed the FAKE_FUNCT_NR hack
- Removed kUnknown() and kStub()
- Dummy/unknown kernel functions are no longer invoked, and a warning is shown instead, with the paremeters passed to them
Note: there is an evil hack used for debugging scripts in invoke_selector(), which probably no longer works now
svn-id: r44461
2009-09-29 14:24:07 +00:00
|
|
|
reg_t kSetQuitStr(EngineState *s, int argc, reg_t *argv) {
|
2009-10-04 18:38:18 +00:00
|
|
|
Common::String quitStr = s->_segMan->getString(argv[0]);
|
2009-09-27 01:50:26 +00:00
|
|
|
debug("Setting quit string to '%s'", quitStr.c_str());
|
|
|
|
return s->r_acc;
|
2009-05-19 02:10:58 +00:00
|
|
|
}
|
|
|
|
|
- Changed the unimplemented debug SCI kernel functions (InspectObj, ShowSends, ShowObjs, ShowFree, StackUsage and Profiler) to be dummy functions - we have our own debugger, and don't use these functions for debugging
- Removed the function number parameter from all kernel functions, as it's no longer needed, and removed the FAKE_FUNCT_NR hack
- Removed kUnknown() and kStub()
- Dummy/unknown kernel functions are no longer invoked, and a warning is shown instead, with the paremeters passed to them
Note: there is an evil hack used for debugging scripts in invoke_selector(), which probably no longer works now
svn-id: r44461
2009-09-29 14:24:07 +00:00
|
|
|
reg_t kStrSplit(EngineState *s, int argc, reg_t *argv) {
|
2009-10-04 18:38:18 +00:00
|
|
|
Common::String format = s->_segMan->getString(argv[1]);
|
2009-09-27 01:50:26 +00:00
|
|
|
Common::String sep_str;
|
|
|
|
const char *sep = NULL;
|
|
|
|
if (!argv[2].isNull()) {
|
2009-10-04 18:38:18 +00:00
|
|
|
sep_str = s->_segMan->getString(argv[2]);
|
2009-09-27 01:50:26 +00:00
|
|
|
sep = sep_str.c_str();
|
|
|
|
}
|
|
|
|
Common::String str = s->strSplit(format.c_str(), sep);
|
2009-08-10 18:37:47 +00:00
|
|
|
|
|
|
|
// Make sure target buffer is large enough
|
2009-10-04 18:38:18 +00:00
|
|
|
SegmentRef buf_r = s->_segMan->dereference(argv[0]);
|
2009-09-27 01:50:26 +00:00
|
|
|
if (!buf_r.isValid() || buf_r.maxSize < (int)str.size() + 1) {
|
2009-08-10 18:37:47 +00:00
|
|
|
warning("StrSplit: buffer %04x:%04x invalid or too small to hold the following text of %i bytes: '%s'", PRINT_REG(argv[0]), str.size() + 1, str.c_str());
|
|
|
|
return NULL_REG;
|
|
|
|
}
|
2009-10-04 18:38:18 +00:00
|
|
|
s->_segMan->strcpy(argv[0], str.c_str());
|
2009-09-27 01:50:26 +00:00
|
|
|
return argv[0];
|
2009-08-10 18:37:47 +00:00
|
|
|
}
|
|
|
|
|
2009-02-21 10:23:36 +00:00
|
|
|
} // End of namespace Sci
|