diff --git a/Makefile b/Makefile index 69eca309..75728a47 100644 --- a/Makefile +++ b/Makefile @@ -459,14 +459,8 @@ binaries-h2data: \ .PHONY: binaries-tools-quake3 binaries-tools-quake3: \ - binaries-q3data \ binaries-q3map2 \ -.PHONY: binaries-q3data -binaries-q3data: \ - $(INSTALLDIR)/q3data.$(EXE) \ - $(INSTALLDIR)/q3data \ - .PHONY: binaries-q3map2 binaries-q3map2: \ $(INSTALLDIR)/q3map2.$(EXE) \ @@ -821,36 +815,6 @@ libetclib.$(A): CPPFLAGS_EXTRA := -Ilibs libetclib.$(A): \ libs/etclib.o \ -$(INSTALLDIR)/q3data.$(EXE): LIBS_EXTRA := $(LIBS_XML) $(LIBS_GLIB) $(LIBS_ZLIB) -$(INSTALLDIR)/q3data.$(EXE): CPPFLAGS_EXTRA := $(CPPFLAGS_XML) $(CPPFLAGS_GLIB) $(CPPFLAGS_ZLIB) -Itools/quake3/common -Ilibs -Iinclude -$(INSTALLDIR)/q3data.$(EXE): \ - tools/quake3/common/aselib.o \ - tools/quake3/common/bspfile.o \ - tools/quake3/common/cmdlib.o \ - tools/quake3/common/imagelib.o \ - tools/quake3/common/inout.o \ - tools/quake3/common/md4.o \ - tools/quake3/common/scriplib.o \ - tools/quake3/common/trilib.o \ - tools/quake3/common/unzip.o \ - tools/quake3/common/vfs.o \ - tools/quake3/common/miniz.o \ - tools/quake3/q3data/3dslib.o \ - tools/quake3/q3data/compress.o \ - tools/quake3/q3data/images.o \ - tools/quake3/q3data/md3lib.o \ - tools/quake3/q3data/models.o \ - tools/quake3/q3data/p3dlib.o \ - tools/quake3/q3data/polyset.o \ - tools/quake3/q3data/q3data.o \ - tools/quake3/q3data/stripper.o \ - tools/quake3/q3data/video.o \ - libfilematch.$(A) \ - libetclib.$(A) \ - libl_net.$(A) \ - libmathlib.$(A) \ - $(if $(findstring Win32,$(OS)),icons/q3data.o,) \ - $(INSTALLDIR)/radiant.$(EXE): LDFLAGS_EXTRA := $(MWINDOWS) $(INSTALLDIR)/radiant.$(EXE): LIBS_EXTRA := $(LIBS_GL) $(LIBS_DL) $(LIBS_XML) $(LIBS_GLIB) $(LIBS_GTK) $(LIBS_GTKGLEXT) $(LIBS_ZLIB) $(LIBS_PANGOFT2) $(INSTALLDIR)/radiant.$(EXE): CPPFLAGS_EXTRA := $(CPPFLAGS_GL) $(CPPFLAGS_DL) $(CPPFLAGS_XML) $(CPPFLAGS_GLIB) $(CPPFLAGS_GTK) $(CPPFLAGS_GTKGLEXT) $(CPPFLAGS_PANGOFT2) -Ilibs -Iinclude diff --git a/icons/q3data.ico b/icons/q3data.ico deleted file mode 100644 index 8f441941..00000000 Binary files a/icons/q3data.ico and /dev/null differ diff --git a/setup/apple/Makefile b/setup/apple/Makefile index a1bf3d17..59b71b44 100644 --- a/setup/apple/Makefile +++ b/setup/apple/Makefile @@ -64,7 +64,6 @@ bundle: dylibbundler -b \ -x $(BINDIR)/radiant.x86_64 \ -x $(BINDIR)/q2map.x86_64 \ - -x $(BINDIR)/q3data.x86_64 \ -x $(BINDIR)/q3map2.x86_64 \ -x $(BINDIR)/qdata3.x86_64 \ `find $(BINDIR)/modules -name "*.dylib" | xargs -I {} echo -x {}` \ diff --git a/setup/data/tools/q3data.qdt b/setup/data/tools/q3data.qdt deleted file mode 100644 index ba30ee12..00000000 --- a/setup/data/tools/q3data.qdt +++ /dev/null @@ -1,552 +0,0 @@ -$aseconvert models/mapobjects/spotlamp/spotlamp_x.ase -$exit - - -$aseconvert models/weapons2/machinegun/machinegun.ase -weapon -$aseconvert models/weapons2/bfg/bfg.ase -weapon -$aseconvert models/weapons2/railgun/railgun.ase -weapon -$aseconvert models/weapons2/shotgun/shotgun.ase -weapon - -$aseconvert models/weapons2/meshes/chaingun.ase -weapon -$aseconvert models/weapons2/meshes/flamethrower.ase -weapon -$aseconvert models/weapons2/meshes/grapple.ase -weapon -$aseconvert models/weapons2/meshes/grenadel.ase -weapon -$aseconvert models/weapons2/meshes/lightning.ase -weapon -$aseconvert models/weapons2/meshes/plasma.ase -weapon -$aseconvert models/weapons2/meshes/railgun.ase -weapon -$aseconvert models/weapons2/meshes/ricochet.ase -weapon -$aseconvert models/weapons2/meshes/rocketl.ase -weapon -$aseconvert models/weapons2/meshes/shotgun.ase -weapon - - -$aseconvert models/mapobjects/chain1.ase -$aseconvert models/mapobjects/chain2.ase -$aseconvert models/mapobjects/chain3.ase -$aseconvert models/mapobjects/chain4.ase - -$exit - -$aseanimconvert models/players/light/bandolier/bandolier.ase -origin 0 0 24 -playerparms 75 138 140 1 -$aseanimconvert models/players/light/brandon/4brandon.ase -origin 0 0 24 -playerparms 75 138 140 1 -$aseanimconvert models/players/light/cash/4cash.ase -origin 0 0 24 -playerparms 75 138 140 1 -$aseanimconvert models/players/light/doom/doom.ase -origin 0 0 24 -playerparms 75 138 140 1 -$aseanimconvert models/players/light/shauna/shauna.ase -origin 0 0 24 -playerparms 75 138 140 1 -$aseanimconvert models/players/medium/tim/4tim.ase -origin 0 0 24 -playerparms 75 138 140 1 -$aseanimconvert models/players/medium/visor/4visor.ase -origin 0 0 24 -playerparms 75 138 140 1 -$aseanimconvert models/players/medium/xian/4xian.ase -origin 0 0 24 -playerparms 75 138 140 1 -$aseanimconvert models/players/medium/carmack/carmack.ase -origin 0 0 24 -playerparms 75 138 140 1 -$aseanimconvert models/players/heavy/paulj/4paulj.ase -origin 0 0 24 -playerparms 75 138 140 1 -$aseanimconvert models/players/heavy/brock/brock.ase -origin 0 0 24 -playerparms 75 138 140 1 - -$exit - -// note: playerparms are "skipStart skipEnd maxUpperFrames maxHeadFrames" -$aseanimconvert models/players/medium/visor/4visor.ase -origin 0 0 24 -playerparms 75 138 140 1 -$aseanimconvert models/players/medium/visor/4visor.ase -lod 1 0 -origin 0 0 24 -playerparms 75 138 140 1 -$aseanimconvert models/players/medium/visor/4visor.ase -lod 2 0 -origin 0 0 24 -playerparms 75 138 140 1 - - - -$aseconvert models/powerups/ammo/backpack.ase - -$aseconvert models/weapons2/meshes/assault.ase -weapon -$aseconvert models/weapons2/meshes/chaingun.ase -weapon -$aseconvert models/weapons2/meshes/flamethrower.ase -weapon -$aseconvert models/weapons2/meshes/grapple.ase -weapon -$aseconvert models/weapons2/meshes/grenadel.ase -weapon -$aseconvert models/weapons2/meshes/lightning.ase -weapon -$aseconvert models/weapons2/meshes/plasma.ase -weapon -$aseconvert models/weapons2/meshes/railgun.ase -weapon -$aseconvert models/weapons2/meshes/ricochet.ase -weapon -$aseconvert models/weapons2/meshes/rocketl.ase -weapon -$aseconvert models/weapons2/meshes/shotgun.ase -weapon - -$aseconvert models/mapobjects/arenalogo.ase - -// -// talk sprite -// -$modelname sprites/balloon -$cd sprites -$spritebase -8 -8 16 16 -$spriteshader sprites/balloon3.tga - -// plasma ball sprite -$modelname sprites/plasma -$cd sprites -$spritebase -16 -16 32 32 -$spriteshader sprites/plasma1.tga -$spriteshader sprites/plasma2.tga - -// -// player models -// note: playerparms are "skipStart skipEnd maxUpperFrames maxHeadFrames" -// -$aseanimconvert models/players/light/bandolier/bandolier.ase -origin 0 0 24 -playerparms 75 138 140 1 -$aseanimconvert models/players/light/brandon/4brandon.ase -origin 0 0 24 -playerparms 75 138 140 1 -$aseanimconvert models/players/light/cash/4cash.ase -origin 0 0 24 -playerparms 75 138 140 1 -$aseanimconvert models/players/light/doom/doom.ase -origin 0 0 24 -playerparms 75 138 140 1 -$aseanimconvert models/players/light/shauna/shauna.ase -origin 0 0 24 -playerparms 75 138 140 1 -$aseanimconvert models/players/medium/tim/4tim.ase -origin 0 0 24 -playerparms 75 138 140 1 -$aseanimconvert models/players/medium/visor/4visor.ase -origin 0 0 24 -playerparms 75 138 140 1 -$aseanimconvert models/players/medium/xian/4xian.ase -origin 0 0 24 -playerparms 75 138 140 1 -$aseanimconvert models/players/medium/carmack/carmack.ase -origin 0 0 24 -playerparms 75 138 140 1 -$aseanimconvert models/players/heavy/paulj/4paulj.ase -origin 0 0 24 -playerparms 75 138 140 1 -$aseanimconvert models/players/heavy/brock/brock.ase -origin 0 0 24 -playerparms 75 138 140 1 - -// -// weaphits -// -$modelname models/weaphits/bullet -$cd models/weaphits -$base bullet01.3ds -$frame bullet01.3ds -$frame bullet02.3ds -$frame bullet03.3ds -$frame bullet04.3ds -$frame bullet05.3ds -$frame bullet06.3ds -$skin bullet01.3ds -$skin bullet03.3ds -$skin bullet05.3ds - -$modelname models/weaphits/ring01 -$cd models/weaphits -$base ring01_1.3ds -$frame ring01_1.3ds -$frame ring01_2.3ds -$frame ring01_3.3ds -$frame ring01_4.3ds -$frame ring01_5.3ds -$frame ring01_6.3ds -$skin ring01_1.3ds -$skin ring01_3.3ds -$skin ring01_5.3ds - -$modelname models/weaphits/ring02 -$cd models/weaphits -$base ring02_1.3ds -$frame ring02_1.3ds -$frame ring02_2.3ds -$frame ring02_3.3ds -$frame ring02_4.3ds -$frame ring02_5.3ds -$frame ring02_6.3ds -$skin ring02_1.3ds -$skin ring02_3.3ds -$skin ring02_5.3ds - -$modelname models/weaphits/boomgra -$cd models/weaphits -$base boomgra1.3ds -$frame boomgra1.3ds -$frame boomgra2.3ds -$frame boomgra3.3ds -$frame boomgra4.3ds -$frame boomgra5.3ds -$frame boomgra6.3ds -$skin boomgra1.3ds -$skin boomgra3.3ds -$skin boomgra5.3ds - -$modelname models/weaphits/boom01 -$cd models/weaphits -$base boom01_1.3ds -$frame boom01_1.3ds -$frame boom01_2.3ds -$frame boom01_3.3ds -$frame boom01_4.3ds -$frame boom01_5.3ds -$frame boom01_6.3ds -$skin boom01_1.3ds -$skin boom01_3.3ds -$skin boom01_5.3ds - -$modelname models/weaphits/boom02 -$cd models/weaphits -$base boom02_1.3ds -$frame boom02_1.3ds -$frame boom02_2.3ds -$frame boom02_3.3ds -$frame boom02_4.3ds -$frame boom02_5.3ds -$frame boom02_6.3ds -$skin boom02_1.3ds -$skin boom02_3.3ds -$skin boom02_5.3ds - -$modelname models/weaphits/boom03 -$cd models/weaphits -$base boom03_1.3ds -$frame boom03_1.3ds -$frame boom03_2.3ds -$frame boom03_3.3ds -$frame boom03_4.3ds -$frame boom03_5.3ds -$frame boom03_6.3ds -$skin boom03_1.3ds -$skin boom03_3.3ds -$skin boom03_5.3ds - -$modelname models/weaphits/boom04 -$cd models/weaphits -$base boom04_1.3ds -$frame boom04_1.3ds -$frame boom04_2.3ds -$frame boom04_3.3ds -$frame boom04_4.3ds -$frame boom04_5.3ds -$frame boom04_6.3ds -$skin boom04_1.3ds -$skin boom04_3.3ds -$skin boom04_5.3ds - -$modelname models/weaphits/boom05 -$cd models/weaphits -$base boom05_1.3ds -$frame boom05_1.3ds -$frame boom05_2.3ds -$frame boom05_3.3ds -$frame boom05_4.3ds -$frame boom05_5.3ds -$frame boom05_6.3ds -$skin boom05_1.3ds -$skin boom05_3.3ds -$skin boom05_5.3ds - -// -// point powerups -// -$aseconvert models/powerups/points/small.ase -$aseconvert models/powerups/points/medium.ase -$aseconvert models/powerups/points/large.ase - -// -// ammo -// -$aseconvert models\powerups\ammo\bfgam.ASE -$aseconvert models\powerups\ammo\bfgam_1.ASE -$aseconvert models\powerups\ammo\bouncyam.ASE -$aseconvert models\powerups\ammo\bouncyam_1.ASE -$aseconvert models\powerups\ammo\carbineam.ASE -$aseconvert models\powerups\ammo\carbineam_1.ASE -$aseconvert models\powerups\ammo\flameam.ASE -$aseconvert models\powerups\ammo\flameam_1.ASE -$aseconvert models\powerups\ammo\grenadeam.ASE -$aseconvert models\powerups\ammo\grenadeam_1.ASE -$aseconvert models\powerups\ammo\lightningam.ASE -$aseconvert models\powerups\ammo\lightningam_1.ASE -$aseconvert models\powerups\ammo\machinegunam.ASE -$aseconvert models\powerups\ammo\machinegunam_1.ASE -$aseconvert models\powerups\ammo\plasmaam.ASE -$aseconvert models\powerups\ammo\plasmaam_1.ASE -$aseconvert models\powerups\ammo\railgunam.ASE -$aseconvert models\powerups\ammo\railgunam_1.ASE -$aseconvert models\powerups\ammo\rocketam.ASE -$aseconvert models\powerups\ammo\rocketam_1.ASE -$aseconvert models\powerups\ammo\shotgunam.ASE -$aseconvert models\powerups\ammo\shotgunam_1.ASE - -$aseconvert models/powerups/ammo/backpack.ase - -// -// missiles -// -$modelname models/ammo/plasma/plasma -$cd models/ammo/plasma -$base plasma1.3ds -$frame plasma1.3ds -$skin plasma1.3ds - -$modelname models/ammo/laser/laser -$cd models/ammo/laser -$base laser1.3ds -$frame laser1.3ds -$skin laser1.3ds - -$modelname models/ammo/rocket/rocket -$cd models/ammo/rocket -$base rocket1.3ds -$frame rocket1.3ds -$skin rocket1.3ds -$skin rocket2.3ds - -$aseconvert models/ammo/grenade1.ase -$aseconvert models/explosions/smoke2.ase - -// -// map objects -// -$aseconvert models/mapobjects/ceilinglamp1.ase -$aseconvert models/mapobjects/ceilinglamp2.ase -$aseconvert models/mapobjects/chain1.ase -$aseconvert models/mapobjects/chain2.ase -$aseconvert models/mapobjects/chain3.ase -$aseconvert models/mapobjects/chain4.ase -$aseconvert models/mapobjects/crux.ase -$aseconvert models/mapobjects/floorlamp1.ase -$aseconvert models/mapobjects/floorlamp2.ase -$aseconvert models/mapobjects/hook.ase -$aseconvert models/mapobjects/impale.ase -$aseconvert models/mapobjects/standinglamp1.ase -$aseconvert models/mapobjects/standinglamp2.ase -$aseconvert models/mapobjects/standinglamp3.ase -$aseconvert models/mapobjects/walllamp1.ase -$aseconvert models/mapobjects/walllamp2.ase -$aseconvert models/mapobjects/walllamp3.ase - - -// -// objects -// -$aseconvert models/objects/dmspot.ase -origin 0 0 24 -$aseconvert models/objects/box01.ase - -// -// weapons -// -$aseconvert models/weapons2/meshes/assault.ase -weapon -$aseconvert models/weapons2/meshes/bfg.ase -weapon -$aseconvert models/weapons2/meshes/chaingun.ase -weapon -$aseconvert models/weapons2/meshes/flamethrower.ase -weapon -$aseconvert models/weapons2/meshes/grapple.ase -weapon -$aseconvert models/weapons2/meshes/grenadel.ase -weapon -$aseconvert models/weapons2/meshes/lightning.ase -weapon -$aseconvert models/weapons2/meshes/plasma.ase -weapon -$aseconvert models/weapons2/meshes/railgun.ase -weapon -$aseconvert models/weapons2/meshes/ricochet.ase -weapon -$aseconvert models/weapons2/meshes/rocketl.ase -weapon -$aseconvert models/weapons2/meshes/shotgun.ase -weapon - -// -// blood -// -$modelname models/weaphits/blood -$cd models/weaphits -$spritebase -16 -16 32 32 -$spriteshader models/weaphits/blood201.tga -$spriteshader models/weaphits/blood202.tga -$spriteshader models/weaphits/blood203.tga -$spriteshader models/weaphits/blood204.tga -$spriteshader models/weaphits/blood205.tga - - -// -// missiles -// -$modelname models/ammo/plasma/plasma -$cd models/ammo/plasma -$base plasma1.3ds -$frame plasma1.3ds -$skin plasma1.3ds - -$modelname models/ammo/laser/laser -$cd models/ammo/laser -$base laser1.3ds -$frame laser1.3ds -$skin laser1.3ds - - -$modelname models/ammo/rocket/rocket -$cd models/ammo/rocket -$base rocket1.3ds -$frame rocket1.3ds -$skin rocket1.3ds -$skin rocket2.3ds - - -// weaphits - -$modelname models/weaphits/bullet -$cd models/weaphits -$base bullet01.3ds -$frame bullet01.3ds -$frame bullet02.3ds -$frame bullet03.3ds -$frame bullet04.3ds -$frame bullet05.3ds -$frame bullet06.3ds -$skin bullet01.3ds -$skin bullet03.3ds -$skin bullet05.3ds - -$modelname models/weaphits/ring01 -$cd models/weaphits -$base ring01_1.3ds -$frame ring01_1.3ds -$frame ring01_2.3ds -$frame ring01_3.3ds -$frame ring01_4.3ds -$frame ring01_5.3ds -$frame ring01_6.3ds -$skin ring01_1.3ds -$skin ring01_3.3ds -$skin ring01_5.3ds - -$modelname models/weaphits/ring02 -$cd models/weaphits -$base ring02_1.3ds -$frame ring02_1.3ds -$frame ring02_2.3ds -$frame ring02_3.3ds -$frame ring02_4.3ds -$frame ring02_5.3ds -$frame ring02_6.3ds -$skin ring02_1.3ds -$skin ring02_3.3ds -$skin ring02_5.3ds - -$modelname models/weaphits/boomgra -$cd models/weaphits -$base boomgra1.3ds -$frame boomgra1.3ds -$frame boomgra2.3ds -$frame boomgra3.3ds -$frame boomgra4.3ds -$frame boomgra5.3ds -$frame boomgra6.3ds -$skin boomgra1.3ds -$skin boomgra3.3ds -$skin boomgra5.3ds - -$modelname models/weaphits/boom01 -$cd models/weaphits -$base boom01_1.3ds -$frame boom01_1.3ds -$frame boom01_2.3ds -$frame boom01_3.3ds -$frame boom01_4.3ds -$frame boom01_5.3ds -$frame boom01_6.3ds -$skin boom01_1.3ds -$skin boom01_3.3ds -$skin boom01_5.3ds - -$modelname models/weaphits/boom02 -$cd models/weaphits -$base boom02_1.3ds -$frame boom02_1.3ds -$frame boom02_2.3ds -$frame boom02_3.3ds -$frame boom02_4.3ds -$frame boom02_5.3ds -$frame boom02_6.3ds -$skin boom02_1.3ds -$skin boom02_3.3ds -$skin boom02_5.3ds - -$modelname models/weaphits/boom03 -$cd models/weaphits -$base boom03_1.3ds -$frame boom03_1.3ds -$frame boom03_2.3ds -$frame boom03_3.3ds -$frame boom03_4.3ds -$frame boom03_5.3ds -$frame boom03_6.3ds -$skin boom03_1.3ds -$skin boom03_3.3ds -$skin boom03_5.3ds - -$modelname models/weaphits/boom04 -$cd models/weaphits -$base boom04_1.3ds -$frame boom04_1.3ds -$frame boom04_2.3ds -$frame boom04_3.3ds -$frame boom04_4.3ds -$frame boom04_5.3ds -$frame boom04_6.3ds -$skin boom04_1.3ds -$skin boom04_3.3ds -$skin boom04_5.3ds - -$modelname models/weaphits/boom05 -$cd models/weaphits -$base boom05_1.3ds -$frame boom05_1.3ds -$frame boom05_2.3ds -$frame boom05_3.3ds -$frame boom05_4.3ds -$frame boom05_5.3ds -$frame boom05_6.3ds -$skin boom05_1.3ds -$skin boom05_3.3ds -$skin boom05_5.3ds - - -// -// armor -// -$aseconvert models/powerups/armor/armor_red.ase -$aseconvert models/powerups/armor/armor_yel.ase -$aseconvert models/powerups/armor/armor_grn.ase -$aseconvert models/powerups/armor/shard.ase -$aseconvert models/powerups/armor/shard_sphere.ase -$aseconvert models/powerups/armor/shard_sphere_1.ase - -// -// health -// -$aseconvert models/powerups/health/small.ase -$aseconvert models/powerups/health/small_1.ase -$aseconvert models/powerups/health/medium.ase -$aseconvert models/powerups/health/medium_1.ase -$aseconvert models/powerups/health/large.ase -$aseconvert models/powerups/health/large_1.ase -$aseconvert models/powerups/health/mega.ase -$aseconvert models/powerups/health/mega_1.ase - -// -// holdable powerups -// -$aseconvert models/powerups/holdable/ringodeth.ase -$aseconvert models/powerups/holdable/medkit.ase -$aseconvert models/powerups/holdable/teleporter.ase - -// -// instant powerups -// -$aseconvert models/powerups/instant/enviro.ase -$aseconvert models/powerups/instant/enviro_1.ase -$aseconvert models/powerups/instant/enviro_ring.ase -$aseconvert models/powerups/instant/enviro_ring_1.ase -$aseconvert models/powerups/instant/flight.ase -$aseconvert models/powerups/instant/flight_1.ase -$aseconvert models/powerups/instant/flight_ring.ase -$aseconvert models/powerups/instant/flight_ring_1.ase -$aseconvert models/powerups/instant/haste.ase -$aseconvert models/powerups/instant/haste_1.ase -$aseconvert models/powerups/instant/haste_ring.ase -$aseconvert models/powerups/instant/haste_ring_1.ase -$aseconvert models/powerups/instant/invis.ase -$aseconvert models/powerups/instant/invis_1.ase -$aseconvert models/powerups/instant/invis_ring.ase -$aseconvert models/powerups/instant/invis_ring_1.ase -$aseconvert models/powerups/instant/scan.ase -$aseconvert models/powerups/instant/scan_1.ase -$aseconvert models/powerups/instant/scan_ring.ase -$aseconvert models/powerups/instant/scan_ring_1.ase -$aseconvert models/powerups/instant/quad.ase -$aseconvert models/powerups/instant/quad_1.ase -$aseconvert models/powerups/instant/quad_ring.ase -$aseconvert models/powerups/instant/quad_ring_1.ase -$aseconvert models/powerups/instant/regen.ase -$aseconvert models/powerups/instant/regen_1.ase -$aseconvert models/powerups/instant/regen_ring.ase -$aseconvert models/powerups/instant/regen_ring_1.ase - -$exit - -// -// maps -// -$maps test_box test_items mirror mirror2 - - -// -// misc -// -$file q3default.cfg - - diff --git a/tools/quake3/common/aselib.cpp b/tools/quake3/common/aselib.cpp deleted file mode 100644 index b115f0d8..00000000 --- a/tools/quake3/common/aselib.cpp +++ /dev/null @@ -1,862 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#include "aselib.h" -#include "cmdlib.h" -#include "inout.h" -#include "qstringops.h" -#include "qpathops.h" - -#include -#include -#include - -#define MAX_ASE_MATERIALS 32 -#define MAX_ASE_OBJECTS 64 -#define MAX_ASE_ANIMATIONS 32 -#define MAX_ASE_ANIMATION_FRAMES 512 - -#define VERBOSE( x ) { if ( ase.verbose ) { Sys_Printf x ; } } - -typedef struct -{ - float x, y, z; - float nx, ny, nz; - float s, t; -} aseVertex_t; - -typedef struct -{ - float s, t; -} aseTVertex_t; - -typedef int aseFace_t[3]; - -typedef struct -{ - int numFaces; - int numVertexes; - int numTVertexes; - - int timeValue; - - aseVertex_t *vertexes; - aseTVertex_t *tvertexes; - aseFace_t *faces, *tfaces; - - int currentFace, currentVertex; -} aseMesh_t; - -typedef struct -{ - int numFrames; - aseMesh_t frames[MAX_ASE_ANIMATION_FRAMES]; - - int currentFrame; -} aseMeshAnimation_t; - -typedef struct -{ - char name[128]; -} aseMaterial_t; - -/* -** contains the animate sequence of a single surface -** using a single material -*/ -typedef struct -{ - char name[128]; - - int materialRef; - int numAnimations; - - aseMeshAnimation_t anim; - -} aseGeomObject_t; - -typedef struct -{ - int numMaterials; - aseMaterial_t materials[MAX_ASE_MATERIALS]; - aseGeomObject_t objects[MAX_ASE_OBJECTS]; - - char *buffer; - char *curpos; - int len; - - int currentObject; - bool verbose; - bool grabAnims; - -} ase_t; - -static char s_token[1024]; -static ase_t ase; -static char gl_filename[1024]; - -static void ASE_Process( void ); -static void ASE_FreeGeomObject( int ndx ); - -/* -** ASE_Load -*/ -void ASE_Load( const char *filename, bool verbose, bool grabAnims ){ - FILE *fp = fopen( filename, "rb" ); - - if ( !fp ) { - Error( "File not found '%s'", filename ); - } - - memset( &ase, 0, sizeof( ase ) ); - - ase.verbose = verbose; - ase.grabAnims = grabAnims; - ase.len = Q_filelength( fp ); - - ase.curpos = ase.buffer = safe_malloc( ase.len ); - - Sys_Printf( "Processing '%s'\n", filename ); - - if ( fread( ase.buffer, ase.len, 1, fp ) != 1 ) { - fclose( fp ); - Error( "fread() != -1 for '%s'", filename ); - } - - fclose( fp ); - - strcpy( gl_filename, filename ); - - ASE_Process(); -} - -/* -** ASE_Free -*/ -void ASE_Free( void ){ - int i; - - for ( i = 0; i < ase.currentObject; i++ ) - { - ASE_FreeGeomObject( i ); - } -} - -/* -** ASE_GetNumSurfaces -*/ -int ASE_GetNumSurfaces( void ){ - return ase.currentObject; -} - -/* -** ASE_GetSurfaceName -*/ -const char *ASE_GetSurfaceName( int which ){ - aseGeomObject_t *pObject = &ase.objects[which]; - - if ( !pObject->anim.numFrames ) { - return 0; - } - - return pObject->name; -} - -/* -** ASE_GetSurfaceAnimation -** -** Returns an animation (sequence of polysets) -*/ -polyset_t *ASE_GetSurfaceAnimation( int which, int *pNumFrames, int skipFrameStart, int skipFrameEnd, int maxFrames ){ - aseGeomObject_t *pObject = &ase.objects[which]; - polyset_t *psets; - int numFramesInAnimation; - int numFramesToKeep; - int i, f; - - if ( !pObject->anim.numFrames ) { - return 0; - } - - if ( pObject->anim.numFrames > maxFrames && maxFrames != -1 ) { - numFramesInAnimation = maxFrames; - } - else - { - numFramesInAnimation = pObject->anim.numFrames; - if ( maxFrames != -1 ) { - Sys_Printf( "WARNING: ASE_GetSurfaceAnimation maxFrames > numFramesInAnimation\n" ); - } - } - - if ( skipFrameEnd != -1 ) { - numFramesToKeep = numFramesInAnimation - ( skipFrameEnd - skipFrameStart + 1 ); - } - else{ - numFramesToKeep = numFramesInAnimation; - } - - *pNumFrames = numFramesToKeep; - - psets = safe_calloc( sizeof( polyset_t ) * numFramesToKeep ); - - for ( f = 0, i = 0; i < numFramesInAnimation; i++ ) - { - int t; - aseMesh_t *pMesh = &pObject->anim.frames[i]; - - if ( skipFrameStart != -1 ) { - if ( i >= skipFrameStart && i <= skipFrameEnd ) { - continue; - } - } - - strcpy( psets[f].name, pObject->name ); - strcpy( psets[f].materialname, ase.materials[pObject->materialRef].name ); - - psets[f].triangles = safe_calloc( sizeof( triangle_t ) * pObject->anim.frames[i].numFaces ); - psets[f].numtriangles = pObject->anim.frames[i].numFaces; - - for ( t = 0; t < pObject->anim.frames[i].numFaces; t++ ) - { - int k; - - for ( k = 0; k < 3; k++ ) - { - psets[f].triangles[t].verts[k][0] = pMesh->vertexes[pMesh->faces[t][k]].x; - psets[f].triangles[t].verts[k][1] = pMesh->vertexes[pMesh->faces[t][k]].y; - psets[f].triangles[t].verts[k][2] = pMesh->vertexes[pMesh->faces[t][k]].z; - - if ( pMesh->tvertexes && pMesh->tfaces ) { - psets[f].triangles[t].texcoords[k][0] = pMesh->tvertexes[pMesh->tfaces[t][k]].s; - psets[f].triangles[t].texcoords[k][1] = pMesh->tvertexes[pMesh->tfaces[t][k]].t; - } - - } - } - - f++; - } - - return psets; -} - -static void ASE_FreeGeomObject( int ndx ){ - aseGeomObject_t *pObject; - int i; - - pObject = &ase.objects[ndx]; - - for ( i = 0; i < pObject->anim.numFrames; i++ ) - { - if ( pObject->anim.frames[i].vertexes ) { - free( pObject->anim.frames[i].vertexes ); - } - if ( pObject->anim.frames[i].tvertexes ) { - free( pObject->anim.frames[i].tvertexes ); - } - if ( pObject->anim.frames[i].faces ) { - free( pObject->anim.frames[i].faces ); - } - if ( pObject->anim.frames[i].tfaces ) { - free( pObject->anim.frames[i].tfaces ); - } - } - - memset( pObject, 0, sizeof( *pObject ) ); -} - -static aseMesh_t *ASE_GetCurrentMesh( void ){ - aseGeomObject_t *pObject; - - if ( ase.currentObject >= MAX_ASE_OBJECTS ) { - Error( "Too many GEOMOBJECTs" ); - return 0; // never called - } - - pObject = &ase.objects[ase.currentObject]; - - if ( pObject->anim.currentFrame >= MAX_ASE_ANIMATION_FRAMES ) { - Error( "Too many MESHes" ); - return 0; - } - - return &pObject->anim.frames[pObject->anim.currentFrame]; -} - -static int CharIsTokenDelimiter( int ch ){ - if ( ch <= 32 ) { - return 1; - } - return 0; -} - -static int ASE_GetToken( bool restOfLine ){ - int i = 0; - - if ( ase.buffer == 0 ) { - return 0; - } - - if ( ( ase.curpos - ase.buffer ) == ase.len ) { - return 0; - } - - // skip over crap - while ( ( ( ase.curpos - ase.buffer ) < ase.len ) && - ( *ase.curpos <= 32 ) ) - { - ase.curpos++; - } - - while ( ( ase.curpos - ase.buffer ) < ase.len ) - { - s_token[i] = *ase.curpos; - - ase.curpos++; - i++; - - if ( ( CharIsTokenDelimiter( s_token[i - 1] ) && !restOfLine ) || - ( ( s_token[i - 1] == '\n' ) || ( s_token[i - 1] == '\r' ) ) ) { - s_token[i - 1] = '\0'; - break; - } - } - - s_token[i] = '\0'; - - return 1; -} - -static void ASE_ParseBracedBlock( void ( *parser )( const char *token ) ){ - int indent = 0; - - while ( ASE_GetToken( false ) ) - { - if ( strEqual( s_token, "{" ) ) { - indent++; - } - else if ( strEqual( s_token, "}" ) ) { - --indent; - if ( indent == 0 ) { - break; - } - else if ( indent < 0 ) { - Error( "Unexpected '}'" ); - } - } - else - { - if ( parser ) { - parser( s_token ); - } - } - } -} - -static void ASE_SkipEnclosingBraces( void ){ - int indent = 0; - - while ( ASE_GetToken( false ) ) - { - if ( strEqual( s_token, "{" ) ) { - indent++; - } - else if ( strEqual( s_token, "}" ) ) { - indent--; - if ( indent == 0 ) { - break; - } - else if ( indent < 0 ) { - Error( "Unexpected '}'" ); - } - } - } -} - -static void ASE_SkipRestOfLine( void ){ - ASE_GetToken( true ); -} - -static void ASE_KeyMAP_DIFFUSE( const char *token ){ - char bitmap[1024]; - char filename[1024]; - - strcpy( filename, gl_filename ); - - if ( strEqual( token, "*BITMAP" ) ) { - ASE_GetToken( false ); - - // the purpose of this whole chunk of code below is to extract the relative path - // from a full path in the ASE - - strcpy( bitmap, s_token + 1 ); - if ( strchr( bitmap, '"' ) ) { - *strchr( bitmap, '"' ) = 0; - } - - /* convert backslash to slash */ - FixDOSName( bitmap ); - - /* remove filename from path */ - strClear( path_get_last_separator( filename ) ); - - /* replaces a relative path with a full path */ - if ( strEqualPrefix( bitmap, "../" ) ) { - while ( strEqualPrefix( bitmap, "../" ) ) - { - /* remove last item from path */ - strClear( path_get_last_separator( filename ) ); - memmove( bitmap, &bitmap[3], sizeof( bitmap ) - 3 ); - } - strcat( filename, "/" ); - strcat( filename, bitmap ); - strcpy( bitmap, filename ); - } - - if ( strstr( bitmap, gamedir ) ) { - strcpy( ase.materials[ase.numMaterials].name, strstr( bitmap, gamedir ) + strlen( gamedir ) ); - Sys_Printf( "material name: \'%s\'\n", ase.materials[ase.numMaterials].name ); - } - else - { - sprintf( ase.materials[ase.numMaterials].name, "(not converted: '%s')", bitmap ); - Sys_Printf( "WARNING: illegal material name '%s'\n", bitmap ); - } - } - else - { - } -} - -static void ASE_KeyMATERIAL( const char *token ){ - if ( strEqual( token, "*MAP_DIFFUSE" ) ) { - ASE_ParseBracedBlock( ASE_KeyMAP_DIFFUSE ); - } - else - { - } -} - -static void ASE_KeyMATERIAL_LIST( const char *token ){ - if ( strEqual( token, "*MATERIAL_COUNT" ) ) { - ASE_GetToken( false ); - VERBOSE( ( "..num materials: %s\n", s_token ) ); - if ( atoi( s_token ) > MAX_ASE_MATERIALS ) { - Error( "Too many materials!" ); - } - ase.numMaterials = 0; - } - else if ( strEqual( token, "*MATERIAL" ) ) { - VERBOSE( ( "..material %d ", ase.numMaterials ) ); - ASE_ParseBracedBlock( ASE_KeyMATERIAL ); - ase.numMaterials++; - } -} - -static void ASE_KeyMESH_VERTEX_LIST( const char *token ){ - aseMesh_t *pMesh = ASE_GetCurrentMesh(); - - if ( strEqual( token, "*MESH_VERTEX" ) ) { - ASE_GetToken( false ); // skip number - - ASE_GetToken( false ); - pMesh->vertexes[pMesh->currentVertex].y = atof( s_token ); - - ASE_GetToken( false ); - pMesh->vertexes[pMesh->currentVertex].x = -atof( s_token ); - - ASE_GetToken( false ); - pMesh->vertexes[pMesh->currentVertex].z = atof( s_token ); - - pMesh->currentVertex++; - - if ( pMesh->currentVertex > pMesh->numVertexes ) { - Error( "pMesh->currentVertex >= pMesh->numVertexes" ); - } - } - else - { - Error( "Unknown token '%s' while parsing MESH_VERTEX_LIST", token ); - } -} - -static void ASE_KeyMESH_FACE_LIST( const char *token ){ - aseMesh_t *pMesh = ASE_GetCurrentMesh(); - - if ( strEqual( token, "*MESH_FACE" ) ) { - ASE_GetToken( false ); // skip face number - - ASE_GetToken( false ); // skip label - ASE_GetToken( false ); // first vertex - pMesh->faces[pMesh->currentFace][0] = atoi( s_token ); - - ASE_GetToken( false ); // skip label - ASE_GetToken( false ); // second vertex - pMesh->faces[pMesh->currentFace][2] = atoi( s_token ); - - ASE_GetToken( false ); // skip label - ASE_GetToken( false ); // third vertex - pMesh->faces[pMesh->currentFace][1] = atoi( s_token ); - - ASE_GetToken( true ); - -/* - if ( ( p = strstr( s_token, "*MESH_MTLID" ) ) != 0 ) - { - p += strlen( "*MESH_MTLID" ) + 1; - mtlID = atoi( p ); - } - else - { - Error( "No *MESH_MTLID found for face!" ); - } - */ - - pMesh->currentFace++; - } - else - { - Error( "Unknown token '%s' while parsing MESH_FACE_LIST", token ); - } -} - -static void ASE_KeyTFACE_LIST( const char *token ){ - aseMesh_t *pMesh = ASE_GetCurrentMesh(); - - if ( strEqual( token, "*MESH_TFACE" ) ) { - int a, b, c; - - ASE_GetToken( false ); - - ASE_GetToken( false ); - a = atoi( s_token ); - ASE_GetToken( false ); - c = atoi( s_token ); - ASE_GetToken( false ); - b = atoi( s_token ); - - pMesh->tfaces[pMesh->currentFace][0] = a; - pMesh->tfaces[pMesh->currentFace][1] = b; - pMesh->tfaces[pMesh->currentFace][2] = c; - - pMesh->currentFace++; - } - else - { - Error( "Unknown token '%s' in MESH_TFACE", token ); - } -} - -static void ASE_KeyMESH_TVERTLIST( const char *token ){ - aseMesh_t *pMesh = ASE_GetCurrentMesh(); - - if ( strEqual( token, "*MESH_TVERT" ) ) { - char u[80], v[80], w[80]; - - ASE_GetToken( false ); - - ASE_GetToken( false ); - strcpy( u, s_token ); - - ASE_GetToken( false ); - strcpy( v, s_token ); - - ASE_GetToken( false ); - strcpy( w, s_token ); - - pMesh->tvertexes[pMesh->currentVertex].s = atof( u ); - pMesh->tvertexes[pMesh->currentVertex].t = 1.0f - atof( v ); - - pMesh->currentVertex++; - - if ( pMesh->currentVertex > pMesh->numTVertexes ) { - Error( "pMesh->currentVertex > pMesh->numTVertexes" ); - } - } - else - { - Error( "Unknown token '%s' while parsing MESH_TVERTLIST", token ); - } -} - -static void ASE_KeyMESH( const char *token ){ - aseMesh_t *pMesh = ASE_GetCurrentMesh(); - - if ( strEqual( token, "*TIMEVALUE" ) ) { - ASE_GetToken( false ); - - pMesh->timeValue = atoi( s_token ); - VERBOSE( ( ".....timevalue: %d\n", pMesh->timeValue ) ); - } - else if ( strEqual( token, "*MESH_NUMVERTEX" ) ) { - ASE_GetToken( false ); - - pMesh->numVertexes = atoi( s_token ); - VERBOSE( ( ".....TIMEVALUE: %d\n", pMesh->timeValue ) ); - VERBOSE( ( ".....num vertexes: %d\n", pMesh->numVertexes ) ); - } - else if ( strEqual( token, "*MESH_NUMFACES" ) ) { - ASE_GetToken( false ); - - pMesh->numFaces = atoi( s_token ); - VERBOSE( ( ".....num faces: %d\n", pMesh->numFaces ) ); - } - else if ( strEqual( token, "*MESH_NUMTVFACES" ) ) { - ASE_GetToken( false ); - - if ( atoi( s_token ) != pMesh->numFaces ) { - Error( "MESH_NUMTVFACES != MESH_NUMFACES" ); - } - } - else if ( strEqual( token, "*MESH_NUMTVERTEX" ) ) { - ASE_GetToken( false ); - - pMesh->numTVertexes = atoi( s_token ); - VERBOSE( ( ".....num tvertexes: %d\n", pMesh->numTVertexes ) ); - } - else if ( strEqual( token, "*MESH_VERTEX_LIST" ) ) { - pMesh->vertexes = safe_calloc( sizeof( aseVertex_t ) * pMesh->numVertexes ); - pMesh->currentVertex = 0; - VERBOSE( ( ".....parsing MESH_VERTEX_LIST\n" ) ); - ASE_ParseBracedBlock( ASE_KeyMESH_VERTEX_LIST ); - } - else if ( strEqual( token, "*MESH_TVERTLIST" ) ) { - pMesh->currentVertex = 0; - pMesh->tvertexes = safe_calloc( sizeof( aseTVertex_t ) * pMesh->numTVertexes ); - VERBOSE( ( ".....parsing MESH_TVERTLIST\n" ) ); - ASE_ParseBracedBlock( ASE_KeyMESH_TVERTLIST ); - } - else if ( strEqual( token, "*MESH_FACE_LIST" ) ) { - pMesh->faces = safe_calloc( sizeof( aseFace_t ) * pMesh->numFaces ); - pMesh->currentFace = 0; - VERBOSE( ( ".....parsing MESH_FACE_LIST\n" ) ); - ASE_ParseBracedBlock( ASE_KeyMESH_FACE_LIST ); - } - else if ( strEqual( token, "*MESH_TFACELIST" ) ) { - pMesh->tfaces = safe_calloc( sizeof( aseFace_t ) * pMesh->numFaces ); - pMesh->currentFace = 0; - VERBOSE( ( ".....parsing MESH_TFACE_LIST\n" ) ); - ASE_ParseBracedBlock( ASE_KeyTFACE_LIST ); - } - else if ( strEqual( token, "*MESH_NORMALS" ) ) { - ASE_ParseBracedBlock( 0 ); - } -} - -static void ASE_KeyMESH_ANIMATION( const char *token ){ - aseMesh_t *pMesh = ASE_GetCurrentMesh(); - - // loads a single animation frame - if ( strEqual( token, "*MESH" ) ) { - VERBOSE( ( "...found MESH\n" ) ); - assert( pMesh->faces == 0 ); - assert( pMesh->vertexes == 0 ); - assert( pMesh->tvertexes == 0 ); - memset( pMesh, 0, sizeof( *pMesh ) ); - - ASE_ParseBracedBlock( ASE_KeyMESH ); - - if ( ++ase.objects[ase.currentObject].anim.currentFrame == MAX_ASE_ANIMATION_FRAMES ) { - Error( "Too many animation frames" ); - } - } - else - { - Error( "Unknown token '%s' while parsing MESH_ANIMATION", token ); - } -} - -static void ASE_KeyGEOMOBJECT( const char *token ){ - if ( strEqual( token, "*NODE_NAME" ) ) { - char *name = ase.objects[ase.currentObject].name; - - ASE_GetToken( true ); - VERBOSE( ( " %s\n", s_token ) ); - strcpy( name, s_token + 1 ); - if ( NULL != strchr( name, '"' ) ) { - strClear( strchr( name, '"' ) ); - } - - if ( strEqualPrefix( name, "tag" ) ) { - while ( strchr( name, '_' ) != strrchr( name, '_' ) ) - { - strClear( strrchr( name, '_' ) ); - } - while ( strrchr( name, ' ' ) ) - { - strClear( strrchr( name, ' ' ) ); - } - } - } - else if ( strEqual( token, "*NODE_PARENT" ) ) { - ASE_SkipRestOfLine(); - } - // ignore unused data blocks - else if ( strEqual( token, "*NODE_TM" ) || - strEqual( token, "*TM_ANIMATION" ) ) { - ASE_ParseBracedBlock( 0 ); - } - // ignore regular meshes that aren't part of animation - else if ( strEqual( token, "*MESH" ) && !ase.grabAnims ) { -/* - if ( strstr( ase.objects[ase.currentObject].name, "tag_" ) == ase.objects[ase.currentObject].name ) - { - s_forceStaticMesh = true; - ASE_ParseBracedBlock( ASE_KeyMESH ); - s_forceStaticMesh = false; - } - */ - ASE_ParseBracedBlock( ASE_KeyMESH ); - if ( ++ase.objects[ase.currentObject].anim.currentFrame == MAX_ASE_ANIMATION_FRAMES ) { - Error( "Too many animation frames" ); - } - ase.objects[ase.currentObject].anim.numFrames = ase.objects[ase.currentObject].anim.currentFrame; - ase.objects[ase.currentObject].numAnimations++; -/* - // ignore meshes that aren't part of animations if this object isn't a - // a tag - else - { - ASE_ParseBracedBlock( 0 ); - } - */ - } - // according to spec these are obsolete - else if ( strEqual( token, "*MATERIAL_REF" ) ) { - ASE_GetToken( false ); - - ase.objects[ase.currentObject].materialRef = atoi( s_token ); - } - // loads a sequence of animation frames - else if ( strEqual( token, "*MESH_ANIMATION" ) ) { - if ( ase.grabAnims ) { - VERBOSE( ( "..found MESH_ANIMATION\n" ) ); - - if ( ase.objects[ase.currentObject].numAnimations ) { - Error( "Multiple MESH_ANIMATIONS within a single GEOM_OBJECT" ); - } - ASE_ParseBracedBlock( ASE_KeyMESH_ANIMATION ); - ase.objects[ase.currentObject].anim.numFrames = ase.objects[ase.currentObject].anim.currentFrame; - ase.objects[ase.currentObject].numAnimations++; - } - else - { - ASE_SkipEnclosingBraces(); - } - } - // skip unused info - else if ( strEqual( token, "*PROP_MOTIONBLUR" ) || - strEqual( token, "*PROP_CASTSHADOW" ) || - strEqual( token, "*PROP_RECVSHADOW" ) ) { - ASE_SkipRestOfLine(); - } -} - -static void ConcatenateObjects( aseGeomObject_t *pObjA, aseGeomObject_t *pObjB ){ -} - -static void CollapseObjects( void ){ - int i; - int numObjects = ase.currentObject; - - for ( i = 0; i < numObjects; i++ ) - { - int j; - - // skip tags - if ( strstr( ase.objects[i].name, "tag" ) == ase.objects[i].name ) { - continue; - } - - if ( !ase.objects[i].numAnimations ) { - continue; - } - - for ( j = i + 1; j < numObjects; j++ ) - { - if ( strstr( ase.objects[j].name, "tag" ) == ase.objects[j].name ) { - continue; - } - if ( ase.objects[i].materialRef == ase.objects[j].materialRef ) { - if ( ase.objects[j].numAnimations ) { - ConcatenateObjects( &ase.objects[i], &ase.objects[j] ); - } - } - } - } -} - -/* -** ASE_Process -*/ -static void ASE_Process( void ){ - while ( ASE_GetToken( false ) ) - { - if ( strEqual( s_token, "*3DSMAX_ASCIIEXPORT" ) || - strEqual( s_token, "*COMMENT" ) ) { - ASE_SkipRestOfLine(); - } - else if ( strEqual( s_token, "*SCENE" ) ) { - ASE_SkipEnclosingBraces(); - } - else if ( strEqual( s_token, "*MATERIAL_LIST" ) ) { - VERBOSE( ( "MATERIAL_LIST\n" ) ); - - ASE_ParseBracedBlock( ASE_KeyMATERIAL_LIST ); - } - else if ( strEqual( s_token, "*GEOMOBJECT" ) ) { - VERBOSE( ( "GEOMOBJECT" ) ); - - ASE_ParseBracedBlock( ASE_KeyGEOMOBJECT ); - - if ( strstr( ase.objects[ase.currentObject].name, "Bip" ) || - strstr( ase.objects[ase.currentObject].name, "ignore_" ) ) { - ASE_FreeGeomObject( ase.currentObject ); - VERBOSE( ( "(discarding BIP/ignore object)\n" ) ); - } - else if ( ( strstr( ase.objects[ase.currentObject].name, "h_" ) != ase.objects[ase.currentObject].name ) && - ( strstr( ase.objects[ase.currentObject].name, "l_" ) != ase.objects[ase.currentObject].name ) && - ( strstr( ase.objects[ase.currentObject].name, "u_" ) != ase.objects[ase.currentObject].name ) && - ( strstr( ase.objects[ase.currentObject].name, "tag" ) != ase.objects[ase.currentObject].name ) && - ase.grabAnims ) { - VERBOSE( ( "(ignoring improperly labeled object '%s')\n", ase.objects[ase.currentObject].name ) ); - ASE_FreeGeomObject( ase.currentObject ); - } - else - { - if ( ++ase.currentObject == MAX_ASE_OBJECTS ) { - Error( "Too many GEOMOBJECTs" ); - } - } - } - else if ( s_token[0] ) { - Sys_Printf( "Unknown token '%s'\n", s_token ); - } - } - - if ( !ase.currentObject ) { - Error( "No animation data!" ); - } - - CollapseObjects(); -} diff --git a/tools/quake3/common/aselib.h b/tools/quake3/common/aselib.h deleted file mode 100644 index 49ec5b57..00000000 --- a/tools/quake3/common/aselib.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#include "polyset.h" - -void ASE_Load( const char *filename, bool verbose, bool meshanims ); -int ASE_GetNumSurfaces( void ); -polyset_t *ASE_GetSurfaceAnimation( int ndx, int *numFrames, int skipFrameStart, int skipFrameEnd, int maxFrames ); -const char *ASE_GetSurfaceName( int ndx ); -void ASE_Free( void ); diff --git a/tools/quake3/common/bspfile.cpp b/tools/quake3/common/bspfile.cpp deleted file mode 100644 index fe4b08ed..00000000 --- a/tools/quake3/common/bspfile.cpp +++ /dev/null @@ -1,676 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#include "cmdlib.h" -#include "qstringops.h" -#include "mathlib.h" -#include "inout.h" -#include "bspfile.h" -#include "scriplib.h" - -void GetLeafNums( void ); - -//============================================================================= - -int bsp_version = Q3_BSP_VERSION; - -int nummodels; -dmodel_t dmodels[MAX_MAP_MODELS]; - -int numShaders; -dshader_t dshaders[MAX_MAP_SHADERS]; - -int entdatasize; -char dentdata[MAX_MAP_ENTSTRING]; - -int numleafs; -dleaf_t dleafs[MAX_MAP_LEAFS]; - -int numplanes; -dplane_t dplanes[MAX_MAP_PLANES]; - -int numnodes; -dnode_t dnodes[MAX_MAP_NODES]; - -int numleafsurfaces; -int dleafsurfaces[MAX_MAP_LEAFFACES]; - -int numleafbrushes; -int dleafbrushes[MAX_MAP_LEAFBRUSHES]; - -int numbrushes; -dbrush_t dbrushes[MAX_MAP_BRUSHES]; - -int numbrushsides; -dbrushside_t dbrushsides[MAX_MAP_BRUSHSIDES]; - -int numLightBytes; -byte *lightBytes; - -int numGridPoints; -byte *gridData; - -int numVisBytes; -byte visBytes[MAX_MAP_VISIBILITY]; - -int numDrawVerts = 0; -int numDrawVertsBuffer = 0; -drawVert_t *drawVerts = NULL; - -int numDrawIndexes; -int drawIndexes[MAX_MAP_DRAW_INDEXES]; - -int numDrawSurfaces; -int numDrawSurfacesBuffer = 0; -dsurface_t *drawSurfaces = NULL; - -int numFogs; -dfog_t dfogs[MAX_MAP_FOGS]; - -void SetLightBytes( int n ){ - free( lightBytes ); - - numLightBytes = n; - - if ( n == 0 ) { - return; - } - - lightBytes = safe_calloc( numLightBytes ); -} - -void SetGridPoints( int n ){ - free( gridData ); - - numGridPoints = n; - - if ( n == 0 ) { - return; - } - - gridData = safe_calloc( numGridPoints * 8 ); -} - -void IncDrawVerts(){ - numDrawVerts++; - - if ( drawVerts == 0 ) { - numDrawVertsBuffer = MAX_MAP_DRAW_VERTS / 37; - - drawVerts = safe_malloc( sizeof( drawVert_t ) * numDrawVertsBuffer ); - - } - else if ( numDrawVerts > numDrawVertsBuffer ) { - numDrawVertsBuffer *= 3; // multiply by 1.5 - numDrawVertsBuffer /= 2; - - if ( numDrawVertsBuffer > MAX_MAP_DRAW_VERTS ) { - numDrawVertsBuffer = MAX_MAP_DRAW_VERTS; - } - - drawVerts = void_ptr( realloc( drawVerts, sizeof( drawVert_t ) * numDrawVertsBuffer ) ); - - if ( !drawVerts ) { - Error( "realloc() failed (IncDrawVerts)" ); - } - } - - memset( drawVerts + ( numDrawVerts - 1 ), 0, sizeof( drawVert_t ) ); -} - -void SetDrawVerts( int n ){ - free( drawVerts ); - - numDrawVerts = - numDrawVertsBuffer = n; - - drawVerts = safe_calloc( sizeof( drawVert_t ) * numDrawVertsBuffer ); -} - -void SetDrawSurfacesBuffer(){ - free( drawSurfaces ); - - numDrawSurfacesBuffer = MAX_MAP_DRAW_SURFS; - - drawSurfaces = safe_calloc( sizeof( dsurface_t ) * numDrawSurfacesBuffer ); -} - -void SetDrawSurfaces( int n ){ - free( drawSurfaces ); - - numDrawSurfaces = - numDrawSurfacesBuffer = n; - - drawSurfaces = safe_calloc( sizeof( dsurface_t ) * numDrawSurfacesBuffer ); -} - -void BspFilesCleanup(){ - free( drawVerts ); - free( drawSurfaces ); - free( lightBytes ); - free( gridData ); -} - -//============================================================================= - -/* - ============= - SwapBlock - - If all values are 32 bits, this can be used to swap everything - ============= - */ -void SwapBlock( int *block, int sizeOfBlock ) { - int i; - - sizeOfBlock >>= 2; - for ( i = 0 ; i < sizeOfBlock ; i++ ) { - block[i] = LittleLong( block[i] ); - } -} - -/* - ============= - SwapBSPFile - - Byte swaps all data in a bsp file. - ============= - */ -void SwapBSPFile( void ) { - int i; - - // models - SwapBlock( (int *)dmodels, nummodels * sizeof( dmodels[0] ) ); - - // shaders (don't swap the name) - for ( i = 0 ; i < numShaders ; i++ ) { - dshaders[i].contentFlags = LittleLong( dshaders[i].contentFlags ); - dshaders[i].surfaceFlags = LittleLong( dshaders[i].surfaceFlags ); - } - - // planes - SwapBlock( (int *)dplanes, numplanes * sizeof( dplanes[0] ) ); - - // nodes - SwapBlock( (int *)dnodes, numnodes * sizeof( dnodes[0] ) ); - - // leafs - SwapBlock( (int *)dleafs, numleafs * sizeof( dleafs[0] ) ); - - // leaffaces - SwapBlock( (int *)dleafsurfaces, numleafsurfaces * sizeof( dleafsurfaces[0] ) ); - - // leafbrushes - SwapBlock( (int *)dleafbrushes, numleafbrushes * sizeof( dleafbrushes[0] ) ); - - // brushes - SwapBlock( (int *)dbrushes, numbrushes * sizeof( dbrushes[0] ) ); - - // brushsides - SwapBlock( (int *)dbrushsides, numbrushsides * sizeof( dbrushsides[0] ) ); - - // vis - ( (int *)&visBytes )[0] = LittleLong( ( (int *)&visBytes )[0] ); - ( (int *)&visBytes )[1] = LittleLong( ( (int *)&visBytes )[1] ); - - // drawverts (don't swap colors ) - for ( i = 0 ; i < numDrawVerts ; i++ ) { - drawVerts[i].lightmap[0] = LittleFloat( drawVerts[i].lightmap[0] ); - drawVerts[i].lightmap[1] = LittleFloat( drawVerts[i].lightmap[1] ); - drawVerts[i].st[0] = LittleFloat( drawVerts[i].st[0] ); - drawVerts[i].st[1] = LittleFloat( drawVerts[i].st[1] ); - drawVerts[i].xyz[0] = LittleFloat( drawVerts[i].xyz[0] ); - drawVerts[i].xyz[1] = LittleFloat( drawVerts[i].xyz[1] ); - drawVerts[i].xyz[2] = LittleFloat( drawVerts[i].xyz[2] ); - drawVerts[i].normal[0] = LittleFloat( drawVerts[i].normal[0] ); - drawVerts[i].normal[1] = LittleFloat( drawVerts[i].normal[1] ); - drawVerts[i].normal[2] = LittleFloat( drawVerts[i].normal[2] ); - } - - // drawindexes - SwapBlock( (int *)drawIndexes, numDrawIndexes * sizeof( drawIndexes[0] ) ); - - // drawsurfs - SwapBlock( (int *)drawSurfaces, numDrawSurfaces * sizeof( drawSurfaces[0] ) ); - - // fogs - for ( i = 0 ; i < numFogs ; i++ ) { - dfogs[i].brushNum = LittleLong( dfogs[i].brushNum ); - dfogs[i].visibleSide = LittleLong( dfogs[i].visibleSide ); - } -} - - - -/* - ============= - GetLumpElements - ============= - */ -int GetLumpElements( dheader_t *header, int lump, int size ) { - int length; - - length = header->lumps[lump].filelen; - - if ( length % size ) { - Error( "LoadBSPFile: odd lump size" ); - } - - return length / size; -} - -/* - ============= - CopyLump - ============= - */ -int CopyLump( dheader_t *header, int lump, void *dest, int size ) { - int length, ofs; - - length = header->lumps[lump].filelen; - ofs = header->lumps[lump].fileofs; - - if ( length == 0 ) { - return 0; - } - - if ( length % size ) { - Error( "LoadBSPFile: odd lump size" ); - } - - memcpy( dest, (byte *)header + ofs, length ); - - return length / size; -} - -/* - ============= - LoadBSPFile - ============= - */ -void LoadBSPFile( const char *filename ) { - dheader_t *header; - - // load the file header - LoadFile( filename, (void **)&header ); - - // swap the header - SwapBlock( (int *)header, sizeof( *header ) ); - - if ( header->ident != BSP_IDENT ) { - Error( "%s is not a IBSP file", filename ); - } - if ( header->version != bsp_version ) { - Error( "%s is version %i, not %i", filename, header->version, bsp_version ); - } - - numShaders = CopyLump( header, LUMP_SHADERS, dshaders, sizeof( dshader_t ) ); - nummodels = CopyLump( header, LUMP_MODELS, dmodels, sizeof( dmodel_t ) ); - numplanes = CopyLump( header, LUMP_PLANES, dplanes, sizeof( dplane_t ) ); - numleafs = CopyLump( header, LUMP_LEAFS, dleafs, sizeof( dleaf_t ) ); - numnodes = CopyLump( header, LUMP_NODES, dnodes, sizeof( dnode_t ) ); - numleafsurfaces = CopyLump( header, LUMP_LEAFSURFACES, dleafsurfaces, sizeof( dleafsurfaces[0] ) ); - numleafbrushes = CopyLump( header, LUMP_LEAFBRUSHES, dleafbrushes, sizeof( dleafbrushes[0] ) ); - numbrushes = CopyLump( header, LUMP_BRUSHES, dbrushes, sizeof( dbrush_t ) ); - numbrushsides = CopyLump( header, LUMP_BRUSHSIDES, dbrushsides, sizeof( dbrushside_t ) ); - numDrawVerts = GetLumpElements( header, LUMP_DRAWVERTS, sizeof( drawVert_t ) ); - SetDrawVerts( numDrawVerts ); - CopyLump( header, LUMP_DRAWVERTS, drawVerts, sizeof( drawVert_t ) ); - numDrawSurfaces = GetLumpElements( header, LUMP_SURFACES, sizeof( dsurface_t ) ); - SetDrawSurfaces( numDrawSurfaces ); - numDrawSurfaces = CopyLump( header, LUMP_SURFACES, drawSurfaces, sizeof( dsurface_t ) ); - numFogs = CopyLump( header, LUMP_FOGS, dfogs, sizeof( dfog_t ) ); - numDrawIndexes = CopyLump( header, LUMP_DRAWINDEXES, drawIndexes, sizeof( drawIndexes[0] ) ); - - numVisBytes = CopyLump( header, LUMP_VISIBILITY, visBytes, 1 ); - numLightBytes = GetLumpElements( header, LUMP_LIGHTMAPS, 1 ); - SetLightBytes( numLightBytes ); - CopyLump( header, LUMP_LIGHTMAPS, lightBytes, 1 ); - entdatasize = CopyLump( header, LUMP_ENTITIES, dentdata, 1 ); - - numGridPoints = GetLumpElements( header, LUMP_LIGHTGRID, 8 ); - SetGridPoints( numGridPoints ); - CopyLump( header, LUMP_LIGHTGRID, gridData, 8 ); - - - free( header ); // everything has been copied out - - // swap everything - SwapBSPFile(); -} - - -//============================================================================ - -/* - ============= - AddLump - ============= - */ -void AddLump( FILE *bspfile, dheader_t *header, int lumpnum, const void *data, int len ) { - lump_t *lump; - - lump = &header->lumps[lumpnum]; - - lump->fileofs = LittleLong( ftell( bspfile ) ); - lump->filelen = LittleLong( len ); - SafeWrite( bspfile, data, ( len + 3 ) & ~3 ); -} - -/* - ============= - WriteBSPFile - - Swaps the bsp file in place, so it should not be referenced again - ============= - */ -void WriteBSPFile( const char *filename ) { - dheader_t outheader, *header; - FILE *bspfile; - - header = &outheader; - memset( header, 0, sizeof( dheader_t ) ); - - SwapBSPFile(); - - header->ident = LittleLong( BSP_IDENT ); - header->version = LittleLong( bsp_version ); - - bspfile = SafeOpenWrite( filename ); - SafeWrite( bspfile, header, sizeof( dheader_t ) ); // overwritten later - - AddLump( bspfile, header, LUMP_SHADERS, dshaders, numShaders * sizeof( dshader_t ) ); - AddLump( bspfile, header, LUMP_PLANES, dplanes, numplanes * sizeof( dplane_t ) ); - AddLump( bspfile, header, LUMP_LEAFS, dleafs, numleafs * sizeof( dleaf_t ) ); - AddLump( bspfile, header, LUMP_NODES, dnodes, numnodes * sizeof( dnode_t ) ); - AddLump( bspfile, header, LUMP_BRUSHES, dbrushes, numbrushes * sizeof( dbrush_t ) ); - AddLump( bspfile, header, LUMP_BRUSHSIDES, dbrushsides, numbrushsides * sizeof( dbrushside_t ) ); - AddLump( bspfile, header, LUMP_LEAFSURFACES, dleafsurfaces, numleafsurfaces * sizeof( dleafsurfaces[0] ) ); - AddLump( bspfile, header, LUMP_LEAFBRUSHES, dleafbrushes, numleafbrushes * sizeof( dleafbrushes[0] ) ); - AddLump( bspfile, header, LUMP_MODELS, dmodels, nummodels * sizeof( dmodel_t ) ); - AddLump( bspfile, header, LUMP_DRAWVERTS, drawVerts, numDrawVerts * sizeof( drawVert_t ) ); - AddLump( bspfile, header, LUMP_SURFACES, drawSurfaces, numDrawSurfaces * sizeof( dsurface_t ) ); - AddLump( bspfile, header, LUMP_VISIBILITY, visBytes, numVisBytes ); - AddLump( bspfile, header, LUMP_LIGHTMAPS, lightBytes, numLightBytes ); - AddLump( bspfile, header, LUMP_LIGHTGRID, gridData, 8 * numGridPoints ); - AddLump( bspfile, header, LUMP_ENTITIES, dentdata, entdatasize ); - AddLump( bspfile, header, LUMP_FOGS, dfogs, numFogs * sizeof( dfog_t ) ); - AddLump( bspfile, header, LUMP_DRAWINDEXES, drawIndexes, numDrawIndexes * sizeof( drawIndexes[0] ) ); - - fseek( bspfile, 0, SEEK_SET ); - SafeWrite( bspfile, header, sizeof( dheader_t ) ); - fclose( bspfile ); -} - -//============================================================================ - -/* - ============= - PrintBSPFileSizes - - Dumps info about current file - ============= - */ -void PrintBSPFileSizes( void ) { - if ( !num_entities ) { - ParseEntities(); - } - - Sys_Printf( "%6i models %7i\n" - ,nummodels, (int)( nummodels * sizeof( dmodel_t ) ) ); - Sys_Printf( "%6i shaders %7i\n" - ,numShaders, (int)( numShaders * sizeof( dshader_t ) ) ); - Sys_Printf( "%6i brushes %7i\n" - ,numbrushes, (int)( numbrushes * sizeof( dbrush_t ) ) ); - Sys_Printf( "%6i brushsides %7i\n" - ,numbrushsides, (int)( numbrushsides * sizeof( dbrushside_t ) ) ); - Sys_Printf( "%6i fogs %7i\n" - ,numFogs, (int)( numFogs * sizeof( dfog_t ) ) ); - Sys_Printf( "%6i planes %7i\n" - ,numplanes, (int)( numplanes * sizeof( dplane_t ) ) ); - Sys_Printf( "%6i entdata %7i\n", num_entities, entdatasize ); - - Sys_Printf( "\n" ); - - Sys_Printf( "%6i nodes %7i\n" - ,numnodes, (int)( numnodes * sizeof( dnode_t ) ) ); - Sys_Printf( "%6i leafs %7i\n" - ,numleafs, (int)( numleafs * sizeof( dleaf_t ) ) ); - Sys_Printf( "%6i leafsurfaces %7i\n" - ,numleafsurfaces, (int)( numleafsurfaces * sizeof( dleafsurfaces[0] ) ) ); - Sys_Printf( "%6i leafbrushes %7i\n" - ,numleafbrushes, (int)( numleafbrushes * sizeof( dleafbrushes[0] ) ) ); - Sys_Printf( "%6i drawverts %7i\n" - ,numDrawVerts, (int)( numDrawVerts * sizeof( drawVerts[0] ) ) ); - Sys_Printf( "%6i drawindexes %7i\n" - ,numDrawIndexes, (int)( numDrawIndexes * sizeof( drawIndexes[0] ) ) ); - Sys_Printf( "%6i drawsurfaces %7i\n" - ,numDrawSurfaces, (int)( numDrawSurfaces * sizeof( drawSurfaces[0] ) ) ); - - Sys_Printf( "%6i lightmaps %7i\n" - ,numLightBytes / ( LIGHTMAP_WIDTH * LIGHTMAP_HEIGHT * 3 ), numLightBytes ); - Sys_Printf( " visibility %7i\n" - , numVisBytes ); -} - - -//============================================ - -int num_entities; -entity_t entities[MAX_MAP_ENTITIES]; - -void StripTrailing( char *e ){ - char *s = e + strlen( e ) - 1; - while ( s >= e && *s <= 32 ) - { - strClear( s ); - s--; - } -} - -/* - ================= - ParseEpair - ================= - */ -epair_t *ParseEpair( void ) { - epair_t *e = safe_calloc( sizeof( epair_t ) ); - - if ( strlen( token ) >= MAX_KEY - 1 ) { - Error( "ParseEpar: token too long" ); - } - e->key = copystring( token ); - GetToken( false ); - if ( strlen( token ) >= MAX_VALUE - 1 ) { - Error( "ParseEpar: token too long" ); - } - e->value = copystring( token ); - - // strip trailing spaces that sometimes get accidentally - // added in the editor - StripTrailing( e->key ); - StripTrailing( e->value ); - - return e; -} - - -/* - ================ - ParseEntity - ================ - */ -bool ParseEntity( void ) { - epair_t *e; - entity_t *mapent; - - if ( !GetToken( true ) ) { - return false; - } - - if ( !strEqual( token, "{" ) ) { - Error( "ParseEntity: { not found" ); - } - if ( num_entities == MAX_MAP_ENTITIES ) { - Error( "num_entities == MAX_MAP_ENTITIES" ); - } - mapent = &entities[num_entities]; - num_entities++; - - do { - if ( !GetToken( true ) ) { - Error( "ParseEntity: EOF without closing brace" ); - } - if ( strEqual( token, "}" ) ) { - break; - } - e = ParseEpair(); - e->next = mapent->epairs; - mapent->epairs = e; - } while ( 1 ); - - return true; -} - -/* - ================ - ParseEntities - - Parses the dentdata string into entities - ================ - */ -void ParseEntities( void ) { - num_entities = 0; - ParseFromMemory( dentdata, entdatasize ); - - while ( ParseEntity() ) { - } -} - - -/* - ================ - UnparseEntities - - Generates the dentdata string from all the entities - This allows the utilities to add or remove key/value pairs - to the data created by the map editor. - ================ - */ -void UnparseEntities( void ) { - char *buf, *end; - epair_t *ep; - char line[2048]; - int i; - char key[1024], value[1024]; - - buf = dentdata; - end = buf; - *end = 0; - - for ( i = 0 ; i < num_entities ; i++ ) { - ep = entities[i].epairs; - if ( !ep ) { - continue; // ent got removed - } - - strcat( end, "{\n" ); - end += 2; - - for ( ep = entities[i].epairs ; ep ; ep = ep->next ) { - strcpy( key, ep->key ); - StripTrailing( key ); - strcpy( value, ep->value ); - StripTrailing( value ); - - sprintf( line, "\"%s\" \"%s\"\n", key, value ); - strcat( end, line ); - end += strlen( line ); - } - strcat( end, "}\n" ); - end += 2; - - if ( end > buf + MAX_MAP_ENTSTRING ) { - Error( "Entity text too long" ); - } - } - entdatasize = end - buf + 1; -} - -void PrintEntity( const entity_t *ent ) { - epair_t *ep; - - Sys_Printf( "------- entity %p -------\n", ent ); - for ( ep = ent->epairs ; ep ; ep = ep->next ) { - Sys_Printf( "%s = %s\n", ep->key, ep->value ); - } - -} - -void SetKeyValue( entity_t *ent, const char *key, const char *value ) { - epair_t *ep; - - for ( ep = ent->epairs ; ep ; ep = ep->next ) { - if ( strEqual( ep->key, key ) ) { - free( ep->value ); - ep->value = copystring( value ); - return; - } - } - ep = safe_malloc( sizeof( *ep ) ); - ep->next = ent->epairs; - ent->epairs = ep; - ep->key = copystring( key ); - ep->value = copystring( value ); -} - -const char *ValueForKey( const entity_t *ent, const char *key ) { - epair_t *ep; - - for ( ep = ent->epairs ; ep ; ep = ep->next ) { - if ( strEqual( ep->key, key ) ) { - return ep->value; - } - } - return ""; -} - -vec_t FloatForKey( const entity_t *ent, const char *key ) { - const char *k; - - k = ValueForKey( ent, key ); - return atof( k ); -} - -void GetVectorForKey( const entity_t *ent, const char *key, vec3_t vec ) { - const char *k; - double v1, v2, v3; - - k = ValueForKey( ent, key ); - - // scanf into doubles, then assign, so it is vec_t size independent - v1 = v2 = v3 = 0; - sscanf( k, "%lf %lf %lf", &v1, &v2, &v3 ); - vec[0] = v1; - vec[1] = v2; - vec[2] = v3; -} diff --git a/tools/quake3/common/bspfile.h b/tools/quake3/common/bspfile.h deleted file mode 100644 index 1f08a2d5..00000000 --- a/tools/quake3/common/bspfile.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "qfiles.h" -#include "surfaceflags.h" - -extern int bsp_version; - -extern int nummodels; -extern dmodel_t dmodels[MAX_MAP_MODELS]; - -extern int numShaders; -extern dshader_t dshaders[MAX_MAP_MODELS]; - -extern int entdatasize; -extern char dentdata[MAX_MAP_ENTSTRING]; - -extern int numleafs; -extern dleaf_t dleafs[MAX_MAP_LEAFS]; - -extern int numplanes; -extern dplane_t dplanes[MAX_MAP_PLANES]; - -extern int numnodes; -extern dnode_t dnodes[MAX_MAP_NODES]; - -extern int numleafsurfaces; -extern int dleafsurfaces[MAX_MAP_LEAFFACES]; - -extern int numleafbrushes; -extern int dleafbrushes[MAX_MAP_LEAFBRUSHES]; - -extern int numbrushes; -extern dbrush_t dbrushes[MAX_MAP_BRUSHES]; - -extern int numbrushsides; -extern dbrushside_t dbrushsides[MAX_MAP_BRUSHSIDES]; - -void SetLightBytes( int n ); -extern int numLightBytes; -extern byte *lightBytes; - -void SetGridPoints( int n ); -extern int numGridPoints; -extern byte *gridData; - -extern int numVisBytes; -extern byte visBytes[MAX_MAP_VISIBILITY]; - -void SetDrawVerts( int n ); -void IncDrawVerts(); -extern int numDrawVerts; -extern drawVert_t *drawVerts; - -extern int numDrawIndexes; -extern int drawIndexes[MAX_MAP_DRAW_INDEXES]; - -void SetDrawSurfaces( int n ); -void SetDrawSurfacesBuffer(); -extern int numDrawSurfaces; -extern dsurface_t *drawSurfaces; - -extern int numFogs; -extern dfog_t dfogs[MAX_MAP_FOGS]; - -void LoadBSPFile( const char *filename ); -void WriteBSPFile( const char *filename ); -void PrintBSPFileSizes( void ); - -//=============== - - -typedef struct epair_s { - struct epair_s *next; - char *key; - char *value; -} epair_t; - -typedef struct { - vec3_t origin; - struct bspbrush_s *brushes; - struct parseMesh_s *patches; - int firstDrawSurf; - epair_t *epairs; -} entity_t; - -extern int num_entities; -extern entity_t entities[MAX_MAP_ENTITIES]; - -void ParseEntities( void ); -void UnparseEntities( void ); - -void SetKeyValue( entity_t *ent, const char *key, const char *value ); -const char *ValueForKey( const entity_t *ent, const char *key ); -// will return "" if not present - -vec_t FloatForKey( const entity_t *ent, const char *key ); -void GetVectorForKey( const entity_t *ent, const char *key, vec3_t vec ); - -epair_t *ParseEpair( void ); - -void PrintEntity( const entity_t *ent ); diff --git a/tools/quake3/common/cmdlib.cpp b/tools/quake3/common/cmdlib.cpp index d5aa910c..e2abbc07 100644 --- a/tools/quake3/common/cmdlib.cpp +++ b/tools/quake3/common/cmdlib.cpp @@ -47,7 +47,6 @@ #include #endif -#define BASEDIRNAME "quake" // assumed to have a 2 or 3 following void_ptr safe_malloc( size_t size ){ void *p = malloc( size ); @@ -66,121 +65,6 @@ void_ptr safe_calloc( size_t size ){ } -/* - =================== - ExpandWildcards - - Mimic unix command line expansion - =================== - */ -#define MAX_EX_ARGC 1024 -int ex_argc; -char *ex_argv[MAX_EX_ARGC]; -#ifdef _WIN32 -#include "io.h" -void ExpandWildcards( int *argc, char ***argv ){ - struct _finddata_t fileinfo; - - ex_argc = 0; - for ( int i = 0 ; i < *argc ; i++ ) - { - char *path = ( *argv )[i]; - if ( path[0] == '-' - || ( !strchr( path, '*' ) && !strchr( path, '?' ) ) ) { - ex_argv[ex_argc++] = path; - continue; - } - - const int handle = _findfirst( path, &fileinfo ); - if ( handle == -1 ) { - return; - } - - do - { - ex_argv[ex_argc++] = copystring( StringOutputStream( 256 )( PathFilenameless( path ), fileinfo.name ) ); - } while ( _findnext( handle, &fileinfo ) != -1 ); - - _findclose( handle ); - } - - *argc = ex_argc; - *argv = ex_argv; -} -#else -void ExpandWildcards( int *argc, char ***argv ){ -} -#endif - -/* - - qdir will hold the path up to the quake directory, including the slash - - f:\quake\ - /raid/quake/ - - gamedir will hold qdir + the game directory (id1, id2, etc) - - */ - -char qdir[1024]; -char gamedir[1024]; -char writedir[1024]; - -void SetQdirFromPath( const char *path ){ - const char *c; - const char *sep; - int len, count; - - path = ExpandArg( path ); - - // search for "quake2" in path - - len = strlen( BASEDIRNAME ); - for ( c = path + strlen( path ) - 1 ; c != path ; c-- ) - { - if ( strniEqual( c, BASEDIRNAME, len ) ) { - // - //strncpy (qdir, path, c+len+2-path); - // the +2 assumes a 2 or 3 following quake which is not the - // case with a retail install - // so we need to add up how much to the next separator - sep = c + len; - count = 1; - while ( !strEmpty( sep ) && !path_separator( *sep ) ) - { - sep++; - count++; - } - strncpy( qdir, path, c + len + count - path ); - Sys_Printf( "qdir: %s\n", qdir ); - FixDOSName( qdir ); - - c += len + count; - while ( *c ) - { - if ( path_separator( *c ) ) { - strncpy( gamedir, path, c + 1 - path ); - FixDOSName( gamedir ); - Sys_Printf( "gamedir: %s\n", gamedir ); - - if ( strEmpty( writedir ) ) { - strcpy( writedir, gamedir ); - } - else{ - path_add_slash( writedir ); - } - - return; - } - c++; - } - Error( "No gamedir in %s", path ); - return; - } - } - Error( "SetQdirFromPath: no '%s' in %s", BASEDIRNAME, path ); -} char *ExpandArg( const char *path ){ static char full[1024]; @@ -195,17 +79,6 @@ char *ExpandArg( const char *path ){ return full; } -char *ExpandPath( const char *path ){ - static char full[1024]; - if ( path_is_absolute( path ) ) { - strcpy( full, path ); - } - else{ - sprintf( full, "%s%s", qdir, path ); - } - return full; -} - /* @@ -283,23 +156,6 @@ void Q_mkdir( const char *path ){ } } -/* - ============ - FileTime - - returns -1 if not present - ============ - */ -int FileTime( const char *path ){ - struct stat buf; - - if ( stat( path,&buf ) == -1 ) { - return -1; - } - - return buf.st_mtime; -} - /* @@ -445,52 +301,6 @@ void SaveFile( const char *filename, const void *buffer, int count ){ } -/* - ============== - ParseNum / ParseHex - ============== - */ -int ParseHex( const char *hex ){ - const char *str; - int num; - - num = 0; - str = hex; - - while ( *str ) - { - num <<= 4; - if ( *str >= '0' && *str <= '9' ) { - num += *str - '0'; - } - else if ( *str >= 'a' && *str <= 'f' ) { - num += 10 + *str - 'a'; - } - else if ( *str >= 'A' && *str <= 'F' ) { - num += 10 + *str - 'A'; - } - else{ - Error( "Bad hex number: %s",hex ); - } - str++; - } - - return num; -} - - -int ParseNum( const char *str ){ - if ( str[0] == '$' ) { - return ParseHex( str + 1 ); - } - if ( str[0] == '0' && str[1] == 'x' ) { - return ParseHex( str + 2 ); - } - return atol( str ); -} - - - /* ============================================================================ @@ -607,120 +417,6 @@ float LittleFloat( float l ){ //======================================================= -// FIXME: byte swap? - -// this is a 16 bit, non-reflected CRC using the polynomial 0x1021 -// and the initial and final xor values shown below... in other words, the -// CCITT standard CRC used by XMODEM - -#define CRC_INIT_VALUE 0xffff -#define CRC_XOR_VALUE 0x0000 - -static unsigned short crctable[256] = -{ - 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, - 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, - 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, - 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, - 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, - 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, - 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, - 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, - 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, - 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, - 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, - 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, - 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, - 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, - 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, - 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, - 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, - 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, - 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, - 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, - 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, - 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, - 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, - 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, - 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, - 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, - 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, - 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, - 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, - 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, - 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, - 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 -}; - -void CRC_Init( unsigned short *crcvalue ){ - *crcvalue = CRC_INIT_VALUE; -} - -void CRC_ProcessByte( unsigned short *crcvalue, byte data ){ - *crcvalue = ( *crcvalue << 8 ) ^ crctable[( *crcvalue >> 8 ) ^ data]; -} - -unsigned short CRC_Value( unsigned short crcvalue ){ - return crcvalue ^ CRC_XOR_VALUE; -} -//============================================================================= - -/* - ============ - CreatePath - ============ - */ -void CreatePath( const char *path ){ - const char *ofs; - char dir[1024]; - -#ifdef _WIN32 - int olddrive = -1; - - if ( path[1] == ':' ) { - olddrive = _getdrive(); - _chdrive( toupper( path[0] ) - 'A' + 1 ); - } -#endif - - if ( path[1] == ':' ) { - path += 2; - } - - for ( ofs = path + 1 ; *ofs ; ofs++ ) - { - if ( path_separator( *ofs ) ) { // create the directory - memcpy( dir, path, ofs - path ); - dir[ ofs - path ] = 0; - Q_mkdir( dir ); - } - } - -#ifdef _WIN32 - if ( olddrive != -1 ) { - _chdrive( olddrive ); - } -#endif -} - - -/* - ============ - QCopyFile - - Used to archive source files - ============ - */ -void QCopyFile( const char *from, const char *to ){ - void *buffer; - int length; - - length = LoadFile( from, &buffer ); - CreatePath( to ); - SaveFile( to, buffer, length ); - free( buffer ); -} - void Sys_Sleep( int n ){ #ifdef WIN32 Sleep( n ); diff --git a/tools/quake3/common/cmdlib.h b/tools/quake3/common/cmdlib.h index d7a24fa3..b69e0f57 100644 --- a/tools/quake3/common/cmdlib.h +++ b/tools/quake3/common/cmdlib.h @@ -50,17 +50,10 @@ void_ptr safe_calloc( size_t size ); void Q_getwd( char *out ); int Q_filelength( FILE *f ); -int FileTime( const char *path ); void Q_mkdir( const char *path ); -extern char qdir[1024]; -extern char gamedir[1024]; -extern char writedir[1024]; -void SetQdirFromPath( const char *path ); char *ExpandArg( const char *path ); // from cmd line -char *ExpandPath( const char *path ); // from scripts -void ExpandWildcards( int *argc, char ***argv ); double I_FloatTime( void ); @@ -76,8 +69,6 @@ void SaveFile( const char *filename, const void *buffer, int count ); bool FileExists( const char *filename ); -int ParseNum( const char *str ); - short BigShort( short l ); short LittleShort( short l ); int BigLong( int l ); @@ -86,12 +77,5 @@ float BigFloat( float l ); float LittleFloat( float l ); -void CRC_Init( unsigned short *crcvalue ); -void CRC_ProcessByte( unsigned short *crcvalue, byte data ); -unsigned short CRC_Value( unsigned short crcvalue ); - -void CreatePath( const char *path ); -void QCopyFile( const char *from, const char *to ); - // sleep for the given amount of milliseconds void Sys_Sleep( int n ); diff --git a/tools/quake3/common/l3dslib.cpp b/tools/quake3/common/l3dslib.cpp deleted file mode 100644 index bd90fe94..00000000 --- a/tools/quake3/common/l3dslib.cpp +++ /dev/null @@ -1,312 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// l3dslib.c: library for loading triangles from an Alias triangle file -// - -#include -#include "cmdlib.h" -#include "mathlib.h" -#include "trilib.h" -#include "l3dslib.h" - -#define MAIN3DS 0x4D4D -#define EDIT3DS 0x3D3D // this is the start of the editor config -#define EDIT_OBJECT 0x4000 -#define OBJ_TRIMESH 0x4100 -#define TRI_VERTEXL 0x4110 -#define TRI_FACEL1 0x4120 - -#define MAXVERTS 2000 -#define MAXTRIANGLES 750 - -typedef struct { - int v[4]; -} tri; - -float fverts[MAXVERTS][3]; -tri tris[MAXTRIANGLES]; - -int bytesread, level, numtris, totaltris; -int vertsfound, trisfound; - -triangle_t *ptri; - - -// Alias stores triangles as 3 explicit vertices in .tri files, so even though we -// start out with a vertex pool and vertex indices for triangles, we have to convert -// to raw, explicit triangles -void StoreAliasTriangles( void ){ - int i, j, k; - - if ( ( totaltris + numtris ) > MAXTRIANGLES ) { - Error( "Error: Too many triangles" ); - } - - for ( i = 0; i < numtris ; i++ ) - { - for ( j = 0 ; j < 3 ; j++ ) - { - for ( k = 0 ; k < 3 ; k++ ) - { - ptri[i + totaltris].verts[j][k] = fverts[tris[i].v[j]][k]; - } - } - } - - totaltris += numtris; - numtris = 0; - vertsfound = 0; - trisfound = 0; -} - - -int ParseVertexL( FILE *input ){ - int i, j, startbytesread, numverts; - unsigned short tshort; - - if ( vertsfound ) { - Error( "Error: Multiple vertex chunks" ); - } - - vertsfound = 1; - startbytesread = bytesread; - - if ( feof( input ) ) { - Error( "Error: unexpected end of file" ); - } - - fread( &tshort, sizeof( tshort ), 1, input ); - bytesread += sizeof( tshort ); - numverts = (int)tshort; - - if ( numverts > MAXVERTS ) { - Error( "Error: Too many vertices" ); - } - - for ( i = 0 ; i < numverts ; i++ ) - { - for ( j = 0 ; j < 3 ; j++ ) - { - if ( feof( input ) ) { - Error( "Error: unexpected end of file" ); - } - - fread( &fverts[i][j], sizeof( float ), 1, input ); - bytesread += sizeof( float ); - } - } - - if ( vertsfound && trisfound ) { - StoreAliasTriangles(); - } - - return bytesread - startbytesread; -} - - -int ParseFaceL1( FILE *input ){ - - int i, j, startbytesread; - unsigned short tshort; - - if ( trisfound ) { - Error( "Error: Multiple face chunks" ); - } - - trisfound = 1; - startbytesread = bytesread; - - if ( feof( input ) ) { - Error( "Error: unexpected end of file" ); - } - - fread( &tshort, sizeof( tshort ), 1, input ); - bytesread += sizeof( tshort ); - numtris = (int)tshort; - - if ( numtris > MAXTRIANGLES ) { - Error( "Error: Too many triangles" ); - } - - for ( i = 0 ; i < numtris ; i++ ) - { - for ( j = 0 ; j < 4 ; j++ ) - { - if ( feof( input ) ) { - Error( "Error: unexpected end of file" ); - } - - fread( &tshort, sizeof( tshort ), 1, input ); - bytesread += sizeof( tshort ); - tris[i].v[j] = (int)tshort; - } - } - - if ( vertsfound && trisfound ) { - StoreAliasTriangles(); - } - - return bytesread - startbytesread; -} - - -int ParseChunk( FILE *input ){ -#define BLOCK_SIZE 4096 - char temp[BLOCK_SIZE]; - unsigned short type; - int i, length, w, t, retval; - - level++; - retval = 0; - -// chunk type - if ( feof( input ) ) { - Error( "Error: unexpected end of file" ); - } - - fread( &type, sizeof( type ), 1, input ); - bytesread += sizeof( type ); - -// chunk length - if ( feof( input ) ) { - Error( "Error: unexpected end of file" ); - } - - fread( &length, sizeof( length ), 1, input ); - bytesread += sizeof( length ); - w = length - 6; - -// process chunk if we care about it, otherwise skip it - switch ( type ) - { - case TRI_VERTEXL: - w -= ParseVertexL( input ); - goto ParseSubchunk; - - case TRI_FACEL1: - w -= ParseFaceL1( input ); - goto ParseSubchunk; - - case EDIT_OBJECT: - // read the name - i = 0; - - do - { - if ( feof( input ) ) { - Error( "Error: unexpected end of file" ); - } - - fread( &temp[i], 1, 1, input ); - i++; - w--; - bytesread++; - } while ( temp[i - 1] ); - // fall through - case MAIN3DS: - case OBJ_TRIMESH: - case EDIT3DS: - // parse through subchunks -ParseSubchunk: - while ( w > 0 ) - { - w -= ParseChunk( input ); - } - - retval = length; - goto Done; - - default: - // skip other chunks - while ( w > 0 ) - { - t = w; - - if ( t > BLOCK_SIZE ) { - t = BLOCK_SIZE; - } - - if ( feof( input ) ) { - Error( "Error: unexpected end of file" ); - } - - fread( &temp, t, 1, input ); - bytesread += t; - - w -= t; - } - - retval = length; - goto Done; - } - -Done: - level--; - return retval; -} - - -void Load3DSTriangleList( char *filename, triangle_t **pptri, int *numtriangles ){ - FILE *input; - short int tshort; - - bytesread = 0; - level = 0; - numtris = 0; - totaltris = 0; - vertsfound = 0; - trisfound = 0; - - if ( ( input = fopen( filename, "rb" ) ) == 0 ) { - fprintf( stderr, "reader: could not open file '%s'\n", filename ); - exit( 0 ); - } - - fread( &tshort, sizeof( tshort ), 1, input ); - -// should only be MAIN3DS, but some files seem to start with EDIT3DS, with -// no MAIN3DS - if ( ( tshort != MAIN3DS ) && ( tshort != EDIT3DS ) ) { - fprintf( stderr, "File is not a 3DS file.\n" ); - exit( 0 ); - } - -// back to top of file so we can parse the first chunk descriptor - fseek( input, 0, SEEK_SET ); - - ptri = safe_malloc( MAXTRIANGLES * sizeof( triangle_t ) ); - - *pptri = ptri; - -// parse through looking for the relevant chunk tree (MAIN3DS | EDIT3DS | EDIT_OBJECT | -// OBJ_TRIMESH | {TRI_VERTEXL, TRI_FACEL1}) and skipping other chunks - ParseChunk( input ); - - if ( vertsfound || trisfound ) { - Error( "Incomplete triangle set" ); - } - - *numtriangles = totaltris; - - fclose( input ); -} diff --git a/tools/quake3/common/l3dslib.h b/tools/quake3/common/l3dslib.h deleted file mode 100644 index cc5cddab..00000000 --- a/tools/quake3/common/l3dslib.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// l3dslib.h: header file for loading triangles from a 3DS triangle file -// -void Load3DSTriangleList( char *filename, triangle_t **pptri, int *numtriangles ); diff --git a/tools/quake3/common/polyset.h b/tools/quake3/common/polyset.h deleted file mode 100644 index 76ee8991..00000000 --- a/tools/quake3/common/polyset.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __POLYSET_H__ -#define __POLYSET_H__ - -#define POLYSET_MAXTRIANGLES 4096 -#define POLYSET_MAXPOLYSETS 64 - -#include "mathlib.h" - -typedef float st_t[2]; -typedef float rgb_t[3]; - -typedef struct { - vec3_t verts[3]; - vec3_t normals[3]; - st_t texcoords[3]; -} triangle_t; - -typedef struct -{ - char name[100]; - char materialname[100]; - triangle_t *triangles; - int numtriangles; -} polyset_t; - -polyset_t *Polyset_LoadSets( const char *file, int *numpolysets, int maxTrisPerSet ); -polyset_t *Polyset_CollapseSets( polyset_t *psets, int numpolysets ); -polyset_t *Polyset_SplitSets( polyset_t *psets, int numpolysets, int *pNumNewPolysets, int maxTris ); -void Polyset_SnapSets( polyset_t *psets, int numpolysets ); -void Polyset_ComputeNormals( polyset_t *psets, int numpolysets ); - -#endif diff --git a/tools/quake3/common/qfiles.h b/tools/quake3/common/qfiles.h deleted file mode 100644 index f2709de6..00000000 --- a/tools/quake3/common/qfiles.h +++ /dev/null @@ -1,491 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __QFILES_H__ -#define __QFILES_H__ - -// -// qfiles.h: quake file formats -// This file must be identical in the quake and utils directories -// - -#include "mathlib.h" - -// surface geometry should not exceed these limits -#define SHADER_MAX_VERTEXES 1000 -#define SHADER_MAX_INDEXES ( 6 * SHADER_MAX_VERTEXES ) - - -// the maximum size of game relative pathnames -#define MAX_QPATH 64 - -/* - ======================================================================== - - QVM files - - ======================================================================== - */ - -#define VM_MAGIC 0x12721444 -typedef struct { - int vmMagic; - - int instructionCount; - - int codeOffset; - int codeLength; - - int dataOffset; - int dataLength; - int litLength; // ( dataLength - litLength ) should be byteswapped on load - int bssLength; // zero filled memory appended to datalength -} vmHeader_t; - - -/* - ======================================================================== - - PCX files are used for 8 bit images - - ======================================================================== - */ - -typedef struct { - char manufacturer; - char version; - char encoding; - char bits_per_pixel; - unsigned short xmin,ymin,xmax,ymax; - unsigned short hres,vres; - unsigned char palette[48]; - char reserved; - char color_planes; - unsigned short bytes_per_line; - unsigned short palette_type; - char filler[58]; - unsigned char data; // unbounded -} pcx_t; - - -/* - ======================================================================== - - TGA files are used for 24/32 bit images - - ======================================================================== - */ - -typedef struct _TargaHeader { - unsigned char id_length, colormap_type, image_type; - unsigned short colormap_index, colormap_length; - unsigned char colormap_size; - unsigned short x_origin, y_origin, width, height; - unsigned char pixel_size, attributes; -} TargaHeader; - - - -/* - ======================================================================== - - .MD3 triangle model file format - - ======================================================================== - */ - -#define MD3_IDENT ( ( '3' << 24 ) + ( 'P' << 16 ) + ( 'D' << 8 ) + 'I' ) -#define MD3_VERSION 15 - -// limits -#define MD3_MAX_LODS 4 -#define MD3_MAX_TRIANGLES 8192 // per surface -#define MD3_MAX_VERTS 4096 // per surface -#define MD3_MAX_SHADERS 256 // per surface -#define MD3_MAX_FRAMES 1024 // per model -#define MD3_MAX_SURFACES 32 // per model -#define MD3_MAX_TAGS 16 // per frame - -// vertex scales -#define MD3_XYZ_SCALE ( 1.0 / 64 ) - -typedef struct md3Frame_s { - vec3_t bounds[2]; - vec3_t localOrigin; - float radius; - char name[16]; -} md3Frame_t; - -typedef struct md3Tag_s { - char name[MAX_QPATH]; // tag name - vec3_t origin; - vec3_t axis[3]; -} md3Tag_t; - -/* -** md3Surface_t -** -** CHUNK SIZE -** header sizeof( md3Surface_t ) -** shaders sizeof( md3Shader_t ) * numShaders -** triangles[0] sizeof( md3Triangle_t ) * numTriangles -** st sizeof( md3St_t ) * numVerts -** XyzNormals sizeof( md3XyzNormal_t ) * numVerts * numFrames -*/ -typedef struct { - int ident; // - - char name[MAX_QPATH]; // polyset name - - int flags; - int numFrames; // all surfaces in a model should have the same - - int numShaders; // all surfaces in a model should have the same - int numVerts; - - int numTriangles; - int ofsTriangles; - - int ofsShaders; // offset from start of md3Surface_t - int ofsSt; // texture coords are common for all frames - int ofsXyzNormals; // numVerts * numFrames - - int ofsEnd; // next surface follows -} md3Surface_t; - -typedef struct { - char name[MAX_QPATH]; - int shaderIndex; // for in-game use -} md3Shader_t; - -typedef struct { - int indexes[3]; -} md3Triangle_t; - -typedef struct { - float st[2]; -} md3St_t; - -typedef struct { - short xyz[3]; - short normal; -} md3XyzNormal_t; - -typedef struct { - int ident; - int version; - - char name[MAX_QPATH]; // model name - - int flags; - - int numFrames; - int numTags; - int numSurfaces; - - int numSkins; - - int ofsFrames; // offset for first frame - int ofsTags; // numFrames * numTags - int ofsSurfaces; // first surface, others follow - - int ofsEnd; // end of file -} md3Header_t; - -/* - ============================================================================== - - MD4 file format - - ============================================================================== - */ - -#define MD4_IDENT ( ( '4' << 24 ) + ( 'P' << 16 ) + ( 'D' << 8 ) + 'I' ) -#define MD4_VERSION 1 -#define MD4_MAX_BONES 128 - -typedef struct { - int boneIndex; // these are indexes into the boneReferences, - float boneWeight; // not the global per-frame bone list -} md4Weight_t; - -typedef struct { - vec3_t vertex; - vec3_t normal; - float texCoords[2]; - int numWeights; - md4Weight_t weights[1]; // variable sized -} md4Vertex_t; - -typedef struct { - int indexes[3]; -} md4Triangle_t; - -typedef struct { - int ident; - - char name[MAX_QPATH]; // polyset name - char shader[MAX_QPATH]; - int shaderIndex; // for in-game use - - int ofsHeader; // this will be a negative number - - int numVerts; - int ofsVerts; - - int numTriangles; - int ofsTriangles; - - // Bone references are a set of ints representing all the bones - // present in any vertex weights for this surface. This is - // needed because a model may have surfaces that need to be - // drawn at different sort times, and we don't want to have - // to re-interpolate all the bones for each surface. - int numBoneReferences; - int ofsBoneReferences; - - int ofsEnd; // next surface follows -} md4Surface_t; - -typedef struct { - float matrix[3][4]; -} md4Bone_t; - -typedef struct { - vec3_t bounds[2]; // bounds of all surfaces of all LOD's for this frame - vec3_t localOrigin; // midpoint of bounds, used for sphere cull - float radius; // dist from localOrigin to corner - char name[16]; - md4Bone_t bones[1]; // [numBones] -} md4Frame_t; - -typedef struct { - int numSurfaces; - int ofsSurfaces; // first surface, others follow - int ofsEnd; // next lod follows -} md4LOD_t; - -typedef struct { - int ident; - int version; - - char name[MAX_QPATH]; // model name - - // frames and bones are shared by all levels of detail - int numFrames; - int numBones; - int ofsFrames; // md4Frame_t[numFrames] - - // each level of detail has completely separate sets of surfaces - int numLODs; - int ofsLODs; - - int ofsEnd; // end of file -} md4Header_t; - - -/* - ============================================================================== - - .BSP file format - - ============================================================================== - */ - - -#define BSP_IDENT ( ( 'P' << 24 ) + ( 'S' << 16 ) + ( 'B' << 8 ) + 'I' ) -// little-endian "IBSP" - -//#define BSP_VERSION 46 -#define Q3_BSP_VERSION 46 -#define WOLF_BSP_VERSION 47 - -// there shouldn't be any problem with increasing these values at the -// expense of more memory allocation in the utilities -#define MAX_MAP_MODELS 0x400 -#define MAX_MAP_BRUSHES 0x8000 -#define MAX_MAP_ENTITIES 0x800 -#define MAX_MAP_ENTSTRING 0x40000 -#define MAX_MAP_SHADERS 0x400 - -#define MAX_MAP_AREAS 0x100 // MAX_MAP_AREA_BYTES in q_shared must match! -#define MAX_MAP_FOGS 0x100 -#define MAX_MAP_PLANES 0x20000 -#define MAX_MAP_NODES 0x20000 -#define MAX_MAP_BRUSHSIDES 0x40000 //% 0x20000 /* ydnar */ -#define MAX_MAP_LEAFS 0x20000 -#define MAX_MAP_LEAFFACES 0x20000 -#define MAX_MAP_LEAFBRUSHES 0x40000 -#define MAX_MAP_PORTALS 0x20000 -#define MAX_MAP_LIGHTING 0x800000 -#define MAX_MAP_LIGHTGRID 0x800000 -#define MAX_MAP_VISIBILITY 0x200000 - -#define MAX_MAP_DRAW_SURFS 0x20000 -#define MAX_MAP_DRAW_VERTS 0x80000 -#define MAX_MAP_DRAW_INDEXES 0x80000 - - -// key / value pair sizes in the entities lump -#define MAX_KEY 32 -#define MAX_VALUE 1024 - -// the editor uses these predefined yaw angles to orient entities up or down -#define ANGLE_UP -1 -#define ANGLE_DOWN -2 - -#define LIGHTMAP_WIDTH 128 -#define LIGHTMAP_HEIGHT 128 - -#define MIN_WORLD_COORD ( -65536 ) -#define MAX_WORLD_COORD ( 65536 ) -#define WORLD_SIZE ( MAX_WORLD_COORD - MIN_WORLD_COORD ) - -//============================================================================= - - -typedef struct { - int fileofs, filelen; -} lump_t; - -#define LUMP_ENTITIES 0 -#define LUMP_SHADERS 1 -#define LUMP_PLANES 2 -#define LUMP_NODES 3 -#define LUMP_LEAFS 4 -#define LUMP_LEAFSURFACES 5 -#define LUMP_LEAFBRUSHES 6 -#define LUMP_MODELS 7 -#define LUMP_BRUSHES 8 -#define LUMP_BRUSHSIDES 9 -#define LUMP_DRAWVERTS 10 -#define LUMP_DRAWINDEXES 11 -#define LUMP_FOGS 12 -#define LUMP_SURFACES 13 -#define LUMP_LIGHTMAPS 14 -#define LUMP_LIGHTGRID 15 -#define LUMP_VISIBILITY 16 -#define HEADER_LUMPS 17 - -typedef struct { - int ident; - int version; - - lump_t lumps[HEADER_LUMPS]; -} dheader_t; - -typedef struct { - float mins[3], maxs[3]; - int firstSurface, numSurfaces; - int firstBrush, numBrushes; -} dmodel_t; - -typedef struct { - char shader[MAX_QPATH]; - int surfaceFlags; - int contentFlags; -} dshader_t; - -// planes x^1 is always the opposite of plane x - -typedef struct { - float normal[3]; - float dist; -} dplane_t; - -typedef struct { - int planeNum; - int children[2]; // negative numbers are -(leafs+1), not nodes - int mins[3]; // for frustum culling - int maxs[3]; -} dnode_t; - -typedef struct { - int cluster; // -1 = opaque cluster (do I still store these?) - int area; - - int mins[3]; // for frustum culling - int maxs[3]; - - int firstLeafSurface; - int numLeafSurfaces; - - int firstLeafBrush; - int numLeafBrushes; -} dleaf_t; - -typedef struct { - int planeNum; // positive plane side faces out of the leaf - int shaderNum; -} dbrushside_t; - -typedef struct { - int firstSide; - int numSides; - int shaderNum; // the shader that determines the contents flags -} dbrush_t; - -typedef struct { - char shader[MAX_QPATH]; - int brushNum; - int visibleSide; // the brush side that ray tests need to clip against (-1 == none) -} dfog_t; - -typedef struct { - vec3_t xyz; - float st[2]; - float lightmap[2]; - vec3_t normal; - byte color[4]; -} drawVert_t; - -typedef enum { - MST_BAD, - MST_PLANAR, - MST_PATCH, - MST_TRIANGLE_SOUP, - MST_FLARE -} mapSurfaceType_t; - -typedef struct { - int shaderNum; - int fogNum; - int surfaceType; - - int firstVert; - int numVerts; - - int firstIndex; - int numIndexes; - - int lightmapNum; - int lightmapX, lightmapY; - int lightmapWidth, lightmapHeight; - - vec3_t lightmapOrigin; - vec3_t lightmapVecs[3]; // for patches, [0] and [1] are lodbounds - - int patchWidth; - int patchHeight; -} dsurface_t; - - -#endif diff --git a/tools/quake3/common/surfaceflags.h b/tools/quake3/common/surfaceflags.h deleted file mode 100644 index 36a3eb70..00000000 --- a/tools/quake3/common/surfaceflags.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// Copyright (C) 1999-2000 Id Software, Inc. -// -// This file must be identical in the quake and utils directories - -// contents flags are separate bits -// a given brush can contribute multiple content bits - -// these definitions also need to be in q_shared.h! - -#define CONTENTS_SOLID 1 // an eye is never valid in a solid -#define CONTENTS_LAVA 8 -#define CONTENTS_SLIME 16 -#define CONTENTS_WATER 32 -#define CONTENTS_FOG 64 - -#define CONTENTS_AREAPORTAL 0x8000 - -#define CONTENTS_PLAYERCLIP 0x10000 -#define CONTENTS_MONSTERCLIP 0x20000 -//bot specific contents types -#define CONTENTS_TELEPORTER 0x40000 -#define CONTENTS_JUMPPAD 0x80000 -#define CONTENTS_CLUSTERPORTAL 0x100000 -#define CONTENTS_DONOTENTER 0x200000 -#define CONTENTS_BOTCLIP 0x400000 - -#define CONTENTS_ORIGIN 0x1000000 // removed before bsping an entity - -#define CONTENTS_BODY 0x2000000 // should never be on a brush, only in game -#define CONTENTS_CORPSE 0x4000000 -#define CONTENTS_DETAIL 0x8000000 // brushes not used for the bsp -#define CONTENTS_STRUCTURAL 0x10000000 // brushes used for the bsp -#define CONTENTS_TRANSLUCENT 0x20000000 // don't consume surface fragments inside -#define CONTENTS_TRIGGER 0x40000000 -#define CONTENTS_NODROP 0x80000000 // don't leave bodies or items (death fog, lava) - -#define SURF_NODAMAGE 0x1 // never give falling damage -#define SURF_SLICK 0x2 // effects game physics -#define SURF_SKY 0x4 // lighting from environment map -#define SURF_LADDER 0x8 -#define SURF_NOIMPACT 0x10 // don't make missile explosions -#define SURF_NOMARKS 0x20 // don't leave missile marks -#define SURF_FLESH 0x40 // make flesh sounds and effects -#define SURF_NODRAW 0x80 // don't generate a drawsurface at all -#define SURF_HINT 0x100 // make a primary bsp splitter -#define SURF_SKIP 0x200 // completely ignore, allowing non-closed brushes -#define SURF_NOLIGHTMAP 0x400 // surface doesn't need a lightmap -#define SURF_POINTLIGHT 0x800 // generate lighting info at vertexes -#define SURF_METALSTEPS 0x1000 // clanking footsteps -#define SURF_NOSTEPS 0x2000 // no footstep sounds -#define SURF_NONSOLID 0x4000 // don't collide against curves with this set -#define SURF_LIGHTFILTER 0x8000 // act as a light filter during q3map -light -#define SURF_ALPHASHADOW 0x10000 // do per-pixel light shadow casting in q3map -#define SURF_NODLIGHT 0x20000 // don't dlight even if solid (solid lava, skies) -#define SURF_DUST 0x40000 // leave a dust trail when walking on this surface - - - - -/* ydnar flags */ - -#define CONTENTS_OPAQUE 0x02 -#define CONTENTS_LIGHTGRID 0x04 - -#define SURF_VERTEXLIT ( SURF_POINTLIGHT | SURF_NOLIGHTMAP ) - - - -/* wolfenstein flags (collisions with valid q3a flags are noted) */ - -#define CONTENTS_MISSILECLIP 0x80 -#define CONTENTS_ITEM 0x100 -#define CONTENTS_AI_NOSIGHT 0x1000 -#define CONTENTS_CLIPSHOT 0x2000 -#define CONTENTS_DONOTENTER_LARGE 0x400000 /* CONTENTS_BOTCLIP */ - -#define SURF_CERAMIC 0x40 /* SURF_FLESH */ -#define SURF_METAL 0x1000 /* SURF_METALSTEPS */ -#define SURF_WOOD 0x40000 /* SURF_DUST */ -#define SURF_GRASS 0x80000 -#define SURF_GRAVEL 0x100000 -#define SURF_GLASS 0x200000 -#define SURF_SNOW 0x400000 -#define SURF_ROOF 0x800000 -#define SURF_RUBBLE 0x1000000 -#define SURF_CARPET 0x2000000 -#define SURF_MONSTERSLICK 0x4000000 -#define SURF_MONSLICK_W 0x8000000 -#define SURF_MONSLICK_N 0x10000000 -#define SURF_MONSLICK_E 0x20000000 -#define SURF_MONSLICK_S 0x40000000 diff --git a/tools/quake3/common/trilib.cpp b/tools/quake3/common/trilib.cpp deleted file mode 100644 index 191164c6..00000000 --- a/tools/quake3/common/trilib.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// trilib.c: library for loading triangles from an Alias triangle file -// - -#include -#include "cmdlib.h" -#include "inout.h" -#include "qstringops.h" -#include "mathlib.h" -#include "polyset.h" -#include "trilib.h" - -// on disk representation of a face - - -#define FLOAT_START 99999.0 -#define FLOAT_END -FLOAT_START -#define MAGIC 123322 - -typedef struct { - float v[3]; -} vector; - -typedef struct -{ - vector n; /* normal */ - vector p; /* point */ - vector c; /* color */ - float u; /* u */ - float v; /* v */ -} aliaspoint_t; - -typedef struct { - aliaspoint_t pt[3]; -} tf_triangle; - - -static void ByteSwapTri( tf_triangle *tri ){ - for ( size_t i = 0 ; i < sizeof( tf_triangle ) / 4 ; i++ ) - { - ( (int *)tri )[i] = BigLong( ( (int *)tri )[i] ); - } -} - -static void ReadPolysetGeometry( triangle_t *tripool, FILE *input, int count, triangle_t *ptri ){ - tf_triangle tri; - int i; - - for ( i = 0; i < count; ++i ) { - int j; - - fread( &tri, sizeof( tf_triangle ), 1, input ); - ByteSwapTri( &tri ); - for ( j = 0 ; j < 3 ; j++ ) - { - int k; - - for ( k = 0 ; k < 3 ; k++ ) - { - ptri->verts[j][k] = tri.pt[j].p.v[k]; - ptri->normals[j][k] = tri.pt[j].n.v[k]; -// ptri->colors[j][k] = tri.pt[j].c.v[k]; - } - - ptri->texcoords[j][0] = tri.pt[j].u; - ptri->texcoords[j][1] = tri.pt[j].v; - } - - ptri++; - if ( ( ptri - tripool ) >= POLYSET_MAXTRIANGLES ) { - Error( "Error: too many triangles; increase POLYSET_MAXTRIANGLES\n" ); - } - } -} - -void TRI_LoadPolysets( const char *filename, polyset_t **ppPSET, int *numpsets ){ - FILE *input; - float start; - char name[256], tex[256]; - int i, count, magic, pset = 0; - triangle_t *ptri; - polyset_t *pPSET; - int iLevel; - int exitpattern; - float t; - - t = -FLOAT_START; - *( (unsigned char *)&exitpattern + 0 ) = *( (unsigned char *)&t + 3 ); - *( (unsigned char *)&exitpattern + 1 ) = *( (unsigned char *)&t + 2 ); - *( (unsigned char *)&exitpattern + 2 ) = *( (unsigned char *)&t + 1 ); - *( (unsigned char *)&exitpattern + 3 ) = *( (unsigned char *)&t + 0 ); - - if ( ( input = fopen( filename, "rb" ) ) == 0 ) { - Error( "reader: could not open file '%s'", filename ); - } - - iLevel = 0; - - fread( &magic, sizeof( int ), 1, input ); - if ( BigLong( magic ) != MAGIC ) { - Error( "%s is not a Alias object separated triangle file, magic number is wrong.", filename ); - } - - pPSET = safe_calloc( POLYSET_MAXPOLYSETS * sizeof( polyset_t ) ); - ptri = safe_calloc( POLYSET_MAXTRIANGLES * sizeof( triangle_t ) ); - - *ppPSET = pPSET; - - while ( feof( input ) == 0 ) { - if ( fread( &start, sizeof( float ), 1, input ) < 1 ) { - break; - } - *(int *)&start = BigLong( *(int *)&start ); - if ( *(int *)&start != exitpattern ) { - if ( start == FLOAT_START ) { - /* Start of an object or group of objects. */ - i = -1; - do { - /* There are probably better ways to read a string from */ - /* a file, but this does allow you to do error checking */ - /* (which I'm not doing) on a per character basis. */ - ++i; - fread( &( name[i] ), sizeof( char ), 1, input ); - } while ( name[i] != '\0' ); - - if ( i != 0 ) { - strncpy( pPSET[pset].name, name, sizeof( pPSET[pset].name ) - 1 ); - } - else{ - strcpy( pPSET[pset].name, "(unnamed)" ); - } - strLower( pPSET[pset].name ); - -// indent(); -// fprintf( stdout, "OBJECT START: %s\n", name ); - fread( &count, sizeof( int ), 1, input ); - count = BigLong( count ); - ++iLevel; - if ( count != 0 ) { -// indent(); -// fprintf( stdout, "NUMBER OF TRIANGLES: %d\n", count ); - - i = -1; - do { - ++i; - fread( &( tex[i] ), sizeof( char ), 1, input ); - } while ( tex[i] != '\0' ); - -/* - if ( i != 0 ) - strncpy( pPSET[pset].texname, tex, sizeof( pPSET[pset].texname ) - 1 ); - else - strcpy( pPSET[pset].texname, "(unnamed)" ); - strLower( pPSET[pset].texname ); - */ - -// indent(); -// fprintf( stdout, " Object texture name: '%s'\n", tex ); - } - - /* Else (count == 0) this is the start of a group, and */ - /* no texture name is present. */ - } - else if ( start == FLOAT_END ) { - /* End of an object or group. Yes, the name should be */ - /* obvious from context, but it is in here just to be */ - /* safe and to provide a little extra information for */ - /* those who do not wish to write a recursive reader. */ - /* Mea culpa. */ - --iLevel; - i = -1; - do { - ++i; - fread( &( name[i] ), sizeof( char ), 1, input ); - } while ( name[i] != '\0' ); - - if ( i != 0 ) { - strncpy( pPSET[pset].name, name, sizeof( pPSET[pset].name ) - 1 ); - } - else{ - strcpy( pPSET[pset].name, "(unnamed)" ); - } - - strLower( pPSET[pset].name ); - -// indent(); -// fprintf( stdout, "OBJECT END: %s\n", name ); - continue; - } - } - -// -// read the triangles -// - if ( count > 0 ) { - pPSET[pset].triangles = ptri; - ReadPolysetGeometry( pPSET[0].triangles, input, count, ptri ); - ptri += count; - pPSET[pset].numtriangles = count; - if ( ++pset >= POLYSET_MAXPOLYSETS ) { - Error( "Error: too many polysets; increase POLYSET_MAXPOLYSETS\n" ); - } - } - } - - *numpsets = pset; - - fclose( input ); -} diff --git a/tools/quake3/common/trilib.h b/tools/quake3/common/trilib.h deleted file mode 100644 index ad14dec8..00000000 --- a/tools/quake3/common/trilib.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// -// trilib.h: header file for loading triangles from an Alias triangle file -// -void TRI_LoadPolysets( const char *filename, polyset_t **ppPSET, int *numpsets ); diff --git a/tools/quake3/q3data/.cvswrappers b/tools/quake3/q3data/.cvswrappers deleted file mode 100644 index 2ea7d171..00000000 --- a/tools/quake3/q3data/.cvswrappers +++ /dev/null @@ -1,2 +0,0 @@ -*.dsp -m 'COPY' -k 'b' -*.dsw -m 'COPY' -k 'b' diff --git a/tools/quake3/q3data/3dslib.cpp b/tools/quake3/q3data/3dslib.cpp deleted file mode 100644 index 2dacb3e1..00000000 --- a/tools/quake3/q3data/3dslib.cpp +++ /dev/null @@ -1,658 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "q3data.h" - -static void Load3DS( const char *filename, _3DS_t *p3DS, bool verbose ); - -static bool s_verbose; - -#define MAX_MATERIALS 100 -#define MAX_NAMED_OBJECTS 100 -#define MAX_MESH_MATERIAL_GROUPS 100 -#define MAX_TRI_OBJECTS 512 - -static char s_buffer[1000000]; - -static int ReadString( FILE *fp, char *buffer ){ - int i = 0; - int bytesRead = 0; - - do - { - fread( &buffer[i], 1, sizeof( char ), fp ); - bytesRead++; - } while ( buffer[i++] != 0 ); - buffer[i] = 0; - - return bytesRead; -} - -static int ReadChunkAndLength( FILE *fp, unsigned short *chunk, long *len ){ - if ( fread( chunk, sizeof( *chunk ), 1, fp ) != 1 ) { - return 0; - } - if ( fread( len, sizeof( long ), 1, fp ) != 1 ) { - Error( "Unexpected EOF found" ); - } - return 1; -} - -static void LoadMapName( FILE *fp, char *buffer, int thisChunkLen ){ - unsigned short chunkID; - long chunkLen; - long bytesRead = 0; - - while ( ReadChunkAndLength( fp, &chunkID, &chunkLen ) ) - { - switch ( chunkID ) - { - case _3DS_CHUNK_MAT_MAPNAME: - fread( buffer, chunkLen - 6, 1, fp ); - break; - default: - fread( s_buffer, chunkLen - 6, 1, fp ); - break; - } - bytesRead += chunkLen; - if ( bytesRead >= thisChunkLen ) { - return; - } - } -} - -static void LoadMaterialList( FILE *fp, long thisChunkLen, _3DSMaterial_t *pMat ){ - long chunkLen; - unsigned short chunkID; - long bytesRead = 0; - _3DSMaterial_t mat; - char curdir[1024]; - char buffer[2048]; - - memset( &mat, 0, sizeof( mat ) ); - - if ( s_verbose ) { - printf( " >>> MATERIAL LIST\n" ); - } - - while ( ReadChunkAndLength( fp, &chunkID, &chunkLen ) ) - { - switch ( chunkID ) - { - case _3DS_CHUNK_MAT_NAME: - fread( mat.name, chunkLen - 6, 1, fp ); - if ( s_verbose ) { - printf( " found mat name '%s'\n", mat.name ); - } - break; - case _3DS_CHUNK_TEXMAP: - LoadMapName( fp, mat.texture, chunkLen - 6 ); - if ( s_verbose ) { - printf( " found texture '%s'\n", mat.texture ); - } - break; - case _3DS_CHUNK_SPECMAP: - LoadMapName( fp, mat.specular, chunkLen - 6 ); - if ( s_verbose ) { - printf( " found specular map '%s'\n", mat.specular ); - } - break; - case _3DS_CHUNK_OPACMAP: - LoadMapName( fp, mat.opacity, chunkLen - 6 ); - if ( s_verbose ) { - printf( " found opacity map '%s'\n", mat.opacity ); - } - break; - case _3DS_CHUNK_REFLMAP: - LoadMapName( fp, mat.reflection, chunkLen - 6 ); - if ( s_verbose ) { - printf( " found reflection map '%s'\n", mat.reflection ); - } - break; - case _3DS_CHUNK_BUMPMAP: - LoadMapName( fp, mat.bump, chunkLen - 6 ); - if ( s_verbose ) { - printf( " found bump map '%s'\n", mat.bump ); - } - break; - default: - fread( s_buffer, chunkLen - 6, 1, fp ); - break; - } - - bytesRead += chunkLen; - - if ( bytesRead >= thisChunkLen ) { - break; - } - } - - Q_getwd( curdir ); - - if ( mat.texture[0] ) { - sprintf( buffer, "%s%s", curdir, mat.texture ); - if ( strstr( buffer, gamedir + 1 ) ) { - strcpy( mat.texture, strstr( buffer, gamedir + 1 ) + strlen( gamedir ) - 1 ); - } - else{ - strcpy( mat.texture, buffer ); - } - } - - if ( mat.specular[0] ) { - sprintf( buffer, "%s%s", curdir, mat.specular ); - if ( strstr( buffer, gamedir + 1 ) ) { - strcpy( mat.specular, strstr( buffer, gamedir + 1 ) + strlen( gamedir ) - 1 ); - } - else{ - strcpy( mat.specular, buffer ); - } - } - - if ( mat.bump[0] ) { - sprintf( buffer, "%s%s", curdir, mat.bump ); - if ( strstr( buffer, gamedir + 1 ) ) { - strcpy( mat.bump, strstr( buffer, gamedir + 1 ) + strlen( gamedir ) - 1 ); - } - else{ - strcpy( mat.bump, buffer ); - } - } - - if ( mat.reflection[0] ) { - sprintf( buffer, "%s%s", curdir, mat.reflection ); - if ( strstr( buffer, gamedir + 1 ) ) { - strcpy( mat.reflection, strstr( buffer, gamedir + 1 ) + strlen( gamedir ) - 1 ); - } - else{ - strcpy( mat.reflection, buffer ); - } - } - - if ( mat.opacity[0] ) { - sprintf( buffer, "%s%s", curdir, mat.opacity ); - if ( strstr( buffer, gamedir + 1 ) ) { - strcpy( mat.opacity, strstr( buffer, gamedir + 1 ) + strlen( gamedir ) - 1 ); - } - else{ - strcpy( mat.opacity, buffer ); - } - } - - *pMat = mat; -} - -static void LoadMeshMaterialGroup( FILE *fp, long thisChunkLen, _3DSMeshMaterialGroup_t *pMMG ){ - _3DSMeshMaterialGroup_t mmg; - - memset( &mmg, 0, sizeof( mmg ) ); - - ReadString( fp, mmg.name ); - - fread( &mmg.numFaces, sizeof( mmg.numFaces ), 1, fp ); - mmg.pFaces = safe_malloc( sizeof( mmg.pFaces[0] ) * mmg.numFaces ); - fread( mmg.pFaces, sizeof( mmg.pFaces[0] ), mmg.numFaces, fp ); - - if ( s_verbose ) { - printf( " >>> MESH MATERIAL GROUP '%s' (%d faces)\n", mmg.name, mmg.numFaces ); - - { - int i; - - for ( i = 0; i < mmg.numFaces; i++ ) - { - printf( " %d\n", mmg.pFaces[i] ); - } - } - } - - *pMMG = mmg; -} - -static void LoadNamedTriObject( FILE *fp, long thisChunkLen, _3DSTriObject_t *pTO ){ - long chunkLen; - unsigned short chunkID; - int i = 0; - long bytesRead = 0; - _3DSTriObject_t triObj; - _3DSMeshMaterialGroup_t meshMaterialGroups[MAX_MESH_MATERIAL_GROUPS]; - int numMeshMaterialGroups = 0; - - memset( &triObj, 0, sizeof( triObj ) ); - - if ( s_verbose ) { - printf( " >>> NAMED TRI OBJECT\n" ); - } - - while ( ReadChunkAndLength( fp, &chunkID, &chunkLen ) ) - { - switch ( chunkID ) - { - case _3DS_CHUNK_MSH_MAT_GROUP: - LoadMeshMaterialGroup( fp, chunkLen - 6, &meshMaterialGroups[numMeshMaterialGroups] ); - bytesRead += chunkLen; - numMeshMaterialGroups++; - break; - case _3DS_CHUNK_FACE_ARRAY: - fread( &triObj.numFaces, sizeof( triObj.numFaces ), 1, fp ); - assert( triObj.pFaces == 0 ); - - triObj.pFaces = safe_malloc( sizeof( triObj.pFaces[0] ) * triObj.numFaces ); - fread( triObj.pFaces, sizeof( triObj.pFaces[0] ), triObj.numFaces, fp ); - bytesRead += sizeof( triObj.numFaces ) + triObj.numFaces * sizeof( triObj.pFaces[0] ) + 6; - - if ( s_verbose ) { - printf( " found face array with %d faces\n", triObj.numFaces ); - for ( i = 0; i < triObj.numFaces; i++ ) - { - printf( " %d: %d,%d,%d\n", i, triObj.pFaces[i].a, triObj.pFaces[i].b, triObj.pFaces[i].c ); - } - } - - break; - case _3DS_CHUNK_POINT_ARRAY: - fread( &triObj.numPoints, sizeof( triObj.numPoints ), 1, fp ); - triObj.pPoints = safe_malloc( sizeof( triObj.pPoints[0] ) * triObj.numPoints ); - fread( triObj.pPoints, sizeof( triObj.pPoints[0] ), triObj.numPoints, fp ); - bytesRead += sizeof( triObj.numPoints ) + triObj.numPoints * sizeof( triObj.pPoints[0] ) + 6; - - // flip points around into our coordinate system - for ( i = 0; i < triObj.numPoints; i++ ) - { - float x, y, z; - - x = triObj.pPoints[i].x; - y = triObj.pPoints[i].y; - z = triObj.pPoints[i].z; - - triObj.pPoints[i].x = -y; - triObj.pPoints[i].y = x; - triObj.pPoints[i].z = z; - } - - if ( s_verbose ) { - printf( " found point array with %d points\n", triObj.numPoints ); - for ( i = 0; i < triObj.numPoints; i++ ) - { - printf( " %d: %f,%f,%f\n", i, triObj.pPoints[i].x, triObj.pPoints[i].y, triObj.pPoints[i].z ); - } - } - break; - case _3DS_CHUNK_TEX_VERTS: - fread( &triObj.numTexVerts, sizeof( triObj.numTexVerts ), 1, fp ); - triObj.pTexVerts = safe_malloc( sizeof( triObj.pTexVerts[0] ) * triObj.numTexVerts ); - fread( triObj.pTexVerts, sizeof( triObj.pTexVerts[0] ), triObj.numTexVerts, fp ); - bytesRead += sizeof( triObj.numTexVerts ) + sizeof( triObj.pTexVerts[0] ) * triObj.numTexVerts + 6; - - if ( s_verbose ) { - printf( " found tex vert array with %d tex verts\n", triObj.numTexVerts ); - for ( i = 0; i < triObj.numTexVerts; i++ ) - { - printf( " %d: %f,%f\n", i, triObj.pTexVerts[i].s, triObj.pTexVerts[i].t ); - } - } - break; - default: - fread( s_buffer, chunkLen - 6, 1, fp ); - bytesRead += chunkLen; - break; - } - - if ( bytesRead >= thisChunkLen ) { - break; - } - } - *pTO = triObj; - - if ( numMeshMaterialGroups == 0 ) { - numMeshMaterialGroups = 1; - strcpy( meshMaterialGroups[0].name, "(null)" ); - if ( pTO->numTexVerts ) { - printf( "Warning: assigning (null) skin to tri object\n" ); - } - } - else - { - assert( pTO->numFaces == meshMaterialGroups[0].numFaces ); - } - - pTO->pMeshMaterialGroups = safe_malloc( sizeof( _3DSMeshMaterialGroup_t ) * numMeshMaterialGroups ); - memcpy( pTO->pMeshMaterialGroups, meshMaterialGroups, numMeshMaterialGroups * sizeof( meshMaterialGroups[0] ) ); - pTO->numMeshMaterialGroups = numMeshMaterialGroups; - - // - // sanity checks - // - assert( numMeshMaterialGroups <= 1 ); -} - -static void LoadNamedObject( FILE *fp, long thisChunkLen, _3DSNamedObject_t *pNO ){ - long chunkLen; - unsigned short chunkID; - long bytesRead = 0; - char name[100]; - _3DSTriObject_t triObj[MAX_TRI_OBJECTS]; - int numTriObjects = 0; - - memset( triObj, 0, sizeof( triObj ) ); - - bytesRead += ReadString( fp, name ); - - if ( s_verbose ) { - printf( " >>> NAMED OBJECT '%s'\n", name ); - } - - while ( ReadChunkAndLength( fp, &chunkID, &chunkLen ) ) - { - switch ( chunkID ) - { - case _3DS_CHUNK_NAMED_TRI_OBJECT: - LoadNamedTriObject( fp, chunkLen - 6, &triObj[numTriObjects] ); - numTriObjects++; - break; - default: - fread( s_buffer, chunkLen - 6, 1, fp ); - break; - } - - bytesRead += chunkLen; - - if ( bytesRead >= thisChunkLen ) { - break; - } - } - - strcpy( pNO->name, name ); - pNO->pTriObjects = safe_malloc( sizeof( _3DSTriObject_t ) * numTriObjects ); - memcpy( pNO->pTriObjects, triObj, sizeof( triObj[0] ) * numTriObjects ); - pNO->numTriObjects = numTriObjects; - - assert( numTriObjects <= 1 ); -} - -static void LoadEditChunk( FILE *fp, long thisChunkLen, _3DSEditChunk_t *pEC ){ - unsigned short chunkID; - long chunkLen; - long bytesRead = 0; - _3DSEditChunk_t editChunk; - - _3DSMaterial_t mat[MAX_MATERIALS]; - _3DSNamedObject_t namedObjects[MAX_NAMED_OBJECTS]; - - int numMaterials = 0, numNamedObjects = 0; - - memset( &editChunk, 0, sizeof( editChunk ) ); - - if ( s_verbose ) { - printf( ">>> EDIT CHUNK\n" ); - } - - while ( ReadChunkAndLength( fp, &chunkID, &chunkLen ) ) - { - switch ( chunkID ) - { - case _3DS_CHUNK_MAT_LIST: - LoadMaterialList( fp, chunkLen - 6, &mat[numMaterials] ); - numMaterials++; - break; - case _3DS_CHUNK_NAMED_OBJECT: - LoadNamedObject( fp, chunkLen - 6, &namedObjects[numNamedObjects] ); - if ( namedObjects[numNamedObjects].numTriObjects != 0 ) { - ++numNamedObjects; - } - break; - case _3DS_CHUNK_MESH_VERSION: - default: - fread( s_buffer, chunkLen - 6, 1, fp ); - break; - } - - bytesRead += chunkLen; - - if ( bytesRead >= thisChunkLen ) { - break; - } - } - - if ( numMaterials == 0 ) { - numMaterials = 1; - strcpy( mat[0].name, "(null)" ); - printf( "Warning: no material definitions found\n" ); - } - - pEC->numNamedObjects = numNamedObjects; - - pEC->pMaterials = safe_malloc( sizeof( _3DSMaterial_t ) * numMaterials ); - pEC->pNamedObjects = safe_malloc( sizeof( _3DSNamedObject_t ) * numNamedObjects ); - - memcpy( pEC->pMaterials, mat, numMaterials * sizeof( mat[0] ) ); - memcpy( pEC->pNamedObjects, namedObjects, numNamedObjects * sizeof( namedObjects[0] ) ); -} - -static void Load3DS( const char *filename, _3DS_t *p3DS, bool verbose ){ - FILE *fp; - unsigned short chunkID; - long chunkLen; - _3DSEditChunk_t editChunk; - - s_verbose = verbose; - - if ( ( fp = fopen( filename, "rb" ) ) == 0 ) { - Error( "Unable to open '%s'", filename ); - } - - // read magic number - if ( ( fread( &chunkID, sizeof( short ), 1, fp ) != 1 ) || - ( LittleShort( chunkID ) != _3DS_CHUNK_MAGIC ) ) { - Error( "Missing or incorrect magic number in '%s'", filename ); - } - if ( fread( &chunkLen, sizeof( chunkLen ), 1, fp ) != 1 ) { - Error( "Unexpected EOF encountered in '%s'", filename ); - } - // version number - if ( !ReadChunkAndLength( fp, &chunkID, &chunkLen ) ) { - Error( "Missing version number in '%s'", filename ); - } - if ( fread( s_buffer, chunkLen - 6, 1, fp ) != 1 ) { - Error( "Unexpected EOF encountered in '%s'", filename ); - } - - while ( ReadChunkAndLength( fp, &chunkID, &chunkLen ) ) - { - switch ( chunkID ) - { - case _3DS_CHUNK_EDIT: - LoadEditChunk( fp, chunkLen - 6, &editChunk ); - break; - case _3DS_CHUNK_KEYFRAME_DATA: - fread( s_buffer, chunkLen - 6, 1, fp ); - break; - default: - fread( s_buffer, chunkLen - 6, 1, fp ); - break; - } - } - - fclose( fp ); - - p3DS->editChunk = editChunk; -} - -static void ComputeNormals( _3DSTriObject_t *pTO, triangle_t *pTris ){ - vec3_t faceNormals[POLYSET_MAXTRIANGLES]; - vec3_t vertexNormals[POLYSET_MAXTRIANGLES * 3]; - vec3_t side0, side1, facenormal; - int f, v; - - memset( faceNormals, 0, sizeof( faceNormals ) ); - memset( vertexNormals, 0, sizeof( vertexNormals ) ); - - // - // compute face normals - // - for ( f = 0; f < pTO->numFaces; f++ ) - { - VectorSubtract( pTris[f].verts[0], pTris[f].verts[1], side0 ); - VectorSubtract( pTris[f].verts[2], pTris[f].verts[1], side1 ); - - CrossProduct( side0, side1, facenormal ); - VectorNormalize( facenormal, faceNormals[f] ); - } - - // - // sum vertex normals - // - for ( v = 0; v < pTO->numPoints; v++ ) - { - for ( f = 0; f < pTO->numFaces; f++ ) - { - if ( ( pTO->pFaces[f].a == v ) || - ( pTO->pFaces[f].b == v ) || - ( pTO->pFaces[f].c == v ) ) { - vertexNormals[v][0] += faceNormals[f][0]; - vertexNormals[v][1] += faceNormals[f][1]; - vertexNormals[v][2] += faceNormals[f][2]; - } - } - - VectorNormalize( vertexNormals[v], vertexNormals[v] ); - } - - // - // copy vertex normals into triangles - // - for ( f = 0; f < pTO->numFaces; f++ ) - { - int i0 = pTO->pFaces[f].c; - int i1 = pTO->pFaces[f].b; - int i2 = pTO->pFaces[f].a; - - VectorCopy( vertexNormals[i0], pTris[f].normals[0] ); - VectorCopy( vertexNormals[i1], pTris[f].normals[1] ); - VectorCopy( vertexNormals[i2], pTris[f].normals[2] ); - } -} - -/* -** void _3DS_LoadPolysets -*/ -void _3DS_LoadPolysets( const char *filename, polyset_t **ppPSET, int *numpsets, bool verbose ){ - _3DS_t _3ds; - int numPolysets; - polyset_t *pPSET; - triangle_t *ptri, *triangles; - int i; - - // load the 3DS - memset( &_3ds, 0, sizeof( _3ds ) ); - Load3DS( filename, &_3ds, verbose ); - - // compute information - numPolysets = _3ds.editChunk.numNamedObjects; - - // allocate memory - pPSET = safe_calloc( numPolysets * sizeof( polyset_t ) ); - triangles = ptri = safe_calloc( POLYSET_MAXTRIANGLES * sizeof( triangle_t ) ); - - // copy the data over - for ( i = 0; i < numPolysets; i++ ) - { - char matnamebuf[1024]; - int j; - triangle_t *tri; - _3DSTriObject_t *pTO = &_3ds.editChunk.pNamedObjects[i].pTriObjects[0]; - - pPSET[i].triangles = ptri; - pPSET[i].numtriangles = pTO->numFaces; - strcpy( pPSET[i].name, _3ds.editChunk.pNamedObjects[i].name ); - - strcpy( matnamebuf, filename ); - StripFilename( matnamebuf ); - strcat( matnamebuf, pTO->pMeshMaterialGroups[0].name ); - - if ( strstr( matnamebuf, gamedir ) ) { - strcpy( pPSET[i].materialname, strstr( matnamebuf, gamedir ) + strlen( gamedir ) ); - } - else{ - strcpy( pPSET[i].materialname, pTO->pMeshMaterialGroups[0].name ); - } - - assert( pPSET[i].numtriangles < POLYSET_MAXTRIANGLES ); - - for ( tri = ptri, j = 0; j < pPSET[i].numtriangles; j++ ) - { - int i0 = pTO->pFaces[j].c; - int i1 = pTO->pFaces[j].b; - int i2 = pTO->pFaces[j].a; - - tri->verts[0][0] = pTO->pPoints[i0].x; - tri->verts[0][1] = pTO->pPoints[i0].y; - tri->verts[0][2] = pTO->pPoints[i0].z; - - tri->verts[1][0] = pTO->pPoints[i1].x; - tri->verts[1][1] = pTO->pPoints[i1].y; - tri->verts[1][2] = pTO->pPoints[i1].z; - - tri->verts[2][0] = pTO->pPoints[i2].x; - tri->verts[2][1] = pTO->pPoints[i2].y; - tri->verts[2][2] = pTO->pPoints[i2].z; -/* - for ( k = 0; k < 3; k++ ) - { - tri->colors[0][k] = 1; - tri->colors[1][k] = 1; - tri->colors[2][k] = 1; - } - */ - - if ( pTO->pTexVerts ) { - tri->texcoords[0][0] = pTO->pTexVerts[i0].s; - tri->texcoords[0][1] = 1.0f - pTO->pTexVerts[i0].t; - tri->texcoords[1][0] = pTO->pTexVerts[i1].s; - tri->texcoords[1][1] = 1.0f - pTO->pTexVerts[i1].t; - tri->texcoords[2][0] = pTO->pTexVerts[i2].s; - tri->texcoords[2][1] = 1.0f - pTO->pTexVerts[i2].t; - } - - tri++; - } - - ptri += pPSET[i].numtriangles; - assert( ptri - triangles < POLYSET_MAXTRIANGLES ); - } - - // compute normal data -#if 0 - for ( i = 0; i < numPolysets; i++ ) - { - // unique vertices based solely on vertex position - ComputeNormals( &_3ds.editChunk.pNamedObjects[i].pTriObjects[0], - pPSET[i].triangles ); - } -#endif - - free( _3ds.editChunk.pMaterials ); - free( _3ds.editChunk.pNamedObjects ); - - *ppPSET = pPSET; - *numpsets = numPolysets; -} diff --git a/tools/quake3/q3data/3dslib.h b/tools/quake3/q3data/3dslib.h deleted file mode 100644 index 5ea8a212..00000000 --- a/tools/quake3/q3data/3dslib.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -typedef struct -{ - float x, y, z; -} _3DSPoint_t; - -typedef struct -{ - short a, b, c; - short flags; -} _3DSFace_t; - -typedef struct -{ - float s, t; -} _3DSTexVert_t; - -typedef struct -{ - char name[100]; - short numFaces; - short *pFaces; -} _3DSMeshMaterialGroup_t; - -typedef struct -{ - char name[80]; - - char texture[100]; - char specular[100]; - char reflection[100]; - char bump[100]; - char opacity[100]; -} _3DSMaterial_t; - -typedef struct -{ - short numFaces, numPoints, numTexVerts; - int numMeshMaterialGroups; - - _3DSPoint_t *pPoints; - _3DSFace_t *pFaces; - _3DSTexVert_t *pTexVerts; - - _3DSMeshMaterialGroup_t *pMeshMaterialGroups; -} _3DSTriObject_t; - -typedef struct -{ - char name[100]; - - int numTriObjects; - _3DSTriObject_t *pTriObjects; -} _3DSNamedObject_t; - -typedef struct -{ - int numNamedObjects; - int numMaterials; - - _3DSNamedObject_t *pNamedObjects; - _3DSMaterial_t *pMaterials; - -} _3DSEditChunk_t; - -typedef struct -{ - _3DSEditChunk_t editChunk; -} _3DS_t; - -#define _3DS_CHUNK_NULL 0x0000 -#define _3DS_CHUNK_UNKNOWN0 0x0001 -#define _3DS_CHUNK_M3D_VERSION 0x0002 -#define _3DS_CHUNK_M3D_KFVERSION 0x0005 -#define _3DS_CHUNK_COLOR_F 0x0010 -#define _3DS_CHUNK_COLOR_24 0x0011 -#define _3DS_CHUNK_LIN_COLOR_24 0x0012 -#define _3DS_CHUNK_LIN_COLOR_F 0x0013 -#define _3DS_CHUNK_INT_PERCENTAGE 0x0030 -#define _3DS_CHUNK_FLOAT_PERCENT 0x0031 -#define _3DS_CHUNK_MASTER_SCALE 0x0100 -#define _3DS_CHUNK_CHUNK_TYPE 0x0995 -#define _3DS_CHUNK_CHUNK_UNIQUE 0x0996 -#define _3DS_CHUNK_NOT_CHUNK 0x0997 -#define _3DS_CHUNK_CONTAINER 0x0998 -#define _3DS_CHUNK_IS_CHUNK 0x0999 -#define _3DS_CHUNK_C_SXP_SELFI_MASKDATA 0x0c3c - -#define _3DS_CHUNK_BITMAP 0x1100 -#define _3DS_CHUNK_USE_BITMAP 0x1101 -#define _3DS_CHUNK_SOLID_BGND 0x1200 -#define _3DS_CHUNK_USE_SOLID_BGND 0x1201 - -#define _3DS_CHUNK_EDIT 0x3d3d -#define _3DS_CHUNK_MESH_VERSION 0x3d3e - -#define _3DS_CHUNK_NAMED_OBJECT 0x4000 -#define _3DS_CHUNK_NAMED_TRI_OBJECT 0x4100 -#define _3DS_CHUNK_POINT_ARRAY 0x4110 -#define _3DS_CHUNK_POINT_FLAG_ARRAY 0x4111 -#define _3DS_CHUNK_FACE_ARRAY 0x4120 -#define _3DS_CHUNK_MSH_MAT_GROUP 0x4130 -#define _3DS_CHUNK_TEX_VERTS 0x4140 -#define _3DS_CHUNK_SMOOTH_GROUP 0x4150 -#define _3DS_CHUNK_MESH_MATRIX 0x4160 -#define _3DS_CHUNK_MAGIC 0x4d4d - -#define _3DS_CHUNK_MAT_NAME 0xa000 -#define _3DS_CHUNK_TEXMAP 0xa200 -#define _3DS_CHUNK_SPECMAP 0xa204 -#define _3DS_CHUNK_OPACMAP 0xa210 -#define _3DS_CHUNK_REFLMAP 0xa220 -#define _3DS_CHUNK_BUMPMAP 0xa230 -#define _3DS_CHUNK_MAT_MAPNAME 0xa300 -#define _3DS_CHUNK_MAT_LIST 0xafff - -#define _3DS_CHUNK_KEYFRAME_DATA 0xb000 - -void _3DS_LoadPolysets( const char *filename, polyset_t **ppPSET, int *numpsets, bool verbose ); diff --git a/tools/quake3/q3data/compress.cpp b/tools/quake3/q3data/compress.cpp deleted file mode 100644 index ca8607c8..00000000 --- a/tools/quake3/q3data/compress.cpp +++ /dev/null @@ -1,787 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "q3data.h" - -#if 0 -/* - ================== - MTF - ================== - */ -cblock_t MTF( cblock_t in ){ - int i, j, b, code; - byte *out_p; - int index[256]; - cblock_t out; - - out_p = out.data = malloc( in.count + 4 ); - - // write count - *out_p++ = in.count & 255; - *out_p++ = ( in.count >> 8 ) & 255; - *out_p++ = ( in.count >> 16 ) & 255; - *out_p++ = ( in.count >> 24 ) & 255; - - for ( i = 0 ; i < 256 ; i++ ) - index[i] = i; - - for ( i = 0 ; i < in.count ; i++ ) - { - b = in.data[i]; - code = index[b]; - *out_p++ = code; - - // shuffle b indexes to 0 - for ( j = 0 ; j < 256 ; j++ ) - if ( index[j] < code ) { - index[j]++; - } - index[b] = 0; - } - - out.count = out_p - out.data; - - return out; -} - - -//========================================================================== - -int bwt_size; -byte *bwt_data; - -int bwtCompare( const void *elem1, const void *elem2 ){ - int i; - int i1, i2; - int b1, b2; - - i1 = *(int *)elem1; - i2 = *(int *)elem2; - - for ( i = 0 ; i < bwt_size ; i++ ) - { - b1 = bwt_data[i1]; - b2 = bwt_data[i2]; - if ( b1 < b2 ) { - return -1; - } - if ( b1 > b2 ) { - return 1; - } - if ( ++i1 == bwt_size ) { - i1 = 0; - } - if ( ++i2 == bwt_size ) { - i2 = 0; - } - } - - return 0; -} - -/* - ================== - BWT - ================== - */ -cblock_t BWT( cblock_t in ){ - int *sorted; - int i; - byte *out_p; - cblock_t out; - - bwt_size = in.count; - bwt_data = in.data; - - sorted = malloc( in.count * sizeof( *sorted ) ); - for ( i = 0 ; i < in.count ; i++ ) - sorted[i] = i; - qsort( sorted, in.count, sizeof( *sorted ), bwtCompare ); - - out_p = out.data = malloc( in.count + 8 ); - - // write count - *out_p++ = in.count & 255; - *out_p++ = ( in.count >> 8 ) & 255; - *out_p++ = ( in.count >> 16 ) & 255; - *out_p++ = ( in.count >> 24 ) & 255; - - // write head index - for ( i = 0 ; i < in.count ; i++ ) - if ( sorted[i] == 0 ) { - break; - } - *out_p++ = i & 255; - *out_p++ = ( i >> 8 ) & 255; - *out_p++ = ( i >> 16 ) & 255; - *out_p++ = ( i >> 24 ) & 255; - - // write the L column - for ( i = 0 ; i < in.count ; i++ ) - *out_p++ = in.data[( sorted[i] + in.count - 1 ) % in.count]; - - free( sorted ); - - out.count = out_p - out.data; - - return out; -} - -//========================================================================== - -typedef struct hnode_s -{ - int count; - bool used; - int children[2]; -} hnode_t; - -int numhnodes; -hnode_t hnodes[512]; -unsigned charbits[256]; -int charbitscount[256]; - -int SmallestNode( void ){ - int i; - int best, bestnode; - - best = 99999999; - bestnode = -1; - for ( i = 0 ; i < numhnodes ; i++ ) - { - if ( hnodes[i].used ) { - continue; - } - if ( !hnodes[i].count ) { - continue; - } - if ( hnodes[i].count < best ) { - best = hnodes[i].count; - bestnode = i; - } - } - - if ( bestnode == -1 ) { - return -1; - } - - hnodes[bestnode].used = true; - return bestnode; -} - -void BuildChars( int nodenum, unsigned bits, int bitcount ){ - hnode_t *node; - - if ( nodenum < 256 ) { - if ( bitcount > 32 ) { - Error( "bitcount > 32" ); - } - charbits[nodenum] = bits; - charbitscount[nodenum] = bitcount; - return; - } - - node = &hnodes[nodenum]; - bits <<= 1; - BuildChars( node->children[0], bits, bitcount + 1 ); - bits |= 1; - BuildChars( node->children[1], bits, bitcount + 1 ); -} - -/* - ================== - Huffman - ================== - */ -cblock_t Huffman( cblock_t in ){ - int i; - hnode_t *node; - int outbits, c; - unsigned bits; - byte *out_p; - cblock_t out; - int max, maxchar; - - // count - memset( hnodes, 0, sizeof( hnodes ) ); - for ( i = 0 ; i < in.count ; i++ ) - hnodes[in.data[i]].count++; - - // normalize counts - max = 0; - maxchar = 0; - for ( i = 0 ; i < 256 ; i++ ) - { - if ( hnodes[i].count > max ) { - max = hnodes[i].count; - maxchar = i; - } - } - if ( max == 0 ) { - Error( "Huffman: max == 0" ); - } - - for ( i = 0 ; i < 256 ; i++ ) - { - hnodes[i].count = ( hnodes[i].count * 255 + max - 1 ) / max; - } - - // build the nodes - numhnodes = 256; - while ( numhnodes != 511 ) - { - node = &hnodes[numhnodes]; - - // pick two lowest counts - node->children[0] = SmallestNode(); - if ( node->children[0] == -1 ) { - break; // no more - - } - node->children[1] = SmallestNode(); - if ( node->children[1] == -1 ) { - if ( node->children[0] != numhnodes - 1 ) { - Error( "Bad smallestnode" ); - } - break; - } - node->count = hnodes[node->children[0]].count + - hnodes[node->children[1]].count; - numhnodes++; - } - - BuildChars( numhnodes - 1, 0, 0 ); - - out_p = out.data = malloc( in.count * 2 + 1024 ); - memset( out_p, 0, in.count * 2 + 1024 ); - - // write count - *out_p++ = in.count & 255; - *out_p++ = ( in.count >> 8 ) & 255; - *out_p++ = ( in.count >> 16 ) & 255; - *out_p++ = ( in.count >> 24 ) & 255; - - // save out the 256 normalized counts so the tree can be recreated - for ( i = 0 ; i < 256 ; i++ ) - *out_p++ = hnodes[i].count; - - // write bits - outbits = 0; - for ( i = 0 ; i < in.count ; i++ ) - { - c = charbitscount[in.data[i]]; - bits = charbits[in.data[i]]; - while ( c ) - { - c--; - if ( bits & ( 1 << c ) ) { - out_p[outbits >> 3] |= 1 << ( outbits & 7 ); - } - outbits++; - } - } - - out_p += ( outbits + 7 ) >> 3; - - out.count = out_p - out.data; - - return out; -} - -//========================================================================== - -/* - ================== - RLE - ================== - */ -#define RLE_CODE 0xe8 -#define RLE_TRIPPLE 0xe9 - -int rle_counts[256]; -int rle_bytes[256]; - -cblock_t RLE( cblock_t in ){ - int i; - byte *out_p; - int val; - int repeat; - cblock_t out; - - out_p = out.data = malloc( in.count * 2 ); - - // write count - *out_p++ = in.count & 255; - *out_p++ = ( in.count >> 8 ) & 255; - *out_p++ = ( in.count >> 16 ) & 255; - *out_p++ = ( in.count >> 24 ) & 255; - - for ( i = 0 ; i < in.count ; ) - { - val = in.data[i]; - rle_bytes[val]++; - repeat = 1; - i++; - while ( i < in.count && repeat < 255 && in.data[i] == val ) - { - repeat++; - i++; - } - if ( repeat < 256 ) { - rle_counts[repeat]++; - } - if ( repeat > 3 || val == RLE_CODE ) { - *out_p++ = RLE_CODE; - *out_p++ = val; - *out_p++ = repeat; - } - else - { - while ( repeat-- ) - *out_p++ = val; - } - } - - out.count = out_p - out.data; - return out; -} - -//========================================================================== - -unsigned lzss_head[256]; -unsigned lzss_next[0x20000]; - -/* - ================== - LZSS - ================== - */ -#define BACK_WINDOW 0x10000 -#define BACK_BITS 16 -#define FRONT_WINDOW 16 -#define FRONT_BITS 4 -cblock_t LZSS( cblock_t in ){ - int i; - byte *out_p; - cblock_t out; - int val; - int j, start, max; - int bestlength, beststart; - int outbits; - - if ( in.count >= sizeof( lzss_next ) / 4 ) { - Error( "LZSS: too big" ); - } - - memset( lzss_head, -1, sizeof( lzss_head ) ); - - out_p = out.data = malloc( in.count * 2 ); - memset( out.data, 0, in.count * 2 ); - - // write count - *out_p++ = in.count & 255; - *out_p++ = ( in.count >> 8 ) & 255; - *out_p++ = ( in.count >> 16 ) & 255; - *out_p++ = ( in.count >> 24 ) & 255; - - outbits = 0; - for ( i = 0 ; i < in.count ; ) - { - val = in.data[i]; -#if 1 -// chained search - bestlength = 0; - beststart = 0; - - max = FRONT_WINDOW; - if ( i + max > in.count ) { - max = in.count - i; - } - - start = lzss_head[val]; - while ( start != -1 && start >= i - BACK_WINDOW ) - { - // count match length - for ( j = 0 ; j < max ; j++ ) - if ( in.data[start + j] != in.data[i + j] ) { - break; - } - if ( j > bestlength ) { - bestlength = j; - beststart = start; - } - start = lzss_next[start]; - } - -#else -// slow simple search - // search for a match - max = FRONT_WINDOW; - if ( i + max > in.count ) { - max = in.count - i; - } - - start = i - BACK_WINDOW; - if ( start < 0 ) { - start = 0; - } - bestlength = 0; - beststart = 0; - for ( ; start < i ; start++ ) - { - if ( in.data[start] != val ) { - continue; - } - // count match length - for ( j = 0 ; j < max ; j++ ) - if ( in.data[start + j] != in.data[i + j] ) { - break; - } - if ( j > bestlength ) { - bestlength = j; - beststart = start; - } - } -#endif - beststart = BACK_WINDOW - ( i - beststart ); - - if ( bestlength < 3 ) { // output a single char - bestlength = 1; - - out_p[outbits >> 3] |= 1 << ( outbits & 7 ); // set bit to mark char - outbits++; - for ( j = 0 ; j < 8 ; j++, outbits++ ) - if ( val & ( 1 << j ) ) { - out_p[outbits >> 3] |= 1 << ( outbits & 7 ); - } - } - else - { // output a phrase - outbits++; // leave a 0 bit to mark phrase - for ( j = 0 ; j < BACK_BITS ; j++, outbits++ ) - if ( beststart & ( 1 << j ) ) { - out_p[outbits >> 3] |= 1 << ( outbits & 7 ); - } - for ( j = 0 ; j < FRONT_BITS ; j++, outbits++ ) - if ( bestlength & ( 1 << j ) ) { - out_p[outbits >> 3] |= 1 << ( outbits & 7 ); - } - } - - while ( bestlength-- ) - { - val = in.data[i]; - lzss_next[i] = lzss_head[val]; - lzss_head[val] = i; - i++; - } - } - - out_p += ( outbits + 7 ) >> 3; - out.count = out_p - out.data; - return out; -} - -//========================================================================== - -#define MIN_REPT 15 -#define MAX_REPT 0 -#define HUF_TOKENS ( 256 + MAX_REPT ) - -unsigned charbits1[256][HUF_TOKENS]; -int charbitscount1[256][HUF_TOKENS]; - -hnode_t hnodes1[256][HUF_TOKENS * 2]; -int numhnodes1[256]; - -int order0counts[256]; - -/* - ================== - SmallestNode1 - ================== - */ -int SmallestNode1( hnode_t *hnodes, int numhnodes ){ - int i; - int best, bestnode; - - best = 99999999; - bestnode = -1; - for ( i = 0 ; i < numhnodes ; i++ ) - { - if ( hnodes[i].used ) { - continue; - } - if ( !hnodes[i].count ) { - continue; - } - if ( hnodes[i].count < best ) { - best = hnodes[i].count; - bestnode = i; - } - } - - if ( bestnode == -1 ) { - return -1; - } - - hnodes[bestnode].used = true; - return bestnode; -} - - -/* - ================== - BuildChars1 - ================== - */ -void BuildChars1( int prev, int nodenum, unsigned bits, int bitcount ){ - hnode_t *node; - - if ( nodenum < HUF_TOKENS ) { - if ( bitcount > 32 ) { - Error( "bitcount > 32" ); - } - charbits1[prev][nodenum] = bits; - charbitscount1[prev][nodenum] = bitcount; - return; - } - - node = &hnodes1[prev][nodenum]; - bits <<= 1; - BuildChars1( prev, node->children[0], bits, bitcount + 1 ); - bits |= 1; - BuildChars1( prev, node->children[1], bits, bitcount + 1 ); -} - - -/* - ================== - BuildTree1 - ================== - */ -void BuildTree1( int prev ){ - hnode_t *node, *nodebase; - int numhnodes; - - // build the nodes - numhnodes = HUF_TOKENS; - nodebase = hnodes1[prev]; - while ( 1 ) - { - node = &nodebase[numhnodes]; - - // pick two lowest counts - node->children[0] = SmallestNode1( nodebase, numhnodes ); - if ( node->children[0] == -1 ) { - break; // no more - - } - node->children[1] = SmallestNode1( nodebase, numhnodes ); - if ( node->children[1] == -1 ) { - break; - } - - node->count = nodebase[node->children[0]].count + - nodebase[node->children[1]].count; - numhnodes++; - } - numhnodes1[prev] = numhnodes - 1; - BuildChars1( prev, numhnodes - 1, 0, 0 ); -} - - -/* - ================== - Huffman1_Count - ================== - */ -void Huffman1_Count( cblock_t in ){ - int i; - int prev; - int v; - int rept; - - prev = 0; - for ( i = 0 ; i < in.count ; i++ ) - { - v = in.data[i]; - order0counts[v]++; - hnodes1[prev][v].count++; - prev = v; -#if 1 - for ( rept = 1 ; i + rept < in.count && rept < MAX_REPT ; rept++ ) - if ( in.data[i + rept] != v ) { - break; - } - if ( rept > MIN_REPT ) { - hnodes1[prev][255 + rept].count++; - i += rept - 1; - } -#endif - } -} - - -/* - ================== - Huffman1_Build - ================== - */ -byte scaled[256][HUF_TOKENS]; -void Huffman1_Build( FILE *f ){ - int i, j, v; - int max; - int total; - - for ( i = 0 ; i < 256 ; i++ ) - { - // normalize and save the counts - max = 0; - for ( j = 0 ; j < HUF_TOKENS ; j++ ) - { - if ( hnodes1[i][j].count > max ) { - max = hnodes1[i][j].count; - } - } - if ( max == 0 ) { - max = 1; - } - total = 0; - for ( j = 0 ; j < HUF_TOKENS ; j++ ) - { // easy to overflow 32 bits here! - v = ( hnodes1[i][j].count * (double)255 + max - 1 ) / max; - if ( v > 255 ) { - Error( "v > 255" ); - } - scaled[i][j] = hnodes1[i][j].count = v; - if ( v ) { - total++; - } - } - if ( total == 1 ) { // must have two tokens - if ( !scaled[i][0] ) { - scaled[i][0] = hnodes1[i][0].count = 1; - } - else{ - scaled[i][1] = hnodes1[i][1].count = 1; - } - } - - BuildTree1( i ); - } - -#if 0 - // count up the total bits - total = 0; - for ( i = 0 ; i < 256 ; i++ ) - for ( j = 0 ; j < 256 ; j++ ) - total += charbitscount1[i][j] * hnodes1[i][j].count; - - total = ( total + 7 ) / 8; - printf( "%i bytes huffman1 compressed\n", total ); -#endif - - fwrite( scaled, 1, sizeof( scaled ), f ); -} - -/* - ================== - Huffman1 - - Order 1 compression with pre-built table - ================== - */ -cblock_t Huffman1( cblock_t in ){ - int i; - int outbits, c; - unsigned bits; - byte *out_p; - cblock_t out; - int prev; - int v; - int rept; - - out_p = out.data = malloc( in.count * 2 + 1024 ); - memset( out_p, 0, in.count * 2 + 1024 ); - - // write count - *out_p++ = in.count & 255; - *out_p++ = ( in.count >> 8 ) & 255; - *out_p++ = ( in.count >> 16 ) & 255; - *out_p++ = ( in.count >> 24 ) & 255; - - // write bits - outbits = 0; - prev = 0; - for ( i = 0 ; i < in.count ; i++ ) - { - v = in.data[i]; - - c = charbitscount1[prev][v]; - bits = charbits1[prev][v]; - if ( !c ) { - Error( "!bits" ); - } - while ( c ) - { - c--; - if ( bits & ( 1 << c ) ) { - out_p[outbits >> 3] |= 1 << ( outbits & 7 ); - } - outbits++; - } - - prev = v; -#if 1 - // check for repeat encodes - for ( rept = 1 ; i + rept < in.count && rept < MAX_REPT ; rept++ ) - if ( in.data[i + rept] != v ) { - break; - } - if ( rept > MIN_REPT ) { - c = charbitscount1[prev][255 + rept]; - bits = charbits1[prev][255 + rept]; - if ( !c ) { - Error( "!bits" ); - } - while ( c ) - { - c--; - if ( bits & ( 1 << c ) ) { - out_p[outbits >> 3] |= 1 << ( outbits & 7 ); - } - outbits++; - } - i += rept - 1; - } -#endif - } - - out_p += ( outbits + 7 ) >> 3; - - out.count = out_p - out.data; - - return out; -} - -#endif diff --git a/tools/quake3/q3data/images.cpp b/tools/quake3/q3data/images.cpp deleted file mode 100644 index 23cfbe9f..00000000 --- a/tools/quake3/q3data/images.cpp +++ /dev/null @@ -1,487 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "q3data.h" - -byte *byteimage, *lbmpalette; -int byteimagewidth, byteimageheight; - - -char mip_prefix[1024]; // directory to dump the textures in - -bool colormap_issued; -byte colormap_palette[768]; - -/* - ============== - Cmd_Grab - - $grab filename x y width height - ============== - */ -void Cmd_Grab( void ){ - int xl,yl,w,h,y; - byte *cropped; - char savename[1024]; - char dest[1024]; - - GetToken( false ); - - if ( path_separator( token[0] ) ) { - sprintf( savename, "%s%s.pcx", writedir, token + 1 ); - } - else{ - sprintf( savename, "%spics/%s.pcx", writedir, token ); - } - - if ( g_release ) { - if ( path_separator( token[0] ) ) { - sprintf( dest, "%s.pcx", token + 1 ); - } - else{ - sprintf( dest, "pics/%s.pcx", token ); - } - - ReleaseFile( dest ); - return; - } - - GetToken( false ); - xl = atoi( token ); - GetToken( false ); - yl = atoi( token ); - GetToken( false ); - w = atoi( token ); - GetToken( false ); - h = atoi( token ); - - if ( xl < 0 || yl < 0 || w < 0 || h < 0 || xl + w > byteimagewidth || yl + h > byteimageheight ) { - Error( "GrabPic: Bad size: %i, %i, %i, %i",xl,yl,w,h ); - } - - // crop it to the proper size - cropped = safe_malloc( w * h ); - for ( y = 0 ; y < h ; y++ ) - { - memcpy( cropped + y * w, byteimage + ( y + yl ) * byteimagewidth + xl, w ); - } - - // save off the new image - printf( "saving %s\n", savename ); - CreatePath( savename ); - WritePCXfile( savename, cropped, w, h, lbmpalette ); - - free( cropped ); -} - -/* - ============== - Cmd_Raw - - $grab filename x y width height - ============== - */ -void Cmd_Raw( void ){ - int xl,yl,w,h,y; - byte *cropped; - char savename[1024]; - char dest[1024]; - - GetToken( false ); - - sprintf( savename, "%s%s.lmp", writedir, token ); - - if ( g_release ) { - sprintf( dest, "%s.lmp", token ); - ReleaseFile( dest ); - return; - } - - GetToken( false ); - xl = atoi( token ); - GetToken( false ); - yl = atoi( token ); - GetToken( false ); - w = atoi( token ); - GetToken( false ); - h = atoi( token ); - - if ( xl < 0 || yl < 0 || w < 0 || h < 0 || xl + w > byteimagewidth || yl + h > byteimageheight ) { - Error( "GrabPic: Bad size: %i, %i, %i, %i",xl,yl,w,h ); - } - - // crop it to the proper size - cropped = safe_malloc( w * h ); - for ( y = 0 ; y < h ; y++ ) - { - memcpy( cropped + y * w, byteimage + ( y + yl ) * byteimagewidth + xl, w ); - } - - // save off the new image - printf( "saving %s\n", savename ); - CreatePath( savename ); - - SaveFile( savename, cropped, w * h ); - - free( cropped ); -} - -/* - ============================================================================= - - COLORMAP GRABBING - - ============================================================================= - */ - -/* - =============== - BestColor - =============== - */ -byte BestColor( int r, int g, int b, int start, int stop ){ - int i; - int dr, dg, db; - int bestdistortion, distortion; - int bestcolor; - byte *pal; - -// -// let any color go to 0 as a last resort -// - bestdistortion = 256 * 256 * 4; - bestcolor = 0; - - pal = colormap_palette + start * 3; - for ( i = start ; i <= stop ; i++ ) - { - dr = r - (int)pal[0]; - dg = g - (int)pal[1]; - db = b - (int)pal[2]; - pal += 3; - distortion = dr * dr + dg * dg + db * db; - if ( distortion < bestdistortion ) { - if ( !distortion ) { - return i; // perfect match - - } - bestdistortion = distortion; - bestcolor = i; - } - } - - return bestcolor; -} - - -/* - ============== - Cmd_Colormap - - $colormap filename - - the brightes colormap is first in the table (FIXME: reverse this now?) - - 64 rows of 256 : lightmaps - 256 rows of 256 : translucency table - ============== - */ -void Cmd_Colormap( void ){ - int levels, brights; - int l, c; - float frac, red, green, blue; - float range; - byte *cropped, *lump_p; - char savename[1024]; - char dest[1024]; - - colormap_issued = true; - if ( !g_release ) { - memcpy( colormap_palette, lbmpalette, 768 ); - } - - if ( !TokenAvailable() ) { // just setting colormap_issued - return; - } - - GetToken( false ); - sprintf( savename, "%spics/%s.pcx", writedir, token ); - - if ( g_release ) { - sprintf( dest, "pics/%s.pcx", token ); - ReleaseFile( dest ); - return; - } - - range = 2; - levels = 64; - brights = 1; // ignore 255 (transparent) - - cropped = safe_malloc( ( levels + 256 ) * 256 ); - lump_p = cropped; - -// shaded levels - for ( l = 0; l < levels; l++ ) - { - frac = range - range * (float)l / ( levels - 1 ); - for ( c = 0 ; c < 256 - brights ; c++ ) - { - red = lbmpalette[c * 3]; - green = lbmpalette[c * 3 + 1]; - blue = lbmpalette[c * 3 + 2]; - - red = (int)( red * frac + 0.5 ); - green = (int)( green * frac + 0.5 ); - blue = (int)( blue * frac + 0.5 ); - -// -// note: 254 instead of 255 because 255 is the transparent color, and we -// don't want anything remapping to that -// don't use color 0, because NT can't remap that (or 255) -// - *lump_p++ = BestColor( red,green,blue, 1, 254 ); - } - - // fullbrights always stay the same - for ( ; c < 256 ; c++ ) - *lump_p++ = c; - } - -// 66% transparency table - for ( l = 0; l < 255; l++ ) - { - for ( c = 0 ; c < 255 ; c++ ) - { - red = lbmpalette[c * 3] * 0.33 + lbmpalette[l * 3] * 0.66; - green = lbmpalette[c * 3 + 1] * 0.33 + lbmpalette[l * 3 + 1] * 0.66; - blue = lbmpalette[c * 3 + 2] * 0.33 + lbmpalette[l * 3 + 2] * 0.66; - - *lump_p++ = BestColor( red,green,blue, 1, 254 ); - } - *lump_p++ = 255; - } - for ( c = 0 ; c < 256 ; c++ ) - *lump_p++ = 255; - - // save off the new image - printf( "saving %s\n", savename ); - CreatePath( savename ); - WritePCXfile( savename, cropped, 256, levels + 256, lbmpalette ); - - free( cropped ); -} - -/* - ============================================================================= - - MIPTEX GRABBING - - ============================================================================= - */ - -byte pixdata[256]; - -int d_red, d_green, d_blue; - -byte palmap[32][32][32]; -bool palmap_built; - -/* - ============= - FindColor - ============= - */ -int FindColor( int r, int g, int b ){ - int bestcolor; - - if ( r > 255 ) { - r = 255; - } - if ( r < 0 ) { - r = 0; - } - if ( g > 255 ) { - g = 255; - } - if ( g < 0 ) { - g = 0; - } - if ( b > 255 ) { - b = 255; - } - if ( b < 0 ) { - b = 0; - } -#ifndef TABLECOLORS - bestcolor = BestColor( r, g, b, 0, 254 ); -#else - bestcolor = palmap[r >> 3][g >> 3][b >> 3]; -#endif - - return bestcolor; -} - - -void BuildPalmap( void ){ -#ifdef TABLECOLORS - int r, g, b; - int bestcolor; - - if ( palmap_built ) { - return; - } - palmap_built = true; - - for ( r = 4 ; r < 256 ; r += 8 ) - { - for ( g = 4 ; g < 256 ; g += 8 ) - { - for ( b = 4 ; b < 256 ; b += 8 ) - { - bestcolor = BestColor( r, g, b, 1, 254 ); - palmap[r >> 3][g >> 3][b >> 3] = bestcolor; - } - } - } -#endif - - if ( !colormap_issued ) { - Error( "You must issue a $colormap command first" ); - } - -} - -/* - ============= - AveragePixels - ============= - */ -byte AveragePixels( int count ){ - int r,g,b; - int i; - int vis; - int pix; - int bestcolor; - byte *pal; - - vis = 0; - r = g = b = 0; - for ( i = 0 ; i < count ; i++ ) - { - pix = pixdata[i]; - - r += lbmpalette[pix * 3]; - g += lbmpalette[pix * 3 + 1]; - b += lbmpalette[pix * 3 + 2]; - vis++; - } - - r /= vis; - g /= vis; - b /= vis; - - // error diffusion - r += d_red; - g += d_green; - b += d_blue; - -// -// find the best color -// - bestcolor = FindColor( r, g, b ); - - // error diffusion - pal = colormap_palette + bestcolor * 3; - d_red = r - (int)pal[0]; - d_green = g - (int)pal[1]; - d_blue = b - (int)pal[2]; - - return bestcolor; -} - - - -/* - ============================================================================= - - ENVIRONMENT MAP GRABBING - - Creates six pcx files from tga files without any palette edge seams - also copies the tga files for GL rendering. - ============================================================================= - */ - -// 3dstudio environment map suffixes -const char *suf[6] = {"rt", "ft", "lf", "bk", "up", "dn"}; - -/* - ================= - Cmd_Environment - ================= - */ -void Cmd_Environment( void ){ - char name[1024]; - int i, x, y; - byte image[256 * 256]; - byte *tga; - - GetToken( false ); - - if ( g_release ) { - for ( i = 0 ; i < 6 ; i++ ) - { - sprintf( name, "env/%s%s.pcx", token, suf[i] ); - ReleaseFile( name ); - sprintf( name, "env/%s%s.tga", token, suf[i] ); - ReleaseFile( name ); - } - return; - } - // get the palette - BuildPalmap(); - - sprintf( name, "%senv/", gamedir ); - CreatePath( name ); - - // convert the images - for ( i = 0 ; i < 6 ; i++ ) - { - sprintf( name, "%senv/%s%s.tga", gamedir, token, suf[i] ); - printf( "loading %s...\n", name ); - LoadTGA( name, &tga, NULL, NULL ); - - for ( y = 0 ; y < 256 ; y++ ) - { - for ( x = 0 ; x < 256 ; x++ ) - { - image[y * 256 + x] = FindColor( tga[( y * 256 + x ) * 4 + 0],tga[( y * 256 + x ) * 4 + 1],tga[( y * 256 + x ) * 4 + 2] ); - } - } - free( tga ); - sprintf( name, "%senv/%s%s.pcx", writedir, token, suf[i] ); - if ( FileTime( name ) != -1 ) { - printf( "%s already exists, not overwriting.\n", name ); - } - else{ - WritePCXfile( name, image, 256, 256, colormap_palette ); - } - } -} diff --git a/tools/quake3/q3data/md3lib.cpp b/tools/quake3/q3data/md3lib.cpp deleted file mode 100644 index 483bd0ed..00000000 --- a/tools/quake3/q3data/md3lib.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "md3lib.h" -#include "inout.h" -#include "../common/cmdlib.h" -#include - -/* -** MD3_ComputeTagFromTri -*/ -void MD3_ComputeTagFromTri( md3Tag_t *pTag, const float pTri[3][3] ){ - float len[3]; - vec3_t axes[3], sides[3]; - int longestSide, shortestSide, hypotSide; - int origin; - int j; - float d; - - memset( axes, 0, sizeof( axes ) ); - memset( sides, 0, sizeof( sides ) ); - - // - // compute sides - // - for ( j = 0; j < 3; j++ ) - { - sides[j][0] = pTri[( j + 1 ) % 3][0] - pTri[j][0]; - sides[j][1] = pTri[( j + 1 ) % 3][1] - pTri[j][1]; - sides[j][2] = pTri[( j + 1 ) % 3][2] - pTri[j][2]; - - len[j] = ( float ) sqrt( DotProduct( sides[j], sides[j] ) ); - } - -#if 0 - if ( len[0] > len[1] && len[0] > len[2] ) { - longestSide = 0; shortestSide = 1; origin = 2; - } - else if ( len[1] > len[0] && len[1] > len[2] ) { - longestSide = 1; shortestSide = 2; origin = 0; - } - else if ( len[2] > len[0] && len[2] > len[1] ) { - longestSide = 2; shortestSide = 0; origin = 1; - } - else - { - Error( "invalid tag triangle, must be a right triangle with unequal length sides" ); - } -#endif - hypotSide = len[0] > len[1]? ( len[0] > len[2]? 0 : 2 ) : ( len[1] > len[2]? 1 : 2 ); - origin = ( hypotSide + 2 ) % 3; - len[hypotSide] = -1; - - longestSide = len[0] > len[1]? ( len[0] > len[2]? 0 : 2 ) : ( len[1] > len[2]? 1 : 2 ); - len[longestSide] = -1; - - shortestSide = len[0] > len[1]? ( len[0] > len[2]? 0 : 2 ) : ( len[1] > len[2]? 1 : 2 ); - len[shortestSide] = -1; - - -// VectorNormalize( sides[shortestSide], axes[0] ); -// VectorNormalize( sides[longestSide], axes[1] ); - VectorNormalize( sides[longestSide], axes[0] ); - VectorNormalize( sides[shortestSide], axes[1] ); - - // project shortest side so that it is exactly 90 degrees to the longer side - d = DotProduct( axes[0], axes[1] ); - VectorMA( axes[0], -d, axes[1], axes[0] ); - VectorNormalize( axes[0], axes[0] ); - - CrossProduct( sides[longestSide], sides[shortestSide], axes[2] ); - VectorNormalize( axes[2], axes[2] ); - - pTag->origin[0] = pTri[origin][0]; - pTag->origin[1] = pTri[origin][1]; - pTag->origin[2] = pTri[origin][2]; - - VectorCopy( axes[0], pTag->axis[0] ); - VectorCopy( axes[1], pTag->axis[1] ); - VectorCopy( axes[2], pTag->axis[2] ); -} - -/* - ============== - MD3_Dump - ============== - */ -void MD3_Dump( const char *filename ){ - md3Header_t header; - md3Tag_t *pTag; - md3Surface_t *pSurface; - FILE *fp; - void *_buffer; - void *buffer; - int fileSize; - int i; - - if ( ( fp = fopen( filename, "rb" ) ) == 0 ) { - Error( "Unable to open '%s'\n", filename ); - } - - fileSize = Q_filelength( fp ); - _buffer = safe_malloc( fileSize ); - fread( _buffer, fileSize, 1, fp ); - fclose( fp ); - - buffer = ( char * ) _buffer; - header = *( md3Header_t * ) _buffer; - - if ( header.ident != MD3_IDENT ) { - Error( "Incorrect ident for '%s'\n", filename ); - } - - printf( "Contents of '%s'\n", filename ); - printf( " version: %d\n", header.version ); - printf( " name: %s\n", header.name ); - printf( " num frames: %d\n", header.numFrames ); - printf( " num tags: %d\n", header.numTags ); - printf( " num surfaces: %d\n", header.numSurfaces ); - printf( " num skins: %d\n", header.numSkins ); - printf( " file size: %d\n", fileSize ); - - printf( "--- TAGS ---\n" ); - pTag = ( md3Tag_t * ) ( ( ( char * ) buffer ) + header.ofsTags ); - for ( i = 0; i < header.numTags; i++, pTag++ ) - { - printf( " tag %d ('%s')\n", i, pTag->name ); - printf( " origin: %f,%f,%f\n", pTag->origin[0], pTag->origin[1], pTag->origin[2] ); - printf( " vf: %f,%f,%f\n", pTag->axis[0][0], pTag->axis[0][1], pTag->axis[0][2] ); - printf( " vr: %f,%f,%f\n", pTag->axis[1][0], pTag->axis[1][1], pTag->axis[1][2] ); - printf( " vu: %f,%f,%f\n", pTag->axis[2][0], pTag->axis[2][1], pTag->axis[2][2] ); - } - - printf( "--- SURFACES ---\n" ); - pSurface = ( md3Surface_t * ) ( ( ( char * ) buffer ) + header.ofsSurfaces ); - - for ( i = 0; i < header.numSurfaces; i++ ) - { - int j; - - md3Shader_t *pShader = ( md3Shader_t * ) ( ( ( char * ) pSurface ) + pSurface->ofsShaders ); - - printf( "\n surface %d ('%s')\n", i, pSurface->name ); - printf( " num frames: %d\n", pSurface->numFrames ); - printf( " num shaders: %d\n", pSurface->numShaders ); - printf( " num tris: %d\n", pSurface->numTriangles ); - printf( " num verts: %d\n", pSurface->numVerts ); - - if ( pSurface->numShaders > 0 ) { - printf( " --- SHADERS ---\n" ); - - for ( j = 0; j < pSurface->numShaders; j++, pShader++ ) - { - printf( " shader %d ('%s')\n", j, pShader->name ); - } - } - pSurface = ( md3Surface_t * ) ( ( ( char * ) pSurface ) + pSurface->ofsEnd ); - } - - free( _buffer ); -} diff --git a/tools/quake3/q3data/md3lib.h b/tools/quake3/q3data/md3lib.h deleted file mode 100644 index 2722a3e7..00000000 --- a/tools/quake3/q3data/md3lib.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "../common/qfiles.h" - -void MD3_Dump( const char *filename ); -void MD3_ComputeTagFromTri( md3Tag_t *pTag, const float tri[3][3] ); diff --git a/tools/quake3/q3data/models.cpp b/tools/quake3/q3data/models.cpp deleted file mode 100644 index 1835df69..00000000 --- a/tools/quake3/q3data/models.cpp +++ /dev/null @@ -1,2062 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "q3data.h" - -//================================================================= - -static void OrderSurfaces( void ); -static void LoadBase( const char *filename ); -static int LoadModelFile( const char *filename, polyset_t **ppsets, int *pnumpolysets ); - -#define MAX_SURFACE_TRIS ( SHADER_MAX_INDEXES / 3 ) -#define MAX_SURFACE_VERTS SHADER_MAX_VERTEXES - -#define MD3_TYPE_UNKNOWN 0 -#define MD3_TYPE_BASE3DS 1 -#define MD3_TYPE_SPRITE 2 -#define MD3_TYPE_ASE 3 - -#define MAX_ANIM_FRAMES 512 -#define MAX_ANIM_SURFACES 32 - -typedef struct -{ - polyset_t *frames; - int numFrames; -} SurfaceAnimation_t; - -typedef struct -{ - polyset_t *surfaces[MAX_ANIM_SURFACES]; - int numSurfaces; -} ObjectAnimationFrame_t; - -typedef struct { - vec3_t xyz; - vec3_t normal; - vec3_t color; - float st[2]; - int index; -} baseVertex_t; - -typedef struct { - baseVertex_t v[3]; -} baseTriangle_t; - -//================================================================ - -typedef struct -{ - md3Surface_t header; - md3Shader_t shaders[MD3_MAX_SHADERS]; - // all verts (xyz_normal) - float *verts[MD3_MAX_FRAMES]; - - baseTriangle_t baseTriangles[MD3_MAX_TRIANGLES]; - - // the triangles will be sorted so that they form long generalized tristrips - int orderedTriangles[MD3_MAX_TRIANGLES][3]; - int lodTriangles[MD3_MAX_TRIANGLES][3]; - baseVertex_t baseVertexes[MD3_MAX_VERTS]; - -} md3SurfaceData_t; - -typedef struct -{ - int skinwidth, skinheight; - - md3SurfaceData_t surfData[MD3_MAX_SURFACES]; - - md3Tag_t tags[MD3_MAX_FRAMES][MD3_MAX_TAGS]; - md3Frame_t frames[MD3_MAX_FRAMES]; - - md3Header_t model; - float scale_up; // set by $scale - vec3_t adjust; // set by $origin - vec3_t aseAdjust; - int fixedwidth, fixedheight; // set by $skinsize - - int maxSurfaceTris; - - int lowerSkipFrameStart, lowerSkipFrameEnd; - int maxUpperFrames; - int maxHeadFrames; - int currentLod; - float lodBias; - - int type; // MD3_TYPE_BASE, MD3_TYPE_OLDBASE, MD3_TYPE_ASE, or MD3_TYPE_SPRITE - -} q3data; - -q3data g_data; - -// the command list holds counts, the count * 3 xyz, st, normal indexes -// that are valid for every frame -char g_cddir[1024]; -char g_modelname[1024]; - -//============================================================== - -/* - =============== - ClearModel - =============== - */ -void ClearModel( void ){ - int i; - - g_data.type = MD3_TYPE_UNKNOWN; - - for ( i = 0; i < MD3_MAX_SURFACES; i++ ) - { - memset( &g_data.surfData[i].header, 0, sizeof( g_data.surfData[i].header ) ); - memset( &g_data.surfData[i].shaders, 0, sizeof( g_data.surfData[i].shaders ) ); - memset( &g_data.surfData[i].verts, 0, sizeof( g_data.surfData[i].verts ) ); - } - - memset( g_data.tags, 0, sizeof( g_data.tags ) ); - - for ( i = 0; i < g_data.model.numSurfaces; i++ ) - { - int j; - - for ( j = 0; j < g_data.surfData[i].header.numShaders; j++ ) - { - memset( &g_data.surfData[i].shaders[j], 0, sizeof( g_data.surfData[i].shaders[j] ) ); - } - } - memset( &g_data.model, 0, sizeof( g_data.model ) ); - memset( g_cddir, 0, sizeof( g_cddir ) ); - - g_modelname[0] = 0; - g_data.scale_up = 1.0; - memset( &g_data.model, 0, sizeof( g_data.model ) ); - VectorCopy( vec3_origin, g_data.adjust ); - g_data.fixedwidth = g_data.fixedheight = 0; - g_skipmodel = false; -} - -/* -** void WriteModelSurface( FILE *modelouthandle, md3SurfaceData_t *pSurfData ) -** -** This routine assumes that the file position has been adjusted -** properly prior to entry to point at the beginning of the surface. -** -** Since surface header information is completely relative, we can't -** just randomly seek to an arbitrary surface location right now. Is -** this something we should add? -*/ -void WriteModelSurface( FILE *modelouthandle, md3SurfaceData_t *pSurfData ){ - md3Surface_t *pSurf = &pSurfData->header; - md3Shader_t *pShader = pSurfData->shaders; - baseVertex_t *pBaseVertex = pSurfData->baseVertexes; - float **verts = pSurfData->verts; - - short xyznormals[MD3_MAX_VERTS][4]; - - float base_st[MD3_MAX_VERTS][2]; - md3Surface_t surftemp; - - int f, i, j, k; - - if ( strstr( pSurf->name, "tag_" ) == pSurf->name ) { - return; - } - - // - // write out the header - // - surftemp = *pSurf; - surftemp.ident = LittleLong( MD3_IDENT ); - surftemp.flags = LittleLong( pSurf->flags ); - surftemp.numFrames = LittleLong( pSurf->numFrames ); - surftemp.numShaders = LittleLong( pSurf->numShaders ); - - surftemp.ofsShaders = LittleLong( pSurf->ofsShaders ); - - surftemp.ofsTriangles = LittleLong( pSurf->ofsTriangles ); - surftemp.numTriangles = LittleLong( pSurf->numTriangles ); - - surftemp.ofsSt = LittleLong( pSurf->ofsSt ); - surftemp.ofsXyzNormals = LittleLong( pSurf->ofsXyzNormals ); - surftemp.ofsEnd = LittleLong( pSurf->ofsEnd ); - - SafeWrite( modelouthandle, &surftemp, sizeof( surftemp ) ); - - if ( g_verbose ) { - printf( "surface '%s'\n", pSurf->name ); - printf( "...num shaders: %d\n", pSurf->numShaders ); - } - - // - // write out shaders - // - for ( i = 0; i < pSurf->numShaders; i++ ) - { - md3Shader_t shadertemp; - - if ( g_verbose ) { - printf( "......'%s'\n", pShader[i].name ); - } - - shadertemp = pShader[i]; - shadertemp.shaderIndex = LittleLong( shadertemp.shaderIndex ); - SafeWrite( modelouthandle, &shadertemp, sizeof( shadertemp ) ); - } - - // - // write out the triangles - // - for ( i = 0 ; i < pSurf->numTriangles ; i++ ) - { - for ( j = 0 ; j < 3 ; j++ ) - { - int ivalue = LittleLong( pSurfData->orderedTriangles[i][j] ); - pSurfData->orderedTriangles[i][j] = ivalue; - } - } - - SafeWrite( modelouthandle, pSurfData->orderedTriangles, pSurf->numTriangles * sizeof( g_data.surfData[0].orderedTriangles[0] ) ); - - if ( g_verbose ) { - printf( "\n...num verts: %d\n", pSurf->numVerts ); - printf( "...TEX COORDINATES\n" ); - } - - // - // write out the texture coordinates - // - for ( i = 0; i < pSurf->numVerts ; i++ ) { - base_st[i][0] = LittleFloat( pBaseVertex[i].st[0] ); - base_st[i][1] = LittleFloat( pBaseVertex[i].st[1] ); - if ( g_verbose ) { - printf( "......%d: %f,%f\n", i, base_st[i][0], base_st[i][1] ); - } - } - SafeWrite( modelouthandle, base_st, pSurf->numVerts * sizeof( base_st[0] ) ); - - // - // write the xyz_normal - // - if ( g_verbose ) { - printf( "...XYZNORMALS\n" ); - } - for ( f = 0; f < g_data.model.numFrames; f++ ) - { - for ( j = 0 ; j < pSurf->numVerts; j++ ) - { - short value; - - for ( k = 0 ; k < 3 ; k++ ) - { - value = ( short ) ( verts[f][j * 6 + k] / MD3_XYZ_SCALE ); - xyznormals[j][k] = LittleShort( value ); - } - NormalToLatLong( &verts[f][j * 6 + 3], (byte *)&xyznormals[j][3] ); - } - SafeWrite( modelouthandle, xyznormals, pSurf->numVerts * sizeof( short ) * 4 ); - } -} - -/* -** void WriteModelFile( FILE *modelouthandle ) -** -** CHUNK SIZE -** header sizeof( md3Header_t ) -** frames sizeof( md3Frame_t ) * numFrames -** tags sizeof( md3Tag_t ) * numFrames * numTags -** surfaces surfaceSum -*/ -void WriteModelFile( FILE *modelouthandle ){ - int f; - int i, j; - md3Header_t modeltemp; - long surfaceSum = 0; - int numRealSurfaces = 0; - int numFrames = g_data.model.numFrames; - - // compute offsets for all surfaces, sum their total size - for ( i = 0; i < g_data.model.numSurfaces; i++ ) - { - if ( strstr( g_data.surfData[i].header.name, "tag_" ) != g_data.surfData[i].header.name ) { - md3Surface_t *psurf = &g_data.surfData[i].header; - - if ( psurf->numTriangles == 0 || psurf->numVerts == 0 ) { - continue; - } - - // - // the triangle and vertex split threshold is controlled by a parameter - // to $base, a la $base blah.3ds 1900, where "1900" determines the number - // of triangles to split on - // - else if ( psurf->numVerts > MAX_SURFACE_VERTS ) { - Error( "too many vertices\n" ); - } - - psurf->numFrames = numFrames; - - psurf->ofsShaders = sizeof( md3Surface_t ); - - if ( psurf->numTriangles > MAX_SURFACE_TRIS ) { - Error( "too many faces\n" ); - } - - psurf->ofsTriangles = psurf->ofsShaders + psurf->numShaders * sizeof( md3Shader_t ); - - psurf->ofsSt = psurf->ofsTriangles + psurf->numTriangles * sizeof( md3Triangle_t ); - psurf->ofsXyzNormals = psurf->ofsSt + psurf->numVerts * sizeof( md3St_t ); - psurf->ofsEnd = psurf->ofsXyzNormals + psurf->numFrames * psurf->numVerts * ( sizeof( short ) * 4 ); - - surfaceSum += psurf->ofsEnd; - - numRealSurfaces++; - } - } - - g_data.model.ident = MD3_IDENT; - g_data.model.version = MD3_VERSION; - - g_data.model.ofsFrames = sizeof( md3Header_t ); - g_data.model.ofsTags = g_data.model.ofsFrames + numFrames * sizeof( md3Frame_t ); - g_data.model.ofsSurfaces = g_data.model.ofsTags + numFrames * g_data.model.numTags * sizeof( md3Tag_t ); - g_data.model.ofsEnd = g_data.model.ofsSurfaces + surfaceSum; - - // - // write out the model header - // - modeltemp = g_data.model; - modeltemp.ident = LittleLong( modeltemp.ident ); - modeltemp.version = LittleLong( modeltemp.version ); - modeltemp.numFrames = LittleLong( modeltemp.numFrames ); - modeltemp.numTags = LittleLong( modeltemp.numTags ); - modeltemp.numSurfaces = LittleLong( numRealSurfaces ); - modeltemp.ofsFrames = LittleLong( modeltemp.ofsFrames ); - modeltemp.ofsTags = LittleLong( modeltemp.ofsTags ); - modeltemp.ofsSurfaces = LittleLong( modeltemp.ofsSurfaces ); - modeltemp.ofsEnd = LittleLong( modeltemp.ofsEnd ); - - SafeWrite( modelouthandle, &modeltemp, sizeof( modeltemp ) ); - - // - // write out the frames - // - for ( i = 0 ; i < numFrames ; i++ ) - { - vec3_t tmpVec; - float maxRadius = 0; - - // - // compute localOrigin and radius - // - g_data.frames[i].localOrigin[0] = - g_data.frames[i].localOrigin[1] = - g_data.frames[i].localOrigin[2] = 0; - - for ( j = 0; j < 8; j++ ) - { - tmpVec[0] = g_data.frames[i].bounds[( j & 1 ) != 0][0]; - tmpVec[1] = g_data.frames[i].bounds[( j & 2 ) != 0][1]; - tmpVec[2] = g_data.frames[i].bounds[( j & 4 ) != 0][2]; - - if ( VectorLength( tmpVec ) > maxRadius ) { - maxRadius = VectorLength( tmpVec ); - } - } - - g_data.frames[i].radius = LittleFloat( maxRadius ); - - // swap - for ( j = 0 ; j < 3 ; j++ ) { - g_data.frames[i].bounds[0][j] = LittleFloat( g_data.frames[i].bounds[0][j] ); - g_data.frames[i].bounds[1][j] = LittleFloat( g_data.frames[i].bounds[1][j] ); - g_data.frames[i].localOrigin[j] = LittleFloat( g_data.frames[i].localOrigin[j] ); - } - } - fseek( modelouthandle, g_data.model.ofsFrames, SEEK_SET ); - SafeWrite( modelouthandle, g_data.frames, numFrames * sizeof( g_data.frames[0] ) ); - - // - // write out the tags - // - fseek( modelouthandle, g_data.model.ofsTags, SEEK_SET ); - for ( f = 0 ; f < g_data.model.numFrames; f++ ) - { - int t; - - for ( t = 0; t < g_data.model.numTags; t++ ) - { - g_data.tags[f][t].origin[0] = LittleFloat( g_data.tags[f][t].origin[0] ); - g_data.tags[f][t].origin[1] = LittleFloat( g_data.tags[f][t].origin[1] ); - g_data.tags[f][t].origin[2] = LittleFloat( g_data.tags[f][t].origin[2] ); - - for ( j = 0 ; j < 3 ; j++ ) - { - g_data.tags[f][t].axis[0][j] = LittleFloat( g_data.tags[f][t].axis[0][j] ); - g_data.tags[f][t].axis[1][j] = LittleFloat( g_data.tags[f][t].axis[1][j] ); - g_data.tags[f][t].axis[2][j] = LittleFloat( g_data.tags[f][t].axis[2][j] ); - } - } - SafeWrite( modelouthandle, g_data.tags[f], g_data.model.numTags * sizeof( md3Tag_t ) ); - } - - // - // write out the surfaces - // - fseek( modelouthandle, g_data.model.ofsSurfaces, SEEK_SET ); - for ( i = 0; i < g_data.model.numSurfaces; i++ ) - { - WriteModelSurface( modelouthandle, &g_data.surfData[i] ); - } -} - - -/* - =============== - FinishModel - =============== - */ -void FinishModel( int type ){ - FILE *modelouthandle; - FILE *defaultSkinHandle; - char name[1024]; - int i; - - if ( !g_data.model.numFrames ) { - return; - } - - // - // build generalized triangle strips - // - OrderSurfaces(); - - if ( type == TYPE_PLAYER ) { - sprintf( name, "%s%s", writedir, g_modelname ); - path_set_extension( name, "_default.skin" ); - - defaultSkinHandle = fopen( name, "wt" ); - for ( i = 0; i < g_data.model.numSurfaces; i++ ) - { - fprintf( defaultSkinHandle, "%s,%s\n", g_data.surfData[i].header.name, g_data.surfData[i].shaders[0].name ); - } - fclose( defaultSkinHandle ); - } - - sprintf( name, "%s%s", writedir, g_modelname ); - - // - // copy the model and its shaders to release directory tree - // if doing a release build - // - if ( g_release ) { - int i, j; - md3SurfaceData_t *pSurf; - - ReleaseFile( g_modelname ); - - for ( i = 0; i < g_data.model.numSurfaces; i++ ) { - pSurf = &g_data.surfData[i]; - for ( j = 0; j < g_data.model.numSkins; j++ ) { - ReleaseShader( pSurf->shaders[j].name ); - } - } - return; - } - - // - // write the model output file - // - printf( "saving to %s\n", name ); - CreatePath( name ); - modelouthandle = SafeOpenWrite( name ); - - WriteModelFile( modelouthandle ); - - printf( "%4d surfaces\n", g_data.model.numSurfaces ); - printf( "%4d frames\n", g_data.model.numFrames ); - printf( "%4d tags\n", g_data.model.numTags ); - printf( "file size: %d\n", (int)ftell( modelouthandle ) ); - printf( "---------------------\n" ); - - fclose( modelouthandle ); -} - -/* -** OrderSurfaces -** -** Reorders triangles in all the surfaces. -*/ -static void OrderSurfaces( void ){ - int s; - extern bool g_stripify; - - // go through each surface and find best strip/fans possible - for ( s = 0; s < g_data.model.numSurfaces; s++ ) - { - int mesh[MD3_MAX_TRIANGLES][3]; - int i; - - printf( "stripifying surface %d/%d with %d tris\n", s, g_data.model.numSurfaces, g_data.surfData[s].header.numTriangles ); - - for ( i = 0; i < g_data.surfData[s].header.numTriangles; i++ ) - { - mesh[i][0] = g_data.surfData[s].lodTriangles[i][0]; - mesh[i][1] = g_data.surfData[s].lodTriangles[i][1]; - mesh[i][2] = g_data.surfData[s].lodTriangles[i][2]; - } - - if ( g_stripify ) { - OrderMesh( mesh, // input - g_data.surfData[s].orderedTriangles, // output - g_data.surfData[s].header.numTriangles ); - } - else - { - memcpy( g_data.surfData[s].orderedTriangles, mesh, sizeof( int ) * 3 * g_data.surfData[s].header.numTriangles ); - } - } -} - - -/* - =============================================================== - - BASE FRAME SETUP - - =============================================================== - */ -/* - ============ - CopyTrianglesToBaseTriangles - - ============ - */ -static void CopyTrianglesToBaseTriangles( triangle_t *ptri, int numtri, baseTriangle_t *bTri ){ - int i; -// int width, height, iwidth, iheight, swidth; -// float s_scale, t_scale; -// float scale; -// vec3_t mins, maxs; - -/* - // - // find bounds of all the verts on the base frame - // - ClearBounds (mins, maxs); - - for (i=0 ; i= 150) - scale = 150.0 / width; - if (height*scale >= 190) - scale = 190.0 / height; - - s_scale = t_scale = scale; - - iwidth = ceil(width*s_scale); - iheight = ceil(height*t_scale); - - iwidth += 4; - iheight += 4; - } - else - { // new style - iwidth = g_data.fixedwidth / 2; - iheight = g_data.fixedheight; - - s_scale = (float)(iwidth-4) / width; - t_scale = (float)(iheight-4) / height; - } - - // make the width a multiple of 4; some hardware requires this, and it ensures - // dword alignment for each scan - swidth = iwidth*2; - g_data.skinwidth = (swidth + 3) & ~3; - g_data.skinheight = iheight; - */ - - for ( i = 0; i < numtri ; i++, ptri++, bTri++ ) - { - int j; - - for ( j = 0 ; j < 3 ; j++ ) - { - VectorCopy( ptri->verts[j], bTri->v[j].xyz ); - VectorCopy( ptri->normals[j], bTri->v[j].normal ); - - bTri->v[j].st[0] = ptri->texcoords[j][0]; - bTri->v[j].st[1] = ptri->texcoords[j][1]; - } - } -} - -static void BuildBaseFrame( const char *filename, ObjectAnimationFrame_t *pOAF ){ - baseTriangle_t *bTri; - baseVertex_t *bVert; - int i, j; - - // calculate the base triangles - for ( i = 0; i < g_data.model.numSurfaces; i++ ) - { - CopyTrianglesToBaseTriangles( pOAF->surfaces[i]->triangles, - pOAF->surfaces[i]->numtriangles, - g_data.surfData[i].baseTriangles ); - - strcpy( g_data.surfData[i].header.name, pOAF->surfaces[i]->name ); - - g_data.surfData[i].header.numTriangles = pOAF->surfaces[i]->numtriangles; - g_data.surfData[i].header.numVerts = 0; - -/* - if ( strstr( filename, gamedir + 1 ) ) - { - strcpy( shaderName, strstr( filename, gamedir + 1 ) + strlen( gamedir ) - 1 ); - } - else - { - strcpy( shaderName, filename ); - } - - StripFilename( shaderName ); - - strcpy( shaderName, pOAF->surfaces[i]->materialname ); - */ - strcpy( g_data.surfData[i].shaders[g_data.surfData[i].header.numShaders].name, pOAF->surfaces[i]->materialname ); - - g_data.surfData[i].header.numShaders++; - } - - // - // compute unique vertices for each polyset - // - for ( i = 0; i < g_data.model.numSurfaces; i++ ) - { - int t; - - for ( t = 0; t < pOAF->surfaces[i]->numtriangles; t++ ) - { - bTri = &g_data.surfData[i].baseTriangles[t]; - - for ( j = 0 ; j < 3 ; j++ ) - { - int k; - - bVert = &bTri->v[j]; - - // get the xyz index - for ( k = 0; k < g_data.surfData[i].header.numVerts; k++ ) - { - if ( ( g_data.surfData[i].baseVertexes[k].st[0] == bVert->st[0] ) && - ( g_data.surfData[i].baseVertexes[k].st[1] == bVert->st[1] ) && - ( VectorCompare( bVert->xyz, g_data.surfData[i].baseVertexes[k].xyz ) ) && - ( VectorCompare( bVert->normal, g_data.surfData[i].baseVertexes[k].normal ) ) ) { - break; // this vertex is already in the base vertex list - } - } - - if ( k == g_data.surfData[i].header.numVerts ) { // new index - g_data.surfData[i].baseVertexes[g_data.surfData[i].header.numVerts] = *bVert; - g_data.surfData[i].header.numVerts++; - } - - bVert->index = k; - - g_data.surfData[i].lodTriangles[t][j] = k; - } - } - } - - // - // find tags - // - for ( i = 0; i < g_data.model.numSurfaces; i++ ) - { - if ( strstr( pOAF->surfaces[i]->name, "tag_" ) == pOAF->surfaces[i]->name ) { - if ( pOAF->surfaces[i]->numtriangles != 1 ) { - Error( "tag polysets must consist of only one triangle" ); - } - if ( strstr( filename, "_flash.md3" ) && !strcmp( pOAF->surfaces[i]->name, "tag_parent" ) ) { - continue; - } - printf( "found tag '%s'\n", pOAF->surfaces[i]->name ); - g_data.model.numTags++; - } - } - -} - -static int LoadModelFile( const char *filename, polyset_t **psets, int *numpolysets ){ - char file1[1024]; - - printf( "---------------------\n" ); - if ( !path_is_absolute( filename ) ) { - sprintf( file1, "%s/%s", g_cddir, filename ); - } - else - { - strcpy( file1, filename ); - } - - if ( FileTime( file1 ) == -1 ) { - Error( "%s doesn't exist", file1 ); - } - - // - // load the base triangles - // - *psets = Polyset_LoadSets( file1, numpolysets, g_data.maxSurfaceTris ); - - // - // snap polysets - // - Polyset_SnapSets( *psets, *numpolysets ); - - if ( strstr( file1, ".3ds" ) || strstr( file1, ".3DS" ) ) { - return MD3_TYPE_BASE3DS; - } - - Error( "Unknown model file type" ); - - return MD3_TYPE_UNKNOWN; -} - -/* - ================= - Cmd_Base - ================= - */ -void Cmd_Base( void ){ - char filename[1024]; - - GetToken( false ); - sprintf( filename, "%s/%s", g_cddir, token ); - LoadBase( filename ); -} - -static void LoadBase( const char *filename ){ - int numpolysets; - polyset_t *psets; - int i; - ObjectAnimationFrame_t oaf; - - // determine polyset splitting threshold - if ( TokenAvailable() ) { - GetToken( false ); - g_data.maxSurfaceTris = atoi( token ); - } - else - { - g_data.maxSurfaceTris = MAX_SURFACE_TRIS - 1; - } - - g_data.type = LoadModelFile( filename, &psets, &numpolysets ); - - Polyset_ComputeNormals( psets, numpolysets ); - - g_data.model.numSurfaces = numpolysets; - - memset( &oaf, 0, sizeof( oaf ) ); - - for ( i = 0; i < numpolysets; i++ ) - { - oaf.surfaces[i] = &psets[i]; - oaf.numSurfaces = numpolysets; - } - - BuildBaseFrame( filename, &oaf ); - - free( psets[0].triangles ); - free( psets ); -} - -/* - ================= - Cmd_SpriteBase - - $spritebase xorg yorg width height - - Generate a single square for the model - ================= - */ -void Cmd_SpriteBase( void ){ - float xl, yl, width, height; - - g_data.type = MD3_TYPE_SPRITE; - - GetToken( false ); - xl = atof( token ); - GetToken( false ); - yl = atof( token ); - GetToken( false ); - width = atof( token ); - GetToken( false ); - height = atof( token ); - -// if (g_skipmodel || g_release || g_archive) -// return; - - printf( "---------------------\n" ); - - g_data.surfData[0].verts[0] = safe_calloc( sizeof( float ) * 6 * 4 ); - - g_data.surfData[0].header.numVerts = 4; - - g_data.surfData[0].verts[0][0 + 0] = 0; - g_data.surfData[0].verts[0][0 + 1] = -xl; - g_data.surfData[0].verts[0][0 + 2] = yl + height; - - g_data.surfData[0].verts[0][0 + 3] = -1; - g_data.surfData[0].verts[0][0 + 4] = 0; - g_data.surfData[0].verts[0][0 + 5] = 0; - g_data.surfData[0].baseVertexes[0].st[0] = 0; - g_data.surfData[0].baseVertexes[0].st[1] = 0; - - - g_data.surfData[0].verts[0][6 + 0] = 0; - g_data.surfData[0].verts[0][6 + 1] = -xl - width; - g_data.surfData[0].verts[0][6 + 2] = yl + height; - - g_data.surfData[0].verts[0][6 + 3] = -1; - g_data.surfData[0].verts[0][6 + 4] = 0; - g_data.surfData[0].verts[0][6 + 5] = 0; - g_data.surfData[0].baseVertexes[1].st[0] = 1; - g_data.surfData[0].baseVertexes[1].st[1] = 0; - - - g_data.surfData[0].verts[0][12 + 0] = 0; - g_data.surfData[0].verts[0][12 + 1] = -xl - width; - g_data.surfData[0].verts[0][12 + 2] = yl; - - g_data.surfData[0].verts[0][12 + 3] = -1; - g_data.surfData[0].verts[0][12 + 4] = 0; - g_data.surfData[0].verts[0][12 + 5] = 0; - g_data.surfData[0].baseVertexes[2].st[0] = 1; - g_data.surfData[0].baseVertexes[2].st[1] = 1; - - - g_data.surfData[0].verts[0][18 + 0] = 0; - g_data.surfData[0].verts[0][18 + 1] = -xl; - g_data.surfData[0].verts[0][18 + 2] = yl; - - g_data.surfData[0].verts[0][18 + 3] = -1; - g_data.surfData[0].verts[0][18 + 4] = 0; - g_data.surfData[0].verts[0][18 + 5] = 0; - g_data.surfData[0].baseVertexes[3].st[0] = 0; - g_data.surfData[0].baseVertexes[3].st[1] = 1; - - g_data.surfData[0].lodTriangles[0][0] = 0; - g_data.surfData[0].lodTriangles[0][1] = 1; - g_data.surfData[0].lodTriangles[0][2] = 2; - - g_data.surfData[0].lodTriangles[1][0] = 2; - g_data.surfData[0].lodTriangles[1][1] = 3; - g_data.surfData[0].lodTriangles[1][2] = 0; - - g_data.model.numSurfaces = 1; - - g_data.surfData[0].header.numTriangles = 2; - g_data.surfData[0].header.numVerts = 4; - - g_data.model.numFrames = 1; -} - -/* - =========================================================================== - - FRAME GRABBING - - =========================================================================== - */ - -/* - =============== - GrabFrame - =============== - */ -void GrabFrame( const char *frame ){ - int i, j, k; - char file1[1024]; - md3Frame_t *fr; - md3Tag_t tagParent; - float *frameXyz; - float *frameNormals; - const char *framefile; - polyset_t *psets; - bool parentTagExists = false; - int numpolysets; - int numtags = 0; - int tagcount; - - // the frame 'run1' will be looked for as either - // run.1 or run1.tri, so the new alias sequence save - // feature an be used - if ( frame[1] != ':' ) { -// framefile = FindFrameFile (frame); - framefile = frame; - sprintf( file1, "%s/%s",g_cddir, framefile ); - } - else - { - strcpy( file1, frame ); - } - printf( "grabbing %s\n", file1 ); - - if ( g_data.model.numFrames >= MD3_MAX_FRAMES ) { - Error( "model.numFrames >= MD3_MAX_FRAMES" ); - } - fr = &g_data.frames[g_data.model.numFrames]; - - strcpy( fr->name, frame ); - - psets = Polyset_LoadSets( file1, &numpolysets, g_data.maxSurfaceTris ); - - // - // snap polysets - // - Polyset_SnapSets( psets, numpolysets ); - - // - // compute vertex normals - // - Polyset_ComputeNormals( psets, numpolysets ); - - // - // flip everything to compensate for the alias coordinate system - // and perform global scale and adjust - // - for ( i = 0; i < g_data.model.numSurfaces; i++ ) - { - triangle_t *ptri = psets[i].triangles; - int t; - - for ( t = 0; t < psets[i].numtriangles; t++ ) - { - - for ( j = 0; j < 3; j++ ) - { - - // scale and adjust - for ( k = 0 ; k < 3 ; k++ ) { - ptri[t].verts[j][k] = ptri[t].verts[j][k] * g_data.scale_up + - g_data.adjust[k]; - - if ( ptri[t].verts[j][k] > 1023 || - ptri[t].verts[j][k] < -1023 ) { - Error( "Model extents too large" ); - } - } - } - } - } - - // - // find and count tags, locate parent tag - // - for ( i = 0; i < numpolysets; i++ ) - { - if ( strstr( psets[i].name, "tag_" ) == psets[i].name ) { - if ( strstr( psets[i].name, "tag_parent" ) == psets[i].name ) { - if ( strstr( psets[i].name, "tag_parent" ) ) { - float tri[3][3]; - - if ( parentTagExists ) { - Error( "Multiple parent tags not allowed" ); - } - - memcpy( tri[0], psets[i].triangles[0].verts[0], sizeof( float ) * 3 ); - memcpy( tri[1], psets[i].triangles[0].verts[1], sizeof( float ) * 3 ); - memcpy( tri[2], psets[i].triangles[0].verts[2], sizeof( float ) * 3 ); - - MD3_ComputeTagFromTri( &tagParent, tri ); - strcpy( tagParent.name, psets[i].name ); - g_data.tags[g_data.model.numFrames][numtags] = tagParent; - parentTagExists = true; - - } - } - numtags++; - } - - if ( strcmp( psets[i].name, g_data.surfData[i].header.name ) ) { - Error( "Mismatched surfaces from base('%s') to frame('%s') in model '%s'\n", g_data.surfData[i].header.name, psets[i].name, g_modelname ); - } - } - - if ( numtags != g_data.model.numTags ) { - Error( "mismatched number of tags in frame(%d) vs. base(%d)", numtags, g_data.model.numTags ); - } - - if ( numpolysets != g_data.model.numSurfaces ) { - Error( "mismatched number of surfaces in frame(%d) vs. base(%d)", numpolysets - numtags, g_data.model.numSurfaces ); - } - - // - // prepare to accumulate bounds and normals - // - ClearBounds( fr->bounds[0], fr->bounds[1] ); - - // - // store the frame's vertices in the same order as the base. This assumes the - // triangles and vertices in this frame are in exactly the same order as in the - // base - // - for ( i = 0, tagcount = 0; i < numpolysets; i++ ) - { - int t; - triangle_t *pTris = psets[i].triangles; - - strcpy( g_data.surfData[i].header.name, psets[i].name ); - - // - // parent tag adjust - // - if ( parentTagExists ) { - for ( t = 0; t < psets[i].numtriangles; t++ ) - { - for ( j = 0; j < 3 ; j++ ) - { - vec3_t tmp; - - VectorSubtract( pTris[t].verts[j], tagParent.origin, tmp ); - - pTris[t].verts[j][0] = DotProduct( tmp, tagParent.axis[0] ); - pTris[t].verts[j][1] = DotProduct( tmp, tagParent.axis[1] ); - pTris[t].verts[j][2] = DotProduct( tmp, tagParent.axis[2] ); - - VectorCopy( pTris[t].normals[j], tmp ); - pTris[t].normals[j][0] = DotProduct( tmp, tagParent.axis[0] ); - pTris[t].normals[j][1] = DotProduct( tmp, tagParent.axis[1] ); - pTris[t].normals[j][2] = DotProduct( tmp, tagParent.axis[2] ); - } - } - } - - // - // compute tag data - // - if ( strstr( psets[i].name, "tag_" ) == psets[i].name ) { - md3Tag_t *pTag = &g_data.tags[g_data.model.numFrames][tagcount]; - float tri[3][3]; - - strcpy( pTag->name, psets[i].name ); - - memcpy( tri[0], pTris[0].verts[0], sizeof( float ) * 3 ); - memcpy( tri[1], pTris[0].verts[1], sizeof( float ) * 3 ); - memcpy( tri[2], pTris[0].verts[2], sizeof( float ) * 3 ); - - MD3_ComputeTagFromTri( pTag, tri ); - tagcount++; - } - else - { - if ( g_data.surfData[i].verts[g_data.model.numFrames] ) { - free( g_data.surfData[i].verts[g_data.model.numFrames] ); - } - frameXyz = g_data.surfData[i].verts[g_data.model.numFrames] = safe_calloc( sizeof( float ) * 6 * g_data.surfData[i].header.numVerts ); - frameNormals = frameXyz + 3; - - for ( t = 0; t < psets[i].numtriangles; t++ ) - { - for ( j = 0; j < 3 ; j++ ) - { - int index; - - index = g_data.surfData[i].baseTriangles[t].v[j].index; - frameXyz[index * 6 + 0] = pTris[t].verts[j][0]; - frameXyz[index * 6 + 1] = pTris[t].verts[j][1]; - frameXyz[index * 6 + 2] = pTris[t].verts[j][2]; - frameNormals[index * 6 + 0] = pTris[t].normals[j][0]; - frameNormals[index * 6 + 1] = pTris[t].normals[j][1]; - frameNormals[index * 6 + 2] = pTris[t].normals[j][2]; - AddPointToBounds( &frameXyz[index * 6], fr->bounds[0], fr->bounds[1] ); - } - } - } - } - - g_data.model.numFrames++; - - // only free the first triangle array, all of the psets in this array share the - // same triangle pool!!! -// free( psets[0].triangles ); -// free( psets ); -} - -//=========================================================================== - - - -/* - =============== - Cmd_Frame - =============== - */ -void Cmd_Frame( void ){ - while ( TokenAvailable() ) - { - GetToken( false ); - if ( g_skipmodel ) { - continue; - } - if ( g_release || g_archive ) { - g_data.model.numFrames = 1; // don't skip the writeout - continue; - } - - GrabFrame( token ); - } -} - - -/* - =============== - Cmd_Skin - - =============== - */ -void SkinFrom3DS( const char *filename ){ - polyset_t *psets; - char name[1024]; - int numPolysets; - int i; - - _3DS_LoadPolysets( filename, &psets, &numPolysets, g_verbose ); - - for ( i = 0; i < numPolysets; i++ ) - { -/* - if ( strstr( filename, gamedir + 1 ) ) - { - strcpy( name, strstr( filename, gamedir + 1 ) + strlen( gamedir ) - 1 ); - } - else - { - strcpy( name, filename ); - } - - StripFilename( name ); - */ - strcpy( name, psets[i].materialname ); - strcpy( g_data.surfData[i].shaders[g_data.surfData[i].header.numShaders].name, name ); - - g_data.surfData[i].header.numShaders++; - } - - free( psets[0].triangles ); - free( psets ); -} - -void Cmd_Skin( void ){ - char skinfile[1024]; - - if ( g_data.type == MD3_TYPE_BASE3DS ) { - GetToken( false ); - - sprintf( skinfile, "%s/%s", g_cddir, token ); - - if ( strstr( token, ".3ds" ) || strstr( token, ".3DS" ) ) { - SkinFrom3DS( skinfile ); - } - else - { - Error( "Unknown file format for $skin '%s'\n", skinfile ); - } - } - else - { - Error( "invalid model type while processing $skin" ); - } - - g_data.model.numSkins++; -} - -/* - ================= - Cmd_SpriteShader - ================= - - This routine is also called for $oldskin - - */ -void Cmd_SpriteShader(){ - GetToken( false ); - strcpy( g_data.surfData[0].shaders[g_data.surfData[0].header.numShaders].name, token ); - g_data.surfData[0].header.numShaders++; - g_data.model.numSkins++; -} - -/* - ================= - Cmd_Origin - ================= - */ -void Cmd_Origin( void ){ - // rotate points into frame of reference so model points down the - // positive x axis - // FIXME: use alias native coordinate system - GetToken( false ); - g_data.adjust[1] = -atof( token ); - - GetToken( false ); - g_data.adjust[0] = atof( token ); - - GetToken( false ); - g_data.adjust[2] = -atof( token ); -} - - -/* - ================= - Cmd_ScaleUp - ================= - */ -void Cmd_ScaleUp( void ){ - GetToken( false ); - g_data.scale_up = atof( token ); - if ( g_skipmodel || g_release || g_archive ) { - return; - } - - printf( "Scale up: %f\n", g_data.scale_up ); -} - - -/* - ================= - Cmd_Skinsize - - Set a skin size other than the default - QUAKE3: not needed - ================= - */ -void Cmd_Skinsize( void ){ - GetToken( false ); - g_data.fixedwidth = atoi( token ); - GetToken( false ); - g_data.fixedheight = atoi( token ); -} - -/* - ================= - Cmd_Modelname - - Begin creating a model of the given name - ================= - */ -void Cmd_Modelname( void ){ - FinishModel( TYPE_UNKNOWN ); - ClearModel(); - - GetToken( false ); - strcpy( g_modelname, token ); - path_set_extension( g_modelname, ".md3" ); - strcpy( g_data.model.name, g_modelname ); -} - -/* - =============== - fCmd_Cd - =============== - */ -void Cmd_Cd( void ){ - if ( g_cddir[0] ) { - Error( "$cd command without a $modelname" ); - } - - GetToken( false ); - - sprintf( g_cddir, "%s%s", gamedir, token ); - - // if -only was specified and this cd doesn't match, - // skip the model (you only need to match leading chars, - // so you could regrab all monsters with -only models/monsters) - if ( !g_only[0] ) { - return; - } - if ( !strEqualPrefix( token, g_only ) ) { - g_skipmodel = true; - printf( "skipping %s\n", token ); - } -} - -void Convert3DStoMD3( const char *file ){ - LoadBase( file ); - GrabFrame( file ); - SkinFrom3DS( file ); - - strcpy( g_data.model.name, g_modelname ); - - FinishModel( TYPE_UNKNOWN ); - ClearModel(); -} - -/* -** Cmd_3DSConvert -*/ -void Cmd_3DSConvert(){ - char file[1024]; - - FinishModel( TYPE_UNKNOWN ); - ClearModel(); - - GetToken( false ); - - sprintf( file, "%s%s", gamedir, token ); - strcpy( g_modelname, token ); - path_set_extension( g_modelname, ".md3" ); - - if ( FileTime( file ) == -1 ) { - Error( "%s doesn't exist", file ); - } - - if ( TokenAvailable() ) { - GetToken( false ); - g_data.scale_up = atof( token ); - } - - Convert3DStoMD3( file ); -} - -static void ConvertASE( const char *filename, int type, bool grabAnims ); - -/* -** Cmd_ASEConvert -*/ -void Cmd_ASEConvert( bool grabAnims ){ - char filename[1024]; - int type = TYPE_ITEM; - - FinishModel( TYPE_UNKNOWN ); - ClearModel(); - - GetToken( false ); - sprintf( filename, "%s%s", gamedir, token ); - - strcpy( g_modelname, token ); - path_set_extension( g_modelname, ".md3" ); - strcpy( g_data.model.name, g_modelname ); - - if ( !strstr( filename, ".ase" ) && !strstr( filename, ".ASE" ) ) { - strcat( filename, ".ASE" ); - } - - g_data.maxSurfaceTris = MAX_SURFACE_TRIS - 1; - - while ( TokenAvailable() ) - { - GetToken( false ); - if ( !strcmp( token, "-origin" ) ) { - if ( !TokenAvailable() ) { - Error( "missing parameter for -origin" ); - } - GetToken( false ); - g_data.aseAdjust[1] = -atof( token ); - - if ( !TokenAvailable() ) { - Error( "missing parameter for -origin" ); - } - GetToken( false ); - g_data.aseAdjust[0] = atof( token ); - - if ( !TokenAvailable() ) { - Error( "missing parameter for -origin" ); - } - GetToken( false ); - g_data.aseAdjust[2] = -atof( token ); - } - else if ( !strcmp( token, "-lod" ) ) { - if ( !TokenAvailable() ) { - Error( "No parameter for -lod" ); - } - GetToken( false ); - g_data.currentLod = atoi( token ); - if ( g_data.currentLod > MD3_MAX_LODS - 1 ) { - Error( "-lod parameter too large! (%d)\n", g_data.currentLod ); - } - - if ( !TokenAvailable() ) { - Error( "No second parameter for -lod" ); - } - GetToken( false ); - g_data.lodBias = atof( token ); - } - else if ( !strcmp( token, "-maxtris" ) ) { - if ( !TokenAvailable() ) { - Error( "No parameter for -maxtris" ); - } - GetToken( false ); - g_data.maxSurfaceTris = atoi( token ); - } - else if ( !strcmp( token, "-playerparms" ) ) { - if ( !TokenAvailable() ) { - Error( "missing skip start parameter for -playerparms" ); - } - GetToken( false ); - g_data.lowerSkipFrameStart = atoi( token ); - -#if 0 - if ( !TokenAvailable() ) { - Error( "missing skip end parameter for -playerparms" ); - } - GetToken( false ); - g_data.lowerSkipFrameEnd = atoi( token ); -#endif - - if ( !TokenAvailable() ) { - Error( "missing upper parameter for -playerparms" ); - } - GetToken( false ); - g_data.maxUpperFrames = atoi( token ); - - g_data.lowerSkipFrameEnd = g_data.maxUpperFrames - 1; - -#if 0 - if ( !TokenAvailable() ) { - Error( "missing head parameter for -playerparms" ); - } - GetToken( false ); - g_data.maxHeadFrames = atoi( token ); -#endif - g_data.maxHeadFrames = 1; - - if ( type != TYPE_ITEM ) { - Error( "invalid argument" ); - } - - type = TYPE_PLAYER; - } - else if ( !strcmp( token, "-weapon" ) ) { - if ( type != TYPE_ITEM ) { - Error( "invalid argument" ); - } - - type = TYPE_WEAPON; - } - } - - g_data.type = MD3_TYPE_ASE; - - if ( type == TYPE_WEAPON && grabAnims ) { - Error( "can't grab anims with weapon models" ); - } - if ( type == TYPE_PLAYER && !grabAnims ) { - Error( "player models must be converted with $aseanimconvert" ); - } - - if ( type == TYPE_WEAPON ) { - ConvertASE( filename, type, false ); - ConvertASE( filename, TYPE_HAND, true ); - } - else - { - ConvertASE( filename, type, grabAnims ); - } -} - -static int GetSurfaceAnimations( SurfaceAnimation_t sanims[MAX_ANIM_SURFACES], - const char *part, - int skipFrameStart, - int skipFrameEnd, - int maxFrames ){ - int numSurfaces; - int numValidSurfaces; - int i; - int numFrames = -1; - - if ( ( numSurfaces = ASE_GetNumSurfaces() ) > MAX_ANIM_SURFACES ) { - Error( "Too many surfaces in ASE" ); - } - - for ( numValidSurfaces = 0, i = 0; i < numSurfaces; i++ ) - { - polyset_t *splitSets; - int numNewFrames; - const char *surfaceName = ASE_GetSurfaceName( i ); - - if ( !surfaceName ) { - continue; -// Error( "Missing animation frames in model" ); - } - - if ( strstr( surfaceName, "tag_" ) || - !strcmp( part, "any" ) || - ( strstr( surfaceName, part ) == surfaceName ) ) { - - // skip this if it's an inappropriate tag - if ( strcmp( part, "any" ) ) { - // ignore non-"tag_head" tags if this is the head - if ( !strcmp( part, "h_" ) && strstr( surfaceName, "tag_" ) && strcmp( surfaceName, "tag_head" ) ) { - continue; - } - // ignore "tag_head" if this is the legs - if ( !strcmp( part, "l_" ) && !strcmp( surfaceName, "tag_head" ) ) { - continue; - } - // ignore "tag_weapon" if this is the legs - if ( !strcmp( part, "l_" ) && !strcmp( surfaceName, "tag_weapon" ) ) { - continue; - } - } - - if ( ( sanims[numValidSurfaces].frames = ASE_GetSurfaceAnimation( i, &sanims[numValidSurfaces].numFrames, skipFrameStart, skipFrameEnd, maxFrames ) ) != 0 ) { - splitSets = Polyset_SplitSets( sanims[numValidSurfaces].frames, sanims[numValidSurfaces].numFrames, &numNewFrames, g_data.maxSurfaceTris ); - - if ( numFrames == -1 ) { - numFrames = sanims[numValidSurfaces].numFrames; - } - else if ( numFrames != sanims[numValidSurfaces].numFrames ) { - Error( "Different number of animation frames on surfaces" ); - } - - if ( sanims[numValidSurfaces].frames != splitSets ) { - int j; - - // free old data if we split the surfaces - for ( j = 0; j < sanims[numValidSurfaces].numFrames; j++ ) - { - free( sanims[numValidSurfaces].frames[j].triangles ); - free( sanims[numValidSurfaces].frames ); - } - - sanims[numValidSurfaces].frames = splitSets; - sanims[numValidSurfaces].numFrames = numNewFrames; - } - Polyset_SnapSets( sanims[numValidSurfaces].frames, sanims[numValidSurfaces].numFrames ); - Polyset_ComputeNormals( sanims[numValidSurfaces].frames, sanims[numValidSurfaces].numFrames ); - - numValidSurfaces++; - } - } - } - - return numValidSurfaces; -} - -static int SurfaceOrderToFrameOrder( SurfaceAnimation_t sanims[], ObjectAnimationFrame_t oanims[], int numSurfaces ){ - int i, s; - int numFrames = -1; - - /* - ** we have the data here arranged in surface order, now we need to convert it to - ** frame order - */ - for ( i = 0, s = 0; i < numSurfaces; i++ ) - { - int j; - - if ( sanims[i].frames ) { - if ( numFrames == -1 ) { - numFrames = sanims[i].numFrames; - } - else if ( numFrames != sanims[i].numFrames ) { - Error( "numFrames != sanims[i].numFrames (%d != %d)\n", numFrames, sanims[i].numFrames ); - } - - for ( j = 0; j < sanims[i].numFrames; j++ ) - { - oanims[j].surfaces[s] = &sanims[i].frames[j]; - oanims[j].numSurfaces = numSurfaces; - } - s++; - } - } - - return numFrames; -} - -static void BuildAnimationFromOAFs( const char *filename, ObjectAnimationFrame_t oanims[], int numFrames, int type ){ - int f, i, j, tagcount; - float *frameXyz; - float *frameNormals; - - g_data.model.numSurfaces = oanims[0].numSurfaces; - g_data.model.numFrames = numFrames; - if ( g_data.model.numFrames < 0 ) { - Error( "model.numFrames < 0" ); - } - if ( g_data.model.numFrames >= MD3_MAX_FRAMES ) { - Error( "model.numFrames >= MD3_MAX_FRAMES" ); - } - - // build base frame - BuildBaseFrame( filename, &oanims[0] ); - - // build animation frames - for ( f = 0; f < numFrames; f++ ) - { - ObjectAnimationFrame_t *pOAF = &oanims[f]; - bool parentTagExists = false; - md3Tag_t tagParent; - int numtags = 0; - md3Frame_t *fr; - - fr = &g_data.frames[f]; - - strcpy( fr->name, "(from ASE)" ); - - // scale and adjust frame - for ( i = 0; i < pOAF->numSurfaces; i++ ) - { - triangle_t *pTris = pOAF->surfaces[i]->triangles; - int t; - - for ( t = 0; t < pOAF->surfaces[i]->numtriangles; t++ ) - { - for ( j = 0; j < 3; j++ ) - { - int k; - - // scale and adjust - for ( k = 0 ; k < 3 ; k++ ) { - pTris[t].verts[j][k] = pTris[t].verts[j][k] * g_data.scale_up + - g_data.aseAdjust[k]; - - if ( pTris[t].verts[j][k] > 1023 || - pTris[t].verts[j][k] < -1023 ) { - Error( "Model extents too large" ); - } - } - } - } - } - - // - // find and count tags, locate parent tag - // - for ( i = 0; i < pOAF->numSurfaces; i++ ) - { - if ( strstr( pOAF->surfaces[i]->name, "tag_" ) == pOAF->surfaces[i]->name ) { - // ignore parent tags when grabbing a weapon model and this is the flash portion - if ( !strcmp( pOAF->surfaces[i]->name, "tag_parent" ) && strstr( filename, "_flash.md3" ) ) { - continue; - } - else if ( !strstr( filename, "_hand.md3" ) && ( - ( !strcmp( pOAF->surfaces[i]->name, "tag_parent" ) && !strstr( filename, "_flash.md3" ) ) || - ( !strcmp( pOAF->surfaces[i]->name, "tag_torso" ) && ( strstr( filename, "upper_" ) || strstr( filename, "upper.md3" ) ) ) || - ( !strcmp( pOAF->surfaces[i]->name, "tag_head" ) && ( strstr( filename, "head.md3" ) || strstr( filename, "head_" ) ) ) || - ( !strcmp( pOAF->surfaces[i]->name, "tag_flash" ) && strstr( filename, "_flash.md3" ) ) || - ( !strcmp( pOAF->surfaces[i]->name, "tag_weapon" ) && type == TYPE_WEAPON ) ) ) { - float tri[3][3]; - - if ( parentTagExists ) { - Error( "Multiple parent tags not allowed" ); - } - - memcpy( tri[0], pOAF->surfaces[i]->triangles[0].verts[0], sizeof( float ) * 3 ); - memcpy( tri[1], pOAF->surfaces[i]->triangles[0].verts[1], sizeof( float ) * 3 ); - memcpy( tri[2], pOAF->surfaces[i]->triangles[0].verts[2], sizeof( float ) * 3 ); - - MD3_ComputeTagFromTri( &tagParent, tri ); - strcpy( tagParent.name, "tag_parent" ); - g_data.tags[f][numtags] = tagParent; - parentTagExists = true; - } - else - { - float tri[3][3]; - - memcpy( tri[0], pOAF->surfaces[i]->triangles[0].verts[0], sizeof( float ) * 3 ); - memcpy( tri[1], pOAF->surfaces[i]->triangles[0].verts[1], sizeof( float ) * 3 ); - memcpy( tri[2], pOAF->surfaces[i]->triangles[0].verts[2], sizeof( float ) * 3 ); - - MD3_ComputeTagFromTri( &g_data.tags[f][numtags], tri ); - strcpy( g_data.tags[f][numtags].name, pOAF->surfaces[i]->name ); - if ( strstr( g_data.tags[f][numtags].name, "tag_flash" ) ) { - *( strstr( g_data.tags[f][numtags].name, "tag_flash" ) + strlen( "tag_flash" ) ) = 0; - } - } - - numtags++; - } - - if ( strcmp( pOAF->surfaces[i]->name, g_data.surfData[i].header.name ) ) { - Error( "Mismatched surfaces from base('%s') to frame('%s') in model '%s'\n", g_data.surfData[i].header.name, pOAF->surfaces[i]->name, filename ); - } - } - - if ( numtags != g_data.model.numTags ) { - Error( "mismatched number of tags in frame(%d) vs. base(%d)", numtags, g_data.model.numTags ); - } - - // - // prepare to accumulate bounds and normals - // - ClearBounds( fr->bounds[0], fr->bounds[1] ); - - // - // store the frame's vertices in the same order as the base. This assumes the - // triangles and vertices in this frame are in exactly the same order as in the - // base - // - for ( i = 0, tagcount = 0; i < pOAF->numSurfaces; i++ ) - { - int t; - triangle_t *pTris = pOAF->surfaces[i]->triangles; - - // - // parent tag adjust - // - if ( parentTagExists ) { - for ( t = 0; t < pOAF->surfaces[i]->numtriangles; t++ ) - { - for ( j = 0; j < 3 ; j++ ) - { - vec3_t tmp; - - VectorSubtract( pTris[t].verts[j], tagParent.origin, tmp ); - - pTris[t].verts[j][0] = DotProduct( tmp, tagParent.axis[0] ); - pTris[t].verts[j][1] = DotProduct( tmp, tagParent.axis[1] ); - pTris[t].verts[j][2] = DotProduct( tmp, tagParent.axis[2] ); - - VectorCopy( pTris[t].normals[j], tmp ); - pTris[t].normals[j][0] = DotProduct( tmp, tagParent.axis[0] ); - pTris[t].normals[j][1] = DotProduct( tmp, tagParent.axis[1] ); - pTris[t].normals[j][2] = DotProduct( tmp, tagParent.axis[2] ); - } - } - } - - // - // compute tag data - // - if ( strstr( pOAF->surfaces[i]->name, "tag_" ) == pOAF->surfaces[i]->name ) { - md3Tag_t *pTag = &g_data.tags[f][tagcount]; - float tri[3][3]; - - strcpy( pTag->name, pOAF->surfaces[i]->name ); - - memcpy( tri[0], pTris[0].verts[0], sizeof( float ) * 3 ); - memcpy( tri[1], pTris[0].verts[1], sizeof( float ) * 3 ); - memcpy( tri[2], pTris[0].verts[2], sizeof( float ) * 3 ); - - MD3_ComputeTagFromTri( pTag, tri ); - tagcount++; - } - else - { - if ( g_data.surfData[i].verts[f] ) { - free( g_data.surfData[i].verts[f] ); - } - frameXyz = g_data.surfData[i].verts[f] = safe_calloc( sizeof( float ) * 6 * g_data.surfData[i].header.numVerts ); - frameNormals = frameXyz + 3; - - for ( t = 0; t < pOAF->surfaces[i]->numtriangles; t++ ) - { - for ( j = 0; j < 3 ; j++ ) - { - int index; - - index = g_data.surfData[i].baseTriangles[t].v[j].index; - frameXyz[index * 6 + 0] = pTris[t].verts[j][0]; - frameXyz[index * 6 + 1] = pTris[t].verts[j][1]; - frameXyz[index * 6 + 2] = pTris[t].verts[j][2]; - frameNormals[index * 6 + 0] = pTris[t].normals[j][0]; - frameNormals[index * 6 + 1] = pTris[t].normals[j][1]; - frameNormals[index * 6 + 2] = pTris[t].normals[j][2]; - AddPointToBounds( &frameXyz[index * 6], fr->bounds[0], fr->bounds[1] ); - } - } - } - } - } - - if ( strstr( filename, gamedir + 1 ) ) { - strcpy( g_modelname, strstr( filename, gamedir + 1 ) + strlen( gamedir ) - 1 ); - } - else - { - strcpy( g_modelname, filename ); - } - - FinishModel( type ); - ClearModel(); -} - -static void ConvertASE( const char *filename, int type, bool grabAnims ){ - int i, j; - int numSurfaces; - int numFrames = -1; - SurfaceAnimation_t surfaceAnimations[MAX_ANIM_SURFACES]; - ObjectAnimationFrame_t objectAnimationFrames[MAX_ANIM_FRAMES]; - char outfilename[1024]; - - /* - ** load ASE into memory - */ - ASE_Load( filename, g_verbose, grabAnims ); - - /* - ** process parts - */ - if ( type == TYPE_ITEM ) { - numSurfaces = GetSurfaceAnimations( surfaceAnimations, "any", -1, -1, -1 ); - - if ( numSurfaces <= 0 ) { - Error( "numSurfaces <= 0" ); - } - - numFrames = SurfaceOrderToFrameOrder( surfaceAnimations, objectAnimationFrames, numSurfaces ); - - if ( numFrames <= 0 ) { - Error( "numFrames <= 0" ); - } - - strcpy( outfilename, filename ); - path_set_extension( outfilename, ".md3" ); - BuildAnimationFromOAFs( outfilename, objectAnimationFrames, numFrames, type ); - - // free memory - for ( i = 0; i < numSurfaces; i++ ) - { - if ( surfaceAnimations[i].frames ) { - for ( j = 0; j < surfaceAnimations[i].numFrames; j++ ) - { - free( surfaceAnimations[i].frames[j].triangles ); - } - free( surfaceAnimations[i].frames ); - surfaceAnimations[i].frames = 0; - } - } - } - else if ( type == TYPE_PLAYER ) { - bool tagTorso = false; - bool tagHead = false; - bool tagWeapon = false; - - // - // verify that all necessary tags exist - // - numSurfaces = ASE_GetNumSurfaces(); - for ( i = 0; i < numSurfaces; i++ ) - { - if ( !strcmp( ASE_GetSurfaceName( i ), "tag_head" ) ) { - tagHead = true; - } - if ( !strcmp( ASE_GetSurfaceName( i ), "tag_torso" ) ) { - tagTorso = true; - } - if ( !strcmp( ASE_GetSurfaceName( i ), "tag_weapon" ) ) { - tagWeapon = true; - } - } - - if ( !tagWeapon ) { - Error( "Missing tag_weapon!" ); - } - if ( !tagTorso ) { - Error( "Missing tag_torso!" ); - } - if ( !tagWeapon ) { - Error( "Missing tag_weapon!" ); - } - - // get all upper body surfaces - numSurfaces = GetSurfaceAnimations( surfaceAnimations, "u_", -1, -1, g_data.maxUpperFrames ); - numFrames = SurfaceOrderToFrameOrder( surfaceAnimations, objectAnimationFrames, numSurfaces ); - strcpy( outfilename, filename ); - StripFilename( outfilename ); - - if ( g_data.currentLod == 0 ) { - strcat( outfilename, "upper.md3" ); - } - else - { - char temp[128]; - - sprintf( temp, "upper_%d.md3", g_data.currentLod ); - strcat( outfilename, temp ); - } - - BuildAnimationFromOAFs( outfilename, objectAnimationFrames, numFrames, type ); - - // free memory - for ( i = 0; i < numSurfaces; i++ ) - { - if ( surfaceAnimations[i].frames ) { - for ( j = 0; j < surfaceAnimations[i].numFrames; j++ ) - { - free( surfaceAnimations[i].frames[j].triangles ); - } - free( surfaceAnimations[i].frames ); - surfaceAnimations[i].frames = 0; - } - } - - // get lower body surfaces - numSurfaces = GetSurfaceAnimations( surfaceAnimations, "l_", g_data.lowerSkipFrameStart, g_data.lowerSkipFrameEnd, -1 ); - numFrames = SurfaceOrderToFrameOrder( surfaceAnimations, objectAnimationFrames, numSurfaces ); - strcpy( outfilename, filename ); - StripFilename( outfilename ); - - if ( g_data.currentLod == 0 ) { - strcat( outfilename, "lower.md3" ); - } - else - { - char temp[128]; - - sprintf( temp, "lower_%d.md3", g_data.currentLod ); - strcat( outfilename, temp ); - } - BuildAnimationFromOAFs( outfilename, objectAnimationFrames, numFrames, type ); - - // free memory - for ( i = 0; i < numSurfaces; i++ ) - { - if ( surfaceAnimations[i].frames ) { - for ( j = 0; j < surfaceAnimations[i].numFrames; j++ ) - { - free( surfaceAnimations[i].frames[j].triangles ); - } - free( surfaceAnimations[i].frames ); - surfaceAnimations[i].frames = 0; - } - } - - // get head surfaces - numSurfaces = GetSurfaceAnimations( surfaceAnimations, "h_", -1, -1, g_data.maxHeadFrames ); - numFrames = SurfaceOrderToFrameOrder( surfaceAnimations, objectAnimationFrames, numSurfaces ); - strcpy( outfilename, filename ); - StripFilename( outfilename ); - - if ( g_data.currentLod == 0 ) { - strcat( outfilename, "head.md3" ); - } - else - { - char temp[128]; - - sprintf( temp, "head_%d.md3", g_data.currentLod ); - strcat( outfilename, temp ); - } - BuildAnimationFromOAFs( outfilename, objectAnimationFrames, numFrames, type ); - - // free memory - for ( i = 0; i < numSurfaces; i++ ) - { - if ( surfaceAnimations[i].frames ) { - for ( j = 0; j < surfaceAnimations[i].numFrames; j++ ) - { - free( surfaceAnimations[i].frames[j].triangles ); - } - free( surfaceAnimations[i].frames ); - surfaceAnimations[i].frames = 0; - } - } - } - else if ( type == TYPE_WEAPON ) { - // get the weapon surfaces - numSurfaces = GetSurfaceAnimations( surfaceAnimations, "w_", -1, -1, -1 ); - numFrames = SurfaceOrderToFrameOrder( surfaceAnimations, objectAnimationFrames, numSurfaces ); - - strcpy( outfilename, filename ); - path_set_extension( outfilename, ".md3" ); - BuildAnimationFromOAFs( outfilename, objectAnimationFrames, numFrames, type ); - - // free memory - for ( i = 0; i < numSurfaces; i++ ) - { - if ( surfaceAnimations[i].frames ) { - for ( j = 0; j < surfaceAnimations[i].numFrames; j++ ) - { - free( surfaceAnimations[i].frames[j].triangles ); - } - free( surfaceAnimations[i].frames ); - surfaceAnimations[i].frames = 0; - } - } - - // get the flash surfaces - numSurfaces = GetSurfaceAnimations( surfaceAnimations, "f_", -1, -1, -1 ); - numFrames = SurfaceOrderToFrameOrder( surfaceAnimations, objectAnimationFrames, numSurfaces ); - - strcpy( outfilename, filename ); - path_set_extension( outfilename, "_flash.md3" ); - BuildAnimationFromOAFs( outfilename, objectAnimationFrames, numFrames, TYPE_ITEM ); - - // free memory - for ( i = 0; i < numSurfaces; i++ ) - { - if ( surfaceAnimations[i].frames ) { - for ( j = 0; j < surfaceAnimations[i].numFrames; j++ ) - { - free( surfaceAnimations[i].frames[j].triangles ); - } - free( surfaceAnimations[i].frames ); - surfaceAnimations[i].frames = 0; - } - } - } - else if ( type == TYPE_HAND ) { - // get the hand tags - numSurfaces = GetSurfaceAnimations( surfaceAnimations, "tag_", -1, -1, -1 ); - numFrames = SurfaceOrderToFrameOrder( surfaceAnimations, objectAnimationFrames, numSurfaces ); - - strcpy( outfilename, filename ); - path_set_extension( outfilename, "_hand.md3" ); - BuildAnimationFromOAFs( outfilename, objectAnimationFrames, numFrames, TYPE_HAND ); - - // free memory - for ( i = 0; i < numSurfaces; i++ ) - { - if ( surfaceAnimations[i].frames ) { - for ( j = 0; j < surfaceAnimations[i].numFrames; j++ ) - { - free( surfaceAnimations[i].frames[j].triangles ); - } - free( surfaceAnimations[i].frames ); - surfaceAnimations[i].frames = 0; - } - } - } - else - { - Error( "Unknown type passed to ConvertASE()" ); - } - - g_data.currentLod = 0; - g_data.lodBias = 0; - g_data.maxHeadFrames = 0; - g_data.maxUpperFrames = 0; - g_data.lowerSkipFrameStart = 0; - g_data.lowerSkipFrameEnd = 0; - VectorCopy( vec3_origin, g_data.aseAdjust ); - - // unload ASE from memory - ASE_Free(); -} diff --git a/tools/quake3/q3data/oldstuff.cpp b/tools/quake3/q3data/oldstuff.cpp deleted file mode 100644 index 2789b94c..00000000 --- a/tools/quake3/q3data/oldstuff.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#if 0 - -/* -** ReindexTriangle -** -** Given a triangle_t, find which indices match into the associated -** surface's base triangles. -*/ -static void ReindexTriangle( int surfno, triangle_t *pTri, int indices[3] ){ - int t, i; - md3SurfaceData_t *pSurfData = &g_data.surfData[surfno]; - int matches[3][3]; - int numMatches = 0; - - - indices[0] = -1; - indices[1] = -1; - indices[2] = -1; - - for ( i = 0; i < 3; i++ ) - { - numMatches = 0; - - matches[i][0] = -1; - matches[i][1] = -1; - matches[i][2] = -1; - - for ( t = 0; t < pSurfData->header.numVerts; t++ ) - { - if ( !VectorCompare( pTri->verts[i], pSurfData->baseVertexes[t].xyz ) ) { - continue; - } - -/* - if ( !VectorCompare( pTri->normals[i], pSurfData->baseVertexes[t].normal ) ) - continue; - if ( pTri->texcoords[i][0] != pSurfData->baseVertexes[t].st[0] ) - continue; - if ( pTri->texcoords[i][1] != pSurfData->baseVertexes[t].st[1] ) - continue; - */ - - matches[i][numMatches++] = t; - } - - if ( indices[i] == -1 ) { -// Error( "Could not ReindexTriangle, vertex not found" ); - } - } - -#if 0 - for ( t = 0; t < psets[i].numtriangles; t++ ) - { - int b; - - bTri = &g_data.surfData[i].baseTriangles[t]; - - for ( j = 0 ; j < 3 ; j++ ) - { - bVert = &bTri->v[j]; - - // get the xyz index - for ( k = 0; k < g_data.surfData[i].header.numVerts; k++ ) - { - if ( ( g_data.surfData[i].baseVertexes[k].st[0] == bVert->st[0] ) && - ( g_data.surfData[i].baseVertexes[k].st[1] == bVert->st[1] ) && - ( VectorCompare( bVert->xyz, g_data.surfData[i].baseVertexes[k].xyz ) ) && - ( VectorCompare( bVert->normal, g_data.surfData[i].baseVertexes[k].normal ) ) ) { - break; // this vertex is already in the base vertex list - } - } - - if ( k == g_data.surfData[i].header.numVerts ) { // new index - g_data.surfData[i].baseVertexes[g_data.surfData[i].header.numVerts] = *bVert; - g_data.surfData[i].header.numVerts++; - } - - bVert->index = k; - } - } -#endif -} - -const char *FindFrameFile( const char *frame ){ - int time1; - char file1[1024]; - static char retname[1024]; - char base[32]; - char suffix[32]; - const char *s; - - if ( strchr( frame, '.' ) ) { - return frame; // already in dot format - - } - // split 'run1' into 'run' and '1' - s = frame + strlen( frame ) - 1; - - while ( s != frame && *s >= '0' && *s <= '9' ) - s--; - - strcpy( suffix, s + 1 ); - strcpy( base, frame ); - base[s - frame + 1] = 0; - - // check for 'run1.tri' - sprintf( file1, "%s/%s%s.tri", g_cddir, base, suffix ); - time1 = FileTime( file1 ); - if ( time1 != -1 ) { - sprintf( retname, "%s%s.tri", base, suffix ); - return retname; - } - - // check for 'run.1' - sprintf( file1, "%s/%s.%s",g_cddir, base, suffix ); - time1 = FileTime( file1 ); - if ( time1 != -1 ) { - sprintf( retname, "%s.%s", base, suffix ); - return retname; - } - - Error( "frame %s could not be found",frame ); - return NULL; -} - -#endif diff --git a/tools/quake3/q3data/p3dlib.cpp b/tools/quake3/q3data/p3dlib.cpp deleted file mode 100644 index 27bc8fc5..00000000 --- a/tools/quake3/q3data/p3dlib.cpp +++ /dev/null @@ -1,316 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "p3dlib.h" - -#include -#include -#include - -#include "../common/cmdlib.h" -#include "../common/qstringops.h" -#include "../common/qpathops.h" - -#define MAX_POLYSETS 64 - -typedef struct -{ - long len; - - int numPairs; - char polysetNames[MAX_POLYSETS][256]; - char shaders[MAX_POLYSETS][256]; - - char *buffer, *curpos; -} p3d_t; - -static p3d_t p3d; - -static int P3DProcess(); -static int P3DGetToken( int restOfLine ); - -static char s_token[1024]; -static int s_curpair; - -/* -** P3DLoad -** -*/ -int P3DLoad( const char *filename ){ - FILE *fp = fopen( filename, "rb" ); - - if ( !fp ) { - return 0; - } - - memset( &p3d, 0, sizeof( p3d ) ); - - p3d.len = Q_filelength( fp ); - - p3d.curpos = p3d.buffer = safe_malloc( p3d.len ); - - if ( fread( p3d.buffer, p3d.len, 1, fp ) != 1 ) { - fclose( fp ); - return 0; - } - - fclose( fp ); - - return P3DProcess(); -} - -/* -** P3DClose -** -*/ -void P3DClose(){ - if ( p3d.buffer ) { - free( p3d.buffer ); - p3d.buffer = 0; - } -} - -int CharIsTokenDelimiter( int ch ){ - if ( ch <= 32 ) { - return 1; - } - return 0; -} - -int P3DSkipToToken( const char *name ){ - while ( P3DGetToken( 0 ) ) - { - if ( striEqual( s_token, name ) ) { - return 1; - } - } - - return 0; -} - -/* -** P3DGetToken -** -*/ -int P3DGetToken( int restOfLine ){ - int i = 0; - - if ( p3d.buffer == 0 ) { - return 0; - } - - if ( ( p3d.curpos - p3d.buffer ) == p3d.len ) { - return 0; - } - - // skip over crap - while ( ( ( p3d.curpos - p3d.buffer ) < p3d.len ) && - ( *p3d.curpos <= 32 ) ) - { - p3d.curpos++; - } - - while ( ( p3d.curpos - p3d.buffer ) < p3d.len ) - { - s_token[i] = *p3d.curpos; - - p3d.curpos++; - i++; - - if ( ( CharIsTokenDelimiter( s_token[i - 1] ) && !restOfLine ) || - ( ( s_token[i - 1] == '\n' ) ) ) { - s_token[i - 1] = 0; - break; - } - } - - s_token[i] = 0; - - return 1; -} - -int P3DGetNextPair( char **psetName, char **associatedShader ){ - if ( s_curpair < p3d.numPairs ) { - *psetName = p3d.polysetNames[s_curpair]; - *associatedShader = p3d.shaders[s_curpair]; - s_curpair++; - return 1; - } - - return 0; -} - -int P3DSkipToTokenInBlock( const char *name ){ - int iLevel = 0; - - while ( P3DGetToken( 0 ) ) - { - if ( strEqual( s_token, "}" ) ) { - iLevel--; - } - else if ( strEqual( s_token, "{" ) ) { - iLevel++; - } - - if ( striEqual( s_token, name ) ) { - return 1; - } - - if ( iLevel == 0 ) { - return 0; - } - } - - return 0; -} - -/* -** P3DProcess -** -** Nothing fancy here. -*/ -int P3DProcess(){ - - s_curpair = 0; - - // first token should be a string - P3DGetToken( 1 ); // Voodoo Ascii File - - // skip to the first Obj declaration - while ( P3DGetToken( 0 ) ) - { - if ( striEqual( s_token, "Obj" ) ) { - int j = 0, k = 0; - - if ( P3DSkipToToken( "Text" ) ) { - if ( P3DSkipToTokenInBlock( "TMap" ) ) { - if ( !P3DSkipToToken( "Path" ) ) { - return 0; - } - - if ( !P3DGetToken( 1 ) ) { - return 0; - } - - while ( s_token[j] != 0 ) - { - if ( s_token[j] == '\\' ) { - j++; - p3d.shaders[p3d.numPairs][k] = '/'; - } - else - { - p3d.shaders[p3d.numPairs][k] = s_token[j]; - } - j++; - k++; - } - p3d.shaders[p3d.numPairs][k] = 0; - - StripExtension( p3d.shaders[p3d.numPairs] ); - - // - // skip to the end of the Object and grab its name - // - if ( !P3DSkipToToken( "Name" ) ) { - return 0; - } - - if ( P3DGetToken( 0 ) ) { - // strip off leading 'Obj_' if it exists - if ( strstr( s_token, "Obj_" ) == s_token ) { - strcpy( p3d.polysetNames[p3d.numPairs], s_token + strlen( "Obj_" ) ); - } - else{ - strcpy( p3d.polysetNames[p3d.numPairs], s_token ); - } - - // strip off trailing unused color information -// if ( strrchr( p3d.polysetNames[p3d.numPairs], '_' ) != 0 ) -// *strrchr( p3d.polysetNames[p3d.numPairs], '_' ) = 0; - - p3d.numPairs++; - } - else - { - return 0; - } - } - } - } - } - - s_curpair = 0; - - return 1; -} - -#if 0 -void SkinFromP3D( const char *file ){ - char filename[1024]; - char *psetName, *associatedShader; - - /* - ** a P3D file contains a list of polysets, each with a list of associated - ** texture names that constitute it's - ** - ** Thus: - ** - ** P3D file -> skin - ** polyset -> polyset - ** texture -> texture.SHADER becomes polyset's shader - */ - sprintf( filename, "%s/%s", g_cddir, file ); - - if ( !P3DLoad( filename ) ) { - Error( "unable to load '%s'", filename ); - } - - while ( P3DGetNextPair( &psetName, &associatedShader ) ) - { - int i; - - // find the polyset in the object that this particular pset/shader pair - // corresponds to and append the shader to it - for ( i = 0; i < g_data.model.numSurfaces; i++ ) - { - if ( striEqual( g_data.surfData[i].header.name, psetName ) ) { - char *p; - - if ( strstr( associatedShader, gamedir + 1 ) ) { - p = strstr( associatedShader, gamedir + 1 ) + strlen( gamedir ) - 1; - } - else - { - p = associatedShader; - } - - strcpy( g_data.surfData[i].shaders[g_data.surfData[i].header.numShaders].name, p ); - - g_data.surfData[i].header.numShaders++; - } - } - - } - - P3DClose(); -} -#endif diff --git a/tools/quake3/q3data/p3dlib.h b/tools/quake3/q3data/p3dlib.h deleted file mode 100644 index 4b2fcf19..00000000 --- a/tools/quake3/q3data/p3dlib.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#define P3D_GET_CROSSLINE 1 -#define P3D_GET_RESTOFLINE 2 - -int P3DLoad( const char *filename ); -void P3DClose(); - -int P3DGetNextPair( char **name, char **associatedShader ); diff --git a/tools/quake3/q3data/polyset.cpp b/tools/quake3/q3data/polyset.cpp deleted file mode 100644 index 469aca1b..00000000 --- a/tools/quake3/q3data/polyset.cpp +++ /dev/null @@ -1,267 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "q3data.h" - -polyset_t *Polyset_SplitSets( polyset_t *psets, int numpolysets, int *pNumNewPolysets, int maxTris ){ - int p, np, op; - int numNewPolysets = 0; - int numSplitPolysets = 0; - polyset_t *newpsets; - int sumTriangles = 0; - - for ( p = 0; p < numpolysets; p++ ) - { - numNewPolysets += psets[p].numtriangles / maxTris + 1; - } - - if ( numNewPolysets == numpolysets ) { - return psets; - } - - printf( "Warning: creating %d polysets from input of %d polysets\n", numNewPolysets, numpolysets ); - - newpsets = safe_calloc( sizeof( polyset_t ) * numNewPolysets ); - - for ( np = 0, op = 0; op < numpolysets; op++ ) - { - numSplitPolysets = ( psets[op].numtriangles / ( maxTris + 1 ) ) + 1; - if ( numSplitPolysets == 1 ) { - memcpy( &newpsets[np], &psets[op], sizeof( polyset_t ) ); - np++; - } - else - { - sumTriangles = 0; - - // split this pset into multiple smaller psets - for ( p = 0; p < numSplitPolysets; p++, np++ ) - { - memcpy( &newpsets[np], &psets[op], sizeof( polyset_t ) ); - - newpsets[np].triangles = psets[op].triangles + sumTriangles; - - if ( sumTriangles + maxTris > psets[op].numtriangles ) { - newpsets[np].numtriangles = psets[op].numtriangles - sumTriangles; - } - else{ - newpsets[np].numtriangles = maxTris; - } - - sumTriangles += newpsets[np].numtriangles; - } - } - } - - *pNumNewPolysets = numNewPolysets; - - return newpsets; -} - -polyset_t *Polyset_LoadSets( const char *file, int *numpolysets, int maxTrisPerSet ){ - polyset_t *psets; - polyset_t *finalpsets; - - // - // load the frame - // - if ( path_extension_is( file, "3ds" ) ) { - _3DS_LoadPolysets( file, &psets, numpolysets, g_verbose ); - } - else{ - Error( "TRI files no longer supported" ); - } -// TRI_LoadPolysets( file, &psets, numpolysets ); - -/* - // - // scale polysets - // - for ( i = 0; i < psets; i++ ) - { - int j; - - for ( j = 0; j < psets[i].numtriangles; j++ ) - { - } - } - */ - - // - // split polysets if necessary - // - finalpsets = Polyset_SplitSets( psets, *numpolysets, numpolysets, maxTrisPerSet ); - - return finalpsets; -} - -polyset_t *Polyset_CollapseSets( polyset_t *psets, int numpolysets ){ - int p; - int sumtriangles = 0; - - polyset_t *oldpsets = psets; - - // - // no tag checking because this is an $oldbase and thus shouldn't have any - // tags - // - for ( p = 0; p < numpolysets; p++ ) - { - sumtriangles += oldpsets[p].numtriangles; - } - - psets = safe_calloc( sizeof( polyset_t ) ); - psets[0].numtriangles = sumtriangles; - psets[0].triangles = safe_malloc( MD3_MAX_TRIANGLES * sizeof( triangle_t ) ); - - // each call to "LoadPolysets" only allocates a single large chunk of - // triangle memory that is utilized by all the polysets loaded by - // that one call - memcpy( psets[0].triangles, oldpsets[0].triangles, sizeof( triangle_t ) * sumtriangles ); - - free( oldpsets[0].triangles ); - free( oldpsets ); - - return psets; -} - -static float SnapFloat( float x ){ - int ix; - - x *= 1.0f / MD3_XYZ_SCALE; - ix = ( int ) x; - x = ( float ) ix; - x *= MD3_XYZ_SCALE; - - return x; -} - -void Polyset_SnapSets( polyset_t *psets, int numpolysets ){ - int p; - - for ( p = 0; p < numpolysets; p++ ) - { - int t; - - for ( t = 0; t < psets[p].numtriangles; t++ ) - { - int v; - - for ( v = 0; v < 3; v++ ) - { - psets[p].triangles[t].verts[v][0] = SnapFloat( psets[p].triangles[t].verts[v][0] ); - psets[p].triangles[t].verts[v][1] = SnapFloat( psets[p].triangles[t].verts[v][1] ); - psets[p].triangles[t].verts[v][2] = SnapFloat( psets[p].triangles[t].verts[v][2] ); - } - } - } -} - -void Polyset_ComputeNormals( polyset_t *psets, int numpolysets ){ - int p; - int i, t; - int vertexIndex[MD3_MAX_TRIANGLES][3]; - vec3_t verts[MD3_MAX_VERTS]; - vec3_t normals[MD3_MAX_VERTS]; - vec3_t faceNormals[MD3_MAX_TRIANGLES]; - - // - // iterate through polysets - // - for ( p = 0; p < numpolysets; p++ ) - { - int numUniqueVertices = 0; - - assert( psets[p].numtriangles < MD3_MAX_TRIANGLES ); - - memset( vertexIndex, 0xff, sizeof( vertexIndex ) ); - memset( verts, 0, sizeof( verts ) ); - memset( normals, 0, sizeof( normals ) ); - - // - // unique vertices - // - for ( t = 0; t < psets[p].numtriangles; t++ ) - { - int j; - - for ( j = 0; j < 3; j++ ) - { - for ( i = 0; i < numUniqueVertices; i++ ) - { - if ( VectorCompare( psets[p].triangles[t].verts[j], verts[i] ) ) { - break; - } - } - if ( i == numUniqueVertices ) { - vertexIndex[t][j] = numUniqueVertices; - VectorCopy( ( psets[p].triangles[t].verts[j] ), ( verts[numUniqueVertices] ) ); - numUniqueVertices++; - } - else - { - vertexIndex[t][j] = i; - } - } - } - - // - // compute face normals - // - for ( t = 0; t < psets[p].numtriangles; t++ ) - { - vec3_t side0, side1, facenormal; - - VectorSubtract( psets[p].triangles[t].verts[0], psets[p].triangles[t].verts[1], side0 ); - VectorSubtract( psets[p].triangles[t].verts[2], psets[p].triangles[t].verts[1], side1 ); - - CrossProduct( side0, side1, facenormal ); - VectorNormalize( facenormal, faceNormals[t] ); - } - - // - // sum normals and copy them back - // - for ( i = 0; i < numUniqueVertices; i++ ) - { - for ( t = 0; t < psets[p].numtriangles; t++ ) - { - if ( vertexIndex[t][0] == i || - vertexIndex[t][1] == i || - vertexIndex[t][2] == i ) { - normals[i][0] += faceNormals[t][0]; - normals[i][1] += faceNormals[t][1]; - normals[i][2] += faceNormals[t][2]; - } - } - VectorNormalize( normals[i], normals[i] ); - } - - - for ( t = 0; t < psets[p].numtriangles; t++ ) - { - VectorCopy( normals[vertexIndex[t][0]], psets[p].triangles[t].normals[0] ); - VectorCopy( normals[vertexIndex[t][1]], psets[p].triangles[t].normals[1] ); - VectorCopy( normals[vertexIndex[t][2]], psets[p].triangles[t].normals[2] ); - } - } -} diff --git a/tools/quake3/q3data/q3data.cpp b/tools/quake3/q3data/q3data.cpp deleted file mode 100644 index 69d879af..00000000 --- a/tools/quake3/q3data/q3data.cpp +++ /dev/null @@ -1,644 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "q3data.h" -#include "md3lib.h" - -#include "vfs.h" - -bool g_verbose; -bool g_stripify = true; -bool g_release; // don't grab, copy output data to new tree -char g_releasedir[1024]; // c:\quake2\baseq2, etc -bool g_archive; // don't grab, copy source data to new tree -char g_only[256]; // if set, only grab this cd -bool g_skipmodel; // set true when a cd is not g_only - -// bogus externs for some TA hacks (common/ using them against q3map) -char *moddir = NULL; - -/* - ======================================================= - - PAK FILES - - ======================================================= - */ - -unsigned Com_BlockChecksum( void *buffer, int length ); - -typedef struct -{ - char name[56]; - int filepos, filelen; -} packfile_t; - -typedef struct -{ - char id[4]; - int dirofs; - int dirlen; -} packheader_t; - -packfile_t pfiles[16384]; -FILE *pakfile; -packfile_t *pf; -packheader_t pakheader; - -/* - ============== - ReleaseFile - - Filename should be gamedir relative. - Either copies the file to the release dir, or adds it to - the pak file. - ============== - */ -void ReleaseFile( char *filename ){ - char source[1024]; - char dest[1024]; - - if ( !g_release ) { - return; - } - - sprintf( source, "%s%s", gamedir, filename ); - sprintf( dest, "%s/%s", g_releasedir, filename ); - printf( "copying to %s\n", dest ); - QCopyFile( source, dest ); - return; -} - -typedef struct -{ - // shader - // opaque - // opaque 2 - // blend - // blend 2 - char names[5][1024]; - int num; -} ShaderFiles_t; - -ShaderFiles_t s_shaderFiles; - -void FindShaderFiles( char *filename ){ - char buffer[1024]; - char stripped[1024]; - char linebuffer[1024]; - int len, i; - char *buf; - const char *diffuseExtensions[] = - { - ".TGA", - ".WAL", - ".PCX", - 0 - }; - const char *otherExtensions[] = - { - ".specular.TGA", - ".blend.TGA", - ".alpha.TGA", - 0 - }; - - s_shaderFiles.num = 0; - - strcpy( stripped, filename ); - path_set_extension( stripped, ".shader" ); - - if ( FileExists( stripped ) ) { - char *p; - char mapa[512], mapb[512]; - - strcpy( s_shaderFiles.names[s_shaderFiles.num], stripped ); - s_shaderFiles.num++; - - // load and parse - len = LoadFile( stripped, (void **)&buf ); - - p = buf; - - while ( p - buf < len ) - { - i = 0; - - // skip spaces - while ( *p == ' ' || *p == '\n' || *p == '\t' ) - p++; - - // grab rest of the line - while ( *p != 0 && *p != '\n' ) - { - linebuffer[i] = *p; - i++; - p++; - } - if ( *p == '\n' ) { - p++; - } - linebuffer[i] = 0; - - strLower( linebuffer ); - - // see if the line specifies an opaque map or blendmap - if ( strstr( linebuffer, "opaquemap" ) == linebuffer || - strstr( linebuffer, "blendmap" ) == linebuffer ) { - int j; - - i = 0; - - mapa[0] = mapb[0] = 0; - - // skip past the keyword - while ( linebuffer[i] != ' ' && linebuffer[i] != '\t' && linebuffer[i] ) - i++; - // skip past spaces - while ( ( linebuffer[i] == ' ' || linebuffer[i] == '\t' ) && linebuffer[i] ) - i++; - - // grab first map name - j = 0; - while ( linebuffer[i] != ' ' && linebuffer[i] != '\t' && linebuffer[i] ) - { - mapa[j] = linebuffer[i]; - j++; - i++; - } - mapa[j] = 0; - - // skip past spaces - while ( ( linebuffer[i] == ' ' || linebuffer[i] == '\t' ) && linebuffer[i] ) - i++; - - // grab second map name - j = 0; - while ( linebuffer[i] != ' ' && linebuffer[i] != '\t' && linebuffer[i] ) - { - mapb[j] = linebuffer[i]; - j++; - i++; - } - mapb[j] = 0; - - // store map names - if ( mapa[0] != 0 && mapa[0] != '-' ) { - sprintf( s_shaderFiles.names[s_shaderFiles.num], "%s%s", gamedir, mapa ); - s_shaderFiles.num++; - } - if ( mapb[0] != 0 && mapb[0] != '-' && mapb[0] != '^' && mapb[0] != '*' ) { - sprintf( s_shaderFiles.names[s_shaderFiles.num], "%s%s", gamedir, mapb ); - s_shaderFiles.num++; - } - } - } - } - else - { - StripExtension( stripped ); - - // look for diffuse maps - for ( i = 0; i < 3; i++ ) - { - strcpy( buffer, stripped ); - strcat( buffer, diffuseExtensions[i] ); - if ( FileExists( buffer ) ) { - strcpy( s_shaderFiles.names[s_shaderFiles.num], buffer ); - s_shaderFiles.num++; - break; - } - } - for ( i = 0; i < 3; i++ ) - { - strcpy( buffer, stripped ); - strcat( buffer, otherExtensions[i] ); - if ( FileExists( buffer ) ) { - strcpy( s_shaderFiles.names[s_shaderFiles.num], buffer ); - s_shaderFiles.num++; - } - } - } -} - -/* - ============== - ReleaseShader - - Copies all needed files for a shader to the release directory - ============== - */ -void ReleaseShader( char *filename ){ - char fullpath[1024]; - char dest[1024]; - char stripped[1024]; - int i; - - sprintf( fullpath, "%s%s", gamedir, filename ); - - FindShaderFiles( fullpath ); - - for ( i = 0; i < s_shaderFiles.num; i++ ) - { - strcpy( stripped, s_shaderFiles.names[i] ); - if ( strstr( stripped, gamedir ) ) { - memmove( stripped, stripped + strlen( gamedir ), strlen( stripped ) ); - } - sprintf( dest, "%s/%s", g_releasedir, stripped ); - printf( "copying to %s\n", dest ); - QCopyFile( s_shaderFiles.names[i], dest ); - } -} - -/* - =============== - Cmd_File - - This is only used to cause a file to be copied during a release - build (default.cfg, maps, etc) - =============== - */ -void Cmd_File( void ){ - GetToken( false ); - ReleaseFile( token ); -} - -/* - =============== - PackDirectory_r - - =============== - */ -#ifdef WIN32 -#include "io.h" -void PackDirectory_r( char *dir ){ - struct _finddata_t fileinfo; - int handle; - char dirstring[1024]; - char filename[1024]; - - sprintf( dirstring, "%s%s/*.*", gamedir, dir ); - - handle = _findfirst( dirstring, &fileinfo ); - if ( handle == -1 ) { - return; - } - - do - { - sprintf( filename, "%s/%s", dir, fileinfo.name ); - if ( fileinfo.attrib & _A_SUBDIR ) { // directory - if ( fileinfo.name[0] != '.' ) { // don't pak . and .. - PackDirectory_r( filename ); - } - continue; - } - // copy or pack the file - ReleaseFile( filename ); - } while ( _findnext( handle, &fileinfo ) != -1 ); - - _findclose( handle ); -} -#else - -#include -#include - -void PackDirectory_r( char *dir ){ - struct dirent **namelist, *ent; - int count; - struct stat st; - int i; - char fullname[1024]; - char dirstring[1024]; - char *name; - - sprintf( dirstring, "%s%s", gamedir, dir ); - count = scandir( dirstring, &namelist, NULL, NULL ); - - for ( i = 0 ; i < count ; i++ ) - { - ent = namelist[i]; - name = ent->d_name; - - if ( name[0] == '.' ) { - continue; - } - - sprintf( fullname, "%s/%s", dir, name ); - sprintf( dirstring, "%s%s/%s", gamedir, dir, name ); - - if ( stat( dirstring, &st ) == -1 ) { - Error( "fstating %s", pf->name ); - } - if ( S_ISDIR( st.st_mode ) != 0 ) { // directory - PackDirectory_r( fullname ); - continue; - } - - // copy or pack the file - ReleaseFile( fullname ); - } -} -#endif - - -/* - =============== - Cmd_Dir - - This is only used to cause a directory to be copied during a - release build (sounds, etc) - =============== - */ -void Cmd_Dir( void ){ - GetToken( false ); - PackDirectory_r( token ); -} - -//======================================================================== - -#define MAX_RTEX 16384 -int numrtex; -char rtex[MAX_RTEX][64]; - -void ReleaseTexture( char *name ){ - int i; - char path[1024]; - - for ( i = 0 ; i < numrtex ; i++ ) - if ( striEqual( name, rtex[i] ) ) { - return; - } - - if ( numrtex == MAX_RTEX ) { - Error( "numrtex == MAX_RTEX" ); - } - - strcpy( rtex[i], name ); - numrtex++; - - sprintf( path, "textures/%s.wal", name ); - ReleaseFile( path ); -} - -/* - =============== - Cmd_Maps - - Only relevant for release and pak files. - Releases the .bsp files for the maps, and scans all of the files to - build a list of all textures used, which are then released. - =============== - */ -void Cmd_Maps( void ){ - char map[1024]; - - while ( TokenAvailable() ) - { - GetToken( false ); - sprintf( map, "maps/%s.bsp", token ); - ReleaseFile( map ); - - if ( !g_release ) { - continue; - } - - // get all the texture references - sprintf( map, "%smaps/%s.bsp", gamedir, token ); - LoadBSPFile( map ); - } -} - - -//============================================================== - -/* - =============== - ParseScript - =============== - */ -void ParseScript( void ){ - while ( 1 ) - { - do - { // look for a line starting with a $ command - if ( !GetToken( true ) ) { - return; - } - if ( token[0] == '$' ) { - break; - } - while ( TokenAvailable() ) - GetToken( false ); - } while ( 1 ); - - // - // model commands - // - if ( !strcmp( token, "$modelname" ) ) { - Cmd_Modelname(); - } - else if ( !strcmp( token, "$base" ) ) { - Cmd_Base(); - } - else if ( !strcmp( token, "$exit" ) ) { - break; - } - else if ( !strcmp( token, "$3dsconvert" ) ) { - Cmd_3DSConvert(); - } - else if ( !strcmp( token, "$spritebase" ) ) { - Cmd_SpriteBase(); - } - else if ( !strcmp( token, "$cd" ) ) { - Cmd_Cd(); - } - else if ( !strcmp( token, "$origin" ) ) { - Cmd_Origin(); - } - else if ( !strcmp( token, "$scale" ) ) { - Cmd_ScaleUp(); - } - else if ( !strcmp( token, "$frame" ) ) { - Cmd_Frame(); - } - else if ( !strcmp( token, "$skin" ) ) { - Cmd_Skin(); - } - else if ( !strcmp( token, "$spriteshader" ) ) { - Cmd_SpriteShader(); - } - else if ( !strcmp( token, "$aseconvert" ) ) { - Cmd_ASEConvert( false ); - } - else if ( !strcmp( token, "$aseanimconvert" ) ) { - Cmd_ASEConvert( true ); - } - - // - // image commands - // - else if ( !strcmp( token, "$grab" ) ) { - Cmd_Grab(); - } - else if ( !strcmp( token, "$raw" ) ) { - Cmd_Raw(); - } - else if ( !strcmp( token, "$colormap" ) ) { - Cmd_Colormap(); - } - else if ( !strcmp( token, "$environment" ) ) { - Cmd_Environment(); - } - - // - // video - // - else if ( !strcmp( token, "$video" ) ) { - Cmd_Video(); - } - // - // misc - // - else if ( !strcmp( token, "$file" ) ) { - Cmd_File(); - } - else if ( !strcmp( token, "$dir" ) ) { - Cmd_Dir(); - } - else if ( !strcmp( token, "$maps" ) ) { - Cmd_Maps(); - } - else{ - Error( "bad command %s\n", token ); - } - } -} - -//======================================================= - -#include "version.h" - -/* - ============== - main - ============== - */ -int main( int argc, char **argv ){ - int i; // VC4.2 compiler bug if auto... - char path[1024]; - - // using GtkRadiant's versioning next to Id's versioning - printf( "Q3Data - (c) 1999 Id Software Inc.\n" ); - printf( "NetRadiant - v" RADIANT_VERSION " " __DATE__ "\n" ); - - ExpandWildcards( &argc, &argv ); - - for ( i = 1 ; i < argc ; i++ ) - { - if ( !strcmp( argv[i], "-release" ) ) { - g_release = true; - strcpy( g_releasedir, argv[i + 1] ); - printf( "Copy output to: %s\n", g_releasedir ); - i++; - } - else if ( !strcmp( argv[i], "-nostrips" ) ) { - g_stripify = false; - printf( "Not optimizing for strips\n" ); - } - else if ( !strcmp( argv[i], "-writedir" ) ) { - strcpy( writedir, argv[i + 1] ); - printf( "Write output to: %s\n", writedir ); - i++; - } - else if ( !strcmp( argv[i], "-verbose" ) ) { - g_verbose = true; - } - else if ( !strcmp( argv[i], "-dump" ) ) { - printf( "Dumping contents of: '%s'\n", argv[i + 1] ); - if ( path_extension_is( argv[i + 1], "md3" ) ) { - MD3_Dump( argv[i + 1] ); - } - else - { - Error( "Do not know how to dump the contents of '%s'\n", argv[i + 1] ); - } - i++; - } - else if ( !strcmp( argv[i], "-3dsconvert" ) ) { - // NOTE TTimo this is broken, tried on a sample .3ds - // what happens .. it calls the Convert3DStoMD3, - // which calls the scriptlib function in non initialized state .. and crashes - printf( "Converting %s.3DS to %s.MD3\n", argv[i + 1], argv[i + 1] ); - SetQdirFromPath( argv[i + 1] ); - vfsInitDirectory( gamedir ); - Convert3DStoMD3( argv[i + 1] ); - i++; - } - else if ( !strcmp( argv[i], "-only" ) ) { - strcpy( g_only, argv[i + 1] ); - printf( "Only grabbing %s\n", g_only ); - i++; - } - else if ( !strcmp( argv[i], "-gamedir" ) ) { - strcpy( gamedir, argv[i + 1] ); - i++; - } - else if ( argv[i][0] == '-' ) { - Error( "Unknown option \"%s\"", argv[i] ); - } - else{ - break; - } - } - - if ( i == argc ) { - Error( "usage: q3data [-dump ] [-release ] [-only ] [-3dsconvert ] [-verbose] [file.qdt]" ); - } - - for ( ; i < argc ; i++ ) - { - printf( "--------------- %s ---------------\n", argv[i] ); - // load the script - strcpy( path, argv[i] ); - DefaultExtension( path, ".qdt" ); - if ( !gamedir[0] ) { - SetQdirFromPath( path ); - } - // NOTE TTimo - // q3data went through a partial conversion to use the vfs - // it was never actually tested before 1.1.1 - // the code is still mostly using direct file access calls - vfsInitDirectory( gamedir ); - LoadScriptFile( ExpandArg( path ), -1 ); - - // - // parse it - // - ParseScript(); - - // write out the last model - FinishModel( TYPE_UNKNOWN ); - } - - return 0; -} diff --git a/tools/quake3/q3data/q3data.h b/tools/quake3/q3data/q3data.h deleted file mode 100644 index c4175548..00000000 --- a/tools/quake3/q3data/q3data.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// q3data.h - - -#include -#include -#include -#include -#include - -#include "../common/cmdlib.h" -#include "../common/inout.h" -#include "../common/qstringops.h" -#include "../common/qpathops.h" -#include "scriplib.h" -#include "mathlib.h" -#include "polyset.h" -#include "trilib.h" -#include "imagelib.h" -#include "qthreads.h" -#include "l3dslib.h" -#include "bspfile.h" -#include "p3dlib.h" -#include "3dslib.h" -#include "aselib.h" -#include "md3lib.h" - -void Cmd_ASEConvert( bool grabAnims ); -void Cmd_3DSConvert( void ); -void Cmd_Modelname( void ); -void Cmd_SpriteBase( void ); -void Cmd_Base( void ); -void Cmd_Cd( void ); -void Cmd_Origin( void ); -void Cmd_ScaleUp( void ); -void Cmd_Frame( void ); -void Cmd_Modelname( void ); -void Cmd_SpriteShader( void ); -void Cmd_Skin( void ); -void Cmd_Skinsize( void ); -void FinishModel( int type ); - -void Cmd_Grab( void ); -void Cmd_Raw( void ); -void Cmd_Mip( void ); -void Cmd_Environment( void ); -void Cmd_Colormap( void ); - -void Cmd_File( void ); -void Cmd_Dir( void ); -void Cmd_StartWad( void ); -void Cmd_EndWad( void ); -void Cmd_Mippal( void ); -void Cmd_Mipdir( void ); - -void Cmd_Video( void ); - -void ReleaseFile( char *filename ); -void ReleaseShader( char *filename ); - -void Convert3DStoMD3( const char *filename ); - -void OrderMesh( int input[][3], int output[][3], int numTris ); - -extern byte *byteimage, *lbmpalette; -extern int byteimagewidth, byteimageheight; - -extern bool g_release; // don't grab, copy output data to new tree -extern char g_releasedir[1024]; // c:\quake2\baseq2, etc -extern bool g_archive; // don't grab, copy source data to new tree -extern bool do3ds; -extern char g_only[256]; // if set, only grab this cd -extern bool g_skipmodel; // set true when a cd is not g_only -extern bool g_verbose; - -extern char *trifileext; - -#define TYPE_ITEM 0 -#define TYPE_PLAYER 1 -#define TYPE_WEAPON 2 -#define TYPE_HAND 3 -#define TYPE_UNKNOWN 4 diff --git a/tools/quake3/q3data/stripper.cpp b/tools/quake3/q3data/stripper.cpp deleted file mode 100644 index f2e1c14a..00000000 --- a/tools/quake3/q3data/stripper.cpp +++ /dev/null @@ -1,293 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include - -static int s_used[8192]; // same as MD3_MAX_TRIANGLES - -/* -** FindNextTriangleInStrip -** -** Given a surface and triangle this tries to find the next triangle -** in the strip that would continue the strip. The next triangle in -** the strip should have the same winding as this triangle. -*/ -static int FindNextTriangleInStripOrFan( int mesh[][3], int tri, int orientation, int numTris, int odd ){ - int t; - int currentTri[3]; - int side; - int a, b, c; - int refa, refb; - - currentTri[0] = mesh[tri][( 0 + orientation ) % 3]; - currentTri[1] = mesh[tri][( 1 + orientation ) % 3]; - currentTri[2] = mesh[tri][( 2 + orientation ) % 3]; - - if ( odd ) { - refa = currentTri[1]; - refb = currentTri[2]; - } - else - { - refa = currentTri[2]; - refb = currentTri[0]; - } - - // go through all triangles and look for sides that match - // this triangle's - for ( t = 0; t < numTris; t++ ) - { - // don't check against self or against previously used triangles - if ( t == tri ) { - continue; - } - if ( s_used[t] ) { - continue; - } - - // check all three sides of the candidate triangle - for ( side = 0; side < 3; side++ ) - { - // check only the second (abutting) side - if ( ( refa == mesh[t][( side + 1 ) % 3] ) && - ( refb == mesh[t][side] ) ) { - - a = mesh[t][0]; - b = mesh[t][1]; - c = mesh[t][2]; - - // rotate the candidate triangle to align it properly in the strip - if ( side == 1 ) { - mesh[t][0] = b; - mesh[t][1] = c; - mesh[t][2] = a; - } - else if ( side == 2 ) { - mesh[t][0] = c; - mesh[t][1] = a; - mesh[t][2] = b; - } - - return t; - } -/* - else - { - Error( "fans not implemented yet" ); - - // check only the third (abutting) side - if ( ( currentTri[2] == pSurf->baseTriangles[t].v[side].index ) && - ( currentTri[0] == pSurf->baseTriangles[t].v[(side+1)%3].index ) ) - { - return t; - } - } - */ - } - } - - return -1; -} - -/* -** StripLength -*/ -static int StripLength( int mesh[][3], int strip[][3], int tri, int orientation, int numInputTris, int fillNo ){ - int stripIndex = 0; - int next; - - int odd = 1; - - strip[stripIndex][0] = mesh[tri][( 0 + orientation ) % 3]; - strip[stripIndex][1] = mesh[tri][( 1 + orientation ) % 3]; - strip[stripIndex][2] = mesh[tri][( 2 + orientation ) % 3]; - s_used[tri] = fillNo; - stripIndex++; - - next = tri; - - while ( ( next = FindNextTriangleInStripOrFan( mesh, next, orientation, numInputTris, odd ) ) != -1 ) - { - s_used[next] = fillNo; - odd = !odd; - strip[stripIndex][0] = mesh[next][0]; - strip[stripIndex][1] = mesh[next][1]; - strip[stripIndex][2] = mesh[next][2]; - stripIndex++; - - // all iterations after first need to be with an unrotated reference triangle - orientation = 0; - } - - return stripIndex; -} - -/* -** BuildOptimizedList -** -** Attempts to build the longest strip/fan possible. Does not adhere -** to pure strip or fan, will intermix between the two so long as some -** type of connectivity can be maintained. -*/ -#define MAX_ORIENTATIONS 3 -#define MAX_MATCHED_SIDES 4 -#define MAX_SEED_TRIANGLES 16 - -static int BuildOptimizedList( int mesh[][3], int strip[][3], int numInputTris ){ - int t; - int stripLen = 0; - int bestTri = -1, bestLength = 0, bestOrientation = -1; - int matchedSides = 0; - int orientation = 0; - int seedTriangles[MAX_MATCHED_SIDES][MAX_SEED_TRIANGLES]; - int seedLengths[MAX_ORIENTATIONS][MAX_MATCHED_SIDES][MAX_SEED_TRIANGLES]; - int numSeeds[MAX_MATCHED_SIDES] = { 0, 0, 0 }; - int i; - - // build a ranked list of candidate seed triangles based on - // number of offshoot strips. Precedence goes to orphans, - // then corners, then edges, and interiors. - memset( seedTriangles, 0xff, sizeof( seedTriangles ) ); - memset( seedLengths, 0xff, sizeof( seedLengths ) ); - - for ( i = 0; i < MAX_MATCHED_SIDES; i++ ) - { - // find the triangle with lowest number of child strips - for ( t = 0; t < numInputTris; t++ ) - { - int orientation; - int n; - - if ( s_used[t] ) { - continue; - } - - // try the candidate triangle in three different orientations - matchedSides = 0; - for ( orientation = 0; orientation < 3; orientation++ ) - { - if ( ( n = FindNextTriangleInStripOrFan( mesh, t, orientation, numInputTris, 1 ) ) != -1 ) { - matchedSides++; - } - } - - if ( matchedSides == i ) { - seedTriangles[i][numSeeds[i]] = t; - numSeeds[i]++; - if ( numSeeds[i] == MAX_SEED_TRIANGLES ) { - break; - } - } - } - } - - // we have a list of potential seed triangles, so we now go through each - // potential candidate and look to see which produces the longest strip - // and select our startTri based on this - for ( i = 0; i < MAX_MATCHED_SIDES; i++ ) - { - int j; - - for ( j = 0; j < numSeeds[i]; j++ ) - { - for ( orientation = 0; orientation < 3; orientation++ ) - { - int k; - - seedLengths[orientation][i][j] = StripLength( mesh, strip, seedTriangles[i][j], orientation, numInputTris, 2 ); - - if ( seedLengths[orientation][i][j] > bestLength ) { - bestTri = seedTriangles[i][j]; - bestLength = seedLengths[orientation][i][j]; - bestOrientation = orientation; - } - - for ( k = 0; k < numInputTris; k++ ) - { - if ( s_used[k] == 2 ) { - s_used[k] = 0; - } - } - } - } - - if ( bestTri != -1 ) { - break; - } - } - - // build the strip for real - if ( bestTri != -1 ) { - stripLen = StripLength( mesh, strip, bestTri, bestOrientation, numInputTris, 1 ); - } - - return stripLen; -} - -/* -** OrderMesh -** -** Given an input mesh and an output mesh, this routine will reorder -** the triangles within the mesh into strips/fans. -*/ -void OrderMesh( int input[][3], int output[][3], int numTris ){ - int i; - int sumStrippedTriangles = 0; - int strippedTriangles; - int totalStrips = 0; - int strip[8192][3]; // could dump directly into 'output', but - // this helps with debugging - - memset( s_used, 0, sizeof( s_used ) ); - -#if 0 - FILE *fp = fopen( "strip.txt", "wt" ); - - for ( i = 0; i < numTris; i++ ) - { - fprintf( fp, "%4d: %3d %3d %3d\n", i, input[i][0], input[i][1], input[i][2] ); - } - fclose( fp ); -#endif - - // while there are still triangles that are not part of a strip - while ( sumStrippedTriangles < numTris ) - { - // build a strip - strippedTriangles = BuildOptimizedList( input, strip, numTris ); - - for ( i = 0; i < strippedTriangles; i++ ) - { - output[sumStrippedTriangles + i][0] = strip[i][0]; - output[sumStrippedTriangles + i][1] = strip[i][1]; - output[sumStrippedTriangles + i][2] = strip[i][2]; - } - - sumStrippedTriangles += strippedTriangles; - totalStrips++; - } - - printf( "Triangles on surface: %d\n", sumStrippedTriangles ); - printf( "Total strips from surface: %d\n", totalStrips ); - printf( "Average strip length: %f\n", ( float ) sumStrippedTriangles / totalStrips ); -} diff --git a/tools/quake3/q3data/video.cpp b/tools/quake3/q3data/video.cpp deleted file mode 100644 index 4c63a8c1..00000000 --- a/tools/quake3/q3data/video.cpp +++ /dev/null @@ -1,1135 +0,0 @@ -/* - Copyright (C) 1999-2006 Id Software, Inc. and contributors. - For a list of contributors, see the accompanying CONTRIBUTORS file. - - This file is part of GtkRadiant. - - GtkRadiant is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - GtkRadiant is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GtkRadiant; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include "q3data.h" - -static int s_resample_width = 256; -static int s_resample_height = 256; - -#define OUTPUT_TGAS 1 - -#define UNCOMPRESSED 0 -#define BTC_COMPRESSION 1 - -static int s_compression_method = BTC_COMPRESSION; - -static const char *CIN_EXTENSION = "cn2"; -static const int CIN_SIGNATURE = ( 'C' << 24 ) | ( 'I' << 16 ) | ( 'N' << 8 ) | ( '2' ); - -static byte *s_soundtrack; -static char s_base[32]; -static char s_output_base[32]; - -// for compression routines -typedef struct -{ - void *data; - int count, width, height; -} cblock_t; - -/* - =============================================================================== - - WAV loading - - =============================================================================== - */ - -typedef struct -{ - int rate; - int width; - int channels; - int loopstart; - int samples; - int dataofs; // chunk starts this many bytes from file start -} wavinfo_t; - - -byte *data_p; -byte *iff_end; -byte *last_chunk; -byte *iff_data; -int iff_chunk_len; - - -static int s_samplecounts[0x10000]; -static wavinfo_t s_wavinfo; - -short GetLittleShort( void ){ - short val = 0; - val = *data_p; - val = val + ( *( data_p + 1 ) << 8 ); - data_p += 2; - return val; -} - -int GetLittleLong( void ){ - int val = 0; - val = *data_p; - val = val + ( *( data_p + 1 ) << 8 ); - val = val + ( *( data_p + 2 ) << 16 ); - val = val + ( *( data_p + 3 ) << 24 ); - data_p += 4; - return val; -} - -void FindNextChunk( const char *name ){ - while ( 1 ) - { - data_p = last_chunk; - - if ( data_p >= iff_end ) { // didn't find the chunk - data_p = NULL; - return; - } - - data_p += 4; - iff_chunk_len = GetLittleLong(); - if ( iff_chunk_len < 0 ) { - data_p = NULL; - return; - } -// if (iff_chunk_len > 1024*1024) -// Sys_Error ("FindNextChunk: %i length is past the 1 meg sanity limit", iff_chunk_len); - data_p -= 8; - last_chunk = data_p + 8 + ( ( iff_chunk_len + 1 ) & ~1 ); - if ( strEqualPrefix( (const char*)data_p, name ) ) { - return; - } - } -} - -void FindChunk( const char *name ){ - last_chunk = iff_data; - FindNextChunk( name ); -} - - -void DumpChunks( void ){ - char str[5]; - - str[4] = 0; - data_p = iff_data; - do - { - memcpy( str, data_p, 4 ); - data_p += 4; - iff_chunk_len = GetLittleLong(); - printf( "0x%p : %s (%d)\n", data_p - 4, str, iff_chunk_len ); - data_p += ( iff_chunk_len + 1 ) & ~1; - } while ( data_p < iff_end ); -} - -/* - ============ - GetWavinfo - ============ - */ -wavinfo_t GetWavinfo( char *name, byte *wav, int wavlength ){ - wavinfo_t info; - int i; - int format; - int samples; - - memset( &info, 0, sizeof( info ) ); - - if ( !wav ) { - return info; - } - - iff_data = wav; - iff_end = wav + wavlength; - -// find "RIFF" chunk - FindChunk( "RIFF" ); - if ( !( data_p && strEqualPrefix( (const char*)( data_p + 8 ), "WAVE" ) ) ) { - printf( "Missing RIFF/WAVE chunks\n" ); - return info; - } - -// get "fmt " chunk - iff_data = data_p + 12; -// DumpChunks (); - - FindChunk( "fmt " ); - if ( !data_p ) { - printf( "Missing fmt chunk\n" ); - return info; - } - data_p += 8; - format = GetLittleShort(); - if ( format != 1 ) { - printf( "Microsoft PCM format only\n" ); - return info; - } - - info.channels = GetLittleShort(); - info.rate = GetLittleLong(); - data_p += 4 + 2; - info.width = GetLittleShort() / 8; - -// get cue chunk - FindChunk( "cue " ); - if ( data_p ) { - data_p += 32; - info.loopstart = GetLittleLong(); -// Com_Printf("loopstart=%d\n", sfx->loopstart); - - // if the next chunk is a LIST chunk, look for a cue length marker - FindNextChunk( "LIST" ); - if ( data_p ) { - if ( strEqualPrefix( (const char*)( data_p + 28 ), "mark" ) ) { // this is not a proper parse, but it works with cooledit... - data_p += 24; - i = GetLittleLong(); // samples in loop - info.samples = info.loopstart + i; - } - } - } - else{ - info.loopstart = -1; - } - -// find data chunk - FindChunk( "data" ); - if ( !data_p ) { - printf( "Missing data chunk\n" ); - return info; - } - - data_p += 4; - samples = GetLittleLong(); - - if ( info.samples ) { - if ( samples < info.samples ) { - Error( "Sound %s has a bad loop length", name ); - } - } - else{ - info.samples = samples; - } - - info.dataofs = data_p - wav; - - return info; -} - -//===================================================================== - -/* - ============== - LoadSoundtrack - ============== - */ -void LoadSoundtrack( void ){ - char name[1024]; - FILE *f; - int len; - int i, val, j; - - s_soundtrack = NULL; - sprintf( name, "%svideo/%s/%s.wav", gamedir, s_base, s_base ); - printf( "WAV: %s\n", name ); - f = fopen( name, "rb" ); - if ( !f ) { - printf( "no soundtrack for %s\n", s_base ); - return; - } - len = Q_filelength( f ); - s_soundtrack = safe_malloc( len ); - fread( s_soundtrack, 1, len, f ); - fclose( f ); - - s_wavinfo = GetWavinfo( name, s_soundtrack, len ); - - // count samples for compression - memset( s_samplecounts, 0, sizeof( s_samplecounts ) ); - - j = s_wavinfo.samples / 2; - for ( i = 0 ; i < j ; i++ ) - { - val = ( (unsigned short *)( s_soundtrack + s_wavinfo.dataofs ) )[i]; - s_samplecounts[val]++; - } - val = 0; - for ( i = 0 ; i < 0x10000 ; i++ ) - if ( s_samplecounts[i] ) { - val++; - } - - printf( "%i unique sample values\n", val ); -} - -/* - ================== - WriteSound - ================== - */ -void WriteSound( FILE *output, int frame ){ - int start, end; - int count; - int empty = 0; - int i; - int sample; - int width; - - width = s_wavinfo.width * s_wavinfo.channels; - - start = frame * s_wavinfo.rate / 14; - end = ( frame + 1 ) * s_wavinfo.rate / 14; - count = end - start; - - for ( i = 0 ; i < count ; i++ ) - { - sample = start + i; - if ( sample > s_wavinfo.samples || !s_soundtrack ) { - fwrite( &empty, 1, width, output ); - } - else{ - fwrite( s_soundtrack + s_wavinfo.dataofs + sample * width, 1, width,output ); - } - } -} - -//========================================================================== - -static float s_resampleXRatio; -static float s_resampleYRatio; - -static void BoxFilterHorizontalElements( unsigned char *dst, unsigned char *src, float s0, float s1 ){ - float w; - float rSum = 0, gSum = 0, bSum = 0; - float x = s0; - float sumWeight = 0; - - for ( x = s0; x < s1; x++, src += 4 ) - { - if ( x == s0 ) { - w = ( int ) ( s0 + 1 ) - x; - } - else if ( x + 1 >= s1 ) { - w = s1 - ( int ) x; - } - else - { - w = 1.0f; - } - - rSum += src[0] * w; - gSum += src[1] * w; - bSum += src[2] * w; - sumWeight += w; - } - - rSum /= sumWeight; - gSum /= sumWeight; - bSum /= sumWeight; - - dst[0] = ( unsigned char ) ( rSum + 0.5 ); - dst[1] = ( unsigned char ) ( gSum + 0.5 ); - dst[2] = ( unsigned char ) ( bSum + 0.5 ); -} - -static void BoxFilterVerticalElements( unsigned char *dst, // destination of the filter process - unsigned char *src, // source pixels - int srcStep, // stride of the source pixels - float s0, float s1 ){ - float w; - float rSum = 0, gSum = 0, bSum = 0; - float y = s0; - float sumWeight = 0; - - for ( y = s0; y < ( int ) ( s1 + 1 ) ; y++, src += srcStep ) - { - if ( y == s0 ) { - w = ( int ) ( s0 + 1 ) - y; - } - else if ( y + 1 >= s1 ) { - w = s1 - ( int ) y; - } - else - { - w = 1.0f; - } - - rSum += src[0] * w; - gSum += src[1] * w; - bSum += src[2] * w; - sumWeight += w; - } - - rSum /= sumWeight; - gSum /= sumWeight; - bSum /= sumWeight; - - dst[0] = ( unsigned char ) ( rSum + 0.5 ); - dst[1] = ( unsigned char ) ( gSum + 0.5 ); - dst[2] = ( unsigned char ) ( bSum + 0.5 ); - dst[3] = 0xff; - -} - -static void BoxFilterRow( unsigned char *dstStart, cblock_t *in, int dstRow, int rowWidth ){ - int i; - unsigned char *indata = ( unsigned char * ) in->data; - - indata += 4 * dstRow * in->width; - - for ( i = 0; i < rowWidth; i++ ) - { - float c0 = i * s_resampleXRatio; - float c1 = ( i + 1 ) * s_resampleXRatio; - - BoxFilterHorizontalElements( &dstStart[i * 4], &indata[( ( int ) c0 ) * 4], c0, c1 ); - } -} - -static void BoxFilterColumn( unsigned char *dstStart, unsigned char *srcStart, int dstCol, int dstRowWidth, int dstColHeight, int srcRowWidthInPels ){ - float c0, c1; - int i; - - for ( i = 0; i < dstColHeight; i++ ) - { - c0 = i * s_resampleYRatio; - c1 = ( i + 1 ) * s_resampleYRatio; - - BoxFilterVerticalElements( &dstStart[i * 4 * dstRowWidth], &srcStart[(int)c0 * srcRowWidthInPels * 4], srcRowWidthInPels * 4, c0, c1 ); - } -} - -#define DROP_SAMPLE 0 -#define BOX_FILTER 1 - -static void ResampleFrame( cblock_t *in, unsigned char *out, int method, int outWidth, int outHeight ){ - int row, column; - unsigned char *indata = ( unsigned char * ) in->data; - - s_resampleXRatio = in->width / ( float ) outWidth; - s_resampleYRatio = in->height / ( float ) outHeight; - - if ( method == DROP_SAMPLE ) { - for ( row = 0; row < outHeight; row++ ) - { - int r = ( int ) ( row * s_resampleYRatio ); - - for ( column = 0; column < outWidth; column++ ) - { - int c = ( int ) ( column * s_resampleXRatio ); - - out[( row * outWidth + column ) * 4 + 0] = indata[( r * in->width + c ) * 4 + 0]; - out[( row * outWidth + column ) * 4 + 1] = indata[( r * in->width + c ) * 4 + 1]; - out[( row * outWidth + column ) * 4 + 2] = indata[( r * in->width + c ) * 4 + 2]; - out[( row * outWidth + column ) * 4 + 3] = 0xff; - } - } - } - else if ( method == BOX_FILTER ) { - unsigned char intermediate[1024 * 1024 * 4]; - - assert( in->height <= 1024 ); - assert( in->width <= 1024 ); - - // - // filter our M x N source image into a RESAMPLE_WIDTH x N horizontally filtered image - // - for ( row = 0; row < in->height; row++ ) - { - BoxFilterRow( &intermediate[row * 4 * outWidth], in, row, outWidth ); - } - - // - // filter our RESAMPLE_WIDTH x N horizontally filtered image into a RESAMPLE_WIDTH x RESAMPLE_HEIGHT filtered image - // - for ( column = 0; column < outWidth; column++ ) - { - BoxFilterColumn( &out[column * 4], &intermediate[column * 4], column, outWidth, outHeight, s_resample_width ); - } - } -} - -static float BTCDistanceSquared( float a[3], float b[3] ){ - return ( b[0] - a[0] ) * ( b[0] - a[0] ) + - ( b[1] - a[1] ) * ( b[1] - a[1] ) + - ( b[2] - a[2] ) * ( b[2] - a[2] ); -} - -static void BTCFindEndpoints( float inBlock[4][4][3], unsigned int endPoints[2][2] ){ - float longestDistance = -1; - - int bX, bY; - - // - // find the two points farthest from each other - // - for ( bY = 0; bY < 4; bY++ ) - { - for ( bX = 0; bX < 4; bX++ ) - { - int cX, cY; - float d; - - // - // check the rest of the current row - // - for ( cX = bX + 1; cX < 4; cX++ ) - { - if ( ( d = BTCDistanceSquared( inBlock[bY][bX], inBlock[bY][cX] ) ) > longestDistance ) { - longestDistance = d; - endPoints[0][0] = bX; - endPoints[0][1] = bY; - endPoints[1][0] = cX; - endPoints[1][1] = bY; - } - } - - // - // check remaining rows and columns - // - for ( cY = bY + 1; cY < 4; cY++ ) - { - for ( cX = 0; cX < 4; cX++ ) - { - if ( ( d = BTCDistanceSquared( inBlock[bY][bX], inBlock[cY][cX] ) ) > longestDistance ) { - longestDistance = d; - endPoints[0][0] = bX; - endPoints[0][1] = bY; - endPoints[1][0] = cX; - endPoints[1][1] = cY; - } - } - } - } - } -} - -static float BTCQuantizeBlock( float inBlock[4][4][3], unsigned int endPoints[2][2], int btcQuantizedBlock[4][4], float bestError ){ - int i; - int blockY, blockX; - float dR, dG, dB; - float R, G, B; - float error = 0; - float colorLine[4][3]; - - // - // build the color line - // - dR = inBlock[endPoints[1][1]][endPoints[1][0]][0] - - inBlock[endPoints[0][1]][endPoints[0][0]][0]; - dG = inBlock[endPoints[1][1]][endPoints[1][0]][1] - - inBlock[endPoints[0][1]][endPoints[0][0]][1]; - dB = inBlock[endPoints[1][1]][endPoints[1][0]][2] - - inBlock[endPoints[0][1]][endPoints[0][0]][2]; - - dR *= 0.33f; - dG *= 0.33f; - dB *= 0.33f; - - R = inBlock[endPoints[0][1]][endPoints[0][0]][0]; - G = inBlock[endPoints[0][1]][endPoints[0][0]][1]; - B = inBlock[endPoints[0][1]][endPoints[0][0]][2]; - - for ( i = 0; i < 4; i++ ) - { - colorLine[i][0] = R; - colorLine[i][1] = G; - colorLine[i][2] = B; - - R += dR; - G += dG; - B += dB; - } - - // - // quantize each pixel into the appropriate range - // - for ( blockY = 0; blockY < 4; blockY++ ) - { - for ( blockX = 0; blockX < 4; blockX++ ) - { - float distance = 10000000000; - int shortest = -1; - - for ( i = 0; i < 4; i++ ) - { - float d; - - if ( ( d = BTCDistanceSquared( inBlock[blockY][blockX], colorLine[i] ) ) < distance ) { - distance = d; - shortest = i; - } - } - - error += distance; - - // - // if bestError is not -1 then that means this is a speculative quantization - // - if ( bestError != -1 ) { - if ( error > bestError ) { - return error; - } - } - - btcQuantizedBlock[blockY][blockX] = shortest; - } - } - - return error; -} - -/* -** float BTCCompressBlock -*/ -static float BTCCompressBlock( float inBlock[4][4][3], unsigned long out[2] ){ - int i; - int btcQuantizedBlock[4][4]; // values should be [0..3] - unsigned long encodedEndPoints, encodedBitmap; - unsigned int endPoints[2][2]; // endPoints[0] = color start, endPoints[1] = color end - int blockY, blockX; - float error = 0; - float bestError = 10000000000; - unsigned int bestEndPoints[2][2]; - -#if 0 - // - // find the "ideal" end points for the color vector - // - BTCFindEndpoints( inBlock, endPoints ); - error = BTCQuantizeBlock( inBlock, endPoints, btcQuantizedBlock ); - memcpy( bestEndPoints, endPoints, sizeof( bestEndPoints ) ); -#else - for ( blockY = 0; blockY < 4; blockY++ ) - { - for ( blockX = 0; blockX < 4; blockX++ ) - { - int x2, y2; - - for ( y2 = 0; y2 < 4; y2++ ) - { - for ( x2 = 0; x2 < 4; x2++ ) - { - if ( ( x2 == blockX ) && ( y2 == blockY ) ) { - continue; - } - - endPoints[0][0] = blockX; - endPoints[0][1] = blockY; - endPoints[1][0] = x2; - endPoints[1][1] = y2; - - error = BTCQuantizeBlock( inBlock, endPoints, btcQuantizedBlock, -1 ); //bestError ); - - if ( error < bestError ) { - bestError = error; - memcpy( bestEndPoints, endPoints, sizeof( bestEndPoints ) ); - } - } - } - } - } - - error = BTCQuantizeBlock( inBlock, bestEndPoints, btcQuantizedBlock, -1.0f ); -#endif - - // - // encode the results - // - encodedBitmap = 0; - for ( blockY = 0; blockY < 4; blockY++ ) - { - for ( blockX = 0; blockX < 4; blockX++ ) - { - int shift = ( blockX + blockY * 4 ) * 2; - encodedBitmap |= btcQuantizedBlock[blockY][blockX] << shift; - } - } - - // - // encode endpoints - // - encodedEndPoints = 0; - for ( i = 0; i < 2; i++ ) - { - int iR, iG, iB; - - iR = ( ( int ) inBlock[bestEndPoints[i][1]][bestEndPoints[i][0]][0] ); - if ( iR > 255 ) { - iR = 255; - } - else if ( iR < 0 ) { - iR = 0; - } - iR >>= 3; - - iG = ( ( int ) inBlock[bestEndPoints[i][1]][bestEndPoints[i][0]][1] ); - if ( iG > 255 ) { - iG = 255; - } - else if ( iG < 0 ) { - iG = 0; - } - iG >>= 2; - - iB = ( ( int ) inBlock[bestEndPoints[i][1]][bestEndPoints[i][0]][2] ); - if ( iB > 255 ) { - iB = 255; - } - else if ( iB < 0 ) { - iB = 0; - } - iB >>= 3; - - - encodedEndPoints |= ( ( ( iR << 11 ) | ( iG << 5 ) | ( iB ) ) << ( i * 16 ) ); - } - - // - // store - // - out[0] = encodedBitmap; - out[1] = encodedEndPoints; - - return error; -} - -/* -** void BTCDecompressFrame -*/ -static void BTCDecompressFrame( unsigned long *src, unsigned char *dst ){ - int x, y; - int iR, iG, iB; - int dstX, dstY; - float colorStart[3], colorEnd[3]; - unsigned char colorRampABGR[4][4]; - unsigned encoded; - - memset( colorRampABGR, 0xff, sizeof( colorRampABGR ) ); - - for ( y = 0; y < s_resample_height / 4; y++ ) - { - for ( x = 0; x < s_resample_width / 4; x++ ) - { - unsigned colorStartPacked = src[( y * s_resample_width / 4 + x ) * 2 + 1] & 0xffff; - unsigned colorEndPacked = src[( y * s_resample_width / 4 + x ) * 2 + 1] >> 16; - - // - // grab the end points - // 0 = color start - // 1 = color end - // - iR = ( ( colorStartPacked >> 11 ) & ( ( 1 << 5 ) - 1 ) ); - iR = ( iR << 3 ) | ( iR >> 2 ); - iG = ( ( colorStartPacked >> 5 ) & ( ( 1 << 6 ) - 1 ) ); - iG = ( iG << 2 ) | ( iG >> 4 ); - iB = ( ( colorStartPacked ) & ( ( 1 << 5 ) - 1 ) ); - iB = ( iB << 3 ) | ( iB >> 2 ); - - colorStart[0] = iR; - colorStart[1] = iG; - colorStart[2] = iB; - colorRampABGR[0][0] = iR; - colorRampABGR[0][1] = iG; - colorRampABGR[0][2] = iB; - - iR = ( ( colorEndPacked >> 11 ) & ( ( 1 << 5 ) - 1 ) ); - iR = ( iR << 3 ) | ( iR >> 2 ); - iG = ( ( colorEndPacked >> 5 ) & ( ( 1 << 6 ) - 1 ) ); - iG = ( iG << 2 ) | ( iG >> 4 ); - iB = ( colorEndPacked & ( ( 1 << 5 ) - 1 ) ); - iB = ( iB << 3 ) | ( iB >> 2 ); - - colorEnd[0] = iR; - colorEnd[1] = iG; - colorEnd[2] = iB; - colorRampABGR[3][0] = iR; - colorRampABGR[3][1] = iG; - colorRampABGR[3][2] = iB; - - // - // compute this block's color ramp - // FIXME: This needs to be reversed on big-endian machines - // - - colorRampABGR[1][0] = colorStart[0] * 0.66f + colorEnd[0] * 0.33f; - colorRampABGR[1][1] = colorStart[1] * 0.66f + colorEnd[1] * 0.33f; - colorRampABGR[1][2] = colorStart[2] * 0.66f + colorEnd[2] * 0.33f; - - colorRampABGR[2][0] = colorStart[0] * 0.33f + colorEnd[0] * 0.66f; - colorRampABGR[2][1] = colorStart[1] * 0.33f + colorEnd[1] * 0.66f; - colorRampABGR[2][2] = colorStart[2] * 0.33f + colorEnd[2] * 0.66f; - - // - // decode the color data - // information is encoded in 2-bit pixels, with low order bits corresponding - // to upper left pixels. These 2-bit values are indexed into the block's - // computer color ramp. - // - encoded = src[( y * s_resample_width / 4 + x ) * 2 + 0]; - - for ( dstY = 0; dstY < 4; dstY++ ) - { - for ( dstX = 0; dstX < 4; dstX++ ) - { - memcpy( &dst[( y * 4 + dstY ) * s_resample_width * 4 + x * 4 * 4 + dstX * 4], colorRampABGR[encoded & 3], sizeof( colorRampABGR[0] ) ); - encoded >>= 2; - } - } - } - } -} - -/* -** BTCCompressFrame -** -** Perform a BTC compression using a 2-bit encoding at each pixel. This -** compression method is performed by decomposing the incoming image into -** a sequence of 4x4 blocks. At each block two color values are computed -** that define the endpoints of a vector in color space that represent -** the two colors "farthest apart". -*/ -static float BTCCompressFrame( unsigned char *src, unsigned long *dst ){ - int x, y; - int bX, bY; - float btcBlock[4][4][3]; - - float error = 0; - - for ( y = 0; y < s_resample_height / 4; y++ ) - { - for ( x = 0; x < s_resample_width / 4; x++ ) - { - // - // fill in the BTC block with raw values - // - for ( bY = 0; bY < 4; bY++ ) - { - for ( bX = 0; bX < 4; bX++ ) - { - btcBlock[bY][bX][0] = src[( y * 4 + bY ) * s_resample_width * 4 + ( x * 4 + bX ) * 4 + 0]; - btcBlock[bY][bX][1] = src[( y * 4 + bY ) * s_resample_width * 4 + ( x * 4 + bX ) * 4 + 1]; - btcBlock[bY][bX][2] = src[( y * 4 + bY ) * s_resample_width * 4 + ( x * 4 + bX ) * 4 + 2]; - } - } - - error += BTCCompressBlock( btcBlock, &dst[( y * s_resample_width / 4 + x ) * 2] ); - } - } - - return error / ( ( s_resample_width / 4 ) * ( s_resample_height / 4 ) ); -} - -/* - =================== - LoadFrame - =================== - */ -cblock_t LoadFrame( char *base, int frame, int digits, byte **palette ){ - int ten3, ten2, ten1, ten0; - cblock_t in; - int width, height; - char name[1024]; - FILE *f; - - in.data = NULL; - in.count = -1; - - ten3 = frame / 1000; - ten2 = ( frame - ten3 * 1000 ) / 100; - ten1 = ( frame - ten3 * 1000 - ten2 * 100 ) / 10; - ten0 = frame % 10; - - if ( digits == 4 ) { - sprintf( name, "%svideo/%s/%s%i%i%i%i.tga", gamedir, base, base, ten3, ten2, ten1, ten0 ); - } - else{ - sprintf( name, "%svideo/%s/%s%i%i%i.tga", gamedir, base, base, ten2, ten1, ten0 ); - } - - f = fopen( name, "rb" ); - if ( !f ) { - in.data = NULL; - return in; - } - fclose( f ); - - printf( "%s", name ); - LoadTGA( name, ( unsigned char ** ) &in.data, &width, &height ); - if ( palette ) { - *palette = 0; - } -// Load256Image (name, &in.data, palette, &width, &height); - in.count = width * height; - in.width = width; - in.height = height; -// FIXME: map 0 and 255! - -#if 0 - // rle compress - rle = RLE( in ); - free( in.data ); - - return rle; -#endif - - return in; -} - -/* - =============== - Cmd_Video - - video - =============== - */ -void Cmd_Video( void ){ - float sumError = 0, error = 0, maxError = 0; - char savename[1024]; - char name[1024]; - FILE *output; - int startframe, frame; - int width, height; - int i; - int digits; - int minutes; - float fseconds; - int remSeconds; - cblock_t in; - unsigned char *resampled; - unsigned long *compressed; - clock_t start, stop; - - GetToken( false ); - strcpy( s_base, token ); - if ( g_release ) { -// sprintf (savename, "video/%s.cin", token); -// ReleaseFile (savename); - return; - } - - GetToken( false ); - strcpy( s_output_base, token ); - - GetToken( false ); - digits = atoi( token ); - - GetToken( false ); - - if ( !strcmp( token, "btc" ) ) { - s_compression_method = BTC_COMPRESSION; - printf( "Compression: BTC\n" ); - } - else if ( !strcmp( token, "uc" ) ) { - s_compression_method = UNCOMPRESSED; - printf( "Compression: none\n" ); - } - else - { - Error( "Uknown compression method '%s'\n", token ); - } - - GetToken( false ); - s_resample_width = atoi( token ); - - GetToken( false ); - s_resample_height = atoi( token ); - - resampled = safe_malloc( sizeof( unsigned char ) * 4 * s_resample_width * s_resample_height ); - compressed = safe_malloc( sizeof( long ) * 2 * ( s_resample_width / 4 ) * ( s_resample_height / 4 ) ); - - printf( "Resample width: %d\n", s_resample_width ); - printf( "Resample height: %d\n", s_resample_height ); - - // optionally skip frames - if ( TokenAvailable() ) { - GetToken( false ); - startframe = atoi( token ); - } - else{ - startframe = 0; - } - - sprintf( savename, "%svideo/%s.%s", writedir, s_output_base, CIN_EXTENSION ); - - // load the entire sound wav file if present - LoadSoundtrack(); - - if ( digits == 4 ) { - sprintf( name, "%svideo/%s/%s0000.tga", gamedir, s_base, s_base ); - } - else{ - sprintf( name, "%svideo/%s/%s000.tga", gamedir, s_base, s_base ); - } - - printf( "%s\n", name ); - LoadTGA( name, NULL, &width, &height ); - - output = fopen( savename, "wb" ); - if ( !output ) { - Error( "Can't open %s", savename ); - } - - // write header info - i = LittleLong( CIN_SIGNATURE ); - fwrite( &i, 4, 1, output ); - i = LittleLong( s_resample_width ); - fwrite( &i, 4, 1, output ); - i = LittleLong( s_resample_height ); - fwrite( &i, 4, 1, output ); - i = LittleLong( s_wavinfo.rate ); - fwrite( &i, 4, 1, output ); - i = LittleLong( s_wavinfo.width ); - fwrite( &i, 4, 1, output ); - i = LittleLong( s_wavinfo.channels ); - fwrite( &i, 4, 1, output ); - i = LittleLong( s_compression_method ); - fwrite( &i, 4, 1, output ); - - start = clock(); - - // perform compression on a per frame basis - for ( frame = startframe ; ; frame++ ) - { - printf( "%02d: ", frame ); - in = LoadFrame( s_base, frame, digits, 0 ); - if ( !in.data ) { - break; - } - - ResampleFrame( &in, ( unsigned char * ) resampled, BOX_FILTER, s_resample_width, s_resample_height ); - - if ( s_compression_method == UNCOMPRESSED ) { - printf( "\n" ); - fwrite( resampled, 1, sizeof( unsigned char ) * s_resample_width * s_resample_height * 4, output ); - -#if OUTPUT_TGAS - { - int x, y; - char buffer[1000]; - - for ( y = 0; y < s_resample_height / 2; y++ ) - { - for ( x = 0; x < s_resample_width; x++ ) - { - unsigned char tmp[4]; - - tmp[0] = resampled[( s_resample_height - 1 - y ) * s_resample_width * 4 + x * 4 + 0]; - tmp[1] = resampled[( s_resample_height - 1 - y ) * s_resample_width * 4 + x * 4 + 1]; - tmp[2] = resampled[( s_resample_height - 1 - y ) * s_resample_width * 4 + x * 4 + 2]; - tmp[3] = resampled[( s_resample_height - 1 - y ) * s_resample_width * 4 + x * 4 + 3]; - - resampled[( s_resample_height - 1 - y ) * s_resample_width * 4 + x * 4 + 0] = resampled[y * s_resample_width * 4 + x * 4 + 0]; - resampled[( s_resample_height - 1 - y ) * s_resample_width * 4 + x * 4 + 1] = resampled[y * s_resample_width * 4 + x * 4 + 1]; - resampled[( s_resample_height - 1 - y ) * s_resample_width * 4 + x * 4 + 2] = resampled[y * s_resample_width * 4 + x * 4 + 2]; - resampled[( s_resample_height - 1 - y ) * s_resample_width * 4 + x * 4 + 3] = resampled[y * s_resample_width * 4 + x * 4 + 3]; - - resampled[y * s_resample_width * 4 + x * 4 + 0] = tmp[0]; - resampled[y * s_resample_width * 4 + x * 4 + 1] = tmp[1]; - resampled[y * s_resample_width * 4 + x * 4 + 2] = tmp[2]; - resampled[y * s_resample_width * 4 + x * 4 + 3] = tmp[3]; - } - } - - sprintf( buffer, "%svideo/%s/uc%04d.tga", gamedir, s_base, frame ); - WriteTGA( buffer, resampled, s_resample_width, s_resample_height ); - } -#endif - } - else if ( s_compression_method == BTC_COMPRESSION ) { - error = BTCCompressFrame( resampled, compressed ); - - sumError += error; - - if ( error > maxError ) { - maxError = error; - } - - printf( " (error = %f)\n", error ); - fwrite( compressed, 1, 2 * sizeof( long ) * ( s_resample_width / 4 ) * ( s_resample_height / 4 ), output ); - -#if OUTPUT_TGAS - { - int x, y; - unsigned char *uncompressed; - char buffer[1000]; - - uncompressed = safe_malloc( sizeof( unsigned char ) * 4 * s_resample_width * s_resample_height ); - BTCDecompressFrame( compressed, uncompressed ); - - for ( y = 0; y < s_resample_height / 2; y++ ) - { - for ( x = 0; x < s_resample_width; x++ ) - { - unsigned char tmp[4]; - - tmp[0] = uncompressed[( s_resample_height - 1 - y ) * s_resample_width * 4 + x * 4 + 0]; - tmp[1] = uncompressed[( s_resample_height - 1 - y ) * s_resample_width * 4 + x * 4 + 1]; - tmp[2] = uncompressed[( s_resample_height - 1 - y ) * s_resample_width * 4 + x * 4 + 2]; - tmp[3] = uncompressed[( s_resample_height - 1 - y ) * s_resample_width * 4 + x * 4 + 3]; - - uncompressed[( s_resample_height - 1 - y ) * s_resample_width * 4 + x * 4 + 0] = uncompressed[y * s_resample_width * 4 + x * 4 + 0]; - uncompressed[( s_resample_height - 1 - y ) * s_resample_width * 4 + x * 4 + 1] = uncompressed[y * s_resample_width * 4 + x * 4 + 1]; - uncompressed[( s_resample_height - 1 - y ) * s_resample_width * 4 + x * 4 + 2] = uncompressed[y * s_resample_width * 4 + x * 4 + 2]; - uncompressed[( s_resample_height - 1 - y ) * s_resample_width * 4 + x * 4 + 3] = uncompressed[y * s_resample_width * 4 + x * 4 + 3]; - - uncompressed[y * s_resample_width * 4 + x * 4 + 0] = tmp[0]; - uncompressed[y * s_resample_width * 4 + x * 4 + 1] = tmp[1]; - uncompressed[y * s_resample_width * 4 + x * 4 + 2] = tmp[2]; - uncompressed[y * s_resample_width * 4 + x * 4 + 3] = tmp[3]; - } - } - - - sprintf( buffer, "%svideo/%s/btc%04d.tga", gamedir, s_base, frame ); - WriteTGA( buffer, uncompressed, s_resample_width, s_resample_height ); - - free( uncompressed ); - } -#endif - } - - WriteSound( output, frame ); - - free( in.data ); - } - stop = clock(); - - printf( "\n" ); - - printf( "Total size: %ld\n", ftell( output ) ); - printf( "Average error: %f\n", sumError / ( frame - startframe ) ); - printf( "Max error: %f\n", maxError ); - - fseconds = ( stop - start ) / 1000.0f; - minutes = fseconds / 60; - remSeconds = fseconds - minutes * 60; - - printf( "Total time: %d s (%d m %d s)\n", ( int ) fseconds, minutes, remSeconds ); - printf( "Time/frame: %.2f seconds\n", fseconds / ( frame - startframe ) ); - - fclose( output ); - - if ( s_soundtrack ) { - free( s_soundtrack ); - s_soundtrack = 0; - } -}