PSX version battle backgrounds

  • Thread starter Thread starter Micky
  • Start date Start date
Status
Not open for further replies.
M

Micky

Guest
I haven't found any other documentation on this, except (I think) for the PC version. This is for the PSX version.
Code: [Select]
Code:
Battle Backgrounds PSX======================Backgrounds are stored in probably the easiest model format used in FF7. I reconstructed this from the code for my background-to-Maya converter, so there could be errors. I haven't seen any other documentation on this, so please excuse any duplication...The backgrounds are stored in LZS files in the STAGE1 and STAGE2 directories. They are using the ff7-standard lzs compression.They begin with a directory: The first word is the number of sections, then there is one pointer for each sections.Each section contains a mesh for the background, except for the first that contains some unknown data and the last that contains the TIM-format texture and palettes.Each section starts with vertex data, followed by a triangle and a quad data.Vertex data:1 u32 size of vertex data8 byte per vertex:3 u16 x,y,z1 u16  pad(?)Triangle data1 u16 number of triangles1 u16 texture page (among other flags)16 bytes per triangle:3 u16 offset into vertex table1 u16 unknown2 u8 u1, v11 u16 palette (and some other flags)2 u8 u2, v22 u8 u3, v3  Quad data1 u16 number of quads1 u16 texture page (among other flags)20 bytes per quad:4 u16 offset into vertex table2 u8 u1, v11 u16  palette2 u8 u2, v22 u8 u3, v32 u8 u4, v41 u16  unknownDisplaying the backgrounds is a bit tricky on modern graphics boards, as they don't support palletised textures anymore. Which is understandable given the large number of fetches that would be required for displaying a properly filtered texture - but not very helpful. I solved that by a pre-process that stores the palette on each pixel and then looks up the colour during export.
 
And some code to display them with OpenGL. Works on my Mac, but as I'm using GLUT it should work on Windows, too.
I'm not sure if this is enough to make spell effects work, but you can always calculate normals and add a colour array as well.
Could probably be optimised a bit more, but even in this form it should draw a lot faster than on the PSX...
It doesn't do alpha-blending, just some alpha-kill so you can see through trees and bushes.
Enjoy.
(Small fix to remember the current directory.)
Code: [Select]
Code:
// System#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>// STL#include <string>#include <cassert>#if 1// GLUT#include <GLUT/glut.h>// OpenGL#include <OpenGL/OpenGL.h>#include <OpenGL/gl.h>#include <OpenGL/glu.h>#else// GLUT#include <glut/glut.h>// OpenGL#include <gl/gl.h>#include <gl/glu.h>#endifusing namespace std;typedef unsigned char u8;typedef unsigned short int u16;typedef unsigned long int u32;typedef signed char s8;typedef signed short int s16;typedef signed long int s32;// utility functionsu16 get_u16le(void const * const buf){ return ((u8*)buf)[0] | (((u8*)buf)[1]<<8);}u32 get_u32le(void const * const buf){ return ((u8*)buf)[0] | (((u8*)buf)[1]<<8) | (((u8*)buf)[2]<<16) | (((u8*)buf)[3]<<24);}int load( const string & name, void ** data ){        size_t size = 0;        *data = NULL;        int fd = open( name.c_str(), O_RDONLY, 0 );        if (fd >= 0) {                struct stat sb;                if ( fstat( fd, &sb ) >= 0) {                        assert( sb.st_size > 0 );                        void *tmp = malloc( sb.st_size );                        if ( tmp!=NULL ) {                                if (read( fd, tmp, sb.st_size ) == sb.st_size) {                                        *data = tmp;                                        size = sb.st_size;                                } else {                                        free(tmp);                                }                        }                }                close( fd );        }        return size;}int load_lzs(const string & name, void ** data ){ // read compressed data u8 *buf; int tsize = load( name, (void**)&buf ); int isize = get_u32le(buf) + 4;  if (isize != tsize) {  free(buf);  *data = NULL;  return 0; }  // decompress; int osize = (isize + 255) & ~255; u8 * obuf = (u8 *)malloc(osize); int iofs = 4, oofs = 0; u8 cmd=0, bit=0; while (iofs < isize) {  if (bit == 0) {   cmd = buf[iofs++];   bit = 8;  }  if (cmd&1) {   obuf[oofs++]=buf[iofs++];   if (oofs==osize) {    osize+=256;    obuf = (u8*)realloc(obuf, osize);   }  } else {   u8 a = buf[iofs++];   u8 b = buf[iofs++];   u16 o = a | ((b&0xF0)<<4);   u8 len = (b&0xF)+3;      int rofs =  oofs - ((oofs - 18 - o) & 0xFFF);   for (int j=0; j<len; j++) {    if (rofs < 0) {     obuf[oofs++]=0;    } else {     obuf[oofs++]=obuf[rofs];    }    if (oofs==osize) {     osize+=256;     obuf = (u8*)realloc(obuf, osize);    }    rofs++;   }  }  cmd>>=1;  bit--; } free( buf );  *data = obuf; return oofs;}// Background loading and storagestruct Vertex { s16 x, y, z; s16 u, v;};struct Element { u16 a, b, c, s; // s = shader};struct Mesh { int texture; int element_start; int element_count;};struct Shader { int texture; int palette;};struct Background { int vertex_count; Vertex *vertex; int element_count; Element *element; int *indexbuffer; int shader_count; Shader *shader; GLuint *textures; int mesh_count; Mesh *mesh;};intadd_vertex(Background *bg, s16 x, s16 y, s16 z, u8 u, u8 v){ for (int i=0; i<bg->vertex_count; i++) {  if (bg->vertex[i].x == x && bg->vertex[i].y == y && bg->vertex[i].z == z && bg->vertex[i].u == u && bg->vertex[i].v == v) {   return i;  } }  int idx = bg->vertex_count++; bg->vertex = (Vertex *)realloc(bg->vertex, bg->vertex_count * sizeof(Vertex)); bg->vertex[idx].x = x; bg->vertex[idx].y = y; bg->vertex[idx].z = z; bg->vertex[idx].u = u; bg->vertex[idx].v = v; return idx;}int add_triangle(Background *bg, u16 a, u16 b, u16 c, u16 s){ int idx = bg->element_count++; bg->element = (Element*)realloc(bg->element, bg->element_count * sizeof(Element)); bg->element[idx].a = a; bg->element[idx].b = b; bg->element[idx].c = c; bg->element[idx].s = s; return idx;}intadd_shader(Background *bg, int texture, int palette){ for (int i=0; i<bg->shader_count; i++) {  if (bg->shader[i].texture == texture && bg->shader[i].palette == palette) {   return i;  } }  int idx = bg->shader_count++; bg->shader = (Shader *)realloc(bg->shader, bg->shader_count * sizeof(Shader)); bg->shader[idx].texture = texture; bg->shader[idx].palette = palette;  return idx;}voidload_background(const string & filename, Background *bg){ bg->vertex_count = 0; bg->vertex = NULL; bg->element_count = 0; bg->element = NULL; bg->textures = NULL; bg->shader_count = 0; bg->shader = NULL; bg->mesh_count = 0; bg->mesh = NULL;  u8 * data; int size = load_lzs(filename, (void**)&data); int num_pointer = get_u32le(data);  // background texture int texdata = get_u32le(data + num_pointer * 4); int npal = get_u16le(data + texdata + 18); int paldata_size = get_u32le(data+texdata+8); int pal_ofs = texdata + 20; int picdata_size = get_u32le(data+texdata+8+paldata_size); int pic_ofs = texdata + 20 + npal*512 + 12;  int xsize = get_u16le(data+pic_ofs-4)*2; int ysize = get_u16le(data+pic_ofs-2);  // convert mesh data for (int i=1; i<num_pointer-1; i++) {  int base = get_u32le(data + 4 + i * 4);    // triangles  int triangle_offset = base + 4 + get_u32le(data + base);  int num_triangles = get_u16le(data + triangle_offset);  int mesh_tri_flags = get_u16le(data + triangle_offset + 2);    int texture_idx = ((mesh_tri_flags & 0x0E)-6) / 2;  for (int j=0; j<num_triangles; j++) {   int point[3];   int ofs = triangle_offset + 4 + j * 16;   for (int k=0; k<3; k++) {    int p = get_u16le(data + ofs + k * 2) + base + 4;    s16 x =  ((s16)get_u16le(data + p + 0*2));    s16 y = -((s16)get_u16le(data + p + 1*2));    s16 z =  ((s16)get_u16le(data + p + 2*2));    const int uv_offsets[3] = { 8, 12, 14 };    u8 u = data[ofs + uv_offsets[k] + 0];    u8 v = data[ofs + uv_offsets[k] + 1];    point[k] = add_vertex(bg, x,y,z,u,v);   }   u16 flags1 = get_u16le(data + ofs + 6);   u16 flags2 = get_u16le(data + ofs + 10);      int palette_idx = (flags2 >> 6) & 7;   int shader_idx = add_shader(bg, texture_idx, palette_idx);      add_triangle(bg, point[0], point[1], point[2], shader_idx);  }    // quads  int quad_offset = triangle_offset + 4 + num_triangles * 16;  int num_quads = get_u16le(data + quad_offset);  int mesh_quad_flags = get_u16le(data + quad_offset + 2);  for (int j=0; j<num_quads; j++) {   int point[4];   int ofs = quad_offset + 4 + j * 20;   for (int k=0; k<4; k++) {    int p = get_u16le(data + ofs + k * 2) + base + 4;    s16 x =  ((s16)get_u16le(data + p + 0 * 2));    s16 y = -((s16)get_u16le(data + p + 1 * 2));    s16 z =  ((s16)get_u16le(data + p + 2 * 2));        const int uv_offsets[4] = { 8, 12, 14, 16 };    u8 u = data[ofs + uv_offsets[k] + 0];    u8 v = data[ofs + uv_offsets[k] + 1];    point[k] = add_vertex(bg, x,y,z,u,v);   }   u16 flags1 = get_u16le(data + ofs + 18);   u16 flags2 = get_u16le(data + ofs + 10);   int palette_idx = (flags2 >> 6) & 7;   int shader_idx = add_shader(bg, texture_idx, palette_idx);      add_triangle(bg, point[0], point[1], point[2], shader_idx);   add_triangle(bg, point[3], point[2], point[1], shader_idx);  } }  // build meshes bg->indexbuffer = (int*)malloc(bg->element_count * 3 * sizeof(int)); int cur_mesh = 0; for (int i=0; i<bg->element_count; i++) {  bg->indexbuffer[i * 3 + 0] = bg->element[i].a;  bg->indexbuffer[i * 3 + 1] = bg->element[i].b;  bg->indexbuffer[i * 3 + 2] = bg->element[i].c;    if (bg->mesh_count > 0 && bg->mesh[cur_mesh].texture == bg->element[i].s) {   bg->mesh[cur_mesh].element_count++;  } else {   cur_mesh = bg->mesh_count++;   bg->mesh = (Mesh*)realloc(bg->mesh, bg->mesh_count * sizeof(Mesh));   bg->mesh[cur_mesh].texture = bg->element[i].s;   bg->mesh[cur_mesh].element_start = i*3;   bg->mesh[cur_mesh].element_count = 1;  } }  // build required textures struct RGBA {  u8 r, g, b, a; };  RGBA *clut = (RGBA*)malloc(sizeof(RGBA) * 256 * (npal)); for (int j = 0; j < npal; j++) {  for (int i=0; i<256; i++) {   u16 col = (data[i*2 + pal_ofs + j*512 + 1]<<8) | data[i*2 + pal_ofs + j * 512];   clut[i+j*256].r = (((col      ) & 31) * 255 + 15) / 31;   clut[i+j*256].g = (((col >>  5) & 31) * 255 + 15) / 31;   clut[i+j*256].b = (((col >> 10) & 31) * 255 + 15) / 31;   clut[i+j*256].a = ((col & 0x8000) || (col == 0)) ? 0 : 255;  } }  bg->textures = (GLuint*)malloc(sizeof(GLuint) * bg->shader_count); glGenTextures( bg->shader_count, bg->textures); RGBA *texture = (RGBA*)malloc(sizeof(RGBA) * 256 * 256); for (int i=0; i<bg->shader_count; i++) {  // build#if 1  if ( bg->shader[i].palette >= npal ) {   printf("%i %i\n", bg->shader[i].palette, npal);   bg->shader[i].palette = 0;  }#endif  for (int y=0; y<256; y++) {   for (int x=0; x<256; x++) {    texture[y*256+x] = clut[data[pic_ofs + y * xsize + x + bg->shader[i].texture * 256] + bg->shader[i].palette * 256];   }  }    // copy to GL  glBindTexture( GL_TEXTURE_2D, bg->textures[i]);#if 0  // blocky  glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, texture);  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );#else  // interpolated  gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, 256, 256, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, texture);  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );  glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR );#endif } free(texture); free(clut); free(data);}// GLUT and OpenGL stuffBackground battle;int rot_y;int rot_x;void ReshapeWindowFunc(int width, int height){ const double kFOVy = 0.57735; const double kZNear = 0.1;  glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); GLdouble aspect = ((GLfloat)width / (GLfloat)height) * (kZNear * kFOVy); glFrustum(-aspect, aspect, -(kZNear * kFOVy), (kZNear * kFOVy), kZNear, 1000.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity();}void MainRenderLoop(void){ // render glClearColor(0, 0, 0, 1.00); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable( GL_DEPTH_TEST ); glDepthFunc( GL_LEQUAL );    glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 1.0f/255.0f); glEnable( GL_TEXTURE_2D ); glEnable( GL_CULL_FACE ); glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );        glDisable( GL_LIGHTING ); glDisable( GL_BLEND ); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );  glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glRotatef( (float)rot_x * 360.0f / 256.0f, 1.0f, 0.0f, 0.0f ); glRotatef( (float)rot_y * 360.0f / 256.0f, 0.0f, 1.0f, 0.0f ); glTranslatef( 0, -16, 0); glScalef( 1.0f/256.0f, 1.0f/256.0f, 1.0f/256.0f );  glMatrixMode(GL_TEXTURE); glLoadIdentity(); glScalef(1.0f/256.0f, 1.0f/256.0f, 0); glTranslatef( 0.5f, 0.5f, 0);  glEnableClientState( GL_VERTEX_ARRAY ); glEnableClientState( GL_TEXTURE_COORD_ARRAY );  glVertexPointer( 3, GL_SHORT, sizeof(Vertex), &(battle.vertex[0].x) ); glTexCoordPointer( 2, GL_SHORT, sizeof(Vertex), &(battle.vertex[0].u) ); for (int i = 0; i < battle.mesh_count; i++) {  glBindTexture(GL_TEXTURE_2D, battle.textures[battle.mesh[i].texture]);  glDrawElements(GL_TRIANGLES, battle.mesh[i].element_count * 3, GL_UNSIGNED_INT, battle.indexbuffer + battle.mesh[i].element_start); }  glDisableClientState( GL_TEXTURE_COORD_ARRAY ); glDisableClientState( GL_VERTEX_ARRAY );  glFlush();}void SpecialHandler(int key, int x, int y){ switch (key) {  case GLUT_KEY_UP:   rot_x -= 4;   if (rot_x < -64) {     rot_x = -64;    }   break;  case GLUT_KEY_DOWN:   rot_x += 4;   if (rot_x > 64) {     rot_x = 64;    }   break;  case GLUT_KEY_LEFT:   rot_y -= 5;   break;  case GLUT_KEY_RIGHT:   rot_y += 5;   break; } glutPostRedisplay();}void KeyboardHandler(unsigned char key, int x, int y){ switch (key) {  case 27:   exit(0);   break; }}int main(int argc, char *argv[]) { if (argc != 2) {  fprintf(stderr, "stageview <stage.lzs>\n"); } else {// get current directory  char cwd[1024];  getcwd(cwd, sizeof(cwd));              string path;  if (argv[1][0] != 0 && argv[1][0] != '/' && argv[1][1] != 0 && argv[1][1] != ':' && argv[1][2] != 0 && argv[1][2] != '\\') {   path = string(cwd) + "/";  }  // init opengl and glut  glutInit(&argc, (char **) argv);  glutInitWindowSize(640, 480);  glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);  glutCreateWindow(argv[0]);  glutDisplayFunc(MainRenderLoop);  glutIdleFunc(MainRenderLoop);  glutReshapeFunc(ReshapeWindowFunc);  glutKeyboardFunc(KeyboardHandler);  glutSpecialFunc(SpecialHandler);      // load data  load_background(path + argv[1], &battle);    rot_y = rot_x = 0;    // main (this will never return)  glutMainLoop(); } return 0;}
 
I called it "stageview", but in the end you can call it mickysprogram if you like.  :D
 
I put all the files of GLUT bin for Win32 in WINDOWS/System32 folder(XPpro)
and the stageview crashes
have I done something wrong?
Thanks
 
Glut dlls go in the system folder, not system32.

Did you open it in a DOS box? You gave it parameters, right?
 
Actually in the begining I put the dll in System folder but the program crashed so I changed the location to System32 without any results
anyway I'll try to recompile
Thx
 
stageview.exe has encontered a problem and needs to close

Code: [Select]
Code:
<?xml version="1.0" encoding="UTF-16"?><DATABASE><EXE NAME="SYSTEM INFO" FILTER="GRABMI_FILTER_SYSTEM">    <MATCHING_FILE NAME="advapi32.dll" SIZE="549888" CHECKSUM="0x4F484D70" BIN_FILE_VERSION="5.1.2600.0" BIN_PRODUCT_VERSION="5.1.2600.0" PRODUCT_VERSION="5.1.2600.0" FILE_DESCRIPTION="Advanced Windows 32 Base API" COMPANY_NAME="Microsoft Corporation" PRODUCT_NAME="Microsoft® Windows® Operating System" FILE_VERSION="5.1.2600.0 (XPClient.010817-1148)" ORIGINAL_FILENAME="advapi32.dll" INTERNAL_NAME="advapi32.dll" LEGAL_COPYRIGHT="© Microsoft Corporation. All rights reserved." VERFILEDATEHI="0x0" VERFILEDATELO="0x0" VERFILEOS="0x40004" VERFILETYPE="0x2" MODULE_TYPE="WIN32" PE_CHECKSUM="0x8F9C5" LINKER_VERSION="0x50001" UPTO_BIN_FILE_VERSION="5.1.2600.0" UPTO_BIN_PRODUCT_VERSION="5.1.2600.0" LINK_DATE="08/18/2001 05:33:02" UPTO_LINK_DATE="08/18/2001 05:33:02" VER_LANGUAGE="English (United States) [0x409]" />    <MATCHING_FILE NAME="gdi32.dll" SIZE="241664" CHECKSUM="0x63C03AF9" BIN_FILE_VERSION="5.1.2600.132" BIN_PRODUCT_VERSION="5.1.2600.132" PRODUCT_VERSION="5.1.2600.132" FILE_DESCRIPTION="GDI Client DLL" COMPANY_NAME="Microsoft Corporation" PRODUCT_NAME="Microsoft® Windows® Operating System" FILE_VERSION="5.1.2600.132 (xpclnt_qfe.021108-2107)" ORIGINAL_FILENAME="gdi32" INTERNAL_NAME="gdi32" LEGAL_COPYRIGHT="© Microsoft Corporation. All rights reserved." VERFILEDATEHI="0x0" VERFILEDATELO="0x0" VERFILEOS="0x40004" VERFILETYPE="0x2" MODULE_TYPE="WIN32" PE_CHECKSUM="0x4A673" LINKER_VERSION="0x50001" UPTO_BIN_FILE_VERSION="5.1.2600.132" UPTO_BIN_PRODUCT_VERSION="5.1.2600.132" LINK_DATE="03/30/2004 01:25:40" UPTO_LINK_DATE="03/30/2004 01:25:40" VER_LANGUAGE="English (United States) [0x409]" />    <MATCHING_FILE NAME="kernel32.dll" SIZE="926720" CHECKSUM="0x6262EEA5" BIN_FILE_VERSION="5.1.2600.0" BIN_PRODUCT_VERSION="5.1.2600.0" PRODUCT_VERSION="5.1.2600.0" FILE_DESCRIPTION="Windows NT BASE API Client DLL" COMPANY_NAME="Microsoft Corporation" PRODUCT_NAME="Microsoft® Windows® Operating System" FILE_VERSION="5.1.2600.0 (xpclient.010817-1148)" ORIGINAL_FILENAME="kernel32" INTERNAL_NAME="kernel32" LEGAL_COPYRIGHT="© Microsoft Corporation. All rights reserved." VERFILEDATEHI="0x0" VERFILEDATELO="0x0" VERFILEOS="0x40004" VERFILETYPE="0x2" MODULE_TYPE="WIN32" PE_CHECKSUM="0xE8792" LINKER_VERSION="0x50001" UPTO_BIN_FILE_VERSION="5.1.2600.0" UPTO_BIN_PRODUCT_VERSION="5.1.2600.0" LINK_DATE="08/18/2001 05:33:02" UPTO_LINK_DATE="08/18/2001 05:33:02" VER_LANGUAGE="English (United States) [0x409]" />    <MATCHING_FILE NAME="ntdll.dll" SIZE="651264" CHECKSUM="0xEA9C095" BIN_FILE_VERSION="5.1.2600.114" BIN_PRODUCT_VERSION="5.1.2600.114" PRODUCT_VERSION="5.1.2600.114" FILE_DESCRIPTION="NT Layer DLL" COMPANY_NAME="Microsoft Corporation" PRODUCT_NAME="Microsoft® Windows® Operating System" FILE_VERSION="5.1.2600.114 (xpclnt_qfe.021108-2107)" ORIGINAL_FILENAME="ntdll.dll" INTERNAL_NAME="ntdll.dll" LEGAL_COPYRIGHT="© Microsoft Corporation. All rights reserved." VERFILEDATEHI="0x0" VERFILEDATELO="0x0" VERFILEOS="0x40004" VERFILETYPE="0x2" MODULE_TYPE="WIN32" PE_CHECKSUM="0xA2397" LINKER_VERSION="0x50001" UPTO_BIN_FILE_VERSION="5.1.2600.114" UPTO_BIN_PRODUCT_VERSION="5.1.2600.114" LINK_DATE="05/02/2003 18:03:00" UPTO_LINK_DATE="05/02/2003 18:03:00" VER_LANGUAGE="English (United States) [0x409]" />    <MATCHING_FILE NAME="ole32.dll" SIZE="1105408" CHECKSUM="0x9E050449" BIN_FILE_VERSION="5.1.2600.136" BIN_PRODUCT_VERSION="5.1.2600.136" PRODUCT_VERSION="5.1.2600.136" FILE_DESCRIPTION="Microsoft OLE for Windows" COMPANY_NAME="Microsoft Corporation" PRODUCT_NAME="Microsoft® Windows® Operating System" FILE_VERSION="5.1.2600.136 (xpclnt_qfe.021108-2107)" ORIGINAL_FILENAME="OLE32.DLL" INTERNAL_NAME="OLE32.DLL" LEGAL_COPYRIGHT="© Microsoft Corporation. All rights reserved." VERFILEDATEHI="0x0" VERFILEDATELO="0x0" VERFILEOS="0x40004" VERFILETYPE="0x2" MODULE_TYPE="WIN32" PE_CHECKSUM="0x11DC8A" LINKER_VERSION="0x50001" UPTO_BIN_FILE_VERSION="5.1.2600.136" UPTO_BIN_PRODUCT_VERSION="5.1.2600.136" LINK_DATE="03/06/2004 02:05:11" UPTO_LINK_DATE="03/06/2004 02:05:11" VER_LANGUAGE="English (United States) [0x409]" />    <MATCHING_FILE NAME="oleaut32.dll" SIZE="569344" CHECKSUM="0x33FCD4B1" BIN_FILE_VERSION="3.50.5014.0" BIN_PRODUCT_VERSION="3.50.5014.0" PRODUCT_VERSION="3.50.5014.0" FILE_DESCRIPTION="Microsoft OLE 3.50  for Windows NT(TM) and Windows 95(TM) Operating Systems" COMPANY_NAME="Microsoft Corporation" PRODUCT_NAME="Microsoft OLE 3.50  for Windows NT(TM) and Windows 95(TM) Operating Systems" FILE_VERSION="3.50.5014.0" INTERNAL_NAME="OLEAUT32.DLL" LEGAL_COPYRIGHT="Copyright © Microsoft Corp. 1993-1999." VERFILEDATEHI="0x0" VERFILEDATELO="0x0" VERFILEOS="0x40004" VERFILETYPE="0x2" MODULE_TYPE="WIN32" PE_CHECKSUM="0x9AC05" LINKER_VERSION="0x0" UPTO_BIN_FILE_VERSION="3.50.5014.0" UPTO_BIN_PRODUCT_VERSION="3.50.5014.0" LINK_DATE="08/18/2001 05:33:04" UPTO_LINK_DATE="08/18/2001 05:33:04" VER_LANGUAGE="English (United States) [0x409]" />    <MATCHING_FILE NAME="shell32.dll" SIZE="8223744" CHECKSUM="0x14E5D605" BIN_FILE_VERSION="6.0.2600.115" BIN_PRODUCT_VERSION="6.0.2600.115" PRODUCT_VERSION="6.00.2600.115" FILE_DESCRIPTION="Windows Shell Common Dll" COMPANY_NAME="Microsoft Corporation" PRODUCT_NAME="Microsoft® Windows® Operating System" FILE_VERSION="6.00.2600.115 (xpclnt_qfe.021108-2107)" ORIGINAL_FILENAME="SHELL32.DLL" INTERNAL_NAME="SHELL32" LEGAL_COPYRIGHT="© Microsoft Corporation. All rights reserved." VERFILEDATEHI="0x0" VERFILEDATELO="0x0" VERFILEOS="0x40004" VERFILETYPE="0x2" MODULE_TYPE="WIN32" PE_CHECKSUM="0x7E7306" LINKER_VERSION="0x50001" UPTO_BIN_FILE_VERSION="6.0.2600.115" UPTO_BIN_PRODUCT_VERSION="6.0.2600.115" LINK_DATE="06/11/2003 20:53:04" UPTO_LINK_DATE="06/11/2003 20:53:04" VER_LANGUAGE="English (United States) [0x409]" />    <MATCHING_FILE NAME="user32.dll" SIZE="528896" CHECKSUM="0x19795864" BIN_FILE_VERSION="5.1.2600.118" BIN_PRODUCT_VERSION="5.1.2600.118" PRODUCT_VERSION="5.1.2600.118" FILE_DESCRIPTION="Windows XP USER API Client DLL" COMPANY_NAME="Microsoft Corporation" PRODUCT_NAME="Microsoft® Windows® Operating System" FILE_VERSION="5.1.2600.118 (xpclnt_qfe.021108-2107)" ORIGINAL_FILENAME="user32" INTERNAL_NAME="user32" LEGAL_COPYRIGHT="© Microsoft Corporation. All rights reserved." VERFILEDATEHI="0x0" VERFILEDATELO="0x0" VERFILEOS="0x40004" VERFILETYPE="0x2" MODULE_TYPE="WIN32" PE_CHECKSUM="0x8BA11" LINKER_VERSION="0x50001" UPTO_BIN_FILE_VERSION="5.1.2600.118" UPTO_BIN_PRODUCT_VERSION="5.1.2600.118" LINK_DATE="09/26/2003 18:51:30" UPTO_LINK_DATE="09/26/2003 18:51:30" VER_LANGUAGE="English (United States) [0x409]" />    <MATCHING_FILE NAME="WININET.DLL" SIZE="585216" CHECKSUM="0x6668671E" BIN_FILE_VERSION="6.0.2737.800" BIN_PRODUCT_VERSION="6.0.2737.800" PRODUCT_VERSION="6.00.2737.800" FILE_DESCRIPTION="Internet Extensions for Win32" COMPANY_NAME="Microsoft Corporation" PRODUCT_NAME="Microsoft® Windows® Operating System" FILE_VERSION="6.00.2737.800" ORIGINAL_FILENAME="wininet.dll" INTERNAL_NAME="wininet.dll" LEGAL_COPYRIGHT="© Microsoft Corporation. All rights reserved." VERFILEDATEHI="0x0" VERFILEDATELO="0x0" VERFILEOS="0x40004" VERFILETYPE="0x2" MODULE_TYPE="WIN32" PE_CHECKSUM="0x953E8" LINKER_VERSION="0x50001" UPTO_BIN_FILE_VERSION="6.0.2737.800" UPTO_BIN_PRODUCT_VERSION="6.0.2737.800" LINK_DATE="01/08/2004 22:23:34" UPTO_LINK_DATE="01/08/2004 22:23:34" VER_LANGUAGE="English (United States) [0x409]" />    <MATCHING_FILE NAME="winsock.dll" SIZE="2864" CHECKSUM="0x73AE8088" BIN_FILE_VERSION="3.10.0.103" BIN_PRODUCT_VERSION="3.10.0.103" PRODUCT_VERSION="3.10" FILE_DESCRIPTION="Windows Socket 16-Bit DLL" COMPANY_NAME="Microsoft Corporation" PRODUCT_NAME="Microsoft® Windows(TM) Operating System" FILE_VERSION="3.10" ORIGINAL_FILENAME="WINSOCK.DLL" INTERNAL_NAME="WINSOCK" LEGAL_COPYRIGHT="Copyright © Microsoft Corp. 1981-1996" VERFILEDATEHI="0x0" VERFILEDATELO="0x0" VERFILEOS="0x10001" VERFILETYPE="0x2" MODULE_TYPE="WIN16" S16BIT_DESCRIPTION="BSD Socket API for Windows" S16BIT_MODULE_NAME="WINSOCK" UPTO_BIN_FILE_VERSION="3.10.0.103" UPTO_BIN_PRODUCT_VERSION="3.10.0.103" VER_LANGUAGE="English (United States) [0x409]" /></EXE></DATABASE>
 
Under linux:

NVIDIA has no OpenGL.h lib

for some reason it was trying to include it. I forced it not to.

I get this at compile time

Code: [Select]
Code:
halkun@naru:~/lab> gcc stageview.cpp -o stagestageview.cpp: In function `int load(const std::string&, void**)':stageview.cpp:62: error: `assert' undeclared (first use this function)stageview.cpp:62: error: (Each undeclared identifier is reported only once for each function it appears in.)

Of course this is useless without a makefile. I have to include my X11 libs and my GL libs at link time, I'm just seeing of it would even compile first
 
Anakin: You can put glut.dll into the same directory as sceneview.exe. When windows looks for DLLs it looks into the current directory first.

halkun: OpenGL.h is a Mac library that provides stuff that is similar to the glx stuff on Linux and wgl stuff on windows. you don't need to include that.
for assert:
#include <cassert>
or
#include <assert.h>

Sorry about that.

Makefile make more sense if you have more then one file... And as I can't attach a zip file to a message I wanted to have it as simple as possible. Please try a bash script for now.

It works fine here, so if you can give me a stack trace I can have a look:
Code: [Select]
Code:
gdb stageview(inside gdb)r <somestagefile.lzs>bt
 
Anakin: You can put glut.dll into the same directory as sceneview.exe. When windows looks for DLLs it looks into the current directory first.
[/code]

still no
it crashes after a while though, as if it "tries" but cannot initialize a graphics window or something
 
Something seems to change the current directory and then the file loading fails. This worked fine for me, because my development directory is far away from the data directory and I always use the absolute path...

So what you can do is run stageview with the absolute path to the file:
Code: [Select]
Code:
 stageview D:\STAGE1\STAGE09.LZS
(if D: is your CD drive)

I did a small fix to the code above. It is not very elegant, but should cover both Unix-y and Windows-y operating systems.
 
Heh.. It's following the pattern of all the files that are on the FF7 disks for the PSX.
Essentially That's binary RSD texture data.  And it's using a standard archive style used in FF7

Now if I could only make more sense of BCX files.. things could role, there is something funny with them and I just can't quite figure out what they did differently with them.

I should have at least the beginings of these decoded (IE just the vertices and wire frame for now).  I suppose I can add POV output in a little while (grin).

Here are what I use for FF7 models in my program (which has like 20 different files now).

Code: [Select]
Code:
// Pallette/Color Look Up Tables for TIM filestypedef  UINT16 CLUT_4bpp[16];typedef  UINT16 CLUT_8bpp[256];// PSX FF7 Model datatypedef struct{   UINT16   Parent;   INT16    Length;   UINT32   Offset;}PSX_UNK_BM;typedef struct{   UINT8 R;   UINT8 G;   UINT8 B;   UINT8 U;}PSX_FF7_CLR;typedef struct{   INT16   X;   INT16   Y;   INT16   Z;   UINT16   U;}PSX_FF7_VERTEX;typedef struct{   UINT16   A;   UINT16   B;   UINT16   C;   UINT16   D;}PSX_FF7_POLY;typedef struct{   PSX_FF7_POLY  Vertexs;   PSX_FF7_CLR   Colors[3];}PSX_FF7_TRI;typedef struct{   PSX_FF7_POLY  Vertexs;   PSX_FF7_CLR   Colors[4];}PSX_FF7_QUAD;typedef struct{   PSX_FF7_POLY   Vertexs;   UINT8          U0, V0;   UINT8          PAL, ZZ;   UINT8          U1, V1;   UINT8          U2, V2;}PSX_FF7_TTRI;typedef struct{   PSX_FF7_POLY   Vertexs;   UINT8          U0, V0;   UINT8          PAL, ZZ0;   UINT8          U1, V1;   UINT8          U2, V2;   UINT8          U3, V3;   UINT16         ZZ1;}PSX_FF7_TQUAD;

Cyb
 
Heh.. It's following the pattern of all the files that are on the FF7 disks for the PSX.
It is obviously arranged that way so that it can be fed into the hardware as fast as possible. Which doesn't match the PC hardware, so I arrange it into a vertex array and triangle list. The triangle list isn't the best format, but should do. And I don't have to include a triangle stripper.  :)

Now if someone could just help decode the animation data for player and monster models... I've got the body parts and the weapons, and I've got the skeleton hierarchy. But that's useless without the angles.

BTW: Did anyone get useable data out of a Xenogears disc image? Or any other Square game?
 
Now if someone could just help decode the animation data for player and monster models..

Thats the whole problem at the moment, we CANT decode the the data...Hell, I dont even think we can FIND it.  I may be wrong though.
 
I dont even think we can FIND it.  I may be wrong though.
Oh, that's easy. There is a lot of data in the battle models that is not covered by the mesh and texture.
But so far I haven't found a system, which suggest that the data is compressed.
Can anyone tell me if the pyramid "monster" from the test battle (ENEMY000.LZS) is meant to be animated?
 
Under linux:

NVIDIA has no OpenGL.h lib

for some reason it was trying to include it. I forced it not to.

I get this at compile time

Code: [Select]
Code:
halkun@naru:~/lab> gcc stageview.cpp -o stagestageview.cpp: In function `int load(const std::string&, void**)':stageview.cpp:62: error: `assert' undeclared (first use this function)stageview.cpp:62: error: (Each undeclared identifier is reported only once for each function it appears in.)

Of course this is useless without a makefile. I have to include my X11 libs and my GL libs at link time, I'm just seeing of it would even compile first

These are the includes I used. I think you are missing a couple.

Code: [Select]
Code:
#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <assert.h>// STL#include <string>// OpenGL#include <GL/gl.h>#include <GL/gl.h>#include <GL/glu.h>#include <GL/glext.h>#include <GL/glut.h>

Also, when you link it, you will need to use -lgl -lglu -lglut.
 
Heh.. It's following the pattern of all the files that are on the FF7 disks for the PSX.
It is obviously arranged that way so that it can be fed into the hardware as fast as possible. Which doesn't match the PC hardware, so I arrange it into a vertex array and triangle list. The triangle list isn't the best format, but should do. And I don't have to include a triangle stripper.  :)
You might be better off creating a DList for that instead, which you can rotate seperately. Currently I generate everything but the textures over and over again.  I figured out what I had been doing with the textures (wrong that is).  Because of the way windows does things is the problem.  Essentially OGL was not initialized until I clicked where the data was being displayed (stupid).  None of the textures were valid because of this (dang it).  I have to reorganize it so things are done in the proper order.  How I create the textures is run through the textured triangles and Quads finding the max and mins, then use the palette data to draw on a bitmap that region.  This is done for all the textured objects.  My biggest problem has been detecting transparency in a texture.  Currently I assume color zero is transparent in all paletted textures.

Now if someone could just help decode the animation data for player and monster models... I've got the body parts and the weapons, and I've got the skeleton hierarchy. But that's useless without the angles.

BTW: Did anyone get useable data out of a Xenogears disc image? Or any other Square game?

If you looked VERY carefully at what I listed in those data structures you'll note I have the COMPLETE bone setup for FF7 in there (it's not hard to find LOL).  I found the weapons a while back too.  One needs the animation files to display the complete figure (as you might guess).  I'm sure you read my 'findings' in the FF7 model viewer thread.  The only thing I need now is (drum roll) the animation rotation information for the bones and joints like you.  

I am positive section 2 is VERY important in figuring out the animation I'm just not sure how.

Not Xeno but I have actually gotten somewhere with Ff8 and FF9.

But so far I haven't found a system, which suggest that the data is compressed.
Can anyone tell me if the pyramid "monster" from the test battle (ENEMY000.LZS) is meant to be animated?
As for compressed... It's possible but why compress something twice?  I can do a second decompression on that data and see if anything interesting comes out I suppose.

ENEMY000.LZS
I think it's a bare bones thing, if you get into the debug room you might be able to battle those debug objects and find out.  As far as I know it is just 4 triangles and a quad.  Section 2 is very suspicious here because it still is about the same size as always.

If a model has more parts (see CLOUD.LZS) then section 2 grows. It's size varies depending on the number of sections.

Cyb
 
Status
Not open for further replies.
Back
Top