Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
8557 | maxcodehac | 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] = "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 | }>>>>> |