home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / System / Swatch / Development / swatch 1.7 / about.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-12  |  12.4 KB  |  555 lines  |  [TEXT/KAHL]

  1. /**
  2.  
  3.     about.c
  4.     Copyright (c) 1990-1992, joe holt
  5.  
  6.  **/
  7.  
  8.  
  9. /**-----------------------------------------------------------------------------
  10.  **
  11.  **    Headers
  12.  **
  13.  **/
  14.  
  15. #include <FixMath.h>
  16. #include <Folders.h>
  17. #include <Sound.h>
  18.  
  19. #ifndef __about__
  20. #include "about.h"
  21. #endif
  22. #ifndef __ctypes__
  23. #include "ctypes.h"
  24. #endif
  25. #ifndef __content__
  26. #include "content.h"
  27. #endif
  28. #ifndef __display__
  29. #include "display.h"
  30. #endif
  31. #ifndef __prefs__
  32. #include "prefs.h"
  33. #endif
  34. #ifndef __resources__
  35. #include "resources.h"
  36. #endif
  37. #ifndef __swatch__
  38. #include "swatch.h"
  39. #endif
  40.  
  41.  
  42. /**-----------------------------------------------------------------------------
  43.  **
  44.  ** Private Constants
  45.  **
  46.  **/
  47.  
  48. #define TICK_FREQ            2
  49. #define CHAR_WIDTH            8
  50. #define CHAR_HEIGHT            12
  51.  
  52. #define MAX_BITS            25
  53.  
  54. #define LAUNCH_FREQ            (10)
  55. #define SWIRL_DELAY            (9*60 + 52)
  56. #define BY_DELAY            (15*60 + 30)
  57. #define BIT_DELAY            (18*60 + 40)
  58. #define INTER_BIT_DELAY        (500)
  59. #define INTER_BIT_INC        (50)
  60. #define ERASE2_DELAY        (32*60)
  61. #define FIRST_BEAT_DELAY    (30)
  62. #define CREDITS2_DELAY        (28*60)
  63. #define HEART_FRAMES        (200)
  64.  
  65.  
  66. /**-----------------------------------------------------------------------------
  67.  **
  68.  ** Private Variables
  69.  **
  70.  **/
  71.  
  72. #define MAX_FLYING            12
  73. static char credits[] = "Swatch 1.7d9";
  74. static char credits2[] = "\pCopyright ©1992, joe holt";
  75.  
  76.  
  77. typedef struct {
  78.     Boolean flying;
  79.     Fixed x, y, dx, dy;
  80.     int16 size;
  81.     Rect r;
  82. } Flying_bit;
  83.  
  84. typedef struct {
  85.     int16 stage;
  86.     char c;
  87.     uns32 next_tick;
  88.     Fixed x, y, dx, dy, ddx, ddy;
  89.     Fixed maxx, maxy, dmax;
  90.     int16 num_bits, num_bits2;
  91.     Flying_bit bit[MAX_BITS];
  92.     Rect r;
  93. } Flyer;
  94.  
  95.  
  96. /**-----------------------------------------------------------------------------
  97.  **
  98.  ** Private Functions
  99.  **
  100.  **/
  101.  
  102. static Handle Read_riff( void );
  103. static void Dispose_riff( Handle riff );
  104.  
  105. static int16 random( int16 max );
  106.  
  107.  
  108. /*******************************************************************************
  109.  **
  110.  **    Public Variables
  111.  **
  112.  **/
  113.  
  114.  
  115. /*******************************************************************************
  116.  **
  117.  **    Public Functions
  118.  **
  119.  **/
  120.  
  121. static Handle Read_riff( void )
  122. {
  123.     short prefs_VRefNum;
  124.     int32 prefs_DirID;
  125.     OSErr err;
  126.     HParamBlockRec read_PB;
  127.     Handle riff;
  128.  
  129.     riff = nil;
  130.     read_PB.ioParam.ioRefNum = 0;
  131.  
  132.     err = FindFolder( kOnSystemDisk, kPreferencesFolderType, kDontCreateFolder,
  133.             &prefs_VRefNum, &prefs_DirID );
  134.     if ( err ) return nil;
  135.  
  136.     read_PB.ioParam.ioNamePtr = (StringPtr) pstr(Prefs_riffname_STR_x);
  137.     read_PB.ioParam.ioVRefNum = prefs_VRefNum;
  138.     read_PB.fileParam.ioDirID = prefs_DirID;
  139.     read_PB.ioParam.ioVersNum = 0;
  140.     read_PB.ioParam.ioPermssn = 0;
  141.     read_PB.ioParam.ioMisc = NULL;
  142.     if ( PBHOpen( &read_PB, FALSE ) ) goto no_riff;
  143.  
  144.     if ( PBGetEOF( (ParamBlockRec *) &read_PB, FALSE ) ) goto no_riff;
  145.  
  146.     if ( !( riff = MFTempNewHandle( (Size) read_PB.ioParam.ioMisc, &err ) ) )
  147.         goto no_riff;
  148.     MFTempHLock( riff, &err );
  149.  
  150.     read_PB.ioParam.ioBuffer = (Ptr) StripAddress( *riff );
  151.     read_PB.ioParam.ioReqCount = (int32) read_PB.ioParam.ioMisc;
  152.     read_PB.ioParam.ioPosMode = fsFromStart;
  153.     read_PB.ioParam.ioPosOffset = 0;
  154.     if ( PBRead( (ParamBlockRec *) &read_PB, FALSE ) ) goto no_riff;
  155.  
  156.     PBClose( (ParamBlockRec *) &read_PB, FALSE );
  157.     return riff;
  158.  
  159. no_riff:
  160.     if ( read_PB.ioParam.ioRefNum ) PBClose( (ParamBlockRec *) &read_PB, FALSE );
  161.  
  162.     if ( riff ) DisposHandle( riff );
  163.     return nil;
  164. }
  165.  
  166.  
  167. static void Dispose_riff( Handle riff )
  168. {
  169.     DisposeHandle( riff );
  170. }
  171.  
  172.  
  173. void Do_about( WindowPtr the_window )
  174. {
  175.     Handle fly_handle;
  176.     OSErr err;
  177.     Flyer *fly;
  178.     Flyer *f;
  179.     Flying_bit *b;
  180.     int16 i, j;
  181.     int16 launch_c;
  182.     uns32 next_launch, ticker, start_ticks, swirl_delay;
  183.     int16 num_active;
  184.     Fixed window_right, window_bottom, sx, sy, byx, byy;
  185.     Boolean got_beat;
  186.     int16 inter_bit_delay;
  187.     Handle snd;
  188.     SndChannelPtr chan;
  189.  
  190.     fly_handle = MFTempNewHandle( MAX_FLYING * sizeof( Flyer ), &err );
  191.     if ( !fly_handle ) return;
  192.  
  193.     HLock( fly_handle );
  194.     fly = (Flyer *) StripAddress( *fly_handle );
  195.  
  196.     ClipRect( &the_window->portRect );
  197.     snd = Read_riff();
  198.  
  199.     HideCursor();
  200.     Set_back_color( HEAP_UNLOCKED_COLOR );
  201.     Set_fore_color( HEAP_LOCKED_COLOR );
  202.  
  203.     EraseRect( &the_window->portRect );
  204.     window_right = (int32) the_window->portRect.right << 16;
  205.     window_bottom = (int32) the_window->portRect.bottom << 16;
  206.  
  207.     for ( f = fly, i = MAX_FLYING; i; --i, ++f ) {
  208.         Fixed n, ni, sp;
  209.  
  210.         f->stage = 0;
  211.         f->num_bits2 = f->num_bits = random( MAX_BITS / 2 ) + MAX_BITS / 2;
  212.         n = FixDiv( (int32) random( 360 ) << 16, 0x00394FEF /* 2pi / 360 */ );
  213.         ni = FixDiv( 0x0006487F /* 2pi */, (int32) f->num_bits << 16 );
  214.         for (  b = f->bit, j = f->num_bits; j; --j, ++b ) {
  215.             b->flying = TRUE;
  216.             SetRect( &b->r, 0, 0, 0, 0 );
  217.             b->size = random( 10 ) + 5;
  218.             sp = (int32) b->size << 16;
  219.             b->size = (15 - b->size) / 5 + 1;
  220.             b->dx = FixMul( Frac2Fix( FracCos( n ) ), sp );
  221.             b->dy = FixMul( Frac2Fix( FracSin( n ) ), sp );
  222.             n += ni;
  223.         }
  224.     }
  225.  
  226.     if ( snd ) {
  227.         chan = NULL;
  228.         if ( !SndNewChannel( &chan, 0, 0, NULL ) )
  229.             SndPlay( chan, snd, TRUE );
  230.     }
  231.     start_ticks = TickCount();
  232.  
  233.     sx = FixDiv( window_right, 2L << 16 ) + (12L << 16);
  234.     sy = FixDiv( window_bottom, 2L << 16 ) - (165L << 16);
  235.     byx = FixDiv( window_right, 2L << 16 ) - (65L << 16);
  236.     byy = FixDiv( window_bottom, 2L << 16 ) + (19L << 16);
  237.     swirl_delay = SWIRL_DELAY;
  238.     if ( sy < 0 )
  239.         swirl_delay = swirl_delay - ( FixMul( (175L << 16) + sy, 0x00002800 ) >> 16 );
  240.     next_launch = start_ticks + swirl_delay;
  241.     got_beat = FALSE;
  242.     launch_c = 0;
  243.     num_active = MAX_FLYING;
  244.     inter_bit_delay = 1;
  245.     while ( !Button() && num_active ) {
  246.         for ( f = fly, i = MAX_FLYING; i; --i, ++f ) {
  247.  
  248.             switch ( f->stage ) {
  249.             case 0:
  250.                 if ( got_beat ) {
  251.                     f->stage = 2;
  252.                     continue;
  253.                 }
  254.                 if ( TickCount() < start_ticks + FIRST_BEAT_DELAY )
  255.                     continue;
  256.  
  257.                 got_beat = TRUE;
  258.                 f->r.top = -40;
  259.                 f->r.bottom = -40 + CELL_HEIGHT * 2;
  260.                 f->r.left = the_window->portRect.right / 2 - 121;
  261.                 f->r.right = f->r.left + 242;
  262.                 f->stage++;
  263.                 f->next_tick = 0;
  264.                 break;
  265.  
  266.             case 1: {
  267.                 Rect r;
  268.  
  269.                 if ( TickCount() < f->next_tick )
  270.                     continue;
  271.  
  272.                 f->next_tick = TickCount() + TICK_FREQ * 2;
  273.                 ScrollRect( &f->r, 0, 1, the_window->clipRgn );
  274.                 OffsetRect( &f->r, 0, 1 );
  275.  
  276.                 if ( f->r.top < 1 ) {
  277.                     r = f->r;
  278.                     Set_fore_color_or_pattern( BLACK_COLOR );
  279.                     MoveTo( r.left + 20, r.top + CELL_HEIGHT - 2 );
  280.                     DrawString( (StringPtr) "\pLocked" );
  281.                     MoveTo( r.left + 100, r.top + CELL_HEIGHT - 2 );
  282.                     DrawString( (StringPtr) "\pUnlocked" );
  283.                     MoveTo( r.left + 180, r.top + CELL_HEIGHT - 2 );
  284.                     DrawString( (StringPtr) "\pFree" );
  285.  
  286.                     r.top += CELL_HEIGHT + 2;
  287.                     r.bottom -= 2;
  288.                     Set_fore_color_or_pattern( HEAP_BORDER_COLOR );
  289.                     FrameRect( &r );
  290.                     InsetRect( &r, 1, 1 );
  291.     
  292.                     r.left = r.right - 80;
  293.                     Set_fore_color_or_pattern( HEAP_FREE_COLOR );
  294.                     PaintRect( &r );
  295.                     r.left -= 80;
  296.                     r.right -= 80;
  297.                     Set_fore_color_or_pattern( HEAP_UNLOCKED_COLOR );
  298.                     PaintRect( &r );
  299.                     r.left -= 80;
  300.                     r.right -= 80;
  301.                     Set_fore_color_or_pattern( HEAP_LOCKED_COLOR );
  302.                     PaintRect( &r );
  303.                 }
  304.                 else {
  305.                     RgnHandle aRgn;
  306.                     
  307.                     ClipRect( &the_window->portRect );
  308.                     aRgn = NewRgn();
  309.                     r = f->r;
  310.                     r.top += CELL_HEIGHT + 2;
  311.                     r.bottom -= 2;
  312.                     RectRgn( aRgn, &r );
  313.                     DiffRgn( the_window->clipRgn, aRgn, the_window->clipRgn );
  314.  
  315.                     r.top = f->r.top + 5;
  316.                     r.bottom = r.top + CHAR_HEIGHT;
  317.                     r.left = f->r.left + 20;
  318.                     r.right = r.left + StringWidth( (StringPtr) "\pLocked" );
  319.                     RectRgn( aRgn, &r );
  320.                     DiffRgn( the_window->clipRgn, aRgn, the_window->clipRgn );
  321.  
  322.                     r.left = f->r.left + 100;
  323.                     r.right = r.left + StringWidth( (StringPtr) "\pUnlocked" );
  324.                     RectRgn( aRgn, &r );
  325.                     DiffRgn( the_window->clipRgn, aRgn, the_window->clipRgn );
  326.  
  327.                     r.left = f->r.left + 180;
  328.                     r.right = r.left + StringWidth( (StringPtr) "\pFree" );
  329.                     RectRgn( aRgn, &r );
  330.                     DiffRgn( the_window->clipRgn, aRgn, the_window->clipRgn );
  331.  
  332.                     DisposeRgn( aRgn );
  333.                     f->stage++;
  334.                     continue;
  335.                 }
  336.                 ClipRect( &the_window->portRect );
  337.                 break;
  338.             }
  339.  
  340.             case 2:
  341.                 if ( TickCount() < next_launch )
  342.                     continue;
  343.  
  344.                 f->stage++;
  345.                 if ( launch_c < 20 ) {
  346.                     f->maxx = 18L << 16;
  347.                     f->maxy = 18L << 16;
  348.                     f->dx = -f->maxx;
  349.                     f->dy = 0;
  350.                     f->x = sx;
  351.                     f->y = sy;
  352.                     f->ddx = -1L << 16;
  353.                     f->ddy = 1L << 16;
  354.                     f->dmax = 0x1DFF;
  355.                     sx += (int32) CHAR_WIDTH << 16;
  356.                     f->next_tick = 0;
  357.                 }
  358.                 else {
  359.                     f->maxx = 0;
  360.                     f->maxy = 0;
  361.                     f->dx = 0;
  362.                     f->dy = 0;
  363.                     f->x = byx;
  364.                     f->y = byy;
  365.                     f->ddx = 0;
  366.                     f->ddy = 0;
  367.                     f->dmax = 0;
  368.                     byx += (int32) CHAR_WIDTH << 16;
  369.                     f->next_tick = start_ticks + BY_DELAY + random( 100 );
  370.                 }
  371.                 f->c = credits[launch_c++];
  372.                 SetRect( &f->r, 0, 0, 0, 0 );
  373.                 next_launch = TickCount() + LAUNCH_FREQ;
  374.                 break;
  375.  
  376.             case 3:
  377.                 if ( TickCount() < f->next_tick )
  378.                     continue;
  379.  
  380.                 f->next_tick = TickCount() + TICK_FREQ;
  381.     
  382.                 f->x += f->dx;
  383.                 f->y += f->dy;
  384.                 f->dx += f->ddx;
  385.                 if ( f->ddx > 0 && f->dx >= f->maxx ) {
  386.                     f->ddx = -f->ddx;
  387.                     f->dx = f->maxx;
  388.                 }
  389.                 else if (f->ddx < 0 && f->dx <= -f->maxx) {
  390.                     f->ddx = -f->ddx;
  391.                     f->dx = -f->maxx;
  392.                 }
  393.                 f->dy += f->ddy;
  394.                 if ( f->ddy > 0 && f->dy >= f->maxy ) {
  395.                     f->ddy = -f->ddy;
  396.                     f->dy = f->maxy;
  397.                 }
  398.                 else if (f->ddy < 0 && f->dy <= -f->maxy) {
  399.                     f->ddy = -f->ddy;
  400.                     f->dy = -f->maxy;
  401.                 }
  402.                 f->maxx -= f->dmax;
  403.                 f->maxy -= f->dmax;
  404.             
  405.                 EraseRect( &f->r );
  406.                 f->r.left = f->x >> 16;
  407.                 f->r.bottom = (f->y >> 16) + 2;
  408.                 f->r.right = f->r.left + CHAR_WIDTH;
  409.                 f->r.top = f->r.bottom - CHAR_HEIGHT;
  410.         
  411.                 MoveTo( f->r.left, f->r.bottom - 2 );
  412.                 DrawChar( f->c );
  413.  
  414.                 if ( f->maxx <= 0 || f->maxy <= 0 ) {
  415.                     f->stage++;
  416.                     for ( j = f->num_bits, b = f->bit; j; --j, ++b ) {
  417.                         b->x = f->x + (CHAR_WIDTH / 2 << 16);
  418.                         b->y = f->y - (CHAR_HEIGHT / 2 << 16);
  419.                     }
  420.                 }
  421.                 break;
  422.  
  423.             case 4:
  424.                 if ( TickCount() < start_ticks + BIT_DELAY )
  425.                     continue;
  426.  
  427.                 f->next_tick = TickCount() + random( inter_bit_delay );
  428.                 if ( inter_bit_delay < INTER_BIT_DELAY )
  429.                     inter_bit_delay += INTER_BIT_INC;
  430.                 f->stage++;
  431.             /* fall into next */
  432.             case 5:
  433.                 if ( (TickCount() & 0xF) == (f->next_tick & 0xF) ) {
  434.                     f->r.left = f->x >> 16;
  435.                     f->r.bottom = (f->y >> 16) + 2;
  436.             
  437.                     MoveTo( f->x >> 16, f->y >> 16 );
  438.                     DrawChar( f->c );
  439.                 }
  440.  
  441.                 if ( TickCount() < f->next_tick )
  442.                     continue;
  443.  
  444.                 f->r.left = f->x >> 16;
  445.                 f->r.bottom = (f->y >> 16) + 2;
  446.                 f->r.right = f->r.left + CHAR_WIDTH;
  447.                 f->r.top = f->r.bottom - CHAR_HEIGHT;
  448.                 EraseRect( &f->r );
  449.                 f->stage++;
  450.             /* fall into next */
  451.             case 6:
  452.                 if ( TickCount() < f->next_tick )
  453.                     continue;
  454.  
  455.                 for ( j = f->num_bits, b = f->bit; j; --j, ++b ) {
  456.                     if ( b->flying ) {
  457.                         EraseRect( &b->r );
  458.     
  459.                         b->x += b->dx;
  460.                         b->y += b->dy;
  461.                         if ( b->x < 0 || b->x > window_right ||
  462.                                 b->y < 0 || b->y > window_bottom ) {
  463.                             b->flying = FALSE;
  464.                             if ( !--f->num_bits2 ) {
  465.                                 f->stage++;
  466.                                 f->next_tick = start_ticks + CREDITS2_DELAY;
  467.                                 continue;
  468.                             }
  469.                         }
  470.                         else {
  471.                             b->r.left = b->x >> 16;
  472.                             b->r.right = b->r.left + b->size;
  473.                             b->r.top = b->y >> 16;
  474.                             b->r.bottom = b->r.top + b->size;
  475.                             PaintRect( &b->r );
  476.                         }
  477.                     }
  478.                 }
  479.                 f->next_tick = TickCount() + 2;
  480.                 break;
  481.  
  482.             case 7:
  483.                 if ( TickCount() >= start_ticks + ERASE2_DELAY ) {
  484.                     f->stage++;
  485.                     --num_active;
  486.                     continue;
  487.                 }
  488.  
  489.                 if ( TickCount() < f->next_tick )
  490.                     continue;
  491.                 MoveTo( ( the_window->portRect.right - StringWidth( (StringPtr) credits2 ) ) / 2,
  492.                         the_window->portRect.bottom - 20 );
  493.                 DrawString( (StringPtr) credits2 );
  494.                 f->next_tick = TickCount() + ERASE2_DELAY; /* never again */
  495.                 break;
  496.  
  497.             default:
  498.                 break;
  499.             }
  500.         }
  501.  
  502.         
  503.     }
  504.  
  505.     ticker = start_ticks + ERASE2_DELAY;
  506.     while ( !Button() && TickCount() < ticker );
  507.  
  508.     ClipRect( &the_window->portRect );
  509.  
  510.     if ( Use_color ) {
  511.         Rect r;
  512.  
  513.         Set_back_color( BACK_COLOR );
  514.         Set_fore_color( BLACK_COLOR );
  515.  
  516.         r = the_window->portRect;
  517.         while ( r.top < the_window->portRect.bottom ) {
  518.             r.bottom = r.top + CELL_HEIGHT;
  519.             EraseRect( &r );
  520.             r.top += CELL_HEIGHT;
  521.             ticker = TickCount() + 3;
  522.             while ( TickCount() < ticker );
  523.         }
  524.     }
  525.     else
  526.         EraseRect( &the_window->portRect );
  527.     InvalRect( &the_window->portRect );
  528.  
  529.     DisposeHandle( (Handle) fly_handle );
  530.     if ( snd ) {
  531.         SndDisposeChannel( chan, TRUE );
  532.         Dispose_riff( snd );
  533.     }
  534.     FlushEvents( mUpMask | mDownMask | keyDownMask | autoKeyMask | keyUpMask, 0 );
  535.     ShowCursor();
  536. }
  537.  
  538.  
  539. /**-----------------------------------------------------------------------------
  540.  **
  541.  **    Private Functions
  542.  **
  543.  **/
  544.  
  545.  
  546. static int16 random( int16 max )
  547. {
  548.     int16 x;
  549.  
  550.     x = Random();
  551.     if ( x < 0 )
  552.         x = -x;
  553.     return x % max;
  554. }
  555.