Procházet zdrojové kódy

support vpk1 for portal2, fix #36

Ivan Avdeev před 6 roky
rodič
revize
b82178b678
4 změnil soubory, kde provedl 22 přidání a 9 odebrání
  1. 6 6
      src/collection.c
  2. 7 1
      src/material.c
  3. 2 0
      src/render.c
  4. 7 2
      src/vpk.h

+ 6 - 6
src/collection.c

@@ -172,7 +172,7 @@ struct VPKFileMetadata {
 	} dir, arc;
 };
 
-#define MAX_VPK_ARCHIVES 32
+#define MAX_VPK_ARCHIVES 152
 
 struct VPKCollection {
 	struct ICollection head;
@@ -205,7 +205,7 @@ static size_t vpkCollectionFileRead(struct IFile *file, size_t offset, size_t si
 	if (offset < meta->dir.size) {
 		const void *begin = ((char*)f->collection->dir.data) + offset + meta->dir.off;
 		const size_t dir_size_left = meta->dir.size - offset;
-		if (size < dir_size_left) {
+		if (size <= dir_size_left) {
 			memcpy(buffer, begin, size);
 			return size;
 		}
@@ -324,19 +324,19 @@ struct ICollection *collectionCreateVPK(struct Memories *mem, const char *dir_fi
 	const char *dir = collection->dir.data;
 	const size_t size = collection->dir.size;
 
-	if (size <= sizeof(struct VPK2Header)) {
+	if (size <= sizeof(VPK1Header)) {
 		PRINT("VPK header is too small");
 		exit(-1);
 	}
 
-	const struct VPK2Header *header = (void*)collection->dir.data;
+	const VPK1Header *header = (void*)collection->dir.data;
 
 	if (header->signature != VPK_SIGNATURE) {
 		PRINTF("Wrong VPK signature %08x", header->signature);
 		exit(-1);
 	}
 
-	if (header->version != 2) {
+	if (header->version < 1 || header->version > 2) {
 		PRINTF("VPK version %d is not supported", header->version);
 		exit(-1);
 	}
@@ -345,7 +345,7 @@ struct ICollection *collectionCreateVPK(struct Memories *mem, const char *dir_fi
 
 	int max_archives = -1;
 	const char *const end = dir + size;
-	const char *c = dir + sizeof(struct VPK2Header);
+	const char *c = dir + ((header->version == 1) ? sizeof(VPK1Header) : sizeof(VPK2Header));
 	for (;;) {
 		// read extension
 		const struct StringView ext = readString(&c, end);

+ 7 - 1
src/material.c

@@ -147,8 +147,11 @@ static int materialLoad(struct IFile *file, struct ICollection *coll, Material *
 		return 0;
 	}
 
-	if (file->size != file->read(file, 0, file->size, buffer))
+	const int read_size = file->read(file, 0, file->size, buffer);
+	if ((int)file->size != read_size) {
+		PRINTF("Cannot read material file: %d != %d", (int)file->size, read_size);
 		return 0;
+	}
 
 	MaterialContext ctx = {
 		.collection = coll,
@@ -165,6 +168,9 @@ static int materialLoad(struct IFile *file, struct ICollection *coll, Material *
 
 	const int success = VMFResult_Success == vmfParse(&parser_state);
 
+	if (!success)
+		PRINTF("Failed to read material with contents:\n" PRI_SV, PRI_SVV(parser_state.data));
+
 	if (success && ctx.mat->base_texture.texture)
 		ctx.mat->average_color = ctx.mat->base_texture.texture->avg_color;
 

+ 2 - 0
src/render.c

@@ -643,6 +643,8 @@ static void renderSkybox(const struct Camera *camera, const struct BSPModel *mod
 
 	GL_CALL(glDisable(GL_CULL_FACE));
 	for (int i = 0; i < BSPSkyboxDir_COUNT; ++i) {
+		if (!model->skybox[i] || !model->skybox[i]->base_texture.texture)
+			continue;
 		renderUseMaterial(model->skybox[i]);
 		renderApplyAttribs(attribs, &box_buffer, 0);
 		GL_CALL(glDrawArrays(GL_TRIANGLES, i*6, 6));

+ 7 - 2
src/vpk.h

@@ -3,12 +3,17 @@
 
 #pragma pack(1)
 #define VPK_SIGNATURE (0x55aa1234ul)
-struct VPK2Header {
+typedef struct {
+	uint32_t signature;
+	uint32_t version;
+	uint32_t treeSize;
+} VPK1Header;
+typedef struct {
 	uint32_t signature;
 	uint32_t version;
 	uint32_t treeSize;
 	uint32_t dontCareSize[4];
-};
+} VPK2Header;
 
 #define VPK_TERMINATOR (0xffffu)
 struct VPKTreeEntry {