1 //-------------------------------------------------------------------------
2 /*
3 Copyright (C) 1997, 2005 - 3D Realms Entertainment
4
5 This file is part of Shadow Warrior version 1.2
6
7 Shadow Warrior is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
16 See the GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22 Original Source: 1997 - Frank Maddin and Jim Norwood
23 Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms
24 */
25 //-------------------------------------------------------------------------
26
27 // CONSOLE.C
28 // Handles all argument storing and user console variable modifications.
29 // Copyright (c) 1996 by Jim Norwood
30
31 #include "build.h"
32
33 #include "mytypes.h"
34 #include "keys.h"
35 #include "names2.h"
36 #include "panel.h"
37 #include "game.h"
38 #include "tags.h"
39 #include "player.h"
40 #include "lists.h"
41 #include "warp.h"
42 #include "quake.h"
43
44 #include "mathutil.h"
45 #include "function.h"
46 #include "control.h"
47 #include "trigger.h"
48
49 #include "menus.h"
50 #include "net.h"
51 #include "pal.h"
52
53 #include "weapon.h"
54 #include "text.h"
55 #include "jsector.h"
56
57 // DEFINES ///////////////////////////////////////////////////////////////////////////////////
58 #define MAX_USER_ARGS 100
59 #define MAX_CONSOLE_COMMANDS 100
60 #define MAX_HISTORY 20
61
62 BOOL SpriteInfo = FALSE;
63 extern BOOL QuitFlag;
64
65 // FUNCTION PROTOTYPES ///////////////////////////////////////////////////////////////////////
66 void CON_ProcessOptions( void );
67 void CON_ClearConsole( void );
68 BYTE CON_CommandCmp(const char *str1, const char *str2, int len);
69 void CheatInput(void);
70
71 // Modify actor routines
72 void CON_ModXrepeat( void );
73 void CON_ModYrepeat( void );
74 void CON_ModTranslucent( void );
75 void CON_GetHelp( void );
76 void CON_Sound( void );
77 void CON_Reverb( void );
78 void CON_Heap( void );
79 void CON_Cache( void );
80 void CON_SoundTest( void );
81 void CON_SpriteInfo( void );
82 void CON_KillSprite( void );
83 void CON_SpriteDetail( void );
84 void CON_UserDetail( void );
85 void CON_Quit( void );
86 void CON_LoadSetup( void );
87 void CON_DamageData( void );
88 void CON_WinPachinko( void );
89 void CON_Tweak( void );
90 void CON_Bunny( void );
91 void CON_CheckHeap( void );
92 void CON_DumpHeap( void );
93 void CON_ShowMirror( void );
94 void CON_MultiNameChange( void );
95 void CON_DumpSoundList( void );
96
97 // STRUCTURES ////////////////////////////////////////////////////////////////////////////////
98
99 typedef struct
100 {
101 const char *command; // Text string representing the command that calls this function
102 void (*function)(void); // Function assigned to the command, take no parameters
103
104 } CON_COMMAND, *CON_COMMANDp;
105
106 // Contains any commands that don't get added by particular setup functions
107 CON_COMMAND pre_commands[] = {
108 #if DEBUG
109 {"bobbing", CON_ProcessOptions},
110 {"swnext", CheatInput},
111 {"swprev", CheatInput},
112 {"swsecret", CheatInput},
113 {"swstart", CheatInput},
114 {"swres", CheatInput},
115 {"swloc", CheatInput},
116 {"swroom", CheatInput},
117 {"swmap", CheatInput},
118 {"swvox", CheatInput},
119 {"swsave", CheatInput},
120 #endif
121 #if DEBUG
122 {"george", CheatInput},
123 {"blackburn", CheatInput},
124 {"reverb", CON_Reverb},
125 {"mem", CON_Heap},
126 {"cache", CON_Cache},
127 {"xrepeat", CON_ModXrepeat},
128 {"yrepeat", CON_ModYrepeat},
129 {"translucent", CON_ModTranslucent},
130 {"spriteinfo", CON_SpriteInfo},
131 {"kill", CON_KillSprite},
132 {"showsprite", CON_SpriteDetail},
133 {"showuser", CON_UserDetail},
134 {"damage", CON_DamageData},
135 {"tweak", CON_Tweak},
136 {"checkheap", CON_CheckHeap},
137 {"dumpheap", CON_DumpHeap},
138 {"showmirror", CON_ShowMirror},
139 {"clear", CON_ClearConsole},
140 {"dumpsounds", CON_DumpSoundList},
141 {"help", CON_GetHelp},
142 //{"quit", CON_Quit},
143 #endif
144 {"swchan", CheatInput},
145 {"swgimme", CheatInput},
146 {"swtrek##", CheatInput},
147 {"swgreed", CheatInput},
148 {"swghost", CheatInput},
149 {"swstart", CheatInput},
150 {"swres", CheatInput},
151 {"swloc", CheatInput},
152 {"swmap", CheatInput},
153 {"swsave", CheatInput},
154 {"sound", CON_SoundTest},
155 {"winpachinko", CON_WinPachinko},
156 {"config", CON_LoadSetup},
157 {"swtrix", CON_Bunny},
158 {"swname", CON_MultiNameChange},
159 {NULL, NULL}
160 };
161
162
163 // GLOBALS ///////////////////////////////////////////////////////////////////////////////////
164
165 CON_COMMAND commandlist[MAX_CONSOLE_COMMANDS]; // Console command array
166 CON_COMMANDp commandptr; // Pointer to a command
167
168 SHORT numcommands=0; // Total number of commands in the command list
169
170 char command_history[MAX_HISTORY][256]; // History of what has been typed in lately
171 SHORT curr_history=0; // Line currently being pointed to in the history array
172 SHORT numhistory=0;
173
174 // Array which stores all the user arguments passed into the game.
175 static char user_args[MAX_USER_ARGS][256];
176 static BYTE con_argnum=0; // Total number of arguments that were passed into the game
177
178 char con_message[80]; // Holds the current console message to send to adduserquote
179
180 // FUNCTIONS /////////////////////////////////////////////////////////////////////////////////
181
182
183 //
184 // Frank's neato input string checker, useful for my stuff too.
185 //
CON_CommandCmp(const char * str1,const char * str2,int len)186 BYTE CON_CommandCmp(const char *str1, const char *str2, int len)
187 {
188 const char *cp1 = str1;
189 const char *cp2 = str2;
190
191 do
192 {
193 if (*cp1 != *cp2)
194 {
195 if (*cp1 != '#' && *cp2 != '#')
196 return(FALSE);
197 else
198 if ( (*cp1 == '#' && !isdigit(*cp2)) || (*cp2 == '#' && !isdigit(*cp1)) )
199 return(FALSE);
200 }
201
202 cp1++;
203 cp2++;
204 }
205 while (--len);
206
207 return(TRUE);
208 }
209
IsCommand(char * str)210 BOOL IsCommand(char *str)
211 {
212 int i;
213 char first[512];
214
215 sscanf(str,"%s",first);
216
217 for (i = 0; i < numcommands; i++)
218 {
219 // Don't even try if they aren't the same length
220 if(strlen(first) != strlen(commandlist[i].command))
221 continue;
222
223 // See if it's in there
224 if (CON_CommandCmp(first, commandlist[i].command, strlen(first)))
225 {
226 return(TRUE);
227 }
228 }
229
230 return(FALSE);
231 }
232
233 //
234 // Sends a message to the user quote array
235 //
236
CON_Message(const char * message,...)237 void CON_Message(const char *message, ...)
238 {
239 va_list argptr;
240
241 va_start (argptr,message);
242 vsprintf (&con_message[0],message,argptr);
243 va_end (argptr);
244
245 // Send message to user quote array for immediate display
246 adduserquote(&con_message[0]);
247 }
248
249 //
250 // Sends a message to the console quote array
251 //
252
CON_ConMessage(const char * message,...)253 void CON_ConMessage(const char *message, ...)
254 {
255 va_list argptr;
256
257 va_start (argptr,message);
258 vsprintf (&con_message[0],message,argptr);
259 va_end (argptr);
260
261 // Send message to user quote array for immediate display
262 addconquote(&con_message[0]);
263 }
264
265 //
266 // Stores user arguments passed in on the command line for later inspection
267 //
CON_StoreArg(const char * userarg)268 void CON_StoreArg(const char *userarg)
269 {
270 if(con_argnum < MAX_USER_ARGS)
271 {
272 strcpy(&user_args[con_argnum][0],userarg);
273 Bstrlwr(&user_args[con_argnum][0]);
274 con_argnum++;
275 }
276 }
277
278 //
279 // Checkes the user command array to see if user did in fact pass in a particular argument
280 //
CON_CheckParm(const char * userarg)281 BOOL CON_CheckParm(const char *userarg)
282 {
283 SHORT i;
284
285 for(i=0;i<con_argnum;i++)
286 {
287 if(!strcmp(&user_args[i][0],userarg))
288 return(TRUE); // Yep, it's in there
289 }
290
291 return(FALSE); // Not a parameter that was passed in
292 }
293
294 //
295 // Scrolls up and down through previous user commands like DosKey
296 // Copies the history text string into the MessageInputCommand
297 //
CON_CommandHistory(signed char dir)298 void CON_CommandHistory(signed char dir)
299 {
300 if(curr_history + dir < numhistory)
301 curr_history += dir;
302 if(curr_history < 0) curr_history = 0;
303 if(curr_history > MAX_HISTORY) curr_history = MAX_HISTORY;
304
305 strcpy(MessageInputString, command_history[curr_history]);
306 }
307
CON_AddHistory(const char * commandstr)308 void CON_AddHistory(const char *commandstr)
309 {
310 int i;
311
312 for(i=MAX_HISTORY-1;i>=0;i--)
313 {
314 strcpy(command_history[i],command_history[i-1]);
315 }
316 strcpy(command_history[0],commandstr);
317 if((++numhistory) > MAX_HISTORY) numhistory = MAX_HISTORY;
318 }
319
320
321 //
322 // Adds a command name to the command list and assigns the appropriate function pointer
323 //
CON_AddCommand(const char * command,void (* function)(void))324 BOOL CON_AddCommand(const char *command, void (*function)(void))
325 {
326 if(command != NULL && function != NULL && numcommands < MAX_CONSOLE_COMMANDS)
327 {
328 // strcpy(commandlist[numcommands].command, command);
329 commandlist[numcommands].command = command;
330 commandlist[numcommands].function = function;
331
332 // Increment counter to set up for next command insertion
333 numcommands++;
334
335 ASSERT(numcommands <= MAX_CONSOLE_COMMANDS);
336
337 return(TRUE);
338 }
339
340 return(FALSE);
341 }
342
343 //
344 // Process commands
345 // Returns TRUE upon success
346 //
CON_ProcessUserCommand(void)347 void CON_ProcessUserCommand( void )
348 {
349 SHORT i=0;
350 char temp_message[256],command_str[256];
351
352 strcpy(temp_message,MessageInputString);
353 sscanf(Bstrlwr(temp_message),"%s", command_str); // Get the base command type
354
355 for (i = 0; i < numcommands; i++)
356 {
357 // Don't even try if they aren't the same length
358 if(strlen(command_str) != strlen(commandlist[i].command)) continue;
359 // See if it's in there
360 if(CON_CommandCmp(command_str, commandlist[i].command, strlen(command_str)))
361 {
362 if (commandlist[i].function)
363 {
364 (*commandlist[i].function)();
365 CON_AddHistory(MessageInputString); // Keep history only of valid input
366 return;
367 }
368 }
369 }
370
371 if(ConPanel)
372 CON_ConMessage("Syntax Error or Command not enabled!");
373 }
374
375 //
376 // Initialize the console command list with the pre_command startup array
377 //
CON_InitConsole(void)378 void CON_InitConsole( void )
379 {
380 CON_COMMANDp i;
381
382 for (i = &pre_commands[0]; i->command != NULL; i++)
383 {
384 if(!CON_AddCommand(i->command, i->function))
385 {
386 printf("CON_InitConsole: Failed to add command contained in pre_commands list.\n");
387 TerminateGame();
388 exit(0);
389 }
390 }
391
392 //printf("CON_InitConsole: Command list initialized.\n");
393 }
394
395 //
396 // Process as a command, anything that could be set in the options menu as well
397 //
CON_ProcessOptions(void)398 void CON_ProcessOptions( void )
399 {
400
401 }
402
403 // Clear the console screen
CON_ClearConsole(void)404 void CON_ClearConsole( void )
405 {
406 short i;
407
408 for(i=0; i<MAXCONQUOTES; i++)
409 strcpy(con_quote[i],"\0");
410 }
411
412 /////////////////////////////////////////////////////////////////////////////////////////////
413 // The user console programming function library ////////////////////////////////////////////
414 /////////////////////////////////////////////////////////////////////////////////////////////
415
CheckValidSprite(short SpriteNum)416 BOOL CheckValidSprite(short SpriteNum)
417 {
418 if(SpriteNum < 0 || SpriteNum > 6144)
419 {
420 CON_ConMessage("ERROR: Sprite %d is out of range.",SpriteNum);
421 return(FALSE);
422 }
423 return(TRUE);
424 }
425
426 // Get help on a console command
CON_GetHelp(void)427 void CON_GetHelp( void )
428 {
429 char base[80], command[80];
430 short i;
431
432
433 if (sscanf(MessageInputString,"%s %s",base,command) < 2)
434 {
435 CON_ConMessage("Usage: help [keyword]");
436 return;
437 }
438
439 Bstrlwr(command); // Make sure operator is all lower case
440
441 if(!strcmp(command, "xrepeat"))
442 {
443 CON_ConMessage("Usage: xrepeat [repeat value 0-255],");
444 CON_ConMessage(" [User ID (-1 for all ID's)], [SpriteNum (-1 for all of type ID)]");
445 return;
446 }else
447 if(!strcmp(command, "yrepeat"))
448 {
449 CON_ConMessage("Usage: yrepeat [repeat value 0-255],");
450 CON_ConMessage(" [User ID (-1 for all ID's)], [SpriteNum (-1 for all of type ID)]");
451 return;
452 }else
453 if(!strcmp(command, "translucent"))
454 {
455 CON_ConMessage("Usage: translucent [OFF/ON 0-1],");
456 CON_ConMessage(" [User ID (-1 for all ID's)], [SpriteNum (-1 for all of type ID)]");
457 return;
458 }else
459 {
460 CON_ConMessage("No help was located on that subject.");
461 }
462 }
463
464 // Modify sprites xrepeat value
CON_ModXrepeat(void)465 void CON_ModXrepeat( void )
466 {
467 char base[80];
468 SHORT op1=64,op2=-1,op3=-1;
469 short i;
470
471
472 if (sscanf(MessageInputString,"%s %hd %hd %hd",base,&op1,&op2,&op3) < 4)
473 {
474 strcpy(MessageInputString,"help xrepeat");
475 CON_GetHelp();
476 return;
477 }
478
479 if (op3 == -1)
480 {
481 for(i=0; i<MAXSPRITES; i++)
482 {
483 SPRITEp sp = &sprite[i];
484 USERp u = User[i];
485
486 if(op2 == -1)
487 sp->xrepeat = op1;
488 else
489 {
490 if(u->ID == op2)
491 sp->xrepeat = op1;
492 }
493 }
494 if(op2 == -1)
495 CON_ConMessage("Xrepeat set to %d for all u->ID's for all sprites.",op1);
496 else
497 CON_ConMessage("Xrepeat set to %d for u->ID = %d for all sprites.",op1,op2);
498 } else
499 {
500 // Do it only for one sprite
501 SPRITEp sp = &sprite[op3];
502 USERp u = User[op3];
503
504 if(!CheckValidSprite(op3)) return;
505
506 sp->xrepeat = op1;
507 CON_ConMessage("Xrepeat set to %d for sprite %d.",op1,op3);
508 }
509 }
510
511 // Modify sprites yrepeat value
CON_ModYrepeat(void)512 void CON_ModYrepeat( void )
513 {
514 char base[80];
515 SHORT op1=64,op2=-1,op3=-1;
516 short i;
517
518
519 if (sscanf(MessageInputString,"%s %hd %hd %hd",base,&op1,&op2,&op3) < 4)
520 {
521 strcpy(MessageInputString,"help yrepeat");
522 CON_GetHelp();
523 return;
524 }
525
526
527 if (op3 == -1)
528 {
529 for(i=0; i<MAXSPRITES; i++)
530 {
531 SPRITEp sp = &sprite[i];
532 USERp u = User[i];
533
534 if(op2 == -1)
535 sp->yrepeat = op1;
536 else
537 {
538 if(u->ID == op2)
539 sp->yrepeat = op1;
540 }
541 }
542 if(op2 == -1)
543 CON_ConMessage("Yrepeat set to %d for all u->ID's for all sprites.",op1);
544 else
545 CON_ConMessage("Yrepeat set to %d for u->ID = %d for all sprites.",op1,op2);
546 } else
547 {
548 // Do it only for one sprite
549 SPRITEp sp = &sprite[op3];
550 USERp u = User[op3];
551
552 if(!CheckValidSprite(op3)) return;
553
554 sp->yrepeat = op1;
555 CON_ConMessage("Yrepeat set to %d for sprite %d.",op1,op3);
556 }
557 }
558
CON_ModTranslucent(void)559 void CON_ModTranslucent( void )
560 {
561 char base[80];
562 SHORT op1=0;
563 SPRITEp sp;
564 USERp u;
565
566 // Format: translucent [SpriteNum]
567 if (sscanf(MessageInputString,"%s %hd",base,&op1) < 2)
568 {
569 strcpy(MessageInputString,"help translucent");
570 CON_GetHelp();
571 return;
572 }
573
574 if(!CheckValidSprite(op1)) return;
575
576 sp = &sprite[op1];
577 u = User[op1];
578
579 if(TEST(sp->cstat,CSTAT_SPRITE_TRANSLUCENT))
580 {
581 RESET(sp->cstat,CSTAT_SPRITE_TRANSLUCENT);
582 CON_ConMessage("Translucence RESET for sprite %d.",op1);
583 } else
584 {
585 SET(sp->cstat,CSTAT_SPRITE_TRANSLUCENT);
586 CON_ConMessage("Translucence SET for sprite %d.",op1);
587 }
588 }
589
CON_SoundTest(void)590 void CON_SoundTest( void )
591 {
592 int handle;
593 int zero=0;
594 char base[80];
595 SHORT op1=0;
596
597 // Format: sound [number]
598 if (sscanf(MessageInputString,"%s %hd",base,&op1) < 2)
599 {
600 strcpy(MessageInputString,"help sound");
601 CON_GetHelp();
602 return;
603 }
604
605 if(op1 < 0 || op1 >= DIGI_MAX)
606 {
607 CON_ConMessage("Sound number out of range.");
608 return;
609 }
610
611 handle = PlaySound(op1,&zero,&zero,&zero,v3df_none);
612 }
613
614
CON_Reverb(void)615 void CON_Reverb( void )
616 {
617 char base[80];
618 SHORT op1=0;
619 PLAYERp pp = Player + screenpeek;
620
621 // Format: reverb [number]
622 if (sscanf(MessageInputString,"%s %hd",base,&op1) < 2)
623 {
624 strcpy(MessageInputString,"help reverb");
625 CON_GetHelp();
626 return;
627 }
628
629 CON_ConMessage("Reverb is now set to %d.",op1);
630 COVER_SetReverb(op1);
631 pp->Reverb = op1;
632 }
633
CON_Heap(void)634 void CON_Heap( void )
635 {
636 /*
637 int totalmemory=0;
638 extern int TotalMemory, ActualHeap;
639 int i;
640 void *testheap;
641
642 totalmemory = Z_AvailHeap();
643 CON_ConMessage("Total heap at game startup = %d", TotalMemory);
644 CON_ConMessage("ActualHeap reserved for non-cache use = %d", ActualHeap);
645 CON_ConMessage("Total unallocated blocks in bytes minus reserved heap = %d", totalmemory);
646 CON_ConMessage("NOTE: Allocation exceeding ActualHeap will result in out of memory");
647 // Find remaining heap space unused
648 i = ActualHeap;
649 while(i>0)
650 {
651 testheap = AllocMem(i);
652 if(!testheap)
653 i-=1024L; // Decrease in 1k increments
654 else
655 {
656 CON_ConMessage("Heap test result (+ or - 1k):");
657 CON_ConMessage("=============================");
658 CON_ConMessage("Unallocated heap space remaining = %d",i);
659 CON_ConMessage("Unallocated heap space used = %d",ActualHeap - i);
660 FreeMem(testheap);
661 i=0; // Beam us out of here Scotty!
662 }
663 }
664
665 if(ActualHeap < 50000L)
666 {
667 CON_ConMessage("ALERT: Memory is critically low!");
668 }
669 */
670 }
671
TileRangeMem(int start)672 int TileRangeMem(int start)
673 {
674 int i;
675 int total=0;
676
677 switch(start)
678 {
679 case 4096: // Evil Ninja
680 for(i=4096; i<=4239; i++)
681 total += tilesizx[i]*tilesizy[i];
682 break;
683 case 800: // Hornet
684 for(i=800; i<=811; i++)
685 total += tilesizx[i]*tilesizy[i];
686 break;
687 case 817:
688 for(i=817; i<=819; i++) // Bouncing Betty
689 total += tilesizx[i]*tilesizy[i];
690 break;
691 case 820: // Skull
692 for(i=820; i<=854; i++)
693 total += tilesizx[i]*tilesizy[i];
694 break;
695 case 960:
696 for(i=960; i<=1016; i++) // Serpent God
697 total += tilesizx[i]*tilesizy[i];
698 for(i=1300; i<=1314; i++)
699 total += tilesizx[i]*tilesizy[i];
700 break;
701 case 1024:
702 for(i=1024; i<=1175; i++) // LoWang
703 total += tilesizx[i]*tilesizy[i];
704 break;
705 case 1320:
706 for(i=1320; i<=1396; i++) // Skeletor Priest
707 total += tilesizx[i]*tilesizy[i];
708 break;
709 case 1400:
710 for(i=1400; i<=1440; i++) // Coolie
711 total += tilesizx[i]*tilesizy[i];
712 for(i=4260; i<=4266; i++)
713 total += tilesizx[i]*tilesizy[i];
714 break;
715 case 1441:
716 for(i=1441; i<=1450; i++) // Coolie Ghost
717 total += tilesizx[i]*tilesizy[i];
718 for(i=4267; i<=4312; i++)
719 total += tilesizx[i]*tilesizy[i];
720 break;
721 case 1469:
722 for(i=1469; i<=1497; i++) // Guardian
723 total += tilesizx[i]*tilesizy[i];
724 for(i=1504; i<=1518; i++)
725 total += tilesizx[i]*tilesizy[i];
726 break;
727 case 1580:
728 for(i=1580; i<=1644; i++) // Little Ripper
729 total += tilesizx[i]*tilesizy[i];
730 break;
731 case 4320:
732 for(i=4320; i<=4427; i++) // Big Ripper
733 total += tilesizx[i]*tilesizy[i];
734 break;
735 case 2540:
736 for(i=2540; i<=2546; i++) // Trashcan
737 total += tilesizx[i]*tilesizy[i];
738 break;
739 case 4430:
740 for(i=4430; i<=4479; i++) // Fish
741 total += tilesizx[i]*tilesizy[i];
742 break;
743 case 4490:
744 for(i=4490; i<=4544; i++) // Sumo
745 total += tilesizx[i]*tilesizy[i];
746 break;
747 case 5023:
748 for(i=5023; i<=5026; i++) // Toilet Girl
749 total += tilesizx[i]*tilesizy[i];
750 break;
751 case 5032:
752 for(i=5032; i<=5035; i++) // Wash Girl
753 total += tilesizx[i]*tilesizy[i];
754 break;
755 case 2000:
756 for(i=2000; i<=2002; i++) // Chop Stick Panel
757 total += tilesizx[i]*tilesizy[i];
758 break;
759 case 2004:
760 for(i=2004; i<=2009; i++) // Uzi Panel
761 total += tilesizx[i]*tilesizy[i];
762 for(i=2040; i<=2043; i++) // Uzi Overlays
763 total += tilesizx[i]*tilesizy[i];
764 break;
765 case 2010:
766 for(i=2010; i<=2019; i++) // Rail Panel
767 total += tilesizx[i]*tilesizy[i];
768 break;
769 case 2130:
770 for(i=2130; i<=2137; i++) // Shuriken Panel
771 total += tilesizx[i]*tilesizy[i];
772 break;
773 case 2050:
774 for(i=2050; i<=2053; i++) // Heart Panel
775 total += tilesizx[i]*tilesizy[i];
776 break;
777 case 2054:
778 for(i=2054; i<=2057; i++) // HotHead Panel
779 total += tilesizx[i]*tilesizy[i];
780 break;
781 case 2070:
782 for(i=2070; i<=2077; i++) // Rocket Launcher Panel
783 total += tilesizx[i]*tilesizy[i];
784 break;
785 case 2080:
786 for(i=2080; i<=2083; i++) // Sword Panel
787 total += tilesizx[i]*tilesizy[i];
788 break;
789 case 4090:
790 for(i=4090; i<=4093; i++) // Bloody Sword Panel
791 total += tilesizx[i]*tilesizy[i];
792 break;
793 case 2121:
794 for(i=2121; i<=2126; i++) // 40MM Panel
795 total += tilesizx[i]*tilesizy[i];
796 break;
797 case 2211:
798 for(i=2211; i<=2216; i++) // Shotgun Panel
799 total += tilesizx[i]*tilesizy[i];
800 for(i=2225; i<=2227; i++) // Shotgun Quad-Mode Panel
801 total += tilesizx[i]*tilesizy[i];
802 break;
803 case 2220:
804 for(i=2220; i<=2224; i++) // Sticky Bomb Panel
805 total += tilesizx[i]*tilesizy[i];
806 break;
807 }
808
809 return(total);
810 }
811
CON_Cache(void)812 void CON_Cache( void )
813 {
814 char incache[8192]; // 8192 so it can index maxwalls as well
815 int i,j,tottiles,totsprites,totactors;
816
817
818 memset(incache,0,8192);
819
820 // Calculate all level tiles, non-actor stuff
821 for(i=0;i<numsectors;i++)
822 {
823 incache[sector[i].ceilingpicnum] = 1;
824 incache[sector[i].floorpicnum] = 1;
825 }
826
827 for(i=0;i<numwalls;i++)
828 {
829 incache[wall[i].picnum] = 1;
830 if (wall[i].overpicnum >= 0)
831 incache[wall[i].overpicnum] = 1;
832 }
833
834 tottiles = 0;
835 for(i=0;i<8192;i++)
836 if (incache[i] > 0)
837 tottiles += tilesizx[i]*tilesizy[i];
838
839 //////////////////////////////////////////////
840
841 memset(incache,0,8192);
842
843 // Sprites on the stat list get counted as cached, others don't
844 for(i=0;i<MAXSPRITES;i++)
845 if (sprite[i].statnum < MAXSTATUS)
846 incache[sprite[i].picnum] = 1;
847
848 totsprites = 0;
849 totactors = 0;
850
851 for(i=0;i<MAXSPRITES;i++)
852 {
853 if (incache[i] > 0)
854 {
855 switch(i)
856 {
857 case 4096:
858 totactors+=TileRangeMem(4096);
859 incache[4096]=0;
860 break;
861 case 800:
862 totactors+=TileRangeMem(800);
863 incache[800]=0;
864 break;
865 case 817:
866 totactors+=TileRangeMem(817);
867 incache[817]=0;
868 break;
869 case 820:
870 totactors+=TileRangeMem(820);
871 incache[820]=0;
872 break;
873 case 960:
874 totactors+=TileRangeMem(960);
875 incache[960]=0;
876 break;
877 //case 1024: // Lo Wang is calculated later
878 // totactors+=TileRangeMem(1024);
879 // incache[1024]=0;
880 //break;
881 case 1320:
882 totactors+=TileRangeMem(1320);
883 incache[1320]=0;
884 break;
885 case 1400:
886 totactors+=TileRangeMem(1400);
887 incache[1400]=0;
888 break;
889 case 1441:
890 totactors+=TileRangeMem(1441);
891 incache[1441]=0;
892 break;
893 case 1469:
894 totactors+=TileRangeMem(1469);
895 incache[1469]=0;
896 break;
897 case 1580:
898 totactors+=TileRangeMem(1580);
899 incache[1580]=0;
900 break;
901 case 4320:
902 totactors+=TileRangeMem(4320);
903 incache[4320]=0;
904 break;
905 case 2540:
906 totactors+=TileRangeMem(2540);
907 incache[2540]=0;
908 break;
909 case 4430:
910 totactors+=TileRangeMem(4430);
911 incache[4430]=0;
912 break;
913 case 4490:
914 totactors+=TileRangeMem(4490);
915 incache[4490]=0;
916 break;
917 case 5023:
918 totactors+=TileRangeMem(5023);
919 incache[5023]=0;
920 break;
921 case 5032:
922 totactors+=TileRangeMem(5032);
923 incache[5032]=0;
924 break;
925 case 2000:
926 totactors+=TileRangeMem(2000);
927 incache[2000]=0;
928 break;
929 case 2004:
930 totactors+=TileRangeMem(2004);
931 incache[2004]=0;
932 break;
933 case 2010:
934 totactors+=TileRangeMem(2010);
935 incache[2010]=0;
936 break;
937 case 2130:
938 totactors+=TileRangeMem(2130);
939 incache[2130]=0;
940 break;
941 case 2050:
942 totactors+=TileRangeMem(2050);
943 incache[2050]=0;
944 break;
945 case 2054:
946 totactors+=TileRangeMem(2054);
947 incache[2054]=0;
948 break;
949 case 2070:
950 totactors+=TileRangeMem(2070);
951 incache[2070]=0;
952 break;
953 case 2080:
954 totactors+=TileRangeMem(2080);
955 incache[2080]=0;
956 break;
957 case 4090:
958 totactors+=TileRangeMem(4090);
959 incache[4090]=0;
960 break;
961 case 2121:
962 totactors+=TileRangeMem(2121);
963 incache[2121]=0;
964 break;
965 case 2211:
966 totactors+=TileRangeMem(2211);
967 incache[2211]=0;
968 break;
969 case 2220:
970 totactors+=TileRangeMem(2220);
971 incache[2220]=0;
972 break;
973
974 default: totsprites += tilesizx[i]*tilesizy[i];
975 }
976 }
977 }
978
979 CON_ConMessage("/////////////////////////////////////////////");
980 CON_ConMessage("Current Memory Consumption:");
981 CON_ConMessage("Total Tiles = %d",tottiles);
982 CON_ConMessage("Total Sprites = %d",totsprites);
983 CON_ConMessage("Total Actors = %d",totactors);
984 CON_ConMessage("Total Memory = %d",(tottiles+totsprites+totactors));
985 CON_ConMessage("Total with LoWang = %d",(tottiles+totsprites+totactors+TileRangeMem(1024)));
986 CON_ConMessage("/////////////////////////////////////////////");
987
988 }
989
CON_SpriteInfo(void)990 void CON_SpriteInfo( void )
991 {
992 SpriteInfo++;
993 if(SpriteInfo > 2) SpriteInfo = 0;
994
995 if(SpriteInfo == 0)
996 CON_ConMessage("Sprite information is OFF.");
997 else
998 if(SpriteInfo == 1)
999 CON_ConMessage("Sprite information is ON (Brief Mode).");
1000 else
1001 CON_ConMessage("Sprite information is ON (Verbose Mode).");
1002 }
1003
CON_KillSprite(void)1004 void CON_KillSprite( void )
1005 {
1006 char base[80];
1007 SHORT op1=0;
1008 SPRITEp sp;
1009 short i;
1010 USERp u;
1011
1012 // Format: kill [SpriteNum]
1013 if (sscanf(MessageInputString,"%s %hd",base,&op1) < 2)
1014 {
1015 strcpy(MessageInputString,"help kill");
1016 CON_GetHelp();
1017 return;
1018 }
1019
1020 if(op1 == -1)
1021 {
1022 for(i=0; i<MAXSPRITES; i++)
1023 {
1024 u = User[i];
1025 if(!u->PlayerP)
1026 SetSuicide(i);
1027 }
1028 CON_ConMessage("Killed all sprites except Players.");
1029 } else
1030 {
1031 if(!CheckValidSprite(op1)) return;
1032
1033 SetSuicide(op1);
1034 CON_ConMessage("Killed sprite %d.",op1);
1035 }
1036
1037 }
1038
CON_SpriteDetail(void)1039 void CON_SpriteDetail( void )
1040 {
1041 char base[80];
1042 SHORT op1=0;
1043 SPRITEp sp;
1044 short i;
1045
1046 // Format: showsprite [SpriteNum]
1047 if (sscanf(MessageInputString,"%s %hd",base,&op1) < 2)
1048 {
1049 strcpy(MessageInputString,"help showsprite");
1050 CON_GetHelp();
1051 return;
1052 }
1053
1054 if(!CheckValidSprite(op1)) return;
1055 sp = &sprite[op1];
1056
1057 CON_ConMessage("x = %d, y = %d, z = %d",sp->x,sp->y,sp->z);
1058 CON_ConMessage("cstat = %d, picnum = %d",sp->cstat,sp->picnum);
1059 CON_ConMessage("shade = %d, pal = %d, clipdist = %d",sp->shade,sp->pal,sp->clipdist);
1060 CON_ConMessage("xrepeat = %d, yrepeat = %d",sp->xrepeat, sp->yrepeat);
1061 CON_ConMessage("xoffset = %d, yoffset = %d",sp->xoffset, sp->yoffset);
1062 CON_ConMessage("sectnum = %d, statnum = %d",sp->sectnum, sp->statnum);
1063 CON_ConMessage("ang = %d, owner = %d",sp->ang,sp->owner);
1064 CON_ConMessage("xvel = %d, yvel = %d, zvel = %d",sp->xvel,sp->yvel,sp->zvel);
1065 CON_ConMessage("lotag = %d, hitag = %d, extra = %d",sp->lotag,sp->hitag,sp->extra);
1066 }
1067
CON_UserDetail(void)1068 void CON_UserDetail( void )
1069 {
1070 char base[80];
1071 SHORT op1=0;
1072 SPRITEp sp;
1073 short i;
1074 USERp u;
1075
1076 // Format: showuser [SpriteNum]
1077 if (sscanf(MessageInputString,"%s %hd",base,&op1) < 2)
1078 {
1079 strcpy(MessageInputString,"help showsprite");
1080 CON_GetHelp();
1081 return;
1082 }
1083
1084 if(!CheckValidSprite(op1)) return;
1085 sp = &sprite[op1];
1086 u = User[op1];
1087
1088 if(!u) return;
1089
1090 CON_ConMessage("State = %p, Rot = %p",u->State,u->Rot);
1091 CON_ConMessage("StateStart = %p, StateEnd = %p",u->StateStart,u->StateEnd);
1092 CON_ConMessage("ActorActionFunc = %p",u->ActorActionFunc);
1093 CON_ConMessage("ActorActionSet = %p",u->ActorActionSet);
1094 CON_ConMessage("Personality = %p",u->Personality);
1095 CON_ConMessage("Attrib = %p",u->Attrib);
1096 CON_ConMessage("Flags = %d, Flags2 = %d, Tics = %d",u->Flags,u->Flags2,u->Tics);
1097 CON_ConMessage("RotNum = %d, ID = %d",u->RotNum,u->ID);
1098 CON_ConMessage("Health = %d, MaxHealth = %d",u->Health,u->MaxHealth);
1099 CON_ConMessage("LastDamage = %d, PainThreshold = %d",u->LastDamage,u->PainThreshold);
1100 CON_ConMessage("jump_speed = %d, jump_grav = %d",u->jump_speed,u->jump_grav);
1101 CON_ConMessage("xchange = %d, ychange = %d, zchange = %d",u->xchange,u->ychange,u->zchange);
1102 CON_ConMessage("ret = %d, WaitTics = %d, spal = %d",u->ret,u->WaitTics,u->spal);
1103 }
1104
CON_Quit(void)1105 void CON_Quit( void )
1106 {
1107 if (CommPlayers >= 2)
1108 MultiPlayQuitFlag = TRUE;
1109 else
1110 QuitFlag = TRUE;
1111 }
1112
CON_MultiNameChange(void)1113 void CON_MultiNameChange( void )
1114 {
1115 char base[16],command[16];
1116
1117 // Format: swname [name]
1118 if (sscanf(MessageInputString,"%6s %12s",base,command) < 2)
1119 return;
1120
1121 SendMulitNameChange(command, -1);
1122 }
1123
CON_LoadSetup(void)1124 void CON_LoadSetup( void )
1125 {
1126 /*
1127 char base[80],command[80];
1128 extern char setupfilename[64];
1129
1130 // Format: showuser [SpriteNum]
1131 if (sscanf(MessageInputString,"%s %s",base,command) < 2)
1132 {
1133 strcpy(MessageInputString,"help config");
1134 CON_GetHelp();
1135 return;
1136 }
1137
1138 if (!SafeFileExists(command))
1139 {
1140 CON_ConMessage("CON_LoadSetup: %s does not exist.",command);
1141 return;
1142 } else
1143 {
1144 strcpy(setupfilename,command);
1145 }
1146 initkeys();
1147 CONFIG_ReadSetup();
1148 CONTROL_Startup( ControllerType, &GetTime, 120 );
1149 SetupGameButtons();
1150
1151 if (CONTROL_JoystickEnabled)
1152 {
1153 CONTROL_CenterJoystick(CenterCenter, UpperLeft, LowerRight, CenterThrottle,
1154 CenterRudder);
1155 }
1156 CON_ConMessage("Loaded new config file.");
1157 */
1158 CON_ConMessage("JonoF: Maybe later");
1159 }
1160
1161 char *damagename[] = {
1162 "WPN_STAR","WPN_UZI",
1163 "WPN_SHOTGUN","WPN_MICRO",
1164 "WPN_GRENADE","WPN_MINE",
1165 "WPN_RAIL","WPN_HEART",
1166 "WPN_HOTHEAD","WPN_NAPALM"
1167 "WPN_RING","WPN_ROCKET",
1168 "WPN_SWORD","WPN_FIST",
1169 "DMG_NAPALM","DMG_MIRV_METEOR",
1170 "DMG_SERP_METEOR","DMG_ELECTRO_SHARD",
1171 "DMG_SECTOR_EXP","DMG_BOLT_EXP",
1172 "DMG_TANK_SHELL_EXP","DMG_FIREBALL_EXP",
1173 "DMG_NAPALM_EXP","DMG_SKULL_EXP",
1174 "DMG_BASIC_EXP","DMG_GRENADE_EXP",
1175 "DMG_MINE_EXP","DMG_MINE_SHRAP",
1176 "DMG_MICRO_EXP","DMG_NUCLEAR_EXP",
1177 "DMG_RADIATION_CLOUD","DMG_FLASHBOMB",
1178 "DMG_FIREBALL_FLAMES","DMG_RIPPER_SLASH",
1179 "DMG_SKEL_SLASH","DMG_COOLG_BASH",
1180 "DMG_COOLG_FIRE","DMG_GORO_CHOP",
1181 "DMG_GORO_FIREBALL","DMG_SERP_SLASH",
1182 "DMG_LAVA_BOULDER","DMG_LAVA_SHARD",
1183 "DMG_HORNET_STING","DMG_EEL_ELECTRO",
1184 "DMG_SPEAR_TRAP","DMG_VOMIT",
1185 "DMG_BLADE"
1186 };
1187
CON_DamageData(void)1188 void CON_DamageData( void )
1189 {
1190
1191 char base[80],field[80];
1192 SHORT op1=0;
1193 unsigned int op2, i;
1194 SPRITEp sp;
1195 USERp u;
1196
1197 // Format: damage [field] [item] [value]
1198 if (sscanf(MessageInputString,"%s %s %hd %u",base,field,&op1,&op2) < 3)
1199 {
1200 strcpy(MessageInputString,"help damage");
1201 CON_GetHelp();
1202 return;
1203 }
1204
1205 if(op1 < -1 || op1 > 46)
1206 {
1207 CON_ConMessage("Damage Data index is out of range.");
1208 return;
1209 }
1210
1211 if(!strcmp(field,"damage_lo"))
1212 {
1213 DamageData[op1].damage_lo = op2;
1214 CON_ConMessage("DamageData[%s].damage_lo = %d",damagename[op1],op2);
1215 } else
1216 if(!strcmp(field,"damage_hi"))
1217 {
1218 DamageData[op1].damage_hi = op2;
1219 CON_ConMessage("DamageData[%s].damage_hi = %d",damagename[op1],op2);
1220 } else
1221 if(!strcmp(field,"radius"))
1222 {
1223 DamageData[op1].radius = op2;
1224 CON_ConMessage("DamageData[%s].radius = %d",damagename[op1],op2);
1225 } else
1226 if(!strcmp(field,"max_ammo"))
1227 {
1228 DamageData[op1].max_ammo = op2;
1229 CON_ConMessage("DamageData[%s].max_ammo = %d",damagename[op1],op2);
1230 } else
1231 if(!strcmp(field,"min_ammo"))
1232 {
1233 DamageData[op1].min_ammo = op2;
1234 CON_ConMessage("DamageData[%s].min_ammo = %d",damagename[op1],op2);
1235 }
1236 if(!strcmp(field,"show"))
1237 {
1238 if(op1 == -1)
1239 {
1240 for(i=op2; i<=op2+10; i+=2)
1241 {
1242 if(i<47)
1243 CON_ConMessage("[%d] = %s [%d] = %s",i,damagename[i],i+1,damagename[i+1]);
1244 }
1245 } else
1246 {
1247 CON_ConMessage(" ");
1248 CON_ConMessage("Item = %s:",damagename[op1]);
1249 CON_ConMessage("damage_lo = %d, damag_hi = %d",DamageData[op1].damage_lo,DamageData[op1].damage_hi);
1250 CON_ConMessage("radius = %u",DamageData[op1].radius);
1251 CON_ConMessage("min_ammo = %d, max_ammo = %d",DamageData[op1].min_ammo,DamageData[op1].max_ammo);
1252 CON_ConMessage(" ");
1253 }
1254 }
1255 }
1256
CON_WinPachinko(void)1257 void CON_WinPachinko( void )
1258 {
1259 extern BOOL Pachinko_Win_Cheat;
1260 PLAYERp pp = Player + myconnectindex;
1261 extern void CheckSndData( char *file, int line );
1262
1263 if (CommEnabled)
1264 return;
1265
1266 Pachinko_Win_Cheat = !Pachinko_Win_Cheat;
1267
1268 //CheckSndData( __FILE__, __LINE__ );
1269
1270 if(Pachinko_Win_Cheat)
1271 PutStringInfo(pp,"Pachinko Win Cheat Enabled");
1272 else
1273 PutStringInfo(pp,"Pachinko Win Cheat Disabled");
1274 }
1275
CON_Tweak(void)1276 void CON_Tweak( void )
1277 {
1278 char base[80], command[80];
1279 int op1=0;
1280
1281 // Format: tweak [weapon] [number]
1282 if (sscanf(MessageInputString,"%s %s %d",base,command,&op1) < 3)
1283 {
1284 strcpy(MessageInputString,"help tweak");
1285 CON_GetHelp();
1286 return;
1287 }
1288
1289 Bstrlwr(command); // Make sure operator is all lower case
1290 if(!strcmp(command,"adjust"))
1291 {
1292 extern short ADJUST;
1293 ADJUST = op1;
1294 CON_ConMessage("Zvelocity ADJUST set to %d.",op1);
1295 } else
1296 if(!strcmp(command,"adjustv"))
1297 {
1298 extern int ADJUSTV;
1299 ADJUSTV = op1;
1300 CON_ConMessage("Zvelocity ADJUSTV set to %d.",op1);
1301 }
1302 }
1303
CON_Bunny(void)1304 void CON_Bunny( void )
1305 {
1306 PLAYERp pp = Player + myconnectindex;
1307
1308 if (CommEnabled)
1309 return;
1310
1311 pp->BunnyMode = !pp->BunnyMode;
1312 if(pp->BunnyMode)
1313 PutStringInfo(pp,"Bunny rockets enabled!");
1314 else
1315 PutStringInfo(pp,"Bunny rockets disabled!");
1316 }
1317
CON_CheckHeap(void)1318 void CON_CheckHeap( void )
1319 {
1320 /*
1321 switch( _heapchk() )
1322 {
1323 case _HEAPOK:
1324 CON_ConMessage( "OK - heap is good\n" );
1325 break;
1326 case _HEAPEMPTY:
1327 CON_ConMessage( "OK - heap is empty\n" );
1328 break;
1329 case _HEAPBADBEGIN:
1330 CON_ConMessage( "ERROR - heap is damaged\n" );
1331 break;
1332 case _HEAPBADNODE:
1333 CON_ConMessage( "ERROR - bad node in heap\n" );
1334 break;
1335 }
1336 */
1337 CON_ConMessage("JonoF: Not now");
1338 }
1339
1340 /*
1341 void heap_dump( void )
1342 {
1343 struct _heapinfo h_info;
1344 int heap_status;
1345
1346 h_info._pentry = NULL;
1347 for(;;) {
1348 heap_status = _heapwalk( &h_info );
1349 if( heap_status != _HEAPOK ) break;
1350 printf( " %s block at %Fp of size %4.4X\n",
1351 (h_info._useflag == _USEDENTRY ? "USED" : "FREE"),
1352 h_info._pentry, h_info._size );
1353
1354 }
1355
1356 switch( heap_status ) {
1357 case _HEAPEND:
1358 printf( "OK - end of heap\n" );
1359 break;
1360 case _HEAPEMPTY:
1361 printf( "OK - heap is empty\n" );
1362 break;
1363 case _HEAPBADBEGIN:
1364 printf( "ERROR - heap is damaged\n" );
1365 break;
1366 case _HEAPBADPTR:
1367 printf( "ERROR - bad pointer to heap\n" );
1368 break;
1369 case _HEAPBADNODE:
1370
1371 printf( "ERROR - bad node in heap\n" );
1372 }
1373 }
1374 */
1375
CON_DumpHeap(void)1376 void CON_DumpHeap( void )
1377 {
1378 //heap_dump(); // Dump it.
1379 CON_ConMessage("JonoF: Not now");
1380 }
1381
CON_ShowMirror(void)1382 void CON_ShowMirror( void )
1383 {
1384 char base[80];
1385 SHORT op1=0;
1386
1387 // Format: showmirror [SpriteNum]
1388 if (sscanf(MessageInputString,"%s %hd",base,&op1) < 2)
1389 {
1390 strcpy(MessageInputString,"help showmirror");
1391 CON_GetHelp();
1392 return;
1393 }
1394
1395 if(op1 < 0 || op1 > 9)
1396 {
1397 CON_ConMessage("Mirror number is out of range!");
1398 return;
1399 }
1400
1401 CON_ConMessage("camera is the ST1 sprite used as the view spot");
1402 CON_ConMessage("camspite is the SpriteNum of the drawtotile tile in editart");
1403 CON_ConMessage("camspic is the tile number of the drawtotile in editart");
1404 CON_ConMessage("iscamera is whether or not this mirror is a camera type");
1405 CON_ConMessage(" ");
1406 CON_ConMessage("mirror[%d].mirrorwall = %d",op1,mirror[op1].mirrorwall);
1407 CON_ConMessage("mirror[%d].mirrorsector = %d",op1,mirror[op1].mirrorsector);
1408 CON_ConMessage("mirror[%d].camera = %d",op1,mirror[op1].camera);
1409 CON_ConMessage("mirror[%d].camsprite = %d",op1,mirror[op1].camsprite);
1410 CON_ConMessage("mirror[%d].campic = %d",op1,mirror[op1].campic);
1411 CON_ConMessage("mirror[%d].iscamera = %d",op1,mirror[op1].ismagic);
1412 }
1413
CON_DumpSoundList(void)1414 void CON_DumpSoundList( void )
1415 {
1416 extern void DumpSounds(void);
1417
1418 DumpSounds();
1419 CON_Message("Sounds dumped to dbg.foo");
1420
1421 }
1422
1423