📄 rungame.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 + -