2014-03-15 16:59:03 +00:00
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team.
2020-02-19 22:08:45 +00:00
// Copyright (C) 1999-2020 by Sonic Team Junior.
2014-03-15 16:59:03 +00:00
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file dehacked.c
/// \brief Load dehacked file and change tables and text
# include "doomdef.h"
# include "m_cond.h"
2020-10-29 05:48:29 +00:00
# include "deh_soc.h"
# include "deh_tables.h"
2014-03-15 16:59:03 +00:00
2020-10-29 05:48:29 +00:00
boolean deh_loaded = false ;
2014-03-15 16:59:03 +00:00
2020-10-29 05:48:29 +00:00
boolean gamedataadded = false ;
boolean titlechanged = false ;
boolean introchanged = false ;
2014-03-15 16:59:03 +00:00
2020-10-29 05:48:29 +00:00
static int dbg_line ;
static INT32 deh_num_warning = 0 ;
2014-03-15 16:59:03 +00:00
2020-10-29 05:48:29 +00:00
FUNCPRINTF void deh_warning ( const char * first , . . . )
{
va_list argptr ;
char * buf = Z_Malloc ( 1000 , PU_STATIC , NULL ) ;
2014-03-15 16:59:03 +00:00
2020-10-29 05:48:29 +00:00
va_start ( argptr , first ) ;
vsnprintf ( buf , 1000 , first , argptr ) ; // sizeof only returned 4 here. it didn't like that pointer.
va_end ( argptr ) ;
2014-03-15 16:59:03 +00:00
2020-10-29 05:48:29 +00:00
if ( dbg_line = = - 1 ) // Not in a SOC, line number unknown.
CONS_Alert ( CONS_WARNING , " %s \n " , buf ) ;
else
CONS_Alert ( CONS_WARNING , " Line %u: %s \n " , dbg_line , buf ) ;
deh_num_warning + + ;
Z_Free ( buf ) ;
}
void deh_strlcpy ( char * dst , const char * src , size_t size , const char * warntext )
{
size_t len = strlen ( src ) + 1 ; // Used to determine if truncation has been done
if ( len > size )
deh_warning ( " %s exceeds max length of %s " , warntext , sizeu1 ( size - 1 ) ) ;
strlcpy ( dst , src , size ) ;
}
2014-03-15 16:59:03 +00:00
ATTRINLINE static FUNCINLINE char myfget_color ( MYFILE * f )
{
char c = * f - > curpos + + ;
if ( c = = ' ^ ' ) // oh, nevermind then.
return ' ^ ' ;
if ( c > = ' 0 ' & & c < = ' 9 ' )
return 0x80 + ( c - ' 0 ' ) ;
2020-12-06 10:28:12 +00:00
c = tolower ( c ) ;
if ( c > = ' a ' & & c < = ' f ' )
return 0x80 + 10 + ( c - ' a ' ) ;
2014-03-15 16:59:03 +00:00
return 0x80 ; // Unhandled -- default to no color
}
ATTRINLINE static FUNCINLINE char myfget_hex ( MYFILE * f )
{
char c = * f - > curpos + + , endchr = 0 ;
if ( c = = ' \\ ' ) // oh, nevermind then.
return ' \\ ' ;
if ( c > = ' 0 ' & & c < = ' 9 ' )
endchr + = ( c - ' 0 ' ) < < 4 ;
else if ( c > = ' A ' & & c < = ' F ' )
endchr + = ( ( c - ' A ' ) + 10 ) < < 4 ;
else if ( c > = ' a ' & & c < = ' f ' )
endchr + = ( ( c - ' a ' ) + 10 ) < < 4 ;
else // invalid. stop and return a question mark.
return ' ? ' ;
c = * f - > curpos + + ;
if ( c > = ' 0 ' & & c < = ' 9 ' )
endchr + = ( c - ' 0 ' ) ;
else if ( c > = ' A ' & & c < = ' F ' )
endchr + = ( ( c - ' A ' ) + 10 ) ;
else if ( c > = ' a ' & & c < = ' f ' )
endchr + = ( ( c - ' a ' ) + 10 ) ;
else // invalid. stop and return a question mark.
return ' ? ' ;
return endchr ;
}
char * myfgets ( char * buf , size_t bufsize , MYFILE * f )
{
size_t i = 0 ;
if ( myfeof ( f ) )
return NULL ;
// we need one byte for a null terminated string
bufsize - - ;
while ( i < bufsize & & ! myfeof ( f ) )
{
char c = * f - > curpos + + ;
if ( c = = ' ^ ' )
buf [ i + + ] = myfget_color ( f ) ;
else if ( c = = ' \\ ' )
buf [ i + + ] = myfget_hex ( f ) ;
else if ( c ! = ' \r ' )
buf [ i + + ] = c ;
if ( c = = ' \n ' )
break ;
}
buf [ i ] = ' \0 ' ;
dbg_line + + ;
return buf ;
}
2020-10-29 05:48:29 +00:00
char * myhashfgets ( char * buf , size_t bufsize , MYFILE * f )
2014-03-15 16:59:03 +00:00
{
size_t i = 0 ;
if ( myfeof ( f ) )
return NULL ;
// we need one byte for a null terminated string
bufsize - - ;
while ( i < bufsize & & ! myfeof ( f ) )
{
char c = * f - > curpos + + ;
if ( c = = ' ^ ' )
buf [ i + + ] = myfget_color ( f ) ;
else if ( c = = ' \\ ' )
buf [ i + + ] = myfget_hex ( f ) ;
else if ( c ! = ' \r ' )
buf [ i + + ] = c ;
if ( c = = ' \n ' ) // Ensure debug line is right...
dbg_line + + ;
if ( c = = ' # ' )
2018-11-03 08:38:16 +00:00
{
2018-11-03 09:04:09 +00:00
if ( i > 0 ) // don't let i wrap past 0
i - - ; // don't include hash char in string
2014-03-15 16:59:03 +00:00
break ;
2018-11-03 08:38:16 +00:00
}
}
2018-11-03 09:04:09 +00:00
if ( buf [ i ] ! = ' # ' ) // don't include hash char in string
i + + ;
2018-11-03 08:38:16 +00:00
buf [ i ] = ' \0 ' ;
2018-11-03 09:04:09 +00:00
2014-03-15 16:59:03 +00:00
return buf ;
}
2020-10-29 05:48:29 +00:00
// Used when you do something invalid like read a bad item number
// to prevent extra unnecessary errors
static void ignorelines ( MYFILE * f )
2014-03-15 16:59:03 +00:00
{
2020-10-29 05:48:29 +00:00
char * s = Z_Malloc ( MAXLINELEN , PU_STATIC , NULL ) ;
do
2014-03-15 16:59:03 +00:00
{
2020-10-29 05:48:29 +00:00
if ( myfgets ( s , MAXLINELEN , f ) )
{
if ( s [ 0 ] = = ' \n ' )
break ;
}
} while ( ! myfeof ( f ) ) ;
Z_Free ( s ) ;
2014-03-15 16:59:03 +00:00
}
2020-10-29 05:48:29 +00:00
static void DEH_LoadDehackedFile ( MYFILE * f , boolean mainfile )
2014-03-15 16:59:03 +00:00
{
char * s = Z_Malloc ( MAXLINELEN , PU_STATIC , NULL ) ;
2020-10-29 05:48:29 +00:00
char textline [ MAXLINELEN ] ;
2014-03-15 16:59:03 +00:00
char * word ;
char * word2 ;
INT32 i ;
2020-10-29 05:48:29 +00:00
if ( ! deh_loaded )
initfreeslots ( ) ;
2019-10-14 05:24:44 +00:00
2020-10-29 05:48:29 +00:00
deh_num_warning = 0 ;
2019-10-14 05:24:44 +00:00
2020-10-29 05:48:29 +00:00
gamedataadded = titlechanged = introchanged = false ;
// it doesn't test the version of SRB2 and version of dehacked file
dbg_line = - 1 ; // start at -1 so the first line is 0.
while ( ! myfeof ( f ) )
2014-03-15 16:59:03 +00:00
{
2020-10-29 05:48:29 +00:00
char origpos [ 128 ] ;
INT32 size = 0 ;
char * traverse ;
myfgets ( s , MAXLINELEN , f ) ;
memcpy ( textline , s , MAXLINELEN ) ;
if ( s [ 0 ] = = ' \n ' | | s [ 0 ] = = ' # ' )
continue ;
traverse = s ;
while ( traverse [ 0 ] ! = ' \n ' )
2014-03-15 16:59:03 +00:00
{
2020-10-29 05:48:29 +00:00
traverse + + ;
size + + ;
}
strncpy ( origpos , s , size ) ;
origpos [ size ] = ' \0 ' ;
2014-03-15 16:59:03 +00:00
2020-10-29 05:48:29 +00:00
if ( NULL ! = ( word = strtok ( s , " " ) ) ) {
strupr ( word ) ;
if ( word [ strlen ( word ) - 1 ] = = ' \n ' )
word [ strlen ( word ) - 1 ] = ' \0 ' ;
}
if ( word )
{
if ( fastcmp ( word , " FREESLOT " ) )
{
readfreeslots ( f ) ;
continue ;
}
else if ( fastcmp ( word , " MAINCFG " ) )
{
readmaincfg ( f ) ;
continue ;
}
else if ( fastcmp ( word , " WIPES " ) )
{
readwipes ( f ) ;
continue ;
}
word2 = strtok ( NULL , " " ) ;
if ( word2 ) {
strupr ( word2 ) ;
if ( word2 [ strlen ( word2 ) - 1 ] = = ' \n ' )
word2 [ strlen ( word2 ) - 1 ] = ' \0 ' ;
i = atoi ( word2 ) ;
}
else
i = 0 ;
if ( fastcmp ( word , " CHARACTER " ) )
2019-10-14 05:24:44 +00:00
{
2020-10-29 05:48:29 +00:00
if ( i > = 0 & & i < 32 )
readPlayer ( f , i ) ;
else
2019-10-14 05:24:44 +00:00
{
2020-10-29 05:48:29 +00:00
deh_warning ( " Character %d out of range (0 - 31) " , i ) ;
ignorelines ( f ) ;
2019-10-14 05:24:44 +00:00
}
2020-10-29 05:48:29 +00:00
continue ;
2019-10-14 05:24:44 +00:00
}
2020-10-29 05:48:29 +00:00
else if ( fastcmp ( word , " EMBLEM " ) )
2014-03-15 16:59:03 +00:00
{
2020-10-29 05:48:29 +00:00
if ( ! mainfile & & ! gamedataadded )
{
deh_warning ( " You must define a custom gamedata to use \" %s \" " , word ) ;
ignorelines ( f ) ;
}
else
2014-03-15 16:59:03 +00:00
{
2020-10-29 05:48:29 +00:00
if ( ! word2 )
i = numemblems + 1 ;
if ( i > 0 & & i < = MAXEMBLEMS )
{
if ( numemblems < i )
numemblems = i ;
reademblemdata ( f , i ) ;
}
else
2014-03-15 16:59:03 +00:00
{
2020-10-29 05:48:29 +00:00
deh_warning ( " Emblem number %d out of range (1 - %d) " , i , MAXEMBLEMS ) ;
ignorelines ( f ) ;
2014-03-15 16:59:03 +00:00
}
}
2020-10-29 05:48:29 +00:00
continue ;
}
else if ( fastcmp ( word , " EXTRAEMBLEM " ) )
{
if ( ! mainfile & & ! gamedataadded )
2014-03-15 16:59:03 +00:00
{
2020-10-29 05:48:29 +00:00
deh_warning ( " You must define a custom gamedata to use \" %s \" " , word ) ;
ignorelines ( f ) ;
2014-03-15 16:59:03 +00:00
}
else
{
2020-10-29 05:48:29 +00:00
if ( ! word2 )
i = numextraemblems + 1 ;
2014-03-15 16:59:03 +00:00
2020-10-29 05:48:29 +00:00
if ( i > 0 & & i < = MAXEXTRAEMBLEMS )
{
if ( numextraemblems < i )
numextraemblems = i ;
readextraemblemdata ( f , i ) ;
}
else
{
deh_warning ( " Extra emblem number %d out of range (1 - %d) " , i , MAXEXTRAEMBLEMS ) ;
ignorelines ( f ) ;
2014-03-15 16:59:03 +00:00
}
}
continue ;
}
if ( word2 )
2019-08-19 01:26:52 +00:00
{
2020-10-29 05:48:29 +00:00
if ( fastcmp ( word , " THING " ) | | fastcmp ( word , " MOBJ " ) | | fastcmp ( word , " OBJECT " ) )
2019-10-14 05:24:44 +00:00
{
2020-10-29 05:48:29 +00:00
if ( i = = 0 & & word2 [ 0 ] ! = ' 0 ' ) // If word2 isn't a number
i = get_mobjtype ( word2 ) ; // find a thing by name
if ( i < NUMMOBJTYPES & & i > 0 )
readthing ( f , i ) ;
else
2019-10-14 05:24:44 +00:00
{
2020-10-29 05:48:29 +00:00
deh_warning ( " Thing %d out of range (1 - %d) " , i , NUMMOBJTYPES - 1 ) ;
ignorelines ( f ) ;
2019-10-14 05:24:44 +00:00
}
}
2020-10-29 05:48:29 +00:00
else if ( fastcmp ( word , " SKINCOLOR " ) | | fastcmp ( word , " COLOR " ) )
2014-03-15 16:59:03 +00:00
{
2020-10-29 05:48:29 +00:00
if ( i = = 0 & & word2 [ 0 ] ! = ' 0 ' ) // If word2 isn't a number
i = get_skincolor ( word2 ) ; // find a skincolor by name
if ( i & & i < numskincolors )
readskincolor ( f , i ) ;
else
2014-03-15 16:59:03 +00:00
{
2020-10-29 05:48:29 +00:00
deh_warning ( " Skincolor %d out of range (1 - %d) " , i , numskincolors - 1 ) ;
ignorelines ( f ) ;
2014-03-15 16:59:03 +00:00
}
}
2020-10-29 05:48:29 +00:00
else if ( fastcmp ( word , " SPRITE2 " ) )
{
if ( i = = 0 & & word2 [ 0 ] ! = ' 0 ' ) // If word2 isn't a number
i = get_sprite2 ( word2 ) ; // find a sprite by name
if ( i < ( INT32 ) free_spr2 & & i > = ( INT32 ) SPR2_FIRSTFREESLOT )
readsprite2 ( f , i ) ;
else
{
deh_warning ( " Sprite2 number %d out of range (%d - %d) " , i , SPR2_FIRSTFREESLOT , free_spr2 - 1 ) ;
ignorelines ( f ) ;
2014-03-15 16:59:03 +00:00
}
2020-10-29 05:48:29 +00:00
}
# ifdef HWRENDER
else if ( fastcmp ( word , " LIGHT " ) )
{
// TODO: Read lights by name
if ( i > 0 & & i < NUMLIGHTS )
readlight ( f , i ) ;
else
{
deh_warning ( " Light number %d out of range (1 - %d) " , i , NUMLIGHTS - 1 ) ;
ignorelines ( f ) ;
2014-03-15 16:59:03 +00:00
}
2020-10-29 05:48:29 +00:00
}
# endif
else if ( fastcmp ( word , " SPRITE " ) | | fastcmp ( word , " SPRITEINFO " ) )
{
if ( i = = 0 & & word2 [ 0 ] ! = ' 0 ' ) // If word2 isn't a number
i = get_sprite ( word2 ) ; // find a sprite by name
if ( i < NUMSPRITES & & i > 0 )
readspriteinfo ( f , i , false ) ;
else
{
deh_warning ( " Sprite number %d out of range (0 - %d) " , i , NUMSPRITES - 1 ) ;
ignorelines ( f ) ;
2020-02-15 08:18:41 +00:00
}
2020-10-29 05:48:29 +00:00
}
else if ( fastcmp ( word , " SPRITE2INFO " ) )
2019-12-18 21:59:47 +00:00
{
2020-10-29 05:48:29 +00:00
if ( i = = 0 & & word2 [ 0 ] ! = ' 0 ' ) // If word2 isn't a number
i = get_sprite2 ( word2 ) ; // find a sprite by name
if ( i < NUMPLAYERSPRITES & & i > = 0 )
readspriteinfo ( f , i , true ) ;
else
{
deh_warning ( " Sprite2 number %d out of range (0 - %d) " , i , NUMPLAYERSPRITES - 1 ) ;
ignorelines ( f ) ;
}
2019-12-18 21:59:47 +00:00
}
2020-10-29 05:48:29 +00:00
else if ( fastcmp ( word , " LEVEL " ) )
2020-07-12 11:39:52 +00:00
{
2020-10-29 05:48:29 +00:00
// Support using the actual map name,
// i.e., Level AB, Level FZ, etc.
// Convert to map number
if ( word2 [ 0 ] > = ' A ' & & word2 [ 0 ] < = ' Z ' )
i = M_MapNumber ( word2 [ 0 ] , word2 [ 1 ] ) ;
2020-07-12 11:39:52 +00:00
2020-10-29 05:48:29 +00:00
if ( i > 0 & & i < = NUMMAPS )
readlevelheader ( f , i ) ;
else
2020-07-12 11:39:52 +00:00
{
2020-10-29 05:48:29 +00:00
deh_warning ( " Level number %d out of range (1 - %d) " , i , NUMMAPS ) ;
ignorelines ( f ) ;
2020-07-12 11:39:52 +00:00
}
2020-10-29 05:48:29 +00:00
}
else if ( fastcmp ( word , " GAMETYPE " ) )
{
// Get the gametype name from textline
// instead of word2, so that gametype names
// aren't allcaps
INT32 c ;
for ( c = 0 ; c < MAXLINELEN ; c + + )
2020-07-12 11:39:52 +00:00
{
2020-10-29 05:48:29 +00:00
if ( textline [ c ] = = ' \0 ' )
break ;
if ( textline [ c ] = = ' ' )
{
char * gtname = ( textline + c + 1 ) ;
if ( gtname )
{
// remove funny characters
INT32 j ;
for ( j = 0 ; j < ( MAXLINELEN - c ) ; j + + )
{
if ( gtname [ j ] = = ' \0 ' )
break ;
if ( gtname [ j ] < 32 )
gtname [ j ] = ' \0 ' ;
}
readgametype ( f , gtname ) ;
}
2020-07-12 11:39:52 +00:00
break ;
2020-10-29 05:48:29 +00:00
}
2020-07-12 11:39:52 +00:00
}
}
2020-10-29 05:48:29 +00:00
else if ( fastcmp ( word , " CUTSCENE " ) )
{
if ( i > 0 & & i < 129 )
readcutscene ( f , i - 1 ) ;
else
{
deh_warning ( " Cutscene number %d out of range (1 - 128) " , i ) ;
ignorelines ( f ) ;
}
2020-02-15 08:18:41 +00:00
}
2020-10-29 05:48:29 +00:00
else if ( fastcmp ( word , " PROMPT " ) )
2019-09-29 22:03:10 +00:00
{
2020-10-29 05:48:29 +00:00
if ( i > 0 & & i < MAX_PROMPTS )
readtextprompt ( f , i - 1 ) ;
2019-09-29 22:03:10 +00:00
else
{
2020-10-29 05:48:29 +00:00
deh_warning ( " Prompt number %d out of range (1 - %d) " , i , MAX_PROMPTS ) ;
ignorelines ( f ) ;
2019-09-29 22:03:10 +00:00
}
}
2020-10-29 05:48:29 +00:00
else if ( fastcmp ( word , " FRAME " ) | | fastcmp ( word , " STATE " ) )
2019-12-18 17:37:48 +00:00
{
2020-10-29 05:48:29 +00:00
if ( i = = 0 & & word2 [ 0 ] ! = ' 0 ' ) // If word2 isn't a number
i = get_state ( word2 ) ; // find a state by name
if ( i < NUMSTATES & & i > = 0 )
readframe ( f , i ) ;
else
2019-12-18 17:37:48 +00:00
{
2020-10-29 05:48:29 +00:00
deh_warning ( " Frame %d out of range (0 - %d) " , i , NUMSTATES - 1 ) ;
ignorelines ( f ) ;
2019-12-18 17:37:48 +00:00
}
}
2020-10-29 05:48:29 +00:00
else if ( fastcmp ( word , " SOUND " ) )
2019-12-18 17:37:48 +00:00
{
2020-10-29 05:48:29 +00:00
if ( i = = 0 & & word2 [ 0 ] ! = ' 0 ' ) // If word2 isn't a number
i = get_sfx ( word2 ) ; // find a sound by name
if ( i < NUMSFX & & i > 0 )
readsound ( f , i ) ;
else
{
deh_warning ( " Sound %d out of range (1 - %d) " , i , NUMSFX - 1 ) ;
ignorelines ( f ) ;
}
2019-12-18 17:37:48 +00:00
}
2020-10-29 05:48:29 +00:00
else if ( fastcmp ( word , " HUDITEM " ) )
2019-12-18 17:37:48 +00:00
{
2020-10-29 05:48:29 +00:00
if ( i = = 0 & & word2 [ 0 ] ! = ' 0 ' ) // If word2 isn't a number
i = get_huditem ( word2 ) ; // find a huditem by name
if ( i > = 0 & & i < NUMHUDITEMS )
readhuditem ( f , i ) ;
else
2019-12-18 17:37:48 +00:00
{
2020-10-29 05:48:29 +00:00
deh_warning ( " HUD item number %d out of range (0 - %d) " , i , NUMHUDITEMS - 1 ) ;
ignorelines ( f ) ;
2019-12-18 17:37:48 +00:00
}
}
2020-10-29 05:48:29 +00:00
else if ( fastcmp ( word , " MENU " ) )
2019-12-18 17:37:48 +00:00
{
2020-10-29 05:48:29 +00:00
if ( i = = 0 & & word2 [ 0 ] ! = ' 0 ' ) // If word2 isn't a number
i = get_menutype ( word2 ) ; // find a huditem by name
if ( i > = 1 & & i < NUMMENUTYPES )
readmenu ( f , i ) ;
2016-12-29 17:02:05 +00:00
else
2014-03-15 16:59:03 +00:00
{
2020-10-29 05:48:29 +00:00
// zero-based, but let's start at 1
deh_warning ( " Menu number %d out of range (1 - %d) " , i , NUMMENUTYPES - 1 ) ;
ignorelines ( f ) ;
}
2014-03-15 16:59:03 +00:00
}
2020-10-29 05:48:29 +00:00
else if ( fastcmp ( word , " UNLOCKABLE " ) )
{
if ( ! mainfile & & ! gamedataadded )
{
deh_warning ( " You must define a custom gamedata to use \" %s \" " , word ) ;
ignorelines ( f ) ;
}
else if ( i > 0 & & i < = MAXUNLOCKABLES )
readunlockable ( f , i - 1 ) ;
else
{
deh_warning ( " Unlockable number %d out of range (1 - %d) " , i , MAXUNLOCKABLES ) ;
ignorelines ( f ) ;
}
2014-03-15 16:59:03 +00:00
}
2020-10-29 05:48:29 +00:00
else if ( fastcmp ( word , " CONDITIONSET " ) )
{
if ( ! mainfile & & ! gamedataadded )
{
deh_warning ( " You must define a custom gamedata to use \" %s \" " , word ) ;
ignorelines ( f ) ;
}
else if ( i > 0 & & i < = MAXCONDITIONSETS )
readconditionset ( f , ( UINT8 ) i ) ;
else
{
deh_warning ( " Condition set number %d out of range (1 - %d) " , i , MAXCONDITIONSETS ) ;
ignorelines ( f ) ;
}
2020-02-15 08:18:41 +00:00
}
2020-10-29 05:48:29 +00:00
else if ( fastcmp ( word , " SRB2 " ) )
2015-10-31 18:45:42 +00:00
{
2020-10-29 05:48:29 +00:00
if ( isdigit ( word2 [ 0 ] ) )
{
i = atoi ( word2 ) ;
if ( i ! = PATCHVERSION )
{
deh_warning (
" Patch is for SRB2 version %d, "
" only version %d is supported " ,
i ,
PATCHVERSION
) ;
}
}
else
{
deh_warning (
" SRB2 version definition has incorrect format, "
" use \" SRB2 %d \" " ,
PATCHVERSION
) ;
}
2020-02-09 19:11:52 +00:00
}
2020-10-29 05:48:29 +00:00
// Clear all data in certain locations (mostly for unlocks)
// Unless you REALLY want to piss people off,
// define a custom gamedata /before/ doing this!!
// (then again, modifiedgame will prevent game data saving anyway)
else if ( fastcmp ( word , " CLEAR " ) )
{
boolean clearall = ( fastcmp ( word2 , " ALL " ) ) ;
2014-03-15 16:59:03 +00:00
2020-10-29 05:48:29 +00:00
if ( ! mainfile & & ! gamedataadded )
{
deh_warning ( " You must define a custom gamedata to use \" %s \" " , word ) ;
continue ;
}
2014-03-15 16:59:03 +00:00
2020-10-29 05:48:29 +00:00
if ( clearall | | fastcmp ( word2 , " UNLOCKABLES " ) )
memset ( & unlockables , 0 , sizeof ( unlockables ) ) ;
2014-03-15 16:59:03 +00:00
2020-10-29 05:48:29 +00:00
if ( clearall | | fastcmp ( word2 , " EMBLEMS " ) )
{
memset ( & emblemlocations , 0 , sizeof ( emblemlocations ) ) ;
numemblems = 0 ;
}
2014-03-15 16:59:03 +00:00
2020-10-29 05:48:29 +00:00
if ( clearall | | fastcmp ( word2 , " EXTRAEMBLEMS " ) )
{
memset ( & extraemblems , 0 , sizeof ( extraemblems ) ) ;
numextraemblems = 0 ;
2015-01-28 15:16:50 +00:00
}
2020-10-29 05:48:29 +00:00
if ( clearall | | fastcmp ( word2 , " CONDITIONSETS " ) )
clear_conditionsets ( ) ;
if ( clearall | | fastcmp ( word2 , " LEVELS " ) )
clear_levels ( ) ;
2015-01-28 15:16:50 +00:00
}
2020-10-29 05:48:29 +00:00
else
deh_warning ( " Unknown word: %s " , word ) ;
2020-02-15 08:18:41 +00:00
}
2020-10-29 05:48:29 +00:00
else
deh_warning ( " missing argument for '%s' " , word ) ;
2020-02-15 08:18:41 +00:00
}
2020-10-29 05:48:29 +00:00
else
deh_warning ( " No word in this line: %s " , s ) ;
} // end while
2014-03-15 16:59:03 +00:00
2020-10-29 05:48:29 +00:00
if ( gamedataadded )
G_LoadGameData ( ) ;
if ( gamestate = = GS_TITLESCREEN )
2014-03-15 16:59:03 +00:00
{
2020-10-29 05:48:29 +00:00
if ( introchanged )
2014-03-15 16:59:03 +00:00
{
2020-10-29 05:48:29 +00:00
menuactive = false ;
I_UpdateMouseGrab ( ) ;
COM_BufAddText ( " playintro " ) ;
}
else if ( titlechanged )
{
menuactive = false ;
I_UpdateMouseGrab ( ) ;
COM_BufAddText ( " exitgame " ) ; // Command_ExitGame_f() but delayed
2014-03-15 16:59:03 +00:00
}
}
2020-10-29 05:48:29 +00:00
dbg_line = - 1 ;
if ( deh_num_warning )
2020-06-06 12:50:58 +00:00
{
2020-10-29 05:48:29 +00:00
CONS_Printf ( M_GetText ( " %d warning%s in the SOC lump \n " ) , deh_num_warning , deh_num_warning = = 1 ? " " : " s " ) ;
if ( devparm ) {
I_Error ( " %s%s " , va ( M_GetText ( " %d warning%s in the SOC lump \n " ) , deh_num_warning , deh_num_warning = = 1 ? " " : " s " ) , M_GetText ( " See log.txt for details. \n " ) ) ;
//while (!I_GetKey())
//I_OsPolling();
2014-03-15 16:59:03 +00:00
}
2020-10-29 05:48:29 +00:00
}
2014-03-15 16:59:03 +00:00
2020-10-29 05:48:29 +00:00
deh_loaded = true ;
Z_Free ( s ) ;
2014-03-15 16:59:03 +00:00
}
2020-10-29 05:48:29 +00:00
// read dehacked lump in a wad (there is special trick for for deh
// file that are converted to wad in w_wad.c)
void DEH_LoadDehackedLumpPwad ( UINT16 wad , UINT16 lump , boolean mainfile )
2014-03-15 16:59:03 +00:00
{
2020-10-29 05:48:29 +00:00
MYFILE f ;
f . wad = wad ;
f . size = W_LumpLengthPwad ( wad , lump ) ;
f . data = Z_Malloc ( f . size + 1 , PU_STATIC , NULL ) ;
W_ReadLumpPwad ( wad , lump , f . data ) ;
f . curpos = f . data ;
f . data [ f . size ] = 0 ;
DEH_LoadDehackedFile ( & f , mainfile ) ;
Z_Free ( f . data ) ;
2014-03-15 16:59:03 +00:00
}
2020-10-29 05:48:29 +00:00
void DEH_LoadDehackedLump ( lumpnum_t lumpnum )
2017-05-17 19:36:40 +00:00
{
2020-10-29 05:48:29 +00:00
DEH_LoadDehackedLumpPwad ( WADFILENUM ( lumpnum ) , LUMPNUM ( lumpnum ) , false ) ;
2017-05-17 19:36:40 +00:00
}
2020-10-29 05:48:29 +00:00
void DEH_Check ( void )
2014-03-15 16:59:03 +00:00
{
2020-10-29 05:48:29 +00:00
# if defined(_DEBUG) || defined(PARANOIA)
const size_t dehstates = sizeof ( STATE_LIST ) / sizeof ( const char * ) ;
const size_t dehmobjs = sizeof ( MOBJTYPE_LIST ) / sizeof ( const char * ) ;
const size_t dehpowers = sizeof ( POWERS_LIST ) / sizeof ( const char * ) ;
const size_t dehcolors = sizeof ( COLOR_ENUMS ) / sizeof ( const char * ) ;
2017-05-17 19:36:40 +00:00
2020-10-29 05:48:29 +00:00
if ( dehstates ! = S_FIRSTFREESLOT )
I_Error ( " You forgot to update the Dehacked states list, you dolt! \n (%d states defined, versus %s in the Dehacked list) \n " , S_FIRSTFREESLOT , sizeu1 ( dehstates ) ) ;
2017-05-17 19:36:40 +00:00
2020-10-29 05:48:29 +00:00
if ( dehmobjs ! = MT_FIRSTFREESLOT )
I_Error ( " You forgot to update the Dehacked mobjtype list, you dolt! \n (%d mobj types defined, versus %s in the Dehacked list) \n " , MT_FIRSTFREESLOT , sizeu1 ( dehmobjs ) ) ;
2014-03-15 16:59:03 +00:00
2020-10-29 05:48:29 +00:00
if ( dehpowers ! = NUMPOWERS )
I_Error ( " You forgot to update the Dehacked powers list, you dolt! \n (%d powers defined, versus %s in the Dehacked list) \n " , NUMPOWERS , sizeu1 ( dehpowers ) ) ;
2014-03-15 16:59:03 +00:00
2020-10-29 05:48:29 +00:00
if ( dehcolors ! = SKINCOLOR_FIRSTFREESLOT )
I_Error ( " You forgot to update the Dehacked colors list, you dolt! \n (%d colors defined, versus %s in the Dehacked list) \n " , SKINCOLOR_FIRSTFREESLOT , sizeu1 ( dehcolors ) ) ;
# endif
2014-03-15 16:59:03 +00:00
}