Skip to content

Commit

Permalink
Added simple application sample.
Browse files Browse the repository at this point in the history
  • Loading branch information
boocmp committed Oct 31, 2022
1 parent d44737d commit 130a160
Show file tree
Hide file tree
Showing 11 changed files with 620 additions and 0 deletions.
39 changes: 39 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Defines the Chromium style for automatic reformatting.
# http://clang.llvm.org/docs/ClangFormatStyleOptions.html
BasedOnStyle: Chromium
# This defaults to 'Auto'. Explicitly set it for a while, so that
# 'vector<vector<int> >' in existing files gets formatted to
# 'vector<vector<int>>'. ('Auto' means that clang-format will only use
# 'int>>' if the file already contains at least one such instance.)
Standard: Cpp11

# Make sure code like:
# IPC_BEGIN_MESSAGE_MAP()
# IPC_MESSAGE_HANDLER(WidgetHostViewHost_Update, OnUpdate)
# IPC_END_MESSAGE_MAP()
# gets correctly indented.
MacroBlockBegin: "^\
BEGIN_MSG_MAP|\
BEGIN_MSG_MAP_EX|\
BEGIN_SAFE_MSG_MAP_EX|\
CR_BEGIN_MSG_MAP_EX|\
IPC_BEGIN_MESSAGE_MAP|\
IPC_BEGIN_MESSAGE_MAP_WITH_PARAM|\
IPC_PROTOBUF_MESSAGE_TRAITS_BEGIN|\
IPC_STRUCT_BEGIN|\
IPC_STRUCT_BEGIN_WITH_PARENT|\
IPC_STRUCT_TRAITS_BEGIN|\
POLPARAMS_BEGIN|\
PPAPI_BEGIN_MESSAGE_MAP$"
MacroBlockEnd: "^\
CR_END_MSG_MAP|\
END_MSG_MAP|\
IPC_END_MESSAGE_MAP|\
IPC_PROTOBUF_MESSAGE_TRAITS_END|\
IPC_STRUCT_END|\
IPC_STRUCT_TRAITS_END|\
POLPARAMS_END|\
PPAPI_END_MESSAGE_MAP$"

# TODO: Remove this once clang-format r357700 is rolled in.
JavaImportGroups: ['android', 'androidx', 'com', 'dalvik', 'junit', 'org', 'com.google.android.apps.chrome', 'org.chromium', 'java', 'javax']
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
build/

# Prerequisites
*.d

Expand Down
29 changes: 29 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(Windows) Launch",
"type": "cppvsdbg",
"request": "launch",
"program": "${workspaceFolder}/build/Debug/gamebase.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"console": "integratedTerminal"
},
{
"name": "(MacOS) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/gamebase",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
}
]
}
63 changes: 63 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
cmake_minimum_required (VERSION 3.5.0)

set(CMAKE_OSX_ARCHITECTURES "arm64" CACHE INTERNAL "" FORCE)

# Project name
project (gamebase)

if (WIN32)
SET(SDL2_DIR "../SDL2/cmake")
SET(SDL2_IMAGE_DIR "../SDL2_image/cmake")
endif()

find_package (SDL2 REQUIRED)
find_package (SDL2_IMAGE REQUIRED)

# Include SDL2 support for cmake

message(STATUS ${SDL2_IMAGE_INCLUDE_DIR})
message(STATUS ${SDL2_INCLUDE_DIR})
include_directories(${SDL2_INCLUDE_DIR})

# Include header files
include_directories (graphics)

set(SOURCES
${PROJECT_SOURCE_DIR}/main.cpp
${PROJECT_SOURCE_DIR}/app/baseapp.cpp
${PROJECT_SOURCE_DIR}/app/baseapp.h
${PROJECT_SOURCE_DIR}/graphics/graphics.cpp
${PROJECT_SOURCE_DIR}/graphics/graphics.h

${PROJECT_SOURCE_DIR}/snake/snake.h
)
add_executable(${PROJECT_NAME} ${SOURCES})

target_link_libraries(${PROJECT_NAME}
SDL2::SDL2
SDL2_image::SDL2_image
)

set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 17)

if(WIN32)
get_target_property(SDL2_LIBRARY SDL2::SDL2 IMPORTED_LOCATION)
get_filename_component(SDL2_LIBRARY_NAME "${SDL2_LIBRARY}" NAME)

add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
MAIN_DEPENDENCY "${SDL2_LIBRARY}"
BYPRODUCTS "${SDL2_LIBRARY_NAME}"
COMMENT "Copying SDL2 DLL"
COMMAND "${CMAKE_COMMAND}" -E copy "${SDL2_LIBRARY}" "${CMAKE_BINARY_DIR}/Debug/${SDL2_LIBRARY_NAME}"
)

get_target_property(SDL2_IMAGE_LIBRARY SDL2_image::SDL2_image IMPORTED_LOCATION)
get_filename_component(SDL2_IMAGE_LIBRARY_NAME "${SDL2_IMAGE_LIBRARY}" NAME)

add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
MAIN_DEPENDENCY "${SDL2_IMAGE_LIBRARY}"
BYPRODUCTS "${SDL2_IMAGE_LIBRARY_NAME}"
COMMENT "Copying SDL2_image DLL"
COMMAND "${CMAKE_COMMAND}" -E copy "${SDL2_IMAGE_LIBRARY}" "${CMAKE_BINARY_DIR}/Debug/${SDL2_IMAGE_LIBRARY_NAME}"
)
endif()
52 changes: 52 additions & 0 deletions app/baseapp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include "baseapp.h"

#include <SDL.h>

namespace app {

GameApp::~GameApp() = default;

void GameApp::Run() {
Initialize();

Uint32 time = SDL_GetTicks();

for (bool exit = false; !exit && !is_over_;) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
exit = true;
break;
}
}

Uint32 delta_time = SDL_GetTicks() - time;
time = SDL_GetTicks();

if (delta_time > 0) {
Update(delta_time);
}

ProcessInput(SDL_GetKeyboardState(nullptr));

SDL_SetRenderDrawColor(render::GetRenderer(), 0, 0, 0, 255);
SDL_RenderClear(render::GetRenderer());

Render();

SDL_RenderPresent(render::GetRenderer());

SDL_Delay(1000 / 60);
}

Free();

render::FreeAllResources();
}

void GameApp::GameOver() {
is_over_ = true;
}

} // namespace app
25 changes: 25 additions & 0 deletions app/baseapp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include "../graphics/graphics.h"

namespace app {

class GameApp : public render::RenderWindow {
public:
using render::RenderWindow::RenderWindow;
~GameApp() override;

void Run();
void GameOver();

private:
virtual void Initialize() {}
virtual void Free() {}
virtual void Update(Uint32 millis ) {}
virtual void Render() {}
virtual void ProcessInput(const Uint8* keyboard) {}

bool is_over_ = false;
};

} // namespace app
111 changes: 111 additions & 0 deletions graphics/graphics.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#include "graphics.h"

#include <SDL.h>
#include <SDL_image.h>

#include <exception>
#include <filesystem>
#include <stdexcept>
#include <unordered_map>

namespace render {

SDL_Renderer* GetRenderer() {
if (!RenderWindow::sdl_renderer_)
throw std::logic_error("Initialize RenderWindow first.");
return RenderWindow::sdl_renderer_;
}

SDL_Window* RenderWindow::sdl_window_ = nullptr;
SDL_Renderer* RenderWindow::sdl_renderer_ = nullptr;

RenderWindow::RenderWindow(int width, int height)
: width_(width), height_(height) {
if (sdl_window_ || sdl_renderer_)
throw std::logic_error("Renderer window already exist");

SDL_Init(SDL_INIT_EVERYTHING);

sdl_window_ = SDL_CreateWindow("GAME", SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, width_, height_, 0);

sdl_renderer_ = SDL_CreateRenderer(sdl_window_, -1, SDL_RENDERER_ACCELERATED);
}

RenderWindow::~RenderWindow() {
SDL_DestroyRenderer(sdl_renderer_);
SDL_DestroyWindow(sdl_window_);
SDL_Quit();
}

} // namespace render

namespace render {

class ResourceManager {
public:
static ResourceManager& GetInstance() {
static ResourceManager instance;
return instance;
}

void LoadResource(const std::filesystem::path& path,
const std::string& name) {
SDL_Texture* texture =
IMG_LoadTexture(GetRenderer(), path.string().c_str());
if (!texture)
throw std::invalid_argument("Can't find resource: " + path.string());
textures_[name] = texture;
}

void FreeAllResources() {
for (auto& [name, texture] : textures_) {
SDL_DestroyTexture(texture);
}
textures_.clear();
}

SDL_Texture* GetTexture(const std::string& name) {
auto fnd = textures_.find(name);
if (fnd == textures_.end())
return nullptr;
return fnd->second;
}

private:
ResourceManager() {
if (!RenderWindow::sdl_window_)
throw std::logic_error("Initialize RenderWindow first");
}

~ResourceManager() { FreeAllResources(); }

std::unordered_map<std::string, SDL_Texture*> textures_;
};

void LoadResource(const std::filesystem::path& path, const std::string& name) {
if (!name.empty()) {
ResourceManager::GetInstance().LoadResource(path, name);
} else {
ResourceManager::GetInstance().LoadResource(path, path.filename().string());
}
}

void DrawImage(const std::string& name, int x, int y, int w, int h) {
auto* texture = ResourceManager::GetInstance().GetTexture(name);
if (!texture)
throw std::invalid_argument("Texture " + name + " is not loaded.");

SDL_Rect rect = {x, y, w, h};
if (w == 0 || h == 0) {
SDL_QueryTexture(texture, nullptr, nullptr, &rect.w, &rect.h);
}

SDL_RenderCopy(GetRenderer(), texture, nullptr, &rect);
}

void FreeAllResources() {
ResourceManager::GetInstance().FreeAllResources();
}

} // namespace render
32 changes: 32 additions & 0 deletions graphics/graphics.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#pragma once

#include <SDL.h>

#include <filesystem>
#include <string>

namespace render {

class RenderWindow {
public:
RenderWindow(int width, int height);
virtual ~RenderWindow();

public:
friend SDL_Renderer* GetRenderer();

int width_ = 0;
int height_ = 0;
static SDL_Window* sdl_window_;
static SDL_Renderer* sdl_renderer_;
};

SDL_Renderer* GetRenderer();

void LoadResource(const std::filesystem::path& path,
const std::string& name = {});
void FreeAllResources();

void DrawImage(const std::string& name, int x, int y, int w = 0, int h = 0);

} // namespace render
Loading

0 comments on commit 130a160

Please sign in to comment.