OXYGENHUB
◆ rrdc-perf enhanced-x16-emulator / src / video.h
5.4 KiB · Objective-C · last changed feat: the RRDC control port (-controlport), contract 0.6: GET/POST /perf from the Performance panel's measurements, built by perf_json.c with DAP's x16/perfStats; a guest marker region named in advance; a framed guest's regions carried across the frame boundary and an interrupt after $F1 counted as work (#1) 25 days ago source blame history raw
9120e874 Andy McCall 1
// Commander X16 Emulator
2
// Copyright (c) 2019 Michael Steil
3
// All rights reserved. License: 2-clause BSD
4
5
#ifndef _VIDEO_H_
6
#define _VIDEO_H_
7
8
#include <stdbool.h>
9
#include <stdint.h>
10
#include <stdio.h>
11
#include <SDL.h>
12
#include "glue.h"
13
14
#ifdef __cplusplus
15
extern "C" {
16
#endif
17
18
bool video_init(int window_scale, float screen_x_scale, char *quality, bool fullscreen, float opacity);
19
void video_reset(void);
20
bool video_step(float mhz, float steps, bool midline);
21
bool video_update(void);
22
void video_present_no_input(void);
23
void video_repaint_only(void);
24
// The ImGui debugger window, in builds configured with -DENABLE_IMGUI.
25
// Both are always defined: without the UI, available() is false and the pump
26
// reports "stay paused", so call sites need no #ifdef.
27
bool video_debug_ui_available(void);
28
int  video_debug_ui_pump_paused(void);
29
bool video_is_debug_ui_window(Uint32 window_id);
30
bool video_event_targets_debug_ui(const SDL_Event *ev);
31
void video_debug_ui_shortcut_key(const SDL_Event *ev);
32
void video_debug_ui_feed_event(const SDL_Event *ev);
33
34
// ─── Debug view accessors ──────────────────────────────────────────────────
35
// Per-scanline history of the layer registers each display line was actually
36
// rendered with. Programs rewrite MAPBASE/TILEBASE/scroll part-way down a frame
37
// from a line IRQ ("raster split"), so one register snapshot describes only one
38
// band of the screen.
39
//
40
// out_regs receives the 7 layer registers L?_CONFIG..L?_VSCROLL_H; out_eff_y is
41
// the composer's effective layer Y for that line, before the layer's own
42
// VSCROLL; out_layer_row is the row of the layer image the line displayed,
43
// recorded rather than derivable because the renderer mixes two register
44
// generations; out_enabled is false for a line the layer did not reach the
45
// screen on, including border lines outside the active display window. Returns
46
// false if the line is out of range or has not been rendered yet. Every
47
// out-parameter is optional.
48
//
49
// Accurate for the common shape of a raster split -- a program rewriting
50
// MAPBASE/TILEBASE/scroll from a line IRQ so that horizontal bands differ --
51
// and approximate in narrower ones. Known limits: out_regs is the layout
52
// generation, one behind the generation the row was computed from, so a scroll
53
// change at the split misleads anything derived from out_regs alone; bitmap
54
// mode takes its palette offset from the live registers, so a palette change at
55
// a split reports up to two lines late; there is one snapshot per scanline and
56
// the last render_line() call wins, so a mid-line change is not represented;
57
// settlement is tracked per line rather than per layer; and a split that
58
// changes tile geometry falls back to the live registers for those rows.
59
// Getting these exact means having each render_layer_line_* publish the state
60
// it actually used, rather than reconstructing it from outside as this does.
61
bool video_get_layer_line_state(uint8_t layer, uint16_t line, uint8_t out_regs[7],
62
                                uint16_t *out_eff_y, bool *out_enabled,
63
                                uint16_t *out_layer_row);
64
uint16_t video_get_scanline_count(void);
65
66
// The frame period video_step() actually raises a new frame on, expressed in
67
// VERA's 25 MHz dot clock and in scanlines. Together with the CPU clock these
68
// give the cycles a program has between vsyncs, which is what a performance
69
// budget is measured against.
70
//
71
// NTSC reports a FIELD, not a full interlaced frame, because a field is what
72
// video_step() signals a new frame at -- and it is also what a program syncing
73
// to VSYNC actually gets.
74
uint32_t video_frame_dot_clocks(void);
75
uint16_t video_frame_scanlines(void);
76
77
// Size in layer pixels of the image the composer is actually displaying: the
78
// active window (DC_HSTART/HSTOP, DC_VSTART/VSTOP) scaled by DC_HSCALE/VSCALE.
79
// Viewers use this to size themselves to the current video mode.
80
void video_get_active_layer_size(int *out_w, int *out_h);
81
82
// Cycles until the next enabled VERA interrupt and the ISR bit that will cause
83
// it (1 = VSYNC, 2 = LINE); false when neither is enabled.
84
bool video_next_irq(float mhz, uint32_t *out_cycles, uint8_t *out_source);
85
void video_get_irq_state(uint8_t *out_ien, uint8_t *out_isr, uint16_t *out_irq_line);
86
void video_end(void);
87
bool video_get_irq_out(void);
2980b7b6 Andy McCall ↶ 88
// For the control port (control_backend.c): the last whole frame, BGRA8888,
89
// and the count of frames completed.
90
const uint8_t *video_get_framebuffer(int *width, int *height);
91
uint32_t video_get_frame_count(void);
9120e874 Andy McCall 92
void video_save(SDL_RWops *f);
93
uint8_t video_read(uint8_t reg, bool debugOn);
94
void video_write(uint8_t reg, uint8_t value);
95
96
// Announce that the next video_write() is the DEBUGGER's, not the guest's, so
97
// its data-port traffic is not charged to VERA's bandwidth accounting.
98
// video_read() is told the same thing directly, as its debugOn argument.
99
void video_set_debug_write(bool on);
100
void video_update_title(const char* window_title);
101
102
uint8_t via1_read(uint8_t reg, bool debug);
103
void via1_write(uint8_t reg, uint8_t value);
104
105
// For debugging purposes only:
106
uint8_t video_space_read(uint32_t address);
107
void video_space_write(uint32_t address, uint8_t value);
108
109
bool video_is_tilemap_address(int addr);
110
bool video_is_tiledata_address(int addr);
111
bool video_is_special_address(int addr);
112
113
uint32_t video_get_address(uint8_t sel);
114
uint32_t video_get_fx_accum(void);
115
uint8_t video_get_dc_value(uint8_t reg);
116
117
#ifdef __cplusplus
118
}
119
#endif
120
121
#endif