mirror of https://github.com/mgba-emu/mgba.git
DS Video: Begin stubbing out rendering
This commit is contained in:
parent
2dc8f76294
commit
0b81939104
|
@ -58,6 +58,7 @@ file(GLOB GBA_RENDERER_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gba/renderers/*.c)
|
|||
file(GLOB GBA_SIO_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gba/sio/lockstep.c)
|
||||
file(GLOB GB_SIO_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gb/sio/lockstep.c)
|
||||
file(GLOB GB_RENDERER_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/gb/renderers/*.c)
|
||||
file(GLOB DS_RENDERER_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/ds/renderers/*.c)
|
||||
file(GLOB THIRD_PARTY_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/third-party/inih/*.c)
|
||||
set(CLI_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/feature/commandline.c)
|
||||
set(CORE_VFS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/vfs/vfs-mem.c)
|
||||
|
@ -640,7 +641,8 @@ if(M_CORE_DS)
|
|||
add_definitions(-DM_CORE_DS)
|
||||
list(APPEND CORE_SRC
|
||||
${ARM_SRC}
|
||||
${DS_SRC})
|
||||
${DS_SRC}
|
||||
${DS_RENDERER_SRC})
|
||||
list(APPEND DEBUGGER_SRC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/arm/debugger/cli-debugger.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/arm/debugger/debugger.c
|
||||
|
|
|
@ -29,9 +29,25 @@ enum {
|
|||
DS_VIDEO_TOTAL_LENGTH = DS_VIDEO_HORIZONTAL_LENGTH * DS_VIDEO_VERTICAL_TOTAL_PIXELS,
|
||||
};
|
||||
|
||||
struct DSVideoRenderer {
|
||||
void (*init)(struct DSVideoRenderer* renderer);
|
||||
void (*reset)(struct DSVideoRenderer* renderer);
|
||||
void (*deinit)(struct DSVideoRenderer* renderer);
|
||||
|
||||
uint16_t (*writeVideoRegister)(struct DSVideoRenderer* renderer, uint32_t address, uint16_t value);
|
||||
void (*drawScanline)(struct DSVideoRenderer* renderer, int y);
|
||||
void (*finishFrame)(struct DSVideoRenderer* renderer);
|
||||
|
||||
void (*getPixels)(struct DSVideoRenderer* renderer, size_t* stride, const void** pixels);
|
||||
void (*putPixels)(struct DSVideoRenderer* renderer, size_t stride, const void* pixels);
|
||||
|
||||
uint16_t* vram;
|
||||
};
|
||||
|
||||
struct DS;
|
||||
struct DSVideo {
|
||||
struct DS* p;
|
||||
struct DSVideoRenderer* renderer;
|
||||
struct mTimingEvent event7;
|
||||
struct mTimingEvent event9;
|
||||
|
||||
|
@ -48,6 +64,7 @@ struct DSVideo {
|
|||
void DSVideoInit(struct DSVideo* video);
|
||||
void DSVideoReset(struct DSVideo* video);
|
||||
void DSVideoDeinit(struct DSVideo* video);
|
||||
void DSVideoAssociateRenderer(struct DSVideo* video, struct DSVideoRenderer* renderer);
|
||||
|
||||
struct DSCommon;
|
||||
void DSVideoWriteDISPSTAT(struct DSCommon* dscore, uint16_t value);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <mgba/internal/arm/debugger/debugger.h>
|
||||
#include <mgba/internal/ds/ds.h>
|
||||
#include <mgba/internal/ds/extra/cli.h>
|
||||
#include <mgba/internal/ds/renderers/software.h>
|
||||
#include <mgba-util/memory.h>
|
||||
#include <mgba-util/patch.h>
|
||||
#include <mgba-util/vfs.h>
|
||||
|
@ -19,6 +20,7 @@ struct DSCore {
|
|||
struct mCore d;
|
||||
struct ARMCore* arm7;
|
||||
struct ARMCore* arm9;
|
||||
struct DSVideoSoftwareRenderer renderer;
|
||||
int keys;
|
||||
struct mCPUComponent* components[CPU_COMPONENT_MAX];
|
||||
struct mDebuggerPlatform* debuggerPlatform;
|
||||
|
@ -52,6 +54,9 @@ static bool _DSCoreInit(struct mCore* core) {
|
|||
ARMInit(arm7);
|
||||
ARMInit(arm9);
|
||||
|
||||
DSVideoSoftwareRendererCreate(&dscore->renderer);
|
||||
dscore->renderer.outputBuffer = NULL;
|
||||
|
||||
dscore->keys = 0;
|
||||
ds->keySource = &dscore->keys;
|
||||
|
||||
|
@ -110,12 +115,19 @@ static void _DSCoreDesiredVideoDimensions(struct mCore* core, unsigned* width, u
|
|||
}
|
||||
|
||||
static void _DSCoreSetVideoBuffer(struct mCore* core, color_t* buffer, size_t stride) {
|
||||
struct DSCore* dscore = (struct DSCore*) core;
|
||||
dscore->renderer.outputBuffer = buffer;
|
||||
dscore->renderer.outputBufferStride = stride;
|
||||
}
|
||||
|
||||
static void _DSCoreGetPixels(struct mCore* core, const void** buffer, size_t* stride) {
|
||||
struct DSCore* dscore = (struct DSCore*) core;
|
||||
dscore->renderer.d.getPixels(&dscore->renderer.d, stride, buffer);
|
||||
}
|
||||
|
||||
static void _DSCorePutPixels(struct mCore* core, const void* buffer, size_t stride) {
|
||||
struct DSCore* dscore = (struct DSCore*) core;
|
||||
dscore->renderer.d.putPixels(&dscore->renderer.d, stride, buffer);
|
||||
}
|
||||
|
||||
static struct blip_t* _DSCoreGetAudioChannel(struct mCore* core, int ch) {
|
||||
|
@ -162,6 +174,11 @@ static void _DSCoreReset(struct mCore* core) {
|
|||
struct DSCore* dscore = (struct DSCore*) core;
|
||||
struct DS* ds = (struct DS*) core->board;
|
||||
|
||||
if (dscore->renderer.outputBuffer) {
|
||||
struct DSVideoRenderer* renderer = &dscore->renderer.d;
|
||||
DSVideoAssociateRenderer(&ds->video, renderer);
|
||||
}
|
||||
|
||||
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
|
||||
struct VFile* bios7 = 0;
|
||||
struct VFile* bios9 = 0;
|
||||
|
@ -240,7 +257,7 @@ static void _DSCoreClearKeys(struct mCore* core, uint32_t keys) {
|
|||
dscore->keys &= ~keys;
|
||||
}
|
||||
|
||||
static int32_t _DSCoreFrameCounter(struct mCore* core) {
|
||||
static int32_t _DSCoreFrameCounter(const struct mCore* core) {
|
||||
struct DS* ds = core->board;
|
||||
return ds->video.frameCounter;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/* Copyright (c) 2013-2017 Jeffrey Pfau
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include <mgba/internal/ds/renderers/software.h>
|
||||
|
||||
static void DSVideoSoftwareRendererInit(struct DSVideoRenderer* renderer);
|
||||
static void DSVideoSoftwareRendererDeinit(struct DSVideoRenderer* renderer);
|
||||
static void DSVideoSoftwareRendererReset(struct DSVideoRenderer* renderer);
|
||||
static uint16_t DSVideoSoftwareRendererWriteVideoRegister(struct DSVideoRenderer* renderer, uint32_t address, uint16_t value);
|
||||
static void DSVideoSoftwareRendererDrawScanline(struct DSVideoRenderer* renderer, int y);
|
||||
static void DSVideoSoftwareRendererFinishFrame(struct DSVideoRenderer* renderer);
|
||||
static void DSVideoSoftwareRendererGetPixels(struct DSVideoRenderer* renderer, size_t* stride, const void** pixels);
|
||||
static void DSVideoSoftwareRendererPutPixels(struct DSVideoRenderer* renderer, size_t stride, const void* pixels);
|
||||
|
||||
void DSVideoSoftwareRendererCreate(struct DSVideoSoftwareRenderer* renderer) {
|
||||
renderer->d.init = DSVideoSoftwareRendererInit;
|
||||
renderer->d.reset = DSVideoSoftwareRendererReset;
|
||||
renderer->d.deinit = DSVideoSoftwareRendererDeinit;
|
||||
renderer->d.drawScanline = DSVideoSoftwareRendererDrawScanline;
|
||||
renderer->d.finishFrame = DSVideoSoftwareRendererFinishFrame;
|
||||
renderer->d.getPixels = DSVideoSoftwareRendererGetPixels;
|
||||
renderer->d.putPixels = DSVideoSoftwareRendererPutPixels;
|
||||
}
|
||||
|
||||
static void DSVideoSoftwareRendererInit(struct DSVideoRenderer* renderer) {
|
||||
}
|
||||
|
||||
static void DSVideoSoftwareRendererReset(struct DSVideoRenderer* renderer) {
|
||||
}
|
||||
|
||||
static void DSVideoSoftwareRendererDeinit(struct DSVideoRenderer* renderer) {
|
||||
}
|
||||
|
||||
static uint16_t DSVideoSoftwareRendererWriteVideoRegister(struct DSVideoRenderer* renderer, uint32_t address, uint16_t value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
static void DSVideoSoftwareRendererDrawScanline(struct DSVideoRenderer* renderer, int y) {
|
||||
}
|
||||
|
||||
static void DSVideoSoftwareRendererFinishFrame(struct DSVideoRenderer* renderer) {
|
||||
}
|
||||
|
||||
static void DSVideoSoftwareRendererGetPixels(struct DSVideoRenderer* renderer, size_t* stride, const void** pixels) {
|
||||
}
|
||||
|
||||
static void DSVideoSoftwareRendererPutPixels(struct DSVideoRenderer* renderer, size_t stride, const void* pixels) {
|
||||
}
|
|
@ -14,6 +14,15 @@
|
|||
|
||||
mLOG_DEFINE_CATEGORY(DS_VIDEO, "DS Video");
|
||||
|
||||
static void DSVideoDummyRendererInit(struct DSVideoRenderer* renderer);
|
||||
static void DSVideoDummyRendererReset(struct DSVideoRenderer* renderer);
|
||||
static void DSVideoDummyRendererDeinit(struct DSVideoRenderer* renderer);
|
||||
static uint16_t DSVideoDummyRendererWriteVideoRegister(struct DSVideoRenderer* renderer, uint32_t address, uint16_t value);
|
||||
static void DSVideoDummyRendererDrawScanline(struct DSVideoRenderer* renderer, int y);
|
||||
static void DSVideoDummyRendererFinishFrame(struct DSVideoRenderer* renderer);
|
||||
static void DSVideoDummyRendererGetPixels(struct DSVideoRenderer* renderer, size_t* stride, const void** pixels);
|
||||
static void DSVideoDummyRendererPutPixels(struct DSVideoRenderer* renderer, size_t stride, const void* pixels);
|
||||
|
||||
static void _startHblank7(struct mTiming*, void* context, uint32_t cyclesLate);
|
||||
static void _startHdraw7(struct mTiming*, void* context, uint32_t cyclesLate);
|
||||
static void _startHblank9(struct mTiming*, void* context, uint32_t cyclesLate);
|
||||
|
@ -88,7 +97,19 @@ const struct DSVRAMBankInfo {
|
|||
},
|
||||
};
|
||||
|
||||
static struct DSVideoRenderer dummyRenderer = {
|
||||
.init = DSVideoDummyRendererInit,
|
||||
.reset = DSVideoDummyRendererReset,
|
||||
.deinit = DSVideoDummyRendererDeinit,
|
||||
.writeVideoRegister = DSVideoDummyRendererWriteVideoRegister,
|
||||
.drawScanline = DSVideoDummyRendererDrawScanline,
|
||||
.finishFrame = DSVideoDummyRendererFinishFrame,
|
||||
.getPixels = DSVideoDummyRendererGetPixels,
|
||||
.putPixels = DSVideoDummyRendererPutPixels,
|
||||
};
|
||||
|
||||
void DSVideoInit(struct DSVideo* video) {
|
||||
video->renderer = &dummyRenderer;
|
||||
video->vram = NULL;
|
||||
video->frameskip = 0;
|
||||
video->event7.name = "DS7 Video";
|
||||
|
@ -118,6 +139,7 @@ void DSVideoReset(struct DSVideo* video) {
|
|||
mappedMemoryFree(video->vram, DS_SIZE_VRAM);
|
||||
}
|
||||
video->vram = anonymousMemoryMap(DS_SIZE_VRAM);
|
||||
video->renderer->vram = video->vram;
|
||||
|
||||
video->p->memory.vramBank[0] = &video->vram[0x00000];
|
||||
video->p->memory.vramBank[1] = &video->vram[0x10000];
|
||||
|
@ -128,9 +150,20 @@ void DSVideoReset(struct DSVideo* video) {
|
|||
video->p->memory.vramBank[6] = &video->vram[0x4A000];
|
||||
video->p->memory.vramBank[7] = &video->vram[0x4C000];
|
||||
video->p->memory.vramBank[8] = &video->vram[0x50000];
|
||||
|
||||
video->renderer->deinit(video->renderer);
|
||||
video->renderer->init(video->renderer);
|
||||
}
|
||||
|
||||
void DSVideoAssociateRenderer(struct DSVideo* video, struct DSVideoRenderer* renderer) {
|
||||
video->renderer->deinit(video->renderer);
|
||||
video->renderer = renderer;
|
||||
renderer->vram = video->vram;
|
||||
video->renderer->init(video->renderer);
|
||||
}
|
||||
|
||||
void DSVideoDeinit(struct DSVideo* video) {
|
||||
DSVideoAssociateRenderer(video, &dummyRenderer);
|
||||
mappedMemoryFree(video->vram, DS_SIZE_VRAM);
|
||||
}
|
||||
|
||||
|
@ -160,6 +193,9 @@ void _startHdraw7(struct mTiming* timing, void* context, uint32_t cyclesLate) {
|
|||
switch (video->vcount) {
|
||||
case DS_VIDEO_VERTICAL_PIXELS:
|
||||
video->p->ds7.memory.io[DS_REG_DISPSTAT >> 1] = GBARegisterDISPSTATFillInVblank(dispstat);
|
||||
if (video->frameskipCounter <= 0) {
|
||||
video->renderer->finishFrame(video->renderer);
|
||||
}
|
||||
if (GBARegisterDISPSTATIsVblankIRQ(dispstat)) {
|
||||
DSRaiseIRQ(video->p->ds7.cpu, video->p->ds7.memory.io, DS_IRQ_VBLANK);
|
||||
}
|
||||
|
@ -179,6 +215,9 @@ void _startHblank7(struct mTiming* timing, void* context, uint32_t cyclesLate) {
|
|||
|
||||
// Begin Hblank
|
||||
dispstat = GBARegisterDISPSTATFillInHblank(dispstat);
|
||||
if (video->vcount < DS_VIDEO_VERTICAL_PIXELS && video->frameskipCounter <= 0) {
|
||||
video->renderer->drawScanline(video->renderer, video->vcount);
|
||||
}
|
||||
|
||||
if (GBARegisterDISPSTATIsHblankIRQ(dispstat)) {
|
||||
DSRaiseIRQ(video->p->ds7.cpu, video->p->ds7.memory.io, DS_IRQ_HBLANK);
|
||||
|
@ -272,3 +311,48 @@ void DSVideoConfigureVRAM(struct DSMemory* memory, int index, uint8_t value) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void DSVideoDummyRendererInit(struct DSVideoRenderer* renderer) {
|
||||
UNUSED(renderer);
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
static void DSVideoDummyRendererReset(struct DSVideoRenderer* renderer) {
|
||||
UNUSED(renderer);
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
static void DSVideoDummyRendererDeinit(struct DSVideoRenderer* renderer) {
|
||||
UNUSED(renderer);
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
static uint16_t DSVideoDummyRendererWriteVideoRegister(struct DSVideoRenderer* renderer, uint32_t address, uint16_t value) {
|
||||
UNUSED(renderer);
|
||||
return value;
|
||||
}
|
||||
|
||||
static void DSVideoDummyRendererDrawScanline(struct DSVideoRenderer* renderer, int y) {
|
||||
UNUSED(renderer);
|
||||
UNUSED(y);
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
static void DSVideoDummyRendererFinishFrame(struct DSVideoRenderer* renderer) {
|
||||
UNUSED(renderer);
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
static void DSVideoDummyRendererGetPixels(struct DSVideoRenderer* renderer, size_t* stride, const void** pixels) {
|
||||
UNUSED(renderer);
|
||||
UNUSED(stride);
|
||||
UNUSED(pixels);
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
static void DSVideoDummyRendererPutPixels(struct DSVideoRenderer* renderer, size_t stride, const void* pixels) {
|
||||
UNUSED(renderer);
|
||||
UNUSED(stride);
|
||||
UNUSED(pixels);
|
||||
// Nothing to do
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue