34 : 
wxWindow(parent, id), panel(panel), game(panel->game.get()) {
 
   60   Coords null_coords = { -1, -1 };
 
   76   if (!(size.x > 0 && size.y > 0)) {
 
   97           neighbor.
x += coords.
x, neighbor.
y += coords.
y;
 
  105       if (is_blocked != was_blocked) {
 
  124   window_dc.
Blit(update_pos, update_region.
GetSize(), &this->board_dc, update_pos);
 
  150       if (!update_region.
Intersects(tile_rect)) 
continue;
 
  162           dc, tileset.water_tiles[coords_hash % WXSIZEOF(tileset.water_tiles)], tile_pos
 
  168         dc, tileset.ice_tiles[coords_hash % WXSIZEOF(tileset.ice_tiles)], tile_pos
 
  171       auto check_water = [&](
int dx, 
int dy) -> 
bool {
 
  172         Coords neighbor = { coords.
x + dx, coords.
y + dy };
 
  176       auto draw_edge = [&](
int dx, 
int dy, 
TileEdge type) {
 
  177         if (check_water(dx, dy)) {
 
  178           this->
draw_bitmap(dc, tileset.tile_edges[type], tile_pos);
 
  186       auto draw_concave_corner = [&](
int dx, 
int dy, 
TileCorner type) -> 
void {
 
  187         if (check_water(dx, dy) && !check_water(dx, 0) && !check_water(0, dy)) {
 
  188           this->
draw_bitmap(dc, tileset.tile_concave_corners[type], tile_pos);
 
  196       auto draw_convex_corner = [&](
int dx, 
int dy, 
TileCorner type) -> 
void {
 
  197         if (check_water(dx, 0) && check_water(0, dy)) {
 
  198           this->
draw_bitmap(dc, tileset.tile_convex_corners[type], tile_pos);
 
  209           dc, tileset.fish_sprites[(fish - 1) % WXSIZEOF(tileset.fish_sprites)], tile_pos
 
  221   bool is_penguin_selected = 
false;
 
  222   Coords selected_penguin = { -1, -1 };
 
  233       if (!update_region.
Intersects(tile_rect)) 
continue;
 
  241         this->
draw_bitmap(dc, tileset.blocked_tile, tile_pos);
 
  247         bool flipped = 
false;
 
  248         if (is_penguin_selected && 
coords_same(coords, selected_penguin)) {
 
  249           flipped = mouse_coords.
x < selected_penguin.
x;
 
  252           flipped ? tileset.penguin_sprites_flipped : tileset.penguin_sprites;
 
  254           dc, penguin_sprites[player % WXSIZEOF(tileset.penguin_sprites)], tile_pos
 
  258       this->
draw_bitmap(dc, tileset.grid_tile, tile_pos);
 
  280   wxPen green_pen((*wxGREEN).ChangeLightness(75), 4);
 
  281   wxPen red_pen((*wxRED).ChangeLightness(75), 4);
 
  285     dc.
DrawLine(arrow_start, arrow_fail);
 
  287     dc.
DrawLine(arrow_start, arrow_fail);
 
  298     dc.
DrawLine(arrow_start, arrow_end);
 
  300     dc.
SetPen(valid ? green_pen : red_pen);
 
  301     dc.
DrawLine(arrow_start, arrow_end);
 
  309   if (start == end) 
return;
 
  320     dc.
DrawLine(end - head1i, end + head1i);
 
  321     dc.
DrawLine(end - head2i, end + head2i);
 
  354   auto event_type = 
event.GetEventType();
 
bool is_tile_in_bounds(const Game *game, Coords coords)
Checks if the given coords are within the bounds of the board.
 
short get_tile(const Game *game, Coords coords)
Returns the value of the tile at coords. Fails if coords are outside the bounds.
 
bool get_tile_attr(const Game *game, Coords coords, short attr)
Checks whether the attribute attr of the tile at coords is set.
 
void set_tile_attr(Game *game, Coords coords, short attr, bool value)
Sets (or resets) the attribute attr of the tile at coords.
 
Functions for working with the game board (and the specifics of its encoding)
 
#define is_fish_tile(tile)
 
#define is_penguin_tile(tile)
 
#define is_water_tile(tile)
 
@ TILE_DIRTY
Set when a tile is changed with set_tile, can be unset by the UI. All tiles initially have this attri...
 
#define get_tile_player_id(tile)
 
#define get_tile_fish(tile)
 
wxBrush * wxTRANSPARENT_BRUSH
 
wxBEGIN_EVENT_TABLE(CanvasPanel, wxWindow) wxEND_EVENT_TABLE()
 
Responsible for drawing the board and painting the UI overlays.
 
wxRect get_tile_rect(Coords coords) const
 
void paint_selected_tile_outline(wxDC &dc, Coords coords, bool blocked=false)
 
void on_paint(wxPaintEvent &event)
 
void paint_tiles(wxDC &dc, const wxRect &update_region)
 
void paint_arrow_head(wxDC &dc, wxPoint start, wxPoint end, wxSize head_size, ArrowHeadType head_type=ARROW_HEAD_NORMAL)
 
void paint_move_arrow(wxDC &dc, Coords start, Coords end)
 
void on_any_mouse_event(wxMouseEvent &event)
 
static const wxCoord TILE_SIZE
 
Coords tile_coords_at_point(wxPoint point) const
 
CanvasPanel(wxWindow *parent, wxWindowID id, GamePanel *panel)
 
wxPoint get_tile_centre(Coords coords) const
 
Coords get_selected_penguin_coords() const
 
void draw_bitmap(wxDC &dc, const wxBitmap &bitmap, const wxPoint &pos)
 
void paint_board(wxDC &dc, const wxRect &update_region, wxDC &tiles_dc)
 
wxSize get_canvas_size() const
 
virtual void on_mouse_move(wxMouseEvent &event)
 
virtual void on_mouse_up(wxMouseEvent &event)
 
virtual void on_mouse_down(wxMouseEvent &event)
 
virtual void on_mouse_enter_leave(wxMouseEvent &event)
 
virtual void paint_overlay(wxDC &dc)
 
virtual void update_tile_attributes()
 
GameController * controller
 
virtual bool IsOk() const
 
virtual bool Create(int width, int height, int depth=wxBITMAP_SCREEN_DEPTH)
 
void SetPen(const wxPen &pen)
 
bool Blit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height, wxDC *source, wxCoord xsrc, wxCoord ysrc, wxRasterOperationMode logicalFunc=wxCOPY, bool useMask=false, wxCoord xsrcMask=wxDefaultCoord, wxCoord ysrcMask=wxDefaultCoord)
 
void DrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
 
void SetBrush(const wxBrush &brush)
 
void DrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
 
void GetSize(wxCoord *width, wxCoord *height) const
 
void DrawBitmap(const wxBitmap &bitmap, wxCoord x, wxCoord y, bool useMask=false)
 
void SelectObjectAsSource(const wxBitmap &bitmap)
 
void SelectObject(wxBitmap &bitmap)
 
bool ButtonDown(wxMouseButton but=wxMOUSE_BTN_ANY) const
 
bool ButtonUp(wxMouseButton but=wxMOUSE_BTN_ANY) const
 
wxPoint GetPosition() const
 
bool Intersects(const wxRect &rect) const
 
void GetBox(wxCoord &x, wxCoord &y, wxCoord &width, wxCoord &height) const
 
void SetInitialSize(const wxSize &size=wxDefaultSize)
 
const wxRegion & GetUpdateRegion() const
 
void SetDoubleBuffered(bool on)
 
int game_find_player_by_id(const Game *self, short id)
Returns an index of the player or -1 if no such player was found.
 
Player * game_get_player(const Game *self, int idx)
Returns a pointer to the player at the given index. Fails if the index isn't within the bounds of the...
 
bool game_check_player_index(const Game *self, int idx)
Checks if idx is within the bounds of Game::players.
 
The core of the unified game logic library, contains the Game struct.
 
@ GAME_PHASE_MOVEMENT
Set by movement_begin.
 
@ TILE_OVERLAY_NEEDS_REDRAW
 
wxAppDerivedClass & wxGetApp()
 
wxEventType wxEVT_LEFT_DOWN
 
#define wxEND_EVENT_TABLE()
 
wxEventType wxEVT_LEFT_UP
 
wxEventType wxEVT_ENTER_WINDOW
 
wxEventType wxEVT_LEAVE_WINDOW
 
A pair of 2D coordinates, used for addressing the Game::board_grid.
 
GamePhase phase
The current state of the state machine, initially set to GAME_PHASE_NONE. Use game_set_phase for sett...
 
int board_width
Use setup_board for setting this.
 
int board_height
Use setup_board for setting this.
 
int current_player_index
A negative value means that there is no current player selected. Use game_set_current_player for sett...
 
short id
The unique ID, usually (but not necessarily) is just index + 1.
 
bool coords_same(Coords a, Coords b)
Checks if two Coords pairs are equal.
 
const Coords NEIGHBOR_TO_COORDS[NEIGHBOR_MAX]
A table that maps Neighbor variants to relative Coords.
 
uint32_t fnv32_hash(uint32_t state, const void *buf, size_t len)
Computes the 32-bit FNV-1a hash of a given byte sequence.
 
#define FNV32_INITIAL_STATE
A constant for fnv32_hash.