2014-01-13 09:35:46 +00:00
|
|
|
#ifndef NALL_IMAGE_BASE_HPP
|
|
|
|
#define NALL_IMAGE_BASE_HPP
|
|
|
|
|
|
|
|
namespace nall {
|
|
|
|
|
|
|
|
struct image {
|
2015-06-18 10:48:53 +00:00
|
|
|
enum class blend : unsigned {
|
|
|
|
add,
|
|
|
|
sourceAlpha, //color = sourceColor * sourceAlpha + targetColor * (1 - sourceAlpha)
|
|
|
|
sourceColor, //color = sourceColor
|
|
|
|
targetAlpha, //color = targetColor * targetAlpha + sourceColor * (1 - targetAlpha)
|
|
|
|
targetColor, //color = targetColor
|
|
|
|
};
|
2014-01-13 09:35:46 +00:00
|
|
|
|
|
|
|
struct channel {
|
2015-06-18 10:48:53 +00:00
|
|
|
channel(uint64_t mask, unsigned depth, unsigned shift) : _mask(mask), _depth(depth), _shift(shift) {
|
|
|
|
}
|
2014-01-13 09:35:46 +00:00
|
|
|
|
2015-06-18 10:48:53 +00:00
|
|
|
auto operator==(const channel& source) const -> bool {
|
|
|
|
return _mask == source._mask && _depth == source._depth && _shift == source._shift;
|
2014-01-13 09:35:46 +00:00
|
|
|
}
|
|
|
|
|
2015-06-18 10:48:53 +00:00
|
|
|
auto operator!=(const channel& source) const -> bool {
|
2014-01-13 09:35:46 +00:00
|
|
|
return !operator==(source);
|
|
|
|
}
|
|
|
|
|
2015-06-18 10:48:53 +00:00
|
|
|
alwaysinline auto mask() const { return _mask; }
|
|
|
|
alwaysinline auto depth() const { return _depth; }
|
|
|
|
alwaysinline auto shift() const { return _shift; }
|
2014-01-13 09:35:46 +00:00
|
|
|
|
2015-06-18 10:48:53 +00:00
|
|
|
private:
|
|
|
|
uint64_t _mask;
|
|
|
|
unsigned _depth;
|
|
|
|
unsigned _shift;
|
2014-01-13 09:35:46 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
//core.hpp
|
|
|
|
inline image(const image& source);
|
|
|
|
inline image(image&& source);
|
|
|
|
inline image(bool endian, unsigned depth, uint64_t alphaMask, uint64_t redMask, uint64_t greenMask, uint64_t blueMask);
|
|
|
|
inline image(const string& filename);
|
Update to v094r09 release.
byuu says:
This will easily be the biggest diff in the history of higan. And not in
a good way.
* target-higan and target-loki have been blown away completely
* nall and ruby massively updated
* phoenix replaced with hiro (pretty near a total rewrite)
* target-higan restarted using hiro (just a window for now)
* all emulation cores updated to compile again
* installation changed to not require root privileges (installs locally)
For the foreseeable future (maybe even permanently?), the new higan UI
will only build under Linux/BSD with GTK+ 2.20+. Probably the most
likely route for Windows/OS X will be to try and figure out how to build
hiro/GTK on those platforms, as awful as that would be. The other
alternative would be to produce new UIs for those platforms ... which
would actually be a good opportunity to make something much more user
friendly.
Being that I just started on this a few hours ago, that means that for
at least a few weeks, don't expect to be able to actually play any
games. Right now, you can pretty much just compile the binary and that's
it. It's quite possible that some nall changes didn't produce
compilation errors, but will produce runtime errors. So until the UI can
actually load games, we won't know if anything is broken. But we should
mostly be okay. It was mostly just trim<1> -> trim changes, moving to
Hash::SHA256 (much cleaner), and patching some reckless memory copy
functions enough to compile.
Progress isn't going to be like it was before: I'm now dividing my time
much thinner between studying and other hobbies.
My aim this time is not to produce a binary for everyone to play games
on. Rather, it's to keep the emulator alive. I want to be able to apply
critical patches again. And I would also like the base of the emulator
to live on, for use in other emulator frontends that utilize higan.
2015-02-26 10:10:46 +00:00
|
|
|
inline image(const vector<uint8_t>& buffer);
|
2014-01-13 09:35:46 +00:00
|
|
|
inline image(const uint8_t* data, unsigned size);
|
|
|
|
inline image();
|
|
|
|
inline ~image();
|
|
|
|
|
2015-06-18 10:48:53 +00:00
|
|
|
inline auto operator=(const image& source) -> image&;
|
|
|
|
inline auto operator=(image&& source) -> image&;
|
|
|
|
|
|
|
|
inline explicit operator bool() const;
|
|
|
|
inline auto operator==(const image& source) const -> bool;
|
|
|
|
inline auto operator!=(const image& source) const -> bool;
|
|
|
|
|
|
|
|
inline auto read(const uint8_t* data) const -> uint64_t;
|
|
|
|
inline auto write(uint8_t* data, uint64_t value) const -> void;
|
2014-01-13 09:35:46 +00:00
|
|
|
|
2015-06-18 10:48:53 +00:00
|
|
|
inline auto free() -> void;
|
|
|
|
inline auto empty() const -> bool;
|
|
|
|
inline auto load(const string& filename) -> bool;
|
|
|
|
inline auto allocate(unsigned width, unsigned height) -> void;
|
2014-01-13 09:35:46 +00:00
|
|
|
|
|
|
|
//fill.hpp
|
2015-06-18 10:48:53 +00:00
|
|
|
inline auto fill(uint64_t color = 0) -> void;
|
|
|
|
inline auto gradient(uint64_t a, uint64_t b, uint64_t c, uint64_t d) -> void;
|
|
|
|
inline auto gradient(uint64_t a, uint64_t b, signed radiusX, signed radiusY, signed centerX, signed centerY, function<double (double, double)> callback) -> void;
|
|
|
|
inline auto crossGradient(uint64_t a, uint64_t b, signed radiusX, signed radiusY, signed centerX, signed centerY) -> void;
|
|
|
|
inline auto diamondGradient(uint64_t a, uint64_t b, signed radiusX, signed radiusY, signed centerX, signed centerY) -> void;
|
|
|
|
inline auto horizontalGradient(uint64_t a, uint64_t b, signed radiusX, signed radiusY, signed centerX, signed centerY) -> void;
|
|
|
|
inline auto radialGradient(uint64_t a, uint64_t b, signed radiusX, signed radiusY, signed centerX, signed centerY) -> void;
|
|
|
|
inline auto sphericalGradient(uint64_t a, uint64_t b, signed radiusX, signed radiusY, signed centerX, signed centerY) -> void;
|
|
|
|
inline auto squareGradient(uint64_t a, uint64_t b, signed radiusX, signed radiusY, signed centerX, signed centerY) -> void;
|
|
|
|
inline auto verticalGradient(uint64_t a, uint64_t b, signed radiusX, signed radiusY, signed centerX, signed centerY) -> void;
|
2014-01-13 09:35:46 +00:00
|
|
|
|
|
|
|
//scale.hpp
|
2015-06-18 10:48:53 +00:00
|
|
|
inline auto scale(unsigned width, unsigned height, bool linear = true) -> void;
|
2014-01-13 09:35:46 +00:00
|
|
|
|
|
|
|
//blend.hpp
|
2015-06-18 10:48:53 +00:00
|
|
|
inline auto impose(blend mode, unsigned targetX, unsigned targetY, image source, unsigned x, unsigned y, unsigned width, unsigned height) -> void;
|
2014-01-13 09:35:46 +00:00
|
|
|
|
|
|
|
//utility.hpp
|
2015-06-18 10:48:53 +00:00
|
|
|
inline auto crop(unsigned x, unsigned y, unsigned width, unsigned height) -> bool;
|
|
|
|
inline auto alphaBlend(uint64_t alphaColor) -> void;
|
Update to v094r43 release.
byuu says:
Updated to compile with all of the new hiro changes. My next step is to
write up hiro API documentation, and move the API from alpha (constantly
changing) to beta (rarely changing), in preparation for the first stable
release (backward-compatible changes only.)
Added "--fullscreen" command-line option. I like this over
a configuration file option. Lets you use the emulator in both modes
without having to modify the config file each time.
Also enhanced the command-line game loading. You can now use any of
these methods:
higan /path/to/game-folder.sfc
higan /path/to/game-folder.sfc/
higan /path/to/game-folder.sfc/program.rom
The idea is to support launchers that insist on loading files only.
Technically, the file can be any name (manifest.bml also works); the
only criteria is that the file actually exists and is a file, and not
a directory. This is a requirement to support the first version (a
directory lacking the trailing / identifier), because I don't want my
nall::string class to query the file system to determine if the string
is an actual existing file or directory for its pathname() / dirname()
functions.
Anyway, every game folder I've made so far has program.rom, and that's
very unlikely to change, so this should be fine.
Now, of course, if you drop a regular "game.sfc" file on the emulator,
it won't even try to load it, unless it's in a folder that ends in .fc,
.sfc, etc. In which case, it'll bail out immediately by being unable to
produce a manifest for what is obviously not really a game folder.
2015-08-30 02:08:26 +00:00
|
|
|
inline auto alphaMultiply() -> void;
|
2015-06-18 10:48:53 +00:00
|
|
|
inline auto transform(const image& source = {}) -> void;
|
|
|
|
inline auto transform(bool endian, unsigned depth, uint64_t alphaMask, uint64_t redMask, uint64_t greenMask, uint64_t blueMask) -> void;
|
|
|
|
|
|
|
|
//static.hpp
|
|
|
|
static inline auto bitDepth(uint64_t color) -> unsigned;
|
|
|
|
static inline auto bitShift(uint64_t color) -> unsigned;
|
|
|
|
static inline auto normalize(uint64_t color, unsigned sourceDepth, unsigned targetDepth) -> uint64_t;
|
|
|
|
|
|
|
|
//access
|
|
|
|
alwaysinline auto data() { return _data; }
|
|
|
|
alwaysinline auto data() const { return _data; }
|
|
|
|
alwaysinline auto width() const { return _width; }
|
|
|
|
alwaysinline auto height() const { return _height; }
|
|
|
|
|
|
|
|
alwaysinline auto endian() const { return _endian; }
|
|
|
|
alwaysinline auto depth() const { return _depth; }
|
|
|
|
alwaysinline auto stride() const { return (_depth + 7) >> 3; }
|
|
|
|
|
|
|
|
alwaysinline auto pitch() const { return _width * stride(); }
|
|
|
|
alwaysinline auto size() const { return _height * pitch(); }
|
|
|
|
|
|
|
|
alwaysinline auto alpha() const { return _alpha; }
|
|
|
|
alwaysinline auto red() const { return _red; }
|
|
|
|
alwaysinline auto green() const { return _green; }
|
|
|
|
alwaysinline auto blue() const { return _blue; }
|
2014-01-13 09:35:46 +00:00
|
|
|
|
2015-06-18 10:48:53 +00:00
|
|
|
private:
|
2014-01-13 09:35:46 +00:00
|
|
|
//core.hpp
|
2015-06-18 10:48:53 +00:00
|
|
|
inline auto allocate(unsigned width, unsigned height, unsigned stride) -> uint8_t*;
|
2014-01-13 09:35:46 +00:00
|
|
|
|
|
|
|
//scale.hpp
|
2015-06-18 10:48:53 +00:00
|
|
|
inline auto scaleLinearWidth(unsigned width) -> void;
|
|
|
|
inline auto scaleLinearHeight(unsigned height) -> void;
|
|
|
|
inline auto scaleLinear(unsigned width, unsigned height) -> void;
|
|
|
|
inline auto scaleNearest(unsigned width, unsigned height) -> void;
|
2014-01-13 09:35:46 +00:00
|
|
|
|
|
|
|
//load.hpp
|
2015-06-18 10:48:53 +00:00
|
|
|
inline auto loadBMP(const string& filename) -> bool;
|
2015-08-02 06:23:13 +00:00
|
|
|
inline auto loadBMP(const uint8_t* data, unsigned size) -> bool;
|
2015-06-18 10:48:53 +00:00
|
|
|
inline auto loadPNG(const string& filename) -> bool;
|
|
|
|
inline auto loadPNG(const uint8_t* data, unsigned size) -> bool;
|
2014-01-13 09:35:46 +00:00
|
|
|
|
|
|
|
//interpolation.hpp
|
2015-06-18 10:48:53 +00:00
|
|
|
alwaysinline auto isplit(uint64_t* component, uint64_t color) -> void;
|
|
|
|
alwaysinline auto imerge(const uint64_t* component) -> uint64_t;
|
|
|
|
alwaysinline auto interpolate1f(uint64_t a, uint64_t b, double x) -> uint64_t;
|
|
|
|
alwaysinline auto interpolate1f(uint64_t a, uint64_t b, uint64_t c, uint64_t d, double x, double y) -> uint64_t;
|
|
|
|
alwaysinline auto interpolate1i(int64_t a, int64_t b, uint32_t x) -> uint64_t;
|
|
|
|
alwaysinline auto interpolate1i(int64_t a, int64_t b, int64_t c, int64_t d, uint32_t x, uint32_t y) -> uint64_t;
|
|
|
|
inline auto interpolate4f(uint64_t a, uint64_t b, double x) -> uint64_t;
|
|
|
|
inline auto interpolate4f(uint64_t a, uint64_t b, uint64_t c, uint64_t d, double x, double y) -> uint64_t;
|
|
|
|
inline auto interpolate4i(uint64_t a, uint64_t b, uint32_t x) -> uint64_t;
|
|
|
|
inline auto interpolate4i(uint64_t a, uint64_t b, uint64_t c, uint64_t d, uint32_t x, uint32_t y) -> uint64_t;
|
|
|
|
|
|
|
|
uint8_t* _data = nullptr;
|
|
|
|
unsigned _width = 0;
|
|
|
|
unsigned _height = 0;
|
|
|
|
|
|
|
|
bool _endian = 0; //0 = lsb, 1 = msb
|
|
|
|
unsigned _depth = 32;
|
|
|
|
|
|
|
|
channel _alpha{255u << 24, 8, 24};
|
|
|
|
channel _red {255u << 16, 8, 16};
|
|
|
|
channel _green{255u << 8, 8, 8};
|
|
|
|
channel _blue {255u << 0, 8, 0};
|
2014-01-13 09:35:46 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|