mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-04-02 10:42:14 -04:00
byuu says: This release features many substantial Game Boy emulation improvements (all courtesy of Jonas Quinn), a new audio DSP class, and BPS patching support. Changelog (since v081): - added new DSP audio engine; supports sample-averaging for the Game Boy's high frequency rate - GB: MMM01 images with boot loader at bottom of ROM can now be loaded - GB: EI is delayed one cycle; fixes Bubble Bobble [Jonas Quinn] - GB: fixed window -7 offset behavior; fixes Contra 3 first boss [Jonas Quinn] - GB: disable LCD interrupts when rendering is off; fixes Super Mario Land 2 [Jonas Quinn] - GB: fixed noise channel LFSR; fixes Zelda: LA lightning sound [Jonas Quinn] - GB: square channels use initial_length like the noise channel [Jonas Quinn] - UI: added BPS patching support; removed UPS patching support - UI: when loading BS-X/Sufami Turbo/Game Boy games; display game title instead of BIOS title - UI: modified timestamps on screenshots for Windows/NTFS (which disallows use of ':')
101 lines
3.3 KiB
C++
Executable file
101 lines
3.3 KiB
C++
Executable file
#ifndef NALL_BMP_HPP
|
|
#define NALL_BMP_HPP
|
|
|
|
#include <nall/file.hpp>
|
|
|
|
//BMP reader / writer
|
|
//author: byuu
|
|
//note: only 24-bit RGB and 32-bit ARGB uncompressed images supported
|
|
|
|
namespace nall {
|
|
|
|
struct bmp {
|
|
inline static bool read(const string &filename, uint32_t *&data, unsigned &width, unsigned &height);
|
|
inline static bool write(const string &filename, const uint32_t *data, unsigned width, unsigned height, unsigned pitch, bool alpha = false);
|
|
};
|
|
|
|
bool bmp::read(const string &filename, uint32_t *&data, unsigned &width, unsigned &height) {
|
|
file fp;
|
|
if(fp.open(filename, file::mode::read) == false) return false;
|
|
if(fp.size() < 0x36) return false;
|
|
|
|
if(fp.readm(2) != 0x424d) return false;
|
|
fp.seek(0x000a);
|
|
unsigned offset = fp.readl(4);
|
|
unsigned dibsize = fp.readl(4);
|
|
if(dibsize != 40) return false;
|
|
signed headerWidth = fp.readl(4);
|
|
if(headerWidth < 0) return false;
|
|
signed headerHeight = fp.readl(4);
|
|
fp.readl(2);
|
|
unsigned bitsPerPixel = fp.readl(2);
|
|
if(bitsPerPixel != 24 && bitsPerPixel != 32) return false;
|
|
unsigned compression = fp.readl(4);
|
|
if(compression != 0) return false;
|
|
fp.seek(offset);
|
|
|
|
bool noFlip = headerHeight < 0;
|
|
width = headerWidth, height = abs(headerHeight);
|
|
data = new uint32_t[width * height];
|
|
|
|
unsigned bytesPerPixel = bitsPerPixel / 8;
|
|
unsigned alignedWidth = width * bytesPerPixel;
|
|
unsigned paddingLength = 0;
|
|
while(alignedWidth % 4) alignedWidth++, paddingLength++;
|
|
|
|
for(unsigned y = 0; y < height; y++) {
|
|
uint32_t *p = noFlip ? data + y * width : data + (height - 1 - y) * width;
|
|
for(unsigned x = 0; x < width; x++, p++) {
|
|
*p = fp.readl(bytesPerPixel);
|
|
if(bytesPerPixel == 3) *p |= 255 << 24;
|
|
}
|
|
if(paddingLength) fp.readl(paddingLength);
|
|
}
|
|
|
|
fp.close();
|
|
return true;
|
|
}
|
|
|
|
bool bmp::write(const string &filename, const uint32_t *data, unsigned width, unsigned height, unsigned pitch, bool alpha) {
|
|
file fp;
|
|
if(fp.open(filename, file::mode::write) == false) return false;
|
|
|
|
unsigned bitsPerPixel = alpha ? 32 : 24;
|
|
unsigned bytesPerPixel = bitsPerPixel / 8;
|
|
unsigned alignedWidth = width * bytesPerPixel;
|
|
unsigned paddingLength = 0;
|
|
unsigned imageSize = alignedWidth * height;
|
|
unsigned fileSize = 0x36 + imageSize;
|
|
while(alignedWidth % 4) alignedWidth++, paddingLength++;
|
|
|
|
fp.writem(0x424d, 2); //signature
|
|
fp.writel(fileSize, 4); //file size
|
|
fp.writel(0, 2); //reserved
|
|
fp.writel(0, 2); //reserved
|
|
fp.writel(0x36, 4); //offset
|
|
|
|
fp.writel(40, 4); //DIB size
|
|
fp.writel(width, 4); //width
|
|
fp.writel(-height, 4); //height
|
|
fp.writel(1, 2); //color planes
|
|
fp.writel(bitsPerPixel, 2); //bits per pixel
|
|
fp.writel(0, 4); //compression method (BI_RGB)
|
|
fp.writel(imageSize, 4); //image data size
|
|
fp.writel(3780, 4); //horizontal resolution
|
|
fp.writel(3780, 4); //vertical resolution
|
|
fp.writel(0, 4); //palette size
|
|
fp.writel(0, 4); //important color count
|
|
|
|
for(unsigned y = 0; y < height; y++) {
|
|
const uint32_t *p = (const uint32_t*)((const uint8_t*)data + y * pitch);
|
|
for(unsigned x = 0; x < width; x++) fp.writel(*p++, bytesPerPixel);
|
|
if(paddingLength) fp.writel(0, paddingLength);
|
|
}
|
|
|
|
fp.close();
|
|
return true;
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|