Lephisto/src/main.cpp
Rtch90 56dc9ee5a8 [Fix] Fixed broken system info view.
[Fix] Fixed mouse screw up in system view.
2017-11-13 22:30:54 +00:00

374 lines
10 KiB
C++

#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 "star_system.h"
#include "space_station.h"
#include "space_station_view.h"
#include "info_view.h"
float L3D::timeStep = 1.0f;
int L3D::scrWidth;
int L3D::scrHeight;
float L3D::scrAspect;
SDL_Surface* L3D::scrSurface;
sigc::signal<void, SDL_keysym*> L3D::onKeyPress;
sigc::signal<void, SDL_keysym*> L3D::onKeyRelease;
sigc::signal<void, int, int, int> L3D::onMouseButtonUp;
sigc::signal<void, int, int, int> 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;
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);
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) {
Frame* earth_frame = new Frame(Space::GetRootFrame(), "Earth");
earth_frame->SetPosition(vector3d(149598000000.0, 0, 0));
earth_frame->SetRadius(2*380000000); /* 2 moon orbital radii. */
player = new Player(ShipType::SLEEK);
player->SetLabel("Me");
player->SetFrame(earth_frame);
player->SetPosition(vector3d(100, 0, 0));
Space::AddBody(player);
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(earth_frame);
body->SetPosition(vector3d(i*200, 0, -200));
Space::AddBody(body);
}
{
SpaceStation* body = new SpaceStation();
body->SetLabel("Some Back Country Joint");
body->SetFrame(earth_frame);
body->SetPosition(vector3d(0, 0, 6000));
Space::AddBody(body);
}
Planet* planet = new Planet(StarSystem::SBody::SUBTYPE_PLANET_INDIGENOUS_LIFE);
planet->SetLabel("Earth");
planet->SetPosition(vector3d(0, 0, -8000000.0));
planet->SetFrame(earth_frame);
Space::AddBody(planet);
Frame* moon_frame = new Frame(earth_frame, "Moon");
moon_frame->SetPosition(vector3d(0, -380000000.0, 0));
moon_frame->SetRadius(10*1738140.0); /* 10 moon radii. */
Planet* moon = new Planet(StarSystem::SBody::SUBTYPE_PLANET_DWARF);
moon->SetLabel("Moon");
moon->SetPosition(vector3d(0, 0, 0));
moon->SetRadius(1738140.0);
moon->SetFrame(moon_frame);
Space::AddBody(moon);
Star* sol = new Star(StarSystem::SBody::SUBTYPE_STAR_G);
sol->SetLabel("Sol");
sol->SetRadius(6.955e8);
sol->SetPosition(vector3d(0, 0, 0));
sol->SetFrame(Space::GetRootFrame());
Space::AddBody(sol);
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();
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::timeStep * 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(&sector_x, &sector_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(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;
}