⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rungame.cpp

📁 3D游戏模板
💻 CPP
字号:
/* game runner
 * Template CS game
 * (C)2001 Mat Sutcliffe. See license.txt for license info (GPL)
 */

#include <cssysdef.h>
#include <iutil/objreg.h>
#include <iutil/event.h>
#include <iutil/eventh.h>
#include <iutil/eventq.h>
#include <csutil/csevent.h>
#include <iutil/cfgmgr.h>
#include <ivaria/conin.h>
#include <ivideo/natwin.h>
#include <ivideo/graph2d.h>
#include <ivideo/graph3d.h>
#include <ivideo/fontserv.h>
#include <csutil/inpnames.h>
#include <csutil/hashmap.h>
#include <cssys/sysfunc.h>

#include "rungame.h"
#include "game/game.h"
#include "sound.h"
#include "console.h"
#include "menu/menu.h"
#include "sys.h"

class BindPos : public iInputBinderPosition {
	private:
		int *p;
	public:
		SCF_DECLARE_IBASE;

		BindPos (int *pp) { SCF_CONSTRUCT_IBASE(NULL); p = pp; }
		virtual ~BindPos () {}

		int Get () const { return *p; }
		void Set (int pp) { *p = pp; }
};

class BindBool : public iInputBinderBoolean {
	private:
		int *b;
	public:
		SCF_DECLARE_IBASE;

		BindBool (int *bb) { SCF_CONSTRUCT_IBASE(NULL); b = bb; }
		virtual ~BindBool () {}

		bool Get () const { return *b; }
		void Set (bool bb) { *b = bb ? 1 : 0; }
};

SCF_IMPLEMENT_IBASE(GameRunner)
	SCF_IMPLEMENTS_INTERFACE(iEventHandler)
SCF_IMPLEMENT_IBASE_END

SCF_IMPLEMENT_IBASE(BindPos)
	SCF_IMPLEMENTS_INTERFACE(iInputBinderPosition)
SCF_IMPLEMENT_IBASE_END

SCF_IMPLEMENT_IBASE(BindBool)
	SCF_IMPLEMENTS_INTERFACE(iInputBinderBoolean)
SCF_IMPLEMENT_IBASE_END

GameRunner::GameRunner(Sound *snd, Console *con, Game *gam, Menu *men, iObjectRegistry *objreg) {
	SCF_CONSTRUCT_IBASE(NULL);
	conin = CS_QUERY_REGISTRY(objreg, iConsoleInput);
	conout = CS_QUERY_REGISTRY(objreg, iConsoleOutput);
	sound = snd;
	console = con;
	game = gam;
	menu = men;
	fps_on = 0;
	conf = CS_QUERY_REGISTRY(objreg, iConfigManager);

	cmdhash = new csHashMap;
	for (int i = 0; game->inputcmds[i].str; i++) {
		cmdhash->Put(csHashCompute(game->inputcmds[i].str),
			(csHashObject) & game->inputcmds[i]);
	}

	gfx2d = CS_QUERY_REGISTRY(objreg, iGraphics2D);
	iNativeWindow *win = gfx2d->GetNativeWindow();
	if (win) win->SetTitle(GAME);
	g2dfont = gfx2d->GetFontServer()->LoadFont(CSFONT_LARGE);
	stats = CS_QUERY_REGISTRY(objreg, iPerfStats);

	gfx3d = CS_QUERY_REGISTRY(objreg, iGraphics3D);
	gfx3d->Open();

	binder = new csInputBinder;
	refreshconf();
	canvas_off = 0;
	eventq = CS_QUERY_REGISTRY(objreg, iEventQueue);
	eventq->RegisterListener(this, CSMASK_Input |
		CSMASK_Broadcast | CSMASK_Command | CSMASK_Nothing);
}

GameRunner::~GameRunner() {
	eventq->RemoveListener(this);
	delete binder;
	csHashIterator iter (cmdhash);
	while (csVar<int> *v = (csVar<int> *) iter.Next ()) delete v;
	delete cmdhash;
	gfx3d->Close();
}

void GameRunner::refreshconf() {
	binder->UnbindAll();
	csRef <iConfigIterator> iter (conf->Enumerate(GAME ".Bind."));
	while (iter->Next()) {
		csEvent ev;
		const char *cmd = iter->GetKey(false);
		char *code = (char *)iter->GetStr();
		csParseInputDef (code, ev, false);
		inputcmd_t *inp =
			(inputcmd_t *)cmdhash->Get(csHashCompute(cmd));
		if (inp) switch (ev.Type) {
			case csevKeyDown:
			case csevMouseDown:
			case csevJoystickDown:
			binder->Bind (ev, new BindBool (inp->var), inp->toggle);
			break;

			case csevMouseMove:
			case csevJoystickMove:
			binder->Bind (ev, new BindPos (inp->var));
			break;

			default:
			break;
		}
	}

	for (int i = 0; rsoptions[i].str; i++) {
		int value = conf->GetInt(rsoptions[i].str, -1);
		if (value != -1)
			gfx3d->SetRenderState(rsoptions[i].num, value);
	}

	fps_on = conf->GetBool(GAME ".ShowFPS");
}

bool GameRunner::HandleEvent(iEvent &ev) {
	if (ev.Type == csevBroadcast) switch (ev.Command.Code) {
		case cscmdPreProcess:
		game->preframe(ev.Time);
		return 1;

		case cscmdProcess:
		if (canvas_off) {
			csSleep(100);
			return 0;
		} else {
			gfx3d->BeginDraw(CSDRAW_3DGRAPHICS
				| CSDRAW_CLEARZBUFFER | CSDRAW_CLEARSCREEN);
			if (game->playing) game->doframe(ev.Time);
			return 1;
		}

		case cscmdPostProcess:
		if (canvas_off) {
			csSleep(100);
			return 0;
		} else {
			gfx3d->BeginDraw(CSDRAW_2DGRAPHICS);
			game->postframe(ev.Time);
			if (menu->visible) menu->draw();
			else if (console->visible) conout->Draw2D();
			if (fps_on) fps();
			return 1;
		}

		case cscmdFinalProcess:
		gfx3d->FinishDraw();
		gfx3d->Print(NULL);
		return 1;

		case cscmdCanvasHidden:
		canvas_off = 1;
		return 1;

		case cscmdCanvasExposed:
		canvas_off = 0;
		return 1;

		default:
		return 0;
	}

	if (CS_IS_INPUT_EVENT(ev)) {
		if (CS_IS_KEYBOARD_EVENT(ev)) {
			if (ev.Type == csevKeyDown) {
				if (ev.Key.Code == CSKEY_ESC) {
					console->hide();
					menu->toggle();
					if (! menu->visible) refreshconf();
					if (menu->visible)
						game->playing = 0;
					else game->playing = 1;
					return 1;
				} else if (ev.Key.Char == '`') {
					menu->hide();
					console->toggle();
					if (! console->visible) refreshconf();
					if (console->visible)
						game->playing = 0;
					else game->playing = 1;
					return 1;
				}
			}
			if (console->visible) return conin->HandleEvent(ev);
		}
		if (menu->visible) return menu->HandleEvent(ev);
		return binder->QueryHandler()->HandleEvent(ev);
	}
	return 0;
}

void GameRunner::fps() {
	char n[16];
	sprintf(n, "FPS: %d", (int) stats->GetFPS());
	gfx2d->Write(g2dfont, 10, 10, -1, -1, n);
}

rsoption_t GameRunner::rsoptions[] = {
#	define OPT	GAME ".Gfx."
	{ OPT "ZBuffer",	G3DRENDERSTATE_ZBUFFERMODE },
	{ OPT "Dither",		G3DRENDERSTATE_DITHERENABLE },
	{ OPT "BiMap",		G3DRENDERSTATE_BILINEARMAPPINGENABLE },
	{ OPT "TriMap",		G3DRENDERSTATE_TRILINEARMAPPINGENABLE },
	{ OPT "Transp",		G3DRENDERSTATE_TRANSPARENCYENABLE },
	{ OPT "MipMap",		G3DRENDERSTATE_MIPMAPENABLE },
	{ OPT "TexMap",		G3DRENDERSTATE_TEXTUREMAPPINGENABLE },
	{ OPT "Light",		G3DRENDERSTATE_LIGHTINGENABLE },
	{ OPT "Interlace",	G3DRENDERSTATE_INTERLACINGENABLE },
	{ OPT "MMX",		G3DRENDERSTATE_MMXENABLE },
	{ OPT "Interpol",	G3DRENDERSTATE_INTERPOLATIONSTEP },
	{ OPT "MaxPolys",	G3DRENDERSTATE_MAXPOLYGONSTODRAW },
	{ OPT "Shade",		G3DRENDERSTATE_GOURAUDENABLE },
	{ OPT "Edges",		G3DRENDERSTATE_EDGES },
	{ NULL, (G3D_RENDERSTATEOPTION)0 }
};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -