mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-08-31 09:32:23 +02:00
Update to v094r38 release.
byuu says: I'll post more detailed changes later, but basically: - fixed Baldur's Gate bug - guess if no flash ROM ID present (fixes Magical Vacation, many many others) - nall cleanups - sfc/cartridge major cleanups - bsxcartridge/"bsx" renamed to mcc/"mcc" after the logic chip it uses (consistency with SGB/ICD2) - ... and more!
This commit is contained in:
49
nall/decode/base64.hpp
Normal file
49
nall/decode/base64.hpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#ifndef NALL_DECODE_BASE64_HPP
|
||||
#define NALL_DECODE_BASE64_HPP
|
||||
|
||||
namespace nall { namespace Decode {
|
||||
|
||||
inline auto Base64(const string& text) -> vector<uint8_t> {
|
||||
auto value = [](char n) -> uint8_t {
|
||||
if(n >= 'A' && n <= 'Z') return n - 'A' + 0;
|
||||
if(n >= 'a' && n <= 'z') return n - 'a' + 26;
|
||||
if(n >= '0' && n <= '9') return n - '0' + 52;
|
||||
if(n == '+' || n == '-') return 62;
|
||||
if(n == '/' || n == '_') return 63;
|
||||
return 64; //error code
|
||||
};
|
||||
|
||||
vector<uint8_t> result;
|
||||
|
||||
uint8_t buffer, output;
|
||||
for(unsigned i = 0; i < text.size(); i++) {
|
||||
uint8_t buffer = value(text[i]);
|
||||
if(buffer > 63) break;
|
||||
|
||||
switch(i & 3) {
|
||||
case 0:
|
||||
output = buffer << 2;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
result.append(output | buffer >> 4);
|
||||
output = (buffer & 15) << 4;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
result.append(output | buffer >> 2);
|
||||
output = (buffer & 3) << 6;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
result.append(output | buffer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
@@ -1,8 +1,79 @@
|
||||
#ifndef NALL_DECODE_BMP_HPP
|
||||
#define NALL_DECODE_BMP_HPP
|
||||
|
||||
namespace nall {
|
||||
namespace nall { namespace Decode {
|
||||
|
||||
}
|
||||
struct BMP {
|
||||
BMP() = default;
|
||||
BMP(const string& filename) { load(filename); }
|
||||
BMP(const uint8_t* data, unsigned size) { load(data, size); }
|
||||
|
||||
explicit operator bool() const { return _data; }
|
||||
|
||||
auto reset() -> void {
|
||||
if(_data) { delete[] _data; _data = nullptr; }
|
||||
}
|
||||
|
||||
auto data() -> uint32_t* { return _data; }
|
||||
auto data() const -> const uint32_t* { return _data; }
|
||||
auto width() const -> unsigned { return _width; }
|
||||
auto height() const -> unsigned { return _height; }
|
||||
|
||||
auto load(const string& filename) -> bool {
|
||||
auto buffer = file::read(filename);
|
||||
return load(buffer.data(), buffer.size());
|
||||
}
|
||||
|
||||
auto load(const uint8_t* data, unsigned size) -> bool {
|
||||
if(size < 0x36) return false;
|
||||
const uint8_t* p = data;
|
||||
if(read(p, 2) != 0x4d42) return false; //signature
|
||||
read(p, 8);
|
||||
unsigned offset = read(p, 4);
|
||||
if(read(p, 4) != 40) return false; //DIB size
|
||||
signed width = read(p, 4);
|
||||
if(width < 0) return false;
|
||||
signed height = read(p, 4);
|
||||
bool flip = height < 0;
|
||||
if(flip) height = -height;
|
||||
read(p, 2);
|
||||
unsigned bitsPerPixel = read(p, 2);
|
||||
if(bitsPerPixel != 24 && bitsPerPixel != 32) return false;
|
||||
if(read(p, 4) != 0) return false; //compression type
|
||||
|
||||
_width = width;
|
||||
_height = height;
|
||||
_data = new uint32_t[width * height];
|
||||
|
||||
unsigned bytesPerPixel = bitsPerPixel / 8;
|
||||
unsigned alignedWidth = width * bytesPerPixel;
|
||||
unsigned paddingLength = 0;
|
||||
while(alignedWidth % 4) alignedWidth++, paddingLength++;
|
||||
|
||||
p = data + offset;
|
||||
for(auto y : range(height)) {
|
||||
uint32_t* output = flip ? _data + (height - 1 - y) * width : _data + y * width;
|
||||
for(auto x : range(width)) {
|
||||
*output++ = read(p, bytesPerPixel) | (bitsPerPixel == 24 ? 255u << 24 : 0);
|
||||
}
|
||||
if(paddingLength) read(p, paddingLength);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t* _data = nullptr;
|
||||
unsigned _width = 0;
|
||||
unsigned _height = 0;
|
||||
|
||||
auto read(const uint8_t*& buffer, unsigned length) -> uintmax_t {
|
||||
uintmax_t result = 0;
|
||||
for(auto n : range(length)) result |= (uintmax_t)*buffer++ << (n << 3);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
@@ -31,8 +31,8 @@ struct PNG {
|
||||
uint8_t* data = nullptr;
|
||||
unsigned size = 0;
|
||||
|
||||
inline bool decode(const string& filename);
|
||||
inline bool decode(const uint8_t* sourceData, unsigned sourceSize);
|
||||
inline bool load(const string& filename);
|
||||
inline bool load(const uint8_t* sourceData, unsigned sourceSize);
|
||||
inline unsigned readbits(const uint8_t*& data);
|
||||
unsigned bitpos = 0;
|
||||
|
||||
@@ -54,14 +54,14 @@ protected:
|
||||
inline unsigned read(const uint8_t* data, unsigned length);
|
||||
};
|
||||
|
||||
bool PNG::decode(const string& filename) {
|
||||
bool PNG::load(const string& filename) {
|
||||
if(auto memory = file::read(filename)) {
|
||||
return decode(memory.data(), memory.size());
|
||||
return load(memory.data(), memory.size());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PNG::decode(const uint8_t* sourceData, unsigned sourceSize) {
|
||||
bool PNG::load(const uint8_t* sourceData, unsigned sourceSize) {
|
||||
if(sourceSize < 8) return false;
|
||||
if(read(sourceData + 0, 4) != 0x89504e47) return false;
|
||||
if(read(sourceData + 4, 4) != 0x0d0a1a0a) return false;
|
||||
|
Reference in New Issue
Block a user