mirror of https://github.com/mgba-emu/mgba.git
Merge branch 'master' (early part) into medusa
This commit is contained in:
commit
b6db8581df
6
CHANGES
6
CHANGES
|
@ -70,6 +70,12 @@ Misc:
|
|||
- PSP2: Use system enter key by default
|
||||
- 3DS: Remove deprecated CSND interface
|
||||
|
||||
0.6.3: (2017-04-14)
|
||||
Bugfixes:
|
||||
- GB Audio: Revert unsigned audio changes
|
||||
- GB Video: Fix bad merge (fixes mgba.io/i/1040)
|
||||
- GBA Video: Fix OBJ blending regression (fixes mgba.io/i/1037)
|
||||
|
||||
0.6.2: (2017-04-03)
|
||||
Bugfixes:
|
||||
- Core: Fix ROM patches not being unloaded when disabled (fixes mgba.io/i/962)
|
||||
|
|
|
@ -920,7 +920,7 @@ if(BUILD_PERF)
|
|||
target_link_libraries(${BINARY_NAME}-perf ${BINARY_NAME} ${PERF_LIB} ${OS_LIB})
|
||||
set_target_properties(${BINARY_NAME}-perf PROPERTIES COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES}")
|
||||
install(TARGETS ${BINARY_NAME}-perf DESTINATION bin COMPONENT ${BINARY_NAME}-perf)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/tools/perf.py DESTINATION "${CMAKE_INSTALL_LIBDIR}/${BINARY_NAME}" COMPONENT ${BINARY_NAME}-perf)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/tools/perf.py DESTINATION "${LIBDIR}/${BINARY_NAME}" COMPONENT ${BINARY_NAME}-perf)
|
||||
endif()
|
||||
|
||||
if(BUILD_TEST)
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
.Nm medusa-emu-qt
|
||||
.Op Fl 123456fg
|
||||
.Op Fl b Ar biosfile
|
||||
.Op Fl C Ar option Ns = Ns Ar value
|
||||
.Op Fl l Ar loglevel
|
||||
.Op Fl p Ar patchfile
|
||||
.Op Fl s Ar n
|
||||
|
@ -40,6 +41,11 @@ If this flag is omitted,
|
|||
.Nm
|
||||
will use the BIOS specified in the configuration file,
|
||||
or a high\(hylevel emulated BIOS if none is specified.
|
||||
.It Fl C Ar option Ns = Ns Ar value , Fl -config Ar option Ns = Ns Ar value
|
||||
Override the given config
|
||||
.Ar option
|
||||
with
|
||||
.Ar value .
|
||||
.It Fl f
|
||||
Start the emulator full\(hyscreen.
|
||||
.It Fl g
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
.Nm medusa-emu
|
||||
.Op Fl 123456dfg
|
||||
.Op Fl b Ar biosfile
|
||||
.Op Fl C Ar option Ns = Ns Ar value
|
||||
.Op Fl c Ar cheatfile
|
||||
.Op Fl l Ar loglevel
|
||||
.Op Fl p Ar patchfile
|
||||
|
@ -42,6 +43,11 @@ If this flag is omitted,
|
|||
.Nm
|
||||
will use the BIOS specified in the configuration file,
|
||||
or a high\(hylevel emulated BIOS if none is specified.
|
||||
.It Fl C Ar option Ns = Ns Ar value , Fl -config Ar option Ns = Ns Ar value
|
||||
Override the given config
|
||||
.Ar option
|
||||
with
|
||||
.Ar value .
|
||||
.It Fl c Ar cheatfile , Fl -cheats Ar cheatfile
|
||||
Apply cheat codes from
|
||||
.Ar cheatfile .
|
||||
|
|
|
@ -62,7 +62,7 @@ enum GBSGBCommand {
|
|||
SGB_PICON_EN,
|
||||
SGB_DATA_SND,
|
||||
SGB_DATA_TRN,
|
||||
SGB_MLT_REG,
|
||||
SGB_MLT_REQ,
|
||||
SGB_JUMP,
|
||||
SGB_CHR_TRN,
|
||||
SGB_PCT_TRN,
|
||||
|
@ -107,6 +107,8 @@ struct GB {
|
|||
int sgbBit;
|
||||
int currentSgbBits;
|
||||
uint8_t sgbPacket[16];
|
||||
uint8_t sgbControllers;
|
||||
uint8_t sgbCurrentController;
|
||||
|
||||
struct mCoreCallbacksList coreCallbacks;
|
||||
struct mAVStream* stream;
|
||||
|
|
|
@ -39,15 +39,9 @@ struct GBVideoSoftwareRenderer {
|
|||
enum GBModel model;
|
||||
|
||||
int sgbTransfer;
|
||||
uint8_t sgbPacket[16];
|
||||
uint8_t sgbPacket[128];
|
||||
uint8_t sgbCommandHeader;
|
||||
int sgbPacketId;
|
||||
int sgbDataSets;
|
||||
uint8_t sgbPartialDataSet[15];
|
||||
bool sgbBorders;
|
||||
int sgbAttrX;
|
||||
int sgbAttrY;
|
||||
int sgbAttrDirection;
|
||||
};
|
||||
|
||||
void GBVideoSoftwareRendererCreate(struct GBVideoSoftwareRenderer*);
|
||||
|
|
|
@ -258,6 +258,9 @@ DECL_BITS(GBSerializedMemoryFlags, ActiveRtcReg, 5, 3);
|
|||
DECL_BITFIELD(GBSerializedSGBFlags, uint32_t);
|
||||
DECL_BITS(GBSerializedSGBFlags, P1Bits, 0, 2);
|
||||
DECL_BITS(GBSerializedSGBFlags, RenderMode, 2, 2);
|
||||
DECL_BITS(GBSerializedSGBFlags, BufferIndex, 4, 3);
|
||||
DECL_BITS(GBSerializedSGBFlags, CurrentController, 7, 2);
|
||||
DECL_BITS(GBSerializedSGBFlags, ReqControllers, 9, 2);
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct GBSerializedState {
|
||||
|
@ -388,15 +391,15 @@ struct GBSerializedState {
|
|||
uint8_t vram[GB_SIZE_VRAM];
|
||||
uint8_t wram[GB_SIZE_WORKING_RAM];
|
||||
|
||||
uint32_t reserved2[0xE0];
|
||||
uint32_t reserved2[0xC4];
|
||||
|
||||
struct {
|
||||
uint8_t attributes[90];
|
||||
uint8_t command;
|
||||
uint8_t bits;
|
||||
GBSerializedSGBFlags flags;
|
||||
uint8_t packet[16];
|
||||
uint32_t reserved[4];
|
||||
uint8_t inProgressPacket[16];
|
||||
uint8_t packet[128];
|
||||
uint8_t charRam[SGB_SIZE_CHAR_RAM];
|
||||
uint8_t mapRam[SGB_SIZE_MAP_RAM];
|
||||
uint8_t palRam[SGB_SIZE_PAL_RAM];
|
||||
|
|
|
@ -143,6 +143,8 @@ struct GBVideo {
|
|||
int ocpIndex;
|
||||
bool ocpIncrement;
|
||||
uint8_t sgbCommandHeader;
|
||||
int sgbBufferIndex;
|
||||
uint8_t sgbPacketBuffer[128];
|
||||
|
||||
uint16_t dmgPalette[12];
|
||||
uint16_t palette[64];
|
||||
|
|
|
@ -290,7 +290,9 @@ static void _GBCoreSetAVStream(struct mCore* core, struct mAVStream* stream) {
|
|||
struct GB* gb = core->board;
|
||||
gb->stream = stream;
|
||||
if (stream && stream->videoDimensionsChanged) {
|
||||
stream->videoDimensionsChanged(stream, GB_VIDEO_HORIZONTAL_PIXELS, GB_VIDEO_VERTICAL_PIXELS);
|
||||
unsigned width, height;
|
||||
core->desiredVideoDimensions(core, &width, &height);
|
||||
stream->videoDimensionsChanged(stream, width, height);
|
||||
}
|
||||
if (stream && stream->videoFrameRateChanged) {
|
||||
stream->videoFrameRateChanged(stream, core->frameCycles(core), core->frequency(core));
|
||||
|
|
|
@ -446,6 +446,8 @@ void GBReset(struct LR35902Core* cpu) {
|
|||
}
|
||||
|
||||
gb->sgbBit = -1;
|
||||
gb->sgbControllers = 0;
|
||||
gb->sgbCurrentController = 0;
|
||||
gb->currentSgbBits = 0;
|
||||
memset(gb->sgbPacket, 0, sizeof(gb->sgbPacket));
|
||||
|
||||
|
|
|
@ -113,6 +113,9 @@ static void _writeSGBBits(struct GB* gb, int bits) {
|
|||
return;
|
||||
}
|
||||
gb->currentSgbBits = bits;
|
||||
if (bits == 3) {
|
||||
gb->sgbCurrentController = (gb->sgbCurrentController + 1) & gb->sgbControllers;
|
||||
}
|
||||
if (gb->sgbBit == 128 && bits == 2) {
|
||||
GBVideoWriteSGBPacket(&gb->video, gb->sgbPacket);
|
||||
++gb->sgbBit;
|
||||
|
@ -503,10 +506,13 @@ void GBIOWrite(struct GB* gb, unsigned address, uint8_t value) {
|
|||
|
||||
static uint8_t _readKeys(struct GB* gb) {
|
||||
uint8_t keys = *gb->keySource;
|
||||
if (gb->sgbCurrentController != 0) {
|
||||
keys = 0;
|
||||
}
|
||||
switch (gb->memory.io[REG_JOYP] & 0x30) {
|
||||
case 0x30:
|
||||
// TODO: Increment
|
||||
keys = (gb->video.sgbCommandHeader >> 3) == SGB_MLT_REG ? 0xF : 0;
|
||||
keys = (gb->video.sgbCommandHeader >> 3) == SGB_MLT_REQ ? 0xF - gb->sgbCurrentController : 0;
|
||||
break;
|
||||
case 0x20:
|
||||
keys >>= 4;
|
||||
|
|
|
@ -81,23 +81,17 @@ static void _regenerateSGBBorder(struct GBVideoSoftwareRenderer* renderer) {
|
|||
if (SGBBgAttributesIsXFlip(mapData)) {
|
||||
for (i = 0; i < 8; ++i) {
|
||||
colorSelector = (tileData[0] >> i & 0x1) << 0 | (tileData[1] >> i & 0x1) << 1 | (tileData[2] >> i & 0x1) << 2 | (tileData[3] >> i & 0x1) << 3;
|
||||
// The first color of every palette is transparent
|
||||
if (colorSelector) {
|
||||
renderer->outputBuffer[base + i] = renderer->palette[paletteBase | colorSelector];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 7; i >= 0; --i) {
|
||||
colorSelector = (tileData[0] >> i & 0x1) << 0 | (tileData[1] >> i & 0x1) << 1 | (tileData[2] >> i & 0x1) << 2 | (tileData[3] >> i & 0x1) << 3;
|
||||
|
||||
if (colorSelector) {
|
||||
renderer->outputBuffer[base + 7 - i] = renderer->palette[paletteBase | colorSelector];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void _setAttribute(uint8_t* sgbAttributes, unsigned x, unsigned y, int palette) {
|
||||
int p = sgbAttributes[(x >> 2) + 5 * y];
|
||||
|
@ -108,12 +102,7 @@ static inline void _setAttribute(uint8_t* sgbAttributes, unsigned x, unsigned y,
|
|||
|
||||
static void _parseAttrBlock(struct GBVideoSoftwareRenderer* renderer, int start) {
|
||||
uint8_t block[6];
|
||||
if (start < 0) {
|
||||
memcpy(block, renderer->sgbPartialDataSet, -start);
|
||||
memcpy(&block[-start], renderer->sgbPacket, 6 + start);
|
||||
} else {
|
||||
memcpy(block, &renderer->sgbPacket[start], 6);
|
||||
}
|
||||
unsigned x0 = block[2];
|
||||
unsigned x1 = block[4];
|
||||
unsigned y0 = block[3];
|
||||
|
@ -268,14 +257,16 @@ static void GBVideoSoftwareRendererWriteSGBPacket(struct GBVideoRenderer* render
|
|||
struct GBVideoSoftwareRenderer* softwareRenderer = (struct GBVideoSoftwareRenderer*) renderer;
|
||||
memcpy(softwareRenderer->sgbPacket, data, sizeof(softwareRenderer->sgbPacket));
|
||||
int i;
|
||||
if (!(softwareRenderer->sgbCommandHeader & 7)) {
|
||||
softwareRenderer->sgbCommandHeader = data[0];
|
||||
softwareRenderer->sgbPacketId = 0;
|
||||
softwareRenderer->sgbTransfer = 0;
|
||||
}
|
||||
--softwareRenderer->sgbCommandHeader;
|
||||
++softwareRenderer->sgbPacketId;
|
||||
int set;
|
||||
int sets;
|
||||
int attrX;
|
||||
int attrY;
|
||||
int attrDirection;
|
||||
int pBefore;
|
||||
int pAfter;
|
||||
int pDiv;
|
||||
switch (softwareRenderer->sgbCommandHeader >> 3) {
|
||||
case SGB_PAL_SET:
|
||||
softwareRenderer->sgbPacket[1] = data[9];
|
||||
|
@ -290,58 +281,96 @@ static void GBVideoSoftwareRendererWriteSGBPacket(struct GBVideoRenderer* render
|
|||
}
|
||||
break;
|
||||
case SGB_ATTR_BLK:
|
||||
if (softwareRenderer->sgbPacketId == 1) {
|
||||
softwareRenderer->sgbDataSets = softwareRenderer->sgbPacket[1];
|
||||
sets = softwareRenderer->sgbPacket[1];
|
||||
i = 2;
|
||||
} else {
|
||||
i = (9 - softwareRenderer->sgbPacketId) % 3 * -2;
|
||||
}
|
||||
for (; i <= 10 && softwareRenderer->sgbDataSets; i += 6, --softwareRenderer->sgbDataSets) {
|
||||
for (; i < (softwareRenderer->sgbCommandHeader & 7) << 4 && sets; i += 6, --sets) {
|
||||
_parseAttrBlock(softwareRenderer, i);
|
||||
}
|
||||
if (i < 16 && softwareRenderer->sgbDataSets) {
|
||||
memcpy(softwareRenderer->sgbPartialDataSet, &softwareRenderer->sgbPacket[i], 16 - i);
|
||||
break;
|
||||
case SGB_ATTR_DIV:
|
||||
pAfter = softwareRenderer->sgbPacket[1] & 3;
|
||||
pBefore = (softwareRenderer->sgbPacket[1] >> 2) & 3;
|
||||
pDiv = (softwareRenderer->sgbPacket[1] >> 4) & 3;
|
||||
attrX = softwareRenderer->sgbPacket[2];
|
||||
if (softwareRenderer->sgbPacket[1] & 0x40) {
|
||||
if (attrX > GB_VIDEO_VERTICAL_PIXELS / 8) {
|
||||
attrX = GB_VIDEO_VERTICAL_PIXELS / 8;
|
||||
}
|
||||
int j;
|
||||
for (j = 0; j < attrX; ++j) {
|
||||
for (i = 0; i < GB_VIDEO_HORIZONTAL_PIXELS / 8; ++i) {
|
||||
_setAttribute(renderer->sgbAttributes, i, j, pBefore);
|
||||
}
|
||||
}
|
||||
if (attrX < GB_VIDEO_VERTICAL_PIXELS / 8) {
|
||||
for (i = 0; i < GB_VIDEO_HORIZONTAL_PIXELS / 8; ++i) {
|
||||
_setAttribute(renderer->sgbAttributes, i, attrX, pDiv);
|
||||
}
|
||||
|
||||
}
|
||||
for (; j < GB_VIDEO_VERTICAL_PIXELS / 8; ++j) {
|
||||
for (i = 0; i < GB_VIDEO_HORIZONTAL_PIXELS / 8; ++i) {
|
||||
_setAttribute(renderer->sgbAttributes, i, j, pAfter);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (attrX > GB_VIDEO_HORIZONTAL_PIXELS / 8) {
|
||||
attrX = GB_VIDEO_HORIZONTAL_PIXELS / 8;
|
||||
}
|
||||
int j;
|
||||
for (j = 0; j < attrX; ++j) {
|
||||
for (i = 0; i < GB_VIDEO_HORIZONTAL_PIXELS / 8; ++i) {
|
||||
_setAttribute(renderer->sgbAttributes, j, i, pBefore);
|
||||
}
|
||||
}
|
||||
if (attrX < GB_VIDEO_HORIZONTAL_PIXELS / 8) {
|
||||
for (i = 0; i < GB_VIDEO_VERTICAL_PIXELS / 8; ++i) {
|
||||
_setAttribute(renderer->sgbAttributes, attrX, i, pDiv);
|
||||
}
|
||||
|
||||
}
|
||||
for (; j < GB_VIDEO_HORIZONTAL_PIXELS / 8; ++j) {
|
||||
for (i = 0; i < GB_VIDEO_VERTICAL_PIXELS / 8; ++i) {
|
||||
_setAttribute(renderer->sgbAttributes, j, i, pAfter);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SGB_ATTR_CHR:
|
||||
if (softwareRenderer->sgbPacketId == 1) {
|
||||
softwareRenderer->sgbAttrX = softwareRenderer->sgbPacket[1];
|
||||
softwareRenderer->sgbAttrY = softwareRenderer->sgbPacket[2];
|
||||
if (softwareRenderer->sgbAttrX >= GB_VIDEO_HORIZONTAL_PIXELS / 8) {
|
||||
softwareRenderer->sgbAttrX = 0;
|
||||
attrX = softwareRenderer->sgbPacket[1];
|
||||
attrY = softwareRenderer->sgbPacket[2];
|
||||
if (attrX >= GB_VIDEO_HORIZONTAL_PIXELS / 8) {
|
||||
attrX = 0;
|
||||
}
|
||||
if (softwareRenderer->sgbAttrY >= GB_VIDEO_VERTICAL_PIXELS / 8) {
|
||||
softwareRenderer->sgbAttrY = 0;
|
||||
if (attrY >= GB_VIDEO_VERTICAL_PIXELS / 8) {
|
||||
attrY = 0;
|
||||
}
|
||||
softwareRenderer->sgbDataSets = softwareRenderer->sgbPacket[3];
|
||||
softwareRenderer->sgbDataSets |= softwareRenderer->sgbPacket[4] << 8;
|
||||
softwareRenderer->sgbAttrDirection = softwareRenderer->sgbPacket[5];
|
||||
sets = softwareRenderer->sgbPacket[3];
|
||||
sets |= softwareRenderer->sgbPacket[4] << 8;
|
||||
attrDirection = softwareRenderer->sgbPacket[5];
|
||||
i = 6;
|
||||
} else {
|
||||
i = 0;
|
||||
}
|
||||
for (; i < 16 && softwareRenderer->sgbDataSets; ++i) {
|
||||
for (; i < (softwareRenderer->sgbCommandHeader & 7) << 4 && sets; ++i) {
|
||||
int j;
|
||||
for (j = 0; j < 4 && softwareRenderer->sgbDataSets; ++j, --softwareRenderer->sgbDataSets) {
|
||||
for (j = 0; j < 4 && sets; ++j, --sets) {
|
||||
uint8_t p = softwareRenderer->sgbPacket[i] >> (6 - j * 2);
|
||||
_setAttribute(renderer->sgbAttributes, softwareRenderer->sgbAttrX, softwareRenderer->sgbAttrY, p & 3);
|
||||
if (softwareRenderer->sgbAttrDirection) {
|
||||
++softwareRenderer->sgbAttrY;
|
||||
if (softwareRenderer->sgbAttrY >= GB_VIDEO_VERTICAL_PIXELS / 8) {
|
||||
softwareRenderer->sgbAttrY = 0;
|
||||
++softwareRenderer->sgbAttrX;
|
||||
_setAttribute(renderer->sgbAttributes, attrX, attrY, p & 3);
|
||||
if (attrDirection) {
|
||||
++attrY;
|
||||
if (attrY >= GB_VIDEO_VERTICAL_PIXELS / 8) {
|
||||
attrY = 0;
|
||||
++attrX;
|
||||
}
|
||||
if (softwareRenderer->sgbAttrX >= GB_VIDEO_HORIZONTAL_PIXELS / 8) {
|
||||
softwareRenderer->sgbAttrX = 0;
|
||||
if (attrX >= GB_VIDEO_HORIZONTAL_PIXELS / 8) {
|
||||
attrX = 0;
|
||||
}
|
||||
} else {
|
||||
++softwareRenderer->sgbAttrX;
|
||||
if (softwareRenderer->sgbAttrX >= GB_VIDEO_HORIZONTAL_PIXELS / 8) {
|
||||
softwareRenderer->sgbAttrX = 0;
|
||||
++softwareRenderer->sgbAttrY;
|
||||
++attrX;
|
||||
if (attrX >= GB_VIDEO_HORIZONTAL_PIXELS / 8) {
|
||||
attrX = 0;
|
||||
++attrY;
|
||||
}
|
||||
if (softwareRenderer->sgbAttrY >= GB_VIDEO_VERTICAL_PIXELS / 8) {
|
||||
softwareRenderer->sgbAttrY = 0;
|
||||
if (attrY >= GB_VIDEO_VERTICAL_PIXELS / 8) {
|
||||
attrY = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -349,23 +378,40 @@ static void GBVideoSoftwareRendererWriteSGBPacket(struct GBVideoRenderer* render
|
|||
|
||||
break;
|
||||
case SGB_ATRC_EN:
|
||||
if (softwareRenderer->sgbBorders) {
|
||||
case SGB_MASK_EN:
|
||||
if (softwareRenderer->sgbBorders && !renderer->sgbRenderMode) {
|
||||
_regenerateSGBBorder(softwareRenderer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void GBVideoSoftwareRendererWritePalette(struct GBVideoRenderer* renderer, int index, uint16_t value) {
|
||||
struct GBVideoSoftwareRenderer* softwareRenderer = (struct GBVideoSoftwareRenderer*) renderer;
|
||||
color_t color = mColorFrom555(value);
|
||||
if (softwareRenderer->model == GB_MODEL_SGB && index < 0x10 && index && !(index & 3)) {
|
||||
if (softwareRenderer->model == GB_MODEL_SGB) {
|
||||
if (index < 0x10 && index && !(index & 3)) {
|
||||
color = softwareRenderer->palette[0];
|
||||
} else if (index >= 0x40 && !(index & 0xF)) {
|
||||
color = softwareRenderer->palette[0];
|
||||
}
|
||||
}
|
||||
softwareRenderer->palette[index] = color;
|
||||
if (renderer->cache) {
|
||||
mCacheSetWritePalette(renderer->cache, index, color);
|
||||
}
|
||||
|
||||
if (softwareRenderer->model == GB_MODEL_SGB && !index && GBRegisterLCDCIsEnable(softwareRenderer->lcdc)) {
|
||||
renderer->writePalette(renderer, 0x04, value);
|
||||
renderer->writePalette(renderer, 0x08, value);
|
||||
renderer->writePalette(renderer, 0x0C, value);
|
||||
renderer->writePalette(renderer, 0x40, value);
|
||||
renderer->writePalette(renderer, 0x50, value);
|
||||
renderer->writePalette(renderer, 0x60, value);
|
||||
renderer->writePalette(renderer, 0x70, value);
|
||||
if (softwareRenderer->sgbBorders && !renderer->sgbRenderMode) {
|
||||
_regenerateSGBBorder(softwareRenderer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void GBVideoSoftwareRendererWriteVRAM(struct GBVideoRenderer* renderer, uint16_t address) {
|
||||
|
@ -580,7 +626,7 @@ static void GBVideoSoftwareRendererFinishFrame(struct GBVideoRenderer* renderer)
|
|||
case SGB_PAL_TRN:
|
||||
case SGB_CHR_TRN:
|
||||
case SGB_PCT_TRN:
|
||||
if (softwareRenderer->sgbTransfer > 0 && softwareRenderer->sgbBorders) {
|
||||
if (softwareRenderer->sgbTransfer > 0 && softwareRenderer->sgbBorders && !renderer->sgbRenderMode) {
|
||||
// Make sure every buffer sees this if we're multibuffering
|
||||
_regenerateSGBBorder(softwareRenderer);
|
||||
}
|
||||
|
|
|
@ -212,9 +212,13 @@ void GBSGBSerialize(struct GB* gb, struct GBSerializedState* state) {
|
|||
GBSerializedSGBFlags flags = 0;
|
||||
flags = GBSerializedSGBFlagsSetP1Bits(flags, gb->currentSgbBits);
|
||||
flags = GBSerializedSGBFlagsSetRenderMode(flags, gb->video.renderer->sgbRenderMode);
|
||||
flags = GBSerializedSGBFlagsSetBufferIndex(flags, gb->video.sgbBufferIndex);
|
||||
flags = GBSerializedSGBFlagsSetReqControllers(flags, gb->sgbControllers);
|
||||
flags = GBSerializedSGBFlagsSetCurrentController(flags, gb->sgbCurrentController);
|
||||
STORE_32LE(flags, 0, &state->sgb.flags);
|
||||
|
||||
memcpy(state->sgb.packet, gb->sgbPacket, sizeof(state->sgb.packet));
|
||||
memcpy(state->sgb.packet, gb->video.sgbPacketBuffer, sizeof(state->sgb.packet));
|
||||
memcpy(state->sgb.inProgressPacket, gb->sgbPacket, sizeof(state->sgb.inProgressPacket));
|
||||
|
||||
if (gb->video.renderer->sgbCharRam) {
|
||||
memcpy(state->sgb.charRam, gb->video.renderer->sgbCharRam, sizeof(state->sgb.charRam));
|
||||
|
@ -241,8 +245,12 @@ void GBSGBDeserialize(struct GB* gb, const struct GBSerializedState* state) {
|
|||
LOAD_32LE(flags, 0, &state->sgb.flags);
|
||||
gb->currentSgbBits = GBSerializedSGBFlagsGetP1Bits(flags);
|
||||
gb->video.renderer->sgbRenderMode = GBSerializedSGBFlagsGetRenderMode(flags);
|
||||
gb->video.sgbBufferIndex = GBSerializedSGBFlagsGetBufferIndex(flags);
|
||||
gb->sgbControllers = GBSerializedSGBFlagsGetReqControllers(flags);
|
||||
gb->sgbCurrentController = GBSerializedSGBFlagsGetCurrentController(flags);
|
||||
|
||||
memcpy(gb->sgbPacket, state->sgb.packet, sizeof(state->sgb.packet));
|
||||
memcpy(gb->video.sgbPacketBuffer, state->sgb.packet, sizeof(state->sgb.packet));
|
||||
memcpy(gb->sgbPacket, state->sgb.inProgressPacket, sizeof(state->sgb.inProgressPacket));
|
||||
|
||||
if (!gb->video.renderer->sgbCharRam) {
|
||||
gb->video.renderer->sgbCharRam = anonymousMemoryMap(SGB_SIZE_CHAR_RAM);
|
||||
|
@ -267,5 +275,4 @@ void GBSGBDeserialize(struct GB* gb, const struct GBSerializedState* state) {
|
|||
memcpy(gb->video.renderer->sgbAttributes, state->sgb.attributes, sizeof(state->sgb.attributes));
|
||||
|
||||
GBVideoWriteSGBPacket(&gb->video, (uint8_t[16]) { (SGB_ATRC_EN << 3) | 1, 0 });
|
||||
GBVideoWriteSGBPacket(&gb->video, gb->sgbPacket);
|
||||
}
|
||||
|
|
|
@ -113,6 +113,7 @@ void GBVideoReset(struct GBVideo* video) {
|
|||
video->renderer->sgbAttributes = malloc(90 * 45);
|
||||
memset(video->renderer->sgbAttributes, 0, 90 * 45);
|
||||
video->sgbCommandHeader = 0;
|
||||
video->sgbBufferIndex = 0;
|
||||
}
|
||||
|
||||
video->palette[0] = video->dmgPalette[0];
|
||||
|
@ -580,6 +581,7 @@ void GBVideoDisableCGB(struct GBVideo* video) {
|
|||
void GBVideoWriteSGBPacket(struct GBVideo* video, uint8_t* data) {
|
||||
int i;
|
||||
if (!(video->sgbCommandHeader & 7)) {
|
||||
video->sgbBufferIndex = 0;
|
||||
if ((data[0] >> 3) > SGB_OBJ_TRN) {
|
||||
video->sgbCommandHeader = 0;
|
||||
return;
|
||||
|
@ -587,20 +589,25 @@ void GBVideoWriteSGBPacket(struct GBVideo* video, uint8_t* data) {
|
|||
video->sgbCommandHeader = data[0];
|
||||
}
|
||||
--video->sgbCommandHeader;
|
||||
memcpy(&video->sgbPacketBuffer[video->sgbBufferIndex << 4], data, 16);
|
||||
++video->sgbBufferIndex;
|
||||
if (video->sgbCommandHeader & 7) {
|
||||
return;
|
||||
}
|
||||
switch (video->sgbCommandHeader >> 3) {
|
||||
case SGB_PAL01:
|
||||
video->palette[0] = data[1] | (data[2] << 8);
|
||||
video->palette[1] = data[3] | (data[4] << 8);
|
||||
video->palette[2] = data[5] | (data[6] << 8);
|
||||
video->palette[3] = data[7] | (data[8] << 8);
|
||||
video->palette[0] = video->sgbPacketBuffer[1] | (video->sgbPacketBuffer[2] << 8);
|
||||
video->palette[1] = video->sgbPacketBuffer[3] | (video->sgbPacketBuffer[4] << 8);
|
||||
video->palette[2] = video->sgbPacketBuffer[5] | (video->sgbPacketBuffer[6] << 8);
|
||||
video->palette[3] = video->sgbPacketBuffer[7] | (video->sgbPacketBuffer[8] << 8);
|
||||
|
||||
video->palette[4] = data[1] | (data[2] << 8);
|
||||
video->palette[5] = data[9] | (data[10] << 8);
|
||||
video->palette[6] = data[11] | (data[12] << 8);
|
||||
video->palette[7] = data[13] | (data[14] << 8);
|
||||
video->palette[4] = video->sgbPacketBuffer[1] | (video->sgbPacketBuffer[2] << 8);
|
||||
video->palette[5] = video->sgbPacketBuffer[9] | (video->sgbPacketBuffer[10] << 8);
|
||||
video->palette[6] = video->sgbPacketBuffer[11] | (video->sgbPacketBuffer[12] << 8);
|
||||
video->palette[7] = video->sgbPacketBuffer[13] | (video->sgbPacketBuffer[14] << 8);
|
||||
|
||||
video->palette[8] = data[1] | (data[2] << 8);
|
||||
video->palette[12] = data[1] | (data[2] << 8);
|
||||
video->palette[8] = video->sgbPacketBuffer[1] | (video->sgbPacketBuffer[2] << 8);
|
||||
video->palette[12] = video->sgbPacketBuffer[1] | (video->sgbPacketBuffer[2] << 8);
|
||||
|
||||
video->renderer->writePalette(video->renderer, 0, video->palette[0]);
|
||||
video->renderer->writePalette(video->renderer, 1, video->palette[1]);
|
||||
|
@ -614,13 +621,13 @@ void GBVideoWriteSGBPacket(struct GBVideo* video, uint8_t* data) {
|
|||
video->renderer->writePalette(video->renderer, 12, video->palette[12]);
|
||||
break;
|
||||
case SGB_PAL23:
|
||||
video->palette[9] = data[3] | (data[4] << 8);
|
||||
video->palette[10] = data[5] | (data[6] << 8);
|
||||
video->palette[11] = data[7] | (data[8] << 8);
|
||||
video->palette[9] = video->sgbPacketBuffer[3] | (video->sgbPacketBuffer[4] << 8);
|
||||
video->palette[10] = video->sgbPacketBuffer[5] | (video->sgbPacketBuffer[6] << 8);
|
||||
video->palette[11] = video->sgbPacketBuffer[7] | (video->sgbPacketBuffer[8] << 8);
|
||||
|
||||
video->palette[13] = data[9] | (data[10] << 8);
|
||||
video->palette[14] = data[11] | (data[12] << 8);
|
||||
video->palette[15] = data[13] | (data[14] << 8);
|
||||
video->palette[13] = video->sgbPacketBuffer[9] | (video->sgbPacketBuffer[10] << 8);
|
||||
video->palette[14] = video->sgbPacketBuffer[11] | (video->sgbPacketBuffer[12] << 8);
|
||||
video->palette[15] = video->sgbPacketBuffer[13] | (video->sgbPacketBuffer[14] << 8);
|
||||
video->renderer->writePalette(video->renderer, 9, video->palette[9]);
|
||||
video->renderer->writePalette(video->renderer, 10, video->palette[10]);
|
||||
video->renderer->writePalette(video->renderer, 11, video->palette[11]);
|
||||
|
@ -629,18 +636,18 @@ void GBVideoWriteSGBPacket(struct GBVideo* video, uint8_t* data) {
|
|||
video->renderer->writePalette(video->renderer, 15, video->palette[15]);
|
||||
break;
|
||||
case SGB_PAL03:
|
||||
video->palette[0] = data[1] | (data[2] << 8);
|
||||
video->palette[1] = data[3] | (data[4] << 8);
|
||||
video->palette[2] = data[5] | (data[6] << 8);
|
||||
video->palette[3] = data[7] | (data[8] << 8);
|
||||
video->palette[0] = video->sgbPacketBuffer[1] | (video->sgbPacketBuffer[2] << 8);
|
||||
video->palette[1] = video->sgbPacketBuffer[3] | (video->sgbPacketBuffer[4] << 8);
|
||||
video->palette[2] = video->sgbPacketBuffer[5] | (video->sgbPacketBuffer[6] << 8);
|
||||
video->palette[3] = video->sgbPacketBuffer[7] | (video->sgbPacketBuffer[8] << 8);
|
||||
|
||||
video->palette[4] = data[1] | (data[2] << 8);
|
||||
video->palette[8] = data[1] | (data[2] << 8);
|
||||
video->palette[4] = video->sgbPacketBuffer[1] | (video->sgbPacketBuffer[2] << 8);
|
||||
video->palette[8] = video->sgbPacketBuffer[1] | (video->sgbPacketBuffer[2] << 8);
|
||||
|
||||
video->palette[12] = data[1] | (data[2] << 8);
|
||||
video->palette[13] = data[9] | (data[10] << 8);
|
||||
video->palette[14] = data[11] | (data[12] << 8);
|
||||
video->palette[15] = data[13] | (data[14] << 8);
|
||||
video->palette[12] = video->sgbPacketBuffer[1] | (video->sgbPacketBuffer[2] << 8);
|
||||
video->palette[13] = video->sgbPacketBuffer[9] | (video->sgbPacketBuffer[10] << 8);
|
||||
video->palette[14] = video->sgbPacketBuffer[11] | (video->sgbPacketBuffer[12] << 8);
|
||||
video->palette[15] = video->sgbPacketBuffer[13] | (video->sgbPacketBuffer[14] << 8);
|
||||
video->renderer->writePalette(video->renderer, 0, video->palette[0]);
|
||||
video->renderer->writePalette(video->renderer, 1, video->palette[1]);
|
||||
video->renderer->writePalette(video->renderer, 2, video->palette[2]);
|
||||
|
@ -653,13 +660,13 @@ void GBVideoWriteSGBPacket(struct GBVideo* video, uint8_t* data) {
|
|||
video->renderer->writePalette(video->renderer, 15, video->palette[15]);
|
||||
break;
|
||||
case SGB_PAL12:
|
||||
video->palette[5] = data[3] | (data[4] << 8);
|
||||
video->palette[6] = data[5] | (data[6] << 8);
|
||||
video->palette[7] = data[7] | (data[8] << 8);
|
||||
video->palette[5] = video->sgbPacketBuffer[3] | (video->sgbPacketBuffer[4] << 8);
|
||||
video->palette[6] = video->sgbPacketBuffer[5] | (video->sgbPacketBuffer[6] << 8);
|
||||
video->palette[7] = video->sgbPacketBuffer[7] | (video->sgbPacketBuffer[8] << 8);
|
||||
|
||||
video->palette[9] = data[9] | (data[10] << 8);
|
||||
video->palette[10] = data[11] | (data[12] << 8);
|
||||
video->palette[11] = data[13] | (data[14] << 8);
|
||||
video->palette[9] = video->sgbPacketBuffer[9] | (video->sgbPacketBuffer[10] << 8);
|
||||
video->palette[10] = video->sgbPacketBuffer[11] | (video->sgbPacketBuffer[12] << 8);
|
||||
video->palette[11] = video->sgbPacketBuffer[13] | (video->sgbPacketBuffer[14] << 8);
|
||||
video->renderer->writePalette(video->renderer, 5, video->palette[5]);
|
||||
video->renderer->writePalette(video->renderer, 6, video->palette[6]);
|
||||
video->renderer->writePalette(video->renderer, 7, video->palette[7]);
|
||||
|
@ -669,7 +676,7 @@ void GBVideoWriteSGBPacket(struct GBVideo* video, uint8_t* data) {
|
|||
break;
|
||||
case SGB_PAL_SET:
|
||||
for (i = 0; i < 4; ++i) {
|
||||
uint16_t entry = (data[2 + (i * 2)] << 8) | data[1 + (i * 2)];
|
||||
uint16_t entry = (video->sgbPacketBuffer[2 + (i * 2)] << 8) | video->sgbPacketBuffer[1 + (i * 2)];
|
||||
if (entry >= 0x200) {
|
||||
mLOG(GB, STUB, "Unimplemented SGB palette overflow: %03X", entry);
|
||||
continue;
|
||||
|
@ -685,6 +692,7 @@ void GBVideoWriteSGBPacket(struct GBVideo* video, uint8_t* data) {
|
|||
}
|
||||
break;
|
||||
case SGB_ATTR_BLK:
|
||||
case SGB_ATTR_DIV:
|
||||
case SGB_ATTR_CHR:
|
||||
case SGB_PAL_TRN:
|
||||
case SGB_ATRC_EN:
|
||||
|
@ -693,16 +701,17 @@ void GBVideoWriteSGBPacket(struct GBVideo* video, uint8_t* data) {
|
|||
case SGB_ATTR_TRN:
|
||||
case SGB_ATTR_SET:
|
||||
break;
|
||||
case SGB_MLT_REG:
|
||||
case SGB_MLT_REQ:
|
||||
video->p->sgbControllers = video->sgbPacketBuffer[1] & 0x3;
|
||||
return;
|
||||
case SGB_MASK_EN:
|
||||
video->renderer->sgbRenderMode = data[1] & 0x3;
|
||||
video->renderer->sgbRenderMode = video->sgbPacketBuffer[1] & 0x3;
|
||||
break;
|
||||
default:
|
||||
mLOG(GB, STUB, "Unimplemented SGB command: %02X", data[0] >> 3);
|
||||
mLOG(GB, STUB, "Unimplemented SGB command: %02X", video->sgbPacketBuffer[0] >> 3);
|
||||
return;
|
||||
}
|
||||
video->renderer->writeSGBPacket(video->renderer, data);
|
||||
video->renderer->writeSGBPacket(video->renderer, video->sgbPacketBuffer);
|
||||
}
|
||||
|
||||
static void GBVideoDummyRendererInit(struct GBVideoRenderer* renderer, enum GBModel model, bool borders) {
|
||||
|
|
Loading…
Reference in New Issue