diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index fa5073cf..8d1b028f 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -12,7 +12,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "104"; + static const string Version = "104.01"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "http://byuu.org/"; diff --git a/higan/ms/vdp/background.cpp b/higan/ms/vdp/background.cpp index edbb9b6f..48c53863 100644 --- a/higan/ms/vdp/background.cpp +++ b/higan/ms/vdp/background.cpp @@ -48,6 +48,8 @@ auto VDP::Background::run() -> void { output.color.bit(1) = vdp.vram[patternAddress + 1].bit(index); output.color.bit(2) = vdp.vram[patternAddress + 2].bit(index); output.color.bit(3) = vdp.vram[patternAddress + 3].bit(index); + + if(output.color == 0) output.priority = 0; } auto VDP::Background::power() -> void { diff --git a/higan/ms/vdp/vdp.cpp b/higan/ms/vdp/vdp.cpp index 051e2b31..ebf1f6d0 100644 --- a/higan/ms/vdp/vdp.cpp +++ b/higan/ms/vdp/vdp.cpp @@ -38,13 +38,14 @@ auto VDP::main() -> void { sprite.run(); step(2); - uint12 color = palette(io.backdropColor); - if(background.output.color && (background.output.priority || !sprite.output.color)) { - color = palette(background.output.palette << 4 | background.output.color); - } else if(sprite.output.color) { - color = palette(16 | sprite.output.color); + uint12 color = palette(16 | io.backdropColor); + if(!io.leftClip || x >= 8) { + if(background.output.priority || !sprite.output.color) { + color = palette(background.output.palette << 4 | background.output.color); + } else if(sprite.output.color) { + color = palette(16 | sprite.output.color); + } } - if(x <= 7 && io.leftClip) color = palette(io.backdropColor); if(!io.displayEnable) color = 0; *screen++ = color; } diff --git a/higan/sfc/cartridge/load.cpp b/higan/sfc/cartridge/load.cpp index 8fd2acf7..a66ff00b 100644 --- a/higan/sfc/cartridge/load.cpp +++ b/higan/sfc/cartridge/load.cpp @@ -1,7 +1,7 @@ auto Cartridge::loadCartridge(Markup::Node node) -> void { information.title.cartridge = node["information/title"].text(); auto board = node["board"]; - if(!region() || region() == "Auto") { + if(region() == "Auto") { if(board["region"].text() == "ntsc") information.region = "NTSC"; if(board["region"].text() == "pal") information.region = "PAL"; } diff --git a/higan/target-tomoko/program/interface.cpp b/higan/target-tomoko/program/interface.cpp index 2f7a3aaf..54245143 100644 --- a/higan/target-tomoko/program/interface.cpp +++ b/higan/target-tomoko/program/interface.cpp @@ -28,6 +28,7 @@ auto Program::load(uint id, string name, string type, string_vector options) -> if(mediumQueue) { auto entry = mediumQueue.takeLeft().split("|", 1L); location = entry.right(); + if(entry.size() == 1) option = options(0); if(entry.size() == 2) option = entry.left(); } else { BrowserDialog dialog; diff --git a/icarus/heuristics/mega-drive.cpp b/icarus/heuristics/mega-drive.cpp index 0072f88b..1c4559fb 100644 --- a/icarus/heuristics/mega-drive.cpp +++ b/icarus/heuristics/mega-drive.cpp @@ -25,13 +25,13 @@ MegaDriveCartridge::MegaDriveCartridge(string location, uint8_t* data, uint size ramTo |= data[0x01ba] << 8; ramTo |= data[0x01bb] << 0; - if(!(ramFrom & 1) && !(ramTo & 1)) ramMode = "lo"; - if( (ramFrom & 1) && (ramTo & 1)) ramMode = "hi"; + if(!(ramFrom & 1) && !(ramTo & 1)) ramMode = "hi"; + if( (ramFrom & 1) && (ramTo & 1)) ramMode = "lo"; if(!(ramFrom & 1) && (ramTo & 1)) ramMode = "word"; uint32_t ramSize = ramTo - ramFrom + 1; - if(ramMode == "lo") ramSize = (ramTo >> 1) - (ramFrom >> 1) + 1; if(ramMode == "hi") ramSize = (ramTo >> 1) - (ramFrom >> 1) + 1; + if(ramMode == "lo") ramSize = (ramTo >> 1) - (ramFrom >> 1) + 1; if(ramMode == "word") ramSize = ramTo - ramFrom + 1; if(ramMode != "none") ramSize = bit::round(min(0x20000, ramSize)); diff --git a/nall/mosaic.hpp b/nall/mosaic.hpp deleted file mode 100644 index ac6e6f2a..00000000 --- a/nall/mosaic.hpp +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include -#include -#include diff --git a/nall/mosaic/bitstream.hpp b/nall/mosaic/bitstream.hpp deleted file mode 100644 index d46e971c..00000000 --- a/nall/mosaic/bitstream.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -namespace nall { namespace mosaic { - -struct bitstream { - ~bitstream() { - close(); - } - - auto read(uint64_t addr) const -> bool { - if(data == nullptr || (addr >> 3) >= size) return 0; - uint mask = endian == 0 ? (0x01 << (addr & 7)) : (0x80 >> (addr & 7)); - return data[addr >> 3] & mask; - } - - auto write(uint64_t addr, bool value) -> void { - if(data == nullptr || readonly == true || (addr >> 3) >= size) return; - uint mask = endian == 0 ? (0x01 << (addr & 7)) : (0x80 >> (addr & 7)); - if(value == 0) data[addr >> 3] &= ~mask; - if(value == 1) data[addr >> 3] |= mask; - } - - auto open(const string& filename) -> bool { - readonly = false; - if(fp.open(filename, filemap::mode::readwrite) == false) { - readonly = true; - if(fp.open(filename, filemap::mode::read) == false) { - return false; - } - } - data = fp.data(); - size = fp.size(); - return true; - } - - auto close() -> void { - fp.close(); - data = nullptr; - } - - filemap fp; - uint8_t* data = nullptr; - uint size = 0; - bool readonly = false; - bool endian = 1; -}; - -}} diff --git a/nall/mosaic/context.hpp b/nall/mosaic/context.hpp deleted file mode 100644 index ceb13422..00000000 --- a/nall/mosaic/context.hpp +++ /dev/null @@ -1,221 +0,0 @@ -#pragma once - -namespace nall { namespace mosaic { - -struct context { - context() { - reset(); - } - - auto objectWidth() const -> uint { return blockWidth * tileWidth * mosaicWidth + paddingWidth; } - auto objectHeight() const -> uint { return blockHeight * tileHeight * mosaicHeight + paddingHeight; } - auto objectSize() const -> uint { - uint size = blockStride * tileWidth * tileHeight * mosaicWidth * mosaicHeight - + blockOffset * tileHeight * mosaicWidth * mosaicHeight - + tileStride * mosaicWidth * mosaicHeight - + tileOffset * mosaicHeight; - return max(1u, size); - } - - auto reset() -> void { - offset = 0; - width = 0; - height = 0; - count = 0; - - endian = 1; - order = 0; - depth = 1; - - blockWidth = 1; - blockHeight = 1; - blockStride = 0; - blockOffset = 0; - block.reset(); - - tileWidth = 1; - tileHeight = 1; - tileStride = 0; - tileOffset = 0; - tile.reset(); - - mosaicWidth = 1; - mosaicHeight = 1; - mosaicStride = 0; - mosaicOffset = 0; - mosaic.reset(); - - paddingWidth = 0; - paddingHeight = 0; - paddingColor = 0; - palette.reset(); - } - - auto eval(const string& expression) -> uint { - if(auto result = Eval::integer(expression)) return result(); - return 0u; - } - - auto eval(vector& buffer, const string& expression_) -> void { - string expression = expression_; - bool function = false; - for(auto& c : expression) { - if(c == '(') function = true; - if(c == ')') function = false; - if(c == ',' && function == true) c = ';'; - } - - auto list = expression.split(","); - for(auto& item : list) { - item.strip(); - if(item.match("f(?*) ?*")) { - item.trimLeft("f(", 1L); - auto part = item.split(") ", 1L); - auto args = part[0].split(";", 3L).strip(); - - uint length = eval(args(0, "0")); - uint offset = eval(args(1, "0")); - uint stride = eval(args(2, "0")); - if(args.size() < 2) offset = buffer.size(); - if(args.size() < 3) stride = 1; - - for(uint n = 0; n < length; n++) { - string fn = part[1]; - fn.replace("n", string{n}); - fn.replace("o", string{offset}); - fn.replace("p", string{buffer.size()}); - buffer.resize(offset + 1); - buffer[offset] = eval(fn); - offset += stride; - } - } else if(item.match("base64*")) { - uint offset = 0; - item.trimLeft("base64", 1L); - if(item.match("(?*) *")) { - item.trimLeft("(", 1L); - auto part = item.split(") ", 1L); - offset = eval(part[0]); - item = part(1, ""); - } - item.strip(); - for(auto& c : item) { - if(c >= 'A' && c <= 'Z') buffer.append(offset + c - 'A' + 0); - if(c >= 'a' && c <= 'z') buffer.append(offset + c - 'a' + 26); - if(c >= '0' && c <= '9') buffer.append(offset + c - '0' + 52); - if(c == '-') buffer.append(offset + 62); - if(c == '_') buffer.append(offset + 63); - } - } else if(item.match("file *")) { - item.trimLeft("file ", 1L); - item.strip(); - //... - } else if(item) { - buffer.append(eval(item)); - } - } - } - - auto parse(const string& data) -> void { - reset(); - - auto lines = data.split("\n"); - for(auto& line : lines) { - auto part = line.split(":", 1L).strip(); - if(part.size() != 2) continue; - - if(part[0] == "offset") offset = eval(part[1]); - if(part[0] == "width") width = eval(part[1]); - if(part[0] == "height") height = eval(part[1]); - if(part[0] == "count") count = eval(part[1]); - - if(part[0] == "endian") endian = eval(part[1]); - if(part[0] == "order") order = eval(part[1]); - if(part[0] == "depth") depth = eval(part[1]); - - if(part[0] == "blockWidth") blockWidth = eval(part[1]); - if(part[0] == "blockHeight") blockHeight = eval(part[1]); - if(part[0] == "blockStride") blockStride = eval(part[1]); - if(part[0] == "blockOffset") blockOffset = eval(part[1]); - if(part[0] == "block") eval(block, part[1]); - - if(part[0] == "tileWidth") tileWidth = eval(part[1]); - if(part[0] == "tileHeight") tileHeight = eval(part[1]); - if(part[0] == "tileStride") tileStride = eval(part[1]); - if(part[0] == "tileOffset") tileOffset = eval(part[1]); - if(part[0] == "tile") eval(tile, part[1]); - - if(part[0] == "mosaicWidth") mosaicWidth = eval(part[1]); - if(part[0] == "mosaicHeight") mosaicHeight = eval(part[1]); - if(part[0] == "mosaicStride") mosaicStride = eval(part[1]); - if(part[0] == "mosaicOffset") mosaicOffset = eval(part[1]); - if(part[0] == "mosaic") eval(mosaic, part[1]); - - if(part[0] == "paddingWidth") paddingWidth = eval(part[1]); - if(part[0] == "paddingHeight") paddingHeight = eval(part[1]); - if(part[0] == "paddingColor") paddingColor = eval(part[1]); - if(part[0] == "palette") eval(palette, part[1]); - } - - sanitize(); - } - - auto load(const string& filename) -> bool { - if(auto filedata = string::read(filename)) { - parse(filedata); - return true; - } - return false; - } - - auto sanitize() -> void { - if(depth < 1) depth = 1; - if(depth > 24) depth = 24; - - if(blockWidth < 1) blockWidth = 1; - if(blockHeight < 1) blockHeight = 1; - - if(tileWidth < 1) tileWidth = 1; - if(tileHeight < 1) tileHeight = 1; - - if(mosaicWidth < 1) mosaicWidth = 1; - if(mosaicHeight < 1) mosaicHeight = 1; - - //set alpha to full opacity - paddingColor |= 255u << 24; - for(auto& color : palette) color |= 255u << 24; - } - - uint offset; - uint width; - uint height; - uint count; - - bool endian; //0 = lsb, 1 = msb - bool order; //0 = linear, 1 = planar - uint depth; //1 - 24bpp - - uint blockWidth; - uint blockHeight; - uint blockStride; - uint blockOffset; - vector block; - - uint tileWidth; - uint tileHeight; - uint tileStride; - uint tileOffset; - vector tile; - - uint mosaicWidth; - uint mosaicHeight; - uint mosaicStride; - uint mosaicOffset; - vector mosaic; - - uint paddingWidth; - uint paddingHeight; - uint paddingColor; - vector palette; -}; - -}} diff --git a/nall/mosaic/parser.hpp b/nall/mosaic/parser.hpp deleted file mode 100644 index 5d68cd83..00000000 --- a/nall/mosaic/parser.hpp +++ /dev/null @@ -1,119 +0,0 @@ -#pragma once - -namespace nall { namespace mosaic { - -struct parser { - //export from bitstream to canvas - auto load(bitstream& stream, uint64_t offset, context& ctx, uint width, uint height) -> void { - canvas.allocate(width, height); - canvas.fill(ctx.paddingColor); - parse(1, stream, offset, ctx, width, height); - } - - //import from canvas to bitstream - auto save(bitstream& stream, uint64_t offset, context& ctx) -> bool { - if(stream.readonly) return false; - parse(0, stream, offset, ctx, canvas.width(), canvas.height()); - return true; - } - -private: - auto read(uint x, uint y) const -> uint32_t { - uint addr = y * canvas.width() + x; - if(addr >= canvas.width() * canvas.height()) return 0u; - auto buffer = (uint32_t*)canvas.data(); - return buffer[addr]; - } - - auto write(uint x, uint y, uint32_t data) -> void { - uint addr = y * canvas.width() + x; - if(addr >= canvas.width() * canvas.height()) return; - auto buffer = (uint32_t*)canvas.data(); - buffer[addr] = data; - } - - auto parse(bool load, bitstream& stream, uint64_t offset, context& ctx, uint width, uint height) -> void { - stream.endian = ctx.endian; - uint canvasWidth = width / (ctx.mosaicWidth * ctx.tileWidth * ctx.blockWidth + ctx.paddingWidth); - uint canvasHeight = height / (ctx.mosaicHeight * ctx.tileHeight * ctx.blockHeight + ctx.paddingHeight); - uint bitsPerBlock = ctx.depth * ctx.blockWidth * ctx.blockHeight; - - uint objectOffset = 0; - for(uint objectY = 0; objectY < canvasHeight; objectY++) { - for(uint objectX = 0; objectX < canvasWidth; objectX++) { - if(objectOffset >= ctx.count && ctx.count > 0) break; - uint objectIX = objectX * ctx.objectWidth(); - uint objectIY = objectY * ctx.objectHeight(); - objectOffset++; - - uint mosaicOffset = 0; - for(uint mosaicY = 0; mosaicY < ctx.mosaicHeight; mosaicY++) { - for(uint mosaicX = 0; mosaicX < ctx.mosaicWidth; mosaicX++) { - uint mosaicData = ctx.mosaic(mosaicOffset, mosaicOffset); - uint mosaicIX = (mosaicData % ctx.mosaicWidth) * (ctx.tileWidth * ctx.blockWidth); - uint mosaicIY = (mosaicData / ctx.mosaicWidth) * (ctx.tileHeight * ctx.blockHeight); - mosaicOffset++; - - uint tileOffset = 0; - for(uint tileY = 0; tileY < ctx.tileHeight; tileY++) { - for(uint tileX = 0; tileX < ctx.tileWidth; tileX++) { - uint tileData = ctx.tile(tileOffset, tileOffset); - uint tileIX = (tileData % ctx.tileWidth) * ctx.blockWidth; - uint tileIY = (tileData / ctx.tileWidth) * ctx.blockHeight; - tileOffset++; - - uint blockOffset = 0; - for(uint blockY = 0; blockY < ctx.blockHeight; blockY++) { - for(uint blockX = 0; blockX < ctx.blockWidth; blockX++) { - if(load) { - uint palette = 0; - for(uint n = 0; n < ctx.depth; n++) { - uint index = blockOffset++; - if(ctx.order == 1) index = (index % ctx.depth) * ctx.blockWidth * ctx.blockHeight + (index / ctx.depth); - palette |= stream.read(offset + ctx.block(index, index)) << n; - } - - write( - objectIX + mosaicIX + tileIX + blockX, - objectIY + mosaicIY + tileIY + blockY, - ctx.palette(palette, palette) - ); - } else /* save */ { - uint32_t palette = read( - objectIX + mosaicIX + tileIX + blockX, - objectIY + mosaicIY + tileIY + blockY - ); - - for(uint n = 0; n < ctx.depth; n++) { - uint index = blockOffset++; - if(ctx.order == 1) index = (index % ctx.depth) * ctx.blockWidth * ctx.blockHeight + (index / ctx.depth); - stream.write(offset + ctx.block(index, index), palette & 1); - palette >>= 1; - } - } - } //blockX - } //blockY - - offset += ctx.blockStride; - } //tileX - - offset += ctx.blockOffset; - } //tileY - - offset += ctx.tileStride; - } //mosaicX - - offset += ctx.tileOffset; - } //mosaicY - - offset += ctx.mosaicStride; - } //objectX - - offset += ctx.mosaicOffset; - } //objectY - } - - image canvas; -}; - -}}