Added support for Ghost Trick TDS textures

This commit is contained in:
Ed-1T 2023-10-23 14:30:09 -04:00
parent f725dc76fb
commit d10b8a08ca
7 changed files with 150 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
.vs/
Debug/
Release/

View File

@ -191,6 +191,7 @@
<ClCompile Include="nscrviewer.c" /> <ClCompile Include="nscrviewer.c" />
<ClCompile Include="palette.c" /> <ClCompile Include="palette.c" />
<ClCompile Include="palops.c" /> <ClCompile Include="palops.c" />
<ClCompile Include="tds.c" />
<ClCompile Include="texconv.c" /> <ClCompile Include="texconv.c" />
<ClCompile Include="texture.c" /> <ClCompile Include="texture.c" />
<ClCompile Include="textureeditor.c" /> <ClCompile Include="textureeditor.c" />
@ -230,6 +231,7 @@
<ClInclude Include="palette.h" /> <ClInclude Include="palette.h" />
<ClInclude Include="palops.h" /> <ClInclude Include="palops.h" />
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />
<ClInclude Include="tds.h" />
<ClInclude Include="texconv.h" /> <ClInclude Include="texconv.h" />
<ClInclude Include="texture.h" /> <ClInclude Include="texture.h" />
<ClInclude Include="textureeditor.h" /> <ClInclude Include="textureeditor.h" />

View File

@ -336,6 +336,7 @@ int ObjIdentify(char *file, int size, LPCWSTR path) {
else if (CellIsValidHudson(buffer, bufferSize)) type = FILE_TYPE_CELL; else if (CellIsValidHudson(buffer, bufferSize)) type = FILE_TYPE_CELL;
else if (CellIsValidGhostTrick(buffer, bufferSize)) type = FILE_TYPE_CELL; else if (CellIsValidGhostTrick(buffer, bufferSize)) type = FILE_TYPE_CELL;
else if (AnmIsValidGhostTrick(buffer, bufferSize)) type = FILE_TYPE_NANR; else if (AnmIsValidGhostTrick(buffer, bufferSize)) type = FILE_TYPE_NANR;
else if (TdsIsValid(buffer, bufferSize)) type = FILE_TYPE_TDS;
//test for bin format files //test for bin format files
else { else {

View File

@ -15,6 +15,7 @@
#define FILE_TYPE_COMBO2D 10 #define FILE_TYPE_COMBO2D 10
#define FILE_TYPE_NMCR 11 #define FILE_TYPE_NMCR 11
#define FILE_TYPE_NMAR 12 #define FILE_TYPE_NMAR 12
#define FILE_TYPE_TDS 13
typedef struct OBJECT_HEADER_ { typedef struct OBJECT_HEADER_ {
int size; int size;

View File

@ -20,6 +20,7 @@
#include "tileeditor.h" #include "tileeditor.h"
#include "textureeditor.h" #include "textureeditor.h"
#include "nsbtx.h" #include "nsbtx.h"
#include "tds.h"
#include "nmcrviewer.h" #include "nmcrviewer.h"
#include "colorchooser.h" #include "colorchooser.h"
#include "ui.h" #include "ui.h"
@ -658,6 +659,9 @@ VOID OpenFileByName(HWND hWnd, LPCWSTR path) {
case FILE_TYPE_IMAGE: case FILE_TYPE_IMAGE:
CreateImageDialog(hWnd, path); CreateImageDialog(hWnd, path);
break; break;
case FILE_TYPE_TDS:
CreateTdsViewer(data->hWndMdi, path);
break;
case FILE_TYPE_COMBO2D: case FILE_TYPE_COMBO2D:
{ {
//since we're kind of stepping around things a bit, we need to decompress here if applicable //since we're kind of stepping around things a bit, we need to decompress here if applicable

112
NitroPaint/tds.c Normal file
View File

@ -0,0 +1,112 @@
#include "tds.h"
#include "texture.h"
#include "textureeditor.h"
#include <Windows.h>
#include <stdio.h>
HWND CreateTdsViewer(HWND hWndParent, LPCWSTR path) {
TdsFile tds;
int n = TdsReadFile(&tds, path);
if (n) {
MessageBox(hWndParent, L"Invalid file.", L"Invalid file", MB_ICONERROR);
return NULL;
}
return CreateTextureEditorImmediate(CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hWndParent, &tds.texture);
}
void TdsFree(OBJECT_HEADER* header) {
TdsFile* tds = (TdsFile*)header;
if (tds->texture.texels.texel != NULL) free(tds->texture.texels.texel);
if (tds->texture.texels.cmp != NULL) free(tds->texture.texels.cmp);
if (tds->texture.palette.pal != NULL) free(tds->texture.palette.pal);
}
void TdsInit(TdsFile* tds) {
tds->header.size = sizeof(TdsFile);
ObjInit((OBJECT_HEADER*)tds, FILE_TYPE_TDS, 0);
tds->header.dispose = TdsFree;
}
int TdsIsValid(char* buffer, unsigned int size) {
if (size < 0x24 || (size & 3)) return 0;
uint32_t magic = *(uint32_t*)(buffer + 0);
if (magic != '.tds') return 0;
uint32_t texCount = *(uint32_t*)(buffer + 0x04);
if (texCount != 1) {
printf("!!!TexCount not 1!!!\n");
return 0;
}
uint32_t texFormat = *(uint8_t*)(buffer + 0x08);
uint32_t texSizeS = *(uint8_t*)(buffer + 0x09);
uint32_t texSizeT = *(uint8_t*)(buffer + 0x0A);
uint32_t textureOffset = *(uint32_t*)(buffer + 0x0C);
uint32_t paletteOffset = *(uint32_t*)(buffer + 0x14);
uint32_t width = *(uint32_t*)(buffer + 0x1C);
uint32_t height = *(uint32_t*)(buffer + 0x20);
if (textureOffset < 0x24 || textureOffset >= size)
return 0;
if (paletteOffset < 0x24 || paletteOffset >= size)
return 0;
if (width > (8 << texSizeS) || height > (8 << texSizeT) || texFormat == 0)
return 0;
if (texFormat == CT_4x4) {
printf("!!!TexFormat is 4x4!?!?\n");
return 0;
}
return 1;
}
int TdsRead(TdsFile* tds, char* buffer, int size) {
//is it valid?
if (!TdsIsValid(buffer, size)) return 1;
TdsInit(tds);
uint32_t texFormat = *(uint8_t*)(buffer + 0x08);
uint32_t texSizeS = *(uint8_t*)(buffer + 0x09);
uint32_t texSizeT = *(uint8_t*)(buffer + 0x0A);
uint32_t textureOffset = *(uint32_t*)(buffer + 0x0C);
uint32_t textureLength = *(uint32_t*)(buffer + 0x10);
uint32_t paletteOffset = *(uint32_t*)(buffer + 0x14);
uint32_t paletteLength = *(uint32_t*)(buffer + 0x18);
uint32_t width = *(uint32_t*)(buffer + 0x1C);
uint32_t height = *(uint32_t*)(buffer + 0x20);
uint32_t texImageParam = 0;
texImageParam |= (texSizeS & 0x7) << 20;
texImageParam |= (texSizeT & 0x7) << 23;
texImageParam |= (texFormat & 0x7) << 26;
tds->texture.texels.texImageParam = texImageParam;
tds->texture.texels.height = height;
tds->texture.texels.cmp = NULL;
tds->texture.texels.texel = calloc(textureLength, 1);
memcpy(tds->texture.texels.texel, buffer + textureOffset, textureLength);
tds->texture.palette.nColors = paletteLength / 2;
tds->texture.palette.pal = calloc(paletteLength, 1);
memcpy(tds->texture.palette.pal, buffer + paletteOffset, paletteLength);
return 0;
}
int TdsReadFile(TdsFile* tds, LPCWSTR path) {
return ObjReadFile(path, (OBJECT_HEADER*)tds, (OBJECT_READER)TdsRead);
}
int TdsWrite(TdsFile* tds, BSTREAM* stream) {
return 0;
}
int TdsWriteFile(TdsFile* tds, LPWSTR name) {
return ObjWriteFile(name, (OBJECT_HEADER*)tds, (OBJECT_WRITER)TdsWrite);
}

26
NitroPaint/tds.h Normal file
View File

@ -0,0 +1,26 @@
#pragma once
#include <Windows.h>
#include "texture.h"
#include "filecommon.h"
typedef struct TdsFile_ {
OBJECT_HEADER header;
TEXTURE texture;
} TdsFile;
HWND CreateTdsViewer(HWND hWndParent, LPCWSTR path);
void TdsInit(TdsFile* tds);
int TdsRead(TdsFile* tds, char* buffer, int size);
int TdsIsValid(char* buffer, unsigned int size);
int TdsReadFile(TdsFile* tds, LPCWSTR path);
int TdsWriteFile(TdsFile* tds, LPWSTR filename);
int TdsWrite(TdsFile* tds, BSTREAM* stream);