예제 #1
0
파일: heglk.c 프로젝트: BPaden/garglk
void heglk_printfatalerror(char *err)
{
	static winid_t win = NULL;
	
	if (!win)
	{
		winid_t rootwin = glk_window_get_root();
		if (!rootwin)
			win = glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
		else
			win = glk_window_open(rootwin, winmethod_Below | winmethod_Fixed, 
				3, wintype_TextBuffer, 0);
	}
	
	if (win)
	{
		glk_put_string_stream(glk_window_get_stream(win), err);
	}
}
예제 #2
0
void GlkInterface::showBeyondZorkTitle() {
	uint winW, winH, imgW, imgH;
	winid_t win = glk_window_open(0, 0, 0, wintype_Graphics, 0);
	glk_window_get_size(win, &winW, &winH);

	if (os_picture_data(1, &imgW, &imgH)) {
		os_draw_picture(1, win, Common::Rect(0, 0, winW, winH));
		_events->waitForPress();
	}

	glk_window_close(win, nullptr);
}
예제 #3
0
파일: glkmisc.c 프로젝트: BPaden/garglk
void os_fatal (const char *s)
{
	char err[256];
	sprintf(err,"%s",s);

	if (!gos_lower)
		gos_lower = glk_window_open(0, 0, 0, wintype_TextBuffer, 0);

	glk_set_window(gos_lower);
	glk_set_style(style_Normal);
	glk_put_string("\n\nFatal error: ");
	glk_put_string(err);
	glk_put_string("\n");
	glk_exit();
}
예제 #4
0
파일: heglk.c 프로젝트: BPaden/garglk
void glk_main(void)
{
	/* Open the main window... */
	mainwin = glk_window_open(0, 0, 0, wintype_TextBuffer, 1);

	/* ...and set it up for default output */
	glk_set_window(currentwin = mainwin);

	/* It's possible that the main window failed to open. There's
	   nothing we can do without it, so exit */
	if (!mainwin)
		return; 

	he_main(0, NULL);	/* no argc, argv */
}
예제 #5
0
void os_banners_open(osbanid_t banner)
{
    if (!banner)
        return;

    if (banner->valid)
    {
        if (banner->size && banner->parent && banner->parent->win)
        {
            os_banner_styles_apply(banner);
            if (!banner->win)
                banner->win = glk_window_open(banner->parent->win, banner->method,
                                              banner->size, banner->type, banner->id);
            banner_contents_display(banner->contents);
        }
        os_banners_open(banner->children);
    }

    os_banners_open(banner->next);
}
예제 #6
0
static glsi32 classes_restore(glk_object_save_t *objects, glui32 objects_count, int versionNum)
{
    glk_object_save_t *cur;
    int found;
    classtable_t *ctab;
    classref_t *cref, *cref_id;
    int i, j;
    window_t *win = NULL, *splitwin = NULL;
    struct glk_window_autosave *foundwin = NULL;
    stream_t *str = NULL;
    struct glk_stream_autosave *foundstr = NULL;
    glui32 id;
    int winct = 0, winct2 = 0;
    t_winid winid[kMaxGlkViews];
    stream_t *cur_str = NULL;
    char errbuf[256];

    for (i = 0; i < kMaxGlkViews; i++) {
        winid[i].win = NULL;
        winid[i].id = 0;
    }
    int winLastId = classes[gidisp_Class_Window]->lastid;
    for (i = 0; i < objects_count; i++) {
        cur = objects + i;
        if (cur->type == gidisp_Class_Window && cur->id+1 > winLastId)
            winLastId = cur->id+1;
    }
    classes[gidisp_Class_Window]->lastid = winLastId; // make sure ids of new windows don't overlap orig ids

    for (i = 0; i < objects_count; i++) {
        found = FALSE;
        // windows come first, in the correct order, alternated with their streams/hints
        cur = objects + i;
        // don't bother iterating through current - there are none at autoload
        if (cur->type == gidisp_Class_Window) {
            winct++;
            foundwin = &cur->obj.win;
            classes_denormalize_pointers(gidisp_Class_Window, foundwin);
            winid[winct-1].id = cur->id; // fill this in for a pair, too

            if (foundwin->type != wintype_Pair) {
                splitwin = NULL;
                if (foundwin->splitwin != kInvalidSplitWin) { // this had no splitwin going in
                    for (j = 0; j < kMaxGlkViews; j++) {
                        if (winid[j].id == foundwin->splitwin) {
                            splitwin = winid[j].win;
                            break;
                        }
                    }
                }
                win = (window_t *)glk_window_open(splitwin, foundwin->method, foundwin->size, foundwin->type, foundwin->rock);
                if (!win) {
                    sprintf(errbuf, "\nCould not create %s window with id %ld. Aborting restore.\n",
                            foundwin->type == wintype_TextBuffer ? "textbuffer" :
                            foundwin->type == wintype_TextGrid ? "textgrid" :
                            foundwin->type == wintype_Blank ? "blank" : "graphics", (long)cur->id);
                    iosif_win_puts(0, errbuf);
                    return FALSE;
                }
                winid[winct-1].win = win;

                // check id, set id if necessary
                id = classes_find_id_for_object(gidisp_Class_Window, win);
                if (id != cur->id) {
                    cref_id = classes_pop_cref(gidisp_Class_Window, id);
                    cref_id->id = cur->id; // auto-awarding should ensure that an id has not been reused
                    classes_push_cref(gidisp_Class_Window, cref_id);
                }
                if (versionNum == FrotzGlkClassChunkVersionNumV1) {
                    win->line_request = foundwin->requ.v1.line_request;
                    win->char_request = foundwin->requ.v1.char_request;
                    win->line_request_uni = foundwin->requ.v1.line_request_uni;
                    win->char_request_uni = foundwin->requ.v1.char_request_uni;
                } else {
                    int req = foundwin->requ.v2.reqFlags;
                    win->line_request = (req & kGlkReqLine) != 0;
                    win->line_request_uni = (req & kGlkReqLineUni) != 0;
                    win->char_request = (req & kGlkReqChar) != 0;
                    win->mouse_request = (req & kGlkReqMouse) != 0;
                    win->hyper_request = (req & kGlkReqHyper) != 0;
                    win->echo_line_input = (req & kGlkReqNoEchoLine) == 0;
                    if (win->type == wintype_TextBuffer) {
                        window_textbuffer_t *wtb = (window_textbuffer_t*)win->data;
                        wtb->inecho = win->echo_line_input;
                    }
                    if (win->mouse_request && (win->type == wintype_Graphics || win->type == wintype_TextGrid))
                        iosif_enable_tap(win->iosif_glkViewNum);
                    if (win->hyper_request && (win->type == wintype_TextGrid || win->type == wintype_TextBuffer))
                        iosif_enable_tap(win->iosif_glkViewNum);
                }
                if (foundwin->inbuf) {
                    window_textbuffer_t *wtb = (window_textbuffer_t*)win->data;
                    wtb->inbuf = foundwin->inbuf;
                    wtb->inmax = foundwin->inmax;
                }
                found = TRUE;
            }
            if (found && (win->type == wintype_TextBuffer || win->type == wintype_TextGrid)) {
                // read STREAM chunk
                i++;
                cur = objects + i;

                if (cur->type != gidisp_Class_Stream) {
                    sprintf(errbuf, "\nUnexpected window stream type %d. Aborting restore.\n", cur->type);
                    iosif_win_puts(0, errbuf);
                    return FALSE;
                } else {
                    foundstr = &cur->obj.str;
                    str = win->str;

                    id = classes_find_id_for_object(gidisp_Class_Stream, str);
                    if (id != cur->id) {
                        cref_id = classes_pop_cref(gidisp_Class_Stream, id);
                        cref_id->id = cur->id; // auto-awarding should verify that an id has not been reused
                        classes_push_cref(gidisp_Class_Stream, cref_id);
                    }
                    classes_denormalize_pointers(gidisp_Class_Stream, foundstr);

                    str->rock = foundstr->rock;
                    str->readcount = foundstr->readcount;
                    str->writecount = foundstr->writecount;
                    str->readable = foundstr->readable;
                    str->writable = foundstr->writable;
                    if (!str->buf && foundstr->buf) {
                        str->buf = foundstr->buf;
                        str->bufptr = foundstr->bufptr;
                        str->bufend = foundstr->bufend;
                        str->bufeof = foundstr->bufeof;
                        str->buflen = foundstr->buflen;
                    }
                    if (cur->iscurrent) {
                        cur_str = str;
                    }
                }
                // read STYLE chunk
                i++;
                cur = objects + i;

                if (cur->type != type_Style) {
                    sprintf(errbuf, "\nUnexpected stream type %d. Aborting restore.\n", cur->type);
                    iosif_win_puts(0, errbuf);
                    return FALSE;
                } else {
                    gli_window_set_stylehints(win, (GLK_STYLE_HINTS *)&cur->obj.style);
                }
                iosif_set_glk_default_colors(win->iosif_glkViewNum);
            } else if (found && win->type == wintype_Graphics) {
                if (i+1 < objects_count && objects[i+1].type == type_Graphics) {
                    i++;
                    cur = objects + i;
                    window_graphics_t *wgp = (window_graphics_t*)win->data;
                    wgp->width = cur->obj.gfx.width;
                    wgp->height = cur->obj.gfx.height;
                    wgp->backcolor = cur->obj.gfx.backcolor;
                    iosif_set_background_color(win->iosif_glkViewNum, wgp->backcolor);
                    iosif_restore_glk_win_graphics_img(wingfxcount++, win->iosif_glkViewNum);
                }
            } else if (found && win->type == wintype_Pair) {
                // this will never happen
                i++;
            }
        } else if (cur->type == gidisp_Class_Stream) {
            break;
        } else if (cur->type == type_Pair) {
            struct glk_winpair_autosave *pairwin = &cur->obj.pair;
            // find the children; if they exist, make sure that this window is registered under the correct id
            glui32 id1 = (glui32)pairwin->child1;
            glui32 id2 = (glui32)pairwin->child2;
            window_t *win1 = NULL;
            window_t *win2 = NULL;

            for (j = 0; j < kMaxGlkViews; j++) {
                if (winid[j].id == id1) {
                    win1 = winid[j].win;
                } else if (winid[j].id == id2) {
                    win2 = winid[j].win;
                }
                if (win1 && win2) break;
            }
            if (win1 && win2) { // we found it
                // check id, set id if necessary
                id = classes_find_id_for_object(gidisp_Class_Window, win1->parent); // get the parent
                if (id != cur->id) {
                    cref_id = classes_pop_cref(gidisp_Class_Window, id);
                    cref_id->id = cur->id; // auto-awarding should ensure that an id has not been reused
                    classes_push_cref(gidisp_Class_Window, cref_id);
                }
                // enter window in the window id list, so other windows can find it, too, if it's being used as a splitwin
                for (j = 0; j < kMaxGlkViews; j++) {
                    if (winid[j].id == cur->id) {
                        winid[j].win = win1->parent;
                        break;
                    }
                }
            }
        } else if (cur->type == gidisp_Class_Fileref)
            ;
    }
    // verify window count
    if ((ctab = classes[gidisp_Class_Window])) {
        for (j = 0; j < CLASSHASH_SIZE; j++) {
            cref = ctab->bucket[j];
            for ( ; cref; cref = cref->next) {
                winct2++;
            }
        }
    }
    if (winct != winct2) {
        sprintf(errbuf, "\n[Autorestore warning: window count mismatch %d!=%d]\n", winct, winct2);
        iosif_win_puts(0, errbuf);
    }

    // freakin' great, so let's re-iterate, simultaneously doing an iteration and compare

    // start over, verify all window ids, including pairs
    win = NULL;
    for (i = 0; i < objects_count; i++) {
        // windows come first, in the correct order, alternated with their streams
        cur = objects + i;
        if (cur->type == gidisp_Class_Window) {
            foundwin = &cur->obj.win;

            win = gli_window_iterate_backward(win, NULL);
            if (win->type == foundwin->type) {
                win->rock = foundwin->rock;
                id = classes_find_id_for_object(gidisp_Class_Window, win);
                if (id != cur->id) {
                    cref_id = classes_pop_cref(gidisp_Class_Window, id);
                    cref_id->id = cur->id; // auto-awarding should verify that an id has not been reused
                    classes_push_cref(gidisp_Class_Window, cref_id);
                }
                //break; // This incorrect break was in cellardoor impl --
            } else {
                iosif_win_puts(0, "\nCould not restore saved state. Sorry. Aborting restore.\n");
                return FALSE;
            }
            // restore RECT
            win->bbox = foundwin->bbox;

            if (win->type == wintype_TextBuffer || win->type == wintype_TextGrid) {
                // read STREAM chunk
                i++;
                cur = objects + i;
                if (cur->type != gidisp_Class_Stream) {
                    iosif_win_puts(0, "\nMissing stream. Aborting restore.\n");
                    return FALSE;
                } else {
                    foundstr = &cur->obj.str;
                    str = win->str;

                    str->rock = foundstr->rock;
                    id = classes_find_id_for_object(gidisp_Class_Stream, str);
                    if (id != cur->id) {
                        cref_id = classes_pop_cref(gidisp_Class_Stream, id);
                        cref_id->id = cur->id; // auto-awarding should verify that an id has not been reused
                        classes_push_cref(gidisp_Class_Stream, cref_id);
                    }
                }
                // read STYLE chunk
                i++;
                cur = objects + i;
                if (cur->type != type_Style) {
                    // style chunk is not where it should be
                    iosif_win_puts(0, "\nMissing style chunk. Aborting restore.\n");
                    return FALSE;
                }
            } else if (win->type == wintype_Pair) {
                // read PAIR chunk
                i++;
                cur = objects + i;

                if (cur->type != type_Pair) {
                    iosif_win_puts(0, "\nCorrupt win pair. Aborting restore.\n");
                    return FALSE;
                } else {
                    struct glk_winpair_autosave *foundpair = &cur->obj.pair;
                    window_pair_t *pair = (window_pair_t *)win->data;

                    pair->splitpos = foundpair->splitpos;
                    pair->splitwidth = foundpair->splitwidth;
                    pair->dir = foundpair->dir;
                    pair->vertical = foundpair->vertical;
                    pair->backward = foundpair->backward;
                    pair->size = foundpair->size;
                }
            }
        } else if (cur->type == gidisp_Class_Stream) { // now do the streams
#if 0 // this doesn't work and seems to corrupt autorestore, e.g. Counterfeit Monkey
            stream_t *tempstr;

            found = FALSE;
            foundstr = &cur->obj.str;

            if ((ctab = classes[gidisp_Class_Stream])) {
                for (j = 0; j < CLASSHASH_SIZE; j++) {
                    cref = ctab->bucket[j];
                    for ( ; cref; cref = cref->next) {
                        tempstr = (stream_t *)cref->obj;
                        if (tempstr->type == foundstr->type && tempstr->rock == foundstr->rock) { // this id should be clearer
                            id = classes_find_id_for_object(gidisp_Class_Stream, tempstr);
                            if (id != cur->id) {
                                cref_id = classes_pop_cref(gidisp_Class_Stream, id);
                                cref_id->id = cur->id; // auto-awarding should verify that an id has not been reused
                                classes_push_cref(gidisp_Class_Stream, cref_id);
                            }
                            classes_denormalize_pointers(gidisp_Class_Stream, foundstr);

                            tempstr->rock = foundstr->rock;
                            if (tempstr->type != strtype_File && !tempstr->buf && foundstr->buf) {
                                tempstr->readcount = foundstr->readcount;
                                tempstr->writecount = foundstr->writecount;
                                tempstr->readable = foundstr->readable;
                                tempstr->writable = foundstr->writable;
                                tempstr->buf = foundstr->buf;
                                tempstr->bufptr = foundstr->bufptr;
                                tempstr->bufend = foundstr->bufend;
                                tempstr->bufeof = foundstr->bufeof;
                                tempstr->buflen = foundstr->buflen;
                                if (cur->iscurrent) {
                                    cur_str = tempstr;
                                }
                            } else if (tempstr->type == strtype_File) {
                                //fd("not touching file info for the moment");
                            }
                            found = TRUE;
                            break;
                        }
                    }
                    if (found)
                        break;
                }
            }
            if (!found) {
                // we're here because nothing matched; make a new stream
                sprintf(errbuf, "\n[Autorestore warning: a stream of type %s is missing: id %d]\n",
                        (cur->type == strtype_File) ? "strtype_File" :
                        (cur->type == strtype_Window) ? "strtype_Window" :
                        (cur->type == strtype_Memory) ? "strtype_Memory" : "UNKNOWN", (int)cur->id);
                iosif_win_puts(0, errbuf);
            }
#endif
        } else if (cur->type == gidisp_Class_Fileref) {
            //			iosif_win_puts(0, "\n[Autorestore warning: missing file stream]\n");
            if (*cur->obj.fref.filename && strcmp(cur->obj.fref.filename, kFrotzAutoSaveFile)!=0) {
                glui32 usage = (cur->obj.fref.textmode ? fileusage_TextMode : 0)
                               | (cur->obj.fref.filetype & fileusage_TypeMask);

                fileref_t *fref = gli_new_fileref(cur->obj.fref.filename, usage, cur->obj.fref.rock);
                id = classes_find_id_for_object(gidisp_Class_Fileref, fref);
                if (id != cur->id) {
                    cref_id = classes_pop_cref(gidisp_Class_Fileref, id);
                    cref_id->id = cur->id; // auto-awarding should verify that an id has not been reused
                    classes_push_cref(gidisp_Class_Fileref, cref_id);
                }
            }
        } else if (cur->type == type_Style) {
            if (cur->id == STYLEHINT_TEXT_BUFFER) {
                gli_window_set_stylehints((winid_t)STYLEHINT_TEXT_BUFFER, (GLK_STYLE_HINTS *)&cur->obj.style);
            } else if (cur->id == STYLEHINT_TEXT_GRID) {
                gli_window_set_stylehints((winid_t)STYLEHINT_TEXT_GRID, (GLK_STYLE_HINTS *)&cur->obj.style);
            }
        }
    }
    // restore current output stream
    if (cur_str) {
        glk_stream_set_current(cur_str);
    }
    return TRUE;
}
예제 #7
0
파일: t23run.cpp 프로젝트: BPaden/garglk
void glk_main(void)
{
    int stat;
    static const char *defexts[] = { "gam", "t3" };
    char prog_arg[OSFNMAX];
    char fname[OSFNMAX];
    int engine_ver;

    int argc = tads_argc;
    char **argv = tads_argv;

    winid_t mainwin;
    char buf[256];
    char copyright[512];
    char errorload[512];

#ifdef GARGLK
    garglk_set_program_name("TADS " TADS_RUNTIME_VERSION " / " T3VM_VSN_STRING);
    garglk_set_program_info(
                "TADS Interpreter by Michael J. Roberts\n"
                "TADS 2 VM version " TADS_RUNTIME_VERSION "\n"
                "T3 VM version " T3VM_VSN_STRING "\n"
                "Gargoyle port by Tor Andersson\n"
    );
#endif

    /* 
     *   if one of our special usage message arguments was given, show the
     *   usage 
     */
    if (argc == 2 && stricmp(argv[1], "-help2") == 0)
    {
        /* invoke the tads 2 main entrypoint with no arguments */
        main_t2(1, argv);
        
        /* that's all we need to do with this option */
        os_term(OSEXSUCC);
    }
    else if (argc == 2 && stricmp(argv[1], "-help3") == 0)
    {
        /* invoke the tads 3 main entrypoint with no arguments */
        main_t3(1, argv);
        
        /* that's all we need to do with this option */
        os_term(OSEXSUCC);
    }

    /* look at the arguments and try to find the program name */
    if (!vm_get_game_arg(argc, argv, prog_arg, sizeof(prog_arg), &engine_ver))
    {
        /* 
         *   there's no game file name specified or implied - show the
         *   generic combined v2/v3 usage message 
         */
        mainwin = glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
        glk_set_window(mainwin);

         /* copyright-date-string */
        sprintf(copyright,
                "TADS Interpreter - "
                "Copyright (c) 1993, 2004 Michael J. Roberts\n"
                "TADS 2 VM version " TADS_RUNTIME_VERSION " / "
                "T3 VM version " T3VM_VSN_STRING "\n\n");
        glk_put_string(copyright);

        sprintf(errorload,
                "Error: you didn't specify a game file name on the command "
                "line, or the command "
                "options are incorrect. You must specify the name of "
                "the game file you would "
                "like to run.\n"
                "\n"
                "If you'd like a list of command-line options for TADS 2 "
                "games, specify -help2 "
                "instead of giving a game file name. Or, if you'd like a "
                "list of command-line "
                "options for TADS 3, specify -help3.\n");
        glk_put_string(errorload);

        /* pause (if desired by OS layer) and exit */
        os_expause();
        os_term(OSEXFAIL);
    }

    /* determine the type of the game we have */
    engine_ver = vm_get_game_type(prog_arg, fname, sizeof(fname),
                                  defexts,
                                  sizeof(defexts)/sizeof(defexts[0]));

    /* presume failure */
    stat = OSEXFAIL;

    /* see what we have */
    switch(engine_ver)
    {
        case VM_GGT_TADS2:
            /* run the game using the TADS 2 engine */
            stat = main_t2(argc, argv);
            break;

        case VM_GGT_TADS3:
            /* run the game using the TADS 3 engine */
            stat = main_t3(argc, argv);
            break;

        case VM_GGT_INVALID:
            /* invalid file type */
            sprintf(buf,
                    "The file you have selected (%s) is not a valid game file.\n",
                    fname);
            mainwin = glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
            glk_set_window(mainwin);
            glk_put_string(buf);
            break;

        case VM_GGT_NOT_FOUND:
            /* file not found */
            sprintf(buf, "The game file (%s) cannot be found.\n", prog_arg);
            mainwin = glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
            glk_set_window(mainwin);
            glk_put_string(buf);
            break;

        case VM_GGT_AMBIG:
            /* ambiguous file */
            sprintf(buf,"The game file (%s) cannot be found exactly as given, "
                        "but multiple game "
                        "files with this name and different default suffixes "
                        "(.gam, .t3) exist. "
                        "Please specify the full name of the file, including the "
                        "suffix, that you "
                        "wish to use.\n",
                   prog_arg);
            mainwin = glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
            glk_set_window(mainwin);
            glk_put_string(buf);
            break;
    }

    /* pause (if desired by OS layer) and terminate with our status code */
    os_expause();
    os_term(stat);
}
예제 #8
0
void GlkInterface::initialize() {
	uint width, height;

	/*
	 * Init glk stuff
	 */

	 // monor
	glk_stylehint_set(wintype_AllTypes, style_Preformatted, stylehint_Proportional, 0);
	glk_stylehint_set(wintype_AllTypes, style_Preformatted, stylehint_Weight, 0);
	glk_stylehint_set(wintype_AllTypes, style_Preformatted, stylehint_Oblique, 0);

	// monob
	glk_stylehint_set(wintype_AllTypes, style_Subheader, stylehint_Proportional, 0);
	glk_stylehint_set(wintype_AllTypes, style_Subheader, stylehint_Weight, 1);
	glk_stylehint_set(wintype_AllTypes, style_Subheader, stylehint_Oblique, 0);

	// monoi
	glk_stylehint_set(wintype_AllTypes, style_Alert, stylehint_Proportional, 0);
	glk_stylehint_set(wintype_AllTypes, style_Alert, stylehint_Weight, 0);
	glk_stylehint_set(wintype_AllTypes, style_Alert, stylehint_Oblique, 1);

	// monoz
	glk_stylehint_set(wintype_AllTypes, style_BlockQuote, stylehint_Proportional, 0);
	glk_stylehint_set(wintype_AllTypes, style_BlockQuote, stylehint_Weight, 1);
	glk_stylehint_set(wintype_AllTypes, style_BlockQuote, stylehint_Oblique, 1);

	// propr
	glk_stylehint_set(wintype_TextBuffer, style_Normal, stylehint_Proportional, 1);
	glk_stylehint_set(wintype_TextGrid, style_Normal, stylehint_Proportional, 0);
	glk_stylehint_set(wintype_AllTypes, style_Normal, stylehint_Weight, 0);
	glk_stylehint_set(wintype_AllTypes, style_Normal, stylehint_Oblique, 0);

	// propb
	glk_stylehint_set(wintype_TextBuffer, style_Header, stylehint_Proportional, 1);
	glk_stylehint_set(wintype_TextGrid, style_Header, stylehint_Proportional, 0);
	glk_stylehint_set(wintype_AllTypes, style_Header, stylehint_Weight, 1);
	glk_stylehint_set(wintype_AllTypes, style_Header, stylehint_Oblique, 0);

	// propi
	glk_stylehint_set(wintype_TextBuffer, style_Emphasized, stylehint_Proportional, 1);
	glk_stylehint_set(wintype_TextGrid, style_Emphasized, stylehint_Proportional, 0);
	glk_stylehint_set(wintype_AllTypes, style_Emphasized, stylehint_Weight, 0);
	glk_stylehint_set(wintype_AllTypes, style_Emphasized, stylehint_Oblique, 1);

	// propi
	glk_stylehint_set(wintype_TextBuffer, style_Note, stylehint_Proportional, 1);
	glk_stylehint_set(wintype_TextGrid, style_Note, stylehint_Proportional, 0);
	glk_stylehint_set(wintype_AllTypes, style_Note, stylehint_Weight, 1);
	glk_stylehint_set(wintype_AllTypes, style_Note, stylehint_Oblique, 1);

	/*
	 * Get the screen size
	 */

	gos_lower = glk_window_open(0, 0, 0, wintype_TextGrid, 0);
	if (!gos_lower)
		gos_lower = glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
	glk_window_get_size(gos_lower, &width, &height);
	glk_window_close(gos_lower, nullptr);

	gos_channel = nullptr;

	/*
	 * Icky magic bit setting
	 */

	if (h_version == V3 && _tandyBit)
		h_config |= CONFIG_TANDY;

	if (h_version == V3 && gos_upper)
		h_config |= CONFIG_SPLITSCREEN;

	if (h_version == V3 && !gos_upper)
		h_config |= CONFIG_NOSTATUSLINE;

	if (h_version >= V4)
		h_config |= CONFIG_BOLDFACE | CONFIG_EMPHASIS |
		CONFIG_FIXED | CONFIG_TIMEDINPUT | CONFIG_COLOUR;

	if (h_version >= V5)
		h_flags &= ~(GRAPHICS_FLAG | MOUSE_FLAG | MENU_FLAG);

	if ((h_version >= 5) && (h_flags & SOUND_FLAG))
		h_flags |= SOUND_FLAG;

	if ((h_version == 3) && (h_flags & OLD_SOUND_FLAG))
		h_flags |= OLD_SOUND_FLAG;

	if ((h_version == 6) && (_sound != 0))
		h_config |= CONFIG_SOUND;

	if (h_version >= V5 && (h_flags & UNDO_FLAG))
		if (_undo_slots == 0)
			h_flags &= ~UNDO_FLAG;

	h_screen_cols = width;
	h_screen_rows = height;

	h_screen_height = h_screen_rows;
	h_screen_width = h_screen_cols;

	h_font_width = 1;
	h_font_height = 1;

	// Must be after screen dimensions are computed
	if (g_conf->_graphics) {
		if (_blorb)
			// Blorb file containers allow graphics
			h_flags |= GRAPHICS_FLAG;
		else if ((h_version == V6 || _storyId == BEYOND_ZORK) && initPictures())
			// Earlier Infocom game with picture files
			h_flags |= GRAPHICS_FLAG;
	}

	// Use the ms-dos interpreter number for v6, because that's the
	// kind of graphics files we understand
	h_interpreter_number = h_version == 6 ? INTERP_MSDOS : INTERP_AMIGA;
	h_interpreter_version = 'F';

	// Set these per spec 8.3.2.
	h_default_foreground = WHITE_COLOUR;
	h_default_background = BLACK_COLOUR;
	if (h_flags & COLOUR_FLAG)
		h_flags &= ~COLOUR_FLAG;

	/*
	 * Open the windows
	 */
	if (_storyId == BEYOND_ZORK)
		showBeyondZorkTitle();

	gos_lower = glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
	gos_upper = glk_window_open(gos_lower,
		winmethod_Above | winmethod_Fixed,
		0,
		wintype_TextGrid, 0);

	glk_set_window(gos_lower);
	gos_curwin = gos_lower;

	// Set the screen colors
	garglk_set_zcolors(_defaultForeground, _defaultBackground);

	// Add any sound folder or zip
	addSound();
}
예제 #9
0
파일: glkmisc.c 프로젝트: BPaden/garglk
void os_init_screen(void)
{
	glui32 width, height;

	/*
	 * Init glk stuff
	 */

	/* monor */
	glk_stylehint_set(wintype_AllTypes,   style_Preformatted, stylehint_Proportional, 0);
	glk_stylehint_set(wintype_AllTypes,   style_Preformatted, stylehint_Weight, 0);
	glk_stylehint_set(wintype_AllTypes,   style_Preformatted, stylehint_Oblique, 0);

	/* monob */
	glk_stylehint_set(wintype_AllTypes,   style_Subheader,    stylehint_Proportional, 0);
	glk_stylehint_set(wintype_AllTypes,   style_Subheader,    stylehint_Weight, 1);
	glk_stylehint_set(wintype_AllTypes,   style_Subheader,    stylehint_Oblique, 0);

	/* monoi */
	glk_stylehint_set(wintype_AllTypes,   style_Alert,        stylehint_Proportional, 0);
	glk_stylehint_set(wintype_AllTypes,   style_Alert,        stylehint_Weight, 0);
	glk_stylehint_set(wintype_AllTypes,   style_Alert,        stylehint_Oblique, 1);

	/* monoz */
	glk_stylehint_set(wintype_AllTypes,   style_BlockQuote,   stylehint_Proportional, 0);
	glk_stylehint_set(wintype_AllTypes,   style_BlockQuote,   stylehint_Weight, 1);
	glk_stylehint_set(wintype_AllTypes,   style_BlockQuote,   stylehint_Oblique, 1);

	/* propr */
	glk_stylehint_set(wintype_TextBuffer, style_Normal,       stylehint_Proportional, 1);
	glk_stylehint_set(wintype_TextGrid,   style_Normal,       stylehint_Proportional, 0);
	glk_stylehint_set(wintype_AllTypes,   style_Normal,       stylehint_Weight, 0);
	glk_stylehint_set(wintype_AllTypes,   style_Normal,       stylehint_Oblique, 0);

	/* propb */
	glk_stylehint_set(wintype_TextBuffer, style_Header,       stylehint_Proportional, 1);
	glk_stylehint_set(wintype_TextGrid,   style_Header,       stylehint_Proportional, 0);
	glk_stylehint_set(wintype_AllTypes,   style_Header,       stylehint_Weight, 1);
	glk_stylehint_set(wintype_AllTypes,   style_Header,       stylehint_Oblique, 0);

	/* propi */
	glk_stylehint_set(wintype_TextBuffer, style_Emphasized,   stylehint_Proportional, 1);
	glk_stylehint_set(wintype_TextGrid,   style_Emphasized,   stylehint_Proportional, 0);
	glk_stylehint_set(wintype_AllTypes,   style_Emphasized,   stylehint_Weight, 0);
	glk_stylehint_set(wintype_AllTypes,   style_Emphasized,   stylehint_Oblique, 1);

	/* propi */
	glk_stylehint_set(wintype_TextBuffer, style_Note,         stylehint_Proportional, 1);
	glk_stylehint_set(wintype_TextGrid,   style_Note,         stylehint_Proportional, 0);
	glk_stylehint_set(wintype_AllTypes,   style_Note,         stylehint_Weight, 1);
	glk_stylehint_set(wintype_AllTypes,   style_Note,         stylehint_Oblique, 1);

	gos_lower = glk_window_open(0, 0, 0, wintype_TextGrid, 0);
	if (!gos_lower)
		gos_lower = glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
	glk_window_get_size(gos_lower, &width, &height);
	glk_window_close(gos_lower, NULL);

	gos_lower = glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
	gos_upper = glk_window_open(gos_lower,
			winmethod_Above | winmethod_Fixed,
			0,
			wintype_TextGrid, 0);

	gos_channel = NULL;

	glk_set_window(gos_lower);
	gos_curwin = gos_lower;

	/*
	 * Icky magic bit setting
	 */

	if (h_version == V3 && user_tandy_bit)
		h_config |= CONFIG_TANDY;

	if (h_version == V3 && gos_upper)
		h_config |= CONFIG_SPLITSCREEN;

	if (h_version == V3 && !gos_upper)
		h_config |= CONFIG_NOSTATUSLINE;

	if (h_version >= V4)
		h_config |= CONFIG_BOLDFACE | CONFIG_EMPHASIS |
			CONFIG_FIXED | CONFIG_TIMEDINPUT | CONFIG_COLOUR;

	if (h_version >= V5)
		h_flags &= ~(GRAPHICS_FLAG | MOUSE_FLAG | MENU_FLAG);

	if ((h_version >= 5) && (h_flags & SOUND_FLAG))
		h_flags |= SOUND_FLAG;

	if ((h_version == 3) && (h_flags & OLD_SOUND_FLAG))
		h_flags |= OLD_SOUND_FLAG;

	if ((h_version == 6) && (option_sound != 0)) 
		h_config |= CONFIG_SOUND;

	if (h_version >= V5 && (h_flags & UNDO_FLAG))
		if (option_undo_slots == 0)
			h_flags &= ~UNDO_FLAG;

	h_screen_cols = width;
	h_screen_rows = height;

	h_screen_height = h_screen_rows;
	h_screen_width = h_screen_cols;

	h_font_width = 1;
	h_font_height = 1;

	/* Must be after screen dimensions are computed.  */
	if (h_version == V6) {
		h_flags &= ~GRAPHICS_FLAG;
	}

	/* Use the ms-dos interpreter number for v6, because that's the
	 * kind of graphics files we understand.  Otherwise, use DEC.  */
	h_interpreter_number = h_version == 6 ? INTERP_MSDOS : INTERP_DEC_20;
	h_interpreter_version = 'F';
	{
		/* Set these per spec 8.3.2. */
		h_default_foreground = WHITE_COLOUR;
		h_default_background = BLACK_COLOUR;
		if (h_flags & COLOUR_FLAG) h_flags &= ~COLOUR_FLAG;
	}
}
예제 #10
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 */
  }
}
예제 #11
0
파일: heglk.c 프로젝트: BPaden/garglk
void hugo_settextpos(int x, int y)
{
/* The top-left corner of the current active window is (1, 1). */

	if (currentwin==NULL) return;

	/* Try to determine if we're trying to position fixed-width
	   text in the main window, as in a menu, for example
	*/
	if (!just_cleared_screen && !inwindow &&
		!(glk_current_font & PROP_FONT)
		&& y!=1			/* not just cls */
		&& y < SCREENHEIGHT-0x0f)	/* 0x0f is arbitrary */
	{
		/* See if we're already in the auxiliary window */
		if (currentwin!=auxwin)
		{
			/* If not, create it, making it 100% of
			   mainwin's height
			*/
			if (auxwin==NULL)
			{
				auxwin = glk_window_open(mainwin,
					winmethod_Below | winmethod_Proportional,
					100,
					wintype_TextGrid,
					0);
			}
			else
				glk_window_clear(auxwin);

			glk_set_window(currentwin = auxwin);
		}
	}

	/* On the other hand, if we were in a textgrid window and
	   no longer need to be, get out
	*/
	else if (auxwin)
	{
		stream_result_t sr;

		/* Close auxwin */
		glk_window_close(auxwin, &sr);
		auxwin = NULL;

		/* Clear the screen (both windows) */
		glk_window_clear(mainwin);
		glk_window_clear(secondwin);

		glk_set_window(currentwin = mainwin);
	}

	just_cleared_screen = false;

	/* Can only move the Glk cursor in a textgrid window */
	if (currentwin!=mainwin)
		glk_window_move_cursor(currentwin, x-1, y-1);

	/* Must be set: */
	currentline = y;
	currentpos = (x-1)*CHARWIDTH;   /* Note:  zero-based */
}
예제 #12
0
파일: heglk.c 프로젝트: BPaden/garglk
void hugo_settextwindow(int left, int top, int right, int bottom)
{
	static int secondwin_bottom = 0;

	/* Hugo's arbitrarily positioned windows don't currently
	   mesh with what Glk has to offer, so we have to ignore any
	   non-Glk-ish Windows and just maintain the current
	   parameters
	*/
	if ((top!=1 || bottom>=physical_windowbottom/FIXEDLINEHEIGHT+1)
		/* Pre-v2.4 didn't support proper windowing */
		&& (game_version>=24 || !inwindow))
	{
		in_valid_window = false;
		
		/* Glk-illegal floating window; setting currentwin
		   to NULL will tell hugo_print() not to print in it:
		*/
		if (bottom<physical_windowbottom/FIXEDLINEHEIGHT+1)
		{
			currentwin = NULL;
			glk_set_window(mainwin);
			return;
		}
		else
			glk_set_window(currentwin = mainwin);
	}

	/* Otherwise this is a valid window (positioned along the
	   top of the screen a la a status window), so... */
	else
	{
		/* Arbitrary height of 4 lines for pre-v2.4 windows */
		if (game_version < 24) bottom = 4;

		/* ...either create a new window if none exists... */
		if (!secondwin)
		{
			glk_stylehint_set (wintype_TextGrid, style_Normal, stylehint_ReverseColor, 1);
			glk_stylehint_set (wintype_TextGrid, style_Subheader, stylehint_ReverseColor, 1);
			glk_stylehint_set (wintype_TextGrid, style_Emphasized, stylehint_ReverseColor, 1);

			winid_t p;

			p = glk_window_get_parent(mainwin);
			secondwin = glk_window_open(mainwin,//p,
				winmethod_Above | winmethod_Fixed,
				bottom,
				wintype_TextGrid,
				0);
		}

		/* ...or resize the existing one if necessary */
		else if (bottom!=secondwin_bottom)
		{
			winid_t p;

			p  = glk_window_get_parent(secondwin);
			glk_window_set_arrangement(p, 
				winmethod_Above | winmethod_Fixed,
				bottom,
				secondwin);
		}

		if (secondwin)
		{
			if (game_version < 24)
				glk_window_clear(secondwin);

			glk_set_window(currentwin = secondwin);
			in_valid_window = true;
			secondwin_bottom = bottom;
		}
		else
		{
			currentwin = NULL;
			glk_set_window(mainwin);
			secondwin_bottom = 0;
			return;
		}
	}

	physical_windowleft = (left-1)*FIXEDCHARWIDTH;
	physical_windowtop = (top-1)*FIXEDLINEHEIGHT;
	physical_windowright = right*FIXEDCHARWIDTH-1;
	physical_windowbottom = bottom*FIXEDLINEHEIGHT-1;
	physical_windowwidth = (right-left+1)*FIXEDCHARWIDTH;
	physical_windowheight = (bottom-top+1)*FIXEDLINEHEIGHT;
}
예제 #13
0
파일: multiwin.c 프로젝트: chimara/Chimara
/* The glk_main() function is called by the Glk system; it's the main entry
    point for your program. */
void glk_main(void)
{
    char commandbuf1[256]; /* For mainwin1 */
    char commandbuf2[256]; /* For mainwin2 */

    /* Open the main windows. */
    mainwin1 = glk_window_open(0, 0, 0, wintype_TextBuffer, 1);
    if (!mainwin1) {
        /* It's possible that the main window failed to open. There's
            nothing we can do without it, so exit. */
        return;
    }

    /* Open a second window: a text grid, above the main window, five
        lines high. It is possible that this will fail also, but we accept
        that. */
    statuswin = glk_window_open(mainwin1,
        winmethod_Above | winmethod_Fixed,
        5, wintype_TextGrid, 0);

    /* And a third window, a second story window below the main one. */
    mainwin2 = glk_window_open(mainwin1,
        winmethod_Below | winmethod_Proportional,
        50, wintype_TextBuffer, 0);

    /* We're going to be switching from one window to another all the
        time. So we'll be setting the output stream on a case-by-case
        basis. Every function that prints must set the output stream
        first. (Contrast model.c, where the output stream is always the
        main window, and every function that changes that must set it
        back afterwards.) */

    glk_set_window(mainwin1);
    glk_put_string("Multiwin\nAn Interactive Sample Glk Program\n");
    glk_put_string("By Andrew Plotkin.\nRelease 3.\n");
    glk_put_string("Type \"help\" for a list of commands.\n");

    glk_set_window(mainwin2);
    glk_put_string("Note that the upper left-hand window accepts character");
    glk_put_string(" input. Hit 'h' to split the window horizontally, 'v' to");
    glk_put_string(" split the window vertically, 'c' to close a window,");
    glk_put_string(" and any other key (including special keys) to display");
    glk_put_string(" key codes. All new windows accept these same keys as");
    glk_put_string(" well.\n\n");
    glk_put_string("This bottom window accepts normal line input.\n");

    if (statuswin) {
        /* For fun, let's open a fourth window now, splitting the status
            window. */
        winid_t keywin;
        keywin = glk_window_open(statuswin,
            winmethod_Left | winmethod_Proportional,
            66, wintype_TextGrid, KEYWINROCK);
        if (keywin) {
            glk_request_char_event(keywin);
        }
    }

    /* Draw the key window now, since we don't draw it every input (as
        we do the status window. */
    draw_keywins();

    inputpending1 = FALSE;
    inputpending2 = FALSE;
    already1 = 0;
    already2 = 0;

    while (1) {
        char *cx, *cmd;
        int doneloop, len;
        winid_t whichwin = NULL;
        event_t ev;

        draw_statuswin();
        /* We're not redrawing the key windows every command. */

        /* Either main window, or both, could already have line input
            pending. If so, leave that window alone. If there is no
            input pending on a window, set a line input request, but
            keep around any characters that were in the buffer already. */

        if (mainwin1 && !inputpending1) {
            glk_set_window(mainwin1);
            glk_put_string("\n>");
            /* We request up to 255 characters. The buffer can hold 256,
                but we are going to stick a null character at the end, so
                we have to leave room for that. Note that the Glk library
                does *not* put on that null character. */
            glk_request_line_event(mainwin1, commandbuf1, 255, already1);
            inputpending1 = TRUE;
        }

        if (mainwin2 && !inputpending2) {
            glk_set_window(mainwin2);
            glk_put_string("\n>");
            /* See above. */
            glk_request_line_event(mainwin2, commandbuf2, 255, already2);
            inputpending2 = TRUE;
        }

        doneloop = FALSE;
        while (!doneloop) {

            /* Grab an event. */
            glk_select(&ev);

            switch (ev.type) {

                case evtype_LineInput:
                    /* If the event comes from one main window or the other,
                        we mark that window as no longer having line input
                        pending. We also set commandbuf to point to the
                        appropriate buffer. Then we leave the event loop. */
                    if (mainwin1 && ev.win == mainwin1) {
                        whichwin = mainwin1;
                        inputpending1 = FALSE;
                        cmd = commandbuf1;
                        doneloop = TRUE;
                    }
                    else if (mainwin2 && ev.win == mainwin2) {
                        whichwin = mainwin2;
                        inputpending2 = FALSE;
                        cmd = commandbuf2;
                        doneloop = TRUE;
                    }
                    break;

                case evtype_CharInput:
                    /* It's a key event, from one of the keywins. We
                        call a subroutine rather than exiting the
                        event loop (although I could have done it
                        that way too.) */
                    perform_key(ev.win, ev.val1);
                    break;

                case evtype_Timer:
                    /* It's a timer event. This does exit from the event
                        loop, since we're going to interrupt input in
                        mainwin1 and then re-print the prompt. */
                    whichwin = NULL;
                    cmd = NULL;
                    doneloop = TRUE;
                    break;

                case evtype_Arrange:
                    /* Windows have changed size, so we have to redraw the
                        status window and key window. But we stay in the
                        event loop. */
                    draw_statuswin();
                    draw_keywins();
                    break;
            }
        }

        if (cmd == NULL) {
            /* It was a timer event. */
            perform_timer();
            continue;
        }

        /* It was a line input event. cmd now points at a line of input
            from one of the main windows. */

        /* The line we have received in commandbuf is not null-terminated.
            We handle that first. */
        len = ev.val1; /* Will be between 0 and 255, inclusive. */
        cmd[len] = '\0';

        /* Then squash to lower-case. */
        for (cx = cmd; *cx; cx++) {
            *cx = glk_char_to_lower(*cx);
        }

        /* Then trim whitespace before and after. */

        for (cx = cmd; *cx == ' '; cx++, len--) { };

        cmd = cx;

        for (cx = cmd+len-1; cx >= cmd && *cx == ' '; cx--) { };
        *(cx+1) = '\0';

        /* cmd now points to a nice null-terminated string. We'll do the
            simplest possible parsing. */
        if (str_eq(cmd, "")) {
            glk_set_window(whichwin);
            glk_put_string("Excuse me?\n");
        }
        else if (str_eq(cmd, "help")) {
            verb_help(whichwin);
        }
        else if (str_eq(cmd, "yada")) {
            verb_yada(whichwin);
        }
        else if (str_eq(cmd, "both")) {
            verb_both(whichwin);
        }
        else if (str_eq(cmd, "clear")) {
            verb_clear(whichwin);
        }
        else if (str_eq(cmd, "page")) {
            verb_page(whichwin);
        }
        else if (str_eq(cmd, "pageboth")) {
            verb_pageboth(whichwin);
        }
        else if (str_eq(cmd, "timer")) {
            verb_timer(whichwin);
        }
        else if (str_eq(cmd, "untimer")) {
            verb_untimer(whichwin);
        }
        else if (str_eq(cmd, "chars")) {
            verb_chars(whichwin);
        }
        else if (str_eq(cmd, "jump")) {
            verb_jump(whichwin);
        }
        else if (str_eq(cmd, "quit")) {
            verb_quit(whichwin);
        }
        else {
            glk_set_window(whichwin);
            glk_put_string("I don't understand the command \"");
            glk_put_string(cmd);
            glk_put_string("\".\n");
        }

        if (whichwin == mainwin1)
            already1 = 0;
        else if (whichwin == mainwin2)
            already2 = 0;
    }
}
예제 #14
0
파일: multiwin.c 프로젝트: chimara/Chimara
/* React to character input in a key window. */
static void perform_key(winid_t win, glui32 key)
{
    glui32 width, height, len;
    int ix;
    char buf[128], keyname[64];

    if (key == 'h' || key == 'v') {
        winid_t newwin;
        glui32 loc;
        /* Open a new keywindow. */
        if (key == 'h')
            loc = winmethod_Right | winmethod_Proportional;
        else
            loc = winmethod_Below | winmethod_Proportional;
        newwin = glk_window_open(win,
            loc, 50, wintype_TextGrid, KEYWINROCK);
        /* Since the new window has rock value KEYWINROCK, the
            draw_keywins() routine will redraw it. */
        if (newwin) {
            /* Request character input. In this program, only keywins
                get char input, so the CharInput events always call
                perform_key() -- and so the new window will respond
                to keys just as this one does. */
            glk_request_char_event(newwin);
            /* We now have to redraw the keywins, because any or all of
                them could have changed size when we opened newwin.
                glk_window_open() does not generate Arrange events; we
                have to do the redrawing manually. */
            draw_keywins();
        }
        /* Re-request character input for this window, so that future
            keys are accepted. */
        glk_request_char_event(win);
        return;
    }
    else if (key == 'c') {
        /* Close this keywindow. */
        glk_window_close(win, NULL);
        /* Again, any key windows could have changed size. Also the
            status window could have (if this was the last key window). */
        draw_keywins();
        draw_statuswin();
        return;
    }

    /* Print a string naming the key that was just hit. */

    switch (key) {
        case ' ':
            str_cpy(keyname, "space");
            break;
        case keycode_Left:
            str_cpy(keyname, "left");
            break;
        case keycode_Right:
            str_cpy(keyname, "right");
            break;
        case keycode_Up:
            str_cpy(keyname, "up");
            break;
        case keycode_Down:
            str_cpy(keyname, "down");
            break;
        case keycode_Return:
            str_cpy(keyname, "return");
            break;
        case keycode_Delete:
            str_cpy(keyname, "delete");
            break;
        case keycode_Escape:
            str_cpy(keyname, "escape");
            break;
        case keycode_Tab:
            str_cpy(keyname, "tab");
            break;
        case keycode_PageUp:
            str_cpy(keyname, "page up");
            break;
        case keycode_PageDown:
            str_cpy(keyname, "page down");
            break;
        case keycode_Home:
            str_cpy(keyname, "home");
            break;
        case keycode_End:
            str_cpy(keyname, "end");
            break;
        default:
            if (key <= keycode_Func1 && key >= keycode_Func12) {
                str_cpy(keyname, "function key");
            }
            else if (key < 32) {
                str_cpy(keyname, "ctrl-");
                keyname[5] = '@' + key;
                keyname[6] = '\0';
            }
            else if (key <= 255) {
                keyname[0] = key;
                keyname[1] = '\0';
            }
            else {
                str_cpy(keyname, "unknown key");
            }
            break;
    }

    str_cpy(buf, "Key: ");
    str_cat(buf, keyname);

    len = str_len(buf);

    /* Print the string centered in this window. */
    glk_set_window(win);
    glk_window_get_size(win, &width, &height);
    glk_window_move_cursor(win, 0, height/2);
    for (ix=0; ix<width; ix++)
        glk_put_char(' ');

    width = width/2;
    len = len/2;

    if (width > len)
        width = width-len;
    else
        width = 0;

    glk_window_move_cursor(win, width, height/2);
    glk_put_string(buf);

    /* Re-request character input for this window, so that future
        keys are accepted. */
    glk_request_char_event(win);
}
예제 #15
0
void glk_main(void)
{
    winid_t win_a = NULL, win_b = NULL, win_c = NULL, win_d = NULL;
	
	fprintf(stderr, "TEST CASES FROM GLK SPEC\n\n"
			"(Press a key in window A to continue each time)\n\n"
			"Say you do two splits, each a 50-50 percentage split. You start\n"
			"with the original window A, and split that into A and B; then\n"
			"you split B into B and C.\n\n");
	
	win_a = glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
	win_b = glk_window_open(win_a, winmethod_Proportional | winmethod_Below,
							50, wintype_TextBuffer, 0);
	win_c = glk_window_open(win_b, winmethod_Proportional | winmethod_Below,
							50, wintype_TextBuffer, 0);
	if(!win_a || !win_b || !win_c)
		return;
	center_text(win_a, "A");
	center_text(win_b, "B");
	center_text(win_c, "C");
	
	wait_for_key(win_a);
	glk_window_close(glk_window_get_root(), NULL);
	
	fprintf(stderr, "Or, you could split A into A and B, and then split A\n"
			"again into A and C.\n\n");
	
	win_a = glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
	win_b = glk_window_open(win_a, winmethod_Proportional | winmethod_Below,
							50, wintype_TextBuffer, 0);
	win_c = glk_window_open(win_a, winmethod_Proportional | winmethod_Below,
							50, wintype_TextBuffer, 0);
	if(!win_a || !win_b || !win_c)
		return;
	center_text(win_a, "A");
	center_text(win_b, "B");
	center_text(win_c, "C");
	
	wait_for_key(win_a);
	glk_window_close(glk_window_get_root(), NULL);
	
	fprintf(stderr, "Here are more ways to perform the first example; all of\n"
			"them have the same tree structure, but look different on the\n"
			"screen. Here, we turn the second split (B into B/C) upside down;\n"
			"we put the new window (C) above the old window (B).\n\n");
	
	win_a = glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
	win_b = glk_window_open(win_a, winmethod_Proportional | winmethod_Below,
							50, wintype_TextBuffer, 0);
	win_c = glk_window_open(win_b, winmethod_Proportional | winmethod_Above,
							50, wintype_TextBuffer, 0);
	if(!win_a || !win_b || !win_c)
		return;
	center_text(win_a, "A");
	center_text(win_b, "B");
	center_text(win_c, "C");
	
	wait_for_key(win_a);
	glk_window_close(glk_window_get_root(), NULL);
			
	fprintf(stderr, "Here, we mess with the percentages. The first split (A\n"
			"into A/B) is a 25-75 split, which makes B three times the size\n"
			"of A. The second (B into B/C) is a 33-66 split, which makes C\n"
			"twice the size of B. This looks rather like the second example,\n"
			"but has a different internal structure.\n\n");
	
	win_a = glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
	win_b = glk_window_open(win_a, winmethod_Proportional | winmethod_Below,
							75, wintype_TextBuffer, 0);
	win_c = glk_window_open(win_b, winmethod_Proportional | winmethod_Below,
							67, wintype_TextBuffer, 0);
	if(!win_a || !win_b || !win_c)
		return;
	center_text(win_a, "A");
	center_text(win_b, "B");
	center_text(win_c, "C");
	
	wait_for_key(win_a);
	glk_window_close(glk_window_get_root(), NULL);
	
	fprintf(stderr, "Here, the second split (B into B/C) is vertical instead\n"
			"of horizontal, with the new window (C) on the left of the old\n"
			"one.\n\n");
	
	win_a = glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
	win_b = glk_window_open(win_a, winmethod_Proportional | winmethod_Below,
							50, wintype_TextBuffer, 0);
	win_c = glk_window_open(win_b, winmethod_Proportional | winmethod_Left,
							50, wintype_TextBuffer, 0);
	if(!win_a || !win_b || !win_c)
		return;
	center_text(win_a, "A");
	center_text(win_b, "B");
	center_text(win_c, "C");
	
	wait_for_key(win_a);
	glk_window_close(glk_window_get_root(), NULL);
	
	fprintf(stderr, "In the following two-split process, you can see that\n"
			"when a window is split, it is replaced by a new pair window, and\n"
			"moves down to become one of its two children.\n\n");
	
	if(!(win_a = glk_window_open(0, 0, 0, wintype_TextBuffer, 0)))
		return;
	center_text(win_a, "A");
	wait_for_key(win_a);
	
	if(!(win_b = glk_window_open(win_a, 
								 winmethod_Proportional | winmethod_Below,
								 50, wintype_TextBuffer, 0)))
		return;
	center_text(win_a, "A");
	center_text(win_b, "B");
	wait_for_key(win_a);
	
	if(!(win_c = glk_window_open(win_b, winmethod_Proportional | winmethod_Left,
								 50, wintype_TextBuffer, 0)))
		return;
	center_text(win_a, "A");
	center_text(win_b, "B");
	center_text(win_c, "C");
	wait_for_key(win_a);
	
	glk_window_close(glk_window_get_root(), NULL);
	
	fprintf(stderr, "What happens when there is a conflict? The rules are\n"
			"simple. Size control always flows down the tree, and the player\n"
			"is at the top. Let's bring out an example: first we split A into\n"
			"A and B, with a 50%% proportional split. Then we split A into A\n"
			"and C, with C above, being a text grid window, and C gets a\n"
			"fixed size of two rows (as measured in its own font size). A\n"
			"gets whatever remains of the 50%% it had before.\n\n");
	
	win_a = glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
	win_b = glk_window_open(win_a, winmethod_Proportional | winmethod_Below,
							50, wintype_TextBuffer, 0);
	win_c = glk_window_open(win_a, winmethod_Fixed | winmethod_Above,
							2, wintype_TextGrid, 0);
	if(!win_a || !win_b || !win_c)
		return;
	center_text(win_a, "A");
	center_text(win_b, "B: 50%");
	print_two_rows(win_c);
	wait_for_key(win_a);
	
	fprintf(stderr, "(Stage 1) Now the player stretches the window\n"
			"vertically.\n\n");
	
	wait_for_key(win_a);
	
	fprintf(stderr, "(Stage 2) Then the user maliciously starts squeezing the\n"
			"window down, in stages.\n\n");
	
	center_text(win_a, "A");
	center_text(win_b, "B: 50%");
	print_two_rows(win_c);
	wait_for_key(win_a);
	
	fprintf(stderr, "(Stage 3) The logic remains the same. At stage 3,\n"
			"there's no room left for A, so it winds up with zero height.\n"
			"Nothing displayed in A will be visible.\n\n");
	
	center_text(win_a, "A");
	center_text(win_b, "B");
	center_text(win_c, "C");
	wait_for_key(win_a);
	
	fprintf(stderr, "(Stage 4) At stage 4, there isn't even room in the upper\n"
			"50%% to give C its two rows; so it only gets one.\n\n");
	
	center_text(win_a, "A");
	center_text(win_b, "B");
	center_text(win_c, "C");
	wait_for_key(win_a);
	
	fprintf(stderr, "(Stage 5) Finally, C is squashed out of existence as\n"
			"well.\n\n");
	
	center_text(win_a, "A");
	center_text(win_b, "B");
	wait_for_key(win_a);
	
	glk_window_close(glk_window_get_root(), NULL);
	
	fprintf(stderr, "What happens when you split a fixed-size window? The\n"
			"resulting pair window retains the same size constraint as the\n"
			"original window that was split. The key window for the original\n"
			"split is still the key window for that split, even though it's\n"
			"now a grandchild instead of a child.\n\n");
	
	if(!(win_a = glk_window_open(0, 0, 0, wintype_TextBuffer, 0)))
		return;
	center_text(win_a, "A");
	wait_for_key(win_a);
	
	fprintf(stderr, "After the first split, the new pair window (O1, which\n"
			"covers the whole screen) knows that its first child (A) is above\n"
			"the second, and gets 50%% of its own area. (A is the key window\n"
			"for this split, but a proportional split doesn't care about key\n"
			"windows.)\n\n");
	
	if(!(win_b = glk_window_open(win_a, 
								 winmethod_Proportional | winmethod_Below,
								 50, wintype_TextBuffer, 0)))
		return;
	center_text(win_a, "A: 50%");
	center_text(win_b, "B");
	wait_for_key(win_a);
	
	fprintf(stderr, "After the second split, all this remains true; O1 knows\n"
			"that its first child gets 50%% of its space, and A is O1's key\n"
			"window. But now O1's first child is O2 instead of A. The newer\n"
			"pair window (O2) knows that its first child (C) is above the\n"
			"second, and gets a fixed size of two rows. (As measured in C's\n"
			"font, because C is O2's key window.)\n\n");
	
	if(!(win_c = glk_window_open(win_a, winmethod_Fixed | winmethod_Above, 2,
								 wintype_TextGrid, 0)))
		return;
	center_text(win_a, "A");
	center_text(win_b, "B");
	print_two_rows(win_c);
	wait_for_key(win_a);
	
	fprintf(stderr, "If we split C, now, the resulting pair will still be two\n"
			"C-font rows high -- that is, tall enough for two lines of\n"
			"whatever font C displays. For the sake of example, we'll do this\n"
			"vertically.\n\n");
	
	if(!(win_d = glk_window_open(win_c, 
								 winmethod_Proportional | winmethod_Right,
								 50, wintype_TextBuffer, 0)))
		return;
	center_text(win_a, "A");
	center_text(win_b, "B");
	center_text(win_c, "C");
	center_text(win_d, "D");
	wait_for_key(win_a);
	
	fprintf(stderr, "When you close a window (and it is not the root window),\n"
			"the other window in its pair takes over all the freed-up area.\n"
			"Let's close D, in the current example:\n\n");
	
	glk_window_close(win_d, NULL);
	center_text(win_a, "A");
	center_text(win_b, "B");
	center_text(win_c, "C");
	wait_for_key(win_a);
	
	fprintf(stderr, "But what if we had closed C instead of D? We would have\n"
			"gotten this:\n\n");
	
	glk_window_close(glk_window_get_root(), NULL);
	win_a = glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
	win_b = glk_window_open(win_a, winmethod_Proportional | winmethod_Below, 50,
							wintype_TextBuffer, 0);
	win_c = glk_window_open(win_a, winmethod_Fixed | winmethod_Above, 2,
							wintype_TextGrid, 0);
	win_d = glk_window_open(win_c, winmethod_Proportional | winmethod_Right, 50,
							wintype_TextBuffer, 0);
	glk_window_close(win_c, NULL);
	center_text(win_a, "A");
	center_text(win_b, "B");
	center_text(win_d, "D");
	wait_for_key(win_a);
	
	fprintf(stderr, "Consider the example above, where D had collapsed to\n"
			"zero height. Say D was a text buffer window. You could make a\n"
			"more useful layout:\n\n");
	winid_t o2 = glk_window_get_parent(win_d);
	glk_window_set_arrangement(o2, winmethod_Above | winmethod_Fixed, 3, win_d);
	center_text(win_a, "A");
	center_text(win_b, "B");
	center_text(win_d, "D");
	wait_for_key(win_a);
	
	fprintf(stderr, "If you later wanted to expand D to five rows:\n\n");
	glk_window_set_arrangement(o2, winmethod_Above | winmethod_Fixed, 5, NULL);
	center_text(win_a, "A");
	center_text(win_b, "B");
	center_text(win_d, "D");
	wait_for_key(win_a);
	
	fprintf(stderr, "This changes the constraint to be on the lower child of\n"
			"O2, which is A. The key window is still D; so A would then be\n"
			"three rows high as measured in D's font, and D would get the\n"
			"rest of O2's space. That may not be what you want.\n\n");
	glk_window_set_arrangement(o2, winmethod_Below | winmethod_Fixed, 3, NULL);
	center_text(win_a, "A");
	center_text(win_b, "B");
	center_text(win_d, "D");
	wait_for_key(win_a);
	
	fprintf(stderr, "To set A to be three rows high as measured in A's font,\n"
			"you would do:\n\n");
	glk_window_set_arrangement(o2, winmethod_Below | winmethod_Fixed, 3, win_a);
	center_text(win_a, "A");
	center_text(win_b, "B");
	center_text(win_d, "D");
	wait_for_key(win_a);
	
	fprintf(stderr, "Or you could change O2 to a proportional split:\n\n");
	glk_window_set_arrangement(o2, winmethod_Below | winmethod_Proportional, 30,
							   NULL);
	center_text(win_a, "A");
	center_text(win_b, "B");
	center_text(win_d, "D");
	wait_for_key(win_a);
	
	fprintf(stderr, "Or:\n\n");
	glk_window_set_arrangement(o2, winmethod_Above | winmethod_Proportional, 70,
							   NULL);
	center_text(win_a, "A");
	center_text(win_b, "B");
	center_text(win_d, "D");
	wait_for_key(win_a);
	
	glk_window_close(win_d, NULL);
	glk_window_close(win_b, NULL);
	glk_window_clear(win_a);
	glk_set_window(win_a);
	glk_put_string("That's all, folks...");
}
예제 #16
0
void glk_main(void)
{
	FILE *f;
	int vb,no;

	Bottom = glk_window_open(0, 0, 0, wintype_TextBuffer, 1);
	if(Bottom == NULL)
		glk_exit();
	glk_set_window(Bottom);

	if(game_file == NULL)
		Fatal("No game provided");

	f = fopen(game_file, "r");
	if(f==NULL)
		Fatal("Cannot open game");

	if (Options & TRS80_STYLE)
	{
		Width = 64;
		TopHeight = 11;
	}
	else
	{
		Width = 80;
		TopHeight = 10;
	}

	if(split_screen)
	{
		Top = glk_window_open(Bottom, winmethod_Above | winmethod_Fixed, TopHeight, wintype_TextGrid, 0);
		if(Top == NULL)
		{
			split_screen = 0;
			Top = Bottom;
		}
	}
	else
	{
		Top = Bottom;
	}

	Output("\
Scott Free, A Scott Adams game driver in C.\n\
Release 1.14, (c) 1993,1994,1995 Swansea University Computer Society.\n\
Distributed under the GNU software license\n\n");
	LoadDatabase(f,(Options&DEBUGGING)?1:0);
	fclose(f);
	srand(time(NULL));
	while(1)
	{
		glk_tick();

		PerformActions(0,0);

		Look();

		if(GetInput(&vb,&no) == -1)
			continue;
		switch(PerformActions(vb,no))
		{
			case -1:Output("I don't understand your command. ");
				break;
			case -2:Output("I can't do that yet. ");
				break;
		}
		/* Brian Howarth games seem to use -1 for forever */
		if(Items[LIGHT_SOURCE].Location/*==-1*/!=DESTROYED && GameHeader.LightTime!= -1)
		{
			GameHeader.LightTime--;
			if(GameHeader.LightTime<1)
			{
				BitFlags|=(1<<LIGHTOUTBIT);
				if(Items[LIGHT_SOURCE].Location==CARRIED ||
					Items[LIGHT_SOURCE].Location==MyLoc)
				{
					if(Options&SCOTTLIGHT)
						Output("Light has run out! ");
					else
						Output("Your light has run out. ");
				}
				if(Options&PREHISTORIC_LAMP)
					Items[LIGHT_SOURCE].Location=DESTROYED;
			}
			else if(GameHeader.LightTime<25)
			{
				if(Items[LIGHT_SOURCE].Location==CARRIED ||
					Items[LIGHT_SOURCE].Location==MyLoc)
				{

					if(Options&SCOTTLIGHT)
					{
						Output("Light runs out in ");
						OutputNumber(GameHeader.LightTime);
						Output(" turns. ");
					}
					else
					{
						if(GameHeader.LightTime%5==0)
							Output("Your light is growing dim. ");
					}
				}
			}
		}
	}
}
예제 #17
0
파일: model.c 프로젝트: imclab/Chimara
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();
}
예제 #18
0
파일: glkmisc.c 프로젝트: BPaden/garglk
void os_process_arguments(int argc, char *argv[]) 
{
	int c;

#ifdef GARGLK
	garglk_set_program_name("Frotz " VERSION);
	garglk_set_program_info(
			"Glk Frotz " VERSION "\n"
			"Original Frotz by Stefan Jokisch\n"
			"Unix port by Jim Dunleavy and David Griffith\n"
			"Glk port by Tor Andersson\n");
#endif

	/* Parse the options */
	do {
		c = zgetopt(argc, argv, "aAioOPQs:S:tu:xZ:");
		switch (c)
		{
			case 'a': option_attribute_assignment = 1; break;
			case 'A': option_attribute_testing = 1; break;
			case 'i': option_ignore_errors = 1; break;
			case 'o': option_object_movement = 1; break;
			case 'O': option_object_locating = 1; break;
			case 'P': option_piracy = 1; break;
			case 'Q': option_save_quetzal = 0; break;
			case 's': user_random_seed = atoi(zoptarg); break;
			case 'S': option_script_cols = atoi(zoptarg); break;
			case 't': user_tandy_bit = 1; break;
			case 'u': option_undo_slots = atoi(zoptarg); break;
			case 'x': option_expand_abbreviations = 1; break;
			case 'Z': option_err_report_mode = atoi(zoptarg);
					  if ((option_err_report_mode < ERR_REPORT_NEVER) ||
							  (option_err_report_mode > ERR_REPORT_FATAL))
						  option_err_report_mode = ERR_DEFAULT_REPORT_MODE;
					  break;
		}
	} while (c != EOF);

	if (((argc - zoptind) != 1) && ((argc - zoptind) != 2))
	{
		winid_t win;
		char buf[256];
		win = glk_window_open(0, 0, 0, wintype_TextBuffer, 0);
		glk_set_window(win);
		glk_put_string("FROTZ V" VERSION " -- Glk 0.7.0 interface.\n");
		glk_put_string(INFORMATION);
		sprintf(buf,
				"    -Z # error checking mode (default = %d)\n"
				"         %d = don't report errors.  "
				"%d = report first error.\n"
				"         %d = report all errors.  "
				"%d = exit after any error.\n",
				ERR_DEFAULT_REPORT_MODE, ERR_REPORT_NEVER,
				ERR_REPORT_ONCE, ERR_REPORT_ALWAYS, ERR_REPORT_FATAL);
		glk_put_string(buf);
		glk_exit();
	}
	else
	{
		char *s;

		story_name = argv[zoptind++];
		if (zoptind < argc)
			graphics_filename = argv[zoptind++];

		#ifdef GARGLK
		s = strrchr(story_name, '\\');
		if (!s) s = strrchr(story_name, '/');
		garglk_set_story_name(s ? s + 1 : story_name);
		#endif
	}
}