From 2d92d39f05db8fb70e87fc9f68986edb0454cf30 Mon Sep 17 00:00:00 2001 From: Nicolay Korslund Date: Wed, 6 Jan 2010 12:28:37 +0100 Subject: [PATCH] Started porting NIF records from D. --- nif/controlled.h | 57 ++++++++++++++++++++++++++++ nif/extra.h | 46 ++++++++++++++++++++++ nif/nif_file.cpp | 18 +++++---- nif/nif_file.h | 16 +++++++- nif/node.h | 47 +++++++++++++++++++++++ nif/record.h | 8 +++- nif/record_ptr.h | 88 +++++++++++++++++++++++++++++++++++++++++++ nif/tests/niftool.cpp | 1 + 8 files changed, 271 insertions(+), 10 deletions(-) create mode 100644 nif/controlled.h create mode 100644 nif/extra.h create mode 100644 nif/node.h create mode 100644 nif/record_ptr.h diff --git a/nif/controlled.h b/nif/controlled.h new file mode 100644 index 0000000000..c5397993e3 --- /dev/null +++ b/nif/controlled.h @@ -0,0 +1,57 @@ +/* + OpenMW - The completely unofficial reimplementation of Morrowind + Copyright (C) 2008-2010 Nicolay Korslund + Email: < korslund@gmail.com > + WWW: http://openmw.sourceforge.net/ + + This file (controlled.h) is part of the OpenMW package. + + OpenMW is distributed as free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License + version 3, as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + version 3 along with this program. If not, see + http://www.gnu.org/licenses/ . + + */ + +#ifndef _NIF_CONTROLLED_H_ +#define _NIF_CONTROLLED_H_ + +#include "extra.h" + +namespace Nif +{ + +/// Anything that has a controller +struct Controlled : Extra +{ + ControllerPtr controller; + + void read(NIFFile *nif) + { + Extra::read(nif); + controller.read(nif); + } +}; + +/// Has name, extra-data and controller +struct Named : Controlled +{ + SString name; + + void read(NIFFile *nif) + { + name = nif->getString(); + Controlled::read(nif); + } +}; + +} // Namespace +#endif diff --git a/nif/extra.h b/nif/extra.h new file mode 100644 index 0000000000..57ea666349 --- /dev/null +++ b/nif/extra.h @@ -0,0 +1,46 @@ +/* + OpenMW - The completely unofficial reimplementation of Morrowind + Copyright (C) 2008-2010 Nicolay Korslund + Email: < korslund@gmail.com > + WWW: http://openmw.sourceforge.net/ + + This file (extra.h) is part of the OpenMW package. + + OpenMW is distributed as free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License + version 3, as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + version 3 along with this program. If not, see + http://www.gnu.org/licenses/ . + + */ + +#ifndef _NIF_EXTRA_H_ +#define _NIF_EXTRA_H_ + +#include "record.h" +#include "nif_file.h" +#include "record_ptr.h" + +namespace Nif +{ + +/** A record that can have extra data. The extra data objects + themselves decend from the Extra class, and all the extra data + connected to an object form a linked list +*/ +struct Extra : Record +{ + ExtraPtr extra; + + void read(NIFFile *nif) { extra.read(nif); } +}; + +} // Namespace +#endif diff --git a/nif/nif_file.cpp b/nif/nif_file.cpp index a184965504..fadd64728b 100644 --- a/nif/nif_file.cpp +++ b/nif/nif_file.cpp @@ -22,11 +22,16 @@ */ #include "nif_file.h" - +#include "record.h" #include "../tools/stringops.h" +#include "extra.h" +#include "controlled.h" +#include "node.h" + #include using namespace std; +using namespace Nif; void NIFFile::parse() { @@ -50,12 +55,11 @@ void NIFFile::parse() cout << i << ": " << rec.toString() << endl; - NifRecord *r = NULL; - - if(rec == "NiNode") cout << " got a node!\n"; - - if(r) r->read(this); - else cout << "No record was created\n"; + Node r; + r.read(this); + cout << r.name.toString() << endl; + cout << r.extra.getIndex() << endl; + cout << r.controller.getIndex() << endl; break; } diff --git a/nif/nif_file.h b/nif/nif_file.h index 0931312465..3152bd0763 100644 --- a/nif/nif_file.h +++ b/nif/nif_file.h @@ -32,11 +32,15 @@ #include #include +#include #include "record.h" using namespace Mangle::Stream; +namespace Nif +{ + class NIFFile { enum NIFVersion @@ -54,7 +58,7 @@ class NIFFile std::string filename; /// Record list - std::vector records; + std::vector records; /// Used for error handling void fail(const std::string &msg) @@ -88,6 +92,14 @@ class NIFFile parse(); } + Record *getRecord(int index) + { + assert(index >= 0 && index < records.size()); + Record *res = records[index]; + assert(res != NULL); + return res; + } + /* ************************************************ @@ -110,4 +122,6 @@ class NIFFile const char *getString(int size) { return (const char*)inp->getPtr(size); } }; + +} // Namespace #endif diff --git a/nif/node.h b/nif/node.h new file mode 100644 index 0000000000..6434555d36 --- /dev/null +++ b/nif/node.h @@ -0,0 +1,47 @@ +/* + OpenMW - The completely unofficial reimplementation of Morrowind + Copyright (C) 2008-2010 Nicolay Korslund + Email: < korslund@gmail.com > + WWW: http://openmw.sourceforge.net/ + + This file (node.h) is part of the OpenMW package. + + OpenMW is distributed as free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License + version 3, as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + version 3 along with this program. If not, see + http://www.gnu.org/licenses/ . + + */ + +#ifndef _NIF_NODE_H_ +#define _NIF_NODE_H_ + +#include "controlled.h" + +namespace Nif +{ + +/** A Node is an object that's part of the main NIF tree. It has + parent node (unless it's the root), and transformation (location + and rotation) relative to it's parent. + */ +struct Node : Named +{ + // Not done + + void read(NIFFile *nif) + { + Named::read(nif); + } +}; + +} // Namespace +#endif diff --git a/nif/record.h b/nif/record.h index 52fbd030c4..0fb64ed3a9 100644 --- a/nif/record.h +++ b/nif/record.h @@ -24,11 +24,14 @@ #ifndef _NIF_RECORD_H_ #define _NIF_RECORD_H_ +namespace Nif +{ + class NIFFile; -class NifRecord +/// Base class for all records +struct Record { - public: virtual void read(NIFFile *nif) = 0; /* @@ -39,4 +42,5 @@ class NifRecord */ }; +} // Namespace #endif diff --git a/nif/record_ptr.h b/nif/record_ptr.h new file mode 100644 index 0000000000..998c4fc48c --- /dev/null +++ b/nif/record_ptr.h @@ -0,0 +1,88 @@ +/* + OpenMW - The completely unofficial reimplementation of Morrowind + Copyright (C) 2008-2010 Nicolay Korslund + Email: < korslund@gmail.com > + WWW: http://openmw.sourceforge.net/ + + This file (record_ptr.h) is part of the OpenMW package. + + OpenMW is distributed as free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License + version 3, as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + version 3 along with this program. If not, see + http://www.gnu.org/licenses/ . + + */ + +#ifndef _NIF_RECORD_PTR_H_ +#define _NIF_RECORD_PTR_H_ + +#include "nif_file.h" + +namespace Nif +{ +template +class RecordPtrT +{ + int index; + X* ptr; + NIFFile *nif; + + public: + + RecordPtrT() : index(-2), ptr(NULL) {} + + /// Read the index from the nif + void read(NIFFile *_nif) + { + // Can only read the index once + assert(index == -2); + + // Store the NIFFile pointer for later + nif = _nif; + + // And the index, of course + index = nif->getInt(); + } + + /// Look up the actual object from the index + X* operator->() + { + // Have we found the pointer already? + if(ptr == NULL) + { + // Get the record + assert(index >= 0); + Record *r = nif->getRecord(index); + + // And cast it + ptr = dynamic_cast(r); + assert(ptr != NULL); + } + return ptr; + } + + /// Pointers are allowed to be empty + bool empty() { return index == -1; } + + int getIndex() { return index; } +}; + + +class Extra; +class Controller; +class Node; + +typedef RecordPtrT ExtraPtr; +typedef RecordPtrT ControllerPtr; +typedef RecordPtrT NodePtr; + +} // Namespace +#endif diff --git a/nif/tests/niftool.cpp b/nif/tests/niftool.cpp index 624231a99b..2843b9ab3d 100644 --- a/nif/tests/niftool.cpp +++ b/nif/tests/niftool.cpp @@ -9,6 +9,7 @@ using namespace Mangle::Stream; using namespace std; +using namespace Nif; int main(int argc, char **args) {