Exemplo n.º 1
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);
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
int glkint_setfilepos(z_file *fileref, long seek, int whence)
{
  if (fileref->implementation == FILE_IMPLEMENTATION_STDIO)
    return z_filesys_interface_c.setfilepos(fileref, seek, whence);
  else
  {
    if (whence == SEEK_SET)
      glk_stream_set_position(
          (strid_t)fileref->file_object, seek, seekmode_Start);
    else if (whence == SEEK_CUR)
      glk_stream_set_position(
          (strid_t)fileref->file_object, seek, seekmode_Current);
    else if (whence == SEEK_END)
      glk_stream_set_position(
          (strid_t)fileref->file_object, seek, seekmode_End);
    return 0;
  }
}
Exemplo n.º 5
0
/* db_restart - restart the current game */
int db_restart()
{
    glk_stream_set_position(datafd,saveoff,seekmode_Start);
    if (glk_get_buffer_stream(datafd,save,slen) != slen)
		return (NIL);
    complement(save,slen);
    setvalue(V_OCOUNT,ocount);
    
	longjmp(restart,1);
}
Exemplo n.º 6
0
BOOL ifffindchunk(strid_t stream, const char *type, glui32 *length, glui32 loc)
{
  char t[4];
  glui32 file_size;

  glk_stream_set_position(stream, 0, seekmode_End);
  file_size = glk_stream_get_position(stream);

  glk_stream_set_position(stream, loc, seekmode_Start);
  *length = 0;
  do {
    glk_stream_set_position(stream, *length, seekmode_Current);
    if(!iffgetchunk(stream, t, length, file_size))
      return FALSE;
   } while((t[0] != type[0]) || (t[1] != type[1]) ||
	   (t[2] != type[2]) || (t[3] != type[3]));

  return TRUE;
}
Exemplo n.º 7
0
static int reposition_write(dest_t *dest, glui32 pos)
{
  if (dest->ismem) {
    dest->pos = pos;
  }
  else {
    glk_stream_set_position(dest->str, pos, seekmode_Start);
    dest->pos = pos;
  }

  return 0;
}
Exemplo n.º 8
0
static glui32 write_memstate(dest_t *dest)
{
  glui32 res, pos;
  int val;
  int runlen;
  unsigned char ch;

  res = write_long(dest, endmem);
  if (res)
    return res;

  runlen = 0;
  glk_stream_set_position(gamefile, gamefile_start+ramstart, seekmode_Start);

  for (pos=ramstart; pos<endmem; pos++) {
    ch = Mem1(pos);
    if (pos < endgamefile) {
      val = glk_get_char_stream(gamefile);
      if (val == -1) {
        fatal_error("The game file ended unexpectedly while saving.");
      }
      ch ^= (unsigned char)val;
    }
    if (ch == 0) {
      runlen++;
    }
    else {
      /* Write any run we've got. */
      while (runlen) {
        if (runlen >= 0x100)
          val = 0x100;
        else
          val = runlen;
        res = write_byte(dest, 0);
        if (res)
          return res;
        res = write_byte(dest, (val-1));
        if (res)
          return res;
        runlen -= val;
      }
      /* Write the byte we got. */
      res = write_byte(dest, ch);
      if (res)
        return res;
    }
  }
  /* It's possible we've got a run left over, but we don't write it. */

  return 0;
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
0
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;
  }
}
Exemplo n.º 11
0
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;  
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
0
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;
    }
}
Exemplo n.º 14
0
/* 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;
}
Exemplo n.º 15
0
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();
}
Exemplo n.º 16
0
git_sint32 restoreFromFile (git_sint32 * base, git_sint32 id,
    git_uint32 protectPos, git_uint32 protectSize)
{
    git_uint32 protectEnd = protectPos + protectSize;
    git_uint32 i;
    strid_t file;
    glui32 fileSize, fileStart;

    int gotIdent = 0;
    int gotMemory = 0;
    int gotStack = 0;
    int gotHeap = 0;

    // Find out what stream they want to use, and make sure it's valid.
    file = git_find_stream_by_id (id);
    if (file == 0)
        return 1;

    // Read IFF header.
    if (readWord (file) != read32("FORM"))
        return 1; // Not an IFF file.
    
    fileSize = readWord (file);
    fileStart = glk_stream_get_position (file);
    
    if (readWord (file) != read32("IFZS"))
        return 1; // Not a Quetzal file.
    
    // Discard the current heap.
    heap_clear();
    
    // Read all the chunks.
    
    while (glk_stream_get_position(file) < fileStart + fileSize)
    {
        git_uint32 chunkType, chunkSize, chunkStart;
        chunkType = readWord (file);
        chunkSize = readWord (file);
        chunkStart = glk_stream_get_position (file);

        if (chunkType == read32("IFhd"))
        {
            if (gotIdent)
                return 1;

            gotIdent = 1;

            if (chunkSize != 128)
                return 1;

            for (i = 0 ; i < 128 ; ++i)
            {
                glui32 c = glk_get_char_stream (file);
                if (gRom [i] != c)
                    return 1;
            }
        }
        else if (chunkType == read32("Stks"))
        {
            if (gotStack)
                return 1;

            gotStack = 1;

            if (chunkSize & 3)
                return 1;

            gStackPointer = base;
            for ( ; chunkSize > 0 ; chunkSize -= 4)
                *gStackPointer++ = readWord(file);
        }
        else if (chunkType == read32("CMem"))
        {
            git_uint32 bytesRead = 0;
            if (gotMemory)
                return 1;

            gotMemory = 1;

            if (resizeMemory (readWord(file), 1))
                fatalError ("Can't resize memory map");

            bytesRead = 4;
            i = gRamStart;
            while (i < gExtStart && bytesRead < chunkSize)
            {
                int mult = 0;
                char c = (char) glk_get_char_stream(file);
                ++bytesRead;
                
                if (c == 0)
                {
                    mult = (unsigned char) glk_get_char_stream(file);
                    ++bytesRead;
                }
                
                for (++mult ; mult > 0 ; --mult, ++i)
                    if (i >= protectEnd || i < protectPos)
                        gRam [i] = gRom [i] ^ c;
            }

            while (i < gEndMem && bytesRead < chunkSize)
            {
                int mult = 0;
                char c = (char) glk_get_char_stream(file);
                ++bytesRead;
                
                if (c == 0)
                {
                    mult = (unsigned char) glk_get_char_stream(file);
                    ++bytesRead;
                }
                
                for (++mult ; mult > 0 ; --mult, ++i)
                    if (i >= protectEnd || i < protectPos)
                        gRam [i] = c;
            }

            while (i < gExtStart)
                if (i >= protectEnd || i < protectPos)
                    gRam [i] = gRom [i], ++i;

            while (i < gEndMem)
                if (i >= protectEnd || i < protectPos)
                    gRam [i] = 0, ++i;

            if (bytesRead != chunkSize)
                return 1; // Too much data!

            if (chunkSize & 1)
                glk_get_char_stream (file);
        }
        else if (chunkType == read32("MAll"))
        {
            glui32 heapSize = 0;
            glui32 * heap = 0;

            if (gotHeap)
                return 1;

            gotHeap = 1;

            if (chunkSize & 3)
                return 1;

            if (chunkSize > 0)
            {
                heap = malloc (chunkSize);
                heapSize = chunkSize / 4;
                for (i = 0 ; i < heapSize ; ++i)
                    heap[i] = readWord(file);

                /* The summary might have come from any interpreter, so it could
                  be out of order. We'll sort it. */
                qsort(heap+2, (heapSize-2)/2, 8, &sort_heap_summary);

                if (heap_apply_summary (heapSize, heap))
                    fatalError ("Couldn't apply heap summary");
                free (heap);
            }
        }
        else
        {
            // Unknown chunk type -- just skip it.
            glk_stream_set_position (file, (chunkSize + 1) & ~1, seekmode_Current);
        }
    }

    // Make sure we have all the chunks we need.

    if (!gotIdent)
        fatalError ("No ident chunk in save file");

    if (!gotStack)
        fatalError ("No stack chunk in save file");

    if (!gotMemory)
        fatalError ("No memory chunk in save file");

    // If we reach this point, we restored successfully.

    return 0;
}
Exemplo n.º 17
0
git_sint32 saveToFile (git_sint32 * base, git_sint32 * sp, git_sint32 id)
{
    git_uint32 n, zeroCount;
    glui32 fileSize, fileSizePos;
    glui32 memSize, memSizePos;
    glui32 heapSize;
    glui32* heap;

    strid_t file, oldFile;

    // Find out what stream they want to use, and make sure it's valid.
    file = git_find_stream_by_id (id);
    if (file == 0)
        return 1;

    // Get the state of the heap.
    if (heap_get_summary (&heapSize, &heap))
        fatalError ("Couldn't get heap summary");

    // Make the given stream the default.
    oldFile = glk_stream_get_current ();
    glk_stream_set_current (file);

    // Write Quetzal header.
    glk_put_string ("FORM");

    fileSizePos = glk_stream_get_position (file);
    writeWord (0);

    glk_put_string ("IFZS");

    // Header chunk.
    glk_put_string ("IFhd");
    writeWord (128);
    glk_put_buffer ((char *) gRom, 128);

    // Stack chunk.
    glk_put_string ("Stks");
    writeWord ((sp - base) * 4);
    for (n = 0 ; n < (git_uint32) (sp - base) ; ++n)
        writeWord (base [n]);

    // Heap chunk.
    if (heap != 0)
    {
        glk_put_string ("MAll");
        writeWord (heapSize * 4);
        for (n = 0 ; n < heapSize ; ++n)
            writeWord (heap [n]);
        free(heap);
    }

    // Memory chunk.
    glk_put_string ("CMem");
    memSizePos = glk_stream_get_position (file);
    writeWord (0);

    writeWord (gEndMem);
    for (zeroCount = 0, n = gRamStart ; n < gEndMem ; ++n)
    {
        unsigned char romC = (n < gExtStart) ? gRom[n] : 0;
        unsigned char c = ((git_uint32) romC) ^ ((git_uint32) gRam[n]);
        if (c == 0)
            ++zeroCount;
        else
        {
            for ( ; zeroCount > 256 ; zeroCount -= 256)
            {
                glk_put_char (0);
                glk_put_char (0xff);
            }

            if (zeroCount > 0)
            {
                glk_put_char (0);
                glk_put_char ((char) (zeroCount - 1));
                zeroCount = 0;
            }

            glk_put_char (c);
        }
    }
    // Note: we don't bother writing out any remaining zeroes,
    // because the memory is padded out with zeroes on restore.

    memSize = glk_stream_get_position (file) - memSizePos - 4;
    if (memSize & 1)
       glk_put_char (0);

    // Back up and fill in the lengths.
    fileSize = glk_stream_get_position (file) - fileSizePos - 4;

    glk_stream_set_position (file, fileSizePos, seekmode_Start);
    writeWord (fileSize);

    glk_stream_set_position (file, memSizePos, seekmode_Start);
    writeWord (memSize);

    // Restore the previous default stream.
    glk_stream_set_current (oldFile);

    // And we're done.
    return 0;
}
Exemplo n.º 18
0
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 */
  }
}
Exemplo n.º 19
0
int glkunix_startup_code(glkunix_startup_t *data)
{
  /* It turns out to be more convenient if we return TRUE from here, even 
     when an error occurs, and display an error in glk_main(). */
  int ix;
  char *filename = NULL;
  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;
  }
}
Exemplo n.º 20
0
int glkunix_startup_code(glkunix_startup_t *data)
{
  /* It turns out to be more convenient if we return TRUE from here, even 
     when an error occurs, and display an error in glk_main(). */
  int ix;
  char *filename = NULL;
  unsigned char buf[12];
  int res;

#ifdef GARGLK
  char *cx;
#endif

#ifdef GARGLK
  garglk_set_program_name("Glulxe 0.5.2");
  garglk_set_program_info("Glulxe 0.5.2 by Andrew Plotkin");
#endif

  /* Parse out the arguments. They've already been checked for validity,
     and the library-specific ones stripped out.
     As usual for Unix, the zeroth argument is the executable name. */
  for (ix=1; ix<data->argc; ix++) {

#if VM_PROFILING
    if (!strcmp(data->argv[ix], "--profile")) {
      ix++;
      if (ix<data->argc) {
        strid_t profstr = glkunix_stream_open_pathname_gen(data->argv[ix], TRUE, FALSE, 1);
        if (!profstr) {
          init_err = "Unable to open profile output file.";
          init_err2 = data->argv[ix];
          return TRUE;
        }
        setup_profile(profstr, NULL);
      }
      continue;
    }
#endif /* VM_PROFILING */

    if (filename) {
      init_err = "You must supply exactly one game file.";
      return TRUE;
    }
    filename = data->argv[ix];
  }

  if (!filename) {
    init_err = "You must supply the name of a game file.";
    return TRUE;
  }
    
  gamefile = glkunix_stream_open_pathname(filename, FALSE, 1);
  if (!gamefile) {
    init_err = "The game file could not be opened.";
    init_err2 = filename;
    return TRUE;
  }

#ifdef GARGLK
  cx = strrchr(data->argv[1], '/');
  if (!cx) cx = strrchr(data->argv[1], '\\');
  garglk_set_story_name(cx ? cx + 1 : data->argv[1]);
#endif

  /* Now we have to check to see if it's a Blorb file. */

  glk_stream_set_position(gamefile, 0, seekmode_Start);
  res = glk_get_buffer_stream(gamefile, (char *)buf, 12);
  if (!res) {
    init_err = "The data in this stand-alone game is too short to read.";
    return TRUE;
  }
    
  if (buf[0] == 'G' && buf[1] == 'l' && buf[2] == 'u' && buf[3] == 'l') {
    locate_gamefile(FALSE);
    return TRUE;
  }
  else if (buf[0] == 'F' && buf[1] == 'O' && buf[2] == 'R' && buf[3] == 'M'
    && buf[8] == 'I' && buf[9] == 'F' && buf[10] == 'R' && buf[11] == 'S') {
    locate_gamefile(TRUE);
    return TRUE;
  }
  else {
    init_err = "This is neither a Glulx game file nor a Blorb file "
      "which contains one.";
    return TRUE;
  }
}
Exemplo n.º 21
0
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;
}
Exemplo n.º 22
0
static glui32 read_memstate(dest_t *dest, glui32 chunklen)
{
  glui32 chunkend = dest->pos + chunklen;
  glui32 newlen;
  glui32 res, pos;
  int val;
  int runlen;
  unsigned char ch, ch2;
#ifdef SERIALIZE_CACHE_RAM
  glui32 cachepos;
#endif /* SERIALIZE_CACHE_RAM */

  heap_clear();

  res = read_long(dest, &newlen);
  if (res)
    return res;

  res = change_memsize(newlen, FALSE);
  if (res)
    return res;

  runlen = 0;

#ifdef SERIALIZE_CACHE_RAM
  cachepos = 0;
#else /* SERIALIZE_CACHE_RAM */
  glk_stream_set_position(gamefile, gamefile_start+ramstart, seekmode_Start);
#endif /* SERIALIZE_CACHE_RAM */

  for (pos=ramstart; pos<endmem; pos++) {
    if (pos < endgamefile) {
#ifdef SERIALIZE_CACHE_RAM
      val = ramcache[cachepos];
      cachepos++;
#else /* SERIALIZE_CACHE_RAM */
      val = glk_get_char_stream(gamefile);
      if (val == -1) {
        fatal_error("The game file ended unexpectedly while restoring.");
      }
#endif /* SERIALIZE_CACHE_RAM */
      ch = (unsigned char)val;
    }
    else {
      ch = 0;
    }

    if (dest->pos >= chunkend) {
      /* we're into the final, unstored run. */
    }
    else if (runlen) {
      runlen--;
    }
    else {
      res = read_byte(dest, &ch2);
      if (res)
        return res;
      if (ch2 == 0) {
        res = read_byte(dest, &ch2);
        if (res)
          return res;
        runlen = (glui32)ch2;
      }
      else {
        ch ^= ch2;
      }
    }

    if (pos >= protectstart && pos < protectend)
      continue;

    MemW1(pos, ch);
  }

  return 0;
}
Exemplo n.º 23
0
/* 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
}