#include #include #include #include #include "global.h" #include "queue.h" #ifdef __GNUC__ #include #ifdef WINDOWS #include #endif #endif #ifdef WINDOWS #include #undef WRITE_XML char *win_command_line; #endif //WINDOWS #include "global.h" #include "init.h" #include "translate.h" Uint32 cur_time=0, last_time=0;//for FPS char version_string[]=VER_STRING; int client_version_major=VER_MAJOR; int client_version_minor=VER_MINOR; int client_version_release=VER_RELEASE; int client_version_patch=VER_BUILD; int version_first_digit=10; //protocol/game version sent to server int version_second_digit=18; int gargc; char ** gargv; /**********************************************************************/ void cleanup_mem(void) { int i; history_destroy(); command_cleanup(); queue_destroy(buddy_request_queue); cleanup_text_buffers(); cleanup_fonts(); cursors_cleanup(); destroy_all_actors(); end_actors_lists(); cleanup_lights(); /* 2d objects */ for(i = 0; i < MAX_OBJ_2D_DEF; i++) { if(obj_2d_list[i] != NULL) { free(obj_2d_list[i]); } } /* 3d objects */ for(i = 0; i < MAX_OBJ_3D; i++) { if(objects_list[i] != NULL) { destroy_3d_object(i); } } /* caches */ cache_e3d->free_item = &destroy_e3d; cache_delete(cache_e3d); cache_e3d = NULL; cache_delete(cache_system); cache_system = NULL; /* map location information */ for (i = 0; continent_maps[i].name; i++) { free(continent_maps[i].name); } free (continent_maps); } int start_rendering() { static int done = 0; static void * network_thread_data[2] = { NULL, NULL }; SDL_Thread *network_thread; queue_t *message_queue; #ifndef WINDOWS SDL_EventState(SDL_SYSWMEVENT,SDL_ENABLE); #endif queue_initialise(&message_queue); network_thread_data[0] = message_queue; network_thread_data[1] = &done; network_thread = SDL_CreateThread(get_message_from_server, network_thread_data); /* Loop until done. */ while( !done ) { SDL_Event event; // handle SDL events while( SDL_PollEvent( &event ) ) { done = HandleEvent(&event); } //advance the clock cur_time = SDL_GetTicks(); //check for network data if(!queue_isempty(message_queue)) { message_t *message; while((message = queue_pop(message_queue)) != NULL) { process_message_from_server(message->data, message->length); free(message->data); free(message); } } #ifdef OLC olc_process(); #endif //OLC my_tcp_flush(my_socket); // make sure the tcp output buffer is set if(!limit_fps || (cur_time-last_time && 1000/(cur_time-last_time) <= limit_fps)) { //draw everything draw_scene(); last_time=cur_time; } else { SDL_Delay(1);//give up timeslice for anyone else } #ifdef TIMER_CHECK //Check the timers to make sure that they are all still alive... check_timers(); #endif //cache handling if(cache_system)cache_system_maint(); //see if we need to exit if(exit_now) { done = 1; break; } } if(!done) { done = 1; } log_error("Client closed"); SDL_WaitThread(network_thread,&done); queue_destroy(message_queue); if(pm_log.ppl)free_pm_log(); //save all local data save_local_data(NULL, 0); turn_music_off(); //cleans up and waits for the thread unload_questlog(); free_icons(); free_vars(); cleanup_rules(); #ifdef MINIMAP save_exploration_map(); #endif //MINIMAP #ifdef COUNTERS cleanup_counters(); #endif //COUNTERS cleanup_chan_names(); unload_e3d_list(); // do we really want to overwrite this file?? SDL_RemoveTimer(draw_scene_timer); SDL_RemoveTimer(misc_timer); end_particles_list(); #ifdef NEW_FRUSTUM free_bbox_tree(main_bbox_tree); main_bbox_tree = NULL; #endif /* Destroy our GL context, etc. */ destroy_sound(); SDL_QuitSubSystem(SDL_INIT_AUDIO); SDL_QuitSubSystem(SDL_INIT_TIMER); /*#ifdef WINDOWS // attempt to restart if requested if(restart_required > 0){ log_error("Restarting %s", win_command_line); SDL_CreateThread(system, win_command_line); } #endif //WINDOWS */ SDL_Quit( ); cleanup_mem(); xmlCleanupParser(); FreeXML(); // shouldn't this be before SDL_Quit()? that shutsdown the video mode if (use_frame_buffer) free_reflection_framebuffer(); return(0); } extern char *optarg; extern int optind, opterr, optopt; void read_command_line() { int i=1; if(gargc<2)return; for(;i 0){ log_error("Restarting %s\n", *argv); execv(*argv, argv); } #endif //WINDOWS return 0; } #ifdef WINDOWS // splits a char* into a char ** based on the delimiters int makeargv(char *s, char *delimiters, char ***argvp) { int i, numtokens; char *snew, *t; if ((s == NULL) || (delimiters == NULL) || (argvp == NULL)) return -1; *argvp = NULL; snew = s + strspn(s, delimiters); if ((t = malloc(strlen(snew) + 1)) == NULL) return -1; strcpy(t, snew); // It's fine that this isn't strncpy, since t is sizeof(snew) + 1. numtokens = 0; if (strtok(t, delimiters) != NULL) for (numtokens = 1; strtok(NULL, delimiters) != NULL; numtokens++); if ((*argvp = malloc((numtokens + 1)*sizeof(char *))) == NULL){ free(t); return -1; } if (numtokens == 0) free(t); else{ strcpy(t, snew); **argvp = strtok(t, delimiters); for (i = 1; i < numtokens; i++) *((*argvp) + i) = strtok(NULL, delimiters); } *((*argvp) + numtokens) = NULL; return numtokens; } //frees the char** created by makeargv void freemakeargv(char **argv) { if (argv == NULL) return; if (*argv != NULL) free(*argv); free(argv); } int APIENTRY WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow) { char **argv= NULL; int argc= makeargv(win_command_line, " \t\n", &argv); win_command_line= GetCommandLine(); Main(argc, (char **) argv); freemakeargv(argv); // attempt to restart if requested if(restart_required > 0){ STARTUPINFO si; PROCESS_INFORMATION pi; log_error("Restarting %s", win_command_line); ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); CreateProcess(NULL, win_command_line, NULL, // Process handle not inheritable. NULL, // Thread handle not inheritable. FALSE, // Set handle inheritance to FALSE. DETACHED_PROCESS, // Keep this separate NULL, // Use parent's environment block. NULL, // Use parent's starting directory. &si, // Pointer to STARTUPINFO structure. &pi); // Pointer to PROCESS_INFORMATION structure } return 0; } #endif