예제 #1
0
frefid_t glk_fileref_create_by_path(glui32 usage, const char *path,
                                    glui32 rock)
{
    fileref_t *fref  = gli_new_fileref(path, usage, rock);
    if (!fref) gli_strict_warning("fileref_create_by_name: unable to create fileref.");
    return fref;
}
예제 #2
0
frefid_t glk_fileref_create_by_prompt(glui32 usage, glui32 fmode, glui32 rock)
{
    fileref_t *fref;
    char buf[256];
    int val, filter;
    char *prompt;

    strcpy(buf, "");

    switch (usage & fileusage_TypeMask)
    {
    case fileusage_SavedGame:
        prompt = "Saved game";
        filter = FILTER_SAVE;
        break;
    case fileusage_Transcript:
        prompt = "Transcript file";
        filter = FILTER_TEXT;
        break;
    case fileusage_InputRecord:
        prompt = "Command record file";
        filter = FILTER_TEXT;
        break;
    case fileusage_Data:
    default:
        prompt = "Data file";
        filter = FILTER_ALL;
        break;
    }

    if (fmode == filemode_Read)
        winopenfile(prompt, buf, sizeof buf, filter);
    else
        winsavefile(prompt, buf, sizeof buf, filter);

    val = strlen(buf);
    if (!val)
    {
        /* The player just hit return. It would be nice to provide a
            default value, but this implementation is too cheap. */
        return NULL;
    }

    fref = gli_new_fileref(buf, usage, rock);
    if (!fref)
    {
        gli_strict_warning("fileref_create_by_prompt: unable to create fileref.");
        return NULL;
    }

    return fref;
}
예제 #3
0
frefid_t glk_fileref_create_by_name(glui32 usage, char *name,
    glui32 rock)
{
    fileref_t *fref;
    char buf[BUFLEN];
    char buf2[2*BUFLEN+10];
    int len;
    char *cx;
    char *suffix;
    
    /* The new spec recommendations: delete all characters in the
       string "/\<>:|?*" (including quotes). Truncate at the first
       period. Change to "null" if there's nothing left. Then append
       an appropriate suffix: ".glkdata", ".glksave", ".txt".
    */

    for (cx=name, len=0; (*cx && *cx!='.' && len<BUFLEN-1); cx++) {
        switch (*cx) {
            case '"':
            case '\\':
            case '/':
            case '>':
            case '<':
            case ':':
            case '|':
            case '?':
            case '*':
                break;
            default:
                buf[len++] = *cx;
        }
      }
      buf[len] = '\0';

    if (len == 0) {
        strcpy(buf, "null");
        len = strlen(buf);
    }
    
    suffix = gli_suffix_for_usage(usage);
    sprintf(buf2, "%s/%s%s", workingdir, buf, suffix);

    fref = gli_new_fileref(buf2, usage, rock);
    if (!fref) {
        gli_strict_warning(L"fileref_create_by_name: unable to create fileref.");
        return NULL;
    }
    
    return fref;
}
예제 #4
0
frefid_t glk_fileref_create_by_name(glui32 usage, const char *name,
                                    glui32 rock)
{
    fileref_t *fref;
    char buf[256];
    char buf2[256];
    int len;
    char *cx;

    len = strlen(name);
    if (len > 255)
        len = 255;

    /* Take out all dangerous characters, and make sure the length is greater
        than zero.  The overall goal is to make a legal
        platform-native filename, without any extra directory
        components.
       Suffixes are another sore point. Really, the game program
        shouldn't have a suffix on the name passed to this function. So
        in DOS/Windows, this function should chop off dot-and-suffix,
        if there is one, and then add a dot and a three-letter suffix
        appropriate to the file type (as gleaned from the usage
        argument.)
    */

    memcpy(buf, name, len);
    if (len == 0)
    {
        buf[0] = 'X';
        len++;
    }
    buf[len] = '\0';

    for (cx=buf; *cx; cx++)
    {
        if (*cx == '/' || *cx == '\\' || *cx == ':')
            *cx = '-';
    }

    sprintf(buf2, "%s/%s", gli_workdir, buf);

    fref = gli_new_fileref(buf2, usage, rock);
    if (!fref)
    {
        gli_strict_warning("fileref_create_by_name: unable to create fileref.");
        return NULL;
    }

    return fref;
}
예제 #5
0
frefid_t glk_fileref_create_by_name(glui32 usage, char *name,
  glui32 rock)
{
  fileref_t *fref;
  char buf[256];
  char buf2[256];
  int len;
  char *cx;
    
  len = strlen(name);
  if (len > 255)
    len = 255;
    
  /* Take out all '/' characters, and make sure the length is greater 
     than zero. Again, this is the right behavior in Unix. 
     DOS/Windows might want to take out '\' instead, unless the
     stdio library converts slashes for you. They'd also want to trim 
     to 8 characters. Remember, the overall goal is to make a legal 
     platform-native filename, without any extra directory 
     components.
     Suffixes are another sore point. Really, the game program 
     shouldn't have a suffix on the name passed to this function. So
     in DOS/Windows, this function should chop off dot-and-suffix,
     if there is one, and then add a dot and a three-letter suffix
     appropriate to the file type (as gleaned from the usage 
     argument.)
  */
    
  memcpy(buf, name, len);
  if (len == 0) {
    buf[0] = 'X';
    len++;
  }
  buf[len] = '\0';
    
  for (cx=buf; *cx; cx++) {
    if (*cx == '/')
      *cx = '-';
  }
    
  sprintf(buf2, "%s/%s", workingdir, buf);

  fref = gli_new_fileref(buf2, usage, rock);
  if (!fref) {
    gli_strict_warning("fileref_create_by_name: unable to create fileref.");
    return 0;
  }
    
  return fref;
}
예제 #6
0
frefid_t glk_fileref_create_temp(glui32 usage, glui32 rock)
{
    char *filename;
    fileref_t *fref;
    char *tempdir = getenv("TEMP");
    if (tempdir == NULL) tempdir = ".";
    filename = tempnam(tempdir, "gargtmp");

    fref = gli_new_fileref(filename, usage, rock);
    if (!fref)
    {
        gli_strict_warning("fileref_create_temp: unable to create fileref.");
        return NULL;
    }

    return fref;
}
예제 #7
0
frefid_t glk_fileref_create_from_fileref(glui32 usage, frefid_t oldfref,
    glui32 rock)
{
    fileref_t *fref; 

    if (!oldfref) {
        gli_strict_warning(L"fileref_create_from_fileref: invalid ref");
        return NULL;
    }

    fref = gli_new_fileref(oldfref->filename, usage, rock);
    if (!fref) {
        gli_strict_warning(L"fileref_create_from_fileref: unable to create fileref.");
        return NULL;
    }
    
    return fref;
}
예제 #8
0
frefid_t glk_fileref_create_temp(glui32 usage, glui32 rock)
{
  char *filename;
  fileref_t *fref;
    
  /* This is a pretty good way to do this on Unix systems. 
     I have no idea about the DOS/Windows world. */
        
  filename = tmpnam(NULL);
    
  fref = gli_new_fileref(filename, usage, rock);
  if (!fref) {
    gli_strict_warning("fileref_create_temp: unable to create fileref.");
    return 0;
  }
    
  return fref;
}
예제 #9
0
frefid_t glk_fileref_create_temp(glui32 usage, glui32 rock)
{
    char *filename;
    fileref_t *fref;
    
    /* This is a pretty good way to do this on Unix systems. On Macs,
        it's pretty bad, but this library won't be used much on the Mac 
        -- I hope. I have no idea about the DOS/Windows world. */
        
    filename = tmpnam(NULL);
    
    fref = gli_new_fileref(filename, usage, rock);
    if (!fref) {
        gli_strict_warning("fileref_create_temp: unable to create fileref.");
        return NULL;
    }
    
    return fref;
}
예제 #10
0
frefid_t glk_fileref_create_by_prompt(glui32 usage, glui32 fmode,
    glui32 rock)
{
    fileref_t *fref;
//    struct stat sbuf;
    char buf[BUFLEN], newbuf[BUFLEN];
    char *cx;
    int ix, val;
    char *prompt, *prompt2, *lastbuf;
    int ipflag = FILE_RESTORE;
    
    switch (usage & fileusage_TypeMask) {
        case fileusage_SavedGame:
            prompt = "Enter saved game";
            ipflag = fmode == filemode_Read ? FILE_RESTORE : FILE_SAVE;
            lastbuf = lastsavename;
            break;
        case fileusage_Transcript:
            prompt = "Enter transcript file";
            ipflag = FILE_SCRIPT;
            lastbuf = lastscriptname;
            break;
        case fileusage_InputRecord:
            prompt = "Enter command record file";
            ipflag = fmode == filemode_Read ? FILE_PLAYBACK : FILE_RECORD;
            lastbuf = lastcmdname;
            break;
        case fileusage_Data:
        default:
            prompt = "Enter data file";
            ipflag = fmode == filemode_Read ? FILE_LOAD_AUX : FILE_SAVE_AUX;
            lastbuf = lastdataname;
            break;
    }
    
    if (fmode == filemode_Read)
        prompt2 = "to load";
    else
        prompt2 = "to store";
    
    sprintf(newbuf, "%s %s: ", prompt, prompt2);

    ix =  iosif_prompt_file_name(buf, "", ipflag);

    if (!ix) {
        /* The player cancelled input. */
        return NULL;
    }
    val = strlen(buf);
    
    while (val 
        && (buf[val-1] == '\n' 
            || buf[val-1] == '\r' 
            || buf[val-1] == ' '))
        val--;
    buf[val] = '\0';
   
    for (cx = buf; *cx == ' '; cx++) { }
    
    val = strlen(cx);
    if (!val) {
        /* The player just hit return. */
        return NULL;
    }

    if (cx[0] == '/') {
        strcpy(newbuf, cx);
        cx = newbuf;
    }
    else {
        if (strlen(workingdir) + 1 + strlen(cx) >= BUFLEN) {
            gli_strict_warning(L"fileref_create_by_name: filename too long.");
            return NULL;
        }
        sprintf(newbuf, "%s/%s", workingdir, cx);
        cx = newbuf + strlen(workingdir) + 1;
    }

    strcpy(lastbuf, cx);

    fref = gli_new_fileref(newbuf, usage, rock);
    if (!fref) {
        gli_strict_warning(L"fileref_create_by_prompt: unable to create fileref.");
        return NULL;
    }
    
    return fref;
}
예제 #11
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;
}
예제 #12
0
frefid_t glk_fileref_create_by_prompt(glui32 usage, glui32 fmode,
    glui32 rock)
{
    fileref_t *fref;
    char buf[256], newbuf[256];
    char *cx;
    int val;
    char *prompt, *prompt2;
    
    switch (usage & fileusage_TypeMask) {
        case fileusage_SavedGame:
            prompt = "Enter saved game";
            break;
        case fileusage_Transcript:
            prompt = "Enter transcript file";
            break;
        case fileusage_InputRecord:
            prompt = "Enter command record file";
            break;
        case fileusage_Data:
        default:
            prompt = "Enter data file";
            break;
    }
    
    if (fmode == filemode_Read)
        prompt2 = "to load";
    else
        prompt2 = "to store";
    
    printf("%s %s: ", prompt, prompt2);
    
    fgets(buf, 255, stdin);
    val = strlen(buf);
    
    while (val 
        && (buf[val-1] == '\n' 
            || buf[val-1] == '\r' 
            || buf[val-1] == ' '))
        val--;
    buf[val] = '\0';
    
    for (cx = buf; *cx == ' '; cx++) { }
    
    val = strlen(cx);
    if (!val) {
        /* The player just hit return. It would be nice to provide a
            default value, but this implementation is too cheap. */
        return NULL;
    }
    
    if (cx[0] == '/')
        strcpy(newbuf, cx);
    else
        sprintf(newbuf, "%s/%s", workingdir, cx);

    fref = gli_new_fileref(newbuf, usage, rock);
    if (!fref) {
        gli_strict_warning("fileref_create_by_prompt: unable to create fileref.");
        return NULL;
    }
    
    return fref;
}
예제 #13
0
frefid_t glk_fileref_create_by_prompt(glui32 usage, glui32 fmode,
  glui32 rock)
{
  fileref_t *fref;
  struct stat sbuf;
  char buf[256], prbuf[256], newbuf[256];
  char *cx;
  int ix, val;
  char *prompt, *prompt2, *lastbuf;
    
  switch (usage & fileusage_TypeMask) {
  case fileusage_SavedGame:
    prompt = "Enter saved game";
    lastbuf = lastsavename;
    break;
  case fileusage_Transcript:
    prompt = "Enter transcript file";
    lastbuf = lastscriptname;
    break;
  case fileusage_InputRecord:
    prompt = "Enter command record file";
    lastbuf = lastcmdname;
    break;
  case fileusage_Data:
  default:
    prompt = "Enter data file";
    lastbuf = lastdataname;
    break;
  }
    
  if (fmode == filemode_Read)
    prompt2 = "to load";
  else
    prompt2 = "to store";
    
  sprintf(prbuf, "%s %s: ", prompt, prompt2);
    
  if (prefs.prompt_defaults) {
    strcpy(buf, lastbuf);
    val = strlen(buf);
  }
  else {
    buf[0] = 0;
    val = 0;
  }
    
  ix = xmsg_getline(prbuf, buf, 255, &val);
  if (!ix) {
    /* The player cancelled input. */
    return 0;
  }
    
  buf[val] = '\0';
    
  while (val 
    && (buf[val-1] == '\n' 
      || buf[val-1] == '\r' 
      || buf[val-1] == ' '))
    val--;
  buf[val] = '\0';
    
  for (cx = buf; *cx == ' '; cx++) { }
    
  val = strlen(cx);
  if (!val) {
    /* The player just hit return. */
    return 0;
  }
    
  if (cx[0] == '/')
    strcpy(newbuf, cx);
  else
    sprintf(newbuf, "%s/%s", workingdir, cx);
    
  if (fmode != filemode_Read) {
    if (!stat(newbuf, &sbuf) && S_ISREG(sbuf.st_mode)) {
      sprintf(prbuf, "Overwrite \"%s\"? [y/n] ", cx);
      while (1) {
	ix = xmsg_getchar(prbuf);
	if (ix == 'n' || ix == 'N' || ix == '\033' || ix == '\007') {
	  return 0;
	}
	if (ix == 'y' || ix == 'Y') {
	  break;
	}
      }
    }
  }

  strcpy(lastbuf, cx);

  fref = gli_new_fileref(newbuf, usage, rock);
  if (!fref) {
    gli_strict_warning("fileref_create_by_prompt: unable to create fileref.");
    return 0;
  }
    
  return fref;
}