Skip to content

Commit 413b39a

Browse files
committed
Merge branch 'Template' into github-actions
2 parents ba06d5a + 4ae48a6 commit 413b39a

File tree

13 files changed

+453
-46
lines changed

13 files changed

+453
-46
lines changed

.github/workflows/Build.yml

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -176,29 +176,27 @@ jobs:
176176
- name: Build
177177
id: build
178178
run: |
179+
sudo apt-get update && sudo apt-get install -y libopengl0 libglu1-mesa
179180
PACKAGE_NAME=${{ github.ref_name }}
180-
PACKAGE_VERSION=1.0.0
181+
chmod +x ./$PACKAGE_NAME
182+
PACKAGE_VERSION=$(./$PACKAGE_NAME --version --minimal-output)
183+
PACKAGE_DESC="$(./$PACKAGE_NAME --desc --minimal-output)"
181184
PACKAGE_DIR="./$PACKAGE_NAME-$PACKAGE_VERSION"
182185
mkdir -p "$PACKAGE_DIR"/usr/bin
183-
chmod +x ./$PACKAGE_NAME
184186
mv "./$PACKAGE_NAME" "$PACKAGE_DIR/usr/bin/"
185187
ln -sf libraylib.so.5.5.0 libraylib.so.550
186188
ln -sf libraylib.so.5.5.0 libraylib.so
187189
mkdir -p "$PACKAGE_DIR"/usr/lib/$PACKAGE_NAME
188190
mv ./*.so* "$PACKAGE_DIR/usr/lib/$PACKAGE_NAME/"
189191
190-
if [ -d "./resources" ]; then
191-
mkdir -p "$PACKAGE_DIR/usr/share/$PACKAGE_NAME/"
192-
cp -r ./resources "$PACKAGE_DIR/usr/share/$PACKAGE_NAME/"
193-
if [ -f "./resources/icon.png" ]; then
194-
ICON_DIR="usr/share/icons"
195-
mkdir -p "$PACKAGE_DIR/$ICON_DIR"
196-
ICON_PATH="$ICON_DIR/$PACKAGE_NAME.png"
197-
cp ./resources/icon.png "$PACKAGE_DIR/$ICON_PATH"
198-
DESKTOP_ICON_LINE="Icon=/$ICON_PATH"
199-
fi
200-
rm -rf resources
201-
fi
192+
mkdir -p "$PACKAGE_DIR/usr/share/$PACKAGE_NAME/"
193+
cp -r ./resources "$PACKAGE_DIR/usr/share/$PACKAGE_NAME/"
194+
ICON_DIR="usr/share/icons"
195+
mkdir -p "$PACKAGE_DIR/$ICON_DIR"
196+
ICON_PATH="$ICON_DIR/$PACKAGE_NAME.png"
197+
cp ./resources/icon.png "$PACKAGE_DIR/$ICON_PATH"
198+
DESKTOP_ICON_LINE="Icon=/$ICON_PATH"
199+
rm -rf resources
202200
203201
mkdir -p "$PACKAGE_DIR/usr/share/applications/"
204202
cat <<EOF > "$PACKAGE_DIR/usr/share/applications/$PACKAGE_NAME.desktop"
@@ -207,7 +205,7 @@ jobs:
207205
Name=$PACKAGE_NAME
208206
GenericName=$PACKAGE_NAME
209207
$DESKTOP_ICON_LINE
210-
Comment=Placeholder - to be replaced
208+
Comment=$PACKAGE_DESCRIPTION
211209
Exec=/usr/bin/$PACKAGE_NAME
212210
TryExec=/usr/bin/$PACKAGE_NAME
213211
Terminal=false
@@ -225,7 +223,8 @@ jobs:
225223
Priority: optional
226224
Architecture: amd64
227225
Maintainer: Johnny Cena <iamahuman1395@gmail.com>
228-
Description: Placeholder - to be replaced
226+
Description: $PACKAGE_DESCRIPTION
227+
229228
EOF
230229
231230
dpkg-deb --build "$PACKAGE_DIR" "$PACKAGE_DIR".deb
@@ -234,7 +233,6 @@ jobs:
234233
235234
- name: Test package
236235
run: |
237-
sudo apt-get update && sudo apt-get install -y libopengl0 libglu1-mesa
238236
sudo dpkg -i ${{ steps.build.outputs.package-path }}
239237
240238
- name: Upload
@@ -258,13 +256,8 @@ jobs:
258256
id: organize
259257
run: |
260258
rm -rf "Debian package" "Windows installer"
261-
if [ -d "build-win-msvc/resources" ]; then
262-
echo "resources-found=true" >> $GITHUB_OUTPUT
263-
mv build-win-msvc/resources .
264-
rm -rf */resources
265-
else
266-
echo "resources-found=false" >> $GITHUB_OUTPUT
267-
fi
259+
mv build-win-msvc/resources .
260+
rm -rf */resources
268261
269262
mkdir Release
270263
mkdir RelWithDebInfo
@@ -298,7 +291,6 @@ jobs:
298291
name: RelWithDebInfo Builds
299292

300293
- name: Upload resources zip
301-
if: steps.organize.outputs.resources-found == 'true'
302294
uses: actions/upload-artifact@v4
303295
with:
304296
path: resources/*

CMakeLists.txt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ execute_process(
77
OUTPUT_VARIABLE GIT_BRANCH
88
OUTPUT_STRIP_TRAILING_WHITESPACE
99
)
10-
project(${GIT_BRANCH}) # i might decide to change this in specific branches but overall itll be the default
10+
project(${GIT_BRANCH}
11+
LANGUAGES CXX
12+
VERSION 1.0.0
13+
)
1114

1215
if(NOT DONT_USE_CACHING_COMPILER)
1316
message(STATUS "Looking for ccache/sccache")
@@ -96,9 +99,11 @@ if(DEFINED BIN_SUFFIX)
9699
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "${PROJECT_NAME}-${BIN_SUFFIX}")
97100
endif()
98101
set_target_properties(${PROJECT_NAME} PROPERTIES
99-
BUILD_RPATH "$ORIGIN:$ORIGIN/../lib/${PROJECT_NAME}:/usr/lib/${PROJECT_NAME}"
102+
BUILD_RPATH "$ORIGIN:$ORIGIN/../lib/${PROJECT_NAME}:/usr/lib/${PROJECT_NAME}"
100103
)
101104
target_compile_definitions(${PROJECT_NAME} PRIVATE CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE})
105+
target_compile_definitions(${PROJECT_NAME} PRIVATE PROJECT_NAME="${PROJECT_NAME}")
106+
target_compile_definitions(${PROJECT_NAME} PRIVATE PROJECT_VERSION="${PROJECT_VERSION}")
102107
target_include_directories(${PROJECT_NAME} PRIVATE ${raylib_SOURCE_DIR}/src)
103108
target_link_libraries(${PROJECT_NAME} raylib)
104109

icon.rc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
IDI_ICON1 ICON "resources/icon.ico"

resources/icon.ico

16.6 KB
Binary file not shown.

resources/image.png

6.56 KB
Loading

src/argv.cpp

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
#include <raylib.h>
2+
#include <sstream>
3+
#include <iostream>
4+
#include <optional>
5+
#include "game.hpp"
6+
7+
int traceLogLevel = LOG_INFO;
8+
9+
void Game::handleArgv(int argc, char* argv[]) {
10+
11+
if (argc > 1) {
12+
bool hasError = false;
13+
struct Option {
14+
std::optional<char> singleChar;
15+
std::string full;
16+
bool& v;
17+
};
18+
static auto _this = this; // static for the tracelog callback to be able to access it
19+
bool minimalOutput = false;
20+
static bool silent = false; // here too
21+
bool verbose = false;
22+
bool saveLogs = false;
23+
bool printVersion = false;
24+
bool printHelp = false;
25+
bool printDescription = false;
26+
static std::vector<Option> const options{
27+
{ 'm', "--minimal-output", minimalOutput },
28+
{ 's', "--silent", silent },
29+
{ 'V', "--verbose", verbose },
30+
{ 'S', "--save-logs", saveLogs },
31+
{ 'v', "--version", printVersion },
32+
{ 'h', "--help", printHelp },
33+
{ 'u', "--usage", printHelp },
34+
{ 'd', "--desc", printDescription },
35+
};
36+
37+
std::optional<Path> altSaveDir;
38+
for (size_t i = 1; i < argc; i++) {
39+
std::string arg = argv[i];
40+
if (arg.starts_with("--")) {
41+
bool found = false;
42+
static char constexpr ALT_SAVE_DIR_ARG[] = "--save-dir=";
43+
if (arg.starts_with(ALT_SAVE_DIR_ARG)) {
44+
altSaveDir = arg.substr(sizeof(ALT_SAVE_DIR_ARG) - 1, std::string::npos);
45+
found = true;
46+
} else for (auto const& option : options) {
47+
if (arg == option.full) {
48+
option.v = found = true;
49+
break;
50+
}
51+
}
52+
if (!found) {
53+
std::cerr << argv[0] << ": \033[31merror\033[0m: unrecognized option -- " << arg << std::endl;
54+
hasError = true;
55+
}
56+
} else if (arg.starts_with("-")) {
57+
for (size_t i = 1; i < arg.size(); i++) {
58+
bool found = false;
59+
for (auto const& option : options) {
60+
if (arg[i] == option.singleChar) {
61+
option.v = found = true;
62+
break;
63+
}
64+
}
65+
if (!found) {
66+
std::cerr << argv[0] << ": \033[31merror\033[0m: unrecognized option -- -" << arg[i] << std::endl;
67+
hasError = true;
68+
}
69+
}
70+
} else {
71+
std::cerr << argv[0] << ": \033[31merror\033[0m: invalid argument -- " << arg << std::endl;
72+
hasError = true;
73+
}
74+
}
75+
/*
76+
std::cout << "args found:\n";
77+
for (auto const& option : options) {
78+
if (option.v){
79+
std::cout << '\t';
80+
if (option.singleChar) std::cout << '-' << *option.singleChar << '/';
81+
std::cout << option.full << '\n';
82+
}
83+
}
84+
*/
85+
if (verbose) traceLogLevel = LOG_TRACE;
86+
m_shouldSaveLogs = saveLogs;
87+
88+
auto traceLogCallback = [](int logType, const char* text, va_list args) {
89+
static size_t constexpr MAX_TRACELOG_MSG_LENGTH = 512;
90+
if (logType < traceLogLevel) return;
91+
92+
va_list argsCopy;
93+
va_copy(argsCopy, args);
94+
int size = std::vsnprintf(nullptr, 0, text, argsCopy);
95+
va_end(argsCopy);
96+
std::vector<char> buffer(size + 1);
97+
std::vsnprintf(buffer.data(), buffer.size(), text, args);
98+
99+
std::time_t currentTime = std::time(0);
100+
std::tm* localTime = std::localtime(&currentTime);
101+
102+
std::stringstream ss;
103+
ss << "[ "
104+
<< localTime->tm_hour << ":"
105+
<< localTime->tm_min << ":"
106+
<< localTime->tm_sec << " ] ";
107+
switch (logType) {
108+
case LOG_TRACE: ss << "TRACE: "; break;
109+
case LOG_DEBUG: ss << "DEBUG: "; break;
110+
case LOG_INFO: ss << "INFO: "; break;
111+
case LOG_WARNING: ss << "WARNING: "; break;
112+
case LOG_ERROR: ss << "ERROR: "; break;
113+
case LOG_FATAL: ss << "FATAL: "; break;
114+
default: break;
115+
}
116+
ss << std::string(buffer.data());
117+
118+
if (!silent) std::cout << ss.str() << std::endl;
119+
if (_this->m_shouldSaveLogs) _this->m_logs << ss.str() << std::endl;
120+
_this->m_logs.flush();
121+
};
122+
SetTraceLogCallback(traceLogCallback);
123+
124+
if (printVersion) {
125+
if (minimalOutput) std::cout << PROJECT_VERSION "\n";
126+
else std::cout << "'" PROJECT_NAME "' is a template - it is not a distributed product.\n"
127+
"it does not follow the usual versioning scheme;\n"
128+
"but its version could be considered as " PROJECT_VERSION " .\n";
129+
exit(0);
130+
} else if (printHelp) {
131+
std::cout << "Usage: " << argv[0] << " <options>\n"
132+
" -m, --minimal-output -- used for --version and --description. meant to automate package metadata in GitHub Actions.\n"
133+
" -s, --silent -- disables all logging.\n"
134+
" -V, --verbose -- sets the log level to LOG_TRACE instead of LOG_INFO.\n"
135+
" -S, --save-logs -- saves logs to a file. unaffected by --silent.\n"
136+
" -h, --help -- prints this help message and exits.\n"
137+
" -u, --usage -- same as --help.\n"
138+
" -d, --desc, -- prints a general description of this app.\n"
139+
" --save-dir=<dir> -- sets a custom directory to use for save data. includes log files.\n";
140+
exit(0);
141+
} else if (printDescription) {
142+
if (minimalOutput) std::cout << "Template project for raylib apps\n";
143+
else std::cout << "'" PROJECT_NAME "' is a template project. it is used to easily create\n"
144+
"and start new projects using raylib. it is not a full game nor an app.\n";
145+
exit(0);
146+
}
147+
148+
if (altSaveDir) {
149+
if (!DirectoryExists((*altSaveDir).string().c_str()))
150+
MakeDirectory((*altSaveDir).string().c_str());
151+
saveDir = *altSaveDir;
152+
}
153+
154+
if (hasError) exit(1);
155+
}
156+
157+
}

src/basics.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include <raylib.h>
2+
#include "basics.hpp"
3+
4+
int screenWidth = 700;
5+
int screenHeight = 500;
6+
7+
Path const resourceDir = [] -> Path {
8+
Path const exeDir = GetApplicationDirectory();
9+
#ifdef _WIN32
10+
return exeDir;
11+
#elif defined(__linux__)
12+
if (exeDir.string().starts_with("/usr") &&
13+
DirectoryExists("/usr/share/" PROJECT_NAME "/resources")
14+
) return Path{"/usr/share"}/PROJECT_NAME/"resources";
15+
#endif
16+
return exeDir/"resources";
17+
}();
18+
19+
Path saveDir = [] -> Path {
20+
Path ret = Path{GetApplicationDirectory()} / "save";
21+
#ifdef _WIN32
22+
Path appData = std::getenv("APPDATA");
23+
ret = appData/PROJECT_NAME;
24+
#elif defined(__linux__)
25+
Path homeDir = std::getenv("HOME");
26+
ret = homeDir/".local"/"share"/PROJECT_NAME;
27+
#endif
28+
if (!DirectoryExists(ret.string().c_str()))
29+
MakeDirectory(ret.string().c_str());
30+
return ret;
31+
}();

src/basics.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#pragma once
2+
#include <filesystem>
3+
4+
int constexpr START_SCREEN_WIDTH = 700;
5+
int constexpr START_SCREEN_HEIGHT = 500;
6+
7+
using Path = std::filesystem::path;
8+
extern Path const resourceDir;
9+
extern Path saveDir;

src/game.cpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#include <cmath>
2+
#include <raylib.h>
3+
#include "game.hpp"
4+
#include "basics.hpp"
5+
6+
Game::Game(int argc, char* argv[]) : m_shouldSaveLogs(false), m_logs(""),
7+
m_screenWidth(START_SCREEN_WIDTH), m_screenHeight(START_SCREEN_HEIGHT),
8+
m_resourceManager() {
9+
10+
handleArgv(argc, argv);
11+
12+
SetConfigFlags(FLAG_WINDOW_RESIZABLE);
13+
InitWindow(m_screenWidth, m_screenHeight, "Hello!");
14+
SetTargetFPS(60);
15+
16+
m_resourceManager.initialize();
17+
if (!m_resourceManager.loadImage("app-icon", "icon.png"))
18+
TraceLog(LOG_WARNING, "Failed to load app icon");
19+
SetWindowIcon(m_resourceManager.getImage("app-icon"));
20+
21+
if (!m_resourceManager.loadTexture("image", "image.png"))
22+
TraceLog(LOG_WARNING, "Failed to load dummy resource");
23+
m_dummyResource = m_resourceManager.getTexture("image");
24+
}
25+
Game::~Game() {
26+
m_resourceManager.uninitialize();
27+
CloseWindow();
28+
29+
std::time_t currentTime = std::time(0);
30+
std::tm* localTime = std::localtime(&currentTime);
31+
32+
if (m_shouldSaveLogs) {
33+
char const* logFileName = TextFormat("%i.%i.%i-%i:%i:%i.log",
34+
localTime->tm_year + 1900,
35+
localTime->tm_mon + 1,
36+
localTime->tm_mday,
37+
localTime->tm_hour,
38+
localTime->tm_min,
39+
localTime->tm_sec
40+
);
41+
Path logsDir = saveDir/"logs";
42+
if (!DirectoryExists(logsDir.string().c_str())) MakeDirectory(logsDir.string().c_str());
43+
SaveFileText((logsDir/logFileName).string().c_str(), m_logs.str().c_str());
44+
}
45+
}
46+
47+
void Game::run() {
48+
49+
while (!WindowShouldClose()) {
50+
BeginDrawing();
51+
ClearBackground(SKYBLUE);
52+
53+
m_dummyResourceRotation += GetFrameTime() * (70 * cos(GetTime() * 1.5) + 100.f);
54+
if (m_dummyResourceRotation > 360) m_dummyResourceRotation -= 360;
55+
56+
float const scale = sin(GetTime()) + 2.f;
57+
Vector2 const position = {
58+
static_cast<float>(m_screenWidth - m_dummyResource.width * scale) / 2,
59+
static_cast<float>(m_screenHeight - m_dummyResource.height * scale) / 2,
60+
};
61+
62+
Vector2 texSize = { static_cast<float>(m_dummyResource.width), static_cast<float>(m_dummyResource.height) };
63+
64+
DrawTexturePro(m_dummyResource, { 0, 0, texSize.x, texSize.y }, {
65+
m_screenWidth / 2.f, m_screenHeight / 2.f,
66+
texSize.x * scale, texSize.y * scale
67+
}, { texSize.x / 2, texSize.y / 2 }, m_dummyResourceRotation, WHITE);
68+
69+
EndDrawing();
70+
71+
m_screenWidth = GetScreenWidth();
72+
m_screenHeight = GetScreenHeight();
73+
}
74+
75+
76+
}

0 commit comments

Comments
 (0)