📄 disp.c
字号:
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( ©,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( ©,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 + -