int uio_unmountAllDirs(uio_Repository *repository) { int i; i = repository->numMounts; while (i--) uio_unmountDir(repository->mounts[i]->mountHandle); return 0; }
void * _GetFontData (uio_Stream *fp, DWORD length) { COUNT numDirEntries; DIRENTRY fontDir = NULL; BuildCharDesc *bcds = NULL; size_t numBCDs = 0; int dirEntryI; uio_DirHandle *fontDirHandle = NULL; uio_MountHandle *fontMount = NULL; FONT fontPtr = NULL; if (_cur_resfile_name == 0) goto err; if (fp != (uio_Stream*)~0) { // font is zipped instead of being in a directory char *s1, *s2; int n; const char *fontZipName; char fontDirName[PATH_MAX]; if ((((s2 = 0), (s1 = strrchr (_cur_resfile_name, '/')) == 0) && (s2 = strrchr (_cur_resfile_name, '\\')) == 0)) { strcpy(fontDirName, "."); fontZipName = _cur_resfile_name; } else { if (s2 > s1) s1 = s2; n = s1 - _cur_resfile_name + 1; strncpy (fontDirName, _cur_resfile_name, n - 1); fontDirName[n - 1] = 0; fontZipName = _cur_resfile_name + n; } fontDirHandle = uio_openDir (repository, fontDirName, 0); fontMount = uio_mountDir (repository, _cur_resfile_name, uio_FSTYPE_ZIP, fontDirHandle, fontZipName, "/", autoMount, uio_MOUNT_RDONLY | uio_MOUNT_TOP, NULL); uio_closeDir (fontDirHandle); } fontDir = CaptureDirEntryTable (LoadDirEntryTable (contentDir, _cur_resfile_name, ".", match_MATCH_SUBSTRING)); if (fontDir == 0) goto err; numDirEntries = GetDirEntryTableCount (fontDir); fontDirHandle = uio_openDirRelative (contentDir, _cur_resfile_name, 0); if (fontDirHandle == NULL) goto err; bcds = HMalloc (numDirEntries * sizeof (BuildCharDesc)); if (bcds == NULL) goto err; // Load the surfaces for all dir Entries for (dirEntryI = 0; dirEntryI < numDirEntries; dirEntryI++) { char *char_name; unsigned int charIndex; TFB_Canvas canvas; EXTENT size; char_name = GetDirEntryAddress (SetAbsDirEntryTableIndex ( fontDir, dirEntryI)); if (sscanf (char_name, "%x.", &charIndex) != 1) continue; if (charIndex > 0xffff) continue; canvas = TFB_DrawCanvas_LoadFromFile (fontDirHandle, char_name); if (canvas == NULL) continue; TFB_DrawCanvas_GetExtent (canvas, &size); if (size.width == 0 || size.height == 0) { TFB_DrawCanvas_Delete (canvas); continue; } bcds[numBCDs].canvas = canvas; bcds[numBCDs].index = charIndex; numBCDs++; } uio_closeDir (fontDirHandle); DestroyDirEntryTable (ReleaseDirEntryTable (fontDir)); if (fontMount != 0) uio_unmountDir(fontMount); #if 0 if (numBCDs == 0) goto err; #endif // sort on the character index qsort (bcds, numBCDs, sizeof (BuildCharDesc), compareBCDIndex); fontPtr = AllocFont (0); if (fontPtr == NULL) goto err; fontPtr->Leading = 0; fontPtr->LeadingWidth = 0; { size_t startBCD = 0; UniChar pageStart; FONT_PAGE **pageEndPtr = &fontPtr->fontPages; while (startBCD < numBCDs) { // Process one character page. size_t endBCD; pageStart = bcds[startBCD].index & CHARACTER_PAGE_MASK; endBCD = startBCD; while (endBCD < numBCDs && (bcds[endBCD].index & CHARACTER_PAGE_MASK) == pageStart) endBCD++; { size_t bcdI; int numChars = bcds[endBCD - 1].index + 1 - bcds[startBCD].index; FONT_PAGE *page = AllocFontPage (numChars); page->pageStart = pageStart; page->firstChar = bcds[startBCD].index; page->numChars = numChars; *pageEndPtr = page; pageEndPtr = &page->next; for (bcdI = startBCD; bcdI < endBCD; bcdI++) { // Process one character. BuildCharDesc *bcd = &bcds[bcdI]; TFB_Char *destChar = &page->charDesc[bcd->index - page->firstChar]; if (destChar->data != NULL) { // There's already an image for this character. log_add (log_Debug, "Duplicate image for character %d " "for font %s.", (int) bcd->index, _cur_resfile_name); TFB_DrawCanvas_Delete (bcd->canvas); continue; } processFontChar (destChar, bcd->canvas); TFB_DrawCanvas_Delete (bcd->canvas); if (destChar->disp.height > fontPtr->Leading) fontPtr->Leading = destChar->disp.height; if (destChar->disp.width > fontPtr->LeadingWidth) fontPtr->LeadingWidth = destChar->disp.width; } } startBCD = endBCD; } *pageEndPtr = NULL; } fontPtr->Leading++; HFree (bcds); (void) fp; /* Satisfying compiler (unused parameter) */ (void) length; /* Satisfying compiler (unused parameter) */ return fontPtr; err: if (fontPtr != 0) HFree (fontPtr); if (bcds != NULL) { size_t bcdI; for (bcdI = 0; bcdI < numBCDs; bcdI++) TFB_DrawCanvas_Delete (bcds[bcdI].canvas); HFree (bcds); } if (fontDirHandle != NULL) uio_closeDir (fontDirHandle); if (fontDir != 0) DestroyDirEntryTable (ReleaseDirEntryTable (fontDir)); if (fontMount != 0) uio_unmountDir(fontMount); return 0; }
void * _GetCelData (uio_Stream *fp, DWORD length) { int cel_total, cel_index, n; DWORD opos; char CurrentLine[1024], filename[PATH_MAX]; TFB_Canvas *img; AniData *ani; DRAWABLE Drawable; uio_MountHandle *aniMount = 0; uio_DirHandle *aniDir = 0; uio_Stream *aniFile = 0; opos = uio_ftell (fp); { char *s1, *s2; char aniDirName[PATH_MAX]; const char *aniFileName; uint8 buf[4] = { 0, 0, 0, 0 }; uint32 header; if (_cur_resfile_name == 0 || (((s2 = 0), (s1 = strrchr (_cur_resfile_name, '/')) == 0) && (s2 = strrchr (_cur_resfile_name, '\\')) == 0)) { n = 0; } else { if (s2 > s1) s1 = s2; n = s1 - _cur_resfile_name + 1; } uio_fread(buf, 4, 1, fp); header = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); if (_cur_resfile_name && header == 0x04034b50) { // zipped ani file if (n) { strncpy (aniDirName, _cur_resfile_name, n - 1); aniDirName[n - 1] = 0; aniFileName = _cur_resfile_name + n; } else { strcpy(aniDirName, "."); aniFileName = _cur_resfile_name; } aniDir = uio_openDir (repository, aniDirName, 0); aniMount = uio_mountDir (repository, aniDirName, uio_FSTYPE_ZIP, aniDir, aniFileName, "/", autoMount, uio_MOUNT_RDONLY | uio_MOUNT_TOP, NULL); aniFile = uio_fopen (aniDir, aniFileName, "r"); opos = 0; n = 0; } else { // unpacked ani file strncpy (filename, _cur_resfile_name, n); aniFile = fp; aniDir = contentDir; } } cel_total = 0; uio_fseek (aniFile, opos, SEEK_SET); while (uio_fgets (CurrentLine, sizeof (CurrentLine), aniFile)) { ++cel_total; } img = HMalloc (sizeof (TFB_Canvas) * cel_total); ani = HMalloc (sizeof (AniData) * cel_total); if (!img || !ani) { log_add (log_Warning, "Couldn't allocate space for '%s'", _cur_resfile_name); if (aniMount) { uio_fclose(aniFile); uio_closeDir(aniDir); uio_unmountDir(aniMount); } HFree (img); HFree (ani); return NULL; } cel_index = 0; uio_fseek (aniFile, opos, SEEK_SET); while (uio_fgets (CurrentLine, sizeof (CurrentLine), aniFile) && cel_index < cel_total) { sscanf (CurrentLine, "%s %d %d %d %d", &filename[n], &ani[cel_index].transparent_color, &ani[cel_index].colormap_index, &ani[cel_index].hotspot_x, &ani[cel_index].hotspot_y); img[cel_index] = TFB_DrawCanvas_LoadFromFile (aniDir, filename); if (img[cel_index] == NULL) { const char *err; err = TFB_DrawCanvas_GetError (); log_add (log_Warning, "_GetCelData: Unable to load image!"); if (err != NULL) log_add (log_Warning, "Gfx Driver reports: %s", err); } else { ++cel_index; } if ((int)uio_ftell (aniFile) - (int)opos >= (int)length) break; } Drawable = NULL; if (cel_index && (Drawable = AllocDrawable (cel_index))) { if (!Drawable) { while (cel_index--) TFB_DrawCanvas_Delete (img[cel_index]); HFree (Drawable); Drawable = NULL; } else { FRAME FramePtr; Drawable->Flags = WANT_PIXMAP; Drawable->MaxIndex = cel_index - 1; FramePtr = &Drawable->Frame[cel_index]; while (--FramePtr, cel_index--) process_image (FramePtr, img, ani, cel_index); } } if (Drawable == NULL) log_add (log_Warning, "Couldn't get cel data for '%s'", _cur_resfile_name); if (aniMount) { uio_fclose(aniFile); uio_closeDir(aniDir); uio_unmountDir(aniMount); } HFree (img); HFree (ani); return Drawable; }
void initRepository(void) { static uio_AutoMount autoMountZip = { .pattern = "*.zip", .matchType = match_MATCH_SUFFIX, .fileSystemID = uio_FSTYPE_ZIP, .mountFlags = uio_MOUNT_BELOW | uio_MOUNT_RDONLY }; static uio_AutoMount *autoMount[] = { &autoMountZip, NULL }; uio_init(); repository = uio_openRepository(0); memset(&mountHandles, '\0', sizeof mountHandles); #if 1 mountHandles[0] = debugMountOne(repository, "/", uio_FSTYPE_STDIO, NULL, NULL, "/home/svdb/cvs/sc2/content", autoMount, uio_MOUNT_TOP | uio_MOUNT_RDONLY, NULL); #endif #if 1 mountHandles[1] = debugMountOne(repository, "/", uio_FSTYPE_STDIO, NULL, NULL, "/home/svdb/cvs/sc2/src/sc2code/ships", autoMount, uio_MOUNT_TOP | uio_MOUNT_RDONLY, NULL); #endif #if 1 mountHandles[2] = debugMountOne(repository, "/", uio_FSTYPE_STDIO, NULL, NULL, "/tmp/vfstest", autoMount, uio_MOUNT_TOP, NULL); #endif #if 1 mountHandles[3] = debugMountOne(repository, "/", uio_FSTYPE_STDIO, NULL, NULL, "/tmp/vfstest2", autoMount, uio_MOUNT_TOP, NULL); #endif // TODO: should work too: #if 0 mountHandle[4] = debugMountOne(repository, "/zip/", uio_FSTYPE_ZIP, NULL, NULL, "/ziptest/foo.zip", autoMount, uio_MOUNT_TOP, NULL); #endif { uio_DirHandle *rootDir; rootDir = uio_openDir(repository, "/", 0); if (rootDir == NULL) { fprintf(stderr, "Could not open '/' dir.\n"); } else { #if 1 mountHandles[4] = debugMountOne(repository, "/example/", uio_FSTYPE_ZIP, rootDir, "/example2.zip", "/", autoMount, uio_MOUNT_TOP | uio_MOUNT_RDONLY, NULL); #endif #if 1 mountHandles[5] = debugMountOne(repository, "/example/", uio_FSTYPE_ZIP, rootDir, "/example/example.zip", "/", autoMount, uio_MOUNT_TOP | uio_MOUNT_RDONLY, NULL); #endif #if 1 mountHandles[6] = debugMountOne(repository, "/zip/", uio_FSTYPE_ZIP, rootDir, "/voice.zip", "/", autoMount, uio_MOUNT_TOP | uio_MOUNT_RDONLY, NULL); #endif #if 1 mountHandles[7] = debugMountOne(repository, "/foo/", uio_FSTYPE_ZIP, rootDir, "/foo2.zip", "/", autoMount, uio_MOUNT_TOP | uio_MOUNT_RDONLY, NULL); #endif uio_closeDir(rootDir); } } mountHandles[8] = debugMountOne(repository, "/tmp/", uio_FSTYPE_STDIO, NULL, NULL, "/tmp/", autoMount, uio_MOUNT_TOP, NULL); #if 1 mountHandles[8] = debugMountOne(repository, "/root/root/", uio_FSTYPE_STDIO, NULL, NULL, "/", autoMount, uio_MOUNT_TOP | uio_MOUNT_RDONLY, NULL); #endif } void unInitRepository(void) { #if 1 int i; // uio_printMountTree(stderr, repository->mountTree, 0); // fprintf(stderr, "\n"); for (i = 7; i >= 0; i--) { if (mountHandles[i] != NULL) uio_unmountDir(mountHandles[i]); // uio_printMountTree(stderr, repository->mountTree, 0); // uio_printMounts(stderr, repository); // fprintf(stderr, "\n"); } #endif uio_closeRepository(repository); uio_unInit(); }