-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpak.c
100 lines (81 loc) · 2.05 KB
/
pak.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pak.h"
typedef struct {
char magic[4];
int32_t offset;
int32_t size;
} PakHeader;
typedef struct {
char filename[56];
int32_t offset;
int32_t size;
} PakEntry;
typedef struct {
char *filename;
int size;
void *data;
} File;
struct s_PakFile {
File *files;
int numFiles;
};
PakFile *readPakFile(const char *filename){
PakFile *pak = malloc(sizeof(PakFile));
FILE *fp = fopen(filename, "rb");
if(fp == NULL){
printf("Could not open file: %s\n", filename);
return NULL;
}
PakHeader header;
// Read in PAK header
fread(&header, sizeof(PakHeader), 1, fp);
// Verify that this is a valid pak file
if(header.magic[0] != 'P' || header.magic[1] != 'A' ||
header.magic[2] != 'C' || header.magic[3] != 'K'){
printf("Invalid pak file: %s\n", filename);
return NULL;
}
PakEntry *entries = malloc(header.size);
int numEntries = header.size/sizeof(PakEntry);
pak->numFiles = numEntries;
pak->files = malloc(sizeof(FILE)*numEntries);
// Go to first entry
fseek(fp, header.offset, SEEK_SET);
// Read in all entries
fread(entries, sizeof(PakEntry), numEntries, fp);
// Read all file entries
for(int i=0; i < numEntries; i++){
int filenameLength = strlen(entries[i].filename);
pak->files[i].filename = malloc(filenameLength+1);
strcpy(pak->files[i].filename, entries[i].filename);
pak->files[i].size = entries[i].size;
pak->files[i].data = malloc(pak->files[i].size);
fseek(fp, entries[i].offset, SEEK_SET);
fread(pak->files[i].data, 1, pak->files[i].size, fp);
}
fclose(fp);
free(entries);
return pak;
}
void *readFile(PakFile *pf, const char *filename, int *size){
for(int i=0; i<pf->numFiles; i++){
if(strcmp(filename, pf->files[i].filename) == 0){
// If size pointer isn't NULL set file size
if(size != NULL){
*size = pf->files[i].size;
}
return pf->files[i].data;
}
}
return NULL;
}
void freePak(PakFile *pf){
for(int i=0; i<pf->numFiles; i++){
free(pf->files[i].filename);
free(pf->files[i].data);
}
free(pf->files);
free(pf);
}