1533 lines
No EOL
46 KiB
C
1533 lines
No EOL
46 KiB
C
#include "game/hsfload.h"
|
|
#include "string.h"
|
|
#include "ctype.h"
|
|
|
|
#define AS_S16(field) (*((s16 *)&(field)))
|
|
GXColor rgba[100];
|
|
HsfHeader head;
|
|
HsfData Model;
|
|
|
|
static BOOL MotionOnly;
|
|
static HsfData *MotionModel;
|
|
static void *VertexDataTop;
|
|
static void *NormalDataTop;
|
|
void *fileptr;
|
|
char *StringTable;
|
|
char *DicStringTable;
|
|
void **NSymIndex;
|
|
HsfObject *objtop;
|
|
HsfBuffer *vtxtop;
|
|
HsfCluster *ClusterTop;
|
|
HsfAttribute *AttributeTop;
|
|
HsfMaterial *MaterialTop;
|
|
|
|
static void FileLoad(void *data);
|
|
static HsfData *SetHsfModel(void);
|
|
static void MaterialLoad(void);
|
|
static void AttributeLoad(void);
|
|
static void SceneLoad(void);
|
|
static void ColorLoad(void);
|
|
static void VertexLoad(void);
|
|
static void NormalLoad(void);
|
|
static void STLoad(void);
|
|
static void FaceLoad(void);
|
|
static void ObjectLoad(void);
|
|
static void CenvLoad(void);
|
|
static void SkeletonLoad(void);
|
|
static void PartLoad(void);
|
|
static void ClusterLoad(void);
|
|
static void ShapeLoad(void);
|
|
static void MapAttrLoad(void);
|
|
static void PaletteLoad(void);
|
|
static void BitmapLoad(void);
|
|
static void MotionLoad(void);
|
|
static void MatrixLoad(void);
|
|
|
|
static s32 SearchObjectSetName(HsfData *data, char *name);
|
|
static HsfBuffer *SearchVertexPtr(s32 id);
|
|
static HsfBuffer *SearchNormalPtr(s32 id);
|
|
static HsfBuffer *SearchStPtr(s32 id);
|
|
static HsfBuffer *SearchColorPtr(s32 id);
|
|
static HsfBuffer *SearchFacePtr(s32 id);
|
|
static HsfCenv *SearchCenvPtr(s32 id);
|
|
static HsfPart *SearchPartPtr(s32 id);
|
|
static HsfPalette *SearchPalettePtr(s32 id);
|
|
|
|
static HsfBitmap *SearchBitmapPtr(s32 id);
|
|
static char *GetString(u32 *str_ofs);
|
|
static char *GetMotionString(u16 *str_ofs);
|
|
|
|
HsfData *LoadHSF(void *data)
|
|
{
|
|
HsfData *hsf;
|
|
Model.root = NULL;
|
|
objtop = NULL;
|
|
FileLoad(data);
|
|
SceneLoad();
|
|
ColorLoad();
|
|
PaletteLoad();
|
|
BitmapLoad();
|
|
MaterialLoad();
|
|
AttributeLoad();
|
|
VertexLoad();
|
|
NormalLoad();
|
|
STLoad();
|
|
FaceLoad();
|
|
ObjectLoad();
|
|
CenvLoad();
|
|
SkeletonLoad();
|
|
PartLoad();
|
|
ClusterLoad();
|
|
ShapeLoad();
|
|
MapAttrLoad();
|
|
MotionLoad();
|
|
MatrixLoad();
|
|
hsf = SetHsfModel();
|
|
InitEnvelope(hsf);
|
|
objtop = NULL;
|
|
return hsf;
|
|
|
|
}
|
|
|
|
void ClusterAdjustObject(HsfData *model, HsfData *src_model)
|
|
{
|
|
HsfCluster *cluster;
|
|
s32 i;
|
|
if(!src_model) {
|
|
return;
|
|
}
|
|
if(src_model->clusterCnt == 0) {
|
|
return;
|
|
}
|
|
cluster = src_model->cluster;
|
|
if(cluster->adjusted) {
|
|
return;
|
|
}
|
|
cluster->adjusted = 1;
|
|
for(i=0; i<src_model->clusterCnt; i++, cluster++) {
|
|
char *name = cluster->targetName;
|
|
cluster->target = SearchObjectSetName(model, name);
|
|
}
|
|
}
|
|
|
|
static void FileLoad(void *data)
|
|
{
|
|
fileptr = data;
|
|
memcpy(&head, fileptr, sizeof(HsfHeader));
|
|
memset(&Model, 0, sizeof(HsfData));
|
|
NSymIndex = (void **)((u32)fileptr+head.symbol.ofs);
|
|
StringTable = (char *)((u32)fileptr+head.string.ofs);
|
|
ClusterTop = (HsfCluster *)((u32)fileptr+head.cluster.ofs);
|
|
AttributeTop = (HsfAttribute *)((u32)fileptr+head.attribute.ofs);
|
|
MaterialTop = (HsfMaterial *)((u32)fileptr+head.material.ofs);
|
|
}
|
|
|
|
static HsfData *SetHsfModel(void)
|
|
{
|
|
HsfData *data = fileptr;
|
|
data->scene = Model.scene;
|
|
data->sceneCnt = Model.sceneCnt;
|
|
data->attribute = Model.attribute;
|
|
data->attributeCnt = Model.attributeCnt;
|
|
data->bitmap = Model.bitmap;
|
|
data->bitmapCnt = Model.bitmapCnt;
|
|
data->cenv = Model.cenv;
|
|
data->cenvCnt = Model.cenvCnt;
|
|
data->skeleton = Model.skeleton;
|
|
data->skeletonCnt = Model.skeletonCnt;
|
|
data->face = Model.face;
|
|
data->faceCnt = Model.faceCnt;
|
|
data->material = Model.material;
|
|
data->materialCnt = Model.materialCnt;
|
|
data->motion = Model.motion;
|
|
data->motionCnt = Model.motionCnt;
|
|
data->normal = Model.normal;
|
|
data->normalCnt = Model.normalCnt;
|
|
data->root = Model.root;
|
|
data->objectCnt = Model.objectCnt;
|
|
data->object = objtop;
|
|
data->matrix = Model.matrix;
|
|
data->matrixCnt = Model.matrixCnt;
|
|
data->palette = Model.palette;
|
|
data->paletteCnt = Model.paletteCnt;
|
|
data->st = Model.st;
|
|
data->stCnt = Model.stCnt;
|
|
data->vertex = Model.vertex;
|
|
data->vertexCnt = Model.vertexCnt;
|
|
data->cenv = Model.cenv;
|
|
data->cenvCnt = Model.cenvCnt;
|
|
data->cluster = Model.cluster;
|
|
data->clusterCnt = Model.clusterCnt;
|
|
data->part = Model.part;
|
|
data->partCnt = Model.partCnt;
|
|
data->shape = Model.shape;
|
|
data->shapeCnt = Model.shapeCnt;
|
|
data->mapAttr = Model.mapAttr;
|
|
data->mapAttrCnt = Model.mapAttrCnt;
|
|
return data;
|
|
}
|
|
|
|
char *SetName(u32 *str_ofs)
|
|
{
|
|
char *ret = GetString(str_ofs);
|
|
return ret;
|
|
}
|
|
|
|
static inline char *SetMotionName(u16 *str_ofs)
|
|
{
|
|
char *ret = GetMotionString(str_ofs);
|
|
return ret;
|
|
}
|
|
|
|
static void MaterialLoad(void)
|
|
{
|
|
s32 i;
|
|
s32 j;
|
|
if(head.material.count) {
|
|
HsfMaterial *file_mat = (HsfMaterial *)((u32)fileptr+head.material.ofs);
|
|
HsfMaterial *curr_mat;
|
|
HsfMaterial *new_mat;
|
|
for(i=0; i<head.material.count; i++) {
|
|
curr_mat = &file_mat[i];
|
|
}
|
|
new_mat = file_mat;
|
|
Model.material = new_mat;
|
|
Model.materialCnt = head.material.count;
|
|
file_mat = (HsfMaterial *)((u32)fileptr+head.material.ofs);
|
|
for(i=0; i<head.material.count; i++, new_mat++) {
|
|
curr_mat = &file_mat[i];
|
|
new_mat->name = SetName((u32 *)&curr_mat->name);
|
|
new_mat->pass = curr_mat->pass;
|
|
new_mat->vtxMode = curr_mat->vtxMode;
|
|
new_mat->litColor[0] = curr_mat->litColor[0];
|
|
new_mat->litColor[1] = curr_mat->litColor[1];
|
|
new_mat->litColor[2] = curr_mat->litColor[2];
|
|
new_mat->color[0] = curr_mat->color[0];
|
|
new_mat->color[1] = curr_mat->color[1];
|
|
new_mat->color[2] = curr_mat->color[2];
|
|
new_mat->shadowColor[0] = curr_mat->shadowColor[0];
|
|
new_mat->shadowColor[1] = curr_mat->shadowColor[1];
|
|
new_mat->shadowColor[2] = curr_mat->shadowColor[2];
|
|
new_mat->hilite_scale = curr_mat->hilite_scale;
|
|
new_mat->unk18 = curr_mat->unk18;
|
|
new_mat->invAlpha = curr_mat->invAlpha;
|
|
new_mat->unk20[0] = curr_mat->unk20[0];
|
|
new_mat->unk20[1] = curr_mat->unk20[1];
|
|
new_mat->refAlpha = curr_mat->refAlpha;
|
|
new_mat->unk2C = curr_mat->unk2C;
|
|
new_mat->numAttrs = curr_mat->numAttrs;
|
|
new_mat->attrs = (HsfAttribute **)(NSymIndex+((u32)curr_mat->attrs));
|
|
rgba[i].r = new_mat->litColor[0];
|
|
rgba[i].g = new_mat->litColor[1];
|
|
rgba[i].b = new_mat->litColor[2];
|
|
rgba[i].a = 255;
|
|
for(j=0; j<new_mat->numAttrs; j++) {
|
|
new_mat->attrs[j] = new_mat->attrs[j];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void AttributeLoad(void)
|
|
{
|
|
HsfAttribute *file_attr;
|
|
HsfAttribute *new_attr;
|
|
HsfAttribute *temp_attr;
|
|
s32 i;
|
|
if(head.attribute.count) {
|
|
temp_attr = file_attr = (HsfAttribute *)((u32)fileptr+head.attribute.ofs);
|
|
new_attr = temp_attr;
|
|
Model.attribute = new_attr;
|
|
Model.attributeCnt = head.attribute.count;
|
|
for(i=0; i<head.attribute.count; i++, new_attr++) {
|
|
if((u32)file_attr[i].name != -1) {
|
|
new_attr->name = SetName((u32 *)&file_attr[i].name);
|
|
} else {
|
|
new_attr->name = NULL;
|
|
}
|
|
new_attr->bitmap = SearchBitmapPtr((s32)file_attr[i].bitmap);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void SceneLoad(void)
|
|
{
|
|
HsfScene *file_scene;
|
|
HsfScene *new_scene;
|
|
if(head.scene.count) {
|
|
file_scene = (HsfScene *)((u32)fileptr+head.scene.ofs);
|
|
new_scene = file_scene;
|
|
new_scene->unk8 = file_scene->unk8;
|
|
new_scene->unk4 = file_scene->unk4;
|
|
Model.scene = new_scene;
|
|
Model.sceneCnt = head.scene.count;
|
|
}
|
|
}
|
|
|
|
static void ColorLoad(void)
|
|
{
|
|
s32 i;
|
|
HsfBuffer *file_color;
|
|
HsfBuffer *new_color;
|
|
void *data;
|
|
void *color_data;
|
|
HsfBuffer *temp_color;
|
|
|
|
if(head.color.count) {
|
|
temp_color = file_color = (HsfBuffer *)((u32)fileptr+head.color.ofs);
|
|
data = &file_color[head.color.count];
|
|
for(i=0; i<head.color.count; i++, file_color++);
|
|
new_color = temp_color;
|
|
Model.color = new_color;
|
|
Model.colorCnt = head.color.count;
|
|
file_color = (HsfBuffer *)((u32)fileptr+head.color.ofs);
|
|
data = &file_color[head.color.count];
|
|
for(i=0; i<head.color.count; i++, new_color++, file_color++) {
|
|
color_data = file_color->data;
|
|
new_color->name = SetName((u32 *)&file_color->name);
|
|
new_color->data = (void *)((u32)data+(u32)color_data);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void VertexLoad(void)
|
|
{
|
|
s32 i, j;
|
|
HsfBuffer *file_vertex;
|
|
HsfBuffer *new_vertex;
|
|
void *data;
|
|
HsfVector3f *data_elem;
|
|
void *temp_data;
|
|
|
|
if(head.vertex.count) {
|
|
vtxtop = file_vertex = (HsfBuffer *)((u32)fileptr+head.vertex.ofs);
|
|
data = (void *)&file_vertex[head.vertex.count];
|
|
for(i=0; i<head.vertex.count; i++, file_vertex++) {
|
|
for(j=0; j<(u32)file_vertex->count; j++) {
|
|
data_elem = (HsfVector3f *)(((u32)data)+((u32)file_vertex->data)+(j*sizeof(HsfVector3f)));
|
|
}
|
|
}
|
|
new_vertex = vtxtop;
|
|
Model.vertex = new_vertex;
|
|
Model.vertexCnt = head.vertex.count;
|
|
file_vertex = (HsfBuffer *)((u32)fileptr+head.vertex.ofs);
|
|
VertexDataTop = data = (void *)&file_vertex[head.vertex.count];
|
|
for(i=0; i<head.vertex.count; i++, new_vertex++, file_vertex++) {
|
|
temp_data = file_vertex->data;
|
|
new_vertex->count = file_vertex->count;
|
|
new_vertex->name = SetName((u32 *)&file_vertex->name);
|
|
new_vertex->data = (void *)((u32)data+(u32)temp_data);
|
|
for(j=0; j<new_vertex->count; j++) {
|
|
data_elem = (HsfVector3f *)(((u32)data)+((u32)temp_data)+(j*sizeof(HsfVector3f)));
|
|
((HsfVector3f *)new_vertex->data)[j].x = data_elem->x;
|
|
((HsfVector3f *)new_vertex->data)[j].y = data_elem->y;
|
|
((HsfVector3f *)new_vertex->data)[j].z = data_elem->z;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void NormalLoad(void)
|
|
{
|
|
s32 i, j;
|
|
void *temp_data;
|
|
HsfBuffer *file_normal;
|
|
HsfBuffer *new_normal;
|
|
HsfBuffer *temp_normal;
|
|
void *data;
|
|
|
|
|
|
if(head.normal.count) {
|
|
s32 cenv_count = head.cenv.count;
|
|
temp_normal = file_normal = (HsfBuffer *)((u32)fileptr+head.normal.ofs);
|
|
data = (void *)&file_normal[head.normal.count];
|
|
new_normal = temp_normal;
|
|
Model.normal = new_normal;
|
|
Model.normalCnt = head.normal.count;
|
|
file_normal = (HsfBuffer *)((u32)fileptr+head.normal.ofs);
|
|
NormalDataTop = data = (void *)&file_normal[head.normal.count];
|
|
for(i=0; i<head.normal.count; i++, new_normal++, file_normal++) {
|
|
temp_data = file_normal->data;
|
|
new_normal->count = file_normal->count;
|
|
new_normal->name = SetName((u32 *)&file_normal->name);
|
|
new_normal->data = (void *)((u32)data+(u32)temp_data);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void STLoad(void)
|
|
{
|
|
s32 i, j;
|
|
HsfBuffer *file_st;
|
|
HsfBuffer *temp_st;
|
|
HsfBuffer *new_st;
|
|
void *data;
|
|
HsfVector2f *data_elem;
|
|
void *temp_data;
|
|
|
|
if(head.st.count) {
|
|
temp_st = file_st = (HsfBuffer *)((u32)fileptr+head.st.ofs);
|
|
data = (void *)&file_st[head.st.count];
|
|
for(i=0; i<head.st.count; i++, file_st++) {
|
|
for(j=0; j<(u32)file_st->count; j++) {
|
|
data_elem = (HsfVector2f *)(((u32)data)+((u32)file_st->data)+(j*sizeof(HsfVector2f)));
|
|
}
|
|
}
|
|
new_st = temp_st;
|
|
Model.st = new_st;
|
|
Model.stCnt = head.st.count;
|
|
file_st = (HsfBuffer *)((u32)fileptr+head.st.ofs);
|
|
data = (void *)&file_st[head.st.count];
|
|
for(i=0; i<head.st.count; i++, new_st++, file_st++) {
|
|
temp_data = file_st->data;
|
|
new_st->count = file_st->count;
|
|
new_st->name = SetName((u32 *)&file_st->name);
|
|
new_st->data = (void *)((u32)data+(u32)temp_data);
|
|
for(j=0; j<new_st->count; j++) {
|
|
data_elem = (HsfVector2f *)(((u32)data)+((u32)temp_data)+(j*sizeof(HsfVector2f)));
|
|
((HsfVector2f *)new_st->data)[j].x = data_elem->x;
|
|
((HsfVector2f *)new_st->data)[j].y = data_elem->y;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void FaceLoad(void)
|
|
{
|
|
HsfBuffer *file_face;
|
|
HsfBuffer *new_face;
|
|
HsfBuffer *temp_face;
|
|
HsfFace *temp_data;
|
|
HsfFace *data;
|
|
HsfFace *file_face_strip;
|
|
HsfFace *new_face_strip;
|
|
HsfTristrip *strip;
|
|
s32 i;
|
|
s32 j;
|
|
|
|
if(head.face.count) {
|
|
temp_face = file_face = (HsfBuffer *)((u32)fileptr+head.face.ofs);
|
|
data = (HsfFace *)&file_face[head.face.count];
|
|
new_face = temp_face;
|
|
Model.face = new_face;
|
|
Model.faceCnt = head.face.count;
|
|
file_face = (HsfBuffer *)((u32)fileptr+head.face.ofs);
|
|
data = (HsfFace *)&file_face[head.face.count];
|
|
for(i=0; i<head.face.count; i++, new_face++, file_face++) {
|
|
temp_data = file_face->data;
|
|
new_face->name = SetName((u32 *)&file_face->name);
|
|
new_face->count = file_face->count;
|
|
new_face->data = (void *)((u32)data+(u32)temp_data);
|
|
strip = (HsfTristrip *)(&((HsfFace *)new_face->data)[new_face->count]);
|
|
}
|
|
new_face = temp_face;
|
|
for(i=0; i<head.face.count; i++, new_face++) {
|
|
file_face_strip = new_face_strip = new_face->data;
|
|
for(j=0; j<new_face->count; j++, new_face_strip++, file_face_strip++) {
|
|
if(file_face_strip->type == 4) {
|
|
new_face_strip->strip.data = &strip[(u32)file_face_strip->strip.data];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void DispObject(HsfObject *parent, HsfObject *object)
|
|
{
|
|
u32 i;
|
|
HsfObject *child_obj;
|
|
HsfObject *temp_object;
|
|
struct {
|
|
HsfObject *parent;
|
|
HsfBuffer *shape;
|
|
HsfCluster *cluster;
|
|
} temp;
|
|
|
|
temp.parent = parent;
|
|
object->type = object->type;
|
|
switch(object->type) {
|
|
case HSF_OBJ_MESH:
|
|
{
|
|
HsfObjectData *data;
|
|
HsfObject *new_object;
|
|
|
|
data = &object->data;
|
|
new_object = temp_object = object;
|
|
new_object->data.childrenCount = data->childrenCount;
|
|
new_object->data.children = (HsfObject **)&NSymIndex[(u32)data->children];
|
|
for(i=0; i<new_object->data.childrenCount; i++) {
|
|
child_obj = &objtop[(u32)new_object->data.children[i]];
|
|
new_object->data.children[i] = child_obj;
|
|
}
|
|
new_object->data.parent = parent;
|
|
if(Model.root == NULL) {
|
|
Model.root = temp_object;
|
|
}
|
|
new_object->type = HSF_OBJ_MESH;
|
|
new_object->data.vertex = SearchVertexPtr((s32)data->vertex);
|
|
new_object->data.normal = SearchNormalPtr((s32)data->normal);
|
|
new_object->data.st = SearchStPtr((s32)data->st);
|
|
new_object->data.color = SearchColorPtr((s32)data->color);
|
|
new_object->data.face = SearchFacePtr((s32)data->face);
|
|
new_object->data.vertexShape = (HsfBuffer **)&NSymIndex[(u32)data->vertexShape];
|
|
for(i=0; i<new_object->data.vertexShapeCnt; i++) {
|
|
temp.shape = &vtxtop[(u32)new_object->data.vertexShape[i]];
|
|
new_object->data.vertexShape[i] = temp.shape;
|
|
}
|
|
new_object->data.cluster = (HsfCluster **)&NSymIndex[(u32)data->cluster];
|
|
for(i=0; i<new_object->data.clusterCnt; i++) {
|
|
temp.cluster = &ClusterTop[(u32)new_object->data.cluster[i]];
|
|
new_object->data.cluster[i] = temp.cluster;
|
|
}
|
|
new_object->data.cenv = SearchCenvPtr((s32)data->cenv);
|
|
new_object->data.material = Model.material;
|
|
if((s32)data->attribute >= 0) {
|
|
new_object->data.attribute = Model.attribute;
|
|
} else {
|
|
new_object->data.attribute = NULL;
|
|
}
|
|
new_object->data.file[0] = (void *)((u32)fileptr+(u32)data->file[0]);
|
|
new_object->data.file[1] = (void *)((u32)fileptr+(u32)data->file[1]);
|
|
new_object->data.base.pos.x = data->base.pos.x;
|
|
new_object->data.base.pos.y = data->base.pos.y;
|
|
new_object->data.base.pos.z = data->base.pos.z;
|
|
new_object->data.base.rot.x = data->base.rot.x;
|
|
new_object->data.base.rot.y = data->base.rot.y;
|
|
new_object->data.base.rot.z = data->base.rot.z;
|
|
new_object->data.base.scale.x = data->base.scale.x;
|
|
new_object->data.base.scale.y = data->base.scale.y;
|
|
new_object->data.base.scale.z = data->base.scale.z;
|
|
new_object->data.mesh.min.x = data->mesh.min.x;
|
|
new_object->data.mesh.min.y = data->mesh.min.y;
|
|
new_object->data.mesh.min.z = data->mesh.min.z;
|
|
new_object->data.mesh.max.x = data->mesh.max.x;
|
|
new_object->data.mesh.max.y = data->mesh.max.y;
|
|
new_object->data.mesh.max.z = data->mesh.max.z;
|
|
for(i=0; i<data->childrenCount; i++) {
|
|
DispObject(new_object, new_object->data.children[i]);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case HSF_OBJ_NULL1:
|
|
{
|
|
HsfObjectData *data;
|
|
HsfObject *new_object;
|
|
data = &object->data;
|
|
new_object = temp_object = object;
|
|
new_object->data.parent = parent;
|
|
new_object->data.childrenCount = data->childrenCount;
|
|
new_object->data.children = (HsfObject **)&NSymIndex[(u32)data->children];
|
|
for(i=0; i<new_object->data.childrenCount; i++) {
|
|
child_obj = &objtop[(u32)new_object->data.children[i]];
|
|
new_object->data.children[i] = child_obj;
|
|
}
|
|
if(Model.root == NULL) {
|
|
Model.root = temp_object;
|
|
}
|
|
for(i=0; i<data->childrenCount; i++) {
|
|
DispObject(new_object, new_object->data.children[i]);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case HSF_OBJ_REPLICA:
|
|
{
|
|
HsfObjectData *data;
|
|
HsfObject *new_object;
|
|
data = &object->data;
|
|
new_object = temp_object = object;
|
|
new_object->data.parent = parent;
|
|
new_object->data.childrenCount = data->childrenCount;
|
|
new_object->data.children = (HsfObject **)&NSymIndex[(u32)data->children];
|
|
for(i=0; i<new_object->data.childrenCount; i++) {
|
|
child_obj = &objtop[(u32)new_object->data.children[i]];
|
|
new_object->data.children[i] = child_obj;
|
|
}
|
|
if(Model.root == NULL) {
|
|
Model.root = temp_object;
|
|
}
|
|
new_object->data.replica = &objtop[(u32)new_object->data.replica];
|
|
for(i=0; i<data->childrenCount; i++) {
|
|
DispObject(new_object, new_object->data.children[i]);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case HSF_OBJ_ROOT:
|
|
{
|
|
HsfObjectData *data;
|
|
HsfObject *new_object;
|
|
data = &object->data;
|
|
new_object = temp_object = object;
|
|
new_object->data.parent = parent;
|
|
new_object->data.childrenCount = data->childrenCount;
|
|
new_object->data.children = (HsfObject **)&NSymIndex[(u32)data->children];
|
|
for(i=0; i<new_object->data.childrenCount; i++) {
|
|
child_obj = &objtop[(u32)new_object->data.children[i]];
|
|
new_object->data.children[i] = child_obj;
|
|
}
|
|
if(Model.root == NULL) {
|
|
Model.root = temp_object;
|
|
}
|
|
for(i=0; i<data->childrenCount; i++) {
|
|
DispObject(new_object, new_object->data.children[i]);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case HSF_OBJ_JOINT:
|
|
{
|
|
HsfObjectData *data;
|
|
HsfObject *new_object;
|
|
data = &object->data;
|
|
new_object = temp_object = object;
|
|
new_object->data.parent = parent;
|
|
new_object->data.childrenCount = data->childrenCount;
|
|
new_object->data.children = (HsfObject **)&NSymIndex[(u32)data->children];
|
|
for(i=0; i<new_object->data.childrenCount; i++) {
|
|
child_obj = &objtop[(u32)new_object->data.children[i]];
|
|
new_object->data.children[i] = child_obj;
|
|
}
|
|
if(Model.root == NULL) {
|
|
Model.root = temp_object;
|
|
}
|
|
for(i=0; i<data->childrenCount; i++) {
|
|
DispObject(new_object, new_object->data.children[i]);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case HSF_OBJ_NULL2:
|
|
{
|
|
HsfObjectData *data;
|
|
HsfObject *new_object;
|
|
data = &object->data;
|
|
new_object = temp_object = object;
|
|
new_object->data.parent = parent;
|
|
new_object->data.childrenCount = data->childrenCount;
|
|
new_object->data.children = (HsfObject **)&NSymIndex[(u32)data->children];
|
|
for(i=0; i<new_object->data.childrenCount; i++) {
|
|
child_obj = &objtop[(u32)new_object->data.children[i]];
|
|
new_object->data.children[i] = child_obj;
|
|
}
|
|
if(Model.root == NULL) {
|
|
Model.root = temp_object;
|
|
}
|
|
for(i=0; i<data->childrenCount; i++) {
|
|
DispObject(new_object, new_object->data.children[i]);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case HSF_OBJ_MAP:
|
|
{
|
|
HsfObjectData *data;
|
|
HsfObject *new_object;
|
|
data = &object->data;
|
|
new_object = temp_object = object;
|
|
new_object->data.parent = parent;
|
|
new_object->data.childrenCount = data->childrenCount;
|
|
new_object->data.children = (HsfObject **)&NSymIndex[(u32)data->children];
|
|
for(i=0; i<new_object->data.childrenCount; i++) {
|
|
child_obj = &objtop[(u32)new_object->data.children[i]];
|
|
new_object->data.children[i] = child_obj;
|
|
}
|
|
if(Model.root == NULL) {
|
|
Model.root = temp_object;
|
|
}
|
|
for(i=0; i<data->childrenCount; i++) {
|
|
DispObject(new_object, new_object->data.children[i]);
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static inline void FixupObject(HsfObject *object)
|
|
{
|
|
HsfObjectData *objdata_8;
|
|
HsfObjectData *objdata_7;
|
|
|
|
s32 obj_type = object->type;
|
|
switch(obj_type) {
|
|
case 8:
|
|
{
|
|
objdata_8 = &object->data;
|
|
object->type = HSF_OBJ_NONE2;
|
|
}
|
|
break;
|
|
|
|
case 7:
|
|
{
|
|
objdata_7 = &object->data;
|
|
object->type = HSF_OBJ_NONE1;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
static void ObjectLoad(void)
|
|
{
|
|
s32 i;
|
|
HsfObject *object;
|
|
HsfObject *new_object;
|
|
s32 obj_type;
|
|
|
|
if(head.object.count) {
|
|
objtop = object = (HsfObject *)((u32)fileptr+head.object.ofs);
|
|
for(i=0; i<head.object.count; i++, object++) {
|
|
new_object = object;
|
|
new_object->name = SetName((u32 *)&object->name);
|
|
}
|
|
object = objtop;
|
|
for(i=0; i<head.object.count; i++, object++) {
|
|
if((s32)object->data.parent == -1) {
|
|
break;
|
|
}
|
|
}
|
|
DispObject(NULL, object);
|
|
Model.objectCnt = head.object.count;
|
|
object = objtop;
|
|
for(i=0; i<head.object.count; i++, object++) {
|
|
FixupObject(object);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void CenvLoad(void)
|
|
{
|
|
HsfCenvMulti *multi_file;
|
|
HsfCenvMulti *multi_new;
|
|
HsfCenvSingle *single_new;
|
|
HsfCenvSingle *single_file;
|
|
HsfCenvDual *dual_file;
|
|
HsfCenvDual *dual_new;
|
|
|
|
HsfCenv *cenv_new;
|
|
HsfCenv *cenv_file;
|
|
void *data_base;
|
|
void *weight_base;
|
|
|
|
s32 j;
|
|
s32 i;
|
|
|
|
if(head.cenv.count) {
|
|
cenv_file = (HsfCenv *)((u32)fileptr+head.cenv.ofs);
|
|
data_base = &cenv_file[head.cenv.count];
|
|
weight_base = data_base;
|
|
cenv_new = cenv_file;
|
|
Model.cenvCnt = head.cenv.count;
|
|
Model.cenv = cenv_file;
|
|
for(i=0; i<head.cenv.count; i++) {
|
|
cenv_new[i].singleData = (HsfCenvSingle *)((u32)cenv_file[i].singleData+(u32)data_base);
|
|
cenv_new[i].dualData = (HsfCenvDual *)((u32)cenv_file[i].dualData+(u32)data_base);
|
|
cenv_new[i].multiData = (HsfCenvMulti *)((u32)cenv_file[i].multiData+(u32)data_base);
|
|
cenv_new[i].singleCount = cenv_file[i].singleCount;
|
|
cenv_new[i].dualCount = cenv_file[i].dualCount;
|
|
cenv_new[i].multiCount = cenv_file[i].multiCount;
|
|
cenv_new[i].copyCount = cenv_file[i].copyCount;
|
|
cenv_new[i].vtxCount = cenv_file[i].vtxCount;
|
|
weight_base = (void *)((u32)weight_base+(cenv_new[i].singleCount*sizeof(HsfCenvSingle)));
|
|
weight_base = (void *)((u32)weight_base+(cenv_new[i].dualCount*sizeof(HsfCenvDual)));
|
|
weight_base = (void *)((u32)weight_base+(cenv_new[i].multiCount*sizeof(HsfCenvMulti)));
|
|
}
|
|
for(i=0; i<head.cenv.count; i++) {
|
|
single_new = single_file = cenv_new[i].singleData;
|
|
for(j=0; j<cenv_new[i].singleCount; j++) {
|
|
single_new[j].target = single_file[j].target;
|
|
single_new[j].posCnt = single_file[j].posCnt;
|
|
single_new[j].pos = single_file[j].pos;
|
|
single_new[j].normalCnt = single_file[j].normalCnt;
|
|
single_new[j].normal = single_file[j].normal;
|
|
|
|
}
|
|
dual_new = dual_file = cenv_new[i].dualData;
|
|
for(j=0; j<cenv_new[i].dualCount; j++) {
|
|
dual_new[j].target1 = dual_file[j].target1;
|
|
dual_new[j].target2 = dual_file[j].target2;
|
|
dual_new[j].weightCnt = dual_file[j].weightCnt;
|
|
dual_new[j].weight = (HsfCenvDualWeight *)((u32)weight_base+(u32)dual_file[j].weight);
|
|
}
|
|
multi_new = multi_file = cenv_new[i].multiData;
|
|
for(j=0; j<cenv_new[i].multiCount; j++) {
|
|
multi_new[j].weightCnt = multi_file[j].weightCnt;
|
|
multi_new[j].pos = multi_file[j].pos;
|
|
multi_new[j].posCnt = multi_file[j].posCnt;
|
|
multi_new[j].normal = multi_file[j].normal;
|
|
multi_new[j].normalCnt = multi_file[j].normalCnt;
|
|
multi_new[j].weight = (HsfCenvMultiWeight *)((u32)weight_base+(u32)multi_file[j].weight);
|
|
}
|
|
dual_new = dual_file = cenv_new[i].dualData;
|
|
for(j=0; j<cenv_new[i].dualCount; j++) {
|
|
HsfCenvDualWeight *discard = dual_new[j].weight;
|
|
}
|
|
multi_new = multi_file = cenv_new[i].multiData;
|
|
for(j=0; j<cenv_new[i].multiCount; j++) {
|
|
HsfCenvMultiWeight *weight = multi_new[j].weight;
|
|
s32 k;
|
|
for(k=0; k<multi_new[j].weightCnt; k++, weight++);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void SkeletonLoad(void)
|
|
{
|
|
HsfSkeleton *skeleton_file;
|
|
HsfSkeleton *skeleton_new;
|
|
s32 i;
|
|
|
|
if(head.skeleton.count) {
|
|
skeleton_new = skeleton_file = (HsfSkeleton *)((u32)fileptr+head.skeleton.ofs);
|
|
Model.skeletonCnt = head.skeleton.count;
|
|
Model.skeleton = skeleton_file;
|
|
for(i=0; i<head.skeleton.count; i++) {
|
|
skeleton_new[i].name = SetName((u32 *)&skeleton_file[i].name);
|
|
skeleton_new[i].transform.pos.x = skeleton_file[i].transform.pos.x;
|
|
skeleton_new[i].transform.pos.y = skeleton_file[i].transform.pos.y;
|
|
skeleton_new[i].transform.pos.z = skeleton_file[i].transform.pos.z;
|
|
skeleton_new[i].transform.rot.x = skeleton_file[i].transform.rot.x;
|
|
skeleton_new[i].transform.rot.y = skeleton_file[i].transform.rot.y;
|
|
skeleton_new[i].transform.rot.z = skeleton_file[i].transform.rot.z;
|
|
skeleton_new[i].transform.scale.x = skeleton_file[i].transform.scale.x;
|
|
skeleton_new[i].transform.scale.y = skeleton_file[i].transform.scale.y;
|
|
skeleton_new[i].transform.scale.z = skeleton_file[i].transform.scale.z;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void PartLoad(void)
|
|
{
|
|
HsfPart *part_file;
|
|
HsfPart *part_new;
|
|
|
|
u16 *data;
|
|
s32 i, j;
|
|
|
|
if(head.part.count) {
|
|
part_new = part_file = (HsfPart *)((u32)fileptr+head.part.ofs);
|
|
Model.partCnt = head.part.count;
|
|
Model.part = part_file;
|
|
data = (u16 *)&part_file[head.part.count];
|
|
for(i=0; i<head.part.count; i++, part_new++) {
|
|
part_new->name = SetName((u32 *)&part_file[i].name);
|
|
part_new->count = part_file[i].count;
|
|
part_new->vertex = &data[(u32)part_file[i].vertex];
|
|
for(j=0; j<part_new->count; j++) {
|
|
part_new->vertex[j] = part_new->vertex[j];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void ClusterLoad(void)
|
|
{
|
|
HsfCluster *cluster_file;
|
|
HsfCluster *cluster_new;
|
|
|
|
s32 i, j;
|
|
|
|
if(head.cluster.count) {
|
|
cluster_new = cluster_file = (HsfCluster *)((u32)fileptr+head.cluster.ofs);
|
|
Model.clusterCnt = head.cluster.count;
|
|
Model.cluster = cluster_file;
|
|
for(i=0; i<head.cluster.count; i++) {
|
|
HsfBuffer *vertex;
|
|
u32 vertexSym;
|
|
cluster_new[i].name[0] = SetName((u32 *)&cluster_file[i].name[0]);
|
|
cluster_new[i].name[1] = SetName((u32 *)&cluster_file[i].name[1]);
|
|
cluster_new[i].targetName = SetName((u32 *)&cluster_file[i].targetName);
|
|
cluster_new[i].part = SearchPartPtr((s32)cluster_file[i].part);
|
|
cluster_new[i].unk95 = cluster_file[i].unk95;
|
|
cluster_new[i].type = cluster_file[i].type;
|
|
cluster_new[i].vertexCnt = cluster_file[i].vertexCnt;
|
|
vertexSym = (u32)cluster_file[i].vertex;
|
|
cluster_new[i].vertex = (HsfBuffer **)&NSymIndex[vertexSym];
|
|
for(j=0; j<cluster_new[i].vertexCnt; j++) {
|
|
vertex = SearchVertexPtr((s32)cluster_new[i].vertex[j]);
|
|
cluster_new[i].vertex[j] = vertex;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void ShapeLoad(void)
|
|
{
|
|
s32 i, j;
|
|
HsfShape *shape_new;
|
|
HsfShape *shape_file;
|
|
|
|
if(head.shape.count) {
|
|
shape_new = shape_file = (HsfShape *)((u32)fileptr+head.shape.ofs);
|
|
Model.shapeCnt = head.shape.count;
|
|
Model.shape = shape_file;
|
|
for(i=0; i<Model.shapeCnt; i++) {
|
|
u32 vertexSym;
|
|
HsfBuffer *vertex;
|
|
|
|
shape_new[i].name = SetName((u32 *)&shape_file[i].name);
|
|
shape_new[i].count16[0] = shape_file[i].count16[0];
|
|
shape_new[i].count16[1] = shape_file[i].count16[1];
|
|
vertexSym = (u32)shape_file[i].vertex;
|
|
shape_new[i].vertex = (HsfBuffer **)&NSymIndex[vertexSym];
|
|
for(j=0; j<shape_new[i].count16[1]; j++) {
|
|
vertex = &vtxtop[(u32)shape_new[i].vertex[j]];
|
|
shape_new[i].vertex[j] = vertex;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void MapAttrLoad(void)
|
|
{
|
|
s32 i;
|
|
HsfMapAttr *mapattr_base;
|
|
HsfMapAttr *mapattr_file;
|
|
HsfMapAttr *mapattr_new;
|
|
s16 *data;
|
|
|
|
if(head.mapAttr.count) {
|
|
mapattr_file = mapattr_base = (HsfMapAttr *)((u32)fileptr+head.mapAttr.ofs);
|
|
mapattr_new = mapattr_base;
|
|
Model.mapAttrCnt = head.mapAttr.count;
|
|
Model.mapAttr = mapattr_base;
|
|
data = (s16 *)&mapattr_base[head.mapAttr.count];
|
|
for(i=0; i<head.mapAttr.count; i++, mapattr_file++, mapattr_new++) {
|
|
mapattr_new->data = &data[(u32)mapattr_file->data];
|
|
}
|
|
}
|
|
}
|
|
|
|
static void BitmapLoad(void)
|
|
{
|
|
HsfBitmap *bitmap_file;
|
|
HsfBitmap *bitmap_temp;
|
|
HsfBitmap *bitmap_new;
|
|
HsfPalette *palette;
|
|
void *data;
|
|
s32 i;
|
|
|
|
if(head.bitmap.count) {
|
|
bitmap_temp = bitmap_file = (HsfBitmap *)((u32)fileptr+head.bitmap.ofs);
|
|
data = &bitmap_file[head.bitmap.count];
|
|
for(i=0; i<head.bitmap.count; i++, bitmap_file++);
|
|
bitmap_new = bitmap_temp;
|
|
Model.bitmap = bitmap_file;
|
|
Model.bitmapCnt = head.bitmap.count;
|
|
bitmap_file = (HsfBitmap *)((u32)fileptr+head.bitmap.ofs);
|
|
data = &bitmap_file[head.bitmap.count];
|
|
for(i=0; i<head.bitmap.count; i++, bitmap_file++, bitmap_new++) {
|
|
bitmap_new->name = SetName((u32 *)&bitmap_file->name);
|
|
bitmap_new->dataFmt = bitmap_file->dataFmt;
|
|
bitmap_new->pixSize = bitmap_file->pixSize;
|
|
bitmap_new->sizeX = bitmap_file->sizeX;
|
|
bitmap_new->sizeY = bitmap_file->sizeY;
|
|
bitmap_new->palSize = bitmap_file->palSize;
|
|
palette = SearchPalettePtr((u32)bitmap_file->palData);
|
|
if(palette) {
|
|
bitmap_new->palData = palette->data;
|
|
}
|
|
bitmap_new->data = (void *)((u32)data+(u32)bitmap_file->data);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void PaletteLoad(void)
|
|
{
|
|
s32 i;
|
|
s32 j;
|
|
HsfPalette *palette_file;
|
|
HsfPalette *palette_temp;
|
|
HsfPalette *palette_new;
|
|
|
|
void *data_base;
|
|
u16 *temp_data;
|
|
u16 *data;
|
|
|
|
if(head.palette.count) {
|
|
palette_temp = palette_file = (HsfPalette *)((u32)fileptr+head.palette.ofs);
|
|
data_base = (u16 *)&palette_file[head.palette.count];
|
|
for(i=0; i<head.palette.count; i++, palette_file++) {
|
|
temp_data = (u16 *)((u32)data_base+(u32)palette_file->data);
|
|
}
|
|
Model.palette = palette_temp;
|
|
Model.paletteCnt = head.palette.count;
|
|
palette_new = palette_temp;
|
|
palette_file = (HsfPalette *)((u32)fileptr+head.palette.ofs);
|
|
data_base = (u16 *)&palette_file[head.palette.count];
|
|
for(i=0; i<head.palette.count; i++, palette_file++, palette_new++) {
|
|
temp_data = (u16 *)((u32)data_base+(u32)palette_file->data);
|
|
data = temp_data;
|
|
palette_new->name = SetName((u32 *)&palette_file->name);
|
|
palette_new->data = data;
|
|
palette_new->palSize = palette_file->palSize;
|
|
for(j=0; j<palette_file->palSize; j++) {
|
|
data[j] = data[j];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
char *MakeObjectName(char *name)
|
|
{
|
|
static char buf[768];
|
|
int index, num_minus;
|
|
char *temp_name;
|
|
num_minus = 0;
|
|
index = 0;
|
|
temp_name = name;
|
|
while(*temp_name) {
|
|
if(*temp_name == '-') {
|
|
name = temp_name+1;
|
|
break;
|
|
}
|
|
temp_name++;
|
|
}
|
|
while(*name) {
|
|
if(num_minus != 0) {
|
|
break;
|
|
}
|
|
if(*name == '_' && !isalpha(name[1])) {
|
|
num_minus++;
|
|
break;
|
|
}
|
|
buf[index] = *name;
|
|
name++;
|
|
index++;
|
|
}
|
|
buf[index] = '\0';
|
|
return buf;
|
|
}
|
|
|
|
int CmpObjectName(char *name1, char *name2)
|
|
{
|
|
int temp = 0;
|
|
return strcmp(name1, name2);
|
|
}
|
|
|
|
static inline char *MotionGetName(HsfTrack *track)
|
|
{
|
|
char *ret;
|
|
if(DicStringTable) {
|
|
ret = &DicStringTable[track->target];
|
|
} else {
|
|
ret = GetMotionString(&track->target);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static inline s32 FindObjectName(char *name)
|
|
{
|
|
s32 i;
|
|
HsfObject *object;
|
|
|
|
object = objtop;
|
|
for(i=0; i<head.object.count; i++, object++) {
|
|
if(!CmpObjectName(object->name, name)) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
static inline s32 FindClusterName(char *name)
|
|
{
|
|
s32 i;
|
|
HsfCluster *cluster;
|
|
|
|
cluster = ClusterTop;
|
|
for(i=0; i<head.cluster.count; i++, cluster++) {
|
|
if(!strcmp(cluster->name[0], name)) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
static inline int FindMotionClusterName(char *name)
|
|
{
|
|
s32 i;
|
|
HsfCluster *cluster;
|
|
|
|
cluster = MotionModel->cluster;
|
|
for(i=0; i<MotionModel->clusterCnt; i++, cluster++) {
|
|
if(!strcmp(cluster->name[0], name)) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
static inline s32 FindAttributeName(char *name)
|
|
{
|
|
s32 i;
|
|
HsfAttribute *attribute;
|
|
|
|
attribute = AttributeTop;
|
|
for(i=0; i<head.attribute.count; i++, attribute++) {
|
|
if(!attribute->name) {
|
|
continue;
|
|
}
|
|
if(!strcmp(attribute->name, name)) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
static inline int FindMotionAttributeName(char *name)
|
|
{
|
|
s32 i;
|
|
HsfAttribute *attribute;
|
|
|
|
attribute = MotionModel->attribute;
|
|
for(i=0; i<MotionModel->attributeCnt; i++, attribute++) {
|
|
if(!attribute->name) {
|
|
continue;
|
|
}
|
|
if(!strcmp(attribute->name, name)) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
static inline void MotionLoadTransform(HsfTrack *track, void *data)
|
|
{
|
|
float *step_data;
|
|
float *linear_data;
|
|
float *bezier_data;
|
|
HsfTrack *out_track;
|
|
char *name;
|
|
s32 numKeyframes;
|
|
out_track = track;
|
|
name = MotionGetName(track);
|
|
if(objtop) {
|
|
out_track->target = FindObjectName(name);
|
|
}
|
|
numKeyframes = AS_S16(track->numKeyframes);
|
|
switch(track->curveType) {
|
|
case HSF_CURVE_STEP:
|
|
{
|
|
step_data = (float *)((u32)data+(u32)track->data);
|
|
out_track->data = step_data;
|
|
}
|
|
break;
|
|
|
|
case HSF_CURVE_LINEAR:
|
|
{
|
|
linear_data = (float *)((u32)data+(u32)track->data);
|
|
out_track->data = linear_data;
|
|
}
|
|
break;
|
|
|
|
case HSF_CURVE_BEZIER:
|
|
{
|
|
bezier_data = (float *)((u32)data+(u32)track->data);
|
|
out_track->data = bezier_data;
|
|
}
|
|
break;
|
|
|
|
case HSF_CURVE_CONST:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static inline void MotionLoadCluster(HsfTrack *track, void *data)
|
|
{
|
|
s32 numKeyframes;
|
|
float *step_data;
|
|
float *linear_data;
|
|
float *bezier_data;
|
|
HsfTrack *out_track;
|
|
char *name;
|
|
|
|
out_track = track;
|
|
name = SetMotionName(&track->target);
|
|
if(!MotionOnly) {
|
|
AS_S16(out_track->target) = FindClusterName(name);
|
|
} else {
|
|
AS_S16(out_track->target) = FindMotionClusterName(name);
|
|
}
|
|
numKeyframes = AS_S16(track->numKeyframes);
|
|
(void)out_track;
|
|
switch(track->curveType) {
|
|
case HSF_CURVE_STEP:
|
|
{
|
|
step_data = (float *)((u32)data+(u32)track->data);
|
|
out_track->data = step_data;
|
|
}
|
|
break;
|
|
|
|
case HSF_CURVE_LINEAR:
|
|
{
|
|
linear_data = (float *)((u32)data+(u32)track->data);
|
|
out_track->data = linear_data;
|
|
}
|
|
break;
|
|
|
|
case HSF_CURVE_BEZIER:
|
|
{
|
|
bezier_data = (float *)((u32)data+(u32)track->data);
|
|
out_track->data = bezier_data;
|
|
}
|
|
break;
|
|
|
|
case HSF_CURVE_CONST:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static inline void MotionLoadClusterWeight(HsfTrack *track, void *data)
|
|
{
|
|
s32 numKeyframes;
|
|
float *step_data;
|
|
float *linear_data;
|
|
float *bezier_data;
|
|
HsfTrack *out_track;
|
|
char *name;
|
|
|
|
out_track = track;
|
|
name = SetMotionName(&track->target);
|
|
if(!MotionOnly) {
|
|
AS_S16(out_track->target) = FindClusterName(name);
|
|
} else {
|
|
AS_S16(out_track->target) = FindMotionClusterName(name);
|
|
}
|
|
numKeyframes = AS_S16(track->numKeyframes);
|
|
(void)out_track;
|
|
switch(track->curveType) {
|
|
case HSF_CURVE_STEP:
|
|
{
|
|
step_data = (float *)((u32)data+(u32)track->data);
|
|
out_track->data = step_data;
|
|
}
|
|
break;
|
|
|
|
case HSF_CURVE_LINEAR:
|
|
{
|
|
linear_data = (float *)((u32)data+(u32)track->data);
|
|
out_track->data = linear_data;
|
|
}
|
|
break;
|
|
|
|
case HSF_CURVE_BEZIER:
|
|
{
|
|
bezier_data = (float *)((u32)data+(u32)track->data);
|
|
out_track->data = bezier_data;
|
|
}
|
|
break;
|
|
|
|
case HSF_CURVE_CONST:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static inline void MotionLoadMaterial(HsfTrack *track, void *data)
|
|
{
|
|
float *step_data;
|
|
float *linear_data;
|
|
float *bezier_data;
|
|
s32 numKeyframes;
|
|
HsfTrack *out_track;
|
|
out_track = track;
|
|
numKeyframes = AS_S16(track->numKeyframes);
|
|
switch(track->curveType) {
|
|
case HSF_CURVE_STEP:
|
|
{
|
|
step_data = (float *)((u32)data+(u32)track->data);
|
|
out_track->data = step_data;
|
|
}
|
|
break;
|
|
|
|
case HSF_CURVE_LINEAR:
|
|
{
|
|
linear_data = (float *)((u32)data+(u32)track->data);
|
|
out_track->data = linear_data;
|
|
}
|
|
break;
|
|
|
|
case HSF_CURVE_BEZIER:
|
|
{
|
|
bezier_data = (float *)((u32)data+(u32)track->data);
|
|
out_track->data = bezier_data;
|
|
}
|
|
break;
|
|
|
|
case HSF_CURVE_CONST:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static inline void MotionLoadAttribute(HsfTrack *track, void *data)
|
|
{
|
|
HsfBitmapKey *file_frame;
|
|
HsfBitmapKey *new_frame;
|
|
s32 i;
|
|
float *step_data;
|
|
float *linear_data;
|
|
float *bezier_data;
|
|
HsfTrack *out_track;
|
|
char *name;
|
|
out_track = track;
|
|
if(AS_S16(out_track->target) != -1) {
|
|
name = SetMotionName(&track->target);
|
|
if(!MotionOnly) {
|
|
AS_S16(out_track->param) = FindAttributeName(name);
|
|
} else {
|
|
AS_S16(out_track->param) = FindMotionAttributeName(name);
|
|
}
|
|
}
|
|
|
|
switch(track->curveType) {
|
|
case HSF_CURVE_STEP:
|
|
{
|
|
step_data = (float *)((u32)data+(u32)track->data);
|
|
out_track->data = step_data;
|
|
}
|
|
break;
|
|
|
|
case HSF_CURVE_LINEAR:
|
|
{
|
|
linear_data = (float *)((u32)data+(u32)track->data);
|
|
out_track->data = linear_data;
|
|
}
|
|
break;
|
|
|
|
case HSF_CURVE_BEZIER:
|
|
{
|
|
bezier_data = (float *)((u32)data+(u32)track->data);
|
|
out_track->data = bezier_data;
|
|
}
|
|
break;
|
|
|
|
case HSF_CURVE_BITMAP:
|
|
{
|
|
new_frame = file_frame = (HsfBitmapKey *)((u32)data+(u32)track->data);
|
|
out_track->data = file_frame;
|
|
for(i=0; i<out_track->numKeyframes; i++, file_frame++, new_frame++) {
|
|
new_frame->data = SearchBitmapPtr((s32)file_frame->data);
|
|
}
|
|
}
|
|
break;
|
|
case HSF_CURVE_CONST:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void MotionLoad(void)
|
|
{
|
|
HsfMotion *file_motion;
|
|
HsfMotion *temp_motion;
|
|
HsfMotion *new_motion;
|
|
HsfTrack *track_base;
|
|
void *track_data;
|
|
s32 i;
|
|
|
|
MotionOnly = FALSE;
|
|
MotionModel = NULL;
|
|
if(head.motion.count) {
|
|
temp_motion = file_motion = (HsfMotion *)((u32)fileptr+head.motion.ofs);
|
|
new_motion = temp_motion;
|
|
Model.motion = new_motion;
|
|
Model.motionCnt = file_motion->numTracks;
|
|
track_base = (HsfTrack *)&file_motion[head.motion.count];
|
|
track_data = &track_base[file_motion->numTracks];
|
|
new_motion->track = track_base;
|
|
for(i=0; i<(s32)file_motion->numTracks; i++) {
|
|
switch(track_base[i].type) {
|
|
case HSF_TRACK_TRANSFORM:
|
|
case HSF_TRACK_MORPH:
|
|
MotionLoadTransform(&track_base[i], track_data);
|
|
break;
|
|
|
|
case HSF_TRACK_CLUSTER:
|
|
MotionLoadCluster(&track_base[i], track_data);
|
|
break;
|
|
|
|
case HSF_TRACK_CLUSTER_WEIGHT:
|
|
MotionLoadClusterWeight(&track_base[i], track_data);
|
|
break;
|
|
|
|
case HSF_TRACK_MATERIAL:
|
|
MotionLoadMaterial(&track_base[i], track_data);
|
|
break;
|
|
|
|
case HSF_TRACK_ATTRIBUTE:
|
|
MotionLoadAttribute(&track_base[i], track_data);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
//HACK: Bump register of i to r31
|
|
(void)i;
|
|
(void)i;
|
|
(void)i;
|
|
(void)i;
|
|
(void)i;
|
|
(void)i;
|
|
(void)i;
|
|
(void)i;
|
|
(void)i;
|
|
(void)i;
|
|
(void)i;
|
|
(void)i;
|
|
(void)i;
|
|
(void)i;
|
|
(void)i;
|
|
(void)i;
|
|
(void)i;
|
|
(void)i;
|
|
(void)i;
|
|
(void)i;
|
|
(void)i;
|
|
(void)i;
|
|
(void)i;
|
|
}
|
|
|
|
static void MatrixLoad(void)
|
|
{
|
|
HsfMatrix *matrix_file;
|
|
|
|
if(head.matrix.count) {
|
|
matrix_file = (HsfMatrix *)((u32)fileptr+head.matrix.ofs);
|
|
matrix_file->data = (Mtx *)((u32)fileptr+head.matrix.ofs+sizeof(HsfMatrix));
|
|
Model.matrix = matrix_file;
|
|
Model.matrixCnt = head.matrix.count;
|
|
}
|
|
}
|
|
|
|
static s32 SearchObjectSetName(HsfData *data, char *name)
|
|
{
|
|
HsfObject *object = data->object;
|
|
s32 i;
|
|
for(i=0; i<data->objectCnt; i++, object++) {
|
|
if(!CmpObjectName(object->name, name)) {
|
|
return i;
|
|
}
|
|
}
|
|
OSReport("Search Object Error %s\n", name);
|
|
return -1;
|
|
}
|
|
|
|
static HsfBuffer *SearchVertexPtr(s32 id)
|
|
{
|
|
HsfBuffer *vertex;
|
|
if(id == -1) {
|
|
return NULL;
|
|
}
|
|
vertex = (HsfBuffer *)((u32)fileptr+head.vertex.ofs);
|
|
vertex += id;
|
|
return vertex;
|
|
}
|
|
|
|
static HsfBuffer *SearchNormalPtr(s32 id)
|
|
{
|
|
HsfBuffer *normal;
|
|
if(id == -1) {
|
|
return NULL;
|
|
}
|
|
normal = (HsfBuffer *)((u32)fileptr+head.normal.ofs);
|
|
normal += id;
|
|
return normal;
|
|
}
|
|
|
|
static HsfBuffer *SearchStPtr(s32 id)
|
|
{
|
|
HsfBuffer *st;
|
|
if(id == -1) {
|
|
return NULL;
|
|
}
|
|
st = (HsfBuffer *)((u32)fileptr+head.st.ofs);
|
|
st += id;
|
|
return st;
|
|
}
|
|
|
|
static HsfBuffer *SearchColorPtr(s32 id)
|
|
{
|
|
HsfBuffer *color;
|
|
if(id == -1) {
|
|
return NULL;
|
|
}
|
|
color = (HsfBuffer *)((u32)fileptr+head.color.ofs);
|
|
color += id;
|
|
return color;
|
|
}
|
|
|
|
static HsfBuffer *SearchFacePtr(s32 id)
|
|
{
|
|
HsfBuffer *face;
|
|
if(id == -1) {
|
|
return NULL;
|
|
}
|
|
face = (HsfBuffer *)((u32)fileptr+head.face.ofs);
|
|
face += id;
|
|
return face;
|
|
}
|
|
|
|
static HsfCenv *SearchCenvPtr(s32 id)
|
|
{
|
|
HsfCenv *cenv;
|
|
if(id == -1) {
|
|
return NULL;
|
|
}
|
|
cenv = (HsfCenv *)((u32)fileptr+head.cenv.ofs);
|
|
cenv += id;
|
|
return cenv;
|
|
}
|
|
|
|
static HsfPart *SearchPartPtr(s32 id)
|
|
{
|
|
HsfPart *part;
|
|
if(id == -1) {
|
|
return NULL;
|
|
}
|
|
part = (HsfPart *)((u32)fileptr+head.part.ofs);
|
|
part += id;
|
|
return part;
|
|
}
|
|
|
|
static HsfPalette *SearchPalettePtr(s32 id)
|
|
{
|
|
HsfPalette *palette;
|
|
if(id == -1) {
|
|
return NULL;
|
|
}
|
|
palette = Model.palette;
|
|
palette += id;
|
|
return palette;
|
|
}
|
|
|
|
static HsfBitmap *SearchBitmapPtr(s32 id)
|
|
{
|
|
HsfBitmap *bitmap;
|
|
if(id == -1) {
|
|
return NULL;
|
|
}
|
|
bitmap = (HsfBitmap *)((u32)fileptr+head.bitmap.ofs);
|
|
bitmap += id;
|
|
return bitmap;
|
|
}
|
|
|
|
static char *GetString(u32 *str_ofs)
|
|
{
|
|
char *ret = &StringTable[*str_ofs];
|
|
return ret;
|
|
}
|
|
|
|
static char *GetMotionString(u16 *str_ofs)
|
|
{
|
|
char *ret = &StringTable[*str_ofs];
|
|
return ret;
|
|
} |