Sfoglia il codice sorgente

Support CSM.BIN in Chasm: The Rift and add ignores

Jon Daniel 2 anni fa
parent
commit
713d09f916
6 ha cambiato i file con 148 aggiunte e 1 eliminazioni
  1. 10 1
      .gitignore
  2. 7 0
      CMakeLists.txt
  3. 3 0
      src/physfs.c
  4. 1 0
      src/physfs.h
  5. 123 0
      src/physfs_archiver_csm.c
  6. 4 0
      src/physfs_internal.h

+ 10 - 1
.gitignore

@@ -1,2 +1,11 @@
 cmake-build
-
+CMakeFiles/
+CMakeCache.txt
+Makefile
+test_physfs*
+libphysfs.*
+install_manifest.txt
+cmake_install.cmake
+CMakeDoxy*
+extras/physfs.pc
+Doxyfile

+ 7 - 0
CMakeLists.txt

@@ -91,6 +91,7 @@ set(PHYSFS_SRCS
     src/physfs_archiver_mvl.c
     src/physfs_archiver_qpak.c
     src/physfs_archiver_wad.c
+    src/physfs_archiver_csm.c
     src/physfs_archiver_zip.c
     src/physfs_archiver_slb.c
     src/physfs_archiver_iso9660.c
@@ -124,6 +125,11 @@ if(NOT PHYSFS_ARCHIVE_WAD)
     add_definitions(-DPHYSFS_SUPPORTS_WAD=0)
 endif()
 
+option(PHYSFS_ARCHIVE_CSM "Enable Chasm: The Rift CSM.BIN support" TRUE)
+if(NOT PHYSFS_ARCHIVE_CSM)
+    add_definitions(-DPHYSFS_SUPPORTS_CSM=0)
+endif()
+
 option(PHYSFS_ARCHIVE_HOG "Enable Descent I/II HOG support" TRUE)
 if(NOT PHYSFS_ARCHIVE_HOG)
     add_definitions(-DPHYSFS_SUPPORTS_HOG=0)
@@ -318,6 +324,7 @@ message_bool_option("ZIP support" PHYSFS_ARCHIVE_ZIP)
 message_bool_option("7zip support" PHYSFS_ARCHIVE_7Z)
 message_bool_option("GRP support" PHYSFS_ARCHIVE_GRP)
 message_bool_option("WAD support" PHYSFS_ARCHIVE_WAD)
+message_bool_option("CSM support" PHYSFS_ARCHIVE_CSM)
 message_bool_option("HOG support" PHYSFS_ARCHIVE_HOG)
 message_bool_option("MVL support" PHYSFS_ARCHIVE_MVL)
 message_bool_option("QPAK support" PHYSFS_ARCHIVE_QPAK)

+ 3 - 0
src/physfs.c

@@ -1188,6 +1188,9 @@ static int initStaticArchivers(void)
     #if PHYSFS_SUPPORTS_WAD
         REGISTER_STATIC_ARCHIVER(WAD);
     #endif
+    #if PHYSFS_SUPPORTS_CSM
+        REGISTER_STATIC_ARCHIVER(CSM);
+    #endif
     #if PHYSFS_SUPPORTS_SLB
         REGISTER_STATIC_ARCHIVER(SLB);
     #endif

+ 1 - 0
src/physfs.h

@@ -148,6 +148,7 @@
  *   - .HOG (Descent I/II/III HOG file archives)
  *   - .MVL (Descent II movielib archives)
  *   - .WAD (DOOM engine archives)
+ *   - .BIN (Chasm: The Rift engine archives)
  *   - .VDF (Gothic I/II engine archives)
  *   - .SLB (Independence War archives)
  *

+ 123 - 0
src/physfs_archiver_csm.c

@@ -0,0 +1,123 @@
+/*
+ * CSM support routines for PhysicsFS.
+ *
+ * This driver handles Chasm: The Rift engine archives ("CSM.BINs"). 
+ * This format (but not this driver) was developed by Action Forms Ltd.
+ * and published by Megamedia for use with the Chasm: The Rift engine.
+ * The specs of the format are from http://github.com/Panzerschrek/Chasm-Reverse
+ * The format of the archive: (from the specs)
+ *
+ *  A CSM file has three parts:
+ *  (1) a 6 byte header
+ *  (2) a TOC that contains the names, offsets, and
+ *      sizes of all the entries in the CSM.BIN
+ *
+ *  The header consists of three four-byte parts:
+ *    (a) an ASCII string which must be "CSid"
+ *    (b) a uint16 which is the number of TOC entries in the CSM.BIN
+ *
+ *  The TOC has one -byte entry for every lump. Each entry consists
+ *  of three parts:
+ *
+ *    (a) a uint8, the length of the filename
+ *    (b) an 12-byte ASCII string, the name of the entry, padded with zeros.
+ *    (c) a uint32, the size of the entry in bytes
+ *    (d) a uint32, the file offset to the start of the entry
+ * 
+ *
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ *
+ * This file written by Jon Daniel, based on the WAD archiver by
+ *  Travis Wells.
+ */
+
+#define __PHYSICSFS_INTERNAL__
+#include "physfs_internal.h"
+
+#if PHYSFS_SUPPORTS_CSM
+
+static int csmLoadEntries(PHYSFS_Io *io, const PHYSFS_uint16 count, void *arc)
+{
+    PHYSFS_uint16 i;
+    for (i = 0; i < count; i++)
+    {
+    	PHYSFS_uint8 fn_len;
+	char name[12];
+        PHYSFS_uint32 size;
+        PHYSFS_uint32 pos;
+
+        BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &fn_len, 1), 0);
+        BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, name, 12), 0);
+        BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &size, 4), 0);
+        BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &pos, 4), 0);
+
+	if(fn_len > 12) fn_len = 12;
+        name[fn_len] = '\0'; /* name might not be null-terminated in file. */
+        size = PHYSFS_swapULE32(size);
+        pos = PHYSFS_swapULE32(pos);
+        BAIL_IF_ERRPASS(!UNPK_addEntry(arc, name, 0, -1, -1, pos, size), 0);
+    } /* for */
+
+    return 1;
+} /* csmLoadEntries */
+
+
+static void *CSM_openArchive(PHYSFS_Io *io, const char *name,
+                             int forWriting, int *claimed)
+{
+    PHYSFS_uint8 buf[4];
+    PHYSFS_uint16 count;
+    void *unpkarc;
+
+    assert(io != NULL);  /* shouldn't ever happen. */
+
+    BAIL_IF(forWriting, PHYSFS_ERR_READ_ONLY, NULL);
+    BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, buf, sizeof (buf)), NULL);
+    if (memcmp(buf, "CSid", 4) != 0)
+        BAIL(PHYSFS_ERR_UNSUPPORTED, NULL);
+
+    *claimed = 1;
+
+    BAIL_IF_ERRPASS(!__PHYSFS_readAll(io, &count, sizeof (count)), NULL);
+    count = PHYSFS_swapULE16(count);
+
+
+    unpkarc = UNPK_openArchive(io, 0, 1);
+    BAIL_IF_ERRPASS(!unpkarc, NULL);
+
+    if (!csmLoadEntries(io, count, unpkarc))
+    {
+        UNPK_abandonArchive(unpkarc);
+        return NULL;
+    } /* if */
+
+    return unpkarc;
+} /* CSM_openArchive */
+
+
+const PHYSFS_Archiver __PHYSFS_Archiver_CSM =
+{
+    CURRENT_PHYSFS_ARCHIVER_API_VERSION,
+    {
+        "CSM",
+        "Chasm: The Rift engine format",
+	"Jon Daniel <jondaniel879@gmail.com>",
+        "http://www.github.com/Panzerschrek/Chasm-Reverse",
+        0,  /* supportsSymlinks */
+    },
+    CSM_openArchive,
+    UNPK_enumerate,
+    UNPK_openRead,
+    UNPK_openWrite,
+    UNPK_openAppend,
+    UNPK_remove,
+    UNPK_mkdir,
+    UNPK_stat,
+    UNPK_closeArchive
+};
+
+#endif  /* defined PHYSFS_SUPPORTS_CSM */
+
+/* end of physfs_archiver_CSM.c ... */
+

+ 4 - 0
src/physfs_internal.h

@@ -88,6 +88,7 @@ extern const PHYSFS_Archiver __PHYSFS_Archiver_QPAK;
 extern const PHYSFS_Archiver __PHYSFS_Archiver_HOG;
 extern const PHYSFS_Archiver __PHYSFS_Archiver_MVL;
 extern const PHYSFS_Archiver __PHYSFS_Archiver_WAD;
+extern const PHYSFS_Archiver __PHYSFS_Archiver_CSM;
 extern const PHYSFS_Archiver __PHYSFS_Archiver_SLB;
 extern const PHYSFS_Archiver __PHYSFS_Archiver_ISO9660;
 extern const PHYSFS_Archiver __PHYSFS_Archiver_VDF;
@@ -200,6 +201,9 @@ void __PHYSFS_smallFree(void *ptr);
 #ifndef PHYSFS_SUPPORTS_WAD
 #define PHYSFS_SUPPORTS_WAD PHYSFS_SUPPORTS_DEFAULT
 #endif
+#ifndef PHYSFS_SUPPORTS_CSM
+#define PHYSFS_SUPPORTS_CSM PHYSFS_SUPPORTS_DEFAULT
+#endif
 #ifndef PHYSFS_SUPPORTS_QPAK
 #define PHYSFS_SUPPORTS_QPAK PHYSFS_SUPPORTS_DEFAULT
 #endif