diff options
Diffstat (limited to 'apps/plugins/sdl/progs/wolf3d/id_pm.c')
-rw-r--r-- | apps/plugins/sdl/progs/wolf3d/id_pm.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/apps/plugins/sdl/progs/wolf3d/id_pm.c b/apps/plugins/sdl/progs/wolf3d/id_pm.c new file mode 100644 index 0000000000..4b8d580b14 --- /dev/null +++ b/apps/plugins/sdl/progs/wolf3d/id_pm.c | |||
@@ -0,0 +1,125 @@ | |||
1 | #include "wl_def.h" | ||
2 | |||
3 | int ChunksInFile; | ||
4 | int PMSpriteStart; | ||
5 | int PMSoundStart; | ||
6 | |||
7 | bool PMSoundInfoPagePadded = false; | ||
8 | |||
9 | // holds the whole VSWAP | ||
10 | uint32_t *PMPageData; | ||
11 | size_t PMPageDataSize; | ||
12 | |||
13 | // ChunksInFile+1 pointers to page starts. | ||
14 | // The last pointer points one byte after the last page. | ||
15 | uint8_t **PMPages; | ||
16 | |||
17 | void PM_Startup() | ||
18 | { | ||
19 | char fname[13 + sizeof(DATADIR)] = DATADIR "vswap."; | ||
20 | strcat(fname,extension); | ||
21 | |||
22 | FILE *file = fopen(fname,"rb"); | ||
23 | if(!file) | ||
24 | CA_CannotOpen(fname); | ||
25 | |||
26 | ChunksInFile = 0; | ||
27 | fread(&ChunksInFile, sizeof(word), 1, file); | ||
28 | PMSpriteStart = 0; | ||
29 | fread(&PMSpriteStart, sizeof(word), 1, file); | ||
30 | PMSoundStart = 0; | ||
31 | fread(&PMSoundStart, sizeof(word), 1, file); | ||
32 | |||
33 | uint32_t* pageOffsets = (uint32_t *) malloc((ChunksInFile + 1) * sizeof(int32_t)); | ||
34 | CHECKMALLOCRESULT(pageOffsets); | ||
35 | fread(pageOffsets, sizeof(uint32_t), ChunksInFile, file); | ||
36 | |||
37 | word *pageLengths = (word *) malloc(ChunksInFile * sizeof(word)); | ||
38 | CHECKMALLOCRESULT(pageLengths); | ||
39 | fread(pageLengths, sizeof(word), ChunksInFile, file); | ||
40 | |||
41 | fseek(file, 0, SEEK_END); | ||
42 | long fileSize = ftell(file); | ||
43 | long pageDataSize = fileSize - pageOffsets[0]; | ||
44 | if(pageDataSize > (size_t) -1) | ||
45 | Quit("The page file \"%s\" is too large!", fname); | ||
46 | |||
47 | pageOffsets[ChunksInFile] = fileSize; | ||
48 | |||
49 | uint32_t dataStart = pageOffsets[0]; | ||
50 | int i; | ||
51 | |||
52 | // Check that all pageOffsets are valid | ||
53 | for(i = 0; i < ChunksInFile; i++) | ||
54 | { | ||
55 | if(!pageOffsets[i]) continue; // sparse page | ||
56 | if(pageOffsets[i] < dataStart || pageOffsets[i] >= (size_t) fileSize) | ||
57 | Quit("Illegal page offset for page %i: %u (filesize: %u)", | ||
58 | i, pageOffsets[i], fileSize); | ||
59 | } | ||
60 | |||
61 | // Calculate total amount of padding needed for sprites and sound info page | ||
62 | int alignPadding = 0; | ||
63 | for(i = PMSpriteStart; i < PMSoundStart; i++) | ||
64 | { | ||
65 | if(!pageOffsets[i]) continue; // sparse page | ||
66 | uint32_t offs = pageOffsets[i] - dataStart + alignPadding; | ||
67 | if(offs & 1) | ||
68 | alignPadding++; | ||
69 | } | ||
70 | |||
71 | if((pageOffsets[ChunksInFile - 1] - dataStart + alignPadding) & 1) | ||
72 | alignPadding++; | ||
73 | |||
74 | PMPageDataSize = (size_t) pageDataSize + alignPadding; | ||
75 | PMPageData = (uint32_t *) malloc(PMPageDataSize); | ||
76 | CHECKMALLOCRESULT(PMPageData); | ||
77 | |||
78 | PMPages = (uint8_t **) malloc((ChunksInFile + 1) * sizeof(uint8_t *)); | ||
79 | CHECKMALLOCRESULT(PMPages); | ||
80 | |||
81 | // Load pages and initialize PMPages pointers | ||
82 | uint8_t *ptr = (uint8_t *) PMPageData; | ||
83 | for(i = 0; i < ChunksInFile; i++) | ||
84 | { | ||
85 | if(i >= PMSpriteStart && i < PMSoundStart || i == ChunksInFile - 1) | ||
86 | { | ||
87 | size_t offs = ptr - (uint8_t *) PMPageData; | ||
88 | |||
89 | // pad with zeros to make it 2-byte aligned | ||
90 | if(offs & 1) | ||
91 | { | ||
92 | *ptr++ = 0; | ||
93 | if(i == ChunksInFile - 1) PMSoundInfoPagePadded = true; | ||
94 | } | ||
95 | } | ||
96 | |||
97 | PMPages[i] = ptr; | ||
98 | |||
99 | if(!pageOffsets[i]) | ||
100 | continue; // sparse page | ||
101 | |||
102 | // Use specified page length, when next page is sparse page. | ||
103 | // Otherwise, calculate size from the offset difference between this and the next page. | ||
104 | uint32_t size; | ||
105 | if(!pageOffsets[i + 1]) size = pageLengths[i]; | ||
106 | else size = pageOffsets[i + 1] - pageOffsets[i]; | ||
107 | |||
108 | fseek(file, pageOffsets[i], SEEK_SET); | ||
109 | fread(ptr, 1, size, file); | ||
110 | ptr += size; | ||
111 | } | ||
112 | |||
113 | // last page points after page buffer | ||
114 | PMPages[ChunksInFile] = ptr; | ||
115 | |||
116 | free(pageLengths); | ||
117 | free(pageOffsets); | ||
118 | fclose(file); | ||
119 | } | ||
120 | |||
121 | void PM_Shutdown() | ||
122 | { | ||
123 | free(PMPages); | ||
124 | free(PMPageData); | ||
125 | } | ||