forked from gzalo/HalfMapper
-
Notifications
You must be signed in to change notification settings - Fork 0
/
wad.cpp
74 lines (59 loc) · 2.8 KB
/
wad.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include "common.h"
#include "bsp.h"
#include "wad.h"
int wadLoad(const string &filename){
ifstream inWAD(filename.c_str(), ios::binary);
if(!inWAD.is_open()){ cerr << "Can't load WAD " << filename << "." << endl; return -1; }
//Read header
WADHEADER wh; inWAD.read((char*)&wh, sizeof(wh));
if(wh.szMagic[0] != 'W' || wh.szMagic[1] != 'A' || wh.szMagic[2] != 'D' || wh.szMagic[3] != '3') return -1;
//Read directory entries
WADDIRENTRY *wdes = new WADDIRENTRY[wh.nDir];
inWAD.seekg(wh.nDirOffset, ios::beg);
inWAD.read((char*)wdes, sizeof(WADDIRENTRY)*wh.nDir);
uint8_t *dataDr = new uint8_t[512*512]; //Raw texture data
uint8_t *dataUp = new uint8_t[512*512*4]; //32 bit texture
uint8_t *dataPal = new uint8_t[256*3]; //256 color pallete
for(int i=0;i<wh.nDir;i++){
inWAD.seekg(wdes[i].nFilePos, ios::beg);
BSPMIPTEX bmt;
inWAD.read((char*)&bmt, sizeof(bmt));
if(textures.count(bmt.szName) == 0){ //Only load if it's the first appearance of the texture
TEXTURE n;
n.w = bmt.nWidth; n.h = bmt.nHeight;
glGenTextures(1, &n.texId);
glBindTexture(GL_TEXTURE_2D, n.texId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 3);
//Sizes of each mipmap
const int dimensionsSquared[4] = {1,4,16,64};
const int dimensions[4] = {1,2,4,8};
//Read each mipmap
for(int mip=3;mip>=0;mip--){
inWAD.seekg(wdes[i].nFilePos+bmt.nOffsets[mip], ios::beg);
inWAD.read((char*)dataDr, bmt.nWidth*bmt.nHeight/dimensionsSquared[mip]);
if(mip == 3){
//Read the pallete (comes after last mipmap)
uint16_t dummy; inWAD.read((char*)&dummy, 2);
inWAD.read((char*)dataPal, 256*3);
}
for(uint32_t y=0;y<bmt.nHeight/dimensions[mip];y++)
for(uint32_t x=0;x<bmt.nWidth/dimensions[mip];x++){
dataUp[(x+y*bmt.nWidth/dimensions[mip])*4] = dataPal[dataDr[y*bmt.nWidth/dimensions[mip]+x]*3];
dataUp[(x+y*bmt.nWidth/dimensions[mip])*4+1] = dataPal[dataDr[y*bmt.nWidth/dimensions[mip]+x]*3+1];
dataUp[(x+y*bmt.nWidth/dimensions[mip])*4+2] = dataPal[dataDr[y*bmt.nWidth/dimensions[mip]+x]*3+2];
//Do full transparency on blue pixels
if(dataUp[(x+y*bmt.nWidth/dimensions[mip])*4] == 0 && dataUp[(x+y*bmt.nWidth/dimensions[mip])*4+1] == 0 && dataUp[(x+y*bmt.nWidth/dimensions[mip])*4+2] == 255)
dataUp[(x+y*bmt.nWidth/dimensions[mip])*4+3] = 0;
else
dataUp[(x+y*bmt.nWidth/dimensions[mip])*4+3] = 255;
}
glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA, bmt.nWidth/dimensions[mip], bmt.nHeight/dimensions[mip], 0, GL_RGBA, GL_UNSIGNED_BYTE, dataUp);
}
textures[bmt.szName]=n;
}
}
delete []dataDr; delete []dataUp; delete []dataPal; delete []wdes;
return 0;
}