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