2006-03-20 17:12:09 +00:00
/*
2014-06-01 17:55:23 +00:00
* Portions of this file are copyright Rebirth contributors and licensed as
* described in COPYING . txt .
* Portions of this file are copyright Parallax Software and licensed
* according to the Parallax license below .
* See COPYING . txt for license details .
2006-03-20 17:12:09 +00:00
THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
SOFTWARE CORPORATION ( " PARALLAX " ) . PARALLAX , IN DISTRIBUTING THE CODE TO
END - USERS , AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN , GRANTS A
ROYALTY - FREE , PERPETUAL LICENSE TO SUCH END - USERS FOR USE BY SUCH END - USERS
IN USING , DISPLAYING , AND CREATING DERIVATIVE WORKS THEREOF , SO LONG AS
SUCH USE , DISPLAY OR CREATION IS FOR NON - COMMERCIAL , ROYALTY OR REVENUE
FREE PURPOSES . IN NO EVENT SHALL THE END - USER USE THE COMPUTER CODE
CONTAINED HEREIN FOR REVENUE - BEARING PURPOSES . THE END - USER UNDERSTANDS
AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE .
COPYRIGHT 1993 - 1999 PARALLAX SOFTWARE CORPORATION . ALL RIGHTS RESERVED .
*/
/*
*
* Routines to parse bitmaps . tbl
* Only used for editor , since the registered version of descent 1.
*
*/
2012-11-11 22:12:51 +00:00
# include <algorithm>
2018-07-18 04:39:28 +00:00
# include <string>
2006-03-20 17:12:09 +00:00
# include <stdio.h>
# include <stdlib.h>
# include <stdarg.h>
# include <string.h>
# include <ctype.h>
# include "pstypes.h"
# include "gr.h"
# include "bm.h"
# include "u_mem.h"
2012-07-07 18:35:06 +00:00
# include "dxxerror.h"
2006-03-20 17:12:09 +00:00
# include "object.h"
2014-07-20 01:09:55 +00:00
# include "physfsx.h"
2006-03-20 17:12:09 +00:00
# include "vclip.h"
# include "effects.h"
# include "polyobj.h"
# include "wall.h"
# include "textures.h"
# include "game.h"
# include "iff.h"
# include "hostage.h"
# include "powerup.h"
# include "sounds.h"
# include "piggy.h"
# include "aistruct.h"
# include "robot.h"
# include "weapon.h"
# include "gauges.h"
# include "player.h"
# include "endlevel.h"
# include "cntrlcen.h"
2014-07-23 02:09:33 +00:00
# include "physfs-serial.h"
2006-03-20 17:12:09 +00:00
# include "args.h"
# include "text.h"
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
# include "fuelcen.h"
# elif defined(DXX_BUILD_DESCENT_II)
# include "gamepal.h"
2006-03-20 17:12:09 +00:00
# include "interp.h"
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
# include "strutil.h"
2018-07-18 04:39:28 +00:00
# if DXX_USE_EDITOR
2006-03-20 17:12:09 +00:00
# include "editor/texpage.h"
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
2020-02-06 03:22:45 +00:00
# include "compiler-cf_assert.h"
2014-01-18 18:02:02 +00:00
# include "compiler-range_for.h"
2018-07-18 04:39:28 +00:00
# include "partial_range.h"
2016-12-11 01:56:44 +00:00
# include "d_enumerate.h"
2019-05-04 18:27:37 +00:00
# include "d_range.h"
2022-06-05 17:44:53 +00:00
# include "d_zip.h"
2014-01-18 18:02:02 +00:00
2012-11-11 22:12:51 +00:00
using std : : min ;
2020-10-07 03:59:14 +00:00
namespace dcx {
2006-03-20 17:12:09 +00:00
2020-04-04 19:30:22 +00:00
namespace {
2020-10-07 03:59:14 +00:00
enum class bm_type : uint8_t
{
none = 0xff ,
cockpit = 0 ,
textures = 2 ,
vclip = 4 ,
effects = 5 ,
eclip = 6 ,
wall_anims = 12 ,
wclip = 13 ,
robot = 14 ,
gauges = 20 ,
/* if DXX_BUILD_DESCENT_II */
gauges_hires = 21 ,
/* endif */
} ;
static bm_type current_bm_type = bm_type : : none ;
2020-04-04 19:30:22 +00:00
uint8_t wall_explodes_flag ;
uint8_t wall_blastable_flag ;
uint8_t wall_hidden_flag ;
uint8_t tmap1_flag ; //flag if this is used as tmap_num (not tmap_num2)
}
2020-10-07 03:59:14 +00:00
}
namespace dsx {
namespace {
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
static short N_ObjBitmaps = 0 ;
# endif
2020-10-07 03:59:14 +00:00
}
2006-03-20 17:12:09 +00:00
2016-09-11 18:49:16 +00:00
# if DXX_USE_EDITOR
2016-07-09 17:58:34 +00:00
powerup_names_array Powerup_names ;
2016-07-09 17:58:34 +00:00
robot_names_array Robot_names ;
2016-07-09 17:58:34 +00:00
# endif
2016-06-25 23:21:36 +00:00
}
2006-03-20 17:12:09 +00:00
2020-10-07 03:59:14 +00:00
namespace dcx {
namespace {
static short N_ObjBitmapPtrs ;
static int Num_robot_ais ;
2006-03-20 17:12:09 +00:00
//---------------- Internal variables ---------------------------
static int SuperX = - 1 ;
static int Installed = 0 ;
static short tmap_count = 0 ;
static short texture_count = 0 ;
2020-10-07 03:59:14 +00:00
}
}
namespace dsx {
namespace {
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
static unsigned clip_count ;
static unsigned clip_num ;
static uint16_t frames ;
# elif defined(DXX_BUILD_DESCENT_II)
static char * arg ;
2006-03-20 17:12:09 +00:00
static short clip_count = 0 ;
static short clip_num ;
static short frames ;
2018-07-18 04:39:28 +00:00
static char * dest_bm ; //clip number to play when destroyed
# endif
2020-10-07 03:59:14 +00:00
}
}
namespace dcx {
namespace {
2018-07-18 04:39:28 +00:00
static short sound_num ;
2006-03-20 17:12:09 +00:00
static float play_time ;
static int hit_sound = - 1 ;
static int abm_flag = 0 ;
static int rod_flag = 0 ;
2020-04-04 19:30:22 +00:00
static short wall_open_sound , wall_close_sound ;
2015-12-04 03:36:31 +00:00
static float vlighting = 0 ;
2006-03-20 17:12:09 +00:00
static int obj_eclip ;
static int dest_vclip ; //what vclip to play when exploding
static int dest_eclip ; //what eclip to play when exploding
static fix dest_size ; //3d size of explosion
static int crit_clip ; //clip number to play when destroyed
static int crit_flag ; //flag if this is a destroyed eclip
static int num_sounds = 0 ;
2018-07-18 04:39:28 +00:00
static int linenum ; //line int table currently being parsed
2020-10-07 03:59:14 +00:00
}
}
2006-03-20 17:12:09 +00:00
//------------------- Useful macros and variables ---------------
# define IFTOK(str) if (!strcmp(arg, str))
2020-10-07 03:59:14 +00:00
namespace dsx {
namespace {
2006-03-20 17:12:09 +00:00
// For the sake of LINT, defining prototypes to module's functions
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
static void bm_read_sound ( char * & arg , int skip , int pc_shareware ) ;
2022-07-09 13:39:29 +00:00
static void bm_read_robot_ai ( d_robot_info_array & Robot_info , char * & arg , int skip ) ;
static void bm_read_robot ( d_level_shared_robot_info_state & LevelSharedRobotInfoState , char * & arg , int skip ) ;
2018-07-18 04:39:28 +00:00
static void bm_read_object ( char * & arg , int skip ) ;
static void bm_read_player_ship ( char * & arg , int skip ) ;
2018-10-21 00:24:07 +00:00
static void bm_read_some_file ( d_vclip_array & Vclip , const std : : string & dest_bm , char * & arg , int skip ) ;
2018-07-18 04:39:28 +00:00
static void bm_read_weapon ( char * & arg , int skip , int unused_flag ) ;
static void bm_read_powerup ( char * & arg , int unused_flag ) ;
static void bm_read_hostage ( char * & arg ) ;
static void verify_textures ( ) ;
# elif defined(DXX_BUILD_DESCENT_II)
2022-06-11 15:00:02 +00:00
# if DXX_USE_EDITOR
2013-09-22 22:26:27 +00:00
static void bm_read_alias ( void ) ;
2022-06-11 15:00:02 +00:00
# endif
2013-09-22 22:26:27 +00:00
static void bm_read_marker ( void ) ;
2022-07-09 13:39:29 +00:00
static void bm_read_robot_ai ( d_robot_info_array & Robot_info , int skip ) ;
2013-09-22 22:26:27 +00:00
static void bm_read_powerup ( int unused_flag ) ;
static void bm_read_hostage ( void ) ;
2022-07-09 13:39:29 +00:00
static void bm_read_robot ( d_level_shared_robot_info_state & LevelSharedRobotInfoState , int skip ) ;
2013-09-22 22:26:27 +00:00
static void bm_read_weapon ( int skip , int unused_flag ) ;
static void bm_read_reactor ( void ) ;
static void bm_read_exitmodel ( void ) ;
static void bm_read_player_ship ( void ) ;
2018-10-21 00:24:07 +00:00
static void bm_read_some_file ( d_vclip_array & Vclip , int skip ) ;
2015-01-18 01:58:33 +00:00
static void bm_read_sound ( int skip ) ;
2013-09-22 22:26:27 +00:00
static void clear_to_end_of_line ( void ) ;
static void verify_textures ( void ) ;
2018-07-18 04:39:28 +00:00
# endif
2020-10-07 03:59:14 +00:00
}
2006-03-20 17:12:09 +00:00
//---------------------------------------------------------------
2012-11-18 18:21:50 +00:00
int compute_average_pixel ( grs_bitmap * n )
2006-03-20 17:12:09 +00:00
{
int total_red , total_green , total_blue ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2016-09-04 00:02:52 +00:00
auto pptr = n - > bm_data ;
2018-07-18 04:39:28 +00:00
# endif
const unsigned bm_h = n - > bm_h , bm_w = n - > bm_w ;
2006-03-20 17:12:09 +00:00
total_red = 0 ;
total_green = 0 ;
total_blue = 0 ;
2018-07-18 04:39:28 +00:00
const auto product = ( bm_h * bm_w ) ;
# if defined(DXX_BUILD_DESCENT_I)
for ( unsigned row = 0 ; row < bm_h ; row + + )
for ( unsigned column = 0 ; column < bm_w ; column + + )
# elif defined(DXX_BUILD_DESCENT_II)
2016-12-11 01:56:44 +00:00
for ( auto counter = product ; counter - - ; )
2018-07-18 04:39:28 +00:00
# endif
2016-12-11 01:56:44 +00:00
{
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
const auto color = gr_gpixel ( * n , column , row ) ;
const auto & p = gr_palette [ color ] ;
# elif defined(DXX_BUILD_DESCENT_II)
2016-12-11 01:56:44 +00:00
const auto & p = gr_palette [ * pptr + + ] ;
2018-07-18 04:39:28 +00:00
# endif
2016-12-11 01:56:44 +00:00
total_red + = p . r ;
total_green + = p . g ;
total_blue + = p . b ;
2006-03-20 17:12:09 +00:00
}
2016-12-11 01:56:44 +00:00
total_red / = product ;
total_green / = product ;
total_blue / = product ;
2006-03-20 17:12:09 +00:00
return BM_XRGB ( total_red / 2 , total_green / 2 , total_blue / 2 ) ;
}
2022-07-09 13:39:29 +00:00
namespace {
2006-03-20 17:12:09 +00:00
//---------------------------------------------------------------
// Loads a bitmap from either the piggy file, a r64 file, or a
// whatever extension is passed.
2018-07-18 04:39:28 +00:00
static bitmap_index bm_load_sub ( const int skip , const char * const filename )
2006-03-20 17:12:09 +00:00
{
bitmap_index bitmap_num ;
2013-01-06 21:03:57 +00:00
palette_array_t newpal ;
2006-03-20 17:12:09 +00:00
int iff_error ; //reference parm to avoid warning message
bitmap_num . index = 0 ;
2008-02-11 12:12:57 +00:00
if ( skip ) {
2006-03-20 17:12:09 +00:00
return bitmap_num ;
}
2020-05-02 21:18:42 +00:00
std : : array < char , 20 > fname { } ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
removeext ( filename , fname ) ;
# elif defined(DXX_BUILD_DESCENT_II)
2022-06-11 15:00:02 +00:00
const auto path = d_splitpath ( filename ) ;
2018-08-26 18:10:36 +00:00
if ( path . base_end - path . base_start > = fname . size ( ) )
2013-06-09 18:10:09 +00:00
Error ( " File <%s> - bitmap error, filename too long " , filename ) ;
2018-08-26 18:10:36 +00:00
memcpy ( fname . data ( ) , path . base_start , path . base_end - path . base_start ) ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
2018-08-26 18:10:36 +00:00
bitmap_num = piggy_find_bitmap ( fname . data ( ) ) ;
2006-03-20 17:12:09 +00:00
if ( bitmap_num . index ) {
return bitmap_num ;
}
2013-12-08 00:30:12 +00:00
grs_bitmap n ;
2016-05-28 17:31:27 +00:00
iff_error = iff_read_bitmap ( filename , n , & newpal ) ;
2006-03-20 17:12:09 +00:00
if ( iff_error ! = IFF_NO_ERROR ) {
Error ( " File <%s> - IFF error: %s, line %d " , filename , iff_errormsg ( iff_error ) , linenum ) ;
}
2016-10-28 03:39:40 +00:00
gr_remap_bitmap_good ( n , newpal , iff_has_transparency ? iff_transparent_color : - 1 , SuperX ) ;
2006-03-20 17:12:09 +00:00
2020-05-22 02:40:26 +00:00
# if !DXX_USE_OGL
2013-12-08 00:30:12 +00:00
n . avg_color = compute_average_pixel ( & n ) ;
2020-05-22 02:40:26 +00:00
# endif
2006-03-20 17:12:09 +00:00
2022-10-02 19:51:35 +00:00
bitmap_num = piggy_register_bitmap ( n , fname , 0 ) ;
2006-03-20 17:12:09 +00:00
return bitmap_num ;
}
2020-05-02 21:18:42 +00:00
static void ab_load ( int skip , const char * filename , std : : array < bitmap_index , MAX_BITMAPS_PER_BRUSH > & bmp , unsigned * nframes )
2006-03-20 17:12:09 +00:00
{
bitmap_index bi ;
int iff_error ; //reference parm to avoid warning message
2013-01-06 21:03:57 +00:00
palette_array_t newpal ;
2020-05-02 21:18:42 +00:00
std : : array < char , 24 > tempname ;
2006-03-20 17:12:09 +00:00
2008-02-11 12:12:57 +00:00
if ( skip ) {
2006-03-20 17:12:09 +00:00
Assert ( bogus_bitmap_initialized ! = 0 ) ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
bmp [ 0 ] = piggy_register_bitmap ( bogus_bitmap , " bogus " , 0 ) ;
# elif defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
bmp [ 0 ] . index = 0 ; //index of bogus bitmap==0 (I think) //&bogus_bitmap;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
* nframes = 1 ;
return ;
}
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
2020-05-02 21:18:42 +00:00
std : : array < char , 20 > fname ;
2018-07-18 04:39:28 +00:00
removeext ( filename , fname ) ;
# elif defined(DXX_BUILD_DESCENT_II)
2022-06-11 15:00:02 +00:00
const auto path = d_splitpath ( filename ) ;
2018-07-18 04:39:28 +00:00
# endif
{
unsigned i ;
2006-03-20 17:12:09 +00:00
for ( i = 0 ; i < MAX_BITMAPS_PER_BRUSH ; i + + ) {
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
2018-08-26 18:10:36 +00:00
snprintf ( tempname . data ( ) , tempname . size ( ) , " %.16s#%d " , fname . data ( ) , i ) ;
2018-07-18 04:39:28 +00:00
# elif defined(DXX_BUILD_DESCENT_II)
2018-08-26 18:10:36 +00:00
snprintf ( tempname . data ( ) , tempname . size ( ) , " %.*s#%d " , DXX_ptrdiff_cast_int ( path . base_end - path . base_start ) , path . base_start , i ) ;
2018-07-18 04:39:28 +00:00
# endif
2018-08-26 18:10:36 +00:00
bi = piggy_find_bitmap ( tempname . data ( ) ) ;
2018-07-18 04:39:28 +00:00
if ( ! bi . index )
2006-03-20 17:12:09 +00:00
break ;
bmp [ i ] = bi ;
}
if ( i ) {
* nframes = i ;
return ;
}
2018-07-18 04:39:28 +00:00
}
2006-03-20 17:12:09 +00:00
// Note that last argument passes an address to the array newpal (which is a pointer).
// type mismatch found using lint, will substitute this line with an adjusted
// one. If fatal error, then it can be easily changed.
2020-05-02 21:18:42 +00:00
std : : array < std : : unique_ptr < grs_main_bitmap > , MAX_BITMAPS_PER_BRUSH > bm ;
2014-09-27 23:06:33 +00:00
iff_error = iff_read_animbrush ( filename , bm , nframes , newpal ) ;
2006-03-20 17:12:09 +00:00
if ( iff_error ! = IFF_NO_ERROR ) {
Error ( " File <%s> - IFF error: %s, line %d " , filename , iff_errormsg ( iff_error ) , linenum ) ;
}
2018-07-18 04:39:28 +00:00
const auto nf = * nframes ;
# if defined(DXX_BUILD_DESCENT_I)
if ( nf > = bm . size ( ) )
return ;
# endif
2019-05-04 18:27:37 +00:00
range_for ( const uint_fast32_t i , xrange ( nf ) )
2018-07-18 04:39:28 +00:00
{
2020-02-06 03:22:45 +00:00
cf_assert ( i < bm . size ( ) ) ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
2018-08-26 18:10:36 +00:00
snprintf ( tempname . data ( ) , tempname . size ( ) , " %s#% " PRIuFAST32 , fname . data ( ) , i ) ;
2018-07-18 04:39:28 +00:00
# elif defined(DXX_BUILD_DESCENT_II)
2018-08-26 18:10:36 +00:00
snprintf ( tempname . data ( ) , tempname . size ( ) , " %.*s#% " PRIuFAST32 , DXX_ptrdiff_cast_int ( path . base_end - path . base_start ) , path . base_start , i ) ;
2018-07-18 04:39:28 +00:00
# endif
2016-05-28 17:31:27 +00:00
gr_remap_bitmap_good ( * bm [ i ] . get ( ) , newpal , iff_has_transparency ? iff_transparent_color : - 1 , SuperX ) ;
2020-05-22 02:40:26 +00:00
# if !DXX_USE_OGL
2014-09-27 23:14:50 +00:00
bm [ i ] - > avg_color = compute_average_pixel ( bm [ i ] . get ( ) ) ;
2020-05-22 02:40:26 +00:00
# endif
2022-10-02 19:51:35 +00:00
bmp [ i ] = piggy_register_bitmap ( * bm [ i ] . get ( ) , tempname , 0 ) ;
2006-03-20 17:12:09 +00:00
}
}
2022-07-09 13:39:29 +00:00
}
2012-11-11 00:14:30 +00:00
int ds_load ( int skip , const char * filename ) {
2006-03-20 17:12:09 +00:00
int i ;
2012-11-18 18:21:50 +00:00
digi_sound n ;
2006-03-20 17:12:09 +00:00
char rawname [ 100 ] ;
2008-02-11 12:12:57 +00:00
if ( skip ) {
2010-12-04 05:45:43 +00:00
// We tell piggy_register_sound it's in the pig file, when in actual fact it's in no file
// This just tells piggy_close not to attempt to free it
2022-10-02 19:51:35 +00:00
return piggy_register_sound ( & bogus_sound , " bogus " , 1 , game_sound_offset { } ) ;
2006-03-20 17:12:09 +00:00
}
2020-05-02 21:18:42 +00:00
std : : array < char , 20 > fname ;
2006-03-20 17:12:09 +00:00
removeext ( filename , fname ) ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
2018-08-26 18:10:36 +00:00
snprintf ( rawname , sizeof ( rawname ) , " Sounds/%s.raw " , fname . data ( ) ) ;
2018-07-18 04:39:28 +00:00
# elif defined(DXX_BUILD_DESCENT_II)
2018-08-26 18:10:36 +00:00
snprintf ( rawname , sizeof ( rawname ) , " Sounds/%s.%s " , fname . data ( ) , ( GameArg . SndDigiSampleRate = = SAMPLE_RATE_22K ) ? " r22 " : " raw " ) ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
2018-08-26 18:10:36 +00:00
i = piggy_find_sound ( fname . data ( ) ) ;
2006-03-20 17:12:09 +00:00
if ( i ! = 255 ) {
return i ;
}
2021-07-25 23:00:56 +00:00
if ( auto cfp = PHYSFSX_openReadBuffered ( rawname ) . first )
2015-01-17 18:31:42 +00:00
{
2012-11-18 18:21:50 +00:00
n . length = PHYSFS_fileLength ( cfp ) ;
MALLOC ( n . data , ubyte , n . length ) ;
PHYSFS_read ( cfp , n . data , 1 , n . length ) ;
n . freq = 11025 ;
2006-03-20 17:12:09 +00:00
} else {
return 255 ;
}
2022-10-02 19:51:35 +00:00
i = piggy_register_sound ( & n , fname . data ( ) , 0 , game_sound_offset { } ) ;
2006-03-20 17:12:09 +00:00
return i ;
}
2020-10-07 03:59:14 +00:00
}
2022-07-09 13:39:29 +00:00
namespace dcx {
2020-10-07 03:59:14 +00:00
namespace {
2006-03-20 17:12:09 +00:00
//parse a float
2013-10-27 22:00:14 +00:00
static float get_float ( )
2006-03-20 17:12:09 +00:00
{
char * xarg ;
2015-01-29 04:27:35 +00:00
xarg = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
return atof ( xarg ) ;
}
//parse an int
2013-10-27 22:00:14 +00:00
static int get_int ( )
2006-03-20 17:12:09 +00:00
{
char * xarg ;
2015-01-29 04:27:35 +00:00
xarg = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
return atoi ( xarg ) ;
}
2020-10-07 03:59:14 +00:00
}
2022-07-09 13:39:29 +00:00
}
2006-03-20 17:12:09 +00:00
2020-10-07 03:59:14 +00:00
namespace dsx {
namespace {
2006-03-20 17:12:09 +00:00
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
//loads a texture and returns the texture num
2013-10-27 22:00:14 +00:00
static int get_texture ( char * name )
2006-03-20 17:12:09 +00:00
{
2018-12-30 00:43:59 +00:00
auto & TmapInfo = LevelUniqueTmapInfoState . TmapInfo ;
2006-03-20 17:12:09 +00:00
char short_name [ FILENAME_LEN ] ;
int i ;
strcpy ( short_name , name ) ;
REMOVE_DOTS ( short_name ) ;
for ( i = 0 ; i < texture_count ; i + + )
2012-05-18 23:36:43 +00:00
if ( ! d_stricmp ( TmapInfo [ i ] . filename , short_name ) )
2006-03-20 17:12:09 +00:00
break ;
if ( i = = texture_count ) {
2008-02-11 12:12:57 +00:00
Textures [ texture_count ] = bm_load_sub ( 0 , name ) ;
2014-07-23 02:27:22 +00:00
TmapInfo [ texture_count ] . filename . copy_if ( short_name ) ;
2006-03-20 17:12:09 +00:00
texture_count + + ;
Assert ( texture_count < MAX_TEXTURES ) ;
NumTextures = texture_count ;
}
return i ;
}
# define DEFAULT_PIG_PALETTE "groupa.256"
2018-07-18 04:39:28 +00:00
# endif
2020-10-07 03:59:14 +00:00
}
2018-07-18 04:39:28 +00:00
# define LINEBUF_SIZE 600
2006-03-20 17:12:09 +00:00
2022-06-11 15:00:02 +00:00
# if defined(DXX_BUILD_DESCENT_I) || (defined(DXX_BUILD_DESCENT_II) && DXX_USE_EDITOR)
2006-03-20 17:12:09 +00:00
//-----------------------------------------------------------------
2008-02-11 12:12:57 +00:00
// Initializes all properties and bitmaps from BITMAPS.TBL file.
2006-03-20 17:12:09 +00:00
// This is called when the editor is IN.
2008-02-11 12:12:57 +00:00
// If no editor, properties_read_cmp() is called.
2022-07-09 13:39:29 +00:00
int gamedata_read_tbl ( d_level_shared_robot_info_state & LevelSharedRobotInfoState , d_vclip_array & Vclip , int pc_shareware )
2006-03-20 17:12:09 +00:00
{
2019-03-03 00:31:09 +00:00
auto & Effects = LevelUniqueEffectsClipState . Effects ;
2018-12-30 00:43:59 +00:00
auto & TmapInfo = LevelUniqueTmapInfoState . TmapInfo ;
2020-04-04 19:30:22 +00:00
auto & WallAnims = GameSharedState . WallAnims ;
2016-05-22 17:49:31 +00:00
int have_bin_tbl ;
2006-03-20 17:12:09 +00:00
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
std : : string dest_bm ;
ObjType [ 0 ] = OL_PLAYER ;
ObjId [ 0 ] = 0 ;
Num_total_object_types = 1 ;
# elif defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
// Open BITMAPS.TBL for reading.
have_bin_tbl = 0 ;
2021-07-25 23:00:56 +00:00
auto InfoFile = PHYSFSX_openReadBuffered ( " BITMAPS.TBL " ) . first ;
2015-01-17 18:31:42 +00:00
if ( ! InfoFile )
{
2021-07-25 23:00:56 +00:00
InfoFile = PHYSFSX_openReadBuffered ( " BITMAPS.BIN " ) . first ;
2015-01-17 18:31:42 +00:00
if ( ! InfoFile )
2006-03-20 17:12:09 +00:00
return 0 ; //missing BITMAPS.TBL and BITMAPS.BIN file
have_bin_tbl = 1 ;
}
gr_use_palette_table ( DEFAULT_PIG_PALETTE ) ;
load_palette ( DEFAULT_PIG_PALETTE , - 2 , 0 ) ; //special: tell palette code which pig is loaded
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
2020-08-24 01:31:28 +00:00
Sounds . fill ( 255 ) ;
AltSounds . fill ( 255 ) ;
2006-03-20 17:12:09 +00:00
2020-04-04 19:30:22 +00:00
DXX_MAKE_VAR_UNDEFINED ( TmapInfo ) ;
2016-05-22 17:49:31 +00:00
range_for ( auto & ti , TmapInfo )
{
ti . eclip_num = eclip_none ;
2021-11-01 03:37:20 +00:00
ti . flags = { } ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2016-05-22 17:49:31 +00:00
ti . slide_u = ti . slide_v = 0 ;
ti . destroyed = - 1 ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
}
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2020-04-04 19:30:22 +00:00
DXX_MAKE_VAR_UNDEFINED ( Reactors ) ;
2015-08-26 03:15:10 +00:00
range_for ( auto & i , Reactors )
i . model_num = - 1 ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
Num_effects = 0 ;
2020-04-04 19:30:22 +00:00
DXX_MAKE_VAR_UNDEFINED ( Effects ) ;
2016-05-22 17:49:31 +00:00
range_for ( auto & ec , Effects )
{
2006-03-20 17:12:09 +00:00
//Effects[i].bm_ptr = (grs_bitmap **) -1;
2014-01-19 22:58:24 +00:00
ec . changing_wall_texture = - 1 ;
2020-10-07 03:59:14 +00:00
ec . changing_object_texture = object_bitmap_index : : None ;
2014-01-19 22:58:24 +00:00
ec . segnum = segment_none ;
ec . vc . num_frames = - 1 ; //another mark of being unused
2006-03-20 17:12:09 +00:00
}
2016-05-22 17:49:31 +00:00
for ( unsigned i = 0 ; i < MAX_POLYGON_MODELS ; + + i )
2006-03-20 17:12:09 +00:00
Dying_modelnums [ i ] = Dead_modelnums [ i ] = - 1 ;
Num_vclips = 0 ;
2020-04-04 19:30:22 +00:00
DXX_MAKE_VAR_UNDEFINED ( Vclip ) ;
2016-05-22 17:49:31 +00:00
range_for ( auto & vc , Vclip )
{
vc . num_frames = - 1 ;
vc . flags = 0 ;
2006-03-20 17:12:09 +00:00
}
2020-04-04 19:30:22 +00:00
DXX_MAKE_VAR_UNDEFINED ( WallAnims ) ;
2016-05-22 17:49:31 +00:00
range_for ( auto & wa , WallAnims )
2017-06-17 23:05:16 +00:00
wa . num_frames = wclip_frames_none ;
2006-03-20 17:12:09 +00:00
Num_wall_anims = 0 ;
if ( Installed )
return 1 ;
Installed = 1 ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
// Open BITMAPS.TBL for reading.
have_bin_tbl = 0 ;
2021-07-25 23:00:56 +00:00
auto & & [ InfoFile , physfserr ] = PHYSFSX_openReadBuffered ( " BITMAPS.TBL " ) ;
2018-07-18 04:39:28 +00:00
if ( ! InfoFile )
{
2021-07-25 23:00:56 +00:00
auto & & [ InfoFileBin , physfserr2 ] = PHYSFSX_openReadBuffered ( " BITMAPS.BIN " ) ;
if ( ! InfoFileBin )
Error ( " Failed to open BITMAPS.TBL and BITMAPS.BIN: \" %s \" , \" %s \" \n " , PHYSFS_getErrorByCode ( physfserr ) , PHYSFS_getErrorByCode ( physfserr2 ) ) ;
InfoFile = std : : move ( InfoFileBin ) ;
2018-07-18 04:39:28 +00:00
have_bin_tbl = 1 ;
}
# endif
2006-03-20 17:12:09 +00:00
linenum = 0 ;
2018-07-18 04:39:28 +00:00
2011-06-01 07:59:55 +00:00
PHYSFSX_fseek ( InfoFile , 0L , SEEK_SET ) ;
2006-03-20 17:12:09 +00:00
2014-09-07 19:48:10 +00:00
PHYSFSX_gets_line_t < LINEBUF_SIZE > inputline ;
2013-11-23 00:13:36 +00:00
while ( PHYSFSX_fgets ( inputline , InfoFile ) ) {
2006-03-20 17:12:09 +00:00
int l ;
2018-07-18 04:39:28 +00:00
const char * temp_ptr ;
2008-02-11 12:12:57 +00:00
int skip ;
2006-03-20 17:12:09 +00:00
linenum + + ;
if ( have_bin_tbl ) { // is this a binary tbl file
decode_text_line ( inputline ) ;
} else {
while ( inputline [ ( l = strlen ( inputline ) ) - 2 ] = = ' \\ ' ) {
if ( ! isspace ( inputline [ l - 3 ] ) ) { //if not space before backslash...
inputline [ l - 2 ] = ' ' ; //add one
l + + ;
}
2022-10-02 19:51:35 +00:00
if ( ! PHYSFSX_fgets ( inputline , InfoFile , l - 2 ) )
break ;
2006-03-20 17:12:09 +00:00
linenum + + ;
}
}
REMOVE_EOL ( inputline ) ;
if ( strchr ( inputline , ' ; ' ) ! = NULL ) REMOVE_COMMENTS ( inputline ) ;
if ( strlen ( inputline ) = = LINEBUF_SIZE - 1 )
Error ( " Possible line truncation in BITMAPS.TBL on line %d \n " , linenum ) ;
SuperX = - 1 ;
if ( ( temp_ptr = strstr ( inputline , " superx= " ) ) ) {
2019-11-18 00:22:34 +00:00
/* Historically, this was done with atoi, so the input
* source was allowed to have unconvertible characters .
* Accept such lines by ignoring any trailing content .
*/
SuperX = strtol ( & temp_ptr [ 7 ] , nullptr , 10 ) ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
Assert ( SuperX = = 254 ) ;
//the superx color isn't kept around, so the new piggy regeneration
//code doesn't know what it is, so it assumes that it's 254, so
//this code requires that it be 254
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
}
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
char * arg = strtok ( inputline , space_tab ) ;
# elif defined(DXX_BUILD_DESCENT_II)
2015-01-29 04:27:35 +00:00
arg = strtok ( inputline , space_tab ) ;
2018-07-18 04:39:28 +00:00
# endif
2020-05-22 02:40:26 +00:00
if ( arg & & arg [ 0 ] = = ' @ ' )
2018-07-18 04:39:28 +00:00
{
2006-03-20 17:12:09 +00:00
arg + + ;
2008-02-11 12:12:57 +00:00
skip = pc_shareware ;
2006-03-20 17:12:09 +00:00
} else
2008-02-11 12:12:57 +00:00
skip = 0 ;
2006-03-20 17:12:09 +00:00
while ( arg ! = NULL )
{
// Check all possible flags and defines.
2020-10-07 03:59:14 +00:00
if ( * arg = = ' $ ' ) current_bm_type = bm_type : : none ; // reset to no flags as default.
2006-03-20 17:12:09 +00:00
2020-10-07 03:59:14 +00:00
IFTOK ( " $COCKPIT " ) current_bm_type = bm_type : : cockpit ;
else IFTOK ( " $GAUGES " ) { current_bm_type = bm_type : : gauges ; clip_count = 0 ; }
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
else IFTOK ( " $SOUND " ) bm_read_sound ( arg , skip , pc_shareware ) ;
# elif defined(DXX_BUILD_DESCENT_II)
2020-10-07 03:59:14 +00:00
else IFTOK ( " $GAUGES_HIRES " ) { current_bm_type = bm_type : : gauges_hires ; clip_count = 0 ; }
2013-11-10 03:31:22 +00:00
else IFTOK ( " $ALIAS " ) bm_read_alias ( ) ;
2015-01-18 01:58:33 +00:00
else IFTOK ( " $SOUND " ) bm_read_sound ( skip ) ;
2018-07-18 04:39:28 +00:00
# endif
2020-10-07 03:59:14 +00:00
else IFTOK ( " $DOOR_ANIMS " ) current_bm_type = bm_type : : wall_anims ;
else IFTOK ( " $WALL_ANIMS " ) current_bm_type = bm_type : : wall_anims ;
else IFTOK ( " $TEXTURES " ) current_bm_type = bm_type : : textures ;
else IFTOK ( " $VCLIP " ) { current_bm_type = bm_type : : vclip ; vlighting = 0 ; clip_count = 0 ; }
2014-10-04 15:04:44 +00:00
else IFTOK ( " $ECLIP " )
{
2020-10-07 03:59:14 +00:00
current_bm_type = bm_type : : eclip ;
2014-10-04 15:04:44 +00:00
vlighting = 0 ;
clip_count = 0 ;
obj_eclip = 0 ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
dest_bm . clear ( ) ;
# elif defined(DXX_BUILD_DESCENT_II)
2014-10-04 15:04:44 +00:00
dest_bm = NULL ;
2018-07-18 04:39:28 +00:00
# endif
2014-10-04 15:04:44 +00:00
dest_vclip = vclip_none ;
dest_eclip = eclip_none ;
dest_size = - 1 ;
crit_clip = - 1 ;
crit_flag = 0 ;
sound_num = sound_none ;
}
else IFTOK ( " $WCLIP " )
{
2020-10-07 03:59:14 +00:00
current_bm_type = bm_type : : wclip ;
2014-10-04 15:04:44 +00:00
vlighting = 0 ;
clip_count = 0 ;
wall_open_sound = wall_close_sound = sound_none ;
2020-04-04 19:30:22 +00:00
wall_explodes_flag = 0 ;
wall_blastable_flag = 0 ;
2014-10-04 15:04:44 +00:00
tmap1_flag = 0 ;
2020-04-04 19:30:22 +00:00
wall_hidden_flag = 0 ;
2014-10-04 15:04:44 +00:00
}
2006-03-20 17:12:09 +00:00
2020-10-07 03:59:14 +00:00
else IFTOK ( " $EFFECTS " ) { current_bm_type = bm_type : : effects ; clip_num = 0 ; }
2006-03-20 17:12:09 +00:00
2016-09-11 18:49:16 +00:00
# if DXX_USE_EDITOR
2006-03-20 17:12:09 +00:00
else IFTOK ( " !METALS_FLAG " ) TextureMetals = texture_count ;
else IFTOK ( " !LIGHTS_FLAG " ) TextureLights = texture_count ;
else IFTOK ( " !EFFECTS_FLAG " ) TextureEffects = texture_count ;
2018-07-18 04:39:28 +00:00
# else
# if defined(DXX_BUILD_DESCENT_I)
else IFTOK ( " !METALS_FLAG " ) ;
else IFTOK ( " !LIGHTS_FLAG " ) ;
else IFTOK ( " !EFFECTS_FLAG " ) ;
# endif
2006-03-20 17:12:09 +00:00
# endif
else IFTOK ( " lighting " ) TmapInfo [ texture_count - 1 ] . lighting = fl2f ( get_float ( ) ) ;
else IFTOK ( " damage " ) TmapInfo [ texture_count - 1 ] . damage = fl2f ( get_float ( ) ) ;
2021-11-01 03:37:20 +00:00
else IFTOK ( " volatile " ) TmapInfo [ texture_count - 1 ] . flags | = tmapinfo_flag : : lava ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2021-11-01 03:37:20 +00:00
else IFTOK ( " goal_blue " ) TmapInfo [ texture_count - 1 ] . flags | = tmapinfo_flag : : goal_blue ;
else IFTOK ( " goal_red " ) TmapInfo [ texture_count - 1 ] . flags | = tmapinfo_flag : : goal_red ;
else IFTOK ( " water " ) TmapInfo [ texture_count - 1 ] . flags | = tmapinfo_flag : : water ;
else IFTOK ( " force_field " ) TmapInfo [ texture_count - 1 ] . flags | = tmapinfo_flag : : force_field ;
2006-03-20 17:12:09 +00:00
else IFTOK ( " slide " ) { TmapInfo [ texture_count - 1 ] . slide_u = fl2f ( get_float ( ) ) > > 8 ; TmapInfo [ texture_count - 1 ] . slide_v = fl2f ( get_float ( ) ) > > 8 ; }
2015-01-29 04:27:35 +00:00
else IFTOK ( " destroyed " ) { int t = texture_count - 1 ; TmapInfo [ t ] . destroyed = get_texture ( strtok ( NULL , space_tab ) ) ; }
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
//else IFTOK("Num_effects") Num_effects = get_int();
else IFTOK ( " Num_wall_anims " ) Num_wall_anims = get_int ( ) ;
else IFTOK ( " clip_num " ) clip_num = get_int ( ) ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
else IFTOK ( " dest_bm " )
{
char * p = strtok ( NULL , space_tab ) ;
if ( p )
dest_bm = p ;
else
dest_bm . clear ( ) ;
}
# elif defined(DXX_BUILD_DESCENT_II)
2015-01-29 04:27:35 +00:00
else IFTOK ( " dest_bm " ) dest_bm = strtok ( NULL , space_tab ) ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
else IFTOK ( " dest_vclip " ) dest_vclip = get_int ( ) ;
else IFTOK ( " dest_eclip " ) dest_eclip = get_int ( ) ;
else IFTOK ( " dest_size " ) dest_size = fl2f ( get_float ( ) ) ;
else IFTOK ( " crit_clip " ) crit_clip = get_int ( ) ;
else IFTOK ( " crit_flag " ) crit_flag = get_int ( ) ;
else IFTOK ( " sound_num " ) sound_num = get_int ( ) ;
else IFTOK ( " frames " ) frames = get_int ( ) ;
else IFTOK ( " time " ) play_time = get_float ( ) ;
else IFTOK ( " obj_eclip " ) obj_eclip = get_int ( ) ;
else IFTOK ( " hit_sound " ) hit_sound = get_int ( ) ;
else IFTOK ( " abm_flag " ) abm_flag = get_int ( ) ;
2020-04-04 19:30:22 +00:00
else IFTOK ( " tmap1_flag " ) tmap1_flag = get_int ( ) ? WCF_TMAP1 : 0 ;
2006-03-20 17:12:09 +00:00
else IFTOK ( " vlighting " ) vlighting = get_float ( ) ;
else IFTOK ( " rod_flag " ) rod_flag = get_int ( ) ;
else IFTOK ( " superx " ) get_int ( ) ;
else IFTOK ( " open_sound " ) wall_open_sound = get_int ( ) ;
else IFTOK ( " close_sound " ) wall_close_sound = get_int ( ) ;
2020-04-04 19:30:22 +00:00
else IFTOK ( " explodes " ) wall_explodes_flag = get_int ( ) ? WCF_EXPLODES : 0 ;
else IFTOK ( " blastable " ) wall_blastable_flag = get_int ( ) ? WCF_BLASTABLE : 0 ;
else IFTOK ( " hidden " ) wall_hidden_flag = get_int ( ) ? WCF_HIDDEN : 0 ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
2022-07-09 13:39:29 +00:00
else IFTOK ( " $ROBOT_AI " ) bm_read_robot_ai ( LevelSharedRobotInfoState . Robot_info , arg , skip ) ;
2018-07-18 04:39:28 +00:00
else IFTOK ( " $POWERUP " ) { bm_read_powerup ( arg , 0 ) ; continue ; }
else IFTOK ( " $POWERUP_UNUSED " ) { bm_read_powerup ( arg , 1 ) ; continue ; }
else IFTOK ( " $HOSTAGE " ) { bm_read_hostage ( arg ) ; continue ; }
2022-07-09 13:39:29 +00:00
else IFTOK ( " $ROBOT " ) { bm_read_robot ( LevelSharedRobotInfoState , arg , skip ) ; continue ; }
2018-07-18 04:39:28 +00:00
else IFTOK ( " $WEAPON " ) { bm_read_weapon ( arg , skip , 0 ) ; continue ; }
else IFTOK ( " $WEAPON_UNUSED " ) { bm_read_weapon ( arg , skip , 1 ) ; continue ; }
else IFTOK ( " $OBJECT " ) { bm_read_object ( arg , skip ) ; continue ; }
else IFTOK ( " $PLAYER_SHIP " ) { bm_read_player_ship ( arg , skip ) ; continue ; }
# elif defined(DXX_BUILD_DESCENT_II)
2022-07-09 13:39:29 +00:00
else IFTOK ( " $ROBOT_AI " ) bm_read_robot_ai ( LevelSharedRobotInfoState . Robot_info , skip ) ;
2006-03-20 17:12:09 +00:00
else IFTOK ( " $POWERUP " ) { bm_read_powerup ( 0 ) ; continue ; }
else IFTOK ( " $POWERUP_UNUSED " ) { bm_read_powerup ( 1 ) ; continue ; }
else IFTOK ( " $HOSTAGE " ) { bm_read_hostage ( ) ; continue ; }
2022-07-09 13:39:29 +00:00
else IFTOK ( " $ROBOT " ) { bm_read_robot ( LevelSharedRobotInfoState , skip ) ; continue ; }
2008-02-11 12:12:57 +00:00
else IFTOK ( " $WEAPON " ) { bm_read_weapon ( skip , 0 ) ; continue ; }
else IFTOK ( " $WEAPON_UNUSED " ) { bm_read_weapon ( skip , 1 ) ; continue ; }
2006-03-20 17:12:09 +00:00
else IFTOK ( " $REACTOR " ) { bm_read_reactor ( ) ; continue ; }
else IFTOK ( " $MARKER " ) { bm_read_marker ( ) ; continue ; }
else IFTOK ( " $PLAYER_SHIP " ) { bm_read_player_ship ( ) ; continue ; }
else IFTOK ( " $EXIT " ) {
2008-02-11 12:12:57 +00:00
if ( pc_shareware )
2018-07-18 04:39:28 +00:00
bm_read_exitmodel ( ) ;
2008-02-11 12:12:57 +00:00
else
2006-03-20 17:12:09 +00:00
clear_to_end_of_line ( ) ;
continue ;
}
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
else { //not a special token, must be a bitmap!
// Remove any illegal/unwanted spaces and tabs at this point.
while ( ( * arg = = ' \t ' ) | | ( * arg = = ' ' ) ) arg + + ;
2018-07-18 04:39:28 +00:00
if ( * arg = = ' \0 ' ) { break ; }
2006-03-20 17:12:09 +00:00
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
//check for '=' in token, indicating error
if ( strchr ( arg , ' = ' ) )
Error ( " Unknown token <'%s'> on line %d of BITMAPS.TBL " , arg , linenum ) ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
// Otherwise, 'arg' is apparently a bitmap filename.
// Load bitmap and process it below:
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
2018-10-21 00:24:07 +00:00
bm_read_some_file ( Vclip , dest_bm , arg , skip ) ;
2018-07-18 04:39:28 +00:00
# elif defined(DXX_BUILD_DESCENT_II)
2018-10-21 00:24:07 +00:00
bm_read_some_file ( Vclip , skip ) ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
}
arg = strtok ( NULL , equal_space ) ;
continue ;
}
}
NumTextures = texture_count ;
2018-12-30 00:43:59 +00:00
LevelUniqueTmapInfoState . Num_tmaps = tmap_count ;
2006-03-20 17:12:09 +00:00
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
Textures [ NumTextures + + ] . index = 0 ; //entry for bogus tmap
2015-01-17 18:31:42 +00:00
InfoFile . reset ( ) ;
2018-07-18 04:39:28 +00:00
# endif
2018-12-30 00:43:59 +00:00
assert ( LevelSharedRobotInfoState . N_robot_types = = Num_robot_ais ) ; //should be one ai info per robot
2006-03-20 17:12:09 +00:00
verify_textures ( ) ;
//check for refereced but unused clip count
2021-06-28 03:37:50 +00:00
for ( auto & & [ idx , e ] : enumerate ( Effects ) )
2016-12-11 01:56:44 +00:00
{
2020-10-07 03:59:14 +00:00
if ( ( e . changing_wall_texture ! = - 1 | | e . changing_object_texture ! = object_bitmap_index : : None ) & & e . vc . num_frames = = ~ 0u )
2022-10-09 23:15:20 +00:00
Error ( " EClip % " DXX_PRI_size_type " referenced (by polygon object?), but not defined " , idx ) ;
2016-12-11 01:56:44 +00:00
}
2006-03-20 17:12:09 +00:00
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
# ifndef NDEBUG
{
//make sure all alt sounds refer to valid main sounds
2016-05-22 17:49:31 +00:00
for ( unsigned i = 0 ; i < num_sounds ; + + i )
{
2006-03-20 17:12:09 +00:00
int alt = AltSounds [ i ] ;
Assert ( alt = = 0 | | alt = = - 1 | | Sounds [ alt ] ! = 255 ) ;
}
}
# endif
2007-06-11 15:54:09 +00:00
gr_use_palette_table ( D2_DEFAULT_PALETTE ) ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
return 0 ;
}
2022-06-11 15:00:02 +00:00
# endif
2006-03-20 17:12:09 +00:00
2020-10-07 03:59:14 +00:00
namespace {
2016-06-25 23:21:36 +00:00
2006-03-20 17:12:09 +00:00
void verify_textures ( )
{
2019-03-03 00:31:09 +00:00
# if defined(DXX_BUILD_DESCENT_II)
auto & Effects = LevelUniqueEffectsClipState . Effects ;
# endif
2006-03-20 17:12:09 +00:00
grs_bitmap * bmp ;
2018-07-18 04:39:28 +00:00
int j ;
2006-03-20 17:12:09 +00:00
j = 0 ;
2018-12-30 00:43:59 +00:00
const auto Num_tmaps = LevelUniqueTmapInfoState . Num_tmaps ;
2018-07-18 04:39:28 +00:00
for ( uint_fast32_t i = 0 ; i < Num_tmaps ; + + i )
{
2006-03-20 17:12:09 +00:00
bmp = & GameBitmaps [ Textures [ i ] . index ] ;
if ( ( bmp - > bm_w ! = 64 ) | | ( bmp - > bm_h ! = 64 ) | | ( bmp - > bm_rowsize ! = 64 ) ) {
j + + ;
}
}
if ( j )
2008-04-06 20:23:28 +00:00
Error ( " %d textures were not 64x64. " , j ) ;
2006-03-20 17:12:09 +00:00
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
for ( uint_fast32_t i = 0 ; i < Num_effects ; + + i )
2020-10-07 03:59:14 +00:00
if ( const auto changing_object_texture = Effects [ i ] . changing_object_texture ; changing_object_texture ! = object_bitmap_index : : None )
{
const auto & o = ObjBitmaps [ changing_object_texture ] . index ;
if ( GameBitmaps [ o ] . bm_w ! = 64 | | GameBitmaps [ o ] . bm_h ! = 64 )
2018-07-18 04:39:28 +00:00
Error ( " Effect % " PRIuFAST32 " is used on object, but is not 64x64 " , i ) ;
2020-10-07 03:59:14 +00:00
}
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
}
2022-06-11 15:00:02 +00:00
# if defined(DXX_BUILD_DESCENT_II) && DXX_USE_EDITOR
2006-03-20 17:12:09 +00:00
void bm_read_alias ( )
{
char * t ;
Assert ( Num_aliases < MAX_ALIASES ) ;
2015-01-29 04:27:35 +00:00
t = strtok ( NULL , space_tab ) ; strncpy ( alias_list [ Num_aliases ] . alias_name , t , sizeof ( alias_list [ Num_aliases ] . alias_name ) ) ;
t = strtok ( NULL , space_tab ) ; strncpy ( alias_list [ Num_aliases ] . file_name , t , sizeof ( alias_list [ Num_aliases ] . file_name ) ) ;
2006-03-20 17:12:09 +00:00
Num_aliases + + ;
}
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
2020-10-07 03:59:14 +00:00
}
}
2022-07-09 13:39:29 +00:00
namespace {
2015-07-25 23:10:47 +00:00
static void set_lighting_flag ( grs_bitmap & bmp )
2006-03-20 17:12:09 +00:00
{
2017-01-15 00:03:13 +00:00
bmp . set_flag_mask ( vlighting < 0 , BM_FLAG_NO_LIGHTING ) ;
2006-03-20 17:12:09 +00:00
}
2018-07-18 04:39:28 +00:00
static void set_texture_name ( const char * name )
2006-03-20 17:12:09 +00:00
{
2018-12-30 00:43:59 +00:00
auto & TmapInfo = LevelUniqueTmapInfoState . TmapInfo ;
2014-07-23 02:27:22 +00:00
TmapInfo [ texture_count ] . filename . copy_if ( name , FILENAME_LEN ) ;
2014-07-26 22:45:01 +00:00
REMOVE_DOTS ( & TmapInfo [ texture_count ] . filename [ 0u ] ) ;
2006-03-20 17:12:09 +00:00
}
2022-07-09 13:39:29 +00:00
}
namespace dsx {
namespace {
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
static void bm_read_eclip ( const std : : string & dest_bm , const char * const arg , int skip )
# elif defined(DXX_BUILD_DESCENT_II)
2013-10-27 22:00:14 +00:00
static void bm_read_eclip ( int skip )
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
{
2019-03-03 00:31:09 +00:00
auto & Effects = LevelUniqueEffectsClipState . Effects ;
2018-12-30 00:43:59 +00:00
auto & TmapInfo = LevelUniqueTmapInfoState . TmapInfo ;
2006-03-20 17:12:09 +00:00
bitmap_index bitmap ;
2017-10-14 17:10:31 +00:00
assert ( clip_num < Effects . size ( ) ) ;
2006-03-20 17:12:09 +00:00
if ( clip_num + 1 > Num_effects )
Num_effects = clip_num + 1 ;
Effects [ clip_num ] . flags = 0 ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2018-03-31 21:53:01 +00:00
unsigned dest_bm_num = 0 ;
2006-03-20 17:12:09 +00:00
//load the dest bitmap first, so that after this routine, the last-loaded
//texture will be the monitor, so that lighting parameter will be applied
//to the correct texture
if ( dest_bm ) { //deal with bitmap for blown up clip
2014-07-23 02:27:22 +00:00
d_fname short_name ;
2006-03-20 17:12:09 +00:00
int i ;
2014-07-23 02:27:22 +00:00
short_name . copy_if ( dest_bm , FILENAME_LEN ) ;
2014-07-26 22:45:01 +00:00
REMOVE_DOTS ( & short_name [ 0u ] ) ;
2006-03-20 17:12:09 +00:00
for ( i = 0 ; i < texture_count ; i + + )
2012-05-18 23:36:43 +00:00
if ( ! d_stricmp ( TmapInfo [ i ] . filename , short_name ) )
2006-03-20 17:12:09 +00:00
break ;
if ( i = = texture_count ) {
2008-02-11 12:12:57 +00:00
Textures [ texture_count ] = bm_load_sub ( skip , dest_bm ) ;
2014-07-23 02:27:22 +00:00
TmapInfo [ texture_count ] . filename = short_name ;
2006-03-20 17:12:09 +00:00
texture_count + + ;
Assert ( texture_count < MAX_TEXTURES ) ;
NumTextures = texture_count ;
}
else if ( Textures [ i ] . index = = 0 ) //was found, but registered out
2008-02-11 12:12:57 +00:00
Textures [ i ] = bm_load_sub ( skip , dest_bm ) ;
2006-03-20 17:12:09 +00:00
dest_bm_num = i ;
}
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
2018-07-18 04:39:28 +00:00
if ( ! abm_flag )
{
2008-02-11 12:12:57 +00:00
bitmap = bm_load_sub ( skip , arg ) ;
2006-03-20 17:12:09 +00:00
Effects [ clip_num ] . vc . play_time = fl2f ( play_time ) ;
Effects [ clip_num ] . vc . num_frames = frames ;
Effects [ clip_num ] . vc . frame_time = fl2f ( play_time ) / frames ;
Assert ( clip_count < frames ) ;
Effects [ clip_num ] . vc . frames [ clip_count ] = bitmap ;
2015-07-25 23:10:47 +00:00
set_lighting_flag ( GameBitmaps [ bitmap . index ] ) ;
2006-03-20 17:12:09 +00:00
Assert ( ! obj_eclip ) ; //obj eclips for non-abm files not supported!
Assert ( crit_flag = = 0 ) ;
if ( clip_count = = 0 ) {
Effects [ clip_num ] . changing_wall_texture = texture_count ;
Assert ( tmap_count < MAX_TEXTURES ) ;
2013-12-22 00:54:00 +00:00
tmap_count + + ;
2006-03-20 17:12:09 +00:00
Textures [ texture_count ] = bitmap ;
set_texture_name ( arg ) ;
Assert ( texture_count < MAX_TEXTURES ) ;
texture_count + + ;
TmapInfo [ texture_count ] . eclip_num = clip_num ;
NumTextures = texture_count ;
}
clip_count + + ;
} else {
2020-05-02 21:18:42 +00:00
std : : array < bitmap_index , MAX_BITMAPS_PER_BRUSH > bm ;
2006-03-20 17:12:09 +00:00
abm_flag = 0 ;
2008-02-11 12:12:57 +00:00
ab_load ( skip , arg , bm , & Effects [ clip_num ] . vc . num_frames ) ;
2006-03-20 17:12:09 +00:00
Effects [ clip_num ] . vc . play_time = fl2f ( play_time ) ;
Effects [ clip_num ] . vc . frame_time = Effects [ clip_num ] . vc . play_time / Effects [ clip_num ] . vc . num_frames ;
2018-07-18 04:39:28 +00:00
clip_count = 0 ;
2015-07-25 23:10:47 +00:00
set_lighting_flag ( GameBitmaps [ bm [ clip_count ] . index ] ) ;
2006-03-20 17:12:09 +00:00
Effects [ clip_num ] . vc . frames [ clip_count ] = bm [ clip_count ] ;
if ( ! obj_eclip & & ! crit_flag ) {
Effects [ clip_num ] . changing_wall_texture = texture_count ;
Assert ( tmap_count < MAX_TEXTURES ) ;
2013-12-22 00:54:00 +00:00
tmap_count + + ;
2006-03-20 17:12:09 +00:00
Textures [ texture_count ] = bm [ clip_count ] ;
set_texture_name ( arg ) ;
Assert ( texture_count < MAX_TEXTURES ) ;
TmapInfo [ texture_count ] . eclip_num = clip_num ;
texture_count + + ;
NumTextures = texture_count ;
}
if ( obj_eclip ) {
2020-10-07 03:59:14 +00:00
if ( Effects [ clip_num ] . changing_object_texture = = object_bitmap_index : : None )
{ //first time referenced
Effects [ clip_num ] . changing_object_texture = static_cast < object_bitmap_index > ( N_ObjBitmaps ) ; // XChange ObjectBitmaps
2006-03-20 17:12:09 +00:00
N_ObjBitmaps + + ;
}
ObjBitmaps [ Effects [ clip_num ] . changing_object_texture ] = Effects [ clip_num ] . vc . frames [ 0 ] ;
}
//if for an object, Effects_bm_ptrs set in object load
for ( clip_count = 1 ; clip_count < Effects [ clip_num ] . vc . num_frames ; clip_count + + ) {
2015-07-25 23:10:47 +00:00
set_lighting_flag ( GameBitmaps [ bm [ clip_count ] . index ] ) ;
2006-03-20 17:12:09 +00:00
Effects [ clip_num ] . vc . frames [ clip_count ] = bm [ clip_count ] ;
}
}
Effects [ clip_num ] . crit_clip = crit_clip ;
Effects [ clip_num ] . sound_num = sound_num ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
if ( ! dest_bm . empty ( ) )
# elif defined(DXX_BUILD_DESCENT_II)
if ( dest_bm )
# endif
{ //deal with bitmap for blown up clip
# if defined(DXX_BUILD_DESCENT_I)
char short_name [ 13 ] ;
int i ;
strcpy ( short_name , dest_bm . c_str ( ) ) ;
REMOVE_DOTS ( short_name ) ;
for ( i = 0 ; i < texture_count ; i + + )
if ( ! d_stricmp ( static_cast < const char * > ( TmapInfo [ i ] . filename ) , short_name ) )
break ;
if ( i = = texture_count ) {
Textures [ texture_count ] = bm_load_sub ( skip , dest_bm . c_str ( ) ) ;
TmapInfo [ texture_count ] . filename . copy_if ( short_name ) ;
texture_count + + ;
Assert ( texture_count < MAX_TEXTURES ) ;
NumTextures = texture_count ;
}
Effects [ clip_num ] . dest_bm_num = i ;
# elif defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
Effects [ clip_num ] . dest_bm_num = dest_bm_num ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
2014-10-04 15:04:44 +00:00
if ( dest_vclip = = vclip_none )
2006-03-20 17:12:09 +00:00
Error ( " Desctuction vclip missing on line %d " , linenum ) ;
if ( dest_size = = - 1 )
Error ( " Desctuction vclip missing on line %d " , linenum ) ;
Effects [ clip_num ] . dest_vclip = dest_vclip ;
Effects [ clip_num ] . dest_size = dest_size ;
Effects [ clip_num ] . dest_eclip = dest_eclip ;
}
else {
2018-03-31 21:53:01 +00:00
Effects [ clip_num ] . dest_bm_num = ~ 0u ;
2014-10-04 15:04:44 +00:00
Effects [ clip_num ] . dest_eclip = eclip_none ;
2006-03-20 17:12:09 +00:00
}
if ( crit_flag )
Effects [ clip_num ] . flags | = EF_CRITICAL ;
}
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
static void bm_read_gauges ( const char * const arg , int skip )
# elif defined(DXX_BUILD_DESCENT_II)
2013-10-27 22:00:14 +00:00
static void bm_read_gauges ( int skip )
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
{
bitmap_index bitmap ;
2012-11-18 18:20:13 +00:00
unsigned i , num_abm_frames ;
2006-03-20 17:12:09 +00:00
if ( ! abm_flag ) {
2008-02-11 12:12:57 +00:00
bitmap = bm_load_sub ( skip , arg ) ;
2006-03-20 17:12:09 +00:00
Assert ( clip_count < MAX_GAUGE_BMS ) ;
Gauges [ clip_count ] = bitmap ;
clip_count + + ;
} else {
2020-05-02 21:18:42 +00:00
std : : array < bitmap_index , MAX_BITMAPS_PER_BRUSH > bm ;
2006-03-20 17:12:09 +00:00
abm_flag = 0 ;
2008-02-11 12:12:57 +00:00
ab_load ( skip , arg , bm , & num_abm_frames ) ;
2006-03-20 17:12:09 +00:00
for ( i = clip_count ; i < clip_count + num_abm_frames ; i + + ) {
Assert ( i < MAX_GAUGE_BMS ) ;
Gauges [ i ] = bm [ i - clip_count ] ;
}
clip_count + = num_abm_frames ;
}
}
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
static void bm_read_wclip ( char * const arg , int skip )
# elif defined(DXX_BUILD_DESCENT_II)
2013-10-27 22:00:14 +00:00
static void bm_read_gauges_hires ( )
2006-03-20 17:12:09 +00:00
{
bitmap_index bitmap ;
2012-11-18 18:20:13 +00:00
unsigned i , num_abm_frames ;
2006-03-20 17:12:09 +00:00
if ( ! abm_flag ) {
2008-02-11 12:12:57 +00:00
bitmap = bm_load_sub ( 0 , arg ) ;
2006-03-20 17:12:09 +00:00
Assert ( clip_count < MAX_GAUGE_BMS ) ;
Gauges_hires [ clip_count ] = bitmap ;
clip_count + + ;
} else {
2020-05-02 21:18:42 +00:00
std : : array < bitmap_index , MAX_BITMAPS_PER_BRUSH > bm ;
2006-03-20 17:12:09 +00:00
abm_flag = 0 ;
2008-02-11 12:12:57 +00:00
ab_load ( 0 , arg , bm , & num_abm_frames ) ;
2006-03-20 17:12:09 +00:00
for ( i = clip_count ; i < clip_count + num_abm_frames ; i + + ) {
Assert ( i < MAX_GAUGE_BMS ) ;
Gauges_hires [ i ] = bm [ i - clip_count ] ;
}
clip_count + = num_abm_frames ;
}
}
2013-10-27 22:00:14 +00:00
static void bm_read_wclip ( int skip )
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
{
2018-12-30 00:43:59 +00:00
auto & TmapInfo = LevelUniqueTmapInfoState . TmapInfo ;
2020-04-04 19:30:22 +00:00
auto & WallAnims = GameSharedState . WallAnims ;
2006-03-20 17:12:09 +00:00
bitmap_index bitmap ;
Assert ( clip_num < MAX_WALL_ANIMS ) ;
2020-04-04 19:30:22 +00:00
auto & wa = WallAnims [ clip_num ] ;
wa . flags = wall_explodes_flag | wall_blastable_flag | wall_hidden_flag | tmap1_flag ;
2006-03-20 17:12:09 +00:00
if ( ! abm_flag ) {
2008-02-11 12:12:57 +00:00
bitmap = bm_load_sub ( skip , arg ) ;
2020-04-04 19:30:22 +00:00
if ( wa . num_frames ! = wclip_frames_none & & clip_count = = 0 )
2006-03-20 17:12:09 +00:00
Error ( " Wall Clip %d is already used! " , clip_num ) ;
2020-04-04 19:30:22 +00:00
wa . play_time = fl2f ( play_time ) ;
wa . num_frames = frames ;
2006-03-20 17:12:09 +00:00
//WallAnims[clip_num].frame_time = fl2f(play_time)/frames;
Assert ( clip_count < frames ) ;
2020-04-04 19:30:22 +00:00
wa . frames [ clip_count + + ] = texture_count ;
wa . open_sound = wall_open_sound ;
wa . close_sound = wall_close_sound ;
2006-03-20 17:12:09 +00:00
Textures [ texture_count ] = bitmap ;
2015-07-25 23:10:47 +00:00
set_lighting_flag ( GameBitmaps [ bitmap . index ] ) ;
2006-03-20 17:12:09 +00:00
set_texture_name ( arg ) ;
Assert ( texture_count < MAX_TEXTURES ) ;
texture_count + + ;
NumTextures = texture_count ;
if ( clip_num > = Num_wall_anims ) Num_wall_anims = clip_num + 1 ;
} else {
2020-05-02 21:18:42 +00:00
std : : array < bitmap_index , MAX_BITMAPS_PER_BRUSH > bm ;
2012-11-18 18:20:13 +00:00
unsigned nframes ;
2020-04-04 19:30:22 +00:00
if ( wa . num_frames ! = wclip_frames_none )
2006-03-20 17:12:09 +00:00
Error ( " AB_Wall clip %d is already used! " , clip_num ) ;
abm_flag = 0 ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
ab_load ( skip , arg , bm , & nframes ) ;
# elif defined(DXX_BUILD_DESCENT_II)
2008-02-11 12:12:57 +00:00
ab_load ( 0 , arg , bm , & nframes ) ;
2018-07-18 04:39:28 +00:00
# endif
2020-04-04 19:30:22 +00:00
wa . num_frames = nframes ;
wa . play_time = fl2f ( play_time ) ;
2006-03-20 17:12:09 +00:00
//WallAnims[clip_num].frame_time = fl2f(play_time)/nframes;
2020-04-04 19:30:22 +00:00
wa . open_sound = wall_open_sound ;
wa . close_sound = wall_close_sound ;
strcpy ( & wa . filename [ 0 ] , arg ) ;
REMOVE_DOTS ( & wa . filename [ 0 ] ) ;
2006-03-20 17:12:09 +00:00
if ( clip_num > = Num_wall_anims ) Num_wall_anims = clip_num + 1 ;
2015-07-25 23:10:47 +00:00
set_lighting_flag ( GameBitmaps [ bm [ clip_count ] . index ] ) ;
2006-03-20 17:12:09 +00:00
2020-04-04 19:30:22 +00:00
for ( clip_count = 0 ; clip_count < wa . num_frames ; clip_count + + ) {
2006-03-20 17:12:09 +00:00
Textures [ texture_count ] = bm [ clip_count ] ;
2015-07-25 23:10:47 +00:00
set_lighting_flag ( GameBitmaps [ bm [ clip_count ] . index ] ) ;
2020-04-04 19:30:22 +00:00
wa . frames [ clip_count ] = texture_count ;
2006-03-20 17:12:09 +00:00
REMOVE_DOTS ( arg ) ;
2014-07-26 22:45:01 +00:00
snprintf ( & TmapInfo [ texture_count ] . filename [ 0u ] , TmapInfo [ texture_count ] . filename . size ( ) , " %s#%d " , arg , clip_count ) ;
2006-03-20 17:12:09 +00:00
Assert ( texture_count < MAX_TEXTURES ) ;
texture_count + + ;
NumTextures = texture_count ;
}
}
}
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
2018-10-21 00:24:07 +00:00
static void bm_read_vclip ( d_vclip_array & Vclip , const char * const arg , int skip )
2018-07-18 04:39:28 +00:00
# elif defined(DXX_BUILD_DESCENT_II)
2018-10-21 00:24:07 +00:00
static void bm_read_vclip ( d_vclip_array & Vclip , int skip )
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
{
bitmap_index bi ;
2018-10-21 00:24:07 +00:00
assert ( clip_num < Vclip . size ( ) ) ;
2006-03-20 17:12:09 +00:00
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
if ( clip_num > = Num_vclips )
Num_vclips = clip_num + 1 ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
if ( ! abm_flag ) {
2018-07-18 04:39:28 +00:00
if ( Vclip [ clip_num ] . num_frames ! = ~ 0u & & clip_count = = 0 )
2006-03-20 17:12:09 +00:00
Error ( " Vclip %d is already used! " , clip_num ) ;
2008-02-11 12:12:57 +00:00
bi = bm_load_sub ( skip , arg ) ;
2006-03-20 17:12:09 +00:00
Vclip [ clip_num ] . play_time = fl2f ( play_time ) ;
Vclip [ clip_num ] . num_frames = frames ;
Vclip [ clip_num ] . frame_time = fl2f ( play_time ) / frames ;
Vclip [ clip_num ] . light_value = fl2f ( vlighting ) ;
Vclip [ clip_num ] . sound_num = sound_num ;
2015-07-25 23:10:47 +00:00
set_lighting_flag ( GameBitmaps [ bi . index ] ) ;
2006-03-20 17:12:09 +00:00
Assert ( clip_count < frames ) ;
Vclip [ clip_num ] . frames [ clip_count + + ] = bi ;
if ( rod_flag ) {
rod_flag = 0 ;
Vclip [ clip_num ] . flags | = VF_ROD ;
2018-07-18 04:39:28 +00:00
}
2006-03-20 17:12:09 +00:00
} else {
2020-05-02 21:18:42 +00:00
std : : array < bitmap_index , MAX_BITMAPS_PER_BRUSH > bm ;
2006-03-20 17:12:09 +00:00
abm_flag = 0 ;
2018-07-18 04:39:28 +00:00
if ( Vclip [ clip_num ] . num_frames ! = ~ 0u )
2006-03-20 17:12:09 +00:00
Error ( " AB_Vclip %d is already used! " , clip_num ) ;
2008-02-11 12:12:57 +00:00
ab_load ( skip , arg , bm , & Vclip [ clip_num ] . num_frames ) ;
2006-03-20 17:12:09 +00:00
if ( rod_flag ) {
//int i;
rod_flag = 0 ;
Vclip [ clip_num ] . flags | = VF_ROD ;
2018-07-18 04:39:28 +00:00
}
2006-03-20 17:12:09 +00:00
Vclip [ clip_num ] . play_time = fl2f ( play_time ) ;
Vclip [ clip_num ] . frame_time = fl2f ( play_time ) / Vclip [ clip_num ] . num_frames ;
Vclip [ clip_num ] . light_value = fl2f ( vlighting ) ;
Vclip [ clip_num ] . sound_num = sound_num ;
2015-07-25 23:10:47 +00:00
set_lighting_flag ( GameBitmaps [ bm [ clip_count ] . index ] ) ;
2006-03-20 17:12:09 +00:00
for ( clip_count = 0 ; clip_count < Vclip [ clip_num ] . num_frames ; clip_count + + ) {
2015-07-25 23:10:47 +00:00
set_lighting_flag ( GameBitmaps [ bm [ clip_count ] . index ] ) ;
2006-03-20 17:12:09 +00:00
Vclip [ clip_num ] . frames [ clip_count ] = bm [ clip_count ] ;
}
}
}
2018-12-13 02:31:38 +00:00
}
2022-07-09 13:39:29 +00:00
}
namespace dcx {
namespace {
2006-03-20 17:12:09 +00:00
// ------------------------------------------------------------------------------
2021-09-19 10:53:48 +00:00
static void get4fix ( enumerated_array < fix , NDL , Difficulty_level_type > & fixp )
2006-03-20 17:12:09 +00:00
{
char * curtext ;
2015-02-28 19:36:01 +00:00
range_for ( auto & i , fixp )
{
2015-01-29 04:27:35 +00:00
curtext = strtok ( NULL , space_tab ) ;
2015-02-28 19:36:01 +00:00
i = fl2f ( atof ( curtext ) ) ;
2006-03-20 17:12:09 +00:00
}
}
// ------------------------------------------------------------------------------
2021-09-19 10:53:48 +00:00
static void get4byte ( enumerated_array < int8_t , NDL , Difficulty_level_type > & bytep )
2006-03-20 17:12:09 +00:00
{
char * curtext ;
2015-02-28 19:36:01 +00:00
range_for ( auto & i , bytep )
{
2015-01-29 04:27:35 +00:00
curtext = strtok ( NULL , space_tab ) ;
2015-02-28 19:36:01 +00:00
i = atoi ( curtext ) ;
2006-03-20 17:12:09 +00:00
}
}
// ------------------------------------------------------------------------------
// Convert field of view from an angle in 0..360 to cosine.
2021-09-19 10:53:48 +00:00
static void adjust_field_of_view ( enumerated_array < fix , NDL , Difficulty_level_type > & fovp )
2006-03-20 17:12:09 +00:00
{
fixang tt ;
float ff ;
2015-02-28 19:36:01 +00:00
range_for ( auto & i , fovp )
{
ff = - f2fl ( i ) ;
2006-03-20 17:12:09 +00:00
if ( ff > 179 ) {
ff = 179 ;
}
ff = ff / 360 ;
tt = fl2f ( ff ) ;
2015-06-02 03:03:31 +00:00
i = fix_cos ( tt ) ;
2006-03-20 17:12:09 +00:00
}
}
2022-10-09 23:15:20 +00:00
static polygon_simpler_model_index build_polygon_simpler_model_index_from_polygon_model_index ( const unsigned i )
{
const auto ii = i + 1 ;
if ( ii > MAX_POLYGON_MODELS )
return polygon_simpler_model_index : : None ;
return static_cast < polygon_simpler_model_index > ( ii ) ;
}
2022-07-09 13:39:29 +00:00
}
}
2020-10-07 03:59:14 +00:00
2022-07-09 13:39:29 +00:00
namespace dsx {
2020-10-07 03:59:14 +00:00
namespace {
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
static void clear_to_end_of_line ( char * & arg )
{
arg = NULL ;
}
# elif defined(DXX_BUILD_DESCENT_II)
static void clear_to_end_of_line ( )
2006-03-20 17:12:09 +00:00
{
2015-01-29 04:27:35 +00:00
arg = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
while ( arg ! = NULL )
2015-01-29 04:27:35 +00:00
arg = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
}
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
static void bm_read_sound ( char * & arg , int skip , int pc_shareware )
# elif defined(DXX_BUILD_DESCENT_II)
2015-01-18 01:58:33 +00:00
void bm_read_sound ( int skip )
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
{
int alt_sound_num ;
2016-05-22 17:49:31 +00:00
const int read_sound_num = get_int ( ) ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
alt_sound_num = pc_shareware ? read_sound_num : get_int ( ) ;
# elif defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
alt_sound_num = get_int ( ) ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
2016-05-22 17:49:31 +00:00
if ( read_sound_num > = MAX_SOUNDS )
2006-03-20 17:12:09 +00:00
Error ( " Too many sound files. \n " ) ;
2016-05-22 17:49:31 +00:00
if ( read_sound_num > = num_sounds )
num_sounds = read_sound_num + 1 ;
2006-03-20 17:12:09 +00:00
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2016-05-22 17:49:31 +00:00
if ( Sounds [ read_sound_num ] ! = 255 )
Error ( " Sound num %d already used, bitmaps.tbl, line %d \n " , read_sound_num , linenum ) ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
2015-01-29 04:27:35 +00:00
arg = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
2016-05-22 17:49:31 +00:00
Sounds [ read_sound_num ] = ds_load ( skip , arg ) ;
2006-03-20 17:12:09 +00:00
if ( alt_sound_num = = 0 )
2016-05-22 17:49:31 +00:00
AltSounds [ read_sound_num ] = sound_num ;
2006-03-20 17:12:09 +00:00
else if ( alt_sound_num < 0 )
2016-05-22 17:49:31 +00:00
AltSounds [ read_sound_num ] = 255 ;
2006-03-20 17:12:09 +00:00
else
2016-05-22 17:49:31 +00:00
AltSounds [ read_sound_num ] = alt_sound_num ;
2006-03-20 17:12:09 +00:00
2016-05-22 17:49:31 +00:00
if ( Sounds [ read_sound_num ] = = 255 )
2006-03-20 17:12:09 +00:00
Error ( " Can't load soundfile <%s> " , arg ) ;
}
// ------------------------------------------------------------------------------
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
2022-07-09 13:39:29 +00:00
static void bm_read_robot_ai ( d_robot_info_array & Robot_info , char * & arg , const int skip )
2018-07-18 04:39:28 +00:00
# elif defined(DXX_BUILD_DESCENT_II)
2022-07-09 13:39:29 +00:00
void bm_read_robot_ai ( d_robot_info_array & Robot_info , const int skip )
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
{
char * robotnum_text ;
int robotnum ;
2015-01-29 04:27:35 +00:00
robotnum_text = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
robotnum = atoi ( robotnum_text ) ;
Assert ( robotnum < MAX_ROBOT_TYPES ) ;
2017-08-26 19:47:51 +00:00
auto & robptr = Robot_info [ robotnum ] ;
2006-03-20 17:12:09 +00:00
Assert ( robotnum = = Num_robot_ais ) ; //make sure valid number
2008-02-11 12:12:57 +00:00
if ( skip ) {
2006-03-20 17:12:09 +00:00
Num_robot_ais + + ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
clear_to_end_of_line ( arg ) ;
# elif defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
clear_to_end_of_line ( ) ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
return ;
}
Num_robot_ais + + ;
2017-08-26 19:47:51 +00:00
get4fix ( robptr . field_of_view ) ;
get4fix ( robptr . firing_wait ) ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2017-08-26 19:47:51 +00:00
get4fix ( robptr . firing_wait2 ) ;
2018-07-18 04:39:28 +00:00
# endif
2017-08-26 19:47:51 +00:00
get4byte ( robptr . rapidfire_count ) ;
get4fix ( robptr . turn_time ) ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
2021-09-19 10:53:48 +00:00
enumerated_array < fix , NDL , Difficulty_level_type > fire_power , // damage done by a hit from this robot
2018-07-18 04:39:28 +00:00
shield ; // shield strength of this robot
get4fix ( fire_power ) ;
get4fix ( shield ) ;
# elif defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
// get4fix(robptr->fire_power);
// get4fix(robptr->shield);
2018-07-18 04:39:28 +00:00
# endif
2017-08-26 19:47:51 +00:00
get4fix ( robptr . max_speed ) ;
get4fix ( robptr . circle_distance ) ;
get4byte ( robptr . evade_speed ) ;
2006-03-20 17:12:09 +00:00
2017-08-26 19:47:51 +00:00
robptr . always_0xabcd = 0xabcd ;
adjust_field_of_view ( robptr . field_of_view ) ;
2006-03-20 17:12:09 +00:00
}
// ----------------------------------------------------------------------------------------------
//this will load a bitmap for a polygon models. it puts the bitmap into
//the array ObjBitmaps[], and also deals with animating bitmaps
//returns a pointer to the bitmap
2014-08-23 17:06:44 +00:00
static grs_bitmap * load_polymodel_bitmap ( int skip , const char * name )
2006-03-20 17:12:09 +00:00
{
2019-03-03 00:31:09 +00:00
auto & Effects = LevelUniqueEffectsClipState . Effects ;
2016-07-10 04:11:35 +00:00
assert ( N_ObjBitmaps < ObjBitmaps . size ( ) ) ;
2006-03-20 17:12:09 +00:00
// Assert( N_ObjBitmaps == N_ObjBitmapPtrs );
if ( name [ 0 ] = = ' % ' ) { //an animating bitmap!
2018-03-31 21:53:01 +00:00
const unsigned eclip_num = atoi ( name + 1 ) ;
2006-03-20 17:12:09 +00:00
2020-10-07 03:59:14 +00:00
auto & changing_object_texture = Effects [ eclip_num ] . changing_object_texture ;
// On first reference, changing_object_texture will be None.
// Assign it a value.
if ( changing_object_texture = = object_bitmap_index : : None )
changing_object_texture = static_cast < object_bitmap_index > ( N_ObjBitmaps + + ) ;
ObjBitmapPtrs [ N_ObjBitmapPtrs + + ] = changing_object_texture ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2016-07-10 04:11:35 +00:00
assert ( N_ObjBitmaps < ObjBitmaps . size ( ) ) ;
assert ( N_ObjBitmapPtrs < ObjBitmapPtrs . size ( ) ) ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
return NULL ;
}
else {
2020-10-07 03:59:14 +00:00
const auto loaded_value = bm_load_sub ( skip , name ) ;
const auto oi = static_cast < object_bitmap_index > ( N_ObjBitmaps ) ;
auto & ob = ObjBitmaps [ oi ] ;
ob = loaded_value ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2020-10-07 03:59:14 +00:00
if ( GameBitmaps [ ob . index ] . bm_w ! = 64 | | GameBitmaps [ ob . index ] . bm_h ! = 64 )
2006-03-20 17:12:09 +00:00
Error ( " Bitmap <%s> is not 64x64 " , name ) ;
2018-07-18 04:39:28 +00:00
# endif
2020-10-07 03:59:14 +00:00
ObjBitmapPtrs [ N_ObjBitmapPtrs + + ] = oi ;
2006-03-20 17:12:09 +00:00
N_ObjBitmaps + + ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2016-07-10 04:11:35 +00:00
assert ( N_ObjBitmaps < ObjBitmaps . size ( ) ) ;
assert ( N_ObjBitmapPtrs < ObjBitmapPtrs . size ( ) ) ;
2018-07-18 04:39:28 +00:00
# endif
2020-10-07 03:59:14 +00:00
return & GameBitmaps [ ob . index ] ;
2006-03-20 17:12:09 +00:00
}
}
# define MAX_MODEL_VARIANTS 4
// ------------------------------------------------------------------------------
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
2022-07-09 13:39:29 +00:00
static void bm_read_robot ( d_level_shared_robot_info_state & LevelSharedRobotInfoState , char * & arg , int skip )
2018-07-18 04:39:28 +00:00
# elif defined(DXX_BUILD_DESCENT_II)
2022-07-09 13:39:29 +00:00
void bm_read_robot ( d_level_shared_robot_info_state & LevelSharedRobotInfoState , int skip )
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
{
char * model_name [ MAX_MODEL_VARIANTS ] ;
int n_models , i ;
int first_bitmap_num [ MAX_MODEL_VARIANTS ] ;
char * equal_ptr ;
2017-10-14 17:10:30 +00:00
int exp1_vclip_num = vclip_none ;
int exp1_sound_num = sound_none ;
int exp2_vclip_num = vclip_none ;
int exp2_sound_num = sound_none ;
2006-03-20 17:12:09 +00:00
fix lighting = F1_0 / 2 ; // Default
fix strength = F1_0 * 10 ; // Default strength
fix mass = f1_0 * 4 ;
fix drag = f1_0 / 2 ;
2018-07-18 04:39:28 +00:00
weapon_id_type weapon_type = weapon_id_type : : LASER_ID_L1 ;
2015-04-26 20:15:51 +00:00
int contains_count = 0 , contains_id = 0 , contains_prob = 0 , contains_type = 0 ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
weapon_id_type weapon_type2 = weapon_id_type : : unspecified ;
2015-04-26 20:15:51 +00:00
auto behavior = ai_behavior : : AIB_NORMAL ;
2006-03-20 17:12:09 +00:00
int companion = 0 , smart_blobs = 0 , energy_blobs = 0 , badass = 0 , energy_drain = 0 , kamikaze = 0 , thief = 0 , pursuit = 0 , lightcast = 0 , death_roll = 0 ;
fix glow = 0 , aim = F1_0 ;
int deathroll_sound = SOUND_BOSS_SHARE_DIE ; //default
2018-07-18 04:39:28 +00:00
int taunt_sound = ROBOT_SEE_SOUND_DEFAULT ;
ubyte flags = 0 ;
# endif
2006-03-20 17:12:09 +00:00
int score_value = 1000 ;
int cloak_type = 0 ; // Default = this robot does not cloak
int attack_type = 0 ; // Default = this robot attacks by firing (1=lunge)
int boss_flag = 0 ; // Default = robot is not a boss.
int see_sound = ROBOT_SEE_SOUND_DEFAULT ;
int attack_sound = ROBOT_ATTACK_SOUND_DEFAULT ;
int claw_sound = ROBOT_CLAW_SOUND_DEFAULT ;
2018-12-30 00:43:59 +00:00
assert ( LevelSharedRobotInfoState . N_robot_types < MAX_ROBOT_TYPES ) ;
2006-03-20 17:12:09 +00:00
2018-12-30 00:43:59 +00:00
auto & Robot_info = LevelSharedRobotInfoState . Robot_info ;
2008-02-11 12:12:57 +00:00
if ( skip ) {
2018-12-30 00:43:59 +00:00
auto & ri = Robot_info [ LevelSharedRobotInfoState . N_robot_types + + ] ;
ri . model_num = - 1 ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
Num_total_object_types + + ;
clear_to_end_of_line ( arg ) ;
# elif defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
clear_to_end_of_line ( ) ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
return ;
}
2015-01-29 04:27:35 +00:00
model_name [ 0 ] = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
first_bitmap_num [ 0 ] = N_ObjBitmapPtrs ;
n_models = 1 ;
// Process bitmaps
2020-10-07 03:59:14 +00:00
current_bm_type = bm_type : : robot ;
2015-01-29 04:27:35 +00:00
arg = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
while ( arg ! = NULL ) {
equal_ptr = strchr ( arg , ' = ' ) ;
if ( equal_ptr ) {
* equal_ptr = ' \0 ' ;
equal_ptr + + ;
// if we have john=cool, arg is 'john' and equal_ptr is 'cool'
2012-05-18 23:36:43 +00:00
if ( ! d_stricmp ( arg , " exp1_vclip " ) ) {
2006-03-20 17:12:09 +00:00
exp1_vclip_num = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " exp2_vclip " ) ) {
2006-03-20 17:12:09 +00:00
exp2_vclip_num = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " exp1_sound " ) ) {
2006-03-20 17:12:09 +00:00
exp1_sound_num = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " exp2_sound " ) ) {
2006-03-20 17:12:09 +00:00
exp2_sound_num = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " lighting " ) ) {
2006-03-20 17:12:09 +00:00
lighting = fl2f ( atof ( equal_ptr ) ) ;
if ( ( lighting < 0 ) | | ( lighting > F1_0 ) ) {
Error ( " In bitmaps.tbl, lighting value of %.2f is out of range 0..1. \n " , f2fl ( lighting ) ) ;
}
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " weapon_type " ) ) {
2015-12-03 03:26:49 +00:00
weapon_type = static_cast < weapon_id_type > ( atoi ( equal_ptr ) ) ;
2018-07-18 04:39:28 +00:00
}
# if defined(DXX_BUILD_DESCENT_II)
else if ( ! d_stricmp ( arg , " weapon_type2 " ) )
{
2015-12-03 03:26:49 +00:00
weapon_type2 = static_cast < weapon_id_type > ( atoi ( equal_ptr ) ) ;
2018-07-18 04:39:28 +00:00
}
# endif
else if ( ! d_stricmp ( arg , " strength " ) ) {
2006-03-20 17:12:09 +00:00
strength = i2f ( atoi ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " mass " ) ) {
2006-03-20 17:12:09 +00:00
mass = fl2f ( atof ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " drag " ) ) {
2006-03-20 17:12:09 +00:00
drag = fl2f ( atof ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " contains_id " ) ) {
2006-03-20 17:12:09 +00:00
contains_id = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " contains_type " ) ) {
2006-03-20 17:12:09 +00:00
contains_type = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " contains_count " ) ) {
2006-03-20 17:12:09 +00:00
contains_count = atoi ( equal_ptr ) ;
2018-07-18 04:39:28 +00:00
}
# if defined(DXX_BUILD_DESCENT_II)
else if ( ! d_stricmp ( arg , " companion " ) ) {
2006-03-20 17:12:09 +00:00
companion = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " badass " ) ) {
2006-03-20 17:12:09 +00:00
badass = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " lightcast " ) ) {
2006-03-20 17:12:09 +00:00
lightcast = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " glow " ) ) {
2006-03-20 17:12:09 +00:00
glow = fl2f ( atof ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " death_roll " ) ) {
2006-03-20 17:12:09 +00:00
death_roll = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " deathroll_sound " ) ) {
2006-03-20 17:12:09 +00:00
deathroll_sound = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " thief " ) ) {
2006-03-20 17:12:09 +00:00
thief = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " kamikaze " ) ) {
2006-03-20 17:12:09 +00:00
kamikaze = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " pursuit " ) ) {
2006-03-20 17:12:09 +00:00
pursuit = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " smart_blobs " ) ) {
2006-03-20 17:12:09 +00:00
smart_blobs = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " energy_blobs " ) ) {
2006-03-20 17:12:09 +00:00
energy_blobs = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " energy_drain " ) ) {
2006-03-20 17:12:09 +00:00
energy_drain = atoi ( equal_ptr ) ;
2018-07-18 04:39:28 +00:00
}
# endif
else if ( ! d_stricmp ( arg , " contains_prob " ) ) {
2006-03-20 17:12:09 +00:00
contains_prob = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " cloak_type " ) ) {
2006-03-20 17:12:09 +00:00
cloak_type = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " attack_type " ) ) {
2006-03-20 17:12:09 +00:00
attack_type = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " boss " ) ) {
2006-03-20 17:12:09 +00:00
boss_flag = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " score_value " ) ) {
2006-03-20 17:12:09 +00:00
score_value = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " see_sound " ) ) {
2006-03-20 17:12:09 +00:00
see_sound = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " attack_sound " ) ) {
2006-03-20 17:12:09 +00:00
attack_sound = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " claw_sound " ) ) {
2006-03-20 17:12:09 +00:00
claw_sound = atoi ( equal_ptr ) ;
2018-07-18 04:39:28 +00:00
}
# if defined(DXX_BUILD_DESCENT_II)
else if ( ! d_stricmp ( arg , " taunt_sound " ) ) {
2006-03-20 17:12:09 +00:00
taunt_sound = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " aim " ) ) {
2006-03-20 17:12:09 +00:00
aim = fl2f ( atof ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " big_radius " ) ) {
2006-03-20 17:12:09 +00:00
if ( atoi ( equal_ptr ) )
flags | = RIF_BIG_RADIUS ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " behavior " ) ) {
if ( ! d_stricmp ( equal_ptr , " STILL " ) )
2015-04-02 02:36:57 +00:00
behavior = ai_behavior : : AIB_STILL ;
2012-05-18 23:36:43 +00:00
else if ( ! d_stricmp ( equal_ptr , " NORMAL " ) )
2015-04-02 02:36:57 +00:00
behavior = ai_behavior : : AIB_NORMAL ;
2012-05-18 23:36:43 +00:00
else if ( ! d_stricmp ( equal_ptr , " BEHIND " ) )
2015-04-02 02:36:57 +00:00
behavior = ai_behavior : : AIB_BEHIND ;
2012-05-18 23:36:43 +00:00
else if ( ! d_stricmp ( equal_ptr , " RUN_FROM " ) )
2015-04-02 02:36:57 +00:00
behavior = ai_behavior : : AIB_RUN_FROM ;
2012-05-18 23:36:43 +00:00
else if ( ! d_stricmp ( equal_ptr , " SNIPE " ) )
2015-04-02 02:36:57 +00:00
behavior = ai_behavior : : AIB_SNIPE ;
2012-05-18 23:36:43 +00:00
else if ( ! d_stricmp ( equal_ptr , " STATION " ) )
2015-04-02 02:36:57 +00:00
behavior = ai_behavior : : AIB_STATION ;
2012-05-18 23:36:43 +00:00
else if ( ! d_stricmp ( equal_ptr , " FOLLOW " ) )
2015-04-02 02:36:57 +00:00
behavior = ai_behavior : : AIB_FOLLOW ;
2006-03-20 17:12:09 +00:00
else
Int3 ( ) ; // Error. Illegal behavior type for current robot.
2018-07-18 04:39:28 +00:00
}
# endif
else if ( ! d_stricmp ( arg , " name " ) ) {
2016-09-11 18:49:16 +00:00
# if DXX_USE_EDITOR
2018-12-30 00:43:59 +00:00
auto & name = Robot_names [ LevelSharedRobotInfoState . N_robot_types ] ;
2016-07-09 17:58:34 +00:00
const auto len = strlen ( equal_ptr ) ;
assert ( len < name . size ( ) ) ; // Oops, name too long.
memcpy ( name . data ( ) , & equal_ptr [ 1 ] , len - 2 ) ;
name [ len - 2 ] = 0 ;
# endif
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " simple_model " ) ) {
2006-03-20 17:12:09 +00:00
model_name [ n_models ] = equal_ptr ;
first_bitmap_num [ n_models ] = N_ObjBitmapPtrs ;
n_models + + ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
Assert ( n_models < MAX_MODEL_VARIANTS ) ;
2018-07-18 04:39:28 +00:00
# endif
}
# if defined(DXX_BUILD_DESCENT_II)
else
{
2006-03-20 17:12:09 +00:00
Int3 ( ) ;
2018-07-18 04:39:28 +00:00
}
# endif
2006-03-20 17:12:09 +00:00
} else { // Must be a texture specification...
2008-02-11 12:12:57 +00:00
load_polymodel_bitmap ( skip , arg ) ;
2006-03-20 17:12:09 +00:00
}
2015-01-29 04:27:35 +00:00
arg = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
}
2018-12-30 00:43:59 +00:00
auto & current_robot_info = Robot_info [ LevelSharedRobotInfoState . N_robot_types ] ;
2006-03-20 17:12:09 +00:00
//clear out anim info
2018-12-30 00:43:59 +00:00
range_for ( auto & g , current_robot_info . anim_states )
2016-12-11 01:56:44 +00:00
range_for ( auto & s , g )
2018-07-18 04:39:28 +00:00
s . n_joints = 0 ;
2006-03-20 17:12:09 +00:00
first_bitmap_num [ n_models ] = N_ObjBitmapPtrs ;
2018-12-30 00:43:59 +00:00
auto & Polygon_models = LevelSharedPolygonModelState . Polygon_models ;
2006-03-20 17:12:09 +00:00
for ( i = 0 ; i < n_models ; i + + ) {
int n_textures ;
n_textures = first_bitmap_num [ i + 1 ] - first_bitmap_num [ i ] ;
2022-10-09 23:15:20 +00:00
const auto model_num = load_polygon_model ( model_name [ i ] , n_textures , first_bitmap_num [ i ] , ( i = = 0 ) ? & current_robot_info : nullptr ) ;
2006-03-20 17:12:09 +00:00
if ( i = = 0 )
2018-12-30 00:43:59 +00:00
current_robot_info . model_num = model_num ;
2006-03-20 17:12:09 +00:00
else
2022-10-09 23:15:20 +00:00
Polygon_models [ 0 ] . simpler_model = build_polygon_simpler_model_index_from_polygon_model_index ( model_num ) ;
2006-03-20 17:12:09 +00:00
}
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
ObjType [ Num_total_object_types ] = OL_ROBOT ;
2018-12-30 00:43:59 +00:00
ObjId [ Num_total_object_types ] = LevelSharedRobotInfoState . N_robot_types ;
2018-07-18 04:39:28 +00:00
# elif defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
if ( ( glow > i2f ( 15 ) ) | | ( glow < 0 ) | | ( glow ! = 0 & & glow < 0x1000 ) ) {
Int3 ( ) ;
}
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
2018-12-30 00:43:59 +00:00
current_robot_info . exp1_vclip_num = exp1_vclip_num ;
current_robot_info . exp2_vclip_num = exp2_vclip_num ;
current_robot_info . exp1_sound_num = exp1_sound_num ;
current_robot_info . exp2_sound_num = exp2_sound_num ;
current_robot_info . lighting = lighting ;
current_robot_info . weapon_type = weapon_type ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2018-12-30 00:43:59 +00:00
current_robot_info . weapon_type2 = weapon_type2 ;
# endif
current_robot_info . strength = strength ;
current_robot_info . mass = mass ;
current_robot_info . drag = drag ;
current_robot_info . cloak_type = cloak_type ;
current_robot_info . attack_type = attack_type ;
current_robot_info . boss_flag = boss_flag ;
current_robot_info . contains_id = contains_id ;
current_robot_info . contains_count = contains_count ;
current_robot_info . contains_prob = contains_prob ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2018-12-30 00:43:59 +00:00
current_robot_info . companion = companion ;
current_robot_info . badass = badass ;
current_robot_info . lightcast = lightcast ;
current_robot_info . glow = ( glow > > 12 ) ; //convert to 4:4
current_robot_info . death_roll = death_roll ;
current_robot_info . deathroll_sound = deathroll_sound ;
current_robot_info . thief = thief ;
current_robot_info . flags = flags ;
current_robot_info . kamikaze = kamikaze ;
current_robot_info . pursuit = pursuit ;
current_robot_info . smart_blobs = smart_blobs ;
current_robot_info . energy_blobs = energy_blobs ;
current_robot_info . energy_drain = energy_drain ;
# endif
current_robot_info . score_value = score_value ;
current_robot_info . see_sound = see_sound ;
current_robot_info . attack_sound = attack_sound ;
current_robot_info . claw_sound = claw_sound ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2018-12-30 00:43:59 +00:00
current_robot_info . taunt_sound = taunt_sound ;
current_robot_info . behavior = behavior ; // Default behavior for this robot, if coming out of matcen.
current_robot_info . aim = min ( f2i ( aim * 255 ) , 255 ) ; // how well this robot type can aim. 255=perfect
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
if ( contains_type )
2018-12-30 00:43:59 +00:00
current_robot_info . contains_type = OBJ_ROBOT ;
2006-03-20 17:12:09 +00:00
else
2018-12-30 00:43:59 +00:00
current_robot_info . contains_type = OBJ_POWERUP ;
2006-03-20 17:12:09 +00:00
2018-12-30 00:43:59 +00:00
+ + LevelSharedRobotInfoState . N_robot_types ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
Num_total_object_types + + ;
# elif defined(DXX_BUILD_DESCENT_II)
2020-10-07 03:59:14 +00:00
current_bm_type = bm_type : : none ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
}
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
//read a polygon object of some sort
void bm_read_object ( char * & arg , int skip )
# elif defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
//read a reactor model
2008-02-11 12:12:57 +00:00
void bm_read_reactor ( void )
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
{
char * model_name , * model_name_dead = NULL ;
int first_bitmap_num , first_bitmap_num_dead = 0 , n_normal_bitmaps ;
char * equal_ptr ;
short model_num ;
fix lighting = F1_0 / 2 ; // Default
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
2019-11-18 00:22:34 +00:00
int type = - 1 ;
2018-07-18 04:39:28 +00:00
fix strength = 0 ;
# elif defined(DXX_BUILD_DESCENT_II)
2015-08-26 03:15:10 +00:00
assert ( Num_reactors < Reactors . size ( ) ) ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
2015-01-29 04:27:35 +00:00
model_name = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
// Process bitmaps
2020-10-07 03:59:14 +00:00
current_bm_type = bm_type : : none ;
2015-01-29 04:27:35 +00:00
arg = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
first_bitmap_num = N_ObjBitmapPtrs ;
while ( arg ! = NULL ) {
equal_ptr = strchr ( arg , ' = ' ) ;
if ( equal_ptr ) {
* equal_ptr = ' \0 ' ;
equal_ptr + + ;
// if we have john=cool, arg is 'john' and equal_ptr is 'cool'
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
if ( ! d_stricmp ( arg , " type " ) ) {
if ( ! d_stricmp ( equal_ptr , " controlcen " ) )
type = OL_CONTROL_CENTER ;
else if ( ! d_stricmp ( equal_ptr , " clutter " ) )
type = OL_CLUTTER ;
else if ( ! d_stricmp ( equal_ptr , " exit " ) )
type = OL_EXIT ;
}
else
# endif
2012-05-18 23:36:43 +00:00
if ( ! d_stricmp ( arg , " dead_pof " ) ) {
2006-03-20 17:12:09 +00:00
model_name_dead = equal_ptr ;
first_bitmap_num_dead = N_ObjBitmapPtrs ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " lighting " ) ) {
2006-03-20 17:12:09 +00:00
lighting = fl2f ( atof ( equal_ptr ) ) ;
if ( ( lighting < 0 ) | | ( lighting > F1_0 ) ) {
Error ( " In bitmaps.tbl, lighting value of %.2f is out of range 0..1. \n " , f2fl ( lighting ) ) ;
}
2018-07-18 04:39:28 +00:00
}
# if defined(DXX_BUILD_DESCENT_I)
else if ( ! d_stricmp ( arg , " strength " ) ) {
strength = fl2f ( atof ( equal_ptr ) ) ;
}
# elif defined(DXX_BUILD_DESCENT_II)
else {
2006-03-20 17:12:09 +00:00
Int3 ( ) ;
2018-07-18 04:39:28 +00:00
}
# endif
2006-03-20 17:12:09 +00:00
} else { // Must be a texture specification...
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
load_polymodel_bitmap ( skip , arg ) ;
# elif defined(DXX_BUILD_DESCENT_II)
2008-02-11 12:12:57 +00:00
load_polymodel_bitmap ( 0 , arg ) ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
}
2015-01-29 04:27:35 +00:00
arg = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
}
if ( model_name_dead )
n_normal_bitmaps = first_bitmap_num_dead - first_bitmap_num ;
else
n_normal_bitmaps = N_ObjBitmapPtrs - first_bitmap_num ;
model_num = load_polygon_model ( model_name , n_normal_bitmaps , first_bitmap_num , NULL ) ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
if ( type = = OL_CONTROL_CENTER )
read_model_guns ( model_name , Reactors [ 0 ] ) ;
# endif
2006-03-20 17:12:09 +00:00
if ( model_name_dead )
Dead_modelnums [ model_num ] = load_polygon_model ( model_name_dead , N_ObjBitmapPtrs - first_bitmap_num_dead , first_bitmap_num_dead , NULL ) ;
else
Dead_modelnums [ model_num ] = - 1 ;
2019-11-18 00:22:34 +00:00
# if defined(DXX_BUILD_DESCENT_I)
2006-03-20 17:12:09 +00:00
if ( type = = - 1 )
Error ( " No object type specfied for object in BITMAPS.TBL on line %d \n " , linenum ) ;
2018-07-18 04:39:28 +00:00
ObjType [ Num_total_object_types ] = type ;
ObjId [ Num_total_object_types ] = model_num ;
ObjStrength [ Num_total_object_types ] = strength ;
Num_total_object_types + + ;
if ( type = = OL_EXIT ) {
exit_modelnum = model_num ;
destroyed_exit_modelnum = Dead_modelnums [ model_num ] ;
}
# elif defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
Reactors [ Num_reactors ] . model_num = model_num ;
2015-07-25 23:10:48 +00:00
read_model_guns ( model_name , Reactors [ Num_reactors ] ) ;
2006-03-20 17:12:09 +00:00
Num_reactors + + ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
}
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
//read the marker object
void bm_read_marker ( )
{
char * model_name ;
int first_bitmap_num , n_normal_bitmaps ;
char * equal_ptr ;
2015-01-29 04:27:35 +00:00
model_name = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
// Process bitmaps
2020-10-07 03:59:14 +00:00
current_bm_type = bm_type : : none ;
2015-01-29 04:27:35 +00:00
arg = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
first_bitmap_num = N_ObjBitmapPtrs ;
while ( arg ! = NULL ) {
equal_ptr = strchr ( arg , ' = ' ) ;
if ( equal_ptr ) {
* equal_ptr = ' \0 ' ;
equal_ptr + + ;
// if we have john=cool, arg is 'john' and equal_ptr is 'cool'
Int3 ( ) ;
} else { // Must be a texture specification...
2008-02-11 12:12:57 +00:00
load_polymodel_bitmap ( 0 , arg ) ;
2006-03-20 17:12:09 +00:00
}
2015-01-29 04:27:35 +00:00
arg = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
}
n_normal_bitmaps = N_ObjBitmapPtrs - first_bitmap_num ;
2020-08-24 01:31:28 +00:00
LevelSharedPolygonModelState . Marker_model_num = load_polygon_model ( model_name , n_normal_bitmaps , first_bitmap_num , NULL ) ;
2006-03-20 17:12:09 +00:00
}
//read the exit model
void bm_read_exitmodel ( )
{
char * model_name , * model_name_dead = NULL ;
2008-04-06 20:23:28 +00:00
int first_bitmap_num = 0 , first_bitmap_num_dead = 0 , n_normal_bitmaps ;
2006-03-20 17:12:09 +00:00
char * equal_ptr ;
short model_num ;
2015-01-29 04:27:35 +00:00
model_name = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
// Process bitmaps
2020-10-07 03:59:14 +00:00
current_bm_type = bm_type : : none ;
2015-01-29 04:27:35 +00:00
arg = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
first_bitmap_num = N_ObjBitmapPtrs ;
while ( arg ! = NULL ) {
equal_ptr = strchr ( arg , ' = ' ) ;
if ( equal_ptr ) {
* equal_ptr = ' \0 ' ;
equal_ptr + + ;
// if we have john=cool, arg is 'john' and equal_ptr is 'cool'
2012-05-18 23:36:43 +00:00
if ( ! d_stricmp ( arg , " dead_pof " ) ) {
2006-03-20 17:12:09 +00:00
model_name_dead = equal_ptr ;
first_bitmap_num_dead = N_ObjBitmapPtrs ;
} else {
Int3 ( ) ;
2018-07-18 04:39:28 +00:00
}
2006-03-20 17:12:09 +00:00
} else { // Must be a texture specification...
2008-02-11 12:12:57 +00:00
load_polymodel_bitmap ( 0 , arg ) ;
2006-03-20 17:12:09 +00:00
}
2015-01-29 04:27:35 +00:00
arg = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
}
if ( model_name_dead )
n_normal_bitmaps = first_bitmap_num_dead - first_bitmap_num ;
else
n_normal_bitmaps = N_ObjBitmapPtrs - first_bitmap_num ;
model_num = load_polygon_model ( model_name , n_normal_bitmaps , first_bitmap_num , NULL ) ;
if ( model_name_dead )
Dead_modelnums [ model_num ] = load_polygon_model ( model_name_dead , N_ObjBitmapPtrs - first_bitmap_num_dead , first_bitmap_num_dead , NULL ) ;
else
Dead_modelnums [ model_num ] = - 1 ;
exit_modelnum = model_num ;
destroyed_exit_modelnum = Dead_modelnums [ model_num ] ;
}
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
void bm_read_player_ship ( char * & arg , int skip )
# elif defined(DXX_BUILD_DESCENT_II)
2008-02-11 12:12:57 +00:00
void bm_read_player_ship ( void )
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
{
char * model_name_dying = NULL ;
char * model_name [ MAX_MODEL_VARIANTS ] ;
int n_models = 0 , i ;
int first_bitmap_num [ MAX_MODEL_VARIANTS ] ;
char * equal_ptr ;
robot_info ri ;
int last_multi_bitmap_num = - 1 ;
// Process bitmaps
2020-10-07 03:59:14 +00:00
current_bm_type = bm_type : : none ;
2006-03-20 17:12:09 +00:00
2015-01-29 04:27:35 +00:00
arg = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
Player_ship - > mass = Player_ship - > drag = 0 ; //stupid defaults
2014-10-04 15:04:44 +00:00
Player_ship - > expl_vclip_num = vclip_none ;
2006-03-20 17:12:09 +00:00
while ( arg ! = NULL ) {
equal_ptr = strchr ( arg , ' = ' ) ;
if ( equal_ptr ) {
* equal_ptr = ' \0 ' ;
equal_ptr + + ;
// if we have john=cool, arg is 'john' and equal_ptr is 'cool'
2012-05-18 23:36:43 +00:00
if ( ! d_stricmp ( arg , " model " ) ) {
2006-03-20 17:12:09 +00:00
Assert ( n_models = = 0 ) ;
model_name [ 0 ] = equal_ptr ;
first_bitmap_num [ 0 ] = N_ObjBitmapPtrs ;
n_models = 1 ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " simple_model " ) ) {
2006-03-20 17:12:09 +00:00
model_name [ n_models ] = equal_ptr ;
first_bitmap_num [ n_models ] = N_ObjBitmapPtrs ;
n_models + + ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
Assert ( n_models < MAX_MODEL_VARIANTS ) ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
if ( First_multi_bitmap_num ! = - 1 & & last_multi_bitmap_num = = - 1 )
last_multi_bitmap_num = N_ObjBitmapPtrs ;
}
2012-05-18 23:36:43 +00:00
else if ( ! d_stricmp ( arg , " mass " ) )
2006-03-20 17:12:09 +00:00
Player_ship - > mass = fl2f ( atof ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
else if ( ! d_stricmp ( arg , " drag " ) )
2006-03-20 17:12:09 +00:00
Player_ship - > drag = fl2f ( atof ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
// else if (!d_stricmp( arg, "low_thrust" ))
2006-03-20 17:12:09 +00:00
// Player_ship->low_thrust = fl2f(atof(equal_ptr));
2012-05-18 23:36:43 +00:00
else if ( ! d_stricmp ( arg , " max_thrust " ) )
2006-03-20 17:12:09 +00:00
Player_ship - > max_thrust = fl2f ( atof ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
else if ( ! d_stricmp ( arg , " reverse_thrust " ) )
2006-03-20 17:12:09 +00:00
Player_ship - > reverse_thrust = fl2f ( atof ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
else if ( ! d_stricmp ( arg , " brakes " ) )
2006-03-20 17:12:09 +00:00
Player_ship - > brakes = fl2f ( atof ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
else if ( ! d_stricmp ( arg , " wiggle " ) )
2006-03-20 17:12:09 +00:00
Player_ship - > wiggle = fl2f ( atof ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
else if ( ! d_stricmp ( arg , " max_rotthrust " ) )
2006-03-20 17:12:09 +00:00
Player_ship - > max_rotthrust = fl2f ( atof ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
else if ( ! d_stricmp ( arg , " dying_pof " ) )
2006-03-20 17:12:09 +00:00
model_name_dying = equal_ptr ;
2012-05-18 23:36:43 +00:00
else if ( ! d_stricmp ( arg , " expl_vclip_num " ) )
2006-03-20 17:12:09 +00:00
Player_ship - > expl_vclip_num = atoi ( equal_ptr ) ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
else {
Int3 ( ) ;
2018-07-18 04:39:28 +00:00
}
# endif
2006-03-20 17:12:09 +00:00
}
2012-05-18 23:36:43 +00:00
else if ( ! d_stricmp ( arg , " multi_textures " ) ) {
2006-03-20 17:12:09 +00:00
First_multi_bitmap_num = N_ObjBitmapPtrs ;
first_bitmap_num [ n_models ] = N_ObjBitmapPtrs ;
}
else // Must be a texture specification...
2018-07-18 04:39:28 +00:00
{
# if defined(DXX_BUILD_DESCENT_I)
load_polymodel_bitmap ( skip , arg ) ;
# elif defined(DXX_BUILD_DESCENT_II)
2008-02-11 12:12:57 +00:00
load_polymodel_bitmap ( 0 , arg ) ;
2018-07-18 04:39:28 +00:00
# endif
}
2006-03-20 17:12:09 +00:00
2015-01-29 04:27:35 +00:00
arg = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
}
if ( First_multi_bitmap_num ! = - 1 & & last_multi_bitmap_num = = - 1 )
last_multi_bitmap_num = N_ObjBitmapPtrs ;
if ( First_multi_bitmap_num = = - 1 )
first_bitmap_num [ n_models ] = N_ObjBitmapPtrs ;
2012-04-15 13:32:48 +00:00
Assert ( last_multi_bitmap_num - First_multi_bitmap_num = = ( MAX_PLAYERS - 1 ) * 2 ) ;
2006-03-20 17:12:09 +00:00
2018-12-30 00:43:59 +00:00
auto & Polygon_models = LevelSharedPolygonModelState . Polygon_models ;
2006-03-20 17:12:09 +00:00
for ( i = 0 ; i < n_models ; i + + ) {
int n_textures ;
n_textures = first_bitmap_num [ i + 1 ] - first_bitmap_num [ i ] ;
2022-06-05 17:44:53 +00:00
const auto model_num = load_polygon_model ( model_name [ i ] , n_textures , first_bitmap_num [ i ] , ( i = = 0 ) ? & ri : nullptr ) ;
2006-03-20 17:12:09 +00:00
if ( i = = 0 )
Player_ship - > model_num = model_num ;
else
2022-10-09 23:15:20 +00:00
Polygon_models [ 0 ] . simpler_model = build_polygon_simpler_model_index_from_polygon_model_index ( model_num ) ;
2006-03-20 17:12:09 +00:00
}
if ( model_name_dying ) {
Assert ( n_models ) ;
Dying_modelnums [ Player_ship - > model_num ] = load_polygon_model ( model_name_dying , first_bitmap_num [ 1 ] - first_bitmap_num [ 0 ] , first_bitmap_num [ 0 ] , NULL ) ;
}
Assert ( ri . n_guns = = N_PLAYER_GUNS ) ;
//calc player gun positions
{
2022-06-05 17:44:53 +00:00
const auto & r = ri ;
const auto & pm = Polygon_models [ Player_ship - > model_num ] ;
/* Binding to the zip iterator produces references. For r.gun_points
* and r . gun_submodels , a mutable local is desired instead .
*
* If there are no submodels , copy directly from ` r . gun_points ` to
* ` plr_gun_point ` ( bound to an element of ` Player_ship - > gun_points ` ) .
*
* If there are submodels :
* - Copy the submodel index into a local ` mn `
* - Copy the r . gun_points vector into a local ` pnt `
* - Redirect ` ppnt ` to the local .
* - Update the local as needed from the polygon models .
* - Copy that local to ` plr_gun_point ` .
*
* This minimizes unnecessary copying .
*/
for ( auto & & [ rpnt , rmn , plr_gun_point ] : zip ( partial_range ( r . gun_points , r . n_guns ) , r . gun_submodels , Player_ship - > gun_points ) )
{
auto ppnt = & rpnt ;
/* Create a local copy to be modified by the `while` loop. */
vms_vector pnt ;
if ( auto mn = rmn )
{
2006-03-20 17:12:09 +00:00
//instance up the tree for this gun
2022-06-05 17:44:53 +00:00
pnt = rpnt ;
ppnt = & pnt ;
for ( ; mn & & mn < std : : size ( pm . submodel_offsets ) ; mn = pm . submodel_parents [ mn ] )
vm_vec_add2 ( pnt , pm . submodel_offsets [ mn ] ) ;
2006-03-20 17:12:09 +00:00
}
2022-06-05 17:44:53 +00:00
plr_gun_point = * ppnt ;
2006-03-20 17:12:09 +00:00
}
}
}
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
2018-10-21 00:24:07 +00:00
void bm_read_some_file ( d_vclip_array & Vclip , const std : : string & dest_bm , char * & arg , int skip )
2018-07-18 04:39:28 +00:00
# elif defined(DXX_BUILD_DESCENT_II)
2018-10-21 00:24:07 +00:00
void bm_read_some_file ( d_vclip_array & Vclip , int skip )
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
{
2020-10-07 03:59:14 +00:00
switch ( current_bm_type ) {
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2020-10-07 03:59:14 +00:00
case bm_type : : none :
Error ( " Trying to read bitmap <%s> with current_bm_type==BM_NONE on line %d of BITMAPS.TBL " , arg , linenum ) ;
2006-03-20 17:12:09 +00:00
break ;
2018-07-18 04:39:28 +00:00
# endif
2020-10-07 03:59:14 +00:00
case bm_type : : cockpit : {
2006-03-20 17:12:09 +00:00
bitmap_index bitmap ;
2008-02-11 12:12:57 +00:00
bitmap = bm_load_sub ( skip , arg ) ;
2022-02-12 18:57:12 +00:00
if ( Num_cockpits > = N_COCKPIT_BITMAPS )
throw std : : runtime_error ( " too many cockpit bitmaps " ) ;
cockpit_bitmap [ static_cast < cockpit_mode_t > ( Num_cockpits + + ) ] = bitmap ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
return ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
}
break ;
2020-10-07 03:59:14 +00:00
case bm_type : : gauges :
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
bm_read_gauges ( arg , skip ) ;
# elif defined(DXX_BUILD_DESCENT_II)
2008-02-11 12:12:57 +00:00
bm_read_gauges ( skip ) ;
2006-03-20 17:12:09 +00:00
return ;
break ;
2020-10-07 03:59:14 +00:00
case bm_type : : gauges_hires :
2006-03-20 17:12:09 +00:00
bm_read_gauges_hires ( ) ;
return ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
break ;
2020-10-07 03:59:14 +00:00
case bm_type : : vclip :
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
2018-10-21 00:24:07 +00:00
bm_read_vclip ( Vclip , arg , skip ) ;
2018-07-18 04:39:28 +00:00
# elif defined(DXX_BUILD_DESCENT_II)
2018-10-21 00:24:07 +00:00
bm_read_vclip ( Vclip , skip ) ;
2006-03-20 17:12:09 +00:00
return ;
2018-07-18 04:39:28 +00:00
# endif
break ;
2020-10-07 03:59:14 +00:00
case bm_type : : eclip :
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
bm_read_eclip ( dest_bm , arg , skip ) ;
# elif defined(DXX_BUILD_DESCENT_II)
2008-02-11 12:12:57 +00:00
bm_read_eclip ( skip ) ;
2006-03-20 17:12:09 +00:00
return ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
break ;
2020-10-07 03:59:14 +00:00
case bm_type : : textures : {
2006-03-20 17:12:09 +00:00
bitmap_index bitmap ;
2008-02-11 12:12:57 +00:00
bitmap = bm_load_sub ( skip , arg ) ;
2006-03-20 17:12:09 +00:00
Assert ( tmap_count < MAX_TEXTURES ) ;
2013-12-22 00:54:00 +00:00
tmap_count + + ;
2006-03-20 17:12:09 +00:00
Textures [ texture_count ] = bitmap ;
set_texture_name ( arg ) ;
Assert ( texture_count < MAX_TEXTURES ) ;
texture_count + + ;
NumTextures = texture_count ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
return ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
}
break ;
2020-10-07 03:59:14 +00:00
case bm_type : : wclip :
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
bm_read_wclip ( arg , skip ) ;
break ;
default :
# elif defined(DXX_BUILD_DESCENT_II)
2008-02-11 12:12:57 +00:00
bm_read_wclip ( skip ) ;
2006-03-20 17:12:09 +00:00
return ;
2018-07-18 04:39:28 +00:00
# endif
2020-10-07 03:59:14 +00:00
case bm_type : : effects :
case bm_type : : wall_anims :
case bm_type : : robot :
2006-03-20 17:12:09 +00:00
break ;
}
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2020-10-07 03:59:14 +00:00
Error ( " Trying to read bitmap <%s> with unknown current_bm_type <%x> on line %d of BITMAPS.TBL " , arg , static_cast < unsigned > ( current_bm_type ) , linenum ) ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
}
// ------------------------------------------------------------------------------
// If unused_flag is set, then this is just a placeholder. Don't actually reference vclips or load bbms.
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
void bm_read_weapon ( char * & arg , int skip , int unused_flag )
# elif defined(DXX_BUILD_DESCENT_II)
2008-02-11 12:12:57 +00:00
void bm_read_weapon ( int skip , int unused_flag )
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
{
int i , n ;
int n_models = 0 ;
char * equal_ptr ;
char * pof_file_inner = NULL ;
char * model_name [ MAX_MODEL_VARIANTS ] ;
int first_bitmap_num [ MAX_MODEL_VARIANTS ] ;
int lighted ; //flag for whether is a texture is lighted
Assert ( N_weapon_types < MAX_WEAPON_TYPES ) ;
n = N_weapon_types ;
N_weapon_types + + ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
Assert ( N_weapon_types < = MAX_WEAPON_TYPES ) ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
if ( unused_flag ) {
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
clear_to_end_of_line ( arg ) ;
# elif defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
clear_to_end_of_line ( ) ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
return ;
}
2008-02-11 12:12:57 +00:00
if ( skip ) {
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
clear_to_end_of_line ( arg ) ;
# elif defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
clear_to_end_of_line ( ) ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
return ;
}
// Initialize weapon array
2020-08-24 01:31:28 +00:00
Weapon_info [ n ] . render = WEAPON_RENDER_NONE ; // 0=laser, 1=blob, 2=object
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . bitmap . index = 0 ;
Weapon_info [ n ] . model_num = - 1 ;
Weapon_info [ n ] . model_num_inner = - 1 ;
Weapon_info [ n ] . blob_size = 0x1000 ; // size of blob
2014-10-04 15:04:44 +00:00
Weapon_info [ n ] . flash_vclip = vclip_none ;
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . flash_sound = SOUND_LASER_FIRED ;
Weapon_info [ n ] . flash_size = 0 ;
2014-10-04 15:04:44 +00:00
Weapon_info [ n ] . robot_hit_vclip = vclip_none ;
Weapon_info [ n ] . robot_hit_sound = sound_none ;
Weapon_info [ n ] . wall_hit_vclip = vclip_none ;
Weapon_info [ n ] . wall_hit_sound = sound_none ;
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . impact_size = 0 ;
2021-09-19 10:53:48 +00:00
for ( auto & i : Weapon_info [ n ] . strength )
i = F1_0 ;
for ( auto & i : Weapon_info [ n ] . speed )
i = F1_0 * 10 ;
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . mass = F1_0 ;
Weapon_info [ n ] . thrust = 0 ;
Weapon_info [ n ] . drag = 0 ;
2021-09-19 10:53:48 +00:00
Weapon_info [ n ] . persistent = weapon_info : : persistence_flag : : terminate_on_impact ;
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . energy_usage = 0 ; // How much fuel is consumed to fire this weapon.
Weapon_info [ n ] . ammo_usage = 0 ; // How many units of ammunition it uses.
Weapon_info [ n ] . fire_wait = F1_0 / 4 ; // Time until this weapon can be fired again.
Weapon_info [ n ] . fire_count = 1 ; // Number of bursts fired from EACH GUN per firing. For weapons which fire from both sides, 3*fire_count shots will be fired.
Weapon_info [ n ] . damage_radius = 0 ; // Radius of damage for missiles, not lasers. Does damage to objects within this radius of hit point.
//--01/19/95, mk-- Weapon_info[n].damage_force = 0; // Force (movement) due to explosion
Weapon_info [ n ] . destroyable = 1 ; // Weapons default to destroyable
2020-12-20 20:39:07 +00:00
Weapon_info [ n ] . matter = weapon_info : : matter_flag : : energy ; // Weapons default to not being constructed of matter (they are energy!)
2020-12-20 20:39:07 +00:00
Weapon_info [ n ] . bounce = weapon_info : : bounce_type : : never ; // Weapons default to not bouncing off walls
2006-03-20 17:12:09 +00:00
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . flags = 0 ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . lifetime = WEAPON_DEFAULT_LIFETIME ; // Number of bursts fired from EACH GUN per firing. For weapons which fire from both sides, 3*fire_count shots will be fired.
Weapon_info [ n ] . po_len_to_width_ratio = F1_0 * 10 ;
Weapon_info [ n ] . picture . index = 0 ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . hires_picture . index = 0 ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . homing_flag = 0 ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . flash = 0 ;
Weapon_info [ n ] . multi_damage_scale = F1_0 ;
Weapon_info [ n ] . afterburner_size = 0 ;
2015-12-03 03:26:49 +00:00
Weapon_info [ n ] . children = weapon_id_type : : unspecified ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
// Process arguments
2015-01-29 04:27:35 +00:00
arg = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
lighted = 1 ; //assume first texture is lighted
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . speedvar = 128 ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
while ( arg ! = NULL ) {
equal_ptr = strchr ( arg , ' = ' ) ;
if ( equal_ptr ) {
* equal_ptr = ' \0 ' ;
equal_ptr + + ;
// if we have john=cool, arg is 'john' and equal_ptr is 'cool'
2012-05-18 23:36:43 +00:00
if ( ! d_stricmp ( arg , " laser_bmp " ) ) {
2006-03-20 17:12:09 +00:00
// Load bitmap with name equal_ptr
2008-02-11 12:12:57 +00:00
Weapon_info [ n ] . bitmap = bm_load_sub ( skip , equal_ptr ) ; //load_polymodel_bitmap(equal_ptr);
2020-08-24 01:31:28 +00:00
Weapon_info [ n ] . render = WEAPON_RENDER_LASER ;
2006-03-20 17:12:09 +00:00
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " blob_bmp " ) ) {
2006-03-20 17:12:09 +00:00
// Load bitmap with name equal_ptr
2008-02-11 12:12:57 +00:00
Weapon_info [ n ] . bitmap = bm_load_sub ( skip , equal_ptr ) ; //load_polymodel_bitmap(equal_ptr);
2020-08-24 01:31:28 +00:00
Weapon_info [ n ] . render = WEAPON_RENDER_BLOB ;
2006-03-20 17:12:09 +00:00
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " weapon_vclip " ) ) {
2006-03-20 17:12:09 +00:00
// Set vclip to play for this weapon.
Weapon_info [ n ] . bitmap . index = 0 ;
2020-08-24 01:31:28 +00:00
Weapon_info [ n ] . render = WEAPON_RENDER_VCLIP ;
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . weapon_vclip = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " none_bmp " ) ) {
2008-02-11 12:12:57 +00:00
Weapon_info [ n ] . bitmap = bm_load_sub ( skip , equal_ptr ) ;
2020-08-24 01:31:28 +00:00
Weapon_info [ n ] . render = WEAPON_RENDER_NONE ;
2006-03-20 17:12:09 +00:00
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " weapon_pof " ) ) {
2006-03-20 17:12:09 +00:00
// Load pof file
Assert ( n_models = = 0 ) ;
model_name [ 0 ] = equal_ptr ;
first_bitmap_num [ 0 ] = N_ObjBitmapPtrs ;
n_models = 1 ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " simple_model " ) ) {
2006-03-20 17:12:09 +00:00
model_name [ n_models ] = equal_ptr ;
first_bitmap_num [ n_models ] = N_ObjBitmapPtrs ;
n_models + + ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
Assert ( n_models < MAX_MODEL_VARIANTS ) ;
2018-07-18 04:39:28 +00:00
# endif
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " weapon_pof_inner " ) ) {
2006-03-20 17:12:09 +00:00
// Load pof file
pof_file_inner = equal_ptr ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " strength " ) ) {
2021-09-19 10:53:48 +00:00
for ( auto & i : unchecked_partial_range ( Weapon_info [ n ] . strength , Weapon_info [ n ] . strength . size ( ) - 1 ) )
{
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
2021-09-19 10:53:48 +00:00
i = i2f ( atoi ( equal_ptr ) ) ;
2018-07-18 04:39:28 +00:00
# elif defined(DXX_BUILD_DESCENT_II)
2021-09-19 10:53:48 +00:00
i = fl2f ( atof ( equal_ptr ) ) ;
2018-07-18 04:39:28 +00:00
# endif
2015-01-29 04:27:35 +00:00
equal_ptr = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
}
2021-09-19 10:53:48 +00:00
Weapon_info [ n ] . strength . back ( ) = i2f ( atoi ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " mass " ) ) {
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . mass = fl2f ( atof ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " drag " ) ) {
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . drag = fl2f ( atof ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " thrust " ) ) {
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . thrust = fl2f ( atof ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " matter " ) ) {
2020-12-20 20:39:07 +00:00
Weapon_info [ n ] . matter = static_cast < weapon_info : : matter_flag > ( atoi ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " bounce " ) ) {
2020-12-20 20:39:07 +00:00
Weapon_info [ n ] . bounce = static_cast < weapon_info : : bounce_type > ( atoi ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " speed " ) ) {
2021-09-19 10:53:48 +00:00
for ( auto & i : unchecked_partial_range ( Weapon_info [ n ] . speed , Weapon_info [ n ] . speed . size ( ) - 1 ) )
{
i = i2f ( atoi ( equal_ptr ) ) ;
2015-01-29 04:27:35 +00:00
equal_ptr = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
}
2021-09-19 10:53:48 +00:00
Weapon_info [ n ] . speed . back ( ) = i2f ( atoi ( equal_ptr ) ) ;
2018-07-18 04:39:28 +00:00
}
# if defined(DXX_BUILD_DESCENT_II)
else if ( ! d_stricmp ( arg , " speedvar " ) ) {
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . speedvar = ( atoi ( equal_ptr ) * 128 ) / 100 ;
2018-07-18 04:39:28 +00:00
}
# endif
else if ( ! d_stricmp ( arg , " flash_vclip " ) ) {
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . flash_vclip = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " flash_sound " ) ) {
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . flash_sound = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " flash_size " ) ) {
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . flash_size = fl2f ( atof ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " blob_size " ) ) {
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . blob_size = fl2f ( atof ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " robot_hit_vclip " ) ) {
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . robot_hit_vclip = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " robot_hit_sound " ) ) {
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . robot_hit_sound = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " wall_hit_vclip " ) ) {
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . wall_hit_vclip = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " wall_hit_sound " ) ) {
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . wall_hit_sound = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " impact_size " ) ) {
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . impact_size = fl2f ( atof ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " lighted " ) ) {
2006-03-20 17:12:09 +00:00
lighted = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " lw_ratio " ) ) {
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . po_len_to_width_ratio = fl2f ( atof ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " lightcast " ) ) {
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . light = fl2f ( atof ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " persistent " ) ) {
2021-09-19 10:53:48 +00:00
Weapon_info [ n ] . persistent = atoi ( equal_ptr ) ? weapon_info : : persistence_flag : : persistent : weapon_info : : persistence_flag : : terminate_on_impact ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " energy_usage " ) ) {
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . energy_usage = fl2f ( atof ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " ammo_usage " ) ) {
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . ammo_usage = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " fire_wait " ) ) {
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . fire_wait = fl2f ( atof ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " fire_count " ) ) {
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . fire_count = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " damage_radius " ) ) {
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . damage_radius = fl2f ( atof ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
//--01/19/95, mk-- } else if (!d_stricmp(arg, "damage_force" )) {
2006-03-20 17:12:09 +00:00
//--01/19/95, mk-- Weapon_info[n].damage_force = fl2f(atof(equal_ptr));
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " lifetime " ) ) {
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . lifetime = fl2f ( atof ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " destroyable " ) ) {
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . destroyable = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " picture " ) ) {
2008-02-11 12:12:57 +00:00
Weapon_info [ n ] . picture = bm_load_sub ( skip , equal_ptr ) ;
2018-07-18 04:39:28 +00:00
}
# if defined(DXX_BUILD_DESCENT_II)
else if ( ! d_stricmp ( arg , " hires_picture " ) ) {
2008-02-11 12:12:57 +00:00
Weapon_info [ n ] . hires_picture = bm_load_sub ( skip , equal_ptr ) ;
2018-07-18 04:39:28 +00:00
}
# endif
else if ( ! d_stricmp ( arg , " homing " ) ) {
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . homing_flag = ! ! atoi ( equal_ptr ) ;
2018-07-18 04:39:28 +00:00
}
# if defined(DXX_BUILD_DESCENT_II)
else if ( ! d_stricmp ( arg , " flash " ) ) {
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . flash = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " multi_damage_scale " ) ) {
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . multi_damage_scale = fl2f ( atof ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " afterburner_size " ) ) {
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . afterburner_size = f2i ( 16 * fl2f ( atof ( equal_ptr ) ) ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " children " ) ) {
2015-12-03 03:26:49 +00:00
Weapon_info [ n ] . children = static_cast < weapon_id_type > ( atoi ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " placable " ) ) {
2006-03-20 17:12:09 +00:00
if ( atoi ( equal_ptr ) ) {
Weapon_info [ n ] . flags | = WIF_PLACABLE ;
}
} else {
Int3 ( ) ;
2018-07-18 04:39:28 +00:00
}
# endif
2006-03-20 17:12:09 +00:00
} else { // Must be a texture specification...
grs_bitmap * bm ;
2008-02-11 12:12:57 +00:00
bm = load_polymodel_bitmap ( skip , arg ) ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
if ( bm & & ! lighted )
# elif defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
if ( ! lighted )
2018-07-18 04:39:28 +00:00
# endif
2017-01-15 00:03:13 +00:00
bm - > add_flags ( BM_FLAG_NO_LIGHTING ) ;
2006-03-20 17:12:09 +00:00
lighted = 1 ; //default for next bitmap is lighted
}
2015-01-29 04:27:35 +00:00
arg = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
}
first_bitmap_num [ n_models ] = N_ObjBitmapPtrs ;
2018-12-30 00:43:59 +00:00
auto & Polygon_models = LevelSharedPolygonModelState . Polygon_models ;
2006-03-20 17:12:09 +00:00
for ( i = 0 ; i < n_models ; i + + ) {
int n_textures ;
n_textures = first_bitmap_num [ i + 1 ] - first_bitmap_num [ i ] ;
2022-10-09 23:15:20 +00:00
const auto model_num = load_polygon_model ( model_name [ i ] , n_textures , first_bitmap_num [ i ] , NULL ) ;
2006-03-20 17:12:09 +00:00
if ( i = = 0 ) {
2020-08-24 01:31:28 +00:00
Weapon_info [ n ] . render = WEAPON_RENDER_POLYMODEL ;
2006-03-20 17:12:09 +00:00
Weapon_info [ n ] . model_num = model_num ;
}
else
2022-10-09 23:15:20 +00:00
Polygon_models [ 0 ] . simpler_model = build_polygon_simpler_model_index_from_polygon_model_index ( model_num ) ;
2006-03-20 17:12:09 +00:00
}
if ( pof_file_inner ) {
Assert ( n_models ) ;
Weapon_info [ n ] . model_num_inner = load_polygon_model ( pof_file_inner , first_bitmap_num [ 1 ] - first_bitmap_num [ 0 ] , first_bitmap_num [ 0 ] , NULL ) ;
}
}
// ------------------------------------------------------------------------------
# define DEFAULT_POWERUP_SIZE i2f(3)
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
void bm_read_powerup ( char * & arg , int unused_flag )
# elif defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
void bm_read_powerup ( int unused_flag )
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
{
int n ;
char * equal_ptr ;
Assert ( N_powerup_types < MAX_POWERUP_TYPES ) ;
n = N_powerup_types ;
N_powerup_types + + ;
if ( unused_flag ) {
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
clear_to_end_of_line ( arg ) ;
# elif defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
clear_to_end_of_line ( ) ;
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
return ;
}
// Initialize powerup array
Powerup_info [ n ] . light = F1_0 / 3 ; // Default lighting value.
2014-10-04 15:04:44 +00:00
Powerup_info [ n ] . vclip_num = vclip_none ;
Powerup_info [ n ] . hit_sound = sound_none ;
2006-03-20 17:12:09 +00:00
Powerup_info [ n ] . size = DEFAULT_POWERUP_SIZE ;
2016-09-11 18:49:16 +00:00
# if DXX_USE_EDITOR
2006-03-20 17:12:09 +00:00
Powerup_names [ n ] [ 0 ] = 0 ;
2016-07-09 17:58:34 +00:00
# endif
2006-03-20 17:12:09 +00:00
// Process arguments
2015-01-29 04:27:35 +00:00
arg = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
while ( arg ! = NULL ) {
equal_ptr = strchr ( arg , ' = ' ) ;
if ( equal_ptr ) {
* equal_ptr = ' \0 ' ;
equal_ptr + + ;
// if we have john=cool, arg is 'john' and equal_ptr is 'cool'
2012-05-18 23:36:43 +00:00
if ( ! d_stricmp ( arg , " vclip_num " ) ) {
2006-03-20 17:12:09 +00:00
Powerup_info [ n ] . vclip_num = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " light " ) ) {
2006-03-20 17:12:09 +00:00
Powerup_info [ n ] . light = fl2f ( atof ( equal_ptr ) ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " hit_sound " ) ) {
2006-03-20 17:12:09 +00:00
Powerup_info [ n ] . hit_sound = atoi ( equal_ptr ) ;
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " name " ) ) {
2016-09-11 18:49:16 +00:00
# if DXX_USE_EDITOR
2016-07-09 17:58:34 +00:00
auto & name = Powerup_names [ n ] ;
const auto len = strlen ( equal_ptr ) ;
assert ( len < name . size ( ) ) ; // Oops, name too long.
memcpy ( name . data ( ) , & equal_ptr [ 1 ] , len - 2 ) ;
name [ len - 2 ] = 0 ;
# endif
2012-05-18 23:36:43 +00:00
} else if ( ! d_stricmp ( arg , " size " ) ) {
2006-03-20 17:12:09 +00:00
Powerup_info [ n ] . size = fl2f ( atof ( equal_ptr ) ) ;
2018-07-18 04:39:28 +00:00
}
# if defined(DXX_BUILD_DESCENT_II)
else {
2006-03-20 17:12:09 +00:00
Int3 ( ) ;
2018-07-18 04:39:28 +00:00
}
# endif
}
# if defined(DXX_BUILD_DESCENT_II)
else { // Must be a texture specification...
2006-03-20 17:12:09 +00:00
Int3 ( ) ;
}
2018-07-18 04:39:28 +00:00
# endif
2015-01-29 04:27:35 +00:00
arg = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
}
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
ObjType [ Num_total_object_types ] = OL_POWERUP ;
ObjId [ Num_total_object_types ] = n ;
Num_total_object_types + + ;
# endif
2006-03-20 17:12:09 +00:00
}
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
void bm_read_hostage ( char * & arg )
# elif defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
void bm_read_hostage ( )
2018-07-18 04:39:28 +00:00
# endif
2006-03-20 17:12:09 +00:00
{
int n ;
char * equal_ptr ;
Assert ( N_hostage_types < MAX_HOSTAGE_TYPES ) ;
n = N_hostage_types ;
N_hostage_types + + ;
// Process arguments
2015-01-29 04:27:35 +00:00
arg = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
while ( arg ! = NULL ) {
equal_ptr = strchr ( arg , ' = ' ) ;
if ( equal_ptr ) {
* equal_ptr = ' \0 ' ;
equal_ptr + + ;
2012-05-18 23:36:43 +00:00
if ( ! d_stricmp ( arg , " vclip_num " ) )
2006-03-20 17:12:09 +00:00
Hostage_vclip_num [ n ] = atoi ( equal_ptr ) ;
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_II)
2006-03-20 17:12:09 +00:00
else {
Int3 ( ) ;
}
2018-07-18 04:39:28 +00:00
# endif
}
# if defined(DXX_BUILD_DESCENT_II)
else {
2006-03-20 17:12:09 +00:00
Int3 ( ) ;
}
2018-07-18 04:39:28 +00:00
# endif
2015-01-29 04:27:35 +00:00
arg = strtok ( NULL , space_tab ) ;
2006-03-20 17:12:09 +00:00
}
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
ObjType [ Num_total_object_types ] = OL_HOSTAGE ;
ObjId [ Num_total_object_types ] = n ;
Num_total_object_types + + ;
# endif
2006-03-20 17:12:09 +00:00
}
2020-10-07 03:59:14 +00:00
}
}
2018-07-18 04:39:28 +00:00
# if defined(DXX_BUILD_DESCENT_I)
2020-05-02 21:18:42 +00:00
DEFINE_SERIAL_UDT_TO_MESSAGE ( tmap_info , t , ( static_cast < const std : : array < char , 13 > & > ( t . filename ) , t . flags , t . lighting , t . damage , t . eclip_num ) ) ;
2018-07-18 04:39:28 +00:00
ASSERT_SERIAL_UDT_MESSAGE_SIZE ( tmap_info , 26 ) ;
# elif defined(DXX_BUILD_DESCENT_II)
2014-07-23 02:09:33 +00:00
DEFINE_SERIAL_UDT_TO_MESSAGE ( tmap_info , t , ( t . flags , serial : : pad < 3 > ( ) , t . lighting , t . damage , t . eclip_num , t . destroyed , t . slide_u , t . slide_v ) ) ;
ASSERT_SERIAL_UDT_MESSAGE_SIZE ( tmap_info , 20 ) ;
2015-01-17 18:31:43 +00:00
# endif