374 lines
10 KiB
C++
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(§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(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;
|
|
}
|
|
|