commit 248c5ca9873d7cd3df5495b40ae73c3c1e8f476d Author: Safariminer Date: Sun Apr 27 15:39:25 2025 -0400 Initial commit, can load titlepics diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d543370 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +deps +.vs +x86 +x64 +Debug +Release \ No newline at end of file diff --git a/RLDoom.sln b/RLDoom.sln new file mode 100644 index 0000000..311f4a7 --- /dev/null +++ b/RLDoom.sln @@ -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}") = "RLDoom", "RLDoom\RLDoom.vcxproj", "{54DCC6C0-95DC-4912-B671-111A85269507}" +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 + {54DCC6C0-95DC-4912-B671-111A85269507}.Debug|x64.ActiveCfg = Debug|x64 + {54DCC6C0-95DC-4912-B671-111A85269507}.Debug|x64.Build.0 = Debug|x64 + {54DCC6C0-95DC-4912-B671-111A85269507}.Debug|x86.ActiveCfg = Debug|Win32 + {54DCC6C0-95DC-4912-B671-111A85269507}.Debug|x86.Build.0 = Debug|Win32 + {54DCC6C0-95DC-4912-B671-111A85269507}.Release|x64.ActiveCfg = Release|x64 + {54DCC6C0-95DC-4912-B671-111A85269507}.Release|x64.Build.0 = Release|x64 + {54DCC6C0-95DC-4912-B671-111A85269507}.Release|x86.ActiveCfg = Release|Win32 + {54DCC6C0-95DC-4912-B671-111A85269507}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/RLDoom/RLDoom.vcxproj b/RLDoom/RLDoom.vcxproj new file mode 100644 index 0000000..171ccf7 --- /dev/null +++ b/RLDoom/RLDoom.vcxproj @@ -0,0 +1,152 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {54dcc6c0-95dc-4912-b671-111a85269507} + RLDoom + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + $(SOLUTIONDIR)deps/include + + + Console + true + $(SOLUTIONDIR)deps/lib + raylib.lib;winmm.lib;gdi32.lib;$(CoreLibraryDependencies);%(AdditionalDependencies) + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + $(SOLUTIONDIR)deps/include + + + Console + true + true + true + $(SOLUTIONDIR)deps/lib + raylib.lib;winmm.lib;gdi32.lib;$(CoreLibraryDependencies);%(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/RLDoom/RLDoom.vcxproj.filters b/RLDoom/RLDoom.vcxproj.filters new file mode 100644 index 0000000..0ec3d80 --- /dev/null +++ b/RLDoom/RLDoom.vcxproj.filters @@ -0,0 +1,51 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/RLDoom/RLDoom.vcxproj.user b/RLDoom/RLDoom.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/RLDoom/RLDoom.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/RLDoom/RLDoom_Color.cpp b/RLDoom/RLDoom_Color.cpp new file mode 100644 index 0000000..988d4e2 --- /dev/null +++ b/RLDoom/RLDoom_Color.cpp @@ -0,0 +1,36 @@ +#include "RLDoom_Color.h" +#include "RLDoom_Utils.h" + +RLDoom::Graphics::PlayPal RLDoom::Graphics::LoadPlayPal(std::string data) +{ + PlayPal retval; + for (int i = 0; i < data.size() / 768; i++) { + RLDoom::Graphics::Palette p; + std::string paletteData = RLDoom::Utils::Strings::IterativeStringExcerpt(data, i * 768, 768); + for (int j = 0; j < 256; j++) { + DoomColor color; + color.r = paletteData[j * 3]; + color.g = paletteData[j * 3 + 1]; + color.b = paletteData[j * 3 + 2]; + p.push_back(color); + } + retval.push_back(p); + } + return retval; +} + +RLDoom::Graphics::ColorMapFile RLDoom::Graphics::LoadColorMapFile(std::string data) +{ + ColorMapFile retval; + + for (int i = 0; i < data.size() / 256; i++) { + ColorMap colormap; + std::string colormapdata = RLDoom::Utils::Strings::IterativeStringExcerpt(data, i * 256, 256); + for (int j = 0; j < colormapdata.size(); j++) { + colormap.push_back((PaletteColor)colormapdata[j]); + } + retval.push_back(colormap); + } + + return retval; +} diff --git a/RLDoom/RLDoom_Color.h b/RLDoom/RLDoom_Color.h new file mode 100644 index 0000000..f786a3f --- /dev/null +++ b/RLDoom/RLDoom_Color.h @@ -0,0 +1,26 @@ +#pragma once +#include +#include +namespace RLDoom { + namespace Graphics { + struct DoomColor { + unsigned char r, g, b; + }; + + struct Color : public DoomColor{ + unsigned char a; + }; + + using Palette = std::vector; + + typedef uint8_t PaletteColor; + + using PlayPal = std::vector; + PlayPal LoadPlayPal(std::string data); + + using ColorMap = std::vector; + using ColorMapFile = std::vector; + ColorMapFile LoadColorMapFile(std::string data); + + } +} \ No newline at end of file diff --git a/RLDoom/RLDoom_Engine.h b/RLDoom/RLDoom_Engine.h new file mode 100644 index 0000000..7aa1ef0 --- /dev/null +++ b/RLDoom/RLDoom_Engine.h @@ -0,0 +1,14 @@ +#pragma once + +#include "RLDoom_Color.h" +#include "RLDoom_FileSystem.h" +#include "RLDoom_Patch.h" +#include "RLDoom_Utils.h" + +namespace RLDoom { + namespace System { + class Application { + + }; + } +} \ No newline at end of file diff --git a/RLDoom/RLDoom_FileSystem.cpp b/RLDoom/RLDoom_FileSystem.cpp new file mode 100644 index 0000000..a9f3124 --- /dev/null +++ b/RLDoom/RLDoom_FileSystem.cpp @@ -0,0 +1,77 @@ +#include "RLDoom_FileSystem.h" +#include "RLDoom_Utils.h" +#include +#include +#include + +RLDoom::FileSystem::WAD::WAD() +{ + std::cout << "Warning: Empty WAD instance created.\n"; +} + +RLDoom::FileSystem::WAD::WAD(std::string path) +{ + 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 (RLDoom::Utils::Strings::IterativeComp(filedata, 0, "IWAD")) { + wadType = IWAD; + std::cout << "File is an IWAD\n"; + } + else if (RLDoom::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 = RLDoom::Utils::Strings::StringIndexToInteger_4b_le(filedata, 4); + + std::cout << "File has " << lumpCount << " lumps\n"; + int directoryPointer = RLDoom::Utils::Strings::StringIndexToInteger_4b_le(filedata, 8); + + std::string directory = RLDoom::Utils::Strings::IterativeStringExcerpt(filedata, directoryPointer, 16 * lumpCount); + + for (int i = 0; i < lumpCount; i++) { + Lump lump; + std::string lumpIndex = RLDoom::Utils::Strings::IterativeStringExcerpt(directory, i * 16, 16); + int lumpPointer = RLDoom::Utils::Strings::StringIndexToInteger_4b_le(lumpIndex, 0); + int lumpSize = RLDoom::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 = RLDoom::Utils::Strings::IterativeStringExcerpt(filedata, lumpPointer, lumpSize); + + lumps.push_back(lump); + + std::cout << "(" << i << "/" << lumpCount << ")" << "Loaded lump \"" << lump.name << "\" of size " << lumpSize << "\n"; + } +} + +RLDoom::FileSystem::WAD::~WAD() +{ +} + +RLDoom::FileSystem::FileSystem::FileSystem() +{ +} + +RLDoom::FileSystem::WAD* RLDoom::FileSystem::FileSystem::getWAD(std::string wad) +{ + return wads[wad]; +} + +std::map RLDoom::FileSystem::FileSystem::getWADs() +{ + return wads; +} + +RLDoom::FileSystem::FileSystem::~FileSystem() +{ +} diff --git a/RLDoom/RLDoom_FileSystem.h b/RLDoom/RLDoom_FileSystem.h new file mode 100644 index 0000000..947cfe1 --- /dev/null +++ b/RLDoom/RLDoom_FileSystem.h @@ -0,0 +1,37 @@ +#pragma once +#include +#include +#include + +namespace RLDoom { + namespace FileSystem { + typedef enum { + INVALID, IWAD, PWAD + } WADType; + struct Lump { + std::string name, data; + }; + + class WAD { + std::vector lumps; + public: + WADType wadType; + int lumpCount; + WAD(); + WAD(std::string path); + std::vector getLumps() { + return lumps; + } + ~WAD(); + }; + + class FileSystem { + std::map wads; + public: + FileSystem(); + WAD* getWAD(std::string wad); + std::map getWADs(); + ~FileSystem(); + }; + } +} \ No newline at end of file diff --git a/RLDoom/RLDoom_Patch.cpp b/RLDoom/RLDoom_Patch.cpp new file mode 100644 index 0000000..7e2c6ee --- /dev/null +++ b/RLDoom/RLDoom_Patch.cpp @@ -0,0 +1,41 @@ +#include "RLDoom_Patch.h" +#include "RLDoom_Utils.h" + +RLDoom::Graphics::Patch RLDoom::Graphics::LoadPatch(std::string data) +{ + Patch retval; + retval.width = RLDoom::Utils::Strings::StringIndexToInteger_2b_le(data, 0); + retval.height = RLDoom::Utils::Strings::StringIndexToInteger_2b_le(data, 2); + retval.left = RLDoom::Utils::Strings::StringIndexToInteger_2b_le(data, 4); + retval.top = RLDoom::Utils::Strings::StringIndexToInteger_2b_le(data, 6); + retval.pixels.resize(retval.width * retval.height); + retval.columnsofs.resize(retval.width); + for (int i = 0; i < retval.columnsofs.size(); i++) { + retval.columnsofs[i] = RLDoom::Utils::Strings::StringIndexToInteger_4b_le(data, 8 + i * 4); + } + for (int i = 0; i < retval.columnsofs.size(); i++) { + uint8_t rowstart = 0; + + bool running = true; + + int offset = 0; + + while (running) { + rowstart = data[retval.columnsofs[i] + offset]; + if (rowstart == 255) { + running = false; + break; + } + uint8_t pixelCount = data[retval.columnsofs[i] + 1 + offset]; + uint8_t dummy1 = data[retval.columnsofs[i] + 2 + offset]; + for (int j = 0; j < pixelCount; j++) { + retval.pixels[(j + rowstart) * retval.width + i] = data[retval.columnsofs[i] + 3 + j + offset]; + std::cout << "Writing to " << (j + rowstart) << ":" << i << "\n"; + } + offset += 3 + pixelCount + 1; + + } + } + + return retval; +} diff --git a/RLDoom/RLDoom_Patch.h b/RLDoom/RLDoom_Patch.h new file mode 100644 index 0000000..3706065 --- /dev/null +++ b/RLDoom/RLDoom_Patch.h @@ -0,0 +1,20 @@ +#pragma once +#include +#include +#include "RLDoom_Color.h" + +namespace RLDoom { + namespace Graphics { + struct Post { + uint8_t topdelta; + uint8_t length; + std::basic_string data; + }; + struct Patch { + uint16_t width, height, left, top; + std::vector columnsofs; + std::vector pixels; + }; + Patch LoadPatch(std::string data); + } +} \ No newline at end of file diff --git a/RLDoom/RLDoom_Utils.cpp b/RLDoom/RLDoom_Utils.cpp new file mode 100644 index 0000000..fafc327 --- /dev/null +++ b/RLDoom/RLDoom_Utils.cpp @@ -0,0 +1,46 @@ +#include "RLDoom_Utils.h" + +bool RLDoom::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 RLDoom::Utils::Strings::IterativeStringExcerpt(std::string originalString, int startPointer, int length) +{ + std::string retval = ""; + + for (int i = 0; i < length; i++) { + retval += originalString[startPointer + i]; + } + + return retval; +} + +int32_t RLDoom::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 RLDoom::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; +} diff --git a/RLDoom/RLDoom_Utils.h b/RLDoom/RLDoom_Utils.h new file mode 100644 index 0000000..7cce772 --- /dev/null +++ b/RLDoom/RLDoom_Utils.h @@ -0,0 +1,13 @@ +#pragma once +#include + +namespace RLDoom { + namespace Utils { + 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); + } + } +} \ No newline at end of file diff --git a/RLDoom/main.cpp b/RLDoom/main.cpp new file mode 100644 index 0000000..31604e6 --- /dev/null +++ b/RLDoom/main.cpp @@ -0,0 +1,63 @@ +#include "RLDoom_FileSystem.h" +#include "RLDoom_Patch.h" +#include "RLDoom_Color.h" + +#include + +int main() { + InitWindow(640, 400, "RLDoom"); + SetTargetFPS(60); + SetExitKey(0); + + + RLDoom::FileSystem::WAD wad; + RLDoom::Graphics::ColorMapFile colormap; + RLDoom::Graphics::PlayPal playpal; + RLDoom::Graphics::Patch titlepic; + Image titlepicImage = GenImageColor(320, 200, BLANK); + Texture2D titlepicTexture = LoadTextureFromImage(titlepicImage); + + while (!WindowShouldClose()) { + BeginDrawing(); + ClearBackground(BLACK); + DrawText("Drop an IWAD here to see its TITLEPIC.\nOnce an IWAD is loaded, you can drop PWADs.", 0, 0, 10, WHITE); + if (IsFileDropped()) { + FilePathList droppedFiles = LoadDroppedFiles(); + for (int i = 0; i < droppedFiles.count; i++) { + wad = RLDoom::FileSystem::WAD(droppedFiles.paths[i]); + for (int j = 0; j < wad.lumpCount; j++) { + if (wad.getLumps()[j].name == "COLORMAP") { + colormap = RLDoom::Graphics::LoadColorMapFile(wad.getLumps()[j].data); + } + if (wad.getLumps()[j].name == "PLAYPAL") { + playpal = RLDoom::Graphics::LoadPlayPal(wad.getLumps()[j].data); + } + if (wad.getLumps()[j].name == "TITLEPIC") { + titlepic = RLDoom::Graphics::LoadPatch(wad.getLumps()[j].data); + for (int y = 0; y < titlepic.height; y++) { + for (int x = 0; x < titlepic.width; x++) { + ImageDrawPixel(&titlepicImage, x, y, { + playpal[0][colormap[0][titlepic.pixels[y * titlepic.width + x]]].r, + playpal[0][colormap[0][titlepic.pixels[y * titlepic.width + x]]].g, + playpal[0][colormap[0][titlepic.pixels[y * titlepic.width + x]]].b, + 255 + }); + } + } + UnloadTexture(titlepicTexture); + titlepicTexture = LoadTextureFromImage(titlepicImage); + } + } + } + UnloadDroppedFiles(droppedFiles); + } + DrawTextureEx(titlepicTexture, { 0,0 }, 0, 2, WHITE); + EndDrawing(); + } + + + + + UnloadTexture(titlepicTexture); + CloseWindow(); +} \ No newline at end of file