mirror of https://github.com/mgba-emu/mgba.git
Add dummy renderer + frame counting infrastructure from GBA.js
This commit is contained in:
parent
9b5d5d6478
commit
2fe2c80ae5
|
@ -100,7 +100,7 @@ void ARMReset(struct ARMCore* cpu) {
|
||||||
cpu->spsr.packed = 0;
|
cpu->spsr.packed = 0;
|
||||||
|
|
||||||
cpu->cycles = 0;
|
cpu->cycles = 0;
|
||||||
cpu->nextEvent = INT_MAX;
|
cpu->nextEvent = 0;
|
||||||
|
|
||||||
cpu->shifterOperand = 0;
|
cpu->shifterOperand = 0;
|
||||||
cpu->shifterCarryOut = 0;
|
cpu->shifterCarryOut = 0;
|
||||||
|
|
|
@ -2,7 +2,23 @@
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
|
static void GBAVideoDummyRendererInit(struct GBAVideoRenderer* renderer);
|
||||||
|
static void GBAVideoDummyRendererDeinit(struct GBAVideoRenderer* renderer);
|
||||||
|
static uint16_t GBAVideoDummyRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value);
|
||||||
|
static void GBAVideoDummyRendererDrawScanline(struct GBAVideoRenderer* renderer, int y);
|
||||||
|
static void GBAVideoDummyRendererFinishFrame(struct GBAVideoRenderer* renderer);
|
||||||
|
|
||||||
|
static struct GBAVideoRenderer dummyRenderer = {
|
||||||
|
.init = GBAVideoDummyRendererInit,
|
||||||
|
.deinit = GBAVideoDummyRendererDeinit,
|
||||||
|
.writeVideoRegister = GBAVideoDummyRendererWriteVideoRegister,
|
||||||
|
.drawScanline = GBAVideoDummyRendererDrawScanline,
|
||||||
|
.finishFrame = GBAVideoDummyRendererFinishFrame
|
||||||
|
};
|
||||||
|
|
||||||
void GBAVideoInit(struct GBAVideo* video) {
|
void GBAVideoInit(struct GBAVideo* video) {
|
||||||
|
video->renderer = &dummyRenderer;
|
||||||
|
|
||||||
video->inHblank = 0;
|
video->inHblank = 0;
|
||||||
video->inVblank = 0;
|
video->inVblank = 0;
|
||||||
video->vcounter = 0;
|
video->vcounter = 0;
|
||||||
|
@ -23,5 +39,94 @@ void GBAVideoInit(struct GBAVideo* video) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t GBAVideoProcessEvents(struct GBAVideo* video, int32_t cycles) {
|
int32_t GBAVideoProcessEvents(struct GBAVideo* video, int32_t cycles) {
|
||||||
return INT_MAX;
|
video->nextEvent -= cycles;
|
||||||
|
if (video->nextEvent <= 0) {
|
||||||
|
video->lastHblank -= video->eventDiff;
|
||||||
|
video->nextHblank -= video->eventDiff;
|
||||||
|
video->nextHblankIRQ -= video->eventDiff;
|
||||||
|
video->nextVcounterIRQ -= video->eventDiff;
|
||||||
|
|
||||||
|
if (video->inHblank) {
|
||||||
|
// End Hblank
|
||||||
|
video->inHblank = 0;
|
||||||
|
video->nextEvent = video->nextHblank;
|
||||||
|
|
||||||
|
++video->vcount;
|
||||||
|
|
||||||
|
switch (video->vcount) {
|
||||||
|
case VIDEO_VERTICAL_PIXELS:
|
||||||
|
video->inVblank = 1;
|
||||||
|
video->renderer->finishFrame(video->renderer);
|
||||||
|
video->nextVblankIRQ = video->nextEvent + VIDEO_TOTAL_LENGTH;
|
||||||
|
//video->cpu.mmu.runVblankDmas();
|
||||||
|
if (video->vblankIRQ) {
|
||||||
|
//video->cpu.irq.raiseIRQ(video->cpu.irq.IRQ_VBLANK);
|
||||||
|
}
|
||||||
|
//video->vblankCallback();
|
||||||
|
break;
|
||||||
|
case VIDEO_VERTICAL_TOTAL_PIXELS - 1:
|
||||||
|
video->inVblank = 0;
|
||||||
|
break;
|
||||||
|
case VIDEO_VERTICAL_TOTAL_PIXELS:
|
||||||
|
video->vcount = 0;
|
||||||
|
//video->renderPath.startDraw();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
video->vcounter = video->vcount == video->vcountSetting;
|
||||||
|
if (video->vcounter && video->vcounterIRQ) {
|
||||||
|
//video->cpu.irq.raiseIRQ(video->cpu.irq.IRQ_VCOUNTER);
|
||||||
|
video->nextVcounterIRQ += VIDEO_TOTAL_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (video->vcount < VIDEO_VERTICAL_PIXELS) {
|
||||||
|
video->renderer->drawScanline(video->renderer, video->vcount);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Begin Hblank
|
||||||
|
video->inHblank = 1;
|
||||||
|
video->lastHblank = video->nextHblank;
|
||||||
|
video->nextEvent = video->lastHblank + VIDEO_HBLANK_LENGTH;
|
||||||
|
video->nextHblank = video->nextEvent + VIDEO_HDRAW_LENGTH;
|
||||||
|
video->nextHblankIRQ = video->nextHblank;
|
||||||
|
|
||||||
|
if (video->vcount < VIDEO_VERTICAL_PIXELS) {
|
||||||
|
//video->cpu.mmu.runHblankDmas();
|
||||||
|
}
|
||||||
|
if (video->hblankIRQ) {
|
||||||
|
//video->cpu.irq.raiseIRQ(video->cpu.irq.IRQ_HBLANK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
video->eventDiff = video->nextEvent;
|
||||||
|
}
|
||||||
|
return video->nextEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void GBAVideoDummyRendererInit(struct GBAVideoRenderer* renderer) {
|
||||||
|
(void)(renderer);
|
||||||
|
// Nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GBAVideoDummyRendererDeinit(struct GBAVideoRenderer* renderer) {
|
||||||
|
(void)(renderer);
|
||||||
|
// Nothing to do
|
||||||
|
}
|
||||||
|
static uint16_t GBAVideoDummyRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value) {
|
||||||
|
(void)(renderer);
|
||||||
|
(void)(address);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GBAVideoDummyRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) {
|
||||||
|
(void)(renderer);
|
||||||
|
(void)(y);
|
||||||
|
// Nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GBAVideoDummyRendererFinishFrame(struct GBAVideoRenderer* renderer) {
|
||||||
|
(void)(renderer);
|
||||||
|
printf("Drawing a frame\n");
|
||||||
|
// Nothing to do
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,12 +26,13 @@ struct GBAVideoRenderer {
|
||||||
void (*deinit)(struct GBAVideoRenderer* renderer);
|
void (*deinit)(struct GBAVideoRenderer* renderer);
|
||||||
|
|
||||||
uint16_t (*writeVideoRegister)(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value);
|
uint16_t (*writeVideoRegister)(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value);
|
||||||
void (*drawScanline)(struct GBAVideoRenderer* video, int y);
|
void (*drawScanline)(struct GBAVideoRenderer* renderer, int y);
|
||||||
void (*finishFrame)(struct GBAVideoRenderer* video);
|
void (*finishFrame)(struct GBAVideoRenderer* renderer);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GBAVideo {
|
struct GBAVideo {
|
||||||
struct GBAVideoRenderer renderer;
|
struct GBA* p;
|
||||||
|
struct GBAVideoRenderer* renderer;
|
||||||
|
|
||||||
// DISPSTAT
|
// DISPSTAT
|
||||||
int inHblank;
|
int inHblank;
|
||||||
|
@ -49,6 +50,7 @@ struct GBAVideo {
|
||||||
int32_t lastHblank;
|
int32_t lastHblank;
|
||||||
int32_t nextHblank;
|
int32_t nextHblank;
|
||||||
int32_t nextEvent;
|
int32_t nextEvent;
|
||||||
|
int32_t eventDiff;
|
||||||
|
|
||||||
int32_t nextHblankIRQ;
|
int32_t nextHblankIRQ;
|
||||||
int32_t nextVblankIRQ;
|
int32_t nextVblankIRQ;
|
||||||
|
|
|
@ -33,6 +33,9 @@ void GBAInit(struct GBA* gba) {
|
||||||
GBABoardInit(&gba->board);
|
GBABoardInit(&gba->board);
|
||||||
ARMAssociateBoard(&gba->cpu, &gba->board.d);
|
ARMAssociateBoard(&gba->cpu, &gba->board.d);
|
||||||
|
|
||||||
|
gba->video.p = gba;
|
||||||
|
GBAVideoInit(&gba->video);
|
||||||
|
|
||||||
ARMReset(&gba->cpu);
|
ARMReset(&gba->cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue