diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/sci/engine/kernel.cpp | 32 | ||||
-rw-r--r-- | engines/sci/engine/kernel.h | 16 | ||||
-rw-r--r-- | engines/sci/engine/kfile.cpp | 66 | ||||
-rw-r--r-- | engines/sci/engine/kgraphics.cpp | 20 | ||||
-rw-r--r-- | engines/sci/engine/kmenu.cpp | 6 | ||||
-rw-r--r-- | engines/sci/engine/kmisc.cpp | 8 | ||||
-rw-r--r-- | engines/sci/engine/kpathing.cpp | 10 | ||||
-rw-r--r-- | engines/sci/engine/kstring.cpp | 46 | ||||
-rw-r--r-- | engines/sci/engine/seg_manager.cpp | 33 | ||||
-rw-r--r-- | engines/sci/engine/seg_manager.h | 28 | ||||
-rw-r--r-- | engines/sci/engine/stringfrag.cpp | 30 | ||||
-rw-r--r-- | engines/sci/gfx/menubar.cpp | 4 |
12 files changed, 156 insertions, 143 deletions
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index 2aa70789c9..6d749b36ee 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -721,38 +721,6 @@ bool kernel_matches_signature(SegManager *segMan, const char *sig, int argc, con return (*sig == 0 || (*sig & KSIG_ELLIPSIS)); } -static void *_kernel_dereference_pointer(SegManager *segMan, reg_t pointer, int entries, int align) { - int maxsize; - void *retval = segMan->dereference(pointer, &maxsize); - - if (!retval) - return NULL; - - if (pointer.offset & (align - 1)) { - warning("Unaligned pointer read: %04x:%04x expected with %d alignment", PRINT_REG(pointer), align); - return NULL; - } - - if (entries > maxsize) { - warning("Trying to dereference pointer %04x:%04x beyond end of segment", PRINT_REG(pointer)); - return NULL; - } - return retval; - -} - -byte *kernelDerefBulkPtr(SegManager *segMan, reg_t pointer, int entries) { - return (byte *)_kernel_dereference_pointer(segMan, pointer, entries, 1); -} - -reg_t *kernelDerefRegPtr(SegManager *segMan, reg_t pointer, int entries) { - return (reg_t *)_kernel_dereference_pointer(segMan, pointer, entries, sizeof(reg_t)); -} - -char *kernelDerefString(SegManager *segMan, reg_t pointer, int entries) { - return (char *)_kernel_dereference_pointer(segMan, pointer, entries, 1); -} - void Kernel::setDefaultKernelNames() { _kernelNames = Common::StringList(sci_default_knames, SCI_KNAMES_DEFAULT_ENTRIES_NR); diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index d849d80d0c..3ae8d97e50 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -224,22 +224,6 @@ int invoke_selector(EngineState *s, reg_t object, int selector_id, SelectorInvoc */ char *kernel_lookup_text(EngineState *s, reg_t address, int index); -/******************** Kernel function parameter macros ********************/ - -/* Returns the parameter value or (alt) if not enough parameters were supplied */ -/** - * Dereferences a heap pointer - * @param s The state to operate on - * @param pointer The pointer to dereference - * @parm entries The number of values expected (for checking; use 0 for strings) - * @return A physical reference to the address pointed to, or NULL on error or - * if not enugh entries were available. - * reg_t dereferenciation also assures alignedness of data. - */ -reg_t *kernelDerefRegPtr(SegManager *segMan, reg_t pointer, int entries); -byte *kernelDerefBulkPtr(SegManager *segMan, reg_t pointer, int entries); -char *kernelDerefString(SegManager *segMan, reg_t pointer, int entries = 0); - /******************** Priority macros/functions ********************/ /** * Finds the position of the priority band specified diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index 5f2cd7f5ce..dac1c31cec 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -197,7 +197,7 @@ void file_open(EngineState *s, const char *filename, int mode) { } reg_t kFOpen(EngineState *s, int, int argc, reg_t *argv) { - char *name = kernelDerefString(s->segMan, argv[0]); + char *name = s->segMan->kernelDerefString(argv[0]); int mode = argv[1].toUint16(); debug(3, "kFOpen(%s,0x%x)", name, mode); @@ -250,7 +250,7 @@ void fwrite_wrapper(EngineState *s, int handle, char *data, int length) { reg_t kFPuts(EngineState *s, int, int argc, reg_t *argv) { int handle = argv[0].toUint16(); - char *data = kernelDerefString(s->segMan, argv[1]); + char *data = s->segMan->kernelDerefString(argv[1]); fwrite_wrapper(s, handle, data, strlen(data)); return s->r_acc; @@ -307,7 +307,7 @@ static void fseek_wrapper(EngineState *s, int handle, int offset, int whence) { } reg_t kFGets(EngineState *s, int, int argc, reg_t *argv) { - char *dest = kernelDerefString(s->segMan, argv[0]); + char *dest = s->segMan->kernelDerefString(argv[0]); int maxsize = argv[1].toUint16(); int handle = argv[2].toUint16(); @@ -320,7 +320,7 @@ reg_t kFGets(EngineState *s, int, int argc, reg_t *argv) { * Writes the cwd to the supplied address and returns the address in acc. */ reg_t kGetCWD(EngineState *s, int, int argc, reg_t *argv) { - char *targetaddr = kernelDerefString(s->segMan, argv[0]); + char *targetaddr = s->segMan->kernelDerefString(argv[0]); // We do not let the scripts see the file system, instead pretending // we are always in the same directory. @@ -356,8 +356,8 @@ reg_t kDeviceInfo(EngineState *s, int, int argc, reg_t *argv) { switch (mode) { case K_DEVICE_INFO_GET_DEVICE: - input_s = kernelDerefString(s->segMan, argv[1]); - output_s = kernelDerefString(s->segMan, argv[2]); + input_s = s->segMan->kernelDerefString(argv[1]); + output_s = s->segMan->kernelDerefString(argv[2]); assert(input_s != output_s); strcpy(output_s, "/"); @@ -365,15 +365,15 @@ reg_t kDeviceInfo(EngineState *s, int, int argc, reg_t *argv) { break; case K_DEVICE_INFO_GET_CURRENT_DEVICE: - output_s = kernelDerefString(s->segMan, argv[1]); + output_s = s->segMan->kernelDerefString(argv[1]); strcpy(output_s, "/"); debug(3, "K_DEVICE_INFO_GET_CURRENT_DEVICE() -> %s", output_s); break; case K_DEVICE_INFO_PATHS_EQUAL: { - char *path1_s = kernelDerefString(s->segMan, argv[1]); - char *path2_s = kernelDerefString(s->segMan, argv[2]); + char *path1_s = s->segMan->kernelDerefString(argv[1]); + char *path2_s = s->segMan->kernelDerefString(argv[2]); debug(3, "K_DEVICE_INFO_PATHS_EQUAL(%s,%s)", path1_s, path2_s); return make_reg(0, Common::matchString(path2_s, path1_s, true)); @@ -381,7 +381,7 @@ reg_t kDeviceInfo(EngineState *s, int, int argc, reg_t *argv) { break; case K_DEVICE_INFO_IS_FLOPPY: - input_s = kernelDerefString(s->segMan, argv[1]); + input_s = s->segMan->kernelDerefString(argv[1]); debug(3, "K_DEVICE_INFO_IS_FLOPPY(%s)", input_s); return NULL_REG; /* Never */ @@ -390,8 +390,8 @@ reg_t kDeviceInfo(EngineState *s, int, int argc, reg_t *argv) { ** for more information on our workaround for this. */ case K_DEVICE_INFO_GET_SAVECAT_NAME: { - output_s = kernelDerefString(s->segMan, argv[1]); - game_prefix = kernelDerefString(s->segMan, argv[2]); + output_s = s->segMan->kernelDerefString(argv[1]); + game_prefix = s->segMan->kernelDerefString(argv[2]); sprintf(output_s, "__throwaway"); debug(3, "K_DEVICE_INFO_GET_SAVECAT_NAME(%s) -> %s", game_prefix, output_s); @@ -399,8 +399,8 @@ reg_t kDeviceInfo(EngineState *s, int, int argc, reg_t *argv) { break; case K_DEVICE_INFO_GET_SAVEFILE_NAME: { - output_s = kernelDerefString(s->segMan, argv[1]); - game_prefix = kernelDerefString(s->segMan, argv[2]); + output_s = s->segMan->kernelDerefString(argv[1]); + game_prefix = s->segMan->kernelDerefString(argv[2]); int savegame_id = argv[3].toUint16(); sprintf(output_s, "__throwaway"); debug(3, "K_DEVICE_INFO_GET_SAVEFILE_NAME(%s,%d) -> %s", game_prefix, savegame_id, output_s); @@ -428,7 +428,7 @@ reg_t kGetSaveDir(EngineState *s, int, int argc, reg_t *argv) { } reg_t kCheckFreeSpace(EngineState *s, int, int argc, reg_t *argv) { - char *path = kernelDerefString(s->segMan, argv[0]); + char *path = s->segMan->kernelDerefString(argv[0]); debug(3, "kCheckFreeSpace(%s)", path); // We simply always pretend that there is enough space. @@ -486,7 +486,7 @@ void listSavegames(Common::Array<SavegameDesc> &saves) { } reg_t kCheckSaveGame(EngineState *s, int, int argc, reg_t *argv) { - char *game_id = kernelDerefString(s->segMan, argv[0]); + char *game_id = s->segMan->kernelDerefString(argv[0]); int savedir_nr = argv[1].toUint16(); debug(3, "kCheckSaveGame(%s, %d)", game_id, savedir_nr); @@ -522,10 +522,10 @@ reg_t kCheckSaveGame(EngineState *s, int, int argc, reg_t *argv) { } reg_t kGetSaveFiles(EngineState *s, int, int argc, reg_t *argv) { - char *game_id = kernelDerefString(s->segMan, argv[0]); - char *nametarget = kernelDerefString(s->segMan, argv[1]); + char *game_id = s->segMan->kernelDerefString(argv[0]); + char *nametarget = s->segMan->kernelDerefString(argv[1]); reg_t nametarget_base = argv[1]; - reg_t *nameoffsets = kernelDerefRegPtr(s->segMan, argv[2], 0); + reg_t *nameoffsets = s->segMan->kernelDerefRegPtr(argv[2], 0); debug(3, "kGetSaveFiles(%s,%s)", game_id, nametarget); @@ -572,11 +572,11 @@ reg_t kGetSaveFiles(EngineState *s, int, int argc, reg_t *argv) { } reg_t kSaveGame(EngineState *s, int, int argc, reg_t *argv) { - char *game_id = kernelDerefString(s->segMan, argv[0]); + char *game_id = s->segMan->kernelDerefString(argv[0]); int savedir_nr = argv[1].toUint16(); int savedir_id; // Savegame ID, derived from savedir_nr and the savegame ID list - char *game_description = kernelDerefString(s->segMan, argv[2]); - char *version = argc > 3 ? strdup(kernelDerefString(s->segMan, argv[3])) : NULL; + char *game_description = s->segMan->kernelDerefString(argv[2]); + char *version = argc > 3 ? strdup(s->segMan->kernelDerefString(argv[3])) : NULL; debug(3, "kSaveGame(%s,%d,%s,%s)", game_id, savedir_nr, game_description, version); s->game_version = version; @@ -645,7 +645,7 @@ reg_t kSaveGame(EngineState *s, int, int argc, reg_t *argv) { } reg_t kRestoreGame(EngineState *s, int, int argc, reg_t *argv) { - char *game_id = kernelDerefString(s->segMan, argv[0]); + char *game_id = s->segMan->kernelDerefString(argv[0]); int savedir_nr = argv[1].toUint16(); debug(3, "kRestoreGame(%s,%d)", game_id, savedir_nr); @@ -684,7 +684,7 @@ reg_t kRestoreGame(EngineState *s, int, int argc, reg_t *argv) { } reg_t kValidPath(EngineState *s, int, int argc, reg_t *argv) { - const char *path = kernelDerefString(s->segMan, argv[0]); + const char *path = s->segMan->kernelDerefString(argv[0]); // FIXME: For now, we only accept the (fake) root dir "/" as a valid path. s->r_acc = make_reg(0, 0 == strcmp(path, "/")); @@ -735,7 +735,7 @@ void DirSeeker::nextFile() { return; } - char *mem = kernelDerefString(_vm->segMan, _outbuffer); + char *mem = _vm->segMan->kernelDerefString(_outbuffer); memset(mem, 0, 13); // TODO: Transform the string back into a format usable by the SCI scripts. @@ -756,7 +756,7 @@ reg_t kFileIO(EngineState *s, int, int argc, reg_t *argv) { switch (func_nr) { case K_FILEIO_OPEN : { - char *name = kernelDerefString(s->segMan, argv[1]); + char *name = s->segMan->kernelDerefString(argv[1]); int mode = argv[2].toUint16(); file_open(s, name, mode); @@ -772,7 +772,7 @@ reg_t kFileIO(EngineState *s, int, int argc, reg_t *argv) { } case K_FILEIO_READ_RAW : { int handle = argv[1].toUint16(); - char *dest = kernelDerefString(s->segMan, argv[2]); + char *dest = s->segMan->kernelDerefString(argv[2]); int size = argv[3].toUint16(); debug(3, "K_FILEIO_READ_RAW(%d,%d)", handle, size); @@ -781,7 +781,7 @@ reg_t kFileIO(EngineState *s, int, int argc, reg_t *argv) { } case K_FILEIO_WRITE_RAW : { int handle = argv[1].toUint16(); - char *buf = kernelDerefString(s->segMan, argv[2]); + char *buf = s->segMan->kernelDerefString(argv[2]); int size = argv[3].toUint16(); debug(3, "K_FILEIO_WRITE_RAW(%d,%d)", handle, size); @@ -789,7 +789,7 @@ reg_t kFileIO(EngineState *s, int, int argc, reg_t *argv) { break; } case K_FILEIO_UNLINK : { - char *name = kernelDerefString(s->segMan, argv[1]); + char *name = s->segMan->kernelDerefString(argv[1]); debug(3, "K_FILEIO_UNLINK(%s)", name); Common::SaveFileManager *saveFileMan = g_engine->getSaveFileManager(); @@ -800,7 +800,7 @@ reg_t kFileIO(EngineState *s, int, int argc, reg_t *argv) { break; } case K_FILEIO_READ_STRING : { - char *dest = kernelDerefString(s->segMan, argv[1]); + char *dest = s->segMan->kernelDerefString(argv[1]); int size = argv[2].toUint16(); int handle = argv[3].toUint16(); debug(3, "K_FILEIO_READ_STRING(%d,%d)", handle, size); @@ -811,7 +811,7 @@ reg_t kFileIO(EngineState *s, int, int argc, reg_t *argv) { case K_FILEIO_WRITE_STRING : { int handle = argv[1].toUint16(); int size = argv[3].toUint16(); - char *buf = kernelDerefString(s->segMan, argv[2], size); + char *buf = s->segMan->kernelDerefString(argv[2], size); debug(3, "K_FILEIO_WRITE_STRING(%d,%d)", handle, size); // FIXME: What is the difference between K_FILEIO_WRITE_STRING and @@ -832,7 +832,7 @@ reg_t kFileIO(EngineState *s, int, int argc, reg_t *argv) { break; } case K_FILEIO_FIND_FIRST : { - char *mask = kernelDerefString(s->segMan, argv[1]); + char *mask = s->segMan->kernelDerefString(argv[1]); reg_t buf = argv[2]; int attr = argv[3].toUint16(); // We won't use this, Win32 might, though... debug(3, "K_FILEIO_FIND_FIRST(%s,0x%x)", mask, attr); @@ -851,7 +851,7 @@ reg_t kFileIO(EngineState *s, int, int argc, reg_t *argv) { break; } case K_FILEIO_FILE_EXISTS : { - char *name = kernelDerefString(s->segMan, argv[1]); + char *name = s->segMan->kernelDerefString(argv[1]); // Check for regular file bool exists = Common::File::exists(name); diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp index f2370c5aad..b455974901 100644 --- a/engines/sci/engine/kgraphics.cpp +++ b/engines/sci/engine/kgraphics.cpp @@ -602,14 +602,14 @@ reg_t kGraph(EngineState *s, int, int argc, reg_t *argv) { reg_t kTextSize(EngineState *s, int, int argc, reg_t *argv) { int width, height; - char *text = argv[1].segment ? kernelDerefString(s->segMan, argv[1]) : NULL; + char *text = argv[1].segment ? s->segMan->kernelDerefString(argv[1]) : NULL; const char *sep = NULL; - reg_t *dest = kernelDerefRegPtr(s->segMan, argv[0], 4); + reg_t *dest = s->segMan->kernelDerefRegPtr(argv[0], 4); int maxwidth = (argc > 3) ? argv[3].toUint16() : 0; int font_nr = argv[2].toUint16(); if ((argc > 4) && (argv[4].segment)) - sep = kernelDerefString(s->segMan, argv[4]); + sep = s->segMan->kernelDerefString(argv[4]); if (maxwidth < 0) maxwidth = 0; @@ -1298,7 +1298,7 @@ static void _k_draw_control(EngineState *s, reg_t obj, int inverse); static void disableCertainButtons(SegManager *segMan, Common::String gameName, reg_t obj) { reg_t text_pos = GET_SEL32(obj, text); - char *text = text_pos.isNull() ? NULL : (char *)segMan->dereference(text_pos, NULL); + char *text = text_pos.isNull() ? NULL : segMan->kernelDerefString(text_pos); int type = GET_SEL32V(obj, type); int state = GET_SEL32V(obj, state); @@ -1396,7 +1396,7 @@ reg_t kEditControl(EngineState *s, int, int argc, reg_t *argv) { reg_t text_pos = GET_SEL32(obj, text); int display_offset = 0; - char *text = (char *)s->segMan->dereference(text_pos, NULL); + char *text = s->segMan->kernelDerefString(text_pos); int textlen; if (!text) { @@ -1559,7 +1559,7 @@ static void _k_draw_control(EngineState *s, reg_t obj, int inverse) { int font_nr = GET_SEL32V(obj, font); reg_t text_pos = GET_SEL32(obj, text); - const char *text = text_pos.isNull() ? NULL : (char *)s->segMan->dereference(text_pos, NULL); + const char *text = text_pos.isNull() ? NULL : s->segMan->kernelDerefString(text_pos); int view = GET_SEL32V(obj, view); int cel = sign_extend_byte(GET_SEL32V(obj, cel)); int loop = sign_extend_byte(GET_SEL32V(obj, loop)); @@ -2506,7 +2506,7 @@ reg_t kNewWindow(EngineState *s, int, int argc, reg_t *argv) { lWhite.alpha = 0; lWhite.priority = -1; lWhite.control = -1; - const char *title = argv[4 + argextra].segment ? kernelDerefString(s->segMan, argv[4 + argextra]) : NULL; + const char *title = argv[4 + argextra].segment ? s->segMan->kernelDerefString(argv[4 + argextra]) : NULL; window = sciw_new_window(s, gfx_rect(x, y, xl, yl), s->titlebar_port->_font, fgcolor, bgcolor, s->titlebar_port->_font, lWhite, black, title ? s->strSplit(title, NULL).c_str() : NULL, flags); @@ -3135,7 +3135,7 @@ reg_t kDisplay(EngineState *s, int, int argc, reg_t *argv) { if (textp.segment) { argpt = 1; - text = kernelDerefString(s->segMan, textp); + text = s->segMan->kernelDerefString(textp); } else { argpt = 2; text = kernel_lookup_text(s, textp, index); @@ -3303,7 +3303,7 @@ reg_t kDisplay(EngineState *s, int, int argc, reg_t *argv) { } static reg_t kShowMovie_Windows(EngineState *s, int argc, reg_t *argv) { - const char *filename = kernelDerefString(s->segMan, argv[1]); + const char *filename = s->segMan->kernelDerefString(argv[1]); Graphics::AVIPlayer *player = new Graphics::AVIPlayer(g_system); @@ -3382,7 +3382,7 @@ static reg_t kShowMovie_Windows(EngineState *s, int argc, reg_t *argv) { } static reg_t kShowMovie_DOS(EngineState *s, int argc, reg_t *argv) { - const char *filename = kernelDerefString(s->segMan, argv[0]); + const char *filename = s->segMan->kernelDerefString(argv[0]); int delay = argv[1].toUint16(); // Time between frames in ticks int frameNr = 0; SeqDecoder seq; diff --git a/engines/sci/engine/kmenu.cpp b/engines/sci/engine/kmenu.cpp index 45265dd74a..b2edbe8a45 100644 --- a/engines/sci/engine/kmenu.cpp +++ b/engines/sci/engine/kmenu.cpp @@ -34,8 +34,8 @@ namespace Sci { reg_t kAddMenu(EngineState *s, int, int argc, reg_t *argv) { - char *name = kernelDerefString(s->segMan, argv[0]); - char *contents = kernelDerefString(s->segMan, argv[1]); + char *name = s->segMan->kernelDerefString(argv[0]); + char *contents = s->segMan->kernelDerefString(argv[1]); s->_menubar->addMenu(s->gfx_state, name, contents, s->titlebar_port->_font, argv[1]); @@ -78,7 +78,7 @@ reg_t kDrawStatus(EngineState *s, int, int argc, reg_t *argv) { s->status_bar_background = bgcolor; if (text.segment) { - const char *tmp = strdup(kernelDerefString(s->segMan, text)); + const char *tmp = strdup(s->segMan->kernelDerefString(text)); s->_statusBarText = tmp ? tmp : ""; } diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp index b52adba740..5247d76e5b 100644 --- a/engines/sci/engine/kmisc.cpp +++ b/engines/sci/engine/kmisc.cpp @@ -187,8 +187,8 @@ reg_t kMemory(EngineState *s, int, int argc, reg_t *argv) { break; case K_MEMORY_MEMCPY : { int size = argv[3].toUint16(); - byte *dest = kernelDerefBulkPtr(s->segMan, argv[1], size); - byte *src = kernelDerefBulkPtr(s->segMan, argv[2], size); + byte *dest = s->segMan->kernelDerefBulkPtr(argv[1], size); + byte *src = s->segMan->kernelDerefBulkPtr(argv[2], size); if (dest && src) memcpy(dest, src, size); @@ -204,7 +204,7 @@ reg_t kMemory(EngineState *s, int, int argc, reg_t *argv) { break; } case K_MEMORY_PEEK : { - byte *ref = kernelDerefBulkPtr(s->segMan, argv[1], 2); + byte *ref = s->segMan->kernelDerefBulkPtr(argv[1], 2); if (!ref) { // This occurs in KQ5CD when interacting with certain objects @@ -218,7 +218,7 @@ reg_t kMemory(EngineState *s, int, int argc, reg_t *argv) { break; } case K_MEMORY_POKE : { - byte *ref = kernelDerefBulkPtr(s->segMan, argv[1], 2); + byte *ref = s->segMan->kernelDerefBulkPtr(argv[1], 2); if (!ref) { warning("Attempt to poke invalid memory at %04x:%04x", PRINT_REG(argv[1])); diff --git a/engines/sci/engine/kpathing.cpp b/engines/sci/engine/kpathing.cpp index 6e6ec27eaf..1687434124 100644 --- a/engines/sci/engine/kpathing.cpp +++ b/engines/sci/engine/kpathing.cpp @@ -295,8 +295,8 @@ static bool polygons_equal(SegManager *segMan, reg_t p1, reg_t p2) { if (size != GET_SEL32(p2, size).toUint16()) return false; - const byte *p1_points = kernelDerefBulkPtr(segMan, GET_SEL32(p1, points), size * POLY_POINT_SIZE); - const byte *p2_points = kernelDerefBulkPtr(segMan, GET_SEL32(p2, points), size * POLY_POINT_SIZE); + const byte *p1_points = segMan->kernelDerefBulkPtr(GET_SEL32(p1, points), size * POLY_POINT_SIZE); + const byte *p2_points = segMan->kernelDerefBulkPtr(GET_SEL32(p2, points), size * POLY_POINT_SIZE); bool p1_is_reg_t = polygon_is_reg_t(p1_points, size); bool p2_is_reg_t = polygon_is_reg_t(p2_points, size); @@ -359,7 +359,7 @@ static void draw_polygon(EngineState *s, reg_t polygon) { int size = GET_SEL32(polygon, size).toUint16(); int type = GET_SEL32(polygon, type).toUint16(); Common::Point first, prev; - const byte *list = kernelDerefBulkPtr(s->segMan, points, size * POLY_POINT_SIZE); + const byte *list = s->segMan->kernelDerefBulkPtr(points, size * POLY_POINT_SIZE); int is_reg_t = polygon_is_reg_t(list, size); int i; @@ -406,7 +406,7 @@ static void print_polygon(SegManager *segMan, reg_t polygon) { int size = GET_SEL32(polygon, size).toUint16(); int type = GET_SEL32(polygon, type).toUint16(); int i; - const byte *point_array = kernelDerefBulkPtr(segMan, points, size * POLY_POINT_SIZE); + const byte *point_array = segMan->kernelDerefBulkPtr(points, size * POLY_POINT_SIZE); int is_reg_t = polygon_is_reg_t(point_array, size); Common::Point point; @@ -1230,7 +1230,7 @@ static Polygon *convert_polygon(EngineState *s, reg_t polygon) { int i; reg_t points = GET_SEL32(polygon, points); int size = GET_SEL32(polygon, size).toUint16(); - const byte *list = kernelDerefBulkPtr(s->segMan, points, size * POLY_POINT_SIZE); + const byte *list = s->segMan->kernelDerefBulkPtr(points, size * POLY_POINT_SIZE); Polygon *poly = new Polygon(GET_SEL32(polygon, type).toUint16()); int is_reg_t = polygon_is_reg_t(list, size); diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp index d12e890d40..a17222f205 100644 --- a/engines/sci/engine/kstring.cpp +++ b/engines/sci/engine/kstring.cpp @@ -44,7 +44,7 @@ char *kernel_lookup_text(EngineState *s, reg_t address, int index) { Resource *textres; if (address.segment) - return kernelDerefString(s->segMan, address); + return s->segMan->kernelDerefString(address); else { int textlen; int _index = index; @@ -87,7 +87,7 @@ reg_t kSaid(EngineState *s, int, int argc, reg_t *argv) { if (!heap_said_block.segment) return NULL_REG; - said_block = (byte *)kernelDerefBulkPtr(s->segMan, heap_said_block, 0); + said_block = (byte *)s->segMan->kernelDerefBulkPtr(heap_said_block, 0); if (!said_block) { warning("Said on non-string, pointer %04x:%04x", PRINT_REG(heap_said_block)); @@ -189,7 +189,7 @@ reg_t kSetSynonyms(EngineState *s, int, int argc, reg_t *argv) { reg_t kParse(EngineState *s, int, int argc, reg_t *argv) { SegManager *segMan = s->segMan; reg_t stringpos = argv[0]; - char *string = kernelDerefString(s->segMan, stringpos); + char *string = s->segMan->kernelDerefString(stringpos); char *error; ResultWordList words; reg_t event = argv[1]; @@ -242,7 +242,7 @@ reg_t kParse(EngineState *s, int, int argc, reg_t *argv) { s->r_acc = make_reg(0, 0); PUT_SEL32V(event, claimed, 1); if (error) { - char *pbase_str = kernelDerefString(s->segMan, s->parser_base); + char *pbase_str = s->segMan->kernelDerefString(s->parser_base); strcpy(pbase_str, error); debugC(2, kDebugLevelParser, "Word unknown: %s\n", error); /* Issue warning: */ @@ -259,7 +259,7 @@ reg_t kParse(EngineState *s, int, int argc, reg_t *argv) { reg_t kStrEnd(EngineState *s, int, int argc, reg_t *argv) { reg_t address = argv[0]; - char *seeker = kernelDerefString(s->segMan, address); + char *seeker = s->segMan->kernelDerefString(address); while (*seeker++) ++address.offset; @@ -268,16 +268,16 @@ reg_t kStrEnd(EngineState *s, int, int argc, reg_t *argv) { } reg_t kStrCat(EngineState *s, int, int argc, reg_t *argv) { - char *s1 = kernelDerefString(s->segMan, argv[0]); - char *s2 = kernelDerefString(s->segMan, argv[1]); + char *s1 = s->segMan->kernelDerefString(argv[0]); + char *s2 = s->segMan->kernelDerefString(argv[1]); strcat(s1, s2); return argv[0]; } reg_t kStrCmp(EngineState *s, int, int argc, reg_t *argv) { - char *s1 = kernelDerefString(s->segMan, argv[0]); - char *s2 = kernelDerefString(s->segMan, argv[1]); + char *s1 = s->segMan->kernelDerefString(argv[0]); + char *s2 = s->segMan->kernelDerefString(argv[1]); if (argc > 2) return make_reg(0, strncmp(s1, s2, argv[2].toUint16())); @@ -287,8 +287,8 @@ reg_t kStrCmp(EngineState *s, int, int argc, reg_t *argv) { reg_t kStrCpy(EngineState *s, int, int argc, reg_t *argv) { - char *dest = kernelDerefString(s->segMan, argv[0]); - char *src = kernelDerefString(s->segMan, argv[1]); + char *dest = s->segMan->kernelDerefString(argv[0]); + char *src = s->segMan->kernelDerefString(argv[1]); if (!dest) { warning("Attempt to strcpy TO invalid pointer %04x:%04x", @@ -352,7 +352,7 @@ static int is_print_str(const char *str) { reg_t kStrAt(EngineState *s, int, int argc, reg_t *argv) { - char *dest = kernelDerefString(s->segMan, argv[0]); + char *dest = s->segMan->kernelDerefString(argv[0]); reg_t *dest2; if (!dest) { @@ -394,7 +394,7 @@ reg_t kStrAt(EngineState *s, int, int argc, reg_t *argv) { reg_t kReadNumber(EngineState *s, int, int argc, reg_t *argv) { - char *source = kernelDerefString(s->segMan, argv[0]); + char *source = s->segMan->kernelDerefString(argv[0]); while (isspace(*source)) source++; /* Skip whitespace */ @@ -420,7 +420,7 @@ reg_t kReadNumber(EngineState *s, int, int argc, reg_t *argv) { reg_t kFormat(EngineState *s, int, int argc, reg_t *argv) { int *arguments; reg_t dest = argv[0]; - char *target = kernelDerefString(s->segMan, dest); + char *target = s->segMan->kernelDerefString(dest); reg_t position = argv[1]; /* source */ int index = argv[2].toUint16(); char *source; @@ -633,7 +633,7 @@ reg_t kFormat(EngineState *s, int, int argc, reg_t *argv) { reg_t kStrLen(EngineState *s, int, int argc, reg_t *argv) { - char *str = kernelDerefString(s->segMan, argv[0]); + char *str = s->segMan->kernelDerefString(argv[0]); if (!str) { warning("StrLen: invalid pointer %04x:%04x", PRINT_REG(argv[0])); @@ -665,7 +665,7 @@ reg_t kGetFarText(EngineState *s, int, int argc, reg_t *argv) { ** resource. */ - strcpy(kernelDerefString(s->segMan, argv[2]), seeker); /* Copy the string and get return value */ + strcpy(s->segMan->kernelDerefString(argv[2]), seeker); /* Copy the string and get return value */ return argv[2]; } @@ -740,7 +740,7 @@ reg_t kMessage(EngineState *s, int, int argc, reg_t *argv) { if (!bufferReg.isNull()) { int len = str.size() + 1; - buffer = kernelDerefString(s->segMan, bufferReg, len); + buffer = s->segMan->kernelDerefString(bufferReg, len); if (buffer) { strcpy(buffer, str.c_str()); @@ -748,7 +748,7 @@ reg_t kMessage(EngineState *s, int, int argc, reg_t *argv) { warning("Message: buffer %04x:%04x invalid or too small to hold the following text of %i bytes: '%s'", PRINT_REG(bufferReg), len, str.c_str()); // Set buffer to empty string if possible - buffer = kernelDerefString(s->segMan, bufferReg, 1); + buffer = s->segMan->kernelDerefString(bufferReg, 1); if (buffer) *buffer = 0; } @@ -788,7 +788,7 @@ reg_t kMessage(EngineState *s, int, int argc, reg_t *argv) { case K_MESSAGE_LASTMESSAGE: { MessageTuple msg = s->_msgState.getLastTuple(); int module = s->_msgState.getLastModule(); - byte *buffer = kernelDerefBulkPtr(s->segMan, argv[1], 10); + byte *buffer = s->segMan->kernelDerefBulkPtr(argv[1], 10); if (buffer) { WRITE_LE_UINT16(buffer, module); @@ -810,18 +810,18 @@ reg_t kMessage(EngineState *s, int, int argc, reg_t *argv) { } reg_t kSetQuitStr(EngineState *s, int, int argc, reg_t *argv) { - char *quitStr = kernelDerefString(s->segMan, argv[0]); + char *quitStr = s->segMan->kernelDerefString(argv[0]); debug("Setting quit string to '%s'", quitStr); return s->r_acc; } reg_t kStrSplit(EngineState *s, int, int argc, reg_t *argv) { - const char *format = kernelDerefString(s->segMan, argv[1]); - const char *sep = !argv[2].isNull() ? kernelDerefString(s->segMan, argv[2]) : NULL; + const char *format = s->segMan->kernelDerefString(argv[1]); + const char *sep = !argv[2].isNull() ? s->segMan->kernelDerefString(argv[2]) : NULL; Common::String str = s->strSplit(format, sep); // Make sure target buffer is large enough - char *buf = kernelDerefString(s->segMan, argv[0], str.size() + 1); + char *buf = s->segMan->kernelDerefString(argv[0], str.size() + 1); if (buf) { strcpy(buf, str.c_str()); diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index cafccc7e87..f516fa4093 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -930,6 +930,39 @@ byte *SegManager::dereference(reg_t pointer, int *size) { return mobj->dereference(pointer, size); } +static void *_kernel_dereference_pointer(SegManager *segMan, reg_t pointer, int entries, int align) { + int maxsize; + void *retval = segMan->dereference(pointer, &maxsize); + + if (!retval) + return NULL; + + if (pointer.offset & (align - 1)) { + warning("Unaligned pointer read: %04x:%04x expected with %d alignment", PRINT_REG(pointer), align); + return NULL; + } + + if (entries > maxsize) { + warning("Trying to dereference pointer %04x:%04x beyond end of segment", PRINT_REG(pointer)); + return NULL; + } + return retval; + +} + +byte *SegManager::kernelDerefBulkPtr(reg_t pointer, int entries) { + return (byte *)_kernel_dereference_pointer(this, pointer, entries, 1); +} + +reg_t *SegManager::kernelDerefRegPtr(reg_t pointer, int entries) { + return (reg_t *)_kernel_dereference_pointer(this, pointer, entries, sizeof(reg_t)); +} + +char *SegManager::kernelDerefString(reg_t pointer, int entries) { + return (char *)_kernel_dereference_pointer(this, pointer, entries, 1); +} + + byte *SegManager::allocDynmem(int size, const char *descr, reg_t *addr) { SegmentId seg; MemObject *mobj = allocSegment(MEM_OBJ_DYNMEM, &seg); diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h index 41ff119dcc..1945db1f74 100644 --- a/engines/sci/engine/seg_manager.h +++ b/engines/sci/engine/seg_manager.h @@ -333,6 +333,34 @@ public: byte *dereference(reg_t reg, int *size); /** + * Dereferences a heap pointer pointing to raw memory. + * @param pointer The pointer to dereference + * @parm entries The number of values expected (for checkingO + * @return A physical reference to the address pointed to, or NULL on error or + * if not enough entries were available. + */ + byte *kernelDerefBulkPtr(reg_t pointer, int entries); + + /** + * Dereferences a heap pointer pointing to a (list of) register(s). + * Ensures alignedness of data. + * @param pointer The pointer to dereference + * @parm entries The number of values expected (for checking) + * @return A physical reference to the address pointed to, or NULL on error or + * if not enough entries were available. + */ + reg_t *kernelDerefRegPtr(reg_t pointer, int entries); + + /** + * Dereferences a heap pointer pointing to raw memory. + * @param pointer The pointer to dereference + * @parm entries The number of values expected (for checking) + * @return A physical reference to the address pointed to, or NULL on error or + * if not enough entries were available. + */ + char *kernelDerefString(reg_t pointer, int entries = 0); + + /** * Finds a unique segment by type * @param type The type of the segment to find * @return The segment number, or -1 if the segment wasn't found diff --git a/engines/sci/engine/stringfrag.cpp b/engines/sci/engine/stringfrag.cpp index 0eb9546125..05a1b47cf2 100644 --- a/engines/sci/engine/stringfrag.cpp +++ b/engines/sci/engine/stringfrag.cpp @@ -103,7 +103,7 @@ static int internal_is_valid_stringfrag(EngineState *s, reg_t *buffer) { } int is_valid_stringfrag(EngineState *s, reg_t pos) { - reg_t *buffer = kernelDerefRegPtr(s->segMan, pos, 1); + reg_t *buffer = s->segMan->kernelDerefRegPtr(pos, 1); return internal_is_valid_stringfrag(s, buffer); } @@ -138,7 +138,7 @@ static int internal_stringfrag_length(EngineState *s, reg_t *buffer) { } int stringfrag_length(EngineState *s, reg_t pos) { - reg_t *buffer = kernelDerefRegPtr(s->segMan, pos, 1); + reg_t *buffer = s->segMan->kernelDerefRegPtr(pos, 1); return internal_stringfrag_length(s, buffer); } @@ -169,7 +169,7 @@ static void internal_stringfrag_to_ascii(EngineState *s, reg_t *buffer) { } void stringfrag_to_ascii(EngineState *s, reg_t pos) { - reg_t *buffer = kernelDerefRegPtr(s->segMan, pos, 1); + reg_t *buffer = s->segMan->kernelDerefRegPtr(pos, 1); internal_stringfrag_to_ascii(s, buffer); } @@ -191,7 +191,7 @@ static void internal_ascii_to_stringfrag(EngineState *s, reg_t *buffer) { } void ascii_to_stringfrag(EngineState *s, reg_t pos) { - reg_t *buffer = kernelDerefRegPtr(s->segMan, pos, 1); + reg_t *buffer = s->segMan->kernelDerefRegPtr(pos, 1); internal_ascii_to_stringfrag(s, buffer); } @@ -214,7 +214,7 @@ static void internal_stringfrag_append_char(EngineState *s, reg_t *buffer, unsig } void stringfrag_append_char(EngineState *s, reg_t pos, unsigned char c) { - reg_t *buffer = kernelDerefRegPtr(s->segMan, pos, 1); + reg_t *buffer = s->segMan->kernelDerefRegPtr(pos, 1); internal_stringfrag_append_char(s, buffer, c); } @@ -311,7 +311,7 @@ static void internal_stringfrag_insert_char(EngineState *s, reg_t *buffer, int p } void stringfrag_insert_char(EngineState *s, reg_t pos, int p, unsigned char c) { - reg_t *buffer = kernelDerefRegPtr(s->segMan, pos, 1); + reg_t *buffer = s->segMan->kernelDerefRegPtr(pos, 1); internal_stringfrag_insert_char(s, buffer, p, c); } @@ -343,7 +343,7 @@ static void internal_stringfrag_delete_char(EngineState *s, reg_t *buffer, int p } void stringfrag_delete_char(EngineState *s, reg_t pos, int p) { - reg_t *buffer = kernelDerefRegPtr(s->segMan, pos, 1); + reg_t *buffer = s->segMan->kernelDerefRegPtr(pos, 1); internal_stringfrag_delete_char(s, buffer, p); } @@ -360,8 +360,8 @@ void internal_stringfrag_strcpy(EngineState *s, reg_t *dest, reg_t *src) { } void stringfrag_strcpy(EngineState *s, reg_t dest, reg_t src) { - reg_t *destbuf = kernelDerefRegPtr(s->segMan, dest, 1); - reg_t *srcbuf = kernelDerefRegPtr(s->segMan, src, 1); + reg_t *destbuf = s->segMan->kernelDerefRegPtr(dest, 1); + reg_t *srcbuf = s->segMan->kernelDerefRegPtr(src, 1); internal_stringfrag_strcpy(s, destbuf, srcbuf); } @@ -388,8 +388,8 @@ void internal_stringfrag_strncpy(EngineState *s, reg_t *dest, reg_t *src, int le } void stringfrag_strncpy(EngineState *s, reg_t dest, reg_t src, int len) { - reg_t *destbuf = kernelDerefRegPtr(s->segMan, dest, 1); - reg_t *srcbuf = kernelDerefRegPtr(s->segMan, src, 1); + reg_t *destbuf = s->segMan->kernelDerefRegPtr(dest, 1); + reg_t *srcbuf = s->segMan->kernelDerefRegPtr(src, 1); internal_stringfrag_strncpy(s, destbuf, srcbuf, len); } @@ -416,8 +416,8 @@ int internal_stringfrag_strcmp(EngineState *s, reg_t *s1, reg_t *s2) { } void stringfrag_strcmp(EngineState *s, reg_t s1, reg_t s2) { - reg_t *s1buf = kernelDerefRegPtr(s->segMan, s1, 1); - reg_t *s2buf = kernelDerefRegPtr(s->segMan, s2, 1); + reg_t *s1buf = s->segMan->kernelDerefRegPtr(s1, 1); + reg_t *s2buf = s->segMan->kernelDerefRegPtr(s2, 1); internal_stringfrag_strcmp(s, s1buf, s2buf); } @@ -449,8 +449,8 @@ int internal_stringfrag_strncmp(EngineState *s, reg_t *s1, reg_t *s2, int len) { } void stringfrag_strncmp(EngineState *s, reg_t s1, reg_t s2, int len) { - reg_t *s1buf = kernelDerefRegPtr(s->segMan, s1, 1); - reg_t *s2buf = kernelDerefRegPtr(s->segMan, s2, 1); + reg_t *s1buf = s->segMan->kernelDerefRegPtr(s1, 1); + reg_t *s2buf = s->segMan->kernelDerefRegPtr(s2, 1); internal_stringfrag_strncmp(s, s1buf, s2buf, len); } diff --git a/engines/sci/gfx/menubar.cpp b/engines/sci/gfx/menubar.cpp index ab0b7d1375..2562ff7ba2 100644 --- a/engines/sci/gfx/menubar.cpp +++ b/engines/sci/gfx/menubar.cpp @@ -294,7 +294,7 @@ int Menubar::setAttribute(EngineState *s, int menu_nr, int item_nr, int attribut case MENU_ATTRIBUTE_SAID: if (value.segment) { item->_saidPos = value; - memcpy(item->_said, kernelDerefBulkPtr(s->segMan, value, 0), MENU_SAID_SPEC_SIZE); // Copy Said spec + memcpy(item->_said, s->segMan->kernelDerefBulkPtr(value, 0), MENU_SAID_SPEC_SIZE); // Copy Said spec item->_flags |= MENU_ATTRIBUTE_FLAGS_SAID; } else @@ -304,7 +304,7 @@ int Menubar::setAttribute(EngineState *s, int menu_nr, int item_nr, int attribut case MENU_ATTRIBUTE_TEXT: assert(value.segment); - item->_text = kernelDerefString(s->segMan, value); + item->_text = s->segMan->kernelDerefString(value); item->_textPos = value; break; |