speed relative to target. fiddle with planet draw distance. make check (tests.cpp).
git-svn-id: https://pioneer.svn.sourceforge.net/svnroot/pioneer/trunk@260 e632f14b-6550-0410-b89e-a82653faca30master
parent
068477b226
commit
75d9ce8d40
15
src/Body.cpp
15
src/Body.cpp
|
@ -132,3 +132,18 @@ void Body::OrientOnSurface(double radius, double latitude, double longitude)
|
|||
rot = rot.InverseOf();
|
||||
SetRotMatrix(rot);
|
||||
}
|
||||
|
||||
|
||||
vector3d Body::GetVelocityRelativeTo(const Frame *f) const
|
||||
{
|
||||
matrix4x4d m;
|
||||
Frame::GetFrameTransform(GetFrame(), f, m);
|
||||
return (m.ApplyRotationOnly(GetVelocity()) + Frame::GetFrameRelativeVelocity(GetFrame(), f));
|
||||
}
|
||||
|
||||
|
||||
vector3d Body::GetVelocityRelativeTo(const Body *other) const
|
||||
{
|
||||
return GetVelocity() - other->GetVelocityRelativeTo(GetFrame());
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,8 @@ public:
|
|||
virtual void TimeStepUpdate(const float timeStep) {}
|
||||
// Override to clear any pointers you hold to the dying body.
|
||||
virtual void NotifyDeath(const Body* const dyingBody) {}
|
||||
vector3d GetVelocityRelativeTo(const Body *other) const;
|
||||
vector3d GetVelocityRelativeTo(const Frame *f) const;
|
||||
// for putting on planet surface, oriented +y up
|
||||
void OrientOnSurface(double radius, double latitude, double longitude);
|
||||
vector3d GetPositionRelTo(const Frame *);
|
||||
|
|
|
@ -112,6 +112,35 @@ void Frame::ApplyEnteringTransform(matrix4x4d &m) const
|
|||
m = m * m_orient.InverseOf() * matrix4x4d::Translation(-m_pos);
|
||||
}
|
||||
|
||||
vector3d Frame::GetFrameRelativeVelocity(const Frame *fFrom, const Frame *fTo)
|
||||
{
|
||||
if (fFrom == fTo) return vector3d(0,0,0);
|
||||
vector3d v1 = vector3d(0,0,0);
|
||||
vector3d v2 = vector3d(0,0,0);
|
||||
|
||||
matrix4x4d m = matrix4x4d::Identity();
|
||||
|
||||
const Frame *f = fFrom;
|
||||
const Frame *root = Space::rootFrame;
|
||||
|
||||
// move forwards from origin to root
|
||||
while ((f!=root) && (fTo != f)) {
|
||||
v1 += m.ApplyRotationOnly(-f->GetVelocity());
|
||||
m = m * f->m_orient.InverseOf();
|
||||
f = f->m_parent;
|
||||
}
|
||||
|
||||
// move backwards from target to root
|
||||
while (fTo != f) {
|
||||
v2 = fTo->m_orient.ApplyRotationOnly(fTo->GetVelocity() + v2);
|
||||
fTo = fTo->m_parent;
|
||||
}
|
||||
|
||||
vector3d out = v1 + m.ApplyRotationOnly(v2);
|
||||
// printf("v1: %.2f,%.2f,%.2f v2: %.2f,%.2f,%.2f ~= %.2f,%.2f,%.2f\n", v1.x, v1.y, v1.z, v2.x, v2.y, v2.z, out.x, out.y, out.z);
|
||||
return out;
|
||||
}
|
||||
|
||||
void Frame::GetFrameTransform(const Frame *fFrom, const Frame *fTo, matrix4x4d &m)
|
||||
{
|
||||
matrix4x4d m2 = matrix4x4d::Identity();
|
||||
|
|
|
@ -47,6 +47,7 @@ public:
|
|||
void ApplyEnteringTransform(matrix4x4d &m) const;
|
||||
|
||||
static void GetFrameTransform(const Frame *fFrom, const Frame *fTo, matrix4x4d &m);
|
||||
static vector3d GetFrameRelativeVelocity(const Frame *fFrom, const Frame *fTo);
|
||||
|
||||
bool IsLocalPosInFrame(const vector3d &pos) {
|
||||
return (pos.Length() < m_radius);
|
||||
|
|
|
@ -21,9 +21,18 @@ pioneer_SOURCES = main.cpp glfreetype.cpp Body.cpp Space.cpp Ship.cpp Player.cpp
|
|||
StarSystem.cpp Sector.cpp SystemInfoView.cpp GenericSystemView.cpp utils.cpp SpaceStation.cpp \
|
||||
SpaceStationView.cpp ModelBody.cpp ShipType.cpp InfoView.cpp ModelCollMeshData.cpp \
|
||||
ObjectViewerView.cpp custom_starsystems.cpp Serializer.cpp Sfx.cpp Ship-AI.cpp MarketAgent.cpp \
|
||||
EquipType.cpp CargoBody.cpp NameGenerator.cpp perlin.cpp GeoSphere.cpp
|
||||
EquipType.cpp CargoBody.cpp NameGenerator.cpp perlin.cpp GeoSphere.cpp Pi.cpp
|
||||
pioneer_LDADD = sbre/libsbre.a collider/libcollider.a mods/libmods.a libgui.a
|
||||
|
||||
sbreviewer_SOURCES = SbreViewer.cpp glfreetype.cpp
|
||||
sbreviewer_LDADD = sbre/libsbre.a collider/libcollider.a libgui.a
|
||||
|
||||
check_PROGRAMS = tests
|
||||
tests_SOURCES = tests.cpp glfreetype.cpp Body.cpp Space.cpp Ship.cpp Player.cpp DynamicBody.cpp Planet.cpp \
|
||||
Star.cpp Frame.cpp ShipCpanel.cpp SectorView.cpp mtrand.cpp WorldView.cpp SystemView.cpp \
|
||||
StarSystem.cpp Sector.cpp SystemInfoView.cpp GenericSystemView.cpp utils.cpp SpaceStation.cpp \
|
||||
SpaceStationView.cpp ModelBody.cpp ShipType.cpp InfoView.cpp ModelCollMeshData.cpp \
|
||||
ObjectViewerView.cpp custom_starsystems.cpp Serializer.cpp Sfx.cpp Ship-AI.cpp MarketAgent.cpp \
|
||||
EquipType.cpp CargoBody.cpp NameGenerator.cpp perlin.cpp GeoSphere.cpp Pi.cpp
|
||||
tests_LDADD = collider/libcollider.a libgui.a mods/libmods.a sbre/libsbre.a
|
||||
|
||||
|
|
|
@ -0,0 +1,670 @@
|
|||
#include "libs.h"
|
||||
#include "Pi.h"
|
||||
#include "Gui.h"
|
||||
#include "glfreetype.h"
|
||||
#include "Player.h"
|
||||
#include "Space.h"
|
||||
#include "Planet.h"
|
||||
#include "Star.h"
|
||||
#include "Frame.h"
|
||||
#include "ShipCpanel.h"
|
||||
#include "SectorView.h"
|
||||
#include "SystemView.h"
|
||||
#include "SystemInfoView.h"
|
||||
#include "WorldView.h"
|
||||
#include "ObjectViewerView.h"
|
||||
#include "StarSystem.h"
|
||||
#include "SpaceStation.h"
|
||||
#include "SpaceStationView.h"
|
||||
#include "CargoBody.h"
|
||||
#include "InfoView.h"
|
||||
#include "Serializer.h"
|
||||
#include "NameGenerator.h"
|
||||
#include "mods/Mods.h"
|
||||
|
||||
float Pi::timeAccel = 1.0f;
|
||||
int Pi::scrWidth;
|
||||
int Pi::scrHeight;
|
||||
float Pi::scrAspect;
|
||||
SDL_Surface *Pi::scrSurface;
|
||||
sigc::signal<void, SDL_keysym*> Pi::onKeyPress;
|
||||
sigc::signal<void, SDL_keysym*> Pi::onKeyRelease;
|
||||
sigc::signal<void, int, int, int> Pi::onMouseButtonUp;
|
||||
sigc::signal<void, int, int, int> Pi::onMouseButtonDown;
|
||||
sigc::signal<void> Pi::onPlayerChangeHyperspaceTarget;
|
||||
sigc::signal<void> Pi::onPlayerHyperspaceToNewSystem;
|
||||
char Pi::keyState[SDLK_LAST];
|
||||
char Pi::mouseButton[5];
|
||||
int Pi::mouseMotion[2];
|
||||
enum Pi::MapView Pi::mapView;
|
||||
Player *Pi::player;
|
||||
View *Pi::currentView;
|
||||
WorldView *Pi::worldView;
|
||||
ObjectViewerView *Pi::objectViewerView;
|
||||
SpaceStationView *Pi::spaceStationView;
|
||||
InfoView *Pi::infoView;
|
||||
SectorView *Pi::sectorView;
|
||||
SystemView *Pi::systemView;
|
||||
SystemInfoView *Pi::systemInfoView;
|
||||
ShipCpanel *Pi::cpan;
|
||||
StarSystem *Pi::selectedSystem;
|
||||
StarSystem *Pi::currentSystem;
|
||||
MTRand Pi::rng;
|
||||
double Pi::gameTime;
|
||||
float Pi::frameTime;
|
||||
GLUquadric *Pi::gluQuadric;
|
||||
bool Pi::showDebugInfo;
|
||||
int Pi::statSceneTris;
|
||||
|
||||
void Pi::Init(IniConfig &config)
|
||||
{
|
||||
int width = config.Int("ScrWidth");
|
||||
int height = config.Int("ScrHeight");
|
||||
const SDL_VideoInfo *info = NULL;
|
||||
Uint32 sdlInitFlags = SDL_INIT_VIDEO;
|
||||
#if defined _WIN32 && defined _DEBUG
|
||||
sdlInitFlags |= SDL_INIT_NOPARACHUTE;
|
||||
#endif
|
||||
if (SDL_Init(sdlInitFlags) < 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");
|
||||
Pi::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 ((Pi::scrSurface = SDL_SetVideoMode(width, height, info->vfmt->BitsPerPixel, flags)) == 0) {
|
||||
// fall back on 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 ((Pi::scrSurface = SDL_SetVideoMode(width, height, info->vfmt->BitsPerPixel, flags)) == 0) {
|
||||
fprintf(stderr, "Video mode set failed: %s\n", SDL_GetError());
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
glewInit();
|
||||
SDL_WM_SetCaption("Pioneer","Pioneer");
|
||||
Pi::scrWidth = width;
|
||||
Pi::scrHeight = height;
|
||||
Pi::scrAspect = width / (float)height;
|
||||
|
||||
Pi::rng.seed(time(NULL));
|
||||
|
||||
NameGenerator::Init();
|
||||
InitOpenGL();
|
||||
|
||||
GLFTInit();
|
||||
Space::Init();
|
||||
|
||||
Gui::Init(scrWidth, scrHeight, 800, 600);
|
||||
Mods::Init();
|
||||
}
|
||||
|
||||
void Pi::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 ();
|
||||
|
||||
fprintf(stderr, "GL_ARB_vertex_buffer_object: %s\n", GLEW_ARB_vertex_buffer_object ? "Yes" : "No");
|
||||
}
|
||||
|
||||
void Pi::Quit()
|
||||
{
|
||||
SDL_Quit();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void Pi::SetTimeAccel(float s)
|
||||
{
|
||||
// don't want player to spin like mad when hitting time accel
|
||||
if (s > 10) {
|
||||
player->SetAngVelocity(vector3d(0,0,0));
|
||||
player->SetTorque(vector3d(0,0,0));
|
||||
player->SetAngThrusterState(0, 0.0f);
|
||||
player->SetAngThrusterState(1, 0.0f);
|
||||
player->SetAngThrusterState(2, 0.0f);
|
||||
}
|
||||
timeAccel = s;
|
||||
}
|
||||
|
||||
void Pi::SetMapView(enum MapView v)
|
||||
{
|
||||
mapView = v;
|
||||
if (v == MAP_SECTOR)
|
||||
SetView(sectorView);
|
||||
else
|
||||
SetView(systemView);
|
||||
}
|
||||
|
||||
void Pi::SetView(View *v)
|
||||
{
|
||||
if (currentView) currentView->HideAll();
|
||||
currentView = v;
|
||||
currentView->OnSwitchTo();
|
||||
currentView->ShowAll();
|
||||
}
|
||||
|
||||
void Screendump(char *destFile)
|
||||
{
|
||||
const int W = Pi::GetScrWidth();
|
||||
const int H = Pi::GetScrHeight();
|
||||
std::vector<char> pixel_data(3*W*H);
|
||||
short TGAhead[] = {0, 2, 0, 0, 0, 0, W, H, 24};
|
||||
FILE *out = fopen(destFile, "w");
|
||||
if (!out) goto error;
|
||||
glReadBuffer(GL_FRONT);
|
||||
glReadPixels(0, 0, W, H, GL_BGR, GL_UNSIGNED_BYTE, &pixel_data[0]);
|
||||
if (fwrite(&TGAhead, sizeof(TGAhead), 3, out) != 3) goto error;
|
||||
if (fwrite(&pixel_data[0], 3*W*H, 1, out) != 1) goto error;
|
||||
fclose(out);
|
||||
return;
|
||||
error:
|
||||
printf("Failed to write screendump.\n");
|
||||
}
|
||||
|
||||
void Pi::HandleEvents()
|
||||
{
|
||||
SDL_Event event;
|
||||
|
||||
Pi::mouseMotion[0] = Pi::mouseMotion[1] = 0;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
Gui::HandleSDLEvent(&event);
|
||||
switch (event.type) {
|
||||
case SDL_KEYDOWN:
|
||||
if (KeyState(SDLK_LCTRL) && (event.key.keysym.sym == SDLK_q)) Pi::Quit();
|
||||
if (event.key.keysym.sym == SDLK_i) Pi::showDebugInfo = !Pi::showDebugInfo;
|
||||
if ((event.key.keysym.sym == SDLK_PRINT) && KeyState(SDLK_LCTRL)) {
|
||||
char buf[256];
|
||||
const time_t t = time(0);
|
||||
struct tm *_tm = localtime(&t);
|
||||
strftime(buf, sizeof(buf), "screenshot-%Y%m%d-%H%M%S.tga", _tm);
|
||||
Screendump(buf);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (event.key.keysym.sym == SDLK_F12) {
|
||||
matrix4x4d m; Pi::player->GetRotMatrix(m);
|
||||
vector3d dir = m*vector3d(0,0,-1);
|
||||
/* add test object */
|
||||
if (KeyState(SDLK_LSHIFT)) {
|
||||
Frame *rotFrame = new Frame(Pi::player->GetFrame(), "Station rot frame");
|
||||
rotFrame->SetRadius(3000.0);//(1.1*sbody->GetRadius());
|
||||
rotFrame->SetPosition(Pi::player->GetPosition()+5000.0*dir);
|
||||
rotFrame->SetAngVelocity(vector3d(0,2*M_PI/10,0));
|
||||
SpaceStation *station = new SpaceStation(SpaceStation::JJHOOP);
|
||||
station->SetLabel("Poemi-chan's Folly");
|
||||
station->SetFrame(rotFrame);
|
||||
station->SetRotMatrix(matrix4x4d::RotateZMatrix(M_PI));
|
||||
Space::AddBody(station);
|
||||
} else if (KeyState(SDLK_RSHIFT)) {
|
||||
CargoBody *cargo = new CargoBody(Equip::HYDROGEN);
|
||||
cargo->SetFrame(Pi::player->GetFrame());
|
||||
cargo->SetPosition(Pi::player->GetPosition()+100.0*dir);
|
||||
cargo->SetVelocity(Pi::player->GetVelocity());
|
||||
Space::AddBody(cargo);
|
||||
} else {
|
||||
Ship *ship = new Ship(ShipType::LADYBIRD);
|
||||
ship->AIInstruct(Ship::DO_KILL, Pi::player);
|
||||
ship->SetFrame(Pi::player->GetFrame());
|
||||
ship->SetPosition(Pi::player->GetPosition()+100.0*dir);
|
||||
ship->SetVelocity(Pi::player->GetVelocity());
|
||||
Space::AddBody(ship);
|
||||
}
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
if (event.key.keysym.sym == SDLK_F11) SDL_WM_ToggleFullScreen(Pi::scrSurface);
|
||||
if (event.key.keysym.sym == SDLK_F10) Pi::SetView(Pi::objectViewerView);
|
||||
if (event.key.keysym.sym == SDLK_F9) Serializer::Write::Game("quicksave.sav");
|
||||
Pi::keyState[event.key.keysym.sym] = 1;
|
||||
Pi::onKeyPress.emit(&event.key.keysym);
|
||||
break;
|
||||
case SDL_KEYUP:
|
||||
Pi::keyState[event.key.keysym.sym] = 0;
|
||||
Pi::onKeyRelease.emit(&event.key.keysym);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
Pi::mouseButton[event.button.button] = 1;
|
||||
Pi::onMouseButtonDown.emit(event.button.button,
|
||||
event.button.x, event.button.y);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
Pi::mouseButton[event.button.button] = 0;
|
||||
Pi::onMouseButtonUp.emit(event.button.button,
|
||||
event.button.x, event.button.y);
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
Pi::mouseMotion[0] += event.motion.xrel;
|
||||
Pi::mouseMotion[1] += event.motion.yrel;
|
||||
// SDL_GetRelativeMouseState(&Pi::mouseMotion[0], &Pi::mouseMotion[1]);
|
||||
break;
|
||||
case SDL_QUIT:
|
||||
Pi::Quit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_intro(float _time)
|
||||
{
|
||||
static float lightCol[4] = { 1,1,1,0 };
|
||||
static float lightDir[4] = { 0,1,0,0 };
|
||||
|
||||
static ObjParams params = {
|
||||
{ 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0.0f, 0.0f, -1.0f }, { 0.0f, 0.0f, 0.0f },
|
||||
{ // pColor[3]
|
||||
{ { .2f, .2f, .5f }, { 1, 1, 1 }, { 0, 0, 0 }, 100.0 },
|
||||
{ { 0.5f, 0.5f, 0.5f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 },
|
||||
{ { 0.8f, 0.8f, 0.8f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 } },
|
||||
{ "PIONEER" },
|
||||
};
|
||||
glRotatef(_time*10, 1, 0, 0);
|
||||
Pi::worldView->DrawBgStars();
|
||||
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
||||
sbreSetDepthRange(Pi::GetScrWidth()*0.5, 0.0f, 1.0f);
|
||||
sbreSetDirLight (lightCol, lightDir);
|
||||
matrix4x4d rot = matrix4x4d::RotateYMatrix(_time) * matrix4x4d::RotateZMatrix(0.6*_time) *
|
||||
matrix4x4d::RotateXMatrix(_time*.7);
|
||||
vector3d p(0, 0, -80);
|
||||
sbreRenderModel(&p.x, &rot[0], 61, ¶ms);
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
static void draw_tombstone(float _time)
|
||||
{
|
||||
static float lightCol[4] = { 1,1,1,0 };
|
||||
static float lightDir[4] = { 0,1,0,0 };
|
||||
|
||||
static ObjParams params = {
|
||||
{ 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 0.0f },
|
||||
{ // pColor[3]
|
||||
{ { 1.0f, 1.0f, 1.0f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 },
|
||||
{ { 0.8f, 0.6f, 0.5f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 },
|
||||
{ { 0.5f, 0.5f, 0.5f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 } },
|
||||
{ "RIP OLD BEAN" },
|
||||
};
|
||||
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
||||
sbreSetDepthRange(Pi::GetScrWidth()*0.5, 0.0f, 1.0f);
|
||||
sbreSetDirLight (lightCol, lightDir);
|
||||
matrix4x4d rot = matrix4x4d::RotateYMatrix(_time*2);
|
||||
vector3d p(0, 0, -MAX(150 - 30*_time, 30));
|
||||
sbreRenderModel(&p.x, &rot[0], 91, ¶ms);
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
void Pi::TombStoneLoop()
|
||||
{
|
||||
Uint32 last_time = SDL_GetTicks();
|
||||
float _time = 0;
|
||||
cpan->HideAll();
|
||||
currentView->HideAll();
|
||||
do {
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
float fracH = 1.0 / Pi::GetScrAspect();
|
||||
glFrustum(-1, 1, -fracH, fracH, 1.0f, 10000.0f);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glClearColor(0,0,0,0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
Pi::HandleEvents();
|
||||
SDL_ShowCursor(1);
|
||||
SDL_WM_GrabInput(SDL_GRAB_OFF);
|
||||
|
||||
draw_tombstone(_time);
|
||||
Gui::Draw();
|
||||
glFlush();
|
||||
SDL_GL_SwapBuffers();
|
||||
|
||||
Pi::frameTime = 0.001*(SDL_GetTicks() - last_time);
|
||||
_time += Pi::frameTime;
|
||||
last_time = SDL_GetTicks();
|
||||
} while (!((_time > 2.0) && ((Pi::MouseButtonState(1)) || Pi::KeyState(SDLK_SPACE)) ));
|
||||
}
|
||||
|
||||
void Pi::Start()
|
||||
{
|
||||
player = new Player(ShipType::SWANKY);
|
||||
player->m_equipment.Set(Equip::SLOT_ENGINE, 0, Equip::DRIVE_CLASS1);
|
||||
player->m_equipment.Set(Equip::SLOT_LASER, 0, Equip::LASER_2MW_BEAM);
|
||||
player->m_equipment.Set(Equip::SLOT_LASER, 1, Equip::LASER_4MW_BEAM);
|
||||
player->m_equipment.Add(Equip::SLOT_CARGO, Equip::HYDROGEN);
|
||||
player->m_equipment.Add(Equip::SLOT_CARGO, Equip::HYDROGEN);
|
||||
player->m_equipment.Add(Equip::SLOT_CARGO, Equip::HYDROGEN);
|
||||
player->SetLabel("me");
|
||||
player->SetMoney(1000);
|
||||
Space::AddBody(player);
|
||||
|
||||
cpan = new ShipCpanel();
|
||||
sectorView = new SectorView();
|
||||
systemView = new SystemView();
|
||||
systemInfoView = new SystemInfoView();
|
||||
worldView = new WorldView();
|
||||
objectViewerView = new ObjectViewerView();
|
||||
spaceStationView = new SpaceStationView();
|
||||
infoView = new InfoView();
|
||||
|
||||
Gui::Fixed *splash = new Gui::Fixed(Gui::Screen::GetWidth(), Gui::Screen::GetHeight());
|
||||
Gui::Screen::AddBaseWidget(splash, 0, 0);
|
||||
splash->SetTransparency(true);
|
||||
|
||||
const float w = Gui::Screen::GetWidth() / 2;
|
||||
const float h = Gui::Screen::GetHeight() / 2;
|
||||
const int OPTS = 4;
|
||||
Gui::ToggleButton *opts[OPTS];
|
||||
opts[0] = new Gui::ToggleButton(); opts[0]->SetShortcut(SDLK_1, KMOD_NONE);
|
||||
opts[1] = new Gui::ToggleButton(); opts[1]->SetShortcut(SDLK_2, KMOD_NONE);
|
||||
opts[2] = new Gui::ToggleButton(); opts[2]->SetShortcut(SDLK_3, KMOD_NONE);
|
||||
opts[3] = new Gui::ToggleButton(); opts[3]->SetShortcut(SDLK_4, KMOD_NONE);
|
||||
splash->Add(opts[0], w, h-64);
|
||||
splash->Add(new Gui::Label("New game starting on Earth"), w+32, h-64);
|
||||
splash->Add(opts[1], w, h-32);
|
||||
splash->Add(new Gui::Label("New game starting on debug point"), w+32, h-32);
|
||||
splash->Add(opts[2], w, h);
|
||||
splash->Add(new Gui::Label("Load quicksave"), w+32, h);
|
||||
splash->Add(opts[3], w, h+32);
|
||||
splash->Add(new Gui::Label("Quit"), w+32, h+32);
|
||||
|
||||
splash->ShowAll();
|
||||
|
||||
int choice = 0;
|
||||
Uint32 last_time = SDL_GetTicks();
|
||||
float _time = 0;
|
||||
do {
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
float fracH = 1.0 / Pi::GetScrAspect();
|
||||
glFrustum(-1, 1, -fracH, fracH, 1.0f, 10000.0f);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glClearColor(0,0,0,0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
Pi::HandleEvents();
|
||||
SDL_ShowCursor(1);
|
||||
SDL_WM_GrabInput(SDL_GRAB_OFF);
|
||||
|
||||
draw_intro(_time);
|
||||
Gui::Draw();
|
||||
glFlush();
|
||||
SDL_GL_SwapBuffers();
|
||||
|
||||
Pi::frameTime = 0.001*(SDL_GetTicks() - last_time);
|
||||
_time += Pi::frameTime;
|
||||
last_time = SDL_GetTicks();
|
||||
|
||||
// poll ui instead of using callbacks :-J
|
||||
for (int i=0; i<OPTS; i++) if (opts[i]->GetPressed()) choice = i+1;
|
||||
} while (!choice);
|
||||
splash->HideAll();
|
||||
|
||||
if (choice == 1) {
|
||||
/* Earth start point */
|
||||
SBodyPath path(0,0,0);
|
||||
HyperspaceTo(&path);
|
||||
//Frame *pframe = *(++(++(Space::rootFrame->m_children.begin())));
|
||||
//player->SetFrame(pframe);
|
||||
// XXX there isn't a sensible way to find stations for a planet.
|
||||
SpaceStation *station = 0;
|
||||
for (Space::bodiesIter_t i = Space::bodies.begin(); i!=Space::bodies.end(); i++) {
|
||||
if ((*i)->IsType(Object::SPACESTATION)) { station = (SpaceStation*)*i; break; }
|
||||
}
|
||||
assert(station);
|
||||
player->SetPosition(vector3d(0,0,0));
|
||||
player->SetFrame(station->GetFrame());
|
||||
player->SetDockedWith(station, 0);
|
||||
MainLoop();
|
||||
} else if (choice == 2) {
|
||||
/* debug start point */
|
||||
SBodyPath path(0,0,1);
|
||||
path.elem[0] = 0; // zeroth child of root body
|
||||
path.elem[1] = 4;
|
||||
HyperspaceTo(&path);
|
||||
player->SetPosition(vector3d(0,0,2*EARTH_RADIUS));
|
||||
/* Frame *stationFrame = new Frame(pframe, "Station frame...");
|
||||
stationFrame->SetRadius(5000);
|
||||
stationFrame->m_sbody = 0;
|
||||
stationFrame->SetPosition(vector3d(0,0,zpos));
|
||||
stationFrame->SetAngVelocity(vector3d(0,0,0.5));
|
||||
|
||||
for (int i=0; i<4; i++) {
|
||||
Ship *body = new Ship(ShipType::LADYBIRD);
|
||||
char buf[64];
|
||||
snprintf(buf,sizeof(buf),"X%c-0%02d", 'A'+i, i);
|
||||
body->SetLabel(buf);
|
||||
body->SetFrame(stationFrame);
|
||||
body->SetPosition(vector3d(200*(i+1), 0, 2000));
|
||||
Space::AddBody(body);
|
||||
}
|
||||
|
||||
SpaceStation *station = new SpaceStation(SpaceStation::JJHOOP);
|
||||
station->SetLabel("Poemi-chan's Folly");
|
||||
station->SetFrame(stationFrame);
|
||||
station->SetPosition(vector3d(0,0,0));
|
||||
Space::AddBody(station);
|
||||
|
||||
SpaceStation *station2 = new SpaceStation(SpaceStation::GROUND_FLAVOURED);
|
||||
station2->SetLabel("Conor's End");
|
||||
station2->SetFrame(*pframe->m_children.begin()); // rotating frame of planet
|
||||
station2->OrientOnSurface(EARTH_RADIUS, M_PI/4, M_PI/4);
|
||||
Space::AddBody(station2);
|
||||
*/
|
||||
// player->SetDockedWith(station2, 0);
|
||||
|
||||
MainLoop();
|
||||
} else if (choice == 3) {
|
||||
// load quicksave
|
||||
Serializer::Read::Game("quicksave.sav");
|
||||
MainLoop();
|
||||
}
|
||||
}
|
||||
|
||||
void Pi::MainLoop()
|
||||
{
|
||||
cpan->ShowAll();
|
||||
|
||||
SetView(worldView);
|
||||
|
||||
Uint32 last_stats = SDL_GetTicks();
|
||||
int frame_stat = 0;
|
||||
int phys_stat = 0;
|
||||
char fps_readout[128];
|
||||
Uint32 time_before_frame = SDL_GetTicks();
|
||||
Uint32 last_phys_update = time_before_frame;
|
||||
|
||||
for (;;) {
|
||||
frame_stat++;
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
currentView->Draw3D();
|
||||
// XXX 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.
|
||||
Pi::HandleEvents();
|
||||
// hide cursor for ship control.
|
||||
if (Pi::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
|
||||
if (Pi::showDebugInfo) {
|
||||
Gui::Screen::EnterOrtho();
|
||||
glColor3f(1,1,1);
|
||||
Gui::Screen::RenderString(fps_readout);
|
||||
Gui::Screen::LeaveOrtho();
|
||||
}
|
||||
//#endif /* DEBUG */
|
||||
|
||||
glFlush();
|
||||
SDL_GL_SwapBuffers();
|
||||
//if (glGetError()) printf ("GL: %s\n", gluErrorString (glGetError ()));
|
||||
|
||||
Pi::frameTime = 0.001*(SDL_GetTicks() - time_before_frame);
|
||||
time_before_frame = SDL_GetTicks();
|
||||
|
||||
// Fixed 62.5hz physics
|
||||
int num_steps = 0;
|
||||
while (time_before_frame - last_phys_update > 16) {
|
||||
last_phys_update += 16;
|
||||
const float step = Pi::GetTimeStep();
|
||||
if (step) Space::TimeStep(step);
|
||||
gameTime += step;
|
||||
phys_stat++;
|
||||
if (++num_steps > 3) break;
|
||||
}
|
||||
currentView->Update();
|
||||
|
||||
if (SDL_GetTicks() - last_stats > 1000) {
|
||||
snprintf(fps_readout, sizeof(fps_readout), "%d fps, %d phys updates, %d triangles, %.3f M tris/sec", frame_stat, phys_stat, Pi::statSceneTris, Pi::statSceneTris*frame_stat*1e-6);
|
||||
frame_stat = 0;
|
||||
phys_stat = 0;
|
||||
last_stats += 1000;
|
||||
}
|
||||
Pi::statSceneTris = 0;
|
||||
}
|
||||
}
|
||||
|
||||
StarSystem *Pi::GetSelectedSystem()
|
||||
{
|
||||
int sector_x, sector_y, system_idx;
|
||||
Pi::sectorView->GetSelectedSystem(§or_x, §or_y, &system_idx);
|
||||
if (system_idx == -1) {
|
||||
selectedSystem = 0;
|
||||
return NULL;
|
||||
}
|
||||
if (selectedSystem) {
|
||||
if (!selectedSystem->IsSystem(sector_x, sector_y, system_idx)) {
|
||||
delete selectedSystem;
|
||||
selectedSystem = 0;
|
||||
}
|
||||
}
|
||||
if (!selectedSystem) {
|
||||
selectedSystem = new StarSystem(sector_x, sector_y, system_idx);
|
||||
}
|
||||
return selectedSystem;
|
||||
}
|
||||
|
||||
void Pi::HyperspaceTo(const SBodyPath *dest)
|
||||
{
|
||||
bool new_system = false;
|
||||
if (currentSystem) {
|
||||
if (!currentSystem->IsSystem(dest->sectorX, dest->sectorY, dest->systemIdx)) {
|
||||
delete currentSystem;
|
||||
currentSystem = 0;
|
||||
}
|
||||
}
|
||||
if (!currentSystem) {
|
||||
currentSystem = new StarSystem(dest->sectorX, dest->sectorY, dest->systemIdx);
|
||||
Space::Clear();
|
||||
Space::BuildSystem();
|
||||
new_system = true;
|
||||
}
|
||||
|
||||
|
||||
SBody *targetBody = currentSystem->GetBodyByPath(dest);
|
||||
Frame *pframe = Space::GetFrameWithSBody(targetBody);
|
||||
assert(pframe);
|
||||
float longitude = rng.Double(M_PI);
|
||||
float latitude = rng.Double(M_PI);
|
||||
float dist = (0.4 + rng.Double(0.2)) * AU;
|
||||
Pi::player->SetPosition(vector3d(sin(longitude)*cos(latitude)*dist,
|
||||
sin(latitude)*dist,
|
||||
cos(longitude)*cos(latitude)*dist));
|
||||
Pi::player->SetVelocity(vector3d(0.0));
|
||||
Pi::player->SetFrame(pframe);
|
||||
|
||||
if (new_system) Pi::onPlayerHyperspaceToNewSystem.emit();
|
||||
}
|
||||
|
||||
void Pi::Serialize()
|
||||
{
|
||||
using namespace Serializer::Write;
|
||||
StarSystem::Serialize(selectedSystem);
|
||||
wr_double(gameTime);
|
||||
StarSystem::Serialize(currentSystem);
|
||||
Space::Serialize();
|
||||
sectorView->Save();
|
||||
worldView->Save();
|
||||
}
|
||||
|
||||
void Pi::Unserialize()
|
||||
{
|
||||
using namespace Serializer::Read;
|
||||
selectedSystem = StarSystem::Unserialize();
|
||||
gameTime = rd_double();
|
||||
currentSystem = StarSystem::Unserialize();
|
||||
Space::Clear();
|
||||
if (Pi::player) {
|
||||
Pi::player->MarkDead();
|
||||
Space::bodies.remove(Pi::player);
|
||||
delete Pi::player;
|
||||
Pi::player = 0;
|
||||
}
|
||||
Space::Unserialize();
|
||||
sectorView->Load();
|
||||
worldView->Load();
|
||||
}
|
||||
|
||||
IniConfig::IniConfig(const char *filename)
|
||||
{
|
||||
FILE *f = fopen_or_die(filename, "r");
|
||||
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);
|
||||
}
|
||||
|
|
@ -89,7 +89,7 @@ void Planet::SetRadius(double radius)
|
|||
assert(0);
|
||||
}
|
||||
|
||||
double Planet::GetTerrainHeight(vector3d &pos)
|
||||
double Planet::GetTerrainHeight(const vector3d pos)
|
||||
{
|
||||
double radius = GetRadius();
|
||||
if (m_geosphere) {
|
||||
|
@ -321,20 +321,20 @@ void Planet::Render(const Frame *a_camFrame)
|
|||
{
|
||||
glPushMatrix();
|
||||
|
||||
double rad = sbody->GetRadius();
|
||||
matrix4x4d ftran;
|
||||
Frame::GetFrameTransform(GetFrame(), a_camFrame, ftran);
|
||||
vector3d fpos = ftran * GetPosition();
|
||||
double rad = GetRadius();
|
||||
|
||||
double apparent_size = rad / fpos.Length();
|
||||
double len = fpos.Length();
|
||||
double origLen = len;
|
||||
|
||||
do {
|
||||
while ((len-rad)*0.25 > 32*WORLDVIEW_ZNEAR) {
|
||||
rad *= 0.25;
|
||||
fpos = 0.25*fpos;
|
||||
len *= 0.25;
|
||||
} while ((len-rad)*0.25 > 4*WORLDVIEW_ZNEAR);
|
||||
}
|
||||
|
||||
glTranslatef(fpos.x, fpos.y, fpos.z);
|
||||
glColor3f(1,1,1);
|
||||
|
|
|
@ -21,7 +21,7 @@ public:
|
|||
virtual void SetFrame(Frame *f);
|
||||
virtual bool OnCollision(Body *b, Uint32 flags) { return true; }
|
||||
virtual double GetMass() const { return m_mass; }
|
||||
double GetTerrainHeight(vector3d &pos);
|
||||
double GetTerrainHeight(const vector3d pos);
|
||||
protected:
|
||||
virtual void Save();
|
||||
virtual void Load();
|
||||
|
|
|
@ -84,6 +84,8 @@ void Player::SetDockedWith(SpaceStation *s, int port)
|
|||
|
||||
void Player::TimeStepUpdate(const float timeStep)
|
||||
{
|
||||
Body *b;
|
||||
vector3d v;
|
||||
ClearThrusterState();
|
||||
if (Pi::GetView() == Pi::worldView) PollControls();
|
||||
|
||||
|
@ -109,7 +111,14 @@ void Player::TimeStepUpdate(const float timeStep)
|
|||
}
|
||||
break;
|
||||
case CONTROL_FIXSPEED:
|
||||
AIAccelToModelRelativeVelocity(vector3d(0,0,-m_setSpeed));
|
||||
b = (GetCombatTarget() ? GetCombatTarget() : GetNavTarget());
|
||||
v = -m_setSpeed;
|
||||
if (b) {
|
||||
matrix4x4d m;
|
||||
GetRotMatrix(m);
|
||||
v += m.InverseOf() * b->GetVelocityRelativeTo(this->GetFrame());
|
||||
}
|
||||
AIAccelToModelRelativeVelocity(v);
|
||||
break;
|
||||
case CONTROL_AUTOPILOT:
|
||||
break;
|
||||
|
@ -224,8 +233,15 @@ void Player::DrawHUD(const Frame *cam_frame)
|
|||
|
||||
// Direction indicator
|
||||
const float sz = HUD_CROSSHAIR_SIZE;
|
||||
vector3d vel = GetVelocity();
|
||||
vel -= GetFrame()->GetStasisVelocityAtPosition(GetPosition());
|
||||
vector3d vel;
|
||||
Body *velRelTo = (GetCombatTarget() ? GetCombatTarget() : GetNavTarget());
|
||||
if (velRelTo) {
|
||||
vel = GetVelocityRelativeTo(velRelTo);
|
||||
} else {
|
||||
vel = GetVelocity() - GetFrame()->GetStasisVelocityAtPosition(GetPosition());
|
||||
}
|
||||
|
||||
//vector3d Frame::GetFrameRelativeVelocity(const Frame *fFrom, const Frame *fTo)
|
||||
|
||||
vector3d loc_v = cam_frame->GetOrientation().InverseOf() * vel;
|
||||
if (loc_v.z < 0) {
|
||||
|
@ -302,12 +318,13 @@ void Player::DrawHUD(const Frame *cam_frame)
|
|||
}
|
||||
|
||||
{
|
||||
double _vel = sqrt(vel[0]*vel[0] + vel[1]*vel[1] + vel[2]*vel[2]);
|
||||
double _vel = vel.Length();
|
||||
char buf[128];
|
||||
const char *rel_to = (velRelTo ? velRelTo->GetLabel().c_str() : GetFrame()->GetLabel());
|
||||
if (_vel > 1000) {
|
||||
snprintf(buf,sizeof(buf), "Velocity: %.2f km/s", _vel*0.001);
|
||||
snprintf(buf,sizeof(buf), "Velocity: %.2f km/s (relative to %s)", _vel*0.001, rel_to);
|
||||
} else {
|
||||
snprintf(buf,sizeof(buf), "Velocity: %.0f m/s", _vel);
|
||||
snprintf(buf,sizeof(buf), "Velocity: %.0f m/s (relative to %s)", _vel, rel_to);
|
||||
}
|
||||
glPushMatrix();
|
||||
glTranslatef(2, Gui::Screen::GetHeight()-Gui::Screen::GetFontHeight()-66, 0);
|
||||
|
|
|
@ -112,7 +112,10 @@ Frame *GetFrameWithSBody(const SBody *b)
|
|||
|
||||
void MoveOrbitingObjectFrames(Frame *f)
|
||||
{
|
||||
if (f->m_sbody) {
|
||||
if (f == Space::rootFrame) {
|
||||
f->SetPosition(vector3d(0,0,0));
|
||||
f->SetVelocity(vector3d(0,0,0));
|
||||
} else if (f->m_sbody) {
|
||||
// this isn't very smegging efficient
|
||||
vector3d pos = f->m_sbody->orbit.CartesianPosAtTime(Pi::GetGameTime());
|
||||
vector3d pos2 = f->m_sbody->orbit.CartesianPosAtTime(Pi::GetGameTime()+1.0);
|
||||
|
|
|
@ -740,7 +740,7 @@ void StarSystem::MakePlanetsAround(SBody *primary)
|
|||
discMax = MIN(discMax, fixed(1,3)*primary->CalcHillRadius());
|
||||
}
|
||||
|
||||
printf("Around %s: Range %f -> %f AU\n", primary->name.c_str(), discMin.ToDouble(), discMax.ToDouble());
|
||||
//printf("Around %s: Range %f -> %f AU\n", primary->name.c_str(), discMin.ToDouble(), discMax.ToDouble());
|
||||
|
||||
fixed initialJump = rand.NFixed(5);
|
||||
fixed pos = (fixed(1,1) - initialJump)*discMin + (initialJump*discMax);
|
||||
|
@ -842,7 +842,6 @@ void SBody::PickPlanetType(StarSystem *system, MTRand &rand)
|
|||
fixed minDistToStar, maxDistToStar, averageDistToStar;
|
||||
const SBody *star = FindStarAndTrueOrbitalRange(minDistToStar, maxDistToStar);
|
||||
averageDistToStar = (minDistToStar+maxDistToStar)>>1;
|
||||
printf("Star of %s is %s\n", name.c_str(), star->name.c_str());
|
||||
|
||||
/* this is all of course a total fucking joke and un-physical */
|
||||
int bbody_temp;
|
||||
|
|
667
src/main.cpp
667
src/main.cpp
|
@ -1,671 +1,6 @@
|
|||
#include <signal.h>
|
||||
#include "libs.h"
|
||||
#include "Pi.h"
|
||||
#include "Gui.h"
|
||||
#include "glfreetype.h"
|
||||
#include "Player.h"
|
||||
#include "Space.h"
|
||||
#include "Planet.h"
|
||||
#include "Star.h"
|
||||
#include "Frame.h"
|
||||
#include "ShipCpanel.h"
|
||||
#include "SectorView.h"
|
||||
#include "SystemView.h"
|
||||
#include "SystemInfoView.h"
|
||||
#include "WorldView.h"
|
||||
#include "ObjectViewerView.h"
|
||||
#include "StarSystem.h"
|
||||
#include "SpaceStation.h"
|
||||
#include "SpaceStationView.h"
|
||||
#include "CargoBody.h"
|
||||
#include "InfoView.h"
|
||||
#include "Serializer.h"
|
||||
#include "NameGenerator.h"
|
||||
#include "mods/Mods.h"
|
||||
|
||||
float Pi::timeAccel = 1.0f;
|
||||
int Pi::scrWidth;
|
||||
int Pi::scrHeight;
|
||||
float Pi::scrAspect;
|
||||
SDL_Surface *Pi::scrSurface;
|
||||
sigc::signal<void, SDL_keysym*> Pi::onKeyPress;
|
||||
sigc::signal<void, SDL_keysym*> Pi::onKeyRelease;
|
||||
sigc::signal<void, int, int, int> Pi::onMouseButtonUp;
|
||||
sigc::signal<void, int, int, int> Pi::onMouseButtonDown;
|
||||
sigc::signal<void> Pi::onPlayerChangeHyperspaceTarget;
|
||||
sigc::signal<void> Pi::onPlayerHyperspaceToNewSystem;
|
||||
char Pi::keyState[SDLK_LAST];
|
||||
char Pi::mouseButton[5];
|
||||
int Pi::mouseMotion[2];
|
||||
enum Pi::MapView Pi::mapView;
|
||||
Player *Pi::player;
|
||||
View *Pi::currentView;
|
||||
WorldView *Pi::worldView;
|
||||
ObjectViewerView *Pi::objectViewerView;
|
||||
SpaceStationView *Pi::spaceStationView;
|
||||
InfoView *Pi::infoView;
|
||||
SectorView *Pi::sectorView;
|
||||
SystemView *Pi::systemView;
|
||||
SystemInfoView *Pi::systemInfoView;
|
||||
ShipCpanel *Pi::cpan;
|
||||
StarSystem *Pi::selectedSystem;
|
||||
StarSystem *Pi::currentSystem;
|
||||
MTRand Pi::rng;
|
||||
double Pi::gameTime;
|
||||
float Pi::frameTime;
|
||||
GLUquadric *Pi::gluQuadric;
|
||||
bool Pi::showDebugInfo;
|
||||
int Pi::statSceneTris;
|
||||
|
||||
void Pi::Init(IniConfig &config)
|
||||
{
|
||||
int width = config.Int("ScrWidth");
|
||||
int height = config.Int("ScrHeight");
|
||||
const SDL_VideoInfo *info = NULL;
|
||||
Uint32 sdlInitFlags = SDL_INIT_VIDEO;
|
||||
#if defined _WIN32 && defined _DEBUG
|
||||
sdlInitFlags |= SDL_INIT_NOPARACHUTE;
|
||||
#endif
|
||||
if (SDL_Init(sdlInitFlags) < 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");
|
||||
Pi::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 ((Pi::scrSurface = SDL_SetVideoMode(width, height, info->vfmt->BitsPerPixel, flags)) == 0) {
|
||||
// fall back on 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 ((Pi::scrSurface = SDL_SetVideoMode(width, height, info->vfmt->BitsPerPixel, flags)) == 0) {
|
||||
fprintf(stderr, "Video mode set failed: %s\n", SDL_GetError());
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
glewInit();
|
||||
SDL_WM_SetCaption("Pioneer","Pioneer");
|
||||
Pi::scrWidth = width;
|
||||
Pi::scrHeight = height;
|
||||
Pi::scrAspect = width / (float)height;
|
||||
|
||||
Pi::rng.seed(time(NULL));
|
||||
|
||||
NameGenerator::Init();
|
||||
InitOpenGL();
|
||||
|
||||
GLFTInit();
|
||||
Space::Init();
|
||||
|
||||
Gui::Init(scrWidth, scrHeight, 800, 600);
|
||||
Mods::Init();
|
||||
}
|
||||
|
||||
void Pi::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 ();
|
||||
|
||||
fprintf(stderr, "GL_ARB_vertex_buffer_object: %s\n", GLEW_ARB_vertex_buffer_object ? "Yes" : "No");
|
||||
}
|
||||
|
||||
void Pi::Quit()
|
||||
{
|
||||
SDL_Quit();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void Pi::SetTimeAccel(float s)
|
||||
{
|
||||
// don't want player to spin like mad when hitting time accel
|
||||
if (s > 10) {
|
||||
player->SetAngVelocity(vector3d(0,0,0));
|
||||
player->SetTorque(vector3d(0,0,0));
|
||||
player->SetAngThrusterState(0, 0.0f);
|
||||
player->SetAngThrusterState(1, 0.0f);
|
||||
player->SetAngThrusterState(2, 0.0f);
|
||||
}
|
||||
timeAccel = s;
|
||||
}
|
||||
|
||||
void Pi::SetMapView(enum MapView v)
|
||||
{
|
||||
mapView = v;
|
||||
if (v == MAP_SECTOR)
|
||||
SetView(sectorView);
|
||||
else
|
||||
SetView(systemView);
|
||||
}
|
||||
|
||||
void Pi::SetView(View *v)
|
||||
{
|
||||
if (currentView) currentView->HideAll();
|
||||
currentView = v;
|
||||
currentView->OnSwitchTo();
|
||||
currentView->ShowAll();
|
||||
}
|
||||
|
||||
void Screendump(char *destFile)
|
||||
{
|
||||
const int W = Pi::GetScrWidth();
|
||||
const int H = Pi::GetScrHeight();
|
||||
std::vector<char> pixel_data(3*W*H);
|
||||
short TGAhead[] = {0, 2, 0, 0, 0, 0, W, H, 24};
|
||||
FILE *out = fopen(destFile, "w");
|
||||
if (!out) goto error;
|
||||
glReadBuffer(GL_FRONT);
|
||||
glReadPixels(0, 0, W, H, GL_BGR, GL_UNSIGNED_BYTE, &pixel_data[0]);
|
||||
if (fwrite(&TGAhead, sizeof(TGAhead), 3, out) != 3) goto error;
|
||||
if (fwrite(&pixel_data[0], 3*W*H, 1, out) != 1) goto error;
|
||||
fclose(out);
|
||||
return;
|
||||
error:
|
||||
printf("Failed to write screendump.\n");
|
||||
}
|
||||
|
||||
void Pi::HandleEvents()
|
||||
{
|
||||
SDL_Event event;
|
||||
|
||||
Pi::mouseMotion[0] = Pi::mouseMotion[1] = 0;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
Gui::HandleSDLEvent(&event);
|
||||
switch (event.type) {
|
||||
case SDL_KEYDOWN:
|
||||
if (KeyState(SDLK_LCTRL) && (event.key.keysym.sym == SDLK_q)) Pi::Quit();
|
||||
if (event.key.keysym.sym == SDLK_i) Pi::showDebugInfo = !Pi::showDebugInfo;
|
||||
if ((event.key.keysym.sym == SDLK_PRINT) && KeyState(SDLK_LCTRL)) {
|
||||
char buf[256];
|
||||
const time_t t = time(0);
|
||||
struct tm *_tm = localtime(&t);
|
||||
strftime(buf, sizeof(buf), "screenshot-%Y%m%d-%H%M%S.tga", _tm);
|
||||
Screendump(buf);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (event.key.keysym.sym == SDLK_F12) {
|
||||
matrix4x4d m; Pi::player->GetRotMatrix(m);
|
||||
vector3d dir = m*vector3d(0,0,-1);
|
||||
/* add test object */
|
||||
if (KeyState(SDLK_LSHIFT)) {
|
||||
Frame *rotFrame = new Frame(Pi::player->GetFrame(), "Station rot frame");
|
||||
rotFrame->SetRadius(3000.0);//(1.1*sbody->GetRadius());
|
||||
rotFrame->SetPosition(Pi::player->GetPosition()+5000.0*dir);
|
||||
rotFrame->SetAngVelocity(vector3d(0,2*M_PI/10,0));
|
||||
SpaceStation *station = new SpaceStation(SpaceStation::JJHOOP);
|
||||
station->SetLabel("Poemi-chan's Folly");
|
||||
station->SetFrame(rotFrame);
|
||||
station->SetRotMatrix(matrix4x4d::RotateZMatrix(M_PI));
|
||||
Space::AddBody(station);
|
||||
} else if (KeyState(SDLK_RSHIFT)) {
|
||||
CargoBody *cargo = new CargoBody(Equip::HYDROGEN);
|
||||
cargo->SetFrame(Pi::player->GetFrame());
|
||||
cargo->SetPosition(Pi::player->GetPosition()+100.0*dir);
|
||||
cargo->SetVelocity(Pi::player->GetVelocity());
|
||||
Space::AddBody(cargo);
|
||||
} else {
|
||||
Ship *ship = new Ship(ShipType::LADYBIRD);
|
||||
ship->AIInstruct(Ship::DO_KILL, Pi::player);
|
||||
ship->SetFrame(Pi::player->GetFrame());
|
||||
ship->SetPosition(Pi::player->GetPosition()+100.0*dir);
|
||||
ship->SetVelocity(Pi::player->GetVelocity());
|
||||
Space::AddBody(ship);
|
||||
}
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
if (event.key.keysym.sym == SDLK_F11) SDL_WM_ToggleFullScreen(Pi::scrSurface);
|
||||
if (event.key.keysym.sym == SDLK_F10) Pi::SetView(Pi::objectViewerView);
|
||||
if (event.key.keysym.sym == SDLK_F9) Serializer::Write::Game("quicksave.sav");
|
||||
Pi::keyState[event.key.keysym.sym] = 1;
|
||||
Pi::onKeyPress.emit(&event.key.keysym);
|
||||
break;
|
||||
case SDL_KEYUP:
|
||||
Pi::keyState[event.key.keysym.sym] = 0;
|
||||
Pi::onKeyRelease.emit(&event.key.keysym);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
Pi::mouseButton[event.button.button] = 1;
|
||||
Pi::onMouseButtonDown.emit(event.button.button,
|
||||
event.button.x, event.button.y);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
Pi::mouseButton[event.button.button] = 0;
|
||||
Pi::onMouseButtonUp.emit(event.button.button,
|
||||
event.button.x, event.button.y);
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
Pi::mouseMotion[0] += event.motion.xrel;
|
||||
Pi::mouseMotion[1] += event.motion.yrel;
|
||||
// SDL_GetRelativeMouseState(&Pi::mouseMotion[0], &Pi::mouseMotion[1]);
|
||||
break;
|
||||
case SDL_QUIT:
|
||||
Pi::Quit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_intro(float _time)
|
||||
{
|
||||
static float lightCol[4] = { 1,1,1,0 };
|
||||
static float lightDir[4] = { 0,1,0,0 };
|
||||
|
||||
static ObjParams params = {
|
||||
{ 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0.0f, 0.0f, -1.0f }, { 0.0f, 0.0f, 0.0f },
|
||||
{ // pColor[3]
|
||||
{ { .2f, .2f, .5f }, { 1, 1, 1 }, { 0, 0, 0 }, 100.0 },
|
||||
{ { 0.5f, 0.5f, 0.5f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 },
|
||||
{ { 0.8f, 0.8f, 0.8f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 } },
|
||||
{ "PIONEER" },
|
||||
};
|
||||
glRotatef(_time*10, 1, 0, 0);
|
||||
Pi::worldView->DrawBgStars();
|
||||
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
||||
sbreSetDepthRange(Pi::GetScrWidth()*0.5, 0.0f, 1.0f);
|
||||
sbreSetDirLight (lightCol, lightDir);
|
||||
matrix4x4d rot = matrix4x4d::RotateYMatrix(_time) * matrix4x4d::RotateZMatrix(0.6*_time) *
|
||||
matrix4x4d::RotateXMatrix(_time*.7);
|
||||
vector3d p(0, 0, -80);
|
||||
sbreRenderModel(&p.x, &rot[0], 61, ¶ms);
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
static void draw_tombstone(float _time)
|
||||
{
|
||||
static float lightCol[4] = { 1,1,1,0 };
|
||||
static float lightDir[4] = { 0,1,0,0 };
|
||||
|
||||
static ObjParams params = {
|
||||
{ 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 0.0f },
|
||||
{ // pColor[3]
|
||||
{ { 1.0f, 1.0f, 1.0f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 },
|
||||
{ { 0.8f, 0.6f, 0.5f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 },
|
||||
{ { 0.5f, 0.5f, 0.5f }, { 0, 0, 0 }, { 0, 0, 0 }, 0 } },
|
||||
{ "RIP OLD BEAN" },
|
||||
};
|
||||
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
||||
sbreSetDepthRange(Pi::GetScrWidth()*0.5, 0.0f, 1.0f);
|
||||
sbreSetDirLight (lightCol, lightDir);
|
||||
matrix4x4d rot = matrix4x4d::RotateYMatrix(_time*2);
|
||||
vector3d p(0, 0, -MAX(150 - 30*_time, 30));
|
||||
sbreRenderModel(&p.x, &rot[0], 91, ¶ms);
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
void Pi::TombStoneLoop()
|
||||
{
|
||||
Uint32 last_time = SDL_GetTicks();
|
||||
float _time = 0;
|
||||
cpan->HideAll();
|
||||
currentView->HideAll();
|
||||
do {
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
float fracH = 1.0 / Pi::GetScrAspect();
|
||||
glFrustum(-1, 1, -fracH, fracH, 1.0f, 10000.0f);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glClearColor(0,0,0,0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
Pi::HandleEvents();
|
||||
SDL_ShowCursor(1);
|
||||
SDL_WM_GrabInput(SDL_GRAB_OFF);
|
||||
|
||||
draw_tombstone(_time);
|
||||
Gui::Draw();
|
||||
glFlush();
|
||||
SDL_GL_SwapBuffers();
|
||||
|
||||
Pi::frameTime = 0.001*(SDL_GetTicks() - last_time);
|
||||
_time += Pi::frameTime;
|
||||
last_time = SDL_GetTicks();
|
||||
} while (!((_time > 2.0) && ((Pi::MouseButtonState(1)) || Pi::KeyState(SDLK_SPACE)) ));
|
||||
}
|
||||
|
||||
void Pi::Start()
|
||||
{
|
||||
player = new Player(ShipType::SWANKY);
|
||||
player->m_equipment.Set(Equip::SLOT_ENGINE, 0, Equip::DRIVE_CLASS1);
|
||||
player->m_equipment.Set(Equip::SLOT_LASER, 0, Equip::LASER_2MW_BEAM);
|
||||
player->m_equipment.Set(Equip::SLOT_LASER, 1, Equip::LASER_4MW_BEAM);
|
||||
player->m_equipment.Add(Equip::SLOT_CARGO, Equip::HYDROGEN);
|
||||
player->m_equipment.Add(Equip::SLOT_CARGO, Equip::HYDROGEN);
|
||||
player->m_equipment.Add(Equip::SLOT_CARGO, Equip::HYDROGEN);
|
||||
player->SetLabel("me");
|
||||
player->SetMoney(1000);
|
||||
Space::AddBody(player);
|
||||
|
||||
cpan = new ShipCpanel();
|
||||
sectorView = new SectorView();
|
||||
systemView = new SystemView();
|
||||
systemInfoView = new SystemInfoView();
|
||||
worldView = new WorldView();
|
||||
objectViewerView = new ObjectViewerView();
|
||||
spaceStationView = new SpaceStationView();
|
||||
infoView = new InfoView();
|
||||
|
||||
Gui::Fixed *splash = new Gui::Fixed(Gui::Screen::GetWidth(), Gui::Screen::GetHeight());
|
||||
Gui::Screen::AddBaseWidget(splash, 0, 0);
|
||||
splash->SetTransparency(true);
|
||||
|
||||
const float w = Gui::Screen::GetWidth() / 2;
|
||||
const float h = Gui::Screen::GetHeight() / 2;
|
||||
const int OPTS = 4;
|
||||
Gui::ToggleButton *opts[OPTS];
|
||||
opts[0] = new Gui::ToggleButton(); opts[0]->SetShortcut(SDLK_1, KMOD_NONE);
|
||||
opts[1] = new Gui::ToggleButton(); opts[1]->SetShortcut(SDLK_2, KMOD_NONE);
|
||||
opts[2] = new Gui::ToggleButton(); opts[2]->SetShortcut(SDLK_3, KMOD_NONE);
|
||||
opts[3] = new Gui::ToggleButton(); opts[3]->SetShortcut(SDLK_4, KMOD_NONE);
|
||||
splash->Add(opts[0], w, h-64);
|
||||
splash->Add(new Gui::Label("New game starting on Earth"), w+32, h-64);
|
||||
splash->Add(opts[1], w, h-32);
|
||||
splash->Add(new Gui::Label("New game starting on debug point"), w+32, h-32);
|
||||
splash->Add(opts[2], w, h);
|
||||
splash->Add(new Gui::Label("Load quicksave"), w+32, h);
|
||||
splash->Add(opts[3], w, h+32);
|
||||
splash->Add(new Gui::Label("Quit"), w+32, h+32);
|
||||
|
||||
splash->ShowAll();
|
||||
|
||||
int choice = 0;
|
||||
Uint32 last_time = SDL_GetTicks();
|
||||
float _time = 0;
|
||||
do {
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
float fracH = 1.0 / Pi::GetScrAspect();
|
||||
glFrustum(-1, 1, -fracH, fracH, 1.0f, 10000.0f);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glClearColor(0,0,0,0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
Pi::HandleEvents();
|
||||
SDL_ShowCursor(1);
|
||||
SDL_WM_GrabInput(SDL_GRAB_OFF);
|
||||
|
||||
draw_intro(_time);
|
||||
Gui::Draw();
|
||||
glFlush();
|
||||
SDL_GL_SwapBuffers();
|
||||
|
||||
Pi::frameTime = 0.001*(SDL_GetTicks() - last_time);
|
||||
_time += Pi::frameTime;
|
||||
last_time = SDL_GetTicks();
|
||||
|
||||
// poll ui instead of using callbacks :-J
|
||||
for (int i=0; i<OPTS; i++) if (opts[i]->GetPressed()) choice = i+1;
|
||||
} while (!choice);
|
||||
splash->HideAll();
|
||||
|
||||
if (choice == 1) {
|
||||
/* Earth start point */
|
||||
SBodyPath path(0,0,0);
|
||||
HyperspaceTo(&path);
|
||||
//Frame *pframe = *(++(++(Space::rootFrame->m_children.begin())));
|
||||
//player->SetFrame(pframe);
|
||||
// XXX there isn't a sensible way to find stations for a planet.
|
||||
SpaceStation *station = 0;
|
||||
for (Space::bodiesIter_t i = Space::bodies.begin(); i!=Space::bodies.end(); i++) {
|
||||
if ((*i)->IsType(Object::SPACESTATION)) { station = (SpaceStation*)*i; break; }
|
||||
}
|
||||
assert(station);
|
||||
player->SetFrame(station->GetFrame());
|
||||
player->SetDockedWith(station, 0);
|
||||
MainLoop();
|
||||
} else if (choice == 2) {
|
||||
/* debug start point */
|
||||
SBodyPath path(0,0,1);
|
||||
path.elem[0] = 0; // zeroth child of root body
|
||||
HyperspaceTo(&path);
|
||||
player->SetPosition(vector3d(0,0,2*EARTH_RADIUS));
|
||||
/* Frame *stationFrame = new Frame(pframe, "Station frame...");
|
||||
stationFrame->SetRadius(5000);
|
||||
stationFrame->m_sbody = 0;
|
||||
stationFrame->SetPosition(vector3d(0,0,zpos));
|
||||
stationFrame->SetAngVelocity(vector3d(0,0,0.5));
|
||||
|
||||
for (int i=0; i<4; i++) {
|
||||
Ship *body = new Ship(ShipType::LADYBIRD);
|
||||
char buf[64];
|
||||
snprintf(buf,sizeof(buf),"X%c-0%02d", 'A'+i, i);
|
||||
body->SetLabel(buf);
|
||||
body->SetFrame(stationFrame);
|
||||
body->SetPosition(vector3d(200*(i+1), 0, 2000));
|
||||
Space::AddBody(body);
|
||||
}
|
||||
|
||||
SpaceStation *station = new SpaceStation(SpaceStation::JJHOOP);
|
||||
station->SetLabel("Poemi-chan's Folly");
|
||||
station->SetFrame(stationFrame);
|
||||
station->SetPosition(vector3d(0,0,0));
|
||||
Space::AddBody(station);
|
||||
|
||||
SpaceStation *station2 = new SpaceStation(SpaceStation::GROUND_FLAVOURED);
|
||||
station2->SetLabel("Conor's End");
|
||||
station2->SetFrame(*pframe->m_children.begin()); // rotating frame of planet
|
||||
station2->OrientOnSurface(EARTH_RADIUS, M_PI/4, M_PI/4);
|
||||
Space::AddBody(station2);
|
||||
*/
|
||||
// player->SetDockedWith(station2, 0);
|
||||
|
||||
MainLoop();
|
||||
} else if (choice == 3) {
|
||||
// load quicksave
|
||||
Serializer::Read::Game("quicksave.sav");
|
||||
MainLoop();
|
||||
}
|
||||
}
|
||||
|
||||
void Pi::MainLoop()
|
||||
{
|
||||
cpan->ShowAll();
|
||||
|
||||
SetView(worldView);
|
||||
|
||||
Uint32 last_stats = SDL_GetTicks();
|
||||
int frame_stat = 0;
|
||||
int phys_stat = 0;
|
||||
char fps_readout[128];
|
||||
Uint32 time_before_frame = SDL_GetTicks();
|
||||
Uint32 last_phys_update = time_before_frame;
|
||||
|
||||
for (;;) {
|
||||
frame_stat++;
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
currentView->Draw3D();
|
||||
// XXX 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.
|
||||
Pi::HandleEvents();
|
||||
// hide cursor for ship control.
|
||||
if (Pi::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
|
||||
if (Pi::showDebugInfo) {
|
||||
Gui::Screen::EnterOrtho();
|
||||
glColor3f(1,1,1);
|
||||
Gui::Screen::RenderString(fps_readout);
|
||||
Gui::Screen::LeaveOrtho();
|
||||
}
|
||||
//#endif /* DEBUG */
|
||||
|
||||
glFlush();
|
||||
SDL_GL_SwapBuffers();
|
||||
//if (glGetError()) printf ("GL: %s\n", gluErrorString (glGetError ()));
|
||||
|
||||
Pi::frameTime = 0.001*(SDL_GetTicks() - time_before_frame);
|
||||
time_before_frame = SDL_GetTicks();
|
||||
|
||||
// Fixed 62.5hz physics
|
||||
int num_steps = 0;
|
||||
while (time_before_frame - last_phys_update > 16) {
|
||||
last_phys_update += 16;
|
||||
const float step = Pi::GetTimeStep();
|
||||
if (step) Space::TimeStep(step);
|
||||
gameTime += step;
|
||||
phys_stat++;
|
||||
if (++num_steps > 3) break;
|
||||
}
|
||||
currentView->Update();
|
||||
|
||||
if (SDL_GetTicks() - last_stats > 1000) {
|
||||
snprintf(fps_readout, sizeof(fps_readout), "%d fps, %d phys updates, %d triangles, %.3f M tris/sec", frame_stat, phys_stat, Pi::statSceneTris, Pi::statSceneTris*frame_stat*1e-6);
|
||||
frame_stat = 0;
|
||||
phys_stat = 0;
|
||||
last_stats += 1000;
|
||||
}
|
||||
Pi::statSceneTris = 0;
|
||||
}
|
||||
}
|
||||
|
||||
StarSystem *Pi::GetSelectedSystem()
|
||||
{
|
||||
int sector_x, sector_y, system_idx;
|
||||
Pi::sectorView->GetSelectedSystem(§or_x, §or_y, &system_idx);
|
||||
if (system_idx == -1) {
|
||||
selectedSystem = 0;
|
||||
return NULL;
|
||||
}
|
||||
if (selectedSystem) {
|
||||
if (!selectedSystem->IsSystem(sector_x, sector_y, system_idx)) {
|
||||
delete selectedSystem;
|
||||
selectedSystem = 0;
|
||||
}
|
||||
}
|
||||
if (!selectedSystem) {
|
||||
selectedSystem = new StarSystem(sector_x, sector_y, system_idx);
|
||||
}
|
||||
return selectedSystem;
|
||||
}
|
||||
|
||||
void Pi::HyperspaceTo(const SBodyPath *dest)
|
||||
{
|
||||
bool new_system = false;
|
||||
if (currentSystem) {
|
||||
if (!currentSystem->IsSystem(dest->sectorX, dest->sectorY, dest->systemIdx)) {
|
||||
delete currentSystem;
|
||||
currentSystem = 0;
|
||||
}
|
||||
}
|
||||
if (!currentSystem) {
|
||||
currentSystem = new StarSystem(dest->sectorX, dest->sectorY, dest->systemIdx);
|
||||
Space::Clear();
|
||||
Space::BuildSystem();
|
||||
new_system = true;
|
||||
}
|
||||
|
||||
|
||||
SBody *targetBody = currentSystem->GetBodyByPath(dest);
|
||||
Frame *pframe = Space::GetFrameWithSBody(targetBody);
|
||||
assert(pframe);
|
||||
float longitude = rng.Double(M_PI);
|
||||
float latitude = rng.Double(M_PI);
|
||||
float dist = (0.4 + rng.Double(0.2)) * AU;
|
||||
Pi::player->SetPosition(vector3d(sin(longitude)*cos(latitude)*dist,
|
||||
sin(latitude)*dist,
|
||||
cos(longitude)*cos(latitude)*dist));
|
||||
Pi::player->SetVelocity(vector3d(0.0));
|
||||
Pi::player->SetFrame(pframe);
|
||||
|
||||
if (new_system) Pi::onPlayerHyperspaceToNewSystem.emit();
|
||||
}
|
||||
|
||||
void Pi::Serialize()
|
||||
{
|
||||
using namespace Serializer::Write;
|
||||
StarSystem::Serialize(selectedSystem);
|
||||
wr_double(gameTime);
|
||||
StarSystem::Serialize(currentSystem);
|
||||
Space::Serialize();
|
||||
sectorView->Save();
|
||||
worldView->Save();
|
||||
}
|
||||
|
||||
void Pi::Unserialize()
|
||||
{
|
||||
using namespace Serializer::Read;
|
||||
selectedSystem = StarSystem::Unserialize();
|
||||
gameTime = rd_double();
|
||||
currentSystem = StarSystem::Unserialize();
|
||||
Space::Clear();
|
||||
if (Pi::player) {
|
||||
Pi::player->MarkDead();
|
||||
Space::bodies.remove(Pi::player);
|
||||
delete Pi::player;
|
||||
Pi::player = 0;
|
||||
}
|
||||
Space::Unserialize();
|
||||
sectorView->Load();
|
||||
worldView->Load();
|
||||
}
|
||||
|
||||
IniConfig::IniConfig(const char *filename)
|
||||
{
|
||||
FILE *f = fopen_or_die(filename, "r");
|
||||
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);
|
||||
}
|
||||
#include <signal.h>
|
||||
|
||||
void sigsegv_handler(int signum)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
#include "Pi.h"
|
||||
#include "Frame.h"
|
||||
#include "Space.h"
|
||||
|
||||
#define CRAP 0.00001
|
||||
static void test(vector3d a, vector3d b)
|
||||
{
|
||||
vector3d c = a-b;
|
||||
c.x = fabs(c.x);
|
||||
c.y = fabs(c.y);
|
||||
c.z = fabs(c.z);
|
||||
if ((c.x < CRAP) && (c.y < CRAP) && (c.z < CRAP)) {
|
||||
printf("PASSED\n");
|
||||
} else {
|
||||
printf("\nFAILED-------------------\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_frames(Frame *f, int depth)
|
||||
{
|
||||
for(int i=0; i<depth; i++) putchar('\t');
|
||||
printf("%s: Vel %f\n", f->GetLabel(), f->GetVelocity().Length());
|
||||
std::list<Frame*> m_children;
|
||||
for (std::list<Frame*>::iterator i = f->m_children.begin(); i!=f->m_children.end(); ++i) {
|
||||
dump_frames(*i, depth+1);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_frames()
|
||||
{
|
||||
printf("Testing FOR\n");
|
||||
matrix4x4d m;
|
||||
vector3d a,b;
|
||||
Frame *root = new Frame(0, "Root");
|
||||
Space::rootFrame = root;
|
||||
|
||||
Frame *fa1 = new Frame(root, "Fa1");
|
||||
fa1->SetVelocity(vector3d(0,0,10));
|
||||
|
||||
Frame *fa2 = new Frame(fa1, "Fa2");
|
||||
fa2->SetVelocity(vector3d(0,0,1));
|
||||
|
||||
Frame *fb1 = new Frame(root, "Fb1");
|
||||
fb1->SetVelocity(vector3d(0,0,10));
|
||||
|
||||
Frame *fb2 = new Frame(fb1, "Fb2");
|
||||
fb2->SetVelocity(vector3d(0,0,5));
|
||||
|
||||
a = Frame::GetFrameRelativeVelocity(fb1, root);
|
||||
b = Frame::GetFrameRelativeVelocity(root, fb1);
|
||||
test(a, vector3d(0,0,-10));
|
||||
test(b, vector3d(0,0,10));
|
||||
a = Frame::GetFrameRelativeVelocity(fb2, root);
|
||||
b = Frame::GetFrameRelativeVelocity(root, fb2);
|
||||
test(a, vector3d(0,0,-15));
|
||||
test(b, vector3d(0,0,15));
|
||||
|
||||
a = Frame::GetFrameRelativeVelocity(fb2, fa2);
|
||||
b = Frame::GetFrameRelativeVelocity(fa2, fb2);
|
||||
test(a, vector3d(0, 0, -4));
|
||||
test(b, vector3d(0, 0, 4));
|
||||
|
||||
|
||||
// ----------- make some frames rotated --------
|
||||
m = matrix4x4d::RotateYMatrix(M_PI/2);
|
||||
fb2->SetOrientation(m);
|
||||
m = matrix4x4d::RotateYMatrix(M_PI);
|
||||
fb1->SetOrientation(m);
|
||||
|
||||
a = Frame::GetFrameRelativeVelocity(fb2, root);
|
||||
b = Frame::GetFrameRelativeVelocity(root, fb2);
|
||||
test(a, vector3d(-10, 0, -5));
|
||||
test(b, vector3d(5, 0, -10));
|
||||
|
||||
a = Frame::GetFrameRelativeVelocity(fb2, fa2);
|
||||
b = Frame::GetFrameRelativeVelocity(fa2, fb2);
|
||||
test(a, vector3d(-21, 0, -5));
|
||||
test(b, vector3d(5, 0, -21));
|
||||
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
test_frames();
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue