DS Video: Begin stubbing out rendering

This commit is contained in:
Vicki Pfau 2017-02-16 11:37:06 -08:00
parent 2dc8f76294
commit 0b81939104
5 changed files with 172 additions and 2 deletions

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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) {
}

View File

@ -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
}