|
|
|
|
@ -1,4 +1,15 @@
|
|
|
|
|
|
|
|
|
|
// Some defaults for the game layout
|
|
|
|
|
#define HEX_SIZE 25 |
|
|
|
|
#define HEX_RADIUS 7 |
|
|
|
|
#define HEX_ORIENTATION layout_flat |
|
|
|
|
#define FILL_COLOR 0x5C5C5CFF |
|
|
|
|
#define SELECTED_FILL_COLOR 0xF46000FF |
|
|
|
|
#define DEBUG_DRAW true |
|
|
|
|
#define VIEWPORT_WIDTH 1280 |
|
|
|
|
#define VIEWPORT_HEIGHT 720 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <string> |
|
|
|
|
#include <vector> |
|
|
|
|
|
|
|
|
|
@ -17,15 +28,11 @@
|
|
|
|
|
using std::vector; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: global variables
|
|
|
|
|
v2i viewportDims(1280, 720); |
|
|
|
|
vector<hex_info> *hexInfoArray; |
|
|
|
|
Layout global_layout(layout_flat, Point(25, 25), Point(viewportDims.x/2,viewportDims.y/2)); |
|
|
|
|
uint32 selected_fill_color = 0xF46000FF; |
|
|
|
|
uint32 fill_color = 0x5C5C5CFF; |
|
|
|
|
game_state* g_game_state; |
|
|
|
|
render_state* g_render_state; |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
createHexes(vector<hex_info> *hxi_array) |
|
|
|
|
createHexes(vector<hex_info> *hxi_array, const Layout &layout, uint32 color) |
|
|
|
|
{ |
|
|
|
|
// create a hexagonal grid of hexagons
|
|
|
|
|
int map_radius = 7; |
|
|
|
|
@ -37,87 +44,35 @@ createHexes(vector<hex_info> *hxi_array)
|
|
|
|
|
for (int r = r1; r <= r2; r++) |
|
|
|
|
{ |
|
|
|
|
hex_info hxi; |
|
|
|
|
hxi.hexID = (int32) hexInfoArray->size(); |
|
|
|
|
hxi.hexID = (int32) hxi_array->size(); |
|
|
|
|
hxi.hex.q = q; hxi.hex.r = r; hxi.hex.s = -q-r; |
|
|
|
|
Point p = hex_to_pixel(global_layout, hxi.hex); |
|
|
|
|
Point p = hex_to_pixel(layout, hxi.hex); |
|
|
|
|
hxi.XPos = p.x; |
|
|
|
|
hxi.YPos = p.y; |
|
|
|
|
hxi.current_color = fill_color; |
|
|
|
|
hxi.stored_color = hxi.current_color; |
|
|
|
|
hxi.vertices = polygon_corners(global_layout, hxi.hex); |
|
|
|
|
hxi.current_color = color; |
|
|
|
|
hxi.stored_color = color; |
|
|
|
|
hxi.vertices = polygon_corners(layout, hxi.hex); |
|
|
|
|
hxi.vertices.shrink_to_fit(); |
|
|
|
|
hxi_array->push_back(hxi); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// TODO: global variables
|
|
|
|
|
bool isSelecting = false; |
|
|
|
|
hex_info *startHex; |
|
|
|
|
hex_info *currentHex; |
|
|
|
|
vector<hex_info> selectedHexes; |
|
|
|
|
HexDrawMode globalDrawMode = NONE; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
// TODO: many globals used here
|
|
|
|
|
void |
|
|
|
|
debugRender() |
|
|
|
|
{ |
|
|
|
|
if (globalDrawMode == CONE_FILL) |
|
|
|
|
{ |
|
|
|
|
if (startHex && currentHex) |
|
|
|
|
{ |
|
|
|
|
Point p1 = hex_to_pixel(global_layout, startHex->hex); |
|
|
|
|
Point p2 = hex_to_pixel(global_layout, currentHex->hex); |
|
|
|
|
|
|
|
|
|
// NOTE: some cone drawing shenanigans
|
|
|
|
|
real32 angle = (real32) atan2(p2.y - p1.y, p2.x - p1.x); |
|
|
|
|
real32 len = (real32) hypot(p2.y - p1.y, p2.x - p1.x); |
|
|
|
|
real32 coneAngle = 24.5f * (real32) M_PI / 180; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: add matrix math library for rotation transform?
|
|
|
|
|
// |x| | cos(a + b) -sin(a + b) 0 |
|
|
|
|
|
// |y| * | sin(a + b) cos(a + b) 0 |
|
|
|
|
|
// |0| | 0 0 1 |
|
|
|
|
|
//
|
|
|
|
|
real32 x1 = len * cosf(angle); |
|
|
|
|
real32 y1 = len * sinf(angle); |
|
|
|
|
// top of cone
|
|
|
|
|
real32 topX = x1 * cosf(coneAngle) - y1 * sinf(coneAngle) + (real32) p1.x; |
|
|
|
|
real32 topY = x1 * sinf(coneAngle) + y1 * cosf(coneAngle) + (real32) p1.y; |
|
|
|
|
// bottom of cone
|
|
|
|
|
real32 botX = x1 * cosf(coneAngle) + y1 * sinf(coneAngle) + (real32) p1.x; |
|
|
|
|
real32 botY = x1 * sinf(-1 * coneAngle) + y1 * cosf(coneAngle) + (real32) p1.y; |
|
|
|
|
|
|
|
|
|
glColor4f(1.0f, 1.0f, 0.5f, 1.0f); |
|
|
|
|
glLineWidth(1.0f); |
|
|
|
|
glBegin(GL_LINE_LOOP); |
|
|
|
|
glVertex3d(p1.x, p1.y, 0); |
|
|
|
|
glVertex3f(botX, botY, 0); |
|
|
|
|
glVertex3d(p2.x, p2.y, 0); |
|
|
|
|
glVertex3f(topX, topY, 0); |
|
|
|
|
glEnd(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
v2i |
|
|
|
|
mapMouseToViewport(int32 x, int32 y) |
|
|
|
|
{ |
|
|
|
|
v2i coords; |
|
|
|
|
coords.x = x; |
|
|
|
|
coords.y = viewportDims.y - y; |
|
|
|
|
coords.y = g_render_state->viewport_dims.y - y; |
|
|
|
|
return coords; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
resetHexes() |
|
|
|
|
{ |
|
|
|
|
startHex = currentHex = 0; |
|
|
|
|
g_game_state->start_hex = g_game_state->current_hex = 0; |
|
|
|
|
|
|
|
|
|
for (hex_info &hxi : *hexInfoArray) |
|
|
|
|
for (hex_info &hxi : *g_game_state->hex_array) |
|
|
|
|
{ |
|
|
|
|
hxi.selected = false; |
|
|
|
|
hxi.current_color = hxi.stored_color; |
|
|
|
|
@ -128,9 +83,9 @@ hex_info *
|
|
|
|
|
getSingleHex(int32 x, int32 y) |
|
|
|
|
{ |
|
|
|
|
Point p(x, y); |
|
|
|
|
Hex h = hex_round(pixel_to_hex(global_layout, p)); |
|
|
|
|
Hex h = hex_round(pixel_to_hex(g_game_state->hex_layout, p)); |
|
|
|
|
|
|
|
|
|
for (hex_info &hxi : *hexInfoArray) |
|
|
|
|
for (hex_info &hxi : *g_game_state->hex_array) |
|
|
|
|
{ |
|
|
|
|
if (hex_equal(h, hxi.hex)) |
|
|
|
|
{ |
|
|
|
|
@ -145,9 +100,9 @@ void
|
|
|
|
|
setStartHex(hex_info *hex) |
|
|
|
|
{ |
|
|
|
|
hex->selected = true; |
|
|
|
|
hex->current_color = selected_fill_color; |
|
|
|
|
startHex = currentHex = hex; |
|
|
|
|
isSelecting = true; |
|
|
|
|
hex->current_color = g_render_state->selected_fill_color; |
|
|
|
|
g_game_state->start_hex = g_game_state->current_hex = hex; |
|
|
|
|
g_game_state->is_selecting = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
@ -164,20 +119,20 @@ startHexFill(int32 x, int32 y)
|
|
|
|
|
void |
|
|
|
|
updateHexFill(int32 x, int32 y) |
|
|
|
|
{ |
|
|
|
|
if (isSelecting) |
|
|
|
|
if (g_game_state->is_selecting) |
|
|
|
|
{ |
|
|
|
|
hex_info *hxi = getSingleHex(x, y); |
|
|
|
|
if (hxi && (hxi != currentHex)) |
|
|
|
|
if (hxi && (hxi != g_game_state->current_hex)) |
|
|
|
|
{ |
|
|
|
|
currentHex = hxi; |
|
|
|
|
int l = hex_distance(startHex->hex, currentHex->hex); |
|
|
|
|
g_game_state->current_hex = hxi; |
|
|
|
|
int l = hex_distance(g_game_state->start_hex->hex, g_game_state->current_hex->hex); |
|
|
|
|
|
|
|
|
|
for (hex_info &h : *hexInfoArray) |
|
|
|
|
for (hex_info &h : *g_game_state->hex_array) |
|
|
|
|
{ |
|
|
|
|
if (hex_distance(startHex->hex, h.hex) <= l) |
|
|
|
|
if (hex_distance(g_game_state->start_hex->hex, h.hex) <= l) |
|
|
|
|
{ |
|
|
|
|
h.selected = true; |
|
|
|
|
h.current_color = selected_fill_color; |
|
|
|
|
h.current_color = g_render_state->selected_fill_color; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
@ -203,15 +158,15 @@ startHexLineDraw(int32 x, int32 y)
|
|
|
|
|
void |
|
|
|
|
updateHexLineDraw(int32 x, int32 y) |
|
|
|
|
{ |
|
|
|
|
if (isSelecting) |
|
|
|
|
if (g_game_state->is_selecting) |
|
|
|
|
{ |
|
|
|
|
hex_info *hxi = getSingleHex(x, y); |
|
|
|
|
if (hxi && (hxi != currentHex)) |
|
|
|
|
if (hxi && (hxi != g_game_state->current_hex)) |
|
|
|
|
{ |
|
|
|
|
currentHex = hxi; |
|
|
|
|
vector<Hex> hexLine = hex_linedraw(startHex->hex, hxi->hex); |
|
|
|
|
g_game_state->current_hex = hxi; |
|
|
|
|
vector<Hex> hexLine = hex_linedraw(g_game_state->start_hex->hex, hxi->hex); |
|
|
|
|
|
|
|
|
|
for (hex_info &h1 : *hexInfoArray) |
|
|
|
|
for (hex_info &h1 : *g_game_state->hex_array) |
|
|
|
|
{ |
|
|
|
|
for (uint i = 0; i < hexLine.size(); i++) |
|
|
|
|
{
|
|
|
|
|
@ -219,7 +174,7 @@ updateHexLineDraw(int32 x, int32 y)
|
|
|
|
|
if (hex_equal(h1.hex, h2)) |
|
|
|
|
{ |
|
|
|
|
h1.selected = true; |
|
|
|
|
h1.current_color = selected_fill_color; |
|
|
|
|
h1.current_color = g_render_state->selected_fill_color; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
else if (i == hexLine.size() - 1) |
|
|
|
|
@ -247,23 +202,23 @@ startHexConeFill(int32 x, int32 y)
|
|
|
|
|
void |
|
|
|
|
updateHexConeFill(int32 x, int32 y) |
|
|
|
|
{ |
|
|
|
|
if (isSelecting) |
|
|
|
|
if (g_game_state->is_selecting) |
|
|
|
|
{ |
|
|
|
|
hex_info *hxi = getSingleHex(x, y); |
|
|
|
|
if (hxi && (hxi != currentHex)) |
|
|
|
|
if (hxi && (hxi != g_game_state->current_hex)) |
|
|
|
|
{ |
|
|
|
|
currentHex = hxi; |
|
|
|
|
g_game_state->current_hex = hxi; |
|
|
|
|
|
|
|
|
|
for (hex_info &h : *hexInfoArray) |
|
|
|
|
for (hex_info &h : *g_game_state->hex_array) |
|
|
|
|
{ |
|
|
|
|
if (&h == startHex) |
|
|
|
|
if (&h == g_game_state->start_hex) |
|
|
|
|
{ |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
if (hex_equal(h.hex, hxi->hex)) |
|
|
|
|
{ |
|
|
|
|
h.selected = true; |
|
|
|
|
h.current_color = selected_fill_color; |
|
|
|
|
h.current_color = g_render_state->selected_fill_color; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
@ -279,23 +234,8 @@ void
|
|
|
|
|
handleMouseDown(SDL_MouseButtonEvent &e) |
|
|
|
|
{ |
|
|
|
|
v2i coords = mapMouseToViewport(e.x, e.y); |
|
|
|
|
|
|
|
|
|
// mouse click handled by gui
|
|
|
|
|
/*
|
|
|
|
|
if (gooeyHitTest(coords)) |
|
|
|
|
{ |
|
|
|
|
HexDrawMode mode = gooeyPressButton(coords); |
|
|
|
|
if (mode != NONE) |
|
|
|
|
{ |
|
|
|
|
resetHexes(); |
|
|
|
|
globalDrawMode = mode; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
switch (globalDrawMode) |
|
|
|
|
|
|
|
|
|
switch (g_game_state->draw_mode) |
|
|
|
|
{ |
|
|
|
|
case FILL: |
|
|
|
|
startHexFill(coords.x, coords.y); |
|
|
|
|
@ -322,7 +262,7 @@ handleMouseDown(SDL_MouseButtonEvent &e)
|
|
|
|
|
hex->selected = !hex->selected; |
|
|
|
|
if (hex->selected) |
|
|
|
|
{ |
|
|
|
|
hex->current_color = selected_fill_color; |
|
|
|
|
hex->current_color = g_render_state->selected_fill_color; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
@ -338,7 +278,7 @@ handleMouseMove(SDL_MouseMotionEvent &e)
|
|
|
|
|
{ |
|
|
|
|
v2i coords = mapMouseToViewport(e.x, e.y); |
|
|
|
|
|
|
|
|
|
switch (globalDrawMode) |
|
|
|
|
switch (g_game_state->draw_mode) |
|
|
|
|
{ |
|
|
|
|
case FILL: |
|
|
|
|
updateHexFill(coords.x, coords.y); |
|
|
|
|
@ -367,18 +307,18 @@ handleMouseUp(SDL_MouseButtonEvent &e)
|
|
|
|
|
{ |
|
|
|
|
//v2i coords = mapMouseToViewport(e.x, e.y);
|
|
|
|
|
|
|
|
|
|
switch (globalDrawMode) |
|
|
|
|
switch (g_game_state->draw_mode) |
|
|
|
|
{ |
|
|
|
|
case FILL: |
|
|
|
|
isSelecting = false; |
|
|
|
|
g_game_state->is_selecting = false; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case LINE: |
|
|
|
|
isSelecting = false; |
|
|
|
|
g_game_state->is_selecting = false; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case CONE_FILL: |
|
|
|
|
isSelecting = false; |
|
|
|
|
g_game_state->is_selecting = false; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case PATHFINDING: |
|
|
|
|
@ -422,14 +362,14 @@ enterLoop(SDL_Handles &handles)
|
|
|
|
|
case SDL_MOUSEBUTTONDOWN: |
|
|
|
|
if (!gooey_wants) |
|
|
|
|
{ |
|
|
|
|
isSelecting = true; |
|
|
|
|
g_game_state->is_selecting = true; |
|
|
|
|
handleMouseDown(e.button); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case SDL_MOUSEBUTTONUP: |
|
|
|
|
if (!gooey_wants) |
|
|
|
|
{ |
|
|
|
|
isSelecting = false; |
|
|
|
|
g_game_state->is_selecting = false; |
|
|
|
|
handleMouseUp(e.button); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
@ -444,8 +384,8 @@ enterLoop(SDL_Handles &handles)
|
|
|
|
|
|
|
|
|
|
// TODO: move loop to main() and condense all these SDL event functions?
|
|
|
|
|
// something like a large processSDLEvents()
|
|
|
|
|
renderFrame(hexInfoArray); |
|
|
|
|
renderGooey(handles, globalDrawMode); |
|
|
|
|
renderFrame(g_game_state->hex_array /* TODO: pass in game state*/); |
|
|
|
|
renderGooey(handles, g_game_state->draw_mode); |
|
|
|
|
SDL_GL_SwapWindow(handles.window); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -462,6 +402,14 @@ cleanUp(SDL_Handles &handles)
|
|
|
|
|
SDL_GL_DeleteContext(handles.glContext); |
|
|
|
|
SDL_DestroyWindow(handles.window); |
|
|
|
|
SDL_Quit(); |
|
|
|
|
|
|
|
|
|
if (g_game_state) |
|
|
|
|
{ |
|
|
|
|
if (g_game_state->hex_array) |
|
|
|
|
delete g_game_state->hex_array; |
|
|
|
|
delete g_game_state; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -475,8 +423,24 @@ int main(int argc, char* argv[])
|
|
|
|
|
AixLog::Log::init<AixLog::SinkCout>(AixLog::Severity::trace, AixLog::Type::normal); |
|
|
|
|
LOG(INFO) << "Application started\n"; |
|
|
|
|
|
|
|
|
|
hexInfoArray = new vector<hex_info>; |
|
|
|
|
createHexes(hexInfoArray); |
|
|
|
|
// init global game state
|
|
|
|
|
Layout layout(HEX_ORIENTATION, Point(HEX_SIZE, HEX_SIZE), Point(VIEWPORT_WIDTH / 2, VIEWPORT_HEIGHT / 2)); |
|
|
|
|
g_game_state = new game_state(layout); |
|
|
|
|
g_game_state->hex_array = new vector<hex_info>; |
|
|
|
|
g_game_state->is_selecting = false; |
|
|
|
|
g_game_state->start_hex = 0x0; |
|
|
|
|
g_game_state->current_hex = 0x0; |
|
|
|
|
g_game_state->draw_mode = NONE; |
|
|
|
|
|
|
|
|
|
// init global render state
|
|
|
|
|
g_render_state = new render_state(); |
|
|
|
|
g_render_state->is_debug_draw = DEBUG_DRAW; |
|
|
|
|
g_render_state->viewport_dims = v2i(VIEWPORT_WIDTH, VIEWPORT_HEIGHT); |
|
|
|
|
g_render_state->fill_color = FILL_COLOR; |
|
|
|
|
g_render_state->selected_fill_color = SELECTED_FILL_COLOR; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
createHexes(g_game_state->hex_array, g_game_state->hex_layout, g_render_state->fill_color); |
|
|
|
|
SDL_Handles handles; |
|
|
|
|
|
|
|
|
|
if (SDL_Init(SDL_INIT_VIDEO) != 0) |
|
|
|
|
@ -485,29 +449,27 @@ int main(int argc, char* argv[])
|
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!initRenderer(handles, viewportDims)) |
|
|
|
|
if (!initRenderer(handles, g_render_state->viewport_dims)) |
|
|
|
|
{ |
|
|
|
|
LOG(ERROR) << "Unable to initialize graphics, exiting\n"; |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!createScene(hexInfoArray)) |
|
|
|
|
if (!createScene(g_game_state->hex_array)) |
|
|
|
|
{ |
|
|
|
|
LOG(ERROR) << "Error in vertex data, exiting\n"; |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!initGooey(handles, viewportDims)) |
|
|
|
|
if (!initGooey(handles, g_render_state->viewport_dims)) |
|
|
|
|
{ |
|
|
|
|
LOG(ERROR) << "Fooey, No Gooey!\n"; |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: condense main loop
|
|
|
|
|
enterLoop(handles); |
|
|
|
|
cleanUp(handles); |
|
|
|
|
delete hexInfoArray; |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|