Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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. }
  126.