xref: /haiku/src/tests/kits/game/chart/ChartWindow.h (revision b8ded2f89783a220c7b3019d48266a682cc79158)
1 /*
2 
3 	ChartWindow.h
4 
5 	by Pierre Raynaud-Richard.
6 
7 */
8 
9 /*
10 	Copyright 1999, Be Incorporated.   All Rights Reserved.
11 	This file may be used under the terms of the Be Sample Code License.
12 */
13 
14 #ifndef CHART_WINDOW_H
15 #define CHART_WINDOW_H
16 
17 #include <DirectWindow.h>
18 #include <OS.h>
19 #include <Locker.h>
20 #include <StringView.h>
21 #include <PictureButton.h>
22 
23 #include "ChartRender.h"
24 #include "ChartView.h"
25 
26 /* This window can be used in 3 modes : window mode is just a
27    normal window (that you move and resize freely), fullscreen
28    resize the window to adjust its content area to the full
29    size of the screen. Demo mode resize the window to have the
30    animate part of it fit the full screen. */
31 enum {
32 	WINDOW_MODE		= 0,
33 	FULLSCREEN_MODE	= 1,
34 	FULLDEMO_MODE	= 2
35 };
36 
37 /* Special animation mode. Comet create 2 comets flying around
38    randomaly. Novas add a couple start with flashing burst of
39    light. Battle was never implemented... */
40 enum {
41 	SPECIAL_NONE	= 0,
42 	SPECIAL_COMET	= 1,
43 	SPECIAL_NOVAS	= 2,
44 	SPECIAL_BATTLE	= 3
45 };
46 
47 /* Three types of display mode : line is supposed to use line
48    array to draw pixel (but is not currently implemented). Bitmap
49    use an offscreen BBitmap and DrawBitmap for each frame. Direct
50    use the DirectWindow API to draw directly on the screen. */
51 enum {
52 	DISPLAY_OFF		= 0,
53 	DISPLAY_LINE	= 1,
54 	DISPLAY_BITMAP	= 2,
55 	DISPLAY_DIRECT	= 3
56 };
57 
58 /* Five ways of moving the camera around : not at all, simple
59    rotation around the center of the starfield, slow straight
60    move, fast straight move, and a random move (flying around). */
61 enum {
62 	ANIMATION_OFF		= 0,
63 	ANIMATION_ROTATE	= 1,
64 	ANIMATION_SLOW_MOVE	= 2,
65 	ANIMATION_FAST_MOVE = 3,
66 	ANIMATION_FREE_MOVE = 4
67 };
68 
69 /* Three types of star field. A new random starfield is created
70    everytime you change the starfield type. The first will just
71    put stars randomly in space. The second will concentrate
72    star in 10 places. The last one will put half the star in a
73    big spiral galaxy, and the other one in a few amas. */
74 enum {
75 	SPACE_CHAOS		= 0,
76 	SPACE_AMAS		= 1,
77 	SPACE_SPIRAL	= 2
78 };
79 
80 /* All messages exchanged between the UI and the engine. */
81 enum {
82 	ANIM_OFF_MSG		= 1000,
83 	ANIM_SLOW_ROT_MSG	= 1001,
84 	ANIM_SLOW_MOVE_MSG	= 1002,
85 	ANIM_FAST_MOVE_MSG	= 1003,
86 	ANIM_FREE_MOVE_MSG	= 1004,
87 	DISP_OFF_MSG		= 2000,
88 	DISP_LINE_MSG		= 2001,
89 	DISP_BITMAP_MSG		= 2002,
90 	DISP_DIRECT_MSG		= 2003,
91 	OPEN_COLOR_MSG		= 3000,
92 	OPEN_DENSITY_MSG	= 3100,
93 	OPEN_REFRESH_MSG	= 3200,
94 	SPACE_CHAOS_MSG		= 3300,
95 	SPACE_AMAS_MSG		= 3301,
96 	SPACE_SPIRAL_MSG	= 3302,
97 	FULL_SCREEN_MSG		= 4000,
98 	AUTO_DEMO_MSG		= 4100,
99 	BACK_DEMO_MSG		= 4101,
100 	SECOND_THREAD_MSG	= 4200,
101 	COLORS_RED_MSG		= 5000,
102 	COLORS_GREEN_MSG	= 5001,
103 	COLORS_BLUE_MSG		= 5002,
104 	COLORS_YELLOW_MSG	= 5003,
105 	COLORS_ORANGE_MSG	= 5004,
106 	COLORS_PINK_MSG		= 5005,
107 	COLORS_WHITE_MSG	= 5006,
108 	SPECIAL_NONE_MSG	= 6000,
109 	SPECIAL_COMET_MSG	= 6001,
110 	SPECIAL_NOVAS_MSG	= 6002,
111 	SPECIAL_BATTLE_MSG	= 6003,
112 	COLOR_PALETTE_MSG	= 7000,
113 	STAR_DENSITY_MSG	= 8000,
114 	REFRESH_RATE_MSG	= 9000
115 };
116 
117 enum {
118 	/* Number of star used to generate the special animation */
119 	SPECIAL_COUNT_MAX	= 512,
120 	/* Number of keypoint used for the "random" animation */
121 	KEY_POINT_MAX		= 16
122 };
123 
124 /* Basic 3D point/vector class, used for basic vectorial
125    operations. */
126 class TPoint {
127 public:
128 	float   	x;
129 	float   	y;
130 	float   	z;
131 
132 	TPoint		operator* (const float k) const;
133 	TPoint		operator- (const TPoint& v2) const;
134 	TPoint		operator+ (const TPoint& v2) const;
135 	TPoint		operator^ (const TPoint& v2) const;
136 	float		Length() const;
137 };
138 
139 /* Basic 3x3 matrix used for 3D transform. */
140 class TMatrix {
141 public:
142 	float 		m[3][3];
143 
144 	TPoint		operator* (const TPoint& v) const;
145 	TPoint		Axis(int32 index);
146 	TMatrix		Transpose() const;
147 	void		Set(const float alpha, const float theta, const float phi);
148 };
149 
150 
151 class BBox;
152 class BView;
153 
154 /* The main window class, encapsulating both UI and engine. */
155 class ChartWindow : public BDirectWindow {
156 public:
157 		/* standard constructor and destructor */
158 				ChartWindow(BRect frame, const char *name);
159 virtual			~ChartWindow();
160 
161 		/* standard window members */
162 virtual	bool	QuitRequested();
163 virtual	void	MessageReceived(BMessage *message);
164 virtual void	ScreenChanged(BRect screen_size, color_space depth);
165 virtual	void	FrameResized(float new_width, float new_height);
166 
167 		/* this struct embedded all user settable parameters that
168 		   can be set by the UI. The idea is to solve all possible
169 		   synchronisation problem between the UI settings and the
170 		   engine (when using DirectWindow mode) by defining a
171 		   current setting state and a next setting state. The UI
172 		   touches only the next setting state, never the one
173 		   currently use by the engine. This way the engine doesn't
174 		   have to be synchronised with the UI. */
175 		struct setting {
176 			/* do we want to use the second thread ? */
177 			bool		second_thread;
178 			/* which ones of the 7 star colors are we using ? */
179 			bool		colors[7];
180 			/* what window configuration mode are we using ? */
181 			int32		fullscreen_mode;
182 			/* what special mode are we using ? */
183 			int32		special;
184 			/* what display mode are we using ? */
185 			int32		display;
186 			/* what starfield model are we using ? */
187 			int32		space_model;
188 			/* what camera animation are we using ? */
189 			int32		animation;
190 			/* what is the density of the current starfield
191 			   model ? */
192 			int32		star_density;
193 			/* what's the current required refresh rate ? */
194 			float		refresh_rate;
195 			/* what's the current background color for the animated
196 			   view ? */
197 			rgb_color	back_color;
198 			/* what's the current color_space of the screen ? */
199 			color_space	depth;
200 			/* what's the current dimension of the content area of
201 			   the window ? */
202 			int32		width, height;
203 
204 			/* used to copy a whole setting in another. */
205 			void		Set(setting *master);
206 		};
207 
208 		/* this union is used to store special animation information
209 		   that are defined per star. */
210 		typedef union {
211 			/* for the comet, it's a speed vector and to
212 			   counters to define how long the star will
213 			   continue before disappearing. */
214 			struct {
215 				float		dx;
216 				float		dy;
217 				float		dz;
218 				int32		count;
219 				int32		count0;
220 			} comet;
221 			/* for the novas, just counters to define the
222 			   pulse cycle of the star. */
223 			struct {
224 				float		count;
225 				int32		count0;
226 			} nova;
227 			/* battle was not implemented. */
228 			struct {
229 				int32		count;
230 			} battle;
231 		} special;
232 
233 	/* public instance members */
234 		/* the current instantenuous potential frame/rate
235 		   as display by the vue-meter. */
236 		int32			fInstantLoadLevel;
237 		/* the offscreen Bitmap used, if any. */
238 		BBitmap			*fOffscreen;
239 		/* the current active setting used by the engine */
240 		setting			fCurrentSettings;
241 
242 
243 
244 /* the private stuff... */
245 private:
246 	/* User Interface related stuff. */
247 		BBox		*fStatusBox;
248 		BBox		*fColorsBox;
249 		BBox		*fSpecialBox;
250 
251 		BView		*fLeftView;
252 		BView		*fTopView;
253 
254 		/* Find a window by its name if already opened. */
255 static	BWindow		*GetAppWindow(const char *name);
256 		/* Used to set the content of PictureButton. */
257 		BPicture	*ButtonPicture(bool active, int32 button_type);
258 		/* Those function create and handle the other settings
259 		   floating windows, for the background color, the star
260 		   density and the refresh rate. */
261 		void		OpenColorPalette(BPoint here);
262 		void		OpenStarDensity(BPoint here);
263 		void		OpenRefresh(BPoint here);
264 		/* Draw the state of the instant-load vue-meter */
265 		void		DrawInstantLoad(float frame_per_second);
266 		/* Print the performances numbers, based on the real framerate. */
267 		void		PrintStatNumbers(float fps);
268 
269 	/* Engine setting related functions. */
270 		/* Init the geometry engine of the camera at startup. */
271 		void		InitGeometry();
272 		/* Check and apply changes between a new setting state
273 		   and the currently used one. */
274 		void		ChangeSetting(setting new_set);
275 		/* Initialise a new starfield of the specified model. */
276 		void		InitStars(int32 model);
277 		/* Fill a star list with random stars in [0-1]x[0-1]x[0-1]. */
278 		void		FillStarList(star *list, int32 count);
279 		/* Init a new special animation of a specific type. */
280 		void		InitSpecials(int32 code);
281 		/* Change the star field colors depending a new set of
282 		   selected colors. */
283 		void		SetStarColors(int32	*color_list, int32 color_count);
284 		/* Change the global geometry of the camera when the
285 		   viewing area is resized. */
286 		void		SetGeometry(int32 dh, int32 dv);
287 		/* Change the color_space configuration of a buffer */
288 		void		SetColorSpace(buffer *buf, color_space depth);
289 		/* Used to sync the pre-offset matrix pointer whenever the buffer
290 		   bits pointer changes. */
291 		void		SetPatternBits(buffer *buf);
292 
293 	/* Engine processing related functions. */
294 		/* those functions are the two processing threads launcher */
295 static	int32		Animation(void *data);
296 static	int32		Animation2(void *data);
297 		/* After every camera move or rotation, reprocess the torus
298 		   cycle of the starfield to maintain the pyramid of vision
299 		   of the camera completly inside a 1x1x1 iteration of the
300 		   starfield. */
301 		void		SetCubeOffset();
302 		/* Process the camera animation for a specified time step */
303 		void		CameraAnimation(float time_factor);
304 		/* Used by the random move camera animation. */
305 		void		SelectNewTarget();
306 		void		FollowTarget();
307 		/* Process the special animation for a specified time step */
308 		void		AnimSpecials(float time_step);
309 		/* Sync the embedded camera state with the window class camera
310 		   state (before calling the embedded C-engine in ChartRender.c */
311 		void		SyncGeo();
312 		/* Control the star processing (done by 1 or 2 threads) and
313 		   executed by the embedded C-engine in ChartRender.c */
314 		void		RefreshStars(buffer *buf, float time_step);
315 
316 	/* Offscreen bitmap configuration related functions. */
317 		/* Used to update the state of the offscreen Bitmap to stay
318 		   in sync with the current settings. */
319 		void		CheckBitmap(color_space depth, int32 width, int32 height);
320 		/* Set the basic clipping of the offscreen Bitmap (everything
321 		   visible) */
322 		void		SetBitmapClipping(int32 width, int32 height);
323 		/* Draw the offscreen bitmap background. */
324 		void		SetBitmapBackGround();
325 
326 	/* DirectWindow related functions */
327 		/* Process a change of state in the direct access to the
328 		   frame buffer. */
329 		void		SwitchContext(direct_buffer_info *info);
330 public:
331 		/* this is the hook controling direct screen connection */
332 virtual void		DirectConnected(direct_buffer_info *info);
333 
334 
335 private:
336 	/* Pseudo-random generator state and increment function. */
337 		int32		fCrcAlea;
338 inline	void		CrcStep();
339 
340 
341 	/* Various private instance variables. */
342 		/* the next setting, as modified by the UI */
343 		setting			fNextSettings;
344 
345 
346 		/* the buffer descriptors for the offscreen bitmap and
347 		   the DirectWindow buffer. */
348 		buffer			fBitmapBuffer;
349 		buffer			fDirectBuffer;
350 
351 		/* current maximal dimensions of the offscreen Bitmap buffer */
352 		int32			fMaxWidth, fMaxHeight;
353 
354 		/* memorize previous state for switch between fullscreen
355 		   and window mode */
356 		BRect			fPreviousFrame;
357 		int32			fPreviousFullscreenMode;
358 
359 		/* cycling threshold for the cubic torus starfield, that
360 		   guarantees that the 1x1x1 sample will contain the full
361 		   pyramid of vision. */
362 		TPoint			fCut;
363 
364 		/* maximal depth of the pyramid of vision */
365 		float			fDepthRef;
366 
367 		int32			fBackColorIndex;
368 
369 		/* target frame duration, in microsecond. */
370 		bigtime_t		fFrameDelay;
371 
372 		/* various UI object that we need to reach directly. */
373 		BButton			*fOffwindowButton;
374 		ChartView		*fChartView;
375 		BStringView		*fCpuLoadView, *fFramesView;
376 		InstantView		*fInstantLoad;
377 		BPictureButton	*fColorButton, *fDensityButton, *fRefreshButton;
378 
379 		/* states used to describe the camera position, rotation
380 		   and dynamic (in other case than free move). */
381 		float			fCameraAlpha, fCameraTheta, fCameraPhi;
382 		float			fDynamicAlpha;
383 		float			fDynamicTheta;
384 		float			fDynamicPhi;
385 		int32			fCountAlpha, fCountTheta, fCountPhi;
386 		TPoint			fOrigin;
387 		TMatrix			fCamera;
388 		TMatrix			fCameraInvert;
389 
390 		/* the camera geometry descriptor required by the embedded
391 		   C-engine (just a copy of part of the previous states) */
392 		geometry		fGeometry;
393 
394 		/* states used by the free move camera animation */
395 		int32			fTrackingTarget;
396 		int32			fKeyPointCount;
397 		float			fSpeed, fTargetSpeed;
398 		float			fLastDynamicDelay;
399 		TPoint			fKeyPoints[KEY_POINT_MAX];
400 
401 		/* main starfield. */
402 		star_packet		fStars;
403 
404 		/* used for the special animation */
405 		TPoint			fComet[2];
406 		TPoint			fDeltaComet[2];
407 		special			*fSpecialList;
408 		star_packet		fSpecials;
409 
410 		/* the two processing threads. */
411 		thread_id		fAnimationThread;
412 		thread_id		fSecondAnimationThread;
413 
414 		/* context of the second processing thread (when used). */
415 		float			fSecondThreadThreshold;
416 		buffer			*fSecondThreadBuffer;
417 		sem_id			fSecondThreadLock;
418 		sem_id			fSecondThreadRelease;
419 		bigtime_t			fSecondThreadDelay;
420 		star_packet		fStars2;
421 		star_packet		fSpecials2;
422 
423 		/* Flag used to terminate the processing threads */
424 		bool			fKillThread;
425 
426 		/* Direct connection status */
427 		bool			fDirectConnected;
428 
429 		/* used to synchronise the star animation drawing. */
430 		sem_id			fDrawingLock;
431 };
432 
433 #endif
434