mirror of
https://gitlab.com/skmp/dca3-game.git
synced 2025-04-28 13:07:59 +03:00
Merge branch 'skmp/col-compress' into 'main'
.col repack See merge request skmp/dca3-game!36
This commit is contained in:
commit
6c3f183759
16 changed files with 288 additions and 84 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -377,6 +377,7 @@ liberty/dca-liberty-sim.elf
|
|||
liberty/animtool*
|
||||
liberty/texconv*
|
||||
liberty/imgtool*
|
||||
liberty/coltool*
|
||||
liberty/extract-sfx*
|
||||
liberty/pack-sfx*
|
||||
liberty/analyze-profile*
|
||||
|
@ -395,6 +396,7 @@ miami/dca-miami-sim.elf
|
|||
miami/animtool*
|
||||
miami/texconv*
|
||||
miami/imgtool*
|
||||
miami/coltool*
|
||||
miami/extract-sfx*
|
||||
miami/pack-sfx*
|
||||
miami/analyze-profile*
|
||||
|
|
|
@ -293,6 +293,9 @@ texconv: $(OBJS_TEXCONV) | pvrtex # You'll have to rebuild pvrtex manually if yo
|
|||
animtool: ../src/tools/animtool.cpp
|
||||
$(CXX) -std=c++17 -o $@ -g -O0 $<
|
||||
|
||||
coltool: ../src/tools/coltool.cpp
|
||||
$(CXX) -std=c++17 -o $@ -g -O0 $<
|
||||
|
||||
-include $(DEPS)
|
||||
|
||||
#### Repacking ####
|
||||
|
@ -520,6 +523,22 @@ $(REPACK_GTA_DIR)/%.IFP: $(GTA_DIR)/%.IFP animtool
|
|||
@mkdir -p $(@D)
|
||||
./animtool $< $@
|
||||
|
||||
# first try the mods loose directory
|
||||
$(REPACK_GTA_DIR)/%.col: $(GTA_MOD_LOOSE_DIR)/%.col coltool
|
||||
@mkdir -p $(@D)
|
||||
./coltool $< $@
|
||||
$(REPACK_GTA_DIR)/%.COL: $(GTA_MOD_LOOSE_DIR)/%.COL coltool
|
||||
@mkdir -p $(@D)
|
||||
./coltool $< $@
|
||||
|
||||
#if not, the original files
|
||||
$(REPACK_GTA_DIR)/%.col: $(GTA_DIR)/%.col coltool
|
||||
@mkdir -p $(@D)
|
||||
./coltool $< $@
|
||||
$(REPACK_GTA_DIR)/%.COL: $(GTA_DIR)/%.COL coltool
|
||||
@mkdir -p $(@D)
|
||||
./coltool $< $@
|
||||
|
||||
$(REPACK_DIR)/packed: $(IMG_TEXTURES_DC) $(IMG_MODELS_DC)
|
||||
mkdir -p $(@D)
|
||||
mkdir -p "$(REPACK_GTA_DIR)/models/gta3"
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# models/coll/peds.col # not actually used
|
||||
|
||||
MISC_FILES = \
|
||||
anim/cuts.dir \
|
||||
anim/cuts.img \
|
||||
|
@ -110,7 +112,6 @@ MISC_FILES = \
|
|||
models/Coll/commer.col \
|
||||
models/Coll/generic.col \
|
||||
models/Coll/indust.col \
|
||||
models/Coll/peds.col \
|
||||
models/Coll/suburb.col \
|
||||
models/Coll/vehicles.col \
|
||||
models/Coll/weapons.col \
|
||||
|
|
|
@ -299,6 +299,9 @@ texconv: $(OBJS_TEXCONV) | pvrtex # You'll have to rebuild pvrtex manually if yo
|
|||
animtool: ../src/tools/animtool.cpp
|
||||
$(CXX) -std=c++17 -o $@ -g -O0 $<
|
||||
|
||||
coltool: ../src/tools/coltool.cpp
|
||||
$(CXX) -std=c++17 -o $@ -g -O0 $<
|
||||
|
||||
-include $(DEPS)
|
||||
|
||||
#### Repacking ####
|
||||
|
@ -355,7 +358,7 @@ TEXTURE_DOWNSAMPLE_IMG ?= HALF
|
|||
IMG_TEXTURES_DC = $(addprefix $(REPACK_IMG_DC_DIR)/, $(IMG_TEXTURES))
|
||||
IMG_MODELS_DC = $(addprefix $(REPACK_IMG_DC_DIR)/, $(IMG_MODELS))
|
||||
IMG_IFP_DC = $(addprefix $(REPACK_IMG_DC_DIR)/, $(IMG_IFP))
|
||||
IMG_MISC_DC = $(addprefix $(REPACK_IMG_DC_DIR)/, $(IMG_MISC))
|
||||
IMG_COL_DC = $(addprefix $(REPACK_IMG_DC_DIR)/, $(IMG_COL))
|
||||
|
||||
CUTS_IFP_DC = $(addprefix $(REPACK_CUTS_DC_DIR)/, $(CUTS_IFP))
|
||||
CUTS_MISC_DC = $(addprefix $(REPACK_CUTS_DC_DIR)/, $(CUTS_MISC))
|
||||
|
@ -372,7 +375,7 @@ STREAM_ADPCM_DC = $(addprefix $(REPACK_GTA_DIR)/stream/, $(STREAM_WAV:.wav=.APM)
|
|||
IMG_TEXTURES_ORIG = $(addprefix $(REPACK_IMG_ORIG_DIR)/, $(IMG_TEXTURES))
|
||||
IMG_MODELS_ORIG = $(addprefix $(REPACK_IMG_ORIG_DIR)/, $(IMG_MODELS))
|
||||
IMG_IFP_ORIG = $(addprefix $(REPACK_IMG_ORIG_DIR)/, $(IMG_IFP))
|
||||
IMG_MISC_ORIG = $(addprefix $(REPACK_IMG_ORIG_DIR)/, $(IMG_MISC))
|
||||
IMG_COL_ORIG = $(addprefix $(REPACK_IMG_ORIG_DIR)/, $(IMG_COL))
|
||||
|
||||
CUTS_IFP_ORIG = $(addprefix $(REPACK_CUTS_ORIG_DIR)/, $(CUTS_IFP))
|
||||
CUTS_MISC_ORIG = $(addprefix $(REPACK_CUTS_ORIG_DIR)/, $(CUTS_MISC))
|
||||
|
@ -396,7 +399,7 @@ $(REPACK_DIR)/unpacked: imgtool $(GTA_DIR)/models/gta3.img $(GTA_DIR)/models/gta
|
|||
./imgtool unpack "$(GTA_DIR)/models/gta3" "$(REPACK_IMG_ORIG_DIR)"
|
||||
@touch $@
|
||||
|
||||
$(IMG_TEXTURES_ORIG) $(IMG_MODELS_ORIG) $(IMG_IFP_ORIG) $(IMG_MISC_ORIG): $(REPACK_DIR)/unpacked
|
||||
$(IMG_TEXTURES_ORIG) $(IMG_MODELS_ORIG) $(IMG_IFP_ORIG) $(IMG_COL_ORIG): $(REPACK_DIR)/unpacked
|
||||
@test -f $@
|
||||
@touch $@
|
||||
|
||||
|
@ -442,17 +445,17 @@ $(REPACK_IMG_DC_DIR)/%.TXD: $(REPACK_IMG_ORIG_DIR)/%.TXD texconv
|
|||
./texconv $< $@ $(DEFAULT_RES) $(DEFAULT_RES) -e $(PVR_ENCODER) -d $(TEXTURE_DOWNSAMPLE_IMG)
|
||||
|
||||
# First try the mods img directory
|
||||
$(REPACK_IMG_DC_DIR)/%.col: $(GTA_MOD_IMG_DIR)/%.col
|
||||
$(REPACK_IMG_DC_DIR)/%.col: $(GTA_MOD_IMG_DIR)/%.col coltool
|
||||
@mkdir -p $(@D)
|
||||
cp $< $@
|
||||
./coltool $< $@
|
||||
$(REPACK_IMG_DC_DIR)/%.ifp: $(GTA_MOD_IMG_DIR)/%.ifp animtool
|
||||
@mkdir -p $(@D)
|
||||
./animtool $< $@
|
||||
|
||||
# if not, the extracted img directory
|
||||
$(REPACK_IMG_DC_DIR)/%.col: $(REPACK_IMG_ORIG_DIR)/%.col
|
||||
$(REPACK_IMG_DC_DIR)/%.col: $(REPACK_IMG_ORIG_DIR)/%.col coltool
|
||||
@mkdir -p $(@D)
|
||||
cp $< $@
|
||||
./coltool $< $@
|
||||
$(REPACK_IMG_DC_DIR)/%.ifp: $(REPACK_IMG_ORIG_DIR)/%.ifp animtool
|
||||
@mkdir -p $(@D)
|
||||
./animtool $< $@
|
||||
|
@ -524,7 +527,23 @@ $(REPACK_GTA_DIR)/%.IFP: $(GTA_DIR)/%.IFP animtool
|
|||
@mkdir -p $(@D)
|
||||
./animtool $< $@
|
||||
|
||||
$(REPACK_DIR)/packed: $(IMG_TEXTURES_DC) $(IMG_MODELS_DC) $(IMG_IFP_DC) $(IMG_MISC_DC)
|
||||
# first try the mods loose directory
|
||||
$(REPACK_GTA_DIR)/%.col: $(GTA_MOD_LOOSE_DIR)/%.col coltool
|
||||
@mkdir -p $(@D)
|
||||
./coltool $< $@
|
||||
$(REPACK_GTA_DIR)/%.COL: $(GTA_MOD_LOOSE_DIR)/%.COL coltool
|
||||
@mkdir -p $(@D)
|
||||
./coltool $< $@
|
||||
|
||||
#if not, the original files
|
||||
$(REPACK_GTA_DIR)/%.col: $(GTA_DIR)/%.col coltool
|
||||
@mkdir -p $(@D)
|
||||
./coltool $< $@
|
||||
$(REPACK_GTA_DIR)/%.COL: $(GTA_DIR)/%.COL coltool
|
||||
@mkdir -p $(@D)
|
||||
./coltool $< $@
|
||||
|
||||
$(REPACK_DIR)/packed: $(IMG_TEXTURES_DC) $(IMG_MODELS_DC) $(IMG_IFP_DC) $(IMG_COL_DC)
|
||||
mkdir -p $(@D)
|
||||
mkdir -p "$(REPACK_GTA_DIR)/models/gta3"
|
||||
./imgtool pack "$(REPACK_GTA_DIR)/models/gta3" "$(REPACK_IMG_DC_DIR)"
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# models/coll/peds.col # not actually used
|
||||
|
||||
MISC_FILES = \
|
||||
\
|
||||
txd/LOADSC8.TXD \
|
||||
|
@ -27,7 +29,6 @@ MISC_FILES = \
|
|||
models/fonts.txd \
|
||||
models/hud.txd \
|
||||
models/coll/weapons.col \
|
||||
models/coll/peds.col \
|
||||
models/coll/vehicles.col \
|
||||
models/coll/generic.col \
|
||||
models/MISC.TXD \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
IMG_MISC = \
|
||||
IMG_COL = \
|
||||
airport.col \
|
||||
airportN.col \
|
||||
bank.col \
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include "ColTriangle.h"
|
||||
|
||||
void
|
||||
CColTriangle::Set(const CompressedVector *, int a, int b, int c, uint8 surf, uint8 piece)
|
||||
CColTriangle::Set(const CompressedVector *, uint16 a, uint16 b, uint16 c, uint8 surf, uint8 piece)
|
||||
{
|
||||
this->a = a;
|
||||
this->b = b;
|
||||
|
|
|
@ -18,7 +18,7 @@ struct CColTriangle
|
|||
uint16 c;
|
||||
uint8 surface;
|
||||
|
||||
void Set(const CompressedVector *v, int a, int b, int c, uint8 surf, uint8 piece);
|
||||
void Set(const CompressedVector *v, uint16 a, uint16 b, uint16 c, uint8 surf, uint8 piece);
|
||||
};
|
||||
|
||||
struct CColTrianglePlane
|
||||
|
|
|
@ -5,7 +5,7 @@ struct CompressedVector
|
|||
#ifdef COMPRESSED_COL_VECTORS
|
||||
int16 x, y, z;
|
||||
CVector Get(void) const { return CVector(x, y, z)/128.0f; };
|
||||
void Set(float x, float y, float z) { this->x = lroundf(x*128.0f); this->y = lroundf(y*128.0f); this->z = lroundf(z*128.0f); };
|
||||
void SetFixed(int16 x, int16 y, int16 z) { this->x = x; this->y = y; this->z = z; };
|
||||
#ifdef GTA_PS2
|
||||
void Unpack(uint128 &qword) const {
|
||||
__asm__ volatile (
|
||||
|
|
|
@ -215,7 +215,7 @@ CFileLoader::LoadCollisionFile(const char *filename)
|
|||
fd = CFileMgr::OpenFile(filename, "rb");
|
||||
|
||||
while(CFileMgr::Read(fd, (char*)&header, sizeof(header))){
|
||||
assert(header.ident == 'LLOC');
|
||||
assert(header.ident == 'CLOC');
|
||||
CFileMgr::Read(fd, (char*)work_buff, header.size);
|
||||
memcpy(modelname, work_buff, 24);
|
||||
|
||||
|
@ -295,14 +295,8 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
|
|||
model.vertices = (CompressedVector*)RwMalloc(numVertices*sizeof(CompressedVector));
|
||||
REGISTER_MEMPTR(&model.vertices);
|
||||
for(i = 0; i < numVertices; i++){
|
||||
model.vertices[i].Set(*(float*)buf, *(float*)(buf+4), *(float*)(buf+8));
|
||||
if(lroundf(Abs(*(float*)buf)) >= 256 ||
|
||||
lroundf(Abs(*(float*)(buf+4))) >= 256 ||
|
||||
lroundf(Abs(*(float*)(buf+8))) >= 256) {
|
||||
dbglog(DBG_CRITICAL, "%s:Collision volume too big\n", modelname);
|
||||
assert(false && "Collision volume too big");
|
||||
}
|
||||
buf += 12;
|
||||
model.vertices[i].SetFixed(*(int16*)buf, *(int16*)(buf+2), *(int16*)(buf+4));
|
||||
buf += 6;
|
||||
}
|
||||
}else
|
||||
model.vertices = nil;
|
||||
|
@ -313,8 +307,11 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
|
|||
model.triangles = (CColTriangle*)RwMalloc(model.numTriangles*sizeof(CColTriangle));
|
||||
REGISTER_MEMPTR(&model.triangles);
|
||||
for(i = 0; i < model.numTriangles; i++){
|
||||
model.triangles[i].Set(model.vertices, *(int32*)buf, *(int32*)(buf+4), *(int32*)(buf+8), buf[12], buf[13]);
|
||||
buf += 16;
|
||||
model.triangles[i].Set(model.vertices, *(uint16*)buf, *(uint16*)(buf+2), *(uint16*)(buf+4), buf[6], buf[7]);
|
||||
buf += 8;
|
||||
assert(model.triangles[i].a < numVertices);
|
||||
assert(model.triangles[i].b < numVertices);
|
||||
assert(model.triangles[i].c < numVertices);
|
||||
}
|
||||
}else
|
||||
model.triangles = nil;
|
||||
|
|
|
@ -163,36 +163,36 @@ Error(char *fmt, ...)
|
|||
void
|
||||
ValidateVersion()
|
||||
{
|
||||
int32 file = CFileMgr::OpenFile("models\\coll\\peds.col", "rb");
|
||||
char buff[128];
|
||||
// int32 file = CFileMgr::OpenFile("models\\coll\\peds.col", "rb");
|
||||
// char buff[128];
|
||||
|
||||
if ( file != -1 )
|
||||
{
|
||||
CFileMgr::Seek(file, 100, SEEK_SET);
|
||||
// if ( file != -1 )
|
||||
// {
|
||||
// CFileMgr::Seek(file, 100, SEEK_SET);
|
||||
|
||||
for ( int i = 0; i < 128; i++ )
|
||||
{
|
||||
CFileMgr::Read(file, &buff[i], sizeof(char));
|
||||
buff[i] -= 23;
|
||||
if ( buff[i] == '\0' )
|
||||
break;
|
||||
CFileMgr::Seek(file, 99, SEEK_CUR);
|
||||
}
|
||||
// for ( int i = 0; i < 128; i++ )
|
||||
// {
|
||||
// CFileMgr::Read(file, &buff[i], sizeof(char));
|
||||
// buff[i] -= 23;
|
||||
// if ( buff[i] == '\0' )
|
||||
// break;
|
||||
// CFileMgr::Seek(file, 99, SEEK_CUR);
|
||||
// }
|
||||
|
||||
if ( !strncmp(buff, "grandtheftauto3", 15) )
|
||||
{
|
||||
strncpy(version_name, &buff[15], 64);
|
||||
CFileMgr::CloseFile(file);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// if ( !strncmp(buff, "grandtheftauto3", 15) )
|
||||
// {
|
||||
// strncpy(version_name, &buff[15], 64);
|
||||
// CFileMgr::CloseFile(file);
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
|
||||
LoadingScreen("Invalid version", NULL, NULL);
|
||||
// LoadingScreen("Invalid version", NULL, NULL);
|
||||
|
||||
while(true)
|
||||
{
|
||||
;
|
||||
}
|
||||
// while(true)
|
||||
// {
|
||||
// ;
|
||||
// }
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -18,7 +18,7 @@ struct CColTriangle
|
|||
uint16 c;
|
||||
uint8 surface;
|
||||
|
||||
void Set(int a, int b, int c, uint8 surf)
|
||||
void Set(uint16 a, uint16 b, uint16 c, uint8 surf)
|
||||
{
|
||||
this->a = a;
|
||||
this->b = b;
|
||||
|
|
|
@ -5,7 +5,7 @@ struct CompressedVector
|
|||
#ifdef COMPRESSED_COL_VECTORS
|
||||
int16 x, y, z;
|
||||
CVector Get(void) const { return CVector(x, y, z)/128.0f; };
|
||||
void Set(float x, float y, float z) { this->x = x*128.0f; this->y = y*128.0f; this->z = z*128.0f; };
|
||||
void SetFixed(int16 x, int16 y, int16 z) { this->x = x; this->y = y; this->z = z; };
|
||||
#ifdef GTA_PS2
|
||||
void Unpack(uint128 &qword) const {
|
||||
__asm__ volatile (
|
||||
|
|
|
@ -189,7 +189,7 @@ CFileLoader::LoadCollisionFile(const char *filename, uint8 colSlot)
|
|||
assert(fd > 0);
|
||||
|
||||
while(CFileMgr::Read(fd, (char*)&header, sizeof(header))){
|
||||
assert(header.ident == 'LLOC');
|
||||
assert(header.ident == 'CLOC');
|
||||
CFileMgr::Read(fd, (char*)work_buff, header.size);
|
||||
memcpy(modelname, work_buff, 24);
|
||||
|
||||
|
@ -226,7 +226,7 @@ CFileLoader::LoadCollisionFileFirstTime(uint8 *buffer, uint32 size, uint8 colSlo
|
|||
while(size > 8){
|
||||
header = (ColHeader*)buffer;
|
||||
modelsize = header->size;
|
||||
if(header->ident != 'LLOC')
|
||||
if(header->ident != 'CLOC')
|
||||
return size-8 < CDSTREAM_SECTOR_SIZE;
|
||||
memcpy(modelname, buffer+8, 24);
|
||||
memcpy(work_buff, buffer+32, modelsize-24);
|
||||
|
@ -260,7 +260,7 @@ CFileLoader::LoadCollisionFile(uint8 *buffer, uint32 size, uint8 colSlot)
|
|||
while(size > 8){
|
||||
header = (ColHeader*)buffer;
|
||||
modelsize = header->size;
|
||||
if(header->ident != 'LLOC')
|
||||
if(header->ident != 'CLOC')
|
||||
return size-8 < CDSTREAM_SECTOR_SIZE;
|
||||
memcpy(modelname, buffer+8, 24);
|
||||
memcpy(work_buff, buffer+32, modelsize-24);
|
||||
|
@ -345,14 +345,14 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
|
|||
model.vertices = (CompressedVector*)RwMalloc(numVertices*sizeof(CompressedVector));
|
||||
REGISTER_MEMPTR(&model.vertices);
|
||||
for(i = 0; i < numVertices; i++){
|
||||
model.vertices[i].Set(*(float*)buf, *(float*)(buf+4), *(float*)(buf+8));
|
||||
model.vertices[i].SetFixed(*(int16*)buf, *(int16*)(buf+2), *(int16*)(buf+4));
|
||||
#if 0
|
||||
if(Abs(*(float*)buf) >= 256.0f ||
|
||||
Abs(*(float*)(buf+4)) >= 256.0f ||
|
||||
Abs(*(float*)(buf+8)) >= 256.0f)
|
||||
printf("%s:Collision volume too big\n", modelname);
|
||||
#endif
|
||||
buf += 12;
|
||||
buf += 6;
|
||||
}
|
||||
}else
|
||||
model.vertices = nil;
|
||||
|
@ -363,8 +363,11 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
|
|||
model.triangles = (CColTriangle*)RwMalloc(model.numTriangles*sizeof(CColTriangle));
|
||||
REGISTER_MEMPTR(&model.triangles);
|
||||
for(i = 0; i < model.numTriangles; i++){
|
||||
model.triangles[i].Set(*(int32*)buf, *(int32*)(buf+4), *(int32*)(buf+8), buf[12]);
|
||||
buf += 16;
|
||||
model.triangles[i].Set(*(uint16*)buf, *(uint16*)(buf+2), *(uint16*)(buf+4), buf[6]);
|
||||
buf += 8;
|
||||
assert(model.triangles[i].a < numVertices);
|
||||
assert(model.triangles[i].b < numVertices);
|
||||
assert(model.triangles[i].c < numVertices);
|
||||
}
|
||||
}else
|
||||
model.triangles = nil;
|
||||
|
|
|
@ -169,36 +169,36 @@ Error(char *fmt, ...)
|
|||
void
|
||||
ValidateVersion()
|
||||
{
|
||||
int32 file = CFileMgr::OpenFile("models\\coll\\peds.col", "rb");
|
||||
char buff[128];
|
||||
// int32 file = CFileMgr::OpenFile("models\\coll\\peds.col", "rb");
|
||||
// char buff[128];
|
||||
|
||||
if ( file != -1 )
|
||||
{
|
||||
CFileMgr::Seek(file, 100, SEEK_SET);
|
||||
// if ( file != -1 )
|
||||
// {
|
||||
// CFileMgr::Seek(file, 100, SEEK_SET);
|
||||
|
||||
for ( int i = 0; i < 128; i++ )
|
||||
{
|
||||
CFileMgr::Read(file, &buff[i], sizeof(char));
|
||||
buff[i] -= 23;
|
||||
if ( buff[i] == '\0' )
|
||||
break;
|
||||
CFileMgr::Seek(file, 99, SEEK_CUR);
|
||||
}
|
||||
// for ( int i = 0; i < 128; i++ )
|
||||
// {
|
||||
// CFileMgr::Read(file, &buff[i], sizeof(char));
|
||||
// buff[i] -= 23;
|
||||
// if ( buff[i] == '\0' )
|
||||
// break;
|
||||
// CFileMgr::Seek(file, 99, SEEK_CUR);
|
||||
// }
|
||||
|
||||
if ( !strncmp(buff, "grandtheftauto3", 15) )
|
||||
{
|
||||
strncpy(version_name, &buff[15], 64);
|
||||
CFileMgr::CloseFile(file);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// if ( !strncmp(buff, "grandtheftauto3", 15) )
|
||||
// {
|
||||
// strncpy(version_name, &buff[15], 64);
|
||||
// CFileMgr::CloseFile(file);
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
|
||||
LoadingScreen("Invalid version", NULL, NULL);
|
||||
// LoadingScreen("Invalid version", NULL, NULL);
|
||||
|
||||
while(true)
|
||||
{
|
||||
;
|
||||
}
|
||||
// while(true)
|
||||
// {
|
||||
// ;
|
||||
// }
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
162
src/tools/coltool.cpp
Normal file
162
src/tools/coltool.cpp
Normal file
|
@ -0,0 +1,162 @@
|
|||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
|
||||
// Our collision file header. In the original code the header is read from the file.
|
||||
// Here we assume it contains an identifier and a size.
|
||||
struct ColHeader {
|
||||
int32_t ident; // should be 'LLOC'
|
||||
int32_t size; // size of the following collision data chunk
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 3) {
|
||||
std::cerr << "Usage: repack_collision <input_file> <output_file>\n";
|
||||
return 1;
|
||||
}
|
||||
const char* inputFile = argv[1];
|
||||
const char* outputFile = argv[2];
|
||||
|
||||
std::ifstream infile(inputFile, std::ios::binary);
|
||||
if (!infile) {
|
||||
std::cerr << "Error: Cannot open input file: " << inputFile << "\n";
|
||||
return 1;
|
||||
}
|
||||
std::ofstream outfile(outputFile, std::ios::binary);
|
||||
if (!outfile) {
|
||||
std::cerr << "Error: Cannot open output file: " << outputFile << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Process each collision model in the file.
|
||||
// Each chunk starts with a ColHeader followed by header.size bytes.
|
||||
while (infile.peek() != EOF) {
|
||||
ColHeader header;
|
||||
infile.read(reinterpret_cast<char*>(&header), sizeof(header));
|
||||
if (!infile) break;
|
||||
|
||||
// Check that the header ident is correct (should equal 'LLOC')
|
||||
if (header.ident != 'LLOC') {
|
||||
auto curpos = infile.tellg();
|
||||
infile.seekg(0, infile.end);
|
||||
auto remaining = infile.tellg() - curpos;
|
||||
|
||||
if (remaining < 2048) {
|
||||
return 0;
|
||||
} else {
|
||||
std::cerr << "Error: Invalid header identifier encountered.\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
header.ident = 'CLOC';
|
||||
|
||||
// Read the collision chunk into a work buffer.
|
||||
std::vector<char> work_buff(header.size);
|
||||
infile.read(work_buff.data(), header.size);
|
||||
if (!infile) break;
|
||||
|
||||
// The first 24 bytes of work_buff are the model name.
|
||||
// The rest of the buffer is the collision model data.
|
||||
// We now “repackage” the collision model data into a new vector.
|
||||
std::vector<char> out_buff;
|
||||
// Copy model name (first 24 bytes)
|
||||
out_buff.insert(out_buff.end(), work_buff.begin(), work_buff.begin() + 24);
|
||||
|
||||
// Set an offset into work_buff where the collision model data begins.
|
||||
size_t offset = 24;
|
||||
|
||||
// === Process Collision Model Data ===
|
||||
// Copy first 44 bytes (bounding sphere, bounding box, and extra bytes)
|
||||
out_buff.insert(out_buff.end(), work_buff.begin() + offset, work_buff.begin() + offset + 44);
|
||||
// We need to extract numSpheres which is stored at offset 40 (within collision data)
|
||||
int16_t numSpheres = *reinterpret_cast<int16_t*>(&work_buff[24 + 40]);
|
||||
offset += 44;
|
||||
|
||||
assert(work_buff.size() > offset);
|
||||
// Copy each sphere data block (20 bytes per sphere)
|
||||
for (int i = 0; i < numSpheres; i++) {
|
||||
out_buff.insert(out_buff.end(), work_buff.begin() + offset, work_buff.begin() + offset + 20);
|
||||
offset += 20;
|
||||
}
|
||||
|
||||
// Process lines: read 4 bytes (includes numLines)
|
||||
int16_t numLines = *reinterpret_cast<int16_t*>(&work_buff[offset]);
|
||||
out_buff.insert(out_buff.end(), work_buff.begin() + offset, work_buff.begin() + offset + 4);
|
||||
offset += 4;
|
||||
// For each line, copy 24 bytes
|
||||
for (int i = 0; i < numLines; i++) {
|
||||
out_buff.insert(out_buff.end(), work_buff.begin() + offset, work_buff.begin() + offset + 24);
|
||||
offset += 24;
|
||||
}
|
||||
|
||||
// Process boxes: next 4 bytes hold numBoxes
|
||||
int16_t numBoxes = *reinterpret_cast<int16_t*>(&work_buff[offset]);
|
||||
out_buff.insert(out_buff.end(), work_buff.begin() + offset, work_buff.begin() + offset + 4);
|
||||
offset += 4;
|
||||
// For each box, copy 28 bytes
|
||||
for (int i = 0; i < numBoxes; i++) {
|
||||
assert(work_buff.size() > offset);
|
||||
out_buff.insert(out_buff.end(), work_buff.begin() + offset, work_buff.begin() + offset + 28);
|
||||
offset += 28;
|
||||
}
|
||||
|
||||
// Process vertices: next 4 bytes (numVertices)
|
||||
int16_t numVertices = *reinterpret_cast<int16_t*>(&work_buff[offset]);
|
||||
out_buff.insert(out_buff.end(), work_buff.begin() + offset, work_buff.begin() + offset + 4);
|
||||
offset += 4;
|
||||
assert(work_buff.size() > offset);
|
||||
|
||||
// For each vertex, convert to fixed point (6 bytes for every 12 bytes in)
|
||||
for (int i = 0; i < numVertices; i++) {
|
||||
for (int v = 0; v < 3; v++) {
|
||||
assert(work_buff.size() > offset);
|
||||
float d = *(float*)(work_buff.data() + offset);
|
||||
offset += 4;
|
||||
auto fix = llround(d * 128);
|
||||
assert(fix >= -32768 && fix <32767);
|
||||
int16_t fix16 = int16_t(fix);
|
||||
out_buff.insert(out_buff.end(), (uint8_t*)(&fix16), (uint8_t*)(&fix16 + 1));
|
||||
}
|
||||
}
|
||||
|
||||
// Process triangles: next 4 bytes (numTriangles)
|
||||
int16_t numTriangles = *reinterpret_cast<int16_t*>(&work_buff[offset]);
|
||||
out_buff.insert(out_buff.end(), work_buff.begin() + offset, work_buff.begin() + offset + 4);
|
||||
offset += 4;
|
||||
// For each triangle, copy 16 bytes
|
||||
for (int i = 0; i < numTriangles; i++) {
|
||||
for (int v = 0; v < 3; v++) {
|
||||
int32_t d = *(int32_t*)(work_buff.data() + offset);
|
||||
offset += 4;
|
||||
assert(d >= -32768 && d <32767);
|
||||
assert(d < numVertices);
|
||||
int16_t d16 = int16_t(d);
|
||||
out_buff.insert(out_buff.end(), (uint8_t*)(&d16), (uint8_t*)(&d16 + 1));
|
||||
}
|
||||
|
||||
out_buff.push_back(work_buff[offset]);
|
||||
out_buff.push_back(work_buff[offset+1]); // 'piece', not actually used
|
||||
offset += 4;
|
||||
}
|
||||
// === End repackaging of collision model data ===
|
||||
|
||||
// align to 4 bytes
|
||||
while (out_buff.size() & 3) {
|
||||
out_buff.push_back(0);
|
||||
}
|
||||
|
||||
// Update header.size to match our repackaged chunk size.
|
||||
header.size = static_cast<int32_t>(out_buff.size());
|
||||
|
||||
// Write the header and the repackaged collision model data to the output file.
|
||||
outfile.write(reinterpret_cast<char*>(&header), sizeof(header));
|
||||
outfile.write(out_buff.data(), out_buff.size());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue