/* Blake Stone strings are stored in text chunks. They're referenced by an * index. Strings are stored separated by ^XX at the end of a line. */ void Language::SetupBlakeStrings(const char* lumpname, const char* prefix) { int lumpnum = Wads.CheckNumForName(lumpname); if(lumpnum == -1) return; FMemLump wadLump = Wads.ReadLump(lumpnum); unsigned int num = 1; // Start at prefix_1 unsigned int pos = 0; unsigned int start = 0; const char* data = reinterpret_cast<const char*>(wadLump.GetMem()); static const WORD endToken = ('X'<<8)|'X'; // Since both chars are the same this should be endian safe while(pos+2 < wadLump.GetSize()) { if(data[pos] == '^' && *(WORD*)(data+pos+1) == endToken) { FString name; FString str(data+start, pos-start); name.Format("%s%d", prefix, num++); strings[name] = str; pos += 3; while((data[pos] == '\n' || data[pos] == '\r') && pos < wadLump.GetSize()) ++pos; start = pos; } else ++pos; } }
void FTextureManager::InitPalettedVersions() { int lump, lastlump = 0; PalettedVersions.Clear(); while ((lump = Wads.FindLump("PALVERS", &lastlump)) != -1) { FMemLump data = Wads.ReadLump(lump); Scanner sc((const char*)data.GetMem(), data.GetSize()); while (sc.GetNextToken()) { FTextureID pic1 = CheckForTexture(sc->str, FTexture::TEX_Any); if (!pic1.isValid()) { sc.ScriptMessage(Scanner::WARNING, "Unknown texture %s to replace", sc->str.GetChars()); } sc.GetNextToken(); FTextureID pic2 = CheckForTexture(sc->str, FTexture::TEX_Any); if (!pic2.isValid()) { sc.ScriptMessage(Scanner::WARNING, "Unknown texture %s to use as replacement", sc->str.GetChars()); } if (pic1.isValid() && pic2.isValid()) { PalettedVersions[pic1.GetIndex()] = pic2.GetIndex(); } } } }
void FTextureManager::LoadTextureDefs(int wadnum, const char *lumpname) { int remapLump, lastLump; char src[9]; //bool is32bit; //int width, height; //int type, mode; TArray<FTextureID> tlist; lastLump = 0; src[8] = '\0'; while ((remapLump = Wads.FindLump(lumpname, &lastLump)) != -1) { if (Wads.GetLumpFile(remapLump) == wadnum) { FMemLump lmp = Wads.ReadLump(remapLump); Scanner sc((const char*)lmp.GetMem(), lmp.GetSize()); sc.SetScriptIdentifier(Wads.GetLumpFullName(remapLump)); while (sc.CheckToken(TK_Identifier)) { /*if (sc.Compare("remap")) // remap an existing texture { sc.MustGetString(); // allow selection by type if (sc.Compare("wall")) type=FTexture::TEX_Wall, mode=FTextureManager::TEXMAN_Overridable; else if (sc.Compare("flat")) type=FTexture::TEX_Flat, mode=FTextureManager::TEXMAN_Overridable; else if (sc.Compare("sprite")) type=FTexture::TEX_Sprite, mode=0; else type = FTexture::TEX_Any, mode = 0; if (type != FTexture::TEX_Any) sc.MustGetString(); sc.String[8]=0; tlist.Clear(); int amount = ListTextures(sc.String, tlist); FName texname = sc.String; sc.MustGetString(); int lumpnum = Wads.CheckNumForFullName(sc.String, true, ns_patches); if (lumpnum == -1) lumpnum = Wads.CheckNumForFullName(sc.String, true, ns_graphics); if (tlist.Size() == 0) { Printf("Attempting to remap non-existent texture %s to %s\n", texname.GetChars(), sc.String); } else if (lumpnum == -1) { Printf("Attempting to remap texture %s to non-existent lump %s\n", texname.GetChars(), sc.String); } else { for(unsigned int i = 0; i < tlist.Size(); i++) { FTexture * oldtex = Textures[tlist[i].GetIndex()].Texture; int sl; // only replace matching types. For sprites also replace any MiscPatches // based on the same lump. These can be created for icons. if (oldtex->UseType == type || type == FTexture::TEX_Any || (mode == TEXMAN_Overridable && oldtex->UseType == FTexture::TEX_Override) || (type == FTexture::TEX_Sprite && oldtex->UseType == FTexture::TEX_MiscPatch && (sl=oldtex->GetSourceLump()) >= 0 && Wads.GetLumpNamespace(sl) == ns_sprites) ) { FTexture * newtex = FTexture::CreateTexture (lumpnum, FTexture::TEX_Any); if (newtex != NULL) { // Replace the entire texture and adjust the scaling and offset factors. newtex->bWorldPanning = true; newtex->SetScaledSize(oldtex->GetScaledWidth(), oldtex->GetScaledHeight()); newtex->LeftOffset = FixedMul(oldtex->GetScaledLeftOffset(), newtex->xScale); newtex->TopOffset = FixedMul(oldtex->GetScaledTopOffset(), newtex->yScale); ReplaceTexture(tlist[i], newtex, true); } } } } } else if (sc.Compare("define")) // define a new "fake" texture { sc.GetString(); FString base = ExtractFileBase(sc.String, false); if (!base.IsEmpty()) { strncpy(src, base, 8); int lumpnum = Wads.CheckNumForFullName(sc.String, true, ns_patches); if (lumpnum == -1) lumpnum = Wads.CheckNumForFullName(sc.String, true, ns_graphics); sc.GetString(); is32bit = !!sc.Compare("force32bit"); if (!is32bit) sc.UnGet(); sc.GetNumber(); width = sc.Number; sc.GetNumber(); height = sc.Number; if (lumpnum>=0) { FTexture *newtex = FTexture::CreateTexture(lumpnum, FTexture::TEX_Override); if (newtex != NULL) { // Replace the entire texture and adjust the scaling and offset factors. newtex->bWorldPanning = true; newtex->SetScaledSize(width, height); memcpy(newtex->Name, src, sizeof(newtex->Name)); FTextureID oldtex = TexMan.CheckForTexture(src, FTexture::TEX_MiscPatch); if (oldtex.isValid()) { ReplaceTexture(oldtex, newtex, true); newtex->UseType = FTexture::TEX_Override; } else AddTexture(newtex); } } } //else Printf("Unable to define hires texture '%s'\n", tex->Name); } else */if (sc->str.CompareNoCase("texture") == 0) { ParseXTexture(sc, FTexture::TEX_Override); } else if (sc->str.CompareNoCase("sprite") == 0) { ParseXTexture(sc, FTexture::TEX_Sprite); } else if (sc->str.CompareNoCase("walltexture") == 0) { ParseXTexture(sc, FTexture::TEX_Wall); } else if (sc->str.CompareNoCase("flat") == 0) { ParseXTexture(sc, FTexture::TEX_Flat); } else if (sc->str.CompareNoCase("graphic") == 0) { ParseXTexture(sc, FTexture::TEX_MiscPatch); } else if(sc->str.CompareNoCase("artindex") == 0) { sc.MustGetToken(TK_IntConst); int index = sc->number; sc.MustGetToken(','); sc.MustGetToken(TK_StringConst); if(index > 255) sc.ScriptMessage(Scanner::ERROR, "Can't assign art index over 255.\n"); artIndex[index].textureName = sc->str; } else { sc.ScriptMessage(Scanner::ERROR, "Texture definition expected, found '%s'", sc->str.GetChars()); } } } } }
void Language::ReadLump(int lump, const char* language) { FMemLump wadLump = Wads.ReadLump(lump); Scanner sc((const char*)(wadLump.GetMem()), wadLump.GetSize()); sc.SetScriptIdentifier(Wads.GetLumpFullName(lump)); int token = TK_NoToken; bool skip = false; bool noReplace = false; while(sc.GetNextToken()) { token = sc->token; if(token == '[') { // match with language sc.MustGetToken(TK_Identifier); if(sc->str.Compare(language) != 0) skip = true; else { skip = false; noReplace = false; } if(sc.CheckToken(TK_Identifier)) { if(sc->str.Compare("default") == 0) { // if not the correct language, go in no replace mode. if(skip) { skip = false; noReplace = true; } } else { printf("Unexpected identifier '%s'\n", sc->str.GetChars()); exit(0); } } sc.MustGetToken(']'); } else if(token == TK_Identifier) { FName index = sc->str; sc.MustGetToken('='); sc.MustGetToken(TK_StringConst); if(!skip) { if(!noReplace || (noReplace && strings.CheckKey(index) == NULL)) strings[index] = sc->str; } sc.MustGetToken(';'); } else { sc.ScriptMessage(Scanner::ERROR, "Unexpected token.\n"); exit(0); } } }