Permalink
Browse files

Qt: Add layer placement features

  • Loading branch information...
endrift committed Apr 27, 2018
1 parent 8ea524d commit 67a135e5e7a5d6366f516972f25e7c71bff91447
View
@@ -49,6 +49,7 @@ Misc:
- GBA Memory: 64 MiB GBA Video cartridge support
- PSP2: Use system enter key by default
- 3DS: Remove deprecated CSND interface
+ - Qt: Options to mess around with layer placement
0.6.3: (2017-04-14)
Bugfixes:
View
@@ -153,6 +153,7 @@ struct mCore {
size_t (*listAudioChannels)(const struct mCore*, const struct mCoreChannelInfo**);
void (*enableVideoLayer)(struct mCore*, size_t id, bool enable);
void (*enableAudioChannel)(struct mCore*, size_t id, bool enable);
+ void (*adjustVideoLayer)(struct mCore*, size_t id, int32_t x, int32_t y);
#ifndef MINIMAL_CORE
void (*startVideoLog)(struct mCore*, struct mVideoLogContext*);
@@ -38,6 +38,13 @@ struct GBVideoSoftwareRenderer {
GBRegisterLCDC lcdc;
enum GBModel model;
+ int16_t objOffsetX;
+ int16_t objOffsetY;
+ int16_t offsetScx;
+ int16_t offsetScy;
+ int16_t offsetWx;
+ int16_t offsetWy;
+
int sgbTransfer;
uint8_t sgbPacket[128];
uint8_t sgbCommandHeader;
@@ -44,6 +44,8 @@ struct GBAVideoSoftwareBackground {
int32_t sy;
int yCache;
uint16_t mapCache[64];
+ int32_t offsetX;
+ int32_t offsetY;
};
enum BlendEffect {
@@ -159,6 +161,8 @@ struct GBAVideoSoftwareRenderer {
int oamDirty;
int oamMax;
struct GBAVideoSoftwareSprite sprites[128];
+ int16_t objOffsetX;
+ int16_t objOffsetY;
uint32_t scanlineDirty[5];
uint16_t nextIo[REG_SOUND1CNT_LO];
View
@@ -791,13 +791,17 @@ static bool _GBCoreSavedataRestore(struct mCore* core, const void* sram, size_t
static size_t _GBCoreListVideoLayers(const struct mCore* core, const struct mCoreChannelInfo** info) {
UNUSED(core);
- *info = _GBVideoLayers;
+ if (info) {
+ *info = _GBVideoLayers;
+ }
return sizeof(_GBVideoLayers) / sizeof(*_GBVideoLayers);
}
static size_t _GBCoreListAudioChannels(const struct mCore* core, const struct mCoreChannelInfo** info) {
UNUSED(core);
- *info = _GBAudioChannels;
+ if (info) {
+ *info = _GBAudioChannels;
+ }
return sizeof(_GBAudioChannels) / sizeof(*_GBAudioChannels);
}
@@ -832,6 +836,26 @@ static void _GBCoreEnableAudioChannel(struct mCore* core, size_t id, bool enable
}
}
+static void _GBCoreAdjustVideoLayer(struct mCore* core, size_t id, int32_t x, int32_t y) {
+ struct GBCore* gbcore = (struct GBCore*) core;
+ switch (id) {
+ case 0:
+ gbcore->renderer.offsetScx = x;
+ gbcore->renderer.offsetScy = y;
+ break;
+ case 1:
+ gbcore->renderer.offsetWx = x;
+ gbcore->renderer.offsetWy = y;
+ break;
+ case 2:
+ gbcore->renderer.objOffsetX = x;
+ gbcore->renderer.objOffsetY = y;
+ break;
+ default:
+ return;
+ }
+}
+
#ifndef MINIMAL_CORE
static void _GBCoreStartVideoLog(struct mCore* core, struct mVideoLogContext* context) {
struct GBCore* gbcore = (struct GBCore*) core;
@@ -934,6 +958,7 @@ struct mCore* GBCoreCreate(void) {
core->listAudioChannels = _GBCoreListAudioChannels;
core->enableVideoLayer = _GBCoreEnableVideoLayer;
core->enableAudioChannel = _GBCoreEnableAudioChannel;
+ core->adjustVideoLayer = _GBCoreAdjustVideoLayer;
#ifndef MINIMAL_CORE
core->startVideoLog = _GBCoreStartVideoLog;
core->endVideoLog = _GBCoreEndVideoLog;
@@ -198,6 +198,13 @@ static void GBVideoSoftwareRendererInit(struct GBVideoRenderer* renderer, enum G
softwareRenderer->sgbTransfer = 0;
softwareRenderer->sgbCommandHeader = 0;
softwareRenderer->sgbBorders = sgbBorders;
+ softwareRenderer->objOffsetX = 0;
+ softwareRenderer->objOffsetY = 0;
+ softwareRenderer->offsetScx = 0;
+ softwareRenderer->offsetScy = 0;
+ softwareRenderer->offsetWx = 0;
+ softwareRenderer->offsetWy = 0;
+
int i;
for (i = 0; i < 64; ++i) {
softwareRenderer->lookup[i] = i;
@@ -471,18 +478,18 @@ static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, i
int wy = softwareRenderer->wy + softwareRenderer->currentWy;
if (GBRegisterLCDCIsWindow(softwareRenderer->lcdc) && wy <= y && endX >= softwareRenderer->wx - 7) {
if (softwareRenderer->wx - 7 > 0 && !softwareRenderer->d.disableBG) {
- GBVideoSoftwareRendererDrawBackground(softwareRenderer, maps, startX, softwareRenderer->wx - 7, softwareRenderer->scx, softwareRenderer->scy + y);
+ GBVideoSoftwareRendererDrawBackground(softwareRenderer, maps, startX, softwareRenderer->wx - 7, softwareRenderer->scx - softwareRenderer->offsetScx, softwareRenderer->scy + y - softwareRenderer->offsetScy);
}
maps = &softwareRenderer->d.vram[GB_BASE_MAP];
if (GBRegisterLCDCIsWindowTileMap(softwareRenderer->lcdc)) {
maps += GB_SIZE_MAP;
}
if (!softwareRenderer->d.disableWIN) {
- GBVideoSoftwareRendererDrawBackground(softwareRenderer, maps, softwareRenderer->wx - 7, endX, 7 - softwareRenderer->wx, y - wy);
+ GBVideoSoftwareRendererDrawBackground(softwareRenderer, maps, softwareRenderer->wx - 7, endX, 7 - softwareRenderer->wx - softwareRenderer->offsetWx, y - wy - softwareRenderer->offsetWy);
}
} else if (!softwareRenderer->d.disableBG) {
- GBVideoSoftwareRendererDrawBackground(softwareRenderer, maps, startX, endX, softwareRenderer->scx, softwareRenderer->scy + y);
+ GBVideoSoftwareRendererDrawBackground(softwareRenderer, maps, startX, endX, softwareRenderer->scx - softwareRenderer->offsetScx, softwareRenderer->scy + y - softwareRenderer->offsetScy);
}
} else if (!softwareRenderer->d.disableBG) {
memset(&softwareRenderer->row[startX], 0, endX - startX);
@@ -778,30 +785,32 @@ static void GBVideoSoftwareRendererDrawBackground(struct GBVideoSoftwareRenderer
}
static void GBVideoSoftwareRendererDrawObj(struct GBVideoSoftwareRenderer* renderer, struct GBObj* obj, int startX, int endX, int y) {
- int ix = obj->x - 8;
+ int objX = obj->x + renderer->objOffsetX;
+ int ix = objX - 8;
if (endX < ix || startX >= ix + 8) {
return;
}
- if (obj->x < endX) {
- endX = obj->x;
+ if (objX < endX) {
+ endX = objX;
}
- if (obj->x - 8 > startX) {
- startX = obj->x - 8;
+ if (objX - 8 > startX) {
+ startX = objX - 8;
}
if (startX < 0) {
startX = 0;
}
uint8_t* data = renderer->d.vram;
int tileOffset = 0;
int bottomY;
+ int objY = obj->y + renderer->objOffsetY;
if (GBObjAttributesIsYFlip(obj->attr)) {
- bottomY = 7 - ((y - obj->y - 16) & 7);
- if (GBRegisterLCDCIsObjSize(renderer->lcdc) && y - obj->y < -8) {
+ bottomY = 7 - ((y - objY - 16) & 7);
+ if (GBRegisterLCDCIsObjSize(renderer->lcdc) && y - objY < -8) {
++tileOffset;
}
} else {
- bottomY = (y - obj->y - 16) & 7;
- if (GBRegisterLCDCIsObjSize(renderer->lcdc) && y - obj->y >= -8) {
+ bottomY = (y - objY - 16) & 7;
+ if (GBRegisterLCDCIsObjSize(renderer->lcdc) && y - objY >= -8) {
++tileOffset;
}
}
@@ -825,12 +834,12 @@ static void GBVideoSoftwareRendererDrawObj(struct GBVideoSoftwareRenderer* rende
}
int bottomX;
int x = startX;
- if ((x - obj->x) & 7) {
+ if ((x - objX) & 7) {
for (; x < endX; ++x) {
if (GBObjAttributesIsXFlip(obj->attr)) {
- bottomX = (x - obj->x) & 7;
+ bottomX = (x - objX) & 7;
} else {
- bottomX = 7 - ((x - obj->x) & 7);
+ bottomX = 7 - ((x - objX) & 7);
}
int objTile = obj->tile + tileOffset;
uint8_t tileDataLower = data[(objTile * 8 + bottomY) * 2];
View
@@ -795,13 +795,17 @@ static bool _GBACoreSavedataRestore(struct mCore* core, const void* sram, size_t
static size_t _GBACoreListVideoLayers(const struct mCore* core, const struct mCoreChannelInfo** info) {
UNUSED(core);
- *info = _GBAVideoLayers;
+ if (info) {
+ *info = _GBAVideoLayers;
+ }
return sizeof(_GBAVideoLayers) / sizeof(*_GBAVideoLayers);
}
static size_t _GBACoreListAudioChannels(const struct mCore* core, const struct mCoreChannelInfo** info) {
UNUSED(core);
- *info = _GBAAudioChannels;
+ if (info) {
+ *info = _GBAAudioChannels;
+ }
return sizeof(_GBAAudioChannels) / sizeof(*_GBAAudioChannels);
}
@@ -841,6 +845,27 @@ static void _GBACoreEnableAudioChannel(struct mCore* core, size_t id, bool enabl
}
}
+static void _GBACoreAdjustVideoLayer(struct mCore* core, size_t id, int32_t x, int32_t y) {
+ struct GBACore* gbacore = (struct GBACore*) core;
+ switch (id) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ gbacore->renderer.bg[id].offsetX = x;
+ gbacore->renderer.bg[id].offsetY = y;
+ break;
+ case 4:
+ gbacore->renderer.objOffsetX = x;
+ gbacore->renderer.objOffsetY = y;
+ gbacore->renderer.oamDirty = 1;
+ break;
+ default:
+ return;
+ }
+ memset(gbacore->renderer.scanlineDirty, 0xFFFFFFFF, sizeof(gbacore->renderer.scanlineDirty));
+}
+
#ifndef MINIMAL_CORE
static void _GBACoreStartVideoLog(struct mCore* core, struct mVideoLogContext* context) {
struct GBACore* gbacore = (struct GBACore*) core;
@@ -946,6 +971,7 @@ struct mCore* GBACoreCreate(void) {
core->listAudioChannels = _GBACoreListAudioChannels;
core->enableVideoLayer = _GBACoreEnableVideoLayer;
core->enableAudioChannel = _GBACoreEnableAudioChannel;
+ core->adjustVideoLayer = _GBACoreAdjustVideoLayer;
#ifndef MINIMAL_CORE
core->startVideoLog = _GBACoreStartVideoLog;
core->endVideoLog = _GBACoreEndVideoLog;
@@ -446,13 +446,13 @@
}
void GBAVideoSoftwareRendererDrawBackgroundMode0(struct GBAVideoSoftwareRenderer* renderer, struct GBAVideoSoftwareBackground* background, int y) {
- int inX = (renderer->start + background->x) & 0x1FF;
+ int inX = (renderer->start + background->x - background->offsetX) & 0x1FF;
int length = renderer->end - renderer->start;
if (background->mosaic) {
int mosaicV = GBAMosaicControlGetBgV(renderer->mosaic) + 1;
y -= y % mosaicV;
}
- int inY = y + background->y;
+ int inY = y + background->y - background->offsetY;
uint16_t mapData;
unsigned yBase = inY & 0xF8;
@@ -147,6 +147,7 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re
}
int32_t x = (uint32_t) GBAObjAttributesBGetX(sprite->b) << 23;
x >>= 23;
+ x += renderer->objOffsetX;
uint16_t* vramBase = &renderer->d.vram[BASE_TILE >> 1];
bool align = GBAObjAttributesAIs256Color(sprite->a) && !GBARegisterDISPCNTIsObjCharacterMapping(renderer->dispcnt);
unsigned charBase = (GBAObjAttributesCGetTile(sprite->c) & ~align) * 0x20;
@@ -185,7 +186,7 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re
}
}
- int inY = y - (int) GBAObjAttributesAGetY(sprite->a);
+ int inY = y - ((int) GBAObjAttributesAGetY(sprite->a) + renderer->objOffsetY);
int stride = GBARegisterDISPCNTIsObjCharacterMapping(renderer->dispcnt) ? (width >> !GBAObjAttributesAIs256Color(sprite->a)) : 0x80;
uint32_t current;
@@ -114,6 +114,9 @@ static void GBAVideoSoftwareRendererReset(struct GBAVideoRenderer* renderer) {
softwareRenderer->mosaic = 0;
softwareRenderer->nextY = 0;
+ softwareRenderer->objOffsetX = 0;
+ softwareRenderer->objOffsetY = 0;
+
memset(softwareRenderer->scanlineDirty, 0xFFFFFFFF, sizeof(softwareRenderer->scanlineDirty));
memset(softwareRenderer->cache, 0, sizeof(softwareRenderer->cache));
memset(softwareRenderer->nextIo, 0, sizeof(softwareRenderer->nextIo));
@@ -142,6 +145,8 @@ static void GBAVideoSoftwareRendererReset(struct GBAVideoRenderer* renderer) {
bg->sx = 0;
bg->sy = 0;
bg->yCache = -1;
+ bg->offsetX = 0;
+ bg->offsetY = 0;
}
}
@@ -507,8 +512,9 @@ static void _cleanOAM(struct GBAVideoSoftwareRenderer* renderer) {
height <<= GBAObjAttributesAGetDoubleSize(obj.a);
}
if (GBAObjAttributesAGetY(obj.a) < VIDEO_VERTICAL_PIXELS || GBAObjAttributesAGetY(obj.a) + height >= VIDEO_VERTICAL_TOTAL_PIXELS) {
- renderer->sprites[oamMax].y = GBAObjAttributesAGetY(obj.a);
- renderer->sprites[oamMax].endY = GBAObjAttributesAGetY(obj.a) + height;
+ int y = GBAObjAttributesAGetY(obj.a) + renderer->objOffsetY;
+ renderer->sprites[oamMax].y = y;
+ renderer->sprites[oamMax].endY = y + height;
renderer->sprites[oamMax].obj = obj;
++oamMax;
}
@@ -102,6 +102,7 @@ set(SOURCE_FILES
ObjView.cpp
OverrideView.cpp
PaletteView.cpp
+ PlacementControl.cpp
PrinterView.cpp
RegisterView.cpp
ROMInfo.cpp
@@ -135,6 +136,7 @@ set(UI_FILES
ObjView.ui
OverrideView.ui
PaletteView.ui
+ PlacementControl.ui
PrinterView.ui
ROMInfo.ui
SensorView.ui
Oops, something went wrong.

0 comments on commit 67a135e

Please sign in to comment.