コード例 #1
0
ファイル: iff.c プロジェクト: BeniEnge/as_son_of_hunkypunk
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);
}
コード例 #2
0
ファイル: git.c プロジェクト: DavidKinder/Git
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);
}
コード例 #3
0
ファイル: glk_filesys_if.c プロジェクト: chrender/libglkif
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);
}
コード例 #4
0
ファイル: launcher.c プロジェクト: c4rlo/gargoyle-fedora
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;
}
コード例 #5
0
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);
}
コード例 #6
0
ファイル: trivial.c プロジェクト: abrobston/gtkglk
/* 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;
}
コード例 #7
0
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);
}
コード例 #8
0
ファイル: struct.c プロジェクト: BPaden/garglk
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;
}
コード例 #9
0
ファイル: serial.c プロジェクト: MikulasZelinka/glulxe
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;  
}
コード例 #10
0
ファイル: advdbs.c プロジェクト: BPaden/garglk
/* 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);
}
コード例 #11
0
ファイル: gi_blorb.c プロジェクト: q200981193/iosglk
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;
}
コード例 #12
0
ファイル: trivial.c プロジェクト: abrobston/gtkglk
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;
}
コード例 #13
0
ファイル: serial.c プロジェクト: MikulasZelinka/glulxe
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;
}
コード例 #14
0
ファイル: op_save.c プロジェクト: BPaden/garglk
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);
}
コード例 #15
0
ファイル: unixstrt.c プロジェクト: HieuLsw/iphonefrotz
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;
  }
}
コード例 #16
0
ファイル: op_save.c プロジェクト: BPaden/garglk
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;
}
コード例 #17
0
ファイル: startunix.c プロジェクト: sussman/twisty
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;
}
コード例 #18
0
ファイル: macstart.c プロジェクト: 309972460/software
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;
    }
}
コード例 #19
0
ファイル: serial.c プロジェクト: MikulasZelinka/glulxe
/* 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;
}
コード例 #20
0
ファイル: unixstrt.c プロジェクト: cspiegel/garglk
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;
  }
}
コード例 #21
0
ファイル: dispatch.c プロジェクト: castaway/glknew
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 */
  }
}
コード例 #22
0
ファイル: unixstrt.c プロジェクト: BPaden/garglk
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;
  }
}
コード例 #23
0
ファイル: gi_blorb.c プロジェクト: q200981193/iosglk
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;
}
コード例 #24
0
ファイル: advdbs.c プロジェクト: BPaden/garglk
/* 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
}
コード例 #25
0
ファイル: savefile.c プロジェクト: BPaden/garglk
static git_uint32 readWord (strid_t file)
{
    char buffer [4];
    glk_get_buffer_stream (file, buffer, 4);
    return (git_uint32) read32 (buffer);
}
コード例 #26
0
ファイル: stack.c プロジェクト: BeniEnge/as_son_of_hunkypunk
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;
}