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

📄 disp.c

📁 一个runtils v2.0图形音乐库的demo程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/*============================================================================*/
/*   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 + -