Skip to content

Commit dadaa11

Browse files
committed
output-frame-interval-ms
1 parent c49958d commit dadaa11

4 files changed

Lines changed: 33 additions & 0 deletions

File tree

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ The command-line app sits above `../libppuc` and indirectly above `../io-boards`
1616
- For non-WPC games, GI behavior may be forced from `libppuc` rather than driven by PinMAME GI updates.
1717
- `ppuc-pinmame` owns host-side ball search. It is disabled by default and is enabled with `--ball-search` or `Runtime.BallSearch=true`; only coils marked `ballSearch: true` in YAML are pulsed.
1818
- Switch refresh is always active by default through `--switch-refresh-idle-ms` / `Runtime.SwitchRefreshIdleMs` and uses `button: true` switch metadata to ignore cabinet/flipper button activity for the idle decision.
19+
- Runtime output/switch-poll cadence is configurable with `--output-frame-interval-ms` / `Runtime.OutputFrameIntervalMs`; the default remains 4 ms.
1920

2021
## Confirmed Cross-Layer Finding
2122

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ An example runtime ini file is available at `examples/ppuc-pinmame.ini`.
111111
update arrives for `Runtime.SwitchRefreshIdleMs`, the host sends a v2 switch
112112
refresh command. IO boards re-read their switch inputs, restart their local
113113
switch readers, and return full switch bitmaps through the normal switch chain.
114+
The normal runtime output/switch-poll cadence is controlled by
115+
`Runtime.OutputFrameIntervalMs` or `--output-frame-interval-ms`; the default is
116+
`4`.
114117

115118
Switches can be marked as cabinet/player buttons in the game YAML:
116119

@@ -136,6 +139,7 @@ search:
136139
137140
```ini
138141
[Runtime]
142+
OutputFrameIntervalMs = 4
139143
BallSearch = true
140144
BallSearchDelayMs = 15000
141145
BallSearchRoundDelayMs = 5000

examples/ppuc-pinmame.ini

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ SwitchReplyDelayUs = 2000
9898
# Must be greater than 0 because switch refresh is always active.
9999
SwitchRefreshIdleMs = 15000
100100

101+
# Runtime output frame interval in milliseconds. Lower values increase switch
102+
# poll cadence but leave less idle time for the host and IO boards.
103+
OutputFrameIntervalMs = 4
104+
101105
# Enable host-side ball search for older ROMs without native ball search.
102106
BallSearch = false
103107

src/ppuc.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
#define MAIN_LOOP_SLEEP_US 20 // Main loop sleep time in microseconds
6767
constexpr auto kPinmameTrackedStatePollInterval = std::chrono::milliseconds(500);
6868
constexpr uint32_t kDefaultSwitchRefreshIdleMs = 15000;
69+
constexpr uint32_t kDefaultOutputFrameIntervalMs = 4;
6970
constexpr uint32_t kDefaultBallSearchDelayMs = 15000;
7071
constexpr uint32_t kDefaultBallSearchRoundDelayMs = 5000;
7172
constexpr uint32_t kBallSearchCoilPulseMs = 200;
@@ -2254,6 +2255,10 @@ static struct cag_option options[] = {
22542255
.access_name = "switch-refresh-idle-ms",
22552256
.value_name = "VALUE",
22562257
.description = "Force a full switch refresh after this many ms without non-button switch updates"},
2258+
{.identifier = '%',
2259+
.access_name = "output-frame-interval-ms",
2260+
.value_name = "VALUE",
2261+
.description = "Runtime output frame interval in milliseconds; lower values increase switch poll cadence"},
22572262
{.identifier = 'B',
22582263
.access_name = "ball-search",
22592264
.value_name = NULL,
@@ -2716,6 +2721,8 @@ int main(int argc, char** argv)
27162721
uint32_t opt_switch_reply_delay_us = 0;
27172722
const char* opt_switch_refresh_idle_ms_arg = NULL;
27182723
uint32_t opt_switch_refresh_idle_ms = kDefaultSwitchRefreshIdleMs;
2724+
const char* opt_output_frame_interval_ms_arg = NULL;
2725+
uint32_t opt_output_frame_interval_ms = kDefaultOutputFrameIntervalMs;
27192726
bool opt_ball_search = false;
27202727
const char* opt_ball_search_delay_ms_arg = NULL;
27212728
uint32_t opt_ball_search_delay_ms = kDefaultBallSearchDelayMs;
@@ -2879,6 +2886,8 @@ int main(int argc, char** argv)
28792886
opt_switch_reply_delay_us_arg = DuplicateOptionalIniString(value);
28802887
else if (key == "SwitchRefreshIdleMs")
28812888
opt_switch_refresh_idle_ms_arg = DuplicateOptionalIniString(value);
2889+
else if (key == "OutputFrameIntervalMs")
2890+
opt_output_frame_interval_ms_arg = DuplicateOptionalIniString(value);
28822891
else if (key == "BallSearch")
28832892
opt_ball_search = ParseIniBool(value);
28842893
else if (key == "BallSearchDelayMs")
@@ -3072,6 +3081,9 @@ int main(int argc, char** argv)
30723081
case 'g':
30733082
opt_switch_refresh_idle_ms_arg = cag_option_get_value(&cag_context);
30743083
break;
3084+
case '%':
3085+
opt_output_frame_interval_ms_arg = cag_option_get_value(&cag_context);
3086+
break;
30753087
case 'B':
30763088
opt_ball_search = true;
30773089
break;
@@ -3223,6 +3235,17 @@ int main(int argc, char** argv)
32233235
fprintf(stderr, "--switch-refresh-idle-ms must be greater than 0 because switch re-reading is always active\n");
32243236
return 1;
32253237
}
3238+
if (opt_output_frame_interval_ms_arg &&
3239+
!ParseUint32Strict(opt_output_frame_interval_ms_arg, &opt_output_frame_interval_ms))
3240+
{
3241+
fprintf(stderr, "Invalid value for --output-frame-interval-ms: %s\n", opt_output_frame_interval_ms_arg);
3242+
return 1;
3243+
}
3244+
if (opt_output_frame_interval_ms == 0)
3245+
{
3246+
fprintf(stderr, "--output-frame-interval-ms must be greater than 0\n");
3247+
return 1;
3248+
}
32263249
if (opt_ball_search_delay_ms_arg && !ParseUint32Strict(opt_ball_search_delay_ms_arg, &opt_ball_search_delay_ms))
32273250
{
32283251
fprintf(stderr, "Invalid value for --ball-search-delay-ms: %s\n", opt_ball_search_delay_ms_arg);
@@ -3464,6 +3487,7 @@ int main(int argc, char** argv)
34643487
ppuc->SetCoilHoldFrames(opt_coil_hold_frames);
34653488
ppuc->SetSwitchReplyDelayUs(opt_switch_reply_delay_us);
34663489
ppuc->SetSwitchRefreshIdleMs(opt_switch_refresh_idle_ms);
3490+
ppuc->SetOutputFrameIntervalMs(opt_output_frame_interval_ms);
34673491
ppuc->SetDisableFastFlipForTests(opt_switch_test || opt_coil_test || opt_lamp_test || opt_gi_test ||
34683492
opt_flasher_test);
34693493

0 commit comments

Comments
 (0)