This repository has been archived by the owner on Mar 8, 2024. It is now read-only.
forked from markol/machines
-
Notifications
You must be signed in to change notification settings - Fork 2
/
display.hpp
211 lines (170 loc) · 6.67 KB
/
display.hpp
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
/*
* D I S P L A Y . H P P
* (c) Charybdis Limited, 1997. All Rights Reserved
*/
#ifndef _REN_DISPLAY_HPP
#define _REN_DISPLAY_HPP
#include "base/base.hpp"
#include <SDL.h>
#include "render/render.hpp"
#include <vector>
template <class T> class ctl_list;
class SysPathName;
class RenSurface;
class RenCursor2d;
class RenIDisplay;
// When a Direct3D app goes into full-screen exculsive mode, this class
// is used to set the mode. Probably should be merged with DevDisplay?
class RenDisplay
{
public:
RenDisplay(SDL_Window* wnd);
~RenDisplay();
// Go to full-screen exclusive mode. Returns true to indicate success.
bool useFullScreen();
void resetToNormalScreen();
bool fullScreen() const;
class Mode
{
public:
Mode() = default;
Mode(const Mode& m) = default;
Mode& operator=(const Mode& m)
{
width_ = m.width_;
height_ = m.height_;
depth_ = m.depth_;
rate_ = m.rate_;
mode_ = m.mode_;
return *this;
}
bool operator==(const Mode& m) const
{
return width_ == m.width_ && height_ == m.height_ && (rate_ == m.rate_ || rate_ == 0 || m.rate_ == 0);
}
bool isValid() const { return width_; }
int width() const { return width_; }
int height() const { return height_; }
int bitDepth() const { return depth_; }
int refreshRate() const { return rate_; }
int pixels() const { return width_ * height_; }
int memoryRequired() const { return (pixels() * depth_) / 8; }
const SDL_DisplayMode& mode() const { return mode_; }
private:
// Only RenDisplay can create modes. Thus, clients are prevented from
// requesting modes that aren't actually possible.
friend class RenDisplay;
friend class RenDDEnumerator;
Mode(int w, int h, int r)
: width_(w)
, height_(h)
, depth_(32)
, rate_(r)
{
}
Mode(const SDL_DisplayMode& m)
: width_(m.w)
, height_(m.h)
, depth_(SDL_BITSPERPIXEL(m.format))
, rate_(m.refresh_rate)
, mode_(m)
{
}
int width_{};
int height_{};
int depth_{};
int rate_{};
SDL_DisplayMode mode_{};
};
// Clients cannot create modes, they must use modeList to get
// a list of modes, choose one and pass a reference to useMode.
using Modes = std::vector<Mode>;
const Modes& modeList() const;
bool useMode(const Mode&);
const Mode& currentMode() const;
void buildDisplayModesList();
const Mode getDesktopDisplayMode() const;
const Mode getFailSafeDisplayMode() const;
const Mode findMode(int width, int height, int refreshRate);
const Mode getWindowedMode(int width, int height) const;
const Mode& lowestAllowedMode() const;
bool lowestAllowedMode(const Mode& lowMode);
bool lowestAllowedMode(int width, int height, int depth);
const Mode& highestAllowedMode() const;
bool setHighestAllowedMode(uint32_t maxMemory);
bool setHighestAllowedMode();
// If there's not enough video memory to create all the required
// surfaces at the current resolution, this method can be used to
// switch to a lower resolution, at the *same* bit depth. Returns
// false if there isn't a lower mode available.
// PRE(modeList().size() > 0);
bool useLowerMode();
// Finds the nearest mode for which Mode::pixels() <= pixels and
// for which the depth is an *exact* match. Returns false if there
// was no suitable mode.
// PRE(modeList().size() > 0);
bool useNearestMode(int pixels, int bitDepth);
// Finds the lowest resolution mode for the given depth. Returns false
// if there was no mode of the given depth. If no depth is specified,
// you get the lowest mode.
// PRE(modeList().size() > 0);
bool useLowestMode(int bitDepth);
enum MemoryType
{
SYSTEM_MEMORY,
VIDEO_MEMORY
};
// Call when rendering is finished to swap the front and back buffers.
// If zbDepth==0 no z-buffer is created.
bool createSurfaces(MemoryType zbType, int zbDepth);
// Updates the cursor, if necessary.
void startFrame();
void flipBuffers(RenSurface backSurf);
void flipBuffers();
// Flip the buffers but copy and stretch a sub-area of the back buffer
// onto the front buffer. The fromArea rectangle in the back buffer is
// stretched to entirely cover the frontBuffer.
void stretchFlipBuffers(RenSurface backSurf, RenSurface frontSurf, const Ren::Rect& fromArea);
// This method should be called every frame in case Alt-Tab has been
// pressed. Returns false if one of the buffers is lost and it could
// not be restored. Rendering should not proceed if this returns false.
bool checkForLostSurfaces();
// Beware: if this display releases the front buffer, back buffer
// pointers may become invalid. There's not much that can be done
// about this, apart from writing a very sophisticated version of
// COMPtr which knows about the dependencies.
// LPDIRECTDRAWSURFACE backBuffer();
// IDirectDrawSurface* backBuffer();
// IDirectDrawSurface* frontBuffer();
void useCursor(const RenCursor2d*);
const RenCursor2d* currentCursor() const;
void setCursorGrabEnabled(bool enabled);
void supportsGammaCorrection(bool);
bool supportsGammaCorrection() const;
void gammaCorrection(const double& gammaCorrection);
const double& gammaCorrection() const;
bool isPrimaryDriver() const;
uint32_t frameNumber() const;
SDL_Window* window();
RenIDisplay& displayImpl();
const RenIDisplay& displayImpl() const;
// PRE(pImpl_!=NULL);
void CLASS_INVARIANT;
private:
// **Important** the back buffer must be released before the primary. The
// order of declartion is critical. See note in fallibleCreateSurfaces.
RenIDisplay* pImpl_;
bool fallibleCreateSurfaces(MemoryType zbType, int zbDepth);
friend class RenDDEnumerator;
// Operations deliberately revoked
RenDisplay(const RenDisplay&);
RenDisplay& operator=(const RenDisplay&);
bool operator==(const RenDisplay&);
};
std::ostream& operator<<(std::ostream& o, const RenDisplay& t);
std::ostream& operator<<(std::ostream& o, const RenDisplay::Mode& t);
bool operator<(const RenDisplay::Mode& mode1, const RenDisplay::Mode& mode2);
bool operator>(const RenDisplay::Mode& mode1, const RenDisplay::Mode& mode2);
bool operator>=(const RenDisplay::Mode& mode1, const RenDisplay::Mode& mode2);
#endif
/* End DISPLAY.HPP **************************************************/