int CAICallback::GetFileSize (const char *name) { CFileHandler fh (name); if (!fh.FileExists ()) return -1; return fh.FileSize(); }
int CAICallback::GetFileSize (const char *filename, const char* modes) { CFileHandler fh (filename, modes); if (!fh.FileExists ()) return -1; return fh.FileSize(); }
bool CAICallback::ReadFile (const char *name, void *buffer, int bufferLength) { CFileHandler fh (name); int fs; if (!fh.FileExists() || bufferLength < (fs = fh.FileSize())) return false; fh.Read (buffer, fs); return true; }
CCobFile::CCobFile(CFileHandler &in, string name) { char *cobdata = NULL; this->name = name; //Figure out size needed and allocate it int size = in.FileSize(); // Handle errors (this is fairly fatal..) if (size < 0) { logOutput.Print("Could not find script for unit %s", name.c_str()); exit(0); } cobdata = new char[size]; //Read the entire thing, we will need it in.Read(cobdata, size); //Time to parse COBHeader ch; READ_COBHEADER(ch,cobdata); for (int i = 0; i < ch.NumberOfScripts; ++i) { int ofs; ofs = *(int *)&cobdata[ch.OffsetToScriptNameOffsetArray + i * 4]; ofs = swabdword(ofs); string s = &cobdata[ofs]; scriptNames.push_back(s); ofs = *(int *)&cobdata[ch.OffsetToScriptCodeIndexArray + i * 4]; ofs = swabdword(ofs); scriptOffsets.push_back(ofs); } //Check for zero-length scripts for (int i = 0; i < ch.NumberOfScripts - 1; ++i) { scriptLengths.push_back(scriptOffsets[i + 1] - scriptOffsets[i]); } scriptLengths.push_back(ch.TotalScriptLen - scriptOffsets[ch.NumberOfScripts - 1]); for (int i = 0; i < ch.NumberOfPieces; ++i) { int ofs; ofs = *(int *)&cobdata[ch.OffsetToPieceNameOffsetArray + i * 4]; ofs = swabdword(ofs); string s = StringToLower(&cobdata[ofs]); pieceNames.push_back(s); } int code_octets = size - ch.OffsetToScriptCode; int code_ints = (code_octets) / 4 + 4; code = new int[code_ints]; memcpy(code, &cobdata[ch.OffsetToScriptCode], code_octets); for (int i = 0; i < code_ints; i++) { code[i] = swabdword(code[i]); } numStaticVars = ch.NumberOfStaticVars; // If this is a TA:K script, read the sound names if (ch.VersionSignature == 6) { for (int i = 0; i < ch.NumberOfSounds; ++i) { int ofs; ofs = *(int *)&cobdata[ch.OffsetToSoundNameArray + i * 4]; /* TODO This probably isn't correct. */ ofs = swabdword(ofs); string s = &cobdata[ofs]; // Load the wave file and store the ID for future use s = "sounds/" + s + ".wav"; sounds.push_back(sound->GetWaveId(s)); } } delete[] cobdata; //Create a reverse mapping (name->int) for (unsigned int i = 0; i < scriptNames.size(); ++i) { scriptMap[scriptNames[i]] = i; } //Map common function names to indicies scriptIndex.resize(COBFN_Last + COB_MaxWeapons * 5); scriptIndex[COBFN_Create] = getFunctionId("Create"); scriptIndex[COBFN_StartMoving] = getFunctionId("StartMoving"); scriptIndex[COBFN_StopMoving] = getFunctionId("StopMoving"); scriptIndex[COBFN_Activate] = getFunctionId("Activate"); scriptIndex[COBFN_Killed] = getFunctionId("Killed"); scriptIndex[COBFN_Deactivate] = getFunctionId("Deactivate"); scriptIndex[COBFN_SetDirection] = getFunctionId("SetDirection"); scriptIndex[COBFN_SetSpeed] = getFunctionId("SetSpeed"); scriptIndex[COBFN_RockUnit] = getFunctionId("RockUnit"); scriptIndex[COBFN_HitByWeapon] = getFunctionId("HitByWeapon"); scriptIndex[COBFN_MoveRate0] = getFunctionId("MoveRate0"); scriptIndex[COBFN_MoveRate1] = getFunctionId("MoveRate1"); scriptIndex[COBFN_MoveRate2] = getFunctionId("MoveRate2"); scriptIndex[COBFN_MoveRate3] = getFunctionId("MoveRate3"); scriptIndex[COBFN_SetSFXOccupy] = getFunctionId("setSFXoccupy"); // Also add the weapon aiming stuff for (int i = 0; i < COB_MaxWeapons; ++i) { char buf[15]; sprintf(buf, "Weapon%d", i + 1); string weapon(buf); sprintf(buf, "%d", i + 1); string weap(buf); scriptIndex[COBFN_QueryPrimary + i] = getFunctionId("Query" + weapon); scriptIndex[COBFN_AimPrimary + i] = getFunctionId("Aim" + weapon); scriptIndex[COBFN_AimFromPrimary + i] = getFunctionId("AimFrom" + weapon); scriptIndex[COBFN_FirePrimary + i] = getFunctionId("Fire" + weapon); scriptIndex[COBFN_EndBurst + i] = getFunctionId("EndBurst" + weap); // If new-naming functions are not found, we need to support the old naming scheme if (i > 2) continue; switch (i) { case 0: weapon = "Primary"; break; case 1: weapon = "Secondary"; break; case 2: weapon = "Tertiary"; break; } if (scriptIndex[COBFN_QueryPrimary + i] == -1) scriptIndex[COBFN_QueryPrimary + i] = getFunctionId("Query" + weapon); if (scriptIndex[COBFN_AimPrimary + i] == -1) scriptIndex[COBFN_AimPrimary + i] = getFunctionId("Aim" + weapon); if (scriptIndex[COBFN_AimFromPrimary + i] == -1) scriptIndex[COBFN_AimFromPrimary + i] = getFunctionId("AimFrom" + weapon); if (scriptIndex[COBFN_FirePrimary + i] == -1) scriptIndex[COBFN_FirePrimary + i] = getFunctionId("Fire" + weapon); } }
CglFont::CglFont(const std::string& fontfile, int size, int _outlinewidth, float _outlineweight): fontSize(size), fontPath(fontfile), outlineWidth(_outlinewidth), outlineWeight(_outlineweight), inBeginEnd(false) { if (size<=0) size = 14; const float invSize = 1.0f / size; const float normScale = invSize / 64.0f; FT_Library library; FT_Face face; //! initialize Freetype2 library FT_Error error = FT_Init_FreeType(&library); if (error) { string msg = "FT_Init_FreeType failed:"; msg += GetFTError(error); throw std::runtime_error(msg); } //! load font via VFS CFileHandler* f = new CFileHandler(fontPath); if (!f->FileExists()) { //! check in 'fonts/', too if (fontPath.substr(0, 6) != "fonts/") { delete f; fontPath = "fonts/" + fontPath; f = new CFileHandler(fontPath); } if (!f->FileExists()) { delete f; FT_Done_FreeType(library); throw content_error("Couldn't find font '" + fontfile + "'."); } } int filesize = f->FileSize(); FT_Byte* buf = new FT_Byte[filesize]; f->Read(buf,filesize); delete f; //! create face error = FT_New_Memory_Face(library, buf, filesize, 0, &face); if (error) { FT_Done_FreeType(library); delete[] buf; string msg = fontfile + ": FT_New_Face failed: "; msg += GetFTError(error); throw content_error(msg); } //! set render size error = FT_Set_Pixel_Sizes(face, 0, size); if (error) { FT_Done_Face(face); FT_Done_FreeType(library); delete[] buf; string msg = fontfile + ": FT_Set_Pixel_Sizes failed: "; msg += GetFTError(error); throw content_error(msg); } //! setup character range charstart = 32; charend = 254; //! char 255 = colorcode chars = (charend - charstart) + 1; //! get font information fontFamily = face->family_name; fontStyle = face->style_name; //! font's descender & height (in pixels) fontDescender = normScale * FT_MulFix(face->descender, face->size->metrics.y_scale); //lineHeight = invSize * (FT_MulFix(face->height, face->size->metrics.y_scale) / 64.0f); //lineHeight = invSize * math::ceil(FT_MulFix(face->height, face->size->metrics.y_scale) / 64.0f); lineHeight = face->height / face->units_per_EM; //lineHeight = invSize * face->size->metrics.height / 64.0f; if (lineHeight<=0.0f) { lineHeight = 1.25 * invSize * (face->bbox.yMax - face->bbox.yMin); } //! used to create the glyph textureatlas CFontTextureRenderer texRenderer(outlineWidth, outlineWeight); for (unsigned int i = charstart; i <= charend; i++) { GlyphInfo* g = &glyphs[i]; //! translate WinLatin (codepage-1252) to Unicode (used by freetype) int unicode = WinLatinToUnicode(i); //! convert to an anti-aliased bitmap error = FT_Load_Char(face, unicode, FT_LOAD_RENDER); if ( error ) { continue; } FT_GlyphSlot slot = face->glyph; //! Keep sign! const float ybearing = slot->metrics.horiBearingY * normScale; const float xbearing = slot->metrics.horiBearingX * normScale; g->advance = slot->advance.x * normScale; g->height = slot->metrics.height * normScale; g->descender = ybearing - g->height; g->x0 = xbearing; g->y0 = ybearing - fontDescender; g->x1 = (xbearing + slot->metrics.width * normScale); g->y1 = g->y0 - g->height; texRenderer.AddGlyph(i, slot->bitmap.width, slot->bitmap.rows, slot->bitmap.buffer, slot->bitmap.pitch); } //! create font atlas texture fontTexture = texRenderer.CreateTexture(); texWidth = texRenderer.texWidth; texHeight = texRenderer.texHeight; //! get glyph's uv coords in the atlas for (unsigned int i = charstart; i <= charend; i++) { texRenderer.GetGlyph(i,&glyphs[i]); } //! generate kerning tables for (unsigned int i = charstart; i <= charend; i++) { GlyphInfo& g = glyphs[i]; int unicode = WinLatinToUnicode(i); FT_UInt left_glyph = FT_Get_Char_Index(face, unicode); for (unsigned int j = 0; j <= 255; j++) { unicode = WinLatinToUnicode(j); FT_UInt right_glyph = FT_Get_Char_Index(face, unicode); FT_Vector kerning; kerning.x = kerning.y = 0.0f; FT_Get_Kerning(face, left_glyph, right_glyph, FT_KERNING_DEFAULT, &kerning); g.kerning[j] = g.advance + normScale * static_cast<float>(kerning.x); } } //! initialize null char GlyphInfo& g = glyphs[0]; g.height = g.descender = g.advance = 0.0f; for (unsigned int j = 0; j <= 255; j++) { g.kerning[j] = 0.0f; } FT_Done_Face(face); FT_Done_FreeType(library); delete[] buf; textColor = white; outlineColor = darkOutline; }