#g: doom (1993)
Explore tagged Tumblr posts
Text
Video Game Track Bracket Round 2
Two Planets Approach the Roche Limit from Kirby and the Forgotten Land
youtube
vs.
At Doom's Gate from Doom (1993)
youtube
Propaganda under the cut. If you want your propaganda reblogged and added to future polls, please tag it as propaganda or otherwise indicate this!
Two Planets Approach the Roche Limit:
Immensely cinematic and introducing scientific states of planets in the title? Yup. It’s a Kirby song.
At Doom's Gate:
iconic
#tournament poll#f: kirby#s: kirby#g: kirby and the forgotten land#s: doom#g: doom (1993)#kirby#doom 1993#forgotten land#fecto elefis#kirby and the forgotten land#round 2#t: two planets approach the roche limit#t: at doom's gate
21 notes
·
View notes
Text
Recommending some of my favorite rap songs. As a latin american trans woman, I didn't grow up with rap, but I learned to listen to and appreciate it. These are some great songs I think everyone should hear, and hopefully add to their playlists. These are Spotify links, but you can find these songs elsewhere too. My favorites are in blue:
Pop Rap: She's a Bitch by Missy Elliot (1999); Comfortable (ft. Babyface) by Lil Wayne (2003); Savage (ft. Beyoncé) by Megan Thee Stallion (2020); Too Many Nights (ft. Don Toliver & Future) by Metro Boomin (2022); Never Lose Me (ft. SZA & Cardi B) by Flo Mili (2024)
Classic Rap: My Mic Sounds Nice by Salt-N-Pepa (1986); South Bronx by Boogie Down Productions (1987); Welcome To The Terrordome by Public Enemy (1990); Born and Raised In Compton by DJ Quik (1991); When In Love by MC Lyte (1991)
Gangsta Rap: Gimme the Loot by The Notorious B.I.G. (1994); Cloverland (ft. Botany Boyz) by DJ Screw (1996); The Art of Peer Pressure by Kendrick Lamar (2012); Norf Norf by Vince Staples (2015); Tear Gas (ft. Rick Ross & Lil Wayne) by Conway the Machine (2022)
G-Funk: Nuthin' But A "G" Thang (ft. Snoop Dogg) by Dr. Dre (1992); Funkdafied by Da Brat (1994); It's Supposed to Bubble by UGK (1994); Dusted 'N' Disgusted (ft. 2Pac, Mac Mall & Spice 1) by E-40 (1995); Can't C Me by 2Pac (1996)
Conscious Rap: Proletariat Blues by Blue Scholars (2006); 4 Your Eyez Only by J. Cole (2016); Blood of the Fang by clipping. (2019); Iman (ft. SiR & JID) by Rapsody (2019); I Love You, I Hate You by Little Simz (2021)
Abstract Rap: Accordion by Madvillain (MF DOOM & Madlib) (2000); Mural by Lupe Fiasco (2015); The Punishment of Sisyphus by Hermit and the Recluse (Ka & Animoss) (2018); Magician (Suture) by Milo (2017); Arugula by Junglepussy (2020)
Jazz Rap: Jazz (We've Got) by A Tribe Called Quest (1991); 93 'Til Infinity by Souls Of Mischief (1993); The World Is Yours by Nas (1994); Yesterday by Noname (2016); Live! from the Kitchen Table (ft. Ghais Guevara) by McKinley Dixon (2023)
Trap: Ridin' N' Da Chevy by Three Six Mafia (1999); Love Don't Live (U Abandoned Me) by Gangsta Boo (2001); Kay Kay by Chief Keef (2012); Digits by Young Thug (2016); Poppin by Rico Nasty (2017)
Experimental Rap: Spiritual Healing by dälek (2002); Persistence by Lil Ugly Mane (2015); Ain't It Funny by Danny Brown (2016); Thug Tears by JPEGMAFIA (2018); Superman That by Injury Reserve (2021)
I strongly recommend checking out other songs by these artists, the albums these songs are from, more songs from these genres and others I didn't include, and to explore everything hip hop has to offer (especially hip hop made by women). Feel free to add any artists and songs I (obviously) missed, that you think deserve more love and recognition, particularly independent music. Enjoy!
233 notes
·
View notes
Text
I'm Grim or Vince.
He/him. INTP. 15-17.
This is my personal blog. I'll just talk about and post whatever I like. If you don't like it, feel free to block and leave. I'll sometimes post some of my music stuff on here as well. Singing, piano, bass. I don't know. I'll post whatever.
grim.txt - The guy decides to yap. Oh fuck, who let him speak? Please do not let him cook.
grim.mp3/grim.mp4 - Videos and/or audios of the man himself. Schizophrenic rambles? Genuine takes on society? Who knows.
art.txt - HOLY SHIT ART?! Either drawings or music. Just using .txt because it makes it easier to categorize.
Music I enjoy: KMFDM, Genitorturers, Mindless Self Indulgence, Nine Inch Nails, Cigarettes after sex, Smashing Pumpkins, Rammstein, Fried by Fluoride, Alex G, Crush Sign Motorist, Nirvana, Korn, Slipknot, Gorillaz, Radiohead, TV Girl, Green day, Femtanyl, Marilyn Manson. Shit, the list goes on.
Media I like: Invader Zim, Postal, DOOM 1993, Postal, Hatred, Vocaloid, Creepypasta, Ranfren, Zero day, Duck! The Carbine high massacre, School-Live!, Sanrio, Fable (two and three), Crash Bandicoot: Mind over Mutant, Hazbin Hotel/Helluva Boss (love the shows, fucking hate most of the fandom), Spongebob,
41 notes
·
View notes
Text
[Image description: A polyam flag with the words “four or more fic-a-thon” on it. To the left of the infinity sign, there's a post-it that says "4 weeks to go". End description.]
THE FOUR OR MORE 2024 FICATHON HAS ONLY 4 WEEKS LEFT — Prompts by fandom
AO3 COLLECTION | SQUIDGEWORLD COLLECTION
Whether you've been itching to write something for that one prompt that you've been chewing on since day one or you're just hearing about this event and your curiosity has been piqued, this is your chance to see if someone has requested a fandom you're interested in. And if no one has requested your fandom, why not go ahead and leave a prompt. You never know who's watching.
Fandoms listed alphabetically with links to the respective prompts below the cut. Don't forget comments can have more than one prompt.
THIS LIST CONTAINS PROMPTS LEFT UNTIL SEPTEMBER 21st 1:30 pm GMT/UTC -4. Want to know if maybe someone has left more prompts after this? Check the main Ficathon post for more info.
A
A fandom you've never written before
Ace Attorney
Angel the series
Attack on Titan
B
Babylon 5
Buffyverse (Part 1)
Buffyverse (Part 2)
C
Chicago Fire
Chicago Med
D
Days of Our Lives
Doctor Who
Doom Patrol TV
F
Fate/Stay Night
Final Fantasy VII (Part 1)
Final Fantasy VII (Part 2)
Final Fantasy VIII
Fire Emblem: Three Houses
Friends
Full House
G
General Hospital
Grey's Anatomy (Part 1)
Grey's Anatomy (Part 2)
Grey's Anatomy (Part 3)
Gossip Girl
M
Monster Prom
P
Pretty Little Liars
Psych
S
Sabrina the Teenage Witch
Saved by the Bell
Sense8
Star Ocean 2
T
Teen Wolf
The Murderbot Diaries
The Scum Villain's Self-Saving System
Twisters (2024)
W
Warhammer 40000
Women's Murder Club
X
X-files
Y
Yu-Gi-Oh! VRAINS
Multiple fandoms or crossovers
A League of Nobleman, Tian Guan Ci Fu, The Scum Villain's Self-Saving System
Ace Attorney, Any fandom, Amphibia, Doctor Who, Dracula, The Owl House, Pokemon Horizons, Stardew Valley, The Great Ace Attorney, Star Trek AOS, Star Trek DS9, Star Trek Lower Decks, Star Trek TNG
Animator Vs. Animation, Any fandom, Deltarune, HfjONE, Omori, The Demon Headmaster (2019)
Angel the series, Buffy the vampire slayer (Part 1)
Angel the series, Buffy the vampire slayer (Part 2)
Any fandom, Angel the series, Buffy the vampire slayer
Any fandom, Charlie's Angels
Any fandom, Chicago Med
Any fandom, Danganronpa, Team Fortress 2
Any fandom, NU: carnival
Any fandom, Pitch Perfect
Any fandom, Love Between Fairy and Devil, Marvel, MDZS/The Untamed
Any PreCure Series, Delicious Party PreCure, Star Twinkle PreCure, Tropical Rouge PreCure
Beast Wars: Transformers, Detective Conan/Magic Kaito, Leverage, RWBY
Bridgerton (TV)/Much Ado About Nothing (Shakespeare or 1993 movie)
Caos, H2O, High School Musical: The Musical The Series, Outer Banks, Teen Wolf, The OC
Critical Role, Star Wars
Dead Boys Detective Agency, Julie and the Phantoms, Sense8, Star Trek Voyager, The Raven Cycle
Dishonored, Dragon Age
Final Fantasy VIII, MDZS, Teen Wolf, Voltron (2016)
General Hospital, MCU
Kamen Rider (various series), Ohsama Sentai King-Ohger, Samurai Sentai Shinkenger, Yu-Gi-Oh! 5D's, Yu-Gi-Oh! ARC-V, Yu-Gi-Oh! VRAINS
MDZS, Star Trek, The Scum Villain's Self-Saving System, Voltron (2016)
If you have any questions, don't hesitate to contact us.
#polyships#poly shipping#polyam shipping#polyamorous ships#polyamory#writing event#ficathon#admin post#fourormore#OT4#OT5#OT6#star trek#final fantasy#teen wolf#buffyverse#yugioh#polyamoryinfandoms#prompts
34 notes
·
View notes
Text
notepad collective. .
note / raymond / dylan / milenko
absolutely any pronouns. this includes offensive neos.
openly problematic. visibly disabled.
no DNI! but christians please do not follow.
about us below
Body name: Raymond
System name: Notepad collective
Collective name: Dylan / Milenko
Current host(s) name: Nero
Relationship status: Host has a boyfriend! But particular headmates are single.
System origin: Mostly traumagenic. A few others mixed in though.
Special interests: Firearms, true crime (mainly shootings), shooting games, punk shit, Arcane League Of Legends, kittens(!!!!!!!!!), kink, queer liberation, webfishing, the 90s
Hobbies: DIYing (sewing patches, painting shit, etc.), airsoft, drawing (digital and traditional), smoking, browsing the internet
Musical taste: Nine Inch Nails, KMFDM, Crass, Slipknot, Insane Clown Posse, Deftones, Radiohead, Alex G, Mitski, Grimes, Tyler The Creator, Rammstein
Favorite games: DOOM (1993) DOOM 2, DOOM 64, OMORI, Postal Redux, Webfishing, Animal Crossing New Horizons
Disabilities/disorders/etc.: Autism (med-high support needs), Rheumatoid Arthritis, hypermobile Ehlers Danlos syndrome, DID, plantar fascitis, some unknown heart condition that makes it beat too fast, OCD, NPD, BPD, depression, anxiety, permenent drug induced psychosis, scoliosis, 14q11.2 deletion syndrome
Disability aids we regularly use: AAC device, cane, visual schedules, knee braces, sensory aids
12 notes
·
View notes
Text
G/t Rec/favorite list from AO3 part 1
Bite-sized by bluprismwrites
Taken place during Act 1 of Baldur's Gate 3. Meet Ria, a 10 centimetre tall (4 inches) borrower who is trying her best to survive out in the wilderness of Faerûn without being crushed underfoot, squashed, or eaten. Astarion, weak with hunger, manages to catch a whiff of Ria's scent, and driven by his bloodlust he tracks her down with the intention of eating her. Of course, things get a little complicated when Gale becomes involved.
Nine- by ittybluebell
At four inches tall, Clover's used to danger. They never wanted eight giant strangers invading their life, but now Clover must quickly adapt to this new family and the threats that follow. The cluster will do anything to protect their smallest member. And Clover will do what they can.
Beast of mars by Raventroll80
After a Millennia asleep, the Doom Slayer awakens to a situation all too familiar. Hell has broken lose on Mars, and with demons around every corner, the Slayer must put a stop to the invasion before things get worse. Should be easy for a 15 foot troll right?
Only a couple days by pocket_lad
If Adelaide knew what dinosaurs were before this trip, she probably wouldn't have come, but after being discovered by a Human Bean named Ian Malcolm, she found herself on increasingly sporadic and dangerous adventures....and she kind of liked it. For the most part.
Basically Jurassic Park (1993) but if Ian Malcolm brought a three-inch tall borrower with him.
Aaron’s unscheduled stay by notabanishedprivateer
Aaron gets into a dire situation after being forced to venture outside the wall
Tiny terrors by cravesweets
A machine accident somehow shrunk and separated Danny into two, with one normal Danny Fenton and one wild gremblin Phantom, who decided to kidnap him to some creepy gothic mansion for no reason.
Borrower danny by DP_Marvel94
A teeny tiny Danny starts living in Wayne Manor
Finders keepers, losers weepers (but also please stop crying I’m new to this) By ShowrunnerIhardlyknowher
Working for a pest control company had its ups and downs, but for the most part the benefits were satisfactory. Good insurance, optional overtime, the chance to acquire a child who conveniently fit into a shirt pocket while you try to figure out what to do now.
Not quite sure there's a parenting handbook that covers the care and keeping of an abandoned borrower.
Meaning of freedom by deadheaded-stepchild (itsybitsykitsy)
It’s been roughly 30 years since borrowers had been discovered, their one and only safeguard, secrecy, compromised. And humanity has deemed it to do with them as they saw fit, regardless of how they feel about it.
Just an anthology of how borrowers now have to live their lives now that humans sees them as pests, pets and even test subjects. Sometimes worse. Stories may have happy endings, bad ones, bittersweet ones, or open-ended ones. Some have continuing overarching plots and some are one and done. Rating may change due to contents of certain stories and warnings will be posted beforehand.
House call by trumpetteacow
Dr. Ludwig, the Medic, responds to a house call from his old friend, Misha, the Heavy, complaining of a vague ailment. While he can't fix his illness, lacking in medical licensure, he does solve his borrower problem—unfortunately for Jeremy, the Scout.
12 notes
·
View notes
Text
DOOM source code line 1-30,000
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // // $Log:$ // // DESCRIPTION: the automap code // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: am_map.c,v 1.4 1997/02/03 21:24:33 b1 Exp $";
#include <stdio.h>
#include "z_zone.h" #include "doomdef.h" #include "st_stuff.h" #include "p_local.h" #include "w_wad.h"
#include "m_cheat.h" #include "i_system.h"
// Needs access to LFB. #include "v_video.h"
// State. #include "doomstat.h" #include "r_state.h"
// Data. #include "dstrings.h"
#include "am_map.h"
// For use if I do walls with outsides/insides #define REDS (256-5*16) #define REDRANGE 16 #define BLUES (256-4*16+8) #define BLUERANGE 8 #define GREENS (7*16) #define GREENRANGE 16 #define GRAYS (6*16) #define GRAYSRANGE 16 #define BROWNS (4*16) #define BROWNRANGE 16 #define YELLOWS (256-32+7) #define YELLOWRANGE 1 #define BLACK 0 #define WHITE (256-47)
// Automap colors #define BACKGROUND BLACK #define YOURCOLORS WHITE #define YOURRANGE 0 #define WALLCOLORS REDS #define WALLRANGE REDRANGE #define TSWALLCOLORS GRAYS #define TSWALLRANGE GRAYSRANGE #define FDWALLCOLORS BROWNS #define FDWALLRANGE BROWNRANGE #define CDWALLCOLORS YELLOWS #define CDWALLRANGE YELLOWRANGE #define THINGCOLORS GREENS #define THINGRANGE GREENRANGE #define SECRETWALLCOLORS WALLCOLORS #define SECRETWALLRANGE WALLRANGE #define GRIDCOLORS (GRAYS + GRAYSRANGE/2) #define GRIDRANGE 0 #define XHAIRCOLORS GRAYS
// drawing stuff #define FB 0
#define AM_PANDOWNKEY KEY_DOWNARROW #define AM_PANUPKEY KEY_UPARROW #define AM_PANRIGHTKEY KEY_RIGHTARROW #define AM_PANLEFTKEY KEY_LEFTARROW #define AM_ZOOMINKEY '=' #define AM_ZOOMOUTKEY '-' #define AM_STARTKEY KEY_TAB #define AM_ENDKEY KEY_TAB #define AM_GOBIGKEY '0' #define AM_FOLLOWKEY 'f' #define AM_GRIDKEY 'g' #define AM_MARKKEY 'm' #define AM_CLEARMARKKEY 'c'
#define AM_NUMMARKPOINTS 10
// scale on entry #define INITSCALEMTOF (.2*FRACUNIT) // how much the automap moves window per tic in frame-buffer coordinates // moves 140 pixels in 1 second #define F_PANINC 4 // how much zoom-in per tic // goes to 2x in 1 second #define M_ZOOMIN ((int) (1.02*FRACUNIT)) // how much zoom-out per tic // pulls out to 0.5x in 1 second #define M_ZOOMOUT ((int) (FRACUNIT/1.02))
// translates between frame-buffer and map distances #define FTOM(x) FixedMul(((x)<<16),scale_ftom) #define MTOF(x) (FixedMul((x),scale_mtof)>>16) // translates between frame-buffer and map coordinates #define CXMTOF(x) (f_x + MTOF((x)-m_x)) #define CYMTOF(y) (f_y + (f_h - MTOF((y)-m_y)))
// the following is crap #define LINE_NEVERSEE ML_DONTDRAW
typedef struct { int x, y; } fpoint_t;
typedef struct { fpoint_t a, b; } fline_t;
typedef struct { fixed_t x,y; } mpoint_t;
typedef struct { mpoint_t a, b; } mline_t;
typedef struct { fixed_t slp, islp; } islope_t;
// // The vector graphics for the automap. // A line drawing of the player pointing right, // starting from the middle. // #define R ((8*PLAYERRADIUS)/7) mline_t player_arrow[] = { { { -R+R/8, 0 }, { R, 0 } }, // ----- { { R, 0 }, { R-R/2, R/4 } }, // -----> { { R, 0 }, { R-R/2, -R/4 } }, { { -R+R/8, 0 }, { -R-R/8, R/4 } }, // >----> { { -R+R/8, 0 }, { -R-R/8, -R/4 } }, { { -R+3*R/8, 0 }, { -R+R/8, R/4 } }, // >>---> { { -R+3*R/8, 0 }, { -R+R/8, -R/4 } } }; #undef R #define NUMPLYRLINES (sizeof(player_arrow)/sizeof(mline_t))
#define R ((8*PLAYERRADIUS)/7) mline_t cheat_player_arrow[] = { { { -R+R/8, 0 }, { R, 0 } }, // ----- { { R, 0 }, { R-R/2, R/6 } }, // -----> { { R, 0 }, { R-R/2, -R/6 } }, { { -R+R/8, 0 }, { -R-R/8, R/6 } }, // >-----> { { -R+R/8, 0 }, { -R-R/8, -R/6 } }, { { -R+3*R/8, 0 }, { -R+R/8, R/6 } }, // >>-----> { { -R+3*R/8, 0 }, { -R+R/8, -R/6 } }, { { -R/2, 0 }, { -R/2, -R/6 } }, // >>-d---> { { -R/2, -R/6 }, { -R/2+R/6, -R/6 } }, { { -R/2+R/6, -R/6 }, { -R/2+R/6, R/4 } }, { { -R/6, 0 }, { -R/6, -R/6 } }, // >>-dd--> { { -R/6, -R/6 }, { 0, -R/6 } }, { { 0, -R/6 }, { 0, R/4 } }, { { R/6, R/4 }, { R/6, -R/7 } }, // >>-ddt-> { { R/6, -R/7 }, { R/6+R/32, -R/7-R/32 } }, { { R/6+R/32, -R/7-R/32 }, { R/6+R/10, -R/7 } } }; #undef R #define NUMCHEATPLYRLINES (sizeof(cheat_player_arrow)/sizeof(mline_t))
#define R (FRACUNIT) mline_t triangle_guy[] = { { { -.867*R, -.5*R }, { .867*R, -.5*R } }, { { .867*R, -.5*R } , { 0, R } }, { { 0, R }, { -.867*R, -.5*R } } }; #undef R #define NUMTRIANGLEGUYLINES (sizeof(triangle_guy)/sizeof(mline_t))
#define R (FRACUNIT) mline_t thintriangle_guy[] = { { { -.5*R, -.7*R }, { R, 0 } }, { { R, 0 }, { -.5*R, .7*R } }, { { -.5*R, .7*R }, { -.5*R, -.7*R } } }; #undef R #define NUMTHINTRIANGLEGUYLINES (sizeof(thintriangle_guy)/sizeof(mline_t))
static int cheating = 0; static int grid = 0;
static int leveljuststarted = 1; // kluge until AM_LevelInit() is called
boolean automapactive = false; static int finit_width = SCREENWIDTH; static int finit_height = SCREENHEIGHT - 32;
// location of window on screen static int f_x; static int f_y;
// size of window on screen static int f_w; static int f_h;
static int lightlev; // used for funky strobing effect static byte* fb; // pseudo-frame buffer static int amclock;
static mpoint_t m_paninc; // how far the window pans each tic (map coords) static fixed_t mtof_zoommul; // how far the window zooms in each tic (map coords) static fixed_t ftom_zoommul; // how far the window zooms in each tic (fb coords)
static fixed_t m_x, m_y; // LL x,y where the window is on the map (map coords) static fixed_t m_x2, m_y2; // UR x,y where the window is on the map (map coords)
// // width/height of window on map (map coords) // static fixed_t m_w; static fixed_t m_h;
// based on level size static fixed_t min_x; static fixed_t min_y; static fixed_t max_x; static fixed_t max_y;
static fixed_t max_w; // max_x-min_x, static fixed_t max_h; // max_y-min_y
// based on player size static fixed_t min_w; static fixed_t min_h;
static fixed_t min_scale_mtof; // used to tell when to stop zooming out static fixed_t max_scale_mtof; // used to tell when to stop zooming in
// old stuff for recovery later static fixed_t old_m_w, old_m_h; static fixed_t old_m_x, old_m_y;
// old location used by the Follower routine static mpoint_t f_oldloc;
// used by MTOF to scale from map-to-frame-buffer coords static fixed_t scale_mtof = INITSCALEMTOF; // used by FTOM to scale from frame-buffer-to-map coords (=1/scale_mtof) static fixed_t scale_ftom;
static player_t *plr; // the player represented by an arrow
static patch_t *marknums[10]; // numbers used for marking by the automap static mpoint_t markpoints[AM_NUMMARKPOINTS]; // where the points are static int markpointnum = 0; // next point to be assigned
static int followplayer = 1; // specifies whether to follow the player around
static unsigned char cheat_amap_seq[] = { 0xb2, 0x26, 0x26, 0x2e, 0xff }; static cheatseq_t cheat_amap = { cheat_amap_seq, 0 };
static boolean stopped = true;
extern boolean viewactive; //extern byte screens[][SCREENWIDTH*SCREENHEIGHT];
void V_MarkRect ( int x, int y, int width, int height );
// Calculates the slope and slope according to the x-axis of a line // segment in map coordinates (with the upright y-axis n' all) so // that it can be used with the brain-dead drawing stuff.
void AM_getIslope ( mline_t* ml, islope_t* is ) { int dx, dy;
dy = ml->a.y - ml->b.y; dx = ml->b.x - ml->a.x; if (!dy) is->islp = (dx<0?-MAXINT:MAXINT); else is->islp = FixedDiv(dx, dy); if (!dx) is->slp = (dy<0?-MAXINT:MAXINT); else is->slp = FixedDiv(dy, dx);
}
// // // void AM_activateNewScale(void) { m_x += m_w/2; m_y += m_h/2; m_w = FTOM(f_w); m_h = FTOM(f_h); m_x -= m_w/2; m_y -= m_h/2; m_x2 = m_x + m_w; m_y2 = m_y + m_h; }
// // // void AM_saveScaleAndLoc(void) { old_m_x = m_x; old_m_y = m_y; old_m_w = m_w; old_m_h = m_h; }
// // // void AM_restoreScaleAndLoc(void) {
m_w = old_m_w; m_h = old_m_h; if (!followplayer) { m_x = old_m_x; m_y = old_m_y; } else { m_x = plr->mo->x - m_w/2; m_y = plr->mo->y - m_h/2; } m_x2 = m_x + m_w; m_y2 = m_y + m_h;
// Change the scaling multipliers scale_mtof = FixedDiv(f_w<<FRACBITS, m_w); scale_ftom = FixedDiv(FRACUNIT, scale_mtof); }
// // adds a marker at the current location // void AM_addMark(void) { markpoints[markpointnum].x = m_x + m_w/2; markpoints[markpointnum].y = m_y + m_h/2; markpointnum = (markpointnum + 1) % AM_NUMMARKPOINTS;
}
// // Determines bounding box of all vertices, // sets global variables controlling zoom range. // void AM_findMinMaxBoundaries(void) { int i; fixed_t a; fixed_t b;
min_x = min_y = MAXINT; max_x = max_y = -MAXINT;
for (i=0;i<numvertexes;i++) { if (vertexes[i].x < min_x) min_x = vertexes[i].x; else if (vertexes[i].x > max_x) max_x = vertexes[i].x;
if (vertexes[i].y < min_y) min_y = vertexes[i].y; else if (vertexes[i].y > max_y) max_y = vertexes[i].y; }
max_w = max_x - min_x; max_h = max_y - min_y;
min_w = 2*PLAYERRADIUS; // const? never changed? min_h = 2*PLAYERRADIUS;
a = FixedDiv(f_w<<FRACBITS, max_w); b = FixedDiv(f_h<<FRACBITS, max_h);
min_scale_mtof = a < b ? a : b; max_scale_mtof = FixedDiv(f_h<<FRACBITS, 2*PLAYERRADIUS);
}
// // // void AM_changeWindowLoc(void) { if (m_paninc.x || m_paninc.y) { followplayer = 0; f_oldloc.x = MAXINT; }
m_x += m_paninc.x; m_y += m_paninc.y;
if (m_x + m_w/2 > max_x) m_x = max_x - m_w/2; else if (m_x + m_w/2 < min_x) m_x = min_x - m_w/2;
if (m_y + m_h/2 > max_y) m_y = max_y - m_h/2; else if (m_y + m_h/2 < min_y) m_y = min_y - m_h/2;
m_x2 = m_x + m_w; m_y2 = m_y + m_h; }
// // // void AM_initVariables(void) { int pnum; static event_t st_notify = { ev_keyup, AM_MSGENTERED };
automapactive = true; fb = screens[0];
f_oldloc.x = MAXINT; amclock = 0; lightlev = 0;
m_paninc.x = m_paninc.y = 0; ftom_zoommul = FRACUNIT; mtof_zoommul = FRACUNIT;
m_w = FTOM(f_w); m_h = FTOM(f_h);
// find player to center on initially if (!playeringame[pnum = consoleplayer]) for (pnum=0;pnum<MAXPLAYERS;pnum++) if (playeringame[pnum]) break;
plr = &players[pnum]; m_x = plr->mo->x - m_w/2; m_y = plr->mo->y - m_h/2; AM_changeWindowLoc();
// for saving & restoring old_m_x = m_x; old_m_y = m_y; old_m_w = m_w; old_m_h = m_h;
// inform the status bar of the change ST_Responder(&st_notify);
}
// // // void AM_loadPics(void) { int i; char namebuf[9];
for (i=0;i<10;i++) { sprintf(namebuf, "AMMNUM%d", i); marknums[i] = W_CacheLumpName(namebuf, PU_STATIC); }
}
void AM_unloadPics(void) { int i;
for (i=0;i<10;i++) Z_ChangeTag(marknums[i], PU_CACHE);
}
void AM_clearMarks(void) { int i;
for (i=0;i<AM_NUMMARKPOINTS;i++) markpoints[i].x = -1; // means empty markpointnum = 0; }
// // should be called at the start of every level // right now, i figure it out myself // void AM_LevelInit(void) { leveljuststarted = 0;
f_x = f_y = 0; f_w = finit_width; f_h = finit_height;
AM_clearMarks();
AM_findMinMaxBoundaries(); scale_mtof = FixedDiv(min_scale_mtof, (int) (0.7*FRACUNIT)); if (scale_mtof > max_scale_mtof) scale_mtof = min_scale_mtof; scale_ftom = FixedDiv(FRACUNIT, scale_mtof); }
// // // void AM_Stop (void) { static event_t st_notify = { 0, ev_keyup, AM_MSGEXITED };
AM_unloadPics(); automapactive = false; ST_Responder(&st_notify); stopped = true; }
// // // void AM_Start (void) { static int lastlevel = -1, lastepisode = -1;
if (!stopped) AM_Stop(); stopped = false; if (lastlevel != gamemap || lastepisode != gameepisode) { AM_LevelInit(); lastlevel = gamemap; lastepisode = gameepisode; } AM_initVariables(); AM_loadPics(); }
// // set the window scale to the maximum size // void AM_minOutWindowScale(void) { scale_mtof = min_scale_mtof; scale_ftom = FixedDiv(FRACUNIT, scale_mtof); AM_activateNewScale(); }
// // set the window scale to the minimum size // void AM_maxOutWindowScale(void) { scale_mtof = max_scale_mtof; scale_ftom = FixedDiv(FRACUNIT, scale_mtof); AM_activateNewScale(); }
// // Handle events (user inputs) in automap mode // boolean AM_Responder ( event_t* ev ) {
int rc; static int cheatstate=0; static int bigstate=0; static char buffer[20];
rc = false;
if (!automapactive) { if (ev->type == ev_keydown && ev->data1 == AM_STARTKEY) { AM_Start (); viewactive = false; rc = true; } }
else if (ev->type == ev_keydown) {
rc = true; switch(ev->data1) { case AM_PANRIGHTKEY: // pan right if (!followplayer) m_paninc.x = FTOM(F_PANINC); else rc = false; break; case AM_PANLEFTKEY: // pan left if (!followplayer) m_paninc.x = -FTOM(F_PANINC); else rc = false; break; case AM_PANUPKEY: // pan up if (!followplayer) m_paninc.y = FTOM(F_PANINC); else rc = false; break; case AM_PANDOWNKEY: // pan down if (!followplayer) m_paninc.y = -FTOM(F_PANINC); else rc = false; break; case AM_ZOOMOUTKEY: // zoom out mtof_zoommul = M_ZOOMOUT; ftom_zoommul = M_ZOOMIN; break; case AM_ZOOMINKEY: // zoom in mtof_zoommul = M_ZOOMIN; ftom_zoommul = M_ZOOMOUT; break; case AM_ENDKEY: bigstate = 0; viewactive = true; AM_Stop (); break; case AM_GOBIGKEY: bigstate = !bigstate; if (bigstate) { AM_saveScaleAndLoc(); AM_minOutWindowScale(); } else AM_restoreScaleAndLoc(); break; case AM_FOLLOWKEY: followplayer = !followplayer; f_oldloc.x = MAXINT; plr->message = followplayer ? AMSTR_FOLLOWON : AMSTR_FOLLOWOFF; break; case AM_GRIDKEY: grid = !grid; plr->message = grid ? AMSTR_GRIDON : AMSTR_GRIDOFF; break; case AM_MARKKEY: sprintf(buffer, "%s %d", AMSTR_MARKEDSPOT, markpointnum); plr->message = buffer; AM_addMark(); break; case AM_CLEARMARKKEY: AM_clearMarks(); plr->message = AMSTR_MARKSCLEARED; break; default: cheatstate=0; rc = false; } if (!deathmatch && cht_CheckCheat(&cheat_amap, ev->data1)) { rc = false; cheating = (cheating+1) % 3; } }
else if (ev->type == ev_keyup) { rc = false; switch (ev->data1) { case AM_PANRIGHTKEY: if (!followplayer) m_paninc.x = 0; break; case AM_PANLEFTKEY: if (!followplayer) m_paninc.x = 0; break; case AM_PANUPKEY: if (!followplayer) m_paninc.y = 0; break; case AM_PANDOWNKEY: if (!followplayer) m_paninc.y = 0; break; case AM_ZOOMOUTKEY: case AM_ZOOMINKEY: mtof_zoommul = FRACUNIT; ftom_zoommul = FRACUNIT; break; } }
return rc;
}
// // Zooming // void AM_changeWindowScale(void) {
// Change the scaling multipliers scale_mtof = FixedMul(scale_mtof, mtof_zoommul); scale_ftom = FixedDiv(FRACUNIT, scale_mtof);
if (scale_mtof < min_scale_mtof) AM_minOutWindowScale(); else if (scale_mtof > max_scale_mtof) AM_maxOutWindowScale(); else AM_activateNewScale(); }
// // // void AM_doFollowPlayer(void) {
if (f_oldloc.x != plr->mo->x || f_oldloc.y != plr->mo->y) { m_x = FTOM(MTOF(plr->mo->x)) - m_w/2; m_y = FTOM(MTOF(plr->mo->y)) - m_h/2; m_x2 = m_x + m_w; m_y2 = m_y + m_h; f_oldloc.x = plr->mo->x; f_oldloc.y = plr->mo->y;
// m_x = FTOM(MTOF(plr->mo->x - m_w/2)); // m_y = FTOM(MTOF(plr->mo->y - m_h/2)); // m_x = plr->mo->x - m_w/2; // m_y = plr->mo->y - m_h/2;
}
}
// // // void AM_updateLightLev(void) { static nexttic = 0; //static int litelevels[] = { 0, 3, 5, 6, 6, 7, 7, 7 }; static int litelevels[] = { 0, 4, 7, 10, 12, 14, 15, 15 }; static int litelevelscnt = 0;
// Change light level if (amclock>nexttic) { lightlev = litelevels[litelevelscnt++]; if (litelevelscnt == sizeof(litelevels)/sizeof(int)) litelevelscnt = 0; nexttic = amclock + 6 - (amclock % 6); }
}
// // Updates on Game Tick // void AM_Ticker (void) {
if (!automapactive) return;
amclock++;
if (followplayer) AM_doFollowPlayer();
// Change the zoom if necessary if (ftom_zoommul != FRACUNIT) AM_changeWindowScale();
// Change x,y location if (m_paninc.x || m_paninc.y) AM_changeWindowLoc();
// Update light level // AM_updateLightLev();
}
// // Clear automap frame buffer. // void AM_clearFB(int color) { memset(fb, color, f_w*f_h); }
// // Automap clipping of lines. // // Based on Cohen-Sutherland clipping algorithm but with a slightly // faster reject and precalculated slopes. If the speed is needed, // use a hash algorithm to handle the common cases. // boolean AM_clipMline ( mline_t* ml, fline_t* fl ) { enum { LEFT =1, RIGHT =2, BOTTOM =4, TOP =8 };
register outcode1 = 0; register outcode2 = 0; register outside;
fpoint_t tmp; int dx; int dy;
#define DOOUTCODE(oc, mx, my) \ (oc) = 0; \ if ((my) < 0) (oc) |= TOP; \ else if ((my) >= f_h) (oc) |= BOTTOM; \ if ((mx) < 0) (oc) |= LEFT; \ else if ((mx) >= f_w) (oc) |= RIGHT;
// do trivial rejects and outcodes if (ml->a.y > m_y2) outcode1 = TOP; else if (ml->a.y < m_y) outcode1 = BOTTOM;
if (ml->b.y > m_y2) outcode2 = TOP; else if (ml->b.y < m_y) outcode2 = BOTTOM;
if (outcode1 & outcode2) return false; // trivially outside
if (ml->a.x < m_x) outcode1 |= LEFT; else if (ml->a.x > m_x2) outcode1 |= RIGHT;
if (ml->b.x < m_x) outcode2 |= LEFT; else if (ml->b.x > m_x2) outcode2 |= RIGHT;
if (outcode1 & outcode2) return false; // trivially outside
// transform to frame-buffer coordinates. fl->a.x = CXMTOF(ml->a.x); fl->a.y = CYMTOF(ml->a.y); fl->b.x = CXMTOF(ml->b.x); fl->b.y = CYMTOF(ml->b.y);
DOOUTCODE(outcode1, fl->a.x, fl->a.y); DOOUTCODE(outcode2, fl->b.x, fl->b.y);
if (outcode1 & outcode2) return false;
while (outcode1 | outcode2) { // may be partially inside box // find an outside point if (outcode1) outside = outcode1; else outside = outcode2; // clip to each side if (outside & TOP) { dy = fl->a.y - fl->b.y; dx = fl->b.x - fl->a.x; tmp.x = fl->a.x + (dx*(fl->a.y))/dy; tmp.y = 0; } else if (outside & BOTTOM) { dy = fl->a.y - fl->b.y; dx = fl->b.x - fl->a.x; tmp.x = fl->a.x + (dx*(fl->a.y-f_h))/dy; tmp.y = f_h-1; } else if (outside & RIGHT) { dy = fl->b.y - fl->a.y; dx = fl->b.x - fl->a.x; tmp.y = fl->a.y + (dy*(f_w-1 - fl->a.x))/dx; tmp.x = f_w-1; } else if (outside & LEFT) { dy = fl->b.y - fl->a.y; dx = fl->b.x - fl->a.x; tmp.y = fl->a.y + (dy*(-fl->a.x))/dx; tmp.x = 0; }
if (outside == outcode1) { fl->a = tmp; DOOUTCODE(outcode1, fl->a.x, fl->a.y); } else { fl->b = tmp; DOOUTCODE(outcode2, fl->b.x, fl->b.y); } if (outcode1 & outcode2) return false; // trivially outside }
return true; } #undef DOOUTCODE
// // Classic Bresenham w/ whatever optimizations needed for speed // void AM_drawFline ( fline_t* fl, int color ) { register int x; register int y; register int dx; register int dy; register int sx; register int sy; register int ax; register int ay; register int d;
static fuck = 0;
// For debugging only if ( fl->a.x < 0 || fl->a.x >= f_w || fl->a.y < 0 || fl->a.y >= f_h || fl->b.x < 0 || fl->b.x >= f_w || fl->b.y < 0 || fl->b.y >= f_h) { fprintf(stderr, "fuck %d \r", fuck++); return; }
#define PUTDOT(xx,yy,cc) fb[(yy)*f_w+(xx)]=(cc)
dx = fl->b.x - fl->a.x; ax = 2 * (dx<0 ? -dx : dx); sx = dx<0 ? -1 : 1;
dy = fl->b.y - fl->a.y; ay = 2 * (dy<0 ? -dy : dy); sy = dy<0 ? -1 : 1;
x = fl->a.x; y = fl->a.y;
if (ax > ay) { d = ay - ax/2; while (1) { PUTDOT(x,y,color); if (x == fl->b.x) return; if (d>=0) { y += sy; d -= ax; } x += sx; d += ay; } } else { d = ax - ay/2; while (1) { PUTDOT(x, y, color); if (y == fl->b.y) return; if (d >= 0) { x += sx; d -= ay; } y += sy; d += ax; } } }
// // Clip lines, draw visible part sof lines. // void AM_drawMline ( mline_t* ml, int color ) { static fline_t fl;
if (AM_clipMline(ml, &fl)) AM_drawFline(&fl, color); // draws it on frame buffer using fb coords }
// // Draws flat (floor/ceiling tile) aligned grid lines. // void AM_drawGrid(int color) { fixed_t x, y; fixed_t start, end; mline_t ml;
// Figure out start of vertical gridlines start = m_x; if ((start-bmaporgx)%(MAPBLOCKUNITS<<FRACBITS)) start += (MAPBLOCKUNITS<<FRACBITS) - ((start-bmaporgx)%(MAPBLOCKUNITS<<FRACBITS)); end = m_x + m_w;
// draw vertical gridlines ml.a.y = m_y; ml.b.y = m_y+m_h; for (x=start; x<end; x+=(MAPBLOCKUNITS<<FRACBITS)) { ml.a.x = x; ml.b.x = x; AM_drawMline(&ml, color); }
// Figure out start of horizontal gridlines start = m_y; if ((start-bmaporgy)%(MAPBLOCKUNITS<<FRACBITS)) start += (MAPBLOCKUNITS<<FRACBITS) - ((start-bmaporgy)%(MAPBLOCKUNITS<<FRACBITS)); end = m_y + m_h;
// draw horizontal gridlines ml.a.x = m_x; ml.b.x = m_x + m_w; for (y=start; y<end; y+=(MAPBLOCKUNITS<<FRACBITS)) { ml.a.y = y; ml.b.y = y; AM_drawMline(&ml, color); }
}
// // Determines visible lines, draws them. // This is LineDef based, not LineSeg based. // void AM_drawWalls(void) { int i; static mline_t l;
for (i=0;i<numlines;i++) { l.a.x = lines[i].v1->x; l.a.y = lines[i].v1->y; l.b.x = lines[i].v2->x; l.b.y = lines[i].v2->y; if (cheating || (lines[i].flags & ML_MAPPED)) { if ((lines[i].flags & LINE_NEVERSEE) && !cheating) continue; if (!lines[i].backsector) { AM_drawMline(&l, WALLCOLORS+lightlev); } else { if (lines[i].special == 39) { // teleporters AM_drawMline(&l, WALLCOLORS+WALLRANGE/2); } else if (lines[i].flags & ML_SECRET) // secret door { if (cheating) AM_drawMline(&l, SECRETWALLCOLORS + lightlev); else AM_drawMline(&l, WALLCOLORS+lightlev); } else if (lines[i].backsector->floorheight != lines[i].frontsector->floorheight) { AM_drawMline(&l, FDWALLCOLORS + lightlev); // floor level change } else if (lines[i].backsector->ceilingheight != lines[i].frontsector->ceilingheight) { AM_drawMline(&l, CDWALLCOLORS+lightlev); // ceiling level change } else if (cheating) { AM_drawMline(&l, TSWALLCOLORS+lightlev); } } } else if (plr->powers[pw_allmap]) { if (!(lines[i].flags & LINE_NEVERSEE)) AM_drawMline(&l, GRAYS+3); } } }
// // Rotation in 2D. // Used to rotate player arrow line character. // void AM_rotate ( fixed_t* x, fixed_t* y, angle_t a ) { fixed_t tmpx;
tmpx = FixedMul(*x,finecosine[a>>ANGLETOFINESHIFT]) - FixedMul(*y,finesine[a>>ANGLETOFINESHIFT]);
*y = FixedMul(*x,finesine[a>>ANGLETOFINESHIFT]) + FixedMul(*y,finecosine[a>>ANGLETOFINESHIFT]);
*x = tmpx; }
void AM_drawLineCharacter ( mline_t* lineguy, int lineguylines, fixed_t scale, angle_t angle, int color, fixed_t x, fixed_t y ) { int i; mline_t l;
for (i=0;i<lineguylines;i++) { l.a.x = lineguy[i].a.x; l.a.y = lineguy[i].a.y;
if (scale) { l.a.x = FixedMul(scale, l.a.x); l.a.y = FixedMul(scale, l.a.y); }
if (angle) AM_rotate(&l.a.x, &l.a.y, angle);
l.a.x += x; l.a.y += y;
l.b.x = lineguy[i].b.x; l.b.y = lineguy[i].b.y;
if (scale) { l.b.x = FixedMul(scale, l.b.x); l.b.y = FixedMul(scale, l.b.y); }
if (angle) AM_rotate(&l.b.x, &l.b.y, angle); l.b.x += x; l.b.y += y;
AM_drawMline(&l, color); } }
void AM_drawPlayers(void) { int i; player_t* p; static int their_colors[] = { GREENS, GRAYS, BROWNS, REDS }; int their_color = -1; int color;
if (!netgame) { if (cheating) AM_drawLineCharacter (cheat_player_arrow, NUMCHEATPLYRLINES, 0, plr->mo->angle, WHITE, plr->mo->x, plr->mo->y); else AM_drawLineCharacter (player_arrow, NUMPLYRLINES, 0, plr->mo->angle, WHITE, plr->mo->x, plr->mo->y); return; }
for (i=0;i<MAXPLAYERS;i++) { their_color++; p = &players[i];
if ( (deathmatch && !singledemo) && p != plr) continue;
if (!playeringame[i]) continue;
if (p->powers[pw_invisibility]) color = 246; // *close* to black else color = their_colors[their_color]; AM_drawLineCharacter (player_arrow, NUMPLYRLINES, 0, p->mo->angle, color, p->mo->x, p->mo->y); }
}
void AM_drawThings ( int colors, int colorrange) { int i; mobj_t* t;
for (i=0;i<numsectors;i++) { t = sectors[i].thinglist; while (t) { AM_drawLineCharacter (thintriangle_guy, NUMTHINTRIANGLEGUYLINES, 16<<FRACBITS, t->angle, colors+lightlev, t->x, t->y); t = t->snext; } } }
void AM_drawMarks(void) { int i, fx, fy, w, h;
for (i=0;i<AM_NUMMARKPOINTS;i++) { if (markpoints[i].x != -1) { // w = SHORT(marknums[i]->width); // h = SHORT(marknums[i]->height); w = 5; // because something's wrong with the wad, i guess h = 6; // because something's wrong with the wad, i guess fx = CXMTOF(markpoints[i].x); fy = CYMTOF(markpoints[i].y); if (fx >= f_x && fx <= f_w - w && fy >= f_y && fy <= f_h - h) V_DrawPatch(fx, fy, FB, marknums[i]); } }
}
void AM_drawCrosshair(int color) { fb[(f_w*(f_h+1))/2] = color; // single point for now
}
void AM_Drawer (void) { if (!automapactive) return;
AM_clearFB(BACKGROUND); if (grid) AM_drawGrid(GRIDCOLORS); AM_drawWalls(); AM_drawPlayers(); if (cheating==2) AM_drawThings(THINGCOLORS, THINGRANGE); AM_drawCrosshair(XHAIRCOLORS);
AM_drawMarks();
V_MarkRect(f_x, f_y, f_w, f_h);
} // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // AutoMap module. // //-----------------------------------------------------------------------------
#ifndef __AMMAP_H__ #define __AMMAP_H__
// Used by ST StatusBar stuff. #define AM_MSGHEADER (('a'<<24)+('m'<<16)) #define AM_MSGENTERED (AM_MSGHEADER | ('e'<<8)) #define AM_MSGEXITED (AM_MSGHEADER | ('x'<<8))
// Called by main loop. boolean AM_Responder (event_t* ev);
// Called by main loop. void AM_Ticker (void);
// Called by main loop, // called instead of view drawer if automap active. void AM_Drawer (void);
// Called to force the automap to quit // if the level is completed while it is up. void AM_Stop (void);
#endif //----------------------------------------------------------------------------- // // $Log:$ // //-----------------------------------------------------------------------------
* TODO: see below, and in the "TODO" file. Enjoy!
Mon Dec 22 20:29:16 1997 <[email protected]>
* CVS logs and other obsolete stuff removed. Anybody who wants to keep some revision control now has a clean slate to start with.
Mon Dec 22 19:53:34 1997 <[email protected]>
* i_sound.c: enabled SNDSERV, as SNDINTR for some reason just gives ghastly results e.g. on E4M2. Frankly, I am at a loss. SNDSERV is now default, until the internal sound driver is a bit more reliable. Note that the current redundancy means that changes like the one below will have to be propagated manually to the soundserver sources.
* m_menu.c: the 4th episode is now removed with the original doom.wad. You need to rename the Ultimate DOOM/Special Edition retail IWAD to doomu.wad now, or you won't see the 4th episode in the menu. The compile time SPECIAL define is thus gone.
Mon Dec 22 17:08:33 1997 <[email protected]>
* v_video.c (V_DrawPatch): another last minute hack. While shareware, retail, commercial, and plutonia (being a full DOOM2 IWAD) seem to work okay now, TNT gives an error on finishing the first mission: "Patch at -35, -5 exceeds LFB". I changed the error abort into a simple return, thus the patch is ignored. The intermission screen seems to come up okay. * TODO: check which patch, and whether it is an IWAD problem.
* i_sound.c: the sound table is hardwired in sounds.h/sounds.c. As our current crude sound handling simply loads *all* sounds at startup, we are going to miss some with DOOM1 WAD files. I could skip them, but decided to load a placeholder instead (dspistol). It might be good to use a distinct default sound for WAD debug purposes. A zero length sound lump would work, but would not be noticeable. Anyway, shareware and retail work now. * TODO: implement proper handling for missing lumps, sound and otherwise. Perhaps move sound table into WAD?
* g_game.c (G_DoPlayDemo): finally removed the annoying "Demo is from a different game version" abort. It now simply declines to playback the demo, and waits for user input on some do_nothing screen.
* doomdef.h&Cie.: Lesson of the day - do not replace a bunch of booleans with an enum and use the same identifiers. Point in case: "if ( commercial )" will not give an error, and will always be true as long as the enum value is greater than zero. I found that the DOOM2 vs. DOOM differences are everywhere (weapons, monsters, doors). Number of episodes varies from shareware/commercial to registered to retail, while commercial has a unique set (two of them, counting the german edition) of maps in one episode. Plus, TNT and Plutonia add some TITLE strings to the mixture. Well, Plutonia and TNT are treated as DOOM2 for now, so you will miss the startup message.
* wi_stuff.h (NUMEPISODES): removed SPECIAL switch. It is no 4 times 9 for wi_stuff.c internal static arrays - doesn't matter. * TODO: unified handling with DOOM 2 - dynamic allocation of arrays.
* i_sound.c (I_UpdateSound): okay, I separated the mixing, now done synchonously, along with a flag signalling the timer that the mixing buffer has been updated. The handler is now very short, and I tried several intervals down to 50usecs, w/o complaints. Now the man page says: "system timer resolution currently 10ms". Odd. Anyway, while the double shotgun/plasma rapid fire problem seems to be a bit less disturbing at higher refresh, it's still there. I set the interval to 500usec, which is sufficient for avoiding any buffer update misses. Conclusion after just two days of experimentation: yep, sound driver code isn't fun at all.
As for the bug - well, Dave Taylor suggested close distance getting into a divide-by-near-zero situation, screwing up the volume. I can't figure why latency of an external sound driver or screen size affect this, but I am running out of ideas. * i_sound.c: Some more experimentation with the timer driven sound. It doesn't work well using an intervall of less then 30 msecs - there will be artifacts with say 50 msecs. This is pretty obvious with a target frame rate of at least 30fps, methinks. Using the REAL/SIGALRM timer with 30msec gets rid of the artifacts, it seems - at the expense of slowing down things on a P133 to a noticeable jerkiness. Bah.
Mon Dec 22 00:36:54 1997 <[email protected]>
* info.c: and i_video.c and i_sound.c - don't ask me why some Linux header files are different with gcc vs. g++, or what the complaint about the g++ complaint info.c state table is all about: "initializer element for `states[..].action.acp1' is not constant" Undid some changes, compiled with gcc, playtested, seems okay. Done for today... yesterday.
* i_net.c (ntohl): okay, htons/htonl, ntohs,ntohl are back to haunt me. Copied the macros that on my box aren't used for whatever reason directly into the source. Got rid of all other multiple and undefined references. CC=g++ now compiles (still many warnings) and links, but the binary dumps a core after Init PlayLoop. So be it.
Sun Dec 21 12:38:08 1997 <[email protected]>
* p_enemy.c (P_NewChaseDir): changed tdir to int, removed the LUTs - spurious locks were due to endless loops created by boneheaded predecessor map. Has to be a better way to do enum dirtype_t anyway. Problem seems to be fixed.
* CC=gcc again, this time loads of #includes to fix "implicit declarations, and one or two unused variables. DOOM now compiles without any -Wall warnings left, as C.
* Bug: compiled the reworked code with gcc. Within a solid while of testing and blasting away, it locked once. Got a core, which gdb doesn't grok. Bah.
* TODO: okay, linkage of g++ build modules give loads of errors, because we have many implicits, plus missing #pragma implementation causing multiple definitions. Yet, this is the very first time DOOM was compiled as C++ without a parsing error. So there. * sounds.c: included doomtype.h and removed yet another enum { false, true } definition.
* p_saveg.c (misc): several. * p_mobj.c (P_SpawnMobj): (actionf_p1)P_MobjThinker * p_spec.c (EV_DoDonut): (action_p1) T_MoveFloor (twice). * p_plats.c (EV_DoPlat): (actionf_p1) T_PlatRaise. * p_plats.c (EV_StopPlat): (actionf_v)NULL. * p_plats.c (P_ActivateInStasis): same * p_lights.c (P_SpawnGlowingLight): (actionf_p1) T_Glow. * p_lights.c (P_SpawnStrobeFlash): (actionf_p1) T_StrobeFlash. * p_lights.c (P_SpawnLightFlash): (actionf_p1) T_LightFlash. * p_lights.c (P_SpawnFireFlicker): (actionf_p1) T_FireFlicker. * p_floor.c (EV_DoFloor): (actionf_p1) T_MoveFloor. * p_floor.c (EV_BuildStairs): same (twice). * p_doors.c (EV_VerticalDoor): (actionf_p1)T_VerticalDoor. * p_doors.c (P_SpawnDoorCloseIn30): same * p_doors.c (P_SpawnDoorRaiseIn5Mins): same * p_doors.c (EV_DoDoor): same * p_ceilng.c (EV_CeilingCrushStop): (actionf_v)NULL. * p_ceilng.c (EV_DoCeiling): (actionf_p1)T_MoveCeiling. * p_ceilng.c (P_ActivateInStasisCeiling): same. These gave g++ errors, but have been ignored by gcc.
* r_data.c (R_PrecacheLevel): (actionf_p1)P_MobjThinker.
* p_saveg.c: conversions (actionf_p1)T_Whatever.
* p_tick.c: cast (actionf_v)(-1).
* p_telept.c: yet another (actionf_p1)P_MobjThinker. * p_mobj.c (P_MobjThinker): cast (actionf_v)(-1). * TODO: decent NOP/NULL/Nil function pointer. I'd introduce a global A_NOP() function that chokes up an error message. Why -1 instead of NULL?
* p_enemy.c: conversions (actionf_p1)P_MobjThinker.
* d_think.h/info.h: think_t is essentially the same action function pointer stuff. I moved the definitions from info.h to d_think.h, and aliased them with a typedef. Now more changes needed.
* p_enemy.c (successor, predecessor): new LUT, to provide increments/decrements for enum dirtype_t, as g++ complaints: "no post-increment/decrement operator for type"
* Makefile (CC): okay, tried "g++" once more. A few errors (above). Plus shitloads of warnings (obviously, better "unused" checking with C++, lots of the usual int2enum suspects, implicit declarations, the works).
* p_mobj.c: action.acp1 used accordingly. * p_pspr.c: action.acp2 used accordingly. * TODO: info.c:144 warning "missing braces around initializer for `states[0].action'" * info.h/info.c: some experimental stuff on action function pointers. * TODO: still some sound glitches at startup. * i_sound.c: few more cleanups. Made mixing use channel loop instead of unroll, set mixbuffer to zero ot start. Removed some more DOS leftovers (8bit), kept some as comment.
* hu_stuff.c (HU_Start): More gamemode changes. As in d_main.c, I decided to use DOOM2 as default whenever one needed - it was sold most, and had the superset of items, enemies and monsters.
* TODO: the handling of WAD specific messages like HU_TITLE, HU_TITLE2, HU_TITLEP etc. should definitely be removed.
* d_main.c (CheckBetaTest): Removed outdated, DOS specific BETATEST stuff. d_main.c (IdentifyVersion): Numerous changes to gamemode handling.
* TODO: currently, french language is enabled by detecting an doom2f.wad - yet it needs FRENCH define at compile time. I removed most language stuff, and propose handling that at runtime, using a switch in the config file. Well, mission specific texts won't work outside the WAD anyway.
* TODO: along the same lines: I suggest removing the misc. devparm switches as well - lots of redundancy not needed anymore.
* Makefile: finally added a doomstat.c for all the global state variables listing internal engine configuration. Right now, these are scattered everywhere. Declaration to be found in doomstat.h header.
* f_finale.c (F_StartFinale): Reworked the entire finale handling based on game mode enum.
* doomstat.h: Global variables for game mode and language. Removed old booleans.
* doomdef.h: GameMode_t and Language_t enum added. Boolean for language was kinda limiting to 2 alternatives (french, english), and five boolean plus #define SPECIAL for game version is just ugly. * wi_stuff.h: SPECIAL switch compiles two different EXE's, one for 3 episodes of 9 maps each (DOOM 1 registered), one for 4 episodes of 9 maps each (DOOM 1 retail/FinalDOOM). Implicitely, the DOOM2 config (one episode, 34 missions) is handled. How is the german edition (32 missions only) done? Frankly, this is a mess. The problem is that intermission (animated as in DOOM 1, simple backdrop as in DOOM2) as well as certain items (double shotgun) as well as certain rendering stuff (sky texture) depend on this.
Plus, it ties into runtime flags as "commercial" as well. Yuck. Each change will change the game. Postponed.
* d_net.c,m_misc.c: removed last two NeXT remains.
* d_englsh.h,d_french.h,d_main.c,m_misc.c,r_draw.c,v_video.c: more WATCOM remains removed. Kept some stuff that handeld the blocky mode/detailshift in DOS, which is n.a. in Linux - but probably not worth fixing.
Sat Dec 20 15:16:51 1997 <[email protected]>
* Bug: core dump when using doom.wad or doom1.wad without a "-file UNUSED/doom2.wad". Version dependend handling of stuff (double shotgun) comes to mind.
* doomdef.h: SNDSERV enables external sound server support. SNDINTR enables internal sound output with timer (asynchronous). Default is internal, synchronous.
* i_sound.c (I_HandleSoundTimer): Okay, the plasma/double shotgun sound bug (crapyy sund when firing nose-to-wall) is obviously a problem with blocking at refresh - smaller screen size makes it go away. I won't do threads w/o a proper gdb, and I can't do whatever Dave Taylor did with LinuxQuake w/o the sources, thus I broke down and implemented a timer based solution. Seems to work fine, given the fact that this is the first time ever I implemented sound handling.
Fri Dec 19 10:02:48 1997 <[email protected]>
* m_menu.c/i_sound.c/s_sound.c: Removed a few more inconsistencies due to old internal sound handling (DOS), external (Linux sndserver), and new internal (the unfinished merge of both the former). The Options/Sound/Music volume menu is accessible now. It was due to an internal scaling of the menu (effective range 0-15), up to 0..120, by multiply with 8 scattered all over the place, that we got a v_video.c: I_Error ("Bad V_DrawPatch") Now I am using the menu resolution everywhere, and scaling should only be done in the actual mixing/output. * OK, obviously this hasn't been updated in months. This is because: a) most of the time nothing happened, and b) when something got done, it was too much to keep track of it by CVS and/or ChangeLog.
Basically, what happened in the meantime is that I did not find a publisher who believed that the book sales would be worth doing it. Within the limited amount of time that I could dedicate to a project that will not generate any revenue whatsoever, I spent some time on cleaning up the Linux code base which works, essentially. I might or might not be able to participate in a Mesa+Voodoo+Glide based GLDOOM port for Linux. I won't waste a minute on Win32 without getting paid for it.
Because of the legal issues involved with the DMX sound library id licensed for DOS DOOM, Linuxdoom is the only code base that has sound support at all. Other UNIX ports (SGI, Sun) could probably be revived and integrated w/o too many problems. There is no Win32 port - I never had access to WinDOOM or Jim Dose's GLDOOM sources. There is no Linux OpenGL (read: Mesa) support yet - that'd involve internal changes which will best be done after a public source release.
John Carmack opted for a release of the Linux code. I have removed all DMX references I could get a hold of, but preserved some of the original sound handling within DOOM that interfaced with DMX. Linuxdoom (like previous UNIX ports) used a separate sound server binary. I did some work on putting the sound server module back into the engine. It works, but shutdown (pending sounds), and sound output parallel to refresh (blocking) is crappy, and there is a problem with double shotgun and plasma at close distance (as well as with lots of other noises going on). As the mixing code is identical to the separate soundserver, and as it doesn't seem to be a blocking issue, I am currently at a loss - I wonder whether the IPC communication with the soundserver process introduced a delay that changed behaviour, or whether I simply overlooked a bug. I am currently lacking the time to track this down, so I am keeping both internal and soundserver source.
I did remove DOS and Watcom specifics. I did also remove the texture mapping and fixed point assembly. From my experience, it isn't worth the trouble to ue GCC inline assembler, as performance of the same loop written in C is perfectly sufficient. On demand I will put both assembly modules into some documentation, as they are probably of historic interest.
There is no Sun DGA, Irix, or other non-Linux stuff in this code base (at least, not intentionally). They will be back when ports to other UNIX environments will be merged back (I can't do testing, and the modules were separate and not consistent, so I refrained from wasting time on this prior to a public release).
While I made only minor changes to the actual code (some fixes, some cleaning up of SHM and audio), I did a huge amount of shuffling around. I introduced many more header files and modules, some of them laughably small (doing these changes is bound to screw up CVS, so no CVS record anymore for the time being). I would introduce even more separation if I had the time. Splitting the animation/AI/behaviour code that defines "DOOM - The Game" into a separate game.so (like Quake2 does) should definitely be done. Separating a ref_soft.so aka "DOOM - The Engine", and defining a clean interface prior to introducing a ref_gl.so is recommended as well.
I am going to purge some more leftovers, remove the obsolete CVS history except for comments, and try to clean up the last "implicit declaration" and "unused variable" warnings. Except for enabling cheats in nightmare (to have more fun while testing), I did not change the game mechanics at all. I would strongly advise against doing so w/o the proper separations suggested above. I will not waste time on fixing detail and blocky mode, lack of resize, or other stuff that it better addressed by a proper GLDOOM port.
Sat Aug 16 08:07:16 1997 <[email protected]>
* p_pspr.c: Moved the sprite animation stuff from doomdef.h here.
* info.h: Added #ifndef __INFO__ for multiple inclusion. I am not going to deal with multigen, or changing the original DOOM monster animation anyway.
* p_spec.h/c: Moved anim_t etc., locally used only. There is another anim_t in wi_stuff.h/c, now local as well, so collisions on header inclusion should not occur. #include "doomdef.h" #include "doomstat.h" these should now be topmost includes. * doomstat.h, doomdef.h, wi_stuff.h, d_player.h: I moved wbstartstruct_t to d_player.h, and wminfo to doomstat.h. Basically, I will try to move all global state related stuff into doomstat.h, and all data structures defined for state variables into doomdef.h - this will be kinda greek tragedy, and never finished, but a body can try.
* wi_stuff.h/c, wi_data.h: Removed wi_data.h, put all local stuff blah... see below. I have found several unused global variables, started outcommenting them with //U, will remove them later. It might be Watcom/PC stuff, or somebody put the actual numbers into the implementation instead of using STARDIST, ANIMPERIOD & Cie. * st_stuff.h/c: from doomdef.h, local stuff moved into st_stuff.c, etc. In the current revisions, I am tolerating warnings of the "implicit declaration" kind - the linker resolves the stuff, and it will be handy in unmangling the modules once the headers contain only the globally visible stuff.
* am_map.h/c, am_data.h: Removed am_data.h, put all local stuff into am_map.c, moved globally needed headers from doomdef.h into am_map.h.
* p_saveg.h, p_setup.h, p_tick.h: created, stuff from doomde.h moved there
* d_main.c, d_net.c, doomdef.h: Decided to dump mprintf, as only needed for Watcom support which is not going to happen.
* doomdef.h: Moved function prototypes to appropriate headers: d_main.h, d_net.h.
Fri Aug 15 16:38:53 1997 <[email protected]>
* doomstat.h: added a few more comments, regrouped some of the state variables.
* doomdata.h: added a few more comments.
Thu Aug 14 10:38:37 1997 <[email protected]>
* g_game.c (G_DoLoadLevel): copied the skyflatnum determination here, from the R_InitSkyMap - once should be sufficient.
* Makefile, r_sky.h/c: added r_sky module. The sky handling was scattered over r_bsp, r_main, r_plane, doomstat.h...
* r_bsp.c, r_main.c, r_segs.c: Removed RD_* calls from R_debug.m, NeXT switches.
* r_local.h: Removed the R_debug.m NeXT specific debugging code headers. Removed "drawbsp" flag from here, and r_main.c, too.
* r_data.c: Started to remove NORMALUNIX switches, using LINUX instead. Basically, different UNIX platforms using the same code should simply be ANDed in the #ifdef switches.
* r_draw.c: Removed some more, but not all WATCOMC support. There is an unresolved problem with the fuzzy blitting in the lowres (blocky) modes - either the "detailshift" flag triggered lowres mode will be removed, or the bug has to be fixed.
* r_bsp.h, r_draw.h, r_things.h, r_data.h, r_segs.h, r_main.h, r_plane.h: Created from r_local.h. * Back to work. Till March 22nd, a lot of source shuffling and addition of new header files, separating stuff, and creating new, smaller modules. Some Watcom/PC/DMX/NeXT etc. related stuff got removed, but not all (yet). None of this ended up in the Log (sorry) or the revision control (CVS is not well suited while number of files and respective names change a lot, especially if stuff gets deleted and/or re-introduced). Major change: part of the sound code got copied from the separate Linux sndserver sources to the linuxdoom source. Re-integration and removal of sndserver pending. Nothing of importance happend since then (priorities).
Mon Feb 3 16:41:05 1997 <[email protected] ()>
* m_misc.c: Created m_argv, m_random and m_bbox, kept remains in m_misc for the time being. Misc. files changed to include only necessary modules. Moved bbox definitions from doomdata.h.
* m_menu.h: Created from doomdef.h. Misc. changes in dependend modules. I am not going to list every affected file from now on. See Log entries within each file.
* dstrings.h: Now handles multi-language support and switches. So far, only english (default) and french are available.
* d_englsh.h: Created from dstrings.h.
* g_game.h: Created, from doomdef.h.
* am_map.c, st_stuff.c, wi_stuff.c: * Makefile: Added m_cheat, removed dutils. Doubly linked list stuff unused.
* m_cheat.h, m_cheat.c: Created, basci cheat string scrambling and check, from dutils.h and dutils.c.
* doomdef.h Moved screen declaration to v_video.h.
* dutils.h, dutils.c Remode code for f_wipe.h and f_wipe.c.
* Makefile * d_main.c, Added f_wipe files.
* f_wipe.h, f_wipe.c: Created, screen wipe/melt at mission begin, from dutils.h and dutils.c.
* d_textur.h: Created from doomdata.h. Separates all the patch/texture defintions. Needed for v_video module.
* r_local.h, wi_stuff.h, st_lib.h, hu_lib.h: * i_x.c, d_main.c, m_menu.c, m_misc.c: Added v_video.h.
* v_video.h: Created. Using headers from doomdef.h. Forward of patch_t. Moved bool and byte to doomtype.h.
Thu Jan 30 20:50:16 1997 <[email protected] ()>
* doomtype.h: Created, for fixed_t. Should add angle_t here, too.
* tables.c: Added SlopeDiv from r_main.c, added all defines and typedefs related to basic trig table use here, removed it. Currently "tables.h" is included in doomdef.h and r_local.h, too. This is not too cleanly separated, but we have to start somewhere, right?
* tables.h: Created from doomdef.h. Note that tables.c had fixed size tables, while doomdef.h calculated from the value of FINEANGLES. In addition, entries were given as either "int" or "fixed_t". Bad boys.
* z_zone.c: * s_sound.c: * hu_stuff.c: * st_lib.c, st_stuff.c: * wi_stuff.c: * w_wad.c: * r_things.c, r_plane.c, r_draw.c, r_data.c: * p_tick.c, p_mobj.c, p_spec.c, p_setup.c, p_lights.c, p_plats.c, p_floor.c, p_doors.c, p_ceilng.c: * am_map.c: * m_misc.c, m_menu.c: * g_game.c: * d_main.c: * f_finale.c: Added #include "z_zone.h".
* z_zone.h: Created, from stuff in doomdef.h
* CVS checkin. Reformatting run, last one. Took a week to go through all the sources, w/o even looking to closely.
* st_stuff.c (ST_Responder): Removed a first tiny bit of redundancy (NO_CLIP checks). Should remove idspispod completely, later.
Wed Jan 29 19:53:43 1997 <[email protected] ()>
* Another one, while we are on it. All S (Sound) files.
* CVS checkin. Reformatting run, all R (Refresh) files.
* r_draw.c (R_DrawSpanLow): The non-Watcom, non-asm lowres mode was just a copy of the default mode. As detailshift was used to scale the image down, lowres mode just filled the left half of the buffer. * r_draw.c (R_DrawColumnLow): Tried the same hack for walls, horribly broken. Postponed.
Tue Jan 28 19:32:48 1997 <[email protected] ()>
* CVS checkin. Another reformatting run. Did all P files.
* p_spec.c: P_FindNextHighestFloor The number of adjoining sectors is limited to 20, because of a temporary LUT needed for determining lowest height in adjacent sectors. No overflow checking is done.
Sun Jan 26 08:41:21 1997 <[email protected] ()>
* Another CVS checkin of a formatting run. D,F,G,HU,I,M have been changed.
* Note: in initial and current release, linuxxdoom -3 -file plutonia.wad, idclev 12 produces a Segmentation fault.
Wed Jan 22 14:03:00 1997 <[email protected] ()>
* m_menu.c: initializer-string for array of chars is too long (skullName) warning: unused parameter `int choice' (a couple of times)
* Attempt to compile as C++. Loads of warnings, a couple of errors. p_enemy.c (P_Move): r_things.c (R_ProjectSprite) `catch', `throw', and `try' are all C++ reserved words, thus changed "try" to "try_ok". Fixed. p_pspr.c: In function `void P_SetPsprite(struct player_s *, ... )': too many arguments to function No convenient fix - state->action is declared void action(), but called w/o, with one, or with two parameters. There are more like this. Going to be a tough one. Union of pointers? Postponed.
r_plane.c: In function `void R_DrawPlanes()': s_sound.c: In function `int S_AdjustSoundParams(struct mobj_s *, .. )': p_map.c: In function `bool PIT_StompThing(struct mobj_s *)': p_maputl.c: In function `int P_AproxDistance(int, int)': r_main.c: In function `int R_PointToDist(int, int)': p_enemy.c: In function `void P_NewChaseDir(struct mobj_s *)': warning: implicit declaration of function `int abs(...)' <stdlib.h>
Wed Jan 22 12:15:00 1997 <[email protected] ()>
* CVS checkin of purification run. Sources now compile without any "-Wall" warnings.
* Note: with -file "tnt.wad", we get an "Error: Bad V_DrawPatch" abort each time we enter an exit. Invalid or missing intermission screen?
* Makefile (CFLAGS): added -Wall, first purification run.
d_main.c: In function `D_DoomMain': warning: implicit declaration of function `mkdir' <fcntl.h>
i_unix.c: In function `I_StartSound': warning: control reaches end of non-void function i_unix.c: In function `I_InitNetwork': warning: implicit declaration of function `inet_addr' <arpa/inet.h> i_unix.c: At top level: warning: `endianness' defined but not used
i_x.c: In function `I_Error': warning: unused variable `string' i_x.c: In function `I_GetEvent': warning: suggest parentheses around arithmetic in operand of | i_x.c: In function `I_FinishUpdate': warning: unused variable `bigscreen' i_x.c: In function `grabsharedmemory': warning: implicit declaration of function `getuid' <unistd.h> warning: unused variable `done' i_x.c: In function `I_InitGraphics': warning: suggest parentheses around assignment used as truth value warning: char format, different type arg (arg 3) warning: char format, different type arg (arg 5) warning: implicit declaration of function `XShmGetEventBase' i_x.c: In function `InitExpand2': warning: unused variable `jexp' warning: unused variable `iexp'
m_menu.c: In function `M_ReadSaveStrings': warning: implicit declaration of function `read' <sys/types.h> warning: implicit declaration of function `close' <unistd.h>
m_misc.c: In function `M_WriteFile': warning: implicit declaration of function `write' warning: implicit declaration of function `close' m_misc.c: In function `M_ReadFile': warning: implicit declaration of function `read' m_misc.c: In function `M_ScreenShot': warning: implicit declaration of function `access' <unistd.h>
p_pspr.c: In function `P_MovePsprites': suggest parentheses around assignment used as truth value
p_spec.c: In function `P_SpawnSpecials': warning: implicit declaration of function `atoi' <stdlib.h>
w_wad.c: In function `strupr': warning: implicit declaration of function `toupper' <ctype.h> w_wad.c: In function `W_AddFile': warning: implicit declaration of function `read' <sys/types.h> warning: implicit declaration of function `lseek' warning: implicit declaration of function `close' <unistd.h>
wi_stuff.c: In function `WI_loadData': warning: unused variable `pic' wi_stuff.c: At top level: warning: `background' defined but not used
Tue Jan 21 22:00:00 1997 <[email protected] ()>
* doomdata.h (__BYTEBOOL__): Use builtin ANSI C++ bool.
* d_main.c (IdentifyVersion): Bug fix: insufficient malloc created errors in malloc/realloc calls later on. Welcome to the risks of Copy'n'paste.
Tue Jan 21 13:20:05 1997 <[email protected] ()>
* First formatting checkin. A word of explanation: prior to making any changes to the source, a couple of formatting runs will be made, followed by some purification runs. For this run, the Emacs mode selection line has been changed to use C++ style indenting (cc-mode.el). Each file has been automatically reformatted using Emacs indent-region. A few files have been changed manually already (i.e., comments, use of tabs). Warning: using "diff" to compare files of different states during the reformatting will not give useful results.
* hu_stuff.c: fixed "assignment discard const", the last remaining error message with default compilation.
Sun Jan 19 14:27:06 1997 <[email protected] ()>
* Makefile: Minor fix for sndserver target, removed linuxsdoom target for the time being, added CVS header (kind of).
* Initial CVS checkin.
* soundsrv/irix/linux/sun.c: Changed includes (irix.h removed, soundsrv.h included).
* i_svga.c: Changed to DOS 8+3.
* soundsrv.h/c: Changed to DOS 8+3, included irix.h in soundsrv.h.
* r_local.h: Same for PI, include math.h with Linux.
* doomdef.h: Got rid of multiply defined warnings for Linux, included values.h.
* FILES2: created a commented list of all files, removed a few more files (sndserver test, NeXT leftovers, DMX header). Identified the following main modules (see FILES2): AM, HU, M, P, R, S, ST, W, WI. Some stuff is separate (Z, F), some not clearly separable (G, D). System specific interfaces are in I. Some of the latter replace i_main.c (i.e. the void/int main(argc,argv) call), e.g. SVGA, others (X11, SHM, DGA) don't. There is a certain amount of overlap, and the largest module (with possibly most overlap) is P - playing, i.e. all the games state and animation handling. Dithering is currently not used.
Sat Jan 18 15:14:41 1997 <[email protected] ()>
* r_draw.c: fixed !defined(USEASM) lines for R_DrawColumn/Span. Removed fpfunc.o/S from Makefile, now compiling X11 w/o any assembler. Got a running linuxxdoom again. We are in business. This source is going to be used for the initial CVS check in.
* Tried a quick hack compiling it as COFF a.out instead of ELF, with "gcc -b i486-linuxaout". Same linker errors. Tried removing -DUSE_ASM. Still using fpfunc.S.
* Tried linuxxdoom. Compile run: some warnings (redefinition of MAX/MIN SHORT/INT/LONG) in doomdef.h and (PI redefined) r_local.h. Link run: crashed, undefined references in d_main.c: undefined reference to `FixedDiv2' am_map.c: undefined reference to `FixedMul' r_main.c: undefined reference to `R_DrawColumn' r_main.c: undefined reference to `R_DrawSpan' r_plane.c: undefined reference to `FixedMul'
This stuff is defined in fpfunc.S (Fixed point) and in r_draw.c (assembler in tmap.S not used). However, "nm," shows that r_draw.o does not include the drawing functions (see below - USE_ASM). Furthermore, the global symbols in fpfunc.S begin with an underscore, "_FixedMul" and "_FixedDiv2".
More problems within fpfunc.o: undefined references to
`_dc_yl' `_dc_yh' `_ylookup' `_centery' `_dc_x' `_columnofs' `_dc_iscale' `_dc_texturemid' `_dc_source' `_dc_colormap'
`_ds_y' `_ds_x1' `_ds_x2' `_ds_xfrac' `_ds_yfrac' `_ds_xstep' `_ds_ystep' `_ds_colormap' `_ds_source'
Again, underscore problem. Note: tmap.S currently obsolete, as somebody pasted all the texture mapping assembly into fpfunc.S. Gotta clean that up.
* Created initial release from CD sources, created ChangeLog. Let the games begin.
************************************************************** DOOM source code ChangeLog file **************************************************************
/ChangeLog/1.14/Mon Feb 3 22:45:08 1997// /DOOMLIC.TXT/1.3/Sun Jan 26 07:44:56 1997// /FILES/1.1/Sun Jan 19 17:22:41 1997// /FILES2/1.1/Sun Jan 19 17:22:42 1997// /Makefile/1.6/Mon Feb 3 22:45:08 1997// /am_data.h/1.2/Tue Jan 21 18:59:56 1997// /am_map.c/1.4/Mon Feb 3 21:24:33 1997// /am_map.h/1.2/Tue Jan 21 18:59:56 1997// /d_englsh.h/1.1/Mon Feb 3 21:48:03 1997// /d_event.h/1.2/Mon Feb 3 22:01:47 1997// /d_french.h/1.3/Mon Feb 3 21:48:03 1997// /d_main.c/1.8/Mon Feb 3 22:45:09 1997// /d_net.c/1.3/Mon Feb 3 22:01:47 1997// /d_textur.h/1.1/Mon Feb 3 16:47:51 1997// /doomdata.h/1.5/Mon Feb 3 22:45:09 1997// /doomdef.h/1.9/Mon Feb 3 22:45:09 1997// /doomtype.h/1.2/Mon Feb 3 22:45:09 1997// /dstrings.h/1.4/Mon Feb 3 21:48:03 1997// /dutils.c/1.5/Mon Feb 3 17:11:23 1997// /dutils.h/1.4/Mon Feb 3 17:11:23 1997// /f_finale.c/1.5/Mon Feb 3 21:26:34 1997// /f_finale.h/1.1/Mon Feb 3 21:26:34 1997// /f_wipe.c/1.2/Mon Feb 3 22:45:09 1997// /f_wipe.h/1.1/Mon Feb 3 17:11:23 1997// /fpfunc.S/1.1/Sun Jan 19 17:22:43 1997// /g_game.c/1.8/Mon Feb 3 22:45:09 1997// /g_game.h/1.1/Mon Feb 3 21:34:47 1997// /hu_lib.c/1.3/Sun Jan 26 07:44:58 1997// /hu_lib.h/1.4/Mon Feb 3 16:47:52 1997// /hu_stuff.c/1.4/Mon Feb 3 16:47:52 1997// /hu_stuff.h/1.3/Sun Jan 26 07:44:58 1997// /i_dga.c/1.3/Sun Jan 26 07:44:58 1997// /i_ibm.c/1.3/Sun Jan 26 07:44:58 1997// /i_main.c/1.4/Mon Feb 3 22:45:10 1997// /i_pcnet.c/1.3/Sun Jan 26 07:44:59 1997// /i_sound.c/1.3/Sun Jan 26 07:44:59 1997// /i_sound.h/1.3/Sun Jan 26 07:44:59 1997// /i_svga.c/1.3/Sun Jan 26 07:44:59 1997// /i_unix.c/1.5/Mon Feb 3 22:45:10 1997// /i_x.c/1.6/Mon Feb 3 22:45:10 1997// /info.c/1.3/Sun Jan 26 07:45:00 1997// /info.h/1.3/Sun Jan 26 07:45:00 1997// /irix.c/1.3/Sun Jan 26 07:45:00 1997// /irix.h/1.3/Sun Jan 26 07:45:01 1997// /linux.c/1.3/Sun Jan 26 07:45:01 1997// /m_argv.c/1.1/Mon Feb 3 22:45:10 1997// /m_argv.h/1.1/Mon Feb 3 22:45:10 1997// /m_bbox.c/1.1/Mon Feb 3 22:45:10 1997// /m_bbox.h/1.1/Mon Feb 3 22:45:10 1997// /m_cheat.c/1.1/Mon Feb 3 21:24:34 1997// /m_cheat.h/1.1/Mon Feb 3 21:24:34 1997// /m_menu.c/1.7/Mon Feb 3 22:45:10 1997// /m_menu.h/1.1/Mon Feb 3 22:01:49 1997// /m_misc.c/1.6/Mon Feb 3 22:45:10 1997// /m_misc.h/1.1/Mon Feb 3 22:45:11 1997// /m_random.c/1.1/Mon Feb 3 22:45:11 1997// /m_random.h/1.1/Mon Feb 3 22:45:11 1997// /p_ceilng.c/1.4/Mon Feb 3 16:47:53 1997// /p_doors.c/1.4/Mon Feb 3 16:47:53 1997// /p_enemy.c/1.5/Mon Feb 3 22:45:11 1997// /p_floor.c/1.4/Mon Feb 3 16:47:54 1997// /p_inter.c/1.4/Mon Feb 3 22:45:11 1997// /p_lights.c/1.5/Mon Feb 3 22:45:11 1997// /p_local.h/1.3/Tue Jan 28 22:08:27 1997// /p_map.c/1.5/Mon Feb 3 22:45:11 1997// /p_maputl.c/1.5/Mon Feb 3 22:45:11 1997// /p_mobj.c/1.5/Mon Feb 3 22:45:12 1997// /p_plats.c/1.5/Mon Feb 3 22:45:12 1997// /p_pspr.c/1.5/Mon Feb 3 22:45:12 1997// /p_setup.c/1.5/Mon Feb 3 22:45:12 1997// /p_sight.c/1.3/Tue Jan 28 22:08:28 1997// /p_spec.c/1.6/Mon Feb 3 22:45:12 1997// /p_spec.h/1.3/Tue Jan 28 22:08:29 1997// /p_switch.c/1.3/Tue Jan 28 22:08:29 1997// /p_telept.c/1.3/Tue Jan 28 22:08:29 1997// /p_tick.c/1.4/Mon Feb 3 16:47:55 1997// /p_user.c/1.3/Tue Jan 28 22:08:29 1997// /r_bsp.c/1.4/Mon Feb 3 22:45:12 1997// /r_data.c/1.4/Mon Feb 3 16:47:55 1997// /r_draw.c/1.4/Mon Feb 3 16:47:55 1997// /r_local.h/1.4/Mon Feb 3 21:26:34 1997// /r_main.c/1.5/Mon Feb 3 22:45:12 1997// /r_plane.c/1.4/Mon Feb 3 16:47:55 1997// /r_segs.c/1.3/Wed Jan 29 20:10:19 1997// /r_things.c/1.5/Mon Feb 3 16:47:56 1997// /s_sound.c/1.6/Mon Feb 3 22:45:12 1997// /sounds.c/1.3/Wed Jan 29 22:40:44 1997// /sounds.h/1.3/Wed Jan 29 22:40:44 1997// /soundsrv.c/1.3/Wed Jan 29 22:40:44 1997// /soundsrv.h/1.3/Wed Jan 29 22:40:44 1997// /soundst.h/1.3/Wed Jan 29 22:40:45 1997// /st_lib.c/1.4/Mon Feb 3 16:47:56 1997// /st_lib.h/1.4/Mon Feb 3 16:47:56 1997// /st_stuff.c/1.6/Mon Feb 3 22:45:13 1997// /st_stuff.h/1.3/Thu Jan 30 19:54:22 1997// /sun.c/1.3/Thu Jan 30 19:54:22 1997// /tables.c/1.4/Mon Feb 3 16:47:57 1997// /tables.h/1.1/Mon Feb 3 16:47:57 1997// /tmap.S/1.1/Sun Jan 19 17:22:51 1997// /v_video.c/1.5/Mon Feb 3 22:45:13 1997// /v_video.h/1.2/Mon Feb 3 17:11:59 1997// /w_wad.c/1.5/Mon Feb 3 16:47:57 1997// /wadread.c/1.3/Thu Jan 30 19:54:23 1997// /wadread.h/1.3/Thu Jan 30 19:54:23 1997// /wi_data.h/1.3/Thu Jan 30 19:54:23 1997// /wi_stuff.c/1.7/Mon Feb 3 22:45:13 1997// /wi_stuff.h/1.4/Mon Feb 3 16:47:58 1997// /z_zone.c/1.4/Mon Feb 3 16:47:58 1997// /z_zone.h/1.1/Mon Feb 3 16:47:58 1997// /info/cvsroot/id/id_doom /info/cvsroot/ // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // Printed strings for translation. // English language support (default). // //-----------------------------------------------------------------------------
#ifndef __D_ENGLSH__ #define __D_ENGLSH__
// // Printed strings for translation //
// // D_Main.C // #define D_DEVSTR "Development mode ON.\n" #define D_CDROM "CD-ROM Version: default.cfg from c:\\doomdata\n"
// // M_Menu.C // #define PRESSKEY "press a key." #define PRESSYN "press y or n." #define QUITMSG "are you sure you want to\nquit this great game?" #define LOADNET "you can't do load while in a net game!\n\n"PRESSKEY #define QLOADNET "you can't quickload during a netgame!\n\n"PRESSKEY #define QSAVESPOT "you haven't picked a quicksave slot yet!\n\n"PRESSKEY #define SAVEDEAD "you can't save if you aren't playing!\n\n"PRESSKEY #define QSPROMPT "quicksave over your game named\n\n'%s'?\n\n"PRESSYN #define QLPROMPT "do you want to quickload the game named\n\n'%s'?\n\n"PRESSYN
#define NEWGAME \ "you can't start a new game\n"\ "while in a network game.\n\n"PRESSKEY
#define NIGHTMARE \ "are you sure? this skill level\n"\ "isn't even remotely fair.\n\n"PRESSYN
#define SWSTRING \ "this is the shareware version of doom.\n\n"\ "you need to order the entire trilogy.\n\n"PRESSKEY
#define MSGOFF "Messages OFF" #define MSGON "Messages ON" #define NETEND "you can't end a netgame!\n\n"PRESSKEY #define ENDGAME "are you sure you want to end the game?\n\n"PRESSYN
#define DOSY "(press y to quit)"
#define DETAILHI "High detail" #define DETAILLO "Low detail" #define GAMMALVL0 "Gamma correction OFF" #define GAMMALVL1 "Gamma correction level 1" #define GAMMALVL2 "Gamma correction level 2" #define GAMMALVL3 "Gamma correction level 3" #define GAMMALVL4 "Gamma correction level 4" #define EMPTYSTRING "empty slot"
// // P_inter.C // #define GOTARMOR "Picked up the armor." #define GOTMEGA "Picked up the MegaArmor!" #define GOTHTHBONUS "Picked up a health bonus." #define GOTARMBONUS "Picked up an armor bonus." #define GOTSTIM "Picked up a stimpack." #define GOTMEDINEED "Picked up a medikit that you REALLY need!" #define GOTMEDIKIT "Picked up a medikit." #define GOTSUPER "Supercharge!"
#define GOTBLUECARD "Picked up a blue keycard." #define GOTYELWCARD "Picked up a yellow keycard." #define GOTREDCARD "Picked up a red keycard." #define GOTBLUESKUL "Picked up a blue skull key." #define GOTYELWSKUL "Picked up a yellow skull key." #define GOTREDSKULL "Picked up a red skull key."
#define GOTINVUL "Invulnerability!" #define GOTBERSERK "Berserk!" #define GOTINVIS "Partial Invisibility" #define GOTSUIT "Radiation Shielding Suit" #define GOTMAP "Computer Area Map" #define GOTVISOR "Light Amplification Visor" #define GOTMSPHERE "MegaSphere!"
#define GOTCLIP "Picked up a clip." #define GOTCLIPBOX "Picked up a box of bullets." #define GOTROCKET "Picked up a rocket." #define GOTROCKBOX "Picked up a box of rockets." #define GOTCELL "Picked up an energy cell." #define GOTCELLBOX "Picked up an energy cell pack." #define GOTSHELLS "Picked up 4 shotgun shells." #define GOTSHELLBOX "Picked up a box of shotgun shells." #define GOTBACKPACK "Picked up a backpack full of ammo!"
#define GOTBFG9000 "You got the BFG9000! Oh, yes." #define GOTCHAINGUN "You got the chaingun!" #define GOTCHAINSAW "A chainsaw! Find some meat!" #define GOTLAUNCHER "You got the rocket launcher!" #define GOTPLASMA "You got the plasma gun!" #define GOTSHOTGUN "You got the shotgun!" #define GOTSHOTGUN2 "You got the super shotgun!"
// // P_Doors.C // #define PD_BLUEO "You need a blue key to activate this object" #define PD_REDO "You need a red key to activate this object" #define PD_YELLOWO "You need a yellow key to activate this object" #define PD_BLUEK "You need a blue key to open this door" #define PD_REDK "You need a red key to open this door" #define PD_YELLOWK "You need a yellow key to open this door"
// // G_game.C // #define GGSAVED "game saved."
// // HU_stuff.C // #define HUSTR_MSGU "[Message unsent]"
#define HUSTR_E1M1 "E1M1: Hangar" #define HUSTR_E1M2 "E1M2: Nuclear Plant" #define HUSTR_E1M3 "E1M3: Toxin Refinery" #define HUSTR_E1M4 "E1M4: Command Control" #define HUSTR_E1M5 "E1M5: Phobos Lab" #define HUSTR_E1M6 "E1M6: Central Processing" #define HUSTR_E1M7 "E1M7: Computer Station" #define HUSTR_E1M8 "E1M8: Phobos Anomaly" #define HUSTR_E1M9 "E1M9: Military Base"
#define HUSTR_E2M1 "E2M1: Deimos Anomaly" #define HUSTR_E2M2 "E2M2: Containment Area" #define HUSTR_E2M3 "E2M3: Refinery" #define HUSTR_E2M4 "E2M4: Deimos Lab" #define HUSTR_E2M5 "E2M5: Command Center" #define HUSTR_E2M6 "E2M6: Halls of the Damned" #define HUSTR_E2M7 "E2M7: Spawning Vats" #define HUSTR_E2M8 "E2M8: Tower of Babel" #define HUSTR_E2M9 "E2M9: Fortress of Mystery"
#define HUSTR_E3M1 "E3M1: Hell Keep" #define HUSTR_E3M2 "E3M2: Slough of Despair" #define HUSTR_E3M3 "E3M3: Pandemonium" #define HUSTR_E3M4 "E3M4: House of Pain" #define HUSTR_E3M5 "E3M5: Unholy Cathedral" #define HUSTR_E3M6 "E3M6: Mt. Erebus" #define HUSTR_E3M7 "E3M7: Limbo" #define HUSTR_E3M8 "E3M8: Dis" #define HUSTR_E3M9 "E3M9: Warrens"
#define HUSTR_E4M1 "E4M1: Hell Beneath" #define HUSTR_E4M2 "E4M2: Perfect Hatred" #define HUSTR_E4M3 "E4M3: Sever The Wicked" #define HUSTR_E4M4 "E4M4: Unruly Evil" #define HUSTR_E4M5 "E4M5: They Will Repent" #define HUSTR_E4M6 "E4M6: Against Thee Wickedly" #define HUSTR_E4M7 "E4M7: And Hell Followed" #define HUSTR_E4M8 "E4M8: Unto The Cruel" #define HUSTR_E4M9 "E4M9: Fear"
#define HUSTR_1 "level 1: entryway" #define HUSTR_2 "level 2: underhalls" #define HUSTR_3 "level 3: the gantlet" #define HUSTR_4 "level 4: the focus" #define HUSTR_5 "level 5: the waste tunnels" #define HUSTR_6 "level 6: the crusher" #define HUSTR_7 "level 7: dead simple" #define HUSTR_8 "level 8: tricks and traps" #define HUSTR_9 "level 9: the pit" #define HUSTR_10 "level 10: refueling base" #define HUSTR_11 "level 11: 'o' of destruction!"
#define HUSTR_12 "level 12: the factory" #define HUSTR_13 "level 13: downtown" #define HUSTR_14 "level 14: the inmost dens" #define HUSTR_15 "level 15: industrial zone" #define HUSTR_16 "level 16: suburbs" #define HUSTR_17 "level 17: tenements" #define HUSTR_18 "level 18: the courtyard" #define HUSTR_19 "level 19: the citadel" #define HUSTR_20 "level 20: gotcha!"
#define HUSTR_21 "level 21: nirvana" #define HUSTR_22 "level 22: the catacombs" #define HUSTR_23 "level 23: barrels o' fun" #define HUSTR_24 "level 24: the chasm" #define HUSTR_25 "level 25: bloodfalls" #define HUSTR_26 "level 26: the abandoned mines" #define HUSTR_27 "level 27: monster condo" #define HUSTR_28 "level 28: the spirit world" #define HUSTR_29 "level 29: the living end" #define HUSTR_30 "level 30: icon of sin"
#define HUSTR_31 "level 31: wolfenstein" #define HUSTR_32 "level 32: grosse"
#define PHUSTR_1 "level 1: congo" #define PHUSTR_2 "level 2: well of souls" #define PHUSTR_3 "level 3: aztec" #define PHUSTR_4 "level 4: caged" #define PHUSTR_5 "level 5: ghost town" #define PHUSTR_6 "level 6: baron's lair" #define PHUSTR_7 "level 7: caughtyard" #define PHUSTR_8 "level 8: realm" #define PHUSTR_9 "level 9: abattoire" #define PHUSTR_10 "level 10: onslaught" #define PHUSTR_11 "level 11: hunted"
#define PHUSTR_12 "level 12: speed" #define PHUSTR_13 "level 13: the crypt" #define PHUSTR_14 "level 14: genesis" #define PHUSTR_15 "level 15: the twilight" #define PHUSTR_16 "level 16: the omen" #define PHUSTR_17 "level 17: compound" #define PHUSTR_18 "level 18: neurosphere" #define PHUSTR_19 "level 19: nme" #define PHUSTR_20 "level 20: the death domain"
#define PHUSTR_21 "level 21: slayer" #define PHUSTR_22 "level 22: impossible mission" #define PHUSTR_23 "level 23: tombstone" #define PHUSTR_24 "level 24: the final frontier" #define PHUSTR_25 "level 25: the temple of darkness" #define PHUSTR_26 "level 26: bunker" #define PHUSTR_27 "level 27: anti-christ" #define PHUSTR_28 "level 28: the sewers" #define PHUSTR_29 "level 29: odyssey of noises" #define PHUSTR_30 "level 30: the gateway of hell"
#define PHUSTR_31 "level 31: cyberden" #define PHUSTR_32 "level 32: go 2 it"
#define THUSTR_1 "level 1: system control" #define THUSTR_2 "level 2: human bbq" #define THUSTR_3 "level 3: power control" #define THUSTR_4 "level 4: wormhole" #define THUSTR_5 "level 5: hanger" #define THUSTR_6 "level 6: open season" #define THUSTR_7 "level 7: prison" #define THUSTR_8 "level 8: metal" #define THUSTR_9 "level 9: stronghold" #define THUSTR_10 "level 10: redemption" #define THUSTR_11 "level 11: storage facility"
#define THUSTR_12 "level 12: crater" #define THUSTR_13 "level 13: nukage processing" #define THUSTR_14 "level 14: steel works" #define THUSTR_15 "level 15: dead zone" #define THUSTR_16 "level 16: deepest reaches" #define THUSTR_17 "level 17: processing area" #define THUSTR_18 "level 18: mill" #define THUSTR_19 "level 19: shipping/respawning" #define THUSTR_20 "level 20: central processing"
#define THUSTR_21 "level 21: administration center" #define THUSTR_22 "level 22: habitat" #define THUSTR_23 "level 23: lunar mining project" #define THUSTR_24 "level 24: quarry" #define THUSTR_25 "level 25: baron's den" #define THUSTR_26 "level 26: ballistyx" #define THUSTR_27 "level 27: mount pain" #define THUSTR_28 "level 28: heck" #define THUSTR_29 "level 29: river styx" #define THUSTR_30 "level 30: last call"
#define THUSTR_31 "level 31: pharaoh" #define THUSTR_32 "level 32: caribbean"
#define HUSTR_CHATMACRO1 "I'm ready to kick butt!" #define HUSTR_CHATMACRO2 "I'm OK." #define HUSTR_CHATMACRO3 "I'm not looking too good!" #define HUSTR_CHATMACRO4 "Help!" #define HUSTR_CHATMACRO5 "You suck!" #define HUSTR_CHATMACRO6 "Next time, scumbag..." #define HUSTR_CHATMACRO7 "Come here!" #define HUSTR_CHATMACRO8 "I'll take care of it." #define HUSTR_CHATMACRO9 "Yes" #define HUSTR_CHATMACRO0 "No"
#define HUSTR_TALKTOSELF1 "You mumble to yourself" #define HUSTR_TALKTOSELF2 "Who's there?" #define HUSTR_TALKTOSELF3 "You scare yourself" #define HUSTR_TALKTOSELF4 "You start to rave" #define HUSTR_TALKTOSELF5 "You've lost it..."
#define HUSTR_MESSAGESENT "[Message Sent]"
// The following should NOT be changed unless it seems // just AWFULLY necessary
#define HUSTR_PLRGREEN "Green: " #define HUSTR_PLRINDIGO "Indigo: " #define HUSTR_PLRBROWN "Brown: " #define HUSTR_PLRRED "Red: "
#define HUSTR_KEYGREEN 'g' #define HUSTR_KEYINDIGO 'i' #define HUSTR_KEYBROWN 'b' #define HUSTR_KEYRED 'r'
// // AM_map.C //
#define AMSTR_FOLLOWON "Follow Mode ON" #define AMSTR_FOLLOWOFF "Follow Mode OFF"
#define AMSTR_GRIDON "Grid ON" #define AMSTR_GRIDOFF "Grid OFF"
#define AMSTR_MARKEDSPOT "Marked Spot" #define AMSTR_MARKSCLEARED "All Marks Cleared"
// // ST_stuff.C //
#define STSTR_MUS "Music Change" #define STSTR_NOMUS "IMPOSSIBLE SELECTION" #define STSTR_DQDON "Degreelessness Mode On" #define STSTR_DQDOFF "Degreelessness Mode Off"
#define STSTR_KFAADDED "Very Happy Ammo Added" #define STSTR_FAADDED "Ammo (no keys) Added"
#define STSTR_NCON "No Clipping Mode ON" #define STSTR_NCOFF "No Clipping Mode OFF"
#define STSTR_BEHOLD "inVuln, Str, Inviso, Rad, Allmap, or Lite-amp" #define STSTR_BEHOLDX "Power-up Toggled"
#define STSTR_CHOPPERS "... doesn't suck - GM" #define STSTR_CLEV "Changing Level..."
// // F_Finale.C // #define E1TEXT \ "Once you beat the big badasses and\n"\ "clean out the moon base you're supposed\n"\ "to win, aren't you? Aren't you? Where's\n"\ "your fat reward and ticket home? What\n"\ "the hell is this? It's not supposed to\n"\ "end this way!\n"\ "\n" \ "It stinks like rotten meat, but looks\n"\ "like the lost Deimos base. Looks like\n"\ "you're stuck on The Shores of Hell.\n"\ "The only way out is through.\n"\ "\n"\ "To continue the DOOM experience, play\n"\ "The Shores of Hell and its amazing\n"\ "sequel, Inferno!\n"
#define E2TEXT \ "You've done it! The hideous cyber-\n"\ "demon lord that ruled the lost Deimos\n"\ "moon base has been slain and you\n"\ "are triumphant! But ... where are\n"\ "you? You clamber to the edge of the\n"\ "moon and look down to see the awful\n"\ "truth.\n" \ "\n"\ "Deimos floats above Hell itself!\n"\ "You've never heard of anyone escaping\n"\ "from Hell, but you'll make the bastards\n"\ "sorry they ever heard of you! Quickly,\n"\ "you rappel down to the surface of\n"\ "Hell.\n"\ "\n" \ "Now, it's on to the final chapter of\n"\ "DOOM! -- Inferno."
#define E3TEXT \ "The loathsome spiderdemon that\n"\ "masterminded the invasion of the moon\n"\ "bases and caused so much death has had\n"\ "its ass kicked for all time.\n"\ "\n"\ "A hidden doorway opens and you enter.\n"\ "You've proven too tough for Hell to\n"\ "contain, and now Hell at last plays\n"\ "fair -- for you emerge from the door\n"\ "to see the green fields of Earth!\n"\ "Home at last.\n" \ "\n"\ "You wonder what's been happening on\n"\ "Earth while you were battling evil\n"\ "unleashed. It's good that no Hell-\n"\ "spawn could have come through that\n"\ "door with you ..."
#define E4TEXT \ "the spider mastermind must have sent forth\n"\ "its legions of hellspawn before your\n"\ "final confrontation with that terrible\n"\ "beast from hell. but you stepped forward\n"\ "and brought forth eternal damnation and\n"\ "suffering upon the horde as a true hero\n"\ "would in the face of something so evil.\n"\ "\n"\ "besides, someone was gonna pay for what\n"\ "happened to daisy, your pet rabbit.\n"\ "\n"\ "but now, you see spread before you more\n"\ "potential pain and gibbitude as a nation\n"\ "of demons run amok among our cities.\n"\ "\n"\ "next stop, hell on earth!"
// after level 6, put this:
#define C1TEXT \ "YOU HAVE ENTERED DEEPLY INTO THE INFESTED\n" \ "STARPORT. BUT SOMETHING IS WRONG. THE\n" \ "MONSTERS HAVE BROUGHT THEIR OWN REALITY\n" \ "WITH THEM, AND THE STARPORT'S TECHNOLOGY\n" \ "IS BEING SUBVERTED BY THEIR PRESENCE.\n" \ "\n"\ "AHEAD, YOU SEE AN OUTPOST OF HELL, A\n" \ "FORTIFIED ZONE. IF YOU CAN GET PAST IT,\n" \ "YOU CAN PENETRATE INTO THE HAUNTED HEART\n" \ "OF THE STARBASE AND FIND THE CONTROLLING\n" \ "SWITCH WHICH HOLDS EARTH'S POPULATION\n" \ "HOSTAGE."
// After level 11, put this:
#define C2TEXT \ "YOU HAVE WON! YOUR VICTORY HAS ENABLED\n" \ "HUMANKIND TO EVACUATE EARTH AND ESCAPE\n"\ "THE NIGHTMARE. NOW YOU ARE THE ONLY\n"\ "HUMAN LEFT ON THE FACE OF THE PLANET.\n"\ "CANNIBAL MUTATIONS, CARNIVOROUS ALIENS,\n"\ "AND EVIL SPIRITS ARE YOUR ONLY NEIGHBORS.\n"\ "YOU SIT BACK AND WAIT FOR DEATH, CONTENT\n"\ "THAT YOU HAVE SAVED YOUR SPECIES.\n"\ "\n"\ "BUT THEN, EARTH CONTROL BEAMS DOWN A\n"\ "MESSAGE FROM SPACE: \"SENSORS HAVE LOCATED\n"\ "THE SOURCE OF THE ALIEN INVASION. IF YOU\n"\ "GO THERE, YOU MAY BE ABLE TO BLOCK THEIR\n"\ "ENTRY. THE ALIEN BASE IS IN THE HEART OF\n"\ "YOUR OWN HOME CITY, NOT FAR FROM THE\n"\ "STARPORT.\" SLOWLY AND PAINFULLY YOU GET\n"\ "UP AND RETURN TO THE FRAY."
// After level 20, put this:
#define C3TEXT \ "YOU ARE AT THE CORRUPT HEART OF THE CITY,\n"\ "SURROUNDED BY THE CORPSES OF YOUR ENEMIES.\n"\ "YOU SEE NO WAY TO DESTROY THE CREATURES'\n"\ "ENTRYWAY ON THIS SIDE, SO YOU CLENCH YOUR\n"\ "TEETH AND PLUNGE THROUGH IT.\n"\ "\n"\ "THERE MUST BE A WAY TO CLOSE IT ON THE\n"\ "OTHER SIDE. WHAT DO YOU CARE IF YOU'VE\n"\ "GOT TO GO THROUGH HELL TO GET TO IT?"
// After level 29, put this:
#define C4TEXT \ "THE HORRENDOUS VISAGE OF THE BIGGEST\n"\ "DEMON YOU'VE EVER SEEN CRUMBLES BEFORE\n"\ "YOU, AFTER YOU PUMP YOUR ROCKETS INTO\n"\ "HIS EXPOSED BRAIN. THE MONSTER SHRIVELS\n"\ "UP AND DIES, ITS THRASHING LIMBS\n"\ "DEVASTATING UNTOLD MILES OF HELL'S\n"\ "SURFACE.\n"\ "\n"\ "YOU'VE DONE IT. THE INVASION IS OVER.\n"\ "EARTH IS SAVED. HELL IS A WRECK. YOU\n"\ "WONDER WHERE BAD FOLKS WILL GO WHEN THEY\n"\ "DIE, NOW. WIPING THE SWEAT FROM YOUR\n"\ "FOREHEAD YOU BEGIN THE LONG TREK BACK\n"\ "HOME. REBUILDING EARTH OUGHT TO BE A\n"\ "LOT MORE FUN THAN RUINING IT WAS.\n"
// Before level 31, put this:
#define C5TEXT \ "CONGRATULATIONS, YOU'VE FOUND THE SECRET\n"\ "LEVEL! LOOKS LIKE IT'S BEEN BUILT BY\n"\ "HUMANS, RATHER THAN DEMONS. YOU WONDER\n"\ "WHO THE INMATES OF THIS CORNER OF HELL\n"\ "WILL BE."
// Before level 32, put this:
#define C6TEXT \ "CONGRATULATIONS, YOU'VE FOUND THE\n"\ "SUPER SECRET LEVEL! YOU'D BETTER\n"\ "BLAZE THROUGH THIS ONE!\n"
// after map 06
#define P1TEXT \ "You gloat over the steaming carcass of the\n"\ "Guardian. With its death, you've wrested\n"\ "the Accelerator from the stinking claws\n"\ "of Hell. You relax and glance around the\n"\ "room. Damn! There was supposed to be at\n"\ "least one working prototype, but you can't\n"\ "see it. The demons must have taken it.\n"\ "\n"\ "You must find the prototype, or all your\n"\ "struggles will have been wasted. Keep\n"\ "moving, keep fighting, keep killing.\n"\ "Oh yes, keep living, too."
// after map 11
#define P2TEXT \ "Even the deadly Arch-Vile labyrinth could\n"\ "not stop you, and you've gotten to the\n"\ "prototype Accelerator which is soon\n"\ "efficiently and permanently deactivated.\n"\ "\n"\ "You're good at that kind of thing."
// after map 20
#define P3TEXT \ "You've bashed and battered your way into\n"\ "the heart of the devil-hive. Time for a\n"\ "Search-and-Destroy mission, aimed at the\n"\ "Gatekeeper, whose foul offspring is\n"\ "cascading to Earth. Yeah, he's bad. But\n"\ "you know who's worse!\n"\ "\n"\ "Grinning evilly, you check your gear, and\n"\ "get ready to give the bastard a little Hell\n"\ "of your own making!"
// after map 30
#define P4TEXT \ "The Gatekeeper's evil face is splattered\n"\ "all over the place. As its tattered corpse\n"\ "collapses, an inverted Gate forms and\n"\ "sucks down the shards of the last\n"\ "prototype Accelerator, not to mention the\n"\ "few remaining demons. You're done. Hell\n"\ "has gone back to pounding bad dead folks \n"\ "instead of good live ones. Remember to\n"\ "tell your grandkids to put a rocket\n"\ "launcher in your coffin. If you go to Hell\n"\ "when you die, you'll need it for some\n"\ "final cleaning-up ..."
// before map 31
#define P5TEXT \ "You've found the second-hardest level we\n"\ "got. Hope you have a saved game a level or\n"\ "two previous. If not, be prepared to die\n"\ "aplenty. For master marines only."
// before map 32
#define P6TEXT \ "Betcha wondered just what WAS the hardest\n"\ "level we had ready for ya? Now you know.\n"\ "No one gets out alive."
#define T1TEXT \ "You've fought your way out of the infested\n"\ "experimental labs. It seems that UAC has\n"\ "once again gulped it down. With their\n"\ "high turnover, it must be hard for poor\n"\ "old UAC to buy corporate health insurance\n"\ "nowadays..\n"\ "\n"\ "Ahead lies the military complex, now\n"\ "swarming with diseased horrors hot to get\n"\ "their teeth into you. With luck, the\n"\ "complex still has some warlike ordnance\n"\ "laying around."
#define T2TEXT \ "You hear the grinding of heavy machinery\n"\ "ahead. You sure hope they're not stamping\n"\ "out new hellspawn, but you're ready to\n"\ "ream out a whole herd if you have to.\n"\ "They might be planning a blood feast, but\n"\ "you feel about as mean as two thousand\n"\ "maniacs packed into one mad killer.\n"\ "\n"\ "You don't plan to go down easy."
#define T3TEXT \ "The vista opening ahead looks real damn\n"\ "familiar. Smells familiar, too -- like\n"\ "fried excrement. You didn't like this\n"\ "place before, and you sure as hell ain't\n"\ "planning to like it now. The more you\n"\ "brood on it, the madder you get.\n"\ "Hefting your gun, an evil grin trickles\n"\ "onto your face. Time to take some names."
#define T4TEXT \ "Suddenly, all is silent, from one horizon\n"\ "to the other. The agonizing echo of Hell\n"\ "fades away, the nightmare sky turns to\n"\ "blue, the heaps of monster corpses start \n"\ "to evaporate along with the evil stench \n"\ "that filled the air. Jeeze, maybe you've\n"\ "done it. Have you really won?\n"\ "\n"\ "Something rumbles in the distance.\n"\ "A blue light begins to glow inside the\n"\ "ruined skull of the demon-spitter."
#define T5TEXT \ "What now? Looks totally different. Kind\n"\ "of like King Tut's condo. Well,\n"\ "whatever's here can't be any worse\n"\ "than usual. Can it? Or maybe it's best\n"\ "to let sleeping gods lie.."
#define T6TEXT \ "Time for a vacation. You've burst the\n"\ "bowels of hell and by golly you're ready\n"\ "for a break. You mutter to yourself,\n"\ "Maybe someone else can kick Hell's ass\n"\ "next time around. Ahead lies a quiet town,\n"\ "with peaceful flowing water, quaint\n"\ "buildings, and presumably no Hellspawn.\n"\ "\n"\ "As you step off the transport, you hear\n"\ "the stomp of a cyberdemon's iron shoe."
// // Character cast strings F_FINALE.C // #define CC_ZOMBIE "ZOMBIEMAN" #define CC_SHOTGUN "SHOTGUN GUY" #define CC_HEAVY "HEAVY WEAPON DUDE" #define CC_IMP "IMP" #define CC_DEMON "DEMON" #define CC_LOST "LOST SOUL" #define CC_CACO "CACODEMON" #define CC_HELL "HELL KNIGHT" #define CC_BARON "BARON OF HELL" #define CC_ARACH "ARACHNOTRON" #define CC_PAIN "PAIN ELEMENTAL" #define CC_REVEN "REVENANT" #define CC_MANCU "MANCUBUS" #define CC_ARCH "ARCH-VILE" #define CC_SPIDER "THE SPIDER MASTERMIND" #define CC_CYBER "THE CYBERDEMON" #define CC_HERO "OUR HERO"
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // // //-----------------------------------------------------------------------------
#ifndef __D_EVENT__ #define __D_EVENT__
#include "doomtype.h"
// // Event handling. //
// Input event types. typedef enum { ev_keydown, ev_keyup, ev_mouse, ev_joystick } evtype_t;
// Event structure. typedef struct { evtype_t type; int data1; // keys / mouse/joystick buttons int data2; // mouse/joystick x move int data3; // mouse/joystick y move } event_t;
typedef enum { ga_nothing, ga_loadlevel, ga_newgame, ga_loadgame, ga_savegame, ga_playdemo, ga_completed, ga_victory, ga_worlddone, ga_screenshot } gameaction_t;
// // Button/action code definitions. // typedef enum { // Press "Fire". BT_ATTACK = 1, // Use button, to open doors, activate switches. BT_USE = 2,
// Flag: game events, not really buttons. BT_SPECIAL = 128, BT_SPECIALMASK = 3,
// Flag, weapon change pending. // If true, the next 3 bits hold weapon num. BT_CHANGE = 4, // The 3bit weapon mask and shift, convenience. BT_WEAPONMASK = (8+16+32), BT_WEAPONSHIFT = 3,
// Pause the game. BTS_PAUSE = 1, // Save the game at each console. BTS_SAVEGAME = 2,
// Savegame slot numbers // occupy the second byte of buttons. BTS_SAVEMASK = (4+8+16), BTS_SAVESHIFT = 2,
} buttoncode_t;
// // GLOBAL VARIABLES // #define MAXEVENTS 64
extern event_t events[MAXEVENTS]; extern int eventhead; extern int eventtail;
extern gameaction_t gameaction;
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // Printed strings, french translation. // //-----------------------------------------------------------------------------
#ifndef __D_FRENCH__ #define __D_FRENCH__
// // D_Main.C // #define D_DEVSTR "MODE DEVELOPPEMENT ON.\n" #define D_CDROM "VERSION CD-ROM: DEFAULT.CFG DANS C:\\DOOMDATA\n"
// // M_Menu.C // #define PRESSKEY "APPUYEZ SUR UNE TOUCHE." #define PRESSYN "APPUYEZ SUR Y OU N" #define QUITMSG "VOUS VOULEZ VRAIMENT\nQUITTER CE SUPER JEU?" #define LOADNET "VOUS NE POUVEZ PAS CHARGER\nUN JEU EN RESEAU!\n\n"PRESSKEY #define QLOADNET "CHARGEMENT RAPIDE INTERDIT EN RESEAU!\n\n"PRESSKEY #define QSAVESPOT "VOUS N'AVEZ PAS CHOISI UN EMPLACEMENT!\n\n"PRESSKEY #define SAVEDEAD "VOUS NE POUVEZ PAS SAUVER SI VOUS NE JOUEZ "\ "PAS!\n\n"PRESSKEY #define QSPROMPT "SAUVEGARDE RAPIDE DANS LE FICHIER \n\n'%s'?\n\n"PRESSYN #define QLPROMPT "VOULEZ-VOUS CHARGER LA SAUVEGARDE"\ "\n\n'%s'?\n\n"PRESSYN #define NEWGAME "VOUS NE POUVEZ PAS LANCER\n"\ "UN NOUVEAU JEU SUR RESEAU.\n\n"PRESSKEY #define NIGHTMARE "VOUS CONFIRMEZ? CE NIVEAU EST\n"\ "VRAIMENT IMPITOYABLE!n"PRESSYN #define SWSTRING "CECI EST UNE VERSION SHAREWARE DE DOOM.\n\n"\ "VOUS DEVRIEZ COMMANDER LA TRILOGIE COMPLETE.\n\n"PRESSKEY #define MSGOFF "MESSAGES OFF" #define MSGON "MESSAGES ON" #define NETEND "VOUS NE POUVEZ PAS METTRE FIN A UN JEU SUR "\ "RESEAU!\n\n"PRESSKEY #define ENDGAME "VOUS VOULEZ VRAIMENT METTRE FIN AU JEU?\n\n"PRESSYN
#define DOSY "(APPUYEZ SUR Y POUR REVENIR AU OS.)"
#define DETAILHI "GRAPHISMES MAXIMUM " #define DETAILLO "GRAPHISMES MINIMUM " #define GAMMALVL0 "CORRECTION GAMMA OFF" #define GAMMALVL1 "CORRECTION GAMMA NIVEAU 1" #define GAMMALVL2 "CORRECTION GAMMA NIVEAU 2" #define GAMMALVL3 "CORRECTION GAMMA NIVEAU 3" #define GAMMALVL4 "CORRECTION GAMMA NIVEAU 4" #define EMPTYSTRING "EMPLACEMENT VIDE"
// // P_inter.C // #define GOTARMOR "ARMURE RECUPEREE." #define GOTMEGA "MEGA-ARMURE RECUPEREE!" #define GOTHTHBONUS "BONUS DE SANTE RECUPERE." #define GOTARMBONUS "BONUS D'ARMURE RECUPERE." #define GOTSTIM "STIMPACK RECUPERE." #define GOTMEDINEED "MEDIKIT RECUPERE. VOUS EN AVEZ VRAIMENT BESOIN!" #define GOTMEDIKIT "MEDIKIT RECUPERE." #define GOTSUPER "SUPERCHARGE!"
#define GOTBLUECARD "CARTE MAGNETIQUE BLEUE RECUPEREE." #define GOTYELWCARD "CARTE MAGNETIQUE JAUNE RECUPEREE." #define GOTREDCARD "CARTE MAGNETIQUE ROUGE RECUPEREE." #define GOTBLUESKUL "CLEF CRANE BLEUE RECUPEREE." #define GOTYELWSKUL "CLEF CRANE JAUNE RECUPEREE." #define GOTREDSKULL "CLEF CRANE ROUGE RECUPEREE."
#define GOTINVUL "INVULNERABILITE!" #define GOTBERSERK "BERSERK!" #define GOTINVIS "INVISIBILITE PARTIELLE " #define GOTSUIT "COMBINAISON ANTI-RADIATIONS " #define GOTMAP "CARTE INFORMATIQUE " #define GOTVISOR "VISEUR A AMPLIFICATION DE LUMIERE " #define GOTMSPHERE "MEGASPHERE!"
#define GOTCLIP "CHARGEUR RECUPERE." #define GOTCLIPBOX "BOITE DE BALLES RECUPEREE." #define GOTROCKET "ROQUETTE RECUPEREE." #define GOTROCKBOX "CAISSE DE ROQUETTES RECUPEREE." #define GOTCELL "CELLULE D'ENERGIE RECUPEREE." #define GOTCELLBOX "PACK DE CELLULES D'ENERGIE RECUPERE." #define GOTSHELLS "4 CARTOUCHES RECUPEREES." #define GOTSHELLBOX "BOITE DE CARTOUCHES RECUPEREE." #define GOTBACKPACK "SAC PLEIN DE MUNITIONS RECUPERE!"
#define GOTBFG9000 "VOUS AVEZ UN BFG9000! OH, OUI!" #define GOTCHAINGUN "VOUS AVEZ LA MITRAILLEUSE!" #define GOTCHAINSAW "UNE TRONCONNEUSE!" #define GOTLAUNCHER "VOUS AVEZ UN LANCE-ROQUETTES!" #define GOTPLASMA "VOUS AVEZ UN FUSIL A PLASMA!" #define GOTSHOTGUN "VOUS AVEZ UN FUSIL!" #define GOTSHOTGUN2 "VOUS AVEZ UN SUPER FUSIL!"
// // P_Doors.C // #define PD_BLUEO "IL VOUS FAUT UNE CLEF BLEUE" #define PD_REDO "IL VOUS FAUT UNE CLEF ROUGE" #define PD_YELLOWO "IL VOUS FAUT UNE CLEF JAUNE" #define PD_BLUEK PD_BLUEO #define PD_REDK PD_REDO #define PD_YELLOWK PD_YELLOWO
// // G_game.C // #define GGSAVED "JEU SAUVEGARDE."
// // HU_stuff.C // #define HUSTR_MSGU "[MESSAGE NON ENVOYE]"
#define HUSTR_E1M1 "E1M1: HANGAR" #define HUSTR_E1M2 "E1M2: USINE NUCLEAIRE " #define HUSTR_E1M3 "E1M3: RAFFINERIE DE TOXINES " #define HUSTR_E1M4 "E1M4: CENTRE DE CONTROLE " #define HUSTR_E1M5 "E1M5: LABORATOIRE PHOBOS " #define HUSTR_E1M6 "E1M6: TRAITEMENT CENTRAL " #define HUSTR_E1M7 "E1M7: CENTRE INFORMATIQUE " #define HUSTR_E1M8 "E1M8: ANOMALIE PHOBOS " #define HUSTR_E1M9 "E1M9: BASE MILITAIRE "
#define HUSTR_E2M1 "E2M1: ANOMALIE DEIMOS " #define HUSTR_E2M2 "E2M2: ZONE DE CONFINEMENT " #define HUSTR_E2M3 "E2M3: RAFFINERIE" #define HUSTR_E2M4 "E2M4: LABORATOIRE DEIMOS " #define HUSTR_E2M5 "E2M5: CENTRE DE CONTROLE " #define HUSTR_E2M6 "E2M6: HALLS DES DAMNES " #define HUSTR_E2M7 "E2M7: CUVES DE REPRODUCTION " #define HUSTR_E2M8 "E2M8: TOUR DE BABEL " #define HUSTR_E2M9 "E2M9: FORTERESSE DU MYSTERE "
#define HUSTR_E3M1 "E3M1: DONJON DE L'ENFER " #define HUSTR_E3M2 "E3M2: BOURBIER DU DESESPOIR " #define HUSTR_E3M3 "E3M3: PANDEMONIUM" #define HUSTR_E3M4 "E3M4: MAISON DE LA DOULEUR " #define HUSTR_E3M5 "E3M5: CATHEDRALE PROFANE " #define HUSTR_E3M6 "E3M6: MONT EREBUS" #define HUSTR_E3M7 "E3M7: LIMBES" #define HUSTR_E3M8 "E3M8: DIS" #define HUSTR_E3M9 "E3M9: CLAPIERS"
#define HUSTR_1 "NIVEAU 1: ENTREE " #define HUSTR_2 "NIVEAU 2: HALLS SOUTERRAINS " #define HUSTR_3 "NIVEAU 3: LE FEU NOURRI " #define HUSTR_4 "NIVEAU 4: LE FOYER " #define HUSTR_5 "NIVEAU 5: LES EGOUTS " #define HUSTR_6 "NIVEAU 6: LE BROYEUR " #define HUSTR_7 "NIVEAU 7: L'HERBE DE LA MORT" #define HUSTR_8 "NIVEAU 8: RUSES ET PIEGES " #define HUSTR_9 "NIVEAU 9: LE PUITS " #define HUSTR_10 "NIVEAU 10: BASE DE RAVITAILLEMENT " #define HUSTR_11 "NIVEAU 11: LE CERCLE DE LA MORT!"
#define HUSTR_12 "NIVEAU 12: L'USINE " #define HUSTR_13 "NIVEAU 13: LE CENTRE VILLE" #define HUSTR_14 "NIVEAU 14: LES ANTRES PROFONDES " #define HUSTR_15 "NIVEAU 15: LA ZONE INDUSTRIELLE " #define HUSTR_16 "NIVEAU 16: LA BANLIEUE" #define HUSTR_17 "NIVEAU 17: LES IMMEUBLES" #define HUSTR_18 "NIVEAU 18: LA COUR " #define HUSTR_19 "NIVEAU 19: LA CITADELLE " #define HUSTR_20 "NIVEAU 20: JE T'AI EU!"
#define HUSTR_21 "NIVEAU 21: LE NIRVANA" #define HUSTR_22 "NIVEAU 22: LES CATACOMBES " #define HUSTR_23 "NIVEAU 23: LA GRANDE FETE " #define HUSTR_24 "NIVEAU 24: LE GOUFFRE " #define HUSTR_25 "NIVEAU 25: LES CHUTES DE SANG" #define HUSTR_26 "NIVEAU 26: LES MINES ABANDONNEES " #define HUSTR_27 "NIVEAU 27: CHEZ LES MONSTRES " #define HUSTR_28 "NIVEAU 28: LE MONDE DE L'ESPRIT " #define HUSTR_29 "NIVEAU 29: LA LIMITE " #define HUSTR_30 "NIVEAU 30: L'ICONE DU PECHE "
#define HUSTR_31 "NIVEAU 31: WOLFENSTEIN" #define HUSTR_32 "NIVEAU 32: LE MASSACRE"
#define HUSTR_CHATMACRO1 "JE SUIS PRET A LEUR EN FAIRE BAVER!" #define HUSTR_CHATMACRO2 "JE VAIS BIEN." #define HUSTR_CHATMACRO3 "JE N'AI PAS L'AIR EN FORME!" #define HUSTR_CHATMACRO4 "AU SECOURS!" #define HUSTR_CHATMACRO5 "TU CRAINS!" #define HUSTR_CHATMACRO6 "LA PROCHAINE FOIS, MINABLE..." #define HUSTR_CHATMACRO7 "VIENS ICI!" #define HUSTR_CHATMACRO8 "JE VAIS M'EN OCCUPER." #define HUSTR_CHATMACRO9 "OUI" #define HUSTR_CHATMACRO0 "NON"
#define HUSTR_TALKTOSELF1 "VOUS PARLEZ TOUT SEUL " #define HUSTR_TALKTOSELF2 "QUI EST LA?" #define HUSTR_TALKTOSELF3 "VOUS VOUS FAITES PEUR " #define HUSTR_TALKTOSELF4 "VOUS COMMENCEZ A DELIRER " #define HUSTR_TALKTOSELF5 "VOUS ETES LARGUE..."
#define HUSTR_MESSAGESENT "[MESSAGE ENVOYE]"
// The following should NOT be changed unless it seems // just AWFULLY necessary
#define HUSTR_PLRGREEN "VERT: " #define HUSTR_PLRINDIGO "INDIGO: " #define HUSTR_PLRBROWN "BRUN: " #define HUSTR_PLRRED "ROUGE: "
#define HUSTR_KEYGREEN 'g' // french key should be "V" #define HUSTR_KEYINDIGO 'i' #define HUSTR_KEYBROWN 'b' #define HUSTR_KEYRED 'r'
// // AM_map.C //
#define AMSTR_FOLLOWON "MODE POURSUITE ON" #define AMSTR_FOLLOWOFF "MODE POURSUITE OFF"
#define AMSTR_GRIDON "GRILLE ON" #define AMSTR_GRIDOFF "GRILLE OFF"
#define AMSTR_MARKEDSPOT "REPERE MARQUE " #define AMSTR_MARKSCLEARED "REPERES EFFACES "
// // ST_stuff.C //
#define STSTR_MUS "CHANGEMENT DE MUSIQUE " #define STSTR_NOMUS "IMPOSSIBLE SELECTION" #define STSTR_DQDON "INVULNERABILITE ON " #define STSTR_DQDOFF "INVULNERABILITE OFF"
#define STSTR_KFAADDED "ARMEMENT MAXIMUM! " #define STSTR_FAADDED "ARMES (SAUF CLEFS) AJOUTEES"
#define STSTR_NCON "BARRIERES ON" #define STSTR_NCOFF "BARRIERES OFF"
#define STSTR_BEHOLD " inVuln, Str, Inviso, Rad, Allmap, or Lite-amp" #define STSTR_BEHOLDX "AMELIORATION ACTIVEE"
#define STSTR_CHOPPERS "... DOESN'T SUCK - GM" #define STSTR_CLEV "CHANGEMENT DE NIVEAU..."
// // F_Finale.C // #define E1TEXT "APRES AVOIR VAINCU LES GROS MECHANTS\n"\ "ET NETTOYE LA BASE LUNAIRE, VOUS AVEZ\n"\ "GAGNE, NON? PAS VRAI? OU EST DONC VOTRE\n"\ " RECOMPENSE ET VOTRE BILLET DE\n"\ "RETOUR? QU'EST-QUE CA VEUT DIRE?CE"\ "N'EST PAS LA FIN ESPEREE!\n"\ "\n" \ "CA SENT LA VIANDE PUTREFIEE, MAIS\n"\ "ON DIRAIT LA BASE DEIMOS. VOUS ETES\n"\ "APPAREMMENT BLOQUE AUX PORTES DE L'ENFER.\n"\ "LA SEULE ISSUE EST DE L'AUTRE COTE.\n"\ "\n"\ "POUR VIVRE LA SUITE DE DOOM, JOUEZ\n"\ "A 'AUX PORTES DE L'ENFER' ET A\n"\ "L'EPISODE SUIVANT, 'L'ENFER'!\n" #define E2TEXT "VOUS AVEZ REUSSI. L'INFAME DEMON\n"\ "QUI CONTROLAIT LA BASE LUNAIRE DE\n"\ "DEIMOS EST MORT, ET VOUS AVEZ\n"\ "TRIOMPHE! MAIS... OU ETES-VOUS?\n"\ "VOUS GRIMPEZ JUSQU'AU BORD DE LA\n"\ "LUNE ET VOUS DECOUVREZ L'ATROCE\n"\ "VERITE.\n" \ "\n"\ "DEIMOS EST AU-DESSUS DE L'ENFER!\n"\ "VOUS SAVEZ QUE PERSONNE NE S'EN\n"\ "EST JAMAIS ECHAPPE, MAIS CES FUMIERS\n"\ "VONT REGRETTER DE VOUS AVOIR CONNU!\n"\ "VOUS REDESCENDEZ RAPIDEMENT VERS\n"\ "LA SURFACE DE L'ENFER.\n"\ "\n" \ "VOICI MAINTENANT LE CHAPITRE FINAL DE\n"\ "DOOM! -- L'ENFER."
#define E3TEXT "LE DEMON ARACHNEEN ET REPUGNANT\n"\ "QUI A DIRIGE L'INVASION DES BASES\n"\ "LUNAIRES ET SEME LA MORT VIENT DE SE\n"\ "FAIRE PULVERISER UNE FOIS POUR TOUTES.\n"\ "\n"\ "UNE PORTE SECRETE S'OUVRE. VOUS ENTREZ.\n"\ "VOUS AVEZ PROUVE QUE VOUS POUVIEZ\n"\ "RESISTER AUX HORREURS DE L'ENFER.\n"\ "IL SAIT ETRE BEAU JOUEUR, ET LORSQUE\n"\ "VOUS SORTEZ, VOUS REVOYEZ LES VERTES\n"\ "PRAIRIES DE LA TERRE, VOTRE PLANETE.\n"\ "\n"\ "VOUS VOUS DEMANDEZ CE QUI S'EST PASSE\n"\ "SUR TERRE PENDANT QUE VOUS AVEZ\n"\ "COMBATTU LE DEMON. HEUREUSEMENT,\n"\ "AUCUN GERME DU MAL N'A FRANCHI\n"\ "CETTE PORTE AVEC VOUS..."
// after level 6, put this:
#define C1TEXT "VOUS ETES AU PLUS PROFOND DE L'ASTROPORT\n" \ "INFESTE DE MONSTRES, MAIS QUELQUE CHOSE\n" \ "NE VA PAS. ILS ONT APPORTE LEUR PROPRE\n" \ "REALITE, ET LA TECHNOLOGIE DE L'ASTROPORT\n" \ "EST AFFECTEE PAR LEUR PRESENCE.\n" \ "\n"\ "DEVANT VOUS, VOUS VOYEZ UN POSTE AVANCE\n" \ "DE L'ENFER, UNE ZONE FORTIFIEE. SI VOUS\n" \ "POUVEZ PASSER, VOUS POURREZ PENETRER AU\n" \ "COEUR DE LA BASE HANTEE ET TROUVER \n" \ "L'INTERRUPTEUR DE CONTROLE QUI GARDE LA \n" \ "POPULATION DE LA TERRE EN OTAGE."
// After level 11, put this:
#define C2TEXT "VOUS AVEZ GAGNE! VOTRE VICTOIRE A PERMIS\n" \ "A L'HUMANITE D'EVACUER LA TERRE ET \n"\ "D'ECHAPPER AU CAUCHEMAR. VOUS ETES \n"\ "MAINTENANT LE DERNIER HUMAIN A LA SURFACE \n"\ "DE LA PLANETE. VOUS ETES ENTOURE DE \n"\ "MUTANTS CANNIBALES, D'EXTRATERRESTRES \n"\ "CARNIVORES ET D'ESPRITS DU MAL. VOUS \n"\ "ATTENDEZ CALMEMENT LA MORT, HEUREUX \n"\ "D'AVOIR PU SAUVER VOTRE RACE.\n"\ "MAIS UN MESSAGE VOUS PARVIENT SOUDAIN\n"\ "DE L'ESPACE: \"NOS CAPTEURS ONT LOCALISE\n"\ "LA SOURCE DE L'INVASION EXTRATERRESTRE.\n"\ "SI VOUS Y ALLEZ, VOUS POURREZ PEUT-ETRE\n"\ "LES ARRETER. LEUR BASE EST SITUEE AU COEUR\n"\ "DE VOTRE VILLE NATALE, PRES DE L'ASTROPORT.\n"\ "VOUS VOUS RELEVEZ LENTEMENT ET PENIBLEMENT\n"\ "ET VOUS REPARTEZ POUR LE FRONT."
// After level 20, put this:
#define C3TEXT "VOUS ETES AU COEUR DE LA CITE CORROMPUE,\n"\ "ENTOURE PAR LES CADAVRES DE VOS ENNEMIS.\n"\ "VOUS NE VOYEZ PAS COMMENT DETRUIRE LA PORTE\n"\ "DES CREATURES DE CE COTE. VOUS SERREZ\n"\ "LES DENTS ET PLONGEZ DANS L'OUVERTURE.\n"\ "\n"\ "IL DOIT Y AVOIR UN MOYEN DE LA FERMER\n"\ "DE L'AUTRE COTE. VOUS ACCEPTEZ DE\n"\ "TRAVERSER L'ENFER POUR LE FAIRE?"
// After level 29, put this:
#define C4TEXT "LE VISAGE HORRIBLE D'UN DEMON D'UNE\n"\ "TAILLE INCROYABLE S'EFFONDRE DEVANT\n"\ "VOUS LORSQUE VOUS TIREZ UNE SALVE DE\n"\ "ROQUETTES DANS SON CERVEAU. LE MONSTRE\n"\ "SE RATATINE, SES MEMBRES DECHIQUETES\n"\ "SE REPANDANT SUR DES CENTAINES DE\n"\ "KILOMETRES A LA SURFACE DE L'ENFER.\n"\ "\n"\ "VOUS AVEZ REUSSI. L'INVASION N'AURA.\n"\ "PAS LIEU. LA TERRE EST SAUVEE. L'ENFER\n"\ "EST ANEANTI. EN VOUS DEMANDANT OU IRONT\n"\ "MAINTENANT LES DAMNES, VOUS ESSUYEZ\n"\ "VOTRE FRONT COUVERT DE SUEUR ET REPARTEZ\n"\ "VERS LA TERRE. SA RECONSTRUCTION SERA\n"\ "BEAUCOUP PLUS DROLE QUE SA DESTRUCTION.\n"
// Before level 31, put this:
#define C5TEXT "FELICITATIONS! VOUS AVEZ TROUVE LE\n"\ "NIVEAU SECRET! IL SEMBLE AVOIR ETE\n"\ "CONSTRUIT PAR LES HUMAINS. VOUS VOUS\n"\ "DEMANDEZ QUELS PEUVENT ETRE LES\n"\ "HABITANTS DE CE COIN PERDU DE L'ENFER."
// Before level 32, put this:
#define C6TEXT "FELICITATIONS! VOUS AVEZ DECOUVERT\n"\ "LE NIVEAU SUPER SECRET! VOUS FERIEZ\n"\ "MIEUX DE FONCER DANS CELUI-LA!\n"
// // Character cast strings F_FINALE.C // #define CC_ZOMBIE "ZOMBIE" #define CC_SHOTGUN "TYPE AU FUSIL" #define CC_HEAVY "MEC SUPER-ARME" #define CC_IMP "DIABLOTIN" #define CC_DEMON "DEMON" #define CC_LOST "AME PERDUE" #define CC_CACO "CACODEMON" #define CC_HELL "CHEVALIER DE L'ENFER" #define CC_BARON "BARON DE L'ENFER" #define CC_ARACH "ARACHNOTRON" #define CC_PAIN "ELEMENTAIRE DE LA DOULEUR" #define CC_REVEN "REVENANT" #define CC_MANCU "MANCUBUS" #define CC_ARCH "ARCHI-INFAME" #define CC_SPIDER "L'ARAIGNEE CERVEAU" #define CC_CYBER "LE CYBERDEMON" #define CC_HERO "NOTRE HEROS"
#endif //----------------------------------------------------------------------------- // // $Log:$ // //-----------------------------------------------------------------------------
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id:$";
// We are referring to sprite numbers. #include "info.h"
#ifdef __GNUG__ #pragma implementation "d_items.h" #endif #include "d_items.h"
// // PSPRITE ACTIONS for waepons. // This struct controls the weapon animations. // // Each entry is: // ammo/amunition type // upstate // downstate // readystate // atkstate, i.e. attack/fire/hit frame // flashstate, muzzle flash // weaponinfo_t weaponinfo[NUMWEAPONS] = { { // fist am_noammo, S_PUNCHUP, S_PUNCHDOWN, S_PUNCH, S_PUNCH1, S_NULL }, { // pistol am_clip, S_PISTOLUP, S_PISTOLDOWN, S_PISTOL, S_PISTOL1, S_PISTOLFLASH }, { // shotgun am_shell, S_SGUNUP, S_SGUNDOWN, S_SGUN, S_SGUN1, S_SGUNFLASH1 }, { // chaingun am_clip, S_CHAINUP, S_CHAINDOWN, S_CHAIN, S_CHAIN1, S_CHAINFLASH1 }, { // missile launcher am_misl, S_MISSILEUP, S_MISSILEDOWN, S_MISSILE, S_MISSILE1, S_MISSILEFLASH1 }, { // plasma rifle am_cell, S_PLASMAUP, S_PLASMADOWN, S_PLASMA, S_PLASMA1, S_PLASMAFLASH1 }, { // bfg 9000 am_cell, S_BFGUP, S_BFGDOWN, S_BFG, S_BFG1, S_BFGFLASH1 }, { // chainsaw am_noammo, S_SAWUP, S_SAWDOWN, S_SAW, S_SAW1, S_NULL }, { // super shotgun am_shell, S_DSGUNUP, S_DSGUNDOWN, S_DSGUN, S_DSGUN1, S_DSGUNFLASH1 }, };
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // Items: key cards, artifacts, weapon, ammunition. // //-----------------------------------------------------------------------------
#ifndef __D_ITEMS__ #define __D_ITEMS__
#include "doomdef.h"
#ifdef __GNUG__ #pragma interface #endif
// Weapon info: sprite frames, ammunition use. typedef struct { ammotype_t ammo; int upstate; int downstate; int readystate; int atkstate; int flashstate;
} weaponinfo_t;
extern weaponinfo_t weaponinfo[NUMWEAPONS];
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // DOOM main program (D_DoomMain) and game loop (D_DoomLoop), // plus functions to determine game mode (shareware, registered), // parse command line parameters, configure game parameters (turbo), // and call the startup functions. // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: d_main.c,v 1.8 1997/02/03 22:45:09 b1 Exp $";
#define BGCOLOR 7 #define FGCOLOR 8
#ifdef NORMALUNIX #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #endif
#include "doomdef.h" #include "doomstat.h"
#include "dstrings.h" #include "sounds.h"
#include "z_zone.h" #include "w_wad.h" #include "s_sound.h" #include "v_video.h"
#include "f_finale.h" #include "f_wipe.h"
#include "m_argv.h" #include "m_misc.h" #include "m_menu.h"
#include "i_system.h" #include "i_sound.h" #include "i_video.h"
#include "g_game.h"
#include "hu_stuff.h" #include "wi_stuff.h" #include "st_stuff.h" #include "am_map.h"
#include "p_setup.h" #include "r_local.h"
#include "d_main.h"
// // D-DoomLoop() // Not a globally visible function, // just included for source reference, // called by D_DoomMain, never exits. // Manages timing and IO, // calls all ?_Responder, ?_Ticker, and ?_Drawer, // calls I_GetTime, I_StartFrame, and I_StartTic // void D_DoomLoop (void);
char* wadfiles[MAXWADFILES];
boolean devparm; // started game with -devparm boolean nomonsters; // checkparm of -nomonsters boolean respawnparm; // checkparm of -respawn boolean fastparm; // checkparm of -fast
boolean drone;
boolean singletics = false; // debug flag to cancel adaptiveness
//extern int soundVolume; //extern int sfxVolume; //extern int musicVolume;
extern boolean inhelpscreens;
skill_t startskill; int startepisode; int startmap; boolean autostart;
FILE* debugfile;
boolean advancedemo;
char wadfile[1024]; // primary wad file char mapdir[1024]; // directory of development maps char basedefault[1024]; // default file
void D_CheckNetGame (void); void D_ProcessEvents (void); void G_BuildTiccmd (ticcmd_t* cmd); void D_DoAdvanceDemo (void);
// // EVENT HANDLING // // Events are asynchronous inputs generally generated by the game user. // Events can be discarded if no responder claims them // event_t events[MAXEVENTS]; int eventhead; int eventtail;
// // D_PostEvent // Called by the I/O functions when input is detected // void D_PostEvent (event_t* ev) { events[eventhead] = *ev; eventhead = (++eventhead)&(MAXEVENTS-1); }
// // D_ProcessEvents // Send all the events of the given timestamp down the responder chain // void D_ProcessEvents (void) { event_t* ev; // IF STORE DEMO, DO NOT ACCEPT INPUT if ( ( gamemode == commercial ) && (W_CheckNumForName("map01")<0) ) return; for ( ; eventtail != eventhead ; eventtail = (++eventtail)&(MAXEVENTS-1) ) { ev = &events[eventtail]; if (M_Responder (ev)) continue; // menu ate the event G_Responder (ev); } }
// // D_Display // draw current display, possibly wiping it from the previous //
// wipegamestate can be set to -1 to force a wipe on the next draw gamestate_t wipegamestate = GS_DEMOSCREEN; extern boolean setsizeneeded; extern int showMessages; void R_ExecuteSetViewSize (void);
void D_Display (void) { static boolean viewactivestate = false; static boolean menuactivestate = false; static boolean inhelpscreensstate = false; static boolean fullscreen = false; static gamestate_t oldgamestate = -1; static int borderdrawcount; int nowtime; int tics; int wipestart; int y; boolean done; boolean wipe; boolean redrawsbar;
if (nodrawers) return; // for comparative timing / profiling redrawsbar = false;
// change the view size if needed if (setsizeneeded) { R_ExecuteSetViewSize (); oldgamestate = -1; // force background redraw borderdrawcount = 3; }
// save the current screen if about to wipe if (gamestate != wipegamestate) { wipe = true; wipe_StartScreen(0, 0, SCREENWIDTH, SCREENHEIGHT); } else wipe = false;
if (gamestate == GS_LEVEL && gametic) HU_Erase();
// do buffered drawing switch (gamestate) { case GS_LEVEL: if (!gametic) break; if (automapactive) AM_Drawer (); if (wipe || (viewheight != 200 && fullscreen) ) redrawsbar = true; if (inhelpscreensstate && !inhelpscreens) redrawsbar = true; // just put away the help screen ST_Drawer (viewheight == 200, redrawsbar ); fullscreen = viewheight == 200; break;
case GS_INTERMISSION: WI_Drawer (); break;
case GS_FINALE: F_Drawer (); break;
case GS_DEMOSCREEN: D_PageDrawer (); break; }
// draw buffered stuff to screen I_UpdateNoBlit ();
// draw the view directly if (gamestate == GS_LEVEL && !automapactive && gametic) R_RenderPlayerView (&players[displayplayer]);
if (gamestate == GS_LEVEL && gametic) HU_Drawer ();
// clean up border stuff if (gamestate != oldgamestate && gamestate != GS_LEVEL) I_SetPalette (W_CacheLumpName ("PLAYPAL",PU_CACHE));
// see if the border needs to be initially drawn if (gamestate == GS_LEVEL && oldgamestate != GS_LEVEL) { viewactivestate = false; // view was not active R_FillBackScreen (); // draw the pattern into the back screen }
// see if the border needs to be updated to the screen if (gamestate == GS_LEVEL && !automapactive && scaledviewwidth != 320) { if (menuactive || menuactivestate || !viewactivestate) borderdrawcount = 3; if (borderdrawcount) { R_DrawViewBorder (); // erase old menu stuff borderdrawcount--; }
}
menuactivestate = menuactive; viewactivestate = viewactive; inhelpscreensstate = inhelpscreens; oldgamestate = wipegamestate = gamestate;
// draw pause pic if (paused) { if (automapactive) y = 4; else y = viewwindowy+4; V_DrawPatchDirect(viewwindowx+(scaledviewwidth-68)/2, y,0,W_CacheLumpName ("M_PAUSE", PU_CACHE)); }
// menus go directly to the screen M_Drawer (); // menu is drawn even on top of everything NetUpdate (); // send out any new accumulation
// normal update if (!wipe) { I_FinishUpdate (); // page flip or blit buffer return; }
// wipe update wipe_EndScreen(0, 0, SCREENWIDTH, SCREENHEIGHT);
wipestart = I_GetTime () - 1;
do { do { nowtime = I_GetTime (); tics = nowtime - wipestart; } while (!tics); wipestart = nowtime; done = wipe_ScreenWipe(wipe_Melt , 0, 0, SCREENWIDTH, SCREENHEIGHT, tics); I_UpdateNoBlit (); M_Drawer (); // menu is drawn even on top of wipes I_FinishUpdate (); // page flip or blit buffer } while (!done); }
// // D_DoomLoop // extern boolean demorecording;
void D_DoomLoop (void) { if (demorecording) G_BeginRecording (); if (M_CheckParm ("-debugfile")) { char filename[20]; sprintf (filename,"debug%i.txt",consoleplayer); printf ("debug output to: %s\n",filename); debugfile = fopen (filename,"w"); } I_InitGraphics ();
while (1) { // frame syncronous IO operations I_StartFrame (); // process one or more tics if (singletics) { I_StartTic (); D_ProcessEvents (); G_BuildTiccmd (&netcmds[consoleplayer][maketic%BACKUPTICS]); if (advancedemo) D_DoAdvanceDemo (); M_Ticker (); G_Ticker (); gametic++; maketic++; } else { TryRunTics (); // will run at least one tic } S_UpdateSounds (players[consoleplayer].mo);// move positional sounds
// Update display, next frame, with current state. D_Display ();
#ifndef SNDSERV // Sound mixing for the buffer is snychronous. I_UpdateSound(); #endif // Synchronous sound output is explicitly called. #ifndef SNDINTR // Update sound output. I_SubmitSound(); #endif } }
// // DEMO LOOP // int demosequence; int pagetic; char *pagename;
// // D_PageTicker // Handles timing for warped projection // void D_PageTicker (void) { if (--pagetic < 0) D_AdvanceDemo (); }
// // D_PageDrawer // void D_PageDrawer (void) { V_DrawPatch (0,0, 0, W_CacheLumpName(pagename, PU_CACHE)); }
// // D_AdvanceDemo // Called after each demo or intro demosequence finishes // void D_AdvanceDemo (void) { advancedemo = true; }
// // This cycles through the demo sequences. // FIXME - version dependend demo numbers? // void D_DoAdvanceDemo (void) { players[consoleplayer].playerstate = PST_LIVE; // not reborn advancedemo = false; usergame = false; // no save / end game here paused = false; gameaction = ga_nothing;
if ( gamemode == retail ) demosequence = (demosequence+1)%7; else demosequence = (demosequence+1)%6;
switch (demosequence) { case 0: if ( gamemode == commercial ) pagetic = 35 * 11; else pagetic = 170; gamestate = GS_DEMOSCREEN; pagename = "TITLEPIC"; if ( gamemode == commercial ) S_StartMusic(mus_dm2ttl); else S_StartMusic (mus_intro); break; case 1: G_DeferedPlayDemo ("demo1"); break; case 2: pagetic = 200; gamestate = GS_DEMOSCREEN; pagename = "CREDIT"; break; case 3: G_DeferedPlayDemo ("demo2"); break; case 4: gamestate = GS_DEMOSCREEN; if ( gamemode == commercial) { pagetic = 35 * 11; pagename = "TITLEPIC"; S_StartMusic(mus_dm2ttl); } else { pagetic = 200;
if ( gamemode == retail ) pagename = "CREDIT"; else pagename = "HELP2"; } break; case 5: G_DeferedPlayDemo ("demo3"); break; // THE DEFINITIVE DOOM Special Edition demo case 6: G_DeferedPlayDemo ("demo4"); break; } }
// // D_StartTitle // void D_StartTitle (void) { gameaction = ga_nothing; demosequence = -1; D_AdvanceDemo (); }
// print title for every printed line char title[128];
// // D_AddFile // void D_AddFile (char *file) { int numwadfiles; char *newfile; for (numwadfiles = 0 ; wadfiles[numwadfiles] ; numwadfiles++) ;
newfile = malloc (strlen(file)+1); strcpy (newfile, file); wadfiles[numwadfiles] = newfile; }
// // IdentifyVersion // Checks availability of IWAD files by name, // to determine whether registered/commercial features // should be executed (notably loading PWAD's). // void IdentifyVersion (void) {
char* doom1wad; char* doomwad; char* doomuwad; char* doom2wad;
char* doom2fwad; char* plutoniawad; char* tntwad;
#ifdef NORMALUNIX char *home; char *doomwaddir; doomwaddir = getenv("DOOMWADDIR"); if (!doomwaddir) doomwaddir = ".";
// Commercial. doom2wad = malloc(strlen(doomwaddir)+1+9+1); sprintf(doom2wad, "%s/doom2.wad", doomwaddir);
// Retail. doomuwad = malloc(strlen(doomwaddir)+1+8+1); sprintf(doomuwad, "%s/doomu.wad", doomwaddir);
// Registered. doomwad = malloc(strlen(doomwaddir)+1+8+1); sprintf(doomwad, "%s/doom.wad", doomwaddir);
// Shareware. doom1wad = malloc(strlen(doomwaddir)+1+9+1); sprintf(doom1wad, "%s/doom1.wad", doomwaddir);
// Bug, dear Shawn. // Insufficient malloc, caused spurious realloc errors. plutoniawad = malloc(strlen(doomwaddir)+1+/*9*/12+1); sprintf(plutoniawad, "%s/plutonia.wad", doomwaddir);
tntwad = malloc(strlen(doomwaddir)+1+9+1); sprintf(tntwad, "%s/tnt.wad", doomwaddir);
// French stuff. doom2fwad = malloc(strlen(doomwaddir)+1+10+1); sprintf(doom2fwad, "%s/doom2f.wad", doomwaddir);
home = getenv("HOME"); if (!home) I_Error("Please set $HOME to your home directory"); sprintf(basedefault, "%s/.doomrc", home); #endif
if (M_CheckParm ("-shdev")) { gamemode = shareware; devparm = true; D_AddFile (DEVDATA"doom1.wad"); D_AddFile (DEVMAPS"data_se/texture1.lmp"); D_AddFile (DEVMAPS"data_se/pnames.lmp"); strcpy (basedefault,DEVDATA"default.cfg"); return; }
if (M_CheckParm ("-regdev")) { gamemode = registered; devparm = true; D_AddFile (DEVDATA"doom.wad"); D_AddFile (DEVMAPS"data_se/texture1.lmp"); D_AddFile (DEVMAPS"data_se/texture2.lmp"); D_AddFile (DEVMAPS"data_se/pnames.lmp"); strcpy (basedefault,DEVDATA"default.cfg"); return; }
if (M_CheckParm ("-comdev")) { gamemode = commercial; devparm = true; /* I don't bother if(plutonia) D_AddFile (DEVDATA"plutonia.wad"); else if(tnt) D_AddFile (DEVDATA"tnt.wad"); else*/ D_AddFile (DEVDATA"doom2.wad"); D_AddFile (DEVMAPS"cdata/texture1.lmp"); D_AddFile (DEVMAPS"cdata/pnames.lmp"); strcpy (basedefault,DEVDATA"default.cfg"); return; }
if ( !access (doom2fwad,R_OK) ) { gamemode = commercial; // C'est ridicule! // Let's handle languages in config files, okay? language = french; printf("French version\n"); D_AddFile (doom2fwad); return; }
if ( !access (doom2wad,R_OK) ) { gamemode = commercial; D_AddFile (doom2wad); return; }
if ( !access (plutoniawad, R_OK ) ) { gamemode = commercial; D_AddFile (plutoniawad); return; }
if ( !access ( tntwad, R_OK ) ) { gamemode = commercial; D_AddFile (tntwad); return; }
if ( !access (doomuwad,R_OK) ) { gamemode = retail; D_AddFile (doomuwad); return; }
if ( !access (doomwad,R_OK) ) { gamemode = registered; D_AddFile (doomwad); return; }
if ( !access (doom1wad,R_OK) ) { gamemode = shareware; D_AddFile (doom1wad); return; }
printf("Game mode indeterminate.\n"); gamemode = indetermined;
// We don't abort. Let's see what the PWAD contains. //exit(1); //I_Error ("Game mode indeterminate\n"); }
// // Find a Response File // void FindResponseFile (void) { int i; #define MAXARGVS 100 for (i = 1;i < myargc;i++) if (myargv[i][0] == '@') { FILE * handle; int size; int k; int index; int indexinfile; char *infile; char *file; char *moreargs[20]; char *firstargv; // READ THE RESPONSE FILE INTO MEMORY handle = fopen (&myargv[i][1],"rb"); if (!handle) { printf ("\nNo such response file!"); exit(1); } printf("Found response file %s!\n",&myargv[i][1]); fseek (handle,0,SEEK_END); size = ftell(handle); fseek (handle,0,SEEK_SET); file = malloc (size); fread (file,size,1,handle); fclose (handle); // KEEP ALL CMDLINE ARGS FOLLOWING @RESPONSEFILE ARG for (index = 0,k = i+1; k < myargc; k++) moreargs[index++] = myargv[k]; firstargv = myargv[0]; myargv = malloc(sizeof(char *)*MAXARGVS); memset(myargv,0,sizeof(char *)*MAXARGVS); myargv[0] = firstargv; infile = file; indexinfile = k = 0; indexinfile++; // SKIP PAST ARGV[0] (KEEP IT) do { myargv[indexinfile++] = infile+k; while(k < size && ((*(infile+k)>= ' '+1) && (*(infile+k)<='z'))) k++; *(infile+k) = 0; while(k < size && ((*(infile+k)<= ' ') || (*(infile+k)>'z'))) k++; } while(k < size); for (k = 0;k < index;k++) myargv[indexinfile++] = moreargs[k]; myargc = indexinfile; // DISPLAY ARGS printf("%d command-line args:\n",myargc); for (k=1;k<myargc;k++) printf("%s\n",myargv[k]);
break; } }
// // D_DoomMain // void D_DoomMain (void) { int p; char file[256];
FindResponseFile (); IdentifyVersion (); setbuf (stdout, NULL); modifiedgame = false; nomonsters = M_CheckParm ("-nomonsters"); respawnparm = M_CheckParm ("-respawn"); fastparm = M_CheckParm ("-fast"); devparm = M_CheckParm ("-devparm"); if (M_CheckParm ("-altdeath")) deathmatch = 2; else if (M_CheckParm ("-deathmatch")) deathmatch = 1;
switch ( gamemode ) { case retail: sprintf (title, " " "The Ultimate DOOM Startup v%i.%i" " ", VERSION/100,VERSION%100); break; case shareware: sprintf (title, " " "DOOM Shareware Startup v%i.%i" " ", VERSION/100,VERSION%100); break; case registered: sprintf (title, " " "DOOM Registered Startup v%i.%i" " ", VERSION/100,VERSION%100); break; case commercial: sprintf (title, " " "DOOM 2: Hell on Earth v%i.%i" " ", VERSION/100,VERSION%100); break; /*FIXME case pack_plut: sprintf (title, " " "DOOM 2: Plutonia Experiment v%i.%i" " ", VERSION/100,VERSION%100); break; case pack_tnt: sprintf (title, " " "DOOM 2: TNT - Evilution v%i.%i" " ", VERSION/100,VERSION%100); break; */ default: sprintf (title, " " "Public DOOM - v%i.%i" " ", VERSION/100,VERSION%100); break; }
printf ("%s\n",title);
if (devparm) printf(D_DEVSTR);
if (M_CheckParm("-cdrom")) { printf(D_CDROM); mkdir("c:\\doomdata",0); strcpy (basedefault,"c:/doomdata/default.cfg"); }
// turbo option if ( (p=M_CheckParm ("-turbo")) ) { int scale = 200; extern int forwardmove[2]; extern int sidemove[2]; if (p<myargc-1) scale = atoi (myargv[p+1]); if (scale < 10) scale = 10; if (scale > 400) scale = 400; printf ("turbo scale: %i%%\n",scale); forwardmove[0] = forwardmove[0]*scale/100; forwardmove[1] = forwardmove[1]*scale/100; sidemove[0] = sidemove[0]*scale/100; sidemove[1] = sidemove[1]*scale/100; }
// add any files specified on the command line with -file wadfile // to the wad list // // convenience hack to allow -wart e m to add a wad file // prepend a tilde to the filename so wadfile will be reloadable p = M_CheckParm ("-wart"); if (p) { myargv[p][4] = 'p'; // big hack, change to -warp
// Map name handling. switch (gamemode ) { case shareware: case retail: case registered: sprintf (file,"~"DEVMAPS"E%cM%c.wad", myargv[p+1][0], myargv[p+2][0]); printf("Warping to Episode %s, Map %s.\n", myargv[p+1],myargv[p+2]); break; case commercial: default: p = atoi (myargv[p+1]); if (p<10) sprintf (file,"~"DEVMAPS"cdata/map0%i.wad", p); else sprintf (file,"~"DEVMAPS"cdata/map%i.wad", p); break; } D_AddFile (file); } p = M_CheckParm ("-file"); if (p) { // the parms after p are wadfile/lump names, // until end of parms or another - preceded parm modifiedgame = true; // homebrew levels while (++p != myargc && myargv[p][0] != '-') D_AddFile (myargv[p]); }
p = M_CheckParm ("-playdemo");
if (!p) p = M_CheckParm ("-timedemo");
if (p && p < myargc-1) { sprintf (file,"%s.lmp", myargv[p+1]); D_AddFile (file); printf("Playing demo %s.lmp.\n",myargv[p+1]); }
// get skill / episode / map from parms startskill = sk_medium; startepisode = 1; startmap = 1; autostart = false;
p = M_CheckParm ("-skill"); if (p && p < myargc-1) { startskill = myargv[p+1][0]-'1'; autostart = true; }
p = M_CheckParm ("-episode"); if (p && p < myargc-1) { startepisode = myargv[p+1][0]-'0'; startmap = 1; autostart = true; } p = M_CheckParm ("-timer"); if (p && p < myargc-1 && deathmatch) { int time; time = atoi(myargv[p+1]); printf("Levels will end after %d minute",time); if (time>1) printf("s"); printf(".\n"); }
p = M_CheckParm ("-avg"); if (p && p < myargc-1 && deathmatch) printf("Austin Virtual Gaming: Levels will end after 20 minutes\n");
p = M_CheckParm ("-warp"); if (p && p < myargc-1) { if (gamemode == commercial) startmap = atoi (myargv[p+1]); else { startepisode = myargv[p+1][0]-'0'; startmap = myargv[p+2][0]-'0'; } autostart = true; }
// init subsystems printf ("V_Init: allocate screens.\n"); V_Init ();
printf ("M_LoadDefaults: Load system defaults.\n"); M_LoadDefaults (); // load before initing other systems
printf ("Z_Init: Init zone memory allocation daemon. \n"); Z_Init ();
printf ("W_Init: Init WADfiles.\n"); W_InitMultipleFiles (wadfiles);
// Check for -file in shareware if (modifiedgame) { // These are the lumps that will be checked in IWAD, // if any one is not present, execution will be aborted. char name[23][8]= { "e2m1","e2m2","e2m3","e2m4","e2m5","e2m6","e2m7","e2m8","e2m9", "e3m1","e3m3","e3m3","e3m4","e3m5","e3m6","e3m7","e3m8","e3m9", "dphoof","bfgga0","heada1","cybra1","spida1d1" }; int i; if ( gamemode == shareware) I_Error("\nYou cannot -file with the shareware " "version. Register!");
// Check for fake IWAD with right name, // but w/o all the lumps of the registered version. if (gamemode == registered) for (i = 0;i < 23; i++) if (W_CheckNumForName(name[i])<0) I_Error("\nThis is not the registered version."); }
// Iff additonal PWAD files are used, print modified banner if (modifiedgame) { /*m*/printf ( "===========================================================================\n" "ATTENTION: This version of DOOM has been modified. If you would like to\n" "get a copy of the original game, call 1-800-IDGAMES or see the readme file.\n" " You will not receive technical support for modified games.\n" " press enter to continue\n" "===========================================================================\n" ); getchar (); }
// Check and print which version is executed. switch ( gamemode ) { case shareware: case indetermined: printf ( "===========================================================================\n" " Shareware!\n" "===========================================================================\n" ); break; case registered: case retail: case commercial: printf ( "===========================================================================\n" " Commercial product - do not distribute!\n" " Please report software piracy to the SPA: 1-800-388-PIR8\n" "===========================================================================\n" ); break; default: // Ouch. break; }
printf ("M_Init: Init miscellaneous info.\n"); M_Init ();
printf ("R_Init: Init DOOM refresh daemon - "); R_Init ();
printf ("\nP_Init: Init Playloop state.\n"); P_Init ();
printf ("I_Init: Setting up machine state.\n"); I_Init ();
printf ("D_CheckNetGame: Checking network game status.\n"); D_CheckNetGame ();
printf ("S_Init: Setting up sound.\n"); S_Init (snd_SfxVolume /* *8 */, snd_MusicVolume /* *8*/ );
printf ("HU_Init: Setting up heads up display.\n"); HU_Init ();
printf ("ST_Init: Init status bar.\n"); ST_Init ();
// check for a driver that wants intermission stats p = M_CheckParm ("-statcopy"); if (p && p<myargc-1) { // for statistics driver extern void* statcopy;
statcopy = (void*)atoi(myargv[p+1]); printf ("External statistics registered.\n"); }
// start the apropriate game based on parms p = M_CheckParm ("-record");
if (p && p < myargc-1) { G_RecordDemo (myargv[p+1]); autostart = true; } p = M_CheckParm ("-playdemo"); if (p && p < myargc-1) { singledemo = true; // quit after one demo G_DeferedPlayDemo (myargv[p+1]); D_DoomLoop (); // never returns } p = M_CheckParm ("-timedemo"); if (p && p < myargc-1) { G_TimeDemo (myargv[p+1]); D_DoomLoop (); // never returns } p = M_CheckParm ("-loadgame"); if (p && p < myargc-1) { if (M_CheckParm("-cdrom")) sprintf(file, "c:\\doomdata\\"SAVEGAMENAME"%c.dsg",myargv[p+1][0]); else sprintf(file, SAVEGAMENAME"%c.dsg",myargv[p+1][0]); G_LoadGame (file); }
if ( gameaction != ga_loadgame ) { if (autostart || netgame) G_InitNew (startskill, startepisode, startmap); else D_StartTitle (); // start up intro loop
}
D_DoomLoop (); // never returns } // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // System specific interface stuff. // //-----------------------------------------------------------------------------
#ifndef __D_MAIN__ #define __D_MAIN__
#include "d_event.h"
#ifdef __GNUG__ #pragma interface #endif
#define MAXWADFILES 20 extern char* wadfiles[MAXWADFILES];
void D_AddFile (char *file);
// // D_DoomMain() // Not a globally visible function, just included for source reference, // calls all startup code, parses command line options. // If not overrided by user input, calls N_AdvanceDemo. // void D_DoomMain (void);
// Called by IO functions when input is detected. void D_PostEvent (event_t* ev);
// // BASE LEVEL // void D_PageTicker (void); void D_PageDrawer (void); void D_AdvanceDemo (void); void D_StartTitle (void);
#endif // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // DOOM Network game communication and protocol, // all OS independend parts. // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: d_net.c,v 1.3 1997/02/03 22:01:47 b1 Exp $";
#include "m_menu.h" #include "i_system.h" #include "i_video.h" #include "i_net.h" #include "g_game.h" #include "doomdef.h" #include "doomstat.h"
#define NCMD_EXIT 0x80000000 #define NCMD_RETRANSMIT 0x40000000 #define NCMD_SETUP 0x20000000 #define NCMD_KILL 0x10000000 // kill game #define NCMD_CHECKSUM 0x0fffffff
doomcom_t* doomcom; doomdata_t* netbuffer; // points inside doomcom
// // NETWORKING // // gametic is the tic about to (or currently being) run // maketic is the tick that hasn't had control made for it yet // nettics[] has the maketics for all players // // a gametic cannot be run until nettics[] > gametic for all players // #define RESENDCOUNT 10 #define PL_DRONE 0x80 // bit flag in doomdata->player
ticcmd_t localcmds[BACKUPTICS];
ticcmd_t netcmds[MAXPLAYERS][BACKUPTICS]; int nettics[MAXNETNODES]; boolean nodeingame[MAXNETNODES]; // set false as nodes leave game boolean remoteresend[MAXNETNODES]; // set when local needs tics int resendto[MAXNETNODES]; // set when remote needs tics int resendcount[MAXNETNODES];
int nodeforplayer[MAXPLAYERS];
int maketic; int lastnettic; int skiptics; int ticdup; int maxsend; // BACKUPTICS/(2*ticdup)-1
void D_ProcessEvents (void); void G_BuildTiccmd (ticcmd_t *cmd); void D_DoAdvanceDemo (void);
boolean reboundpacket; doomdata_t reboundstore;
// // // int NetbufferSize (void) { return (int)&(((doomdata_t *)0)->cmds[netbuffer->numtics]); }
// // Checksum // unsigned NetbufferChecksum (void) { unsigned c; int i,l;
c = 0x1234567;
// FIXME -endianess? #ifdef NORMALUNIX return 0; // byte order problems #endif
l = (NetbufferSize () - (int)&(((doomdata_t *)0)->retransmitfrom))/4; for (i=0 ; i<l ; i++) c += ((unsigned *)&netbuffer->retransmitfrom)[i] * (i+1);
return c & NCMD_CHECKSUM; }
// // // int ExpandTics (int low) { int delta; delta = low - (maketic&0xff); if (delta >= -64 && delta <= 64) return (maketic&~0xff) + low; if (delta > 64) return (maketic&~0xff) - 256 + low; if (delta < -64) return (maketic&~0xff) + 256 + low; I_Error ("ExpandTics: strange value %i at maketic %i",low,maketic); return 0; }
// // HSendPacket // void HSendPacket (int node, int flags ) { netbuffer->checksum = NetbufferChecksum () | flags;
if (!node) { reboundstore = *netbuffer; reboundpacket = true; return; }
if (demoplayback) return;
if (!netgame) I_Error ("Tried to transmit to another node"); doomcom->command = CMD_SEND; doomcom->remotenode = node; doomcom->datalength = NetbufferSize (); if (debugfile) { int i; int realretrans; if (netbuffer->checksum & NCMD_RETRANSMIT) realretrans = ExpandTics (netbuffer->retransmitfrom); else realretrans = -1;
fprintf (debugfile,"send (%i + %i, R %i) [%i] ", ExpandTics(netbuffer->starttic), netbuffer->numtics, realretrans, doomcom->datalength); for (i=0 ; i<doomcom->datalength ; i++) fprintf (debugfile,"%i ",((byte *)netbuffer)[i]);
fprintf (debugfile,"\n"); }
I_NetCmd (); }
// // HGetPacket // Returns false if no packet is waiting // boolean HGetPacket (void) { if (reboundpacket) { *netbuffer = reboundstore; doomcom->remotenode = 0; reboundpacket = false; return true; }
if (!netgame) return false;
if (demoplayback) return false; doomcom->command = CMD_GET; I_NetCmd ();
if (doomcom->remotenode == -1) return false;
if (doomcom->datalength != NetbufferSize ()) { if (debugfile) fprintf (debugfile,"bad packet length %i\n",doomcom->datalength); return false; } if (NetbufferChecksum () != (netbuffer->checksum&NCMD_CHECKSUM) ) { if (debugfile) fprintf (debugfile,"bad packet checksum\n"); return false; }
if (debugfile) { int realretrans; int i; if (netbuffer->checksum & NCMD_SETUP) fprintf (debugfile,"setup packet\n"); else { if (netbuffer->checksum & NCMD_RETRANSMIT) realretrans = ExpandTics (netbuffer->retransmitfrom); else realretrans = -1; fprintf (debugfile,"get %i = (%i + %i, R %i)[%i] ", doomcom->remotenode, ExpandTics(netbuffer->starttic), netbuffer->numtics, realretrans, doomcom->datalength);
for (i=0 ; i<doomcom->datalength ; i++) fprintf (debugfile,"%i ",((byte *)netbuffer)[i]); fprintf (debugfile,"\n"); } } return true; }
// // GetPackets // char exitmsg[80];
void GetPackets (void) { int netconsole; int netnode; ticcmd_t *src, *dest; int realend; int realstart; while ( HGetPacket() ) { if (netbuffer->checksum & NCMD_SETUP) continue; // extra setup packet netconsole = netbuffer->player & ~PL_DRONE; netnode = doomcom->remotenode; // to save bytes, only the low byte of tic numbers are sent // Figure out what the rest of the bytes are realstart = ExpandTics (netbuffer->starttic); realend = (realstart+netbuffer->numtics); // check for exiting the game if (netbuffer->checksum & NCMD_EXIT) { if (!nodeingame[netnode]) continue; nodeingame[netnode] = false; playeringame[netconsole] = false; strcpy (exitmsg, "Player 1 left the game"); exitmsg[7] += netconsole; players[consoleplayer].message = exitmsg; if (demorecording) G_CheckDemoStatus (); continue; } // check for a remote game kill if (netbuffer->checksum & NCMD_KILL) I_Error ("Killed by network driver");
nodeforplayer[netconsole] = netnode; // check for retransmit request if ( resendcount[netnode] <= 0 && (netbuffer->checksum & NCMD_RETRANSMIT) ) { resendto[netnode] = ExpandTics(netbuffer->retransmitfrom); if (debugfile) fprintf (debugfile,"retransmit from %i\n", resendto[netnode]); resendcount[netnode] = RESENDCOUNT; } else resendcount[netnode]--; // check for out of order / duplicated packet if (realend == nettics[netnode]) continue; if (realend < nettics[netnode]) { if (debugfile) fprintf (debugfile, "out of order packet (%i + %i)\n" , realstart,netbuffer->numtics); continue; } // check for a missed packet if (realstart > nettics[netnode]) { // stop processing until the other system resends the missed tics if (debugfile) fprintf (debugfile, "missed tics from %i (%i - %i)\n", netnode, realstart, nettics[netnode]); remoteresend[netnode] = true; continue; }
// update command store from the packet { int start;
remoteresend[netnode] = false; start = nettics[netnode] - realstart; src = &netbuffer->cmds[start];
while (nettics[netnode] < realend) { dest = &netcmds[netconsole][nettics[netnode]%BACKUPTICS]; nettics[netnode]++; *dest = *src; src++; } } } }
// // NetUpdate // Builds ticcmds for console player, // sends out a packet // int gametime;
void NetUpdate (void) { int nowtime; int newtics; int i,j; int realstart; int gameticdiv;
// check time nowtime = I_GetTime ()/ticdup; newtics = nowtime - gametime; gametime = nowtime; if (newtics <= 0) // nothing new to update goto listen;
if (skiptics <= newtics) { newtics -= skiptics; skiptics = 0; } else { skiptics -= newtics; newtics = 0; } netbuffer->player = consoleplayer;
// build new ticcmds for console player gameticdiv = gametic/ticdup; for (i=0 ; i<newtics ; i++) { I_StartTic (); D_ProcessEvents (); if (maketic - gameticdiv >= BACKUPTICS/2-1) break; // can't hold any more //printf ("mk:%i ",maketic); G_BuildTiccmd (&localcmds[maketic%BACKUPTICS]); maketic++; }
if (singletics) return; // singletic update is syncronous
// send the packet to the other nodes for (i=0 ; i<doomcom->numnodes ; i++) if (nodeingame[i]) { netbuffer->starttic = realstart = resendto[i]; netbuffer->numtics = maketic - realstart; if (netbuffer->numtics > BACKUPTICS) I_Error ("NetUpdate: netbuffer->numtics > BACKUPTICS");
resendto[i] = maketic - doomcom->extratics;
for (j=0 ; j< netbuffer->numtics ; j++) netbuffer->cmds[j] = localcmds[(realstart+j)%BACKUPTICS]; if (remoteresend[i]) { netbuffer->retransmitfrom = nettics[i]; HSendPacket (i, NCMD_RETRANSMIT); } else { netbuffer->retransmitfrom = 0; HSendPacket (i, 0); } }
// listen for other packets listen: GetPackets (); }
// // CheckAbort // void CheckAbort (void) { event_t *ev; int stoptic; stoptic = I_GetTime () + 2; while (I_GetTime() < stoptic) I_StartTic (); I_StartTic (); for ( ; eventtail != eventhead ; eventtail = (++eventtail)&(MAXEVENTS-1) ) { ev = &events[eventtail]; if (ev->type == ev_keydown && ev->data1 == KEY_ESCAPE) I_Error ("Network game synchronization aborted."); } }
// // D_ArbitrateNetStart // void D_ArbitrateNetStart (void) { int i; boolean gotinfo[MAXNETNODES]; autostart = true; memset (gotinfo,0,sizeof(gotinfo)); if (doomcom->consoleplayer) { // listen for setup info from key player printf ("listening for network start info...\n"); while (1) { CheckAbort (); if (!HGetPacket ()) continue; if (netbuffer->checksum & NCMD_SETUP) { if (netbuffer->player != VERSION) I_Error ("Different DOOM versions cannot play a net game!"); startskill = netbuffer->retransmitfrom & 15; deathmatch = (netbuffer->retransmitfrom & 0xc0) >> 6; nomonsters = (netbuffer->retransmitfrom & 0x20) > 0; respawnparm = (netbuffer->retransmitfrom & 0x10) > 0; startmap = netbuffer->starttic & 0x3f; startepisode = netbuffer->starttic >> 6; return; } } } else { // key player, send the setup info printf ("sending network start info...\n"); do { CheckAbort (); for (i=0 ; i<doomcom->numnodes ; i++) { netbuffer->retransmitfrom = startskill; if (deathmatch) netbuffer->retransmitfrom |= (deathmatch<<6); if (nomonsters) netbuffer->retransmitfrom |= 0x20; if (respawnparm) netbuffer->retransmitfrom |= 0x10; netbuffer->starttic = startepisode * 64 + startmap; netbuffer->player = VERSION; netbuffer->numtics = 0; HSendPacket (i, NCMD_SETUP); }
#if 1 for(i = 10 ; i && HGetPacket(); --i) { if((netbuffer->player&0x7f) < MAXNETNODES) gotinfo[netbuffer->player&0x7f] = true; } #else while (HGetPacket ()) { gotinfo[netbuffer->player&0x7f] = true; } #endif
for (i=1 ; i<doomcom->numnodes ; i++) if (!gotinfo[i]) break; } while (i < doomcom->numnodes); } }
// // D_CheckNetGame // Works out player numbers among the net participants // extern int viewangleoffset;
void D_CheckNetGame (void) { int i; for (i=0 ; i<MAXNETNODES ; i++) { nodeingame[i] = false; nettics[i] = 0; remoteresend[i] = false; // set when local needs tics resendto[i] = 0; // which tic to start sending } // I_InitNetwork sets doomcom and netgame I_InitNetwork (); if (doomcom->id != DOOMCOM_ID) I_Error ("Doomcom buffer invalid!");
netbuffer = &doomcom->data; consoleplayer = displayplayer = doomcom->consoleplayer; if (netgame) D_ArbitrateNetStart ();
printf ("startskill %i deathmatch: %i startmap: %i startepisode: %i\n", startskill, deathmatch, startmap, startepisode); // read values out of doomcom ticdup = doomcom->ticdup; maxsend = BACKUPTICS/(2*ticdup)-1; if (maxsend<1) maxsend = 1; for (i=0 ; i<doomcom->numplayers ; i++) playeringame[i] = true; for (i=0 ; i<doomcom->numnodes ; i++) nodeingame[i] = true; printf ("player %i of %i (%i nodes)\n", consoleplayer+1, doomcom->numplayers, doomcom->numnodes);
}
// // D_QuitNetGame // Called before quitting to leave a net game // without hanging the other players // void D_QuitNetGame (void) { int i, j; if (debugfile) fclose (debugfile); if (!netgame || !usergame || consoleplayer == -1 || demoplayback) return; // send a bunch of packets for security netbuffer->player = consoleplayer; netbuffer->numtics = 0; for (i=0 ; i<4 ; i++) { for (j=1 ; j<doomcom->numnodes ; j++) if (nodeingame[j]) HSendPacket (j, NCMD_EXIT); I_WaitVBL (1); } }
// // TryRunTics // int frametics[4]; int frameon; int frameskip[4]; int oldnettics;
extern boolean advancedemo;
void TryRunTics (void) { int i; int lowtic; int entertic; static int oldentertics; int realtics; int availabletics; int counts; int numplaying;
// get real tics entertic = I_GetTime ()/ticdup; realtics = entertic - oldentertics; oldentertics = entertic;
// get available tics NetUpdate (); lowtic = MAXINT; numplaying = 0; for (i=0 ; i<doomcom->numnodes ; i++) { if (nodeingame[i]) { numplaying++; if (nettics[i] < lowtic) lowtic = nettics[i]; } } availabletics = lowtic - gametic/ticdup;
// decide how many tics to run if (realtics < availabletics-1) counts = realtics+1; else if (realtics < availabletics) counts = realtics; else counts = availabletics;
if (counts < 1) counts = 1; frameon++;
if (debugfile) fprintf (debugfile, "=======real: %i avail: %i game: %i\n", realtics, availabletics,counts);
if (!demoplayback) { // ideally nettics[0] should be 1 - 3 tics above lowtic // if we are consistantly slower, speed up time for (i=0 ; i<MAXPLAYERS ; i++) if (playeringame[i]) break; if (consoleplayer == i) { // the key player does not adapt } else { if (nettics[0] <= nettics[nodeforplayer[i]]) { gametime--; // printf ("-"); } frameskip[frameon&3] = (oldnettics > nettics[nodeforplayer[i]]); oldnettics = nettics[0]; if (frameskip[0] && frameskip[1] && frameskip[2] && frameskip[3]) { skiptics = 1; // printf ("+"); } } }// demoplayback // wait for new tics if needed while (lowtic < gametic/ticdup + counts) { NetUpdate (); lowtic = MAXINT; for (i=0 ; i<doomcom->numnodes ; i++) if (nodeingame[i] && nettics[i] < lowtic) lowtic = nettics[i]; if (lowtic < gametic/ticdup) I_Error ("TryRunTics: lowtic < gametic"); // don't stay in here forever -- give the menu a chance to work if (I_GetTime ()/ticdup - entertic >= 20) { M_Ticker (); return; } }
// run the count * ticdup dics while (counts--) { for (i=0 ; i<ticdup ; i++) { if (gametic/ticdup > lowtic) I_Error ("gametic>lowtic"); if (advancedemo) D_DoAdvanceDemo (); M_Ticker (); G_Ticker (); gametic++; // modify command for duplicated tics if (i != ticdup-1) { ticcmd_t *cmd; int buf; int j; buf = (gametic/ticdup)%BACKUPTICS; for (j=0 ; j<MAXPLAYERS ; j++) { cmd = &netcmds[j][buf]; cmd->chatchar = 0; if (cmd->buttons & BT_SPECIAL) cmd->buttons = 0; } } } NetUpdate (); // check for new console commands } } // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // Networking stuff. // //-----------------------------------------------------------------------------
#ifndef __D_NET__ #define __D_NET__
#include "d_player.h"
#ifdef __GNUG__ #pragma interface #endif
// // Network play related stuff. // There is a data struct that stores network // communication related stuff, and another // one that defines the actual packets to // be transmitted. //
#define DOOMCOM_ID 0x12345678l
// Max computers/players in a game. #define MAXNETNODES 8
// Networking and tick handling related. #define BACKUPTICS 12
typedef enum { CMD_SEND = 1, CMD_GET = 2
} command_t;
// // Network packet data. // typedef struct { // High bit is retransmit request. unsigned checksum; // Only valid if NCMD_RETRANSMIT. byte retransmitfrom;
byte starttic; byte player; byte numtics; ticcmd_t cmds[BACKUPTICS];
} doomdata_t;
typedef struct { // Supposed to be DOOMCOM_ID? long id;
// DOOM executes an int to execute commands. short intnum; // Communication between DOOM and the driver. // Is CMD_SEND or CMD_GET. short command; // Is dest for send, set by get (-1 = no packet). short remotenode;
// Number of bytes in doomdata to be sent short datalength;
// Info common to all nodes. // Console is allways node 0. short numnodes; // Flag: 1 = no duplication, 2-5 = dup for slow nets. short ticdup; // Flag: 1 = send a backup tic in every packet. short extratics; // Flag: 1 = deathmatch. short deathmatch; // Flag: -1 = new game, 0-5 = load savegame short savegame; short episode; // 1-3 short map; // 1-9 short skill; // 1-5
// Info specific to this node. short consoleplayer; short numplayers;
// These are related to the 3-display mode, // in which two drones looking left and right // were used to render two additional views // on two additional computers. // Probably not operational anymore. // 1 = left, 0 = center, -1 = right short angleoffset; // 1 = drone short drone;
// The packet data to be sent. doomdata_t data;
} doomcom_t;
// Create any new ticcmds and broadcast to other players. void NetUpdate (void);
// Broadcasts special packets to other players // to notify of game exit void D_QuitNetGame (void);
//? how many ticks to run? void TryRunTics (void);
#endif
//----------------------------------------------------------------------------- // // $Log:$ // //-----------------------------------------------------------------------------
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // // //-----------------------------------------------------------------------------
#ifndef __D_PLAYER__ #define __D_PLAYER__
// The player data structure depends on a number // of other structs: items (internal inventory), // animation states (closely tied to the sprites // used to represent them, unfortunately). #include "d_items.h" #include "p_pspr.h"
// In addition, the player is just a special // case of the generic moving object/actor. #include "p_mobj.h"
// Finally, for odd reasons, the player input // is buffered within the player data struct, // as commands per game tick. #include "d_ticcmd.h"
#ifdef __GNUG__ #pragma interface #endif
// // Player states. // typedef enum { // Playing or camping. PST_LIVE, // Dead on the ground, view follows killer. PST_DEAD, // Ready to restart/respawn??? PST_REBORN
} playerstate_t;
// // Player internal flags, for cheats and debug. // typedef enum { // No clipping, walk through barriers. CF_NOCLIP = 1, // No damage, no health loss. CF_GODMODE = 2, // Not really a cheat, just a debug aid. CF_NOMOMENTUM = 4
} cheat_t;
// // Extended player object info: player_t // typedef struct player_s { mobj_t* mo; playerstate_t playerstate; ticcmd_t cmd;
// Determine POV, // including viewpoint bobbing during movement. // Focal origin above r.z fixed_t viewz; // Base height above floor for viewz. fixed_t viewheight; // Bob/squat speed. fixed_t deltaviewheight; // bounded/scaled total momentum. fixed_t bob;
// This is only used between levels, // mo->health is used during levels. int health; int armorpoints; // Armor type is 0-2. int armortype;
// Power ups. invinc and invis are tic counters. int powers[NUMPOWERS]; boolean cards[NUMCARDS]; boolean backpack;
// Frags, kills of other players. int frags[MAXPLAYERS]; weapontype_t readyweapon;
// Is wp_nochange if not changing. weapontype_t pendingweapon;
boolean weaponowned[NUMWEAPONS]; int ammo[NUMAMMO]; int maxammo[NUMAMMO];
// True if button down last tic. int attackdown; int usedown;
// Bit flags, for cheats and debug. // See cheat_t, above. int cheats;
// Refired shots are less accurate. int refire;
// For intermission stats. int killcount; int itemcount; int secretcount;
// Hint messages. char* message;
// For screen flashing (red or bright). int damagecount; int bonuscount;
// Who did damage (NULL for floors/ceilings). mobj_t* attacker;
// So gun flashes light up areas. int extralight;
// Current PLAYPAL, ??? // can be set to REDCOLORMAP for pain, etc. int fixedcolormap;
// Player skin colorshift, // 0-3 for which color to draw player. int colormap;
// Overlay view sprites (gun, etc). pspdef_t psprites[NUMPSPRITES];
// True if secret level has been done. boolean didsecret;
} player_t;
// // INTERMISSION // Structure passed e.g. to WI_Start(wb) // typedef struct { boolean in; // whether the player is in game
// Player stats, kills, collected items etc. int skills; int sitems; int ssecret; int stime; int frags[4]; int score; // current score on entry, modified on return
} wbplayerstruct_t;
typedef struct { int epsd; // episode # (0-2)
// if true, splash the secret level boolean didsecret;
// previous and next levels, origin 0 int last; int next;
int maxkills; int maxitems; int maxsecret; int maxfrags;
// the par time int partime;
// index of this player in game int pnum;
wbplayerstruct_t plyr[MAXPLAYERS];
} wbstartstruct_t;
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // Typedefs related to to textures etc., // isolated here to make it easier separating modules. // //-----------------------------------------------------------------------------
#ifndef __D_TEXTUR__ #define __D_TEXTUR__
#include "doomtype.h"
// // Flats? // // a pic is an unmasked block of pixels typedef struct { byte width; byte height; byte data; } pic_t;
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // MapObj data. Map Objects or mobjs are actors, entities, // thinker, take-your-pick... anything that moves, acts, or // suffers state changes of more or less violent nature. // //-----------------------------------------------------------------------------
#ifndef __D_THINK__ #define __D_THINK__
#ifdef __GNUG__ #pragma interface #endif
// // Experimental stuff. // To compile this as "ANSI C with classes" // we will need to handle the various // action functions cleanly. // typedef void (*actionf_v)(); typedef void (*actionf_p1)( void* ); typedef void (*actionf_p2)( void*, void* );
typedef union { actionf_p1 acp1; actionf_v acv; actionf_p2 acp2;
} actionf_t;
// Historically, "think_t" is yet another // function pointer to a routine to handle // an actor. typedef actionf_t think_t;
// Doubly linked list of actors. typedef struct thinker_s { struct thinker_s* prev; struct thinker_s* next; think_t function;
} thinker_t;
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // System specific interface stuff. // //-----------------------------------------------------------------------------
#ifndef __D_TICCMD__ #define __D_TICCMD__
#include "doomtype.h"
#ifdef __GNUG__ #pragma interface #endif
// The data sampled per tick (single player) // and transmitted to other peers (multiplayer). // Mainly movements/button commands per game tick, // plus a checksum for internal state consistency. typedef struct { char forwardmove; // *2048 for move char sidemove; // *2048 for move short angleturn; // <<16 for angle delta short consistancy; // checks for net game byte chatchar; byte buttons; } ticcmd_t;
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // all external data is defined here // most of the data is loaded into different structures at run time // some internal structures shared by many modules are here // //-----------------------------------------------------------------------------
#ifndef __DOOMDATA__ #define __DOOMDATA__
// The most basic types we use, portability. #include "doomtype.h"
// Some global defines, that configure the game. #include "doomdef.h"
// // Map level types. // The following data structures define the persistent format // used in the lumps of the WAD files. //
// Lump order in a map WAD: each map needs a couple of lumps // to provide a complete scene geometry description. enum { ML_LABEL, // A separator, name, ExMx or MAPxx ML_THINGS, // Monsters, items.. ML_LINEDEFS, // LineDefs, from editing ML_SIDEDEFS, // SideDefs, from editing ML_VERTEXES, // Vertices, edited and BSP splits generated ML_SEGS, // LineSegs, from LineDefs split by BSP ML_SSECTORS, // SubSectors, list of LineSegs ML_NODES, // BSP nodes ML_SECTORS, // Sectors, from editing ML_REJECT, // LUT, sector-sector visibility ML_BLOCKMAP // LUT, motion clipping, walls/grid element };
// A single Vertex. typedef struct { short x; short y; } mapvertex_t;
// A SideDef, defining the visual appearance of a wall, // by setting textures and offsets. typedef struct { short textureoffset; short rowoffset; char toptexture[8]; char bottomtexture[8]; char midtexture[8]; // Front sector, towards viewer. short sector; } mapsidedef_t;
// A LineDef, as used for editing, and as input // to the BSP builder. typedef struct { short v1; short v2; short flags; short special; short tag; // sidenum[1] will be -1 if one sided short sidenum[2]; } maplinedef_t;
// // LineDef attributes. //
// Solid, is an obstacle. #define ML_BLOCKING 1
// Blocks monsters only. #define ML_BLOCKMONSTERS 2
// Backside will not be present at all // if not two sided. #define ML_TWOSIDED 4
// If a texture is pegged, the texture will have // the end exposed to air held constant at the // top or bottom of the texture (stairs or pulled // down things) and will move with a height change // of one of the neighbor sectors. // Unpegged textures allways have the first row of // the texture at the top pixel of the line for both // top and bottom textures (use next to windows).
// upper texture unpegged #define ML_DONTPEGTOP 8
// lower texture unpegged #define ML_DONTPEGBOTTOM 16
// In AutoMap: don't map as two sided: IT'S A SECRET! #define ML_SECRET 32
// Sound rendering: don't let sound cross two of these. #define ML_SOUNDBLOCK 64
// Don't draw on the automap at all. #define ML_DONTDRAW 128
// Set if already seen, thus drawn in automap. #define ML_MAPPED 256
// Sector definition, from editing. typedef struct { short floorheight; short ceilingheight; char floorpic[8]; char ceilingpic[8]; short lightlevel; short special; short tag; } mapsector_t;
// SubSector, as generated by BSP. typedef struct { short numsegs; // Index of first one, segs are stored sequentially. short firstseg; } mapsubsector_t;
// LineSeg, generated by splitting LineDefs // using partition lines selected by BSP builder. typedef struct { short v1; short v2; short angle; short linedef; short side; short offset; } mapseg_t;
// BSP node structure.
// Indicate a leaf. #define NF_SUBSECTOR 0x8000
typedef struct { // Partition line from (x,y) to x+dx,y+dy) short x; short y; short dx; short dy;
// Bounding box for each child, // clip against view frustum. short bbox[2][4];
// If NF_SUBSECTOR its a subsector, // else it's a node of another subtree. unsigned short children[2];
} mapnode_t;
// Thing definition, position, orientation and type, // plus skill/visibility flags and attributes. typedef struct { short x; short y; short angle; short type; short options; } mapthing_t;
#endif // __DOOMDATA__ //----------------------------------------------------------------------------- // // $Log:$ // //-----------------------------------------------------------------------------
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // DoomDef - basic defines for DOOM, e.g. Version, game mode // and skill level, and display parameters. // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: m_bbox.c,v 1.1 1997/02/03 22:45:10 b1 Exp $";
#ifdef __GNUG__ #pragma implementation "doomdef.h" #endif #include "doomdef.h"
// Location for any defines turned variables.
// None.
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // Internally used data structures for virtually everything, // key definitions, lots of other stuff. // //-----------------------------------------------------------------------------
#ifndef __DOOMDEF__ #define __DOOMDEF__
#include <stdio.h> #include <string.h>
// // Global parameters/defines. // // DOOM version enum { VERSION = 110 };
// Game mode handling - identify IWAD version // to handle IWAD dependend animations etc. typedef enum { shareware, // DOOM 1 shareware, E1, M9 registered, // DOOM 1 registered, E3, M27 commercial, // DOOM 2 retail, E1 M34 // DOOM 2 german edition not handled retail, // DOOM 1 retail, E4, M36 indetermined // Well, no IWAD found.
} GameMode_t;
// Mission packs - might be useful for TC stuff? typedef enum { doom, // DOOM 1 doom2, // DOOM 2 pack_tnt, // TNT mission pack pack_plut, // Plutonia pack none
} GameMission_t;
// Identify language to use, software localization. typedef enum { english, french, german, unknown
} Language_t;
// If rangecheck is undefined, // most parameter validation debugging code will not be compiled #define RANGECHECK
// Do or do not use external soundserver. // The sndserver binary to be run separately // has been introduced by Dave Taylor. // The integrated sound support is experimental, // and unfinished. Default is synchronous. // Experimental asynchronous timer based is // handled by SNDINTR. #define SNDSERV 1 //#define SNDINTR 1
// This one switches between MIT SHM (no proper mouse) // and XFree86 DGA (mickey sampling). The original // linuxdoom used SHM, which is default. //#define X11_DGA 1
// // For resize of screen, at start of game. // It will not work dynamically, see visplanes. // #define BASE_WIDTH 320
// It is educational but futile to change this // scaling e.g. to 2. Drawing of status bar, // menues etc. is tied to the scale implied // by the graphics. #define SCREEN_MUL 1 #define INV_ASPECT_RATIO 0.625 // 0.75, ideally
// Defines suck. C sucks. // C++ might sucks for OOP, but it sure is a better C. // So there. #define SCREENWIDTH 320 //SCREEN_MUL*BASE_WIDTH //320 #define SCREENHEIGHT 200 //(int)(SCREEN_MUL*BASE_WIDTH*INV_ASPECT_RATIO) //200
// The maximum number of players, multiplayer/networking. #define MAXPLAYERS 4
// State updates, number of tics / second. #define TICRATE 35
// The current state of the game: whether we are // playing, gazing at the intermission screen, // the game final animation, or a demo. typedef enum { GS_LEVEL, GS_INTERMISSION, GS_FINALE, GS_DEMOSCREEN } gamestate_t;
// // Difficulty/skill settings/filters. //
// Skill flags. #define MTF_EASY 1 #define MTF_NORMAL 2 #define MTF_HARD 4
// Deaf monsters/do not react to sound. #define MTF_AMBUSH 8
typedef enum { sk_baby, sk_easy, sk_medium, sk_hard, sk_nightmare } skill_t;
// // Key cards. // typedef enum { it_bluecard, it_yellowcard, it_redcard, it_blueskull, it_yellowskull, it_redskull,
NUMCARDS
} card_t;
// The defined weapons, // including a marker indicating // user has not changed weapon. typedef enum { wp_fist, wp_pistol, wp_shotgun, wp_chaingun, wp_missile, wp_plasma, wp_bfg, wp_chainsaw, wp_supershotgun,
NUMWEAPONS,
// No pending weapon change. wp_nochange
} weapontype_t;
// Ammunition types defined. typedef enum { am_clip, // Pistol / chaingun ammo. am_shell, // Shotgun / double barreled shotgun. am_cell, // Plasma rifle, BFG. am_misl, // Missile launcher. NUMAMMO, am_noammo // Unlimited for chainsaw / fist.
} ammotype_t;
// Power up artifacts. typedef enum { pw_invulnerability, pw_strength, pw_invisibility, pw_ironfeet, pw_allmap, pw_infrared, NUMPOWERS
} powertype_t;
// // Power up durations, // how many seconds till expiration, // assuming TICRATE is 35 ticks/second. // typedef enum { INVULNTICS = (30*TICRATE), INVISTICS = (60*TICRATE), INFRATICS = (120*TICRATE), IRONTICS = (60*TICRATE)
} powerduration_t;
// // DOOM keyboard definition. // This is the stuff configured by Setup.Exe. // Most key data are simple ascii (uppercased). // #define KEY_RIGHTARROW 0xae #define KEY_LEFTARROW 0xac #define KEY_UPARROW 0xad #define KEY_DOWNARROW 0xaf #define KEY_ESCAPE 27 #define KEY_ENTER 13 #define KEY_TAB 9 #define KEY_F1 (0x80+0x3b) #define KEY_F2 (0x80+0x3c) #define KEY_F3 (0x80+0x3d) #define KEY_F4 (0x80+0x3e) #define KEY_F5 (0x80+0x3f) #define KEY_F6 (0x80+0x40) #define KEY_F7 (0x80+0x41) #define KEY_F8 (0x80+0x42) #define KEY_F9 (0x80+0x43) #define KEY_F10 (0x80+0x44) #define KEY_F11 (0x80+0x57) #define KEY_F12 (0x80+0x58)
#define KEY_BACKSPACE 127 #define KEY_PAUSE 0xff
#define KEY_EQUALS 0x3d #define KEY_MINUS 0x2d
#define KEY_RSHIFT (0x80+0x36) #define KEY_RCTRL (0x80+0x1d) #define KEY_RALT (0x80+0x38)
#define KEY_LALT KEY_RALT
// DOOM basic types (boolean), // and max/min values. //#include "doomtype.h"
// Fixed point. //#include "m_fixed.h"
// Endianess handling. //#include "m_swap.h"
// Binary Angles, sine/cosine/atan lookups. //#include "tables.h"
// Event type. //#include "d_event.h"
// Game function, skills. //#include "g_game.h"
// All external data is defined here. //#include "doomdata.h"
// All important printed strings. // Language selection (message strings). //#include "dstrings.h"
// Player is a special actor. //struct player_s;
//#include "d_items.h" //#include "d_player.h" //#include "p_mobj.h" //#include "d_net.h"
// PLAY //#include "p_tick.h"
// Header, generated by sound utility. // The utility was written by Dave Taylor. //#include "sounds.h"
#endif // __DOOMDEF__ //----------------------------------------------------------------------------- // // $Log:$ // //-----------------------------------------------------------------------------
LIMITED USE SOFTWARE LICENSE AGREEMENT
This Limited Use Software License Agreement (the "Agreement") is a legal agreement between you, the end-user, and Id Software, Inc. ("ID"). By downloading or purchasing the software material, which includes source code (the "Source Code"), artwork data, music and software tools (collectively, the "Software"), you are agreeing to be bound by the terms of this Agreement. If you do not agree to the terms of this Agreement, promptly destroy the Software you may have downloaded or copied.
ID SOFTWARE LICENSE
1. Grant of License. ID grants to you the right to use the Software. You have no ownership or proprietary rights in or to the Software, or the Trademark. For purposes of this section, "use" means loading the Software into RAM, as well as installation on a hard disk or other storage device. The Software, together with any archive copy thereof, shall be destroyed when no longer used in accordance with this Agreement, or when the right to use the Software is terminated. You agree that the Software will not be shipped, transferred or exported into any country in violation of the U.S. Export Administration Act (or any other law governing such matters) and that you will not utilize, in any other manner, the Software in violation of any applicable law.
2. Permitted Uses. For educational purposes only, you, the end-user, may use portions of the Source Code, such as particular routines, to develop your own software, but may not duplicate the Source Code, except as noted in paragraph 4. The limited right referenced in the preceding sentence is hereinafter referred to as "Educational Use." By so exercising the Educational Use right you shall not obtain any ownership, copyright, proprietary or other interest in or to the Source Code, or any portion of the Source Code. You may dispose of your own software in your sole discretion. With the exception of the Educational Use right, you may not otherwise use the Software, or an portion of the Software, which includes the Source Code, for commercial gain.
3. Prohibited Uses: Under no circumstances shall you, the end-user, be permitted, allowed or authorized to commercially exploit the Software. Neither you nor anyone at your direction shall do any of the following acts with regard to the Software, or any portion thereof:
Rent;
Sell;
Lease;
Offer on a pay-per-play basis;
Distribute for money or any other consideration; or
In any other manner and through any medium whatsoever commercially exploit or use for any commercial purpose.
Notwithstanding the foregoing prohibitions, you may commercially exploit the software you develop by exercising the Educational Use right, referenced in paragraph 2. hereinabove.
4. Copyright. The Software and all copyrights related thereto (including all characters and other images generated by the Software or depicted in the Software) are owned by ID and is protected by United States copyright laws and international treaty provisions. Id shall retain exclusive ownership and copyright in and to the Software and all portions of the Software and you shall have no ownership or other proprietary interest in such materials. You must treat the Software like any other copyrighted material. You may not otherwise reproduce, copy or disclose to others, in whole or in any part, the Software. You may not copy the written materials accompanying the Software. You agree to use your best efforts to see that any user of the Software licensed hereunder complies with this Agreement.
5. NO WARRANTIES. ID DISCLAIMS ALL WARRANTIES, BOTH EXPRESS IMPLIED, INCLUDING BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE WITH RESPECT TO THE SOFTWARE. THIS LIMITED WARRANTY GIVES YOU SPECIFIC LEGAL RIGHTS. YOU MAY HAVE OTHER RIGHTS WHICH VARY FROM JURISDICTION TO JURISDICTION. ID DOES NOT WARRANT THAT THE OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED, ERROR FREE OR MEET YOUR SPECIFIC REQUIREMENTS. THE WARRANTY SET FORTH ABOVE IS IN LIEU OF ALL OTHER EXPRESS WARRANTIES WHETHER ORAL OR WRITTEN. THE AGENTS, EMPLOYEES, DISTRIBUTORS, AND DEALERS OF ID ARE NOT AUTHORIZED TO MAKE MODIFICATIONS TO THIS WARRANTY, OR ADDITIONAL WARRANTIES ON BEHALF OF ID.
Exclusive Remedies. The Software is being offered to you free of any charge. You agree that you have no remedy against ID, its affiliates, contractors, suppliers, and agents for loss or damage caused by any defect or failure in the Software regardless of the form of action, whether in contract, tort, includinegligence, strict liability or otherwise, with regard to the Software. This Agreement shall be construed in accordance with and governed by the laws of the State of Texas. Copyright and other proprietary matters will be governed by United States laws and international treaties. IN ANY CASE, ID SHALL NOT BE LIABLE FOR LOSS OF DATA, LOSS OF PROFITS, LOST SAVINGS, SPECIAL, INCIDENTAL, CONSEQUENTIAL, INDIRECT OR OTHER SIMILAR DAMAGES ARISING FROM BREACH OF WARRANTY, BREACH OF CONTRACT, NEGLIGENCE, OR OTHER LEGAL THEORY EVEN IF ID OR ITS AGENT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so the above limitation or exclusion may not apply to you.
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // Put all global tate variables here. // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: m_bbox.c,v 1.1 1997/02/03 22:45:10 b1 Exp $";
#ifdef __GNUG__ #pragma implementation "doomstat.h" #endif #include "doomstat.h"
// Game Mode - identify IWAD as shareware, retail etc. GameMode_t gamemode = indetermined; GameMission_t gamemission = doom;
// Language. Language_t language = english;
// Set if homebrew PWAD stuff has been added. boolean modifiedgame;
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // All the global variables that store the internal state. // Theoretically speaking, the internal state of the engine // should be found by looking at the variables collected // here, and every relevant module will have to include // this header file. // In practice, things are a bit messy. // //-----------------------------------------------------------------------------
#ifndef __D_STATE__ #define __D_STATE__
// We need globally shared data structures, // for defining the global state variables. #include "doomdata.h" #include "d_net.h"
// We need the playr data structure as well. #include "d_player.h"
#ifdef __GNUG__ #pragma interface #endif
// ------------------------ // Command line parameters. // extern boolean nomonsters; // checkparm of -nomonsters extern boolean respawnparm; // checkparm of -respawn extern boolean fastparm; // checkparm of -fast
extern boolean devparm; // DEBUG: launched with -devparm
// ----------------------------------------------------- // Game Mode - identify IWAD as shareware, retail etc. // extern GameMode_t gamemode; extern GameMission_t gamemission;
// Set if homebrew PWAD stuff has been added. extern boolean modifiedgame;
// ------------------------------------------- // Language. extern Language_t language;
// ------------------------------------------- // Selected skill type, map etc. //
// Defaults for menu, methinks. extern skill_t startskill; extern int startepisode; extern int startmap;
extern boolean autostart;
// Selected by user. extern skill_t gameskill; extern int gameepisode; extern int gamemap;
// Nightmare mode flag, single player. extern boolean respawnmonsters;
// Netgame? Only true if >1 player. extern boolean netgame;
// Flag: true only if started as net deathmatch. // An enum might handle altdeath/cooperative better. extern boolean deathmatch; // ------------------------- // Internal parameters for sound rendering. // These have been taken from the DOS version, // but are not (yet) supported with Linux // (e.g. no sound volume adjustment with menu.
// These are not used, but should be (menu). // From m_menu.c: // Sound FX volume has default, 0 - 15 // Music volume has default, 0 - 15 // These are multiplied by 8. extern int snd_SfxVolume; // maximum volume for sound extern int snd_MusicVolume; // maximum volume for music
// Current music/sfx card - index useless // w/o a reference LUT in a sound module. // Ideally, this would use indices found // in: /usr/include/linux/soundcard.h extern int snd_MusicDevice; extern int snd_SfxDevice; // Config file? Same disclaimer as above. extern int snd_DesiredMusicDevice; extern int snd_DesiredSfxDevice;
// ------------------------- // Status flags for refresh. //
// Depending on view size - no status bar? // Note that there is no way to disable the // status bar explicitely. extern boolean statusbaractive;
extern boolean automapactive; // In AutoMap mode? extern boolean menuactive; // Menu overlayed? extern boolean paused; // Game Pause?
extern boolean viewactive;
extern boolean nodrawers; extern boolean noblit;
extern int viewwindowx; extern int viewwindowy; extern int viewheight; extern int viewwidth; extern int scaledviewwidth;
// This one is related to the 3-screen display mode. // ANG90 = left side, ANG270 = right extern int viewangleoffset;
// Player taking events, and displaying. extern int consoleplayer; extern int displayplayer;
// ------------------------------------- // Scores, rating. // Statistics on a given map, for intermission. // extern int totalkills; extern int totalitems; extern int totalsecret;
// Timer, for scores. extern int levelstarttic; // gametic at level start extern int leveltime; // tics in game play for par
// -------------------------------------- // DEMO playback/recording related stuff. // No demo, there is a human player in charge? // Disable save/end game? extern boolean usergame;
//? extern boolean demoplayback; extern boolean demorecording;
// Quit after playing a demo from cmdline. extern boolean singledemo;
//? extern gamestate_t gamestate;
//----------------------------- // Internal parameters, fixed. // These are set by the engine, and not changed // according to user inputs. Partly load from // WAD, partly set at startup time.
extern int gametic;
// Bookkeeping on players - state. extern player_t players[MAXPLAYERS];
// Alive? Disconnected? extern boolean playeringame[MAXPLAYERS];
// Player spawn spots for deathmatch. #define MAX_DM_STARTS 10 extern mapthing_t deathmatchstarts[MAX_DM_STARTS]; extern mapthing_t* deathmatch_p;
// Player spawn spots. extern mapthing_t playerstarts[MAXPLAYERS];
// Intermission stats. // Parameters for world map / intermission. extern wbstartstruct_t wminfo;
// LUT of ammunition limits for each kind. // This doubles with BackPack powerup item. extern int maxammo[NUMAMMO];
//----------------------------------------- // Internal parameters, used for engine. //
// File handling stuff. extern char basedefault[1024]; extern FILE* debugfile;
// if true, load all graphics at level load extern boolean precache;
// wipegamestate can be set to -1 // to force a wipe on the next draw extern gamestate_t wipegamestate;
extern int mouseSensitivity; //? // debug flag to cancel adaptiveness extern boolean singletics;
extern int bodyqueslot;
// Needed to store the number of the dummy sky flat. // Used for rendering, // as well as tracking projectiles etc. extern int skyflatnum;
// Netgame stuff (buffers and pointers, i.e. indices).
// This is ??? extern doomcom_t* doomcom;
// This points inside doomcom. extern doomdata_t* netbuffer;
extern ticcmd_t localcmds[BACKUPTICS]; extern int rndindex;
extern int maketic; extern int nettics[MAXNETNODES];
extern ticcmd_t netcmds[MAXPLAYERS][BACKUPTICS]; extern int ticdup;
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // Simple basic typedefs, isolated here to make it easier // separating modules. // //-----------------------------------------------------------------------------
#ifndef __DOOMTYPE__ #define __DOOMTYPE__
#ifndef __BYTEBOOL__ #define __BYTEBOOL__ // Fixed to use builtin bool type with C++. #ifdef __cplusplus typedef bool boolean; #else typedef enum {false, true} boolean; #endif typedef unsigned char byte; #endif
// Predefined with some OS. #ifdef LINUX #include <values.h> #else #define MAXCHAR ((char)0x7f) #define MAXSHORT ((short)0x7fff)
// Max pos 32-bit int. #define MAXINT ((int)0x7fffffff) #define MAXLONG ((long)0x7fffffff) #define MINCHAR ((char)0x80) #define MINSHORT ((short)0x8000)
// Max negative 32-bit integer. #define MININT ((int)0x80000000) #define MINLONG ((long)0x80000000) #endif
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // Globally defined strings. // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: m_bbox.c,v 1.1 1997/02/03 22:45:10 b1 Exp $";
#ifdef __GNUG__ #pragma implementation "dstrings.h" #endif #include "dstrings.h"
char* endmsg[NUM_QUITMESSAGES+1]= { // DOOM1 QUITMSG, "please don't leave, there's more\ndemons to toast!", "let's beat it -- this is turning\ninto a bloodbath!", "i wouldn't leave if i were you.\ndos is much worse.", "you're trying to say you like dos\nbetter than me, right?", "don't leave yet -- there's a\ndemon around that corner!", "ya know, next time you come in here\ni'm gonna toast ya.", "go ahead and leave. see if i care."
// QuitDOOM II messages "you want to quit?\nthen, thou hast lost an eighth!", "don't go now, there's a \ndimensional shambler waiting\nat the dos prompt!", "get outta here and go back\nto your boring programs.", "if i were your boss, i'd \n deathmatch ya in a minute!", "look, bud. you leave now\nand you forfeit your body count!", "just leave. when you come\nback, i'll be waiting with a bat.", "you're lucky i don't smack\nyou for thinking about leaving."
// FinalDOOM? "fuck you, pussy!\nget the fuck out!", "you quit and i'll jizz\nin your cystholes!", "if you leave, i'll make\nthe lord drink my jizz.", "hey, ron! can we say\n'fuck' in the game?", "i'd leave: this is just\nmore monsters and levels.\nwhat a load.", "suck it down, asshole!\nyou're a fucking wimp!", "don't quit now! we're \nstill spending your money!",
// Internal debug. Different style, too. "THIS IS NO MESSAGE!\nPage intentionally left blank." };
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // // $Log:$ // // DESCRIPTION: // DOOM strings, by language. // //-----------------------------------------------------------------------------
#ifndef __DSTRINGS__ #define __DSTRINGS__
// All important printed strings. // Language selection (message strings). // Use -DFRENCH etc.
#ifdef FRENCH #include "d_french.h" #else #include "d_englsh.h" #endif
// Misc. other strings. #define SAVEGAMENAME "doomsav"
// // File locations, // relative to current position. // Path names are OS-sensitive. // #define DEVMAPS "devmaps" #define DEVDATA "devdata"
// Not done in french?
// QuitDOOM messages #define NUM_QUITMESSAGES 22
extern char* endmsg[];
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // Game completion, final screen animation. // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: f_finale.c,v 1.5 1997/02/03 21:26:34 b1 Exp $";
#include <ctype.h>
// Functions. #include "i_system.h" #include "m_swap.h" #include "z_zone.h" #include "v_video.h" #include "w_wad.h" #include "s_sound.h"
// Data. #include "dstrings.h" #include "sounds.h"
#include "doomstat.h" #include "r_state.h"
// ? //#include "doomstat.h" //#include "r_local.h" //#include "f_finale.h"
// Stage of animation: // 0 = text, 1 = art screen, 2 = character cast int finalestage;
int finalecount;
#define TEXTSPEED 3 #define TEXTWAIT 250
char* e1text = E1TEXT; char* e2text = E2TEXT; char* e3text = E3TEXT; char* e4text = E4TEXT;
char* c1text = C1TEXT; char* c2text = C2TEXT; char* c3text = C3TEXT; char* c4text = C4TEXT; char* c5text = C5TEXT; char* c6text = C6TEXT;
char* p1text = P1TEXT; char* p2text = P2TEXT; char* p3text = P3TEXT; char* p4text = P4TEXT; char* p5text = P5TEXT; char* p6text = P6TEXT;
char* t1text = T1TEXT; char* t2text = T2TEXT; char* t3text = T3TEXT; char* t4text = T4TEXT; char* t5text = T5TEXT; char* t6text = T6TEXT;
char* finaletext; char* finaleflat;
void F_StartCast (void); void F_CastTicker (void); boolean F_CastResponder (event_t *ev); void F_CastDrawer (void);
// // F_StartFinale // void F_StartFinale (void) { gameaction = ga_nothing; gamestate = GS_FINALE; viewactive = false; automapactive = false;
// Okay - IWAD dependend stuff. // This has been changed severly, and // some stuff might have changed in the process. switch ( gamemode ) {
// DOOM 1 - E1, E3 or E4, but each nine missions case shareware: case registered: case retail: { S_ChangeMusic(mus_victor, true); switch (gameepisode) { case 1: finaleflat = "FLOOR4_8"; finaletext = e1text; break; case 2: finaleflat = "SFLR6_1"; finaletext = e2text; break; case 3: finaleflat = "MFLR8_4"; finaletext = e3text; break; case 4: finaleflat = "MFLR8_3"; finaletext = e4text; break; default: // Ouch. break; } break; }
// DOOM II and missions packs with E1, M34 case commercial: { S_ChangeMusic(mus_read_m, true);
switch (gamemap) { case 6: finaleflat = "SLIME16"; finaletext = c1text; break; case 11: finaleflat = "RROCK14"; finaletext = c2text; break; case 20: finaleflat = "RROCK07"; finaletext = c3text; break; case 30: finaleflat = "RROCK17"; finaletext = c4text; break; case 15: finaleflat = "RROCK13"; finaletext = c5text; break; case 31: finaleflat = "RROCK19"; finaletext = c6text; break; default: // Ouch. break; } break; }
// Indeterminate. default: S_ChangeMusic(mus_read_m, true); finaleflat = "F_SKY1"; // Not used anywhere else. finaletext = c1text; // FIXME - other text, music? break; }
finalestage = 0; finalecount = 0; }
boolean F_Responder (event_t *event) { if (finalestage == 2) return F_CastResponder (event); return false; }
// // F_Ticker // void F_Ticker (void) { int i;
// check for skipping if ( (gamemode == commercial) && ( finalecount > 50) ) { // go on to the next level for (i=0 ; i<MAXPLAYERS ; i++) if (players[i].cmd.buttons) break; if (i < MAXPLAYERS) { if (gamemap == 30) F_StartCast (); else gameaction = ga_worlddone; } }
// advance animation finalecount++; if (finalestage == 2) { F_CastTicker (); return; } if ( gamemode == commercial) return; if (!finalestage && finalecount>strlen (finaletext)*TEXTSPEED + TEXTWAIT) { finalecount = 0; finalestage = 1; wipegamestate = -1; // force a wipe if (gameepisode == 3) S_StartMusic (mus_bunny); } }
// // F_TextWrite //
#include "hu_stuff.h" extern patch_t *hu_font[HU_FONTSIZE];
void F_TextWrite (void) { byte* src; byte* dest;
int x,y,w; int count; char* ch; int c; int cx; int cy;
// erase the entire screen to a tiled background src = W_CacheLumpName ( finaleflat , PU_CACHE); dest = screens[0]; for (y=0 ; y<SCREENHEIGHT ; y++) { for (x=0 ; x<SCREENWIDTH/64 ; x++) { memcpy (dest, src+((y&63)<<6), 64); dest += 64; } if (SCREENWIDTH&63) { memcpy (dest, src+((y&63)<<6), SCREENWIDTH&63); dest += (SCREENWIDTH&63); } }
V_MarkRect (0, 0, SCREENWIDTH, SCREENHEIGHT);
// draw some of the text onto the screen cx = 10; cy = 10; ch = finaletext; count = (finalecount - 10)/TEXTSPEED; if (count < 0) count = 0; for ( ; count ; count-- ) { c = *ch++; if (!c) break; if (c == '\n') { cx = 10; cy += 11; continue; } c = toupper(c) - HU_FONTSTART; if (c < 0 || c> HU_FONTSIZE) { cx += 4; continue; } w = SHORT (hu_font[c]->width); if (cx+w > SCREENWIDTH) break; V_DrawPatch(cx, cy, 0, hu_font[c]); cx+=w; } }
// // Final DOOM 2 animation // Casting by id Software. // in order of appearance // typedef struct { char *name; mobjtype_t type; } castinfo_t;
castinfo_t castorder[] = { {CC_ZOMBIE, MT_POSSESSED}, {CC_SHOTGUN, MT_SHOTGUY}, {CC_HEAVY, MT_CHAINGUY}, {CC_IMP, MT_TROOP}, {CC_DEMON, MT_SERGEANT}, {CC_LOST, MT_SKULL}, {CC_CACO, MT_HEAD}, {CC_HELL, MT_KNIGHT}, {CC_BARON, MT_BRUISER}, {CC_ARACH, MT_BABY}, {CC_PAIN, MT_PAIN}, {CC_REVEN, MT_UNDEAD}, {CC_MANCU, MT_FATSO}, {CC_ARCH, MT_VILE}, {CC_SPIDER, MT_SPIDER}, {CC_CYBER, MT_CYBORG}, {CC_HERO, MT_PLAYER},
{NULL,0} };
int castnum; int casttics; state_t* caststate; boolean castdeath; int castframes; int castonmelee; boolean castattacking;
// // F_StartCast // extern gamestate_t wipegamestate;
void F_StartCast (void) { wipegamestate = -1; // force a screen wipe castnum = 0; caststate = &states[mobjinfo[castorder[castnum].type].seestate]; casttics = caststate->tics; castdeath = false; finalestage = 2; castframes = 0; castonmelee = 0; castattacking = false; S_ChangeMusic(mus_evil, true); }
// // F_CastTicker // void F_CastTicker (void) { int st; int sfx; if (--casttics > 0) return; // not time to change state yet if (caststate->tics == -1 || caststate->nextstate == S_NULL) { // switch from deathstate to next monster castnum++; castdeath = false; if (castorder[castnum].name == NULL) castnum = 0; if (mobjinfo[castorder[castnum].type].seesound) S_StartSound (NULL, mobjinfo[castorder[castnum].type].seesound); caststate = &states[mobjinfo[castorder[castnum].type].seestate]; castframes = 0; } else { // just advance to next state in animation if (caststate == &states[S_PLAY_ATK1]) goto stopattack; // Oh, gross hack! st = caststate->nextstate; caststate = &states[st]; castframes++; // sound hacks.... switch (st) { case S_PLAY_ATK1: sfx = sfx_dshtgn; break; case S_POSS_ATK2: sfx = sfx_pistol; break; case S_SPOS_ATK2: sfx = sfx_shotgn; break; case S_VILE_ATK2: sfx = sfx_vilatk; break; case S_SKEL_FIST2: sfx = sfx_skeswg; break; case S_SKEL_FIST4: sfx = sfx_skepch; break; case S_SKEL_MISS2: sfx = sfx_skeatk; break; case S_FATT_ATK8: case S_FATT_ATK5: case S_FATT_ATK2: sfx = sfx_firsht; break; case S_CPOS_ATK2: case S_CPOS_ATK3: case S_CPOS_ATK4: sfx = sfx_shotgn; break; case S_TROO_ATK3: sfx = sfx_claw; break; case S_SARG_ATK2: sfx = sfx_sgtatk; break; case S_BOSS_ATK2: case S_BOS2_ATK2: case S_HEAD_ATK2: sfx = sfx_firsht; break; case S_SKULL_ATK2: sfx = sfx_sklatk; break; case S_SPID_ATK2: case S_SPID_ATK3: sfx = sfx_shotgn; break; case S_BSPI_ATK2: sfx = sfx_plasma; break; case S_CYBER_ATK2: case S_CYBER_ATK4: case S_CYBER_ATK6: sfx = sfx_rlaunc; break; case S_PAIN_ATK3: sfx = sfx_sklatk; break; default: sfx = 0; break; } if (sfx) S_StartSound (NULL, sfx); } if (castframes == 12) { // go into attack frame castattacking = true; if (castonmelee) caststate=&states[mobjinfo[castorder[castnum].type].meleestate]; else caststate=&states[mobjinfo[castorder[castnum].type].missilestate]; castonmelee ^= 1; if (caststate == &states[S_NULL]) { if (castonmelee) caststate= &states[mobjinfo[castorder[castnum].type].meleestate]; else caststate= &states[mobjinfo[castorder[castnum].type].missilestate]; } } if (castattacking) { if (castframes == 24 || caststate == &states[mobjinfo[castorder[castnum].type].seestate] ) { stopattack: castattacking = false; castframes = 0; caststate = &states[mobjinfo[castorder[castnum].type].seestate]; } } casttics = caststate->tics; if (casttics == -1) casttics = 15; }
// // F_CastResponder //
boolean F_CastResponder (event_t* ev) { if (ev->type != ev_keydown) return false; if (castdeath) return true; // already in dying frames // go into death frame castdeath = true; caststate = &states[mobjinfo[castorder[castnum].type].deathstate]; casttics = caststate->tics; castframes = 0; castattacking = false; if (mobjinfo[castorder[castnum].type].deathsound) S_StartSound (NULL, mobjinfo[castorder[castnum].type].deathsound); return true; }
void F_CastPrint (char* text) { char* ch; int c; int cx; int w; int width;
// find width ch = text; width = 0; while (ch) { c = *ch++; if (!c) break; c = toupper(c) - HU_FONTSTART; if (c < 0 || c> HU_FONTSIZE) { width += 4; continue; } w = SHORT (hu_font[c]->width); width += w; }
// draw it cx = 160-width/2; ch = text; while (ch) { c = *ch++; if (!c) break; c = toupper(c) - HU_FONTSTART; if (c < 0 || c> HU_FONTSIZE) { cx += 4; continue; } w = SHORT (hu_font[c]->width); V_DrawPatch(cx, 180, 0, hu_font[c]); cx+=w; } }
// // F_CastDrawer // void V_DrawPatchFlipped (int x, int y, int scrn, patch_t *patch);
void F_CastDrawer (void) { spritedef_t* sprdef; spriteframe_t* sprframe; int lump; boolean flip; patch_t* patch;
// erase the entire screen to a background V_DrawPatch (0,0,0, W_CacheLumpName ("BOSSBACK", PU_CACHE));
F_CastPrint (castorder[castnum].name);
// draw the current frame in the middle of the screen sprdef = &sprites[caststate->sprite]; sprframe = &sprdef->spriteframes[ caststate->frame & FF_FRAMEMASK]; lump = sprframe->lump[0]; flip = (boolean)sprframe->flip[0]; patch = W_CacheLumpNum (lump+firstspritelump, PU_CACHE); if (flip) V_DrawPatchFlipped (160,170,0,patch); else V_DrawPatch (160,170,0,patch); }
// // F_DrawPatchCol // void F_DrawPatchCol ( int x, patch_t* patch, int col ) { column_t* column; byte* source; byte* dest; byte* desttop; int count; column = (column_t *)((byte *)patch + LONG(patch->columnofs[col])); desttop = screens[0]+x;
// step through the posts in a column while (column->topdelta != 0xff ) { source = (byte *)column + 3; dest = desttop + column->topdelta*SCREENWIDTH; count = column->length; while (count--) { *dest = *source++; dest += SCREENWIDTH; } column = (column_t *)( (byte *)column + column->length + 4 ); } }
// // F_BunnyScroll // void F_BunnyScroll (void) { int scrolled; int x; patch_t* p1; patch_t* p2; char name[10]; int stage; static int laststage; p1 = W_CacheLumpName ("PFUB2", PU_LEVEL); p2 = W_CacheLumpName ("PFUB1", PU_LEVEL);
V_MarkRect (0, 0, SCREENWIDTH, SCREENHEIGHT); scrolled = 320 - (finalecount-230)/2; if (scrolled > 320) scrolled = 320; if (scrolled < 0) scrolled = 0; for ( x=0 ; x<SCREENWIDTH ; x++) { if (x+scrolled < 320) F_DrawPatchCol (x, p1, x+scrolled); else F_DrawPatchCol (x, p2, x+scrolled - 320); } if (finalecount < 1130) return; if (finalecount < 1180) { V_DrawPatch ((SCREENWIDTH-13*8)/2, (SCREENHEIGHT-8*8)/2,0, W_CacheLumpName ("END0",PU_CACHE)); laststage = 0; return; } stage = (finalecount-1180) / 5; if (stage > 6) stage = 6; if (stage > laststage) { S_StartSound (NULL, sfx_pistol); laststage = stage; } sprintf (name,"END%i",stage); V_DrawPatch ((SCREENWIDTH-13*8)/2, (SCREENHEIGHT-8*8)/2,0, W_CacheLumpName (name,PU_CACHE)); }
// // F_Drawer // void F_Drawer (void) { if (finalestage == 2) { F_CastDrawer (); return; }
if (!finalestage) F_TextWrite (); else { switch (gameepisode) { case 1: if ( gamemode == retail ) V_DrawPatch (0,0,0, W_CacheLumpName("CREDIT",PU_CACHE)); else V_DrawPatch (0,0,0, W_CacheLumpName("HELP2",PU_CACHE)); break; case 2: V_DrawPatch(0,0,0, W_CacheLumpName("VICTORY2",PU_CACHE)); break; case 3: F_BunnyScroll (); break; case 4: V_DrawPatch (0,0,0, W_CacheLumpName("ENDPIC",PU_CACHE)); break; } } }
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // // //-----------------------------------------------------------------------------
#ifndef __F_FINALE__ #define __F_FINALE__
#include "doomtype.h" #include "d_event.h" // // FINALE //
// Called by main loop. boolean F_Responder (event_t* ev);
// Called by main loop. void F_Ticker (void);
// Called by main loop. void F_Drawer (void);
void F_StartFinale (void);
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // Mission begin melt/wipe screen special effect. // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: f_wipe.c,v 1.2 1997/02/03 22:45:09 b1 Exp $";
#include "z_zone.h" #include "i_video.h" #include "v_video.h" #include "m_random.h"
#include "doomdef.h"
#include "f_wipe.h"
// // SCREEN WIPE PACKAGE //
// when zero, stop the wipe static boolean go = 0;
static byte* wipe_scr_start; static byte* wipe_scr_end; static byte* wipe_scr;
void wipe_shittyColMajorXform ( short* array, int width, int height ) { int x; int y; short* dest;
dest = (short*) Z_Malloc(width*height*2, PU_STATIC, 0);
for(y=0;y<height;y++) for(x=0;x<width;x++) dest[x*height+y] = array[y*width+x];
memcpy(array, dest, width*height*2);
Z_Free(dest);
}
int wipe_initColorXForm ( int width, int height, int ticks ) { memcpy(wipe_scr, wipe_scr_start, width*height); return 0; }
int wipe_doColorXForm ( int width, int height, int ticks ) { boolean changed; byte* w; byte* e; int newval;
changed = false; w = wipe_scr; e = wipe_scr_end;
while (w!=wipe_scr+width*height) { if (*w != *e) { if (*w > *e) { newval = *w - ticks; if (newval < *e) *w = *e; else *w = newval; changed = true; } else if (*w < *e) { newval = *w + ticks; if (newval > *e) *w = *e; else *w = newval; changed = true; } } w++; e++; }
return !changed;
}
int wipe_exitColorXForm ( int width, int height, int ticks ) { return 0; }
static int* y;
int wipe_initMelt ( int width, int height, int ticks ) { int i, r;
// copy start screen to main screen memcpy(wipe_scr, wipe_scr_start, width*height);
// makes this wipe faster (in theory) // to have stuff in column-major format wipe_shittyColMajorXform((short*)wipe_scr_start, width/2, height); wipe_shittyColMajorXform((short*)wipe_scr_end, width/2, height);
// setup initial column positions // (y<0 => not ready to scroll yet) y = (int *) Z_Malloc(width*sizeof(int), PU_STATIC, 0); y[0] = -(M_Random()%16); for (i=1;i<width;i++) { r = (M_Random()%3) - 1; y[i] = y[i-1] + r; if (y[i] > 0) y[i] = 0; else if (y[i] == -16) y[i] = -15; }
return 0; }
int wipe_doMelt ( int width, int height, int ticks ) { int i; int j; int dy; int idx;
short* s; short* d; boolean done = true;
width/=2;
while (ticks--) { for (i=0;i<width;i++) { if (y[i]<0) { y[i]++; done = false; } else if (y[i] < height) { dy = (y[i] < 16) ? y[i]+1 : 8; if (y[i]+dy >= height) dy = height - y[i]; s = &((short *)wipe_scr_end)[i*height+y[i]]; d = &((short *)wipe_scr)[y[i]*width+i]; idx = 0; for (j=dy;j;j--) { d[idx] = *(s++); idx += width; } y[i] += dy; s = &((short *)wipe_scr_start)[i*height]; d = &((short *)wipe_scr)[y[i]*width+i]; idx = 0; for (j=height-y[i];j;j--) { d[idx] = *(s++); idx += width; } done = false; } } }
return done;
}
int wipe_exitMelt ( int width, int height, int ticks ) { Z_Free(y); return 0; }
int wipe_StartScreen ( int x, int y, int width, int height ) { wipe_scr_start = screens[2]; I_ReadScreen(wipe_scr_start); return 0; }
int wipe_EndScreen ( int x, int y, int width, int height ) { wipe_scr_end = screens[3]; I_ReadScreen(wipe_scr_end); V_DrawBlock(x, y, 0, width, height, wipe_scr_start); // restore start scr. return 0; }
int wipe_ScreenWipe ( int wipeno, int x, int y, int width, int height, int ticks ) { int rc; static int (*wipes[])(int, int, int) = { wipe_initColorXForm, wipe_doColorXForm, wipe_exitColorXForm, wipe_initMelt, wipe_doMelt, wipe_exitMelt };
void V_MarkRect(int, int, int, int);
// initial stuff if (!go) { go = 1; // wipe_scr = (byte *) Z_Malloc(width*height, PU_STATIC, 0); // DEBUG wipe_scr = screens[0]; (*wipes[wipeno*3])(width, height, ticks); }
// do a piece of wipe-in V_MarkRect(0, 0, width, height); rc = (*wipes[wipeno*3+1])(width, height, ticks); // V_DrawBlock(x, y, 0, width, height, wipe_scr); // DEBUG
// final stuff if (rc) { go = 0; (*wipes[wipeno*3+2])(width, height, ticks); }
return !go;
} // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // Mission start screen wipe/melt, special effects. // //-----------------------------------------------------------------------------
#ifndef __F_WIPE_H__ #define __F_WIPE_H__
// // SCREEN WIPE PACKAGE //
enum { // simple gradual pixel change for 8-bit only wipe_ColorXForm,
// weird screen melt wipe_Melt,
wipe_NUMWIPES };
int wipe_StartScreen ( int x, int y, int width, int height );
int wipe_EndScreen ( int x, int y, int width, int height );
int wipe_ScreenWipe ( int wipeno, int x, int y, int width, int height, int ticks );
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- total 1258 -rw-r--r-- 1 b1 prog 0 Jan 18 15:08 FILES -rw-r--r-- 1 b1 prog 5799 Jan 18 15:07 Makefile -rw-r--r-- 1 b1 prog 1943 Jan 18 15:07 am_data.h -rw-r--r-- 1 b1 prog 20263 Jan 18 15:07 am_map.c -rw-r--r-- 1 b1 prog 2494 Jan 18 15:07 am_map.h -rw-r--r-- 1 b1 prog 1499 Jan 18 15:07 am_oids.c -rw-r--r-- 1 b1 prog 338 Jan 18 15:07 am_oids.h -rw-r--r-- 1 b1 prog 14005 Jan 18 15:07 d_french.h -rw-r--r-- 1 b1 prog 25287 Jan 18 15:07 d_main.c -rw-r--r-- 1 b1 prog 15586 Jan 18 15:07 d_net.c -rw-r--r-- 1 b1 prog 744 Jan 18 15:07 defs.inc -rw-r--r-- 1 b1 prog 3569 Jan 18 15:07 dither.c -rw-r--r-- 1 b1 prog 355 Jan 18 15:07 dither.h -rw-r--r-- 1 b1 prog 4234 Jan 18 15:07 doomdata.h -rw-r--r-- 1 b1 prog 32779 Jan 18 15:07 doomdef.h -rw-r--r-- 1 b1 prog 192 Jan 18 15:07 drcoord.h -rw-r--r-- 1 b1 prog 22377 Jan 18 15:07 dstrings.h -rw-r--r-- 1 b1 prog 6582 Jan 18 15:07 dutils.c -rw-r--r-- 1 b1 prog 1821 Jan 18 15:07 dutils.h -rw-r--r-- 1 b1 prog 14072 Jan 18 15:07 f_finale.c -rw-r--r-- 1 b1 prog 7357 Jan 18 15:07 fpfunc.S -rw-r--r-- 1 b1 prog 34770 Jan 18 15:07 g_game.c -rw-r--r-- 1 b1 prog 5394 Jan 18 15:07 hu_lib.c -rw-r--r-- 1 b1 prog 2878 Jan 18 15:07 hu_lib.h -rw-r--r-- 1 b1 prog 12040 Jan 18 15:07 hu_stuff.c -rw-r--r-- 1 b1 prog 934 Jan 18 15:07 hu_stuff.h -rw-r--r-- 1 b1 prog 6238 Jan 18 15:07 i_cyber.c -rw-r--r-- 1 b1 prog 18324 Jan 18 15:07 i_dga.c -rw-r--r-- 1 b1 prog 2499 Jan 18 15:07 i_header.h -rw-r--r-- 1 b1 prog 32815 Jan 18 15:07 i_ibm.c -rw-r--r-- 1 b1 prog 1867 Jan 18 15:07 i_ibm_a.asm -rw-r--r-- 1 b1 prog 121 Jan 18 15:07 i_main.c -rw-r--r-- 1 b1 prog 8251 Jan 18 15:07 i_pcnet.c -rw-r--r-- 1 b1 prog 8561 Jan 18 15:07 i_sound.c -rw-r--r-- 1 b1 prog 439 Jan 18 15:07 i_sound.h -rw-r--r-- 1 b1 prog 9537 Jan 18 15:07 i_svgalib.c -rw-r--r-- 1 b1 prog 10886 Jan 18 15:07 i_unix.c -rw-r--r-- 1 b1 prog 20891 Jan 18 15:07 i_x.c -rw-r--r-- 1 b1 prog 128797 Jan 18 15:07 info.c -rw-r--r-- 1 b1 prog 15840 Jan 18 15:07 info.h -rw-r--r-- 1 b1 prog 3477 Jan 18 15:07 irix.c -rw-r--r-- 1 b1 prog 240 Jan 18 15:07 irix.h -rw-r--r-- 1 b1 prog 1363 Jan 18 15:07 linux.c -rw-r--r-- 1 b1 prog 34628 Jan 18 15:07 m_menu.c -rw-r--r-- 1 b1 prog 13741 Jan 18 15:07 m_misc.c -rw-r--r-- 1 b1 prog 6117 Jan 18 15:07 p_ceilng.c -rw-r--r-- 1 b1 prog 15062 Jan 18 15:07 p_doors.c -rw-r--r-- 1 b1 prog 33758 Jan 18 15:07 p_enemy.c -rw-r--r-- 1 b1 prog 11409 Jan 18 15:07 p_floor.c -rw-r--r-- 1 b1 prog 16265 Jan 18 15:07 p_inter.c -rw-r--r-- 1 b1 prog 7592 Jan 18 15:07 p_lights.c -rw-r--r-- 1 b1 prog 6447 Jan 18 15:07 p_local.h -rw-r--r-- 1 b1 prog 30138 Jan 18 15:07 p_map.c -rw-r--r-- 1 b1 prog 14672 Jan 18 15:07 p_maputl.c -rw-r--r-- 1 b1 prog 17276 Jan 18 15:07 p_mobj.c -rw-r--r-- 1 b1 prog 5940 Jan 18 15:07 p_plats.c -rw-r--r-- 1 b1 prog 17084 Jan 18 15:07 p_pspr.c -rw-r--r-- 1 b1 prog 12828 Jan 18 15:07 p_setup.c -rw-r--r-- 1 b1 prog 5962 Jan 18 15:07 p_sight.c -rw-r--r-- 1 b1 prog 23846 Jan 18 15:07 p_spec.c -rw-r--r-- 1 b1 prog 11140 Jan 18 15:07 p_spec.h -rw-r--r-- 1 b1 prog 14229 Jan 18 15:07 p_switch.c -rw-r--r-- 1 b1 prog 1910 Jan 18 15:07 p_telept.c -rw-r--r-- 1 b1 prog 14075 Jan 18 15:07 p_tick.c -rw-r--r-- 1 b1 prog 7044 Jan 18 15:07 p_user.c -rw-r--r-- 1 b1 prog 13013 Jan 18 15:07 planar.asm -rw-r--r-- 1 b1 prog 9811 Jan 18 15:07 r_bsp.c -rw-r--r-- 1 b1 prog 14619 Jan 18 15:07 r_data.c -rw-r--r-- 1 b1 prog 13591 Jan 18 15:07 r_draw.c -rw-r--r-- 1 b1 prog 11378 Jan 18 15:07 r_local.h -rw-r--r-- 1 b1 prog 14868 Jan 18 15:07 r_main.c -rw-r--r-- 1 b1 prog 7108 Jan 18 15:07 r_plane.c -rw-r--r-- 1 b1 prog 15420 Jan 18 15:07 r_segs.c -rw-r--r-- 1 b1 prog 18969 Jan 18 15:07 r_things.c -rw-r--r-- 1 b1 prog 12274 Jan 18 15:07 s_sound.c -rw-r--r-- 1 b1 prog 12812 Jan 18 15:07 sndserver.c -rw-r--r-- 1 b1 prog 141 Jan 18 15:07 sndserver.h -rw-r--r-- 1 b1 prog 5811 Jan 18 15:07 sounds.c -rw-r--r-- 1 b1 prog 2674 Jan 18 15:07 sounds.h -rw-r--r-- 1 b1 prog 3975 Jan 18 15:07 soundst.h -rw-r--r-- 1 b1 prog 3461 Jan 18 15:07 st_lib.c -rw-r--r-- 1 b1 prog 2254 Jan 18 15:07 st_lib.h -rw-r--r-- 1 b1 prog 22769 Jan 18 15:07 st_stuff.c -rw-r--r-- 1 b1 prog 4685 Jan 18 15:07 st_stuff.h -rw-r--r-- 1 b1 prog 1725 Jan 18 15:07 sun.c -rw-r--r-- 1 b1 prog 75 Jan 18 15:07 t.c -rw-r--r-- 1 b1 prog 114621 Jan 18 15:07 tables.c -rw-r--r-- 1 b1 prog 5485 Jan 18 15:07 tmap.S -rw-r--r-- 1 b1 prog 10904 Jan 18 15:07 v_video.c -rw-r--r-- 1 b1 prog 268 Jan 18 15:07 vgaview.h -rw-r--r-- 1 b1 prog 9920 Jan 18 15:07 w_wad.c -rw-r--r-- 1 b1 prog 3629 Jan 18 15:07 wadread.c -rw-r--r-- 1 b1 prog 551 Jan 18 15:07 wadread.h -rw-r--r-- 1 b1 prog 3583 Jan 18 15:07 wi_data.h -rw-r--r-- 1 b1 prog 25608 Jan 18 15:07 wi_stuff.c -rw-r--r-- 1 b1 prog 1544 Jan 18 15:07 wi_stuff.h -rw-r--r-- 1 b1 prog 8501 Jan 18 15:07 z_zone.c ChangeLog FILES FILES2 Makefile
----------------------------------------------------------------------- Global and misc. stuff ----------------------------------------------------------------------- doomdata.h - external data definitions (WAD file structure) doomdef.h - internal data definitions (game structs) dstrings.h - printed strings for translation, english d_french.h - printed strings for translation
info.h info.c - LUT's for Thing TAB, Frame TAB, generated by multigen utility dutils.h dutils.c - Dave's utilities including doubly-linked lists & simple state machines. Used in WI, ST, AM, and d_main.c
------------------------------------------------------------------------ DOOM game loop and top level stuff ------------------------------------------------------------------------ g_game.c - Game loop functions, event handling etc.
boolean G_CheckDemoStatus (void); void G_ReadDemoTiccmd (ticcmd_t *cmd); void G_WriteDemoTiccmd (ticcmd_t *cmd); void G_PlayerReborn (int player); void G_InitNew (skill_t skill, int episode, int map);
void G_DoReborn (int playernum);
void G_DoLoadLevel (void); void G_DoNewGame (void); void G_DoLoadGame (void); void G_DoPlayDemo (void); void G_DoCompleted (void); void G_DoVictory (void); void G_DoWorldDone (void); void G_DoSaveGame (void);
d_main.c - event handling, D_DoomMain() and other functions NOT int main()
d_net.c - high level networking protocol code
------------------------------------------------------------------ I Interfaces, system specifics ------------------------------------------------------------------ i_main.c - main(), calls D_DoomMain(). i_svgalib.c - Linux SVGAlib code, including main(), replaces i_main.c
i_x.c - X11 with SHM code, use with i_main.c i_dga.c - X11 DGA code, use with i_main.c i_unix.c - fixed point, networking, and display stuff for UNIX
i_ibm.c - IBM DOS VGA graphics and key/mouse/joystick, use with i_main.c i_pcnet.c - IPX networking, DOS
fpfunc.S - fixed point assembly and (currently) duplicate of tmap.S - texture mapping assembly (currently unused)
------------------------------------------------------------------ AM AutoMap ------------------------------------------------------------------ am_data.h - vector graphics for the automap
am_map.h am_map.c - automap code
------------------------------------------------------------------ HU Heads Up ------------------------------------------------------------------ hu_lib.h hu_lib.c - heads-up text and input code
hu_stuff.h hu_stuff.c - Heads-up displays
------------------------------------------------------------------- M Menu ------------------------------------------------------------------- m_menu.c - DOOM options code and leaving messages
m_misc.c - misc. HUD text display, input checks, and random table, file I/O
------------------------------------------------------------------- P Play??? ------------------------------------------------------------------- p_local.h - header for all play modules
p_spec.h - specials, lighting, doors, plats, texture animation p_spec.c - specials, texture animation
p_doors.c - door code p_plats.c - platform raising/lowering code p_ceilng.c - active (e.g. crushing) ceilings p_floor.c - active (e.g. raising) floors p_lights.c - dynamic (e.g. flickering) lighting p_switch.c - button switches and animation
p_enemy.c - enemy AI and animation p_inter.c - object/object interaction? p_map.c - movement objects, handling of collisions p_maputl.c - distance, position etc. utilities for movement p_mobj.c - mobile objects handling, spawn etc. p_user.c - more movement, bobbing etc.
p_telept.c - teleportation code
p_sight.c - LOS checks, REJECT
p_pspr.c - weapon overlays, bobbing, raising, sprite tables, firing, ammo bookkeeping
p_setup.c - load map from WAF file, setup code
p_tick.c - savegame function (archive/unarchive), thinker list handling, allocation, game tick execution (updates)
------------------------------------------------------------------- R Rendering ------------------------------------------------------------------- r_local.h - header for all rendering modules, internal map data structure definitions
r_bsp.c - BSP seg's clipping
r_data.c - texture column caching, patch assembly, flats, colormaps, sprites, lookup by name
r_draw.c - access to framebuffer API, drawing C functions
r_main.c - geometry functions, trigonometry lookups, R_RenderPlayerView
r_plane.c - floor/ceiling visplanes, sky
r_segs.c - drawing segs, marking hslices for floors/ceilings
r_things.c - sprite and sprite frame/rotation handling, drawing
tables.c - trigonometry lookup tables, static
v_video.c - gamma correction lookup, patch drawing to rectangle
------------------------------------------------------------------- S Sound ------------------------------------------------------------------- s_sound.c - more sound and music handling
soundst.h - sound and music data structures sounds.h sounds.c - sound and music lump LUT's (manually maintained)
sndserver.h sndserver.c - (Irix) sndserver code
irix.h irix.c - SGI Irix sound/sndserver support code
linux.c - Linux voxware sound/sndserver support code, replaces irix.c, uses irix.h sun.c - SUN replacement for irix.c
i_sound.h i_sound.c - DOS DMX music and sound interface
------------------------------------------------------------------- ST STatus bar ------------------------------------------------------------------- st_lib.h st_lib.c - status bar widget code
st_stuff.c st_stuff.h - status bar code
------------------------------------------------------------------- W Wad file I/O ------------------------------------------------------------------- w_wad.c - lump based functions wadread.h wadread.c - lump I/O, get SFX
------------------------------------------------------------------- WI WIn / level end screens ------------------------------------------------------------------- wi_data.h - lookups for intermission screens, patch positions
wi_stuff.h wi_stuff.c - intermission animation patchwork
------------------------------------------------------------------- Z Zone memory allocation ------------------------------------------------------------------- z_zone.c
------------------------------------------------------------------- F Final screen animation ------------------------------------------------------------------- f_finale.c - DOOM mission end screens? (bunny)
------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: none // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: g_game.c,v 1.8 1997/02/03 22:45:09 b1 Exp $";
#include <string.h> #include <stdlib.h>
#include "doomdef.h" #include "doomstat.h"
#include "z_zone.h" #include "f_finale.h" #include "m_argv.h" #include "m_misc.h" #include "m_menu.h" #include "m_random.h" #include "i_system.h"
#include "p_setup.h" #include "p_saveg.h" #include "p_tick.h"
#include "d_main.h"
#include "wi_stuff.h" #include "hu_stuff.h" #include "st_stuff.h" #include "am_map.h"
// Needs access to LFB. #include "v_video.h"
#include "w_wad.h"
#include "p_local.h"
#include "s_sound.h"
// Data. #include "dstrings.h" #include "sounds.h"
// SKY handling - still the wrong place. #include "r_data.h" #include "r_sky.h"
#include "g_game.h"
#define SAVEGAMESIZE 0x2c000 #define SAVESTRINGSIZE 24
boolean G_CheckDemoStatus (void); void G_ReadDemoTiccmd (ticcmd_t* cmd); void G_WriteDemoTiccmd (ticcmd_t* cmd); void G_PlayerReborn (int player); void G_InitNew (skill_t skill, int episode, int map);
void G_DoReborn (int playernum);
void G_DoLoadLevel (void); void G_DoNewGame (void); void G_DoLoadGame (void); void G_DoPlayDemo (void); void G_DoCompleted (void); void G_DoVictory (void); void G_DoWorldDone (void); void G_DoSaveGame (void);
gameaction_t gameaction; gamestate_t gamestate; skill_t gameskill; boolean respawnmonsters; int gameepisode; int gamemap;
boolean paused; boolean sendpause; // send a pause event next tic boolean sendsave; // send a save event next tic boolean usergame; // ok to save / end game
boolean timingdemo; // if true, exit with report on completion boolean nodrawers; // for comparative timing purposes boolean noblit; // for comparative timing purposes int starttime; // for comparative timing purposes
boolean viewactive;
boolean deathmatch; // only if started as net death boolean netgame; // only true if packets are broadcast boolean playeringame[MAXPLAYERS]; player_t players[MAXPLAYERS];
int consoleplayer; // player taking events and displaying int displayplayer; // view being displayed int gametic; int levelstarttic; // gametic at level start int totalkills, totalitems, totalsecret; // for intermission
char demoname[32]; boolean demorecording; boolean demoplayback; boolean netdemo; byte* demobuffer; byte* demo_p; byte* demoend; boolean singledemo; // quit after playing a demo from cmdline
boolean precache = true; // if true, load all graphics at start
wbstartstruct_t wminfo; // parms for world map / intermission
short consistancy[MAXPLAYERS][BACKUPTICS];
byte* savebuffer;
// // controls (have defaults) // int key_right; int key_left;
int key_up; int key_down; int key_strafeleft; int key_straferight; int key_fire; int key_use; int key_strafe; int key_speed;
int mousebfire; int mousebstrafe; int mousebforward;
int joybfire; int joybstrafe; int joybuse; int joybspeed;
#define MAXPLMOVE (forwardmove[1])
#define TURBOTHRESHOLD 0x32
fixed_t forwardmove[2] = {0x19, 0x32}; fixed_t sidemove[2] = {0x18, 0x28}; fixed_t angleturn[3] = {640, 1280, 320}; // + slow turn
#define SLOWTURNTICS 6
#define NUMKEYS 256
boolean gamekeydown[NUMKEYS]; int turnheld; // for accelerative turning
boolean mousearray[4]; boolean* mousebuttons = &mousearray[1]; // allow [-1]
// mouse values are used once int mousex; int mousey;
int dclicktime; int dclickstate; int dclicks; int dclicktime2; int dclickstate2; int dclicks2;
// joystick values are repeated int joyxmove; int joyymove; boolean joyarray[5]; boolean* joybuttons = &joyarray[1]; // allow [-1]
int savegameslot; char savedescription[32];
#define BODYQUESIZE 32
mobj_t* bodyque[BODYQUESIZE]; int bodyqueslot;
void* statcopy; // for statistics driver
int G_CmdChecksum (ticcmd_t* cmd) { int i; int sum = 0; for (i=0 ; i< sizeof(*cmd)/4 - 1 ; i++) sum += ((int *)cmd)[i]; return sum; }
// // G_BuildTiccmd // Builds a ticcmd from all of the available inputs // or reads it from the demo buffer. // If recording a demo, write it out // void G_BuildTiccmd (ticcmd_t* cmd) { int i; boolean strafe; boolean bstrafe; int speed; int tspeed; int forward; int side;
ticcmd_t* base;
base = I_BaseTiccmd (); // empty, or external driver memcpy (cmd,base,sizeof(*cmd)); cmd->consistancy = consistancy[consoleplayer][maketic%BACKUPTICS];
strafe = gamekeydown[key_strafe] || mousebuttons[mousebstrafe] || joybuttons[joybstrafe]; speed = gamekeydown[key_speed] || joybuttons[joybspeed];
forward = side = 0;
// use two stage accelerative turning // on the keyboard and joystick if (joyxmove < 0 || joyxmove > 0 || gamekeydown[key_right] || gamekeydown[key_left]) turnheld += ticdup; else turnheld = 0;
if (turnheld < SLOWTURNTICS) tspeed = 2; // slow turn else tspeed = speed;
// let movement keys cancel each other out if (strafe) { if (gamekeydown[key_right]) { // fprintf(stderr, "strafe right\n"); side += sidemove[speed]; } if (gamekeydown[key_left]) { // fprintf(stderr, "strafe left\n"); side -= sidemove[speed]; } if (joyxmove > 0) side += sidemove[speed]; if (joyxmove < 0) side -= sidemove[speed];
} else { if (gamekeydown[key_right]) cmd->angleturn -= angleturn[tspeed]; if (gamekeydown[key_left]) cmd->angleturn += angleturn[tspeed]; if (joyxmove > 0) cmd->angleturn -= angleturn[tspeed]; if (joyxmove < 0) cmd->angleturn += angleturn[tspeed]; }
if (gamekeydown[key_up]) { // fprintf(stderr, "up\n"); forward += forwardmove[speed]; } if (gamekeydown[key_down]) { // fprintf(stderr, "down\n"); forward -= forwardmove[speed]; } if (joyymove < 0) forward += forwardmove[speed]; if (joyymove > 0) forward -= forwardmove[speed]; if (gamekeydown[key_straferight]) side += sidemove[speed]; if (gamekeydown[key_strafeleft]) side -= sidemove[speed];
// buttons cmd->chatchar = HU_dequeueChatChar();
if (gamekeydown[key_fire] || mousebuttons[mousebfire] || joybuttons[joybfire]) cmd->buttons |= BT_ATTACK;
if (gamekeydown[key_use] || joybuttons[joybuse] ) { cmd->buttons |= BT_USE; // clear double clicks if hit use button dclicks = 0; }
// chainsaw overrides for (i=0 ; i<NUMWEAPONS-1 ; i++) if (gamekeydown['1'+i]) { cmd->buttons |= BT_CHANGE; cmd->buttons |= i<<BT_WEAPONSHIFT; break; }
// mouse if (mousebuttons[mousebforward]) forward += forwardmove[speed];
// forward double click if (mousebuttons[mousebforward] != dclickstate && dclicktime > 1 ) { dclickstate = mousebuttons[mousebforward]; if (dclickstate) dclicks++; if (dclicks == 2) { cmd->buttons |= BT_USE; dclicks = 0; } else dclicktime = 0; } else { dclicktime += ticdup; if (dclicktime > 20) { dclicks = 0; dclickstate = 0; } }
// strafe double click bstrafe = mousebuttons[mousebstrafe] || joybuttons[joybstrafe]; if (bstrafe != dclickstate2 && dclicktime2 > 1 ) { dclickstate2 = bstrafe; if (dclickstate2) dclicks2++; if (dclicks2 == 2) { cmd->buttons |= BT_USE; dclicks2 = 0; } else dclicktime2 = 0; } else { dclicktime2 += ticdup; if (dclicktime2 > 20) { dclicks2 = 0; dclickstate2 = 0; } }
forward += mousey; if (strafe) side += mousex*2; else cmd->angleturn -= mousex*0x8;
mousex = mousey = 0; if (forward > MAXPLMOVE) forward = MAXPLMOVE; else if (forward < -MAXPLMOVE) forward = -MAXPLMOVE; if (side > MAXPLMOVE) side = MAXPLMOVE; else if (side < -MAXPLMOVE) side = -MAXPLMOVE;
cmd->forwardmove += forward; cmd->sidemove += side;
// special buttons if (sendpause) { sendpause = false; cmd->buttons = BT_SPECIAL | BTS_PAUSE; }
if (sendsave) { sendsave = false; cmd->buttons = BT_SPECIAL | BTS_SAVEGAME | (savegameslot<<BTS_SAVESHIFT); } }
// // G_DoLoadLevel // extern gamestate_t wipegamestate;
void G_DoLoadLevel (void) { int i;
// Set the sky map. // First thing, we have a dummy sky texture name, // a flat. The data is in the WAD only because // we look for an actual index, instead of simply // setting one. skyflatnum = R_FlatNumForName ( SKYFLATNAME );
// DOOM determines the sky texture to be used // depending on the current episode, and the game version. if ( (gamemode == commercial) || ( gamemode == pack_tnt ) || ( gamemode == pack_plut ) ) { skytexture = R_TextureNumForName ("SKY3"); if (gamemap < 12) skytexture = R_TextureNumForName ("SKY1"); else if (gamemap < 21) skytexture = R_TextureNumForName ("SKY2"); }
levelstarttic = gametic; // for time calculation
if (wipegamestate == GS_LEVEL) wipegamestate = -1; // force a wipe
gamestate = GS_LEVEL;
for (i=0 ; i<MAXPLAYERS ; i++) { if (playeringame[i] && players[i].playerstate == PST_DEAD) players[i].playerstate = PST_REBORN; memset (players[i].frags,0,sizeof(players[i].frags)); } P_SetupLevel (gameepisode, gamemap, 0, gameskill); displayplayer = consoleplayer; // view the guy you are playing starttime = I_GetTime (); gameaction = ga_nothing; Z_CheckHeap ();
// clear cmd building stuff memset (gamekeydown, 0, sizeof(gamekeydown)); joyxmove = joyymove = 0; mousex = mousey = 0; sendpause = sendsave = paused = false; memset (mousebuttons, 0, sizeof(mousebuttons)); memset (joybuttons, 0, sizeof(joybuttons)); }
// // G_Responder // Get info needed to make ticcmd_ts for the players. // boolean G_Responder (event_t* ev) { // allow spy mode changes even during the demo if (gamestate == GS_LEVEL && ev->type == ev_keydown && ev->data1 == KEY_F12 && (singledemo || !deathmatch) ) { // spy mode do { displayplayer++; if (displayplayer == MAXPLAYERS) displayplayer = 0; } while (!playeringame[displayplayer] && displayplayer != consoleplayer); return true; }
// any other key pops up menu if in demos if (gameaction == ga_nothing && !singledemo && (demoplayback || gamestate == GS_DEMOSCREEN) ) { if (ev->type == ev_keydown || (ev->type == ev_mouse && ev->data1) || (ev->type == ev_joystick && ev->data1) ) { M_StartControlPanel (); return true; } return false; }
if (gamestate == GS_LEVEL) { #if 0 if (devparm && ev->type == ev_keydown && ev->data1 == ';') { G_DeathMatchSpawnPlayer (0); return true; } #endif if (HU_Responder (ev)) return true; // chat ate the event if (ST_Responder (ev)) return true; // status window ate it if (AM_Responder (ev)) return true; // automap ate it } if (gamestate == GS_FINALE) { if (F_Responder (ev)) return true; // finale ate the event } switch (ev->type) { case ev_keydown: if (ev->data1 == KEY_PAUSE) { sendpause = true; return true; } if (ev->data1 <NUMKEYS) gamekeydown[ev->data1] = true; return true; // eat key down events
case ev_keyup: if (ev->data1 <NUMKEYS) gamekeydown[ev->data1] = false; return false; // always let key up events filter down case ev_mouse: mousebuttons[0] = ev->data1 & 1; mousebuttons[1] = ev->data1 & 2; mousebuttons[2] = ev->data1 & 4; mousex = ev->data2*(mouseSensitivity+5)/10; mousey = ev->data3*(mouseSensitivity+5)/10; return true; // eat events
case ev_joystick: joybuttons[0] = ev->data1 & 1; joybuttons[1] = ev->data1 & 2; joybuttons[2] = ev->data1 & 4; joybuttons[3] = ev->data1 & 8; joyxmove = ev->data2; joyymove = ev->data3; return true; // eat events
default: break; }
return false; }
// // G_Ticker // Make ticcmd_ts for the players. // void G_Ticker (void) { int i; int buf; ticcmd_t* cmd;
// do player reborns if needed for (i=0 ; i<MAXPLAYERS ; i++) if (playeringame[i] && players[i].playerstate == PST_REBORN) G_DoReborn (i);
// do things to change the game state while (gameaction != ga_nothing) { switch (gameaction) { case ga_loadlevel: G_DoLoadLevel (); break; case ga_newgame: G_DoNewGame (); break; case ga_loadgame: G_DoLoadGame (); break; case ga_savegame: G_DoSaveGame (); break; case ga_playdemo: G_DoPlayDemo (); break; case ga_completed: G_DoCompleted (); break; case ga_victory: F_StartFinale (); break; case ga_worlddone: G_DoWorldDone (); break; case ga_screenshot: M_ScreenShot (); gameaction = ga_nothing; break; case ga_nothing: break; } }
// get commands, check consistancy, // and build new consistancy check buf = (gametic/ticdup)%BACKUPTICS;
for (i=0 ; i<MAXPLAYERS ; i++) { if (playeringame[i]) { cmd = &players[i].cmd;
memcpy (cmd, &netcmds[i][buf], sizeof(ticcmd_t));
if (demoplayback) G_ReadDemoTiccmd (cmd); if (demorecording) G_WriteDemoTiccmd (cmd); // check for turbo cheats if (cmd->forwardmove > TURBOTHRESHOLD && !(gametic&31) && ((gametic>>5)&3) == i ) { static char turbomessage[80]; extern char *player_names[4]; sprintf (turbomessage, "%s is turbo!",player_names[i]); players[consoleplayer].message = turbomessage; } if (netgame && !netdemo && !(gametic%ticdup) ) { if (gametic > BACKUPTICS && consistancy[i][buf] != cmd->consistancy) { I_Error ("consistency failure (%i should be %i)", cmd->consistancy, consistancy[i][buf]); } if (players[i].mo) consistancy[i][buf] = players[i].mo->x; else consistancy[i][buf] = rndindex; } } }
// check for special buttons for (i=0 ; i<MAXPLAYERS ; i++) { if (playeringame[i]) { if (players[i].cmd.buttons & BT_SPECIAL) { switch (players[i].cmd.buttons & BT_SPECIALMASK) { case BTS_PAUSE: paused ^= 1; if (paused) S_PauseSound (); else S_ResumeSound (); break; case BTS_SAVEGAME: if (!savedescription[0]) strcpy (savedescription, "NET GAME"); savegameslot = (players[i].cmd.buttons & BTS_SAVEMASK)>>BTS_SAVESHIFT; gameaction = ga_savegame; break; } } } }
// do main actions switch (gamestate) { case GS_LEVEL: P_Ticker (); ST_Ticker (); AM_Ticker (); HU_Ticker (); break; case GS_INTERMISSION: WI_Ticker (); break; case GS_FINALE: F_Ticker (); break;
case GS_DEMOSCREEN: D_PageTicker (); break; } }
// // PLAYER STRUCTURE FUNCTIONS // also see P_SpawnPlayer in P_Things //
// // G_InitPlayer // Called at the start. // Called by the game initialization functions. // void G_InitPlayer (int player) { player_t* p;
// set up the saved info p = &players[player]; // clear everything else to defaults G_PlayerReborn (player); }
// // G_PlayerFinishLevel // Can when a player completes a level. // void G_PlayerFinishLevel (int player) { player_t* p; p = &players[player]; memset (p->powers, 0, sizeof (p->powers)); memset (p->cards, 0, sizeof (p->cards)); p->mo->flags &= ~MF_SHADOW; // cancel invisibility p->extralight = 0; // cancel gun flashes p->fixedcolormap = 0; // cancel ir gogles p->damagecount = 0; // no palette changes p->bonuscount = 0; }
// // G_PlayerReborn // Called after a player dies // almost everything is cleared and initialized // void G_PlayerReborn (int player) { player_t* p; int i; int frags[MAXPLAYERS]; int killcount; int itemcount; int secretcount; memcpy (frags,players[player].frags,sizeof(frags)); killcount = players[player].killcount; itemcount = players[player].itemcount; secretcount = players[player].secretcount; p = &players[player]; memset (p, 0, sizeof(*p));
memcpy (players[player].frags, frags, sizeof(players[player].frags)); players[player].killcount = killcount; players[player].itemcount = itemcount; players[player].secretcount = secretcount;
p->usedown = p->attackdown = true; // don't do anything immediately p->playerstate = PST_LIVE; p->health = MAXHEALTH; p->readyweapon = p->pendingweapon = wp_pistol; p->weaponowned[wp_fist] = true; p->weaponowned[wp_pistol] = true; p->ammo[am_clip] = 50; for (i=0 ; i<NUMAMMO ; i++) p->maxammo[i] = maxammo[i]; }
// // G_CheckSpot // Returns false if the player cannot be respawned // at the given mapthing_t spot // because something is occupying it // void P_SpawnPlayer (mapthing_t* mthing);
boolean G_CheckSpot ( int playernum, mapthing_t* mthing ) { fixed_t x; fixed_t y; subsector_t* ss; unsigned an; mobj_t* mo; int i; if (!players[playernum].mo) { // first spawn of level, before corpses for (i=0 ; i<playernum ; i++) if (players[i].mo->x == mthing->x << FRACBITS && players[i].mo->y == mthing->y << FRACBITS) return false; return true; } x = mthing->x << FRACBITS; y = mthing->y << FRACBITS; if (!P_CheckPosition (players[playernum].mo, x, y) ) return false;
// flush an old corpse if needed if (bodyqueslot >= BODYQUESIZE) P_RemoveMobj (bodyque[bodyqueslot%BODYQUESIZE]); bodyque[bodyqueslot%BODYQUESIZE] = players[playernum].mo; bodyqueslot++; // spawn a teleport fog ss = R_PointInSubsector (x,y); an = ( ANG45 * (mthing->angle/45) ) >> ANGLETOFINESHIFT;
mo = P_SpawnMobj (x+20*finecosine[an], y+20*finesine[an] , ss->sector->floorheight , MT_TFOG); if (players[consoleplayer].viewz != 1) S_StartSound (mo, sfx_telept); // don't start sound on first frame
return true; }
// // G_DeathMatchSpawnPlayer // Spawns a player at one of the random death match spots // called at level load and each death // void G_DeathMatchSpawnPlayer (int playernum) { int i,j; int selections; selections = deathmatch_p - deathmatchstarts; if (selections < 4) I_Error ("Only %i deathmatch spots, 4 required", selections);
for (j=0 ; j<20 ; j++) { i = P_Random() % selections; if (G_CheckSpot (playernum, &deathmatchstarts[i]) ) { deathmatchstarts[i].type = playernum+1; P_SpawnPlayer (&deathmatchstarts[i]); return; } }
// no good spot, so the player will probably get stuck P_SpawnPlayer (&playerstarts[playernum]); }
// // G_DoReborn // void G_DoReborn (int playernum) { int i; if (!netgame) { // reload the level from scratch gameaction = ga_loadlevel; } else { // respawn at the start
// first dissasociate the corpse players[playernum].mo->player = NULL; // spawn at random spot if in death match if (deathmatch) { G_DeathMatchSpawnPlayer (playernum); return; } if (G_CheckSpot (playernum, &playerstarts[playernum]) ) { P_SpawnPlayer (&playerstarts[playernum]); return; } // try to spawn at one of the other players spots for (i=0 ; i<MAXPLAYERS ; i++) { if (G_CheckSpot (playernum, &playerstarts[i]) ) { playerstarts[i].type = playernum+1; // fake as other player P_SpawnPlayer (&playerstarts[i]); playerstarts[i].type = i+1; // restore return; } // he's going to be inside something. Too bad. } P_SpawnPlayer (&playerstarts[playernum]); } }
void G_ScreenShot (void) { gameaction = ga_screenshot; }
// DOOM Par Times int pars[4][10] = { {0}, {0,30,75,120,90,165,180,180,30,165}, {0,90,90,90,120,90,360,240,30,170}, {0,90,45,90,150,90,90,165,30,135} };
// DOOM II Par Times int cpars[32] = { 30,90,120,120,90,150,120,120,270,90, // 1-10 210,150,150,150,210,150,420,150,210,150, // 11-20 240,150,180,150,150,300,330,420,300,180, // 21-30 120,30 // 31-32 };
// // G_DoCompleted // boolean secretexit; extern char* pagename;
void G_ExitLevel (void) { secretexit = false; gameaction = ga_completed; }
// Here's for the german edition. void G_SecretExitLevel (void) { // IF NO WOLF3D LEVELS, NO SECRET EXIT! if ( (gamemode == commercial) && (W_CheckNumForName("map31")<0)) secretexit = false; else secretexit = true; gameaction = ga_completed; }
void G_DoCompleted (void) { int i; gameaction = ga_nothing;
for (i=0 ; i<MAXPLAYERS ; i++) if (playeringame[i]) G_PlayerFinishLevel (i); // take away cards and stuff if (automapactive) AM_Stop (); if ( gamemode != commercial) switch(gamemap) { case 8: gameaction = ga_victory; return; case 9: for (i=0 ; i<MAXPLAYERS ; i++) players[i].didsecret = true; break; } //#if 0 Hmmm - why? if ( (gamemap == 8) && (gamemode != commercial) ) { // victory gameaction = ga_victory; return; } if ( (gamemap == 9) && (gamemode != commercial) ) { // exit secret level for (i=0 ; i<MAXPLAYERS ; i++) players[i].didsecret = true; } //#endif
wminfo.didsecret = players[consoleplayer].didsecret; wminfo.epsd = gameepisode -1; wminfo.last = gamemap -1;
// wminfo.next is 0 biased, unlike gamemap if ( gamemode == commercial) { if (secretexit) switch(gamemap) { case 15: wminfo.next = 30; break; case 31: wminfo.next = 31; break; } else switch(gamemap) { case 31: case 32: wminfo.next = 15; break; default: wminfo.next = gamemap; } } else { if (secretexit) wminfo.next = 8; // go to secret level else if (gamemap == 9) { // returning from secret level switch (gameepisode) { case 1: wminfo.next = 3; break; case 2: wminfo.next = 5; break; case 3: wminfo.next = 6; break; case 4: wminfo.next = 2; break; } } else wminfo.next = gamemap; // go to next level } wminfo.maxkills = totalkills; wminfo.maxitems = totalitems; wminfo.maxsecret = totalsecret; wminfo.maxfrags = 0; if ( gamemode == commercial ) wminfo.partime = 35*cpars[gamemap-1]; else wminfo.partime = 35*pars[gameepisode][gamemap]; wminfo.pnum = consoleplayer;
for (i=0 ; i<MAXPLAYERS ; i++) { wminfo.plyr[i].in = playeringame[i]; wminfo.plyr[i].skills = players[i].killcount; wminfo.plyr[i].sitems = players[i].itemcount; wminfo.plyr[i].ssecret = players[i].secretcount; wminfo.plyr[i].stime = leveltime; memcpy (wminfo.plyr[i].frags, players[i].frags , sizeof(wminfo.plyr[i].frags)); }
gamestate = GS_INTERMISSION; viewactive = false; automapactive = false;
if (statcopy) memcpy (statcopy, &wminfo, sizeof(wminfo)); WI_Start (&wminfo); }
// // G_WorldDone // void G_WorldDone (void) { gameaction = ga_worlddone;
if (secretexit) players[consoleplayer].didsecret = true;
if ( gamemode == commercial ) { switch (gamemap) { case 15: case 31: if (!secretexit) break; case 6: case 11: case 20: case 30: F_StartFinale (); break; } } }
void G_DoWorldDone (void) { gamestate = GS_LEVEL; gamemap = wminfo.next+1; G_DoLoadLevel (); gameaction = ga_nothing; viewactive = true; }
// // G_InitFromSavegame // Can be called by the startup code or the menu task. // extern boolean setsizeneeded; void R_ExecuteSetViewSize (void);
char savename[256];
void G_LoadGame (char* name) { strcpy (savename, name); gameaction = ga_loadgame; }
#define VERSIONSIZE 16
void G_DoLoadGame (void) { int length; int i; int a,b,c; char vcheck[VERSIONSIZE]; gameaction = ga_nothing; length = M_ReadFile (savename, &savebuffer); save_p = savebuffer + SAVESTRINGSIZE;
// skip the description field memset (vcheck,0,sizeof(vcheck)); sprintf (vcheck,"version %i",VERSION); if (strcmp (save_p, vcheck)) return; // bad version save_p += VERSIONSIZE; gameskill = *save_p++; gameepisode = *save_p++; gamemap = *save_p++; for (i=0 ; i<MAXPLAYERS ; i++) playeringame[i] = *save_p++;
// load a base level G_InitNew (gameskill, gameepisode, gamemap);
// get the times a = *save_p++; b = *save_p++; c = *save_p++; leveltime = (a<<16) + (b<<8) + c; // dearchive all the modifications P_UnArchivePlayers (); P_UnArchiveWorld (); P_UnArchiveThinkers (); P_UnArchiveSpecials ();
if (*save_p != 0x1d) I_Error ("Bad savegame");
// done Z_Free (savebuffer);
if (setsizeneeded) R_ExecuteSetViewSize ();
// draw the pattern into the back screen R_FillBackScreen (); }
// // G_SaveGame // Called by the menu task. // Description is a 24 byte text string // void G_SaveGame ( int slot, char* description ) { savegameslot = slot; strcpy (savedescription, description); sendsave = true; }
void G_DoSaveGame (void) { char name[100]; char name2[VERSIONSIZE]; char* description; int length; int i; if (M_CheckParm("-cdrom")) sprintf(name,"c:\\doomdata\\"SAVEGAMENAME"%d.dsg",savegameslot); else sprintf (name,SAVEGAMENAME"%d.dsg",savegameslot); description = savedescription; save_p = savebuffer = screens[1]+0x4000; memcpy (save_p, description, SAVESTRINGSIZE); save_p += SAVESTRINGSIZE; memset (name2,0,sizeof(name2)); sprintf (name2,"version %i",VERSION); memcpy (save_p, name2, VERSIONSIZE); save_p += VERSIONSIZE; *save_p++ = gameskill; *save_p++ = gameepisode; *save_p++ = gamemap; for (i=0 ; i<MAXPLAYERS ; i++) *save_p++ = playeringame[i]; *save_p++ = leveltime>>16; *save_p++ = leveltime>>8; *save_p++ = leveltime;
P_ArchivePlayers (); P_ArchiveWorld (); P_ArchiveThinkers (); P_ArchiveSpecials (); *save_p++ = 0x1d; // consistancy marker length = save_p - savebuffer; if (length > SAVEGAMESIZE) I_Error ("Savegame buffer overrun"); M_WriteFile (name, savebuffer, length); gameaction = ga_nothing; savedescription[0] = 0; players[consoleplayer].message = GGSAVED;
// draw the pattern into the back screen R_FillBackScreen (); }
// // G_InitNew // Can be called by the startup code or the menu task, // consoleplayer, displayplayer, playeringame[] should be set. // skill_t d_skill; int d_episode; int d_map;
void G_DeferedInitNew ( skill_t skill, int episode, int map) { d_skill = skill; d_episode = episode; d_map = map; gameaction = ga_newgame; }
void G_DoNewGame (void) { demoplayback = false; netdemo = false; netgame = false; deathmatch = false; playeringame[1] = playeringame[2] = playeringame[3] = 0; respawnparm = false; fastparm = false; nomonsters = false; consoleplayer = 0; G_InitNew (d_skill, d_episode, d_map); gameaction = ga_nothing; }
// The sky texture to be used instead of the F_SKY1 dummy. extern int skytexture;
void G_InitNew ( skill_t skill, int episode, int map ) { int i; if (paused) { paused = false; S_ResumeSound (); }
if (skill > sk_nightmare) skill = sk_nightmare;
// This was quite messy with SPECIAL and commented parts. // Supposedly hacks to make the latest edition work. // It might not work properly. if (episode < 1) episode = 1;
if ( gamemode == retail ) { if (episode > 4) episode = 4; } else if ( gamemode == shareware ) { if (episode > 1) episode = 1; // only start episode 1 on shareware } else { if (episode > 3) episode = 3; }
if (map < 1) map = 1;
if ( (map > 9) && ( gamemode != commercial) ) map = 9; M_ClearRandom (); if (skill == sk_nightmare || respawnparm ) respawnmonsters = true; else respawnmonsters = false; if (fastparm || (skill == sk_nightmare && gameskill != sk_nightmare) ) { for (i=S_SARG_RUN1 ; i<=S_SARG_PAIN2 ; i++) states[i].tics >>= 1; mobjinfo[MT_BRUISERSHOT].speed = 20*FRACUNIT; mobjinfo[MT_HEADSHOT].speed = 20*FRACUNIT; mobjinfo[MT_TROOPSHOT].speed = 20*FRACUNIT; } else if (skill != sk_nightmare && gameskill == sk_nightmare) { for (i=S_SARG_RUN1 ; i<=S_SARG_PAIN2 ; i++) states[i].tics <<= 1; mobjinfo[MT_BRUISERSHOT].speed = 15*FRACUNIT; mobjinfo[MT_HEADSHOT].speed = 10*FRACUNIT; mobjinfo[MT_TROOPSHOT].speed = 10*FRACUNIT; } // force players to be initialized upon first level load for (i=0 ; i<MAXPLAYERS ; i++) players[i].playerstate = PST_REBORN;
usergame = true; // will be set false if a demo paused = false; demoplayback = false; automapactive = false; viewactive = true; gameepisode = episode; gamemap = map; gameskill = skill;
viewactive = true;
// set the sky map for the episode if ( gamemode == commercial) { skytexture = R_TextureNumForName ("SKY3"); if (gamemap < 12) skytexture = R_TextureNumForName ("SKY1"); else if (gamemap < 21) skytexture = R_TextureNumForName ("SKY2"); } else switch (episode) { case 1: skytexture = R_TextureNumForName ("SKY1"); break; case 2: skytexture = R_TextureNumForName ("SKY2"); break; case 3: skytexture = R_TextureNumForName ("SKY3"); break; case 4: // Special Edition sky skytexture = R_TextureNumForName ("SKY4"); break; }
G_DoLoadLevel (); }
// // DEMO RECORDING // #define DEMOMARKER 0x80
void G_ReadDemoTiccmd (ticcmd_t* cmd) { if (*demo_p == DEMOMARKER) { // end of demo data stream G_CheckDemoStatus (); return; } cmd->forwardmove = ((signed char)*demo_p++); cmd->sidemove = ((signed char)*demo_p++); cmd->angleturn = ((unsigned char)*demo_p++)<<8; cmd->buttons = (unsigned char)*demo_p++; }
void G_WriteDemoTiccmd (ticcmd_t* cmd) { if (gamekeydown['q']) // press q to end demo recording G_CheckDemoStatus (); *demo_p++ = cmd->forwardmove; *demo_p++ = cmd->sidemove; *demo_p++ = (cmd->angleturn+128)>>8; *demo_p++ = cmd->buttons; demo_p -= 4; if (demo_p > demoend - 16) { // no more space G_CheckDemoStatus (); return; } G_ReadDemoTiccmd (cmd); // make SURE it is exactly the same }
// // G_RecordDemo // void G_RecordDemo (char* name) { int i; int maxsize; usergame = false; strcpy (demoname, name); strcat (demoname, ".lmp"); maxsize = 0x20000; i = M_CheckParm ("-maxdemo"); if (i && i<myargc-1) maxsize = atoi(myargv[i+1])*1024; demobuffer = Z_Malloc (maxsize,PU_STATIC,NULL); demoend = demobuffer + maxsize; demorecording = true; }
void G_BeginRecording (void) { int i; demo_p = demobuffer; *demo_p++ = VERSION; *demo_p++ = gameskill; *demo_p++ = gameepisode; *demo_p++ = gamemap; *demo_p++ = deathmatch; *demo_p++ = respawnparm; *demo_p++ = fastparm; *demo_p++ = nomonsters; *demo_p++ = consoleplayer; for (i=0 ; i<MAXPLAYERS ; i++) *demo_p++ = playeringame[i]; }
// // G_PlayDemo //
char* defdemoname;
void G_DeferedPlayDemo (char* name) { defdemoname = name; gameaction = ga_playdemo; }
void G_DoPlayDemo (void) { skill_t skill; int i, episode, map; gameaction = ga_nothing; demobuffer = demo_p = W_CacheLumpName (defdemoname, PU_STATIC); if ( *demo_p++ != VERSION) { fprintf( stderr, "Demo is from a different game version!\n"); gameaction = ga_nothing; return; }
skill = *demo_p++; episode = *demo_p++; map = *demo_p++; deathmatch = *demo_p++; respawnparm = *demo_p++; fastparm = *demo_p++; nomonsters = *demo_p++; consoleplayer = *demo_p++; for (i=0 ; i<MAXPLAYERS ; i++) playeringame[i] = *demo_p++; if (playeringame[1]) { netgame = true; netdemo = true; }
// don't spend a lot of time in loadlevel precache = false; G_InitNew (skill, episode, map); precache = true;
usergame = false; demoplayback = true; }
// // G_TimeDemo // void G_TimeDemo (char* name) { nodrawers = M_CheckParm ("-nodraw"); noblit = M_CheckParm ("-noblit"); timingdemo = true; singletics = true;
defdemoname = name; gameaction = ga_playdemo; }
/* =================== = = G_CheckDemoStatus = = Called after a death or level completion to allow demos to be cleaned up = Returns true if a new demo loop action will take place =================== */
boolean G_CheckDemoStatus (void) { int endtime; if (timingdemo) { endtime = I_GetTime (); I_Error ("timed %i gametics in %i realtics",gametic , endtime-starttime); } if (demoplayback) { if (singledemo) I_Quit (); Z_ChangeTag (demobuffer, PU_CACHE); demoplayback = false; netdemo = false; netgame = false; deathmatch = false; playeringame[1] = playeringame[2] = playeringame[3] = 0; respawnparm = false; fastparm = false; nomonsters = false; consoleplayer = 0; D_AdvanceDemo (); return true; }
if (demorecording) { *demo_p++ = DEMOMARKER; M_WriteFile (demoname, demobuffer, demo_p - demobuffer); Z_Free (demobuffer); demorecording = false; I_Error ("Demo %s recorded",demoname); } return false; }
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // Duh. // //-----------------------------------------------------------------------------
#ifndef __G_GAME__ #define __G_GAME__
#include "doomdef.h" #include "d_event.h"
// // GAME // void G_DeathMatchSpawnPlayer (int playernum);
void G_InitNew (skill_t skill, int episode, int map);
// Can be called by the startup code or M_Responder. // A normal game starts at map 1, // but a warp test can start elsewhere void G_DeferedInitNew (skill_t skill, int episode, int map);
void G_DeferedPlayDemo (char* demo);
// Can be called by the startup code or M_Responder, // calls P_SetupLevel or W_EnterWorld. void G_LoadGame (char* name);
void G_DoLoadGame (void);
// Called by M_Responder. void G_SaveGame (int slot, char* description);
// Only called by startup code. void G_RecordDemo (char* name);
void G_BeginRecording (void);
void G_PlayDemo (char* name); void G_TimeDemo (char* name); boolean G_CheckDemoStatus (void);
void G_ExitLevel (void); void G_SecretExitLevel (void);
void G_WorldDone (void);
void G_Ticker (void); boolean G_Responder (event_t* ev);
void G_ScreenShot (void);
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: heads-up text and input code // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: hu_lib.c,v 1.3 1997/01/26 07:44:58 b1 Exp $";
#include <ctype.h>
#include "doomdef.h"
#include "v_video.h" #include "m_swap.h"
#include "hu_lib.h" #include "r_local.h" #include "r_draw.h"
// boolean : whether the screen is always erased #define noterased viewwindowx
extern boolean automapactive; // in AM_map.c
void HUlib_init(void) { }
void HUlib_clearTextLine(hu_textline_t* t) { t->len = 0; t->l[0] = 0; t->needsupdate = true; }
void HUlib_initTextLine ( hu_textline_t* t, int x, int y, patch_t** f, int sc ) { t->x = x; t->y = y; t->f = f; t->sc = sc; HUlib_clearTextLine(t); }
boolean HUlib_addCharToTextLine ( hu_textline_t* t, char ch ) {
if (t->len == HU_MAXLINELENGTH) return false; else { t->l[t->len++] = ch; t->l[t->len] = 0; t->needsupdate = 4; return true; }
}
boolean HUlib_delCharFromTextLine(hu_textline_t* t) {
if (!t->len) return false; else { t->l[--t->len] = 0; t->needsupdate = 4; return true; }
}
void HUlib_drawTextLine ( hu_textline_t* l, boolean drawcursor ) {
int i; int w; int x; unsigned char c;
// draw the new stuff x = l->x; for (i=0;i<l->len;i++) { c = toupper(l->l[i]); if (c != ' ' && c >= l->sc && c <= '_') { w = SHORT(l->f[c - l->sc]->width); if (x+w > SCREENWIDTH) break; V_DrawPatchDirect(x, l->y, FG, l->f[c - l->sc]); x += w; } else { x += 4; if (x >= SCREENWIDTH) break; } }
// draw the cursor if requested if (drawcursor && x + SHORT(l->f['_' - l->sc]->width) <= SCREENWIDTH) { V_DrawPatchDirect(x, l->y, FG, l->f['_' - l->sc]); } }
// sorta called by HU_Erase and just better darn get things straight void HUlib_eraseTextLine(hu_textline_t* l) { int lh; int y; int yoffset; static boolean lastautomapactive = true;
// Only erases when NOT in automap and the screen is reduced, // and the text must either need updating or refreshing // (because of a recent change back from the automap)
if (!automapactive && viewwindowx && l->needsupdate) { lh = SHORT(l->f[0]->height) + 1; for (y=l->y,yoffset=y*SCREENWIDTH ; y<l->y+lh ; y++,yoffset+=SCREENWIDTH) { if (y < viewwindowy || y >= viewwindowy + viewheight) R_VideoErase(yoffset, SCREENWIDTH); // erase entire line else { R_VideoErase(yoffset, viewwindowx); // erase left border R_VideoErase(yoffset + viewwindowx + viewwidth, viewwindowx); // erase right border } } }
lastautomapactive = automapactive; if (l->needsupdate) l->needsupdate--;
}
void HUlib_initSText ( hu_stext_t* s, int x, int y, int h, patch_t** font, int startchar, boolean* on ) {
int i;
s->h = h; s->on = on; s->laston = true; s->cl = 0; for (i=0;i<h;i++) HUlib_initTextLine(&s->l[i], x, y - i*(SHORT(font[0]->height)+1), font, startchar);
}
void HUlib_addLineToSText(hu_stext_t* s) {
int i;
// add a clear line if (++s->cl == s->h) s->cl = 0; HUlib_clearTextLine(&s->l[s->cl]);
// everything needs updating for (i=0 ; i<s->h ; i++) s->l[i].needsupdate = 4;
}
void HUlib_addMessageToSText ( hu_stext_t* s, char* prefix, char* msg ) { HUlib_addLineToSText(s); if (prefix) while (*prefix) HUlib_addCharToTextLine(&s->l[s->cl], *(prefix++));
while (*msg) HUlib_addCharToTextLine(&s->l[s->cl], *(msg++)); }
void HUlib_drawSText(hu_stext_t* s) { int i, idx; hu_textline_t *l;
if (!*s->on) return; // if not on, don't draw
// draw everything for (i=0 ; i<s->h ; i++) { idx = s->cl - i; if (idx < 0) idx += s->h; // handle queue of lines l = &s->l[idx];
// need a decision made here on whether to skip the draw HUlib_drawTextLine(l, false); // no cursor, please }
}
void HUlib_eraseSText(hu_stext_t* s) {
int i;
for (i=0 ; i<s->h ; i++) { if (s->laston && !*s->on) s->l[i].needsupdate = 4; HUlib_eraseTextLine(&s->l[i]); } s->laston = *s->on;
}
void HUlib_initIText ( hu_itext_t* it, int x, int y, patch_t** font, int startchar, boolean* on ) { it->lm = 0; // default left margin is start of text it->on = on; it->laston = true; HUlib_initTextLine(&it->l, x, y, font, startchar); }
// The following deletion routines adhere to the left margin restriction void HUlib_delCharFromIText(hu_itext_t* it) { if (it->l.len != it->lm) HUlib_delCharFromTextLine(&it->l); }
void HUlib_eraseLineFromIText(hu_itext_t* it) { while (it->lm != it->l.len) HUlib_delCharFromTextLine(&it->l); }
// Resets left margin as well void HUlib_resetIText(hu_itext_t* it) { it->lm = 0; HUlib_clearTextLine(&it->l); }
void HUlib_addPrefixToIText ( hu_itext_t* it, char* str ) { while (*str) HUlib_addCharToTextLine(&it->l, *(str++)); it->lm = it->l.len; }
// wrapper function for handling general keyed input. // returns true if it ate the key boolean HUlib_keyInIText ( hu_itext_t* it, unsigned char ch ) {
if (ch >= ' ' && ch <= '_') HUlib_addCharToTextLine(&it->l, (char) ch); else if (ch == KEY_BACKSPACE) HUlib_delCharFromIText(it); else if (ch != KEY_ENTER) return false; // did not eat key
return true; // ate the key
}
void HUlib_drawIText(hu_itext_t* it) {
hu_textline_t *l = &it->l;
if (!*it->on) return; HUlib_drawTextLine(l, true); // draw the line w/ cursor
}
void HUlib_eraseIText(hu_itext_t* it) { if (it->laston && !*it->on) it->l.needsupdate = 4; HUlib_eraseTextLine(&it->l); it->laston = *it->on; }
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: none // //-----------------------------------------------------------------------------
#ifndef __HULIB__ #define __HULIB__
// We are referring to patches. #include "r_defs.h"
// background and foreground screen numbers // different from other modules. #define BG 1 #define FG 0
// font stuff #define HU_CHARERASE KEY_BACKSPACE
#define HU_MAXLINES 4 #define HU_MAXLINELENGTH 80
// // Typedefs of widgets //
// Text Line widget // (parent of Scrolling Text and Input Text widgets) typedef struct { // left-justified position of scrolling text window int x; int y;
patch_t** f; // font int sc; // start character char l[HU_MAXLINELENGTH+1]; // line of text int len; // current line length
// whether this line needs to be udpated int needsupdate;
} hu_textline_t;
// Scrolling Text window widget // (child of Text Line widget) typedef struct { hu_textline_t l[HU_MAXLINES]; // text lines to draw int h; // height in lines int cl; // current line number
// pointer to boolean stating whether to update window boolean* on; boolean laston; // last value of *->on.
} hu_stext_t;
// Input Text Line widget // (child of Text Line widget) typedef struct { hu_textline_t l; // text line to input on
// left margin past which I am not to delete characters int lm;
// pointer to boolean stating whether to update window boolean* on; boolean laston; // last value of *->on;
} hu_itext_t;
// // Widget creation, access, and update routines //
// initializes heads-up widget library void HUlib_init(void);
// // textline code //
// clear a line of text void HUlib_clearTextLine(hu_textline_t *t);
void HUlib_initTextLine(hu_textline_t *t, int x, int y, patch_t **f, int sc);
// returns success boolean HUlib_addCharToTextLine(hu_textline_t *t, char ch);
// returns success boolean HUlib_delCharFromTextLine(hu_textline_t *t);
// draws tline void HUlib_drawTextLine(hu_textline_t *l, boolean drawcursor);
// erases text line void HUlib_eraseTextLine(hu_textline_t *l);
// // Scrolling Text window widget routines //
// ? void HUlib_initSText ( hu_stext_t* s, int x, int y, int h, patch_t** font, int startchar, boolean* on );
// add a new line void HUlib_addLineToSText(hu_stext_t* s);
// ? void HUlib_addMessageToSText ( hu_stext_t* s, char* prefix, char* msg );
// draws stext void HUlib_drawSText(hu_stext_t* s);
// erases all stext lines void HUlib_eraseSText(hu_stext_t* s);
// Input Text Line widget routines void HUlib_initIText ( hu_itext_t* it, int x, int y, patch_t** font, int startchar, boolean* on );
// enforces left margin void HUlib_delCharFromIText(hu_itext_t* it);
// enforces left margin void HUlib_eraseLineFromIText(hu_itext_t* it);
// resets line and left margin void HUlib_resetIText(hu_itext_t* it);
// left of left-margin void HUlib_addPrefixToIText ( hu_itext_t* it, char* str );
// whether eaten boolean HUlib_keyInIText ( hu_itext_t* it, unsigned char ch );
void HUlib_drawIText(hu_itext_t* it);
// erases all itext lines void HUlib_eraseIText(hu_itext_t* it);
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: Heads-up displays // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: hu_stuff.c,v 1.4 1997/02/03 16:47:52 b1 Exp $";
#include <ctype.h>
#include "doomdef.h"
#include "z_zone.h"
#include "m_swap.h"
#include "hu_stuff.h" #include "hu_lib.h" #include "w_wad.h"
#include "s_sound.h"
#include "doomstat.h"
// Data. #include "dstrings.h" #include "sounds.h"
// // Locally used constants, shortcuts. // #define HU_TITLE (mapnames[(gameepisode-1)*9+gamemap-1]) #define HU_TITLE2 (mapnames2[gamemap-1]) #define HU_TITLEP (mapnamesp[gamemap-1]) #define HU_TITLET (mapnamest[gamemap-1]) #define HU_TITLEHEIGHT 1 #define HU_TITLEX 0 #define HU_TITLEY (167 - SHORT(hu_font[0]->height))
#define HU_INPUTTOGGLE 't' #define HU_INPUTX HU_MSGX #define HU_INPUTY (HU_MSGY + HU_MSGHEIGHT*(SHORT(hu_font[0]->height) +1)) #define HU_INPUTWIDTH 64 #define HU_INPUTHEIGHT 1
char* chat_macros[] = { HUSTR_CHATMACRO0, HUSTR_CHATMACRO1, HUSTR_CHATMACRO2, HUSTR_CHATMACRO3, HUSTR_CHATMACRO4, HUSTR_CHATMACRO5, HUSTR_CHATMACRO6, HUSTR_CHATMACRO7, HUSTR_CHATMACRO8, HUSTR_CHATMACRO9 };
char* player_names[] = { HUSTR_PLRGREEN, HUSTR_PLRINDIGO, HUSTR_PLRBROWN, HUSTR_PLRRED };
char chat_char; // remove later. static player_t* plr; patch_t* hu_font[HU_FONTSIZE]; static hu_textline_t w_title; boolean chat_on; static hu_itext_t w_chat; static boolean always_off = false; static char chat_dest[MAXPLAYERS]; static hu_itext_t w_inputbuffer[MAXPLAYERS];
static boolean message_on; boolean message_dontfuckwithme; static boolean message_nottobefuckedwith;
static hu_stext_t w_message; static int message_counter;
extern int showMessages; extern boolean automapactive;
static boolean headsupactive = false;
// // Builtin map names. // The actual names can be found in DStrings.h. //
char* mapnames[] = // DOOM shareware/registered/retail (Ultimate) names. {
HUSTR_E1M1, HUSTR_E1M2, HUSTR_E1M3, HUSTR_E1M4, HUSTR_E1M5, HUSTR_E1M6, HUSTR_E1M7, HUSTR_E1M8, HUSTR_E1M9,
HUSTR_E2M1, HUSTR_E2M2, HUSTR_E2M3, HUSTR_E2M4, HUSTR_E2M5, HUSTR_E2M6, HUSTR_E2M7, HUSTR_E2M8, HUSTR_E2M9,
HUSTR_E3M1, HUSTR_E3M2, HUSTR_E3M3, HUSTR_E3M4, HUSTR_E3M5, HUSTR_E3M6, HUSTR_E3M7, HUSTR_E3M8, HUSTR_E3M9,
HUSTR_E4M1, HUSTR_E4M2, HUSTR_E4M3, HUSTR_E4M4, HUSTR_E4M5, HUSTR_E4M6, HUSTR_E4M7, HUSTR_E4M8, HUSTR_E4M9,
"NEWLEVEL", "NEWLEVEL", "NEWLEVEL", "NEWLEVEL", "NEWLEVEL", "NEWLEVEL", "NEWLEVEL", "NEWLEVEL", "NEWLEVEL" };
char* mapnames2[] = // DOOM 2 map names. { HUSTR_1, HUSTR_2, HUSTR_3, HUSTR_4, HUSTR_5, HUSTR_6, HUSTR_7, HUSTR_8, HUSTR_9, HUSTR_10, HUSTR_11, HUSTR_12, HUSTR_13, HUSTR_14, HUSTR_15, HUSTR_16, HUSTR_17, HUSTR_18, HUSTR_19, HUSTR_20, HUSTR_21, HUSTR_22, HUSTR_23, HUSTR_24, HUSTR_25, HUSTR_26, HUSTR_27, HUSTR_28, HUSTR_29, HUSTR_30, HUSTR_31, HUSTR_32 };
char* mapnamesp[] = // Plutonia WAD map names. { PHUSTR_1, PHUSTR_2, PHUSTR_3, PHUSTR_4, PHUSTR_5, PHUSTR_6, PHUSTR_7, PHUSTR_8, PHUSTR_9, PHUSTR_10, PHUSTR_11, PHUSTR_12, PHUSTR_13, PHUSTR_14, PHUSTR_15, PHUSTR_16, PHUSTR_17, PHUSTR_18, PHUSTR_19, PHUSTR_20, PHUSTR_21, PHUSTR_22, PHUSTR_23, PHUSTR_24, PHUSTR_25, PHUSTR_26, PHUSTR_27, PHUSTR_28, PHUSTR_29, PHUSTR_30, PHUSTR_31, PHUSTR_32 };
char *mapnamest[] = // TNT WAD map names. { THUSTR_1, THUSTR_2, THUSTR_3, THUSTR_4, THUSTR_5, THUSTR_6, THUSTR_7, THUSTR_8, THUSTR_9, THUSTR_10, THUSTR_11, THUSTR_12, THUSTR_13, THUSTR_14, THUSTR_15, THUSTR_16, THUSTR_17, THUSTR_18, THUSTR_19, THUSTR_20, THUSTR_21, THUSTR_22, THUSTR_23, THUSTR_24, THUSTR_25, THUSTR_26, THUSTR_27, THUSTR_28, THUSTR_29, THUSTR_30, THUSTR_31, THUSTR_32 };
const char* shiftxform;
const char french_shiftxform[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, ' ', '!', '"', '#', '$', '%', '&', '"', // shift-' '(', ')', '*', '+', '?', // shift-, '_', // shift-- '>', // shift-. '?', // shift-/ '0', // shift-0 '1', // shift-1 '2', // shift-2 '3', // shift-3 '4', // shift-4 '5', // shift-5 '6', // shift-6 '7', // shift-7 '8', // shift-8 '9', // shift-9 '/', '.', // shift-; '<', '+', // shift-= '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', // shift-[ '!', // shift-backslash - OH MY GOD DOES WATCOM SUCK ']', // shift-] '"', '_', '\'', // shift-` 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '{', '|', '}', '~', 127
};
const char english_shiftxform[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, ' ', '!', '"', '#', '$', '%', '&', '"', // shift-' '(', ')', '*', '+', '<', // shift-, '_', // shift-- '>', // shift-. '?', // shift-/ ')', // shift-0 '!', // shift-1 '@', // shift-2 '#', // shift-3 '$', // shift-4 '%', // shift-5 '^', // shift-6 '&', // shift-7 '*', // shift-8 '(', // shift-9 ':', ':', // shift-; '<', '+', // shift-= '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', // shift-[ '!', // shift-backslash - OH MY GOD DOES WATCOM SUCK ']', // shift-] '"', '_', '\'', // shift-` 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '{', '|', '}', '~', 127 };
char frenchKeyMap[128]= { 0, 1,2,3,4,5,6,7,8,9,10, 11,12,13,14,15,16,17,18,19,20, 21,22,23,24,25,26,27,28,29,30, 31, ' ','!','"','#','$','%','&','%','(',')','*','+',';','-',':','!', '0','1','2','3','4','5','6','7','8','9',':','M','<','=','>','?', '@','Q','B','C','D','E','F','G','H','I','J','K','L',',','N','O', 'P','A','R','S','T','U','V','Z','X','Y','W','^','\\','$','^','_', '@','Q','B','C','D','E','F','G','H','I','J','K','L',',','N','O', 'P','A','R','S','T','U','V','Z','X','Y','W','^','\\','$','^',127 };
char ForeignTranslation(unsigned char ch) { return ch < 128 ? frenchKeyMap[ch] : ch; }
void HU_Init(void) {
int i; int j; char buffer[9];
if (french) shiftxform = french_shiftxform; else shiftxform = english_shiftxform;
// load the heads-up font j = HU_FONTSTART; for (i=0;i<HU_FONTSIZE;i++) { sprintf(buffer, "STCFN%.3d", j++); hu_font[i] = (patch_t *) W_CacheLumpName(buffer, PU_STATIC); }
}
void HU_Stop(void) { headsupactive = false; }
void HU_Start(void) {
int i; char* s;
if (headsupactive) HU_Stop();
plr = &players[consoleplayer]; message_on = false; message_dontfuckwithme = false; message_nottobefuckedwith = false; chat_on = false;
// create the message widget HUlib_initSText(&w_message, HU_MSGX, HU_MSGY, HU_MSGHEIGHT, hu_font, HU_FONTSTART, &message_on);
// create the map title widget HUlib_initTextLine(&w_title, HU_TITLEX, HU_TITLEY, hu_font, HU_FONTSTART);
switch ( gamemode ) { case shareware: case registered: case retail: s = HU_TITLE; break;
/* FIXME case pack_plut: s = HU_TITLEP; break; case pack_tnt: s = HU_TITLET; break; */ case commercial: default: s = HU_TITLE2; break; }
while (*s) HUlib_addCharToTextLine(&w_title, *(s++));
// create the chat widget HUlib_initIText(&w_chat, HU_INPUTX, HU_INPUTY, hu_font, HU_FONTSTART, &chat_on);
// create the inputbuffer widgets for (i=0 ; i<MAXPLAYERS ; i++) HUlib_initIText(&w_inputbuffer[i], 0, 0, 0, 0, &always_off);
headsupactive = true;
}
void HU_Drawer(void) {
HUlib_drawSText(&w_message); HUlib_drawIText(&w_chat); if (automapactive) HUlib_drawTextLine(&w_title, false);
}
void HU_Erase(void) {
HUlib_eraseSText(&w_message); HUlib_eraseIText(&w_chat); HUlib_eraseTextLine(&w_title);
}
void HU_Ticker(void) {
int i, rc; char c;
// tick down message counter if message is up if (message_counter && !--message_counter) { message_on = false; message_nottobefuckedwith = false; }
if (showMessages || message_dontfuckwithme) {
// display message if necessary if ((plr->message && !message_nottobefuckedwith) || (plr->message && message_dontfuckwithme)) { HUlib_addMessageToSText(&w_message, 0, plr->message); plr->message = 0; message_on = true; message_counter = HU_MSGTIMEOUT; message_nottobefuckedwith = message_dontfuckwithme; message_dontfuckwithme = 0; }
} // else message_on = false;
// check for incoming chat characters if (netgame) { for (i=0 ; i<MAXPLAYERS; i++) { if (!playeringame[i]) continue; if (i != consoleplayer && (c = players[i].cmd.chatchar)) { if (c <= HU_BROADCAST) chat_dest[i] = c; else { if (c >= 'a' && c <= 'z') c = (char) shiftxform[(unsigned char) c]; rc = HUlib_keyInIText(&w_inputbuffer[i], c); if (rc && c == KEY_ENTER) { if (w_inputbuffer[i].l.len && (chat_dest[i] == consoleplayer+1 || chat_dest[i] == HU_BROADCAST)) { HUlib_addMessageToSText(&w_message, player_names[i], w_inputbuffer[i].l.l); message_nottobefuckedwith = true; message_on = true; message_counter = HU_MSGTIMEOUT; if ( gamemode == commercial ) S_StartSound(0, sfx_radio); else S_StartSound(0, sfx_tink); } HUlib_resetIText(&w_inputbuffer[i]); } } players[i].cmd.chatchar = 0; } } }
}
#define QUEUESIZE 128
static char chatchars[QUEUESIZE]; static int head = 0; static int tail = 0;
void HU_queueChatChar(char c) { if (((head + 1) & (QUEUESIZE-1)) == tail) { plr->message = HUSTR_MSGU; } else { chatchars[head] = c; head = (head + 1) & (QUEUESIZE-1); } }
char HU_dequeueChatChar(void) { char c;
if (head != tail) { c = chatchars[tail]; tail = (tail + 1) & (QUEUESIZE-1); } else { c = 0; }
return c; }
boolean HU_Responder(event_t *ev) {
static char lastmessage[HU_MAXLINELENGTH+1]; char* macromessage; boolean eatkey = false; static boolean shiftdown = false; static boolean altdown = false; unsigned char c; int i; int numplayers;
static char destination_keys[MAXPLAYERS] = { HUSTR_KEYGREEN, HUSTR_KEYINDIGO, HUSTR_KEYBROWN, HUSTR_KEYRED };
static int num_nobrainers = 0;
numplayers = 0; for (i=0 ; i<MAXPLAYERS ; i++) numplayers += playeringame[i];
if (ev->data1 == KEY_RSHIFT) { shiftdown = ev->type == ev_keydown; return false; } else if (ev->data1 == KEY_RALT || ev->data1 == KEY_LALT) { altdown = ev->type == ev_keydown; return false; }
if (ev->type != ev_keydown) return false;
if (!chat_on) { if (ev->data1 == HU_MSGREFRESH) { message_on = true; message_counter = HU_MSGTIMEOUT; eatkey = true; } else if (netgame && ev->data1 == HU_INPUTTOGGLE) { eatkey = chat_on = true; HUlib_resetIText(&w_chat); HU_queueChatChar(HU_BROADCAST); } else if (netgame && numplayers > 2) { for (i=0; i<MAXPLAYERS ; i++) { if (ev->data1 == destination_keys[i]) { if (playeringame[i] && i!=consoleplayer) { eatkey = chat_on = true; HUlib_resetIText(&w_chat); HU_queueChatChar(i+1); break; } else if (i == consoleplayer) { num_nobrainers++; if (num_nobrainers < 3) plr->message = HUSTR_TALKTOSELF1; else if (num_nobrainers < 6) plr->message = HUSTR_TALKTOSELF2; else if (num_nobrainers < 9) plr->message = HUSTR_TALKTOSELF3; else if (num_nobrainers < 32) plr->message = HUSTR_TALKTOSELF4; else plr->message = HUSTR_TALKTOSELF5; } } } } } else { c = ev->data1; // send a macro if (altdown) { c = c - '0'; if (c > 9) return false; // fprintf(stderr, "got here\n"); macromessage = chat_macros[c]; // kill last message with a '\n' HU_queueChatChar(KEY_ENTER); // DEBUG!!! // send the macro message while (*macromessage) HU_queueChatChar(*macromessage++); HU_queueChatChar(KEY_ENTER); // leave chat mode and notify that it was sent chat_on = false; strcpy(lastmessage, chat_macros[c]); plr->message = lastmessage; eatkey = true; } else { if (french) c = ForeignTranslation(c); if (shiftdown || (c >= 'a' && c <= 'z')) c = shiftxform[c]; eatkey = HUlib_keyInIText(&w_chat, c); if (eatkey) { // static unsigned char buf[20]; // DEBUG HU_queueChatChar(c); // sprintf(buf, "KEY: %d => %d", ev->data1, c); // plr->message = buf; } if (c == KEY_ENTER) { chat_on = false; if (w_chat.l.len) { strcpy(lastmessage, w_chat.l.l); plr->message = lastmessage; } } else if (c == KEY_ESCAPE) chat_on = false; } }
return eatkey;
} // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: Head up display // //-----------------------------------------------------------------------------
#ifndef __HU_STUFF_H__ #define __HU_STUFF_H__
#include "d_event.h"
// // Globally visible constants. // #define HU_FONTSTART '!' // the first font characters #define HU_FONTEND '_' // the last font characters
// Calculate # of glyphs in font. #define HU_FONTSIZE (HU_FONTEND - HU_FONTSTART + 1)
#define HU_BROADCAST 5
#define HU_MSGREFRESH KEY_ENTER #define HU_MSGX 0 #define HU_MSGY 0 #define HU_MSGWIDTH 64 // in characters #define HU_MSGHEIGHT 1 // in lines
#define HU_MSGTIMEOUT (4*TICRATE)
// // HEADS UP TEXT //
void HU_Init(void); void HU_Start(void);
boolean HU_Responder(event_t* ev);
void HU_Ticker(void); void HU_Drawer(void); char HU_dequeueChatChar(void); void HU_Erase(void);
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // Main program, simply calls D_DoomMain high level loop. // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: i_main.c,v 1.4 1997/02/03 22:45:10 b1 Exp $";
#include "doomdef.h"
#include "m_argv.h" #include "d_main.h"
int main ( int argc, char** argv ) { myargc = argc; myargv = argv;
D_DoomMain ();
return 0; } // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: m_bbox.c,v 1.1 1997/02/03 22:45:10 b1 Exp $";
#include <stdlib.h> #include <string.h> #include <stdio.h>
#include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <errno.h> #include <unistd.h> #include <netdb.h> #include <sys/ioctl.h>
#include "i_system.h" #include "d_event.h" #include "d_net.h" #include "m_argv.h"
#include "doomstat.h"
#ifdef __GNUG__ #pragma implementation "i_net.h" #endif #include "i_net.h"
// For some odd reason... #define ntohl(x) \ ((unsigned long int)((((unsigned long int)(x) & 0x000000ffU) << 24) | \ (((unsigned long int)(x) & 0x0000ff00U) << 8) | \ (((unsigned long int)(x) & 0x00ff0000U) >> 8) | \ (((unsigned long int)(x) & 0xff000000U) >> 24)))
#define ntohs(x) \ ((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \ (((unsigned short int)(x) & 0xff00) >> 8))) \ #define htonl(x) ntohl(x) #define htons(x) ntohs(x)
void NetSend (void); boolean NetListen (void);
// // NETWORKING //
int DOOMPORT = (IPPORT_USERRESERVED +0x1d );
int sendsocket; int insocket;
struct sockaddr_in sendaddress[MAXNETNODES];
void (*netget) (void); void (*netsend) (void);
// // UDPsocket // int UDPsocket (void) { int s; // allocate a socket s = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); if (s<0) I_Error ("can't create socket: %s",strerror(errno)); return s; }
// // BindToLocalPort // void BindToLocalPort ( int s, int port ) { int v; struct sockaddr_in address; memset (&address, 0, sizeof(address)); address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = port; v = bind (s, (void *)&address, sizeof(address)); if (v == -1) I_Error ("BindToPort: bind: %s", strerror(errno)); }
// // PacketSend // void PacketSend (void) { int c; doomdata_t sw; // byte swap sw.checksum = htonl(netbuffer->checksum); sw.player = netbuffer->player; sw.retransmitfrom = netbuffer->retransmitfrom; sw.starttic = netbuffer->starttic; sw.numtics = netbuffer->numtics; for (c=0 ; c< netbuffer->numtics ; c++) { sw.cmds[c].forwardmove = netbuffer->cmds[c].forwardmove; sw.cmds[c].sidemove = netbuffer->cmds[c].sidemove; sw.cmds[c].angleturn = htons(netbuffer->cmds[c].angleturn); sw.cmds[c].consistancy = htons(netbuffer->cmds[c].consistancy); sw.cmds[c].chatchar = netbuffer->cmds[c].chatchar; sw.cmds[c].buttons = netbuffer->cmds[c].buttons; } //printf ("sending %i\n",gametic); c = sendto (sendsocket , &sw, doomcom->datalength ,0,(void *)&sendaddress[doomcom->remotenode] ,sizeof(sendaddress[doomcom->remotenode])); // if (c == -1) // I_Error ("SendPacket error: %s",strerror(errno)); }
// // PacketGet // void PacketGet (void) { int i; int c; struct sockaddr_in fromaddress; int fromlen; doomdata_t sw; fromlen = sizeof(fromaddress); c = recvfrom (insocket, &sw, sizeof(sw), 0 , (struct sockaddr *)&fromaddress, &fromlen ); if (c == -1 ) { if (errno != EWOULDBLOCK) I_Error ("GetPacket: %s",strerror(errno)); doomcom->remotenode = -1; // no packet return; }
{ static int first=1; if (first) printf("len=%d:p=[0x%x 0x%x] \n", c, *(int*)&sw, *((int*)&sw+1)); first = 0; }
// find remote node number for (i=0 ; i<doomcom->numnodes ; i++) if ( fromaddress.sin_addr.s_addr == sendaddress[i].sin_addr.s_addr ) break;
if (i == doomcom->numnodes) { // packet is not from one of the players (new game broadcast) doomcom->remotenode = -1; // no packet return; } doomcom->remotenode = i; // good packet from a game player doomcom->datalength = c; // byte swap netbuffer->checksum = ntohl(sw.checksum); netbuffer->player = sw.player; netbuffer->retransmitfrom = sw.retransmitfrom; netbuffer->starttic = sw.starttic; netbuffer->numtics = sw.numtics;
for (c=0 ; c< netbuffer->numtics ; c++) { netbuffer->cmds[c].forwardmove = sw.cmds[c].forwardmove; netbuffer->cmds[c].sidemove = sw.cmds[c].sidemove; netbuffer->cmds[c].angleturn = ntohs(sw.cmds[c].angleturn); netbuffer->cmds[c].consistancy = ntohs(sw.cmds[c].consistancy); netbuffer->cmds[c].chatchar = sw.cmds[c].chatchar; netbuffer->cmds[c].buttons = sw.cmds[c].buttons; } }
int GetLocalAddress (void) { char hostname[1024]; struct hostent* hostentry; // host information entry int v;
// get local address v = gethostname (hostname, sizeof(hostname)); if (v == -1) I_Error ("GetLocalAddress : gethostname: errno %d",errno); hostentry = gethostbyname (hostname); if (!hostentry) I_Error ("GetLocalAddress : gethostbyname: couldn't get local host"); return *(int *)hostentry->h_addr_list[0]; }
// // I_InitNetwork // void I_InitNetwork (void) { boolean trueval = true; int i; int p; struct hostent* hostentry; // host information entry doomcom = malloc (sizeof (*doomcom) ); memset (doomcom, 0, sizeof(*doomcom) );
// set up for network i = M_CheckParm ("-dup"); if (i && i< myargc-1) { doomcom->ticdup = myargv[i+1][0]-'0'; if (doomcom->ticdup < 1) doomcom->ticdup = 1; if (doomcom->ticdup > 9) doomcom->ticdup = 9; } else doomcom-> ticdup = 1; if (M_CheckParm ("-extratic")) doomcom-> extratics = 1; else doomcom-> extratics = 0; p = M_CheckParm ("-port"); if (p && p<myargc-1) { DOOMPORT = atoi (myargv[p+1]); printf ("using alternate port %i\n",DOOMPORT); }
// parse network game options, // -net <consoleplayer> <host> <host> ... i = M_CheckParm ("-net"); if (!i) { // single player game netgame = false; doomcom->id = DOOMCOM_ID; doomcom->numplayers = doomcom->numnodes = 1; doomcom->deathmatch = false; doomcom->consoleplayer = 0; return; }
netsend = PacketSend; netget = PacketGet; netgame = true;
// parse player number and host list doomcom->consoleplayer = myargv[i+1][0]-'1';
doomcom->numnodes = 1; // this node for sure i++; while (++i < myargc && myargv[i][0] != '-') { sendaddress[doomcom->numnodes].sin_family = AF_INET; sendaddress[doomcom->numnodes].sin_port = htons(DOOMPORT); if (myargv[i][0] == '.') { sendaddress[doomcom->numnodes].sin_addr.s_addr = inet_addr (myargv[i]+1); } else { hostentry = gethostbyname (myargv[i]); if (!hostentry) I_Error ("gethostbyname: couldn't find %s", myargv[i]); sendaddress[doomcom->numnodes].sin_addr.s_addr = *(int *)hostentry->h_addr_list[0]; } doomcom->numnodes++; } doomcom->id = DOOMCOM_ID; doomcom->numplayers = doomcom->numnodes;
// build message to receive insocket = UDPsocket (); BindToLocalPort (insocket,htons(DOOMPORT)); ioctl (insocket, FIONBIO, &trueval);
sendsocket = UDPsocket (); }
void I_NetCmd (void) { if (doomcom->command == CMD_SEND) { netsend (); } else if (doomcom->command == CMD_GET) { netget (); } else I_Error ("Bad net cmd: %i\n",doomcom->command); }
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // System specific network interface stuff. // //-----------------------------------------------------------------------------
#ifndef __I_NET__ #define __I_NET__
#ifdef __GNUG__ #pragma interface #endif
// Called by D_DoomMain.
void I_InitNetwork (void); void I_NetCmd (void);
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // System interface for sound. // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: i_unix.c,v 1.5 1997/02/03 22:45:10 b1 Exp $";
#include <stdio.h> #include <stdlib.h> #include <stdarg.h>
#include <math.h>
#include <sys/time.h> #include <sys/types.h>
#ifndef LINUX #include <sys/filio.h> #endif
#include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h>
// Linux voxware output. #include <linux/soundcard.h>
// Timer stuff. Experimental. #include <time.h> #include <signal.h>
#include "z_zone.h"
#include "i_system.h" #include "i_sound.h" #include "m_argv.h" #include "m_misc.h" #include "w_wad.h"
#include "doomdef.h"
// UNIX hack, to be removed. #ifdef SNDSERV // Separate sound server process. FILE* sndserver=0; char* sndserver_filename = "./sndserver "; #elif SNDINTR
// Update all 30 millisecs, approx. 30fps synchronized. // Linux resolution is allegedly 10 millisecs, // scale is microseconds. #define SOUND_INTERVAL 500
// Get the interrupt. Set duration in millisecs. int I_SoundSetTimer( int duration_of_tick ); void I_SoundDelTimer( void ); #else // None? #endif
// A quick hack to establish a protocol between // synchronous mix buffer updates and asynchronous // audio writes. Probably redundant with gametic. static int flag = 0;
// The number of internal mixing channels, // the samples calculated for each mixing step, // the size of the 16bit, 2 hardware channel (stereo) // mixing buffer, and the samplerate of the raw data.
// Needed for calling the actual sound output. #define SAMPLECOUNT 512 #define NUM_CHANNELS 8 // It is 2 for 16bit, and 2 for two channels. #define BUFMUL 4 #define MIXBUFFERSIZE (SAMPLECOUNT*BUFMUL)
#define SAMPLERATE 11025 // Hz #define SAMPLESIZE 2 // 16bit
// The actual lengths of all sound effects. int lengths[NUMSFX];
// The actual output device. int audio_fd;
// The global mixing buffer. // Basically, samples from all active internal channels // are modifed and added, and stored in the buffer // that is submitted to the audio device. signed short mixbuffer[MIXBUFFERSIZE];
// The channel step amount... unsigned int channelstep[NUM_CHANNELS]; // ... and a 0.16 bit remainder of last step. unsigned int channelstepremainder[NUM_CHANNELS];
// The channel data pointers, start and end. unsigned char* channels[NUM_CHANNELS]; unsigned char* channelsend[NUM_CHANNELS];
// Time/gametic that the channel started playing, // used to determine oldest, which automatically // has lowest priority. // In case number of active sounds exceeds // available channels. int channelstart[NUM_CHANNELS];
// The sound in channel handles, // determined on registration, // might be used to unregister/stop/modify, // currently unused. int channelhandles[NUM_CHANNELS];
// SFX id of the playing sound effect. // Used to catch duplicates (like chainsaw). int channelids[NUM_CHANNELS];
// Pitch to stepping lookup, unused. int steptable[256];
// Volume lookups. int vol_lookup[128*256];
// Hardware left and right channel volume lookup. int* channelleftvol_lookup[NUM_CHANNELS]; int* channelrightvol_lookup[NUM_CHANNELS];
// // Safe ioctl, convenience. // void myioctl ( int fd, int command, int* arg ) { int rc; extern int errno;
rc = ioctl(fd, command, arg); if (rc < 0) { fprintf(stderr, "ioctl(dsp,%d,arg) failed\n", command); fprintf(stderr, "errno=%d\n", errno); exit(-1); } }
// // This function loads the sound data from the WAD lump, // for single sound. // void* getsfx ( char* sfxname, int* len ) { unsigned char* sfx; unsigned char* paddedsfx; int i; int size; int paddedsize; char name[20]; int sfxlump;
// Get the sound data from the WAD, allocate lump // in zone memory. sprintf(name, "ds%s", sfxname);
// Now, there is a severe problem with the // sound handling, in it is not (yet/anymore) // gamemode aware. That means, sounds from // DOOM II will be requested even with DOOM // shareware. // The sound list is wired into sounds.c, // which sets the external variable. // I do not do runtime patches to that // variable. Instead, we will use a // default sound for replacement. if ( W_CheckNumForName(name) == -1 ) sfxlump = W_GetNumForName("dspistol"); else sfxlump = W_GetNumForName(name);
size = W_LumpLength( sfxlump );
// Debug. // fprintf( stderr, "." ); //fprintf( stderr, " -loading %s (lump %d, %d bytes)\n", // sfxname, sfxlump, size ); //fflush( stderr );
sfx = (unsigned char*)W_CacheLumpNum( sfxlump, PU_STATIC );
// Pads the sound effect out to the mixing buffer size. // The original realloc would interfere with zone memory. paddedsize = ((size-8 + (SAMPLECOUNT-1)) / SAMPLECOUNT) * SAMPLECOUNT;
// Allocate from zone memory. paddedsfx = (unsigned char*)Z_Malloc( paddedsize+8, PU_STATIC, 0 ); // ddt: (unsigned char *) realloc(sfx, paddedsize+8); // This should interfere with zone memory handling, // which does not kick in in the soundserver.
// Now copy and pad. memcpy( paddedsfx, sfx, size ); for (i=size ; i<paddedsize+8 ; i++) paddedsfx[i] = 128;
// Remove the cached lump. Z_Free( sfx );
// Preserve padded length. *len = paddedsize;
// Return allocated padded data. return (void *) (paddedsfx + 8); }
// // This function adds a sound to the // list of currently active sounds, // which is maintained as a given number // (eight, usually) of internal channels. // Returns a handle. // int addsfx ( int sfxid, int volume, int step, int seperation ) { static unsigned short handlenums = 0;
int i; int rc = -1;
int oldest = gametic; int oldestnum = 0; int slot;
int rightvol; int leftvol;
// Chainsaw troubles. // Play these sound effects only one at a time. if ( sfxid == sfx_sawup || sfxid == sfx_sawidl || sfxid == sfx_sawful || sfxid == sfx_sawhit || sfxid == sfx_stnmov || sfxid == sfx_pistol ) { // Loop all channels, check. for (i=0 ; i<NUM_CHANNELS ; i++) { // Active, and using the same SFX? if ( (channels[i]) && (channelids[i] == sfxid) ) { // Reset. channels[i] = 0; // We are sure that iff, // there will only be one. break; } } }
// Loop all channels to find oldest SFX. for (i=0; (i<NUM_CHANNELS) && (channels[i]); i++) { if (channelstart[i] < oldest) { oldestnum = i; oldest = channelstart[i]; } }
// Tales from the cryptic. // If we found a channel, fine. // If not, we simply overwrite the first one, 0. // Probably only happens at startup. if (i == NUM_CHANNELS) slot = oldestnum; else slot = i;
// Okay, in the less recent channel, // we will handle the new SFX. // Set pointer to raw data. channels[slot] = (unsigned char *) S_sfx[sfxid].data; // Set pointer to end of raw data. channelsend[slot] = channels[slot] + lengths[sfxid];
// Reset current handle number, limited to 0..100. if (!handlenums) handlenums = 100;
// Assign current handle number. // Preserved so sounds could be stopped (unused). channelhandles[slot] = rc = handlenums++;
// Set stepping??? // Kinda getting the impression this is never used. channelstep[slot] = step; // ??? channelstepremainder[slot] = 0; // Should be gametic, I presume. channelstart[slot] = gametic;
// Separation, that is, orientation/stereo. // range is: 1 - 256 seperation += 1;
// Per left/right channel. // x^2 seperation, // adjust volume properly. leftvol = volume - ((volume*seperation*seperation) >> 16); ///(256*256); seperation = seperation - 257; rightvol = volume - ((volume*seperation*seperation) >> 16);
// Sanity check, clamp volume. if (rightvol < 0 || rightvol > 127) I_Error("rightvol out of bounds");
if (leftvol < 0 || leftvol > 127) I_Error("leftvol out of bounds");
// Get the proper lookup table piece // for this volume level??? channelleftvol_lookup[slot] = &vol_lookup[leftvol*256]; channelrightvol_lookup[slot] = &vol_lookup[rightvol*256];
// Preserve sound SFX id, // e.g. for avoiding duplicates of chainsaw. channelids[slot] = sfxid;
// You tell me. return rc; }
// // SFX API // Note: this was called by S_Init. // However, whatever they did in the // old DPMS based DOS version, this // were simply dummies in the Linux // version. // See soundserver initdata(). // void I_SetChannels() { // Init internal lookups (raw data, mixing buffer, channels). // This function sets up internal lookups used during // the mixing process. int i; int j;
int* steptablemid = steptable + 128;
// Okay, reset internal mixing channels to zero. /*for (i=0; i<NUM_CHANNELS; i++) { channels[i] = 0; }*/
// This table provides step widths for pitch parameters. // I fail to see that this is currently used. for (i=-128 ; i<128 ; i++) steptablemid[i] = (int)(pow(2.0, (i/64.0))*65536.0);
// Generates volume lookup tables // which also turn the unsigned samples // into signed samples. for (i=0 ; i<128 ; i++) for (j=0 ; j<256 ; j++) vol_lookup[i*256+j] = (i*(j-128)*256)/127; }
void I_SetSfxVolume(int volume) { // Identical to DOS. // Basically, this should propagate // the menu/config file setting // to the state variable used in // the mixing. snd_SfxVolume = volume; }
// MUSIC API - dummy. Some code from DOS version. void I_SetMusicVolume(int volume) { // Internal state variable. snd_MusicVolume = volume; // Now set volume on output device. // Whatever( snd_MusciVolume ); }
// // Retrieve the raw data lump index // for a given SFX name. // int I_GetSfxLumpNum(sfxinfo_t* sfx) { char namebuf[9]; sprintf(namebuf, "ds%s", sfx->name); return W_GetNumForName(namebuf); }
// // Starting a sound means adding it // to the current list of active sounds // in the internal channels. // As the SFX info struct contains // e.g. a pointer to the raw data, // it is ignored. // As our sound handling does not handle // priority, it is ignored. // Pitching (that is, increased speed of playback) // is set, but currently not used by mixing. // int I_StartSound ( int id, int vol, int sep, int pitch, int priority ) {
// UNUSED priority = 0;
#ifdef SNDSERV if (sndserver) { fprintf(sndserver, "p%2.2x%2.2x%2.2x%2.2x\n", id, pitch, vol, sep); fflush(sndserver); } // warning: control reaches end of non-void function. return id; #else // Debug. //fprintf( stderr, "starting sound %d", id );
// Returns a handle (not used). id = addsfx( id, vol, steptable[pitch], sep );
// fprintf( stderr, "/handle is %d\n", id );
return id; #endif }
void I_StopSound (int handle) { // You need the handle returned by StartSound. // Would be looping all channels, // tracking down the handle, // an setting the channel to zero.
// UNUSED. handle = 0; }
int I_SoundIsPlaying(int handle) { // Ouch. return gametic < handle; }
// // This function loops all active (internal) sound // channels, retrieves a given number of samples // from the raw sound data, modifies it according // to the current (internal) channel parameters, // mixes the per channel samples into the global // mixbuffer, clamping it to the allowed range, // and sets up everything for transferring the // contents of the mixbuffer to the (two) // hardware channels (left and right, that is). // // This function currently supports only 16bit. // void I_UpdateSound( void ) { #ifdef SNDINTR // Debug. Count buffer misses with interrupt. static int misses = 0; #endif
// Mix current sound data. // Data, from raw sound, for right and left. register unsigned int sample; register int dl; register int dr;
// Pointers in global mixbuffer, left, right, end. signed short* leftout; signed short* rightout; signed short* leftend; // Step in mixbuffer, left and right, thus two. int step;
// Mixing channel index. int chan;
// Left and right channel // are in global mixbuffer, alternating. leftout = mixbuffer; rightout = mixbuffer+1; step = 2;
// Determine end, for left channel only // (right channel is implicit). leftend = mixbuffer + SAMPLECOUNT*step;
// Mix sounds into the mixing buffer. // Loop over step*SAMPLECOUNT, // that is 512 values for two channels. while (leftout != leftend) { // Reset left/right value. dl = 0; dr = 0;
// Love thy L2 chache - made this a loop. // Now more channels could be set at compile time // as well. Thus loop those channels. for ( chan = 0; chan < NUM_CHANNELS; chan++ ) { // Check channel, if active. if (channels[ chan ]) { // Get the raw data from the channel. sample = *channels[ chan ]; // Add left and right part // for this channel (sound) // to the current data. // Adjust volume accordingly. dl += channelleftvol_lookup[ chan ][sample]; dr += channelrightvol_lookup[ chan ][sample]; // Increment index ??? channelstepremainder[ chan ] += channelstep[ chan ]; // MSB is next sample??? channels[ chan ] += channelstepremainder[ chan ] >> 16; // Limit to LSB??? channelstepremainder[ chan ] &= 65536-1;
// Check whether we are done. if (channels[ chan ] >= channelsend[ chan ]) channels[ chan ] = 0; } } // Clamp to range. Left hardware channel. // Has been char instead of short. // if (dl > 127) *leftout = 127; // else if (dl < -128) *leftout = -128; // else *leftout = dl;
if (dl > 0x7fff) *leftout = 0x7fff; else if (dl < -0x8000) *leftout = -0x8000; else *leftout = dl;
// Same for right hardware channel. if (dr > 0x7fff) *rightout = 0x7fff; else if (dr < -0x8000) *rightout = -0x8000; else *rightout = dr;
// Increment current pointers in mixbuffer. leftout += step; rightout += step; }
#ifdef SNDINTR // Debug check. if ( flag ) { misses += flag; flag = 0; }
if ( misses > 10 ) { fprintf( stderr, "I_SoundUpdate: missed 10 buffer writes\n"); misses = 0; }
// Increment flag for update. flag++; #endif }
// // This would be used to write out the mixbuffer // during each game loop update. // Updates sound buffer and audio device at runtime. // It is called during Timer interrupt with SNDINTR. // Mixing now done synchronous, and // only output be done asynchronous? // void I_SubmitSound(void) { // Write it to DSP device. write(audio_fd, mixbuffer, SAMPLECOUNT*BUFMUL); }
void I_UpdateSoundParams ( int handle, int vol, int sep, int pitch) { // I fail too see that this is used. // Would be using the handle to identify // on which channel the sound might be active, // and resetting the channel parameters.
// UNUSED. handle = vol = sep = pitch = 0; }
void I_ShutdownSound(void) { #ifdef SNDSERV if (sndserver) { // Send a "quit" command. fprintf(sndserver, "q\n"); fflush(sndserver); } #else // Wait till all pending sounds are finished. int done = 0; int i;
// FIXME (below). fprintf( stderr, "I_ShutdownSound: NOT finishing pending sounds\n"); fflush( stderr );
while ( !done ) { for( i=0 ; i<8 && !channels[i] ; i++);
// FIXME. No proper channel output. //if (i==8) done=1; } #ifdef SNDINTR I_SoundDelTimer(); #endif
// Cleaning up -releasing the DSP device. close ( audio_fd ); #endif
// Done. return; }
void I_InitSound() { #ifdef SNDSERV char buffer[256];
if (getenv("DOOMWADDIR")) sprintf(buffer, "%s/%s", getenv("DOOMWADDIR"), sndserver_filename); else sprintf(buffer, "%s", sndserver_filename);
// start sound process if ( !access(buffer, X_OK) ) { strcat(buffer, " -quiet"); sndserver = popen(buffer, "w"); } else fprintf(stderr, "Could not start sound server [%s]\n", buffer); #else
int i;
#ifdef SNDINTR fprintf( stderr, "I_SoundSetTimer: %d microsecs\n", SOUND_INTERVAL ); I_SoundSetTimer( SOUND_INTERVAL ); #endif
// Secure and configure sound device first. fprintf( stderr, "I_InitSound: ");
audio_fd = open("/dev/dsp", O_WRONLY); if (audio_fd<0) fprintf(stderr, "Could not open /dev/dsp\n");
i = 11 | (2<<16); myioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &i); myioctl(audio_fd, SNDCTL_DSP_RESET, 0);
i=SAMPLERATE;
myioctl(audio_fd, SNDCTL_DSP_SPEED, &i);
i=1; myioctl(audio_fd, SNDCTL_DSP_STEREO, &i);
myioctl(audio_fd, SNDCTL_DSP_GETFMTS, &i);
if (i&=AFMT_S16_LE) myioctl(audio_fd, SNDCTL_DSP_SETFMT, &i); else fprintf(stderr, "Could not play signed 16 data\n");
fprintf(stderr, " configured audio device\n" );
// Initialize external data (all sounds) at start, keep static. fprintf( stderr, "I_InitSound: ");
for (i=1 ; i<NUMSFX ; i++) { // Alias? Example is the chaingun sound linked to pistol. if (!S_sfx[i].link) { // Load data from WAD file. S_sfx[i].data = getsfx( S_sfx[i].name, &lengths[i] ); } else { // Previously loaded already? S_sfx[i].data = S_sfx[i].link->data; lengths[i] = lengths[(S_sfx[i].link - S_sfx)/sizeof(sfxinfo_t)]; } }
fprintf( stderr, " pre-cached all sound data\n");
// Now initialize mixbuffer with zero. for ( i = 0; i< MIXBUFFERSIZE; i++ ) mixbuffer[i] = 0;
// Finished initialization. fprintf(stderr, "I_InitSound: sound module ready\n");
#endif }
// // MUSIC API. // Still no music done. // Remains. Dummies. // void I_InitMusic(void) { } void I_ShutdownMusic(void) { }
static int looping=0; static int musicdies=-1;
void I_PlaySong(int handle, int looping) { // UNUSED. handle = looping = 0; musicdies = gametic + TICRATE*30; }
void I_PauseSong (int handle) { // UNUSED. handle = 0; }
void I_ResumeSong (int handle) { // UNUSED. handle = 0; }
void I_StopSong(int handle) { // UNUSED. handle = 0;
looping = 0; musicdies = 0; }
void I_UnRegisterSong(int handle) { // UNUSED. handle = 0; }
int I_RegisterSong(void* data) { // UNUSED. data = NULL;
return 1; }
// Is the song playing? int I_QrySongPlaying(int handle) { // UNUSED. handle = 0; return looping || musicdies > gametic; }
// // Experimental stuff. // A Linux timer interrupt, for asynchronous // sound output. // I ripped this out of the Timer class in // our Difference Engine, including a few // SUN remains... // #ifdef sun typedef sigset_t tSigSet; #else typedef int tSigSet; #endif
// We might use SIGVTALRM and ITIMER_VIRTUAL, if the process // time independend timer happens to get lost due to heavy load. // SIGALRM and ITIMER_REAL doesn't really work well. // There are issues with profiling as well. static int /*__itimer_which*/ itimer = ITIMER_REAL;
static int sig = SIGALRM;
// Interrupt handler. void I_HandleSoundTimer( int ignore ) { // Debug. //fprintf( stderr, "%c", '+' ); fflush( stderr );
// Feed sound device if necesary. if ( flag ) { // See I_SubmitSound(). // Write it to DSP device. write(audio_fd, mixbuffer, SAMPLECOUNT*BUFMUL);
// Reset flag counter. flag = 0; } else return;
// UNUSED, but required. ignore = 0; return; }
// Get the interrupt. Set duration in millisecs. int I_SoundSetTimer( int duration_of_tick ) { // Needed for gametick clockwork. struct itimerval value; struct itimerval ovalue; struct sigaction act; struct sigaction oact;
int res;
// This sets to SA_ONESHOT and SA_NOMASK, thus we can not use it. // signal( _sig, handle_SIG_TICK );
// Now we have to change this attribute for repeated calls. act.sa_handler = I_HandleSoundTimer; #ifndef sun //ac t.sa_mask = _sig; #endif act.sa_flags = SA_RESTART;
sigaction( sig, &act, &oact );
value.it_interval.tv_sec = 0; value.it_interval.tv_usec = duration_of_tick; value.it_value.tv_sec = 0; value.it_value.tv_usec = duration_of_tick;
// Error is -1. res = setitimer( itimer, &value, &ovalue );
// Debug. if ( res == -1 ) fprintf( stderr, "I_SoundSetTimer: interrupt n.a.\n");
return res; }
// Remove the interrupt. Set duration to zero. void I_SoundDelTimer() { // Debug. if ( I_SoundSetTimer( 0 ) == -1) fprintf( stderr, "I_SoundDelTimer: failed to remove interrupt. Doh!\n"); } // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // // DESCRIPTION: // System interface, sound. // //-----------------------------------------------------------------------------
#ifndef __I_SOUND__ #define __I_SOUND__
#include "doomdef.h"
// UNIX hack, to be removed. #ifdef SNDSERV #include <stdio.h> extern FILE* sndserver; extern char* sndserver_filename; #endif
#include "doomstat.h" #include "sounds.h"
// Init at program start... void I_InitSound();
// ... update sound buffer and audio device at runtime... void I_UpdateSound(void); void I_SubmitSound(void);
// ... shut down and relase at program termination. void I_ShutdownSound(void);
// // SFX I/O //
// Initialize channels? void I_SetChannels();
// Get raw data lump index for sound descriptor. int I_GetSfxLumpNum (sfxinfo_t* sfxinfo );
// Starts a sound in a particular sound channel. int I_StartSound ( int id, int vol, int sep, int pitch, int priority );
// Stops a sound channel. void I_StopSound(int handle);
// Called by S_*() functions // to see if a channel is still playing. // Returns 0 if no longer playing, 1 if playing. int I_SoundIsPlaying(int handle);
// Updates the volume, separation, // and pitch of a sound channel. void I_UpdateSoundParams ( int handle, int vol, int sep, int pitch );
// // MUSIC I/O // void I_InitMusic(void); void I_ShutdownMusic(void); // Volume. void I_SetMusicVolume(int volume); // PAUSE game handling. void I_PauseSong(int handle); void I_ResumeSong(int handle); // Registers a song handle to song data. int I_RegisterSong(void *data); // Called by anything that wishes to start music. // plays a song, and when the song is done, // starts playing it again in an endless loop. // Horrible thing to do, considering. void I_PlaySong ( int handle, int looping ); // Stops a song over 3 seconds. void I_StopSong(int handle); // See above (register), then think backwards void I_UnRegisterSong(int handle);
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: m_bbox.c,v 1.1 1997/02/03 22:45:10 b1 Exp $";
#include <stdlib.h> #include <stdio.h> #include <string.h>
#include <stdarg.h> #include <sys/time.h> #include <unistd.h>
#include "doomdef.h" #include "m_misc.h" #include "i_video.h" #include "i_sound.h"
#include "d_net.h" #include "g_game.h"
#ifdef __GNUG__ #pragma implementation "i_system.h" #endif #include "i_system.h"
int mb_used = 6;
void I_Tactile ( int on, int off, int total ) { // UNUSED. on = off = total = 0; }
ticcmd_t emptycmd; ticcmd_t* I_BaseTiccmd(void) { return &emptycmd; }
int I_GetHeapSize (void) { return mb_used*1024*1024; }
byte* I_ZoneBase (int* size) { *size = mb_used*1024*1024; return (byte *) malloc (*size); }
// // I_GetTime // returns time in 1/70th second tics // int I_GetTime (void) { struct timeval tp; struct timezone tzp; int newtics; static int basetime=0;
gettimeofday(&tp, &tzp); if (!basetime) basetime = tp.tv_sec; newtics = (tp.tv_sec-basetime)*TICRATE + tp.tv_usec*TICRATE/1000000; return newtics; }
// // I_Init // void I_Init (void) { I_InitSound(); // I_InitGraphics(); }
// // I_Quit // void I_Quit (void) { D_QuitNetGame (); I_ShutdownSound(); I_ShutdownMusic(); M_SaveDefaults (); I_ShutdownGraphics(); exit(0); }
void I_WaitVBL(int count) { #ifdef SGI sginap(1); #else #ifdef SUN sleep(0); #else usleep (count * (1000000/70) ); #endif #endif }
void I_BeginRead(void) { }
void I_EndRead(void) { }
byte* I_AllocLow(int length) { byte* mem;
mem = (byte *)malloc (length); memset (mem,0,length); return mem; }
// // I_Error // extern boolean demorecording;
void I_Error (char *error, ...) { va_list argptr;
// Message first. va_start (argptr,error); fprintf (stderr, "Error: "); vfprintf (stderr,error,argptr); fprintf (stderr, "\n"); va_end (argptr);
fflush( stderr );
// Shutdown. Here might be other errors. if (demorecording) G_CheckDemoStatus();
D_QuitNetGame (); I_ShutdownGraphics();
exit(-1); } // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // System specific interface stuff. // //-----------------------------------------------------------------------------
#ifndef __I_SYSTEM__ #define __I_SYSTEM__
#include "d_ticcmd.h" #include "d_event.h"
#ifdef __GNUG__ #pragma interface #endif
// Called by DoomMain. void I_Init (void);
// Called by startup code // to get the ammount of memory to malloc // for the zone management. byte* I_ZoneBase (int *size);
// Called by D_DoomLoop, // returns current time in tics. int I_GetTime (void);
// // Called by D_DoomLoop, // called before processing any tics in a frame // (just after displaying a frame). // Time consuming syncronous operations // are performed here (joystick reading). // Can call D_PostEvent. // void I_StartFrame (void);
// // Called by D_DoomLoop, // called before processing each tic in a frame. // Quick syncronous operations are performed here. // Can call D_PostEvent. void I_StartTic (void);
// Asynchronous interrupt functions should maintain private queues // that are read by the synchronous functions // to be converted into events.
// Either returns a null ticcmd, // or calls a loadable driver to build it. // This ticcmd will then be modified by the gameloop // for normal input. ticcmd_t* I_BaseTiccmd (void);
// Called by M_Responder when quit is selected. // Clean exit, displays sell blurb. void I_Quit (void);
// Allocates from low memory under dos, // just mallocs under unix byte* I_AllocLow (int length);
void I_Tactile (int on, int off, int total);
void I_Error (char *error, ...);
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // DOOM graphics stuff for X11, UNIX. // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: i_x.c,v 1.6 1997/02/03 22:45:10 b1 Exp $";
#include <stdlib.h> #include <unistd.h> #include <sys/ipc.h> #include <sys/shm.h>
#include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/keysym.h>
#include <X11/extensions/XShm.h> // Had to dig up XShm.c for this one. // It is in the libXext, but not in the XFree86 headers. #ifdef LINUX int XShmGetEventBase( Display* dpy ); // problems with g++? #endif
#include <stdarg.h> #include <sys/time.h> #include <sys/types.h> #include <sys/socket.h>
#include <netinet/in.h> #include <errnos.h> #include <signal.h>
#include "doomstat.h" #include "i_system.h" #include "v_video.h" #include "m_argv.h" #include "d_main.h"
#include "doomdef.h"
#define POINTER_WARP_COUNTDOWN 1
Display* X_display=0; Window X_mainWindow; Colormap X_cmap; Visual* X_visual; GC X_gc; XEvent X_event; int X_screen; XVisualInfo X_visualinfo; XImage* image; int X_width; int X_height;
// MIT SHared Memory extension. boolean doShm;
XShmSegmentInfo X_shminfo; int X_shmeventtype;
// Fake mouse handling. // This cannot work properly w/o DGA. // Needs an invisible mouse cursor at least. boolean grabMouse; int doPointerWarp = POINTER_WARP_COUNTDOWN;
// Blocky mode, // replace each 320x200 pixel with multiply*multiply pixels. // According to Dave Taylor, it still is a bonehead thing // to use .... static int multiply=1;
// // Translates the key currently in X_event //
int xlatekey(void) {
int rc;
switch(rc = XKeycodeToKeysym(X_display, X_event.xkey.keycode, 0)) { case XK_Left: rc = KEY_LEFTARROW; break; case XK_Right: rc = KEY_RIGHTARROW; break; case XK_Down: rc = KEY_DOWNARROW; break; case XK_Up: rc = KEY_UPARROW; break; case XK_Escape: rc = KEY_ESCAPE; break; case XK_Return: rc = KEY_ENTER; break; case XK_Tab: rc = KEY_TAB; break; case XK_F1: rc = KEY_F1; break; case XK_F2: rc = KEY_F2; break; case XK_F3: rc = KEY_F3; break; case XK_F4: rc = KEY_F4; break; case XK_F5: rc = KEY_F5; break; case XK_F6: rc = KEY_F6; break; case XK_F7: rc = KEY_F7; break; case XK_F8: rc = KEY_F8; break; case XK_F9: rc = KEY_F9; break; case XK_F10: rc = KEY_F10; break; case XK_F11: rc = KEY_F11; break; case XK_F12: rc = KEY_F12; break; case XK_BackSpace: case XK_Delete: rc = KEY_BACKSPACE; break;
case XK_Pause: rc = KEY_PAUSE; break;
case XK_KP_Equal: case XK_equal: rc = KEY_EQUALS; break;
case XK_KP_Subtract: case XK_minus: rc = KEY_MINUS; break;
case XK_Shift_L: case XK_Shift_R: rc = KEY_RSHIFT; break; case XK_Control_L: case XK_Control_R: rc = KEY_RCTRL; break; case XK_Alt_L: case XK_Meta_L: case XK_Alt_R: case XK_Meta_R: rc = KEY_RALT; break; default: if (rc >= XK_space && rc <= XK_asciitilde) rc = rc - XK_space + ' '; if (rc >= 'A' && rc <= 'Z') rc = rc - 'A' + 'a'; break; }
return rc;
}
void I_ShutdownGraphics(void) { // Detach from X server if (!XShmDetach(X_display, &X_shminfo)) I_Error("XShmDetach() failed in I_ShutdownGraphics()");
// Release shared memory. shmdt(X_shminfo.shmaddr); shmctl(X_shminfo.shmid, IPC_RMID, 0);
// Paranoia. image->data = NULL; }
// // I_StartFrame // void I_StartFrame (void) { // er?
}
static int lastmousex = 0; static int lastmousey = 0; boolean mousemoved = false; boolean shmFinished;
void I_GetEvent(void) {
event_t event;
// put event-grabbing stuff in here XNextEvent(X_display, &X_event); switch (X_event.type) { case KeyPress: event.type = ev_keydown; event.data1 = xlatekey(); D_PostEvent(&event); // fprintf(stderr, "k"); break; case KeyRelease: event.type = ev_keyup; event.data1 = xlatekey(); D_PostEvent(&event); // fprintf(stderr, "ku"); break; case ButtonPress: event.type = ev_mouse; event.data1 = (X_event.xbutton.state & Button1Mask) | (X_event.xbutton.state & Button2Mask ? 2 : 0) | (X_event.xbutton.state & Button3Mask ? 4 : 0) | (X_event.xbutton.button == Button1) | (X_event.xbutton.button == Button2 ? 2 : 0) | (X_event.xbutton.button == Button3 ? 4 : 0); event.data2 = event.data3 = 0; D_PostEvent(&event); // fprintf(stderr, "b"); break; case ButtonRelease: event.type = ev_mouse; event.data1 = (X_event.xbutton.state & Button1Mask) | (X_event.xbutton.state & Button2Mask ? 2 : 0) | (X_event.xbutton.state & Button3Mask ? 4 : 0); // suggest parentheses around arithmetic in operand of | event.data1 = event.data1 ^ (X_event.xbutton.button == Button1 ? 1 : 0) ^ (X_event.xbutton.button == Button2 ? 2 : 0) ^ (X_event.xbutton.button == Button3 ? 4 : 0); event.data2 = event.data3 = 0; D_PostEvent(&event); // fprintf(stderr, "bu"); break; case MotionNotify: event.type = ev_mouse; event.data1 = (X_event.xmotion.state & Button1Mask) | (X_event.xmotion.state & Button2Mask ? 2 : 0) | (X_event.xmotion.state & Button3Mask ? 4 : 0); event.data2 = (X_event.xmotion.x - lastmousex) << 2; event.data3 = (lastmousey - X_event.xmotion.y) << 2;
if (event.data2 || event.data3) { lastmousex = X_event.xmotion.x; lastmousey = X_event.xmotion.y; if (X_event.xmotion.x != X_width/2 && X_event.xmotion.y != X_height/2) { D_PostEvent(&event); // fprintf(stderr, "m"); mousemoved = false; } else { mousemoved = true; } } break; case Expose: case ConfigureNotify: break; default: if (doShm && X_event.type == X_shmeventtype) shmFinished = true; break; }
}
Cursor createnullcursor ( Display* display, Window root ) { Pixmap cursormask; XGCValues xgc; GC gc; XColor dummycolour; Cursor cursor;
cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/); xgc.function = GXclear; gc = XCreateGC(display, cursormask, GCFunction, &xgc); XFillRectangle(display, cursormask, gc, 0, 0, 1, 1); dummycolour.pixel = 0; dummycolour.red = 0; dummycolour.flags = 04; cursor = XCreatePixmapCursor(display, cursormask, cursormask, &dummycolour,&dummycolour, 0,0); XFreePixmap(display,cursormask); XFreeGC(display,gc); return cursor; }
// // I_StartTic // void I_StartTic (void) {
if (!X_display) return;
while (XPending(X_display)) I_GetEvent();
// Warp the pointer back to the middle of the window // or it will wander off - that is, the game will // loose input focus within X11. if (grabMouse) { if (!--doPointerWarp) { XWarpPointer( X_display, None, X_mainWindow, 0, 0, 0, 0, X_width/2, X_height/2);
doPointerWarp = POINTER_WARP_COUNTDOWN; } }
mousemoved = false;
}
// // I_UpdateNoBlit // void I_UpdateNoBlit (void) { // what is this? }
// // I_FinishUpdate // void I_FinishUpdate (void) {
static int lasttic; int tics; int i; // UNUSED static unsigned char *bigscreen=0;
// draws little dots on the bottom of the screen if (devparm) {
i = I_GetTime(); tics = i - lasttic; lasttic = i; if (tics > 20) tics = 20;
for (i=0 ; i<tics*2 ; i+=2) screens[0][ (SCREENHEIGHT-1)*SCREENWIDTH + i] = 0xff; for ( ; i<20*2 ; i+=2) screens[0][ (SCREENHEIGHT-1)*SCREENWIDTH + i] = 0x0;
}
// scales the screen size before blitting it if (multiply == 2) { unsigned int *olineptrs[2]; unsigned int *ilineptr; int x, y, i; unsigned int twoopixels; unsigned int twomoreopixels; unsigned int fouripixels;
ilineptr = (unsigned int *) (screens[0]); for (i=0 ; i<2 ; i++) olineptrs[i] = (unsigned int *) &image->data[i*X_width];
y = SCREENHEIGHT; while (y--) { x = SCREENWIDTH; do { fouripixels = *ilineptr++; twoopixels = (fouripixels & 0xff000000) | ((fouripixels>>8) & 0xffff00) | ((fouripixels>>16) & 0xff); twomoreopixels = ((fouripixels<<16) & 0xff000000) | ((fouripixels<<8) & 0xffff00) | (fouripixels & 0xff); #ifdef __BIG_ENDIAN__ *olineptrs[0]++ = twoopixels; *olineptrs[1]++ = twoopixels; *olineptrs[0]++ = twomoreopixels; *olineptrs[1]++ = twomoreopixels; #else *olineptrs[0]++ = twomoreopixels; *olineptrs[1]++ = twomoreopixels; *olineptrs[0]++ = twoopixels; *olineptrs[1]++ = twoopixels; #endif } while (x-=4); olineptrs[0] += X_width/4; olineptrs[1] += X_width/4; }
} else if (multiply == 3) { unsigned int *olineptrs[3]; unsigned int *ilineptr; int x, y, i; unsigned int fouropixels[3]; unsigned int fouripixels;
ilineptr = (unsigned int *) (screens[0]); for (i=0 ; i<3 ; i++) olineptrs[i] = (unsigned int *) &image->data[i*X_width];
y = SCREENHEIGHT; while (y--) { x = SCREENWIDTH; do { fouripixels = *ilineptr++; fouropixels[0] = (fouripixels & 0xff000000) | ((fouripixels>>8) & 0xff0000) | ((fouripixels>>16) & 0xffff); fouropixels[1] = ((fouripixels<<8) & 0xff000000) | (fouripixels & 0xffff00) | ((fouripixels>>8) & 0xff); fouropixels[2] = ((fouripixels<<16) & 0xffff0000) | ((fouripixels<<8) & 0xff00) | (fouripixels & 0xff); #ifdef __BIG_ENDIAN__ *olineptrs[0]++ = fouropixels[0]; *olineptrs[1]++ = fouropixels[0]; *olineptrs[2]++ = fouropixels[0]; *olineptrs[0]++ = fouropixels[1]; *olineptrs[1]++ = fouropixels[1]; *olineptrs[2]++ = fouropixels[1]; *olineptrs[0]++ = fouropixels[2]; *olineptrs[1]++ = fouropixels[2]; *olineptrs[2]++ = fouropixels[2]; #else *olineptrs[0]++ = fouropixels[2]; *olineptrs[1]++ = fouropixels[2]; *olineptrs[2]++ = fouropixels[2]; *olineptrs[0]++ = fouropixels[1]; *olineptrs[1]++ = fouropixels[1]; *olineptrs[2]++ = fouropixels[1]; *olineptrs[0]++ = fouropixels[0]; *olineptrs[1]++ = fouropixels[0]; *olineptrs[2]++ = fouropixels[0]; #endif } while (x-=4); olineptrs[0] += 2*X_width/4; olineptrs[1] += 2*X_width/4; olineptrs[2] += 2*X_width/4; }
} else if (multiply == 4) { // Broken. Gotta fix this some day. void Expand4(unsigned *, double *); Expand4 ((unsigned *)(screens[0]), (double *) (image->data)); }
if (doShm) {
if (!XShmPutImage( X_display, X_mainWindow, X_gc, image, 0, 0, 0, 0, X_width, X_height, True )) I_Error("XShmPutImage() failed\n");
// wait for it to finish and processes all input events shmFinished = false; do { I_GetEvent(); } while (!shmFinished);
} else {
// draw the image XPutImage( X_display, X_mainWindow, X_gc, image, 0, 0, 0, 0, X_width, X_height );
// sync up with server XSync(X_display, False);
}
}
// // I_ReadScreen // void I_ReadScreen (byte* scr) { memcpy (scr, screens[0], SCREENWIDTH*SCREENHEIGHT); }
// // Palette stuff. // static XColor colors[256];
void UploadNewPalette(Colormap cmap, byte *palette) {
register int i; register int c; static boolean firstcall = true;
#ifdef __cplusplus if (X_visualinfo.c_class == PseudoColor && X_visualinfo.depth == 8) #else if (X_visualinfo.class == PseudoColor && X_visualinfo.depth == 8) #endif { // initialize the colormap if (firstcall) { firstcall = false; for (i=0 ; i<256 ; i++) { colors[i].pixel = i; colors[i].flags = DoRed|DoGreen|DoBlue; } }
// set the X colormap entries for (i=0 ; i<256 ; i++) { c = gammatable[usegamma][*palette++]; colors[i].red = (c<<8) + c; c = gammatable[usegamma][*palette++]; colors[i].green = (c<<8) + c; c = gammatable[usegamma][*palette++]; colors[i].blue = (c<<8) + c; }
// store the colors to the current colormap XStoreColors(X_display, cmap, colors, 256);
} }
// // I_SetPalette // void I_SetPalette (byte* palette) { UploadNewPalette(X_cmap, palette); }
// // This function is probably redundant, // if XShmDetach works properly. // ddt never detached the XShm memory, // thus there might have been stale // handles accumulating. // void grabsharedmemory(int size) {
int key = ('d'<<24) | ('o'<<16) | ('o'<<8) | 'm'; struct shmid_ds shminfo; int minsize = 320*200; int id; int rc; // UNUSED int done=0; int pollution=5;
// try to use what was here before do { id = shmget((key_t) key, minsize, 0777); // just get the id if (id != -1) { rc=shmctl(id, IPC_STAT, &shminfo); // get stats on it if (!rc) { if (shminfo.shm_nattch) { fprintf(stderr, "User %d appears to be running " "DOOM. Is that wise?\n", shminfo.shm_cpid); key++; } else { if (getuid() == shminfo.shm_perm.cuid) { rc = shmctl(id, IPC_RMID, 0); if (!rc) fprintf(stderr, "Was able to kill my old shared memory\n"); else I_Error("Was NOT able to kill my old shared memory"); id = shmget((key_t)key, size, IPC_CREAT|0777); if (id==-1) I_Error("Could not get shared memory"); rc=shmctl(id, IPC_STAT, &shminfo); break; } if (size >= shminfo.shm_segsz) { fprintf(stderr, "will use %d's stale shared memory\n", shminfo.shm_cpid); break; } else { fprintf(stderr, "warning: can't use stale " "shared memory belonging to id %d, " "key=0x%x\n", shminfo.shm_cpid, key); key++; } } } else { I_Error("could not get stats on key=%d", key); } } else { id = shmget((key_t)key, size, IPC_CREAT|0777); if (id==-1) { extern int errno; fprintf(stderr, "errno=%d\n", errno); I_Error("Could not get any shared memory"); } break; } } while (--pollution);
if (!pollution) { I_Error("Sorry, system too polluted with stale " "shared memory segments.\n"); }
X_shminfo.shmid = id;
// attach to the shared memory segment image->data = X_shminfo.shmaddr = shmat(id, 0, 0);
fprintf(stderr, "shared memory id=%d, addr=0x%x\n", id, (int) (image->data)); }
void I_InitGraphics(void) {
char* displayname; char* d; int n; int pnum; int x=0; int y=0;
// warning: char format, different type arg char xsign=' '; char ysign=' ';
int oktodraw; unsigned long attribmask; XSetWindowAttributes attribs; XGCValues xgcvalues; int valuemask; static int firsttime=1;
if (!firsttime) return; firsttime = 0;
signal(SIGINT, (void (*)(int)) I_Quit);
if (M_CheckParm("-2")) multiply = 2;
if (M_CheckParm("-3")) multiply = 3;
if (M_CheckParm("-4")) multiply = 4;
X_width = SCREENWIDTH * multiply; X_height = SCREENHEIGHT * multiply;
// check for command-line display name if ( (pnum=M_CheckParm("-disp")) ) // suggest parentheses around assignment displayname = myargv[pnum+1]; else displayname = 0;
// check if the user wants to grab the mouse (quite unnice) grabMouse = !!M_CheckParm("-grabmouse");
// check for command-line geometry if ( (pnum=M_CheckParm("-geom")) ) // suggest parentheses around assignment { // warning: char format, different type arg 3,5 n = sscanf(myargv[pnum+1], "%c%d%c%d", &xsign, &x, &ysign, &y); if (n==2) x = y = 0; else if (n==6) { if (xsign == '-') x = -x; if (ysign == '-') y = -y; } else I_Error("bad -geom parameter"); }
// open the display X_display = XOpenDisplay(displayname); if (!X_display) { if (displayname) I_Error("Could not open display [%s]", displayname); else I_Error("Could not open display (DISPLAY=[%s])", getenv("DISPLAY")); }
// use the default visual X_screen = DefaultScreen(X_display); if (!XMatchVisualInfo(X_display, X_screen, 8, PseudoColor, &X_visualinfo)) I_Error("xdoom currently only supports 256-color PseudoColor screens"); X_visual = X_visualinfo.visual;
// check for the MITSHM extension doShm = XShmQueryExtension(X_display);
// even if it's available, make sure it's a local connection if (doShm) { if (!displayname) displayname = (char *) getenv("DISPLAY"); if (displayname) { d = displayname; while (*d && (*d != ':')) d++; if (*d) *d = 0; if (!(!strcasecmp(displayname, "unix") || !*displayname)) doShm = false; } }
fprintf(stderr, "Using MITSHM extension\n");
// create the colormap X_cmap = XCreateColormap(X_display, RootWindow(X_display, X_screen), X_visual, AllocAll);
// setup attributes for main window attribmask = CWEventMask | CWColormap | CWBorderPixel; attribs.event_mask = KeyPressMask | KeyReleaseMask // | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | ExposureMask;
attribs.colormap = X_cmap; attribs.border_pixel = 0;
// create the main window X_mainWindow = XCreateWindow( X_display, RootWindow(X_display, X_screen), x, y, X_width, X_height, 0, // borderwidth 8, // depth InputOutput, X_visual, attribmask, &attribs );
XDefineCursor(X_display, X_mainWindow, createnullcursor( X_display, X_mainWindow ) );
// create the GC valuemask = GCGraphicsExposures; xgcvalues.graphics_exposures = False; X_gc = XCreateGC( X_display, X_mainWindow, valuemask, &xgcvalues );
// map the window XMapWindow(X_display, X_mainWindow);
// wait until it is OK to draw oktodraw = 0; while (!oktodraw) { XNextEvent(X_display, &X_event); if (X_event.type == Expose && !X_event.xexpose.count) { oktodraw = 1; } }
// grabs the pointer so it is restricted to this window if (grabMouse) XGrabPointer(X_display, X_mainWindow, True, ButtonPressMask|ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, X_mainWindow, None, CurrentTime);
if (doShm) {
X_shmeventtype = XShmGetEventBase(X_display) + ShmCompletion;
// create the image image = XShmCreateImage( X_display, X_visual, 8, ZPixmap, 0, &X_shminfo, X_width, X_height );
grabsharedmemory(image->bytes_per_line * image->height);
// UNUSED // create the shared memory segment // X_shminfo.shmid = shmget (IPC_PRIVATE, // image->bytes_per_line * image->height, IPC_CREAT | 0777); // if (X_shminfo.shmid < 0) // { // perror(""); // I_Error("shmget() failed in InitGraphics()"); // } // fprintf(stderr, "shared memory id=%d\n", X_shminfo.shmid); // attach to the shared memory segment // image->data = X_shminfo.shmaddr = shmat(X_shminfo.shmid, 0, 0);
if (!image->data) { perror(""); I_Error("shmat() failed in InitGraphics()"); }
// get the X server to attach to it if (!XShmAttach(X_display, &X_shminfo)) I_Error("XShmAttach() failed in InitGraphics()");
} else { image = XCreateImage( X_display, X_visual, 8, ZPixmap, 0, (char*)malloc(X_width * X_height), X_width, X_height, 8, X_width );
}
if (multiply == 1) screens[0] = (unsigned char *) (image->data); else screens[0] = (unsigned char *) malloc (SCREENWIDTH * SCREENHEIGHT);
}
unsigned exptable[256];
void InitExpand (void) { int i; for (i=0 ; i<256 ; i++) exptable[i] = i | (i<<8) | (i<<16) | (i<<24); }
double exptable2[256*256];
void InitExpand2 (void) { int i; int j; // UNUSED unsigned iexp, jexp; double* exp; union { double d; unsigned u[2]; } pixel; printf ("building exptable2...\n"); exp = exptable2; for (i=0 ; i<256 ; i++) { pixel.u[0] = i | (i<<8) | (i<<16) | (i<<24); for (j=0 ; j<256 ; j++) { pixel.u[1] = j | (j<<8) | (j<<16) | (j<<24); *exp++ = pixel.d; } } printf ("done.\n"); }
int inited;
void Expand4 ( unsigned* lineptr, double* xline ) { double dpixel; unsigned x; unsigned y; unsigned fourpixels; unsigned step; double* exp; exp = exptable2; if (!inited) { inited = 1; InitExpand2 (); } step = 3*SCREENWIDTH/2; y = SCREENHEIGHT-1; do { x = SCREENWIDTH;
do { fourpixels = lineptr[0]; dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) ); xline[0] = dpixel; xline[160] = dpixel; xline[320] = dpixel; xline[480] = dpixel; dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) ); xline[1] = dpixel; xline[161] = dpixel; xline[321] = dpixel; xline[481] = dpixel;
fourpixels = lineptr[1]; dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) ); xline[2] = dpixel; xline[162] = dpixel; xline[322] = dpixel; xline[482] = dpixel; dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) ); xline[3] = dpixel; xline[163] = dpixel; xline[323] = dpixel; xline[483] = dpixel;
fourpixels = lineptr[2]; dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) ); xline[4] = dpixel; xline[164] = dpixel; xline[324] = dpixel; xline[484] = dpixel; dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) ); xline[5] = dpixel; xline[165] = dpixel; xline[325] = dpixel; xline[485] = dpixel;
fourpixels = lineptr[3]; dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) ); xline[6] = dpixel; xline[166] = dpixel; xline[326] = dpixel; xline[486] = dpixel; dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) ); xline[7] = dpixel; xline[167] = dpixel; xline[327] = dpixel; xline[487] = dpixel;
lineptr+=4; xline+=8; } while (x-=16); xline += step; } while (y--); }
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // System specific interface stuff. // //-----------------------------------------------------------------------------
#ifndef __I_VIDEO__ #define __I_VIDEO__
#include "doomtype.h"
#ifdef __GNUG__ #pragma interface #endif
// Called by D_DoomMain, // determines the hardware configuration // and sets up the video mode void I_InitGraphics (void);
void I_ShutdownGraphics(void);
// Takes full 8 bit values. void I_SetPalette (byte* palette);
void I_UpdateNoBlit (void); void I_FinishUpdate (void);
// Wait for vertical retrace or pause a bit. void I_WaitVBL(int count);
void I_ReadScreen (byte* scr);
void I_BeginRead (void); void I_EndRead (void);
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // Thing frame/state LUT, // generated by multigen utilitiy. // This one is the original DOOM version, preserved. // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: info.c,v 1.3 1997/01/26 07:45:00 b1 Exp $";
// Data. #include "sounds.h" #include "m_fixed.h"
#ifdef __GNUG__ #pragma implementation "info.h" #endif #include "info.h"
#include "p_mobj.h"
char *sprnames[NUMSPRITES] = { "TROO","SHTG","PUNG","PISG","PISF","SHTF","SHT2","CHGG","CHGF","MISG", "MISF","SAWG","PLSG","PLSF","BFGG","BFGF","BLUD","PUFF","BAL1","BAL2", "PLSS","PLSE","MISL","BFS1","BFE1","BFE2","TFOG","IFOG","PLAY","POSS", "SPOS","VILE","FIRE","FATB","FBXP","SKEL","MANF","FATT","CPOS","SARG", "HEAD","BAL7","BOSS","BOS2","SKUL","SPID","BSPI","APLS","APBX","CYBR", "PAIN","SSWV","KEEN","BBRN","BOSF","ARM1","ARM2","BAR1","BEXP","FCAN", "BON1","BON2","BKEY","RKEY","YKEY","BSKU","RSKU","YSKU","STIM","MEDI", "SOUL","PINV","PSTR","PINS","MEGA","SUIT","PMAP","PVIS","CLIP","AMMO", "ROCK","BROK","CELL","CELP","SHEL","SBOX","BPAK","BFUG","MGUN","CSAW", "LAUN","PLAS","SHOT","SGN2","COLU","SMT2","GOR1","POL2","POL5","POL4", "POL3","POL1","POL6","GOR2","GOR3","GOR4","GOR5","SMIT","COL1","COL2", "COL3","COL4","CAND","CBRA","COL6","TRE1","TRE2","ELEC","CEYE","FSKU", "COL5","TBLU","TGRN","TRED","SMBT","SMGT","SMRT","HDB1","HDB2","HDB3", "HDB4","HDB5","HDB6","POB1","POB2","BRS1","TLMP","TLP2" };
// Doesn't work with g++, needs actionf_p1 void A_Light0(); void A_WeaponReady(); void A_Lower(); void A_Raise(); void A_Punch(); void A_ReFire(); void A_FirePistol(); void A_Light1(); void A_FireShotgun(); void A_Light2(); void A_FireShotgun2(); void A_CheckReload(); void A_OpenShotgun2(); void A_LoadShotgun2(); void A_CloseShotgun2(); void A_FireCGun(); void A_GunFlash(); void A_FireMissile(); void A_Saw(); void A_FirePlasma(); void A_BFGsound(); void A_FireBFG(); void A_BFGSpray(); void A_Explode(); void A_Pain(); void A_PlayerScream(); void A_Fall(); void A_XScream(); void A_Look(); void A_Chase(); void A_FaceTarget(); void A_PosAttack(); void A_Scream(); void A_SPosAttack(); void A_VileChase(); void A_VileStart(); void A_VileTarget(); void A_VileAttack(); void A_StartFire(); void A_Fire(); void A_FireCrackle(); void A_Tracer(); void A_SkelWhoosh(); void A_SkelFist(); void A_SkelMissile(); void A_FatRaise(); void A_FatAttack1(); void A_FatAttack2(); void A_FatAttack3(); void A_BossDeath(); void A_CPosAttack(); void A_CPosRefire(); void A_TroopAttack(); void A_SargAttack(); void A_HeadAttack(); void A_BruisAttack(); void A_SkullAttack(); void A_Metal(); void A_SpidRefire(); void A_BabyMetal(); void A_BspiAttack(); void A_Hoof(); void A_CyberAttack(); void A_PainAttack(); void A_PainDie(); void A_KeenDie(); void A_BrainPain(); void A_BrainScream(); void A_BrainDie(); void A_BrainAwake(); void A_BrainSpit(); void A_SpawnSound(); void A_SpawnFly(); void A_BrainExplode();
state_t states[NUMSTATES] = { {SPR_TROO,0,-1,{NULL},S_NULL,0,0}, // S_NULL {SPR_SHTG,4,0,{A_Light0},S_NULL,0,0}, // S_LIGHTDONE {SPR_PUNG,0,1,{A_WeaponReady},S_PUNCH,0,0}, // S_PUNCH {SPR_PUNG,0,1,{A_Lower},S_PUNCHDOWN,0,0}, // S_PUNCHDOWN {SPR_PUNG,0,1,{A_Raise},S_PUNCHUP,0,0}, // S_PUNCHUP {SPR_PUNG,1,4,{NULL},S_PUNCH2,0,0}, // S_PUNCH1 {SPR_PUNG,2,4,{A_Punch},S_PUNCH3,0,0}, // S_PUNCH2 {SPR_PUNG,3,5,{NULL},S_PUNCH4,0,0}, // S_PUNCH3 {SPR_PUNG,2,4,{NULL},S_PUNCH5,0,0}, // S_PUNCH4 {SPR_PUNG,1,5,{A_ReFire},S_PUNCH,0,0}, // S_PUNCH5 {SPR_PISG,0,1,{A_WeaponReady},S_PISTOL,0,0},// S_PISTOL {SPR_PISG,0,1,{A_Lower},S_PISTOLDOWN,0,0}, // S_PISTOLDOWN {SPR_PISG,0,1,{A_Raise},S_PISTOLUP,0,0}, // S_PISTOLUP {SPR_PISG,0,4,{NULL},S_PISTOL2,0,0}, // S_PISTOL1 {SPR_PISG,1,6,{A_FirePistol},S_PISTOL3,0,0},// S_PISTOL2 {SPR_PISG,2,4,{NULL},S_PISTOL4,0,0}, // S_PISTOL3 {SPR_PISG,1,5,{A_ReFire},S_PISTOL,0,0}, // S_PISTOL4 {SPR_PISF,32768,7,{A_Light1},S_LIGHTDONE,0,0}, // S_PISTOLFLASH {SPR_SHTG,0,1,{A_WeaponReady},S_SGUN,0,0}, // S_SGUN {SPR_SHTG,0,1,{A_Lower},S_SGUNDOWN,0,0}, // S_SGUNDOWN {SPR_SHTG,0,1,{A_Raise},S_SGUNUP,0,0}, // S_SGUNUP {SPR_SHTG,0,3,{NULL},S_SGUN2,0,0}, // S_SGUN1 {SPR_SHTG,0,7,{A_FireShotgun},S_SGUN3,0,0}, // S_SGUN2 {SPR_SHTG,1,5,{NULL},S_SGUN4,0,0}, // S_SGUN3 {SPR_SHTG,2,5,{NULL},S_SGUN5,0,0}, // S_SGUN4 {SPR_SHTG,3,4,{NULL},S_SGUN6,0,0}, // S_SGUN5 {SPR_SHTG,2,5,{NULL},S_SGUN7,0,0}, // S_SGUN6 {SPR_SHTG,1,5,{NULL},S_SGUN8,0,0}, // S_SGUN7 {SPR_SHTG,0,3,{NULL},S_SGUN9,0,0}, // S_SGUN8 {SPR_SHTG,0,7,{A_ReFire},S_SGUN,0,0}, // S_SGUN9 {SPR_SHTF,32768,4,{A_Light1},S_SGUNFLASH2,0,0}, // S_SGUNFLASH1 {SPR_SHTF,32769,3,{A_Light2},S_LIGHTDONE,0,0}, // S_SGUNFLASH2 {SPR_SHT2,0,1,{A_WeaponReady},S_DSGUN,0,0}, // S_DSGUN {SPR_SHT2,0,1,{A_Lower},S_DSGUNDOWN,0,0}, // S_DSGUNDOWN {SPR_SHT2,0,1,{A_Raise},S_DSGUNUP,0,0}, // S_DSGUNUP {SPR_SHT2,0,3,{NULL},S_DSGUN2,0,0}, // S_DSGUN1 {SPR_SHT2,0,7,{A_FireShotgun2},S_DSGUN3,0,0}, // S_DSGUN2 {SPR_SHT2,1,7,{NULL},S_DSGUN4,0,0}, // S_DSGUN3 {SPR_SHT2,2,7,{A_CheckReload},S_DSGUN5,0,0}, // S_DSGUN4 {SPR_SHT2,3,7,{A_OpenShotgun2},S_DSGUN6,0,0}, // S_DSGUN5 {SPR_SHT2,4,7,{NULL},S_DSGUN7,0,0}, // S_DSGUN6 {SPR_SHT2,5,7,{A_LoadShotgun2},S_DSGUN8,0,0}, // S_DSGUN7 {SPR_SHT2,6,6,{NULL},S_DSGUN9,0,0}, // S_DSGUN8 {SPR_SHT2,7,6,{A_CloseShotgun2},S_DSGUN10,0,0}, // S_DSGUN9 {SPR_SHT2,0,5,{A_ReFire},S_DSGUN,0,0}, // S_DSGUN10 {SPR_SHT2,1,7,{NULL},S_DSNR2,0,0}, // S_DSNR1 {SPR_SHT2,0,3,{NULL},S_DSGUNDOWN,0,0}, // S_DSNR2 {SPR_SHT2,32776,5,{A_Light1},S_DSGUNFLASH2,0,0}, // S_DSGUNFLASH1 {SPR_SHT2,32777,4,{A_Light2},S_LIGHTDONE,0,0}, // S_DSGUNFLASH2 {SPR_CHGG,0,1,{A_WeaponReady},S_CHAIN,0,0}, // S_CHAIN {SPR_CHGG,0,1,{A_Lower},S_CHAINDOWN,0,0}, // S_CHAINDOWN {SPR_CHGG,0,1,{A_Raise},S_CHAINUP,0,0}, // S_CHAINUP {SPR_CHGG,0,4,{A_FireCGun},S_CHAIN2,0,0}, // S_CHAIN1 {SPR_CHGG,1,4,{A_FireCGun},S_CHAIN3,0,0}, // S_CHAIN2 {SPR_CHGG,1,0,{A_ReFire},S_CHAIN,0,0}, // S_CHAIN3 {SPR_CHGF,32768,5,{A_Light1},S_LIGHTDONE,0,0}, // S_CHAINFLASH1 {SPR_CHGF,32769,5,{A_Light2},S_LIGHTDONE,0,0}, // S_CHAINFLASH2 {SPR_MISG,0,1,{A_WeaponReady},S_MISSILE,0,0}, // S_MISSILE {SPR_MISG,0,1,{A_Lower},S_MISSILEDOWN,0,0}, // S_MISSILEDOWN {SPR_MISG,0,1,{A_Raise},S_MISSILEUP,0,0}, // S_MISSILEUP {SPR_MISG,1,8,{A_GunFlash},S_MISSILE2,0,0}, // S_MISSILE1 {SPR_MISG,1,12,{A_FireMissile},S_MISSILE3,0,0}, // S_MISSILE2 {SPR_MISG,1,0,{A_ReFire},S_MISSILE,0,0}, // S_MISSILE3 {SPR_MISF,32768,3,{A_Light1},S_MISSILEFLASH2,0,0}, // S_MISSILEFLASH1 {SPR_MISF,32769,4,{NULL},S_MISSILEFLASH3,0,0}, // S_MISSILEFLASH2 {SPR_MISF,32770,4,{A_Light2},S_MISSILEFLASH4,0,0}, // S_MISSILEFLASH3 {SPR_MISF,32771,4,{A_Light2},S_LIGHTDONE,0,0}, // S_MISSILEFLASH4 {SPR_SAWG,2,4,{A_WeaponReady},S_SAWB,0,0}, // S_SAW {SPR_SAWG,3,4,{A_WeaponReady},S_SAW,0,0}, // S_SAWB {SPR_SAWG,2,1,{A_Lower},S_SAWDOWN,0,0}, // S_SAWDOWN {SPR_SAWG,2,1,{A_Raise},S_SAWUP,0,0}, // S_SAWUP {SPR_SAWG,0,4,{A_Saw},S_SAW2,0,0}, // S_SAW1 {SPR_SAWG,1,4,{A_Saw},S_SAW3,0,0}, // S_SAW2 {SPR_SAWG,1,0,{A_ReFire},S_SAW,0,0}, // S_SAW3 {SPR_PLSG,0,1,{A_WeaponReady},S_PLASMA,0,0}, // S_PLASMA {SPR_PLSG,0,1,{A_Lower},S_PLASMADOWN,0,0}, // S_PLASMADOWN {SPR_PLSG,0,1,{A_Raise},S_PLASMAUP,0,0}, // S_PLASMAUP {SPR_PLSG,0,3,{A_FirePlasma},S_PLASMA2,0,0}, // S_PLASMA1 {SPR_PLSG,1,20,{A_ReFire},S_PLASMA,0,0}, // S_PLASMA2 {SPR_PLSF,32768,4,{A_Light1},S_LIGHTDONE,0,0}, // S_PLASMAFLASH1 {SPR_PLSF,32769,4,{A_Light1},S_LIGHTDONE,0,0}, // S_PLASMAFLASH2 {SPR_BFGG,0,1,{A_WeaponReady},S_BFG,0,0}, // S_BFG {SPR_BFGG,0,1,{A_Lower},S_BFGDOWN,0,0}, // S_BFGDOWN {SPR_BFGG,0,1,{A_Raise},S_BFGUP,0,0}, // S_BFGUP {SPR_BFGG,0,20,{A_BFGsound},S_BFG2,0,0}, // S_BFG1 {SPR_BFGG,1,10,{A_GunFlash},S_BFG3,0,0}, // S_BFG2 {SPR_BFGG,1,10,{A_FireBFG},S_BFG4,0,0}, // S_BFG3 {SPR_BFGG,1,20,{A_ReFire},S_BFG,0,0}, // S_BFG4 {SPR_BFGF,32768,11,{A_Light1},S_BFGFLASH2,0,0}, // S_BFGFLASH1 {SPR_BFGF,32769,6,{A_Light2},S_LIGHTDONE,0,0}, // S_BFGFLASH2 {SPR_BLUD,2,8,{NULL},S_BLOOD2,0,0}, // S_BLOOD1 {SPR_BLUD,1,8,{NULL},S_BLOOD3,0,0}, // S_BLOOD2 {SPR_BLUD,0,8,{NULL},S_NULL,0,0}, // S_BLOOD3 {SPR_PUFF,32768,4,{NULL},S_PUFF2,0,0}, // S_PUFF1 {SPR_PUFF,1,4,{NULL},S_PUFF3,0,0}, // S_PUFF2 {SPR_PUFF,2,4,{NULL},S_PUFF4,0,0}, // S_PUFF3 {SPR_PUFF,3,4,{NULL},S_NULL,0,0}, // S_PUFF4 {SPR_BAL1,32768,4,{NULL},S_TBALL2,0,0}, // S_TBALL1 {SPR_BAL1,32769,4,{NULL},S_TBALL1,0,0}, // S_TBALL2 {SPR_BAL1,32770,6,{NULL},S_TBALLX2,0,0}, // S_TBALLX1 {SPR_BAL1,32771,6,{NULL},S_TBALLX3,0,0}, // S_TBALLX2 {SPR_BAL1,32772,6,{NULL},S_NULL,0,0}, // S_TBALLX3 {SPR_BAL2,32768,4,{NULL},S_RBALL2,0,0}, // S_RBALL1 {SPR_BAL2,32769,4,{NULL},S_RBALL1,0,0}, // S_RBALL2 {SPR_BAL2,32770,6,{NULL},S_RBALLX2,0,0}, // S_RBALLX1 {SPR_BAL2,32771,6,{NULL},S_RBALLX3,0,0}, // S_RBALLX2 {SPR_BAL2,32772,6,{NULL},S_NULL,0,0}, // S_RBALLX3 {SPR_PLSS,32768,6,{NULL},S_PLASBALL2,0,0}, // S_PLASBALL {SPR_PLSS,32769,6,{NULL},S_PLASBALL,0,0}, // S_PLASBALL2 {SPR_PLSE,32768,4,{NULL},S_PLASEXP2,0,0}, // S_PLASEXP {SPR_PLSE,32769,4,{NULL},S_PLASEXP3,0,0}, // S_PLASEXP2 {SPR_PLSE,32770,4,{NULL},S_PLASEXP4,0,0}, // S_PLASEXP3 {SPR_PLSE,32771,4,{NULL},S_PLASEXP5,0,0}, // S_PLASEXP4 {SPR_PLSE,32772,4,{NULL},S_NULL,0,0}, // S_PLASEXP5 {SPR_MISL,32768,1,{NULL},S_ROCKET,0,0}, // S_ROCKET {SPR_BFS1,32768,4,{NULL},S_BFGSHOT2,0,0}, // S_BFGSHOT {SPR_BFS1,32769,4,{NULL},S_BFGSHOT,0,0}, // S_BFGSHOT2 {SPR_BFE1,32768,8,{NULL},S_BFGLAND2,0,0}, // S_BFGLAND {SPR_BFE1,32769,8,{NULL},S_BFGLAND3,0,0}, // S_BFGLAND2 {SPR_BFE1,32770,8,{A_BFGSpray},S_BFGLAND4,0,0}, // S_BFGLAND3 {SPR_BFE1,32771,8,{NULL},S_BFGLAND5,0,0}, // S_BFGLAND4 {SPR_BFE1,32772,8,{NULL},S_BFGLAND6,0,0}, // S_BFGLAND5 {SPR_BFE1,32773,8,{NULL},S_NULL,0,0}, // S_BFGLAND6 {SPR_BFE2,32768,8,{NULL},S_BFGEXP2,0,0}, // S_BFGEXP {SPR_BFE2,32769,8,{NULL},S_BFGEXP3,0,0}, // S_BFGEXP2 {SPR_BFE2,32770,8,{NULL},S_BFGEXP4,0,0}, // S_BFGEXP3 {SPR_BFE2,32771,8,{NULL},S_NULL,0,0}, // S_BFGEXP4 {SPR_MISL,32769,8,{A_Explode},S_EXPLODE2,0,0}, // S_EXPLODE1 {SPR_MISL,32770,6,{NULL},S_EXPLODE3,0,0}, // S_EXPLODE2 {SPR_MISL,32771,4,{NULL},S_NULL,0,0}, // S_EXPLODE3 {SPR_TFOG,32768,6,{NULL},S_TFOG01,0,0}, // S_TFOG {SPR_TFOG,32769,6,{NULL},S_TFOG02,0,0}, // S_TFOG01 {SPR_TFOG,32768,6,{NULL},S_TFOG2,0,0}, // S_TFOG02 {SPR_TFOG,32769,6,{NULL},S_TFOG3,0,0}, // S_TFOG2 {SPR_TFOG,32770,6,{NULL},S_TFOG4,0,0}, // S_TFOG3 {SPR_TFOG,32771,6,{NULL},S_TFOG5,0,0}, // S_TFOG4 {SPR_TFOG,32772,6,{NULL},S_TFOG6,0,0}, // S_TFOG5 {SPR_TFOG,32773,6,{NULL},S_TFOG7,0,0}, // S_TFOG6 {SPR_TFOG,32774,6,{NULL},S_TFOG8,0,0}, // S_TFOG7 {SPR_TFOG,32775,6,{NULL},S_TFOG9,0,0}, // S_TFOG8 {SPR_TFOG,32776,6,{NULL},S_TFOG10,0,0}, // S_TFOG9 {SPR_TFOG,32777,6,{NULL},S_NULL,0,0}, // S_TFOG10 {SPR_IFOG,32768,6,{NULL},S_IFOG01,0,0}, // S_IFOG {SPR_IFOG,32769,6,{NULL},S_IFOG02,0,0}, // S_IFOG01 {SPR_IFOG,32768,6,{NULL},S_IFOG2,0,0}, // S_IFOG02 {SPR_IFOG,32769,6,{NULL},S_IFOG3,0,0}, // S_IFOG2 {SPR_IFOG,32770,6,{NULL},S_IFOG4,0,0}, // S_IFOG3 {SPR_IFOG,32771,6,{NULL},S_IFOG5,0,0}, // S_IFOG4 {SPR_IFOG,32772,6,{NULL},S_NULL,0,0}, // S_IFOG5 {SPR_PLAY,0,-1,{NULL},S_NULL,0,0}, // S_PLAY {SPR_PLAY,0,4,{NULL},S_PLAY_RUN2,0,0}, // S_PLAY_RUN1 {SPR_PLAY,1,4,{NULL},S_PLAY_RUN3,0,0}, // S_PLAY_RUN2 {SPR_PLAY,2,4,{NULL},S_PLAY_RUN4,0,0}, // S_PLAY_RUN3 {SPR_PLAY,3,4,{NULL},S_PLAY_RUN1,0,0}, // S_PLAY_RUN4 {SPR_PLAY,4,12,{NULL},S_PLAY,0,0}, // S_PLAY_ATK1 {SPR_PLAY,32773,6,{NULL},S_PLAY_ATK1,0,0}, // S_PLAY_ATK2 {SPR_PLAY,6,4,{NULL},S_PLAY_PAIN2,0,0}, // S_PLAY_PAIN {SPR_PLAY,6,4,{A_Pain},S_PLAY,0,0}, // S_PLAY_PAIN2 {SPR_PLAY,7,10,{NULL},S_PLAY_DIE2,0,0}, // S_PLAY_DIE1 {SPR_PLAY,8,10,{A_PlayerScream},S_PLAY_DIE3,0,0}, // S_PLAY_DIE2 {SPR_PLAY,9,10,{A_Fall},S_PLAY_DIE4,0,0}, // S_PLAY_DIE3 {SPR_PLAY,10,10,{NULL},S_PLAY_DIE5,0,0}, // S_PLAY_DIE4 {SPR_PLAY,11,10,{NULL},S_PLAY_DIE6,0,0}, // S_PLAY_DIE5 {SPR_PLAY,12,10,{NULL},S_PLAY_DIE7,0,0}, // S_PLAY_DIE6 {SPR_PLAY,13,-1,{NULL},S_NULL,0,0}, // S_PLAY_DIE7 {SPR_PLAY,14,5,{NULL},S_PLAY_XDIE2,0,0}, // S_PLAY_XDIE1 {SPR_PLAY,15,5,{A_XScream},S_PLAY_XDIE3,0,0}, // S_PLAY_XDIE2 {SPR_PLAY,16,5,{A_Fall},S_PLAY_XDIE4,0,0}, // S_PLAY_XDIE3 {SPR_PLAY,17,5,{NULL},S_PLAY_XDIE5,0,0}, // S_PLAY_XDIE4 {SPR_PLAY,18,5,{NULL},S_PLAY_XDIE6,0,0}, // S_PLAY_XDIE5 {SPR_PLAY,19,5,{NULL},S_PLAY_XDIE7,0,0}, // S_PLAY_XDIE6 {SPR_PLAY,20,5,{NULL},S_PLAY_XDIE8,0,0}, // S_PLAY_XDIE7 {SPR_PLAY,21,5,{NULL},S_PLAY_XDIE9,0,0}, // S_PLAY_XDIE8 {SPR_PLAY,22,-1,{NULL},S_NULL,0,0}, // S_PLAY_XDIE9 {SPR_POSS,0,10,{A_Look},S_POSS_STND2,0,0}, // S_POSS_STND {SPR_POSS,1,10,{A_Look},S_POSS_STND,0,0}, // S_POSS_STND2 {SPR_POSS,0,4,{A_Chase},S_POSS_RUN2,0,0}, // S_POSS_RUN1 {SPR_POSS,0,4,{A_Chase},S_POSS_RUN3,0,0}, // S_POSS_RUN2 {SPR_POSS,1,4,{A_Chase},S_POSS_RUN4,0,0}, // S_POSS_RUN3 {SPR_POSS,1,4,{A_Chase},S_POSS_RUN5,0,0}, // S_POSS_RUN4 {SPR_POSS,2,4,{A_Chase},S_POSS_RUN6,0,0}, // S_POSS_RUN5 {SPR_POSS,2,4,{A_Chase},S_POSS_RUN7,0,0}, // S_POSS_RUN6 {SPR_POSS,3,4,{A_Chase},S_POSS_RUN8,0,0}, // S_POSS_RUN7 {SPR_POSS,3,4,{A_Chase},S_POSS_RUN1,0,0}, // S_POSS_RUN8 {SPR_POSS,4,10,{A_FaceTarget},S_POSS_ATK2,0,0}, // S_POSS_ATK1 {SPR_POSS,5,8,{A_PosAttack},S_POSS_ATK3,0,0}, // S_POSS_ATK2 {SPR_POSS,4,8,{NULL},S_POSS_RUN1,0,0}, // S_POSS_ATK3 {SPR_POSS,6,3,{NULL},S_POSS_PAIN2,0,0}, // S_POSS_PAIN {SPR_POSS,6,3,{A_Pain},S_POSS_RUN1,0,0}, // S_POSS_PAIN2 {SPR_POSS,7,5,{NULL},S_POSS_DIE2,0,0}, // S_POSS_DIE1 {SPR_POSS,8,5,{A_Scream},S_POSS_DIE3,0,0}, // S_POSS_DIE2 {SPR_POSS,9,5,{A_Fall},S_POSS_DIE4,0,0}, // S_POSS_DIE3 {SPR_POSS,10,5,{NULL},S_POSS_DIE5,0,0}, // S_POSS_DIE4 {SPR_POSS,11,-1,{NULL},S_NULL,0,0}, // S_POSS_DIE5 {SPR_POSS,12,5,{NULL},S_POSS_XDIE2,0,0}, // S_POSS_XDIE1 {SPR_POSS,13,5,{A_XScream},S_POSS_XDIE3,0,0}, // S_POSS_XDIE2 {SPR_POSS,14,5,{A_Fall},S_POSS_XDIE4,0,0}, // S_POSS_XDIE3 {SPR_POSS,15,5,{NULL},S_POSS_XDIE5,0,0}, // S_POSS_XDIE4 {SPR_POSS,16,5,{NULL},S_POSS_XDIE6,0,0}, // S_POSS_XDIE5 {SPR_POSS,17,5,{NULL},S_POSS_XDIE7,0,0}, // S_POSS_XDIE6 {SPR_POSS,18,5,{NULL},S_POSS_XDIE8,0,0}, // S_POSS_XDIE7 {SPR_POSS,19,5,{NULL},S_POSS_XDIE9,0,0}, // S_POSS_XDIE8 {SPR_POSS,20,-1,{NULL},S_NULL,0,0}, // S_POSS_XDIE9 {SPR_POSS,10,5,{NULL},S_POSS_RAISE2,0,0}, // S_POSS_RAISE1 {SPR_POSS,9,5,{NULL},S_POSS_RAISE3,0,0}, // S_POSS_RAISE2 {SPR_POSS,8,5,{NULL},S_POSS_RAISE4,0,0}, // S_POSS_RAISE3 {SPR_POSS,7,5,{NULL},S_POSS_RUN1,0,0}, // S_POSS_RAISE4 {SPR_SPOS,0,10,{A_Look},S_SPOS_STND2,0,0}, // S_SPOS_STND {SPR_SPOS,1,10,{A_Look},S_SPOS_STND,0,0}, // S_SPOS_STND2 {SPR_SPOS,0,3,{A_Chase},S_SPOS_RUN2,0,0}, // S_SPOS_RUN1 {SPR_SPOS,0,3,{A_Chase},S_SPOS_RUN3,0,0}, // S_SPOS_RUN2 {SPR_SPOS,1,3,{A_Chase},S_SPOS_RUN4,0,0}, // S_SPOS_RUN3 {SPR_SPOS,1,3,{A_Chase},S_SPOS_RUN5,0,0}, // S_SPOS_RUN4 {SPR_SPOS,2,3,{A_Chase},S_SPOS_RUN6,0,0}, // S_SPOS_RUN5 {SPR_SPOS,2,3,{A_Chase},S_SPOS_RUN7,0,0}, // S_SPOS_RUN6 {SPR_SPOS,3,3,{A_Chase},S_SPOS_RUN8,0,0}, // S_SPOS_RUN7 {SPR_SPOS,3,3,{A_Chase},S_SPOS_RUN1,0,0}, // S_SPOS_RUN8 {SPR_SPOS,4,10,{A_FaceTarget},S_SPOS_ATK2,0,0}, // S_SPOS_ATK1 {SPR_SPOS,32773,10,{A_SPosAttack},S_SPOS_ATK3,0,0}, // S_SPOS_ATK2 {SPR_SPOS,4,10,{NULL},S_SPOS_RUN1,0,0}, // S_SPOS_ATK3 {SPR_SPOS,6,3,{NULL},S_SPOS_PAIN2,0,0}, // S_SPOS_PAIN {SPR_SPOS,6,3,{A_Pain},S_SPOS_RUN1,0,0}, // S_SPOS_PAIN2 {SPR_SPOS,7,5,{NULL},S_SPOS_DIE2,0,0}, // S_SPOS_DIE1 {SPR_SPOS,8,5,{A_Scream},S_SPOS_DIE3,0,0}, // S_SPOS_DIE2 {SPR_SPOS,9,5,{A_Fall},S_SPOS_DIE4,0,0}, // S_SPOS_DIE3 {SPR_SPOS,10,5,{NULL},S_SPOS_DIE5,0,0}, // S_SPOS_DIE4 {SPR_SPOS,11,-1,{NULL},S_NULL,0,0}, // S_SPOS_DIE5 {SPR_SPOS,12,5,{NULL},S_SPOS_XDIE2,0,0}, // S_SPOS_XDIE1 {SPR_SPOS,13,5,{A_XScream},S_SPOS_XDIE3,0,0}, // S_SPOS_XDIE2 {SPR_SPOS,14,5,{A_Fall},S_SPOS_XDIE4,0,0}, // S_SPOS_XDIE3 {SPR_SPOS,15,5,{NULL},S_SPOS_XDIE5,0,0}, // S_SPOS_XDIE4 {SPR_SPOS,16,5,{NULL},S_SPOS_XDIE6,0,0}, // S_SPOS_XDIE5 {SPR_SPOS,17,5,{NULL},S_SPOS_XDIE7,0,0}, // S_SPOS_XDIE6 {SPR_SPOS,18,5,{NULL},S_SPOS_XDIE8,0,0}, // S_SPOS_XDIE7 {SPR_SPOS,19,5,{NULL},S_SPOS_XDIE9,0,0}, // S_SPOS_XDIE8 {SPR_SPOS,20,-1,{NULL},S_NULL,0,0}, // S_SPOS_XDIE9 {SPR_SPOS,11,5,{NULL},S_SPOS_RAISE2,0,0}, // S_SPOS_RAISE1 {SPR_SPOS,10,5,{NULL},S_SPOS_RAISE3,0,0}, // S_SPOS_RAISE2 {SPR_SPOS,9,5,{NULL},S_SPOS_RAISE4,0,0}, // S_SPOS_RAISE3 {SPR_SPOS,8,5,{NULL},S_SPOS_RAISE5,0,0}, // S_SPOS_RAISE4 {SPR_SPOS,7,5,{NULL},S_SPOS_RUN1,0,0}, // S_SPOS_RAISE5 {SPR_VILE,0,10,{A_Look},S_VILE_STND2,0,0}, // S_VILE_STND {SPR_VILE,1,10,{A_Look},S_VILE_STND,0,0}, // S_VILE_STND2 {SPR_VILE,0,2,{A_VileChase},S_VILE_RUN2,0,0}, // S_VILE_RUN1 {SPR_VILE,0,2,{A_VileChase},S_VILE_RUN3,0,0}, // S_VILE_RUN2 {SPR_VILE,1,2,{A_VileChase},S_VILE_RUN4,0,0}, // S_VILE_RUN3 {SPR_VILE,1,2,{A_VileChase},S_VILE_RUN5,0,0}, // S_VILE_RUN4 {SPR_VILE,2,2,{A_VileChase},S_VILE_RUN6,0,0}, // S_VILE_RUN5 {SPR_VILE,2,2,{A_VileChase},S_VILE_RUN7,0,0}, // S_VILE_RUN6 {SPR_VILE,3,2,{A_VileChase},S_VILE_RUN8,0,0}, // S_VILE_RUN7 {SPR_VILE,3,2,{A_VileChase},S_VILE_RUN9,0,0}, // S_VILE_RUN8 {SPR_VILE,4,2,{A_VileChase},S_VILE_RUN10,0,0}, // S_VILE_RUN9 {SPR_VILE,4,2,{A_VileChase},S_VILE_RUN11,0,0}, // S_VILE_RUN10 {SPR_VILE,5,2,{A_VileChase},S_VILE_RUN12,0,0}, // S_VILE_RUN11 {SPR_VILE,5,2,{A_VileChase},S_VILE_RUN1,0,0}, // S_VILE_RUN12 {SPR_VILE,32774,0,{A_VileStart},S_VILE_ATK2,0,0}, // S_VILE_ATK1 {SPR_VILE,32774,10,{A_FaceTarget},S_VILE_ATK3,0,0}, // S_VILE_ATK2 {SPR_VILE,32775,8,{A_VileTarget},S_VILE_ATK4,0,0}, // S_VILE_ATK3 {SPR_VILE,32776,8,{A_FaceTarget},S_VILE_ATK5,0,0}, // S_VILE_ATK4 {SPR_VILE,32777,8,{A_FaceTarget},S_VILE_ATK6,0,0}, // S_VILE_ATK5 {SPR_VILE,32778,8,{A_FaceTarget},S_VILE_ATK7,0,0}, // S_VILE_ATK6 {SPR_VILE,32779,8,{A_FaceTarget},S_VILE_ATK8,0,0}, // S_VILE_ATK7 {SPR_VILE,32780,8,{A_FaceTarget},S_VILE_ATK9,0,0}, // S_VILE_ATK8 {SPR_VILE,32781,8,{A_FaceTarget},S_VILE_ATK10,0,0}, // S_VILE_ATK9 {SPR_VILE,32782,8,{A_VileAttack},S_VILE_ATK11,0,0}, // S_VILE_ATK10 {SPR_VILE,32783,20,{NULL},S_VILE_RUN1,0,0}, // S_VILE_ATK11 {SPR_VILE,32794,10,{NULL},S_VILE_HEAL2,0,0}, // S_VILE_HEAL1 {SPR_VILE,32795,10,{NULL},S_VILE_HEAL3,0,0}, // S_VILE_HEAL2 {SPR_VILE,32796,10,{NULL},S_VILE_RUN1,0,0}, // S_VILE_HEAL3 {SPR_VILE,16,5,{NULL},S_VILE_PAIN2,0,0}, // S_VILE_PAIN {SPR_VILE,16,5,{A_Pain},S_VILE_RUN1,0,0}, // S_VILE_PAIN2 {SPR_VILE,16,7,{NULL},S_VILE_DIE2,0,0}, // S_VILE_DIE1 {SPR_VILE,17,7,{A_Scream},S_VILE_DIE3,0,0}, // S_VILE_DIE2 {SPR_VILE,18,7,{A_Fall},S_VILE_DIE4,0,0}, // S_VILE_DIE3 {SPR_VILE,19,7,{NULL},S_VILE_DIE5,0,0}, // S_VILE_DIE4 {SPR_VILE,20,7,{NULL},S_VILE_DIE6,0,0}, // S_VILE_DIE5 {SPR_VILE,21,7,{NULL},S_VILE_DIE7,0,0}, // S_VILE_DIE6 {SPR_VILE,22,7,{NULL},S_VILE_DIE8,0,0}, // S_VILE_DIE7 {SPR_VILE,23,5,{NULL},S_VILE_DIE9,0,0}, // S_VILE_DIE8 {SPR_VILE,24,5,{NULL},S_VILE_DIE10,0,0}, // S_VILE_DIE9 {SPR_VILE,25,-1,{NULL},S_NULL,0,0}, // S_VILE_DIE10 {SPR_FIRE,32768,2,{A_StartFire},S_FIRE2,0,0}, // S_FIRE1 {SPR_FIRE,32769,2,{A_Fire},S_FIRE3,0,0}, // S_FIRE2 {SPR_FIRE,32768,2,{A_Fire},S_FIRE4,0,0}, // S_FIRE3 {SPR_FIRE,32769,2,{A_Fire},S_FIRE5,0,0}, // S_FIRE4 {SPR_FIRE,32770,2,{A_FireCrackle},S_FIRE6,0,0}, // S_FIRE5 {SPR_FIRE,32769,2,{A_Fire},S_FIRE7,0,0}, // S_FIRE6 {SPR_FIRE,32770,2,{A_Fire},S_FIRE8,0,0}, // S_FIRE7 {SPR_FIRE,32769,2,{A_Fire},S_FIRE9,0,0}, // S_FIRE8 {SPR_FIRE,32770,2,{A_Fire},S_FIRE10,0,0}, // S_FIRE9 {SPR_FIRE,32771,2,{A_Fire},S_FIRE11,0,0}, // S_FIRE10 {SPR_FIRE,32770,2,{A_Fire},S_FIRE12,0,0}, // S_FIRE11 {SPR_FIRE,32771,2,{A_Fire},S_FIRE13,0,0}, // S_FIRE12 {SPR_FIRE,32770,2,{A_Fire},S_FIRE14,0,0}, // S_FIRE13 {SPR_FIRE,32771,2,{A_Fire},S_FIRE15,0,0}, // S_FIRE14 {SPR_FIRE,32772,2,{A_Fire},S_FIRE16,0,0}, // S_FIRE15 {SPR_FIRE,32771,2,{A_Fire},S_FIRE17,0,0}, // S_FIRE16 {SPR_FIRE,32772,2,{A_Fire},S_FIRE18,0,0}, // S_FIRE17 {SPR_FIRE,32771,2,{A_Fire},S_FIRE19,0,0}, // S_FIRE18 {SPR_FIRE,32772,2,{A_FireCrackle},S_FIRE20,0,0}, // S_FIRE19 {SPR_FIRE,32773,2,{A_Fire},S_FIRE21,0,0}, // S_FIRE20 {SPR_FIRE,32772,2,{A_Fire},S_FIRE22,0,0}, // S_FIRE21 {SPR_FIRE,32773,2,{A_Fire},S_FIRE23,0,0}, // S_FIRE22 {SPR_FIRE,32772,2,{A_Fire},S_FIRE24,0,0}, // S_FIRE23 {SPR_FIRE,32773,2,{A_Fire},S_FIRE25,0,0}, // S_FIRE24 {SPR_FIRE,32774,2,{A_Fire},S_FIRE26,0,0}, // S_FIRE25 {SPR_FIRE,32775,2,{A_Fire},S_FIRE27,0,0}, // S_FIRE26 {SPR_FIRE,32774,2,{A_Fire},S_FIRE28,0,0}, // S_FIRE27 {SPR_FIRE,32775,2,{A_Fire},S_FIRE29,0,0}, // S_FIRE28 {SPR_FIRE,32774,2,{A_Fire},S_FIRE30,0,0}, // S_FIRE29 {SPR_FIRE,32775,2,{A_Fire},S_NULL,0,0}, // S_FIRE30 {SPR_PUFF,1,4,{NULL},S_SMOKE2,0,0}, // S_SMOKE1 {SPR_PUFF,2,4,{NULL},S_SMOKE3,0,0}, // S_SMOKE2 {SPR_PUFF,1,4,{NULL},S_SMOKE4,0,0}, // S_SMOKE3 {SPR_PUFF,2,4,{NULL},S_SMOKE5,0,0}, // S_SMOKE4 {SPR_PUFF,3,4,{NULL},S_NULL,0,0}, // S_SMOKE5 {SPR_FATB,32768,2,{A_Tracer},S_TRACER2,0,0}, // S_TRACER {SPR_FATB,32769,2,{A_Tracer},S_TRACER,0,0}, // S_TRACER2 {SPR_FBXP,32768,8,{NULL},S_TRACEEXP2,0,0}, // S_TRACEEXP1 {SPR_FBXP,32769,6,{NULL},S_TRACEEXP3,0,0}, // S_TRACEEXP2 {SPR_FBXP,32770,4,{NULL},S_NULL,0,0}, // S_TRACEEXP3 {SPR_SKEL,0,10,{A_Look},S_SKEL_STND2,0,0}, // S_SKEL_STND {SPR_SKEL,1,10,{A_Look},S_SKEL_STND,0,0}, // S_SKEL_STND2 {SPR_SKEL,0,2,{A_Chase},S_SKEL_RUN2,0,0}, // S_SKEL_RUN1 {SPR_SKEL,0,2,{A_Chase},S_SKEL_RUN3,0,0}, // S_SKEL_RUN2 {SPR_SKEL,1,2,{A_Chase},S_SKEL_RUN4,0,0}, // S_SKEL_RUN3 {SPR_SKEL,1,2,{A_Chase},S_SKEL_RUN5,0,0}, // S_SKEL_RUN4 {SPR_SKEL,2,2,{A_Chase},S_SKEL_RUN6,0,0}, // S_SKEL_RUN5 {SPR_SKEL,2,2,{A_Chase},S_SKEL_RUN7,0,0}, // S_SKEL_RUN6 {SPR_SKEL,3,2,{A_Chase},S_SKEL_RUN8,0,0}, // S_SKEL_RUN7 {SPR_SKEL,3,2,{A_Chase},S_SKEL_RUN9,0,0}, // S_SKEL_RUN8 {SPR_SKEL,4,2,{A_Chase},S_SKEL_RUN10,0,0}, // S_SKEL_RUN9 {SPR_SKEL,4,2,{A_Chase},S_SKEL_RUN11,0,0}, // S_SKEL_RUN10 {SPR_SKEL,5,2,{A_Chase},S_SKEL_RUN12,0,0}, // S_SKEL_RUN11 {SPR_SKEL,5,2,{A_Chase},S_SKEL_RUN1,0,0}, // S_SKEL_RUN12 {SPR_SKEL,6,0,{A_FaceTarget},S_SKEL_FIST2,0,0}, // S_SKEL_FIST1 {SPR_SKEL,6,6,{A_SkelWhoosh},S_SKEL_FIST3,0,0}, // S_SKEL_FIST2 {SPR_SKEL,7,6,{A_FaceTarget},S_SKEL_FIST4,0,0}, // S_SKEL_FIST3 {SPR_SKEL,8,6,{A_SkelFist},S_SKEL_RUN1,0,0}, // S_SKEL_FIST4 {SPR_SKEL,32777,0,{A_FaceTarget},S_SKEL_MISS2,0,0}, // S_SKEL_MISS1 {SPR_SKEL,32777,10,{A_FaceTarget},S_SKEL_MISS3,0,0}, // S_SKEL_MISS2 {SPR_SKEL,10,10,{A_SkelMissile},S_SKEL_MISS4,0,0}, // S_SKEL_MISS3 {SPR_SKEL,10,10,{A_FaceTarget},S_SKEL_RUN1,0,0}, // S_SKEL_MISS4 {SPR_SKEL,11,5,{NULL},S_SKEL_PAIN2,0,0}, // S_SKEL_PAIN {SPR_SKEL,11,5,{A_Pain},S_SKEL_RUN1,0,0}, // S_SKEL_PAIN2 {SPR_SKEL,11,7,{NULL},S_SKEL_DIE2,0,0}, // S_SKEL_DIE1 {SPR_SKEL,12,7,{NULL},S_SKEL_DIE3,0,0}, // S_SKEL_DIE2 {SPR_SKEL,13,7,{A_Scream},S_SKEL_DIE4,0,0}, // S_SKEL_DIE3 {SPR_SKEL,14,7,{A_Fall},S_SKEL_DIE5,0,0}, // S_SKEL_DIE4 {SPR_SKEL,15,7,{NULL},S_SKEL_DIE6,0,0}, // S_SKEL_DIE5 {SPR_SKEL,16,-1,{NULL},S_NULL,0,0}, // S_SKEL_DIE6 {SPR_SKEL,16,5,{NULL},S_SKEL_RAISE2,0,0}, // S_SKEL_RAISE1 {SPR_SKEL,15,5,{NULL},S_SKEL_RAISE3,0,0}, // S_SKEL_RAISE2 {SPR_SKEL,14,5,{NULL},S_SKEL_RAISE4,0,0}, // S_SKEL_RAISE3 {SPR_SKEL,13,5,{NULL},S_SKEL_RAISE5,0,0}, // S_SKEL_RAISE4 {SPR_SKEL,12,5,{NULL},S_SKEL_RAISE6,0,0}, // S_SKEL_RAISE5 {SPR_SKEL,11,5,{NULL},S_SKEL_RUN1,0,0}, // S_SKEL_RAISE6 {SPR_MANF,32768,4,{NULL},S_FATSHOT2,0,0}, // S_FATSHOT1 {SPR_MANF,32769,4,{NULL},S_FATSHOT1,0,0}, // S_FATSHOT2 {SPR_MISL,32769,8,{NULL},S_FATSHOTX2,0,0}, // S_FATSHOTX1 {SPR_MISL,32770,6,{NULL},S_FATSHOTX3,0,0}, // S_FATSHOTX2 {SPR_MISL,32771,4,{NULL},S_NULL,0,0}, // S_FATSHOTX3 {SPR_FATT,0,15,{A_Look},S_FATT_STND2,0,0}, // S_FATT_STND {SPR_FATT,1,15,{A_Look},S_FATT_STND,0,0}, // S_FATT_STND2 {SPR_FATT,0,4,{A_Chase},S_FATT_RUN2,0,0}, // S_FATT_RUN1 {SPR_FATT,0,4,{A_Chase},S_FATT_RUN3,0,0}, // S_FATT_RUN2 {SPR_FATT,1,4,{A_Chase},S_FATT_RUN4,0,0}, // S_FATT_RUN3 {SPR_FATT,1,4,{A_Chase},S_FATT_RUN5,0,0}, // S_FATT_RUN4 {SPR_FATT,2,4,{A_Chase},S_FATT_RUN6,0,0}, // S_FATT_RUN5 {SPR_FATT,2,4,{A_Chase},S_FATT_RUN7,0,0}, // S_FATT_RUN6 {SPR_FATT,3,4,{A_Chase},S_FATT_RUN8,0,0}, // S_FATT_RUN7 {SPR_FATT,3,4,{A_Chase},S_FATT_RUN9,0,0}, // S_FATT_RUN8 {SPR_FATT,4,4,{A_Chase},S_FATT_RUN10,0,0}, // S_FATT_RUN9 {SPR_FATT,4,4,{A_Chase},S_FATT_RUN11,0,0}, // S_FATT_RUN10 {SPR_FATT,5,4,{A_Chase},S_FATT_RUN12,0,0}, // S_FATT_RUN11 {SPR_FATT,5,4,{A_Chase},S_FATT_RUN1,0,0}, // S_FATT_RUN12 {SPR_FATT,6,20,{A_FatRaise},S_FATT_ATK2,0,0}, // S_FATT_ATK1 {SPR_FATT,32775,10,{A_FatAttack1},S_FATT_ATK3,0,0}, // S_FATT_ATK2 {SPR_FATT,8,5,{A_FaceTarget},S_FATT_ATK4,0,0}, // S_FATT_ATK3 {SPR_FATT,6,5,{A_FaceTarget},S_FATT_ATK5,0,0}, // S_FATT_ATK4 {SPR_FATT,32775,10,{A_FatAttack2},S_FATT_ATK6,0,0}, // S_FATT_ATK5 {SPR_FATT,8,5,{A_FaceTarget},S_FATT_ATK7,0,0}, // S_FATT_ATK6 {SPR_FATT,6,5,{A_FaceTarget},S_FATT_ATK8,0,0}, // S_FATT_ATK7 {SPR_FATT,32775,10,{A_FatAttack3},S_FATT_ATK9,0,0}, // S_FATT_ATK8 {SPR_FATT,8,5,{A_FaceTarget},S_FATT_ATK10,0,0}, // S_FATT_ATK9 {SPR_FATT,6,5,{A_FaceTarget},S_FATT_RUN1,0,0}, // S_FATT_ATK10 {SPR_FATT,9,3,{NULL},S_FATT_PAIN2,0,0}, // S_FATT_PAIN {SPR_FATT,9,3,{A_Pain},S_FATT_RUN1,0,0}, // S_FATT_PAIN2 {SPR_FATT,10,6,{NULL},S_FATT_DIE2,0,0}, // S_FATT_DIE1 {SPR_FATT,11,6,{A_Scream},S_FATT_DIE3,0,0}, // S_FATT_DIE2 {SPR_FATT,12,6,{A_Fall},S_FATT_DIE4,0,0}, // S_FATT_DIE3 {SPR_FATT,13,6,{NULL},S_FATT_DIE5,0,0}, // S_FATT_DIE4 {SPR_FATT,14,6,{NULL},S_FATT_DIE6,0,0}, // S_FATT_DIE5 {SPR_FATT,15,6,{NULL},S_FATT_DIE7,0,0}, // S_FATT_DIE6 {SPR_FATT,16,6,{NULL},S_FATT_DIE8,0,0}, // S_FATT_DIE7 {SPR_FATT,17,6,{NULL},S_FATT_DIE9,0,0}, // S_FATT_DIE8 {SPR_FATT,18,6,{NULL},S_FATT_DIE10,0,0}, // S_FATT_DIE9 {SPR_FATT,19,-1,{A_BossDeath},S_NULL,0,0}, // S_FATT_DIE10 {SPR_FATT,17,5,{NULL},S_FATT_RAISE2,0,0}, // S_FATT_RAISE1 {SPR_FATT,16,5,{NULL},S_FATT_RAISE3,0,0}, // S_FATT_RAISE2 {SPR_FATT,15,5,{NULL},S_FATT_RAISE4,0,0}, // S_FATT_RAISE3 {SPR_FATT,14,5,{NULL},S_FATT_RAISE5,0,0}, // S_FATT_RAISE4 {SPR_FATT,13,5,{NULL},S_FATT_RAISE6,0,0}, // S_FATT_RAISE5 {SPR_FATT,12,5,{NULL},S_FATT_RAISE7,0,0}, // S_FATT_RAISE6 {SPR_FATT,11,5,{NULL},S_FATT_RAISE8,0,0}, // S_FATT_RAISE7 {SPR_FATT,10,5,{NULL},S_FATT_RUN1,0,0}, // S_FATT_RAISE8 {SPR_CPOS,0,10,{A_Look},S_CPOS_STND2,0,0}, // S_CPOS_STND {SPR_CPOS,1,10,{A_Look},S_CPOS_STND,0,0}, // S_CPOS_STND2 {SPR_CPOS,0,3,{A_Chase},S_CPOS_RUN2,0,0}, // S_CPOS_RUN1 {SPR_CPOS,0,3,{A_Chase},S_CPOS_RUN3,0,0}, // S_CPOS_RUN2 {SPR_CPOS,1,3,{A_Chase},S_CPOS_RUN4,0,0}, // S_CPOS_RUN3 {SPR_CPOS,1,3,{A_Chase},S_CPOS_RUN5,0,0}, // S_CPOS_RUN4 {SPR_CPOS,2,3,{A_Chase},S_CPOS_RUN6,0,0}, // S_CPOS_RUN5 {SPR_CPOS,2,3,{A_Chase},S_CPOS_RUN7,0,0}, // S_CPOS_RUN6 �� {SPR_CPOS,3,3,{A_Chase},S_CPOS_RUN8,0,0}, // S_CPOS_RUN7 {SPR_CPOS,3,3,{A_Chase},S_CPOS_RUN1,0,0}, // S_CPOS_RUN8 {SPR_CPOS,4,10,{A_FaceTarget},S_CPOS_ATK2,0,0}, // S_CPOS_ATK1 {SPR_CPOS,32773,4,{A_CPosAttack},S_CPOS_ATK3,0,0}, // S_CPOS_ATK2 {SPR_CPOS,32772,4,{A_CPosAttack},S_CPOS_ATK4,0,0}, // S_CPOS_ATK3 {SPR_CPOS,5,1,{A_CPosRefire},S_CPOS_ATK2,0,0}, // S_CPOS_ATK4 {SPR_CPOS,6,3,{NULL},S_CPOS_PAIN2,0,0}, // S_CPOS_PAIN {SPR_CPOS,6,3,{A_Pain},S_CPOS_RUN1,0,0}, // S_CPOS_PAIN2 {SPR_CPOS,7,5,{NULL},S_CPOS_DIE2,0,0}, // S_CPOS_DIE1 {SPR_CPOS,8,5,{A_Scream},S_CPOS_DIE3,0,0}, // S_CPOS_DIE2 {SPR_CPOS,9,5,{A_Fall},S_CPOS_DIE4,0,0}, // S_CPOS_DIE3 {SPR_CPOS,10,5,{NULL},S_CPOS_DIE5,0,0}, // S_CPOS_DIE4 {SPR_CPOS,11,5,{NULL},S_CPOS_DIE6,0,0}, // S_CPOS_DIE5 {SPR_CPOS,12,5,{NULL},S_CPOS_DIE7,0,0}, // S_CPOS_DIE6 {SPR_CPOS,13,-1,{NULL},S_NULL,0,0}, // S_CPOS_DIE7 {SPR_CPOS,14,5,{NULL},S_CPOS_XDIE2,0,0}, // S_CPOS_XDIE1 {SPR_CPOS,15,5,{A_XScream},S_CPOS_XDIE3,0,0}, // S_CPOS_XDIE2 {SPR_CPOS,16,5,{A_Fall},S_CPOS_XDIE4,0,0}, // S_CPOS_XDIE3 {SPR_CPOS,17,5,{NULL},S_CPOS_XDIE5,0,0}, // S_CPOS_XDIE4 {SPR_CPOS,18,5,{NULL},S_CPOS_XDIE6,0,0}, // S_CPOS_XDIE5 {SPR_CPOS,19,-1,{NULL},S_NULL,0,0}, // S_CPOS_XDIE6 {SPR_CPOS,13,5,{NULL},S_CPOS_RAISE2,0,0}, // S_CPOS_RAISE1 {SPR_CPOS,12,5,{NULL},S_CPOS_RAISE3,0,0}, // S_CPOS_RAISE2 {SPR_CPOS,11,5,{NULL},S_CPOS_RAISE4,0,0}, // S_CPOS_RAISE3 {SPR_CPOS,10,5,{NULL},S_CPOS_RAISE5,0,0}, // S_CPOS_RAISE4 {SPR_CPOS,9,5,{NULL},S_CPOS_RAISE6,0,0}, // S_CPOS_RAISE5 {SPR_CPOS,8,5,{NULL},S_CPOS_RAISE7,0,0}, // S_CPOS_RAISE6 {SPR_CPOS,7,5,{NULL},S_CPOS_RUN1,0,0}, // S_CPOS_RAISE7 {SPR_TROO,0,10,{A_Look},S_TROO_STND2,0,0}, // S_TROO_STND {SPR_TROO,1,10,{A_Look},S_TROO_STND,0,0}, // S_TROO_STND2 {SPR_TROO,0,3,{A_Chase},S_TROO_RUN2,0,0}, // S_TROO_RUN1 {SPR_TROO,0,3,{A_Chase},S_TROO_RUN3,0,0}, // S_TROO_RUN2 {SPR_TROO,1,3,{A_Chase},S_TROO_RUN4,0,0}, // S_TROO_RUN3 {SPR_TROO,1,3,{A_Chase},S_TROO_RUN5,0,0}, // S_TROO_RUN4 {SPR_TROO,2,3,{A_Chase},S_TROO_RUN6,0,0}, // S_TROO_RUN5 {SPR_TROO,2,3,{A_Chase},S_TROO_RUN7,0,0}, // S_TROO_RUN6 {SPR_TROO,3,3,{A_Chase},S_TROO_RUN8,0,0}, // S_TROO_RUN7 {SPR_TROO,3,3,{A_Chase},S_TROO_RUN1,0,0}, // S_TROO_RUN8 {SPR_TROO,4,8,{A_FaceTarget},S_TROO_ATK2,0,0}, // S_TROO_ATK1 {SPR_TROO,5,8,{A_FaceTarget},S_TROO_ATK3,0,0}, // S_TROO_ATK2 {SPR_TROO,6,6,{A_TroopAttack},S_TROO_RUN1,0,0}, // S_TROO_ATK3 {SPR_TROO,7,2,{NULL},S_TROO_PAIN2,0,0}, // S_TROO_PAIN {SPR_TROO,7,2,{A_Pain},S_TROO_RUN1,0,0}, // S_TROO_PAIN2 {SPR_TROO,8,8,{NULL},S_TROO_DIE2,0,0}, // S_TROO_DIE1 {SPR_TROO,9,8,{A_Scream},S_TROO_DIE3,0,0}, // S_TROO_DIE2 {SPR_TROO,10,6,{NULL},S_TROO_DIE4,0,0}, // S_TROO_DIE3 {SPR_TROO,11,6,{A_Fall},S_TROO_DIE5,0,0}, // S_TROO_DIE4 {SPR_TROO,12,-1,{NULL},S_NULL,0,0}, // S_TROO_DIE5 {SPR_TROO,13,5,{NULL},S_TROO_XDIE2,0,0}, // S_TROO_XDIE1 {SPR_TROO,14,5,{A_XScream},S_TROO_XDIE3,0,0}, // S_TROO_XDIE2 {SPR_TROO,15,5,{NULL},S_TROO_XDIE4,0,0}, // S_TROO_XDIE3 {SPR_TROO,16,5,{A_Fall},S_TROO_XDIE5,0,0}, // S_TROO_XDIE4 {SPR_TROO,17,5,{NULL},S_TROO_XDIE6,0,0}, // S_TROO_XDIE5 {SPR_TROO,18,5,{NULL},S_TROO_XDIE7,0,0}, // S_TROO_XDIE6 {SPR_TROO,19,5,{NULL},S_TROO_XDIE8,0,0}, // S_TROO_XDIE7 {SPR_TROO,20,-1,{NULL},S_NULL,0,0}, // S_TROO_XDIE8 {SPR_TROO,12,8,{NULL},S_TROO_RAISE2,0,0}, // S_TROO_RAISE1 {SPR_TROO,11,8,{NULL},S_TROO_RAISE3,0,0}, // S_TROO_RAISE2 {SPR_TROO,10,6,{NULL},S_TROO_RAISE4,0,0}, // S_TROO_RAISE3 {SPR_TROO,9,6,{NULL},S_TROO_RAISE5,0,0}, // S_TROO_RAISE4 {SPR_TROO,8,6,{NULL},S_TROO_RUN1,0,0}, // S_TROO_RAISE5 {SPR_SARG,0,10,{A_Look},S_SARG_STND2,0,0}, // S_SARG_STND {SPR_SARG,1,10,{A_Look},S_SARG_STND,0,0}, // S_SARG_STND2 {SPR_SARG,0,2,{A_Chase},S_SARG_RUN2,0,0}, // S_SARG_RUN1 {SPR_SARG,0,2,{A_Chase},S_SARG_RUN3,0,0}, // S_SARG_RUN2 {SPR_SARG,1,2,{A_Chase},S_SARG_RUN4,0,0}, // S_SARG_RUN3 {SPR_SARG,1,2,{A_Chase},S_SARG_RUN5,0,0}, // S_SARG_RUN4 {SPR_SARG,2,2,{A_Chase},S_SARG_RUN6,0,0}, // S_SARG_RUN5 {SPR_SARG,2,2,{A_Chase},S_SARG_RUN7,0,0}, // S_SARG_RUN6 {SPR_SARG,3,2,{A_Chase},S_SARG_RUN8,0,0}, // S_SARG_RUN7 {SPR_SARG,3,2,{A_Chase},S_SARG_RUN1,0,0}, // S_SARG_RUN8 {SPR_SARG,4,8,{A_FaceTarget},S_SARG_ATK2,0,0}, // S_SARG_ATK1 {SPR_SARG,5,8,{A_FaceTarget},S_SARG_ATK3,0,0}, // S_SARG_ATK2 {SPR_SARG,6,8,{A_SargAttack},S_SARG_RUN1,0,0}, // S_SARG_ATK3 {SPR_SARG,7,2,{NULL},S_SARG_PAIN2,0,0}, // S_SARG_PAIN {SPR_SARG,7,2,{A_Pain},S_SARG_RUN1,0,0}, // S_SARG_PAIN2 {SPR_SARG,8,8,{NULL},S_SARG_DIE2,0,0}, // S_SARG_DIE1 {SPR_SARG,9,8,{A_Scream},S_SARG_DIE3,0,0}, // S_SARG_DIE2 {SPR_SARG,10,4,{NULL},S_SARG_DIE4,0,0}, // S_SARG_DIE3 {SPR_SARG,11,4,{A_Fall},S_SARG_DIE5,0,0}, // S_SARG_DIE4 {SPR_SARG,12,4,{NULL},S_SARG_DIE6,0,0}, // S_SARG_DIE5 {SPR_SARG,13,-1,{NULL},S_NULL,0,0}, // S_SARG_DIE6 {SPR_SARG,13,5,{NULL},S_SARG_RAISE2,0,0}, // S_SARG_RAISE1 {SPR_SARG,12,5,{NULL},S_SARG_RAISE3,0,0}, // S_SARG_RAISE2 {SPR_SARG,11,5,{NULL},S_SARG_RAISE4,0,0}, // S_SARG_RAISE3 {SPR_SARG,10,5,{NULL},S_SARG_RAISE5,0,0}, // S_SARG_RAISE4 {SPR_SARG,9,5,{NULL},S_SARG_RAISE6,0,0}, // S_SARG_RAISE5 {SPR_SARG,8,5,{NULL},S_SARG_RUN1,0,0}, // S_SARG_RAISE6 {SPR_HEAD,0,10,{A_Look},S_HEAD_STND,0,0}, // S_HEAD_STND {SPR_HEAD,0,3,{A_Chase},S_HEAD_RUN1,0,0}, // S_HEAD_RUN1 {SPR_HEAD,1,5,{A_FaceTarget},S_HEAD_ATK2,0,0}, // S_HEAD_ATK1 {SPR_HEAD,2,5,{A_FaceTarget},S_HEAD_ATK3,0,0}, // S_HEAD_ATK2 {SPR_HEAD,32771,5,{A_HeadAttack},S_HEAD_RUN1,0,0}, // S_HEAD_ATK3 {SPR_HEAD,4,3,{NULL},S_HEAD_PAIN2,0,0}, // S_HEAD_PAIN {SPR_HEAD,4,3,{A_Pain},S_HEAD_PAIN3,0,0}, // S_HEAD_PAIN2 {SPR_HEAD,5,6,{NULL},S_HEAD_RUN1,0,0}, // S_HEAD_PAIN3 {SPR_HEAD,6,8,{NULL},S_HEAD_DIE2,0,0}, // S_HEAD_DIE1 {SPR_HEAD,7,8,{A_Scream},S_HEAD_DIE3,0,0}, // S_HEAD_DIE2 {SPR_HEAD,8,8,{NULL},S_HEAD_DIE4,0,0}, // S_HEAD_DIE3 {SPR_HEAD,9,8,{NULL},S_HEAD_DIE5,0,0}, // S_HEAD_DIE4 {SPR_HEAD,10,8,{A_Fall},S_HEAD_DIE6,0,0}, // S_HEAD_DIE5 {SPR_HEAD,11,-1,{NULL},S_NULL,0,0}, // S_HEAD_DIE6 {SPR_HEAD,11,8,{NULL},S_HEAD_RAISE2,0,0}, // S_HEAD_RAISE1 {SPR_HEAD,10,8,{NULL},S_HEAD_RAISE3,0,0}, // S_HEAD_RAISE2 {SPR_HEAD,9,8,{NULL},S_HEAD_RAISE4,0,0}, // S_HEAD_RAISE3 {SPR_HEAD,8,8,{NULL},S_HEAD_RAISE5,0,0}, // S_HEAD_RAISE4 {SPR_HEAD,7,8,{NULL},S_HEAD_RAISE6,0,0}, // S_HEAD_RAISE5 {SPR_HEAD,6,8,{NULL},S_HEAD_RUN1,0,0}, // S_HEAD_RAISE6 {SPR_BAL7,32768,4,{NULL},S_BRBALL2,0,0}, // S_BRBALL1 {SPR_BAL7,32769,4,{NULL},S_BRBALL1,0,0}, // S_BRBALL2 {SPR_BAL7,32770,6,{NULL},S_BRBALLX2,0,0}, // S_BRBALLX1 {SPR_BAL7,32771,6,{NULL},S_BRBALLX3,0,0}, // S_BRBALLX2 {SPR_BAL7,32772,6,{NULL},S_NULL,0,0}, // S_BRBALLX3 {SPR_BOSS,0,10,{A_Look},S_BOSS_STND2,0,0}, // S_BOSS_STND {SPR_BOSS,1,10,{A_Look},S_BOSS_STND,0,0}, // S_BOSS_STND2 {SPR_BOSS,0,3,{A_Chase},S_BOSS_RUN2,0,0}, // S_BOSS_RUN1 {SPR_BOSS,0,3,{A_Chase},S_BOSS_RUN3,0,0}, // S_BOSS_RUN2 {SPR_BOSS,1,3,{A_Chase},S_BOSS_RUN4,0,0}, // S_BOSS_RUN3 {SPR_BOSS,1,3,{A_Chase},S_BOSS_RUN5,0,0}, // S_BOSS_RUN4 {SPR_BOSS,2,3,{A_Chase},S_BOSS_RUN6,0,0}, // S_BOSS_RUN5 {SPR_BOSS,2,3,{A_Chase},S_BOSS_RUN7,0,0}, // S_BOSS_RUN6 {SPR_BOSS,3,3,{A_Chase},S_BOSS_RUN8,0,0}, // S_BOSS_RUN7 {SPR_BOSS,3,3,{A_Chase},S_BOSS_RUN1,0,0}, // S_BOSS_RUN8 {SPR_BOSS,4,8,{A_FaceTarget},S_BOSS_ATK2,0,0}, // S_BOSS_ATK1 {SPR_BOSS,5,8,{A_FaceTarget},S_BOSS_ATK3,0,0}, // S_BOSS_ATK2 {SPR_BOSS,6,8,{A_BruisAttack},S_BOSS_RUN1,0,0}, // S_BOSS_ATK3 {SPR_BOSS,7,2,{NULL},S_BOSS_PAIN2,0,0}, // S_BOSS_PAIN {SPR_BOSS,7,2,{A_Pain},S_BOSS_RUN1,0,0}, // S_BOSS_PAIN2 {SPR_BOSS,8,8,{NULL},S_BOSS_DIE2,0,0}, // S_BOSS_DIE1 {SPR_BOSS,9,8,{A_Scream},S_BOSS_DIE3,0,0}, // S_BOSS_DIE2 {SPR_BOSS,10,8,{NULL},S_BOSS_DIE4,0,0}, // S_BOSS_DIE3 {SPR_BOSS,11,8,{A_Fall},S_BOSS_DIE5,0,0}, // S_BOSS_DIE4 {SPR_BOSS,12,8,{NULL},S_BOSS_DIE6,0,0}, // S_BOSS_DIE5 {SPR_BOSS,13,8,{NULL},S_BOSS_DIE7,0,0}, // S_BOSS_DIE6 {SPR_BOSS,14,-1,{A_BossDeath},S_NULL,0,0}, // S_BOSS_DIE7 {SPR_BOSS,14,8,{NULL},S_BOSS_RAISE2,0,0}, // S_BOSS_RAISE1 {SPR_BOSS,13,8,{NULL},S_BOSS_RAISE3,0,0}, // S_BOSS_RAISE2 {SPR_BOSS,12,8,{NULL},S_BOSS_RAISE4,0,0}, // S_BOSS_RAISE3 {SPR_BOSS,11,8,{NULL},S_BOSS_RAISE5,0,0}, // S_BOSS_RAISE4 {SPR_BOSS,10,8,{NULL},S_BOSS_RAISE6,0,0}, // S_BOSS_RAISE5 {SPR_BOSS,9,8,{NULL},S_BOSS_RAISE7,0,0}, // S_BOSS_RAISE6 {SPR_BOSS,8,8,{NULL},S_BOSS_RUN1,0,0}, // S_BOSS_RAISE7 {SPR_BOS2,0,10,{A_Look},S_BOS2_STND2,0,0}, // S_BOS2_STND {SPR_BOS2,1,10,{A_Look},S_BOS2_STND,0,0}, // S_BOS2_STND2 {SPR_BOS2,0,3,{A_Chase},S_BOS2_RUN2,0,0}, // S_BOS2_RUN1 {SPR_BOS2,0,3,{A_Chase},S_BOS2_RUN3,0,0}, // S_BOS2_RUN2 {SPR_BOS2,1,3,{A_Chase},S_BOS2_RUN4,0,0}, // S_BOS2_RUN3 {SPR_BOS2,1,3,{A_Chase},S_BOS2_RUN5,0,0}, // S_BOS2_RUN4 {SPR_BOS2,2,3,{A_Chase},S_BOS2_RUN6,0,0}, // S_BOS2_RUN5 {SPR_BOS2,2,3,{A_Chase},S_BOS2_RUN7,0,0}, // S_BOS2_RUN6 {SPR_BOS2,3,3,{A_Chase},S_BOS2_RUN8,0,0}, // S_BOS2_RUN7 {SPR_BOS2,3,3,{A_Chase},S_BOS2_RUN1,0,0}, // S_BOS2_RUN8 {SPR_BOS2,4,8,{A_FaceTarget},S_BOS2_ATK2,0,0}, // S_BOS2_ATK1 {SPR_BOS2,5,8,{A_FaceTarget},S_BOS2_ATK3,0,0}, // S_BOS2_ATK2 {SPR_BOS2,6,8,{A_BruisAttack},S_BOS2_RUN1,0,0}, // S_BOS2_ATK3 {SPR_BOS2,7,2,{NULL},S_BOS2_PAIN2,0,0}, // S_BOS2_PAIN {SPR_BOS2,7,2,{A_Pain},S_BOS2_RUN1,0,0}, // S_BOS2_PAIN2 {SPR_BOS2,8,8,{NULL},S_BOS2_DIE2,0,0}, // S_BOS2_DIE1 {SPR_BOS2,9,8,{A_Scream},S_BOS2_DIE3,0,0}, // S_BOS2_DIE2 {SPR_BOS2,10,8,{NULL},S_BOS2_DIE4,0,0}, // S_BOS2_DIE3 {SPR_BOS2,11,8,{A_Fall},S_BOS2_DIE5,0,0}, // S_BOS2_DIE4 {SPR_BOS2,12,8,{NULL},S_BOS2_DIE6,0,0}, // S_BOS2_DIE5 {SPR_BOS2,13,8,{NULL},S_BOS2_DIE7,0,0}, // S_BOS2_DIE6 {SPR_BOS2,14,-1,{NULL},S_NULL,0,0}, // S_BOS2_DIE7 {SPR_BOS2,14,8,{NULL},S_BOS2_RAISE2,0,0}, // S_BOS2_RAISE1 {SPR_BOS2,13,8,{NULL},S_BOS2_RAISE3,0,0}, // S_BOS2_RAISE2 {SPR_BOS2,12,8,{NULL},S_BOS2_RAISE4,0,0}, // S_BOS2_RAISE3 {SPR_BOS2,11,8,{NULL},S_BOS2_RAISE5,0,0}, // S_BOS2_RAISE4 {SPR_BOS2,10,8,{NULL},S_BOS2_RAISE6,0,0}, // S_BOS2_RAISE5 {SPR_BOS2,9,8,{NULL},S_BOS2_RAISE7,0,0}, // S_BOS2_RAISE6 {SPR_BOS2,8,8,{NULL},S_BOS2_RUN1,0,0}, // S_BOS2_RAISE7 {SPR_SKUL,32768,10,{A_Look},S_SKULL_STND2,0,0}, // S_SKULL_STND {SPR_SKUL,32769,10,{A_Look},S_SKULL_STND,0,0}, // S_SKULL_STND2 {SPR_SKUL,32768,6,{A_Chase},S_SKULL_RUN2,0,0}, // S_SKULL_RUN1 {SPR_SKUL,32769,6,{A_Chase},S_SKULL_RUN1,0,0}, // S_SKULL_RUN2 {SPR_SKUL,32770,10,{A_FaceTarget},S_SKULL_ATK2,0,0}, // S_SKULL_ATK1 {SPR_SKUL,32771,4,{A_SkullAttack},S_SKULL_ATK3,0,0}, // S_SKULL_ATK2 {SPR_SKUL,32770,4,{NULL},S_SKULL_ATK4,0,0}, // S_SKULL_ATK3 {SPR_SKUL,32771,4,{NULL},S_SKULL_ATK3,0,0}, // S_SKULL_ATK4 {SPR_SKUL,32772,3,{NULL},S_SKULL_PAIN2,0,0}, // S_SKULL_PAIN {SPR_SKUL,32772,3,{A_Pain},S_SKULL_RUN1,0,0}, // S_SKULL_PAIN2 {SPR_SKUL,32773,6,{NULL},S_SKULL_DIE2,0,0}, // S_SKULL_DIE1 {SPR_SKUL,32774,6,{A_Scream},S_SKULL_DIE3,0,0}, // S_SKULL_DIE2 {SPR_SKUL,32775,6,{NULL},S_SKULL_DIE4,0,0}, // S_SKULL_DIE3 {SPR_SKUL,32776,6,{A_Fall},S_SKULL_DIE5,0,0}, // S_SKULL_DIE4 {SPR_SKUL,9,6,{NULL},S_SKULL_DIE6,0,0}, // S_SKULL_DIE5 {SPR_SKUL,10,6,{NULL},S_NULL,0,0}, // S_SKULL_DIE6 {SPR_SPID,0,10,{A_Look},S_SPID_STND2,0,0}, // S_SPID_STND {SPR_SPID,1,10,{A_Look},S_SPID_STND,0,0}, // S_SPID_STND2 {SPR_SPID,0,3,{A_Metal},S_SPID_RUN2,0,0}, // S_SPID_RUN1 {SPR_SPID,0,3,{A_Chase},S_SPID_RUN3,0,0}, // S_SPID_RUN2 {SPR_SPID,1,3,{A_Chase},S_SPID_RUN4,0,0}, // S_SPID_RUN3 {SPR_SPID,1,3,{A_Chase},S_SPID_RUN5,0,0}, // S_SPID_RUN4 {SPR_SPID,2,3,{A_Metal},S_SPID_RUN6,0,0}, // S_SPID_RUN5 {SPR_SPID,2,3,{A_Chase},S_SPID_RUN7,0,0}, // S_SPID_RUN6 {SPR_SPID,3,3,{A_Chase},S_SPID_RUN8,0,0}, // S_SPID_RUN7 {SPR_SPID,3,3,{A_Chase},S_SPID_RUN9,0,0}, // S_SPID_RUN8 {SPR_SPID,4,3,{A_Metal},S_SPID_RUN10,0,0}, // S_SPID_RUN9 {SPR_SPID,4,3,{A_Chase},S_SPID_RUN11,0,0}, // S_SPID_RUN10 {SPR_SPID,5,3,{A_Chase},S_SPID_RUN12,0,0}, // S_SPID_RUN11 {SPR_SPID,5,3,{A_Chase},S_SPID_RUN1,0,0}, // S_SPID_RUN12 {SPR_SPID,32768,20,{A_FaceTarget},S_SPID_ATK2,0,0}, // S_SPID_ATK1 {SPR_SPID,32774,4,{A_SPosAttack},S_SPID_ATK3,0,0}, // S_SPID_ATK2 {SPR_SPID,32775,4,{A_SPosAttack},S_SPID_ATK4,0,0}, // S_SPID_ATK3 {SPR_SPID,32775,1,{A_SpidRefire},S_SPID_ATK2,0,0}, // S_SPID_ATK4 {SPR_SPID,8,3,{NULL},S_SPID_PAIN2,0,0}, // S_SPID_PAIN {SPR_SPID,8,3,{A_Pain},S_SPID_RUN1,0,0}, // S_SPID_PAIN2 {SPR_SPID,9,20,{A_Scream},S_SPID_DIE2,0,0}, // S_SPID_DIE1 {SPR_SPID,10,10,{A_Fall},S_SPID_DIE3,0,0}, // S_SPID_DIE2 {SPR_SPID,11,10,{NULL},S_SPID_DIE4,0,0}, // S_SPID_DIE3 {SPR_SPID,12,10,{NULL},S_SPID_DIE5,0,0}, // S_SPID_DIE4 {SPR_SPID,13,10,{NULL},S_SPID_DIE6,0,0}, // S_SPID_DIE5 {SPR_SPID,14,10,{NULL},S_SPID_DIE7,0,0}, // S_SPID_DIE6 {SPR_SPID,15,10,{NULL},S_SPID_DIE8,0,0}, // S_SPID_DIE7 {SPR_SPID,16,10,{NULL},S_SPID_DIE9,0,0}, // S_SPID_DIE8 {SPR_SPID,17,10,{NULL},S_SPID_DIE10,0,0}, // S_SPID_DIE9 {SPR_SPID,18,30,{NULL},S_SPID_DIE11,0,0}, // S_SPID_DIE10 {SPR_SPID,18,-1,{A_BossDeath},S_NULL,0,0}, // S_SPID_DIE11 {SPR_BSPI,0,10,{A_Look},S_BSPI_STND2,0,0}, // S_BSPI_STND {SPR_BSPI,1,10,{A_Look},S_BSPI_STND,0,0}, // S_BSPI_STND2 {SPR_BSPI,0,20,{NULL},S_BSPI_RUN1,0,0}, // S_BSPI_SIGHT {SPR_BSPI,0,3,{A_BabyMetal},S_BSPI_RUN2,0,0}, // S_BSPI_RUN1 {SPR_BSPI,0,3,{A_Chase},S_BSPI_RUN3,0,0}, // S_BSPI_RUN2 {SPR_BSPI,1,3,{A_Chase},S_BSPI_RUN4,0,0}, // S_BSPI_RUN3 {SPR_BSPI,1,3,{A_Chase},S_BSPI_RUN5,0,0}, // S_BSPI_RUN4 {SPR_BSPI,2,3,{A_Chase},S_BSPI_RUN6,0,0}, // S_BSPI_RUN5 {SPR_BSPI,2,3,{A_Chase},S_BSPI_RUN7,0,0}, // S_BSPI_RUN6 {SPR_BSPI,3,3,{A_BabyMetal},S_BSPI_RUN8,0,0}, // S_BSPI_RUN7 {SPR_BSPI,3,3,{A_Chase},S_BSPI_RUN9,0,0}, // S_BSPI_RUN8 {SPR_BSPI,4,3,{A_Chase},S_BSPI_RUN10,0,0}, // S_BSPI_RUN9 {SPR_BSPI,4,3,{A_Chase},S_BSPI_RUN11,0,0}, // S_BSPI_RUN10 {SPR_BSPI,5,3,{A_Chase},S_BSPI_RUN12,0,0}, // S_BSPI_RUN11 {SPR_BSPI,5,3,{A_Chase},S_BSPI_RUN1,0,0}, // S_BSPI_RUN12 {SPR_BSPI,32768,20,{A_FaceTarget},S_BSPI_ATK2,0,0}, // S_BSPI_ATK1 {SPR_BSPI,32774,4,{A_BspiAttack},S_BSPI_ATK3,0,0}, // S_BSPI_ATK2 {SPR_BSPI,32775,4,{NULL},S_BSPI_ATK4,0,0}, // S_BSPI_ATK3 {SPR_BSPI,32775,1,{A_SpidRefire},S_BSPI_ATK2,0,0}, // S_BSPI_ATK4 {SPR_BSPI,8,3,{NULL},S_BSPI_PAIN2,0,0}, // S_BSPI_PAIN {SPR_BSPI,8,3,{A_Pain},S_BSPI_RUN1,0,0}, // S_BSPI_PAIN2 {SPR_BSPI,9,20,{A_Scream},S_BSPI_DIE2,0,0}, // S_BSPI_DIE1 {SPR_BSPI,10,7,{A_Fall},S_BSPI_DIE3,0,0}, // S_BSPI_DIE2 {SPR_BSPI,11,7,{NULL},S_BSPI_DIE4,0,0}, // S_BSPI_DIE3 {SPR_BSPI,12,7,{NULL},S_BSPI_DIE5,0,0}, // S_BSPI_DIE4 {SPR_BSPI,13,7,{NULL},S_BSPI_DIE6,0,0}, // S_BSPI_DIE5 {SPR_BSPI,14,7,{NULL},S_BSPI_DIE7,0,0}, // S_BSPI_DIE6 {SPR_BSPI,15,-1,{A_BossDeath},S_NULL,0,0}, // S_BSPI_DIE7 {SPR_BSPI,15,5,{NULL},S_BSPI_RAISE2,0,0}, // S_BSPI_RAISE1 {SPR_BSPI,14,5,{NULL},S_BSPI_RAISE3,0,0}, // S_BSPI_RAISE2 {SPR_BSPI,13,5,{NULL},S_BSPI_RAISE4,0,0}, // S_BSPI_RAISE3 {SPR_BSPI,12,5,{NULL},S_BSPI_RAISE5,0,0}, // S_BSPI_RAISE4 {SPR_BSPI,11,5,{NULL},S_BSPI_RAISE6,0,0}, // S_BSPI_RAISE5 {SPR_BSPI,10,5,{NULL},S_BSPI_RAISE7,0,0}, // S_BSPI_RAISE6 {SPR_BSPI,9,5,{NULL},S_BSPI_RUN1,0,0}, // S_BSPI_RAISE7 {SPR_APLS,32768,5,{NULL},S_ARACH_PLAZ2,0,0}, // S_ARACH_PLAZ {SPR_APLS,32769,5,{NULL},S_ARACH_PLAZ,0,0}, // S_ARACH_PLAZ2 {SPR_APBX,32768,5,{NULL},S_ARACH_PLEX2,0,0}, // S_ARACH_PLEX {SPR_APBX,32769,5,{NULL},S_ARACH_PLEX3,0,0}, // S_ARACH_PLEX2 {SPR_APBX,32770,5,{NULL},S_ARACH_PLEX4,0,0}, // S_ARACH_PLEX3 {SPR_APBX,32771,5,{NULL},S_ARACH_PLEX5,0,0}, // S_ARACH_PLEX4 {SPR_APBX,32772,5,{NULL},S_NULL,0,0}, // S_ARACH_PLEX5 {SPR_CYBR,0,10,{A_Look},S_CYBER_STND2,0,0}, // S_CYBER_STND {SPR_CYBR,1,10,{A_Look},S_CYBER_STND,0,0}, // S_CYBER_STND2 {SPR_CYBR,0,3,{A_Hoof},S_CYBER_RUN2,0,0}, // S_CYBER_RUN1 {SPR_CYBR,0,3,{A_Chase},S_CYBER_RUN3,0,0}, // S_CYBER_RUN2 {SPR_CYBR,1,3,{A_Chase},S_CYBER_RUN4,0,0}, // S_CYBER_RUN3 {SPR_CYBR,1,3,{A_Chase},S_CYBER_RUN5,0,0}, // S_CYBER_RUN4 {SPR_CYBR,2,3,{A_Chase},S_CYBER_RUN6,0,0}, // S_CYBER_RUN5 {SPR_CYBR,2,3,{A_Chase},S_CYBER_RUN7,0,0}, // S_CYBER_RUN6 {SPR_CYBR,3,3,{A_Metal},S_CYBER_RUN8,0,0}, // S_CYBER_RUN7 {SPR_CYBR,3,3,{A_Chase},S_CYBER_RUN1,0,0}, // S_CYBER_RUN8 {SPR_CYBR,4,6,{A_FaceTarget},S_CYBER_ATK2,0,0}, // S_CYBER_ATK1 {SPR_CYBR,5,12,{A_CyberAttack},S_CYBER_ATK3,0,0}, // S_CYBER_ATK2 {SPR_CYBR,4,12,{A_FaceTarget},S_CYBER_ATK4,0,0}, // S_CYBER_ATK3 {SPR_CYBR,5,12,{A_CyberAttack},S_CYBER_ATK5,0,0}, // S_CYBER_ATK4 {SPR_CYBR,4,12,{A_FaceTarget},S_CYBER_ATK6,0,0}, // S_CYBER_ATK5 {SPR_CYBR,5,12,{A_CyberAttack},S_CYBER_RUN1,0,0}, // S_CYBER_ATK6 {SPR_CYBR,6,10,{A_Pain},S_CYBER_RUN1,0,0}, // S_CYBER_PAIN {SPR_CYBR,7,10,{NULL},S_CYBER_DIE2,0,0}, // S_CYBER_DIE1 {SPR_CYBR,8,10,{A_Scream},S_CYBER_DIE3,0,0}, // S_CYBER_DIE2 {SPR_CYBR,9,10,{NULL},S_CYBER_DIE4,0,0}, // S_CYBER_DIE3 {SPR_CYBR,10,10,{NULL},S_CYBER_DIE5,0,0}, // S_CYBER_DIE4 {SPR_CYBR,11,10,{NULL},S_CYBER_DIE6,0,0}, // S_CYBER_DIE5 {SPR_CYBR,12,10,{A_Fall},S_CYBER_DIE7,0,0}, // S_CYBER_DIE6 {SPR_CYBR,13,10,{NULL},S_CYBER_DIE8,0,0}, // S_CYBER_DIE7 {SPR_CYBR,14,10,{NULL},S_CYBER_DIE9,0,0}, // S_CYBER_DIE8 {SPR_CYBR,15,30,{NULL},S_CYBER_DIE10,0,0}, // S_CYBER_DIE9 {SPR_CYBR,15,-1,{A_BossDeath},S_NULL,0,0}, // S_CYBER_DIE10 {SPR_PAIN,0,10,{A_Look},S_PAIN_STND,0,0}, // S_PAIN_STND {SPR_PAIN,0,3,{A_Chase},S_PAIN_RUN2,0,0}, // S_PAIN_RUN1 {SPR_PAIN,0,3,{A_Chase},S_PAIN_RUN3,0,0}, // S_PAIN_RUN2 {SPR_PAIN,1,3,{A_Chase},S_PAIN_RUN4,0,0}, // S_PAIN_RUN3 {SPR_PAIN,1,3,{A_Chase},S_PAIN_RUN5,0,0}, // S_PAIN_RUN4 {SPR_PAIN,2,3,{A_Chase},S_PAIN_RUN6,0,0}, // S_PAIN_RUN5 {SPR_PAIN,2,3,{A_Chase},S_PAIN_RUN1,0,0}, // S_PAIN_RUN6 {SPR_PAIN,3,5,{A_FaceTarget},S_PAIN_ATK2,0,0}, // S_PAIN_ATK1 {SPR_PAIN,4,5,{A_FaceTarget},S_PAIN_ATK3,0,0}, // S_PAIN_ATK2 {SPR_PAIN,32773,5,{A_FaceTarget},S_PAIN_ATK4,0,0}, // S_PAIN_ATK3 {SPR_PAIN,32773,0,{A_PainAttack},S_PAIN_RUN1,0,0}, // S_PAIN_ATK4 {SPR_PAIN,6,6,{NULL},S_PAIN_PAIN2,0,0}, // S_PAIN_PAIN {SPR_PAIN,6,6,{A_Pain},S_PAIN_RUN1,0,0}, // S_PAIN_PAIN2 {SPR_PAIN,32775,8,{NULL},S_PAIN_DIE2,0,0}, // S_PAIN_DIE1 {SPR_PAIN,32776,8,{A_Scream},S_PAIN_DIE3,0,0}, // S_PAIN_DIE2 {SPR_PAIN,32777,8,{NULL},S_PAIN_DIE4,0,0}, // S_PAIN_DIE3 {SPR_PAIN,32778,8,{NULL},S_PAIN_DIE5,0,0}, // S_PAIN_DIE4 {SPR_PAIN,32779,8,{A_PainDie},S_PAIN_DIE6,0,0}, // S_PAIN_DIE5 {SPR_PAIN,32780,8,{NULL},S_NULL,0,0}, // S_PAIN_DIE6 {SPR_PAIN,12,8,{NULL},S_PAIN_RAISE2,0,0}, // S_PAIN_RAISE1 {SPR_PAIN,11,8,{NULL},S_PAIN_RAISE3,0,0}, // S_PAIN_RAISE2 {SPR_PAIN,10,8,{NULL},S_PAIN_RAISE4,0,0}, // S_PAIN_RAISE3 {SPR_PAIN,9,8,{NULL},S_PAIN_RAISE5,0,0}, // S_PAIN_RAISE4 {SPR_PAIN,8,8,{NULL},S_PAIN_RAISE6,0,0}, // S_PAIN_RAISE5 {SPR_PAIN,7,8,{NULL},S_PAIN_RUN1,0,0}, // S_PAIN_RAISE6 {SPR_SSWV,0,10,{A_Look},S_SSWV_STND2,0,0}, // S_SSWV_STND {SPR_SSWV,1,10,{A_Look},S_SSWV_STND,0,0}, // S_SSWV_STND2 {SPR_SSWV,0,3,{A_Chase},S_SSWV_RUN2,0,0}, // S_SSWV_RUN1 {SPR_SSWV,0,3,{A_Chase},S_SSWV_RUN3,0,0}, // S_SSWV_RUN2 {SPR_SSWV,1,3,{A_Chase},S_SSWV_RUN4,0,0}, // S_SSWV_RUN3 {SPR_SSWV,1,3,{A_Chase},S_SSWV_RUN5,0,0}, // S_SSWV_RUN4 {SPR_SSWV,2,3,{A_Chase},S_SSWV_RUN6,0,0}, // S_SSWV_RUN5 {SPR_SSWV,2,3,{A_Chase},S_SSWV_RUN7,0,0}, // S_SSWV_RUN6 {SPR_SSWV,3,3,{A_Chase},S_SSWV_RUN8,0,0}, // S_SSWV_RUN7 {SPR_SSWV,3,3,{A_Chase},S_SSWV_RUN1,0,0}, // S_SSWV_RUN8 {SPR_SSWV,4,10,{A_FaceTarget},S_SSWV_ATK2,0,0}, // S_SSWV_ATK1 {SPR_SSWV,5,10,{A_FaceTarget},S_SSWV_ATK3,0,0}, // S_SSWV_ATK2 {SPR_SSWV,32774,4,{A_CPosAttack},S_SSWV_ATK4,0,0}, // S_SSWV_ATK3 {SPR_SSWV,5,6,{A_FaceTarget},S_SSWV_ATK5,0,0}, // S_SSWV_ATK4 {SPR_SSWV,32774,4,{A_CPosAttack},S_SSWV_ATK6,0,0}, // S_SSWV_ATK5 {SPR_SSWV,5,1,{A_CPosRefire},S_SSWV_ATK2,0,0}, // S_SSWV_ATK6 {SPR_SSWV,7,3,{NULL},S_SSWV_PAIN2,0,0}, // S_SSWV_PAIN {SPR_SSWV,7,3,{A_Pain},S_SSWV_RUN1,0,0}, // S_SSWV_PAIN2 {SPR_SSWV,8,5,{NULL},S_SSWV_DIE2,0,0}, // S_SSWV_DIE1 {SPR_SSWV,9,5,{A_Scream},S_SSWV_DIE3,0,0}, // S_SSWV_DIE2 {SPR_SSWV,10,5,{A_Fall},S_SSWV_DIE4,0,0}, // S_SSWV_DIE3 {SPR_SSWV,11,5,{NULL},S_SSWV_DIE5,0,0}, // S_SSWV_DIE4 {SPR_SSWV,12,-1,{NULL},S_NULL,0,0}, // S_SSWV_DIE5 {SPR_SSWV,13,5,{NULL},S_SSWV_XDIE2,0,0}, // S_SSWV_XDIE1 {SPR_SSWV,14,5,{A_XScream},S_SSWV_XDIE3,0,0}, // S_SSWV_XDIE2 {SPR_SSWV,15,5,{A_Fall},S_SSWV_XDIE4,0,0}, // S_SSWV_XDIE3 {SPR_SSWV,16,5,{NULL},S_SSWV_XDIE5,0,0}, // S_SSWV_XDIE4 {SPR_SSWV,17,5,{NULL},S_SSWV_XDIE6,0,0}, // S_SSWV_XDIE5 {SPR_SSWV,18,5,{NULL},S_SSWV_XDIE7,0,0}, // S_SSWV_XDIE6 {SPR_SSWV,19,5,{NULL},S_SSWV_XDIE8,0,0}, // S_SSWV_XDIE7 {SPR_SSWV,20,5,{NULL},S_SSWV_XDIE9,0,0}, // S_SSWV_XDIE8 {SPR_SSWV,21,-1,{NULL},S_NULL,0,0}, // S_SSWV_XDIE9 {SPR_SSWV,12,5,{NULL},S_SSWV_RAISE2,0,0}, // S_SSWV_RAISE1 {SPR_SSWV,11,5,{NULL},S_SSWV_RAISE3,0,0}, // S_SSWV_RAISE2 {SPR_SSWV,10,5,{NULL},S_SSWV_RAISE4,0,0}, // S_SSWV_RAISE3 {SPR_SSWV,9,5,{NULL},S_SSWV_RAISE5,0,0}, // S_SSWV_RAISE4 {SPR_SSWV,8,5,{NULL},S_SSWV_RUN1,0,0}, // S_SSWV_RAISE5 {SPR_KEEN,0,-1,{NULL},S_KEENSTND,0,0}, // S_KEENSTND {SPR_KEEN,0,6,{NULL},S_COMMKEEN2,0,0}, // S_COMMKEEN {SPR_KEEN,1,6,{NULL},S_COMMKEEN3,0,0}, // S_COMMKEEN2 {SPR_KEEN,2,6,{A_Scream},S_COMMKEEN4,0,0}, // S_COMMKEEN3 {SPR_KEEN,3,6,{NULL},S_COMMKEEN5,0,0}, // S_COMMKEEN4 {SPR_KEEN,4,6,{NULL},S_COMMKEEN6,0,0}, // S_COMMKEEN5 {SPR_KEEN,5,6,{NULL},S_COMMKEEN7,0,0}, // S_COMMKEEN6 {SPR_KEEN,6,6,{NULL},S_COMMKEEN8,0,0}, // S_COMMKEEN7 {SPR_KEEN,7,6,{NULL},S_COMMKEEN9,0,0}, // S_COMMKEEN8 {SPR_KEEN,8,6,{NULL},S_COMMKEEN10,0,0}, // S_COMMKEEN9 {SPR_KEEN,9,6,{NULL},S_COMMKEEN11,0,0}, // S_COMMKEEN10 {SPR_KEEN,10,6,{A_KeenDie},S_COMMKEEN12,0,0},// S_COMMKEEN11 {SPR_KEEN,11,-1,{NULL},S_NULL,0,0}, // S_COMMKEEN12 {SPR_KEEN,12,4,{NULL},S_KEENPAIN2,0,0}, // S_KEENPAIN {SPR_KEEN,12,8,{A_Pain},S_KEENSTND,0,0}, // S_KEENPAIN2 {SPR_BBRN,0,-1,{NULL},S_NULL,0,0}, // S_BRAIN {SPR_BBRN,1,36,{A_BrainPain},S_BRAIN,0,0}, // S_BRAIN_PAIN {SPR_BBRN,0,100,{A_BrainScream},S_BRAIN_DIE2,0,0}, // S_BRAIN_DIE1 {SPR_BBRN,0,10,{NULL},S_BRAIN_DIE3,0,0}, // S_BRAIN_DIE2 {SPR_BBRN,0,10,{NULL},S_BRAIN_DIE4,0,0}, // S_BRAIN_DIE3 {SPR_BBRN,0,-1,{A_BrainDie},S_NULL,0,0}, // S_BRAIN_DIE4 {SPR_SSWV,0,10,{A_Look},S_BRAINEYE,0,0}, // S_BRAINEYE {SPR_SSWV,0,181,{A_BrainAwake},S_BRAINEYE1,0,0}, // S_BRAINEYESEE {SPR_SSWV,0,150,{A_BrainSpit},S_BRAINEYE1,0,0}, // S_BRAINEYE1 {SPR_BOSF,32768,3,{A_SpawnSound},S_SPAWN2,0,0}, // S_SPAWN1 {SPR_BOSF,32769,3,{A_SpawnFly},S_SPAWN3,0,0}, // S_SPAWN2 {SPR_BOSF,32770,3,{A_SpawnFly},S_SPAWN4,0,0}, // S_SPAWN3 {SPR_BOSF,32771,3,{A_SpawnFly},S_SPAWN1,0,0}, // S_SPAWN4 {SPR_FIRE,32768,4,{A_Fire},S_SPAWNFIRE2,0,0}, // S_SPAWNFIRE1 {SPR_FIRE,32769,4,{A_Fire},S_SPAWNFIRE3,0,0}, // S_SPAWNFIRE2 {SPR_FIRE,32770,4,{A_Fire},S_SPAWNFIRE4,0,0}, // S_SPAWNFIRE3 {SPR_FIRE,32771,4,{A_Fire},S_SPAWNFIRE5,0,0}, // S_SPAWNFIRE4 {SPR_FIRE,32772,4,{A_Fire},S_SPAWNFIRE6,0,0}, // S_SPAWNFIRE5 {SPR_FIRE,32773,4,{A_Fire},S_SPAWNFIRE7,0,0}, // S_SPAWNFIRE6 {SPR_FIRE,32774,4,{A_Fire},S_SPAWNFIRE8,0,0}, // S_SPAWNFIRE7 {SPR_FIRE,32775,4,{A_Fire},S_NULL,0,0}, // S_SPAWNFIRE8 {SPR_MISL,32769,10,{NULL},S_BRAINEXPLODE2,0,0}, // S_BRAINEXPLODE1 {SPR_MISL,32770,10,{NULL},S_BRAINEXPLODE3,0,0}, // S_BRAINEXPLODE2 {SPR_MISL,32771,10,{A_BrainExplode},S_NULL,0,0}, // S_BRAINEXPLODE3 {SPR_ARM1,0,6,{NULL},S_ARM1A,0,0}, // S_ARM1 {SPR_ARM1,32769,7,{NULL},S_ARM1,0,0}, // S_ARM1A {SPR_ARM2,0,6,{NULL},S_ARM2A,0,0}, // S_ARM2 {SPR_ARM2,32769,6,{NULL},S_ARM2,0,0}, // S_ARM2A {SPR_BAR1,0,6,{NULL},S_BAR2,0,0}, // S_BAR1 {SPR_BAR1,1,6,{NULL},S_BAR1,0,0}, // S_BAR2 {SPR_BEXP,32768,5,{NULL},S_BEXP2,0,0}, // S_BEXP {SPR_BEXP,32769,5,{A_Scream},S_BEXP3,0,0}, // S_BEXP2 {SPR_BEXP,32770,5,{NULL},S_BEXP4,0,0}, // S_BEXP3 {SPR_BEXP,32771,10,{A_Explode},S_BEXP5,0,0}, // S_BEXP4 {SPR_BEXP,32772,10,{NULL},S_NULL,0,0}, // S_BEXP5 {SPR_FCAN,32768,4,{NULL},S_BBAR2,0,0}, // S_BBAR1 {SPR_FCAN,32769,4,{NULL},S_BBAR3,0,0}, // S_BBAR2 {SPR_FCAN,32770,4,{NULL},S_BBAR1,0,0}, // S_BBAR3 {SPR_BON1,0,6,{NULL},S_BON1A,0,0}, // S_BON1 {SPR_BON1,1,6,{NULL},S_BON1B,0,0}, // S_BON1A {SPR_BON1,2,6,{NULL},S_BON1C,0,0}, // S_BON1B {SPR_BON1,3,6,{NULL},S_BON1D,0,0}, // S_BON1C {SPR_BON1,2,6,{NULL},S_BON1E,0,0}, // S_BON1D {SPR_BON1,1,6,{NULL},S_BON1,0,0}, // S_BON1E {SPR_BON2,0,6,{NULL},S_BON2A,0,0}, // S_BON2 {SPR_BON2,1,6,{NULL},S_BON2B,0,0}, // S_BON2A {SPR_BON2,2,6,{NULL},S_BON2C,0,0}, // S_BON2B {SPR_BON2,3,6,{NULL},S_BON2D,0,0}, // S_BON2C {SPR_BON2,2,6,{NULL},S_BON2E,0,0}, // S_BON2D {SPR_BON2,1,6,{NULL},S_BON2,0,0}, // S_BON2E {SPR_BKEY,0,10,{NULL},S_BKEY2,0,0}, // S_BKEY {SPR_BKEY,32769,10,{NULL},S_BKEY,0,0}, // S_BKEY2 {SPR_RKEY,0,10,{NULL},S_RKEY2,0,0}, // S_RKEY {SPR_RKEY,32769,10,{NULL},S_RKEY,0,0}, // S_RKEY2 {SPR_YKEY,0,10,{NULL},S_YKEY2,0,0}, // S_YKEY {SPR_YKEY,32769,10,{NULL},S_YKEY,0,0}, // S_YKEY2 {SPR_BSKU,0,10,{NULL},S_BSKULL2,0,0}, // S_BSKULL {SPR_BSKU,32769,10,{NULL},S_BSKULL,0,0}, // S_BSKULL2 {SPR_RSKU,0,10,{NULL},S_RSKULL2,0,0}, // S_RSKULL {SPR_RSKU,32769,10,{NULL},S_RSKULL,0,0}, // S_RSKULL2 {SPR_YSKU,0,10,{NULL},S_YSKULL2,0,0}, // S_YSKULL {SPR_YSKU,32769,10,{NULL},S_YSKULL,0,0}, // S_YSKULL2 {SPR_STIM,0,-1,{NULL},S_NULL,0,0}, // S_STIM {SPR_MEDI,0,-1,{NULL},S_NULL,0,0}, // S_MEDI {SPR_SOUL,32768,6,{NULL},S_SOUL2,0,0}, // S_SOUL {SPR_SOUL,32769,6,{NULL},S_SOUL3,0,0}, // S_SOUL2 {SPR_SOUL,32770,6,{NULL},S_SOUL4,0,0}, // S_SOUL3 {SPR_SOUL,32771,6,{NULL},S_SOUL5,0,0}, // S_SOUL4 {SPR_SOUL,32770,6,{NULL},S_SOUL6,0,0}, // S_SOUL5 {SPR_SOUL,32769,6,{NULL},S_SOUL,0,0}, // S_SOUL6 {SPR_PINV,32768,6,{NULL},S_PINV2,0,0}, // S_PINV {SPR_PINV,32769,6,{NULL},S_PINV3,0,0}, // S_PINV2 {SPR_PINV,32770,6,{NULL},S_PINV4,0,0}, // S_PINV3 {SPR_PINV,32771,6,{NULL},S_PINV,0,0}, // S_PINV4 {SPR_PSTR,32768,-1,{NULL},S_NULL,0,0}, // S_PSTR {SPR_PINS,32768,6,{NULL},S_PINS2,0,0}, // S_PINS {SPR_PINS,32769,6,{NULL},S_PINS3,0,0}, // S_PINS2 {SPR_PINS,32770,6,{NULL},S_PINS4,0,0}, // S_PINS3 {SPR_PINS,32771,6,{NULL},S_PINS,0,0}, // S_PINS4 {SPR_MEGA,32768,6,{NULL},S_MEGA2,0,0}, // S_MEGA {SPR_MEGA,32769,6,{NULL},S_MEGA3,0,0}, // S_MEGA2 {SPR_MEGA,32770,6,{NULL},S_MEGA4,0,0}, // S_MEGA3 {SPR_MEGA,32771,6,{NULL},S_MEGA,0,0}, // S_MEGA4 {SPR_SUIT,32768,-1,{NULL},S_NULL,0,0}, // S_SUIT {SPR_PMAP,32768,6,{NULL},S_PMAP2,0,0}, // S_PMAP {SPR_PMAP,32769,6,{NULL},S_PMAP3,0,0}, // S_PMAP2 {SPR_PMAP,32770,6,{NULL},S_PMAP4,0,0}, // S_PMAP3 {SPR_PMAP,32771,6,{NULL},S_PMAP5,0,0}, // S_PMAP4 {SPR_PMAP,32770,6,{NULL},S_PMAP6,0,0}, // S_PMAP5 {SPR_PMAP,32769,6,{NULL},S_PMAP,0,0}, // S_PMAP6 {SPR_PVIS,32768,6,{NULL},S_PVIS2,0,0}, // S_PVIS {SPR_PVIS,1,6,{NULL},S_PVIS,0,0}, // S_PVIS2 {SPR_CLIP,0,-1,{NULL},S_NULL,0,0}, // S_CLIP {SPR_AMMO,0,-1,{NULL},S_NULL,0,0}, // S_AMMO {SPR_ROCK,0,-1,{NULL},S_NULL,0,0}, // S_ROCK {SPR_BROK,0,-1,{NULL},S_NULL,0,0}, // S_BROK {SPR_CELL,0,-1,{NULL},S_NULL,0,0}, // S_CELL {SPR_CELP,0,-1,{NULL},S_NULL,0,0}, // S_CELP {SPR_SHEL,0,-1,{NULL},S_NULL,0,0}, // S_SHEL {SPR_SBOX,0,-1,{NULL},S_NULL,0,0}, // S_SBOX {SPR_BPAK,0,-1,{NULL},S_NULL,0,0}, // S_BPAK {SPR_BFUG,0,-1,{NULL},S_NULL,0,0}, // S_BFUG {SPR_MGUN,0,-1,{NULL},S_NULL,0,0}, // S_MGUN {SPR_CSAW,0,-1,{NULL},S_NULL,0,0}, // S_CSAW {SPR_LAUN,0,-1,{NULL},S_NULL,0,0}, // S_LAUN {SPR_PLAS,0,-1,{NULL},S_NULL,0,0}, // S_PLAS {SPR_SHOT,0,-1,{NULL},S_NULL,0,0}, // S_SHOT {SPR_SGN2,0,-1,{NULL},S_NULL,0,0}, // S_SHOT2 {SPR_COLU,32768,-1,{NULL},S_NULL,0,0}, // S_COLU {SPR_SMT2,0,-1,{NULL},S_NULL,0,0}, // S_STALAG {SPR_GOR1,0,10,{NULL},S_BLOODYTWITCH2,0,0}, // S_BLOODYTWITCH {SPR_GOR1,1,15,{NULL},S_BLOODYTWITCH3,0,0}, // S_BLOODYTWITCH2 {SPR_GOR1,2,8,{NULL},S_BLOODYTWITCH4,0,0}, // S_BLOODYTWITCH3 {SPR_GOR1,1,6,{NULL},S_BLOODYTWITCH,0,0}, // S_BLOODYTWITCH4 {SPR_PLAY,13,-1,{NULL},S_NULL,0,0}, // S_DEADTORSO {SPR_PLAY,18,-1,{NULL},S_NULL,0,0}, // S_DEADBOTTOM {SPR_POL2,0,-1,{NULL},S_NULL,0,0}, // S_HEADSONSTICK {SPR_POL5,0,-1,{NULL},S_NULL,0,0}, // S_GIBS {SPR_POL4,0,-1,{NULL},S_NULL,0,0}, // S_HEADONASTICK {SPR_POL3,32768,6,{NULL},S_HEADCANDLES2,0,0}, // S_HEADCANDLES {SPR_POL3,32769,6,{NULL},S_HEADCANDLES,0,0}, // S_HEADCANDLES2 {SPR_POL1,0,-1,{NULL},S_NULL,0,0}, // S_DEADSTICK {SPR_POL6,0,6,{NULL},S_LIVESTICK2,0,0}, // S_LIVESTICK {SPR_POL6,1,8,{NULL},S_LIVESTICK,0,0}, // S_LIVESTICK2 {SPR_GOR2,0,-1,{NULL},S_NULL,0,0}, // S_MEAT2 {SPR_GOR3,0,-1,{NULL},S_NULL,0,0}, // S_MEAT3 {SPR_GOR4,0,-1,{NULL},S_NULL,0,0}, // S_MEAT4 {SPR_GOR5,0,-1,{NULL},S_NULL,0,0}, // S_MEAT5 {SPR_SMIT,0,-1,{NULL},S_NULL,0,0}, // S_STALAGTITE {SPR_COL1,0,-1,{NULL},S_NULL,0,0}, // S_TALLGRNCOL {SPR_COL2,0,-1,{NULL},S_NULL,0,0}, // S_SHRTGRNCOL {SPR_COL3,0,-1,{NULL},S_NULL,0,0}, // S_TALLREDCOL {SPR_COL4,0,-1,{NULL},S_NULL,0,0}, // S_SHRTREDCOL {SPR_CAND,32768,-1,{NULL},S_NULL,0,0}, // S_CANDLESTIK {SPR_CBRA,32768,-1,{NULL},S_NULL,0,0}, // S_CANDELABRA {SPR_COL6,0,-1,{NULL},S_NULL,0,0}, // S_SKULLCOL {SPR_TRE1,0,-1,{NULL},S_NULL,0,0}, // S_TORCHTREE {SPR_TRE2,0,-1,{NULL},S_NULL,0,0}, // S_BIGTREE {SPR_ELEC,0,-1,{NULL},S_NULL,0,0}, // S_TECHPILLAR {SPR_CEYE,32768,6,{NULL},S_EVILEYE2,0,0}, // S_EVILEYE {SPR_CEYE,32769,6,{NULL},S_EVILEYE3,0,0}, // S_EVILEYE2 {SPR_CEYE,32770,6,{NULL},S_EVILEYE4,0,0}, // S_EVILEYE3 {SPR_CEYE,32769,6,{NULL},S_EVILEYE,0,0}, // S_EVILEYE4 {SPR_FSKU,32768,6,{NULL},S_FLOATSKULL2,0,0}, // S_FLOATSKULL {SPR_FSKU,32769,6,{NULL},S_FLOATSKULL3,0,0}, // S_FLOATSKULL2 {SPR_FSKU,32770,6,{NULL},S_FLOATSKULL,0,0}, // S_FLOATSKULL3 {SPR_COL5,0,14,{NULL},S_HEARTCOL2,0,0}, // S_HEARTCOL {SPR_COL5,1,14,{NULL},S_HEARTCOL,0,0}, // S_HEARTCOL2 {SPR_TBLU,32768,4,{NULL},S_BLUETORCH2,0,0}, // S_BLUETORCH {SPR_TBLU,32769,4,{NULL},S_BLUETORCH3,0,0}, // S_BLUETORCH2 {SPR_TBLU,32770,4,{NULL},S_BLUETORCH4,0,0}, // S_BLUETORCH3 {SPR_TBLU,32771,4,{NULL},S_BLUETORCH,0,0}, // S_BLUETORCH4 {SPR_TGRN,32768,4,{NULL},S_GREENTORCH2,0,0}, // S_GREENTORCH {SPR_TGRN,32769,4,{NULL},S_GREENTORCH3,0,0}, // S_GREENTORCH2 �� {SPR_TGRN,32770,4,{NULL},S_GREENTORCH4,0,0}, // S_GREENTORCH3 {SPR_TGRN,32771,4,{NULL},S_GREENTORCH,0,0}, // S_GREENTORCH4 {SPR_TRED,32768,4,{NULL},S_REDTORCH2,0,0}, // S_REDTORCH {SPR_TRED,32769,4,{NULL},S_REDTORCH3,0,0}, // S_REDTORCH2 {SPR_TRED,32770,4,{NULL},S_REDTORCH4,0,0}, // S_REDTORCH3 {SPR_TRED,32771,4,{NULL},S_REDTORCH,0,0}, // S_REDTORCH4 {SPR_SMBT,32768,4,{NULL},S_BTORCHSHRT2,0,0}, // S_BTORCHSHRT {SPR_SMBT,32769,4,{NULL},S_BTORCHSHRT3,0,0}, // S_BTORCHSHRT2 {SPR_SMBT,32770,4,{NULL},S_BTORCHSHRT4,0,0}, // S_BTORCHSHRT3 {SPR_SMBT,32771,4,{NULL},S_BTORCHSHRT,0,0}, // S_BTORCHSHRT4 {SPR_SMGT,32768,4,{NULL},S_GTORCHSHRT2,0,0}, // S_GTORCHSHRT {SPR_SMGT,32769,4,{NULL},S_GTORCHSHRT3,0,0}, // S_GTORCHSHRT2 {SPR_SMGT,32770,4,{NULL},S_GTORCHSHRT4,0,0}, // S_GTORCHSHRT3 {SPR_SMGT,32771,4,{NULL},S_GTORCHSHRT,0,0}, // S_GTORCHSHRT4 {SPR_SMRT,32768,4,{NULL},S_RTORCHSHRT2,0,0}, // S_RTORCHSHRT {SPR_SMRT,32769,4,{NULL},S_RTORCHSHRT3,0,0}, // S_RTORCHSHRT2 {SPR_SMRT,32770,4,{NULL},S_RTORCHSHRT4,0,0}, // S_RTORCHSHRT3 {SPR_SMRT,32771,4,{NULL},S_RTORCHSHRT,0,0}, // S_RTORCHSHRT4 {SPR_HDB1,0,-1,{NULL},S_NULL,0,0}, // S_HANGNOGUTS {SPR_HDB2,0,-1,{NULL},S_NULL,0,0}, // S_HANGBNOBRAIN {SPR_HDB3,0,-1,{NULL},S_NULL,0,0}, // S_HANGTLOOKDN {SPR_HDB4,0,-1,{NULL},S_NULL,0,0}, // S_HANGTSKULL {SPR_HDB5,0,-1,{NULL},S_NULL,0,0}, // S_HANGTLOOKUP {SPR_HDB6,0,-1,{NULL},S_NULL,0,0}, // S_HANGTNOBRAIN {SPR_POB1,0,-1,{NULL},S_NULL,0,0}, // S_COLONGIBS {SPR_POB2,0,-1,{NULL},S_NULL,0,0}, // S_SMALLPOOL {SPR_BRS1,0,-1,{NULL},S_NULL,0,0}, // S_BRAINSTEM {SPR_TLMP,32768,4,{NULL},S_TECHLAMP2,0,0}, // S_TECHLAMP {SPR_TLMP,32769,4,{NULL},S_TECHLAMP3,0,0}, // S_TECHLAMP2 {SPR_TLMP,32770,4,{NULL},S_TECHLAMP4,0,0}, // S_TECHLAMP3 {SPR_TLMP,32771,4,{NULL},S_TECHLAMP,0,0}, // S_TECHLAMP4 {SPR_TLP2,32768,4,{NULL},S_TECH2LAMP2,0,0}, // S_TECH2LAMP {SPR_TLP2,32769,4,{NULL},S_TECH2LAMP3,0,0}, // S_TECH2LAMP2 {SPR_TLP2,32770,4,{NULL},S_TECH2LAMP4,0,0}, // S_TECH2LAMP3 {SPR_TLP2,32771,4,{NULL},S_TECH2LAMP,0,0} // S_TECH2LAMP4 };
mobjinfo_t mobjinfo[NUMMOBJTYPES] = {
{ // MT_PLAYER -1, // doomednum S_PLAY, // spawnstate 100, // spawnhealth S_PLAY_RUN1, // seestate sfx_None, // seesound 0, // reactiontime sfx_None, // attacksound S_PLAY_PAIN, // painstate 255, // painchance sfx_plpain, // painsound S_NULL, // meleestate S_PLAY_ATK1, // missilestate S_PLAY_DIE1, // deathstate S_PLAY_XDIE1, // xdeathstate sfx_pldeth, // deathsound 0, // speed 16*FRACUNIT, // radius 56*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID|MF_SHOOTABLE|MF_DROPOFF|MF_PICKUP|MF_NOTDMATCH, // flags S_NULL // raisestate },
{ // MT_POSSESSED 3004, // doomednum S_POSS_STND, // spawnstate 20, // spawnhealth S_POSS_RUN1, // seestate sfx_posit1, // seesound 8, // reactiontime sfx_pistol, // attacksound S_POSS_PAIN, // painstate 200, // painchance sfx_popain, // painsound 0, // meleestate S_POSS_ATK1, // missilestate S_POSS_DIE1, // deathstate S_POSS_XDIE1, // xdeathstate sfx_podth1, // deathsound 8, // speed 20*FRACUNIT, // radius 56*FRACUNIT, // height 100, // mass 0, // damage sfx_posact, // activesound MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL, // flags S_POSS_RAISE1 // raisestate },
{ // MT_SHOTGUY 9, // doomednum S_SPOS_STND, // spawnstate 30, // spawnhealth S_SPOS_RUN1, // seestate sfx_posit2, // seesound 8, // reactiontime 0, // attacksound S_SPOS_PAIN, // painstate 170, // painchance sfx_popain, // painsound 0, // meleestate S_SPOS_ATK1, // missilestate S_SPOS_DIE1, // deathstate S_SPOS_XDIE1, // xdeathstate sfx_podth2, // deathsound 8, // speed 20*FRACUNIT, // radius 56*FRACUNIT, // height 100, // mass 0, // damage sfx_posact, // activesound MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL, // flags S_SPOS_RAISE1 // raisestate },
{ // MT_VILE 64, // doomednum S_VILE_STND, // spawnstate 700, // spawnhealth S_VILE_RUN1, // seestate sfx_vilsit, // seesound 8, // reactiontime 0, // attacksound S_VILE_PAIN, // painstate 10, // painchance sfx_vipain, // painsound 0, // meleestate S_VILE_ATK1, // missilestate S_VILE_DIE1, // deathstate S_NULL, // xdeathstate sfx_vildth, // deathsound 15, // speed 20*FRACUNIT, // radius 56*FRACUNIT, // height 500, // mass 0, // damage sfx_vilact, // activesound MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL, // flags S_NULL // raisestate },
{ // MT_FIRE -1, // doomednum S_FIRE1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_UNDEAD 66, // doomednum S_SKEL_STND, // spawnstate 300, // spawnhealth S_SKEL_RUN1, // seestate sfx_skesit, // seesound 8, // reactiontime 0, // attacksound S_SKEL_PAIN, // painstate 100, // painchance sfx_popain, // painsound S_SKEL_FIST1, // meleestate S_SKEL_MISS1, // missilestate S_SKEL_DIE1, // deathstate S_NULL, // xdeathstate sfx_skedth, // deathsound 10, // speed 20*FRACUNIT, // radius 56*FRACUNIT, // height 500, // mass 0, // damage sfx_skeact, // activesound MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL, // flags S_SKEL_RAISE1 // raisestate },
{ // MT_TRACER -1, // doomednum S_TRACER, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_skeatk, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_TRACEEXP1, // deathstate S_NULL, // xdeathstate sfx_barexp, // deathsound 10*FRACUNIT, // speed 11*FRACUNIT, // radius 8*FRACUNIT, // height 100, // mass 10, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_SMOKE -1, // doomednum S_SMOKE1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_FATSO 67, // doomednum S_FATT_STND, // spawnstate 600, // spawnhealth S_FATT_RUN1, // seestate sfx_mansit, // seesound 8, // reactiontime 0, // attacksound S_FATT_PAIN, // painstate 80, // painchance sfx_mnpain, // painsound 0, // meleestate S_FATT_ATK1, // missilestate S_FATT_DIE1, // deathstate S_NULL, // xdeathstate sfx_mandth, // deathsound 8, // speed 48*FRACUNIT, // radius 64*FRACUNIT, // height 1000, // mass 0, // damage sfx_posact, // activesound MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL, // flags S_FATT_RAISE1 // raisestate },
{ // MT_FATSHOT -1, // doomednum S_FATSHOT1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_firsht, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_FATSHOTX1, // deathstate S_NULL, // xdeathstate sfx_firxpl, // deathsound 20*FRACUNIT, // speed 6*FRACUNIT, // radius 8*FRACUNIT, // height 100, // mass 8, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_CHAINGUY 65, // doomednum S_CPOS_STND, // spawnstate 70, // spawnhealth S_CPOS_RUN1, // seestate sfx_posit2, // seesound 8, // reactiontime 0, // attacksound S_CPOS_PAIN, // painstate 170, // painchance sfx_popain, // painsound 0, // meleestate S_CPOS_ATK1, // missilestate S_CPOS_DIE1, // deathstate S_CPOS_XDIE1, // xdeathstate sfx_podth2, // deathsound 8, // speed 20*FRACUNIT, // radius 56*FRACUNIT, // height 100, // mass 0, // damage sfx_posact, // activesound MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL, // flags S_CPOS_RAISE1 // raisestate },
{ // MT_TROOP 3001, // doomednum S_TROO_STND, // spawnstate 60, // spawnhealth S_TROO_RUN1, // seestate sfx_bgsit1, // seesound 8, // reactiontime 0, // attacksound S_TROO_PAIN, // painstate 200, // painchance sfx_popain, // painsound S_TROO_ATK1, // meleestate S_TROO_ATK1, // missilestate S_TROO_DIE1, // deathstate S_TROO_XDIE1, // xdeathstate sfx_bgdth1, // deathsound 8, // speed 20*FRACUNIT, // radius 56*FRACUNIT, // height 100, // mass 0, // damage sfx_bgact, // activesound MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL, // flags S_TROO_RAISE1 // raisestate },
{ // MT_SERGEANT 3002, // doomednum S_SARG_STND, // spawnstate 150, // spawnhealth S_SARG_RUN1, // seestate sfx_sgtsit, // seesound 8, // reactiontime sfx_sgtatk, // attacksound S_SARG_PAIN, // painstate 180, // painchance sfx_dmpain, // painsound S_SARG_ATK1, // meleestate 0, // missilestate S_SARG_DIE1, // deathstate S_NULL, // xdeathstate sfx_sgtdth, // deathsound 10, // speed 30*FRACUNIT, // radius 56*FRACUNIT, // height 400, // mass 0, // damage sfx_dmact, // activesound MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL, // flags S_SARG_RAISE1 // raisestate },
{ // MT_SHADOWS 58, // doomednum S_SARG_STND, // spawnstate 150, // spawnhealth S_SARG_RUN1, // seestate sfx_sgtsit, // seesound 8, // reactiontime sfx_sgtatk, // attacksound S_SARG_PAIN, // painstate 180, // painchance sfx_dmpain, // painsound S_SARG_ATK1, // meleestate 0, // missilestate S_SARG_DIE1, // deathstate S_NULL, // xdeathstate sfx_sgtdth, // deathsound 10, // speed 30*FRACUNIT, // radius 56*FRACUNIT, // height 400, // mass 0, // damage sfx_dmact, // activesound MF_SOLID|MF_SHOOTABLE|MF_SHADOW|MF_COUNTKILL, // flags S_SARG_RAISE1 // raisestate },
{ // MT_HEAD 3005, // doomednum S_HEAD_STND, // spawnstate 400, // spawnhealth S_HEAD_RUN1, // seestate sfx_cacsit, // seesound 8, // reactiontime 0, // attacksound S_HEAD_PAIN, // painstate 128, // painchance sfx_dmpain, // painsound 0, // meleestate S_HEAD_ATK1, // missilestate S_HEAD_DIE1, // deathstate S_NULL, // xdeathstate sfx_cacdth, // deathsound 8, // speed 31*FRACUNIT, // radius 56*FRACUNIT, // height 400, // mass 0, // damage sfx_dmact, // activesound MF_SOLID|MF_SHOOTABLE|MF_FLOAT|MF_NOGRAVITY|MF_COUNTKILL, // flags S_HEAD_RAISE1 // raisestate },
{ // MT_BRUISER 3003, // doomednum S_BOSS_STND, // spawnstate 1000, // spawnhealth S_BOSS_RUN1, // seestate sfx_brssit, // seesound 8, // reactiontime 0, // attacksound S_BOSS_PAIN, // painstate 50, // painchance sfx_dmpain, // painsound S_BOSS_ATK1, // meleestate S_BOSS_ATK1, // missilestate S_BOSS_DIE1, // deathstate S_NULL, // xdeathstate sfx_brsdth, // deathsound 8, // speed 24*FRACUNIT, // radius 64*FRACUNIT, // height 1000, // mass 0, // damage sfx_dmact, // activesound MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL, // flags S_BOSS_RAISE1 // raisestate },
{ // MT_BRUISERSHOT -1, // doomednum S_BRBALL1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_firsht, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_BRBALLX1, // deathstate S_NULL, // xdeathstate sfx_firxpl, // deathsound 15*FRACUNIT, // speed 6*FRACUNIT, // radius 8*FRACUNIT, // height 100, // mass 8, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_KNIGHT 69, // doomednum S_BOS2_STND, // spawnstate 500, // spawnhealth S_BOS2_RUN1, // seestate sfx_kntsit, // seesound 8, // reactiontime 0, // attacksound S_BOS2_PAIN, // painstate 50, // painchance sfx_dmpain, // painsound S_BOS2_ATK1, // meleestate S_BOS2_ATK1, // missilestate S_BOS2_DIE1, // deathstate S_NULL, // xdeathstate sfx_kntdth, // deathsound 8, // speed 24*FRACUNIT, // radius 64*FRACUNIT, // height 1000, // mass 0, // damage sfx_dmact, // activesound MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL, // flags S_BOS2_RAISE1 // raisestate },
{ // MT_SKULL 3006, // doomednum S_SKULL_STND, // spawnstate 100, // spawnhealth S_SKULL_RUN1, // seestate 0, // seesound 8, // reactiontime sfx_sklatk, // attacksound S_SKULL_PAIN, // painstate 256, // painchance sfx_dmpain, // painsound 0, // meleestate S_SKULL_ATK1, // missilestate S_SKULL_DIE1, // deathstate S_NULL, // xdeathstate sfx_firxpl, // deathsound 8, // speed 16*FRACUNIT, // radius 56*FRACUNIT, // height 50, // mass 3, // damage sfx_dmact, // activesound MF_SOLID|MF_SHOOTABLE|MF_FLOAT|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_SPIDER 7, // doomednum S_SPID_STND, // spawnstate 3000, // spawnhealth S_SPID_RUN1, // seestate sfx_spisit, // seesound 8, // reactiontime sfx_shotgn, // attacksound S_SPID_PAIN, // painstate 40, // painchance sfx_dmpain, // painsound 0, // meleestate S_SPID_ATK1, // missilestate S_SPID_DIE1, // deathstate S_NULL, // xdeathstate sfx_spidth, // deathsound 12, // speed 128*FRACUNIT, // radius 100*FRACUNIT, // height 1000, // mass 0, // damage sfx_dmact, // activesound MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL, // flags S_NULL // raisestate },
{ // MT_BABY 68, // doomednum S_BSPI_STND, // spawnstate 500, // spawnhealth S_BSPI_SIGHT, // seestate sfx_bspsit, // seesound 8, // reactiontime 0, // attacksound S_BSPI_PAIN, // painstate 128, // painchance sfx_dmpain, // painsound 0, // meleestate S_BSPI_ATK1, // missilestate S_BSPI_DIE1, // deathstate S_NULL, // xdeathstate sfx_bspdth, // deathsound 12, // speed 64*FRACUNIT, // radius 64*FRACUNIT, // height 600, // mass 0, // damage sfx_bspact, // activesound MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL, // flags S_BSPI_RAISE1 // raisestate },
{ // MT_CYBORG 16, // doomednum S_CYBER_STND, // spawnstate 4000, // spawnhealth S_CYBER_RUN1, // seestate sfx_cybsit, // seesound 8, // reactiontime 0, // attacksound S_CYBER_PAIN, // painstate 20, // painchance sfx_dmpain, // painsound 0, // meleestate S_CYBER_ATK1, // missilestate S_CYBER_DIE1, // deathstate S_NULL, // xdeathstate sfx_cybdth, // deathsound 16, // speed 40*FRACUNIT, // radius 110*FRACUNIT, // height 1000, // mass 0, // damage sfx_dmact, // activesound MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL, // flags S_NULL // raisestate },
{ // MT_PAIN 71, // doomednum S_PAIN_STND, // spawnstate 400, // spawnhealth S_PAIN_RUN1, // seestate sfx_pesit, // seesound 8, // reactiontime 0, // attacksound S_PAIN_PAIN, // painstate 128, // painchance sfx_pepain, // painsound 0, // meleestate S_PAIN_ATK1, // missilestate S_PAIN_DIE1, // deathstate S_NULL, // xdeathstate sfx_pedth, // deathsound 8, // speed 31*FRACUNIT, // radius 56*FRACUNIT, // height 400, // mass 0, // damage sfx_dmact, // activesound MF_SOLID|MF_SHOOTABLE|MF_FLOAT|MF_NOGRAVITY|MF_COUNTKILL, // flags S_PAIN_RAISE1 // raisestate },
{ // MT_WOLFSS 84, // doomednum S_SSWV_STND, // spawnstate 50, // spawnhealth S_SSWV_RUN1, // seestate sfx_sssit, // seesound 8, // reactiontime 0, // attacksound S_SSWV_PAIN, // painstate 170, // painchance sfx_popain, // painsound 0, // meleestate S_SSWV_ATK1, // missilestate S_SSWV_DIE1, // deathstate S_SSWV_XDIE1, // xdeathstate sfx_ssdth, // deathsound 8, // speed 20*FRACUNIT, // radius 56*FRACUNIT, // height 100, // mass 0, // damage sfx_posact, // activesound MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL, // flags S_SSWV_RAISE1 // raisestate },
{ // MT_KEEN 72, // doomednum S_KEENSTND, // spawnstate 100, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_KEENPAIN, // painstate 256, // painchance sfx_keenpn, // painsound S_NULL, // meleestate S_NULL, // missilestate S_COMMKEEN, // deathstate S_NULL, // xdeathstate sfx_keendt, // deathsound 0, // speed 16*FRACUNIT, // radius 72*FRACUNIT, // height 10000000, // mass 0, // damage sfx_None, // activesound MF_SOLID|MF_SPAWNCEILING|MF_NOGRAVITY|MF_SHOOTABLE|MF_COUNTKILL, // flags S_NULL // raisestate },
{ // MT_BOSSBRAIN 88, // doomednum S_BRAIN, // spawnstate 250, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_BRAIN_PAIN, // painstate 255, // painchance sfx_bospn, // painsound S_NULL, // meleestate S_NULL, // missilestate S_BRAIN_DIE1, // deathstate S_NULL, // xdeathstate sfx_bosdth, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 10000000, // mass 0, // damage sfx_None, // activesound MF_SOLID|MF_SHOOTABLE, // flags S_NULL // raisestate },
{ // MT_BOSSSPIT 89, // doomednum S_BRAINEYE, // spawnstate 1000, // spawnhealth S_BRAINEYESEE, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 32*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_NOSECTOR, // flags S_NULL // raisestate },
{ // MT_BOSSTARGET 87, // doomednum S_NULL, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 32*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_NOSECTOR, // flags S_NULL // raisestate },
{ // MT_SPAWNSHOT -1, // doomednum S_SPAWN1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_bospit, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_firxpl, // deathsound 10*FRACUNIT, // speed 6*FRACUNIT, // radius 32*FRACUNIT, // height 100, // mass 3, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY|MF_NOCLIP, // flags S_NULL // raisestate },
{ // MT_SPAWNFIRE -1, // doomednum S_SPAWNFIRE1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_BARREL 2035, // doomednum S_BAR1, // spawnstate 20, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_BEXP, // deathstate S_NULL, // xdeathstate sfx_barexp, // deathsound 0, // speed 10*FRACUNIT, // radius 42*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID|MF_SHOOTABLE|MF_NOBLOOD, // flags S_NULL // raisestate },
{ // MT_TROOPSHOT -1, // doomednum S_TBALL1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_firsht, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_TBALLX1, // deathstate S_NULL, // xdeathstate sfx_firxpl, // deathsound 10*FRACUNIT, // speed 6*FRACUNIT, // radius 8*FRACUNIT, // height 100, // mass 3, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_HEADSHOT -1, // doomednum S_RBALL1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_firsht, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_RBALLX1, // deathstate S_NULL, // xdeathstate sfx_firxpl, // deathsound 10*FRACUNIT, // speed 6*FRACUNIT, // radius 8*FRACUNIT, // height 100, // mass 5, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_ROCKET -1, // doomednum S_ROCKET, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_rlaunc, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_EXPLODE1, // deathstate S_NULL, // xdeathstate sfx_barexp, // deathsound 20*FRACUNIT, // speed 11*FRACUNIT, // radius 8*FRACUNIT, // height 100, // mass 20, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_PLASMA -1, // doomednum S_PLASBALL, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_plasma, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_PLASEXP, // deathstate S_NULL, // xdeathstate sfx_firxpl, // deathsound 25*FRACUNIT, // speed 13*FRACUNIT, // radius 8*FRACUNIT, // height 100, // mass 5, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_BFG -1, // doomednum S_BFGSHOT, // spawnstate 1000, // spawnhealth S_NULL, // seestate 0, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_BFGLAND, // deathstate S_NULL, // xdeathstate sfx_rxplod, // deathsound 25*FRACUNIT, // speed 13*FRACUNIT, // radius 8*FRACUNIT, // height 100, // mass 100, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_ARACHPLAZ -1, // doomednum S_ARACH_PLAZ, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_plasma, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_ARACH_PLEX, // deathstate S_NULL, // xdeathstate sfx_firxpl, // deathsound 25*FRACUNIT, // speed 13*FRACUNIT, // radius 8*FRACUNIT, // height 100, // mass 5, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_PUFF -1, // doomednum S_PUFF1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_BLOOD -1, // doomednum S_BLOOD1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_NOBLOCKMAP, // flags S_NULL // raisestate },
{ // MT_TFOG -1, // doomednum S_TFOG, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_IFOG -1, // doomednum S_IFOG, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_TELEPORTMAN 14, // doomednum S_NULL, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_NOSECTOR, // flags S_NULL // raisestate },
{ // MT_EXTRABFG -1, // doomednum S_BFGEXP, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_MISC0 2018, // doomednum S_ARM1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL, // flags S_NULL // raisestate },
{ // MT_MISC1 2019, // doomednum S_ARM2, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL, // flags S_NULL // raisestate },
{ // MT_MISC2 2014, // doomednum S_BON1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL|MF_COUNTITEM, // flags S_NULL // raisestate },
{ // MT_MISC3 2015, // doomednum S_BON2, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL|MF_COUNTITEM, // flags S_NULL // raisestate },
{ // MT_MISC4 5, // doomednum S_BKEY, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL|MF_NOTDMATCH, // flags S_NULL // raisestate },
{ // MT_MISC5 13, // doomednum S_RKEY, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL|MF_NOTDMATCH, // flags S_NULL // raisestate },
{ // MT_MISC6 6, // doomednum S_YKEY, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL|MF_NOTDMATCH, // flags S_NULL // raisestate },
{ // MT_MISC7 39, // doomednum S_YSKULL, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL|MF_NOTDMATCH, // flags S_NULL // raisestate },
{ // MT_MISC8 38, // doomednum S_RSKULL, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL|MF_NOTDMATCH, // flags S_NULL // raisestate },
{ // MT_MISC9 40, // doomednum S_BSKULL, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL|MF_NOTDMATCH, // flags S_NULL // raisestate },
{ // MT_MISC10 2011, // doomednum S_STIM, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL, // flags S_NULL // raisestate },
{ // MT_MISC11 2012, // doomednum S_MEDI, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL, // flags S_NULL // raisestate },
{ // MT_MISC12 2013, // doomednum S_SOUL, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL|MF_COUNTITEM, // flags S_NULL // raisestate },
{ // MT_INV 2022, // doomednum S_PINV, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL|MF_COUNTITEM, // flags S_NULL // raisestate },
{ // MT_MISC13 2023, // doomednum S_PSTR, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL|MF_COUNTITEM, // flags S_NULL // raisestate },
{ // MT_INS 2024, // doomednum S_PINS, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL|MF_COUNTITEM, // flags S_NULL // raisestate },
{ // MT_MISC14 2025, // doomednum S_SUIT, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL, // flags S_NULL // raisestate },
{ // MT_MISC15 2026, // doomednum S_PMAP, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL|MF_COUNTITEM, // flags S_NULL // raisestate },
{ // MT_MISC16 2045, // doomednum S_PVIS, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL|MF_COUNTITEM, // flags S_NULL // raisestate },
{ // MT_MEGA 83, // doomednum S_MEGA, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL|MF_COUNTITEM, // flags S_NULL // raisestate },
{ // MT_CLIP 2007, // doomednum S_CLIP, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL, // flags S_NULL // raisestate },
{ // MT_MISC17 2048, // doomednum S_AMMO, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL, // flags S_NULL // raisestate },
{ // MT_MISC18 2010, // doomednum S_ROCK, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL, // flags S_NULL // raisestate },
{ // MT_MISC19 2046, // doomednum S_BROK, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL, // flags S_NULL // raisestate },
{ // MT_MISC20 2047, // doomednum S_CELL, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL, // flags S_NULL // raisestate },
{ // MT_MISC21 17, // doomednum S_CELP, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL, // flags S_NULL // raisestate },
{ // MT_MISC22 2008, // doomednum S_SHEL, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL, // flags S_NULL // raisestate },
{ // MT_MISC23 2049, // doomednum S_SBOX, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL, // flags S_NULL // raisestate },
{ // MT_MISC24 8, // doomednum S_BPAK, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL, // flags S_NULL // raisestate },
{ // MT_MISC25 2006, // doomednum S_BFUG, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL, // flags S_NULL // raisestate },
{ // MT_CHAINGUN 2002, // doomednum S_MGUN, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL, // flags S_NULL // raisestate },
{ // MT_MISC26 2005, // doomednum S_CSAW, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL, // flags S_NULL // raisestate },
{ // MT_MISC27 2003, // doomednum S_LAUN, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL, // flags S_NULL // raisestate },
{ // MT_MISC28 2004, // doomednum S_PLAS, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL, // flags S_NULL // raisestate },
{ // MT_SHOTGUN 2001, // doomednum S_SHOT, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL, // flags S_NULL // raisestate },
{ // MT_SUPERSHOTGUN 82, // doomednum S_SHOT2, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPECIAL, // flags S_NULL // raisestate },
{ // MT_MISC29 85, // doomednum S_TECHLAMP, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC30 86, // doomednum S_TECH2LAMP, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC31 2028, // doomednum S_COLU, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC32 30, // doomednum S_TALLGRNCOL, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC33 31, // doomednum S_SHRTGRNCOL, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC34 32, // doomednum S_TALLREDCOL, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC35 33, // doomednum S_SHRTREDCOL, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC36 37, // doomednum S_SKULLCOL, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC37 36, // doomednum S_HEARTCOL, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC38 41, // doomednum S_EVILEYE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC39 42, // doomednum S_FLOATSKULL, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC40 43, // doomednum S_TORCHTREE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC41 44, // doomednum S_BLUETORCH, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC42 45, // doomednum S_GREENTORCH, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC43 46, // doomednum S_REDTORCH, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC44 55, // doomednum S_BTORCHSHRT, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC45 56, // doomednum S_GTORCHSHRT, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC46 57, // doomednum S_RTORCHSHRT, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC47 47, // doomednum S_STALAGTITE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC48 48, // doomednum S_TECHPILLAR, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC49 34, // doomednum S_CANDLESTIK, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound 0, // flags S_NULL // raisestate },
{ // MT_MISC50 35, // doomednum S_CANDELABRA, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC51 49, // doomednum S_BLOODYTWITCH, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 68*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID|MF_SPAWNCEILING|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_MISC52 50, // doomednum S_MEAT2, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 84*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID|MF_SPAWNCEILING|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_MISC53 51, // doomednum S_MEAT3, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 84*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID|MF_SPAWNCEILING|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_MISC54 52, // doomednum S_MEAT4, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 68*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID|MF_SPAWNCEILING|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_MISC55 53, // doomednum S_MEAT5, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 52*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID|MF_SPAWNCEILING|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_MISC56 59, // doomednum S_MEAT2, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 84*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPAWNCEILING|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_MISC57 60, // doomednum S_MEAT4, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 68*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPAWNCEILING|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_MISC58 61, // doomednum S_MEAT3, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 52*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPAWNCEILING|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_MISC59 62, // doomednum S_MEAT5, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 52*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPAWNCEILING|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_MISC60 63, // doomednum S_BLOODYTWITCH, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 68*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SPAWNCEILING|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_MISC61 22, // doomednum S_HEAD_DIE6, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound 0, // flags S_NULL // raisestate },
{ // MT_MISC62 15, // doomednum S_PLAY_DIE7, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound 0, // flags S_NULL // raisestate },
{ // MT_MISC63 18, // doomednum S_POSS_DIE5, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound 0, // flags S_NULL // raisestate },
{ // MT_MISC64 21, // doomednum S_SARG_DIE6, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound 0, // flags S_NULL // raisestate },
{ // MT_MISC65 23, // doomednum S_SKULL_DIE6, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound 0, // flags S_NULL // raisestate },
{ // MT_MISC66 20, // doomednum S_TROO_DIE5, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound 0, // flags S_NULL // raisestate },
{ // MT_MISC67 19, // doomednum S_SPOS_DIE5, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound 0, // flags S_NULL // raisestate },
{ // MT_MISC68 10, // doomednum S_PLAY_XDIE9, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound 0, // flags S_NULL // raisestate },
{ // MT_MISC69 12, // doomednum S_PLAY_XDIE9, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound 0, // flags S_NULL // raisestate },
{ // MT_MISC70 28, // doomednum S_HEADSONSTICK, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC71 24, // doomednum S_GIBS, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound 0, // flags S_NULL // raisestate },
{ // MT_MISC72 27, // doomednum S_HEADONASTICK, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC73 29, // doomednum S_HEADCANDLES, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC74 25, // doomednum S_DEADSTICK, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC75 26, // doomednum S_LIVESTICK, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC76 54, // doomednum S_BIGTREE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 32*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC77 70, // doomednum S_BBAR1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID, // flags S_NULL // raisestate },
{ // MT_MISC78 73, // doomednum S_HANGNOGUTS, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 88*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID|MF_SPAWNCEILING|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_MISC79 74, // doomednum S_HANGBNOBRAIN, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 88*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID|MF_SPAWNCEILING|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_MISC80 75, // doomednum S_HANGTLOOKDN, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 64*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID|MF_SPAWNCEILING|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_MISC81 76, // doomednum S_HANGTSKULL, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 64*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID|MF_SPAWNCEILING|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_MISC82 77, // doomednum S_HANGTLOOKUP, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 64*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID|MF_SPAWNCEILING|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_MISC83 78, // doomednum S_HANGTNOBRAIN, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 16*FRACUNIT, // radius 64*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_SOLID|MF_SPAWNCEILING|MF_NOGRAVITY, // flags S_NULL // raisestate },
{ // MT_MISC84 79, // doomednum S_COLONGIBS, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_NOBLOCKMAP, // flags S_NULL // raisestate },
{ // MT_MISC85 80, // doomednum S_SMALLPOOL, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_NOBLOCKMAP, // flags S_NULL // raisestate },
{ // MT_MISC86 81, // doomednum S_BRAINSTEM, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed 20*FRACUNIT, // radius 16*FRACUNIT, // height 100, // mass 0, // damage sfx_None, // activesound MF_NOBLOCKMAP, // flags S_NULL // raisestate } };
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // Thing frame/state LUT, // generated by multigen utilitiy. // This one is the original DOOM version, preserved. // //-----------------------------------------------------------------------------
#ifndef __INFO__ #define __INFO__
// Needed for action function pointer handling. #include "d_think.h"
typedef enum { SPR_TROO, SPR_SHTG, SPR_PUNG, SPR_PISG, SPR_PISF, SPR_SHTF, SPR_SHT2, SPR_CHGG, SPR_CHGF, SPR_MISG, SPR_MISF, SPR_SAWG, SPR_PLSG, SPR_PLSF, SPR_BFGG, SPR_BFGF, SPR_BLUD, SPR_PUFF, SPR_BAL1, SPR_BAL2, SPR_PLSS, SPR_PLSE, SPR_MISL, SPR_BFS1, SPR_BFE1, SPR_BFE2, SPR_TFOG, SPR_IFOG, SPR_PLAY, SPR_POSS, SPR_SPOS, SPR_VILE, SPR_FIRE, SPR_FATB, SPR_FBXP, SPR_SKEL, SPR_MANF, SPR_FATT, SPR_CPOS, SPR_SARG, SPR_HEAD, SPR_BAL7, SPR_BOSS, SPR_BOS2, SPR_SKUL, SPR_SPID, SPR_BSPI, SPR_APLS, SPR_APBX, SPR_CYBR, SPR_PAIN, SPR_SSWV, SPR_KEEN, SPR_BBRN, SPR_BOSF, SPR_ARM1, SPR_ARM2, SPR_BAR1, SPR_BEXP, SPR_FCAN, SPR_BON1, SPR_BON2, SPR_BKEY, SPR_RKEY, SPR_YKEY, SPR_BSKU, SPR_RSKU, SPR_YSKU, SPR_STIM, SPR_MEDI, SPR_SOUL, SPR_PINV, SPR_PSTR, SPR_PINS, SPR_MEGA, SPR_SUIT, SPR_PMAP, SPR_PVIS, SPR_CLIP, SPR_AMMO, SPR_ROCK, SPR_BROK, SPR_CELL, SPR_CELP, SPR_SHEL, SPR_SBOX, SPR_BPAK, SPR_BFUG, SPR_MGUN, SPR_CSAW, SPR_LAUN, SPR_PLAS, SPR_SHOT, SPR_SGN2, SPR_COLU, SPR_SMT2, SPR_GOR1, SPR_POL2, SPR_POL5, SPR_POL4, SPR_POL3, SPR_POL1, SPR_POL6, SPR_GOR2, SPR_GOR3, SPR_GOR4, SPR_GOR5, SPR_SMIT, SPR_COL1, SPR_COL2, SPR_COL3, SPR_COL4, SPR_CAND, SPR_CBRA, SPR_COL6, SPR_TRE1, SPR_TRE2, SPR_ELEC, SPR_CEYE, SPR_FSKU, SPR_COL5, SPR_TBLU, SPR_TGRN, SPR_TRED, SPR_SMBT, SPR_SMGT, SPR_SMRT, SPR_HDB1, SPR_HDB2, SPR_HDB3, SPR_HDB4, SPR_HDB5, SPR_HDB6, SPR_POB1, SPR_POB2, SPR_BRS1, SPR_TLMP, SPR_TLP2, NUMSPRITES
} spritenum_t;
typedef enum { S_NULL, S_LIGHTDONE, S_PUNCH, S_PUNCHDOWN, S_PUNCHUP, S_PUNCH1, S_PUNCH2, S_PUNCH3, S_PUNCH4, S_PUNCH5, S_PISTOL, S_PISTOLDOWN, S_PISTOLUP, S_PISTOL1, S_PISTOL2, S_PISTOL3, S_PISTOL4, S_PISTOLFLASH, S_SGUN, S_SGUNDOWN, S_SGUNUP, S_SGUN1, S_SGUN2, S_SGUN3, S_SGUN4, S_SGUN5, S_SGUN6, S_SGUN7, S_SGUN8, S_SGUN9, S_SGUNFLASH1, S_SGUNFLASH2, S_DSGUN, S_DSGUNDOWN, S_DSGUNUP, S_DSGUN1, S_DSGUN2, S_DSGUN3, S_DSGUN4, S_DSGUN5, S_DSGUN6, S_DSGUN7, S_DSGUN8, S_DSGUN9, S_DSGUN10, S_DSNR1, S_DSNR2, S_DSGUNFLASH1, S_DSGUNFLASH2, S_CHAIN, S_CHAINDOWN, S_CHAINUP, S_CHAIN1, S_CHAIN2, S_CHAIN3, S_CHAINFLASH1, S_CHAINFLASH2, S_MISSILE, S_MISSILEDOWN, S_MISSILEUP, S_MISSILE1, S_MISSILE2, S_MISSILE3, S_MISSILEFLASH1, S_MISSILEFLASH2, S_MISSILEFLASH3, S_MISSILEFLASH4, S_SAW, S_SAWB, S_SAWDOWN, S_SAWUP, S_SAW1, S_SAW2, S_SAW3, S_PLASMA, S_PLASMADOWN, S_PLASMAUP, S_PLASMA1, S_PLASMA2, S_PLASMAFLASH1, S_PLASMAFLASH2, S_BFG, S_BFGDOWN, S_BFGUP, S_BFG1, S_BFG2, S_BFG3, S_BFG4, S_BFGFLASH1, S_BFGFLASH2, S_BLOOD1, S_BLOOD2, S_BLOOD3, S_PUFF1, S_PUFF2, S_PUFF3, S_PUFF4, S_TBALL1, S_TBALL2, S_TBALLX1, S_TBALLX2, S_TBALLX3, S_RBALL1, S_RBALL2, S_RBALLX1, S_RBALLX2, S_RBALLX3, S_PLASBALL, S_PLASBALL2, S_PLASEXP, S_PLASEXP2, S_PLASEXP3, S_PLASEXP4, S_PLASEXP5, S_ROCKET, S_BFGSHOT, S_BFGSHOT2, S_BFGLAND, S_BFGLAND2, S_BFGLAND3, S_BFGLAND4, S_BFGLAND5, S_BFGLAND6, S_BFGEXP, S_BFGEXP2, S_BFGEXP3, S_BFGEXP4, S_EXPLODE1, S_EXPLODE2, S_EXPLODE3, S_TFOG, S_TFOG01, S_TFOG02, S_TFOG2, S_TFOG3, S_TFOG4, S_TFOG5, S_TFOG6, S_TFOG7, S_TFOG8, S_TFOG9, S_TFOG10, S_IFOG, S_IFOG01, S_IFOG02, S_IFOG2, S_IFOG3, S_IFOG4, S_IFOG5, S_PLAY, S_PLAY_RUN1, S_PLAY_RUN2, S_PLAY_RUN3, S_PLAY_RUN4, S_PLAY_ATK1, S_PLAY_ATK2, S_PLAY_PAIN, S_PLAY_PAIN2, S_PLAY_DIE1, S_PLAY_DIE2, S_PLAY_DIE3, S_PLAY_DIE4, S_PLAY_DIE5, S_PLAY_DIE6, S_PLAY_DIE7, S_PLAY_XDIE1, S_PLAY_XDIE2, S_PLAY_XDIE3, S_PLAY_XDIE4, S_PLAY_XDIE5, S_PLAY_XDIE6, S_PLAY_XDIE7, S_PLAY_XDIE8, S_PLAY_XDIE9, S_POSS_STND, S_POSS_STND2, S_POSS_RUN1, S_POSS_RUN2, S_POSS_RUN3, S_POSS_RUN4, S_POSS_RUN5, S_POSS_RUN6, S_POSS_RUN7, S_POSS_RUN8, S_POSS_ATK1, S_POSS_ATK2, S_POSS_ATK3, S_POSS_PAIN, S_POSS_PAIN2, S_POSS_DIE1, S_POSS_DIE2, S_POSS_DIE3, S_POSS_DIE4, S_POSS_DIE5, S_POSS_XDIE1, S_POSS_XDIE2, S_POSS_XDIE3, S_POSS_XDIE4, S_POSS_XDIE5, S_POSS_XDIE6, S_POSS_XDIE7, S_POSS_XDIE8, S_POSS_XDIE9, S_POSS_RAISE1, S_POSS_RAISE2, S_POSS_RAISE3, S_POSS_RAISE4, S_SPOS_STND, S_SPOS_STND2, S_SPOS_RUN1, S_SPOS_RUN2, S_SPOS_RUN3, S_SPOS_RUN4, S_SPOS_RUN5, S_SPOS_RUN6, S_SPOS_RUN7, S_SPOS_RUN8, S_SPOS_ATK1, S_SPOS_ATK2, S_SPOS_ATK3, S_SPOS_PAIN, S_SPOS_PAIN2, S_SPOS_DIE1, S_SPOS_DIE2, S_SPOS_DIE3, S_SPOS_DIE4, S_SPOS_DIE5, S_SPOS_XDIE1, S_SPOS_XDIE2, S_SPOS_XDIE3, S_SPOS_XDIE4, S_SPOS_XDIE5, S_SPOS_XDIE6, S_SPOS_XDIE7, S_SPOS_XDIE8, S_SPOS_XDIE9, S_SPOS_RAISE1, S_SPOS_RAISE2, S_SPOS_RAISE3, S_SPOS_RAISE4, S_SPOS_RAISE5, S_VILE_STND, S_VILE_STND2, S_VILE_RUN1, S_VILE_RUN2, S_VILE_RUN3, S_VILE_RUN4, S_VILE_RUN5, S_VILE_RUN6, S_VILE_RUN7, S_VILE_RUN8, S_VILE_RUN9, S_VILE_RUN10, S_VILE_RUN11, S_VILE_RUN12, S_VILE_ATK1, S_VILE_ATK2, S_VILE_ATK3, S_VILE_ATK4, S_VILE_ATK5, S_VILE_ATK6, S_VILE_ATK7, S_VILE_ATK8, S_VILE_ATK9, S_VILE_ATK10, S_VILE_ATK11, S_VILE_HEAL1, S_VILE_HEAL2, S_VILE_HEAL3, S_VILE_PAIN, S_VILE_PAIN2, S_VILE_DIE1, S_VILE_DIE2, S_VILE_DIE3, S_VILE_DIE4, S_VILE_DIE5, S_VILE_DIE6, S_VILE_DIE7, S_VILE_DIE8, S_VILE_DIE9, S_VILE_DIE10, S_FIRE1, S_FIRE2, S_FIRE3, S_FIRE4, S_FIRE5, S_FIRE6, S_FIRE7, S_FIRE8, S_FIRE9, S_FIRE10, S_FIRE11, S_FIRE12, S_FIRE13, S_FIRE14, S_FIRE15, S_FIRE16, S_FIRE17, S_FIRE18, S_FIRE19, S_FIRE20, S_FIRE21, S_FIRE22, S_FIRE23, S_FIRE24, S_FIRE25, S_FIRE26, S_FIRE27, S_FIRE28, S_FIRE29, S_FIRE30, S_SMOKE1, S_SMOKE2, S_SMOKE3, S_SMOKE4, S_SMOKE5, S_TRACER, S_TRACER2, S_TRACEEXP1, S_TRACEEXP2, S_TRACEEXP3, S_SKEL_STND, S_SKEL_STND2, S_SKEL_RUN1, S_SKEL_RUN2, S_SKEL_RUN3, S_SKEL_RUN4, S_SKEL_RUN5, S_SKEL_RUN6, S_SKEL_RUN7, S_SKEL_RUN8, S_SKEL_RUN9, S_SKEL_RUN10, S_SKEL_RUN11, S_SKEL_RUN12, S_SKEL_FIST1, S_SKEL_FIST2, S_SKEL_FIST3, S_SKEL_FIST4, S_SKEL_MISS1, S_SKEL_MISS2, S_SKEL_MISS3, S_SKEL_MISS4, S_SKEL_PAIN, S_SKEL_PAIN2, S_SKEL_DIE1, S_SKEL_DIE2, S_SKEL_DIE3, S_SKEL_DIE4, S_SKEL_DIE5, S_SKEL_DIE6, S_SKEL_RAISE1, S_SKEL_RAISE2, S_SKEL_RAISE3, S_SKEL_RAISE4, S_SKEL_RAISE5, S_SKEL_RAISE6, S_FATSHOT1, S_FATSHOT2, S_FATSHOTX1, S_FATSHOTX2, S_FATSHOTX3, S_FATT_STND, S_FATT_STND2, S_FATT_RUN1, S_FATT_RUN2, S_FATT_RUN3, S_FATT_RUN4, S_FATT_RUN5, S_FATT_RUN6, S_FATT_RUN7, S_FATT_RUN8, S_FATT_RUN9, S_FATT_RUN10, S_FATT_RUN11, S_FATT_RUN12, S_FATT_ATK1, S_FATT_ATK2, S_FATT_ATK3, S_FATT_ATK4, S_FATT_ATK5, S_FATT_ATK6, S_FATT_ATK7, S_FATT_ATK8, S_FATT_ATK9, S_FATT_ATK10, S_FATT_PAIN, S_FATT_PAIN2, S_FATT_DIE1, S_FATT_DIE2, S_FATT_DIE3, S_FATT_DIE4, S_FATT_DIE5, S_FATT_DIE6, S_FATT_DIE7, S_FATT_DIE8, S_FATT_DIE9, S_FATT_DIE10, S_FATT_RAISE1, S_FATT_RAISE2, S_FATT_RAISE3, S_FATT_RAISE4, S_FATT_RAISE5, S_FATT_RAISE6, S_FATT_RAISE7, S_FATT_RAISE8, S_CPOS_STND, S_CPOS_STND2, S_CPOS_RUN1, S_CPOS_RUN2, S_CPOS_RUN3, S_CPOS_RUN4, S_CPOS_RUN5, S_CPOS_RUN6, S_CPOS_RUN7, S_CPOS_RUN8, S_CPOS_ATK1, S_CPOS_ATK2, S_CPOS_ATK3, S_CPOS_ATK4, S_CPOS_PAIN, S_CPOS_PAIN2, S_CPOS_DIE1, S_CPOS_DIE2, S_CPOS_DIE3, S_CPOS_DIE4, S_CPOS_DIE5, S_CPOS_DIE6, S_CPOS_DIE7, S_CPOS_XDIE1, S_CPOS_XDIE2, S_CPOS_XDIE3, S_CPOS_XDIE4, S_CPOS_XDIE5, S_CPOS_XDIE6, S_CPOS_RAISE1, S_CPOS_RAISE2, S_CPOS_RAISE3, S_CPOS_RAISE4, S_CPOS_RAISE5, S_CPOS_RAISE6, S_CPOS_RAISE7, S_TROO_STND, S_TROO_STND2, S_TROO_RUN1, S_TROO_RUN2, S_TROO_RUN3, S_TROO_RUN4, S_TROO_RUN5, S_TROO_RUN6, S_TROO_RUN7, S_TROO_RUN8, S_TROO_ATK1, S_TROO_ATK2, S_TROO_ATK3, S_TROO_PAIN, S_TROO_PAIN2, S_TROO_DIE1, S_TROO_DIE2, S_TROO_DIE3, S_TROO_DIE4, S_TROO_DIE5, S_TROO_XDIE1, S_TROO_XDIE2, S_TROO_XDIE3, S_TROO_XDIE4, S_TROO_XDIE5, S_TROO_XDIE6, S_TROO_XDIE7, S_TROO_XDIE8, S_TROO_RAISE1, S_TROO_RAISE2, S_TROO_RAISE3, S_TROO_RAISE4, S_TROO_RAISE5, S_SARG_STND, S_SARG_STND2, S_SARG_RUN1, S_SARG_RUN2, S_SARG_RUN3, S_SARG_RUN4, S_SARG_RUN5, S_SARG_RUN6, S_SARG_RUN7, S_SARG_RUN8, S_SARG_ATK1, S_SARG_ATK2, S_SARG_ATK3, S_SARG_PAIN, S_SARG_PAIN2, S_SARG_DIE1, S_SARG_DIE2, S_SARG_DIE3, S_SARG_DIE4, S_SARG_DIE5, S_SARG_DIE6, S_SARG_RAISE1, S_SARG_RAISE2, S_SARG_RAISE3, S_SARG_RAISE4, S_SARG_RAISE5, S_SARG_RAISE6, S_HEAD_STND, S_HEAD_RUN1, S_HEAD_ATK1, S_HEAD_ATK2, S_HEAD_ATK3, S_HEAD_PAIN, S_HEAD_PAIN2, S_HEAD_PAIN3, S_HEAD_DIE1, S_HEAD_DIE2, S_HEAD_DIE3, S_HEAD_DIE4, S_HEAD_DIE5, S_HEAD_DIE6, S_HEAD_RAISE1, S_HEAD_RAISE2, S_HEAD_RAISE3, S_HEAD_RAISE4, S_HEAD_RAISE5, S_HEAD_RAISE6, S_BRBALL1, S_BRBALL2, S_BRBALLX1, S_BRBALLX2, S_BRBALLX3, S_BOSS_STND, S_BOSS_STND2, S_BOSS_RUN1, S_BOSS_RUN2, S_BOSS_RUN3, S_BOSS_RUN4, S_BOSS_RUN5, S_BOSS_RUN6, S_BOSS_RUN7, S_BOSS_RUN8, S_BOSS_ATK1, S_BOSS_ATK2, S_BOSS_ATK3, S_BOSS_PAIN, S_BOSS_PAIN2, S_BOSS_DIE1, S_BOSS_DIE2, S_BOSS_DIE3, S_BOSS_DIE4, S_BOSS_DIE5, S_BOSS_DIE6, S_BOSS_DIE7, S_BOSS_RAISE1, S_BOSS_RAISE2, S_BOSS_RAISE3, S_BOSS_RAISE4, S_BOSS_RAISE5, S_BOSS_RAISE6, S_BOSS_RAISE7, S_BOS2_STND, S_BOS2_STND2, S_BOS2_RUN1, S_BOS2_RUN2, S_BOS2_RUN3, S_BOS2_RUN4, S_BOS2_RUN5, S_BOS2_RUN6, S_BOS2_RUN7, S_BOS2_RUN8, S_BOS2_ATK1, S_BOS2_ATK2, S_BOS2_ATK3, S_BOS2_PAIN, S_BOS2_PAIN2, S_BOS2_DIE1, S_BOS2_DIE2, S_BOS2_DIE3, S_BOS2_DIE4, S_BOS2_DIE5, S_BOS2_DIE6, S_BOS2_DIE7, S_BOS2_RAISE1, S_BOS2_RAISE2, S_BOS2_RAISE3, S_BOS2_RAISE4, S_BOS2_RAISE5, S_BOS2_RAISE6, S_BOS2_RAISE7, S_SKULL_STND, S_SKULL_STND2, S_SKULL_RUN1, S_SKULL_RUN2, S_SKULL_ATK1, S_SKULL_ATK2, S_SKULL_ATK3, S_SKULL_ATK4, S_SKULL_PAIN, S_SKULL_PAIN2, S_SKULL_DIE1, S_SKULL_DIE2, S_SKULL_DIE3, S_SKULL_DIE4, S_SKULL_DIE5, S_SKULL_DIE6, S_SPID_STND, S_SPID_STND2, S_SPID_RUN1, S_SPID_RUN2, S_SPID_RUN3, S_SPID_RUN4, S_SPID_RUN5, S_SPID_RUN6, S_SPID_RUN7, S_SPID_RUN8, S_SPID_RUN9, S_SPID_RUN10, S_SPID_RUN11, S_SPID_RUN12, S_SPID_ATK1, S_SPID_ATK2, S_SPID_ATK3, S_SPID_ATK4, S_SPID_PAIN, S_SPID_PAIN2, S_SPID_DIE1, S_SPID_DIE2, S_SPID_DIE3, S_SPID_DIE4, S_SPID_DIE5, S_SPID_DIE6, S_SPID_DIE7, S_SPID_DIE8, S_SPID_DIE9, S_SPID_DIE10, S_SPID_DIE11, S_BSPI_STND, S_BSPI_STND2, S_BSPI_SIGHT, S_BSPI_RUN1, S_BSPI_RUN2, S_BSPI_RUN3, S_BSPI_RUN4, S_BSPI_RUN5, S_BSPI_RUN6, S_BSPI_RUN7, S_BSPI_RUN8, S_BSPI_RUN9, S_BSPI_RUN10, S_BSPI_RUN11, S_BSPI_RUN12, S_BSPI_ATK1, S_BSPI_ATK2, S_BSPI_ATK3, S_BSPI_ATK4, S_BSPI_PAIN, S_BSPI_PAIN2, S_BSPI_DIE1, S_BSPI_DIE2, S_BSPI_DIE3, S_BSPI_DIE4, S_BSPI_DIE5, S_BSPI_DIE6, S_BSPI_DIE7, S_BSPI_RAISE1, S_BSPI_RAISE2, S_BSPI_RAISE3, S_BSPI_RAISE4, S_BSPI_RAISE5, S_BSPI_RAISE6, S_BSPI_RAISE7, S_ARACH_PLAZ, S_ARACH_PLAZ2, S_ARACH_PLEX, S_ARACH_PLEX2, S_ARACH_PLEX3, S_ARACH_PLEX4, S_ARACH_PLEX5, S_CYBER_STND, S_CYBER_STND2, S_CYBER_RUN1, S_CYBER_RUN2, S_CYBER_RUN3, S_CYBER_RUN4, S_CYBER_RUN5, S_CYBER_RUN6, S_CYBER_RUN7, S_CYBER_RUN8, S_CYBER_ATK1, S_CYBER_ATK2, S_CYBER_ATK3, S_CYBER_ATK4, S_CYBER_ATK5, S_CYBER_ATK6, S_CYBER_PAIN, S_CYBER_DIE1, S_CYBER_DIE2, S_CYBER_DIE3, S_CYBER_DIE4, S_CYBER_DIE5, S_CYBER_DIE6, S_CYBER_DIE7, S_CYBER_DIE8, S_CYBER_DIE9, S_CYBER_DIE10, S_PAIN_STND, S_PAIN_RUN1, S_PAIN_RUN2, S_PAIN_RUN3, S_PAIN_RUN4, S_PAIN_RUN5, S_PAIN_RUN6, S_PAIN_ATK1, S_PAIN_ATK2, S_PAIN_ATK3, S_PAIN_ATK4, S_PAIN_PAIN, S_PAIN_PAIN2, S_PAIN_DIE1, S_PAIN_DIE2, S_PAIN_DIE3, S_PAIN_DIE4, S_PAIN_DIE5, S_PAIN_DIE6, S_PAIN_RAISE1, S_PAIN_RAISE2, S_PAIN_RAISE3, S_PAIN_RAISE4, S_PAIN_RAISE5, S_PAIN_RAISE6, S_SSWV_STND, S_SSWV_STND2, S_SSWV_RUN1, S_SSWV_RUN2, S_SSWV_RUN3, S_SSWV_RUN4, S_SSWV_RUN5, S_SSWV_RUN6, S_SSWV_RUN7, S_SSWV_RUN8, S_SSWV_ATK1, S_SSWV_ATK2, S_SSWV_ATK3, S_SSWV_ATK4, S_SSWV_ATK5, S_SSWV_ATK6, S_SSWV_PAIN, S_SSWV_PAIN2, S_SSWV_DIE1, S_SSWV_DIE2, S_SSWV_DIE3, S_SSWV_DIE4, S_SSWV_DIE5, S_SSWV_XDIE1, S_SSWV_XDIE2, S_SSWV_XDIE3, S_SSWV_XDIE4, S_SSWV_XDIE5, S_SSWV_XDIE6, S_SSWV_XDIE7, S_SSWV_XDIE8, S_SSWV_XDIE9, S_SSWV_RAISE1, S_SSWV_RAISE2, S_SSWV_RAISE3, S_SSWV_RAISE4, S_SSWV_RAISE5, S_KEENSTND, S_COMMKEEN, S_COMMKEEN2, S_COMMKEEN3, S_COMMKEEN4, S_COMMKEEN5, S_COMMKEEN6, S_COMMKEEN7, S_COMMKEEN8, S_COMMKEEN9, S_COMMKEEN10, S_COMMKEEN11, S_COMMKEEN12, S_KEENPAIN, S_KEENPAIN2, S_BRAIN, S_BRAIN_PAIN, S_BRAIN_DIE1, S_BRAIN_DIE2, S_BRAIN_DIE3, S_BRAIN_DIE4, S_BRAINEYE, S_BRAINEYESEE, S_BRAINEYE1, S_SPAWN1, S_SPAWN2, S_SPAWN3, S_SPAWN4, S_SPAWNFIRE1, S_SPAWNFIRE2, S_SPAWNFIRE3, S_SPAWNFIRE4, S_SPAWNFIRE5, S_SPAWNFIRE6, S_SPAWNFIRE7, S_SPAWNFIRE8, S_BRAINEXPLODE1, S_BRAINEXPLODE2, S_BRAINEXPLODE3, S_ARM1, S_ARM1A, S_ARM2, S_ARM2A, S_BAR1, S_BAR2, S_BEXP, S_BEXP2, S_BEXP3, S_BEXP4, S_BEXP5, S_BBAR1, S_BBAR2, S_BBAR3, S_BON1, S_BON1A, S_BON1B, S_BON1C, S_BON1D, S_BON1E, S_BON2, S_BON2A, S_BON2B, S_BON2C, S_BON2D, S_BON2E, S_BKEY, S_BKEY2, S_RKEY, S_RKEY2, S_YKEY, S_YKEY2, S_BSKULL, S_BSKULL2, S_RSKULL, S_RSKULL2, S_YSKULL, S_YSKULL2, S_STIM, S_MEDI, S_SOUL, S_SOUL2, S_SOUL3, S_SOUL4, S_SOUL5, S_SOUL6, S_PINV, S_PINV2, S_PINV3, S_PINV4, S_PSTR, S_PINS, S_PINS2, S_PINS3, S_PINS4, S_MEGA, S_MEGA2, S_MEGA3, S_MEGA4, S_SUIT, S_PMAP, S_PMAP2, S_PMAP3, S_PMAP4, S_PMAP5, S_PMAP6, S_PVIS, S_PVIS2, S_CLIP, S_AMMO, S_ROCK, S_BROK, S_CELL, S_CELP, S_SHEL, S_SBOX, S_BPAK, S_BFUG, S_MGUN, S_CSAW, S_LAUN, S_PLAS, S_SHOT, S_SHOT2, S_COLU, S_STALAG, S_BLOODYTWITCH, S_BLOODYTWITCH2, S_BLOODYTWITCH3, S_BLOODYTWITCH4, S_DEADTORSO, S_DEADBOTTOM, S_HEADSONSTICK, S_GIBS, S_HEADONASTICK, S_HEADCANDLES, S_HEADCANDLES2, S_DEADSTICK, S_LIVESTICK, S_LIVESTICK2, S_MEAT2, S_MEAT3, S_MEAT4, S_MEAT5, S_STALAGTITE, S_TALLGRNCOL, S_SHRTGRNCOL, S_TALLREDCOL, S_SHRTREDCOL, S_CANDLESTIK, S_CANDELABRA, S_SKULLCOL, S_TORCHTREE, S_BIGTREE, S_TECHPILLAR, S_EVILEYE, S_EVILEYE2, S_EVILEYE3, S_EVILEYE4, S_FLOATSKULL, S_FLOATSKULL2, S_FLOATSKULL3, S_HEARTCOL, S_HEARTCOL2, S_BLUETORCH, S_BLUETORCH2, S_BLUETORCH3, S_BLUETORCH4, S_GREENTORCH, S_GREENTORCH2, S_GREENTORCH3, S_GREENTORCH4, S_REDTORCH, S_REDTORCH2, S_REDTORCH3, S_REDTORCH4, S_BTORCHSHRT, S_BTORCHSHRT2, S_BTORCHSHRT3, S_BTORCHSHRT4, S_GTORCHSHRT, S_GTORCHSHRT2, S_GTORCHSHRT3, S_GTORCHSHRT4, S_RTORCHSHRT, S_RTORCHSHRT2, S_RTORCHSHRT3, S_RTORCHSHRT4, S_HANGNOGUTS, S_HANGBNOBRAIN, S_HANGTLOOKDN, S_HANGTSKULL, S_HANGTLOOKUP, S_HANGTNOBRAIN, S_COLONGIBS, S_SMALLPOOL, S_BRAINSTEM, S_TECHLAMP, S_TECHLAMP2, S_TECHLAMP3, S_TECHLAMP4, S_TECH2LAMP, S_TECH2LAMP2, S_TECH2LAMP3, S_TECH2LAMP4, NUMSTATES } statenum_t;
typedef struct { spritenum_t sprite; long frame; long tics; // void (*action) (); actionf_t action; statenum_t nextstate; long misc1, misc2; } state_t;
extern state_t states[NUMSTATES]; extern char *sprnames[NUMSPRITES];
typedef enum { MT_PLAYER, MT_POSSESSED, MT_SHOTGUY, MT_VILE, MT_FIRE, MT_UNDEAD, MT_TRACER, MT_SMOKE, MT_FATSO, MT_FATSHOT, MT_CHAINGUY, MT_TROOP, MT_SERGEANT, MT_SHADOWS, MT_HEAD, MT_BRUISER, MT_BRUISERSHOT, MT_KNIGHT, MT_SKULL, MT_SPIDER, MT_BABY, MT_CYBORG, MT_PAIN, MT_WOLFSS, MT_KEEN, MT_BOSSBRAIN, MT_BOSSSPIT, MT_BOSSTARGET, MT_SPAWNSHOT, MT_SPAWNFIRE, MT_BARREL, MT_TROOPSHOT, MT_HEADSHOT, MT_ROCKET, MT_PLASMA, MT_BFG, MT_ARACHPLAZ, MT_PUFF, MT_BLOOD, MT_TFOG, MT_IFOG, MT_TELEPORTMAN, MT_EXTRABFG, MT_MISC0, MT_MISC1, MT_MISC2, MT_MISC3, MT_MISC4, MT_MISC5, MT_MISC6, MT_MISC7, MT_MISC8, MT_MISC9, MT_MISC10, MT_MISC11, MT_MISC12, MT_INV, MT_MISC13, MT_INS, MT_MISC14, MT_MISC15, MT_MISC16, MT_MEGA, MT_CLIP, MT_MISC17, MT_MISC18, MT_MISC19, MT_MISC20, MT_MISC21, MT_MISC22, MT_MISC23, MT_MISC24, MT_MISC25, MT_CHAINGUN, MT_MISC26, MT_MISC27, MT_MISC28, MT_SHOTGUN, MT_SUPERSHOTGUN, MT_MISC29, MT_MISC30, MT_MISC31, MT_MISC32, MT_MISC33, MT_MISC34, MT_MISC35, MT_MISC36, MT_MISC37, MT_MISC38, MT_MISC39, MT_MISC40, MT_MISC41, MT_MISC42, MT_MISC43, MT_MISC44, MT_MISC45, MT_MISC46, MT_MISC47, MT_MISC48, MT_MISC49, MT_MISC50, MT_MISC51, MT_MISC52, MT_MISC53, MT_MISC54, MT_MISC55, MT_MISC56, MT_MISC57, MT_MISC58, MT_MISC59, MT_MISC60, MT_MISC61, MT_MISC62, MT_MISC63, MT_MISC64, MT_MISC65, MT_MISC66, MT_MISC67, MT_MISC68, MT_MISC69, MT_MISC70, MT_MISC71, MT_MISC72, MT_MISC73, MT_MISC74, MT_MISC75, MT_MISC76, MT_MISC77, MT_MISC78, MT_MISC79, MT_MISC80, MT_MISC81, MT_MISC82, MT_MISC83, MT_MISC84, MT_MISC85, MT_MISC86, NUMMOBJTYPES
} mobjtype_t;
typedef struct { int doomednum; int spawnstate; int spawnhealth; int seestate; int seesound; int reactiontime; int attacksound; int painstate; int painchance; int painsound; int meleestate; int missilestate; int deathstate; int xdeathstate; int deathsound; int speed; int radius; int height; int mass; int damage; int activesound; int flags; int raisestate;
} mobjinfo_t;
extern mobjinfo_t mobjinfo[NUMMOBJTYPES];
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: m_argv.c,v 1.1 1997/02/03 22:45:10 b1 Exp $";
#include <string.h>
int myargc; char** myargv;
// // M_CheckParm // Checks for the given parameter // in the program's command line arguments. // Returns the argument number (1 to argc-1) // or 0 if not present int M_CheckParm (char *check) { int i;
for (i = 1;i<myargc;i++) { if ( !strcasecmp(check, myargv[i]) ) return i; }
return 0; }
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // Nil. // //-----------------------------------------------------------------------------
#ifndef __M_ARGV__ #define __M_ARGV__
// // MISC // extern int myargc; extern char** myargv;
// Returns the position of the given parameter // in the arg list (0 if not found). int M_CheckParm (char* check);
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // Main loop menu stuff. // Random number LUT. // Default Config File. // PCX Screenshots. // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: m_bbox.c,v 1.1 1997/02/03 22:45:10 b1 Exp $";
#ifdef __GNUG__ #pragma implementation "m_bbox.h" #endif #include "m_bbox.h"
void M_ClearBox (fixed_t *box) { box[BOXTOP] = box[BOXRIGHT] = MININT; box[BOXBOTTOM] = box[BOXLEFT] = MAXINT; }
void M_AddToBox ( fixed_t* box, fixed_t x, fixed_t y ) { if (x<box[BOXLEFT]) box[BOXLEFT] = x; else if (x>box[BOXRIGHT]) box[BOXRIGHT] = x; if (y<box[BOXBOTTOM]) box[BOXBOTTOM] = y; else if (y>box[BOXTOP]) box[BOXTOP] = y; }
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // Nil. // //-----------------------------------------------------------------------------
#ifndef __M_BBOX__ #define __M_BBOX__
#include <values.h>
#include "m_fixed.h"
// Bounding box coordinate storage. enum { BOXTOP, BOXBOTTOM, BOXLEFT, BOXRIGHT }; // bbox coordinates
// Bounding box functions. void M_ClearBox (fixed_t* box);
void M_AddToBox ( fixed_t* box, fixed_t x, fixed_t y );
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // Cheat sequence checking. // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: m_cheat.c,v 1.1 1997/02/03 21:24:34 b1 Exp $";
#include "m_cheat.h"
// // CHEAT SEQUENCE PACKAGE //
static int firsttime = 1; static unsigned char cheat_xlate_table[256];
// // Called in st_stuff module, which handles the input. // Returns a 1 if the cheat was successful, 0 if failed. // int cht_CheckCheat ( cheatseq_t* cht, char key ) { int i; int rc = 0;
if (firsttime) { firsttime = 0; for (i=0;i<256;i++) cheat_xlate_table[i] = SCRAMBLE(i); }
if (!cht->p) cht->p = cht->sequence; // initialize if first time
if (*cht->p == 0) *(cht->p++) = key; else if (cheat_xlate_table[(unsigned char)key] == *cht->p) cht->p++; else cht->p = cht->sequence;
if (*cht->p == 1) cht->p++; else if (*cht->p == 0xff) // end of sequence character { cht->p = cht->sequence; rc = 1; }
return rc; }
void cht_GetParam ( cheatseq_t* cht, char* buffer ) {
unsigned char *p, c;
p = cht->sequence; while (*(p++) != 1);
do { c = *p; *(buffer++) = c; *(p++) = 0; } while (c && *p!=0xff );
if (*p==0xff) *buffer = 0;
}
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // Cheat code checking. // //-----------------------------------------------------------------------------
#ifndef __M_CHEAT__ #define __M_CHEAT__
// // CHEAT SEQUENCE PACKAGE //
#define SCRAMBLE(a) \ ((((a)&1)<<7) + (((a)&2)<<5) + ((a)&4) + (((a)&8)<<1) \ + (((a)&16)>>1) + ((a)&32) + (((a)&64)>>5) + (((a)&128)>>7))
typedef struct { unsigned char* sequence; unsigned char* p;
} cheatseq_t;
int cht_CheckCheat ( cheatseq_t* cht, char key );
void cht_GetParam ( cheatseq_t* cht, char* buffer );
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // Fixed point implementation. // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: m_bbox.c,v 1.1 1997/02/03 22:45:10 b1 Exp $";
#include "stdlib.h"
#include "doomtype.h" #include "i_system.h"
#ifdef __GNUG__ #pragma implementation "m_fixed.h" #endif #include "m_fixed.h"
// Fixme. __USE_C_FIXED__ or something.
fixed_t FixedMul ( fixed_t a, fixed_t b ) { return ((long long) a * (long long) b) >> FRACBITS; }
// // FixedDiv, C version. //
fixed_t FixedDiv ( fixed_t a, fixed_t b ) { if ( (abs(a)>>14) >= abs(b)) return (a^b)<0 ? MININT : MAXINT; return FixedDiv2 (a,b); }
fixed_t FixedDiv2 ( fixed_t a, fixed_t b ) { #if 0 long long c; c = ((long long)a<<16) / ((long long)b); return (fixed_t) c; #endif
double c;
c = ((double)a) / ((double)b) * FRACUNIT;
if (c >= 2147483648.0 || c < -2147483648.0) I_Error("FixedDiv: divide by zero"); return (fixed_t) c; } // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // Fixed point arithemtics, implementation. // //-----------------------------------------------------------------------------
#ifndef __M_FIXED__ #define __M_FIXED__
#ifdef __GNUG__ #pragma interface #endif
// // Fixed point, 32bit as 16.16. // #define FRACBITS 16 #define FRACUNIT (1<<FRACBITS)
typedef int fixed_t;
fixed_t FixedMul (fixed_t a, fixed_t b); fixed_t FixedDiv (fixed_t a, fixed_t b); fixed_t FixedDiv2 (fixed_t a, fixed_t b);
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // DOOM selection menu, options, episode etc. // Sliders and icons. Kinda widget stuff. // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: m_menu.c,v 1.7 1997/02/03 22:45:10 b1 Exp $";
#include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <ctype.h>
#include "doomdef.h" #include "dstrings.h"
#include "d_main.h"
#include "i_system.h" #include "i_video.h" #include "z_zone.h" #include "v_video.h" #include "w_wad.h"
#include "r_local.h"
#include "hu_stuff.h"
#include "g_game.h"
#include "m_argv.h" #include "m_swap.h"
#include "s_sound.h"
#include "doomstat.h"
// Data. #include "sounds.h"
#include "m_menu.h"
extern patch_t* hu_font[HU_FONTSIZE]; extern boolean message_dontfuckwithme;
extern boolean chat_on; // in heads-up code
// // defaulted values // int mouseSensitivity; // has default
// Show messages has default, 0 = off, 1 = on int showMessages;
// Blocky mode, has default, 0 = high, 1 = normal int detailLevel; int screenblocks; // has default
// temp for screenblocks (0-9) int screenSize;
// -1 = no quicksave slot picked! int quickSaveSlot;
// 1 = message to be printed int messageToPrint; // ...and here is the message string! char* messageString;
// message x & y int messx; int messy; int messageLastMenuActive;
// timed message = no input from user boolean messageNeedsInput;
void (*messageRoutine)(int response);
#define SAVESTRINGSIZE 24
char gammamsg[5][26] = { GAMMALVL0, GAMMALVL1, GAMMALVL2, GAMMALVL3, GAMMALVL4 };
// we are going to be entering a savegame string int saveStringEnter; int saveSlot; // which slot to save in int saveCharIndex; // which char we're editing // old save description before edit char saveOldString[SAVESTRINGSIZE];
boolean inhelpscreens; boolean menuactive;
#define SKULLXOFF -32 #define LINEHEIGHT 16
extern boolean sendpause; char savegamestrings[10][SAVESTRINGSIZE];
char endstring[160];
// // MENU TYPEDEFS // typedef struct { // 0 = no cursor here, 1 = ok, 2 = arrows ok short status;
char name[10];
// choice = menu item #. // if status = 2, // choice=0:leftarrow,1:rightarrow void (*routine)(int choice);
// hotkey in menu char alphaKey; } menuitem_t;
typedef struct menu_s { short numitems; // # of menu items struct menu_s* prevMenu; // previous menu menuitem_t* menuitems; // menu items void (*routine)(); // draw routine short x; short y; // x,y of menu short lastOn; // last item user was on in menu } menu_t;
short itemOn; // menu item skull is on short skullAnimCounter; // skull animation counter short whichSkull; // which skull to draw
// graphic name of skulls // warning: initializer-string for array of chars is too long char skullName[2][/*8*/9] = {"M_SKULL1","M_SKULL2"};
// current menudef menu_t* currentMenu;
// // PROTOTYPES // void M_NewGame(int choice); void M_Episode(int choice); void M_ChooseSkill(int choice); void M_LoadGame(int choice); void M_SaveGame(int choice); void M_Options(int choice); void M_EndGame(int choice); void M_ReadThis(int choice); void M_ReadThis2(int choice); void M_QuitDOOM(int choice);
void M_ChangeMessages(int choice); void M_ChangeSensitivity(int choice); void M_SfxVol(int choice); void M_MusicVol(int choice); void M_ChangeDetail(int choice); void M_SizeDisplay(int choice); void M_StartGame(int choice); void M_Sound(int choice);
void M_FinishReadThis(int choice); void M_LoadSelect(int choice); void M_SaveSelect(int choice); void M_ReadSaveStrings(void); void M_QuickSave(void); void M_QuickLoad(void);
void M_DrawMainMenu(void); void M_DrawReadThis1(void); void M_DrawReadThis2(void); void M_DrawNewGame(void); void M_DrawEpisode(void); void M_DrawOptions(void); void M_DrawSound(void); void M_DrawLoad(void); void M_DrawSave(void);
void M_DrawSaveLoadBorder(int x,int y); void M_SetupNextMenu(menu_t *menudef); void M_DrawThermo(int x,int y,int thermWidth,int thermDot); void M_DrawEmptyCell(menu_t *menu,int item); void M_DrawSelCell(menu_t *menu,int item); void M_WriteText(int x, int y, char *string); int M_StringWidth(char *string); int M_StringHeight(char *string); void M_StartControlPanel(void); void M_StartMessage(char *string,void *routine,boolean input); void M_StopMessage(void); void M_ClearMenus (void);
// // DOOM MENU // enum { newgame = 0, options, loadgame, savegame, readthis, quitdoom, main_end } main_e;
menuitem_t MainMenu[]= { {1,"M_NGAME",M_NewGame,'n'}, {1,"M_OPTION",M_Options,'o'}, {1,"M_LOADG",M_LoadGame,'l'}, {1,"M_SAVEG",M_SaveGame,'s'}, // Another hickup with Special edition. {1,"M_RDTHIS",M_ReadThis,'r'}, {1,"M_QUITG",M_QuitDOOM,'q'} };
menu_t MainDef = { main_end, NULL, MainMenu, M_DrawMainMenu, 97,64, 0 };
// // EPISODE SELECT // enum { ep1, ep2, ep3, ep4, ep_end } episodes_e;
menuitem_t EpisodeMenu[]= { {1,"M_EPI1", M_Episode,'k'}, {1,"M_EPI2", M_Episode,'t'}, {1,"M_EPI3", M_Episode,'i'}, {1,"M_EPI4", M_Episode,'t'} };
menu_t EpiDef = { ep_end, // # of menu items &MainDef, // previous menu EpisodeMenu, // menuitem_t -> M_DrawEpisode, // drawing routine -> 48,63, // x,y ep1 // lastOn };
// // NEW GAME // enum { killthings, toorough, hurtme, violence, nightmare, newg_end } newgame_e;
menuitem_t NewGameMenu[]= { {1,"M_JKILL", M_ChooseSkill, 'i'}, {1,"M_ROUGH", M_ChooseSkill, 'h'}, {1,"M_HURT", M_ChooseSkill, 'h'}, {1,"M_ULTRA", M_ChooseSkill, 'u'}, {1,"M_NMARE", M_ChooseSkill, 'n'} };
menu_t NewDef = { newg_end, // # of menu items &EpiDef, // previous menu NewGameMenu, // menuitem_t -> M_DrawNewGame, // drawing routine -> 48,63, // x,y hurtme // lastOn };
// // OPTIONS MENU // enum { endgame, messages, detail, scrnsize, option_empty1, mousesens, option_empty2, soundvol, opt_end } options_e;
menuitem_t OptionsMenu[]= { {1,"M_ENDGAM", M_EndGame,'e'}, {1,"M_MESSG", M_ChangeMessages,'m'}, {1,"M_DETAIL", M_ChangeDetail,'g'}, {2,"M_SCRNSZ", M_SizeDisplay,'s'}, {-1,"",0}, {2,"M_MSENS", M_ChangeSensitivity,'m'}, {-1,"",0}, {1,"M_SVOL", M_Sound,'s'} };
menu_t OptionsDef = { opt_end, &MainDef, OptionsMenu, M_DrawOptions, 60,37, 0 };
// // Read This! MENU 1 & 2 // enum { rdthsempty1, read1_end } read_e;
menuitem_t ReadMenu1[] = { {1,"",M_ReadThis2,0} };
menu_t ReadDef1 = { read1_end, &MainDef, ReadMenu1, M_DrawReadThis1, 280,185, 0 };
enum { rdthsempty2, read2_end } read_e2;
menuitem_t ReadMenu2[]= { {1,"",M_FinishReadThis,0} };
menu_t ReadDef2 = { read2_end, &ReadDef1, ReadMenu2, M_DrawReadThis2, 330,175, 0 };
// // SOUND VOLUME MENU // enum { sfx_vol, sfx_empty1, music_vol, sfx_empty2, sound_end } sound_e;
menuitem_t SoundMenu[]= { {2,"M_SFXVOL",M_SfxVol,'s'}, {-1,"",0}, {2,"M_MUSVOL",M_MusicVol,'m'}, {-1,"",0} };
menu_t SoundDef = { sound_end, &OptionsDef, SoundMenu, M_DrawSound, 80,64, 0 };
// // LOAD GAME MENU // enum { load1, load2, load3, load4, load5, load6, load_end } load_e;
menuitem_t LoadMenu[]= { {1,"", M_LoadSelect,'1'}, {1,"", M_LoadSelect,'2'}, {1,"", M_LoadSelect,'3'}, {1,"", M_LoadSelect,'4'}, {1,"", M_LoadSelect,'5'}, {1,"", M_LoadSelect,'6'} };
menu_t LoadDef = { load_end, &MainDef, LoadMenu, M_DrawLoad, 80,54, 0 };
// // SAVE GAME MENU // menuitem_t SaveMenu[]= { {1,"", M_SaveSelect,'1'}, {1,"", M_SaveSelect,'2'}, {1,"", M_SaveSelect,'3'}, {1,"", M_SaveSelect,'4'}, {1,"", M_SaveSelect,'5'}, {1,"", M_SaveSelect,'6'} };
menu_t SaveDef = { load_end, &MainDef, SaveMenu, M_DrawSave, 80,54, 0 };
// // M_ReadSaveStrings // read the strings from the savegame files // void M_ReadSaveStrings(void) { int handle; int count; int i; char name[256]; for (i = 0;i < load_end;i++) { if (M_CheckParm("-cdrom")) sprintf(name,"c:\\doomdata\\"SAVEGAMENAME"%d.dsg",i); else sprintf(name,SAVEGAMENAME"%d.dsg",i);
handle = open (name, O_RDONLY | 0, 0666); if (handle == -1) { strcpy(&savegamestrings[i][0],EMPTYSTRING); LoadMenu[i].status = 0; continue; } count = read (handle, &savegamestrings[i], SAVESTRINGSIZE); close (handle); LoadMenu[i].status = 1; } }
// // M_LoadGame & Cie. // void M_DrawLoad(void) { int i; V_DrawPatchDirect (72,28,0,W_CacheLumpName("M_LOADG",PU_CACHE)); for (i = 0;i < load_end; i++) { M_DrawSaveLoadBorder(LoadDef.x,LoadDef.y+LINEHEIGHT*i); M_WriteText(LoadDef.x,LoadDef.y+LINEHEIGHT*i,savegamestrings[i]); } }
// // Draw border for the savegame description // void M_DrawSaveLoadBorder(int x,int y) { int i; V_DrawPatchDirect (x-8,y+7,0,W_CacheLumpName("M_LSLEFT",PU_CACHE)); for (i = 0;i < 24;i++) { V_DrawPatchDirect (x,y+7,0,W_CacheLumpName("M_LSCNTR",PU_CACHE)); x += 8; }
V_DrawPatchDirect (x,y+7,0,W_CacheLumpName("M_LSRGHT",PU_CACHE)); }
// // User wants to load this game // void M_LoadSelect(int choice) { char name[256]; if (M_CheckParm("-cdrom")) sprintf(name,"c:\\doomdata\\"SAVEGAMENAME"%d.dsg",choice); else sprintf(name,SAVEGAMENAME"%d.dsg",choice); G_LoadGame (name); M_ClearMenus (); }
// // Selected from DOOM menu // void M_LoadGame (int choice) { if (netgame) { M_StartMessage(LOADNET,NULL,false); return; } M_SetupNextMenu(&LoadDef); M_ReadSaveStrings(); }
// // M_SaveGame & Cie. // void M_DrawSave(void) { int i; V_DrawPatchDirect (72,28,0,W_CacheLumpName("M_SAVEG",PU_CACHE)); for (i = 0;i < load_end; i++) { M_DrawSaveLoadBorder(LoadDef.x,LoadDef.y+LINEHEIGHT*i); M_WriteText(LoadDef.x,LoadDef.y+LINEHEIGHT*i,savegamestrings[i]); } if (saveStringEnter) { i = M_StringWidth(savegamestrings[saveSlot]); M_WriteText(LoadDef.x + i,LoadDef.y+LINEHEIGHT*saveSlot,"_"); } }
// // M_Responder calls this when user is finished // void M_DoSave(int slot) { G_SaveGame (slot,savegamestrings[slot]); M_ClearMenus ();
// PICK QUICKSAVE SLOT YET? if (quickSaveSlot == -2) quickSaveSlot = slot; }
// // User wants to save. Start string input for M_Responder // void M_SaveSelect(int choice) { // we are going to be intercepting all chars saveStringEnter = 1;
saveSlot = choice; strcpy(saveOldString,savegamestrings[choice]); if (!strcmp(savegamestrings[choice],EMPTYSTRING)) savegamestrings[choice][0] = 0; saveCharIndex = strlen(savegamestrings[choice]); }
// // Selected from DOOM menu // void M_SaveGame (int choice) { if (!usergame) { M_StartMessage(SAVEDEAD,NULL,false); return; } if (gamestate != GS_LEVEL) return; M_SetupNextMenu(&SaveDef); M_ReadSaveStrings(); }
// // M_QuickSave // char tempstring[80];
void M_QuickSaveResponse(int ch) { if (ch == 'y') { M_DoSave(quickSaveSlot); S_StartSound(NULL,sfx_swtchx); } }
void M_QuickSave(void) { if (!usergame) { S_StartSound(NULL,sfx_oof); return; }
if (gamestate != GS_LEVEL) return; if (quickSaveSlot < 0) { M_StartControlPanel(); M_ReadSaveStrings(); M_SetupNextMenu(&SaveDef); quickSaveSlot = -2; // means to pick a slot now return; } sprintf(tempstring,QSPROMPT,savegamestrings[quickSaveSlot]); M_StartMessage(tempstring,M_QuickSaveResponse,true); }
// // M_QuickLoad // void M_QuickLoadResponse(int ch) { if (ch == 'y') { M_LoadSelect(quickSaveSlot); S_StartSound(NULL,sfx_swtchx); } }
void M_QuickLoad(void) { if (netgame) { M_StartMessage(QLOADNET,NULL,false); return; } if (quickSaveSlot < 0) { M_StartMessage(QSAVESPOT,NULL,false); return; } sprintf(tempstring,QLPROMPT,savegamestrings[quickSaveSlot]); M_StartMessage(tempstring,M_QuickLoadResponse,true); }
// // Read This Menus // Had a "quick hack to fix romero bug" // void M_DrawReadThis1(void) { inhelpscreens = true; switch ( gamemode ) { case commercial: V_DrawPatchDirect (0,0,0,W_CacheLumpName("HELP",PU_CACHE)); break; case shareware: case registered: case retail: V_DrawPatchDirect (0,0,0,W_CacheLumpName("HELP1",PU_CACHE)); break; default: break; } return; }
// // Read This Menus - optional second page. // void M_DrawReadThis2(void) { inhelpscreens = true; switch ( gamemode ) { case retail: case commercial: // This hack keeps us from having to change menus. V_DrawPatchDirect (0,0,0,W_CacheLumpName("CREDIT",PU_CACHE)); break; case shareware: case registered: V_DrawPatchDirect (0,0,0,W_CacheLumpName("HELP2",PU_CACHE)); break; default: break; } return; }
// // Change Sfx & Music volumes // void M_DrawSound(void) { V_DrawPatchDirect (60,38,0,W_CacheLumpName("M_SVOL",PU_CACHE));
M_DrawThermo(SoundDef.x,SoundDef.y+LINEHEIGHT*(sfx_vol+1), 16,snd_SfxVolume);
M_DrawThermo(SoundDef.x,SoundDef.y+LINEHEIGHT*(music_vol+1), 16,snd_MusicVolume); }
void M_Sound(int choice) { M_SetupNextMenu(&SoundDef); }
void M_SfxVol(int choice) { switch(choice) { case 0: if (snd_SfxVolume) snd_SfxVolume--; break; case 1: if (snd_SfxVolume < 15) snd_SfxVolume++; break; } S_SetSfxVolume(snd_SfxVolume /* *8 */); }
void M_MusicVol(int choice) { switch(choice) { case 0: if (snd_MusicVolume) snd_MusicVolume--; break; case 1: if (snd_MusicVolume < 15) snd_MusicVolume++; break; } S_SetMusicVolume(snd_MusicVolume /* *8 */); }
// // M_DrawMainMenu // void M_DrawMainMenu(void) { V_DrawPatchDirect (94,2,0,W_CacheLumpName("M_DOOM",PU_CACHE)); }
// // M_NewGame // void M_DrawNewGame(void) { V_DrawPatchDirect (96,14,0,W_CacheLumpName("M_NEWG",PU_CACHE)); V_DrawPatchDirect (54,38,0,W_CacheLumpName("M_SKILL",PU_CACHE)); }
void M_NewGame(int choice) { if (netgame && !demoplayback) { M_StartMessage(NEWGAME,NULL,false); return; } if ( gamemode == commercial ) M_SetupNextMenu(&NewDef); else M_SetupNextMenu(&EpiDef); }
// // M_Episode // int epi;
void M_DrawEpisode(void) { V_DrawPatchDirect (54,38,0,W_CacheLumpName("M_EPISOD",PU_CACHE)); }
void M_VerifyNightmare(int ch) { if (ch != 'y') return; G_DeferedInitNew(nightmare,epi+1,1); M_ClearMenus (); }
void M_ChooseSkill(int choice) { if (choice == nightmare) { M_StartMessage(NIGHTMARE,M_VerifyNightmare,true); return; } G_DeferedInitNew(choice,epi+1,1); M_ClearMenus (); }
void M_Episode(int choice) { if ( (gamemode == shareware) && choice) { M_StartMessage(SWSTRING,NULL,false); M_SetupNextMenu(&ReadDef1); return; }
// Yet another hack... if ( (gamemode == registered) && (choice > 2)) { fprintf( stderr, "M_Episode: 4th episode requires UltimateDOOM\n"); choice = 0; } epi = choice; M_SetupNextMenu(&NewDef); }
// // M_Options // char detailNames[2][9] = {"M_GDHIGH","M_GDLOW"}; char msgNames[2][9] = {"M_MSGOFF","M_MSGON"};
void M_DrawOptions(void) { V_DrawPatchDirect (108,15,0,W_CacheLumpName("M_OPTTTL",PU_CACHE)); V_DrawPatchDirect (OptionsDef.x + 175,OptionsDef.y+LINEHEIGHT*detail,0, W_CacheLumpName(detailNames[detailLevel],PU_CACHE));
V_DrawPatchDirect (OptionsDef.x + 120,OptionsDef.y+LINEHEIGHT*messages,0, W_CacheLumpName(msgNames[showMessages],PU_CACHE));
M_DrawThermo(OptionsDef.x,OptionsDef.y+LINEHEIGHT*(mousesens+1), 10,mouseSensitivity); M_DrawThermo(OptionsDef.x,OptionsDef.y+LINEHEIGHT*(scrnsize+1), 9,screenSize); }
void M_Options(int choice) { M_SetupNextMenu(&OptionsDef); }
// // Toggle messages on/off // void M_ChangeMessages(int choice) { // warning: unused parameter `int choice' choice = 0; showMessages = 1 - showMessages; if (!showMessages) players[consoleplayer].message = MSGOFF; else players[consoleplayer].message = MSGON ;
message_dontfuckwithme = true; }
// // M_EndGame // void M_EndGameResponse(int ch) { if (ch != 'y') return; currentMenu->lastOn = itemOn; M_ClearMenus (); D_StartTitle (); }
void M_EndGame(int choice) { choice = 0; if (!usergame) { S_StartSound(NULL,sfx_oof); return; } if (netgame) { M_StartMessage(NETEND,NULL,false); return; } M_StartMessage(ENDGAME,M_EndGameResponse,true); }
// // M_ReadThis // void M_ReadThis(int choice) { choice = 0; M_SetupNextMenu(&ReadDef1); }
void M_ReadThis2(int choice) { choice = 0; M_SetupNextMenu(&ReadDef2); }
void M_FinishReadThis(int choice) { choice = 0; M_SetupNextMenu(&MainDef); }
// // M_QuitDOOM // int quitsounds[8] = { sfx_pldeth, sfx_dmpain, sfx_popain, sfx_slop, sfx_telept, sfx_posit1, sfx_posit3, sfx_sgtatk };
int quitsounds2[8] = { sfx_vilact, sfx_getpow, sfx_boscub, sfx_slop, sfx_skeswg, sfx_kntdth, sfx_bspact, sfx_sgtatk };
void M_QuitResponse(int ch) { if (ch != 'y') return; if (!netgame) { if (gamemode == commercial) S_StartSound(NULL,quitsounds2[(gametic>>2)&7]); else S_StartSound(NULL,quitsounds[(gametic>>2)&7]); I_WaitVBL(105); } I_Quit (); }
void M_QuitDOOM(int choice) { // We pick index 0 which is language sensitive, // or one at random, between 1 and maximum number. if (language != english ) sprintf(endstring,"%s\n\n"DOSY, endmsg[0] ); else sprintf(endstring,"%s\n\n"DOSY, endmsg[ (gametic%(NUM_QUITMESSAGES-2))+1 ]);
M_StartMessage(endstring,M_QuitResponse,true); }
void M_ChangeSensitivity(int choice) { switch(choice) { case 0: if (mouseSensitivity) mouseSensitivity--; break; case 1: if (mouseSensitivity < 9) mouseSensitivity++; break; } }
void M_ChangeDetail(int choice) { choice = 0; detailLevel = 1 - detailLevel;
// FIXME - does not work. Remove anyway? fprintf( stderr, "M_ChangeDetail: low detail mode n.a.\n");
return;
/*R_SetViewSize (screenblocks, detailLevel);
if (!detailLevel) players[consoleplayer].message = DETAILHI; else players[consoleplayer].message = DETAILLO;*/ }
void M_SizeDisplay(int choice) { switch(choice) { case 0: if (screenSize > 0) { screenblocks--; screenSize--; } break; case 1: if (screenSize < 8) { screenblocks++; screenSize++; } break; }
R_SetViewSize (screenblocks, detailLevel); }
// // Menu Functions // void M_DrawThermo ( int x, int y, int thermWidth, int thermDot ) { int xx; int i;
xx = x; V_DrawPatchDirect (xx,y,0,W_CacheLumpName("M_THERML",PU_CACHE)); xx += 8; for (i=0;i<thermWidth;i++) { V_DrawPatchDirect (xx,y,0,W_CacheLumpName("M_THERMM",PU_CACHE)); xx += 8; } V_DrawPatchDirect (xx,y,0,W_CacheLumpName("M_THERMR",PU_CACHE));
V_DrawPatchDirect ((x+8) + thermDot*8,y, 0,W_CacheLumpName("M_THERMO",PU_CACHE)); }
void M_DrawEmptyCell ( menu_t* menu, int item ) { V_DrawPatchDirect (menu->x - 10, menu->y+item*LINEHEIGHT - 1, 0, W_CacheLumpName("M_CELL1",PU_CACHE)); }
void M_DrawSelCell ( menu_t* menu, int item ) { V_DrawPatchDirect (menu->x - 10, menu->y+item*LINEHEIGHT - 1, 0, W_CacheLumpName("M_CELL2",PU_CACHE)); }
void M_StartMessage ( char* string, void* routine, boolean input ) { messageLastMenuActive = menuactive; messageToPrint = 1; messageString = string; messageRoutine = routine; messageNeedsInput = input; menuactive = true; return; }
void M_StopMessage(void) { menuactive = messageLastMenuActive; messageToPrint = 0; }
// // Find string width from hu_font chars // int M_StringWidth(char* string) { int i; int w = 0; int c; for (i = 0;i < strlen(string);i++) { c = toupper(string[i]) - HU_FONTSTART; if (c < 0 || c >= HU_FONTSIZE) w += 4; else w += SHORT (hu_font[c]->width); } return w; }
// // Find string height from hu_font chars // int M_StringHeight(char* string) { int i; int h; int height = SHORT(hu_font[0]->height); h = height; for (i = 0;i < strlen(string);i++) if (string[i] == '\n') h += height; return h; }
// // Write a string using the hu_font // void M_WriteText ( int x, int y, char* string) { int w; char* ch; int c; int cx; int cy;
ch = string; cx = x; cy = y; while(1) { c = *ch++; if (!c) break; if (c == '\n') { cx = x; cy += 12; continue; } c = toupper(c) - HU_FONTSTART; if (c < 0 || c>= HU_FONTSIZE) { cx += 4; continue; } w = SHORT (hu_font[c]->width); if (cx+w > SCREENWIDTH) break; V_DrawPatchDirect(cx, cy, 0, hu_font[c]); cx+=w; } }
// // CONTROL PANEL //
// // M_Responder // boolean M_Responder (event_t* ev) { int ch; int i; static int joywait = 0; static int mousewait = 0; static int mousey = 0; static int lasty = 0; static int mousex = 0; static int lastx = 0; ch = -1; if (ev->type == ev_joystick && joywait < I_GetTime()) { if (ev->data3 == -1) { ch = KEY_UPARROW; joywait = I_GetTime() + 5; } else if (ev->data3 == 1) { ch = KEY_DOWNARROW; joywait = I_GetTime() + 5; } if (ev->data2 == -1) { ch = KEY_LEFTARROW; joywait = I_GetTime() + 2; } else if (ev->data2 == 1) { ch = KEY_RIGHTARROW; joywait = I_GetTime() + 2; } if (ev->data1&1) { ch = KEY_ENTER; joywait = I_GetTime() + 5; } if (ev->data1&2) { ch = KEY_BACKSPACE; joywait = I_GetTime() + 5; } } else { if (ev->type == ev_mouse && mousewait < I_GetTime()) { mousey += ev->data3; if (mousey < lasty-30) { ch = KEY_DOWNARROW; mousewait = I_GetTime() + 5; mousey = lasty -= 30; } else if (mousey > lasty+30) { ch = KEY_UPARROW; mousewait = I_GetTime() + 5; mousey = lasty += 30; } mousex += ev->data2; if (mousex < lastx-30) { ch = KEY_LEFTARROW; mousewait = I_GetTime() + 5; mousex = lastx -= 30; } else if (mousex > lastx+30) { ch = KEY_RIGHTARROW; mousewait = I_GetTime() + 5; mousex = lastx += 30; } if (ev->data1&1) { ch = KEY_ENTER; mousewait = I_GetTime() + 15; } if (ev->data1&2) { ch = KEY_BACKSPACE; mousewait = I_GetTime() + 15; } } else if (ev->type == ev_keydown) { ch = ev->data1; } }
if (ch == -1) return false;
// Save Game string input if (saveStringEnter) { switch(ch) { case KEY_BACKSPACE: if (saveCharIndex > 0) { saveCharIndex--; savegamestrings[saveSlot][saveCharIndex] = 0; } break; case KEY_ESCAPE: saveStringEnter = 0; strcpy(&savegamestrings[saveSlot][0],saveOldString); break; case KEY_ENTER: saveStringEnter = 0; if (savegamestrings[saveSlot][0]) M_DoSave(saveSlot); break; default: ch = toupper(ch); if (ch != 32) if (ch-HU_FONTSTART < 0 || ch-HU_FONTSTART >= HU_FONTSIZE) break; if (ch >= 32 && ch <= 127 && saveCharIndex < SAVESTRINGSIZE-1 && M_StringWidth(savegamestrings[saveSlot]) < (SAVESTRINGSIZE-2)*8) { savegamestrings[saveSlot][saveCharIndex++] = ch; savegamestrings[saveSlot][saveCharIndex] = 0; } break; } return true; }
// Take care of any messages that need input if (messageToPrint) { if (messageNeedsInput == true && !(ch == ' ' || ch == 'n' || ch == 'y' || ch == KEY_ESCAPE)) return false; menuactive = messageLastMenuActive; messageToPrint = 0; if (messageRoutine) messageRoutine(ch); menuactive = false; S_StartSound(NULL,sfx_swtchx); return true; } if (devparm && ch == KEY_F1) { G_ScreenShot (); return true; }
// F-Keys if (!menuactive) switch(ch) { case KEY_MINUS: // Screen size down if (automapactive || chat_on) return false; M_SizeDisplay(0); S_StartSound(NULL,sfx_stnmov); return true; case KEY_EQUALS: // Screen size up if (automapactive || chat_on) return false; M_SizeDisplay(1); S_StartSound(NULL,sfx_stnmov); return true; case KEY_F1: // Help key M_StartControlPanel ();
if ( gamemode == retail ) currentMenu = &ReadDef2; else currentMenu = &ReadDef1; itemOn = 0; S_StartSound(NULL,sfx_swtchn); return true; case KEY_F2: // Save M_StartControlPanel(); S_StartSound(NULL,sfx_swtchn); M_SaveGame(0); return true; case KEY_F3: // Load M_StartControlPanel(); S_StartSound(NULL,sfx_swtchn); M_LoadGame(0); return true; case KEY_F4: // Sound Volume M_StartControlPanel (); currentMenu = &SoundDef; itemOn = sfx_vol; S_StartSound(NULL,sfx_swtchn); return true; case KEY_F5: // Detail toggle M_ChangeDetail(0); S_StartSound(NULL,sfx_swtchn); return true; case KEY_F6: // Quicksave S_StartSound(NULL,sfx_swtchn); M_QuickSave(); return true; case KEY_F7: // End game S_StartSound(NULL,sfx_swtchn); M_EndGame(0); return true; case KEY_F8: // Toggle messages M_ChangeMessages(0); S_StartSound(NULL,sfx_swtchn); return true; case KEY_F9: // Quickload S_StartSound(NULL,sfx_swtchn); M_QuickLoad(); return true; case KEY_F10: // Quit DOOM S_StartSound(NULL,sfx_swtchn); M_QuitDOOM(0); return true; case KEY_F11: // gamma toggle usegamma++; if (usegamma > 4) usegamma = 0; players[consoleplayer].message = gammamsg[usegamma]; I_SetPalette (W_CacheLumpName ("PLAYPAL",PU_CACHE)); return true; }
// Pop-up menu? if (!menuactive) { if (ch == KEY_ESCAPE) { M_StartControlPanel (); S_StartSound(NULL,sfx_swtchn); return true; } return false; }
// Keys usable within menu switch (ch) { case KEY_DOWNARROW: do { if (itemOn+1 > currentMenu->numitems-1) itemOn = 0; else itemOn++; S_StartSound(NULL,sfx_pstop); } while(currentMenu->menuitems[itemOn].status==-1); return true; case KEY_UPARROW: do { if (!itemOn) itemOn = currentMenu->numitems-1; else itemOn--; S_StartSound(NULL,sfx_pstop); } while(currentMenu->menuitems[itemOn].status==-1); return true;
case KEY_LEFTARROW: if (currentMenu->menuitems[itemOn].routine && currentMenu->menuitems[itemOn].status == 2) { S_StartSound(NULL,sfx_stnmov); currentMenu->menuitems[itemOn].routine(0); } return true; case KEY_RIGHTARROW: if (currentMenu->menuitems[itemOn].routine && currentMenu->menuitems[itemOn].status == 2) { S_StartSound(NULL,sfx_stnmov); currentMenu->menuitems[itemOn].routine(1); } return true;
case KEY_ENTER: if (currentMenu->menuitems[itemOn].routine && currentMenu->menuitems[itemOn].status) { currentMenu->lastOn = itemOn; if (currentMenu->menuitems[itemOn].status == 2) { currentMenu->menuitems[itemOn].routine(1); // right arrow S_StartSound(NULL,sfx_stnmov); } else { currentMenu->menuitems[itemOn].routine(itemOn); S_StartSound(NULL,sfx_pistol); } } return true; case KEY_ESCAPE: currentMenu->lastOn = itemOn; M_ClearMenus (); S_StartSound(NULL,sfx_swtchx); return true; case KEY_BACKSPACE: currentMenu->lastOn = itemOn; if (currentMenu->prevMenu) { currentMenu = currentMenu->prevMenu; itemOn = currentMenu->lastOn; S_StartSound(NULL,sfx_swtchn); } return true; default: for (i = itemOn+1;i < currentMenu->numitems;i++) if (currentMenu->menuitems[i].alphaKey == ch) { itemOn = i; S_StartSound(NULL,sfx_pstop); return true; } for (i = 0;i <= itemOn;i++) if (currentMenu->menuitems[i].alphaKey == ch) { itemOn = i; S_StartSound(NULL,sfx_pstop); return true; } break; }
return false; }
// // M_StartControlPanel // void M_StartControlPanel (void) { // intro might call this repeatedly if (menuactive) return;
menuactive = 1; currentMenu = &MainDef; // JDC itemOn = currentMenu->lastOn; // JDC }
// // M_Drawer // Called after the view has been rendered, // but before it has been blitted. // void M_Drawer (void) { static short x; static short y; short i; short max; char string[40]; int start;
inhelpscreens = false;
// Horiz. & Vertically center string and print it. if (messageToPrint) { start = 0; y = 100 - M_StringHeight(messageString)/2; while(*(messageString+start)) { for (i = 0;i < strlen(messageString+start);i++) if (*(messageString+start+i) == '\n') { memset(string,0,40); strncpy(string,messageString+start,i); start += i+1; break; } if (i == strlen(messageString+start)) { strcpy(string,messageString+start); start += i; } x = 160 - M_StringWidth(string)/2; M_WriteText(x,y,string); y += SHORT(hu_font[0]->height); } return; }
if (!menuactive) return;
if (currentMenu->routine) currentMenu->routine(); // call Draw routine
// DRAW MENU x = currentMenu->x; y = currentMenu->y; max = currentMenu->numitems;
for (i=0;i<max;i++) { if (currentMenu->menuitems[i].name[0]) V_DrawPatchDirect (x,y,0, W_CacheLumpName(currentMenu->menuitems[i].name ,PU_CACHE)); y += LINEHEIGHT; }
// DRAW SKULL V_DrawPatchDirect(x + SKULLXOFF,currentMenu->y - 5 + itemOn*LINEHEIGHT, 0, W_CacheLumpName(skullName[whichSkull],PU_CACHE));
}
// // M_ClearMenus // void M_ClearMenus (void) { menuactive = 0; // if (!netgame && usergame && paused) // sendpause = true; }
// // M_SetupNextMenu // void M_SetupNextMenu(menu_t *menudef) { currentMenu = menudef; itemOn = currentMenu->lastOn; }
// // M_Ticker // void M_Ticker (void) { if (--skullAnimCounter <= 0) { whichSkull ^= 1; skullAnimCounter = 8; } }
// // M_Init // void M_Init (void) { currentMenu = &MainDef; menuactive = 0; itemOn = currentMenu->lastOn; whichSkull = 0; skullAnimCounter = 10; screenSize = screenblocks - 3; messageToPrint = 0; messageString = NULL; messageLastMenuActive = menuactive; quickSaveSlot = -1;
// Here we could catch other version dependencies, // like HELP1/2, and four episodes.
switch ( gamemode ) { case commercial: // This is used because DOOM 2 had only one HELP // page. I use CREDIT as second page now, but // kept this hack for educational purposes. MainMenu[readthis] = MainMenu[quitdoom]; MainDef.numitems--; MainDef.y += 8; NewDef.prevMenu = &MainDef; ReadDef1.routine = M_DrawReadThis1; ReadDef1.x = 330; ReadDef1.y = 165; ReadMenu1[0].routine = M_FinishReadThis; break; case shareware: // Episode 2 and 3 are handled, // branching to an ad screen. case registered: // We need to remove the fourth episode. EpiDef.numitems--; break; case retail: // We are fine. default: break; }
}
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // Menu widget stuff, episode selection and such. // //-----------------------------------------------------------------------------
#ifndef __M_MENU__ #define __M_MENU__
#include "d_event.h"
// // MENUS // // Called by main loop, // saves config file and calls I_Quit when user exits. // Even when the menu is not displayed, // this can resize the view and change game parameters. // Does all the real work of the menu interaction. boolean M_Responder (event_t *ev);
// Called by main loop, // only used for menu (skull cursor) animation. void M_Ticker (void);
// Called by main loop, // draws the menus directly into the screen buffer. void M_Drawer (void);
// Called by D_DoomMain, // loads the config file. void M_Init (void);
// Called by intro code to force menu up upon a keypress, // does nothing if menu is already up. void M_StartControlPanel (void);
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // // $Log:$ // // DESCRIPTION: // Main loop menu stuff. // Default Config File. // PCX Screenshots. // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: m_misc.c,v 1.6 1997/02/03 22:45:10 b1 Exp $";
#include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> #include <stdlib.h> #include <unistd.h>
#include <ctype.h>
#include "doomdef.h"
#include "z_zone.h"
#include "m_swap.h" #include "m_argv.h"
#include "w_wad.h"
#include "i_system.h" #include "i_video.h" #include "v_video.h"
#include "hu_stuff.h"
// State. #include "doomstat.h"
// Data. #include "dstrings.h"
#include "m_misc.h"
// // M_DrawText // Returns the final X coordinate // HU_Init must have been called to init the font // extern patch_t* hu_font[HU_FONTSIZE];
int M_DrawText ( int x, int y, boolean direct, char* string ) { int c; int w;
while (*string) { c = toupper(*string) - HU_FONTSTART; string++; if (c < 0 || c> HU_FONTSIZE) { x += 4; continue; } w = SHORT (hu_font[c]->width); if (x+w > SCREENWIDTH) break; if (direct) V_DrawPatchDirect(x, y, 0, hu_font[c]); else V_DrawPatch(x, y, 0, hu_font[c]); x+=w; }
return x; }
// // M_WriteFile // #ifndef O_BINARY #define O_BINARY 0 #endif
boolean M_WriteFile ( char const* name, void* source, int length ) { int handle; int count; handle = open ( name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
if (handle == -1) return false;
count = write (handle, source, length); close (handle); if (count < length) return false; return true; }
// // M_ReadFile // int M_ReadFile ( char const* name, byte** buffer ) { int handle, count, length; struct stat fileinfo; byte *buf; handle = open (name, O_RDONLY | O_BINARY, 0666); if (handle == -1) I_Error ("Couldn't read file %s", name); if (fstat (handle,&fileinfo) == -1) I_Error ("Couldn't read file %s", name); length = fileinfo.st_size; buf = Z_Malloc (length, PU_STATIC, NULL); count = read (handle, buf, length); close (handle); if (count < length) I_Error ("Couldn't read file %s", name); *buffer = buf; return length; }
// // DEFAULTS // int usemouse; int usejoystick;
extern int key_right; extern int key_left; extern int key_up; extern int key_down;
extern int key_strafeleft; extern int key_straferight;
extern int key_fire; extern int key_use; extern int key_strafe; extern int key_speed;
extern int mousebfire; extern int mousebstrafe; extern int mousebforward;
extern int joybfire; extern int joybstrafe; extern int joybuse; extern int joybspeed;
extern int viewwidth; extern int viewheight;
extern int mouseSensitivity; extern int showMessages;
extern int detailLevel;
extern int screenblocks;
extern int showMessages;
// machine-independent sound params extern int numChannels;
// UNIX hack, to be removed. #ifdef SNDSERV extern char* sndserver_filename; extern int mb_used; #endif
#ifdef LINUX char* mousetype; char* mousedev; #endif
extern char* chat_macros[];
typedef struct { char* name; int* location; int defaultvalue; int scantranslate; // PC scan code hack int untranslated; // lousy hack } default_t;
default_t defaults[] = { {"mouse_sensitivity",&mouseSensitivity, 5}, {"sfx_volume",&snd_SfxVolume, 8}, {"music_volume",&snd_MusicVolume, 8}, {"show_messages",&showMessages, 1},
#ifdef NORMALUNIX {"key_right",&key_right, KEY_RIGHTARROW}, {"key_left",&key_left, KEY_LEFTARROW}, {"key_up",&key_up, KEY_UPARROW}, {"key_down",&key_down, KEY_DOWNARROW}, {"key_strafeleft",&key_strafeleft, ','}, {"key_straferight",&key_straferight, '.'},
{"key_fire",&key_fire, KEY_RCTRL}, {"key_use",&key_use, ' '}, {"key_strafe",&key_strafe, KEY_RALT}, {"key_speed",&key_speed, KEY_RSHIFT},
// UNIX hack, to be removed. #ifdef SNDSERV {"sndserver", (int *) &sndserver_filename, (int) "sndserver"}, {"mb_used", &mb_used, 2}, #endif
#endif
#ifdef LINUX {"mousedev", (int*)&mousedev, (int)"/dev/ttyS0"}, {"mousetype", (int*)&mousetype, (int)"microsoft"}, #endif
{"use_mouse",&usemouse, 1}, {"mouseb_fire",&mousebfire,0}, {"mouseb_strafe",&mousebstrafe,1}, {"mouseb_forward",&mousebforward,2},
{"use_joystick",&usejoystick, 0}, {"joyb_fire",&joybfire,0}, {"joyb_strafe",&joybstrafe,1}, {"joyb_use",&joybuse,3}, {"joyb_speed",&joybspeed,2},
{"screenblocks",&screenblocks, 9}, {"detaillevel",&detailLevel, 0},
{"snd_channels",&numChannels, 3},
{"usegamma",&usegamma, 0},
{"chatmacro0", (int *) &chat_macros[0], (int) HUSTR_CHATMACRO0 }, {"chatmacro1", (int *) &chat_macros[1], (int) HUSTR_CHATMACRO1 }, {"chatmacro2", (int *) &chat_macros[2], (int) HUSTR_CHATMACRO2 }, {"chatmacro3", (int *) &chat_macros[3], (int) HUSTR_CHATMACRO3 }, {"chatmacro4", (int *) &chat_macros[4], (int) HUSTR_CHATMACRO4 }, {"chatmacro5", (int *) &chat_macros[5], (int) HUSTR_CHATMACRO5 }, {"chatmacro6", (int *) &chat_macros[6], (int) HUSTR_CHATMACRO6 }, {"chatmacro7", (int *) &chat_macros[7], (int) HUSTR_CHATMACRO7 }, {"chatmacro8", (int *) &chat_macros[8], (int) HUSTR_CHATMACRO8 }, {"chatmacro9", (int *) &chat_macros[9], (int) HUSTR_CHATMACRO9 }
};
int numdefaults; char* defaultfile;
// // M_SaveDefaults // void M_SaveDefaults (void) { int i; int v; FILE* f; f = fopen (defaultfile, "w"); if (!f) return; // can't write the file, but don't complain for (i=0 ; i<numdefaults ; i++) { if (defaults[i].defaultvalue > -0xfff && defaults[i].defaultvalue < 0xfff) { v = *defaults[i].location; fprintf (f,"%s\t\t%i\n",defaults[i].name,v); } else { fprintf (f,"%s\t\t\"%s\"\n",defaults[i].name, * (char **) (defaults[i].location)); } } fclose (f); }
// // M_LoadDefaults // extern byte scantokey[128];
void M_LoadDefaults (void) { int i; int len; FILE* f; char def[80]; char strparm[100]; char* newstring; int parm; boolean isstring;
// set everything to base values numdefaults = sizeof(defaults)/sizeof(defaults[0]); for (i=0 ; i<numdefaults ; i++) *defaults[i].location = defaults[i].defaultvalue;
// check for a custom default file i = M_CheckParm ("-config"); if (i && i<myargc-1) { defaultfile = myargv[i+1]; printf (" default file: %s\n",defaultfile); } else defaultfile = basedefault;
// read the file in, overriding any set defaults f = fopen (defaultfile, "r"); if (f) { while (!feof(f)) { isstring = false; if (fscanf (f, "%79s %[^\n]\n", def, strparm) == 2) { if (strparm[0] == '"') { // get a string default isstring = true; len = strlen(strparm); newstring = (char *) malloc(len); strparm[len-1] = 0; strcpy(newstring, strparm+1); } else if (strparm[0] == '0' && strparm[1] == 'x') sscanf(strparm+2, "%x", &parm); else sscanf(strparm, "%i", &parm); for (i=0 ; i<numdefaults ; i++) if (!strcmp(def, defaults[i].name)) { if (!isstring) *defaults[i].location = parm; else *defaults[i].location = (int) newstring; break; } } } fclose (f); } }
// // SCREEN SHOTS //
typedef struct { char manufacturer; char version; char encoding; char bits_per_pixel;
unsigned short xmin; unsigned short ymin; unsigned short xmax; unsigned short ymax;
unsigned short hres; unsigned short vres;
unsigned char palette[48];
char reserved; char color_planes; unsigned short bytes_per_line; unsigned short palette_type;
char filler[58]; unsigned char data; // unbounded } pcx_t;
// // WritePCXfile // void WritePCXfile ( char* filename, byte* data, int width, int height, byte* palette ) { int i; int length; pcx_t* pcx; byte* pack; pcx = Z_Malloc (width*height*2+1000, PU_STATIC, NULL);
pcx->manufacturer = 0x0a; // PCX id pcx->version = 5; // 256 color pcx->encoding = 1; // uncompressed pcx->bits_per_pixel = 8; // 256 color pcx->xmin = 0; pcx->ymin = 0; pcx->xmax = SHORT(width-1); pcx->ymax = SHORT(height-1); pcx->hres = SHORT(width); pcx->vres = SHORT(height); memset (pcx->palette,0,sizeof(pcx->palette)); pcx->color_planes = 1; // chunky image pcx->bytes_per_line = SHORT(width); pcx->palette_type = SHORT(2); // not a grey scale memset (pcx->filler,0,sizeof(pcx->filler));
// pack the image pack = &pcx->data; for (i=0 ; i<width*height ; i++) { if ( (*data & 0xc0) != 0xc0) *pack++ = *data++; else { *pack++ = 0xc1; *pack++ = *data++; } }
// write the palette *pack++ = 0x0c; // palette ID byte for (i=0 ; i<768 ; i++) *pack++ = *palette++;
// write output file length = pack - (byte *)pcx; M_WriteFile (filename, pcx, length);
Z_Free (pcx); }
// // M_ScreenShot // void M_ScreenShot (void) { int i; byte* linear; char lbmname[12];
// munge planar buffer to linear linear = screens[2]; I_ReadScreen (linear);
// find a file name to save it to strcpy(lbmname,"DOOM00.pcx"); for (i=0 ; i<=99 ; i++) { lbmname[4] = i/10 + '0'; lbmname[5] = i%10 + '0'; if (access(lbmname,0) == -1) break; // file doesn't exist } if (i==100) I_Error ("M_ScreenShot: Couldn't create a PCX");
// save the pcx file WritePCXfile (lbmname, linear, SCREENWIDTH, SCREENHEIGHT, W_CacheLumpName ("PLAYPAL",PU_CACHE)); players[consoleplayer].message = "screen shot"; }
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // // //-----------------------------------------------------------------------------
#ifndef __M_MISC__ #define __M_MISC__
#include "doomtype.h" // // MISC //
boolean M_WriteFile ( char const* name, void* source, int length );
int M_ReadFile ( char const* name, byte** buffer );
void M_ScreenShot (void);
void M_LoadDefaults (void);
void M_SaveDefaults (void);
int M_DrawText ( int x, int y, boolean direct, char* string );
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // Random number LUT. // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: m_random.c,v 1.1 1997/02/03 22:45:11 b1 Exp $";
// // M_Random // Returns a 0-255 number // unsigned char rndtable[256] = { 0, 8, 109, 220, 222, 241, 149, 107, 75, 248, 254, 140, 16, 66 , 74, 21, 211, 47, 80, 242, 154, 27, 205, 128, 161, 89, 77, 36 , 95, 110, 85, 48, 212, 140, 211, 249, 22, 79, 200, 50, 28, 188 , 52, 140, 202, 120, 68, 145, 62, 70, 184, 190, 91, 197, 152, 224 , 149, 104, 25, 178, 252, 182, 202, 182, 141, 197, 4, 81, 181, 242 , 145, 42, 39, 227, 156, 198, 225, 193, 219, 93, 122, 175, 249, 0 , 175, 143, 70, 239, 46, 246, 163, 53, 163, 109, 168, 135, 2, 235 , 25, 92, 20, 145, 138, 77, 69, 166, 78, 176, 173, 212, 166, 113 , 94, 161, 41, 50, 239, 49, 111, 164, 70, 60, 2, 37, 171, 75 , 136, 156, 11, 56, 42, 146, 138, 229, 73, 146, 77, 61, 98, 196 , 135, 106, 63, 197, 195, 86, 96, 203, 113, 101, 170, 247, 181, 113 , 80, 250, 108, 7, 255, 237, 129, 226, 79, 107, 112, 166, 103, 241 , 24, 223, 239, 120, 198, 58, 60, 82, 128, 3, 184, 66, 143, 224 , 145, 224, 81, 206, 163, 45, 63, 90, 168, 114, 59, 33, 159, 95 , 28, 139, 123, 98, 125, 196, 15, 70, 194, 253, 54, 14, 109, 226 , 71, 17, 161, 93, 186, 87, 244, 138, 20, 52, 123, 251, 26, 36 , 17, 46, 52, 231, 232, 76, 31, 221, 84, 37, 216, 165, 212, 106 , 197, 242, 98, 43, 39, 175, 254, 145, 190, 84, 118, 222, 187, 136 , 120, 163, 236, 249 };
int rndindex = 0; int prndindex = 0;
// Which one is deterministic? int P_Random (void) { prndindex = (prndindex+1)&0xff; return rndtable[prndindex]; }
int M_Random (void) { rndindex = (rndindex+1)&0xff; return rndtable[rndindex]; }
void M_ClearRandom (void) { rndindex = prndindex = 0; }
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // // //-----------------------------------------------------------------------------
#ifndef __M_RANDOM__ #define __M_RANDOM__
#include "doomtype.h"
// Returns a number from 0 to 255, // from a lookup table. int M_Random (void);
// As M_Random, but used only by the play simulation. int P_Random (void);
// Fix randoms for demos. void M_ClearRandom (void);
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // Endianess handling, swapping 16bit and 32bit. // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: m_bbox.c,v 1.1 1997/02/03 22:45:10 b1 Exp $";
#ifdef __GNUG__ #pragma implementation "m_swap.h" #endif #include "m_swap.h"
// Not needed with big endian. #ifndef __BIG_ENDIAN__
// Swap 16bit, that is, MSB and LSB byte. unsigned short SwapSHORT(unsigned short x) { // No masking with 0xFF should be necessary. return (x>>8) | (x<<8); }
// Swapping 32bit. unsigned long SwapLONG( unsigned long x) { return (x>>24) | ((x>>8) & 0xff00) | ((x<<8) & 0xff0000) | (x<<24); }
#endif
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // Endianess handling, swapping 16bit and 32bit. // //-----------------------------------------------------------------------------
#ifndef __M_SWAP__ #define __M_SWAP__
#ifdef __GNUG__ #pragma interface #endif
// Endianess handling. // WAD files are stored little endian. #ifdef __BIG_ENDIAN__ short SwapSHORT(short); long SwapLONG(long); #define SHORT(x) ((short)SwapSHORT((unsigned short) (x))) #define LONG(x) ((long)SwapLONG((unsigned long) (x))) #else #define SHORT(x) (x) #define LONG(x) (x) #endif
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- ################################################################ # # $Id:$ # # $Log:$ # CC= gcc # gcc or g++
CFLAGS=-g -Wall -DNORMALUNIX -DLINUX # -DUSEASM LDFLAGS=-L/usr/X11R6/lib LIBS=-lXext -lX11 -lnsl -lm
# subdirectory for objects O=linux
# not too sophisticated dependency OBJS= \ $(O)/doomdef.o \ $(O)/doomstat.o \ $(O)/dstrings.o \ $(O)/i_system.o \ $(O)/i_sound.o \ $(O)/i_video.o \ $(O)/i_net.o \ $(O)/tables.o \ $(O)/f_finale.o \ $(O)/f_wipe.o \ $(O)/d_main.o \ $(O)/d_net.o \ $(O)/d_items.o \ $(O)/g_game.o \ $(O)/m_menu.o \ $(O)/m_misc.o \ $(O)/m_argv.o \ $(O)/m_bbox.o \ $(O)/m_fixed.o \ $(O)/m_swap.o \ $(O)/m_cheat.o \ $(O)/m_random.o \ $(O)/am_map.o \ $(O)/p_ceilng.o \ $(O)/p_doors.o \ $(O)/p_enemy.o \ $(O)/p_floor.o \ $(O)/p_inter.o \ $(O)/p_lights.o \ $(O)/p_map.o \ $(O)/p_maputl.o \ $(O)/p_plats.o \ $(O)/p_pspr.o \ $(O)/p_setup.o \ $(O)/p_sight.o \ $(O)/p_spec.o \ $(O)/p_switch.o \ $(O)/p_mobj.o \ $(O)/p_telept.o \ $(O)/p_tick.o \ $(O)/p_saveg.o \ $(O)/p_user.o \ $(O)/r_bsp.o \ $(O)/r_data.o \ $(O)/r_draw.o \ $(O)/r_main.o \ $(O)/r_plane.o \ $(O)/r_segs.o \ $(O)/r_sky.o \ $(O)/r_things.o \ $(O)/w_wad.o \ $(O)/wi_stuff.o \ $(O)/v_video.o \ $(O)/st_lib.o \ $(O)/st_stuff.o \ $(O)/hu_stuff.o \ $(O)/hu_lib.o \ $(O)/s_sound.o \ $(O)/z_zone.o \ $(O)/info.o \ $(O)/sounds.o
all: $(O)/linuxxdoom
clean: rm -f *.o *~ *.flc rm -f linux/*
$(O)/linuxxdoom: $(OBJS) $(O)/i_main.o $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(O)/i_main.o \ -o $(O)/linuxxdoom $(LIBS)
$(O)/%.o: %.c $(CC) $(CFLAGS) -c $< -o $@
############################################################# # ############################################################# // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: Ceiling aninmation (lowering, crushing, raising) // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: p_ceilng.c,v 1.4 1997/02/03 16:47:53 b1 Exp $";
#include "z_zone.h" #include "doomdef.h" #include "p_local.h"
#include "s_sound.h"
// State. #include "doomstat.h" #include "r_state.h"
// Data. #include "sounds.h"
// // CEILINGS //
ceiling_t* activeceilings[MAXCEILINGS];
// // T_MoveCeiling //
void T_MoveCeiling (ceiling_t* ceiling) { result_e res; switch(ceiling->direction) { case 0: // IN STASIS break; case 1: // UP res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->topheight, false,1,ceiling->direction); if (!(leveltime&7)) { switch(ceiling->type) { case silentCrushAndRaise: break; default: S_StartSound((mobj_t *)&ceiling->sector->soundorg, sfx_stnmov); // ? break; } } if (res == pastdest) { switch(ceiling->type) { case raiseToHighest: P_RemoveActiveCeiling(ceiling); break; case silentCrushAndRaise: S_StartSound((mobj_t *)&ceiling->sector->soundorg, sfx_pstop); case fastCrushAndRaise: case crushAndRaise: ceiling->direction = -1; break; default: break; } } break; �� case -1: // DOWN res = T_MovePlane(ceiling->sector, ceiling->speed, ceiling->bottomheight, ceiling->crush,1,ceiling->direction); if (!(leveltime&7)) { switch(ceiling->type) { case silentCrushAndRaise: break; default: S_StartSound((mobj_t *)&ceiling->sector->soundorg, sfx_stnmov); } } if (res == pastdest) { switch(ceiling->type) { case silentCrushAndRaise: S_StartSound((mobj_t *)&ceiling->sector->soundorg, sfx_pstop); case crushAndRaise: ceiling->speed = CEILSPEED; case fastCrushAndRaise: ceiling->direction = 1; break;
case lowerAndCrush: case lowerToFloor: P_RemoveActiveCeiling(ceiling); break;
default: break; } } else // ( res != pastdest ) { if (res == crushed) { switch(ceiling->type) { case silentCrushAndRaise: case crushAndRaise: case lowerAndCrush: ceiling->speed = CEILSPEED / 8; break;
default: break; } } } break; } }
// // EV_DoCeiling // Move a ceiling up/down and all around! // int EV_DoCeiling ( line_t* line, ceiling_e type ) { int secnum; int rtn; sector_t* sec; ceiling_t* ceiling; secnum = -1; rtn = 0;
// Reactivate in-stasis ceilings...for certain types. switch(type) { case fastCrushAndRaise: case silentCrushAndRaise: case crushAndRaise: P_ActivateInStasisCeiling(line); default: break; } while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { sec = §ors[secnum]; if (sec->specialdata) continue; // new door thinker rtn = 1; ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVSPEC, 0); P_AddThinker (&ceiling->thinker); sec->specialdata = ceiling; ceiling->thinker.function.acp1 = (actionf_p1)T_MoveCeiling; ceiling->sector = sec; ceiling->crush = false; switch(type) { case fastCrushAndRaise: ceiling->crush = true; ceiling->topheight = sec->ceilingheight; ceiling->bottomheight = sec->floorheight + (8*FRACUNIT); ceiling->direction = -1; ceiling->speed = CEILSPEED * 2; break;
case silentCrushAndRaise: case crushAndRaise: ceiling->crush = true; ceiling->topheight = sec->ceilingheight; case lowerAndCrush: case lowerToFloor: ceiling->bottomheight = sec->floorheight; if (type != lowerToFloor) ceiling->bottomheight += 8*FRACUNIT; ceiling->direction = -1; ceiling->speed = CEILSPEED; break;
case raiseToHighest: ceiling->topheight = P_FindHighestCeilingSurrounding(sec); ceiling->direction = 1; ceiling->speed = CEILSPEED; break; } ceiling->tag = sec->tag; ceiling->type = type; P_AddActiveCeiling(ceiling); } return rtn; }
// // Add an active ceiling // void P_AddActiveCeiling(ceiling_t* c) { int i;
for (i = 0; i < MAXCEILINGS;i++) { if (activeceilings[i] == NULL) { activeceilings[i] = c; return; } } }
// // Remove a ceiling's thinker // void P_RemoveActiveCeiling(ceiling_t* c) { int i; for (i = 0;i < MAXCEILINGS;i++) { if (activeceilings[i] == c) { activeceilings[i]->sector->specialdata = NULL; P_RemoveThinker (&activeceilings[i]->thinker); activeceilings[i] = NULL; break; } } }
// // Restart a ceiling that's in-stasis // void P_ActivateInStasisCeiling(line_t* line) { int i; for (i = 0;i < MAXCEILINGS;i++) { if (activeceilings[i] && (activeceilings[i]->tag == line->tag) && (activeceilings[i]->direction == 0)) { activeceilings[i]->direction = activeceilings[i]->olddirection; activeceilings[i]->thinker.function.acp1 = (actionf_p1)T_MoveCeiling; } } }
// // EV_CeilingCrushStop // Stop a ceiling from crushing! // int EV_CeilingCrushStop(line_t *line) { int i; int rtn; rtn = 0; for (i = 0;i < MAXCEILINGS;i++) { if (activeceilings[i] && (activeceilings[i]->tag == line->tag) && (activeceilings[i]->direction != 0)) { activeceilings[i]->olddirection = activeceilings[i]->direction; activeceilings[i]->thinker.function.acv = (actionf_v)NULL; activeceilings[i]->direction = 0; // in-stasis rtn = 1; } }
return rtn; } // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: Door animation code (opening/closing) // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: p_doors.c,v 1.4 1997/02/03 16:47:53 b1 Exp $";
#include "z_zone.h" #include "doomdef.h" #include "p_local.h"
#include "s_sound.h"
// State. #include "doomstat.h" #include "r_state.h"
// Data. #include "dstrings.h" #include "sounds.h"
#if 0 // // Sliding door frame information // slidename_t slideFrameNames[MAXSLIDEDOORS] = { {"GDOORF1","GDOORF2","GDOORF3","GDOORF4", // front "GDOORB1","GDOORB2","GDOORB3","GDOORB4"}, // back {"\0","\0","\0","\0"} }; #endif
// // VERTICAL DOORS //
// // T_VerticalDoor // void T_VerticalDoor (vldoor_t* door) { result_e res; switch(door->direction) { case 0: // WAITING if (!--door->topcountdown) { switch(door->type) { case blazeRaise: door->direction = -1; // time to go back down S_StartSound((mobj_t *)&door->sector->soundorg, sfx_bdcls); break; case normal: door->direction = -1; // time to go back down S_StartSound((mobj_t *)&door->sector->soundorg, sfx_dorcls); break; case close30ThenOpen: door->direction = 1; S_StartSound((mobj_t *)&door->sector->soundorg, sfx_doropn); break; default: break; } } break; case 2: // INITIAL WAIT if (!--door->topcountdown) { switch(door->type) { case raiseIn5Mins: door->direction = 1; door->type = normal; S_StartSound((mobj_t *)&door->sector->soundorg, sfx_doropn); break; default: break; } } break; case -1: // DOWN res = T_MovePlane(door->sector, door->speed, door->sector->floorheight, false,1,door->direction); if (res == pastdest) { switch(door->type) { case blazeRaise: case blazeClose: door->sector->specialdata = NULL; P_RemoveThinker (&door->thinker); // unlink and free S_StartSound((mobj_t *)&door->sector->soundorg, sfx_bdcls); break; case normal: case close: door->sector->specialdata = NULL; P_RemoveThinker (&door->thinker); // unlink and free break; case close30ThenOpen: door->direction = 0; door->topcountdown = 35*30; break; default: break; } } else if (res == crushed) { switch(door->type) { case blazeClose: case close: // DO NOT GO BACK UP! break; default: door->direction = 1; S_StartSound((mobj_t *)&door->sector->soundorg, sfx_doropn); break; } } break; case 1: // UP res = T_MovePlane(door->sector, door->speed, door->topheight, false,1,door->direction); if (res == pastdest) { switch(door->type) { case blazeRaise: case normal: door->direction = 0; // wait at top door->topcountdown = door->topwait; break; case close30ThenOpen: case blazeOpen: case open: door->sector->specialdata = NULL; P_RemoveThinker (&door->thinker); // unlink and free break; default: break; } } break; } }
// // EV_DoLockedDoor // Move a locked door up/down //
int EV_DoLockedDoor ( line_t* line, vldoor_e type, mobj_t* thing ) { player_t* p; p = thing->player; if (!p) return 0; switch(line->special) { case 99: // Blue Lock case 133: if ( !p ) return 0; if (!p->cards[it_bluecard] && !p->cards[it_blueskull]) { p->message = PD_BLUEO; S_StartSound(NULL,sfx_oof); return 0; } break; case 134: // Red Lock case 135: if ( !p ) return 0; if (!p->cards[it_redcard] && !p->cards[it_redskull]) { p->message = PD_REDO; S_StartSound(NULL,sfx_oof); return 0; } break; case 136: // Yellow Lock case 137: if ( !p ) return 0; if (!p->cards[it_yellowcard] && !p->cards[it_yellowskull]) { p->message = PD_YELLOWO; S_StartSound(NULL,sfx_oof); return 0; } break; }
return EV_DoDoor(line,type); }
int EV_DoDoor ( line_t* line, vldoor_e type ) { int secnum,rtn; sector_t* sec; vldoor_t* door; secnum = -1; rtn = 0;
while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { sec = §ors[secnum]; if (sec->specialdata) continue; // new door thinker rtn = 1; door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0); P_AddThinker (&door->thinker); sec->specialdata = door;
door->thinker.function.acp1 = (actionf_p1) T_VerticalDoor; door->sector = sec; door->type = type; door->topwait = VDOORWAIT; door->speed = VDOORSPEED; switch(type) { case blazeClose: door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; door->direction = -1; door->speed = VDOORSPEED * 4; S_StartSound((mobj_t *)&door->sector->soundorg, sfx_bdcls); break; case close: door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; door->direction = -1; S_StartSound((mobj_t *)&door->sector->soundorg, sfx_dorcls); break; case close30ThenOpen: door->topheight = sec->ceilingheight; door->direction = -1; S_StartSound((mobj_t *)&door->sector->soundorg, sfx_dorcls); break; case blazeRaise: case blazeOpen: door->direction = 1; door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; door->speed = VDOORSPEED * 4; if (door->topheight != sec->ceilingheight) S_StartSound((mobj_t *)&door->sector->soundorg, sfx_bdopn); break; case normal: case open: door->direction = 1; door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; if (door->topheight != sec->ceilingheight) S_StartSound((mobj_t *)&door->sector->soundorg, sfx_doropn); break; default: break; } } return rtn; }
// // EV_VerticalDoor : open a door manually, no tag value // void EV_VerticalDoor ( line_t* line, mobj_t* thing ) { player_t* player; int secnum; sector_t* sec; vldoor_t* door; int side; side = 0; // only front sides can be used
// Check for locks player = thing->player; switch(line->special) { case 26: // Blue Lock case 32: if ( !player ) return; if (!player->cards[it_bluecard] && !player->cards[it_blueskull]) { player->message = PD_BLUEK; S_StartSound(NULL,sfx_oof); return; } break; case 27: // Yellow Lock case 34: if ( !player ) return; if (!player->cards[it_yellowcard] && !player->cards[it_yellowskull]) { player->message = PD_YELLOWK; S_StartSound(NULL,sfx_oof); return; } break; case 28: // Red Lock case 33: if ( !player ) return; if (!player->cards[it_redcard] && !player->cards[it_redskull]) { player->message = PD_REDK; S_StartSound(NULL,sfx_oof); return; } break; } // if the sector has an active thinker, use it sec = sides[ line->sidenum[side^1]] .sector; secnum = sec-sectors;
if (sec->specialdata) { door = sec->specialdata; switch(line->special) { case 1: // ONLY FOR "RAISE" DOORS, NOT "OPEN"s case 26: case 27: case 28: case 117: if (door->direction == -1) door->direction = 1; // go back up else { if (!thing->player) return; // JDC: bad guys never close doors door->direction = -1; // start going down immediately } return; } } // for proper sound switch(line->special) { case 117: // BLAZING DOOR RAISE case 118: // BLAZING DOOR OPEN S_StartSound((mobj_t *)&sec->soundorg,sfx_bdopn); break; case 1: // NORMAL DOOR SOUND case 31: S_StartSound((mobj_t *)&sec->soundorg,sfx_doropn); break; default: // LOCKED DOOR SOUND S_StartSound((mobj_t *)&sec->soundorg,sfx_doropn); break; }
// new door thinker door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0); P_AddThinker (&door->thinker); sec->specialdata = door; door->thinker.function.acp1 = (actionf_p1) T_VerticalDoor; door->sector = sec; door->direction = 1; door->speed = VDOORSPEED; door->topwait = VDOORWAIT;
switch(line->special) { case 1: case 26: case 27: case 28: door->type = normal; break; case 31: case 32: case 33: case 34: door->type = open; line->special = 0; break; case 117: // blazing door raise door->type = blazeRaise; door->speed = VDOORSPEED*4; break; case 118: // blazing door open door->type = blazeOpen; line->special = 0; door->speed = VDOORSPEED*4; break; }
// find the top and bottom of the movement range door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; }
// // Spawn a door that closes after 30 seconds // void P_SpawnDoorCloseIn30 (sector_t* sec) { vldoor_t* door; door = Z_Malloc ( sizeof(*door), PU_LEVSPEC, 0);
P_AddThinker (&door->thinker);
sec->specialdata = door; sec->special = 0;
door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor; door->sector = sec; door->direction = 0; door->type = normal; door->speed = VDOORSPEED; door->topcountdown = 30 * 35; }
// // Spawn a door that opens after 5 minutes // void P_SpawnDoorRaiseIn5Mins ( sector_t* sec, int secnum ) { vldoor_t* door; door = Z_Malloc ( sizeof(*door), PU_LEVSPEC, 0);
P_AddThinker (&door->thinker);
sec->specialdata = door; sec->special = 0;
door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor; door->sector = sec; door->direction = 2; door->type = raiseIn5Mins; door->speed = VDOORSPEED; door->topheight = P_FindLowestCeilingSurrounding(sec); door->topheight -= 4*FRACUNIT; door->topwait = VDOORWAIT; door->topcountdown = 5 * 60 * 35; }
// UNUSED // Separate into p_slidoor.c?
#if 0 // ABANDONED TO THE MISTS OF TIME!!! // // EV_SlidingDoor : slide a door horizontally // (animate midtexture, then set noblocking line) //
slideframe_t slideFrames[MAXSLIDEDOORS];
void P_InitSlidingDoorFrames(void) { int i; int f1; int f2; int f3; int f4; // DOOM II ONLY... if ( gamemode != commercial) return; for (i = 0;i < MAXSLIDEDOORS; i++) { if (!slideFrameNames[i].frontFrame1[0]) break; f1 = R_TextureNumForName(slideFrameNames[i].frontFrame1); f2 = R_TextureNumForName(slideFrameNames[i].frontFrame2); f3 = R_TextureNumForName(slideFrameNames[i].frontFrame3); f4 = R_TextureNumForName(slideFrameNames[i].frontFrame4);
slideFrames[i].frontFrames[0] = f1; slideFrames[i].frontFrames[1] = f2; slideFrames[i].frontFrames[2] = f3; slideFrames[i].frontFrames[3] = f4; f1 = R_TextureNumForName(slideFrameNames[i].backFrame1); f2 = R_TextureNumForName(slideFrameNames[i].backFrame2); f3 = R_TextureNumForName(slideFrameNames[i].backFrame3); f4 = R_TextureNumForName(slideFrameNames[i].backFrame4);
slideFrames[i].backFrames[0] = f1; slideFrames[i].backFrames[1] = f2; slideFrames[i].backFrames[2] = f3; slideFrames[i].backFrames[3] = f4; } }
// // Return index into "slideFrames" array // for which door type to use // int P_FindSlidingDoorType(line_t* line) { int i; int val; for (i = 0;i < MAXSLIDEDOORS;i++) { val = sides[line->sidenum[0]].midtexture; if (val == slideFrames[i].frontFrames[0]) return i; } return -1; }
void T_SlidingDoor (slidedoor_t* door) { switch(door->status) { case sd_opening: if (!door->timer--) { if (++door->frame == SNUMFRAMES) { // IF DOOR IS DONE OPENING... sides[door->line->sidenum[0]].midtexture = 0; sides[door->line->sidenum[1]].midtexture = 0; door->line->flags &= ML_BLOCKING^0xff; if (door->type == sdt_openOnly) { door->frontsector->specialdata = NULL; P_RemoveThinker (&door->thinker); break; } door->timer = SDOORWAIT; door->status = sd_waiting; } else { // IF DOOR NEEDS TO ANIMATE TO NEXT FRAME... door->timer = SWAITTICS; sides[door->line->sidenum[0]].midtexture = slideFrames[door->whichDoorIndex]. frontFrames[door->frame]; sides[door->line->sidenum[1]].midtexture = slideFrames[door->whichDoorIndex]. backFrames[door->frame]; } } break; case sd_waiting: // IF DOOR IS DONE WAITING... if (!door->timer--) { // CAN DOOR CLOSE? if (door->frontsector->thinglist != NULL || door->backsector->thinglist != NULL) { door->timer = SDOORWAIT; break; }
//door->frame = SNUMFRAMES-1; door->status = sd_closing; door->timer = SWAITTICS; } break; case sd_closing: if (!door->timer--) { if (--door->frame < 0) { // IF DOOR IS DONE CLOSING... door->line->flags |= ML_BLOCKING; door->frontsector->specialdata = NULL; P_RemoveThinker (&door->thinker); break; } else { // IF DOOR NEEDS TO ANIMATE TO NEXT FRAME... door->timer = SWAITTICS; sides[door->line->sidenum[0]].midtexture = slideFrames[door->whichDoorIndex]. frontFrames[door->frame]; sides[door->line->sidenum[1]].midtexture = slideFrames[door->whichDoorIndex]. backFrames[door->frame]; } } break; } }
void EV_SlidingDoor ( line_t* line, mobj_t* thing ) { sector_t* sec; slidedoor_t* door; // DOOM II ONLY... if (gamemode != commercial) return;
// Make sure door isn't already being animated sec = line->frontsector; door = NULL; if (sec->specialdata) { if (!thing->player) return; door = sec->specialdata; if (door->type == sdt_openAndClose) { if (door->status == sd_waiting) door->status = sd_closing; } else return; }
// Init sliding door vars if (!door) { door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0); P_AddThinker (&door->thinker); sec->specialdata = door; door->type = sdt_openAndClose; door->status = sd_opening; door->whichDoorIndex = P_FindSlidingDoorType(line);
if (door->whichDoorIndex < 0) I_Error("EV_SlidingDoor: Can't use texture for sliding door!"); door->frontsector = sec; door->backsector = line->backsector; door->thinker.function = T_SlidingDoor; door->timer = SWAITTICS; door->frame = 0; door->line = line; } } #endif // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // Enemy thinking, AI. // Action Pointer Functions // that are associated with states/frames. // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: p_enemy.c,v 1.5 1997/02/03 22:45:11 b1 Exp $";
#include <stdlib.h>
#include "m_random.h" #include "i_system.h"
#include "doomdef.h" #include "p_local.h"
#include "s_sound.h"
#include "g_game.h"
// State. #include "doomstat.h" #include "r_state.h"
// Data. #include "sounds.h"
typedef enum { DI_EAST, DI_NORTHEAST, DI_NORTH, DI_NORTHWEST, DI_WEST, DI_SOUTHWEST, DI_SOUTH, DI_SOUTHEAST, DI_NODIR, NUMDIRS
} dirtype_t;
// // P_NewChaseDir related LUT. // dirtype_t opposite[] = { DI_WEST, DI_SOUTHWEST, DI_SOUTH, DI_SOUTHEAST, DI_EAST, DI_NORTHEAST, DI_NORTH, DI_NORTHWEST, DI_NODIR };
dirtype_t diags[] = { DI_NORTHWEST, DI_NORTHEAST, DI_SOUTHWEST, DI_SOUTHEAST };
void A_Fall (mobj_t *actor);
// // ENEMY THINKING // Enemies are allways spawned // with targetplayer = -1, threshold = 0 // Most monsters are spawned unaware of all players, // but some can be made preaware //
// // Called by P_NoiseAlert. // Recursively traverse adjacent sectors, // sound blocking lines cut off traversal. //
mobj_t* soundtarget;
void P_RecursiveSound ( sector_t* sec, int soundblocks ) { int i; line_t* check; sector_t* other; // wake up all monsters in this sector if (sec->validcount == validcount && sec->soundtraversed <= soundblocks+1) { return; // already flooded }
sec->validcount = validcount; sec->soundtraversed = soundblocks+1; sec->soundtarget = soundtarget; for (i=0 ;i<sec->linecount ; i++) { check = sec->lines[i]; if (! (check->flags & ML_TWOSIDED) ) continue; P_LineOpening (check);
if (openrange <= 0) continue; // closed door if ( sides[ check->sidenum[0] ].sector == sec) other = sides[ check->sidenum[1] ] .sector; else other = sides[ check->sidenum[0] ].sector; if (check->flags & ML_SOUNDBLOCK) { if (!soundblocks) P_RecursiveSound (other, 1); } else P_RecursiveSound (other, soundblocks); } }
// // P_NoiseAlert // If a monster yells at a player, // it will alert other monsters to the player. // void P_NoiseAlert ( mobj_t* target, mobj_t* emmiter ) { soundtarget = target; validcount++; P_RecursiveSound (emmiter->subsector->sector, 0); }
// // P_CheckMeleeRange // boolean P_CheckMeleeRange (mobj_t* actor) { mobj_t* pl; fixed_t dist; if (!actor->target) return false; pl = actor->target; dist = P_AproxDistance (pl->x-actor->x, pl->y-actor->y);
if (dist >= MELEERANGE-20*FRACUNIT+pl->info->radius) return false; if (! P_CheckSight (actor, actor->target) ) return false; return true; }
// // P_CheckMissileRange // boolean P_CheckMissileRange (mobj_t* actor) { fixed_t dist; if (! P_CheckSight (actor, actor->target) ) return false; if ( actor->flags & MF_JUSTHIT ) { // the target just hit the enemy, // so fight back! actor->flags &= ~MF_JUSTHIT; return true; } if (actor->reactiontime) return false; // do not attack yet // OPTIMIZE: get this from a global checksight dist = P_AproxDistance ( actor->x-actor->target->x, actor->y-actor->target->y) - 64*FRACUNIT;
if (!actor->info->meleestate) dist -= 128*FRACUNIT; // no melee attack, so fire more
dist >>= 16;
if (actor->type == MT_VILE) { if (dist > 14*64) return false; // too far away }
if (actor->type == MT_UNDEAD) { if (dist < 196) return false; // close for fist attack dist >>= 1; }
if (actor->type == MT_CYBORG || actor->type == MT_SPIDER || actor->type == MT_SKULL) { dist >>= 1; }
if (dist > 200) dist = 200; if (actor->type == MT_CYBORG && dist > 160) dist = 160; if (P_Random () < dist) return false; return true; }
// // P_Move // Move in the current direction, // returns false if the move is blocked. // fixed_t xspeed[8] = {FRACUNIT,47000,0,-47000,-FRACUNIT,-47000,0,47000}; fixed_t yspeed[8] = {0,47000,FRACUNIT,47000,0,-47000,-FRACUNIT,-47000};
#define MAXSPECIALCROSS 8
extern line_t* spechit[MAXSPECIALCROSS]; extern int numspechit;
boolean P_Move (mobj_t* actor) { fixed_t tryx; fixed_t tryy;
line_t* ld;
// warning: 'catch', 'throw', and 'try' // are all C++ reserved words boolean try_ok; boolean good; if (actor->movedir == DI_NODIR) return false; if ((unsigned)actor->movedir >= 8) I_Error ("Weird actor->movedir!"); tryx = actor->x + actor->info->speed*xspeed[actor->movedir]; tryy = actor->y + actor->info->speed*yspeed[actor->movedir];
try_ok = P_TryMove (actor, tryx, tryy);
if (!try_ok) { // open any specials if (actor->flags & MF_FLOAT && floatok) { // must adjust height if (actor->z < tmfloorz) actor->z += FLOATSPEED; else actor->z -= FLOATSPEED;
actor->flags |= MF_INFLOAT; return true; } if (!numspechit) return false; actor->movedir = DI_NODIR; good = false; while (numspechit--) { ld = spechit[numspechit]; // if the special is not a door // that can be opened, // return false if (P_UseSpecialLine (actor, ld,0)) good = true; } return good; } else { actor->flags &= ~MF_INFLOAT; } if (! (actor->flags & MF_FLOAT) ) actor->z = actor->floorz; return true; }
// // TryWalk // Attempts to move actor on // in its current (ob->moveangle) direction. // If blocked by either a wall or an actor // returns FALSE // If move is either clear or blocked only by a door, // returns TRUE and sets... // If a door is in the way, // an OpenDoor call is made to start it opening. // boolean P_TryWalk (mobj_t* actor) { if (!P_Move (actor)) { return false; }
actor->movecount = P_Random()&15; return true; }
void P_NewChaseDir (mobj_t* actor) { fixed_t deltax; fixed_t deltay;
dirtype_t d[3];
int tdir; dirtype_t olddir;
dirtype_t turnaround;
if (!actor->target) I_Error ("P_NewChaseDir: called with no target"); olddir = actor->movedir; turnaround=opposite[olddir];
deltax = actor->target->x - actor->x; deltay = actor->target->y - actor->y;
if (deltax>10*FRACUNIT) d[1]= DI_EAST; else if (deltax<-10*FRACUNIT) d[1]= DI_WEST; else d[1]=DI_NODIR;
if (deltay<-10*FRACUNIT) d[2]= DI_SOUTH; else if (deltay>10*FRACUNIT) d[2]= DI_NORTH; else d[2]=DI_NODIR;
// try direct route if (d[1] != DI_NODIR && d[2] != DI_NODIR) { actor->movedir = diags[((deltay<0)<<1)+(deltax>0)]; if (actor->movedir != turnaround && P_TryWalk(actor)) return; }
// try other directions if (P_Random() > 200 || abs(deltay)>abs(deltax)) { tdir=d[1]; d[1]=d[2]; d[2]=tdir; }
if (d[1]==turnaround) d[1]=DI_NODIR; if (d[2]==turnaround) d[2]=DI_NODIR; if (d[1]!=DI_NODIR) { actor->movedir = d[1]; if (P_TryWalk(actor)) { // either moved forward or attacked return; } }
if (d[2]!=DI_NODIR) { actor->movedir =d[2];
if (P_TryWalk(actor)) return; }
// there is no direct path to the player, // so pick another direction. if (olddir!=DI_NODIR) { actor->movedir =olddir;
if (P_TryWalk(actor)) return; }
// randomly determine direction of search if (P_Random()&1) { for ( tdir=DI_EAST; tdir<=DI_SOUTHEAST; tdir++ ) { if (tdir!=turnaround) { actor->movedir =tdir; if ( P_TryWalk(actor) ) return; } } } else { for ( tdir=DI_SOUTHEAST; tdir != (DI_EAST-1); tdir-- ) { if (tdir!=turnaround) { actor->movedir =tdir; if ( P_TryWalk(actor) ) return; } } }
if (turnaround != DI_NODIR) { actor->movedir =turnaround; if ( P_TryWalk(actor) ) return; }
actor->movedir = DI_NODIR; // can not move }
// // P_LookForPlayers // If allaround is false, only look 180 degrees in front. // Returns true if a player is targeted. // boolean P_LookForPlayers ( mobj_t* actor, boolean allaround ) { int c; int stop; player_t* player; sector_t* sector; angle_t an; fixed_t dist; sector = actor->subsector->sector; c = 0; stop = (actor->lastlook-1)&3; for ( ; ; actor->lastlook = (actor->lastlook+1)&3 ) { if (!playeringame[actor->lastlook]) continue; if (c++ == 2 || actor->lastlook == stop) { // done looking return false; } player = &players[actor->lastlook];
if (player->health <= 0) continue; // dead
if (!P_CheckSight (actor, player->mo)) continue; // out of sight if (!allaround) { an = R_PointToAngle2 (actor->x, actor->y, player->mo->x, player->mo->y) - actor->angle; if (an > ANG90 && an < ANG270) { dist = P_AproxDistance (player->mo->x - actor->x, player->mo->y - actor->y); // if real close, react anyway if (dist > MELEERANGE) continue; // behind back } } actor->target = player->mo; return true; }
return false; }
// // A_KeenDie // DOOM II special, map 32. // Uses special tag 666. // void A_KeenDie (mobj_t* mo) { thinker_t* th; mobj_t* mo2; line_t junk;
A_Fall (mo);
// scan the remaining thinkers // to see if all Keens are dead for (th = thinkercap.next ; th != &thinkercap ; th=th->next) { if (th->function.acp1 != (actionf_p1)P_MobjThinker) continue;
mo2 = (mobj_t *)th; if (mo2 != mo && mo2->type == mo->type && mo2->health > 0) { // other Keen not dead return; } }
junk.tag = 666; EV_DoDoor(&junk,open); }
// // ACTION ROUTINES //
// // A_Look // Stay in state until a player is sighted. // void A_Look (mobj_t* actor) { mobj_t* targ; actor->threshold = 0; // any shot will wake up targ = actor->subsector->sector->soundtarget;
if (targ && (targ->flags & MF_SHOOTABLE) ) { actor->target = targ;
if ( actor->flags & MF_AMBUSH ) { if (P_CheckSight (actor, actor->target)) goto seeyou; } else goto seeyou; } if (!P_LookForPlayers (actor, false) ) return; // go into chase state seeyou: if (actor->info->seesound) { int sound; switch (actor->info->seesound) { case sfx_posit1: case sfx_posit2: case sfx_posit3: sound = sfx_posit1+P_Random()%3; break;
case sfx_bgsit1: case sfx_bgsit2: sound = sfx_bgsit1+P_Random()%2; break;
default: sound = actor->info->seesound; break; }
if (actor->type==MT_SPIDER || actor->type == MT_CYBORG) { // full volume S_StartSound (NULL, sound); } else S_StartSound (actor, sound); }
P_SetMobjState (actor, actor->info->seestate); }
// // A_Chase // Actor has a melee attack, // so it tries to close as fast as possible // void A_Chase (mobj_t* actor) { int delta;
if (actor->reactiontime) actor->reactiontime--;
// modify target threshold if (actor->threshold) { if (!actor->target || actor->target->health <= 0) { actor->threshold = 0; } else actor->threshold--; }
// turn towards movement direction if not there yet if (actor->movedir < 8) { actor->angle &= (7<<29); delta = actor->angle - (actor->movedir << 29); if (delta > 0) actor->angle -= ANG90/2; else if (delta < 0) actor->angle += ANG90/2; }
if (!actor->target || !(actor->target->flags&MF_SHOOTABLE)) { // look for a new target if (P_LookForPlayers(actor,true)) return; // got a new target P_SetMobjState (actor, actor->info->spawnstate); return; }
// do not attack twice in a row if (actor->flags & MF_JUSTATTACKED) { actor->flags &= ~MF_JUSTATTACKED; if (gameskill != sk_nightmare && !fastparm) P_NewChaseDir (actor); return; }
// check for melee attack if (actor->info->meleestate && P_CheckMeleeRange (actor)) { if (actor->info->attacksound) S_StartSound (actor, actor->info->attacksound);
P_SetMobjState (actor, actor->info->meleestate); return; }
// check for missile attack if (actor->info->missilestate) { if (gameskill < sk_nightmare && !fastparm && actor->movecount) { goto nomissile; } if (!P_CheckMissileRange (actor)) goto nomissile; P_SetMobjState (actor, actor->info->missilestate); actor->flags |= MF_JUSTATTACKED; return; }
// ? nomissile: // possibly choose another target if (netgame && !actor->threshold && !P_CheckSight (actor, actor->target) ) { if (P_LookForPlayers(actor,true)) return; // got a new target }
// chase towards player if (--actor->movecount<0 || !P_Move (actor)) { P_NewChaseDir (actor); }
// make active sound if (actor->info->activesound && P_Random () < 3) { S_StartSound (actor, actor->info->activesound); } }
// // A_FaceTarget // void A_FaceTarget (mobj_t* actor) { if (!actor->target) return;
actor->flags &= ~MF_AMBUSH; actor->angle = R_PointToAngle2 (actor->x, actor->y, actor->target->x, actor->target->y);
if (actor->target->flags & MF_SHADOW) actor->angle += (P_Random()-P_Random())<<21; }
// // A_PosAttack // void A_PosAttack (mobj_t* actor) { int angle; int damage; int slope; if (!actor->target) return; A_FaceTarget (actor); angle = actor->angle; slope = P_AimLineAttack (actor, angle, MISSILERANGE);
S_StartSound (actor, sfx_pistol); angle += (P_Random()-P_Random())<<20; damage = ((P_Random()%5)+1)*3; P_LineAttack (actor, angle, MISSILERANGE, slope, damage); }
void A_SPosAttack (mobj_t* actor) { int i; int angle; int bangle; int damage; int slope; if (!actor->target) return;
S_StartSound (actor, sfx_shotgn); A_FaceTarget (actor); bangle = actor->angle; slope = P_AimLineAttack (actor, bangle, MISSILERANGE);
for (i=0 ; i<3 ; i++) { angle = bangle + ((P_Random()-P_Random())<<20); damage = ((P_Random()%5)+1)*3; P_LineAttack (actor, angle, MISSILERANGE, slope, damage); } }
void A_CPosAttack (mobj_t* actor) { int angle; int bangle; int damage; int slope; if (!actor->target) return;
S_StartSound (actor, sfx_shotgn); A_FaceTarget (actor); bangle = actor->angle; slope = P_AimLineAttack (actor, bangle, MISSILERANGE);
angle = bangle + ((P_Random()-P_Random())<<20); damage = ((P_Random()%5)+1)*3; P_LineAttack (actor, angle, MISSILERANGE, slope, damage); }
void A_CPosRefire (mobj_t* actor) { // keep firing unless target got out of sight A_FaceTarget (actor);
if (P_Random () < 40) return;
if (!actor->target || actor->target->health <= 0 || !P_CheckSight (actor, actor->target) ) { P_SetMobjState (actor, actor->info->seestate); } }
void A_SpidRefire (mobj_t* actor) { // keep firing unless target got out of sight A_FaceTarget (actor);
if (P_Random () < 10) return;
if (!actor->target || actor->target->health <= 0 || !P_CheckSight (actor, actor->target) ) { P_SetMobjState (actor, actor->info->seestate); } }
void A_BspiAttack (mobj_t *actor) { if (!actor->target) return; A_FaceTarget (actor);
// launch a missile P_SpawnMissile (actor, actor->target, MT_ARACHPLAZ); }
// // A_TroopAttack // void A_TroopAttack (mobj_t* actor) { int damage; if (!actor->target) return; A_FaceTarget (actor); if (P_CheckMeleeRange (actor)) { S_StartSound (actor, sfx_claw); damage = (P_Random()%8+1)*3; P_DamageMobj (actor->target, actor, actor, damage); return; }
// launch a missile P_SpawnMissile (actor, actor->target, MT_TROOPSHOT); }
void A_SargAttack (mobj_t* actor) { int damage;
if (!actor->target) return; A_FaceTarget (actor); if (P_CheckMeleeRange (actor)) { damage = ((P_Random()%10)+1)*4; P_DamageMobj (actor->target, actor, actor, damage); } }
void A_HeadAttack (mobj_t* actor) { int damage; if (!actor->target) return; A_FaceTarget (actor); if (P_CheckMeleeRange (actor)) { damage = (P_Random()%6+1)*10; P_DamageMobj (actor->target, actor, actor, damage); return; }
// launch a missile P_SpawnMissile (actor, actor->target, MT_HEADSHOT); }
void A_CyberAttack (mobj_t* actor) { if (!actor->target) return; A_FaceTarget (actor); P_SpawnMissile (actor, actor->target, MT_ROCKET); }
void A_BruisAttack (mobj_t* actor) { int damage; if (!actor->target) return; if (P_CheckMeleeRange (actor)) { S_StartSound (actor, sfx_claw); damage = (P_Random()%8+1)*10; P_DamageMobj (actor->target, actor, actor, damage); return; }
// launch a missile P_SpawnMissile (actor, actor->target, MT_BRUISERSHOT); }
// // A_SkelMissile // void A_SkelMissile (mobj_t* actor) { mobj_t* mo; if (!actor->target) return; A_FaceTarget (actor); actor->z += 16*FRACUNIT; // so missile spawns higher mo = P_SpawnMissile (actor, actor->target, MT_TRACER); actor->z -= 16*FRACUNIT; // back to normal
mo->x += mo->momx; mo->y += mo->momy; mo->tracer = actor->target; }
int TRACEANGLE = 0xc000000;
void A_Tracer (mobj_t* actor) { angle_t exact; fixed_t dist; fixed_t slope; mobj_t* dest; mobj_t* th; if (gametic & 3) return;
// spawn a puff of smoke behind the rocket P_SpawnPuff (actor->x, actor->y, actor->z); th = P_SpawnMobj (actor->x-actor->momx, actor->y-actor->momy, actor->z, MT_SMOKE);
th->momz = FRACUNIT; th->tics -= P_Random()&3; if (th->tics < 1) th->tics = 1;
// adjust direction dest = actor->tracer; if (!dest || dest->health <= 0) return;
// change angle exact = R_PointToAngle2 (actor->x, actor->y, dest->x, dest->y);
if (exact != actor->angle) { if (exact - actor->angle > 0x80000000) { actor->angle -= TRACEANGLE; if (exact - actor->angle < 0x80000000) actor->angle = exact; } else { actor->angle += TRACEANGLE; if (exact - actor->angle > 0x80000000) actor->angle = exact; } } exact = actor->angle>>ANGLETOFINESHIFT; actor->momx = FixedMul (actor->info->speed, finecosine[exact]); actor->momy = FixedMul (actor->info->speed, finesine[exact]);
// change slope dist = P_AproxDistance (dest->x - actor->x, dest->y - actor->y);
dist = dist / actor->info->speed;
if (dist < 1) dist = 1; slope = (dest->z+40*FRACUNIT - actor->z) / dist;
if (slope < actor->momz) actor->momz -= FRACUNIT/8; else actor->momz += FRACUNIT/8; }
void A_SkelWhoosh (mobj_t* actor) { if (!actor->target) return; A_FaceTarget (actor); S_StartSound (actor,sfx_skeswg); }
void A_SkelFist (mobj_t* actor) { int damage;
if (!actor->target) return; A_FaceTarget (actor); if (P_CheckMeleeRange (actor)) { damage = ((P_Random()%10)+1)*6; S_StartSound (actor, sfx_skepch); P_DamageMobj (actor->target, actor, actor, damage); } }
// // PIT_VileCheck // Detect a corpse that could be raised. // mobj_t* corpsehit; mobj_t* vileobj; fixed_t viletryx; fixed_t viletryy;
boolean PIT_VileCheck (mobj_t* thing) { int maxdist; boolean check; if (!(thing->flags & MF_CORPSE) ) return true; // not a monster
if (thing->tics != -1) return true; // not lying still yet
if (thing->info->raisestate == S_NULL) return true; // monster doesn't have a raise state
maxdist = thing->info->radius + mobjinfo[MT_VILE].radius; if ( abs(thing->x - viletryx) > maxdist || abs(thing->y - viletryy) > maxdist ) return true; // not actually touching corpsehit = thing; corpsehit->momx = corpsehit->momy = 0; corpsehit->height <<= 2; check = P_CheckPosition (corpsehit, corpsehit->x, corpsehit->y); corpsehit->height >>= 2;
if (!check) return true; // doesn't fit here return false; // got one, so stop checking }
// // A_VileChase // Check for ressurecting a body // void A_VileChase (mobj_t* actor) { int xl; int xh; int yl; int yh;
int bx; int by;
mobjinfo_t* info; mobj_t* temp; if (actor->movedir != DI_NODIR) { // check for corpses to raise viletryx = actor->x + actor->info->speed*xspeed[actor->movedir]; viletryy = actor->y + actor->info->speed*yspeed[actor->movedir];
xl = (viletryx - bmaporgx - MAXRADIUS*2)>>MAPBLOCKSHIFT; xh = (viletryx - bmaporgx + MAXRADIUS*2)>>MAPBLOCKSHIFT; yl = (viletryy - bmaporgy - MAXRADIUS*2)>>MAPBLOCKSHIFT; yh = (viletryy - bmaporgy + MAXRADIUS*2)>>MAPBLOCKSHIFT; vileobj = actor; for (bx=xl ; bx<=xh ; bx++) { for (by=yl ; by<=yh ; by++) { // Call PIT_VileCheck to check // whether object is a corpse // that canbe raised. if (!P_BlockThingsIterator(bx,by,PIT_VileCheck)) { // got one! temp = actor->target; actor->target = corpsehit; A_FaceTarget (actor); actor->target = temp; P_SetMobjState (actor, S_VILE_HEAL1); S_StartSound (corpsehit, sfx_slop); info = corpsehit->info; P_SetMobjState (corpsehit,info->raisestate); corpsehit->height <<= 2; corpsehit->flags = info->flags; corpsehit->health = info->spawnhealth; corpsehit->target = NULL;
return; } } } }
// Return to normal attack. A_Chase (actor); }
// // A_VileStart // void A_VileStart (mobj_t* actor) { S_StartSound (actor, sfx_vilatk); }
// // A_Fire // Keep fire in front of player unless out of sight // void A_Fire (mobj_t* actor);
void A_StartFire (mobj_t* actor) { S_StartSound(actor,sfx_flamst); A_Fire(actor); }
void A_FireCrackle (mobj_t* actor) { S_StartSound(actor,sfx_flame); A_Fire(actor); }
void A_Fire (mobj_t* actor) { mobj_t* dest; unsigned an; dest = actor->tracer; if (!dest) return; // don't move it if the vile lost sight if (!P_CheckSight (actor->target, dest) ) return;
an = dest->angle >> ANGLETOFINESHIFT;
P_UnsetThingPosition (actor); actor->x = dest->x + FixedMul (24*FRACUNIT, finecosine[an]); actor->y = dest->y + FixedMul (24*FRACUNIT, finesine[an]); actor->z = dest->z; P_SetThingPosition (actor); }
// // A_VileTarget // Spawn the hellfire // void A_VileTarget (mobj_t* actor) { mobj_t* fog; if (!actor->target) return;
A_FaceTarget (actor);
fog = P_SpawnMobj (actor->target->x, actor->target->x, actor->target->z, MT_FIRE);
actor->tracer = fog; fog->target = actor; fog->tracer = actor->target; A_Fire (fog); }
// // A_VileAttack // void A_VileAttack (mobj_t* actor) { mobj_t* fire; int an; if (!actor->target) return;
A_FaceTarget (actor);
if (!P_CheckSight (actor, actor->target) ) return;
S_StartSound (actor, sfx_barexp); P_DamageMobj (actor->target, actor, actor, 20); actor->target->momz = 1000*FRACUNIT/actor->target->info->mass; an = actor->angle >> ANGLETOFINESHIFT;
fire = actor->tracer;
if (!fire) return; // move the fire between the vile and the player fire->x = actor->target->x - FixedMul (24*FRACUNIT, finecosine[an]); fire->y = actor->target->y - FixedMul (24*FRACUNIT, finesine[an]); P_RadiusAttack (fire, actor, 70 ); }
// // Mancubus attack, // firing three missiles (bruisers) // in three different directions? // Doesn't look like it. // #define FATSPREAD (ANG90/8)
void A_FatRaise (mobj_t *actor) { A_FaceTarget (actor); S_StartSound (actor, sfx_manatk); }
void A_FatAttack1 (mobj_t* actor) { mobj_t* mo; int an; A_FaceTarget (actor); // Change direction to ... actor->angle += FATSPREAD; P_SpawnMissile (actor, actor->target, MT_FATSHOT);
mo = P_SpawnMissile (actor, actor->target, MT_FATSHOT); mo->angle += FATSPREAD; an = mo->angle >> ANGLETOFINESHIFT; mo->momx = FixedMul (mo->info->speed, finecosine[an]); mo->momy = FixedMul (mo->info->speed, finesine[an]); }
void A_FatAttack2 (mobj_t* actor) { mobj_t* mo; int an;
A_FaceTarget (actor); // Now here choose opposite deviation. actor->angle -= FATSPREAD; P_SpawnMissile (actor, actor->target, MT_FATSHOT);
mo = P_SpawnMissile (actor, actor->target, MT_FATSHOT); mo->angle -= FATSPREAD*2; an = mo->angle >> ANGLETOFINESHIFT; mo->momx = FixedMul (mo->info->speed, finecosine[an]); mo->momy = FixedMul (mo->info->speed, finesine[an]); }
void A_FatAttack3 (mobj_t* actor) { mobj_t* mo; int an;
A_FaceTarget (actor);
mo = P_SpawnMissile (actor, actor->target, MT_FATSHOT); mo->angle -= FATSPREAD/2; an = mo->angle >> ANGLETOFINESHIFT; mo->momx = FixedMul (mo->info->speed, finecosine[an]); mo->momy = FixedMul (mo->info->speed, finesine[an]);
mo = P_SpawnMissile (actor, actor->target, MT_FATSHOT); mo->angle += FATSPREAD/2; an = mo->angle >> ANGLETOFINESHIFT; mo->momx = FixedMul (mo->info->speed, finecosine[an]); mo->momy = FixedMul (mo->info->speed, finesine[an]); }
// // SkullAttack // Fly at the player like a missile. // #define SKULLSPEED (20*FRACUNIT)
void A_SkullAttack (mobj_t* actor) { mobj_t* dest; angle_t an; int dist;
if (!actor->target) return; dest = actor->target; actor->flags |= MF_SKULLFLY;
S_StartSound (actor, actor->info->attacksound); A_FaceTarget (actor); an = actor->angle >> ANGLETOFINESHIFT; actor->momx = FixedMul (SKULLSPEED, finecosine[an]); actor->momy = FixedMul (SKULLSPEED, finesine[an]); dist = P_AproxDistance (dest->x - actor->x, dest->y - actor->y); dist = dist / SKULLSPEED;
if (dist < 1) dist = 1; actor->momz = (dest->z+(dest->height>>1) - actor->z) / dist; }
// // A_PainShootSkull // Spawn a lost soul and launch it at the target // void A_PainShootSkull ( mobj_t* actor, angle_t angle ) { fixed_t x; fixed_t y; fixed_t z;
mobj_t* newmobj; angle_t an; int prestep; int count; thinker_t* currentthinker;
// count total number of skull currently on the level count = 0;
currentthinker = thinkercap.next; while (currentthinker != &thinkercap) { if ( (currentthinker->function.acp1 == (actionf_p1)P_MobjThinker) && ((mobj_t *)currentthinker)->type == MT_SKULL) count++; currentthinker = currentthinker->next; }
// if there are allready 20 skulls on the level, // don't spit another one if (count > 20) return;
// okay, there's playe for another one an = angle >> ANGLETOFINESHIFT;
prestep = 4*FRACUNIT + 3*(actor->info->radius + mobjinfo[MT_SKULL].radius)/2;
x = actor->x + FixedMul (prestep, finecosine[an]); y = actor->y + FixedMul (prestep, finesine[an]); z = actor->z + 8*FRACUNIT; newmobj = P_SpawnMobj (x , y, z, MT_SKULL);
// Check for movements. if (!P_TryMove (newmobj, newmobj->x, newmobj->y)) { // kill it immediately P_DamageMobj (newmobj,actor,actor,10000); return; } newmobj->target = actor->target; A_SkullAttack (newmobj); }
// // A_PainAttack // Spawn a lost soul and launch it at the target // void A_PainAttack (mobj_t* actor) { if (!actor->target) return;
A_FaceTarget (actor); A_PainShootSkull (actor, actor->angle); }
void A_PainDie (mobj_t* actor) { A_Fall (actor); A_PainShootSkull (actor, actor->angle+ANG90); A_PainShootSkull (actor, actor->angle+ANG180); A_PainShootSkull (actor, actor->angle+ANG270); }
void A_Scream (mobj_t* actor) { int sound; switch (actor->info->deathsound) { case 0: return; case sfx_podth1: case sfx_podth2: case sfx_podth3: sound = sfx_podth1 + P_Random ()%3; break; case sfx_bgdth1: case sfx_bgdth2: sound = sfx_bgdth1 + P_Random ()%2; break; default: sound = actor->info->deathsound; break; }
// Check for bosses. if (actor->type==MT_SPIDER || actor->type == MT_CYBORG) { // full volume S_StartSound (NULL, sound); } else S_StartSound (actor, sound); }
void A_XScream (mobj_t* actor) { S_StartSound (actor, sfx_slop); }
void A_Pain (mobj_t* actor) { if (actor->info->painsound) S_StartSound (actor, actor->info->painsound); }
void A_Fall (mobj_t *actor) { // actor is on ground, it can be walked over actor->flags &= ~MF_SOLID;
// So change this if corpse objects // are meant to be obstacles. }
// // A_Explode // void A_Explode (mobj_t* thingy) { P_RadiusAttack ( thingy, thingy->target, 128 ); }
// // A_BossDeath // Possibly trigger special effects // if on first boss level // void A_BossDeath (mobj_t* mo) { thinker_t* th; mobj_t* mo2; line_t junk; int i; if ( gamemode == commercial) { if (gamemap != 7) return; if ((mo->type != MT_FATSO) && (mo->type != MT_BABY)) return; } else { switch(gameepisode) { case 1: if (gamemap != 8) return;
if (mo->type != MT_BRUISER) return; break; case 2: if (gamemap != 8) return;
if (mo->type != MT_CYBORG) return; break; case 3: if (gamemap != 8) return; if (mo->type != MT_SPIDER) return; break; case 4: switch(gamemap) { case 6: if (mo->type != MT_CYBORG) return; break; case 8: if (mo->type != MT_SPIDER) return; break; default: return; break; } break; default: if (gamemap != 8) return; break; } }
// make sure there is a player alive for victory for (i=0 ; i<MAXPLAYERS ; i++) if (playeringame[i] && players[i].health > 0) break;
if (i==MAXPLAYERS) return; // no one left alive, so do not end game
// scan the remaining thinkers to see // if all bosses are dead for (th = thinkercap.next ; th != &thinkercap ; th=th->next) { if (th->function.acp1 != (actionf_p1)P_MobjThinker) continue; mo2 = (mobj_t *)th; if (mo2 != mo && mo2->type == mo->type && mo2->health > 0) { // other boss not dead return; } } // victory! if ( gamemode == commercial) { if (gamemap == 7) { if (mo->type == MT_FATSO) { junk.tag = 666; EV_DoFloor(&junk,lowerFloorToLowest); return; } if (mo->type == MT_BABY) { junk.tag = 667; EV_DoFloor(&junk,raiseToTexture); return; } } } else { switch(gameepisode) { case 1: junk.tag = 666; EV_DoFloor (&junk, lowerFloorToLowest); return; break; case 4: switch(gamemap) { case 6: junk.tag = 666; EV_DoDoor (&junk, blazeOpen); return; break; case 8: junk.tag = 666; EV_DoFloor (&junk, lowerFloorToLowest); return; break; } } } G_ExitLevel (); }
void A_Hoof (mobj_t* mo) { S_StartSound (mo, sfx_hoof); A_Chase (mo); }
void A_Metal (mobj_t* mo) { S_StartSound (mo, sfx_metal); A_Chase (mo); }
void A_BabyMetal (mobj_t* mo) { S_StartSound (mo, sfx_bspwlk); A_Chase (mo); }
void A_OpenShotgun2 ( player_t* player, pspdef_t* psp ) { S_StartSound (player->mo, sfx_dbopn); }
void A_LoadShotgun2 ( player_t* player, pspdef_t* psp ) { S_StartSound (player->mo, sfx_dbload); }
void A_ReFire ( player_t* player, pspdef_t* psp );
void A_CloseShotgun2 ( player_t* player, pspdef_t* psp ) { S_StartSound (player->mo, sfx_dbcls); A_ReFire(player,psp); }
mobj_t* braintargets[32]; int numbraintargets; int braintargeton;
void A_BrainAwake (mobj_t* mo) { thinker_t* thinker; mobj_t* m; // find all the target spots numbraintargets = 0; braintargeton = 0; thinker = thinkercap.next; for (thinker = thinkercap.next ; thinker != &thinkercap ; thinker = thinker->next) { if (thinker->function.acp1 != (actionf_p1)P_MobjThinker) continue; // not a mobj
m = (mobj_t *)thinker;
if (m->type == MT_BOSSTARGET ) { braintargets[numbraintargets] = m; numbraintargets++; } } S_StartSound (NULL,sfx_bossit); }
void A_BrainPain (mobj_t* mo) { S_StartSound (NULL,sfx_bospn); }
void A_BrainScream (mobj_t* mo) { int x; int y; int z; mobj_t* th; for (x=mo->x - 196*FRACUNIT ; x< mo->x + 320*FRACUNIT ; x+= FRACUNIT*8) { y = mo->y - 320*FRACUNIT; z = 128 + P_Random()*2*FRACUNIT; th = P_SpawnMobj (x,y,z, MT_ROCKET); th->momz = P_Random()*512;
P_SetMobjState (th, S_BRAINEXPLODE1);
th->tics -= P_Random()&7; if (th->tics < 1) th->tics = 1; } S_StartSound (NULL,sfx_bosdth); }
void A_BrainExplode (mobj_t* mo) { int x; int y; int z; mobj_t* th; x = mo->x + (P_Random () - P_Random ())*2048; y = mo->y; z = 128 + P_Random()*2*FRACUNIT; th = P_SpawnMobj (x,y,z, MT_ROCKET); th->momz = P_Random()*512;
P_SetMobjState (th, S_BRAINEXPLODE1);
th->tics -= P_Random()&7; if (th->tics < 1) th->tics = 1; }
void A_BrainDie (mobj_t* mo) { G_ExitLevel (); }
void A_BrainSpit (mobj_t* mo) { mobj_t* targ; mobj_t* newmobj;
static int easy = 0; easy ^= 1; if (gameskill <= sk_easy && (!easy)) return; // shoot a cube at current target targ = braintargets[braintargeton]; braintargeton = (braintargeton+1)%numbraintargets;
// spawn brain missile newmobj = P_SpawnMissile (mo, targ, MT_SPAWNSHOT); newmobj->target = targ; newmobj->reactiontime = ((targ->y - mo->y)/newmobj->momy) / newmobj->state->tics;
S_StartSound(NULL, sfx_bospit); }
void A_SpawnFly (mobj_t* mo);
// travelling cube sound void A_SpawnSound (mobj_t* mo) { S_StartSound (mo,sfx_boscub); A_SpawnFly(mo); }
void A_SpawnFly (mobj_t* mo) { mobj_t* newmobj; mobj_t* fog; mobj_t* targ; int r; mobjtype_t type; if (--mo->reactiontime) return; // still flying targ = mo->target;
// First spawn teleport fog. fog = P_SpawnMobj (targ->x, targ->y, targ->z, MT_SPAWNFIRE); S_StartSound (fog, sfx_telept);
// Randomly select monster to spawn. r = P_Random ();
// Probability distribution (kind of :), // decreasing likelihood. if ( r<50 ) type = MT_TROOP; else if (r<90) type = MT_SERGEANT; else if (r<120) type = MT_SHADOWS; else if (r<130) type = MT_PAIN; else if (r<160) type = MT_HEAD; else if (r<162) type = MT_VILE; else if (r<172) type = MT_UNDEAD; else if (r<192) type = MT_BABY; else if (r<222) type = MT_FATSO; else if (r<246) type = MT_KNIGHT; else type = MT_BRUISER;
newmobj = P_SpawnMobj (targ->x, targ->y, targ->z, type); if (P_LookForPlayers (newmobj, true) ) P_SetMobjState (newmobj, newmobj->info->seestate); // telefrag anything in this spot P_TeleportMove (newmobj, newmobj->x, newmobj->y);
// remove self (i.e., cube). P_RemoveMobj (mo); }
void A_PlayerScream (mobj_t* mo) { // Default death sound. int sound = sfx_pldeth; if ( (gamemode == commercial) && (mo->health < -50)) { // IF THE PLAYER DIES // LESS THAN -50% WITHOUT GIBBING sound = sfx_pdiehi; }
S_StartSound (mo, sound); } // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // Floor animation: raising stairs. // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: p_floor.c,v 1.4 1997/02/03 16:47:54 b1 Exp $";
#include "z_zone.h" #include "doomdef.h" #include "p_local.h"
#include "s_sound.h"
// State. #include "doomstat.h" #include "r_state.h" // Data. #include "sounds.h"
// // FLOORS //
// // Move a plane (floor or ceiling) and check for crushing // result_e T_MovePlane ( sector_t* sector, fixed_t speed, fixed_t dest, boolean crush, int floorOrCeiling, int direction ) { boolean flag; fixed_t lastpos; switch(floorOrCeiling) { case 0: // FLOOR switch(direction) { case -1: // DOWN if (sector->floorheight - speed < dest) { lastpos = sector->floorheight; sector->floorheight = dest; flag = P_ChangeSector(sector,crush); if (flag == true) { sector->floorheight =lastpos; P_ChangeSector(sector,crush); //return crushed; } return pastdest; } else { lastpos = sector->floorheight; sector->floorheight -= speed; flag = P_ChangeSector(sector,crush); if (flag == true) { sector->floorheight = lastpos; P_ChangeSector(sector,crush); return crushed; } } break; case 1: // UP if (sector->floorheight + speed > dest) { lastpos = sector->floorheight; sector->floorheight = dest; flag = P_ChangeSector(sector,crush); if (flag == true) { sector->floorheight = lastpos; P_ChangeSector(sector,crush); //return crushed; } return pastdest; } else { // COULD GET CRUSHED lastpos = sector->floorheight; sector->floorheight += speed; flag = P_ChangeSector(sector,crush); if (flag == true) { if (crush == true) return crushed; sector->floorheight = lastpos; P_ChangeSector(sector,crush); return crushed; } } break; } break; case 1: // CEILING switch(direction) { case -1: // DOWN if (sector->ceilingheight - speed < dest) { lastpos = sector->ceilingheight; sector->ceilingheight = dest; flag = P_ChangeSector(sector,crush);
if (flag == true) { sector->ceilingheight = lastpos; P_ChangeSector(sector,crush); //return crushed; } return pastdest; } else { // COULD GET CRUSHED lastpos = sector->ceilingheight; sector->ceilingheight -= speed; flag = P_ChangeSector(sector,crush);
if (flag == true) { if (crush == true) return crushed; sector->ceilingheight = lastpos; P_ChangeSector(sector,crush); return crushed; } } break; case 1: // UP if (sector->ceilingheight + speed > dest) { lastpos = sector->ceilingheight; sector->ceilingheight = dest; flag = P_ChangeSector(sector,crush); if (flag == true) { sector->ceilingheight = lastpos; P_ChangeSector(sector,crush); //return crushed; } return pastdest; } else { lastpos = sector->ceilingheight; sector->ceilingheight += speed; flag = P_ChangeSector(sector,crush); // UNUSED #if 0 if (flag == true) { sector->ceilingheight = lastpos; P_ChangeSector(sector,crush); return crushed; } #endif } break; } break; } return ok; }
// // MOVE A FLOOR TO IT'S DESTINATION (UP OR DOWN) // void T_MoveFloor(floormove_t* floor) { result_e res; res = T_MovePlane(floor->sector, floor->speed, floor->floordestheight, floor->crush,0,floor->direction);
if (!(leveltime&7)) S_StartSound((mobj_t *)&floor->sector->soundorg, sfx_stnmov);
if (res == pastdest) { floor->sector->specialdata = NULL;
if (floor->direction == 1) { switch(floor->type) { case donutRaise: floor->sector->special = floor->newspecial; floor->sector->floorpic = floor->texture; default: break; } } else if (floor->direction == -1) { switch(floor->type) { case lowerAndChange: floor->sector->special = floor->newspecial; floor->sector->floorpic = floor->texture; default: break; } } P_RemoveThinker(&floor->thinker);
S_StartSound((mobj_t *)&floor->sector->soundorg, sfx_pstop); }
}
// // HANDLE FLOOR TYPES // int EV_DoFloor ( line_t* line, floor_e floortype ) { int secnum; int rtn; int i; sector_t* sec; floormove_t* floor;
secnum = -1; rtn = 0; while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { sec = §ors[secnum]; // ALREADY MOVING? IF SO, KEEP GOING... if (sec->specialdata) continue; // new floor thinker rtn = 1; floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0); P_AddThinker (&floor->thinker); sec->specialdata = floor; floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor; floor->type = floortype; floor->crush = false;
switch(floortype) { case lowerFloor: floor->direction = -1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = P_FindHighestFloorSurrounding(sec); break;
case lowerFloorToLowest: floor->direction = -1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = P_FindLowestFloorSurrounding(sec); break;
case turboLower: floor->direction = -1; floor->sector = sec; floor->speed = FLOORSPEED * 4; floor->floordestheight = P_FindHighestFloorSurrounding(sec); if (floor->floordestheight != sec->floorheight) floor->floordestheight += 8*FRACUNIT; break;
case raiseFloorCrush: floor->crush = true; case raiseFloor: floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = P_FindLowestCeilingSurrounding(sec); if (floor->floordestheight > sec->ceilingheight) floor->floordestheight = sec->ceilingheight; floor->floordestheight -= (8*FRACUNIT)* (floortype == raiseFloorCrush); break;
case raiseFloorTurbo: floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED*4; floor->floordestheight = P_FindNextHighestFloor(sec,sec->floorheight); break;
case raiseFloorToNearest: floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = P_FindNextHighestFloor(sec,sec->floorheight); break;
case raiseFloor24: floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = floor->sector->floorheight + 24 * FRACUNIT; break; case raiseFloor512: floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = floor->sector->floorheight + 512 * FRACUNIT; break;
case raiseFloor24AndChange: floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = floor->sector->floorheight + 24 * FRACUNIT; sec->floorpic = line->frontsector->floorpic; sec->special = line->frontsector->special; break;
case raiseToTexture: { int minsize = MAXINT; side_t* side; floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED; for (i = 0; i < sec->linecount; i++) { if (twoSided (secnum, i) ) { side = getSide(secnum,i,0); if (side->bottomtexture >= 0) if (textureheight[side->bottomtexture] < minsize) minsize = textureheight[side->bottomtexture]; side = getSide(secnum,i,1); if (side->bottomtexture >= 0) if (textureheight[side->bottomtexture] < minsize) minsize = textureheight[side->bottomtexture]; } } floor->floordestheight = floor->sector->floorheight + minsize; } break; case lowerAndChange: floor->direction = -1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = P_FindLowestFloorSurrounding(sec); floor->texture = sec->floorpic;
for (i = 0; i < sec->linecount; i++) { if ( twoSided(secnum, i) ) { if (getSide(secnum,i,0)->sector-sectors == secnum) { sec = getSector(secnum,i,1);
if (sec->floorheight == floor->floordestheight) { floor->texture = sec->floorpic; floor->newspecial = sec->special; break; } } else { sec = getSector(secnum,i,0);
if (sec->floorheight == floor->floordestheight) { floor->texture = sec->floorpic; floor->newspecial = sec->special; break; } } } } default: break; } } return rtn; }
// // BUILD A STAIRCASE! // int EV_BuildStairs ( line_t* line, stair_e type ) { int secnum; int height; int i; int newsecnum; int texture; int ok; int rtn;
sector_t* sec; sector_t* tsec;
floormove_t* floor;
fixed_t stairsize; fixed_t speed;
secnum = -1; rtn = 0; while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { sec = §ors[secnum]; // ALREADY MOVING? IF SO, KEEP GOING... if (sec->specialdata) continue; // new floor thinker rtn = 1; floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0); P_AddThinker (&floor->thinker); sec->specialdata = floor; floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor; floor->direction = 1; floor->sector = sec; switch(type) { case build8: speed = FLOORSPEED/4; stairsize = 8*FRACUNIT; break; case turbo16: speed = FLOORSPEED*4; stairsize = 16*FRACUNIT; break; } floor->speed = speed; height = sec->floorheight + stairsize; floor->floordestheight = height; texture = sec->floorpic; // Find next sector to raise // 1. Find 2-sided line with same sector side[0] // 2. Other side is the next sector to raise do { ok = 0; for (i = 0;i < sec->linecount;i++) { if ( !((sec->lines[i])->flags & ML_TWOSIDED) ) continue; tsec = (sec->lines[i])->frontsector; newsecnum = tsec-sectors; if (secnum != newsecnum) continue;
tsec = (sec->lines[i])->backsector; newsecnum = tsec - sectors;
if (tsec->floorpic != texture) continue; height += stairsize;
if (tsec->specialdata) continue; sec = tsec; secnum = newsecnum; floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0);
P_AddThinker (&floor->thinker);
sec->specialdata = floor; floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor; floor->direction = 1; floor->sector = sec; floor->speed = speed; floor->floordestheight = height; ok = 1; break; } } while(ok); } return rtn; }
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // Handling interactions (i.e., collisions). // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: p_inter.c,v 1.4 1997/02/03 22:45:11 b1 Exp $";
// Data. #include "doomdef.h" #include "dstrings.h" #include "sounds.h"
#include "doomstat.h"
#include "m_random.h" #include "i_system.h"
#include "am_map.h"
#include "p_local.h"
#include "s_sound.h"
#ifdef __GNUG__ #pragma implementation "p_inter.h" #endif #include "p_inter.h"
#define BONUSADD 6
// a weapon is found with two clip loads, // a big item has five clip loads int maxammo[NUMAMMO] = {200, 50, 300, 50}; int clipammo[NUMAMMO] = {10, 4, 20, 1};
// // GET STUFF //
// // P_GiveAmmo // Num is the number of clip loads, // not the individual count (0= 1/2 clip). // Returns false if the ammo can't be picked up at all //
boolean P_GiveAmmo ( player_t* player, ammotype_t ammo, int num ) { int oldammo; if (ammo == am_noammo) return false; if (ammo < 0 || ammo > NUMAMMO) I_Error ("P_GiveAmmo: bad type %i", ammo); if ( player->ammo[ammo] == player->maxammo[ammo] ) return false; if (num) num *= clipammo[ammo]; else num = clipammo[ammo]/2;
if (gameskill == sk_baby || gameskill == sk_nightmare) { // give double ammo in trainer mode, // you'll need in nightmare num <<= 1; }
oldammo = player->ammo[ammo]; player->ammo[ammo] += num;
if (player->ammo[ammo] > player->maxammo[ammo]) player->ammo[ammo] = player->maxammo[ammo];
// If non zero ammo, // don't change up weapons, // player was lower on purpose. if (oldammo) return true;
// We were down to zero, // so select a new weapon. // Preferences are not user selectable. switch (ammo) { case am_clip: if (player->readyweapon == wp_fist) { if (player->weaponowned[wp_chaingun]) player->pendingweapon = wp_chaingun; else player->pendingweapon = wp_pistol; } break; case am_shell: if (player->readyweapon == wp_fist || player->readyweapon == wp_pistol) { if (player->weaponowned[wp_shotgun]) player->pendingweapon = wp_shotgun; } break; case am_cell: if (player->readyweapon == wp_fist || player->readyweapon == wp_pistol) { if (player->weaponowned[wp_plasma]) player->pendingweapon = wp_plasma; } break; case am_misl: if (player->readyweapon == wp_fist) { if (player->weaponowned[wp_missile]) player->pendingweapon = wp_missile; } default: break; } return true; }
// // P_GiveWeapon // The weapon name may have a MF_DROPPED flag ored in. // boolean P_GiveWeapon ( player_t* player, weapontype_t weapon, boolean dropped ) { boolean gaveammo; boolean gaveweapon; if (netgame && (deathmatch!=2) && !dropped ) { // leave placed weapons forever on net games if (player->weaponowned[weapon]) return false;
player->bonuscount += BONUSADD; player->weaponowned[weapon] = true;
if (deathmatch) P_GiveAmmo (player, weaponinfo[weapon].ammo, 5); else P_GiveAmmo (player, weaponinfo[weapon].ammo, 2); player->pendingweapon = weapon;
if (player == &players[consoleplayer]) S_StartSound (NULL, sfx_wpnup); return false; } if (weaponinfo[weapon].ammo != am_noammo) { // give one clip with a dropped weapon, // two clips with a found weapon if (dropped) gaveammo = P_GiveAmmo (player, weaponinfo[weapon].ammo, 1); else gaveammo = P_GiveAmmo (player, weaponinfo[weapon].ammo, 2); } else gaveammo = false; if (player->weaponowned[weapon]) gaveweapon = false; else { gaveweapon = true; player->weaponowned[weapon] = true; player->pendingweapon = weapon; } return (gaveweapon || gaveammo); }
// // P_GiveBody // Returns false if the body isn't needed at all // boolean P_GiveBody ( player_t* player, int num ) { if (player->health >= MAXHEALTH) return false; player->health += num; if (player->health > MAXHEALTH) player->health = MAXHEALTH; player->mo->health = player->health; return true; }
// // P_GiveArmor // Returns false if the armor is worse // than the current armor. // boolean P_GiveArmor ( player_t* player, int armortype ) { int hits; hits = armortype*100; if (player->armorpoints >= hits) return false; // don't pick up player->armortype = armortype; player->armorpoints = hits; return true; }
// // P_GiveCard // void P_GiveCard ( player_t* player, card_t card ) { if (player->cards[card]) return;
player->bonuscount = BONUSADD; player->cards[card] = 1; }
// // P_GivePower // boolean P_GivePower ( player_t* player, int /*powertype_t*/ power ) { if (power == pw_invulnerability) { player->powers[power] = INVULNTICS; return true; }
if (power == pw_invisibility) { player->powers[power] = INVISTICS; player->mo->flags |= MF_SHADOW; return true; }
if (power == pw_infrared) { player->powers[power] = INFRATICS; return true; }
if (power == pw_ironfeet) { player->powers[power] = IRONTICS; return true; }
if (power == pw_strength) { P_GiveBody (player, 100); player->powers[power] = 1; return true; } if (player->powers[power]) return false; // already got it player->powers[power] = 1; return true; }
// // P_TouchSpecialThing // void P_TouchSpecialThing ( mobj_t* special, mobj_t* toucher ) { player_t* player; int i; fixed_t delta; int sound; delta = special->z - toucher->z;
if (delta > toucher->height || delta < -8*FRACUNIT) { // out of reach return; }
sound = sfx_itemup; player = toucher->player;
// Dead thing touching. // Can happen with a sliding player corpse. if (toucher->health <= 0) return;
// Identify by sprite. switch (special->sprite) { // armor case SPR_ARM1: if (!P_GiveArmor (player, 1)) return; player->message = GOTARMOR; break; case SPR_ARM2: if (!P_GiveArmor (player, 2)) return; player->message = GOTMEGA; break; // bonus items case SPR_BON1: player->health++; // can go over 100% if (player->health > 200) player->health = 200; player->mo->health = player->health; player->message = GOTHTHBONUS; break; case SPR_BON2: player->armorpoints++; // can go over 100% if (player->armorpoints > 200) player->armorpoints = 200; if (!player->armortype) player->armortype = 1; player->message = GOTARMBONUS; break; case SPR_SOUL: player->health += 100; if (player->health > 200) player->health = 200; player->mo->health = player->health; player->message = GOTSUPER; sound = sfx_getpow; break; case SPR_MEGA: if (gamemode != commercial) return; player->health = 200; player->mo->health = player->health; P_GiveArmor (player,2); player->message = GOTMSPHERE; sound = sfx_getpow; break; // cards // leave cards for everyone case SPR_BKEY: if (!player->cards[it_bluecard]) player->message = GOTBLUECARD; P_GiveCard (player, it_bluecard); if (!netgame) break; return; case SPR_YKEY: if (!player->cards[it_yellowcard]) player->message = GOTYELWCARD; P_GiveCard (player, it_yellowcard); if (!netgame) break; return; case SPR_RKEY: if (!player->cards[it_redcard]) player->message = GOTREDCARD; P_GiveCard (player, it_redcard); if (!netgame) break; return; case SPR_BSKU: if (!player->cards[it_blueskull]) player->message = GOTBLUESKUL; P_GiveCard (player, it_blueskull); if (!netgame) break; return; case SPR_YSKU: if (!player->cards[it_yellowskull]) player->message = GOTYELWSKUL; P_GiveCard (player, it_yellowskull); if (!netgame) break; return; case SPR_RSKU: if (!player->cards[it_redskull]) player->message = GOTREDSKULL; P_GiveCard (player, it_redskull); if (!netgame) break; return; // medikits, heals case SPR_STIM: if (!P_GiveBody (player, 10)) return; player->message = GOTSTIM; break; case SPR_MEDI: if (!P_GiveBody (player, 25)) return;
if (player->health < 25) player->message = GOTMEDINEED; else player->message = GOTMEDIKIT; break;
// power ups case SPR_PINV: if (!P_GivePower (player, pw_invulnerability)) return; player->message = GOTINVUL; sound = sfx_getpow; break; case SPR_PSTR: if (!P_GivePower (player, pw_strength)) return; player->message = GOTBERSERK; if (player->readyweapon != wp_fist) player->pendingweapon = wp_fist; sound = sfx_getpow; break; case SPR_PINS: if (!P_GivePower (player, pw_invisibility)) return; player->message = GOTINVIS; sound = sfx_getpow; break; case SPR_SUIT: if (!P_GivePower (player, pw_ironfeet)) return; player->message = GOTSUIT; sound = sfx_getpow; break; case SPR_PMAP: if (!P_GivePower (player, pw_allmap)) return; player->message = GOTMAP; sound = sfx_getpow; break; case SPR_PVIS: if (!P_GivePower (player, pw_infrared)) return; player->message = GOTVISOR; sound = sfx_getpow; break; // ammo case SPR_CLIP: if (special->flags & MF_DROPPED) { if (!P_GiveAmmo (player,am_clip,0)) return; } else { if (!P_GiveAmmo (player,am_clip,1)) return; } player->message = GOTCLIP; break; case SPR_AMMO: if (!P_GiveAmmo (player, am_clip,5)) return; player->message = GOTCLIPBOX; break; case SPR_ROCK: if (!P_GiveAmmo (player, am_misl,1)) return; player->message = GOTROCKET; break; case SPR_BROK: if (!P_GiveAmmo (player, am_misl,5)) return; player->message = GOTROCKBOX; break; case SPR_CELL: if (!P_GiveAmmo (player, am_cell,1)) return; player->message = GOTCELL; break; case SPR_CELP: if (!P_GiveAmmo (player, am_cell,5)) return; player->message = GOTCELLBOX; break; case SPR_SHEL: if (!P_GiveAmmo (player, am_shell,1)) return; player->message = GOTSHELLS; break; case SPR_SBOX: if (!P_GiveAmmo (player, am_shell,5)) return; player->message = GOTSHELLBOX; break; case SPR_BPAK: if (!player->backpack) { for (i=0 ; i<NUMAMMO ; i++) player->maxammo[i] *= 2; player->backpack = true; } for (i=0 ; i<NUMAMMO ; i++) P_GiveAmmo (player, i, 1); player->message = GOTBACKPACK; break; // weapons case SPR_BFUG: if (!P_GiveWeapon (player, wp_bfg, false) ) return; player->message = GOTBFG9000; sound = sfx_wpnup; break; case SPR_MGUN: if (!P_GiveWeapon (player, wp_chaingun, special->flags&MF_DROPPED) ) return; player->message = GOTCHAINGUN; sound = sfx_wpnup; break; case SPR_CSAW: if (!P_GiveWeapon (player, wp_chainsaw, false) ) return; player->message = GOTCHAINSAW; sound = sfx_wpnup; break; case SPR_LAUN: if (!P_GiveWeapon (player, wp_missile, false) ) return; player->message = GOTLAUNCHER; sound = sfx_wpnup; break; case SPR_PLAS: if (!P_GiveWeapon (player, wp_plasma, false) ) return; player->message = GOTPLASMA; sound = sfx_wpnup; break; case SPR_SHOT: if (!P_GiveWeapon (player, wp_shotgun, special->flags&MF_DROPPED ) ) return; player->message = GOTSHOTGUN; sound = sfx_wpnup; break; case SPR_SGN2: if (!P_GiveWeapon (player, wp_supershotgun, special->flags&MF_DROPPED ) ) return; player->message = GOTSHOTGUN2; sound = sfx_wpnup; break; default: I_Error ("P_SpecialThing: Unknown gettable thing"); } if (special->flags & MF_COUNTITEM) player->itemcount++; P_RemoveMobj (special); player->bonuscount += BONUSADD; if (player == &players[consoleplayer]) S_StartSound (NULL, sound); }
// // KillMobj // void P_KillMobj ( mobj_t* source, mobj_t* target ) { mobjtype_t item; mobj_t* mo; target->flags &= ~(MF_SHOOTABLE|MF_FLOAT|MF_SKULLFLY);
if (target->type != MT_SKULL) target->flags &= ~MF_NOGRAVITY;
target->flags |= MF_CORPSE|MF_DROPOFF; target->height >>= 2;
if (source && source->player) { // count for intermission if (target->flags & MF_COUNTKILL) source->player->killcount++;
if (target->player) source->player->frags[target->player-players]++; } else if (!netgame && (target->flags & MF_COUNTKILL) ) { // count all monster deaths, // even those caused by other monsters players[0].killcount++; }
if (target->player) { // count environment kills against you if (!source) target->player->frags[target->player-players]++; target->flags &= ~MF_SOLID; target->player->playerstate = PST_DEAD; P_DropWeapon (target->player);
if (target->player == &players[consoleplayer] && automapactive) { // don't die in auto map, // switch view prior to dying AM_Stop (); } }
if (target->health < -target->info->spawnhealth && target->info->xdeathstate) { P_SetMobjState (target, target->info->xdeathstate); } else P_SetMobjState (target, target->info->deathstate); target->tics -= P_Random()&3;
if (target->tics < 1) target->tics = 1; // I_StartSound (&actor->r, actor->info->deathsound);
// Drop stuff. // This determines the kind of object spawned // during the death frame of a thing. switch (target->type) { case MT_WOLFSS: case MT_POSSESSED: item = MT_CLIP; break; case MT_SHOTGUY: item = MT_SHOTGUN; break; case MT_CHAINGUY: item = MT_CHAINGUN; break; default: return; }
mo = P_SpawnMobj (target->x,target->y,ONFLOORZ, item); mo->flags |= MF_DROPPED; // special versions of items }
// // P_DamageMobj // Damages both enemies and players // "inflictor" is the thing that caused the damage // creature or missile, can be NULL (slime, etc) // "source" is the thing to target after taking damage // creature or NULL // Source and inflictor are the same for melee attacks. // Source can be NULL for slime, barrel explosions // and other environmental stuff. // void P_DamageMobj ( mobj_t* target, mobj_t* inflictor, mobj_t* source, int damage ) { unsigned ang; int saved; player_t* player; fixed_t thrust; int temp; if ( !(target->flags & MF_SHOOTABLE) ) return; // shouldn't happen... if (target->health <= 0) return;
if ( target->flags & MF_SKULLFLY ) { target->momx = target->momy = target->momz = 0; } player = target->player; if (player && gameskill == sk_baby) damage >>= 1; // take half damage in trainer mode
// Some close combat weapons should not // inflict thrust and push the victim out of reach, // thus kick away unless using the chainsaw. if (inflictor && !(target->flags & MF_NOCLIP) && (!source || !source->player || source->player->readyweapon != wp_chainsaw)) { ang = R_PointToAngle2 ( inflictor->x, inflictor->y, target->x, target->y); thrust = damage*(FRACUNIT>>3)*100/target->info->mass;
// make fall forwards sometimes if ( damage < 40 && damage > target->health && target->z - inflictor->z > 64*FRACUNIT && (P_Random ()&1) ) { ang += ANG180; thrust *= 4; } ang >>= ANGLETOFINESHIFT; target->momx += FixedMul (thrust, finecosine[ang]); target->momy += FixedMul (thrust, finesine[ang]); }
// player specific if (player) { // end of game hell hack if (target->subsector->sector->special == 11 && damage >= target->health) { damage = target->health - 1; }
// Below certain threshold, // ignore damage in GOD mode, or with INVUL power. if ( damage < 1000 && ( (player->cheats&CF_GODMODE) || player->powers[pw_invulnerability] ) ) { return; } if (player->armortype) { if (player->armortype == 1) saved = damage/3; else saved = damage/2; if (player->armorpoints <= saved) { // armor is used up saved = player->armorpoints; player->armortype = 0; } player->armorpoints -= saved; damage -= saved; } player->health -= damage; // mirror mobj health here for Dave if (player->health < 0) player->health = 0; player->attacker = source; player->damagecount += damage; // add damage after armor / invuln
if (player->damagecount > 100) player->damagecount = 100; // teleport stomp does 10k points... temp = damage < 100 ? damage : 100;
if (player == &players[consoleplayer]) I_Tactile (40,10,40+temp*2); }
// do the damage target->health -= damage; if (target->health <= 0) { P_KillMobj (source, target); return; }
if ( (P_Random () < target->info->painchance) && !(target->flags&MF_SKULLFLY) ) { target->flags |= MF_JUSTHIT; // fight back! P_SetMobjState (target, target->info->painstate); } target->reactiontime = 0; // we're awake now...
if ( (!target->threshold || target->type == MT_VILE) && source && source != target && source->type != MT_VILE) { // if not intent on another player, // chase after this one target->target = source; target->threshold = BASETHRESHOLD; if (target->state == &states[target->info->spawnstate] && target->info->seestate != S_NULL) P_SetMobjState (target, target->info->seestate); } }
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // // //-----------------------------------------------------------------------------
#ifndef __P_INTER__ #define __P_INTER__
#ifdef __GNUG__ #pragma interface #endif
boolean P_GivePower(player_t*, int);
#endif //----------------------------------------------------------------------------- // // $Log:$ // //----------------------------------------------------------------------------- // Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // Handle Sector base lighting effects. // Muzzle flash? // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: p_lights.c,v 1.5 1997/02/03 22:45:11 b1 Exp $";
#include "z_zone.h" #include "m_random.h"
#include "doomdef.h" #include "p_local.h"
// State. #include "r_state.h"
// // FIRELIGHT FLICKER //
// // T_FireFlicker // void T_FireFlicker (fireflicker_t* flick) { int amount; if (--flick->count) return; amount = (P_Random()&3)*16;
if (flick->sector->lightlevel - amount < flick->minlight) flick->sector->lightlevel = flick->minlight; else flick->sector->lightlevel = flick->maxlight - amount;
flick->count = 4; }
// // P_SpawnFireFlicker // void P_SpawnFireFlicker (sector_t* sector) { fireflicker_t* flick; // Note that we are resetting sector attributes. // Nothing special about it during gameplay. sector->special = 0; flick = Z_Malloc ( sizeof(*flick), PU_LEVSPEC, 0);
P_AddThinker (&flick->thinker);
flick->thinker.function.acp1 = (actionf_p1) T_FireFlicker; flick->sector = sector; flick->maxlight = sector->lightlevel; flick->minlight = P_FindMinSurroundingLight(sector,sector->lightlevel)+16; flick->count = 4; }
// // BROKEN LIGHT FLASHING //
// // T_LightFlash // Do flashing lights. // void T_LightFlash (lightflash_t* flash) { if (--flash->count) return; if (flash->sector->lightlevel == flash->maxlight) { flash-> sector->lightlevel = flash->minlight; flash->count = (P_Random()&flash->mintime)+1; } else { flash-> sector->lightlevel = flash->maxlight; flash->count = (P_Random()&flash->maxtime)+1; }
}
// // P_SpawnLightFlash // After the map has been loaded, scan each sector // for specials that spawn thinkers // void P_SpawnLightFlash (sector_t* sector) { lightflash_t* flash;
// nothing special about it during gameplay sector->special = 0; flash = Z_Malloc ( sizeof(*flash), PU_LEVSPEC, 0);
P_AddThinker (&flash->thinker);
flash->thinker.function.acp1 = (actionf_p1) T_LightFlash; flash->sector = sector; flash->maxlight = sector->lightlevel;
flash->minlight = P_FindMinSurroundingLight(sector,sector->lightlevel); flash->maxtime = 64; flash->mintime = 7; flash->count = (P_Random()&flash->maxtime)+1; }
// // STROBE LIGHT FLASHING //
// // T_StrobeFlash // void T_StrobeFlash (strobe_t* flash) { if (--flash->count) return; if (flash->sector->lightlevel == flash->minlight) { flash-> sector->lightlevel = flash->maxlight; flash->count = flash->brighttime; } else { flash-> sector->lightlevel = flash->minlight; flash->count =flash->darktime; }
}
// // P_SpawnStrobeFlash // After the map has been loaded, scan each sector // for specials that spawn thinkers // void P_SpawnStrobeFlash ( sector_t* sector, int fastOrSlow, int inSync ) { strobe_t* flash; flash = Z_Malloc ( sizeof(*flash), PU_LEVSPEC, 0);
P_AddThinker (&flash->thinker);
flash->sector = sector; flash->darktime = fastOrSlow; flash->brighttime = STROBEBRIGHT; flash->thinker.function.acp1 = (actionf_p1) T_StrobeFlash; flash->maxlight = sector->lightlevel; flash->minlight = P_FindMinSurroundingLight(sector, sector->lightlevel); if (flash->minlight == flash->maxlight) flash->minlight = 0;
// nothing special about it during gameplay sector->special = 0;
if (!inSync) flash->count = (P_Random()&7)+1; else flash->count = 1; }
// // Start strobing lights (usually from a trigger) // void EV_StartLightStrobing(line_t* line) { int secnum; sector_t* sec; secnum = -1; while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { sec = §ors[secnum]; if (sec->specialdata) continue; P_SpawnStrobeFlash (sec,SLOWDARK, 0); } }
// // TURN LINE'S TAG LIGHTS OFF // void EV_TurnTagLightsOff(line_t* line) { int i; int j; int min; sector_t* sector; sector_t* tsec; line_t* templine; sector = sectors;
for (j = 0;j < numsectors; j++, sector++) { if (sector->tag == line->tag) { min = sector->lightlevel; for (i = 0;i < sector->linecount; i++) { templine = sector->lines[i]; tsec = getNextSector(templine,sector); if (!tsec) continue; if (tsec->lightlevel < min) min = tsec->lightlevel; } sector->lightlevel = min; } } }
// // TURN LINE'S TAG LIGHTS ON // void EV_LightTurnOn ( line_t* line, int bright ) { int i; int j; sector_t* sector; sector_t* temp; line_t* templine; sector = sectors; for (i=0;i<numsectors;i++, sector++) { if (sector->tag == line->tag) { // bright = 0 means to search // for highest light level // surrounding sector if (!bright) { for (j = 0;j < sector->linecount; j++) { templine = sector->lines[j]; temp = getNextSector(templine,sector);
if (!temp) continue;
if (temp->lightlevel > bright) bright = temp->lightlevel; } } sector-> lightlevel = bright; } } }
// // Spawn glowing light //
void T_Glow(glow_t* g) { switch(g->direction) { case -1: // DOWN g->sector->lightlevel -= GLOWSPEED; if (g->sector->lightlevel <= g->minlight) { g->sector->lightlevel += GLOWSPEED; g->direction = 1; } break; case 1: // UP g->sector->lightlevel += GLOWSPEED; if (g->sector->lightlevel >= g->maxlight) { g->sector->lightlevel -= GLOWSPEED; g->direction = -1; } break; } }
void P_SpawnGlowingLight(sector_t* sector) { glow_t* g; g = Z_Malloc( sizeof(*g), PU_LEVSPEC, 0);
P_AddThinker(&g->thinker);
g->sector = sector; g->minlight = P_FindMinSurroundingLight(sector,sector->lightlevel); g->maxlight = sector->lightlevel; g->thinker.function.acp1 = (actionf_p1) T_Glow; g->direction = -1;
sector->special = 0; }
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // DESCRIPTION: // Play functions, animation, global header. // //-----------------------------------------------------------------------------
#ifndef __P_LOCAL__ #define __P_LOCAL__
#ifndef __R_LOCAL__ #include "r_local.h" #endif
#define FLOATSPEED (FRACUNIT*4)
#define MAXHEALTH 100 #define VIEWHEIGHT (41*FRACUNIT)
// mapblocks are used to check movement // against lines and things #define MAPBLOCKUNITS 128 #define MAPBLOCKSIZE (MAPBLOCKUNITS*FRACUNIT) #define MAPBLOCKSHIFT (FRACBITS+7) #define MAPBMASK (MAPBLOCKSIZE-1) #define MAPBTOFRAC (MAPBLOCKSHIFT-FRACBITS)
// player radius for movement checking #define PLAYERRADIUS 16*FRACUNIT
// MAXRADIUS is for precalculated sector block boxes // the spider demon is larger, // but we do not have any moving sectors nearby #define MAXRADIUS 32*FRACUNIT
#define GRAVITY FRACUNIT #define MAXMOVE (30*FRACUNIT)
#define USERANGE (64*FRACUNIT) #define MELEERANGE (64*FRACUNIT) #define MISSILERANGE (32*64*FRACUNIT)
// follow a player exlusively for 3 seconds #define BASETHRESHOLD 100
// // P_TICK //
// both the head and tail of the thinker list extern thinker_t thinkercap;
void P_InitThinkers (void); void P_AddThinker (thinker_t* thinker); void P_RemoveThinker (thinker_t* thinker);
// // P_PSPR // void P_SetupPsprites (player_t* curplayer); void P_MovePsprites (player_t* curplayer); void P_DropWeapon (player_t* player);
// // P_USER // void P_PlayerThink (player_t* player);
// // P_MOBJ // #define ONFLOORZ MININT #define ONCEILINGZ MAXINT
// Time interval for item respawning. #define ITEMQUESIZE 128
extern mapthing_t itemrespawnque[ITEMQUESIZE]; extern int itemrespawntime[ITEMQUESIZE]; extern int iquehead; extern int iquetail;
void P_RespawnSpecials (void);
mobj_t* P_SpawnMobj ( fixed_t x, fixed_t y, fixed_t z, mobjtype_t type );
void P_RemoveMobj (mobj_t* th); boolean P_SetMobjState (mobj_t* mobj, statenum_t state); void P_MobjThinker (mobj_t* mobj);
void P_SpawnPuff (fixed_t x, fixed_t y, fixed_t z); void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, int damage); mobj_t* P_SpawnMissile (mobj_t* source, mobj_t* dest, mobjtype_t type); void P_SpawnPlayerMissile (mobj_t* source, mobjtype_t type);
// // P_ENEMY // void P_NoiseAlert (mobj_t* target, mobj_t* emmiter);
// // P_MAPUTL // typedef struct { fixed_t x; fixed_t y; fixed_t dx; fixed_t dy;
} divline_t;
typedef struct { fixed_t frac; // along trace line boolean isaline; union { mobj_t* thing; line_t* line; } d; } intercept_t;
#define MAXINTERCEPTS 128
extern intercept_t intercepts[MAXINTERCEPTS]; extern intercept_t* intercept_p;
typedef boolean (*traverser_t) (intercept_t *in);
fixed_t P_AproxDistance (fixed_t dx, fixed_t dy); int P_PointOnLineSide (fixed_t x, fixed_t y, line_t* line); int P_PointOnDivlineSide (fixed_t x, fixed_t y, divline_t* line); void P_MakeDivline (line_t* li, divline_t* dl); fixed_t P_InterceptVector (divline_t* v2, divline_t* v1); int P_BoxOnLineSide (fixed_t* tmbox, line_t* ld);
extern fixed_t opentop; extern fixed_t openbottom; extern fixed_t openrange; extern fixed_t lowfloor;
void P_LineOpening (line_t* linedef);
boolean P_BlockLinesIterator (int x, int y, boolean(*func)(line_t*) ); boolean P_BlockThingsIterator (int x, int y, boolean(*func)(mobj_t*) );
#define PT_ADDLINES 1 #define PT_ADDTHINGS 2 #define PT_EARLYOUT 4
extern divline_t trace;
boolean P_PathTraverse ( fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int flags, boolean (*trav) (intercept_t *));
void P_UnsetThingPosition (mobj_t* thing); void P_SetThingPosition (mobj_t* thing);
// // P_MAP //
// If "floatok" true, move would be ok // if within "tmfloorz - tmceilingz". extern boolean floatok; extern fixed_t tmfloorz; extern fixed_t tmceilingz;
extern line_t* ceilingline;
boolean P_CheckPosition (mobj_t *thing, fixed_t x, fixed_t y); boolean P_TryMove (mobj_t* thing, fixed_t x, fixed_t y); boolean P_TeleportMove (mobj_t* thing, fixed_t x, fixed_t y); void P_SlideMove (mobj_t* mo); boolean P_CheckSight (mobj_t* t1, mobj_t* t2); void P_UseLines (player_t* player);
boolean P_ChangeSector (sector_t* sector, boolean crunch);
extern mobj_t* linetarget; // who got hit (or NULL)
fixed_t P_AimLineAttack ( mobj_t* t1, angle_t angle, fixed_t distance );
void P_LineAttack ( mobj_t* t1, angle_t angle, fixed_t distance, fixed_t slope, int damage );
void P_RadiusAttack ( mobj_t* spot, mobj_t* source, int damage );
// // P_SETUP // extern byte* rejectmatrix; // for fast sight rejection extern short* blockmaplump; // offsets in blockmap are from here extern short* blockmap; extern int bmapwidth; extern int bmapheight; // in mapblocks extern fixed_t bmaporgx; extern fixed_t bmaporgy; // origin of block map extern mobj_t** blocklinks; // for thing chains
// // P_INTER // extern int maxammo[NUMAMMO]; extern int clipammo[NUMAMMO];
void P_TouchSpecialThing ( mobj_t* special, mobj_t* toucher );
void P_DamageMobj ( mobj_t* target, mobj_t* inflictor, mobj_t* source, int damage );
// // P_SPEC // #include "p_spec.h"
#endif // __P_LOCAL__ //----------------------------------------------------------------------------- // // $Log:$ // //-----------------------------------------------------------------------------
// Emacs style mode select -*- C++ -*- //----------------------------------------------------------------------------- // // $Id:$ // // Copyright (C) 1993-1996 by id Software, Inc. // // This source is available for distribution and/or modification // only under the terms of the DOOM Source Code License as // published by id Software. All rights reserved. // // The source is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License // for more details. // // $Log:$ // // DESCRIPTION: // Movement, collision handling. // Shooting and aiming. // //-----------------------------------------------------------------------------
static const char rcsid[] = "$Id: p_map.c,v 1.5 1997/02/03 22:45:11 b1 Exp $";
#include <stdlib.h>
#include "m_bbox.h" #include "m_random.h" #include "i_system.h"
#include "doomdef.h" #include "p_local.h"
#include "s_sound.h"
// State. #include "doomstat.h" #include "r_state.h" // Data. #include "sounds.h"
fixed_t tmbbox[4]; mobj_t* tmthing; int tmflags; fixed_t tmx; fixed_t tmy;
// If "floatok" true, move would be ok // if within "tmfloorz - tmceilingz". boolean floatok;
fixed_t tmfloorz; fixed_t tmceilingz; fixed_t tmdropoffz;
// keep track of the line that lowers the ceiling, // so missiles don't explode against sky hack walls line_t* ceilingline;
// keep track of special lines as they are hit, // but don't process them until the move is proven valid #define MAXSPECIALCROSS 8
line_t* spechit[MAXSPECIALCROSS]; int numspechit;
15 notes
·
View notes
Text
Weekend Top Ten #613
Top Ten Moments in Jurassic Park
So for no other reason than I want to get it done before the end of the year, this week I’m talking about Jurassic Park. This year is the thirtieth (thirtieth!) anniversary of Jurassic Park. And Jurassic Park is one of the most important films of my lifetime; so important that I genuinely think of my life before 1993, and after 1993. It really was a year.
Jurassic Park is when I fell in love with film. I was always into watching films and stuff like that, but there was something about the synthesis of so many of my interests: Steven Spielberg, the guy who’d been involved in some of my favourite films, from E.T. to Back to the Future to Roger Rabbit; dinosaurs, which were cool; science fiction in general; “grown-up” novels and fiction; blockbuster cinema; special effects; and the whole filmmaking process in general, amped up by all the “making-ofs” I consumed, and especially the fact that I devoured issue 50 of Empire magazine, with its big ol’ T-Rex on the cover. All these things came together, the hinterland between a childish enjoyment of entertaining pastimes and an adult appreciation of an artform; the moment when I dived headfirst into something, wanted to peek behind the curtain, wanted to examine the human beings who’d made all this possible. I’d had a bit of that with comics, learning the names and of writers and artists on Transformers, but now my love of cinema exploded.
It helped that Jurassic Park is an absolute blast, of course.
So as this is the film’s thirtieth year, I wanted to celebrate before the year was over. And it feels apt to go back to a very early format for these Top Tens and list not just my favourite moments, but my favourite moments as represented by a line of dialogue. This was incredibly hard, and not just because there’s no easy line to represent the bit with the kids in the kitchen. But like life, I found a way.
That’s funny coz it’s like a line in the film.
Anyway, unlock the gate, don your yellow poncho, grab a spoonful of jelly and join me as I welcome you… to Jurassic Park. Make sure you’re back here in 2027 for the sequel! More of the same but with Pete Postlethwaite this time!
“I hate being right all the time.”: surely the centrepiece of the film is the barnstorming, paradigm-shifting T-Rex attack. We can talk all we like about the slow ratcheting of tension; the rain, the goat, the goggles, the claw on the fence, “He left us, he left us”, and – of course, of course, of course, the ripples in the water. But as the beast snaps (that sound!) through the fence, and strides purposely onto the road, Ian Malcolm – famous naysayer and doom-monger – regrets so many of his life choices.
“Clever girl.”: probably the film’s most famous line? We’ve been told all along how smart the raptors are (it’s basically the first thing Alan Grant does); they open doors, they move in packs, they solve puzzles. So when they get the drop on park warden bloke Muldoon, it’s little surprise, but he still has the decency to celebrate their success.
“I think we’re back in business!”: Jurassic Park is a sci-fi adventure movie, sure, but it’s also a horror film. There are moments of sustained tension and outright terror, and then there are also jump-scares; and this is the daddy of them all. Ellie has a moment’s reprieve before a bloody big raptor head smashes through the wall behind her. Famously made Princess Diana jump in the cinema.
“Unless they figure out how to open doors…”: another of the showcase CGI scenes, the fidelity of the raptors as they stalk the children in the kitchen was something unprecedented back in ’93. It’s another masterclass from Spielberg, as we have multiple moments of ramping fear, culminating in the frantic dash into the walk-in freezer. And don’t forget, the sequence really begins with that excellent shot of the jelly on Lex’s spoon!
“I’m gonna run you over when I come back down.”: pour one out for Dennis Nedry, the big slobby oaf who’s greed got everyone eaten. Including himself! In a rather gorgeously wet scene full of mud and rain, he insults a tiny, weird dinosaur before it opens a huge, terrifying neck fan and spits big horrid gobs of phlegm at him. It’s a really creepy scene with a freaky jump-scare at the end. In the book he gets disembowelled! It’s well rad.
“Shoot her!”: the opening scene is, I think, rather undersung. It’s a combination of the misty, sweaty jungle setting, and the businesslike routine of the workers. “Loading team, step away.” It all seems mundane and peaceful until the raptor attacks and we instantly see the power of this beast, even if we don’t see the beast itself. Really spooky.
“Welcome to Jurassic Park.”: so many of these moments are terrifying, but the film also has a great sense of awe and wonder. Yes, part of that is the characters seeing dinosaurs for the first time; but it’s also the wonder of this new CG technology that is able to render the animals in such stunning fidelity, like nothing we’d ever seen before. The way the first brachiosaur is revealed, looming gracefully high up in the frame, merrily chewing on a tree, is stunning.
“You didn’t say the magic word!”: I’ve already singled out Nedry for his wet, messy demise, but he’s a great character throughout, his greedy brand of sarcasm undercutting the serious technical wizardry. Arnold trying to break into his code (whist chewing through dozens of cigarettes) culminates in the cheesy animation of Nedry wagging his finger.
“I’ve decided not to endorse your park.”: this final line is a nice zinger as we see our heroes on their way to freedom and safety, but really it represents the entire denouement of the film. Originally, Hammond was going to come in and kill the raptor with a bazooka; but once they knew they could really deliver on these CGI dinosaurs, we have a return to the film’s true hero – the T-Rex (hey, she ate a lawyer; as Weird Al said, it proves they’re really not all bad!). bursting in out of nowhere like the Close Encounters mothership (seriously, how did no one notice her?) she bites a raptor mid-leap, tosses the other one through a skeleton, and gives a big ol’ roar.
“That is one big pile of shit.”: yes, another moment of levity among all the running and screaming and being digested. They stop to find out what’s wrong with a poorly triceratops, and it results in Malcolm staring at, frankly, an enormous bit of poo. It’s funny.
Really disappointed I couldn’t find room for the dinner conversation (“Condors!”), the intro to Nedry (“Dodgson!”), Lex hacking the park (“Unix!”), or sadly anything from Mr. DNA. But what do you expect? It’s a fantastic film.
2 notes
·
View notes
Text
It's been a bit. I mainly listen to music on my commutes to and from school, so I didn't listen to as much over the summer, but here is my list for summer, June through August
The Soul Children - The Soul Children - Soul
Remain in Light - Talking Heads (as preformed by a mostly cover band with the guitarist from talking heads I saw them live and they did really good also I have already listened to the original) - Post Punk
Animals - Pink Floyd (Covered by Colonial Claypool Flying Frog Brigade also already heard the original same story as previous one) - Prog Rock
Mouth to Mouth - Lipps Inc - Disco
PetroDragonic Apocalypse; or, Dawn of Eternal Night: An Annihilation of Planet Earth and the Beginning of Merciless Damnation - King Gizzard & The Lizard Wizard - Doom-ish Prog Metal. Basically, King Gizzard metal, it's very much them and you can tell (in a good way obviously)
Apollo XXI - Steve Lacy - Alternative R&B
Star Booty - Bitch Magnet - Like early early math rock, punk or grunge sounding almost
Light Of Worlds - Kool & The Gang - Funk
My Sound (1993-2004) - Dillininja - Jungle
G I R L - Pharrell Williams - R&B&Pop
The Origin Of My Depression - Uboa - Experimental Stuff I don't even know
Fresh - Sly & The Family Stone - Funk
Incunabula - Autechre - IDM
Phocus - VHS Head - Music made from VHS tapes (weird electronic shit)
Zen, or the Means Without Ends - Heaven Pierce Her - Yeah, this guy listens to Swans, how could you tell? But fr good music a lot of droning with some chill guitar
Isolation - Kali Uchis - R&B
To Smithereens - Gay Beast - Very Noisy Math Rock
Songs EP (Live In Chicago) - Piglet - Math Rock
Ascenseur pour l'échafaud - Miles Davis - Modal Jazz
Vespertine - Björk - Experimental Pop
The Beggar - Swans - Experimental Rock
Songs For The Terrestrially Challenged - Speaking Canaries - Math Rock
Grievances and Dead Malls - Nero's Day At Disneyland - Experimental Breakcore Shit
From Rotting Fantasylands - Nero's Day At Disneyland - Experimental Breakcore once more
Dream of an Endless Ocean - David Szymanski - Experimental Electronic with a lot of Classical Elements
Don Caballero 2 - Don Caballero - I've already listened to it also math rock
10,000 gecs - 1000 gecs - If you havent listen to the album you wont believe me but. Hyperpop with a shocking amount of nu metal of all things. It goes hard though. Also ska sometimes
Locked Into Phantasy - Laura Bousfield - Experimental Breakcore stuff
When The Pawn - Fiona Apple - Some Kind of Pop and/or Alternative
Songs From The Big Chair - Tears For Fears - Pop of the very 80s variety
Attention Shoppers - Nero's Day At Disneyland - Experimental Breakcore
It Was Written - Nas - Gangsta Rap
A Go Go - John Scofield - Instrumental Funk
Surrender - The Chemical Brothers - Dance (which is one of the least creative genre names)
Ashes of the Wake - Lamb of God - Groove Metal
My War - Black Flag - Hardcore Punk with a bit of Mathy stuff
Anthology - Colour - Midwest Emo
The Blues - BB King - Blues
Celebrity Skin - Hole - Grunge
Something Else (Rudy Van Gelder Edition) - Cannonball Adderley - Hard Bop
Songs In The Key Of Life - Stevie Wonder - RnB
100 One Says - 100 Onces - Mathy Rocky
Superunknown - Soundgarden - Grunge
"Bird" Symbols - Charlie Parker - Bop
Clifford Brown and Max Roach - Clifford Brown and Max Roach Quintet - Bop
Light as a Feather - Chick Corea and Return Forever - Jazz Fusion (re-listening)
Quebec - Ween - Experimental Psych Rock
3 notes
·
View notes
Text
Hello there, welcome to my page!
I'm into a lot of fandoms and would like to make g/t content about them because the internet needs more g/t.
Fandoms I'm currently in:
- Pressure (PLEASE SEND ME SEBASTIAN REQUESTS! I LOVE THIS DAMN FISH!!!)
- Minecraft
- Genshin Impact
- Attack on Titan
- My Singing Monsters
- Transformers
- DOOM
- Skibidi Toilet (Shut up, I just like the object heads, okay? >:T)
- Subnautica (OG and BZ)
- Bendy and the Ink Machine/Dark Revival
- Kaiju No.8 (Kafka🥺)
Rules:
What I will do:
Canon Character x Reader (Child reader will only be platonic.)
Sfw vore and G/T (Vore would ONLY be Genshin, anime related fandoms, Pressure.)
Angst, Fluff and a lot of Wholesome stuff
Might do some fearplay here and there😊
What I won't do (Please, NEVER request me any of these down below...):
Nsfw
Smut and Lemon
Pedophilia, Zoophilia... Just any of these kinds of -philia... No, just no...
In other words, if it makes me uncomfortable then I won't do it.
————————————————————
————————————————————
#genshin g/t#genshin impact g/t#attack on titan#aot#demon slayer#kimetsu no yaiba#genshin impact#my singing monsters#msm#transformers#doom eternal#doom 2016#doom 1993#skibidi toilet#bendy and the ink machine#bendy and the dark revival#roblox#pressure#kaiju no. 8
33 notes
·
View notes
Text
On AEW's "Four Pillars"
I understand the metaphor is that they're a solid foundation for the future... but if it were me I'd avoid comparisons to the Four Pillars of Heaven and quickly append a descriptive word... The Four Pillars of... something. Point is, MJF said 'Pillar' a lot on Wednesday and I wanted to take a look at the boys individually and as a set. Threw in my 40 point scale for my own amusement, 30+ usually rounds out to 'main event talent.'
Notably, it's extremely obvious who this group is: under 30, in AEW from day 1, have shown star quality and have paired with a legend or two along the way. It doesn't include other good but less prominent prospects like Dante & Darius Martin, Lee Johnson, Isiah Kassidy & Marq Quen, Brock Anderson, Wheeler Yuta, Lee Moriarty, Fuego Del Sol, Sonny Kiss, Brian Pillman Jr or uh... the Gunns. Daniel Garcia has a long future knocking down pillars, most likely.
Darby Allin (b. 1993 - 28) Work-7 Mic-6 Look-8 X-10 (31)
Darby Allin is neither the best wrestler nor the best talker, his look is the kind of thing that isn't 'cool' per se (many are dubious about the skinny hot topic skate geek when they first see him,) yet he commands attention and possesses an unmistakable aura. He also loves any and all dangerous looking spots. It's a tired comparison, but factor in his brooding sex appeal and he really is the natural heir to the charismatic enigma. They've paired him with Sting, he was CM Punk's first match in 7 years, he's held the TNT title, and in no small part due to his penchant for risk and flair for the dramatic in his self-shot artistic promos, he's been part of several memorable moments already.
He fights from underneath pretty much as a rule, taking a beating due to his size and powering through on daring -- he's definitely found a niche inside the ring. His pace is incredible, and he bumps like he means it. I think my biggest knock against Darby's long-term prospects are the alleged skeletons in his closet -- whether pro wrestling is doomed to always be 'carny shit' or not, it's in everybody's best interests to root out real life heels. They've confronted Sammy G's immature sense of humour, I don't know how closely they want to examine some of the things you hear about Darby -- but shouldn't they?
Sammy Guevara (b. 1993 - 28) Work-8 Mic-7 Look-7 X-8 (30)
'The Spanish God' does indeed have formidable gifts -- a face just straddling the line between cute and punchable atop a body that can match pace with the likes of Flamita, Rey Horus, Mike Bailey and even Ricochet back in 2017. Chris Jericho took one look at Sammy G and climbed right aboard -- it's been a long winding path (aforementioned suspension for gross 'jokes' included) through the Inner Circle and the Pinnacle and all that, but Sammy's star has risen steadily throughout, to the point where he can beat Miro and I'm not even upset about it really that much at all (it's fine.)
He's the best in-ring performer of this quartet right now, and he's arguably the most well-rounded. He's turned as a character once already, I think he's comfortable playing most sides in most angles. He's yet to have a big solo feud (Shawn Spears?) or stand-out match in AEW, probably his best match to-date was against MJF earlier this year. He's now the mid-card champion, so now's the time.
Maxwell Jacob Friedman 'MJF' (b 1996 - 25) Work-6 Mic-10 Look-8 X-8 -- 33
Any appraisal of MJF starts with his stand-out gift, which is praised so often people even start to levy complaints about him being overrated -- that's how you know MJF is great on the stick. Wrestling is very simple actually. Heat is heat, and cheap heat is different from lazy heat, and the clichés are clichés for a reason -- the boy's a maestro and there's no such thing as a wrestler 'peaking' on their promos in their mid 20s. He'll keep talking and finding ways to piss off everyone.
His ring work is of the old-school heel variety, which usually requires him to work to try and deny the crowd the exciting maneuvers of his opponent. Bobby Roode's NXT run is probably the blueprint for just how well this can still work, but at the time Bobby had been at it for close to twenty years (but hey, developmental...) He has a great look for where he's at -- big and strong enough to be a threat worth taking seriously and a smug mug that ranks pretty high on the all-time list.
I kind of want to quibble with Jericho as-Mentor: did MJF need a sparring partner on the mic considering he was already ascendant, and did Sammy need to be tagging with a middle-aged man to shine in the ring? He did accentuate their strengths, though, it made for good TV.
'Jungle Boy' Jack Perry (b 1997 - 24) Work-8 Mic-5 Look-8 X-9 -- 30
Youngest and most literally baby-faced, Jungle Boy is very over, on the strength of his boyish good looks, his fun tag team, his great theme song, and as of late, his being the Robin to Christian Cage's older version of Spiderman. One might expect the son of TV's Dylan McKay to be a little more natural on the mic, but standing next to an all-time snarker like Christian should help. He's still boyishly skinny but he's taller than Adam Cole and I'm not convinced he couldn't basically be Omega-sized in a decade.
His work suits his size and gimmick, he's daring and speedy, he's no technician but 'the snare trap' and other holds are laid in convincingly. Like the rest of the group he has presence, and he's generally booked well -- AEW has made sure to get him his reps and he continues to improve and is almost always adjacent to serious talent. That said, in his current form he's maybe plateauing. What's it going to take to turn this Jungle Boy into a Jungle Man, you know?
#aew#mjf#jungle boy#darby allin#sammy guevara#...curious if anybody cares for this kind of thing#not that apathy will deter me from doing the 4 pillars of the women's division later#wrestling reviews
15 notes
·
View notes
Text
Summoning
Music Style: Epic/Atmospheric Black Metal
Country of Origin: Austria
Years Active: 1993 - Present
Current Members: Silenius (Michael Gregor) - Bass, Vocals, Keyboards; Protector (Richard Lederer) - Guitars, Vocals, Keyboards
Discography: Lugburz (1995) Minas Morgul (1995) Dol Guldur (1997) Stronghold (1999) Let Mortal Heroes Sing Your Fame (2001) Oath Bound (2006) Old Mornings Dawn (2013) With Doom We Come (2018)
Website: https://label.napalmrecords.com/summoning
Youtube: https://www.youtube.com/channel/UC8jG23nTKgkWYfRt8cN2M-g/featured
My Thoughts: In my search for Tolkien Metal, I noticed that there are two main paths one can follow: Power Metal and Black Metal. While not every band that draws from Tolkien will fall in those two categories, and there are lots of variations within those subgenres, most Tolkien Metal falls under one or the other. And if Blind Guardian is the flagship for Tolkien Power Metal, then Summoning is the flagship for Tolkien Black Metal.
Summoning is great at evoking mood and a sense of place purely through instrumentation (they are considered ‘atmospheric black metal’ for a reason). I personally enjoy the contrast between the more melodic/epic instruments and the harsh vocals. My personal favorite album from this band is Oath Bound. It has many of my favorite songs, including “Mirdautas Vras", which is Sauron bragging about how evil he is in Black Speech, and “Land of the Dead”, which starts as a typical Summoning song, but little over halfway through has this absolutely beautiful choral section that keeps coming back throughout the rest of the song. If you don’t listen to any other Summoning songs, please listen to “Land of the Dead”.
9 notes
·
View notes
Text
Historical Context, by Atun-Shei Films
(not mine, youtuber’s history lesson in the community tab, link at the bottom)
I will never make a video about this (I really should have included it in the black Confederates episode of Checkmate Lincolnites, but oh well) so a mini-essay will have to do.
I recently came across a pro-Confederate Facebook post featuring this quote from Confederate major general Patrick Cleburne, written on January 2, 1864:
"It is said slavery is all we are fighting for, and if we give it up we give up all. Even if this were true, which we deny, slavery is not all our enemies are fighting for. It is merely the pretense to establish sectional superiority and a more centralized form of government, and to deprive us of our rights and liberties."
Now, I'm not going to share the post itself, as that would inevitably lead to doxxing and bullying. However, this is a teachable moment, a classic example of the beloved Lost Causer past-time of divorcing quotes from their important contexts.
You need to keep a couple things in mind when considering a historical quote. Who is the speaker? Who are they talking to? Do they have an objective in mind? What events surrounding this person, if any, have inspired them to say this particular thing at this particular time?
Quotes by themselves are useless in historical education and can often be misleading. I see y'all making this mistake with the Cornerstone Speech all the time – it's not the mic drop you think it is. You can't just shove it in someone's face and call it a day. If you really want to change minds, you need to present it in its proper context and alongside other evidence. Only then can you craft a complete and compelling argument.
Now as it happens, Alexander Stephens was totally sincere when he called late 18th century notions of racial equality "wrong," and he spoke for the overwhelming majority of Confederate true believers in the Spring of 1861 when he said that "our new government is founded on exactly the opposite ideas; its foundations are laid, its cornerstone rests, upon the great truth that the [black man] is not equal to the white man; that slavery, subordination to the superior race, is his natural and normal condition." But without context, how would I know that? When making an argument, the onus of proof is on you.
This particular pro-Confederate post presented the Cleburne quote by itself in meme format without any context whatsoever, so allow me to provide one. At first glance, it seems like Cleburne is espousing anti-authoritarian values. It seems like he is declaring, clearly and definitively, that the Southern states did not secede to preserve slavery, but rather to uphold their regional self-determination.
This quote is from a letter Cleburne wrote to Joseph E. Johnston, his commanding officer in the Army of Tennessee, proposing that the Confederate government emancipate and arm the South's enslaved men to bolster the thinning ranks of the army. [1] As you may remember from Checkmate Lincolnites, this proposal was met with shock and horror from the Confederate leadership, who quickly rejected it.
But Cleburne saw further than them. He believed – correctly – that unless something drastic was done, the Confederacy was doomed to destruction. As he writes in the proposal, "Instead of standing defiantly on the borders of our territory or harassing those of the enemy, we are hemmed in to-day into less than two-thirds of it, and still the enemy menacingly confronts us at every point with superior forces."
"If this state continues much longer we must be subjugated," he continues. Defeat would inevitably lead to "the loss of all we now hold most sacred — slaves and all other personal property, lands, homesteads, liberty, justice, safety, pride, manhood."
As Claiborne sat down to write this proposal, exactly one year had passed since the Lincoln issued the Emancipation Proclamation. Though a huge risk, and deeply unpopular with many Northern whites, the edict proved to be a political masterstroke that crippled the Confederate States' ability to wage war.
Namely, it mobilized the growing abolitionist movement in the North, encouraged resistance among Southern blacks, and stoked the ever-present white Southern paranoia of servile insurrection. As Cleburne says of the planter class, "The fear of their slaves is continually haunting them."
It sparked the formation of the United States Colored Troops and the first mass military enlistment of black men in American history. Their contribution to the United States' war effort was already making a difference in 1863, and it would eventually prove invaluable to victory. Lincoln himself mused late the following year that "any different policy in regard to the colored man deprives us of his help, and this is more than we can bear . . . Keep it and you can save the Union. Throw it away, and the Union goes with it." [2]
Lincoln also damaged the Confederate government's relationship with the staunchly abolitionist British Empire. "Our country has already some friends in England," Cleburne writes, "but they cannot assist us without helping slavery, and to do this would be in conflict with their policy for the last quarter of a century."
Cleburne had come to believe that slavery, though "one of our chief sources of strength at the commencement of the war," had become a military "weakness" and a political liability.
He fretted in particular about the Confederate army's dim prospects for future recruitment as the war dragged on. "Our single source of supply is that portion of our white men fit for duty and not now in the ranks," whereas "the President of the United States announces that 'he has already in training an army of 100,000 [black men] as good as any troops,' and every fresh raid he makes and new slice of territory he wrests from us will add to this force."
He emphasizes twice that his issue with slavery was strictly from "a military point of view," to placate Johnston and his fellow officers, who were – like just about all Confederates – rabidly pro-slavery.
Anticipating fierce resistance from his colleagues, Cleburne addresses some common Confederate criticisms of his unusual and radical proposal. "It is said Republicanism cannot exist without the institution [of slavery]," but, he argues, emancipation is preferable to defeat. "We prefer any form of government of which the Southern people may have the molding, to one forced upon us by a conqueror."
Here's where our quote shows up: in the litany of anticipated criticisms. "It is said" – not by Yankee propagandists, but by Confederates themselves – "slavery is all we are fighting for, and if we give it up we give up all."
But Cleburne denies that slavery is his entire reason for fighting, as well he might. Political beliefs in the 1860s were as complex, intricate, and multifaceted as they are today. The moral issue of slavery was tied into legislative issues like state's rights and economic issues like free trade. Confederate soldiers fought for all of those causes, and for more lofty ideals like independence and resistance to invasion. But make no mistake: slavery was the lynchpin of the entire Confederate philosophy.
And Cleburne knew it. He was not a native Southerner, but an Irish immigrant, and sometimes outsiders have the clearest perspectives. He saw what his colleagues could not – the Confederacy was about to crash and burn, and arming slaves was perhaps the only way to avert total annihilation. He knew that it was not what the Confederate leadership wanted to hear, but nonetheless, "no objection ought to outweigh it which is not weightier than independence."
And yet – they rejected it anyway. They even suppressed the knowledge of it. [3]
Cleburne is not speaking for the Confederacy in this quote. He's demonstrating his uniqueness within that system, his break from the party line. So ironically, this quote does far more to reinforce the Confederacy's bone-deep commitment to slavery than to dispel it.
~REFERENCES~ [1] "Patrick Cleburne's Proposal to Arm Slaves," American Battlefield Trust https://www.battlefields.org/learn/pr...
[2] G. S. Borritt. Why the Confederacy Lost (1993). Oxford University Press, Page 137
[3] Kevin Levin. Searching for Black Confederates (2019). UNC Press, Page 57-60
https://www.youtube.com/post/UgyVM9ZsMb_cNkVvdvB4AaABCQ
#history#us history#us civil war#slavery#american slavery#it was about slavery#civil war was about slavery#long post#from youtube#atun shei films#context#it matters#anti csa#patrick cleburn
3 notes
·
View notes
Text
What about the rest of the Forgotten Sonic Characters?
With Sonic Mania Plus comes two returning characters, Mighty and Ray! After 20+ years they’ve finally made their comeback ever since their debut in the segasonic arcade game! Even the Hooligans have made a semi-cameo appearance in the form of the Heavy Magician’s illusions in Mirage Saloon Zone! Since Mania is a celebration of every Sonic game ever it was nice to experience these old characters revitalized back to life!
But with the revitalization of old characters, what does that say about the state of the rest of the forgotten sonic characters? Will they ever see the light of day again? Do some have a more chance of appearing again? Or are they doomed to obscurity? Let’s review the list, starting from when they were introduced and their last major appearance! Starting with:
Sonic CD’s Rosy the Rascal (1993) Latest appearance Sonic R (1996)
I’m sure all of us were disappointed when she wasn’t playable in mania plus. But! With her appearance in the christmas special, she may become playable in the next sonic mania game! Or at least a cameo other than an Amy Doll.
Sonic Triple Trouble’s Fang the Sniper (1994), last appearance Sonic Fighters (1996) and you know what? Let’s throw in Bean and Bark (1996), last appearance Fighters Megamix (1996)
“Hey! What’s the big idea! We just saw them in Mania! You even said they were in Mania!” Well that’s where you’re kinda wrong kid. I said semi-cameo. The hooligans did not actually appear in Sonic Mania, at least not in their actual forms. Right, remember those three were just illusions by the magician. While those were references sure, those aren’t actually the hooligans. While their appearance in a next game like mania is less likely (given they were mirage saloon’s gimmick, and they’ve already had their representation) I wouldn’t be surprised if there wasn’t at least one reference to them in the near future.
Next up! Knuckle’s Chaotix’s Chaotix! (1995) with Espio’s last appearance in the Sonic Fighters (1996)
“Uh hey, what gives? The Chaotix crew have already appeared in modern games, they were just in Forces and Vector is in TSR! what are you on?” Well what I’m on, you see reader, is on Iizuka’s bullshit! You see since their first modern appearance on Sonic Heroes, Takashi Iizuka has stated on record that the modern chaotix crew is not the same characters as the ones in the 32x game. You see when development on the chaotix game was shifted from sonic team to another developer, the story hadn’t been written yet. Same with the characters characterization. That’s why you have a sophisticated 16 year old Charmy. Hot headed detective Espio. Pacifist nomad Mighty. God-fearing, music-loving Vector! While some of the character traits were carried over (like charmy being the glue that held the chaotix together, mighty is still a pacifist in mania, vector still has his headphones, while espio’s detective shtick got applied to the whole crew), they were basically new characters. Even though the chaotix game was viewed noncanon for years, with countless references to it in sonic mania, it seems that sega is much more willing to accept the chaotix as it was. It is very likely that this may get retconned (given how bullshit some of Iizuka’s statements on plotline are), they even might actually cameo in the next mania game if ever!
Tails Skypatrol’s Witchcarters! (1995)
Finally some actual forgotten characters! Bet you didn’t know they exist huh! Well you probably do if you’re reading this list, but i digress. Introducing the witchcarters, Carrotia the Rabbit, Fockewulf the Wolf, Bearenger the Bear and Witchcarter. These characters served as one-off antagonists and henchmen in this spinoff game, where they were left ignored for around 20 years until Archie Sonic’s Eggman’s Dozen arc where they were given redesigns to fit the modern era. They are the less iconic of the two groups of antagonists that Tails has had to fight. But they are very likely to appear in the next mania-like game.
Tails Adventure’s Battle Armada (1995)
Oof another Game Gear title but one that’s more memorable than skypatrol! Along with a metroid-style gameplay, we are introduced to the battle armada! Speedy, his father and Dr. Fukurov are a few of the notable casts introduced here! For around 20 years they were ignored until Archie Sonic (again). They are given a much bigger role compared to the witchcarters! The idea of Speedy as a rival to Tails like metal sonic is to sonic, is such an interesting concept to me! they have a greater chance of appearing in the next mania like game as compared to skypatrol!
Sonic the Fighter’s Honey the Cat! (1996)
Yeahhh, ok let’s be blunt. I love honey the cat. But she probably won’t appear in a game any time soon. Here’s why: She’s basically the mobian version of an already existing character (candy from fighting vipers). She’s a hacked character in the arcade version, removed from the gcn port and an easter egg in the latest port. She was only limited to cameos in the comic before finally debuting properly in the sonic the fighters arc in archie sonic. While Sega has definitely been more lenient with her, unless there’s another fighting game that will come out, honey won’t be appearing any time soon. (and if she does I really hope they use the rest of the fighting vipers cast too, Pane the Boar exists now! and it’s not like anyone’s using the IP! I’d like it if they just,,,, retooled fighting vipers and it’s characters for a sonic fighting game spinoff without sonic characters haha)
Sonic R’s Metal Knuckles and Tails Doll (1996)
Sonic R introduced the counterfeit counterparts to the other 2/3s of team hero. Metal Knuckles and Tails Doll. While I bet they were only created to fill out the roster, we can’t deny that their designs are cool. I don’t want to rule them out because they’re 3d characters since Bean and Bark made 2d appearances in mania, but it’s a mystery on what kind of role they’ll fulfill. Metal Sonic’s first appearance in CD was explicitly clear that he was your rival, someone to beat. These two’s appearances are kinda shoehorned as someone you have to race with but there’s no backstory. Unless there’s racing challenge in the next mania game or these characters are retooled to being a miniboss, they probably won’t appear in a major role in the next mania game, if they ever appear it’d probably be as a background cameo. (which is a shame!)
Sonic Adventure DX and Adventure 2 Battle’s Tikal and Chaos! (1999) latest appearance Tikal-Sonic Runners (2015) Chaos(illusion)-Forces (2017)
Finally we’re out of the classic era and into the adventure era! The adventure era is regarded by a lot as either a. a transitional era between classic to modern sonic, or as a part of the modern sonic era. either way this is where tikal and chaos’s first and playable appearances were made. Now this is a weird case since Chaos came from the Master Emerald and Tikal is a ghost. In their ending you can see them hanging with the chao. Ever since then they’ve been MIA. While I thought they went back into the emerald, it seems that it’s actually questionable what happened to their fate. Will we ever get to see them again? Well this is where things get pretty dicey here on out. These characters don’t have “Classic” immunity, meaning they dont have the possibility to appear in the next mania-like game since they aren’t classic. Unless we have another storyline regarding the echidna colony (unlikely due to penders) then we probably wont see tikal and chaos in a major way any time soon.
Sonic Shuffle’s Void and Lumina (2000)
With character designs looking more akin to NiGHTS into Dreams than a sonic characters, void and lumina are the more different looking characters. Opting for a more fairy look instead. Sonic Shuffle is a board game somewhat akin to mario party. These characters were one-off characters, and i guess that’s it. Unless sega makes another board game using the mainline sonic universe (not storybook sonic) then we won’t see these two again anytime soon.
Sonic Hero/Advance 3/Battle’s Vanilla and Chocola and Emerl/G-merl (2003-2004)
Woof, that’s a lot of characters. So let’s tackle them one by one shall we? Vanilla is Cream’s mother. Kidnapped ala princess peach style in the advance games, she is cream’s driving force to join sonic’s team into taking eggman down. Likewise, Chocola is Cheese’s brother. These two chao are pets of Cream. Chocola is Cream’s driving force to join team Amy into taking down eggman in sonic heroes. Emerl was a robot that died in Sonic Battle and Gemerl is the reconstructed gizoid from emerl’s remains, after the events of advance 3, gemerl lives with cream and vanilla, often portrayed in the comics as the bodyguard for the two. So how likely are they to appear? Well not anytime soon by the looks of it. They only appear if Cream has a heavy role in the story, and with each passing installment cream has been getting lesser roles. I like to think of Cream as the “next sonic”. She has the drive and the heart to become the succeeding hero. I’d love for her to get her own series of games where she is the hero. But unless she gets more roles or she gets her own spinoffs (not likely), these three wont appear anytime soon.
Sonic Riders (2006) latest appearance for storm-Sonic Free Riders (2010) for Jet and Wave-Olympics (2020)
Sonic Riders introduced three babylon rogues. Jet was introduced as Sonic’s rival when it came to races, a title loosely held by metal and shadow (metal was created to be sonic’s rival at everything and shadow was conceptualized as being an antithesis to sonic, jet is the first to be his rival in speed only). Given the nature of these games it’s actually a surprise as to why they didn’t appear in team sonic racing, or in their two previous racing games. Jet and Wave appeared in the olympics 2020 recently but storm has been mia lately. When the next racing game does come out and when they expand their roster we might see the babylon rogues debut in some sweet rides!
Sonic 06′s Elise
Unless it’s in a remake Elise has no chance of returning back due to the whole nature of 06 (and it’s storyline)
Sonic and the Secret Rings and the Black Knight’s Shahra, Merlinus, Caliburn
Not likely given that they are one-off characters in a storybook.
Sonic Rush Adventure’s Eggman Nega and Marine (2007)
I’d really love for Marine to appear again. Eggman Nega appeared in Rivals, he even appears in the olympic games, why can’t marine appear again? Sadly, unless we get a game that involves the sol dimension, these two are out of the question.
Sonic Chronicles’s entire cast (2008)
Haha. no. Most well-known as the first rpg-like game that involves the sonic characters. This game introduces Shade along with other characters. However due to the Penders lawsuit, these characters are now off limits, even to sega. this may also be the reason why we have not seen gemerl again.
Sonic Unleashed’s Lah and Chip (2008)
Chip is the Light Gaia and Lah was made for the special. We probably won’t see these characters again despite having the best writing so far.
Sonic Colors’s Yacker (2010)
Yacker didn’t fare well compared to the rest of his wisp friends. and honestly? I don’t feel too bad. while he may appear if sonic ever does need a flagship representation for the wisps, i doubt he’ll have another big role like in colors.
Sonic Lost World’s Zeti (2013)
Cause let’s face it, only Zavok and Zazz are in the limelight recently. The Zeti are a very polarizing addition to the sonic cast. they don’t have the same rep as the wisps, yet they’re designs are a bit too unique to just be left behind again. What sega’s doing now though is a bit disappointing. Half ass shoe horns into plots. Well at least for TSR, which is a racing game spin-off. We also saw this in forces (along side chaos and shadow of all people). I just hope this isn’t a trend that persists. Either make a proper plot or don’t include the character at all sega. as to when we’ll see them again, that is up to sega. this is a bit of a cloudy are cause sega doesn’t seem to be afraid to use them, but for some reason they arent too confident either.
Sonic Boom’s Sticks.(2014)
Unless There’s another boom game or Sticks is redesigned to modern standards as opposed to boom standards, we’ll probably not see her again. which is disappointing.
Sonic Forces’s Infinite and OC character (2017)
They aren’t really forgotten since it’s only been 2 years. But infinite’s basically been forgotten already! He has no appearances in other games outside forces. Not even in team sonic racing, you’d think he’d be a shoe in, but he isnt! You’d think the make your own avatar would be something that’d be implemented from everygame onward (ngl it was the only good thing about forces) but it’s also isnt seen in tsr. which seems like wasted opportunities!
#fang the sniper#nack the weasel#Bean the Dynamite#Bark the Polar Bear#vector the crocodile#Espio the Chameleon#charmy the bee#bearenger the bear#carrotia the rabbit#focke wulf the wolf#witchcarter#speedy#battle armada#honey the cat#tikal the echidna#chaos#tails doll#metal knuckles#vanilla the rabbit#gemerl#chocola#zeti#void#lumina flowlight#infinite the jackal#gadget the wolf#sonic mania
46 notes
·
View notes
Photo
That Time Forgot: Buick Wildcat
Okay, who would have thought that there was a possibility for you to say “Buick” and “McLaren” in the same sentence? Well, this is quite possibly the only time you can do that. Today, let’s talk a bit about the nameplate’s history... as well as the casting, in today’s installment of That Time Forgot.
Before we talk about the Wildcat in question, let’s go back in time to 1953, when the first Wildcat was introduced.
Enter the 1953 Buick Wildcat, internally known as the Wildcat I. Designed under the direction of GM head of design Harley Earl, the Wildcat was designed for the sole purpose to see if it was feasible to put a fiberglass bodyshell on top of a car. The car was powered by a 322 ci (5.3L) Nailhead V8 producing 188 horsepower. With a wraparound windshield with a 60° slope, the Wildcat successfully influenced the design for Buick’s 1954 cars. After its tour of the auto show circuit complete, the Wildcat was sentenced to the scrapper, but was saved and is now in the hands of Joe Bortz.
1954 came another Wildcat, internally dubbed the Wildcat II. Also designed under the direction of Earl, this Wildcat was a styling exercise, combining modern elements with classic styling from years gone past; it was because of this that Buick billed the Wildcat as an “American Adventure in Tomorrow's Design”. The car was powered by a 322 ci (5.3L) Buick Nailhead V8, producing 220 horsepower, and was specifically made to be fully functional (like the Wildcat I) in the event that GM chief Harlow Curtice wanted one for his own.
In 1955, another Wildcat came, internally designated... guess what. Also designed by Earl, the Wildcat III was probably the most conservative of the three 1950s Wildcat concepts, although it was quite a bit larger and longer than the previous two Wildcats. Powered by the same 322 ci (5.3L) Buick Nailhead V8 as the previous two Wildcats, the Wildcat III’s V8 was boosted to 280 horsepower with the help of a quad-carburetor setup. Nicknamed the “Toy Convertible”, the Wildcat featured a Twin Turbine Dynaflow 2-speed automatic transmission and featured rear seats, allowing for four passengers. After its tour of the auto show circuit was over, the Wildcat III was ordered to be junked; however, nobody really knows for sure what happened to it.
The Wildcat name was subsequently used for a number of full-sized automobiles produced by Buick from 1963 to 1970, but that’s not what you’re here for. Instead, you’re here for this: the 1985 Buick Wildcat.
Some fifteen or so years after production of the Wildcat had halted, Buick came out with another Wildcat. This was a futuristic sports car featuring swoopy lines and a canopy which tilted forward for entrance and exit.
Two prototypes were produced; one non-running one that was showcased at SEMA in 1985, and one fully-functional prototype. The running prototype was powered by an experimental 3.8L Buick V6 built by McLaren Engines (no relation to the British car company).
This exposed engine generated some 360 horsepower at 7,000 rpm and 398 lbf⋅ft (540 Nm) of torque. However, given the hardware this thing ran on, performance for the Wildcat... wasn’t that spectacular, with 0-60 mph (0-96 km/h) taking 8.6 seconds. The top speed for the Wildcat was actually electronically restricted to 70 mph (112 km/h); top speed figures for an unrestricted Wildcat remain unknown.
The body was made of fiberglass and carbon fiber, and the car featured a 4-speed transmission which could be manually shifted.
The interior of the Wildcat was highly advanced for its time, with a screen in the middle of the steering wheel display information such as G-force, torque, oil pressure and a compass. To add to that, a heads-up display was also added, displaying speed, mileage and gear selection on the glass canopy.
Despite all the high-tech features, all the Wildcats remained prototypes, and they now sit among a sea of other cars at the GM Heritage Center, with the exception of the Wildcat III (which isn’t there).
The Wildcat got its big break in the film industry when it appeared briefly in a scene in the 1993 film Demolition Man alongside some seventeen other GM concepts.
Okay, now that we’ve gotten all of this info out of the way, let’s get to the real reason why you’re here.
This casting was introduced in 1993 in the Demolition Man series, alongside eight other cars that appeared in the movie: these were the Oldsmobile Aurora, Olds 442 W-30, GM Ultralite, GM Lean Machine, Corvette Stingray III, Pontiac Salsa, Pontiac Banshee and the Chevrolet ACC Camaro (’93 Camaro), intended to represent the Chevrolet California IROC Camaro Concept. This casting was designed by Larry Wood. Something notable about the Wildcat was the “canopy” piece, which was simply the car’s body painted black.
This casting has a metal base and plastic body. Early versions will say "'93 WARNER” instead of “'93 MATTEL INC” and “BUICK WILDCAT”; I presume the license with Warner Bros. had expired, so they just scrubbed off the Warner licensing information and put their own on.
The Wildcat enjoyed the privilege of being released quite often when it was in the lineup, but ultimately this casting was doomed in 2005 for one reason, and one reason only: the Final Run Series.
The Final Run Series started in 1999 and acted as what I would consider a very glorified funeral for a casting; Hot Wheels would give these cars special tires and paint, in exchange for vowing to never produce them again by cutting their toolings in half. The Wildcat was unfortunately one of the castings to fall victim to the Final Run Series, and although it might not have been one of the more popular castings to retire that year, it was still retired regardless. As the final batch of cars to be Final Run, having been introduced in the 2005 series, the Wildcat will never be seen again in the Hot Wheels lineup unless a new tool and die is created for it, which I believe is highly unlikely. The Final Run Series itself has been on hiatus since 2006. In total, the Wildcat had eighteen releases.
Of note is that the image above says that Tropicool (Good Humor Truck) is one of the castings that was intended to be Final Run; the actual casting that was Final Run was the Treadator, while Tropicool remains in the lineup to this day.
Always on the receiving end of very loud decals due to the large amount of space on the car, perfect for tampos, the Wildcat will be dearly missed (by me, at least) in the Hot Wheels lineup, and I wouldn’t mind seeing a modern recreation of the Wildcat return to the Hot Wheels lineup as a premium piece.
I hope this post has given you a better idea on the history of this futuristic American supercar, and the history of its small Hot Wheels counterpart. As usual, I’d write something like this any day.
1 note
·
View note
Text
DOOM (1993), DOOM II (Classic), And DOOM 3 Are Now Available For Xbox One
mspb( { productId: '9plzphbnhtmf', badgeType: 'large' }, function( badge ) { badge = badge.replace( /www\.microsoft\.com\/store\//g, "www.microsoft.com/en-us/store/" ); document.getElementById( "mspb-5d3f1da705a6b" ).innerHTML = badge; } );
mspb( { productId: '9plt62lrf9v7', badgeType: 'large' }, function( badge ) { badge = badge.replace( /www\.microsoft\.com\/store\//g, "www.microsoft.com/en-us/store/" ); document.getElementById( "mspb-5d3f1da705a8a" ).innerHTML = badge; } );
mspb( { productId: '9nsl68d814gc', badgeType: 'large' }, function( badge ) { badge = badge.replace( /www\.microsoft\.com\/store\//g, "www.microsoft.com/en-us/store/" ); document.getElementById( "mspb-5d3f1da705aa3" ).innerHTML = badge; } );
Product Info:
Developer: Nerve Software / Panic Button Publisher: Bethesda Softworks Website: DOOM Twitter: @nervesoftware / Panic Button / @bethesda / @DOOM
via Xbox Live's Major Nelson https://ift.tt/2yjONBR
2 notes
·
View notes