#include "libs.h" #include "l3d.h" #include "gui.h" #include "glfreetype.h" #include "objimport.h" #include "player.h" #include "space.h" #include "planet.h" #include "star.h" #include "frame.h" #include "ship_cpanel.h" #include "sector_view.h" #include "system_view.h" #include "system_info_view.h" #include "world_view.h" #include "object_viewer_view.h" #include "star_system.h" #include "space_station.h" #include "space_station_view.h" #include "info_view.h" float L3D::timeAccel = 1.0f; int L3D::scrWidth; int L3D::scrHeight; float L3D::scrAspect; SDL_Surface* L3D::scrSurface; sigc::signal L3D::onKeyPress; sigc::signal L3D::onKeyRelease; sigc::signal L3D::onMouseButtonUp; sigc::signal L3D::onMouseButtonDown; char L3D::keyState[SDLK_LAST]; char L3D::mouseButton[5]; int L3D::mouseMotion[2]; enum L3D::CamType L3D::cam_type; enum L3D::MapView L3D::map_view; Player* L3D::player; View* L3D::current_view; WorldView* L3D::world_view; ObjectViewerView* L3D::objectViewerView; SpaceStationView* L3D::spaceStationView; InfoView* L3D::infoView; SectorView* L3D::sector_view; SystemView* L3D::system_view; SystemInfoView* L3D::system_info_view; ShipCpanel* L3D::cpan; StarSystem* L3D::selected_system; MTRand L3D::rng; double L3D::gameTime; float L3D::frameTime; GLUquadric* L3D::gluQuadric; systemloc_t L3D::playerLoc; void L3D::Init(IniConfig& config) { int width = config.Int("ScrWidth"); int height = config.Int("ScrHeight"); const SDL_VideoInfo* info = NULL; if(SDL_Init(SDL_INIT_VIDEO) < 0) { fprintf(stderr, "Video initialization failed: %s\n", SDL_GetError()); exit(-1); } info = SDL_GetVideoInfo(); switch(config.Int("ScrDepth")) { case 16: SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,6); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); break; case 32: SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); break; default: fprintf(stderr, "Fatal error: Invalid screen depth in config.ini.\n"); L3D::Quit(); } SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); Uint32 flags = SDL_OPENGL; if(config.Int("StartFullscreen")) flags |= SDL_FULLSCREEN; if((L3D::scrSurface = SDL_SetVideoMode(width, height, info->vfmt->BitsPerPixel, flags)) == 0) { /* Fall back to 16-bit depth buffer.. */ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); fprintf(stderr,"Failed to set video mode. (%s). Re-trying with 16 bit depth buffer.\n",SDL_GetError()); if((L3D::scrSurface = SDL_SetVideoMode(width, height, info->vfmt->BitsPerPixel, flags)) == 0) { fprintf(stderr, "video mode set failed: %s\n", SDL_GetError()); exit(-1); } } L3D::scrWidth = width; L3D::scrHeight = height; L3D::scrAspect = width / (float)height; InitOpenGL(); dInitODE(); GLFTInit(); Space::Init(); } void L3D::InitOpenGL() { glShadeModel(GL_SMOOTH); glCullFace(GL_BACK); glFrontFace(GL_CCW); glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glClearColor(0, 0, 0, 0); glViewport(0, 0, scrWidth, scrHeight); gluQuadric = gluNewQuadric(); } void L3D::Quit(void) { SDL_Quit(); exit(0); } void L3D::SetCamType(enum CamType c) { cam_type = c; map_view = MAP_NOMAP; SetView(world_view); } void L3D::SetMapView(enum MapView v) { map_view = v; if(v == MAP_SECTOR) SetView(sector_view); else SetView(system_view); } void L3D::SetView(View* v) { if(current_view) current_view->HideAll(); current_view = v; current_view->ShowAll(); } void L3D::HandleEvents(void) { SDL_Event event; L3D::mouseMotion[0] = L3D::mouseMotion[1] = 0; while(SDL_PollEvent(&event)) { Gui::HandleSDLEvent(&event); switch(event.type) { case SDL_KEYDOWN: if(event.key.keysym.sym == SDLK_q) L3D::Quit(); if(event.key.keysym.sym == SDLK_F11) SDL_WM_ToggleFullScreen(L3D::scrSurface); if(event.key.keysym.sym == SDLK_F10) L3D::SetView(L3D::objectViewerView); L3D::keyState[event.key.keysym.sym] = 1; L3D::onKeyPress.emit(&event.key.keysym); break; case SDL_KEYUP: L3D::keyState[event.key.keysym.sym] = 0; L3D::onKeyRelease.emit(&event.key.keysym); break; case SDL_MOUSEBUTTONDOWN: L3D::mouseButton[event.button.button] = 1; L3D::onMouseButtonDown.emit(event.button.button, event.button.x, event.button.y); break; case SDL_MOUSEBUTTONUP: L3D::mouseButton[event.button.button] = 1; L3D::onMouseButtonUp.emit(event.button.button, event.button.x, event.button.y); break; case SDL_MOUSEMOTION: L3D::mouseMotion[0] += event.motion.xrel; L3D::mouseMotion[1] += event.motion.yrel; //SDL_GetRelativeMouseState(&L3D::mouseMotion[0], &L3D::mouseMotion[1]); break; case SDL_QUIT: L3D::Quit(); break; } } } void L3D::MainLoop(void) { player = new Player(ShipType::SLEEK); player->SetLabel("Me"); Space::AddBody(player); StarSystem s(0, 0, 0); HyperspaceTo(&s); /* Linked list eh... Put player at planet f. */ const float zpos = EARTH_RADIUS * 7; Frame* pframe = *(++(++(++(++(Space::rootFrame->m_children.begin()))))); player->SetFrame(pframe); player->SetPosition(vector3d(0, zpos*0.1, zpos)); for(int i = 0; i < 4; i++) { Ship* body = new Ship(ShipType::SLEEK/*LADYBIRD*/); char buf[64]; snprintf(buf, sizeof(buf), "X%c-0%02d", "A"+i, i); body->SetLabel(buf); body->SetFrame(pframe); body->SetPosition(vector3d(i*2000, zpos*0.1, zpos+1000)); Space::AddBody(body); } { SpaceStation* body = new SpaceStation(); body->SetLabel("Poemi-chan's Folly"); body->SetFrame(pframe); body->SetPosition(vector3d(5000, zpos*0.1, zpos-10000)); Space::AddBody(body); } Gui::Init(scrWidth, scrHeight, 640, 480); cpan = new ShipCpanel(); cpan->ShowAll(); sector_view = new SectorView(); system_view = new SystemView(); system_info_view = new SystemInfoView(); world_view = new WorldView(); objectViewerView = new ObjectViewerView(); spaceStationView = new SpaceStationView(); infoView = new InfoView(); SetView(world_view); Uint32 last_stats = SDL_GetTicks(); int frame_stat = 0; char fps_readout[32]; Uint32 time_before_frame = SDL_GetTicks(); for(;;) { frame_stat++; glMatrixMode(GL_MODELVIEW); glLoadIdentity(); current_view->Draw3D(); /* * TODO: HandleEvents at the moment must be after view->Draw3D and before * Gui::Draw so that labels drawn to screen can have mouse events correctly * detected. Gui::Draw wipes memory of label positions. */ L3D::HandleEvents(); /* Hide cursor for ship control. */ if(L3D::MouseButtonState(3)) { SDL_ShowCursor(0); SDL_WM_GrabInput(SDL_GRAB_ON); } else { SDL_ShowCursor(1); SDL_WM_GrabInput(SDL_GRAB_OFF); } Gui::Draw(); #ifdef DEBUG { Gui::Screen::EnterOrtho(); glColor3f(1, 1, 1); glTranslatef(0, Gui::Screen::GetHeight()-20, 0); Gui::Screen::RenderString(fps_readout); Gui::Screen::LeaveOrtho(); } #endif glFlush(); SDL_GL_SwapBuffers(); //if(glGetError()) printf("GL: %s\n", gluErrorString(glGetError())); L3D::frameTime = 0.001*(SDL_GetTicks() - time_before_frame); float step = L3D::timeAccel * L3D::frameTime; time_before_frame = SDL_GetTicks(); /* Game state update stuff. */ if(step) { Space::TimeStep(step); gameTime += step; } current_view->Update(); if(SDL_GetTicks() - last_stats > 1000) { snprintf(fps_readout, sizeof(fps_readout), "%d fps", frame_stat); frame_stat = 0; last_stats += 1000; } } } StarSystem* L3D::GetSelectedSystem(void) { int sector_x, sector_y, system_idx; L3D::sector_view->GetSelectedSystem(§or_x, §or_y, &system_idx); if(system_idx == -1) { selected_system = 0; return NULL; } if(selected_system) { if(!selected_system->IsSystem(sector_x, sector_y, system_idx)) { delete selected_system; selected_system = 0; } } if(!selected_system) { selected_system = new StarSystem(sector_x, sector_y, system_idx); } return selected_system; } void L3D::HyperspaceTo(StarSystem* dest) { Space::Clear(); Space::BuildSystem(dest); float ang = rng.Double(M_PI); L3D::player->SetPosition(vector3d(sin(ang)*8*AU, cos(ang)*8*AU, 0)); dest->GetPos(&L3D::playerLoc); } IniConfig::IniConfig(const char* filename) { FILE* f = fopen(filename, "r"); if(!f) { fprintf(stderr, "Could not open '%s'.\n", filename); L3D::Quit(); } char buf[1024]; while(fgets(buf, sizeof(buf), f)) { if(buf[0] == '#') continue; char* sep = strchr(buf, '='); char* kend = sep; if(!sep) continue; *sep = 0; /* Strip whitespace. */ while(isspace(*(--kend))) *kend = 0; while(isspace(*(++sep))) *sep = 0; /* Snip \r, \n. */ char* vend = sep; while(*(++vend)) if((*vend == '\r') || (*vend == '\n')) { *vend = 0; break; } std::string key = std::string(buf); std::string val = std::string(sep); (*this)[key] = val; } fclose(f); } int main(int argc, char** argv) { printf("Lephisto3D's super high tech demo!\n"); IniConfig cfg("config.ini"); L3D::Init(cfg); L3D::MainLoop(); return 0; }