diff --git a/cmake/compile_commands.json b/cmake/compile_commands.json index adf7c50..b1ee3d5 100644 --- a/cmake/compile_commands.json +++ b/cmake/compile_commands.json @@ -1,20 +1,26 @@ [ { "directory": "/Users/aome/dev/c_projects/Chess/cmake/src", - "command": "/usr/bin/g++ -DSOME_DEFINITION -isystem /Library/Frameworks/SDL2.framework/Headers -iframework /Library/Frameworks -Wall -std=c++17 -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX14.4.sdk -o CMakeFiles/Chess.dir/Main.cpp.o -c /Users/aome/dev/c_projects/Chess/src/Main.cpp", + "command": "/usr/bin/g++ -DSOME_DEFINITION -isystem /Library/Frameworks/SDL2.framework/Headers -iframework /Library/Frameworks -isystem /Library/Frameworks/SDL2_image.framework/Headers -Wall -std=c++17 -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX14.4.sdk -F /Library/Frameworks/ -o CMakeFiles/Chess.dir/Main.cpp.o -c /Users/aome/dev/c_projects/Chess/src/Main.cpp", "file": "/Users/aome/dev/c_projects/Chess/src/Main.cpp", "output": "src/CMakeFiles/Chess.dir/Main.cpp.o" }, { "directory": "/Users/aome/dev/c_projects/Chess/cmake/src", - "command": "/usr/bin/g++ -DSOME_DEFINITION -isystem /Library/Frameworks/SDL2.framework/Headers -iframework /Library/Frameworks -Wall -std=c++17 -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX14.4.sdk -o CMakeFiles/Chess.dir/ChessLoop.cpp.o -c /Users/aome/dev/c_projects/Chess/src/ChessLoop.cpp", + "command": "/usr/bin/g++ -DSOME_DEFINITION -isystem /Library/Frameworks/SDL2.framework/Headers -iframework /Library/Frameworks -isystem /Library/Frameworks/SDL2_image.framework/Headers -Wall -std=c++17 -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX14.4.sdk -F /Library/Frameworks/ -o CMakeFiles/Chess.dir/ChessLoop.cpp.o -c /Users/aome/dev/c_projects/Chess/src/ChessLoop.cpp", "file": "/Users/aome/dev/c_projects/Chess/src/ChessLoop.cpp", "output": "src/CMakeFiles/Chess.dir/ChessLoop.cpp.o" }, { "directory": "/Users/aome/dev/c_projects/Chess/cmake/src", - "command": "/usr/bin/g++ -DSOME_DEFINITION -isystem /Library/Frameworks/SDL2.framework/Headers -iframework /Library/Frameworks -Wall -std=c++17 -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX14.4.sdk -o CMakeFiles/Chess.dir/SDL_Handler.cpp.o -c /Users/aome/dev/c_projects/Chess/src/SDL_Handler.cpp", + "command": "/usr/bin/g++ -DSOME_DEFINITION -isystem /Library/Frameworks/SDL2.framework/Headers -iframework /Library/Frameworks -isystem /Library/Frameworks/SDL2_image.framework/Headers -Wall -std=c++17 -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX14.4.sdk -F /Library/Frameworks/ -o CMakeFiles/Chess.dir/SDL_Handler.cpp.o -c /Users/aome/dev/c_projects/Chess/src/SDL_Handler.cpp", "file": "/Users/aome/dev/c_projects/Chess/src/SDL_Handler.cpp", "output": "src/CMakeFiles/Chess.dir/SDL_Handler.cpp.o" +}, +{ + "directory": "/Users/aome/dev/c_projects/Chess/cmake/src", + "command": "/usr/bin/g++ -DSOME_DEFINITION -isystem /Library/Frameworks/SDL2.framework/Headers -iframework /Library/Frameworks -isystem /Library/Frameworks/SDL2_image.framework/Headers -Wall -std=c++17 -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX14.4.sdk -F /Library/Frameworks/ -o CMakeFiles/Chess.dir/FEN.cpp.o -c /Users/aome/dev/c_projects/Chess/src/FEN.cpp", + "file": "/Users/aome/dev/c_projects/Chess/src/FEN.cpp", + "output": "src/CMakeFiles/Chess.dir/FEN.cpp.o" } ] \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1876076..03a6d4a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,13 +1,13 @@ set(CHESS_SOURCES ChessLoop.cpp SDL_Handler.cpp + FEN.cpp ) if (WIN32) file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/SDL2.dll DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) endif (WIN32) -# add_executable(Chess Main.cpp ${CHESS_SOURCES}) add_executable(${PROJECT_NAME} Main.cpp ${CHESS_SOURCES}) -target_link_libraries(${PROJECT_NAME} SDL2::SDL2 SDL2::SDL2main) +target_link_libraries(${PROJECT_NAME} SDL2::SDL2 SDL2::SDL2main SDL2_image::SDL2_image) diff --git a/src/ChessLoop.cpp b/src/ChessLoop.cpp index dc7a8de..7413c52 100644 --- a/src/ChessLoop.cpp +++ b/src/ChessLoop.cpp @@ -4,6 +4,7 @@ void Chess::Run() { SDL_Handler handler; + handler.render_background(); while (handler.handling_events) { handler.handle_events(); diff --git a/src/FEN.cpp b/src/FEN.cpp new file mode 100644 index 0000000..8225f3c --- /dev/null +++ b/src/FEN.cpp @@ -0,0 +1,31 @@ +#include "FEN.h" + +std::vector FEN::parse(const std::string &fen) +{ + std::vector pieces; + int pos = 0; + for (int i = 0; i <= fen.size(); i++) + { + if (fen[i] == ' ') + { + pieces.push_back(fen.substr(pos, i - pos)); + pos = i + 1; + } + } + pieces.push_back(fen.substr(pos, fen.size() - pos)); + return pieces; +} + +std::vector FEN::get_initial_positions() +{ + std::vector initial_positions; + std::string initial_position = + "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"; + initial_positions = parse(initial_position); + return initial_positions; +} + +std::string FEN::get_positions(const std::vector &positions) +{ + return positions[0]; +} diff --git a/src/FEN.h b/src/FEN.h new file mode 100644 index 0000000..c7aee27 --- /dev/null +++ b/src/FEN.h @@ -0,0 +1,9 @@ +#include +#include + +namespace FEN +{ + std::vector parse(const std::string &fen); + std::vector get_initial_positions(); + std::string get_positions(const std::vector &positions); +}; diff --git a/src/SDL_Handler.cpp b/src/SDL_Handler.cpp index 2d77be5..b540f99 100644 --- a/src/SDL_Handler.cpp +++ b/src/SDL_Handler.cpp @@ -1,5 +1,8 @@ #include "SDL_Handler.h" -#include +#include "FEN.h" +#include +#include +#include SDL_Handler::SDL_Handler() { @@ -14,7 +17,9 @@ void SDL_Handler::clean_up() SDL_DestroyWindow(m_window); if (m_renderer != nullptr) SDL_DestroyRenderer(m_renderer); - std::cout << "Bye!" << std::endl; + if (m_texture != nullptr) + SDL_DestroyTexture(m_texture); + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Handler cleaned up"); SDL_Quit(); } @@ -23,17 +28,34 @@ SDL_Handler::~SDL_Handler() { clean_up(); } void SDL_Handler::render_background() { + SDL_RenderClear(m_renderer); SDL_SetRenderDrawColor(m_renderer, 0, 0xFF, 0, SDL_ALPHA_OPAQUE); SDL_RenderClear(m_renderer); render_board(); SDL_RenderPresent(m_renderer); } +void SDL_Handler::render_texture(SDL_Texture *texture, int t_x, int t_y, int x, + int y) +{ + SDL_Rect src; + SDL_Rect dst; + src.x = t_x; + src.y = t_y; + src.w = 333; + src.h = 333; + dst.x = x; + dst.y = y; + dst.w = dst.h = m_CELL_SIZE; + SDL_RenderCopy(m_renderer, texture, &src, &dst); +} + void SDL_Handler::render_board() { + m_texture = load_texture(PIECES_PATH); // keep board on screen no matter the window size - int board_width = m_win_width > BOARD_WIDTH ? BOARD_WIDTH : m_win_width; - int board_height = m_win_height > BOARD_HEIGHT ? BOARD_HEIGHT : m_win_height; + int board_width = m_win_width > m_BOARD_SIZE ? m_BOARD_SIZE : m_win_width; + int board_height = m_win_height > m_BOARD_SIZE ? m_BOARD_SIZE : m_win_height; for (int file = 0; file < 8; file++) { for (int rank = 0; rank < 8; rank++) @@ -44,26 +66,101 @@ void SDL_Handler::render_board() else SDL_SetRenderDrawColor(m_renderer, 89, 44, 42, SDL_ALPHA_OPAQUE); SDL_Rect rect; - // normalize screen size to 8x8 squares - int square_size = 0; - if (board_width / 8 > board_height / 8) - square_size = board_width / 8; - else - square_size = board_height / 8; #pragma region draw squares int offset_x = (m_win_width / 2) - (board_width / 2); int offset_y = (m_win_height / 2) - (board_height / 2); - rect.x = offset_x + (square_size)*file; - rect.y = offset_y + (square_size)*rank; - rect.w = square_size; - rect.h = square_size; + int x = offset_x + (m_CELL_SIZE)*rank; + int y = offset_y + (m_CELL_SIZE)*file; + rect.x = x; + rect.y = y; + rect.w = rect.h = m_CELL_SIZE; SDL_RenderFillRect(m_renderer, &rect); #pragma endregion +#pragma region draw pieces + +#pragma endregion + } + } + std::vector fen = FEN::get_initial_positions(); + std::string initial_fen = FEN::get_positions(fen); + int file = 0; + int rank = 0; + for (char c : initial_fen) + { + if (c == '/') + { + file = 0; + rank++; + } + else + { + if (std::isdigit(c)) + file += (c - '0') * m_CELL_SIZE; + else + { + int x = (m_win_width / 2) - (board_width / 2) + file; + int y = m_win_height / 2 - m_BOARD_SIZE / 2 + (m_CELL_SIZE)*rank; + switch (c) + { + case 'r': + render_texture(m_texture, 333 * 4, 333, x, y); + break; + case 'b': + render_texture(m_texture, 333 * 2, 333, x, y); + break; + case 'k': + render_texture(m_texture, 0, 333, x, y); + break; + case 'q': + render_texture(m_texture, 333, 333, x, y); + break; + case 'n': + render_texture(m_texture, 333 * 3, 333, x, y); + break; + case 'p': + render_texture(m_texture, 333 * 5, 333, x, y); + break; + case 'R': + render_texture(m_texture, 333 * 4, 0, x, y); + break; + case 'B': + render_texture(m_texture, 333 * 2, 0, x, y); + break; + case 'N': + render_texture(m_texture, 333 * 3, 0, x, y); + break; + case 'P': + render_texture(m_texture, 333 * 5, 0, x, y); + break; + case 'K': + render_texture(m_texture, 0, 0, x, y); + break; + case 'Q': + render_texture(m_texture, 333, 0, x, y); + break; + default: + break; + } + file += m_CELL_SIZE; + } } } } +SDL_Texture *SDL_Handler::load_texture(const char *path) +{ + SDL_Texture *texture = nullptr; + texture = IMG_LoadTexture(m_renderer, path); + if (texture == nullptr) + { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "Unable to load image. ERROR: %s", SDL_GetError()); + return nullptr; + } + return texture; +} + #if defined(__APPLE__) || defined(__MACH__) Uint32 SDL_Handler::m_time_left() { @@ -78,7 +175,8 @@ Uint32 SDL_Handler::m_time_left() void SDL_Handler::handle_events() { -#if defined(__APPLE__) || defined(__MACH__) // MacOS incompatible with SDL_WaitEvent +#if defined(__APPLE__) || \ + defined(__MACH__) // MacOS incompatible with SDL_WaitEvent m_next_time = SDL_GetTicks() + 60; while (SDL_PollEvent(&m_event)) #else @@ -96,15 +194,16 @@ void SDL_Handler::handle_events() case SDL_WINDOWEVENT_SIZE_CHANGED: m_win_width = m_event.window.data1; m_win_height = m_event.window.data2; - if (m_win_height - BOARD_HEIGHT < 0) + if (m_win_height - m_BOARD_SIZE < 0) { - m_win_height = BOARD_HEIGHT; + m_win_height = m_BOARD_SIZE; } - else if (m_win_width - BOARD_WIDTH < 0) + else if (m_win_width - m_BOARD_SIZE < 0) { - m_win_width = BOARD_WIDTH; + m_win_width = m_BOARD_SIZE; } SDL_SetWindowSize(m_window, m_win_width, m_win_height); + render_background(); break; } default: @@ -114,6 +213,10 @@ void SDL_Handler::handle_events() if (m_event.key.keysym.sym == SDLK_ESCAPE) handling_events = false; break; + case SDL_MOUSEBUTTONDOWN: + if (m_event.button.button == SDL_BUTTON_LEFT) + render_background(); + break; default: break; } @@ -123,34 +226,34 @@ void SDL_Handler::handle_events() break; } } - render_background(); }; void SDL_Handler::init() { if (SDL_Init(SDL_INIT_VIDEO) < 0) { - std::cout << "SDL could not initialize! SDL_Error:\n" - << SDL_GetError() << std::endl; + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "SDL could not initialize! SDL_Error: %s", SDL_GetError()); return; } m_window = SDL_CreateWindow( "Chess Game", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, - SCREEN_WIDTH, SCREEN_HEIGHT, + m_SCREEN_WIDTH, m_SCREEN_HEIGHT, SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN); if (m_window == nullptr) { - std::cout << "Window could not be created! SDL_Error: " << SDL_GetError() - << std::endl; + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "Window could not be created! SDL_Error: %s", SDL_GetError()); return; } m_renderer = SDL_CreateRenderer( m_window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); if (m_renderer == nullptr) { - std::cout << "Renderer could not be created! SDL_Error: " << SDL_GetError() - << std::endl; + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "Renderer could not be created! SDL_Error: %s", + SDL_GetError()); return; } } diff --git a/src/SDL_Handler.h b/src/SDL_Handler.h index c7b4822..61c176a 100644 --- a/src/SDL_Handler.h +++ b/src/SDL_Handler.h @@ -1,6 +1,8 @@ #pragma once -#include +#include +#include +#include class SDL_Handler { @@ -12,20 +14,26 @@ class SDL_Handler void render_background(); void render_board(); void handle_events(); + void render_texture(SDL_Texture *texture, int t_x, int t_y, int x, int y); + SDL_Texture *load_texture(const char *path); public: bool handling_events = true; + const char *PIECES_PATH = "../resources/Pieces.png"; + +private: + const int m_SCREEN_WIDTH = 900; + const int m_SCREEN_HEIGHT = 900; + const int m_BOARD_SIZE = 720; + const int m_CELL_SIZE = m_BOARD_SIZE / 8; private: SDL_Window *m_window; SDL_Renderer *m_renderer; - SDL_Event m_event; - const int SCREEN_WIDTH = 800; - const int SCREEN_HEIGHT = 800; - const int BOARD_WIDTH = 640; - const int BOARD_HEIGHT = 640; - int m_win_width = SCREEN_WIDTH; - int m_win_height = SCREEN_HEIGHT; + SDL_Event m_event{}; + SDL_Texture *m_texture{}; + int m_win_width = m_SCREEN_WIDTH; + int m_win_height = m_SCREEN_HEIGHT; #if defined(__APPLE__) || defined(__MACH__) Uint32 m_time_left(); Uint32 m_next_time = SDL_GetTicks() + 60;