Skip to content

Commit

Permalink
add code for running display at 50Hz
Browse files Browse the repository at this point in the history
disabled until i know how it runs on 2ds
related to #46
  • Loading branch information
skyfloogle committed Apr 1, 2024
1 parent 1e90ebf commit dbdde5d
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 2 deletions.
2 changes: 2 additions & 0 deletions include/main.h
Expand Up @@ -11,4 +11,6 @@ extern char rom_name[128];

extern bool game_running;

void frame_pacer_thread();

#endif
1 change: 1 addition & 0 deletions include/periodic.h
Expand Up @@ -3,5 +3,6 @@
typedef void (*threadfunc_t)();

bool startPeriodic(threadfunc_t func, int periodNanos);
bool startPeriodicVsync(threadfunc_t func);
void endThread(threadfunc_t func);
void endThreads();
1 change: 1 addition & 0 deletions include/vb_gui.h
Expand Up @@ -61,6 +61,7 @@ void showError(int code);
extern Thread save_thread;

bool guiShouldPause();
void toggleVsync(bool enable);
void aptBacklight(APT_HookType hook, void* param);
int guiGetInput(bool do_switching);

Expand Down
1 change: 1 addition & 0 deletions include/vb_set.h
Expand Up @@ -78,6 +78,7 @@ typedef struct VB_OPT {
char *PROG_NAME; // Path\Name of program
unsigned long CRC32; // CRC32 of ROM
bool PERF_INFO;
bool VSYNC;
} VB_OPT;

void setDefaults(void);
Expand Down
31 changes: 30 additions & 1 deletion source/3ds/gui_hard.c
Expand Up @@ -13,6 +13,7 @@
#include "vb_types.h"
#include "replay.h"
#include "main.h"
#include "periodic.h"
#include "sprites_t3x.h"
#include "sprites.h"

Expand Down Expand Up @@ -1340,8 +1341,36 @@ bool toggleBacklight(bool enable) {
return enable;
}

void toggleVsync(bool enable) {
endThread(frame_pacer_thread);
u32 vtotal_top, vtotal_bottom;
if (enable) {
// 990 is closer to 50Hz but capture cards don't like when the two screens are out of sync
vtotal_top = 989;
vtotal_bottom = 494;
startPeriodicVsync(frame_pacer_thread);
} else {
vtotal_top = 827;
vtotal_bottom = 413;
startPeriodic(frame_pacer_thread, 20000000);
}
GSPGPU_WriteHWRegs(0x400424, &vtotal_top, 4);
GSPGPU_WriteHWRegs(0x400524, &vtotal_bottom, 4);
}

void aptBacklight(APT_HookType hook, void* param) {
if (backlightEnabled == false) {
if (tVBOpt.VSYNC) {
switch (hook) {
case APTHOOK_ONRESTORE:
case APTHOOK_ONWAKEUP:
toggleVsync(true);
break;
default:
toggleVsync(false);
break;
}
}
if (!backlightEnabled) {
switch (hook) {
case APTHOOK_ONRESTORE:
case APTHOOK_ONWAKEUP:
Expand Down
9 changes: 8 additions & 1 deletion source/3ds/main.c
Expand Up @@ -15,6 +15,7 @@
#include "vb_gui.h"
#include "rom_db.h"
#include "replay.h"
#include "utils.h"

char rom_path[256] = "sdmc:/vb/";
char rom_name[128];
Expand Down Expand Up @@ -60,6 +61,10 @@ int main() {

drc_init();

if (is_citra) {
tVBOpt.VSYNC = false;
}

replay_init();

guiop = 0;
Expand All @@ -76,7 +81,8 @@ int main() {
osSetSpeedupEnable(true);

svcCreateEvent(&frame_event, RESET_STICKY);
startPeriodic(frame_pacer_thread, 20000000);

toggleVsync(tVBOpt.VSYNC);

TickCounter drcTickCounter;
TickCounter frameTickCounter;
Expand Down Expand Up @@ -202,6 +208,7 @@ int main() {
save_sram();

exit:
toggleVsync(false);
sound_close();
if (save_thread) threadJoin(save_thread, U64_MAX);
endThreads();
Expand Down
34 changes: 34 additions & 0 deletions source/3ds/periodic.c
Expand Up @@ -36,6 +36,18 @@ static void periodic(void *periodArgs_v) {
svcCloseHandle(timer);
}

static void periodic_vsync(void *periodArgs_v) {
PeriodArgs *periodArgs = (PeriodArgs*)periodArgs_v;
threadfunc_t func = periodArgs->func;
int id = periodArgs->id;
svcSignalEvent(periodArgs->readyEvent);

while (threadrunning[id]) {
gspWaitForVBlank();
func();
}
}

bool startPeriodic(threadfunc_t func, int periodNanos) {
PeriodArgs periodArgs;
periodArgs.func = func;
Expand All @@ -59,6 +71,28 @@ bool startPeriodic(threadfunc_t func, int periodNanos) {
return false;
}

bool startPeriodicVsync(threadfunc_t func) {
PeriodArgs periodArgs;
periodArgs.func = func;
svcCreateEvent(&periodArgs.readyEvent, RESET_ONESHOT);
for (int i = 0; i < THREAD_COUNT; i++) {
if (!threadrunning[i]) {
periodArgs.id = i;
threadfuncs[i] = func;
threadrunning[i] = true;
threads[i] = threadCreate(periodic_vsync, &periodArgs, 4000, 0x18, 0, true);
if (!threads[i]) {
threadrunning[i] = false;
return false;
}
svcWaitSynchronization(periodArgs.readyEvent, 0);
svcCloseHandle(periodArgs.readyEvent);
return true;
}
}
return false;
}

void endThread(threadfunc_t func) {
for (int i = 0; i < THREAD_COUNT; i++) {
if (threadrunning[i] && threadfuncs[i] == func) {
Expand Down
3 changes: 3 additions & 0 deletions source/3ds/video.c
Expand Up @@ -204,6 +204,9 @@ void video_init() {
C3D_RenderTargetClear(finalScreen[0], C3D_CLEAR_COLOR, 0, 0);
C3D_FrameEnd(0);
gspWaitForVBlank();

u32 vtotal = 990;
GSPGPU_WriteHWRegs(0x400424, &vtotal, 4);
}

void video_render(int alt_buf) {
Expand Down
1 change: 1 addition & 0 deletions source/common/vb_set.c
Expand Up @@ -47,6 +47,7 @@ void setDefaults(void) {
tVBOpt.DEFAULT_EYE = 0;
tVBOpt.PERF_INFO = false;
tVBOpt.ROM_PATH = NULL;
tVBOpt.VSYNC = false;

// Default keys
#ifdef __3DS__
Expand Down

1 comment on commit dbdde5d

@profi200
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"disabled until i know how it runs on 2ds" It works fine on 2DS as long as you don't attempt to enable 3D or wide mode. I have no o2DS to test but iirc people say the output shows weirdly stretched and cut off if you attempt this. On N2DS XL wide mode will work but 3D will not (shows left and right eye lines interleaved) because the parallax barrier is missing.

Please sign in to comment.