Skip to content

Commit

Permalink
Add doublebuffering to SNES9X and Genesis
Browse files Browse the repository at this point in the history
  • Loading branch information
JoeMatt committed Feb 21, 2019
1 parent ac3918b commit d7a9e4a
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 17 deletions.
101 changes: 86 additions & 15 deletions Cores/Genesis-Plus-GX/PVGenesis/Genesis/PVGenesisEmulatorCore.m
Expand Up @@ -15,9 +15,19 @@
#import <OpenGLES/EAGL.h>
#import <OpenGLES/ES3/gl.h>

#include "shared.h"
#include "libretro.h"
#include "state.h"
#include "genesis.h"
#include "md_ntsc.h"
#include "sms_ntsc.h"

@interface PVGenesisEmulatorCore ()
{
uint16_t *_videoBuffer;
uint16_t *videoBuffer;
uint16_t *videoBufferA;
uint16_t *videoBufferB;

int _videoWidth, _videoHeight;
int16_t _pad[2][12];
}
Expand Down Expand Up @@ -60,7 +70,7 @@ static void video_callback(const void *data, unsigned width, unsigned height, si

dispatch_apply(height, the_queue, ^(size_t y){
const uint16_t *src = (uint16_t*)data + y * (pitch >> 1); //pitch is in bytes not pixels
uint16_t *dst = strongCurrent->_videoBuffer + y * 320;
uint16_t *dst = strongCurrent->videoBuffer + y * 320;

memcpy(dst, src, sizeof(uint16_t)*width);
});
Expand Down Expand Up @@ -138,21 +148,23 @@ static bool environment_callback(unsigned cmd, void *data)
return true;
}

- (id)init
{
if ((self = [super init]))
{
_videoBuffer = malloc(320 * 480 * 2);
- (id)init {
if ((self = [super init])) {
videoBufferA = malloc(320 * 480 * 2);
videoBufferB = malloc(320 * 480 * 2);
}

_current = self;

return self;
}

- (void)dealloc
{
free(_videoBuffer);
- (void)dealloc {
free(videoBufferA);
videoBufferA = NULL;
free(videoBufferB);
videoBufferB = NULL;
videoBuffer = NULL;
}

#pragma mark - Execution
Expand Down Expand Up @@ -181,9 +193,26 @@ - (void)stopEmulation
});
}

- (void)executeFrame
{
retro_run();
- (void)executeFrame {
[self executeFrameSkippingFrame:false];
}

- (void)executeFrameSkippingFrame:(BOOL)skip {
int aud;

int skipI = skip ? 1 : 0;

if (system_hw == SYSTEM_MCD)
system_frame_scd(skipI);
else if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
system_frame_gen(skipI);
else
system_frame_sms(skipI);

video_callback(bitmap.data, bitmap.viewport.w + (bitmap.viewport.x * 2), bitmap.viewport.h + (bitmap.viewport.y * 2), bitmap.pitch);

aud = audio_update(soundbuffer) << 1;
audio_batch_callback(soundbuffer, aud >> 1);
}

- (BOOL)loadFileAtPath:(NSString*)path error:(NSError**)error
Expand Down Expand Up @@ -215,6 +244,30 @@ - (BOOL)loadFileAtPath:(NSString*)path error:(NSError**)error
data = (uint8_t*)[dataObj bytes];
const char *meta = NULL;

if (videoBufferA) {
free(videoBufferA);
}
videoBufferA = NULL;

if (videoBufferB) {
free(videoBufferB);
}
videoBufferB = NULL;

videoBuffer = NULL;

#if 0
videoBufferA = (unsigned char *)posix_memalign((void**)&GFX.Screen, 16, GFX.Pitch * 512 * sizeof(uint16));
videoBufferB = (unsigned char *)posix_memalign((void**)&GFX.Screen, 16, GFX.Pitch * 512 * sizeof(uint16));
#else
videoBufferA = (unsigned char *)malloc(320 * 480 * 2);
videoBufferB = (unsigned char *)malloc(320 * 480 * 2);
#endif

bitmap.data = (short unsigned int *)videoBufferA;
videoBuffer = videoBufferB;


retro_set_environment(environment_callback);
retro_init();

Expand Down Expand Up @@ -250,7 +303,7 @@ - (BOOL)loadFileAtPath:(NSString*)path error:(NSError**)error
_sampleRate = info.timing.sample_rate;

retro_get_region();
retro_run();
[self executeFrame];

return YES;
}
Expand Down Expand Up @@ -311,9 +364,27 @@ - (BOOL)writeSaveFile:(NSString *)path forType:(int)type

#pragma mark - Video

- (void)swapBuffers
{
if (bitmap.data == (short unsigned int *)videoBufferA)
{
videoBuffer = videoBufferA;
bitmap.data = (short unsigned int *)videoBufferB;
}
else
{
videoBuffer = videoBufferB;
bitmap.data = (short unsigned int *)videoBufferA;
}
}

- (const void *)videoBuffer
{
return _videoBuffer;
return videoBuffer;
}

-(BOOL)isDoubleBuffered {
return YES;
}

- (CGRect)screenRect
Expand Down
4 changes: 4 additions & 0 deletions Cores/Mupen64Plus/MupenGameCore.m
Expand Up @@ -1433,6 +1433,10 @@ - (BOOL)rendersToOpenGL
return YES;
}

//- (BOOL)isDoubleBuffered {
// return YES;
//}

- (const void *)videoBuffer
{
return NULL;
Expand Down
4 changes: 4 additions & 0 deletions Cores/Reicast/PVReicastCore/Core/PVReicastCore+Video.m
Expand Up @@ -55,6 +55,10 @@ - (BOOL)rendersToOpenGL {
return YES;
}

- (BOOL)isDoubleBuffered {
return YES;
}

- (const void *)videoBuffer {
return NULL;
}
Expand Down
8 changes: 6 additions & 2 deletions Cores/snes9x/PVSNES/SNES/PVSNESEmulatorCore.mm
Expand Up @@ -66,7 +66,7 @@ @interface PVSNESEmulatorCore () {
bool8 S9xDeinitUpdate(int width, int height)
{
__strong PVSNESEmulatorCore *strongCurrent = _current;
[strongCurrent flipBuffers];
[strongCurrent swapBuffers];

return true;
}
Expand Down Expand Up @@ -738,7 +738,7 @@ -(void)printBuildFlags {

#pragma mark Video

- (void)flipBuffers
- (void)swapBuffers
{
if (GFX.Screen == (short unsigned int *)videoBufferA)
{
Expand Down Expand Up @@ -801,6 +801,10 @@ - (BOOL)rendersToOpenGL
#endif
}

- (BOOL)isDoubleBuffered {
return YES;
}

#pragma mark Audio

bool8 S9xOpenSoundDevice(void)
Expand Down

0 comments on commit d7a9e4a

Please sign in to comment.