BOOL fast_saveundo(void) { strid_t stack; glui32 stack_size; /* Avoids realloc() in hopes that'll make it a teensy bit faster */ if(automap_undoslot.z_memsize < dynamic_size) { n_free(automap_undoslot.z_mem); automap_undoslot.z_mem = n_malloc(dynamic_size); automap_undoslot.z_memsize = dynamic_size; } n_memcpy(automap_undoslot.z_mem, z_memory, dynamic_size); automap_undoslot.PC = oldPC; automap_undoslot.stacklength = stack_size = get_quetzal_stack_size(); if(automap_undoslot.stackchunksize < stack_size) { free(automap_undoslot.stackchunk); automap_undoslot.stackchunk = (zbyte *) n_malloc(stack_size); automap_undoslot.stackchunksize = stack_size; } stack = glk_stream_open_memory((char *) automap_undoslot.stackchunk, automap_undoslot.stacklength, filemode_Write, 0); if(!stack) return FALSE; if(!quetzal_stack_save(stack)) { glk_stream_close(stack, NULL); return FALSE; } glk_stream_close(stack, NULL); return TRUE; }
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); }
static void SaveGame(void) { strid_t file; frefid_t ref; int ct; char buf[128]; ref = glk_fileref_create_by_prompt(fileusage_TextMode | fileusage_SavedGame, filemode_Write, 0); if(ref == NULL) return; file = glk_stream_open_file(ref, filemode_Write, 0); glk_fileref_destroy(ref); if(file == NULL) return; for(ct=0;ct<16;ct++) { snprintf(buf, sizeof buf, "%d %d\n",Counters[ct],RoomSaved[ct]); glk_put_string_stream(file, buf); } snprintf(buf, sizeof buf, "%ld %d %hd %d %d %hd\n",BitFlags, (BitFlags&(1<<DARKBIT))?1:0, MyLoc,CurrentCounter,SavedRoom,GameHeader.LightTime); glk_put_string_stream(file, buf); for(ct=0;ct<=GameHeader.NumItems;ct++) { snprintf(buf, sizeof buf, "%hd\n",(short)Items[ct].Location); glk_put_string_stream(file, buf); } glk_stream_close(file, NULL); Output("Saved.\n"); }
void Processor::script_close() { h_flags &= ~SCRIPTING_FLAG; SET_WORD(H_FLAGS, h_flags); glk_stream_close(sfp); ostream_script = false; }
BOOL restoregame(void) { BOOL result; strid_t file; if(automap_unexplore()) return FALSE; file = n_file_prompt(fileusage_SavedGame | fileusage_BinaryMode, filemode_Read); if(!file) return FALSE; result = restorequetzal(file); glk_stream_close(file, NULL); if(result) { glui32 wid, hei; z_find_size(&wid, &hei); set_header(wid, hei); } return result; }
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); }
void Processor::z_save() { bool success = false; if (zargc != 0) { // Open auxilary file frefid_t ref = glk_fileref_create_by_prompt(fileusage_Data | fileusage_BinaryMode, filemode_Write, 0); if (ref != nullptr) { // Write data strid_t f = glk_stream_open_file(ref, filemode_Write); glk_put_buffer_stream(f, (const char *)zmp + zargs[0], zargs[1]); glk_stream_close(f); success = true; } } else { success = saveGame().getCode() == Common::kNoError; } if (h_version <= V3) branch(success); else store(success); }
/* Internal function: do any Glk-thread cleanup for shutting down the Glk library. */ void shutdown_glk_post(void) { ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key); /* Free all opaque objects; can't iterate normally, because the objects are being removed from the global iteration lists */ if(glk_data->root_window) glk_window_close(glk_data->root_window->data, NULL); g_assert(glk_data->root_window == NULL); strid_t str; while( (str = glk_stream_iterate(NULL, NULL)) ) glk_stream_close(str, NULL); frefid_t fref; while( (fref = glk_fileref_iterate(NULL, NULL)) ) glk_fileref_destroy(fref); schanid_t sch; while( (sch = glk_schannel_iterate(NULL, NULL)) ) glk_schannel_destroy(sch); /* Empty the event queue */ g_mutex_lock(&glk_data->event_lock); g_queue_foreach(glk_data->event_queue, (GFunc)g_free, NULL); g_queue_clear(glk_data->event_queue); g_mutex_unlock(&glk_data->event_lock); /* Reset the abort signaling mechanism */ g_mutex_lock(&glk_data->abort_lock); glk_data->abort_signalled = FALSE; g_mutex_unlock(&glk_data->abort_lock); /* Reset arrangement mechanism */ g_mutex_lock(&glk_data->arrange_lock); glk_data->needs_rearrange = FALSE; glk_data->ignore_next_arrange_event = FALSE; g_mutex_unlock(&glk_data->arrange_lock); /* Unref input queues (they are not destroyed because the main thread stil holds a ref */ g_async_queue_unref(glk_data->char_input_queue); g_async_queue_unref(glk_data->line_input_queue); /* Reset other stuff */ glk_data->interrupt_handler = NULL; g_free(glk_data->current_dir); glk_data->current_dir = NULL; /* Remove the dispatch callbacks */ glk_data->register_obj = NULL; glk_data->unregister_obj = NULL; glk_data->register_arr = NULL; glk_data->unregister_arr = NULL; }
BOOL fast_restoreundo(void) { strid_t stack; n_memcpy(z_memory, automap_undoslot.z_mem, dynamic_size); PC = automap_undoslot.PC; stack = glk_stream_open_memory((char *) automap_undoslot.stackchunk, automap_undoslot.stacklength, filemode_Read, 0); quetzal_stack_restore(stack, automap_undoslot.stacklength); glk_stream_close(stack, NULL); return TRUE; }
void profile_quit() { int bucknum; function_t *func; char linebuf[512]; frefid_t profref; strid_t profstr; while (current_frame) { profile_out(); } profref = glk_fileref_create_by_name(fileusage_BinaryMode|fileusage_Data, "profile-raw", 0); if (!profref) fatal_error("Profiler: unable to create profile-raw file"); profstr = glk_stream_open_file(profref, filemode_Write, 0); glk_put_string_stream(profstr, "<profile>\n"); for (bucknum=0; bucknum<FUNC_HASH_SIZE; bucknum++) { char total_buf[20], self_buf[20]; for (func = functions[bucknum]; func; func=func->hash_next) { /* ### sprintf(linebuf, "function %lx called %ld times, total ops %ld, total time %s, self ops %ld, self time %s\n", func->addr, func->call_count, func->total_ops, timeprint(&func->total_time, total_buf), func->self_ops, timeprint(&func->self_time, self_buf)); ### */ sprintf(linebuf, " <function addr=\"%lx\" call_count=\"%ld\" accel_count=\"%ld\" total_ops=\"%ld\" total_time=\"%s\" self_ops=\"%ld\" self_time=\"%s\" />\n", func->addr, func->call_count, func->accel_count, func->total_ops, timeprint(&func->total_time, total_buf), func->self_ops, timeprint(&func->self_time, self_buf)); glk_put_string_stream(profstr, linebuf); } } glk_put_string_stream(profstr, "</profile>\n"); glk_stream_close(profstr, NULL); glulx_free(functions); functions = NULL; }
/* Internal function: shut down all requests and anything not necessary while showing the last displayed configuration of windows. */ void shutdown_glk_pre(void) { ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key); /* Stop any timers */ glk_request_timer_events(0); /* Cancel any pending input requests and flush all window buffers */ winid_t win; for(win = glk_window_iterate(NULL, NULL); win; win = glk_window_iterate(win, NULL)) { switch(win->input_request_type) { case INPUT_REQUEST_CHARACTER: case INPUT_REQUEST_CHARACTER_UNICODE: glk_cancel_char_event(win); break; case INPUT_REQUEST_LINE: case INPUT_REQUEST_LINE_UNICODE: glk_cancel_line_event(win, NULL); break; case INPUT_REQUEST_NONE: default: ; /* TODO: Handle mouse and hyperlink requests */ } flush_window_buffer(win); } /* Close any open resource files */ if(glk_data->resource_map != NULL) { giblorb_destroy_map(glk_data->resource_map); glk_data->resource_map = NULL; glk_stream_close(glk_data->resource_file, NULL); } /* Empty the input queues */ while(g_async_queue_try_pop(glk_data->char_input_queue)) ; while(g_async_queue_try_pop(glk_data->line_input_queue)) ; /* Wait for any pending window rearrange */ g_mutex_lock(&glk_data->arrange_lock); if(glk_data->needs_rearrange) g_cond_wait(&glk_data->rearranged, &glk_data->arrange_lock); g_mutex_unlock(&glk_data->arrange_lock); }
/* Just like restoreundo, but the opposite ;) The idea is to go to the @save_undo location, but return 0 instead of 2 so the game thinks it just successfully saved the game. For games which don't contain @save_undo, jumps to right after the @read instruction. */ BOOL restoreredo(void) { strid_t stack; int i; glui32 wid, hei; stream_result_t poo; move_difference *p = movelist; if(!p || move_index <= 0) return FALSE; move_index--; for(i = 0; i < move_index; i++) { p=p->next; if(!p) return FALSE; } quetzal_undiff(prevstate, dynamic_size, p->delta, p->deltalength, TRUE); n_memcpy(z_memory, prevstate, dynamic_size); stack = glk_stream_open_memory((char *) p->stackchunk, p->stacklength, filemode_Read, 0); quetzal_stack_restore(stack, p->stacklength); glk_stream_close(stack, &poo); if(poo.readcount != p->stacklength) { n_show_error(E_SAVE, "incorrect stack size assessment", poo.readcount); return FALSE; } if(p->PC_in_instruction) { PC = p->PC; mop_store_result(0); false_undo = FALSE; } else { PC = p->PC; false_undo = FALSE; } has_done_save_undo = TRUE; z_find_size(&wid, &hei); set_header(wid, hei); return TRUE; }
void op_save5(void) { unsigned i; char filename[256]; unsigned length; strid_t file = NULL; offset end; switch(numoperands) { case 0: op_save4(); return; case 1: n_show_error(E_INSTR, "call save with bad number of operands", numoperands); mop_store_result(0); return; case 2: file = n_file_prompt(fileusage_Data | fileusage_BinaryMode, filemode_Write); 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_Write, filename); break; } if(!file) { mop_store_result(0); return; } end = ((offset) operand[0]) + operand[1]; if(end > 65535 || end > total_size) { n_show_error(E_MEMORY, "attempt to save data out of range", end); mop_store_result(0); return; } w_glk_put_buffer_stream(file, (char *) z_memory + operand[0], operand[1]); glk_stream_close(file, NULL); mop_store_result(1); }
BOOL savegame(void) { BOOL result; strid_t file; if(automap_unexplore()) return FALSE; file = n_file_prompt(fileusage_SavedGame | fileusage_BinaryMode, filemode_Write); if(!file) return FALSE; result = savequetzal(file); glk_stream_close(file, NULL); return result; }
int glkint_closefile(z_file *file_to_close) { if (file_to_close == NULL) return -1; if (file_to_close->implementation == FILE_IMPLEMENTATION_STDIO) return z_filesys_interface_c.closefile(file_to_close); else { if (file_to_close->file_object) glk_stream_close((strid_t)file_to_close->file_object, NULL); if (file_to_close->filename) free(file_to_close->filename); file_to_close->file_object = NULL; file_to_close->filename = NULL; free(file_to_close); return 0; } }
BOOL restoreundo(void) { strid_t stack; int i; glui32 wid, hei; move_difference *p = movelist; if(!p || move_index < 0) return FALSE; for(i = 0; i < move_index; i++) { p=p->next; if(!p) return FALSE; } move_index++; n_memcpy(z_memory, prevstate, dynamic_size); quetzal_undiff(prevstate, dynamic_size, p->delta, p->deltalength, TRUE); stack = glk_stream_open_memory((char *) p->stackchunk, p->stacklength, filemode_Read, 0); quetzal_stack_restore(stack, p->stacklength); glk_stream_close(stack, NULL); if(p->PC_in_instruction) { PC = p->PC; mop_store_result(2); false_undo = FALSE; } else { PC = p->oldPC; false_undo = TRUE; } has_done_save_undo = TRUE; z_find_size(&wid, &hei); set_header(wid, hei); return TRUE; }
/** * giblorb_set_resource_map: * @file: The file stream to read the resource map from * * This function tells the library that the file is indeed the Blorby source * of all resource goodness. Whenever your program calls an image or sound * function, such as glk_image_draw(), the library will search this file for * the resource you request. * * Do <emphasis>not</emphasis> close the stream after calling this function. * The library is responsible for closing the stream at shutdown time. * * Returns: a Blorb error code. */ giblorb_err_t giblorb_set_resource_map(strid_t file) { ChimaraGlkPrivate *glk_data = g_private_get(&glk_data_key); giblorb_map_t *newmap; /* create map allocates memory */ giblorb_err_t error = giblorb_create_map(file, &newmap); if(error != giblorb_err_None) { g_free(newmap); return error; } /* Check if there was already an existing resource map */ if(glk_data->resource_map != NULL) { WARNING("Overwriting existing resource map.\n"); giblorb_destroy_map(glk_data->resource_map); glk_stream_close(glk_data->resource_file, NULL); } glk_data->resource_map = newmap; glk_data->resource_file = file; return giblorb_err_None; }
void Processor::replay_close() { glk_stream_close(pfp); istream_replay = false; }
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 */ } }
static void read_textpref(strid_t pref, const char *progname) { unsigned n; char buffer[1024]; int prognamelen = n_strlen(progname); if(!pref) return; while(glk_get_line_stream(pref, buffer, sizeof(buffer))) { char *optname; char *optval; long int optnum; if(buffer[0] == '#') continue; while(buffer[0] == '[') { if(n_strncasecmp(buffer+1, progname, prognamelen) != 0 || buffer[1+prognamelen] != ']') { while(glk_get_line_stream(pref, buffer, sizeof(buffer))) if(buffer[0] == '[') break; } else { glk_get_line_stream(pref, buffer, sizeof(buffer)); } } optname = buffer; while(isspace(*optname)) optname++; if((optval = n_strchr(optname, '=')) != NULL) { char *p; *optval = 0; optval++; if((p = n_strchr(optname, ' ')) != NULL) *p = 0; while(isspace(*optval)) optval++; while(isspace(optval[strlen(optval)-1])) optval[strlen(optval)-1] = 0; optnum = n_strtol(optval, NULL, 0); if(n_strcasecmp(optval, "false") == 0 || n_strcasecmp(optval, "f") == 0) optnum = FALSE; if(n_strcasecmp(optval, "true") == 0 || n_strcasecmp(optval, "t") == 0) optnum = TRUE; for(n = 0; n < sizeof(options) / sizeof(*options); n++) { if(n_strcmp(options[n].longname, optname) == 0) { switch(options[n].type) { case option_flag: case option_number: options[n].int_func(optnum); break; case option_file: options[n].str_func(startup_open(optval)); break; case option_wfile: options[n].str_func(startup_wopen(optval)); break; case option_string: options[n].string_func(optval); break; } break; } } } } glk_stream_close(pref, NULL); }
void Processor::record_close() { glk_stream_close(rfp); ostream_record = false; }
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 profile_quit() { int bucknum; function_t *func; char linebuf[512]; strid_t profstr; if (!profiling_active) return; while (current_frame) { profile_out(0); } if (profiling_stream) { profstr = profiling_stream; } else if (profiling_filename) { frefid_t profref = glk_fileref_create_by_name(fileusage_BinaryMode|fileusage_Data, profiling_filename, 0); if (!profref) fatal_error_2("Profiler: unable to create profile output fileref", profiling_filename); profstr = glk_stream_open_file(profref, filemode_Write, 0); } else { fatal_error("Profiler: no profile output handle!"); } glk_put_string_stream(profstr, "<profile>\n"); for (bucknum=0; bucknum<FUNC_HASH_SIZE; bucknum++) { char total_buf[20], self_buf[20]; callcount_t *cc; for (func = functions[bucknum]; func; func=func->hash_next) { /* ### sprintf(linebuf, "function %lx called %ld times, total ops %ld, total time %s, self ops %ld, self time %s\n", func->addr, func->call_count, func->total_ops, timeprint(&func->total_time, total_buf), func->self_ops, timeprint(&func->self_time, self_buf)); ### */ sprintf(linebuf, " <function addr=\"%lx\" call_count=\"%ld\" accel_count=\"%ld\" total_ops=\"%ld\" total_time=\"%s\" self_ops=\"%ld\" self_time=\"%s\" max_depth=\"%ld\" max_stack_use=\"%ld\" />\n", (unsigned long)func->addr, (long)func->call_count, (long)func->accel_count, (long)func->total_ops, timeprint(&func->total_time, total_buf), (long)func->self_ops, timeprint(&func->self_time, self_buf), (long)func->max_depth, (long)func->max_stack_use); glk_put_string_stream(profstr, linebuf); for (cc = func->outcalls; cc; cc = cc->next) { sprintf(linebuf, " <calls fromaddr=\"%lx\" toaddr=\"%lx\" count=\"%ld\" />\n", (unsigned long)func->addr, (unsigned long)cc->toaddr, (long)cc->count); glk_put_string_stream(profstr, linebuf); } } } glk_put_string_stream(profstr, "</profile>\n"); glk_stream_close(profstr, NULL); /* ### Ought to free the function structures, not just the hash array. */ glulx_free(functions); functions = NULL; }
void glk_main(void) { /* Open the main window. */ mainwin = glk_window_open(0, 0, 0, wintype_TextBuffer, 1); if (!mainwin) { /* It's possible that the main window failed to open. There's nothing we can do without it, so exit. */ return; } glui32 buffer[1024]; int i; for(i = 0; i < 512; i++) { buffer[i * 2] = i + 33; buffer[i * 2 + 1] = 32; } /* frefid_t f = glk_fileref_create_temp(fileusage_BinaryMode, 0); if(f) { strid_t s = glk_stream_open_file(f, filemode_ReadWrite, 0);*/ glui32 membuf[512]; strid_t s = glk_stream_open_memory_uni(membuf, 512, filemode_ReadWrite, 0); glk_stream_set_current(s); glk_put_char_uni('X'); glk_put_string("Philip en Marijn zijn vet goed.\n"); glk_put_buffer_uni(buffer, 1024); glk_stream_set_position(s, 0, seekmode_Start); glk_set_window(mainwin); glk_put_char_uni( glk_get_char_stream_uni(s) ); glk_put_char('\n'); printf("Line read: %d\n", glk_get_line_stream_uni(s, buffer, 1024) ); printf("string[5] = %X\n", buffer[5]); glk_put_string_uni(buffer); int count = glk_get_buffer_stream_uni(s, buffer, 1024); printf("Buffer read: %d\n", count); glk_put_string("\n---SOME CHARACTERS---\n"); glk_put_buffer_uni(buffer, count); glk_put_string("\n---THE SAME CHARACTERS IN UPPERCASE---\n"); int newcount = glk_buffer_to_upper_case_uni(buffer, 1024, 1024); glk_put_buffer_uni(buffer, newcount); stream_result_t result; glk_stream_close(s, &result); fprintf(stderr, "Read count: %d\nWrite count: %d\n", result.readcount, result.writecount); /* glk_fileref_destroy(f); }*/ glk_set_interrupt_handler(&sayit); event_t ev; while(1) { glk_put_string("\nprompt> "); glk_request_line_event_uni(mainwin, buffer, 1024, 0); glk_select(&ev); switch(ev.type) { default: printf("Received event:\n"); printf("Type: %d\n", ev.type); printf("Win: %d\n", glk_window_get_rock(ev.win) ); printf("Var1: %d\n", ev.val1); printf("Var2: %d\n", ev.val2); } } /* Bye bye */ glk_exit(); }
BOOL saveundo(BOOL in_instruction) { move_difference newdiff; strid_t stack; stream_result_t poo; if(!allow_saveundo) return TRUE; /* In games which provide @save_undo, we will have already issued a faked saveundo before the first @save_undo hits, since there hadn't been any @save_undo before the first read line. So when this happens, wipe the fake saveundo in favor of the real one */ if(in_instruction && movelist && !movelist->next && !movelist->PC_in_instruction) init_undo(); if(!quetzal_diff(z_memory, prevstate, dynamic_size, &newdiff.delta, &newdiff.deltalength, TRUE)) return FALSE; #ifdef PARANOID { char *newmem = (char *) n_malloc(dynamic_size); n_memcpy(newmem, prevstate, dynamic_size); quetzal_undiff(newmem, dynamic_size, newdiff.delta, newdiff.deltalength, TRUE); if(n_memcmp(z_memory, newmem, dynamic_size)) { n_show_error(E_SAVE, "save doesn't match itself", 0); } n_free(newmem); } #endif newdiff.PC = PC; newdiff.oldPC = oldPC; newdiff.PC_in_instruction = in_instruction; newdiff.stacklength = get_quetzal_stack_size(); newdiff.stackchunk = (zbyte *) n_malloc(newdiff.stacklength); stack = glk_stream_open_memory((char *) newdiff.stackchunk, newdiff.stacklength, filemode_Write, 0); if(!stack) { n_free(newdiff.delta); n_free(newdiff.stackchunk); return FALSE; } if(!quetzal_stack_save(stack)) { glk_stream_close(stack, NULL); n_free(newdiff.delta); n_free(newdiff.stackchunk); return FALSE; } glk_stream_close(stack, &poo); if(poo.writecount != newdiff.stacklength) { n_show_error(E_SAVE, "incorrect stack size assessment", poo.writecount); n_free(newdiff.delta); n_free(newdiff.stackchunk); return FALSE; } while(move_index-- > 0) { n_free(movelist->delta); n_free(movelist->stackchunk); LEremove(movelist); } LEadd(movelist, newdiff); move_index++; n_memcpy(prevstate, z_memory, dynamic_size); has_done_save_undo = TRUE; return TRUE; }