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