code:
//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
Copyright (C) 2017-2019 Nuke.YKT

This file is part of Duke Nukem 3D version 1.5 - Atomic Edition

Duke Nukem 3D is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

Original Source: 1996 - Todd Replogle
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------

#include "types.h"
#include "develop.h"
#include "scriplib.h"
#include "file_lib.h"
#include "gamedefs.h"
#include "keyboard.h"
#include "util_lib.h"
#include "function.h"
#include "control.h"
#include "fx_man.h"
#include "sounds.h"
#include "config.h"
#include "sndcards.h"

#include "duke3d.h"

extern long lastvisinc;

void animatesprites(long x,long y,short a,long smoothratio)
{
    short i, j, k, p, sect, bg;
    long l, t1,t3,t4;
    spritetype *s,*t;

    bg = 0;

    for(j=0;j < spritesortcnt; j++)
    {
        t = &tsprite[j];
        i = t->owner;
        s = &sprite[t->owner];

        switch(t->picnum)
        {
            case BLOODPOOL:
            case FOOTPRINTS:
            case FOOTPRINTS2:
            case FOOTPRINTS3:
            case FOOTPRINTS4:
                if(t->shade == 127) continue;
                break;
            case CHAIR3:

                k = (((t->ang+3072+128-a)&2047)>>8)&7;
                if(k>4)
                {
                    k = 8-k;
                    t->cstat |= 4;
                }
                else t->cstat &= ~4;
                t->picnum = s->picnum+k;
                break;
            case BLOODSPLAT1:
            case BLOODSPLAT2:
            case BLOODSPLAT3:
            case BLOODSPLAT4:
                if(ud.lockout) t->xrepeat = t->yrepeat = 0;
                else if(t->pal == 6)
                {
                    t->shade = -127;
                    continue;
                }
            case BULLETHOLE:
            case CRACK1:
            case CRACK2:
            case CRACK3:
            case CRACK4:
                t->shade = 16;
                continue;
#ifdef RRRA
            case RRTILE1947:
            case RRTILE2859:
            case RRTILE3774:
            case RRTILE5088:
            case RRTILE8094:
            case RRTILE8096:
                continue;
#endif
            case NEON1:
            case NEON2:
            case NEON3:
            case NEON4:
            case NEON5:
            case NEON6:
                continue;
            default:
                if( ( (t->cstat&16) ) || ( badguy(t) && t->extra > 0) || t->statnum == 10)
                {
                    if (shadedsector[s->sectnum] == 1 && s->statnum != 1)
                    {
                        s->shade = 16;
                        t->shade = 16;
                    }
                    continue;
                }
        }

        if (sector[t->sectnum].ceilingstat&1)
        {
            if (badguy(s))
                l = s->shade;
            else
                l = s->shade;
        }
        else
            l = sector[t->sectnum].floorshade;

        if(l < -127) l = -127;
        if(l > 128) l =  127;
        t->shade = l;
    }

    for(j=0;j < spritesortcnt; j++ )  //Between drawrooms() and drawmasks()
    {                             //is the perfect time to animate sprites
        t = &tsprite[j];
        i = t->owner;
        s = &sprite[i];

        switch(s->picnum)
        {
            case SECTOREFFECTOR:
                if(t->lotag == 27 && ud.recstat == 1)
                {
                    t->picnum = 11+((totalclock>>3)&1);
                    t->cstat |= 128;
                }
                else
                    t->xrepeat = t->yrepeat = 0;
                break;
            case FEM10:
            case NAKED1:
            case FEMMAG1:
            case FEMMAG2:
            case STATUE:
            case STATUEFLASH:
            case OOZ:
            case WALLBLOOD1:
            case WALLBLOOD2:
            case WALLBLOOD3:
            case WALLBLOOD4:
            case WALLBLOOD5:
            case SUSHIPLATE1:
            case SUSHIPLATE2:
            case SUSHIPLATE3:
            case SUSHIPLATE4:
            case DOLPHIN1:
            case DOLPHIN2:
            case TOUGHGAL:
                if(ud.lockout)
                {
                    t->xrepeat = t->yrepeat = 0;
                    continue;
                }
        }

        if( t->statnum == 99 ) continue;
        if( s->statnum != 1 && s->picnum == APLAYER && ps[s->yvel].newowner == -1 && s->owner >= 0 )
        {
            t->x -= mulscale16(65536-smoothratio,ps[s->yvel].posx-ps[s->yvel].oposx);
            t->y -= mulscale16(65536-smoothratio,ps[s->yvel].posy-ps[s->yvel].oposy);
            t->z = ps[s->yvel].oposz + mulscale16(smoothratio,ps[s->yvel].posz-ps[s->yvel].oposz);
            t->z += (40<<8);
            s->xrepeat = 24;
            s->yrepeat = 17;
        }
        else if( ( s->statnum == 0 && s->picnum != CRANEPOLE) || s->statnum == 10 || s->statnum == 6 || s->statnum == 4 || s->statnum == 5 || s->statnum == 1 )
        {
            t->x -= mulscale16(65536-smoothratio,s->x-hittype[i].bposx);
            t->y -= mulscale16(65536-smoothratio,s->y-hittype[i].bposy);
            t->z -= mulscale16(65536-smoothratio,s->z-hittype[i].bposz);
        }

        sect = s->sectnum;
        t1 = T2;t3 = T4;t4 = T5;

        switch(s->picnum)
        {
            case RESPAWNMARKERRED:
            case RESPAWNMARKERYELLOW:
            case RESPAWNMARKERGREEN:
                t->picnum = 861+( (totalclock>>4) & 13);
                if (s->picnum == RESPAWNMARKERRED)
                    t->pal = 0;
                else if (s->picnum == RESPAWNMARKERYELLOW)
                    t->pal = 1;
                else
                    t->pal = 2;
                if (ud.marker == 0)
                    t->xrepeat = t->yrepeat = 0;
                break;
            case DUKELYINGDEAD:
                s->xrepeat = 24;
                s->yrepeat = 17;
                if (s->extra > 0)
                    t->z += (6<<8);
                break;
            case BLOODPOOL:
            case FOOTPRINTS:
            case FOOTPRINTS2:
            case FOOTPRINTS3:
            case FOOTPRINTS4:
                if(t->pal == 6)
                    t->shade = -127;
            case MONEY:
            case MONEY+1:
                if(ud.lockout && s->pal == 2)
                {
                    t->xrepeat = t->yrepeat = 0;
                    continue;
                }
                break;
            case TRIPBOMBSPRITE:
                continue;
            case FORCESPHERE:
                if(t->statnum == 5)
                {
                    short sqa,sqb;

                    sqa =
                        getangle(
                            sprite[s->owner].x-ps[screenpeek].posx,
                            sprite[s->owner].y-ps[screenpeek].posy);
                    sqb =
                        getangle(
                            sprite[s->owner].x-t->x,
                            sprite[s->owner].y-t->y);

                    if( klabs(getincangle(sqa,sqb)) > 512 )
                        if( ldist(&sprite[s->owner],t) < ldist(&sprite[ps[screenpeek].i],&sprite[s->owner]) )
                            t->xrepeat = t->yrepeat = 0;
                }
                continue;
            case BURNING:
                if( sprite[s->owner].statnum == 10 )
                {
                    if( display_mirror == 0 && sprite[s->owner].yvel == screenpeek && ps[sprite[s->owner].yvel].over_shoulder_on == 0 )
                        t->xrepeat = 0;
                    else
                    {
                        t->ang = getangle(x-t->x,y-t->y);
                        t->x = sprite[s->owner].x;
                        t->y = sprite[s->owner].y;
                        t->x += sintable[(t->ang+512)&2047]>>10;
                        t->y += sintable[t->ang&2047]>>10;
                    }
                }
                break;

            case ATOMICHEALTH:
                t->z -= (4<<8);
                break;
            case CRYSTALAMMO:
                t->shade = (sintable[(totalclock<<4)&2047]>>10);
                break;
            case SHRINKSPARK:
#ifdef RRRA
                if (sprite[s->owner].picnum == CHEER || sprite[s->owner].picnum == CHEERSTAYPUT)
                {
                    t->picnum = CHEERBLADE+( (totalclock>>4)&3 );
                    t->shade = -127;
                }
                else
#endif
                t->picnum = SHRINKSPARK+( (totalclock>>4)&7 );
                break;
#ifdef RRRA
            case CHEERBOMB:
                t->picnum = CHEERBOMB+( (totalclock>>4)&3 );
                break;
#endif
            case SPIT:
#ifdef RRRA
                if (sprite[s->owner].picnum == MINION && sprite[s->owner].pal == 8)
                    t->picnum = RRTILE3500+( (totalclock>>4)%6 );
                else if (sprite[s->owner].picnum == MINION && sprite[s->owner].pal == 19)
                {
                    t->picnum = RRTILE5090+( (totalclock>>4)&3 );
                    t->shade = -127;
                }
                else if (sprite[s->owner].picnum == MAMA)
                {
                    k = getangle(s->x-x,s->y-y);
                    k = (((s->ang+3072+128-k)&2047)>>8)&7;
                    if(k>4)
                    {
                        k = 8-k;
                        t->cstat |= 4;
                    }
                    else t->cstat &= ~4;
                    t->picnum = RRTILE7274+k;
                }
                else
#endif
                t->picnum = SPIT+( (totalclock>>4)&3 );
                break;
#ifdef RRRA
            case EMPTYBIKE:
                 k = getangle(s->x-x,s->y-y);
                 k = (((s->ang+3072+128-k)&2047)/170);
                 if(k > 6)
                 {
                    k = 12-k;
                    t->cstat |= 4;
                 }
                 else t->cstat &= ~4;
                 t->picnum = EMPTYBIKE+k;
                 break;
            case EMPTYBOAT:
                 k = getangle(s->x-x,s->y-y);
                 k = (((s->ang+3072+128-k)&2047)/170);
                 if(k > 6)
                 {
                    k = 12-k;
                    t->cstat |= 4;
                 }
                 else t->cstat &= ~4;
                 t->picnum = EMPTYBOAT+k;
                 break;
#endif
            case RPG:
                 k = getangle(s->x-x,s->y-y);
                 k = (((s->ang+3072+128-k)&2047)/170);
                 if(k > 6)
                 {
                    k = 12-k;
                    t->cstat |= 4;
                 }
                 else t->cstat &= ~4;
                 t->picnum = RPG+k;
                 break;
#ifdef RRRA
            case RPG2:
                 k = getangle(s->x-x,s->y-y);
                 k = (((s->ang+3072+128-k)&2047)/170);
                 if(k > 6)
                 {
                    k = 12-k;
                    t->cstat |= 4;
                 }
                 else t->cstat &= ~4;
                 t->picnum = RPG2+k;
                 break;
#endif

            case RECON:

                k = getangle(s->x-x,s->y-y);
                if( T1 < 4 )
                    k = (((s->ang+3072+128-k)&2047)/170);
                else k = (((s->ang+3072+128-k)&2047)/170);

                if(k>6)
                {
                    k = 12-k;
                    t->cstat |= 4;
                }
                else t->cstat &= ~4;

                if( klabs(t3) > 64 ) k += 7;
                t->picnum = RECON+k;

                break;

            case APLAYER:

                p = s->yvel;

                if(t->pal == 1) t->z -= (18<<8);

                if(ps[p].over_shoulder_on > 0 && ps[p].newowner < 0 )
                {
                    t->cstat |= 2;
                    if ( screenpeek == myconnectindex && numplayers >= 2 )
                    {
                        t->x = omyx+mulscale16((long)(myx-omyx),smoothratio);
                        t->y = omyy+mulscale16((long)(myy-omyy),smoothratio);
                        t->z = omyz+mulscale16((long)(myz-omyz),smoothratio)+(40<<8);
                        t->ang = omyang+mulscale16((long)(((myang+1024-omyang)&2047)-1024),smoothratio);
                        t->sectnum = mycursectnum;
                    }
                }

                if( ( display_mirror == 1 || screenpeek != p || s->owner == -1 ) && ud.multimode > 1 && ud.showweapons && sprite[ps[p].i].extra > 0 && ps[p].curr_weapon > 0 )
                {
                    memcpy((spritetype *)&tsprite[spritesortcnt],(spritetype *)t,sizeof(spritetype));

                    tsprite[spritesortcnt].statnum = 99;

                    tsprite[spritesortcnt].yrepeat = ( t->yrepeat>>3 );
                    if(t->yrepeat < 4) t->yrepeat = 4;

                    tsprite[spritesortcnt].shade = t->shade;
                    tsprite[spritesortcnt].cstat = 0;

                    switch(ps[p].curr_weapon)
                    {
                        case PISTOL_WEAPON:      tsprite[spritesortcnt].picnum = FIRSTGUNSPRITE;       break;
                        case SHOTGUN_WEAPON:     tsprite[spritesortcnt].picnum = SHOTGUNSPRITE;        break;
                        case CHAINGUN_WEAPON:    tsprite[spritesortcnt].picnum = CHAINGUNSPRITE;       break;
                        case RPG_WEAPON:         tsprite[spritesortcnt].picnum = RPGSPRITE;            break;
#ifdef RRRA
                        case RA16_WEAPON:        tsprite[spritesortcnt].picnum = RPGSPRITE;
#endif
                        case HANDREMOTE_WEAPON:
                        case HANDBOMB_WEAPON:    tsprite[spritesortcnt].picnum = HEAVYHBOMB;           break;
                        case TRIPBOMB_WEAPON:    tsprite[spritesortcnt].picnum = TRIPBOMBSPRITE;       break;
                        case BOWLING_WEAPON:     tsprite[spritesortcnt].picnum = 3437;                 break;
                        case SHRINKER_WEAPON:    tsprite[spritesortcnt].picnum = SHRINKSPARK;          break;
                        case GROW_WEAPON:        tsprite[spritesortcnt].picnum = SHRINKSPARK;          break;
                        case FREEZE_WEAPON:      tsprite[spritesortcnt].picnum = DEVISTATORSPRITE;     break;
                        case DEVISTATOR_WEAPON:  tsprite[spritesortcnt].picnum = FREEZESPRITE;         break;
                    }

                    if(s->owner >= 0)
                        tsprite[spritesortcnt].z = ps[p].posz-(12<<8);
                    else tsprite[spritesortcnt].z = s->z-(51<<8);
                    if(ps[p].curr_weapon == HANDBOMB_WEAPON)
                    {
                        tsprite[spritesortcnt].xrepeat = 10;
                        tsprite[spritesortcnt].yrepeat = 10;
                    }
#ifdef RRRA
                    else if(ps[p].OnMotorcycle || ps[p].OnBoat)
                    {
                        tsprite[spritesortcnt].xrepeat = 0;
                        tsprite[spritesortcnt].yrepeat = 0;
                    }
#endif
                    else
                    {
                        tsprite[spritesortcnt].xrepeat = 16;
                        tsprite[spritesortcnt].yrepeat = 16;
                    }
                    tsprite[spritesortcnt].pal = 0;
                    spritesortcnt++;
                }

                if(s->owner == -1)
                {
                    k = (((s->ang+3072+128-a)&2047)>>8)&7;
                    if(k>4)
                    {
                        k = 8-k;
                        t->cstat |= 4;
                    }
                    else t->cstat &= ~4;

                    if(sector[t->sectnum].lotag == 2) k += 1795-1405;
                    else if( (hittype[i].floorz-s->z) > (64<<8) ) k += 60;

                    t->picnum += k;
                    t->pal = ps[p].palookup;

                    goto PALONLY;
                }

                if( ps[p].on_crane == -1 && (sector[s->sectnum].lotag&0x7ff) != 1 )
                {
                    l = s->z-hittype[ps[p].i].floorz+(3<<8);
                    if( l > 1024 && s->yrepeat > 32 && s->extra > 0 )
                        s->yoffset = (signed char)(l/(s->yrepeat<<2));
                    else s->yoffset=0;
                }

                if(ps[p].newowner > -1)
                {
                    t4 = *(actorscrptr[APLAYER]+1);
                    t3 = 0;
                    t1 = *(actorscrptr[APLAYER]+2);
                }

                if(ud.camerasprite == -1 && ps[p].newowner == -1)
                    if(s->owner >= 0 && display_mirror == 0 && ps[p].over_shoulder_on == 0 )
                        if( ud.multimode < 2 || ( ud.multimode > 1 && p == screenpeek ) )
                {
                    t->owner = -1;
                    t->xrepeat = t->yrepeat = 0;
                    continue;
                }

                PALONLY:

                if( sector[sect].floorpal )
                    t->pal = sector[sect].floorpal;

                if(s->owner == -1) continue;

                if( t->z > hittype[i].floorz && t->xrepeat < 32 )
                    t->z = hittype[i].floorz;

#ifdef RRRA
                if (ps[p].OnMotorcycle && p == screenpeek)
                {
                    t->picnum = RRTILE7219;
                    t->xrepeat = 18;
                    t->yrepeat = 18;
                    t4 = 0;
                    t3 = 0;
                    t1 = 0;
                }
                else if (ps[p].OnMotorcycle)
                {
                    k = (((s->ang+3072+128-a)&2047)/170);
                    if(k>6)
                    {
                        k = 12-k;
                        t->cstat |= 4;
                    }
                    else t->cstat &= ~4;

                    t->picnum = RRTILE7213+k;
                    t->xrepeat = 18;
                    t->yrepeat = 18;
                    t4 = 0;
                    t3 = 0;
                    t1 = 0;
                }
                else if (ps[p].OnBoat && p == screenpeek)
                {
                    t->picnum = RRTILE7190;
                    t->xrepeat = 32;
                    t->yrepeat = 32;
                    t4 = 0;
                    t3 = 0;
                    t1 = 0;
                }
                else if (ps[p].OnBoat)
                {
                    k = (((s->ang+3072+128-a)&2047)/170);
                    if(k>6)
                    {
                        k = 12-k;
                        t->cstat |= 4;
                    }
                    else t->cstat &= ~4;

                    t->picnum = RRTILE7184+k;
                    t->xrepeat = 32;
                    t->yrepeat = 32;
                    t4 = 0;
                    t3 = 0;
                    t1 = 0;
                }
#endif

                break;

            case MINJIBA:
            case MINJIBB:
            case MINJIBC:
#ifdef RRRA
                if (t->pal == 19)
                    t->shade = -127;
#endif
            case JIBS1:
            case JIBS2:
            case JIBS3:
            case JIBS4:
            case JIBS5:
            case JIBS6:
            case DUKEGUN:
            case DUKETORSO:
            case DUKELEG:
            case BILLYJIBA:
            case BILLYJIBB:
            case HULKJIBA:
            case HULKJIBB:
            case HULKJIBC:
            case COOTJIBA:
            case COOTJIBB:
            case COOTJIBC:
#ifdef RRRA
            case RRTILE2460:
            case RRTILE2465:
            case BIKEJIBA:
            case BIKEJIBB:
            case BIKEJIBC:
            case BIKERJIBA:
            case BIKERJIBB:
            case BIKERJIBC:
            case BIKERJIBD:
            case CHEERJIBA:
            case CHEERJIBB:
            case CHEERJIBC:
            case CHEERJIBD:
            case FBOATJIBA:
            case FBOATJIBB:
            case RABBITJIBA:
            case RABBITJIBB:
            case RABBITJIBC:
            case MAMAJIBA:
            case MAMAJIBB:
#endif
                if(ud.lockout)
                {
                    t->xrepeat = t->yrepeat = 0;
                    continue;
                }
                if(t->pal == 6) t->shade = -120;

                if (shadedsector[s->sectnum] == 1)
                    t->shade = 16;

            case SCRAP1:
            case SCRAP2:
            case SCRAP3:
            case SCRAP4:
            case SCRAP5:
            case SCRAP6:
            case SCRAP6+1:
            case SCRAP6+2:
            case SCRAP6+3:
            case SCRAP6+4:
            case SCRAP6+5:
            case SCRAP6+6:
            case SCRAP6+7:

                if(t->picnum == SCRAP1 && s->yvel >= 0)
                    t->picnum = s->yvel;
                else t->picnum += T1;

                if( sector[sect].floorpal )
                    t->pal = sector[sect].floorpal;
                break;

            case WATERBUBBLE:
                if(sector[t->sectnum].floorpicnum == FLOORSLIME)
                {
                    t->pal = 7;
                    break;
                }
            default:

                if( sector[sect].floorpal )
                    t->pal = sector[sect].floorpal;
                break;
        }

        if( actorscrptr[s->picnum] && (t->cstat & 48) != 48)
        {
            if(t4)
            {
                l = *(long *)(t4+8);

                switch( l )
                {
                    case 2:
                        k = (((s->ang+3072+128-a)&2047)>>8)&1;
                        break;

                    case 3:
                    case 4:
                        k = (((s->ang+3072+128-a)&2047)>>7)&7;
                        if(k > 3)
                        {
                            t->cstat |= 4;
                            k = 7-k;
                        }
                        else t->cstat &= ~4;
                        break;

                    case 5:
                        k = getangle(s->x-x,s->y-y);
                        k = (((s->ang+3072+128-k)&2047)>>8)&7;
                        if(k>4)
                        {
                            k = 8-k;
                            t->cstat |= 4;
                        }
                        else t->cstat &= ~4;
                        break;
                    case 7:
                        k = getangle(s->x-x,s->y-y);
                        k = (((s->ang+3072+128-k)&2047)/170);
                        if(k>6)
                        {
                            k = 12-k;
                            t->cstat |= 4;
                        }
                        else t->cstat &= ~4;
                        break;
                    case 8:
                        k = (((s->ang+3072+128-a)&2047)>>8)&7;
                        t->cstat &= ~4;
                        break;
                    default:
                        bg = badguy(s);
                        if (bg && s->statnum == 2 && s->extra > 0)
                        {
                            k = getangle(s->x-x,s->y-y);
                            k = (((s->ang+3072+128-k)&2047)>>8)&7;
                            if(k>4)
                            {
                                k = 8-k;
                                t->cstat |= 4;
                            }
                            else t->cstat &= ~4;
                            break;
                        }
                        k = 0;
                        bg = 0;
                        break;
                }

                if (bg)
                    t->picnum += k + ( *(long *)t4 ) + l * t3;
                else
                    t->picnum += k + ( *(long *)t4 ) + l * t3;

                if(l > 0) while(tilesizx[t->picnum] == 0 && t->picnum > 0 )
                    t->picnum -= l;       //Hack, for actors

                if( hittype[i].dispicnum >= 0)
                    hittype[i].dispicnum = t->picnum;
            }
            else if(display_mirror == 1)
                t->cstat |= 4;
        }

#ifndef RRRA
        if (s->picnum == SBMOVE)
            t->shade = -127;
#endif

        if( s->statnum == 13 || badguy(s) || (s->picnum == APLAYER && s->owner >= 0) )
            if( (s->cstat&48) == 0 && t->statnum != 99 )
                if(s->picnum != EXPLOSION2 && s->picnum != DOMELITE)
                    if(s->picnum != TORNADO)
                        if(s->picnum != EXPLOSION3)
#ifndef RRRA
                            if(s->picnum != SBMOVE)
#endif
        {
            if( hittype[i].dispicnum < 0 )
            {
                hittype[i].dispicnum++;
                continue;
            }
            else if( ud.shadows && spritesortcnt < (MAXSPRITESONSCREEN-2))
            {
                long daz,xrep,yrep;

#ifdef RRRA
                if (sector[sect].lotag == 160) continue;
#endif
                if( (sector[sect].lotag&0xff) > 2 || s->statnum == 4 || s->statnum == 5 || s->picnum == DRONE )
                    daz = sector[sect].floorz;
                else
                    daz = hittype[i].floorz;

                if( (s->z-daz) < (8<<8) )
                    if( ps[screenpeek].posz < daz )
                {
                    memcpy((spritetype *)&tsprite[spritesortcnt],(spritetype *)t,sizeof(spritetype));

                    tsprite[spritesortcnt].statnum = 99;

                    tsprite[spritesortcnt].yrepeat = ( t->yrepeat>>3 );
                    if(t->yrepeat < 4) t->yrepeat = 4;

                    tsprite[spritesortcnt].shade = 127;
                    tsprite[spritesortcnt].cstat |= 2;

                    tsprite[spritesortcnt].z = daz;
                    xrep = tsprite[spritesortcnt].xrepeat;// - (klabs(daz-t->z)>>11);
                    tsprite[spritesortcnt].xrepeat = xrep;
                    tsprite[spritesortcnt].pal = 4;

                    yrep = tsprite[spritesortcnt].yrepeat;// - (klabs(daz-t->z)>>11);
                    tsprite[spritesortcnt].yrepeat = yrep;
                    spritesortcnt++;
                }
            }
        }

        switch(s->picnum)
        {
            case EXPLOSION2:
            case FREEZEBLAST:
            case ATOMICHEALTH:
            case FIRELASER:
            case SHRINKSPARK:
            case CHAINGUN:
            case RPG:
            case EXPLOSION3:
            case COOLEXPLOSION1:
            case OWHIP:
            case UWHIP:
#ifdef RRRA
            case RPG2:
            case RRTILE1790:
#endif
                if(t->picnum == EXPLOSION2)
                {
                    ps[screenpeek].visibility = -127;
                    lastvisinc = totalclock+32;
                    restorepalette = 1;
                    t->pal = 0;
                }
                else if(t->picnum == FIRELASER)
                {
                    t->picnum = FIRELASER+((totalclock>>2)&5);
                }
                t->shade = -127;
                break;
            case UFOBEAM:
            case RRTILE3586:
            case RRTILE3587:
                t->cstat |= 32768;
                s->cstat |= 32768;
                break;
            case DESTRUCTO:
                t->cstat |= 32768;
                break;
            case FIRE:
            case BURNING:
                if( sprite[s->owner].picnum != TREE1 && sprite[s->owner].picnum != TREE2 )
                    t->z = sector[t->sectnum].floorz;
                t->shade = -127;
                break;
            case RRTILE1878:
            case RRTILE1952:
            case RRTILE1953:
            case RRTILE1990:
            case RRTILE2050:
            case RRTILE2056:
            case RRTILE2072:
            case RRTILE2075:
            case RRTILE2083:
            case RRTILE2097:
            case RRTILE2156:
            case RRTILE2157:
            case RRTILE2158:
            case RRTILE2159:
            case RRTILE2160:
            case RRTILE2161:
            case RRTILE2175:
            case RRTILE2176:
            case RRTILE2357:
            case RRTILE2564:
            case RRTILE2573:
            case RRTILE2574:
            case RRTILE2583:
            case RRTILE2604:
            case RRTILE2689:
            case RRTILE2893:
            case RRTILE2894:
            case RRTILE2915:
            case RRTILE2945:
            case RRTILE2946:
            case RRTILE2947:
            case RRTILE2948:
            case RRTILE2949:
            case RRTILE2977:
            case RRTILE2978:
            case RRTILE3116:
            case RRTILE3171:
            case RRTILE3216:
            case RRTILE3720:
#ifdef RRRA
            case WALLLIGHT3:
            case WALLLIGHT1:
            case RRTILE3668:
            case RRTILE3795:
            case RRTILE5035:
            case RRTILE7505:
            case RRTILE7506:
            case RRTILE7533:
            case RRTILE8216:
            case RRTILE8218:
            case RRTILE8220:
#endif
                t->shade = -127;
                break;
#ifdef RRRA
            case CHEER:
                if (t->picnum >= CHEER+102 && t->picnum <= CHEER+151)
                    t->shade = -127;
                break;
            case MINION:
                if (t->pal == 19)
                    t->shade = -127;
                break;
            case BIKER:
                if (t->picnum >= BIKER+54 && t->picnum <= BIKER+58)
                    t->shade = -127;
                else if (t->picnum >= BIKER+84 && t->picnum <= BIKER+88)
                    t->shade = -127;
                break;
            case BILLYRAY:
            case BILLYRAYSTAYPUT:
                if (t->picnum >= BILLYRAY+5 && t->picnum <= BILLYRAY+9)
                    t->shade = -127;
                break;
#endif
            case RRTILE2034:
                t->picnum = RRTILE2034+(totalclock&1);
                break;
            case RRTILE2944:
                t->shade = -127;
                t->picnum = RRTILE2944+((totalclock>>2)&4);
                break;
            case PLAYERONWATER:

                k = (((t->ang+3072+128-a)&2047)>>8)&7;
                if(k>4)
                {
                    k = 8-k;
                    t->cstat |= 4;
                }
                else t->cstat &= ~4;

                t->picnum = s->picnum+k+((T1<4)*5);
                t->shade = sprite[s->owner].shade;
                break;
            case MUD:
                t->picnum = MUD+t1;
                break;
            case WATERSPLASH2:
                t->picnum = WATERSPLASH2+t1;
                break;
            case REACTOR2:
                t->picnum = s->picnum + T3;
                break;
            case SHELL:
                t->picnum = s->picnum+(T1&1);
            case SHOTGUNSHELL:
                t->cstat |= 12;
                if(T1 > 1) t->cstat &= ~4;
                if(T1 > 2) t->cstat &= ~12;
                break;
            case FRAMEEFFECT1:
                if(s->owner >= 0 && sprite[s->owner].statnum < MAXSTATUS)
                {
                    if(sprite[s->owner].picnum == APLAYER)
                        if(ud.camerasprite == -1)
                            if(screenpeek == sprite[s->owner].yvel && display_mirror == 0)
                    {
                        t->owner = -1;
                        break;
                    }
                    if( (sprite[s->owner].cstat&32768) == 0 )
                    {
                        if(sprite[s->owner].picnum == APLAYER)
                            t->picnum = 1554;
                        else
                            t->picnum = hittype[s->owner].dispicnum;
                        t->pal = sprite[s->owner].pal;
                        t->shade = sprite[s->owner].shade;
                        t->ang = sprite[s->owner].ang;
                        t->cstat = 2|sprite[s->owner].cstat;
                    }
                }
                break;

            case CAMERA1:
            case RAT:
                k = (((t->ang+3072+128-a)&2047)>>8)&7;
                if(k>4)
                {
                    k = 8-k;
                    t->cstat |= 4;
                }
                else t->cstat &= ~4;
                t->picnum = s->picnum+k;
                break;
        }

        hittype[i].dispicnum = t->picnum;
        if(sector[t->sectnum].floorpicnum == MIRROR)
            t->xrepeat = t->yrepeat = 0;
    }
}

repo_name: orochi/nblood

license: mit


code:
//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
Copyright (C) 2017-2019 Nuke.YKT

This file is part of Duke Nukem 3D version 1.5 - Atomic Edition

Duke Nukem 3D is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

Original Source: 1996 - Todd Replogle
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------

#include "types.h"
#include "develop.h"
#include "scriplib.h"
#include "file_lib.h"
#include "gamedefs.h"
#include "keyboard.h"
#include "util_lib.h"
#include "function.h"
#include "control.h"
#include "fx_man.h"
#include "sounds.h"
#include "config.h"
#include "sndcards.h"

#include "duke3d.h"

extern char debug_on,actor_tog,*rtsptr;
extern short inputloc;

#ifdef RRRA
#define NUMCHEATCODES 40
char cheatquotes[NUMCHEATCODES][14] = {
    {"hounddog"},
    {"all"},
    {"meadow###"},
    {"yerat"},
    {"view"},
    {"time"},
    {"unlock"},
    {"cluck"},
    {"items"},
    {"rate"},
    {"skill#"},
    {"teachers"},
    {"moonshine"},
    {"critters"},
    {"<RESERVED>"},
    {"<RESERVED>"},
    {"rafael"},
    {"showmap"},
    {"elvis"},
    {"<RESERVED>"},
    {"clip"},
    {"guns"},
    {"inventory"},
    {"keys"},
    {"debug"},
    {"joseph"},
    {"mrbill"},
    {"tony"},
    {"gary"},
    {"rhett"},
    {"aaron"},
    {"nocheat"},
    {"woleslagle"},
    {"mikael"},
    {"greg"},
    {"noah"},
    {"arijit"},
    {"donut"},
    {"kfc"},
    {"van"}
};

char cheatbuf[20],cheatbuflen;
#else
#define NUMCHEATCODES 25
char cheatquotes[NUMCHEATCODES][14] = {
    {"hounddog"},
    {"all"},
    {"meadow###"},
    {"yerat"},
    {"view"},
    {"time"},
    {"unlock"},
    {"cluck"},
    {"items"},
    {"rate"},
    {"skill#"},
    {"teachers"},
    {"moonshine"},
    {"critters"},
    {"<RESERVED>"},
    {"<RESERVED>"},
    {"rafael"},
    {"showmap"},
    {"elvis"},
    {"<RESERVED>"},
    {"clip"},
    {"guns"},
    {"inventory"},
    {"keys"},
    {"debug"}
};

char cheatbuf[10],cheatbuflen;
#endif
void cheats(void)
{
    short ch, i, j, k, keystate, weapon, key;

#ifdef RRRA
    if (ud.m_player_skill > 3 || ps[myconnectindex].nocheat)
#else
    if (ud.m_player_skill > 3)
#endif
        return;

    if( (ps[myconnectindex].gm&MODE_TYPE) || (ps[myconnectindex].gm&MODE_MENU))
        return;

    if ( ps[myconnectindex].cheat_phase == 1)
    {
       while (KB_KeyWaiting())
       {
          ch = KB_Getch();
          ch = tolower(ch);

          if( !( (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') ) )
          {
             ps[myconnectindex].cheat_phase = 0;
//             FTA(46,&ps[myconnectindex]);
             return;
          }

          cheatbuf[cheatbuflen++] = ch;
          cheatbuf[cheatbuflen] = 0;

#ifdef RRRA
          if(cheatbuflen > 13)
#else
          if(cheatbuflen > 11)
#endif
          {
              ps[myconnectindex].cheat_phase = 0;
              return;
          }

          for(k = 0;k < NUMCHEATCODES;k++)
          {
              for(j = 0;j<cheatbuflen;j++)
              {
                  if( cheatbuf[j] == cheatquotes[k][j] || (cheatquotes[k][j] == '#' && ch >= '0' && ch <= '9') )
                  {
                      if( cheatquotes[k][j+1] == 0 ) goto FOUNDCHEAT;
                      if(j == cheatbuflen-1) return;
                  }
                  else break;
              }
          }

          ps[myconnectindex].cheat_phase = 0;
          return;

          FOUNDCHEAT:
          {
                switch(k)
                {
                    case 21:
                        j = 0;

                        for ( weapon = PISTOL_WEAPON;weapon < MAX_WEAPONS-j;weapon++ )
                        {
                            addammo( weapon, &ps[myconnectindex], max_ammo_amount[weapon] );
                            ps[myconnectindex].gotweapon[weapon]  = 1;
                        }
#ifdef RRRA
                        ps[myconnectindex].ammo_amount[RA15_WEAPON] = 1;
#endif

                        KB_FlushKeyboardQueue();
                        ps[myconnectindex].cheat_phase = 0;
                        FTA(119,&ps[myconnectindex]);
                        return;
                    case 22:
                        KB_FlushKeyboardQueue();
                        ps[myconnectindex].cheat_phase = 0;
                        ps[myconnectindex].steroids_amount =         400;
                        ps[myconnectindex].boot_amount          =    2000;
                        ps[myconnectindex].shield_amount =           100;
                        ps[myconnectindex].scuba_amount =            6400;
                        ps[myconnectindex].holoduke_amount =         2400;
                        ps[myconnectindex].jetpack_amount =          600;
                        ps[myconnectindex].firstaid_amount =         max_player_health;
                        FTA(120,&ps[myconnectindex]);
                        ps[myconnectindex].cheat_phase = 0;
                        return;
                    case 23:
                        {
                            int ikey;
                            ps[myconnectindex].got_access =              7;
                            KB_FlushKeyboardQueue();
                            ps[myconnectindex].cheat_phase = 0;
                            for (ikey = 0; ikey < 5; ikey++)
                                ps[myconnectindex].keys[ikey] = 1;
                            FTA(121,&ps[myconnectindex]);
                        }
                        return;
                    case 24:
                        debug_on = 1-debug_on;
                        KB_FlushKeyboardQueue();
                        ps[myconnectindex].cheat_phase = 0;
                        break;
                    case 20:
                        ud.clipping = 1-ud.clipping;
                        KB_FlushKeyboardQueue();
                        ps[myconnectindex].cheat_phase = 0;
                        FTA(112+ud.clipping,&ps[myconnectindex]);
                        return;

                    case 15:
                        FTA(52,&ps[myconnectindex]);
                        ps[myconnectindex].cheat_phase = 0;
                        KB_FlushKeyboardQueue();
                        return;

                    case 14:
                        FTA(51,&ps[myconnectindex]);
                        ps[myconnectindex].cheat_phase = 0;
                        KB_FlushKeyboardQueue();
                        return;

                    case 19:
                        FTA(79,&ps[myconnectindex]);
                        ps[myconnectindex].cheat_phase = 0;
                        KB_ClearKeyDown(sc_N);
                        return;
                    case 0:
                    case 18:

                        ud.god = 1-ud.god;

                        if(ud.god)
                        {
#ifdef RRRA
                            sound(218);
#endif
                            pus = 1;
                            pub = 1;
                            sprite[ps[myconnectindex].i].cstat = 257;

                            hittype[ps[myconnectindex].i].temp_data[0] = 0;
                            hittype[ps[myconnectindex].i].temp_data[1] = 0;
                            hittype[ps[myconnectindex].i].temp_data[2] = 0;
                            hittype[ps[myconnectindex].i].temp_data[3] = 0;
                            hittype[ps[myconnectindex].i].temp_data[4] = 0;
                            hittype[ps[myconnectindex].i].temp_data[5] = 0;

                            sprite[ps[myconnectindex].i].hitag = 0;
                            sprite[ps[myconnectindex].i].lotag = 0;
                            sprite[ps[myconnectindex].i].pal =
                                ps[myconnectindex].palookup;

                            FTA(17,&ps[myconnectindex]);
                        }
                        else
                        {
                            ud.god = 0;
                            sprite[ps[myconnectindex].i].extra = max_player_health;
                            hittype[ps[myconnectindex].i].extra = -1;
                            ps[myconnectindex].last_extra = max_player_health;
                            FTA(18,&ps[myconnectindex]);
                        }

                        sprite[ps[myconnectindex].i].extra = max_player_health;
                        hittype[ps[myconnectindex].i].extra = 0;
                        ps[myconnectindex].cheat_phase = 0;
                        KB_FlushKeyboardQueue();

                        return;

                    case 1:
                        j = 0;
                        for ( weapon = PISTOL_WEAPON;weapon < MAX_WEAPONS-j;weapon++ )
                           ps[myconnectindex].gotweapon[weapon]  = 1;

                        for ( weapon = PISTOL_WEAPON;
                              weapon < (MAX_WEAPONS-j);
                              weapon++ )
                            addammo( weapon, &ps[myconnectindex], max_ammo_amount[weapon] );
#ifdef RRRA
                        ps[myconnectindex].ammo_amount[RA15_WEAPON] = 1;
#endif

                        ps[myconnectindex].steroids_amount =         400;
                        ps[myconnectindex].boot_amount          =    2000;
                        ps[myconnectindex].shield_amount =           100;
                        ps[myconnectindex].scuba_amount =            6400;
                        ps[myconnectindex].holoduke_amount =         2400;
                        ps[myconnectindex].jetpack_amount =          600;
                        ps[myconnectindex].firstaid_amount =         max_player_health;

                        ps[myconnectindex].got_access =              7;
                        for (key = 0; key < 5; key++)
                            ps[myconnectindex].keys[key] = 1;
                        FTA(5,&ps[myconnectindex]);
                        ps[myconnectindex].cheat_phase = 0;

//                        FTA(21,&ps[myconnectindex]);
                        ps[myconnectindex].cheat_phase = 0;
                        KB_FlushKeyboardQueue();
                        ps[myconnectindex].inven_icon = 1;
                        return;

                    case 2:
                    case 10:

                        lastlevel = 0;
                        if(k == 2)
                        {
                            short volnume,levnume;
                            volnume = cheatbuf[6] - '0';
                            levnume = (cheatbuf[7] - '0')*10+(cheatbuf[8]-'0');

                            volnume--;
                            levnume--;
                            if(volnume > 4)
                            {
                                ps[myconnectindex].cheat_phase = 0;
                                KB_FlushKeyboardQueue();
                                return;
                            }
                            else

                            if(volnume == 0)
                            {
                                if(levnume > 7)
                                {
                                    ps[myconnectindex].cheat_phase = 0;
                                    KB_FlushKeyboardQueue();
                                    return;
                                }
                            }
                            else
                            {
                                if(levnume >= 8)
                                {
                                    ps[myconnectindex].cheat_phase = 0;
                                    KB_FlushKeyboardQueue();
                                    return;
                                }
                            }

                            ud.m_volume_number = ud.volume_number = volnume;
                            ud.m_level_number = ud.level_number = levnume;

                        }
                        else ud.m_player_skill = ud.player_skill =
                            cheatbuf[5] - '1';

                        if(numplayers > 1 && myconnectindex == connecthead)
                        {
                            tempbuf[0] = 5;
                            tempbuf[1] = ud.m_level_number;
                            tempbuf[2] = ud.m_volume_number;
                            tempbuf[3] = ud.m_player_skill;
                            tempbuf[4] = ud.m_monsters_off;
                            tempbuf[5] = ud.m_respawn_monsters;
                            tempbuf[6] = ud.m_respawn_items;
                            tempbuf[7] = ud.m_respawn_inventory;
                            tempbuf[8] = ud.m_coop;
                            tempbuf[9] = ud.m_marker;
                            tempbuf[10] = ud.m_ffire;

                            for(i=connecthead;i>=0;i=connectpoint2[i])
                                sendpacket(i,tempbuf,11);
                        }
                        else
                        {
                            ps[myconnectindex].gm |= MODE_RESTART;
                            FX_StopAllSounds();
                            clearsoundlocks();
                            FX_SetReverb(0);
                        }

                        ps[myconnectindex].cheat_phase = 0;
                        KB_FlushKeyboardQueue();
                        return;

                    case 3:
                        ps[myconnectindex].cheat_phase = 0;
                        ud.coords = 1-ud.coords;
                        KB_FlushKeyboardQueue();
                        return;

                    case 4:
#ifdef RRRA
                        if (ps[myconnectindex].OnMotorcycle == 0 && ps[myconnectindex].OnBoat == 0)
                        {
                            if( ps[myconnectindex].over_shoulder_on )
                                ps[myconnectindex].over_shoulder_on = 0;
                            else
                            {
                                ps[myconnectindex].over_shoulder_on = 1;
                                cameradist = 0;
                                cameraclock = totalclock;
                            }
                            FTA(22,&ps[myconnectindex]);
                        }
#else
                        if( ps[myconnectindex].over_shoulder_on )
                            ps[myconnectindex].over_shoulder_on = 0;
                        else
                        {
                            ps[myconnectindex].over_shoulder_on = 1;
                            cameradist = 0;
                            cameraclock = totalclock;
                        }
                        FTA(22,&ps[myconnectindex]);
#endif
                        ps[myconnectindex].cheat_phase = 0;
                        KB_FlushKeyboardQueue();
                        return;
                    case 5:

                        FTA(21,&ps[myconnectindex]);
                        ps[myconnectindex].cheat_phase = 0;
                        KB_FlushKeyboardQueue();
                        return;
                    case 6:
                        for(i=numsectors-1;i>=0;i--) //Unlock
                        {
                            j = sector[i].lotag;
                            if(j == -1 || j == 32767) continue;
                            if( (j & 0x7fff) > 2 )
                            {
                                if( j&(0xffff-16384) )
                                    sector[i].lotag &= (0xffff-16384);
                                operatesectors(i,ps[myconnectindex].i);
                            }
                        }
                        operateforcefields(ps[myconnectindex].i,-1);

                        FTA(100,&ps[myconnectindex]);
                        ps[myconnectindex].cheat_phase = 0;
                        KB_FlushKeyboardQueue();
                        return;

                    case 7:
                        ud.cashman = 1-ud.cashman;
                        KB_ClearKeyDown(sc_N);
                        ps[myconnectindex].cheat_phase = 0;
                        return;
                    case 8:

                        ps[myconnectindex].steroids_amount =         400;
                        ps[myconnectindex].boot_amount          =    2000;
                        ps[myconnectindex].shield_amount =           100;
                        ps[myconnectindex].scuba_amount =            6400;
                        ps[myconnectindex].holoduke_amount =         2400;
                        ps[myconnectindex].jetpack_amount =          600;

                        ps[myconnectindex].firstaid_amount =         max_player_health;
                        ps[myconnectindex].got_access =              7;
                        for (key = 0; key < 5; key++)
                            ps[myconnectindex].keys[key] = 1;
                        FTA(5,&ps[myconnectindex]);
                        ps[myconnectindex].cheat_phase = 0;
                        KB_FlushKeyboardQueue();
                        return;
                    case 17: // SHOW ALL OF THE MAP TOGGLE;
                        ud.showallmap = 1-ud.showallmap;
                        if(ud.showallmap)
                        {
                            for(i=0;i<(MAXSECTORS>>3);i++)
                                show2dsector[i] = 255;
                            for(i=0;i<(MAXWALLS>>3);i++)
                                show2dwall[i] = 255;
                            FTA(111,&ps[myconnectindex]);
                        }
                        else
                        {
                            for(i=0;i<(MAXSECTORS>>3);i++)
                                show2dsector[i] = 0;
                            for(i=0;i<(MAXWALLS>>3);i++)
                                show2dwall[i] = 0;
                            FTA(1,&ps[myconnectindex]);
                        }
                        ps[myconnectindex].cheat_phase = 0;
                        KB_FlushKeyboardQueue();
                        return;

                    case 16:
                        FTA(99,&ps[myconnectindex]);
                        ps[myconnectindex].cheat_phase = 0;
                        KB_FlushKeyboardQueue();
                        return;
                    case 9:
                        ud.tickrate = !ud.tickrate;
                        ps[myconnectindex].cheat_phase = 0;
                        KB_FlushKeyboardQueue();
                        return;
                    case 11:
                        FTA(105,&ps[myconnectindex]);
                        KB_ClearKeyDown(sc_H);
                        ps[myconnectindex].cheat_phase = 0;
                        KB_FlushKeyboardQueue();
                        return;
                    case 12:
                        ps[myconnectindex].steroids_amount = 399;
                        ps[myconnectindex].cheat_phase = 0;
                        FTA(37,&ps[myconnectindex]);
                        KB_FlushKeyboardQueue();
                        return;
                    case 13:
                        if(actor_tog == 3) actor_tog = 0;
                        actor_tog++;
                        ps[screenpeek].cheat_phase = 0;
                        KB_FlushKeyboardQueue();
                        return;
#ifdef RRRA
                    case 25:
                        OnMotorcycle(&ps[myconnectindex],0);
                        ps[myconnectindex].ammo_amount[RA13_WEAPON] = max_ammo_amount[RA13_WEAPON];
                        FTA(126,&ps[myconnectindex]);
                        ps[myconnectindex].cheat_phase = 0;
                        KB_FlushKeyboardQueue();
                        return;
                    case 26:
                        quickkill(&ps[myconnectindex]);
                        FTA(127,&ps[myconnectindex]);
                        ps[myconnectindex].cheat_phase = 0;
                        KB_FlushKeyboardQueue();
                        return;
                    case 28:
                        if (numplayers < 2 && ps[myconnectindex].gm == MODE_GAME && cdon)
                        {
                            rbstop();
                            rbPlayTrack(10);
                        }
                        ps[myconnectindex].cheat_phase = 0;
                        KB_FlushKeyboardQueue();
                        return;
                    case 35:
                        if (ps[myconnectindex].raat5d9)
                            ps[myconnectindex].raat5d9 = 0;
                        else
                            ps[myconnectindex].raat5d9 = 1;
                        ps[myconnectindex].cheat_phase = 0;
                        KB_FlushKeyboardQueue();
                        return;
                    case 29:
                        ud.god = 0;
                        for (weapon = KNEE_WEAPON; weapon < MAX_WEAPONS; weapon++)
                        {
                            ps[myconnectindex].gotweapon[weapon] = 0;
                        }
                        ps[myconnectindex].curr_weapon = KNEE_WEAPON;
                        ps[myconnectindex].nocheat = 1;
                        sprite[ps[myconnectindex].i].extra = 1;
                        FTA(128,&ps[myconnectindex]);
                        ps[myconnectindex].cheat_phase = 0;
                        KB_FlushKeyboardQueue();
                        return;
                    case 30:
                        if (ps[myconnectindex].DrugMode)
                            ps[myconnectindex].DrugMode = 0;
                        else
                            ps[myconnectindex].DrugMode = 5;
                        ps[myconnectindex].cheat_phase = 0;
                        KB_FlushKeyboardQueue();
                        return;
                    case 31:
                        ps[myconnectindex].nocheat = 1;
                        FTA(130,&ps[myconnectindex]);
                        ps[myconnectindex].cheat_phase = 0;
                        KB_FlushKeyboardQueue();
                        return;
                    case 27:
                    case 38:
                    case 39:
                        if (k == 27)
                        {
                            ps[myconnectindex].raat607 = 2;
                        }
                        else if (k == 39)
                        {
                            ps[myconnectindex].raat607 = 3;
                        }
                        else
                        {
                            for (i = 0; i < 7; i++)
                            {
                                short spr;

                                spr = spawn(ps[screenpeek].i,HEN);
                                sprite[spr].pal = 1;
                                sprite[spr].xrepeat = sprite[spr].xrepeat<<2;
                                sprite[spr].yrepeat = sprite[spr].yrepeat<<2;
                            }
                            FTA(139,&ps[myconnectindex]);
                        }
                        ps[myconnectindex].cheat_phase = 0;
                        KB_FlushKeyboardQueue();
                        return;
                    case 32:
                        if (ps[myconnectindex].drink_amt)
                        {
                            ps[myconnectindex].drink_amt = 0;
                            FTA(132,&ps[myconnectindex]);
                        }
                        else
                        {
                            ps[myconnectindex].drink_amt = 90;
                            FTA(131,&ps[myconnectindex]);
                        }
                        ps[myconnectindex].cheat_phase = 0;
                        KB_FlushKeyboardQueue();
                        return;
                    case 33:
                        addammo(PISTOL_WEAPON,&ps[myconnectindex],max_ammo_amount[weapon]);
                        for (weapon = PISTOL_WEAPON; weapon < MAX_WEAPONS; weapon++)
                        {
                            ps[myconnectindex].gotweapon[weapon] = 1;
                        }

                        for (weapon = PISTOL_WEAPON; weapon < MAX_WEAPONS-j; weapon++)
                        {
                            ps[myconnectindex].ammo_amount[weapon] = 66;
                        }

                        ps[myconnectindex].ammo_amount[RA15_WEAPON] = 1;

                        ps[myconnectindex].steroids_amount = 400;
                        ps[myconnectindex].boot_amount = 2000;
                        ps[myconnectindex].shield_amount = 100;
                        ps[myconnectindex].scuba_amount = 6400;
                        ps[myconnectindex].holoduke_amount = 2400;
                        ps[myconnectindex].jetpack_amount = 600;
                        ps[myconnectindex].firstaid_amount = max_player_health;
                        ps[myconnectindex].got_access = 7;
                        for (key = 0; key < 5; key++)
                        {
                            ps[myconnectindex].keys[key] = 1;
                        }

                        FTA(5,&ps[myconnectindex]);
                        ps[myconnectindex].cheat_phase = 0;
                        KB_FlushKeyboardQueue();
                        return;
                    case 34:
                        if (ps[myconnectindex].raat5dd)
                        {
                            ps[myconnectindex].raat5dd = 0;
                            FTA(129,&ps[myconnectindex]);
                        }
                        else
                        {
                            ps[myconnectindex].raat5dd = 1;
                            FTA(137, &ps[myconnectindex]);
                        }
                        ps[myconnectindex].cheat_phase = 0;
                        KB_FlushKeyboardQueue();
                        return;
                    case 36:
                    case 37:
                        OnBoat(&ps[myconnectindex],0);
                        ps[myconnectindex].ammo_amount[RA14_WEAPON] = max_ammo_amount[RA14_WEAPON];
                        FTA(136,&ps[myconnectindex]);
                        ps[myconnectindex].cheat_phase = 0;
                        return;
#endif
                }
             }
          }
       }

    else
    {
        if( KB_KeyPressed(sc_R) )
        {
            if( ps[myconnectindex].cheat_phase >= 0 && numplayers < 2 && ud.recstat == 0)
                ps[myconnectindex].cheat_phase = -1;
        }

        if( KB_KeyPressed(sc_D) )
        {
            if( ps[myconnectindex].cheat_phase == -1 )
            {
                if(ud.player_skill == 4)
                {
                    FTA(22,&ps[myconnectindex]);
                    ps[myconnectindex].cheat_phase = 0;
                }
                else
                {
                    ps[myconnectindex].cheat_phase = 1;
//                    FTA(25,&ps[myconnectindex]);
                    cheatbuflen = 0;
                }
                KB_FlushKeyboardQueue();
            }
            else if(ps[myconnectindex].cheat_phase != 0)
            {
                ps[myconnectindex].cheat_phase = 0;
                KB_ClearKeyDown(sc_R);
                KB_ClearKeyDown(sc_D);
            }
        }
    }
}

long nonsharedtimer;
void nonsharedkeys(void)
{
    short i,ch, weapon;
    long j;

    if(ud.recstat == 2)
    {
        ControlInfo noshareinfo;
        CONTROL_GetInput( &noshareinfo );
    }

    if( KB_KeyPressed( sc_F12 ) )
    {
        KB_ClearKeyDown( sc_F12 );
        screencapture("RDNK0000.pcx",0);
        FTA(103,&ps[myconnectindex]);
    }

    if( !ALT_IS_PRESSED && ud.overhead_on == 0)
        {
            if( BUTTON( gamefunc_Enlarge_Screen ) )
            {
                CONTROL_ClearButton( gamefunc_Enlarge_Screen );
                if(ud.screen_size > 0)
                    sound(341);
                ud.screen_size -= 4;
                vscrn();
            }
            if( BUTTON( gamefunc_Shrink_Screen ) )
            {
                CONTROL_ClearButton( gamefunc_Shrink_Screen );
                if(ud.screen_size < 64) sound(341);
                ud.screen_size += 4;
                vscrn();
            }
        }

    if( ps[myconnectindex].cheat_phase == 1 || ps[myconnectindex].gm&(MODE_MENU|MODE_TYPE)) return;

    if( BUTTON(gamefunc_See_Coop_View) && ( ud.coop == 1 || ud.recstat == 2) )
    {
        CONTROL_ClearButton( gamefunc_See_Coop_View );
        screenpeek = connectpoint2[screenpeek];
        if(screenpeek == -1) screenpeek = connecthead;
        restorepalette = 1;
    }

    if( ud.multimode > 1 && BUTTON(gamefunc_Show_Opponents_Weapon) )
    {
        CONTROL_ClearButton(gamefunc_Show_Opponents_Weapon);
        ud.showweapons = 1-ud.showweapons;
        FTA(82-ud.showweapons,&ps[screenpeek]);
    }

    if( BUTTON(gamefunc_Toggle_Crosshair) )
    {
        CONTROL_ClearButton(gamefunc_Toggle_Crosshair);
        ud.crosshair = 1-ud.crosshair;
        FTA(21-ud.crosshair,&ps[screenpeek]);
    }

    if(ud.overhead_on && BUTTON(gamefunc_Map_Follow_Mode) )
    {
        CONTROL_ClearButton(gamefunc_Map_Follow_Mode);
        ud.scrollmode = 1-ud.scrollmode;
        if(ud.scrollmode)
        {
            ud.folx = ps[screenpeek].oposx;
            ud.foly = ps[screenpeek].oposy;
            ud.fola = ps[screenpeek].oang;
        }
        FTA(83+ud.scrollmode,&ps[myconnectindex]);
    }

    if( SHIFTS_IS_PRESSED || ALT_IS_PRESSED )
    {
        i = 0;
        if( KB_KeyPressed( sc_F1) ) { KB_ClearKeyDown(sc_F1);i = 1; }
        if( KB_KeyPressed( sc_F2) ) { KB_ClearKeyDown(sc_F2);i = 2; }
        if( KB_KeyPressed( sc_F3) ) { KB_ClearKeyDown(sc_F3);i = 3; }
        if( KB_KeyPressed( sc_F4) ) { KB_ClearKeyDown(sc_F4);i = 4; }
        if( KB_KeyPressed( sc_F5) ) { KB_ClearKeyDown(sc_F5);i = 5; }
        if( KB_KeyPressed( sc_F6) ) { KB_ClearKeyDown(sc_F6);i = 6; }
        if( KB_KeyPressed( sc_F7) ) { KB_ClearKeyDown(sc_F7);i = 7; }
        if( KB_KeyPressed( sc_F8) ) { KB_ClearKeyDown(sc_F8);i = 8; }
        if( KB_KeyPressed( sc_F9) ) { KB_ClearKeyDown(sc_F9);i = 9; }
        if( KB_KeyPressed( sc_F10) ) {KB_ClearKeyDown(sc_F10);i = 10; }

        if(i)
        {
            if(SHIFTS_IS_PRESSED)
            {
                if(i == 5 && ps[myconnectindex].fta > 0 && ps[myconnectindex].ftq == 26)
                {
                    music_select++;
                    if(music_select == 44) music_select = 0;
                    strcpy(&tempbuf[0],"PLAYING ");
                    strcat(&tempbuf[0],&music_fn[0][music_select][0]);
                    playmusic(&music_fn[0][music_select][0]);
                    strcpy(&fta_quotes[26][0],&tempbuf[0]);
                    FTA(26,&ps[myconnectindex]);
                    return;
                }

                user_quote = ud.ridecule[i-1];
                user_quote_time = 180;

                ch = 0;

                tempbuf[ch] = 4;
                tempbuf[ch+1] = 0;
                strcat(tempbuf+1,ud.ridecule[i-1]);

                i = 1+strlen(ud.ridecule[i-1]);

                if(ud.multimode > 1)
                    for(ch=connecthead;ch>=0;ch=connectpoint2[ch])
                        if (ch != myconnectindex)
                            sendpacket(ch,tempbuf,i);

                pus = NUMPAGES;
                pub = NUMPAGES;

                return;

            }

            if(ud.lockout == 0)
                if(ALT_IS_PRESSED && ( RTS_NumSounds() > 0 ) && rtsplaying == 0 && VoiceToggle )
            {
                rtsptr = (char *)RTS_GetSound (i-1);
                if(*rtsptr == 'C')
                    FX_PlayVOC3D( rtsptr,0,0,0,255,-i);
                else FX_PlayWAV3D( rtsptr,0,0,0,255,-i);

                rtsplaying = 7;

                if(ud.multimode > 1)
                {
                    tempbuf[0] = 7;
                    tempbuf[1] = i;

                    for(ch=connecthead;ch>=0;ch=connectpoint2[ch])
                        if(ch != myconnectindex)
                            sendpacket(ch,tempbuf,2);
                }

                pus = NUMPAGES;
                pub = NUMPAGES;

                return;
            }
        }
    }

    if(!ALT_IS_PRESSED && !SHIFTS_IS_PRESSED)
    {

        if( ud.multimode > 1 && BUTTON(gamefunc_SendMessage) )
        {
            KB_FlushKeyboardQueue();
            CONTROL_ClearButton( gamefunc_SendMessage );
            ps[myconnectindex].gm |= MODE_TYPE;
            typebuf[0] = 0;
            inputloc = 0;
        }

        if( KB_KeyPressed(sc_F1) || ( ud.show_help && ( KB_KeyPressed(sc_Space) || KB_KeyPressed(sc_Enter) || KB_KeyPressed(sc_kpad_Enter) ) ) )
        {
            KB_ClearKeyDown(sc_F1);
            KB_ClearKeyDown(sc_Space);
            KB_ClearKeyDown(sc_kpad_Enter);
            KB_ClearKeyDown(sc_Enter);
            ud.show_help ++;

#ifdef RRRA
            if( ud.show_help > 3 )
#else
            if( ud.show_help > 2 )
#endif
            {
                ud.show_help = 0;
                if(ud.multimode < 2 && ud.recstat != 2) ready2send = 1;
                vscrn();
            }
            else
            {
                setview(0,0,xdim-1,ydim-1);
                if(ud.multimode < 2 && ud.recstat != 2)
                {
                    ready2send = 0;
                    totalclock = ototalclock;
                }
            }
        }

//        if(ud.multimode < 2)
        {
            if(ud.recstat != 2 && KB_KeyPressed( sc_F2 ) )
            {
                KB_ClearKeyDown( sc_F2 );

                if(movesperpacket == 4 && connecthead != myconnectindex)
                    return;

                FAKE_F2:
                if(sprite[ps[myconnectindex].i].extra <= 0)
                {
                    FTA(118,&ps[myconnectindex]);
                    return;
                }
                cmenu(350);
                screencapt = 1;
                displayrooms(myconnectindex,65536);
                savetemp("redneck.tmp",waloff[MAXTILES-1],160*100);
                screencapt = 0;
                FX_StopAllSounds();
                clearsoundlocks();

//                setview(0,0,xdim-1,ydim-1);
                ps[myconnectindex].gm |= MODE_MENU;

                if(ud.multimode < 2)
                {
                    ready2send = 0;
                    totalclock = ototalclock;
                    screenpeek = myconnectindex;
                }
            }

            if(KB_KeyPressed( sc_F3 ))
            {
                KB_ClearKeyDown( sc_F3 );

                if(movesperpacket == 4 && connecthead != myconnectindex)
                    return;

                cmenu(300);
                FX_StopAllSounds();
                clearsoundlocks();

//                setview(0,0,xdim-1,ydim-1);
                ps[myconnectindex].gm |= MODE_MENU;
                if(ud.multimode < 2 && ud.recstat != 2)
                {
                    ready2send = 0;
                    totalclock = ototalclock;
                }
                screenpeek = myconnectindex;
            }
        }

        if(KB_KeyPressed( sc_F4 ) && FXDevice != NumSoundCards )
        {
            KB_ClearKeyDown( sc_F4 );
            FX_StopAllSounds();
            clearsoundlocks();

            ps[myconnectindex].gm |= MODE_MENU;
            if(ud.multimode < 2 && ud.recstat != 2)
            {
                ready2send = 0;
                totalclock = ototalclock;
            }
            cmenu(700);

        }

        if( KB_KeyPressed( sc_F6 ) && (ps[myconnectindex].gm&MODE_GAME))
        {
            KB_ClearKeyDown( sc_F6 );

            if(movesperpacket == 4 && connecthead != myconnectindex)
                return;

            if(lastsavedpos == -1) goto FAKE_F2;

            KB_FlushKeyboardQueue();

            if(sprite[ps[myconnectindex].i].extra <= 0)
            {
                FTA(118,&ps[myconnectindex]);
                return;
            }
            screencapt = 1;
            displayrooms(myconnectindex,65536);
            savetemp("redneck.tmp",waloff[MAXTILES-1],160*100);
            screencapt = 0;
            if( lastsavedpos >= 0 )
            {
                inputloc = strlen(&ud.savegame[lastsavedpos][0]);
                current_menu = 360+lastsavedpos;
                probey = lastsavedpos;
            }
            FX_StopAllSounds();
            clearsoundlocks();

            setview(0,0,xdim-1,ydim-1);
            ps[myconnectindex].gm |= MODE_MENU;
            if(ud.multimode < 2 && ud.recstat != 2)
            {
                ready2send = 0;
                totalclock = ototalclock;
            }
        }

        if(KB_KeyPressed( sc_F7 ) )
        {
            KB_ClearKeyDown(sc_F7);
#ifdef RRRA
            if (ps[myconnectindex].OnMotorcycle == 0 && ps[myconnectindex].OnBoat == 0)
            {
                if( ps[myconnectindex].over_shoulder_on )
                    ps[myconnectindex].over_shoulder_on = 0;
                else
                {
                    ps[myconnectindex].over_shoulder_on = 1;
                    cameradist = 0;
                    cameraclock = totalclock;
                }
                FTA(109+ps[myconnectindex].over_shoulder_on,&ps[myconnectindex]);
            }
#else
            if( ps[myconnectindex].over_shoulder_on )
                ps[myconnectindex].over_shoulder_on = 0;
            else
            {
                ps[myconnectindex].over_shoulder_on = 1;
                cameradist = 0;
                cameraclock = totalclock;
            }
            FTA(109+ps[myconnectindex].over_shoulder_on,&ps[myconnectindex]);
#endif
        }

        if( KB_KeyPressed( sc_F5 ) && MusicDevice != NumSoundCards )
        {
            KB_ClearKeyDown( sc_F5 );
            strcpy(&tempbuf[0],&music_fn[0][music_select][0]);
            strcat(&tempbuf[0],".  USE SHIFT-F5 TO CHANGE.");
            strcpy(&fta_quotes[26][0],&tempbuf[0]);
            FTA(26,&ps[myconnectindex]);

        }

        if(KB_KeyPressed( sc_F8 ))
        {
            KB_ClearKeyDown( sc_F8 );
            ud.fta_on = !ud.fta_on;
            if(ud.fta_on) FTA(23,&ps[myconnectindex]);
            else
            {
                ud.fta_on = 1;
                FTA(24,&ps[myconnectindex]);
                ud.fta_on = 0;
            }
        }

        if(KB_KeyPressed( sc_F9 ) && (ps[myconnectindex].gm&MODE_GAME) )
        {
            KB_ClearKeyDown( sc_F9 );

            if(movesperpacket == 4 && myconnectindex != connecthead)
                return;

            if( lastsavedpos >= 0 ) cmenu(15001);
            else cmenu(25000);
            FX_StopAllSounds();
            clearsoundlocks();
            ps[myconnectindex].gm |= MODE_MENU;
            if(ud.multimode < 2 && ud.recstat != 2)
            {
                ready2send = 0;
                totalclock = ototalclock;
            }
        }

        if(KB_KeyPressed( sc_F10 ))
        {
            KB_ClearKeyDown( sc_F10 );
            cmenu(500);
            FX_StopAllSounds();
            clearsoundlocks();
            ps[myconnectindex].gm |= MODE_MENU;
            if(ud.multimode < 2 && ud.recstat != 2)
            {
                ready2send = 0;
                totalclock = ototalclock;
            }
        }

        if( ud.overhead_on != 0)
        {

            j = totalclock-nonsharedtimer; nonsharedtimer += j;
            if ( BUTTON( gamefunc_Enlarge_Screen ) )
                ps[myconnectindex].zoom += mulscale6(j,max(ps[myconnectindex].zoom,256));
            if ( BUTTON( gamefunc_Shrink_Screen ) )
                ps[myconnectindex].zoom -= mulscale6(j,max(ps[myconnectindex].zoom,256));

            if( (ps[myconnectindex].zoom > 2048) )
                ps[myconnectindex].zoom = 2048;
            if( (ps[myconnectindex].zoom < 48) )
                ps[myconnectindex].zoom = 48;

        }
    }

    if( KB_KeyPressed(sc_Escape) && ud.overhead_on && ps[myconnectindex].newowner == -1 )
    {
        KB_ClearKeyDown( sc_Escape );
        ud.last_overhead = ud.overhead_on;
        ud.overhead_on = 0;
        ud.scrollmode = 0;
        vscrn();
    }

    if( BUTTON(gamefunc_AutoRun) )
    {
#ifdef RRRA
        if (ps[myconnectindex].OnMotorcycle == 0 && ps[myconnectindex].OnBoat == 0)
        {
            CONTROL_ClearButton(gamefunc_AutoRun);
            ud.auto_run = 1-ud.auto_run;
            FTA(85+ud.auto_run,&ps[myconnectindex]);
        }
#else
        CONTROL_ClearButton(gamefunc_AutoRun);
        ud.auto_run = 1-ud.auto_run;
        FTA(85+ud.auto_run,&ps[myconnectindex]);
#endif
    }

    if( BUTTON(gamefunc_Map) )
    {
        CONTROL_ClearButton( gamefunc_Map );
        if( ud.last_overhead != ud.overhead_on && ud.last_overhead)
        {
            ud.overhead_on = ud.last_overhead;
            ud.last_overhead = 0;
        }
        else
        {
            ud.overhead_on++;
            if(ud.overhead_on == 3 ) ud.overhead_on = 0;
            ud.last_overhead = ud.overhead_on;
        }
        restorepalette = 1;
        vscrn();
    }

    if(KB_KeyPressed( sc_F11 ))
    {
        KB_ClearKeyDown( sc_F11 );
        if(SHIFTS_IS_PRESSED) ud.brightness-=4;
        else ud.brightness+=4;

        if (ud.brightness > (7<<2) )
            ud.brightness = 0;
        else if(ud.brightness < 0)
            ud.brightness = (7<<2);

        setbrightness(ud.brightness>>2,&ps[myconnectindex].palette[0]);
        if(ud.brightness < 20) FTA( 29 + (ud.brightness>>2) ,&ps[myconnectindex]);
        else if(ud.brightness < 40) FTA( 96 + (ud.brightness>>2) - 5,&ps[myconnectindex]);
    }
}


code:
//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
Copyright (C) 2017-2019 Nuke.YKT

This file is part of Duke Nukem 3D version 1.5 - Atomic Edition

Duke Nukem 3D is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

Original Source: 1996 - Todd Replogle
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------

#include "types.h"
#include "develop.h"
#include "scriplib.h"
#include "file_lib.h"
#include "gamedefs.h"
#include "keyboard.h"
#include "util_lib.h"
#include "function.h"
#include "control.h"
#include "fx_man.h"
#include "sounds.h"
#include "config.h"
#include "sndcards.h"

#include "duke3d.h"

extern char confilename[];
extern int32 CommandSoundToggleOff;
extern int32 CommandMusicToggleOff;
extern char firstdemofile[];

#ifdef RRRA
#define VERSION "REL 1.0"
#define HEAD   "REDNECK RAMPAGE RIDES AGAIN(tm) "VERSION" - KENTUCKY BOURBON EDITION"
#define HEAD2  "REDNECK RAMPAGE RIDES AGAIN(tm) "VERSION" - KENTUCKY BOURBON EDITION"
#else
#define VERSION "REL 1.01"
#define HEAD   "REDNECK RAMPAGE(tm) "VERSION" - MOONSHINE"
#define HEAD2  "REDNECK RAMPAGE(tm) "VERSION" - MOONSHINE"
#endif

void comlinehelp(char **argv)
{
    printf("Command line help.  %s [/flags...]\n",argv[0]);
    puts(" ?, /?         This help message");
    puts(" /l##          Level (1-11)");
    puts(" /v#           Volume (1-4)");
    puts(" /v#           Volume (1-3)");
    puts(" /s#           Skill (1-4)");
    puts(" /r            Record demo");
    puts(" /dFILE        Start to play demo FILE");
    puts(" /m            No monsters");
    puts(" /ns           No sound");
    puts(" /nm           No music");
#ifdef RRRA
    puts(" /ni           No intro movie");
#endif
    puts(" /t#           Respawn, 1 = Monsters, 2 = Items, 3 = Inventory, x = All");
    puts(" /c#           MP mode, 1 = Redneck Match(spawn), 2 = Coop, 3 = Redneckmatch(no spawn)");
    puts(" /q#           Fake multiplayer (2-8 players)");
    puts(" /a            Use player AI (fake multiplayer only)");
    puts(" /i#           Network mode (1/0) (multiplayer only)");
    puts(" /f#           Send fewer packets (1, 2, 4) (multiplayer only)");
    puts(" /gFILE        Use a groupfile FILE");
    puts(" /xFILE        Compile FILE (default GAME.CON)");
    puts(" /u#########   User's favorite weapon order (default: 3425689071)");
    puts(" /#            Load and run a game (slot 0-9)");
    puts(" -8250         8250 with modem play, force music OFF");
    puts(" -map FILE     Use a map FILE");
    puts(" -name NAME    Foward NAME");
  printf(" -net          Net mode game");
}

void checkcommandline(int argc,char **argv)
{
    short i, j;
    char *c;

    i = 1;

    ud.fta_on = 1;
    ud.god = 0;
    ud.m_respawn_items = 0;
    ud.m_respawn_monsters = 0;
    ud.m_respawn_inventory = 0;
    ud.warp_on = 0;
    ud.cashman = 0;
    ud.m_player_skill = ud.player_skill = 1;

    if(argc > 1)
    {
        while(i < argc)
        {
            c = argv[i];
            if(*c == '-')
            {
                if( *(c+1) == '8' ) eightytwofifty = 1;
                i++;
                continue;
            }

            if(*c == '?')
            {
                comlinehelp(argv);
                exit(0);
            }

            if(*c == '/')
            {
                c++;
                switch(*c)
                {
                    default:
  //                      printf("Unknown command line parameter '%s'\n",argv[i]);
                    case '?':
                        comlinehelp(argv);
                        exit(0);
                    case 'x':
                    case 'X':
                        c++;
                        if(*c)
                        {
                            strcpy(confilename,c);
                            if(SafeFileExists(c) == 0)
                            {
                                printf("Could not find con file '%s'.\n",confilename );
                                exit(0);
                            }
                            else printf("Using con file: '%s'\n",confilename);
                        }
                        break;
                    case 'g':
                    case 'G':
                        c++;
                        if(*c)
                        {
                            j = initgroupfile(c);
                            if( j == -1 )
                                printf("Could not find group file %s.\n",c);
                            else
                            {
                                groupfile = j;
                                printf("Using group file %s.\n",c);
                            }
                        }

                        break;
                    case 'a':
                    case 'A':
                        ud.playerai = 1;
                        break;
                    case 'n':
                    case 'N':
                        c++;
                        if(*c == 's' || *c == 'S')
                        {
                            CommandSoundToggleOff = 2;
                            puts("Sound off.");
                        }
                        else if(*c == 'm' || *c == 'M')
                        {
                            CommandMusicToggleOff = 1;
                            puts("Music off.");
                        }
#ifdef RRRA
                        else if(*c == 'i' || *c == 'I')
                        {
                            puts("Intro movie off.");
                        }
#endif
                        else
                        {
                            comlinehelp(argv);
                            exit(0);
                        }
                        break;
                    case 'i':
                    case 'I':
                        c++;
                        if(*c == '0') networkmode = 0;
                        if(*c == '1') networkmode = 1;
                        printf("Network Mode %d\n",networkmode);
                        break;
                    case 'c':
                    case 'C':
                        c++;
                        if(*c == '1' || *c == '2' || *c == '3' )
                            ud.m_coop = *c - '0' - 1;
                        else ud.m_coop = 0;

                        switch(ud.m_coop)
                        {
                            case 0:
                                puts("Redneckmatch (spawn).");
                                break;
                            case 1:
                                puts("Cooperative play.");
                                break;
                            case 2:
                                puts("Redneckmatch (no spawn).");
                                break;
                        }

                        break;
                    case 'f':
                    case 'F':
                        c++;
                        if(*c == '1')
                            movesperpacket = 1;
                        if(*c == '2')
                            movesperpacket = 2;
                        if(*c == '4')
                        {
                            movesperpacket = 4;
#ifndef RRRA
                            setpackettimeout(0x3fffffff,0x3fffffff);
#endif
                        }
                        break;
                    case 't':
                    case 'T':
                        c++;
                        if(*c == '1') ud.m_respawn_monsters = 1;
                        else if(*c == '2') ud.m_respawn_items = 1;
                        else if(*c == '3') ud.m_respawn_inventory = 1;
                        else
                        {
                            ud.m_respawn_monsters = 1;
                            ud.m_respawn_items = 1;
                            ud.m_respawn_inventory = 1;
                        }
                        puts("Respawn on.");
                        break;
                    case 'm':
                    case 'M':
                        if( *(c+1) != 'a' && *(c+1) != 'A' )
                        {
                            ud.m_monsters_off = 1;
                            ud.m_player_skill = ud.player_skill = 0;
                            puts("Monsters off.");
                        }
                        break;
                    case 'q':
                    case 'Q':
                        puts("Fake multi Mode.");
                        if( *(++c) == 0) ud.multimode = 1;
                        else ud.multimode = atol(c)%17;
                        ud.m_coop = ud.coop = 0;
                        ud.m_marker = ud.marker = 1;
                        ud.m_respawn_monsters = ud.respawn_monsters = 1;
                        ud.m_respawn_items = ud.respawn_items = 1;
                        ud.m_respawn_inventory = ud.respawn_inventory = 1;

                        break;
                    case 'r':
                    case 'R':
                        ud.m_recstat = 1;
                        puts("Demo record mode on.");
                        break;
                    case 'd':
                    case 'D':
                        c++;
                        printf("Start playing demo %s.\n",c);
                        strcpy(firstdemofile,c);
                        break;
                    case 'l':
                    case 'L':
                        ud.warp_on = 1;
                        c++;
                        ud.m_level_number = ud.level_number = (atol(c)-1)%7;
                        break;
                    case 'j':
                    case 'J':
                        printf("Redneck Ramage (FULL VERSION) v%s\n",VERSION);
                        exit(0);

                    case 'v':
                    case 'V':
                        c++;
                        ud.warp_on = 1;
                        ud.m_volume_number = ud.volume_number = atol(c)-1;
                        break;
                    case 's':
                    case 'S':
                        c++;
                        ud.m_player_skill = ud.player_skill = (atol(c)%5);
                        if(ud.m_player_skill == 4)
                            ud.m_respawn_monsters = ud.respawn_monsters = 1;
                        break;
                    case '0':
                    case '1':
                    case '2':
                    case '3':
                    case '4':
                    case '5':
                    case '6':
                    case '7':
                    case '8':
                    case '9':
                        ud.warp_on = 2 + (*c) - '0';
                        break;
                    case 'u':
                    case 'U':
                        c++;
                        j = 0;
                        if(*c)
                        {
                            puts("Using favorite weapon order(s).");
                            while(*c)
                            {
                                ud.wchoice[0][j] = *c-'0';
                                c++;
                                j++;
                            }
                            while(j < 10)
                            {
                                if(j == 9)
                                    ud.wchoice[0][9] = 1;
                                else
                                    ud.wchoice[0][j] = 2;

                                j++;
                            }
                        }
                        else
                        {
                            puts("Using default weapon orders.");
                            ud.wchoice[0][0] = 3;
                            ud.wchoice[0][1] = 4;
                            ud.wchoice[0][2] = 5;
                            ud.wchoice[0][3] = 7;
                            ud.wchoice[0][4] = 8;
                            ud.wchoice[0][5] = 6;
                            ud.wchoice[0][6] = 0;
                            ud.wchoice[0][7] = 2;
                            ud.wchoice[0][8] = 9;
                            ud.wchoice[0][9] = 1;
                        }

                        break;
                }
            }
            i++;
        }
    }
}

void printstr(short x, short y, char string[81], char attribute)
{
        char character;
        short i, pos;

        pos = (y*80+x)<<1;
        i = 0;
        while (string[i] != 0)
        {
                character = string[i];
                printchrasm(0xb8000+(long)pos,1L,((long)attribute<<8)+(long)character);
                i++;
                pos+=2;
        }
}

/*
void cacheicon(void)
{
    if(cachecount > 0)
    {
        if( (ps[myconnectindex].gm&MODE_MENU) == 0 )
            rotatesprite((320-7)<<16,(200-23)<<16,32768L,0,SPINNINGNUKEICON,0,0,2,windowx1,windowy1,windowx2,windowy2);
        cachecount = 0;
    }
}
       */

void Logo(void)
{
    short i,j,soundanm;

    soundanm = 0;

    ready2send = 0;

    KB_FlushKeyboardQueue();

    setview(0,0,xdim-1,ydim-1);
    clearview(0L);
    palto(0,0,0,63);

    flushperms();
    nextpage();

#ifdef RRRA
    if (numplayers == 1)
    {
        sub_86730(0);
        ps[screenpeek].fogtype = 0;
        if (!KB_KeyWaiting())
        {
            short temp;
            temp = 0;
            getpackets();
            if (ready2send)
                return;
            temp = playanm("1st.anm",5,1);
            if (temp != 10)
            {
                temp = playanm("2nd.anm",5,2);
                if (temp != 10)
                {
                    temp = playanm("3nd.anm",5,3);
                    if (temp != 10)
                    {
                        playanm("4nd.anm",5,4);
                    }
                }
            }
            palto(0,0,0,63);
            KB_FlushKeyboardQueue();
        }

        FX_StopAllSounds();
        clearsoundlocks();
        flushperms();
        clearview(0L);
        nextpage();

        if(!KB_KeyWaiting())
        {
            getpackets();
            if(ready2send)
                return;
            playanm("xatlogo.anm",5,6);
            palto(0,0,0,63);
            KB_FlushKeyboardQueue();
        }

        FX_StopAllSounds();
        clearsoundlocks();
        flushperms();
        clearview(0L);
        nextpage();

        if(!KB_KeyWaiting())
        {
            getpackets();
            if(ready2send)
                return;
            playanm("inter.anm",5,5);
            palto(0,0,0,63);
            KB_FlushKeyboardQueue();
        }
    }
#else
    if(!KB_KeyWaiting())
    {
        getpackets();
        if(ready2send)
            return;
        playanm("rr_intro.anm",5,-1);
        palto(0,0,0,63);
        KB_FlushKeyboardQueue();
    }

    FX_StopAllSounds();
    clearsoundlocks();
    flushperms();
    clearview(0L);
    nextpage();

    if(!KB_KeyWaiting())
    {
        getpackets();
        if(ready2send)
            return;
        playanm("redneck.anm",5,0);
        palto(0,0,0,63);
        KB_FlushKeyboardQueue();
    }

    FX_StopAllSounds();
    clearsoundlocks();
    flushperms();
    clearview(0L);
    nextpage();

    if(!KB_KeyWaiting())
    {
        getpackets();
        if(ready2send)
            return;
        playanm("xatlogo.anm",5,1);
        palto(0,0,0,63);
        KB_FlushKeyboardQueue();
    }
#endif

    FX_StopAllSounds();
    clearsoundlocks();
    flushperms();
    clearview(0L);
    nextpage();
    ps[myconnectindex].palette = (char *) &palette[0];

    if(numplayers > 1)
    {
        palto(0,0,0,0);
        menutext(160,100,0,0,"WAITIN' FER PLAYERS...");
    }

    clearview(0L);
}

void loadtmb(void)
{
    char tmb[8000];
    long fil, l;

    fil = kopen4load("d3dtimbr.tmb",loadfromgrouponly);
    if(fil == -1) return;
    l = kfilelength(fil);
    kread(fil,(char *)tmb,l);
    MUSIC_RegisterTimbreBank(tmb);
    kclose(fil);
}

/*
===================
=
= ShutDown
=
===================
*/

void Shutdown( void )
{
    SoundShutdown();
    MusicShutdown();
    uninittimer();
#ifdef RRRA
    if (numplayers == 1 && playerswhenstarted == 1)
#endif
    uninitengine();
    CONTROL_Shutdown();
    CONFIG_WriteSetup();
#ifndef RRRA
    KB_Shutdown();
#endif
}

#ifdef RRRA
char todd[] = "Redneck Ramage Rides Again(tm) Copyright 1997 Xatrix Entertainment";
#else
char todd[] = "Redneck Ramage(tm) Copyright 1996 Xatrix Entertainment";
#endif
char trees[] = "I want to make a game with trees";
char sixteen[] = "16 Possible Rednecks";

/*
===================
=
= Startup
=
===================
*/

void compilecons(void)
{
   mymembuf = (char *)&hittype[0];
   labelcode = (long *)&sector[0];
   label = (char *)&sprite[0];

//   printf("%ld %ld %ld\n",sizeof(hittype),sizeof(sector),sizeof(sprite));
//   exit(0);

   loadefs(confilename,mymembuf);
   if( loadfromgrouponly )
   {
       printf("  * Writing defaults to current directory.\n");
       loadefs(confilename,mymembuf);
   }
}

void Startup(void)
{
   int i;

   KB_Startup();

   compilecons();

#ifndef RRRA
   CONFIG_GetSetupFilename();
   CONFIG_ReadSetup();
#endif

   if(CommandSoundToggleOff) SoundToggle = 0;
   if(CommandMusicToggleOff) MusicToggle = 0;

   CONTROL_Startup( ControllerType, &GetTime, TICRATE );

   initengine(ScreenMode,ScreenWidth,ScreenHeight);
   inittimer();

   puts("* Hold Esc to Abort. *");
   puts("Loading art header.");
   loadpics("tiles000.art");

   readsavenames();

   tilesizx[MIRROR] = tilesizy[MIRROR] = 0;

   for(i=0;i<MAXPLAYERS;i++) playerreadyflag[i] = 0;
   initmultiplayers(0,0,0);

   if(numplayers > 1)
    puts("Multiplayer initialized.");

   ps[myconnectindex].palette = (char *) &palette[0];
   SetupGameButtons();

   if(networkmode == 255)
   {
       if(numplayers > 1 && numplayers <= 4)
           networkmode = 1;
       else
           networkmode=0;
   }
   puts("Checking music inits.");
   MusicStartup();
   puts("Checking sound inits.");
   SoundStartup();
   loadtmb();
}

void sendscore(char *s)
{
    if(numplayers > 1)
#ifdef RRRA
      return;
#else
      genericmultifunction(-1,s,strlen(s)+1,5);
#endif
}

void getnames(void)
{
    short i,l;

    for(l=0;myname[l];l++)
    {
        ud.user_name[myconnectindex][l] = toupper(myname[l]);
        buf[l+2] = toupper(myname[l]);
    }

    if(numplayers > 1)
    {
        buf[0] = 6;
        buf[1] = BYTEVERSION;

        buf[l+2] = 0;
        l += 3;

        puts("Searching for other players.");
        waitforeverybody();

        for(i=connecthead;i>=0;i=connectpoint2[i])
            if( i != myconnectindex )
                sendpacket(i,&buf[0],l);

        getpackets();

        l = 1;
        buf[0] = 9;

        for(i=0;i<10;i++)
        {
            ud.wchoice[myconnectindex][i] = ud.wchoice[0][i];
            buf[l] = (char) ud.wchoice[0][i];
            l++;
        }

        for(i=connecthead;i>=0;i=connectpoint2[i])
            if(i != myconnectindex)
                sendpacket(i,&buf[0],l);

        getpackets();

        buf[0] = 10;
        buf[1] = ps[0].aim_mode;
        ps[myconnectindex].aim_mode = ps[0].aim_mode;

        for(i=connecthead;i>=0;i=connectpoint2[i])
            if(i != myconnectindex)
                sendpacket(i,buf,2);

        getpackets();
    }
}