Initial Commit. Hello world!

This commit is contained in:
Safariminer 2025-06-01 16:26:04 -04:00
commit d61efe796c
17 changed files with 1696 additions and 0 deletions

9
.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
.vs
.vscode
x84
x64
*.exe
*.ipch
Release
Debug
deps

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Safariminer
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

28
ProjectMorault.sln Normal file
View File

@ -0,0 +1,28 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.12.35527.113 d17.12
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ProjectMorault", "ProjectMorault\ProjectMorault.vcxproj", "{A20204CF-23C4-4386-A432-A135319786DC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A20204CF-23C4-4386-A432-A135319786DC}.Debug|x64.ActiveCfg = Debug|x64
{A20204CF-23C4-4386-A432-A135319786DC}.Debug|x64.Build.0 = Debug|x64
{A20204CF-23C4-4386-A432-A135319786DC}.Debug|x86.ActiveCfg = Debug|Win32
{A20204CF-23C4-4386-A432-A135319786DC}.Debug|x86.Build.0 = Debug|Win32
{A20204CF-23C4-4386-A432-A135319786DC}.Release|x64.ActiveCfg = Release|x64
{A20204CF-23C4-4386-A432-A135319786DC}.Release|x64.Build.0 = Release|x64
{A20204CF-23C4-4386-A432-A135319786DC}.Release|x86.ActiveCfg = Release|Win32
{A20204CF-23C4-4386-A432-A135319786DC}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,9 @@
#pragma once
namespace Morault {
namespace Maps {
class Map {
};
}
}

View File

@ -0,0 +1,72 @@
#include "Morault_Player.h"
#include <raymath.h>
Morault::Gameplay::Player::Player()
{
}
Morault::Gameplay::Player::Player(PlayerData a, PlayerController b)
{
data = a; controller = b; // self explanatory <3
}
Morault::Gameplay::Player::~Player()
{
}
Morault::Gameplay::PlayerController::PlayerController()
{
camera = { 0 };
camera.fovy = 90;
camera.position = { -10,5,0 };
camera.target = { 0,5,0 };
camera.up = { 0,1,0 };
camera.projection = CAMERA_PERSPECTIVE;
rotation = { 10,0,0 };
}
Morault::Gameplay::PlayerController::PlayerController(Vector3 position)
{
camera = { 0 };
camera.fovy = 90;
camera.position = position;
camera.target = { 0, position.y,0 };
camera.up = { 0,1,0 };
camera.projection = CAMERA_PERSPECTIVE;
rotation = { 1,0,0 };
}
int collfloor = 5;
float gravity = 0;
void Morault::Gameplay::PlayerController::UpdatePlayerController(bool focus)
{
if (focus) {
rotation = Vector3RotateByAxisAngle(rotation, { 0,1,0 }, -GetMouseDelta().x * 0.05 * sensitivityMultiplier);
rotation.y = Clamp(rotation.y - GetMouseDelta().y * 0.3 * sensitivityMultiplier, -15, 15);
camera.target = Vector3Add(camera.position, rotation);
if (IsKeyDown(KEY_W)) camera.position = Vector3Add(camera.position, Vector3Multiply({rotation.x, 0, rotation.z}, {GetFrameTime(), GetFrameTime(), GetFrameTime()}));
if (IsKeyDown(KEY_S)) camera.position = Vector3Subtract(camera.position, Vector3Multiply({ rotation.x, 0, rotation.z }, { GetFrameTime(), GetFrameTime(), GetFrameTime() }));
if (IsKeyDown(KEY_A)) camera.position = Vector3Add(camera.position, Vector3Multiply(Vector3RotateByAxisAngle({ rotation.x, 0, rotation.z }, {0,1,0}, DEG2RAD*90), {GetFrameTime(), GetFrameTime(), GetFrameTime()}));
if (IsKeyDown(KEY_D)) camera.position = Vector3Add(camera.position, Vector3Multiply(Vector3RotateByAxisAngle({ rotation.x, 0, rotation.z }, { 0,1,0 }, DEG2RAD * -90), { GetFrameTime(), GetFrameTime(), GetFrameTime() }));
if (IsKeyPressed(KEY_SPACE)) {
gravity -= 5;
}
}
camera.position.y -= gravity*GetFrameTime();
gravity += 10*GetFrameTime();
if (camera.position.y < collfloor) {
camera.position.y = collfloor;
gravity = 0;
}
}
Morault::Gameplay::PlayerController::~PlayerController()
{
camera = { 0 };
}

View File

@ -0,0 +1,42 @@
#pragma once
#include <iostream>
#include <raylib.h>
namespace Morault {
namespace Gameplay {
typedef enum {
CITY,
MALL,
AWAITING_GAME,
IN_GAME,
AFTER_GAME
};
struct PlayerData {
std::string playerName = "";
int hp = 100, xp = 0;
// eventually: std::vector<Item> items;
// eventually: Item* primaryWeapon;
// eventually: Item* secondaryWeapon;
// eventually: Item* cosmetics;
};
class PlayerController {
public:
PlayerController();
PlayerController(Vector3 position);
Vector3 rotation;
Camera camera;
float sensitivityMultiplier = 0.5;
void UpdatePlayerController(bool focus);
~PlayerController();
};
class Player {
public:
Player();
Player(PlayerData, PlayerController);
PlayerData data;
PlayerController controller;
~Player();
};
}
}

View File

@ -0,0 +1,137 @@
#include "Morault_Resources.h"
#include "Morault_Utils.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
std::map<std::string, ::Model> __models_map;
Morault::Resources::_ResourceRequest Morault::Resources::load(std::string modelName)
{
_ResourceRequest retval;
retval.type = _ResourceRequestType::LOAD;
retval.req = modelName;
return retval;
}
Morault::Resources::_ResourceRequest Morault::Resources::get(std::string modelName)
{
_ResourceRequest retval;
retval.type = _ResourceRequestType::GET;
retval.req = modelName;
return retval;
}
Morault::Resources::_ResourceRequest Morault::Resources::unload(std::string modelName)
{
_ResourceRequest retval;
retval.type = _ResourceRequestType::UNLOAD;
retval.req = modelName;
return retval;
}
Morault::Resources::_ResourceRequest Morault::Resources::reload(std::string modelName)
{
_ResourceRequest retval;
retval.type = _ResourceRequestType::RELOAD;
retval.req = modelName;
return retval;
}
std::variant<Model, bool> Morault::Resources::Models(_ResourceRequest request)
{
switch (request.type) {
case LOAD:
__models_map[request.req] = LoadModel(request.req.c_str());
return true;
break;
case GET:
return __models_map[request.req];
break;
case UNLOAD:
UnloadModel(__models_map[request.req]);
return true;
break;
case RELOAD:
UnloadModel(__models_map[request.req]);
__models_map[request.req] = LoadModel(request.req.c_str());
return true;
break;
}
}
Image Morault::Resources::GenTestImage()
{
Image retval = GenImageColor(256, 256, BLANK);
for (int y = 0; y < 256; y++) {
for (int x = 0; x < 256; x++) {
ImageDrawPixel(&retval, x, y, { (unsigned char)x, (unsigned char)y, (unsigned char)(255 - x), 255 });
}
}
return retval;
}
Morault::Resources::WAD::WAD()
{
std::cout << "Warning: Empty WAD instance created.\n";
}
Morault::Resources::WAD::WAD(std::string path)
{
LoadWAD(path);
}
void Morault::Resources::WAD::LoadWAD(std::string path)
{
loaded = false;
lumps.clear();
lumpCount = 0;
std::cout << "Loading file " << path << "...\n";
std::ifstream file(path, std::ios::binary);
std::string filedata;
std::stringstream filestream; filestream << file.rdbuf();
filedata = filestream.str();
if (
Morault::Utils::Strings::IterativeComp(filedata, 0, "IWAD")) {
wadType = IWAD;
std::cout << "File is an IWAD\n";
}
else if (Morault::Utils::Strings::IterativeComp(filedata, 0, "PWAD")) {
wadType = PWAD;
std::cout << "File is a PWAD\n";
}
else {
throw std::runtime_error("Invalid WAD file: Error at header start(IWAD/PWAD)\n");
}
lumpCount = Morault::Utils::Strings::StringIndexToInteger_4b_le(filedata, 4);
std::cout << "File has " << lumpCount << " lumps\n";
int directoryPointer = Morault::Utils::Strings::StringIndexToInteger_4b_le(filedata, 8);
std::string directory = Morault::Utils::Strings::IterativeStringExcerpt(filedata, directoryPointer, 16 * lumpCount);
for (int i = 0; i < lumpCount; i++) {
Lump lump;
std::string lumpIndex = Morault::Utils::Strings::IterativeStringExcerpt(directory, i * 16, 16);
int lumpPointer = Morault::Utils::Strings::StringIndexToInteger_4b_le(lumpIndex, 0);
int lumpSize = Morault::Utils::Strings::StringIndexToInteger_4b_le(lumpIndex, 4);
lump.name = "", lump.data = "";
for (int j = 0; j < 8; j++) {
if (lumpIndex.at(8 + j) != 0x0) lump.name += lumpIndex.at(8 + j);
}
lump.data = Morault::Utils::Strings::IterativeStringExcerpt(filedata, lumpPointer, lumpSize);
lumps.push_back(lump);
std::cout << "(" << i << "/" << lumpCount << ")" << "Loaded lump \"" << lump.name << "\" of size " << lumpSize << "\n";
}
loaded = true;
}
Morault::Resources::WAD::~WAD()
{
}

View File

@ -0,0 +1,56 @@
#pragma once
#include <iostream>
#include <vector>
#include <map>
#include <raylib.h>
#include <variant>
namespace Morault {
namespace Resources {
typedef enum {
GET,
LOAD,
UNLOAD,
RELOAD
} _ResourceRequestType;
struct _ResourceRequest { // to use as std::get<Model>(Models(get("test.obj")));
_ResourceRequestType type;
std::string req;
};
_ResourceRequest load(std::string modelName);
_ResourceRequest get(std::string modelName);
_ResourceRequest unload(std::string modelName);
_ResourceRequest reload(std::string modelName);
std::variant<Model, bool> Models(_ResourceRequest request);
typedef enum {
INVALID, IWAD, PWAD
} WADType;
struct Lump {
std::string name, data;
};
class WAD {
std::vector<Lump> lumps;
public:
bool loaded = false;
WADType wadType;
int lumpCount;
WAD();
WAD(std::string path);
void LoadWAD(std::string path);
std::vector<Lump> getLumps() {
return lumps;
}
~WAD();
};
Image GenTestImage();
}
}

View File

@ -0,0 +1,757 @@
#include "Morault_UDMF.h"
#include <string>
#include "Morault_Utils.h"
#include <sstream>
#include <fstream>
#include <filesystem>
void Morault::UDMF::UDMFMap::LoadMap(std::string textmap)
{
std::stringstream text(textmap);
std::string previousLine;
std::string line;
std::string blockType;
bool inblock = false;
Linedef linedef;
Sidedef sidedef;
Vertex vertex;
Sector sector;
while (std::getline(text, line)) {
auto [key, val] = Morault::Utils::Strings::ParseCLineIntoKeyVal(line);
if (key == "namespace") udmfNamespace = val;
if (key == "") {
if (line == "{") {
blockType = Morault::Utils::Strings::SingleWordTrimmer(previousLine);
if (blockType == "linedef") linedef = Linedef();
if (blockType == "sidedef") sidedef = Sidedef();
if (blockType == "vertex") vertex = Vertex();
if (blockType == "sector") sector = Sector();
inblock = true;
if (blockType != "linedef" && blockType != "sidedef" && blockType != "vertex" && blockType != "sector") {
std::cout << "Unsupported block type " << blockType << "\n";
inblock = false;
}
}
if (line == "}") {
inblock = false;
if (blockType == "linedef") linedefs.push_back(linedef);
if (blockType == "sidedef") sidedefs.push_back(sidedef);
if (blockType == "vertex") vertexes.push_back(vertex);
if (blockType == "sector") sectors.push_back(sector);
}
}
else {
if (inblock) {
if (blockType == "linedef") {
if (key == "v1") linedef.v1 = std::stoi(val);
if (key == "v2") linedef.v2 = std::stoi(val);
if (key == "sidefront") linedef.sidefront = std::stoi(val);
if (key == "sideback") linedef.sideback = std::stoi(val);
//was if (key == "sideback") linedef.sidefront = std::stoi(val);
if (key == "blocking") linedef.blocking = val == "true";
}
if (blockType == "sidedef") {
if (key == "sector") sidedef.sector = std::stoi(val);
if (key == "texturemiddle") sidedef.texturemiddle = val;
}
if (blockType == "vertex") {
if (key == "x") vertex.x = std::stof(val);
if (key == "y") vertex.y = std::stof(val);
}
if (blockType == "sector") {
if (key == "texturefloor") sector.texturefloor = val;
if (key == "textureceiling") sector.textureceiling = val;
if (key == "heightceiling") sector.heightceiling = std::stoi(val);
if (key == "heightfloor") sector.heightfloor = std::stoi(val);
}
}
}
// std::cout << "Key " << key << " as " << val << std::endl;
previousLine = line;
}
std::cout << "Linedefs: " << linedefs.size() << "\n";
std::cout << "Sidedefs: " << sidedefs.size() << "\n";
std::cout << "Vertexes: " << vertexes.size() << "\n";
std::cout << "Sectors: " << sectors.size() << "\n";
}
Model Morault::UDMF::LoadModelUDMFWalls(UDMFMap map)
{
std::string vertices = "";
int verticeCount = 0;
std::string vertexnormals = "";
int vertexNormalsCount = 0;
std::string faces = "";
for (int i = 0; i < map.linedefs.size(); i++) {
// DrawLine(map.vertexes[map.linedefs[i].v1].x + offset.x, map.vertexes[map.linedefs[i].v1].y + offset.y, map.vertexes[map.linedefs[i].v2].x + offset.x, map.vertexes[map.linedefs[i].v2].y + offset.y, YELLOW);
bool valuesUninitialized = true;
float lowestPoint = 0;
float midLowestPoint = 0;
float midHighestPoint = 0;
float highestPoint = 0;
if (map.linedefs[i].sidefront != -1) {
lowestPoint = map.sectors[map.sidedefs[map.linedefs[i].sidefront].sector].heightfloor;
highestPoint = map.sectors[map.sidedefs[map.linedefs[i].sidefront].sector].heightceiling;
midLowestPoint = lowestPoint;
midHighestPoint = highestPoint;
valuesUninitialized = false;
}
if (map.linedefs[i].sideback != -1) {
if (valuesUninitialized) {
// std::cout << "values uninit\n";
lowestPoint = map.sectors[map.sidedefs[map.linedefs[i].sideback].sector].heightfloor;
highestPoint = map.sectors[map.sidedefs[map.linedefs[i].sideback].sector].heightceiling;
midLowestPoint = lowestPoint;
midHighestPoint = highestPoint;
}
else {
// lowestPoint = map.sectors[map.sidedefs[map.linedefs[i].sideback].sector].heightfloor < lowestPoint ? map.sectors[map.sidedefs[map.linedefs[i].sideback].sector].heightfloor : lowestPoint;
// highestPoint = map.sectors[map.sidedefs[map.linedefs[i].sideback].sector].heightceiling > highestPoint ? map.sectors[map.sidedefs[map.linedefs[i].sideback].sector].heightceiling : highestPoint;
int lowPoint = map.sectors[map.sidedefs[map.linedefs[i].sideback].sector].heightfloor;
int highPoint = map.sectors[map.sidedefs[map.linedefs[i].sideback].sector].heightceiling;
if (lowPoint < lowestPoint) lowestPoint = lowPoint;
else midLowestPoint = lowPoint;
if (highPoint > highestPoint) highestPoint = highPoint;
else midHighestPoint = highPoint;
}
valuesUninitialized = false;
}
// std::cout << lowestPoint << " " << midLowestPoint << " " << midHighestPoint << " " << highestPoint << "\n";
if (map.linedefs[i].sidefront != -1) {
if (map.sidedefs[map.linedefs[i].sidefront].texturemiddle != "") {
/*DrawTriangle3D(
{
-1 * map.vertexes[map.linedefs[i].v1].x,
(float)map.sectors[map.sidedefs[map.linedefs[i].sidefront].sector].heightceiling,
map.vertexes[map.linedefs[i].v1].y
},
{
-1 * map.vertexes[map.linedefs[i].v1].x,
(float)map.sectors[map.sidedefs[map.linedefs[i].sidefront].sector].heightfloor,
map.vertexes[map.linedefs[i].v1].y
},
{
-1 * map.vertexes[map.linedefs[i].v2].x,
(float)map.sectors[map.sidedefs[map.linedefs[i].sidefront].sector].heightfloor,
map.vertexes[map.linedefs[i].v2].y
},
ColorLerp({ 255,0,0,255 }, { 0,0,255,255 }, (float)i / (float)map.linedefs.size())
);*/
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v1].x,
(float)map.sectors[map.sidedefs[map.linedefs[i].sidefront].sector].heightceiling,
map.vertexes[map.linedefs[i].v1].y);
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v1].x,
(float)map.sectors[map.sidedefs[map.linedefs[i].sidefront].sector].heightfloor,
map.vertexes[map.linedefs[i].v1].y);
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v2].x,
(float)map.sectors[map.sidedefs[map.linedefs[i].sidefront].sector].heightfloor,
map.vertexes[map.linedefs[i].v2].y);
vertexNormalsCount++;
vertexnormals += TextFormat("vn %f %f %f\n", (map.vertexes[map.linedefs[i].v2].y - map.vertexes[map.linedefs[i].v1].y), 0, -(map.vertexes[map.linedefs[i].v2].x - map.vertexes[map.linedefs[i].v1].x));
faces += TextFormat("f %i//%i %i//%i %i//%i\n", verticeCount + 1, vertexNormalsCount, verticeCount + 2, vertexNormalsCount, verticeCount + 3, vertexNormalsCount);
verticeCount += 3;
/*DrawTriangle3D(
{
-1 * map.vertexes[map.linedefs[i].v1].x,
(float)map.sectors[map.sidedefs[map.linedefs[i].sidefront].sector].heightceiling,
map.vertexes[map.linedefs[i].v1].y
},
{
-1 * map.vertexes[map.linedefs[i].v2].x,
(float)map.sectors[map.sidedefs[map.linedefs[i].sidefront].sector].heightfloor,
map.vertexes[map.linedefs[i].v2].y
},
{
-1 * map.vertexes[map.linedefs[i].v2].x,
(float)map.sectors[map.sidedefs[map.linedefs[i].sidefront].sector].heightceiling,
map.vertexes[map.linedefs[i].v2].y
},
ColorLerp({ 255,0,0,255 }, { 0,255,0,255 }, (float)i / (float)map.linedefs.size())
);*/
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v1].x,
(float)map.sectors[map.sidedefs[map.linedefs[i].sidefront].sector].heightceiling,
map.vertexes[map.linedefs[i].v1].y);
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v2].x,
(float)map.sectors[map.sidedefs[map.linedefs[i].sidefront].sector].heightfloor,
map.vertexes[map.linedefs[i].v2].y);
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v2].x,
(float)map.sectors[map.sidedefs[map.linedefs[i].sidefront].sector].heightceiling,
map.vertexes[map.linedefs[i].v2].y);
vertexNormalsCount++;
vertexnormals += TextFormat("vn %f %f %f\n", (map.vertexes[map.linedefs[i].v2].y - map.vertexes[map.linedefs[i].v1].y), 0, -(map.vertexes[map.linedefs[i].v2].x - map.vertexes[map.linedefs[i].v1].x));
faces += TextFormat("f %i//%i %i//%i %i//%i\n", verticeCount + 1, vertexNormalsCount, verticeCount + 2, vertexNormalsCount, verticeCount + 3, vertexNormalsCount);
verticeCount += 3;
}
/*DrawTriangle3D(
{
-1 * map.vertexes[map.linedefs[i].v1].x,
highestPoint,
map.vertexes[map.linedefs[i].v1].y
},
{
-1 * map.vertexes[map.linedefs[i].v1].x,
midHighestPoint,
map.vertexes[map.linedefs[i].v1].y
},
{
-1 * map.vertexes[map.linedefs[i].v2].x,
midHighestPoint,
map.vertexes[map.linedefs[i].v2].y
},
ColorLerp({ 255,0,0,255 }, { 0,0,255,255 }, (float)i / (float)map.linedefs.size())
);*/
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v1].x,
highestPoint,
map.vertexes[map.linedefs[i].v1].y);
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v1].x,
midHighestPoint,
map.vertexes[map.linedefs[i].v1].y);
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v2].x,
midHighestPoint,
map.vertexes[map.linedefs[i].v2].y);
vertexNormalsCount++;
vertexnormals += TextFormat("vn %f %f %f\n", (map.vertexes[map.linedefs[i].v2].y - map.vertexes[map.linedefs[i].v1].y), 0, -(map.vertexes[map.linedefs[i].v2].x - map.vertexes[map.linedefs[i].v1].x));
faces += TextFormat("f %i//%i %i//%i %i//%i\n", verticeCount + 1, vertexNormalsCount, verticeCount + 2, vertexNormalsCount, verticeCount + 3, vertexNormalsCount);
verticeCount += 3;
/*DrawTriangle3D(
{
-1 * map.vertexes[map.linedefs[i].v1].x,
highestPoint,
map.vertexes[map.linedefs[i].v1].y
},
{
-1 * map.vertexes[map.linedefs[i].v2].x,
midHighestPoint,
map.vertexes[map.linedefs[i].v2].y
},
{
-1 * map.vertexes[map.linedefs[i].v2].x,
highestPoint,
map.vertexes[map.linedefs[i].v2].y
},
ColorLerp({ 255,0,0,255 }, { 0,255,0,255 }, (float)i / (float)map.linedefs.size())
);*/
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v1].x,
highestPoint,
map.vertexes[map.linedefs[i].v1].y);
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v2].x,
midHighestPoint,
map.vertexes[map.linedefs[i].v2].y);
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v2].x,
highestPoint,
map.vertexes[map.linedefs[i].v2].y);
vertexNormalsCount++;
vertexnormals += TextFormat("vn %f %f %f\n", (map.vertexes[map.linedefs[i].v2].y - map.vertexes[map.linedefs[i].v1].y), 0, -(map.vertexes[map.linedefs[i].v2].x - map.vertexes[map.linedefs[i].v1].x));
faces += TextFormat("f %i//%i %i//%i %i//%i\n", verticeCount + 1, vertexNormalsCount, verticeCount + 2, vertexNormalsCount, verticeCount + 3, vertexNormalsCount);
verticeCount += 3;
// ---
/*DrawTriangle3D(
{
-1 * map.vertexes[map.linedefs[i].v1].x,
midLowestPoint,
map.vertexes[map.linedefs[i].v1].y
},
{
-1 * map.vertexes[map.linedefs[i].v1].x,
lowestPoint,
map.vertexes[map.linedefs[i].v1].y
},
{
-1 * map.vertexes[map.linedefs[i].v2].x,
lowestPoint,
map.vertexes[map.linedefs[i].v2].y
},
ColorLerp({ 255,0,0,255 }, { 0,0,255,255 }, (float)i / (float)map.linedefs.size())
);*/
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v1].x,
midLowestPoint,
map.vertexes[map.linedefs[i].v1].y);
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v1].x,
lowestPoint,
map.vertexes[map.linedefs[i].v1].y);
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v2].x,
lowestPoint,
map.vertexes[map.linedefs[i].v2].y);
vertexNormalsCount++;
vertexnormals += TextFormat("vn %f %f %f\n", (map.vertexes[map.linedefs[i].v2].y - map.vertexes[map.linedefs[i].v1].y), 0, -(map.vertexes[map.linedefs[i].v2].x - map.vertexes[map.linedefs[i].v1].x));
faces += TextFormat("f %i//%i %i//%i %i//%i\n", verticeCount + 1, vertexNormalsCount, verticeCount + 2, vertexNormalsCount, verticeCount + 3, vertexNormalsCount);
verticeCount += 3;
/*DrawTriangle3D(
{
-1 * map.vertexes[map.linedefs[i].v1].x,
midLowestPoint,
map.vertexes[map.linedefs[i].v1].y
},
{
-1 * map.vertexes[map.linedefs[i].v2].x,
lowestPoint,
map.vertexes[map.linedefs[i].v2].y
},
{
-1 * map.vertexes[map.linedefs[i].v2].x,
midLowestPoint,
map.vertexes[map.linedefs[i].v2].y
},
ColorLerp({ 255,0,0,255 }, { 0,255,0,255 }, (float)i / (float)map.linedefs.size())
);*/
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v1].x,
midLowestPoint,
map.vertexes[map.linedefs[i].v1].y);
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v2].x,
lowestPoint,
map.vertexes[map.linedefs[i].v2].y);
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v2].x,
midLowestPoint,
map.vertexes[map.linedefs[i].v2].y);
vertexNormalsCount++;
vertexnormals += TextFormat("vn %f %f %f\n", (map.vertexes[map.linedefs[i].v2].y - map.vertexes[map.linedefs[i].v1].y), 0, -(map.vertexes[map.linedefs[i].v2].x - map.vertexes[map.linedefs[i].v1].x));
faces += TextFormat("f %i//%i %i//%i %i//%i\n", verticeCount + 1, vertexNormalsCount, verticeCount + 2, vertexNormalsCount, verticeCount + 3, vertexNormalsCount);
verticeCount += 3;
}
if (map.linedefs[i].sideback != -1) {
if (map.sidedefs[map.linedefs[i].sideback].texturemiddle != "") {
/*DrawTriangle3D(
{
-1 * map.vertexes[map.linedefs[i].v2].x,
(float)map.sectors[map.sidedefs[map.linedefs[i].sideback].sector].heightceiling,
map.vertexes[map.linedefs[i].v2].y
},
{
-1 * map.vertexes[map.linedefs[i].v2].x,
(float)map.sectors[map.sidedefs[map.linedefs[i].sideback].sector].heightfloor,
map.vertexes[map.linedefs[i].v2].y
},
{
-1 * map.vertexes[map.linedefs[i].v1].x,
(float)map.sectors[map.sidedefs[map.linedefs[i].sideback].sector].heightfloor,
map.vertexes[map.linedefs[i].v1].y
},
ColorLerp({ 255,0,0,255 }, { 0,0,255,255 }, i / map.linedefs.size())
);*/
vertices += TextFormat("v %f %f %f\n", // it's at this point i realized I should've probably made this a function
-1 * map.vertexes[map.linedefs[i].v2].x,
(float)map.sectors[map.sidedefs[map.linedefs[i].sideback].sector].heightceiling,
map.vertexes[map.linedefs[i].v2].y);
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v2].x,
(float)map.sectors[map.sidedefs[map.linedefs[i].sideback].sector].heightfloor,
map.vertexes[map.linedefs[i].v2].y);
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v1].x,
(float)map.sectors[map.sidedefs[map.linedefs[i].sideback].sector].heightfloor,
map.vertexes[map.linedefs[i].v1].y);
vertexNormalsCount++;
vertexnormals += TextFormat("vn %f %f %f\n", (map.vertexes[map.linedefs[i].v2].y - map.vertexes[map.linedefs[i].v1].y), 0, -(map.vertexes[map.linedefs[i].v2].x - map.vertexes[map.linedefs[i].v1].x));
faces += TextFormat("f %i//%i %i//%i %i//%i\n", verticeCount + 1, vertexNormalsCount, verticeCount + 2, vertexNormalsCount, verticeCount + 3, vertexNormalsCount);
verticeCount += 3;
/*DrawTriangle3D(
{
-1 * map.vertexes[map.linedefs[i].v2].x,
(float)map.sectors[map.sidedefs[map.linedefs[i].sideback].sector].heightceiling,
map.vertexes[map.linedefs[i].v2].y
},
{
-1 * map.vertexes[map.linedefs[i].v1].x,
(float)map.sectors[map.sidedefs[map.linedefs[i].sideback].sector].heightfloor,
map.vertexes[map.linedefs[i].v1].y
},
{
-1 * map.vertexes[map.linedefs[i].v1].x,
(float)map.sectors[map.sidedefs[map.linedefs[i].sideback].sector].heightceiling,
map.vertexes[map.linedefs[i].v1].y
},
ColorLerp({ 255,0,0,255 }, { 0,0,255,255 }, (float)i / (float)map.linedefs.size())
);*/
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v2].x,
(float)map.sectors[map.sidedefs[map.linedefs[i].sideback].sector].heightceiling,
map.vertexes[map.linedefs[i].v2].y);
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v1].x,
(float)map.sectors[map.sidedefs[map.linedefs[i].sideback].sector].heightfloor,
map.vertexes[map.linedefs[i].v1].y);
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v1].x,
(float)map.sectors[map.sidedefs[map.linedefs[i].sideback].sector].heightceiling,
map.vertexes[map.linedefs[i].v1].y);
vertexNormalsCount++;
vertexnormals += TextFormat("vn %f %f %f\n", (map.vertexes[map.linedefs[i].v2].y - map.vertexes[map.linedefs[i].v1].y), 0, -(map.vertexes[map.linedefs[i].v2].x - map.vertexes[map.linedefs[i].v1].x));
faces += TextFormat("f %i//%i %i//%i %i//%i\n", verticeCount + 1, vertexNormalsCount, verticeCount + 2, vertexNormalsCount, verticeCount + 3, vertexNormalsCount);
verticeCount += 3;
}
/*DrawTriangle3D(
{
-1 * map.vertexes[map.linedefs[i].v2].x,
midHighestPoint,
map.vertexes[map.linedefs[i].v2].y
},
{
-1 * map.vertexes[map.linedefs[i].v1].x,
midHighestPoint,
map.vertexes[map.linedefs[i].v1].y
},
{
-1 * map.vertexes[map.linedefs[i].v1].x,
highestPoint,
map.vertexes[map.linedefs[i].v1].y
},
ColorLerp({ 255,0,0,255 }, { 0,0,255,255 }, (float)i / (float)map.linedefs.size())
);*/
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v2].x,
midHighestPoint,
map.vertexes[map.linedefs[i].v2].y);
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v1].x,
midHighestPoint,
map.vertexes[map.linedefs[i].v1].y);
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v1].x,
highestPoint,
map.vertexes[map.linedefs[i].v1].y);
vertexNormalsCount++;
vertexnormals += TextFormat("vn %f %f %f\n", (map.vertexes[map.linedefs[i].v2].y - map.vertexes[map.linedefs[i].v1].y), 0, -(map.vertexes[map.linedefs[i].v2].x - map.vertexes[map.linedefs[i].v1].x));
faces += TextFormat("f %i//%i %i//%i %i//%i\n", verticeCount + 1, vertexNormalsCount, verticeCount + 2, vertexNormalsCount, verticeCount + 3, vertexNormalsCount);
verticeCount += 3;
/*DrawTriangle3D(
{
-1 * map.vertexes[map.linedefs[i].v2].x,
highestPoint,
map.vertexes[map.linedefs[i].v2].y
},
{
-1 * map.vertexes[map.linedefs[i].v2].x,
midHighestPoint,
map.vertexes[map.linedefs[i].v2].y
},
{
-1 * map.vertexes[map.linedefs[i].v1].x,
highestPoint,
map.vertexes[map.linedefs[i].v1].y
},
ColorLerp({ 255,0,0,255 }, { 0,255,0,255 }, (float)i / (float)map.linedefs.size())
);*/
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v2].x,
highestPoint,
map.vertexes[map.linedefs[i].v2].y);
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v2].x,
midHighestPoint,
map.vertexes[map.linedefs[i].v2].y);
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v1].x,
highestPoint,
map.vertexes[map.linedefs[i].v1].y);
vertexNormalsCount++;
vertexnormals += TextFormat("vn %f %f %f\n", (map.vertexes[map.linedefs[i].v2].y - map.vertexes[map.linedefs[i].v1].y), 0, -(map.vertexes[map.linedefs[i].v2].x - map.vertexes[map.linedefs[i].v1].x));
faces += TextFormat("f %i//%i %i//%i %i//%i\n", verticeCount + 1, vertexNormalsCount, verticeCount + 2, vertexNormalsCount, verticeCount + 3, vertexNormalsCount);
verticeCount += 3;
// ---
/*DrawTriangle3D(
{
-1 * map.vertexes[map.linedefs[i].v2].x,
lowestPoint,
map.vertexes[map.linedefs[i].v2].y
},
{
-1 * map.vertexes[map.linedefs[i].v1].x,
lowestPoint,
map.vertexes[map.linedefs[i].v1].y
},
{
-1 * map.vertexes[map.linedefs[i].v1].x,
midLowestPoint,
map.vertexes[map.linedefs[i].v1].y
},
ColorLerp({ 255,0,0,255 }, { 0,0,255,255 }, (float)i / (float)map.linedefs.size())
);*/
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v2].x,
lowestPoint,
map.vertexes[map.linedefs[i].v2].y);
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v1].x,
lowestPoint,
map.vertexes[map.linedefs[i].v1].y);
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v1].x,
midLowestPoint,
map.vertexes[map.linedefs[i].v1].y);
vertexNormalsCount++;
vertexnormals += TextFormat("vn %f %f %f\n", (map.vertexes[map.linedefs[i].v2].y - map.vertexes[map.linedefs[i].v1].y), 0, -(map.vertexes[map.linedefs[i].v2].x - map.vertexes[map.linedefs[i].v1].x));
faces += TextFormat("f %i//%i %i//%i %i//%i\n", verticeCount + 1, vertexNormalsCount, verticeCount + 2, vertexNormalsCount, verticeCount + 3, vertexNormalsCount);
verticeCount += 3;
/*DrawTriangle3D(
{
-1 * map.vertexes[map.linedefs[i].v2].x,
midLowestPoint,
map.vertexes[map.linedefs[i].v2].y
},
{
-1 * map.vertexes[map.linedefs[i].v2].x,
lowestPoint,
map.vertexes[map.linedefs[i].v2].y
},
{
-1 * map.vertexes[map.linedefs[i].v1].x,
midLowestPoint,
map.vertexes[map.linedefs[i].v1].y
},
ColorLerp({ 255,0,0,255 }, { 0,255,0,255 }, (float)i / (float)map.linedefs.size())
);*/
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v2].x,
midLowestPoint,
map.vertexes[map.linedefs[i].v2].y);
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v2].x,
lowestPoint,
map.vertexes[map.linedefs[i].v2].y);
vertices += TextFormat("v %f %f %f\n",
-1 * map.vertexes[map.linedefs[i].v1].x,
midLowestPoint,
map.vertexes[map.linedefs[i].v1].y);
vertexNormalsCount++;
vertexnormals += TextFormat("vn %f %f %f\n", (map.vertexes[map.linedefs[i].v2].y - map.vertexes[map.linedefs[i].v1].y), 0, -(map.vertexes[map.linedefs[i].v2].x - map.vertexes[map.linedefs[i].v1].x));
faces += TextFormat("f %i//%i %i//%i %i//%i\n", verticeCount + 1, vertexNormalsCount, verticeCount + 2, vertexNormalsCount, verticeCount + 3, vertexNormalsCount);
verticeCount += 3;
}
}
SetRandomSeed(time(NULL));
std::string randomNumber = std::to_string(GetRandomValue(0, INT_MAX));
std::string appdata = ".";// getenv("LOCALAPPDATA");
std::filesystem::create_directory(appdata + "\\ProjectMorault");
std::filesystem::create_directory(appdata + "\\ProjectMorault\\__udmfCache");
std::ofstream cacheModel(appdata + "\\ProjectMorault\\__udmfCache\\" + randomNumber + ".obj");
std::cout << "Outputting cache model to " << appdata + "\\ProjectMorault\\__udmfCache\\" + randomNumber + ".obj" << "\n";
cacheModel << vertices;
cacheModel << vertexnormals;
cacheModel << faces;
cacheModel.close();
std::string p = appdata + "\\ProjectMorault\\__udmfCache\\" + randomNumber + ".obj";
Model retval = LoadModel(p.c_str());
return retval;
}
Model Morault::UDMF::LoadModelUDMFFlats(UDMFMap map)
{
int vertexCount = 0; // number of vertices
std::string vertices = ""; // straight wavefront data for the vertices
int vertexNormalsCount = 0; // number of vertex normals
std::string vertexNormals = ""; // straight wavefront data for vertexNormals
std::string faces; // straight wavefront data for faces
for (int sc = 0; sc < map.sectors.size(); sc++) {
std::vector<Vertex>* verticesVector = new std::vector<Vertex>();
for (int sd = 0; sd < map.sidedefs.size(); sd++) {
if(map.sidedefs[sd].sector == sc){
for (int ld = 0; ld < map.linedefs.size(); ld++) {
if (map.linedefs[ld].sidefront == sd) {
verticesVector->push_back(map.vertexes[map.linedefs[ld].v1]);
verticesVector->push_back(map.vertexes[map.linedefs[ld].v2]);
}
else if (map.linedefs[ld].sideback == sd) { // you, in theory, shouldn't be able to have both the back and front of a linedef be the same.
verticesVector->push_back(map.vertexes[map.linedefs[ld].v2]);// invert vertices if sideback
verticesVector->push_back(map.vertexes[map.linedefs[ld].v1]);
}
}
}
}
// calculating ceilings
/*
vertexNormalsCount++;
vertexNormals += "vn 0 1 0\n";*/
/*faces += "f ";
for (int i = 0; i < verticesVector->size(); i++) {
vertices += TextFormat("v %f %f %f\n", -1 * verticesVector->at(i).x, (float)map.sectors[sc].heightceiling, verticesVector->at(i).y);
faces += TextFormat("%i//%i ", vertexCount + i + 1, vertexNormalsCount);
if (i % 3 == 0 && i != 0) {
faces.pop_back();
faces += "\nf ";
}
}
faces.pop_back();
if (faces.at(faces.size() - 1) == 'f') {
faces.pop_back();
}
else {
faces += TextFormat(" %i//%i", vertexCount + 1, vertexNormalsCount);
}
faces += "\n";
vertexCount += verticesVector->size();*/
// calculating floors
vertexNormalsCount++;
vertexNormals += "vn 0 1 0\n";
faces += "f ";
for (int i = 0; i < verticesVector->size(); i++) {
vertices += TextFormat("v %f %f %f\n", -1 * verticesVector->at(verticesVector->size() - 1 - i).x, (float)map.sectors[sc].heightfloor, verticesVector->at(verticesVector->size() - 1 - i).y);
faces += TextFormat("%i//%i ", vertexCount + i + 1, vertexNormalsCount);
if (i % 3 == 0 && i != 0) {
faces.pop_back();
faces += "\nf ";
}
}
faces.pop_back();
if (faces.at(faces.size() - 1) == 'f') {
faces.pop_back();
}
else {
faces += TextFormat(" %i//%i", vertexCount + 1, vertexNormalsCount);
}
faces += "\n";
vertexCount += verticesVector->size();
delete verticesVector;
}
std::string randomNumber = std::to_string(GetRandomValue(0, INT_MAX));
std::string appdata = ".";// getenv("LOCALAPPDATA");
std::filesystem::create_directory(appdata + "\\ProjectMorault");
std::filesystem::create_directory(appdata + "\\ProjectMorault\\__udmfCache");
std::ofstream cacheModel(appdata + "\\ProjectMorault\\__udmfCache\\" + randomNumber + ".obj");
std::cout << "Outputting cache model to " << appdata + "\\ProjectMorault\\__udmfCache\\" + randomNumber + ".obj" << "\n";
cacheModel << vertices;
cacheModel << vertexNormals;
cacheModel << faces;
cacheModel.close();
std::string p = appdata + "\\ProjectMorault\\__udmfCache\\" + randomNumber + ".obj";
Model retval = LoadModel(p.c_str());
return retval;
}

View File

@ -0,0 +1,51 @@
#pragma once
#include <iostream>
#include <vector>
#include <raylib.h>
namespace Morault {
namespace UDMF { // DEPRECATED, DO NOT USE.
struct Linedef {
int v1, v2, sidefront = -1, sideback = -1;
bool blocking;
};
struct Sidedef {
int sector;
std::string texturetop = "";
std::string texturemiddle = "";
std::string texturebottom = "";
};
struct Vertex {
float x, y;
};
struct Sector {
std::string texturefloor;
std::string textureceiling;
int heightceiling = 128;
int heightfloor = 0;
};
class UDMFMap {
public:
std::string udmfNamespace;
std::vector<Linedef> linedefs;
std::vector<Sidedef> sidedefs;
std::vector<Vertex> vertexes;
std::vector<Sector> sectors;
void LoadMap(std::string textmap);
};
Model LoadModelUDMFWalls(UDMFMap map);
Model LoadModelUDMFFlats(UDMFMap map);
}
}

View File

@ -0,0 +1,123 @@
#include "Morault_Utils.h"
#include <Windows.h>
#include <gl/GL.h>
#include <gl/GLU.h>
bool Morault::Utils::Strings::IterativeComp(std::string originalString, int startPointer, std::string toCompare)
{
bool retVal = true;
for (int i = 0; i < toCompare.length(); i++) {
retVal = originalString.at(startPointer + i) == toCompare.at(i);
if (retVal == false) break;
}
return retVal;
}
std::string Morault::Utils::Strings::IterativeStringExcerpt(std::string originalString, int startPointer, int length)
{
std::string retval = "";
if (startPointer == -1) return retval;
for (int i = 0; i < length; i++) {
retval += originalString[startPointer + i];
}
return retval;
}
int32_t Morault::Utils::Strings::StringIndexToInteger_4b_le(std::string originalString, int startPointer)
{
int32_t retval;
retval = (unsigned char)originalString.at(startPointer + 3) << 24;
retval += (unsigned char)originalString.at(startPointer + 2) << 16;
retval += (unsigned char)originalString.at(startPointer + 1) << 8;
retval += (unsigned char)originalString.at(startPointer);
return retval;
}
int32_t Morault::Utils::Strings::StringIndexToInteger_2b_le(std::string originalString, int startPointer)
{
int32_t retval;
retval = (unsigned char)originalString.at(startPointer + 1) << 8;
retval += (unsigned char)originalString.at(startPointer);
return retval;
}
std::tuple<std::string, std::string> Morault::Utils::Strings::ParseCLineIntoKeyVal(std::string originalString)
{
std::tuple<std::string, std::string> retval;
int equPos = -1, valstartpos = -1, valendpos = -1;
bool inQuotes = false;
for (int i = 0; i < originalString.size(); i++) {
if (originalString[i] == '=' and equPos == -1) {
equPos = i;
valstartpos = i + 1;
}
if (originalString[i] == '"') {
if (inQuotes) {
valendpos = i - 1;
break;
}
if (valstartpos == -1) {
valstartpos = i + 1;
inQuotes = true;
}
}
if (originalString[i] == ';' and not inQuotes) {
valendpos = i - 1;
}
}
try {
retval = std::make_tuple<std::string, std::string>(IterativeStringExcerpt(originalString, 0, equPos), IterativeStringExcerpt(originalString, valstartpos, valendpos - valstartpos + 1));
}
catch(...){
retval = std::make_tuple<std::string, std::string>("", "");
}
return retval;
}
std::string Morault::Utils::Strings::SingleWordTrimmer(std::string originalString)
{
for (int i = 0; i < originalString.size(); i++) {
if (originalString[i] == ' ' or originalString[i] == '/') return IterativeStringExcerpt(originalString, 0, i);
}
return originalString;
}
std::basic_string<Morault::Utils::Geometry::Triangle2D> Morault::Utils::Geometry::TesselateVertexString(VertexString vs)
{
std::basic_string<Triangle2D> retval;
/*GLUtesselator* tess = gluNewTess();
gluTessBeginPolygon(tess, 0);
for (int i = 0; i < vs.size(); i++) {
GLdouble* coords;
coords[0] = static_cast<double>(vs[i].x);
coords[1] = 0;
coords[2] = static_cast<double>(vs[i].y);
gluTessVertex(tess, coords, coords);
}
gluTessEndPolygon(tess);
gluDeleteTess(tess);
*/
throw;
return retval;
}

View File

@ -0,0 +1,26 @@
#pragma once
#include <iostream>
namespace Morault {
namespace Utils {
namespace Geometry {
struct Vertex2D {
float x, y;
};
struct Triangle2D {
float a, b, c;
};
using VertexString = std::basic_string<Vertex2D>;
std::basic_string<Triangle2D> TesselateVertexString(VertexString vs);
}
namespace Strings {
bool IterativeComp(std::string originalString, int startPointer, std::string toCompare);
std::string IterativeStringExcerpt(std::string originalString, int startPointer, int length);
int32_t StringIndexToInteger_4b_le(std::string originalString, int startPointer);
int32_t StringIndexToInteger_2b_le(std::string originalString, int startPointer);
std::tuple<std::string, std::string> ParseCLineIntoKeyVal(std::string originalString);
std::string SingleWordTrimmer(std::string originalString);
}
}
}

View File

@ -0,0 +1,154 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{a20204cf-23c4-4386-a432-a135319786dc}</ProjectGuid>
<RootNamespace>ProjectMorault</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SOLUTIONDIR)deps/include</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SOLUTIONDIR)deps/lib</AdditionalLibraryDirectories>
<AdditionalDependencies>raylib.lib;winmm.lib;gdi32.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(SOLUTIONDIR)deps/include</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SOLUTIONDIR)deps/lib</AdditionalLibraryDirectories>
<AdditionalDependencies>raylib.lib;winmm.lib;gdi32.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
<ClCompile Include="Morault_Player.cpp" />
<ClCompile Include="Morault_Resources.cpp" />
<ClCompile Include="Morault_UDMF.cpp" />
<ClCompile Include="Morault_Utils.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Morault_Map.h" />
<ClInclude Include="Morault_Player.h" />
<ClInclude Include="Morault_Resources.h" />
<ClInclude Include="Morault_UDMF.h" />
<ClInclude Include="Morault_Utils.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Morault_Resources.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Morault_Player.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Morault_Utils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Morault_UDMF.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Morault_Resources.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Morault_Player.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Morault_Utils.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Morault_UDMF.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Morault_Map.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>

129
ProjectMorault/main.cpp Normal file
View File

@ -0,0 +1,129 @@
#include <iostream>
#include <raylib.h>
#include "Morault_Resources.h"
#include "Morault_Player.h"
#include "Morault_UDMF.h"
#include <raymath.h>
#include <rlgl.h>
#define MORAULT_MAP_RENDER_SCALE 0.1f
int main(int argc, char** argv) {
InitWindow(1280, 720, "ProjectMorault");
// SetTargetFPS(60);
SetExitKey(0);
// if (!std::get<bool>(Morault::Resources::Models(Morault::Resources::load("data/baseblock.glb")))) throw std::runtime_error("couldn't load baseblock");
DisableCursor();
Morault::Gameplay::Player player;
player.data.playerName = "TestPlayer0001";
player.data.hp = 100;
player.data.xp = 0;
bool gamePaused = false;
Vector2 offset = { 0,0 };
/*Morault::Resources::WAD wad("data/testmall.wad");
Morault::UDMF::UDMFMap map;
map.LoadMap(wad.getLumps()[1].data);
Model mapModel = Morault::UDMF::LoadModelUDMFWalls(map);
mapModel.materials[0].maps[MATERIAL_MAP_ALBEDO].texture = LoadTextureFromImage(Morault::Resources::GenTestImage());
// Model mapFlatModel = Morault::UDMF::LoadModelUDMFFlats(map);
*/
while (!WindowShouldClose()) {
player.controller.UpdatePlayerController(!gamePaused);
if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) {
offset = Vector2Add(offset, GetMouseDelta());
}
std::vector<Model> floorModels;
BeginDrawing();
ClearBackground(BLACK);
BeginMode3D(player.controller.camera);
DrawGrid(100, 10);
EndMode3D();
/*DrawModel(mapModel, {0,0,0}, MORAULT_MAP_RENDER_SCALE, WHITE);
for (int sc = 0; sc < map.sectors.size(); sc++) {
std::vector<Morault::UDMF::Vertex>* verticesVector = new std::vector<Morault::UDMF::Vertex>();
std::vector<Vector3> meshVector;
for (int sd = 0; sd < map.sidedefs.size(); sd++) {
if (map.sidedefs[sd].sector == sc) {
for (int ld = 0; ld < map.linedefs.size(); ld++) {
if (map.linedefs[ld].sidefront == sd) {
verticesVector->push_back(map.vertexes[map.linedefs[ld].v1]);
verticesVector->push_back(map.vertexes[map.linedefs[ld].v2]);
}
if (map.linedefs[ld].sideback == sd) { // you, in theory, shouldn't be able to have both the back and front of a linedef be the same.
verticesVector->push_back(map.vertexes[map.linedefs[ld].v1]);// invert vertices if sideback
verticesVector->push_back(map.vertexes[map.linedefs[ld].v2]);
}
}
}
}
for (int i = 0; i < verticesVector->size(); i++) {
meshVector.push_back({
(float)verticesVector->at(i).x * -1 * MORAULT_MAP_RENDER_SCALE,
(float)map.sectors[sc].heightfloor * MORAULT_MAP_RENDER_SCALE,
(float)verticesVector->at(i).y * MORAULT_MAP_RENDER_SCALE
});
}
DrawTriangleStrip3D(meshVector.data(), meshVector.size(), {((unsigned char)((float)255*(float)(sc/map.sectors.size()))), 255, 255, 255});
/*Mesh fMesh = {
.vertexCount = (int)verticesVector->size(),
.triangleCount = 1,
.vertices = (float*)MemAlloc(verticesVector->size() * 3 * sizeof(float)),
};
for (int i = 0; i < verticesVector->size(); i++) {
fMesh.vertices[i * 3 + 0] = verticesVector->at(i).x * MORAULT_MAP_RENDER_SCALE * -1;
fMesh.vertices[i * 3 + 1] = map.sectors[sc].heightfloor * MORAULT_MAP_RENDER_SCALE;
fMesh.vertices[i * 3 + 2] = verticesVector->at(i).y * MORAULT_MAP_RENDER_SCALE;
}
UploadMesh(&fMesh, false);
floorModels.push_back(LoadModelFromMesh(fMesh));
delete verticesVector;
}
/*for (int i = 0; i < floorModels.size(); i++) DrawModel(floorModels[i], { 0,0,0 }, 1, WHITE);
//DrawModel(std::get<Model>(Morault::Resources::Models(Morault::Resources::get("data/baseblock.glb"))), { 0,0,0 }, 1, WHITE);
/*DrawText(TextFormat("Camera offset: %i;%i", (int)offset.x, (int)offset.y), 0, 30, 20, WHITE);
DrawText(TextFormat("Mouse pos on map: %i;%i", (int)offset.x + GetMouseX(), (int)offset.y + GetMouseY()), 0, 50, 20, WHITE);
DrawText(TextFormat("Camera offset: %i;%i", (int)player.controller.camera.position.x, (int)player.controller.camera.position.z), 0, 30, 20, WHITE);
DrawText(TextFormat("Linedefs: %i", map.linedefs.size()), 0, 70, 20, WHITE);
DrawText(TextFormat("Sidedefs: %i", map.sidedefs.size()), 0, 90, 20, WHITE);
DrawText(TextFormat("Vertices: %i", map.vertexes.size()), 0, 110, 20, WHITE);
DrawText(TextFormat("Sectors: %i", map.sectors.size()), 0, 130, 20, WHITE);
*/
DrawFPS(0, 0);
EndDrawing();
/*for (int i = 0; i < floorModels.size(); i++) UnloadModel(floorModels[i]);
floorModels.clear();*/
if (IsKeyPressed(KEY_P)) {
int x, y;
std::cin >> x >> y;
player.controller.camera.position.x = x;
player.controller.camera.position.z = y;
}
}
CloseWindow();
}

27
readme.md Normal file
View File

@ -0,0 +1,27 @@
# Project Morault
## A source-available attempt at a humanist and persistent live-service game
Project Morault is a source-available attempt at a humanist and persistent live-service game.
## Goals
### Ideological
- Establish open standards for items, trading, markets, and user interaction
- Create healthier game environments and ranking systems overall
### Technical
- Create an engine that allows any device to run the game at competitive framerates
- Create a simpler map format inspired by UDMF to simplify rendering and collision maths to achieve better performance
## Why say source-available and not open-source?
Collaboration is more or less only open to other tilde.town users for the time being. Forking and modding outside of tilde.town, however, are both allowed and encouraged.
## Dependencies
- C++20
- raylib 5.5
## Building for Windows (VS2022)
Compiling on Windows with Visual Studio 2022 is relatively straight-forward. Simply clone the repository, then create a ``deps`` folder at the root of the repo. Inside your new folder, create an ``include`` folder and a ``lib`` folder. Then, follow the instructions for each dependency. Afterwards, simply open the ``ProjectMorault.sln`` solution using Visual Studio 2022 and run.
### raylib 5.5
First, download [raylib 5.5 built for x64 MSVC from GitHub](https://github.com/raysan5/raylib/releases/download/5.5/raylib-5.5_win64_msvc16.zip). Then, place the contents of the ``include`` folder of the archive within your ``deps/include`` folder. Then, place the contents of the ``lib`` folder of the archive within your ``deps/lib`` folder.