/** * This is an example of program that uses cake library. * In this file, the coder has to write the main function, create the window * (for instance by using GLUT like here), define the keys, manage the mouse * behaviour, order the map loading, and make the main loop for update and redraw. */ #ifdef WIN32 #pragma comment(lib, "cake/glsetup/lib/glut32.lib") // Link for GLUT 3.7.6 #ifdef _DEBUG #pragma comment(lib, "obj_files/caked.lib") // Link for cake library #else #pragma comment(lib, "obj_files/cake.lib") // Link for cake library #endif #endif #include "cake/alias.h" // aliases #include "cake/app.h" // application #include "cake/cake.h" // main cake header #include "cake/client.h" // clients #include "cake/commands.h" // commands #include "cake/console.h" // console #include "cake/definitions.h" // cake definitions #include "cake/demo.h" // demo support #include "cake/files.h" // files support #include "cake/framework.h" // framework #include "cake/logfile.h" // logfile #include "cake/math.h" // math funcs #include "cake/mem.h" // memory #include "cake/overlay.h" // overlay #include "cake/render.h" // render #include "cake/sound.h" // sound/music support #include "cake/system.h" // exceptions #include "cake/timer.h" // timer #include "cake/vars.h" // variables #include "cake/world.h" // world #include "cake/glsetup/glut.h" // OpenGL + GLUT #define DEFAULT_MUSIC "music/sonic1.wav" // default music when no map is loaded //----------------------------------------------------------------------------- // Variables //----------------------------------------------------------------------------- // App and world stuff App* app = NULL; // main application int preview = -1; // map preview state // clients stuff int nstartpos, currstartpos; // client start pos // inputs Var invertMouseX("invertMouseX", -1, VF_PERSISTENT); // mouse x inversion Var invertMouseY("invertMouseY", -1, VF_PERSISTENT); // mouse y inversion struct { int x, y; } mousepos; // mouse x and y position bool AutoCenterMouse = true; // the mouse is always centered bool lButton = false, mButton = false, rButton = false; // mouse buttons state int dx, dy; // mouse rot backup Var mouse_speed("mouse_speed", 0.5f, VF_PERSISTENT); // camera rotation speed (if camera is rotated with mouse) Var zoomspeed("zoomspeed", 300, VF_PERSISTENT); // zoom speed int lastkey; // last key pressed backup typedef enum { KEYUP = 0, KEYDOWN = 1 } key_state; // keyboard key state key_state up, down, left, right, pgnup, pgndown, zoom; // keys that use keystate system (to avoid the dependance to keyboard repetition speed) // console int histLine; // commands history scrolling value Var consoleKey("consoleKey", 96, VF_PERSISTENT); // key used for console opening/closing int tabmode = 1; // console tabulation mode // window int window_index; // window index int width, height; // window width and height int toppos, leftpos; // window position (top and pos) - not used int freq; // window frequency int colorbits; // window color bits (8, 16, 24 or 32) bool fullscr; // is window in fullscreen mode int backupWidth, backupHeight; // backup used for maximisation/reduce #define nwidths 17 #define nheights 17 #define ncolors 5 #define nfreqs 11 int widths[nwidths] = {320, 400, 480, 512, 640, 720, 768, 800, 856, 960, 1024, 1152, 1200, 1280, 1600, 1920, 2048}; int heights[nheights] = {200, 240, 300, 360, 384, 400, 480, 576, 600, 720, 768, 864, 900, 960, 1080, 1200, 1536}; int colors[ncolors] = {8, 15, 16, 24, 32}; int freqs[nfreqs] = {43, 50, 56, 60, 70, 72, 75, 85, 95, 100, 120}; //----------------------------------------------------------------------------- // Functions declarations //----------------------------------------------------------------------------- void AddCommands(void); void RegisterVariables(void); void Keyboard(unsigned char key, int x, int y); void KeyboardUp(unsigned char key, int x, int y); void KeyboardSpec(int key, int x, int y); void KeyboardSpecUp(int key, int x, int y); void MouseClic(int button, int state, int x, int y); void MouseMove(int x, int y); void MouseMovePassive(int x, int y); static void Draw(void); void Reshape(int w, int h); void Idle(void); void Init(); void ParseArgs(int argc, char *argv[]); void Shut(int status); int ScreenShot(char *fName, int hideconsole = 1); void CheckForAllAvailableResolutions(void); void ToggleFullScreen(void); //----------------------------------------------------------------------------- // Commands declarations //----------------------------------------------------------------------------- void cmd_quit(int argc, char *argv[]); void cmd_load(int argc, char *argv[]); void cmd_reload(int argc, char *argv[]); void cmd_defineviewport(int argc, char *argv[]); void cmd_noclip(int argc, char *argv[]); void cmd_lockfrustum(int argc, char *argv[]); void cmd_unload(int argc, char *argv[]); void cmd_record(int argc, char *argv[]); void cmd_stopdemo(int argc, char *argv[]); void cmd_demo(int argc, char *argv[]); void cmd_demodump(int argc, char *argv[]); void cmd_shaderpreview(int argc, char *argv[]); void cmd_resolutions(int argc, char *argv[]); void cmd_screenshot(int argc, char *argv[]); void cmd_fontsize (int argc, char *argv[]); void cmd_tabmode (int argc, char *argv[]); void cmd_togglemousecenter (int argc, char *argv[]); void cmd_preview (int argc, char *argv[]); void cmd_credits(int argc, char *argv[]); void cmd_speed(int argc, char *argv[]); void cmd_fov(int argc, char *argv[]); void cmd_zoomlimit(int argc, char *argv[]); void cmd_tpl(int argc, char *argv[]); void cmd_acceleration(int argc, char *argv[]); void cmd_friction(int argc, char *argv[]); void cmd_getpos(int argc, char *argv[]); void cmd_getrot(int argc, char *argv[]); void cmd_setpos(int argc, char *argv[]); void cmd_setrot(int argc, char *argv[]); void cmd_addpos(int argc, char *argv[]); void cmd_addangle(int argc, char *argv[]); void cmd_getfps(int argc, char *argv[]); void cmd_setnclients(int argc, char *argv[]); void cmd_entityreport(int argc, char *argv[]); void cmd_bspreport(int argc, char *argv[]); void cmd_loadplayer(int argc, char *argv[]); // Save a screenshot in an output file int ScreenShot(char *fName, int hideconsole) { unsigned char *fBuffer3 = (unsigned char*) cake_malloc(3*width*height*sizeof(unsigned char), "Main::ScreenShot.fBuffer3"); if (!fBuffer3) return 0; // no memory allocated for image data memset(fBuffer3, 0, 3*width*height*sizeof(unsigned char)); char fBMPName[255]; strncpy(fBMPName, fName, 255); _strlwr(fBMPName); // makes the filename lowercase if (strcmp(&fBMPName[strlen(fBMPName)-4], ".bmp")) // add a ".bmp" extension if not already present sprintf(fBMPName, "%s.bmp", fBMPName); enum_ConsoleStates consolestate = gConsole->GetState(); if (hideconsole) gConsole->SetState(CLOSED); Draw(); glutSwapBuffers(); // read our image data from the frame buffer glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, fBuffer3); // write the image data to a .bmp file if (!WriteBitmapFile(fBMPName, width, height, 3, fBuffer3)) return 0; cake_free(fBuffer3); gConsole->SetState(consolestate); return 1; } // Displays a list of all available resolutions void CheckForAllAvailableResolutions(void) { char resolution[128]; gConsole->Insertln("List of available resolutions :"); gLogFile->OpenFile(); for (int i = 0; i < nwidths; ++i) for (int j = 0; j < nheights; ++j) for (int k = 0; k < ncolors; ++k) for (int l = 0; l < nfreqs; ++l) { sprintf(resolution, "%dx%d:%d@%d", widths[i], heights[j], colors[k], freqs[l]); glutGameModeString(resolution); if (glutGameModeGet(GLUT_GAME_MODE_POSSIBLE)) { gConsole->Insertln("%s ", resolution); } } gLogFile->CloseFile(); } // Toggles the mode fullscreen/windowed void ToggleFullScreen(void) { fullscr = !fullscr; if (fullscr) { backupWidth = width; backupHeight = height; glutFullScreen(); } else { width = backupWidth; height = backupHeight; glutReshapeWindow(width, height); } } //----------------------------------------------------------------------------- // Keyboard // The following functions manage the keyboard. //----------------------------------------------------------------------------- void Keyboard(unsigned char key, int x, int y) { // Console opening/closing if (key == (unsigned char) consoleKey.ivalue) { if (!app->GetWorld()) { beep(); return; } if (gConsole->ToggleState() == OPENING) histLine = 0; lastkey = key; return; } // if console is active and opened, keyboard actions are done in the console if ((gConsole->GetState() == OPEN || gConsole->GetState() == OPENING) && gConsole->isActive) { bool do_return = true; switch (key) { case 13: char ConsoleBufferCommand[CONSOLE_LINELENGTH]; strncpy(ConsoleBufferCommand, gConsole->GetCurrentCommand(), CONSOLE_LINELENGTH); if (strlen(ConsoleBufferCommand) > 0) { histLine = 0; if (!gCommands->ExecuteCommand(ConsoleBufferCommand)) gConsole->Insertln("\"%s\" : ^5Command not found", ConsoleBufferCommand); } break; case 27: if (strlen(gConsole->GetCurrentCommand())) gConsole->ReInitCurrentCommand(); else if (app->GetWorld()) { gConsole->Close(); gConsole->ReInitCurrentCommand(); } else do_return = false; break; case 8: gConsole->DelChar(); break; case 9: if (tabmode) { if (lastkey == key) { if (glutGetModifiers() == GLUT_ACTIVE_SHIFT) gCommands->PrevSolution(); else gCommands->NextSolution(); } else { gCommands->FirstSolution(gConsole->GetCurrentCommand()); } } else { gCommands->CompleteCommand(gConsole->GetCurrentCommand()); } break; default: gConsole->AddChar((char) key); break; } lastkey = key; if (do_return) return; } // if console is not active, keyboard is attached to engine (or clients camera) switch (key) { case 27: if (!app->StopDemo()) Shut(0); break; case 32: // zoom zoom = KEYDOWN; break; case 'a': case 'A': // move left left = KEYDOWN; break; case 'w': case 'W': // move forwards up = KEYDOWN; break; case 'd': case 'D': // move right right = KEYDOWN; break; case 's': case 'S': // move backwards down = KEYDOWN; break; case 'e': case 'E': // move up pgnup = KEYDOWN; break; case 'q': case 'Q': // move down pgndown = KEYDOWN; break; case 'f': case 'F': // toggle fps display gVars->SetKeyValue("cg_drawFPS", 1-gVars->IntForKey("cg_drawFPS")); break; case 't': case 'T': // toggle time display gVars->SetKeyValue("cg_drawtime", 1-gVars->IntForKey("cg_drawtime")); break; case 'G': case 'g': // changes wireframe mode gVars->SetKeyValue("r_grid", 1-gVars->IntForKey("r_grid")); break; case 'B': case 'b': gVars->SetKeyValue("r_showbbox", 1-gVars->IntForKey("r_showbbox")); break; case 'c': case 'C': // toggle clear mode gVars->SetKeyValue("r_clear", 1-gVars->IntForKey("r_clear")); gConsole->Insertln("r_clear value changed to %d", gVars->IntForKey("r_clear")); break; case 'n': case 'N': // change current client (has effect only if clients are unlinked) app->SetCurrentClient((app->GetCurrentClientIndex()+1)%app->GetNumClients()); gConsole->Insertln("Current client : %d", app->GetCurrentClientIndex()); break; case 'p': case 'P': // change start pos for current client if (!app->GetWorld()) break; if (app->GetWorld()->GetNumStartPos()) { if (key == 'P') { currstartpos = (currstartpos-1)%app->GetWorld()->GetNumStartPos(); if (currstartpos < 0) currstartpos = app->GetWorld()->GetNumStartPos()-1; } else currstartpos = (currstartpos+1)%app->GetWorld()->GetNumStartPos(); app->GetWorld()->SetStartPos(app->GetCurrentClient(), currstartpos); gConsole->Insertln("using start pos %d/%d for client %d", currstartpos+1, app->GetWorld()->GetNumStartPos(), app->GetCurrentClientIndex()); } break; case 'm': case 'M': { Client *client = app->GetCurrentClient(); if (client) { client->flying = !client->flying; gConsole->Insertln("client flying state: %s", client->flying?"ON":"OFF"); } } break; default: gConsole->Insertln("%d : invalid key", key); break; } lastkey = key; } //----------------------------------------------------------------------------- // KeyboardUp //----------------------------------------------------------------------------- void KeyboardUp(unsigned char key, int x, int y) { switch (key) { case 'a': case 'A': left = KEYUP; break; case 'w': case 'W': up = KEYUP; break; case 'd': case 'D': right = KEYUP; break; case 's': case 'S': down = KEYUP; break; case 'e': case 'E': pgnup = KEYUP; break; case 'q': case 'Q': pgndown = KEYUP; break; case 32: zoom = KEYUP; break; default: // should not happen break; } } //----------------------------------------------------------------------------- // KeyboardSpec //----------------------------------------------------------------------------- void KeyboardSpec(int key, int x, int y) { // if console is active and onpened if ((gConsole->GetState() == OPEN || gConsole->GetState() == OPENING) && gConsole->isActive) { switch (key) { case GLUT_KEY_UP: ++histLine; if (histLine > gCommands->GetNbrCommHistLines()) { histLine = gCommands->GetNbrCommHistLines(); beep(); } gConsole->SetCurrentCommand(gCommands->GetHistoryLine(histLine)); break; case GLUT_KEY_DOWN: --histLine; if (histLine < 0) { histLine = 0; beep(); } gConsole->SetCurrentCommand(gCommands->GetHistoryLine(histLine)); break; case GLUT_KEY_LEFT: gConsole->MoveCursor(LEFT); break; case GLUT_KEY_RIGHT: gConsole->MoveCursor(RIGHT); break; case GLUT_KEY_HOME: if (glutGetModifiers() == GLUT_ACTIVE_CTRL) gConsole->ScrollConsole(TOP); else gConsole->MoveCursor(C_EXTREM_LEFT); break; case GLUT_KEY_END: if (glutGetModifiers() == GLUT_ACTIVE_CTRL) gConsole->ScrollConsole(BOTTOM); else gConsole->MoveCursor(C_EXTREM_RIGHT); break; case GLUT_KEY_PAGE_UP: gConsole->ScrollConsole(UP); break; case GLUT_KEY_PAGE_DOWN: gConsole->ScrollConsole(DOWN); break; default: // does nothing break; } lastkey = key; return; } histLine = 0; switch (key) { case GLUT_KEY_F4: gCommands->RepeatLastCommand(); break; case 100: left = KEYDOWN; break; case 101: up = KEYDOWN; break; case 102: right = KEYDOWN; break; case 103: down = KEYDOWN; break; case 104: pgnup = KEYDOWN; break; case 105: pgndown = KEYDOWN; break; default: gConsole->Insertln("%d : invalid key", key); break; } lastkey = key; } //----------------------------------------------------------------------------- // KeyboardSpecUp //----------------------------------------------------------------------------- void KeyboardSpecUp(int key, int x, int y) { switch (key) { case 100: left = KEYUP; break; case 101: up = KEYUP; break; case 102: right = KEYUP; break; case 103: down = KEYUP; break; case 104: pgnup = KEYUP; break; case 105: pgndown = KEYUP; break; default: break; } } //----------------------------------------------------------------------------- // MouseClic // Manage the mouse clics. //----------------------------------------------------------------------------- void MouseClic(int button, int state, int x, int y) { if (preview >= 0) { gFramework->shaders.DeleteShader(preview); preview = -1; } switch (button) { case GLUT_LEFT_BUTTON: if (state == GLUT_DOWN) { lButton = true; dx = x; dy = y; } else if (state == GLUT_UP) lButton = false; break; case GLUT_RIGHT_BUTTON: if (state == GLUT_DOWN) { rButton = true; dx = x; dy = y; Client *client = app->GetCurrentClient(); if (client) client->Jump(); } else if (state == GLUT_UP) rButton = false; break; default: break; } } //----------------------------------------------------------------------------- // MouseMove // Clients camera rotation following mouse //----------------------------------------------------------------------------- void MouseMove(int x, int y) { if (lButton && !fullscr) { Client *client = app->GetCurrentClient(); if (client) client->MoveMouseXY((float) (dx-x), (float) (dy-y)); dx = x; dy = y; } else { mousepos.x = x; mousepos.y = y; } } //----------------------------------------------------------------------------- // MouseMovePassive // Updates the mouse x and y position //----------------------------------------------------------------------------- void MouseMovePassive(int x, int y) { mousepos.x = x; mousepos.y = y; } //----------------------------------------------------------------------------- // Draw // Calls the display refresh. //----------------------------------------------------------------------------- static void Draw(void) { if (!width || !height) return; gRender->BeginFrame(); // clears the screen and the z buffer int numclients = app->GetNumClients(); app->DrawWorld(); app->DrawInterface(); if (preview >= 0) { gOver->Quad(preview, width-196, height-156, 156, 128); gFramework->Render(); // used for displaying the gOver with framework shaders (quite tricky, I know !!) } gRender->EndFrame(); // flips the screen and force the flushing glutSwapBuffers(); } //----------------------------------------------------------------------------- // Reshape //----------------------------------------------------------------------------- void Reshape(int w, int h) { if (gLogFile) gLogFile->Insert("reshaping to %dx%d\n", w, h); width = w; height = h; gRender->SetWindowSettings(w, h); if (gConsole) gConsole->Resize(-1, app->GetWorld()?h/2:h); app->InitClients(); Draw(); } //----------------------------------------------------------------------------- // Idle //----------------------------------------------------------------------------- void Idle(void) { Client *client = app->GetCurrentClient(); if (client) { // Updates camera rotation if (fullscr && AutoCenterMouse) { client->MoveMouseXY(invertMouseX.fvalue*(mousepos.x-(float)width /2.f)*mouse_speed.fvalue, invertMouseY.fvalue*(mousepos.y-(float)height/2.f)*mouse_speed.fvalue); glutWarpPointer((int)((float)width/2.f), (int)((float)height/2.f)); } // Updates camera position if (up == KEYDOWN && down == KEYUP) client->MoveForward(); else if (up == KEYUP && down == KEYDOWN) client->MoveBackward(); if (right == KEYDOWN && left == KEYUP) client->MoveRight(); else if (right == KEYUP && left == KEYDOWN) client->MoveLeft(); if (pgnup == KEYDOWN && pgndown == KEYUP) client->MoveUp(); else if (pgnup == KEYUP && pgndown == KEYDOWN) client->MoveDown(); if (zoom == KEYDOWN) client->Zoom(-zoomspeed.fvalue); else if (zoom == KEYUP) client->Zoom(zoomspeed.fvalue); } glutPostRedisplay(); } //----------------------------------------------------------------------------- // Init //----------------------------------------------------------------------------- void Init() { if (!gRender->Init(glutSwapBuffers)) ThrowException(FATAL_ERROR, "Couldn't initialize render !"); gConsole->Insertln("
^6----- Application starts --------------------------------------"); // Initialize the keys up = down = left = right = pgnup = pgndown = zoom = KEYUP; // Set window settings gRender->SetWindowSettings(width, height, colorbits, freq); // Load console shaders and intialize the console gConsole->SetFont(gConsole->shaders.AddShader("gfx/2d/bigchars", 0, 0, FACETYPE_MESH), 16, 16); gConsole->SetBack(gConsole->shaders.AddShader("console", 0, 0, FACETYPE_MESH)); gConsole->Init(); // Load framework shaders gFramework->SetFont(gFramework->shaders.AddShader("gfx/2d/bigchars", 0, 0, FACETYPE_MESH), NORMAL_CHAR); gFramework->SetFont(gFramework->shaders.AddShader("menu/art/font1_prop", 0, 0, FACETYPE_MESH), PROPFONT1_CHAR); gFramework->SetFont(gFramework->shaders.AddShader("menu/art/font1_prop_glo", 0, 0, FACETYPE_MESH), PROPFONT1_GLOW_CHAR); gFramework->SetFont(gFramework->shaders.AddShader("menu/art/font2_prop", 0, 0, FACETYPE_MESH), PROPFONT2_CHAR); gFramework->Init(); if (fullscr) glutWarpPointer((int)((float)width/2.f), (int)((float) height/2.f)); } void ParseArgs(int argc, char *argv[]) { bool displayinfos = true; gConsole->Insertln("Parsing the command line..."); for (int i = 1; i < argc; ++i) { // +map if (!stricmp(argv[i], "+map")) { if (++i >= argc) { gConsole->Insertln("^1Missing argument for \"+map\" command"); displayinfos = true; } else if (argv[i][0] == '+') { gConsole->Insertln("^1Invalid argument for \"+map\" command"); displayinfos = true; } else if (app->LoadMap(argv[i])) displayinfos = false; else displayinfos = true; } // +demo if (!stricmp(argv[i], "+demo")) { int j; for (j = 1; j < argc; ++j) { if (!stricmp(argv[j], "+map")) { gConsole->Insertln("^1You cannot use \"+demo\" and \"+map\" simultaneously; \"+demo\" argument ignored"); displayinfos = true; break; } } if (j >= argc) // if +map not found { if (++i >= argc) { gConsole->Insertln("^1Missing argument for \"+demo\" command"); displayinfos = true; } else if (argv[i][0] == '+') { gConsole->Insertln("^1Invalid argument for \"+demo\" command"); displayinfos = true; } else { // compute last argument for function j = i+1; while (j < argc && argv[j][0] != '+') ++j; cmd_demo(j-i+1, argv+i-1); // the keyword 'demo' must be included displayinfos = false; } } } } if (displayinfos) { setBGMusic(DEFAULT_MUSIC); // Load a default music gConsole->Insertln("^2You can get a list of available maps with command \"bsplist\"."); gConsole->Insertln("^2Map can be loaded with command \"load mapname\"."); gConsole->Insertln("^2Commands names are displayed with \"cmdlist\"."); gConsole->Insertln("^2Variables names are displayed with \"varlist\"."); gConsole->SetState(OPEN); } } //----------------------------------------------------------------------------- // Shut //----------------------------------------------------------------------------- void Shut(int status) { gConsole->Insertln("
^6----- Application shuting down --------------------------------"); // Unregistering variables gVars->UnregisterVar(invertMouseX); gVars->UnregisterVar(invertMouseY); gVars->UnregisterVar(mouse_speed); gVars->UnregisterVar(zoomspeed); gVars->UnregisterVar(consoleKey); app->Shut(); delete app; if (fullscr) glutLeaveGameMode(); else glutDestroyWindow(window_index); exit(status); } //----------------------------------------------------------------------------- // main // Creates the window and the application //----------------------------------------------------------------------------- int main(int argc, char *argv[]) { glutInit(&argc, argv); // Creates the application. It is important to create it very early in the // code because it reads the "config.ini" file, register variables, read // available packages, etc. app = new App; if (!app) ThrowException(ALLOCATION_ERROR, "Couldn't create the application"); RegisterVariables(); AddCommands(); app->Init(); // Get window sizes from variables (initialized with "config.ini" values) width = gVars->IntForKey("v_width"); height = gVars->IntForKey("v_height"); toppos = gVars->IntForKey("v_top"); leftpos = gVars->IntForKey("v_left"); freq = gVars->IntForKey("v_hz"); colorbits = gVars->IntForKey("v_colorBits"); fullscr = (gVars->IntForKey("v_fullscreen"))?true:false; // Creates the window if (fullscr) { char resolution[128]; sprintf(resolution, "%dx%d:%d@%d", width, height, colorbits, freq); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); glutGameModeString(resolution); glutEnterGameMode(); glutSetCursor(GLUT_CURSOR_NONE); } else { glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); glutInitWindowSize(width, height); glutInitWindowPosition(leftpos, toppos); window_index = glutCreateWindow(_VERSION_); } glutReshapeFunc(Reshape); glutDisplayFunc(Draw); glutKeyboardFunc(Keyboard); glutKeyboardUpFunc(KeyboardUp); glutSpecialUpFunc(KeyboardSpecUp); glutSpecialFunc(KeyboardSpec); glutMouseFunc(MouseClic); glutMotionFunc(MouseMove); glutPassiveMotionFunc(MouseMovePassive); glutIdleFunc(Idle); // Initialize resting values Init(); // Change the engine mode from initialization to running mode app->Run(); // Parse the command arguments ParseArgs(argc, argv); // runs the main loop glutMainLoop(); return 0; } void RegisterVariables(void) { gVars->RegisterVar(invertMouseX); gVars->RegisterVar(invertMouseY); gVars->RegisterVar(mouse_speed); gVars->RegisterVar(zoomspeed); gVars->RegisterVar(consoleKey); } //----------------------------------------------------------------------------- // Commands // It is possible to set commands that can be executed from the console // during engine running. It is very useful for debugging or setting // evenments during execution. Commands have all the same prototype: // void commandname(int argc, char *argv[]) // like the main function. //----------------------------------------------------------------------------- // Quit the application void cmd_quit(int argc, char *argv[]) { Shut(0); } // Load a map void cmd_load(int argc, char *argv[]) { if (argc > 1) { if (app->LoadMap(argv[1])) { gConsole->Resize(-1, height/2); } else { setBGMusic(DEFAULT_MUSIC); // Load a default music } } else gConsole->Insertln("usage: %s ", argv[0]); } // Reload the current map void cmd_reload(int argc, char *argv[]) { if (app->ReloadMap()) { gConsole->Resize(-1, height/2); } else { setBGMusic(DEFAULT_MUSIC); // Load a default music } } void cmd_defineviewport(int argc, char *argv[]) { if (argc > 5) { Client *client = app->GetClient(atoi(argv[1])); if (client) client->Init(atoi(argv[2]), atoi(argv[3]), atoi(argv[4]), atoi(argv[5])); else gConsole->Insertln("^1Invalid client index"); } else gConsole->Insertln("usage: %s "); } void cmd_noclip(int argc, char *argv[]) { int currclient = app->GetCurrentClientIndex(); if (currclient < 0) { gConsole->Insert("^1No available client"); return; } app->GetClient(currclient)->noclip = !app->GetClient(currclient)->noclip; gConsole->Insertln("noclip %s for client %d", app->GetClient(currclient)->noclip?"ON":"OFF", currclient); } void cmd_lockfrustum(int argc, char *argv[]) { int currclient = app->GetCurrentClientIndex(); if (currclient < 0) { gConsole->Insert("^1No available client"); return; } app->GetClient(currclient)->cam.lockfrustum = !app->GetClient(currclient)->cam.lockfrustum; gConsole->Insertln("frustum lock %s for client %d", app->GetClient(currclient)->cam.lockfrustum?"ON":"OFF", currclient); } // Unload the current map void cmd_unload(int argc, char *argv[]) { app->UnloadMap(); setBGMusic(DEFAULT_MUSIC); // Load a default music } void cmd_record(int argc, char *argv[]) { app->RecordDemo((argc>1)?(float)atof(argv[1]):0.1f); } void cmd_stopdemo(int argc, char *argv[]) { if (argc > 1) app->StopDemo(argv[1]); else app->StopDemo(); } void cmd_demo(int argc, char *argv[]) { if (argc > 1) { int i; bool looping = false; for (i = 2; i < argc; ++i) { // get last valid value if (!stricmp(argv[i], "loop")) looping = true; } enum_InterpolationMode mode = AUTO_INTERPOLATION; for (i = 2; i < argc; ++i) { // get last valid value if (!stricmp(argv[i], "linear")) mode = LINEAR_INTERPOLATION; else if (!stricmp(argv[i], "spline")) mode = SPLINE_INTERPOLATION; } app->PlayDemo(argv[1], looping, mode); } else gConsole->Insertln("usage: %s {\"loop\"} {\"linear\", \"spline\"}", argv[0]); } void cmd_demodump(int argc, char *argv[]) { if (argc > 1) { Demo demo; demo.DemoDump(argv[1], (argc > 2)?atol(argv[2]):0); } } void cmd_shaderpreview(int argc, char *argv[]) { if (argc > 1) { if (app->GetWorld()) { preview = gFramework->shaders.AddShader(argv[1], 0, 0, FACETYPE_MESH); gFramework->Update(); } else gConsole->Insertln("^6Some shaders require camera position. Camera is created when " "map is loaded, so load a map to be able to preview shaders."); } } // Display available resolutions void cmd_resolutions(int argc, char *argv[]) { CheckForAllAvailableResolutions(); } // Save a screenshot of current scene (without console) void cmd_screenshot(int argc, char *argv[]) { if (argc > 1) { if (!ScreenShot(argv[1])) gConsole->Insertln("^5!! An error occured while trying to save screenshot bitmap."); } else gConsole->Insertln("usage: %s ", argv[0]); } // Change the fontsize void cmd_fontsize (int argc, char *argv[]) { if (argc < 3) return; gConsole->SetFontSize(atol(argv[1]), atol(argv[2])); } // Sets the tabulation key mode for console void cmd_tabmode (int argc, char *argv[]) { if (argc > 1) { if (!strcmp(argv[1], "0")) tabmode = 0; else tabmode = 1; } } // Toggles the mouse auto center mode void cmd_togglemousecenter (int argc, char *argv[]) { AutoCenterMouse = !AutoCenterMouse; } // Displays a preview (levelshot) of an available map void cmd_preview (int argc, char *argv[]) { if (argc > 1) { char levelshot_name[256] = { '\0' }; sprintf(levelshot_name, "levelshots/%s", argv[1]); preview = gFramework->shaders.AddShader(levelshot_name, 0, 0, FACETYPE_MESH); gFramework->Update(); } } // Displays credits void cmd_credits(int argc, char *argv[]) { gConsole->Insertln("^5Credits:"); gConsole->Insertln("^2Base engine: TITAN PROJECT - Ignacio Castano Aguado"); gConsole->Insertln("^2Addons and new elements: morbac"); gConsole->Insertln("^2With special thanks to: Kaspar, Max, and all cool guys who make demos and tutorials on the web :)"); } void cmd_speed(int argc, char *argv[]) { Client *client = app->GetCurrentClient(); if (!client) { gConsole->Insert("^1No available client"); return; } if (argc > 1) client->max_speed = (float) atof(argv[1]); else gConsole->Insertln("Client speed: %f", app->GetCurrentClient()->max_speed); } void cmd_fov(int argc, char *argv[]) { Client *client = app->GetCurrentClient(); if (!client) { gConsole->Insert("^1No available client"); return; } if (argc > 1) { client->fov = (float) atof(argv[1]); client->UpdateCam(); } else gConsole->Insertln("FOV : %f", client->fov); } void cmd_zoomlimit(int argc, char *argv[]) { Client *client = app->GetCurrentClient(); if (!client) { gConsole->Insert("^1No available client"); return; } if (argc > 1) { client->zoomlimit = (float) atof(argv[1]); } else gConsole->Insertln("zoom limit : %f", client->zoomlimit); } void cmd_tpl(int argc, char *argv[]) { Client *client = app->GetCurrentClient(); if (!client) { gConsole->Insert("^1No available client"); return; } client->pitchLimit = !client->pitchLimit; } void cmd_acceleration(int argc, char *argv[]) { Client *client = app->GetCurrentClient(); if (!client) { gConsole->Insert("^1No available client"); return; } if (argc > 1) client->acceleration = (float) atof(argv[1]); else gConsole->Insertln("Client acceleration value: %f", client->acceleration); } void cmd_friction(int argc, char *argv[]) { Client *client = app->GetCurrentClient(); if (!client) { gConsole->Insert("^1No available client"); return; } if (argc > 1) client->friction = (float) atof(argv[1]); else gConsole->Insertln("Client friction value: %f", client->friction); } void cmd_getpos(int argc, char *argv[]) { Client *client = app->GetCurrentClient(); if (!client) { gConsole->Insert("^1No available client"); return; } gConsole->Insertln("Client position : [%f;%f;%f]", client->cam.pos[0], client->cam.pos[1], client->cam.pos[2]); } void cmd_getrot(int argc, char *argv[]) { Client *client = app->GetCurrentClient(); if (!client) { gConsole->Insert("^1No available client"); return; } gConsole->Insertln("Client angle : [%f;%f;%f]", client->cam.rot[PITCH], client->cam.rot[YAW], client->cam.rot[ROLL]); } void cmd_setpos(int argc, char *argv[]) { if (argc > 3) { Client *client = app->GetCurrentClient(); if (!client) { gConsole->Insert("^1No available client"); return; } client->SetPos((float) atof(argv[1]), (float) atof(argv[2]), (float) atof(argv[3])); } else gConsole->Insertln("usage: %s ", argv[0]); } void cmd_setrot(int argc, char *argv[]) { if (argc > 3) { Client *client = app->GetCurrentClient(); if (!client) { gConsole->Insert("^1No available client"); return; } client->SetAngle((float) atof(argv[1]), (float) atof(argv[2]), (float) atof(argv[3])); } else gConsole->Insertln("usage: %s ", argv[0]); } void cmd_addpos(int argc, char *argv[]) { if (argc > 3) { Client *client = app->GetCurrentClient(); if (!client) { gConsole->Insert("^1No available client"); return; } client->AddPos((float) atof(argv[1]), (float) atof(argv[2]), (float) atof(argv[3])); } else if (argc > 2) { Client *client = app->GetCurrentClient(); if (!client) { gConsole->Insert("^1No available client"); return; } client->AddPos((float) atof(argv[1]), (float) atof(argv[2]), 0); } else if (argc > 1) { Client *client = app->GetCurrentClient(); if (!client) { gConsole->Insert("^1No available client"); return; } client->AddPos((float) atof(argv[1]), 0, 0); } else gConsole->Insertln("usage: %s ", argv[0]); } void cmd_addangle(int argc, char *argv[]) { if (argc > 3) { Client *client = app->GetCurrentClient(); if (!client) { gConsole->Insert("^1No available client"); return; } client->AddAngle((float) atof(argv[1]), (float) atof(argv[2]), (float) atof(argv[3])); } if (argc > 2) { Client *client = app->GetCurrentClient(); if (!client) { gConsole->Insert("^1No available client"); return; } client->AddAngle((float) atof(argv[1]), (float) atof(argv[2]), 0); } if (argc > 1) { Client *client = app->GetCurrentClient(); if (!client) { gConsole->Insert("^1No available client"); return; } client->AddAngle((float) atof(argv[1]), 0, 0); } else gConsole->Insertln("usage: %s ", argv[0]); } void cmd_getfps(int argc, char *argv[]) { gConsole->Insertln("%4.2f fps", app->GetFPS()); } void cmd_setnclients(int argc, char *argv[]) { if (argc > 1) { int numclients = atol(argv[1]); // Create the clients if (numclients <= 0) numclients = 1; app->CreateClients(numclients); if ((nstartpos = app->GetWorld()->GetNumStartPos())) { currstartpos = 0; for (int i = 0; i < numclients; ++i) { app->GetWorld()->SetStartPos(app->GetClient(i), currstartpos); currstartpos = (currstartpos+1)%nstartpos; } } } else gConsole->Insertln("usage: %s ", argv[0]); } void cmd_entityreport(int argc, char *argv[]) { if (app->GetWorld()) app->GetWorld()->GetBSP()->GetEntities()->Report(); else gConsole->Insertln("^1No world !"); } void cmd_bspreport(int argc, char *argv[]) { if (app->GetWorld()) app->GetWorld()->GetBSP()->Report(); else gConsole->Insertln("^1No world !"); } void cmd_loadplayer(int argc, char *argv[]) { if (!app->GetNumClients()) { gConsole->Insertln("^5WARNING: No available client !"); return; } if (argc > 1) { app->GetCurrentClient()->LoadPlayer(argv[1]); } else gConsole->Insertln("usage: %s ", argv[0]); } // Add the commands to the engine commands list void AddCommands(void) { gCommands->AddCommand("quit", cmd_quit, "exit the application"); gAlias->SetAlias("exit", "quit"); gCommands->AddCommand("map", cmd_load, "load a bsp map"); gAlias->SetAlias("load", "map"); gCommands->AddCommand("map_restart", cmd_reload, "reload the current map"); gAlias->SetAlias("reload", "map_restart"); gCommands->AddCommand("unload", cmd_unload, "unload the current map"); gCommands->AddCommand("noclip", cmd_noclip, "toggle the collisions for clients"); gCommands->AddCommand("lockfrustum", cmd_lockfrustum, "loks the frustum for clients"); gCommands->AddCommand("record", cmd_record, "start recording a demo"); gCommands->AddCommand("stopdemo", cmd_stopdemo, "stop recording a demo"); gCommands->AddCommand("demo", cmd_demo, "play recorded demo"); gCommands->AddCommand("demodump", cmd_demodump, "dump demo file content"); gCommands->AddCommand("preview", cmd_preview, "displays the levelshot of a map (if it exists)"); gCommands->AddCommand("shaderpreview", cmd_shaderpreview, "display a sample of shader"); gCommands->AddCommand("fontsize", cmd_fontsize, "sets the font size"); gCommands->AddCommand("tabmode", cmd_tabmode, "sets the current tabulation key comportement"); gCommands->AddCommand("togglemousecenter", cmd_togglemousecenter, "toggles the mouse autocentering"); gAlias->SetAlias("tmc", "togglemousecenter"); gCommands->AddCommand("credits", cmd_credits, "displays the engine and test program credits"); gCommands->AddCommand("speed", cmd_speed, "defines the moving speed of camera"); gCommands->AddCommand("fov", cmd_fov, "defines the camera fov"); gCommands->AddCommand("zoomlimit", cmd_zoomlimit, "defines the camera zoom limit"); gCommands->AddCommand("togglepitchlimit", cmd_tpl, "toggles the camera rotation limitation on Ox axis"); gAlias->SetAlias("tpl", "togglepitchlimit"); gCommands->AddCommand("accel", cmd_acceleration, "defines the acceleration value of client"); gCommands->AddCommand("friction", cmd_friction, "defines the friction value of client"); gCommands->AddCommand("getpos", cmd_getpos, "gets the current camera position"); gCommands->AddCommand("setpos", cmd_setpos, "sets the current camera position"); gCommands->AddCommand("addpos", cmd_addpos, "increments the current client camera position"); gCommands->AddCommand("getrot", cmd_getrot, "gets the current rotation angle"); gCommands->AddCommand("setrot", cmd_setrot, "sets the current rotation angle"); gCommands->AddCommand("addangle", cmd_addangle, "increments the current client camera angle"); gCommands->AddCommand("getfps", cmd_getfps, "returns the current fps rate"); gCommands->AddCommand("setnclients", cmd_setnclients, "sets the number of clients"); gCommands->AddCommand("resolutions", cmd_resolutions, "displays a list of all available screen resolution"); gCommands->AddCommand("screenshot", cmd_screenshot, "takes a screenshot of current window"); gCommands->AddCommand("entityreport", cmd_entityreport, "writes a report on entities in logfile"); gCommands->AddCommand("bspreport", cmd_bspreport, "writes a report on bsp in logfile"); gCommands->AddCommand("defineviewport", cmd_defineviewport, "define the viewport for a client"); gCommands->AddCommand("loadplayer", cmd_loadplayer, "load player skin, sounds, etc."); }