home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2007 September / maximum-cd-2007-09.iso / Assets / data / AssaultCube_v0.93.exe / source / src / main.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2007-06-02  |  13.3 KB  |  444 lines

  1. // main.cpp: initialisation & main loop
  2.  
  3. #include "cube.h"
  4.  
  5. void cleanup(char *msg)         // single program exit point;
  6. {
  7.     stop();
  8.     abortconnect();
  9.     disconnect(1);
  10.     cleangl();
  11.     cleansound();
  12.     cleanupserver();
  13.     SDL_ShowCursor(1);
  14.     if(msg)
  15.     {
  16.         #ifdef WIN32
  17.         MessageBox(NULL, msg, "cube fatal error", MB_OK|MB_SYSTEMMODAL);
  18.         #else
  19.         printf(msg);
  20.         #endif
  21.     }
  22.     SDL_Quit();
  23. }
  24.  
  25. void quit()                     // normal exit
  26. {
  27.     writeservercfg();
  28.     writecfg();
  29.     cleanup(NULL);
  30.     exit(EXIT_SUCCESS);
  31. }
  32.  
  33. void fatal(char *s, char *o)    // failure exit
  34. {
  35.     s_sprintfd(msg)("%s%s (%s)\n", s, o, SDL_GetError());
  36.     cleanup(msg);
  37.     exit(EXIT_FAILURE);
  38. }
  39.  
  40. int scr_w = 1024;
  41. int scr_h = 768;
  42. int VIRTW;
  43.  
  44. void screenshot(char *imagepath)
  45. {
  46.     SDL_Surface *image = SDL_CreateRGBSurface(SDL_SWSURFACE, scr_w, scr_h, 24, 0x0000FF, 0x00FF00, 0xFF0000, 0);
  47.     if(!image) return;
  48.     uchar *tmp = new uchar[scr_w*scr_h*3];
  49.     glPixelStorei(GL_PACK_ALIGNMENT, 1);
  50.     glReadPixels(0, 0, scr_w, scr_h, GL_RGB, GL_UNSIGNED_BYTE, tmp);
  51.     uchar *dst = (uchar *)image->pixels;
  52.     loopi(scr_h)
  53.     {
  54.         memcpy(dst, &tmp[3*scr_w*(scr_h-i-1)], 3*scr_w);
  55.         endianswap(dst, 3, scr_w);
  56.         dst += image->pitch;
  57.     }
  58.     delete[] tmp;
  59.     if(!imagepath[0])
  60.     {
  61.         static string buf;
  62.         s_sprintf(buf)("screenshots/screenshot_%d.bmp", lastmillis);
  63.         imagepath = buf;
  64.     }
  65.     SDL_SaveBMP(image, path(imagepath));
  66.     SDL_FreeSurface(image);
  67. }
  68.  
  69. COMMAND(screenshot, ARG_1STR);
  70. COMMAND(quit, ARG_NONE);
  71.  
  72. SDL_Surface *screen = NULL;
  73.  
  74. extern void setfullscreen(bool enable);
  75.  
  76. VARF(fullscreen, 0, 0, 1, setfullscreen(fullscreen!=0));
  77.  
  78. void setfullscreen(bool enable)
  79. {
  80.     if(enable == !(screen->flags&SDL_FULLSCREEN))
  81.     {
  82. #if defined(WIN32) || defined(__APPLE__)
  83.         conoutf("\"fullscreen\" variable not supported on this platform. Use the -t command-line option.");
  84.         fullscreen = !enable;
  85. #else
  86.         SDL_WM_ToggleFullScreen(screen);
  87.         SDL_WM_GrabInput((screen->flags&SDL_FULLSCREEN) ? SDL_GRAB_ON : SDL_GRAB_OFF);
  88. #endif
  89.     }
  90. }
  91.  
  92. void screenres(int w, int h, int bpp = 0)
  93. {
  94. #if defined(WIN32) || defined(__APPLE__)
  95.     conoutf("\"screenres\" command not supported on this platform. Use the -w and -h command-line options.");
  96. #else
  97.     SDL_Surface *surf = SDL_SetVideoMode(w, h, bpp, SDL_OPENGL|SDL_RESIZABLE|(screen->flags&SDL_FULLSCREEN));
  98.     if(!surf) return;
  99.     scr_w = w;
  100.     scr_h = h;
  101.     VIRTW = scr_w*VIRTH/scr_h;
  102.     screen = surf;
  103.     glViewport(0, 0, w, h);
  104. #endif
  105. }
  106. #if defined(WIN32) || defined(__APPLE__) || !defined(WIN32)
  107. void setresdata(char *s, enet_uint32 c)
  108. {
  109.     extern hashtable<char *, enet_uint32> &resdata;
  110.     resdata[newstring(s)] = c;
  111. }
  112. #endif
  113.  
  114. COMMAND(screenres, ARG_3INT);
  115.  
  116. VARFP(gamma, 30, 100, 300,
  117. {
  118.     float f = gamma/100.0f;
  119.     if(SDL_SetGamma(f,f,f)==-1)
  120.     {
  121.         conoutf("Could not set gamma (card/driver doesn't support it?)");
  122.         conoutf("sdl: %s", SDL_GetError());
  123.     }
  124. });
  125.  
  126. VARP(maxfps, 5, 200, 500);
  127.  
  128. void limitfps(int &millis, int curmillis)
  129. {
  130.     static int fpserror = 0;
  131.     int delay = 1000/maxfps - (millis-curmillis);
  132.     if(delay < 0) fpserror = 0;
  133.     else
  134.     {
  135.         fpserror += 1000%maxfps;
  136.         if(fpserror >= maxfps)
  137.         {
  138.             ++delay;
  139.             fpserror -= maxfps;
  140.         }
  141.         if(delay > 0)
  142.         {
  143.             SDL_Delay(delay);
  144.             millis += delay;
  145.         }
  146.     }
  147. }
  148.  
  149. int lowfps = 30, highfps = 40;
  150.  
  151. void fpsrange(int low, int high)
  152. {
  153.     if(low>high || low<1) return;
  154.     lowfps = low;
  155.     highfps = high;
  156. }
  157.  
  158. COMMAND(fpsrange, ARG_2INT);
  159.  
  160. void keyrepeat(bool on)
  161. {
  162.     SDL_EnableKeyRepeat(on ? SDL_DEFAULT_REPEAT_DELAY : 0,
  163.                              SDL_DEFAULT_REPEAT_INTERVAL);
  164. }
  165.  
  166. VARF(gamespeed, 10, 100, 1000, if(multiplayer()) gamespeed = 100);
  167.  
  168. int main(int argc, char **argv)
  169. {    
  170.     bool dedicated = false;
  171.     int fs = SDL_FULLSCREEN, depth = 0, bpp = 0, fsaa = 0, vsync = -1, par = 0, uprate = 0, maxcl = DEFAULTCLIENTS, scthreshold = -5;
  172.     char *sdesc = "", *ip = "", *master = NULL, *passwd = "", *maprot = NULL, *adminpwd = NULL, *srvmsg = NULL;
  173.  
  174.     #define initlog(s) puts("init: " s)
  175.     initlog("sdl");
  176.     
  177.     for(int i = 1; i<argc; i++)
  178.     {
  179.         char *a = &argv[i][2];
  180.         if(argv[i][0]=='-') switch(argv[i][1])
  181.         {
  182.             case 'd': dedicated = true; break;
  183.             case 't': fs     = 0; break;
  184.             case 'w': scr_w  = atoi(a); break;
  185.             case 'h': scr_h  = atoi(a); break;
  186.             case 'z': depth = atoi(a); break;
  187.             case 'b': bpp = atoi(a); break;
  188.             case 'a': fsaa = atoi(a); break;
  189.             case 'v': vsync = atoi(a); break;
  190.             case 'u': uprate = atoi(a); break;
  191.             case 'n': sdesc  = a; break;
  192.             case 'i': ip     = a; break;
  193.             case 'm': master = a; break;
  194.             case 'p': passwd = a; break;
  195.             case 'r': maprot = a; break; 
  196.             case 'x' : adminpwd = a; break;
  197.             case 'c': maxcl  = atoi(a); break;
  198.             case 'o': srvmsg = a; break;
  199.             case 'k': scthreshold = atoi(a); break;
  200.             default:  conoutf("unknown commandline option");
  201.         }
  202.         else conoutf("unknown commandline argument");
  203.     }
  204.     
  205.     #ifdef _DEBUG
  206.     par = SDL_INIT_NOPARACHUTE;
  207.     fs = 0;
  208.     #endif
  209.  
  210.     if(SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO|par)<0) fatal("Unable to initialize SDL");
  211.  
  212.     initlog("net");
  213.     if(enet_initialize()<0) fatal("Unable to initialise network module");
  214.  
  215.     initclient();
  216.     initserver(dedicated, uprate, sdesc, ip, master, passwd, maxcl, maprot, adminpwd, srvmsg, scthreshold);  // never returns if dedicated
  217.       
  218.     initlog("world");
  219.     empty_world(7, true);
  220.  
  221.     initlog("video: sdl");
  222.     if(SDL_InitSubSystem(SDL_INIT_VIDEO)<0) fatal("Unable to initialize SDL Video");
  223.  
  224.     initlog("video: mode");
  225.     SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
  226.     if(depth) SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, depth);
  227.     if(fsaa)
  228.     {
  229.         SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
  230.         SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, fsaa);
  231.     }
  232.     if(vsync>=0) SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, vsync);
  233.  
  234.     int resize = SDL_RESIZABLE;
  235.     #if defined(WIN32) || defined(__APPLE__)
  236.     resize = 0;
  237.     #endif
  238.     SDL_Rect **modes = SDL_ListModes(NULL, SDL_OPENGL|resize|fs);
  239.     if(modes && modes!=(SDL_Rect **)-1)
  240.     {
  241.         bool hasmode = false;
  242.         for(int i = 0; modes[i]; i++)
  243.         {
  244.             if(scr_w <= modes[i]->w && scr_h <= modes[i]->h) { hasmode = true; break; }
  245.         }
  246.         if(!hasmode) { scr_w = modes[0]->w; scr_h = modes[0]->h; }
  247.     }
  248.     screen = SDL_SetVideoMode(scr_w, scr_h, bpp, SDL_OPENGL|resize|fs);
  249.     if(screen==NULL) fatal("Unable to create OpenGL screen");
  250.     fullscreen = fs!=0;
  251.     VIRTW = scr_w*VIRTH/scr_h;
  252.  
  253.     initlog("video: misc");
  254.     SDL_WM_SetCaption("AssaultCube", NULL);
  255.     #ifndef WIN32
  256.     if(fs)
  257.     #endif
  258.     SDL_WM_GrabInput(SDL_GRAB_ON);
  259.     keyrepeat(false);
  260.     SDL_ShowCursor(0);
  261.  
  262.     initlog("console");
  263.     if(!execfile("config/font.cfg")) fatal("cannot find font definitions");
  264.     if(!setfont("default")) fatal("no default font specified");
  265.  
  266.     initlog("gl");
  267.     gl_init(scr_w, scr_h, bpp, depth, fsaa);
  268.  
  269.     crosshair = textureload("packages/misc/crosshairs/default.png");
  270.     if(!crosshair) fatal("could not find core textures (hint: run AssaultCube from the parent of the bin directory)");
  271.  
  272.     loadingscreen();
  273.  
  274.     particleinit();
  275.  
  276.     initlog("sound");
  277.     initsound();
  278.  
  279.     initlog("cfg");
  280.     extern void *scoremenu, *teammenu, *ctfmenu, *servmenu, *kickmenu, *banmenu, *forceteammenu, *givemastermenu, *docmenu;
  281.     scoremenu = addmenu("score", "frags\tdeath\tpj\tping\tname\tcn", false, renderscores);
  282.     teammenu = addmenu("team score", "frags\tdeath\tpj\tping\tteam\tname\tcn", false, renderscores);
  283.     ctfmenu = addmenu("ctf score", "flags\tfrags\tdeath\tpj\tping\tteam\tname\tcn", false, renderscores);
  284.     servmenu = addmenu("server", "ping\tplr\tserver", true, refreshservers);
  285.     kickmenu = addmenu("kick player", NULL, true, refreshsopmenu);
  286.     banmenu = addmenu("ban player", NULL, true, refreshsopmenu);
  287.     forceteammenu = addmenu("force team", NULL, true, refreshsopmenu);
  288.     givemastermenu = addmenu("give master", NULL, true, refreshsopmenu);
  289.     docmenu = addmenu("reference", NULL, true, renderdocmenu);
  290.  
  291.     persistidents = false;
  292.     exec("config/keymap.cfg");
  293.     exec("config/menus.cfg");
  294.     exec("config/prefabs.cfg");
  295.     exec("config/sounds.cfg");
  296.     exec("config/securemaps.cfg");
  297.     execfile("config/servers.cfg");
  298.     persistidents = true;
  299.  
  300.     static char resdata[] = { 112, 97, 99, 107, 97, 103, 101, 115, 47, 116, 101, 120, 116, 117, 114, 101, 115, 47, 107, 117, 114, 116, 47, 107, 108, 105, 116, 101, 50, 46, 106, 112, 103, 0 };
  301.     gzFile f = gzopen(resdata, "rb9");
  302.     if(f)
  303.     {
  304.         int n;
  305.         gzread(f, &n, sizeof(int));
  306.         endianswap(&n, sizeof(int), 1);
  307.         loopi(n)
  308.         {
  309.             string s;
  310.             gzread(f, s, sizeof(string));
  311.             enet_uint32 c;
  312.             gzread(f, &c, sizeof(enet_uint32));
  313.             setresdata(s, c);
  314.         }
  315.         gzclose(f);
  316.     }
  317.  
  318.     if(!execfile("config/saved.cfg")) exec("config/defaults.cfg");
  319.     execfile("config/autoexec.cfg");
  320.  
  321.     initlog("models");
  322.     preload_playermodels();
  323.     preload_hudguns();
  324.     preload_entmodels();
  325.  
  326.     initlog("docs");
  327.     execfile("config/docs.cfg");
  328.  
  329.     initlog("localconnect");
  330.     localconnect();
  331.     changemap("maps/ac_complex");
  332.    
  333.     initlog("mainloop");
  334.     int ignore = 5, grabmouse = 0;
  335. #ifdef _DEBUG
  336.     int lastflush = 0;
  337. #endif
  338.     for(;;)
  339.     {
  340.         static int curmillis = 0, frames = 0;
  341.         static float fps = 10.0f;
  342.         int millis = SDL_GetTicks();
  343.         limitfps(millis, curmillis);
  344.         int elapsed = millis-curmillis;
  345.         curtime = elapsed*gamespeed/100;
  346.         if(curtime>200) curtime = 200;
  347.         else if(curtime<1) curtime = 1;
  348.  
  349.         cleardlights();
  350.  
  351.         if(demoplayback && demopaused)
  352.         {
  353.             curtime = 0;
  354.             millis = lastmillis;
  355.         }
  356.         else if(lastmillis) updateworld(curtime, lastmillis);
  357.  
  358.         lastmillis += curtime;
  359.         curmillis = millis;
  360.  
  361.         if(!demoplayback) serverslice((int)time(NULL), 0);
  362.  
  363.         frames++;
  364.         fps = (1000.0f/elapsed+fps*10)/11;
  365.  
  366.         computeraytable(camera1->o.x, camera1->o.y);
  367.         if(frames>4) SDL_GL_SwapBuffers();
  368.         extern void updatevol(); updatevol();
  369.         if(frames>3) gl_drawframe(scr_w, scr_h, fps<lowfps ? fps/lowfps : (fps>highfps ? fps/highfps : 1.0f), fps);
  370.         //SDL_Delay(100);
  371.         SDL_Event event;
  372.         int lasttype = 0, lastbut = 0;
  373.         while(SDL_PollEvent(&event))
  374.         {
  375.             switch(event.type)
  376.             {
  377.                 case SDL_QUIT:
  378.                     break;
  379.  
  380.                 #if !defined(WIN32) && !defined(__APPLE__)
  381.                 case SDL_VIDEORESIZE:
  382.                     screenres(event.resize.w, event.resize.h);
  383.                     break;
  384.                 #endif
  385.  
  386.                 case SDL_KEYDOWN: 
  387.                 case SDL_KEYUP: 
  388.                     keypress(event.key.keysym.sym, event.key.state==SDL_PRESSED, event.key.keysym.unicode);
  389.                     break;
  390.  
  391.                 case SDL_ACTIVEEVENT:
  392.                     if(event.active.state & SDL_APPINPUTFOCUS)
  393.                         grabmouse = event.active.gain;
  394.                     else
  395.                     if(event.active.gain)
  396.                         grabmouse = 1;
  397.                     break;
  398.  
  399.                 case SDL_MOUSEMOTION:
  400.                     if(ignore) { ignore--; break; }
  401.                     if(!(screen->flags&SDL_FULLSCREEN) && grabmouse)
  402.                     {
  403.                         #ifdef __APPLE__
  404.                         if(event.motion.y == 0) break;  //let mac users drag windows via the title bar
  405.                         #endif
  406.                         if(event.motion.x == scr_w / 2 && event.motion.y == scr_h / 2) break;
  407.                         SDL_WarpMouse(scr_w / 2, scr_h / 2);
  408.                     }
  409.                     #ifndef WIN32
  410.                     if((screen->flags&SDL_FULLSCREEN) || grabmouse)
  411.                     #endif
  412.                     mousemove(event.motion.xrel, event.motion.yrel);
  413.                     break;
  414.  
  415.                 case SDL_MOUSEBUTTONDOWN:
  416.                 case SDL_MOUSEBUTTONUP:
  417.                     if(lasttype==event.type && lastbut==event.button.button) break; // why?? get event twice without it
  418.                     keypress(-event.button.button, event.button.state!=0, 0);
  419.                     lasttype = event.type;
  420.                     lastbut = event.button.button;
  421.                     break;
  422.             }
  423.         }
  424. #ifdef _DEBUG
  425.         if(millis>lastflush+60000) { 
  426.             fflush(stdout); lastflush = millis; 
  427.         }
  428. #endif
  429.     }
  430.     quit();
  431.     return EXIT_SUCCESS;
  432. }
  433.  
  434. void loadcrosshair(char *c)
  435. {
  436.     s_sprintfd(p)("packages/misc/crosshairs/%s", c);
  437.     crosshair = textureload(p);
  438. }
  439.  
  440. COMMAND(loadcrosshair, ARG_1STR);
  441.  
  442. VAR(version, 1, AC_VERSION, 0);
  443.  
  444.