Subversion Repositories Kolibri OS

Rev

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
}