summaryrefslogtreecommitdiffhomepage
path: root/MagicEx/src/MagicLoad.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'MagicEx/src/MagicLoad.cpp')
-rw-r--r--MagicEx/src/MagicLoad.cpp159
1 files changed, 159 insertions, 0 deletions
diff --git a/MagicEx/src/MagicLoad.cpp b/MagicEx/src/MagicLoad.cpp
new file mode 100644
index 0000000..f398ab3
--- /dev/null
+++ b/MagicEx/src/MagicLoad.cpp
@@ -0,0 +1,159 @@
+/* Starshatter: The Open Source Project
+ Copyright (c) 2021-2024, Starshatter: The Open Source Project Contributors
+ Copyright (c) 2011-2012, Starshatter OpenSource Distribution Contributors
+ Copyright (c) 1997-2006, Destroyer Studios LLC.
+
+ AUTHOR: John DiCamillo
+*/
+
+#include <windows.h>
+
+#include <cstring>
+#include <fstream>
+#include <ios>
+#include <iostream>
+#include <limits>
+#include <vector>
+
+#include <MagicLoad.h>
+
+#include <Bitmap.h>
+#include <Color.h>
+#include <D3DXImage.h>
+#include <Geometry.h>
+#include <Pcx.h>
+
+
+int
+LoadBuffer(const char* filename, BYTE*& buf, bool null_terminate)
+{
+ buf = nullptr;
+ std::fstream file {filename, file.binary | file.in};
+ if (!file.is_open())
+ return 0;
+ file.ignore(std::numeric_limits<std::streamsize>::max());
+ const auto size = file.gcount();
+ file.clear();
+ file.seekg(0);
+ if (null_terminate) {
+ buf = new BYTE[size + 1];
+ if (buf)
+ buf[size] = 0;
+ }
+ else {
+ buf = new BYTE[size];
+ }
+ if (buf) {
+ file.read(reinterpret_cast<char*>(buf), size);
+ return file.gcount();
+ }
+ return 0;
+}
+
+
+int
+LoadTexture(const char* fname, Bitmap*& bitmap, int type)
+{
+ if (fname == nullptr || fname[0] == 0)
+ return 0;
+ bitmap = Bitmap::CheckCache(fname);
+ if (bitmap)
+ return 0; // legacy behaviour
+ const bool is_pcx = std::strstr(fname, ".pcx") || std::strstr(fname, ".PCX");
+ if (is_pcx) {
+ PcxImage pcx;
+ if (pcx.Load((char*) fname) != PCX_OK) // Casting away const!
+ return 0;
+ bitmap = new Bitmap;
+ if (bitmap == nullptr)
+ return 0;
+ if (pcx.himap) {
+ bitmap->CopyHighColorImage(pcx.width, pcx.height, pcx.himap);
+ }
+ else if (pcx.bitmap) {
+ bitmap->CopyImage(pcx.width, pcx.height, pcx.bitmap);
+ std::vector<char> buf(std::strlen(fname) + 2);
+ std::strcpy(buf.data(), fname);
+ if (auto* ext = std::strstr(buf.data(), ".pcx"))
+ *ext = 0;
+ std::strcat(buf.data(), "+.pcx");
+ if (pcx.Load(buf.data()) == PCX_OK && pcx.himap != 0)
+ bitmap->CopyHighColorImage(pcx.width, pcx.height, pcx.himap);
+ }
+ else {
+ // legacy no-op
+ }
+ }
+ else {
+ D3DXImage d3dx;
+ bitmap = new Bitmap;
+ if (d3dx.Load((char*) fname)) {
+ std::cout << "d3dx done" << std::endl;
+ bitmap = new Bitmap;
+ bitmap->CopyHighColorImage(d3dx.width, d3dx.height, d3dx.image);
+ }
+ }
+ if (bitmap) {
+ LoadAlpha(fname, *bitmap, type);
+ bitmap->SetFilename(fname);
+ bitmap->SetType(type);
+ bitmap->MakeTexture();
+ Bitmap::AddToCache(bitmap);
+ }
+ return 0;
+}
+
+
+int
+LoadAlpha(const char* name, Bitmap& bitmap, int type)
+{
+ PcxImage pcx;
+ D3DXImage d3dx;
+ bool pcx_file = strstr(name, ".pcx") || strstr(name, ".PCX");
+ bool bmp_file = strstr(name, ".bmp") || strstr(name, ".BMP");
+ bool jpg_file = strstr(name, ".jpg") || strstr(name, ".JPG");
+ bool png_file = strstr(name, ".png") || strstr(name, ".PNG");
+ bool tga_file = strstr(name, ".tga") || strstr(name, ".TGA");
+
+ // check for an associated alpha-only (grayscale) bitmap:
+ char filename[256];
+ strcpy_s(filename, name);
+
+ char* dot = strrchr(filename, '.');
+ if (dot && pcx_file)
+ strcpy(dot, "@.pcx");
+ else if (dot && bmp_file)
+ strcpy(dot, "@.bmp");
+ else if (dot && jpg_file)
+ strcpy(dot, "@.jpg");
+ else if (dot && png_file)
+ strcpy(dot, "@.png");
+ else if (dot && tga_file)
+ strcpy(dot, "@.tga");
+ else
+ return 0;
+
+ // first try to load from current directory:
+ bool loaded = false;
+
+ if (pcx_file)
+ loaded = pcx.Load(filename) == PCX_OK;
+
+ else
+ loaded = d3dx.Load(filename);
+
+ // now copy the alpha values into the bitmap:
+ if (loaded) {
+ if (pcx_file && pcx.bitmap) {
+ bitmap.CopyAlphaImage(pcx.width, pcx.height, pcx.bitmap);
+ }
+ else if (pcx_file && pcx.himap) {
+ bitmap.CopyAlphaRedChannel(pcx.width, pcx.height, pcx.himap);
+ }
+ else if (d3dx.image) {
+ bitmap.CopyAlphaRedChannel(d3dx.width, d3dx.height, d3dx.image);
+ }
+ }
+
+ return 0;
+}