예제 #1
0
파일: model.cpp 프로젝트: AwkwardDev/server
ModelInstance::ModelInstance(MPQFile &f,const char* ModelInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE *pDirfile)
{
    float ff[3];
    f.read(&id, 4);
    f.read(ff,12);
    pos = fixCoords(Vec3D(ff[0],ff[1],ff[2]));
    f.read(ff,12);
    rot = Vec3D(ff[0],ff[1],ff[2]);
    f.read(&scale,4);
    // scale factor - divide by 1024. blizzard devs must be on crack, why not just use a float?
    sc = scale / 1024.0f;

    char tempname[512];
    sprintf(tempname, "%s/%s", szWorkDirWmo, ModelInstName);
    FILE *input;
    input = fopen(tempname, "r+b");

    if(!input)
    {
        //printf("ModelInstance::ModelInstance couldn't open %s\n", tempname);
        return;
    }

    fseek(input, 8, SEEK_SET); // get the correct no of vertices
    int nVertices;
    fread(&nVertices, sizeof (int), 1, input);
    fclose(input);

    if(nVertices == 0)
        return;

    uint16 adtId = 0;// not used for models
    uint32 flags = MOD_M2;
	if(tileX == 65 && tileY == 65) flags |= MOD_WORLDSPAWN;
    //write mapID, tileX, tileY, Flags, ID, Pos, Rot, Scale, name
    fwrite(&mapID, sizeof(uint32), 1, pDirfile);
    fwrite(&tileX, sizeof(uint32), 1, pDirfile);
    fwrite(&tileY, sizeof(uint32), 1, pDirfile);
    fwrite(&flags, sizeof(uint32), 1, pDirfile);
    fwrite(&adtId, sizeof(uint16), 1, pDirfile);
    fwrite(&id, sizeof(uint32), 1, pDirfile);
    fwrite(&pos, sizeof(float), 3, pDirfile);
    fwrite(&rot, sizeof(float), 3, pDirfile);
    fwrite(&sc, sizeof(float), 1, pDirfile);
    uint32 nlen=strlen(ModelInstName);
    fwrite(&nlen, sizeof(uint32), 1, pDirfile);
    fwrite(ModelInstName, sizeof(char), nlen, pDirfile);

    /* int realx1 = (int) ((float) pos.x / 533.333333f);
    int realy1 = (int) ((float) pos.z / 533.333333f);
    int realx2 = (int) ((float) pos.x / 533.333333f);
    int realy2 = (int) ((float) pos.z / 533.333333f);

    fprintf(pDirfile,"%s/%s %f,%f,%f_%f,%f,%f %f %d %d %d,%d %d\n",
        MapName,
        ModelInstName,
        (float) pos.x, (float) pos.y, (float) pos.z,
        (float) rot.x, (float) rot.y, (float) rot.z,
        sc,
        nVertices,
        realx1, realy1,
        realx2, realy2
        ); */
}
예제 #2
0
파일: wmo.cpp 프로젝트: Aion/mangos
WMOInstance::WMOInstance(MPQFile &f,const char* WmoInstName,const char*MapName, FILE *pDirfile)
{
	pos = Vec3D(0,0,0);

	float ff[3];
	f.read(&id, 4);
	f.read(ff,12);
	pos = Vec3D(ff[0],ff[1],ff[2]);
	f.read(ff,12);
	rot = Vec3D(ff[0],ff[1],ff[2]);
	f.read(ff,12);
	pos2 = Vec3D(ff[0],ff[1],ff[2]);
	f.read(ff,12);
	pos3 = Vec3D(ff[0],ff[1],ff[2]);
	f.read(&d2,4);
	f.read(&d3,4);

	doodadset = (d2 & 0xFFFF0000) >> 16;

	int realx1 = (int) ((float) pos2.x / 533.333333f);
	int realy1 = (int) ((float) pos2.z / 533.333333f);
	int realx2 = (int) ((float) pos3.x / 533.333333f);
	int realy2 = (int) ((float) pos3.z / 533.333333f);

	if(realx1 < 0) 
	{ 
		realx1 +=20; realx2+=20; 
	}
	if(realy1 < 0) 
	{ 
		realy1 +=20; realy2+=20; 
	} // hack to prevent neg. values

	//-----------add_in _dir_file----------------

	char tempname[512];
	//	const char dirname[] = "buildings\\dir";

	sprintf(tempname, "buildings\\%s", WmoInstName);
	FILE *input;
	input = fopen(tempname, "r+b");
	if(!input)
	{
		return;
	}
	fseek(input, 8, SEEK_SET); // get the correct no of vertices
	int nVertices;
	fread(&nVertices, sizeof (int), 1, input);
	fclose(input);
	if(nVertices == 0)
	{
		return;
	}

	/*	FILE *dirfile;
	dirfile = fopen(dirname, "ab");
	if(!dirfile)
	{
	printf("Can't open dirfile!'%s'\n");
	return;
	}
	*/
	float x,z;
	x = pos.x;
	z = pos.z;
	if(x==0 && z == 0) 
	{ x = 533.33333f*32; z = 533.33333f*32; }
	fprintf(pDirfile,"%s/%s %f,%f,%f_%f,%f,%f 1.0 %d %d %d,%d %d\n",
		MapName,
		WmoInstName,
		(float) x, (float) pos.y, (float) z,
		(float) rot.x, (float) rot.y, (float) rot.z,
		nVertices,
		realx1, realy1,
		realx2, realy2
		);

	// fclose(dirfile);
}	
예제 #3
0
파일: wmo.cpp 프로젝트: Carbinfibre/ArcPro
WMOInstance::WMOInstance(MPQFile &f,const char* WmoInstName, uint32 mapID, uint32 tileX, uint32 tileY, FILE *pDirfile)
{
    pos = Vec3D(0,0,0);

    float ff[3];
    f.read(&id, 4);
    f.read(ff,12);
    pos = Vec3D(ff[0],ff[1],ff[2]);
    f.read(ff,12);
    rot = Vec3D(ff[0],ff[1],ff[2]);
    f.read(ff,12);
    pos2 = Vec3D(ff[0],ff[1],ff[2]);
    f.read(ff,12);
    pos3 = Vec3D(ff[0],ff[1],ff[2]);
    f.read(&d2,4);

    uint16 trash,adtId;
    f.read(&adtId,2);
    f.read(&trash,2);

    //-----------add_in _dir_file----------------

    char tempname[512];
    sprintf(tempname, "%s/%s", szWorkDirWmo, WmoInstName);
    FILE *input;
    input = fopen(tempname, "r+b");

    if(!input)
    {
        printf("WMOInstance::WMOInstance: couldn't open %s\n", tempname);
        return;
    }

    fseek(input, 8, SEEK_SET); // get the correct no of vertices
    int nVertices;
    fread(&nVertices, sizeof (int), 1, input);
    fclose(input);

    if(nVertices == 0)
        return;

    float x,z;
    x = pos.x;
    z = pos.z;
    if(x==0 && z == 0)
    {
        pos.x = 533.33333f*32;
        pos.z = 533.33333f*32;
    }
    pos = fixCoords(pos);
    pos2 = fixCoords(pos2);
    pos3 = fixCoords(pos3);

    float scale = 1.0f;
    uint32 flags = MOD_HAS_BOUND;
    if(tileX == 65 && tileY == 65) flags |= MOD_WORLDSPAWN;
    //write mapID, tileX, tileY, Flags, ID, Pos, Rot, Scale, Bound_lo, Bound_hi, name
    fwrite(&mapID, sizeof(uint32), 1, pDirfile);
    fwrite(&tileX, sizeof(uint32), 1, pDirfile);
    fwrite(&tileY, sizeof(uint32), 1, pDirfile);
    fwrite(&flags, sizeof(uint32), 1, pDirfile);
    fwrite(&adtId, sizeof(uint16), 1, pDirfile);
    fwrite(&id, sizeof(uint32), 1, pDirfile);
    fwrite(&pos, sizeof(float), 3, pDirfile);
    fwrite(&rot, sizeof(float), 3, pDirfile);
    fwrite(&scale, sizeof(float), 1, pDirfile);
    fwrite(&pos2, sizeof(float), 3, pDirfile);
    fwrite(&pos3, sizeof(float), 3, pDirfile);
    uint32 nlen=strlen(WmoInstName);
    fwrite(&nlen, sizeof(uint32), 1, pDirfile);
    fwrite(WmoInstName, sizeof(char), nlen, pDirfile);

    /* fprintf(pDirfile,"%s/%s %f,%f,%f_%f,%f,%f 1.0 %d %d %d,%d %d\n",
        MapName,
        WmoInstName,
        (float) x, (float) pos.y, (float) z,
        (float) rot.x, (float) rot.y, (float) rot.z,
        nVertices,
        realx1, realy1,
        realx2, realy2
        ); */

    // fclose(dirfile);
}
예제 #4
0
LiquidModelInstance::LiquidModelInstance(MPQFile &f, uint32 base_pos, uint32 tileID, MH20_Header* header, uint32 mapID, uint32 tileX, uint32 tileY, FILE *pDirfile) : Info(false)
{
	memset(&LiqHeader, 0, sizeof(LiquidHeader));
	LiqHeader.layerCount = header->layerCount;
	if(header->ofsInformation == 0)
	{
		Info = false;
		return;
	}

#ifdef _DEBUG
	printf("Information offset: %i\n", header->ofsInformation);
#endif
	f.seek(header->ofsInformation+base_pos);
	f.read(&LiqHeader.info, sizeof(MH20_Information));

#ifdef _DEBUG
	if(LiqHeader.info.LiquidType != 2) // Skip oceans
	{
		printf("Liquid Data Dump:\n");
		printf("Flags: %08i |\n", LiqHeader.info.flags);
//		printf("Height %08i |\n", LiqHeader.info.height);
//		printf("Level1 %08f |\n", LiqHeader.info.heightLevel1);
//		printf("Level2 %08f |\n", LiqHeader.info.heightLevel2);
		printf("LType: %08i |\n", LiqHeader.info.LiquidType);
		printf("Width: %08i |\n", LiqHeader.info.width);
		printf("xOfset %08i |\n", LiqHeader.info.xOffset);
		printf("yOfset %08i |\n", LiqHeader.info.yOffset);
		WaitForInput();
	}
#endif

	uint16* buff = new uint16[3];
	buff[0] = buff[1] = buff[2] = 0;
	if(LiqHeader.info.ofsHeightmap > 0)
	{
#ifdef _DEBUG
		printf("Height Map Offset: %i\n", LiqHeader.info.ofsHeightmap);
#endif
		f.seek(LiqHeader.info.ofsHeightmap+base_pos);
		f.read(&LiqHeader.heightMap.heightMap, sizeof(float)*2);
		f.read(&LiqHeader.heightMap.transparency, sizeof(char)*2);
		buff[0] = sizeof(LiqHeader.heightMap);
	}

	if(LiqHeader.info.ofsMask2 > 0)
	{
#ifdef _DEBUG
		printf("Mask Offset: %i\n", LiqHeader.info.ofsMask2);
#endif
		f.seek(LiqHeader.info.ofsMask2+base_pos);
		f.read(&LiqHeader.Mask2, sizeof(uint8));
		buff[1] = sizeof(uint8);
	}

	if(header->ofsRender > 0)
	{
#ifdef _DEBUG
		printf("Render offset: %i\n", header->ofsRender);
#endif
		f.seek(header->ofsRender+base_pos);
		f.read(&LiqHeader.Render, sizeof(uint64));
		buff[2] = sizeof(uint64);
	}

	fwrite(&LiqHeader.layerCount, sizeof(uint32), 1, pDirfile);
	fwrite(&LiqHeader.info, sizeof(MH20_Information), 1, pDirfile);

	fwrite(&buff[0], sizeof(uint16), 1, pDirfile);
	if(buff[0])
		fwrite(&LiqHeader.heightMap, sizeof(MH2O_HeightMapData), 1, pDirfile);
	fwrite(&buff[1], sizeof(uint16), 1, pDirfile);
	if(buff[1])
		fwrite(&LiqHeader.Mask2, sizeof(uint8), 1, pDirfile);
	fwrite(&buff[2], sizeof(uint16), 1, pDirfile);
	if(buff[2])
		fwrite(&LiqHeader.Render, sizeof(uint64), 1, pDirfile);
}
예제 #5
0
Application::Application(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    MPQInit();
    instance = this;
    resources = NULL;
    imageLibrary = NULL;
    dotaLibrary = NULL;
    mainWindow = NULL;
    cache = NULL;
    hInstance = _hInstance;
    _loaded = false;

    root = String::getPath(getAppPath());
    cfg.read();

    warLoader = new MPQLoader("Custom_V1");
    warLoader->loadArchive(String::buildFullName(cfg.warPath, "war3.mpq"));
    warLoader->loadArchive(String::buildFullName(cfg.warPath, "war3x.mpq"));
    warLoader->loadArchive(String::buildFullName(cfg.warPath, "war3xlocal.mpq"));
    warLoader->loadArchive(String::buildFullName(cfg.warPath, "war3patch.mpq"));

    if (logCommand(lpCmdLine))
        return;

    ScriptType::initTypes();
    UpdateDialog::init(hInstance);

    INITCOMMONCONTROLSEX iccex;
    iccex.dwSize = sizeof iccex;
    iccex.dwICC = ICC_STANDARD_CLASSES | ICC_PROGRESS_CLASS |
                  ICC_BAR_CLASSES | ICC_TREEVIEW_CLASSES | ICC_LISTVIEW_CLASSES |
                  ICC_TAB_CLASSES | ICC_UPDOWN_CLASS | ICC_DATE_CLASSES;
    InitCommonControlsEx(&iccex);
    LoadLibrary("Riched20.dll");
    OleInitialize(NULL);

    String path = String::getPath(getAppPath());
    String resPath = String::buildFullName(path, "resources.mpq");
    String patchPath = String::buildFullName(path, "install.mpq");
    File* tOpen = File::open(resPath, File::READ);
    if (tOpen == NULL)
    {
        tOpen = File::open(patchPath, File::READ);
        if (tOpen)
        {
            delete tOpen;
            MoveFile(patchPath, resPath);
        }
    }
    else
        delete tOpen;
    resources = MPQArchive::open(resPath);
    MPQArchive* patch = MPQArchive::open(patchPath, File::READ);
    if (patch)
    {
        for (uint32 i = 0; i < patch->getHashSize(); i++)
        {
            char const* name = patch->getFileName(i);
            if (name)
            {
                MPQFile* source = patch->openFile(i, File::READ);
                if (source)
                {
                    MPQFile* dest = resources->openFile(name, File::REWRITE);
                    if (dest)
                    {
                        static uint8 buf[1024];
                        while (int length = source->read(buf, sizeof buf))
                            dest->write(buf, length);
                        delete dest;
                    }
                    delete source;
                }
            }
        }
        delete patch;
        DeleteFile(patchPath);
    }

    imageLibrary = new ImageLibrary(resources);

    cache = new CacheManager();
    dotaLibrary = new DotaLibrary();

#if 0
    File* dlog = File::open("diff.txt", File::REWRITE);
    for (int pt = 0; pt < 120; pt++)
    {
        String prev = "";
        bool different = false;
        for (int ver = 1; ver <= 80 && !different; ver++)
        {
            Dota* dota = dotaLibrary->getDota(makeVersion(6, ver));
            if (dota)
            {
                Dota::Hero* hero = dota->getHero(pt);
                if (hero)
                {
                    if (prev == "")
                        prev = hero->name;
                    else if (prev.icompare(hero->name))
                        different = true;
                }
            }
        }
        if (different)
        {
            dlog->printf("  Pt=%d\r\n", pt);
            prev = "";
            for (int ver = 1; ver <= 80; ver++)
            {
                Dota* dota = dotaLibrary->getDota(makeVersion(6, ver));
                if (dota)
                {
                    Dota::Hero* hero = dota->getHero(pt);
                    if (hero)
                    {
                        if (prev.icompare(hero->name))
                        {
                            dlog->printf("6.%02d = %s\r\n", ver, hero->name);
                            prev = hero->name;
                        }
                    }
                }
            }
        }
    }
    delete dlog;
#endif
#if 0
    dotaLibrary->getDota(parseVersion("6.79e"),
                         "K:\\Progs\\DotAReplay\\maps\\DotA v6.79e.w3x");
    WIN32_FIND_DATA data;
    String enumPath = "K:\\Progs\\DotAReplay\\maps";
    HANDLE hFind = FindFirstFile(String::buildFullName(enumPath, "*"), &data);
    BOOL success = (hFind != INVALID_HANDLE_VALUE);
    while (success)
    {
        String file(data.cFileName);
        if (String::getExtension(file).icompare(".w3x") == 0)
        {
            file.toLower();
            Array<String> sub;
            if (file.rfind("dota{{_| }allstars}?{_| }v(\\d)\\.(\\d\\d)([b-z]?)[^b-z]", 0, &sub) >= 0)
            {
                int major = sub[1].toInt();
                int minor = sub[2].toInt();
                int build = 0;
                if (!sub[3].isEmpty())
                    build = int(sub[3][0] - 'a');
                uint32 version = makeVersion(major, minor, build);

                dotaLibrary->getDota(version, String::buildFullName(enumPath, file));
            }
        }
        success = FindNextFile(hFind, &data);
    }
    FindClose(hFind);
#endif

    mainWindow = new MainWnd();

    mainWindow->postLoad();
    _loaded = true;

    if (lpCmdLine[0])
    {
        COPYDATASTRUCT cd;
        cd.dwData = MAINWND_OPEN_REPLAY;
        cd.cbData = strlen(lpCmdLine) + 1;
        cd.lpData = lpCmdLine;
        PostMessage(getMainWindow(), WM_COPYDATA_FAKE, NULL, (LPARAM) &cd);
    }
}
예제 #6
0
inline void LoadMapChunk(MPQFile &mf, chunk *_chunk)
{
    float h;
    uint32 fourcc;
    uint32 size;
    MapChunkHeader header;

    mf.seekRelative(4);
    mf.read(&size, 4);

    size_t lastpos = mf.getPos() + size;
    mf.read(&header, 0x80);                                 // what if header size got changed?
    _chunk->area_id = header.areaid;

    float xbase = header.xpos;
    float ybase = header.ypos;
    float zbase = header.zpos;
    zbase = TILESIZE * 32 - zbase;
    xbase = TILESIZE * 32 - xbase;
    if(wmoc.x > xbase) wmoc.x = xbase;
    if(wmoc.z > zbase) wmoc.z = zbase;
    int chunkflags = header.flags;
    //printf("LMC: flags %X\n", chunkflags);
    float zmin = 999999999.0f;
    float zmax = -999999999.0f;
    // must be there, bl!zz uses some crazy format
    while (mf.getPos() < lastpos)
    {
        mf.read(&fourcc, 4);
        mf.read(&size, 4);
        size_t nextpos = mf.getPos() + size;
        if(fourcc == 0x4d435654)                            // MCVT
        {
            for (int j = 0; j < 17; ++j)
            {
                for (int i = 0; i < ((j % 2) ? 8 : 9); ++i)
                {
                    mf.read(&h, 4);
                    float z = h + ybase;
                    if (j % 2)
                    {
                        if(isHole(header.holes, i, j))
                            _chunk->v8[i][j / 2] = -1000;
                        else
                            _chunk->v8[i][j / 2] = z;
                    }
                    else
                    {
                        if(isHole(header.holes, i, j))
                            _chunk->v9[i][j / 2] = -1000;
                        else
                            _chunk->v9[i][j / 2] = z;
                    }

                    if(z > zmax) zmax = z;
                    //if(z < zmin) zmin = z;
                }
            }
        }
        else if(fourcc == 0x4d434e52)                       // MCNR
        {
            nextpos = mf.getPos() + 0x1C0;                  // size fix
        }
        else if(fourcc == 0x4d434c51)                       // MCLQ
        {
            // liquid / water level
            char fcc1[5];
            mf.read(fcc1, 4);
            flipcc(fcc1);
            fcc1[4] = 0;
            float *ChunkLiqHeight = new float[81];

            if (!strcmp(fcc1, "MCSE"))
            {
                for(int j = 0; j < 81; ++j)
                {
                    ChunkLiqHeight[j] = -999999;            // no liquid/water
                }
            }
            else
            {
                float maxheight;
                mf.read(&maxheight, 4);
                for(int j = 0; j < 81; ++j)
                {
                    LiqData liq;
                    mf.read(&liq, 8);

                    if(liq.height > maxheight)
                        ChunkLiqHeight[j] = -999999;
                    else
                        ChunkLiqHeight[j] = h;
                }

                if(chunkflags & 4 || chunkflags & 8)
                    MapLiqFlag[chunk_num] |= 1;             // water
                if(chunkflags & 16)
                    MapLiqFlag[chunk_num] |= 2;             // magma/slime
            }
            if(!(chunk_num % 16))
                m = 1024 * (chunk_num / 16);
            k = m + (chunk_num % 16) * 8;
            
            for(int p = 0; p < 72; p += 9)
            {
                for(int s = 0; s < 8; ++s)
                {
                    MapLiqHeight[k] = ChunkLiqHeight[p + s];
                    ++k;    
                }
                k = k + 120;
            }
            delete []ChunkLiqHeight;
            break;
        }
        mf.seek(nextpos);
    }
}
예제 #7
0
파일: adt.cpp 프로젝트: Bootz/TC-One
inline
void LoadMapChunk(MPQFile & mf, chunk*_chunk)
{
    float h;
    uint32 fourcc;
    uint32 size;
    MapChunkHeader header;

    mf.seekRelative(4);
    mf.read(&size, 4);

    size_t lastpos = mf.getPos() + size;
    mf.read(&header, 0x80);
    _chunk->area_id =header.areaid ;
    _chunk->flag =0;

    float xbase = header.xpos;
    float ybase = header.ypos;
    float zbase = header.zpos;
    zbase = TILESIZE*32-zbase;
    xbase = TILESIZE*32-xbase;
    if(wmoc.x >xbase)wmoc.x =xbase;
    if(wmoc.z >zbase)wmoc.z =zbase;
    int chunkflags = header.flags;
    float zmin=999999999.0f;
    float zmax=-999999999.0f;
    //must be there, bl!zz uses some crazy format
    int nTextures;
    while (mf.getPos() < lastpos)
    {
        mf.read(&fourcc,4);
        mf.read(&size, 4);
        //if(size!=580)
        //    printf("\n sz=%d",size);
        size_t nextpos = mf.getPos()  + size;
        if(fourcc==0x4d435654)                              // MCVT
        {
            for (int j=0; j<17; j++)
                for (int i=0; i<((j%2)?8:9); i++)
                {
                    mf.read(&h,4);
                    float z=h+ybase;
                    if (j%2)
                    {
                        if(isHole(header.holes,i,j))
                            _chunk->v8[i][j/2] = -1000;
                        else
                            _chunk->v8[i][j/2] = z;
                    }
                    else
                    {
                        if(isHole(header.holes,i,j))
                            _chunk->v9[i][j/2] = -1000;
                        else
                            _chunk->v9[i][j/2] = z;
                    }

                    if(z>zmax)zmax=z;
                    //if(z<zmin)zmin=z;
                }
        }
        else if(fourcc==0x4d434e52)                         // MCNR
        {
            nextpos = mf.getPos() + 0x1C0; // size fix
        }
        else if(fourcc==0x4d434c51)                         // MCLQ
        {
            // liquid / water level
            //bool haswater;
            char fcc1[5];
            mf.read(fcc1,4);
            flipcc(fcc1);
            fcc1[4]=0;

            if (!strcmp(fcc1,"MCSE"))
            {
                for(int i=0;i<9;i++)
                    for(int j=0;j<9;j++)
                        _chunk->waterlevel[i][j]=-999999; // no liquid/water
            }
            else
            {
                float maxheight;
                mf.read(&maxheight, 4);

                for(int j=0;j<9;j++)
                    for(int i=0;i<9;i++)
                    {
                        mf.read(&h, 4);
                        mf.read(&h, 4);
                        if(h > maxheight)
                            _chunk->waterlevel[i][j]=-999999;
                        else
                            _chunk->waterlevel[i][j]=h;
                    }

                if(chunkflags & 4 || chunkflags & 8)
                    _chunk->flag |=1;
                if(chunkflags & 16)
                    _chunk->flag |=2;

            }
            break;
        }
        else if (fourcc==0x4d434c59)                        // MCLY
        {
            // texture info
            nTextures = (int)size;
        }
        else if (fourcc==0x4d43414c)                        // MCAL
        {
            if (nTextures<=0)
                continue;
        }

        mf.seek(nextpos);
    }
}
예제 #8
0
void OutdoorLightStats::init(MPQFile &f)
{
	float h,m;

	f.seekRelative(4);
	f.read(&h,4);
	f.seekRelative(4);
	f.read(&m,4);
	f.seekRelative(4);
	f.read(&dayIntensity,4);
	
	f.seekRelative(4);
	f.read(&dayColor.x,4);
	f.seekRelative(4);
	f.read(&dayColor.y,4);
	f.seekRelative(4);
	f.read(&dayColor.z,4);

	f.seekRelative(4);
	f.read(&dayDir.x,4);
	f.seekRelative(4);
	f.read(&dayDir.y,4);
	f.seekRelative(4);
	f.read(&dayDir.z,4);

	f.seekRelative(4);
	f.read(&nightIntensity, 4);

	f.seekRelative(4);
	f.read(&nightColor.x,4);
	f.seekRelative(4);
	f.read(&nightColor.y,4);
	f.seekRelative(4);
	f.read(&nightColor.z,4);

	f.seekRelative(4);
	f.read(&nightDir.x,4);
	f.seekRelative(4);
	f.read(&nightDir.y,4);
	f.seekRelative(4);
	f.read(&nightDir.z,4);

	f.seekRelative(4);
	f.read(&ambientIntensity, 4);

	f.seekRelative(4);
	f.read(&ambientColor.x,4);
	f.seekRelative(4);
	f.read(&ambientColor.y,4);
	f.seekRelative(4);
	f.read(&ambientColor.z,4);

	f.seekRelative(4);
	f.read(&fogDepth, 4);
	f.seekRelative(4);
	f.read(&fogIntensity, 4);

	f.seekRelative(4);
	f.read(&fogColor.x,4);
	f.seekRelative(4);
	f.read(&fogColor.y,4);
	f.seekRelative(4);
	f.read(&fogColor.z,4);

    time = (int)h * 60 * 2 + (int)m * 2;

	// HACK: make day & night intensity exclusive; set day intensity to 1.0
	if (dayIntensity > 0) {
		dayIntensity = 1.0f;
		nightIntensity = 0.0f;
	}
}