mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-08-18 13:31:18 +02:00
Update to v093r13 release.
byuu says: This WIP removes nall/input.hpp entirely, and implements the new universal cheat format for FC/SFC/GB/GBC/SGB. GBA is going to be tricky since there's some consternation around byte/word/dword overrides. It's also not immediately obvious to me how to implement the code search in logarithmic time, due to the optional compare value. Lastly, the cheat values inside cheats.bml seem to be broken for the SFC. Likely there's a bug somewhere in the conversion process. Obviously I'll have to fix that before v094. I received no feedback on the universal cheat format. If nobody adds anything before v094, then I don't want to hear any complaining about the formatting :P
This commit is contained in:
164
nall/image/core.hpp
Normal file
164
nall/image/core.hpp
Normal file
@@ -0,0 +1,164 @@
|
||||
#ifndef NALL_IMAGE_CORE_HPP
|
||||
#define NALL_IMAGE_CORE_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
bool image::operator==(const image& source) {
|
||||
if(width != source.width) return false;
|
||||
if(height != source.height) return false;
|
||||
if(pitch != source.pitch) return false;
|
||||
|
||||
if(endian != source.endian) return false;
|
||||
if(stride != source.stride) return false;
|
||||
|
||||
if(alpha != source.alpha) return false;
|
||||
if(red != source.red) return false;
|
||||
if(green != source.green) return false;
|
||||
if(blue != source.blue) return false;
|
||||
|
||||
return memcmp(data, source.data, width * height * stride) == 0;
|
||||
}
|
||||
|
||||
bool image::operator!=(const image& source) {
|
||||
return !operator==(source);
|
||||
}
|
||||
|
||||
image& image::operator=(const image& source) {
|
||||
free();
|
||||
|
||||
width = source.width;
|
||||
height = source.height;
|
||||
pitch = source.pitch;
|
||||
size = source.size;
|
||||
|
||||
endian = source.endian;
|
||||
stride = source.stride;
|
||||
|
||||
alpha = source.alpha;
|
||||
red = source.red;
|
||||
green = source.green;
|
||||
blue = source.blue;
|
||||
|
||||
data = allocate(width, height, stride);
|
||||
memcpy(data, source.data, source.size);
|
||||
return *this;
|
||||
}
|
||||
|
||||
image& image::operator=(image&& source) {
|
||||
free();
|
||||
|
||||
width = source.width;
|
||||
height = source.height;
|
||||
pitch = source.pitch;
|
||||
size = source.size;
|
||||
|
||||
endian = source.endian;
|
||||
stride = source.stride;
|
||||
|
||||
alpha = source.alpha;
|
||||
red = source.red;
|
||||
green = source.green;
|
||||
blue = source.blue;
|
||||
|
||||
data = source.data;
|
||||
source.data = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
image::image(const image& source) {
|
||||
operator=(source);
|
||||
}
|
||||
|
||||
image::image(image&& source) {
|
||||
operator=(std::forward<image>(source));
|
||||
}
|
||||
|
||||
image::image(bool endian, unsigned depth, uint64_t alphaMask, uint64_t redMask, uint64_t greenMask, uint64_t blueMask) {
|
||||
this->endian = endian;
|
||||
this->depth = depth;
|
||||
this->stride = (depth / 8) + ((depth & 7) > 0);
|
||||
|
||||
alpha = {alphaMask, bitDepth(alphaMask), bitShift(alphaMask)};
|
||||
red = {redMask, bitDepth(redMask), bitShift(redMask )};
|
||||
green = {greenMask, bitDepth(greenMask), bitShift(greenMask)};
|
||||
blue = {blueMask, bitDepth(blueMask), bitShift(blueMask )};
|
||||
}
|
||||
|
||||
image::image(const string& filename) {
|
||||
load(filename);
|
||||
}
|
||||
|
||||
image::image(const uint8_t* data, unsigned size) {
|
||||
loadPNG(data, size);
|
||||
}
|
||||
|
||||
image::image() {
|
||||
}
|
||||
|
||||
image::~image() {
|
||||
free();
|
||||
}
|
||||
|
||||
uint64_t image::read(const uint8_t* data) const {
|
||||
uint64_t result = 0;
|
||||
if(endian == 0) {
|
||||
for(signed n = stride - 1; n >= 0; n--) result = (result << 8) | data[n];
|
||||
} else {
|
||||
for(signed n = 0; n < stride; n++) result = (result << 8) | data[n];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void image::write(uint8_t* data, uint64_t value) const {
|
||||
if(endian == 0) {
|
||||
for(signed n = 0; n < stride; n++) {
|
||||
data[n] = value;
|
||||
value >>= 8;
|
||||
}
|
||||
} else {
|
||||
for(signed n = stride - 1; n >= 0; n--) {
|
||||
data[n] = value;
|
||||
value >>= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void image::free() {
|
||||
if(data) delete[] data;
|
||||
data = nullptr;
|
||||
}
|
||||
|
||||
bool image::empty() const {
|
||||
if(data == nullptr) return true;
|
||||
if(width == 0 || height == 0) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool image::load(const string& filename) {
|
||||
if(loadBMP(filename) == true) return true;
|
||||
if(loadPNG(filename) == true) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void image::allocate(unsigned width, unsigned height) {
|
||||
if(data != nullptr && this->width == width && this->height == height) return;
|
||||
free();
|
||||
data = allocate(width, height, stride);
|
||||
pitch = width * stride;
|
||||
size = height * pitch;
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
}
|
||||
|
||||
uint8_t* image::allocate(unsigned width, unsigned height, unsigned stride) {
|
||||
//allocate 1x1 larger than requested; so that linear interpolation does not require bounds-checking
|
||||
unsigned size = width * height * stride;
|
||||
unsigned padding = width * stride + stride;
|
||||
uint8_t* data = new uint8_t[size + padding];
|
||||
memset(data + size, 0x00, padding);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user