int main(int argc, char** argv) {
    SYS_argc = argc;
    SYS_argv = argv;

    // Check command line options
    if (SYS_HasParam("-l")) {
        if (argc != 3) {
            PrintUsage();
            return 0;
        }

        // Load the level and print its data
        L_LoadLevel(argv[argc - 1]);
        printf("Name: %s\n", L_current.name);
        printf("Contains %d resources and %d props\n",
               L_current.res.size, L_current.props.size);

        // Print name of every resource
        printf("\nResources\n");
        for (int i = 0; i < L_current.res.size; i++)
            printf("\t%d:\t%s\n", i, ((resource*)ListGet(&L_current.res, i))->name);

        // Print data of every prop
        printf("\nProps\n");
        for (int i = 0; i < L_current.props.size; i++) {
            prop* p = ListGet(&L_current.props, i);
            printf(
                "\t%d:\tResource: %s\n\t\tPos: %f, %f, %f\n\t\tRot: %f, %f, %f\n",
                i, p->res->name, p->pos[0], p->pos[1], p->pos[2],
                p->rot[0], p->rot[1], p->rot[2]
            );
        }

        return 0;
    }

    // Initialize console variables
    C_Init();

    // Try to open a window with rendering capabilities
    if (!SYS_OpenWindow()) SYS_Error("Failed to open a window with OpenGL Core 3.3");

    // Initialize OpenGL
    V_InitOpenGL();
    fflush(stdout);

    // Initialize main engine
    G_Init();
    fflush(stdout);

    // Initialize rendering system
    V_Init();
    fflush(stdout);

    // Main game loop
    uint32_t current = SYS_TimeMillis();
    uint32_t last = current;
    uint32_t secondTimer = 0, frames = 0;
    while (!SYS_WindowClosed()) {
        last = current;
        current = SYS_TimeMillis();
        SYS_deltaMillis = current - last;
        secondTimer += SYS_deltaMillis;
        frames++;

        if (secondTimer >= 1000) {
            secondTimer -= 1000;

            printf("\rFPS: %d", frames);
            fflush(stdout);
            frames = 0;
        }

        // Update game, then render to screen
        G_Tick();
        V_Tick();
        SYS_UpdateWindow();
    }
    printf("\n");

    G_Quit();
    V_Quit();
    return 0;
}
Exemple #2
0
//
// D_DoomMain
//
void D_DoomMain(void)
{
	int p;
	char file[256];
	char demolumpname[9];

	M_FindResponseFile();

	// print banner

	PrintBanner(PACKAGE_STRING);

	I_Print("Z_Init: Init zone memory allocation daemon. \n");
	Z_Init();

	iwadfile = D_FindIWAD();

	// None found?

	if (iwadfile == NULL) {
		I_Error
		    ("Game mode indeterminate.  No IWAD file was found.  Try\n"
		     "specifying one with the '-iwad' command line parameter.\n");
	}

	modifiedgame = false;

	//!
	// @vanilla
	//
	// Disable monsters.
	//

	nomonsters = M_CheckParm("-nomonsters");

	//!
	// @vanilla
	//
	// Monsters respawn after being killed.
	//

	respawnparm = M_CheckParm("-respawn");

	//!
	// @vanilla
	//
	// Monsters move faster.
	//

	fastparm = M_CheckParm("-fast");

	//! 
	// @vanilla
	//
	// Developer mode.  F1 saves a screenshot in the current working
	// directory.
	//

	devparm = M_CheckParm("-devparm");

	//!
	// @category net
	// @vanilla
	//
	// Start a deathmatch game.
	//

	if (M_CheckParm("-deathmatch"))
		deathmatch = 1;

	//!
	// @category net
	// @vanilla
	//
	// Start a deathmatch 2.0 game.  Weapons do not stay in place and
	// all items respawn after 30 seconds.
	//

	if (M_CheckParm("-altdeath"))
		deathmatch = 2;

	if (devparm)
		I_Print(D_DEVSTR);

	//!
	// @arg <x>
	// @vanilla
	//
	// Turbo mode.  The player's speed is multiplied by x%.  If unspecified,
	// x defaults to 200.  Values are rounded up to 10 and down to 400.
	//

	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;
		/*I_Print ("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;
	}
	// init subsystems
	I_Print("V_Init: allocate screens.\n");
	V_Init();

	I_Print("M_LoadDefaults: Load system defaults.\n");
	M_LoadDefaults();	// load before initing other systems

	I_Print("W_Init: Init WADfiles.\n");
	D_AddFile(iwadfile);

#ifdef FEATURE_WAD_MERGE

	// Merged PWADs are loaded first, because they are supposed to be 
	// modified IWADs.

	//!
	// @arg <files>
	// @category mod
	//
	// Simulates the behavior of deutex's -merge option, merging a PWAD
	// into the main IWAD.  Multiple files may be specified.
	//

	p = M_CheckParm("-merge");

	if (p > 0) {
		for (p = p + 1; p < myargc && myargv[p][0] != '-'; ++p) {
			char *filename;

			filename = D_TryFindWADByName(myargv[p]);

			/*I_Print(" merging %s\n", filename); */
			W_MergeFile(filename);
		}
	}
	// NWT-style merging:

	// NWT's -merge option:

	//!
	// @arg <files>
	// @category mod
	//
	// Simulates the behavior of NWT's -merge option.  Multiple files
	// may be specified.

	p = M_CheckParm("-nwtmerge");

	if (p > 0) {
		for (p = p + 1; p < myargc && myargv[p][0] != '-'; ++p) {
			char *filename;

			filename = D_TryFindWADByName(myargv[p]);

			/*I_Print(" performing NWT-style merge of %s\n", filename); */
			W_NWTDashMerge(filename);
		}
	}
	// Add flats

	//!
	// @arg <files>
	// @category mod
	//
	// Simulates the behavior of NWT's -af option, merging flats into
	// the main IWAD directory.  Multiple files may be specified.
	//

	p = M_CheckParm("-af");

	if (p > 0) {
		for (p = p + 1; p < myargc && myargv[p][0] != '-'; ++p) {
			char *filename;

			filename = D_TryFindWADByName(myargv[p]);

			/*I_Print(" merging flats from %s\n", filename); */
			W_NWTMergeFile(filename, W_NWT_MERGE_FLATS);
		}
	}
	//!
	// @arg <files>
	// @category mod
	//
	// Simulates the behavior of NWT's -as option, merging sprites
	// into the main IWAD directory.  Multiple files may be specified.
	//

	p = M_CheckParm("-as");

	if (p > 0) {
		for (p = p + 1; p < myargc && myargv[p][0] != '-'; ++p) {
			char *filename;

			filename = D_TryFindWADByName(myargv[p]);

			/*I_Print(" merging sprites from %s\n", filename); */
			W_NWTMergeFile(filename, W_NWT_MERGE_SPRITES);
		}
	}
	//!
	// @arg <files>
	// @category mod
	//
	// Equivalent to "-af <files> -as <files>".
	//

	p = M_CheckParm("-aa");

	if (p > 0) {
		for (p = p + 1; p < myargc && myargv[p][0] != '-'; ++p) {
			char *filename;

			filename = D_TryFindWADByName(myargv[p]);

			/*I_Print(" merging sprites and flats from %s\n", filename); */
			W_NWTMergeFile(filename,
				       W_NWT_MERGE_SPRITES | W_NWT_MERGE_FLATS);
		}
	}
#endif

	//!
	// @arg <files>
	// @vanilla
	//
	// Load the specified PWAD files.
	//

	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] != '-') {
			char *filename;

			filename = D_TryFindWADByName(myargv[p]);

			D_AddFile(filename);
		}
	}
	// 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]);
	   I_Print("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)
	   format_number(file,"~"DEVMAPS"cdata/map0%i.wad", p, 10);
	   else
	   format_number(file,"~"DEVMAPS"cdata/map%i.wad", p, 10);
	   break;
	   }
	   D_AddFile (file);
	   } */

	//!
	// @arg <demo>
	// @category demo
	// @vanilla
	//
	// Play back the demo named demo.lmp.
	//

	p = M_CheckParm("-playdemo");

	if (!p) {
		//!
		// @arg <demo>
		// @category demo
		// @vanilla
		//
		// Play back the demo named demo.lmp, determining the framerate
		// of the screen.
		//
		p = M_CheckParm("-timedemo");

	}

	if (p && p < myargc - 1) {
		strcpy(file, myargv[p + 1]);

		if (D_AddFile(file)) {
			strncpy(demolumpname, lumpinfo[numlumps - 1].name, 8);
			demolumpname[8] = '\0';

			/*I_Print("Playing demo %s.\n", file); */
		} else {
			// If file failed to load, still continue trying to play
			// the demo in the same way as Vanilla Doom.  This makes
			// tricks like "-playdemo demo1" possible.

			strncpy(demolumpname, myargv[p + 1], 8);
			demolumpname[8] = '\0';
		}

	}
	// Generate the WAD hash table.  Speed things up a bit.

	I_Print("W_Init: Generate Hash Table.\n");
	W_GenerateHashTable();

	D_IdentifyVersion();
	InitGameVersion();
	D_SetGameDescription();

	// 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.");
	}
	// get skill / episode / map from parms
	startskill = sk_medium;
	startepisode = 1;
	startmap = 1;
	autostart = false;

	//!
	// @arg <skill>
	// @vanilla
	//
	// Set the game skill, 1-5 (1: easiest, 5: hardest).  A skill of
	// 0 disables all monsters.
	//

	p = M_CheckParm("-skill");

	if (p && p < myargc - 1) {
		startskill = myargv[p + 1][0] - '1';
		autostart = true;
	}
	//!
	// @arg <n>
	// @vanilla
	//
	// Start playing on episode n (1-4)
	//

	p = M_CheckParm("-episode");

	if (p && p < myargc - 1) {
		startepisode = myargv[p + 1][0] - '0';
		startmap = 1;
		autostart = true;
	}

	timelimit = 0;

	//! 
	// @arg <n>
	// @category net
	// @vanilla
	//
	// For multiplayer games: exit each level after n minutes.
	//

	p = M_CheckParm("-timer");

	if (p && p < myargc - 1 && deathmatch) {
		timelimit = atoi(myargv[p + 1]);
		/*I_Print("timer: %i\n", timelimit); */
	}
	//!
	// @category net
	// @vanilla
	//
	// Austin Virtual Gaming: end levels after 20 minutes.
	//

	p = M_CheckParm("-avg");

	if (p && p < myargc - 1 && deathmatch) {
		I_Print("Austin Virtual Gaming: Levels will end "
			"after 20 minutes\n");
		timelimit = 20;
	}
	//!
	// @arg [<x> <y> | <xy>]
	// @vanilla
	//
	// Start a game immediately, warping to ExMy (Doom 1) or MAPxy
	// (Doom 2)
	//

	p = M_CheckParm("-warp");

	if (p && p < myargc - 1) {
		if (gamemode == commercial)
			startmap = atoi(myargv[p + 1]);
		else {
			startepisode = myargv[p + 1][0] - '0';

			if (p + 2 < myargc) {
				startmap = myargv[p + 2][0] - '0';
			} else {
				startmap = 1;
			}
		}
		autostart = true;
	}
	// Check for load game parameter
	// We do this here and save the slot number, so that the network code
	// can override it or send the load slot to other players.

	//!
	// @arg <s>
	// @vanilla
	//
	// Load the game in slot s.
	//

	p = M_CheckParm("-loadgame");

	if (p && p < myargc - 1) {
		startloadgame = atoi(myargv[p + 1]);
	} else {
		// Not loading a game
		startloadgame = -1;
	}

	//!
	// @category video
	//
	// Disable vertical mouse movement.
	//

	if (M_CheckParm("-novert"))
		novert = true;

	//!
	// @category video
	//
	// Enable vertical mouse movement.
	//

	if (M_CheckParm("-nonovert"))
		novert = false;

	if (W_CheckNumForName("SS_START") >= 0
	    || W_CheckNumForName("FF_END") >= 0) {
		I_Print
		    ("===========================================================================\n");
		I_Print
		    (" WARNING: The loaded WAD file contains modified sprites or\n"
		     " floor textures.  You may want to use the '-merge' command\n"
		     " line option instead of '-file'.\n");
	}

	I_Print
	    ("===========================================================================\n");

	PrintBanner(gamedescription);

	I_Print
	    ("===========================================================================\n"
	     " " PACKAGE_NAME
	     " is free software, covered by the GNU General Public\n"
	     " License.  There is NO warranty; not even for MERCHANTABILITY or FITNESS\n"
	     " FOR A PARTICULAR PURPOSE. You are welcome to change and distribute\n"
	     " copies under certain conditions. See the source for more information.\n"
	     "===========================================================================\n");

	I_Print("M_Init: Init miscellaneous info.\n");
	M_Init();

	I_Print("R_Init: Init DOOM refresh daemon - ");
	R_Init();

	I_Print("\nP_Init: Init Playloop state.\n");
	P_Init();

	I_Print("\nG_Init: Init game state.\n");
	G_Init();

	I_Print("S_Init: Setting up sound.\n");
	S_Init(sfxVolume * 8, musicVolume * 8);

	PrintGameVersion();

	I_Print("HU_Init: Setting up heads up display.\n");
	HU_Init();

	I_Print("ST_Init: Init status bar.\n");
	ST_Init();

	// If Doom II without a MAP01 lump, this is a store demo.  
	// Moved this here so that MAP01 isn't constantly looked up
	// in the main loop.

	if (gamemode == commercial && W_CheckNumForName("map01") < 0)
		storedemo = true;

	I_Print("\nI_InitGraphics: Init graphics.\n");
	I_InitGraphics();

	//!
	// @arg <x>
	// @category demo
	// @vanilla
	//
	// Record a demo named x.lmp.
	//

	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(demolumpname);
		D_DoomLoop();	// never returns
	}

	if (startloadgame >= 0) {
		strcpy(file, P_SaveGameFile(startloadgame));
		G_LoadGame(file);
	}

	if (gameaction != ga_loadgame) {
		if (autostart || netgame)
			G_InitNew(startskill, startepisode, startmap);
		else
			D_StartTitle();	// start up intro loop
	}

	I_Print("D_DoomLoop: GOGOGOG!\n");
	D_DoomLoop();		// never returns
}
Exemple #3
0
script
static void UpdateMagicUI(struct player *p, struct upgrade *upgr)
{
   struct gui_state *g = &UData.gst;

   G_Begin(g, 320, 240);
   G_UpdateState(g, p);

   PrintSprite(sp_UI_MagicSelectBack, 0,1, 0,1);

   bool any = false;

   for(i32 i = 0; i < countof(minf); i++)
   {
      struct magic_info const *m = &minf[i];

      if(m->st != -1 && !world.cbiupgr[m->st]) continue;

      char gfx[32] = ":UI:"; strcat(gfx, m->name);
      char hot[32] = ":UI:"; strcat(hot, m->name); strcat(hot, "Sel");

      struct gui_pre_btn pre = {
         .gfx      = gfx,
         .hot      = hot,
         .cdef     = "d",
         .cact     = "r",
         .chot     = "k",
         .cdis     = "m",
         .font     = s"cbifont",
         .snd      = s"player/cbi/buttonpress",
         .external = true,
         .w        = 64,
         .h        = 64
      };

      char name[128]; LanguageCV(name, LANG "INFO_SHORT_%s", m->name);

      if(G_Button_FId(g, i + 1, name, m->x, m->y, .preset = &pre))
         GiveMagic(m);
   }

   G_End(g, gui_curs_outline);
}

script
static void GivePlayerZ(i32 tid, struct player *p)
{
   while(ACS_ThingCount(T_NONE, tid)) {
      SetMembI(tid, sm_UserZ, p->z);
      ACS_Delay(1);
   }
}

static void SetMagicUI(struct player *p, bool on)
{
   if(p->dead) return;

   struct upgrade *upgr = p->getUpgr(UPGR_Magic);

   if(on)
   {
      UData.ui = true;
      p->semifrozen++;

      UData.gst.gfxprefix = ":UI:";
      UData.gst.cx = 320/2;
      UData.gst.cy = 240/2;

      G_Init(&UData.gst);
   }
   else if(!on && UData.ui)
   {
      if(UData.gst.hot) GiveMagic(&minf[UData.gst.hot - 1]);

      UData.ui = false;
      p->semifrozen--;

      memset(&UData.gst, 0, sizeof UData.gst);
   }
}

// Extern Functions ----------------------------------------------------------|

script
void Upgr_Magic_Update(struct player *p, struct upgrade *upgr)
{
   StrEntON
   k32 manaperc = p->mana / (k32)p->manamax;

   if(UData.manaperc < 1 && manaperc == 1)
      ACS_LocalAmbientSound(ss_player_manafull, 127);

   UData.manaperc = manaperc;

   if(p->buttons & BT_USER4 && !(p->old.buttons & BT_USER4))
      SetMagicUI(p, true);
   else if(!(p->buttons & BT_USER4) && p->old.buttons & BT_USER4)
      SetMagicUI(p, false);

   if(UData.ui)
      UpdateMagicUI(p, upgr);

   if(manaperc >= 0.7)
      for(i32 i = 0; i < 5 * manaperc; i++)
   {
      k32 dst = ACS_RandomFixed(32, 56);
      k32 ang = ACS_RandomFixed(0, 1);
      i32 tid = ACS_UniqueTID();
      i32 x   = ACS_Cos(ang) * dst;
      i32 y   = ACS_Sin(ang) * dst;
      i32 z   = ACS_Random(8, 48);
      ACS_Spawn(so_ManaLeak, p->x + x, p->y + y, p->z + z, tid);
      SetMembI(tid, sm_UserX, x);
      SetMembI(tid, sm_UserY, y);
      SetPropK(tid, APROP_Alpha, manaperc / 2);
      PtrSet(tid, AAPTR_DEFAULT, AAPTR_MASTER, p->tid);
      GivePlayerZ(tid, p);
   }
}