Welcome to mirror list, hosted at ThFree Co, Russian Federation.

sdlmain.h « include - github.com/dosbox-staging/dosbox-staging.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 9ef107b8d8f4cb2c515b94f533af4db272b2e64b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
/*
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *
 *  Copyright (C) 2022-2022  The DOSBox Staging Team
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#ifndef DOSBOX_SDLMAIN_H
#define DOSBOX_SDLMAIN_H
 
#include <string>
#include <string_view>
#include <string.h>
#include "SDL.h"
#if C_OPENGL
#include <SDL_opengl.h>
#endif
#include "video.h"

#include "../libs/ppscale/ppscale.h"

#define SDL_NOFRAME 0x00000020

// Texture buffer and presentation functions and type-defines
using update_frame_buffer_f = void(const uint16_t *);
using present_frame_f = bool();
static void update_frame_texture([[maybe_unused]] const uint16_t *changedLines);
static bool present_frame_texture();
#if C_OPENGL
static void update_frame_gl_pbo([[maybe_unused]] const uint16_t *changedLines);
static void update_frame_gl_fb(const uint16_t *changedLines);
static bool present_frame_gl();
#endif
static void update_frame_surface(const uint16_t *changedLines);
constexpr void update_frame_noop([[maybe_unused]] const uint16_t *) { /* no-op */ }
static inline bool present_frame_noop() { return true; }

enum class FRAME_MODE {
	UNSET,
	CFR,        // constant frame rate, as defined by the emulated system
	VFR,        // variable frame rate, as defined by the emulated system
	SYNCED_CFR, // constant frame rate, synced with the display's refresh rate
	THROTTLED_VFR, // variable frame rate, throttled to the display's rate
};

enum class HOST_RATE_MODE {
	AUTO,
	SDI, // serial digital interface
	VRR, // variable refresh rate
	CUSTOM,
};

enum class SCALING_MODE { NONE, NEAREST, PERFECT };

enum class VSYNC_STATE {
	UNSET = -2,
	ADAPTIVE = -1,
	OFF = 0,
	ON = 1,
};

// A vsync preference consists of three parts:
//  - What the user asked for
//  - What the host reports vsync as after setting it
//  - What the actual resulting state is after setting it
struct VsyncPreference {
	VSYNC_STATE requested = VSYNC_STATE::UNSET;
	VSYNC_STATE reported = VSYNC_STATE::UNSET;
	VSYNC_STATE resultant = VSYNC_STATE::UNSET;
	int benchmarked_rate = 0;
};

enum PRIORITY_LEVELS {
	PRIORITY_LEVEL_AUTO,
	PRIORITY_LEVEL_LOWEST,
	PRIORITY_LEVEL_LOWER,
	PRIORITY_LEVEL_NORMAL,
	PRIORITY_LEVEL_HIGHER,
	PRIORITY_LEVEL_HIGHEST
};

struct SDL_Block {
	bool initialized = false;
	bool active = false; // If this isn't set don't draw
	bool updating = false;
	bool update_display_contents = true;
	bool resizing_window = false;
	bool wait_on_error = false;
	SCALING_MODE scaling_mode = SCALING_MODE::NONE;
	struct {
		int width = 0;
		int height = 0;
		int flags = 0;
		double scalex = 1.0;
		double scaley = 1.0;
		double pixel_aspect = 1.0;
		uint16_t previous_mode = 0;
		bool has_changed = false;
		GFX_CallBack_t callback = nullptr;
		bool width_was_doubled = false;
		bool height_was_doubled = false;
	} draw = {};
	struct {
		struct {
			int width = 0;
			int height = 0;
			bool fixed = false;
			bool display_res = false;
		} full = {};
		struct {
			// user-configured window size
			int width = 0;
			int height = 0;
			bool resizable = false;
			bool show_decorations = true;
			bool adjusted_initial_size = false;
			int initial_x_pos = -1;
			int initial_y_pos = -1;
			// instantaneous canvas size of the window
			SDL_Rect canvas_size = {};
		} window = {};
		struct {
			int width = 0;
			int height = 0;
		} requested_window_bounds = {};

		uint8_t bpp = 0;
		double dpi_scale = 1.0;
		bool fullscreen = false;
		bool lazy_fullscreen = false;
		bool lazy_fullscreen_req = false;

		// This flag indicates, that we are in the process of switching
		// between fullscreen or window (as oppososed to changing
		// rendering size due to rotating screen, emulation state, or
		// user resizing the window).
		bool switching_fullscreen = false;
		// Lazy window size init triggers updating window size and
		// position when leaving fullscreen for the first time.
		// See FinalizeWindowState function for details.
		bool lazy_init_window_size = false;
		HOST_RATE_MODE host_rate_mode = HOST_RATE_MODE::AUTO;
		double preferred_host_rate = 0.0;
		bool want_resizable_window = false;
		SDL_WindowEventID last_size_event = {};
		SCREEN_TYPES type = SCREEN_SURFACE;
		SCREEN_TYPES want_type = SCREEN_SURFACE;
	} desktop = {};
	struct {
		int num_cycles = 0;
		std::string hint_mouse_str  = {};
		std::string hint_paused_str = {};
		std::string cycles_ms_str   = {};
	} title_bar = {};
	struct {
		VsyncPreference when_windowed = {};
		VsyncPreference when_fullscreen = {};
		VSYNC_STATE current = VSYNC_STATE::ON;
		int skip_us = 0;
	} vsync = {};
#if C_OPENGL
	struct {
		SDL_GLContext context;
		int pitch = 0;
		void *framebuf = nullptr;
		GLuint buffer;
		GLuint texture;
		GLuint displaylist;
		GLint max_texsize;
		bool bilinear;
		bool pixel_buffer_object = false;
		bool npot_textures_supported = false;
		bool use_shader;
		bool framebuffer_is_srgb_encoded;
		GLuint program_object;
		std::string_view shader_source_sv = {};
		struct {
			GLint texture_size;
			GLint input_size;
			GLint output_size;
			GLint frame_count;
		} ruby = {};
		GLuint actual_frame_count;
		GLfloat vertex_data[2*3];
	} opengl = {};
#endif // C_OPENGL
	struct {
		PRIORITY_LEVELS active   = PRIORITY_LEVEL_AUTO;
		PRIORITY_LEVELS inactive = PRIORITY_LEVEL_AUTO;
	} priority = {};

	bool mute_when_inactive  = false;
	bool pause_when_inactive = false;

	SDL_Rect clip = {0, 0, 0, 0};
	SDL_Surface *surface = nullptr;
	SDL_Window *window = nullptr;
	SDL_Renderer *renderer = nullptr;
	std::string render_driver = "";
	int display_number = 0;
	struct {
		SDL_Surface *input_surface = nullptr;
		SDL_Texture *texture = nullptr;
		SDL_PixelFormat *pixelFormat = nullptr;
	} texture = {};
	struct {
		present_frame_f *present = present_frame_noop;
		update_frame_buffer_f *update = update_frame_noop;
		FRAME_MODE desired_mode = FRAME_MODE::UNSET;
		FRAME_MODE mode = FRAME_MODE::UNSET;
		double period_ms = 0.0; // in ms, for use with PIC timers
		int period_us = 0;      // same but in us, for use with chrono
		int period_us_early = 0;
		int period_us_late = 0;
	} frame = {};
	PPScale pp_scale = {};
	SDL_Rect updateRects[1024] = {};
	bool use_exact_window_resolution = false;
	bool use_viewport_limits = false;
	SDL_Point viewport_resolution = {-1, -1};
#if defined (WIN32)
	// Time when sdl regains focus (Alt+Tab) in windowed mode
	int64_t focus_ticks = 0;
#endif
	// State of Alt keys for certain special handlings
	SDL_EventType laltstate = SDL_KEYUP;
	SDL_EventType raltstate = SDL_KEYUP;
};

extern SDL_Block sdl;

#endif