BOOL iffgetchunk(strid_t stream, char *desttype, glui32 *ulength, glui32 file_size) { int i; glui32 c; unsigned char length[4]; c = glk_stream_get_position(stream); if(c & 1) { glk_get_char_stream(stream); /* Eat padding */ c++; } if(glk_get_buffer_stream(stream, desttype, 4) != 4) return FALSE; if(glk_get_buffer_stream(stream, (char *) length, 4) != 4) return FALSE; *ulength = MSBdecode4(length); for(i = 0; i < 4; i++) if(desttype[i] < 0x20 || desttype[i] > 0x7e) return FALSE; c += 8; return ((c + *ulength) <= file_size); }
void gitWithStream (strid_t str, git_uint32 cacheSize, git_uint32 undoSize) { char * game; git_uint32 gamePos; git_uint32 gameSize; git_uint32 remaining; char * ptr; char buffer [4]; glk_stream_set_position (str, 0, seekmode_Start); if (4 != glk_get_buffer_stream (str, buffer, 4)) fatalError ("can't read from game file stream"); if (readtag (buffer) == FORM) { giblorb_result_t result = handleBlorb (str); gamePos = result.data.startpos; gameSize = result.length; } else { gamePos = 0; glk_stream_set_position (str, 0, seekmode_End); gameSize = glk_stream_get_position (str); } game = malloc (gameSize); if (game == NULL) fatalError ("failed to allocate memory to store game file"); glk_stream_set_position (str, gamePos, seekmode_Start); remaining = gameSize; ptr = game; while (remaining > 0) { git_uint32 n = glk_get_buffer_stream (str, ptr, remaining); if (n == 0) fatalError ("failed to read entire game file"); remaining -= n; ptr += n; } gitMain ((git_uint8 *) game, gameSize, cacheSize, undoSize); free (game); }
size_t glkint_readchars(void *ptr, size_t len, z_file *fileref) { if (fileref->implementation == FILE_IMPLEMENTATION_STDIO) return z_filesys_interface_c.readchars(ptr, len, fileref); else return glk_get_buffer_stream((strid_t)fileref->file_object, ptr, len); }
int runblorb(char *path, char *game) { char magic[4]; strid_t file; giblorb_result_t res; giblorb_err_t err; giblorb_map_t *map; sprintf(tmp, "Could not load Blorb file:\n%s\n", game); file = glkunix_stream_open_pathname(game, 0, 0); if (!file) { winmsg(tmp); return FALSE; } err = giblorb_create_map(file, &map); if (err) { winmsg(tmp); return FALSE; } err = giblorb_load_resource(map, giblorb_method_FilePos, &res, giblorb_ID_Exec, 0); if (err) { winmsg(tmp); return FALSE; } glk_stream_set_position(file, res.data.startpos, 0); glk_get_buffer_stream(file, magic, 4); switch (res.chunktype) { case ID_ZCOD: if (strlen(terp)) return winterp(path, strcat(exe,terp), flags, game); else if (magic[0] == 6) return winterp(path, strcat(exe,T_ZSIX), flags, game); else return winterp(path, strcat(exe,T_ZCODE), flags, game); break; case ID_GLUL: if (strlen(terp)) return winterp(path, strcat(exe,terp), flags, game); else return winterp(path, strcat(exe,T_GLULX), flags, game); break; default: sprintf(tmp, "Unknown game type in Blorb file:\n%s\n", game); winmsg(tmp); } return FALSE; }
void Processor::z_restore() { bool success = false; if (zargc != 0) { frefid_t ref = glk_fileref_create_by_prompt(fileusage_Data | fileusage_BinaryMode, filemode_Read, 0); if (ref != nullptr) { // Write data strid_t f = glk_stream_open_file(ref, filemode_Read); glk_get_buffer_stream(f, (char *)zmp + zargs[0], zargs[1]); glk_stream_close(f); success = true; } } else { success = loadGame().getCode() == Common::kNoError; } int result = success ? 2 : -1; if (h_version <= V3) branch(result); else store(result); }
/* Translate character-oriented functions to buffer-oriented ones */ glsi32 glk_get_char_stream(strid_t str) { char c; if(glk_get_buffer_stream(str, &c, 1) == 1) return (unsigned char) c; return -1; }
void glk_main () { strid_t file = mac_gamefile; size_t size, remaining; git_uint8 * data; git_uint8 * ptr; glk_stream_set_position (file, 0, seekmode_End); size = glk_stream_get_position (file); glk_stream_set_position (file, 0, seekmode_Start); data = malloc (size); ptr = data; remaining = size; while (remaining > 0) { size_t n = glk_get_buffer_stream (file, (char *) ptr, remaining); if (n == 0) { printf ("Can't read file."); exit(1); } remaining -= n; ptr += n; } glk_stream_close (file, NULL); git (data, size, CACHE_SIZE, UNDO_SIZE); }
glui32 fillstruct(strid_t stream, const unsigned *info, glui32 *dest, glui32 (*special)(strid_t)) { unsigned char buffer[4]; unsigned e; glui32 len = 0;; for(e = 0; info[e]; e++) { if(info[e] == 0x8000) { *dest++ = special(stream); len++; } else if(info[e] > 4) { unsigned i; for(i = 0; i < info[e]; i++) { *dest++ = glk_get_char_stream(stream); len++; } } else { glk_get_buffer_stream(stream, (char *) buffer, info[e]); switch(info[e]) { case 1: *dest = MSBdecode1(buffer); break; case 2: *dest = MSBdecode2(buffer); break; case 3: *dest = MSBdecode3(buffer); break; case 4: *dest = MSBdecode4(buffer); break; } dest++; len+=info[e]; } } return len; }
glui32 perform_verify() { glui32 len, checksum, newlen; unsigned char buf[4]; glui32 val, newsum, ix; len = gamefile_len; if (len < 256 || (len & 0xFF) != 0) return 1; glk_stream_set_position(gamefile, gamefile_start, seekmode_Start); newsum = 0; /* Read the header */ for (ix=0; ix<9; ix++) { newlen = glk_get_buffer_stream(gamefile, (char *)buf, 4); if (newlen != 4) return 1; val = Read4(buf); if (ix == 3) { if (len != val) return 1; } if (ix == 8) checksum = val; else newsum += val; } /* Read everything else */ for (; ix < len/4; ix++) { newlen = glk_get_buffer_stream(gamefile, (char *)buf, 4); if (newlen != 4) return 1; val = Read4(buf); newsum += val; } if (newsum != checksum) return 1; return 0; }
/* db_restart - restart the current game */ int db_restart() { glk_stream_set_position(datafd,saveoff,seekmode_Start); if (glk_get_buffer_stream(datafd,save,slen) != slen) return (NIL); complement(save,slen); setvalue(V_OCOUNT,ocount); longjmp(restart,1); }
giblorb_err_t giblorb_load_chunk_by_number(giblorb_map_t *map, glui32 method, giblorb_result_t *res, glui32 chunknum) { giblorb_chunkdesc_t *chu; // XCode: removed "chunknum < 0" test to shut up compiler warning if (chunknum >= map->numchunks) return giblorb_err_NotFound; chu = &(map->chunks[chunknum]); switch (method) { case giblorb_method_DontLoad: /* do nothing */ break; case giblorb_method_FilePos: res->data.startpos = chu->datpos; break; case giblorb_method_Memory: if (!chu->ptr) { glui32 readlen; void *dat = giblorb_malloc(chu->len); if (!dat) return giblorb_err_Alloc; glk_stream_set_position(map->file, chu->datpos, seekmode_Start); readlen = glk_get_buffer_stream(map->file, dat, chu->len); if (readlen != chu->len) return giblorb_err_Read; chu->ptr = dat; } res->data.ptr = chu->ptr; break; } res->chunknum = chunknum; res->length = chu->len; res->chunktype = chu->type; return giblorb_err_None; }
glui32 glk_get_line_stream(strid_t str, char *buf, glui32 len) { glui32 readlen; if(len <= 0) return 0; len--; for(readlen = 0; readlen < len && buf[readlen] != '\n'; readlen++) { if(glk_get_buffer_stream(str, buf + readlen, 1) != 1) break; } buf[readlen] = '\0'; return readlen; }
static int read_buffer(dest_t *dest, unsigned char *ptr, glui32 len) { glui32 newlen; if (dest->ismem) { memcpy(ptr, dest->ptr+dest->pos, len); } else { newlen = glk_get_buffer_stream(dest->str, (char *)ptr, len); if (newlen != len) return 1; } dest->pos += len; return 0; }
void op_restore5(void) { int i; char filename[256]; int length; strid_t file; offset end; switch(numoperands) { case 0: op_restore4(); return; case 1: n_show_error(E_INSTR, "call restore with bad number of operands", numoperands); mop_store_result(0); return; case 2: file = n_file_prompt(fileusage_Data | fileusage_BinaryMode, filemode_Read); break; default: length = LOBYTE(operand[2]); if(length > 13) n_show_port(E_INSTR, "save with filename > 13 characters", length); for(i = 0; i < length; i++) filename[i] = glk_char_to_upper(LOBYTE(operand[2] + 1 + i)); filename[length] = 0; file = n_file_name(fileusage_Data | fileusage_BinaryMode, filemode_Read, filename); } if(!file) { mop_store_result(0); return; } end = ((offset) operand[0]) + operand[1]; if(end > 65535 || end > dynamic_size) { n_show_error(E_MEMORY, "attempt to restore data out of range", end); mop_store_result(0); return; } length = glk_get_buffer_stream(file, (char *) z_memory + operand[0], operand[1]); glk_stream_close(file, NULL); mop_store_result(length); }
int glkunix_startup_code_glulxe(glkunix_startup_t *data) { /* It turns out to be more convenient if we return TRUE from here, even when an error occurs, and display an error in glk_main(). */ char *cx; unsigned char buf[12]; int res; if (data->argc <= 1) { ginit_err = "You must supply the name of a game file."; return FALSE; } cx = data->argv[1]; gamefile = glkunix_stream_open_pathname(cx, FALSE, 1); if (!gamefile) { ginit_err = "The game file could not be opened."; ginit_err2 = cx; return TRUE; } /* Now we have to check to see if it's a Blorb file. */ glk_stream_set_position(gamefile, 0, seekmode_Start); res = glk_get_buffer_stream(gamefile, (char *)buf, 12); if (!res) { ginit_err = "The data in this stand-alone game is too short to read."; return TRUE; } if (buf[0] == 'G' && buf[1] == 'l' && buf[2] == 'u' && buf[3] == 'l') { locate_gamefile(FALSE); return TRUE; } else if (buf[0] == 'F' && buf[1] == 'O' && buf[2] == 'R' && buf[3] == 'M' && buf[8] == 'I' && buf[9] == 'F' && buf[10] == 'R' && buf[11] == 'S') { locate_gamefile(TRUE); return TRUE; } else { ginit_err = "This is neither a Glulx game file nor a Blorb file " "which contains one."; return TRUE; } }
BOOL check_game_for_save(strid_t gamefile, zword release, const char serial[6], zword checksum) { int i; unsigned char header[64]; glk_stream_set_position(gamefile, 0, seekmode_Start); if(glk_get_buffer_stream(gamefile, (char *) header, 64) != 64) return FALSE; if(header[HD_ZVERSION] == 0 || header[HD_ZVERSION] > 8) return FALSE; if(MSBdecodeZ(header + HD_RELNUM) != release) return FALSE; if(MSBdecodeZ(header + HD_CHECKSUM) != checksum) return FALSE; for(i = 0; i < 6; i++) { if(header[HD_SERNUM + i] != serial[i]) return FALSE; } return TRUE; }
strid_t intd_filehandle_open(strid_t savefile, glui32 operating_id, glui32 contents_id, glui32 interp_id, glui32 length) { char *name; strid_t str; if(operating_id != 0x554e4958 /* 'UNIX' */) return 0; if(contents_id != 0) return 0; if(interp_id != 0x20202020 /* ' ' */) return 0; name = (char *) n_malloc(length+1); glk_get_buffer_stream(savefile, name, length); name[length] = 0; str = glkunix_stream_open_pathname(name, fileusage_Data | fileusage_BinaryMode, 0); if(str) set_game_filename(name); n_free(name); return str; }
static Boolean startup_when_builtin() { unsigned char buf[12]; int res; glk_stream_set_position(gamefile, 0, seekmode_Start); res = glk_get_buffer_stream(gamefile, (char *)buf, 12); if (!res) { init_err = "The data in this stand-alone game is too short to read."; return FALSE; } if (buf[0] == 'G' && buf[1] == 'l' && buf[2] == 'u' && buf[3] == 'l') { return locate_gamefile(FALSE); } else if (buf[0] == 'F' && buf[1] == 'O' && buf[2] == 'R' && buf[3] == 'M' && buf[8] == 'I' && buf[9] == 'F' && buf[10] == 'R' && buf[11] == 'S') { return locate_gamefile(TRUE); } else { init_err = "This is neither a Glulx game file nor a Blorb file which contains one."; return FALSE; } }
/* init_serial(): Set up the undo chain and anything else that needs to be set up. */ int init_serial() { undo_chain_num = 0; undo_chain_size = max_undo_level; undo_chain = (unsigned char **)glulx_malloc(sizeof(unsigned char *) * undo_chain_size); if (!undo_chain) return FALSE; #ifdef SERIALIZE_CACHE_RAM { glui32 len = (endmem - ramstart); glui32 res; ramcache = (unsigned char *)glulx_malloc(sizeof(unsigned char *) * len); if (!ramcache) return FALSE; glk_stream_set_position(gamefile, gamefile_start+ramstart, seekmode_Start); res = glk_get_buffer_stream(gamefile, (char *)ramcache, len); if (res != len) return FALSE; } #endif /* SERIALIZE_CACHE_RAM */ return TRUE; }
int glkunix_startup_code(glkunix_startup_t *data) { /* It turns out to be more convenient if we return TRUE from here, even when an error occurs, and display an error in glk_main(). */ int ix; char *filename = NULL; char *gameinfofilename = NULL; int gameinfoloaded = FALSE; unsigned char buf[12]; int res; #ifdef GARGLK char *cx; #endif #ifdef GARGLK garglk_set_program_name("Glulxe 0.5.2"); garglk_set_program_info("Glulxe 0.5.2 by Andrew Plotkin"); #endif /* Parse out the arguments. They've already been checked for validity, and the library-specific ones stripped out. As usual for Unix, the zeroth argument is the executable name. */ for (ix=1; ix<data->argc; ix++) { #if VM_PROFILING if (!strcmp(data->argv[ix], "--profile")) { ix++; if (ix<data->argc) { strid_t profstr = glkunix_stream_open_pathname_gen(data->argv[ix], TRUE, FALSE, 1); if (!profstr) { init_err = "Unable to open profile output file."; init_err2 = data->argv[ix]; return TRUE; } setup_profile(profstr, NULL); } continue; } if (!strcmp(data->argv[ix], "--profcalls")) { profile_set_call_counts(TRUE); continue; } #endif /* VM_PROFILING */ #if VM_DEBUGGER if (!strcmp(data->argv[ix], "--gameinfo")) { ix++; if (ix<data->argc) { gameinfofilename = data->argv[ix]; } continue; } if (!strcmp(data->argv[ix], "--cpu")) { debugger_track_cpu(TRUE); continue; } if (!strcmp(data->argv[ix], "--starttrap")) { debugger_set_start_trap(TRUE); continue; } if (!strcmp(data->argv[ix], "--quittrap")) { debugger_set_quit_trap(TRUE); continue; } if (!strcmp(data->argv[ix], "--crashtrap")) { debugger_set_crash_trap(TRUE); continue; } #endif /* VM_DEBUGGER */ if (filename) { init_err = "You must supply exactly one game file."; return TRUE; } filename = data->argv[ix]; } if (!filename) { init_err = "You must supply the name of a game file."; return TRUE; } gamefile = glkunix_stream_open_pathname(filename, FALSE, 1); if (!gamefile) { init_err = "The game file could not be opened."; init_err2 = filename; return TRUE; } #ifdef GARGLK cx = strrchr(data->argv[1], '/'); if (!cx) cx = strrchr(data->argv[1], '\\'); garglk_set_story_name(cx ? cx + 1 : data->argv[1]); #endif #if VM_DEBUGGER if (gameinfofilename) { strid_t debugstr = glkunix_stream_open_pathname_gen(gameinfofilename, FALSE, FALSE, 1); if (!debugstr) { nonfatal_warning("Unable to open gameinfo file for debug data."); } else { int bres = debugger_load_info_stream(debugstr); glk_stream_close(debugstr, NULL); if (!bres) nonfatal_warning("Unable to parse game info."); else gameinfoloaded = TRUE; } } /* Report debugging available, whether a game info file is loaded or not. */ gidebug_debugging_available(debugger_cmd_handler, debugger_cycle_handler); #endif /* VM_DEBUGGER */ /* Now we have to check to see if it's a Blorb file. */ glk_stream_set_position(gamefile, 0, seekmode_Start); res = glk_get_buffer_stream(gamefile, (char *)buf, 12); if (!res) { init_err = "The data in this stand-alone game is too short to read."; return TRUE; } if (buf[0] == 'G' && buf[1] == 'l' && buf[2] == 'u' && buf[3] == 'l') { /* Load game directly from file. */ locate_gamefile(FALSE); return TRUE; } else if (buf[0] == 'F' && buf[1] == 'O' && buf[2] == 'R' && buf[3] == 'M' && buf[8] == 'I' && buf[9] == 'F' && buf[10] == 'R' && buf[11] == 'S') { /* Load game from a chunk in the Blorb file. */ locate_gamefile(TRUE); #if VM_DEBUGGER /* Load the debug info from the Blorb, if it wasn't loaded from a file. */ if (!gameinfoloaded) { glui32 giblorb_ID_Dbug = giblorb_make_id('D', 'b', 'u', 'g'); giblorb_err_t err; giblorb_result_t blorbres; err = giblorb_load_chunk_by_type(giblorb_get_resource_map(), giblorb_method_FilePos, &blorbres, giblorb_ID_Dbug, 0); if (!err) { int bres = debugger_load_info_chunk(gamefile, blorbres.data.startpos, blorbres.length); if (!bres) nonfatal_warning("Unable to parse game info."); else gameinfoloaded = TRUE; } } #endif /* VM_DEBUGGER */ return TRUE; } else { init_err = "This is neither a Glulx game file nor a Blorb file " "which contains one."; return TRUE; } }
void gidispatch_call(glui32 funcnum, glui32 numargs, gluniversal_t *arglist) { gidispatch_function_t *gidispatch_function; char *prototype; int argument = 0; int slot = 0; gidispatch_function = gidispatch_get_function_by_id(funcnum); prototype = gidispatch_prototype(funcnum); printf("DEBUG: dispatch call name=%s, prototype=%s, numargs=%u -- ", gidispatch_function->name, prototype, (unsigned int)numargs); if (strcmp(prototype, "4IuIuIuIs") == 0) { printf("%u, %u, %u, %d\n", arglist[0].uint, arglist[1].uint, arglist[2].uint, arglist[3].sint); } else if (strcmp(prototype, "3IuIu:Iu") == 0) { printf("%u, %u, returning a glui32\n", arglist[0].uint, arglist[1].uint); } else if (strcmp(prototype, "3Qa<Iu:Qa") == 0) { printf("win at %p, outref to a glui32, returning a winid_t\n", arglist[0].opaqueref); } else if (strcmp(prototype, "3Qc<Iu:Qc") == 0) { printf("fileref at %p, outref to a glui32, returning a frefid_t\n", arglist[0].opaqueref); } else if (strcmp(prototype, "1Qa:") == 0) { printf("win at %p\n", arglist[0].opaqueref); } else if (strcmp(prototype, "6QaIuIuIuIu:Qa") == 0) { printf("win at %p, %u, %u, %u, %u, returning a winid_t\n", arglist[0].opaqueref, arglist[1].uint, arglist[2].uint, arglist[3].uint, arglist[4].uint); } else if (strcmp(prototype, "4IuIuIuIs:") == 0) { printf("%u, %u, %u, %d\n", arglist[0].uint, arglist[1].uint, arglist[2].uint, arglist[3].sint); } else if (strcmp(prototype, "1Qb:") == 0) { printf("stream at %p\n", arglist[0].opaqueref); } else if (strcmp(prototype, "1Iu:") == 0) { printf("%u\n", arglist[0].uint); } else if (strcmp(prototype, "2Qb<[2IuIu]:") == 0) { printf("stream at %p, some struct stuff here\n", arglist[0].opaqueref); } else if (strcmp(prototype, "3IuIuIu:") == 0) { printf("%u, %u, %u\n", arglist[0].uint, arglist[1].uint, arglist[2].uint); } else if (strcmp(prototype, "1:Qb") == 0) { printf("returning a strid_t\n"); } else if (strcmp(prototype, "4&+#!IuIuIu:Qb") == 0) { printf("retained, nonnull, array of glui32 at %p for length %u, %u, %u, returning a strid_t\n", arglist[1].array, arglist[2].uint, arglist[3].uint, arglist[4].uint); } else if (strcmp(prototype, "2Qc:Iu") == 0) { printf("fileref at %p, returning a glui32\n", arglist[0].opaqueref); } else if (strcmp(prototype, "1<+[4IuQaIuIu]:") == 0) { printf("some struct stuff here, nonnull\n"); } else if (strcmp(prototype, "1:Qb") == 0) { printf("returning a strid_t\n"); } else if (strcmp(prototype, "2Qb:Is") == 0) { printf("stream at %p, returning a glsi32\n", arglist[0].opaqueref); } else if (strcmp(prototype, "2Qc:Iu") == 0) { printf("fileref at %p, returning a glui32\n", arglist[0].opaqueref); } else if (strcmp(prototype, "3Qa&+#!CnIu:") == 0) { printf("win at %p, retained, nonnull, array of char at %p for length %u, %u\n", arglist[0].opaqueref, arglist[2].array, arglist[3].uint, arglist[4].uint); } else if (strcmp(prototype, "3Qb<Iu:Qb") == 0) { printf("stream at %p, outref to a glui32, returning a strid_t\n", arglist[0].opaqueref); } else if (strcmp(prototype, "4&+#!CnIuIu:Qb") == 0) { printf("retained, nonnull, array of char at %p for length %u, %u, %u, returning a strid_t\n", arglist[1].array, arglist[2].uint, arglist[3].uint, arglist[4].uint); } else if (strcmp(prototype, "4&+#!IuIuIu:Qb") == 0) { printf("retained, nonnull, array of glui32 at %p for length %u, %u, %u, returning a strid_t\n", arglist[1].array, arglist[2].uint, arglist[3].uint, arglist[4].uint); } else if (strcmp(prototype, "4IuSIu:Qc") == 0) { printf("%u, %s, %u, returning a frefid_t\n", arglist[0].uint, arglist[1].charstr, arglist[2].uint); } else if (strcmp(prototype, "4QcIuIu:Qb") == 0) { printf("fileref at %p, %u, %u, returning a strid_t\n", arglist[0].opaqueref, arglist[1].uint, arglist[2].uint); } else if (strcmp(prototype, "3Qa<Iu<Iu:") == 0) { printf("win at %p, outref to a glui32, outref to a glui32\n", arglist[0].opaqueref); } else if (strcmp(prototype, "6QaIuIsIsIuIu:") == 0) { printf("win at %p, %u, %d, %d, %u, %u\n", arglist[0].opaqueref, arglist[1].uint, arglist[2].sint, arglist[3].sint, arglist[4].uint, arglist[5].uint); } else if (strcmp(prototype, "4Iu<Iu<Iu:Iu") == 0) { printf("%u, outref to a glui32, outref to a glui32, returning a glui32\n", arglist[0].uint); } else { printf("unhandled prototype\n"); } switch (funcnum) { case 0x0004: /* gestalt */ arglist[3].uint = glk_gestalt(arglist[0].uint, arglist[1].uint); break; case 0x0005: /* gestalt_ext */ if (arglist[2].ptrflag) { arglist[6].uint = glk_gestalt_ext(arglist[0].uint, arglist[1].uint, arglist[3].array, arglist[4].uint); } else { arglist[4].uint = glk_gestalt_ext(arglist[0].uint, arglist[1].uint, NULL, 0); } break; case 0x0020: /* window_iterate */ if (arglist[1].ptrflag) arglist[4].opaqueref = glk_window_iterate(arglist[0].opaqueref, &arglist[2].uint); else arglist[3].opaqueref = glk_window_iterate(arglist[0].opaqueref, NULL); break; case 0x0023: /* window_open */ arglist[6].opaqueref = glk_window_open(arglist[0].opaqueref, arglist[1].uint, arglist[2].uint, arglist[3].uint, arglist[4].uint); break; case 0x0025: /* window_get_size */ { int ix = 1; glui32 *ptr1, *ptr2; if (!arglist[ix].ptrflag) { ptr1 = NULL; } else { ix++; ptr1 = &(arglist[ix].uint); } ix++; if (!arglist[ix].ptrflag) { ptr2 = NULL; } else { ix++; ptr2 = &(arglist[ix].uint); } ix++; glk_window_get_size(arglist[0].opaqueref, ptr1, ptr2); } break; case 0x0028: /* window_get_type */ arglist[2].uint = glk_window_get_type(arglist[0].opaqueref); break; case 0x002A: /* window_clear */ glk_window_clear(arglist[0].opaqueref); break; case 0x002B: /* window_move_cursor */ glk_window_move_cursor(arglist[0].opaqueref, arglist[1].uint, arglist[2].uint); break; case 0x002F: /* set_window */ glk_set_window(arglist[0].opaqueref); break; case 0x0040: /* stream_iterate */ if (arglist[1].ptrflag) arglist[4].opaqueref = glk_stream_iterate(arglist[0].opaqueref, &arglist[2].uint); else arglist[3].opaqueref = glk_stream_iterate(arglist[0].opaqueref, NULL); break; case 0x0042: /* stream_open_file */ arglist[4].opaqueref = glk_stream_open_file(arglist[0].opaqueref, arglist[1].uint, arglist[2].uint); break; case 0x0043: /* stream_open_memory */ if (arglist[0].ptrflag) arglist[6].opaqueref = glk_stream_open_memory(arglist[1].array, arglist[2].uint, arglist[3].uint, arglist[4].uint); else arglist[4].opaqueref = glk_stream_open_memory(NULL, 0, arglist[1].uint, arglist[2].uint); break; case 0x0044: /* stream_close */ if (arglist[1].ptrflag) { stream_result_t dat; glk_stream_close(arglist[0].opaqueref, &dat); arglist[2].uint = dat.readcount; arglist[3].uint = dat.writecount; } else { glk_stream_close(arglist[0].opaqueref, NULL); } break; case 0x0047: /* stream_set_current */ glk_stream_set_current(arglist[0].opaqueref); break; case 0x0048: /* stream_get_current */ arglist[1].opaqueref = glk_stream_get_current(); break; case 0x0061: /* fileref_create_by_name */ arglist[4].opaqueref = glk_fileref_create_by_name(arglist[0].uint, arglist[1].charstr, arglist[2].uint); break; case 0x0062: /* fileref_create_by_prompt */ arglist[4].opaqueref = glk_fileref_create_by_prompt(arglist[0].uint, arglist[1].uint, arglist[2].uint); break; case 0x0067: /* fileref_does_file_exist */ arglist[2].uint = glk_fileref_does_file_exist(arglist[0].opaqueref); break; case 0x0086: /* set_style */ glk_set_style(arglist[0].uint); break; case 0x0087: /* set_style_stream */ glk_set_style_stream(arglist[0].opaqueref, arglist[1].uint); break; case 0x0090: /* get_char_stream */ arglist[2].sint = glk_get_char_stream(arglist[0].opaqueref); break; case 0x00B0: /* stylehint_set */ glk_stylehint_set(arglist[0].uint, arglist[1].uint, arglist[2].uint, arglist[3].sint); break; case 0x00C0: /* select */ if (arglist[0].ptrflag) { event_t dat; glk_select(&dat); arglist[1].uint = dat.type; arglist[2].opaqueref = dat.win; arglist[3].uint = dat.val1; arglist[4].uint = dat.val2; } else { glk_select(NULL); } break; case 0x00D0: /* request_line_event */ if (arglist[1].ptrflag) glk_request_line_event(arglist[0].opaqueref, arglist[2].array, arglist[3].uint, arglist[4].uint); else glk_request_line_event(arglist[0].opaqueref, NULL, 0, arglist[2].uint); break; case 0x00D2: /* request_char_event */ glk_request_char_event(arglist[0].opaqueref); break; case 0x00E0: /* image_get_info */ { int ix = 1; glui32 *ptr1, *ptr2; if (!arglist[ix].ptrflag) { ptr1 = NULL; } else { ix++; ptr1 = &(arglist[ix].uint); } ix++; if (!arglist[ix].ptrflag) { ptr2 = NULL; } else { ix++; ptr2 = &(arglist[ix].uint); } ix++; ix++; arglist[ix].uint = glk_image_get_info(arglist[0].uint, ptr1, ptr2); } break; case 0x00E1: /* image_draw */ arglist[5].uint = glk_image_draw(arglist[0].opaqueref, arglist[1].uint, arglist[2].sint, arglist[3].sint); break; case 0x00E2: /* image_draw_scaled */ arglist[7].uint = glk_image_draw_scaled(arglist[0].opaqueref, arglist[1].uint, arglist[2].sint, arglist[3].sint, arglist[4].uint, arglist[5].uint); break; case 0x00EA: /* window_fill_rect */ glk_window_fill_rect(arglist[0].opaqueref, arglist[1].uint, arglist[2].sint, arglist[3].sint, arglist[4].uint, arglist[5].uint); break; case 0x0128: /* put_char_uni */ glk_put_char_uni(arglist[0].uint); break; case 0x0139: /* stream_open_memory_uni */ if (arglist[0].ptrflag) arglist[6].opaqueref = glk_stream_open_memory_uni(arglist[1].array, arglist[2].uint, arglist[3].uint, arglist[4].uint); else arglist[4].opaqueref = glk_stream_open_memory_uni(NULL, 0, arglist[1].uint, arglist[2].uint); break; default: printf("Unhandled call to %s via dispatch\n", gidispatch_function->name); #if 0 case 0x0001: /* exit */ glk_exit(); break; case 0x0002: /* set_interrupt_handler */ /* cannot be invoked through dispatch layer */ break; case 0x0003: /* tick */ glk_tick(); break; case 0x0021: /* window_get_rock */ arglist[2].uint = glk_window_get_rock(arglist[0].opaqueref); break; case 0x0022: /* window_get_root */ arglist[1].opaqueref = glk_window_get_root(); break; case 0x0024: /* window_close */ if (arglist[1].ptrflag) { stream_result_t dat; glk_window_close(arglist[0].opaqueref, &dat); arglist[2].uint = dat.readcount; arglist[3].uint = dat.writecount; } else { glk_window_close(arglist[0].opaqueref, NULL); } break; case 0x0026: /* window_set_arrangement */ glk_window_set_arrangement(arglist[0].opaqueref, arglist[1].uint, arglist[2].uint, arglist[3].opaqueref); break; case 0x0027: /* window_get_arrangement */ { int ix = 1; glui32 *ptr1, *ptr2; winid_t *ptr3; if (!arglist[ix].ptrflag) { ptr1 = NULL; } else { ix++; ptr1 = &(arglist[ix].uint); } ix++; if (!arglist[ix].ptrflag) { ptr2 = NULL; } else { ix++; ptr2 = &(arglist[ix].uint); } ix++; if (!arglist[ix].ptrflag) { ptr3 = NULL; } else { ix++; ptr3 = (winid_t *)(&(arglist[ix].opaqueref)); } ix++; glk_window_get_arrangement(arglist[0].opaqueref, ptr1, ptr2, ptr3); } break; case 0x0029: /* window_get_parent */ arglist[2].opaqueref = glk_window_get_parent(arglist[0].opaqueref); break; case 0x002C: /* window_get_stream */ arglist[2].opaqueref = glk_window_get_stream(arglist[0].opaqueref); break; case 0x002D: /* window_set_echo_stream */ glk_window_set_echo_stream(arglist[0].opaqueref, arglist[1].opaqueref); break; case 0x002E: /* window_get_echo_stream */ arglist[2].opaqueref = glk_window_get_echo_stream(arglist[0].opaqueref); break; case 0x0030: /* window_get_sibling */ arglist[2].opaqueref = glk_window_get_sibling(arglist[0].opaqueref); break; case 0x0041: /* stream_get_rock */ arglist[2].uint = glk_stream_get_rock(arglist[0].opaqueref); break; case 0x0045: /* stream_set_position */ glk_stream_set_position(arglist[0].opaqueref, arglist[1].sint, arglist[2].uint); break; case 0x0046: /* stream_get_position */ arglist[2].uint = glk_stream_get_position(arglist[0].opaqueref); break; case 0x0048: /* stream_get_current */ arglist[1].opaqueref = glk_stream_get_current(); break; case 0x0060: /* fileref_create_temp */ arglist[3].opaqueref = glk_fileref_create_temp(arglist[0].uint, arglist[1].uint); break; case 0x0063: /* fileref_destroy */ glk_fileref_destroy(arglist[0].opaqueref); break; case 0x0064: /* fileref_iterate */ if (arglist[1].ptrflag) arglist[4].opaqueref = glk_fileref_iterate(arglist[0].opaqueref, &arglist[2].uint); else arglist[3].opaqueref = glk_fileref_iterate(arglist[0].opaqueref, NULL); break; case 0x0065: /* fileref_get_rock */ arglist[2].uint = glk_fileref_get_rock(arglist[0].opaqueref); break; case 0x0066: /* fileref_delete_file */ glk_fileref_delete_file(arglist[0].opaqueref); break; case 0x0068: /* fileref_create_from_fileref */ arglist[4].opaqueref = glk_fileref_create_from_fileref(arglist[0].uint, arglist[1].opaqueref, arglist[2].uint); break; case 0x0080: /* put_char */ glk_put_char(arglist[0].uch); break; case 0x0081: /* put_char_stream */ glk_put_char_stream(arglist[0].opaqueref, arglist[1].uch); break; case 0x0082: /* put_string */ glk_put_string(arglist[0].charstr); break; case 0x0083: /* put_string_stream */ glk_put_string_stream(arglist[0].opaqueref, arglist[1].charstr); break; case 0x0084: /* put_buffer */ if (arglist[0].ptrflag) glk_put_buffer(arglist[1].array, arglist[2].uint); else glk_put_buffer(NULL, 0); break; case 0x0085: /* put_buffer_stream */ if (arglist[1].ptrflag) glk_put_buffer_stream(arglist[0].opaqueref, arglist[2].array, arglist[3].uint); else glk_put_buffer_stream(arglist[0].opaqueref, NULL, 0); break; case 0x0091: /* get_line_stream */ if (arglist[1].ptrflag) arglist[5].uint = glk_get_line_stream(arglist[0].opaqueref, arglist[2].array, arglist[3].uint); else arglist[3].uint = glk_get_line_stream(arglist[0].opaqueref, NULL, 0); break; case 0x0092: /* get_buffer_stream */ if (arglist[1].ptrflag) arglist[5].uint = glk_get_buffer_stream(arglist[0].opaqueref, arglist[2].array, arglist[3].uint); else arglist[3].uint = glk_get_buffer_stream(arglist[0].opaqueref, NULL, 0); break; case 0x00A0: /* char_to_lower */ arglist[2].uch = glk_char_to_lower(arglist[0].uch); break; case 0x00A1: /* char_to_upper */ arglist[2].uch = glk_char_to_upper(arglist[0].uch); break; case 0x00B1: /* stylehint_clear */ glk_stylehint_clear(arglist[0].uint, arglist[1].uint, arglist[2].uint); break; case 0x00B2: /* style_distinguish */ arglist[4].uint = glk_style_distinguish(arglist[0].opaqueref, arglist[1].uint, arglist[2].uint); break; case 0x00B3: /* style_measure */ if (arglist[3].ptrflag) arglist[6].uint = glk_style_measure(arglist[0].opaqueref, arglist[1].uint, arglist[2].uint, &(arglist[4].uint)); else arglist[5].uint = glk_style_measure(arglist[0].opaqueref, arglist[1].uint, arglist[2].uint, NULL); break; case 0x00C1: /* select_poll */ if (arglist[0].ptrflag) { event_t dat; glk_select_poll(&dat); arglist[1].uint = dat.type; arglist[2].opaqueref = dat.win; arglist[3].uint = dat.val1; arglist[4].uint = dat.val2; } else { glk_select_poll(NULL); } break; case 0x00D1: /* cancel_line_event */ if (arglist[1].ptrflag) { event_t dat; glk_cancel_line_event(arglist[0].opaqueref, &dat); arglist[2].uint = dat.type; arglist[3].opaqueref = dat.win; arglist[4].uint = dat.val1; arglist[5].uint = dat.val2; } else { glk_cancel_line_event(arglist[0].opaqueref, NULL); } break; case 0x00D3: /* cancel_char_event */ glk_cancel_char_event(arglist[0].opaqueref); break; case 0x00D4: /* request_mouse_event */ glk_request_mouse_event(arglist[0].opaqueref); break; case 0x00D5: /* cancel_mouse_event */ glk_cancel_mouse_event(arglist[0].opaqueref); break; case 0x00D6: /* request_timer_events */ glk_request_timer_events(arglist[0].uint); break; #ifdef GLK_MODULE_IMAGE case 0x00E8: /* window_flow_break */ glk_window_flow_break(arglist[0].opaqueref); break; case 0x00E9: /* window_erase_rect */ glk_window_erase_rect(arglist[0].opaqueref, arglist[1].sint, arglist[2].sint, arglist[3].uint, arglist[4].uint); break; case 0x00EB: /* window_set_background_color */ glk_window_set_background_color(arglist[0].opaqueref, arglist[1].uint); break; #endif /* GLK_MODULE_IMAGE */ #ifdef GLK_MODULE_SOUND case 0x00F0: /* schannel_iterate */ if (arglist[1].ptrflag) arglist[4].opaqueref = glk_schannel_iterate(arglist[0].opaqueref, &arglist[2].uint); else arglist[3].opaqueref = glk_schannel_iterate(arglist[0].opaqueref, NULL); break; case 0x00F1: /* schannel_get_rock */ arglist[2].uint = glk_schannel_get_rock(arglist[0].opaqueref); break; case 0x00F2: /* schannel_create */ arglist[2].opaqueref = glk_schannel_create(arglist[0].uint); break; case 0x00F3: /* schannel_destroy */ glk_schannel_destroy(arglist[0].opaqueref); break; case 0x00F8: /* schannel_play */ arglist[3].uint = glk_schannel_play(arglist[0].opaqueref, arglist[1].uint); break; case 0x00F9: /* schannel_play_ext */ arglist[5].uint = glk_schannel_play_ext(arglist[0].opaqueref, arglist[1].uint, arglist[2].uint, arglist[3].uint); break; case 0x00FA: /* schannel_stop */ glk_schannel_stop(arglist[0].opaqueref); break; case 0x00FB: /* schannel_set_volume */ glk_schannel_set_volume(arglist[0].opaqueref, arglist[1].uint); break; case 0x00FC: /* sound_load_hint */ glk_sound_load_hint(arglist[0].uint, arglist[1].uint); break; #endif /* GLK_MODULE_SOUND */ #ifdef GLK_MODULE_HYPERLINKS case 0x0100: /* set_hyperlink */ glk_set_hyperlink(arglist[0].uint); break; case 0x0101: /* set_hyperlink_stream */ glk_set_hyperlink_stream(arglist[0].opaqueref, arglist[1].uint); break; case 0x0102: /* request_hyperlink_event */ glk_request_hyperlink_event(arglist[0].opaqueref); break; case 0x0103: /* cancel_hyperlink_event */ glk_cancel_hyperlink_event(arglist[0].opaqueref); break; #endif /* GLK_MODULE_HYPERLINKS */ #ifdef GLK_MODULE_UNICODE case 0x0120: /* buffer_to_lower_case_uni */ if (arglist[0].ptrflag) arglist[5].uint = glk_buffer_to_lower_case_uni(arglist[1].array, arglist[2].uint, arglist[3].uint); else arglist[3].uint = glk_buffer_to_lower_case_uni(NULL, 0, arglist[1].uint); break; case 0x0121: /* buffer_to_upper_case_uni */ if (arglist[0].ptrflag) arglist[5].uint = glk_buffer_to_upper_case_uni(arglist[1].array, arglist[2].uint, arglist[3].uint); else arglist[3].uint = glk_buffer_to_upper_case_uni(NULL, 0, arglist[1].uint); break; case 0x0122: /* buffer_to_title_case_uni */ if (arglist[0].ptrflag) arglist[6].uint = glk_buffer_to_title_case_uni(arglist[1].array, arglist[2].uint, arglist[3].uint, arglist[4].uint); else arglist[4].uint = glk_buffer_to_title_case_uni(NULL, 0, arglist[1].uint, arglist[2].uint); break; case 0x0129: /* put_string_uni */ glk_put_string_uni(arglist[0].unicharstr); break; case 0x012A: /* put_buffer_uni */ if (arglist[0].ptrflag) glk_put_buffer_uni(arglist[1].array, arglist[2].uint); else glk_put_buffer_uni(NULL, 0); break; case 0x012B: /* put_char_stream_uni */ glk_put_char_stream_uni(arglist[0].opaqueref, arglist[1].uint); break; case 0x012C: /* put_string_stream_uni */ glk_put_string_stream_uni(arglist[0].opaqueref, arglist[1].unicharstr); break; case 0x012D: /* put_buffer_stream_uni */ if (arglist[1].ptrflag) glk_put_buffer_stream_uni(arglist[0].opaqueref, arglist[2].array, arglist[3].uint); else glk_put_buffer_stream_uni(arglist[0].opaqueref, NULL, 0); break; case 0x0130: /* get_char_stream_uni */ arglist[2].sint = glk_get_char_stream_uni(arglist[0].opaqueref); break; case 0x0131: /* get_buffer_stream_uni */ if (arglist[1].ptrflag) arglist[5].uint = glk_get_buffer_stream_uni(arglist[0].opaqueref, arglist[2].array, arglist[3].uint); else arglist[3].uint = glk_get_buffer_stream_uni(arglist[0].opaqueref, NULL, 0); break; case 0x0132: /* get_line_stream_uni */ if (arglist[1].ptrflag) arglist[5].uint = glk_get_line_stream_uni(arglist[0].opaqueref, arglist[2].array, arglist[3].uint); else arglist[3].uint = glk_get_line_stream_uni(arglist[0].opaqueref, NULL, 0); break; case 0x0138: /* stream_open_file_uni */ arglist[4].opaqueref = glk_stream_open_file_uni(arglist[0].opaqueref, arglist[1].uint, arglist[2].uint); break; case 0x0140: /* request_char_event_uni */ glk_request_char_event_uni(arglist[0].opaqueref); break; case 0x0141: /* request_line_event_uni */ if (arglist[1].ptrflag) glk_request_line_event_uni(arglist[0].opaqueref, arglist[2].array, arglist[3].uint, arglist[4].uint); else glk_request_line_event_uni(arglist[0].opaqueref, NULL, 0, arglist[2].uint); break; #endif /* GLK_MODULE_UNICODE */ #endif /* 0 */ } }
int glkunix_startup_code(glkunix_startup_t *data) { /* It turns out to be more convenient if we return TRUE from here, even when an error occurs, and display an error in glk_main(). */ int ix; char *filename = NULL; unsigned char buf[12]; int res; #ifdef GARGLK char *cx; #endif #ifdef GARGLK garglk_set_program_name("Glulxe 0.5.2"); garglk_set_program_info("Glulxe 0.5.2 by Andrew Plotkin"); #endif /* Parse out the arguments. They've already been checked for validity, and the library-specific ones stripped out. As usual for Unix, the zeroth argument is the executable name. */ for (ix=1; ix<data->argc; ix++) { #if VM_PROFILING if (!strcmp(data->argv[ix], "--profile")) { ix++; if (ix<data->argc) { strid_t profstr = glkunix_stream_open_pathname_gen(data->argv[ix], TRUE, FALSE, 1); if (!profstr) { init_err = "Unable to open profile output file."; init_err2 = data->argv[ix]; return TRUE; } setup_profile(profstr, NULL); } continue; } #endif /* VM_PROFILING */ if (filename) { init_err = "You must supply exactly one game file."; return TRUE; } filename = data->argv[ix]; } if (!filename) { init_err = "You must supply the name of a game file."; return TRUE; } gamefile = glkunix_stream_open_pathname(filename, FALSE, 1); if (!gamefile) { init_err = "The game file could not be opened."; init_err2 = filename; return TRUE; } #ifdef GARGLK cx = strrchr(data->argv[1], '/'); if (!cx) cx = strrchr(data->argv[1], '\\'); garglk_set_story_name(cx ? cx + 1 : data->argv[1]); #endif /* Now we have to check to see if it's a Blorb file. */ glk_stream_set_position(gamefile, 0, seekmode_Start); res = glk_get_buffer_stream(gamefile, (char *)buf, 12); if (!res) { init_err = "The data in this stand-alone game is too short to read."; return TRUE; } if (buf[0] == 'G' && buf[1] == 'l' && buf[2] == 'u' && buf[3] == 'l') { locate_gamefile(FALSE); return TRUE; } else if (buf[0] == 'F' && buf[1] == 'O' && buf[2] == 'R' && buf[3] == 'M' && buf[8] == 'I' && buf[9] == 'F' && buf[10] == 'R' && buf[11] == 'S') { locate_gamefile(TRUE); return TRUE; } else { init_err = "This is neither a Glulx game file nor a Blorb file " "which contains one."; return TRUE; } }
giblorb_err_t giblorb_create_map(strid_t file, giblorb_map_t **newmap) { giblorb_err_t err; giblorb_map_t *map; glui32 readlen; glui32 nextpos, totallength; giblorb_chunkdesc_t *chunks; int chunks_size, numchunks; char buffer[16]; *newmap = NULL; if (!lib_inited) { err = giblorb_initialize(); if (err) return err; lib_inited = TRUE; } /* First, chew through the file and index the chunks. */ glk_stream_set_position(file, 0, seekmode_Start); readlen = glk_get_buffer_stream(file, buffer, 12); if (readlen != 12) return giblorb_err_Read; if (giblorb_native4(buffer+0) != giblorb_ID_FORM) return giblorb_err_Format; if (giblorb_native4(buffer+8) != giblorb_ID_IFRS) return giblorb_err_Format; totallength = giblorb_native4(buffer+4) + 8; nextpos = 12; chunks_size = 8; numchunks = 0; chunks = (giblorb_chunkdesc_t *)giblorb_malloc(sizeof(giblorb_chunkdesc_t) * chunks_size); while (nextpos < totallength) { glui32 type, len; int chunum; giblorb_chunkdesc_t *chu; glk_stream_set_position(file, nextpos, seekmode_Start); readlen = glk_get_buffer_stream(file, buffer, 8); if (readlen != 8) return giblorb_err_Read; type = giblorb_native4(buffer+0); len = giblorb_native4(buffer+4); if (numchunks >= chunks_size) { chunks_size *= 2; chunks = (giblorb_chunkdesc_t *)giblorb_realloc(chunks, sizeof(giblorb_chunkdesc_t) * chunks_size); } chunum = numchunks; chu = &(chunks[chunum]); numchunks++; chu->type = type; chu->startpos = nextpos; if (type == giblorb_ID_FORM) { chu->datpos = nextpos; chu->len = len+8; } else { chu->datpos = nextpos+8; chu->len = len; } chu->ptr = NULL; chu->auxdatnum = -1; nextpos = nextpos + len + 8; if (nextpos & 1) nextpos++; if (nextpos > totallength) return giblorb_err_Format; } /* The basic IFF structure seems to be ok, and we have a list of chunks. Now we allocate the map structure itself. */ map = (giblorb_map_t *)giblorb_malloc(sizeof(giblorb_map_t)); if (!map) { giblorb_free(chunks); return giblorb_err_Alloc; } map->inited = giblorb_Inited_Magic; map->file = file; map->chunks = chunks; map->numchunks = numchunks; map->resources = NULL; map->ressorted = NULL; map->numresources = 0; /*map->releasenum = 0; map->zheader = NULL; map->resolution = NULL; map->palettechunk = -1; map->palette = NULL; map->auxsound = NULL; map->auxpict = NULL;*/ /* Now we do everything else involved in loading the Blorb file, such as building resource lists. */ err = giblorb_initialize_map(map); if (err) { giblorb_destroy_map(map); return err; } *newmap = map; return giblorb_err_None; }
/* db_init - read and decode the data file header */ void db_init(strid_t realfd) { int woff,ooff,aoff,voff,n; /* open the data file */ datafd = realfd; // glk_stream_open_file(name, filemode_Read, 0); // if (datafd == NULL) // error("can't open data file"); /* read the header */ if (glk_get_buffer_stream(datafd,hdr,HDR_SIZE) != HDR_SIZE) error("bad data file"); complement(hdr,HDR_SIZE); base = hdr; /* check the magic information */ if (strncmp(&hdr[HDR_MAGIC],"ADVSYS",6) != 0) error("not an adventure data file"); /* check the version number */ if ((n = getword(HDR_VERSION)) < 101 || n > VERSION) error("wrong version number"); /* decode the resident data length header field */ length = getword(HDR_LENGTH); /* allocate space for the resident data structure */ if ((data = malloc(length)) == 0) error("insufficient memory"); /* compute the offset to the data */ saveoff = (long)getword(HDR_DATBLK) * 512L; /* read the resident data structure */ glk_stream_set_position(datafd,saveoff,seekmode_Start); if (glk_get_buffer_stream(datafd,data,length) != length) error("bad data file"); complement(data,length); /* get the table base addresses */ wtable = data + (woff = getword(HDR_WTABLE)); wtypes = data + getword(HDR_WTYPES) - 1; otable = data + (ooff = getword(HDR_OTABLE)); atable = data + (aoff = getword(HDR_ATABLE)); vtable = data + (voff = getword(HDR_VTABLE)); /* get the save data area */ saveoff += (long)getword(HDR_SAVE); save = data + getword(HDR_SAVE); slen = getword(HDR_SLEN); /* get the base of the data and code spaces */ dbase = data + getword(HDR_DBASE); cbase = data + getword(HDR_CBASE); /* initialize the message routines */ msg_init(datafd,getword(HDR_MSGBLK)); /* get the code pointers */ h_init = getword(HDR_INIT); h_update = getword(HDR_UPDATE); h_before = getword(HDR_BEFORE); h_after = getword(HDR_AFTER); h_error = getword(HDR_ERROR); /* get the table lengths */ base = data; wcount = getword(woff); ocount = getword(ooff); acount = getword(aoff); vcount = getword(voff); /* setup the base of the resident data */ base = dbase; /* set the object count */ setvalue(V_OCOUNT,ocount); /* CHANGED FOR GLK */ #ifdef GARGLK garglk_set_story_name(&hdr[HDR_ANAME]); #endif #ifdef WINDOWS { int i; char *buf; i = strlen(&hdr[HDR_ANAME]); i += 1; i += strlen("GLK AdvSys - "); buf = malloc( sizeof(char) * i ); wsprintf(buf, "GLK AdvSys - %s", &hdr[HDR_ANAME]); winglk_window_set_title(buf); } #endif }
static git_uint32 readWord (strid_t file) { char buffer [4]; glk_get_buffer_stream (file, buffer, 4); return (git_uint32) read32 (buffer); }
BOOL quetzal_stack_restore(strid_t stream, glui32 qsize) { glui32 i = 0; int num_frames = 0; kill_stack(); init_stack(1024, 128); while(i < qsize) { unsigned n; unsigned num_locals; zword locals[16]; int num_args; int var; glui32 qframe[5]; i += fillstruct(stream, qstackframe, qframe, NULL); if(qframe[qreturnPC] > total_size) { n_show_error(E_SAVE, "function return PC past end of memory", qframe[qreturnPC]); return FALSE; } if((qframe[qflags] & b11100000) != 0) { n_show_error(E_SAVE, "expected top bits of flag to be zero", qframe[qflags]); return FALSE; } var = qframe[qvar]; if(qframe[qflags] & b00010000) /* from a call_n */ var = -1; num_locals = qframe[qflags] & b00001111; if(num_locals > 15) { n_show_error(E_SAVE, "too many locals", num_locals); return FALSE; } num_args = 0; switch(qframe[qargs]) { default: n_show_error(E_SAVE, "invalid argument count", qframe[qargs]); return FALSE; case b01111111: num_args++; case b00111111: num_args++; case b00011111: num_args++; case b00001111: num_args++; case b00000111: num_args++; case b00000011: num_args++; case b00000001: num_args++; case b00000000: ; } for(n = 0; n < num_locals; n++) { unsigned char v[ZWORD_SIZE]; glk_get_buffer_stream(stream, (char *) v, ZWORD_SIZE); locals[n] = MSBdecodeZ(v); i+=ZWORD_SIZE; } if(zversion != 6 && num_frames == 0) ; /* dummy stack frame; don't really use it */ else add_stack_frame(qframe[qreturnPC], num_locals, locals, num_args, var); for(n = 0; n < qframe[qeval]; n++) { unsigned char v[ZWORD_SIZE]; glk_get_buffer_stream(stream, (char *) v, ZWORD_SIZE); stack_push(MSBdecodeZ(v)); i += ZWORD_SIZE; } num_frames++; } if(!verify_stack()) { n_show_error(E_SAVE, "restored stack fails verification", 0); return FALSE; } return TRUE; }