Example #1
0
int main(int argc, char **argv)
{
    struct icon icon;
    int32_t bpl = 0;
    int i;
    unsigned char *maskp, bm, *pp;

    if (argc<2) {
        Bfprintf(stderr, "generateicon <picture file>\n");
        return 1;
    }

    memset(&icon, 0, sizeof(icon));

    kpzload(argv[1], (intptr_t*)&icon.pixels, (int32_t*)&bpl, (int32_t*)&icon.width, (int32_t*)&icon.height);
    if (!icon.pixels) {
        Bfprintf(stderr, "Failure loading %s\n", argv[1]);
        return 1;
    }

    if (bpl != icon.width * 4) {
        Bfprintf(stderr, "bpl != icon.width * 4\n");
        Bfree(icon.pixels);
        return 1;
    }

    icon.mask = (unsigned char *)Bcalloc(icon.height, (icon.width+7)/8);
    if (!icon.mask) {
        Bfprintf(stderr, "Out of memory\n");
        Bfree(icon.pixels);
        return 1;
    }

    maskp = icon.mask;
    bm = 1;
    pp = (unsigned char *)icon.pixels;
    for (i=0; i<icon.height*icon.width; i++) {
        if (bm == 0) {
            bm = 1;
            maskp++;
        }

        {
            unsigned char c = pp[0];
            pp[0] = pp[2];
            pp[2] = c;
        }
        if (pp[3] > 0) *maskp |= bm;

        bm <<= 1;
        pp += 4;
    }

    writeicon(stdout, &icon);

    Bfree(icon.pixels);
    Bfree(icon.mask);

    return 0;
}
Example #2
0
void texcache_openfiles(void)
{
    Bstrcpy(ptempbuf,TEXCACHEFILE);
    Bstrcat(ptempbuf,".cache");
    texcache.index = Bfopen(ptempbuf, "at+");
    texcache.filehandle = Bopen(TEXCACHEFILE, BO_BINARY|BO_CREAT|BO_APPEND|BO_RDWR, BS_IREAD|BS_IWRITE);

    if (!texcache.index || texcache.filehandle < 0)
    {
        initprintf("Unable to open cache file \"%s\" or \"%s\": %s\n", TEXCACHEFILE, ptempbuf, strerror(errno));
        texcache_closefiles();
        glusetexcache = 0;
        return;
    }

    Bfseek(texcache.index, 0, BSEEK_END);
    if (!Bftell(texcache.index))
    {
        Brewind(texcache.index);
        Bfprintf(texcache.index,"// automatically generated by EDuke32, DO NOT MODIFY!\n");
    }
    else Brewind(texcache.index);

    initprintf("Opened \"%s\" as cache file\n", TEXCACHEFILE);
}
Example #3
0
void savenames(void)
{
    BFILE * fil3;
    int i;

    fil3 = Bfopen("names.h","w");

    if (fil3 != NULL)
    {
        Bfprintf(fil3,"//Be careful when changing this file - it is parsed by Editart and Build.\n");

        for(i=0; i<numwads; i++)
            if (wadata[i][0] != 0)
                Bfprintf(fil3,"#define %s %d\n", wadata[i], i);

        Bfclose(fil3);
    }
}
Example #4
0
void CONFIG_WriteSettings(void) // save binds and aliases to <cfgname>_settings.cfg
{
    int32_t i;
    BFILE *fp;
    char *ptr = Xstrdup(setupfilename);
    char tempbuf[128];

    if (!Bstrcmp(setupfilename, SETUPFILENAME))
        Bsprintf(tempbuf, "settings.cfg");
    else Bsprintf(tempbuf, "%s_settings.cfg", strtok(ptr, "."));

    fp = Bfopen(tempbuf, "wt");

    if (fp)
    {
        Bfprintf(fp,"// this file is automatically generated by EDuke32\n");
        Bfprintf(fp,"// these settings take precedence over your main cfg file\n");
        Bfprintf(fp,"// do not modify if you lack common sense\n");

        Bfprintf(fp,"unbindall\n");

        for (i=0; i<MAXBOUNDKEYS; i++)
            if (CONTROL_KeyIsBound(i))
                Bfprintf(fp,"bind \"%s\"%s \"%s\"\n",CONTROL_KeyBinds[i].key,
                CONTROL_KeyBinds[i].repeat?"":" norepeat",CONTROL_KeyBinds[i].cmdstr);

        for (i=0; i<MAXMOUSEBUTTONS; i++)
            if (CONTROL_MouseIsBound(i))
                Bfprintf(fp,"bind \"%s\"%s \"%s\"\n",CONTROL_MouseBinds[i].key,
                CONTROL_MouseBinds[i].repeat?"":" norepeat",CONTROL_MouseBinds[i].cmdstr);

        OSD_WriteAliases(fp);

        if (g_crosshairSum && g_crosshairSum != DefaultCrosshairColors.r+(DefaultCrosshairColors.g<<1)+(DefaultCrosshairColors.b<<2))
            Bfprintf(fp, "crosshaircolor %d %d %d\n", CrosshairColors.r, CrosshairColors.g, CrosshairColors.b);

        OSD_WriteCvars(fp);

        Bfclose(fp);

        if (!Bstrcmp(setupfilename, SETUPFILENAME))
            OSD_Printf("Wrote settings.cfg\n");
        else OSD_Printf("Wrote %s_settings.cfg\n",ptr);

        Bfree(ptr);
        return;
    }

    if (!Bstrcmp(setupfilename, SETUPFILENAME))
        OSD_Printf("Error writing settings.cfg: %s\n", strerror(errno));
    else OSD_Printf("Error writing %s_settings.cfg: %s\n",ptr,strerror(errno));

    Bfree(ptr);
}
Example #5
0
void texcache_writetex(const char *fn, int32_t len, int32_t dameth, char effect, texcacheheader *head)
{
    static GLint glGetTexLevelParameterivOK = GL_TRUE;
    char cachefn[BMAX_PATH];
    char *pic = NULL, *packbuf = NULL;
    void *midbuf = NULL;
    uint32_t alloclen=0, level;
    uint32_t padx=0, pady=0;
    GLint gi;
    int32_t offset = 0;

    if (!texcache_enabled()) return;

    gi = GL_FALSE;
    bglGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_ARB, &gi);
    if (gi != GL_TRUE)
    {
        if (glGetTexLevelParameterivOK == GL_TRUE)
        {
            OSD_Printf("Error: glGetTexLevelParameteriv returned GL_FALSE!\n");
            glGetTexLevelParameterivOK = GL_FALSE;
        }
        return;
    }

    Blseek(texcache.filehandle, 0, BSEEK_END);

    offset = Blseek(texcache.filehandle, 0, BSEEK_CUR);
    //    OSD_Printf("Caching %s, offset 0x%x\n", cachefn, offset);

    Bmemcpy(head->magic, TEXCACHEMAGIC, 4);   // sizes are set by caller

    if (glusetexcache == 2)
        head->flags |= CACHEAD_COMPRESSED;

    // native -> external (little-endian)
    head->xdim = B_LITTLE32(head->xdim);
    head->ydim = B_LITTLE32(head->ydim);
    head->flags = B_LITTLE32(head->flags);
    head->quality = B_LITTLE32(head->quality);

    if (Bwrite(texcache.filehandle, head, sizeof(texcacheheader)) != sizeof(texcacheheader)) goto failure;

    CLEAR_GL_ERRORS();

    for (level = 0; level==0 || (padx > 1 || pady > 1); level++)
    {
        uint32_t miplen;
        texcachepicture pict;

        bglGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_COMPRESSED_ARB, &gi); WRITEX_FAIL_ON_ERROR();
        if (gi != GL_TRUE) goto failure;   // an uncompressed mipmap
        bglGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_INTERNAL_FORMAT, &gi); WRITEX_FAIL_ON_ERROR();

#ifdef __APPLE__
        if (pr_ati_textureformat_one && gi == 1) gi = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
#endif
        // native -> external (little endian)
        pict.format = B_LITTLE32(gi);
        bglGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &gi); WRITEX_FAIL_ON_ERROR();
        padx = gi; pict.xdim = B_LITTLE32(gi);
        bglGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_HEIGHT, &gi); WRITEX_FAIL_ON_ERROR();
        pady = gi; pict.ydim = B_LITTLE32(gi);
        bglGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_BORDER, &gi); WRITEX_FAIL_ON_ERROR();
        pict.border = B_LITTLE32(gi);
        bglGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_DEPTH, &gi); WRITEX_FAIL_ON_ERROR();
        pict.depth = B_LITTLE32(gi);
        bglGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &gi); WRITEX_FAIL_ON_ERROR();
        miplen = gi; pict.size = B_LITTLE32(gi);

        if (alloclen < miplen)
        {
            pic = (char *)Xrealloc(pic, miplen);
            alloclen = miplen;
            packbuf = (char *)Xrealloc(packbuf, alloclen);
            midbuf = (void *)Xrealloc(midbuf, miplen);
        }

        bglGetCompressedTexImageARB(GL_TEXTURE_2D, level, pic); WRITEX_FAIL_ON_ERROR();

        if (Bwrite(texcache.filehandle, &pict, sizeof(texcachepicture)) != sizeof(texcachepicture)) goto failure;
        if (dxtfilter(texcache.filehandle, &pict, pic, midbuf, packbuf, miplen)) goto failure;
    }

    {
        texcacheindex *t;
        int32_t i = hash_find(&texcache.hashes, texcache_calcid(cachefn, fn, len, dameth, effect));
        if (i > -1)
        {
            // update an existing entry
            t = texcache.iptrs[i];
            t->offset = offset;
            t->len = Blseek(texcache.filehandle, 0, BSEEK_CUR) - t->offset;
            /*initprintf("%s %d got a match for %s offset %d\n",__FILE__, __LINE__, cachefn,offset);*/
        }
        else
        {
            t = texcache.currentindex;
            Bstrcpy(t->name, cachefn);
            t->offset = offset;
            t->len = Blseek(texcache.filehandle, 0, BSEEK_CUR) - t->offset;
            t->next = (texcacheindex *)Xcalloc(1, sizeof(texcacheindex));

            hash_add(&texcache.hashes, cachefn, texcache.numentries, 0);
            if (++texcache.numentries > texcache.iptrcnt)
            {
                texcache.iptrcnt += 512;
                texcache.iptrs = (texcacheindex **) Xrealloc(texcache.iptrs, sizeof(intptr_t) * texcache.iptrcnt);
            }
            texcache.iptrs[texcache.numentries-1] = t;
            texcache.currentindex = t->next;
        }

        if (texcache.index)
        {
            fseek(texcache.index, 0, BSEEK_END);
            Bfprintf(texcache.index, "%s %d %d\n", t->name, t->offset, t->len);
        }
        else OSD_Printf("wtf?\n");
    }

    goto success;

failure:
    initprintf("ERROR: cache failure!\n");
    texcache.currentindex->offset = 0;
    Bmemset(texcache.currentindex->name,0,sizeof(texcache.currentindex->name));

success:
    TEXCACHE_FREEBUFS();
}
Example #6
0
int writeicon(FILE *fp, struct icon *ico)
{
    int i;

    Bfprintf(fp,
        "#include \"sdlayer.h\"\n"
        "\n"
    );
    Bfprintf(fp,"static unsigned int sdlappicon_pixels[] = {\n");
    for (i=0;i<ico->width*ico->height;i++) {
        if ((i%6) == 0) Bfprintf(fp,"\t");
        else Bfprintf(fp," ");
        Bfprintf(fp, "0x%08lx,", (long)B_LITTLE32(ico->pixels[i]));
        if ((i%6) == 5) Bfprintf(fp,"\n");
    }
    if ((i%16) > 0) Bfprintf(fp, "\n");
    Bfprintf(fp, "};\n\n");

    Bfprintf(fp,"static unsigned char sdlappicon_mask[] = {\n");
    for (i=0;i<((ico->width+7)/8)*ico->height;i++) {
        if ((i%14) == 0) Bfprintf(fp,"\t");
        else Bfprintf(fp," ");
        Bfprintf(fp, "%3d,", ico->mask[i]);
        if ((i%14) == 13) Bfprintf(fp,"\n");
    }
    if ((i%16) > 0) Bfprintf(fp, "\n");
    Bfprintf(fp, "};\n\n");

    Bfprintf(fp,
        "struct sdlappicon sdlappicon = {\n"
        "    %d,%d,    // width,height\n"
        "    sdlappicon_pixels,\n"
        "    sdlappicon_mask\n"
        "};\n",
        ico->width, ico->height
    );

    return 0;
}
Example #7
0
int32_t writesetup(const char *fn)
{
    BFILE *fp;
    int32_t i,j,first=1;

    fp = Bfopen(fn,"wt");
    if (!fp) return -1;

    Bfprintf(fp,
             "; Always show configuration options on startup\n"
             ";   0 - No\n"
             ";   1 - Yes\n"
             "forcesetup = %d\n"
             "\n"
             "; Video mode selection\n"
             ";   0 - Windowed\n"
             ";   1 - Fullscreen\n"
             "fullscreen = %d\n"
             "\n"
             "; Video resolution\n"
             "xdim2d = %d\n"
             "ydim2d = %d\n"
             "xdim3d = %d\n"
             "ydim3d = %d\n"
             "\n"
             "; 3D-mode colour depth\n"
             "bpp = %d\n"
             "\n"
             "vsync = %d\n"
             "\n"
#ifdef POLYMER
             "; Rendering mode\n"
             "rendmode = %d\n"
             "\n"
#endif
             "; Grid limits\n"
             "editorgridextent = %d\n"
             "; Startup grid size (0-8, 9 is automatic)\n"
             "grid = %d\n"
             "\n"
#ifdef USE_OPENGL
             ";; OpenGL mode options\n"
             "usemodels = %d\n"
             "usehightile = %d\n"
             "; Enabling lazytileselector allows the tile display to interrupt\n"
             "; drawing hightiles so you can quickly browse without waiting\n"
             "; for all of them to load. Set to 0 if you experience flickering.\n"
             "lazytileselector = %d\n"
             "; glusetexcache: 0:no, 1:yes, 2:compressed\n"
             "; For best performance, keep this setting in sync with EDuke32\n"
             "glusetexcache = %d\n"
             "glusememcache = %d\n"
             "gltexfiltermode = %d\n"
             "glanisotropy = %d\n"
             "r_downsize = %d\n"
             "r_texcompr = %d\n"
             "r_shadescale = %g\n"
             "r_usenewshading = %d\n"
             "\n"
#endif
             "; Use new aspect determination code? (classic/Polymost)\n"
             "r_usenewaspect = %d\n"
#ifndef RENDERTYPEWIN
             "; Screen aspect for fullscreen, in the form WWHH (e.g. 1609 for 16:9).\n"
             "; A value of 0 means to assume that the pixel aspect is square."
             "r_screenxy = %d\n"
#endif
             "\n"

#ifdef RENDERTYPEWIN
             "; Maximum OpenGL mode refresh rate (Windows only, in Hertz)\n"
             "maxrefreshfreq = %d\n"
             "\n"
             "; Window positioning, 0 = center, 1 = memory\n"
             "windowpositioning = %d\n"
             "windowposx = %d\n"
             "windowposy = %d\n"
             "\n"
#endif
             "; 3D mode brightness setting\n"
             "vid_gamma = %g\n"
             "vid_brightness = %g\n"
             "vid_contrast = %g\n"
             "\n"
             "; Game executable used for map testing\n"
             "gameexecutable = %s\n"
             "\n"
#if 0
             "; Sound sample frequency\n"
             ";   0 - 6 KHz\n"
             ";   1 - 8 KHz\n"
             ";   2 - 11.025 KHz\n"
             ";   3 - 16 KHz\n"
             ";   4 - 22.05 KHz\n"
             ";   5 - 32 KHz\n"
             ";   6 - 44.1 KHz\n"
             "samplerate = %d\n"
             "\n"
             "; Music playback\n"
             ";   0 - Off\n"
             ";   1 - On\n"
             "music = %d\n"
             "\n"
#endif
             "; Mouse sensitivity\n"
             "mousesensitivity = %g\n"
             "\n"
             "; Mouse navigation\n"
             ";   0 - No\n"
             ";   1 - Yes\n"
             "mousenavigation = %d\n"
             "\n"
             "; Mouse navigation acceleration\n"
             "mousenavigationaccel = %d\n"
             "\n"
             "; Quick map cycling (SHIFT)+CTRL+X\n"
             ";   0 - No\n"
             ";   1 - Yes\n"
             "quickmapcycling = %d\n"
             "\n"
             "; Reverse meaning of Q and W keys in side view mode\n"
             "sideview_reversehorizrot = %d\n"
             "\n"
             "; Revert CTRL for tile selction\n"
             ";   0 - WHEEL:scrolling, CTRL+WHEEL:zooming\n"
             ";   1 - CTRL+WHEEL:scrolling, WHEEL:zooming\n"
             "revertCTRL = %d\n"
             "\n"
             "; Scroll amount for WHEEL in the tile selection\n"
             "scrollamount = %d\n"
             "\n"
             "; Turning acceleration+declaration\n"
             "turnaccel = %d\n"
             "\n"
             "; Turning deceleration\n"
             "turndecel = %d\n"
             "\n"
             "; Autosave map interval (seconds)\n"
             "autosavesec = %d\n"
             "\n"
             "; Auto corruption check interval (seconds)\n"
             "autocorruptchecksec = %d\n"
             "\n"
             "; Ignore 'already referenced wall' warnings\n"
             "corruptcheck_noalreadyrefd = %d\n"
             "\n"
             "; Fix sprite sectnums when saving a map or entering 3D mode\n"
             "fixmaponsave_sprites = %d\n"
             "\n"
             "; Keep texture stretching when dragging wall vertices\n"
             "keeptexturestretch = %d\n"
             "\n"
             "; Height indicators (0:none, 1:only 2-sided&different, 2:all)\n"
             "showheightindicators = %d\n"
             "\n"
             "; Ambience sound circles (0:none, 1:only in current sector, 2:all)\n"
             "showambiencesounds = %d\n"
             "\n"
             "; TROR: Automatic grayout of plain (non-extended) sectors,\n"
             ";       toggled with Ctrl-A:\n"
             "autogray = %d\n"
//             "; TROR: Show inner gray walls, toggled with Ctrl-Alt-A:\n"
//             "showinnergray = %d\n"
             "\n"
             "; 2D mode display type (0:classic, 1:textured, 2:textured/animated)\n"
             "graphicsmode = %d\n"
             "\n"
             "; Sample rate in Hz\n"
             "samplerate = %d\n"
             "; Ambient sounds in 3D mode (0:off, 1:on)\n"
             "ambiencetoggle = %d\n"
             "parlock = %d\n"
             "\n"
             "; Try executing m32script on invalid command in the OSD? This makes\n"
             "; typing m32script commands into the OSD directly possible.\n"
             "osdtryscript = %d\n"
             "\n"
#if 1
             "; Key Settings\n"
             ";  Here's a map of all the keyboard scan codes: NOTE: values are listed in hex!\n"
             "; +---------------------------------------------------------------------------------------------+\n"
             "; | 01   3B  3C  3D  3E   3F  40  41  42   43  44  57  58          46                           |\n"
             "; |ESC   F1  F2  F3  F4   F5  F6  F7  F8   F9 F10 F11 F12        SCROLL                         |\n"
             "; |                                                                                             |\n"
             "; |29  02  03  04  05  06  07  08  09  0A  0B  0C  0D   0E     D2  C7  C9      45  B5  37  4A   |\n"
             "; | ` '1' '2' '3' '4' '5' '6' '7' '8' '9' '0'  -   =  BACK    INS HOME PGUP  NUMLK KP/ KP* KP-  |\n"
             "; |                                                                                             |\n"
             "; | 0F  10  11  12  13  14  15  16  17  18  19  1A  1B  2B     D3  CF  D1      47  48  49  4E   |\n"
             "; |TAB  Q   W   E   R   T   Y   U   I   O   P   [   ]    \\    DEL END PGDN    KP7 KP8 KP9 KP+   |\n"
             "; |                                                                                             |\n"
             "; | 3A   1E  1F  20  21  22  23  24  25  26  27  28     1C                     4B  4C  4D       |\n"
             "; |CAPS  A   S   D   F   G   H   J   K   L   ;   '   ENTER                    KP4 KP5 KP6    9C |\n"
             "; |                                                                                      KPENTER|\n"
             "; |  2A    2C  2D  2E  2F  30  31  32  33  34  35    36            C8          4F  50  51       |\n"
             "; |LSHIFT  Z   X   C   V   B   N   M   ,   .   /   RSHIFT          UP         KP1 KP2 KP3       |\n"
             "; |                                                                                             |\n"
             "; | 1D     38              39                  B8     9D       CB  D0   CD      52    53        |\n"
             "; |LCTRL  LALT           SPACE                RALT   RCTRL   LEFT DOWN RIGHT    KP0    KP.      |\n"
             "; +---------------------------------------------------------------------------------------------+\n"
             "\n"
             "keyforward = %X\n"
             "keybackward = %X\n"
             "keyturnleft = %X\n"
             "keyturnright = %X\n"
             "keyrun = %X\n"
             "keystrafe = %X\n"
             "keyfire = %X\n"
             "keyuse = %X\n"
             "keystandhigh = %X\n"
             "keystandlow = %X\n"
             "keylookup = %X\n"
             "keylookdown = %X\n"
             "keystrafeleft = %X\n"
             "keystraferight = %X\n"
             "key2dmode = %X\n"
             "keyviewcycle = %X\n"
             "key2dzoomin = %X\n"
             "key2dzoomout = %X\n"
             "keychat = %X\n"
#endif
//             "; Console key scancode, in hex\n"
             "keyconsole = %X\n"
             "\n"
             "; This option allows you to remap keys in case some of them are not available\n"
             "; (like on a notebook). It has to be a comma-separated list of SOURCE-TARGET\n"
             "; scancode values, looked up in the keyboard map above. This also means that\n"
             "; the key positions count, not their labels for non-US keyboards.\n"
             ";\n"
             "; Example:\n"
             ";  1. Map the backslash key (0x2B) to KPENTER (9C), since portable devices\n"
             ";     often don't have the latter\n"
             ";  2. make KP0 (0x52) function as KP5 (0x4C), countering the inability to pan\n"
             ";     using Shift-KP5-KP8/2 in 3D mode\n"
             "; remap = 2B-9C,52-4C\n"
             "remap = ",

             forcesetup, fullscreen, xdim2d, ydim2d, xdimgame, ydimgame, bppgame, vsync,
#ifdef POLYMER
             glrendmode,
#endif
             editorgridextent, clamp(default_grid, 0, 9),
#ifdef USE_OPENGL
             usemodels, usehightile, g_lazy_tileselector,
             glusetexcache, glusememcache, gltexfiltermode, glanisotropy,r_downsize,glusetexcompr,
             shadescale, r_usenewshading,
#endif
             r_usenewaspect,
#ifndef RENDERTYPEWIN
             r_screenxy,
#else
             maxrefreshfreq, windowpos, windowx, windowy,
#endif
             vid_gamma_3d>=0?vid_gamma_3d:vid_gamma,
             vid_brightness_3d>=0?vid_brightness_3d:vid_brightness,
             vid_contrast_3d>=0?vid_contrast_3d:vid_contrast,
             game_executable,
#if 0
             option[7]>>4, option[2],
#endif
             msens, unrealedlook, pk_uedaccel, quickmapcycling,
             sideview_reversehrot,
             revertCTRL,scrollamount,pk_turnaccel,pk_turndecel,autosave,autocorruptcheck,
             corruptcheck_noalreadyrefd, fixmaponsave_sprites, keeptexturestretch,
             showheightindicators,showambiencesounds,
             autogray, //showinnergray,
             graphicsmode,
             MixRate,AmbienceToggle,ParentalLock, !!m32_osd_tryscript,
#if 1
             keys[0], keys[1], keys[2], keys[3], keys[4], keys[5],
             keys[6], keys[7], keys[8], keys[9], keys[10], keys[11],
             keys[12], keys[13], keys[14], keys[15], keys[16], keys[17],
             keys[18],
#endif
             keys[19]
            );

    for (i=0; i<256; i++)
        if (remap[i]!=i)
        {
            Bfprintf(fp,first?"%02X-%02X":",%02X-%02X",i,remap[i]);
            first=0;
        }
    Bfprintf(fp,"\n\n");

    // save m32script history
    Bfprintf(fp,"; Mapster32-script history\n");
    first = 1;
    for (i=scripthistend, j=0; first || i!=scripthistend; i=(i+1)%SCRIPTHISTSIZ, first=0)
    {
        if (scripthist[i])
            Bfprintf(fp, "hist%d = %s\n", j++, scripthist[i]);
    }

    Bfclose(fp);

    return 0;
}