📄 disp.c
字号:
/*============================================================================*/
/* PROJECT NUCLEUS. (c) RocSoft, 1995. */
/* v1.0 18 Jan 95. */
/*============================================================================*/
#include <rgenrl.h>
#include <rgraph.h>
#include <rsprite.h>
#include <rinout.h>
#include <rfileio.h>
#include <rsound.h>
#include <rblast.h>
#include <rmem.h>
#include <rmath.h>
#include "\rocco\glib\games.h"
#include <malloc.h>
#include <memory.h>
#include <string.h>
#include <stdlib.h>
#include "defines.h"
#include "prototyp.h"
#include "globals.h"
/*==================[ External Variable Definitions ]=========================*/
extern char *Banner, Demo_Mode, Demo_Exited;
extern int ParticleMass[];
extern int LogoIndex1[], LogoIndex2[], Logo_Control[14];
extern unsigned int Demo_Timer, Experiment_Timer;
extern int *RootTable;
extern BYTE Screen_Shot;
extern HIGH_SCORE_TABLE High_Scores;
/*=======================[ Local Variable Definitions ]=======================*/
int Last_Mins;
unsigned char Neutron_Fired;
unsigned char Update_Score;
POWER_UP_TYPE Power_Up_Icon;
int Power_Up_Delay;
char *VictoryMsgs[]={ "Congratulations! You've successfully",
"completed all of your tasks. I'm afraid",
"you need to get another day job. Why",
"don't be become your OWN boss and",
"register! Upon registration you get",
"your very own level editor to create",
"loads and loads of different levels!",
NULL };
char *DeathMsgs[NUMBER_OF_MELTDOWNS]={
"",
"Time Meltdown!",
"Mass Meltdown!",
"Rogue Ray Meltdown!",
"Rogue Particle Meltdown!"
};
/*===================[ Functions For Display Control ]========================*/
void Add_Particle_To_Nucleus( int nuc, int mol, int d )
{
int dx, dy, ac;
PARTICLE *p=Cfg.particles+mol;
NUCLEUS *n=Cfg.nuclei+nuc;
n->mass += ParticleMass[p->type];
p->active = TRUE;
p->r = (d<6) ? 3 : d>>1;
p->nucleus = nuc;
dx = p->x - n->cx;
dy = p->y - n->cy;
if ( d<2 ) ac=TRIG_TAB_FACTOR; else
{
ac = (dx*TRIG_TAB_FACTOR)/(d>>1);
ac = ABS(ac);
if ( ac > TRIG_TAB_FACTOR ) ac=TRIG_TAB_FACTOR;
}
if ( dx>=0 )
p->angle = (dy<0) ? 360-PseudoACos(ac) : PseudoACos(ac);
else
p->angle = (dy<0) ? 180+PseudoACos(ac) : 180-PseudoACos(ac);
}
int Calculate_Rogue_Interval( int mintime, int maxtime )
{
return( (mintime || maxtime) ? ((random()%(maxtime-mintime+1))+mintime) : 0 );
}
void Check_Beam_Collisions( void )
{
BEAM *b;
NUCLEUS *n;
SHIELD *s;
int i, j, dx, dy;
for ( i=0, b=Cfg.beams; i<MAX_BEAMS; i++, b++ )
{
if ( b->active && object_active(BEAM_TOON_BASE_PRI+i) )
{
for ( j=0, s=Cfg.shields; j<MAX_SHIELDS; j++, s++ )
{
if ( s->active && object_active(SHIELD_TOON_BASE_PRI+j) )
{
dx = s->x - b->x + ((s->x>b->x)?3:0);
dx = ABS(dx);
dy = s->y - b->y;
dy = ABS(dy);
if ( dx<36 && dy<36 && RootTable[dx*dx+dy*dy]<=((s->rx+s->ry)>>1) )
{
Sfx( SFX_SHIELD_HIT );
delete_object( BEAM_TOON_BASE_PRI+i );
b->active = FALSE;
break;
}
}
}
if ( b->active )
{
for ( j=0, n=Cfg.nuclei; j<MAX_NUCLEI; j++, n++ )
{
if ( n->mass )
{
dx = n->cx - b->x + ((n->cx>b->x)?3:0);
dx = ABS(dx);
dy = n->cy - b->y;
dy = ABS(dy);
if ( dx<=NUCLEUS_HIT_TOLERANCE && dy<=NUCLEUS_HIT_TOLERANCE )
{
Split_Nucleus( n,j,SFX_NUCLEUS_HIT );
delete_object( BEAM_TOON_BASE_PRI+i );
b->active = FALSE;
Meltdown = ROGUE_RAY_MELTDOWN;
break;
}
}
}
}
}
}
}
void Check_Bonus_Pickup( int x, int y )
{
OBJECT *o=ObjectList[object_index(POWER_UP_TOON_BASE_PRI)];
if ( o->status==ACTIVE_OBJECT && o->x1<=x && x<=o->x2 && o->y1<=y && y<=o->y2 )
{
delete_object( POWER_UP_TOON_BASE_PRI );
Sfx( SFX_BONUS_PICKUP );
Cfg.score += PTS_POWER_UP;
Update_Score = TRUE;
switch( Power_Up_Icon )
{
case PUP_NEUTRON:
if ( (Cfg.rays+=Lev->rays) > 99 ) Cfg.rays=99;
Display_Neutron();
break;
case PUP_SHIELD:
if ( (Cfg.shield_cnt+=Lev->shields) > 99 ) Cfg.shield_cnt=99;
Display_Shields();
break;
}
}
}
int Create_Protective_Shield( int x, int y )
{
SHIELD *s;
int i;
for ( i=0, s=Cfg.shields; i<MAX_SHIELDS; i++, s++ )
{
if ( !s->active && !object_active(SHIELD_TOON_BASE_PRI+i) )
{
s->active = TRUE;
s->rx = Shield_Icons[0].w>>1;
s->ry = Shield_Icons[0].h>>1;
s->reps = s->frame = 0;
s->time = Lev->shield_duration;
add_object( SHIELD_TOON_BASE_PRI+i,Toon_Shield,0,s->x=x,s->y=y );
return( FALSE );
}
}
return( TRUE );
}
int Create_Rogue_Beam( void )
{
BEAM *b;
int i;
for ( i=0, b=Cfg.beams; i<MAX_BEAMS; i++, b++ )
{
if ( !b->active && !object_active(BEAM_TOON_BASE_PRI+i) )
{
b->active = TRUE;
b->frame = (random()&0x01) ? 0 : (NUM_OF_BEAMS-1);
b->x = (b->frame==0) ? VX_MIN : VX_MAX;
b->y = (random()%(VY_MAX-VY_MIN-10)) + VY_MIN;
b->vx = (b->frame==0) ? 3 : -3;
add_object( BEAM_TOON_BASE_PRI+i,Toon_Beam,b->frame,b->x,b->y );
return( TRUE );
}
}
return( FALSE );
}
int Create_Rogue_Particle( void )
{
NUCLEUS *n;
PARTICLE *p;
int i, j, ok;
for ( i=0, p=Cfg.rogues; i<MAX_ROGUE_PARTICLES; i++, p++ )
{
if ( !p->rogue && !object_active(ROGUE_TOON_BASE_PRI+i) )
{
p->rogue = TRUE;
p->delay = p->frame = 0;
p->time = Lev->rogue_duration;
do
{
p->x = (random()%(VX_MAX-VX_MIN+1)) + VX_MIN;
p->y = (random()%(VY_MAX-VY_MIN+1)) + VY_MIN;
for ( j=0, ok=TRUE, n=Cfg.nuclei; ok && j<MAX_NUCLEI; j++, n++ )
if ( ABS(n->cx-p->x)<(NUCLEUS_HIT_TOLERANCE<<2) && ABS(n->cy-p->y)<(NUCLEUS_HIT_TOLERANCE<<2) ) ok=FALSE;
}
while ( !ok );
p->vx = Set_Particle_Velocity( SPEED_MASK_2,2 );
p->vy = Set_Particle_Velocity( SPEED_MASK_2,2 );
add_object( ROGUE_TOON_BASE_PRI+i,Toon_Rogue_Particle,0,p->x,p->y );
return( TRUE );
}
}
return( FALSE );
}
void Cycle_Fractal_Colours( void )
{
static char delay=0;
unsigned char *buff=Pal.pal;
if ( ++delay > 6 )
{
delay = 0;
_asm
{
pushf
push ds
push si
push di
lds si, buff
add si, FRACTAL_CYCLE_COLOUR_1
mov ax, ds
mov es, ax
mov di, si
cld /* Both es:[di] & ds:[si] point to palette start */
lodsw /* AX holds G:R colour components */
mov bx, ax /* Stash in bx */
lodsb /* AL hold B component */
mov dl, al /* Stash in dl */
mov cx, FRACTAL_CYCLE_COUNT
shr cx, 1
rep movsw /* Move even number of words */
mov ax, bx /* es:[di] should point to last colour */
stosw
mov al, dl
stosb
pop di
pop si
pop ds
popf
}
}
}
void Detect_Particle_Collisions( void )
{
int i, j, k, dx, dy, d, min;
unsigned int adx, ady;
PARTICLE *p, *pp;
NUCLEUS *n;
SPRITE *s1, *s2;
for ( i=0, n=Cfg.nuclei; i<MAX_NUCLEI; i++, n++ )
{
if ( object_active(COUNTER_TOON_BASE_PRI+i) )
{
if ( Neutron_Fired && n->cx-NUCLEUS_HIT_TOLERANCE<=MouseX && MouseX<=n->cx+NUCLEUS_HIT_TOLERANCE && n->cy-NUCLEUS_HIT_TOLERANCE<=MouseY && MouseY<=n->cy+NUCLEUS_HIT_TOLERANCE )
{
Split_Nucleus( n,i,SFX_NUCLEUS_HIT );
Cfg.score += PTS_NUCLEUS_HIT;
Update_Score = TRUE;
}
else
{
if ( n->mass >= Lev->critical_mass || n->cframe<=0 )
{
if ( n->mass >= Lev->critical_mass && Lev->mass_meltdown ) Meltdown=MASS_MELTDOWN;
Split_Nucleus( n,i,SFX_NUCLEUS_SPLIT );
}
else
{
if ( Lev->rogue_particles )
{
for ( j=0, p=Cfg.rogues; j<MAX_ROGUE_PARTICLES; j++, p++ )
{
if ( p->rogue && object_active(ROGUE_TOON_BASE_PRI+j) )
{
if ( ABS(n->cx-p->x)<NUCLEUS_HIT_TOLERANCE && ABS(n->cy-p->y)<NUCLEUS_HIT_TOLERANCE )
{
Meltdown = ROGUE_PARTICLE_MELTDOWN;
break;
}
}
}
}
}
}
}
}
for ( i=0, p=Cfg.particles; i<Lev->count; i++, p++ )
{
if ( !p->active && ABS(p->vx)<=MIN_SPEED && ABS(p->vy)<=MIN_SPEED )
{
s1 = SParticles+p->type;
for ( j=0, pp=Cfg.particles; j<Lev->count && !p->active; j++, pp++ )
{
if ( j!=i && ABS(pp->vx)<=MIN_SPEED && ABS(pp->vy)<=MIN_SPEED )
{
s2 = SParticles+pp->type;
if ( pp->active )
{
min = (s1->w+s1->h)>>2;
dx = Cfg.nuclei[pp->nucleus].cx;
dy = Cfg.nuclei[pp->nucleus].cy;
}
else
{
min = (s2->w+s2->h+s1->w+s1->h)>>2;
dx = pp->x;
dy = pp->y;
}
dx -= p->x;
dy -= p->y;
if ( (adx=ABS(dx))<=min && (ady=ABS(dy))<=min )
{
if ( (d=RootTable[adx*adx+ady*ady])<=min )
{
if ( pp->active )
Add_Particle_To_Nucleus( pp->nucleus,i,d<<1 );
else
{
for ( k=0, n=Cfg.nuclei; (n->mass>0 || object_active(COUNTER_TOON_BASE_PRI+k)) && k<MAX_NUCLEI; k++, n++ );
if ( k<MAX_NUCLEI )
{
n->cx = p->x + dx/2;
n->cy = p->y + dy/2;
n->speed= ANGLE_START;
n->cframe = Lev->critical_time;
n->n_fired= n->s_fired=FALSE;
if ( add_object(COUNTER_TOON_BASE_PRI+k,Toon_Counter,n->cframe,n->cx-3,n->cy-2)==0 )
{
Add_Particle_To_Nucleus( k,j,d );
Add_Particle_To_Nucleus( k,i,d );
}
}
}
}
}
}
}
}
}
}
void Display_Neutron( void )
{
rect( PANEL_XBASE1+63,PANEL_YBASE+12,PANEL_XBASE1+78,PANEL_YBASE+19,CONTROL_PANEL_COLOUR,FILL,SPLIT_PAGE );
Spr_Printi( SFont,Cfg.rays,PANEL_XBASE1+63,PANEL_YBASE+12,2,8,HORIZ,SPLIT_PAGE );
}
void Display_Panel( void )
{
int i, j;
Fade_Screen( MODE_320x200x256 );
splitscr( VS.my-SPLIT_SCREEN_HEIGHT+1 );
imgvwport( VX_MIN,VY_MIN,VX_MAX,VY_MAX );
mouselim( VX_MIN,VY_MIN,VX_MAX,VY_MAX );
/* Draw play area layout */
Draw_Fractal_Background( 0 );
putspr( Panel,0,0,OWRTE,0 );
putspr( Panel+2,VS.mx-7,0,OWRTE,0 );
putspr( Panel+4,0,VS.my-7,OWRTE,0 );
putspr( Panel+5,VS.mx-7,VS.my-7,OWRTE,0 );
rect( 0,0,VS.mx,SPLIT_SCREEN_HEIGHT-1,CONTROL_PANEL_COLOUR,FILL,SPLIT_PAGE );
putspr( Panel+6,0,0,OWRTE,SPLIT_PAGE );
putspr( Panel+8,VS.mx-7,0,OWRTE,SPLIT_PAGE );
putspr( Panel+11,0,SPLIT_SCREEN_HEIGHT-8,OWRTE,SPLIT_PAGE );
putspr( Panel+13,VS.mx-7,SPLIT_SCREEN_HEIGHT-8,OWRTE,SPLIT_PAGE );
for ( i=8; i<VS.mx-7; i+=8 )
{
putspr( Panel+1,i,0,OWRTE,0 );
putspr( Panel+1,i,VS.my-7,OWRTE,0 );
putspr( Panel+7,i,0,OWRTE,SPLIT_PAGE );
putspr( Panel+12,i,SPLIT_SCREEN_HEIGHT-8,OWRTE,SPLIT_PAGE );
if ( i<SPLIT_SCREEN_HEIGHT-8 )
{
putspr( Panel+9,0,i,OWRTE,SPLIT_PAGE );
putspr( Panel+10,VS.mx-7,i,OWRTE,SPLIT_PAGE );
}
if ( i<VS.my-7 )
{
putspr( Panel+3,0,i,OWRTE,0 );
putspr( Panel+3,VS.mx-7,i,OWRTE,0 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -