mirror of
https://github.com/usatiuk/cardboy.git
synced 2025-10-28 23:27:49 +01:00
a bit more speedup
This commit is contained in:
@@ -568,7 +568,6 @@ union cart_rtc
|
|||||||
} reg;
|
} reg;
|
||||||
uint8_t bytes[5];
|
uint8_t bytes[5];
|
||||||
};
|
};
|
||||||
extern "C" uint8_t gb_rom_read(struct gb_s*, const uint_fast32_t);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emulator context.
|
* Emulator context.
|
||||||
@@ -730,9 +729,14 @@ struct gb_s
|
|||||||
|
|
||||||
/* Implementation defined data. Set to NULL if not required. */
|
/* Implementation defined data. Set to NULL if not required. */
|
||||||
void *priv;
|
void *priv;
|
||||||
|
const uint8_t* rom;
|
||||||
} direct;
|
} direct;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
__attribute__((always_inline)) inline uint8_t gb_rom_read(struct gb_s* s, const uint_fast32_t addr) {
|
||||||
|
return s->direct.rom[addr];
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef PEANUT_GB_HEADER_ONLY
|
#ifndef PEANUT_GB_HEADER_ONLY
|
||||||
|
|
||||||
#define IO_JOYP 0x00
|
#define IO_JOYP 0x00
|
||||||
@@ -3687,7 +3691,7 @@ enum gb_init_error_e gb_init(struct gb_s *gb,
|
|||||||
uint8_t (*gb_cart_ram_read)(struct gb_s*, const uint_fast32_t),
|
uint8_t (*gb_cart_ram_read)(struct gb_s*, const uint_fast32_t),
|
||||||
void (*gb_cart_ram_write)(struct gb_s*, const uint_fast32_t, const uint8_t),
|
void (*gb_cart_ram_write)(struct gb_s*, const uint_fast32_t, const uint8_t),
|
||||||
void (*gb_error)(struct gb_s*, const enum gb_error_e, const uint16_t),
|
void (*gb_error)(struct gb_s*, const enum gb_error_e, const uint16_t),
|
||||||
void *priv)
|
void *priv, const uint8_t* rom_data)
|
||||||
{
|
{
|
||||||
const uint16_t mbc_location = 0x0147;
|
const uint16_t mbc_location = 0x0147;
|
||||||
const uint16_t bank_count_location = 0x0148;
|
const uint16_t bank_count_location = 0x0148;
|
||||||
@@ -3726,6 +3730,7 @@ enum gb_init_error_e gb_init(struct gb_s *gb,
|
|||||||
gb->gb_cart_ram_write = gb_cart_ram_write;
|
gb->gb_cart_ram_write = gb_cart_ram_write;
|
||||||
gb->gb_error = gb_error;
|
gb->gb_error = gb_error;
|
||||||
gb->direct.priv = priv;
|
gb->direct.priv = priv;
|
||||||
|
gb->direct.rom = rom_data;
|
||||||
|
|
||||||
/* Initialise serial transfer function to NULL. If the front-end does
|
/* Initialise serial transfer function to NULL. If the front-end does
|
||||||
* not provide serial support, Peanut-GB will emulate no cable connected
|
* not provide serial support, Peanut-GB will emulate no cable connected
|
||||||
@@ -3879,7 +3884,7 @@ enum gb_init_error_e gb_init(struct gb_s *gb,
|
|||||||
uint8_t (*gb_cart_ram_read)(struct gb_s*, const uint_fast32_t),
|
uint8_t (*gb_cart_ram_read)(struct gb_s*, const uint_fast32_t),
|
||||||
void (*gb_cart_ram_write)(struct gb_s*, const uint_fast32_t, const uint8_t),
|
void (*gb_cart_ram_write)(struct gb_s*, const uint_fast32_t, const uint8_t),
|
||||||
void (*gb_error)(struct gb_s*, const enum gb_error_e, const uint16_t),
|
void (*gb_error)(struct gb_s*, const enum gb_error_e, const uint16_t),
|
||||||
void *priv);
|
void *priv, const uint8_t* rom_data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the emulator and runs for the duration of time equal to one frame.
|
* Executes the emulator and runs for the duration of time equal to one frame.
|
||||||
|
|||||||
@@ -76,6 +76,29 @@ static constexpr LUTFull buildNibbleLUT() {
|
|||||||
|
|
||||||
inline constexpr LUTFull kNibbleLUT = buildNibbleLUT();
|
inline constexpr LUTFull kNibbleLUT = buildNibbleLUT();
|
||||||
|
|
||||||
|
static constexpr LUTFull buildFullHeightWideByteLUT() {
|
||||||
|
LUTFull L{};
|
||||||
|
for (int yp = 0; yp < 2; ++yp)
|
||||||
|
for (int xp = 0; xp < 2; ++xp)
|
||||||
|
for (int p = 0; p < 256; ++p) {
|
||||||
|
const uint8_t p0 = static_cast<uint8_t>(p & 0x03);
|
||||||
|
const uint8_t p1 = static_cast<uint8_t>((p >> 2) & 0x03);
|
||||||
|
const uint8_t p2 = static_cast<uint8_t>((p >> 4) & 0x03);
|
||||||
|
const uint8_t p3 = static_cast<uint8_t>((p >> 6) & 0x03);
|
||||||
|
|
||||||
|
const uint8_t p4a = static_cast<uint8_t>(p0 | (p0 << 2) | (p1 << 4) | (p1 << 6));
|
||||||
|
const uint8_t p4b = static_cast<uint8_t>(p2 | (p2 << 2) | (p3 << 4) | (p3 << 6));
|
||||||
|
|
||||||
|
const uint8_t n0 = makeNibble(p4a, xp, yp);
|
||||||
|
const uint8_t n1 = makeNibble(p4b, xp, yp);
|
||||||
|
|
||||||
|
L[yp][xp][p] = static_cast<uint8_t>((n0 << 4) | (n1 & 0x0F));
|
||||||
|
}
|
||||||
|
return L;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline constexpr LUTFull kFullHeightWideByteLUT = buildFullHeightWideByteLUT();
|
||||||
|
|
||||||
|
|
||||||
namespace apps {
|
namespace apps {
|
||||||
namespace {
|
namespace {
|
||||||
@@ -869,8 +892,8 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::memset(&gb, 0, sizeof(gb));
|
std::memset(&gb, 0, sizeof(gb));
|
||||||
const auto initResult =
|
const auto initResult = gb_init(&gb, &GameboyApp::cartRamRead, &GameboyApp::cartRamWrite,
|
||||||
gb_init(&gb, &GameboyApp::cartRamRead, &GameboyApp::cartRamWrite, &GameboyApp::errorCallback, this);
|
&GameboyApp::errorCallback, this, romDataView);
|
||||||
if (initResult != GB_INIT_NO_ERROR) {
|
if (initResult != GB_INIT_NO_ERROR) {
|
||||||
setStatus(initErrorToString(initResult));
|
setStatus(initErrorToString(initResult));
|
||||||
romData.clear();
|
romData.clear();
|
||||||
@@ -1276,23 +1299,17 @@ private:
|
|||||||
CARDBOY_CHECK(yEnd > yStart);
|
CARDBOY_CHECK(yEnd > yStart);
|
||||||
CARDBOY_CHECK((kFullHeightWideOffsetX % 8) == 0);
|
CARDBOY_CHECK((kFullHeightWideOffsetX % 8) == 0);
|
||||||
|
|
||||||
|
const int xParityBase = kFullHeightWideOffsetX & 1;
|
||||||
|
|
||||||
for (int dstY = yStart; dstY < yEnd; ++dstY) {
|
for (int dstY = yStart; dstY < yEnd; ++dstY) {
|
||||||
const int yParity = dstY & 1;
|
const int yParity = dstY & 1;
|
||||||
int dstX = kFullHeightWideOffsetX;
|
int dstX = kFullHeightWideOffsetX;
|
||||||
|
|
||||||
for (int srcX = 0; srcX < LCD_WIDTH; srcX += 4) {
|
for (int srcX = 0; srcX < LCD_WIDTH; srcX += 4) {
|
||||||
const uint8_t p0 = pixels[srcX + 0];
|
const uint8_t packIndex = static_cast<uint8_t>((pixels[srcX + 0]) | ((pixels[srcX + 1]) << 2) |
|
||||||
const uint8_t p1 = pixels[srcX + 1];
|
((pixels[srcX + 2]) << 4) | ((pixels[srcX + 3]) << 6));
|
||||||
const uint8_t p2 = pixels[srcX + 2];
|
|
||||||
const uint8_t p3 = pixels[srcX + 3];
|
|
||||||
|
|
||||||
const uint8_t p4a = static_cast<uint8_t>(p0 | (p0 << 2) | (p1 << 4) | (p1 << 6));
|
const uint8_t pack = kFullHeightWideByteLUT[yParity][xParityBase][packIndex];
|
||||||
const uint8_t p4b = static_cast<uint8_t>(p2 | (p2 << 2) | (p3 << 4) | (p3 << 6));
|
|
||||||
|
|
||||||
const int xParity = dstX & 1;
|
|
||||||
const uint8_t n0 = kNibbleLUT[yParity][xParity][p4a];
|
|
||||||
const uint8_t n1 = kNibbleLUT[yParity][xParity][p4b];
|
|
||||||
const uint8_t pack = static_cast<uint8_t>((n0 << 4) | (n1 & 0x0F));
|
|
||||||
|
|
||||||
fb.drawBits8(dstX, dstY, pack);
|
fb.drawBits8(dstX, dstY, pack);
|
||||||
dstX += 8;
|
dstX += 8;
|
||||||
@@ -1403,9 +1420,6 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C" __attribute__((always_inline)) uint8_t gb_rom_read(struct gb_s* gb, const uint_fast32_t addr) {
|
|
||||||
return GameboyApp::romRead(gb, addr);
|
|
||||||
}
|
|
||||||
class GameboyAppFactory final : public cardboy::sdk::IAppFactory {
|
class GameboyAppFactory final : public cardboy::sdk::IAppFactory {
|
||||||
public:
|
public:
|
||||||
const char* name() const override { return kGameboyAppName; }
|
const char* name() const override { return kGameboyAppName; }
|
||||||
|
|||||||
Reference in New Issue
Block a user