Uplifted tf out of the ui. Minecraft nbt style
12
Data.qrc
@ -21,4 +21,16 @@
|
|||||||
<file>data/d3dbsp/asset_viewer.d3dbsp</file>
|
<file>data/d3dbsp/asset_viewer.d3dbsp</file>
|
||||||
<file>data/d3dbsp/barebones.d3dbsp</file>
|
<file>data/d3dbsp/barebones.d3dbsp</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
|
<qresource prefix="/images">
|
||||||
|
<file>data/images/XPlor.png</file>
|
||||||
|
<file>data/images/copy.svg</file>
|
||||||
|
<file>data/images/cut.svg</file>
|
||||||
|
<file>data/images/new_file.svg</file>
|
||||||
|
<file>data/images/open_file.svg</file>
|
||||||
|
<file>data/images/open_folder.svg</file>
|
||||||
|
<file>data/images/paste.svg</file>
|
||||||
|
<file>data/images/refresh.svg</file>
|
||||||
|
<file>data/images/save.svg</file>
|
||||||
|
<file>data/images/multiple.png</file>
|
||||||
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
QT += core gui 3dcore 3drender 3dinput 3dextras
|
QT += core gui 3dcore 3drender 3dinput 3dextras
|
||||||
|
|
||||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
|
RC_ICONS = XPlor.ico
|
||||||
|
|
||||||
CONFIG += c++17
|
CONFIG += c++17
|
||||||
|
|
||||||
@ -13,16 +14,24 @@ CONFIG += c++17
|
|||||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
aboutdialog.cpp \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
mainwindow.cpp
|
mainwindow.cpp \
|
||||||
|
modelviewer.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
|
aboutdialog.h \
|
||||||
|
compression.h \
|
||||||
enums.h \
|
enums.h \
|
||||||
|
ffparser.h \
|
||||||
mainwindow.h \
|
mainwindow.h \
|
||||||
|
modelviewer.h \
|
||||||
structs.h \
|
structs.h \
|
||||||
utils.h
|
utils.h \
|
||||||
|
zfparser.h
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
|
aboutdialog.ui \
|
||||||
mainwindow.ui
|
mainwindow.ui
|
||||||
|
|
||||||
# Default rules for deployment.
|
# Default rules for deployment.
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE QtCreatorProject>
|
<!DOCTYPE QtCreatorProject>
|
||||||
<!-- Written by QtCreator 15.0.0, 2025-01-08T01:31:51. -->
|
<!-- Written by QtCreator 15.0.0, 2025-01-12T21:27:06. -->
|
||||||
<qtcreator>
|
<qtcreator>
|
||||||
<data>
|
<data>
|
||||||
<variable>EnvironmentId</variable>
|
<variable>EnvironmentId</variable>
|
||||||
@ -244,10 +244,10 @@
|
|||||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||||
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
||||||
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph "dwarf,4096" -F 250</value>
|
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph "dwarf,4096" -F 250</value>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">FastFile_WaW2</value>
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:</value>
|
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4RunConfiguration:</value>
|
||||||
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">C:/Users/njohnson/Projects/FastFile_WaW/FastFile_WaW.pro</value>
|
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">C:/Users/njohnson/Projects/XPlor/FastFile_WaW.pro</value>
|
||||||
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">true</value>
|
||||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||||
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
||||||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||||
|
|||||||
14
aboutdialog.cpp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include "aboutdialog.h"
|
||||||
|
#include "ui_aboutdialog.h"
|
||||||
|
|
||||||
|
AboutDialog::AboutDialog(QWidget *parent)
|
||||||
|
: QDialog(parent)
|
||||||
|
, ui(new Ui::AboutDialog)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
AboutDialog::~AboutDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
22
aboutdialog.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef ABOUTDIALOG_H
|
||||||
|
#define ABOUTDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class AboutDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class AboutDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit AboutDialog(QWidget *parent = nullptr);
|
||||||
|
~AboutDialog();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::AboutDialog *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ABOUTDIALOG_H
|
||||||
241
aboutdialog.ui
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>AboutDialog</class>
|
||||||
|
<widget class="QDialog" name="AboutDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>350</width>
|
||||||
|
<height>200</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>350</width>
|
||||||
|
<height>200</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>350</width>
|
||||||
|
<height>200</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>About XPlor</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>80</width>
|
||||||
|
<height>80</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>80</width>
|
||||||
|
<height>80</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="pixmap">
|
||||||
|
<pixmap resource="Data.qrc">:/images/data/images/XPlor.png</pixmap>
|
||||||
|
</property>
|
||||||
|
<property name="scaledContents">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignmentFlag::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Orientation::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Roboto</family>
|
||||||
|
<pointsize>16</pointsize>
|
||||||
|
<bold>false</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>XPlor v1.5</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Roboto</family>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Copyright © 2024 RedLine Solutions LLC</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Roboto</family>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>For more, check out redline.llc</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Orientation::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Policy::Fixed</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>10</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_6">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Roboto</family>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>With Help From:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_9">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Roboto</family>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>- Paging Red</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_8">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Roboto</family>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>- ISOCheated</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Roboto</family>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>- SureShotIan</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Orientation::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="Data.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
34
compression.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#ifndef COMPRESSION_H
|
||||||
|
#define COMPRESSION_H
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
#include "QtZlib/zlib.h"
|
||||||
|
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
class Compressor {
|
||||||
|
public:
|
||||||
|
static QByteArray DecompressZLIB(QByteArray compressedData) {
|
||||||
|
QByteArray decompressedData;
|
||||||
|
uLongf decompressedSize = compressedData.size() * 4;
|
||||||
|
decompressedData.resize(static_cast<int>(decompressedSize));
|
||||||
|
|
||||||
|
Bytef *destination = reinterpret_cast<Bytef*>(decompressedData.data());
|
||||||
|
uLongf *destLen = &decompressedSize;
|
||||||
|
const Bytef *source = reinterpret_cast<const Bytef*>(compressedData.data());
|
||||||
|
uLong sourceLen = compressedData.size();
|
||||||
|
|
||||||
|
int result = uncompress(destination, destLen, source, sourceLen);
|
||||||
|
|
||||||
|
if (result == Z_OK) {
|
||||||
|
decompressedData.resize(static_cast<int>(decompressedSize));
|
||||||
|
} else {
|
||||||
|
decompressedData.clear();
|
||||||
|
qDebug() << QString("In DecompressZLIB: %1").arg(Utils::ZLibErrorToString(result)).toLatin1();
|
||||||
|
}
|
||||||
|
return decompressedData;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // COMPRESSION_H
|
||||||
BIN
data/images/XPlor.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
1
data/images/copy.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 24 24"><path fill="currentColor" d="M15 11a3 3 0 0 1-3-3V4H8a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2v-8zm-2-3a2 2 0 0 0 2 2h3.59L13 4.41zM8 3h5l7 7v9a3 3 0 0 1-3 3H8a3 3 0 0 1-3-3V6a3 3 0 0 1 3-3m0 21a5 5 0 0 1-5-5V7h1v12a4 4 0 0 0 4 4h8v1z"/></svg>
|
||||||
|
After Width: | Height: | Size: 332 B |
1
data/images/cut.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 24 24"><path fill="currentColor" d="M9 6.5c0 .79-.26 1.5-.7 2.1L20 20.29V21h-.71l-7.79-7.79l-3.2 3.19c.44.6.7 1.31.7 2.1A3.5 3.5 0 0 1 5.5 22A3.5 3.5 0 0 1 2 18.5A3.5 3.5 0 0 1 5.5 15c.79 0 1.5.26 2.1.7l3.19-3.2L7.6 9.3c-.6.44-1.31.7-2.1.7A3.5 3.5 0 0 1 2 6.5A3.5 3.5 0 0 1 5.5 3A3.5 3.5 0 0 1 9 6.5m-1 0A2.5 2.5 0 0 0 5.5 4A2.5 2.5 0 0 0 3 6.5A2.5 2.5 0 0 0 5.5 9A2.5 2.5 0 0 0 8 6.5M19.29 4H20v.71l-7.15 7.14l-.7-.7zM5.5 16A2.5 2.5 0 0 0 3 18.5A2.5 2.5 0 0 0 5.5 21A2.5 2.5 0 0 0 8 18.5A2.5 2.5 0 0 0 5.5 16"/></svg>
|
||||||
|
After Width: | Height: | Size: 594 B |
BIN
data/images/multiple.png
Normal file
|
After Width: | Height: | Size: 133 KiB |
1
data/images/new_file.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 24 24"><path fill="currentColor" d="M14 11a3 3 0 0 1-3-3V4H7a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2v-8zm-2-3a2 2 0 0 0 2 2h3.59L12 4.41zM7 3h5l7 7v9a3 3 0 0 1-3 3H7a3 3 0 0 1-3-3V6a3 3 0 0 1 3-3m2 16v-2H7v-1h2v-2h1v2h2v1h-2v2z"/></svg>
|
||||||
|
After Width: | Height: | Size: 319 B |
1
data/images/open_file.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 24 24"><path fill="currentColor" d="M14 11a3 3 0 0 1-3-3V4H7a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2v-8zm-2-3a2 2 0 0 0 2 2h3.59L12 4.41zM7 3h5l7 7v9a3 3 0 0 1-3 3H7a3 3 0 0 1-3-3V6a3 3 0 0 1 3-3"/></svg>
|
||||||
|
After Width: | Height: | Size: 287 B |
1
data/images/open_folder.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 24 24"><path fill="currentColor" d="M5 5h4l3 3h6a3 3 0 0 1 3 3v6a3 3 0 0 1-3 3H5a3 3 0 0 1-3-3V8a3 3 0 0 1 3-3m0 1a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h13a2 2 0 0 0 2-2v-6a2 2 0 0 0-2-2h-6.41l-3-3z"/></svg>
|
||||||
|
After Width: | Height: | Size: 275 B |
1
data/images/paste.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 24 24"><path fill="currentColor" d="M11.5 1a2.5 2.5 0 0 1 2.45 2H17a3 3 0 0 1 3 3v13a3 3 0 0 1-3 3H6a3 3 0 0 1-3-3V6a3 3 0 0 1 3-3h3.05a2.5 2.5 0 0 1 2.45-2m1.41 2a1.495 1.495 0 0 0-2.82 0zM6 4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2h-1v3H7V4zm2 0v2h7V4z"/></svg>
|
||||||
|
After Width: | Height: | Size: 363 B |
1
data/images/refresh.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 24 24"><path fill="currentColor" d="M5 5h5v5H9V6.5c-2.35.97-4 3.29-4 6c0 3.58 2.91 6.5 6.5 6.5a6.5 6.5 0 0 0 6.5-6.5c0-3.08-2.14-5.66-5-6.33V5.14c3.42.7 6 3.72 6 7.36c0 4.13-3.36 7.5-7.5 7.5A7.5 7.5 0 0 1 4 12.5C4 9.72 5.5 7.3 7.74 6H5z"/></svg>
|
||||||
|
After Width: | Height: | Size: 321 B |
1
data/images/save.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 24 24"><path fill="currentColor" d="M6 4h10.59L20 7.41V18a3 3 0 0 1-3 3H6a3 3 0 0 1-3-3V7a3 3 0 0 1 3-3m0 1a2 2 0 0 0-2 2v11a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7.91L16.09 5H15v5H6zm1 0v4h7V5zm5 7a3 3 0 0 1 3 3a3 3 0 0 1-3 3a3 3 0 0 1-3-3a3 3 0 0 1 3-3m0 1a2 2 0 0 0-2 2a2 2 0 0 0 2 2a2 2 0 0 0 2-2a2 2 0 0 0-2-2"/></svg>
|
||||||
|
After Width: | Height: | Size: 392 B |
19
enums.h
@ -98,4 +98,23 @@ enum BSPVERSION_TYPE
|
|||||||
BSPVERSION_COD_BO = 45
|
BSPVERSION_COD_BO = 45
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum FF_COMPANY {
|
||||||
|
COMPANY_NONE = 0x00,
|
||||||
|
COMPANY_INFINITY_WARD = 0x01,
|
||||||
|
COMPANY_TREYARCH = 0x02,
|
||||||
|
COMPANY_SLEDGEHAMMER = 0x03,
|
||||||
|
COMPANY_NEVERSOFT = 0x04
|
||||||
|
};
|
||||||
|
|
||||||
|
enum FF_FILETYPE {
|
||||||
|
FILETYPE_NONE = 0x00,
|
||||||
|
FILETYPE_FAST_FILE = 0x01
|
||||||
|
};
|
||||||
|
|
||||||
|
enum FF_SIGNAGE {
|
||||||
|
SIGNAGE_NONE = 0x00,
|
||||||
|
SIGNAGE_SIGNED = 0x01,
|
||||||
|
SIGNAGE_UNSIGNED = 0x02
|
||||||
|
};
|
||||||
|
|
||||||
#endif // ENUMS_H
|
#endif // ENUMS_H
|
||||||
|
|||||||
103
ffparser.h
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
#ifndef FFPARSER_H
|
||||||
|
#define FFPARSER_H
|
||||||
|
|
||||||
|
#include "enums.h"
|
||||||
|
#include "structs.h"
|
||||||
|
|
||||||
|
#include <QDataStream>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
class FastFileParser {
|
||||||
|
public:
|
||||||
|
static FF_COMPANY ParseFFCompany(QDataStream *afastFileStream) {
|
||||||
|
// Check for null datastream ptr
|
||||||
|
if (!afastFileStream) { return COMPANY_NONE; }
|
||||||
|
// Parse company
|
||||||
|
QByteArray companyData(2, Qt::Uninitialized);
|
||||||
|
afastFileStream->readRawData(companyData.data(), 2);
|
||||||
|
if (companyData == "IW") {
|
||||||
|
qDebug() << "Company found: 'INFINITY_WARD'";
|
||||||
|
return COMPANY_INFINITY_WARD;
|
||||||
|
} else if (companyData == "TA") {
|
||||||
|
qDebug() << "Company found: 'TREYARCH'";
|
||||||
|
return COMPANY_TREYARCH;
|
||||||
|
} else if (companyData == "Sl") {
|
||||||
|
qDebug() << "Company found: 'SLEDGEHAMMER'";
|
||||||
|
return COMPANY_SLEDGEHAMMER;
|
||||||
|
} else if (companyData == "NX") {
|
||||||
|
qDebug() << "Company found: 'NEVERSOFT'";
|
||||||
|
return COMPANY_NEVERSOFT;
|
||||||
|
} else {
|
||||||
|
qDebug() << QString("Failed to find company, found '%1'!").arg(companyData);
|
||||||
|
}
|
||||||
|
return COMPANY_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FF_FILETYPE ParseFFFileType(QDataStream *afastFileStream) {
|
||||||
|
// Parse filetype
|
||||||
|
QByteArray fileTypeData(2, Qt::Uninitialized);
|
||||||
|
afastFileStream->readRawData(fileTypeData.data(), 2);
|
||||||
|
if (fileTypeData == "ff") {
|
||||||
|
qDebug() << "File type found: 'FAST_FILE'";
|
||||||
|
return FILETYPE_FAST_FILE;
|
||||||
|
} else {
|
||||||
|
qDebug() << "Failed to find file type!";
|
||||||
|
}
|
||||||
|
return FILETYPE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FF_SIGNAGE ParseFFSignage(QDataStream *afastFileStream) {
|
||||||
|
// Parse filetype
|
||||||
|
QByteArray signedData(1, Qt::Uninitialized);
|
||||||
|
afastFileStream->readRawData(signedData.data(), 1);
|
||||||
|
if (signedData == "u") {
|
||||||
|
qDebug() << "Found valid signage: Unsigned";
|
||||||
|
return SIGNAGE_UNSIGNED;
|
||||||
|
} else if (signedData == "0") {
|
||||||
|
qDebug() << "Found valid signage: Signed";
|
||||||
|
return SIGNAGE_SIGNED;
|
||||||
|
} else {
|
||||||
|
qDebug() << "Failed to determine signage of fastfile!";
|
||||||
|
}
|
||||||
|
return SIGNAGE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString ParseFFMagic(QDataStream *afastFileStream) {
|
||||||
|
// Parse magic
|
||||||
|
QByteArray magicData(3, Qt::Uninitialized);
|
||||||
|
afastFileStream->readRawData(magicData.data(), 3);
|
||||||
|
if (magicData == "100") {
|
||||||
|
qDebug() << QString("Found valid magic: '%1'").arg(magicData);
|
||||||
|
return magicData;
|
||||||
|
} else {
|
||||||
|
qDebug() << "Magic invalid!";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
static quint32 ParseFFVersion(QDataStream *afastFileStream) {
|
||||||
|
// Parse version
|
||||||
|
quint32 version;
|
||||||
|
*afastFileStream >> version;
|
||||||
|
qDebug() << "Version:" << version;
|
||||||
|
if (version == 387) {
|
||||||
|
qDebug() << QString("Found valid version: '%1'").arg(version);
|
||||||
|
return 387;
|
||||||
|
} else {
|
||||||
|
qDebug() << "Version invalid!";
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FastFile ParseFFHeader(QDataStream *afastFileStream) {
|
||||||
|
FastFile fastFile;
|
||||||
|
fastFile.company = ParseFFCompany(afastFileStream);
|
||||||
|
fastFile.fileType = ParseFFFileType(afastFileStream);
|
||||||
|
fastFile.signage = ParseFFSignage(afastFileStream);
|
||||||
|
fastFile.magic = ParseFFMagic(afastFileStream);
|
||||||
|
fastFile.version = ParseFFVersion(afastFileStream);
|
||||||
|
return fastFile;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FFPARSER_H
|
||||||
1265
mainwindow.cpp
111
mainwindow.h
@ -4,6 +4,11 @@
|
|||||||
#include "enums.h"
|
#include "enums.h"
|
||||||
#include "structs.h"
|
#include "structs.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include "aboutdialog.h"
|
||||||
|
#include "compression.h"
|
||||||
|
#include "ffparser.h"
|
||||||
|
#include "zfparser.h"
|
||||||
|
#include "modelviewer.h"
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
@ -12,52 +17,8 @@
|
|||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QTableWidgetItem>
|
#include <QTableWidgetItem>
|
||||||
#include <QTreeWidgetItem>
|
#include <QTreeWidgetItem>
|
||||||
|
#include <QDockWidget>
|
||||||
#include <Qt3DCore/QEntity>
|
#include <QPlainTextEdit>
|
||||||
#include <Qt3DRender/QCamera>
|
|
||||||
#include <Qt3DRender/QCameraLens>
|
|
||||||
#include <Qt3DCore/QTransform>
|
|
||||||
#include <Qt3DCore/QAspectEngine>
|
|
||||||
|
|
||||||
#include <Qt3DInput/QInputAspect>
|
|
||||||
|
|
||||||
#include <Qt3DRender/QRenderAspect>
|
|
||||||
#include <Qt3DRender/QGeometryRenderer>
|
|
||||||
#include <Qt3DExtras/QForwardRenderer>
|
|
||||||
#include <Qt3DExtras/QPhongMaterial>
|
|
||||||
#include <Qt3DExtras/QSphereMesh>
|
|
||||||
#include <Qt3DExtras/QTorusMesh>
|
|
||||||
#include <Qt3DRender/qcamera.h>
|
|
||||||
#include <Qt3DCore/qentity.h>
|
|
||||||
#include <Qt3DRender/qcameralens.h>
|
|
||||||
|
|
||||||
#include <QtWidgets/QApplication>
|
|
||||||
#include <QtWidgets/QWidget>
|
|
||||||
#include <QtWidgets/QHBoxLayout>
|
|
||||||
#include <QtWidgets/QCheckBox>
|
|
||||||
#include <QtWidgets/QCommandLinkButton>
|
|
||||||
#include <QtGui/QScreen>
|
|
||||||
|
|
||||||
#include <Qt3DRender/qmesh.h>
|
|
||||||
#include <Qt3DRender/qtechnique.h>
|
|
||||||
#include <Qt3DRender/qmaterial.h>
|
|
||||||
#include <Qt3DRender/qeffect.h>
|
|
||||||
#include <Qt3DRender/qtexture.h>
|
|
||||||
#include <Qt3DRender/qrenderpass.h>
|
|
||||||
#include <Qt3DRender/qsceneloader.h>
|
|
||||||
#include <Qt3DRender/qpointlight.h>
|
|
||||||
|
|
||||||
#include <Qt3DCore/qtransform.h>
|
|
||||||
#include <Qt3DCore/qaspectengine.h>
|
|
||||||
|
|
||||||
#include <Qt3DRender/qrenderaspect.h>
|
|
||||||
#include <Qt3DExtras/qforwardrenderer.h>
|
|
||||||
|
|
||||||
#include <Qt3DExtras/qt3dwindow.h>
|
|
||||||
#include <Qt3DExtras/qfirstpersoncameracontroller.h>
|
|
||||||
|
|
||||||
#include <Qt3DExtras/QNormalDiffuseMapMaterial>
|
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@ -75,60 +36,15 @@ public:
|
|||||||
~MainWindow();
|
~MainWindow();
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
QByteArray DecompressZLIB(QByteArray compressedData);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_pushButton_FastFile_clicked();
|
bool OpenFastFile(const QString aFastFilePath);
|
||||||
void on_pushButton_FastFile_2_clicked();
|
bool OpenFastFile();
|
||||||
|
|
||||||
QFile *OpenFastFile();
|
bool OpenZoneFile(const QString aZoneFilePath);
|
||||||
QFile *OpenZoneFile();
|
bool OpenZoneFile();
|
||||||
void ParseFFHeader(QFile *aFastFilePtr);
|
|
||||||
void ParseFFCompany(QDataStream *aFastFileStream);
|
|
||||||
void ParseFFFileType(QDataStream *afastFileStream);
|
|
||||||
void ParseFFSignage(QDataStream *afastFileStream);
|
|
||||||
void ParseFFMagic(QDataStream *afastFileStream);
|
|
||||||
void ParseFFVersion(QDataStream *afastFileStream);
|
|
||||||
|
|
||||||
void ParseZoneHeader(QDataStream *aZoneFileStream);
|
|
||||||
void ParseZoneSize(QDataStream *aZoneFileStream);
|
|
||||||
|
|
||||||
void ParseZoneUnknownsA(QDataStream *aZoneFileStream);
|
|
||||||
void ParseZoneUnknownsB(QDataStream *aZoneFileStream);
|
|
||||||
void ParseZoneUnknownsC(QDataStream *aZoneFileStream);
|
|
||||||
void ParseZoneTagCount(QDataStream *aZoneFileStream);
|
|
||||||
void ParseZoneRecordCount(QDataStream *aZoneFileStream);
|
|
||||||
void ParseZoneTags(QDataStream *aZoneFileStream);
|
|
||||||
void ParseZoneIndex(QDataStream *aZoneFileStream);
|
|
||||||
|
|
||||||
void ParseAsset_LocalString(QDataStream *aZoneFileStream);
|
|
||||||
void ParseAsset_RawFile(QDataStream *aZoneFileStream);
|
|
||||||
void ParseAsset_PhysPreset(QDataStream *aZoneFileStream);
|
|
||||||
void ParseAsset_XModel(QDataStream *aZoneFileStream);
|
|
||||||
void ParseAsset_Material(QDataStream *aZoneFileStream);
|
|
||||||
void ParseAsset_PixelShader(QDataStream *aZoneFileStream);
|
|
||||||
void ParseAsset_TechSet(QDataStream *aZoneFileStream);
|
|
||||||
void ParseAsset_Image(QDataStream *aZoneFileStream);
|
|
||||||
void ParseAsset_LoadedSound(QDataStream *aZoneFileStream);
|
|
||||||
void ParseAsset_ColMapMP(QDataStream *aZoneFileStream);
|
|
||||||
void ParseAsset_GameMapSP(QDataStream *aZoneFileStream);
|
|
||||||
void ParseAsset_GameMapMP(QDataStream *aZoneFileStream);
|
|
||||||
void ParseAsset_LightDef(QDataStream *aZoneFileStream);
|
|
||||||
void ParseAsset_UIMap(QDataStream *aZoneFileStream);
|
|
||||||
void ParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream);
|
|
||||||
void ParseAsset_AIType(QDataStream *aZoneFileStream);
|
|
||||||
void ParseAsset_FX(QDataStream *aZoneFileStream);
|
|
||||||
void ParseAsset_XAnim(QDataStream *aZoneFileStream);
|
|
||||||
void ParseAsset_StringTable(QDataStream *aZoneFileStream);
|
|
||||||
void ParseAsset_MenuFile(QDataStream *aZoneFileStream);
|
|
||||||
void ParseAsset_Weapon(QDataStream *aZoneFileStream);
|
|
||||||
void ParseAsset_D3DBSP(QDataStream *aZoneFileStream);
|
|
||||||
|
|
||||||
int LoadFile_D3DBSP(const QString aFilePath);
|
int LoadFile_D3DBSP(const QString aFilePath);
|
||||||
|
|
||||||
void ScriptSelected();
|
|
||||||
void StrTableSelected(QString aStrTableName);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
QMap<QString, int> mTypeMap;
|
QMap<QString, int> mTypeMap;
|
||||||
@ -139,6 +55,11 @@ private:
|
|||||||
QMap<QString, QTreeWidgetItem*> mTreeMap;
|
QMap<QString, QTreeWidgetItem*> mTreeMap;
|
||||||
QMap<QString, QVector<QPair<QString, QString>>> mStrTableMap;
|
QMap<QString, QVector<QPair<QString, QString>>> mStrTableMap;
|
||||||
|
|
||||||
|
QTreeWidget *mTreeWidget;
|
||||||
|
QTreeWidgetItem *mRootItem;
|
||||||
|
QPlainTextEdit *mScriptEditor;
|
||||||
|
ModelViewer *mModelViewer;
|
||||||
|
|
||||||
quint32 mBSPVersion;
|
quint32 mBSPVersion;
|
||||||
quint32 mDiskLumpCount;
|
quint32 mDiskLumpCount;
|
||||||
QVector<quint32> mDiskLumpOrder;
|
QVector<quint32> mDiskLumpOrder;
|
||||||
|
|||||||
1369
mainwindow.ui
73
modelviewer.cpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#include "modelviewer.h"
|
||||||
|
|
||||||
|
ModelViewer::ModelViewer(QWidget *parent)
|
||||||
|
: QWidget{parent} {
|
||||||
|
Qt3DExtras::Qt3DWindow *view = new Qt3DExtras::Qt3DWindow();
|
||||||
|
view->defaultFrameGraph()->setClearColor(QColor(QRgb(0x4d4d4f)));
|
||||||
|
|
||||||
|
QWidget *container = QWidget::createWindowContainer(view);
|
||||||
|
QSize screenSize = view->screen()->size();
|
||||||
|
container->setMinimumSize(QSize(200, 100));
|
||||||
|
container->setMaximumSize(screenSize);
|
||||||
|
|
||||||
|
QHBoxLayout *hLayout = new QHBoxLayout(this);
|
||||||
|
QVBoxLayout *vLayout = new QVBoxLayout();
|
||||||
|
vLayout->setAlignment(Qt::AlignTop);
|
||||||
|
hLayout->addWidget(container, 1);
|
||||||
|
hLayout->addLayout(vLayout);
|
||||||
|
|
||||||
|
// Root entity
|
||||||
|
Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
|
||||||
|
|
||||||
|
// Camera
|
||||||
|
Qt3DRender::QCamera *cameraEntity = view->camera();
|
||||||
|
|
||||||
|
cameraEntity->lens()->setPerspectiveProjection(45.0f, 16.0f/9.0f, 0.1f, 1000.0f);
|
||||||
|
cameraEntity->setPosition(QVector3D(0, 0, 50.0f)); // Move farther along Z-axis
|
||||||
|
cameraEntity->setUpVector(QVector3D(0, 1, 0));
|
||||||
|
cameraEntity->setViewCenter(QVector3D(0, 0, 0));
|
||||||
|
|
||||||
|
Qt3DCore::QEntity *lightEntity = new Qt3DCore::QEntity(rootEntity);
|
||||||
|
Qt3DRender::QPointLight *light = new Qt3DRender::QPointLight(lightEntity);
|
||||||
|
light->setColor("white");
|
||||||
|
light->setIntensity(1);
|
||||||
|
lightEntity->addComponent(light);
|
||||||
|
|
||||||
|
Qt3DCore::QTransform *lightTransform = new Qt3DCore::QTransform(lightEntity);
|
||||||
|
lightTransform->setTranslation(cameraEntity->position());
|
||||||
|
lightEntity->addComponent(lightTransform);
|
||||||
|
|
||||||
|
// For camera controls
|
||||||
|
Qt3DExtras::QFirstPersonCameraController *camController = new Qt3DExtras::QFirstPersonCameraController(rootEntity);
|
||||||
|
camController->setCamera(cameraEntity);
|
||||||
|
|
||||||
|
// Set root object of the scene
|
||||||
|
view->setRootEntity(rootEntity);
|
||||||
|
|
||||||
|
// Load custom 3D model
|
||||||
|
Qt3DRender::QMesh *customMesh = new Qt3DRender::QMesh();
|
||||||
|
customMesh->setSource(QUrl::fromLocalFile(":/obj/data/obj/defaultactor_LOD0.obj"));
|
||||||
|
|
||||||
|
// Adjust the model transformation
|
||||||
|
Qt3DCore::QTransform *customTransform = new Qt3DCore::QTransform();
|
||||||
|
customTransform->setRotationX(-90);
|
||||||
|
customTransform->setRotationY(-90);
|
||||||
|
|
||||||
|
// Keep translation if necessary
|
||||||
|
customTransform->setTranslation(QVector3D(0.0f, -100.0f, -200.0f));
|
||||||
|
|
||||||
|
Qt3DExtras::QNormalDiffuseMapMaterial *customMaterial = new Qt3DExtras::QNormalDiffuseMapMaterial();
|
||||||
|
|
||||||
|
Qt3DRender::QTextureLoader *normalMap = new Qt3DRender::QTextureLoader();
|
||||||
|
normalMap->setSource(QUrl::fromLocalFile(":/obj/data/obj/normalmap.png"));
|
||||||
|
customMaterial->setNormal(normalMap);
|
||||||
|
|
||||||
|
Qt3DRender::QTextureLoader *diffuseMap = new Qt3DRender::QTextureLoader();
|
||||||
|
diffuseMap->setSource(QUrl::fromLocalFile(":/obj/data/obj/diffusemap.png"));
|
||||||
|
customMaterial->setDiffuse(diffuseMap);
|
||||||
|
|
||||||
|
Qt3DCore::QEntity *m_torusEntity = new Qt3DCore::QEntity(rootEntity);
|
||||||
|
m_torusEntity->addComponent(customMesh);
|
||||||
|
m_torusEntity->addComponent(customMaterial);
|
||||||
|
m_torusEntity->addComponent(customTransform);
|
||||||
|
}
|
||||||
53
modelviewer.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#ifndef MODELVIEWER_H
|
||||||
|
#define MODELVIEWER_H
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QCommandLinkButton>
|
||||||
|
#include <QScreen>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
// Qt3DCore includes
|
||||||
|
#include <QEntity>
|
||||||
|
#include <QTransform>
|
||||||
|
#include <QAspectEngine>
|
||||||
|
#include <qtransform.h>
|
||||||
|
#include <qaspectengine.h>
|
||||||
|
#include <qentity.h>
|
||||||
|
// Qt3DInput includes
|
||||||
|
#include <QInputAspect>
|
||||||
|
// Qt3DRender includes
|
||||||
|
#include <QRenderAspect>
|
||||||
|
#include <QGeometryRenderer>
|
||||||
|
#include <QCamera>
|
||||||
|
#include <QCameraLens>
|
||||||
|
#include <QMesh>
|
||||||
|
#include <QTechnique>
|
||||||
|
#include <QMaterial>
|
||||||
|
#include <QEffect>
|
||||||
|
#include <QTexture>
|
||||||
|
#include <QRenderPass>
|
||||||
|
#include <QSceneLoader>
|
||||||
|
#include <QPointLight>
|
||||||
|
// Qt3DExtras includes
|
||||||
|
#include <Qt3DWindow>
|
||||||
|
#include <QFirstPersonCameraController>
|
||||||
|
#include <QNormalDiffuseMapMaterial>
|
||||||
|
#include <QForwardRenderer>
|
||||||
|
#include <QPhongMaterial>
|
||||||
|
#include <QSphereMesh>
|
||||||
|
#include <QTorusMesh>
|
||||||
|
|
||||||
|
class ModelViewer : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit ModelViewer(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MODELVIEWER_H
|
||||||
110
structs.h
@ -1,7 +1,12 @@
|
|||||||
#ifndef STRUCTS_H
|
#ifndef STRUCTS_H
|
||||||
#define STRUCTS_H
|
#define STRUCTS_H
|
||||||
|
|
||||||
|
#include "enums.h"
|
||||||
|
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
|
#include <QString>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QMap>
|
||||||
|
|
||||||
// Define Lump Structure
|
// Define Lump Structure
|
||||||
struct Lump {
|
struct Lump {
|
||||||
@ -16,4 +21,109 @@ struct LumpIndexEntry {
|
|||||||
quint32 length;
|
quint32 length;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct LocalString {
|
||||||
|
QString string;
|
||||||
|
QString alias;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RawFile {
|
||||||
|
quint32 length;
|
||||||
|
QString path;
|
||||||
|
QString contents;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TechSet {
|
||||||
|
QString name;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Animation {
|
||||||
|
quint16 dataByteCount;
|
||||||
|
quint16 dataShortCount;
|
||||||
|
quint16 dataIntCount;
|
||||||
|
quint16 randomDataByteCount;
|
||||||
|
quint16 randomDataIntCount;
|
||||||
|
quint16 numframes;
|
||||||
|
bool isLooped;
|
||||||
|
bool isDelta;
|
||||||
|
quint8 noneRotatedBoneCount;
|
||||||
|
quint8 twoDRotatedBoneCount;
|
||||||
|
quint8 normalRotatedBoneCount;
|
||||||
|
quint8 twoDStaticRotatedBoneCount;
|
||||||
|
quint8 normalStaticRotatedBoneCount;
|
||||||
|
quint8 normalTranslatedBoneCount;
|
||||||
|
quint8 preciseTranslatedBoneCount;
|
||||||
|
quint8 staticTranslatedBoneCount;
|
||||||
|
quint8 noneTranslatedBoneCount;
|
||||||
|
quint8 totalBoneCount;
|
||||||
|
quint8 otherBoneCount1;
|
||||||
|
quint8 otherBoneCount2;
|
||||||
|
quint8 notifyCount;
|
||||||
|
quint8 assetType;
|
||||||
|
bool pad;
|
||||||
|
unsigned int randomDataShortCount;
|
||||||
|
unsigned int indexCount;
|
||||||
|
float frameRate;
|
||||||
|
float frequency;
|
||||||
|
quint32 boneIDsPtr;
|
||||||
|
quint32 dataBytePtr;
|
||||||
|
quint32 dataShortPtr;
|
||||||
|
quint32 dataIntPtr;
|
||||||
|
quint32 randomDataShortPtr;
|
||||||
|
quint32 randomDataBytePtr;
|
||||||
|
quint32 randomDataIntPtr;
|
||||||
|
quint32 longIndiciesPtr;
|
||||||
|
quint32 notificationsPtr;
|
||||||
|
quint32 deltaPartsPtr;
|
||||||
|
QString name;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct StringTable {
|
||||||
|
quint32 columnCount;
|
||||||
|
quint32 rowCount;
|
||||||
|
QString name;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AssetMap {
|
||||||
|
QVector<LocalString> localStrings;
|
||||||
|
QVector<RawFile> rawFiles;
|
||||||
|
//QVector<PhysPreset> phyPresets;
|
||||||
|
//QVector<Model> models;
|
||||||
|
//QVector<Material> rawFiles;
|
||||||
|
//QVector<Shader> shaders;
|
||||||
|
QVector<TechSet> techSets;
|
||||||
|
//QVector<Image> images;
|
||||||
|
//QVector<Sound> sounds;
|
||||||
|
//QVector<CollisionMap> collMaps;
|
||||||
|
//QVector<LightDefinition> lightDefs;
|
||||||
|
//QVector<UiMap> uiMaps;
|
||||||
|
//QVector<DriverGlobal> driverGlobals;
|
||||||
|
//QVector<AiType> aiType;
|
||||||
|
//QVector<Effect> effects;
|
||||||
|
QVector<Animation> animations;
|
||||||
|
QVector<StringTable> stringTables;
|
||||||
|
//QVector<Menu> menus;
|
||||||
|
//QVector<Weapon> weapons;
|
||||||
|
//QVector<D3DBSP> d3dbspDumps;
|
||||||
|
//QVector<SingleplayerMap> spMaps;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ZoneFile {
|
||||||
|
quint32 size;
|
||||||
|
quint32 tagCount;
|
||||||
|
QStringList tags;
|
||||||
|
quint32 recordCount;
|
||||||
|
QStringList records;
|
||||||
|
AssetMap assetMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FastFile {
|
||||||
|
FF_COMPANY company;
|
||||||
|
FF_FILETYPE fileType;
|
||||||
|
FF_SIGNAGE signage;
|
||||||
|
QString magic;
|
||||||
|
quint32 version;
|
||||||
|
|
||||||
|
ZoneFile zoneFile;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // STRUCTS_H
|
#endif // STRUCTS_H
|
||||||
|
|||||||
65
utils.h
@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QtZlib/zlib.h>
|
#include <QtZlib/zlib.h>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
class Utils {
|
class Utils {
|
||||||
public:
|
public:
|
||||||
@ -164,6 +166,69 @@ public:
|
|||||||
static quint32 PaddingSize(quint32 size) {
|
static quint32 PaddingSize(quint32 size) {
|
||||||
return PadInt4(size) - size;
|
return PadInt4(size) - size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QString GetOpenFastFileName(QWidget *parent = nullptr) {
|
||||||
|
// Open file dialog to steam apps
|
||||||
|
const QString steamPath = "C:/Program Files (x86)/Steam/steamapps/common/Call of Duty World at War/zone/english/";
|
||||||
|
const QString fastFilePath = QFileDialog::getOpenFileName(parent, "Open Fast File", steamPath, "Fast File (*.ff);;All Files (*.*)");
|
||||||
|
if (fastFilePath.isNull()) {
|
||||||
|
// User pressed cancel
|
||||||
|
return "";
|
||||||
|
} else if (!QFile::exists(fastFilePath)) {
|
||||||
|
QMessageBox::warning(parent, "Warning!", QString("%1 does not exist!.").arg(fastFilePath));
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return fastFilePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString GetOpenZoneFileName(QWidget *parent = nullptr) {
|
||||||
|
// Open file dialog to steam apps
|
||||||
|
const QString steamPath = "C:/Program Files (x86)/Steam/steamapps/common/Call of Duty World at War/zone/english/";
|
||||||
|
const QString zoneFilePath = QFileDialog::getOpenFileName(parent, "Open Zone File", steamPath, "Zone File (*.zone);;All Files (*.*)");
|
||||||
|
if (zoneFilePath.isNull()) {
|
||||||
|
// User pressed cancel
|
||||||
|
return "";
|
||||||
|
} else if (!QFile::exists(zoneFilePath)) {
|
||||||
|
QMessageBox::warning(parent, "Warning!", QString("%1 does not exist!.").arg(zoneFilePath));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return zoneFilePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString CompanyEnumToStr(FF_COMPANY aCompany) {
|
||||||
|
switch (aCompany) {
|
||||||
|
case COMPANY_NONE:
|
||||||
|
return "None";
|
||||||
|
case COMPANY_INFINITY_WARD:
|
||||||
|
return "Infinity Ward";
|
||||||
|
case COMPANY_TREYARCH:
|
||||||
|
return "Treyarch";
|
||||||
|
case COMPANY_SLEDGEHAMMER:
|
||||||
|
return "Sledgehammer";
|
||||||
|
case COMPANY_NEVERSOFT:
|
||||||
|
return "Neversoft";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString FileTypeEnumToStr(FF_FILETYPE aFileType) {
|
||||||
|
switch (aFileType) {
|
||||||
|
case FILETYPE_NONE:
|
||||||
|
return "None";
|
||||||
|
case FILETYPE_FAST_FILE:
|
||||||
|
return "Fast File";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString SignageEnumToStr(FF_SIGNAGE aSignage) {
|
||||||
|
switch (aSignage) {
|
||||||
|
case SIGNAGE_NONE:
|
||||||
|
return "None";
|
||||||
|
case SIGNAGE_SIGNED:
|
||||||
|
return "Signed";
|
||||||
|
case SIGNAGE_UNSIGNED:
|
||||||
|
return "Unsigned";
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // UTILS_H
|
#endif // UTILS_H
|
||||||
|
|||||||
523
zfparser.h
Normal file
@ -0,0 +1,523 @@
|
|||||||
|
#ifndef ZFPARSER_H
|
||||||
|
#define ZFPARSER_H
|
||||||
|
|
||||||
|
#include "qtypes.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "structs.h"
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QDataStream>
|
||||||
|
|
||||||
|
class ZoneFileParser {
|
||||||
|
public:
|
||||||
|
static ZoneFile ParseZoneHeader(QDataStream *aZoneFileStream) {
|
||||||
|
ZoneFile result;
|
||||||
|
|
||||||
|
result.size = ParseZoneSize(aZoneFileStream);
|
||||||
|
ParseZoneUnknownsA(aZoneFileStream);
|
||||||
|
|
||||||
|
result.tagCount = ParseZoneTagCount(aZoneFileStream);
|
||||||
|
ParseZoneUnknownsB(aZoneFileStream);
|
||||||
|
|
||||||
|
result.recordCount = ParseZoneRecordCount(aZoneFileStream);
|
||||||
|
|
||||||
|
if (result.tagCount) {
|
||||||
|
ParseZoneUnknownsC(aZoneFileStream);
|
||||||
|
result.tags = ParseZoneTags(aZoneFileStream, result.tagCount);
|
||||||
|
} else {
|
||||||
|
aZoneFileStream->skipRawData(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static quint32 ParseZoneSize(QDataStream *aZoneFileStream) {
|
||||||
|
quint32 zoneFileSize;
|
||||||
|
*aZoneFileStream >> zoneFileSize;
|
||||||
|
if (zoneFileSize <= 0) {
|
||||||
|
qDebug() << "Tried to open empty zone file!";
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
zoneFileSize += 36;
|
||||||
|
return zoneFileSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
ParseZoneUnknownsA()
|
||||||
|
|
||||||
|
Parses the 1st section of unknowns as hex vals and uint32s
|
||||||
|
*/
|
||||||
|
static void ParseZoneUnknownsA(QDataStream *aZoneFileStream) {
|
||||||
|
// Byte 4-7, 8-11, 12-15: unknown
|
||||||
|
QByteArray unknown1(4, Qt::Uninitialized);
|
||||||
|
aZoneFileStream->readRawData(unknown1.data(), 4);
|
||||||
|
|
||||||
|
QByteArray unknown2(4, Qt::Uninitialized);
|
||||||
|
aZoneFileStream->readRawData(unknown2.data(), 4);
|
||||||
|
|
||||||
|
QByteArray unknown3(4, Qt::Uninitialized);
|
||||||
|
aZoneFileStream->readRawData(unknown3.data(), 4);
|
||||||
|
|
||||||
|
// Byte 16-19, 20-23: empty/unknown
|
||||||
|
QByteArray unknown4(4, Qt::Uninitialized);
|
||||||
|
aZoneFileStream->readRawData(unknown4.data(), 4);
|
||||||
|
|
||||||
|
QByteArray unknown5(4, Qt::Uninitialized);
|
||||||
|
aZoneFileStream->readRawData(unknown5.data(), 4);
|
||||||
|
|
||||||
|
// Byte 24-27: somehow related to the filesize, but smaller value
|
||||||
|
QByteArray unknown6(4, Qt::Uninitialized);
|
||||||
|
aZoneFileStream->readRawData(unknown6.data(), 4);
|
||||||
|
|
||||||
|
// Byte 28-31, 32-35: unknown
|
||||||
|
QByteArray unknown7(4, Qt::Uninitialized);
|
||||||
|
aZoneFileStream->readRawData(unknown7.data(), 4);
|
||||||
|
|
||||||
|
QByteArray unknown8(4, Qt::Uninitialized);
|
||||||
|
aZoneFileStream->readRawData(unknown8.data(), 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
ParseZoneTagCount()
|
||||||
|
|
||||||
|
Parses the number of string tags in the zone index
|
||||||
|
*/
|
||||||
|
static quint32 ParseZoneTagCount(QDataStream *aZoneFileStream) {
|
||||||
|
quint32 tagCount;
|
||||||
|
*aZoneFileStream >> tagCount;
|
||||||
|
return tagCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
ParseZoneRecordCount()
|
||||||
|
|
||||||
|
Parses the number of records in the zone index
|
||||||
|
*/
|
||||||
|
static quint32 ParseZoneRecordCount(QDataStream *aZoneFileStream) {
|
||||||
|
quint32 recordCount;
|
||||||
|
*aZoneFileStream >> recordCount;
|
||||||
|
return recordCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
ParseZoneUnknownsB()
|
||||||
|
|
||||||
|
Parses the 2nd section of unknowns as hex vals and uint32s
|
||||||
|
*/
|
||||||
|
static void ParseZoneUnknownsB(QDataStream *aZoneFileStream) {
|
||||||
|
// Byte 44-47: Unknown/empty?
|
||||||
|
QByteArray unknown9(4, Qt::Uninitialized);
|
||||||
|
aZoneFileStream->readRawData(unknown9.data(), 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
ParseZoneUnknownsC()
|
||||||
|
|
||||||
|
Parses the 3rd section of unknowns as hex vals and uint32s
|
||||||
|
*/
|
||||||
|
static void ParseZoneUnknownsC(QDataStream *aZoneFileStream) {
|
||||||
|
// Byte 40-43: Unknown/empty?
|
||||||
|
QByteArray unknown10(4, Qt::Uninitialized);
|
||||||
|
aZoneFileStream->readRawData(unknown10.data(), 4);
|
||||||
|
|
||||||
|
// Byte 44-47: Unknown/empty?
|
||||||
|
QByteArray unknown11(4, Qt::Uninitialized);
|
||||||
|
aZoneFileStream->readRawData(unknown11.data(), 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
ParseZoneTags()
|
||||||
|
|
||||||
|
Parses the string tags ate the start of zone file
|
||||||
|
*/
|
||||||
|
static QStringList ParseZoneTags(QDataStream *aZoneFileStream, quint32 tagCount) {
|
||||||
|
QStringList tags;
|
||||||
|
|
||||||
|
// Byte 48-51: Repeated separators? ÿÿÿÿ x i
|
||||||
|
aZoneFileStream->skipRawData(4 * (tagCount - 1));
|
||||||
|
|
||||||
|
// Parse tags/strings before index
|
||||||
|
QString zoneTag;
|
||||||
|
char zoneTagChar;
|
||||||
|
for (quint32 i = 0; i < tagCount - 1; i++) {
|
||||||
|
*aZoneFileStream >> zoneTagChar;
|
||||||
|
while (zoneTagChar != 0) {
|
||||||
|
zoneTag += zoneTagChar;
|
||||||
|
*aZoneFileStream >> zoneTagChar;
|
||||||
|
}
|
||||||
|
tags << zoneTag;
|
||||||
|
zoneTag.clear();
|
||||||
|
}
|
||||||
|
return tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
ParseZoneIndex()
|
||||||
|
|
||||||
|
Parse the binary zone index data and populate table
|
||||||
|
*/
|
||||||
|
static QStringList ParseZoneIndex(QDataStream *aZoneFileStream, quint32 recordCount) {
|
||||||
|
QStringList result;
|
||||||
|
|
||||||
|
// Don't parse if no records
|
||||||
|
if (!recordCount) { return result; }
|
||||||
|
|
||||||
|
// Track past assets and counts
|
||||||
|
QString lastAssetType = "";
|
||||||
|
|
||||||
|
// Parse index & map found asset types
|
||||||
|
for (quint32 i = 0; i < recordCount; i++) {
|
||||||
|
// Skip record start
|
||||||
|
QByteArray rawAssetType(4, Qt::Uninitialized);
|
||||||
|
aZoneFileStream->readRawData(rawAssetType.data(), 4);
|
||||||
|
result << rawAssetType.toHex();
|
||||||
|
|
||||||
|
// Skip separator
|
||||||
|
aZoneFileStream->skipRawData(4);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static AssetMap ParseAssets(QDataStream *aZoneFileStream, QStringList assetOrder) {
|
||||||
|
AssetMap result;
|
||||||
|
|
||||||
|
for (int i = 0; i < assetOrder.size(); i++) {
|
||||||
|
const QString typeHex = assetOrder[i];
|
||||||
|
const QString typeStr = Utils::AssetTypeToString(typeHex);
|
||||||
|
|
||||||
|
if (typeStr == "LOCAL STRING") { // localized string asset
|
||||||
|
result.localStrings << ParseAsset_LocalString(aZoneFileStream);
|
||||||
|
} else if (typeStr == "RAW FILE") { // gsc
|
||||||
|
result.rawFiles << ParseAsset_RawFile(aZoneFileStream);
|
||||||
|
} else if (typeStr == "PHYS PRESET") { // physpreset
|
||||||
|
ParseAsset_PhysPreset(aZoneFileStream);
|
||||||
|
} else if (typeStr == "MODEL") { // xmodel
|
||||||
|
ParseAsset_Model(aZoneFileStream);
|
||||||
|
} else if (typeStr == "MATERIAL") { // material
|
||||||
|
ParseAsset_Material(aZoneFileStream);
|
||||||
|
} else if (typeStr == "SHADER") { // pixelshader
|
||||||
|
ParseAsset_PixelShader(aZoneFileStream);
|
||||||
|
} else if (typeStr == "TECH SET") { // techset include
|
||||||
|
result.techSets << ParseAsset_TechSet(aZoneFileStream);
|
||||||
|
} else if (typeStr == "IMAGE") { // image
|
||||||
|
ParseAsset_Image(aZoneFileStream);
|
||||||
|
} else if (typeStr == "SOUND") { // loaded_sound
|
||||||
|
ParseAsset_LoadedSound(aZoneFileStream);
|
||||||
|
} else if (typeStr == "COLLISION MAP") { // col_map_mp
|
||||||
|
ParseAsset_ColMapMP(aZoneFileStream);
|
||||||
|
} else if (typeStr == "MP MAP") { // game_map_sp
|
||||||
|
ParseAsset_GameMapSP(aZoneFileStream);
|
||||||
|
} else if (typeStr == "SP MAP") { // game_map_mp
|
||||||
|
ParseAsset_GameMapMP(aZoneFileStream);
|
||||||
|
} else if (typeStr == "LIGHT DEF") { // lightdef
|
||||||
|
ParseAsset_LightDef(aZoneFileStream);
|
||||||
|
} else if (typeStr == "UI MAP") { // ui_map
|
||||||
|
ParseAsset_UIMap(aZoneFileStream);
|
||||||
|
} else if (typeStr == "SND DRIVER GLOBALS") { // snddriverglobals
|
||||||
|
ParseAsset_SNDDriverGlobals(aZoneFileStream);
|
||||||
|
} else if (typeStr == "AI TYPE") { // aitype
|
||||||
|
ParseAsset_AIType(aZoneFileStream);
|
||||||
|
} else if (typeStr == "EFFECT") { // aitype
|
||||||
|
ParseAsset_FX(aZoneFileStream);
|
||||||
|
} else if (typeStr == "ANIMATION") { // aitype
|
||||||
|
result.animations << ParseAsset_Animation(aZoneFileStream);
|
||||||
|
} else if (typeStr == "STRING TABLE") { // string_table
|
||||||
|
result.stringTables << ParseAsset_StringTable(aZoneFileStream);
|
||||||
|
} else if (typeStr == "MENU") { // string_table
|
||||||
|
ParseAsset_MenuFile(aZoneFileStream);
|
||||||
|
} else if (typeStr == "WEAPON") { // string_table
|
||||||
|
ParseAsset_Weapon(aZoneFileStream);
|
||||||
|
} else if (typeStr == "D3DBSP DUMP") { // string_table
|
||||||
|
ParseAsset_D3DBSP(aZoneFileStream);
|
||||||
|
} else if (typeStr != "UNKNOWN") {
|
||||||
|
qDebug() << "Found bad asset type!" << typeStr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LocalString ParseAsset_LocalString(QDataStream *aZoneFileStream) {
|
||||||
|
LocalString result;
|
||||||
|
|
||||||
|
// Skip separator
|
||||||
|
aZoneFileStream->skipRawData(8);
|
||||||
|
|
||||||
|
// Parse local string asset contents
|
||||||
|
QString localStr;
|
||||||
|
char localStrChar;
|
||||||
|
*aZoneFileStream >> localStrChar;
|
||||||
|
while (localStrChar != 0) {
|
||||||
|
result.string += localStrChar;
|
||||||
|
*aZoneFileStream >> localStrChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse rawfile name
|
||||||
|
QString aliasName;
|
||||||
|
char aliasNameChar;
|
||||||
|
*aZoneFileStream >> aliasNameChar;
|
||||||
|
while (aliasNameChar != 0) {
|
||||||
|
result.alias += aliasNameChar;
|
||||||
|
*aZoneFileStream >> aliasNameChar;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static RawFile ParseAsset_RawFile(QDataStream *aZoneFileStream) {
|
||||||
|
RawFile result;
|
||||||
|
|
||||||
|
// Skip start separator FF FF FF FF (pointer?)
|
||||||
|
aZoneFileStream->skipRawData(4);
|
||||||
|
|
||||||
|
*aZoneFileStream >> result.length;
|
||||||
|
|
||||||
|
// Skip unknown 4 byte data
|
||||||
|
aZoneFileStream->skipRawData(4);
|
||||||
|
|
||||||
|
// Parse rawfile path
|
||||||
|
char scriptPathChar;
|
||||||
|
*aZoneFileStream >> scriptPathChar;
|
||||||
|
while (scriptPathChar != 0) {
|
||||||
|
result.path += scriptPathChar;
|
||||||
|
*aZoneFileStream >> scriptPathChar;
|
||||||
|
}
|
||||||
|
result.path.replace(",", "");
|
||||||
|
const QStringList pathParts = result.path.split('/');
|
||||||
|
if (pathParts.size() == 0) {
|
||||||
|
qDebug() << "Failed to parse ff path! " << result.path;
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse gsc contents
|
||||||
|
char rawFileContentsChar;
|
||||||
|
*aZoneFileStream >> rawFileContentsChar;
|
||||||
|
while (rawFileContentsChar != 0 && rawFileContentsChar != -1) {
|
||||||
|
result.contents += rawFileContentsChar;
|
||||||
|
*aZoneFileStream >> rawFileContentsChar;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ParseAsset_PhysPreset(QDataStream *aZoneFileStream) {
|
||||||
|
Q_UNUSED(aZoneFileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ParseAsset_Model(QDataStream *aZoneFileStream) {
|
||||||
|
Q_UNUSED(aZoneFileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ParseAsset_Material(QDataStream *aZoneFileStream) {
|
||||||
|
Q_UNUSED(aZoneFileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ParseAsset_PixelShader(QDataStream *aZoneFileStream) {
|
||||||
|
Q_UNUSED(aZoneFileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TechSet ParseAsset_TechSet(QDataStream *aZoneFileStream) {
|
||||||
|
TechSet result;
|
||||||
|
|
||||||
|
aZoneFileStream->skipRawData(4);
|
||||||
|
// Parse techset name
|
||||||
|
char techSetNameChar;
|
||||||
|
*aZoneFileStream >> techSetNameChar;
|
||||||
|
while (techSetNameChar == 0) {
|
||||||
|
*aZoneFileStream >> techSetNameChar;
|
||||||
|
}
|
||||||
|
while (techSetNameChar != 0) {
|
||||||
|
result.name += techSetNameChar;
|
||||||
|
*aZoneFileStream >> techSetNameChar;
|
||||||
|
}
|
||||||
|
result.name.replace(",", "");
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ParseAsset_Image(QDataStream *aZoneFileStream) {
|
||||||
|
Q_UNUSED(aZoneFileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ParseAsset_LoadedSound(QDataStream *aZoneFileStream) {
|
||||||
|
Q_UNUSED(aZoneFileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ParseAsset_ColMapMP(QDataStream *aZoneFileStream) {
|
||||||
|
Q_UNUSED(aZoneFileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ParseAsset_GameMapSP(QDataStream *aZoneFileStream) {
|
||||||
|
Q_UNUSED(aZoneFileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ParseAsset_GameMapMP(QDataStream *aZoneFileStream) {
|
||||||
|
Q_UNUSED(aZoneFileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ParseAsset_LightDef(QDataStream *aZoneFileStream) {
|
||||||
|
Q_UNUSED(aZoneFileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ParseAsset_UIMap(QDataStream *aZoneFileStream) {
|
||||||
|
Q_UNUSED(aZoneFileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ParseAsset_SNDDriverGlobals(QDataStream *aZoneFileStream) {
|
||||||
|
Q_UNUSED(aZoneFileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ParseAsset_AIType(QDataStream *aZoneFileStream) {
|
||||||
|
Q_UNUSED(aZoneFileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ParseAsset_FX(QDataStream *aZoneFileStream) {
|
||||||
|
Q_UNUSED(aZoneFileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Animation ParseAsset_Animation(QDataStream *aZoneFileStream) {
|
||||||
|
Animation result;
|
||||||
|
|
||||||
|
aZoneFileStream->skipRawData(4);
|
||||||
|
|
||||||
|
*aZoneFileStream
|
||||||
|
>> result.dataByteCount
|
||||||
|
>> result.dataShortCount
|
||||||
|
>> result.dataIntCount
|
||||||
|
>> result.randomDataByteCount
|
||||||
|
>> result.randomDataIntCount
|
||||||
|
>> result.numframes
|
||||||
|
>> result.isLooped
|
||||||
|
>> result.isDelta
|
||||||
|
>> result.noneRotatedBoneCount
|
||||||
|
>> result.twoDRotatedBoneCount
|
||||||
|
>> result.normalRotatedBoneCount
|
||||||
|
>> result.twoDStaticRotatedBoneCount
|
||||||
|
>> result.normalStaticRotatedBoneCount
|
||||||
|
>> result.normalTranslatedBoneCount
|
||||||
|
>> result.preciseTranslatedBoneCount
|
||||||
|
>> result.staticTranslatedBoneCount
|
||||||
|
>> result.noneTranslatedBoneCount
|
||||||
|
>> result.totalBoneCount
|
||||||
|
>> result.otherBoneCount1
|
||||||
|
>> result.otherBoneCount2
|
||||||
|
>> result.notifyCount
|
||||||
|
>> result.assetType
|
||||||
|
>> result.pad
|
||||||
|
>> result.randomDataShortCount
|
||||||
|
>> result.indexCount
|
||||||
|
>> result.frameRate
|
||||||
|
>> result.frequency
|
||||||
|
>> result.boneIDsPtr
|
||||||
|
>> result.dataBytePtr
|
||||||
|
>> result.dataShortPtr
|
||||||
|
>> result.dataIntPtr
|
||||||
|
>> result.randomDataShortPtr
|
||||||
|
>> result.randomDataBytePtr
|
||||||
|
>> result.randomDataIntPtr
|
||||||
|
>> result.longIndiciesPtr
|
||||||
|
>> result.notificationsPtr
|
||||||
|
>> result.deltaPartsPtr;
|
||||||
|
|
||||||
|
// Read in x_anim file name
|
||||||
|
QString xAnimName;
|
||||||
|
char xAnimNameChar;
|
||||||
|
*aZoneFileStream >> xAnimNameChar;
|
||||||
|
while (xAnimNameChar != 0) {
|
||||||
|
result.name += xAnimNameChar;
|
||||||
|
*aZoneFileStream >> xAnimNameChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse x_anim index header
|
||||||
|
QVector<quint8> sectionLengths;
|
||||||
|
for (int i = 0; i < result.numframes; i++) {
|
||||||
|
quint8 sectionlength;
|
||||||
|
*aZoneFileStream >> sectionlength;
|
||||||
|
sectionLengths.push_back(sectionlength);
|
||||||
|
// Skip padding
|
||||||
|
aZoneFileStream->skipRawData(1);
|
||||||
|
}
|
||||||
|
// Skip unknown section
|
||||||
|
aZoneFileStream->skipRawData(2 * 8);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ParseAsset_MenuFile(QDataStream *aZoneFileStream) {
|
||||||
|
//MENU_FILE
|
||||||
|
Q_UNUSED(aZoneFileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ParseAsset_Weapon(QDataStream *aZoneFileStream) {
|
||||||
|
//WEAPON_FILE
|
||||||
|
Q_UNUSED(aZoneFileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ParseAsset_D3DBSP(QDataStream *aZoneFileStream) {
|
||||||
|
//D3DBSP_DUMP
|
||||||
|
Q_UNUSED(aZoneFileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static StringTable ParseAsset_StringTable(QDataStream *aZoneFileStream) {
|
||||||
|
StringTable result;
|
||||||
|
|
||||||
|
aZoneFileStream->skipRawData(4);
|
||||||
|
|
||||||
|
*aZoneFileStream
|
||||||
|
>> result.columnCount
|
||||||
|
>> result.rowCount;
|
||||||
|
|
||||||
|
// Todo fix this
|
||||||
|
result.columnCount = 0;
|
||||||
|
result.rowCount = 0;
|
||||||
|
|
||||||
|
aZoneFileStream->skipRawData(4);
|
||||||
|
|
||||||
|
QString stringTableName;
|
||||||
|
char stringTableNameChar;
|
||||||
|
*aZoneFileStream >> stringTableNameChar;
|
||||||
|
while (stringTableNameChar != 0) {
|
||||||
|
result.name += stringTableNameChar;
|
||||||
|
*aZoneFileStream >> stringTableNameChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<QString> tablePointers = QVector<QString>();
|
||||||
|
for (quint32 i = 0; i < result.rowCount; i++) {
|
||||||
|
QByteArray pointerData(4, Qt::Uninitialized);
|
||||||
|
aZoneFileStream->readRawData(pointerData.data(), 4);
|
||||||
|
tablePointers.push_back(pointerData.toHex());
|
||||||
|
|
||||||
|
aZoneFileStream->skipRawData(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const QString &pointerAddr : tablePointers) {
|
||||||
|
QString leadingContent = "";
|
||||||
|
if (pointerAddr == "FFFFFFFF") {
|
||||||
|
char leadingContentChar;
|
||||||
|
*aZoneFileStream >> leadingContentChar;
|
||||||
|
while (leadingContentChar != 0) {
|
||||||
|
leadingContent += leadingContentChar;
|
||||||
|
*aZoneFileStream >> leadingContentChar;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
leadingContent = pointerAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString content;
|
||||||
|
char contentChar;
|
||||||
|
*aZoneFileStream >> contentChar;
|
||||||
|
while (contentChar != 0) {
|
||||||
|
content += contentChar;
|
||||||
|
*aZoneFileStream >> contentChar;
|
||||||
|
}
|
||||||
|
QPair<QString, QString> tableEntry = QPair<QString, QString>();
|
||||||
|
tableEntry.first = leadingContent;
|
||||||
|
tableEntry.second = content;
|
||||||
|
//if (!mStrTableMap.contains(stringTableName)) {
|
||||||
|
// mStrTableMap[stringTableName] = QVector<QPair<QString, QString>>();
|
||||||
|
//}
|
||||||
|
//mStrTableMap[stringTableName].push_back(tableEntry);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ZFPARSER_H
|
||||||