Initial Commit

This commit is contained in:
Andrew Pamment 2025-04-20 10:05:21 +10:00
commit 4d661e4a3e
13 changed files with 420 additions and 0 deletions

38
ADG5.cpp Normal file
View File

@ -0,0 +1,38 @@
// ADG5.cpp : Defines the entry point for the application.
//
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
#include "libtcod.hpp"
#include "Engine.h"
#include "ADG5.h"
using namespace std;
Engine *engine;
int main(int argc, char **argv)
{
auto console = tcod::Console(80, 50);
auto params = TCOD_ContextParams{};
int playerx = 40, playery = 25;
params.console = console.get();
params.window_title = "Andrew's Dungeon Game 5";
params.sdl_window_flags = SDL_WINDOW_RESIZABLE;
params.vsync = true;
params.argc = argc;
params.argv = argv;
auto context = tcod::Context(params);
engine = new Engine(&context, &console);
engine->init();
while (engine->update()) {
engine->render();
}
delete engine;
return 0;
}

8
ADG5.h Normal file
View File

@ -0,0 +1,8 @@
// ADG5.h : Include file for standard system include files,
// or project specific include files.
#pragma once
#include <iostream>
// TODO: Reference additional headers your program requires here.

10
Actor.cpp Normal file
View File

@ -0,0 +1,10 @@
#include "libtcod.hpp"
#include "Actor.h"
Actor::Actor(int x, int y, std::string_view ch, const TCOD_ColorRGB& col) :
x(x), y(y), ch(ch), col(col) {
}
void Actor::render(TCOD_Console& cons) const {
tcod::print(cons, { x, y }, ch, col, std::nullopt);
}

13
Actor.h Normal file
View File

@ -0,0 +1,13 @@
#pragma once
#include "libtcod.hpp"
class Actor {
public:
int x, y; // position on map
std::string_view ch; // ascii code
TCOD_ColorRGB col; // color
Actor(int x, int y, std::string_view ch, const TCOD_ColorRGB& col);
void render(TCOD_Console& cons) const;
};

28
CMakeLists.txt Normal file
View File

@ -0,0 +1,28 @@
# CMakeList.txt : CMake project for ADG5, include source and define
# project specific logic here.
#
cmake_minimum_required (VERSION 3.8)
# Enable Hot Reload for MSVC compilers if supported.
if (POLICY CMP0141)
cmake_policy(SET CMP0141 NEW)
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")
endif()
project ("ADG5")
find_package(libtcod CONFIG REQUIRED)
# Add source to this project's executable.
add_executable (ADG5 "ADG5.cpp" "ADG5.h" "Actor.cpp" "Actor.h" "Map.h" "Map.cpp" "Engine.h" "Engine.cpp" )
target_link_libraries(ADG5
PRIVATE
libtcod::libtcod
)
if (CMAKE_VERSION VERSION_GREATER 3.12)
set_property(TARGET ADG5 PROPERTY CXX_STANDARD 20)
endif()
# TODO: Add tests and install targets if needed.

69
CMakePresets.json Normal file
View File

@ -0,0 +1,69 @@
{
"version": 3,
"configurePresets": [
{
"name": "windows-base",
"hidden": true,
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"installDir": "${sourceDir}/out/install/${presetName}",
"cacheVariables": {
"CMAKE_C_COMPILER": "cl.exe",
"CMAKE_CXX_COMPILER": "cl.exe"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
}
},
{
"name": "vcpkg",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
}
},
{
"name": "x64-debug",
"displayName": "x64 Debug",
"inherits": "windows-base",
"architecture": {
"value": "x64",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
},
{
"name": "x64-release",
"displayName": "x64 Release",
"inherits": "x64-debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
},
{
"name": "x86-debug",
"displayName": "x86 Debug",
"inherits": "windows-base",
"architecture": {
"value": "x86",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
},
{
"name": "x86-release",
"displayName": "x86 Release",
"inherits": "x86-debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
}
]
}

12
CMakeUserPresets.json Normal file
View File

@ -0,0 +1,12 @@
{
"version": 3,
"configurePresets": [
{
"name": "default",
"inherits": "vcpkg",
"environment": {
"VCPKG_ROOT": "C:/Users/apamm/Projects/vcpkg"
}
}
]
}

74
Engine.cpp Normal file
View File

@ -0,0 +1,74 @@
#include <SDL3/SDL.h>
#include "libtcod.hpp"
#include "Actor.h"
#include "Map.h"
#include "Engine.h"
Engine::Engine(tcod::Context *context, tcod::Console *console) {
this->context = context;
this->console = console;
map = nullptr;
player = nullptr;
}
void Engine::init() {
player = new Actor(40, 25, "@", TCOD_ColorRGB(255, 255, 255));
actors.push(player);
map = new Map(80, 45);
}
Engine::~Engine() {
actors.clearAndDelete();
delete map;
}
bool Engine::update() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
context->convert_event_coordinates(event);
switch (event.type) {
case SDL_EVENT_KEY_DOWN:
switch (event.key.key) {
case SDLK_UP:
if (!map->isWall(player->x, player->y - 1))
player->y--;
break;
case SDLK_DOWN:
if (!map->isWall(player->x, player->y + 1))
player->y++;
break;
case SDLK_LEFT:
if (!map->isWall(player->x - 1, player->y))
player->x--;
break;
case SDLK_RIGHT:
if (!map->isWall(player->x + 1, player->y))
player->x++;
break;
default:
break;
}
break;
case SDL_EVENT_QUIT:
return false;
default:
break;
}
}
return true;
}
void Engine::render() {
console->clear();
// draw the map
map->render(*console);
// draw the actors
for (Actor** iterator = actors.begin();
iterator != actors.end(); iterator++) {
(*iterator)->render(*console);
}
context->present(*console);
}

21
Engine.h Normal file
View File

@ -0,0 +1,21 @@
#pragma once
class Actor;
class Map;
#include "libtcod.hpp"
class Engine {
public:
TCODList<Actor*> actors;
Actor* player;
Map* map;
tcod::Context *context;
tcod::Console* console;
Engine(tcod::Context *context, tcod::Console *console);
void init();
~Engine();
bool update();
void render();
};
extern Engine *engine;

102
Map.cpp Normal file
View File

@ -0,0 +1,102 @@
#include "libtcod.hpp"
#include "Map.h"
#include "Actor.h"
#include "Engine.h"
static const int ROOM_MAX_SIZE = 12;
static const int ROOM_MIN_SIZE = 6;
class BspListener : public ITCODBspCallback {
private:
Map& map; // a map to dig
int roomNum; // room number
int lastx = 0, lasty = 0; // center of the last room
public:
BspListener(Map& map) : map(map), roomNum(0) {}
bool visitNode(TCODBsp* node, void* userData) {
if (node->isLeaf()) {
int x, y, w, h;
// dig a room
TCODRandom* rng = TCODRandom::getInstance();
w = rng->getInt(ROOM_MIN_SIZE, node->w - 2);
h = rng->getInt(ROOM_MIN_SIZE, node->h - 2);
x = rng->getInt(node->x + 1, node->x + node->w - w - 1);
y = rng->getInt(node->y + 1, node->y + node->h - h - 1);
map.createRoom(roomNum == 0, x, y, x + w - 1, y + h - 1);
if (roomNum != 0) {
// dig a corridor from last room
map.dig(lastx, lasty, x + w / 2, lasty);
map.dig(x + w / 2, lasty, x + w / 2, y + h / 2);
}
lastx = x + w / 2;
lasty = y + h / 2;
roomNum++;
}
return true;
}
};
Map::Map(int width, int height) : width(width), height(height) {
tiles = new Tile[width * height];
TCODBsp bsp(0, 0, width, height);
bsp.splitRecursive(NULL, 8, ROOM_MAX_SIZE, ROOM_MAX_SIZE, 1.5f, 1.5f);
BspListener listener(*this);
bsp.traverseInvertedLevelOrder(&listener, NULL);
}
Map::~Map() {
delete[] tiles;
}
bool Map::isWall(int x, int y) const {
return !tiles[x + y * width].canWalk;
}
void Map::setWall(int x, int y) {
tiles[x + y * width].canWalk = false;
}
void Map::render(TCOD_Console& cons) const {
static const TCOD_ColorRGB darkWall(0, 0, 100);
static const TCOD_ColorRGB darkGround(50, 50, 150);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
tcod::print(cons, { x, y }, " ", std::nullopt, isWall(x, y) ? darkWall : darkGround);
}
}
}
void Map::dig(int x1, int y1, int x2, int y2) {
if (x2 < x1) {
int tmp = x2;
x2 = x1;
x1 = tmp;
}
if (y2 < y1) {
int tmp = y2;
y2 = y1;
y1 = tmp;
}
for (int tilex = x1; tilex <= x2; tilex++) {
for (int tiley = y1; tiley <= y2; tiley++) {
tiles[tilex + tiley * width].canWalk = true;
}
}
}
void Map::createRoom(bool first, int x1, int y1, int x2, int y2) {
dig(x1, y1, x2, y2);
if (first) {
// put the player in the first room
engine->player->x = (x1 + x2) / 2;
engine->player->y = (y1 + y2) / 2;
}
else {
TCODRandom* rng = TCODRandom::getInstance();
if (rng->getInt(0, 3) == 0) {
engine->actors.push(new Actor((x1 + x2) / 2, (y1 + y2) / 2, "@",
TCOD_ColorRGB(255, 255, 0)));
}
}
}

26
Map.h Normal file
View File

@ -0,0 +1,26 @@
#pragma once
struct Tile {
bool explored; // has the player already seen this tile ?
Tile() : explored(false) {}
};
class Map {
public:
int width, height;
Map(int width, int height);
~Map();
bool isWall(int x, int y) const;
bool isInFov(int x, int y) const;
bool isExplored(int x, int y) const;
void computeFov();
void render(TCOD_Console& cons) const;
protected:
Tile* tiles;
friend class BspListener;
TCODMap* map;
void dig(int x1, int y1, int x2, int y2);
void createRoom(bool first, int x1, int y1, int x2, int y2);
void setWall(int x, int y);
};

14
vcpkg-configuration.json Normal file
View File

@ -0,0 +1,14 @@
{
"default-registry": {
"kind": "git",
"baseline": "0d5cae153065957df7f382de7c1549ccc88027e5",
"repository": "https://github.com/microsoft/vcpkg"
},
"registries": [
{
"kind": "artifact",
"location": "https://github.com/microsoft/vcpkg-ce-catalog/archive/refs/heads/main.zip",
"name": "microsoft"
}
]
}

5
vcpkg.json Normal file
View File

@ -0,0 +1,5 @@
{
"dependencies": [
"libtcod"
]
}