initial test code
This commit is contained in:
commit
0df35fc0c9
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
build
|
55
CMakeLists.txt
Normal file
55
CMakeLists.txt
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
cmake_minimum_required(VERSION 3.14)
|
||||||
|
cmake_policy(SET CMP0046 NEW)
|
||||||
|
cmake_policy(SET CMP0063 NEW)
|
||||||
|
cmake_policy(SET CMP0071 NEW)
|
||||||
|
|
||||||
|
project(agw-quake-tools CXX)
|
||||||
|
|
||||||
|
if(NOT MSVC)
|
||||||
|
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wextra -Werror")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
macro(make_qt_project TARGET_NAME)
|
||||||
|
target_include_directories(${TARGET_NAME} PUBLIC source)
|
||||||
|
|
||||||
|
set_target_properties(
|
||||||
|
${TARGET_NAME}
|
||||||
|
PROPERTIES
|
||||||
|
CXX_STANDARD 17
|
||||||
|
CXX_STANDARD_REQUIRED ON
|
||||||
|
AUTOMOC ON
|
||||||
|
AUTOUIC ON
|
||||||
|
AUTORCC ON)
|
||||||
|
|
||||||
|
target_link_libraries(${TARGET_NAME} Qt5::Core Qt5::Gui Qt5::Widgets)
|
||||||
|
|
||||||
|
target_compile_definitions(
|
||||||
|
${TARGET_NAME}
|
||||||
|
PUBLIC
|
||||||
|
-DQT_DEPRECATED_WARNINGS
|
||||||
|
-DQT_STRICT_ITERATORS
|
||||||
|
-DQT_NO_NARROWING_CONVERSIONS_IN_CONNECT)
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
find_package(
|
||||||
|
Qt5 5.13.0
|
||||||
|
CONFIG
|
||||||
|
REQUIRED
|
||||||
|
COMPONENTS Core Widgets Gui)
|
||||||
|
|
||||||
|
add_executable(
|
||||||
|
quam WIN32
|
||||||
|
source/common.h
|
||||||
|
source/quam/main.cc
|
||||||
|
source/quam/main_window.cc
|
||||||
|
source/quam/main_window.h
|
||||||
|
source/quam/main_window.ui
|
||||||
|
source/quam/pak.cc
|
||||||
|
source/quam/pak.h)
|
||||||
|
|
||||||
|
make_qt_project(quam)
|
||||||
|
|
||||||
|
install(TARGETS quam)
|
||||||
|
|
||||||
|
## EOF
|
125
LICENSE
Normal file
125
LICENSE
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
To the extent possible under law, I, Alison Watson, and all other contributors
|
||||||
|
to quake-tools, have waived all copyright and related or neighboring rights to
|
||||||
|
this Document as described by the Creative Commons Zero license as follows:
|
||||||
|
|
||||||
|
Creative Commons Legal Code
|
||||||
|
|
||||||
|
CC0 1.0 Universal
|
||||||
|
|
||||||
|
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||||
|
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
||||||
|
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||||
|
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||||
|
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
||||||
|
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
||||||
|
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
||||||
|
HEREUNDER.
|
||||||
|
|
||||||
|
Statement of Purpose
|
||||||
|
|
||||||
|
The laws of most jurisdictions throughout the world automatically confer
|
||||||
|
exclusive Copyright and Related Rights (defined below) upon the creator
|
||||||
|
and subsequent owner(s) (each and all, an "owner") of an original work of
|
||||||
|
authorship and/or a database (each, a "Work").
|
||||||
|
|
||||||
|
Certain owners wish to permanently relinquish those rights to a Work for
|
||||||
|
the purpose of contributing to a commons of creative, cultural and
|
||||||
|
scientific works ("Commons") that the public can reliably and without fear
|
||||||
|
of later claims of infringement build upon, modify, incorporate in other
|
||||||
|
works, reuse and redistribute as freely as possible in any form whatsoever
|
||||||
|
and for any purposes, including without limitation commercial purposes.
|
||||||
|
These owners may contribute to the Commons to promote the ideal of a free
|
||||||
|
culture and the further production of creative, cultural and scientific
|
||||||
|
works, or to gain reputation or greater distribution for their Work in
|
||||||
|
part through the use and efforts of others.
|
||||||
|
|
||||||
|
For these and/or other purposes and motivations, and without any
|
||||||
|
expectation of additional consideration or compensation, the person
|
||||||
|
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
||||||
|
is an owner of Copyright and Related Rights in the Work, voluntarily
|
||||||
|
elects to apply CC0 to the Work and publicly distribute the Work under its
|
||||||
|
terms, with knowledge of his or her Copyright and Related Rights in the
|
||||||
|
Work and the meaning and intended legal effect of CC0 on those rights.
|
||||||
|
|
||||||
|
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||||
|
protected by copyright and related or neighboring rights ("Copyright and
|
||||||
|
Related Rights"). Copyright and Related Rights include, but are not
|
||||||
|
limited to, the following:
|
||||||
|
|
||||||
|
i. the right to reproduce, adapt, distribute, perform, display,
|
||||||
|
communicate, and translate a Work;
|
||||||
|
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||||
|
iii. publicity and privacy rights pertaining to a person's image or
|
||||||
|
likeness depicted in a Work;
|
||||||
|
iv. rights protecting against unfair competition in regards to a Work,
|
||||||
|
subject to the limitations in paragraph 4(a), below;
|
||||||
|
v. rights protecting the extraction, dissemination, use and reuse of data
|
||||||
|
in a Work;
|
||||||
|
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||||
|
European Parliament and of the Council of 11 March 1996 on the legal
|
||||||
|
protection of databases, and under any national implementation
|
||||||
|
thereof, including any amended or successor version of such
|
||||||
|
directive); and
|
||||||
|
vii. other similar, equivalent or corresponding rights throughout the
|
||||||
|
world based on applicable law or treaty, and any national
|
||||||
|
implementations thereof.
|
||||||
|
|
||||||
|
2. Waiver. To the greatest extent permitted by, but not in contravention
|
||||||
|
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
||||||
|
irrevocably and unconditionally waives, abandons, and surrenders all of
|
||||||
|
Affirmer's Copyright and Related Rights and associated claims and causes
|
||||||
|
of action, whether now known or unknown (including existing as well as
|
||||||
|
future claims and causes of action), in the Work (i) in all territories
|
||||||
|
worldwide, (ii) for the maximum duration provided by applicable law or
|
||||||
|
treaty (including future time extensions), (iii) in any current or future
|
||||||
|
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
||||||
|
including without limitation commercial, advertising or promotional
|
||||||
|
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
||||||
|
member of the public at large and to the detriment of Affirmer's heirs and
|
||||||
|
successors, fully intending that such Waiver shall not be subject to
|
||||||
|
revocation, rescission, cancellation, termination, or any other legal or
|
||||||
|
equitable action to disrupt the quiet enjoyment of the Work by the public
|
||||||
|
as contemplated by Affirmer's express Statement of Purpose.
|
||||||
|
|
||||||
|
3. Public License Fallback. Should any part of the Waiver for any reason
|
||||||
|
be judged legally invalid or ineffective under applicable law, then the
|
||||||
|
Waiver shall be preserved to the maximum extent permitted taking into
|
||||||
|
account Affirmer's express Statement of Purpose. In addition, to the
|
||||||
|
extent the Waiver is so judged Affirmer hereby grants to each affected
|
||||||
|
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
||||||
|
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
||||||
|
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
||||||
|
maximum duration provided by applicable law or treaty (including future
|
||||||
|
time extensions), (iii) in any current or future medium and for any number
|
||||||
|
of copies, and (iv) for any purpose whatsoever, including without
|
||||||
|
limitation commercial, advertising or promotional purposes (the
|
||||||
|
"License"). The License shall be deemed effective as of the date CC0 was
|
||||||
|
applied by Affirmer to the Work. Should any part of the License for any
|
||||||
|
reason be judged legally invalid or ineffective under applicable law, such
|
||||||
|
partial invalidity or ineffectiveness shall not invalidate the remainder
|
||||||
|
of the License, and in such case Affirmer hereby affirms that he or she
|
||||||
|
will not (i) exercise any of his or her remaining Copyright and Related
|
||||||
|
Rights in the Work or (ii) assert any associated claims and causes of
|
||||||
|
action with respect to the Work, in either case contrary to Affirmer's
|
||||||
|
express Statement of Purpose.
|
||||||
|
|
||||||
|
4. Limitations and Disclaimers.
|
||||||
|
|
||||||
|
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||||
|
surrendered, licensed or otherwise affected by this document.
|
||||||
|
b. Affirmer offers the Work as-is and makes no representations or
|
||||||
|
warranties of any kind concerning the Work, express, implied,
|
||||||
|
statutory or otherwise, including without limitation warranties of
|
||||||
|
title, merchantability, fitness for a particular purpose, non
|
||||||
|
infringement, or the absence of latent or other defects, accuracy, or
|
||||||
|
the present or absence of errors, whether or not discoverable, all to
|
||||||
|
the greatest extent permissible under applicable law.
|
||||||
|
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||||
|
that may apply to the Work or any use thereof, including without
|
||||||
|
limitation any person's Copyright and Related Rights in the Work.
|
||||||
|
Further, Affirmer disclaims responsibility for obtaining any necessary
|
||||||
|
consents, permissions or other rights required for any use of the
|
||||||
|
Work.
|
||||||
|
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||||
|
party to this document and has no duty or obligation with respect to
|
||||||
|
this CC0 or use of the Work.
|
76
source/common.h
Normal file
76
source/common.h
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QtEndian>
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
#include <ios>
|
||||||
|
#include <iostream>
|
||||||
|
#include <istream>
|
||||||
|
#include <iterator>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
static inline QString trMain(char const *sourceText,
|
||||||
|
char const *disambiguation = nullptr,
|
||||||
|
int n = -1) {
|
||||||
|
return QCoreApplication::translate("main", sourceText, disambiguation, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static inline T readLE(std::istream &st) {
|
||||||
|
std::array<char, sizeof(T)> b;
|
||||||
|
st.read(b.data(), b.size());
|
||||||
|
return qFromLittleEndian<T>(b.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static inline T readBE(std::istream &st) {
|
||||||
|
std::array<char, sizeof(T)> b;
|
||||||
|
st.read(b.data(), b.size());
|
||||||
|
return qFromBigEndian<T>(b.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t N>
|
||||||
|
static inline std::array<char, N> readBytes(std::istream &st) {
|
||||||
|
std::array<char, N> b;
|
||||||
|
st.read(b.data(), b.size());
|
||||||
|
return std::move(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename It>
|
||||||
|
static inline std::string escapeText(It begin, It end) {
|
||||||
|
std::stringstream out;
|
||||||
|
out << std::hex << std::uppercase;
|
||||||
|
for(auto it = begin; it != end; ++it) {
|
||||||
|
unsigned char c = *it;
|
||||||
|
switch(c) {
|
||||||
|
case '"': out << "\\\""; break;
|
||||||
|
case '\0': out << "\\0"; break;
|
||||||
|
case '\\': out << "\\\\"; break;
|
||||||
|
case '\a': out << "\\a"; break;
|
||||||
|
case '\b': out << "\\b"; break;
|
||||||
|
case '\f': out << "\\f"; break;
|
||||||
|
case '\n': out << "\\n"; break;
|
||||||
|
case '\r': out << "\\r"; break;
|
||||||
|
case '\t': out << "\\t"; break;
|
||||||
|
case '\v': out << "\\v"; break;
|
||||||
|
default:
|
||||||
|
if(c >= ' ' && c <= '~') {
|
||||||
|
out << c;
|
||||||
|
} else {
|
||||||
|
out << "\\x" << int(c);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// EOF
|
59
source/quam/main.cc
Normal file
59
source/quam/main.cc
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
#include "common.h"
|
||||||
|
#include "quam/main_window.h"
|
||||||
|
#include "quam/pak.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QCommandLineParser>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
|
||||||
|
static void setupAppl(QCoreApplication &appl) {
|
||||||
|
appl.setApplicationName("QuAM!");
|
||||||
|
appl.setApplicationVersion("1.0");
|
||||||
|
appl.setOrganizationDomain("greyserv.net");
|
||||||
|
appl.setOrganizationName("Project Golan");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int modeGui(int argc, char *argv[]) {
|
||||||
|
QApplication appl{argc, argv};
|
||||||
|
setupAppl(appl);
|
||||||
|
MainWindow win;
|
||||||
|
win.show();
|
||||||
|
return appl.exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int modeText(int argc, char *argv[]) {
|
||||||
|
QCoreApplication appl{argc, argv};
|
||||||
|
setupAppl(appl);
|
||||||
|
|
||||||
|
QCommandLineParser par;
|
||||||
|
|
||||||
|
par.setApplicationDescription("Quake Archive Manager");
|
||||||
|
par.setSingleDashWordOptionMode(
|
||||||
|
QCommandLineParser::ParseAsCompactedShortOptions);
|
||||||
|
|
||||||
|
par.addHelpOption();
|
||||||
|
par.addVersionOption();
|
||||||
|
|
||||||
|
QCommandLineOption fileNameOpt{QStringList{"f", "file"},
|
||||||
|
trMain("Open the archive <file>."),
|
||||||
|
trMain("file")};
|
||||||
|
par.addOption(fileNameOpt);
|
||||||
|
|
||||||
|
par.process(appl);
|
||||||
|
|
||||||
|
auto fileName = par.value(fileNameOpt).toStdString();
|
||||||
|
std::ifstream st{fileName, std::ios_base::in | std::ios_base::binary};
|
||||||
|
readPakFile(st);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if(argc == 0) {
|
||||||
|
return modeGui(argc, argv);
|
||||||
|
} else {
|
||||||
|
return modeText(argc, argv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EOF
|
15
source/quam/main_window.cc
Normal file
15
source/quam/main_window.cc
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#include "common.h"
|
||||||
|
#include "quam/main_window.h"
|
||||||
|
#include "quam/pak.h"
|
||||||
|
|
||||||
|
MainWindow::MainWindow(QWidget *parent) :
|
||||||
|
QMainWindow{parent},
|
||||||
|
Ui::MainWindow{}
|
||||||
|
{
|
||||||
|
setupUi(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::openTest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// EOF
|
18
source/quam/main_window.h
Normal file
18
source/quam/main_window.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "quam/ui_main_window.h"
|
||||||
|
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class MainWindow : public QMainWindow, private Ui::MainWindow {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MainWindow(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void openTest();
|
||||||
|
};
|
||||||
|
|
||||||
|
// EOF
|
67
source/quam/main_window.ui
Normal file
67
source/quam/main_window.ui
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MainWindow</class>
|
||||||
|
<widget class="QMainWindow" name="MainWindow">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>640</width>
|
||||||
|
<height>480</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Quam!</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="centralwidget">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButton">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>PushButton</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenuBar" name="menubar">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>640</width>
|
||||||
|
<height>29</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QStatusBar" name="statusbar"/>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>pushButton</sender>
|
||||||
|
<signal>clicked()</signal>
|
||||||
|
<receiver>MainWindow</receiver>
|
||||||
|
<slot>openTest()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>59</x>
|
||||||
|
<y>53</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>319</x>
|
||||||
|
<y>239</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
<slots>
|
||||||
|
<slot>openTest()</slot>
|
||||||
|
</slots>
|
||||||
|
</ui>
|
76
source/quam/pak.cc
Normal file
76
source/quam/pak.cc
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
#include "common.h"
|
||||||
|
#include "quam/pak.h"
|
||||||
|
|
||||||
|
struct PakHeader {
|
||||||
|
quint32 dirOffset;
|
||||||
|
quint32 dirNum;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PakEntry {
|
||||||
|
std::string name;
|
||||||
|
QByteArray data;
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr quint32 sizeOfPakEntry = 64;
|
||||||
|
|
||||||
|
static PakHeader readPakHeader(std::istream &st) {
|
||||||
|
auto magic = readBytes<4>(st);
|
||||||
|
|
||||||
|
if(magic != std::array{'P', 'A', 'C', 'K'}) {
|
||||||
|
throw std::runtime_error("not a pak file (invalid magic number)");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto dirOffset = readLE<quint32>(st);
|
||||||
|
auto dirSize = readLE<quint32>(st);
|
||||||
|
|
||||||
|
if(dirSize % sizeOfPakEntry != 0) {
|
||||||
|
throw std::runtime_error("invalid directory size");
|
||||||
|
}
|
||||||
|
|
||||||
|
PakHeader hdr;
|
||||||
|
hdr.dirOffset = dirOffset;
|
||||||
|
hdr.dirNum = dirSize / sizeOfPakEntry;
|
||||||
|
return hdr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PakEntry readPakEntry(std::istream &st) {
|
||||||
|
auto entName = readBytes<56>(st);
|
||||||
|
auto entOffset = readLE<quint32>(st);
|
||||||
|
auto entSize = readLE<quint32>(st);
|
||||||
|
|
||||||
|
auto pos = st.tellg();
|
||||||
|
|
||||||
|
st.seekg(entOffset);
|
||||||
|
|
||||||
|
QByteArray bytes;
|
||||||
|
bytes.resize(entSize);
|
||||||
|
st.read(bytes.data(), entSize);
|
||||||
|
|
||||||
|
st.seekg(pos);
|
||||||
|
|
||||||
|
auto zero = std::find(entName.cbegin(), entName.cend(), '\0');
|
||||||
|
|
||||||
|
std::string out;
|
||||||
|
std::copy(entName.cbegin(), zero, std::back_inserter(out));
|
||||||
|
|
||||||
|
PakEntry ent;
|
||||||
|
ent.name = std::move(out);
|
||||||
|
ent.data = std::move(bytes);
|
||||||
|
return ent;
|
||||||
|
}
|
||||||
|
|
||||||
|
PakFile readPakFile(std::istream &st) {
|
||||||
|
auto hdr = readPakHeader(st);
|
||||||
|
st.seekg(hdr.dirOffset);
|
||||||
|
|
||||||
|
PakFile pak;
|
||||||
|
|
||||||
|
for(quint32 i = 0; i < hdr.dirNum; i++) {
|
||||||
|
auto ent = readPakEntry(st);
|
||||||
|
pak.emplace(std::move(ent.name), std::move(ent.data));
|
||||||
|
}
|
||||||
|
|
||||||
|
return pak;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EOF
|
8
source/quam/pak.h
Normal file
8
source/quam/pak.h
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class PakFile : public std::map<std::string, QByteArray> {
|
||||||
|
};
|
||||||
|
|
||||||
|
PakFile readPakFile(std::istream &st);
|
||||||
|
|
||||||
|
// EOF
|
Loading…
Reference in New Issue
Block a user