/* Starshatter: The Open Source Project Copyright (c) 2021-2022, 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 "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 = 0; FILE* f = ::fopen(filename, "rb"); if (f) { ::fseek(f, 0, SEEK_END); int len = ftell(f); ::fseek(f, 0, SEEK_SET); if (null_terminate) { buf = new BYTE[len+1]; if (buf) buf[len] = 0; } else { buf = new BYTE[len]; } if (buf) ::fread(buf, len, 1, f); ::fclose(f); return len; } return 0; } int LoadTexture(const char* fname, Bitmap*& bitmap, int type) { int result = 0; if (!fname || !*fname) return result; bitmap = Bitmap::CheckCache(fname); if (!bitmap) { bool pcx_file = strstr(fname, ".pcx") || strstr(fname, ".PCX"); // handle PCX formats: if (pcx_file) { PcxImage pcx; if (pcx.Load((char*) fname) == PCX_OK) { bitmap = new Bitmap; // 32-bit image if (pcx.himap) { bitmap->CopyHighColorImage(pcx.width, pcx.height, pcx.himap); } // 8-bit image, check for 32-bit image as well else if (pcx.bitmap) { bitmap->CopyImage(pcx.width, pcx.height, pcx.bitmap); char tmp[256]; int len = strlen(fname); bool found = false; ZeroMemory(tmp, sizeof(tmp)); for (int i = 0; i < len && !found; i++) { if (strstr(fname + i, ".pcx") == (fname+i)) { found = true; } else { tmp[i] = fname[i]; } } if (found) { strcat_s(tmp, "+.pcx"); if (pcx.Load(tmp) == PCX_OK && pcx.himap != 0) { bitmap->CopyHighColorImage(pcx.width, pcx.height, pcx.himap); } } } } } // for all other formats, use D3DX: else { D3DXImage d3dx; if (d3dx.Load((char*) fname)) { 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 result; } 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; }