Lephisto/src/sector_view.cpp
Allanis 56f5411516 [Add] Some Hyperspace range stuff.
[Add] SectorMap indicates current ship location.
2017-11-13 20:59:38 +00:00

209 lines
5.7 KiB
C++

#include "libs.h"
#include "gui.h"
#include "l3d.h"
#include "sector_view.h"
#include "sector.h"
#include "system_info_view.h"
#include "player.h"
SectorView::SectorView(void) : GenericSystemView() {
SetTransparency(true);
m_px = m_py = 0.5;
m_rot_x = m_rot_z = 0;
m_secx = m_secy = 0;
m_selected = -1;
m_zoom = 1;
m_infoLabel = new Gui::Label("");
Add(m_infoLabel, 2, 2);
Gui::ImageButton* ib = new Gui::ImageButton("icons/sectorview_f6_systeminfo.png");
ib->onClick.connect(sigc::mem_fun(this, &SectorView::OnClickSystemInfo));
ib->SetShortcut(SDLK_F6, KMOD_NONE);
m_rightButtonBar->Add(ib, 2, 2);
m_zoomInButton = new Gui::ImageButton("icons/zoom_in_f7.png");
m_zoomInButton->SetShortcut(SDLK_F7, KMOD_NONE);
m_rightButtonBar->Add(m_zoomInButton, 34, 2);
m_zoomOutButton = new Gui::ImageButton("icons/zoom_out_f8.png");
m_zoomOutButton->SetShortcut(SDLK_F8, KMOD_NONE);
m_rightButtonBar->Add(m_zoomOutButton, 66, 2);
m_gluDiskDlist = glGenLists(1);
glNewList(m_gluDiskDlist, GL_COMPILE);
gluDisk(L3D::gluQuadric, 0.0, 0.2, 20, 1);
glEndList();
}
SectorView::~SectorView(void) {
glDeleteLists(m_gluDiskDlist, 1);
}
void SectorView::OnClickSystemInfo(void) {
L3D::SetView(L3D::system_info_view);
}
bool SectorView::GetSelectedSystem(int* sector_x, int* sector_y, int* system_idx) {
*sector_x = m_secx;
*sector_y = m_secy;
*system_idx = m_selected;
return m_selected != -1;
}
#define DRAW_RAD 2
#define FFRAC(_x) ((_x)-floor(_x))
void SectorView::Draw3D(void) {
GenericSystemView::Draw3D();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(50, L3D::GetScrAspect(), 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
char buf[80];
snprintf(buf, sizeof(buf), "Sector: %d,%d", m_secx, m_secy);
m_infoLabel->SetText(buf);
/* Units are lightyears. */
glTranslatef(0, 0, -10-10*m_zoom);
glRotatef(m_rot_x, 1, 0, 0);
glRotatef(m_rot_z, 0, 0, 1);
glTranslatef(-FFRAC(m_px)*Sector::SIZE, -FFRAC(m_py)*Sector::SIZE, 0);
glDisable(GL_LIGHTING);
for(int sx = -DRAW_RAD; sx <= DRAW_RAD; sx++) {
for(int sy = -DRAW_RAD; sy <= DRAW_RAD; sy++) {
glPushMatrix();
glTranslatef(sx*Sector::SIZE, sy*Sector::SIZE, 0);
DrawSector(m_secx+sx, m_secy+sy);
glPopMatrix();
}
}
glEnable(GL_LIGHTING);
}
void SectorView::PutText(std::string& text) {
/* Highly optimal.. */
GLdouble modelMatrix[16];
GLdouble projMatrix[16];
GLint viewport[4];
glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
glGetIntegerv(GL_VIEWPORT, viewport);
Gui::Screen::EnterOrtho();
vector3d _pos;
if(Gui::Screen::Project(0,0,0, modelMatrix, projMatrix, viewport, &_pos.x, &_pos.y, &_pos.z)) {
Gui::Screen::RenderLabel(text, _pos.x, _pos.y);
}
Gui::Screen::LeaveOrtho();
glDisable(GL_LIGHTING);
}
void SectorView::DrawSector(int sx, int sy) {
Sector s = Sector(sx, sy);
glColor3f(0, .8, 0);
glBegin(GL_LINE_LOOP);
glVertex3f(0, 0, 0);
glVertex3f(0, Sector::SIZE, 0);
glVertex3f(Sector::SIZE, Sector::SIZE, 0);
glVertex3f(Sector::SIZE, 0, 0);
glEnd();
if(!(sx || sy)) glColor3f(1, 1, 0);
int num = 0;
for(std::vector<Sector::System>::iterator i = s.m_systems.begin(); i != s.m_systems.end(); ++i) {
glColor3fv(StarSystem::starColors[(*i).primaryStarClass]);
glPushMatrix();
glTranslatef((*i).p.x, (*i).p.y, 0);
glBegin(GL_LINES);
glVertex3f(0, 0, 0);
glVertex3f(0, 0, (*i).p.z);
glEnd();
glTranslatef(0, 0, (*i).p.z);
glPushMatrix();
glRotatef(-m_rot_z, 0, 0, 1);
glRotatef(-m_rot_x, 1, 0, 0);
glCallList(m_gluDiskDlist);
/* Player location indicator. */
if((sx == L3D::playerLoc.secX) && (sy == L3D::playerLoc.secY) && (num == L3D::playerLoc.sysIdx)) {
shipstats_t stats;
L3D::player->CalcStats(&stats);
glColor3f(0, 0, 1);
glBegin(GL_LINE_LOOP);
/* Draw a lovely circle around our beloved player. */
for(float theta = 0; theta < 2*M_PI; theta += 0.05*M_PI) {
glVertex3f(stats.hyperspace_range*sin(theta), stats.hyperspace_range*cos(theta), 0);
}
glEnd();
glPushMatrix();
glDepthRange(0.2, 1.2);
glColor3f(3, 3, 3);
glCallList(m_gluDiskDlist);
glPopMatrix();
}
/* Selected indicator. */
if((sx == m_secx) && (sy == m_secy) && (num == m_selected)) {
glDepthRange(0.1, 1.1);
glColor3f(0, 0.8, 0);
glScalef(2, 2, 2);
glCallList(m_gluDiskDlist);
}
glDepthRange(0, 1);
glPopMatrix();
glColor3f(.7, .7, .7);
PutText((*i).name);
glPopMatrix();
num++;
}
}
void SectorView::Update(void) {
if(L3D::KeyState(SDLK_LEFT)) m_px -= 0.01;
if(L3D::KeyState(SDLK_RIGHT)) m_px += 0.01;
if(L3D::KeyState(SDLK_UP)) m_py += 0.01;
if(L3D::KeyState(SDLK_DOWN)) m_py -= 0.01;
if(L3D::KeyState(SDLK_EQUALS)) m_zoom *= 0.99;
if(L3D::KeyState(SDLK_MINUS)) m_zoom *= 1.01;
if(m_zoomInButton->IsPressed()) m_zoom *= 0.99;
if(m_zoomOutButton->IsPressed()) m_zoom *= 1.01;
m_zoom = CLAMP(m_zoom, 0.1, 5.0);
if(L3D::MouseButtonState(3)) {
int motion[2];
L3D::GetMouseMotion(motion);
m_rot_x += motion[1];
m_rot_z += motion[0];
}
m_secx = (int)floor(m_px);
m_secy = (int)floor(m_py);
Sector s = Sector(m_secx, m_secy);
float px = FFRAC(m_px)*Sector::SIZE;
float py = FFRAC(m_py)*Sector::SIZE;
m_selected = -1;
float min_dist = FLT_MAX;
for(unsigned int i = 0; i < s.m_systems.size(); i++) {
Sector::System* ss = &s.m_systems[i];
float dx = px - ss->p.x;
float dy = py - ss->p.y;
float dist = sqrtf(dx*dx + dy*dy);
if(dist < min_dist) {
min_dist = dist;
m_selected = i;
}
}
}