TS_RA2_Mission_Editor_sourcecode_23.02.2023_1

TS_RA2_Mission_Editor_sourcecode_23.02.2023_1
This commit is contained in:
brbarnesEA 2024-03-05 11:56:45 -08:00
commit a547a31a37
377 changed files with 90136 additions and 0 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,227 @@
/*
FinalSun/FinalAlert 2 Mission Editor
Copyright (C) 1999-2024 Electronic Arts, Inc.
Authored by Matthias Wagner
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
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
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef FSUNPACKLIB_INCLUDED
#define FSUNPACKLIB_INCLUDED
#include <windows.h>
#include <ddraw.h>
#include <memory>
#include <vector>
#include <string>
#include "Vec3.h"
class VoxelNormalTables;
typedef DWORD HMIXFILE;
typedef DWORD HTSPALETTE;
struct SHPHEADER
{
__int16 zero;
__int16 cx;
__int16 cy;
__int16 c_images;
};
struct SHPIMAGEHEADER
{
__int16 x;
__int16 y;
__int16 cx;
__int16 cy;
__int32 compression;
__int32 unknown;
__int32 zero;
__int32 offset;
};
namespace FSunPackLib
{
enum Game
{
RA2,
RA2_YR,
TS,
TS_FS
};
enum class VoxelNormalClass: std::uint8_t
{
Unknown = 0,
Gen1 = 1,
TS = 2,
Gen3 = 3,
RA2 = 4,
};
extern "C" extern bool _DEBUG_EnableLogs; // only useable in debug library builds
extern "C" extern bool _DEBUG_EnableBreakpoints; // only useable in debug library builds
struct FSPL_EXCEPTION
{
int err_code;
};
extern "C" extern int last_succeeded_operation;
class ColorConverterImpl;
class ColorConverter
{
public:
ColorConverter(const DDPIXELFORMAT& pf);
int GetColor(int a, int r, int g, int b) const;
int GetColor(int r, int g, int b) const;
int GetColor(COLORREF col) const;
private:
std::shared_ptr<ColorConverterImpl> m_impl;
};
// base 64
/*
Converts hex data to Base64 data.
sp - source poINTer
len - length of hex data
Returns a poINTer to the base64 data. Caller must free this memory.
*/
BYTE* EncodeBase64(BYTE* sp, UINT len);
/*
Converts Base64 data to hex data.
sp - source poINTer
dp - dest buffer (should be as large as sp)
Returns the hex data length
*/
int DecodeBase64(const char* sp, std::vector<BYTE>& dest);
// format 80
/*
Pack to a simple format 80 pack like Overlay & OverlayData-Pack
sp - source poINTer (should be the 262144 bytes for overlay & overlaydata)
len - length of the source data (should be 262144)
nSections - section count. should be 32
dest - poINTer to dest poINTer. Function allocates memory, caller must free this memory.
Returns the length of the packed data.
*/
INT EncodeF80(BYTE* sp, UINT len, UINT nSections, BYTE** dest);
/*
Extracts a simple format 80 pack like the Overlay & OverlayData-Pack
Note that it extracts a whole pack, not just a simple section.
In order to simply decode/encode Format80, you should use ConvertFromF80 and ConvertToF80
sp - source poINTer
SourceLength - length of the source
dp - dest buffer
max_size - maximum allowed destination size
*/
bool DecodeF80(const BYTE* sp, UINT SourceLength, std::vector<BYTE>& dp, std::size_t max_size);
// IsoMapPack5
/*
Pack IsoMapPack5.
sp - source poINTer
SourceLength - length of source
dp - destination buffer
Returns size of packed data
*/
UINT EncodeIsoMapPack5(BYTE* sp, UINT SourceLength, BYTE** dp);
/*
Unpack IsoMapPack5.
sp - source poINTer
SourceLength - length of source
dp - destination buffer
*/
UINT DecodeIsoMapPack5(BYTE* sp, UINT SourceLength, BYTE* dp, HWND hProgressBar, BOOL bDebugMode);
BOOL XCC_Initialize(BOOL bUseCache);
HMIXFILE XCC_OpenMix(LPCTSTR szMixFile, HMIXFILE hOwner);
BOOL XCC_GetMixName(HMIXFILE hOwner, std::string& sMixFile);
BOOL XCC_DoesFileExist(LPCSTR szFile, HMIXFILE hOwner);
BOOL XCC_CloseMix(HMIXFILE hMixFile);
BOOL XCC_ExtractFile(const std::string& szFilename, const std::string& szSaveTo, HMIXFILE hOwner);
BOOL XCC_ExtractFile(LPCSTR szFilename, LPCSTR szSaveTo, HMIXFILE hOwner);
BOOL XCC_GetSHPHeader(SHPHEADER* pHeader);
/*
Returns the SHP image header of a image in a SHP file
*/
BOOL XCC_GetSHPImageHeader(int iImageIndex, SHPIMAGEHEADER* pImageHeader);
BOOL SetCurrentTMP(LPCSTR szTMP, HMIXFILE hOwner);
BOOL SetCurrentSHP(LPCSTR szSHP, HMIXFILE hOwner);
BOOL XCC_GetTMPTileInfo(int iTile, POINT* lpPos, int* lpWidth, int* lpHeight, BYTE* lpDirection, BYTE* lpTileHeight, BYTE* lpTileType, RGBTRIPLE* lpRgbLeft, RGBTRIPLE* lpRgbRight);
BOOL XCC_GetTMPInfo(RECT* lpRect, int* iTileCount, int* iTilesX, int* iTilesY);
BOOL LoadTMPImageInSurface(IDirectDraw4* pdd, int iStart, int iCount, LPDIRECTDRAWSURFACE4* pdds, HTSPALETTE hPalette);
BOOL LoadTMPImage(int iStart, int iCount, BYTE** lpTileArray);
BOOL LoadSHPImageInSurface(IDirectDraw4* pdd, HTSPALETTE hPalette, int iImageIndex, int iCount, LPDIRECTDRAWSURFACE4* pdds);
BOOL LoadSHPImage(int iImageIndex, int iCount, BYTE** lpPics);
BOOL LoadSHPImage(int iImageIndex, std::vector<BYTE>& pic);
HTSPALETTE LoadTSPalette(LPCSTR szPalette, HMIXFILE hPaletteOwner);
HTSPALETTE LoadTSPalette(const std::string& szPalette, HMIXFILE hPaletteOwner);
BOOL SetTSPaletteEntry(HTSPALETTE hPalette, BYTE bIndex, RGBTRIPLE* rgb, RGBTRIPLE* orig);
BOOL SetCurrentVXL(LPCSTR lpVXLFile, HMIXFILE hMixFile);
BOOL GetVXLInfo(int* cSections);
BOOL GetVXLSectionInfo(int section, VoxelNormalClass& normalClass);
BOOL LoadVXLImageInSurface(const VoxelNormalTables& normalTables, Vec3f lightDirection, IDirectDraw4* pdd, int iStart, int iCount, Vec3f rotation, Vec3f modelOffset, LPDIRECTDRAWSURFACE4* pdds, HTSPALETTE hPalette, int* lpXCenter = NULL, int* lpYCenter = NULL, int ZAdjust = 0, int* lpXCenterZMax = NULL, int* lpYCenterZMax = NULL, int i3dCenterX = -1, int i3dCenterY = -1);
// modelOffset is applied before VXL/HVA translates and scales and before model-to-world rotation
BOOL LoadVXLImage(const VoxelNormalTables& normalTables, Vec3f lightDirection, Vec3f rotation, Vec3f modelOffset, std::vector<BYTE>& image, std::vector<BYTE>& lighting, int* lpXCenter = NULL, int* lpYCenter = NULL, int ZAdjust = 0, int* lpXCenterZMax = NULL, int* lpYCenterZMax = NULL, int i3dCenterX = -1, int i3dCenterY = -1, RECT* vxlrect = NULL);
BOOL WriteMixFile(LPCTSTR lpMixFile, LPCSTR* lpFiles, DWORD dwFileCount, Game game);
HRESULT SetColorKey(IDirectDrawSurface4* pDDS, COLORREF rgb);
};
#endif

321
MissionEditorPackLib/Vec3.h Normal file
View file

@ -0,0 +1,321 @@
/*
FinalSun/FinalAlert 2 Mission Editor
Copyright (C) 1999-2024 Electronic Arts, Inc.
Authored by Matthias Wagner
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
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
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <cassert>
template<class T>
class Vec3
{
public:
Vec3() = default;
Vec3(T x, T y, T z) : v{ x, y, z }
{
}
Vec3(T v_[3]) : v{ v_[0], v_[1], v_[2] }
{
}
T& operator[](unsigned int i) {
assert(i < 3);
return v[i];
}
const T& operator[](unsigned int i) const {
assert(i < 3);
return v[i];
}
inline T dot(const Vec3& other) const {
return v[0] * other.v[0] + v[1] * other.v[1] + v[2] * other.v[2];
}
inline T length() const
{
return sqrt(squaredLength());
}
inline T squaredLength() const
{
return dot(*this);
}
inline Vec3& normalize()
{
T invL = T(1) / length();
v[0] *= invL;
v[1] *= invL;
v[2] *= invL;
return *this;
}
inline Vec3& negate()
{
v[0] = -v[0];
v[1] = -v[1];
v[2] = -v[2];
return *this;
}
inline Vec3& inverse()
{
v[0] = T(1) / v[0];
v[1] = T(1) / v[1];
v[2] = T(1) / v[2];
return *this;
}
inline Vec3& minimum(const Vec3& v2)
{
v[0] = min(v[0], v2[0]);
v[1] = min(v[1], v2[1]);
v[2] = min(v[2], v2[2]);
return *this;
}
inline Vec3& maximum(const Vec3& v2)
{
v[0] = max(v[0], v2[0]);
v[1] = max(v[1], v2[1]);
v[2] = max(v[2], v2[2]);
return *this;
}
inline Vec3& operator *=(const Vec3& v2) {
v[0] *= v2[0];
v[1] *= v2[1];
v[2] *= v2[2];
return *this;
}
inline Vec3& operator *=(const T scale) {
v[0] *= scale;
v[1] *= scale;
v[2] *= scale;
return *this;
}
inline Vec3& operator /=(const Vec3& v2) {
v[0] /= v2[0];
v[1] /= v2[1];
v[2] /= v2[2];
return *this;
}
inline Vec3& operator /=(const T scale) {
v[0] /= scale;
v[1] /= scale;
v[2] /= scale;
return *this;
}
inline Vec3& operator +=(const Vec3& other) {
v[0] += other.v[0];
v[1] += other.v[1];
v[2] += other.v[2];
return *this;
}
inline Vec3& operator -=(const Vec3& other) {
v[0] -= other.v[0];
v[1] -= other.v[1];
v[2] -= other.v[2];
return *this;
}
inline bool equals(const Vec3& other, T epsilon=T(0.001))
{
return fabs(v[0] - other.v[0]) <= epsilon && fabs(v[1] - other.v[1]) <= epsilon && fabs(v[2] - other.v[2]) <= epsilon;
}
T x() const { return v[0]; }
T y() const { return v[1]; }
T z() const { return v[2]; }
T v[3] = { 0, 0, 0 };
};
template< class T>
inline Vec3<T> operator+(const Vec3<T>& l, const Vec3<T>& r)
{
auto res = l;
res += r;
return res;
}
template< class T>
inline Vec3<T> operator-(const Vec3<T>& l, const Vec3<T>& r)
{
auto res = l;
res -= r;
return res;
}
template< class T>
inline Vec3<T> normalize(Vec3<T> v)
{
return v.normalize();
}
template< class T>
inline Vec3<T> negate(Vec3<T> v)
{
return v.negate();
}
template< class T>
inline Vec3<T> inverse(Vec3<T> v)
{
return v.inverse();
}
template< class T>
inline Vec3<T> minimum(Vec3<T> v, const Vec3<T>& v2)
{
v.minimum(v2);
return v;
}
template< class T>
inline Vec3<T> maximum(Vec3<T> v, const Vec3<T>& v2)
{
v.maximum(v2);
return v;
}
template< class T>
inline Vec3<T> operator /(Vec3<T> v, T scale)
{
v /= scale;
return v;
}
template< class T>
inline Vec3<T> operator *(Vec3<T> v, Vec3<T> v2)
{
v *= v2;
return v;
}
template< class T>
inline Vec3<T> operator /(Vec3<T> v, Vec3<T> v2)
{
v /= v2;
return v;
}
template< class T>
inline Vec3<T> operator *(Vec3<T> v, T scale)
{
v *= scale;
return v;
}
typedef Vec3<float> Vec3f;
template<class T>
class Matrix3_4
{
public:
Matrix3_4(const T (&m_)[3][4])
{
for (int row = 0; row < 3; ++row)
{
for (int col = 0; col < 4; ++col)
{
m[row][col] = m_[row][col];
}
}
}
Matrix3_4(const T* m_)
{
for (int row = 0; row < 3; ++row)
{
for (int col = 0; col < 4; ++col)
{
m[row][col] = m_[row * 4 + col];
}
}
}
Vec3<T> operator *(const Vec3<T> v) const
{
auto x = v[0];
auto y = v[1];
auto z = v[2];
return Vec3<T>(
x * m[0][0] + y * m[0][1] + z * m[0][2] + m[0][3],
x * m[1][0] + y * m[1][1] + z * m[1][2] + m[1][3],
x * m[2][0] + y * m[2][1] + z * m[2][2] + m[2][3]
);
}
Matrix3_4& scaledColumn(unsigned int iColumn, T scale)
{
assert(iColumn < 4);
m[0][iColumn] *= scale;
m[1][iColumn] *= scale;
m[2][iColumn] *= scale;
return *this;
}
Matrix3_4 scaleColumn(unsigned int iColumn, T scale) const
{
assert(iColumn < 4);
Matrix3_4 copy(*this);
copy.m[0][iColumn] *= scale;
copy.m[1][iColumn] *= scale;
copy.m[2][iColumn] *= scale;
return copy;
}
Matrix3_4& setColumn(unsigned int iColumn, const Vec3<T>& v)
{
assert(iColumn < 4);
m[0][iColumn] = v[0];
m[1][iColumn] = v[1];
m[2][iColumn] = v[2];
return *this;
}
Vec3f getColumn(unsigned int iColumn) const
{
assert(iColumn < 4);
return Vec3f(m[0][iColumn], m[1][iColumn], m[2][iColumn]);
}
static Matrix3_4 translation(const Vec3<T> v)
{
return Matrix3_4({ {1, 0, 0, v.x()}, {0, 1, 0, v.y()}, {0, 0, 1, v.z()}});
}
static Matrix3_4 scale(const Vec3<T> v)
{
return Matrix3_4({ {v.x(), 0, 0, 0}, {0, v.y(), 0, 0}, {0, 0, v.z(), 0}});
}
public:
T m[3][4] = { {1, 0, 0, 1}, {0, 1, 0, 1}, {0, 0, 1, 1}};
};
typedef Matrix3_4<float> Matrix3_4f;

View file

@ -0,0 +1,103 @@
/*
FinalSun/FinalAlert 2 Mission Editor
Copyright (C) 1999-2024 Electronic Arts, Inc.
Authored by Matthias Wagner
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
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
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "stdafx.h"
#include "VoxelNormals.h"
#include <array>
#include <math.h>
template<class T>
T read(std::istream& s)
{
T t;
auto p1 = s.tellg();
auto n = sizeof(T);
s.read(reinterpret_cast<char*>(&t), sizeof(T));
auto p2 = s.tellg();
auto p3 = p2 - p1;
//s >> t;
return t;
};
template<class T, int N>
std::array<T, N> read(std::istream& s)
{
std::array<T, N> t;
s.read(reinterpret_cast<char*>(t.data()), sizeof(T) * N);
return t;
};
VoxelNormalTable::VoxelNormalTable(std::istream& f)
{
auto oldEx = f.exceptions();
f.exceptions(f.failbit | f.badbit);
try
{
load(f);
}
catch (const std::exception& ex)
{
f.exceptions(oldEx);
throw ex;
}
}
void VoxelNormalTable::load(std::istream& f)
{
auto count = read<std::uint8_t>(f);
m_normals.clear();
m_normals.reserve(count);
for (auto i = 0; i < count; ++i)
{
auto v = read<float, 3>(f);
m_normals.push_back(Vec3f(v.data()));
}
}
VoxelNormalTables::VoxelNormalTables(std::istream& f)
{
auto oldEx = f.exceptions();
f.exceptions(f.failbit | f.badbit);
try
{
load(f);
}
catch(const std::exception& ex)
{
f.exceptions(oldEx);
throw ex;
}
}
void VoxelNormalTables::load(std::istream& f)
{
auto tableCount = read<std::uint8_t>(f);
for (std::uint32_t i = 0; i < tableCount; ++i)
{
auto normalClass = read<std::uint8_t>(f);
VoxelNormalTable table(f);
auto normalIndex = normalClass - 1;
m_tables.resize(std::max(m_tables.size(), static_cast<std::size_t>(normalClass)));
m_tables[normalIndex] = std::move(table);
}
}

View file

@ -0,0 +1,73 @@
/*
FinalSun/FinalAlert 2 Mission Editor
Copyright (C) 1999-2024 Electronic Arts, Inc.
Authored by Matthias Wagner
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
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
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <istream>
#include <vector>
#include "Vec3.h"
class VoxelNormalTable
{
public:
VoxelNormalTable() = default;
VoxelNormalTable(std::istream& f);
VoxelNormalTable(VoxelNormalTable&& other) noexcept = default;
VoxelNormalTable& operator=(const VoxelNormalTable& other) = default;
VoxelNormalTable& operator=(VoxelNormalTable&& other) noexcept = default;
Vec3f operator[] (unsigned int iNormal) const
{
return iNormal < m_normals.size() ? m_normals[iNormal] : Vec3f(0, 1, 0);
}
private:
void load(std::istream& f);
private:
std::vector<Vec3f> m_normals;
};
class VoxelNormalTables
{
public:
VoxelNormalTables() = default;
VoxelNormalTables(std::istream& f);
bool isValidTable(const std::uint8_t normalClass) const
{
return normalClass > 0 && normalClass <= m_tables.size();
}
// Returns the given normal table. Throws on invalid normalClass.
const VoxelNormalTable& getTable(const std::uint8_t normalClass) const
{
if (!isValidTable(normalClass))
throw std::range_error("Table for normal class does not exist");
return m_tables[normalClass - 1];
}
private:
void load(std::istream& f);
private:
// we use a vector instead of map for fast lookup
std::vector<VoxelNormalTable> m_tables;
};