aboutsummaryrefslogtreecommitdiff
path: root/src/game_tab/left_panel/board
diff options
context:
space:
mode:
authorLoic Guegan <manzerbredes@mailbox.org>2023-01-02 12:02:11 +0100
committerLoic Guegan <manzerbredes@mailbox.org>2023-01-02 12:02:11 +0100
commite40f98ccda04da3bb9811b354b770fb8c6b563e5 (patch)
tree3b0258e0cb3eca9f979d79d71da938fa7efb4bc8 /src/game_tab/left_panel/board
parentd05093513ec5124feed0dc6140789f48218b45c9 (diff)
parent042f6ca17012414d13235d3e04ea9012ff49f79c (diff)
Improve game tab
Diffstat (limited to 'src/game_tab/left_panel/board')
-rw-r--r--src/game_tab/left_panel/board/BoardCanvas.cpp112
-rw-r--r--src/game_tab/left_panel/board/BoardCanvas.hpp20
-rw-r--r--src/game_tab/left_panel/board/Theme.cpp17
-rw-r--r--src/game_tab/left_panel/board/Theme.hpp3
4 files changed, 99 insertions, 53 deletions
diff --git a/src/game_tab/left_panel/board/BoardCanvas.cpp b/src/game_tab/left_panel/board/BoardCanvas.cpp
index 1a85176..f6846f1 100644
--- a/src/game_tab/left_panel/board/BoardCanvas.cpp
+++ b/src/game_tab/left_panel/board/BoardCanvas.cpp
@@ -3,25 +3,50 @@
wxDEFINE_EVENT(PLAY_MOVE_EVENT, wxCommandEvent);
BoardCanvas::BoardCanvas(wxFrame *parent)
- : wxPanel(parent), black_side(false), is_black_turn(true), frozen(false),
+ : wxPanel(parent), black_side(false), frozen(false),
lock_square_size(false), t(new Theme()), t_captures(new Theme()) {
- board = "rnbqkbnrpppppppp PPPPPPPPRNBQKBNR";
is_dragging = false;
valid_drag = false;
+ // Init animation data
+ adata.duration=200;
+ adata.duration_fast=80;
+ adata.fps=30;
+ adata.buffer=new wxBitmap(500,500,32);
adata.reuseBuffer=false;
adata.buffer=nullptr;
- t_captures->ResizePieces(t->GetPiecesSizes() * CAPTURE_FACTOR);
+ // Init game state
+ gs.is_black_turn=false;
+ gs.board = "rnbqkbnrpppppppp PPPPPPPPRNBQKBNR";
+ gs.mat_black=false;
+ gs.mat_white=false;
+ // Init clocks
SetClockTime(-1, -1, -1, false);
SetClockTime(-1, -1, -1, true);
+ // Init capture pieces
+ t_captures->ResizePieces(t->GetPiecesSizes() * CAPTURE_FACTOR);
+ // Load preferences
ApplyPreferences();
// The following should be called when using an EVT_PAINT handler
SetBackgroundStyle(wxBG_STYLE_PAINT);
- adata.duration=200;
- adata.duration_fast=80;
- adata.fps=30;
// Let GameTableLeftPanel process keyboard events:
Bind(wxEVT_KEY_DOWN, [p=this](wxKeyEvent &e){e.ResumePropagation(1);e.Skip();});
Bind(wxEVT_KEY_UP, [p=this](wxKeyEvent &e){e.ResumePropagation(1);e.Skip();});
+ Bind(wxEVT_PAINT, &BoardCanvas::OnPaint, this);
+ Bind(wxEVT_SIZE, &BoardCanvas::OnResize, this);
+ // Mouse events:
+ Bind(wxEVT_MOTION, &BoardCanvas::MouseEvent, this);
+ Bind(wxEVT_LEFT_DOWN, &BoardCanvas::MouseEvent, this);
+ Bind(wxEVT_LEFT_UP, &BoardCanvas::MouseEvent, this);
+}
+
+void BoardCanvas::OnResize(wxSizeEvent &e){
+ wxSize size=e.GetSize();
+ if(size.x>100 && size.y>100){
+ // Setup buffer (use for animations)
+ if(adata.buffer!=nullptr)
+ free(adata.buffer);
+ adata.buffer=new wxBitmap(size.x,size.y,32);
+ }
}
BoardCanvas::~BoardCanvas() {
@@ -43,7 +68,6 @@ BoardCanvas::BoardCanvas(wxFrame *parent, std::uint32_t square_width,
void BoardCanvas::OnPaint(wxPaintEvent &event) {
wxBufferedPaintDC dc(this);
dc.SetBackground(*wxWHITE_BRUSH);
- dc.Clear();
if(!adata.reuseBuffer){
// Setting up required attributes
@@ -56,12 +80,8 @@ void BoardCanvas::OnPaint(wxPaintEvent &event) {
boardX = 0;
if (boardY > canvas_size.y)
boardY = 0;
-
- // Setup buffer (later use for animations)
- if(adata.buffer!=nullptr)
- free(adata.buffer);
- adata.buffer=new wxBitmap(canvas_size.x,canvas_size.y,32);
wxMemoryDC memDC(*adata.buffer);
+ memDC.Clear();
DrawBoard(memDC);
dc.Blit(0,0,canvas_size.x,canvas_size.y,(wxDC*)&memDC,0,0);
}
@@ -73,7 +93,7 @@ void BoardCanvas::OnPaint(wxPaintEvent &event) {
dc.DrawBitmap(*t->Get(adata.piece_moved),
adata.src.x + adata.frame*(adata.transVect.x/adata.frames),
adata.src.y + adata.frame*(adata.transVect.y/adata.frames), false);
- // end drawing
+ // End drawing
adata.frame++;
}
}
@@ -100,24 +120,26 @@ void BoardCanvas::ApplyPreferences() {
Refresh();
}
-void BoardCanvas::SetupBoard(std::string board, bool is_black_turn,
- std::map<char, std::uint8_t> captures,
- std::string white_player, std::string black_player) {
- this->board = board;
- this->is_black_turn = is_black_turn;
- this->captures = captures;
- this->white_player=white_player;
- this->black_player=black_player;
+void BoardCanvas::SetupBoard(const GameState &new_gs) {
+ gs.board = new_gs.board;
+ gs.is_black_turn = new_gs.is_black_turn;
+ gs.captures = new_gs.captures;
+ gs.white=new_gs.white;
+ gs.black=new_gs.black;
+ gs.mat_white=new_gs.mat_white;
+ gs.mat_black=new_gs.mat_black;
+ gs.black_time=new_gs.black_time;
+ gs.white_time=new_gs.white_time;
Refresh();
}
-void BoardCanvas::Animate(const std::string &board, bool is_black_turn, std::map<char, std::uint8_t> captures, std::string src, std::string dst,bool faster){
+void BoardCanvas::Animate(const GameState &new_gs, std::string src, std::string dst, bool faster){
std::uint8_t pfile = src[0]-'a';
std::uint8_t prank = src[1]-'1';
- adata.piece_moved = this->board[pfile + 8 * (7-prank)]; // Piece to move
+ adata.piece_moved = gs.board[pfile + 8 * (7-prank)]; // Piece to move
// Now remove the piece that will be moved
- this->board[pfile + 8 * (7-prank)]=' ';
+ gs.board[pfile + 8 * (7-prank)]=' ';
wxMemoryDC memDC(*adata.buffer);
DrawBoard(memDC);
@@ -164,7 +186,7 @@ void BoardCanvas::Animate(const std::string &board, bool is_black_turn, std::map
}
adata.duration=faster ? duration_backup : duration_backup;
adata.reuseBuffer=false;
- SetupBoard(board, is_black_turn, captures,white_player,black_player);
+ SetupBoard(new_gs);
}
void BoardCanvas::DrawBoard(wxDC &dc) {
@@ -217,7 +239,7 @@ void BoardCanvas::DrawBoard(wxDC &dc) {
}
std::uint32_t px = x + centrer_offset;
std::uint32_t py = y + centrer_offset;
- char piece = board[(7 - pfile) + 8 * prank];
+ char piece = gs.board[(7 - pfile) + 8 * prank];
if (is_dragging && (7 - pfile) == active_square.x &&
(7 - prank) == active_square.y) {
dp = piece;
@@ -228,6 +250,8 @@ void BoardCanvas::DrawBoard(wxDC &dc) {
}
if (piece != ' ') {
dc.DrawBitmap(*t->Get(piece), px, py, false);
+ if((piece == 'k' && gs.mat_black) || (piece == 'K' && gs.mat_white))
+ dc.DrawBitmap(*t->Get('#'), x+square_width/2+centrer_offset, y+centrer_offset, false);
}
}
}
@@ -236,7 +260,7 @@ void BoardCanvas::DrawBoard(wxDC &dc) {
dc.SetPen(wxPen(*wxBLACK, 3));
std::uint32_t badgeY = boardY;
std::uint32_t badgeWidth = square_width / 2;
- if (is_black_turn) {
+ if (gs.is_black_turn) {
dc.SetBrush(*wxBLACK_BRUSH);
if (black_side) {
badgeY = boardY + (8 * square_width) - badgeWidth;
@@ -265,15 +289,15 @@ void BoardCanvas::DrawBoard(wxDC &dc) {
offsetYPlayerName = offsetY+captures_size;
}
for (char p : {'P', 'N', 'B', 'R', 'Q'}) {
- if (captures.find(p) != captures.end()) {
- for (std::uint8_t i = 0; i < captures[p]; i++) {
+ if (gs.captures.find(p) != gs.captures.end()) {
+ for (std::uint8_t i = 0; i < gs.captures[p]; i++) {
dc.DrawBitmap(*t_captures->Get(p), boardX + offsetX, boardY + offsetY);
offsetX += captures_size / 2;
}
offsetX += captures_size / 2;
}
}
- dc.DrawText(wxString(black_player),boardX,boardY + offsetYPlayerName);
+ dc.DrawText(wxString(gs.black),boardX,boardY + offsetYPlayerName);
// Black (white's captures):
offsetX = 0;
if (black_side) {
@@ -284,15 +308,15 @@ void BoardCanvas::DrawBoard(wxDC &dc) {
offsetYPlayerName = offsetY+captures_size;
}
for (char p : {'p', 'n', 'b', 'r', 'q'}) {
- if (captures.find(p) != captures.end()) {
- for (std::uint8_t i = 0; i < captures[p]; i++) {
+ if (gs.captures.find(p) != gs.captures.end()) {
+ for (std::uint8_t i = 0; i < gs.captures[p]; i++) {
dc.DrawBitmap(*t_captures->Get(p), boardX + offsetX, boardY + offsetY);
offsetX += captures_size / 2;
}
offsetX += captures_size / 2;
}
}
- dc.DrawText(wxString(white_player),boardX,boardY + offsetYPlayerName);
+ dc.DrawText(wxString(gs.white),boardX,boardY + offsetYPlayerName);
// Draw dragging piece
if (DrawDraggingPiece) {
@@ -306,9 +330,9 @@ void BoardCanvas::DrawBoard(wxDC &dc) {
}
// Draw Clocks
- if (std::get<0>(black_time) >= 0) {
+ if (std::get<0>(gs.black_time) >= 0) {
wxFont font = dc.GetFont();
- ClockTime clock = black_side ? white_time : black_time;
+ ClockTime clock = black_side ? gs.white_time : gs.black_time;
wxString time =
wxString::Format("%ds", std::get<1>(clock), std::get<2>(clock));
if (std::get<0>(clock) > 0) {
@@ -321,7 +345,7 @@ void BoardCanvas::DrawBoard(wxDC &dc) {
dc.GetTextExtent(time, &width, &height);
dc.DrawText(time,
wxPoint(boardX + square_width * 8 - width, boardY - height - numbers_size.y*2));
- clock = black_side ? black_time : white_time;
+ clock = black_side ? gs.black_time : gs.white_time;
time = wxString::Format("%ds", std::get<1>(clock), std::get<2>(clock));
if (std::get<0>(clock) > 0) {
time = wxString::Format("%d:%d", std::get<0>(clock), std::get<1>(clock));
@@ -359,6 +383,9 @@ void BoardCanvas::MouseEvent(wxMouseEvent &event) {
((char)('a' + file)) + std::to_string(rank + 1);
event.SetString(move);
ProcessEvent(event);
+ } else {
+ // If square not valid just redraw (place piece back to its square)
+ Refresh();
}
}
if (event.LeftDown()) {
@@ -370,7 +397,7 @@ void BoardCanvas::MouseEvent(wxMouseEvent &event) {
if (IsCurrentSquareValid) {
active_square.x = file;
active_square.y = rank;
- if (board[(7 - rank) * 8 + file] != ' ') {
+ if (gs.board[(7 - rank) * 8 + file] != ' ') {
wxLogDebug("Drag start on square (%d,%d)", file, rank);
valid_drag = true;
}
@@ -385,7 +412,8 @@ void BoardCanvas::MouseEvent(wxMouseEvent &event) {
}
void BoardCanvas::Zoom(std::int32_t zoom) {
- t->Zoom(zoom);
+ if(!t->Zoom(zoom))
+ return;
t_captures->ResizePieces(t->GetPiecesSizes() * CAPTURE_FACTOR);
Refresh();
}
@@ -398,12 +426,8 @@ void BoardCanvas::Swap() {
void BoardCanvas::SetClockTime(short hours, short min, short sec,
bool IsBlack) {
if (IsBlack) {
- black_time = std::make_tuple(hours, min, sec);
+ gs.black_time = std::make_tuple(hours, min, sec);
} else {
- white_time = std::make_tuple(hours, min, sec);
+ gs.white_time = std::make_tuple(hours, min, sec);
}
}
-
-wxBEGIN_EVENT_TABLE(BoardCanvas, wxPanel) EVT_PAINT(BoardCanvas::OnPaint)
- EVT_MOUSE_EVENTS(BoardCanvas::MouseEvent)
- wxEND_EVENT_TABLE()
diff --git a/src/game_tab/left_panel/board/BoardCanvas.hpp b/src/game_tab/left_panel/board/BoardCanvas.hpp
index b26526f..7b6ccf7 100644
--- a/src/game_tab/left_panel/board/BoardCanvas.hpp
+++ b/src/game_tab/left_panel/board/BoardCanvas.hpp
@@ -58,6 +58,16 @@ typedef struct AnimState {
wxPoint transVect;
} AnimState;
+typedef struct GameState {
+ std::string white, black;
+ std::string board;
+ std::map<char, std::uint8_t> captures;
+ bool is_black_turn;
+ bool mat_black;
+ bool mat_white;
+ ClockTime black_time, white_time;
+} GameState;
+
class BoardCanvas : public wxPanel {
// *t is theme for board+pieces and
// *t_captures is theme for captured pieces (scale down version of t)
@@ -73,11 +83,11 @@ class BoardCanvas : public wxPanel {
wxSize canvas_size;
wxPoint active_square;
std::map<char, std::uint8_t> captures;
- ClockTime black_time, white_time;
bool frozen,lock_square_size;
// Current animation state
AnimState adata;
+ GameState gs;
public:
BoardCanvas(wxFrame *parent);
@@ -89,10 +99,8 @@ public:
void MouseEvent(wxMouseEvent &event);
void Zoom(std::int32_t zoom);
void Swap();
- void SetupBoard(std::string board, bool is_black_turn,
- std::map<char, std::uint8_t> captures,
- std::string white_player, std::string black_player);
- void Animate(const std::string &board, bool is_black_turn, std::map<char, std::uint8_t> captures, std::string src, std::string dst,bool faster);
+ void OnResize(wxSizeEvent &e);
+ void SetupBoard(const GameState &new_gs);
+ void Animate(const GameState &new_gs, std::string src, std::string dst,bool faster);
void SetClockTime(short hours, short min, short sec, bool IsBlack);
- DECLARE_EVENT_TABLE()
};
diff --git a/src/game_tab/left_panel/board/Theme.cpp b/src/game_tab/left_panel/board/Theme.cpp
index 6ecbafc..f72dfab 100644
--- a/src/game_tab/left_panel/board/Theme.cpp
+++ b/src/game_tab/left_panel/board/Theme.cpp
@@ -11,6 +11,8 @@ Theme::Theme() : square_radius(10) {
config->Read("board/theme/squares/path", "default").ToStdString();
wxFileName square_file(square);
CONFIG_CLOSE(config);
+ // Mat
+ skin['#']=LoadPNG("mat").ConvertToImage();
// Piece
if (piece == "default" || !piece_file.FileExists()) {
wxLogDebug("Loading piece skin from binres");
@@ -95,12 +97,18 @@ wxBitmap *Theme::Get(char c) { return (skin_scaled[c]); }
void Theme::ResizePieces(std::uint32_t width) {
for (std::pair<char, wxImage> c : skin) {
- if (c.first != 's' && c.first != 'S') {
+ if (c.first != 's' && c.first != 'S' && c.first != '#') {
if (skin_scaled.count(c.first))
delete skin_scaled[c.first];
skin_scaled[c.first] =
new wxBitmap(c.second.Scale(width, width, wxIMAGE_QUALITY_HIGH));
}
+ else if(c.first == '#'){
+ if (skin_scaled.count(c.first))
+ delete skin_scaled[c.first];
+ skin_scaled[c.first] =
+ new wxBitmap(c.second.Scale(width*MAT_SIZE_FACTOR, width*MAT_SIZE_FACTOR, wxIMAGE_QUALITY_HIGH));
+ }
}
}
@@ -130,10 +138,15 @@ void Theme::ResizeSquares(std::uint32_t width) {
skin_scaled['3']->SetMask(RoundedMask(width, 3));
}
-void Theme::Zoom(int amount) {
+bool Theme::Zoom(int amount) {
double width = skin_scaled['s']->GetWidth() + amount;
+ if(width<=20)
+ return false;
+ if(width>=180)
+ return false;
ResizeSquares(std::max(width, 1.0));
ResizePieces(std::max(width * PIECE_SIZE_FACTOR, 1.0));
+ return true;
}
void Theme::SetSquareRadius(std::uint8_t radius) {
diff --git a/src/game_tab/left_panel/board/Theme.hpp b/src/game_tab/left_panel/board/Theme.hpp
index 88036d8..c3acf10 100644
--- a/src/game_tab/left_panel/board/Theme.hpp
+++ b/src/game_tab/left_panel/board/Theme.hpp
@@ -8,6 +8,7 @@
#define ELT_DIM 200
#define DEFAULT_SIZE 80
#define PIECE_SIZE_FACTOR 0.8 // Should be between 0 and 1
+#define MAT_SIZE_FACTOR 0.4
#define DEFAULT_PIECE_THEME "assets/pieces/cburnett.png"
#define DEFAULT_SQUARE_THEME "assets/boards/chesscom_8bits.png"
@@ -29,7 +30,7 @@ public:
void ResizeSquaresAndPieces(std::uint32_t width);
void SetSquareRadius(std::uint8_t radius);
std::uint8_t GetSquareRadius();
- void Zoom(int amount);
+ bool Zoom(int amount);
double GetPiecesSizes();
double GetSquaresSizes();