note description: "[ d_main.c 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. ]" license: "[ Copyright (C) 1993-1996 by id Software, Inc. Copyright (C) 2005-2014 Simon Howard Copyright (C) 2021 Ilgiz Mustafin This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ]" class D_MAIN create make feature i_main: I_MAIN wadfiles: LIST [STRING_8] make (a_i_main: I_MAIN) do i_main := a_i_main create {LINKED_LIST [STRING_8]} wadfiles.make pagename := "" singletics := True end feature startskill: INTEGER_32 startepisode: INTEGER_32 startmap: INTEGER_32 autostart: BOOLEAN singletics: BOOLEAN assign set_singletics -- debug flag to cancel adaptiveness set_singletics (a_singletics: like singletics) do singletics := a_singletics end debugfile: detachable FILE feature -- DEMO LOOP demosequence: INTEGER_32 pagetic: INTEGER_32 pagename: STRING_8 feature devparm: BOOLEAN assign set_devparm -- started game with -devparm set_devparm (a_devparm: like devparm) do devparm := a_devparm end nomonsters: BOOLEAN assign set_nomonsters -- checkparm of -nomonsters set_nomonsters (a_nomonsters: like nomonsters) do nomonsters := a_nomonsters end respawnparm: BOOLEAN assign set_respawnparm -- checkparm of -respawn set_respawnparm (a_respawnparm: like respawnparm) do respawnparm := a_respawnparm end fastparm: BOOLEAN assign set_fastparm -- checkparm of -fast set_fastparm (a_fastparm: like fastparm) do fastparm := a_fastparm end feature d_doommain local p: INTEGER_32 file: STRING_8 do {NOT_IMPLEMENTED}.not_implemented ("D_DoomMain", False) findresponsefile identifyversion if i_main.Doomstat_h.gamemode = {GAME_MODE_T}.shareware then print (" DOOM Shareware Startup%N") end p := i_main.m_argv.m_checkparm ("-playdemo") if not p.to_boolean then p := i_main.m_argv.m_checkparm ("-timedemo") end if p.to_boolean and p <= i_main.m_argv.myargv.upper then file := i_main.m_argv.myargv [p + 1].to_string_32 + ".lmp".as_string_8 d_addfile (file) print ("Playing demo " + i_main.m_argv.myargv [p + 1] + ".lmp.%N") end startskill := {DOOMDEF_H}.sk_medium startepisode := 1 startmap := 1 autostart := False print ("V_Init: allocate screens.%N") i_main.V_video.v_init print ("M_LoadDefaults: Load system defauls.%N") i_main.M_misc.m_loaddefaults print ("W_Init: Init WADfiles.%N") i_main.W_wad.w_initmultiplefiles (wadfiles) print ("added%N") print ("==================%N") print (" Shareware!%N") print ("==================%N") print ("M_Init: Init miscellaneous info.%N") i_main.M_menu.m_init print ("R_Init: Init DOOM refresh daemon - ") i_main.R_main.r_init print ("%NP_Init: Init Playloop state.%N") i_main.P_setup.p_init print ("I_Init: Setting up machine state.%N") i_main.I_system.i_init print ("D_CheckNetGame: Checking network game status.%N") i_main.D_net.d_checknetgame print ("S_Init: Setting up sound.%N") i_main.S_sound.s_init (i_main.S_sound.snd_sfxvolume * 8, i_main.S_sound.snd_musicvolume * 8) print ("HU_Init: Setting up heads up display.%N") i_main.Hu_stuff.hu_init print ("ST_Init: Init status bar.%N") i_main.St_stuff.st_init p := i_main.m_argv.m_checkparm ("-record") if p.to_boolean and p < i_main.m_argv.myargv.count - 1 then i_main.G_game.g_recorddemo (i_main.m_argv.myargv [p + 1].to_string_32.as_string_8) autostart := True end p := i_main.m_argv.m_checkparm ("-timedemo") if p /= 0 and p <= i_main.m_argv.myargv.upper then i_main.G_game.g_timedemo (i_main.m_argv.myargv [p + 1].to_string_32.as_string_8) d_doomloop end if i_main.G_game.gameaction /= i_main.G_game.Ga_loadgame then if autostart or i_main.G_game.netgame then i_main.G_game.g_initnew (startskill, startepisode, startmap) else d_starttitle end end d_doomloop end d_starttitle do i_main.G_game.gameaction := {G_GAME}.ga_nothing demosequence := -1 d_advancedemo end advancedemo: BOOLEAN d_advancedemo -- Called after each demo or intro demosequence finishes do advancedemo := True end findresponsefile do {NOT_IMPLEMENTED}.not_implemented ("FindResponseFile", False) end identifyversion do {NOT_IMPLEMENTED}.not_implemented ("IdentifyVersion", False) i_main.Doomstat_h.gamemode := {GAME_MODE_T}.shareware d_addfile ("doom1.wad") end d_addfile (a_wadfile: STRING_8) do wadfiles.extend (a_wadfile) end feature -- D_DoomLoop drone: BOOLEAN d_grabmousecallback: BOOLEAN -- Called to determine whether to grab the mouse pointer do if drone then Result := False elseif i_main.M_menu.menuactive or i_main.G_game.paused then Result := False else Result := (i_main.G_game.gamestate = {DOOMDEF_H}.gs_level) and not i_main.G_game.demoplayback and not advancedemo end end d_doomloop do {NOT_IMPLEMENTED}.not_implemented ("D_DoomLoop", False) if i_main.G_game.demorecording then i_main.G_game.g_beginrecording end i_main.I_video.grabmouse_callback := agent d_grabmousecallback check attached i_main.I_video as iv then iv.i_initgraphics end from until False loop d_runframe end end wipestart: INTEGER_32 wipe: BOOLEAN d_runframe local nowtime: INTEGER_32 tics: INTEGER_32 perf_start, perf_end, perf_total: NATURAL_64 do if wipe then from tics := 0 until tics > 0 loop nowtime := i_main.I_system.i_gettime tics := nowtime - wipestart i_main.I_system.i_sleep (1) end perf_start := i_main.I_timer.i_get_time_us wipestart := nowtime wipe := not i_main.F_wipe.wipe_screenwipe ({F_WIPE}.wipe_melt, 0, 0, {DOOMDEF_H}.screenwidth, {DOOMDEF_H}.screenheight, tics) i_main.I_video.i_updatenoblit i_main.M_menu.m_drawer i_main.I_video.i_finishupdate perf_end := i_main.I_timer.i_get_time_us perf_total := perf_end - perf_start i_main.I_timer.i_log_perf_frame (perf_total, "wipe") else if not i_main.G_game.timingdemo then print ("DOOM LOOP GAMETIC: " + i_main.G_game.gametic.out + ", state " + i_main.G_game.gamestate.out + "%N") else perf_start := i_main.I_timer.i_get_time_us end i_main.I_video.i_startframe if singletics then i_main.I_video.i_starttic d_processevents i_main.G_game.g_buildticcmd (i_main.D_net.Netcmds [i_main.G_game.consoleplayer] [i_main.D_net.maketic \\ {D_NET}.backuptics]) if advancedemo then d_doadvancedemo end i_main.M_menu.m_ticker i_main.G_game.g_ticker i_main.G_game.gametic := i_main.G_game.gametic + 1 i_main.D_net.maketic := i_main.D_net.maketic + 1 else i_main.D_net.tryruntics end i_main.S_sound.s_updatesounds (i_main.G_game.Players [i_main.G_game.consoleplayer].mo) if i_main.I_video.Screenvisible and not i_main.G_game.nodrawers then wipe := i_main.D_display.d_display if wipe then i_main.F_wipe.wipe_endscreen (0, 0, {DOOMDEF_H}.screenwidth, {DOOMDEF_H}.screenheight) wipestart := i_main.I_system.i_gettime - 1 else i_main.I_video.i_finishupdate perf_end := i_main.I_timer.i_get_time_us perf_total := perf_end - perf_start i_main.I_timer.i_log_perf_frame (perf_total, "gamestate " + i_main.G_game.gamestate.out) end end end end d_processevents -- Send all the events of the given timestamp down the responder chain local event: EVENT_T res: BOOLEAN do if i_main.Doomstat_h.gamemode = {GAME_MODE_T}.commercial and i_main.W_wad.w_checknumforname ("map01") < 0 then else from until eventtail = eventhead loop event := Events [eventtail] if not i_main.M_menu.m_responder (event) then res := i_main.G_game.g_responder (event) end eventtail := (eventtail + 1).bit_and ({D_EVENT}.maxevents - 1) end end end d_doadvancedemo -- This cycles through the demo sequences. -- FIXME - version dependend demo numbers? do i_main.G_game.Players [i_main.G_game.consoleplayer].playerstate := {PLAYER_T}.pst_live advancedemo := False i_main.G_game.usergame := False i_main.G_game.paused := False i_main.G_game.gameaction := {G_GAME}.ga_nothing if i_main.Doomstat_h.gamemode = {GAME_MODE_T}.retail then demosequence := (demosequence + 1) \\ 7 else demosequence := (demosequence + 1) \\ 6 end inspect demosequence when 0 then if i_main.Doomstat_h.gamemode = {GAME_MODE_T}.commercial then pagetic := 35 * 11 else pagetic := 170 end i_main.G_game.gamestate := {DOOMDEF_H}.gs_demoscreen pagename := "TITLEPIC" if i_main.Doomstat_h.gamemode = {GAME_MODE_T}.commercial then i_main.S_sound.s_startmusic ({SOUNDS_H}.mus_dm2ttl) else i_main.S_sound.s_startmusic ({SOUNDS_H}.mus_intro) end when 1 then i_main.G_game.g_deferedplaydemo ("demo1") when 2 then pagetic := 200 i_main.G_game.gamestate := {DOOMDEF_H}.gs_demoscreen pagename := "CREDIT" when 3 then i_main.G_game.g_deferedplaydemo ("demo2") when 4 then i_main.G_game.gamestate := {DOOMDEF_H}.gs_demoscreen if i_main.Doomstat_h.gamemode = {GAME_MODE_T}.commercial then pagetic := 35 * 11 pagename := "TITLEPIC" i_main.S_sound.s_startmusic ({SOUNDS_H}.mus_dm2ttl) else pagetic := 200 if i_main.Doomstat_h.gamemode = {GAME_MODE_T}.retail then pagename := "CREDIT" else pagename := "HELP2" end end when 5 then i_main.G_game.g_deferedplaydemo ("demo3") when 6 then i_main.G_game.g_deferedplaydemo ("demo4") else end end feature -- EVENT HANDLING -- Events are asynchronous inputs generally generated by the game user. -- Events can be discarded if no responder claims them Events: ARRAY [EVENT_T] once create Result.make_filled (create {EVENT_T}.make, 0, {D_EVENT}.maxevents) end eventhead: INTEGER_32 eventtail: INTEGER_32 d_postevent (event: EVENT_T) do Events [eventhead] := event eventhead := (eventhead + 1).bit_and ({D_EVENT}.maxevents - 1) ensure advanced_if_there_was_space: old eventhead < {D_EVENT}.maxevents - 1 implies eventhead = old eventhead + 1 wrapped_if_there_was_no_space: old eventhead = {D_EVENT}.maxevents - 1 implies eventhead = 0 end d_pageticker -- Handles timing for warped projection do pagetic := pagetic - 1 if pagetic < 0 then d_advancedemo end end end -- class D_MAIN
Generated by ISE EiffelStudio