-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathDaggerTool.h
444 lines (350 loc) · 11.6 KB
/
DaggerTool.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
/*************************************************************************************************\
*
* Filename: DaggerTool.h
* Purpose: Define all Daggerfall tool classes
* Version: 0.90
* Author: Gavin Clayton
*
* Last Updated: 29/08/2002
*
* Copyright 2002. Gavin Clayton. All Rights Reserved.
*
*
* NOTE:
* This information is derived from Dave Humphrey's DF hacking articles (http://www.m0use.net/~uesp).
* I have occasionally used different naming conventions and expanded based on my own investigations.
* I am deeply grateful to Dave Humphrey for his work. This would not be possible without him.
*
* If changes are made by you to this code, please log them below:
*
*
\*************************************************************************************************/
#if !defined(AFX_DAGGERTOOL_H__51AEEE08_B1F9_4F58_836D_78D53196E7CC__INCLUDED_)
#define AFX_DAGGERTOOL_H__51AEEE08_B1F9_4F58_836D_78D53196E7CC__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "DFTypes.h"
// Predefine classes
class CDaggerTool;
class DTXArchive;
class BSAArchive;
// Defines
#define DFTOOL_SOLIDTEXTURESIZE 32
// Helper macros
#define GetDFFP( d, s ) {long wp = s >> 8; float dp = (unsigned char)s / 1000.0f; d = float(wp) + dp;} // Convert a DF 24.8 fixed point number to a float
// Values used throughout CDaggerTool
enum
{
DTX_RECORDRLE = 0x1108,
DTX_IMAGERLE = 0x0108,
DTX_ROWENCODED = 0x8000,
CIF_COMPRESSED = 0x02,
CIF_WEAPONGROUP = 0x03,
BSA_RECORDTYPESHORT = 0x0200,
BSA_RECORDTYPELONG = 0x0100,
DFTOOL_NOPATCH = 0x8000,
};
// ARCH3D Version enum
enum {
ARCH3DVERSION_NONE,
ARCH3DVERSION_27,
ARCH3DVERSION_26,
ARCH3DVERSION_25,
ARCH3DVERSION_UNKNOWN,
};
// Single untransformed vertex for 3D objects
typedef struct _tagObjectVertex
{
D3DXVECTOR3 pos;
D3DXVECTOR3 normal;
FLOAT tu, tv;
} OBJVERTEX, *LPOBJVERTEX;
#define D3DFVF_OBJVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1)
// Single untransformed face
typedef struct _tagObjectFace
{
OBJVERTEX v0, v1, v2;
} OBJFACE, *LPOBJFACE;
// Define a single entry in the palette
typedef struct
{
unsigned char r, g, b;
} colour_t;
// Define the palette
typedef struct
{
colour_t colour[256];
} palette_t;
// Image Description for GetImage() method of DTXArchive
typedef struct _tagImageDescription
{
int cx; // Image width in pixels
int cy; // Image height in pixels
char pBuffer[DTXSIZE_IMAGE_BUFFER]; // Image buffer in R8G8B8 format
} DTX_IMAGEDESC, *LPDTX_IMAGEDESC;
// Image description for GetIMGDesc() method of CDaggerTool
typedef struct _tagIMG_IMAGEDESC
{
BOOL bHeader; // TRUE if file has header, otherwise FALSE
BOOL bPalette; // TRUE if file has palette, otherwise FALSE
DWORD dwWidth; // Image width in pixels
DWORD dwHeight; // Image height in pixels
DWORD dwBufferSize; // Size of required buffer in bytes
char szPalette[16]; // Name of required .PAL or .COL file
} IMG_IMAGEDESC, *LPIMG_IMAGEDESC;
// Archive description of CIF archive
typedef struct _tagCIF_ARCHIVEDESC
{
int nCurImage; // Current image
int nSubImage; // Subimage for weapon group formats
DWORD dwOffset; // Offset to this image
short Compression; // Specifies if compression is enabled
int cx; // Width of image
int cy; // Height of image
char pBuffer[CIFSIZE_IMAGE_BUFFER]; // Size of required buffer in bytes
BOOL bFinished; // TRUE if no more images can be found
BOOL bWeaponGroup; // TRUE if this is a weapon group image
BOOL bFirstInGroup; // TRUE if first image in group
} CIF_RECORDDESC, *LPCIF_RECORDDESC;
// Image description for BLOCKS.BSA automaps
typedef struct _BLKIMG_AUTOMAP
{
char pBuffer[BLKSIZE_IMAGE_BUFFER];
} BLKIMG_AUTOMAP, *LPBLKIMG_AUTOMAP;
// Base face UV values
typedef struct _FACEUV
{
float u0, v0;
float u1, v1;
float u2, v2;
float u3, v3;
} FACEUV, *LPFACEUV;
// Solid colour reference types
enum
{
DTX_NOTSOLID,
DTX_SOLIDA,
DTX_SOLIDB,
};
// Class to manage texture archives
class DTXArchive
{
public: // construction / destruction
friend class CDaggerTool;
DTXArchive();
virtual ~DTXArchive();
public: // methods
bool Create( LPCSTR pszArena2Path );
bool Open( LPCSTR pszArchive );
void Close();
bool IsOpen() {return m_bIsOpen;}
DWORD GetRecordCount() {return m_dwRecordCount;}
DWORD GetImageCount( DWORD dwRecord ) {
if ( m_nSolidType ) return 1;
return LPDTX_RECORDHEADER(m_pArchive + m_pRecordDirectory[dwRecord].nOffset)->nImages;
}
void GetImageRect( DWORD dwRecord, DWORD dwImage, LPRECT pRectOut ) {
pRectOut->left = 0;
pRectOut->top = 0;
if ( m_nSolidType ) {
pRectOut->right = DFTOOL_SOLIDTEXTURESIZE;
pRectOut->bottom = DFTOOL_SOLIDTEXTURESIZE;
}
else {
LPDTX_RECORDHEADER pRecordHeader = LPDTX_RECORDHEADER(m_pArchive + m_pRecordDirectory[dwRecord].nOffset);
pRectOut->right = pRecordHeader->cx;
pRectOut->bottom = pRecordHeader->cy;
}
}
BOOL GetImage( DWORD dwRecord, DWORD dwImage, LPDTX_IMAGEDESC pImageDescOut, char* pBitsOut = NULL, DWORD dwPitchInBytes = 0 );
const char* GetArchiveName() {return m_strArchiveName.GetBuffer(1);}
const char* GetArchiveDesc() {return m_strArchiveDesc.GetBuffer(1);}
private: // methods
void DecodeRLERows( char *pImageRaw, LPDTX_RECORDHEADER pRecordHeader, LPDTX_RLEROWDIRECTORY pRowDirectory, int cx, int cy );
private: // data
CString m_strArena2Path;
CString m_strArchiveName;
CString m_strArchiveDesc;
bool m_bIsCreated;
bool m_bIsOpen;
long m_nSolidType;
DWORD m_dwLength;
DWORD m_dwRecordCount;
char* m_pArchive;
palette_t m_Palette;
LPDTX_ARCHIVEHEADER m_pHeader;
LPDTX_RECORDDIRECTORY m_pRecordDirectory;
};
typedef DTXArchive* LPDTX_ARCHIVE;
// Class to manage CIF archives
class CIFArchive
{
public: // construction / destruction
friend class CDaggerTool;
CIFArchive();
virtual ~CIFArchive();
public: // methods
BOOL Open( LPCSTR pszPath, LPCSTR pszArchive );
void Close();
BOOL IsOpen() {return m_bIsOpen;}
BOOL GetImage( LPCIF_RECORDDESC pCIFArchDescInOut );
const char* GetArchiveName() {return m_strArchiveName.GetBuffer(1);}
DWORD GetLastRecordCount() {return m_dwLastRecordCount;}
private: // methods
BOOL DecodeImage( LPCIF_RECORDDESC pCIFArchDesc, char *pData );
void DecodeRLEImage( char *pImageRaw, int cx, int cy, char* pDataIn );
private: // data
DWORD m_dwLastRecordCount;
CString m_strArena2Path;
CString m_strArchiveName;
BOOL m_bIsOpen;
DWORD m_dwLength;
char* m_pArchive;
palette_t m_Palette;
};
typedef CIFArchive* LPCIF_ARCHIVE;
// Class to manage BSA archives
class BSAArchive
{
public: // construction / destruction
friend class CDaggerTool;
BSAArchive();
virtual ~BSAArchive();
public: // methods
bool Open( LPCSTR pszPath, LPCSTR pszArchive, BOOL bReadOnly = TRUE );
void Close();
bool IsOpen() {return m_bIsOpen;}
long GetRecordDirectoryType() {return m_nRecordDirectoryType;}
long GetRecordCount() {return m_nRecordCount;}
long GetRecordLength( long nRecord );
bool GetRecordDesc( long nRecord, char* pBufferOut, long nLength );
bool GetRecord( long nRecord, char* pDataOut, long nLength );
bool SetRecord( long nRecord, char *pDataIn, long nLength );
protected: // data
CString m_strArena2Path;
CFile m_bsaFile;
bool m_bIsOpen;
DWORD m_dwLength;
long m_nRecordCount;
long m_nRecordDirectoryType;
long m_nRecordDirectoryEntryLength;
BSA_ARCHIVEHEADER m_bsaHeader;
LPBSA_RECORDDIRECTORYLONG m_pRecordDirectoryLong;
LPBSA_RECORDDIRECTORYSHORT m_pRecordDirectoryShort;
};
// Class to manage ARCH3D.BSA
class BSAArch3D : public BSAArchive
{
public: // construction / destruction
friend class CDaggerTool;
BSAArch3D();
virtual ~BSAArch3D();
public: // methods
bool Open( LPCSTR pszPath, BOOL bReadOnly = TRUE );
void Close();
bool OpenObject( long nObject );
bool OpenObject( LPCSTR pszObjectID );
void CloseObject();
bool IsObjectOpen() {return m_bIsObjectOpen;}
long GetVersion() {return m_lVersion;}
float GetVersionAsFloat();
long GetFaceCount();
LPARCH3D_FACE GetFace( int nFace );
bool GetFaceTexture( LPARCH3D_FACE pFace, long* pnArchiveOut, long* pnRecordOut );
bool GetPureFaceUV( LPARCH3D_FACE pFace, LPSIZE uvOut );
bool PatchPointUV( LPARCH3D_FACE pFace, int nPoint, int U, int V );
long GetPointCount( LPARCH3D_FACE pFace );
bool GetPoint( LPARCH3D_FACE pFace, int nPoint, LPOBJVERTEX pvOut );
long GetCornerPoints( LPARCH3D_FACE pFace, int* pCornerBuffer = NULL, LPOBJVERTEX pPointBuffer = NULL );
bool ExportPureFace( LPARCH3D_FACE pFace, LPOBJVERTEX pvOut, int* pPointCountOut );
bool ExportTriangulatedFace( LPARCH3D_FACE pFace, LPOBJVERTEX pvOut, int* pPointCountOut, LPSIZE pSrcSize = NULL, LPRECT pSubRect = NULL );
bool SetPointUV( LPARCH3D_FACE pFace, int nPoint, short u, short v );
bool SetFaceUV( LPARCH3D_FACE pFace, long nCornerCount, LPOBJVERTEX pCornerVertexBuffer, LPSIZE pSrcSize, LPRECT pSubRect );
bool SetFaceUVOld( LPARCH3D_FACE pFace, long nCornerCount, LPOBJVERTEX pCornerVertexBuffer, LPSIZE pSrcSize, LPRECT pSubRect );
bool SaveObject();
long ResolveObjectID( long ObjectID );
private: // data
bool m_bIsObjectOpen;
char* m_pData;
long m_nDataLength;
LPARCH3D_HEADER m_pHeader;
LPARCH3D_POINT m_pPointList;
LPARCH3D_POINT m_pNormalList;
long m_lVersion;
long m_nCurObject;
LPBSA_RECORDDIRECTORYSHORT m_pRecordDirectory;
THashArray<UINT, 1999> m_haObjectID;
};
class BSABlocks : public BSAArchive
{
public: // construction / destruction
friend class CDaggerTool;
BSABlocks();
virtual ~BSABlocks();
public: // methods
bool Open( LPCSTR pszPath, BOOL bReadOnly = TRUE );
void Close();
bool OpenBlock( long nBlock );
void CloseBlock();
bool IsBlockOpen() {return m_bIsBlockOpen;}
long GetBlockSubRecordCount() {return m_nBlockSubRecordCount;}
long GetOutsideBlockSubRecordCount() {return m_nOutsideBlockSubRecordCount;}
long GetInsideBlockSubRecordCount() {return m_nInsideBlockSubRecordCount;}
LPRMBFLD GetFLD() {return m_pFLD;}
LPRMB_BLOCKHEADER GetOutsideBlockSubRecord( long nRecord );
LPRMB_BLOCKHEADER GetInsideBlockSubRecord( long nRecord );
LPRMB_BLOCK3DOBJECTS GetBlockSubRecord3DObjects( LPRMB_BLOCKHEADER pBlockHeader );
LPRMB_BLOCK3DOBJECTS GetBlock3DObjects();
bool GetBlockAutomap( LPBLKIMG_AUTOMAP pAutomapOut );
private: // data
bool m_bIsBlockOpen;
char* m_pData;
long m_nDataLength;
long m_nCurBlock;
long m_nBlockSubRecordCount;
long m_nOutsideBlockSubRecordCount;
long m_nInsideBlockSubRecordCount;
LPRMBFLD m_pFLD;
LPBSA_RECORDDIRECTORYLONG m_pRecordDirectory;
};
class BSAMaps : public BSAArchive
{
public: // construction / destruction
friend class CDaggerTool;
BSAMaps();
virtual ~BSAMaps();
public: // methods
bool Open( LPCSTR pszPath, BOOL bReadOnly = TRUE );
void Close();
private: // data
LPBSA_RECORDDIRECTORYLONG m_pRecordDirectory;
};
class CDaggerTool
{
public: // construction / destruction
CDaggerTool();
virtual ~CDaggerTool();
public: // methods
BOOL OpenArena2( LPCSTR pszPath, BOOL bReadOnly = TRUE );
void CloseArena2();
BOOL IsArena2Open() {return m_bArena2Open;}
BOOL OpenTextureArchive( LPCSTR pszName );
BOOL OpenCIFArchive( LPCSTR pszName );
BOOL GetIMGDesc( LPCSTR pszName, LPIMG_IMAGEDESC pIMGDescOut );
BOOL GetIMGImage( LPCSTR pszName, char* pBufferOut, LPIMG_IMAGEDESC pIMGDesc = NULL );
const char* GetLastIMGName() {return m_strLastIMGName.GetBuffer(1);}
public: // objects
CString m_strArena2Path;
CString m_strLastIMGName;
DTXArchive m_dtxArchive;
CIFArchive m_cifArchive;
BSAArch3D m_Arch3D;
BSABlocks m_ArchBlocks;
BSAMaps m_ArchMaps;
protected: // methods
BOOL TestArena2Path( LPCSTR pszPath );
private: // data
BOOL m_bArena2Open;
};
#endif // !defined(AFX_DAGGERTOOL_H__51AEEE08_B1F9_4F58_836D_78D53196E7CC__INCLUDED_)