7 bool PMSoundInfoPagePadded
= false;
9 // holds the whole VSWAP
11 size_t PMPageDataSize
;
13 // ChunksInFile+1 pointers to page starts.
14 // The last pointer points one byte after the last page.
19 char fname
[13] = "vswap.";
20 strcat(fname
,extension
);
22 FILE *file
= fopen(fname
,"rb");
27 fread(&ChunksInFile
, sizeof(word
), 1, file
);
29 fread(&PMSpriteStart
, sizeof(word
), 1, file
);
31 fread(&PMSoundStart
, sizeof(word
), 1, file
);
33 uint32_t* pageOffsets
= (uint32_t *) malloc((ChunksInFile
+ 1) * sizeof(int32_t));
34 CHECKMALLOCRESULT(pageOffsets
);
35 fread(pageOffsets
, sizeof(uint32_t), ChunksInFile
, file
);
37 word
*pageLengths
= (word
*) malloc(ChunksInFile
* sizeof(word
));
38 CHECKMALLOCRESULT(pageLengths
);
39 fread(pageLengths
, sizeof(word
), ChunksInFile
, file
);
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
);
47 pageOffsets
[ChunksInFile
] = fileSize
;
49 uint32_t dataStart
= pageOffsets
[0];
52 // Check that all pageOffsets are valid
53 for(i
= 0; i
< ChunksInFile
; i
++)
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
);
61 // Calculate total amount of padding needed for sprites and sound info page
63 for(i
= PMSpriteStart
; i
< PMSoundStart
; i
++)
65 if(!pageOffsets
[i
]) continue; // sparse page
66 uint32_t offs
= pageOffsets
[i
] - dataStart
+ alignPadding
;
71 if((pageOffsets
[ChunksInFile
- 1] - dataStart
+ alignPadding
) & 1)
74 PMPageDataSize
= (size_t) pageDataSize
+ alignPadding
;
75 PMPageData
= (uint32_t *) malloc(PMPageDataSize
);
76 CHECKMALLOCRESULT(PMPageData
);
78 PMPages
= (uint8_t **) malloc((ChunksInFile
+ 1) * sizeof(uint8_t *));
79 CHECKMALLOCRESULT(PMPages
);
81 // Load pages and initialize PMPages pointers
82 uint8_t *ptr
= (uint8_t *) PMPageData
;
83 for(i
= 0; i
< ChunksInFile
; i
++)
85 if(i
>= PMSpriteStart
&& i
< PMSoundStart
|| i
== ChunksInFile
- 1)
87 size_t offs
= ptr
- (uint8_t *) PMPageData
;
89 // pad with zeros to make it 2-byte aligned
93 if(i
== ChunksInFile
- 1) PMSoundInfoPagePadded
= true;
100 continue; // sparse page
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.
105 if(!pageOffsets
[i
+ 1]) size
= pageLengths
[i
];
106 else size
= pageOffsets
[i
+ 1] - pageOffsets
[i
];
108 fseek(file
, pageOffsets
[i
], SEEK_SET
);
109 fread(ptr
, 1, size
, file
);
113 // last page points after page buffer
114 PMPages
[ChunksInFile
] = ptr
;