⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 disp.c

📁 一个runtils v2.0图形音乐库的demo程序
💻 C
📖 第 1 页 / 共 3 页
字号:

        CONSUME_KEYS;

        do
        {
            if ( Demo_Mode ) Play_Demo(); else
            {
                _asm    cli
                MouseB = I_MouseB;
                MouseX = I_MouseX;
                MouseY = I_MouseY;
                _asm    sti
            }

            update_objects(0,0,2);
            if ( (key=inkey(0)) ) Process_Keystroke( key );
            Cycle_Fractal_Colours();

            if ( MouseB&L_BUTTON )     /*  Left button to fire rays  */
            {
                if ( SyringeDir!=0 || !Lev->gun || Cfg.rays==0 )
                {
                    Sfx( SFX_NO_FIRE );
                }
                else
                {
                    Sfx( SFX_NEUTRON_FIRED );
                    SyringeDir=1;
                    Cfg.rays--;
                    Display_Neutron();
                    Neutron_Fired=TRUE;
                }
                MouseB ^= L_BUTTON;
                _asm    cli
                I_MouseB = MouseB;
                _asm    sti
            }
            if ( MouseB&R_BUTTON )     /*  Right button to fire shields  */
            {
                if ( SyringeDir!=0 || !Lev->force_field || Cfg.shield_cnt==0 )
                {
                    Sfx( SFX_NO_FIRE );
                }
                else
                {
                    SyringeDir=1;
                    if ( Create_Protective_Shield(MouseX,MouseY) ) Sfx( SFX_NO_FIRE ); else
                    {
                        Sfx( SFX_SHIELD_FIRED );
                        Cfg.shield_cnt--;
                        Display_Shields();
                    }
                }
                MouseB ^= R_BUTTON;
                _asm    cli
                I_MouseB = MouseB;
                _asm    sti
            }

            Update_Particle_Positions();
            Detect_Particle_Collisions();
            if ( Lev->rogue_beams ) Check_Beam_Collisions();

            if ( object_active(POWER_UP_TOON_BASE_PRI) ) Check_Bonus_Pickup(MouseX,MouseY);

            for ( i=0, t=Cfg.timers, n=Cfg.nuclei; i<MAX_NUCLEI; i++, t++, n++ )
            {
                if ( n->mass && !*t )
                {
                    if ( Lev->orbit_speed_up && n->speed<90 ) n->speed+=ANGLE_INC;
                    n->cframe--;
                    *t = SPEED_UP_TIME;
                }
            }

            if ( !Experiment_Timer )
            {
                Cfg.time--;
                Display_Time();
                Experiment_Timer = 18;
                for ( i=0, s=Cfg.shields; i<MAX_SHIELDS; i++, s++ )
                  if ( s->time ) (s->time--);
                if ( (--Cfg.power_up_timer)==0 )
                {
                    Sfx( SFX_BONUS_PICKUP );
                    add_object( POWER_UP_TOON_BASE_PRI,Toon_PowerUp,((Power_Up_Icon=(Lev->powerup!=PUP_RANDOM)?Lev->powerup:(random()%PUP_RANDOM))==PUP_SHIELD)?0:8,VX_MIN-15,(random()%(VY_MAX-VY_MIN-15))+VY_MIN );
                    Power_Up_Delay     = 0;
                    Cfg.power_up_timer = Lev->power_up_delay;
                }
                if ( Lev->rogue_beams )
                {
                    if ( (--Cfg.beam_timer)==0 )
                    {
                        if ( Create_Rogue_Beam() ) Sfx( SFX_ROGUE_BEAM );
                        Cfg.beam_timer = Calculate_Rogue_Interval( Lev->min_beam_sep,Lev->max_beam_sep );
                    }
                }
                if ( Lev->rogue_particles )
                {
                    for ( i=0, p=Cfg.rogues; i<MAX_ROGUE_PARTICLES; i++, p++ )
                      if ( p->rogue && (--(p->time))==0 )
                      {
                          p->rogue = FALSE;
                          delete_object( ROGUE_TOON_BASE_PRI+i );
                      }
                    if ( (--Cfg.rogue_timer)==0 )
                    {
                        if ( Create_Rogue_Particle() ) Sfx( SFX_ROGUE_PARTICLE );
                        Cfg.rogue_timer = Calculate_Rogue_Interval( Lev->min_rogue_sep,Lev->max_rogue_sep );
                    }
                }
            }

            if ( Update_Score )
            {
                Display_Score();
                Update_Score=FALSE;
            }

            Neutron_Fired=FALSE;

            if ( Demo_Mode && (Demo_Exited || !Demo_Timer) ) break;
        }
        while ( key!=ESCAPEKEY && !Meltdown && Cfg.time );
        Game_Paused = TRUE;
        remove_objects();

        if ( Sound_Source==SOUND_BLASTER ) SB_abort(0x01); else flush_sounds();

        score = Cfg.score;

        if ( Meltdown )
        {
            Sfx( (random()&0x01)?SFX_SCREAM1:SFX_SCREAM2 );
            rect( 0,0,VS.mx,VS.my,BLACK,FILL,2 );
            Spr_Print( SFont,DeathMsgs[Meltdown],(VS.mx-Spr_Strlen(SFont,DeathMsgs[Meltdown]))>>1,30,PROPORTIONAL,HORIZ,2 );
            melt_screen( IPage,2,6 );
            CONSUME_KEYS;
            if ( Demo_Mode ) Meltdown=NO_MELTDOWN; else
            {
                Menu_New_Game( 0 );
                Sfx( SFX_GAME_OVER );
                sleep( 1 );
                CONSUME_KEYS;
            }
        }

        if ( Demo_Mode && Demo_Exited ) break;

        if ( !Meltdown && (Cfg.time==0 || Demo_Mode) )
        {
            if ( !Demo_Mode ) End_Of_Level_Bonus();
            if ( (++Cfg.level) > Max_Levels )
            {
                if ( !Demo_Mode ) Show_Error_Message( VictoryMsgs,SFX_FANFARE,20,IPage );
                break;
            }
            Initialise_Level();
        }
    }
    while ( key!=ESCAPEKEY && !Meltdown );

    if ( !Demo_Mode && key!=ESCAPEKEY )
    {
        CONSUME_KEYS;
        Hall_Of_Fame( &High_Scores,score,1 );
    }

    return( 0 );
}

void Print_Banner( int set_mode )
{
    char   attr=ATTR(BLUE,WHITE);

    if ( set_mode ) setmode( 0x03 );

    setpos( 0,0,0 );

    _asm   mov  ax, 0920H
    _asm   xor  bh, bh
    _asm   mov  bl, attr
    _asm   mov  cx, 80
    _asm   int  10H

    setpos( (80-strlen(Banner))>>1,0,0 );
    prints( Banner,attr,0 );
    setpos( 0,5,0 );
}

void Process_Keystroke( int key )
{
    SPRITE   copy;
    int      x, y;

    switch( key )
    {
        case 'p':
        case 'P':
          Game_Paused=TRUE;
          if ( Sound_Source==SOUND_BLASTER )
          {
              SB_pause(TRUE);
              SB_abort(0x02 );
          }
          else hold_sound( ON );
          if ( !Screen_Shot )
          {
              getspr( &copy,x=(VS.mx-Pause_Icon.w)>>1,y=(VS.my-Pause_Icon.h)>>1,Pause_Icon.w,Pause_Icon.h,IPage );
              putspr( &Pause_Icon,x,y,OWRTE,IPage );
          }
          Wait_For_Event( 32000 );
          if ( !Screen_Shot )
          {
              putspr( &copy,x,y,OWRTE,IPage );
              free( copy.buff );
          }
          Game_Paused=FALSE;
          if ( Sound_Source==SOUND_BLASTER )
          {
              SB_pause(FALSE);
              GOptions_Music(0);
          }
          else hold_sound( OFF );
          break;
        case ESCAPEKEY:
          break;
    }
}

int  Set_Particle_Velocity( int speed_mask, int min )
{
    register int   v;

    do v=(random()%speed_mask)-(speed_mask>>1); while ( v==0 );

    if ( v > 0 )
    {
        if ( v < min ) v=min;
    }
    else if ( v > -min ) v=-min;

    return( v );
}

int  Show_Error_Message( char **msgs, SFX_TYPE sfx, int wait, int page )
{
    SPRITE    save;
    int       x1, y1, x2, y2, l, w, i, ht=SFont[' '].h;

    for ( l=w=0; msgs[l]; l++ )
      if ( (i=Spr_Strlen(SFont,msgs[l]))>w ) w=i;

    w += 16;
    x1 = (VS.mx + 1 - w - 10)>>1;
    y1 = (VS.my + 1 - (l+2)*ht - 8)>>1;
    x2 = x1 + w + 9;
    y2 = y1 + (l+2)*ht + 7;

    if ( getspr(&save,x1,y1,(x2-x1+1),(y2-y1+1),page) ) Terminate( ERR_MALLOC );
    Draw_Edged_Box( x1,y1,x2,y2,WHITE,GREY,L_GREY,page );
    Sfx( sfx );
    for ( i=0; i<l; i++ )
      Spr_Print( SFont,msgs[i],x1+13,y1+(i+1)*ht+4,PROPORTIONAL,HORIZ,page );
    CONSUME_KEYS;
    if ( Demo_Mode )
    {
        for ( w=90; w>0 && !Demo_Exited; w-- ) waitticks( 1 );
        i=(Demo_Exited)?ESCAPEKEY:0;
    }
    else
    {
        if ( !wait ) i=getkey(0); else
        {
            Wait_For_Event( wait );
            i=0;
        }
    }
    putspr( &save,x1,y1,OWRTE,page );
    free( save.buff );

    return( i );
}

int  Show_Experiment_Guide( void )
{
#define   MAX_MSGS              20
    char    buff[8], *msgs[MAX_MSGS];
    int     num=0, i, w, c;
    int     x1, y1, x2, y2, ht;
    FONT    f;

    rom_font( &f,ROM_8x8 );
    ht = f.height;

    for ( i=0; i<MAX_MSGS; i++ )
      if ( (msgs[i]=malloc(80))==NULL ) Terminate( ERR_MALLOC );

    strsetx( msgs[num++],"                      Experiment: ",itoa(Cfg.level,buff,10),NULL );

    for ( i=0; *Lev->text[i]; i++ ) strcpy(msgs[num++],Lev->text[i]);

    *msgs[num++] = '\0';
    strcpy( msgs[num++],"                         Summary" );
    strsetx( msgs[num++],"Experiment Duration ",itoa(Lev->time,buff,10)," seconds.",NULL );
    strsetx( msgs[num++],"Number Of Particles ",itoa(Lev->count,buff,10),".",NULL );
    strsetx( msgs[num++],"Critical Mass       ",itoa(Lev->critical_mass,buff,10)," units ",(Lev->mass_meltdown)?"(Meltdown!).":"(Split Only).",NULL );
    strsetx( msgs[num++],"Critical Time       ",itoa(Lev->critical_time,buff,10)," seconds ",(Lev->time_meltdown)?"(Meltdown!).":"(Split Only).",NULL );
    strsetx( msgs[num++],"Atomic Injector     ",(Lev->gun)?"ACTIVE (":"INACTIVE",(Lev->gun)?itoa(Lev->rays,buff,10):"",(Lev->gun)?" neutrons).":".",NULL );
    strsetx( msgs[num++],"Nuclear Shields     ",(Lev->force_field)?"ACTIVE (":"INACTIVE",(Lev->force_field)?itoa(Lev->shields,buff,10):"",(Lev->force_field)?").":".",NULL );
    if ( Lev->rogue_beams )
      strsetx( msgs[num++],"Rogue Beams         ACTIVE (Meltdown!).",NULL );
    if ( Lev->rogue_particles )
      strsetx( msgs[num++],"Rogue Particles     ACTIVE (Meltdown!).",NULL );

    Fade_Screen( MODE_640x200x16 );
    rect( 0,0,VS.mx,VS.my,BLUE,FILL,0 );

    w  = (sizeof(Levels[0].text[0])-1)*8 + 16;
    x1 = (VS.mx + 1 - w - 10)>>1;
    y1 = (VS.my + 1 - (num+2)*ht - 8)>>1;
    x2 = x1 + w + 9;
    y2 = y1 + (num+2)*ht + 7;

    Draw_Edged_Box( x1,y1,x2,y2,WHITE,GREY,L_GREY,0 );
    Sfx( SFX_LEVEL_START );
    for ( i=0; i<num; i++ )
      gprintf( msgs[i],x1+13,y1+(i+1)*ht+4,BLACK,L_GREY,&f,0 );

    fadein( &DefPal,0 );

    CONSUME_KEYS;
    if ( Demo_Mode )
    {
        Wait_For_Event( 5 );
        c=(Demo_Exited)?ESCAPEKEY:0;
    }
    else
    {
        Wait_For_Event( 30 );
        c=0;
    }

    for ( i=0; i<MAX_MSGS; i++ ) free( msgs[i] );

    return( (c==ESCAPEKEY) );
}

void Split_Nucleus( NUCLEUS *n, int nidx, SFX_TYPE sfx )
{
    PARTICLE   *p;
    int        i;

    n->mass = 0;
    n->s_fired = n->n_fired = FALSE;
    delete_object( COUNTER_TOON_BASE_PRI+nidx );
    Sfx( sfx );
    for ( i=Lev->count, p=Cfg.particles; i>0; i--, p++ )
    {
        if ( p->active && p->nucleus==nidx )
        {
            p->active = FALSE;
            p->vx     = Set_Particle_Velocity( SPEED_MASK_2,2 );
            p->vy     = Set_Particle_Velocity( SPEED_MASK_2,2 );
        }
    }
}

void Update_Particle_Positions( void )
{
    int            i;
    PARTICLE       *p;
    NUCLEUS        *n;

    if ( Lev->rogue_particles )
    {
        for ( i=0, p=Cfg.rogues; i<MAX_ROGUE_PARTICLES; i++, p++ )
        {
            if ( p->rogue )
            {
                Particle_Hit_Shield( p,RogueParticles[p->frame].w,RogueParticles[p->frame].h );
                if ( p->x+p->vx < VX_MIN || p->x+p->vx > VX_MAX ) p->vx=-p->vx;
                if ( p->y+p->vy < VY_MIN || p->y+p->vy > VY_MAX ) p->vy=-p->vy;
                p->x += p->vx;
                p->y += p->vy;
            }
        }
    }

    for ( i=Lev->count, p=Cfg.particles; i>0; i--, p++ )
    {
        if ( p->active )
        {
            n = Cfg.nuclei + p->nucleus;
            if ( (p->angle+=n->speed) >= MAX_DEGREES ) p->angle-=MAX_DEGREES;
            p->x = n->cx + (p->r*PseudoCos(p->angle))/TRIG_TAB_FACTOR;
            p->y = n->cy + (p->r*PseudoSin(p->angle))/TRIG_TAB_FACTOR;
        }
        else
        {
            /*  Look for particle hitting a shield  */

            Particle_Hit_Shield( p,SParticles[p->type].w,SParticles[p->type].h );

            if ( p->x+p->vx < VX_MIN || p->x+p->vx > VX_MAX )
            {
                if ( ABS(p->vx) > MIN_SPEED ) p->vx += (p->vx<0)?1:-1;
                p->vx=-p->vx;
                if ( p->x < VX_MIN ) p->x=VX_MIN; else
                  if ( p->x > VX_MAX ) p->x=VX_MAX;
            }
            if ( p->y+p->vy < VY_MIN || p->y+p->vy > VY_MAX )
            {
                if ( ABS(p->vy) > MIN_SPEED ) p->vy += (p->vy<0)?1:-1;
                p->vy=-p->vy;
                if ( p->y < VY_MIN ) p->y=VY_MIN; else
                  if ( p->y > VY_MAX ) p->y=VY_MAX;
            }
            p->x += p->vx;
            p->y += p->vy;
        }
    }
}

/*==========================[ End Of Source File ]===========================*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -