Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ add_object_library_macros(GS_HIRES_OBJS ee/gs/src/gsHires.c
_gsKit_create_passes
gsKit_hires_sync
gsKit_hires_flip
gsKit_hires_flip_ext
gsKit_hires_prepare_bg
gsKit_hires_set_bg
gsKit_hires_init_screen
Expand Down
8 changes: 8 additions & 0 deletions ee/gs/include/gsCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ struct gsVertex
};
typedef struct gsVertex GSVERTEX;

/// Flip mode for gsKit_hires_flip_ext
typedef enum {
GSFLIP_DIRECT = 0, ///< Flip immediately, no vsync wait
GSFLIP_VSYNC = 1, ///< Wait for vsync before flipping
GSFLIP_RATE_LIMIT_1 = 2, ///< Limit to 60fps (1 vsync per frame)
GSFLIP_RATE_LIMIT_2 = 3 ///< Limit to 30fps (2 vsyncs per frame)
} GSFLIP_MODE;

#ifdef __cplusplus
extern "C" {
#endif
Expand Down
3 changes: 3 additions & 0 deletions ee/gs/include/gsHires.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ void gsKit_hires_sync(GSGLOBAL *gsGlobal);
/// Flips Draw Queue
void gsKit_hires_flip(GSGLOBAL *gsGlobal);

/// Flips Draw Queue with specified flip mode
void gsKit_hires_flip_ext(GSGLOBAL *gsGlobal, GSFLIP_MODE mode);

/// Converts PSM and interlacing for use as background image
void gsKit_hires_prepare_bg(GSGLOBAL *gsGlobal, GSTEXTURE * tex);

Expand Down
27 changes: 27 additions & 0 deletions ee/gs/src/gsHires.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,35 @@ void gsKit_hires_sync(GSGLOBAL *gsGlobal)

#if F_gsKit_hires_flip
void gsKit_hires_flip(GSGLOBAL *gsGlobal)
{
gsKit_hires_flip_ext(gsGlobal, GSFLIP_DIRECT);
}
#endif

#if F_gsKit_hires_flip_ext
// State tracking for rate limiting
static u32 __last_flip_vsync_count = 0;

void gsKit_hires_flip_ext(GSGLOBAL *gsGlobal, GSFLIP_MODE mode)
{
u32 iY;
u32 vsync_end;

// Handle vsync waiting based on mode
switch (mode) {
case GSFLIP_DIRECT: vsync_end = __vsync_count; break;
case GSFLIP_VSYNC: vsync_end = __vsync_count + 1; break;
case GSFLIP_RATE_LIMIT_1: vsync_end = __last_flip_vsync_count + 1; break;
case GSFLIP_RATE_LIMIT_2: vsync_end = __last_flip_vsync_count + 2; break;
}

// Wait for required vsyncs
while (__vsync_count < vsync_end) {
WaitSema(__sema_vsync_id);
}

// Update last flip vsync count
__last_flip_vsync_count = __vsync_count;

// HACK: The start of the first displayed line
// this is needed by the hsync interrupt but must be
Expand Down