xref: /haiku/src/tests/kits/game/chart/ChartWindow.h (revision d3d8b26997fac34a84981e6d2b649521de2cc45a)
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(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	long		Animation(void *data);
296 static	long		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		crc_alea;
338 inline	void		CrcStep();
339 
340 
341 	/* Various private instance variables. */
342 		/* the next setting, as modified by the UI */
343 		setting			next_set;
344 
345 		/* a boolean used to enable a work-around for a bug in
346 		   the DirectWindow flags setting. Only needed for the
347 		   release 3.0 */
348 		bool			need_r3_buffer_reset_work_around;
349 
350 		/* the buffer descriptors for the offscreen bitmap and
351 		   the DirectWindow buffer. */
352 		buffer			bitmap_buffer;
353 		buffer			direct_buffer;
354 
355 		/* current maximal dimensions of the offscreen Bitmap buffer */
356 		int32			max_width, max_height;
357 
358 		/* memorize previous state for switch between fullscreen
359 		   and window mode */
360 		BRect			PreviousFrame;
361 		int32			previous_fullscreen_mode;
362 
363 		/* cycling threshold for the cubic torus starfield, that
364 		   guarantees that the 1x1x1 sample will contain the full
365 		   pyramid of vision. */
366 		TPoint			cut;
367 
368 		/* maximal depth of the pyramid of vision */
369 		float			depth_ref;
370 
371 		int32			back_color_index;
372 
373 		/* target frame duration, in microsecond. */
374 		bigtime_t		frame_delay;
375 
376 		/* various UI object that we need to reach directly. */
377 		BButton			*offwindow_button;
378 		ChartView		*fChartView;
379 		BStringView		*cpu_load, *frames;
380 		InstantView		*fInstantLoad;
381 		BPictureButton	*color_button, *density_button, *refresh_button;
382 
383 		/* states used to describe the camera position, rotation
384 		   and dynamic (in other case than free move). */
385 		float			camera_alpha, camera_theta, camera_phi;
386 		float			d_alpha;
387 		float			d_theta;
388 		float			d_phi;
389 		int32			cnt_alpha, cnt_theta, cnt_phi;
390 		TPoint			origin;
391 		TMatrix			camera;
392 		TMatrix			camera_invert;
393 
394 		/* the camera geometry descriptor required by the embedded
395 		   C-engine (just a copy of part of the previous states) */
396 		geometry		geo;
397 
398 		/* states used by the free move camera animation */
399 		int32			tracking_target;
400 		int32			key_point_count;
401 		float			speed, target_speed;
402 		float			last_dynamic_delay;
403 		TPoint			key_points[KEY_POINT_MAX];
404 
405 		/* main starfield. */
406 		star_packet		stars;
407 
408 		/* used for the special animation */
409 		TPoint			comet[2];
410 		TPoint			delta_comet[2];
411 		special			*special_list;
412 		star_packet		specials;
413 
414 		/* the two processing threads. */
415 		thread_id		fAnimationThread;
416 		thread_id		fSecondAnimationThread;
417 
418 		/* context of the second processing thread (when used). */
419 		float			second_thread_threshold;
420 		buffer			*second_thread_buffer;
421 		sem_id			second_thread_lock;
422 		sem_id			second_thread_release;
423 		bigtime_t		second_thread_delay;
424 		star_packet		stars2;
425 		star_packet		specials2;
426 
427 		/* Flag used to terminate the processing threads */
428 		bool			fKillThread;
429 
430 		/* Direct connection status */
431 		bool			fDirectConnected;
432 
433 		/* used to synchronise the star animation drawing. */
434 		sem_id			fDrawingLock;
435 };
436 
437 #endif
438