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); }
static void texcache_deletefiles(void) { Bstrcpy(ptempbuf, TEXCACHEFILE); unlink(ptempbuf); Bstrcat(ptempbuf, ".cache"); unlink(ptempbuf); }
int32_t texcache_loadoffsets(void) { int32_t foffset, fsize, i; char *fname; scriptfile *script; Bstrcpy(ptempbuf,TEXCACHEFILE); Bstrcat(ptempbuf,".cache"); script = scriptfile_fromfile(ptempbuf); if (!script) return -1; while (!scriptfile_eof(script)) { if (scriptfile_getstring(script, &fname)) break; // hashed filename if (scriptfile_getnumber(script, &foffset)) break; // offset in cache if (scriptfile_getnumber(script, &fsize)) break; // size i = hash_find(&texcache.hashes,fname); if (i > -1) { // update an existing entry texcacheindex *t = texcache.iptrs[i]; t->offset = foffset; t->len = fsize; /*initprintf("%s %d got a match for %s offset %d\n",__FILE__, __LINE__, fname,foffset);*/ } else { Bstrncpyz(texcache.currentindex->name, fname, BMAX_PATH); texcache.currentindex->offset = foffset; texcache.currentindex->len = fsize; texcache.currentindex->next = (texcacheindex *)Xcalloc(1, sizeof(texcacheindex)); hash_add(&texcache.hashes, fname, texcache.numentries, 1); if (++texcache.numentries > texcache.iptrcnt) { texcache.iptrcnt += 512; texcache.iptrs = (texcacheindex **) Xrealloc(texcache.iptrs, sizeof(intptr_t) * texcache.iptrcnt); } texcache.iptrs[texcache.numentries-1] = texcache.currentindex; texcache.currentindex = texcache.currentindex->next; } } scriptfile_close(script); return 0; }
// wrapper for CONTROL_MapKey(), generates key bindings to reflect changes to keyboard setup void CONFIG_MapKey(int32_t which, kb_scancode key1, kb_scancode oldkey1, kb_scancode key2, kb_scancode oldkey2) { int32_t i, j, k; int32_t ii[] = { key1, key2, oldkey1, oldkey2 }; char buf[2*MAXGAMEFUNCLEN]; UNREFERENCED_PARAMETER(which); // CONTROL_MapKey(which, key1, key2); if (which == gamefunc_Show_Console) OSD_CaptureKey(key1); for (k = 0; (unsigned)k < ARRAY_SIZE(ii); k++) { if (ii[k] == 0xff || !ii[k]) continue; for (j=0; ConsoleKeys[j].name; j++) if (ii[k] == ConsoleKeys[j].id) break; tempbuf[0] = 0; for (i=NUMGAMEFUNCTIONS-1; i>=0; i--) { if (ud.config.KeyboardKeys[i][0] == ii[k] || ud.config.KeyboardKeys[i][1] == ii[k]) { Bsprintf(buf,"gamefunc_%s; ",CONFIG_FunctionNumToName(i)); Bstrcat(tempbuf,buf); } } i = Bstrlen(tempbuf); if (i >= 2) { tempbuf[i-2] = 0; // cut off the trailing "; " CONTROL_BindKey(ii[k], tempbuf, 1, ConsoleKeys[j].name ? ConsoleKeys[j].name : "<?>"); } else { CONTROL_FreeKeyBind(ii[k]); } } }
static const char * texcache_calcid(char *cachefn, const char *fn, const int32_t len, const int32_t dameth, const char effect) { // Assert that BMAX_PATH is a multiple of 4 so that struct texcacheid_t // gets no padding inserted by the compiler. EDUKE32_STATIC_ASSERT((BMAX_PATH & 3) == 0); struct texcacheid_t { int32_t len, method; char effect, name[BMAX_PATH+3]; // +3: pad to a multiple of 4 } id = { len, dameth, effect, "" }; Bstrcpy(id.name, fn); while (Bstrlen(id.name) < BMAX_PATH - Bstrlen(fn)) Bstrcat(id.name, fn); Bsprintf(cachefn, "%08x%08x%08x", XXH32((uint8_t *)fn, Bstrlen(fn), TEXCACHEMAGIC[3]), XXH32((uint8_t *)id.name, Bstrlen(id.name), TEXCACHEMAGIC[3]), XXH32((uint8_t *)&id, sizeof(struct texcacheid_t), TEXCACHEMAGIC[3])); return cachefn; }
int32_t Bcanonicalisefilename(char *filename, int32_t removefn) { char cwd[BMAX_PATH]; char *fnp = filename; #ifdef _WIN32 int drv = 0; if (filename[0] && filename[1] == ':') { // filename is prefixed with a drive drv = toupper(filename[0]) - 'A' + 1; fnp += 2; } if (!_getdcwd(drv, cwd, sizeof(cwd))) return -1; for (char *p = cwd; *p; p++) if (*p == '\\') *p = '/'; #else if (!getcwd(cwd, sizeof(cwd))) return -1; #endif char *p = Bstrrchr(cwd, '/'); if (!p || p[1]) Bstrcat(cwd, "/"); char fn[BMAX_PATH]; Bstrcpy(fn, fnp); #ifdef _WIN32 for (p = fn; *p; p++) if (*p == '\\') *p = '/'; #endif if (fn[0] != '/') { // we are dealing with a path relative to the current directory Bstrcpy(filename, cwd); Bstrcat(filename, fn); } else { #ifdef _WIN32 filename[0] = cwd[0]; filename[1] = ':'; filename[2] = 0; Bstrcat(filename, fn); #else Bstrcpy(filename, fn); #endif } fnp = filename; #ifdef _WIN32 fnp += 2; // skip the drive #endif UNREFERENCED_PARAMETER(removefn); // change the call below to use removefn instead of 1? return Bcorrectfilename(fnp, 1); }
int Bcorrectfilename(char *filename, int removefn) { #ifdef _WIN32 int r, trailslash=0; #endif char path[256]="", fn[64]="", scratch[256], *ptr, *ptr2, ch; char cwd[256], *cwdp = cwd; char *tokarr[64]; int ntok=0, i, j; int grpmode = 0; if (!Bstrncasecmp(filename,"GRP:",4)) { grpmode = 1; for (ptr=filename; *ptr; ptr++) if (*ptr == '\\') *ptr = '/'; } #ifdef _WIN32 if (!grpmode) { // Windows uses backslashes so translate all unix-like forwardslashes for (ptr=filename; *ptr; ptr++) if (*ptr == '/') *ptr = '\\'; if (*(ptr-1) == '\\') trailslash = 1; r = GetFullPathName(filename, 256, path, &ptr); if (r > 256) return -1; if (r == 0) return -1; if (!trailslash && removefn && ptr) *ptr=0; if (trailslash) { if (path[ strlen(path) - 1 ] != '\\') strcat(path, "\\"); } for (ptr=path; *ptr; ptr++) if (*ptr == '\\') *ptr = '/'; strcpy(filename,path); } else { #endif #ifndef _WIN32 if (!grpmode) { Bgetcwd(cwd, 256); Bstrcat(cwd, "/"); } else { #endif cwd[0] = '/'; cwd[1] = 0; #ifndef _WIN32 } #endif ptr2 = filename; if (grpmode) { ptr2 += 3; if (ptr2[1] != '/') *ptr2 = '/'; else ptr2++; } if (removefn) { ptr = Bstrrchr(ptr2, '/'); if (ptr) ptr[1] = 0; else if (!grpmode) ptr2[0] = 0; } // now we have all the bits and pieces, clean it all up scratch[0] = 0; if (ptr2[0] != '/') { // relative path, which means prepend the current dir to the path Bstrcat(scratch, cwdp); } Bstrcat(scratch, ptr2); ptr2 = scratch; while ((ptr = Bstrtoken(ptr2==scratch?scratch:NULL,"/",&ptr2,1)) != NULL) { if (!Bstrcmp(ptr,".")) continue; else if (!Bstrcmp(ptr,"..")) { if (ntok>0) ntok--; } else { tokarr[ntok++] = ptr; } } ptr2 = filename; if (grpmode) { Bstrcpy(filename,"GRP:"); ptr2 += 4; } else filename[0] = 0; *(ptr2++) = '/'; for (i=0; i<ntok; i++) { ptr = tokarr[i]; if (i>0) *(ptr2++) = '/'; while (*ptr) *(ptr2++) = *(ptr++); } if (removefn) if (*(ptr2-1) != '/') *(ptr2++) = '/'; *(ptr2) = 0; #ifdef _WIN32 } #endif return 0; }