main.c

Go to the documentation of this file.
00001 
00024 #define _USE_MATH_DEFINES
00025 #ifdef WIN32
00026 #define WIN32_LEAN_AND_MEAN
00027 #include <winsock2.h>
00028 #include <fcntl.h>
00029 #include <io.h>
00030 #include <sys/stat.h>
00031 #endif
00032 #ifdef USE_AUDIO
00033 #include "audio.h"
00034 #endif
00035 #include "color.h"
00036 #include "iothread.h"
00037 #include "tanksprite.h"
00038 #include "game.h"
00039 #include "gameconfig.h"
00040 #include "net.h"
00041 #include "random.h"
00042 #include "states.h"
00043 #include "menustate.h"
00044 #include <SDL_ttf.h>
00045 #include <stdlib.h>
00046 #include <string.h>
00047 #include <memory.h>
00048 
00049 extern Uint32 videoFlags;
00050 
00051 SDL_Joystick *stick = NULL;
00052 
00057 static Sint32 elapsedTime;
00058 
00063 Uint32 frameTime;
00064 
00069 char binPath[128];
00070 
00102 int main(int argc, char *argv[]) {
00103     SDL_VideoInfo const *videoInfo;
00104     SDL_Surface *winIcon;
00105     
00106     #ifdef WIN32
00107     #ifndef USE_GETTEXT
00108     // support a debugging console on Windows
00109     Bool haveCon = FALSE;
00110     if (argc >= 2) {
00111         int loop;
00112         for (loop = 1; loop < argc; loop++) {
00113             if ((strcmp(argv[loop], "-d") == 0) && AllocConsole()) {
00114                 // get the output file handle
00115                 FILE *out =
00116                 _fdopen(_open_osfhandle((intptr_t)GetStdHandle(STD_OUTPUT_HANDLE)
00117                 , _O_TEXT), "w");
00118                 // thought there was a better way to do this . . .
00119                 *stdout = *stderr = *out;
00120                 // flag the creation of the console for later cleanup
00121                 haveCon = TRUE;
00122                 break;
00123             }
00124         }
00125     }
00126     #elif defined(_MSC_VER) && (_MSC_VER > 1310)
00127     FILE oldout, olderr;
00128     oldout = *stdout;
00129     olderr = *stderr;
00130     {
00131         FILE *out;
00138         out = fopen("rtsa_status.txt", "w,ccs=UTF-16LE");
00139         *stdout = *out;
00140         out = fopen("rtsa_errors.txt", "w,ccs=UTF-16LE");
00141         *stderr = *out;
00142     }
00143     #endif
00144     #endif
00145     // output legal info in English before initializing much of anything,
00146     // including the gettext libraries
00147     #ifdef USE_GETTEXT
00148     wprintf(L"Retro Tank Super Attack, Copyright (C) 2007  Jeff Jackowski  jeffj@ro.com\n");
00149     wprintf(L"Retro Tank Super Attack comes with ABSOLUTELY NO WARRANTY. This\n");
00150     wprintf(L"is free software, and you are welcome to redistribute it under\n"); 
00151     wprintf(L"certain conditions as defined by the GPL. For more details, see\n");
00152     wprintf(L"the GPL included in gpl.txt with this program, or at\n");
00153     wprintf(L"http://www.gnu.org/copyleft/gpl.html\n\n");
00154     #else
00155     printf("Retro Tank Super Attack, Copyright (C) 2007  Jeff Jackowski  jeffj@ro.com\n");
00156     printf("Retro Tank Super Attack comes with ABSOLUTELY NO WARRANTY. This\n");
00157     printf("is free software, and you are welcome to redistribute it under\n"); 
00158     printf("certain conditions as defined by the GPL. For more details, see\n");
00159     printf("the GPL included in gpl.txt with this program, or at\n");
00160     printf("http://www.gnu.org/copyleft/gpl.html\n\n");
00161     #endif
00162     {
00163         char *end;
00164         // find the path of the binary
00165         #ifdef WIN32
00166         end = strrchr(argv[0], '\\');
00167         #else
00168         end = strrchr(argv[0], '/');
00169         #endif
00170         // if the character was found . . .
00171         if (end != NULL) {
00172             // set the length to include everything until the slash
00173             size_t len = end - argv[0] + 1;
00174             // copy over the path
00175             strncpy(binPath, argv[0], len);
00176             // terminate the result
00177             binPath[len] = 0;
00178         }
00179         else {
00180             // No usable path, so try to indicate the current directory.
00181             // This happens with Valgrind 2.4, but so far no where else.
00182             binPath[0] = '.';
00183             binPath[1] = '/';
00184             binPath[2] = binPath[3] = 0;
00185         }
00186         // printf("Binary path: %s\n", binPath);
00187     }
00188 
00189     #ifdef WIN32
00190     // initialize the winsock library
00191     fwprintf(stderr, L"Error output test\n");
00192     {
00193         WSADATA result;
00194         if (WSAStartup(0x202, &result) != 0) {
00195             fprintf(stderr, "Could not initalize Winsock\n");
00196             exit(31);
00197         }
00198         if ((result.wVersion & 0xFF) != 2) {
00199             fprintf(stderr,
00200             "Incompatible Winsock version %i.%i found. Need version 2.x\n",
00201             result.wVersion & 0xFF, result.wVersion >> 8);
00202             exit(32);
00203         }
00204     }
00205     /*  
00206     if (getenv("APPDATA")) {
00207         printf("Application data directory is\n\t%s\n", getenv("APPDATA"));
00208     }
00209     */
00210     #else
00211     /*
00212     if (getenv("HOME")) {
00213         printf("Home directory is %s\n", getenv("HOME"));
00214     }
00215     */
00216     #endif
00217     /*
00218     else {
00219         printf("Could not determine the home directory\n");
00220     }
00221     */
00222     
00223     RandInit(); 
00224     StartIOThread();
00225     
00226     /*
00227     {  // host lookup test  ---  remove later
00228         char name[MAX_HOST_LEN];
00229         INetAddr addr;
00230         int ip = 0, res;
00231         gethostname(name, MAX_HOST_LEN);
00232         StartAddrLookup(name);
00233         while ((res = LookupResult(name, &addr)) == 0) SDL_Delay(1);
00234         if (res > 0) {
00235             ip = addr.ipv4.s_addr;
00236             printf("%s -> %u.%u.%u.%u\n", name, ip & 0xFF,
00237             (ip & 0xFF00) >> 8, (ip & 0xFF0000) >> 16, (ip & 0xFF000000) >> 24);
00238         }
00239         StartAddrLookup("owa.fullsail.com");
00240         while ((res = LookupResult(NULL, &addr)) == 0) SDL_Delay(1);
00241         if (res > 0) {
00242             ip = addr.ipv4.s_addr;
00243             printf("owa.fullsail.com -> %u.%u.%u.%u\n", ip & 0xFF,
00244             (ip & 0xFF00) >> 8, (ip & 0xFF0000) >> 16, (ip & 0xFF000000) >> 24);
00245         }
00246         StartStrNameLookup("216.180.54.1", name);
00247         while ((res = LookupResult(NULL, &addr)) == 0) SDL_Delay(1);
00248         if (res > 0) {
00249             ip = addr.ipv4.s_addr;
00250             printf("216.180.54.1 -> %s ", name);
00251             printf(" (%u.%u.%u.%u)\n", ip & 0xFF,
00252             (ip & 0xFF00) >> 8, (ip & 0xFF0000) >> 16, (ip & 0xFF000000) >> 24);
00253         }
00254     }
00255     */
00256 
00257     dInfo.pw = 640;
00258     dInfo.ph = 480;
00259     dInfo.showLabels = TRUE;
00260     
00261     if (!TextInit()) {
00262         fprintf(stderr, "Unable to initialize the text system\n");
00263         exit(1);
00264     }
00265 
00266     // Initialize SDL for video output
00267     if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK /* | SDL_INIT_AUDIO */
00268     /* | SDL_INIT_NOPARACHUTE */) < 0) {
00269         // failed to initalize SDL
00270         prnfile(stderr, strings[STRING_ERR_SDL], SDL_GetError());
00271         exit(2);
00272     }
00273     // Fetch the video info
00274     videoInfo = SDL_GetVideoInfo();
00275     
00276     if (!videoInfo) {
00277         prnfile(stderr, strings[STRING_ERR_VIDQ], SDL_GetError());
00278         SDL_Quit();
00279         exit(3);
00280     }
00281     
00282     // the flags to pass to SDL_SetVideoMode
00283     videoFlags  = SDL_ANYFORMAT | SDL_RESIZABLE | SDL_DOUBLEBUF;
00284     if ((argc >= 2) && (strcmp(argv[1], "-f") == 0)) {
00285         videoFlags |= SDL_FULLSCREEN;
00286     }
00287     
00288     // This checks to see if surfaces can be stored in memory
00289     if (videoInfo->hw_available)
00290         videoFlags |= SDL_HWSURFACE;
00291     else
00292         videoFlags |= SDL_SWSURFACE;
00293     
00294     // This checks if hardware blits can be done
00295     //if (videoInfo->blit_hw)
00296         videoFlags |= SDL_HWACCEL; // always try
00297     
00298     // generate all the tank sprites
00299     GenTankSprites();
00300     
00301     // attempt to get a surface for the window's icon
00302     if ((winIcon = dInfo.display = SDL_CreateRGBSurface(SDL_SWSURFACE, 32, 32,
00303     32, 0xFF, 0xFF00, 0xFF0000, 0xFF000000)) != NULL) {
00304         Player tank;
00305         // set the color values to match the icon's color setup
00306         SetupColorVals();
00307         // setup values to draw a red tank facing up filling a 32x32 surface
00308         dInfo.luw = dInfo.luh = 4;
00309         tank.tank.loc.w = tank.tank.loc.h = dInfo.luw << 3;
00310         tank.tank.physLocX = -2;
00311         tank.tank.physLocY = 0;
00312         tank.rot = 0;
00313         tank.team = 0;
00314         // draw the sprite onto the icon surface
00315         DrawTank(winIcon, (RenderItem*)&tank);
00316         // set the window icon
00317         SDL_WM_SetIcon(winIcon, NULL);
00318     }
00319     // Create a 640x480 SDL surface & window
00320     if ((dInfo.display = SDL_SetVideoMode(dInfo.pw, dInfo.ph, 32, videoFlags))
00321     == NULL) {
00322         prnfile(stderr, strings[STRING_ERR_VIDMODE], SDL_GetError());
00323         SDL_Quit();
00324         exit(4);
00325     }
00326     // if the window icon was created . . .
00327     if (winIcon) {
00328         // free it -- it was copied by SDL, so no reason to keep it
00329         SDL_FreeSurface(winIcon);
00330     }
00331 
00332     // setup the color values to match the display
00333     SetupColorVals();
00334     
00335     // show information on the actual display surface
00336     if (dInfo.display->flags & SDL_DOUBLEBUF) {
00337         // double buffered video
00338         prnout(strings[STRING_STAT_DOUBLEBUFF]);
00339         // No mouse! Can cause problems with double buffered graphics.
00340         SDL_ShowCursor(SDL_DISABLE);
00341     }
00342     else {
00343         // single buffered video
00344         prnout(strings[STRING_STAT_SINGLEBUFF]);
00345     }
00346 
00347     if (dInfo.display->flags & SDL_HWACCEL) {
00348         // hardware accelerarion
00349         prnout(strings[STRING_STAT_HWACCEL]);
00350     }
00351     else {
00352         // all on CPU
00353         prnout(strings[STRING_STAT_NOHWACCEL]);
00354     }
00355     
00356     if (dInfo.display->flags & SDL_HWSURFACE) {
00357         // output surface in graphics memory
00358         prnout(strings[STRING_STAT_OUTGRPMEM]);
00359     }
00360     else {
00361         // output surface in system memory
00362         prnout(strings[STRING_STAT_OUTSYSMEM]);
00363     }
00364     
00365     {
00366         char driver[32];
00367         SDL_VideoDriverName(driver, 32);
00368         // show the video drive's name
00369         prnout(strings[STRING_STAT_VIDDRNAME], driver);
00370     }
00371     
00372     // Initalize the true type font engine
00373     if (TTF_Init() != 0) {
00374         // font library failed to initialize
00375         prnfile(stderr, strings[STRING_ERR_TTFINIT], TTF_GetError());
00376         SDL_Quit();
00377         exit(5);
00378     }
00379     
00380     // initalize the rendering system
00381     if (!RenderInit(128, (dInfo.display->flags & SDL_DOUBLEBUF) ? 2 : 1)) {
00382         // failed to initialize rendering
00383         prnfile(stderr, strings[STRING_ERR_RENDER]);
00384         SDL_Quit();
00385         exit(6);
00386     }
00387     
00388     // initalize the graphical part of the text system
00389     if (!FontInit()) {
00390         // failed to load fonts
00391         prnfile(stderr, strings[STRING_ERR_FNTINIT]);
00392         SDL_Quit();
00393         exit(7);
00394     }
00395     
00396     // initalize joystcks, if any
00397     if (SDL_NumJoysticks() > 0) {
00398         // open the first joystck and check for success
00399         if ((stick = SDL_JoystickOpen(0)) != 0) {
00400             // show joystick info
00401             prnout(strings[STRING_STAT_JOYSTICK],
00402             SDL_JoystickName(0), SDL_JoystickNumAxes(stick),
00403             SDL_JoystickNumButtons(stick));
00404             SDL_JoystickEventState(SDL_ENABLE);
00405         }
00406     }
00407     
00408     // Set the title bar in environments that support it.
00409     TextSetWindowTitle();
00410         
00411     #ifdef USE_AUDIO
00412     if (!InitAudio()) {
00413         // no audio output
00414         prnout(strings[STRING_STAT_NOAUDIO]);
00415         UninitAudio();
00416     }
00417     #endif
00418 
00419     // check for a command line argument with the hostname of the server to
00420     // use
00421     if ((argc >= 3) && (strcmp(argv[1], "-c") == 0)) {
00422         // connect to the specified server
00423         NetInit(argv[2]);
00424     }
00425     else if ((argc >= 2) && (strcmp(argv[1], "-s") == 0)) {
00426         // be a server
00427         NetInitSrv();
00428     }
00429     else {
00430         // discover a server on the LAN
00431         NetInit(NULL);
00432     }
00433     
00434     // start of state loop notification
00435     prnout(strings[STRING_STAT_ENTERSTATE]);
00436     
00437     // setup the initial frame timer state
00438     elapsedTime = SDL_GetTicks();
00439     frameTime = elapsedTime - (elapsedTime % FRAME_DURATION) +
00440     FRAME_DURATION;
00441     elapsedTime %= FRAME_DURATION;
00442     
00443     // run the states until finished
00444     for (; RunState(); ) {
00445         
00446         #ifndef RENDER_EVERY_FRAME
00447         // check for on-time execution
00448         if (elapsedTime <= FRAME_DURATION) {
00449         #endif
00450     
00451             Render();
00452             
00453             // see how much time was used
00454             elapsedTime = SDL_GetTicks() - frameTime;
00455             // adjust for weirdness
00456             if (elapsedTime < 0) {
00457                 elapsedTime = 0;
00458             }
00459     
00460         #ifndef RENDER_EVERY_FRAME
00461             // wait
00462             if (elapsedTime < FRAME_DURATION) {
00463                 SDL_Delay(FRAME_DURATION - elapsedTime);
00464             }
00465         }
00466         else {
00467             // record that we are closer to being at the correct time
00468             // index
00469             elapsedTime -= FRAME_DURATION;
00470         }
00471         #else
00472         SDL_Delay(FRAME_DURATION -
00473         ((elapsedTime > FRAME_DURATION) ? FRAME_DURATION : elapsedTime));
00474         #endif
00475         // advance the time reference once for this trip through the event loop
00476         frameTime += FRAME_DURATION;
00477     }
00478     
00479     //rtsa_char *testStr = strings[STRING_STAT_EXITSTATE];
00480     // notification that the program has left the loop and is shutting down
00481     //int written = 
00482     prnout(strings[STRING_STAT_EXITSTATE]);
00483     
00484     if (menuSettings) {
00485         free(menuSettings);
00486     }
00487     if (stick) {
00488         SDL_JoystickClose(stick);
00489     }
00490     RandUninit();
00491     #ifdef USE_AUDIO
00492     UninitAudio();
00493     #endif
00494     StopIOThread();
00495     NetUninit();
00496     TextUninit();
00497     RenderUninit();
00498     #ifdef WIN32
00499     WSACleanup();
00500     #ifndef USE_GETTEXT
00501     if (haveCon) {
00502         FreeConsole();
00503     }
00504     #elif defined(_MSC_VER) && (_MSC_VER > 1310)
00505     fclose(stdout);
00506     *stdout = oldout;
00507     *stderr = olderr;
00508     #endif
00509     #endif
00510     TTF_Quit();
00511     SDL_Quit();
00512     return 0;
00513 }
00514 

Generated on Mon May 28 04:41:39 2007 for Retro Tank Super Attack by  doxygen 1.5.2