1 //Copyright Paul Reiche, Fred Ford. 1992-2002
2
3 /*
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #include "gfxintrn.h"
20 #include "libs/graphics/gfx_common.h"
21 #include "libs/graphics/drawcmd.h"
22 #include "libs/timelib.h"
23 #include "libs/misc.h"
24 // for TFB_DEBUG_HALT
25
26
27 int ScreenWidth;
28 int ScreenHeight;
29 int ScreenWidthActual;
30 int ScreenHeightActual;
31 int ScreenColorDepth;
32 int GraphicsDriver;
33 int TFB_DEBUG_HALT = 0;
34
35 volatile int TransitionAmount = 255;
36 RECT TransitionClipRect;
37
38 static int gscale = GSCALE_IDENTITY;
39 static int gscale_mode = TFB_SCALE_NEAREST;
40
41 void
DrawFromExtraScreen(RECT * r)42 DrawFromExtraScreen (RECT *r)
43 {
44 TFB_DrawScreen_Copy(r, TFB_SCREEN_EXTRA, TFB_SCREEN_MAIN);
45 }
46
47 void
LoadIntoExtraScreen(RECT * r)48 LoadIntoExtraScreen (RECT *r)
49 {
50 TFB_DrawScreen_Copy(r, TFB_SCREEN_MAIN, TFB_SCREEN_EXTRA);
51 }
52
53 int
SetGraphicScale(int scale)54 SetGraphicScale (int scale)
55 {
56 int old_scale = gscale;
57 gscale = (scale ? scale : GSCALE_IDENTITY);
58 return old_scale;
59 }
60
61 int
GetGraphicScale(void)62 GetGraphicScale (void)
63 {
64 return gscale;
65 }
66
67 int
SetGraphicScaleMode(int mode)68 SetGraphicScaleMode (int mode)
69 {
70 int old_mode = gscale_mode;
71 assert (mode >= TFB_SCALE_NEAREST && mode <= TFB_SCALE_TRILINEAR);
72 gscale_mode = mode;
73 return old_mode;
74 }
75
76 int
GetGraphicScaleMode(void)77 GetGraphicScaleMode (void)
78 {
79 return gscale_mode;
80 }
81
82 /* Batching and Unbatching functions. A "Batch" is a collection of
83 DrawCommands that will never be flipped to the screen half-rendered.
84 BatchGraphics and UnbatchGraphics function vaguely like a non-blocking
85 recursive lock to do this respect. */
86 void
BatchGraphics(void)87 BatchGraphics (void)
88 {
89 TFB_BatchGraphics ();
90 }
91
92 void
UnbatchGraphics(void)93 UnbatchGraphics (void)
94 {
95 TFB_UnbatchGraphics ();
96 }
97
98 /* Sleeps this thread until all Draw Commands queued by that thread have
99 been processed. */
100
101 void
FlushGraphics(void)102 FlushGraphics (void)
103 {
104 TFB_DrawScreen_WaitForSignal ();
105 }
106
107 static void
ExpandRect(RECT * rect,int expansion)108 ExpandRect (RECT *rect, int expansion)
109 {
110 if (rect->corner.x - expansion >= 0)
111 {
112 rect->extent.width += expansion;
113 rect->corner.x -= expansion;
114 }
115 else
116 {
117 rect->extent.width += rect->corner.x;
118 rect->corner.x = 0;
119 }
120
121 if (rect->corner.y - expansion >= 0)
122 {
123 rect->extent.height += expansion;
124 rect->corner.y -= expansion;
125 }
126 else
127 {
128 rect->extent.height += rect->corner.y;
129 rect->corner.y = 0;
130 }
131
132 if (rect->corner.x + rect->extent.width + expansion <= ScreenWidth)
133 rect->extent.width += expansion;
134 else
135 rect->extent.width = ScreenWidth - rect->corner.x;
136
137 if (rect->corner.y + rect->extent.height + expansion <= ScreenHeight)
138 rect->extent.height += expansion;
139 else
140 rect->extent.height = ScreenHeight - rect->corner.y;
141 }
142
143 void
SetTransitionSource(const RECT * pRect)144 SetTransitionSource (const RECT *pRect)
145 {
146 RECT ActualRect;
147
148 if (pRect)
149 { /* expand the rect to accomodate scalers in OpenGL mode */
150 ActualRect = *pRect;
151 pRect = &ActualRect;
152 ExpandRect (&ActualRect, 2);
153 }
154 TFB_DrawScreen_Copy (pRect, TFB_SCREEN_MAIN, TFB_SCREEN_TRANSITION);
155 }
156
157 // ScreenTransition() is synchronous (does not return until transition done)
158 void
ScreenTransition(int TransType,const RECT * pRect)159 ScreenTransition (int TransType, const RECT *pRect)
160 {
161 const TimePeriod DURATION = ONE_SECOND * 31 / 60;
162 TimeCount startTime;
163 (void) TransType; /* dodge compiler warning */
164
165 if (pRect)
166 {
167 TransitionClipRect = *pRect;
168 }
169 else
170 {
171 TransitionClipRect.corner.x = 0;
172 TransitionClipRect.corner.y = 0;
173 TransitionClipRect.extent.width = ScreenWidth;
174 TransitionClipRect.extent.height = ScreenHeight;
175 }
176
177 TFB_UploadTransitionScreen ();
178
179 TransitionAmount = 0;
180 FlushGraphics ();
181 startTime = GetTimeCounter ();
182 while (TransitionAmount < 255)
183 {
184 TimePeriod deltaT;
185 int newAmount;
186
187 SleepThread (ONE_SECOND / 100);
188
189 deltaT = GetTimeCounter () - startTime;
190 newAmount = deltaT * 255 / DURATION;
191 if (newAmount > 255)
192 newAmount = 255;
193
194 TransitionAmount = newAmount;
195 }
196 }
197