Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cmath>
- #include <limits>
- #include <string>
- #include <cstdint>
- #include <cstdarg>
- template<class T>
- struct SComplex
- {
- typedef T value_type;
- value_type f;
- // TODO
- // Must make those comparisions better
- bool operator==(const SComplex& sz) const
- {
- const T epsilon = std::numeric_limits<T>::epsilon();
- return std::abs(this->f - sz.f) <= 0.01;
- }
- bool operator<(const SComplex& sz) const
- {
- const T epsilon = std::numeric_limits<T>::epsilon();
- return ( ((this->f - sz.f) < epsilon) && (fabs(this->f - sz.f) > epsilon) );
- }
- };
- template<size_t N>
- struct SVector
- {
- SComplex<float> c[N];
- template<class Functor>
- bool comp(const SVector& b) const
- {
- Functor comparer;
- for(size_t i = 0; i < N; ++i)
- {
- if(!(comparer(c[i], b.c[i])))
- return false;
- }
- return true;
- }
- bool operator==(const SVector& b) const
- {
- for(size_t i = 0; i < N; ++i)
- {
- if(!(c[i] == b.c[i])) return false;
- }
- return true;
- }
- SComplex<float>& operator[](size_t i)
- {
- return c[i];
- }
- const SComplex<float>& operator[](size_t i) const
- {
- return c[i];
- }
- };
- static_assert(sizeof(SComplex<float>) == sizeof(float), "Wrong size of SComplex");
- /* typedef the wrappers */
- typedef uint32_t hash;
- typedef uint32_t uhash; /* upper case hash */
- typedef SString<32> string32;
- typedef SComplex<float> complex;
- typedef SVector<2> vec2;
- typedef SVector<3> vec3;
- typedef SVector<4> vec4;
- typedef int integer;
- typedef unsigned int flags;
- typedef unsigned int obj_id;
- #define OPI(item, op) (a.item op b.item)
- #define EQ(item) OPI(item, ==)
- #define LE(item) OPI(item, <)
- struct SDataIPL_INST_OBJECT
- {
- obj_id id;
- // won't use modelname because it makes no difference
- integer interior;
- vec3 pos;
- vec4 rot;
- /* used by the parser, not to be used in comparisions */
- integer lod;
- bool operator==(const SDataIPL_INST_OBJECT& b) const
- {
- const SDataIPL_INST_OBJECT& a = *this;
- return EQ(id) && EQ(interior) && EQ(pos) && EQ(rot);
- }
- };
- struct SDataIPL_INST
- {
- typedef SDataIPL_INST_OBJECT SObject;
- SObject obj;
- SObject lod;
- bool has_lod;
- bool operator==(const SDataIPL_INST& b) const
- {
- const SDataIPL_INST& a = *this;
- if(EQ(obj) && EQ(has_lod))
- {
- if(has_lod) return EQ(lod);
- return true;
- }
- return false;
- }
- };
- /*
- * ParseConfigLine
- * Parses @str (modifying it's content) as if it is a Grand Theft Auto config line.
- * Grand Theft Auto config lines use '#' and ';' as comments and they ignore ',' and spaces.
- * So, if @str is " a, b, c, d, e ; cool " the output is "a, b, c, d, e "
- */
- inline char* ParseConfigLine(char* str)
- {
- char* result = str;
- bool bTrim = true;
- //printf("\n>>p> %s\n", str);
- if(result)
- {
- /* Iterate on string making apropiate changes */
- for(char* p = result; *p; ++p)
- {
- if(*p <= ' ' || *p == ',')
- {
- *p = ' ';
- if(bTrim) result = p+1;
- }
- else if(*p == '#' || *p == ';')
- {
- /* Comments, end line here */
- *p = 0;
- break;
- }
- else
- bTrim = false; /* First non space character, no more trim */
- }
- }
- return result;
- }
- }
- }
- /*
- * ScanConfigLine
- * Scans the GTA configuration line @str with format @fmt
- * Retruns true if the scan sucessfully acquieres @count arguments, returns false otherwise
- */
- inline bool ScanConfigLine(int count, const char* str, const char* fmt, ...)
- {
- va_list va; va_start(va, fmt);
- int result = vsscanf(str, fmt, va);
- va_end(va);
- return (result == count);
- }
- #include <vector>
- typedef std::vector<SDataIPL_INST> VectorIPL;
- static VectorIPL newIPL;
- static VectorIPL gameIPL;
- static const char* instFormat = "%d %s %d %g %g %g %g %g %g %g %d \n";
- static const int instCount = 11;
- void ReadIPL(const char* filename, VectorIPL& ipl)
- {
- char *line, dummy[64], buf[256];
- if(FILE* f = fopen(filename, "r"))
- {
- std::vector<SDataIPL_INST::SObject> lines;
- fgets(buf, sizeof(buf), f);
- while(line = ParseConfigLine(fgets(buf, sizeof(buf), f)))
- {
- lines.resize(lines.size() + 1);
- auto& inst = lines.back();
- if(!ScanConfigLine(instCount, line, instFormat,
- &inst.id, dummy, &inst.interior,
- &inst.pos[0].f, &inst.pos[1].f, &inst.pos[2].f,
- &inst.rot[0].f, &inst.rot[1].f, &inst.rot[2].f, &inst.rot[3].f,
- &inst.lod))
- {
- if(line[0] != 'e') { puts("end fail"); throw 0; }
- lines.resize(lines.size() - 1);
- break;
- }
- }
- for(auto& line : lines)
- {
- if(line.lod >= 0)
- {
- lines[line.lod].lod = -2;
- }
- }
- for(auto& line : lines)
- {
- if(line.lod != -2)
- {
- ipl.push_back( SDataIPL_INST() );
- auto& item = ipl.back();
- item.obj = line;
- if(item.has_lod = (line.lod >= 0))
- {
- item.lod = lines[line.lod];
- }
- }
- }
- fclose(f);
- return;
- }
- puts("fopen fail");
- throw 0;
- }
- #include <algorithm>
- int main()
- {
- ReadIPL("new.ipl", newIPL);
- ReadIPL("game.ipl", gameIPL);
- puts("Readen");
- if(gameIPL.size() != newIPL.size())
- puts("IPL size wrong");
- else
- printf("sizecmp: %d == %d\n", gameIPL.size(), newIPL.size());
- size_t nNotFound = 0;
- for(auto& inst : gameIPL)
- {
- if(std::find(newIPL.begin(), newIPL.end(), inst) == newIPL.end())
- {
- printf("\n>\n");
- auto print = [](const SDataIPL_INST_OBJECT& inst)
- {
- printf("%d dummy %d %f %f %f %f %f %f %f %d\n",
- inst.id, inst.interior,
- inst.pos[0].f, inst.pos[1].f, inst.pos[2].f,
- inst.rot[0].f, inst.rot[1].f, inst.rot[2].f, inst.rot[3].f,
- inst.lod);
- };
- print(inst.obj);
- if(inst.has_lod) print(inst.lod);
- printf("<\n");
- ++nNotFound;
- }
- }
- if(nNotFound > 0)
- {
- printf("could not find %d items\n", nNotFound);
- }
- else puts("everything okay");
- puts("done");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement