-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
105 lines (90 loc) · 3.18 KB
/
Copy pathmain.cpp
File metadata and controls
105 lines (90 loc) · 3.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/**
* @file main.cpp
* @brief Composition root: creates the window, GUI, and state machine,
* then runs the loop.
*
* Deliberately thin. Everything about *playing* lives in game::PlayState
* and everything about *choosing a level* in game::MenuState; this file
* only builds what outlives both (window, font, GUI context, the level
* list) and hands it to game::StateMachine.
*
* The level is discovered, never hardcoded: every `.cub` under
* `assets/maps/` is offered by the menu, which is what lets the web build
* pick a level despite having no `argv` to pass one through.
*/
#include <algorithm>
#include <cstdint>
#include <exception>
#include <filesystem>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <string_view>
#include <vector>
#include "core/app_context.hpp"
#include "core/image.hpp"
#include "core/input.hpp"
#include "core/state_machine.hpp"
#include "core/window.hpp"
#include "font.hpp"
#include "gfx/canvas.hpp"
#include "gui_context.hpp"
#include "states/menu_state.hpp"
namespace {
constexpr int32_t kWindowWidth = 1280;
constexpr int32_t kWindowHeight = 720;
constexpr std::string_view kMapsDir = "assets/maps";
constexpr std::string_view kFontAtlasPath = "assets/fonts/ui_font.png";
constexpr int kFontGlyphWidth = 8;
constexpr int kFontGlyphHeight = 16;
std::vector<std::string> ListCubMaps(std::string_view directory) {
std::vector<std::string> paths;
for (const std::filesystem::directory_entry& entry :
std::filesystem::directory_iterator(directory)) {
if (entry.is_regular_file() && entry.path().extension() == ".cub") {
paths.push_back(entry.path().string());
}
}
std::ranges::sort(paths);
return paths;
}
} // namespace
int main() {
try {
std::vector<std::string> map_paths = ListCubMaps(kMapsDir);
if (map_paths.empty()) {
throw std::runtime_error("No .cub maps found under " + std::string(kMapsDir));
}
engine::Window window(kWindowWidth, kWindowHeight, "cub3d");
engine::Input input(window);
engine::Image view_image(window, static_cast<uint32_t>(kWindowWidth),
static_cast<uint32_t>(kWindowHeight));
engine::Canvas canvas(view_image);
view_image.AttachToWindow(0, 0);
gui::Font ui_font(window, std::string(kFontAtlasPath), kFontGlyphWidth, kFontGlyphHeight);
gui::GuiContext gui_ctx;
game::AppContext context{.window = &window,
.gui = &gui_ctx,
.font = &ui_font,
.map_paths = std::move(map_paths),
.loadout = {},
.inventory = {}};
game::StateMachine machine(std::make_unique<game::MenuState>(&context));
input.OnScroll([&](double /*xdelta*/, double ydelta) { machine.OnScroll(ydelta); });
input.OnKey([&](mlx_key_data_t key) { machine.OnKey(key); });
input.OnLoop([&]() {
machine.Update(window.DeltaTime());
if (machine.done()) {
window.Close();
return;
}
machine.Render(&canvas);
});
window.Run();
return 0;
} catch (const std::exception& error) {
std::cerr << "cub3d: " << error.what() << '\n';
return 1;
}
}