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.