summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/progs/wolf3d/id_pm.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/sdl/progs/wolf3d/id_pm.c')
-rw-r--r--apps/plugins/sdl/progs/wolf3d/id_pm.c125
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
3int ChunksInFile;
4int PMSpriteStart;
5int PMSoundStart;
6
7bool PMSoundInfoPagePadded = false;
8
9// holds the whole VSWAP
10uint32_t *PMPageData;
11size_t PMPageDataSize;
12
13// ChunksInFile+1 pointers to page starts.
14// The last pointer points one byte after the last page.
15uint8_t **PMPages;
16
17void 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
121void PM_Shutdown()
122{
123 free(PMPages);
124 free(PMPageData);
125}