#include "mapviewer.h" using namespace std; char *GetWordUp(char *line, char *word) { uint i; while (*line == ' ' || *line == '\t' || *line == ',') line++; sscanf(line, "%s", word); while (*line != ' ' && *line != '\t' && *line != ',') line++; for (i = 0; i < strlen(word); i++) { if (word[i] == ',') word[i] = '\0'; if (islower(word[i])) word[i] = toupper(word[i]); } return line; } char *GetQuotedWordUp(char *line, char *word) { uint i; while (*line == ' ' || *line == '\t' || *line == ',') line++; sscanf(line, "\"%s\"", word); while (*line != ' ' && *line != '\t' && *line != ',') line++; for (i = 0; i < strlen(word); i++) { if (word[i] == ',') word[i] = '\0'; if (islower(word[i])) word[i] = toupper(word[i]); } return line; } char *GetFloat(char *line, float *number) { char buffer[24]; line = GetWordUp(line, buffer); *number = atof(buffer); return line; } char *GetInt(char *line, void *number) { char buffer[24]; int *p; p = (int *) number; line = GetWordUp(line, buffer); *p = atoi(buffer); return line; } char *GetRGB(char *line, byte *color) { char buffer[24]; line = GetWordUp(line, buffer); color[0] = (byte) atoi(buffer); line = GetWordUp(line, buffer); color[1] = (byte) atoi(buffer); line = GetWordUp(line, buffer); color[2] = (byte) atoi(buffer); color[3] = 255; return line; } char *GetRGBA(char *line, byte *color) { char buffer[24]; line = GetWordUp(line, buffer); color[0] = (byte) atoi(buffer); line = GetWordUp(line, buffer); color[1] = (byte) atoi(buffer); line = GetWordUp(line, buffer); color[2] = (byte) atoi(buffer); line = GetWordUp(line, buffer); color[3] = (byte) atoi(buffer); return line; } char *ReadConfigLine(FILE *file, char *buffer) { uint i; char Line[512]; readline: if (fgets(Line, 512, file) == NULL) return NULL; while (1) { if (Line[strlen(Line)-1] == 0xd || Line[strlen(Line)-1] == 0xa) Line[strlen(Line)-1] = '\0'; else break; } for (i = 0; i < strlen(Line); i++) if (Line[i] == '#' || Line[i] == ';' || (Line[i] == '/' && Line[i+1] == '/')) { Line[i] = '\0'; break; } if (Line[0] == '\0') goto readline; strcpy(buffer, Line); return buffer; } RpClump *CFileLoader::LoadClump(RwChar *Path) { RwStream *fdff; RpClump *Clump; fdff = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, Path); if (fdff == NULL) { cerr << "Couldn't open " << Path << endl; exit(11); } Clump = RpClumpStreamRead(fdff); RwStreamClose(fdff, NULL); return Clump; } RpClump *CFileLoader::LoadClump(DirEntry *Entry) { RwStream *fdff; RpClump *Clump; fdff = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, Entry->ContFile); if (fdff == NULL) { cerr << "Couldn't open " << Entry->ContFile << endl; exit(11); } RwStreamSeek(fdff, Entry->Start); Clump = RpClumpStreamRead(fdff); RwStreamClose(fdff, NULL); return Clump; } RwTexDictionary *CFileLoader::LoadTexDict(RwChar *Path) { RwStream *ftxd; RwTexDictionary *Dict; ftxd = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, Path); if (ftxd == NULL) { cerr << "Couldn't open " << Path << endl; exit(12); } Dict = RwTexDictionaryStreamRead(ftxd); RwStreamClose(ftxd, NULL); LoadGLTextures(Dict); FreeRwTextures(Dict); return Dict; } RwTexDictionary *CFileLoader::LoadTexDict(DirEntry *Entry) { RwStream *ftxd; RwTexDictionary *Dict; ftxd = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, Entry->ContFile); if (ftxd == NULL) { cerr << "Couldn't open " << Entry->ContFile << endl; exit(12); } RwStreamSeek(ftxd, Entry->Start); Dict = RwTexDictionaryStreamRead(ftxd); RwStreamClose(ftxd, NULL); LoadGLTextures(Dict); FreeRwTextures(Dict); return Dict; } bool CFileLoader::LoadDff(CWorldObj *obj) { DirEntry *Entry; RpClump *Clump; if ((Entry = obj->DffEntry) == NULL) return false; if (Entry->Unloadable) return false; if (Entry->Data == NULL) { VERBOSE << Entry->FileName << " not loaded...loading\n"; Clump = LoadClump(Entry); if (Clump == NULL) { Entry->Unloadable = true; return false; } Entry->Data = Clump; obj->Clump = Clump; // obj->SetClump(Clump); } else { obj->Clump = (RpClump *) Entry->Data; // obj->SetClump((RpClump *) Entry->Data); } Clump = (RpClump *) Entry->Data; obj->BSphere[0] = Clump->Geo[0].BoundingSphere.position.x; obj->BSphere[1] = Clump->Geo[0].BoundingSphere.position.y; obj->BSphere[2] = Clump->Geo[0].BoundingSphere.position.z; obj->BSphere[3] = Clump->Geo[0].BoundingSphere.radius; return true; } bool CFileLoader::LoadTxd(CWorldObj *obj) { DirEntry *Entry, *ParEntry; RwTexDictionary *Dict, *ParDict; if ((Entry = obj->TxdEntry) == NULL) return false; if (Entry->Data == NULL) { VERBOSE << Entry->FileName << " not loaded...loading\n"; Dict = LoadTexDict(Entry); Entry->Data = Dict; obj->TexDict = Dict; Dict->Parent = NULL; ParEntry = Entry->Parent; if (ParEntry != NULL) { if (ParEntry->Data == NULL) { VERBOSE << ParEntry->FileName << " not loaded...loading\n"; ParDict = LoadTexDict(ParEntry); ParEntry->Data = ParDict; Dict->Parent = ParDict; ParDict->Parent = NULL; } else { Dict->Parent = (RwTexDictionary *) ParEntry->Data; } } } else { obj->TexDict = (RwTexDictionary *) Entry->Data; } return true; } void CFileLoader::UnloadWorldObj(CWorldObj *obj) { // int i; RpClumpDestroy(obj->Clump); obj->Clump = NULL; obj->DffEntry->Data = NULL; if (obj->TxdEntry != NULL) { obj->TxdEntry->RefCount--; // cout << obj->TxdEntry->RefCount << " " << obj->TextureName << endl; if (obj->TxdEntry->RefCount == 0) { VERBOSE << obj->TextureName << " not used...\n"; /* for (i = 0; i < obj->TexDict->numTextures; i++) glDeleteTextures(1, (GLuint *) &obj->TexDict->texture[i].TexID); RwTexDictionaryDestroy(obj->TexDict); obj->TexDict = NULL; obj->DffEntry->Data = NULL; */ // cout << "Could unload " << obj->TextureName << endl; } } } void CFileLoader::FreeRwTextures(RwTexDictionary *TexDict) { RwUInt32 i; for (i = 0; i < TexDict->numTextures; i++) { delete[] TexDict->texture[i].Data; delete[] TexDict->texture[i].Data_a; TexDict->texture[i].Data = NULL; TexDict->texture[i].Data_a = NULL; } } void CFileLoader::LoadGLTextures(RwTexDictionary *TexDict) { RwUInt32 i; RwTexture *tex; GLuint *texid; int size; texid = new GLuint[TexDict->numTextures]; glGenTextures(TexDict->numTextures, texid); for (i = 0; i < TexDict->numTextures; i++) { tex = &TexDict->texture[i]; glBindTexture(GL_TEXTURE_2D, texid[i]); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); if (tex->depth == 32) { if (tex->reversed) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex->width, tex->height, 0, GL_BGRA, GL_UNSIGNED_BYTE, tex->Data_a); else glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex->width, tex->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex->Data_a); } else if (tex->depth == 16) { // cout << "compression " << tex->Compression << endl; if (tex->Compression == 1) { size = tex->width*tex->height/2; glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, tex->width, tex->height, 0, size, tex->Data_a); } else if (tex->Compression == 3) { size = tex->width*tex->height; glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, tex->width, tex->height, 0, size, tex->Data_a); } else { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex->width, tex->height, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, tex->Data_a); } } else { cerr << "Can't handle non 16bit or 32bit textures " << tex->depth << i << "\n"; exit(1); } tex->TexID = texid[i]; } } FILE *CFileLoader::OpenFile(DirEntry *Entry) { FILE *file; if (!(file = fopen(Entry->ContFile, "rb"))) exiterror("Couldn't open file ", Entry->ContFile); fseek(file, Entry->Start, SEEK_SET); return file; }