[docs] Replace cyrillic 'с' with latin 'c' in register names
[kolibrios.git] / contrib / games / wolf3d / id_pm.cpp
blob5d524842e924709db748ae64e9a0911cac9d1589
1 #include "wl_def.h"
3 int ChunksInFile;
4 int PMSpriteStart;
5 int PMSoundStart;
7 bool PMSoundInfoPagePadded = false;
9 // holds the whole VSWAP
10 uint32_t *PMPageData;
11 size_t PMPageDataSize;
13 // ChunksInFile+1 pointers to page starts.
14 // The last pointer points one byte after the last page.
15 uint8_t **PMPages;
17 void PM_Startup()
19 char fname[13] = "vswap.";
20 strcat(fname,extension);
22 FILE *file = fopen(fname,"rb");
23 if(!file)
24 CA_CannotOpen(fname);
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);
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];
50 int i;
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
62 int alignPadding = 0;
63 for(i = PMSpriteStart; i < PMSoundStart; i++)
65 if(!pageOffsets[i]) continue; // sparse page
66 uint32_t offs = pageOffsets[i] - dataStart + alignPadding;
67 if(offs & 1)
68 alignPadding++;
71 if((pageOffsets[ChunksInFile - 1] - dataStart + alignPadding) & 1)
72 alignPadding++;
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
90 if(offs & 1)
92 *ptr++ = 0;
93 if(i == ChunksInFile - 1) PMSoundInfoPagePadded = true;
97 PMPages[i] = ptr;
99 if(!pageOffsets[i])
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.
104 uint32_t size;
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);
110 ptr += size;
113 // last page points after page buffer
114 PMPages[ChunksInFile] = ptr;
116 free(pageLengths);
117 free(pageOffsets);
118 fclose(file);
121 void PM_Shutdown()
123 free(PMPages);
124 free(PMPageData);