123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618 |
- /* -*- Mode: C++; tab-width: 3; indent-tabs-mode: t; c-basic-offset: 3 -*- */
- /*================================================================
- *
- * Project : OpenRaider
- * Author : Mongoose
- * Website : http://www.westga.edu/~stu7440/
- * Email : stu7440@westga.edu
- * Object : OpenRaider
- * License : No use w/o permission (C) 2001 Mongoose
- * Comments: Loads TR 1, 2, 3, and 4 maps, meshes, and textures
- *
- * This file was generated using Mongoose's C++
- * template generator script. <stu7440@westga.edu>
- *
- *-- History ------------------------------------------------
- *
- * 2003.05.13:
- * Mongoose - New API, maintance cost was becoming so high
- * it was needed to sort out methods in groups
- * like my newer source code -- of course some
- * methods were altered or removed ( clean up )
- *
- * 2001.06.19:
- * Mongoose - New texture API for the new TR4/TR5 bump map
- * support, also purged textile exposure
- *
- * 2001.05.21:
- * Mongoose - Added to project OpenRaider, more documentation
- * than Freyja version I wrote ( 3d modeler )
- *
- *
- * 2000-05-13:
- * Mongoose - Added gcc and VC++ pragmas for packing
- *
- * id style typedefs for structs
- *
- * Heavy clean up and ported to C++
- *
- * I saved yuri's notes as best I could and
- * reformatted and corected as needed
- *
- * Mongoose - Created, based on:
- * tr_view's tr2io.c by Yuri Zhivago, PhD,
- * TR Rosetta Stone ( TombRaider pak format specs )
- ================================================================*/
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <math.h>
- #include <string.h>
- #include <stdarg.h>
-
- #include <TombRaider.h>
-
- #ifdef __TEST_TR5_DUMP_TGA
- #include <tga.h>
- #endif
-
- #ifdef DEBUG_MEMORY
- #include <memory_test.h>
- #endif
-
-
- void dump_textures(TombRaider *tr, char *mapname)
- {
- #ifdef __TEST_TR5_DUMP_TGA
- int i;
- unsigned char *image;
- unsigned char *bumpmap;
- char buffer[128];
- FILE *f;
-
-
- if (!tr || !mapname)
- return;
-
- // Dump textures
- printf("\n\t[Texture dumping for '%s']\n", mapname);
-
- for (i = 0; i < tr->NumTextures(); i++)
- {
- tr->Texture(i, &image, &bumpmap);
-
- if (image)
- {
- snprintf(buffer, 128, "%s-%03i-texture.tga", mapname, i);
-
- f = fopen(buffer, "wb");
-
- if (f)
- {
- if (!mtk_image__tga_save(f, image, 256, 256, 4))
- printf("\tWrote texture %s\n", buffer);
-
- fclose(f);
- }
-
- snprintf(buffer, 128, "%s.lst", mapname);
-
- f = fopen(buffer, "a");
-
- if (f)
- {
- fprintf(f, "%s-%03i-texture.tga;\n", mapname, i);
- fclose(f);
- }
-
- delete [] image;
- }
-
- if (bumpmap)
- {
- snprintf(buffer, 64, "%s-%03i-bumpmap.tga", mapname, i);
-
- f = fopen(buffer, "wb");
-
- if (f)
- {
- if (!mtk_image__tga_save(f, bumpmap, 256, 256, 4))
- printf("\tWrote texture %s\n", buffer);
-
- fclose(f);
- }
-
- delete [] bumpmap;
- }
- }
-
- for (i = 0; i < tr->NumSpecialTextures(); i++)
- {
- image = tr->SpecialTexTile(i);
-
- snprintf(buffer, 128, "%s-%03i-special.tga", mapname, i);
-
- f = fopen(buffer, "wb");
-
- if (f)
- {
- if (!mtk_image__tga_save(f, image, 256, 256, 4))
- printf("\tWrote texture %s\n", buffer);
-
- fclose(f);
- }
- else
- {
- printf("\tFailed to write texture %s\n", buffer);
- }
-
- delete [] image;
- }
- #else
- printf("Texture dumping not in this build\n");
- #endif
- }
-
-
- void dump_mesh(TombRaider *tr, char *mapname, int index)
- {
- tr2_object_texture_t *object_texture = NULL;
- tr2_mesh_t *meshes = NULL;
- unsigned int v, check;
- int i, triangles, rectangles, t_index;
- char buffer[128];
- float rgba[4];
- float s, t;
- char id[8];
- FILE *f;
-
-
- if (!mapname || !tr)
- {
- return;
- }
-
- snprintf(buffer, 128, "%s-%03i.mesh", mapname, index);
-
- object_texture = tr->ObjectTextures();
- meshes = tr->Mesh();
-
-
- f = fopen(buffer, "wb");
-
- if (!f)
- {
- perror("Failed to write mesh :");
- return;
- }
-
- // Setup header id and check points
- strncpy(id, "TRMESH", 7);
- id[7] = 0;
- check = 0xcdcdcdcd;
-
-
- fwrite(id, 8, 1, f);
- fwrite(&meshes[index].num_vertices, 2, 1, f);
- fwrite(&meshes[index].num_textured_triangles, 2, 1, f);
- fwrite(&meshes[index].num_textured_rectangles, 2, 1, f);
- fwrite(&meshes[index].num_coloured_triangles, 2, 1, f);
- fwrite(&meshes[index].num_coloured_rectangles, 2, 1, f);
- fwrite(&meshes[index].collision_size, 4, 1, f);
-
-
- // Textured triangles ////////////////////////
- fwrite(&check, 4, 1, f);
- triangles = meshes[index].num_textured_triangles;
-
- for (i = 0; triangles > 0 && i < triangles; i++)
- {
- t_index = meshes[index].textured_triangles[i].texture;
-
- // Store texture info
- fwrite(&object_texture[t_index].tile, 2, 1, f);
- fwrite(&object_texture[t_index].transparency_flags, 2, 1, f);
-
- // Store vertices
- v = meshes[index].textured_triangles[i].vertices[0];
- fwrite(&meshes[index].vertices[v].x, 2, 1, f);
- fwrite(&meshes[index].vertices[v].y, 2, 1, f);
- fwrite(&meshes[index].vertices[v].z, 2, 1, f);
-
- v = meshes[index].textured_triangles[i].vertices[1];
- fwrite(&meshes[index].vertices[v].x, 2, 1, f);
- fwrite(&meshes[index].vertices[v].y, 2, 1, f);
- fwrite(&meshes[index].vertices[v].z, 2, 1, f);
-
- v = meshes[index].textured_triangles[i].vertices[2];
- fwrite(&meshes[index].vertices[v].x, 2, 1, f);
- fwrite(&meshes[index].vertices[v].y, 2, 1, f);
- fwrite(&meshes[index].vertices[v].z, 2, 1, f);
-
- // Store texels
- s = tr->adjustTexel(object_texture[t_index].vertices[0].xpixel,
- object_texture[t_index].vertices[0].xcoordinate);
- t = tr->adjustTexel(object_texture[t_index].vertices[0].ypixel,
- object_texture[t_index].vertices[0].ycoordinate);
- fwrite(&s, 4, 1, f);
- fwrite(&t, 4, 1, f);
-
-
- s = tr->adjustTexel(object_texture[t_index].vertices[1].xpixel,
- object_texture[t_index].vertices[1].xcoordinate);
- t = tr->adjustTexel(object_texture[t_index].vertices[1].ypixel,
- object_texture[t_index].vertices[1].ycoordinate);
- fwrite(&s, 4, 1, f);
- fwrite(&t, 4, 1, f);
-
- s = tr->adjustTexel(object_texture[t_index].vertices[2].xpixel,
- object_texture[t_index].vertices[2].xcoordinate);
- t = tr->adjustTexel(object_texture[t_index].vertices[2].ypixel,
- object_texture[t_index].vertices[2].ycoordinate);
- fwrite(&s, 4, 1, f);
- fwrite(&t, 4, 1, f);
- }
-
- fwrite(&check, 4, 1, f);
-
-
- // Textured rectangles ////////////////////////
- fwrite(&check, 4, 1, f);
- rectangles = meshes[index].num_textured_rectangles;
-
- for (i = 0; rectangles > 0 && i < rectangles; i++)
- {
- t_index = meshes[index].textured_rectangles[i].texture;
-
- // Store texture info
- fwrite(&object_texture[t_index].tile, 2, 1, f);
- fwrite(&object_texture[t_index].transparency_flags, 2, 1, f);
-
- // Store vertices
- v = meshes[index].textured_rectangles[i].vertices[0];
- fwrite(&meshes[index].vertices[v].x, 2, 1, f);
- fwrite(&meshes[index].vertices[v].y, 2, 1, f);
- fwrite(&meshes[index].vertices[v].z, 2, 1, f);
-
- v = meshes[index].textured_rectangles[i].vertices[1];
- fwrite(&meshes[index].vertices[v].x, 2, 1, f);
- fwrite(&meshes[index].vertices[v].y, 2, 1, f);
- fwrite(&meshes[index].vertices[v].z, 2, 1, f);
-
- v = meshes[index].textured_rectangles[i].vertices[2];
- fwrite(&meshes[index].vertices[v].x, 2, 1, f);
- fwrite(&meshes[index].vertices[v].y, 2, 1, f);
- fwrite(&meshes[index].vertices[v].z, 2, 1, f);
-
- v = meshes[index].textured_rectangles[i].vertices[3];
- fwrite(&meshes[index].vertices[v].x, 2, 1, f);
- fwrite(&meshes[index].vertices[v].y, 2, 1, f);
- fwrite(&meshes[index].vertices[v].z, 2, 1, f);
-
- // Store texels
- s = tr->adjustTexel(object_texture[t_index].vertices[0].xpixel,
- object_texture[t_index].vertices[0].xcoordinate);
- t = tr->adjustTexel(object_texture[t_index].vertices[0].ypixel,
- object_texture[t_index].vertices[0].ycoordinate);
- fwrite(&s, 4, 1, f);
- fwrite(&t, 4, 1, f);
-
-
- s = tr->adjustTexel(object_texture[t_index].vertices[1].xpixel,
- object_texture[t_index].vertices[1].xcoordinate);
- t = tr->adjustTexel(object_texture[t_index].vertices[1].ypixel,
- object_texture[t_index].vertices[1].ycoordinate);
- fwrite(&s, 4, 1, f);
- fwrite(&t, 4, 1, f);
-
- s = tr->adjustTexel(object_texture[t_index].vertices[2].xpixel,
- object_texture[t_index].vertices[2].xcoordinate);
- t = tr->adjustTexel(object_texture[t_index].vertices[2].ypixel,
- object_texture[t_index].vertices[2].ycoordinate);
- fwrite(&s, 4, 1, f);
- fwrite(&t, 4, 1, f);
-
- s = tr->adjustTexel(object_texture[t_index].vertices[3].xpixel,
- object_texture[t_index].vertices[3].xcoordinate);
- t = tr->adjustTexel(object_texture[t_index].vertices[3].ypixel,
- object_texture[t_index].vertices[3].ycoordinate);
- fwrite(&s, 4, 1, f);
- fwrite(&t, 4, 1, f);
- }
-
- fwrite(&check, 4, 1, f);
-
- // Coloured triangles ////////////////////////
- fwrite(&check, 4, 1, f);
- triangles = meshes[index].num_coloured_triangles;
-
- for (i = 0; triangles > 0 && i < triangles; i++)
- {
- // Store vertices
- v = meshes[index].coloured_triangles[i].vertices[0];
- fwrite(&meshes[index].vertices[v].x, 2, 1, f);
- fwrite(&meshes[index].vertices[v].y, 2, 1, f);
- fwrite(&meshes[index].vertices[v].z, 2, 1, f);
-
- v = meshes[index].coloured_triangles[i].vertices[1];
- fwrite(&meshes[index].vertices[v].x, 2, 1, f);
- fwrite(&meshes[index].vertices[v].y, 2, 1, f);
- fwrite(&meshes[index].vertices[v].z, 2, 1, f);
-
- v = meshes[index].coloured_triangles[i].vertices[2];
- fwrite(&meshes[index].vertices[v].x, 2, 1, f);
- fwrite(&meshes[index].vertices[v].y, 2, 1, f);
- fwrite(&meshes[index].vertices[v].z, 2, 1, f);
-
- // Store color
- switch (tr->Engine())
- {
- case TR_VERSION_1:
- tr->getColor(meshes[index].coloured_triangles[i].texture
- & 0xff, rgba);
- break;
- default:
- tr->getColor((meshes[index].coloured_triangles[i].texture>>8)
- & 0xff, rgba);
- }
-
- s = rgba[0];
- t = rgba[1];
- fwrite(&s, 4, 1, f);
- fwrite(&t, 4, 1, f);
-
- s = rgba[2];
- t = rgba[3];
- fwrite(&s, 4, 1, f);
- fwrite(&t, 4, 1, f);
- }
-
- fwrite(&check, 4, 1, f);
-
- // Coloured rectangles ////////////////////////
- fwrite(&check, 4, 1, f);
- rectangles = meshes[index].num_coloured_rectangles;
-
- for (i = 0; rectangles > 0 && i < rectangles; i++)
- {
- // Store vertices
- v = meshes[index].coloured_rectangles[i].vertices[0];
- fwrite(&meshes[index].vertices[v].x, 2, 1, f);
- fwrite(&meshes[index].vertices[v].y, 2, 1, f);
- fwrite(&meshes[index].vertices[v].z, 2, 1, f);
-
- v = meshes[index].coloured_rectangles[i].vertices[1];
- fwrite(&meshes[index].vertices[v].x, 2, 1, f);
- fwrite(&meshes[index].vertices[v].y, 2, 1, f);
- fwrite(&meshes[index].vertices[v].z, 2, 1, f);
-
- v = meshes[index].coloured_rectangles[i].vertices[2];
- fwrite(&meshes[index].vertices[v].x, 2, 1, f);
- fwrite(&meshes[index].vertices[v].y, 2, 1, f);
- fwrite(&meshes[index].vertices[v].z, 2, 1, f);
-
- v = meshes[index].coloured_rectangles[i].vertices[3];
- fwrite(&meshes[index].vertices[v].x, 2, 1, f);
- fwrite(&meshes[index].vertices[v].y, 2, 1, f);
- fwrite(&meshes[index].vertices[v].z, 2, 1, f);
-
- // Store color
- switch (tr->Engine())
- {
- case TR_VERSION_1:
- tr->getColor(meshes[index].coloured_rectangles[i].texture
- & 0xff, rgba);
- break;
- default:
- tr->getColor((meshes[index].coloured_rectangles[i].texture>>8)
- & 0xff, rgba);
- }
-
- s = rgba[0];
- t = rgba[1];
- fwrite(&s, 4, 1, f);
- fwrite(&t, 4, 1, f);
-
- s = rgba[2];
- t = rgba[3];
- fwrite(&s, 4, 1, f);
- fwrite(&t, 4, 1, f);
- }
-
- fwrite(&check, 4, 1, f);
- fclose(f);
-
- printf(".");
- fflush(stdout);
- }
-
-
- void dump_lara_stuff(char *mapname, TombRaider &tr)
- {
- unsigned int i, j, k, n;
- tr2_moveable_t *moveable = tr.Moveable();
- unsigned int numMoveables = tr.NumMoveables();
- char filename[64];
- unsigned char *riff;
- unsigned int riffSz, total = 0;
- FILE *f;
-
-
- snprintf(filename, 63, "%s-lara.nfo", mapname);
- f = fopen(filename, "w");
-
- if (!f)
- {
- perror("Failed to write lara.nfo: ");
- return;
- }
-
- for (i = 0; i < numMoveables; ++i)
- {
- j = n = 0;
-
- if (moveable[i].object_id == 0)
- {
- j = moveable[i].starting_mesh;
- n = moveable[i].num_meshes + j;
-
- fprintf(f, "Lara (%i)\n", i);
- }
- else if (moveable[i].object_id == 30)
- {
- j = moveable[i].starting_mesh;
- n = moveable[i].num_meshes + j;
-
- fprintf(f, "Lara ponytail\n");
- }
- else if (tr.Engine() == TR_VERSION_4)
- {
- switch (moveable[i].object_id)
- {
- case 8: // Joints, ( interconnecting skin/ploys )
- case 9:
- fprintf(f, "TR4 lara joints (%i)\n", i);
- j = moveable[i].starting_mesh;
- n = moveable[i].num_meshes + j;
- }
- }
-
- for (k = j; j < n; ++j)
- {
- fprintf(f, "\tMesh[%i] = %i\n", (j - k), j);
- }
- }
-
- fclose(f);
-
- printf("\nDumping %i audio samples: ", tr.getSoundSamplesCount());
-
- for (i = 0, j = 0; i < tr.getSoundSamplesCount(); ++i)
- {
- tr.getSoundSample(i, &riffSz, &riff);
-
- total += riffSz;
-
- snprintf(filename, 63, "%s-%03i.wav", mapname, j++);
- f = fopen(filename, "wb");
-
- if (!f)
- {
- perror("Failed to write riff.wav: ");
- continue;
- }
-
- fwrite(riff, 1, riffSz, f);
- fclose(f);
-
- delete [] riff;
-
- printf(".");
- fflush(stdout);
- }
-
- printf("\n");
-
- if (total)
- {
- printf("Dumped %ibytes (%.2f MB) of audio samples\n",
- total, (float)total/1024000.0);
- }
- }
-
-
- void percent_callback(int p)
- {
- printf("Level %i%% loaded\n", p);
- }
-
-
- int test_main(int argc, char *argv[])
- {
- TombRaider tr;
- char mapname[128];
- int len, i, j;
-
-
- printf("[TombRaider class test]\n");
-
- tr.setDebug(true);
-
- if (argc > 2)
- {
- // Strip for mapname //////////////////////////////
- len = strlen(argv[2]);
-
- for (i = len, j = 0; i > 0; i--, j++)
- if (argv[2][i] == '/' || argv[2][i] == '\\')
- break;
-
- j--;
-
- memset(mapname, 0, 128);
-
- for (i = 0; i < len - j && i < 30; i++)
- mapname[i] = argv[2][i + len - j];
-
- ////////////////////////////////////////////////////
-
-
- if (strncmp(argv[1], "load", 4) == 0)
- {
- if (!tr.Load(argv[2], percent_callback))
- {
- printf("\nmain: Load reports success.\n");
- }
- }
- else if (strncmp(argv[1], "dump", 4) == 0)
- {
- if (!tr.Load(argv[2], percent_callback))
- {
- printf("\nmain: Load reports success.\n");
-
- dump_textures(&tr, mapname);
-
- printf("Mesh dumping: ");
- for (i = 0; i < tr.getMeshCount(); i++)
- {
- dump_mesh(&tr, mapname, i);
- }
-
- if (argc > 3)
- {
- printf("\nLoading external sound SFX.\n");
- tr.loadSFX(argv[3]);
- }
-
- dump_lara_stuff(mapname, tr);
-
- printf("\n");
- }
- else
- {
- printf("\nmain: Load failed.\n");
- }
- }
- else
- printf("\n\n%s [ load | dump ] filename [sound.sfx]\n", argv[0]);
- }
- else
- {
- printf("\n\n%s [ load | dump ] filename [sound.sfx]\n", argv[0]);
- }
-
- return 0;
- }
-
-
- int main(int argc, char *argv[])
- {
- test_main(argc, argv);
-
- #ifdef DEBUG_MEMORY
- dump_memory_report();
- #endif
-
- return 0;
- }
|