Mercurial > ~darius > hgwebdir.cgi > paradise_client
changeset 3:5a977ccbc7a9 default tip
Empty changelog
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/defs.h Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,415 @@ +/* $Id: defs.h,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +/* + * defs.h + */ + +#ifndef defs_h_ +#define defs_h_ + +#include "copyright.h" + +#define MAX_PLAYER 257 /* Maximum number of players we can configure + the game for, not the server's max + players. */ + +#ifdef HOCKEY +/* defs for hockey [BDyess] */ +#define NUM_HOCKEY_LINES 13 +#endif /*HOCKEY*/ + +#ifdef SIZE_LOGGING +/* redefine EXIT as print totals followed by a normal exit [BDyess] */ +#define EXIT(x) {print_totals();exit(x);} +#else +#define EXIT exit +#endif /* SIZE_LOGGING */ + +/* defs for new message window data structure [BDyess] */ +#define WREVIEW 0 +#define WTEAM 1 +#define WINDIV 2 +#define WKILL 3 +#define WPHASER 4 +#define WALL 5 +#define WNUM 6 +/* message window allow mask */ +#define WA_TEAM 1 +#define WA_INDIV 2 +#define WA_KILL 4 +#define WA_PHASER 8 +#define WA_ALL 16 +#define WA_REVIEW 32 +#define WA_MACRO 64 + +/* defs for updatePlayer [BDyess] */ +#define NO_UPDATE 0 +#define SMALL_UPDATE 1 /* update non-blk_bozo players */ +#define LARGE_UPDATE 2 /* update blk_bozo players */ +#define ALL_UPDATE (SMALL_UPDATE|LARGE_UPDATE) /* update both */ + +/* defs for terrain */ +#define TERRAIN_STARTED 1 +#define TERRAIN_DONE 2 + +/* defs for timer [BDyess] */ +#define T_NONE 0 /* no timer */ +#define T_DAY 1 /* time of day */ +#define T_SERVER 2 /* time on server */ +#define T_SHIP 3 /* time in ship */ +#define T_USR 4 /* user reset timer */ +#define T_TOTAL 5 /* number of T_ defs */ +#define TIMESTRLEN 10 /* used in db_timer(), timeString() */ + /* */ + +/* defs for mapmode */ +#define GMAP_NEVER 0 +#define GMAP_FREQUENT 1 +#define GMAP_INFREQUENT 2 + +#ifdef METASERVER +/* metaserver window defs */ +#define LINE 80 +#define METASERVERADDRESS "metaserver.ecst.csuchico.edu" /* new metaserver */ +#define METAPORT 3521 /* HAVE to use nicely formated version */ +#define KEY 3 +#endif /* METASERVER */ + +#define MAX_PLANETS 257 + +#define WINSIDE 500 /* Size of strategic and tactical windows */ +#define BORDER 4 /* border width for option windows */ +#define PSEUDOSIZE 16 +#define CLOAK_PHASES 7 /* number of drawing phases in a cloak + engage/disengage */ +#define NUMRANKS 9 /* old netrek ranks */ +/*#define NUMRANKS2 18*/ + +/* These are configuration definitions */ + +#define GWIDTH 200000 /* galaxy is 200000 spaces on a side */ +#define WARP1 20 /* warp one will move 20 spaces per update */ +#define SCALE 40 /* Window will be one pixel for 20 spaces */ +#define EXPDIST 350 /* At this range a torp will explode */ +#define GRIDSIZE 33333 + +#define DETDIST 1600 /* At this range a player can detonate a torp */ + +#define PHASEDIST 6000 /* At this range a player can do damage with + phasers */ +#define ENTORBDIST 900 /* At this range a player can orbit a planet */ +#define ORBDIST 800 /* A player will orbit at this radius */ +#define ORBSPEED 2 /* This is the fastest a person can go into + orbit */ +#define PFIREDIST 1500 /* At this range a planet will shoot at a + player */ +#define UPDATE 100000 /* Update time is 100000 micro-seconds */ + +#define AUTOQUIT 60 /* auto logout in 60 secs */ + +#define VACANT -1 /* indicates vacant port on a starbase */ +#define DOCKDIST 600 +#define DOCKSPEED 2 /* If base is moving, there will be some + finesse involved to dock */ +#define NUMPORTS 4 +#define SBFUELMIN 10000 /* If starbase's fuel is less than this, it + will not refuel docked vessels */ +#define TRACTDIST 6000 /* maximum effective tractor beam range */ +#define TRACTEHEAT 5 /* ammount tractor beams heat engines */ +#define TRACTCOST 20 /* fuel cost of activated tractor beam */ + +/* These are memory sections */ +#define PLAYER 1 +#define MAXMESSAGE 50 +#define MAXREVIEWMESSAGE 20 + +#ifdef SVR4 +#define MCOPY(b1,b2,l) memcpy(b2,b1,l) +#else +#define MCOPY(b1,b2,l) bcopy(b1,b2,l) +#endif +#define rosette(x, ndiv) (( (((x)&0xff) + 0x100/(2*(ndiv))) * (ndiv)/0x100 ) % ndiv) + +/* These are the teams */ +/* Note that I used bit types for these mostly for messages and + war status. This was probably a mistake. It meant that Ed + had to add the 'remap' area to map these (which are used throughout + the code as the proper team variable) into a nice four team deep + array for his color stuff. Oh well. +*/ +#define NOBODY 0x0 +#define FEDi 0 +#define ROMi 1 +#define KLIi 2 +#define ORIi 3 + /* #define ALLTEAMi 4 *//* replaced by number_of_teams */ +#define FEDm 0x1 +#define ROMm 0x2 +#define KLIm 0x4 +#define ORIm 0x8 +#define ALLTEAM ( (1<<number_of_teams) - 1) + /*#define MAXTEAM 3 *//* number_of_teams -1 */ + /*#define NUMTEAM 4 *//* number_of_teams */ +/* +** These are random configuration variables +*/ +#define VICTORY 3 /* Number of systems needed to conquer the + galaxy */ +#define WARNTIME 30 /* Number of updates to have a warning on the + screen */ +#define MESSTIME 30 /* Number of updates to have a message on the + screen */ + +/* Flags for gettarget */ +#define TARG_SHIP (1<<0) +#define TARG_BASE (1<<1) +#define TARG_PLANET (1<<2) +#define TARG_CLOAK (1<<3) /* Include cloaked ships in search */ +#define TARG_SELF (1<<4) +#define TARG_ENEMY (1<<5) /* enemy ships/planets only */ +#define TARG_FRIENDLY (1<<6) /* friendly ships/planets only */ +#define TARG_TEAM (1<<7) /* same team */ +#define TARG_STAR (1<<8) +#define TARG_NEBULA (1<<9) +#define TARG_BLACKHOLE (1<<10) + +#define TARG_PLAYER (TARG_SHIP|TARG_BASE) +#define TARG_ASTRAL (TARG_PLANET|TARG_STAR|TARG_NEBULA|TARG_BLACKHOLE) + +#define DEFAULT_SERVER "cassius.cs.uiuc.edu" +#define DEFAULT_PORT 2592 + +#define hypot(x,y) sqrt((x)*(x)+(y)*(y)) + +#define ABS(a) /* abs(a) */ (((a) < 0) ? -(a) : (a)) +#ifndef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +#define myPlasmaTorp(t) (me->p_no == (t)->pt_owner) +#define myTorp(t) (me->p_no == (t)->t_owner) +#define friendlyPlasmaTorp(t) ((!(idx_to_mask(me->p_teami) & (t)->pt_war)) || (myPlasmaTorp(t))) +#define friendlyTorp(t) ((!(idx_to_mask(me->p_teami) & (t)->t_war)) || (myTorp(t))) +#define myPhaser(p) (&phasers[me->p_no] == (p)) +#define friendlyPhaser(p) (me->p_teami == players[(p) - phasers].p_teami) +#define myPlayer(p) (me == (p)) +#define myPlanet(p) (me->p_teami == mask_to_idx((p)->pl_owner)) +#define friendlyPlayer(p) ((!(idx_to_mask(me->p_teami) & \ + ((p)->p_swar | (p)->p_hostile))) && \ + (!(idx_to_mask((p)->p_teami) & \ + (me->p_swar | me->p_hostile)))) +#define isAlive(p) ((p)->p_status == PALIVE) +#define isPlaying(p) ((p)->p_status != PFREE) +#define isBase(num) ((num)==STARBASE || (num)==WARBASE || \ + (num)==JUMPSHIP) +#define friendlyPlanet(p) ((p)->pl_info & idx_to_mask(me->p_teami) && \ + !((p)->pl_owner & (me->p_swar | me->p_hostile))) + +#define isLockPlanet(p) ((me->p_flags & PFPLLOCK) && (me->p_planet == p->pl_no)) +#define isLockPlayer(p) ((me->p_flags & PFPLOCK) && (me->p_playerl == p->p_no)) +#define PtOutsideWin(x, y) (x < 0 || x > WINSIDE || y < 0 || y > WINSIDE) /* TSH */ + +#define torpColor(t) \ + (myTorp(t) ? myColor : shipCol[1+players[(t)->t_owner].p_teami]) +#define droneColor(t) \ + (myTorp(t) ? myColor : shipCol[1+players[(t)->t_owner].p_teami]) +#define plasmatorpColor(t) \ + (myPlasmaTorp(t) ? myColor : shipCol[1+players[(t)->pt_owner].p_teami]) +#define phaserColor(p) \ + (myPhaser(p) ? myColor : shipCol[1+players[(p) - phasers].p_teami]) +/* + * Cloaking phase (and not the cloaking flag) is the factor in determining + * the color of the ship. Color 0 is white (same as 'myColor' used to be). + */ +#define playerColor(p) \ + (myPlayer(p) ? myColor : shipCol[1+(p)->p_teami]) +#define planetColor(p) \ + (((p)->pl_info & idx_to_mask(me->p_teami)) ? shipCol[1+mask_to_idx((p)->pl_owner)] : unColor) + +#define planetFont(p) \ + (myPlanet(p) ? W_BoldFont : friendlyPlanet(p) ? W_UnderlineFont \ + : W_RegularFont) +#define shipFont(p) \ + (myPlayer(p) ? W_BoldFont : friendlyPlayer(p) ? W_UnderlineFont \ + : W_RegularFont) +#define bombingRating(p) \ + ((float) (p)->p_stats.st_tarmsbomb * status->timeprod / \ + ((float) (p)->p_stats.st_tticks * status->armsbomb)) +#define planetRating(p) \ + ((float) (p)->p_stats.st_tplanets * status->timeprod / \ + ((float) (p)->p_stats.st_tticks * status->planets)) +#define offenseRating(p) \ + ((float) (p)->p_stats.st_tkills * status->timeprod / \ + ((float) (p)->p_stats.st_tticks * status->kills)) +#define defenseRating(p) \ + ((float) (p)->p_stats.st_tticks * status->losses / \ + ((p)->p_stats.st_tlosses!=0 ? \ + ((float) (p)->p_stats.st_tlosses * status->timeprod) : \ + (status->timeprod))) + +#ifdef SVR4 /* to get it to work under Solaris */ +#define srandom srand48 +#define bcopy(s,d,l) memmove((d),(s),(l)) +#define bzero(s,l) memset((s),(char)0,(l)) +#define random lrand48 +#define rindex(s,c) strrchr((s),(c)) +#endif /* SVR4 */ + +#ifdef ROTATERACE +#define sendTorpReq(dir) sendShortPacket(CP_TORP, RotateDirSend(dir)) +#define sendPhaserReq(dir) sendShortPacket(CP_PHASER, RotateDirSend(dir)) +#define sendDirReq(dir) sendShortPacket(CP_DIRECTION, RotateDirSend(dir)) +#define sendPlasmaReq(dir) sendShortPacket(CP_PLASMA, RotateDirSend(dir)) +#else +#define sendTorpReq(dir) sendShortPacket(CP_TORP, dir) +#define sendPhaserReq(dir) sendShortPacket(CP_PHASER, dir) +#define sendDirReq(dir) sendShortPacket(CP_DIRECTION, dir) +#define sendPlasmaReq(dir) sendShortPacket(CP_PLASMA, dir) +#endif /* ROTATERACE */ + +#define sendSpeedReq(speed) sendShortPacket(CP_SPEED, speed) +#define sendShieldReq(state) sendShortPacket(CP_SHIELD, state) +#define sendOrbitReq(state) sendShortPacket(CP_ORBIT, state) +#define sendRepairReq(state) sendShortPacket(CP_REPAIR, state) +#define sendBeamReq(state) sendShortPacket(CP_BEAM, state) +#define sendCopilotReq(state) sendShortPacket(CP_COPILOT, state) +#define sendDetonateReq() sendShortPacket(CP_DET_TORPS, 0) +#define sendCloakReq(state) sendShortPacket(CP_CLOAK, state) +#define sendBombReq(state) sendShortPacket(CP_BOMB, state) +#define sendPractrReq() sendShortPacket(CP_PRACTR, 0) +#define sendWarReq(mask) sendShortPacket(CP_WAR, mask) +#define sendRefitReq(ship) sendShortPacket(CP_REFIT, ship) +#define sendPlaylockReq(pnum) sendShortPacket(CP_PLAYLOCK, pnum) +#define sendPlanlockReq(pnum) sendShortPacket(CP_PLANLOCK, pnum) +#define sendCoupReq() sendShortPacket(CP_COUP, 0) +#define sendQuitReq() sendShortPacket(CP_QUIT, 0) +#define sendByeReq() sendShortPacket(CP_BYE, 0) +#define sendDockingReq(state) sendShortPacket(CP_DOCKPERM, state) +#define sendResetStatsReq(verify) sendShortPacket(CP_RESETSTATS, verify) +#ifdef ATM +#define sendScanReq(who) sendShortPacket(CP_SCAN, who) /* ATM */ +#endif /* ATM */ + +/* This macro allows us to time things based upon # frames / sec. + */ +#define ticks(x) ((x)*200000/timerDelay) + +char *getdefault(); + +#ifdef ATM +/* + * UDP control stuff + */ +#ifdef GATEWAY +#define UDP_NUMOPTS 11 +#define UDP_GW UDP_NUMOPTS-1 +#else +#define UDP_NUMOPTS 10 +#endif +#define UDP_CURRENT 0 +#define UDP_STATUS 1 +#define UDP_DROPPED 2 +#define UDP_SEQUENCE 3 +#define UDP_SEND 4 +#define UDP_RECV 5 +#define UDP_DEBUG 6 +#define UDP_FORCE_RESET 7 +#define UDP_UPDATE_ALL 8 +#define UDP_DONE 9 +#define COMM_TCP 0 +#define COMM_UDP 1 +#define COMM_VERIFY 2 +#define COMM_UPDATE 3 +#define COMM_MODE 4 +#define SWITCH_TCP_OK 0 +#define SWITCH_UDP_OK 1 +#define SWITCH_DENIED 2 +#define SWITCH_VERIFY 3 +#define CONNMODE_PORT 0 +#define CONNMODE_PACKET 1 +#define STAT_CONNECTED 0 +#define STAT_SWITCH_UDP 1 +#define STAT_SWITCH_TCP 2 +#define STAT_VERIFY_UDP 3 +#define MODE_TCP 0 +#define MODE_SIMPLE 1 +#define MODE_FAT 2 +#define MODE_DOUBLE 3 + +#define UDP_RECENT_INTR 300 +#define UDP_UPDATE_WAIT 5 + +/* client version of UDPDIAG */ +#define UDPDIAG(x) { if (udpDebug) { printf("UDP: "); printf x; }} +#define V_UDPDIAG(x) UDPDIAG(x) +#endif /* ATM */ + +#define RSA_VERSION "RSA v2.0 CLIENT" /* string must begin with characters + "RSA v" */ +#define KEY_SIZE 32 +#define RESERVED_SIZE 16 +#define MSG_LEN 80 +#define NAME_LEN 16 +#define KEYMAP_LEN 96 + +#ifdef ROTATERACE +#define RotateDirSend(d) (rotate?d-rotate_deg:d) +#endif + +#ifdef SHORT_PACKETS +#define SPK_VOFF 0 /* variable packets off */ +#define SPK_VON 1 /* variable packets on */ +#define SPK_MOFF 2 /* message packets off */ +#define SPK_MON 3 /* message packets on */ +#define SPK_M_KILLS 4 /* send kill mesgs */ +#define SPK_M_NOKILLS 5 /* don't send kill mesgs */ +#define SPK_THRESHOLD 6 /* threshold */ +#define SPK_M_WARN 7 /* warnings */ +#define SPK_M_NOWARN 8 /* no warnings */ +#define SPK_SALL 9 /* only planets,kills and weapons */ +#define SPK_ALL 10 /* Full Update - SP_STATS */ + +#define SPK_NUMFIELDS 7 + +#define SPK_VFIELD 0 +#define SPK_MFIELD 1 +#define SPK_KFIELD 2 +#define SPK_WFIELD 3 +#define SPK_TFIELD 4 +#define SPK_WHYFIELD 5 +#define SPK_DONE 6 +#endif + +#ifdef TOOLS +#define TOOLSWINLEN 25 +#endif + +#ifdef BEEPLITE +#define LITE_PLAYERS_MAP 0x01 +#define LITE_PLAYERS_LOCAL 0x02 +#define LITE_SELF 0x04 +#define LITE_PLANETS 0x08 +#define LITE_SOUNDS 0x10 +#define LITE_COLOR 0x20 +#endif + +#ifdef AMIGA +#include "amigadefs.h" +#else +#define sock_write write +#define sock_close close +#define sock_ioctl ioctl +#endif /* AMIGA */ + +#ifdef RECORDER +#define PB_REDALERT -1 +#define PB_YELLOWALERT -2 +#define PB_DEATH -3 +#endif + +#if defined (sgi) || defined (__FreeBSD__) || defined (__NetBSD__) +#define strcmpi strcasecmp +#define strncmpi strncasecmp +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/defwin.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,1023 @@ +/* $Id: defwin.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +#ifdef XTREKRC_HELP +/* + * taken from helpwin.c + * (copyright 1991 ERic mehlhaff Free to use, hack, etc. Just keep + * these credits here. Use of this code may be dangerous to your health + * and/or system. Its use is at your own risk. I assume no responsibility for + * damages, real, potential, or imagined, resulting from the use of it.) + * + */ + +#include <stdio.h> +#include "math.h" +#include <signal.h> +#include <sys/types.h> +#ifdef hpux +#include <time.h> +#else /* hpux */ +#include <sys/time.h> +#endif /* hpux */ +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "proto.h" +#include "data.h" +#ifndef SVR4 +#include <strings.h> +#else +#include <string.h> +#endif + +void def_write +P((char *file)); + +/* this is the number of help messages there are */ + +#define INT_DEF 0 +#define BOOL_DEF 1 +#define STR_DEF 2 +#define SINT_DEF 3 + +#define NAME_WIDTH 18 +#define VAL_WIDTH 8 +#define INDENT 3 +#define MAX_VLINES 58 + +extern int updateSpeed; +#ifdef RECORD +extern char *recordFileName; +#endif + +#define DEFMESSAGES (sizeof(def_messages)/ sizeof(struct def)) + +char *name = NULL, *cloak_chars = NULL, *bmap = NULL, *keymap = NULL, *plist = NULL, *log_file = NULL, *saveFileName = NULL; +int galacticFrequent; + +/* sure its a mess, but it gets the job done */ + +static +struct def { + char *name; + int type; + char *desc; + void *variable; + + struct { + int i_value; /* if int or bool */ + char *s_value; /* if str */ + char *desc; + } values[10]; + + struct { /* the area of the window this def takes up */ + int x, y, rt, bot; + } loc; +} def_messages[] = { + +#ifdef AUTHORIZE + { + "useRSA", BOOL_DEF, "Use RSA checking", + &RSA_Client, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, +#endif + { + "showStats", BOOL_DEF, "Show stats window", + &showStats, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, + { + "showShields", BOOL_DEF, "Show shields around ship", + &showShields, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, + { + "keepPeace", BOOL_DEF, "Stay peaceful when reborn", + &keeppeace, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, + { + "reportKills", BOOL_DEF, "Report kill messages", + &reportKills, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, +#if 0 + { + "altBitmaps", BOOL_DEF, "Use alternate ship bitmaps", + &blk_altbits, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, +#endif + { + "showStars", BOOL_DEF, "Show star background on tactical", + &blk_showStars, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, + { + "showMySpeed", BOOL_DEF, "Show speed next to ship", + &showMySpeed, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, + { + "showTractorPressor", BOOL_DEF, "Show my tract/press", + &showTractorPressor, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, + { + "showLock", INT_DEF, "Lock display for planets/players", + &showLock, + { + { + 0, NULL, "don't show lock" + }, + { + 1, NULL, "show lock on galactic only" + }, + { + 2, NULL, "show lock on tactical only" + }, + { + 3, NULL, "show lock on both" + }, + { + 0, NULL, NULL + }, + } + }, + { + "showGrid", BOOL_DEF, "Show grid on galactic", + &drawgrid, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, + { + "Dashboard", INT_DEF, "Type of dashboard to use", + &Dashboard, + { + { + 0, NULL, "text based dashboard" + }, + { + 1, NULL, "new dashboard" + }, + { + 2, NULL, "color dashboard" + }, + { + 3, NULL, "Rainbow Dashboard" + }, + { + 0, NULL, NULL + }, + } + }, + { + "cloakChars", STR_DEF, "Cloak chars for map", + &(cloak_chars), + { + { + 0, NULL, NULL + }, + }, + }, + { + "logging", BOOL_DEF, "Use message logging", + &logmess, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, + { + "logFile", STR_DEF, "File to use for message logging", + &(log_file), + { + { + 0, NULL, NULL + }, + }, + }, +#ifdef VARY_HULL + { + "warnHull", BOOL_DEF, "Warn hull state based on damage", + &vary_hull, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, +#endif + { + "warpStreaks", BOOL_DEF, "Streak stars when entering warp", + &warpStreaks, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, + { + "useMsgw", BOOL_DEF, "Use message window", + &use_msgw, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, + { + "showShieldDam", BOOL_DEF, "Vary shields based on damage", + &show_shield_dam, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, + { + "updatesPerSec", SINT_DEF, "No. of updates from server per sec", + &updateSpeed, + { + { + 0, NULL, NULL + }, + }, + }, + { + "redrawDelay", SINT_DEF, "Minimum time between redraws (x/10 sec)", + &redrawDelay, + { + { + 0, NULL, NULL + }, + }, + }, + { + "extraAlertBorder", BOOL_DEF, "Show alert on local border", + &extraBorder, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, + { + "galacticFrequent", BOOL_DEF, "Update galactic map frequently", + &galacticFrequent, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, +#ifdef CONTINUOUS_MOUSE + { + "continuousMouse", BOOL_DEF, "Continuous mouse input", + &continuousMouse, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, +#endif + { + "tryUdp", BOOL_DEF, "Try UDP automatically", + &tryUdp, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, + { + "udpClientReceive", INT_DEF, "UDP receive mode", + &udpClientRecv, + { + { + 0, NULL, "TCP only" + }, + { + 1, NULL, "simple UDP" + }, + { + 2, NULL, "fat UDP" + }, + { + 3, NULL, "double UDP (obsolete)" + }, + { + 0, NULL, NULL + }, + }, + }, + { + "udpClientSend", INT_DEF, "UDP send mode", + &udpClientSend, + { + { + 0, NULL, "TCP only" + }, + { + 1, NULL, "simple UDP" + }, + { + 2, NULL, "enforced UDP (state only)" + }, + { + 3, NULL, "enforced UDP (state & weapon)" + }, + { + 0, NULL, NULL + }, + }, + }, + { + "udpSequenceCheck", BOOL_DEF, "UDP sequence checking", + &udpSequenceChk, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, + { + "sortPlayers", BOOL_DEF, "Sort playerlist by teams", + &sortPlayers, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, + { + "robsort", BOOL_DEF, "Put enemies on left in sorted playerlist", + &robsort, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, + { + "hideNoKills", BOOL_DEF, "Replace 0.00 kills with spaces", + &hideNoKills, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, + { + "showDead", BOOL_DEF, "Show dead in playerlist", + &showDead, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, + { + "showPreLogins", BOOL_DEF, "Show pre-logins in playerlist", + &showPreLogins, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, + { + "sortOutfitting", BOOL_DEF, "Sort outfitting ('--') to bottom", + &sortOutfitting, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, + { + "timerType", INT_DEF, "Type of timer to use", + &timerType, + { + { + 0, NULL, "no timer" + }, + { + 1, NULL, "time of day" + }, + { + 2, NULL, "time on server" + }, + { + 3, NULL, "time in ship" + }, + { + 4, NULL, "user set timer" + }, + { + 0, NULL, NULL + }, + }, + }, + { + "showGalactic", INT_DEF, "Galactic planet bitmaps", + &showgalactic, + { + { + 0, NULL, "show nothing on galactic map" + }, + { + 1, NULL, "show facilities on galactic map" + }, + { + 2, NULL, "show owner on galactic map" + }, + { + 3, NULL, "show surface properties on galactic map" + }, + { + 4, NULL, "show scout info age on galactic map" + }, + { + 5, NULL, "show MOO facilities on galactic map" + }, + { + 0, NULL, NULL + }, + }, + }, + { + "showLocal", INT_DEF, "Local planet bitmaps", + &showlocal, + { + { + 0, NULL, "show nothing on local map" + }, + { + 1, NULL, "show facilities on local map" + }, + { + 2, NULL, "show owner on local map" + }, + { + 3, NULL, "show surface properties on local map" + }, + { + 4, NULL, "show MOO facilities" + }, + { + 0, NULL, NULL + }, + }, + }, + { + "name", STR_DEF, "Default player name", + &(name), + { + { + 0, NULL, NULL + }, + }, + }, + { + "keymap", STR_DEF, "Keyboard map", + &(keymap), + { + { + 0, NULL, NULL + }, + }, + }, + { + "buttonmap", STR_DEF, "Mouse button map", + &(bmap), + { + { + 0, NULL, NULL + }, + }, + }, + { + "nameMode", BOOL_DEF, "Show names on map/local", + &namemode, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, +#ifdef SHORT_PACKETS + { + "tryShort", BOOL_DEF, "Try SHORT-PACKETS at startup", + &tryShort, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, +#endif +#ifdef IGNORE_SIGNALS_SEGV_BUS + { + "ignoreSignals", BOOL_DEF, "Ignore SIGSEGV and SIGBUS", + &ignore_signals, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, +#endif +#ifdef SHIFTED_MOUSE + { + "shiftedMouse", BOOL_DEF, "More mouse buttons with shift", + &extended_mouse, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, +#endif +#ifdef BEEPLITE + { + "UseLite", BOOL_DEF, "Use message highliting", + &UseLite, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, + { + "DefLite", BOOL_DEF, "Use default lites", + &DefLite, + { + { + 0, NULL, "" + }, + { + 0, NULL, NULL + }, + }, + }, +#endif + { + "saveFileName", STR_DEF, "Name to save defaults as(click here)", + &(saveFileName), + { + { + 0, NULL, NULL + }, + }, + }, +}; + +char * +itos(v) + int v; +{ + static char value[10]; + sprintf(value, "%d", v); + return value; +} + +char * +btoa(v) + int v; +{ + if (v) + return "on"; + else + return "off"; +} + +static void +def_redraw(d) + struct def *d; +{ + int xo = d->loc.x, yo = d->loc.y; + int x, y, j; + char *val; + W_Color col; + + x = xo; + y = yo; + + W_ClearArea(defWin, d->loc.x, d->loc.y, d->loc.rt - d->loc.x, d->loc.bot - d->loc.y); + + W_WriteText(defWin, x, y, W_Yellow, d->name, strlen(d->name), + W_RegularFont); + x += NAME_WIDTH; + + W_WriteText(defWin, x, y, textColor, d->desc, strlen(d->desc), + W_RegularFont); + y++; + x = xo + INDENT; + + if (d->type != STR_DEF) { + if (!d->values[0].desc && d->variable) { + if (d->type == SINT_DEF) + val = itos(*(int *)d->variable); + else + val = itos(d->values[0].i_value); + + W_WriteText(defWin, x, y, W_Green, val, strlen(val), + W_RegularFont); + y++; + } + for (j = 0; d->values[j].desc; j++) { + switch (d->type) { + case INT_DEF: + val = itos(d->values[j].i_value); + if (d->values[j].i_value == *(int *)d->variable) { + col = W_Green; + + W_WriteText(defWin, x, y, col, val, strlen(val), + W_RegularFont); + if (W_Mono()) { + W_WriteText(defWin, x + 1, y, col, "*", 1, + W_RegularFont); + } + } else { + col = textColor; + + W_WriteText(defWin, x, y, col, val, strlen(val), + W_RegularFont); + } + x = xo + NAME_WIDTH; + W_WriteText(defWin, x, y, col, d->values[j].desc, + strlen(d->values[j].desc), W_RegularFont); + y++; + x = xo + INDENT; + break; + + case BOOL_DEF: + val = btoa(*(int *)d->variable); + W_WriteText(defWin, x, y, W_Green, val, strlen(val), + W_RegularFont); + y++; + x = xo + INDENT; + break; + default: + fprintf(stderr, "Unknown type.\n"); + break; + } + } + } else if (d->variable && *(int *)d->variable) { + W_WriteText(defWin, x, y, W_Green, (char *)*(int *)d->variable, + strlen((char *)(*(int *)d->variable)), + W_RegularFont); + } +} + + +void +showdef() +{ + register i, j, x = 0, y = 0, xo = 0, yo = 0, max_desc = 0, height = 1, width = 1; + register struct def *d; + char *val; + W_Color col; + + name = getdefault("name"); + keymap = getdefault("keymap"); +/* plist = getdefault ("playerlist");*/ + cloak_chars = cloakchars; + bmap = getdefault("buttonmap"); + log_file = getdefault("logfile"); + galacticFrequent = (mapmode == 2) ? 0 : 1; + if (!saveFileName) { + saveFileName = stringDefault("saveFileName", "~/.paradisesaverc"); + saveFileName = expandFilename(saveFileName); + } + if (!defWin) + defWin = W_MakeTextWindow("xtrekrc_help", 1, 100, 174, 60, NULL, NULL, BORDER); + + for (i = 0, d = def_messages; i < DEFMESSAGES; i++, d++) { + x = xo; + y = yo; + + d->loc.x = x; + d->loc.y = y; + + W_WriteText(defWin, x, y, W_Yellow, d->name, strlen(d->name), + W_RegularFont); + x += NAME_WIDTH; + + W_WriteText(defWin, x, y, textColor, d->desc, strlen(d->desc), + W_RegularFont); + if ((int)strlen(d->desc) > max_desc) { + max_desc = strlen(d->desc); + width = MAX(width, x + max_desc); + } + y++; + x = xo + INDENT; + + if (d->type != STR_DEF) { + if (!d->values[0].desc && d->variable) { + if (d->type == SINT_DEF) + val = itos(*(int *)d->variable); + else + val = itos(d->values[0].i_value); + + W_WriteText(defWin, x, y, W_Green, val, strlen(val), + W_RegularFont); + y++; + } + for (j = 0; d->values[j].desc; j++) { + switch (d->type) { + case INT_DEF: + val = itos(d->values[j].i_value); + if (d->values[j].i_value == *(int *)d->variable) { + col = W_Green; + + W_WriteText(defWin, x, y, col, val, strlen(val), + W_RegularFont); + if (W_Mono()) { + W_WriteText(defWin, x + 1, y, col, "*", 1, + W_RegularFont); + } + } else { + col = textColor; + + W_WriteText(defWin, x, y, col, val, strlen(val), + W_RegularFont); + } + x = xo + NAME_WIDTH; + W_WriteText(defWin, x, y, col, d->values[j].desc, + strlen(d->values[j].desc), W_RegularFont); + y++; + x = xo + INDENT; + break; + + case BOOL_DEF: + val = btoa(*(int *)d->variable); + W_WriteText(defWin, x, y, W_Green, val, strlen(val), + W_RegularFont); + y++; + x = xo + INDENT; + break; + default: + fprintf(stderr, "Unknown type.\n"); + break; + } + } + } else if (d->variable && *(int *)d->variable) { + W_WriteText(defWin, x, y, W_Green, (char *)*(int *)d->variable, + strlen((char *)(*(int *)d->variable)), + W_RegularFont); + y++; + } + d->loc.rt = xo + max_desc; + d->loc.bot = y + 1; + + height = MAX(height, y); + if (y > MAX_VLINES) { + yo = 0; + xo += NAME_WIDTH + max_desc + 2; + max_desc = 0; + } else { + yo = y + 1; + } + } + + if (!W_IsMapped(defWin)) { + W_ResizeText(defWin, width, height); + W_MapWindow(defWin); + } +} + +void +def_action(ev) + W_Event *ev; +{ + int i, j, x, y, line; + register struct def *d; + char buf[100]; + + x = ev->x; + y = ev->y; + W_TranslatePoints(ev->Window, &x, &y); + + for (i = 0, d = def_messages; i < DEFMESSAGES; i++, d++) { + if (y >= d->loc.y && y < d->loc.bot && + x >= d->loc.x && x < d->loc.rt) + break; /* found it! */ + } + + if (i >= DEFMESSAGES) + return; + + line = y - d->loc.y; + + switch (ev->type) { + case W_EV_BUTTON: + switch (d->type) { + case BOOL_DEF: + *(int *)d->variable = !(*(int *)d->variable); + def_redraw(d); + break; + case INT_DEF: + case SINT_DEF: + if (line == 0 || d->type == SINT_DEF) { + switch (ev->key) { + case W_LBUTTON: + (*(int *)d->variable)++; + if (!(*(int *)d->values[*(int *)d->variable].desc)) + *(int *)d->variable = 0; + break; + case W_RBUTTON: + (*(int *)d->variable)--; + if (*(int *)d->variable < 0) { + for (j = 0; d->values[j].desc; j++) + /* empty */ ; + *(int *)d->variable = j - 1; + } + break; + case W_MBUTTON: + *(int *)d->variable = 0; + break; + default: + break; + } + } else if (y < d->loc.bot) + *(int *)d->variable = line - 1; + def_redraw(d); + break; + case STR_DEF: + if (d->variable == &saveFileName) + def_write(saveFileName); + break; + default: + break; + } + } +} + +void +def_write(file) + char *file; +{ + int i; + struct def *d; + FILE *f; + + f = fopen(file, "w"); + + + for (i = 0, d = def_messages; i < DEFMESSAGES; i++, d++) { + switch (d->type) { + case INT_DEF: + case SINT_DEF: + fprintf(f, "%s: %d\n", d->name, *(int *)d->variable); + break; + case BOOL_DEF: + fprintf(f, "%s: %s\n", d->name, (*(int *)d->variable ? "on" : "off")); + break; + case STR_DEF: + fprintf(f, "%s: %s\n", d->name, (char *)*(int *)d->variable); + break; + } + } + + fclose(f); +} + + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/detonate.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,34 @@ +/* $Id: detonate.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +/* + * detonate.c + */ +#include "copyright.h" + +#include <stdio.h> +#include <sys/types.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "proto.h" + +/* Detonate torp */ + +void +detmine() +{ + if (paradise) { + sendDetMineReq(-1); + } else { + register int i; + + for (i = 0; i < ntorps; i++) { + int j = i + me->p_no * ntorps; + if (torps[j].t_status == TMOVE || + torps[j].t_status == TSTRAIGHT) { + sendDetMineReq(j); + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/distress.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,870 @@ +/* $Id: distress.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +/* + * distress.c + */ +#include "copyright.h" + +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <ctype.h> +#include <string.h> +#ifndef SERVER +#include "Wlib.h" +#endif +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "gameconf.h" +#include "proto.h" + +/* #$!@$#% length of address field of messages */ +#define ADDRLEN 10 +#define MAXMACLEN 256 +#define MZERO bzero + + +/* + * The two in-line defs that follow enable us to avoid calling strcat over + * and over again. + */ +char *pappend; +#define APPEND(ptr,str) \ + pappend = str; \ + while(*pappend) \ + *ptr++ = *pappend++; + +#define APPEND_CAP(ptr,cap,str) \ + pappend = str; \ + while(*pappend) \ + { \ + *ptr++ = (cap ? toupper(*pappend) : *pappend); \ + pappend++; \ + } + +/* + * This is a hacked version from the K&R book. Basically it puts <n> into + * <s> in reverse and then reverses the string... + * MH. 10-18-93 + */ +int +itoa2(n, s) + int n; + char s[]; +{ + int i, c, j, len; + + if ((c = n) < 0) + n = -n; + + i = 0; + do { + s[i++] = n % 10 + '0'; + } while ((n /= 10) > 0); + + if (c < 0) + s[i++] = '-'; + + s[i] = '\0'; + + len = i--; + + for (j = 0; i > j; j++, i--) { + c = s[i]; + s[i] = s[j]; + s[j] = c; + } + + return len; +} + +/* + * Like APPEND, and APPEND_CAP, APPEND_INT is an in-line function that + * stops us from calling sprintf over and over again. + */ +#define APPEND_INT(ptr, i) \ + ptr += itoa2(i, ptr); + + +#ifdef SERVER +#define ADDRLEN 10 +#define MAXMACLEN 85 +extern char *shiptypes[]; +#define warning(x) fprintf(stderr,x) +#endif + + +char *getaddr(), *getaddr2(); + + + +/* This takes an MDISTR flagged message and makes it into a dist struct */ +void +HandleGenDistr(message, from, to, dist) + char *message; + struct distress *dist; + unsigned char from, to; +{ + + char *mtext; + unsigned char i; + + mtext = &message[ADDRLEN]; +#ifndef SERVER + MZERO((char *) dist, sizeof(dist)); +#else + bzero((char *) dist, sizeof(dist)); +#endif + + dist->sender = from; + dist->distype = mtext[0] & 0x1f; + dist->macroflag = ((mtext[0] & 0x20) > 0); + dist->fuelp = mtext[1] & 0x7f; + dist->dam = mtext[2] & 0x7f; + dist->shld = mtext[3] & 0x7f; + dist->etmp = mtext[4] & 0x7f; + dist->wtmp = mtext[5] & 0x7f; + dist->arms = mtext[6] & 0x1f; + dist->sts = mtext[7] & 0x7f; + dist->wtmpflag = ((dist->sts & PFWEP) != 0) ? 1 : 0; + dist->etempflag = ((dist->sts & PFENG) != 0) ? 1 : 0; + dist->cloakflag = ((dist->sts & PFCLOAK) != 0) ? 1 : 0; + dist->close_pl = mtext[8] & 0x7f; + dist->close_en = mtext[9] & 0x7f; + dist->tclose_pl = mtext[10] & 0x7f; + dist->tclose_en = mtext[11] & 0x7f; + dist->tclose_j = mtext[12] & 0x7f; + dist->close_j = mtext[13] & 0x7f; + dist->tclose_fr = mtext[14] & 0x7f; + dist->close_fr = mtext[15] & 0x7f; + i = 0; + while ((mtext[16 + i] & 0xc0) == 0xc0 && (i < 6)) { + dist->cclist[i] = mtext[16 + i] & 0x1f; + i++; + } + dist->cclist[i] = mtext[16 + i]; + if (dist->cclist[i] == 0x80) + dist->pre_app = 1; + else + dist->pre_app = 0; + dist->preappend[0] = '\0'; + + if (mtext[16 + i + 1] != '\0') { + strncpy(dist->preappend, &mtext[16 + i + 1], MSG_LEN - 1); + dist->preappend[MSG_LEN - 1] = '\0'; + } +} + +/* this converts a dist struct to the appropriate text + (excludes F1->FED text bit).. sorry if this is not what we said + earlier jeff.. but I lost the paper towel I wrote it all down on */ +void +Dist2Mesg(dist, buf) + struct distress *dist; + char *buf; +{ + int len, i; + + sprintf(buf, "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c", + (dist->macroflag << 5) + (dist->distype), + dist->fuelp | 0x80, + dist->dam | 0x80, + dist->shld | 0x80, + dist->etmp | 0x80, + dist->wtmp | 0x80, + dist->arms | 0x80, + dist->sts | 0x80, + dist->close_pl | 0x80, + dist->close_en | 0x80, + dist->tclose_pl | 0x80, + dist->tclose_en | 0x80, + dist->tclose_j | 0x80, + dist->close_j | 0x80, + dist->tclose_fr | 0x80, + dist->close_fr | 0x80); + + /* cclist better be terminated properly otherwise we hose here */ + i = 0; + while (((dist->cclist[i] & 0xc0) == 0xc0)) { + buf[16 + i] = dist->cclist[i]; + i++; + } + /* get the pre/append cclist terminator in there */ + buf[16 + i] = dist->cclist[i]; + buf[16 + i + 1] = '\0'; + + len = 16 + i + 1; + if (dist->preappend[0] != '\0') { + strncat(buf, dist->preappend, MSG_LEN - len); /* false sense of + security? */ + buf[MSG_LEN - 1] = '\0'; + } +} + +/* small permutation on the newmacro code... this takes a pointer to + ** a distress structure and a pointer to a macro syntax string, + ** and converts it into a line of text. + ** 9/1/93 - jn + */ +int +makedistress(dist, cry, pm) + struct distress *dist; /* the info */ + char *cry; /* the call for help! (output) - should be + array */ + char *pm; /* macro to parse, used for distress and + macro */ +{ + char buf1[10 * MAXMACLEN]; + char *pbuf1; + char buf2[10 * MAXMACLEN]; + char buf3[10 * MAXMACLEN]; + char tmp[10 * MAXMACLEN]; + int index = 0; + int index2 = 0; + int index3 = 0; + int cap = 0; + struct player *sender; + struct player *j; + struct planet *l; + char *strcap(); +#ifndef SERVER + extern int ping_tloss_sc; /* total % loss 0--100, server to client */ + extern int ping_tloss_cs; /* total % loss 0--100, client to server */ + extern int ping_av; /* average rt */ + extern int ping_sd; /* standard deviation */ +#endif + char c; + + + sender = &players[dist->sender]; + + if (!(*pm)) { + cry[0] = '\0'; + return (0); + } + buf1[0] = '\0'; + pbuf1 = buf1; + + /* first step is to substitute variables */ + while (*pm) { + if (*pm == '%') { + pm++; + + if (!pm) + continue; + + switch (c = *(pm++)) { + case ' ': + APPEND(pbuf1, " \0"); + break; + case 'O': /* push a 3 character team name into buf */ + cap = 1; + case 'o': /* push a 3 character team name into buf */ + APPEND_CAP(pbuf1, cap, teaminfo[sender->p_teami].shortname); + cap = 0; + break; + case 'a': /* push army number into buf */ + APPEND_INT(pbuf1, dist->arms); + break; + case 'd': /* push damage into buf */ + APPEND_INT(pbuf1, dist->dam); + break; + case 's': /* push shields into buf */ + APPEND_INT(pbuf1, dist->shld); + break; + case 'f': /* push fuel into buf */ + APPEND_INT(pbuf1, dist->fuelp); + break; + case 'w': /* push wtemp into buf */ + APPEND_INT(pbuf1, dist->wtmp); + break; + case 'e': /* push etemp into buf */ + APPEND_INT(pbuf1, dist->etmp); + break; + + case 'P': /* push player id into buf */ + case 'G': /* push friendly player id into buf */ + case 'H': /* push enemy target player id into buf */ + + case 'p': /* push player id into buf */ + case 'g': /* push friendly player id into buf */ + case 'h': /* push enemy target player id into buf */ + + switch (c) { + case 'p': + j = &players[dist->tclose_j]; + break; + case 'g': + j = &players[dist->tclose_fr]; + break; + case 'h': + j = &players[dist->tclose_en]; + break; + case 'P': + j = &players[dist->close_j]; + break; + case 'G': + j = &players[dist->close_fr]; + break; + default: + j = &players[dist->close_en]; + break; + } + tmp[0] = j->p_mapchars[1]; + tmp[1] = '\0'; + APPEND(pbuf1, tmp); + break; + + case 'n': /* push planet armies into buf */ + l = &planets[dist->tclose_pl]; + APPEND_INT(pbuf1, + ((l->pl_info & idx_to_mask(sender->p_teami)) + ? l->pl_armies : -1)); + break; + case 'B': + cap = 1; + case 'b': /* push planet into buf */ + l = &planets[dist->close_pl]; + tmp[0] = l->pl_name[0] - 'A' + 'a'; + tmp[1] = l->pl_name[1]; + tmp[2] = l->pl_name[2]; + tmp[3] = '\0'; + APPEND_CAP(pbuf1, cap, tmp); + cap = 0; + break; + case 'L': + cap = 1; + case 'l': /* push planet into buf */ + l = &planets[dist->tclose_pl]; + tmp[0] = l->pl_name[0] - 'A' + 'a'; + tmp[1] = l->pl_name[1]; + tmp[2] = l->pl_name[2]; + tmp[3] = '\0'; + APPEND_CAP(pbuf1, cap, tmp); + cap = 0; + break; + case 'Z': /* push a 3 character team name into buf */ + cap = 1; + case 'z': /* push a 3 character team name into buf */ + l = &planets[dist->tclose_pl]; + APPEND_CAP(pbuf1, cap, + teaminfo[mask_to_idx(l->pl_owner)].shortname); + cap = 0; + break; + case 't': /* push a team character into buf */ + l = &planets[dist->tclose_pl]; + tmp[0] = teaminfo[mask_to_idx(l->pl_owner)].letter; + tmp[1] = '\0'; + APPEND(pbuf1, tmp); + break; + case 'T': /* push my team into buf */ + tmp[0] = teaminfo[sender->p_teami].letter; + tmp[1] = '\0'; + APPEND(pbuf1, tmp); + break; + case 'c': /* push my id char into buf */ + tmp[0] = sender->p_mapchars[1]; + tmp[1] = '\0'; + APPEND(pbuf1, tmp); + break; + case 'W': /* push WTEMP flag into buf */ + if (dist->wtmpflag) + tmp[0] = '1'; + else + tmp[0] = '0'; + tmp[1] = '\0'; + APPEND(pbuf1, tmp); + break; + case 'E': /* push ETEMP flag into buf */ + if (dist->etempflag) + tmp[0] = '1'; + else + tmp[0] = '0'; + tmp[1] = '\0'; + APPEND(pbuf1, tmp); + break; + case 'K': + cap = 1; + case 'k': + if (cap) + j = &players[dist->tclose_en]; + else + j = sender; + + if (j->p_ship->s_type == STARBASE) + sprintf(tmp, "%5.2f", j->p_stats.st_sbkills / 100.0); + else + sprintf(tmp, "%5.2f", (j->p_stats.st_kills + j->p_stats.st_tkills) / 100.0); + APPEND(pbuf1, tmp); + break; + + case 'U': /* push player name into buf */ + cap = 1; + case 'u': /* push player name into buf */ + j = &players[dist->tclose_en]; + APPEND_CAP(pbuf1, cap, j->p_name); + cap = 0; + break; + case 'I': /* my player name into buf */ + cap = 1; + case 'i': /* my player name into buf */ + APPEND_CAP(pbuf1, cap, sender->p_name); + cap = 0; + break; + case 'S': /* push ship type into buf */ +#ifndef SERVER + *pbuf1++ = sender->p_ship->s_desig[0]; + *pbuf1++ = sender->p_ship->s_desig[1]; +#else + APPEND(pbuf1, shiptypes[sender->p_ship->s_type]); +#endif + break; + +#ifdef SERVER + case 'v': /* push average ping round trip time into buf */ + case 'V': /* push ping stdev into buf */ + case 'y': /* push packet loss into buf */ + APPEND(pbuf1, "0\0"); + case 'M': /* push capitalized lastMessage into buf */ + case 'm': /* push lastMessage into buf */ + break; +#else + case 'M': /* push capitalized lastMessage into buf */ + cap = 1; + case 'm': /* push lastMessage into buf */ + APPEND_CAP(pbuf1, cap, lastMessage); + cap = 0; + break; + + case 'v': /* push average ping round trip time into buf */ + APPEND_INT(pbuf1, ping_av); + break; + + case 'V': /* push ping stdev into buf */ + APPEND_INT(pbuf1, ping_sd); + break; + + case 'y': /* push packet loss into buf */ + /* this is the weighting formula used be socket.c ntserv */ + APPEND_INT(pbuf1, (2 * ping_tloss_sc + ping_tloss_cs) / 3); + break; +#endif + + case '*': /* push %} into buf */ + APPEND(pbuf1, "%*\0"); + break; + case '}': /* push %} into buf */ + APPEND(pbuf1, "%}\0"); + break; + case '{': /* push %{ into buf */ + APPEND(pbuf1, "%{\0"); + break; + case '!': /* push %! into buf */ + APPEND(pbuf1, "%!\0"); + break; + case '?': /* push %? into buf */ + APPEND(pbuf1, "%?\0"); + break; + case '%': /* push %% into buf */ + APPEND(pbuf1, "%%\0"); + break; + default: +/* try to continue +** bad macro character is skipped entirely, +** the message will be parsed without whatever %. has occurred. - jn +*/ + warning("Bad Macro character in distress!"); + fprintf(stderr, "Unrecognizable special character in distress pass 1: %c\n", *(pm - 1)); + break; + } + } else { + tmp[0] = *pm; + tmp[1] = '\0'; + APPEND(pbuf1, tmp); + pm++; + } + + } + + *pbuf1 = '\0'; + + /* second step is to evaluate tests, buf1->buf2 */ + testmacro(buf1, buf2, &index, &index2); + buf2[index2] = '\0'; + + if (index2 <= 0) { + cry[0] = '\0'; + return (0); + } + index2 = 0; + + /* third step is to include conditional text, buf2->buf3 */ + condmacro(buf2, buf3, &index2, &index3, 1); + + if (index3 <= 0) { + cry[0] = '\0'; + return (0); + } + buf3[index3] = '\0'; + + cry[0] = '\0'; + strncat(cry, buf3, MSG_LEN); + + return (index3); +} + +int +testmacro(bufa, bufb, inda, indb) + char *bufa; + char *bufb; + int *inda; + int *indb; +{ + int state = 0; + + if (*indb >= 10 * MAXMACLEN) + return 0; +/* maybe we should do something more "safe" here (and at other returns)? */ + + + while (bufa[*inda] && (*indb < 10 * MAXMACLEN)) { + if (state) { + switch (bufa[(*inda)++]) { + case '*': /* push %* into buf */ + if (*indb < 10 * MAXMACLEN - 2) { + bufb[*indb] = '%'; + (*indb)++; + bufb[*indb] = '*'; + (*indb)++; + } else + return (0); /* we are full, so we are done */ + state = 0; + continue; + break; + + case '%': /* push %% into buf */ + if (*indb < 10 * MAXMACLEN - 2) { + bufb[*indb] = '%'; + (*indb)++; + bufb[*indb] = '%'; + (*indb)++; + } else + return (0); /* we are full, so we are done */ + state = 0; + continue; + break; + + case '{': /* push %{ into buf */ + if (*indb < 10 * MAXMACLEN - 2) { + bufb[*indb] = '%'; + (*indb)++; + bufb[*indb] = '{'; + (*indb)++; + } else + return (0); /* we are full, so we are done */ + state = 0; + continue; + break; + + case '}': /* push %} into buf */ + if (*indb < 10 * MAXMACLEN - 2) { + bufb[*indb] = '%'; + (*indb)++; + bufb[*indb] = '}'; + (*indb)++; + } else + return (0); /* we are full, so we are done */ + state = 0; + continue; + break; + + case '!': /* push %! into buf */ + if (*indb < 10 * MAXMACLEN - 2) { + bufb[*indb] = '%'; + (*indb)++; + bufb[*indb] = '!'; + (*indb)++; + } else + return (0); /* we are full, so we are done */ + state = 0; + continue; + break; + + case '?': /* the dreaded conditional, evaluate it */ + bufb[*indb] = '0' + solvetest(bufa, inda); + (*indb)++; + state = 0; + continue; + break; + + default: + warning("Bad character in Macro!"); + printf("Unrecognizable special character in macro pass2: %c Trying to continue.\n", + bufa[(*inda) - 1]); + state = 0; + continue; + break; + } + } + if (bufa[*inda] == '%') { + state++; + (*inda)++; + continue; + } + state = 0; + + + if (*indb < 10 * MAXMACLEN) { + bufb[*indb] = bufa[*inda]; + (*inda)++; + (*indb)++; + } else + return (0); + } + + return (0); +} + +int +solvetest(bufa, inda) + char *bufa; + int *inda; +{ + int state = 0; + char bufh[10 * MAXMACLEN]; + char bufc[10 * MAXMACLEN]; + int indh = 0, indc = 0, i; + char operation; + + + while (bufa[*inda] && + bufa[*inda] != '<' && + bufa[*inda] != '>' && + bufa[*inda] != '=') { + + bufh[indh++] = bufa[(*inda)++]; + } + bufh[indh] = '\0'; + + operation = bufa[(*inda)++]; + + while (bufa[*inda] && + !(state && + ((bufa[*inda] == '?') || + (bufa[*inda] == '{')))) { + + if (state && (bufa[*inda] == '%' || + bufa[*inda] == '!' || + bufa[*inda] == '}')) { + bufc[indc++] = '%'; + } else if (bufa[*inda] == '%') { + state = 1; + (*inda)++; + continue; + } + state = 0; + bufc[indc++] = bufa[(*inda)++]; + } + bufc[indc] = '\0'; + + if (bufa[*inda]) + (*inda)--; + + if (!operation) /* incomplete is truth, just ask Godel */ + return (1); + + switch (operation) { + case '=': /* character by character equality */ + if (indc != indh) + return (0); + for (i = 0; i < indc; i++) { + if (bufc[i] != bufh[i]) + return (0); + } + return (1); + break; + + case '<': + if (atoi(bufh) < atoi(bufc)) + return (1); + else + return (0); + break; + + case '>': + if (atoi(bufh) > atoi(bufc)) + return (1); + else + return (0); + break; + + default: + warning("Bad operation in Macro!"); + printf("Unrecognizable operation in macro pass3: %c Trying to continue.\n", + operation); + return (1); /* don't know what happened, pretend we do */ + break; + } +} + +int +condmacro(bufa, bufb, inda, indb, flag) + char *bufa; + char *bufb; + int *inda; + int *indb; + int flag; +{ + int newflag, include; + int state = 0; + + + if (*indb >= MAXMACLEN) + return 0; + + include = flag; + + while (bufa[*inda] && (*indb < MAXMACLEN)) { + if (state) { + switch (bufa[(*inda)++]) { + case '}': /* done with this conditional, return */ + return (0); + break; + + case '{': /* handle new conditional */ + if (*indb > 0) { + (*indb)--; + if (bufb[*indb] == '0') + newflag = 0; + else + newflag = 1; + } else /* moron starting with cond, assume true */ + newflag = 1; + + if (include) + condmacro(bufa, bufb, inda, indb, newflag); + else { + (*indb)++; + *inda = skipmacro(bufa, *inda); + } + + state = 0; + continue; + break; + + case '!': /* handle not indicator */ + if (flag) + include = 0; + else + include = 1; + + state = 0; + continue; + break; + + case '%': /* push % into buf */ + if (include) { + if (*indb < MAXMACLEN) { + bufb[*indb] = '%'; + (*indb)++; + } else + return (0); + } + state = 0; + continue; + + default: + warning("Bad character in Macro!"); + printf("Unrecognizable special character in macro pass4: %c Trying to continue.\n", + bufa[(*inda) - 1]); + } + } + if (bufa[*inda] == '%') { + state++; + (*inda)++; + continue; + } + state = 0; + + + if (include) { + if (*indb < MAXMACLEN) { + bufb[*indb] = bufa[*inda]; + (*inda)++; + (*indb)++; + } else + return (0); + } else + (*inda)++; + } + return (0); +} + +int +skipmacro(buf, index) + char buf[]; + int index; +{ + int state = 0; + int end = 0; + + if (index == 0) + index++; + + while (buf[index] && !end) { + if (state) { + switch (buf[index++]) { + case '{': + index = skipmacro(buf, index); + continue; + break; + case '}': + end = 1; + continue; + break; + case '!': + case '%': + state = 0; + continue; + break; + default: + warning("Bad character in Macro!"); + printf("Unrecognizable special character in macro pass5: %c Trying to continue.\n", + buf[index - 1]); + } + } + if (buf[index] == '%') { + state++; + index++; + continue; + } + state = 0; + index++; + } + + return (index); +} + + +/* return a pointer to a capitalized copy of string s */ +char * +strcap(s) + char *s; +{ + static char buf[256]; /* returns static */ + register char *t = buf; + + while (*s) { + if (islower(*s)) + *t++ = toupper(*s++); + else + *t++ = *s++; + } + *t = 0; + if (buf[255]) { + fprintf(stderr, "ERROR: String constant overwritten\n"); + return NULL; + } + return buf; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dmessage.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,778 @@ +/* $Id: dmessage.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +/* + * dmessage.c + * + * for the client of a socket based protocol. + * code for message window scrollback added by Bill Dyess 12/7/93 + */ +#include "copyright.h" + +#include <stdio.h> +#include <math.h> +#include <string.h> +#include <ctype.h> +#ifdef __STDC__ +#include <stdlib.h> +#endif +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "proto.h" +#ifdef SOUND +#include "Slib.h" +#endif + +#define MESSAGESIZE 20 +#define YOFF 0 + +struct messageData { + char *message; + unsigned char flags, from, to; +}; + +struct messageNode { + struct messageData *line; + struct messageNode *next, *prev; +}; + +/* Prototypes */ +int instr P((char *string1, char *string2)); +void CheckFeatures P((char *m)); +void print_message +P((char *message, unsigned int flags, unsigned int from, + unsigned int to, struct messageData * data, + W_Window winmask, int backwards)); + void evalFlags P((int type, char *flagList)); + + void initMessageWindows() +{ + int i; + char *s; + + messWin[WALL].window = W_MakeScrollingWindow("review_all", WINSIDE + BORDER, + YOFF + WINSIDE + 3 * BORDER + 2 * MESSAGESIZE, 80, 10, 0, "xterm", BORDER); + messWin[WTEAM].window = W_MakeScrollingWindow("review_team", WINSIDE + BORDER, + YOFF + WINSIDE + 4 * BORDER + 2 * MESSAGESIZE + 10 * W_Textheight + 8, + 80, 5, 0, "xterm", BORDER); + messWin[WINDIV].window = W_MakeScrollingWindow("review_your", WINSIDE + BORDER, + YOFF + WINSIDE + 5 * BORDER + 2 * MESSAGESIZE + 15 * W_Textheight + 16, + 80, 4, 0, "xterm", BORDER); + messWin[WKILL].window = W_MakeScrollingWindow("review_kill", WINSIDE + BORDER, + YOFF + WINSIDE + 6 * BORDER + 2 * MESSAGESIZE + 19 * W_Textheight + 24, + 80, 6, 0, "xterm", BORDER); + messWin[WPHASER].window = W_MakeScrollingWindow("review_phaser", WINSIDE + + BORDER, YOFF + WINSIDE + 7 * BORDER + 2 * MESSAGESIZE + 24 * W_Textheight + + 32, 80, 3, 0, "xterm", BORDER); + messWin[WREVIEW].window = W_MakeScrollingWindow("review", WINSIDE + BORDER, + YOFF + WINSIDE + 3 * BORDER + 2 * MESSAGESIZE, + 80, 20, 0, "xterm", BORDER); + + /* + initialize the 'allow' flags. Any window can display any message. + [BDyess] + */ + s = stringDefault("review_all.allow", "MA"); + evalFlags(WALL, s); + s = stringDefault("review_team.allow", "T"); + evalFlags(WTEAM, s); + s = stringDefault("review_your.allow", "I"); + evalFlags(WINDIV, s); + s = stringDefault("review_kill.allow", "K"); + evalFlags(WKILL, s); + s = stringDefault("review_phaser.allow", "P"); + evalFlags(WPHASER, s); + s = stringDefault("review.allow", "MATIKP"); + evalFlags(WREVIEW, s); + + for (i = 0; i < WNUM; i++) { + messWin[i].head = messWin[i].curHead = NULL; + } +} + +void +evalFlags(type, flagList) + int type; + char *flagList; +{ + char *orig=flagList; + + messWin[type].flags = 0; + while (*flagList) { + switch (toupper(*flagList)) { + case 'A': + messWin[type].flags |= WA_ALL; + break; + case 'T': + messWin[type].flags |= WA_TEAM; + break; + case 'I': + messWin[type].flags |= WA_INDIV; + break; + case 'K': + messWin[type].flags |= WA_KILL; + break; + case 'P': + messWin[type].flags |= WA_PHASER; + break; + case 'M': + messWin[type].flags |= WA_MACRO; + break; + default: + printf("Invalid allow flag '%c' in allow list, ignoring\n", + *flagList); + break; + } + flagList++; + } + free(orig); +} + +void +messageWinEvent(evt) + W_Event *evt; +/* handles the mouse and keyboard events that happen in one of the message + windows. For key events, if the event is within the team or all window then + it will automatically start the message for you, with destination to the + player's team or ALL, respectively. If it's a button event, it will scroll + the message window back, forward, or to start (left, right, and middle + button respectively). It beeps if there is no messages to scroll (ie at + the top or bottom already). [BDyess] 12/07/93 */ +{ + struct messageNode **headpntr, *runner, *newcpntr; + struct messageData *j; + int windowHeight; + register int i; + W_Window window = evt->Window; + int key = evt->key; + int scroll=0; + + if (!W_IsMapped(window)) + return; + + if (evt->type == W_EV_KEY) { + if (key == ('e' + 128)) { /* erase window [BDyess] */ + W_ClearWindow(window); + } else if(key == ('p'+128)) { + scroll = -1; + } else if(key == ('n'+128)) { + scroll = 1; + } else if (window == messWin[WALL].window) { + smessage_ahead('A', key); + } else if (window == messWin[WTEAM].window) { + smessage_ahead('T', key); + } else { + smessage(key); + } + if(!scroll) + return; + } + headpntr = NULL; + for (i = 0; i < WNUM; i++) { + if (window == messWin[i].window) { + headpntr = &messWin[i].curHead; + break; + } + } + + runner = *headpntr; + if (runner == NULL) { + if(scrollBeep) + W_Beep(); + return; + } + windowHeight = W_WindowHeight(window); + + if(scroll==-1) { + for (i = 0; (i < windowHeight) && runner; i++, runner = runner->next) + ; + if (runner == NULL) { + if (scrollBeep) + W_Beep(); + return; + } + j=runner->line; + print_message(j->message, j->flags, j->from, j->to, NULL, window, 1); + *headpntr = (*headpntr)->next; + return; + } else if(scroll==1) { + if(runner->prev == NULL) { + if (scrollBeep) + W_Beep(); + return; + } + j=runner->prev->line; + print_message(j->message, j->flags, j->from, j->to, NULL, window, 0); + *headpntr = (*headpntr)->prev; + return; + } + switch (key) { + case W_LBUTTON: + for (i = 0; (i < windowHeight-1) && runner->next; i++, runner = runner->next) + ; + newcpntr=runner; + + if (runner->next == NULL) { + if (scrollBeep) + W_Beep(); + break; + } + runner=runner->next; + for (i = 0; (i < windowHeight-1) && runner; i++, runner = runner->next) { + j=runner->line; + print_message(j->message, j->flags, j->from, j->to, NULL, window, 1); + } + if(i<windowHeight-1) { + for(;i<windowHeight-1;i++) + W_WriteText(window,0,-1,0,"",0,0); + } + *headpntr=newcpntr; + break; + case W_RBUTTON: + if (runner->prev == NULL) { + if (scrollBeep) + W_Beep(); + break; + } + for (i = 0; (i < windowHeight-1) && runner->prev; i++, runner = runner->prev) { + j=runner->prev->line; + print_message(j->message, j->flags, j->from, j->to, NULL, window, 0); + } + *headpntr = runner; + break; + case W_MBUTTON: + if (runner->prev == NULL) { + if (scrollBeep) + W_Beep(); + break; + } + W_ClearWindow(window); + while (runner->prev) + runner = runner->prev; + *headpntr = runner; + for (i = 0; i < windowHeight && runner->next; i++, runner = runner->next); + while (runner) { + j = runner->line; + print_message(j->message, j->flags, j->from, j->to, NULL, window, 0); + runner = runner->prev; + } + break; + } +} + +void +rsvp_borg_call(message, from) + char *message; + int from; +{ +#if 0 + int len, pos; + len = strlen(message); + pos = len - 5; + if (strncmp(message + pos, " ", 5) == 0) +#else + char *chk; + + if (strlen(message) < 15) + return; + for (chk = message + 10; *chk && *chk == ' '; chk++) + /* empty body */ ; + if (*chk) + return; +#endif + { + char buf[120]; + + sprintf(buf, "Paradise Client %s (%s)", CLIENTVERS, +#ifdef __osf__ + "DEC OSF/1" +#else +#ifdef NeXT + "NeXT" +#else +#ifdef ultrix + "DEC Ultrix" +#else +#if defined(sparc) && defined(SVR4) + "Solaris" +#else +#ifdef sparc + "SUN4/Sparc" +#else +#ifdef sun + "SUN3" +#else +#ifdef sequent + "sequent" +#else +#ifdef hpux + "hpux" +#else +#ifdef AIX + "AIX" +#else +#ifdef vax + "vax" +#else +#ifdef sgi + "sgi/IRIX" +#else +#ifdef apollo + "apollo" +#else +#ifdef RS6K + "RS6K" +#else +#ifdef linux + "Linux" +#else +#ifdef __NetBSD__ + "NetBSD" +#else +#ifdef __FreeBSD__ + "FreeBSD" +#else +#ifdef AMIGA + "Amiga" +#else + "generic" +#endif /* Amiga */ +#endif /* linux */ +#endif /* RS6K */ +#endif /* apollo */ +#endif /* sgi */ +#endif /* vax */ +#endif /* AIX */ +#endif /* hpux */ +#endif /* sequent */ +#endif /* sun */ +#endif /* sparc */ +#endif /* solaris */ +#endif /* ultrix */ +#endif /* NeXT */ +#endif /* __osf__ */ +#endif /* FreeBSD */ +#endif /* NetBSD */ + ); + if (from == 255) { + sendMessage(buf, MGOD, 0); + } else + sendMessage(buf, MINDIV, from); + } +} + +void +logit(message) + char *message; +/* logs the given message if the 'logmess' variable is set to one. It send the + message to stdout by default, or to a file if one is defined. [BDyess] */ +{ + if (!logmess) + return; + if (logfilehandle && logFile) { + fprintf(logfilehandle, "%s\n", message); + fflush(logfilehandle); + } else { + printf("%s\n", message); + } +} + +void +writeMessage(data, message, color, len, winmask, type, backwards) + struct messageData *data; + char *message; + W_Color color; + int len; + W_Window winmask; + int type; + int backwards; +{ + struct messageNode *newhead; + struct messageWin *j; + + if (data != NULL) { +#ifdef SPEECH /* was AMIGA... ya never know ;-) */ + if (((S_SpeakYour && type & WA_INDIV) || + (S_SpeakTeam && type & WA_TEAM) || + (S_SpeakAll && type & WA_ALL) || + (S_SpeakKill && type & WA_KILL)) && + ((strncmp(message,"GOD->",5) != 0) || S_SpeakGod) && + ((data->from != me->p_no) || S_SpeakSelf)) { + S_SpeakString(message, len); + } +#endif /* SPEECH */ +#ifdef SOUND + if ((type & WA_INDIV) && data->from != me->p_no) { + S_PlaySound(S_WHISTLE); + } +#endif + for (j = &messWin[0]; j < &messWin[WNUM]; j++) { + if (!(j->flags & type)) + continue; + newhead = (struct messageNode *) malloc(sizeof(struct messageNode)); + newhead->next = j->head; + if (newhead->next) + newhead->next->prev = newhead; + newhead->prev = NULL; + newhead->line = data; + if (j->head == j->curHead) { + /* we aren't currently scrolled back [BDyess] */ + W_WriteText(j->window, 0, 0, color, message, len, 0); + j->curHead = newhead; + } + j->head = newhead; + } + } else { /* we're drawing a new page */ + for (j = &messWin[0]; j < &messWin[WNUM]; j++) { + if (!(j->flags & type)) + continue; + if (j->window != winmask) + continue; + W_WriteText(j->window, 0, (backwards ? -1 : 0), color, message, len, 0); + } + } +} + +void +print_message(message, flags, from, to, data, winmask, backwards) + char *message; + unsigned int flags, from, to; + struct messageData *data; + W_Window winmask; + int backwards; +/* this function determines the color that the given message should be and + then passes it to writeMessage, where the data structure for the scroll + back code is created and also where the winmask test is done. The winmask + determines what window the message is written to, useful when calling this + routine from the scrollback routines. If winmask == NULL it doesn't + limit printing at all, eg team messages will go to the team window and to + the total review window. [BDyess] 12/07/93 */ +{ + register int len; + W_Color color; + W_Window targwin; + +#define take MTEAM + MTAKE + MVALID +#define destroy MTEAM + MDEST + MVALID +#define kill MALL + MKILL + MVALID +#define killp MALL + MKILLP + MVALID +#define killa MALL + MKILLA + MVALID +#define bomb MTEAM + MBOMB + MVALID +#define team MTEAM + MVALID +#define conq MALL + MCONQ + MVALID + + len = strlen(message); + if (from == 254) { /* client passing info around */ + switch (showPhaser) { + case 0: + break; + case 1: + writeMessage(data, message, textColor, len, winmask, WA_KILL | WA_REVIEW, backwards); + break; + case 2: + writeMessage(data, message, textColor, len, winmask, WA_REVIEW | WA_PHASER, backwards); + break; + case 3: + writeMessage(data, message, textColor, len, winmask, WA_REVIEW, backwards); + break; + } + return; + } + if (from == 255) { + if (flags == MCONFIG + MINDIV + MVALID) { +/* printf("Going to checkfeatures\n");*/ + CheckFeatures(message); + return; + } + /* From God */ + color = textColor; + } else { + /* kludge to fix the occasional incorrect color message */ + if (*message == ' ' && from != me->p_no) { + /* XXX fix to handle funky teams */ + switch (*(message + 1)) { + case 'F': + color = W_Yellow; + break; + case 'R': + color = W_Red; + break; + case 'K': + color = W_Green; + break; + case 'O': + color = W_Cyan; + break; + case 'I': + color = W_Grey; + break; + default: + color = playerColor(&(players[from])); + } + } else + color = playerColor(&(players[from])); + } + + /* added/modified to fit with the scrollback feature 1/94 -JR */ + if (!paradise && niftyNewMessages) { + if (flags == conq) { + /* output conquer stuff to stdout in addition to message window */ + fprintf(stdout, "%s\n", message); + if (instr(message, "kill")) { + fprintf(stdout, "NOTE: The server here does not properly set message flags\n"); + fprintf(stdout, "You should probably pester the server god to update....\n"); + } + } + if ((flags == team) || (flags == take) || (flags == destroy)) { + writeMessage(data, message, color, len, winmask, WA_TEAM | WA_REVIEW, backwards); + targwin = messWin[WTEAM].window; + } else if ((flags == kill) || (flags == killp) || (flags == killa) || (flags == bomb)) { + writeMessage(data, message, color, len, winmask, + WA_KILL | (reportKills ? WA_REVIEW : 0), backwards); + targwin = messWin[WKILL].window; + } else if (flags & MINDIV) { + writeMessage(data, message, color, len, winmask, (WA_INDIV | WA_REVIEW), backwards); + targwin = messWin[WINDIV].window; + } else if (flags == (MMACRO | MALL)) { + writeMessage(data, message, color, len, winmask, (WA_MACRO | WA_REVIEW), backwards); + targwin = messWin[WALL].window; + } else { + /* + if we don't know where the message belongs by this time, stick + it in the all board... + */ + writeMessage(data, message, color, len, winmask, (WA_ALL | WA_REVIEW), backwards); + targwin = messWin[WALL].window; + } + } else { + + /* + Kludge stuff for report kills... + */ + if ((strncmp(message, "GOD->ALL", 8) == 0 && + (instr(message, "was kill") || + instr(message, "killed by"))) || + instr(message, "burned to a crisp by") || + instr(message, "shot down by") || + (*message != ' ' && instr(message, "We are being attacked"))) { + writeMessage(data, message, color, len, winmask, + WA_KILL | (reportKills ? WA_REVIEW : 0), backwards); + return; + } + /* + note: messages are kept track of even if the associated window is + not mapped. This allows the window to be later mapped and have + all the past messages. [BDyess] + */ + if (flags & MTEAM) { + writeMessage(data, message, color, len, winmask, WA_TEAM | WA_REVIEW, backwards); + targwin = messWin[WTEAM].window; + } else if (flags & MINDIV) { + writeMessage(data, message, color, len, winmask, WA_INDIV | WA_REVIEW, backwards); + targwin = messWin[WINDIV].window; + } else if (flags == (MMACRO | MALL)) { + writeMessage(data, message, color, len, winmask, WA_MACRO | WA_REVIEW, backwards); + targwin = messWin[WALL].window; + } else { + writeMessage(data, message, color, len, winmask, WA_ALL | WA_REVIEW, backwards); + targwin = messWin[WALL].window; + } + } + /* + send warnings to warning or message window, if player doesn't have + messag es mapped + */ + if ((use_msgw && (targwin == messWin[WINDIV].window || targwin == messWin[WTEAM].window)) || + (!W_IsMapped(targwin) && !W_IsMapped(messWin[WREVIEW].window))) { + if (!messpend && messagew) { /* don't collide with messages being + written! */ + W_ClearWindow(messagew); + W_WriteText(messagew, 5, 5, color, message, len, W_RegularFont); + } else + warning(message); + } +} + +void +dmessage(message, flags, from, to) + char *message; + unsigned int flags, from, to; +/* prints the given message by going though several subroutines. Here, it first + creates the data structure that holds the message info and logs the message, + then sends it on it's subroutine path to print it to the correct window(s). + This is a good place to handle any special-functions that occur due to + incoming messages. The data structure for the scroll back is like this: + each window has a head pointer that points to the top of its message + list. Each list only contains the messages that go to it's window. The + lists have pointers to the message itself, so that only one copy of the + message exists even if it is displayed on several windows. Each list also + has a current head pointer that points to the record that is at the bottom + of that current window. If the current head pointer and the head pointer + are different, then the window must be scrolled back. In such a case, new + messages are still received but not printed. [BDyess] 12/07/93 */ +{ + struct messageData *data; + struct distress dist; + int len; + +#ifdef RC_DISTRESS + /* aha! A new type distress/macro call came in. parse it appropriately */ + if (F_gen_distress && (flags == (MTEAM | MDISTR | MVALID))) { + HandleGenDistr(message, from, to, &dist); + len = makedistress(&dist, message, distmacro[dist.distype].macro); +#ifdef BEEPLITE + if (UseLite) + rcdlite(&dist); +#endif + if (len <= 0) + return; + flags ^= MDISTR; + } +#endif + /* + add create message data struct. Used for message scrollback + capability. [BDyess] + */ + data = (struct messageData *) malloc(sizeof(struct messageData)); + data->message = (char *) strdup(message); + data->flags = flags; + data->from = from; + data->to = to; + /* + keep track of how many queued messages there are for use with the + infoIcon [BDyess] + */ + if (infoIcon) { + if (to == me->p_no && flags & MINDIV) { /* personal message */ + me_messages++; + } else if (flags & MTEAM) { /* team message */ + team_messages++; + } else { /* message for all */ + all_messages++; + } + if (iconified) + drawIcon(); + } + logit(message); + + /* + fix for upgrade bug. Forced UDP would resend numbers, (thinking them + speed changes) screwing up upgrading on those twinkish sturgeon + servers. [BDyess] + */ + if (strncmp(message, "UPG->", 5) == 0) + upgrading = 1; + if (upgrading && !(me->p_flags & PFORBIT)) + upgrading = 0; + + if ((from != me->p_no) || pigSelf) + rsvp_borg_call(message, from); + + /* beep when a personal message is sent while iconified [BDyess] */ + if (to == me->p_no && (flags & MINDIV) && iconified) { + W_Beep(); + } + if (from == 255 && + strcmp(message, "Tractor beam aborted warp engagement") == 0) { + me->p_flags &= ~PFWARPPREP; + } + print_message(message, flags, from, to, data, NULL, 0); +} + + +int +instr(string1, string2) + char *string1, *string2; +{ + char *s; + int length; + + length = strlen(string2); + for (s = string1; *s != 0; s++) { + if (*s == *string2 && strncmp(s, string2, length) == 0) + return (1); + } + return (0); +} + +void +CheckFeatures(m) + char *m; +/* I don't know if this works correctly or not. It is ripped from BRM and has + been modified a bit to fit. Right now it doesn't do anything. [BDyess] */ +{ + char buf[BUFSIZ]; + char *pek = &m[10]; + + if ((int) strlen(m) < 11) + return; + + while ((*pek == ' ') && (*pek != '\0')) + pek++; + + strcpy(buf, "Paradise Client: "); + + if (!strcmp(pek, "NO_VIEW_BOX")) { + allowViewBox = 0; + strcat(buf, pek); + } +#ifdef CONTINUOUS_MOUSE + if (!strcmp(pek, "NO_CONTINUOUS_MOUSE")) { + allowContinuousMouse = 0; + strcat(buf, pek); + } +#endif /* CONTINUOUS_MOUSE */ + if (!strcmp(pek, "NO_SHOW_ALL_TRACTORS")) { + allowShowAllTractorPressor = 0; + strcat(buf, pek); + } + if (!strcmp(pek, "HIDE_PLAYERLIST_ON_ENTRY")) { + allowPlayerlist = 0; + strcat(buf, pek); + } + if (!strcmp(pek, "NO_NEWMACRO")) { +/* UseNewMacro = 0;*/ + strcat(buf, pek); + } + if (!strcmp(pek, "NO_SMARTMACRO")) { +/* UseSmartMacro = 0;*/ + strcat(buf, pek); + } + if (!strcmp(pek, "WHY_DEAD")) { + why_dead = 1; + strcat(buf, pek); + } + if (!strcmp(pek, "RC_DISTRESS")) { +/* gen_distress = 1;*/ +/* distmacro = dist_prefered;*/ + strcat(buf, pek); + } + /* what the hell is this? - jmn */ + if (!strncmp(pek, "INFO", 4)) { + strcat(buf, pek); + } + if (strlen(buf) == strlen("Paradise Client: ")) { + strcat(buf, "UNKNOWN FEATURE: "); + strcat(buf, pek); + } + buf[79] = '\0'; + + printf("%s\n", buf); + + W_WriteText(messWin[WREVIEW].window, 0, 0, W_White, buf, strlen(buf), 0); + W_WriteText(messWin[WALL].window, 0, 0, W_White, buf, strlen(buf), 0); +} + +void +sendVersion() +{ + static int version_sent = 0; + char buf[80]; + + if (!version_sent) { + version_sent = 1; + sprintf(buf, "@%s", CLIENTVERS); + pmessage(buf, me->p_no, MINDIV | MCONFIG); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emph_planet_seq.h Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,40 @@ +/* $Id: emph_planet_seq.h,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +#define emph_planet_seq_width 24 +#define emph_planet_seq_height 24 +#define emph_planet_seq_frames 5 +static char emph_planet_seq_bits[emph_planet_seq_frames][72] = {{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, + 0x00, 0x83, 0x01, 0xc0, 0x00, 0x06, 0x40, 0x00, 0x04, 0x20, 0x00, 0x08, + 0x20, 0x00, 0x08, 0x10, 0x00, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x10, + 0x10, 0x00, 0x10, 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x20, 0x00, 0x08, + 0x40, 0x00, 0x04, 0xc0, 0x00, 0x06, 0x00, 0x83, 0x01, 0x00, 0x7c, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x80, 0x01, 0x03, + 0x40, 0x00, 0x04, 0x20, 0x00, 0x08, 0x10, 0x00, 0x10, 0x10, 0x00, 0x10, + 0x08, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x20, + 0x08, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x20, 0x10, 0x00, 0x10, + 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, 0x00, 0x04, 0x80, 0x01, 0x03, +0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +{ + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x80, 0x01, 0x03, 0x40, 0x00, 0x04, + 0x20, 0x00, 0x08, 0x10, 0x00, 0x10, 0x08, 0x00, 0x20, 0x08, 0x00, 0x20, + 0x04, 0x00, 0x40, 0x04, 0x00, 0x40, 0x04, 0x00, 0x40, 0x04, 0x00, 0x40, + 0x04, 0x00, 0x40, 0x04, 0x00, 0x40, 0x04, 0x00, 0x40, 0x08, 0x00, 0x20, + 0x08, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, 0x00, 0x04, +0x80, 0x01, 0x03, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +{ + 0x00, 0xfe, 0x00, 0x80, 0x01, 0x03, 0x60, 0x00, 0x0c, 0x10, 0x00, 0x10, + 0x08, 0x00, 0x20, 0x08, 0x00, 0x20, 0x04, 0x00, 0x40, 0x04, 0x00, 0x40, + 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, + 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x04, 0x00, 0x40, + 0x04, 0x00, 0x40, 0x08, 0x00, 0x20, 0x08, 0x00, 0x20, 0x10, 0x00, 0x10, +0x60, 0x00, 0x0c, 0x80, 0x01, 0x03, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00}, +{ + 0x00, 0xff, 0x01, 0xc0, 0x00, 0x06, 0x30, 0x00, 0x18, 0x08, 0x00, 0x20, + 0x08, 0x00, 0x20, 0x04, 0x00, 0x40, 0x04, 0x00, 0x40, 0x02, 0x00, 0x80, + 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, + 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, + 0x04, 0x00, 0x40, 0x04, 0x00, 0x40, 0x08, 0x00, 0x20, 0x08, 0x00, 0x20, +0x30, 0x00, 0x18, 0xc0, 0x00, 0x06, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00}};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emph_player_seq.h Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,26 @@ +/* $Id: emph_player_seq.h,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +#define emph_player_seq_width 24 +#define emph_player_seq_height 24 +#define emph_player_seq_frames 3 +static char emph_player_seq_bits[emph_player_seq_frames][72] = {{ + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x80, 0x9c, 0x00, + 0x80, 0xff, 0x00, 0xc0, 0xc1, 0x01, 0x60, 0x00, 0x03, 0x38, 0x00, 0x0e, + 0x30, 0x00, 0x06, 0x10, 0x00, 0x04, 0x18, 0x00, 0x0c, 0x1e, 0x00, 0x3c, + 0x18, 0x00, 0x0c, 0x10, 0x00, 0x04, 0x30, 0x00, 0x06, 0x38, 0x00, 0x0e, + 0x60, 0x00, 0x03, 0xc0, 0xc1, 0x01, 0x80, 0xff, 0x00, 0x80, 0x9c, 0x00, +0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +{ + 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x40, 0x1c, 0x01, 0xc0, 0xff, 0x01, + 0xc0, 0xff, 0x01, 0xe0, 0x80, 0x03, 0x7c, 0x00, 0x1f, 0x38, 0x00, 0x0e, + 0x18, 0x00, 0x0c, 0x18, 0x00, 0x0c, 0x1c, 0x00, 0x1c, 0x1f, 0x00, 0x7c, + 0x1c, 0x00, 0x1c, 0x18, 0x00, 0x0c, 0x18, 0x00, 0x0c, 0x38, 0x00, 0x0e, + 0x7c, 0x00, 0x1f, 0xe0, 0x80, 0x03, 0xc0, 0xff, 0x01, 0xc0, 0xff, 0x01, +0x40, 0x1c, 0x01, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00}, +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emph_player_seql.h Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,38 @@ +/* $Id: emph_player_seql.h,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +#define emph_player_seql_width 30 +#define emph_player_seql_height 30 +#define emph_player_seql_frames 3 +static char emph_player_seql_bits[emph_player_seql_frames][120] = {{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x18, 0x06, 0x00, + 0x80, 0xfc, 0x4f, 0x00, 0x80, 0x0f, 0x7c, 0x00, 0xc0, 0x01, 0xe0, 0x00, + 0x60, 0x00, 0x80, 0x01, 0x38, 0x00, 0x00, 0x07, 0x30, 0x00, 0x00, 0x03, + 0x10, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x06, 0x1e, 0x00, 0x00, 0x1e, + 0x0c, 0x00, 0x00, 0x0c, 0x08, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x04, + 0x08, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x04, 0x0c, 0x00, 0x00, 0x0c, + 0x1e, 0x00, 0x00, 0x1e, 0x18, 0x00, 0x00, 0x06, 0x10, 0x00, 0x00, 0x02, + 0x30, 0x00, 0x00, 0x03, 0x38, 0x00, 0x00, 0x07, 0x60, 0x00, 0x80, 0x01, + 0xc0, 0x01, 0xe0, 0x00, 0x80, 0x0f, 0x7c, 0x00, 0x80, 0xfc, 0x4f, 0x00, +0x00, 0x18, 0x06, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}, +{ + 0x00, 0x08, 0x04, 0x00, 0x00, 0x18, 0x06, 0x00, 0x40, 0xfc, 0x8f, 0x00, + 0xc0, 0xff, 0xff, 0x00, 0xc0, 0x0f, 0xfc, 0x00, 0xe0, 0x00, 0xc0, 0x01, + 0x7c, 0x00, 0x80, 0x0f, 0x38, 0x00, 0x00, 0x07, 0x18, 0x00, 0x00, 0x06, + 0x18, 0x00, 0x00, 0x06, 0x1c, 0x00, 0x00, 0x0e, 0x1f, 0x00, 0x00, 0x3e, + 0x0e, 0x00, 0x00, 0x1c, 0x0c, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x0c, + 0x0c, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x0c, 0x0e, 0x00, 0x00, 0x1c, + 0x1f, 0x00, 0x00, 0x3e, 0x1c, 0x00, 0x00, 0x0e, 0x18, 0x00, 0x00, 0x06, + 0x18, 0x00, 0x00, 0x06, 0x38, 0x00, 0x00, 0x07, 0x7c, 0x00, 0x80, 0x0f, + 0xe0, 0x00, 0xc0, 0x01, 0xc0, 0x0f, 0xfc, 0x00, 0xc0, 0xff, 0xff, 0x00, +0x40, 0xfc, 0x8f, 0x00, 0x00, 0x18, 0x06, 0x00, 0x00, 0x08, 0x04, 0x00}, +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/enter.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,65 @@ +/* $Id: enter.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +/* + * enter.c + * + * This version modified to work as the client in a socket based protocol. + */ +#include "copyright.h" + +#include <stdio.h> +#include <sys/types.h> +#include <errno.h> +#include <pwd.h> +#include <string.h> +#include <ctype.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "proto.h" +#include "packets.h" + +/* Enter the game */ + +/* Prototypes */ + +void +enter() +{ + redrawTstats(); + delay = 0; +} + +/* Doesn't really openmem, but it will + * set some stuff up... + */ +static struct status dummy1; +static struct status2 dummy2; +void +openmem() +{ + /* players, weapons, planets are handled in build_default_configuration */ + + /* thingies allocation is handled in build_default_configuration */ + /* thingies = universe.drones; */ + + + status = &dummy1; + status2 = &dummy2; + + /* mctl->mc_current=0; */ + status->time = 1; + status->timeprod = 1; + status->kills = 1; + status->losses = 1; + status->time = 1; + status->planets = 1; + status->armsbomb = 1; + + if (ghoststart) { + me = &players[ghost_pno]; + myship = me->p_ship; + mystats = &(me->p_stats); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/expire.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,45 @@ +/* $Id: expire.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +#ifndef hpux +#include <sys/time.h> +#endif +#include <time.h> +#include <stdio.h> + + +/* Here's a handy perl script to set any timeout you want: + + perl -e 'require "timelocal.pl"; print &timelocal(0,0,0,9,9,93);' + + The arguments to timelocal are (sec, min, hours, mday, mon, year). + These are all 0 based indexing so the 7th day of the month is + really 6 to the perl script. + */ + +static time_t expire = 915091200; + +void +checkExpire(verbose) + int verbose; +{ + time_t now; + + now = time(NULL); + if (verbose) { + printf("This client expires on %s\n", ctime(&expire)); + return; + } + if (now > expire) { + printf("\ + I'm sorry. This client has expired. You may bypass the expire by\n\ +using the -o option which disables RSA authentication. Expired\n\ +clients are not supported by paradise-workers.\n\ + You can find a new set of binaries on ftp.pnetrek.org OR ftp.cs.umn.edu \n\ +in the directory /users/glamm/paradise/bin/. If you have any problems mail \n\ +to paradise-workers@pnetrek.org\n"); + exit(0); + + } else if (now + 10 * 24 * 60 * 60 > expire) { + printf("This client expires in %d days.\n", (int) (expire - now) / (60 * 60 * 24)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/feature.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,222 @@ +/* $Id: feature.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +/* + * Feature.c + * + * March, 1994. Joe Rumsey, Tedd Hadley + * + * most of the functions needed to handle SP_FEATURE/CP_FEATURE + * packets. fill in the features list below for your client, and + * add a call to reportFeatures just before the RSA response is sent. + * handleFeature should just call checkFeature, which will search the + * list and set the appropriate variable. features unknown to the + * server are set to the desired value for client features, and off + * for server/client features. + * + * feature packets look like: +struct feature_cpacket { + char type; + char feature_type; + char arg1, + arg2; + int value; + char name[80]; +}; + + * type is CP_FEATURE, which is 60. feature_spacket is identical. + */ + + +#ifdef FEATURE +#include "copyright.h" + +#include <stdio.h> +#include <sys/types.h> +#include <netinet/in.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "proto.h" +#include "packets.h" + + +void sendFeature P((char *name, int feature_type, + int value, int arg1, int arg2)); +void reportFeatures P((void)); + +/* not the actual packets: this holds a list of features to report for */ +/* this client. */ +struct feature { + char *name; + int *var; /* holds allowed/enabled status */ + char feature_type; /* 'S' or 'C' for server/client */ + int value; /* desired status */ + char *arg1, *arg2; /* where to copy args, if non-null */ +} features[] = { + /* + also sent seperately, put here for checking later. should be ok that + it's sent twice. + */ + {"FEATURE_PACKETS", &F_feature_packets, 'S', 1, 0, 0}, + + {"VIEW_BOX", &allowViewBox, 'C', 1, 0, 0}, + {"SHOW_ALL_TRACTORS", &allowShowAllTractorPressor, 'S', 1, 0, 0}, +#ifdef CONTINUOUS_MOUSE + {"CONTINUOUS_MOUSE", &allowContinuousMouse, 'C', 1, 0, 0}, +#endif + {"NEWMACRO", &F_UseNewMacro, 'C', 1, 0, 0}, + /* {"SMARTMACRO",&UseSmartMacro, 'C', 1, 0, 0}, */ + {"MULTIMACROS", &F_multiline_enabled, 'S', 1, 0, 0}, + {"WHY_DEAD", &why_dead, 'S', 1, 0, 0}, + {"CLOAK_MAXWARP", &cloakerMaxWarp, 'S', 1, 0, 0}, +/*{"DEAD_WARP", &F_dead_warp, 'S', 1, 0, 0},*/ +#ifdef RC_DISTRESS + {"RC_DISTRESS", &F_gen_distress, 'S', 1, 0, 0}, +#ifdef BEEPLITE + {"BEEPLITE", &F_allow_beeplite, 'C', 1, (char*)&F_beeplite_flags, 0}, +#endif +#endif +/* terrain features */ + {"TERRAIN", &F_terrain, 'S', 1, (char*)&F_terrain_major, (char*)&F_terrain_minor}, +/* Gzipped MOTD */ + {"GZ_MOTD", &F_gz_motd, 'S', 1, (char*)&F_gz_motd_major, (char*)&F_gz_motd_minor}, + {0, 0, 0, 0, 0, 0} +}; + +void +checkFeature(packet) + struct feature_spacket *packet; +{ + int i; + int value = ntohl(packet->value); + +#ifdef FEAT_DEBUG + if (packet->type != SP_FEATURE) { + printf("Packet type %d sent to checkFeature!\n", packet->type); + return; + } +#endif + printf("%s: %s(%d)\n", &packet->name[0], + ((value == 1) ? "ON" : (value == 0) ? "OFF" : "UNKNOWN"), + value); + + for (i = 0; features[i].name != 0; i++) { + if (strcmpi(packet->name, features[i].name) == 0) { + /* + if server returns unknown, set to off for server mods, desired + value for client mods. Otherwise, set to value from server. + */ + *features[i].var = (value == -1 ? + (features[i].feature_type == 'S' ? 0 : features[i].value) : + value); + if (features[i].arg1) + *features[i].arg1 = packet->arg1; + if (features[i].arg2) + *features[i].arg2 = packet->arg2; + break; + } + } + if (features[i].name == 0) { + printf("Feature %s from server unknown to client!\n", packet->name); + } +/* special cases: */ + if ((strcmpi(packet->name, "FEATURE_PACKETS")==0)) + reportFeatures(); + else if ((strcmpi(packet->name, "RC_DISTRESS") == 0) && F_gen_distress) + distmacro = dist_prefered; + else if ((strcmpi(packet->name, "BEEPLITE") == 0)) { + switch (value) { + case -1: /* Unknown, we can use all of the features! */ + F_beeplite_flags = LITE_PLAYERS_MAP | + LITE_PLAYERS_LOCAL | + LITE_SELF | + LITE_PLANETS | + LITE_SOUNDS | + LITE_COLOR; + break; + case 1: + if (F_beeplite_flags == 0) { /* Server says we can have + beeplite, but no + options??? must be + configured wrong. */ + F_beeplite_flags = LITE_PLAYERS_MAP | + LITE_PLAYERS_LOCAL | + LITE_SELF | + LITE_PLANETS | + LITE_SOUNDS | + LITE_COLOR; + } + if (!(F_beeplite_flags & LITE_PLAYERS_MAP)) + printf(" LITE_PLAYERS_MAP disabled\n"); + if (!(F_beeplite_flags & LITE_PLAYERS_LOCAL)) + printf(" LITE_PLAYERS_LOCAL disabled\n"); + if (!(F_beeplite_flags & LITE_SELF)) + printf(" LITE_SELF disabled\n"); + if (!(F_beeplite_flags & LITE_PLANETS)) + printf(" LITE_PLANETS disabled\n"); + if (!(F_beeplite_flags & LITE_SOUNDS)) + printf(" LITE_SOUNDS disabled\n"); + if (!(F_beeplite_flags & LITE_COLOR)) + printf(" LITE_COLOR disabled\n"); + break; + default: + break; + } + } +} + +/* call this from handleReserved */ +void +reportFeatures() +{ + struct feature *f; + + /* + Don't send features[0], which is the feature for FEATURE_PACKETS itself. + That's sent from main() + */ + for (f = &features[1]; f->name != 0; f++) { + sendFeature(f->name, + f->feature_type, + f->value, + (f->arg1 ? *f->arg1 : 0), + (f->arg2 ? *f->arg2 : 0)); +#ifdef FEAT_DEBUG + printf("(C->S) %s (%c): %d\n", f->name, f->feature_type, f->value); +#endif + } +} + +void +sendFeature(name, feature_type, value, arg1, arg2) + char *name; + int feature_type; + int value; + int arg1, arg2; +{ + struct feature_cpacket packet; + +#ifdef FEAT_DEBUG + printf( "Sending feature %s (value = %d)\n", name, value ); +#endif + strncpy(packet.name, name, sizeof(packet.name)); + packet.type = CP_FEATURE; + packet.name[sizeof(packet.name) - 1] = 0; + packet.feature_type = feature_type; + packet.value = htonl(value); + packet.arg1 = arg1; + packet.arg2 = arg2; + sendServerPacket((struct player_spacket *) & packet); +} + +void +handleFeature(packet) + struct feature_spacket *packet; +{ +#ifdef FEAT_DEBUG + printf( "Handling Feature packet\n" ); +#endif + checkFeature(packet); +} +#endif /* FEATURE */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/findslot.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,246 @@ +/* $Id: findslot.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +/* + * findslot.c + * + * Kevin Smith 03/23/88 + * + */ +#include "copyright2.h" + +#include <stdio.h> +#include <sys/types.h> +#include <errno.h> +#include <pwd.h> +#include <string.h> +#include <ctype.h> +#ifdef __STDC__ +#include <stdlib.h> +#endif +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "proto.h" + +#define WAITWIDTH 180 +#define WAITHEIGHT 60 +#define WAITTITLE 15 /* height of title for wait window */ +#define WAITICONHEIGHT 50 +#define WAITICONWIDTH 50 + +/* Prototypes */ +static void mapWaitCount P((W_Window countWin, unsigned int count)); +static void mapWaitQuit P((W_Window qwin)); +static void mapWaitWin P((W_Window waitWin)); +static void mapMotdButtonWin P((W_Window motdButtonWin)); +static void mapWaitIcon +P((W_Window waitIcon, unsigned int count, + int *motdMapLater)); + + extern int newMotdStuff; /* from newwin.c */ + + + int findslot() +{ + int oldcount = -1; + W_Window waitWin, qwin, countWin, motdButtonWin, waitIcon; + W_Event event; + int motdMapLater = 0; + + /* Wait for some kind of indication about in/not in */ + while (queuePos == -1) { + socketPause(1, 0); + if (isServerDead()) { + printf("Augh! Ghostbusted!\n"); + EXIT(0); + } + readFromServer(); + if (me != NULL) { + /* We are in! */ + printf("*** socket %d, player %d ( -s %d -G %d [-2] ) ***\n", + nextSocket, me->p_no, + nextSocket, me->p_no); + return (me->p_no); + } + } + + /* We have to wait. Make appropriate windows, etc... */ + waitWin = W_MakeWindow("wait", 0, 0, WAITWIDTH, WAITHEIGHT, NULL, (char *) 0, 2, foreColor); + countWin = W_MakeWindow("count", WAITWIDTH / 3, WAITTITLE, 2 * WAITWIDTH / 3, + WAITHEIGHT - WAITTITLE, waitWin, (char *) 0, 1, foreColor); + qwin = W_MakeWindow("waitquit", 0, WAITTITLE, WAITWIDTH / 3, + WAITHEIGHT - WAITTITLE, waitWin, (char *) 0, 1, foreColor); + motdButtonWin = W_MakeWindow("motd_select", 2 * WAITWIDTH / 3, WAITTITLE, + WAITWIDTH, WAITHEIGHT - WAITTITLE, waitWin, (char *) 0, 1, foreColor); + waitIcon = W_MakeWindow("wait_icon", 0, 0, WAITICONWIDTH, WAITICONHEIGHT, + NULL, NULL, BORDER, foreColor); + W_SetIconWindow(waitWin, waitIcon); + /* showMotdWin(); */ +#ifndef AMIGA + W_MapWindow(waitWin); + W_MapWindow(countWin); + W_MapWindow(qwin); + W_MapWindow(motdButtonWin); +#else + W_MapWindow(waitIcon); +#endif + for (;;) { + socketPause(0, 10000); + readFromServer(); + if (isServerDead()) { + printf("We've been ghostbusted!\n"); + EXIT(0); + } + if (newMotdStuff) + showMotd(motdWin); + while (W_EventsPending()) { + W_NextEvent(&event); + switch ((int) event.type) { + case W_EV_KEY: + if (event.Window == motdWin) { + motdWinEvent(event.key); + } +#ifdef AMIGA + else if (event.Window == waitIcon) { + switch (event.key) { + case 'q': + case 'Q': + printf("OK, bye!\n"); + EXIT(0); + case 'm': + case 'M': + showMotdWin(); + break; + default: + break; + } + } +#endif + case W_EV_BUTTON: /* fall through */ + if (event.Window == qwin) { + printf("OK, bye!\n"); + EXIT(0); + } else if (event.Window == motdButtonWin) { + showMotdWin(); + } else if (event.Window == waitIcon) { + mapWaitIcon(waitIcon, queuePos, NULL); + } + break; + case W_EV_EXPOSE: + if (event.Window == waitWin) { + if (motdMapLater) { + showMotd(motdWin); + motdMapLater = 0; + } + mapWaitWin(waitWin); + } else if (event.Window == qwin) { + mapWaitQuit(qwin); + } else if (event.Window == countWin) { + mapWaitCount(countWin, queuePos); + } else if (event.Window == motdWin) { + showMotd(motdWin); + } else if (event.Window == motdButtonWin) { + mapMotdButtonWin(motdButtonWin); + } else if (event.Window == waitIcon) { + mapWaitIcon(waitIcon, queuePos, &motdMapLater); + } + break; + default: + break; + } + } + if (queuePos != oldcount) { + mapWaitCount(countWin, queuePos); + mapWaitIcon(waitIcon, queuePos, NULL); + oldcount = queuePos; + } + if (me != NULL) { + W_DestroyWindow(waitWin); +#ifdef AMIGA + W_DestroyWindow(waitIcon); +#endif + printf("*** socket %d, player %d ( -s %d -G %d [-2] ) ***\n", + nextSocket, me->p_no, + nextSocket, me->p_no); + return (me->p_no); + } + } +} + +static void +mapWaitWin(waitWin) + W_Window waitWin; +{ + char *s = "Netrek: Game is full."; + + W_WriteText(waitWin, 15, 5, textColor, s, strlen(s), W_RegularFont); +} + +static void +mapWaitQuit(qwin) + W_Window qwin; +{ + char *s = "Quit"; + + W_WriteText(qwin, 15, 15, textColor, s, strlen(s), W_RegularFont); +} + +static void +mapWaitCount(countWin, count) + W_Window countWin; + unsigned int count; +{ + char *s = "Wait"; + char *t = "Queue"; + char buf[10]; + register int len; + + W_WriteText(countWin, 15, 5, textColor, s, strlen(s), W_RegularFont); + W_WriteText(countWin, 20, 15, textColor, t, strlen(t), W_RegularFont); + sprintf(buf, "%d ", count); + len = strlen(buf); + if (count == -1) + strcpy(buf, "?"); + W_WriteText(countWin, WAITWIDTH / 6 - len * W_Textwidth / 2, 25, textColor, buf, + len, W_RegularFont); +} + +static void +mapMotdButtonWin(motdButtonWin) + W_Window motdButtonWin; +{ + char *s = "MOTD"; + + W_WriteText(motdButtonWin, 15, 15, textColor, s, strlen(s), W_RegularFont); +} + +static void +mapWaitIcon(waitIcon, count, motdMapLater) + W_Window waitIcon; + unsigned int count; + int *motdMapLater; +{ + char buf[5]; + int len; + + sprintf(buf, "%d", count); + len = strlen(buf); +#ifndef AMIGA + if (motdMapLater && W_IsMapped(motdWin)) { + *motdMapLater = 1; + W_UnmapWindow(motdWin); + } + W_WriteText(waitIcon, WAITICONWIDTH / 2 - 10, W_Textheight, textColor, buf, len, + W_BigFont); +#else + + W_WriteText(waitIcon, WAITICONWIDTH / 2 - 10, W_Textheight, textColor, buf, len, + W_RegularFont); +/* using the iconWin in place of the 4 separate windows I get otherwise. -JR */ + W_WriteText(waitIcon, 0, 0, textColor, serverName, strlen(serverName), W_RegularFont); + W_WriteText(waitIcon, 0, 2 * W_Textheight, textColor, "Q to quit", 9, W_RegularFont); + W_WriteText(waitIcon, 0, 3 * W_Textheight, textColor, "M for Motd", 10, W_RegularFont); +#endif + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gameconf.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,825 @@ +/* $Id: gameconf.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <time.h> +#ifndef hpux +#include <sys/time.h> +#endif +#ifdef __STDC__ +#include <stdlib.h> +#endif + +#include "gameconf.h" +#include "defaultlogos.h" +#include "data.h" +#include "gppackets.h" + +int number_of_teams; + +struct teaminfo_s *teaminfo = 0; + +void +load_default_teams() +{ + number_of_teams = 4; + + /* independent is teaminfo[-1], allteam is teaminfo[4] */ + teaminfo = 1 + (struct teaminfo_s *) malloc(sizeof(*teaminfo) * (number_of_teams + 2)); + + strcpy(teaminfo[-1].name, "Independant"); + teaminfo[-1].letter = 'I'; + strcpy(teaminfo[-1].shortname, "IND"); + + strcpy(teaminfo[0].name, "Federation"); + teaminfo[0].letter = 'F'; + strcpy(teaminfo[0].shortname, "FED"); + + + strcpy(teaminfo[1].name, "Romulan"); + teaminfo[1].letter = 'R'; + strcpy(teaminfo[1].shortname, "ROM"); + + + strcpy(teaminfo[2].name, "Klingon"); + teaminfo[2].letter = 'K'; + strcpy(teaminfo[2].shortname, "KLI"); + + + strcpy(teaminfo[3].name, "Orion"); + teaminfo[3].letter = 'O'; + strcpy(teaminfo[3].shortname, "ORI"); + + strcpy(teaminfo[4].name, "None"); + teaminfo[4].letter = '-'; + strcpy(teaminfo[4].shortname, "NON"); +} + +void +load_default_teamlogos() +{ + if (number_of_teams < 1) + return; + teaminfo[0].shield_logo = W_StoreBitmap(fedshield_width, fedshield_height, + fedshield_bits, teamWin[0]); + if (number_of_teams < 2) + return; + teaminfo[1].shield_logo = W_StoreBitmap(romshield_width, romshield_height, + romshield_bits, teamWin[1]); + if (number_of_teams < 3) + return; + teaminfo[2].shield_logo = W_StoreBitmap(klishield_width, klishield_height, + klishield_bits, teamWin[2]); + if (number_of_teams < 4) + return; + teaminfo[3].shield_logo = W_StoreBitmap(orishield_width, orishield_height, + orishield_bits, teamWin[3]); +} + +void +load_generic_teams() +{ + /* + reserved letters: A G T + */ + int i; + + /* independent is teaminfo[-1] */ + teaminfo = 1 + (struct teaminfo_s *) malloc(sizeof(*teaminfo) * (number_of_teams + 1)); + + strcpy(teaminfo[-1].name, "Independant"); + teaminfo[-1].letter = 'I'; + strcpy(teaminfo[-1].shortname, "IND"); + + load_default_teamlogos(); /* loads the first 4 team logos */ + + for (i = 0; i < number_of_teams; i++) { + sprintf(teaminfo[i].name, "Team #%d", i); + teaminfo[i].letter = 'J' + i; /* I, J through P */ + sprintf(teaminfo[i].shortname, "T%02d", i); + +#if 0 + /* we should draw something nifty here */ + if (i >= 4) /* the first 4 have been loaded already. */ + teaminfo[i].shield_logo = W_StoreBitmap(1, 1, &i, teamWin[i]); + /* XXX uh-oh if more than 4 teams */ + +/* exactly. If there are more than 4 teams the above will SEGV because + of the &i (which should be a char * bitmap array). +*/ +#endif + + } +} + +void +initialize_thingies() +{ + int i; + int n = (npthingies * nplayers + ngthingies); + thingies = (struct thingy *) malloc(sizeof(*thingies) * n); + for (i = 0; i < n; i++) { + thingies[i].t_shape = SHP_BLANK; + thingies[i].t_no = i; + thingies[i].t_owner = (i >= npthingies * nplayers) ? -1 : (i / npthingies); + } +} + +void +initialize_players() +{ + int i; + + players = (struct player *) malloc(sizeof(*players) * nplayers); + + bzero(players, sizeof(struct player) * nplayers); + + for (i = 0; i < nplayers; i++) { + players[i].p_status = PFREE; + players[i].p_cloakphase = 0; + players[i].p_no = i; + players[i].p_ntorp = 0; + players[i].p_ndrone = 0;/* TSH */ + players[i].p_explode = 1; + players[i].p_stats.st_tticks = 1; + players[i].p_ship = shiptypes->ship; + } +} + +void +initialize_torps() +{ + int i; + + torps = (struct torp *) malloc(sizeof(*torps) * nplayers * ntorps); + + for (i = 0; i < nplayers * ntorps; i++) { + torps[i].t_status = TFREE; + torps[i].t_no = i; + torps[i].t_owner = (i / ntorps); + } +} + +void +initialize_plasmas() +{ + int i; + + plasmatorps = (struct plasmatorp *) malloc(sizeof(*plasmatorps) * nplayers * nplasmas); + + for (i = 0; i < nplayers * nplasmas; i++) { + plasmatorps[i].pt_status = PTFREE; + plasmatorps[i].pt_no = i; + plasmatorps[i].pt_owner = (i / nplasmas); + } +} + +void +initialize_phasers() +{ + int i; + + phasers = (struct phaser *) malloc(sizeof(*phasers) * nplayers * nphasers); + + for (i = 0; i < nplayers * nphasers; i++) { + phasers[i].ph_status = PHFREE; + phasers[i].ph_fuse = 0; + } +} + +void +initialize_planets() +{ + int i; + + planets = (struct planet *) malloc(sizeof(*planets) * nplanets); + + for (i = 0; i < nplanets; i++) { + struct planet *curr = &planets[i]; + curr->pl_no = i; + curr->pl_flags = 0; + curr->pl_owner = 0; + curr->pl_x = curr->pl_y = -10000; + sprintf(curr->pl_name, "planet%d", i); + curr->pl_namelen = strlen(curr->pl_name); + curr->pl_armies = 0; + curr->pl_info = 0; + curr->pl_deadtime = 0; + curr->pl_couptime = 0; + curr->pl_timestamp = 0; + + /* initialize planet redraw for moving planets */ + pl_update[i].plu_update = -1; + } +} + +void +init_ranks() +{ + ranks2 = (struct rank2 *) malloc(sizeof(*ranks2) * nranks2); + ranks2[0].genocides = 0; + ranks2[0].di = 0; + ranks2[0].battle = 0.0; + ranks2[0].strategy = 0.0; + ranks2[0].specship = 0.0; + ranks2[0].name = strdup("Recruit"); + + ranks2[1].genocides = 1; + ranks2[1].di = 10; + ranks2[1].battle = 0.30; + ranks2[1].strategy = 0.3; + ranks2[1].specship = 0.0; + ranks2[1].name = strdup("Specialist"); + + ranks2[2].genocides = 2; + ranks2[2].di = 25; + ranks2[2].battle = 0.40; + ranks2[2].strategy = 0.6; + ranks2[2].specship = 0.0; + ranks2[2].name = strdup("Cadet"); + + ranks2[3].genocides = 3; + ranks2[3].di = 45; + ranks2[3].battle = 0.50; + ranks2[3].strategy = 0.9; + ranks2[3].specship = 0.0; + ranks2[3].name = strdup("Midshipman"); + + ranks2[4].genocides = 4; + ranks2[4].di = 70; + ranks2[4].battle = 0.70; + ranks2[4].strategy = 1.2; + ranks2[4].specship = 0.0; + ranks2[4].name = strdup("Ensn. J.G."); + + ranks2[5].genocides = 5; + ranks2[5].di = 100; + ranks2[5].battle = 0.90; + ranks2[5].strategy = 1.5; + ranks2[5].specship = 0.0; + ranks2[5].name = strdup("Ensign"); + + ranks2[6].genocides = 6; + ranks2[6].di = 140; + ranks2[6].battle = 1.10; + ranks2[6].strategy = 2.0; + ranks2[6].specship = 0.0; + ranks2[6].name = strdup("Lt. J.G."); + + ranks2[7].genocides = 8; + ranks2[7].di = 190; + ranks2[7].battle = 1.30; + ranks2[7].strategy = 2.5; + ranks2[7].specship = 0.0; + ranks2[7].name = strdup("Lieutenant"); + + ranks2[8].genocides = 10; + ranks2[8].di = 250; + ranks2[8].battle = 1.50; + ranks2[8].strategy = 3.0; + ranks2[8].specship = 0.5; + ranks2[8].name = strdup("Lt. Cmdr."); + + ranks2[9].genocides = 15; + ranks2[9].di = 300; + ranks2[9].battle = 1.80; + ranks2[9].strategy = 3.5; + ranks2[9].specship = 0.7; + ranks2[9].name = strdup("Commander"); + + ranks2[10].genocides = 18; + ranks2[10].di = 350; + ranks2[10].battle = 2.00; + ranks2[10].strategy = 4.0; + ranks2[10].specship = 1.0; + ranks2[10].name = strdup("Captain"); + + ranks2[11].genocides = 25; + ranks2[11].di = 400; + ranks2[11].battle = 2.10; + ranks2[11].strategy = 4.3; + ranks2[11].specship = 2.5; + ranks2[11].name = strdup("Fleet Capt."); + + ranks2[12].genocides = 50; + ranks2[12].di = 500; + ranks2[12].battle = 2.15; + ranks2[12].strategy = 4.8; + ranks2[12].specship = 3.0; + ranks2[12].name = strdup("Commodore"); + + ranks2[13].genocides = 75; + ranks2[13].di = 700; + ranks2[13].battle = 2.20; + ranks2[13].strategy = 5.3; + ranks2[13].specship = 3.3; + ranks2[13].name = strdup("Moff"); + + ranks2[14].genocides = 100; + ranks2[14].di = 900; + ranks2[14].battle = 2.25; + ranks2[14].strategy = 5.7; + ranks2[14].specship = 3.6; + ranks2[14].name = strdup("Grand Moff"); + + ranks2[15].genocides = 300; + ranks2[15].di = 1200; + ranks2[15].battle = 2.30; + ranks2[15].strategy = 6.0; + ranks2[15].specship = 3.8; + ranks2[15].name = strdup("Rear Adml."); + + ranks2[16].genocides = 700; + ranks2[16].di = 1700; + ranks2[16].battle = 2.35; + ranks2[16].strategy = 6.1; + ranks2[16].specship = 4.0; + ranks2[16].name = strdup("Admiral"); + + ranks2[17].genocides = 1000; + ranks2[17].di = 2500; + ranks2[17].battle = 2.40; + ranks2[17].strategy = 6.2; + ranks2[17].specship = 4.2; + ranks2[17].name = strdup("Grand Adml."); +} + +void +init_royal() +{ + royal = (struct royalty *) malloc(sizeof(*royal) * nroyals); + + royal[0].name = strdup("none"); + royal[1].name = strdup("Wesley"); + royal[2].name = strdup("Centurion"); + royal[3].name = strdup("Praetor"); + royal[4].name = strdup("Emperor"); +#if 0 + royal[5].name = strdup("Wizard"); + royal[6].name = strdup("Duke"); + royal[7].name = strdup("Count"); + royal[8].name = strdup("Baron"); + royal[9].name = strdup("Knight"); + royal[10].name = strdup("Dread"); + royal[11].name = strdup("Lord of Destruction"); + royal[12].name = strdup("BlitzMeister"); + royal[13].name = strdup("Hitler"); + royal[14].name = strdup("Terminator"); + royal[15].name = strdup("Kamikaze"); + royal[16].name = strdup("Speed Kamikaze"); + royal[17].name = strdup("Carpet Bomber"); + royal[18].name = strdup("NukeMeister"); + royal[19].name = strdup("Terrorist"); + royal[20].name = strdup("Democrat"); + royal[21].name = strdup("Executioner"); + royal[22].name = strdup("DooshMeister"); + royal[23].name = strdup("Diplomat"); + royal[24].name = strdup("speed Diplomat"); + royal[25].name = strdup("Addict"); +#endif /* 0 */ +} + +void +reinit_ranks() +{ + int i; + ranks2 = (struct rank2 *) malloc(sizeof(*ranks2) * nranks2); + + for (i = 0; i < nranks2; i++) { + ranks2[i].name = strdup("blank"); + } +} + +void +reinit_royal() +{ + int i; + royal = (struct royalty *) malloc(sizeof(*royal) * nroyals); + + for (i = 0; i < nroyals; i++) { + royal[i].name = strdup("blank"); + } +} + + +void +resize_players() +{ + int me_no; + + if (me) + me_no = me->p_no; + players = (struct player *) realloc(players, sizeof(*players) * nplayers); + if (me) { + me = &players[me_no]; + myship = me->p_ship; + } +} + +void +free_teams() +{ + int i; + for (i = 0; i < number_of_teams; i++) { + W_FreeBitmap(teaminfo[i].shield_logo); + } + /* we offsetted by 1 to make room for IND */ + free(teaminfo - 1); + teaminfo = 0; +} + +void +free_torps() +{ + free(torps); + torps = 0; +} + +void +free_phasers() +{ + free(phasers); + phasers = 0; +} + +void +free_plasmas() +{ + free(plasmatorps); + plasmatorps = 0; +} + +void +free_thingies() +{ + free(thingies); + thingies = 0; +} + +void +free_ranks() +{ + int i; + for (i = 0; i < nranks2; i++) + if (ranks2[i].name) + free(ranks2[i].name); + free(ranks2); + ranks2 = 0; +} + +void +free_royal() +{ + int i; + for (i = 0; i < nroyals; i++) + if (royal[i].name) + free(royal[i].name); + + free(royal); + royal = 0; +} + +/* + */ + +void +build_default_configuration() +{ + load_default_teams(); + /* can't load logos until we have some windows */ + + init_shiptypes(); + initialize_players(); + initialize_torps(); + initialize_thingies(); + initialize_plasmas(); + initialize_planets(); + initialize_phasers(); + + + init_ranks(); + init_royal(); +} + +/* + */ + + +int +compute_gameparam_size(buf) + char *buf; +{ + struct gameparam_spacket *pkt = (struct gameparam_spacket *) buf; + + if (*buf != SP_GPARAM) + return -1; + + switch (pkt->subtype) { + case 0: + return sizeof(struct gp_sizes_spacket); + case 1: + return sizeof(struct gp_team_spacket); + case 2: + return sizeof(struct gp_teamlogo_spacket); + case 3: + return sizeof(struct gp_shipshape_spacket); + case 4: + return sizeof(struct gp_shipbitmap_spacket); + case 5: + return sizeof(struct gp_rank_spacket); + case 6: + return sizeof(struct gp_royal_spacket); + case 7: + return sizeof(struct gp_teamplanet_spacket); + default: + return -1; + } +} + +void +handleGPsizes(pkt) + struct gp_sizes_spacket *pkt; +{ + free_ranks(); + free_royal(); + + free_teams(); + free_torps(); + free_phasers(); + free_plasmas(); + free_thingies(); + + free_shipshapes(); + + nplayers = pkt->nplayers; + number_of_teams = pkt->nteams; + /* shiptypes */ + nranks2 = pkt->nranks; + nroyals = pkt->nroyal; + nphasers = pkt->nphasers; + ntorps = pkt->ntorps; + nplasmas = pkt->nplasmas; + npthingies = pkt->nthingies; + ngthingies = pkt->gthingies; + + /* gwidth */ + /* flags */ + + load_generic_teams(); + + reinit_ranks(); + reinit_royal(); + + resize_players(); + initialize_torps(); + initialize_phasers(); + initialize_plasmas(); + initialize_thingies(); + + slurp_ship_bitmaps(); +} + +void +handleGPteam(pkt) + struct gp_team_spacket *pkt; +{ + struct teaminfo_s *currteam; + + if ((int) pkt->index >= number_of_teams) { + fprintf(stderr, "Team #%d %s is out of range (0..%d)\n", pkt->index, + pkt->teamname, number_of_teams); + return; + } + currteam = &teaminfo[pkt->index]; + + currteam->letter = pkt->letter; + + strncpy(currteam->shortname, pkt->shortname, 3); + currteam->shortname[3] = 0; + + strncpy(currteam->name, pkt->teamname, sizeof(currteam->name) - 1); + currteam->name[sizeof(currteam->name) - 1] = 0;; +} + +void +handleGPteamlogo(pkt) + struct gp_teamlogo_spacket *pkt; +{ + static char buf[13 * 99]; /* 99x99 */ + static int curr_height = 0; + static int lwidth, lheight; + static int teamindex; + int pwidth; + + if ((unsigned) pkt->teamindex >= number_of_teams) { + fprintf(stderr, "Team #%d is out of range (0..%d)\n", pkt->teamindex, + number_of_teams); + return; + } + if (pkt->y != curr_height) { + fprintf(stderr, "Bad gp_teamlogo packet sequence y(%d) != curr_height(%d)\n", + pkt->y, curr_height); + curr_height = 0; + return; + } + if (curr_height) { + if (lwidth != pkt->logowidth || lheight != pkt->logoheight || + teamindex != pkt->teamindex) { + fprintf(stderr, "gp_teamlogo packet sequence error, %d!=%d || %d!=%d || %d!=%d\n", + lwidth, pkt->logowidth, lheight, pkt->logoheight, + teamindex, pkt->teamindex); + curr_height = 0; + return; + } + } else { + teamindex = pkt->teamindex; + lwidth = pkt->logowidth; + lheight = pkt->logoheight; + if (lwidth > 99 || lheight > 99) { + fprintf(stderr, "logo too big (%dx%d), rejecting\n", lwidth, lheight); + curr_height = 0; + return; + } + } + pwidth = (lwidth - 1) / 8 + 1; + memcpy(buf + pwidth * curr_height, pkt->data, pwidth * pkt->thisheight); + curr_height += pkt->thisheight; + + if (curr_height >= lheight) { + W_FreeBitmap(teaminfo[teamindex].shield_logo); + teaminfo[teamindex].shield_logo = W_StoreBitmap(lwidth, lheight, buf, + teamWin[teamindex]); + curr_height = 0; + } +} + +void +handleGPshipshape(pkt) + struct gp_shipshape_spacket *pkt; +{ + if (pkt->race < -1 || pkt->race >= number_of_teams) { + fprintf(stderr, "race #%d out of range (-1..%d)\n", pkt->race, + number_of_teams - 1); + return; + } + if ( /* pkt->shipno<0 || */ (int) pkt->shipno >= nshiptypes) { + fprintf(stderr, "ship class #%d out of range (0..%d)\n", pkt->shipno, + nshiptypes - 1); + return; + } + replace_shipshape(pkt->race, pkt->shipno, pkt->nviews, + pkt->width, pkt->height); +} + +void +handleGPshipbitmap(pkt) + struct gp_shipbitmap_spacket *pkt; +{ + if (pkt->race < -1 || pkt->race >= number_of_teams) { + fprintf(stderr, "race #%d out of range (-1..%d)\n", pkt->race, + number_of_teams - 1); + return; + } + if ( /* pkt->shipno<0 || */ (int) pkt->shipno >= nshiptypes) { + fprintf(stderr, "ship class #%d out of range (0..%d)\n", pkt->shipno, + nshiptypes - 1); + return; + } + replace_ship_bitmap(pkt->race, pkt->shipno, pkt->thisview, pkt->bitmapdata); +} + +void +handleGPrank(pkt) + struct gp_rank_spacket *pkt; +{ + struct rank2 *curr; + if (pkt->rankn >= nranks2) { + fprintf(stderr, "rank #%d %s out of range (0..%d)\n", pkt->rankn, + pkt->name, nranks2 - 1); + return; + } + curr = &ranks2[pkt->rankn]; + free(curr->name); + + curr->genocides = htonl(pkt->genocides); + curr->di = htonl(pkt->milliDI) / 1000.0; + curr->battle = htonl(pkt->millibattle) / 1000.0; + curr->strategy = htonl(pkt->millistrat) / 1000.0; + curr->specship = htonl(pkt->millispec) / 1000.0; + curr->name = strdup(pkt->name); +} + +void +handleGProyal(pkt) + struct gp_royal_spacket *pkt; +{ + if ((int) pkt->rankn >= nroyals) { + fprintf(stderr, "Royalty #%d %s out of range (0..%d)\n", pkt->rankn, + pkt->name, nroyals - 1); + return; + } + free(royal[pkt->rankn].name); + royal[pkt->rankn].name = strdup(pkt->name); +} + +static unsigned char mplanet_bits[] = { + 0xe0, 0x03, 0x18, 0x0c, 0x04, 0x10, 0x02, 0x20, 0x02, 0x20, 0x01, 0x40, + 0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x02, 0x20, 0x02, 0x20, +0x04, 0x10, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00}; +static unsigned char planet_bits[] = { + 0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x00, 0x60, 0x00, + 0x20, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, + 0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x08, + 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x10, + 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, + 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, + 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, + 0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x02, + 0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0, 0x00, 0x60, 0x00, +0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; + +void +handleGPteamplanet(pkt) + struct gp_teamplanet_spacket *pkt; +{ + { +#define TACTICALSIZE sizeof(pkt->tactical) + unsigned char tactical[TACTICALSIZE]; + int i; + int race = pkt->teamn; + + if (race < -1 || race >= number_of_teams) { + fprintf(stderr, "race #%d out of range (-1..%d)\n", race, + number_of_teams - 1); + return; + } + for (i = 0; i < TACTICALSIZE; i++) { + tactical[i] = (pkt->tactical[i] & pkt->tacticalM[i]) | + (planet_bits[i] & ~pkt->tacticalM[i]); + } + + W_FreeBitmap(bplanets[race + 1]); + bplanets[race + 1] = W_StoreBitmap(30, 30, tactical, w); + +#undef TACTICALSIZE + } + + { +#define GALACTICSIZE sizeof(pkt->galactic) + unsigned char galactic[GALACTICSIZE]; + int i; + int race = pkt->teamn; + + if (race < -1 || race >= number_of_teams) { + fprintf(stderr, "race #%d out of range (-1..%d)\n", race, + number_of_teams - 1); + return; + } + for (i = 0; i < GALACTICSIZE; i++) { + galactic[i] = (pkt->galactic[i] & pkt->galacticM[i]) | + (mplanet_bits[i] & ~pkt->galacticM[i]); + } + + W_FreeBitmap(mbplanets[race + 1]); + mbplanets[race + 1] = W_StoreBitmap(16, 16, galactic, mapw); + +#undef GALACTICSIZE + } +} + +void +handleGameparams(pkt) + struct gameparam_spacket *pkt; +{ + switch (pkt->subtype) { + case 0: + handleGPsizes((struct gp_sizes_spacket *) pkt); + break; + case 1: + handleGPteam((struct gp_team_spacket *) pkt); + break; + case 2: + handleGPteamlogo((struct gp_teamlogo_spacket *) pkt); + break; + case 3: + handleGPshipshape((struct gp_shipshape_spacket *) pkt); + break; + case 4: + handleGPshipbitmap((struct gp_shipbitmap_spacket *) pkt); + break; + case 5: + handleGPrank((struct gp_rank_spacket *) pkt); + break; + case 6: + handleGProyal((struct gp_royal_spacket *) pkt); + break; + case 7: + handleGPteamplanet((struct gp_teamplanet_spacket *) pkt); + break; + default: + fprintf(stderr, "Gameparams packet subtype %d not yet implemented\n", + pkt->subtype); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gameconf.h Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,29 @@ +/* $Id: gameconf.h,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +/* + this header declares declares variables for much information that + used to be constant. + */ + +#ifndef gameconf_h_ +#define gameconf_h_ + +#include "Wlib.h" +#include "proto.h" + +extern struct teaminfo_s { + char name[32]; /* this is not meant to limit the length of + team names */ + W_Icon shield_logo; /* logo that appears in the team choice + window */ + char letter; /* 1-letter abbreviation */ + char shortname[4]; /* 3-letter abbreviation */ +} *teaminfo; + +extern int number_of_teams; + +struct gameparam_spacket; + +void handleGameparams P((struct gameparam_spacket *)); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/getname.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,429 @@ +/* $Id: getname.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +/* + * getname.c + * + * Kevin P. Smith 09/28/88 + * + */ +#include "copyright2.h" + +#include <stdio.h> +#ifdef __STDC__ +#include <stdlib.h> +#include <unistd.h> +#endif +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/file.h> +#include <errno.h> +#include <pwd.h> +#include <string.h> +#include <ctype.h> +#include <time.h> +#ifndef hpux +#include <sys/time.h> +#endif +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "proto.h" + +static char tempname[16]; +static char password1[16]; +static char password2[16]; +static int state, autolog; +static char username[32] = "****"; +#define ST_GETNAME 0 +#define ST_GETPASS 1 +#define ST_MAKEPASS1 2 +#define ST_MAKEPASS2 3 +#define ST_DONE 4 + +/* Prototypes */ +static void adjustString P((int ch, char *str, char *defname)); +static void checkpassword P((void)); +static void displayStartup P((char *defname)); +static void loaddude P((void)); +static void makeNewGuy P((void)); +static void loginproced P((int ch, char *defname)); + +void +noautologin() +{ + char *tempstr; + + autolog = 0; + *defpasswd = *password1 = *password2 = '\0'; + tempstr = "Automatic login failed"; + W_WriteText(w, 100, 100, textColor, tempstr, strlen(tempstr), + W_BoldFont); +} + +void +getname(defname, defpasswd) + char *defname, *defpasswd; +/* Let person identify themselves from w */ +{ + W_Event event; + register ch = 0; + int secondsLeft = 99, laststate; + char tempstr[40]; + long lasttime; + register int j; + +#ifdef RECORDER + if (playback) + return; +#endif + autolog = (*defpasswd && *defname) ? 1 : 0; + + { + struct passwd *passwd; + + passwd = getpwuid(getuid()); + if (passwd) /* believe it or not, getpwuid failed on me - + RF */ + strcpy(username, passwd->pw_name); + } + + bzero(mystats, sizeof(struct stats)); + mystats->st_tticks = 1; + mystats->st_flags = + (ST_NOBITMAPS * (!sendmotdbitmaps) + + ST_KEEPPEACE * keeppeace + + 0); + lasttime = time(NULL); + + if (ghoststart) + return; + + tempname[0] = '\0'; + password1[0] = '\0'; + password2[0] = '\0'; + laststate = state = ST_GETNAME; + displayStartup(defname); + for (;;) { + if (isServerDead()) { + printf("Ack! We've been ghostbusted!\n"); +#ifdef AUTOKEY + if (autoKey) + W_AutoRepeatOn(); +#endif + EXIT(0); + } + if (lasttime != time(NULL)) { + lasttime++; + secondsLeft--; + if (!autolog) { + sprintf(tempstr, "Seconds to go: %d ", secondsLeft); + W_WriteText(w, 150, 400, textColor, tempstr, strlen(tempstr), + W_BoldFont); + } + if (secondsLeft == 0) { + me->p_status = PFREE; + printf("Auto-Quit\n"); +#ifdef AUTOKEY + if (autoKey) + W_AutoRepeatOn(); +#endif + EXIT(0); + } + } + if (state == ST_DONE) { + W_ClearWindow(w); + return; + } + readFromServer(); /* Just in case it wants to say something */ + + if (autolog) { + switch (state) { + case ST_GETNAME: + tempname[0] = '\0'; + ch = 13; + j = 0; + break; + + case ST_GETPASS: + case ST_MAKEPASS1: + case ST_MAKEPASS2: + ch = defpasswd[j++]; + if (ch == '\0') { + j = 0; + ch = 13; + } + break; + + default: + break; + } + + loginproced(ch, defname); + + } + laststate = state; + + if (!W_EventsPending()) + continue; + W_NextEvent(&event); + if (event.Window != w) + continue; + switch ((int) event.type) { + case W_EV_EXPOSE: + displayStartup(defname); + break; + case W_EV_KEY: + ch = event.key; + if (!autolog) + loginproced(ch, defname); + } + } +} + + +static +void +loginproced(ch, defname) + int ch; + char *defname; +{ + if (ch > 255) + ch -= 256; /* was alt key, ignore it */ + if (ch == 10) + ch = 13; + if ((ch == ('d' + 128) || ch == ('D' + 128)) && state == ST_GETNAME && *tempname == '\0') { +#ifdef AUTOKEY + if (autoKey) + W_AutoRepeatOn(); +#endif + EXIT(0); + } + if ((ch < 32 || ch > 127) && ch != 21 && ch != 13 && ch != 8) + return; + switch (state) { + case ST_GETNAME: + if (ch == 13) { + if (*tempname == '\0') { + strcpy(tempname, defname); + } + loaddude(); + displayStartup(defname); + } else { + adjustString(ch, tempname, defname); + } + break; + case ST_GETPASS: + if (ch == 13) { + checkpassword(); + displayStartup(defname); + } else { + adjustString(ch, password1, defname); + } + break; + case ST_MAKEPASS1: + if (ch == 13) { + state = ST_MAKEPASS2; + displayStartup(defname); + } else { + adjustString(ch, password1, defname); + } + break; + case ST_MAKEPASS2: + if (ch == 13) { + makeNewGuy(); + displayStartup(defname); + } else { + adjustString(ch, password2, defname); + } + break; + } +} + +static void +loaddude() +/* Query dude. + */ +{ + if (strcmp(tempname, "Guest") == 0 || strcmp(tempname, "guest") == 0) { + loginAccept = -1; + sendLoginReq(tempname, "", username, 0); + state = ST_DONE; + me->p_pos = -1; + me->p_stats.st_tticks = 1; /* prevent overflow */ + strcpy(me->p_name, tempname); + while (loginAccept == -1) { + socketPause(1, 0); + readFromServer(); + if (isServerDead()) { + printf("Server is dead!\n"); +#ifdef AUTOKEY + if (autoKey) + W_AutoRepeatOn(); +#endif + + EXIT(0); + } + } + if (loginAccept == 0) { + printf("Hmmm... The SOB server won't let me log in as guest!\n"); +#ifdef AUTOKEY + if (autoKey) + W_AutoRepeatOn(); +#endif + + EXIT(0); + } + return; + } + /* Ask about the user */ + loginAccept = -1; + sendLoginReq(tempname, "", username, 1); + while (loginAccept == -1) { + socketPause(1, 0); + readFromServer(); + if (isServerDead()) { + printf("Server is dead!\n"); +#ifdef AUTOKEY + if (autoKey) + W_AutoRepeatOn(); +#endif + + EXIT(0); + } + } + *password1 = *password2 = 0; + if (loginAccept == 0) { + state = ST_MAKEPASS1; + } else { + state = ST_GETPASS; + } +} + +static void +checkpassword() +/* Check dude's password. + * If he is ok, move to state ST_DONE. + */ +{ + char *s; + + sendLoginReq(tempname, password1, username, 0); + loginAccept = -1; + while (loginAccept == -1) { + socketPause(1, 0); + readFromServer(); + if (isServerDead()) { + printf("Server is dead!\n"); +#ifdef AUTOKEY + if (autoKey) + W_AutoRepeatOn(); +#endif + + EXIT(0); + } + } + if (loginAccept == 0) { + if (!autolog) { + s = "Bad password!"; + W_WriteText(w, 100, 100, textColor, s, strlen(s), W_BoldFont); + (void) W_EventsPending(); + sleep(3); + W_ClearWindow(w); + } else + noautologin(); + *tempname = 0; + state = ST_GETNAME; + return; + } + strcpy(me->p_name, tempname); + sendmotdbitmaps = !((me->p_stats.st_flags / ST_NOBITMAPS) & 1); + keeppeace = (me->p_stats.st_flags / ST_KEEPPEACE) & 1; + state = ST_DONE; +} + +static void +makeNewGuy() +/* Make the dude with name tempname and password password1. + * Move to state ST_DONE. + */ +{ + char *s; + + if (strcmp(password1, password2) != 0) { + if (!autolog) { + s = "Passwords do not match"; + W_WriteText(w, 100, 120, textColor, s, strlen(s), W_BoldFont); + (void) W_EventsPending(); + sleep(3); + W_ClearWindow(w); + } else + noautologin(); + *tempname = 0; + state = ST_GETNAME; + return; + } + /* same routine! */ + checkpassword(); +} + +static void +adjustString(ch, str, defname) + char ch, *str; + char *defname; +{ + if (ch == 21) { + *str = '\0'; + if (state == ST_GETNAME) + displayStartup(defname); + } else if (ch == 8 || ch == '\177') { + if ((int) strlen(str) > 0) { + str[strlen(str) - 1] = '\0'; + if (state == ST_GETNAME) + displayStartup(defname); + } + } else { + if (strlen(str) == 15) + return; + str[strlen(str) + 1] = '\0'; + str[strlen(str)] = ch; + if (state == ST_GETNAME) + displayStartup(defname); + } +} + +static void +displayStartup(defname) + char *defname; +/* Draws entry screen based upon state. */ +{ + char s[100]; + char *t; + + if (state == ST_DONE || autolog) + return; + t = "Enter your name. Use the name 'guest' to remain anonymous."; + W_WriteText(w, 100, 30, textColor, t, strlen(t), W_BoldFont); + t = "Type ^D (Ctrl - D) to quit."; + W_WriteText(w, 100, 40, textColor, t, strlen(t), W_BoldFont); + sprintf(s, "Your name (default = %s): %s ", defname, tempname); + W_WriteText(w, 100, 50, textColor, s, strlen(s), W_BoldFont); + if (state == ST_GETPASS) { + t = "Enter password: "; + W_WriteText(w, 100, 60, textColor, t, strlen(t), W_BoldFont); + } + if (state > ST_GETPASS) { + t = "You need to make a password."; + W_WriteText(w, 100, 70, textColor, t, strlen(t), W_BoldFont); + t = "So think of a password you can remember, and enter it."; + W_WriteText(w, 100, 80, textColor, t, strlen(t), W_BoldFont); + t = "What is your password? :"; + W_WriteText(w, 100, 90, textColor, t, strlen(t), W_BoldFont); + } + if (state == ST_MAKEPASS2) { + t = "Enter it again to make sure you typed it right."; + W_WriteText(w, 100, 100, textColor, t, strlen(t), W_BoldFont); + t = "Your password? :"; + W_WriteText(w, 100, 110, textColor, t, strlen(t), W_BoldFont); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/getship.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,395 @@ +/* $Id: getship.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +/* + * getship.c for client of socket protocol. + * + * This file has been mangled so it only sets the ship characteristics needed. + */ +#include "copyright.h" + +#include <stdio.h> +#ifdef __STDC__ +#include <stdlib.h> +#endif +#include <sys/types.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "proto.h" + +/* Prototypes */ +static void getship_default P((struct ship * shipp, int s_type)); + +void +init_shiptypes() +{ + int i; + struct shiplist *temp; + + /* start at -1, the default shiptype */ + for (i = -1; i < nshiptypes; i++) { + temp = (struct shiplist *) malloc(sizeof(struct shiplist)); + temp->ship = (struct ship *) malloc(sizeof(struct ship)); + getship_default(temp->ship, i); + temp->next = shiptypes; + if (temp->next) + temp->next->prev = temp; + temp->prev = NULL; + shiptypes = temp; + } +} + +void +init_galaxy_class() +{ + /* + hack to allow galaxy class ships. By the time the client knows it's + connected to a paradise server, the defaults must already have been + run. [BDyess] + */ + struct shiplist *temp; + + for (temp = shiptypes; temp->ship->s_type != GALAXY; temp = temp->next) + /* null body */ ; + getship_default(temp->ship, GALAXY); + + /* slurp_ship_bitmaps(); */ /* don't destroy downloaded bitmaps */ + + return; +} + +#if 0 +void +init_puck() +{ + /* ditto above init_galaxy_class(), but this time for hockey and puck. + [BDyess] */ + struct shiplist *temp; + + temp = shiptypes; + while(temp->next) temp = temp->next; + temp->next = (struct shiplist*)malloc(sizeof(struct shiplist)); + temp = temp->next; + temp->ship = (struct ship*)malloc(sizeof(struct ship)); + getship_default(temp->ship, PUCK); + temp->next = NULL; + + slurp_ship_bitmaps(); + + return; +} +#endif /*0*/ + +/* now returns a pointer to where the ship data is located. This way + if the data is later changed by the server everybody gets updated. + Plus as a bonus it's more efficient :) [Bill Dyess] */ +struct ship * +getship(s_type) + int s_type; +{ + struct shiplist *temp, *new; + + temp = shiptypes; + while (temp) { + if (temp->ship->s_type == s_type) { + /* bcopy(temp->ship, shipp, sizeof(struct ship)); */ + return temp->ship; + } + temp = temp->next; + } + /* + ok, that shiptype is unheard of. Assume a new shiptype, and get the + values for CA. Also add the ship to the list so if it gets updated by + the server later everyone stays happy. [Bill Dyess] + */ + printf("Error: getship of unknown ship type %d, using CA defaults\n", s_type); + temp = shiptypes; + while (temp) { + if (temp->ship->s_type == DEFAULT) { + printf("Adding ship type %d\n", s_type); + /* bcopy(temp->ship, shipp, sizeof(struct ship)); */ + /* now add the new ship to the list */ + new = (struct shiplist *) malloc(sizeof(struct shiplist)); + new->ship = (struct ship *) malloc(sizeof(struct ship)); + new->next = shiptypes; + new->prev = NULL; + if (shiptypes) + shiptypes->prev = new; + shiptypes = new; + bcopy(temp->ship, new->ship, sizeof(struct ship)); + new->ship->s_type = s_type; + return new->ship; + } + temp = temp->next; + } + return temp->ship; + +} + +/* fill in ship characteristics */ + +static void +getship_default(shipp, s_type) + struct ship *shipp; + int s_type; +{ + switch (s_type) { + case SCOUT: + case PUCK: + shipp->s_torpspeed = 16; + shipp->s_phaserrange = 4500; + shipp->s_maxspeed = 12; + shipp->s_maxfuel = 5000; + shipp->s_maxarmies = 2; + shipp->s_maxshield = 75; + shipp->s_maxdamage = 75; + shipp->s_maxwpntemp = 1000; + shipp->s_maxegntemp = 1000; + if(s_type == PUCK) { + shipp->s_type = PUCK; + shipp->s_letter = 'k'; + shipp->s_desig[0] = 'P'; + shipp->s_desig[1] = 'U'; + shipp->s_bitmap = PUCK; + } else { + shipp->s_type = SCOUT; + shipp->s_letter = 's'; + shipp->s_desig[0] = 'S'; + shipp->s_desig[1] = 'C'; + shipp->s_bitmap = SCOUT; + } + break; + case DESTROYER: + shipp->s_type = DESTROYER; + shipp->s_torpspeed = 14; + shipp->s_phaserrange = 5100; + shipp->s_maxspeed = 10; + shipp->s_maxfuel = 7000; + shipp->s_maxarmies = 5; + shipp->s_maxshield = 85; + shipp->s_maxdamage = 85; + shipp->s_maxwpntemp = 1000; + shipp->s_maxegntemp = 1000; + shipp->s_letter = 'd'; + shipp->s_desig[0] = 'D'; + shipp->s_desig[1] = 'D'; + shipp->s_bitmap = DESTROYER; + break; + default: + case DEFAULT: + case CRUISER: + shipp->s_type = s_type; + shipp->s_torpspeed = 12; + shipp->s_phaserrange = 6000; + shipp->s_maxspeed = 9; + shipp->s_maxfuel = 10000; + shipp->s_maxarmies = 10; + shipp->s_maxshield = 100; + shipp->s_maxdamage = 100; + shipp->s_maxwpntemp = 1000; + shipp->s_maxegntemp = 1000; + shipp->s_letter = 'c'; + shipp->s_desig[0] = 'C'; + shipp->s_desig[1] = 'A'; + shipp->s_bitmap = CRUISER; + break; + case BATTLESHIP: + shipp->s_type = BATTLESHIP; + shipp->s_torpspeed = 12; + shipp->s_phaserrange = 6300; + shipp->s_maxspeed = 8; + shipp->s_maxfuel = 14000; + shipp->s_maxarmies = 6; + shipp->s_maxshield = 130; + shipp->s_maxdamage = 130; + shipp->s_maxwpntemp = 1000; + shipp->s_maxegntemp = 1000; + shipp->s_letter = 'b'; + shipp->s_desig[0] = 'B'; + shipp->s_desig[1] = 'B'; + shipp->s_bitmap = BATTLESHIP; + break; + case ASSAULT: + shipp->s_type = ASSAULT; + shipp->s_torpspeed = 16; + shipp->s_phaserrange = 4800; + shipp->s_maxspeed = 8; + shipp->s_maxfuel = 6000; + shipp->s_maxarmies = 20; + shipp->s_maxshield = 80; + shipp->s_maxdamage = 200; + shipp->s_maxwpntemp = 1000; + shipp->s_maxegntemp = 1200; + shipp->s_letter = 'a'; + shipp->s_desig[0] = 'A'; + shipp->s_desig[1] = 'S'; + shipp->s_bitmap = ASSAULT; + break; + case STARBASE: + shipp->s_type = STARBASE; + shipp->s_torpspeed = 14; + shipp->s_phaserrange = 7200; + shipp->s_maxspeed = 2; + shipp->s_maxfuel = 60000; + shipp->s_maxarmies = 25; + shipp->s_maxshield = 500; + shipp->s_maxdamage = 600; + shipp->s_maxwpntemp = 1300; + shipp->s_maxegntemp = 1000; + shipp->s_letter = 'o'; + shipp->s_desig[0] = 'S'; + shipp->s_desig[1] = 'B'; + shipp->s_bitmap = STARBASE; + break; + case ATT: /* or GALAXY */ + if (paradise) { + shipp->s_type = ATT; + shipp->s_torpspeed = 20; + shipp->s_phaserrange = 6000; + shipp->s_maxspeed = 90; + shipp->s_maxfuel = 60000; + shipp->s_maxarmies = 1000; + shipp->s_maxshield = 30000; + shipp->s_maxdamage = 30000; + shipp->s_maxwpntemp = 10000; + shipp->s_maxegntemp = 10000; + shipp->s_letter = 'X'; + shipp->s_desig[0] = 'A'; + shipp->s_desig[1] = 'T'; + shipp->s_bitmap = ATT; + } else { + shipp->s_type = GALAXY; + shipp->s_torpspeed = 13; + shipp->s_phaserrange = 6000; /* this is a guess */ + shipp->s_maxspeed = 9; + shipp->s_maxfuel = 12000; + shipp->s_maxarmies = 12; + shipp->s_maxshield = 140; + shipp->s_maxdamage = 120; + shipp->s_maxwpntemp = 1000; + shipp->s_maxegntemp = 1000; + shipp->s_letter = 'g'; + shipp->s_desig[0] = 'G'; + shipp->s_desig[1] = 'A'; + shipp->s_bitmap = FLAGSHIP; + } + break; + case FLAGSHIP: + shipp->s_type = FLAGSHIP; + shipp->s_torpspeed = 14; + shipp->s_phaserrange = 5750; + shipp->s_maxspeed = 9; + shipp->s_maxfuel = 14500; + shipp->s_maxarmies = 8; + shipp->s_maxshield = 115; + shipp->s_maxdamage = 115; + shipp->s_maxwpntemp = 1000; + shipp->s_maxegntemp = 1500; + shipp->s_letter = 'f'; + shipp->s_desig[0] = 'F'; + shipp->s_desig[1] = 'L'; + shipp->s_bitmap = FLAGSHIP; + break; + case JUMPSHIP: + shipp->s_type = JUMPSHIP; + shipp->s_torpspeed = 18; + shipp->s_phaserrange = 3000; + shipp->s_maxspeed = 20; + shipp->s_maxfuel = 50000; + shipp->s_maxarmies = 0; + shipp->s_maxshield = 5; + shipp->s_maxdamage = 60; + shipp->s_maxwpntemp = 1300; + shipp->s_maxegntemp = 5000; + shipp->s_letter = 'j'; + shipp->s_desig[0] = 'J'; + shipp->s_desig[1] = 'S'; + shipp->s_bitmap = JUMPSHIP; + break; + case WARBASE: + shipp->s_type = WARBASE; + shipp->s_torpspeed = 15; + shipp->s_phaserrange = 6000; + shipp->s_maxspeed = 3; + shipp->s_maxfuel = 50000; + shipp->s_maxarmies = 0; + shipp->s_maxshield = 150; + shipp->s_maxdamage = 500; + shipp->s_maxwpntemp = 1500; + shipp->s_maxegntemp = 1000; + shipp->s_letter = 'w'; + shipp->s_desig[0] = 'W'; + shipp->s_desig[1] = 'B'; + shipp->s_bitmap = WARBASE; + break; + + case LIGHTCRUISER: + shipp->s_type = LIGHTCRUISER; + shipp->s_torpspeed = 13; + shipp->s_phaserrange = 6000; + shipp->s_maxspeed = 10; + shipp->s_maxfuel = 9000; + shipp->s_maxarmies = 4; + shipp->s_maxshield = 95; + shipp->s_maxdamage = 90; + shipp->s_maxwpntemp = 1000; + shipp->s_maxegntemp = 1500; + shipp->s_letter = 'l'; + shipp->s_desig[0] = 'C'; + shipp->s_desig[1] = 'L'; + shipp->s_bitmap = LIGHTCRUISER; + break; + + case CARRIER: + shipp->s_type = CARRIER; + shipp->s_torpspeed = 10; + shipp->s_phaserrange = 4500; + shipp->s_maxspeed = 10; + shipp->s_maxfuel = 15000; + shipp->s_maxarmies = 3; + shipp->s_maxshield = 100; + shipp->s_maxdamage = 150; + shipp->s_maxwpntemp = 1000; + shipp->s_maxegntemp = 1000; + shipp->s_letter = 'v'; + shipp->s_desig[0] = 'C'; + shipp->s_desig[1] = 'V'; + shipp->s_bitmap = CARRIER; + break; + case UTILITY: + shipp->s_type = UTILITY; + shipp->s_torpspeed = 16; + shipp->s_phaserrange = 5000; + shipp->s_maxspeed = 7; + shipp->s_maxfuel = 12000; + shipp->s_maxarmies = 12; + shipp->s_maxshield = 110; + shipp->s_maxdamage = 180; + shipp->s_maxwpntemp = 1000; + shipp->s_maxegntemp = 1800; + shipp->s_letter = 'u'; + shipp->s_desig[0] = 'U'; + shipp->s_desig[1] = 'T'; + shipp->s_bitmap = UTILITY; + break; + + case PATROL: + shipp->s_type = PATROL; + shipp->s_torpspeed = 15; + shipp->s_phaserrange = 5000; + shipp->s_maxspeed = 11; + shipp->s_maxfuel = 4000; + shipp->s_maxarmies = 1; + shipp->s_maxshield = 50; + shipp->s_maxdamage = 40; + shipp->s_maxwpntemp = 1000; + shipp->s_maxegntemp = 1500; + shipp->s_letter = 'p'; + shipp->s_desig[0] = 'P'; + shipp->s_desig[1] = 'T'; + shipp->s_bitmap = PATROL; + break; + } + buildShipKeymap(shipp); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gppackets.h Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,164 @@ +/* $Id: gppackets.h,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +#ifndef gppackets_h_ +#define gppackets_h_ + +/* the definitions of {INT,CARD}{8,16,32} are in packets.h */ +#include "packets.h" + +struct gameparam_spacket { + INT8 type; + INT8 subtype; /* this packet is not real */ + /* generic game parameter packet */ + INT16 pad; +}; + +struct gp_sizes_spacket { + INT8 type; + INT8 subtype; /* =0 */ + + CARD8 nplayers; + CARD8 nteams; /* max of 8 */ + + CARD8 nshiptypes; + CARD8 nranks; /* number of ranks */ + CARD8 nroyal; /* number of royalties */ + CARD8 nphasers; + + CARD8 ntorps; + CARD8 nplasmas; + CARD8 nthingies; /* per-player */ + CARD8 gthingies; /* auxiliary thingies */ + + CARD32 gwidth; /* galaxy width */ + /* 16 bytes */ + CARD32 flags; /* some game parameter flags */ +#define GP_WRAPVERT (1<<0) +#define GP_WRAPHORIZ (1<<1) +#define GP_WRAPALL (GP_WRAPVERT|GP_WRAPHORIZ) + + /* + The following bytes are room for growth. The size of this packet is + unimportant because it only gets sent once. hopefully we've got + plenty of room. + */ + INT32 ext1; /* maybe more flags? */ + INT32 ext2; + INT32 ext3; + /* 32 bytes */ + + INT32 ext4; + INT32 ext5; + INT32 ext6; + INT32 ext7; + + INT32 ext8; + INT32 ext9; + INT32 ext10; + INT32 ext11; /* 16 ints, 64 bytes */ +}; + +struct gp_team_spacket { + INT8 type; + INT8 subtype; /* =1 */ + + CARD8 index; /* team index */ + char letter; /* team letter 'F' */ + + char shortname[3]; /* non-null-terminated 3-letter abbrev 'FED' */ + CARD8 pad; + /* 8 bytes */ + char teamname[56]; /* padding to 64 byte packet */ +}; + +struct gp_teamlogo_spacket { + /* + This packet contains several adjacent rows of a team's logo bitmap + Data is in raw XBM format (scanline-padded to 8 bits). Maximum bitmap + size is 99x99, which takes 1287 (99x13) bytes. + */ + INT8 type; + INT8 subtype; /* =2 */ + + INT8 logowidth; /* <= 99 */ + INT8 logoheight; /* <= 99 */ + + INT8 y; /* y coord of the start of this packets info */ + INT8 thisheight; /* the height of this packet's info */ + INT8 teamindex; /* which team's logo this is */ + + char data[768 - 7]; /* pad packet to 768 bytes. */ +}; + +struct gp_shipshape_spacket { + INT8 type; + INT8 subtype; /* =3 */ + + CARD8 shipno; + INT8 race; /* -1 is independent */ + CARD8 nviews; /* typically 16 */ + + CARD8 width, height; + CARD8 pad1; +}; + +struct gp_shipbitmap_spacket { + INT8 type; + INT8 subtype; /* =4 */ + + CARD8 shipno; + INT8 race; /* -1 is independent */ + CARD8 thisview; /* 0..nviews-1 */ + + CARD8 bitmapdata[999]; +}; + +struct gp_rank_spacket { + INT8 type; + INT8 subtype; /* =5 */ + + INT8 rankn; /* rank number */ + + char name[-3 + 64 - 20]; /* name of the rank */ + + INT32 genocides; + INT32 milliDI; /* DI*1000 */ + INT32 millibattle; /* battle*1000 */ + INT32 millistrat; /* strategy*1000 */ + INT32 millispec; /* special ships*1000 */ +}; + +struct gp_royal_spacket { + INT8 type; + INT8 subtype; /* =6 */ + + CARD8 rankn; /* rank number */ + + char name[-3 + 64]; /* name of the rank */ +}; + +struct gp_teamplanet_spacket { + INT8 type; + INT8 subtype; /* =7 */ + + INT8 teamn; /* 0..7 */ + CARD8 pad1; + + INT32 ext1; /* extensions? */ + + /* + Bitmaps of the team logo and masks. The bitmap of the planet will be + constructed with (mask ? logo : planet), applied bitwise. This + calculation is equivalent to (logo&mask)|(planet&~mask) + */ + + /* bitmap 30x30, X bitmap format (scanline padded to 8 bits) */ + CARD8 tactical[120]; + CARD8 tacticalM[120]; + + /* bitmap 16x16, X bitmap format (scanline padded to 8 bits) */ + CARD8 galactic[32]; + CARD8 galacticM[32]; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/helpwin.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,298 @@ +/* $Id: helpwin.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +/* + * helpwin.c + * copyright 1991 ERic mehlhaff + * Free to use, hack, etc. Just keep these credits here. + * Use of this code may be dangerous to your health and/or system. + * Its use is at your own risk. + * I assume no responsibility for damages, real, potential, or imagined, + * resulting from the use of it. + * + * Hacked into paradise by Bill Dyess + */ + +#include <stdio.h> +#include <math.h> +#include <signal.h> +#include <sys/types.h> + + +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" + +#ifdef SVR4 +#include <string.h> +#else +#include <strings.h> +#endif + + +/* this is a set of routines that makes up a multi column help window, + ** and shows just what the keymaps current keymap representation of the + ** keys are. + ** + ** fillhelp() handles the filling in if the strings for the help window + ** update_Help_to_Keymap() checks the keymap and sets it up in hte + ** help window. + ** + + ** + ** Format for each entry is follows: + ** first character is the hard-coded character representation for the key + ** in the keymap. Useful for when you re-key things. This could confuse + ** people who do'nt know the keymap format. + ** + ** the next few spaces are either spaces or keys that also do that + ** function. Note that if you have more than 3 keys set to do the same + ** thing, they will not be displayed. + ** So, you could, I suppose map everything to 'Q' and it would not + ** show, but that's a pretty bizarre situation. + ** + + ** + ** Bugs & Comments: + ** You have to be sure that helpWin is defined to be big enough to handle + ** all the messages. That's pretty much a trial&error by-hand thing + ** at this point + ** + ** BZZZT! Not anymore, done automatically [BDyess] + */ + +/* fills in the help window to note all keys also mapped to the + ** listed functions + */ +void update_Help_to_Keymap(); + +char *help_message[] = +{ + " 0 Set speed 0", + " 1 Set speed 1", + " 2 Set speed 2", + " 3 Set speed 3", + " 4 Set speed 4", + " 5 Set speed 5", + " 6 Set speed 6", + " 7 Set speed 7", + " 8 Set speed 8", + " 9 Set speed 9", + "^0 Set speed 10", + "^1 Set speed 11", + "^2 Set speed 12", + "^3 Set speed 13", + "^4 Set speed 14", + "^5 Set speed 15", + "^6 Set speed 16", + "^7 Set speed 17", + "^8 Set speed 18", + "^9 Set speed 19", + "^) Set speed 20", + "^! Set speed 21", + "^@ Set speed 22", + "^# Set speed 23", + "^$ Set speed 24", + "^% Set speed 25", + "^^ Set speed 26", + "^& Set speed 27", + "^* Set speed 28", + "^( Set speed 29", + " % speed = maximum", + " # speed = 1/2 maximum", + " < slow speed 1", + " > speed up 1", + " ` Afterburners", + " - Engage warp", + " k Set course", + " p Fire phaser", + " t Fire photon torpedo", + " f Fire plasma torpedo", + " C Switch special weapon", + " d detonate enemy torps", + " D detonate own torps", + " L List players", + " P List planets", + " S Status graph toggle", + " ] Put up shields", + " [ Put down shields", + " u Shield toggle", + " s Shield toggle", + " i Info on player/planet", + " I Extended info on player", + "^i Info on a planet", + " b Bomb planet", + " z Beam up armies", + " x Beam down armies", + " { Cloak", + " } Uncloak", + " T Toggle tractor beam", + " y Toggle pressor beam", + " _ Turn on tractor beam", + " ^ Turn on pressor beam", + " $ Turn off tractor/pressor beam", + " R Enter repair mode", + " o Orbit planet or dock to outpost", + " e Docking permission toggle", + " r Refit (change ship type)", + " Q Quit", + " q Fast Quit", + " ? Message window toggle", + " c Cloaking device toggle", + " l Lock on to player/planet", + " ; Lock on to planet", + " h Help window toggle", + " w War declarations window", + " N Planet names toggle", + " V Rotate local planet display", + " B Rotate galactic planet display", + " * Send in practice robot", + " E Send Distress signal", + " F Send armies carried report", + " U Show rankings window", + " m Message Window Zoom", + " ' Message Zoom + start to Team", + " / Toggle sorted player list", + " : Toggle message logging", + " ! activate kitchen sink", + " + Show UDP options window", + " = Update all", + " , Ping stats window", + " M Show MOTD window", +#if 0 + " . NetstatWindow", + " \\ LagMeter", +#endif + +#ifdef SHORT_PACKETS + " ~ Toggle PacketWindow", + " \\ Update small", + " | Update medium", +#endif /* SHORT_PACKETS */ + + " (space) Unmap special windows", + +#ifdef TIMER + " @ Reset dashboard timer", + "^t Cycle timer", +#endif /* TIMER */ + "^m Toggle map zoom", +#ifdef WIDE_PLIST + " K Cycle playerlist", +#endif /* WIDE_PLIST */ + +#ifdef MACROS + " X Enter Macro Mode", + " X? Show current Macros", +#endif /* MACROS */ + + " & Reread .paradiserc", + " ) Rotate galaxy clockwise", + " ( Rotate galaxy counter-clockwise", +#ifdef RECORDER + "^r Stop recording", +#endif +#ifdef SOUND + "^s Sound window toggle", +#endif +#ifdef TOOLS + " \" Toggle shell tools window", +#endif +#ifdef AMIGA + " A Flush queued speech", + "HELP Show Amiga keys/info", +#endif + 0 +}; + +int helpmessages = (sizeof(help_message) / sizeof(char *)); +/* this is the number of help messages there are */ + +#define MAXHELP 40 +/* maximum length in characters of key explanation */ + + +void +fillhelp() +{ + register int i = 0, row, column; + char helpmessage[MAXHELP]; + + + /* 4 column help window. THis may be changed depending on font size */ + for (column = 0; column < 4; column++) { + for (row = 1; row < helpmessages / 4 + 2; row++) { + if (help_message[i] == 0) + break; + else { + strcpy(helpmessage, help_message[i]); + update_Help_to_Keymap(helpmessage); + W_WriteText(helpWin, MAXHELP * column, row - 1, textColor, + helpmessage, strlen(helpmessage), W_RegularFont); + i++; + } + } + if (help_message[i] == 0) + break; + } +} + + +/* this takes the help messages and puts in the keymap, so the player can + * see just what does what! + * + * ordinary format: "U Show rankings window", + * translatedd here to "[ sE Computer options window", + */ +void +update_Help_to_Keymap(helpmessage) + char helpmessage[]; +{ + int i, num_mapped = 0, key; + + key = helpmessage[1]; + if (helpmessage[0] == '^') { + /* control character */ + key += 128; + } + if ((int) strlen(helpmessage) < 6) { + return; + } + for (i = 0; i < 256; i++) { + if (myship->s_keymap[i] != key) + continue; + if (i == key) + continue; /* it's already there! don't add it! */ + + /* we've found a key mapped to key! */ + /* the key is i */ + num_mapped += 1 + (i > 127) ? 1 : 0; + if (num_mapped > 3) + continue; /* we've found too many! */ + + /* put the key in the string */ + if (i > 127) { + helpmessage[1 + num_mapped] = '^'; + helpmessage[2 + num_mapped] = i - 128; + } else { + helpmessage[2 + num_mapped] = i; + } + } + + + /* clear spaces if any area available */ +/* switch (num_mapped) + { + case 0: + helpmessage[3] = ' '; + case 1: + helpmessage[4] = ' '; + case 2: + helpmessage[5] = ' '; + case 3: + default: + helpmessage[6] = ' '; + } +*/ + return; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hockey.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,335 @@ +/* $Id: hockey.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +#ifdef HOCKEY +/* code for hockey lines [BDyess] 9/14/94 */ + +#include <stdio.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "proto.h" +#include "gameconf.h" +#include "packets.h" + +void dump_hockey_points(); +/*void init_puck(); /* getship.c */ + +struct player *puck; + +/* check to see if on a hockey server and do initialization [BDyess] */ +void hockeyInit() { + int i,j; + struct planet *l, *last; + int rightmost = 0; + int leftmost = blk_gwidth; + int nplan = paradise ? nplanets : 40; /* shouldn't be Paradise... */ + int middle = blk_gwidth / 2; + int top = 0; + int bottom = blk_gwidth; + int line = 0; + struct point { int x,y; } boxpoints[4]; + /* top-topleft, top-bottomright, bottom-topright, + bottom-bottomright, {x,y} for each [BDyess] */ + W_Color topcolor,bottomcolor; + + topcolor = bottomcolor = W_Grey; + + /* we're playing hockey if a player named "Puck" exists in the 'g' + slot, is independant, is in a scout, and has the login name + 'Robot'. [BDyess] */ + puck = &players['g'-'a'+10]; + if(!hockey) { + if(0 == strcmp(puck->p_name,"Puck") && + 0 == strcmp(puck->p_login,"Robot") && + puck->p_teami < 0 && + SCOUT == puck->p_ship->s_type) { + + printf("Hi Puck!\n"); + hockey = 1; + /*init_puck();*/ + } + } + if(!hockey) /* not a hockey server, nothing more to do */ + return; + + if(puck->p_ship->s_type != PUCK) { + puck->p_ship = getship(PUCK); + redrawPlayer[puck->p_no]; + } + if(tacticalHockeyLines) { + last = &planets[nplan]; + /* guess where the lines are supposed to go based on planet + location. Always draws straight lines, ie. if the border + bows out, tough - the furthest out planet will have a vertical + line through it. [BDyess] */ + + /* first the left and rightmost lines [BDyess] */ + for(l = &planets[0];l < last;l++) { + if(l->pl_x < leftmost) { + leftmost = l->pl_x; + } + if(l->pl_x > rightmost) { + rightmost = l->pl_x; + } + } + hlines[line].vertical = 1; + hlines[line].pos = leftmost; + hlines[line].end1 = 0; + hlines[line].end2 = blk_gwidth; + hlines[line].color = W_Grey; + line++; + hlines[line].vertical = 1; + hlines[line].pos = rightmost; + hlines[line].end1 = 0; + hlines[line].end2 = blk_gwidth; + hlines[line].color = W_Grey; + line++; + /* now guess the middle planet. Pick the planet closest to the + middle of the screen. [BDyess] */ + hlines[line].pos = 0; + for(l = &planets[0];l < last;l++) { + if(ABS(l->pl_y - middle) < ABS(hlines[line].pos - middle)) + hlines[line].pos = l->pl_y; + } + middle = hlines[line].pos; + hlines[line].end1 = leftmost; + hlines[line].end2 = rightmost; + hlines[line].vertical = 0; + hlines[line].color = W_Red; + line++; + /* now find the upper and lower middle lines by picking the planets + closest to the center yet still above/below the middle and inside + the left and rightmost [BDyess] */ + for(l = &planets[0];l < last;l++) { + if(NOBODY == l->pl_owner) continue; + if(l->pl_y > top && l->pl_y < middle && + l->pl_x < rightmost && l->pl_x > leftmost) { + top = l->pl_y; + topcolor = planetColor(l); + } + if(l->pl_y < bottom && l->pl_y > middle && + l->pl_x < rightmost && l->pl_x > leftmost) { + bottom = l->pl_y; + bottomcolor = planetColor(l); + } + } + hlines[line].pos = top; + hlines[line].end1 = leftmost; + hlines[line].end2 = rightmost; + hlines[line].vertical = 0; + hlines[line].color = teamColorHockeyLines ? topcolor : W_Cyan; + line++; + hlines[line].pos = bottom; + hlines[line].end1 = leftmost; + hlines[line].end2 = rightmost; + hlines[line].vertical = 0; + hlines[line].color = teamColorHockeyLines ? bottomcolor : W_Cyan; + line++; + /* last, try to find the goal box. Search for the planets that + are inside the left and right, above/below the upper/lower middle, + and are not neutral. Of those planets, take the top left and + bottom right points [BDyess] */ + /* toplefts */ + boxpoints[0].x = boxpoints[0].y = boxpoints[2].x = boxpoints[2].y = + blk_gwidth; + /* bottomrights */ + boxpoints[1].x = boxpoints[1].y = boxpoints[3].x = boxpoints[3].y = 0; + for(l = &planets[0];l < last;l++) { + /* don't want nobody's planets */ + if(l->pl_owner == NOBODY) continue; + /* check for out-of-bounds */ + if((l->pl_y >= top && l->pl_y <= bottom) || + l->pl_x >= rightmost || l->pl_x <= leftmost) continue; + /* top or bottom? */ + if(l->pl_y < middle) i = 0; /* top */ + else i = 2; /* bottom */ + if(l->pl_x <= boxpoints[i].x && + l->pl_y <= boxpoints[i].y) { /* new topleft */ + boxpoints[i].x = l->pl_x; + boxpoints[i].y = l->pl_y; + } + if(l->pl_x >= boxpoints[i+1].x && + l->pl_y >= boxpoints[i+1].y) { /* new bottomright */ + boxpoints[i+1].x = l->pl_x; + boxpoints[i+1].y = l->pl_y; + } + } + if(! teamColorHockeyLines) { + topcolor = bottomcolor = W_Grey; + } + hlines[line].vertical = 0; + hlines[line].pos = boxpoints[0].y; + hlines[line].end1 = boxpoints[0].x; + hlines[line].end2 = boxpoints[1].x; + hlines[line].color = topcolor; + line++; + hlines[line].vertical = 1; + hlines[line].pos = boxpoints[0].x; + hlines[line].end1 = boxpoints[0].y; + hlines[line].end2 = boxpoints[1].y; + hlines[line].color = topcolor; + line++; + hlines[line].vertical = 0; + hlines[line].pos = boxpoints[1].y; + hlines[line].end1 = boxpoints[0].x; + hlines[line].end2 = boxpoints[1].x; + hlines[line].color = W_Red; + line++; + hlines[line].vertical = 1; + hlines[line].pos = boxpoints[1].x; + hlines[line].end1 = boxpoints[0].y; + hlines[line].end2 = boxpoints[1].y; + hlines[line].color = topcolor; + line++; + + hlines[line].vertical = 0; + hlines[line].pos = boxpoints[2].y; + hlines[line].end1 = boxpoints[2].x; + hlines[line].end2 = boxpoints[3].x; + hlines[line].color = W_Red; + line++; + hlines[line].vertical = 1; + hlines[line].pos = boxpoints[2].x; + hlines[line].end1 = boxpoints[2].y; + hlines[line].end2 = boxpoints[3].y; + hlines[line].color = bottomcolor; + line++; + hlines[line].vertical = 0; + hlines[line].pos = boxpoints[3].y; + hlines[line].end1 = boxpoints[2].x; + hlines[line].end2 = boxpoints[3].x; + hlines[line].color = bottomcolor; + line++; + hlines[line].vertical = 1; + hlines[line].pos = boxpoints[3].x; + hlines[line].end1 = boxpoints[2].y; + hlines[line].end2 = boxpoints[3].y; + hlines[line].color = bottomcolor; + line++; + } +} + +/* draw the tactical hockey lines [BDyess] */ +void tactical_hockey() { + int i; + struct hockeyLine *l = &hlines[0]; + int dx,dx1,dx2,dy,dy1,dy2; + int view = SCALE * WINSIDE / 2; + static int old_tacticalHockeyLines, old_galacticHockeyLines, + old_cleanHockeyGalactic, old_teamColorHockeyLines; + + if(!hockey) + return; + + if(puck->p_ship->s_type != PUCK) { + puck->p_ship = getship(PUCK); + redrawPlayer[puck->p_no]; + } + if(tacticalHockeyLines != old_tacticalHockeyLines) { + redrawall = 1; + old_tacticalHockeyLines = tacticalHockeyLines; + } + if(galacticHockeyLines != old_galacticHockeyLines) { + redrawall = 1; + old_galacticHockeyLines = galacticHockeyLines; + } + if(cleanHockeyGalactic != old_cleanHockeyGalactic) { + redrawall = 1; + old_cleanHockeyGalactic = cleanHockeyGalactic; + } + if(teamColorHockeyLines != old_teamColorHockeyLines) { + old_teamColorHockeyLines = teamColorHockeyLines; + hockeyInit(); + } + /* draw whatever hockey lines are visible [BDyess] */ + if(hockey && tacticalHockeyLines) { /* if it should be drawn */ + for(i = 0, l = &hlines[0]; i < NUM_HOCKEY_LINES; i++, l++) { + if(l->vertical) { + dx = l->pos - me->p_x; + dy1 = l->end1 - me->p_y; + dy2 = l->end2 - me->p_y; + /* is it in view? [BDyess] */ + if(ABS(dx) <= view && + (ABS(dy1) <= view || ABS(dy2) <= view || + (l->end1 <= me->p_y && l->end2 >= me->p_y))) { + dx = dx / SCALE + WINSIDE / 2; + dy1 = dy1 / SCALE + WINSIDE / 2; + dy2 = dy2 / SCALE + WINSIDE / 2; + W_CacheLine(w, dx, dy1, dx, dy2, l->color); + clearline[0][clearlcount] = dx; + clearline[1][clearlcount] = dy1; + clearline[2][clearlcount] = dx; + clearline[3][clearlcount] = dy2; + clearlcount++; + } + } else { /* horizontal */ + dy = l->pos - me->p_y; + dx1 = l->end1 - me->p_x; + dx2 = l->end2 - me->p_x; + /* is it in view? [BDyess] */ + if(ABS(dy) <= view && + (ABS(dx1) <= view || ABS(dx2) <= view || + (l->end1 <= me->p_x && l->end2 >= me->p_x))) { + dy = dy / SCALE + WINSIDE / 2; + dx1 = dx1 / SCALE + WINSIDE / 2; + dx2 = dx2 / SCALE + WINSIDE / 2; + W_CacheLine(w, dx1, dy, dx2, dy, l->color); + clearline[0][clearlcount] = dx1; + clearline[1][clearlcount] = dy; + clearline[2][clearlcount] = dx2; + clearline[3][clearlcount] = dy; + clearlcount++; + } + } + } + } +} + +/* draw the tactical hockey lines [BDyess] */ +void galactic_hockey() { + int i; + struct hockeyLine *l; + int dx,dx1,dx2,dy,dy1,dy2; + int gwidth, offsetx, offsety; + + if(hockey && galacticHockeyLines) { /* if it should be drawn */ + if(blk_zoom) { + gwidth = blk_gwidth / 2; + offsetx = zoom_offset(me->p_x); + offsety = zoom_offset(me->p_y); + /* keep last offset? */ + } else { + gwidth = blk_gwidth; + offsetx = offsety = 0; + } + for(i = 0, l = &hlines[0]; i < NUM_HOCKEY_LINES; i++, l++) { + if(l->vertical) { + dx = (l->pos - offsetx) * WINSIDE / gwidth; + dy1 = (l->end1 - offsety) * WINSIDE / gwidth; + dy2 = (l->end2 - offsety) * WINSIDE / gwidth; + W_MakeLine(mapw, dx, dy1, dx, dy2, l->color); + } else { + dy = (l->pos - offsety) * WINSIDE / gwidth; + dx1 = (l->end1 - offsetx) * WINSIDE / gwidth; + dx2 = (l->end2 - offsetx) * WINSIDE / gwidth; + W_MakeLine(mapw, dx1, dy, dx2, dy, l->color); + } + } + } +} + +void dump_hockey_points() { + int i; + struct hockeyLine *l; + + printf("Hockey points dump:\n"); + for (i = 0, l = &hlines[0]; i < NUM_HOCKEY_LINES; i++, l++) { + if(l->vertical) { + printf("%d: %d,%d %d,%d\n",i,l->pos,l->end1,l->pos,l->end2); + } else { + printf("%d: %d,%d %d,%d\n",i,l->end1,l->pos,l->end2,l->pos); + } + } +} +#endif /*HOCKEY*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hullbitmaps.h Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,65 @@ +/* $Id: hullbitmaps.h,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +#define hull_width 22 +#define hull_height 22 +#define HULL_FRAMES 8 +#define HULL_BYTE_SIZE 66 + +static char hull_bits[HULL_FRAMES][HULL_BYTE_SIZE] = { + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00}, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00}, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00}, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00}, + { + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00} +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/icon.xbm Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,97 @@ +#define icon_width 112 +#define icon_height 80 +static unsigned char icon_bits[] = { + 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x7f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc1, 0x83, + 0x87, 0x9f, 0x7f, 0x3f, 0xf0, 0x3b, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x81, 0x07, 0xc7, 0xcf, 0x3f, 0x7f, 0xf8, 0x39, 0x07, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x81, 0x07, 0xe7, 0x01, 0x0e, 0xe7, 0x3c, 0xb8, 0x03, 0xd8, + 0x02, 0x10, 0x6c, 0x80, 0x81, 0x0f, 0xe7, 0x00, 0x0e, 0xc7, 0x1d, 0xf8, + 0x01, 0x50, 0x56, 0x53, 0x28, 0x80, 0x81, 0x1f, 0xe7, 0x0f, 0x0e, 0xff, + 0xfc, 0xf9, 0x00, 0x20, 0xb2, 0x36, 0x28, 0x80, 0x81, 0x1b, 0xe7, 0x07, + 0x0e, 0x3f, 0xfc, 0xf8, 0x01, 0x50, 0x92, 0x51, 0x28, 0x80, 0x81, 0x3b, + 0xe7, 0x00, 0x0e, 0x77, 0x1c, 0xb8, 0x03, 0xd8, 0x14, 0x53, 0x6c, 0x80, + 0x81, 0x33, 0xe7, 0x01, 0x0e, 0xe7, 0x3c, 0x38, 0x07, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x81, 0x73, 0xc7, 0x1f, 0x0e, 0xe7, 0xf8, 0x3b, 0x0e, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x81, 0x63, 0x87, 0x0f, 0x0e, 0xc7, 0xf1, 0x39, + 0x1c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0xc3, 0x07, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0xc3, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0x83, + 0xe7, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0xc1, 0x03, 0xe7, 0xc6, 0x83, 0x1f, 0x0f, 0x7e, 0x98, 0x0f, 0x1f, 0x3c, + 0xc0, 0x80, 0x01, 0x00, 0xe0, 0xcc, 0x87, 0x3f, 0x1f, 0xfe, 0xdc, 0x87, + 0x0f, 0x3e, 0xe0, 0x80, 0x01, 0x00, 0xe0, 0xdc, 0x85, 0x73, 0x17, 0xce, + 0xdd, 0xc0, 0x01, 0x62, 0xe0, 0x80, 0x01, 0x00, 0xe0, 0xdc, 0x8d, 0x63, + 0x37, 0x8e, 0xdd, 0xc1, 0x0f, 0x60, 0xd0, 0x80, 0x01, 0x00, 0xe0, 0xd8, + 0x89, 0x33, 0x27, 0x8e, 0x9d, 0xc3, 0x07, 0x30, 0xc8, 0x80, 0x01, 0x00, + 0xe0, 0xcf, 0x9d, 0x3f, 0x77, 0x8e, 0x1d, 0xc7, 0x01, 0x18, 0xc8, 0x80, + 0x01, 0x00, 0xe0, 0xc0, 0x97, 0x73, 0x5f, 0x8e, 0x1d, 0xce, 0x01, 0x0c, + 0xf8, 0x81, 0x01, 0x00, 0xe0, 0xc0, 0xb3, 0x63, 0xcf, 0xce, 0x1d, 0x9c, + 0x1f, 0x7e, 0xc3, 0x80, 0x01, 0x00, 0xe0, 0xc0, 0xb1, 0x63, 0xc7, 0xfe, + 0xdc, 0x0f, 0x0f, 0x7e, 0xc3, 0x80, 0x01, 0x00, 0xe0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0xc1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, + 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x01, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x0f, 0x00, 0x80, 0xff, 0x03, 0x00, + 0x00, 0x80, 0x01, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x80, 0x01, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xe0, 0x0f, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x7c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x1f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x21, 0x00, 0x00, 0x00, 0x92, 0x5b, 0x75, 0x83, 0x00, 0x60, + 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x54, 0x0f, 0xa4, 0xc8, 0x73, + 0x2f, 0xa0, 0x1e, 0x00, 0x00, 0x80, 0x01, 0x00, 0x40, 0x89, 0xa2, 0xa8, + 0x00, 0x42, 0xad, 0x58, 0x00, 0x0e, 0x00, 0x80, 0x01, 0x20, 0x40, 0x12, + 0x8b, 0xaa, 0x56, 0x09, 0x00, 0x58, 0x30, 0x04, 0x00, 0x80, 0x01, 0x00, + 0x94, 0xaa, 0x3c, 0x00, 0x10, 0x10, 0x00, 0x00, 0x50, 0x80, 0x03, 0x80, + 0x01, 0x00, 0x38, 0x24, 0xc0, 0x52, 0x4d, 0x49, 0x09, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x01, 0x00, 0x44, 0x45, 0x25, 0x02, 0x0c, 0xc0, 0x0f, 0x00, + 0x00, 0x80, 0x70, 0x80, 0x01, 0x00, 0x1a, 0x42, 0x8a, 0x54, 0x01, 0x04, + 0x00, 0xe0, 0x00, 0x00, 0xc0, 0x80, 0x01, 0x00, 0x40, 0x11, 0x23, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x20, 0x40, + 0x44, 0x4d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x80, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x44, 0xc1, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0xfe, 0x43, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x13, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0xfe, 0x2b, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xe0, 0x07, 0x00, + 0xfc, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xe0, + 0x0f, 0x00, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, + 0x00, 0x30, 0x0c, 0x00, 0xf8, 0x07, 0x80, 0xf0, 0x03, 0x00, 0x00, 0x80, + 0x01, 0x00, 0x00, 0x60, 0x1c, 0x00, 0xf8, 0x07, 0x00, 0xfb, 0x03, 0x00, + 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x80, 0x07, + 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xa0, 0x00, 0x00, 0xf8, 0x03, + 0xc0, 0x07, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, + 0xff, 0x0f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, + 0x00, 0xc0, 0xbf, 0x6f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, + 0x00, 0x80, 0x00, 0xf0, 0xcd, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x01, 0x00, 0x00, 0x00, 0x01, 0xbc, 0x6f, 0xec, 0x41, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0xff, 0x41, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0xe1, 0x1f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0xf0, 0xff, + 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, + 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x7f, };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/inform.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,561 @@ +/* $Id: inform.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +/* + * inform.c + */ +#include "copyright.h" + +#include <stdio.h> +#include <math.h> +#include <signal.h> +#include <string.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "proto.h" +#include "gameconf.h" +#ifdef SOUND +#include "slib.h" +#endif + +/* Display information about the nearest objext to mouse */ + +/* +** When the player asks for info, this routine finds the object +** nearest the mouse, either player or planet, and pop up a window +** with the desired information in it. +** +** We intentionally provide less information than is actually +** available. Keeps the fog of war up. +** +** There is a different sized window for each type player/planet +** and we take care to keep it from extending beyond the main +** window boundaries. +*/ + +/* Prototypes */ +static void inform_planet_paradise P((struct planet * k)); +static void Info_list_normal P((struct player * j)); +static void Info_list_paradise P((struct player * j)); +static void Info_list_small P((struct player * j)); +static void inform_planet_normal P((struct planet * k)); + +int last_key = 0; + +void +inform(ww, x, y, key) + W_Window ww; + int x, y; + char key; +{ + char buf[BUFSIZ]; + int line = 0; + register struct player *j; + register struct planet *k; + int mx, my; + struct obtype *gettarget(), *target; + int windowWidth, windowHeight; + +#ifdef SOUND + S_PlaySound(S_SENSORS); +#endif + mx = x; + my = y; + last_key = key; + if (key == 'i') { + target = gettarget(ww, x, y, TARG_PLAYER | TARG_SELF | TARG_ASTRAL); + } else if (key == 'I') { + target = gettarget(ww, x, y, TARG_PLAYER | TARG_SELF); + } else { /* control 'i' */ + target = gettarget(ww, x, y, TARG_ASTRAL); + key = 'i'; + } + if (target == NULL) + return; /* NULL returned from gettarget indicates no + target found. [BDyess] */ + infomapped = 1; + if (keepInfo > 0 && + key != 'I') /* don't blast the long window */ + infowin_up = keepInfo; + + /* + This is pretty lame. We make a graphics window for the info window so + we can accurately space the thing to barely fit into the galactic map + or whatever. + */ + + windowWidth = W_WindowWidth(ww); + windowHeight = W_WindowHeight(ww); + if (ww == playerw) { + windowWidth *= W_Textwidth; + windowHeight *= W_Textheight; + } + infotype = target->o_type; + if (target->o_type == PLAYERTYPE) { + /* Too close to the edge? */ + if (mx + 23 * W_Textwidth + 2 > windowWidth) + mx = windowWidth - 23 * W_Textwidth - 2; + if (my + 8 * W_Textheight + 2 > windowHeight) + my = windowHeight - 8 * W_Textheight - 2; + if (key == 'i') { + infow = W_MakeWindow("info", mx, my, 23 * W_Textwidth, 8 * W_Textheight, + ww, (char *) 0, 2, foreColor); + W_MapWindow(infow); + j = &players[target->o_num]; + infothing = (void *) j; + Info_list_small(j); + } else { /* New information window! */ + if (!paradise) { /* if a normal server then */ + infow = W_MakeWindow("info", mx, my, 23 * W_Textwidth, + 8 * W_Textheight, ww, (char *) 0, 2, foreColor); + W_MapWindow(infow); + j = &players[target->o_num]; + infothing = (void *) j; + (void) sprintf(buf, "%s (%c%c):", j->p_name, + teaminfo[j->p_teami].letter, shipnos[j->p_no]); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, + playerColor(j), buf, strlen(buf), shipFont(j)); + Info_list_normal(j); + } else { /* else if a paradise server */ + if (mx + 50 * W_Textwidth + 2 > windowWidth) + mx = windowWidth - 50 * W_Textwidth - 2; + if (my + 25 * W_Textheight + 2 > windowHeight) + my = windowHeight - 22 * W_Textheight - 2; + infow = W_MakeWindow("info", mx, my, 50 * W_Textwidth, + 22 * W_Textheight, ww, (char *) 0, 2, foreColor); + W_MapWindow(infow); + j = &players[target->o_num]; + infothing = (void *) j; + (void) sprintf(buf, "%s (%c%c):", j->p_name, + teaminfo[j->p_teami].letter, shipnos[j->p_no]); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, + playerColor(j), buf, strlen(buf), shipFont(j)); + Info_list_paradise(j); + } + } + } else { /* Planet */ + if (paradise) { + /* Too close to the edge? */ + if (mx + 25 * W_Textwidth + 2 > windowWidth) + mx = windowWidth - 25 * W_Textwidth - 2; + if (my + 5 * W_Textheight + 2 > windowHeight) + my = windowHeight - 5 * W_Textheight - 2; + + infow = W_MakeWindow("info", mx, my, W_Textwidth * 25, W_Textheight * 5, ww, + (char *) 0, 2, foreColor); + } else { + /* Too close to the edge? */ + if (mx + 25 * W_Textwidth + 2 > windowWidth) + mx = windowWidth - 25 * W_Textwidth - 2; + if (my + 3 * W_Textheight + 2 > windowHeight) + my = windowHeight - 5 * W_Textheight - 2; + + infow = W_MakeWindow("info", mx, my, W_Textwidth * 25, W_Textheight * 3, ww, + (char *) 0, 2, foreColor); + } + W_MapWindow(infow); + k = &planets[target->o_num]; + infothing = (void *) k; + /* + dist = hypot((double) (me->p_x - k->pl_x), (double) (me->p_y - + k->pl_y)); + */ + + if (!paradise) { /* if not a paradise server */ + inform_planet_normal(k); + } else { /* else must be a paradise server */ + inform_planet_paradise(k); /* go display paradise info */ + } + } +} + + +void +destroyInfo() +{ + W_DestroyWindow(infow); + infow = 0; + infomapped = 0; + infotype = 0; + infoupdate = 0; +} + + +static void +Info_list_small(j) + struct player *j; +{ + char buf[100]; + int line = 0; + double dist; + + (void) sprintf(buf, "%s (%c%c):", j->p_name, teaminfo[j->p_teami].letter, + shipnos[j->p_no]); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), shipFont(j)); + (void) sprintf(buf, "Login %-s", j->p_login); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), + W_RegularFont); + (void) sprintf(buf, "Display %-s", j->p_monitor); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), + W_RegularFont); + (void) sprintf(buf, "Speed %-d", j->p_speed); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), + W_RegularFont); + (void) sprintf(buf, "kills %-4.2f", j->p_kills); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), + W_RegularFont); + dist = hypot((double) (me->p_x - j->p_x), + (double) (me->p_y - j->p_y)) / (double) GRIDSIZE; + (void) sprintf(buf, "dist %-1.2f sectors", dist); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), + W_RegularFont); + (void) sprintf(buf, "S-Class %-2.2s", j->p_ship->s_desig); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), + W_RegularFont); + + if (j->p_swar & idx_to_mask(me->p_teami)) + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + "WAR", 3, + W_RegularFont); + else if (j->p_hostile & idx_to_mask(me->p_teami)) + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + "HOSTILE", 7, + W_RegularFont); + else + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + "PEACEFUL", 8, + W_RegularFont); +} + +static void +inform_planet_normal(k) + struct planet *k; +{ + char buf[100]; + int line = 0; + + if (k->pl_info & idx_to_mask(me->p_teami)) { + (void) sprintf(buf, "%s (%c)", k->pl_name, + teaminfo[mask_to_idx(k->pl_owner)].letter); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, planetColor(k), + buf, strlen(buf), planetFont(k)); + (void) sprintf(buf, "Armies %d", k->pl_armies); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, + planetColor(k), buf, strlen(buf), W_RegularFont); + (void) sprintf(buf, "%s %s %s %s", + (k->pl_flags & PLREPAIR ? "RPR" : " "), + (k->pl_flags & PLFUEL ? "FUEL" : " "), + (k->pl_flags & PLAGRI ? "AGRI" : " "), + team_bit_string(k->pl_info)); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, + planetColor(k), buf, strlen(buf), W_RegularFont); + } else { /* else player has no info on planet */ + (void) sprintf(buf, "%s", k->pl_name); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, planetColor(k), + buf, strlen(buf), W_RegularFont); + (void) sprintf(buf, "No other info"); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, planetColor(k), + buf, strlen(buf), W_RegularFont); + } +} + + +/* This function provides info about planets for a paradise version 2.0 +server. */ + +static void +inform_planet_paradise(k) + struct planet *k; /* the planet */ +{ + char buf[100]; + int line = 0; + + if (k->pl_flags & PLSTAR) { /* test if planet is a star */ + (void) sprintf(buf, "%s", k->pl_name); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, textColor, + buf, strlen(buf), W_RegularFont); + (void) sprintf(buf, "STAR "); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, + textColor, buf, strlen(buf), W_RegularFont); + } else if (!(k->pl_info & idx_to_mask(me->p_teami))) { /* else if no info */ + (void) sprintf(buf, "%s", k->pl_name); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, planetColor(k), + buf, strlen(buf), W_RegularFont); + (void) sprintf(buf, "No other info"); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, planetColor(k), + buf, strlen(buf), W_RegularFont); + } else { /* else we have info */ + (void) sprintf(buf, "%s (%c)", k->pl_name, + teaminfo[mask_to_idx(k->pl_owner)].letter); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, planetColor(k), + buf, strlen(buf), W_RegularFont); + (void) sprintf(buf, "Armies %d", k->pl_armies); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, + planetColor(k), buf, strlen(buf), W_RegularFont); + (void) sprintf(buf, "%s %s %s %s", + (k->pl_flags & PLREPAIR ? "RPR" : " "), + (k->pl_flags & PLFUEL ? "FUEL" : " "), + (k->pl_flags & PLAGRI ? "AGRI" : " "), + (k->pl_flags & PLSHIPYARD ? "SHPYD" : " ")); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, + planetColor(k), buf, strlen(buf), W_RegularFont); + (void) sprintf(buf, "atmos: "); + switch (k->pl_flags & PLATMASK) { + case PLPOISON: + strcat(buf, "TOXC surfc: "); + break; + case PLATYPE3: + strcat(buf, "TNTD surfc: "); + break; + case PLATYPE2: + strcat(buf, "THIN surfc: "); + break; + case PLATYPE1: + strcat(buf, "STND surfc: "); + break; + default: + strcat(buf, " surfc: "); + break; + }; + if (k->pl_flags & PLDILYTH) + strcat(buf, "D"); + else + strcat(buf, " "); + if (k->pl_flags & PLMETAL) + strcat(buf, "M"); + else + strcat(buf, " "); + if (k->pl_flags & PLARABLE) + strcat(buf, "A"); + else + strcat(buf, " "); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, + planetColor(k), buf, strlen(buf), W_RegularFont); + sprintf(buf, "Time: %-5d Visit: %s", + ((idx_to_mask(me->p_teami) == k->pl_owner) ? 0 + : (int) (status2->clock - k->pl_timestamp)), + team_bit_string(k->pl_info)); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, + planetColor(k), buf, strlen(buf), W_RegularFont); + } +} + + + +static void +Info_list_normal(j) + struct player *j; /* player to do info on */ +{ + char buf[80]; + int line = 0; + struct ratings r; + + get_ratings(j, &r); + sprintf(buf, "%s (%c%c):", j->p_name, teaminfo[j->p_teami].letter, + shipnos[j->p_no]); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + strcpy(buf, " Rating Total"); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Bombing: %5.2f %5d", r.r_bombrat, r.r_armies); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Planets: %5.2f %5d", r.r_planetrat, r.r_planets); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Offense: %5.2f %5d", r.r_offrat, r.r_kills); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Defense: %5.2f %5d", r.r_defrat, r.r_losses); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, " Maxkills: %6.2f", r.r_maxkills); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, " Hours: %6.2f", (float) j->p_stats.st_tticks / 36000.0); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); +} + +static void +Info_list_paradise(j) + struct player *j; /* player to do info on */ +{ + char buf[80]; + int line = 0; + struct ratings r; + + get_ratings(j, &r); + + sprintf(buf, "Name: %s", j->p_name); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Rank: %s", ranks2[j->p_stats2.st_rank].name); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Royalty: %s", royal[j->p_stats2.st_royal].name); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Genocides: %4d", r.r_genocides); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "DI: %7.2f", r.r_di); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Maxkills:%6.2f", j->p_stats2.st_tmaxkills); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Kills: %4d", j->p_stats2.st_tkills); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Losses: %4d", j->p_stats2.st_tlosses); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "T-hours: %6.2f", (float) j->p_stats2.st_tticks / 36000.0); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, " "); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + strcpy(buf, " Rating Total"); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Bombing: %5.2f %6d", r.r_bombrat, r.r_armies); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Planets: %5.2f %6d", r.r_planetrat, r.r_planets); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Resources: %5.2f %6d", r.r_resrat, r.r_resources); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Dooshes: %5.2f %6d", r.r_dooshrat, r.r_dooshes); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Ratio: %5.2f", j->p_stats2.st_tkills / + ((j->p_stats2.st_tlosses) ? j->p_stats2.st_tlosses : 1.0)); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Offense: %5.2f", r.r_offrat); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, " "); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "RATINGS"); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Special ships: %7.2f", r.r_specrat); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Battle: %7.2f", r.r_batrat); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Strategy: %7.2f", r.r_stratrat); + W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + + line = 1; + sprintf(buf, " "); + W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "JUMPSHIP STATS"); + W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Planets: %7d", j->p_stats2.st_jsplanets); + W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Hours: %7.2f", (float) j->p_stats2.st_jsticks / 36000.0); + W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "JS rating: %7.2f", r.r_jsrat); + W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + + sprintf(buf, " "); + W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "STARBASE STATS"); + W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Kills: %4d", j->p_stats2.st_sbkills); + W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Losses: %4d", j->p_stats2.st_sblosses); + W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Hours: %7.2f", (float) j->p_stats2.st_sbticks / 36000.0); + W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Maxkills: %7.2f", j->p_stats2.st_sbmaxkills); + W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "SB rating: %7.2f", r.r_sbrat); + W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + + sprintf(buf, " "); + W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "WARBASE STATS"); + W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Kills: %4d", j->p_stats2.st_wbkills); + W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Losses: %4d", j->p_stats2.st_wblosses); + W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Hours: %7.2f", (float) j->p_stats2.st_wbticks / 36000.0); + W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "Maxkills: %7.2f", j->p_stats2.st_wbmaxkills); + W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); + sprintf(buf, "WB rating: %7.2f", r.r_wbrat); + W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j), + buf, strlen(buf), W_RegularFont); +} + +/* + constantly updating info window code [BDyess] +*/ +void +updateInform() +{ + if (!infomapped || !paradise) + return; /* disabled for Bronco servers */ + if (infotype == PLAYERTYPE && last_key == 'i' && (redrawPlayer[me->p_no] || + redrawPlayer[((struct player *) infothing)->p_no])) + infoupdate = 1; + if (infoupdate) { + infoupdate = 0; + W_ClearWindow(infow); + if (infotype == PLAYERTYPE) { + /* if(isAlive((struct player*)infothing)) { */ + if (last_key == 'i')/* use small info */ + Info_list_small((struct player *) infothing); + else if (!paradise) + Info_list_normal((struct player *) infothing); + else + Info_list_paradise((struct player *) infothing); + /* + } else { destroyInfo(); } + */ + } else { /* planet */ + if (!paradise) + inform_planet_normal((struct planet *) infothing); + else + inform_planet_paradise((struct planet *) infothing); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/input.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,1199 @@ +/* $Id: input.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +/* + * input.c + * + * Modified to work as client in socket based protocol + */ +#include "copyright.h" + +#include <stdio.h> +#include <math.h> +#include <sys/types.h> +#ifdef RS6K +#include <sys/select.h> +#endif +#ifdef hpux +#include <time.h> +#else /* hpux */ +#include <sys/time.h> +#endif /* hpux */ +#include <signal.h> +#include <errno.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "packets.h" +#include "proto.h" +#ifdef SOUND +#include "Slib.h" +#endif + +#define control(x) (x)+128 + +/* Prototypes */ +static void buttonaction P((W_Event * data)); +static void keyaction P((W_Event * data)); +static void scan P((W_Window w, int x, int y)); +/*static void selectblkbozo P((W_Event *data));*/ + +static int tmodeChange = 0; /* handles first change of tmode; including */ + /* when a play first joins a tmode game */ + +void +initinput() +{ + /* Nothing doing... */ +} + +void +dispatch_W_key_event(evt) + W_Event *evt; +{ + int i; + + /* try to speed up response -JR */ + if (!messageon && (evt->Window == w || evt->Window == mapw)) { + keyaction(evt); + return; + } + for (i = 0; i < WNUM; i++) { + if (evt->Window == messWin[i].window) { + messageWinEvent(evt); + return; + } + } + if (evt->Window == optionWin) + optionaction(evt); + else if ( +#ifdef NOWARP + messageon || +#endif + evt->Window == messagew || + evt->Window == tstatw || + evt->Window == warnw) { + smessage(evt->key); +#ifdef SHORT_PACKETS + } else if (evt->Window == spWin) { + spaction(evt); +#endif + } else if (evt->Window == motdWin) { + motdWinEvent(evt->key); + } else if (evt->Window == playerw) { + playerwEvent(evt); + } else if (evt->Window == defWin && evt->key == ' ') { + W_UnmapWindow(defWin); +#ifdef SOUND + } else if (evt->Window == soundWin) { + soundaction(evt); +#endif +#ifdef TOOLS + } else if (evt->Window == toolsWin) { + smessage_ahead('!', evt->key); +#endif + } else { + keyaction(evt); + } +} + +void +dispatch_W_button_event(evt) + W_Event *evt; +{ + int i; + + if (evt->Window == w || evt->Window == mapw) { + buttonaction(evt); + return; + } + for (i = 0; i < WNUM; i++) { + if (evt->Window == messWin[i].window) { + messageWinEvent(evt); + return; + } + } + if (evt->Window == war) + waraction(evt); + else if (evt->Window == optionWin) + optionaction(evt); +#ifdef ATM + else if (evt->Window == udpWin) + udpaction(evt); /* UDP */ +#endif /* ATM */ +#ifdef SHORT_PACKETS + else if (evt->Window == spWin) + spaction(evt); +#endif +#ifdef SOUND + else if (evt->Window == soundWin) + soundaction(evt); +#endif + else if (evt->Window == playerw) + selectblkbozo(evt); +#ifdef MACROS + else if (evt->Window == macroWin) + switchmacros(); +#endif +#ifdef XTREKRC_HELP + else if (evt->Window == defWin) + def_action(evt); +#endif + else + buttonaction(evt); +} + +void +dispatch_W_expose_event(evt) + W_Event *evt; +{ + /* + if anything but the iconWin is refreshed, turn off the iconified flag. + [BDyess] + */ + if (evt->Window != iconWin) + iconified = 0; + if (evt->Window == statwin) + redrawStats(); + else if (evt->Window == tstatw) + redrawTstats(); + else if (evt->Window == mapw) + redrawall = 1; + else if (evt->Window == iconWin) + drawIcon(); + else if (evt->Window == helpWin) + fillhelp(); + else if (evt->Window == macroWin) + fillmacro(); + else if (evt->Window == playerw) + playerlist(); + else if (evt->Window == planetw) + planetlist(); + else if (evt->Window == planetw2) + planetlist(); + else if (evt->Window == rankw) + ranklist(); + else if (evt->Window == warnw) + W_ClearWindow(warnw); + else if (evt->Window == messagew) + message_expose(); + else if (evt->Window == motdWin) + motdWinEvent('r'); /* 'r' is refresh */ + /* + lag meter? maybe later - RF else if (evt->Window == lMeter) + redrawLMeter(); + */ + else if (evt->Window == pStats) + redrawPStats(); +#ifdef XTREKRC_HELP + else if (defWin && (evt->Window == defWin)) + showdef(); +#endif +} + +void +dispatch_W_event(evt) + W_Event *evt; +{ + switch ((int) evt->type) { + case W_EV_KEY: + dispatch_W_key_event(evt); + break; +#ifdef AUTOKEY + case W_EV_KEY_OFF: + if (autoKey) + autoKeyOff(evt); + break; +#endif /* AUTOKEY */ + case W_EV_BUTTON: + dispatch_W_button_event(evt); + break; + case W_EV_EXPOSE: + dispatch_W_expose_event(evt); + break; + default: + break; + } +} + +/* this figures out what to set war dec's */ +void autoWarDecl(scheme) + int scheme; +{ + extern int number_of_teams; + int i, j, k, *team, enemymask = 0; + struct player *pptr; + + if((team = (int *)malloc(number_of_teams * sizeof(int))) == NULL) { + perror("autoWarDecl: malloc error\n"); + return; + } + memset(team, 0, sizeof(int)*number_of_teams); + for(i=0, pptr=&players[i]; i < nplayers; i++, pptr++) + if(pptr->p_status != PFREE && !(pptr->p_status == POUTFIT && + pptr->p_teami < 0)) { + team[pptr->p_teami]++; + } + switch(scheme) { + case 1: + /* war with all non-zero member team */ + /* peace with teams with 0 players */ + for(i=0; i < number_of_teams; i++) { + if(i != me->p_teami) + enemymask ^= team[i] ? (1<<i) : 0; + /*printf("team: %i, #: %i\n", i, team[i]); + */ + } + /*printf("mask: %i\n", enemymask); + */ + break; + case 2: + /* war with only the largest enemy */ + /* team; peace with everyone else*/ + for(i=0; i < number_of_teams; i++) { + if ((i != me->p_teami) && (j < team[i])) { + j = team[i]; + k = i; + } + } + enemymask = 0 | (1 << k); + break; + } + sendWarReq(enemymask); + free(team); +} /* end of autoWarDecl */ + + +/* this new event loop allows more flexibility in state transitions */ +void +input() +{ + W_Event data; + fd_set readfds; + int wsock = W_Socket(); + int old_tourn = paradise ? status2->tourn : status->tourn, new_tourn; + +#ifdef AUTOKEY + struct timeval timeout; + + timeout.tv_sec = 0; + timeout.tv_usec = 100000; +#endif /* AUTOKEY */ + +#ifdef RECORDER + if (playback) { + pb_input(); /* recorder.c */ + return; + } +#endif + while (me->p_status == PALIVE || + me->p_status == PEXPLODE || + me->p_status == PDEAD || + me->p_status == POBSERVE) { + +#ifdef TIMELORD + /* we're playing. Count the seconds */ + update_timelord(0); +#endif + + if (keepInfo > 0) { + if (infowin_up >= 0 && + --infowin_up == -1 && + infomapped) { + destroyInfo(); + infowin_up = -2; + } + } + exitInputLoop = 0; + while (W_EventsPending() && !exitInputLoop) { + fastQuit = 0; /* any event cancel fastquit */ + W_NextEvent(&data); + dispatch_W_event(&data); + } + +#if 0 + /* + Do some enforcement of non-paradise feature disabling. The options + menu doesn't deal with this too well. + */ + if (!paradise) { + blk_zoom = 0; + blk_showStars = 0; + } +#endif +#ifndef AMIGA + FD_ZERO(&readfds); + FD_SET(wsock, &readfds); + FD_SET(sock, &readfds); + if (udpSock >= 0) + FD_SET(udpSock, &readfds); +#ifdef AUTOKEY + if (autoKey) { + doAutoKey(); + if (select(32, &readfds, (fd_set *) 0, (fd_set *) 0, &timeout) == 0) /* timeout */ + continue; + } else +#endif + select(32, &readfds, (fd_set *) 0, (fd_set *) 0, 0); +#else /* AMIGA */ +#ifdef DNET + sigsPending = Wait(wsock | sockMask | udpSockMask | SIGBREAKF_CTRL_C); +#else +/* insert code here for Amiga with TCP/IP... */ +#endif /* DNET */ + if (sigsPending & SIGBREAKF_CTRL_C) { + printf("User break, Ctrl-C, exiting!\n"); + exit(0); + } +/* note: for DNET, FD_ISSET is faked, see amigadefs.h -JR */ +#endif /* AMIGA */ + if (FD_ISSET(sock, &readfds) || + (udpSock >= 0 && FD_ISSET(udpSock, &readfds))) { + +#ifdef HANDLER_TIMES + start_log(); +#endif + intrupt(); +#ifdef HANDLER_TIMES + stop_log(64); +#endif + if (isServerDead()) { + printf("Whoops! We've been ghostbusted!\n"); + printf("Pray for a miracle!\n"); + + /* UDP fail-safe */ + commMode = commModeReq = COMM_TCP; + commSwitchTimeout = 0; + if (udpSock >= 0) + closeUdpConn(); + if (udpWin) { + udprefresh(UDP_CURRENT); + udprefresh(UDP_STATUS); + } + connectToServer(nextSocket); + printf("Yea! We've been resurrected!\n"); + } + /* + beep if tmode status changes. Idea from Roger Books. [BDyess] + */ + new_tourn = paradise ? status2->tourn : status->tourn; + + /* change war dec's at transitions to */ + /* positive tmode */ + if (!tmodeChange && new_tourn) { + autoWarDecl(autoSetWar); + tmodeChange = 1; + } + + if (old_tourn != new_tourn) { +#ifndef SOUND + W_Beep(); +#else + S_PlaySound(S_TMODE); +#endif + old_tourn = new_tourn; + } + continue; + } + } +} + + +static void +keyaction(data) + W_Event *data; +{ + unsigned char course; + struct obtype *target; + int key = data->key; + struct shiplist *temp; + + if (data->Window != mapw && data->Window != w + && data->Window != planetw && data->Window != planetw2 + && data->Window != rankw +#ifdef ATM + && data->Window != scanw +#endif /* ATM */ + ) + return; + +#ifdef RECORDER + if (playback) + pb_dokey(data); +#endif + if (localflags & PFREFIT) { + temp = shiptypes; + while (temp) { + if (temp->ship->s_letter == key) { + do_refit(temp->ship->s_type); + return; + } + temp = temp->next; + } + } else { + key = doKeymap(data); + if (key == -1) + return; + } + + switch (key) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + set_speed(key - '0'); + localflags &= ~(PFREFIT); + break; + case 'e': /* Turn off docking permission, eject docked + vessels. */ + sendDockingReq(!(me->p_flags & PFDOCKOK)); + break; + case 'r': + localflags |= PFREFIT; + warning(blk_refitstring); + break; + case control('0'): /* ctrl 0-9, speed 10-19 */ + case control('1'): + case control('2'): + case control('3'): + case control('4'): + case control('5'): + case control('6'): + case control('7'): + case control('8'): + case control('9'): + set_speed(10 + key - control('0')); + localflags &= ~(PFREFIT); + break; + case control(')'): /* ctrl-shift 0-9, speed 20-29 */ + set_speed(20); + localflags &= ~(PFREFIT); + break; + case control('!'): /* ctrl-shift-1, speed 21 */ + set_speed(21); + localflags &= ~(PFREFIT); + break; + case control('@'): /* ctrl-shift-2, speed 22 */ + set_speed(22); + localflags &= ~(PFREFIT); + break; + case control('#'): /* ctrl-shift-3, speed 23 */ + set_speed(23); + localflags &= ~(PFREFIT); + break; + case control('$'): /* ctrl-shift-4, speed 24 */ + set_speed(24); + localflags &= ~(PFREFIT); + break; + case control('%'): /* ctrl-shift-5, speed 25 */ + set_speed(25); + localflags &= ~(PFREFIT); + break; + case control('^'): /* ctrl-shift-6, speed 26 */ + set_speed(26); + localflags &= ~(PFREFIT); + break; + case control('&'): /* ctrl-shift-7, speed 27 */ + set_speed(27); + localflags &= ~(PFREFIT); + break; + case control('*'): /* ctrl-shift-8, speed 28 */ + set_speed(28); + localflags &= ~(PFREFIT); + break; + case control('('): /* ctrl-shift-9, speed 29 */ + set_speed(29); + localflags &= ~(PFREFIT); + break; + case '`': /* afterburners */ + set_speed(98); + localflags &= ~(PFREFIT); + break; + case '-': + set_speed(99); /* warp! */ + localflags &= ~(PFREFIT); + break; + case control('-'): /* suspend warp toggle [BDyess] */ + if (me->p_flags & PFWPSUSPENDED) + set_speed(96); /* unsuspend */ + else + set_speed(97); /* suspend */ + localflags &= ~(PFREFIT); + break; + case '%': /* max impulse */ + set_speed(me->p_ship->s_maxspeed); + localflags &= ~(PFREFIT); + break; + case '<': /* speed -= 1 */ + set_speed(me->p_speed - 1); + localflags &= ~(PFREFIT); + break; + case '>': /* speed += 1 */ + set_speed(me->p_speed + 1); + localflags &= ~(PFREFIT); + break; + case '#': /* halfimpulse */ + set_speed((me->p_ship->s_maxspeed + 1) / 2); + localflags &= ~(PFREFIT); + break; + case ':': /* toggle message logging */ + if (logmess) + warning("Message logging disabled"); + else + warning("Message logging enabled"); + logmess = !logmess; + break; + case '!': +#if 1 + showKitchenSink = !showKitchenSink; + warning(showKitchenSink ? + "Kitchen Sink activated. Bad guys beware!" : + "Kitchen Sink deactivated."); +#else + if (blk_altbits) { + blk_altbits = 0; + warning("Switching to old bitmaps."); + } else { + blk_altbits = 1; + warning("Switching to new bitmaps."); + } + localflags &= ~(PFREFIT); + if (optionWin) + optionredrawoption(&blk_altbits); +#endif + break; +#ifdef TIMER + case '@': + timeBank[T_USR] = time(NULL); + timerType = T_USR; + break; + case control('t'): + timerType++; + if (timerType >= T_TOTAL) + timerType = 0; + break; +#endif /* TIMER */ +#ifdef WIDE_PLIST + case 'K': /* cycle playerlist [BDyess] */ + while (*playerList && *playerList != ',') + playerList++; + if (*playerList == ',') + playerList++; + else if (*playerList == 0) + playerList = playerListStart; + break; +#endif /* WIDE_PLIST */ + case 'a': +#ifdef ATM + if (!W_IsMapped(scanwin)) { + scan(data->Window, data->x, data->y); + } else { + if (scanmapped) + W_UnmapWindow(scanwin); + scanmapped = 0; + } +#endif /* ATM */ + break; + case 'm': /* new from galaxy -- works here too */ + case '\'': /* ' starts message to 'T'eam */ +#ifdef NOWARP + message_on(); +#else + W_WarpPointer(messagew); +#endif + if((key == '\'') && (messpend==0)) { + smessage(lowercaset ? 't' : 'T'); + } + break; + case 'k': /* k = set course */ + course = getcourse(data->Window, data->x, data->y); + set_course(course); + me->p_flags &= ~(PFPLOCK | PFPLLOCK); + localflags &= ~(PFREFIT); + break; + case 'p': /* p = fire phasers */ +#ifdef AUTOKEY + if (autoKey) + autoKeyPhaserReqOn(); + else { + course = getcourse(data->Window, data->x, data->y); + sendPhaserReq(course); + } +#else + course = getcourse(data->Window, data->x, data->y); + sendPhaserReq(course); +#endif /* AUTOKEY */ + break; + case 't': /* t = launch torps */ +#ifdef AUTOKEY + if (autoKey) + autoKeyTorpReqOn(); + else { + course = getcourse(data->Window, data->x, data->y); + sendTorpReq(course); + } +#else + course = getcourse(data->Window, data->x, data->y); + sendTorpReq(course); +#endif /* AUTOKEY */ + break; + case 'f': + /* f = launch plasma torpedos */ +#ifdef AUTOKEY + if (autoKey) + autoKeyPlasmaReqOn(); + else { + course = getcourse(data->Window, data->x, data->y); + sendPlasmaReq(course); + } +#else + course = getcourse(data->Window, data->x, data->y); + sendPlasmaReq(course); +#endif /* AUTOKEY */ + break; + case 'd': /* d = detonate other torps */ +#ifdef AUTOKEY + if (autoKey) + autoKeyDetReqOn(); + else + sendDetonateReq(); +#else + sendDetonateReq(); +#endif /* AUTOKEY */ + break; + case 'D': /* D = detonate my torps */ + detmine(); +#ifdef AUTOKEY + if (autoKey) + autoKeyAllOff(); /* xx */ +#endif + break; + case '[': + shield_down(); + break; + case ']': + shield_up(); + break; + case 'u': /* u = toggle shields */ + shield_tog(); + break; + case 's': /* For Serge */ + shield_tog(); + break; + case 'b': /* b = bomb planet */ +#ifdef AUTOKEY + if (autoKey && !(localflags & PFREFIT)) + autoKeyBombReqOn(); + else + bomb_planet(); +#else + bomb_planet(); +#endif /* AUTOKEY */ + break; + case 'z': /* z = beam up */ +#ifdef AUTOKEY + if (autoKey) + autoKeyBeamUpReqOn(); + else +#endif + beam_up(); + break; + case 'x': /* x = beam down */ +#ifdef AUTOKEY + if (autoKey) + autoKeyBeamDownReqOn(); + else +#endif + beam_down(); + break; + case 'X': /* X = enter macro mode */ + macroState = 1; + warning("Macro mode"); + break; + case 'R': /* R = Go into repair mode */ + sendRepairReq(1); + break; + case 'y': + case 'T': + case '_': /* _ = turn on tractor beam */ + case '^': /* ^ = turn on pressor beam */ + if (me->p_flags & (PFTRACT | PFPRESS)) { + sendTractorReq(0, me->p_no); + if (key == 'T' || key == 'y') + break; + } + target = gettarget(data->Window, data->x, data->y, TARG_PLAYER); + me->p_tractor = target->o_num; + if (key == 'T' || key == '_') { + sendTractorReq(1, target->o_num); + } else { + sendRepressReq(1, target->o_num); + } + break; + case '$': /* turn off tractor/pressor beam */ + sendTractorReq(0, me->p_no); + break; + case 'o': /* o = dock at nearby starbase or orbit + nearest planet */ +#ifdef AUTOKEY + if (autoKey && !(localflags & PFREFIT)) + autoKeyOrbitReqOn(); + else + sendOrbitReq(1); +#else + sendOrbitReq(1); +#endif /* AUTOKEY */ + break; + case 'O': /* O = options Window */ + if (optionWin != NULL && W_IsMapped(optionWin)) + optiondone(); + else + optionwindow(); + break; + case 'Q': + sendQuitReq(); + break; + case 'q': /* fastquit */ + fastQuit = 1; + sendQuitReq(); + break; + case 'V': + { + /* configurable showlocal rotation sequence [BDyess] */ + int i, len = strlen(showLocalSequence); + for (i = 0; i < len; i++) { + if (showLocalSequence[i] - '0' == showlocal) { + showlocal = showLocalSequence[(i + 1) % len] - '0'; + break; + } + } + if (i == len) + showlocal = (*showLocalSequence) - '0'; + if (showlocal > 4) + showlocal = 4; + else if (showlocal < 0) + showlocal = 0; + } + if (optionWin) + optionredrawoption(&showlocal); + break; + case 'B': + { + /* configurable showgalactic rotation sequence [BDyess] */ + int i, len = strlen(showGalacticSequence); + for (i = 0; i < len; i++) { + if (showGalacticSequence[i] - '0' == showgalactic) { + showgalactic = showGalacticSequence[(i + 1) % len] - '0'; + break; + } + } + if (i == len) + showgalactic = (*showGalacticSequence) - '0'; + if (!paradise && showgalactic == 3) + showgalactic = 5; /* force scout ages -> MOO */ + if (showgalactic > 5) + showgalactic = 5; + else if (showgalactic < 0) + showgalactic = 0; + } + redrawall = 1; + if (optionWin) + optionredrawoption(&showgalactic); + break; + case '?': /* ? = Redisplay all message windows */ + if (!W_IsMapped(messWin[WREVIEW].window)) { + if (W_IsMapped(messWin[WALL].window)) { + int i; + for (i = 0; i < WNUM; i++) { + if (W_IsMapped(messWin[i].window)) + W_UnmapWindow(messWin[i].window); + } + } else { + W_MapWindow(messWin[WREVIEW].window); + } + } else { + W_UnmapWindow(messWin[WREVIEW].window); + W_MapWindow(messWin[WALL].window); + W_MapWindow(messWin[WTEAM].window); + W_MapWindow(messWin[WINDIV].window); + W_MapWindow(messWin[WKILL].window); + W_MapWindow(messWin[WPHASER].window); + } + if (optionWin) { + optionredrawtarget(messWin[WREVIEW].window); + optionredrawtarget(messWin[WALL].window); + optionredrawtarget(messWin[WKILL].window); + optionredrawtarget(messWin[WTEAM].window); + optionredrawtarget(messWin[WINDIV].window); + optionredrawtarget(messWin[WPHASER].window); + } + break; + case 'c': /* c = cloak */ + cloak(); + break; + case '{': /* { = cloak, no toggle */ + sendCloakReq(1); + break; + case '}': /* } = uncloak, no toggle */ + sendCloakReq(0); + break; + case 'C': /* C = coups */ + sendCoupReq(); + break; + case ';': /* ; = lock onto planet/base */ + target = gettarget(data->Window, data->x, data->y, + TARG_BASE | TARG_PLANET); + if (target->o_type == PLAYERTYPE) { + sendPlaylockReq(target->o_num); /* a base */ + me->p_playerl = target->o_num; + } else { /* It's a planet */ + sendPlanlockReq(target->o_num); + me->p_planet = target->o_num; + } + break; + case 'l': /* l = lock onto */ + target = gettarget(data->Window, data->x, data->y, + TARG_PLAYER | TARG_ASTRAL); + if (target->o_type == PLAYERTYPE) { + sendPlaylockReq(target->o_num); + me->p_playerl = target->o_num; + } else { /* It's a planet */ + sendPlanlockReq(target->o_num); + me->p_planet = target->o_num; + } + break; + case '/': /* toggle sorted player list */ + sortPlayers = !sortPlayers; + break; + case '*': /* send in practice robot */ + sendPractrReq(); + break; + /* Start of display functions */ + case ' ': /* ' ' = clear special windows */ + W_UnmapWindow(planetw); + W_UnmapWindow(planetw2); + W_UnmapWindow(rankw); + if (infomapped) + destroyInfo(); + W_UnmapWindow(helpWin); + W_UnmapWindow(war); + if (optionWin) + optiondone(); +#ifdef ATM + if (scanmapped) { + W_UnmapWindow(scanwin); + scanmapped = 0; + } + if (udpWin) + udpdone(); +#endif /* ATM */ +#ifdef XTREKRC_HELP + if (defWin) + W_UnmapWindow(defWin); +#endif + break; + case 'E': /* E = send emergency call */ + if (F_gen_distress) + rcd(generic, data); + else + emergency(); + break; + case 'F': /* F = send carry report */ + if (F_gen_distress) + rcd(carrying, data); + else + carry_report(); + break; + case 'L': /* L = Player list */ + if (W_IsMapped(playerw)) { + W_UnmapWindow(playerw); + } else { + W_MapWindow(playerw); + } + break; + case 'P': /* P = Planet list */ + if (W_IsMapped(planetw)) { + W_UnmapWindow(planetw); + W_UnmapWindow(planetw2); + } else { + W_MapWindow(planetw); + W_MapWindow(planetw2); + } + break; + case 'U': /* U = Rank list */ + if (W_IsMapped(rankw)) { + W_UnmapWindow(rankw); + } else { + W_MapWindow(rankw); + } + break; + case 'S': /* S = toggle stat mode */ + if (W_IsMapped(statwin)) { + W_UnmapWindow(statwin); + } else { + W_MapWindow(statwin); + } + break; +#ifdef nodef /* people hit this by accident and think the + client crashed */ + case 'M': /* M = Toggle Map mode */ + mapmode = !mapmode; + if (optionWin) + optionredrawoption(&mapmode); + break; +#endif + case 'M': /* map the motd window */ + showMotdWin(); + break; + case 'N': /* N = Toggle Name mode */ + namemode = !namemode; + if (optionWin) + optionredrawoption(&namemode); + break; + case 'i': /* i = get information */ + case 'I': /* I = get extended information */ + case control('i'): /* ^i = info on a planet [BDyess] */ + if (!infomapped) + inform(data->Window, data->x, data->y, key); + else + destroyInfo(); + break; + case 'h': /* h = Map help window */ + if (W_IsMapped(helpWin)) { + W_UnmapWindow(helpWin); + } else { + W_MapWindow(helpWin); + } + if (optionWin) + optionredrawtarget(helpWin); + break; + case 'w': /* w = map war stuff */ + if (W_IsMapped(war)) + W_UnmapWindow(war); + else + warwindow(); + break; +#ifdef ATM + case '+': /* UDP: pop up UDP control window */ + if (udpWin != NULL && W_IsMapped(udpWin)) + udpdone(); + else { + char buf[80]; + udpwindow(); + sprintf(buf, "UDP client version %.1f", + (float) UDPVERSION / 10.0); + warning(buf); + } + if (optionWin) + optionredrawtarget(udpWin); + break; + case '=': /* UDP: request for full update */ + sendUdpReq(COMM_UPDATE); + break; +#endif /* ATM */ + + case 9: /* tab */ + case control('m'): /* because you can't remap to tab */ + /* actually, you can, put a literal + TAB in a ckeymap entry and it works. + So should we keep this? -JR */ + if(paradise) { + blk_zoom = !blk_zoom; + redrawall = 1; + auto_zoom_timer = udcounter+autoZoomOverride; + if (optionWin) + optionredrawoption(&blk_zoom); + } + break; +#ifdef SHORT_PACKETS + case '~': + if (spWin != NULL && W_IsMapped(spWin)) + spdone(); + else + spwindow(); + if (optionWin) + optionredrawtarget(spWin); + break; + case '\\': + sendShortReq(SPK_SALL); + break; + case '|': + sendShortReq(SPK_ALL); + break; +#endif + case ',': + if (W_IsMapped(pStats)) { + W_UnmapWindow(pStats); + } else { + W_MapWindow(pStats); + redrawPStats(); + } + if (optionWin) + optionredrawtarget(pStats); + break; + case '&': /* reread defaults file */ + if (defaultsFile) { + char buf[150]; + sprintf(buf, "Reading defaults from %s", defaultsFile); + warning(buf); + freeDefaults(); + defaultsFile = initDefaults(defaultsFile); + resetDefaults(); + } else { + warning("No defaults file to read from!"); + } + break; +#ifdef ROTATERACE + case '(': + rotate--; + if (rotate < 0) + rotate = 3; + if (optionWin) + optionredrawoption(&rotate); + rotate_all(); + break; + case ')': + rotate++; + if (rotate > 3) + rotate = 0; + if (optionWin) + optionredrawoption(&rotate); + rotate_all(); + break; +#endif + +#ifdef RECORDER + case control('r'): + stopRecorder(); + break; +#endif + +#ifdef SOUND + case control('s'): + S_SoundWindow(); + break; +#endif +#ifdef TOOLS + case '\"': + showToolsWin(); + break; +#endif +#ifdef AMIGA + case 'A': + { + extern int flush_speech; + flush_speech = 1; + break; + } +#endif /* AMIGA */ + default: + W_Beep(); + break; + } +} + +static void +buttonaction(data) + W_Event *data; +{ + unsigned char course; + +#ifdef NOWARP + if (messageon) + message_off(); /* ATM */ +#endif + + if (data->Window != w && data->Window != mapw +#ifdef ATM + && data->Window != scanwin +#endif /* ATM */ + ) + return; + + data->key--; + if (data->key >= 0 && data->key < 12) { + if (myship->s_buttonmap[data->key] != '\0') { + data->key = myship->s_buttonmap[data->key]; +#if 0 /* do NOT bypass keymap */ + data->key += 256; /* simulate alt key so keymap is bypassed + [BDyess] */ +#endif + keyaction(data); + return; + } else + data->key = data->key % 3; + /* if alt key is pressed, do default */ + } if (data->key > 11) + data->key -= 12; + data->key++; + if (data->key == W_RBUTTON) { + course = getcourse(data->Window, data->x, data->y); + set_course(course); + } else if (data->key == W_LBUTTON) { + course = getcourse(data->Window, data->x, data->y); + sendTorpReq(course); + } else if (data->key == W_MBUTTON) { + course = getcourse(data->Window, data->x, data->y); + sendPhaserReq(course); + } +} + +/* + * changed from unsigned char to irint() for precise rounding (from Leonard + * Dickens) + * + * changed from irint (which ULTRIX doesn't have in its math.h header) to + * floor(x+0.5) for portability. + */ + + + +int +getcourse(ww, x, y) + W_Window ww; + int x, y; +{ + if (ww == mapw) { + int me_x, me_y; + register gwidth, offsetx, offsety; + + if (blk_zoom) { + gwidth = blk_gwidth / 2; + offsetx = zoom_offset(me->p_x); + offsety = zoom_offset(me->p_y); + } else { + gwidth = blk_gwidth; + offsetx = 0; + offsety = 0; + } + me_x = (me->p_x - offsetx) * WINSIDE / gwidth; + me_y = (me->p_y - offsety) * WINSIDE / gwidth; + + return (unsigned char)(int) + floor(0.5 + atan2((double) (x - me_x), + (double) (me_y - y)) + / 3.14159 * 128.); + + + } else { + + double result = atan2((double) (x - WINSIDE / 2), + (double) (WINSIDE / 2 - y)) / 3.14159 * 128.; + + return (unsigned char) (int) floor (result + 0.5); + } +} +#ifdef ATM +static void +scan(w, x, y) + W_Window w; + int x, y; +{ +} +#endif /* ATM */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/interface.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,122 @@ +/* $Id: interface.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +/* + * interface.c + * + * This file will include all the interfaces between the input routines + * and the daemon. They should be useful for writing robots and the + * like + */ +#include "copyright.h" + +#include <stdio.h> +#include <math.h> +#include <sys/types.h> +#include <sys/time.h> +#ifndef sgi +#include <sys/timeb.h> +#endif /* sgi */ +#include <signal.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "packets.h" +#include "proto.h" + +void +set_speed(speed) + int speed; +{ + /* don't repeat useless commands [BDyess] */ + if (me->p_desspeed != speed || me->p_speed != speed) + sendSpeedReq(speed); + me->p_desspeed = speed; +} + +void +set_course(dir) + unsigned int dir; +{ + /* don't repeat commands [BDyess] */ + if (me->p_desdir != dir || me->p_dir != dir) + sendDirReq(dir); + me->p_desdir = dir; +} + +void +shield_up() +{ + if (!(me->p_flags & PFSHIELD)) { + sendShieldReq(1); + } +} + +void +shield_down() +{ + if (me->p_flags & PFSHIELD) { + sendShieldReq(0); + } +} + +void +shield_tog() +{ + if (me->p_flags & PFSHIELD) { + sendShieldReq(0); + } else { + sendShieldReq(1); + } +} + +void +bomb_planet() +{ + if (!(me->p_flags & PFBOMB)) { + sendBombReq(1); + } +} + +void +beam_up() +{ + if (!(me->p_flags & PFBEAMUP)) { + sendBeamReq(1); /* 1 means up... */ + } +} + +void +beam_down() +{ + if (!(me->p_flags & PFBEAMDOWN)) { + sendBeamReq(2); /* 2 means down... */ + } +} + +void +cloak() +{ + if (me->p_flags & PFCLOAK) { + sendCloakReq(0); + } else { + sendCloakReq(1); + } +} + +int +mtime() +{ +#if 0 + struct timeb tm; + + ftime(&tm); + /* mask off 16 high bits and add in milliseconds */ + return (tm.time & 0x0000ffff) * 1000 + tm.millitm; +#else + struct timeval tv; + + gettimeofday(&tv, (struct timezone *) 0); + return (tv.tv_sec & 0x0ffff) * 1000 + tv.tv_usec / 1000; +#endif +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/keymap.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,240 @@ +/* $Id: keymap.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +/* + * keymap.c + * Bill Dyess, 10/20/93 + */ + +#include "copyright.h" +#include <stdio.h> +/*#include <sys/types.h> +#ifdef RS6K +#include <sys/select.h> +#endif +#include <signal.h> +#include <errno.h> +#include "packets.h"*/ +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "proto.h" + +#define control(x) (x)+128 + +int +doKeymap(data) + W_Event *data; +{ + int key = data->key; + +#ifdef MACROS + if (macroState) { /* macro needed a destination or in macro + mode */ + if (key > 256 && data->type != W_EV_BUTTON) { /* an alt-key will exit + the macro mode */ + /* + but let mouse buttons do macros! button conversion is done by + calling function. + */ + warning(" "); + } else { + if (key > 256) + data->key -= 256; + doMacro(data); + return -1; + } + } +#endif /* MACROS */ + + if (key < 256) { /* not alt key */ + key = myship->s_keymap[key]; + +#ifdef MACROS + if (macrotable[key] && (macrotable[key]->flags & MACSINGLE)) { + data->key = key; + doMacro(data); + return -1; + } +#endif /* MACROS */ + + } else + key = key - 256; + return key; +} + +unsigned char def_keymap[256]; +unsigned char def_buttonmap[12]; +void +buildShipKeymap(shipp) + struct ship *shipp; +{ + char keybuf[40], ckeybuf[40], buttonbuf[40], cbuttonbuf[40]; + struct stringlist *l; + + bcopy(def_keymap, shipp->s_keymap, 256); + bcopy(def_buttonmap, shipp->s_buttonmap, 12); + + sprintf(keybuf, "keymap.%c%c", shipp->s_desig[0], shipp->s_desig[1]); + sprintf(ckeybuf, "ckeymap.%c%c", shipp->s_desig[0], shipp->s_desig[1]); + sprintf(buttonbuf, "buttonmap.%c%c", shipp->s_desig[0], shipp->s_desig[1]); + sprintf(cbuttonbuf, "cbuttonmap.%c%c", shipp->s_desig[0], shipp->s_desig[1]); + + for (l = defaults; l; l = l->next) { + if (!strcmpi(keybuf, l->string)) + keymapAdd(l->value, shipp->s_keymap); + else if (!strcmpi(ckeybuf, l->string)) + ckeymapAdd(l->value, shipp->s_keymap); + else if (!strcmpi(buttonbuf, l->string)) + buttonmapAdd(l->value, shipp->s_buttonmap); + else if (!strcmpi(cbuttonbuf, l->string)) + cbuttonmapAdd(l->value, shipp->s_buttonmap); + } +} + +void +initkeymap(type) + int type; +{ + char keybuf[40], ckeybuf[40], buttonbuf[40], cbuttonbuf[40]; + struct ship *sh; + int i, j; + struct stringlist *l; + + keybuf[0] = ckeybuf[0] = buttonbuf[0] = cbuttonbuf[0] = 0; + + if (type < 0) { + for (i = 0; i < 256; i++) + def_keymap[i] = i; + + for (l = defaults; l; l = l->next) { + if (!strcmpi("keymap", l->string)) + keymapAdd(l->value, def_keymap); + else if (!strcmpi("ckeymap", l->string)) + ckeymapAdd(l->value, def_keymap); + else if (!strcmpi("buttonmap", l->string)) + buttonmapAdd(l->value, def_buttonmap); + else if (!strcmpi("cbuttonmap", l->string)) + cbuttonmapAdd(l->value, def_buttonmap); + } + + for (j = 0; j < nshiptypes; j++) { + buildShipKeymap(getship(j)); + } + } +} + +void +keymapAdd(str, map) + char *str, *map; +{ + if (str) { + /* parse non-control char keymap */ + while (*str != '\0' && *(str + 1) != '\0') { + if (*str >= 32 && *str < 127) { + map[(int) *str] = *(str + 1); + } + str += 2; + } + } +} + +void +ckeymapAdd(cstr, map) + char *cstr, *map; +{ + unsigned char key[2]; + short state = 0; + + if (cstr) { + /* + control chars are allowed, so use ^char to mean control, and ^^ to + mean ^ + */ + while (*cstr != '\0') { + if (*cstr == '^') { + cstr++; + if (*cstr == '^' || !*cstr) + key[state] = '^'; + else + key[state] = 128 + *cstr; + } else { + key[state] = *cstr; + } + if (*cstr) + cstr++; + if (state) + map[key[0]] = key[1]; + state = 1 - state; + } + } +} + +void +buttonmapAdd(str, map) + char *str, *map; +{ + unsigned char button, ch; + + if (str) { + while (*str != '\0' && *(str + 1) != '\0') { + if (*str < 'a') + button = *str++ - '1'; + else + button = 9 + *str++ - 'a'; + if (button > 11) + fprintf(stderr, "%c ignored in buttonmap\n", *(str - 1)); + else { + ch = *str++; + map[button] = ch; + } + } + } +} + +void +cbuttonmapAdd(cstr, map) + char *cstr, *map; +{ + unsigned char button, ch; + + if (cstr) { + while (*cstr != '\0' && *(cstr + 1) != '\0') { + /* + code for cbuttonmap, which allows buttons to be mapped to + control keys. [BDyess] + */ + if (*cstr < 'a') + button = *cstr++ - '1'; + else + button = 9 + *cstr++ - 'a'; + if (button > 11) + fprintf(stderr, "%c ignored in cbuttonmap\n", *(cstr - 1)); + else { + ch = *cstr++; + if (ch == '^') { + ch = *cstr++; + if (ch != '^') + ch += 128; + } + map[button] = ch; + } + } + } +} + +#ifdef KEYMAP_DEBUG +void +dumpKeymap() +{ + int i; + + for (i = 0; i < 256; i++) { + printf("%3d %c : %3d %c\n", + i, + isprint(i) ? i : '_', + myship->s_keymap[i], + isprint(myship->s_keymap[i]) ? myship->s_keymap[i] : '_'); + } +} +#endif /* KEYMAP_DEBUG */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/macros.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,1032 @@ +/* $Id: macros.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +/* here's pretty much all the macro code. */ +/* This bears little resemblance to the */ +/* BRM code, i.e. it's somewhat organized :)*/ +/* Bill Dyess 10/05/93 [BDyess]*/ + +#ifdef MACROS +#include"copyright.h" +#include<stdio.h> +#if !defined(SVR4) && !defined(sparc) +#include<strings.h> +#else +#include<string.h> +#endif /* !SVR4 && !sparc */ +#include<ctype.h> +#include<fcntl.h> +#include<sys/types.h> +#include"Wlib.h" +#include"data.h" +#include"defs.h" +#include"struct.h" +#include"gameconf.h" +#include"proto.h" + +#define MAXMACRO 4096 +#if defined(__STDC__) || defined(RS6K) || defined(sgi) +typedef signed char s_char; +#else +typedef char s_char; +#endif + +/* prototypes */ +void doMacro2 P((struct macro * m, W_Event * data)); +void handle_dollar P((char **locpntr, char **destpntr, W_Event * data)); +void handle_special P((char **locpntr, char **destpntr, W_Event * data)); +char *strtoupper P((char *buf)); +char *strtolower P((char *buf)); +void handle_test P((char **locpntr, char **destpntr, W_Event * data)); +void handle_conditional P((char **locpntr, char **destpntr, W_Event * data)); +void getTestString P((char *buf, char **locpntr, char **destpntr, W_Event * data)); +void getConditionalString P((char **locpntr, char **destpntr, W_Event * data)); +void ignoreConditionalString P((char **locpntr)); + +int abortflag = 0; + +void +initMacros() +{ + struct stringlist *s; + char *loc; + unsigned char ch; + struct macro *m; + int i; + struct dmacro_list *dm; + struct dmacro_list *dm_def; + int notdone; + unsigned char c; + char *str; + + /* initialize macro lookup tables */ + bzero(macrotable, sizeof(struct macro *) * 256); + +#ifdef RC_DISTRESS + /* sizeof doesn't work if it isn't in the same source file, shoot me */ + MCOPY(dist_defaults, dist_prefered, sizedist); +#endif + + for (s = defaults; s; s = s->next) { +#ifdef RC_DISTRESS + if (strncmpi(s->string, "dist.", 5) == 0) { + str = (s->string) + 5; + if (*str == '^') { + str++; + if (*str == '^') + c = '^'; + else + c = *str + 128; + } else + c = *str; + str++; + if (*str != '.') { + str = (s->string) + 4; + c = '\0'; + } + str++; + + notdone = 1; + for (dm = &dist_prefered[take], dm_def = &dist_defaults[take], i = take; + dm->name && notdone; dm++, dm_def++, i++) { + if (strcmpi(str, dm->name) == 0) { + dm->macro = strdup(s->value); + if (c) { + if (!macrotable[c]) { + macrotable[c] = (struct macro *) malloc(sizeof(struct macro)); + bzero(macrotable[c], sizeof(struct macro)); + } + macrotable[c]->flags |= MACRCD; + macrotable[c]->to = i; +/* printf("dist.%c.%s: %s\n",c,dm->name,dm->macro);*/ + dm->c = c; + dm_def->c = c; + } + notdone = 0; + } + } + } +#endif /* RC_DISTRESS */ +#ifdef BEEPLITE + + else if (strncmpi(s->string, "lite.", 5) == 0) { + int offset = 5; + char **lt; + + if (s->string[6] == '.') + offset = 7; + + notdone = 1; + + for (lt = &distlite[take], dm = &dist_prefered[take]; + dm->name && notdone; dm++, lt++) { + if (strcmpi(s->string + offset, dm->name) == 0) { + *lt = strdup(s->value); +/* printf("lite.%s: %s\n",dm->name,*lt);*/ + + notdone = 0; + } + } + if (notdone) + fprintf(stderr, "Unknown lite %s\n", s->string + offset); + } +#endif /* BEEPLITE */ + if (!strncmpi("mac", s->string, 3)) { + if (s->string[3] == '.') + loc = s->string + 4; + else if (strncmpi("ro.", s->string + 3, 3)) + continue; + else + loc = s->string + 6; + if (*loc == '^') { /* possible control char */ + loc++; + if (*loc == '^' && *loc) + ch = '^'; + else + ch = *loc + 128; + } else + ch = *loc; + loc++; + if (!macrotable[ch]) { + /* + make sure it doesn't already exist. I've allowed people + to have singlemacro: before the macro.*.* statements, so + it is possible + */ + /* + modified to allow multline macros by creating a linked + list of macro structures. -JR + */ + if (ch == '?') { + printf("Can't use '?' as a macro. It is reserved for the macro window. Ignoring.\n"); + continue; + } + macrotable[ch] = m = (struct macro *) malloc(sizeof(struct macro)); + bzero(m, sizeof(struct macro)); + } else { +#ifdef RC_DISTRESS + if (macrotable[ch]->flags & MACRCD) { + m = macrotable[ch]; + m->flags &= ~(MACRCD); /* in case singleMacro was + set */ + m->next = 0; + } else +#endif + { + m = (struct macro *) malloc(sizeof(struct macro)); + m->next = macrotable[ch]; + macrotable[ch] = m; + m->next->flags |= MACMULTI; + m->flags = m->next->flags; + } + } + if (*(loc++) != '.') + m->to = -2; /* no destination given */ + else { + ch = *loc; + if (ch == '%') { + m->specialto = toupper(*(loc + 1)); + m->to = -1; + } else { + m->to = ch; + } + } + m->string = strdup(s->value); + } else if (!strncmpi("singlemacro", s->string, 11)) { + loc = s->value; + while (*loc) { + ch = *(loc++); + if (ch == '^') {/* for control chars */ + if (*loc != '^' && *loc) + ch = *loc + 128; + loc++; + } + if (!macrotable[ch]) { + m = macrotable[ch] = (struct macro *) malloc(sizeof(struct macro)); + bzero(m, sizeof(struct macro)); + m->flags = MACSINGLE; + } else { + for (m = macrotable[ch]; m; m = m->next) + m->flags |= MACSINGLE; + } + } + } + } + for (i = 0; i < 256; i++) { + /* eliminate any macros that have (null) macro strings */ + if (macrotable[i] && !(macrotable[i]->flags & MACRCD)) { + struct macro *tmp, **scan; + + scan=¯otable[i]; + while (*scan) { + if ( (*scan)->string ) { + scan = &(*scan)->next; + } else { + tmp = (*scan); + *scan = tmp->next; + free(tmp); + } + } + } + } +#ifdef RC_DISTRESS + /* + make macro entries for the default RCD keys, if those keys don't have + macros defined + */ + for (dm = &dist_prefered[take], i = take; dm->name; dm++, i++) { + if (!macrotable[dm->c]) { + macrotable[dm->c] = (struct macro *) malloc(sizeof(struct macro)); + bzero(macrotable[dm->c], sizeof(struct macro)); + macrotable[dm->c]->flags = MACRCD; + macrotable[dm->c]->to = i; + } + } +#endif +} + +void +doMacro(data) + W_Event *data; +/* takes a key as input and creates a string that is then sent to smessage*/ +{ + static struct macro *m; + int key = data->key; + + if (key == '?') { + showMacroWin(); + macroState = 0; + return; + } + if (macroState != 2) + m = macrotable[key]; + if (!m) { + W_Beep(); + warning("No such macro"); + macroState = 0; + return; /* no macro */ + } +#ifdef RC_DISTRESS + if (m->flags & MACRCD) { + rcd(m->to, data); + macroState = 0; + return; + } +#endif + while (m) { + if (macroState == 2) { + m->to = key; + doMacro2(m, data); + m->to = -2; + } else { + doMacro2(m, data); + if (macroState == 2) + return; + } + m = m->next; + } + macroState = 0; + warning(" "); +} + +void +doMacro2(m, data) + struct macro *m; + W_Event *data; +{ + int group = -1, recip = 0; + char buf[MAXMACRO], sourcebuf[MAXMACRO]; + char *loc, *dest; + struct obtype *target; + + /* first figure out who I'm going to send it to */ + if ((s_char)m->to == -1) { /* special recipient */ + switch (m->specialto) { + case 'I': /* send a message to myself */ + case 'C': + group = MINDIV; + recip = me->p_no; + break; + case 'U': /* send message to player nearest mouse */ + case 'P': + group = MINDIV; + target = gettarget(data->Window, data->x, data->y, TARG_PLAYER); + recip = target->o_num; + break; + case 'T': /* send message to team of the player nearest + mouse */ + case 'Z': + group = MTEAM; + target = gettarget(data->Window, data->x, data->y, TARG_PLAYER); + recip = idx_to_mask(players[target->o_num].p_teami); + break; + case 'G': /* send message to nearest friendly player to + my ship */ + group = MINDIV; + target = gettarget((W_Window) 0, me->p_x, me->p_y, + TARG_PLAYER | TARG_FRIENDLY); + recip = target->o_num; + break; + case 'H': /* send message to nearest enemy player to my + ship */ + group = MINDIV; + target = gettarget((W_Window) 0, me->p_x, me->p_y, + TARG_PLAYER | TARG_ENEMY); + recip = target->o_num; + break; + default: + warning("Bad macro - incorrect 'to' field"); + break; + } + } else if ((s_char)m->to == -2) { /* get recipient not provided, so change + state to get one */ + macroState = 2; + warning("Send macro to who?"); + return; + } else + recip = m->to; + /* now parse the macro itself. */ + strcpy(sourcebuf, m->string); + loc = sourcebuf; + dest = buf; + while (*loc) { + if (*loc == '$') { + loc++; + handle_dollar(&loc, &dest, data); /* handle the special escape */ + } else if (*loc == '%') { + loc++; + if (*loc == '*') + return; /* %* means exit macro NOW */ + handle_special(&loc, &dest, data); /* handle the special escape */ + } else { + *(dest++) = *(loc++); + } + } + *dest = 0; + if (buf[0] == 0 || abortflag) { /* abortflag means somewhere there + was a %* */ + abortflag = 0; + macroState = 0; + return; /* null message. If you *really* want to + print a null message, use <space> */ + } + if (group == -1) + group = getgroup(recip, &recip); + if (group <= 0) + return; + if ((m->flags & MACMULTI) && (F_multiline_enabled || paradise)) + group |= MMACRO; + pmessage(buf, recip, group); +} + +void +handle_special(locpntr, destpntr, data) + char **locpntr, **destpntr; + W_Event *data; +{ + char ch = **locpntr; + char *buf = *destpntr; + struct obtype *target; + struct macro *m; + int targettype = 0; + struct id *id; + /* for pingstats */ +#if 0 + extern int ping_iloss_sc; /* inc % loss 0--100, server to client */ + extern int ping_iloss_cs; /* inc % loss 0--100, client to server */ +#endif /* 0 */ + extern int ping_tloss_sc; /* total % loss 0--100, server to client */ + extern int ping_tloss_cs; /* total % loss 0--100, client to server */ +#if 0 + extern int ping_lag; /* delay in ms of last ping */ +#endif /* 0 */ + extern int ping_av; /* average rt */ + extern int ping_sd; /* standard deviation */ + + switch (ch) { + case 'a': /* armies carried by sender */ + sprintf(buf, "%d", me->p_armies); + break; + case 'd': /* sender damage percentage */ + sprintf(buf, "%d", 100 * me->p_damage / me->p_ship->s_maxdamage); + break; + case 's': /* sender shield percentage */ + sprintf(buf, "%d", 100 * me->p_shield / me->p_ship->s_maxshield); + break; + case 'f': /* sender fuel percentage */ + sprintf(buf, "%d", 100 * me->p_fuel / me->p_ship->s_maxfuel); + break; + case 'w': /* sender wtemp percentage */ + sprintf(buf, "%d", 100 * me->p_wtemp / me->p_ship->s_maxwpntemp); + break; + case 'e': /* sender etemp percentage */ + sprintf(buf, "%d", 100 * me->p_etemp / me->p_ship->s_maxegntemp); + break; + case 'r': /* team id character of target player */ + target = gettarget(data->Window, data->x, data->y, TARG_PLAYER); + buf[0] = teaminfo[players[target->o_num].p_teami].letter; + buf[1] = 0; + break; + case 't': /* team id character of target planet */ + target = gettarget(data->Window, data->x, data->y, TARG_PLANET); + buf[0] = teaminfo[mask_to_idx(planets[target->o_num].pl_owner)].letter; + buf[1] = 0; + break; + case 'p': /* id character of target player */ + targettype = TARG_PLAYER; + case 'g': /* id character of target friendly player */ + if (!targettype) + targettype = TARG_PLAYER | TARG_FRIENDLY; + case 'h': /* id char of target enemy player */ + if (!targettype) + targettype = TARG_PLAYER | TARG_ENEMY; + id = getTargetID(data->Window, data->x, data->y, targettype); + buf[0] = id->mapstring[1]; + buf[1] = 0; + break; + case 'P': /* id character of player nearest sender */ + id = getTargetID((W_Window) 0, me->p_x, me->p_y, TARG_PLAYER); + buf[0] = id->mapstring[1]; + buf[1] = 0; + break; + case 'T': /* team id character of sender team */ + buf[0] = me->p_mapchars[0]; + buf[1] = 0; + break; + case 'c': /* sender id character */ + buf[0] = me->p_mapchars[1]; + buf[1] = 0; + break; + case 'C': /* 1 if cloaked, 0 if not [BDyess] */ + if (me->p_flags & PFCLOAK) + buf[0] = '1'; + else + buf[0] = '0'; + buf[1] = 0; + break; + case 'n': /* armies on target planet */ + target = gettarget(data->Window, data->x, data->y, TARG_PLANET); + sprintf(buf, "%d", planets[target->o_num].pl_info ? + planets[target->o_num].pl_armies : + -1); + break; + case 'E': /* 1 if etemped, 0 if not */ + if (me->p_flags & PFENG) + buf[0] = '1'; + else + buf[0] = '0'; + buf[1] = 0; + break; + case 'W': /* 1 if wtemped, 0 if not */ + if (me->p_flags & PFWEP) + buf[0] = '1'; + else + buf[0] = '0'; + buf[1] = 0; + break; + case 'S': /* sender two character ship type */ + strncpy(buf, me->p_ship->s_desig, 2); + buf[2] = 0; + break; + case 'G': /* id char of friendly player nearest sender */ + targettype = TARG_FRIENDLY; + case 'H': /* id char of enemy player nearest sender */ + if (!targettype) + targettype = TARG_ENEMY; + id = getTargetID((W_Window) 0, me->p_x, me->p_y, + TARG_PLAYER | targettype); + buf[0] = id->mapstring[1]; + buf[1] = 0; + break; + case 'l': /* three character name of target planet */ + case 'L': + id = getTargetID(data->Window, data->x, data->y, TARG_PLANET); + strcpy(buf, id->mapstring); + buf[0] = tolower(buf[0]); + break; + case 'i': /* sender full player name (16 character max) */ + case 'I': + strncpy(buf, me->p_name, 16); + buf[16] = 0; + break; + case 'u': /* full name of target player (16 character + max) */ + case 'U': + id = getTargetID(data->Window, data->x, data->y, TARG_PLAYER); + strncpy(buf, id->name, 16); + buf[16] = 0; + break; + case 'z': /* 3 letter team id of target planet */ + case 'Z': + id = getTargetID(data->Window, data->x, data->y, TARG_PLANET); + strcpy(buf, teaminfo[id->team].shortname); + strtolower(buf); + break; + case 'b': /* nearest planet to sender */ + case 'B': + id = getTargetID((W_Window) 0, me->p_x, me->p_y, TARG_PLANET); + strcpy(buf, id->mapstring); + buf[0] = tolower(buf[0]); + break; + case 'v': /* average ping round trip time */ + sprintf(buf, "%d", ping_av); + break; + case 'V': /* ping stdev */ + sprintf(buf, "%d", ping_sd); + break; + case 'y': /* packet loss */ + sprintf(buf, "%d", (2 * ping_tloss_sc + ping_tloss_cs) / 3); + break; + case 'm': /* last message */ + case 'M': + strcpy(buf, lastMessage); + break; + case 'o': /* insert three letter team name */ + case 'O': + strcpy(buf, teaminfo[me->p_teami].shortname); + break; + case ' ': /* nothing. This is so you can start a macro + with spaces */ + buf[0] = ' '; + buf[1] = 0; + break; + case '%': /* insert % */ + buf[0] = '%'; + buf[1] = 0; + break; + case '?': /* start test */ + (*locpntr)++; + handle_test(locpntr, destpntr, data); + return; + case '{': /* conditional */ + handle_conditional(locpntr, destpntr, data); + return; + case '*': /* abort! */ + abortflag = 1; + return; + case '2': /* is paradise? sorry, ran out of good + letters. '2' means, 'is Netrek II?'. */ + buf[0] = paradise + '0'; + buf[1] = 0; + break; + case '_': /* call another macro. Added 1/24/94 [BDyess] */ + (*locpntr)++; + if (**locpntr == '^') { /* control char */ + (*locpntr)++; + m = macrotable[**locpntr + (**locpntr == '^') ? 0 : 128]; + } else { + m = macrotable[(int) **locpntr]; + } + if (m) { /* does the macro exist? */ + char temp[MAXMACRO]; + strcpy(temp, m->string); + strcat(temp, *locpntr + 1); + strcpy(*locpntr + 1, temp); + } else { /* somebody screwed up */ + printf("Error: called macro "); + if (&m - macrotable >= 128) + putchar('^'); + printf("%c doesn't exist.\n", **locpntr); + } + buf[0] = 0; + break; + default: + sprintf(buf, "Unknown %% escape: %%%c", ch); + warning(buf); + buf[0] = 0; + break; + } + if (isupper(ch)) + strtoupper(buf); + (*locpntr)++; + while (**destpntr) + (*destpntr)++; + return; +} + +void +handle_test(locpntr, destpntr, data) + char **locpntr, **destpntr; + W_Event *data; +{ + char l[MAXMACRO], r[MAXMACRO], condition = 0; + short trueflag = 0; + + getTestString(l, locpntr, destpntr, data); + if (**locpntr != '%') { + condition = *((*locpntr)++); + getTestString(r, locpntr, destpntr, data); + } + switch (condition) { + case '=': + if (!strcmp(l, r)) + trueflag = 1; + break; + case '>': + if (atoi(l) > atoi(r)) + trueflag = 1; + break; + case '<': + if (atoi(l) < atoi(r)) + trueflag = 1; + break; + default: + if (atoi(l)) + trueflag = 1; + } + **destpntr = '0' + trueflag; + *(*destpntr + 1) = 0; + (*destpntr)++; + return; +} + +void +handle_conditional(locpntr, destpntr, data) + char **locpntr, **destpntr; + W_Event *data; +{ + (*locpntr)++; + **destpntr = 0; + (*destpntr)--; + if (**destpntr == '0') { + ignoreConditionalString(locpntr); + getConditionalString(locpntr, destpntr, data); + } else { + getConditionalString(locpntr, destpntr, data); + ignoreConditionalString(locpntr); + } + (*locpntr) += 2; + while (**destpntr) + (*destpntr)++; + return; +} + +void +ignoreConditionalString(locpntr) + char **locpntr; +{ + int depth = 0, breakflag = 0; + + while (**locpntr) { + if (**locpntr == '%') { + switch (*(*locpntr + 1)) { + case '!': + if (!depth) + breakflag = 1; + (*locpntr) += 2; + break; + case '}': + if (depth) { + depth--; + (*locpntr) += 2; + } else + breakflag = 1; + break; + case '{': + depth++; + (*locpntr) += 2; + break; + case '*': + abortflag = 1; + return; + default: + (*locpntr)++; + } + if (breakflag) + break; + } else + (*locpntr)++; + } +} + +void +getConditionalString(locpntr, destpntr, data) + char **locpntr, **destpntr; + W_Event *data; +{ + char *dest = *destpntr; + + while (**locpntr) { + if (**locpntr != '%' && **locpntr != '$' && **locpntr) + *(dest++) = *((*locpntr)++); + else if (*(*locpntr + 1) == '!') { + (*locpntr) += 2; + break; + } else if (*(*locpntr + 1) == '}') + break; + else if (**locpntr == '%') { + (*locpntr)++; + handle_special(locpntr, &dest, data); + while (*(dest++)); + dest--; + } else { /* **locpntr must equal '$' */ + (*locpntr)++; + handle_dollar(locpntr, &dest, data); + while (*(dest++)); + dest--; + } + } + *dest = 0; + return; +} + +void +getTestString(buf, locpntr, destpntr, data) + char *buf, **locpntr, **destpntr; + W_Event *data; +{ + char *dest = buf; + + if (**locpntr == '%') { + (*locpntr)++; + handle_special(locpntr, &buf, data); + } else if (**locpntr == '$') { + (*locpntr)++; + handle_dollar(locpntr, &buf, data); + } else { + while (**locpntr != '%' && **locpntr != '$' && **locpntr != '<' && + **locpntr != '>' && **locpntr != '=' && + **locpntr) + *(dest++) = *((*locpntr)++); + *dest = 0; + } + return; +} + +char * +strtoupper(buf) + char *buf; +{ + char *s; + for (s = buf; *s; s++) + *s = toupper(*s); + return buf; +} + +char * +strtolower(buf) + char *buf; +{ + char *s; + for (s = buf; *s; s++) + *s = tolower(*s); + return buf; +} + +/**********************************************************************/ + +/* + start with a $ + + field 1: + (n)earest + (t)arget + (s)elf (doesn't have fields 2 and 3) + (_) ego (has no other fields) + + field 2: + (a)ny + (t)eammate + (f)riendly + (h)ostile + + field 3: + (a)ny + (u)ser + (p)lanet (includes asteroids) + (s)tar + (n)ebula + (b)lack hole + (^) non-planet + (*) any stellar object + + field 4: (optional) NYI + (U)ppercase + (C)apitalize + (L)owercase + + field 5: + full (n)ame (Hammor, Thought) + (i)dentifier (e.g. R5, Ka, Can, Sco) + (#) number (0-9a-z for players, %d for planets) + (t)eam name (Romulan) + (s)hort team id (ROM) + (l)etter of team (R) + (a)rmies + (@) sector + (A)rable, 0=not arable, 1=arable but not AGRI, 2=AGRI + (M)etal, 0, 1, 2(repair), or 3(sy) + (D)ilithium, 0, 1 or 2(fuel) + + Any implementation of the paradise $ codes (subset or superset) + must implement and document the $_ code. -- Robert Forsman +*/ + +void +handle_dollar(locpntr, destpntr, data) + char **locpntr, **destpntr; + W_Event *data; +{ + char *buf = *destpntr; + struct id *target; + char ch = *((*locpntr)++); + W_Window w; + int x, y; + int flags; + int capitalize = 0; + + buf[0] = 0; + + if (ch == '_') { + strcpy(buf, "Paradise netrek $ codes are orthogonal and make sense."); + while (**destpntr) + (*destpntr)++; + return; + } if (ch == 's') { + target = getTargetID((W_Window) 0, me->p_x, me->p_y, TARG_PLAYER | TARG_SELF); + } else { + switch (tolower(ch)) { + case 'n': + w = 0; + x = me->p_x; + y = me->p_y; + break; + case 't': + w = data->Window; + x = data->x; + y = data->y; + break; + default: + printf("Invalid $ code field 1 : `%c'\n", ch); + return; + } + + ch = *((*locpntr)++); + switch (tolower(ch)) { + case 'a': + flags = 0; + break; + case 't': + flags = TARG_TEAM; + break; + case 'f': + flags = TARG_FRIENDLY; + break; + case 'h': + flags = TARG_ENEMY; + break; + default: + printf("Invalid $ code field 2 : `%c'\n", ch); + return; + } + + ch = *((*locpntr)++); + switch (tolower(ch)) { + case 'a': + flags |= TARG_PLAYER | TARG_ASTRAL; + break; + case 'u': + flags |= TARG_PLAYER; + break; + case 'p': + flags |= TARG_PLANET; + break; + case 's': + flags |= TARG_STAR; + break; + case 'n': + flags |= TARG_NEBULA; + break; + case 'b': + flags |= TARG_BLACKHOLE; + break; + case '^': + flags |= (TARG_ASTRAL & ~TARG_PLANET); + /* fall through */ + case '*': + flags |= TARG_PLANET; + break; + default: + printf("Invalid $ code field 3 : `%c'\n", ch); + return; + } + + target = getTargetID(w, x, y, flags); + } + + ch = tolower(*((*locpntr)++)); + if (ch == 'l') + capitalize = -1; + else if (ch == 'c') + capitalize = 1; + else if (ch == 'u') + capitalize = 2; + else + (*locpntr)--; /* oops, back up and try again */ + + ch = *((*locpntr)++); + + switch (ch) { + case 'n': + strcpy(buf, target->name); + break; + case 'i': +/* if (target->type == PLANETTYPE) {*/ + strcpy(buf, target->mapstring); +/* + } else { + buf[0] = target->mapstring[1]; + buf[1] = 0; + }*/ + break; + case '#': + if (target->type == PLANETTYPE) { + sprintf(buf, "%d", target->number); + } else { + buf[0] = target->mapstring[1]; + buf[1] = 0; + } + break; + case 't': + strcpy(buf, teaminfo[target->team].name); + break; + case 's': + strcpy(buf, teaminfo[target->team].shortname); + break; + case 'l': + buf[0] = teaminfo[target->team].letter; + buf[1] = 0; + break; + case 'a': + sprintf(buf, "%d", (target->type == PLANETTYPE) ? + planets[target->number].pl_armies : + players[target->number].p_armies); + break; + case '@': + if (!paradise) + break; + if (target->type == PLANETTYPE) { + x = planets[target->number].pl_x; + y = planets[target->number].pl_y; + } else { + x = players[target->number].p_x; + y = players[target->number].p_y; + } + sprintf(buf, "%d-%d", x / GRIDSIZE + 1, y / GRIDSIZE + 1); + break; + case 'A': /* Arable or AGRI */ + buf[0] = '0'; + if (target->type == PLANETTYPE) { + if (planets[target->number].pl_flags & PLARABLE) + buf[0] = '1'; + if (planets[target->number].pl_flags & PLAGRI) + buf[0] = '2'; + } + buf[1] = 0; + break; + case 'M': /* Metal, Repair, or SY */ + buf[0] = '0'; + if (target->type == PLANETTYPE) { + if (planets[target->number].pl_flags & PLMETAL) + buf[0] = '1'; + if (planets[target->number].pl_flags & PLREPAIR) + buf[0] = '2'; + if (planets[target->number].pl_flags & PLSHIPYARD) + buf[0] = '3'; + } + buf[1] = 0; + break; + case 'D': /* Dilythium or Fuel */ + buf[0] = '0'; + if (target->type == PLANETTYPE) { + if (planets[target->number].pl_flags & PLDILYTH) + buf[0] = '1'; + if (planets[target->number].pl_flags & PLFUEL) + buf[0] = '2'; + } + buf[1] = 0; + break; + default: + printf("Invalid $ code field 4 : `%c'\n", ch); + return; + } + + if (capitalize < 0) { + char *s; + for (s = buf; *s; s++) + *s = tolower(*s); + } else if (capitalize > 1) { + char *s; + for (s = buf; *s; s++) + *s = toupper(*s); + } else if (capitalize) { + char *s; + s = buf; + *s = toupper(*s); + for (s++; *s; s++) + *s = tolower(*s); + } + while (**destpntr) + (*destpntr)++; + return; +} +#endif /* MACROS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/macrowin.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,335 @@ +/* $Id: macrowin.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +/* + * macrowin.c from helpwin.c + * copyright 1993 Nick Trown + * copyright 1991 ERic mehlhaff + * Free to use, hack, etc. Just keep these credits here. + * Use of this code may be dangerous to your health and/or system. + * Its use is at your own risk. + * I assume no responsibility for damages, real, potential, or imagined, + * resulting from the use of it. + * Yeah.....what Eric said... + */ +/* Modified for Paradise, 4/94 -JR */ + +/*#include "config.h"*/ +#include <stdio.h> +#include <math.h> +#include <signal.h> +#include <sys/types.h> + +#include <time.h> +/*#include INC_SYS_TIME*/ +/*#include INC_STRINGS*/ + +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" + + +/* + Fills in macro window with the macros defined in the .xtrekrc. + */ + +#define NUMLINES 80 + +#define MAXMACRO 65 +/* maximum length in characters of key explanation */ + +#define MACROLEN 255 +/* length of construction string since we don't know how long a macro can be */ + + +int lineno = 0; +char maclines[10][MAXMACRO]; +int maclevel = 0; +int macrocnt = 0; /* a global from COW-lite, only needed here + for Paradise. */ + +int +formatline(line) + char *line; +{ + register int end; + char *temp; + int num = 0; + + if (!line) + return 0; + if (strlen(line) <= MAXMACRO) { + strncpy(maclines[num], line, sizeof(maclines[0])); + lineno++; + return 1; + } + temp = line; + while (1) { + end = MAXMACRO - 1; + if (end > strlen(temp)) { + lineno++; + strncpy(maclines[num++], temp, sizeof(maclines[0])); + return (num); + } else + for (; temp[end] != '%'; end--); + + lineno++; + strncpy(maclines[num++], temp, end); + + temp = temp + end; + } +} + + +void +filldist(fill) + int fill; +{ + register int i; + register int row; + register int c; + int num; + char key[3]; + + lineno = 0; + for (i = 1, row = 5; distmacro[i].macro != '\0'; i++) { + if (fill) { + if (distmacro[i].c < 128) + sprintf(key, " %c", distmacro[i].c); + else + sprintf(key, "^%c", distmacro[i].c - 128); + sprintf(maclines[0], "%-8s %s", + key, + distmacro[i].name); + W_WriteText(macroWin, 2, row++, W_Yellow, maclines[0], + strlen(maclines[0]), W_RegularFont); + } + lineno++; + num = formatline(distmacro[i].macro); + if (fill) { + for (c = 0; c < num; c++) { + W_WriteText(macroWin, 8, row++, textColor, maclines[c], + strlen(maclines[c]), W_RegularFont); + } + } + if (lineno > NUMLINES) + continue; + } +} + + + +void +fillmacro() +{ + register int row, i; + char macromessage[MACROLEN]; + struct macro *m; + + W_ClearWindow(macroWin); + sprintf(macromessage, "Packages active: %s%s", + (F_UseNewMacro ? ", NEWMACRO" : ""), + (F_gen_distress ? ", RCD" : "")); + /* (UseSmartMacro ? ", SMARTMACRO" : "")); */ + + W_WriteText(macroWin, 2, 1, textColor, + macromessage, strlen(macromessage), W_RegularFont); + + sprintf(macromessage, "Currently showing: %s", + (maclevel ? "Macros" : "RCDS")); + + W_WriteText(macroWin, 2, 2, textColor, + macromessage, strlen(macromessage), W_RegularFont); + + + if (maclevel == 0) { + W_WriteText(macroWin, 2, 4, W_Yellow, + "Key Distress Name", 21, W_RegularFont); + filldist(1); + return; + } + /* 4 column macro window. This may be changed depending on font size */ + for (row = 4, i = 0; i < 256; i++) { + for (m = macrotable[i]; m; m = m->next, row++) { + if (m->flags & MACRCD) + break; + if (i <= 128) + sprintf(macromessage, "%c ", i); + else + sprintf(macromessage, "^%c", i - 128); +#ifdef NEWMOUSE + if (macro[i].type == NEWMMOUSE) { + switch (macro[i].who) { + case MACRO_PLAYER: + strcat(macromessage, " PL MS "); + break; + case MACRO_TEAM: + strcat(macromessage, " TM MS "); + break; + default: + strcat(macromessage, " SELF "); + break; + } + } else { +#endif + switch (m->to) { + case 'T': + strcat(macromessage, " TEAM "); + break; + case 'A': + strcat(macromessage, " ALL "); + break; + case 'F': + strcat(macromessage, " FED "); + break; + case 'R': + strcat(macromessage, " ROM "); + break; + case 'K': + strcat(macromessage, " KLI "); + break; + case 'O': + strcat(macromessage, " ORI "); + break; +#ifdef MOO + case 'M': + strcat(macromessage, " MOO "); + break; +#endif +#ifdef TOOLS + case '!': + strcat(macromessage, " SHELL "); + break; +#endif +#ifdef NEWMACRO + case '\0': + strcat(macromessage, " SPEC "); + break; +#endif + case -1: + switch (m->specialto) { + case 'I': + case 'C': + strcat(macromessage, " SELF "); + break; + case 'U': + case 'P': + strcat(macromessage, " PL MS "); + break; + case 'T': + case 'Z': + strcat(macromessage, " TM MS "); + break; + case 'G': + strcat(macromessage, " NR FR "); + break; + case 'H': + strcat(macromessage, " NR EN "); + break; + } + break; + case -2: + strcat(macromessage, " QUERY "); + break; + default: + strcat(macromessage, " ---- "); + break; + } + +#ifdef NEWMOUSE + } +#endif + strcat(macromessage, m->string); + macromessage[MAXMACRO] = '\0'; + W_WriteText(macroWin, 2, row, textColor, + macromessage, strlen(macromessage), W_RegularFont); + } + } +} + +void +switchmacros() +{ + int num, i; + struct macro *m; + + if (!macroWin) + return; /* paranoia? */ + + maclevel = abs(maclevel - 1); + + if (maclevel == 0) { + lineno = 0; + filldist(0); + num = lineno + 5; + } else { + for (i = 0, macrocnt = 0; i < 256; i++) { + for (m = macrotable[i]; m; m = m->next) { + if (m->flags & MACRCD) + break; + macrocnt++; +#if 0 + len = strlen(m->string); + while (len > 0) { + totmacros++; + len -= 70; + } +#endif + } + } + num = macrocnt + 5; + } + W_ResizeText(macroWin, 80, num); +#if 0 + W_SetWindowExposeHandler(macroWin, fillmacro); + W_SetWindowButtonHandler(macroWin, switchmacros); +#endif + W_MapWindow(macroWin); +} + + + +void showMacroWin() +{ + int num, i; + struct macro *m; + + if (!macroWin) { + if (maclevel == 0) { + lineno = 0; + filldist(0); + num = lineno + 5; + } else { + for (i = 0, macrocnt = 0; i < 256; i++) { + for (m = macrotable[i]; m; m = m->next) { + if (m->flags & MACRCD) + break; + macrocnt++; +#if 0 + len = strlen(m->string); + while (len > 0) { + totmacros++; + len -= 70; + } +#endif + } + } + num = macrocnt + 5; + } + + macroWin = W_MakeTextWindow("macrow", WINSIDE + BORDER, BORDER, + 80, num, NULL, (char*)0, BORDER); + + W_ResizeText(macroWin, 80, num); +#if 0 + W_DefineTrekCursor(macroWin); + W_SetWindowExposeHandler(macroWin, fillmacro); + W_SetWindowButtonHandler(macroWin, switchmacros); +#endif + W_MapWindow(macroWin); + } else if (W_IsMapped(macroWin)) { + W_DestroyWindow(macroWin); + macroWin = 0; + } else + W_MapWindow(macroWin); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,865 @@ +/* $Id: main.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +/* + * main.c + */ +#include "copyright.h" + +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <signal.h> +#include <setjmp.h> +#include <pwd.h> +#ifdef hpux +#include <time.h> +#else +#include <sys/time.h> +#include <sys/wait.h> +#endif /* hpux */ +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "packets.h" +#include "proto.h" +#include "gameconf.h" +#ifdef SOUND +#include "Slib.h" +#endif +#include "sound.h" + +jmp_buf env; + +#ifdef AMIGA +/* needed for metafork... implemented by running a whole new copy + don't honestly know why I bothered ;-) */ +char **command_line; +int global_argc; +#endif + +#ifdef GATEWAY +#define DEFAULT_GATEWAY "atlgw" /* for Quar */ + +static char *get_gw P((void)); +static unsigned long mkaddr P((char *m)); +static void getUdpPort P((void)); +#endif + +extern int UdpLocalPort; +/* Prototypes */ +static void printUsage P((char *prog)); +static void show_credits (); + +int +main(argc, argv) + int argc; + char **argv; +{ + int intrupt(); + int team, s_type; + char *dpyname = NULL; + int usage = 0; + int err = 0; + char *name, *ptr, *cp; +#if !defined(NeXT) && !defined(RS6K) && !defined(SVR4) + char *rindex(); +#endif + struct passwd *pwent; + int passive = 0; +#ifdef METASERVER + int usemeta = 0; +#endif /* METASERVER */ +/* char *defaultsFile=NULL;*/ + + pseudo[0] = defpasswd[0] = '\0'; + +#ifdef AMIGA + command_line = argv; + global_argc=argc; +#endif + + name = *argv++; + argc--; + if ((ptr = rindex(name, '/')) != NULL) + name = ptr + 1; +#ifdef GATEWAY + netaddr = -1; /* special NULL address */ + serverName = get_gw(); /* default machine is gw */ +#endif + while (*argv) { + if (**argv != '-') { + serverName = *argv; /* don't abort argument processing */ + argv++; + argc--; + } else { + ++*argv; + + argc--; + ptr = *argv++; + while (*ptr) { + switch (*ptr) { + case 'C': /* character name */ + (void) strncpy(pseudo, *argv, sizeof(pseudo)); + argv++; + argc--; + break; + + case 'c': /* Credits */ + show_credits(); + exit (0); + break; + + case 'P': /* authorization password */ + (void) strncpy(defpasswd, *argv, sizeof(defpasswd)); + { + int i; + for (i = 0; (*argv)[i]; i++) + (*argv)[i] = 0; + } + argv++; + argc--; + break; + + case 'u': + usage++; + break; + case 's': + if (*argv) { + xtrekPort = atoi(*argv); + passive = 1; + argv++; + argc--; + } + break; + case 'p': + if (*argv) { + xtrekPort = atoi(*argv); + argv++; + argc--; + } + break; + case 'd': + dpyname = *argv; + argc--; + argv++; + break; +#ifdef METASERVER + case 'm': + usemeta = 1; + break; +#endif /* METASERVER */ + case 'h': + serverName = *argv; + if (!serverName) + err++; +#ifdef GATEWAY + gw_mach = *argv; +#endif + argc--; + argv++; + break; +#ifdef GATEWAY + case 'H': + netaddr = mkaddr(*argv); + argc--; + argv++; + break; +#endif + + case 't': + title = *argv; + argc--; + argv++; + break; + case 'r': + defaultsFile = *argv; + argv++; + argc--; + break; +#ifdef AUTHORIZE + case 'o': + RSA_Client = -1; + break; + case 'R': + RSA_Client = -2; + break; +#else + case 'o': + case 'R': + printf("This client does not have binary authorization.\n"); + break; +#endif + case 'e': +#ifdef AUTHORIZE + checkExpire(1); +#else + printf("This client does not RSA verify and will not expire.\n"); +#endif + exit(0); + break; + case 'f': /* list ftp sites */ + fprintf(stderr, "\n\ +The newest version of the Paradise client can be found at:\n\ + ftp.pnetrek.org in /pub/paradise/bin/\n\ +or ftp.cs.umn.edu in /users/glamm/paradise/bin/\n\ +\n\ +Quick ftp instructions:\n\ +This assumes you are bob@school.edu and are using a Sun workstation\n\ +('sparc' architecture). Modify with your mailing address and architecture.\n\ +Type:\n\ + ftp ftp.cs.umn.edu\n\ + (at name prompt) anonymous\n\ + (at password prompt) bob@school.edu\n\ + (at ftp> prompt) cd users/glamm/paradise/bin\n\ + (at ftp> prompt) binary\n\ + (at ftp> prompt) dir\n\ + (lots of files printed - pick out the latest release for your architecture.\n\ + all the client binaries begin with 'netrek'.)\n\ + (at ftp> prompt) get netrek.Sparc-SunOS-static\n\ + (note: static and dynamic are functionally the same.\n\ + (at ftp> prompt) bye\n\ +\n\ +That's it!\n"); + exit(0); + case 'G': + if (*argv) { + ghoststart++; + ghost_pno = atoi(*argv); + printf("Emergency restart being attempted...\n"); + argv++; + argc--; + } + break; + case '2': /* force paradise */ + paradise = 1; + break; +#ifdef RECORDER + case 'F': /* File playback */ + if (*argv) { + playFile = strdup(*argv); + playback = 1; + argv++; + argc--; + } + break; +#endif + case 'U': + if(*argv == NULL || (UdpLocalPort = atoi(*argv)) <= 0) { + fprintf(stderr, "Error: -U requires a port number\n"); + usage++; + break; + } + argc--; + argv++; + break; + default: + fprintf(stderr, "%s: unknown option '%c'\n", name, *ptr); + err++; + break; + } + ptr++; + } + } + } +#ifdef GATEWAY + if (netaddr == -1) { + fprintf(stderr, + "netrek: no remote address set (-H). Restricted server will not work.\n"); + } +#endif + + + + inittrigtables(); + + initStars(); /* moved from redraw.c at KAO\'s suggestion */ + + if (usage || err) { + printUsage(name); +#ifdef AUTHORIZE + checkExpire(1); +#endif + exit(0); + /* exit(err); Exits from checkExpire */ + } + defaultsFile = initDefaults(defaultsFile); + +#ifdef AUTHORIZE + if (RSA_Client != -1) + checkExpire(0); +#endif + + /* compatability */ + if (argc > 0) + serverName = argv[0]; + + srandom(getpid() + time((long *) 0)); + +#ifdef RECORDER + if(playback || booleanDefault("playback",0)) { + defNickName = "playback"; + usemeta=0; + serverName = "playback"; + } else +#endif + { + if (serverName) { + char temp[80], *s; + sprintf(temp, "server.%s", serverName); + if ((s = getdefault(temp))) { + s=strdup(s); + printf("Using nickname \"%s\" for server %s\n", serverName, s); + defNickName = serverName; + serverName = s; + defFlavor = getdefault("flavor"); + if(defFlavor) + defFlavor=strdup(defFlavor); + } + } + if (!serverName) { + if(serverName = getdefault("server")) + serverName = strdup(serverName); + } + if (!serverName && !passive) { + serverName = DEFAULT_SERVER; +#ifdef METASERVER + usemeta = 1; /* no server specified, show the menu */ +#endif + } + if (passive) + serverName = "passive"; /* newwin gets a wrong title otherwise */ + + if (xtrekPort < 0) + xtrekPort = intDefault("port", -1); + if (xtrekPort < 0) + xtrekPort = DEFAULT_PORT; +#if 0 +#ifdef AUTHORIZE + if (RSA_Client >= 0) + RSA_Client = booleanDefault("useRSA", RSA_Client); + else + RSA_Client = (RSA_Client == -2); +#endif +#endif /* 0 */ + + } /* playback */ + build_default_configuration(); + +#ifdef METASERVER + metaserverAddress = stringDefault("metaserver", + "metaserver.ecst.csuchico.edu"); + if (usemeta) + parsemeta(); +#endif /* METASERVER */ + + W_Initialize(dpyname); +#ifdef SOUND + S_Initialize(); +#endif + + +#ifdef METASERVER + metaFork = booleanDefault("metaFork", metaFork); + /* do the metawindow thang */ + if (usemeta) { + metawindow(); + metainput(); + if (metaFork) + W_Initialize(dpyname); + newwin(dpyname, name); + } else +#endif /* METASERVER */ + + /* this creates the necessary x windows for the game */ + newwin(dpyname, name); + +#ifdef TIMELORD + start_timelord(); +#endif + + /* open memory...? */ + openmem(); +#ifdef RECORDER + if (!startPlayback()) +#endif + { + if (!passive) { + callServer(xtrekPort, serverName); + } else { + connectToServer(xtrekPort); + } + } +#ifdef FEATURE + sendFeature("FEATURE_PACKETS", 'S', 1, 0, 0); +#endif + + timeStart = time(NULL); + findslot(); + + /* sets all the settings from defaults file (.xtrekrc probably) */ + resetDefaults(); + +#ifdef UNIX_SOUND + init_sound(); + play_sound(SND_PARADISE); +#endif + + mapAll(); +/* signal(SIGINT, SIG_IGN);*/ + signal(SIGCHLD, (void (*) ()) reaper); + + /* Get login name */ + if ((pwent = getpwuid(getuid())) != NULL) + (void) strncpy(login, pwent->pw_name, sizeof(login)); + else + (void) strncpy(login, "Bozo", sizeof(login)); + login[sizeof(login) - 1] = '\0'; + + if (pseudo[0] == '\0') { + if ((cp = getdefault("name")) != 0) + (void) strncpy(pseudo, cp, sizeof(pseudo)); + else + (void) strncpy(pseudo, login, sizeof(pseudo)); + } + pseudo[sizeof(pseudo) - 1] = '\0'; + + if (defpasswd[0] == '\0') { + char buf[100], buf2[100]; /* added password by character name -JR */ + sprintf(buf,"password.%s",pseudo); + if (serverName) /* password by server name -TH */ + sprintf(buf2, "password.%s", serverName); + if((cp = getdefault(buf)) || (cp = getdefault(buf2)) || + (cp = getdefault("password"))) + (void) strncpy(defpasswd, cp, sizeof(defpasswd)); + } + defpasswd[sizeof(defpasswd) - 1] = '\0'; + + /* + sendLoginReq("Gray Lensman", "hh", "sfd", 0); loginAccept = -1; while + (loginAccept == -1) { socketPause(1,0); readFromServer(); } + */ + getname(pseudo, defpasswd); + loggedIn = 1; +#ifdef TIMER + timeBank[T_SERVER] = timeStart; + timeBank[T_DAY] = 0; +#endif /* TIMER */ + + +#ifdef AUTOKEY + /* autokey.c */ + autoKeyDefaults(); +#endif /* AUTOKEY */ + + /* + Set p_hostile to hostile, so if keeppeace is on, the guy starts off + hating everyone (like a good fighter should) + */ + me->p_hostile = (1 << number_of_teams) - 1; + + redrawTstats(); + + me->p_planets = 0; + me->p_genoplanets = 0; + me->p_armsbomb = 0; + me->p_genoarmsbomb = 0; + /* Set up a reasonable default */ + me->p_whydead = KQUIT; + me->p_teami = -1; + s_type = defaultShip(CRUISER); /* from rlb7h 11/15/91 TC */ + + if (booleanDefault("netStats", 1)) + startPing(); /* tell the server that we support pings */ + +#ifdef AUTOKEY + if (autoKey) { + /* XX: changes entire state of display */ + W_AutoRepeatOff(); + } +#endif + /* + hack to make galaxy class ships work. This could be more elegant, but + the configuration code would have to be modified quite a bit, since + the client doesn't know if it's on a paradise server until after it + connects, and it needs the configuration info before it connects. + */ + init_galaxy_class(); + + initkeymap(-1); /* needs to have ship types initialized -JR */ + + setjmp(env); /* Reentry point of game */ + + if (ghoststart) { + int i; + + ghoststart = 0; + + for (i = -1; i < 5; i++) + if (teaminfo[i].letter == me->p_mapchars[0]) + break; + + me->p_teami = i; + + if (me->p_damage > me->p_ship->s_maxdamage) { + me->p_status = POUTFIT; + } else + me->p_status = PALIVE; + } else + me->p_status = POUTFIT; + + while (1) { + switch (me->p_status) { + case POUTFIT: + case PTQUEUE: + /* give the player the motd and find out which team he wants */ +#if 1 + new_entrywindow(&team, &s_type); +#else + entrywindow(&team, &s_type); +#endif + allowPlayerlist = 1; + if (W_IsMapped(playerw)) + playerlist(); + +#ifdef RECORDER + if (!playback) +#endif + if (team == -1) { + W_DestroyWindow(w); +#ifdef AUTOKEY + if (autoKey) + W_AutoRepeatOn(); +#endif + sendByeReq(); + sleep(1); + printf("OK, bye!\n"); + EXIT(0); + } + sendVersion(); + myship = getship(myship->s_type); + + currentship = myship->s_type; + + /* + sendOptionsPacket(); /* this would totally blast any flags you + had on the server + */ + + redrawall = 1; + enter(); + calibrate_stats(); + W_ClearWindow(w); + /* + for (i = 0; i < NSIG; i++) { signal(i, SIG_IGN); } + */ + + me->p_status = PALIVE; /* Put player in game */ + +#ifdef UNIX_SOUND + kill_sound (); +#endif + +#ifdef HOCKEY + hockeyInit(); +#endif /*HOCKEY*/ + +#ifdef TIMER + timeBank[T_SHIP] = time(NULL); +#endif /* TIMER */ + + if (showStats) /* Default showstats are on. */ + W_MapWindow(statwin); + +#ifdef GATEWAY + /* pick a nice set of UDP ports */ + getUdpPort(); +#endif + +#if ATM + if (tryUdp && commMode != COMM_UDP) { + sendUdpReq(COMM_UDP); + } +#endif /* ATM */ +#ifdef SHORT_PACKETS + if (tryShort) { + sendShortReq(SPK_VON); + tryShort = 0; /* only try it once */ + } +#endif /* SHORT_PACKETS */ + /* Send request for a full update */ + if (askforUpdate) { + if(recv_short) + sendShortReq(SPK_SALL); + else + sendUdpReq(COMM_UPDATE); + } + sendUpdatePacket(1000000 / updateSpeed); + + W_Deiconify(baseWin); + + break; + case PALIVE: + case PEXPLODE: + case PDEAD: + case POBSERVE: + +#ifdef TIMELORD + /* reading the MOTD doesn't count against your playing time */ + update_timelord_notcount(); +#endif + + /* Get input until the player quits or dies */ + input(); + W_ClearWindow(mapw); +#ifdef TIMELORD + /* get any fractional minutes we missed */ + update_timelord(1); +#endif + break; + default: + printf("client has p_status=%d. how strange\n", me->p_status); + me->p_status = POUTFIT; + } + } + + /* NOTREACHED */ +} + +static void +printUsage(prog) + char *prog; +{ + fprintf(stderr, "Usage:\n %s [ options ] [ ntserv-host ]\n\ +Where options are\n\ + [-h] host server host name\n\ + [-p] port server port number\n\ + [-r] xtrekrc defaults file to replace ~/.xtrekrc\n\ + [-t] title window manager title\n\ + [-d] display set Xwindows display\n\ + [-C] name netrek pseudonym\n\ + [-P] passwd passwd to use to attempt autologin\n\ + [-R] use RSA authorization (default)\n\ + [-o] use old (non-RSA) authorization\n\ + [-s] port wait for connection from ntserv on a port (debugging)\n\ +%s\ +%s\ + [-U] port specify base local UDP port number to use\n\ + [-e] check the expire time on the client\n\ + [-f] how to get the newest client\n\ + [-u] print usage\n\ + [-c] Paradise credits\n\ + For emergency restart:\n\ + [-2] force paradise - use if you were on a paradise server\n\ + [-G] playernum specify player number to use\n\ + [-s] port specify socket number to use\n\ +Paradise Client %s\n\ +For more information on how to play Paradise, use Netscape or Internet\n\ +Explorer and connect to:\n\ + http://www.pnetrek.org/ OR\n\ + http://www.cs.umn.edu/users/glamm/paradise/\n\n", prog, +#ifdef METASERVER + " [-m] check metaserver for active servers\n", +#else + "", +#endif /* METASERVER */ +#ifdef RECORDER + " [-F] file Replay from file instead of connecting\n", +#else + "", +#endif + CLIENTVERS); +} + +void +reaper() +{ +#if defined(hpux) || defined(SVR4) || defined(AMIGA) + wait((int *) 0); +#else + /* well, hell, just use NULL, it works for everything else anyway */ +/* while (wait3((union wait *) 0, WNOHANG, NULL) > 0);*/ + while(wait3(NULL, WNOHANG, NULL) > 0); +#endif /* hpux */ +} + +#ifdef GATEWAY +static struct udpmap_t { + int uid; + int serv_port; + int port; + int local_port; +} udpmap[] = { + /* 5000, 5001, 5000 *//* generic */ + { + 1290, 5010, 5011, 5010 + }, /* fadden */ + { + 757, 5020, 5021, 5020 + }, /* user2 */ +}; +#define MAPSIZE (sizeof(udpmap) / sizeof(struct udpmap_t)) + +static void +getUdpPort() +{ + int i; + uid_t uid; + char *gw_m, *gw_p, *gw_lp, *gw_sp, *err, *getenv(); + + /* should always be set prior, but in case not .. */ + if (!gw_mach) { + gw_m = getenv("GW_MACH"); + if (gw_m) + gw_mach = gw_m; + else + gw_mach = DEFAULT_GATEWAY; + } + uid = getuid(); + + for (i = 0; i < MAPSIZE; i++) { + if (uid == udpmap[i].uid) { + gw_serv_port = udpmap[i].serv_port; + gw_port = udpmap[i].port; + gw_local_port = udpmap[i].local_port; + return; + } + } + + gw_p = getenv("GW_PORT"); + gw_sp = getenv("GW_SPORT"); + gw_lp = getenv("GW_LPORT"); + + if (gw_p) { + gw_port = strtol(gw_p, &err, 10); + if (err == gw_p) { + fprintf(stderr, "netrek: malformed integer for GW_PORT: %s\n", + gw_p); + /* let something else complain about port 0 */ + } + } else + gw_port = 5001; + if (gw_sp) { + gw_serv_port = strtol(gw_sp, &err, 10); + if (err == gw_sp) { + fprintf(stderr, "netrek: malformed integer for GW_SPORT: %s\n", + gw_sp); + /* let something else complain about port 0 */ + } + } else + gw_serv_port = 5000; + + if (gw_lp) { + gw_local_port = strtol(gw_lp, &err, 10); + if (err == gw_lp) { + fprintf(stderr, "netrek: malformed integer for GW_LPORT: %s\n", + gw_lp); + /* let something else complain about port 0 */ + } + } else + gw_local_port = 5000; + + /* + printf("gw_mach: \'%s\'\n", gw_mach); printf("gw_local_port: %d\n", + gw_local_port); printf("gw_serv_port: %d\n", gw_serv_port); + printf("gw_port: %d\n", gw_port); + */ +} + +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> + +/* + * In the event of problems assiocated with the above include files the + * following routine can be alternately used to convert a string + * ("xxx.xxx.xxx.xxx") to an internet address number. + * + * (author: Andy McFadden) + */ + +#ifdef notneeded +unsigned long +dotAddrToNetAddr(str) + char *str; +{ + char *t; + unsigned long answer = 0; + t = str; + for (i = 0; i < 4; i++) { + answer = (answer << 8) | atoi(t); + while (*t && *t != '.') + t++; + if (*t) + t++; + } + return answer; +} +#endif + +/* + * More network "correct" routine + */ + +static unsigned long +mkaddr(m) + char *m; +{ + struct in_addr ad; + struct hostent *hp; + + hp = gethostbyname(m); + if (!hp) { + ad.s_addr = inet_addr(m); + if (ad.s_addr == -1) { + fprintf(stderr, "netrek: unknown host \'%s\'\n", m); + exit(1); + } + } else + bcopy(hp->h_addr, (char *) &ad, hp->h_length); + + return ad.s_addr; +} + +static char * +get_gw() +{ + char *gw_m; + + gw_m = getenv("GW_MACH"); + if (gw_m) + gw_mach = gw_m; + else + gw_mach = DEFAULT_GATEWAY; + + return gw_mach; +} + +#endif + +void +show_credits() +{ + printf ("Paradise Netrek\n\ +\n\ +Copyright (c) 1986 Chris Guthrie\n\ +Copyright (c) 1989 Kevin P. Smith\n\ +Copyright (c) 1993 Larry Denys, Kurt Olsen, Brandon Gillespie, and\n\ + Robert Forsman\n\ +Copyright (c) Eric Mehlaff, Sujal Patel, Robert Glamm, \n\ + Lars Bernhardsson, Kurt Siegl, Nick Trown\n\ +\n\ +Paradise Developers\n\ + Larry Deny Robert Forsman\n\ + Brandon Gillespie Kurt Olsen\n\ +\n\ +Paradise Contributors (In alphabetical order):\n\ + Terence Chang Mike McGrath\n\ + Bill Dyess Matthew Mead\n\ + Jerry Frain Gary Parnes\n\ + Robert Glamm Sujal Patel\n\ + T. Hadley Joe Rumsey\n\ + Heath A. Kehoe Rado Smiljanic\n\ + Andy McFadden Joe Young\n\ +"); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/motdwin.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,93 @@ +/* $Id: motdwin.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +/*** Pop-up motd window code. [BDyess] 11/21/93 ***/ + +#include <stdio.h> +#include <math.h> +#include <signal.h> +#include <sys/types.h> +#ifdef hpux +#include <time.h> +#else /* hpux */ +#include <sys/time.h> +#endif /* hpux */ +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "proto.h" +#ifdef SVR4 +#include <string.h> +#else +#include <strings.h> +#endif + +void +motdWinEvent(key) + int key; +/* handles keystrokes in the motd window */ +{ + static valuesOn = 0; + + switch (key) { + case 'f': /* scroll forward */ + if (currpage == NULL) { + currpage = motddata; + if (currpage == NULL) + break; + } + if (currpage->next == NULL) + break; + if (currpage->next) + currpage->next->prev = currpage; + currpage = currpage->next; + showMotd(motdWin); + break; + case 'b': /* Scroll motd backward */ + if (currpage == NULL || currpage->prev == NULL) + break; + currpage = currpage->prev; + showMotd(motdWin); + break; + case ' ': /* unmap window */ + showMotdWin(); + break; + case '\t': /* tab: swap between sysdef and motd */ + W_ClearWindow(motdWin); + if (!valuesOn) { + showValues(motdWin); + valuesOn = 1; + } else { + showMotd(motdWin); + valuesOn = 0; + } + break; + case 'r': /* refresh */ + if (valuesOn) + showValues(motdWin); + else + showMotd(motdWin); + break; + } +} + +void +showMotdWin() +/* handles map/unmap requests */ +{ + if (!motdWin) { + motdWin = W_MakeWindow( + "Motd" + ,-BORDER, -BORDER, WINSIDE, WINSIDE, NULL, + (char *) 0, BORDER, foreColor); + W_MapWindow(motdWin); + currpage = motddata; + showMotd(motdWin); + } else if (W_IsMapped(motdWin)) { + W_UnmapWindow(motdWin); + } else { + W_MapWindow(motdWin); + currpage = motddata; + showMotd(motdWin); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/newwin.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,1573 @@ +/* $Id: newwin.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +/* + * newwin.c + */ +#include "copyright.h" + +#include <stdio.h> +#ifdef __STDC__ +#include <stdlib.h> +#endif +#include <math.h> +#include <signal.h> +#include <sys/types.h> +#include <string.h> +#ifdef hpux +#include <time.h> +#else /* hpux */ +#include <sys/time.h> +#endif /* hpux */ +#ifdef RS6K +#include <sys/select.h> +#endif +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "gameconf.h" + + + +#include "oldbitmaps.h" +#include "bitmaps_pr.h" +#include "bitmaps3.h" +#include "hullbitmaps.h" +#include "planetbitmaps.h" +#include "rabbitbitmaps.h" +#include "starbitmaps.h" + +#ifdef BEEPLITE +#include "emph_planet_seq.h" +#include "emph_player_seq.h" +#include "emph_player_seql.h" +#endif + +#include "packets.h" +#include "proto.h" + +#define NRHEADERS 4 +W_Icon headerA, headerB, headerchanges[NRHEADERS]; +W_Icon safepic; +/* elapsed time in outfit window [BDyess] */ +int elapsed; + +int newMotdStuff = 0; /* set to 1 when new motd packets arrive */ +static struct piclist *motdPics = NULL; +/*static struct page *currpage = NULL; +static struct page *motddata = NULL;*/ + +#define LINESPERPAGE 38 + +#define BOXSIDE (WINSIDE / 5) +#define TILESIDE 16 +#define MESSAGESIZE 20 +#define STATSIZE (MESSAGESIZE * 2 + BORDER) +#define YOFF 0 + +#define stipple_width 16 +#define stipple_height 16 +static unsigned char stipple_bits[] = { + 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, + 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, + 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, +0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80}; + +/* ATM: extra stuff for those who don't like my visible tractors */ +#define tract_width 5 +#define tract_height 5 +static char tract_bits[] = { +0x1f, 0x04, 0x04, 0x04, 0x04}; +#define press_width 5 +#define press_height 5 +static char press_bits[] = { +0x0f, 0x11, 0x0f, 0x01, 0x01}; + +/* Prototypes */ +static void savebitmaps P((void)); +static int teamRequest P((int team, int ship)); +static int numShips P((int owner)); +static int checkBold P((char *line)); +void showMotd P((W_Window win)); +static void showPics P((W_Window win)); +void showValues P((W_Window win)); +static void getResources P((char *prog)); +static void getTiles P((void)); +static void redrawTeam P((W_Window win, int teamNo, int *lastnum)); +static void redrawQuit P((void)); +static void showTimeLeft P((int time, int max)); + +/* from dashboard.c: */ +void light_erase P((void)); + +extern int helpmessages; + +void +newwin(hostmon, progname) + char *hostmon, *progname; +{ + int i; + + /* W_Initialize(hostmon); */ + + baseWin = W_MakeWindow("netrek", 0, YOFF, WINSIDE * 2 + 1 * BORDER, + WINSIDE + 2 * BORDER + 2 * MESSAGESIZE, NULL, "bomb here", BORDER, gColor); + iconWin = W_MakeWindow("netrek_icon", 0, 0, icon_width, icon_height, NULL, + (char *) 0, BORDER, gColor); + W_SetIconWindow(baseWin, iconWin); + w = W_MakeWindow("local", -BORDER, -BORDER, WINSIDE, WINSIDE, baseWin, + (char *) 0, BORDER, foreColor); + mapw = W_MakeWindow("map", WINSIDE, -BORDER, WINSIDE, WINSIDE, baseWin, + (char *) 0, BORDER, foreColor); + tstatw = W_MakeWindow("tstat", -BORDER, WINSIDE, WINSIDE, STATSIZE, baseWin, + "xterm", BORDER, foreColor); + warnw = W_MakeWindow("warn", WINSIDE, WINSIDE, WINSIDE, MESSAGESIZE, + baseWin, "xterm", BORDER, foreColor); + messagew = W_MakeWindow("message", WINSIDE, WINSIDE + BORDER + MESSAGESIZE, + WINSIDE, MESSAGESIZE, baseWin, "xterm", BORDER, foreColor); + planetw = W_MakeTextWindow("planet", 10, 10, 75, (nplanets + 13) / 2, w, (char *) 0, 2); + planetw2 = W_MakeTextWindow("planet2", 10, 10, 75, (nplanets + 13) / 2, mapw, (char *) 0, 2); + rankw = W_MakeTextWindow("rank", 50, 100, 65, nranks2 + 8, w, (char *) 0, 2); + playerw = W_MakeTextWindow("player", 0, YOFF + WINSIDE + 2 * BORDER + 2 * MESSAGESIZE, + 83, (nplayers + 14) / 2, NULL, (char *) 0, 2); + helpWin = W_MakeTextWindow("help", 0, YOFF + WINSIDE + 2 * BORDER + 2 * MESSAGESIZE, + 160, helpmessages / 4 + 1, NULL, (char *) 0, BORDER); +#ifdef METASERVER + /* + metaWin = W_MakeMenu ("MetaServer List", WINSIDE+10, -BORDER+10, 69, + num_servers + 2, NULL, 2); + */ +#endif /* METASERVER */ +#if 0 + W_SetWindowKeyDownHandler(metaWin, metaaction); + W_SetWindowButtonHandler(metaWin, metaaction); +#endif /* 0 */ + + initMessageWindows(); + + pStats = W_MakeWindow("Network Statistics", 500, 4, pStatsWidth(), pStatsHeight(), + NULL, (char *) 0, 1, foreColor); + udpWin = W_MakeMenu("UDP", WINSIDE + 10, -BORDER + 10, 40, UDP_NUMOPTS, + NULL, 2); + +#ifdef SHORT_PACKETS + spWin = W_MakeMenu("network", WINSIDE + 10, -BORDER + 10, 40, SPK_NUMFIELDS, + NULL, 2); +#endif + +#ifdef TOOLS + toolsWin = W_MakeScrollingWindow("tools", WINSIDE + BORDER, BORDER, + 80, TOOLSWINLEN, NULL, "xterm", BORDER); +#endif + + motdWin = W_MakeWindow("Motd" + ,-BORDER, -BORDER, WINSIDE, WINSIDE, NULL, + (char *) 0, BORDER, foreColor); + + for (i = 0; i < 4; i++) { + teamWin[i] = W_MakeWindow(teaminfo[i].shortname, i * BOXSIDE, 0, + BOXSIDE, BOXSIDE, mapw, (char *) 0, 1, foreColor); + } + qwin = W_MakeWindow("quit", 4 * BOXSIDE, 0, BOXSIDE, BOXSIDE, mapw, + "pirate", 1, foreColor); + +/* statwin = W_MakeWindow("stats", 422, 13, 160, 95, NULL, (char*)0, + 5, foreColor);*/ + statwin = W_MakeWindow("stats", 422, 13, 160, 80, NULL, + (char *) 0, 5, foreColor); + +#define WARHEIGHT 2 +#define WARWIDTH 20 +#define WARBORDER 2 + + war = W_MakeMenu("war", WINSIDE + 10, -BORDER + 10, WARWIDTH, 6, baseWin, + WARBORDER); + + + getResources(progname); + savebitmaps(); +} + +void +mapAll() +{ + initinput(); + W_MapWindow(mapw); + W_MapWindow(tstatw); + W_MapWindow(warnw); + W_MapWindow(messagew); + W_MapWindow(w); + W_MapWindow(baseWin); + + /* + since we aren't mapping windows that have root as parent in + x11window.c (since that messes up the TransientFor feature) we have to + map them here. (If already mapped, W_MapWindow returns) + */ + + if (checkMapped("planet")) + W_MapWindow(planetw); + if (checkMapped("planet2")) + W_MapWindow(planetw2); + if (checkMapped("rank")) + W_MapWindow(rankw); + if (checkMapped("help")) + W_MapWindow(helpWin); + if (checkMapped("Motd")) + W_MapWindow(motdWin); + if (checkMapped("review_all")) + W_MapWindow(messWin[WALL].window); + if (checkMapped("review_team")) + W_MapWindow(messWin[WTEAM].window); + if (checkMapped("review_your")) + W_MapWindow(messWin[WINDIV].window); + if (checkMapped("review_kill")) + W_MapWindow(messWin[WKILL].window); + if (checkMapped("review_phaser")) + W_MapWindow(messWin[WPHASER].window); + if (booleanDefault("player.mapped", 1)) + W_MapWindow(playerw); + if (booleanDefault("review.mapped", 1)) + W_MapWindow(messWin[WREVIEW].window); + if (checkMapped("UDP")) + udpwindow(); + +} + +static void +savebitmaps() +{ + register int i; + int tw, th, mw, mh; + + /* slurp_ship_bitmaps(); */ + + clockpic = W_StoreBitmap(clock_width, clock_height, clock_bits, + qwin); + safepic = W_StoreBitmap(safe_width, safe_height, safe_bits, + qwin); + +#ifdef BEEPLITE + for (i = 0; i < emph_player_seq_frames; i++) { + emph_player_seq[emph_player_seq_frames - (i + 1)] = + W_StoreBitmap(emph_player_seq_width, emph_player_seq_height, + emph_player_seq_bits[i], mapw); + } + + for (i = 0; i < emph_player_seql_frames; i++) { + emph_player_seql[emph_player_seql_frames - (i + 1)] = + W_StoreBitmap(emph_player_seql_width, emph_player_seql_height, + emph_player_seql_bits[i], w); + } + + for (i = 0; i < emph_planet_seq_frames; i++) { + emph_planet_seq[emph_planet_seq_frames - (i + 1)] = + W_StoreBitmap(emph_planet_seq_width, emph_planet_seq_height, + emph_planet_seq_bits[i], mapw); + } +#endif + + load_default_teamlogos(); + + headerA = W_StoreBitmap(headerA_width, headerA_height, + headerA_bits, motdWin); + headerB = W_StoreBitmap(headerB_width, headerB_height, + headerB_bits, motdWin); + headerchanges[0] = W_StoreBitmap(header1_width, header1_height, + header1_bits, motdWin); + headerchanges[1] = W_StoreBitmap(header2_width, header2_height, + header2_bits, motdWin); + headerchanges[2] = W_StoreBitmap(header3_width, header3_height, + header3_bits, motdWin); + headerchanges[3] = W_StoreBitmap(header4_width, header4_height, + header4_bits, motdWin); + for (i = 0; i < HULL_FRAMES; i++) + hull[i] = W_StoreBitmap(hull_width, hull_height, hull_bits[i], w); + + for (i = 0; i < 5; i++) { + cloud[i] = W_StoreBitmap(cloud_width, cloud_height, cloud_bits[4 - i], w); + plasmacloud[i] = W_StoreBitmap(plasmacloud_width, + plasmacloud_height, plasmacloud_bits[4 - i], w); + } + etorp = W_StoreBitmap(etorp_width, etorp_height, etorp_bits, w); + mtorp = W_StoreBitmap(mtorp_width, mtorp_height, mtorp_bits, w); + for (i = 0; i < NDRONEVIEWS; i++) { + drone_bm[i] = W_StoreBitmap(drone_width, drone_height, drone_bits[i], w); + } + eplasmatorp = + W_StoreBitmap(eplasmatorp_width, eplasmatorp_height, eplasmatorp_bits, w); + mplasmatorp = + W_StoreBitmap(mplasmatorp_width, mplasmatorp_height, mplasmatorp_bits, w); + for (i = 0; i < VIEWS; i++) { + fighter[i] = + W_StoreBitmap(fighter_width, fighter_height, fighter_bits[i], w); + }; + warpbeacon = W_StoreBitmap(warpbeacon_width, warpbeacon_height, warpbeacon_bits, w); + wbflash = W_StoreBitmap(warpbeacon_width, warpbeacon_height, warpflash_bits, w); + + tw = planet_width; + th = planet_height; + mw = mplanet_width; + mh = mplanet_height; + + /* tactical screen planet bitmaps for team */ + + bplanets[0] = W_StoreBitmap(tw, th, indplanet_bits, w); + bplanets[1] = W_StoreBitmap(tw, th, fedplanet_bits, w); + bplanets[2] = W_StoreBitmap(tw, th, romplanet_bits, w); + bplanets[3] = W_StoreBitmap(tw, th, kliplanet_bits, w); + bplanets[4] = W_StoreBitmap(tw, th, oriplanet_bits, w); + bplanets[5] = W_StoreBitmap(tw, th, planet_bits, w); + + /* galactic screen planet bitmaps for team */ + + mbplanets[0] = W_StoreBitmap(mw, mh, indmplanet_bits, mapw); + mbplanets[1] = W_StoreBitmap(mw, mh, fedmplanet_bits, mapw); + mbplanets[2] = W_StoreBitmap(mw, mh, rommplanet_bits, mapw); + mbplanets[3] = W_StoreBitmap(mw, mh, klimplanet_bits, mapw); + mbplanets[4] = W_StoreBitmap(mw, mh, orimplanet_bits, mapw); + mbplanets[5] = W_StoreBitmap(mw, mh, mplanet_bits, mapw); + + + + /* tactical screen planet bitmaps for facilities */ + + bplanets2[0] = bplanets[0]; + bplanets2[1] = W_StoreBitmap(tw, th, planet001_bits, w); + bplanets2[2] = W_StoreBitmap(tw, th, planet010_bits, w); + bplanets2[3] = W_StoreBitmap(tw, th, planet011_bits, w); + bplanets2[4] = W_StoreBitmap(tw, th, planet100_bits, w); + bplanets2[5] = W_StoreBitmap(tw, th, planet101_bits, w); + bplanets2[6] = W_StoreBitmap(tw, th, planet110_bits, w); + bplanets2[7] = W_StoreBitmap(tw, th, planet111_bits, w); + bplanets2[8] = W_StoreBitmap(tw, th, planet1010_bits, w); + bplanets2[9] = W_StoreBitmap(tw, th, planet1011_bits, w); + bplanets2[10] = bplanets2[8]; + bplanets2[11] = bplanets2[9]; + bplanets2[12] = W_StoreBitmap(tw, th, planet1110_bits, w); + bplanets2[13] = W_StoreBitmap(tw, th, planet1111_bits, w); + bplanets2[14] = bplanets2[12]; + bplanets2[15] = bplanets2[13]; + + /* galactic screen planet bitmaps for facilities */ + + mbplanets2[0] = mbplanets[0]; + mbplanets2[1] = W_StoreBitmap(mw, mh, mplanet001_bits, mapw); + mbplanets2[2] = W_StoreBitmap(mw, mh, mplanet010_bits, mapw); + mbplanets2[3] = W_StoreBitmap(mw, mh, mplanet011_bits, mapw); + mbplanets2[4] = W_StoreBitmap(mw, mh, mplanet100_bits, mapw); + mbplanets2[5] = W_StoreBitmap(mw, mh, mplanet101_bits, mapw); + mbplanets2[6] = W_StoreBitmap(mw, mh, mplanet110_bits, mapw); + mbplanets2[7] = W_StoreBitmap(mw, mh, mplanet111_bits, mapw); + mbplanets2[8] = W_StoreBitmap(mw, mh, mplanet1010_bits, mapw); + mbplanets2[9] = W_StoreBitmap(mw, mh, mplanet1011_bits, mapw); + mbplanets2[10] = mbplanets2[8]; + mbplanets2[11] = mbplanets2[9]; + mbplanets2[12] = W_StoreBitmap(mw, mh, mplanet1110_bits, mapw); + mbplanets2[13] = W_StoreBitmap(mw, mh, mplanet1111_bits, mapw); + mbplanets2[14] = mbplanets2[12]; + mbplanets2[15] = mbplanets2[13]; + + /* tactical screen planet bitmaps for surface properties */ + + bplanetsr[0] = bplanets[0]; + bplanetsr[1] = W_StoreBitmap(tw, th, planetr001_bits, w); + bplanetsr[2] = W_StoreBitmap(tw, th, planetr010_bits, w); + bplanetsr[3] = W_StoreBitmap(tw, th, planetr011_bits, w); + bplanetsr[4] = W_StoreBitmap(tw, th, planetr100_bits, w); + bplanetsr[5] = W_StoreBitmap(tw, th, planetr101_bits, w); + bplanetsr[6] = W_StoreBitmap(tw, th, planetr110_bits, w); + bplanetsr[7] = W_StoreBitmap(tw, th, planetr111_bits, w); + + /* galactic screen planet bitmaps for surface properties */ + + mbplanetsr[0] = mbplanets[0]; + mbplanetsr[1] = W_StoreBitmap(mw, mh, mplanetr001_bits, mapw); + mbplanetsr[2] = W_StoreBitmap(mw, mh, mplanetr010_bits, mapw); + mbplanetsr[3] = W_StoreBitmap(mw, mh, mplanetr011_bits, mapw); + mbplanetsr[4] = W_StoreBitmap(mw, mh, mplanetr100_bits, mapw); + mbplanetsr[5] = W_StoreBitmap(mw, mh, mplanetr101_bits, mapw); + mbplanetsr[6] = W_StoreBitmap(mw, mh, mplanetr110_bits, mapw); + mbplanetsr[7] = W_StoreBitmap(mw, mh, mplanetr111_bits, mapw); + + /* tactical screen bitmaps for facilities, MOO-style */ + + bplanetsMOO[0] = W_StoreBitmap(tw, th, rmyplanet000_bits, w); + bplanetsMOO[1] = W_StoreBitmap(tw, th, rmyplanet001_bits, w); + bplanetsMOO[2] = W_StoreBitmap(tw, th, rmyplanet010_bits, w); + bplanetsMOO[3] = W_StoreBitmap(tw, th, rmyplanet011_bits, w); + bplanetsMOO[4] = W_StoreBitmap(tw, th, rmyplanet100_bits, w); + bplanetsMOO[5] = W_StoreBitmap(tw, th, rmyplanet101_bits, w); + bplanetsMOO[6] = W_StoreBitmap(tw, th, rmyplanet110_bits, w); + bplanetsMOO[7] = W_StoreBitmap(tw, th, rmyplanet111_bits, w); + bplanetsMOO[8] = W_StoreBitmap(tw, th, rmyplanet1010_bits, w); + bplanetsMOO[9] = W_StoreBitmap(tw, th, rmyplanet1011_bits, w); + bplanetsMOO[10] = bplanetsMOO[8]; + bplanetsMOO[11] = bplanetsMOO[9]; + bplanetsMOO[12] = W_StoreBitmap(tw, th, rmyplanet1110_bits, w); + bplanetsMOO[13] = W_StoreBitmap(tw, th, rmyplanet1111_bits, w); + bplanetsMOO[14] = bplanetsMOO[12]; + bplanetsMOO[15] = bplanetsMOO[13]; + + /* galactic screen bitmaps for facilities, MOO-style */ + + mbplanetsMOO[0] = W_StoreBitmap(mw, mh, rmymplanet000_bits, mapw); + mbplanetsMOO[1] = W_StoreBitmap(mw, mh, rmymplanet001_bits, mapw); + mbplanetsMOO[2] = W_StoreBitmap(mw, mh, rmymplanet010_bits, mapw); + mbplanetsMOO[3] = W_StoreBitmap(mw, mh, rmymplanet011_bits, mapw); + mbplanetsMOO[4] = W_StoreBitmap(mw, mh, mplanet100_bits, mapw); + mbplanetsMOO[5] = W_StoreBitmap(mw, mh, mplanet101_bits, mapw); + mbplanetsMOO[6] = W_StoreBitmap(mw, mh, mplanet110_bits, mapw); + mbplanetsMOO[7] = W_StoreBitmap(mw, mh, mplanet111_bits, mapw); + mbplanetsMOO[8] = W_StoreBitmap(mw, mh, rmymplanet1010_bits, mapw); + mbplanetsMOO[9] = W_StoreBitmap(mw, mh, rmymplanet1011_bits, mapw); + mbplanetsMOO[10] = mbplanetsMOO[8]; + mbplanetsMOO[11] = mbplanetsMOO[9]; + mbplanetsMOO[12] = W_StoreBitmap(mw, mh, mplanet1110_bits, mapw); + mbplanetsMOO[13] = W_StoreBitmap(mw, mh, mplanet1111_bits, mapw); + mbplanetsMOO[14] = mbplanetsMOO[12]; + mbplanetsMOO[15] = mbplanetsMOO[13]; + + for (i = 0; i < NSCOUTAGES; i++) + mbplanetsA[i] = W_StoreBitmap(mw, mh, age_bits[i], mapw); + + /* star bitmaps */ + + for (i = 0; i < STARFRAMES; i++) { + starBM[i] = W_StoreBitmap(star_width, star_height, star_bitarray[i], w); + } + mstarBM = W_StoreBitmap(starm_width, starm_height, starm_bits, mapw); +#ifdef VISIBLE_WORMHOLES + mholeBM = W_StoreBitmap(holem_width, holem_height, holem_bits, mapw); +#endif /*VISIBLE_WORMHOLES*/ + for (i = 0; i < WORMFRAMES; i++) { + wormBM[i] = W_StoreBitmap(wormhole_width, wormhole_height, + wormhole_bitarray[i], w); + } + +/* set of 16 asteroid pics, and 3 asteroid fluff filler pics */ + asteroidBM[0] = W_StoreBitmap(terrain_width, terrain_height, + a0000_bits, w); + asteroidBM[1] = W_StoreBitmap(terrain_width, terrain_height, + a0001_bits, w); + asteroidBM[2] = W_StoreBitmap(terrain_width, terrain_height, + a0010_bits, w); + asteroidBM[3] = W_StoreBitmap(terrain_width, terrain_height, + a0011_bits, w); + asteroidBM[4] = W_StoreBitmap(terrain_width, terrain_height, + a0100_bits, w); + asteroidBM[5] = W_StoreBitmap(terrain_width, terrain_height, + a0101_bits, w); + asteroidBM[6] = W_StoreBitmap(terrain_width, terrain_height, + a0110_bits, w); + asteroidBM[7] = W_StoreBitmap(terrain_width, terrain_height, + a0111_bits, w); + asteroidBM[8] = W_StoreBitmap(terrain_width, terrain_height, + a1000_bits, w); + asteroidBM[9] = W_StoreBitmap(terrain_width, terrain_height, + a1001_bits, w); + asteroidBM[10] = W_StoreBitmap(terrain_width, terrain_height, + a1010_bits, w); + asteroidBM[11] = W_StoreBitmap(terrain_width, terrain_height, + a1011_bits, w); + asteroidBM[12] = W_StoreBitmap(terrain_width, terrain_height, + a1100_bits, w); + asteroidBM[13] = W_StoreBitmap(terrain_width, terrain_height, + a1101_bits, w); + asteroidBM[14] = W_StoreBitmap(terrain_width, terrain_height, + a1110_bits, w); + asteroidBM[15] = W_StoreBitmap(terrain_width, terrain_height, + a1111_bits, w); + asteroidfluff[0] = W_StoreBitmap(terrain_width, terrain_height, + a0_bits, w); + asteroidfluff[1] = W_StoreBitmap(terrain_width, terrain_height, + a1_bits, w); + asteroidfluff[2] = W_StoreBitmap(terrain_width, terrain_height, + a2_bits, w); + for (i = 0; i < 2; i++) { + basteroid2[i] = W_StoreBitmap(asteroid_width, asteroid_height, asteroid_bits, w); + mbasteroid2[i] = W_StoreBitmap(masteroid_width, masteroid_height, masteroid_bits, mapw); + } + for (i = 0; i < 6; i++) { + basteroid[i] = W_StoreBitmap(asteroid_width, asteroid_height, asteroid_bits, w); + mbasteroid[i] = W_StoreBitmap(masteroid_width, masteroid_height, masteroid_bits, mapw); + } + + kitchenSink = W_StoreBitmap(sink_width, sink_height, sink_bits, w); + + for (i = 0; i < EX_FRAMES; i++) { + expview[i] = W_StoreBitmap(ex_width, ex_height, ex_bits[i], w); + } + for (i = 0; i < SBEXPVIEWS; i++) { + sbexpview[i] = W_StoreBitmap(sbexp_width, sbexp_height, sbexp_bits[i], w); + } + + cloakicon = W_StoreBitmap(cloak_width, cloak_height, cloak_bits, w); + icon = W_StoreBitmap(icon_width, icon_height, icon_bits, iconWin); + tractbits = W_StoreBitmap(tract_width, tract_height, tract_bits, w); + pressbits = W_StoreBitmap(press_width, press_height, press_bits, w); +} + +void +get_N_dispatch_outfit_event(team, s_type, lastplayercount) + int *team; + int *s_type; + int *lastplayercount; +{ + W_Event event; + int validshipletter = 0; + static int resetting = 0; + int oldresetting; + int i; + + oldresetting = resetting; + + W_NextEvent(&event); + switch ((int) event.type) { + case W_EV_KEY: + { + struct shiplist *shipscan; + validshipletter = 0; + shipscan = shiptypes; + while (shipscan) { + if (shipscan->ship->s_letter == event.key) { + *s_type = shipscan->ship->s_type; + validshipletter = 1; + break; + } + shipscan = shipscan->next; + } + } + + if (me->p_status == PTQUEUE) { + int i; + for (i = 0; i < WNUM; i++) { + if (event.Window == messWin[i].window) { + messageWinEvent(&event); + break; + } + } + if (i != WNUM) + break; + if (event.Window == messagew || + event.Window == tstatw || + event.Window == warnw) + smessage(event.key); + } + if (event.Window == motdWin) { + motdWinEvent(event.key); + break; + } else if (event.Window == playerw || event.Window == infow) { + /* allow 'i' 'I' and '^i' in playerw [BDyess] */ + playerwEvent(&event); + break; + } else if (event.Window == w || event.Window == mapw) { + switch (event.key) { +#ifdef Q_OUTFITTING + case 'q': + *team = number_of_teams; + me->p_status = PFREE; + break; +#endif /* Q_OUTFITTING */ + case 'R': + warning("Are you sure you want to reset your stats?"); + resetting = 1; + break; + case 'y': + if (resetting) { + sendResetStatsReq('Y'); + warning("OK, your stats have been reset."); + resetting = 0; + } + break; + case 'n': + if (resetting) { + warning("I didn't think so."); + resetting = 0; + } + break; + + case 'f': /* Scroll motd forward */ + if (currpage == NULL) + currpage = motddata; + if (currpage == NULL || currpage->next == NULL) + break; + currpage->next->prev = currpage; + currpage = currpage->next; + showMotd(w); + resetting = 0; + break; + case 'b': /* Scroll motd backward */ + if (currpage == NULL || currpage->prev == NULL) + break; + currpage = currpage->prev; + showMotd(w); + resetting = 0; + break; + /* ok, let's have some info windows available on the TQ */ + + default: /* hmm, something that doesn't have to do + with the MOTD, maybe it's an info window + request */ + switch (doKeymap(&event)) { + case 'U': /* U = Rank list */ + if (W_IsMapped(rankw)) { + W_UnmapWindow(rankw); + } else { + W_MapWindow(rankw); + } + break; + case 'P': /* P = Planet list */ + if (W_IsMapped(planetw)) { + W_UnmapWindow(planetw); + W_UnmapWindow(planetw2); + } else { + W_MapWindow(planetw); + W_MapWindow(planetw2); + } + break; + case 'h': /* h = Map help window */ + if (W_IsMapped(helpWin)) { + W_UnmapWindow(helpWin); + } else { + W_MapWindow(helpWin); + } + if (optionWin) + optionredrawtarget(helpWin); + break; + case 'O': /* O = options Window */ + if (optionWin != NULL && W_IsMapped(optionWin)) + optiondone(); + else + optionwindow(); + break; + case 'w': /* w = map war stuff */ + if (W_IsMapped(war)) + W_UnmapWindow(war); + else + warwindow(); + break; + case '&': + if (defaultsFile) { + char buf[150]; + sprintf(buf, "Reading defaults from %s", defaultsFile); + warning(buf); + freeDefaults(); + defaultsFile = initDefaults(defaultsFile); + resetDefaults(); + } else { + warning("No defaults file to read from!"); + } + } + break; + } + + break; /* switch event type */ + } + if (event.Window == qwin) + return; /* normal keypresses can't make you quit */ + + if (event.Window == optionWin) { + optionaction(&event); + return; + } + if (!validshipletter) + break; + /* + it wasn't the main window, see if they hit the key in a team + window to choose their ship... falling through + */ + case W_EV_BUTTON: + + for (i = 0; i < number_of_teams; i++) + if (event.Window == teamWin[i]) { + *team = i; + break; + } + if (event.Window == qwin) { + *team = number_of_teams; + me->p_status = PFREE; + break; + } + /* allow message scrollback [BDyess] */ + for (i = 0; i < WNUM; i++) { + if (event.Window == messWin[i].window) { + messageWinEvent(&event); + break; + } + } + /* allow bozo selection in playerw [BDyess] */ + if (event.Window == playerw) { + playerwEvent(&event); + break; + } else if (event.Window == war) + waraction(&event); + else if (event.Window == optionWin) + optionaction(&event); + if (*team != -1 && !teamRequest(*team, *s_type)) { + *team = -1; + } + break; + case W_EV_EXPOSE: + for (i = 0; i < number_of_teams; i++) + if (event.Window == teamWin[i]) { + lastplayercount[i] = -1; /* force update */ + redrawTeam(teamWin[i], i, &lastplayercount[i]); + break; + } + if (event.Window == qwin) + redrawQuit(); + else if (event.Window == w) + showMotd(w); + else if (event.Window == mapw) { +#ifdef COW_HAS_IT_WHY_SHOULDNT_WE + if(showMapAtMotd) { + map(); + redraw_death_messages(); + } else +#endif + showValues(mapw); + } else + /* let the normal expose handler figure out who to redraw */ + dispatch_W_expose_event(&event); + break; + } + + if (oldresetting && resetting) { + resetting = 0; + warning("Resetting of stats cancelled"); + } +} + +void +new_entrywindow(team, s_type) + int *team, *s_type; +{ + int i; + int lastplayercount[4]; /* number of players on each team */ + int okayMask, lastOkayMask; /* teams you're allowed to choose */ + char buf[100]; + + /* OUTFIT timeout stuff */ + long startTime = -1; + long lasttime = -1; + int spareTime = 0; + + if (fastQuit) { + *team = -1; + return; + } + lastOkayMask = okayMask = tournMask; + +#ifdef PACKET_LIGHTS + /* erase packet lights to make Bob happy [BDyess] */ + light_erase(); +#endif /* PACKET_LIGHTS */ + + /* + map all team selection windows, and stripe out those that are + unchoosable + */ + for (i = 0; i < number_of_teams; i++) { + if (okayMask & (1 << i)) + W_UnTileWindow(teamWin[i]); + else + W_TileWindow(teamWin[i], stipple); + + W_MapWindow(teamWin[i]); + lastplayercount[i] = -1; + } + W_MapWindow(qwin); + + /* no team selected yet */ + *team = -1; + /* + set to team index (0..n-1) to choose a team. set to n if you want to + quit + */ + + /* I don't know why this restriction is in place - RF */ + if (me->p_whydead != KWINNER && me->p_whydead != KGENOCIDE) { + showMotd(w); +#ifdef COW_HAS_IT_WHY_SHOULDNT_WE + if(showMapAtMotd) { + map(); + redraw_death_messages(); + } else +#endif + showValues(mapw); + } + do { + + /* set team to n if you want to quit */ + while (!W_EventsPending() && (me->p_status == POUTFIT || + me->p_status == PTQUEUE)) { + /* no window events, just process socket stuff */ + fd_set mask; + +#ifdef PACKET_LIGHTS + light_erase(); +#endif /* PACKET_LIGHTS */ + + readFromServer(); + + if (me->p_status == POUTFIT || me->p_status == PTQUEUE) { + /* wait up to a half-second for input from the window system */ + struct timeval tv; + +#ifndef AMIGA + tv.tv_sec = 0; + tv.tv_usec = 500000; + + FD_ZERO(&mask); + FD_SET(W_Socket(), &mask); + select(W_Socket() + 1, &mask, 0, 0, &tv); +#else + StartTimer(0, 500000); + while (1) { +#ifdef DNET + sigsPending = Wait(W_Socket() | portmask | sockMask | udpSockMask | SIGBREAKF_CTRL_C); +#else +/* something else.... */ +#endif + if (sigsPending & SIGBREAKF_CTRL_C) { + printf("Ctrl-c break from entrywindow!\n"); + StopTimer(); + exit(0); + } + if ((sigsPending & (W_Socket() | sockMask | udpSockMask)) || + (CheckIO(&(ior->tr_node)))) + break; + } /* timer returns false signals, wish I knew + why. :-( */ + StopTimer(); +#endif /* AMIGA */ + } + +#ifdef COW_HAS_IT_WHY_SHOULDNT_WE + if(showMapAtMotd) { + map(); + redraw_death_messages(); + } +#endif + + if (me->p_status == PTQUEUE) + startTime = -1; + + if (me->p_status == POUTFIT) { + /* time only elapses in OUTFIT mode */ + + if (startTime == -1) { /* we were on the tqueue */ + /* I hate this [BDyess] */ +#if 1 + W_Deiconify(baseWin); /* we changed status. alert + the user */ +#endif + startTime = time(0); + spareTime = 480; /* Allow them extra time, as long */ + /* as they are active */ + } + elapsed = time(0) - startTime; + + if (elapsed > autoQuit) { + printf("Auto-Quit.\n"); + *team = number_of_teams; + break; + } + } + if (lasttime != time(0)) { + if (W_IsMapped(playerw)) + playerlist2(); + + if (newMotdStuff) { + showMotd(w); +#ifdef COW_HAS_IT_WHY_SHOULDNT_WE + if(showMapAtMotd) { + map(); + redraw_death_messages(); + } else +#endif + showValues(mapw); + } + if (me->p_status == POUTFIT) { + showTimeLeft(elapsed, autoQuit); + } + lasttime = time(0); + } + okayMask = tournMask; + + /* redraw those windows whose choosable status has changed */ + for (i = 0; i < number_of_teams; i++) { + if ((okayMask ^ lastOkayMask) & (1 << i)) { + if (okayMask & (1 << i)) { + W_UnTileWindow(teamWin[i]); + } else { + W_TileWindow(teamWin[i], stipple); + } + lastplayercount[i] = -1; /* force update */ + } + redrawTeam(teamWin[i], i, &lastplayercount[i]); + } + lastOkayMask = okayMask; + } + +#ifdef RECORDER + if (playback) /* silly. Shouldn't even be mapping team windows. */ + break; +#endif + /* they quit or ran out of time */ + if (*team == number_of_teams) { + me->p_status = PFREE; /* exit outer while loop */ + break; + } + /* + this makes them eventually run out of time no matter how awake + they are. Only affects the OUTFIT screen. + */ + if (me->p_status == POUTFIT && startTime != -1) { + if (time(0) - startTime <= spareTime) { + spareTime -= time(0) - startTime; + startTime = time(0); + } else { + startTime += spareTime; + spareTime = 0; + } + } + if (!W_EventsPending()) + continue; + + /* ok, there's a window event pending */ + + /* thiswill set p_status to PFREE if they decide to quit */ + get_N_dispatch_outfit_event(team, s_type, lastplayercount); + + } while ((me->p_status == POUTFIT || + me->p_status == PTQUEUE) +#ifdef RECORDER + && (!pb_update) +#endif + ); + + if (*team >= 0) { + strcpy(buf, "Welcome aboard "); + if (paradise) + strcat(buf, ranks2[me->p_stats2.st_rank].name); + else + strcat(buf, ranks[me->p_stats.st_rank].name); + sprintf(buf, "Welcome aboard %s!", get_players_rank_name(me)); + warning(buf); + } +#ifdef RECORDER + if (playback) { + extern int lastTeamReq; + *team = me->p_teami = lastTeamReq; + } else +#endif + /* if they quit or ran out of time */ + if (me->p_status == PFREE) + *team = -1; + else if (me->p_status == PALIVE || + me->p_status == POBSERVE) + if (*team == -1) + *team = me->p_teami; + else + me->p_teami = *team; + + + for (i = 0; i < number_of_teams; i++) + W_UnmapWindow(teamWin[i]); + W_UnmapWindow(qwin); +} + +/* Attempt to pick specified team & ship */ +static int +teamRequest(team, ship) + int team, ship; +{ + int lastTime; + +#ifdef RECORDER + extern int lastTeamReq; + + if (!playback) + lastTeamReq = team; +#endif +#ifdef TIMELORD + if (!allowed_to_keep_playing()) { + warning("You've played enough for today. Get back to work!"); + return 0; + } +#endif + pickOk = -1; + sendTeamReq(team, ship); + lastTime = time(NULL); + while (pickOk == -1) { + if (lastTime + 3 < time(NULL)) { + sendTeamReq(team, ship); + lastTime = time(NULL); + } + socketPause(0, 20000); + readFromServer(); + if (isServerDead()) { + printf("Whoops! We've been ghostbusted!\n"); + printf("Pray for a miracle!\n"); + + /* UDP fail-safe */ + commMode = commModeReq = COMM_TCP; + commSwitchTimeout = 0; + if (udpSock >= 0) + closeUdpConn(); + if (udpWin) { + udprefresh(UDP_CURRENT); + udprefresh(UDP_STATUS); + } + connectToServer(nextSocket); + printf("Yea! We've been resurrected!\n"); + pickOk = 0; + break; + } +#if 0 /* >this< is redundant ;-) */ + if (me->p_status == PALIVE) { /* well, something happened and we've + got a ship! */ + pickOk = 1; + break; + } +#endif + } + +#if 1 /* this is not redundant? */ + if (pickOk) { + me->p_status = PALIVE; /* we got a ship. We must be alive */ +#ifdef TIMER + timeBank[T_SHIP] = time(NULL); +#endif /* TIMER */ + } +#endif + return (pickOk); +} + +static int +numShips(owner) + int owner; +{ + int i, num = 0; + struct player *p; + + for (i = 0, p = players; i < nplayers; i++, p++) + if ((p->p_status == PALIVE || p->p_status == PTQUEUE) + && p->p_teami == owner) + num++; + return (num); +} + +#if 0 +int +realNumShips(owner) + int owner; +{ + int i, num = 0; + struct player *p; + + for (i = 0, p = players; i < MAXPLAYER; i++, p++) + if (p->p_status != PFREE && + p->p_team == owner) + num++; + return (num); +} +#endif + +#if 0 +int +deadTeam(owner) + int owner; +/* The team is dead if it has no planets and cannot coup it's home planet */ +{ + int i, num = 0; + struct planet *p; + + if (planets[remap[owner] * 10 - 10].pl_couptime == 0) + return (0); + for (i = 0, p = planets; i < MAXPLANETS; i++, p++) { + if (p->pl_owner & owner) { + num++; + } + } + if (num != 0) + return (0); + return (1); +} +#endif + +static int +checkBold(line) +/* Determine if that line should be highlighted on sign-on screen */ +/* Which is done when it is the players own score being displayed */ + char *line; +{ + char *s, *t; + int i; + int end = 0; + + if ((int) strlen(line) < 60) + return (0); + s = line + 4; + if (!me) + return (0); + t = me->p_name; + + for (i = 0; i < 16; i++) { + if (!end) { + if (*t == '\0') + end = 1; + else if (*t != *s) + return (0); + } + if (end) { + if (*s != ' ') + return (0); + } + s++; + t++; + } + return (1); +} + +struct list { + char bold; + struct list *next; + char *data; +}; +static struct list *sysdefptr = NULL; + +void +showMotd(win) + W_Window win; +{ + FILE *fopen(); + int i; + struct list *data; + int count; + int headernum; + + newMotdStuff = 0; /* clear the flag */ + + if (currpage == NULL) + currpage = motddata; + if (currpage == NULL) + return; + if (!W_IsMapped(win)) + return; + + headernum = currpage->page % NRHEADERS; + W_ClearWindow(win); + W_WriteWinBitmap(win, 0, 0, headerA, foreColor); + W_WriteWinBitmap(win, headerA_width, 0, headerB, foreColor); + W_WriteWinBitmap(win, headerA_width, headerB_height, headerchanges[headernum], foreColor); + if (headernum == 2) { /* fill in client: */ + /* note: font dependant */ + W_WriteText(win, headerA_width + header3_x_hot, headerB_height + header3_y_hot + - 7, textColor, CLIENTVERS, strlen(CLIENTVERS), W_BoldFont); + } else if (headernum == 3) {/* fill in server: */ + ; + } + if (currpage->first) { + currpage->first = 0; + data = currpage->text; + while (data != NULL) { + data->bold = checkBold(data->data); + data = data->next; + } + } + data = currpage->text; + count = LINESPERPAGE; /* Magical # of lines to display */ + i = headerA_height / (paradise ? 10 : W_Textheight) + 1; + while (count > 0) { + if (data == NULL) + break; + + if (data->bold) { + W_WriteText(win, 20, i * (paradise ? 10 : W_Textheight), textColor, data->data, + strlen(data->data), W_BoldFont); + } else { + W_WriteText(win, 20, i * (paradise ? 10 : W_Textheight), textColor, data->data, + strlen(data->data), W_RegularFont); + } + data = data->next; + count--; + i++; + } + if (win == w) { + count = W_StringWidth(blk_refitstring, W_RegularFont) / 2; + W_WriteText(mapw, 250 - count, 480, textColor, blk_refitstring, + strlen(blk_refitstring), W_RegularFont); + } + showPics(win); +/* showValues(mapw); Should be handled in event loop now RF */ +} + +static void +showPics(win) + W_Window win; +{ + struct piclist *temp; + int page; + + page = currpage->page; + temp = motdPics; + + while (temp != NULL) { + if (page == temp->page) { + if (temp->thepic) + W_WriteWinBitmap(win, temp->x, temp->y, temp->thepic, foreColor); + else { + W_MakeLine(win, temp->x, temp->y, + temp->x + temp->width - 1, temp->y + temp->height - 1, W_Grey); + W_MakeLine(win, temp->x, temp->y + temp->height - 1, + temp->x + temp->width - 1, temp->y, W_Grey); + W_MakeLine(win, temp->x, temp->y, + temp->x + temp->width - 1, temp->y, W_Grey); + W_MakeLine(win, temp->x, temp->y, + temp->x, temp->y + temp->height - 1, W_Grey); + W_MakeLine(win, temp->x, temp->y + temp->height - 1, + temp->x + temp->width - 1, temp->y + temp->height - 1, W_Grey); + W_MakeLine(win, temp->x + temp->width - 1, temp->y + temp->height - 1, + temp->x + temp->width - 1, temp->y, W_Grey); + } + } + temp = temp->next; + } +} + +/* + * ATM: show the current values of the .sysdef parameters. + */ +void +showValues(win) + W_Window win; +{ + int i; + struct list *data; + + /* try to find the start of the info */ + data = sysdefptr; + + for (i = 12; i < 50; i++) { + if (data == NULL) + break; + if (data->data[0] == '+') /* quick boldface hack */ + W_WriteText(win, 20, i * W_Textheight, textColor, data->data + 1, + strlen(data->data) - 1, W_BoldFont); + else + W_WriteText(win, 20, i * W_Textheight, textColor, data->data, + strlen(data->data), W_RegularFont); + data = data->next; + } +} + +#define BETWEEN_PAGES 0 +#define IN_PAGE 1 +#define IN_SYSDEF 3 + +static int motdlinestate = BETWEEN_PAGES; +static int pagecount = 0; +static struct list **temp = NULL; +static struct page **ptemp = NULL; +static int linecount = 0; +static struct piclist **motd_buftail = &motdPics; + +void +erase_motd() +{ + struct piclist *temppic; + struct page *temppage; + struct list *templist; + + while (motdPics) { + temppic = motdPics; + motdPics = temppic->next; + if (temppic->thepic) + W_FreeBitmap(temppic->thepic); + free(temppic); + } + motd_buftail = &motdPics; + + while (motddata) { + temppage = motddata; + motddata = temppage->next; + while (temppage->text) { + templist = temppage->text; + temppage->text = templist->next; + free(templist->data); + free(templist); + } + free(temppage); + } + motdlinestate = BETWEEN_PAGES; + currpage = 0; + pagecount = 0; + temp = 0; + ptemp = 0; + linecount = 0; + + while (sysdefptr) { + templist = sysdefptr; + sysdefptr = templist->next; + free(templist->data); + free(templist); + } +} + +void +newMotdPic(x, y, width, height, bits, page) + int x, y, page, width, height; + char *bits; +{ + struct piclist *temp; + + { + struct motd_pic_spacket dummy; + if ((width + 7) / 8 * height > sizeof(dummy.bits) && bits) { + fprintf(stderr, "MOTD picture from server is too big! %dx%d couldn't possibly fit in the %d data bytes of the packet\n", + width, height, (int) sizeof(dummy.bits)); + return; + } + } + if ((currpage && page == currpage->page) || page == 0) + newMotdStuff = 1; /* set flag for event loop */ + + temp = (*motd_buftail) = (struct piclist *) malloc(sizeof(struct piclist)); + temp->next = NULL; + temp->x = x; + temp->y = y; + temp->width = width; + temp->height = height; + temp->thepic = bits ? W_StoreBitmap(width, height, bits, motdWin) : 0; + temp->page = page; + motd_buftail = &(temp->next); +} + +void +newMotdLine(line) + char *line; +{ + + /* + Do this first. That way we don't even have to worry about it at all. + */ + + if (strncmp("BLK: ", line, 5) == 0) { + blk_parsemotd(line); + return; + } + if (strncmp("\t@@@", line, 4) == 0 && motdlinestate != IN_SYSDEF) { + motdlinestate = IN_SYSDEF; + temp = &sysdefptr; + } + if (strncmp("\t@@b", line, 4) == 0 && motdlinestate == IN_PAGE) + motdlinestate = BETWEEN_PAGES; + + if (motdlinestate == BETWEEN_PAGES || + (motdlinestate == IN_PAGE && linecount >= LINESPERPAGE)) { + if (motddata == NULL) + ptemp = &motddata; + (*ptemp) = (struct page *) malloc(sizeof(struct page)); + (*ptemp)->next = NULL; + (*ptemp)->first = 1; + (*ptemp)->prev = NULL; + (*ptemp)->page = pagecount++; + temp = &((*ptemp)->text); + (*ptemp)->text = NULL; + ptemp = &((*ptemp)->next); + motdlinestate = IN_PAGE; + linecount = 0; + } + if (strncmp("\t@@", line, 3) == 0) + return; + + if (!currpage || + (pagecount - 1) == currpage->page || + motdlinestate == IN_SYSDEF) + newMotdStuff = 1; /* set flag for event loop */ + + (*temp) = (struct list *) malloc(sizeof(struct list)); + (*temp)->next = NULL; + (*temp)->data = (char *) malloc(strlen(line) + 1); + strcpy((*temp)->data, line); + temp = &((*temp)->next); + + if (motdlinestate == IN_PAGE) + linecount++; +} + +/*ARGSUSED*/ +static void +getResources(prog) + char *prog; +{ + getColorDefs(); + getTiles(); +} + +static void +getTiles() +{ + stipple = W_StoreBitmap(stipple_width, stipple_height, stipple_bits, w); +} + +static void +redrawTeam(win, teamNo, lastnum) + W_Window win; + int teamNo; + int *lastnum; +{ + char buf[BUFSIZ]; + int num = numShips(teamNo); + + /* Only redraw if number of players has changed */ + if (*lastnum == num) + return; + + drawIcon(); + + W_ClearWindow(win); + W_WriteBitmap(0, 0, teaminfo[teamNo].shield_logo, shipCol[teamNo + 1]); + + (void) sprintf(buf, "%d", num); + W_MaskText(win, 5, 46, shipCol[teamNo + 1], buf, strlen(buf), + W_BigFont); + *lastnum = num; +} + +static void +redrawQuit() +{ + /* W_WriteText(qwin, 5, 5, textColor, "Quit xtrek", 10, W_RegularFont); */ + if (me->p_status == PTQUEUE) { + W_ClearArea(qwin, 0, 0, BOXSIDE, BOXSIDE); + W_WriteBitmap(0, 0, safepic, foreColor); + } +} + +void +drawIcon() +{ + if (!iconified) { + me_messages = 0; + team_messages = 0; + all_messages = 0; + } +#ifdef AMIGA + /* + not sure this isn't appropriate for X as well. This is called from + redrawTeam(), so iconified is set, and then all my personal messages + beep...iconified or not. + */ + if (W_IsMapped(iconWin)) +#endif + iconified = 1; + if (!infoIcon) { + W_WriteBitmap(0, 0, icon, W_White); + } else { /* code for information icon 1/15 [BDyess] */ + int side, bottom, top, digits, x, i; + char buf[50]; + + W_ClearWindow(iconWin); + side = icon_width / number_of_teams; + bottom = 0 + side; + top = 0; + W_MakeLine(iconWin, 0, bottom, icon_width, bottom, W_White); + for (i = 0; i <= number_of_teams; i++) { /* draw the vertical + lines */ + x = i * side; + x = (x > icon_width) ? icon_width : x; + W_MakeLine(iconWin, x, bottom, x, top, W_White); + } + for (i = 0; i < number_of_teams; i++) { + sprintf(buf, "%d", numShips(i)); + digits = strlen(buf); + W_WriteText(iconWin, i * side + side / 2 - digits * W_Textwidth / 2, + bottom - side / 2 - W_Textheight / 2, + shipCol[i + 1], buf, digits, W_RegularFont); + } + if (me->p_status == PALIVE) { +#define TOP icon_height-10 + if (me->p_flags & PFGREEN) + W_FillArea(iconWin, 0, TOP, icon_width, + icon_height, W_Green); + else if (me->p_flags & PFYELLOW) + W_FillArea(iconWin, 0, TOP, + icon_width, icon_height, W_Yellow); + else if (me->p_flags & PFRED) + W_FillArea(iconWin, 0, TOP, + icon_width, icon_height, W_Red); + } + if (me_messages) { + sprintf(buf, "Personal: %d", me_messages); + W_WriteText(iconWin, 1, bottom + 2, W_White, buf, strlen(buf), + W_RegularFont); + } + if (team_messages) { + sprintf(buf, "Team: %d", team_messages); + W_WriteText(iconWin, 1, bottom + 2 + W_Textheight, W_White, buf, + strlen(buf), W_RegularFont); + } + if (all_messages) { + sprintf(buf, "All: %d", all_messages); + W_WriteText(iconWin, 1, bottom + 2 + 2 * W_Textheight, W_White, buf, + strlen(buf), W_RegularFont); + } + if (me->p_status == POUTFIT) { + sprintf(buf, "Time left: %d", autoQuit - elapsed); + W_WriteText(iconWin, 1, bottom + 2 + W_Textheight, W_White, buf, + strlen(buf), W_RegularFont); + } + } +} + +#define CLOCK_WID BOXSIDE +#define CLOCK_HEI BOXSIDE +#define CLOCK_BDR 0 + +#ifndef PI +#define PI 3.141592654 +#endif /* PI */ + +static void +showTimeLeft(time, max) + int time, max; +{ + char buf[BUFSIZ]; + int cx, cy, ex, ey, tx, ty; + + if ((max - time) < 10 && time & 1) { + W_Beep(); + W_Deiconify(baseWin); + } + if (iconified) + drawIcon(); + /* XFIX */ + W_ClearArea(qwin, 0, 0, BOXSIDE, BOXSIDE); + + W_WriteBitmap(0, 0, clockpic, foreColor); + + cx = BOXSIDE / 2; + cy = BOXSIDE / 2 - 6; + ex = cx - 35 * Sin[((255 * time) / max + 64) % 256]; + ey = cy - 35 * Cos[((255 * time) / max + 64) % 256]; + W_MakeLine(qwin, cx, cy, ex, ey, foreColor); + + sprintf(buf, "%d", max - time); + cy = BOXSIDE / 2 - 1; + tx = cx - W_StringWidth(buf, W_RegularFont) / 2.0; + ty = cy - W_Textheight; + W_WriteText(qwin, tx, ty, textColor, buf, strlen(buf), W_RegularFont); +} + + +void +do_refit(type) + int type; +{ + sendRefitReq(type); + localflags &= ~PFREFIT; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/oldbitmaps.h Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,832 @@ +/* $Id: oldbitmaps.h,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +static unsigned char ex_bits[5][512] = {{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x01, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x08, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0x08, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0x04, 0x0a, 0x00, 0x12, 0x00, 0x00, 0x10, + 0x11, 0x00, 0x18, 0x00, 0x02, 0x00, 0x00, 0x00, 0x81, 0x06, 0x08, 0x10, 0x00, 0x00, 0x00, + 0x08, 0x10, 0x1a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1c, 0x08, 0x02, 0x00, 0x00, + 0x00, 0x04, 0x07, 0x0b, 0x20, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0b, 0x08, 0x18, 0x00, 0x00, + 0x00, 0x00, 0xc4, 0xe0, 0x0f, 0x06, 0x00, 0x00, 0x00, 0x00, 0x70, 0x94, 0x15, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x30, 0xd5, 0x75, 0x20, 0x00, 0x00, 0x00, 0x00, 0x04, 0x95, 0x22, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x02, 0x60, 0x1b, 0x00, 0x00, 0x00, 0x80, 0x09, 0x00, 0xf4, 0x1e, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x01, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, + 0x26, 0x06, 0x00, 0x00, 0x00, 0x00, 0x04, 0x73, 0x28, 0x08, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0xa0, 0x26, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x30, 0x0c, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x42, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xf0, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00}, +{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x04, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x40, 0x00, + 0x00, 0x00, 0x80, 0x61, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, 0xc0, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x48, 0x04, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x4c, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x04, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, + 0x42, 0x01, 0x00, 0x00, 0x00, 0x00, 0x51, 0x08, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x40, 0x80, 0x00, 0x00, 0x04, 0x08, 0x00, 0x03, 0x00, 0x45, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x07, 0x00, 0x80, 0x00, 0x00, 0x09, 0x08, 0x00, 0x89, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x03, 0xa0, 0xc0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x25, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x12, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x02, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0x12, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x22, 0x92, 0x00, 0x12, + 0x00, 0x00, 0x10, 0x10, 0x00, 0x40, 0x04, 0x00, 0x00, 0x00, 0x90, 0x00, 0x12, 0x42, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x48, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, + 0x47, 0x02, 0x00, 0x00, 0x00, 0x00, 0x20, 0x28, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x42, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, + 0x00, 0x00, 0xc0, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x82, 0x00, 0x20, 0x00, 0x00, 0x00, 0x28, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x14, 0x00, 0x03, 0x00, 0x80, 0x00, 0x80, 0x01, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x20, 0xc0, 0x01, 0x00, 0xc0, 0x21, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x60, 0x00, 0x00, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00}, +{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x48, 0x02, 0x00, 0x08, 0x00, + 0x00, 0x80, 0x01, 0x02, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x80, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x08, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x91, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x44, 0x40, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x30, 0x41, 0x82, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x05, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x01, 0x88, 0x06, 0x45, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x29, + 0x00, 0x00, 0x00, 0x00, 0x30, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x20, + 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x22, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x12, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x90, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, + 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x80, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x80, + 0x21, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00}, +{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x40, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x11, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, + 0x00, 0x00, 0x02, 0x40, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x02, 0x10, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x40, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x82, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x08, 0x02, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x22, 0x20, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, + 0x00, 0x00, 0x00, 0x08, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00}, +{0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x04, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x40, 0x80, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x40, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x42, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x00, + 0x00, 0x20, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x08, 0x00, + 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x02, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x44, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x80, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x20, 0x00, 0x00, 0x00, 0x01, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00}}; + +static unsigned char sbexp_bits[7][800] = {{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x81, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf2, 0x1f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xbe, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf6, 0x4f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xde, 0x7d, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xea, 0xef, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x55, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xdd, 0xfd, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xbf, 0xae, 0x22, 0x36, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xdb, 0xf7, 0x3f, 0x1e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x50, 0xbf, 0xbf, 0x85, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xe5, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xee, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x74, 0x4b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe8, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xf8, 0x49, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x54, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc0, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x78, 0x91, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0xf1, 0x53, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x97, 0x5c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xa0, 0x0c, 0x8c, 0x1b, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc4, 0x01, 0x00, 0xc8, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x02, 0x00, 0x88, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x00, 0x02, 0x40, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x70, 0x00, 0x0c, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x70, 0xe0, 0x0d, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x72, 0xc8, 0x07, 0x40, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x02, 0x78, 0x2f, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x02, 0xb0, 0x0a, 0x20, 0x77, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x13, 0x10, 0x33, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x02, 0x78, 0xbb, 0x81, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0xdc, 0xe7, 0x00, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xac, 0x78, 0x00, 0x31, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x03, 0x74, 0x4b, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x02, 0xe8, 0x3e, 0x00, 0x01, 0x10, 0x00, + 0x00, 0x00, 0x80, 0x00, 0xf8, 0x49, 0x80, 0x09, 0x1c, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x40, 0x07, 0x00, 0x05, 0x1c, 0x00, + 0x00, 0x00, 0x80, 0x09, 0x04, 0x80, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x1d, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xe3, 0x0b, 0x00, 0x22, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x8f, 0x10, 0x00, 0xa0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x4f, 0x20, 0x78, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x80, 0x79, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x78, 0x7c, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0xc0, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x84, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x60, 0x06, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x07, 0x64, 0x3a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x72, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3b, 0x00, 0x00, 0xc0, 0x33, 0x00, 0x00, + 0x00, 0x00, 0xa0, 0x1b, 0x00, 0x00, 0x80, 0x42, 0x00, 0x00, + 0x00, 0x00, 0xd0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, + 0x00, 0x30, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x80, 0x03, 0x03, 0x80, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0xe2, 0x82, 0x03, 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x0e, 0x80, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x0e, 0x80, 0x03, 0xec, 0x10, 0x00, 0x00, 0x60, 0x00, + 0x00, 0x12, 0x00, 0x00, 0x05, 0x93, 0x01, 0x00, 0x20, 0x00, + 0x00, 0x12, 0x00, 0x00, 0x00, 0x5c, 0x0c, 0x00, 0x60, 0x00, + 0x00, 0x30, 0x00, 0xc0, 0x05, 0x81, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x2c, 0x00, 0x00, 0xcc, 0x06, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x28, 0x20, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x80, 0x80, 0x22, 0x00, 0x02, 0x00, 0x00, 0x02, + 0x00, 0x20, 0x00, 0x80, 0x02, 0x20, 0x08, 0x00, 0x20, 0x02, + 0x00, 0x38, 0x00, 0x00, 0x00, 0x11, 0x28, 0x00, 0x20, 0x06, + 0x00, 0x20, 0x00, 0x80, 0x0e, 0xc0, 0x21, 0x00, 0x5c, 0x00, + 0x00, 0x24, 0x00, 0x90, 0x40, 0x58, 0x04, 0x00, 0x20, 0x01, + 0x00, 0x24, 0x00, 0x10, 0x22, 0x02, 0x05, 0x00, 0x20, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x28, 0xb6, 0x00, 0x00, 0x20, 0x01, + 0x00, 0x70, 0x00, 0x00, 0x18, 0xc1, 0x00, 0x00, 0xc0, 0x01, + 0x00, 0xc0, 0x00, 0x00, 0x40, 0x83, 0x04, 0x00, 0xc0, 0x01, + 0x00, 0x00, 0x01, 0x80, 0xfc, 0x41, 0x02, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x03, 0x30, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x10, 0x02, 0x00, 0x40, 0x1d, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x30, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x60, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, + 0x00, 0x00, 0x38, 0x00, 0x81, 0x0f, 0x00, 0x00, 0x2a, 0x00, + 0x00, 0x00, 0xf8, 0x02, 0x80, 0x0f, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0xf8, 0x02, 0x80, 0x0f, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x06, 0xc0, 0x01, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x14, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x70, 0x00, 0x00, 0x85, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x00, 0x30, 0x00, 0x20, 0x3c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xe0, 0xe0, 0x80, 0x00, 0x0b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xe0, 0x79, 0x83, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x19, 0x22, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x28, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xe0, 0x03, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0x90, 0x00, 0x00, 0x00, 0x40, + 0x02, 0x02, 0x00, 0x80, 0x80, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x40, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x20, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x28, 0x90, 0x05, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x00, 0x48, 0x05, 0x00, 0x21, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x84, 0x00, 0x54, 0x05, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x40, 0x05, 0x80, 0x41, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x02, 0x01, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x08, 0x20, 0x20, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x84, 0x82, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x48, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x40, + 0x04, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x21, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x90, 0x40, 0x40, 0x04, 0x00, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x41, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x40, 0xa0, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x40, + 0x40, 0x00, 0x00, 0x00, 0x40, 0x02, 0x04, 0x00, 0x00, 0x30, + 0x00, 0x00, 0x00, 0x80, 0x84, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x20, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0xc0, 0x05, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x00, 0x10, + 0x08, 0x00, 0x00, 0x80, 0x00, 0x10, 0x10, 0x00, 0x00, 0x08, + 0x10, 0x02, 0x00, 0x00, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x08, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3a, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x40, 0x04, + 0x00, 0x60, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +{ + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x08, 0x00, 0x00, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1f, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x60, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x01, 0x00, 0x01, 0x10, 0x04, 0x00, 0x00, + 0x00, 0x40, 0x00, 0x02, 0x02, 0x90, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1c, 0x20, 0x05, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x20, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xc4, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x40, 0x00, 0x00, 0x40, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x42, 0x00, 0x00, 0x04, 0x20, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x81, 0x07, 0x01, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x02, 0x80, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0xc0, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x0d, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x10, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x00, + 0x02, 0x02, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xc0, 0x00, 0x40, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, + 0x00, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00}, +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x80, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x01, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + +/*#define drone_width 6*/ +/*#define drone_height 6*/ + +#ifndef NDRONEVIEWS +#define NDRONEVIEWS 16 +#endif +static unsigned char drone_bits[NDRONEVIEWS][6] = { + {0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x1e}, + {0x18, 0x18, 0x0c, 0x0e, 0x0f, 0x0e}, + {0x00, 0x18, 0x1c, 0x0f, 0x07, 0x06}, + {0x00, 0x30, 0x3f, 0x0f, 0x07, 0x02}, + {0x00, 0x03, 0x3f, 0x3f, 0x03, 0x00}, + {0x02, 0x07, 0x0f, 0x3f, 0x30, 0x00}, + {0x06, 0x07, 0x0f, 0x1c, 0x18, 0x00}, + {0x0e, 0x0f, 0x0e, 0x0c, 0x18, 0x18}, + {0x1e, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c}, + {0x1c, 0x3c, 0x1c, 0x0c, 0x06, 0x06}, + {0x18, 0x38, 0x3c, 0x0e, 0x06, 0x00}, + {0x10, 0x38, 0x3c, 0x3f, 0x03, 0x00}, + {0x00, 0x30, 0x3f, 0x3f, 0x30, 0x00}, + {0x00, 0x03, 0x3f, 0x3c, 0x38, 0x10}, + {0x00, 0x06, 0x0e, 0x3c, 0x38, 0x18}, + {0x06, 0x06, 0x0c, 0x1c, 0x3c, 0x1c} +}; + +static unsigned char plasmacloud_bits[5][26] = {{ + 0x40, 0x00, 0xf2, 0x09, 0xfc, 0x07, 0xfc, 0x07, 0xfe, 0x0f, 0xfe, 0x0f, 0xff, 0x1f, 0xfe, +0x0f, 0xfe, 0x0f, 0xfc, 0x07, 0xfc, 0x07, 0xf2, 0x09, 0x40, 0x00}, +{0x40, 0x00, 0x42, 0x08, 0x44, 0x04, 0xe8, 0x02, 0xf0, 0x01, 0xf8, 0x03, 0xff, 0x1f, 0xf8, +0x03, 0xf0, 0x01, 0xe8, 0x02, 0x44, 0x04, 0x42, 0x08, 0x40, 0x00}, +{0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x48, 0x02, 0x50, 0x01, 0xe0, 0x00, 0xbc, 0x07, 0xe0, +0x00, 0x50, 0x01, 0x48, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00}, +{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xb8, 0x03, 0x40, +0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xb8, 0x03, 0x40, +0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + +static unsigned char cloud_bits[5][18] = {{ + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x28, 0x00, 0x54, 0x00, 0x28, 0x00, 0x10, 0x00, 0x00, +0x00, 0x00, 0x00}, +{0x00, 0x00, 0x28, 0x00, 0x54, 0x00, 0xaa, 0x00, 0x54, 0x00, 0xaa, 0x00, 0x54, 0x00, 0x28, +0x00, 0x00, 0x00}, +{0x54, 0x00, 0xaa, 0x00, 0x55, 0x01, 0xaa, 0x00, 0x55, 0x01, 0xaa, 0x00, 0x55, 0x01, 0xaa, +0x00, 0x54, 0x00}, +{0x00, 0x00, 0x28, 0x00, 0x54, 0x00, 0xaa, 0x00, 0x54, 0x00, 0xaa, 0x00, 0x54, 0x00, 0x28, +0x00, 0x00, 0x00}, +{0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x28, 0x00, 0x54, 0x00, 0x28, 0x00, 0x10, 0x00, 0x00, +0x00, 0x00, 0x00}}; + +static unsigned char etorp_bits[] = {0x05, 0x02, 0x05}; + +static unsigned char eplasmatorp_bits[] = {0x08, 0x2a, 0x1c, 0x7f, 0x1c, 0x2a, 0x08}; + +static unsigned char mtorp_bits[] = {0x02, 0x07, 0x02}; + +static unsigned char mplasmatorp_bits[] = {0x04, 0x0e, 0x1f, 0x0e, 0x04}; + +/* Fighter bitmap */ +#ifndef fighter_width +#define fighter_width 5 +#define fighter_height 5 +#endif +static unsigned char fighter_bits[VIEWS][60] = {{ +0x04, 0x04, 0x0e, 0x1f, 0x04}, +{0x08, 0x04, 0x0f, 0x0e, 0x0a}, +{0x10, 0x0f, 0x0f, 0x0e, 0x0c}, +{0x01, 0x17, 0x0e, 0x07, 0x04}, +{0x02, 0x06, 0x1f, 0x06, 0x02}, +{0x04, 0x07, 0x0e, 0x17, 0x00}, +{0x0c, 0x0e, 0x0f, 0x0f, 0x10}, +{0x1a, 0x0e, 0x0f, 0x04, 0x08}, +{0x04, 0x1f, 0x0e, 0x04, 0x04}, +{0x0a, 0x0e, 0x1e, 0x04, 0x02}, +{0x06, 0x0e, 0x1e, 0x1e, 0x01}, +{0x04, 0x1c, 0x0e, 0x1d, 0x10}, +{0x08, 0x0c, 0x1f, 0x0c, 0x08}, +{0x00, 0x1d, 0x0e, 0x1c, 0x04}, +{0x01, 0x1e, 0x1e, 0x0e, 0x06}, +{0x02, 0x04, 0x1e, 0x0e, 0x0b}}; + +static unsigned char warpbeacon_bits[] = { +0x18, 0x24, 0x24, 0x24, 0x18, 0xdb, 0x3c, 0xdb, 0x18, 0x18, 0x3c, 0x18}; + +static unsigned char warpflash_bits[] = { +0x24, 0x18, 0x7e, 0x18, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/option.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,1029 @@ +/* $Id: option.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +/* + * option.c + */ +#include "copyright.h" + +#include <stdio.h> +#include <ctype.h> +#include "Wlib.h" +#ifdef SOUND +#include "Slib.h" +#endif +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "packets.h" +#include "proto.h" + +#ifdef DEBUG +#define IFDEBUG(foo) foo +#else +#define IFDEBUG(foo) +#endif + +static int notdone; /* not done flag */ +static int oldzoom = -2; + +/* kludgy way to make options that do some action when clicked: */ +static int clearPhaserStats = 1; +static int reloadShipBitmaps = 1; + +#ifdef ROTATERACE +static int old_rotate, old_rotate_deg; +#endif + +static int old_ping; + +/* static int updateSpeed= 5;*/ +static int lastUpdateSpeed = -1; + +static char newkeys[14]; +static char newckeys[14]; +static char newbuttons[14]; +static char newcbuttons[14]; + +static int remapAllShips = 1; + +char *keymapmes[] = { + "Key/Buttonmap only affect THIS ship type", + "Key/Buttonmap affect ALL ship types", + "" +}; + +#ifdef TIMER +char *timermes[] = +{"Timer shows nothing (off)", + "Timer shows time of day", + "Timer shows time on server", + "Timer shows time in ship", + "Timer shows user-set time", +""}; +#endif /* TIMER */ + +char *localmes[] = +{"Show owner on local planets", + "Show facilities on local planets", + "Show nothing on local planets", + "Show surface properties on local planets", + "Show MOO facilities on local planets", +""}; + +char *galacticmes[] = +{"Show owner on galactic map", + "Show facilities on galactic map", + "Show nothing on galactic map", + "Show surface properties on galactic map", + "Show scout info age on galactic map", + "Show MOO facilities on galactic map", +""}; + +#ifdef ROTATERACE +char *rotatemess[] = +{"Don't rotate galaxy", + "Rotate galaxy 90 degrees", + "Rotate galaxy 180 degrees", + "Rotate galaxy 270 degrees", + "" +}; +#endif + +char *mapupdates[] = +{"Don't update galactic map", + "Update galactic map frequently", + "Update galactic map rarely", +""}; + +static char *lockoptions[] = +{"Don't show lock icon", + "show lock icon on galactic map only", + "Show lock icon on tactical map only", +"Show lock icon on both map windows", ""}; + +static char *phaseroptions[] = +{"Don't show phaser messages", + "Phaser messages in kill window", + "Phaser messages in phaser window", + "Phaser messages in phaser window only", + "Phaser messages in total review only", +""}; + +static char *dashboardoptions[] = +{"Old Dashboard", + "New Dashboard", + "Color Dashboard", + "Rainbow Dashboard", +""}; + +static char *autoZoomOpts[] = +{"Don't auto-zoom map", + "Auto-zoom map on Red OR Yellow Alert", + "Auto-zoom map on Red Alert", +""}; + +static char *autoUnZoomOpts[] = +{"Don't auto-unzoom map", + "Auto-unzoom map on Green alert", + "Auto-unzoom map on Green OR Yellow Alert", +""}; + +static char *autoSetWarOpts[] = +{"Don't auto set war declarations", + "Set war with non-zero player teams", + "Set war with largest enemy team", +""}; + +/* useful for options that are an int with a range */ +struct int_range { + int min_value; /* value is >= this */ + int max_value; /* value is <= this */ + int increment; /* a click raises/lowers this amount */ + /* do bitwise shift by 1 if increment */ + /* == -1 */ +}; + + +/* + * Only one of op_option, op_targetwin, and op_string should be defined. If + * op_string is defined, op_size should be too and op_text is used without a + * "Don't" prefix. if op_range is defined, there should be a %d in op_text + * for it, op_size will be non-useful, and the 'Don't ' prefix won't appear + */ +struct option { + char *op_text; /* text to display when on */ + int *op_option; /* variable to test/modify (optional) */ + W_Window *op_targetwin; /* target window to map/unmap (optional) */ + char *op_string; /* string to modify (optional) */ + int op_size; /* size of *op_string (optional) */ + char **op_array; /* array of strings to switch between */ + struct int_range *op_range; /* struct definint an integer range option */ + + int op_num; /* used internally */ +}; + +/* for the paged options menus */ +struct option_menu { + int page_num; /* page number of this menu */ + struct option_menu *Next; + struct option *menu; /* pointers to arrary of options */ + int numopt; /* number of options in this menu page */ + int updated; /* 1 if options can be changed externally */ +}; + +/* pointer to first entry in the options menu list */ +static +struct option_menu *FirstMenu = NULL; +static +struct option_menu *CurrentMenu = NULL; /* menu currently looked at */ +int MenuPage = 1; /* current menu page */ +int MaxOptions = 0; /* maximum number of options in all menu + pages */ +struct int_range MenuPages = +{1, 1, 1}; + +/* range of updates for keep-info-window-up option */ +struct int_range keepInfo_range = +{0, 100, 1}; + +/* updates: use of the int range thing... */ +struct int_range updates_range = +{1, 10, 1}; + +struct int_range redraw_delay_range = +{0, 10, 1}; + +/* range of menus. Will be updated when menu list is assembled */ +struct int_range Menus_Range = +{1, 1, 1}; + +#ifdef CONTINUOUS_MOUSE +struct int_range clickDelay_range = +{0, 20, 1}; +#endif /* CONTINUOUS_MOUSE */ + +#ifdef BEEPLITE +struct int_range beeplite_planet_range = +{0, 50, 1}; +struct int_range beeplite_player_range = +{0, 50, 1}; +#endif + +struct int_range zoom_override_range = +{0, 99, 1}; + +#ifdef LOCAL_SHIPSTATS +struct int_range statHeight_range = +{4,100, 4}; +#endif + +/* range for tacPlanetInfo */ +struct int_range tacPlanetInfo_range = {0, 31, 1}; + +/* menus */ + +struct option Features_Menu[] = +{ + {"Defaults Menu", &MenuPage, 0, 0, 0, NULL, &Menus_Range}, + {"Page %d (click here to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range}, + {0, &mapmode, 0, 0, 0, mapupdates, NULL}, + {0, &showgalactic, 0, 0, 0, galacticmes, NULL}, + {0, &showlocal, 0, 0, 0, localmes, NULL}, +#ifdef SHOW_IND + {"show IND planets", &showIND, 0, 0, 0, NULL, NULL}, +#endif + {"send MOTD bitmaps", &sendmotdbitmaps, 0, 0, 0, NULL, NULL}, + {"reload ship bitmaps", &reloadShipBitmaps, 0, 0, 0, NULL, NULL}, + {"stay peaceful when reborn", &keeppeace, 0, 0, 0, NULL, NULL}, + {0, &remapAllShips, 0, 0, 0, keymapmes, NULL}, + {"new keymap entries: %s_", 0, 0, newkeys, 13, NULL, NULL}, + {"new ckeymap entries: %s_", 0, 0, newckeys, 13, NULL, NULL}, + {"new buttonmap entries: %s_", 0, 0, newbuttons, 13, NULL, NULL}, + {"new cbuttonmap entries: %s_", 0, 0, newcbuttons, 13, NULL, NULL}, + {"report kill messages", &reportKills, 0, 0, 0, NULL, NULL}, +#if 0 + /* need to figure out how to dispatch options */ + {"recv variable packets", &recv_short, 0, 0, 0, NULL}, + {"recv kill messages", &recv_kmesg, 0, 0, 0, NULL}, +#endif + {"keep info %d upds (0=forever)", &keepInfo, 0, 0, 0, 0, &keepInfo_range}, + {"%d updates per second", &updateSpeed, 0, 0, 0, 0, &updates_range}, + {"%d/10 sec screen refresh delay", &redrawDelay, 0, 0, 0, 0, &redraw_delay_range}, + {"collect ping stats", &ping, 0, 0, 0, NULL, NULL}, + {"avoid message kludge", &niftyNewMessages, 0, 0, 0, NULL, NULL}, +#ifdef CONTINUOUS_MOUSE + {"use continuous mouse", &continuousMouse, 0, 0, 0, NULL, NULL}, + {"%d updates repeat delay", &clickDelay, 0, 0, 0, 0, &clickDelay_range}, +#endif /* CONTINUOUS_MOUSE */ +#ifdef UNIX_SOUND + {"play sound effects", &playSounds, 0, 0, 0, NULL, NULL}, +#endif + {"done", ¬done, 0, 0, 0, NULL, NULL}, + {NULL, 0, 0, 0, 0, NULL, NULL, /**/ -1} +}; + +struct option Window_Menu[] = +{ + {"Window Menu", &MenuPage, 0, 0, 0, NULL, &Menus_Range}, + {"Page %d (click here to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range}, + {"show \"all\" message window", 0, &messWin[WALL].window, 0, 0, NULL, NULL}, + {"show \"team\" message window", 0, &messWin[WTEAM].window, 0, 0, NULL, NULL}, + {"show \"your\" message window", 0, &messWin[WINDIV].window, 0, 0, NULL, NULL}, + {"show \"kill\" message window", 0, &messWin[WKILL].window, 0, 0, NULL, NULL}, + {"show \"phaser\" message window", 0, &messWin[WPHASER].window, 0, 0, NULL, NULL}, + {"show \"joined\" message window", 0, &messWin[WREVIEW].window, 0, 0, NULL, NULL}, + {"show ship statistics window", 0, &statwin, 0, 0, NULL, NULL}, + {"show network statistics window", 0, &pStats, 0, 0, NULL, NULL}, + {"show help window", 0, &helpWin, 0, 0, NULL, NULL}, +#ifdef XTREKRC_HELP + {"show xtrekrc defaults window", 0, &defWin, 0, 0, NULL, NULL}, +#endif +#ifdef TOOLS + {"show shell tools window", 0, &toolsWin, 0, 0, NULL, NULL}, +#endif + {0, &showPhaser, 0, 0, 0, phaseroptions, NULL}, + {"", &showLock, 0, 0, 0, lockoptions, NULL}, + {"show lock line", &lockLine, 0, 0, 0, NULL, NULL}, + {"sort planets by team", &mapSort, 0, 0, 0, NULL, NULL}, +#ifdef NOWARP + {"enable message warp", &warp, 0, 0, 0, NULL, NULL}, +#endif + {"use info icon", &infoIcon, 0, 0, 0, NULL, NULL}, + {"done", ¬done, 0, 0, 0, NULL, NULL}, + {NULL, 0, 0, 0, 0, NULL, NULL, /**/ -1} +}; + +struct option Display_Menu[] = +{ + {"Features Display Menu", &MenuPage, 0, 0, 0, NULL, &Menus_Range}, + {"Page %d (click here to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range}, +#ifdef ROTATERACE + {0, &rotate, 0, 0, 0, rotatemess, NULL}, +#endif + {"draw background stars", &blk_showStars, 0, 0, 0, NULL}, + {"show warp/star streaks", &warpStreaks, 0, 0, 0, NULL, NULL}, + {"show tractor/pressor", &showTractorPressor, 0, 0, 0, NULL, NULL}, + {"show all tractors/pressors", &showAllTractorPressor, 0, 0, 0, NULL, NULL}, + {"show shields", &showShields, 0, 0, 0, NULL, NULL}, + {"show shield damage", &show_shield_dam, 0, 0, 0, NULL, NULL}, +#ifdef VARY_HULL + {"show hull damage indicators", &vary_hull, 0, 0, 0, NULL, NULL}, +#endif /* VARY_HULL */ + + {"show tactical planet names", &namemode, 0, 0, 0, NULL, NULL}, + + {"zoom galactic map", &blk_zoom, 0, 0, 0, NULL, NULL}, + {0,&autoZoom, 0, 0, 0, autoZoomOpts, NULL}, + {0,&autoUnZoom, 0, 0, 0, autoUnZoomOpts, NULL}, + {"Manual zoom overrides auto-zoom %d updates",&autoZoomOverride, 0, 0, 0, NULL, + &zoom_override_range}, + {"draw galactic map grid", &drawgrid, 0, 0, 0, NULL}, + {"show sector numbers", §orNums, 0, 0, 0, NULL, NULL}, + {"show view box", &viewBox, 0, 0, 0, NULL, NULL}, + {0, &autoSetWar, 0, 0, 0, autoSetWarOpts, NULL}, + {"show planet info on tactical: %d", &tacPlanetInfo, 0, 0, 0, 0, &tacPlanetInfo_range}, +#ifdef BEEPLITE + {"use RCD highlighting", &UseLite, 0, 0, 0, NULL, NULL}, + {"highlight/use default RCDs", &DefLite, 0, 0, 0, NULL, NULL}, + {"No. of updates to highlight player: %d", &beep_lite_cycle_time_player, + 0, 0, 0, NULL, &beeplite_player_range}, + {"No. of updates to highlight planet: %d", &beep_lite_cycle_time_planet, + 0, 0, 0, NULL, &beeplite_planet_range}, +#endif + {"done", ¬done, 0, 0, 0, NULL, NULL}, + {NULL, 0, 0, 0, 0, NULL, NULL, /**/ -1} +}; + +struct option Playerdash_Menu[] = +{ + {"Playerlist/Dashboard Menu", &MenuPage, 0, 0, 0, NULL, &Menus_Range}, + {"Page %d (click here to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range}, + {"sort playerlist", &sortPlayers, 0, 0, 0, NULL, NULL}, + {"show dead players in playerlist", &showDead, 0, 0, 0, NULL, NULL}, + {"show players as they log in", &showPreLogins, 0, 0, 0, NULL, NULL}, + {"hide 0.00 kills in playerlist", &hideNoKills, 0, 0, 0, NULL, NULL}, + {"sort outfitting to bottom", &sortOutfitting, 0, 0, 0, NULL, NULL}, + {0, &Dashboard, 0, 0, 0, dashboardoptions, NULL}, +#ifdef TIMER + {0, &timerType, 0, 0, 0, timermes, NULL}, +#endif /* TIMER */ +#ifdef LOCAL_SHIPSTATS + {"show ship stats on local window",&localShipStats, 0, 0, 0, NULL, NULL}, + {"Local ship stats height: %d",&statHeight, 0, 0, 0, NULL, &statHeight_range}, +#endif +#ifdef PACKET_LIGHTS + {"show packet lights", &packetLights, 0, 0, 0, NULL, NULL}, +#endif + {"keep phaser statistics", &phaserStats,0,0,0,NULL, NULL}, + {"clear phaser statistics", &clearPhaserStats, 0, 0, 0, NULL, NULL}, + {"done", ¬done, 0, 0, 0, NULL, NULL}, + {NULL, 0, 0, 0, 0, NULL, NULL, /**/ -1} +}; + +#ifdef HOCKEY +struct option Hockey_Menu[] = +{ + {"Hockey Menu", &MenuPage, 0, 0, 0, NULL, &Menus_Range}, + {"Page %d (click here to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range}, + {"show tactical hockey lines", &tacticalHockeyLines, 0, 0, 0, NULL, NULL}, + {"show galactic hockey lines", &galacticHockeyLines, 0, 0, 0, NULL, NULL}, + {"show planets on the galactic", &cleanHockeyGalactic, 0, 0, 0, NULL, NULL}, + {"color hockey lines by team", &teamColorHockeyLines, 0, 0, 0, NULL, NULL}, + {"done", ¬done, 0, 0, 0, NULL, NULL}, + {NULL, 0, 0, 0, 0, NULL, NULL, /**/ -1} +}; +#endif /*HOCKEY*/ + +#if 0 +struct option Network_Menu[] = +{ + {"Network menu", &MenuPage, 0, 0, 0, NULL, &Menus_Range}, + {"Page %d (click here to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range}, + + {"done", ¬done, 0, 0, 0, NULL, NULL}, + {NULL, 0, 0, 0, 0, NULL, NULL, /**/ -1} +}; +#endif /* 0 */ + +#if 0 +{ + "show shields", &showShields, 0, 0, 0, NULL, NULL +}, +{ + "show UDP control window", 0, &udpWin, 0, 0, NULL, NULL +}, +{ + "show short packets window", 0, &spWin, 0, 0, NULL, NULL +}, +struct option SillyFeatures_Menu[] = +{ + {"Silly Features Menu", &MenuPage, 0, 0, 0, NULL, &Menus_Range}, + {"Page %d (click here to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range}, + {"alert on extra border(s)", &extraBorder, 0, 0, 0, NULL, NULL}, +#ifdef BORGTEST + {"borg torp test", &bd, 0, 0, 0, NULL, NULL}, /* BORG TEST */ +#endif + {"done", ¬done, 0, 0, 0, NULL, NULL}, + {NULL, 0, 0, 0, 0, NULL, NULL, /**/ -1} +}; +#endif /* 0 */ + +#ifdef AMIGA + +static char *autopointmess[] = { + "AutoPoint: none", + "AutoPoint: Redirect input", + "AutoPoint: Activate window on input", + "AutoPoint: Full (inefficient)", "" +}; + +static char *dooshSoundMess[] = { + "Play doosh sound when YOU kill a carrier", + "Play doosh sound when ANY carrier dies", + "" +}; + +struct int_range soundVolRange = {0, 64, 4}; +struct int_range speechVolRange = {0, 64, 4}; + +extern int speechVol; +extern int S_AddPeriod; +extern int monoBitmaps; + +struct option Amiga_Menu[] = { + {"Amiga Features Menu", &MenuPage, 0, 0, 0, NULL, &Menus_Range}, + {"Page %d (click to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range}, + {0, &autoPoint, 0, 0, 0, autopointmess, NULL}, + {"do keyboard window depth", &W_KeyDepth, 0, 0, 0, NULL, NULL}, + {"use AnimPointers", &animPointers, 0, 0, 0, NULL, NULL}, + {"use one color bitmaps", &monoBitmaps, 0, 0, 0, NULL, NULL}, + {"use Workbench screen", &useWorkbench, 0, 0, 0, NULL, NULL}, + {"speak messages to \"all\"", &S_SpeakAll, 0, 0, 0, NULL, NULL}, + {"speak messages to you", &S_SpeakYour, 0, 0, 0, NULL, NULL}, + {"speak messages to team", &S_SpeakTeam, 0, 0, 0, NULL, NULL}, + {"speak \"kill\" messages", &S_SpeakKill, 0, 0, 0, NULL, NULL}, + {"speak messages from God", &S_SpeakGod, 0, 0, 0, NULL, NULL}, + {"speak messages from YOU", &S_SpeakSelf, 0, 0, 0, NULL, NULL}, + {"speak login/out messages", &S_SpeakLogins, 0, 0, 0, NULL, NULL}, + {"ignore repeated messages", &S_IgnoreMultiple, 0, 0, 0, 0, 0}, + {"add a period to the end of messages", &S_AddPeriod, 0, 0, 0, 0, 0}, + {"Speech volume: %d", &speechVol, 0, 0, 0, NULL, &speechVolRange}, +#ifdef SOUND + {"play digitized sounds", &soundOn, 0, 0, 0, NULL, NULL}, + {"Sound volume: %d", &soundVol, 0, 0, 0, NULL, &soundVolRange}, + {"show sounds window", 0, &soundWin, 0, 0, NULL, NULL}, + {0, &alwaysSoundDoosh, 0, 0, 0, dooshSoundMess, 0}, +#endif + {"done", ¬done, 0, 0, 0, NULL, NULL}, + {NULL, 0, 0, 0, 0, NULL, NULL, /**/ -1} +}; + +#endif /* AMIGA */ + +#define NUMOPTIONS(menu) ((sizeof((menu))/sizeof((menu)[0]))-1) + + +/* option menu sizes and such */ +#define OPTIONBORDER 2 +#define OPTIONLEN 40 + +static void RefreshOptions P((void)); +static void SetMenuPage P((int pagenum)); +static int InitOptionMenus P((void)); +static void AddOptMenu P((struct option NewMenu[], int updated)); +static int NumOptions P((struct option OpMenu[])); +/*static void UpdateOptions P((void));*/ +void optionrefresh P((register struct option * op)); + + +/* Set up the option menus and window. */ +void +optionwindow() +{ + /* Init not done flag */ + notdone = 1; + + old_ping = ping; + old_rotate = rotate; + old_rotate_deg = rotate_deg; + + *newkeys = '\0'; + *newckeys = '\0'; + *newbuttons = '\0'; + *newcbuttons = '\0'; + if (FirstMenu == NULL) { + if (!paradise) { /* remove the extra planet settings */ + localmes[3] = ""; + galacticmes[3] = ""; + } + MaxOptions = InitOptionMenus(); + if (MaxOptions < 0) { + fprintf(stderr, "InitOptionMenus() error %d!\n", MaxOptions); + notdone = 0; + return; + } + } + /* Create window big enough to hold option windows */ + if (optionWin == NULL) { + + optionWin = W_MakeMenu("option", WINSIDE + 10, -BORDER + 10, OPTIONLEN, + MaxOptions, baseWin, OPTIONBORDER); + CurrentMenu = FirstMenu; + + RefreshOptions(); + } + W_ResizeMenu(optionWin, OPTIONLEN, CurrentMenu->numopt); + /* Map window */ + W_MapWindow(optionWin); +} + +/* refresh all current options */ +static void +RefreshOptions() +{ + int i; + struct option_menu *option; + + if (notdone == 0 || (option = CurrentMenu) == NULL) + return; + + for (i = 0; i < option->numopt; i++) { + optionrefresh(&(option->menu[i])); + } +#ifdef nodef /* if we resize, we don't need this */ + if (option->numopt < MaxOptions) + for (i = option->numopt; i < MaxOptions; i++) { + OptionClear(i); + } +#endif +} + +#ifdef nodef +/* blank out option line 'i' */ +static void +OptionClear(i) +{ + char *blanktext = " "; + if (optionWin && notdone) + W_WriteText(optionWin, 0, i, textColor, blanktext, OPTIONLEN, 0); +} +#endif + +/* Redraw the specified option entry */ +void +optionredrawtarget(win) + W_Window win; +{ + register struct option *op; + +#ifdef nodef + if (notdone == 0) + return; +#endif + + for (op = CurrentMenu->menu; op->op_text; op++) { + if (op->op_targetwin && win == *op->op_targetwin) { + optionrefresh(op); + break; + } + } +} + +/* Redraw the specified option option */ +void +optionredrawoption(ip) + int *ip; +{ + register struct option *op; + +#ifdef nodef + if (notdone == 0) + return; +#endif + + for (op = CurrentMenu->menu; op->op_num >= 0; op++) { + if (ip == op->op_option) { + optionrefresh(op); + break; + } + } +} + +/* Refresh the option window given by the option struct */ +void +optionrefresh(op) + register struct option *op; +{ + register int on; + char buf[BUFSIZ]; + + if (op == NULL || notdone == 0) + return; + + if (op->op_string) { + (void) sprintf(buf, op->op_text, op->op_string); + } else if (op->op_array) { /* Array of strings */ + strcpy(buf, op->op_array[*op->op_option]); + } else if (op->op_range) { + (void) sprintf(buf, op->op_text, *(op->op_option)); + } else { + /* Either a boolean or a window */ + if (op->op_option) + on = *op->op_option;/* use int for status */ + else if (op->op_targetwin) + on = W_IsMapped(*op->op_targetwin); /* use window for status */ + else + on = 1; /* shouldn't happen */ + + if (!on) + strcpy(buf, "Don't "); + else + buf[0] = '\0'; + strcat(buf, op->op_text); + } + + if (islower(buf[0])) + buf[0] = toupper(buf[0]); + + if (op->op_num == 0) { /* title */ + W_WriteText(optionWin, 0, op->op_num, W_Yellow, buf, strlen(buf), 0); + } else if (op->op_num == 1) { /* "click" entry */ + W_WriteText(optionWin, 0, op->op_num, W_Green, buf, strlen(buf), 0); + } else + W_WriteText(optionWin, 0, op->op_num, textColor, buf, strlen(buf), 0); +} + +/* deal with events sent to the option window */ +int +optionaction(data) + W_Event *data; +{ + register struct option *op; + int i; + register char *cp; + + if (data->y >= CurrentMenu->numopt) { + W_Beep(); + return (0); + } + if (notdone == 0) + return (0); + + op = &(CurrentMenu->menu[data->y]); + + /* Update string; don't claim keystrokes for non-string options */ + /* deal with options with string input first */ + if (op->op_string == 0) { + if (data->type == W_EV_KEY) + return (0); + } else { + if (data->type == W_EV_BUTTON) + return (0); + switch (data->key) { + + case '\b': /* delete character */ + case '\177': + cp = op->op_string; + i = strlen(cp); + if (i > 0) { + cp += i - 1; + *cp = '\0'; + } + break; + + case '\027': /* word erase */ + cp = op->op_string; + i = strlen(cp); + /* back up over blanks */ + while (--i >= 0 && isspace(cp[i])); + i++; + /* back up over non-blanks */ + while (--i >= 0 && !isspace(cp[i])); + i++; + cp[i] = '\0'; + break; + + case '\025': /* kill line */ + case '\030': + op->op_string[0] = '\0'; + break; + + default: /* add character to the list */ + if (data->key < 32 || data->key > 127) + break; + cp = op->op_string; + i = strlen(cp); + if (i < (op->op_size - 1) && !iscntrl(data->key)) { + cp += i; + cp[1] = '\0'; + cp[0] = data->key; + } else + W_Beep(); + break; + } + } + + /* Toggle int, if it exists */ + if (op->op_array) { + if (data->key == W_LBUTTON) { + (*op->op_option)++; + if (*(op->op_array)[*op->op_option] == '\0') { + *op->op_option = 0; + } + } else if (data->key == W_MBUTTON) { + /* set option number to zero on the middle key to ease shutoff */ + *op->op_option = 0; + } else if (data->key == W_RBUTTON) { + /* if right button, decrease option */ + (*op->op_option)--; + /* if decreased too far, set to top option */ + if (*(op->op_option) < 0) { + *op->op_option = 0; + while (*(op->op_array)[*op->op_option] != '\0') { + (*op->op_option)++; + } + (*op->op_option)--; + } + } + if(op->op_option == &showgalactic) + redrawall=1; + } else if (op->op_range) { + if (data->key == W_RBUTTON) { + if (op->op_range->increment == -1) /* bitwise shifts by 1 */ + if (*op->op_option == 0) + (*op->op_option) = op->op_range->max_value; + else + (*op->op_option) = (*op->op_option) >> 1; + else + (*op->op_option) -= op->op_range->increment; + } else if (data->key == W_MBUTTON) { + (*op->op_option) = op->op_range->min_value; + } else if (data->key == W_LBUTTON) { + if (op->op_range->increment == -1) + if (*op->op_option == 0) + (*op->op_option) = 1; + else + (*op->op_option) = (*op->op_option) << 1; + else + (*op->op_option) += op->op_range->increment; + } + /* wrap value around within option range */ + if (*(op->op_option) > op->op_range->max_value) + *(op->op_option) = op->op_range->min_value; + if (*(op->op_option) < op->op_range->min_value) + *(op->op_option) = op->op_range->max_value; + } else if (op->op_option) { + *op->op_option = !*op->op_option; + if(op->op_option == &blk_zoom) { + if(!paradise) { + blk_zoom=0; + } else { + redrawall=1; + } + } else if((op->op_option == &blk_showStars) && !paradise) + blk_showStars = 0; + else if((op->op_option == &drawgrid) || + (op->op_option == §orNums)) + redrawall=1; + else if(op->op_option == &clearPhaserStats) { + phasFired=phasHits=totalDmg=0; + clearPhaserStats=1; + warning("Phaser statistics reset!"); + } else if(op->op_option == &reloadShipBitmaps) { + free_shipshapes(); + slurp_ship_bitmaps(); + reloadShipBitmaps = 1; + warning("Read ship bitmaps"); + } +#ifdef AMIGA + else if(op->op_option == &useWorkbench) { + switchScreen(); + } +#endif + } + /* Map/unmap window, if it exists */ + if (op->op_targetwin) { + if (W_IsMapped(*op->op_targetwin)) { + if (*op->op_targetwin == udpWin) + udpdone(); + else if (*op->op_targetwin == spWin) + spdone(); + else + W_UnmapWindow(*op->op_targetwin); + } else { + if (*op->op_targetwin == udpWin) + udpwindow(); + else if (*op->op_targetwin == spWin) + spwindow(); +#ifdef SOUND + else if (*op->op_targetwin == soundWin) + S_SoundWindow(); +#endif + else + W_MapWindow(*op->op_targetwin); + if (*op->op_targetwin == pStats) + redrawPStats(); +#ifdef XTREKRC_HELP + if (*op->op_targetwin == defWin) + showdef(); +#endif + } + } + /* deal with possible menu change */ + if (MenuPage != CurrentMenu->page_num) { + SetMenuPage(MenuPage); + RefreshOptions(); + } + if (!notdone) /* if done, that is */ + optiondone(); + else + optionrefresh(op); + + + return (1); +} + +/* + * find the menu in the menus linked list that matches the one in the * + * argument + */ +static void +SetMenuPage(pagenum) + int pagenum; +{ + int i = 1; + if (FirstMenu != NULL) + for (CurrentMenu = FirstMenu; CurrentMenu->Next != NULL && + CurrentMenu->page_num != pagenum; i++, CurrentMenu = CurrentMenu->Next); + W_ResizeMenu(optionWin, OPTIONLEN, CurrentMenu->numopt); +} + +void +optiondone() +{ + int shpn; + struct ship *shp; + + /* Unmap window */ + W_UnmapWindow(optionWin); + + if(remapAllShips) { + for(shpn=0;shpn<nshiptypes;shpn++) { + shp=getship(shpn); + keymapAdd(newkeys, shp->s_keymap); + ckeymapAdd(newckeys, shp->s_keymap); + buttonmapAdd(newbuttons, shp->s_buttonmap); + cbuttonmapAdd(newcbuttons, shp->s_buttonmap); + } + } else { /* only affect current ship */ + /* update keymap and buttonmap [Bdyess] */ + keymapAdd(newkeys, myship->s_keymap); + ckeymapAdd(newckeys, myship->s_keymap); + buttonmapAdd(newbuttons, myship->s_buttonmap); + cbuttonmapAdd(newcbuttons, myship->s_buttonmap); + } + + /* optionrefresh(&(option[KEYMAP])); Not sure why this is really needed */ + + sendOptionsPacket(); /* update server as to the client's options */ + + if (updateSpeed != lastUpdateSpeed) { + sendUpdatePacket(1000000 / updateSpeed); + lastUpdateSpeed = updateSpeed; + } + if (oldzoom != blk_zoom) { + redrawall = 1; + oldzoom = blk_zoom; + } + if (ping != old_ping) { + old_ping = ping; + if (ping) + startPing(); + else + stopPing(); + } +#ifdef BEEPLITE + if (DefLite) + litedefaults(); +#endif + +#ifdef ROTATERACE + if (rotate != old_rotate) { + + rotate_all(); +#if 0 + register i; + register struct planet *l; + int nplan = (paradise) ? nplanets : 40; + + redrawall = 1; + reinitPlanets = 1; + + for (i = 0, l = planets; i < nplan; i++, l++) { + if (rotate) { + rotate_deg = -old_rotate_deg + rotate * 64; + rotate_coord(&l->pl_x, &l->pl_y, rotate_deg, + blk_gwidth / 2, blk_gwidth / 2); + rotate_deg = rotate * 64; + } else { + rotate_deg = -old_rotate_deg; + rotate_coord(&l->pl_x, &l->pl_y, rotate_deg, + blk_gwidth / 2, blk_gwidth / 2); + rotate_deg = 0; + } + } +#endif + old_rotate = rotate; + old_rotate_deg = rotate_deg; + + } +#endif +} + +/* set up menus linked list */ +static int +InitOptionMenus() +{ + int i = 1; + int maxopts = 0; + + IFDEBUG(printf("Adding OptionMenus\n"); + ) + /* AddOptMenu( &OptionsMenu, 0); */ + AddOptMenu(Features_Menu, 0); + AddOptMenu(Window_Menu, 0); + AddOptMenu(Display_Menu, 0); + AddOptMenu(Playerdash_Menu, 0); +#ifdef HOCKEY + AddOptMenu(Hockey_Menu, 0); +#endif /*HOCKEY*/ +#ifdef AMIGA + AddOptMenu(Amiga_Menu, 0); +#endif + /* AddOptMenu(SillyFeatures_Menu, 0); */ + /* AddOptMenu(Network_Menu, 0); */ + + for (i = 1, CurrentMenu = FirstMenu; CurrentMenu != NULL; + i++, CurrentMenu = CurrentMenu->Next) { + CurrentMenu->page_num = i; /* repage the menus.. */ + if (CurrentMenu->numopt > maxopts) + maxopts = CurrentMenu->numopt; + } + CurrentMenu = FirstMenu; + Menus_Range.max_value = i - 1; + IFDEBUG(printf("OptionMenus Added! Maxopt = %d \n", i); + ) + return maxopts; +} + +static void +AddOptMenu(NewMenu, updated) + struct option NewMenu[]; + int updated; +{ + struct option_menu *menuptr; + struct option_menu *newmenu; + int i = 0; + + IFDEBUG(printf("AddOptMenu\n"); + ) + menuptr = FirstMenu; + + newmenu = (struct option_menu *) malloc(sizeof(struct option_menu)); + if (newmenu == NULL) { + perror("Malloc Error adding a menu"); + return; + } + /* add to list */ + if (FirstMenu == NULL) { + FirstMenu = newmenu; + } else { + for (i = 0, menuptr = FirstMenu; menuptr->Next != NULL; menuptr = menuptr->Next) + i++; + menuptr->Next = newmenu; + } + newmenu->page_num = i; + newmenu->Next = NULL; + newmenu->numopt = NumOptions(NewMenu); + newmenu->menu = NewMenu; + newmenu->updated = updated; + IFDEBUG(printf("Menu Added! \n", i); + ) +} + +static int +NumOptions(OpMenu) + struct option OpMenu[]; +{ + int i = 0; + struct option *ptr; + + ptr = &OpMenu[0]; + for (i = 0; ptr->op_num != -1 && ptr->op_option != ¬done; i++) { + IFDEBUG(printf("Option #%d..\n", i); + ) + IFDEBUG(if (ptr->op_text != NULL) printf("OP_Text:%s\n", ptr->op_text); + ) + ptr = &OpMenu[i]; + ptr->op_num = i; + } + + IFDEBUG(printf("NumOptions in this menu: %d\n", i); + ) + return i; +} + +/* + * a function that could be called regularly, to deal with menus that * might + * be updated by external events. I.e. the udp menu! + */ +#if 0 +static void +UpdateOptions() +{ + if (notdone == 0) + return; /* don't update if menu isn't in use */ + if (CurrentMenu->updated) + RefreshOptions(); +} +#endif /* 0 */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/packets.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,321 @@ +/* $Id: packets.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +#include <stddef.h> + +#include "defs.h" +#include "packets.h" +#include "gppackets.h" +#include "wtext.h" + +size_t client_packet_sizes[] = { + 0, + sizeof(struct mesg_cpacket), + sizeof(struct speed_cpacket), + sizeof(struct dir_cpacket), + sizeof(struct phaser_cpacket), + sizeof(struct plasma_cpacket), + sizeof(struct torp_cpacket), + sizeof(struct quit_cpacket), + sizeof(struct login_cpacket), + sizeof(struct outfit_cpacket), + /* 10 v */ + sizeof(struct war_cpacket), + sizeof(struct practr_cpacket), + sizeof(struct shield_cpacket), + sizeof(struct repair_cpacket), + sizeof(struct orbit_cpacket), + sizeof(struct planlock_cpacket), + sizeof(struct playlock_cpacket), + sizeof(struct bomb_cpacket), + sizeof(struct beam_cpacket), + sizeof(struct cloak_cpacket), + /* 20 v */ + sizeof(struct det_torps_cpacket), + sizeof(struct det_mytorp_cpacket), + sizeof(struct copilot_cpacket), + sizeof(struct refit_cpacket), + sizeof(struct tractor_cpacket), + sizeof(struct repress_cpacket), + sizeof(struct coup_cpacket), + sizeof(struct socket_cpacket), + sizeof(struct options_cpacket), + sizeof(struct bye_cpacket), + /* 30 v */ + sizeof(struct dockperm_cpacket), + sizeof(struct updates_cpacket), + sizeof(struct resetstats_cpacket), + sizeof(struct reserved_cpacket), + sizeof(struct scan_cpacket), + sizeof(struct udp_req_cpacket), + sizeof(struct sequence_cpacket), + sizeof(struct rsa_key_cpacket), + sizeof(struct obvious_packet), + 0, + /* 40 v */ + 0, + 0, + sizeof(struct ping_cpacket),/* 42 */ +#ifdef SHORT_PACKETS + sizeof(struct shortreq_cpacket), + sizeof(struct threshold_cpacket), + 0, /* CP_S_MESSAGE */ + 0, /* CP_S_RESERVED */ + 0, /* CP_S_DUMMY */ +#else + 0, + 0, + 0, + 0, + 0, /* 47 */ +#endif + 0, /* 48 */ + 0, + /* 50 v */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* 59 */ +#ifdef FEATURE + sizeof(struct feature_cpacket) /* CP_FEATURE */ +#else + 0 +#endif +}; + +#define num_cpacket_sizes sizeof(client_packet_sizes)/sizeof(*client_packet_sizes) + +int +size_of_cpacket(pkt) + void *pkt; +{ + CARD8 type; + CARD8 subtype; + + type = ((CARD8 *) pkt)[0]; + subtype = ((CARD8 *) pkt)[1]; + + if (type < num_cpacket_sizes && client_packet_sizes[type] > 0) + return client_packet_sizes[type]; + + switch (type) { +#ifdef CP_FIRE_WEAPON + case CP_FIRE_WEAPON: + { + struct fire_weapon_cpacket *fwp = pkt; + return (fwp->mech == TM_POSITION) ? 12 : 4; + } +#endif + +#ifdef SHORT_PACKETS + case CP_S_MESSAGE: + return ((unsigned char *) pkt)[3]; + case CP_S_RESERVED: + case CP_S_DUMMY: + /* hmm? good question */ + return 0; +#endif /* SHORT_PACKETS */ + + default: + return 0; + } +} + + +int server_packet_sizes[] = { + 0, /* record 0 */ + sizeof(struct mesg_spacket),/* SP_MESSAGE */ + sizeof(struct plyr_info_spacket), /* SP_PLAYER_INFO */ + sizeof(struct kills_spacket), /* SP_KILLS */ + sizeof(struct player_spacket), /* SP_PLAYER */ + sizeof(struct torp_info_spacket), /* SP_TORP_INFO */ + sizeof(struct torp_spacket),/* SP_TORP */ + sizeof(struct phaser_spacket), /* SP_PHASER */ + sizeof(struct plasma_info_spacket), /* SP_PLASMA_INFO */ + sizeof(struct plasma_spacket), /* SP_PLASMA */ + /* 10 v */ + sizeof(struct warning_spacket), /* SP_WARNING */ + sizeof(struct motd_spacket),/* SP_MOTD */ + sizeof(struct you_spacket), /* SP_YOU */ + sizeof(struct queue_spacket), /* SP_QUEUE */ + sizeof(struct status_spacket), /* SP_STATUS */ + sizeof(struct planet_spacket), /* SP_PLANET */ + sizeof(struct pickok_spacket), /* SP_PICKOK */ + sizeof(struct login_spacket), /* SP_LOGIN */ + sizeof(struct flags_spacket), /* SP_FLAGS */ + sizeof(struct mask_spacket),/* SP_MASK */ + /* 20 v */ + sizeof(struct pstatus_spacket), /* SP_PSTATUS */ + sizeof(struct badversion_spacket), /* SP_BADVERSION */ + sizeof(struct hostile_spacket), /* SP_HOSTILE */ + sizeof(struct stats_spacket), /* SP_STATS */ + sizeof(struct plyr_login_spacket), /* SP_PL_LOGIN */ + sizeof(struct reserved_spacket), /* SP_RESERVED */ + sizeof(struct planet_loc_spacket), /* SP_PLANET_LOC */ + sizeof(struct scan_spacket),/* SP_SCAN (ATM) */ + sizeof(struct udp_reply_spacket), /* SP_UDP_REPLY */ + sizeof(struct sequence_spacket), /* SP_SEQUENCE */ + /* 30 v */ + sizeof(struct sc_sequence_spacket), /* SP_SC_SEQUENCE */ + sizeof(struct rsa_key_spacket), /* SP_RSA_KEY */ + sizeof(struct motd_pic_spacket), /* SP_MOTD_PIC */ + sizeof(struct stats_spacket2), /* SP_STATS2 */ + sizeof(struct status_spacket2), /* SP_STATUS2 */ + sizeof(struct planet_spacket2), /* SP_PLANET2 */ + sizeof(struct obvious_packet), /* SP_NEW_MOTD */ + sizeof(struct thingy_spacket), /* SP_THINGY */ + sizeof(struct thingy_info_spacket), /* SP_THINGY_INFO */ + sizeof(struct ship_cap_spacket), /* SP_SHIP_CAP */ + /* 40 v */ +#ifdef SHORT_PACKETS + sizeof(struct shortreply_spacket), /* SP_S_REPLY */ + -1, /* SP_S_MESSAGE */ + -1, /* SP_S_WARNING */ + sizeof(struct youshort_spacket), /* SP_S_YOU */ + sizeof(struct youss_spacket), /* SP_S_YOU_SS */ + -1, /* SP_S_PLAYER */ +#else + -1, + -1, + -1, + -1, + -1, + -1, +#endif + sizeof(struct ping_spacket),/* SP_PING */ + -1, /* SP_S_TORP */ + -1, /* SP_S_TORP_INFO */ + 20, /* SP_S_8_TORP */ + /* 50 v */ + -1, /* SP_S_PLANET */ + -1, /* SP_GPARAM */ + -1, /* SP_PARADISE_EXT1 */ + sizeof(struct terrain_packet2), /* SP_TERRAIN2 */ + sizeof(struct terrain_info_packet2), /* SP_TERRAIN_INFO2 */ + -1, + -1, + -1, + -1, + -1, + /* 60 v */ +#ifdef FEATURE + sizeof(struct feature_spacket), +#else + -1, +#endif + -1 +}; + +#define num_spacket_sizes (sizeof(server_packet_sizes) / sizeof(server_packet_sizes[0]) - 1) + +#ifdef SHORT_PACKETS +unsigned char numofbits[256] = +{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, + 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, + 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, + 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, + 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, + 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, + 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, + 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, + 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, + 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, + 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, + 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, + 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, + 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, + 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, +5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8}; + +static int vtsize[9] = +{4, 8, 8, 12, 12, 16, 20, 20, 24}; /* How big is the torppacket */ +int vtisize[9] = +{4, 7, 9, 11, 13, 16, 18, 20, 22}; /* 4 byte Header + torpdata */ + + +static int +padto4(sz) + int sz; +{ + return (sz % 4) ? (sz / 4 + 1) * 4 : sz; + +} +#endif + +int +size_of_spacket(pkt) + unsigned char *pkt; +{ + switch (pkt[0]) { + case SP_GPARAM: + switch (pkt[1]) { + case 0: + return sizeof(struct gp_sizes_spacket); + case 1: + return sizeof(struct gp_team_spacket); + case 2: + return sizeof(struct gp_teamlogo_spacket); + case 3: + return sizeof(struct gp_shipshape_spacket); + case 4: + return sizeof(struct gp_shipbitmap_spacket); + case 5: + return sizeof(struct gp_rank_spacket); + case 6: + return sizeof(struct gp_royal_spacket); + case 7: + return sizeof(struct gp_teamplanet_spacket); + default: + return 0; + } +#ifdef SHORT_PACKETS + case SP_S_MESSAGE: + return padto4(pkt[4]); /* IMPORTANT Changed */ + case SP_S_WARNING: + if (pkt[1] == STEXTE_STRING || + pkt[1] == SHORT_WARNING) { + return padto4(pkt[3]); + } else + return 4; /* Normal Packet */ + case SP_S_PLAYER: + if (pkt[1] & 128) { /* Small +extended Header */ + return padto4(((pkt[1] & 0x3f) * 4) + 4); + } else if (pkt[1] & 64) { /* Small Header */ + return padto4(((pkt[1] & 0x3f) * 4) + 4); + } else { /* Big Header */ + return padto4((pkt[1] * 4 + 12)); + } + case SP_S_TORP: + return padto4(vtsize[numofbits[pkt[1]]]); + case SP_S_TORP_INFO: + return padto4((vtisize[numofbits[pkt[1]]] + numofbits[pkt[3]])); + case SP_S_PLANET: + return padto4((pkt[1] * VPLANET_SIZE) + 2); +#endif + case SP_PARADISE_EXT1: + switch (pkt[1]) { + case SP_PE1_MISSING_BITMAP: + return sizeof(struct pe1_missing_bitmap_spacket); + case SP_PE1_NUM_MISSILES: + return sizeof(struct pe1_num_missiles_spacket); + default: + return 0; + } +#ifdef RECORDER + case REC_UPDATE: + { + extern int playback; + if (playback) /* if not, something's very wrong... */ + return 4; + } +#endif + default: + return (*pkt < num_spacket_sizes && server_packet_sizes[*pkt] >= 0) + ? server_packet_sizes[*pkt] : 0; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/packets.h Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,1115 @@ +/* $Id: packets.h,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +/*-------------------------------------------------------------------------- +NETREK II -- Paradise 2.1 FILE: packets.h + +Permission to use, copy, modify, and distribute this software and its +documentation for any NON-COMMERCIAL purpose (following the terms of +the GNU General Public License (read the file 'COPYING')) and without +fee is hereby granted, provided that this copyright notice appear in all +copies. No representations are made about the suitability of this +software for any purpose. This software is provided "as is" without +express or implied warranty. + + Xtrek Copyright 1986 Chris Guthrie + Netrek (Xtrek II) Copyright 1989 Kevin P. Smith + Scott Silvey + Paradise II (Netrek II) Copyright 1993 Larry Denys + Kurt Olsen + Brandon Gillespie + Paradise II by: + Larry Denys, Kurt Olsen, Brandon Gillespie, and Rob Forsman + and: + Heath Kehoe, Mike Lutz, Mike McGrath, Ted Hadley, and Mark Kolb +--------------------------------------------------------------------------*/ + +/* + * Include file for socket I/O xtrek. + * + * Kevin P. Smith 1/29/89 + */ + +#ifndef packets_h_ +#define packets_h_ + +#define STATUS_TOKEN "\t@@@" /* ATM */ + +/* the following typedefs allow portability to machines without the + ubiquitous 32-bit architecture (KSR1, Cray, DEC Alpha) */ + +typedef unsigned int CARD32; +typedef unsigned short CARD16; +typedef unsigned char CARD8; + +typedef int INT32; +typedef short INT16; +#if __STDC__ || defined(sgi) || defined(RS6K) +typedef signed char INT8; +#else +/* stupid compilers */ +typedef char INT8; +#endif + +/* + * TCP and UDP use identical packet formats; the only difference is that, + * when in UDP mode, all packets sent from server to client have a sequence + * number appended to them. + * + * (note: ALL packets, whether sent on the TCP or UDP channel, will have + * the sequence number. Thus it's important that client & server agree on + * when to switch. This was done to keep critical and non-critical data + * in sync.) + */ + +/* the various pad members of the structures are used for explicit + data alignment. They do not contain any data. All structures are + aligned to 4 bytes. If your compiler forces 8 byte alignment, you + will not be adhering to the netrek protocol. + */ + +/* packets sent from xtrek server to remote client */ +#define SP_MESSAGE 1 +#define SP_PLAYER_INFO 2 /* general player info not elsewhere */ +#define SP_KILLS 3 /* # kills a player has */ +#define SP_PLAYER 4 /* x,y for player */ +#define SP_TORP_INFO 5 /* torp status */ +#define SP_TORP 6 /* torp location */ +#define SP_PHASER 7 /* phaser status and direction */ +#define SP_PLASMA_INFO 8 /* player login information */ +#define SP_PLASMA 9 /* like SP_TORP */ +#define SP_WARNING 10 /* like SP_MESG */ +#define SP_MOTD 11 /* line from .motd screen */ +#define SP_YOU 12 /* info on you? */ +#define SP_QUEUE 13 /* estimated loc in queue? */ +#define SP_STATUS 14 /* galaxy status numbers */ +#define SP_PLANET 15 /* planet armies & facilities */ +#define SP_PICKOK 16 /* your team & ship was accepted */ +#define SP_LOGIN 17 /* login response */ +#define SP_FLAGS 18 /* give flags for a player */ +#define SP_MASK 19 /* tournament mode mask */ +#define SP_PSTATUS 20 /* give status for a player */ +#define SP_BADVERSION 21 /* invalid version number */ +#define SP_HOSTILE 22 /* hostility settings for a player */ +#define SP_STATS 23 /* a player's statistics */ +#define SP_PL_LOGIN 24 /* new player logs in */ +#define SP_RESERVED 25 /* for future use */ +#define SP_PLANET_LOC 26 /* planet name, x, y */ + +#define SP_SCAN 27 /* scan packet */ +#define SP_UDP_REPLY 28 /* notify client of UDP status */ +#define SP_SEQUENCE 29 /* sequence # packet */ +#define SP_SC_SEQUENCE 30 /* this trans is semi-critical info */ +#define SP_RSA_KEY 31 /* RSA data packet */ + +#define SP_MOTD_PIC 32 /* motd bitmap pictures */ +#define SP_STATS2 33 /* new stats packet */ +#define SP_STATUS2 34 /* new status packet */ +#define SP_PLANET2 35 /* new planet packet */ +#define SP_NEW_MOTD 36 /* New MOTD info notification uses */ +#define SP_THINGY 37 /* thingy location */ +#define SP_THINGY_INFO 38 /* thingy status */ +#define SP_SHIP_CAP 39 /* ship capabilities */ + +#ifdef SHORT_PACKETS +#define SP_S_REPLY 40 /* reply to send-short request */ +#define SP_S_MESSAGE 41 /* var. Message Packet */ +#define SP_S_WARNING 42 /* Warnings with 4 Bytes */ +#define SP_S_YOU 43 /* hostile,armies,whydead,etc .. */ +#define SP_S_YOU_SS 44 /* your ship status */ +#define SP_S_PLAYER 45 /* variable length player packet */ +#endif + +#define SP_PING 46 /* ping packet */ + +#ifdef SHORT_PACKETS +#define SP_S_TORP 47 /* variable length torp packet */ +#define SP_S_TORP_INFO 48 /* SP_S_TORP with TorpInfo */ +#define SP_S_8_TORP 49 /* optimized SP_S_TORP */ +#define SP_S_PLANET 50 /* see SP_PLANET */ + +/* variable length packets */ +#define VPLAYER_SIZE 4 +#define SHORTVERSION 10 /* other number blocks, like UDP Version */ +#endif + +#define SP_GPARAM 51 /* game params packet */ + +/* the following is a family of packets with the same type, but a + discriminating subtype */ +#define SP_PARADISE_EXT1 52 +#define SP_PE1_MISSING_BITMAP 0 +#define SP_PE1_NUM_MISSILES 1 +/* end of packet 52 subtypes */ +#define SP_TERRAIN2 53 /* Terrain packets */ +#define SP_TERRAIN_INFO2 54 /* Terrain info */ + +#ifdef FEATURE +/* feature_spacket, response to feature_cpacket requests. identical structures */ +#define SP_FEATURE 60 +#endif + +#ifdef RECORDER +/* special type tells us when to update the display on playback. + Not sent or received, only placed in the recorder file */ +#define REC_UPDATE 127 +#endif + +/* packets sent from remote client to xtrek server */ +#define CP_MESSAGE 1 /* send a message */ +#define CP_SPEED 2 /* set speed */ +#define CP_DIRECTION 3 /* change direction */ +#define CP_PHASER 4 /* phaser in a direction */ +#define CP_PLASMA 5 /* plasma (in a direction) */ +#define CP_TORP 6 /* fire torp in a direction */ +#define CP_QUIT 7 /* self destruct */ +#define CP_LOGIN 8 /* log in (name, password) */ +#define CP_OUTFIT 9 /* outfit to new ship */ +#define CP_WAR 10 /* change war status */ +#define CP_PRACTR 11 /* create practice robot? */ +#define CP_SHIELD 12 /* raise/lower sheilds */ +#define CP_REPAIR 13 /* enter repair mode */ +#define CP_ORBIT 14 /* orbit planet/starbase */ +#define CP_PLANLOCK 15 /* lock on planet */ +#define CP_PLAYLOCK 16 /* lock on player */ +#define CP_BOMB 17 /* bomb a planet */ +#define CP_BEAM 18 /* beam armies up/down */ +#define CP_CLOAK 19 /* cloak on/off */ +#define CP_DET_TORPS 20 /* detonate enemy torps */ +#define CP_DET_MYTORP 21 /* detonate one of my torps */ +#define CP_COPILOT 22 /* toggle copilot mode */ +#define CP_REFIT 23 /* refit to different ship type */ +#define CP_TRACTOR 24 /* tractor on/off */ +#define CP_REPRESS 25 /* pressor on/off */ +#define CP_COUP 26 /* coup home planet */ +#define CP_SOCKET 27 /* new socket for reconnection */ +#define CP_OPTIONS 28 /* send my options to be saved */ +#define CP_BYE 29 /* I'm done! */ +#define CP_DOCKPERM 30 /* set docking permissions */ +#define CP_UPDATES 31 /* set number of usecs per update */ +#define CP_RESETSTATS 32 /* reset my stats packet */ +#define CP_RESERVED 33 /* for future use */ + +#define CP_SCAN 34 /* ATM: request for player scan */ + +#define CP_UDP_REQ 35 /* request UDP on/off */ +#define CP_SEQUENCE 36 /* sequence # packet */ +#define CP_RSA_KEY 37 /* request MOTD */ +#define CP_ASK_MOTD 38 /* request MOTD */ + +#define CP_PING_RESPONSE 42 /* client response */ + +#ifdef SHORT_PACKETS +#define CP_S_REQ 43 +#define CP_S_THRS 44 +#define CP_S_MESSAGE 45 /* vari. Message Packet */ +#define CP_S_RESERVED 46 +#define CP_S_DUMMY 47 +#endif + +#ifdef FEATURE +#define CP_FEATURE 60 +#endif + +#define SOCKVERSION 4 +#define UDPVERSION 10 /* changing this blocks other */ + /* versions */ + +struct packet_handler { + void (*handler) (); +}; + + +/* + * These are server --> client packets + */ + +struct mesg_spacket { + INT8 type; /* SP_MESSAGE */ + CARD8 m_flags; + CARD8 m_recpt; + CARD8 m_from; + char mesg[80]; +}; + +struct plyr_info_spacket { + INT8 type; /* SP_PLAYER_INFO */ + INT8 pnum; + INT8 shiptype; + INT8 team; +}; + +struct kills_spacket { + INT8 type; /* SP_KILLS */ + INT8 pnum; + INT8 pad1; + INT8 pad2; + CARD32 kills; /* where 1234=12.34 kills and 0=0.00 kills */ +}; + +struct player_spacket { + INT8 type; /* SP_PLAYER */ + INT8 pnum; + CARD8 dir; + INT8 speed; + INT32 x, y; +}; + +struct torp_info_spacket { + INT8 type; /* SP_TORP_INFO */ + INT8 war; + INT8 status; /* TFREE, TDET, etc... */ + INT8 pad1; /* pad needed for cross cpu compatibility */ + INT16 tnum; + INT16 pad2; +}; + +struct torp_spacket { + INT8 type; /* SP_TORP */ + CARD8 dir; + INT16 tnum; + INT32 x, y; +}; + +/* Shapes of thingys. It would be best to add to the end of this list and + try to coordinate your additions with other hackers. */ +enum thingy_types { + SHP_BLANK, SHP_MISSILE, SHP_BOOM, SHP_TORP, SHP_PLASMA, SHP_MINE, + SHP_PBOOM, SHP_FIGHTER, SHP_WARP_BEACON +}; + +struct thingy_info_spacket { + INT8 type; /* SP_THINGY_INFO */ + INT8 war; + INT16 shape; /* a thingy_types */ + INT16 tnum; + INT16 owner; +}; + +struct thingy_spacket { + INT8 type; /* SP_THINGY */ + CARD8 dir; + INT16 tnum; + INT32 x, y; +}; + +struct phaser_spacket { + INT8 type; /* SP_PHASER */ + INT8 pnum; + INT8 status; /* PH_HIT, etc... */ + CARD8 dir; + INT32 x, y; + INT32 target; +}; + +struct plasma_info_spacket { + INT8 type; /* SP_PLASMA_INFO */ + INT8 war; + INT8 status; /* TFREE, TDET, etc... */ + INT8 pad1; /* pad needed for cross cpu compatibility */ + INT16 pnum; + INT16 pad2; +}; + +struct plasma_spacket { + INT8 type; /* SP_PLASMA */ + INT8 pad1; + INT16 pnum; + INT32 x, y; +}; + +struct warning_spacket { + INT8 type; /* SP_WARNING */ + INT8 pad1; + INT8 pad2; + INT8 pad3; + char mesg[80]; +}; + +struct motd_spacket { + INT8 type; /* SP_MOTD */ + INT8 pad1; + INT8 pad2; + INT8 pad3; + char line[80]; +}; + +struct you_spacket { + INT8 type; /* SP_YOU */ + INT8 pnum; /* Guy needs to know this... */ + INT8 hostile; + INT8 swar; + INT8 armies; + INT8 tractor; /* ATM - visible tractor (was pad1) */ + CARD8 pad2; + CARD8 pad3; + CARD32 flags; + INT32 damage; + INT32 shield; + INT32 fuel; + INT16 etemp; + INT16 wtemp; + INT16 whydead; + INT16 whodead; +}; + +struct queue_spacket { + INT8 type; /* SP_QUEUE */ + INT8 pad1; + INT16 pos; +}; + +struct status_spacket { + INT8 type; /* SP_STATUS */ + INT8 tourn; + INT8 pad1; + INT8 pad2; + CARD32 armsbomb; + CARD32 planets; + CARD32 kills; + CARD32 losses; + CARD32 time; + CARD32 timeprod; +}; + +struct planet_spacket { + INT8 type; /* SP_PLANET */ + INT8 pnum; + INT8 owner; + INT8 info; + INT16 flags; + INT16 pad2; + INT32 armies; +}; + +/* terrain info for Paradise terrain */ +/* 5/16/95 rpg */ + +struct terrain_info_packet2 { + CARD8 type; /* SP_TERRAIN_INFO2 */ + CARD8 pad; + CARD16 pad2; + CARD16 xdim; + CARD16 ydim; +}; + +struct terrain_packet2 { + CARD8 type; /* SP_TERRAIN2 */ + CARD8 sequence; + CARD8 total_pkts; + CARD8 length; + CARD8 terrain_type[128]; /* Ugh... this needs to be fixed 5/16/95 rpg */ + /* CARD16 terrain_alt1[128]; */ + /* CARD16 terrain_alt2[128]; */ +}; + +struct pickok_spacket { + INT8 type; /* SP_PICKOK */ + INT8 state; + INT8 pad2; + INT8 pad3; +}; + +struct login_spacket { + INT8 type; /* SP_LOGIN */ + INT8 accept; /* 1/0 */ + INT8 pad2; + INT8 pad3; + INT32 flags; + char keymap[96]; +}; + +struct flags_spacket { + INT8 type; /* SP_FLAGS */ + INT8 pnum; /* whose flags are they? */ + INT8 tractor; /* ATM - visible tractors */ + INT8 pad2; + CARD32 flags; +}; + +struct mask_spacket { + INT8 type; /* SP_MASK */ + INT8 mask; + INT8 pad1; + INT8 pad2; +}; + +struct pstatus_spacket { + INT8 type; /* SP_PSTATUS */ + INT8 pnum; + INT8 status; + INT8 pad1; +}; + +struct badversion_spacket { + INT8 type; /* SP_BADVERSION */ + INT8 why; + INT8 pad2; + INT8 pad3; +}; + +struct hostile_spacket { + INT8 type; /* SP_HOSTILE */ + INT8 pnum; + INT8 war; + INT8 hostile; +}; + +struct stats_spacket { + INT8 type; /* SP_STATS */ + INT8 pnum; + INT8 pad1; + INT8 pad2; + INT32 tkills; /* Tournament kills */ + INT32 tlosses; /* Tournament losses */ + INT32 kills; /* overall */ + INT32 losses; /* overall */ + INT32 tticks; /* ticks of tournament play time */ + INT32 tplanets; /* Tournament planets */ + INT32 tarmies; /* Tournament armies */ + INT32 sbkills; /* Starbase kills */ + INT32 sblosses; /* Starbase losses */ + INT32 armies; /* non-tourn armies */ + INT32 planets; /* non-tourn planets */ + INT32 maxkills; /* max kills as player * 100 */ + INT32 sbmaxkills; /* max kills as sb * 100 */ +}; + +struct plyr_login_spacket { + INT8 type; /* SP_PL_LOGIN */ + INT8 pnum; + INT8 rank; + INT8 pad1; + char name[16]; + char monitor[16]; + char login[16]; +}; + +struct reserved_spacket { + INT8 type; /* SP_RESERVED */ + INT8 pad1; + INT8 pad2; + INT8 pad3; + INT8 data[16]; +}; + +struct planet_loc_spacket { + INT8 type; /* SP_PLANET_LOC */ + INT8 pnum; + INT8 pad2; + INT8 pad3; + INT32 x; + INT32 y; + char name[16]; +}; + +struct scan_spacket { /* ATM */ + INT8 type; /* SP_SCAN */ + INT8 pnum; + INT8 success; + INT8 pad1; + INT32 p_fuel; + INT32 p_armies; + INT32 p_shield; + INT32 p_damage; + INT32 p_etemp; + INT32 p_wtemp; +}; + +struct udp_reply_spacket { /* UDP */ + INT8 type; /* SP_UDP_REPLY */ + INT8 reply; + INT8 pad1; + INT8 pad2; + INT32 port; +}; + +struct sequence_spacket { /* UDP */ + INT8 type; /* SP_SEQUENCE */ + INT8 pad1; + CARD16 sequence; +}; +struct sc_sequence_spacket { /* UDP */ + INT8 type; /* SP_CP_SEQUENCE */ + INT8 pad1; + CARD16 sequence; +}; + +/* + * Game configuration. + * KAO 1/23/93 + */ + +struct ship_cap_spacket { /* Server configuration of client */ + INT8 type; /* screw motd method */ + INT8 operation; /* 0 = add/change a ship, 1 = remove a ship */ + INT16 s_type; /* SP_SHIP_CAP */ + INT16 s_torpspeed; + INT16 s_phaserrange; + INT32 s_maxspeed; + INT32 s_maxfuel; + INT32 s_maxshield; + INT32 s_maxdamage; + INT32 s_maxwpntemp; + INT32 s_maxegntemp; + INT16 s_width; + INT16 s_height; + INT16 s_maxarmies; + INT8 s_letter; + INT8 pad2; + char s_name[16]; + INT8 s_desig1; + INT8 s_desig2; + INT16 s_bitmap; +}; + +struct motd_pic_spacket { + INT8 type; /* SP_MOTD_PIC */ + INT8 pad1; + INT16 x, y, page; + INT16 width, height; + INT8 bits[1016]; +}; + + + /* This is used to send paradise style stats */ +struct stats_spacket2 { + INT8 type; /* SP_STATS2 */ + INT8 pnum; + INT8 pad1; + INT8 pad2; + + INT32 genocides; /* number of genocides participated in */ + INT32 maxkills; /* max kills ever * 100 */ + INT32 di; /* destruction inflicted for all time * 100 */ + INT32 kills; /* Kills in tournament play */ + INT32 losses; /* Losses in tournament play */ + INT32 armsbomb; /* Tournament armies bombed */ + INT32 resbomb; /* resources bombed off */ + INT32 dooshes; /* armies killed while being carried */ + INT32 planets; /* Tournament planets conquered */ + INT32 tticks; /* Tournament ticks */ + /* SB/WB/JS stats are entirely separate */ + INT32 sbkills; /* Kills as starbase */ + INT32 sblosses; /* Losses as starbase */ + INT32 sbticks; /* Time as starbase */ + INT32 sbmaxkills; /* Max kills as starbase * 100 */ + INT32 wbkills; /* Kills as warbase */ + INT32 wblosses; /* Losses as warbase */ + INT32 wbticks; /* Time as warbase */ + INT32 wbmaxkills; /* Max kills as warbase * 100 */ + INT32 jsplanets; /* planets assisted with in JS */ + INT32 jsticks; /* ticks played as a JS */ + INT32 rank; /* Ranking of the player */ + INT32 royal; /* royaly, specialty, rank */ +}; + + /* status info for paradise stats */ +struct status_spacket2 { + INT8 type; /* SP_STATUS2 */ + INT8 tourn; + INT8 pad1; + INT8 pad2; + CARD32 dooshes; /* total number of armies dooshed */ + CARD32 armsbomb; /* all t-mode armies bombed */ + CARD32 resbomb; /* resources bombed */ + CARD32 planets; /* all t-mode planets taken */ + CARD32 kills; /* all t-mode kills made */ + CARD32 losses; /* all t-mode losses */ + CARD32 sbkills; /* total kills in SB's */ + CARD32 sblosses; /* total losses in Sb's */ + CARD32 sbtime; /* total time in SB's */ + CARD32 wbkills; /* kills in warbases */ + CARD32 wblosses; /* losses in warbases */ + CARD32 wbtime; /* total time played in wb's */ + CARD32 jsplanets; /* total planets taken by jump ships */ + CARD32 jstime; /* total time in a jump ship */ + CARD32 time; /* t mode time in this game */ + CARD32 timeprod; /* t-mode ship ticks--sort of like */ +}; + + + /* planet info for a paradise planet */ +struct planet_spacket2 { + INT8 type; /* SP_PLANET2 */ + INT8 pnum; /* planet number */ + INT8 owner; /* owner of the planet */ + INT8 info; /* who has touched planet */ + INT32 flags; /* planet's flags */ + INT32 timestamp; /* timestamp for info on planet */ + INT32 armies; /* armies on the planet */ +}; + +struct obvious_packet { + INT8 type; /* SP_NEW_MOTD */ + INT8 pad1; /* CP_ASK_MOTD */ +}; + +struct rsa_key_spacket { + INT8 type; /* SP_RSA_KEY */ + INT8 pad1; + INT8 pad2; + INT8 pad3; + CARD8 data[KEY_SIZE]; +}; + + +struct ping_spacket { + INT8 type; /* SP_PING */ + CARD8 number; /* id (ok to wrap) */ + CARD16 lag; /* delay of last ping in ms */ + + CARD8 tloss_sc; /* total loss server-client 0-100% */ + CARD8 tloss_cs; /* total loss client-server 0-100% */ + + CARD8 iloss_sc; /* inc. loss server-client 0-100% */ + CARD8 iloss_cs; /* inc. loss client-server 0-100% */ +}; + +struct paradiseext1_spacket { + INT8 type; + CARD8 subtype; + INT16 pad; +}; + +struct pe1_missing_bitmap_spacket { + INT8 type; + CARD8 subtype; + + INT16 page; + + INT16 x, y; + INT16 width, height; +}; + +struct pe1_num_missiles_spacket { + INT8 type; /* SP_PARADISE_EXT1 */ + CARD8 subtype; /* SP_PE1_NUM_MISSILES */ + + INT16 num; /* number of missiles */ +}; + +/* + * These are the client --> server packets + */ + +struct mesg_cpacket { + INT8 type; /* CP_MESSAGE */ + INT8 group; + INT8 indiv; + INT8 pad1; + char mesg[80]; +}; + +struct speed_cpacket { + INT8 type; /* CP_SPEED */ + INT8 speed; + INT8 pad1; + INT8 pad2; +}; + +struct dir_cpacket { + INT8 type; /* CP_DIRECTION */ + CARD8 dir; + INT8 pad1; + INT8 pad2; +}; + +struct phaser_cpacket { + INT8 type; /* CP_PHASER */ + CARD8 dir; + INT8 pad1; + INT8 pad2; +}; + +struct plasma_cpacket { + INT8 type; /* CP_PLASMA */ + CARD8 dir; + INT8 pad1; + INT8 pad2; +}; + +struct torp_cpacket { + INT8 type; /* CP_TORP */ + CARD8 dir; /* direction to fire torp */ + INT8 pad1; + INT8 pad2; +}; + +struct quit_cpacket { + INT8 type; /* CP_QUIT */ + INT8 pad1; + INT8 pad2; + INT8 pad3; +}; + +struct login_cpacket { + INT8 type; /* CP_LOGIN */ + INT8 query; + INT8 pad2; + INT8 pad3; + char name[16]; + char password[16]; + char login[16]; +}; + +struct outfit_cpacket { + INT8 type; /* CP_OUTFIT */ + INT8 team; + INT8 ship; + INT8 pad1; +}; + +struct war_cpacket { + INT8 type; /* CP_WAR */ + INT8 newmask; + INT8 pad1; + INT8 pad2; +}; + +struct practr_cpacket { + INT8 type; /* CP_PRACTR */ + INT8 pad1; + INT8 pad2; + INT8 pad3; +}; + +struct shield_cpacket { + INT8 type; /* CP_SHIELD */ + INT8 state; /* up/down */ + INT8 pad1; + INT8 pad2; +}; + +struct repair_cpacket { + INT8 type; /* CP_REPAIR */ + INT8 state; /* on/off */ + INT8 pad1; + INT8 pad2; +}; + +struct orbit_cpacket { + INT8 type; /* CP_ORBIT */ + INT8 state; /* on/off */ + INT8 pad1; + INT8 pad2; +}; + +struct planlock_cpacket { + INT8 type; /* CP_PLANLOCK */ + INT8 pnum; + INT8 pad1; + INT8 pad2; +}; + +struct playlock_cpacket { + INT8 type; /* CP_PLAYLOCK */ + INT8 pnum; + INT8 pad1; + INT8 pad2; +}; + +struct bomb_cpacket { + INT8 type; /* CP_BOMB */ + INT8 state; + INT8 pad1; + INT8 pad2; +}; + +struct beam_cpacket { + INT8 type; /* CP_BEAM */ + INT8 state; + INT8 pad1; + INT8 pad2; +}; + +struct cloak_cpacket { + INT8 type; /* CP_CLOAK */ + INT8 state; + INT8 pad1; + INT8 pad2; +}; + +struct det_torps_cpacket { + INT8 type; /* CP_DET_TORPS */ + INT8 pad1; + INT8 pad2; + INT8 pad3; +}; + +struct det_mytorp_cpacket { + INT8 type; /* CP_DET_MYTORP */ + INT8 pad1; + INT16 tnum; +}; + +struct copilot_cpacket { + INT8 type; /* CP_COPLIOT */ + INT8 state; + INT8 pad1; + INT8 pad2; +}; + +struct refit_cpacket { + INT8 type; /* CP_REFIT */ + INT8 ship; + INT8 pad1; + INT8 pad2; +}; + +struct tractor_cpacket { + INT8 type; /* CP_TRACTOR */ + INT8 state; + INT8 pnum; + INT8 pad2; +}; + +struct repress_cpacket { + INT8 type; /* CP_REPRESS */ + INT8 state; + INT8 pnum; + INT8 pad2; +}; + +struct coup_cpacket { + INT8 type; /* CP_COUP */ + INT8 pad1; + INT8 pad2; + INT8 pad3; +}; + +struct socket_cpacket { + INT8 type; /* CP_SOCKET */ + INT8 version; + INT8 udp_version; /* was pad2 */ + INT8 pad3; + CARD32 socket; +}; + +struct options_cpacket { + INT8 type; /* CP_OPTIONS */ + INT8 pad1; + INT8 pad2; + INT8 pad3; + CARD32 flags; + INT8 keymap[96]; +}; + +struct bye_cpacket { + INT8 type; /* CP_BYE */ + INT8 pad1; + INT8 pad2; + INT8 pad3; +}; + +struct dockperm_cpacket { + INT8 type; /* CP_DOCKPERM */ + INT8 state; + INT8 pad2; + INT8 pad3; +}; + +struct updates_cpacket { + INT8 type; /* CP_UPDATES */ + INT8 pad1; + INT8 pad2; + INT8 pad3; + CARD32 usecs; +}; + +struct resetstats_cpacket { + INT8 type; /* CP_RESETSTATS */ + INT8 verify; /* 'Y' - just to make sure he meant it */ + INT8 pad2; + INT8 pad3; +}; + +struct reserved_cpacket { + INT8 type; /* CP_RESERVED */ + INT8 pad1; + INT8 pad2; + INT8 pad3; + INT8 data[16]; + INT8 resp[16]; +}; + +struct scan_cpacket { /* ATM */ + INT8 type; /* CP_SCAN */ + INT8 pnum; + INT8 pad1; + INT8 pad2; +}; + +struct udp_req_cpacket { /* UDP */ + INT8 type; /* CP_UDP_REQ */ + INT8 request; + INT8 connmode; /* respond with port # or just send UDP + packet? */ + INT8 pad2; + INT32 port; /* compensate for hosed recvfrom() */ +}; + +struct sequence_cpacket { /* UDP */ + INT8 type; /* CP_SEQUENCE */ + INT8 pad1; + CARD16 sequence; +}; + +struct rsa_key_cpacket { + INT8 type; /* CP_RSA_KEY */ + INT8 pad1; + INT8 pad2; + INT8 pad3; + CARD8 global[KEY_SIZE]; + CARD8 public[KEY_SIZE]; + CARD8 resp[KEY_SIZE]; +}; + +/* the CP_ASK_MOTD packet is the same as temp_spacket */ + +struct ping_cpacket { + INT8 type; /* CP_PING_RESPONSE */ + CARD8 number; /* id */ + INT8 pingme; /* if client wants server to ping */ + INT8 pad1; + + INT32 cp_sent; /* # packets sent to server */ + INT32 cp_recv; /* # packets recv from server */ +}; + + +#ifdef FEATURE +/* feature_cpacket and _spacket are identical! */ +struct feature_cpacket { /* CP_FEATURE */ + INT8 type; + char feature_type; /* either 'C' or 'S' */ + CARD8 arg1; /* could be INT8 depending on feature */ + CARD8 arg2; /* but only BEEP_LITE uses it, for now */ + INT32 value; + char name[80]; +}; + +struct feature_spacket { /* SP_FEATURE */ + INT8 type; + char feature_type; /* either 'C' or 'S' */ + CARD8 arg1; + CARD8 arg2; + INT32 value; + char name[80]; +}; +#endif /* FEATURE */ + +/* + * short stuff + */ + +#ifdef SHORT_PACKETS +struct shortreq_cpacket { /* CP_S_REQ */ + INT8 type; + INT8 req; + INT8 version; + INT8 pad2; +}; + +struct threshold_cpacket { /* CP_S_THRS */ + INT8 type; + INT8 pad1; + CARD16 thresh; +}; + +struct shortreply_spacket { /* SP_S_REPLY */ + INT8 type; + INT8 repl; + CARD16 winside; + INT32 gwidth; +}; + +struct youshort_spacket { /* SP_S_YOU */ + INT8 type; + + INT8 pnum; + INT8 hostile; + INT8 swar; + + INT8 armies; + INT8 whydead; + INT8 whodead; + + INT8 pad1; + + CARD32 flags; +}; + +struct youss_spacket { /* SP_S_YOU_SS */ + INT8 type; + INT8 pad1; + + CARD16 damage; + CARD16 shield; + CARD16 fuel; + CARD16 etemp; + CARD16 wtemp; +}; + +#define VPLANET_SIZE 6 + +struct planet_s_spacket { /* body of SP_S_PLANET */ + INT8 pnum; + INT8 owner; + INT8 info; + CARD8 armies; /* more than 255 Armies ? ... */ + INT16 flags; +}; +struct warning_s_spacket { /* SP_S_WARNING */ + INT8 type; + CARD8 whichmessage; + INT8 argument, argument2;/* for phaser etc ... */ +}; + +struct player_s_spacket { + INT8 type; /* SP_S_PLAYER Header */ + INT8 packets; /* How many player-packets are in this packet + ( only the first 6 bits are relevant ) */ + CARD8 dir; + INT8 speed; + INT32 x, y; /* To get the absolute Position */ +}; + +/* The format of the body: +struct player_s_body_spacket { Body of new Player Packet + CARD8 pnum; 0-4 = pnum, 5 local or galactic, 6 = 9. x-bit, 7 9. y-bit + CARD8 speeddir; 0-3 = speed , 4-7 direction of ship + CARD8 x; low 8 bits from X-Pixelcoordinate + CARD8 y; low 8 bits from Y-Pixelcoordinate +}; +*/ + +struct torp_s_spacket { + INT8 type; /* SP_S_TORP */ + CARD8 bitset; /* bit=1 that torp is in packet */ + CARD8 whichtorps; /* Torpnumber of first torp / 8 */ + CARD8 data[21]; /* For every torp 2*9 bit coordinates */ +}; + +struct mesg_s_spacket { + INT8 type; /* SP_S_MESSAGE */ + CARD8 m_flags; + CARD8 m_recpt; + CARD8 m_from; + CARD8 length; /* Length of whole packet */ + INT8 mesg; + INT8 pad2; + INT8 pad3; + INT8 pad[76]; +}; + +struct mesg_s_cpacket { + INT8 type; /* CP_S__MESSAGE */ + INT8 group; + INT8 indiv; + INT8 length; /* Size of whole packet */ + INT8 mesg[80]; +}; + +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paradise.sndsrv.freebsd.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,295 @@ +/* + * paradise.sndsrv.c - USS-Lite Compatible Sound - July 1996 + * This server is FreeBSD Specific. + * Sujal M. Patel (smpatel@umiacs.umd.edu) + * + * + * Copyright (c) 1994-1996, Sujal M. Patel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: paradise.sndsrv.freebsd.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <machine/soundcard.h> +#include <sys/time.h> +#include <signal.h> +#include <string.h> + + + +char *FILENAME[] = { + "/explode.raw", + "/cloak.raw", + "/firetorp.raw", + "/phaser.raw", + "/plasma.raw", + "/shield.raw", + "/torphit.raw", + "/explode_big.raw", + "/paradise.raw", + "/thermal.raw", + "/redalert.raw" + }; + +#define NUM_SOUNDS (sizeof(FILENAME)/sizeof(char*)) + +signed char *sound_buffer[NUM_SOUNDS]; +int sound_size[NUM_SOUNDS]; +int fragsize; + + +/* Terminate: Signal Handler */ +void quit () +{ + exit (0); +} + + + +void init (int argc, char **argv) +{ + int i; + char s[1024]; + + if (argc != 3) + { + printf ("This program is only executed by netrek.paradise\n"); + exit (1); + } + + for (i=0; i < NUM_SOUNDS; i++) + { + s[0] = 0; + strcat (s, argv[1]); + if (s[(int)strlen(s) - 1] == '/') FILENAME[i]++; + strcat (s, FILENAME[i]); + FILENAME[i] = malloc ((int)strlen (s)); + strcpy (FILENAME[i],s); + sound_buffer[i]=NULL; + sound_size[i]=0; + } + + signal(SIGTERM, quit); /* Setup Terminate Signal Handler */ +} + + +/* + Setup DSP: Opens /dev/dsp or /dev/pcdsp + Sets fragment size on VoxWare + Sets speed to 8000hz + Should set mono mode + Error checking +*/ +int setup_dsp (char *dspdev,int *is_pcsp) +{ + int dsp, frag, value; + int mixer; + + dsp = open(dspdev, O_RDWR); + if (dsp < 1) + { + fprintf (stderr, "paradise.sndsrv: Couldn't open device %s\n",dspdev); + return -1; + } + + *is_pcsp = 0; + fragsize = 0; + + frag = 0x00020009; /* try 512 bytes, for 1/16 second frag size */ + ioctl(dsp, SNDCTL_DSP_SETFRAGMENT, &frag); + value = 8010; + if (ioctl(dsp, SNDCTL_DSP_SPEED, &value)) + { + fprintf (stderr, "paradise.sndsrv: Couldn't set DSP rate!\n"); + }; + value = 0; + ioctl(dsp, SNDCTL_DSP_STEREO, &value); + ioctl(dsp, SNDCTL_DSP_GETBLKSIZE, &fragsize); + /*fprintf(stderr,"paradise.sndsrv: fragment set to %d\n",fragsize);*/ + + if (!fragsize) + { + /* Don't Assume just because you can't set the fragment, use proper IOCTL */ + fprintf (stderr, "paradise.sndsrv: Couldn't set Fragment Size.\nAssuming PC Speaker!\n"); + fragsize = 128; + *is_pcsp = 1; + } else { + mixer = open("/dev/mixer",O_RDWR | O_NONBLOCK); + if(mixer==-1) { + fprintf(stderr,"paradise.sndsrv: Couldn't open mixer %s\n","/dev/mixer"); + return(-1); + }; + value=0x6464; + ioctl(mixer,SOUND_MIXER_WRITE_PCM,&value); + ioctl(mixer,SOUND_MIXER_WRITE_VOLUME,&value); /*what does this do?*/ + close(mixer); + } + + return dsp; +} + +/* + This just keeps the pipe from breaking... + Eventually I'll look at the paradise signal handlers and + just trap this. +*/ +int do_nothing(void) +{ + while(1) sleep (5); +} + +int read_sound(int k) +{ + int i,fd,size; + + /*fprintf(stderr,"loading sound %d, %s\n",k,FILENAME[k]);*/ + + fd = open(FILENAME[k], O_RDONLY); + if(fd<=0) + { + fprintf (stderr, "paradise.sndsrv: The sound %s could not be opened\n", FILENAME[k]); + sound_size[k]=-1; + return(0); + }; + size=lseek(fd,0,SEEK_END); + sound_size[k]=(size/fragsize)+1; /*size in fragments*/ + sound_buffer[k]=malloc(sound_size[k]*fragsize); + if(sound_buffer[k]==NULL) + { + fprintf(stderr,"paradise.sndsrv: couldn't malloc memory for sound\n"); + sound_size[k]=-1; + close(fd); + return(0); + }; + lseek(fd,0,SEEK_SET); + read(fd,sound_buffer[k],size); + close(fd); + for(i=0;i<size;i++) sound_buffer[k][i]^=0x80; + memset(sound_buffer[k]+size,0,sound_size[k]*fragsize-size); + + /*fprintf(stderr,"sound has been loaded, %d bytes\n",size);*/ /*DEBUG*/ + return(1); +} + + +void do_everything (int dsp, int is_pcsp) +{ + char k; + int i, j ; + int terminate = -1; /* Which Sound to Terminate */ + int playing[16]; /* Sound numbers that we are playing */ + int position[16]; /* Current position in each sound file */ + int playnum = 0; /* Number of sounds currently being played */ + unsigned char final[512]; /* Final Mixing Buffer */ + int premix[512]; + char *sample; + + for(;;) { + terminate = -1; + /* Try to open a new sound if we get an integer on the 'in' pipe */ + i=read(STDIN_FILENO,&k,sizeof(k)); + if(i==0) { /* EOF on pipe means parent has closed its end */ + /*fprintf(stderr,"paradise.sndsrv: shutting down\n"); */ + kill(getpid(), SIGTERM); + }; + if(i!=-1) { /* there was something in the pipe */ + /*fprintf(stderr,"Just read a %d from pipe\n",(int)k);*/ /*DEBUG*/ + /* Negative means terminate the FIRST sound in the buffer */ + if(k<0) { + /*fprintf(stderr,"terminating sound\n");*/ /*DEBUG*/ + terminate = 0; + } else { + if(sound_size[k]==0) read_sound(k); + if(sound_size[k]>0 && playnum<16) { + position[playnum]=0; + playing[playnum++]=k; + /*fprintf(stderr,"sound %d added to play queue\n",playnum-1);*/ /*DEBUG*/ + }; + }; + }; + + /* terminate a sound if necessary */ + for(i=0;i<playnum;i++) + { + if((position[i]==sound_size[playing[i]]) || (terminate==i)) + { + /*fprintf(stderr,"finished playing sound %d\n",i);*/ /*DEBUG*/ + /*fprintf(stderr,"is was at position %d\n",position[i]);*/ /*DEBUG*/ + memmove(playing+i,playing+i+1,(playnum-i)*sizeof(int)); + memmove(position+i,position+i+1,(playnum-i)*sizeof(int)); + playnum--;i--; + }; + }; + + if(playnum) { + /* Mix each sound into the final buffer */ + memset(premix,0,sizeof(premix)); + for(i=0;i<playnum;i++) { + sample=sound_buffer[playing[i]]+position[i]*fragsize; + for(j=0;j<fragsize;j++) { + premix[j]+=*(sample+j); + }; + position[i]++; + }; + for(i=0;i<fragsize;i++) + final[i]=(premix[i]>255)?255:(premix[i]<-256?0:(premix[i]>>1)+128); + } else { + /* + We have no sounds to play + Just fill the buffer with silence and maybe play it + */ + memset(final,128,sizeof(final)); + }; + write (dsp, final, fragsize); + /* + The sound server is in a tight loop, EXCEPT for this + write which blocks. Any optimizations in the above + code would really be helpful. Right now the server + takes up to 7% cpu on a 486DX/50. + */ + } +} + + + +void main (argc, argv) +int argc; +char **argv; +{ + int dsp, is_pcsp, ppid; + char filename[512]; + + fcntl(STDIN_FILENO,F_SETFL,O_NONBLOCK); + init (argc, argv); + dsp = setup_dsp (argv[2],&is_pcsp); + + if (dsp < 1) do_nothing(); + + do_everything (dsp, is_pcsp); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paradise.sndsrv.hp.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,293 @@ +/* + * paradise.sndsrv.c - USS-Lite Compatible Sound - July 1996 + * This server is HP/UX Specific. + * Sujal M. Patel (smpatel@umiacs.umd.edu) + * + * + * Copyright (c) 1994-1996, Sujal M. Patel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: paradise.sndsrv.hp.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <sys/time.h> +#include <sys/audio.h> +#include <signal.h> +#include <string.h> + + +char *FILENAME[] = { + "/explode.raw", + "/cloak.raw", + "/firetorp.raw", + "/phaser.raw", + "/plasma.raw", + "/shield.raw", + "/torphit.raw", + "/explode_big.raw", + "/paradise.raw", + "/thermal.raw", + "/redalert.raw" + }; + +#define NUM_SOUNDS (sizeof(FILENAME)/sizeof(char*)) + +signed char *sound_buffer[NUM_SOUNDS]; +int sound_size[NUM_SOUNDS]; +#define fragsize (256) + + +/* Terminate: Signal Handler */ +void quit () +{ + exit (0); +} + + + +void init (int argc, char **argv) +{ + int i; + char s[1024]; + + if (argc != 3) + { + printf ("This program is only executed by Paradise\n"); + exit (1); + } + + for (i=0; i < NUM_SOUNDS; i++) + { + s[0] = 0; + strcat (s, argv[1]); + if (s[(int)strlen(s) - 1] == '/') FILENAME[i]++; + strcat (s, FILENAME[i]); + FILENAME[i] = malloc ((int)strlen (s)+1); + strcpy (FILENAME[i],s); + sound_buffer[i]=NULL; + sound_size[i]=0; + } + + signal(SIGTERM, quit); /* Setup Terminate Signal Handler */ +} + + +/* + Setup DSP: Opens /dev/audio + Sets fragment size to 512 + Error checking +*/ +int setup_dsp (char *dspdev) +{ + int dsp, frag, value; + int mixer; + + dsp = open(dspdev, O_RDWR); + if (dsp < 1) + { + fprintf (stderr, "paradise.sndsrv: Couldn't open device %s\n",dspdev); + return -1; + } + + if (-1 == ioctl(dsp, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_LINEAR16BIT)) { + fprintf(stderr,"paradise.sndsrv: parameter setting failed"); + return; + } + + if (-1 == ioctl(dsp, AUDIO_SET_CHANNELS, 1)) { + fprintf(stderr,"paradise.sndsrv: parameter setting failed"); + return; + } + + if (-1 == ioctl(dsp, AUDIO_SET_SAMPLE_RATE, 16000)) { + fprintf(stderr,"paradise.sndsrv: parameter setting failed"); + return -1; + } + + if (-1 == ioctl(dsp, AUDIO_SET_OUTPUT, AUDIO_OUT_INTERNAL)) { + fprintf(stderr,"paradise.sndsrv: parameter setting failed"); + return -1; + } + + + return dsp; +} + +/* + This just keeps the pipe from breaking... + Eventually I'll look at the paradise signal handlers and + just trap this. +*/ +int do_nothing(void) +{ + while(1) sleep (5); +} + +int read_sound(int k) +{ + int i,fd,size; + unsigned char * b; + short * d; + + /* fprintf(stderr,"loading sound %d, %s\n",k,FILENAME[k]); */ + + fd = open(FILENAME[k], O_RDONLY); + if(fd<=0) + { + fprintf (stderr, "paradise.sndsrv: The sound %s could not be opened\n", FILENAME[k]); + sound_size[k]=-1; + return(0); + }; + size=lseek(fd,0,SEEK_END); + sound_size[k]=((size)/fragsize)+1; /*size in fragments*/ + sound_buffer[k]=malloc(sound_size[k]*sizeof(short)*fragsize); + if(sound_buffer[k]==NULL) + { + fprintf(stderr,"paradise.sndsrv: couldn't malloc memory for sound\n"); + sound_size[k]=-1; + close(fd); + return(0); + }; + lseek(fd,0,SEEK_SET); + read(fd,sound_buffer[k],size); + + b = ((unsigned char *)sound_buffer[k])+sound_size[k]*fragsize; + d = sound_buffer[k] + sound_size[k]*fragsize; + /* fprintf(stderr,"size = %d\n",sound_size[k]*fragsize); */ + for (i=0; i < sound_size[k]*fragsize; i++) { + *(--d) = (((short)*(--b))-128) << 8; + } + + close(fd); + bzero(((char *)sound_buffer[k])+size, sound_size[k]*sizeof(short)*fragsize-size); + + /* fprintf(stderr,"buba! sound has been loaded, %d bytes\n",size);*/ /*DEBUG*/ + return(1); +} + + +void do_everything (int dsp) +{ + char k; + int i, j ; + int terminate = -1; /* Which Sound to Terminate */ + int playing[16]; /* Sound numbers that we are playing */ + int position[16]; /* Current position in each sound file */ + int playnum = 0; /* Number of sounds currently being played */ + short final[fragsize]; /* Final Mixing Buffer */ + short *sample; + + for(;;) { + terminate = -1; + /* Try to open a new sound if we get an integer on the 'in' pipe */ + i=read(STDIN_FILENO,&k,sizeof(k)); + if(i==0) { /* EOF on pipe means parent has closed its end */ + /*fprintf(stderr,"paradise.sndsrv: shutting down\n"); */ + kill(getpid(), SIGTERM); + }; + if(i!=-1) { /* there was something in the pipe */ + /*fprintf(stderr,"Just read a %d from pipe\n",(int)k);*/ /*DEBUG*/ + /* Negative means terminate the FIRST sound in the buffer */ + if(k<0) { + fprintf(stderr,"terminating sound\n"); /*DEBUG*/ + terminate = 0; + } else { + if(sound_size[(int)k]==0) read_sound(k); + if(sound_size[(int)k]>0 && playnum<16) { + position[playnum]=0; + playing[playnum++]=k; + /* fprintf(stderr,"sound %d added to play queue\n",playnum-1);*/ /*DEBUG*/ + }; + }; + }; + + /* terminate a sound if necessary */ + for(i=0;i<playnum;i++) + { + if((position[i]==sound_size[playing[i]]) || (terminate==i)) + { + /* fprintf(stderr,"finished playing sound %d\n",i); */ /*DEBUG*/ + /* fprintf(stderr,"is was at position %d\n",position[i]); */ /*DEBUG*/ + bcopy(playing+i+1,playing+i,(playnum-i)*sizeof(int)); + bcopy(position+i+1,position+i,(playnum-i)*sizeof(int)); + playnum--;i--; + }; + }; + + memset(final, 0, sizeof(final)); + if(playnum) { + /* Mix each sound into the final buffer */ + for(i=0;i<playnum;i++) { + short * f = final; + sample=sound_buffer[playing[i]]+position[i]*fragsize; + for(j=0;j<fragsize;j++) { + long s = *f; + s += *sample++; + if (s < -32768) { + s = -32768; + } + if (s > 32767) { + s = 32767; + } + *f++ = (short)s; + }; + position[i]++; + } + } else { + /* + We have no sounds to play + Just fill the buffer with silence and maybe play it + */ + }; + write (dsp, final, fragsize*sizeof(short)); + /* + The sound server is in a tight loop, EXCEPT for this + write which blocks. Any optimizations in the above + code would really be helpful. Right now the server + takes up to 7% cpu on a 486DX/50. + */ + } +} + + + +void main (argc, argv) +int argc; +char **argv; +{ + int dsp; + + fcntl(STDIN_FILENO,F_SETFL,O_NONBLOCK); + init (argc, argv); + dsp = setup_dsp (argv[2]); + + if (dsp < 1) do_nothing(); + + do_everything (dsp); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paradise.sndsrv.linux.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,295 @@ +/* + * paradise.sndsrv.c - USS-Lite Compatible Sound - July 1996 + * This server is Linux Specific. + * Sujal M. Patel (smpatel@umiacs.umd.edu) + * + * + * Copyright (c) 1994-1996, Sujal M. Patel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: paradise.sndsrv.linux.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <linux/soundcard.h> +#include <sys/time.h> +#include <signal.h> +#include <string.h> + + + +char *FILENAME[] = { + "/explode.raw", + "/cloak.raw", + "/firetorp.raw", + "/phaser.raw", + "/plasma.raw", + "/shield.raw", + "/torphit.raw", + "/explode_big.raw", + "/paradise.raw", + "/thermal.raw", + "/redalert.raw" + }; + +#define NUM_SOUNDS (sizeof(FILENAME)/sizeof(char*)) + +signed char *sound_buffer[NUM_SOUNDS]; +int sound_size[NUM_SOUNDS]; +int fragsize; + + +/* Terminate: Signal Handler */ +void quit () +{ + exit (0); +} + + + +void init (int argc, char **argv) +{ + int i; + char s[1024]; + + if (argc != 3) + { + printf ("This program is only executed by netrek.paradise\n"); + exit (1); + } + + for (i=0; i < NUM_SOUNDS; i++) + { + s[0] = 0; + strcat (s, argv[1]); + if (s[(int)strlen(s) - 1] == '/') FILENAME[i]++; + strcat (s, FILENAME[i]); + FILENAME[i] = malloc ((int)strlen (s)); + strcpy (FILENAME[i],s); + sound_buffer[i]=NULL; + sound_size[i]=0; + } + + signal(SIGTERM, quit); /* Setup Terminate Signal Handler */ +} + + +/* + Setup DSP: + Sets fragment size on VoxWare + Sets speed to 8000hz + Should set mono mode + Error checking +*/ +int setup_dsp (char *dspdev,int *is_pcsp) +{ + int dsp, frag, value; + int mixer; + + dsp = open(dspdev, O_RDWR); + if (dsp < 1) + { + fprintf (stderr, "paradise.sndsrv: Couldn't open device %s\n",dspdev); + return -1; + } + + *is_pcsp = 0; + fragsize = 0; + + frag = 0x00020009; /* try 512 bytes, for 1/16 second frag size */ + ioctl(dsp, SNDCTL_DSP_SETFRAGMENT, &frag); + value = 8010; + if (ioctl(dsp, SNDCTL_DSP_SPEED, &value)) + { + fprintf (stderr, "paradise.sndsrv: Couldn't set DSP rate!\n"); + }; + value = 0; + ioctl(dsp, SNDCTL_DSP_STEREO, &value); + ioctl(dsp, SNDCTL_DSP_GETBLKSIZE, &fragsize); + /*fprintf(stderr,"paradise.sndsrv: fragment set to %d\n",fragsize);*/ + + if (!fragsize) + { + /* Don't Assume just because you can't set the fragment, use proper IOCTL */ + fprintf (stderr, "paradise.sndsrv: Couldn't set Fragment Size.\nAssuming PC Speaker!\n"); + fragsize = 128; + *is_pcsp = 1; + } else { + mixer = open("/dev/mixer",O_RDWR | O_NONBLOCK); + if(mixer==-1) { + fprintf(stderr,"paradise.sndsrv: Couldn't open mixer %s\n","/dev/mixer"); + return(-1); + }; + value=0x6464; + ioctl(mixer,SOUND_MIXER_WRITE_PCM,&value); + ioctl(mixer,SOUND_MIXER_WRITE_VOLUME,&value); /*what does this do?*/ + close(mixer); + } + + return dsp; +} + +/* + This just keeps the pipe from breaking... + Eventually I'll look at the paradise signal handlers and + just trap this. +*/ +int do_nothing(void) +{ + while(1) sleep (5); +} + +int read_sound(int k) +{ + int i,fd,size; + + /*fprintf(stderr,"loading sound %d, %s\n",k,FILENAME[k]);*/ + + fd = open(FILENAME[k], O_RDONLY); + if(fd<=0) + { + fprintf (stderr, "paradise.sndsrv: The sound %s could not be opened\n", FILENAME[k]); + sound_size[k]=-1; + return(0); + }; + size=lseek(fd,0,SEEK_END); + sound_size[k]=(size/fragsize)+1; /*size in fragments*/ + sound_buffer[k]=malloc(sound_size[k]*fragsize); + if(sound_buffer[k]==NULL) + { + fprintf(stderr,"paradise.sndsrv: couldn't malloc memory for sound\n"); + sound_size[k]=-1; + close(fd); + return(0); + }; + lseek(fd,0,SEEK_SET); + read(fd,sound_buffer[k],size); + close(fd); + for(i=0;i<size;i++) sound_buffer[k][i]^=0x80; + memset(sound_buffer[k]+size,0,sound_size[k]*fragsize-size); + + /*fprintf(stderr,"sound has been loaded, %d bytes\n",size);*/ /*DEBUG*/ + return(1); +} + + +void do_everything (int dsp, int is_pcsp) +{ + char k; + int i, j ; + int terminate = -1; /* Which Sound to Terminate */ + int playing[16]; /* Sound numbers that we are playing */ + int position[16]; /* Current position in each sound file */ + int playnum = 0; /* Number of sounds currently being played */ + unsigned char final[512]; /* Final Mixing Buffer */ + int premix[512]; + char *sample; + + for(;;) { + terminate = -1; + /* Try to open a new sound if we get an integer on the 'in' pipe */ + i=read(STDIN_FILENO,&k,sizeof(k)); + if(i==0) { /* EOF on pipe means parent has closed its end */ + /*fprintf(stderr,"paradise.sndsrv: shutting down\n"); */ + kill(getpid(), SIGTERM); + }; + if(i!=-1) { /* there was something in the pipe */ + /*fprintf(stderr,"Just read a %d from pipe\n",(int)k);*/ /*DEBUG*/ + /* Negative means terminate the FIRST sound in the buffer */ + if(k<0) { + /*fprintf(stderr,"terminating sound\n");*/ /*DEBUG*/ + terminate = 0; + } else { + if(sound_size[k]==0) read_sound(k); + if(sound_size[k]>0 && playnum<16) { + position[playnum]=0; + playing[playnum++]=k; + /*fprintf(stderr,"sound %d added to play queue\n",playnum-1);*/ /*DEBUG*/ + }; + }; + }; + + /* terminate a sound if necessary */ + for(i=0;i<playnum;i++) + { + if((position[i]==sound_size[playing[i]]) || (terminate==i)) + { + /*fprintf(stderr,"finished playing sound %d\n",i);*/ /*DEBUG*/ + /*fprintf(stderr,"is was at position %d\n",position[i]);*/ /*DEBUG*/ + memmove(playing+i,playing+i+1,(playnum-i)*sizeof(int)); + memmove(position+i,position+i+1,(playnum-i)*sizeof(int)); + playnum--;i--; + }; + }; + + if(playnum) { + /* Mix each sound into the final buffer */ + memset(premix,0,sizeof(premix)); + for(i=0;i<playnum;i++) { + sample=sound_buffer[playing[i]]+position[i]*fragsize; + for(j=0;j<fragsize;j++) { + premix[j]+=*(sample+j); + }; + position[i]++; + }; + for(i=0;i<fragsize;i++) + final[i]=(premix[i]>255)?255:(premix[i]<-256?0:(premix[i]>>1)+128); + } else { + /* + We have no sounds to play + Just fill the buffer with silence and maybe play it + */ + memset(final,128,sizeof(final)); + }; + write (dsp, final, fragsize); + /* + The sound server is in a tight loop, EXCEPT for this + write which blocks. Any optimizations in the above + code would really be helpful. Right now the server + takes up to 7% cpu on a 486DX/50. + */ + } +} + + + +void main (argc, argv) +int argc; +char **argv; +{ + int dsp, is_pcsp, ppid; + char filename[512]; + + fcntl(STDIN_FILENO,F_SETFL,O_NONBLOCK); + init (argc, argv); + dsp = setup_dsp (argv[2],&is_pcsp); + + if (dsp < 1) do_nothing(); + + do_everything (dsp, is_pcsp); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paradise.sndsrv.sun.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,283 @@ +/* + * paradise.sndsrv.c - VoxWare(tm) Compatible Sound - July 1996 + * This server is SunOS Specific. + * Sujal M. Patel (smpatel@umiacs.umd.edu) + * + * Copyright (c) 1994-1996, Sujal M. Patel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: paradise.sndsrv.sun.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <sys/time.h> +#include <signal.h> +#include <string.h> + +char *FILENAME[] = { + "/explode.raw", + "/cloak.raw", + "/firetorp.raw", + "/phaser.raw", + "/plasma.raw", + "/shield.raw", + "/torphit.raw", + "/explode_big.raw", + "/paradise.raw", + "/thermal.raw", + "/redalert.raw" + }; + +#define NUM_SOUNDS (sizeof(FILENAME)/sizeof(char*)) + +signed char *sound_buffer[NUM_SOUNDS]; +int sound_size[NUM_SOUNDS]; +int fragsize; + + +/* Terminate: Signal Handler */ +void +quit () +{ + exit (0); +} + + + +void +init (int argc, char **argv) +{ + int i; + char s[1024]; + + if (argc != 3) + { + printf ("This program is only executed by Paradise\n"); + exit (1); + } + + for (i = 0; i < NUM_SOUNDS; i++) + { + s[0] = 0; + strcat (s, argv[1]); + if (s[(int) strlen (s) - 1] == '/') + FILENAME[i]++; + strcat (s, FILENAME[i]); + FILENAME[i] = malloc ((int) strlen (s) + 1); + strcpy (FILENAME[i], s); + sound_buffer[i] = NULL; + sound_size[i] = 0; + } + + signal (SIGTERM, quit); /* Setup Terminate Signal Handler */ +} + + +/* + Setup DSP: Opens /dev/audio + Sets fragment size to 512 + Error checking + */ +int +setup_dsp (char *dspdev) +{ + int dsp, frag, value; + int mixer; + + dsp = open (dspdev, O_RDWR); + if (dsp < 1) + { + fprintf (stderr, "paradise.sndsrv: Couldn't open device %s\n", dspdev); + return -1; + } + + fragsize = 512; + + return dsp; +} + +/* + This just keeps the pipe from breaking... + Eventually I'll look at the paradise signal handlers and + just trap this. + */ +int +do_nothing (void) +{ + while (1) + sleep (5); +} + +int +read_sound (int k) +{ + int i, fd, size; + + /*fprintf(stderr,"loading sound %d, %s\n",k,FILENAME[k]); */ + + fd = open (FILENAME[k], O_RDONLY); + if (fd <= 0) + { + fprintf (stderr, "paradise.sndsrv: The sound %s could not be opened\n", FILENAME[k]); + sound_size[k] = -1; + return (0); + }; + size = lseek (fd, 0, SEEK_END); + sound_size[k] = (size / fragsize) + 1; /*size in fragments */ + sound_buffer[k] = malloc (sound_size[k] * fragsize); + if (sound_buffer[k] == NULL) + { + fprintf (stderr, "paradise.sndsrv: couldn't malloc memory for sound\n"); + sound_size[k] = -1; + close (fd); + return (0); + }; + lseek (fd, 0, SEEK_SET); + read (fd, sound_buffer[k], size); + close (fd); + for (i = 0; i < size; i++) + sound_buffer[k][i] ^= 0x80; + bzero (sound_buffer[k] + size, sound_size[k] * fragsize - size); + + /*fprintf(stderr,"sound has been loaded, %d bytes\n",size); *//*DEBUG */ + return (1); +} + + +void +do_everything (int dsp) +{ + char k; + int i, j; + int terminate = -1; /* Which Sound to Terminate */ + int playing[16]; /* Sound numbers that we are playing */ + int position[16]; /* Current position in each sound file */ + int playnum = 0; /* Number of sounds currently being played */ + unsigned char final[512]; /* Final Mixing Buffer */ + int premix[512]; + char *sample; + + for (;;) + { + terminate = -1; + /* Try to open a new sound if we get an integer on the 'in' pipe */ + i = read (STDIN_FILENO, &k, sizeof (k)); + if (i == 0) + { /* EOF on pipe means parent has closed its end */ + /*fprintf(stderr,"paradise.sndsrv: shutting down\n"); */ + kill (getpid (), SIGTERM); + }; + if (i != -1) + { /* there was something in the pipe */ + /*fprintf(stderr,"Just read a %d from pipe\n",(int)k); *//*DEBUG */ + /* Negative means terminate the FIRST sound in the buffer */ + if (k < 0) + { + /*fprintf(stderr,"terminating sound\n"); *//*DEBUG */ + terminate = 0; + } + else + { + if (sound_size[(int) k] == 0) + read_sound (k); + if (sound_size[(int) k] > 0 && playnum < 16) + { + position[playnum] = 0; + playing[playnum++] = k; + /*fprintf(stderr,"sound %d added to play queue\n",playnum-1); *//*DEBUG */ + }; + }; + }; + + /* terminate a sound if necessary */ + for (i = 0; i < playnum; i++) + { + if ((position[i] == sound_size[playing[i]]) || (terminate == i)) + { + /*fprintf(stderr,"finished playing sound %d\n",i); *//*DEBUG */ + /*fprintf(stderr,"is was at position %d\n",position[i]); *//*DEBUG */ + bcopy (playing + i + 1, playing + i, (playnum - i) * sizeof (int)); + bcopy (position + i + 1, position + i, (playnum - i) * sizeof (int)); + playnum--; + i--; + }; + }; + + if (playnum) + { + /* Mix each sound into the final buffer */ + bzero (premix, sizeof (premix)); + for (i = 0; i < playnum; i++) + { + sample = sound_buffer[playing[i]] + position[i] * fragsize; + for (j = 0; j < fragsize; j++) + { + premix[j] += *(sample + j); + }; + position[i]++; + }; + for (i = 0; i < fragsize; i++) + final[i] = (premix[i] > 255) ? 255 : (premix[i] < -256 ? 0 : (premix[i] >> 1) + 128); + } + else + { + /* + We have no sounds to play + Just fill the buffer with silence and maybe play it + */ + memset (final, 128, sizeof (final)); + }; + write (dsp, final, fragsize); + /* + The sound server is in a tight loop, EXCEPT for this + write which blocks. Any optimizations in the above + code would really be helpful. Right now the server + takes up to 7% cpu on a 486DX/50. + */ + } +} + + + +void +main (argc, argv) + int argc; + char **argv; +{ + int dsp; + + fcntl (STDIN_FILENO, F_SETFL, O_NONBLOCK); + init (argc, argv); + dsp = setup_dsp (argv[2]); + + if (dsp < 1) + do_nothing (); + + do_everything (dsp); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/parsemeta.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,487 @@ +/* $Id: parsemeta.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +/* + * meta.c - Nick Trown May 1993 + */ + +#ifdef METASERVER + +#include "copyright.h" +#include <fcntl.h> +#include <stdio.h> +#include <ctype.h> +#include <sys/types.h> +#include <sys/time.h> +#include <stdlib.h> +#include <sys/socket.h> +#include <unistd.h> + +#ifdef RS6K +#include <sys/select.h> +#include <fcntl.h> +#endif + +#ifndef DNET +#include <netinet/in.h> +#include <arpa/inet.h> +#endif +#include <netdb.h> +#include <errno.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "proto.h" + +#include <string.h> +#if !defined(SYSV) && !defined(apollo) && !defined(SVR4) +#include <strings.h> +#endif + +#define BUF 4096 + +static void metarefresh P((int i)); +static void metadone P((void)); + +int pid = 0; +int num_servers = 0; +int max_servers = 20; +struct servers *serverlist = NULL; +char *keystrings[] = {"OPEN:", "Wait queue:", "Nobody"}; + +/* + I was planning to use this function a lot but it doesn't look like + I need it more than once. It finds the next number after position + 'start'. + */ + +int +getnumber(string, start) + char *string; + int start; +{ +#if 0 /* this is stupid [BDyess] */ + char temp[LINE]; + int c; + int tc = 0; + + for (c = start; c <= (int) strlen(string); c++) { + if ((string[c] >= '0') && (string[c] <= '9')) { + temp[tc++] = string[c]; + } else if (tc > 0) { + temp[tc] = '\0'; + return (atoi(temp)); + } + } + return 0; +#endif /*0*/ + + string += start; + while(!isdigit(*string) && *string) string++; + return atoi(string); +} + + +/* + The connection to the metaserver is by Andy McFadden. + This calls the metaserver and parses the output into something + useful + */ + +static int +open_port(host, port, verbose) + char *host; + int port; + int verbose; +{ +#ifdef DNET + return DNetOpenMeta(host, port); +#else + struct sockaddr_in addr; + struct hostent *hp; + int s; + + + /* Connect to the metaserver */ + /* get numeric form */ + if ((addr.sin_addr.s_addr = inet_addr(host)) == -1) { + if ((hp = gethostbyname(host)) == NULL) { + if (verbose) + fprintf(stderr, "unknown host '%s'\n", host); + return (-1); + } else { + addr.sin_addr.s_addr = *(long *) hp->h_addr; + } + } + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + if (verbose) + perror("socket"); + return (-1); + } + if (connect(s, (struct sockaddr *) & addr, sizeof(addr)) < 0) { + if (verbose) + perror("connect"); + close(s); + return (-1); + } + return (s); +#endif /* DNET */ +} + +static int +readmeta(s) + int s; +{ + int cc, lc = 0, c, tc; + + static char buf[BUF + 1]; + static char *numstr; + static char line[LINE + 1]; + +#ifndef DEBUG + while (1) { +#ifdef DNET /* annoying... */ + if ((cc = sock_read(s, buf, BUF)) < 0) { +#else /* } */ /* to balance the {'s for emacs */ + if ((cc = sock_read(s, buf, BUF)) <= 0) { + if (cc < 0) + perror("read"); +#endif /* DNET */ + sock_close(s); + return (cc); + } +#else + /* + cat the output of the metaserver port 3521 to a file called "output" + for testing purposes + */ + s = open("output", O_RDONLY); + + if ((cc = read(s, buf, BUF)) <= 0) { + if (cc < 0) + perror("read"); + close(s); + return (cc); + } + fwrite(buf, cc, 1, stdout); + close(s); +#endif + + for (c = 0; c < cc; c++) { + if (buf[c] != '\n') /* Break up the buffer into lines */ + line[lc++] = buf[c]; + else { + line[lc] = 0; /* random problems without this. No terminator + means invalid strlen(). [BDyess] */ + if (sscanf(line, "-h %s -p %d %d", /* parse line */ + serverlist[num_servers].address, + &serverlist[num_servers].port, + &serverlist[num_servers].time) == 3) { + /* get what type of server it is */ + serverlist[num_servers].typeflag = line[strlen(line) - 1]; + if (serverlist[num_servers].typeflag == 'P') { + serverlist[num_servers].status = 2; + serverlist[num_servers].players = 0; + } else + serverlist[num_servers].status = -1; + + /* + I don't have it checking the servers with nobody playing + because the menu window would then be too large to fit on + a 1024 x 768 window. :( - NBT + */ + + for (tc = 0; tc < KEY; tc++) + if ((numstr = strstr(line, keystrings[tc]))) { + serverlist[num_servers].status = tc; + serverlist[num_servers].players = getnumber(numstr, 0); + } + if (strrchr(line, 'R')) + serverlist[num_servers].RSA_client = 1; + else + serverlist[num_servers].RSA_client = 0; + + if (serverlist[num_servers].status >= 0 && + (serverlist[num_servers].status != 2 || + serverlist[num_servers].typeflag == 'P')) { + +#ifdef DEBUG + printf("HOST:%-30s PORT:%-6d %12s %-5d %d\n", + serverlist[num_servers].address, + serverlist[num_servers].port, + keystrings[serverlist[num_servers].status], + serverlist[num_servers].players, + serverlist[num_servers].RSA_client); +#endif + + serverlist[num_servers].hilited = 0; + num_servers++; /* It's valid */ + if(num_servers == max_servers) { + /* double the size every time it's exceeded [BDyess] */ + serverlist = (struct servers*) realloc(serverlist, + sizeof(struct servers) * (max_servers *= 2)); + } + } + } + lc = 0; + /*line[0] = '\0'; silly [BDyess] */ + } + } +} + /* close(s); */ +} + + +void +parsemeta() +{ + int s; + + num_servers = 0; + + /* serverlist is now dynamic and grows. This fixes the random coredump + and data corruption problems the previous static method caused. + [BDyess] */ + if(serverlist) free(serverlist); + serverlist = (struct servers*) malloc(sizeof(struct servers) * max_servers); + + if (serverName) { + strcpy(serverlist[num_servers].address, serverName); + serverlist[num_servers].port = xtrekPort; + +#ifdef RSA + serverlist[num_servers].RSA_client = RSA_Client; +#endif + + serverlist[num_servers].status = KEY + 1; + serverlist[num_servers].players = 0; + num_servers++; + } + printf("connecting to metaserver..."); + fflush(stdout); + +#ifdef DEBUG + readmeta(0); +#else + if ((s = open_port(metaserverAddress, METAPORT, 1)) > 0) { + readmeta(s); + } else { + printf("failed (%s , %d)\n", metaserverAddress, METAPORT); + } +#endif + printf("\n"); +} + + +/* Show the meta server menu window */ + +void +metawindow() +{ + register int i; + static int old_num_servers = -1; + + if (old_num_servers != num_servers) { + if (metaWin) + W_DestroyWindow(metaWin); + metaWin = W_MakeMenu("MetaServer List", WINSIDE + 10, -BORDER + 10, 69, + num_servers + 2, NULL, 2); + } + for (i = 0; i < num_servers; i++) + metarefresh(i); + + /* add refresh option [BDyess] */ + W_WriteText(metaWin, 0, num_servers, textColor, "Refresh", 7, 0); + + /* Add quit option */ + W_WriteText(metaWin, 0, num_servers + 1, textColor, "Quit", 4, W_RegularFont); + + /* Map window */ + if (!W_IsMapped(metaWin)) + W_MapWindow(metaWin); +} + +/* + * Refresh item i + */ +static void +metarefresh(i) + int i; +{ + char buf[BUFSIZ]; + + if (serverlist[i].status < KEY) { + sprintf(buf, "%-40s %12s ", + serverlist[i].address, + keystrings[serverlist[i].status]); + if (serverlist[i].status != 2) + sprintf(buf + strlen(buf), "%-5d ", serverlist[i].players); + else + strcat(buf, " "); + switch (serverlist[i].typeflag) { + case 'P': + strcat(buf, "Paradise"); + break; + case 'B': + strcat(buf, "Bronco"); + break; + case 'C': + strcat(buf, "Chaos"); + break; + case 'I': + strcat(buf, "INL"); + break; + case 'S': + strcat(buf, "Sturgeon"); + break; + case 'H': + strcat(buf, "Hockey"); + break; + case 'F': + strcat(buf, "Dogfight"); + break; + } + } else if (serverlist[i].status == KEY) { /* For when I have checking + code */ + sprintf(buf, "%-40s CANNOT CONNECT", serverlist[i].address); + } else if (serverlist[i].status == KEY + 1) { + sprintf(buf, "%-40s DEFAULT SERVER", serverlist[i].address); + } + W_WriteText(metaWin, 0, i, + serverlist[i].hilited ? W_Yellow : textColor, + buf, (int)strlen(buf), + serverlist[i].hilited ? W_HighlightFont : W_RegularFont); +} + + +/* + Check selection to see if was valid. If it was then we have a winner! + */ +static void +metaaction(data) + W_Event *data; +{ + int s; + static time_t lastRefresh = 0; + static time_t t; + + if ((data->y >= 0) && (data->y < num_servers)) { + xtrekPort = serverlist[data->y].port; + serverName = serverlist[data->y].address; + +#ifdef RSA + RSA_Client = serverlist[data->y].RSA_client; +#endif + serverlist[data->y].hilited = 1; + metarefresh(data->y); + + if ((s = open_port(serverName, xtrekPort, 0)) <= 0) { + serverlist[data->y].status = KEY; + serverlist[data->y].hilited = 0; + metarefresh(data->y); + } else { + sock_close(s); +#ifndef AMIGA + /* allow spawning off multiple clients [BDyess] */ + if (metaFork) { + /* just blink yellow [BDyess] */ + serverlist[data->y].hilited = 0; + metarefresh(data->y); + pid = fork(); + } else +#else + /* + OUCH. fork() sucks ;-) Using "run" is equivalent to appending + a & to a command in Unix. (my shell allows &, but it's not + built in to AmigaDOS.) This is a stupid kludge. I + should write a silly shell or rexx script to do all the + metaserver stuff instead, and not compile PARSEMETA at all. + */ + if (metaFork) { + extern char *command_line; /* main.c, argv */ + extern int global_argc; + int ac; + char buf2[256]; + char buf[80]; + + sprintf(buf,"run %s ",command_line[0]); + for(ac=1;ac<global_argc;ac++) { + if(strcmp(command_line[ac], "-m") == 0) + ac++; + else { + strcat(buf,command_line[ac]); + strcat(buf," "); + } + } + printf(buf2,"-h %s -p %d", command_line[0], serverName, xtrekPort); + strcat(buf, buf2); + Execute(buf, Input(), Output()); + } else +#endif /* AMIGA */ + { + pid = 1; + metadone(); + } + } + } else if (data->y == num_servers) { /* refresh [BDyess] */ + /* + they can bang on refresh all day, but it won't refresh any faster + than once/minute. [BDyess] + */ + if ((t = time(NULL)) < lastRefresh + 60) + return; + lastRefresh = t; + parsemeta(); /* connect and parse info */ + metawindow(); /* refresh */ + } else { /* quit */ + metadone(); + exit(0); + } +} + + +/* + Unmap the metaWindow + */ + +static void +metadone() +{ + /* Unmap window */ + W_UnmapWindow(metaWin); +} + + +/* + My own little input() function. I needed this so I don't have + to use all the bull in the main input(). Plus to use it I'd have + to call mapAll() first and the client would read in the default + server and then call it up before I can select a server. + */ + +void +metainput() +{ + W_Event data; + + while (W_IsMapped(metaWin) && pid == 0) { + W_GetEvent(&data); + switch ((int) data.type) { + case W_EV_KEY: + if (data.Window == metaWin) + metaaction(&data); + break; + case W_EV_BUTTON: + if (data.Window == metaWin) + metaaction(&data); + break; + case W_EV_EXPOSE: + break; + default: + break; + } + } +} +#endif /* METASERVER */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ping.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,147 @@ +/* $Id: ping.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +/* + * ping.c + * + */ + +#include "copyright2.h" +#include <stdio.h> +#include <sys/types.h> +#include <sys/time.h> +#include <netinet/in.h> +#include <math.h> +#include <errno.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "packets.h" +#include "proto.h" + +/* These are used only in pingstats.c */ + +int ping_iloss_sc = 0; /* inc % loss 0--100, server to client */ +int ping_iloss_cs = 0; /* inc % loss 0--100, client to server */ +int ping_tloss_sc = 0; /* total % loss 0--100, server to client */ +int ping_tloss_cs = 0; /* total % loss 0--100, client to server */ +int ping_lag = 0; /* delay in ms of last ping */ +int ping_av = 0; /* rt time */ +int ping_sd = 0; /* std deviation */ + +static int sum, n; +static int M, var; +static double s2; + +void sendServerPingResponse P((int number)); +void calc_lag P((void)); + +void +handlePing(packet) /* SP_PING */ + struct ping_spacket *packet; +{ + ping = 1; /* we got a ping */ + +/* +printf("ping received at %d (lag: %d)\n", msetime(), (int)packet->lag); +*/ + sendServerPingResponse((int) packet->number); + ping_lag = ntohs(packet->lag); + ping_iloss_sc = (int) packet->iloss_sc; + ping_iloss_cs = (int) packet->iloss_cs; + ping_tloss_sc = (int) packet->tloss_sc; + ping_tloss_cs = (int) packet->tloss_cs; + + calc_lag(); + + if (W_IsMapped(pStats)) /* pstat window */ + updatePStats(); +} + +void +startPing() +{ + static + struct ping_cpacket packet; + extern int serverDead; + + packet.type = CP_PING_RESPONSE; + packet.pingme = 1; + + if (gwrite(sock, (char *) &packet, sizeof(struct ping_cpacket)) != + sizeof(struct ping_cpacket)) { + printf("gwrite failed.\n"); + serverDead = 1; + } +} + +void +stopPing() +{ + static + struct ping_cpacket packet; + extern int serverDead; + + ping = 0; + packet.type = CP_PING_RESPONSE; + packet.pingme = 0; + + if (gwrite(sock, (char *) &packet, sizeof(struct ping_cpacket)) != + sizeof(struct ping_cpacket)) { + printf("gwrite failed.\n"); + serverDead = 1; + } +} + +void +sendServerPingResponse(number) /* CP_PING_RESPONSE */ + int number; +{ + struct ping_cpacket packet; + int s; + extern int serverDead; + + if (udpSock >= 0) { + s = udpSock; + packets_sent++; + } else + s = sock; + + packet.type = CP_PING_RESPONSE; + packet.pingme = (char) ping; + packet.number = (unsigned char) number; + /* count this one */ + packet.cp_sent = htonl(packets_sent); + packet.cp_recv = htonl(packets_received); + +/* +printf("ping response sent at %d\n", msetime()); +*/ + + if (gwrite(s, (char *) &packet, sizeof(struct ping_cpacket)) != + sizeof(struct ping_cpacket)) { + printf("gwrite failed.\n"); + serverDead = 1; + } +} + +void +calc_lag() +{ + /* probably ghostbusted */ + /* without this things can get really bad */ + if (ping_lag > 2000 || ping_lag == 0) + return; + + n++; + sum += ping_lag; + s2 += (ping_lag * ping_lag); + if (n == 1) + return; + + M = sum / n; + var = (s2 - M * sum) / (n - 1); + + ping_av = M; + ping_sd = (int) sqrt((double) var); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pingstats.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,224 @@ +/* $Id: pingstats.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +/* + * pingstats.c (mostly taken from stats.c) + */ +#include "copyright.h" + +#include <stdio.h> +#include <math.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "proto.h" + +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + +#define BX_OFF() ((textWidth + 1) * W_Textwidth + S_IBORDER) +#define BY_OFF(line) ((line) * (W_Textheight + S_IBORDER) + S_IBORDER) +#define TX_OFF(len) ((textWidth - len) * W_Textwidth + S_IBORDER) +#define TY_OFF(line) BY_OFF(line) + +/* right side labels */ +#define TEXT_WIDTH (5*W_Textwidth + 2*STAT_BORDER) +#define STAT_WIDTH (260 + TEXT_WIDTH) +#define STAT_HEIGHT BY_OFF(NUM_SLIDERS) +#define STAT_BORDER 2 +#define S_IBORDER 5 +#define STAT_X 422 +#define STAT_Y 13 + +#define SL_WID \ + (STAT_WIDTH -TEXT_WIDTH - 2 * S_IBORDER - (textWidth + 1) * W_Textwidth) +#define SL_HEI (W_Textheight) + +#define NUM_ELS(a) (sizeof (a) / sizeof (*(a))) +#define NUM_SLIDERS NUM_ELS(sliders) + +typedef struct slider { + char *label; + int min, max; + int green, yellow; + int label_length; + int diff; + int *var; + int lastVal; +} SLIDER; + +typedef struct record { + int *data; + int last_value; +} RECORD; + +static SLIDER sliders[] = { + {"round trip time", 0, 500, 100, 200}, + {"average r.t. time", 0, 500, 100, 200}, + {"lag (st. dev.)", 0, 100, 20, 50}, + {"%pack in loss", 0, 50, 10, 20}, + {"%pack out loss", 0, 50, 10, 20}, + {"tot %pack loss in", 0, 50, 5, 10}, + {"tot %pack loss out", 0, 50, 5, 10}, +}; + +static int textWidth = 0; +static int initialized = 0; + +/* prototypes */ +static void box P((int filled, int x, int y, int wid, int hei, W_Color color)); +static void text P((int value, int y)); + +/* externals from ping.c (didn't feel like cluttering up data.c with them) */ +extern int ping_iloss_sc; /* inc % loss 0--100, server to client */ +extern int ping_iloss_cs; /* inc % loss 0--100, client to server */ +extern int ping_tloss_sc; /* total % loss 0--100, server to client */ +extern int ping_tloss_cs; /* total % loss 0--100, client to server */ +extern int ping_lag; /* delay in ms of last ping */ +extern int ping_av; /* average rt */ +extern int ping_sd; /* standard deviation */ + +int +pStatsHeight() +{ + return STAT_HEIGHT; +} + +int +pStatsWidth() +{ + return STAT_WIDTH; +} + +void +initPStats() +{ + int i; + + if (initialized) + return; + initialized = 1; + sliders[0].var = (int *) &ping_lag; + sliders[1].var = (int *) &ping_av; + sliders[2].var = (int *) &ping_sd; + sliders[3].var = (int *) &ping_iloss_sc; + sliders[4].var = (int *) &ping_iloss_cs; + sliders[5].var = (int *) &ping_tloss_sc; + sliders[6].var = (int *) &ping_tloss_cs; + + /* adjust */ + if (ping_av > 0) { + sliders[0].max = MAX(ping_av * 2, 200); + sliders[1].max = MAX(ping_av * 2, 200); + } + for (i = 0; i < NUM_SLIDERS; i++) { + sliders[i].label_length = strlen(sliders[i].label); + textWidth = MAX(textWidth, sliders[i].label_length); + sliders[i].diff = sliders[i].max - sliders[i].min; + sliders[i].lastVal = 0; + } +} + +void +redrawPStats() +{ + int i; + + W_ClearWindow(pStats); + initPStats(); + for (i = 0; i < NUM_SLIDERS; i++) { + sliders[i].lastVal = 0; + } + for (i = 0; i < NUM_SLIDERS; i++) { + W_WriteText(pStats, TX_OFF(sliders[i].label_length), TY_OFF(i), + textColor, sliders[i].label, sliders[i].label_length, + W_RegularFont); + box(0, BX_OFF() - 1, BY_OFF(i) - 1, SL_WID + 2, SL_HEI + 2, borderColor); + sliders[i].lastVal = 0; + } +} + +void +updatePStats() +{ + int i, value, diff, old_x, new_x; + W_Color color; + SLIDER *s; + + /* do the average and standard deviation calculations */ + initPStats(); + + for (i = 0; i < NUM_SLIDERS; i++) { + s = &sliders[i]; + value = *(s->var); + /* update decimal values at the right */ + text(*(s->var), BY_OFF(i)); + + if (value < s->min) + value = s->min; + else if (value > s->max) + value = s->max; + if (value == s->lastVal) + continue; + diff = value - s->lastVal; + if (diff < 0) { /* bar decreasing */ + old_x = s->lastVal * SL_WID / s->diff; + new_x = value * SL_WID / s->diff; + box(1, BX_OFF() + new_x, BY_OFF(i), old_x - new_x, SL_HEI, backColor); + + if (s->lastVal > s->green && value <= s->green) + box(1, BX_OFF(), BY_OFF(i), new_x, SL_HEI, gColor); + else if (s->lastVal > s->yellow && value <= s->yellow) + box(1, BX_OFF(), BY_OFF(i), new_x, SL_HEI, yColor); + } else { /* bar increasing */ + if (s->lastVal <= s->yellow && value > s->yellow) { + color = rColor; + s->lastVal = 0; + } else if (s->lastVal <= s->green && value > s->green) { + color = yColor; + s->lastVal = 0; + } else if (value > s->yellow) + color = rColor; + else if (value > s->green) + color = yColor; + else + color = gColor; + + old_x = s->lastVal * SL_WID / s->diff; + new_x = value * SL_WID / s->diff; + box(1, BX_OFF() + old_x, BY_OFF(i), new_x - old_x, SL_HEI, color); + } + s->lastVal = value; + } +} + +static +void +box(filled, x, y, wid, hei, color) + int filled, x, y, wid, hei; + W_Color color; +{ + if (wid == 0) + return; + + if (filled) { + /* XFIX */ + W_FillArea(pStats, x, y, wid + 1, hei + 1, color); + return; + } + W_MakeLine(pStats, x, y, x + wid, y, color); + W_MakeLine(pStats, x + wid, y, x + wid, y + hei, color); + W_MakeLine(pStats, x + wid, y + hei, x, y + hei, color); + W_MakeLine(pStats, x, y + hei, x, y, color); +} + +static +void +text(value, y) + int value, y; +{ + char buf[6]; + sprintf(buf, "(%3d)", value); /* fix */ + + W_WriteText(pStats, STAT_WIDTH - TEXT_WIDTH, y, textColor, + buf, 5, W_RegularFont); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/planetbitmaps.h Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,500 @@ +/* $Id: planetbitmaps.h,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +#define indplanet_width 30 +#define indplanet_height 30 +static unsigned char indplanet_bits[] = { + 0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x00, 0x60, 0x00, 0x20, 0x00, 0x80, + 0x00, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x04, 0x04, 0x00, + 0x00, 0x04, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x01, + 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, + 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, + 0x08, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x04, 0x04, 0x00, + 0x00, 0x04, 0x08, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0, +0x00, 0x60, 0x00, 0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; + +#define indmplanet_width 16 +#define indmplanet_height 16 +static unsigned char indmplanet_bits[] = { + 0xe0, 0x03, 0x18, 0x0c, 0x04, 0x10, 0x02, 0x20, 0x02, 0x20, 0x01, 0x40, 0x01, 0x40, 0x01, + 0x40, 0x01, 0x40, 0x01, 0x40, 0x02, 0x20, 0x02, 0x20, 0x04, 0x10, 0x18, 0x0c, 0xe0, 0x03, +0x00, 0x00}; + +static unsigned char planet_bits[] = { + 0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x00, 0x60, 0x00, 0x20, 0x00, 0x80, + 0x00, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x04, 0x04, 0xf0, + 0x03, 0x04, 0x02, 0xf8, 0x07, 0x08, 0x02, 0x1c, 0x0e, 0x08, 0x02, 0x0c, 0x0c, 0x08, 0x01, + 0x00, 0x0c, 0x10, 0x01, 0x00, 0x0e, 0x10, 0x01, 0x00, 0x07, 0x10, 0x01, 0x80, 0x03, 0x10, + 0x01, 0xc0, 0x01, 0x10, 0x01, 0xc0, 0x00, 0x10, 0x01, 0xc0, 0x00, 0x10, 0x02, 0xc0, 0x00, + 0x08, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x04, 0xc0, 0x00, 0x04, 0x04, 0xc0, + 0x00, 0x04, 0x08, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0, +0x00, 0x60, 0x00, 0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; + +#define fedplanet_width 30 +#define fedplanet_height 30 +static unsigned char fedplanet_bits[] = { + 0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x00, 0x60, 0x00, 0x20, 0x00, 0x80, + 0x00, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x04, 0x40, 0x00, 0x04, 0x04, 0xe0, + 0x00, 0x04, 0x02, 0xe0, 0x00, 0x08, 0x02, 0xf0, 0x01, 0x08, 0x02, 0xf0, 0x01, 0x08, 0x01, + 0xf8, 0x03, 0x10, 0x01, 0xf8, 0x03, 0x10, 0x01, 0xfc, 0x07, 0x10, 0x01, 0xfc, 0x07, 0x10, + 0x01, 0xfe, 0x0f, 0x10, 0x01, 0xbe, 0x0f, 0x10, 0x01, 0x1f, 0x1f, 0x10, 0x02, 0x0f, 0x1e, + 0x08, 0x82, 0x07, 0x3c, 0x08, 0x82, 0x03, 0x38, 0x08, 0x84, 0x01, 0x30, 0x04, 0x04, 0x00, + 0x00, 0x04, 0x08, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0, +0x00, 0x60, 0x00, 0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; + +#define oriplanet_width 30 +#define oriplanet_height 30 +static unsigned char oriplanet_bits[] = { + 0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x00, 0x60, 0x00, 0x20, 0xf8, 0x83, + 0x00, 0x10, 0xfe, 0x0f, 0x01, 0x08, 0x01, 0x10, 0x02, 0x04, 0x00, 0x00, 0x04, 0x44, 0x00, + 0x40, 0x04, 0x82, 0x01, 0x30, 0x08, 0x12, 0x07, 0x1c, 0x09, 0x12, 0xfe, 0x0f, 0x09, 0x11, + 0xfc, 0x07, 0x11, 0x19, 0xf8, 0x03, 0x13, 0x19, 0xf8, 0x03, 0x13, 0x19, 0xf0, 0x01, 0x13, + 0x19, 0xf0, 0x01, 0x13, 0x19, 0xf0, 0x01, 0x13, 0x39, 0xe0, 0x80, 0x13, 0x32, 0xe0, 0x80, + 0x09, 0x32, 0xe0, 0x80, 0x09, 0x62, 0xe0, 0xc0, 0x08, 0x64, 0xe0, 0xc0, 0x04, 0xc4, 0x40, + 0x60, 0x04, 0x88, 0x41, 0x30, 0x02, 0x10, 0x46, 0x0c, 0x01, 0x20, 0x48, 0x82, 0x00, 0xc0, +0x00, 0x60, 0x00, 0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; + +#define kliplanet_width 30 +#define kliplanet_height 30 +static unsigned char kliplanet_bits[] = { + 0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x40, 0x60, 0x00, 0x20, 0x40, 0x80, + 0x00, 0x10, 0x40, 0x00, 0x01, 0x08, 0x40, 0x00, 0x02, 0x04, 0x40, 0x00, 0x04, 0x04, 0x40, + 0x00, 0x04, 0x02, 0xe0, 0x00, 0x08, 0x02, 0xe0, 0x00, 0x08, 0x02, 0xe0, 0x00, 0x08, 0x01, + 0xf0, 0x01, 0x10, 0x01, 0xf0, 0x01, 0x10, 0x01, 0xf0, 0x01, 0x10, 0x01, 0xf8, 0x03, 0x10, + 0x01, 0xf0, 0x01, 0x10, 0x01, 0xe6, 0x0c, 0x10, 0x01, 0x4f, 0x1e, 0x10, 0x02, 0x1f, 0x3f, + 0x08, 0x82, 0x1f, 0x7f, 0x08, 0x82, 0x0f, 0xfe, 0x08, 0xc4, 0x07, 0xf8, 0x05, 0xc4, 0x01, + 0x00, 0x04, 0xc8, 0x00, 0x00, 0x02, 0x50, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0, +0x00, 0x60, 0x00, 0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; + +#define romplanet_width 30 +#define romplanet_height 30 +static unsigned char romplanet_bits[] = { + 0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x00, 0x60, 0x00, 0x20, 0x40, 0x80, + 0x00, 0x10, 0xe0, 0x00, 0x01, 0x08, 0xf8, 0x03, 0x02, 0x04, 0xa0, 0x00, 0x04, 0x04, 0xa0, + 0x00, 0x04, 0x02, 0xb0, 0x01, 0x08, 0x02, 0xac, 0x06, 0x08, 0x02, 0xaa, 0x09, 0x08, 0x01, + 0x4a, 0x09, 0x10, 0x01, 0x11, 0x11, 0x10, 0x01, 0x21, 0x11, 0x10, 0x01, 0x21, 0x11, 0x10, + 0x01, 0xc1, 0x10, 0x10, 0x01, 0x01, 0x16, 0x10, 0x01, 0x02, 0x09, 0x10, 0x02, 0x02, 0x09, + 0x08, 0x02, 0x0c, 0x06, 0x08, 0x02, 0xf0, 0x01, 0x08, 0x04, 0xa0, 0x00, 0x04, 0x04, 0xa0, + 0x00, 0x04, 0x08, 0xa0, 0x00, 0x02, 0x10, 0x40, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0, +0x00, 0x60, 0x00, 0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; + +static unsigned char mplanet_bits[] = { + 0xe0, 0x03, 0x18, 0x0c, 0x04, 0x10, 0x02, 0x20, 0xc2, 0x21, 0x21, 0x42, 0x01, 0x42, 0x01, + 0x41, 0x81, 0x40, 0x81, 0x40, 0x02, 0x20, 0x82, 0x20, 0x04, 0x10, 0x18, 0x0c, 0xe0, 0x03, +0x00, 0x00}; +#define klimplanet_width 16 +#define klimplanet_height 16 +static unsigned char klimplanet_bits[] = { + 0xe0, 0x03, 0x18, 0x0c, 0x84, 0x10, 0x82, 0x20, 0x82, 0x20, 0xc1, 0x41, + 0xc1, 0x41, 0xc1, 0x41, 0xb1, 0x42, 0x71, 0x47, 0x3a, 0x27, 0x0a, 0x2c, +0x04, 0x10, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00}; +#define rommplanet_width 16 +#define rommplanet_height 16 +static unsigned char rommplanet_bits[] = { + 0xe0, 0x03, 0x18, 0x0c, 0x84, 0x10, 0x82, 0x20, 0xc2, 0x21, 0xa1, 0x42, + 0x31, 0x45, 0xd1, 0x44, 0x11, 0x47, 0xa1, 0x42, 0xc2, 0x21, 0x82, 0x20, +0x84, 0x10, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00}; +#define orimplanet_width 16 +#define orimplanet_height 16 +static unsigned char orimplanet_bits[] = { + 0xe0, 0x03, 0x18, 0x0c, 0xc4, 0x11, 0xf2, 0x27, 0x02, 0x20, 0x39, 0x4e, 0xe1, 0x43, 0xc5, + 0x51, 0xcd, 0x59, 0x89, 0x48, 0x9a, 0x2c, 0x92, 0x24, 0xa4, 0x12, 0x18, 0x0c, 0xe0, 0x03, +0x00, 0x00}; +#define fedmplanet_width 16 +#define fedmplanet_height 16 +static unsigned char fedmplanet_bits[] = { + 0xe0, 0x03, 0x18, 0x0c, 0x04, 0x10, 0x02, 0x20, 0x82, 0x20, 0xc1, 0x41, + 0xc1, 0x41, 0xe1, 0x43, 0xe1, 0x43, 0x71, 0x47, 0x32, 0x26, 0x02, 0x20, +0x04, 0x10, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00}; + +#define mplanet111_width 16 +#define mplanet111_height 16 +static unsigned char mplanet111_bits[] = { + 0xe0, 0x03, 0x18, 0x0c, 0x44, 0x11, 0x5a, 0x21, 0xda, 0x21, 0x81, 0x4c, + 0x99, 0x54, 0xa5, 0x54, 0xbd, 0x54, 0xa5, 0x5c, 0xda, 0x21, 0x5a, 0x21, +0x44, 0x11, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00}; +#define mplanet110_width 16 +#define mplanet110_height 16 +static unsigned char mplanet110_bits[] = { + 0xe0, 0x03, 0x18, 0x0c, 0x44, 0x11, 0x5a, 0x21, 0xda, 0x21, 0x81, 0x40, + 0x99, 0x40, 0xa5, 0x40, 0xbd, 0x40, 0xa5, 0x40, 0xda, 0x21, 0x5a, 0x21, +0x44, 0x11, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00}; +#define mplanet101_width 16 +#define mplanet101_height 16 +static unsigned char mplanet101_bits[] = { + 0xe0, 0x03, 0x18, 0x0c, 0x04, 0x10, 0x1a, 0x20, 0x1a, 0x20, 0x01, 0x4c, + 0x19, 0x54, 0x25, 0x54, 0x3d, 0x54, 0x25, 0x5c, 0x1a, 0x20, 0x1a, 0x20, +0x04, 0x10, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00}; +#define mplanet100_width 16 +#define mplanet100_height 16 +static unsigned char mplanet100_bits[] = { + 0xe0, 0x03, 0x18, 0x0c, 0x04, 0x10, 0x1a, 0x20, 0x1a, 0x20, 0x01, 0x40, + 0x19, 0x40, 0x25, 0x40, 0x3d, 0x40, 0x25, 0x40, 0x1a, 0x20, 0x1a, 0x20, +0x04, 0x10, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00}; +#define mplanet011_width 16 +#define mplanet011_height 16 +static unsigned char mplanet011_bits[] = { + 0xe0, 0x03, 0x18, 0x0c, 0x44, 0x11, 0x42, 0x21, 0xc2, 0x21, 0x81, 0x4c, + 0x81, 0x54, 0x81, 0x54, 0x81, 0x54, 0x81, 0x5c, 0xc2, 0x21, 0x42, 0x21, +0x44, 0x11, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00}; +#define mplanet010_width 16 +#define mplanet010_height 16 +static unsigned char mplanet010_bits[] = { + 0xe0, 0x03, 0x18, 0x0c, 0x44, 0x11, 0x42, 0x21, 0xc2, 0x21, 0x81, 0x40, + 0x81, 0x40, 0x81, 0x40, 0x81, 0x40, 0x81, 0x40, 0xc2, 0x21, 0x42, 0x21, +0x44, 0x11, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00}; +#define mplanet001_width 16 +#define mplanet001_height 16 +static unsigned char mplanet001_bits[] = { + 0xe0, 0x03, 0x18, 0x0c, 0x04, 0x10, 0x02, 0x20, 0x02, 0x20, 0x01, 0x4c, + 0x01, 0x54, 0x01, 0x54, 0x01, 0x54, 0x01, 0x5c, 0x02, 0x20, 0x02, 0x20, +0x04, 0x10, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00}; + +#define mplanet1111_width 16 +#define mplanet1111_height 16 +static unsigned char mplanet1111_bits[] = { + 0xe0, 0x03, 0x18, 0x0c, 0x44, 0x11, 0xda, 0x21, 0x9a, 0x20, 0xc1, 0x4d, + 0x59, 0x55, 0x25, 0x54, 0x3d, 0x54, 0xa5, 0x5c, 0x9a, 0x23, 0xda, 0x21, +0x04, 0x11, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00}; + +#define mplanet1110_width 16 +#define mplanet1110_height 16 +static unsigned char mplanet1110_bits[] = { + 0xe0, 0x03, 0x18, 0x0c, 0x44, 0x11, 0xda, 0x21, 0x9a, 0x20, 0xc1, 0x41, + 0x59, 0x41, 0x25, 0x40, 0x3d, 0x40, 0xa5, 0x40, 0x9a, 0x23, 0xda, 0x21, +0x04, 0x11, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00}; + +#define mplanet1010_width 16 +#define mplanet1010_height 16 +static unsigned char mplanet1010_bits[] = { + 0xe0, 0x03, 0x18, 0x0c, 0x44, 0x11, 0xc2, 0x21, 0x82, 0x20, 0xc1, 0x41, + 0x41, 0x41, 0x01, 0x40, 0x01, 0x40, 0x81, 0x40, 0x82, 0x23, 0xc2, 0x21, +0x04, 0x11, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00}; + +#define mplanet1011_width 16 +#define mplanet1011_height 16 +static unsigned char mplanet1011_bits[] = { + 0xe0, 0x03, 0x18, 0x0c, 0x44, 0x11, 0xc2, 0x21, 0x82, 0x20, 0xc1, 0x4d, + 0x41, 0x55, 0x01, 0x54, 0x01, 0x54, 0x81, 0x5c, 0x82, 0x23, 0xc2, 0x21, +0x04, 0x11, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00}; + +#define planet111_width 30 +#define planet111_height 30 +static unsigned char planet111_bits[] = { + 0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x10, 0x61, 0x00, + 0x20, 0x18, 0x83, 0x00, 0x10, 0x18, 0x03, 0x01, 0x08, 0x18, 0x03, 0x02, + 0x04, 0xf8, 0x03, 0x04, 0xe4, 0xf8, 0x03, 0x04, 0xe2, 0xe0, 0xf8, 0x08, + 0xe2, 0xe0, 0x08, 0x09, 0x42, 0x40, 0x08, 0x0a, 0xf9, 0xe3, 0xa8, 0x12, + 0xf5, 0x45, 0x48, 0x12, 0x55, 0xe5, 0xa8, 0x12, 0xf5, 0x45, 0x08, 0x12, + 0x55, 0xe5, 0x08, 0x12, 0xf5, 0x45, 0x08, 0x12, 0xb1, 0xe1, 0x08, 0x12, + 0xb2, 0x41, 0xf8, 0x0b, 0xb2, 0xe1, 0x00, 0x08, 0xb2, 0xe1, 0x00, 0x08, + 0xb4, 0xf9, 0x03, 0x04, 0x04, 0xf8, 0x03, 0x04, 0x08, 0x18, 0x03, 0x02, + 0x10, 0x18, 0x03, 0x01, 0x20, 0x18, 0x83, 0x00, 0xc0, 0x10, 0x61, 0x00, +0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; +#define planet110_width 30 +#define planet110_height 30 +static unsigned char planet110_bits[] = { + 0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x10, 0x61, 0x00, + 0x20, 0x18, 0x83, 0x00, 0x10, 0x18, 0x03, 0x01, 0x08, 0x18, 0x03, 0x02, + 0x04, 0xf8, 0x03, 0x04, 0xe4, 0xf8, 0x03, 0x04, 0xe2, 0xe0, 0x00, 0x08, + 0xe2, 0xe0, 0x00, 0x08, 0x42, 0x40, 0x00, 0x08, 0xf9, 0xe3, 0x00, 0x10, + 0xf5, 0x45, 0x00, 0x10, 0x55, 0xe5, 0x00, 0x10, 0xf5, 0x45, 0x00, 0x10, + 0x55, 0xe5, 0x00, 0x10, 0xf5, 0x45, 0x00, 0x10, 0xb1, 0xe1, 0x00, 0x10, + 0xb2, 0x41, 0x00, 0x08, 0xb2, 0xe1, 0x00, 0x08, 0xb2, 0xe1, 0x00, 0x08, + 0xb4, 0xf9, 0x03, 0x04, 0x04, 0xf8, 0x03, 0x04, 0x08, 0x18, 0x03, 0x02, + 0x10, 0x18, 0x03, 0x01, 0x20, 0x18, 0x83, 0x00, 0xc0, 0x10, 0x61, 0x00, +0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; +#define planet101_width 30 +#define planet101_height 30 +static unsigned char planet101_bits[] = { + 0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x00, 0x60, 0x00, + 0x20, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, + 0x04, 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x04, 0xe2, 0x00, 0xf8, 0x08, + 0xe2, 0x00, 0x08, 0x09, 0x42, 0x00, 0x08, 0x0a, 0xf9, 0x03, 0xa8, 0x12, + 0xf5, 0x05, 0x48, 0x12, 0x55, 0x05, 0xa8, 0x12, 0xf5, 0x05, 0x08, 0x12, + 0x55, 0x05, 0x08, 0x12, 0xf5, 0x05, 0x08, 0x12, 0xb1, 0x01, 0x08, 0x12, + 0xb2, 0x01, 0xf8, 0x0b, 0xb2, 0x01, 0x00, 0x08, 0xb2, 0x01, 0x00, 0x08, + 0xb4, 0x01, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x02, + 0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0, 0x00, 0x60, 0x00, +0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; +#define planet100_width 30 +#define planet100_height 30 +static unsigned char planet100_bits[] = { + 0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x00, 0x60, 0x00, + 0x20, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, + 0x04, 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x08, + 0xe2, 0x00, 0x00, 0x08, 0x42, 0x00, 0x00, 0x08, 0xf9, 0x03, 0x00, 0x10, + 0xf5, 0x05, 0x00, 0x10, 0x55, 0x05, 0x00, 0x10, 0xf5, 0x05, 0x00, 0x10, + 0x55, 0x05, 0x00, 0x10, 0xf5, 0x05, 0x00, 0x10, 0xb1, 0x01, 0x00, 0x10, + 0xb2, 0x01, 0x00, 0x08, 0xb2, 0x01, 0x00, 0x08, 0xb2, 0x01, 0x00, 0x08, + 0xb4, 0x01, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x02, + 0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0, 0x00, 0x60, 0x00, +0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; +#define planet011_width 30 +#define planet011_height 30 +static unsigned char planet011_bits[] = { + 0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x10, 0x61, 0x00, + 0x20, 0x18, 0x83, 0x00, 0x10, 0x18, 0x03, 0x01, 0x08, 0x18, 0x03, 0x02, + 0x04, 0xf8, 0x03, 0x04, 0x04, 0xf8, 0x03, 0x04, 0x02, 0xe0, 0xf8, 0x08, + 0x02, 0xe0, 0x08, 0x09, 0x02, 0x40, 0x08, 0x0a, 0x01, 0xe0, 0xa8, 0x12, + 0x01, 0x40, 0x48, 0x12, 0x01, 0xe0, 0xa8, 0x12, 0x01, 0x40, 0x08, 0x12, + 0x01, 0xe0, 0x08, 0x12, 0x01, 0x40, 0x08, 0x12, 0x01, 0xe0, 0x08, 0x12, + 0x02, 0x40, 0xf8, 0x0b, 0x02, 0xe0, 0x00, 0x08, 0x02, 0xe0, 0x00, 0x08, + 0x04, 0xf8, 0x03, 0x04, 0x04, 0xf8, 0x03, 0x04, 0x08, 0x18, 0x03, 0x02, + 0x10, 0x18, 0x03, 0x01, 0x20, 0x18, 0x83, 0x00, 0xc0, 0x10, 0x61, 0x00, +0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; +#define planet010_width 30 +#define planet010_height 30 +static unsigned char planet010_bits[] = { + 0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x10, 0x61, 0x00, + 0x20, 0x18, 0x83, 0x00, 0x10, 0x18, 0x03, 0x01, 0x08, 0x18, 0x03, 0x02, + 0x04, 0xf8, 0x03, 0x04, 0x04, 0xf8, 0x03, 0x04, 0x02, 0xe0, 0x00, 0x08, + 0x02, 0xe0, 0x00, 0x08, 0x02, 0x40, 0x00, 0x08, 0x01, 0xe0, 0x00, 0x10, + 0x01, 0x40, 0x00, 0x10, 0x01, 0xe0, 0x00, 0x10, 0x01, 0x40, 0x00, 0x10, + 0x01, 0xe0, 0x00, 0x10, 0x01, 0x40, 0x00, 0x10, 0x01, 0xe0, 0x00, 0x10, + 0x02, 0x40, 0x00, 0x08, 0x02, 0xe0, 0x00, 0x08, 0x02, 0xe0, 0x00, 0x08, + 0x04, 0xf8, 0x03, 0x04, 0x04, 0xf8, 0x03, 0x04, 0x08, 0x18, 0x03, 0x02, + 0x10, 0x18, 0x03, 0x01, 0x20, 0x18, 0x83, 0x00, 0xc0, 0x10, 0x61, 0x00, +0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; +#define planet001_width 30 +#define planet001_height 30 +static unsigned char planet001_bits[] = { + 0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x00, 0x60, 0x00, + 0x20, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, + 0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0xf8, 0x08, + 0x02, 0x00, 0x08, 0x09, 0x02, 0x00, 0x08, 0x0a, 0x01, 0x00, 0xa8, 0x12, + 0x01, 0x00, 0x48, 0x12, 0x01, 0x00, 0xa8, 0x12, 0x01, 0x00, 0x08, 0x12, + 0x01, 0x00, 0x08, 0x12, 0x01, 0x00, 0x08, 0x12, 0x01, 0x00, 0x08, 0x12, + 0x02, 0x00, 0xf8, 0x0b, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, + 0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x02, + 0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0, 0x00, 0x60, 0x00, +0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; + +#define planet1111_width 30 +#define planet1111_height 30 +static unsigned char planet1111_bits[] = { + 0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0xa0, 0x60, 0x00, + 0x20, 0xb0, 0x81, 0x00, 0x10, 0xb0, 0x01, 0x01, 0x08, 0xf0, 0x01, 0x02, + 0x04, 0x40, 0x00, 0x04, 0xe4, 0xe0, 0x00, 0x04, 0xe2, 0x40, 0xf8, 0x08, + 0xe2, 0xe0, 0x08, 0x09, 0x42, 0x40, 0x08, 0x0a, 0xf9, 0xe3, 0xa8, 0x12, + 0xf5, 0x45, 0x48, 0x12, 0x55, 0xf5, 0xa9, 0x12, 0xf5, 0xb5, 0x09, 0x12, + 0x55, 0xb5, 0x09, 0x12, 0xf5, 0xa5, 0x08, 0x12, 0xb1, 0x01, 0x08, 0x12, + 0xb2, 0x91, 0xf9, 0x0b, 0xb2, 0xf1, 0x00, 0x08, 0xb2, 0xf5, 0x07, 0x08, + 0xb4, 0x1d, 0x03, 0x04, 0x04, 0x18, 0x03, 0x04, 0x08, 0x18, 0x07, 0x02, + 0x10, 0xfc, 0x05, 0x01, 0x20, 0xe0, 0x81, 0x00, 0xc0, 0x30, 0x61, 0x00, +0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; + +#define planet1110_width 30 +#define planet1110_height 30 +static unsigned char planet1110_bits[] = { + 0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0xa0, 0x60, 0x00, + 0x20, 0xb0, 0x81, 0x00, 0x10, 0xb0, 0x01, 0x01, 0x08, 0xf0, 0x01, 0x02, + 0x04, 0x40, 0x00, 0x04, 0xe4, 0xe0, 0x00, 0x04, 0xe2, 0x40, 0x00, 0x08, + 0xe2, 0xe0, 0x00, 0x08, 0x42, 0x40, 0x00, 0x08, 0xf9, 0xe3, 0x00, 0x10, + 0xf5, 0x45, 0x00, 0x10, 0x55, 0xf5, 0x01, 0x10, 0xf5, 0xb5, 0x01, 0x10, + 0x55, 0xb5, 0x01, 0x10, 0xf5, 0xa5, 0x00, 0x10, 0xb1, 0x01, 0x00, 0x10, + 0xb2, 0x91, 0x01, 0x08, 0xb2, 0xf1, 0x00, 0x08, 0xb2, 0xf5, 0x07, 0x08, + 0xb4, 0x1d, 0x03, 0x04, 0x04, 0x18, 0x03, 0x04, 0x08, 0x18, 0x07, 0x02, + 0x10, 0xfc, 0x05, 0x01, 0x20, 0xe0, 0x81, 0x00, 0xc0, 0x30, 0x61, 0x00, +0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; + +#define planet1010_width 30 +#define planet1010_height 30 +static unsigned char planet1010_bits[] = { + 0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0xa0, 0x60, 0x00, + 0x20, 0xb0, 0x81, 0x00, 0x10, 0xb0, 0x01, 0x01, 0x08, 0xf0, 0x01, 0x02, + 0x04, 0x40, 0x00, 0x04, 0x04, 0xe0, 0x00, 0x04, 0x02, 0x40, 0x00, 0x08, + 0x02, 0xe0, 0x00, 0x08, 0x02, 0x40, 0x00, 0x08, 0x01, 0xe0, 0x00, 0x10, + 0x01, 0x40, 0x00, 0x10, 0x01, 0xf0, 0x01, 0x10, 0x01, 0xb0, 0x01, 0x10, + 0x01, 0xb0, 0x01, 0x10, 0x01, 0xa0, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, + 0x02, 0x90, 0x01, 0x08, 0x02, 0xf0, 0x00, 0x08, 0x02, 0xf4, 0x07, 0x08, + 0x04, 0x1c, 0x03, 0x04, 0x04, 0x18, 0x03, 0x04, 0x08, 0x18, 0x07, 0x02, + 0x10, 0xfc, 0x05, 0x01, 0x20, 0xe0, 0x81, 0x00, 0xc0, 0x30, 0x61, 0x00, +0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; + +#define planet1011_width 30 +#define planet1011_height 30 +static unsigned char planet1011_bits[] = { + 0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0xa0, 0x60, 0x00, + 0x20, 0xb0, 0x81, 0x00, 0x10, 0xb0, 0x01, 0x01, 0x08, 0xf0, 0x01, 0x02, + 0x04, 0x40, 0x00, 0x04, 0x04, 0xe0, 0x00, 0x04, 0x02, 0x40, 0xf8, 0x08, + 0x02, 0xe0, 0x08, 0x09, 0x02, 0x40, 0x08, 0x0a, 0x01, 0xe0, 0xa8, 0x12, + 0x01, 0x40, 0x48, 0x12, 0x01, 0xf0, 0xa9, 0x12, 0x01, 0xb0, 0x09, 0x12, + 0x01, 0xb0, 0x09, 0x12, 0x01, 0xa0, 0x08, 0x12, 0x01, 0x00, 0x08, 0x12, + 0x02, 0x90, 0xf9, 0x0b, 0x02, 0xf0, 0x00, 0x08, 0x02, 0xf4, 0x07, 0x08, + 0x04, 0x1c, 0x03, 0x04, 0x04, 0x18, 0x03, 0x04, 0x08, 0x18, 0x07, 0x02, + 0x10, 0xfc, 0x05, 0x01, 0x20, 0xe0, 0x81, 0x00, 0xc0, 0x30, 0x61, 0x00, +0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; + +#if 0 +static unsigned char shield_bits[] = { + 0xc0, 0x3f, 0x00, 0x30, 0xc0, 0x00, 0x08, 0x00, 0x01, 0x04, 0x00, 0x02, + 0x02, 0x00, 0x04, 0x02, 0x00, 0x04, 0x01, 0x00, 0x08, 0x01, 0x00, 0x08, + 0x01, 0x00, 0x08, 0x01, 0x00, 0x08, 0x01, 0x00, 0x08, 0x01, 0x00, 0x08, + 0x01, 0x00, 0x08, 0x01, 0x00, 0x08, 0x02, 0x00, 0x04, 0x02, 0x00, 0x04, +0x04, 0x00, 0x02, 0x08, 0x00, 0x01, 0x30, 0xc0, 0x00, 0xc0, 0x3f, 0x00}; +#endif + +static unsigned char cloak_bits[] = { + 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x08, 0x82, 0x00, + 0x04, 0x00, 0x01, 0x20, 0x20, 0x00, 0x00, 0x02, 0x00, 0x80, 0x08, 0x00, + 0x01, 0x00, 0x04, 0x49, 0x90, 0x04, 0x01, 0x00, 0x04, 0x80, 0x08, 0x00, + 0x00, 0x02, 0x00, 0x20, 0x20, 0x00, 0x04, 0x00, 0x01, 0x08, 0x82, 0x00, +0x10, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00}; + +#define starm_width 16 +#define starm_height 16 +static unsigned char starm_bits[] = { + 0x40, 0x00, 0x8c, 0x00, 0xc8, 0x10, 0xf8, 0x1b, 0x18, 0x0c, 0x28, 0x0b, + 0x6d, 0x28, 0x4e, 0x7c, 0x08, 0x19, 0x28, 0x09, 0x1c, 0x07, 0xe4, 0x0f, +0x86, 0x18, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00}; + +#define star_width 30 +#define star_height 30 +static unsigned char star_bits[] = { + 0x00, 0x20, 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0xc0, 0x10, 0xc0, 0x00, + 0x80, 0x10, 0x42, 0x00, 0x80, 0x30, 0x63, 0x00, 0x80, 0xfb, 0x3b, 0x00, + 0x00, 0x07, 0x3c, 0x00, 0x00, 0x0f, 0x34, 0x00, 0xfc, 0x09, 0x24, 0x00, + 0xc4, 0x18, 0x60, 0x1d, 0x46, 0x11, 0xc8, 0x17, 0x60, 0x03, 0x8c, 0x03, + 0x60, 0x00, 0x86, 0x00, 0x20, 0x84, 0x83, 0x00, 0x20, 0xd0, 0xb8, 0x00, + 0x3c, 0x1e, 0xa0, 0x14, 0x7e, 0x9c, 0x80, 0x06, 0x72, 0x82, 0xc4, 0x03, + 0x60, 0x80, 0xc8, 0x01, 0x40, 0xc0, 0x70, 0x00, 0xc0, 0x60, 0xf0, 0x00, + 0xc0, 0x23, 0xd8, 0x00, 0x80, 0x77, 0xce, 0x03, 0x80, 0xfc, 0x07, 0x06, + 0xc0, 0x40, 0x06, 0x04, 0xc0, 0x60, 0x0c, 0x00, 0x40, 0x10, 0x18, 0x00, +0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00}; + +#if 0 +#define holem_width 16 +#define holem_height 16 +static unsigned char holem_bits[] = { + 0xf0, 0x0f, 0x08, 0x10, 0xe4, 0x27, 0x12, 0x48, 0xc9, 0x93, 0x25, 0xa4, + 0x95, 0xa9, 0x55, 0xaa, 0x55, 0xa9, 0x55, 0xa4, 0x95, 0x93, 0x25, 0x48, + 0xc9, 0x27, 0x12, 0x10, 0xe4, 0x0f, 0x08, 0x00}; + +#define holem_width 16 +#define holem_height 16 +static char holem_bits[] = { + 0x10, 0x11, 0x20, 0x12, 0x40, 0x12, 0x87, 0x0a, 0x98, 0x8a, 0x20, 0x45, + 0x5e, 0x23, 0xe1, 0x19, 0x98, 0x87, 0xc4, 0x7a, 0xa2, 0x04, 0x51, 0x19, + 0x50, 0xe1, 0x48, 0x02, 0x48, 0x04, 0x88, 0x08}; +#endif /*0*/ + +#ifdef VISIBLE_WORMHOLES +#define holem_width 16 +#define holem_height 16 +static char holem_bits[] = { + 0x00, 0x01, 0x20, 0x02, 0x40, 0x12, 0x84, 0x0a, 0x98, 0x0a, 0x20, 0x45, + 0x5e, 0x23, 0xe1, 0x19, 0x98, 0x87, 0xc4, 0x7a, 0xa2, 0x04, 0x50, 0x19, + 0x50, 0x21, 0x48, 0x02, 0x40, 0x04, 0x80, 0x00}; +#endif /*VISIBLE_WORMHOLES*/ + +#define asteroid_width 30 +#define asteroid_height 30 +static unsigned char asteroid_bits[] = { + 0x00, 0xf0, 0x01, 0x00, 0x00, 0x0e, 0x1e, 0x00, 0x80, 0x01, 0x20, 0x00, + 0x40, 0x00, 0x41, 0x00, 0x30, 0x06, 0x80, 0x01, 0x10, 0x09, 0x00, 0x01, + 0x88, 0x10, 0x10, 0x02, 0x84, 0x10, 0x28, 0x04, 0x04, 0x09, 0x10, 0x04, + 0x02, 0x86, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x10, + 0x11, 0x02, 0x00, 0x11, 0x01, 0x20, 0x80, 0x20, 0x01, 0x50, 0x00, 0x20, + 0x01, 0x20, 0x00, 0x28, 0x01, 0x00, 0x39, 0x34, 0x82, 0x04, 0x44, 0x34, + 0x02, 0x00, 0x44, 0x28, 0x02, 0x00, 0x44, 0x20, 0x1c, 0x08, 0x38, 0x10, + 0xe0, 0x00, 0x00, 0x10, 0x00, 0xc1, 0x01, 0x10, 0x00, 0x22, 0x22, 0x08, + 0x00, 0xc2, 0x01, 0x06, 0x00, 0x02, 0x80, 0x01, 0x00, 0x02, 0x60, 0x00, +0x00, 0x0e, 0x10, 0x00, 0x00, 0x70, 0x08, 0x00, 0x00, 0x80, 0x07, 0x00}; + +#define masteroid_width 16 +#define masteroid_height 16 +static unsigned char masteroid_bits[] = { + 0xe0, 0x07, 0x18, 0x08, 0x34, 0x30, 0x4a, 0x2c, 0x4a, 0x4c, 0x31, 0x40, + 0x05, 0x80, 0xc1, 0x90, 0xc1, 0xc4, 0x11, 0xca, 0x07, 0x84, 0x1c, 0x81, +0xb0, 0x4a, 0x30, 0x31, 0x60, 0x0c, 0xc0, 0x07}; + +#define age_width 16 +#define age_height 16 +static unsigned char age_bits[NSCOUTAGES][32] = { + { + 0xe0, 0x03, 0x18, 0x0c, 0x04, 0x10, 0x02, 0x20, 0x02, 0x20, 0x01, 0x40, + 0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x02, 0x20, 0x02, 0x20, + 0x04, 0x10, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00}, + { + 0xe0, 0x03, 0x18, 0x0c, 0xac, 0x12, 0x02, 0x20, 0xaa, 0x2a, 0x01, 0x40, + 0xab, 0x6a, 0x01, 0x40, 0xab, 0x6a, 0x01, 0x40, 0xaa, 0x2a, 0x02, 0x20, + 0xac, 0x1a, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00}, + { + 0xe0, 0x03, 0x58, 0x0d, 0xac, 0x1a, 0x56, 0x35, 0xaa, 0x2a, 0x55, 0x55, + 0xab, 0x6a, 0x55, 0x55, 0xab, 0x6a, 0x55, 0x55, 0xaa, 0x2a, 0x56, 0x35, + 0xac, 0x1a, 0x58, 0x0d, 0xe0, 0x03, 0x00, 0x00}, + { + 0xe0, 0x03, 0x58, 0x0d, 0xfc, 0x1f, 0x56, 0x35, 0xfe, 0x3f, 0x55, 0x55, + 0xff, 0x7f, 0x55, 0x55, 0xff, 0x7f, 0x55, 0x55, 0xfe, 0x3f, 0x56, 0x35, + 0xfc, 0x1f, 0x58, 0x0d, 0xe0, 0x03, 0x00, 0x00}, + { + 0xe0, 0x03, 0xf8, 0x0f, 0xfc, 0x1f, 0xfe, 0x3f, 0xfe, 0x3f, 0xff, 0x7f, + 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xfe, 0x3f, 0xfe, 0x3f, + 0xfc, 0x1f, 0xf8, 0x0f, 0xe0, 0x03, 0x00, 0x00} +}; + +/* MOO-style bitmaps extended to paradise -RF */ +#define rmyplanet1010_width 30 +#define rmyplanet1010_height 30 +static unsigned char rmyplanet1010_bits[] = { + 0x01, 0x18, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x60, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, + 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, + 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02, + 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x60, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; +#define rmyplanet1011_width 30 +#define rmyplanet1011_height 30 +static unsigned char rmyplanet1011_bits[] = { + 0x01, 0x18, 0x03, 0x07, 0x02, 0x00, 0x00, 0x05, 0xc4, 0x00, 0x60, 0x07, + 0x18, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, + 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, + 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02, + 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x60, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; +#define rmyplanet1110_width 30 +#define rmyplanet1110_height 30 +static unsigned char rmyplanet1110_bits[] = { + 0x01, 0xf8, 0x03, 0x00, 0x02, 0x07, 0x1c, 0x00, 0xc4, 0x00, 0x60, 0x00, + 0x28, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, + 0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x08, + 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x10, + 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, + 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, + 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, + 0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x02, + 0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0, 0x00, 0x60, 0x00, +0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; +#define rmyplanet1111_width 30 +#define rmyplanet1111_height 30 +static unsigned char rmyplanet1111_bits[] = { + 0x01, 0xf8, 0x03, 0x07, 0x02, 0x07, 0x1c, 0x05, 0xc4, 0x00, 0x60, 0x07, + 0x28, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x08, + 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x10, + 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, + 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, + 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, + 0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x02, + 0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0, 0x00, 0x60, 0x00, +0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; +#define rmymplanet1010_width 16 +#define rmymplanet1010_height 16 +static unsigned char rmymplanet1010_bits[] = { + 0xa0, 0x02, 0x08, 0x08, 0x40, 0x01, 0xc2, 0x21, 0x80, 0x00, 0xc1, 0x41, + 0x40, 0x01, 0x01, 0x40, 0x00, 0x00, 0x81, 0x40, 0x80, 0x03, 0xc2, 0x21, +0x00, 0x01, 0x08, 0x08, 0xa0, 0x02, 0x00, 0x00}; +#define rmymplanet1011_width 16 +#define rmymplanet1011_height 16 +static unsigned char rmymplanet1011_bits[] = { + 0xa0, 0x02, 0x08, 0x08, 0x40, 0x01, 0xc2, 0x21, 0x80, 0x00, 0xc1, 0x4d, + 0x40, 0x15, 0x01, 0x54, 0x00, 0x14, 0x81, 0x5c, 0x80, 0x03, 0xc2, 0x21, +0x00, 0x01, 0x08, 0x08, 0xa0, 0x02, 0x00, 0x00};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/planetlist.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,256 @@ +/* $Id: planetlist.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */ + +/* + * planetlist.c + */ +#include "copyright.h" +#include <stdio.h> +#include <string.h> + +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "proto.h" + +/* Prototypes */ +static void planet_list_paradise P((void)); +static void planet_list_normal P((void)); +static void print_planet P((W_Window wind, int line, struct planet * j)); + +static char *teamname[5] = { + "IND", + "FED", + "ROM", + "KLI", + "ORI" +}; + +/* +** Open a window which contains all the planets and their current +** statistics. Players will not know about planets that their team +** has not orbited. +*/ + +void +planetlist() +{ + /* + W_ClearWindow(planetw); + */ + if (!paradise) { /* if not a paradise server then */ + planet_list_normal(); + } else { /* else must be a paradise server */ + planet_list_paradise(); + } +} + + +/*This function provides the planet list for a normal server. */ + +static void +planet_list_normal() +{ + int k = 0; /* for row number */ + int i; /* looping var */ + struct planet *j; /* to point to a planet */ + char buf[100]; /* to sprintf into */ + char buf1[40]; + W_Window wind; + + wind = planetw; + + for (i = 0, j = &planets[i]; i < nplanets; i++, j++) { + if (i == 0 || i == nplanets / 2) { + if (i != 0) { + wind = planetw2; + } + sprintf(buf, "Planet name Own Armies Resources Info"); + W_WriteText(wind, 2, 1, textColor, buf, strlen(buf), W_RegularFont); + k = 2; + } + sprintf(buf1, "%-16s ", j->pl_name); + if (j->pl_info & idx_to_mask(me->p_teami)) { + sprintf(buf, "%3s %3d %s%s%s %s ", + teamname[mask_to_idx(j->pl_owner) + 1], + j->pl_armies, + (j->pl_flags & PLREPAIR ? "REPR " : " "), + (j->pl_flags & PLFUEL ? "FUEL " : " "), + (j->pl_flags & PLAGRI ? "AGRI " : " "), + team_bit_string(j->pl_info)); + W_WriteText(wind, 2, k, planetColor(j), buf1, strlen(buf1), + planetFont(j)); + W_WriteText(wind, 24, k++, planetColor(j), buf, strlen(buf), + planetFont(j)); + } + /* end of have info */ + else { /* else no info on planet */ + W_WriteText(wind, 2, k++, planetColor(j), buf1, strlen(buf1), + planetFont(j)); + } + } /* end of for loop */ + +} + + + +/*This function provides the planet list for a paradise server version 2.0 */ + +static void +planet_list_paradise() +{ + typedef struct planet *plptr; + + int k = 0; /* for row number */ + int i, team_pnum; /* looping var */ + plptr j; /* to point to a planet */ + char buf[100]; /* to sprintf into */ + W_Window wind; + extern int number_of_teams; + plptr **team_p; + int *team_pcount; + + wind = planetw; + + /* this malloc stuff will handle any number of teams/races */ + + /* team's planet counters */ + team_pcount = (int *) malloc((number_of_teams + 1) * sizeof(int)); + for (i = 0; i < number_of_teams + 1; i++) + team_pcount[i] = 0; + + if (mapSort) { + /* make some memory */ + team_p = (plptr **) malloc((number_of_teams + 1) * sizeof(struct planet *)); + for (i = 0; i < (number_of_teams + 1); i++) + team_p[i] = (plptr *) malloc(nplanets * sizeof(struct planet *)); + + /* loop thru and put proper team planeter point on each planet */ + for (i = 0, j = &planets[i]; i < nplanets; i++, j++) { + k = mask_to_idx(j->pl_owner) + 1; /* which team gets planet */ + team_p[k][team_pcount[k]] = j; + team_pcount[k]++; + } + + /* go thru each teams planet list and display */ + for (i = 0, k = 0; i < (number_of_teams + 1); i++) { + for (team_pnum = 0; team_pnum < team_pcount[i]; team_pnum++, k++) { + + j = team_p[i][team_pnum]; + /* (nplanets+13)/2 is the height of window; from newwin.c */ + if (k == 0 || k >= ((nplanets + 13) / 2)) { + if (k != 0) + wind = planetw2; + sprintf(buf, "Planet name sctr own armies RESOURCES SURFC ATMOS VISIT TIME"); + W_WriteText(wind, 2, 1, textColor, buf, strlen(buf), W_RegularFont); + k = 2; + } + print_planet(wind, k, j); + } /* end of 2nd for */ + if (team_pcount[i] > 0) + k++; + } /* end of 1st for */ + + for (i = 0; i < (number_of_teams + 1); i++) + free(team_p[i]); + free(team_p); + } else { /* do the original alpa only sort planet list */ + + for (i = 0, j = &planets[i]; i < nplanets; i++, j++, k++) { + if (i == 0 || i == nplanets / 2) { + + sprintf(buf, "Planet name sctr own armies RESOURCES SURFC ATMOS VISIT TIME"); + + if (i != 0) { + wind = planetw2; + } + W_WriteText(wind, 2, 1, textColor, buf, strlen(buf), W_RegularFont); + k = 2; + } + team_pcount[mask_to_idx(j->pl_owner) + 1]++; + print_planet(wind, k, j); + } + } + + k++; + for (i = 0; i < (number_of_teams + 1); i++) { + W_Color cur_color; + + cur_color = shipCol[i]; + sprintf(buf, "%s: ", teamname[i]); + W_WriteText(wind, i * 7 + 2, k, cur_color, buf, strlen(buf), W_RegularFont); + sprintf(buf, " %.2i", team_pcount[i]); + W_WriteText(wind, i * 7 + 2, k + 1, cur_color, buf, strlen(buf), W_RegularFont); + } + + free(team_pcount); + +} /* end of planet_list_paradise */ + + +/****************************** print_planet() ************************/ +static void +print_planet(wind, line, j) + W_Window wind; + int line; + struct planet *j; +{ + char buf[100]; /* to sprintf into */ + + sprintf(buf, "%-16s %d-%d", j->pl_name, (j->pl_x / GRIDSIZE) + 1, + (j->pl_y / GRIDSIZE) + 1); + W_WriteText(wind, 2, line, textColor, buf, strlen(buf), + W_RegularFont); + + if (j->pl_info & idx_to_mask(me->p_teami)) { + if (PL_TYPE(*j) == PLSTAR) { /* if planet actually a star */ + W_WriteText(wind, 24, line, textColor, "---S T A R---", 13, + W_RegularFont); + } else if (PL_TYPE(*j) == PLWHOLE) { /* if wormhole... */ + W_WriteText(wind, 24, line, textColor, "---W O R M H O L E---", 21, + W_RegularFont); + } else { /* else planet not a star */ + char *s = NULL; + + switch (j->pl_flags & PLATMASK) { + case PLPOISON: + s = "TOXC"; + break; + case PLATYPE3: + s = "TNTD"; + break; + case PLATYPE2: + s = "THIN"; + break; + case PLATYPE1: + s = "STND"; + break; + }; + sprintf(buf, "%3s %3d %c%c%c%c %c%c%c %4s", + teamname[mask_to_idx(j->pl_owner) + 1], + j->pl_armies, + (j->pl_flags & PLREPAIR ? 'R' : ' '), + (j->pl_flags & PLFUEL ? 'F' : ' '), + (j->pl_flags & PLAGRI ? 'A' : ' '), + (j->pl_flags & PLSHIPYARD ? 'S' : ' '), + (j->pl_flags & PLDILYTH ? 'D' : ' '), + (j->pl_flags & PLMETAL ? 'M' : ' '), + (j->pl_flags & PLARABLE ? 'A' : ' '), + s); + + W_WriteText(wind, 24, line, planetColor(j), buf, strlen(buf), + planetFont(j)); + + sprintf(buf, "%4s %3ld", + team_bit_string(j->pl_info), + ((idx_to_mask(me->p_teami) == j->pl_owner) ? 0 : (status2->clock - j->pl_timestamp))); + + W_WriteText(wind, 64, line, planetColor(j), buf, strlen(buf), + planetFont(j)); + } + } else { + sprintf(buf, "--- No info; Scout me ---"); + W_WriteText(wind, 24, line, textColor, buf, strlen(buf), + W_RegularFont); + } +} /* end of print_planet */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/planets.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,481 @@ +/* $Id: planets.c,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */ + +/* + * planets.c + * + * Kevin P. Smith 2/21/89 + * + * This file contains the galaxy definition as well as some support for + * determining when parts of the galactic map need to be redrawn. + */ +#include "copyright2.h" + +#include <stdio.h> +#include <math.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "proto.h" + +/* define to get profiling info, to better set DEPTH and DETAIL [BDyess] */ +/*#define PROFILE1 /* maxdepth printed */ +/*#define PROFILE2 /* every PLREDRAW setting printed (VERBOSE) */ + +/* Note: DETAIL * MUST * be a factor of GWIDTH. */ +#define DETAIL 80 /* Size of redraw array */ +#define RADIUS 2 /* number of adjacent cells to register in */ +#define SIZE 2500 +#define DEPTH 8 +#ifdef PROFILE1 +#define ADDPLANET(i,j,k) { \ + for(z=0;z<DEPTH;z++) { \ + if(redraws[i][j][z] == (char)-1) { \ + redraws[i][j][z] = k; \ + break; \ + } \ + } z++; \ + if(z > maxdepth) maxdepth = z; \ +} +#else /* not PROFILEing */ +#define ADDPLANET(i,j,k) { \ + for(z=0;z<DEPTH;z++) { \ + if(redraws[i][j][z] == (char)-1) { \ + redraws[i][j][z]=k; \ + break; \ + } \ + } \ +} +#endif /* PROFILE1 */ + +#define LEFT 1 /* position flags for corner guessing */ +#define RIGHT 2 +#define TOP 4 +#define BOTTOM 8 + +struct _star { + int s_x, s_y; + int s_color; +}; + +static void redrawStarSector P((struct _star star_sector[16])); + +/* + planets may be on top of each other or very close, so more than one planet + can exist in a given block. The 3rd dimension is for a list of planets. + [BDyess] +*/ +char redraws[DETAIL][DETAIL][DEPTH]; +static int initialized = 0; + +/* + since planets may be moved, the redraw matrix must be updated. This + function is for updating just one planet. This should help the moving + planet efficiency problems quite a bit. [BDyess] +*/ +void +initOnePlanet(pl) + struct planet *pl; +{ +} + +/* + rewritten to repair UNBELIEVABLE inefficiencies in the original [BDyess] +*/ +void +initPlanets() +{ + register int i, j, k, x, y, z, r, s; + struct planet *pl; +#ifdef PROFILE1 + int maxdepth = 0; +#endif /* PROFILE1 */ + + /* initialize lookup array */ + for (i = 0; i < DETAIL; i++) { + for (j = 0; j < DETAIL; j++) { + for (k = 0; k < DEPTH; k++) { + redraws[i][j][k] = -1; + } + } + } + + /* + check all the planets. If part of the planet falls inside a box in + the lookup array, add it to the refresh list for that box. [BDyess] + */ + for (k = 0, pl = planets; k < nplanets; k++, pl++) { + x = pl->pl_x; + y = pl->pl_y; + i = x / SIZE - 3; + j = y / SIZE - 2; + /* + fill cells around the target cell with the planetnum like so: **** + + ** + + x** **** + + ** + + ** taller than wide because of text **** + + [BDyess] + */ + for (r = 0; r < 5; r++) { + i++; + if (i <= 0) + continue; + if (i >= DETAIL) + break; + for (s = 0; s < 7; s++) { + j += s; + if (j <= 0) + continue; + if (j >= DETAIL) + break; + ADDPLANET(i, j, k) + j -= s; + } + } +#if 0 /* this works, and allows the radius around + the hot spot to be changed. It's disabled + because a less-flexible piece of code + (above) is a bit faster. Plus, it's hard + to generalize about that extra added + lines. [BDyess] */ + ADDPLANET(i, j, k) + for (r = 1; r <= RADIUS; r++) { + /* draw box sides in all four directions */ + /* bottom */ + i += r; + ADDPLANET(i, j, k) + for (s = 1; s <= r; s++) { + j += s; + ADDPLANET(i, j, k) + j -= 2 * s; + ADDPLANET(i, j, k) + j += s; + } + /* top */ + i -= 2 * r; + ADDPLANET(i, j, k) + for (s = 1; s <= r; s++) { + j += s; + ADDPLANET(i, j, k) + j -= 2 * s; + ADDPLANET(i, j, k) + j += s; + } + /* left */ + i += r; + j += r; + ADDPLANET(i, j, k) + for (s = 1; s < r; s++) { + i += s; + ADDPLANET(i, j, k) + i -= 2 * s; + ADDPLANET(i, j, k) + i += s; + } + /* right */ + j -= 2 * r; + ADDPLANET(i, j, k) + for (s = 1; s < r; s++) { + i += s; + ADDPLANET(i, j, k) + i -= 2 * s; + ADDPLANET(i, j, k) + i += s; + } + } +#endif /* 0 */ + } + initialized = 1; +#ifdef PROFILE1 + printf("max depth = %d\n", maxdepth); +#endif /* PROFILE1 */ +} + +void +checkRedraw(x, y) + int x, y; +{ + int j; + char i; + + if (!initialized || x < 0 || y < 0 || x >= blk_gwidth || y >= blk_gwidth) + return; + x /= SIZE; + y /= SIZE; + for (j = 0; j < DEPTH; j++) { + i = redraws[x][y][j]; + if (i == (char) -1) + return; + planets[i].pl_flags |= PLREDRAW; +#ifdef PROFILE2 + printf("setting PLREDRAW flag for %s\n", planets[i].pl_name); +#endif /* PROFILE2 */ + } +} + + +/* NOTE: this has been rewritten -- see below */ + +#define NUMSTARS 1600 + +static int starsX[NUMSTARS]; +static int starsY[NUMSTARS]; + +void +_initStars() +{ + register int i; + + for (i = 0; i < NUMSTARS; i++) { + starsX[i] = (i % 40) * 5000 + random() % 5000; + starsY[i] = (i / 40) * 5000 + random() % 5000; + } +} + +void +_drawStars() +{ + int i; + int x, y; + + for (i = 0; i < NUMSTARS; i++) { + x = starsX[i] - me->p_x; + y = starsY[i] - me->p_y; + if (ABS(x) < 10000 && ABS(y) < 10000) { + x = x / SCALE + WINSIDE / 2; + y = y / SCALE + WINSIDE / 2; + W_DrawPoint(w, x, y, W_White); + W_CacheClearArea(w, x, y, 1, 1); + } + } +} + +/* + * This rewrite improves drawStars() by a factor of about 30 (according to + * gprof) + */ + +/* blk_gwidth/(WINSIDE * SCALE) == 10 for blk_gwidth == 200000 */ +static struct _star stars[10][10][16]; + +void +initStars() +{ + register int i, j, k; + + for (i = 0; i < 10; i++) { + for (j = 0; j < 10; j++) { + for (k = 0; k < 16; k++) { + stars[i][j][k].s_x = i * (WINSIDE * SCALE) + random() % (WINSIDE * SCALE); + stars[i][j][k].s_y = j * (WINSIDE * SCALE) + random() % (WINSIDE * SCALE); + stars[i][j][k].s_color = randcolor(); + } + } + } +} + +int +randcolor() +{ + switch (random() % 10) { + case 0:return W_Yellow; + case 1: + return W_Red; + case 2: + return W_Green; + case 3: + return W_Cyan; + default: + return W_White; + } +} + +void +drawStars() +{ + /* + note: cpp symbols in expressions (WINSIDE*SCALE) will be precalculated + by any C optimizer + */ + int sectorx = me->p_x / (WINSIDE * SCALE), sectory = me->p_y / (WINSIDE * SCALE); + int sector_offx = me->p_x - sectorx * (WINSIDE * SCALE), sector_offy = me->p_y - sectory * (WINSIDE * SCALE); + int l = 0, r = 0, t = 0, b = 0; + + if (sector_offx < 0) { /* goddamn rounding towards 0 */ + sectorx--; + sector_offx += WINSIDE * SCALE; + } + if (sector_offy < 0) { /* goddamn rounding towards 0 */ + sectory--; + sector_offy += WINSIDE * SCALE; + } +#define MAXSECTOR (blk_gwidth/(WINSIDE*SCALE)) + + /* at worst we have to redraw 4 star sectors */ + + /* draw the one we're in */ + /* + check first to make sure it's valid. This is mainly important for if + it tries to redraw and we're already dead + */ + if (sectorx < 0 || sectory < 0) + return; + + l = sector_offx < (WINSIDE * SCALE) / 2 && sectorx > 0; + r = sector_offx > (WINSIDE * SCALE) / 2 && sectorx + 1 < MAXSECTOR; + t = sector_offy < (WINSIDE * SCALE) / 2 && sectory > 0; + b = sector_offy > (WINSIDE * SCALE) / 2 && sectory + 1 < MAXSECTOR; + + if (t) { + if (l) /* redraw upper-left sector */ + redrawStarSector(stars[sectorx - 1][sectory - 1]); + + /* redraw upper sector */ + redrawStarSector(stars[sectorx][sectory - 1]); + + if (r) /* redraw upper-right sector */ + redrawStarSector(stars[sectorx + 1][sectory - 1]); + } + if (l) /* redraw left sector */ + redrawStarSector(stars[sectorx - 1][sectory]); + + /* redraw center sector */ + redrawStarSector(stars[sectorx][sectory]); + + if (r) /* redraw right sector */ + redrawStarSector(stars[sectorx + 1][sectory]); + + if (b) { + if (l) /* redraw bottom-left sector */ + redrawStarSector(stars[sectorx - 1][sectory + 1]); + + /* redraw bottom sector */ + redrawStarSector(stars[sectorx][sectory + 1]); + + if (r) /* redraw bottom-right sector */ + redrawStarSector(stars[sectorx + 1][sectory + 1]); + } + W_FlushPointCaches(w); +} + +static void +redrawStarSector(star_sector) + struct _star star_sector[16]; +{ + register i, dx, dy, dxx, dyy; + register struct _star *s; + static int warpflag = 0; /* assume starting out not in warp */ + static int streaksOn = 0, lastspeed = 0, lastsubspeed = 0, updates = 0; + static int streaklength = 1; + + if (warpStreaks) { + if (warpflag != (me->p_flags & PFWARP)) { /* change in warp state */ + streaksOn = 1; + warpflag = (me->p_flags & PFWARP); + } + if (streaksOn) { + if (warpflag && (me->p_speed < lastspeed || + (me->p_speed == lastspeed && me->p_subspeed <= lastsubspeed))) { + /* finished accelerating */ + updates++; + if (updates > 5) { + lastspeed = me->p_speed; + lastsubspeed = me->p_subspeed; + updates = 0; + streaksOn = 0; + redrawStarSector(star_sector); + return; + } + } else if (streaklength == 1 || (!warpflag && ((me->p_speed > lastspeed) || + (me->p_speed == lastspeed && me->p_subspeed >= lastsubspeed)))) { + /* finished decelerating */ + updates++; + if (updates > 5) { + lastspeed = me->p_speed; + lastsubspeed = me->p_subspeed; + updates = 0; + streaksOn = 0; + streaklength = 1; + redrawStarSector(star_sector); + return; + } + } else + updates = 0; + lastspeed = me->p_speed; + lastsubspeed = me->p_subspeed; + /* draw the streaks */ + if (warpflag) + streaklength += 3; + else + streaklength--; + dxx = (int) (Cos[me->p_dir] * streaklength); + dyy = (int) (Sin[me->p_dir] * streaklength); + for (i = 0, s = star_sector; i < 16; i++, s++) { + dx = s->s_x - me->p_x; + dy = s->s_y - me->p_y; + if (ABS(dx) > (SCALE * WINSIDE / 2) || ABS(dy) > (SCALE * WINSIDE / 2)) + continue; + + dx = dx / SCALE + WINSIDE / 2; + dy = dy / SCALE + WINSIDE / 2; + W_CacheLine(w, dx, dy, dx - dxx, dy - dyy, s->s_color); + + clearline[0][clearlcount] = dx; + clearline[1][clearlcount] = dy; + clearline[2][clearlcount] = dx - dxx; + clearline[3][clearlcount] = dy - dyy; + clearlcount++; + } + return; + } + } + for (i = 0, s = star_sector; i < 16; i++, s++) { + dx = s->s_x - me->p_x; + dy = s->s_y - me->p_y; + if (ABS(dx) > (SCALE * WINSIDE / 2) || ABS(dy) > (SCALE * WINSIDE / 2)) + continue; + + dx = dx / SCALE + WINSIDE / 2; + dy = dy / SCALE + WINSIDE / 2; + W_CachePoint(w, dx, dy, s->s_color); +#ifndef AMIGA + /* + this is a minor kludge: as long as there are less then 128 stars + in a sector these cached requests will not actually be written to + the X server until the next redraw cycle begins. + */ + W_CacheClearArea(w, dx, dy, 1, 1); +#else + clearline[0][clearlcount] = dx; + clearline[1][clearlcount] = dy; + clearline[2][clearlcount] = dx; + clearline[3][clearlcount] = dy; + clearlcount++; +#endif + } +} + +#if 0 +void +clearStars() +{ + int i; + int x, y; + + for (i = 0; i < NUMSTARS; i++) { + x = starsX[i] - me->p_x; + y = starsY[i] - me->p_y; + if (ABS(x) < 10000 && ABS(y) < 10000) { + x = x / SCALE + WINSIDE / 2; + y = y / SCALE + WINSIDE / 2; + W_CacheClearArea(w, x, y, 1, 1); + } + } +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/playerlist.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,518 @@ +/* $Id: playerlist.c,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */ + +/* + * playerlist.c + * modified to sort by teams by Bill Dyess on 9/23/93 + */ +#include "copyright.h" + +#include <stdio.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "proto.h" +#include "gameconf.h" +#include "packets.h" + +/* Prototypes */ +static void dofulllist P((struct player * pptr, int vpos)); +/* static char *get_players_rank_name P((struct player *j));*/ +void getdesig P((struct player * j, char *desig)); + +struct teamstruct { + short teamnum; + short totalnum; + short outfitnum; + short row; + short outfitrow; +}; + +int lastsortPlayers, lasthnk, lastspl, lastshowDead; + +void +playerlist() +{ + int i; + char buf[100]; + + if (slot == NULL) { + if ((slot = (short *) malloc(sizeof(short) * 33)) == NULL) { + perror("out of memory?!?\n"); + exit(-1); + } + } + if (*playerList != 0 && *playerList != ',') { /* do the wide thing + [BDyess] */ + wideplayerlist(); + return; + } + for (i = 0; i < 33; i++) + slot[i] = -2; + lastsortPlayers = sortPlayers; + lasthnk = hideNoKills; + lastspl = showPreLogins; + lastshowDead = showDead; + + W_ClearWindow(playerw); + + (void) strcpy(buf, " Type Rank Name Kills Type Rank Name Kills"); + W_WriteText(playerw, 0, 1, textColor, buf, strlen(buf), W_RegularFont); + + if (!paradise) + (void) strcpy(buf, " Type Rank Name Kills Win Loss Ratio Offense Defense DI"); + else + (void) strcpy(buf, " Type Rank Name Kills Win Loss Ratio Battle Strategy DI"); + + W_WriteText(playerw, 0, 20, textColor, buf, strlen(buf), W_RegularFont); + + for (i = 0; i < nplayers; i++) + updatePlayer[i] |= ALL_UPDATE; + + playerlist2(); +} + + +void +playerlist2() +{ + register int i, k, z; + char buf[100]; + short extra = 0, outfitextra = 0; + struct teamstruct teams[4]; + struct teamstruct *quadrant[4], *tempquad; /* topleft, topright, + bottomleft, bottomright */ + register struct player *j; + static short sequentialSort = 0; + char *rname; + char desig[3]; + short currentSlot; + static int usingWide = 0; + + if (*playerList != 0 && *playerList != ',') { /* do the wide thing + [BDyess] */ + if (slot == NULL) { + playerlist(); + return; + } + wideplayerlist2(); + usingWide = 1; + return; + } + /* keeps the playerlist from being drawn when not allowed [BDyess] */ + if (!allowPlayerlist) + return; + + if (slot == NULL || lastsortPlayers != sortPlayers || + lasthnk != hideNoKills || + lastspl != showPreLogins || + lastshowDead != showDead || + usingWide) { + usingWide = 0; + if(resizePlayerList) + W_ResizeText(playerw,83,W_WindowHeight(playerw)); + playerlist(); + return; + } + if (!W_IsMapped(playerw)) + return; + if (updatePlayer[me->p_no] & LARGE_UPDATE) + dofulllist(me, 21); + if (blk_bozolist >= 0) + if (updatePlayer[blk_bozolist] & LARGE_UPDATE) + dofulllist(&players[blk_bozolist], 22); + /* + if sortPlayers is on: the players team goes in the top left (top right + if robSort: on), the next-largest team in the top right, the third + largest in the bottom left, and everything else in the bottom right + */ + if (sortPlayers) { + bzero(teams, sizeof(teams)); + for (i = 0; i < 4; i++) + teams[i].teamnum = i; + /* figure out how many players on each team */ + for (i = 0, j = &players[i]; i < nplayers; i++, j++) { + if (j->p_status != PFREE && !(j->p_status == POUTFIT && j->p_teami < 0)) { + if (j->p_teami < 0 || j->p_teami == number_of_teams) { + if (!showDead) + continue; + extra++; + if (j->p_status == POUTFIT && sortOutfitting) + outfitextra++; + } else if (j->p_teami == number_of_teams) { + if (!showPreLogins) + continue; + extra++; + if (j->p_status == POUTFIT && sortOutfitting) + outfitextra++; + } else { + teams[j->p_teami].totalnum++; + if (j->p_status == POUTFIT && showDead && sortOutfitting) + teams[j->p_teami].outfitnum++; + } + } + /* + printf("player %d is on team %d with status %d\n", + i,j->p_teami,j->p_status); + */ + } + + for (i = 0; i < 4; i++) + quadrant[i] = &teams[i]; + if (me->p_teami >= 0 && me->p_teami < number_of_teams) + teams[me->p_teami].totalnum += 10000; + for (i = 3; i > 0; i--) { + for (k = 0; k < i; k++) { + if (quadrant[k]->totalnum < quadrant[k + 1]->totalnum) { + tempquad = quadrant[k]; + quadrant[k] = quadrant[k + 1]; + quadrant[k + 1] = tempquad; + } + } + } + if (me->p_teami >= 0 && me->p_teami < number_of_teams) { + teams[me->p_teami].totalnum -= 10000; + if (robsort) { + quadrant[0] = quadrant[1]; + quadrant[1] = &teams[me->p_teami]; + } + } + quadrant[3]->totalnum += extra; + quadrant[3]->outfitnum += outfitextra; + + if (quadrant[0]->totalnum > 16 || quadrant[1]->totalnum > 16) { + /* + if one team is so huge as to not fit on just one side, then + just list all the players sequentially, but still team sorted. + For now, set a flag and clear any freshly empty space. + */ + if (sequentialSort == 0) { + sequentialSort = 1; + playerlist(); + return; + } + quadrant[0]->row = 0; + quadrant[1]->row = quadrant[0]->totalnum; + quadrant[2]->row = quadrant[1]->row + quadrant[1]->totalnum; + quadrant[3]->row = quadrant[2]->row + quadrant[2]->totalnum; + /* wipe out the blank sections */ + for (i = quadrant[3]->row + quadrant[3]->totalnum; i < 32; i++) { + if (slot[i] != -1) { + /* + if we get here, it's not possible to have players + blank on the left side + */ + W_ClearArea(playerw, 44, i - 16 + 1, 41, 1); + slot[i] = -1; + } + } + } else { + if (sequentialSort == 1) { + sequentialSort = 0; + playerlist(); + return; + } + quadrant[0]->row = quadrant[1]->row = 2; + if (quadrant[0]->totalnum + quadrant[2]->totalnum <= 16) { + quadrant[2]->row = 18 - quadrant[2]->totalnum; + } else { + quadrant[2]->row = 2 + quadrant[0]->totalnum; + quadrant[3]->totalnum += quadrant[0]->totalnum + quadrant[2]->totalnum - 16; + } + if (quadrant[1]->totalnum + quadrant[3]->totalnum <= 16) { + quadrant[3]->row = 18 - quadrant[3]->totalnum; + } else { + quadrant[3]->row = 2 + quadrant[1]->totalnum; + quadrant[2]->row -= quadrant[1]->totalnum + quadrant[3]->totalnum - 16; + } + + for (i = 0; i < 4; i++) + quadrant[i]->outfitrow = quadrant[i]->row + quadrant[i]->totalnum - + quadrant[i]->outfitnum; + /* wipe out the blank sections */ + for (i = 2 + quadrant[0]->totalnum; i < quadrant[2]->row; i++) { + if (slot[i - 2] != -1 || players[slot[i - 2]].p_status != POUTFIT) { + W_ClearArea(playerw, 0, i, 41, 1); + slot[i - 2] = -1; + } + } + for (i = 2 + quadrant[1]->totalnum; i < quadrant[3]->row; i++) { + if (slot[16 + i - 2] != -1) { + W_ClearArea(playerw, 44, i, 41, 1); + slot[16 + i - 2] = -1; + } + } + } + } + /* update the display for each player */ + for (i = 0, j = &players[i]; i < nplayers; i++, j++) { + + if (!updatePlayer[i] && !sortPlayers && slot[i] == j->p_no) + continue; + + getdesig(j, desig); + if (!desig[0]) { + if (!sortPlayers) + W_ClearArea(playerw, (i > 15) ? 44 : 0, (i > 15) ? i - 16 + 2 : i + 2, 41, 1); + continue; /* don't display this guy, he's toast */ + } + rname = get_players_rank_name(j); + (void) sprintf(buf, "%c%c %2.2s %-9.9s %-15.15s", + teaminfo[j->p_teami].letter, + shipnos[j->p_no], + desig, + rname, + j->p_name); + /* + replace 0.00 kills with spaces if not alive and paradise or not + RSA + */ + /* this is optional with the hideNoKills option */ + if ((j->p_kills <= 0 && + (paradise || RSA_Client <= 0) && hideNoKills) + || (j->p_status & ~PALIVE)) + strcat(buf, " "); + else + sprintf(buf + strlen(buf), "%6.2f", j->p_kills); + if (!sortPlayers) { +#ifdef PLPROF + printf("Updating player %d\n", j->p_no); +#endif /* PLPROF */ + W_WriteText(playerw, (i > 15) ? 44 : 0, + (i > 15) ? i - 16 + 2 : i + 2, playerColor(j), buf, + strlen(buf), shipFont(j)); + slot[i] = j->p_no; + } else if (!sequentialSort) { + /* find out which quadrant he should be in */ + for (z = 0; j->p_teami != quadrant[z]->teamnum && z < 3; z++); + if (j->p_status == POUTFIT && sortOutfitting) + k = quadrant[z]->outfitrow++ - quadrant[z]->row; + else + k = 0; + if (quadrant[z]->row + k > 18) { + z += 1; + if (z > 3) + z -= 2; + } + currentSlot = (z % 2) * 16 + quadrant[z]->row - 2 + k; + if (slot[currentSlot] != j->p_no || updatePlayer[j->p_no] & SMALL_UPDATE) { + slot[currentSlot] = j->p_no; +#ifdef PLPROF + printf("Updating %d, currentslot = %d, updatePlayer = %d\n", + j->p_no, currentSlot, updatePlayer[j->p_no]); +#endif /* PLPROF */ + W_WriteText(playerw, 44 * (z % 2), k + quadrant[z]->row, + playerColor(j), buf, strlen(buf), shipFont(j)); + } + if (!k) + quadrant[z]->row++; + } else { /* do sequential sort placement */ + /* find out which quadrant he should be in */ + for (z = 0; j->p_teami != quadrant[z]->teamnum && z < 3; z++); + currentSlot = quadrant[z]->row++; + if (slot[currentSlot] != j->p_no || updatePlayer[j->p_no] & SMALL_UPDATE) { + if (currentSlot >= 16) { + W_WriteText(playerw, 44, currentSlot - 16 + 2, playerColor(j), + buf, strlen(buf), shipFont(j)); + } else { + W_WriteText(playerw, 0, currentSlot + 2, playerColor(j), buf, + strlen(buf), shipFont(j)); + } + } + } + +#if 0 + if (slot[currentSlot] != j->p_no || updatePlayer[j->p_no] & SMALL_UPDATE) { + slot[currentSlot] = j->p_no; +#ifdef PLPROF + printf("Updating %d\n", j->p_no); +#endif /* PLPROF */ + W_WriteText(playerw, currentSlot >= 16 ? 44 : 0, + currentSlot >= 16 ? currentSlot + 2 - 16 : currentSlot + 2, + playerColor(j), buf, strlen(buf), shipFont(j)); + } + } +#endif /* 0 */ + updatePlayer[j->p_no] = NO_UPDATE; +} +} + +void +getdesig(j, desig) + struct player *j; + char *desig; +{ + switch (j->p_status) { + case PALIVE: + strncpy(desig, j->p_ship->s_desig, 2); + j->p_ship->s_desig[2] = 0; + break; + case PTQUEUE: + strcpy(desig, "tq"); + break; + case POUTFIT: + if ((j->p_teami < 0) || !showDead) + desig[0] = 0; + else + strcpy(desig, "--"); + break; + case PEXPLODE: + case PDEAD: + if (showDead) + strcpy(desig, "**"); + else + desig[0] = 0; + break; + case POBSERVE: + strcpy(desig, "ob"); + break; + default: + desig[0] = 0; + break; + } + /* + if (!*desig) j->p_teami = -1; + */ + if (j->p_teami == number_of_teams && !showPreLogins) + desig[0] = 0; +} + +static void +dofulllist(pptr, vpos) + struct player *pptr; + int vpos; +{ + char buf[100]; + char *rname; + char desig[3]; + struct ratings r; + + if (!W_IsMapped(playerw)) + return; + + getdesig(pptr, desig); + if (!desig[0]) { + if (pptr->p_no == blk_bozolist) + blk_bozolist = -1; + W_ClearArea(playerw, 0, vpos, 83, 1); + return; + } + get_ratings(pptr, &r); + + rname = get_players_rank_name(pptr); + if (!paradise) + sprintf(buf, "%c%c %2.2s %-9.9s %-16.16s%5.2f %5d %5d %6.2f %5.2f %5.2f %8.2f ", + teaminfo[pptr->p_teami].letter, + shipnos[pptr->p_no], + desig /* pptr->p_ship->s_desig */ , + rname, + pptr->p_name, + pptr->p_kills, + r.r_kills, + r.r_losses, + r.r_ratio, + r.r_offrat, + r.r_defrat, + r.r_di); + else + sprintf(buf, "%c%c %2.2s %-9.9s %-16.16s%5.2f %5d %5d %6.2f %5.2f %5.2f %8.2f ", + teaminfo[pptr->p_teami].letter, + shipnos[pptr->p_no], + desig /* pptr->p_ship->s_desig */ , + rname, + pptr->p_name, + pptr->p_kills, + r.r_kills, + r.r_losses, + r.r_ratio, + r.r_batrat, + r.r_stratrat, + r.r_di); + +#ifdef PLPROF + printf("Updating %d\n", pptr->p_no); +#endif /* PLPROF */ + W_WriteText(playerw, 0, vpos, playerColor(pptr), buf, strlen(buf), + shipFont(pptr)); +} + +char * +get_players_rank_name(j) + struct player *j; +{ + char *r; + if (j->p_stats.st_rank < 0) + j->p_stats.st_rank = 0; + if (!paradise) { + r = ranks[j->p_stats.st_rank].name; + } else { + if (j->p_stats2.st_royal == 0) + r = ranks2[j->p_stats2.st_rank].name; + else + r = royal[j->p_stats2.st_royal].name; + } + return (r); +} + +void +playerwEvent(data) + W_Event *data; +{ + int key; + struct obtype *target; + + key = doKeymap(data); + if (key == -1) + return; + switch (key) { + case 'l': /* lock on [BDyess] */ + target = gettarget(data->Window, data->x, data->y, TARG_PLAYER); + sendPlaylockReq(target->o_num); + me->p_playerl = target->o_num; + break; + case 'i': + case 'I': + if (!infomapped) + inform(data->Window, data->x, data->y, key); + else + destroyInfo(); + break; + case 'X': + macroState = 1; + warning("Macro mode"); + break; + default: + warning("Invalid key"); + } +} + +void +selectblkbozo(data) + W_Event *data; +{ + int width, slotnum; + + if (*playerList + && *playerList != ',') + return; + width = W_WindowWidth(data->Window); + if (data->key == W_RBUTTON || data->key == W_LBUTTON || data->key == W_MBUTTON) + if (data->y > W_Textheight * 2 + 1 && data->y < W_Textheight * 19) { + W_TranslatePoints(data->Window, &data->x, &data->y); + slotnum = 0; + if (data->x > width / 2) + slotnum += 16; + /* only look for players in the slotspace */ + if (data->y <= (16 + 1)) { + slotnum += data->y - 2; + if (slot[slotnum] != me->p_no) + blk_bozolist = slot[slotnum]; + if (blk_bozolist >= 0) { + updatePlayer[blk_bozolist] |= LARGE_UPDATE; + } else { + blk_bozolist = -1; + W_ClearArea(playerw, 0, 22, 83, 1); + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/proto.h Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,312 @@ +/* $Id: proto.h,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */ + +#ifndef proto_h_ +#define proto_h_ + +#ifndef P +#ifdef __STDC__ +#define P(s) s +#else +#define P(s) () +#endif +#endif + +#include <stdio.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include "Wlib.h" +#include "struct.h" + +/* autokey.c */ +int setAutoKeyOn P((void)); +int setAutoKeyOff P((void)); +void autoKeyDefaults P((void)); +int doAutoKey P((void)); +int autoKeyAllOff P((void)); +int autoKeyOff P((W_Event * data)); +int autoKeyTorpOn P((void)); +int autoKeyTorpReqOn P((void)); +int autoKeyPhaserOn P((void)); +int autoKeyPhaserReqOn P((void)); +int autoKeyDetOn P((void)); +int autoKeyDetReqOn P((void)); +int autoKeyPlasmaReqOn P((void)); +int autoKeyBombReqOn P((void)); +int autoKeyBeamUpReqOn P((void)); +int autoKeyBeamDownReqOn P((void)); +int autoKeyOrbitReqOn P((void)); + +/* beeplite.c */ +void litedefaults P((void)); +void rcdlite P((struct distress *)); + +/* blk_parsemotd.c */ +void blk_parsemotd P((char *line)); + +/* colors.c */ +void getColorDefs P((void)); + +/* data.c */ + +/* dashboard.c */ +void stline P((int flag)); +void redrawTstats P((void)); +void light_send P((void)); +void light_receive P((void)); + +/* death.c */ +void death P((void)); + +/* defaults.c */ +char *initDefaults P((char *deffile)); +char *getdefault P((char *str)); +char *stringDefault P((char *str, char *preferred)); +int booleanDefault P((char *def, int preferred)); +int intDefault P((char *def, int preferred)); +int defaultShip P((int preferred)); +void resetDefaults P((void)); +char *expandFilename P((char *)); + +/* detonate.c */ +void detmine P((void)); + +/* distress.c */ +int testmacro P((char *, char *, int *, int *)); +int condmacro P((char *, char *, int *, int *, int)); +int solvetest P((char *, int *)); +int skipmacro P((char [], int)); +int makedistress P((struct distress *, char *, char *)); + +/* dmessage.c */ +void dmessage P((char *message, unsigned int flags, unsigned int from, unsigned int to)); +void logit P((char *message)); +void sendVersion P((void)); + +/* enter.c */ +void enter P((void)); +void openmem P((void)); + +/* findslot.c */ +int findslot P((void)); + +/* getname.c */ +void getname P((char *defname, char *defpasswd)); + +/* getship.c */ +void init_shiptypes P((void)); +struct ship *getship P((int s_type)); +void init_galaxy_class P((void)); + +/* helpwin.c */ +void fillhelp P((void)); + +/* inform.c */ +void inform P((W_Window ww, int x, int y, int key)); +void destroyInfo P((void)); + +/* input.c */ +void initinput P((void)); +void input P((void)); +int getcourse P((W_Window ww, int x, int y)); + +/* interface.c */ +void set_speed P((int speed)); +void set_course P((unsigned int dir)); +void shield_up P((void)); +void shield_down P((void)); +void shield_tog P((void)); +void bomb_planet P((void)); +void beam_up P((void)); +void beam_down P((void)); +void repair P((void)); +void repair_off P((void)); +void repeat_message P((void)); +void cloak P((void)); +void cloak_on P((void)); +void cloak_off P((void)); +int mtime P((void)); + +/* keymap.c */ +void buildShipKeymap P((struct ship * shipp)); +void initkeymap P((int type)); +void keymapAdd P((char *str, char *map)); +void ckeymapAdd P((char *cstr, char *map)); +void buttonmapAdd P((char *str, char *map)); +void cbuttonmapAdd P((char *cstr, char *map)); +void dumpKeymap P((void)); + +/* main.c */ +/* doy, this prototype is wholly unecessary */ +/* int main P((int argc, char **argv)); */ +void reaper P((void)); +unsigned long dotAddrToNetAddr P((char *str)); + +#ifdef MACROS +/* macros.c */ +void doMacro P((W_Event * data)); +void initMacros P((void)); + +/* macrowin.c */ +void showMacroWin P((void)); +#endif /* MACROS */ + +/* newwin.c */ +void newwin P((char *hostmon, char *progname)); +void mapAll P((void)); +void entrywindow P((int *team, int *s_type)); +int deadTeam P((int owner)); +void erase_motd P((void)); +void newMotdPic P((int x, int y, int width, int height, char *bits, int page)); +void newMotdLine P((char *line)); +void fillhelp P((void)); +void drawIcon P((void)); +void do_refit P((int type)); +void showMotd P((W_Window win)); + +/* motdwin.c */ +void motdWinEvent P((int)); +void showMotdWin P((void)); + +/* option.c */ +void optionwindow P((void)); +void optionredrawtarget P((W_Window win)); +void optionredrawoption P((int *ip)); +int optionaction P((W_Event * data)); +void optiondone P((void)); + +#ifdef METASERVER +/* parsemeta.c */ +void parsemeta P((void)); +void metawindow P((void)); +void metainput P((void)); +/* void metaaction P((W_Event * data)); */ +#endif /* METASERVER */ + +/* planetlist.c */ +void planetlist P((void)); + +/* planets.c */ +void initPlanets P((void)); +void checkRedraw P((int x, int y)); +void initStars P((void)); +void drawStars P((void)); +void clearStars P((void)); + +/* playerlist.c */ +void playerlist P((void)); +void playerlist2 P((void)); +struct player; +char *get_players_rank_name P((struct player * j)); +void selectblkbozo P((W_Event * data)); +void playerwEvent P((W_Event * data)); + +/* ranklist.c */ +void ranklist P((void)); + +/* ratings.c */ +struct ratings *get_ratings P((struct player * s, struct ratings * r)); + +/* redraw.c */ +struct _clearzone *new_czone P((void)); + +/* reserved.c */ +int makeReservedPacket P((void *packet)); +int encryptReservedPacket P((void *spacket, void *cpacket, char *server, int pno)); + +/* shipbitmaps.c */ +void slurp_ship_bitmaps P((void)); +void replace_shipshape P((int, int, int, int, int)); +void replace_ship_bitmaps P((int, int, int, char *)); + +/* sintab.c */ +void inittrigtables P((void)); + +/* smessage.c */ +void message_expose P((void)); +void smessage P((int ichar)); +void smessage_ahead P((int head, int ichar)); +void pmessage P((char *str, int recip, int group)); +void emergency P((void)); +void carry_report P((void)); +void message_on P((void)); +void message_off P((void)); +void sendCharMessage P((char *buf, int ch)); + +/* socket.c */ +void print_totals P((void)); +void connectToServer P((int port)); +void callServer P((int port, char *server)); +int isServerDead P((void)); +void socketPause P((int sec, int usec)); +int readFromServer P((void)); +int readFromServer P((void)); +void sendShortPacket P((int type, int state)); +void sendTeamReq P((int team, int ship)); +void sendLoginReq P((char *name, char *pass, char *login, int query)); +void sendTractorReq P((int state, int pnum)); +void sendRepressReq P((int state, int pnum)); +void sendDetMineReq P((int torp)); +void sendMessage P((char *mes, int group, int indiv)); +void sendOptionsPacket P((void)); +void sendUpdatePacket P((long speed)); +void sendUdpReq P((int req)); +int closeUdpConn P((void)); +short swaps P((int in)); +int mask_to_idx P((int)); + +/* stats.c */ +void redrawStats P((void)); +void updateStats P((void)); +void calibrate_stats P((void)); + +/* udpopt.c */ +void udpwindow P((void)); +void udprefresh P((int i)); +void udpaction P((W_Event * data)); +void udpdone P((void)); + +/* util.c */ +int angdist P((unsigned int x, unsigned int y)); +struct obtype *gettarget P((W_Window ww, int x, int y, int targtype)); +struct id *getTargetID P((W_Window ww, int x, int y, int targtype)); +char *team_bit_string P((int mask)); + +/* varydamage.c */ +struct ship_shape; +void doShields P((int dx, int dy, struct ship_shape * ship_bits, struct player * j)); +void doHull P((int dx, int dy, struct ship_shape * ship_bits, struct player * j)); + +/* war.c */ +void warwindow P((void)); +void waraction P((W_Event * data)); + +/* warning.c */ +void warning P((char *text)); +char *timeString P((time_t time)); + +/* wide_plist.c */ +void wideplayerlist P((void)); +void wideplayerlist2 P((void)); + +/* x11window.c */ +int checkMapped P((char *window)); +void W_RenameWindow P((W_Window window, char *str)); +void W_GetEvent P((W_Event * wevent)); + +#ifdef RECORDER +/* recorder.c */ +void startRecorder P((void)); +void stopRecorder P((void)); +void recordPacket P((char *data, int len)); +void writeUpdateMarker P((void)); +int startPlayback P((void)); +int readRecorded P((int fp, char *data, int len)); +#endif + +#ifdef XTREKRC_HELP +/* defwin.c */ +void showdef P((void)); +void def_action P((W_Event *ev)); +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/puck.h Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,10 @@ +/* $Id: puck.h,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */ + +#define puck_width 20 +#define puck_height 20 +static unsigned char puck_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x07, 0x00, 0xc0, 0x1f, 0x00, 0xe0, 0x3f, 0x00, 0xe0, 0x3f, 0x00, + 0xf0, 0x7f, 0x00, 0xf0, 0x7f, 0x00, 0xf0, 0x7f, 0x00, 0xe0, 0x3f, 0x00, + 0xe0, 0x3f, 0x00, 0xc0, 0x1f, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rabbitbitmaps.h Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,142 @@ +/* $Id: rabbitbitmaps.h,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */ + +#define rmyplanet000_width 30 +#define rmyplanet000_height 30 +static unsigned char rmyplanet000_bits[] = +{ + 0x00, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, + 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, + 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02, + 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x60, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; +#define rmyplanet001_width 30 +#define rmyplanet001_height 30 +static unsigned char rmyplanet001_bits[] = +{ + 0x00, 0x18, 0x03, 0x07, 0x00, 0x00, 0x00, 0x05, 0xc0, 0x00, 0x60, 0x07, + 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, + 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, + 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02, + 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x60, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; +#define rmyplanet010_width 30 +#define rmyplanet010_height 30 +static unsigned char rmyplanet010_bits[] = +{ + 0x1c, 0x18, 0x03, 0x00, 0x14, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x60, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, + 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, + 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02, + 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x60, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; +#define rmyplanet011_width 30 +#define rmyplanet011_height 30 +static unsigned char rmyplanet011_bits[] = +{ + 0x1c, 0x18, 0x03, 0x07, 0x14, 0x00, 0x00, 0x05, 0xdc, 0x00, 0x60, 0x07, + 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, + 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, + 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02, + 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x60, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; +#define rmyplanet100_width 30 +#define rmyplanet100_height 30 +static unsigned char rmyplanet100_bits[] = +{ + 0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x00, 0x60, 0x00, + 0x20, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, + 0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x08, + 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x10, + 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, + 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, + 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, + 0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x02, + 0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0, 0x00, 0x60, 0x00, +0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; +#define rmyplanet101_width 30 +#define rmyplanet101_height 30 +static unsigned char rmyplanet101_bits[] = +{ + 0x00, 0xf8, 0x03, 0x07, 0x00, 0x07, 0x1c, 0x05, 0xc0, 0x00, 0x60, 0x07, + 0x20, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x08, + 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x10, + 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, + 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, + 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, + 0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x02, + 0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0, 0x00, 0x60, 0x00, +0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; +#define rmyplanet110_width 30 +#define rmyplanet110_height 30 +static unsigned char rmyplanet110_bits[] = +{ + 0x1c, 0xf8, 0x03, 0x00, 0x14, 0x07, 0x1c, 0x00, 0xdc, 0x00, 0x60, 0x00, + 0x10, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, + 0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x08, + 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x10, + 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, + 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, + 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, + 0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x02, + 0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0, 0x00, 0x60, 0x00, +0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; +#define rmyplanet111_width 30 +#define rmyplanet111_height 30 +static unsigned char rmyplanet111_bits[] = +{ + 0x1c, 0xf8, 0x03, 0x07, 0x14, 0x07, 0x1c, 0x05, 0xdc, 0x00, 0x60, 0x07, + 0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x08, + 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x10, + 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, + 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, + 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, + 0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x02, + 0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0, 0x00, 0x60, 0x00, +0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}; +#define rmymplanet011_width 16 +#define rmymplanet011_height 16 +static unsigned char rmymplanet011_bits[] = +{ + 0xa0, 0x02, 0x08, 0x08, 0x40, 0x01, 0x42, 0x21, 0xc0, 0x01, 0x81, 0x4c, + 0x80, 0x14, 0x81, 0x54, 0x80, 0x14, 0x81, 0x5c, 0xc0, 0x01, 0x42, 0x21, +0x40, 0x01, 0x08, 0x08, 0xa0, 0x02, 0x00, 0x00}; +#define rmymplanet010_width 16 +#define rmymplanet010_height 16 +static unsigned char rmymplanet010_bits[] = +{ + 0xa0, 0x02, 0x08, 0x08, 0x40, 0x01, 0x42, 0x21, 0xc0, 0x01, 0x81, 0x40, + 0x80, 0x00, 0x81, 0x40, 0x80, 0x00, 0x81, 0x40, 0xc0, 0x01, 0x42, 0x21, +0x40, 0x01, 0x08, 0x08, 0xa0, 0x02, 0x00, 0x00}; +#define rmymplanet001_width 16 +#define rmymplanet001_height 16 +static unsigned char rmymplanet001_bits[] = +{ + 0xa0, 0x02, 0x08, 0x08, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x01, 0x4c, + 0x00, 0x14, 0x01, 0x54, 0x00, 0x14, 0x01, 0x5c, 0x00, 0x00, 0x02, 0x20, +0x00, 0x00, 0x08, 0x08, 0xa0, 0x02, 0x00, 0x00}; +#define rmymplanet000_width 16 +#define rmymplanet000_height 16 +static unsigned char rmymplanet000_bits[] = +{ + 0xa0, 0x02, 0x08, 0x08, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x01, 0x40, + 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x02, 0x20, +0x00, 0x00, 0x08, 0x08, 0xa0, 0x02, 0x00, 0x00};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ranklist.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,95 @@ +/* $Id: ranklist.c,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */ + +/* + * ranklist.c + * + * Kevin P. Smith 12/5/88 + * + */ +#include "copyright2.h" + +#include <stdio.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "proto.h" + +/* Prototypes */ +static void print_ranks_paradise P((void)); + + +void +ranklist() +{ + register int i; + char buf[80]; + + /* + W_ClearWindow(rankw); + */ + if (!paradise) { + (void) strcpy(buf, " Rank Hours Defense Ratings DI"); + W_WriteText(rankw, 1, 1, textColor, buf, strlen(buf), W_BoldFont); + for (i = 0; i < NUMRANKS; i++) { + sprintf(buf, "%-11.11s %5.0f %8.2f %8.2f %7.2f", + ranks[i].name, + ranks[i].hours, + ranks[i].defense, + ranks[i].ratings, + ranks[i].ratings * ranks[i].hours); + if (mystats->st_rank == i) { + W_WriteText(rankw, 1, i + 2, W_Cyan, buf, strlen(buf), W_BoldFont); + } else { + W_WriteText(rankw, 1, i + 2, textColor, buf, strlen(buf), + W_RegularFont); + } + } + strcpy(buf, "To achieve a rank, you need a high enough defense, and"); + W_WriteText(rankw, 1, i + 3, textColor, buf, strlen(buf), W_RegularFont); + strcpy(buf, "either enough hours, and bombing + planet + offense ratings"); + W_WriteText(rankw, 1, i + 4, textColor, buf, strlen(buf), W_RegularFont); + strcpy(buf, "above shown ratings, or too few hours, and a DI rating above"); + W_WriteText(rankw, 1, i + 5, textColor, buf, strlen(buf), W_RegularFont); + strcpy(buf, "the shown DI rating."); + W_WriteText(rankw, 1, i + 6, textColor, buf, strlen(buf), W_RegularFont); + } else { /* else we are in a paradise server */ + print_ranks_paradise(); + } +} + + + +static void +print_ranks_paradise() +{ + register int i; + char buf[80]; + + W_ResizeText(rankw, 65, nranks2 + 8); + + (void) strcpy(buf, " Rank genocides DI battle strategy special ships"); + W_WriteText(rankw, 1, 1, textColor, buf, strlen(buf), W_BoldFont); + for (i = 0; i < nranks2; i++) { + sprintf(buf, "%-11.11s %5d %8.2f %8.2f %8.2f %7.2f", + ranks2[i].name, + ranks2[i].genocides, + ranks2[i].di, + ranks2[i].battle, + ranks2[i].strategy, + ranks2[i].specship); + if (mystats->st_rank == i) { + W_WriteText(rankw, 1, i + 2, W_Cyan, buf, strlen(buf), W_BoldFont); + } else { + W_WriteText(rankw, 1, i + 2, textColor, buf, strlen(buf), W_RegularFont); + } + } + strcpy(buf, "To achieve a rank, you need a high enough number of"); + W_WriteText(rankw, 1, i + 3, textColor, buf, strlen(buf), W_RegularFont); + strcpy(buf, "genocides, a high enough DI, a high enough battle"); + W_WriteText(rankw, 1, i + 4, textColor, buf, strlen(buf), W_RegularFont); + strcpy(buf, "rating, a high enough strategy rating, and a high"); + W_WriteText(rankw, 1, i + 5, textColor, buf, strlen(buf), W_RegularFont); + strcpy(buf, "enough special ship rating"); + W_WriteText(rankw, 1, i + 6, textColor, buf, strlen(buf), W_RegularFont); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ratings.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,163 @@ +/* $Id: ratings.c,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */ + +/* + * ratings.c, 2/13/94 Bill Dyess + */ +#include "copyright.h" + +#include <stdio.h> +#include <math.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "gameconf.h" + +/* + fills the ratings struct pointed to by r with the stats for the player + pointed to by j [BDyess] +*/ +struct ratings * +get_ratings(j, r) + struct player *j; + struct ratings *r; +{ + if (paradise) { + struct stats2 *s; /* point to player's paradise stats */ + float t, t2; /* temps */ + + s = &(j->p_stats2); + /* fill in kills, losses, and maxkills based on ship type */ + if (j->p_ship->s_type == STARBASE) { + r->r_kills = s->st_sbkills; + r->r_losses = s->st_sblosses; + r->r_maxkills = s->st_sbmaxkills; + } else if (j->p_ship->s_type == WARBASE) { + r->r_kills = s->st_wbkills; + r->r_losses = s->st_wblosses; + r->r_maxkills = s->st_wbmaxkills; + } else { + r->r_kills = s->st_tkills; + r->r_losses = s->st_tlosses; + r->r_maxkills = s->st_tmaxkills; + } + /* calculate ratio */ + r->r_ratio = (r->r_losses != 0) ? r->r_kills / (float) r->r_losses + : r->r_kills; + /* + r->r_ratio = (s->st_tlosses != 0) ? (float) s->st_tkills / (float) + s->st_tlosses : s->st_tkills; + */ + if(!status2->timeprod) + t = s->st_tticks; + else + t = (float) s->st_tticks / (float) status2->timeprod; /* hour ratio */ + if (t == 0.0) + t = 1.0; + t2 = t * (float) status2->losses; /* get expected losses */ + if(t2 == 0) t2=1; + r->r_defrat = s->st_tlosses / t2; /* calc defense rating */ + + t2 = t * (float) status2->kills; /* get expected kills */ + if(t2 == 0) t2=1; + r->r_offrat = s->st_tkills / t2; /* calc offense rating */ + + t2 = t * (float) status2->armsbomb; /* expected armies bombed */ + if(t2 == 0) t2=1; + r->r_bombrat = (float) s->st_tarmsbomb / t2; /* bomb rating */ + + t2 = t * (float) status2->resbomb; /* expected resources bmbd */ + if(t2 == 0) t2=1; + r->r_resrat = (float) s->st_tresbomb / t2; /* resrce bmbd rating */ + + t2 = t * (float) status2->dooshes; /* expected armies dooshed */ + if(t2 == 0) t2=1; + r->r_dooshrat = (float) s->st_tdooshes / t2; /* doosh rating */ + + r->r_batrat = r->r_dooshrat + r->r_offrat; /* get battle rating */ + + t2 = t * (float) status2->planets; /* expected planets */ + if(t2 == 0) t2=1; + r->r_planetrat = (float) s->st_tplanets / t2; /* get planet rating */ + /* strategy rating */ + r->r_stratrat = r->r_bombrat + r->r_resrat + r->r_planetrat; + /* calculate sb rating */ + t2 = (float) status2->sbkills / (float)( (status2->sblosses > 0) ? status2->sblosses : 1); + if (s->st_sblosses == 0) + r->r_sbrat = 0.0; + else + r->r_sbrat = ((float) s->st_sbkills / (float) s->st_sblosses) / t2; + /* calculate wb rating */ + t2 = (float) status2->wbkills / (float)( (status2->wblosses > 0) ? status2->wblosses : 1); + if (s->st_wblosses == 0) + r->r_wbrat = 0.0; + else + r->r_wbrat = ((float) s->st_wbkills / (float) s->st_wblosses) / t2; + /* calculate js rating */ + t = (float) s->st_jsticks / (float)( (status2->jstime > 0) ? status2->jstime : 1); + t2 = t * (float) status2->jsplanets; /* get expected js planets */ + if (t2 == 0.0) + r->r_jsrat = 0.0; + else + r->r_jsrat = (float) s->st_jsplanets / t2; /* js rating */ + r->r_jsplanets = s->st_jsplanets; /* store js planets */ + + r->r_specrat = r->r_sbrat + r->r_wbrat + r->r_jsrat; /* get special ship + rating */ + /* put the sum of the three major ratings in the 'ratings' slot */ + r->r_ratings = r->r_specrat + r->r_batrat + r->r_stratrat; + r->r_genocides = s->st_genocides; /* get # genocides */ + r->r_di = s->st_di; /* get player's DI */ + t = (s->st_tticks) ? s->st_tticks : 1.0; + r->r_killsPerHour = r->r_kills * 36000.0 / t; + r->r_lossesPerHour = r->r_losses * 36000.0 / t; + r->r_planets = s->st_tplanets; + r->r_armies = s->st_tarmsbomb; + r->r_resources = s->st_tresbomb; + r->r_dooshes = s->st_tdooshes; + /* r->r_jsplanets = s->st_jsplanets; */ + } else { /* bronco stats */ + struct stats *s = &j->p_stats; + + r->r_offrat = offenseRating(j); /* offense */ + r->r_planetrat = planetRating(j); /* planet */ + r->r_bombrat = bombingRating(j); /* bombing */ + r->r_offrat = offenseRating(j); /* offense */ + r->r_defrat = defenseRating(j); /* defense */ + r->r_resrat = 0; /* these don't apply */ + r->r_dooshrat = 0; + r->r_stratrat = 0; + r->r_batrat = 0; + r->r_sbrat = 0; + r->r_wbrat = 0; + r->r_jsrat = 0; + r->r_jsplanets = 0; + r->r_specrat = 0; + r->r_ratings = r->r_offrat + r->r_planetrat + r->r_bombrat; /* ratings */ + r->r_di = r->r_ratings * s->st_tticks / 36000.0; /* di */ + /* fill in kills, losses, and ratio based on ship type */ + if (j->p_ship->s_type == STARBASE) { + r->r_kills = s->st_sbkills; + r->r_losses = s->st_sblosses; + r->r_ratio = (s->st_sblosses != 0) + ? (float) r->r_kills / (float) r->r_losses + : (float) j->p_stats.st_sbkills; + r->r_maxkills = j->p_stats.st_sbmaxkills; + } else { + r->r_kills = s->st_kills + s->st_tkills; + r->r_losses = s->st_losses + s->st_tlosses; + r->r_ratio = (r->r_losses != 0) + ? (float) r->r_kills / (float) r->r_losses + : r->r_kills; + r->r_maxkills = s->st_maxkills; + } + r->r_planets = s->st_tplanets + s->st_planets; + r->r_armies = s->st_armsbomb + s->st_tarmsbomb; + /* not recorded in bronco */ + r->r_resources = 0; + /* r->r_jsplanets = 0; */ + r->r_dooshes = 0; + r->r_genocides = 0; + } + return r; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/recorder.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,347 @@ +/* $Id: recorder.c,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */ + +#ifdef RECORDER + +#include <stdio.h> +#include <sys/types.h> +#include <sys/file.h> +#include <sys/stat.h> +#include <sys/select.h> +#include <fcntl.h> + +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "proto.h" +#include "packets.h" + +int record_total; +int lastTeamReq = -1; +int recfp = -1, playfp = -1; + +void pb_skip P((int frames)); + +void +startRecorder() +{ + if (recordGame = booleanDefault("recordGame", recordGame)) { + recordFile = stringDefault("recordFile", "/tmp/netrek.record"); + recordFile = expandFilename(recordFile); + maxRecord = intDefault("maxRecord", maxRecord); + recfp = open(recordFile, O_WRONLY | O_TRUNC | O_APPEND | O_CREAT, S_IRWXU); + if (recfp >= 0) + printf("Game being recorded to %s. Max size is %d\n", recordFile, maxRecord); + else { + perror("startRecorder"); + printf("Can't open file %s for recording\n", recordFile); + recordGame = 0; + } + } +} + +void +stopRecorder() +{ + char buf[80]; + + close(recfp); + recfp = -1; + recordGame = 0; + sprintf(buf, "Recording stopped, %d bytes (%d updates) written to %s\n", + record_total, udcounter, (recordFile==NULL) ? "Nothing" : recordFile); + warning(buf); +} + +void +recordPacket(data, len) + char *data; + int len; +{ + int res; + + if (recfp >= 0 && len > 0) { + switch (*data) { + case SP_PICKOK: /* playback needs to know what team! */ + data[2] = (char) lastTeamReq; + break; + case SP_RSA_KEY: + case SP_MOTD: + case SP_MOTD_PIC: + case SP_NEW_MOTD: + return; + default: + break; + } + res = write(recfp, data, len); + record_total += res; + if ((maxRecord && (record_total > maxRecord)) || (res <= 0)) + stopRecorder(); + } +} + +void +writeUpdateMarker() +{ + unsigned char update_buf[4]; + + update_buf[0] = REC_UPDATE; + /* + record stuff not normally sent by server. Otherwise tractors and lock + markers don't work during playback + */ + update_buf[1] = (unsigned char) me->p_tractor; + update_buf[2] = (unsigned char) ((me->p_flags & PFPLOCK) ? me->p_playerl : me->p_planet); + /* one more byte here, any ideas? */ + record_total += write(recfp, update_buf, 4); +} + +int +startPlayback() +{ + if (playback || (playback = booleanDefault("playback", 0))) { + if (!playFile) + playFile = stringDefault("playFile", "/tmp/netrek.record"); + playFile = expandFilename(playFile); + + playfp = open(playFile, O_RDONLY, 0); + if (playfp < 0) { + perror("startPlayback"); + printf("Couldn't open playback file %s\n", playFile); + exit(0); + } + printf("Replaying %s\n", playFile); + return 1; + } + return 0; +} + +int +readRecorded(fp, data, len) + int fp, len; + char *data; +{ + int ret; + + if (!playback || len < 0 || playfp < 0) + return -1; + if (len > 4) /* make sure we don't skip updates */ + len = 4; + ret = read(playfp, data, len); + if (ret <= 0) + EXIT(0); + return ret; +} + +void +pb_dokey(event) +W_Event *event; +{ + switch (event->key&0xff) { + case 'p': + case 'P': + paused = !paused; + pb_scan=0; + if (paused) + pb_advance = 0; + break; + case 'r': + case 'R': + pb_advance = PB_REDALERT; + paused = 0; + break; + case 'y': + case 'Y': + pb_advance = PB_YELLOWALERT; + paused = 0; + break; + case 'd': + case 'D': + pb_advance = PB_DEATH; + paused = 0; + break; + case ' ': + if(paused) { + if(pb_scan) + pb_skip(pb_advance); + else { + pb_advance=1; + paused=0; + } + } else { + paused = 1; + pb_advance=0; + } + break; + case 'f': + case 'F': /* fast forward */ + pb_scan=!pb_scan; + if(pb_scan) { + pb_advance=10; + pb_slow=0; + paused=0; + warning("1-9: set speed. P-Pause, F-Fast Fwd off"); + } else { + pb_advance=0; + pb_slow=0; + paused=0; + warning("Playback mode, keys: P)ause R)ed Y)ellow D)eath F)ast Q)uit"); + } + break; + case 's': /* Slow mode */ + case 'S': + if(pb_scan || paused || !pb_slow) + pb_slow=1; + else + pb_slow=0; + pb_scan=0; + paused=0; + pb_advance=0; + break; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if(!pb_scan) + pb_advance += (event->key - '0') * 10; + else + pb_advance = (event->key - '0') * 10; + paused = 0; + break; + case 'q': + case 'Q': + exit(0); + default: + warning("Playback mode, keys: P)ause R)ed Y)ellow D)eath F)ast Q)uit"); + } +} + +void +pb_skip(frames) + int frames; +{ + while(frames) { + pb_update=0; + readFromServer(); + frames-=pb_update; + udcounter+=pb_update; + } +} + +void +pb_framectr(xloc, yloc) + int xloc, yloc; +{ + char buf[20]; + + if(paused) + strcpy(buf,"PAU"); + else if(pb_scan) + strcpy(buf,"FFW"); + else if(pb_advance) { + switch(pb_advance) { + case PB_REDALERT: + strcpy(buf,"RED"); + break; + case PB_YELLOWALERT: + strcpy(buf,"YLW"); + break; + case PB_DEATH: + strcpy(buf,"DTH"); + break; + default: + buf[0]='+'; + buf[1]=(pb_advance / 10) + '0'; + buf[2]=(pb_advance % 10) + '0'; + break; + } + } else if(pb_slow) + strcpy(buf,"SLW"); + else + strcpy(buf,"NRM"); + + sprintf((buf+3),":%8d",udcounter); + + W_WriteText(tstatw, xloc, yloc, textColor, buf, 12, W_RegularFont); +} + +void +pb_input() +{ + W_Event data; + fd_set readfds; + int wsock = W_Socket(); + + struct timeval timeout; + + timeout.tv_sec = 0; + timeout.tv_usec = 200000; + + intrupt(); /* draws the first frame */ + + while (me->p_status == PALIVE || + me->p_status == PEXPLODE || + me->p_status == PDEAD || + me->p_status == POBSERVE) { + + if (keepInfo > 0) { + if (infowin_up >= 0 && + --infowin_up == -1 && + infomapped) { + destroyInfo(); + infowin_up = -2; + } + } + exitInputLoop = 0; + while (W_EventsPending() && !exitInputLoop) { + fastQuit = 0; /* any event cancel fastquit */ + W_NextEvent(&data); + dispatch_W_event(&data); + } + if (!paradise) /* stars are ok, it's just a recording. + zoom doesn't make sense. */ + blk_zoom = 0; + +#ifndef AMIGA + FD_ZERO(&readfds); + FD_SET(wsock, &readfds); + if (paused) { + select(32, &readfds, (fd_set *) 0, (fd_set *) 0, 0); + continue; + } else if(pb_slow && !pb_scan) + select(32, &readfds, (fd_set *) 0, (fd_set *) 0,&timeout); + + /* otherwise, in full blast mode, don't wait on anything. */ + +#else /* AMIGA */ + if (paused) { + sigsPending = Wait(wsock | SIGBREAKF_CTRL_C); + continue; + } else if(pb_slow && !pb_scan) { + StartTimer(0,200000); + while(1) { + sigsPending = Wait(wsock | portmask | SIGBREAKF_CTRL_C); + if((sigsPending & (wsock | SIGBREAKF_CTRL_C)) || + CheckIO(&(ior->tr_node))) + break; + } + + StopTimer(); + } + + if (sigsPending & SIGBREAKF_CTRL_C) { + printf("User break, Ctrl-C, exiting!\n"); + exit(0); + } +#endif /* AMIGA */ + /* at this point, we're sure it's time for at least one frame. */ + intrupt(); + } +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/redraw.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,2564 @@ +/* + * redraw.c + */ +#include "copyright.h" + +#include <stdio.h> +#include <signal.h> +#include <math.h> +#include <ctype.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "packets.h" +#include "proto.h" +#include "gameconf.h" +#ifdef SOUND +#include "Slib.h" +#endif +#include "sound.h" + +typedef struct tractor Tractor; +struct tractor { + int sx, sy, d1x, d1y, d2x, d2y; /* source (x,y) dest (x1,y1) (x2,y2) */ + Tractor *next; +} *tracthead = NULL, *tractcurrent = NULL, *tractrunner; + +struct _clearzone * +new_czone() +{ + if (clearzone == 0) { + czsize = 10; + clearzone = (struct _clearzone *) malloc(sizeof(*clearzone) * czsize); + clearcount = 0; + } else if (clearcount >= czsize) { + clearzone = (struct _clearzone *) realloc(clearzone, + sizeof(*clearzone) * (czsize *= 2)); + } + return &clearzone[clearcount++]; +} + +/* Prototypes */ +static void local P((void)); +#ifndef COW_HAS_IT_WHY_SHOULDNT_WE +static +#endif +void map P((void)); +static void redraw P((void)); +/* static void stline P((int flag));*/ +static W_Icon planetBitmap P((struct planet * p)); +static W_Icon planetmBitmap P((struct planet * p)); + +void +intrupt() +{ + static long lastread; + static struct timeval lastredraw = {0, 0}; + struct timeval t; + static int needredraw=0; + +#ifndef __osf__ + long time(); +#endif + + udcounter++; + + needredraw += readFromServer(); + + gettimeofday(&t, NULL); + if (needredraw && ((unsigned int) redrawDelay * 100000 < + (unsigned int) ((t.tv_sec - lastredraw.tv_sec) * 1000000 + + (t.tv_usec - lastredraw.tv_usec)))) { + needredraw = 0; + lastredraw=t; +#if 0 + lastread = time(NULL); +#endif +#ifdef RECORDER + if (!playback || (pb_update && + ((!pb_scan) || !(udcounter % pb_advance)))) +#endif + { + redraw(); + playerlist2(); + } +#ifdef RECORDER + if (playback) { + if(!pb_scan) { + if (pb_advance > 0) { + if ((pb_advance -= pb_update) <= 0) { + pb_advance = 0; + paused = 1; + } + } else if (pb_advance < 0) { + switch (pb_advance) { + case PB_REDALERT: + if (me->p_flags & PFRED) { + pb_advance = 0; + paused = 1; + } + break; + case PB_YELLOWALERT: + if (me->p_flags & PFYELLOW) { + pb_advance = 0; + paused = 1; + } + break; + case PB_DEATH: + default: + if (me->p_status != PALIVE) { + pb_advance = 0; + paused = 1; + } + break; + } + } + } + pb_update = 0; + } + if (recordGame) + writeUpdateMarker(); +#endif + } +#if 0 + if (lastread + 3 < time(NULL)) { + /* + We haven't heard from server for awhile... Strategy: send a + useless packet to "ping" server. + */ + sendWarReq(me->p_hostile); + } +#endif + if (me->p_status == POUTFIT) { + death(); + } +} + +static void +redraw() +{ + + /* erase warning line if necessary */ + if ((warntimer <= udcounter) && (warncount > 0)) { +#ifndef AMIGA + /* XFIX */ + W_ClearArea(warnw, 5, 5, W_Textwidth * warncount, W_Textheight); +#else + W_ClearWindow(warnw); +#endif + warncount = 0; + } + if (W_FastClear) { + W_ClearWindow(w); + clearcount = 0; + clearlcount = 0; + tractcurrent = tracthead; + } else { +#if 0 + /* just to save a little time on all the function calls */ + /* all the normal clear functions are implemented as well. */ + W_FlushClearZones(w, clearzone, clearcount); + clearcount = 0; +#else + while (clearcount) { + clearcount--; + /* XFIX */ + W_CacheClearArea(w, clearzone[clearcount].x, + clearzone[clearcount].y, clearzone[clearcount].width, + clearzone[clearcount].height); + + /* + W_ClearArea(w, clearzone[clearcount].x, + clearzone[clearcount].y, clearzone[clearcount].width, + clearzone[clearcount].height); + */ + } +#endif + while (clearlcount) { + clearlcount--; + /* XFIX */ + W_CacheLine(w, clearline[0][clearlcount], + clearline[1][clearlcount], clearline[2][clearlcount], + clearline[3][clearlcount], backColor); + /* + W_MakeLine(w, clearline[0][clearlcount], + clearline[1][clearlcount], clearline[2][clearlcount], + clearline[3][clearlcount], backColor); + */ + } + /* XFIX */ +#ifndef AMIGA + W_FlushClearAreaCache(w); + W_FlushLineCaches(w); +#endif + /* erase the tractor lines [BDyess] */ + for (tractrunner = tracthead; tractrunner != tractcurrent; + tractrunner = tractrunner->next) { + W_MakeTractLine(w, tractrunner->sx, tractrunner->sy, + tractrunner->d1x, tractrunner->d1y, + backColor); + W_MakeTractLine(w, tractrunner->sx, tractrunner->sy, + tractrunner->d2x, tractrunner->d2y, + backColor); + } + tractcurrent = tracthead; + } + + local(); /* redraw local window */ + +#ifdef AMIGA /* would do it in W_EventsPending, just have + it here so the display is updated sooner. */ + W_Flush(); +#endif + + /* XFIX */ + W_FlushLineCaches(w); + + stline(0); + + if (W_IsMapped(statwin)) + updateStats(); + + updateInform(); /* check and update info window [BDyess] */ + + /* XFIX: last since its least accurate information */ + if (mapmode) + map(); + +} + +static W_Icon terrainBitmap(int x, int y) +{ + int aster_bm = 0; + int aster_fluff = 0; + + /* is no asteroids, then return fluff if adjacent 'roids */ + if (!(terrainInfo[x*250 + y].types & T_ASTEROIDS)) aster_fluff = 1; + + /* check surrounding terrain */ + if (x > 0) + if (terrainInfo[(x-1)*250 + y].types & T_ASTEROIDS) + aster_bm |= (1<<0); + if (x < 249) + if (terrainInfo[(x+1)*250 + y].types & T_ASTEROIDS) + aster_bm |= (1<<2); + if (y > 0) + if (terrainInfo[x*250 + y-1].types & T_ASTEROIDS) + aster_bm |= (1<<3); + if (y < 249) + if (terrainInfo[x*250 + y+1].types & T_ASTEROIDS) + aster_bm |= (1<<1); + + if (aster_fluff && aster_bm) return asteroidfluff[(x*250 + y)%3]; + else return asteroidBM[aster_bm]; +} + +static W_Icon +planetBitmap(p) + register struct planet *p; +{ + int i; + if (paradise) { + switch (PL_TYPE(*p)) { + case PLWHOLE: + return wormBM[udcounter % WORMFRAMES]; + break; + case PLSTAR: + return starBM[udcounter % STARFRAMES]; + break; + case PLAST: + return basteroid[0]; + } + } + if (showlocal == 2) { + return (bplanets[0]); + } else if (p->pl_info & idx_to_mask(me->p_teami)) { + if (showlocal == 1 || showlocal == 4) { + i = 0; + if ((paradise) && (p->pl_flags & PLSHIPYARD)) + i += 8; + if (p->pl_armies > 4) + i += 4; + if (p->pl_flags & PLREPAIR) + i += 2; + if (p->pl_flags & PLFUEL) + i += 1; + return ((showlocal == 1 ? bplanets2 : bplanetsMOO)[i]); + } else if (showlocal == 0) { + int team = mask_to_idx(p->pl_owner); + if (team < -1) + team = -1; + else if (team >= number_of_teams) + team = number_of_teams - 1; + return (bplanets[1 + team]); + } else { + int mask; + if (paradise) + mask = (p->pl_flags & PLSURMASK) >> PLSURSHIFT; + else { + mask = ((p->pl_flags & PLFUEL) ? 1 : 0) + | ((p->pl_flags & PLREPAIR) ? 2 : 0) + | ((p->pl_flags & PLAGRI) ? 4 : 0); + } + return bplanetsr[mask]; + } + } else { + return (bplanets[5]); + } +} + + +static W_Icon +planetmBitmap(p) + register struct planet *p; +{ + int i; + if (paradise) { + switch (p->pl_flags & PLTYPEMASK) { + case PLSTAR: + return mstarBM; + case PLAST: + return mbasteroid[0]; +#ifdef VISIBLE_WORMHOLES + case PLWHOLE: + return mholeBM; +#endif /*VISIBLE_WORMHOLES*/ + } + } + if (showgalactic == 2) { + return (mbplanets[0]); + } else if (showgalactic == 4) { + int infoage = 4; + if (!(p->pl_info & idx_to_mask(me->p_teami))) + return mbplanetsA[NSCOUTAGES - 1]; + if (p->pl_owner == idx_to_mask(me->p_teami)) + return mbplanetsA[0]; + + for (i = 0; + i < NSCOUTAGES - 1 && infoage < status2->clock - p->pl_timestamp; + i++, infoage = infoage * 5 / 3) { + } + return mbplanetsA[i]; + } else if (p->pl_info & idx_to_mask(me->p_teami)) { + if (showgalactic == 1 || showgalactic == 5) { + i = 0; + if ((paradise) && (p->pl_flags & PLSHIPYARD)) + i += 8; + if (p->pl_armies > 4) + i += 4; + if (p->pl_flags & PLREPAIR) + i += 2; + if (p->pl_flags & PLFUEL) + i += 1; + return ((showgalactic == 1 ? mbplanets2 : mbplanetsMOO)[i]); + } else if (showgalactic == 0) { + int team = mask_to_idx(p->pl_owner); + if (team < -1) + team = -1; + else if (team >= number_of_teams) + team = number_of_teams - 1; + return (mbplanets[1 + team]); + } else { + int mask; + if (paradise) + mask = (p->pl_flags & PLSURMASK) >> PLSURSHIFT; + else { + mask = ((p->pl_flags & PLFUEL) ? 1 : 0) + | ((p->pl_flags & PLREPAIR) ? 2 : 0) + | ((p->pl_flags & PLAGRI) ? 4 : 0); + } + return mbplanetsr[mask]; + } + } else { + return (mbplanets[5]); + } +} + +/* call this from local for each player, instead of having an extra loop! */ +static void +redraw_photon_torps(j) + struct player *j; +{ + int i, h; + struct torp *k; + int dx, dy; + int view; + struct _clearzone *cz; + + view = SCALE * WINSIDE / 2; + i = j->p_no; + if (!j->p_ntorp) + return; + for (h = 0, k = &torps[ntorps * i + h]; h < ntorps; h++, k++) { + if (!k->t_status) + continue; + dx = k->t_x - me->p_x; + dy = k->t_y - me->p_y; + if (ABS(dx) > view || ABS(dy) > view) { + /* Call any torps off screen "free" (if owned by other) */ + if (k->t_status == TEXPLODE && j != me) { + k->t_status = TFREE; + j->p_ntorp--; + } + continue; + } + dx = dx / SCALE + WINSIDE / 2; + dy = dy / SCALE + WINSIDE / 2; +#ifdef UNIX_SOUND + if ((k->t_status == TEXPLODE) && (k->t_fuse == 5)) play_sound (SND_TORPHIT); +#endif + if (k->t_status == TEXPLODE) { + + k->t_fuse--; + if (k->t_fuse <= 0) { + k->t_status = TFREE; + j->p_ntorp--; + continue; + } + if (k->t_fuse >= NUMDETFRAMES) { + k->t_fuse = NUMDETFRAMES - 1; + } + W_WriteBitmap(dx - (cloud_width / 2), dy - (cloud_height / 2), + cloud[k->t_fuse], torpColor(k)); + cz = new_czone(); + cz->x = dx - (cloud_width / 2); + cz->y = dy - (cloud_height / 2); + cz->width = cloud_width; + cz->height = cloud_height; + } else if (k->t_owner != me->p_no && ((k->t_war & idx_to_mask(me->p_teami)) || + (idx_to_mask(players[k->t_owner].p_teami) & (me->p_hostile | me->p_swar)))) { + /* + solid. Looks strange. W_FillArea(w, dx - (etorp_width/2), dy + - (etorp_height/2), etorp_width, etorp_height, torpColor(k)); + */ + +#ifdef BORGTEST + W_CacheLine(w, dx - (etorp_width / 2), dy - (etorp_height / 2), + dx + (etorp_width / 2), dy + (etorp_height / 2), + (k->t_turns == 32767) ? notColor(k) : torpColor(k)); + W_CacheLine(w, dx + (etorp_width / 2), dy - (etorp_height / 2), + dx - (etorp_width / 2), dy + (etorp_height / 2), + (k->t_turns == 32767) ? notColor(k) : torpColor(k)); +#else +#ifdef TORPBITS + /* + went back to this for Amiga, one bitmap is faster than 2 + lines. + */ + W_WriteBitmap(dx - (etorp_width / 2), dy - (etorp_height / 2), + etorp, torpColor(k)); +#else + /* XFIX */ + if (0 && k->frame) { + W_CacheLine(w, dx - 2, dy, + dx + 2, dy, torpColor(k)); + W_CacheLine(w, dx, dy - 2, + dx, dy + 2, torpColor(k)); + } else { + W_CacheLine(w, dx - 1, dy - 1, + dx + 1, dy + 1, torpColor(k)); + W_CacheLine(w, dx + 1, dy - 1, + dx - 1, dy + 1, torpColor(k)); + } + k->frame = !k->frame; +#endif /* TORPBITS */ +#endif + + cz = new_czone(); + cz->x = dx - (etorp_width / 2); + cz->y = dy - (etorp_height / 2); + cz->width = etorp_width; + cz->height = etorp_height; + } else { + /* XFIX */ + + if (0 /* animateTorps */ ) { + switch (k->frame) { + case 0: + W_CacheLine(w, dx - (mtorp_width / 2), dy, dx, + dy, torpColor(k)); + break; + case 1: + W_CacheLine(w, dx - (mtorp_width / 2), dy - (mtorp_width / 2), + dx, dy, torpColor(k)); + break; + case 2: + W_CacheLine(w, dx, dy, dx, + dy + (mtorp_width / 2), torpColor(k)); + break; + case 3: + W_CacheLine(w, dx, dy, + dx + (mtorp_width / 2), dy - (mtorp_width / 2), torpColor(k)); + break; + case 4: + W_CacheLine(w, dx, dy, dx + (mtorp_width / 2), + dy, torpColor(k)); + break; + case 5: + W_CacheLine(w, dx - (mtorp_width / 2), dy - (mtorp_width / 2), + dx, dy, torpColor(k)); + break; + case 6: + W_CacheLine(w, dx, dy - (mtorp_width / 2), dx, + dy, torpColor(k)); + break; + case 7: + W_CacheLine(w, dx - (mtorp_width / 2), dy - (mtorp_width / 2), + dx, dy, torpColor(k)); + break; + } + k->frame++; + if (k->frame > 7) + k->frame = 0; + } else { +#ifdef TORPBITS + W_WriteBitmap(dx - (mtorp_width / 2), dy - (mtorp_height / 2), + mtorp, torpColor(k)); +#else + W_CacheLine(w, dx - (mtorp_width / 2), dy, + dx + (mtorp_width / 2), dy, torpColor(k)); + W_CacheLine(w, dx, dy - (mtorp_width / 2), + dx, dy + (mtorp_width / 2), torpColor(k)); +#endif + } + + cz = new_czone(); + cz->x = dx - (mtorp_width / 2); + cz->y = dy - (mtorp_height / 2); + cz->width = mtorp_width; + cz->height = mtorp_height; + } + } +} + +static void +draw_one_thingy(k) + struct thingy *k; +{ + int dx, dy; + int view; + struct _clearzone *cz; + view = SCALE * WINSIDE / 2; + + if (k->t_shape == SHP_BLANK) + return; + /* printf("%d,%d - %d,%d\n", me->p_x, me->p_y, k->t_x, k->t_y); */ + dx = k->t_x - me->p_x; + dy = k->t_y - me->p_y; + if (ABS(dx) > view || ABS(dy) > view) { + return; + } + dx = dx / SCALE + WINSIDE / 2; + dy = dy / SCALE + WINSIDE / 2; + switch (k->t_shape) { + case SHP_BOOM: + k->t_fuse--; + if (k->t_fuse <= 0) { + k->t_shape = SHP_BLANK; + return; + } + if (k->t_fuse >= NUMDETFRAMES) { + k->t_fuse = NUMDETFRAMES - 1; + } + W_WriteBitmap(dx - (cloud_width / 2), dy - (cloud_height / 2), + cloud[k->t_fuse], droneColor(k)); + cz = new_czone(); + cz->x = dx - (cloud_width / 2); + cz->y = dy - (cloud_height / 2); + cz->width = cloud_width; + cz->height = cloud_height; + break; + case SHP_MISSILE: + { + int dview = (int) (k->t_dir * NDRONEVIEWS + 128) / 256; + if (dview >= NDRONEVIEWS) + dview -= NDRONEVIEWS; + W_WriteBitmap + (dx - (drone_width / 2), dy - (drone_height / 2), + drone_bm[dview], + droneColor(k)); + } + cz = new_czone(); + cz->x = dx - (drone_width / 2); + cz->y = dy - (drone_height / 2); + cz->width = drone_width; + cz->height = drone_height; + break; + case SHP_TORP: + if (k->t_owner != me->p_no && + ((k->t_war & idx_to_mask(me->p_teami)) || + (idx_to_mask(players[k->t_owner].p_teami) & (me->p_hostile | me->p_swar)))) { + W_CacheLine(w, dx - (etorp_width / 2), dy - (etorp_height / 2), + dx + (etorp_width / 2), dy + (etorp_height / 2), torpColor(k)); + W_CacheLine(w, dx + (etorp_width / 2), dy - (etorp_height / 2), + dx - (etorp_width / 2), dy + (etorp_height / 2), torpColor(k)); + cz = new_czone(); + cz->x = dx - (etorp_width / 2); + cz->y = dy - (etorp_height / 2); + cz->width = etorp_width; + cz->height = etorp_height; + } else { + W_CacheLine(w, dx - (mtorp_width / 2), dy, dx + (mtorp_width / 2), dy, + torpColor(k)); + W_CacheLine(w, dx, dy - (mtorp_width / 2), dx, dy + (mtorp_width / 2), + torpColor(k)); + cz = new_czone(); + cz->x = dx - (mtorp_width / 2); + cz->y = dy - (mtorp_height / 2); + cz->width = mtorp_width; + cz->height = mtorp_height; + } + break; + case SHP_PLASMA: + case SHP_MINE: /* use plasma until I get a nifty bitmap */ + if (k->t_owner != me->p_no && + ((k->t_war & idx_to_mask(me->p_teami)) || + (idx_to_mask(players[k->t_owner].p_teami) & (me->p_hostile | me->p_swar)))) { + W_WriteBitmap(dx - (eplasmatorp_width / 2), + dy - (eplasmatorp_height / 2), + eplasmatorp, torpColor(k)); + cz = new_czone(); + cz->x = dx - (eplasmatorp_width / 2); + cz->y = dy - (eplasmatorp_height / 2); + cz->width = eplasmatorp_width; + cz->height = eplasmatorp_height; + } else { + W_WriteBitmap(dx - (mplasmatorp_width / 2), + dy - (mplasmatorp_height / 2), + mplasmatorp, torpColor(k)); + cz = new_czone(); + cz->x = dx - (mplasmatorp_width / 2); + cz->y = dy - (mplasmatorp_height / 2); + cz->width = mplasmatorp_width; + cz->height = mplasmatorp_height; + } + break; + case SHP_PBOOM: + k->t_fuse--; + if (k->t_fuse <= 0) { + k->t_shape = SHP_BLANK; + return; + } + if (k->t_fuse >= NUMDETFRAMES) { + k->t_fuse = NUMDETFRAMES - 1; + } + W_WriteBitmap(dx - (plasmacloud_width / 2), + dy - (plasmacloud_height / 2), + plasmacloud[k->t_fuse], torpColor(k)); + cz = new_czone(); + cz->x = dx - (plasmacloud_width / 2); + cz->y = dy - (plasmacloud_height / 2); + cz->width = plasmacloud_width; + cz->height = plasmacloud_height; + break; + case SHP_FIGHTER: + { + int fview = (int) (k->t_dir * VIEWS + 128) / 256; + if (fview >= VIEWS) + fview -= VIEWS; + W_WriteBitmap(dx - (fighter_width / 2), + dy - (fighter_height / 2), + fighter[fview], torpColor(k)); + cz = new_czone(); + cz->x = dx - (fighter_width / 2); + cz->y = dy - (fighter_height / 2); + cz->width = fighter_width; + cz->height = fighter_height; + } + break; + case SHP_WARP_BEACON: + { + cz = new_czone(); + cz->x = dx - (warpbeacon_width / 2); + cz->y = dy - (warpbeacon_height / 2); + cz->width = warpbeacon_width; + cz->height = warpbeacon_height; + W_WriteBitmap(cz->x, cz->y, + warpbeacon, W_White); + if (k->t_fuse > 4) { + W_WriteBitmap(cz->x, cz->y, + wbflash, shipCol[1 + mask_to_idx(k->t_owner)]); + } + if (++(k->t_fuse) > 6) + k->t_fuse = 0; + } + } +} + +static void +redraw_drones(j) + struct player *j; +{ + int i, h; + int count; + + i = j->p_no; + + if (!j->p_ndrone) + return; + count = 0; + + for (h = i * npthingies; h < npthingies * (i + 1); h++) { + draw_one_thingy(&thingies[h]); + if (thingies[h].t_shape != SHP_BLANK) + count++; + } + j->p_ndrone = count; +} + +static void +redraw_other_drones() +{ + int h; + + for (h = 0; h < ngthingies; h++) + draw_one_thingy(&thingies[nplayers * npthingies + h]); +} + +static void +redraw_plasma_torps(j) + struct player *j; +{ + int h, i; + register struct plasmatorp *pt; + struct _clearzone *cz; + + int dx, dy; + int view; + + view = SCALE * WINSIDE / 2; + i = j->p_no; + + if (!j->p_nplasmatorp) + return; + for (h = 0, pt = &plasmatorps[nplasmas * i + h]; h < nplasmas; h++, pt++) { + if (!pt->pt_status) + continue; + dx = pt->pt_x - me->p_x; + dy = pt->pt_y - me->p_y; + if (ABS(dx) > view || ABS(dy) > view) + continue; + dx = dx / SCALE + WINSIDE / 2; + dy = dy / SCALE + WINSIDE / 2; +#ifdef UNIX_SOUND + if ((pt->pt_status == TEXPLODE) && (pt->pt_fuse == 5)) + play_sound (SND_TORPHIT); /* Torp Hit used for Plasma Hit */ +#endif + if (pt->pt_status == PTEXPLODE) { + pt->pt_fuse--; + if (pt->pt_fuse <= 0) { + pt->pt_status = PTFREE; + j->p_nplasmatorp--; + continue; + } + if (pt->pt_fuse >= NUMDETFRAMES) { + pt->pt_fuse = NUMDETFRAMES - 1; + } + W_WriteBitmap(dx - (plasmacloud_width / 2), + dy - (plasmacloud_height / 2), + plasmacloud[pt->pt_fuse], plasmatorpColor(pt)); + cz = new_czone(); + cz->x = dx - (plasmacloud_width / 2); + cz->y = dy - (plasmacloud_height / 2); + cz->width = plasmacloud_width; + cz->height = plasmacloud_height; + } + /* needmore: if(pt->pt_war & idx_to_mask(me->p_teami)) */ + else if (pt->pt_owner != me->p_no && ((pt->pt_war & idx_to_mask(me->p_teami)) || + (idx_to_mask(players[pt->pt_owner].p_teami) & (me->p_hostile | me->p_swar)))) { + W_WriteBitmap(dx - (eplasmatorp_width / 2), + dy - (eplasmatorp_height / 2), + eplasmatorp, plasmatorpColor(pt)); + cz = new_czone(); + cz->x = dx - (eplasmatorp_width / 2); + cz->y = dy - (eplasmatorp_height / 2); + cz->width = eplasmatorp_width; + cz->height = eplasmatorp_height; + } else { + W_WriteBitmap(dx - (mplasmatorp_width / 2), + dy - (mplasmatorp_height / 2), + mplasmatorp, plasmatorpColor(pt)); + cz = new_czone(); + cz->x = dx - (mplasmatorp_width / 2); + cz->y = dy - (mplasmatorp_height / 2); + cz->width = mplasmatorp_width; + cz->height = mplasmatorp_height; + } + } +} + +#ifdef HOCKEY +void tactical_hockey P((void)); +#endif + +void +redraw_terrain() +{ + int i,j; + int view; + int nx, ny; /* for adjusted coords, based on ship position */ + int tx, ty, x; /* terrain grid x and y for 0,0 on the local */ + struct _clearzone *cz; + + view = SCALE * WINSIDE / 2; + + nx = (int) ((me->p_x - view) / SCALE)%terrain_width; + ny = (int) ((me->p_y - view) / SCALE)%terrain_height; + + ty = (int) ((me->p_y - view)/(GWIDTH/250)); + x = tx = (int) ((me->p_x - view)/(GWIDTH/250)); + if (ty < 0) ty = 0; + if (tx < 0) { + tx = 0; + x = 0; + } + + if(received_terrain_info) { + for (i=0; i < WINSIDE; i += terrain_height) { + for (j=0; j < WINSIDE; j += terrain_width) { + if ((terrainInfo[tx*250+ty].types & T_ASTEROIDS) || + ((tx > 0) && (terrainInfo[(tx-1)*250+ty].types & T_ASTEROIDS)) || + ((tx < 249) && (terrainInfo[(tx+1)*250+ty].types & T_ASTEROIDS)) || + ((ty > 0) && (terrainInfo[tx*250+(ty-1)].types & T_ASTEROIDS)) || + ((tx < 249) && (terrainInfo[tx*250+(ty+1)].types & T_ASTEROIDS))) { + W_WriteBitmap(j-nx, i-ny, terrainBitmap(tx,ty), W_Grey); + cz = new_czone(); + cz->x = j-nx; + cz->y = i-ny; + cz->width = terrain_width; + cz->height = terrain_height; + } + tx++; + if (tx >= 250) { + tx = x; + break; + } + } + ty++; + if (ty >= 250) break; + tx = x; + } + } +} + +void +redraw_all_planets() +{ + int view; + int i; + int dx, dy; + struct _clearzone *cz; + struct planet *l; + int nplan; + + view = SCALE * WINSIDE / 2; + nplan = paradise ? nplanets : 40; + +#ifdef HOCKEY + if(hockey) { + tactical_hockey(); + } +#endif /*HOCKEY*/ + for (i = 0, l = &planets[i]; i < nplan; i++, l++) { + dx = l->pl_x - me->p_x; + dy = l->pl_y - me->p_y; + if (ABS(dx) > view || ABS(dy) > view) + continue; + dx = dx / SCALE + WINSIDE / 2; + dy = dy / SCALE + WINSIDE / 2; + if (PL_TYPE(*l) == PLWHOLE) + W_WriteBitmap(dx - (wormhole_width / 2), dy - (wormhole_height / 2), + planetBitmap(l), + ((paradise) && (PL_TYPE(*l) == PLWHOLE)) + ? textColor + : planetColor(l)); + else + W_WriteBitmap(dx - (planet_width / 2), dy - (planet_height / 2), + planetBitmap(l), + ((paradise) && (PL_TYPE(*l) == PLSTAR)) + ? textColor + : planetColor(l)); +#ifdef SHOW_IND + if (showIND && (l->pl_info & idx_to_mask(me->p_teami)) && (l->pl_owner == NOBODY) && l->pl_flags & PLPLANET) + { + W_CacheLine (w, dx - (planet_width / 2), dy - (planet_height / 2), + dx + (planet_width / 2 - 1), dy + (planet_height / 2 - 1), + W_White); + W_CacheLine (w, dx + (planet_width / 2 - 1), dy - (planet_height / 2), + dx - (planet_width / 2), dy + (planet_height / 2 - 1), + W_White); + } +#endif + if (namemode) { + if (PL_TYPE(*l) != PLWHOLE) { + W_MaskText(w, dx - l->pl_namelen * W_Textwidth / 2, dy + (planet_height / 2), + ((paradise) && (PL_TYPE(*l) == PLSTAR)) + ? textColor + : planetColor(l), + l->pl_name, l->pl_namelen, planetFont(l)); + cz = new_czone(); + cz->x = dx - l->pl_namelen * W_Textwidth / 2; + cz->y = dy + (planet_height / 2); + cz->width = W_Textwidth * l->pl_namelen; + cz->height = W_Textheight; + } + } + /* put letters and number next to */ + /* planet bitmaps for resources and */ + /* armies */ + if (paradise && tacPlanetInfo) { + if (PL_TYPE(*l) == PLPLANET) { + char dspstr[8]; + if (tacPlanetInfo & 1) + sprintf(dspstr, "%d", l->pl_armies); + if ((tacPlanetInfo & 2) && (l->pl_flags & PLREPAIR)) + strcat(dspstr, "R"); + if ((tacPlanetInfo & 4) && (l->pl_flags & PLFUEL)) + strcat(dspstr, "F"); + if ((tacPlanetInfo & 8) && (l->pl_flags & PLAGRI)) + strcat(dspstr, "A"); + if ((tacPlanetInfo & 16) && (l->pl_flags & PLSHIPYARD)) + strcat(dspstr, "S"); + cz = new_czone(); + cz->x = dx + planet_width/2 + 2; + cz->y = dy; + cz->width = W_Textwidth * strlen(dspstr); + cz->height = W_Textheight; + W_MaskText(w, cz->x, cz->y, + planetColor(l), dspstr, strlen(dspstr), + planetFont(l)); + } + } + + /*--------draw tactical lock*/ + if ((showLock & 2) && (me->p_flags & PFPLLOCK) && (me->p_planet == l->pl_no)) { + W_WriteTriangle(w, dx, dy - (planet_height) / 2 - 6, 5, 0, foreColor); + cz=new_czone(); + cz->x=dx-5; + cz->y=dy - (planet_height) / 2 - 12; + cz->width=11; + cz->height=7; + } + cz = new_czone(); + if (PL_TYPE(*l) == PLWHOLE) { + cz->x = dx - (wormhole_width / 2); + cz->y = dy - (wormhole_height / 2); + cz->width = wormhole_width; + cz->height = wormhole_height; + } else { + cz->x = dx - (planet_width / 2); + /*cz->y = dy - (planet_height / 2) - 13;*/ + cz->y = dy - (planet_height / 2); + cz->width = planet_width; + /*cz->height = planet_height + 26;*/ + cz->height = planet_height; + } + } +} + +void +doShowMySpeed(dx, dy, ship_bits, j) + int dx, dy; + struct ship_shape *ship_bits; + struct player *j; +{ + struct _clearzone *cz; + char idbuf[5]; + int len; + int color; + + sprintf(idbuf, "%c,%d", *(shipnos + j->p_no), me->p_speed); + len = strlen(idbuf); + /* + color the playernum,speed based on warp/afterburn/warpprep state + [BDyess] + */ + switch (me->p_flags & (PFWARP | PFAFTER | PFWARPPREP)) { + case PFWARP: + color = W_Cyan; + me->p_flags &= ~PFWARPPREP; + break; + case PFAFTER: + color = rColor; + break; + case PFWARPPREP: + color = yColor; + break; + default: /* impulse */ + if (me->p_speed > 0) { + color = gColor; + } else { /* stopped */ + color = textColor; + } + break; + } + dx += ship_bits->width / 2; + dy -= ship_bits->height / 2; + /* underline number,speed if warp is suspended [BDyess] */ + W_MaskText(w, dx, dy, color, idbuf, len, (me->p_flags & PFWPSUSPENDED) ? + W_UnderlineFont : shipFont(j)); + + cz = new_czone(); + cz->x = dx; + cz->y = dy; + cz->width = len * W_Textwidth; + cz->height = W_Textheight; +} + +#ifdef LOCAL_SHIPSTATS +/* show just about anything next to ship on local display + DSFAPWE - for each letter in statString, show a line for: + Damage, Shields, Fuel, Armies, sPeed, Wtemp, Etemp + + lower case = reverse length + */ +static void +doLocalShipstats() +{ + char *sptr; + int num=0, len, x=localStatsX, i; + struct _clearzone *cz; + W_Color color; + + for(sptr=statString;*sptr;sptr++) { + switch(toupper(*sptr)) { + case 'W': + len=(statHeight*me->p_wtemp) / me->p_ship->s_maxwpntemp; + break; + case 'E': + len=(statHeight*me->p_etemp) / me->p_ship->s_maxegntemp; + break; + case 'P': + len=(statHeight*me->p_speed)/me->p_ship->s_maxspeed; + break; + case 'D': + len=(statHeight*me->p_damage)/me->p_ship->s_maxdamage; + break; + case 'S': + len=statHeight - ((statHeight*me->p_shield)/me->p_ship->s_maxshield); + break; + case 'F': + len=statHeight - ((statHeight*me->p_fuel)/me->p_ship->s_maxfuel); + break; + case 'A': + len= me->p_ship->s_maxarmies ? + (statHeight*me->p_armies)/me->p_ship->s_maxarmies : 0; + break; + default: + continue; + } + if(islower(*sptr)) + len=statHeight - len; + if(len>statHeight) + len=statHeight; + + if(len>2*(statHeight/3) || toupper(*sptr) == 'A') + color=W_Red; + else if(len<(statHeight/3)) + color=W_Green; + else + color=W_Yellow; + if(len>0) + W_CacheLine(w,x+W_Textwidth/2,localStatsY-len,x+W_Textwidth/2,localStatsY,color); + W_MaskText(w,x,localStatsY+1,W_White,sptr,1,W_RegularFont); + x+=W_Textwidth; + } + if(x>localStatsX) { + W_CacheLine(w,localStatsX,localStatsY-statHeight,x,localStatsY-statHeight,W_White); + W_CacheLine(w,localStatsX,localStatsY,x,localStatsY,W_White); + cz=new_czone(); + cz->x=localStatsX; + cz->y=localStatsY-statHeight+1; + cz->width=x-localStatsX; + cz->height=statHeight-2; + } +} +#endif + +static void +local() +{ + register int i; + register struct player *j; + register struct phaser *php; + struct _clearzone *cz; + + int dx, dy; + int view; + char idbuf[10]; + struct ship_shape *ship_bits; + if (showKitchenSink) { + cz = new_czone(); + cz->width = 76; + cz->height = 60; + cz->x = 500 - cz->width; + cz->y = 0; + W_WriteBitmap(cz->x, cz->y, kitchenSink, W_Grey); + } + /* + Kludge to try to fix missing ID chars on tactical (short range) + display. + */ + idbuf[0] = '0'; + idbuf[1] = '\0'; + /* Draw Terrain */ + redraw_terrain(); + /* Draw Planets */ + redraw_all_planets(); + /* Draw ships */ + view = SCALE * WINSIDE / 2; + for (i = 0, j = &players[i]; i < nplayers; i++, j++) { + int tx, ty; + if (me->p_x < 0) + continue; + + /* more efficient than using a separate loop for this */ + redraw_photon_torps(j); + redraw_drones(j); + redraw_plasma_torps(j); + + if ((j->p_status != PALIVE) && (j->p_status != PEXPLODE)) + continue; + +#ifdef UNIX_SOUND + if (myPlayer(j) && (j->p_flags & PFCLOAK) && + (j->p_cloakphase == 0)) play_sound (SND_CLOAK); + if (myPlayer(j) && (!(j->p_flags & PFCLOAK)) && + (j->p_cloakphase == 6)) play_sound (SND_CLOAK); +#endif + + if (j->p_flags & PFCLOAK) { + if (j->p_cloakphase < (CLOAK_PHASES - 1)) { + j->p_cloakphase++; + } + } else { + if (j->p_cloakphase) { + j->p_cloakphase--; + } + } + dx = j->p_x - me->p_x; + dy = j->p_y - me->p_y; + if (ABS(dx) > view || ABS(dy) > view) { + if(j->p_status == PEXPLODE) + j->p_explode++; + continue; + } + dx = dx / SCALE + WINSIDE / 2; + dy = dy / SCALE + WINSIDE / 2; + if (j->p_status == PALIVE) { + + ship_bits = shape_of_ship(j->p_teami, j->p_ship->s_bitmap); + + if (j->p_flags & PFCLOAK && (j->p_cloakphase == (CLOAK_PHASES - 1))) { + if (myPlayer(j)) { + W_WriteBitmap(dx - (cloak_width / 2), dy - (cloak_height / 2), + cloakicon, myColor); + cz = new_czone(); + cz->x = dx - (ship_bits->width / 2 + 1); + cz->y = dy - (ship_bits->height / 2 + 1); + cz->width = ship_bits->width + 2; + cz->height = ship_bits->height + 2; + doShields(dx, dy, ship_bits, j); +#ifdef VARY_HULL + doHull(dx, dy, ship_bits, j); +#endif /* VARY_HULL */ + if (showMySpeed) + doShowMySpeed(dx, dy, ship_bits, j); + } + continue; + } + cz = new_czone(); +#ifdef BEEPLITE + if (emph_player_seq_n[j->p_no] > 0 && + ((F_beeplite_flags & LITE_PLAYERS_LOCAL) || + ((j == me) && (F_beeplite_flags & LITE_SELF)))) { + int seq_n = emph_player_seq_n[j->p_no] % emph_player_seql_frames; + + cz->x = dx - (emph_player_seql_width / 2); + cz->y = dy - (emph_player_seql_height / 2); + cz->width = emph_player_seql_width; + cz->height = emph_player_seql_height; + + W_WriteBitmap(dx - (emph_player_seql_width / 2), + dy - (emph_player_seql_height / 2), + emph_player_seql[seq_n], + emph_player_color[j->p_no]); + } else +#endif + { + cz->x = dx - (ship_bits->width / 2); + cz->y = dy - (ship_bits->height / 2); + cz->width = ship_bits->width; + cz->height = ship_bits->height; + } + W_WriteBitmap(dx - (ship_bits->width / 2), + dy - (ship_bits->height / 2), + ship_bits->bmap[rosette((int) j->p_dir, + (int) ship_bits->nviews)], playerColor(j)); + if (j->p_cloakphase > 0) { + W_WriteBitmap(dx - (cloak_width / 2), + dy - (cloak_height / 2), cloakicon, playerColor(j)); + doShields(dx, dy, ship_bits, j); + if (j == me) { +#ifdef VARY_HULL + doHull(dx, dy, ship_bits, j); +#endif /* VARY_HULL */ + if (showMySpeed) + doShowMySpeed(dx, dy, ship_bits, j); + } + continue; + } + if (showLock & 2) { + if ((me->p_flags & PFPLOCK) && (me->p_playerl == j->p_no)) { + W_WriteTriangle(w, dx, dy + (ship_bits->width / 2), + 4, 1, foreColor); + cz = new_czone(); + cz->x = dx - 4; + cz->y = dy + (ship_bits->height / 2); + cz->width = 9; + cz->height = 5; + } + } + doShields(dx, dy, ship_bits, j); +#ifdef VARY_HULL + doHull(dx, dy, ship_bits, j); +#endif /* VARY_HULL */ + if (showMySpeed && j == me) + doShowMySpeed(dx, dy, ship_bits, j); + else { + int color = playerColor(j); + idbuf[0] = *(shipnos + j->p_no); + + W_MaskText(w, dx + (ship_bits->width / 2), + dy - (ship_bits->height / 2), color, + idbuf, 1, shipFont(j)); + + cz = new_czone(); + cz->x = dx + (ship_bits->width / 2); + cz->y = dy - (ship_bits->height / 2); + cz->width = W_Textwidth; + cz->height = W_Textheight; + } + } else if (j->p_status == PEXPLODE) { + int i; + i = j->p_explode; + if (i < EX_FRAMES || (i < SBEXPVIEWS && j->p_ship->s_type == STARBASE)) { + +#ifdef SOUND + if(i==0) + S_PlaySound(S_EXPLOSION); +#endif +#ifdef UNIX_SOUND + if (i==0) + { + if (j->p_ship->s_type == STARBASE) + play_sound(SND_EXP_SB); /* Starbase Explode */ + else play_sound(SND_EXPLOSION); /* Ship Explosion */ + } +#endif + + cz = new_czone(); + if (j->p_ship->s_type == STARBASE) { + W_WriteBitmap(dx - (sbexp_width / 2), + dy - (sbexp_height / 2), sbexpview[i], + playerColor(j)); + cz->x = dx - (sbexp_width / 2); + cz->y = dy - (sbexp_height / 2); + cz->width = sbexp_width; + cz->height = sbexp_height; + } else { + W_WriteBitmap(dx - (ex_width / 2), dy - (ex_height / 2), + expview[i], playerColor(j)); + cz->x = dx - (ex_width / 2); + cz->y = dy - (ex_height / 2); + cz->width = ex_width; + cz->height = ex_height; + } + j->p_explode++; + } + } + /* Now draw his phaser (if it exists) */ + php = &phasers[j->p_no]; + if (php->ph_status != PHFREE) { + if (php->ph_status == PHMISS) { + /* Here I will have to compute end coordinate */ + tx = j->p_x + j->p_ship->s_phaserrange * Cos[php->ph_dir]; + ty = j->p_y + j->p_ship->s_phaserrange * Sin[php->ph_dir]; + tx = (tx - me->p_x) / SCALE + WINSIDE / 2; + ty = (ty - me->p_y) / SCALE + WINSIDE / 2; + } else if (php->ph_status == PHHIT2) { + tx = (php->ph_x - me->p_x) / SCALE + WINSIDE / 2; + ty = (php->ph_y - me->p_y) / SCALE + WINSIDE / 2; + } else { /* Start point is dx, dy */ + tx = (players[php->ph_target].p_x - me->p_x) / + SCALE + WINSIDE / 2; + ty = (players[php->ph_target].p_y - me->p_y) / + SCALE + WINSIDE / 2; + } + + + php->ph_fuse++; + +#ifdef CHECK_DROPPED + if (php->ph_fuse > longest_ph_fuse + 1 && php->ph_status != PHGHOST) { + if (reportDroppedPackets) + printf("Dropped phaser free, player %d (fuse)\n", j->p_no); + php->ph_status = PHGHOST; + } + if (php->ph_status != PHGHOST) { +#endif +#ifdef W_PHASERLINE +/* + * an old redraw.c I used for the Amiga port(not this port) had this. + * Draws a dashed line instead of solid..different pattern from tractor + * lines. At least that's what I guessed for amigawindow.c :-) -JR + */ + + if (j->p_teami != me->p_teami) + W_MakePhaserLine(w, dx, dy, tx, ty, + (php->ph_fuse % 2 && php->ph_status != PHMISS) ? + foreColor : + shipCol[1 + j->p_teami], + php->ph_fuse); + else +#endif + { + W_Color ph_col; + if (jubileePhasers) { + + switch (php->ph_fuse % 4) { + case 0: + ph_col = W_Red; + break; + case 1: + ph_col = W_Yellow; + break; + case 2: + ph_col = W_Green; + break; + case 3: + ph_col = W_Cyan; + break; + } + if (php->ph_status == PHMISS) + ph_col = W_White; + } else { + ph_col = (php->ph_fuse % 2 && php->ph_status != PHMISS) ? + foreColor : + shipCol[1 + j->p_teami]; + } + W_CacheLine(w, dx, dy, tx, ty, ph_col); + } + clearline[0][clearlcount] = dx; + clearline[1][clearlcount] = dy; + clearline[2][clearlcount] = tx; + clearline[3][clearlcount] = ty; + clearlcount++; +#ifdef CHECK_DROPPED + } /* PHGHOST */ +#endif + } + } + + /* ATM - show tractor/pressor beams (modified by James Collins) */ + /* showTractorPressor is a variable set by xtrekrc. */ + /* modified to show all T/P's 1/28/94 [BDyess] */ + /* fixed display bug 1/29/94 [BDyess] */ + dx = WINSIDE / 2; + dy = WINSIDE / 2; + if (showTractorPressor) { + double theta; + unsigned char dir; + int lx[2], ly[2], px, py, target_width; + struct player *victim = &players[me->p_tractor]; + int last; + if (paradise && showAllTractorPressor && allowShowAllTractorPressor) { + /* check everybody */ + last = nplayers; + j = &players[0]; + i = 0; + } else { + /* only check self */ + last = me->p_no + 1; + j = me; + i = me->p_no; + } + for (; i < last; i++, j++) { + if (!(j->p_flags & (PFTRACT | PFPRESS) && isAlive(j))) + continue; + if (!paradise && RSA_Client > 0 && j != me) + continue; + victim = &players[j->p_tractor]; + if (victim->p_flags & PFCLOAK) + break; /* can't see tractors on cloaked opponents */ + if (j == me) { + dx = dy = WINSIDE / 2; + } else { + dx = (j->p_x - me->p_x) / SCALE + WINSIDE / 2; + dy = (j->p_y - me->p_y) / SCALE + WINSIDE / 2; + } + if (PtOutsideWin(dx, dy)) + continue; /* he's off the screen */ + px = (victim->p_x - me->p_x) / SCALE + WINSIDE / 2; + py = (victim->p_y - me->p_y) / SCALE + WINSIDE / 2; + if (px == dx && py == dy) + break; +#define XPI 3.1415926 + theta = atan2((double) (px - dx), (double) (dy - py)) + XPI / 2.0; + dir = (unsigned char) (theta / XPI * 128.0); + target_width = shape_of_ship(victim->p_teami, + victim->p_ship->s_bitmap)->width; + if (!(victim->p_flags & PFSHIELD)) + target_width /= 2; + lx[0] = px + (Cos[dir] * (target_width / 2)); + ly[0] = py + (Sin[dir] * (target_width / 2)); + lx[1] = px - (Cos[dir] * (target_width / 2)); + ly[1] = py - (Sin[dir] * (target_width / 2)); +#undef XPI + if (j->p_flags & PFPRESS) { + W_MakeTractLine(w, dx, dy, lx[0], ly[0], W_Yellow); + W_MakeTractLine(w, dx, dy, lx[1], ly[1], W_Yellow); + } else { + W_MakeTractLine(w, dx, dy, lx[0], ly[0], W_Green); + W_MakeTractLine(w, dx, dy, lx[1], ly[1], W_Green); + } + /* + keeping track of tractors seperately from other lines allows + clearing them diffently. Clearing them the same as other + solid lines caused occasional bits to be left on the screen. + This is the fix. [BDyess] + */ + if (tractcurrent == NULL) { /* just starting */ + tractcurrent = tracthead = (Tractor *) malloc(sizeof(Tractor)); + tracthead->next = NULL; + } + tractcurrent->sx = dx; + tractcurrent->sy = dy; + tractcurrent->d1x = lx[0]; + tractcurrent->d1y = ly[0]; + tractcurrent->d2x = lx[1]; + tractcurrent->d2y = ly[1]; + /* get ready for the next run through */ + if (tractcurrent->next) { /* already malloc'd before */ + tractcurrent = tractcurrent->next; + } else { /* new maximum, create a new struct */ + tractcurrent->next = (Tractor *) malloc(sizeof(Tractor)); + tractcurrent = tractcurrent->next; + tractcurrent->next = NULL; + } + } + } + /* changed torps/drones/plasmas to one call per player, in the above loop */ + /* still have leftover drones to draw: */ + redraw_other_drones(); + + /* Draw Edges */ + if (me->p_x < (WINSIDE / 2) * SCALE) { + int sy, ey; + dx = (WINSIDE / 2) - (me->p_x) / SCALE; + sy = (WINSIDE / 2) + (0 - me->p_y) / SCALE; + ey = (WINSIDE / 2) + (blk_gwidth - me->p_y) / SCALE; + if (sy < 0) + sy = 0; + if (ey > WINSIDE - 1) + ey = WINSIDE - 1; + /* XFIX */ + W_CacheLine(w, dx, sy, dx, ey, warningColor); + /* + W_MakeLine(w, dx, sy, dx, ey, warningColor); + */ + clearline[0][clearlcount] = dx; + clearline[1][clearlcount] = sy; + clearline[2][clearlcount] = dx; + clearline[3][clearlcount] = ey; + clearlcount++; + } + if ((blk_gwidth - me->p_x) < (WINSIDE / 2) * SCALE) { + int sy, ey; + dx = (WINSIDE / 2) + (blk_gwidth - me->p_x) / SCALE; + sy = (WINSIDE / 2) + (0 - me->p_y) / SCALE; + ey = (WINSIDE / 2) + (blk_gwidth - me->p_y) / SCALE; + if (sy < 0) + sy = 0; + if (ey > WINSIDE - 1) + ey = WINSIDE - 1; + /* XFIX */ + W_CacheLine(w, dx, sy, dx, ey, warningColor); + /* + W_MakeLine(w, dx, sy, dx, ey, warningColor); + */ + clearline[0][clearlcount] = dx; + clearline[1][clearlcount] = sy; + clearline[2][clearlcount] = dx; + clearline[3][clearlcount] = ey; + clearlcount++; + } + if (me->p_y < (WINSIDE / 2) * SCALE) { + int sx, ex; + dy = (WINSIDE / 2) - (me->p_y) / SCALE; + sx = (WINSIDE / 2) + (0 - me->p_x) / SCALE; + ex = (WINSIDE / 2) + (blk_gwidth - me->p_x) / SCALE; + if (sx < 0) + sx = 0; + if (ex > WINSIDE - 1) + ex = WINSIDE - 1; + /* XFIX */ + W_CacheLine(w, sx, dy, ex, dy, warningColor); + /* + W_MakeLine(w, sx, dy, ex, dy, warningColor); + */ + clearline[0][clearlcount] = sx; + clearline[1][clearlcount] = dy; + clearline[2][clearlcount] = ex; + clearline[3][clearlcount] = dy; + clearlcount++; + } + if ((blk_gwidth - me->p_y) < (WINSIDE / 2) * SCALE) { + int sx, ex; + dy = (WINSIDE / 2) + (blk_gwidth - me->p_y) / SCALE; + sx = (WINSIDE / 2) + (0 - me->p_x) / SCALE; + ex = (WINSIDE / 2) + (blk_gwidth - me->p_x) / SCALE; + if (sx < 0) + sx = 0; + if (ex > WINSIDE - 1) + ex = WINSIDE - 1; + /* XFIX */ + W_CacheLine(w, sx, dy, ex, dy, warningColor); + /* + W_MakeLine(w, sx, dy, ex, dy, warningColor); + */ + clearline[0][clearlcount] = sx; + clearline[1][clearlcount] = dy; + clearline[2][clearlcount] = ex; + clearline[3][clearlcount] = dy; + clearlcount++; + } + /* Change border color to signify alert status */ + +#ifdef UNIX_SOUND + if (oldalert != (me->p_flags & (PFGREEN | PFYELLOW | PFRED))) + { + if (me->p_flags & PFRED) + maybe_play_sound (SND_REDALERT); /* Red Alert, play ONLY once */ + else sound_completed (SND_REDALERT); /* Done with Red Alert */ + } +#endif + + if (oldalert != (me->p_flags & (PFGREEN | PFYELLOW | PFRED))) { + if(paradise && auto_zoom_timer<udcounter && (autoZoom || autoUnZoom)) { + int old_zoom=blk_zoom; + switch(autoZoom) { + case 1: + if(me->p_flags & (PFYELLOW | PFRED)) + blk_zoom = 1; + break; + case 2: + if(me->p_flags & (PFRED)) + blk_zoom = 1; + break; + } + switch(autoUnZoom) { + case 1: + if(me->p_flags & (PFGREEN)) + blk_zoom = 0; + break; + case 2: + if(me->p_flags & (PFYELLOW | PFGREEN)) + blk_zoom = 0; + break; + } + if(old_zoom != blk_zoom) + redrawall=1; + } + oldalert = (me->p_flags & (PFGREEN | PFYELLOW | PFRED)); + if (infoIcon && iconified) + drawIcon(); + switch (oldalert) { + case PFGREEN: + if (extraBorder) + W_ChangeBorder(w, gColor); + W_ChangeBorder(baseWin, gColor); + W_ChangeBorder(iconWin, gColor); + break; + case PFYELLOW: + if (extraBorder) + W_ChangeBorder(w, yColor); + W_ChangeBorder(baseWin, yColor); + W_ChangeBorder(iconWin, yColor); + break; + case PFRED: + if (extraBorder) + W_ChangeBorder(w, rColor); + W_ChangeBorder(baseWin, rColor); + W_ChangeBorder(iconWin, rColor); + break; + } + } + /* draw stars */ + + if (blk_showStars) + drawStars(); + +#ifdef LOCAL_SHIPSTATS + if(localShipStats) + doLocalShipstats(); +#endif + + +} +#define DRAWGRID 4 + +int +zoom_offset(v) + int v; +{ + if (blk_zoom) { + register gwidth, ov; + /* dimension of zoom area */ + gwidth = blk_gwidth / 2; + /* offset to bring us into new zoom area */ + ov = (v / (int) gwidth) * gwidth; + if (blk_zoom > 1) + return ov; + else + /* sector offset into new zoom area */ + return ov + (((v - ov) / GRIDSIZE) * GRIDSIZE) - GRIDSIZE; + } else + return v; +} + +#ifdef HOCKEY +void galactic_hockey P((void)); +#endif + +#ifndef COW_HAS_IT_WHY_SHOULDNT_WE +static +#endif +void +map() +{ + int nplan; + register int i, k, tmp = blk_gwidth/250; + register struct player *j; + register struct planet *l; + register int dx, dy, odx, ody; + static osx = 0, osy = 0; /* old square */ + static last_offsetx, last_offsety; + static int grid_fuse; /* TSH */ + register int gwidth, offsetx, offsety; + int color, pl = 0; + /* + last_lock is used to hold the begin/end point for lock line; [0] holds + me->; [1] holds target lock; lockx[2] holds status of line so we can + erase if line is there but lock if off + */ + static last_lockx[3] = {0, 0, 0}, last_locky[2]; + int me_galx, me_galy; + + grid_fuse++; /* we only draw the grids every DRAWGRID + interval */ + + /* set number of planets for later */ + nplan = (paradise) ? nplanets : 40; + + if (reinitPlanets) { + initPlanets(); + reinitPlanets = 0; +#ifdef HOCKEY + /* planets moved so the lines need updating [BDyess] */ + if(hockey) hockeyInit(); +#endif /*HOCKEY*/ + } + +#ifdef HOCKEY + galactic_hockey(); +#endif /*HOCKEY*/ + + if (blk_zoom) { + gwidth = blk_gwidth / 2; + offsetx = zoom_offset(me->p_x); + offsety = zoom_offset(me->p_y); + + if (offsetx != last_offsetx || offsety != last_offsety) + redrawall = 1; + + last_offsetx = offsetx; + last_offsety = offsety; + } else { + gwidth = blk_gwidth; + offsetx = 0; + offsety = 0; + } + + me_galx = (me->p_x - offsetx) * WINSIDE / gwidth; + me_galy = (me->p_y - offsety) * WINSIDE / gwidth; + +/* draw asteroid dots -- this is a test only. MDM */ + if( received_terrain_info && paradise ){ + /* but avoid that SEGV! */ + for( i = 0; i < 250; i++ ){ + for( k = udcounter%10; k < 250; k += 10){ + if(terrainInfo[i*250+k].types & T_ASTEROIDS) { + W_DrawPoint( mapw, + (i*tmp - offsetx) * WINSIDE / gwidth, + (k*tmp - offsety) * WINSIDE / gwidth, + W_White); + } + if (terrainInfo[i*250+k].types & T_NEBULA) { + W_DrawPoint( mapw, + ((i*tmp - offsetx) * WINSIDE / gwidth) + 1, + ((k*tmp - offsety) * WINSIDE / gwidth) + 1, + W_Red); + } + } + } + } + + if (redrawall) + W_ClearWindow(mapw); + + /* draw grid on galactic */ + if ((redrawall || (grid_fuse % DRAWGRID) == 0) && (paradise) && (drawgrid)) { + int x, y, w, h, grid; + char numbuf[1]; + grid = GRIDSIZE * WINSIDE / gwidth; + for (i = 1; i <= 6 / (blk_zoom ? 2 : 1); i++) { + /* looks nasty but we only have to do it 3 times if blk_zoom */ + + /* horizontal line */ + x = 0; + y = i * grid; + w = WINSIDE; + numbuf[0] = '0' + (char) i; + if (blk_zoom) { + /* we might have to clip */ + dy = i * GRIDSIZE + offsety; + if (dy >= 0 && dy <= blk_gwidth + 2 * GRIDSIZE) { + if (offsetx < 0) { + x = grid; + w = 2 * x; + } else if (offsetx + 3 * GRIDSIZE > blk_gwidth) { + w = 2 * grid; + } + W_MakeTractLine(mapw, x, y, x + w, y, W_Grey); + } + if (sectorNums) { + numbuf[0] = '0' + (char) (i + offsety / 33333); + if ((numbuf[0] == '0') || (numbuf[0] == '7')) + numbuf[0] = ' '; + if (i == 1) /* so numbers dont overwrite in 1st box */ + W_WriteText(mapw, x + 2, y - grid + 11, W_Grey, numbuf, 1, + W_RegularFont); + else + W_WriteText(mapw, x + 2, y - grid + 2, W_Grey, numbuf, 1, + W_RegularFont); + } + } else { + W_MakeTractLine(mapw, x, y, x + w, y, W_Grey); + if (sectorNums) { + W_WriteText(mapw, x + 2, y - grid + 2, W_Grey, numbuf, 1, W_RegularFont); + } + } + /* vertical line */ + x = i * grid; + y = 0; + h = WINSIDE; + + if (blk_zoom) { + /* we might have to clip */ + dx = i * GRIDSIZE + offsetx; + if (dx >= 0 && dx <= blk_gwidth + 2 * GRIDSIZE) { + if (offsety < 0) { + y = grid; + h = 2 * y; + } else if (offsety + 3 * GRIDSIZE > blk_gwidth) { + h = 2 * grid; + } + W_MakeTractLine(mapw, x, y, x, y + h, W_Grey); + } + if (sectorNums) { + numbuf[0] = '0' + (char) (i + offsetx / 33333); + if ((numbuf[0] == '0') || (numbuf[0] == '7')) + numbuf[0] = ' '; + if (i == 1) + W_WriteText(mapw, x - grid + 11, y + 2, W_Grey, numbuf, 1, + W_RegularFont); + else + W_WriteText(mapw, x - grid + 2, y + 2, W_Grey, numbuf, 1, + W_RegularFont); + } + } else { + W_MakeTractLine(mapw, x, y, x, y + h, W_Grey); + if (sectorNums) { + W_WriteText(mapw, x - grid + 2, y + 2, W_Grey, numbuf, 1, + W_RegularFont); + } + } + } + + dx = ((me->p_x - offsetx) / GRIDSIZE) * GRIDSIZE; + dy = ((me->p_y - offsety) / GRIDSIZE) * GRIDSIZE; + if (!redrawall && ((osx != dx) || (osy != dy))) { + + /* clear old sector */ + x = osx * WINSIDE / gwidth; + y = osy * WINSIDE / gwidth; + w = h = grid; + + W_DrawSectorHighlight(mapw, x, y, w, h, backColor); + + osx = dx; + osy = dy; + } + /* draw our current sector */ + x = dx * WINSIDE / gwidth; + w = h = grid; + y = dy * WINSIDE / gwidth; + + W_DrawSectorHighlight(mapw, x, y, w, h, yColor); + } + /* Erase ships */ + for (i = 0, j = &players[i]; i < nplayers; i++, j++) { + lastUpdate[i]++; + /* + Erase the guy if: redrawPlayer[i] is set and the mapmode setting + allows it. + */ + if (!redrawPlayer[i] || (mapmode == GMAP_INFREQUENT && lastUpdate[i] < 5)) + continue; + lastUpdate[i] = 0; + /* Clear his old image... */ + if (mclearzone[2][i]) { + /* XFIX */ + if (!redrawall) { + W_ClearArea(mapw, mclearzone[0][i], mclearzone[1][i], + mclearzone[2][i], mclearzone[3][i]); + /* Redraw the hole just left next update */ + checkRedraw(mclearzone[4][i], mclearzone[5][i]); + } + mclearzone[2][i] = 0; + } + } + /* Draw Planets */ +#ifdef HOCKEY + if(! (hockey && cleanHockeyGalactic)) { +#endif + for (i = 0, l = &planets[i]; i < nplan; i++, l++) { + char buf[4]; + int color; + if (!(l->pl_flags & PLREDRAW) && (!redrawall)) + continue; + l->pl_flags &= ~PLREDRAW; /* Turn redraw flag off! */ + + dx = (l->pl_x - offsetx) * WINSIDE / gwidth; + dy = (l->pl_y - offsety) * WINSIDE / gwidth; + + if (PtOutsideWin(dx, dy)) + continue; + + if (0 == strncmp(l->pl_name, "New ", 4)) { + strncpy(buf, l->pl_name + 4, 3); + } else if (0 == strncmp(l->pl_name, "Planet ", 7)) { + strncpy(buf, l->pl_name + 7, 3); + } else + strncpy(buf, l->pl_name, 3); + + /* moving planets */ + if (pl_update[l->pl_no].plu_update == 1) { + odx = (pl_update[l->pl_no].plu_x - offsetx) * WINSIDE / gwidth; + ody = (pl_update[l->pl_no].plu_y - offsety) * WINSIDE / gwidth; + + /* XFIX */ + W_ClearArea(mapw, odx - (mplanet_width / 2), ody - (mplanet_height / 2), + mplanet_width, mplanet_height); + + W_WriteText(mapw, odx - (mplanet_width / 2), ody + (mplanet_height / 2), + backColor, buf, 3, planetFont(l)); + + pl_update[l->pl_no].plu_update = 0; + } +#if 0 +/* not necessary, pl_update is now set whenever a planet needs to be + * erased. -JR + */ + else { + + /* XFIX */ + W_ClearArea(mapw, dx - (mplanet_width / 2), dy - (mplanet_height / 2), + mplanet_width, mplanet_height); + } +#endif + color = ((paradise) && (l->pl_flags & (PLSTAR | PLWHOLE))) ? + textColor : planetColor(l); +#ifdef BEEPLITE + if (UseLite && emph_planet_seq_n[l->pl_no] > 0 && + (F_beeplite_flags & LITE_PLANETS)) { + int seq_n = emph_planet_seq_n[l->pl_no] % emph_planet_seq_frames; + + if ((emph_planet_seq_n[l->pl_no] -= 1) > 0) + W_OverlayBitmap(dx - (emph_planet_seq_width / 2), + dy - (emph_planet_seq_height / 2), + emph_planet_seq[seq_n], + emph_planet_color[l->pl_no]); + else + W_ClearArea(mapw, dx - (emph_planet_seq_width / 2), + dy - (emph_planet_seq_height / 2), + emph_planet_seq_width, emph_planet_seq_height); + W_WriteBitmap(dx - (mplanet_width / 2), dy - (mplanet_height / 2), + planetmBitmap(l), color); + l->pl_flags |= PLREDRAW; /* Leave redraw on until done + highlighting */ + pl_update[l->pl_no].plu_update = 1; + } else +#endif + if (!(PL_TYPE(*l) == PLWHOLE)) { /* non wormholes */ + W_WriteBitmap(dx - (mplanet_width / 2), dy - (mplanet_height / 2), + planetmBitmap(l), color); + W_WriteText(mapw, dx - (mplanet_width / 2), dy + (mplanet_height / 2), + color, buf, ((strlen(buf) >= 3) ? 3 : strlen(buf)), + planetFont(l)); +#ifdef SHOW_IND + if (showIND && (l->pl_info & idx_to_mask(me->p_teami)) && (l->pl_owner == NOBODY) && l->pl_flags & PLPLANET) + { + W_MakeLine (mapw, dx + (mplanet_width / 2 - 1), dy + (mplanet_height / 2 - 1), + dx - (mplanet_width / 2), dy - (mplanet_height / 2), + W_White); + W_MakeLine (mapw, dx - (mplanet_width / 2), dy + (mplanet_height / 2 - 1), + dx + (mplanet_width / 2 - 1), dy - (mplanet_height / 2), + W_White); + } +#endif + } +#ifdef VISIBLE_WORMHOLES + else { /* wormholes show when scouted [BDyess] */ + if(l->pl_info & idx_to_mask(me->p_teami)) { /* have info [BDyess]*/ + printf("l->pl_info == %d\n",l->pl_info); + W_WriteBitmap(dx - (mplanet_width / 2), + dy - (mplanet_height / 2), + planetmBitmap(l), + color); + } + } +#endif /*VISIBLE_WORMHOLES*/ +#ifdef HOCKEY + } +#endif + /* Draw ships */ + for (i = 0, j = &players[i]; i < nplayers; i++, j++) { + /* + We draw the guy if redrawall, or we just erased him. Also, we + redraw if we haven't drawn for 30 frames. (in case he was erased + by other ships). + */ + if (lastUpdate[i] != 0 && (!redrawall) && lastUpdate[i] < 30) + continue; + if (j->p_status != PALIVE) + continue; + lastUpdate[i] = 0; + dx = (j->p_x - offsetx) * WINSIDE / gwidth; + dy = (j->p_y - offsety) * WINSIDE / gwidth; + + if ((showLock & 1) && !(j->p_flags & PFCLOAK)) { + if ((me->p_flags & PFPLOCK) && (me->p_playerl == j->p_no)) { + if (lockLine) { + if ((last_lockx[0] != me_galx) || (last_locky[0] != me_galx) || + (last_lockx[1] != dx) || (last_locky[1] != dy)) { + W_MakeTractLine(mapw, last_lockx[0], last_locky[0], + last_lockx[1], last_locky[1], backColor); + last_lockx[0] = me_galx; + last_locky[0] = me_galy; + last_lockx[1] = dx; + last_locky[1] = dy; + last_lockx[2] = 1; + W_MakeTractLine(mapw, last_lockx[0], last_locky[0], + last_lockx[1], last_locky[1], W_Green); + + } + } + W_WriteTriangle(mapw, dx, dy + 6, 4, 1, foreColor); + pl = 1; + } + } + if (PtOutsideWin(dx, dy)) + continue; + + if (blk_friendlycloak == 1) { + if (j->p_flags & PFCLOAK) { + if (myPlayer(j)) + color = myColor; + else if (friendlyPlayer(j)) + color = playerColor(j); + else + color = unColor; + } else + color = playerColor(j); + + pl = 0; + if (j->p_flags & PFCLOAK) + W_WriteText(mapw, dx - W_Textwidth * cloakcharslen / 2, + dy - W_Textheight / 2, color, cloakchars, cloakcharslen, + W_RegularFont); + else + W_WriteText(mapw, dx - W_Textwidth, + dy - W_Textheight / 2, color, j->p_mapchars, 2, + shipFont(j)); + } else { + if (j->p_flags & PFCLOAK) { + W_WriteText(mapw, dx - W_Textwidth * cloakcharslen / 2, + dy - W_Textheight / 2, unColor, cloakchars, cloakcharslen, + W_RegularFont); + } else { + W_WriteText(mapw, dx - W_Textwidth, + dy - W_Textheight / 2, playerColor(j), j->p_mapchars, 2, + shipFont(j)); + } + } + +#ifdef BEEPLITE + if (UseLite && emph_player_seq_n[i] > 0 && + (F_beeplite_flags & LITE_PLAYERS_MAP)) { + int seq_n = emph_player_seq_n[i] % emph_player_seq_frames; + + W_WriteBitmap(dx - (emph_player_seq_width / 2 - 1), + dy - (emph_player_seq_height / 2 + 1), + emph_player_seq[seq_n], + emph_player_color[i]); + emph_player_seq_n[i] -= 1; + mclearzone[0][i] = dx - (emph_player_seq_width / 2 - 1); + mclearzone[1][i] = dy - (emph_player_seq_height / 2 + 1); + mclearzone[2][i] = emph_player_seq_width; + mclearzone[3][i] = emph_player_seq_height; + mclearzone[4][i] = j->p_x; + mclearzone[5][i] = j->p_y; + /* + Force redraw for this guy no matter what. Even if stationary. + */ + lastUpdate[i] = 30; + /* Leave redraw on until done highlighting */ + redrawPlayer[i] = 1; + } else +#endif + { + if (j->p_flags & PFCLOAK) { + mclearzone[0][i] = dx - W_Textwidth * cloakcharslen / 2; + mclearzone[1][i] = dy - W_Textheight / 2; + mclearzone[2][i] = W_Textwidth * cloakcharslen; + } else { + mclearzone[0][i] = dx - W_Textwidth; + mclearzone[1][i] = dy - W_Textheight / 2; + mclearzone[2][i] = W_Textwidth * 2; + } + if (pl) + mclearzone[3][i] = W_Textheight + 8; + else + mclearzone[3][i] = W_Textheight; + /* Set these so we can checkRedraw() next time */ + mclearzone[4][i] = j->p_x; + mclearzone[5][i] = j->p_y; + redrawPlayer[i] = 0; + } + } + /* draw viewBox if wanted [BDyess] */ +#define VIEWDIST SCALE * WINSIDE * WINSIDE / (gwidth * 2) +#define REDRAWDIST SCALE * WINSIDE / 2 + if (viewBox && allowViewBox) { + static int viewx = 0, viewy = 0; + + dx = (me->p_x - offsetx) * WINSIDE / gwidth; + dy = (me->p_y - offsety) * WINSIDE / gwidth; + if (viewx != dx || viewy != dy || redrawall) { + /* clear old dots - placed here for less flicker */ + W_DrawPoint(mapw, viewx + VIEWDIST, viewy + VIEWDIST, backColor); + W_DrawPoint(mapw, viewx + VIEWDIST, viewy - VIEWDIST, backColor); + W_DrawPoint(mapw, viewx - VIEWDIST, viewy + VIEWDIST, backColor); + W_DrawPoint(mapw, viewx - VIEWDIST, viewy - VIEWDIST, backColor); + /* redraw any planets they overwrote */ + viewx *= gwidth / WINSIDE + offsetx; /* correct from view + scale */ + viewy *= gwidth / WINSIDE + offsety; + checkRedraw(viewx + REDRAWDIST, viewy + REDRAWDIST); + checkRedraw(viewx + REDRAWDIST, viewy - REDRAWDIST); + checkRedraw(viewx - REDRAWDIST, viewy + REDRAWDIST); + checkRedraw(viewx - REDRAWDIST, viewy - REDRAWDIST); + /* draw the new points */ + W_DrawPoint(mapw, dx + VIEWDIST, dy + VIEWDIST, W_White); + W_DrawPoint(mapw, dx + VIEWDIST, dy - VIEWDIST, W_White); + W_DrawPoint(mapw, dx - VIEWDIST, dy + VIEWDIST, W_White); + W_DrawPoint(mapw, dx - VIEWDIST, dy - VIEWDIST, W_White); + viewx = dx; /* store the points for later */ + viewy = dy; /* clearing */ + } + } +#undef VIEWDIST +#undef REDRAWDIST + + if (clearlmcount) { + W_WriteTriangle(mapw, clearlmark[0], clearlmark[1], 4, 0, backColor); + clearlmcount--; + } + if (showLock & 1) { + /* for now draw this everytime */ + if ((me->p_flags & PFPLLOCK) && (me->p_status != POBSERVE)) { + struct planet *l = &planets[me->p_planet]; + dx = (l->pl_x - offsetx) * WINSIDE / gwidth; + dy = (l->pl_y - offsety) * WINSIDE / gwidth; + + if (lockLine) { + if ((last_lockx[0] != me_galx) || (last_locky[0] != me_galx) || + (last_lockx[1] != dx) || (last_locky[1] != dy)) { + W_MakeTractLine(mapw, last_lockx[0], last_locky[0], + last_lockx[1], last_locky[1], backColor); + last_lockx[0] = me_galx; + last_locky[0] = me_galy; + last_lockx[1] = dx; + last_locky[1] = dy; + last_lockx[2] = 1; + W_MakeTractLine(mapw, last_lockx[0], last_locky[0], + last_lockx[1], last_locky[1], W_Green); + } + } + if (!PtOutsideWin(dx, dy)) { + W_WriteTriangle(mapw, dx, dy - (mplanet_height) / 2 - 4, 4, 0, + foreColor); + clearlmark[0] = dx; + clearlmark[1] = dy - (mplanet_height) / 2 - 4; + clearlmcount++; + } + } + } + /* if lock line is drawn but no lock; erase lock line */ + if (lockLine && ((me->p_flags & (PFPLLOCK | PFPLOCK)) == 0) && last_lockx[2]) { + W_MakeTractLine(mapw, last_lockx[0], last_locky[0], last_lockx[1], + last_locky[1], backColor); + last_lockx[2] = 0; + } + /* redraw warp beacon routes */ + + for (i = 0; i < ngthingies; i += 2) { + struct thingy *k = &thingies[i + nplayers * npthingies]; + if (k[0].t_shape == SHP_WARP_BEACON && + k[1].t_shape == SHP_WARP_BEACON) { + W_MakeLine(mapw, (k[0].t_x - offsetx) * WINSIDE / gwidth, + (k[0].t_y - offsety) * WINSIDE / gwidth, + (k[1].t_x - offsetx) * WINSIDE / gwidth, + (k[1].t_y - offsety) * WINSIDE / gwidth, + W_Grey); + } + } + } + redrawall = 0; +} + +#define TWODIGIT_L(p, val) \ +{ \ + if ((val)<10) { \ + (p)[0] = (val)+'0'; \ + (p)[1] = ' '; \ + } else { \ + (p)[0] = (val)/10 + '0'; \ + (p)[1] = (val)%10 + '0'; \ + } \ +} + +#define TWODIGIT_R(p, val) \ +{ \ + if ((val)<10) { \ + (p)[0] = ' '; \ + (p)[1] = (val)+'0'; \ + } else { \ + (p)[0] = (val)/10 + '0'; \ + (p)[1] = (val)%10 + '0'; \ + } \ +} + +#define THREEDIGIT_C(p, val) \ +{ \ + if ((val)<10) { \ + (p)[0] = ' '; (p)[1] = (val)+'0'; (p)[2] = ' '; \ + } else if ((val)<100) { \ + (p)[0] = (val)/10 + '0'; \ + (p)[1] = (val)%10 + '0'; \ + (p)[2] = ' '; \ + } else { \ + (p)[0] = (val)/100 + '0'; \ + (p)[1] = ((val)/10 %10) + '0'; \ + (p)[2] = (val)%10 + '0'; \ + } \ +} + +#define THREEDIGIT_R(p, val) \ +{ \ + if ((val)<10) { \ + (p)[0] = ' '; (p)[1] = ' '; (p)[2] = (val)+'0'; \ + } else if ((val)<100) { \ + (p)[0] = ' '; \ + (p)[1] = (val)/10 + '0'; \ + (p)[2] = (val)%10 + '0'; \ + } else { \ + (p)[0] = (val)/100 + '0'; \ + (p)[1] = ((val)/10 %10) + '0'; \ + (p)[2] = (val)%10 + '0'; \ + } \ +} + +#define FOURDIGIT_R(p, val) \ +{ \ + if ((val)<10) { \ + (p)[0] = ' '; \ + (p)[1] = ' '; \ + (p)[2] = ' '; \ + (p)[3] = (val)+'0'; \ + } else if ((val)<100) { \ + (p)[0] = ' '; \ + (p)[1] = ' '; \ + (p)[2] = (val)/10 + '0'; \ + (p)[3] = (val)%10 + '0'; \ + } else if ((val)<1000) { \ + (p)[0] = ' '; \ + (p)[1] = (val)/100 + '0'; \ + (p)[2] = ((val)/10 %10) + '0'; \ + (p)[3] = (val)%10 + '0'; \ + } else { \ + (p)[0] = (val)/1000 + '0'; \ + (p)[1] = ((val)/100 %10) + '0'; \ + (p)[2] = ((val)/10 %10) + '0'; \ + (p)[3] = (val)%10 + '0'; \ + } \ +} + +#define SIXDIGIT_R(p, val) \ +{ \ + if ((val)<10) { \ + (p)[0] = ' '; \ + (p)[1] = ' '; \ + (p)[2] = ' '; \ + (p)[3] = ' '; \ + (p)[4] = ' '; \ + (p)[5] = (val)+'0'; \ + } else if ((val)<100) { \ + (p)[0] = ' '; \ + (p)[1] = ' '; \ + (p)[2] = ' '; \ + (p)[3] = ' '; \ + (p)[4] = (val)/10 + '0'; \ + (p)[5] = (val)%10 + '0'; \ + } else if ((val)<1000) { \ + (p)[0] = ' '; \ + (p)[1] = ' '; \ + (p)[2] = ' '; \ + (p)[3] = (val)/100 + '0'; \ + (p)[4] = ((val)/10 %10) + '0'; \ + (p)[5] = (val)%10 + '0'; \ + } else if ((val)<10000) { \ + (p)[0] = ' '; \ + (p)[1] = ' '; \ + (p)[2] = ((val)/1000 %10) + '0'; \ + (p)[3] = ((val)/100 %10) + '0'; \ + (p)[4] = ((val)/10 %10) + '0'; \ + (p)[5] = (val)%10 + '0'; \ + } else if ((val)<100000) { \ + (p)[0] = ' '; \ + (p)[1] = ((val)/10000 %10) + '0'; \ + (p)[2] = ((val)/1000 %10) + '0'; \ + (p)[3] = ((val)/100 %10) + '0'; \ + (p)[4] = ((val)/10 %10) + '0'; \ + (p)[5] = (val)%10 + '0'; \ + } else { \ + (p)[0] = (val)/100000 + '0'; \ + (p)[1] = ((val)/10000 %10) + '0'; \ + (p)[2] = ((val)/1000 %10) + '0'; \ + (p)[3] = ((val)/100 %10) + '0'; \ + (p)[4] = ((val)/10 %10) + '0'; \ + (p)[5] = (val)%10 + '0'; \ + } \ +} + +#define SIXnTWOf_R(p, val) \ +{ \ + (p)[3] = '.'; \ + (p)[4] = ((int) (10*(val))) %10 + '0'; \ + (p)[5] = ((int) (100*(val))) %10 + '0'; \ + if ((val)<10) { \ + (p)[0] = ' '; \ + (p)[1] = ' '; \ + (p)[2] = ((int)(val))+'0'; \ + } else if ((val)<100) { \ + (p)[0] = ' '; \ + (p)[1] = ((int)(val))/10 + '0'; \ + (p)[2] = ((int)(val))%10 + '0'; \ + } else { \ + (p)[0] = ((int)(val))/100 + '0'; \ + (p)[1] = (((int)(val))/10 %10) + '0'; \ + (p)[2] = ((int)(val))%10 + '0'; \ + } \ +} + +#if 0 + +static void +stline(flag) + int flag; +{ + static char buf1[80]; + static char buf2[80]; + static char whichbuf = 0; + static int lastnewDashboard; + register char *buf, *oldbuf; + register char *s; + register int i, j; + int k; +/* if you don't do something like this, then switching in the options menu + is 'entertaining' */ + if (newDashboard != lastnewDashboard) { + lastnewDashboard = newDashboard; + redrawTstats(); + return; + } +/* use the new dashboard if we can */ + + + + + + + if (newDashboard) { + db_redraw(flag); + return; + } + /* Instead of one sprintf, we do all this by hand for optimization */ + + if (flag) + whichbuf = 0; /* We must completely refresh */ + + if (whichbuf != 2) { + buf = buf1; + oldbuf = buf2; + } else { + buf = buf2; + oldbuf = buf1; + } + buf[0] = (me->p_flags & PFSHIELD ? 'S' : ' '); + if (me->p_flags & PFGREEN) + buf[1] = 'G'; + else if (me->p_flags & PFYELLOW) + buf[1] = 'Y'; + else if (me->p_flags & PFRED) + buf[1] = 'R'; + buf[2] = (me->p_flags & (PFPLLOCK | PFPLOCK) ? 'L' : ' '); + buf[3] = (me->p_flags & PFREPAIR ? 'R' : ' '); + buf[4] = (me->p_flags & PFBOMB ? 'B' : ' '); + buf[5] = (me->p_flags & PFORBIT ? 'O' : ' '); + buf[6] = (me->p_flags & PFDOCKOK ? 'D' : ' '); +/* buf[6] = (me->p_flags & PFDOCK ? 'D' : ' ');*/ + buf[7] = (me->p_flags & PFCLOAK ? 'C' : ' '); + buf[8] = (me->p_flags & PFWEP ? 'W' : ' '); + buf[9] = (me->p_flags & PFENG ? 'E' : ' '); + if (me->p_flags & PFPRESS) + buf[10] = 'P'; + else if (me->p_flags & PFTRACT) + buf[10] = 'T'; + else + buf[10] = ' '; + if (me->p_flags & PFBEAMUP) + buf[11] = 'u'; + else if (me->p_flags & PFBEAMDOWN) + buf[11] = 'd'; + else + buf[11] = ' '; + if (!paradise) + buf[12] = (status->tourn) ? 't' : ' '; + else + buf[12] = (status2->tourn) ? 't' : ' '; + + buf[13] = ' '; + +#if 1 +/* w/i indicator is a kludge - it just guesses based on the speed of + the ship */ + sprintf(buf + 14, "%2d%c %3d %3d %1d %6.2f %3d %6d %4d %4d ", + me->p_speed, (me->p_speed > me->p_ship->s_maxspeed + 2) ? 'w' : 'i', + me->p_damage, me->p_shield, me->p_ntorp, me->p_kills, + me->p_armies, me->p_fuel, me->p_wtemp, me->p_etemp); +#else +#if 0 + TWODIGIT_L(&buf[14], me->p_speed); + buf[16] = 'i'; + buf[17] = ' '; + buf[18] = ' '; + buf[19] = ' '; + THREEDIGIT_R(&buf[20], me->p_damage); + buf[23] = ' '; + THREEDIGIT_R(&buf[24], me->p_shield); + buf[27] = ' '; + TWODIGIT_R(&buf[28], me->p_ntorp); + buf[30] = ' '; + buf[31] = ' '; + SIXnTWOf_R(&buf[32], me->p_kills); + buf[38] = ' '; + THREEDIGIT_C(&buf[39], me->p_armies); + buf[42] = ' '; + SIXDIGIT_R(&buf[43], me->p_fuel); + buf[49] = ' '; + buf[50] = ' '; + FOURDIGIT_R(&buf[51], me->p_wtemp / 10); + buf[55] = ' '; + FOURDIGIT_R(&buf[56], me->p_etemp / 10); + buf[60] = ' '; + buf[61] = ' '; +#else + buf[14] = '0' + ((me->p_speed % 100) / 10); + if (buf[14] == '0') + buf[14] = ' '; + buf[15] = '0' + (me->p_speed % 10); /* speed */ + buf[16] = ' '; + buf[17] = ' '; + buf[18] = '0' + (me->p_damage / 100); + if (buf[18] == '0') + buf[18] = ' '; + buf[19] = '0' + ((me->p_damage % 100) / 10); + if ((buf[19] == '0') && (me->p_damage < 100)) + buf[19] = ' '; + buf[20] = '0' + (me->p_damage % 10); + buf[21] = ' '; + buf[22] = '0' + (me->p_shield / 100); + if (buf[22] == '0') + buf[22] = ' '; + buf[23] = '0' + ((me->p_shield % 100) / 10); + if ((buf[23] == '0') && (me->p_shield < 100)) + buf[23] = ' '; + buf[24] = '0' + (me->p_shield % 10); + buf[25] = ' '; + buf[26] = ' '; + buf[27] = '0' + ((me->p_ntorp % 100) / 10); + if (buf[27] == '0') + buf[27] = ' '; + buf[28] = '0' + (me->p_ntorp % 10); + buf[29] = ' '; + buf[30] = ' '; + buf[31] = ' '; + buf[32] = ' '; + buf[33] = '0' + ((int) (me->p_kills / 10)); + if (buf[33] == '0') + buf[33] = ' '; + buf[34] = '0' + (((int) me->p_kills) % 10); + buf[35] = '.'; + buf[36] = '0' + (((int) (me->p_kills * 10)) % 10); + buf[37] = '0' + (((int) (me->p_kills * 100)) % 10); + buf[38] = ' '; + buf[39] = ' '; + buf[40] = ' '; + buf[41] = '0' + ((me->p_armies % 100) / 10); + if (buf[41] == '0') + buf[41] = ' '; + buf[42] = '0' + (me->p_armies % 10); + buf[43] = ' '; + buf[44] = ' '; + buf[45] = ' '; + + buf[46] = '0' + (me->p_fuel / 100000); + if (buf[46] == '0') + buf[46] = ' '; + buf[47] = '0' + ((me->p_fuel % 100000) / 10000); + if ((buf[47] == '0') && (me->p_fuel < 100000)) + buf[47] = ' '; + buf[48] = '0' + ((me->p_fuel % 10000) / 1000); + if ((buf[48] == '0') && (me->p_fuel < 10000)) + buf[48] = ' '; + buf[49] = '0' + ((me->p_fuel % 1000) / 100); + if ((buf[49] == '0') && (me->p_fuel < 1000)) + buf[49] = ' '; + buf[50] = '0' + ((me->p_fuel % 100) / 10); + if ((buf[50] == '0') && (me->p_fuel < 100)) + buf[50] = ' '; + buf[51] = '0' + (me->p_fuel % 10); + buf[52] = ' '; + buf[53] = ' '; + buf[54] = ' '; + + buf[55] = '0' + ((me->p_wtemp / 10) / 100); + if (buf[55] == '0') + buf[55] = ' '; + buf[56] = '0' + (((me->p_wtemp / 10) % 100) / 10); + if ((buf[56] == '0') && (me->p_wtemp < 1000)) + buf[56] = ' '; + buf[57] = '0' + ((me->p_wtemp / 10) % 10); + + buf[58] = ' '; + buf[59] = ' '; + buf[60] = ' '; + buf[61] = '0' + ((me->p_etemp / 10) / 1000); + if (buf[61] == '0') + buf[61] = ' '; + buf[62] = '0' + (((me->p_etemp / 10) % 1000) / 100); + if (buf[62] == '0' && me->p_etemp < 1000) + buf[62] = ' '; + buf[63] = '0' + (((me->p_etemp / 10) % 100) / 10); + if ((buf[63] == '0') && (me->p_etemp < 1000)) + buf[63] = ' '; + buf[64] = '0' + ((me->p_etemp / 10) % 10); + buf[65] = ' '; +#endif +#endif + + if (whichbuf == 0) { + /* Draw status line */ + W_WriteText(tstatw, TSTATW_BASEX, 16, textColor, buf, 66, W_RegularFont); + whichbuf = 1; + } else { /* Hacks to make it print only what is + necessary */ + whichbuf = 3 - whichbuf; + j = -1; + for (i = 0; i < 66; i++) { + if (*(buf++) != *(oldbuf++)) { + /* Different string */ + if (j == -1) { + k = i; + s = buf - 1; + } + j = 0; + } else { + /* Same string */ + if (j == -1) + continue; + j++; + if (j == 20) { /* Random number */ + W_WriteText(tstatw, TSTATW_BASEX + W_Textwidth * k, 16, textColor, + s, i - k - 19, W_RegularFont); + j = -1; + } + } + } + if (j != -1) { + W_WriteText(tstatw, TSTATW_BASEX + W_Textwidth * k, 16, textColor, s, i - k - j, + W_RegularFont); + } + } +} + +void +redrawTstats() +{ + char buf[100]; + W_ClearWindow(tstatw); + /* use new dashboard if possible */ + if (newDashboard) { + db_redraw(1); + return; + } + stline(1); /* This is for refresh. We redraw player + stats too */ + strcpy(buf, "Flags Speed Dam Shd Trp Kills Ams Fuel Wtmp Etmp Special" /* "Flags Warp + Dam Shd Torps Kills + Armies Fuel Wtemp + Etemp" */ ); + W_WriteText(tstatw, TSTATW_BASEX, 5, textColor, buf, strlen(buf), W_RegularFont); + sprintf(buf, + "Maximum: %2d %3d %3d 8 %3d %6d %4d %4d ", + me->p_ship->s_maxspeed, me->p_ship->s_maxdamage, + me->p_ship->s_maxshield, me->p_ship->s_maxarmies, + me->p_ship->s_maxfuel, me->p_ship->s_maxwpntemp / 10, + me->p_ship->s_maxegntemp / 10); + W_WriteText(tstatw, TSTATW_BASEX, 27, textColor, buf, strlen(buf), W_RegularFont); +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/reserved.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,44 @@ +/* $Id: reserved.c,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */ + +/* reserved.c + + * Kevin P. Smith 7/3/89 + */ +#include "copyright2.h" +#include <stdio.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> +#include "defs.h" +#include "packets.h" + +void +makeReservedPacket(packet) + struct reserved_spacket *packet; +{ + int i; + + for (i = 0; i < 16; i++) { + packet->data[i] = random() % 256; + } packet->type = SP_RESERVED; +} + +void +encryptReservedPacket(spacket, cpacket, server, pno) + struct reserved_spacket *spacket; + struct reserved_cpacket *cpacket; + char *server; + int pno; +{ + + memcpy(cpacket->data, spacket->data, 16); + memcpy(cpacket->resp, spacket->data, 16); + cpacket->type = CP_RESERVED; + + /* + Encryption algorithm goes here. Take the 16 bytes in cpacket->data, + and create cpacket->resp, which you require the client to also do. If + he fails, he gets kicked out. + */ +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rotate.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,130 @@ +/* $Id: rotate.c,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */ + +/* + * rotate.c + * + */ +#include "copyright2.h" + +#include <stdio.h> +#include <sys/types.h> +#ifndef AMIGA /* not that this file needs any network + stuff... -JR */ +#include <sys/socket.h> +#include <sys/time.h> +#include <netinet/in.h> +#include <netinet/tcp.h> +#include <netdb.h> +#endif +#include <math.h> +#include <errno.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "packets.h" + +#ifdef ROTATERACE + +void +rotate_dir(d, r) + unsigned char *d; + int r; +{ + (*d) += r; +} + +/* general rotation */ + +void +rotate_coord(x, y, d, cx, cy) + int *x, *y; /* values used and returned */ + int d; /* degree (pi == 128) */ + int cx, cy; /* around center point */ +{ + register + int ox, oy; + + ox = *x; + oy = *y; + + switch (d) { + + case 0: + return; + + case 64: + case -192: + *x = cy - oy + cx; + *y = ox - cx + cy; + break; + + case 128: + case -128: + *x = cx - ox + cx; + *y = cy - oy + cy; + break; + + case 192: + case -64: + *x = oy - cy + cx; + *y = cx - ox + cy; + break; + + default:{ + /* do it the hard way */ + /* + there is another way to do this, by using the cos(d) and + sin(d) and the stock rotation matrix from linear algebra. + */ + double dir; + double r, dx, dy; + double rd = (double) d * 3.1415927 / 128.; + + if (*x != cx || *y != cy) { + dx = (double) (*x - cx); + dy = (double) (cy - *y); + dir = atan2(dx, dy) - 3.1415927 / 2.; + r = hypot(dx, dy); + dir += rd; + *x = (int) (r * cos(dir) + cx); + *y = (int) (r * sin(dir) + cy); + } + } + } +} + +void +rotate_gcenter(x, y) + int *x, *y; /* values used and returned */ +{ + rotate_coord(x, y, rotate_deg, blk_gwidth / 2, blk_gwidth / 2); +} + +#endif + +void rotate_all() +{ + register i; + register struct planet *l; + register struct player *j; + + int nplan = (paradise) ? nplanets : 40; + int old_rotate_deg = rotate_deg; + + redrawall = 1; + reinitPlanets = 1; + + rotate_deg = -old_rotate_deg + rotate * 64; + + for (i = 0, l = planets; i < nplan; i++, l++) { + rotate_gcenter(&l->pl_x, &l->pl_y); + } + + for (i=0, j = players; i < nplayers; i++, j++) { + rotate_gcenter(&j->p_x, &j->p_y); + rotate_dir(&j->p_dir, rotate_deg); + } + + rotate_deg = rotate * 64; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sample.xtrekrc Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,681 @@ +# Sample .xtrekrc +# +# Specify this file with: +# netrek -r defaults +# +# If you do not specify a file, then .paradiserc from your home directory +# is used. If .paradiserc does not exist then .xtrekrc is used. +# +# Documentation for all options is available at +# http://www.pnetrek.org/ +# +# You can have defaults from other files included using '#include <file>'. +# This lets you put all your public settings into one file, .xtrekrc for +# example and all your private stuff into another file. You can use ~ in +# the file name to signify your $HOME directory. In your private +# file you can have passwords in the form of 'password: passwd' for a +# general password, or 'password.player: passwd' for passwd's associated +# with your player name, or 'password.server: passwd' for server specific +# passwords. + +name: guest + +# changes to the basic colors: +#color.white: white +#color.black: black +#color.red: paleVioletRed1 +#color.green: green +#color.yellow: yellow +#color.cyan: cyan +#color.cyan: dodgerblue +color.cyan: DeepSkyBlue +#color.light grey: light grey + +#miscellaneous toggles +# 0=none, 1=time of day, 2=time on server, 3=time in ship, 4=user set time +timerType: 3 +#shipBitmapPath: /home/smpatel/netrek/bitmaps/ +#soundPath: /home/smpatel/netrek/sounds +#soundDev: /dev/dsp +# put enemy on left with sorted playerlist +robsort: on +# show dead players in playerlist +showDead: on +# sort outfitting ('--') players to bottom +sortOutfitting: on +# show pre-login players +showPreLogins: on +# replace 0.00 with " " when acceptable (paradise servers) +hideNoKills: on +warpStreaks: on +# use rainbow dashboard in paradise +# 0=old dashboard, 1=new dashboard, 2=color dashboard, 3=rainbow dashboard +Dashboard: 3 +# clear my keymap each time, ie ignore the server's copy +clearMap: on +# use hull warning dots +warnHull: on +# replace ?? cloaker symbol with >< +cloakChars: >< +showShields: on +#showStats: on +reportKills: on +showMySpeed: on +# vary color of shields with damage +varyShields: on +keepPeace: on +galacticFrequent: on +showTractor: on +showTractorPressor: on +showPlanetNames: on +showPlanetOwner: off +sortPlayers: on +warp: on +defaultShip: CA +logging: on +logMessage: on +logfile: /home/smpatel/paradise.log +# galactic map stuff: 0=ownership 1=resources 2=nothing +showGalactic: 1 +showLocal: 1 +# lock : 0=don't show 1=galactic only 2=tactical only 3=both +showLock: 3 +netStats: off +tryUDP: on +# udpClientSend: 0=TCP only 1=simple UDP 2=enforced UDP (state only) +# 3=enforced UDP (state & weap) +udpClientSend: 3 +# udpClientReceive: 0=TCP only 1=simple UDP 2=fat UDP 3=double UDP +udpClientReceive: 2 +udpSequenceCheck: on +# udpDebug: 0 = OFF 1 = ON (conect msgs only) 2 = ON (verbose output) +udpDebug: 0 +udpUpdates: 5 +# I'd turn this on, but there's no 'fat S_P' - I can manually enable if lag +# is bad +tryShort: off +WaitMotd.mapped: on +# show tractor/pressor of everyone in tactical +showAllTractorPressor: on +# show # per team and messages +infoIcon: on +updateSpeed: 0 +# set time for autoquit +autoQuit: 199 +# show blinking lights on console for packets +packetLights: on +# show box on galactic map representing tactical window +viewBox: on +# number sectors in galactic map +sectorNums: on +# display a line from you to target of lock +lockLine: on +# use new sorting for planet list +mapSort: on +# automaticly set war dec's according the scheme: +# 1) set war with nonzero player teams, peace w/ 0 player teams +# 2) set war with largest enemy team, peace w/ everyone else +autoSetWar: 1 +# extra info on resources of local planets; add the values of what you want +# displayed: 1 = army count; 2 = repair; 4 = fuel; 8 = agri; 16 = shipyard +# paradise option only +tacPlanetInfo: 9 +# cycle phaser hits through all colors +jubileePhasers: on +# send request for full update ('=') each time you enter +askforupdate: on +# allow a lower case t to send messages to team +lowercaset: on +#use the flight recorder? +#recordGame: on +#recordFile: /tmp/netrek.record +#set maximum record file size in bytes: +maxRecord: 1000000 +# Playback (also, -F <filename> from command line) +#playback: on +#playFile: /tmp/netrek.record +#A minimum of x/10's of a second between redraws: +redrawDelay: 0 +#Draw an X over independant planets: (good for b&w) +showIND: off +#some very silly stuff to draw ship status on local window. +# Either needs work, or needs to be tossed ;) +#(part of an effort to get rid of the dashboard on my small display) +#stats that can be shown: +#'D'amage, 'S'hields, 'F'uel, 'A'rmies, s'P'eed, 'W'temp, 'E'temp +#a lower case letter reverses the line for that stat. +statString: dASF +localShipStats: on +localStatsX: 25 +localStatsY: 450 +statHeight: 80 +#only with short packets: remove "GOD->ALL" from the front of kill msgs. +godToAllOnKills: off +#don't beep when you try to scroll too far: +scrollBeep: off +# Also in scrolling windows: ^p scrolls one line back, ^n one line forward, +# left button one page pack, right button page forward, middle button to end, +# ^e clears the window(but not the scrollback) + +#----[ fonts +#italicfont: 6x10i +#font: -*-clean-medium-r-normal--10-100-75-75-c-60-* +#boldfont: -*-clean-bold-r-normal--10-100-75-75-c-60-* +#italicfont: -*-clean-italic-r-normal--10-100-75-75-c-60-* +#italicfont: -schumacher-clean-bold-r-normal--10-100-75-75-c-60-iso8859-1 +# italic=normal +italicfont: -*-clean-medium-r-normal--10-100-75-75-c-60-* +#bigfont: -*-fixed-medium-r-normal--24-*-100-100-c-120-*-* + +# Here I start messing around with window placement. +# For *all* of the windows listed, you can specify if you want them mapped, +# their geometry, and their parent. +# When specifying geometry for text (and scrolling) windows, specify +# in terms of characters wide and high. Specify size of a menu only +# at your own risk (there is no real benefit to doing this). + +netrek.geometry: 1000x800+0+1 # The main window +netrek_icon.geometry: +1031+0 # The icon +#stats.geometry: +512+576 +#player.geometry: 82x24+0+576 # The player list +player.geometry: 82x24+0+550 # The player list +player.mapped: on +player.parent: netrek +#review.geometry: 82x24+512+576 # Main message window +review.geometry: 82x24+500+548 # Main message window +review.mapped: on +review.parent: netrek + +# +# This is my keymap help file followed by keymap: +# comments to Bill.Dyess@eng.auburn.edu (Thought) +# +# Key Default Function New Function Key +#------------------------------------------------------------------------------ +#| a | ? | afterburners (`) | a | +#| b | bomb planet | | b | +#| c | cloaking | | c | +#| d | detonate other torpedoes | detonate own torps (D) | d | +#| e | docking permission toggle | max warp (%) | e | +#| f | launch plasma torpedoes | | f | +#| g | - | fire phasers (p) | g | +#| h | help window toggle | whatever 'a' was (a) | h | +#| i | info on player / planet | | i | +#| j | - | war window toggle (w) | j | +#| k | set course | | k | +#| l | lock onto player / planet | | l | +#| n | - | change ship types (r) | n | +#| o | orbit (dock at starbase) | | o | +#| p | fire phaser | | p | +#| q | quick quit | warp 3 (3) | q | +#| r | change ship type | pressor beam on (^) | r | +#| s | shields toggle | | s | +#| t | launch torpedoes | tractor beam off (_) | t | +#| u | shields toggle | | u | +#| v | - | info on player / planet (i) | v | +#| w | war window toggle | warp 5 (5) | w | +#| x | beam down armies | Macro mode (X) | x | +#| y | pressor beam toggle | tractor/pressor off ($) | y | +#| z | beam up armies | Coup/Change weapons (C) | z | +#| ' | start message to team | | ' | +#| A | - | army call (F) | A | +#| B | show galactic info (two levels) | | B | +#| C | coup a planet / change weapons | show local info (two levels) (V) | C | +#| D | detonate my torpedoes | ludicrous speed (-) | D | +#| E | emergency distress call | | E | +#| F | army call | lock onto player / planet (l) | F | +#| G | - | lock onto planet (;) | G | +#| I | extended info on player | | I | +#| L | list players | | L | +#| O | options window | | O | +#| M | map updates toggle | | M | +#| N | name mode toggle | | N | +#| P | list planets | | P | +#| Q | self destruct | quick quit (q) | Q | +#| R | repair mode | | R | +#| S | toggle status graph | | S | +#| T | toggle tractor beam | transwarp (*) | T | +#| U | list ranks | | U | +#| V | show local info (two levels) | extended info on player (I) | V | +#| W | - | toggle war window | W | +#| X | macro mode | beam down armies (x) | X | +#| Z | - | beam up armies (z) | Z | +#| ? | message window toggle | help window toggle (h) | ? | +#| _ | turn on tractor beam | | _ | +#| ^ | turn on pressor beam | | ^ | +#| $ | turn off tractor/pressor | | $ | +#| ; | lock onto planet | | ; | +#| * | bring in practice robot | | * | +#| [ | shield down | | [ | +#| ] | shield up | | ] | +#| * | practice robot / transwarp | torps (t) | * | +#| & | re-read .xtrekrc | | & | +#| ` | afterburners | warp 0 (0) | ` | +#|0-9| warp 0-9 | |0-9| +#| ) | warp 10 | | ) | +#| ! | warp 11 | | ! | +#| @ | warp 12 | | @ | +#| % | max warp | | % | +#| # | half warp | | # | +#|Spc| clear all windows | det other torpedoes (d) |Spc| +#| / | - | docking permission toggle (e) | / | +#| - | ludicrous speed | | - | +#------------------------------------------------------------------------------ +#buttonmap uses the remapped keys (annoying) +#buttonmap: 1*2p3k4*5p6k7*8p9ka*bpck +# +#This is the default keymap +#keymap: aabbccddeeffhhiikklloopprrssttuuwwxxyyzz BBCCDDEEIILLOOMMNNPPRRSSTTUUVV??[[]]**00112233445566778899((!!@@%%## +# +keymap: a`bbccdDe%ffgphaiijjkkllmmnrooppq3sst_uuviw5xXy$zC dAFBBCVD-EEFlG;HHIIJJKKLLMMNNOOPPQqRRSST*UUVIWwXxYYZz?h[[]]*t`01133/er^ +# ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ +#ckeymap: ^q^1^w^2^e^3^r^4^xX +# ^ ^ ^ ^ ^ +#keymap: a`dDe%ffgphajwnrq3rytTviw5xXylzCAFCVD-FlGeT*QQVIWwXxZz?h d/e`01133*t +# +#Messages : put cursor in lower thin window, type: 0-9a-j for player, t +#for team, A for all, F/R/K/O for races. Hit Esc to cancel a message. +# +#New keymap graphically: +# +# (q) (w) (e) (r) (t) (y) +# warp3 warp5 maxwarp pressor tractor lockon +# +# (a) (s) (d) (f) (g) (h) +# aftrbrnrs shields detmyown phaser plasma whatever-a +# +# (z) (x) (c) (v) (b) (n) +# weapchange macromode cloak viewinfo bomb newship +# +#Shifted: +# +# (Q) (W) (E) (R) (T) +# quit warwindow emermesg repair transwarp +# +# (A) (S) (D) (F) (G) +# army call status ludicrous lockon dockingtoggle +# +# (Z) (X) (C) (V) (B) +# beamup beamdown localinfo2 xtrainfo galacinfo +# +############################################################################### +# this sets the default server and port (and verification scheme) +server: fod.pnetrek.org +server.arctica: netrek.cis.ufl.edu +server.eden: eelpout.micro.umn.edu +port.arctica 2592 +useRSA.arctica on + +# phaser window +# 0 = don't show 1 = show on kill window 2 = show on phaser window +# 3 = show on total review window only +showPhaser: 2 +review_phaser.mapped: on +review_phaser.parent: netrek +review_phaser.geometry: 81x3+501+500 +#review_phaser.geometry: 81x4+501+543 # pre-newdash + +############################################################################### +# from: jjudy@argon.berkeley.edu (Jack W. Judy) +# Heh! This makes it almost impossible to screw-up and *accidently* choose +# the *wrong* team! Got this idea from an old post. +fed.parent: local #fed - Fed selection window +fed.geometry: 100x100+0+400 +rom.parent: local #rom - Romulan selection window +rom.geometry: 100x100+0+0 +kli.parent: local #kli - Klingon selection window +kli.geometry: 100x100+400+0 +ori.parent: local #ori - Orion selection window +ori.geometry: 100x100+400+400 +quit.parent: local #quit +quit.geometry: 100x100+200+0 + +############################################################################### +# Macro stuff +############################################################################### +#Standard: +# +#%a armies carried by sender +#%d sender damage percentage +#%s sender shield percentage +#%f sender fuel percentage +#%w sender wtemp percentage +#%e sender etemp percentage +#%t team id character of target planet +#%T team id character of sender team +#%c sender id character +#%n armies on target planet +#%E 1 if etemped, 0 if not +#%W 1 if wtemped, 0 if not +#%S sender two character ship type +#%p id character of target player +#%g id char of target friendly player +#%h id char of target enemy player +#%P id character of player nearest sender +#%G id char of friendly player nearest sender +#%H id char of enemy player nearest sender +#%l three character name of target planet +#%i sender full player name (16 character max) +#%u full name of target player (16 character max) +#%z 3 letter team id of target planet +#%b sender nearest planet +#%* abort macro immediately, sending nothing +#% <space> sends nothing - allows macros to start with spaces +#%2 1 if on a paradise server, 0 otherwise +# +#FULLY CAPITALIZED: +#%L three character name of target planet +#%I sender full player name (16 character max) +#%U full name of target player (16 character max) +#%Z 3 letter team id of target planet +#%B sender nearest planet +# +#Ping stats: (may differ slightly from server '!' ping stats) +#%v average ping stat round trip time +#%V ping stat round trip standard deviation +#%y percent total packet loss as calculated by server formula +# +#Miscellanous: +#%m the last message you sent +#%M the last message you sent in all caps +# +#As a further extension to NEWMACRO, a macro may now be sent +#to any of the following destinations: +# +#%i %I %c send message to self +#%u %U %p send message to player nearest mouse +#%t %z %Z send message to team of player nearest mouse +#%g send message to nearest friendly player to my ship +#%h send message to nearest enemy player to my ship +# +#Further, tests may be done within the macro system, the syntax +#for these test is as follows. +#%? introduces a test +#= equivalence +#> greater +#< less +# +#Expressions are evaluated on a character by character basis until the +#test is resolved. The text of the test is then replaced in the macro +#by 1 or 0. +# +#Test are then fed to a syntax I call conditional text. The best way +#to demonstrate how this works is example. +# +#1%{included if true%!included if false%} +# +#This would print: +#included if true +# +#0%{included if true%!included if false%} +#included if false +# +# Paradise orthoganal macros (Robert Forsman) +# +# start with a $ +# +# field 1: +# (n)earest +# (t)arget +# (s)elf (doesn't have fields 2 and 3) +# (_) ego (has no other fields) +# +# field 2: +# (a)ny +# (t)eammate +# (f)riendly +# (h)ostile +# +# field 3: +# (a)ny +# (u)ser +# (p)lanet (includes asteroids) +# (s)tar +# (n)ebula +# (b)lack hole +# (^) non-planet +# (*) any stellar object +# +# field 4: (optional) NYI +# (U)ppercase +# (C)apitalize +# (L)owercase +# +# field 5: +# full (n)ame (Hammor, Thought) +# (i)dentifier (e.g. R5, Ka, Can, Sco) +# (#) number (0-9a-z for players, %d for planets) +# (t)eam name (Romulan) +# (s)hort team id (ROM) +# (l)etter of team (R) +# (a)rmies +# (@) sector +# (M) 0=not metal planet, 1=metal, 2=repair, 3=shipyard +# (A) 0=not arable, 1=arable, 2=agri +# (D) 0=not dilithium, 1=dilithium, 2=fuel +# +# Any implementation of the paradise $ codes (subset or superset) +# must implement and document the $_ code. -- Robert Forsman +#start macros: + +mac.a.T: %?%n<0%{TOUCH %2%{$tasUi->%}%L!%!%2%{$tasLi->%}%l@%n%} +mac.b.T: bomb %2%{$tasLi->%}%l%?%n>4%{ @ %n%} %2%{%?$tapD>1%{ FUEL%}%?$tapA=2%{ AGRI%}%?$tapM>1%{ REPAIR%}%?$tapM>2%{ SHIPYARD%}%} +mac.c: Carrying %?%a>0%{%a arm%?%a=1%{y.%!ies.%}%!no armies.%} +#mac.d.T: %E%{%!%W%{%!I'm fine.%}%}%E%{ETEMPED!!! %}%W%{WTEMPED!!! %}Carrying %?%a>0%{%a armies!%!NO armies.%} +mac.d.T: ogg %p +mac.e.T: Need ESCORT to %l%?%a>0%{, carrying %a arm%?%a=1%{y%!ies!%}%} +mac.f.T: %2%{$tasi->%}%l @ %n +mac.g.T: going to %l%?%a>0%{, carrying %a arm%?%a=1%{y%!ies!%}%} +#mac.h.T: %E%{ETEMPED!!! %}%W%{WTEMPED!!! %}Carrying %?%a>0%{%a armies!%!NO armies.%} +mac.m: %m +mac.n: no +mac.o: ok +# pig call (5 spaces) +mac.p.A: % +mac.q.%i: queue +mac.r.%H: resistance is futile +mac.s.T: We need a sc bomber. +mac.t.T: no t-mode :( +mac.t: thanks +#mac.u.%i: test u macro to self +mac.v: %T%c PING stats: Average: %v ms, Stdv: %V ms, Loss: %y%% +mac.x.T: %L! +mac.y: yes +mac.D.T: %p++ near %l +#mac.E.T: Ignore that last distress +mac.F: resistance is not futile?? +#mac.G.T: Ogg %p! +#mac.G: Go to %l +mac.I.%u: %u: det when you escort! +mac.K.A: KissMy%S +#mac.N.%i: NEWGALAXY +mac.O.%u: (%i) ogging +#mac.R.A: I'm a %?%S=SB%{star base!%!twink!%} +#mac.S.%i: START +#mac.T.%i: %Z +mac.T.T: T-MODE! +#mac.W.%t: SHUT UP, TWINKS!! +#mac.X.T: EMERGENCY @ %L!! + +# hacker note: I have no idea what the stuff in quotes means -RF +#** Giardia Froth's "Ich mochte einen Diebstahl melden." ** + +mac.1.A: $nhuLn, %i taunts your uncle's monkey. +mac.2.A: $nhuLn, %i taunts your ecelesiastical roadkill. +mac.3.A: $nhuLn, %i taunts your upper left bicuspid. +mac.4.A: $nhuLn, %i taunts your favorite obtuse angle. + +mac.`.A: %i wishes that he wasn't a twink like $nhuLn. + + +#whatever +macro.5.%i: %%v %v, %%V %V, %%y %y + +# test macros. +macro.6.%i: %%a %a, %%d %d, %%s %s, %%f %f, %%w %w, %%e %e +macro.7.%i: %%E %E, %%W %w, %%i %i, %%o %o, %%T %T, %%c %c, %%S %S +#target +macro.8.%i: %%t %t, %%p %p, %%g %g, %%h %h, %%n %n +macro.9.%i: %%l %l, %%u %u, %%z %z, + +# nearest +macro.0.%i: %%P %P, %%G %G, %%H %H, %%b %b + +# new distresses +singleMacro: EA +#mac.F.T: %?%S=SB%{Your starbase (%i) is carrying %?%a=0%{NO%!%a%} %?%a=1%{army%!armies%}%!%T%c@%B: I have %?%a=0%{NO%!%a%} %?%a=1%{army%!armies%} on board, heading for %L%?%n<0%{ (untouched)%!@%n%}%} +mac.A.T: %?%S=SB%{Your starbase (%i) is carrying %?%a=0%{NO%!%a%} %?%a=1%{army%!armies%}%!%T%c@%B: I have %?%a=0%{NO%!%a%} %?%a=1%{army%!armies%} on board%} +#mac.Z.T: Going for %L NOW!! DET for me!! (%?%a=0%{NO%!%a%} %?%a=1%{army%!armies%}) +#mac.E.T: HELP! %T%c@%B: %?%a=0%{NO%!%a%} %?%a=1%{army%!armies%}, %d%% dam, %s%% shlds, %?%S=SB%{%!%?%f<15%{NO%!%f%%%} gas%} %E%{ETMP!!%} %?%S=SB%{%W%{WTMP!!%!%w%% wtmp%}%} + +# Multi line macros! One regular macro for each line of the multi-macro: +mac.d.A:% __ _ _ _ _ +mac.d.A:% | _\ /_\ // \\ / \ +mac.d.A:% || \\// \\//___\\\_/ +mac.d.A:% ||_//\\_//\\---// _ +mac.d.A:% |__/ \_/ \\ // {_} + +# use the 'M' flag to specify where multi-macros are displayed: +# (they go to review and review_all by default) +review_all.allow: AM +review.allow: ATIM + +# Receiver Configurable Distress +# each one defined with +#dist.key.name: <format string> +# key is the key you want to use to send that type, format string is how +# an RCD of that type should appear to YOU. You cannot affect how an RCD +# looks to anyone else. The key works just like a macro key, IE press 'X' +# first and then the key, unless that key is defined as a singleMacro, in +# which case you press just that key. +# +# The format string uses the same format as regular macros...except that +# I haven't yet fixed it to use Paradise extensions. That means especially +# that $ escapes do not work, as well as a couple of % escapes which do not +# exist in COW-lite (where I got the code) +# +# The types of RCD for the name field are: +# taking +# ogg +# bomb +# space_control +# save_planet +# base_ogg +# help1 +# help2 +# escorting +# ogging +# bombing +# controlling +# asw +# asbomb +# doing1 +# doing2 +# free_beer +# no_gas +# crippled +# pickup +# pop +# carrying +# other1 +# other2 +# help +# +# defaults are defined for all of them, look at the macro window ('X?') +# to see them. Also, the macro window has 2 pages now, click a mouse +# button to flip between RCD's and regular macros. +# +# The client will send an RCD for E and F by default if on a server that +# supports it. other types of rcd's have macro keys defined. +# +# Note: If you have a macro and an RCD defined for the same key, the macro +# ALWAYS over-rides the RCD. I'm not sure that's the right way to do it, +# but that's what it says in the docs for RCD, so that's how I programmed it... +# +# samples: (these are some of what I use) +dist.E.help: %T%c(%S) %B: HELP! %?%d>90%{HULL GONE! %!%?%d>20%{%d%% dam %}%}%?%s<10%{SHLDS OUT! %!%?%s<80%{%s%% shd %}%}%?%f<10%{NO %!%f%% %}fuel %?%S=SB%{%w%%wtmp%}%E%{ETEMP! %}%W%{WTEMP! %}%?%a>0%{%a %?%a=1%{ogre%!ogres%}%} +dist.F.carrying: %T%c(%S) %B: (%?%S=SB%{%w%%wt%} %s%%sh %d%%dm %f%%fu) Carrying %a armies. +dist.+.pickup: %i(%T%c): %p++ @ %l +dist.p.taking: %T%c(%S) %B: Carrying %a to %l%?%n>-1%{ @ %n%} + +# Beep-lite! +# +# Read the normal beep-lite docs. As an extension, you may specify +# the color for each lite by placing a letter for the color after a +# particular lite. This is being disallowed by most servers, currently +# it only works on calvin. The letters allowed are wrygce, case is not +# important. (e is for grey, the rest should be obvious) example: + +# hilite taker and target in red +lite.taking: /cr/lr + +# To use beep-lite, you must have the next line, or set it from +# the options menu: +UseLite: on +# also, there are several built in lites defined that can be enabled +# by: +DefLite: on + + +############################################################################### +# +# This is the list of windows I've been able to find. Most you will +# probably not want to screw around with, but these can be controlled +# (at least it appears that way in the code...). +# +# I found these by greping for: +# checkMapped +# W_MakeWindow +# W_MakeTextWindow +# W_MakeScrollingWindow +# W_MakeMenu +# +#Window list: +# +#planet - Planet listing (P) +#rank - The rank window (U) +#help - Help window (h) +#macro - Macro Listing (X-?) +#MetaServer List - Metaserver stuff (not quite sure how to use it) +#review - The munged list of messages from all sources +#review_all - Messages to all +#review_team - Messages to your team +#review_your - Messages to you +#review_kill - Kill messages +#review_phaser - The phaser damage window +#netstat - Network statistics +#lagMeter - The Lag-o-Meter +#pingStats - Ping statistics window +#player - Player list +#tstat - Dashboard +#UDP - UDP controls +#network - +#local - Main fighting window +#map - Galactic map +#option - The options window +#wait - +#count - +#waitquit - +#waitmotd - +#info - +#netrek - The "main" window (parent) +#netrek_icon - +#warn - Warnings ("forgot your toothbrush",et al) +#message - Message sending window +#FED - Team windows on entry +#ROM - Team windows on entry +#KLI - Team windows on entry +#ORI - Team windows on entry +#quit - Quit box on entry +#stats - +#scanner - +#war - War delcarations +# +# This gives you: +# name.mapped (on/off for initial mapping) +# name.parent (which window you want this one to be in) +# name.geometry (size and location) +# +############################################################################### +# THE END +###############################################################################
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/senddist.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,174 @@ +/* $Id: senddist.c,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */ + +/* + * distress.c + */ +#include "copyright.h" + +#include <stdio.h> +#include <signal.h> +#include <ctype.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "gameconf.h" + + +/* #$!@$#% length of address field of messages */ +#define ADDRLEN 10 + + +/* this loads all sorts of useful data into a distress struct. + */ +struct distress * +loaddistress(i, data) + enum dist_type i; + W_Event *data; +{ + struct distress *dist; + struct obtype *gettarget(), *gettarget2(), *target; + + dist = (struct distress *) malloc(sizeof(struct distress)); + + dist->sender = me->p_no; + dist->dam = (100 * me->p_damage) / me->p_ship->s_maxdamage; + dist->shld = (100 * me->p_shield) / me->p_ship->s_maxshield; + dist->arms = me->p_armies; + dist->fuelp = (100 * me->p_fuel) / me->p_ship->s_maxfuel; + dist->wtmp = (100 * me->p_wtemp) / me->p_ship->s_maxwpntemp; + dist->etmp = (100 * me->p_etemp) / me->p_ship->s_maxegntemp; + /* so.. call me paranoid -jmn */ + dist->sts = (me->p_flags & 0xff) | 0x80; + dist->wtmpflag = ((me->p_flags & PFWEP) > 0) ? 1 : 0; + dist->etempflag = ((me->p_flags & PFENG) > 0) ? 1 : 0; + dist->cloakflag = ((me->p_flags & PFCLOAK) > 0) ? 1 : 0; + + dist->distype = i; + if (dist->distype > generic || dist->distype < take) + dist->distype = generic; + + target = gettarget(0, me->p_x, me->p_y, TARG_PLANET); + dist->close_pl = target->o_num; + + target = gettarget(data->Window, data->x, data->y, TARG_PLANET); + dist->tclose_pl = target->o_num; + + target = gettarget(0, me->p_x, me->p_y, TARG_PLAYER | TARG_ENEMY); + dist->close_en = target->o_num; + + target = gettarget(data->Window, data->x, data->y, TARG_PLAYER | TARG_ENEMY); + dist->tclose_en = target->o_num; + + target = gettarget(0, me->p_x, me->p_y, TARG_PLAYER | TARG_FRIENDLY); + dist->close_fr = target->o_num; + + target = gettarget(data->Window, data->x, data->y, TARG_PLAYER | TARG_FRIENDLY); + dist->tclose_fr = target->o_num; + + target = gettarget(0, me->p_x, me->p_y, TARG_PLAYER); + dist->close_j = target->o_num; + + target = gettarget(data->Window, data->x, data->y, TARG_PLAYER); + dist->tclose_j = target->o_num; + + /* lets make sure these aren't something stupid */ + dist->cclist[0] = 0x80; + dist->preappend[0] = '\0'; + dist->macroflag = 0; + + return (dist); +} + +/* Coordinating function for _SENDING_ a RCD */ +/* Send an rcd signal out to everyone. */ + +void +rcd(i, data) + enum dist_type i; + W_Event *data; +{ + char ebuf[200]; + struct distress *dist; + char cry[MSG_LEN]; + char *info, *getaddr2(); + int len; + int recip; + int group; + + + group = MTEAM; + recip = idx_to_mask(me->p_teami); + + dist = loaddistress(i, data); + + if (F_gen_distress) { + /* send a generic distress message */ + Dist2Mesg(dist, ebuf); + pmessage(ebuf, recip, group | MDISTR); + } else { + len = makedistress(dist, cry, distmacro[dist->distype].macro); + + if (len > 0) { + /* klude alert */ + info = cry; + if (strncmp(getaddr2(MTEAM, mask_to_idx(recip)), cry, 8) == 0) { + /* + this means we should _strip_ the leading bit because it's + redundant + */ + info = cry + 9; + } + } + pmessage(info, recip, group); + } + + free(dist); +} + +/* the primary subroutine for newmacro, converts the strange and wonderful + ** newmacro syntax into an actual message. + ** This is about as inefficient as they come, but how often is the player + ** going to send a macro?? + ** 6/3/93 - jn + */ +int +pmacro(mnum, who, data) + int mnum; + char who; + W_Event *data; +{ + char addr; + int group, len, recip; + char cry[MSG_LEN]; + char *pm; + struct distress *dist; + + + if (!F_UseNewMacro) + return 0; + + /* get recipient and group */ + if ((who == 't') || (who == 'T')) + addr = teaminfo[me->p_teami].letter; + else + addr = who; + + group = getgroup(addr, &recip); + + if (!group) { + printf("Bad group!\n"); + return (0); + } + pm = macrotable[mnum]->string; + + dist = loaddistress(0, data); + + len = makedistress(dist, cry, pm); + + if (len > 0) + pmessage(cry, recip, group); + + free(dist); + return 1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shipbitmaps.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,863 @@ +/* $Id: shipbitmaps.c,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */ + +/* with this file, now the user can define and develop new ship bitmap + sets ('albums') more easily. + + The user need only create a file in the proper directory with the +proper name with the proper format. The directory is specified by the +shipBitmapPath resource in the .xtrekrc. Its default is +/usr/games/lib/netrek. The name of the file is "R%d.C%d" where the +first integer is the race number and the second is the ship class +number. + + The format of the file is: 3 4-byte integers in network byte order. +The first is the number of views in the file (this field is currently +ignored but should have the value 16). The second integer is the +width and the third is the height. Then follows raw bitmap data. I +don't know what the format is, but it's basically a binary version of +the X bitmap file format. Translate those hex numbers to raw bytes +and you have it. I can tell you that each line is padded to 8 bits. + +*/ + +#include <stdio.h> +#ifndef AMIGA +#include <sys/param.h> +#include <netinet/in.h> +#endif +#include <errno.h> + +#ifdef m_flags + /* appears under HPUX */ +#undef m_flags +#endif + +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "gameconf.h" + +#ifdef NOSHIPBITMAPS +#include "bitmaps_CASB.h" +#else +#include "bitmaps_NEW.h" +#ifdef HOCKEY +#include "puck.h" +#endif /*HOCKEY*/ +#endif + +static int +get_ship_width(team, shipn) + int team, shipn; +{ +#ifndef NOSHIPBITMAPS + if (shipn == ATT && paradise) + return att_width; + switch (team) { + case 0: + switch (shipn) { +#ifdef HOCKEY + case PUCK: + return puck_width; +#endif /*HOCKEY*/ + case SCOUT: + return fed_scout_width; + case DESTROYER: + return fed_destroyer_width; + case CRUISER: + return fed_cruiser_width; + case BATTLESHIP: + return fed_battleship_width; + case ASSAULT: + return fed_assault_width; + case STARBASE: + return fed_starbase_width; + case JUMPSHIP: + return fed_jumpship_width; + case FLAGSHIP: + return fed_galaxy_width; + case GALAXY: + return fed_galaxy_width; + case WARBASE: + return fed_warbase_width; + case LIGHTCRUISER: + return fed_lightcruiser_width; + case CARRIER: + return fed_carrier_height; + case UTILITY: + return fed_utility_width; + case PATROL: + return fed_patrol_width; + } + case 1: + switch (shipn) { +#ifdef HOCKEY + case PUCK: + return puck_width; +#endif /*HOCKEY*/ + case SCOUT: + return rom_scout_width; + case DESTROYER: + return rom_destroyer_width; + case CRUISER: + return rom_cruiser_width; + case BATTLESHIP: + return rom_battleship_width; + case ASSAULT: + return rom_assault_width; + case STARBASE: + return rom_starbase_width; + case JUMPSHIP: + return rom_jumpship_width; + case FLAGSHIP: + return rom_galaxy_width; + case GALAXY: + return rom_galaxy_width; + case WARBASE: + return rom_warbase_width; + case LIGHTCRUISER: + return rom_lightcruiser_width; + case CARRIER: + return rom_carrier_height; + case UTILITY: + return rom_utility_width; + case PATROL: + return rom_patrol_width; + } + case 2: + switch (shipn) { +#ifdef HOCKEY + case PUCK: + return puck_width; +#endif /*HOCKEY*/ + case SCOUT: + return kli_scout_width; + case DESTROYER: + return kli_destroyer_width; + case CRUISER: + return kli_cruiser_width; + case BATTLESHIP: + return kli_battleship_width; + case ASSAULT: + return kli_assault_width; + case STARBASE: + return kli_starbase_width; + case JUMPSHIP: + return kli_jumpship_width; + case FLAGSHIP: + return kli_galaxy_width; + case GALAXY: + return kli_galaxy_width; + case WARBASE: + return kli_warbase_width; + case LIGHTCRUISER: + return kli_lightcruiser_width; + case CARRIER: + return kli_carrier_height; + case UTILITY: + return kli_utility_width; + case PATROL: + return kli_patrol_width; + } + case 3: + switch (shipn) { +#ifdef HOCKEY + case PUCK: + return puck_width; +#endif /*HOCKEY*/ + case SCOUT: + return ori_scout_width; + case DESTROYER: + return ori_destroyer_width; + case CRUISER: + return ori_cruiser_width; + case BATTLESHIP: + return ori_battleship_width; + case ASSAULT: + return ori_assault_width; + case STARBASE: + return ori_starbase_width; + case JUMPSHIP: + return ori_jumpship_width; + case FLAGSHIP: + return ori_galaxy_width; + case GALAXY: + return ori_galaxy_width; + case WARBASE: + return ori_warbase_width; + case LIGHTCRUISER: + return ori_lightcruiser_width; + case CARRIER: + return ori_carrier_height; + case UTILITY: + return ori_utility_width; + case PATROL: + return ori_patrol_width; + } + case -1: + switch (shipn) { +#ifdef HOCKEY + case PUCK: + return puck_width; +#endif /*HOCKEY*/ + case SCOUT: + return ind_scout_width; + case DESTROYER: + return ind_destroyer_width; + case CRUISER: + return ind_cruiser_width; + case BATTLESHIP: + return ind_battleship_width; + case ASSAULT: + return ind_assault_width; + case STARBASE: + return ind_starbase_width; + case JUMPSHIP: + return ind_starbase_width; + case FLAGSHIP: + return ind_galaxy_width; + case GALAXY: + return ind_galaxy_width; + case WARBASE: + return ind_starbase_width; + case LIGHTCRUISER: + return ind_lightcruiser_width; + case CARRIER: + return ind_carrier_height; + case UTILITY: + return ind_utility_width; + case PATROL: + return ind_patrol_width; + } + } +#endif /* NOSHIPBITMAPS */ + return 20; +} + + +static int +get_ship_height(team, shipn) + int team, shipn; +{ +#ifndef NOSHIPBITMAPS + if (shipn == ATT && paradise) + return att_height; + switch (team) { + case 0: + switch (shipn) { +#ifdef HOCKEY + case PUCK: + return puck_height; +#endif /*HOCKEY*/ + case SCOUT: + return fed_scout_height; + case DESTROYER: + return fed_destroyer_height; + case CRUISER: + return fed_cruiser_height; + case BATTLESHIP: + return fed_battleship_height; + case ASSAULT: + return fed_assault_height; + case STARBASE: + return fed_starbase_height; + case JUMPSHIP: + return fed_jumpship_height; + case FLAGSHIP: + return fed_galaxy_height; + case GALAXY: + return fed_galaxy_height; + case WARBASE: + return fed_warbase_height; + case LIGHTCRUISER: + return fed_lightcruiser_height; + case CARRIER: + return fed_carrier_height; + case UTILITY: + return fed_utility_height; + case PATROL: + return fed_patrol_height; + } + case 1: + switch (shipn) { +#ifdef HOCKEY + case PUCK: + return puck_height; +#endif /*HOCKEY*/ + case SCOUT: + return rom_scout_height; + case DESTROYER: + return rom_destroyer_height; + case CRUISER: + return rom_cruiser_height; + case BATTLESHIP: + return rom_battleship_height; + case ASSAULT: + return rom_assault_height; + case STARBASE: + return rom_starbase_height; + case JUMPSHIP: + return rom_jumpship_height; + case FLAGSHIP: + return rom_galaxy_height; + case GALAXY: + return rom_galaxy_height; + case WARBASE: + return rom_warbase_height; + case LIGHTCRUISER: + return rom_lightcruiser_height; + case CARRIER: + return rom_carrier_height; + case UTILITY: + return rom_utility_height; + case PATROL: + return rom_patrol_height; + } + case 2: + switch (shipn) { +#ifdef HOCKEY + case PUCK: + return puck_height; +#endif /*HOCKEY*/ + case SCOUT: + return kli_scout_height; + case DESTROYER: + return kli_destroyer_height; + case CRUISER: + return kli_cruiser_height; + case BATTLESHIP: + return kli_battleship_height; + case ASSAULT: + return kli_assault_height; + case STARBASE: + return kli_starbase_height; + case JUMPSHIP: + return kli_jumpship_height; + case FLAGSHIP: + return kli_galaxy_height; + case GALAXY: + return kli_galaxy_height; + case WARBASE: + return kli_warbase_height; + case LIGHTCRUISER: + return kli_lightcruiser_height; + case CARRIER: + return kli_carrier_height; + case UTILITY: + return kli_utility_height; + case PATROL: + return kli_patrol_height; + } + case 3: + switch (shipn) { +#ifdef HOCKEY + case PUCK: + return puck_height; +#endif /*HOCKEY*/ + case SCOUT: + return ori_scout_height; + case DESTROYER: + return ori_destroyer_height; + case CRUISER: + return ori_cruiser_height; + case BATTLESHIP: + return ori_battleship_height; + case ASSAULT: + return ori_assault_height; + case STARBASE: + return ori_starbase_height; + case JUMPSHIP: + return ori_jumpship_height; + case FLAGSHIP: + return ori_galaxy_height; + case GALAXY: + return ori_galaxy_height; + case WARBASE: + return ori_warbase_height; + case LIGHTCRUISER: + return ori_lightcruiser_height; + case CARRIER: + return ori_carrier_height; + case UTILITY: + return ori_utility_height; + case PATROL: + return ori_patrol_height; + } + case -1: + switch (shipn) { +#ifdef HOCKEY + case PUCK: + return puck_height; +#endif /*HOCKEY*/ + case SCOUT: + return ind_scout_height; + case DESTROYER: + return ind_destroyer_height; + case CRUISER: + return ind_cruiser_height; + case BATTLESHIP: + return ind_battleship_height; + case ASSAULT: + return ind_assault_height; + case STARBASE: + return ind_starbase_height; + case JUMPSHIP: + return ind_starbase_height; + case FLAGSHIP: + return ind_galaxy_height; + case GALAXY: + return ind_galaxy_height; + case WARBASE: + return ind_starbase_height; + case LIGHTCRUISER: + return ind_lightcruiser_height; + case CARRIER: + return ind_carrier_height; + case UTILITY: + return ind_utility_height; + case PATROL: + return ind_patrol_height; + } + } +#endif /* NOSHIPBITMAPS */ + return 20; +} + +static int +get_ship_nviews(shipn) + int shipn; +{ + if (shipn == STARBASE || + shipn == WARBASE || + shipn == JUMPSHIP +#ifdef HOCKEY + || shipn == PUCK +#endif /*HOCKEY*/ + ) + return 1; + else + return 16; +} + +static unsigned char * +get_ship_bits(team, shipn, view) + int team, shipn; + int view; +{ +#ifndef NOSHIPBITMAPS + if (shipn == ATT && paradise) { + if (view > 0) + view = 0; + return att_bits[view]; + } +#endif + if (view > 16) + view = 0; + switch (team) { + case 0: +#ifndef NOSHIPBITMAPS + switch (shipn) { +#ifdef HOCKEY + case PUCK: + return puck_bits; +#endif /*HOCKEY*/ + case SCOUT: + return fed_scout_bits[view]; + case DESTROYER: + return fed_destroyer_bits[view]; + case CRUISER: + return fed_cruiser_bits[view]; + case BATTLESHIP: + return fed_battleship_bits[view]; + case ASSAULT: + return fed_assault_bits[view]; + case STARBASE: + return fed_starbase_bits; + case JUMPSHIP: + return fed_jumpship_bits; + case FLAGSHIP: + return fed_galaxy_bits[view]; + case GALAXY: + return fed_galaxy_bits[view]; + case WARBASE: + return fed_warbase_bits; + case LIGHTCRUISER: + return fed_lightcruiser_bits[view]; + case CARRIER: + return fed_carrier_bits[view]; + case UTILITY: + return fed_utility_bits[view]; + case PATROL: + return fed_patrol_bits[view]; + } +#else + if (get_ship_nviews(shipn) == 1) + return fed_starbase_bits; + else + return fed_cruiser_bits[view]; +#endif + case 1: +#ifndef NOSHIPBITMAPS + switch (shipn) { +#ifdef HOCKEY + case PUCK: + return puck_bits; +#endif /*HOCKEY*/ + case SCOUT: + return rom_scout_bits[view]; + case DESTROYER: + return rom_destroyer_bits[view]; + case CRUISER: + return rom_cruiser_bits[view]; + case BATTLESHIP: + return rom_battleship_bits[view]; + case ASSAULT: + return rom_assault_bits[view]; + case STARBASE: + return rom_starbase_bits; + case JUMPSHIP: + return rom_jumpship_bits; + case FLAGSHIP: + return rom_galaxy_bits[view]; + case GALAXY: + return rom_galaxy_bits[view]; + case WARBASE: + return rom_warbase_bits; + case LIGHTCRUISER: + return rom_lightcruiser_bits[view]; + case CARRIER: + return rom_carrier_bits[view]; + case UTILITY: + return rom_utility_bits[view]; + case PATROL: + return rom_patrol_bits[view]; + } +#else + if (get_ship_nviews(shipn) == 1) + return rom_starbase_bits; + else + return rom_cruiser_bits[view]; +#endif + case 2: +#ifndef NOSHIPBITMAPS + switch (shipn) { +#ifdef HOCKEY + case PUCK: + return puck_bits; +#endif /*HOCKEY*/ + case SCOUT: + return kli_scout_bits[view]; + case DESTROYER: + return kli_destroyer_bits[view]; + case CRUISER: + return kli_cruiser_bits[view]; + case BATTLESHIP: + return kli_battleship_bits[view]; + case ASSAULT: + return kli_assault_bits[view]; + case STARBASE: + return kli_starbase_bits; + case JUMPSHIP: + return kli_jumpship_bits; + case FLAGSHIP: + return kli_galaxy_bits[view]; + case GALAXY: + return kli_galaxy_bits[view]; + case WARBASE: + return kli_warbase_bits; + case LIGHTCRUISER: + return kli_lightcruiser_bits[view]; + case CARRIER: + return kli_carrier_bits[view]; + case UTILITY: + return kli_utility_bits[view]; + case PATROL: + return kli_patrol_bits[view]; + } +#else + if (get_ship_nviews(shipn) == 1) + return kli_starbase_bits; + else + return kli_cruiser_bits[view]; +#endif + case 3: +#ifndef NOSHIPBITMAPS + switch (shipn) { +#ifdef HOCKEY + case PUCK: + return puck_bits; +#endif /*HOCKEY*/ + case SCOUT: + return ori_scout_bits[view]; + case DESTROYER: + return ori_destroyer_bits[view]; + case CRUISER: + return ori_cruiser_bits[view]; + case BATTLESHIP: + return ori_battleship_bits[view]; + case ASSAULT: + return ori_assault_bits[view]; + case STARBASE: + return ori_starbase_bits; + case JUMPSHIP: + return ori_jumpship_bits; + case FLAGSHIP: + return ori_galaxy_bits[view]; + case GALAXY: + return ori_galaxy_bits[view]; + case WARBASE: + return ori_warbase_bits; + case LIGHTCRUISER: + return ori_lightcruiser_bits[view]; + case CARRIER: + return ori_carrier_bits[view]; + case UTILITY: + return ori_utility_bits[view]; + case PATROL: + return ori_patrol_bits[view]; + } +#else + if (get_ship_nviews(shipn) == 1) + return ori_starbase_bits; + else + return ori_cruiser_bits[view]; +#endif + case -1: +#ifndef NOSHIPBITMAPS + switch (shipn) { +#ifdef HOCKEY + case PUCK: + return puck_bits; +#endif /*HOCKEY*/ + case SCOUT: + return ind_scout_bits[view]; + case DESTROYER: + return ind_destroyer_bits[view]; + case CRUISER: + return ind_cruiser_bits[view]; + case BATTLESHIP: + return ind_battleship_bits[view]; + case ASSAULT: + return ind_assault_bits[view]; + case STARBASE: + return ind_starbase_bits; + case JUMPSHIP: + return ind_starbase_bits; + case FLAGSHIP: + return ind_galaxy_bits[view]; + case GALAXY: + return ind_galaxy_bits[view]; + case WARBASE: + return ind_starbase_bits; + case LIGHTCRUISER: + return ind_lightcruiser_bits[view]; + case CARRIER: + return ind_carrier_bits[view]; + case UTILITY: + return ind_utility_bits[view]; + case PATROL: + return ind_patrol_bits[view]; + } +#else + if (get_ship_nviews(shipn) == 1) + return fed_starbase_bits; + else + return fed_cruiser_bits[view]; +#endif + } + return fed_cruiser_bits[view]; +} + + +/* points at the beginning of the fed ship shapes. Independent are + at negative indices */ +static struct ship_shape *all_ship_shapes = 0; + +struct ship_shape * +shape_of_ship(team, shipclass) + int team, shipclass; +{ + if (team < -1 || team >= number_of_teams || + shipclass < 0 || shipclass >= nshiptypes) + return &all_ship_shapes[-nshiptypes]; + return &all_ship_shapes[team * nshiptypes + shipclass]; +} + +void +clear_one_ship_shape(shp) + struct ship_shape *shp; +{ + int j; + for (j = 0; j < shp->nviews; j++) { + W_FreeBitmap(shp->bmap[j]); + } + shp->nviews = 0; + free(shp->bmap); + shp->bmap = 0; + W_FreeBitmap(shp->shield); + shp->shield = 0; +} + +void +free_shipshapes() +{ + /* don't forget that IND offset */ + int race, i; + if (!all_ship_shapes) /* if nothing there to begin with */ + return; + for (race = -1; race < number_of_teams; race++) { + for (i = 0; i < nshiptypes; i++) { + clear_one_ship_shape(shape_of_ship(race, i)); + } + } + free(all_ship_shapes - nshiptypes); + all_ship_shapes = 0; +} + +void +slurp_ship_bitmaps() +{ + int i, race, k; + int width, height, size = 0; + int nviews; /* NYI */ + unsigned char *buf = 0, *buf2; + char *freeme; + char *mainbitmapdir, *bitmapdir; + static char path[MAXPATHLEN]; + + if (all_ship_shapes == 0) { + all_ship_shapes = nshiptypes + (struct ship_shape *) + malloc(sizeof(*all_ship_shapes) * (number_of_teams + 1) * nshiptypes); + } + mainbitmapdir = stringDefault("shipBitmapPath", +#ifndef AMIGA /* worked this way, sort of... was annoying. */ + "/usr/games/lib/netrek" +#else + "netrek:graphics" +#endif /* AMIGA */ + ); + mainbitmapdir = expandFilename(mainbitmapdir); + + for (race = -1 /* IND */ ; race < number_of_teams; race++) { + freeme = NULL; + /* you can now have a different bitmapDir for each race [BDyess] */ + sprintf(path, "shipBitmapPath.%d", race); + if ((bitmapdir = getdefault(path)) == NULL) + bitmapdir = mainbitmapdir; + else + bitmapdir = freeme = expandFilename((char *) strdup(bitmapdir)); + for (k = 0; k < nshiptypes; k++) { + struct ship_shape *curr_shape = shape_of_ship(race, k); + FILE *fp; + sprintf(path, "%s/R%d.C%d", bitmapdir, race, k); + + fp = fopen(path, "r"); + if (fp == 0) { + if (errno != ENOENT) { + fprintf(stderr, "Error accessing ship bitmap file %s:", path); + perror(""); + } + nviews = get_ship_nviews(k, 0); + width = get_ship_width(race, k, 0); + height = get_ship_height(race, k, 0); + } else { + fread(&nviews, sizeof(nviews), 1, fp); + nviews = ntohl(nviews); + fread(&width, sizeof(width), 1, fp); + width = ntohl(width); + fread(&height, sizeof(height), 1, fp); + height = ntohl(height); + if (nviews > get_ship_nviews(k, 0)) + nviews = get_ship_nviews(k, 0); + size = (width + 7) / 8 * height; + buf = (unsigned char *) malloc(size); + } + + curr_shape->nviews = nviews /* nviews */ ; + curr_shape->width = width; + curr_shape->height = height; + curr_shape->shield = W_MakeShieldBitmap(width, height, w); + + curr_shape->bmap = (W_Icon *) malloc(sizeof(*curr_shape->bmap) * + nviews); + + for (i = 0; i < nviews; i++) { + if (fp) { + fread(buf, size, 1, fp); + curr_shape->bmap[i] = + W_StoreBitmap(width, height, buf, w); + } else { + buf2 = get_ship_bits(race, k, i); + curr_shape->bmap[i] = + W_StoreBitmap(width, height, buf2, w); + } + +#if 0 + /* these widths and heights are not necessarily correct */ + if (fp) + buf2 = get_ship_bits(race, k, i, blk_altbits); + else + buf2 = get_ship_bits(race, k, i, !blk_altbits); + + curr_shape->bmap[i + (blk_altbits ? 0 : nviews)] = + W_StoreBitmap(width, height, buf2, w); +#endif + } + + if (fp) { + free(buf); + fclose(fp); + } + } + if (freeme) + free(freeme); + } +} + +void +replace_shipshape(race, shiptype, nviews, width, height) + int race, shiptype, nviews, width, height; +{ + struct ship_shape *shp = shape_of_ship(race, shiptype); + int i; + + clear_one_ship_shape(shp); + + shp->nviews = nviews; + shp->bmap = (W_Icon *) malloc(sizeof(*shp->bmap) * nviews); + shp->width = width; + shp->height = height; + shp->shield = W_MakeShieldBitmap(width, height, w); + for (i = 0; i < nviews; i++) { + /* we really should check the files again. */ + shp->bmap[i] = W_StoreBitmap(get_ship_width(race, shiptype), + get_ship_height(race, shiptype), + get_ship_bits(race, shiptype, i, 0), + w); +#if 0 + shp->bmap[i + nviews] = W_StoreBitmap(get_ship_width(race, shiptype), + get_ship_height(race, shiptype), + get_ship_bits(race, shiptype, i, 0), + w); +#endif + } +} + + +void +replace_ship_bitmap(race, shiptype, view, bits) + int race, shiptype, view; + unsigned char *bits; +{ + struct ship_shape *shp = shape_of_ship(race, shiptype); + + if (view >= shp->nviews) { + fprintf(stderr, "race %d, ship class %d: view %d out of range (0..%d)\n", + race, shiptype, view, shp->nviews - 1); + return; + } + W_FreeBitmap(shp->bmap[view]); + /* store the bitmaps into the auxiliary view */ + shp->bmap[view] = W_StoreBitmap(shp->width, shp->height, bits, w); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/shortcomm.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,1387 @@ +/* $Id: shortcomm.c,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */ + +/* This file implements all SHORT_PACKETS functions */ +/* HW 19.07.93 */ +#ifdef SHORT_PACKETS + +#ifdef HPBSD +#include <machine/endian.h> +#endif + +#include <stdio.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <sys/socket.h> +#include <sys/time.h> +#ifdef RS6K +#include <sys/select.h> +#endif /* RS6K */ +#include <netdb.h> +#include <math.h> +#include <errno.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "packets.h" +#include "gameconf.h" +#ifdef SOUND +#include "Slib.h" +#endif +#include "sound.h" + +#if 1 + +char * +ship_type(shp) + struct ship *shp; +{ + static char ring[4][3]; + static int ri; + char *rval; + ring[ri][0] = shp->s_desig[0]; + ring[ri][1] = shp->s_desig[1]; + ring[ri][2] = 0; + rval = ring[ri]; + ri++; + if (ri >= sizeof(ring) / sizeof(*ring)) + ri = 0; + return rval; +} +#define TEAM_LETTER(p) ( teaminfo[(p).p_teami].letter ) +#define TEAM_SHORT(p) ( teaminfo[(p).p_teami].shortname ) +#define TEAM_LETTERP(pl) ( teaminfo[mask_to_idx((pl).pl_owner)].letter ) +#define TEAM_SHORTP(pl) ( teaminfo[mask_to_idx((pl).pl_owner)].shortname ) +#define reviewWin messWin[WREVIEW].window +#define MAXTORP ntorps +#define MAXPLANETS nplanets +#define MAXPLASMA nplasmas + +#else + +#define ship_type(shp) shiptype[(shp).s_type] +#define TEAM_LETTER(p) ( teamlet[(p).p_team] ) +#define TEAM_SHORT(p) ( teamshort[(p).p_team] ) +#define TEAM_LETTERP(pl) ( teamlet[(pl).pl_owner] ) +#define TEAM_SHORTP(pl) ( teamshort[(pl).pl_owner] ) + +#endif + +/* from here on all SHORT_PACKETS */ +#include "wtext.h" /* here are all warningdefines */ + +/* Here are all warnings that are send with SP_S_WARNING */ +/* HW 93 */ + +/* DaemonMessages */ +char *daemon_texts[] = +{ +/* Game_Paused() */ + "Game is paused. CONTINUE to continue.", /* 0 */ + "Game is no-longer paused!",/* 1 */ + "Game is paused. Captains CONTINUE to continue.", /* 2 */ + "Game will continue in 10 seconds", /* 3 */ +/* send_about_to_start() */ + "Teams chosen. Game will start in 1 minute.", /* 4 */ + "----------- Game will start in 1 minute -------------", /* 5 */ +}; + +/* VARITEXTE = warnings with 1 or more arguments argument */ +char *vari_texts[] = +{ +/* redraw.c */ + "Engineering: Energizing transporters in %d seconds", /* 0 */ + "Stand By ... Self Destruct in %d seconds", /* 1 */ + "Helmsman: Docking manuever completed Captain. All moorings secured at port %d.", /* 2 */ +/* interface.c from INL server */ + "Not constructed yet. %d minutes required for completion", /* 3 */ + +}; + + + +char *w_texts[] = +{ +/* socket.c */ + "Tractor beams haven't been invented yet.", /* 0 */ + "Weapons's Officer: Cannot tractor while cloaked, sir!", /* 1 */ + "Weapon's Officer: Vessel is out of range of our tractor beam.", /* 2 */ + +/* handleRepressReq */ +/**************** coup.c ***********************/ +/* coup() */ + "You must have one kill to throw a coup", /* 3 */ + "You must orbit your home planet to throw a coup", /* 4 */ + "You already own a planet!!!", /* 5 */ + "You must orbit your home planet to throw a coup", /* 6 */ + "Too many armies on planet to throw a coup", /* 7 */ + "Planet not yet ready for a coup", /* 8 */ +/* getentry.c */ +/* getentry() */ + "I cannot allow that. Pick another team", /* 9 */ + "Please confirm change of teams. Select the new team again.", /* 10 */ + "That is an illegal ship type. Try again.", /* 11 */ + "That ship hasn't beed designed yet. Try again.", /* 12 */ + "Your new starbase is still under construction", /* 13 */ + "Your team is not capable of defending such an expensive ship!", /* 14 */ + "Your team's stuggling economy cannot support such an expenditure!", /* 15 */ + "Your side already has a starbase!", /* 16 */ +/* plasma.c */ +/* nplasmatorp(course, type) */ + "Plasmas haven't been invented yet.", /* 17 */ + "Weapon's Officer: Captain, this ship is not armed with plasma torpedoes!", /* 18 */ + "Plasma torpedo launch tube has exceeded the maximum safe temperature!", /* 19 */ + "Our fire control system limits us to 1 live torpedo at a time captain!", /* 20 */ + "Our fire control system limits us to 1 live torpedo at a time captain!", /* 21 */ + "We don't have enough fuel to fire a plasma torpedo!", /* 22 */ + "We cannot fire while our vessel is undergoing repairs.", /* 23 */ + "We are unable to fire while in cloak, captain!", /* 24 */ +/******** torp.c *********/ +/* ntorp(course, type) */ + "Torpedo launch tubes have exceeded maximum safe temperature!", /* 25 */ + "Our computers limit us to having 8 live torpedos at a time captain!", /* 26 */ + "We don't have enough fuel to fire photon torpedos!", /* 27 */ + "We cannot fire while our vessel is in repair mode.", /* 28 */ + "We are unable to fire while in cloak, captain!", /* 29 */ + "We only have forward mounted cannons.", /* 30 */ +/* phasers.c */ +/* phaser(course) */ + "Weapons Officer: This ship is not armed with phasers, captain!", /* 31 */ + "Phasers have not recharged", /* 32 */ + "Not enough fuel for phaser", /* 33 */ + "Can't fire while repairing", /* 34 */ + "Weapons overheated", /* 35 */ + "Cannot fire while cloaked",/* 36 */ + "Phaser missed!!!", /* 37 */ + "You destroyed the plasma torpedo!", /* 38 */ +/* interface.c */ +/* bomb_planet() */ + "Must be orbiting to bomb", /* 39 */ + "Can't bomb your own armies. Have you been reading Catch-22 again?", /* 40 */ + "Must declare war first (no Pearl Harbor syndrome allowed here).", /* 41 */ + "Bomb out of T-mode? Please verify your order to bomb.", /* 42 */ + "Hoser!", /* 43 */ +/* beam_up() */ + "Must be orbiting or docked to beam up.", /* 44 */ + "Those aren't our men.", /* 45 */ + "Comm Officer: We're not authorized to beam foriegn troops on board!", /* 46 */ +/* beam_down() */ + "Must be orbiting or docked to beam down.", /* 47 */ + "Comm Officer: Starbase refuses permission to beam our troops over.", /* 48 */ +/* declare_war(mask) */ + "Pausing ten seconds to re-program battle computers.", /* 49 */ +/* do_refit(type) */ + "You must orbit your HOME planet to apply for command reassignment!", /* 50 */ + "You must orbit your home planet to apply for command reassignment!", /* 51 */ + "Can only refit to starbase on your home planet.", /* 52 */ + "You must dock YOUR starbase to apply for command reassignment!", /* 53 */ + "Must orbit home planet or dock your starbase to apply for command reassignment!", /* 54 */ + "Central Command refuses to accept a ship in this condition!", /* 55 */ + "You must beam your armies down before moving to your new ship", /* 56 */ + "That ship hasn't been designed yet.", /* 57 */ + "Your side already has a starbase!", /* 58 */ + "Your team is not capable of defending such an expensive ship", /* 59 */ + "Your new starbase is still under construction", /* 60 */ + "Your team's stuggling economy cannot support such an expenditure!", /* 61 */ + "You are being transported to your new vessel .... ", /* 62 */ +/* redraw.c */ +/* auto_features() */ + "Engineering: Energize. [ SFX: chimes ]", /* 63 */ + "Wait, you forgot your toothbrush!", /* 64 */ + "Nothing like turning in a used ship for a new one.", /* 65 */ + "First officer: Oh no, not you again... we're doomed!", /* 66 */ + "First officer: Uh, I'd better run diagnostics on the escape pods.", /* 67 */ + "Shipyard controller: This time, *please* be more careful, okay?", /* 68 */ + "Weapons officer: Not again! This is absurd...", /* 69 */ + "Weapons officer: ... the whole ship's computer is down?", /* 70 */ + "Weapons officer: Just to twiddle a few bits of the ship's memory?", /* 71 */ + "Weapons officer: Bah! [ bangs fist on inoperative console ]", /* 72 */ + "First Officer: Easy, big guy... it's just one of those mysterious", /* 73 */ + "First Officer: laws of the universe, like 'tires on the ether'.", /* 74 */ + "First Officer: laws of the universe, like 'Klingon bitmaps are ugly'.", /* 75 */ + "First Officer: laws of the universe, like 'all admirals have scummed'.", /* 76 */ + "First Officer: laws of the universe, like 'Mucus Pig exists'.", /* 77 */ + "First Officer: laws of the universe, like 'guests advance 5x faster'.", /* 78 */ +/* orbit.c */ +/*orbit() */ + "Helmsman: Captain, the maximum safe speed for docking or orbiting is warp 2!", /* 79 */ + "Central Command regulations prohibits you from orbiting foreign planets", /* 80 */ + "Helmsman: Sensors read no valid targets in range to dock or orbit sir!", /* 81 */ +/* redraw.c */ + "No more room on board for armies", /* 82 */ + "You notice everyone on the bridge is staring at you.", /* 83 */ +/* startdaemon.c */ +/* practice_robo() */ + "Can't send in practice robot with other players in the game.", /* 84 */ +/* socket.c */ +/* doRead(asock) */ + "Self Destruct has been canceled", /* 85 */ +/* handleMessageReq(packet) */ + "Be quiet", /* 86 */ + "You are censured. Message was not sent.", /* 87 */ + "You are ignoring that player. Message was not sent.", /* 88 */ + "That player is censured. Message was not sent.", /* 89 */ +/* handleQuitReq(packet) */ + "Self destruct initiated", /* 90 */ +/* handleScan(packet) */ + "Scanners haven't been invented yet", /* 91 */ +/* handleUdpReq(packet) */ + "WARNING: BROKEN mode is enabled", /* 92 */ + "Server can't do that UDP mode", /* 93 */ + "Server will send with TCP only", /* 94 */ + "Server will send with simple UDP", /* 95 */ + "Request for fat UDP DENIED (set to simple)", /* 96 */ + "Request for double UDP DENIED (set to simple)", /* 97 */ +/* forceUpdate() */ + "Update request DENIED (chill out!)", /* 98 */ +/* INL redraw.c */ + "Player lock lost while player dead.", /* 99 */ + "Can only lock on own team.", /* 100 */ + "You can only warp to your own team's planets!", /* 101 */ + "Planet lock lost on change of ownership.", /* 102 */ + " Weapons officer: Finally! systems are back online!", /* 103 */ + +}; + +#define NUMWTEXTS (sizeof w_texts / sizeof w_texts[0]) +#define NUMVARITEXTS ( sizeof vari_texts / sizeof vari_texts[0]) +#define NUMDAEMONTEXTS ( sizeof daemon_texts / sizeof daemon_texts[0]) + + +void add_whydead(); + +extern int vtisize[]; +extern unsigned char numofbits[]; +#if 0 +int Plx[MAX_PLAYER], Ply[MAX_PLAYER], Pgx[MAX_PLAYER], Pgy[MAX_PLAYER]; +unsigned char Pdir[MAX_PLAYER]; +#endif +int my_x, my_y; /* for rotation we need to keep track of our + real coordinates */ +/* SP_S_WARNING vari texte */ +char *s_texte[256]; /* Better with a malloc scheme */ +char no_memory[] = +{"Not enough memory for warning string!"}; + +#if 0 +/* For INL Server */ +char *shiptype[NUM_TYPES] = +{"SC", "DD", "CA", "BB", "AS", "SB", "??"}; +#endif +int spwinside = 500; /* WINSIDE from Server */ +long spgwidth = 100000; + + +void +sendThreshold(v) + unsigned short v; +{ + struct threshold_cpacket p; + + p.type = CP_S_THRS; + p.thresh = v; + sendServerPacket((struct player_spacket *) & p); +} + +void +handleVTorp(sbuf) + unsigned char *sbuf; +{ + unsigned char *which, *data; + unsigned char bitset; + struct torp *thetorp; + int dx, dy; + int shiftvar; + + int i; + register int shift = 0; /* How many torps are extracted (for shifting + ) */ + +/* now we must find the data ... :-) */ + if (sbuf[0] == SP_S_8_TORP) { /* MAX packet */ + bitset = 0xff; + which = &sbuf[1]; + data = &sbuf[2]; + } else { /* Normal Packet */ + bitset = sbuf[1]; + which = &sbuf[2]; + data = &sbuf[3]; + } + +#ifdef CORRUPTED_PACKETS +/* we probably should do something clever here - jmn */ +#endif + + thetorp = &torps[((unsigned char) *which * 8)]; + for (shift = 0, i = 0; i < 8; +#if defined(RS6K) || defined(__SABER__) + i++, thetorp++, bitset >>= 1) { +#else + i++, thetorp++, bitset = ((unsigned char)bitset) >> 1) { +#endif + if (bitset & 01) { + dx = (*data >> shift); + data++; + shiftvar = (unsigned char) *data; /* to silence gcc */ + shiftvar <<= (8 - shift); + dx |= (shiftvar & 511); + shift++; + dy = (*data >> shift); + data++; + shiftvar = (unsigned char) *data; /* to silence gcc */ + shiftvar <<= (8 - shift); + dy |= (shiftvar & 511); + shift++; + if (shift == 8) { + shift = 0; + data++; + } +/* This is necessary because TFREE/TMOVE is now encoded in the bitset */ + if (thetorp->t_status == TFREE) { + thetorp->t_status = TMOVE; /* guess */ + players[thetorp->t_owner].p_ntorp++; +#ifdef UNIX_SOUND + play_sound (SND_FIRETORP); /* Fire Torp */ +#endif + } else if (thetorp->t_owner == me->p_no && thetorp->t_status == TEXPLODE) { + thetorp->t_status = TMOVE; /* guess */ + } + /* Check if torp is visible */ + if (dx > spwinside || dy > spwinside) { + thetorp->t_x = -100000; /* Not visible */ + thetorp->t_y = -100000; + } else { /* visible */ +/* thetorp->t_x = me->p_x + ((dx - spwinside / 2) * SCALE); + thetorp->t_y = me->p_y + ((dy - spwinside / 2) * SCALE); */ + thetorp->t_x = my_x + ((dx - spwinside / 2) * SCALE); + thetorp->t_y = my_y + ((dy - spwinside / 2) * SCALE); +#ifdef ROTATERACE + if (rotate) { + rotate_coord(&thetorp->t_x, &thetorp->t_y, rotate_deg, + spgwidth / 2, spgwidth / 2); + } +#endif + } + } + /* if */ + else { /* We got a TFREE */ + if (thetorp->t_status && thetorp->t_status != TEXPLODE) { + players[thetorp->t_owner].p_ntorp--; + thetorp->t_status = TFREE; /* That's no guess */ + } + } + } /* for */ +} + +void +handleSelfShort(packet) + struct youshort_spacket *packet; +{ + me = (ghoststart ? &players[ghost_pno] : &players[packet->pnum]); + myship = me->p_ship; + mystats = &(me->p_stats); + me->p_hostile = packet->hostile; + me->p_swar = packet->swar; + me->p_armies = packet->armies; + me->p_flags = ntohl(packet->flags); + me->p_whydead = packet->whydead; + me->p_whodead = packet->whodead; +#ifdef SOUND + S_HandlePFlags(); +#endif +} + +void +handleSelfShip(packet) + struct youss_spacket *packet; +{ + if (!me) + return; /* wait.. */ + + me->p_damage = ntohs(packet->damage); + me->p_shield = ntohs(packet->shield); + me->p_fuel = ntohs(packet->fuel); + me->p_etemp = ntohs(packet->etemp); + me->p_wtemp = ntohs(packet->wtemp); +#ifdef SOUND + S_HandlePFlags(); +#endif +} + +void +handleVPlayer(sbuf) + unsigned char *sbuf; +{ + register int x, y, i, numofplayers, pl_no, save; + register struct player *pl; + unsigned char newdir; /* needed for uncloak kludge with ROTATERACE */ + int offset; + + numofplayers = (unsigned char) sbuf[1] & 0x3f; + + if (sbuf[1] & (unsigned char) 128) { /* Short Header + Extended */ + sbuf += 4; + offset = 32; /* more than 32 players? */ + } else if (sbuf[1] & 64) { /* Short Header */ + sbuf += 4; + offset = 0; + } else { + struct player_s_spacket *packet = (struct player_s_spacket *) sbuf; + pl = &players[me->p_no]; + pl->p_dir = (unsigned char) packet->dir; +#if 0 + Pdir[me->p_no] = (unsigned char) rosette(pl->p_dir, 16); +#endif + pl->p_speed = packet->speed; +#ifdef FEATURE + if (F_dead_warp && (pl->p_speed == 14)) { + if (pl->p_status == PALIVE) { + pl->p_status = PEXPLODE; + pl->p_explode = 0; + } + } else +#endif + { + pl->p_x = my_x = ntohl(packet->x); + pl->p_y = my_y = ntohl(packet->y); +#ifdef ROTATERACE + if (rotate) { + rotate_coord(&pl->p_x, &pl->p_y, + rotate_deg, spgwidth / 2, spgwidth / 2); + rotate_dir(&pl->p_dir, rotate_deg); + } +#endif +#if 0 + Plx[me->p_no] = WINSIDE / 2; + Ply[me->p_no] = WINSIDE / 2; + Pgx[me->p_no] = pl->p_x * WINSIDE / spgwidth; + Pgy[me->p_no] = pl->p_y * WINSIDE / spgwidth; +#endif + } + redrawPlayer[me->p_no] = 1; + sbuf += 12; /* Now the small packets */ + offset = 0; + } + for (i = 0; i < numofplayers; i++) { + pl_no = ((unsigned char) *sbuf & 0x1f) + offset; + if (pl_no >= nplayers) + continue; + save = (unsigned char) *sbuf; + sbuf++; + pl = &players[pl_no]; + pl->p_speed = (unsigned char) *sbuf & 15; /* SPEED */ +#if 0 + Pdir[pl_no] = (unsigned char) *sbuf >> 4; /* DIR */ +#endif + newdir = (unsigned char) *sbuf & 0xf0; /* realDIR */ + +#ifdef ROTATERACE + if (rotate) + rotate_dir(&newdir, rotate_deg); +#endif +#ifdef FEATURE + if (cloakerMaxWarp) { + if (pl->p_speed == 15) + pl->p_flags |= PFCLOAK; + else + pl->p_flags &= ~(PFCLOAK); + } else +#endif + { +#ifdef CHECK_DROPPED + /* + this is a mess. Too many exceptions. I don't use it any + more. cloakerMaxWarp is much much better, but requires server + support. + */ + /* + Kludge to fix lost uncloak packets! [3/94] -JR may be a + problem with server sending directions after cloakphase is at + CLOAK_PHASES-1, since cloakphase is strictly a client variable + :( + */ + if (pl->p_flags & PFCLOAK && pl->p_cloakphase >= (CLOAK_PHASES - 1) && + (pl->p_dir & 0xf0 != newdir & 0xf0) && !(pl->p_flags & PFORBIT)) { + int i, plocked = 0; + for (i = 0; i < nplayers; i++) { + if ((phasers[i].ph_status & PHHIT) && (phasers[i].ph_target == pl_no)) { + plocked = 1; + break; + } + } + if (!plocked) + /* + if all of the above, the guy is *probably* uncloaked. + Ask the server. + */ + sendShortReq(SPK_SALL); + } +#endif + } + pl->p_dir = newdir; /* realDIR */ + + sbuf++; + x = (unsigned char) *sbuf++; + y = (unsigned char) *sbuf++; /* The lower 8 Bits are saved */ + + /* Now we must preprocess the coordinates */ + if ((unsigned char) save & 64) + x |= 256; + if ((unsigned char) save & 128) + y |= 256; +#ifdef FEATURE + /* + MAY CHANGE! dead_warp is still an experiment, some servers are + also sending illegal co-ords for dead players, so we'll just + ignore 'em for now if the guy's dead. + */ + if (F_dead_warp && pl->p_speed == 14) { + if (pl->p_status == PALIVE) { + pl->p_status = PEXPLODE; + pl->p_explode = 0; + } + redrawPlayer[pl->p_no] = 1; + continue; + } +#endif + /* Now test if it's galactic or local coord */ + if (save & 32) { /* It's galactic */ +#if 0 + if (x >= 501 || y >= 501) { + pl->p_x = -500 * spgwidth / spwinside; + pl->p_y = -500 * spgwidth / spwinside; + } else +#endif + { + pl->p_x = x * spgwidth / spwinside; + pl->p_y = y * spgwidth / spwinside; + } +#if 0 + Pgx[pl_no] = x; + Pgy[pl_no] = y; + Plx[pl_no] = -1; /* Not visible */ + Ply[pl_no] = -1; +#endif + } else { /* Local */ + pl->p_x = my_x + ((x - spwinside / 2) * SCALE); + pl->p_y = my_y + ((y - spwinside / 2) * SCALE); +#if 0 + Plx[pl_no] = x; + Ply[pl_no] = y; + Pgx[pl_no] = pl->p_x * spwinside / spgwidth; + Pgy[pl_no] = pl->p_y * spwinside / spgwidth; +#endif + } + redrawPlayer[pl->p_no] = 1; +#ifdef ROTATERACE + if (rotate) { + rotate_coord(&pl->p_x, &pl->p_y, + rotate_deg, spgwidth / 2, spgwidth / 2); + } +#endif + } /* for */ +} + +void +handleSMessage(packet) + struct mesg_s_spacket *packet; +{ + char buf[100]; + char addrbuf[9]; + +#if 0 + if (debug) + printf("Length of Message is: %d total Size %d \n", strlen(&packet->mesg), (int) packet->length); +#endif + if (packet->m_from >= nplayers) + packet->m_from = 255; + + if (packet->m_from == 255) + strcpy(addrbuf, "GOD->"); + else { + sprintf(addrbuf, " %c%c->", TEAM_LETTER(players[packet->m_from]), + shipnos[players[packet->m_from].p_no]); + } + + switch (packet->m_flags & (MTEAM | MINDIV | MALL)) { + case MALL: + sprintf(addrbuf + 5, "ALL"); + break; + case MTEAM: + sprintf(addrbuf + 5, TEAM_SHORT(*me)); + break; + case MINDIV: + /* I know that it's me -> xxx but i copied it straight ... */ + sprintf(addrbuf + 5, "%c%c ", TEAM_LETTER(players[packet->m_recpt]), + shipnos[packet->m_recpt]); + break; + default: + sprintf(addrbuf + 5, "ALL"); + break; + } + sprintf(buf, "%-9s%s", addrbuf, &packet->mesg); + dmessage(buf, packet->m_flags, packet->m_from, packet->m_recpt); +} + +void +handleShortReply(packet) + struct shortreply_spacket *packet; +{ + switch (packet->repl) { + case SPK_VOFF: + recv_short = 0; + sprefresh(SPK_VFIELD); + break; + case SPK_VON: + recv_short = 1; + sprefresh(SPK_VFIELD); + + spwinside = (CARD16) ntohs(packet->winside); + /* + bug in server-side SP code, wrong-endian machines confuse a client + with normal byte order + */ + if (spwinside == 0xf401) + spwinside = 0x01f4; + + if (paradise) { + spgwidth = (INT32) ntohl(packet->gwidth); + blk_gwidth = spgwidth; + blk_windgwidth = (float)spwinside; + redrawall = 1; + + /* + bug in server-side SP code, wrong-endian machines confuse a + client with normal byte order + */ + if (spgwidth == 0xa0860100) + spgwidth = 0x000186a0; + if (spgwidth == 0x0100) + spgwidth = 0x000186a0; + } + break; + case SPK_MOFF: + recv_mesg = 0; + sprefresh(SPK_MFIELD); + W_SetSensitive(reviewWin, 0); + break; + case SPK_MON: + recv_mesg = 1; + sprefresh(SPK_MFIELD); + W_SetSensitive(reviewWin, 1); + break; + case SPK_M_KILLS: + recv_kmesg = 1; + sprefresh(SPK_KFIELD); + break; + case SPK_M_NOKILLS: + recv_kmesg = 0; + sprefresh(SPK_KFIELD); + break; + case SPK_M_WARN: + recv_warn = 1; + sprefresh(SPK_WFIELD); + break; + case SPK_M_NOWARN: + recv_warn = 0; + sprefresh(SPK_WFIELD); + break; + + case SPK_THRESHOLD: + break; + default: + fprintf(stderr, "%s: unknown response packet value short-req: %d\n", + "netrek", packet->repl); + } +} + +void +handleVTorpInfo(sbuf) + unsigned char *sbuf; +{ + unsigned char *bitset, *which, *data, *infobitset, *infodata; + struct torp *thetorp; + int dx, dy; + int shiftvar; + char status, war; + register int i; + register int shift = 0; /* How many torps are extracted (for shifting + ) */ + +/* now we must find the data ... :-) */ + bitset = &sbuf[1]; + which = &sbuf[2]; + infobitset = &sbuf[3]; +/* Where is the data ? */ + data = &sbuf[4]; + infodata = &sbuf[vtisize[numofbits[(unsigned char) sbuf[1]]]]; + + thetorp = &torps[(unsigned char) (*which * 8)]; + + for (shift = 0, i = 0; i < 8; +#if defined(RS6K) || defined(__SABER__) + thetorp++, *bitset >>= 1, *infobitset >>= 1, i++) { +#else + thetorp++, *bitset = ((unsigned char)*bitset) >> 1, *infobitset = ((unsigned char) *infobitset) >> 1, i++) { +#endif + + if (*bitset & 01) { + dx = (*data >> shift); + data++; + shiftvar = (unsigned char) *data; /* to silence gcc */ + shiftvar <<= (8 - shift); + dx |= (shiftvar & 511); + shift++; + dy = (*data >> shift); + data++; + shiftvar = (unsigned char) *data; /* to silence gcc */ + shiftvar <<= (8 - shift); + dy |= (shiftvar & 511); + shift++; + if (shift == 8) { + shift = 0; + data++; + } + /* Check for torp with no TorpInfo */ + if (!(*infobitset & 01)) { + if (thetorp->t_status == TFREE) { + thetorp->t_status = TMOVE; /* guess */ + players[thetorp->t_owner].p_ntorp++; + } else if (thetorp->t_owner == me->p_no && + thetorp->t_status == TEXPLODE) { /* If TFREE got lost */ + thetorp->t_status = TMOVE; /* guess */ + } + } + /* Check if torp is visible */ + if (dx > spwinside || dy > spwinside) { + thetorp->t_x = -100000; /* Not visible */ + thetorp->t_y = -100000; + } else { /* visible */ +/* thetorp->t_x = me->p_x + ((dx - spwinside / 2) * SCALE); + thetorp->t_y = me->p_y + ((dy - spwinside / 2) * SCALE); +*/ + thetorp->t_x = my_x + ((dx - spwinside / 2) * + SCALE); + thetorp->t_y = my_y + ((dy - spwinside / 2) * + SCALE); + +#ifdef ROTATERACE + if (rotate) { + rotate_coord(&thetorp->t_x, &thetorp->t_y, rotate_deg, + spgwidth / 2, spgwidth / 2); + } +#endif + } + } + /* if */ + else { /* Got a TFREE ? */ + if (!(*infobitset & 01)) { /* No other TorpInfo for this Torp */ + if (thetorp->t_status && thetorp->t_status != TEXPLODE) { + players[thetorp->t_owner].p_ntorp--; + thetorp->t_status = TFREE; /* That's no guess */ + } + } + } + /* Now the TorpInfo */ + if (*infobitset & 01) { + war = (unsigned char) *infodata & 15 /* 0x0f */ ; + status = ((unsigned char) *infodata & 0xf0) >> 4; + infodata++; + if (status == TEXPLODE && thetorp->t_status == TFREE) { + /* FAT: redundant explosion; don't update p_ntorp */ + continue; + } + if (thetorp->t_status == TFREE && status) { + players[thetorp->t_owner].p_ntorp++; +#ifdef UNIX_SOUND + play_sound (SND_FIRETORP); /* Fire Torp */ +#endif + } + if (thetorp->t_status && status == TFREE) { + players[thetorp->t_owner].p_ntorp--; + } + thetorp->t_war = war; + if (status != thetorp->t_status) { + /* FAT: prevent explosion reset */ + thetorp->t_status = status; + if (thetorp->t_status == TEXPLODE) { + thetorp->t_fuse = NUMDETFRAMES; + } + } + } /* if */ + } /* for */ +} + +void +handleVPlanet(sbuf) + unsigned char *sbuf; +{ + register int i; + register int numofplanets; /* How many Planets are in the packet */ + struct planet *plan; + struct planet_s_spacket *packet = (struct planet_s_spacket *) & sbuf[2]; + /* FAT: prevent excessive redraw */ + int redraw = 0; + + numofplanets = (unsigned char) sbuf[1]; + + if (numofplanets > MAXPLANETS + 1) + return; + + for (i = 0; i < numofplanets; i++, packet++) { + if (packet->pnum < 0 || packet->pnum >= MAXPLANETS) + continue; + + plan = &planets[packet->pnum]; + if (plan->pl_owner != packet->owner) + redraw = 1; + plan->pl_owner = packet->owner; + + if (plan->pl_info != packet->info) + redraw = 1; + + plan->pl_info = packet->info; + /* Redraw the planet because it was updated by server */ + + if (plan->pl_flags != (int) ntohs(packet->flags)) + redraw = 1; + plan->pl_flags = (int) ntohs(packet->flags); + + if (plan->pl_armies != (unsigned char) packet->armies) { +/*#ifdef EM*/ + /* + don't redraw when armies change unless it crosses the '4' * + army limit. Keeps people from watching for planet 'flicker' * + when players are beaming + */ + int planetarmies = (unsigned char) packet->armies; + if ((plan->pl_armies < 5 && planetarmies > 4) || + (plan->pl_armies > 4 && planetarmies < 5)) +/*#endif*/ + redraw = 1; + } + + plan->pl_armies = (unsigned char) packet->armies; + if (plan->pl_info == 0) { + plan->pl_owner = NOBODY; + } + + if (redraw) { + plan->pl_flags |= PLREDRAW; + pl_update[packet->pnum].plu_update = 1; + pl_update[packet->pnum].plu_x = plan->pl_x; + pl_update[packet->pnum].plu_y = plan->pl_y; + + } + } /* FOR */ +} + +void +sendShortReq(state) + char state; +{ + struct shortreq_cpacket shortReq; + + shortReq.type = CP_S_REQ; + shortReq.req = state; + shortReq.version = SHORTVERSION; + switch (state) { + case SPK_VON: + warning("Sending short packet request"); + break; + case SPK_VOFF: + warning("Sending old packet request"); + break; + default: + break; + } + if ((state == SPK_SALL || state == SPK_ALL) && recv_short) { + /* Let the client do the work, and not the network :-) */ + + register int i; + for (i = 0; i < nplayers * MAXTORP; i++) + torps[i].t_status = TFREE; + + for (i = 0; i < nplayers * MAXPLASMA; i++) + plasmatorps[i].pt_status = PTFREE; + + for (i = 0; i < nplayers; i++) { + players[i].p_ntorp = 0; + players[i].p_nplasmatorp = 0; + phasers[i].ph_status = PHFREE; + } + if (state == SPK_SALL) + warning("Sent request for small update (weapons+planets+kills)"); + else if (state == SPK_ALL) + warning("Sent request for medium update (all except stats)"); + else + warning("Sent some unknown request..."); + } + sendServerPacket((struct shortreq_cpacket *) & shortReq); +} + +char *whydeadmess[] = +{"", "[quit]", "[photon]", "[phaser]", "[planet]", "[explosion]", + "", "", "[ghostbust]", "[genocide]", "", "[plasma]", "[detted photon]", "[chain explosion]", +"[TEAM]", "", "[team det]", "[team explosion]"}; + + +void +handleSWarning(packet) + struct warning_s_spacket *packet; +{ + char buf[80]; + register struct player *target; + register int damage; + static int arg3, arg4; /* Here are the arguments for warnings with + more than 2 arguments */ + static int karg3, karg4, karg5 = 0; + char killmess[20]; + + switch (packet->whichmessage) { + case TEXTE: /* damage used as tmp var */ + damage = (unsigned char) packet->argument; + damage |= (unsigned char) packet->argument2 << 8; + if (damage >= 0 && damage < NUMWTEXTS) + warning(w_texts[damage]); + break; + case PHASER_HIT_TEXT: + target = &players[(unsigned char) packet->argument & 0x3f]; + damage = (unsigned char) packet->argument2; + if ((unsigned char) packet->argument & 64) + damage |= 256; + if ((unsigned char) packet->argument & 128) + damage |= 512; + (void) sprintf(buf, "Phaser burst hit %s for %d points", target->p_name, damage); + warning(buf); + break; + case BOMB_INEFFECTIVE: + sprintf(buf, "Weapons Officer: Bombing is ineffective. Only %d armies are defending.", + (int) packet->argument); /* nifty info feature 2/14/92 + TMC */ + warning(buf); + break; + case BOMB_TEXT: + sprintf(buf, "Weapons Officer: Bombarding %s... Sensors read %d armies left.", + planets[(unsigned char) packet->argument].pl_name, + (unsigned char) packet->argument2); + warning(buf); + break; + case BEAMUP_TEXT: + sprintf(buf, "%s: Too few armies to beam up", + planets[(unsigned char) packet->argument].pl_name); + warning(buf); + break; + case BEAMUP2_TEXT: + sprintf(buf, "Beaming up. (%d/%d)", (unsigned char) packet->argument, (unsigned char) packet->argument2); + warning(buf); + break; + case BEAMUPSTARBASE_TEXT: + sprintf(buf, "Starbase %s: Too few armies to beam up", + players[packet->argument].p_name); + warning(buf); + break; + case BEAMDOWNSTARBASE_TEXT: + sprintf(buf, "No more armies to beam down to Starbase %s.", + players[packet->argument].p_name); + warning(buf); + + break; + case BEAMDOWNPLANET_TEXT: + sprintf(buf, "No more armies to beam down to %s.", + planets[(unsigned char) packet->argument].pl_name); + warning(buf); + break; + case SBREPORT: + sprintf(buf, "Transporter Room: Starbase %s reports all troop bunkers are full!", + players[packet->argument].p_name); + warning(buf); + break; + case ONEARG_TEXT: + if (packet->argument >= 0 && packet->argument < NUMVARITEXTS) { + sprintf(buf, vari_texts[packet->argument], (unsigned char) packet->argument2); + warning(buf); + } + break; + case BEAM_D_PLANET_TEXT: + sprintf(buf, "Beaming down. (%d/%d) %s has %d armies left", + arg3, + arg4, + planets[(unsigned char) packet->argument].pl_name, + packet->argument2); + warning(buf); + break; + case ARGUMENTS: + arg3 = (unsigned char) packet->argument; + arg4 = (unsigned char) packet->argument2; + break; + case BEAM_U_TEXT: + sprintf(buf, "Transfering ground units. (%d/%d) Starbase %s has %d armies left", + (unsigned char) arg3, (unsigned char) arg4, players[packet->argument].p_name, (unsigned char) packet->argument2); + warning(buf); + break; + case LOCKPLANET_TEXT: + sprintf(buf, "Locking onto %s", planets[(unsigned char) packet->argument].pl_name); + warning(buf); + break; + case SBRANK_TEXT: + sprintf(buf, "You need a rank of %s or higher to command a starbase!", ranks[packet->argument].name); + warning(buf); + break; + case SBDOCKREFUSE_TEXT: + sprintf(buf, "Starbase %s refusing us docking permission captain.", + players[packet->argument].p_name); + warning(buf); + break; + case SBDOCKDENIED_TEXT: + sprintf(buf, "Starbase %s: Permission to dock denied, all ports currently occupied.", players[packet->argument].p_name); + warning(buf); + break; + case SBLOCKSTRANGER: + sprintf(buf, "Locking onto %s (%c%c)", + players[packet->argument].p_name, + TEAM_LETTER(players[packet->argument]), + shipnos[players[packet->argument].p_no]); + warning(buf); + break; + case SBLOCKMYTEAM: + sprintf(buf, "Locking onto %s (%c%c) (docking is %s)", + players[packet->argument].p_name, + TEAM_LETTER(players[packet->argument]), + shipnos[players[packet->argument].p_no], + (players[packet->argument].p_flags & PFDOCKOK) ? "enabled" : "disabled"); + warning(buf); + break; + case DMKILL: + { + struct mesg_spacket msg; + int killer, victim, armies; + float kills; + victim = (unsigned char) packet->argument & 0x3f; + killer = (unsigned char) packet->argument2 & 0x3f; + /* that's only a temp */ + damage = (unsigned char) karg3; + damage |= (karg4 & 127) << 8; + kills = damage / 100.0; + if (kills == 0.0) + strcpy(killmess, "NO CREDIT"); + else + sprintf(killmess, "%0.2f", kills); + armies = (((unsigned char) packet->argument >> 6) | ((unsigned char) packet->argument2 & 192) >> 4); + if (karg4 & 128) + armies |= 16; + if (armies == 0) { + (void) sprintf(msg.mesg, "%s%s (%c%c) [%c%c] was kill %s for %s (%c%c) [%c%c]", + (godToAllOnKills ? "GOD->ALL " : ""), + players[victim].p_name, + TEAM_LETTER(players[victim]), + shipnos[victim], + players[victim].p_ship->s_desig[0], + players[victim].p_ship->s_desig[1], + killmess, + players[killer].p_name, + TEAM_LETTER(players[killer]), + shipnos[killer], + players[killer].p_ship->s_desig[0], + players[killer].p_ship->s_desig[1]); + msg.m_flags = MALL | MVALID | MKILL; + } else { +#ifdef SOUND /* was feeling a little silly :-) */ + if (killer == me->p_no || alwaysSoundDoosh) + S_PlaySound(S_DOOSH); +#endif + (void) sprintf(msg.mesg, "%s%s (%c%c+%d armies) [%c%c]: kill %s for %s (%c%c) [%c%c]", + (godToAllOnKills ? "GOD->ALL " : ""), + players[victim].p_name, + TEAM_LETTER(players[victim]), + shipnos[victim], + armies, + players[victim].p_ship->s_desig[0], + players[victim].p_ship->s_desig[1], + killmess, + players[killer].p_name, + TEAM_LETTER(players[killer]), + shipnos[killer], + players[killer].p_ship->s_desig[0], + players[killer].p_ship->s_desig[1]); + msg.m_flags = MALL | MVALID | MKILLA; + } + if (why_dead) { + add_whydead(msg.mesg, karg5); + karg5 = 0; + } + msg.type = SP_MESSAGE; + msg.mesg[79] = '\0'; + msg.m_recpt = 0; + msg.m_from = 255; + handleMessage(&msg); + } + break; + case KILLARGS: + karg3 = (unsigned char) packet->argument; + karg4 = (unsigned char) packet->argument2; + break; + case KILLARGS2: + karg5 = (unsigned char) packet->argument; + break; + case DMKILLP: + { + struct mesg_spacket msg; + (void) sprintf(msg.mesg, "%s%s (%c%c) [%c%c] killed by %s (%c)", + (godToAllOnKills ? "GOD->ALL " : ""), + players[packet->argument].p_name, + TEAM_LETTER(players[packet->argument]), + shipnos[packet->argument], + players[packet->argument].p_ship->s_desig[0], + players[packet->argument].p_ship->s_desig[1], + planets[(unsigned char) packet->argument2].pl_name, + TEAM_LETTERP(planets[(unsigned char) packet->argument2])); + if (why_dead) { + add_whydead(msg.mesg, karg5); + karg5 = 0; + } + msg.type = SP_MESSAGE; + msg.mesg[79] = '\0'; + msg.m_flags = MALL | MVALID | MKILLP; + msg.m_recpt = 0; + msg.m_from = 255; + handleMessage(&msg); + } + break; + case DMBOMB: + { + struct mesg_spacket msg; + char buf1[80]; + (void) sprintf(buf, "%-3s->%-3s", planets[(unsigned char) packet->argument2].pl_name, TEAM_SHORTP(planets[(unsigned char) packet->argument2])); + (void) sprintf(buf1, "We are being attacked by %s %c%c who is %d%% damaged.", + players[packet->argument].p_name, + TEAM_LETTER(players[packet->argument]), + shipnos[packet->argument], + arg3); + (void) sprintf(msg.mesg, "%s %s", buf, buf1); + msg.type = SP_MESSAGE; + msg.mesg[79] = '\0'; + msg.m_flags = MTEAM | MBOMB | MVALID; + msg.m_recpt = planets[(unsigned char) packet->argument2].pl_owner; + msg.m_from = 255; + handleMessage(&msg); + } + break; + case DMDEST: + { + struct mesg_spacket msg; + char buf1[80]; + (void) sprintf(buf, "%s destroyed by %s (%c%c)", + planets[(unsigned char) packet->argument].pl_name, + players[packet->argument2].p_name, + TEAM_LETTER(players[packet->argument2]), + shipnos[(unsigned char) packet->argument2]); + (void) sprintf(buf1, "%-3s->%-3s", + planets[(unsigned char) packet->argument].pl_name, TEAM_SHORTP(planets[(unsigned char) packet->argument])); + (void) sprintf(msg.mesg, "%s %s", buf1, buf); + msg.type = SP_MESSAGE; + msg.mesg[79] = '\0'; + msg.m_flags = MTEAM | MDEST | MVALID; + msg.m_recpt = planets[(unsigned char) packet->argument].pl_owner; + msg.m_from = 255; + handleMessage(&msg); + } + break; + case DMTAKE: + { + struct mesg_spacket msg; + char buf1[80]; + (void) sprintf(buf, "%s taken over by %s (%c%c)", + planets[(unsigned char) packet->argument].pl_name, + players[packet->argument2].p_name, + TEAM_LETTER(players[packet->argument2]), + shipnos[packet->argument2]); + (void) sprintf(buf1, "%-3s->%-3s", + planets[(unsigned char) packet->argument].pl_name, TEAM_SHORT(players[packet->argument2])); + (void) sprintf(msg.mesg, "%s %s", buf1, buf); + msg.type = SP_MESSAGE; + msg.mesg[79] = '\0'; + msg.m_flags = MTEAM | MTAKE | MVALID; + msg.m_recpt = idx_to_mask(players[packet->argument2].p_teami); + msg.m_from = 255; + handleMessage(&msg); + } + break; + case DGHOSTKILL: + { + struct mesg_spacket msg; + ushort damage; + damage = (unsigned char) karg3; + damage |= (unsigned char) (karg4 & 0xff) << 8; + (void) sprintf(msg.mesg, "GOD->ALL %s (%c%c) was kill %0.2f for the GhostBusters", + players[(unsigned char) packet->argument].p_name, TEAM_LETTER(players[(unsigned char) packet->argument]), + shipnos[(unsigned char) packet->argument], + (float) damage / 100.0); + msg.type = SP_MESSAGE; + msg.mesg[79] = '\0'; + msg.m_flags = MALL | MVALID; + msg.m_recpt = 0; + msg.m_from = 255; + handleMessage(&msg); + } + break; +/* INL Daemon Mesages */ + case INLDMKILLP: + { + struct mesg_spacket msg; + *buf = 0; + if (arg3) { /* Armies */ + sprintf(buf, "+%d", arg3); +#ifdef SOUND + if(alwaysSoundDoosh) + S_PlaySound(S_DOOSH); +#endif + } + (void) sprintf(msg.mesg, "%s%s[%s] (%c%c%s) killed by %s (%c)", + (godToAllOnKills ? "GOD->ALL " : ""), + players[(unsigned char) packet->argument].p_name, + ship_type(players[(unsigned char) packet->argument].p_ship), + TEAM_LETTER(players[(unsigned char) packet->argument]), + shipnos[(unsigned char) packet->argument], + buf, + planets[(unsigned char) packet->argument2].pl_name, + TEAM_LETTERP(planets[(unsigned char) packet->argument2])); + if (why_dead) { + add_whydead(msg.mesg, karg5); + karg5 = 0; + } + msg.type = SP_MESSAGE; + msg.mesg[79] = '\0'; + msg.m_flags = MALL | MVALID | MKILLP; + msg.m_recpt = 0; + msg.m_from = 255; + handleMessage(&msg); + } + break; + case INLDMKILL: + { + struct mesg_spacket msg; + int killer, victim, armies; + float kills; + victim = (unsigned char) packet->argument & 0x3f; + killer = (unsigned char) packet->argument2 & 0x3f; + /* that's only a temp */ + damage = (unsigned char) karg3; + damage |= (karg4 & 127) << 8; + kills = damage / 100.0; + armies = (((unsigned char) packet->argument >> 6) | ((unsigned char) packet->argument2 & 192) >> 4); + if (karg4 & 128) + armies |= 16; + if (armies == 0) { + (void) sprintf(msg.mesg, "%s%s[%s] (%c%c) was kill %0.2f for %s[%s] (%c%c)", + (godToAllOnKills ? "GOD->ALL " : ""), + players[victim].p_name, + ship_type(players[victim].p_ship), + TEAM_LETTER(players[victim]), + shipnos[victim], + kills, + players[killer].p_name, + ship_type(players[killer].p_ship), + TEAM_LETTER(players[killer]), + shipnos[killer]); + msg.m_flags = MALL | MVALID | MKILL; + } else { +#ifdef SOUND + if(killer == me->p_no || alwaysSoundDoosh) + S_PlaySound(S_DOOSH); +#endif + (void) sprintf(msg.mesg, "%s%s[%s] (%c%c+%d armies) was kill %0.2f for %s[%s] (%c%c)", + (godToAllOnKills ? "GOD->ALL " : ""), + players[victim].p_name, + ship_type(players[victim].p_ship), + TEAM_LETTER(players[victim]), + shipnos[victim], + armies, + kills, + players[killer].p_name, + ship_type(players[killer].p_ship), + TEAM_LETTER(players[killer]), + shipnos[killer]); + msg.m_flags = MALL | MVALID | MKILLA; + } + if (why_dead) { + add_whydead(msg.mesg, karg5); + karg5 = 0; + } + msg.type = SP_MESSAGE; + msg.mesg[79] = '\0'; + msg.m_recpt = 0; + msg.m_from = 255; + handleMessage(&msg); + } + break; + case INLDRESUME: + { + struct mesg_spacket msg; + sprintf(msg.mesg, " Game will resume in %d seconds", (unsigned char) packet->argument); + msg.m_flags = MALL | MVALID; + msg.type = SP_MESSAGE; + msg.mesg[79] = '\0'; + msg.m_recpt = 0; + msg.m_from = 255; + handleMessage(&msg); + } + break; + case INLDTEXTE: + if (packet->argument >= 0 && (unsigned char) packet->argument < NUMDAEMONTEXTS) { + struct mesg_spacket msg; + strcpy(msg.mesg, daemon_texts[(unsigned char) packet->argument]); + msg.m_flags = MALL | MVALID; + msg.type = SP_MESSAGE; + msg.mesg[79] = '\0'; + msg.m_recpt = 0; + msg.m_from = 255; + handleMessage(&msg); + } + break; + case STEXTE: + warning(s_texte[(unsigned char) packet->argument]); + break; + case SHORT_WARNING: + { + struct warning_spacket *warn = (struct warning_spacket *) packet; + warning(warn->mesg); + } + break; + case STEXTE_STRING: + { + struct warning_spacket *warn = (struct warning_spacket *) packet; + warning(warn->mesg); + s_texte[(unsigned char) warn->pad2] = (char *) malloc(warn->pad3 - 4); + if (s_texte[(unsigned char) warn->pad2] == NULL) { + s_texte[(unsigned char) warn->pad2] = no_memory; + warning("Could not add warning! (No memory!)"); + } else + strcpy(s_texte[(unsigned char) warn->pad2], warn->mesg); + } + break; + default: + warning("Unknown Short Warning!"); + break; + } +} + +#define MY_SIZEOF(a) (sizeof(a) / sizeof(*(a))) + +void +add_whydead(s, m) /* 7/22/93 LAB */ + char *s; + int m; +{ + char b[256]; + + if (m < MY_SIZEOF(whydeadmess)) { + sprintf(b, "%-50s %s", s, whydeadmess[m]); + b[79] = '\0'; + strcpy(s, b); + } +} + +#endif + +/* END SHORT_PACKETS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sintab.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,114 @@ +/* $Id: sintab.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */ + +/* + * sintab.c + * + * Also initialize blk_giwdth to 100000 and blk_windgwidth + * to WINSIDE/blk_gwidth + */ +#include "copyright.h" + +double *Cos; +double Sin[] = { + -1.0000, -0.9997, -0.9988, -0.9973, -0.9952, -0.9925, + -0.9892, -0.9853, -0.9808, -0.9757, -0.9701, -0.9638, + -0.9570, -0.9496, -0.9416, -0.9330, -0.9239, -0.9143, + -0.9040, -0.8933, -0.8820, -0.8701, -0.8578, -0.8449, + -0.8315, -0.8176, -0.8033, -0.7884, -0.7731, -0.7573, + -0.7410, -0.7243, -0.7072, -0.6896, -0.6716, -0.6533, + -0.6345, -0.6153, -0.5958, -0.5759, -0.5557, -0.5351, + -0.5142, -0.4930, -0.4715, -0.4497, -0.4277, -0.4054, + -0.3828, -0.3600, -0.3370, -0.3138, -0.2904, -0.2668, + -0.2431, -0.2192, -0.1952, -0.1711, -0.1469, -0.1225, + -0.0982, -0.0737, -0.0492, -0.0247, /* Cos */ -0.0001, 0.0244, /* 90 */ + 0.0489, 0.0734, 0.0979, 0.1223, 0.1466, 0.1708, + 0.1949, 0.2190, 0.2428, 0.2666, 0.2901, 0.3135, + 0.3367, 0.3598, 0.3825, 0.4051, 0.4274, 0.4495, + 0.4713, 0.4928, 0.5140, 0.5349, 0.5554, 0.5757, + 0.5956, 0.6151, 0.6343, 0.6531, 0.6714, 0.6894, + 0.7070, 0.7241, 0.7408, 0.7571, 0.7729, 0.7882, + 0.8031, 0.8175, 0.8314, 0.8448, 0.8576, 0.8700, + 0.8818, 0.8931, 0.9039, 0.9141, 0.9238, 0.9329, + 0.9415, 0.9495, 0.9569, 0.9637, 0.9700, 0.9757, + 0.9808, 0.9852, 0.9891, 0.9925, 0.9952, 0.9973, + 0.9988, 0.9997, 1.0000, 0.9997, 0.9988, 0.9973, /* 180 */ + 0.9952, 0.9925, 0.9892, 0.9853, 0.9808, 0.9757, + 0.9700, 0.9638, 0.9569, 0.9495, 0.9415, 0.9330, + 0.9239, 0.9142, 0.9040, 0.8932, 0.8819, 0.8701, + 0.8577, 0.8449, 0.8315, 0.8176, 0.8032, 0.7884, + 0.7730, 0.7572, 0.7410, 0.7243, 0.7071, 0.6896, + 0.6716, 0.6532, 0.6344, 0.6153, 0.5957, 0.5758, + 0.5556, 0.5350, 0.5141, 0.4929, 0.4714, 0.4496, + 0.4276, 0.4053, 0.3827, 0.3599, 0.3369, 0.3137, + 0.2903, 0.2667, 0.2430, 0.2191, 0.1951, 0.1710, + 0.1468, 0.1225, 0.0981, 0.0736, 0.0491, 0.0246, + 0.0000, -0.0245, -0.0490, -0.0735, -0.0980, -0.1224, /* 270 */ + -0.1467, -0.1709, -0.1950, -0.2190, -0.2429, -0.2667, + -0.2902, -0.3136, -0.3368, -0.3598, -0.3826, -0.4052, + -0.4275, -0.4496, -0.4713, -0.4928, -0.5140, -0.5349, + -0.5555, -0.5758, -0.5956, -0.6152, -0.6343, -0.6531, + -0.6715, -0.6895, -0.7071, -0.7242, -0.7409, -0.7572, + -0.7730, -0.7883, -0.8032, -0.8175, -0.8314, -0.8448, + -0.8577, -0.8700, -0.8819, -0.8932, -0.9040, -0.9142, + -0.9238, -0.9330, -0.9415, -0.9495, -0.9569, -0.9638, + -0.9700, -0.9757, -0.9808, -0.9853, -0.9892, -0.9925, + -0.9952, -0.9973, -0.9988, -0.9997, /* }; */ +/* +double Cos[] = { + 0.0000, 0.0245, 0.0491, 0.0736, 0.0980, 0.1224, + 0.1467, 0.1710, 0.1951, 0.2191, 0.2430, 0.2667, + 0.2903, 0.3137, 0.3369, 0.3599, 0.3827, 0.4052, + 0.4275, 0.4496, 0.4714, 0.4929, 0.5141, 0.5350, + 0.5556, 0.5758, 0.5957, 0.6152, 0.6344, 0.6532, + 0.6715, 0.6895, 0.7071, 0.7242, 0.7409, 0.7572, + 0.7730, 0.7883, 0.8032, 0.8176, 0.8315, 0.8448, + 0.8577, 0.8701, 0.8819, 0.8932, 0.9040, 0.9142, + 0.9239, 0.9330, 0.9415, 0.9495, 0.9569, 0.9638, + 0.9700, 0.9757, 0.9808, 0.9853, 0.9892, 0.9925, + 0.9952, 0.9973, 0.9988, 0.9997, 1.0000, 0.9997, + 0.9988, 0.9973, 0.9952, 0.9925, 0.9892, 0.9853, + 0.9808, 0.9757, 0.9700, 0.9638, 0.9570, 0.9495, + 0.9416, 0.9330, 0.9239, 0.9142, 0.9040, 0.8933, + 0.8819, 0.8701, 0.8578, 0.8449, 0.8315, 0.8176, + 0.8032, 0.7884, 0.7731, 0.7573, 0.7410, 0.7243, + 0.7072, 0.6896, 0.6716, 0.6532, 0.6344, 0.6153, + 0.5958, 0.5759, 0.5556, 0.5351, 0.5142, 0.4930, + 0.4715, 0.4497, 0.4276, 0.4053, 0.3828, 0.3600, + 0.3370, 0.3138, 0.2904, 0.2668, 0.2431, 0.2192, + 0.1952, 0.1710, 0.1468, 0.1225, 0.0981, 0.0737, + 0.0492, 0.0246, 0.0001, -0.0244, -0.0490, -0.0735, + -0.0979, -0.1223, -0.1466, -0.1709, -0.1950, -0.2190, + -0.2429, -0.2666, -0.2902, -0.3136, -0.3368, -0.3598, + -0.3826, -0.4051, -0.4275, -0.4495, -0.4713, -0.4928, + -0.5140, -0.5349, -0.5555, -0.5757, -0.5956, -0.6151, + -0.6343, -0.6531, -0.6715, -0.6895, -0.7070, -0.7242, + -0.7409, -0.7571, -0.7729, -0.7883, -0.8031, -0.8175, + -0.8314, -0.8448, -0.8577, -0.8700, -0.8819, -0.8932, + -0.9039, -0.9142, -0.9238, -0.9329, -0.9415, -0.9495, + -0.9569, -0.9637, -0.9700, -0.9757, -0.9808, -0.9853, + -0.9892, -0.9925, -0.9952, -0.9973, -0.9988, -0.9997, +*/ + + -1.0000, -0.9997, -0.9988, -0.9973, -0.9952, -0.9925, + -0.9892, -0.9853, -0.9808, -0.9757, -0.9701, -0.9638, + -0.9570, -0.9496, -0.9416, -0.9330, -0.9239, -0.9143, + -0.9041, -0.8933, -0.8820, -0.8702, -0.8578, -0.8449, + -0.8316, -0.8177, -0.8033, -0.7884, -0.7731, -0.7573, + -0.7411, -0.7244, -0.7072, -0.6897, -0.6717, -0.6533, + -0.6345, -0.6154, -0.5958, -0.5759, -0.5557, -0.5351, + -0.5142, -0.4930, -0.4715, -0.4498, -0.4277, -0.4054, + -0.3828, -0.3601, -0.3371, -0.3138, -0.2905, -0.2669, + -0.2432, -0.2193, -0.1953, -0.1711, -0.1469, -0.1226, +-0.0982, -0.0737, -0.0493, -0.0247}; + +#define WINSIDE 500 +extern int blk_gwidth; +extern float blk_windgwidth; + +void +inittrigtables() +{ + Cos = Sin + 64; + blk_gwidth = 100000; + blk_windgwidth = ((float) WINSIDE) / blk_gwidth; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/smessage.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,728 @@ +/* $Id: smessage.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */ + +/* + * smessage.c + */ +#include "copyright.h" + +#include <stdio.h> +#include <math.h> +#include <signal.h> +#include <string.h> +#include <ctype.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "proto.h" +#include "gameconf.h" + +#define ADDRLEN 10 +#define M_XOFF 5 +#ifndef AMIGA +#define M_YOFF 5 +#else +#define M_YOFF 1 +#endif + +#define MSGLEN 80 + +/* XFIX */ +#define BLANKCHAR(col, n) W_ClearArea(messagew, M_XOFF+W_Textwidth*(col), \ + M_YOFF, W_Textwidth * (n), W_Textheight); +#define DRAWCURSOR(col) W_WriteText(messagew, M_XOFF+W_Textwidth*(col), \ + M_YOFF, textColor, &cursor, 1, W_RegularFont); + +static int lcount; +static char buf[MSGLEN]; +static char cursor = '_'; + +char addr, *addr_str; + +/* Prototypes */ +static void smessage_first P((int ichar)); + /*static*/ char *getaddr P((int who)); + /*static*/ char *getaddr2 P((int flags, int recip)); + +void +message_expose() +{ + if (!messpend) + return; + + W_WriteText(messagew, M_XOFF, M_YOFF, textColor, addr_str, + strlen(addr_str), W_RegularFont); + W_WriteText(messagew, M_XOFF + ADDRLEN * W_Textwidth, M_YOFF, textColor, + buf, lcount - ADDRLEN, W_RegularFont); + DRAWCURSOR(lcount); +} + +void +smessage_ahead(head, ichar) + char head; + char ichar; +{ + if (messpend == 0) { + smessage_first(head); + } + smessage(ichar); +} + +static void +smessage_first(ichar) + char ichar; +{ + messpend = 1; + + /* clear out message window in case messages went there */ + W_ClearWindow(messagew); + if (mdisplayed) { + BLANKCHAR(0, lastcount); + mdisplayed = 0; + } + /* Put the proper recipient in the window */ + if (/*(ichar == 't') || */ + /* that's a player number! */ + /* YUCK! */ + (ichar == 'T')) + addr = teaminfo[me->p_teami].letter; + else + addr = ichar; + addr_str = getaddr(addr); + if (addr_str == 0) { + /* print error message */ + messpend = 0; +#ifdef NOWARP + message_off(); +#else + W_WarpPointer(NULL); +#endif + } else { + W_WriteText(messagew, M_XOFF, M_YOFF, textColor, addr_str, + strlen(addr_str), W_RegularFont); + lcount = ADDRLEN; + DRAWCURSOR(ADDRLEN); + } +} + +void +smessage(ichar) + int ichar; +{ + register int i; + char twochar[2], *delim; + + if (messpend == 0) { + if(lowercaset && ichar == 't') + ichar='T'; + else if(lowercaset && (ichar == 'T')) + ichar='t'; + smessage_first(ichar); + return; + } + switch (ichar) { + case '\b': /* character erase */ + case '\177': + if (--lcount < ADDRLEN) { + lcount = ADDRLEN; + break; + } + BLANKCHAR(lcount + 1, 1); + DRAWCURSOR(lcount); + break; + + case 'w'+256: /* word erase */ + i = 0; + /* back up over blanks */ + while (--lcount >= ADDRLEN && + isspace((unsigned char) buf[lcount - ADDRLEN] & ~(0x80))) + i++; + lcount++; + /* back up over non-blanks */ + while (--lcount >= ADDRLEN && + !isspace((unsigned char) buf[lcount - ADDRLEN] & ~(0x80))) + i++; + lcount++; + + if (i > 0) { + BLANKCHAR(lcount, i + 1); + DRAWCURSOR(lcount); + } + break; + + case 'u'+256: /* kill line */ + case 'x'+256: + if (lcount > ADDRLEN) { + BLANKCHAR(ADDRLEN, lcount - ADDRLEN + 1); + lcount = ADDRLEN; + DRAWCURSOR(ADDRLEN); + } + break; + + case '\033': /* abort message */ + BLANKCHAR(0, lcount + 1); + mdisplayed = 0; + messpend = 0; +#ifdef NOWARP + message_off(); +#else + W_WarpPointer(NULL); +#endif + break; + + case '\r': /* send message */ + buf[lcount - ADDRLEN] = '\0'; + messpend = 0; + sendCharMessage(buf, addr); + BLANKCHAR(0, lcount + 1); + mdisplayed = 0; + lcount = 0; + break; + + default: /* add character */ + if (lcount >= 79) { /* send mesg and continue mesg */ + if (addr == 'M') + if ((delim = strchr(buf, '>') + 1) == NULL) { + W_Beep(); + break; + } + else { + i = delim - buf; + buf[lcount - ADDRLEN + 1] = '\0'; + sendCharMessage(buf, addr); + memset(delim, '\0', sizeof(buf) - i); + BLANKCHAR(i, lcount + 1); + W_WriteText(messagew, M_XOFF, M_YOFF, textColor, + addr_str, strlen(addr_str), W_RegularFont); + W_WriteText(messagew, M_XOFF+(strlen(addr_str) + + 1) * W_Textwidth, + M_YOFF, textColor, buf, strlen(buf), W_RegularFont); + lcount = i + ADDRLEN; + DRAWCURSOR(i + ADDRLEN); + } + else { + buf[lcount - ADDRLEN + 1] = '\0'; + sendCharMessage(buf, addr); + BLANKCHAR(0, lcount + 1); + W_WriteText(messagew, M_XOFF, M_YOFF, textColor, addr_str, + strlen(addr_str), W_RegularFont); + lcount = ADDRLEN; + DRAWCURSOR(ADDRLEN); + } + } + if (ichar > 255) + break; + twochar[0] = ichar; + twochar[1] = cursor; + W_WriteText(messagew, M_XOFF + W_Textwidth * lcount, M_YOFF, + textColor, twochar, 2, W_RegularFont); + buf[(lcount++) - ADDRLEN] = ichar; + break; + } +} + +void +sendCharMessage(buf, ch) + char *buf; + int ch; +{ + char tmp[MSGLEN], *delim; + int i, count; + +/* uses ch to find out what kind of message it is and then sends + it there */ + switch ((char) ch) { + case 'A': + pmessage(buf, 0, MALL); + break; + case 'F': + pmessage(buf, FEDm, MTEAM); + break; + case 'R': + pmessage(buf, ROMm, MTEAM); + break; + case 'K': + pmessage(buf, KLIm, MTEAM); + break; + case 'O': + pmessage(buf, ORIm, MTEAM); + break; + case 'G': + pmessage(buf, 0, MGOD); + break; +#ifdef TOOLS + case '!': + pmessage(buf, 0, MTOOLS); + break; +#endif + case 'T': + pmessage(buf, idx_to_mask(me->p_teami), MTEAM); + break; + case 'M': + /* mcast format: hit M and list of target addresses followed */ + /* by greater than(>) and message. the entire mesg including */ + /* addresses will be sent to each address */ + if((delim = strchr(buf, '>')) != NULL) { + count = delim - buf; /* number of addresses */ + strncpy(tmp, buf, count); + if(strchr(tmp, ' ') == NULL) + for(i=0; i < count; i++) { /* dont do tmp[0] is M */ + sendCharMessage(buf, tmp[i]); + } + } + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + pmessage(buf, ch - '0', MINDIV); + break; + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': + pmessage(buf, ch - 'a' + 10, MINDIV); + break; + default: + { + int i; + for (i = 0; i < number_of_teams; i++) { + if (ch == teaminfo[i].letter) + break; + } + if (i < number_of_teams) { + pmessage(buf, idx_to_mask(i), MTEAM); + break; + } + } + warning("Not legal recipient"); + } +} + +void +pmessage(str, recip, group) + char *str; + int recip; + int group; +{ + char newbuf[100]; + + strcpy(lastMessage, str); + switch(group) { +#ifdef TOOLS + case MTOOLS: + sendTools(str); + break; +#endif + default: + sendMessage(str, group, recip); + } + if ((group == MTEAM && recip != idx_to_mask(me->p_teami)) || + (group == MINDIV && recip != me->p_no)) { + sprintf(newbuf, "%s %s", + getaddr2(group, (group == MTEAM) ? + mask_to_idx(recip) : recip), + str); + newbuf[79] = 0; + dmessage(newbuf, group, me->p_no, recip); + } +#ifdef NOWARP + message_off(); +#else + W_WarpPointer(NULL); +#endif +} + +/*static */ +char * +getaddr(who) + char who; +{ + switch (who) { + case 'A': + return (getaddr2(MALL, 0)); + case 'F': + return (getaddr2(MTEAM, FEDi)); + case 'R': + return (getaddr2(MTEAM, ROMi)); + case 'K': + return (getaddr2(MTEAM, KLIi)); + case 'O': + return (getaddr2(MTEAM, ORIi)); + case 'G': + return (getaddr2(MGOD, 0)); +#ifdef TOOLS + case '!': + return (getaddr2(MTOOLS, 0)); +#endif + case 'M': + return (getaddr2(MCAST, 0));; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (isPlaying(&players[who - '0'])) { + return (getaddr2(MINDIV, who - '0')); + } else { + warning("Player is not in game"); + return (0); + } + break; + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': + if (who - 'a' + 10 > nplayers) { + warning("Invalid player number"); + return (0); + } else if (isPlaying(&players[who - 'a' + 10])) { + return (getaddr2(MINDIV, who - 'a' + 10)); + } else { + warning("Player is not in game"); + return (0); + } + break; + default: + { + int i; + for (i = 0; i < number_of_teams; i++) { + if (addr == teaminfo[i].letter) + break; + } + if (i < number_of_teams) { + return getaddr2(MTEAM, i); + } + } + warning("Not legal recipient"); + return (0); + } +} + +/*static*/ +char * +getaddr2(flags, recip) + int flags; + int recip; +{ + static char addrmesg[ADDRLEN]; + + (void) sprintf(addrmesg, " %c%c->", teaminfo[me->p_teami].letter, shipnos[me->p_no]); + switch (flags) { + case MALL: + (void) sprintf(&addrmesg[5], "ALL"); + break; + case MTEAM: + (void) sprintf(&addrmesg[5], teaminfo[recip].shortname); + break; + case MINDIV: + (void) sprintf(&addrmesg[5], "%c%c ", + teaminfo[players[recip].p_teami].letter, shipnos[recip]); + break; + case MGOD: + (void) sprintf(&addrmesg[5], "GOD"); + break; +#ifdef TOOLS + case MTOOLS: + (void) sprintf(addrmesg, " Shell>"); + break; +#endif + case MCAST: + (void) sprintf(&addrmesg[5], "MCAS"); + } + + return (addrmesg); +} + +/* Used in NEWMACRO, useful elsewhere also */ +int +getgroup(addr, recip) + char addr; + int *recip; +{ + *recip = 0; + + switch (addr) { + case 'A': + *recip = 0; + return (MALL); + break; + case 'T': /* had to add this...why didn't COW-lite need + it?? -JR */ + *recip = idx_to_mask(me->p_teami); + return (MTEAM); + break; + case 'F': + *recip = FEDm; + return (MTEAM); + break; + case 'R': + *recip = ROMm; + return (MTEAM); + break; + case 'K': + *recip = KLIm; + return (MTEAM); + break; + case 'O': + *recip = ORIm; + return (MTEAM); + break; + case 'G': + *recip = 0; + return (MGOD); + break; +#ifdef TOOLS + case '!': + *recip = 0; + return (MTOOLS); + break; +#endif + case 'M': + *recip = 0; + return (MMOO); + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (players[addr - '0'].p_status == PFREE) { + warning("That player left the game. message not sent."); + return 0; + } + *recip = addr - '0'; + return (MINDIV); + break; + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': + if (players[addr - 'a' + 10].p_status == PFREE) { + warning("That player left the game. message not sent."); + return 0; + } + *recip = addr - 'a' + 10; + return (MINDIV); + break; + default: + warning("Not legal recipient"); + } + return 0; +} + + + + + +/*-------------------------------EMERGENCY--------------------------------*/ +/* This function sends a distress message out to the player's team. */ +void +emergency() +{ + char ebuf[120]; /* to sprintf into */ + char buf2[20]; + + sprintf(ebuf, "Distress %c%c", /* get team and end */ + teaminfo[me->p_teami].letter, shipnos[me->p_no]); + switch (myship->s_type) { + case STARBASE: + strcat(ebuf, " (Starbase): "); + break; + case WARBASE: + strcat(ebuf, " (Warbase): "); + break; + case JUMPSHIP: + strcat(ebuf, " (Jumpship): "); + break; + default: + strcat(ebuf, ": "); + } + if (me->p_damage != 0) { + if (me->p_damage > me->p_ship->s_maxdamage - 30) + sprintf(buf2, "DEAD MAN "); + else + sprintf(buf2, "damg: %d%% ", (100 * me->p_damage) / me->p_ship->s_maxdamage); + strcat(ebuf, buf2); + } + if (me->p_shield < me->p_ship->s_maxshield) { + if (me->p_shield < 5) + sprintf(buf2, "NO SHIELDS "); + else + sprintf(buf2, "shld: %d%% ", (100 * me->p_shield) / me->p_ship->s_maxshield); + strcat(ebuf, buf2); + } + if (me->p_wtemp > 0) { + if (me->p_flags & PFWEP) + sprintf(buf2, "WTEMP "); + else + sprintf(buf2, "W %d%% ", (100 * me->p_wtemp) / me->p_ship->s_maxwpntemp); + strcat(ebuf, buf2); + } + if (me->p_etemp > 0) { + if (me->p_flags & PFENG) + sprintf(buf2, "ETEMP "); + else + sprintf(buf2, "E %d%% ", (100 * me->p_etemp) / me->p_ship->s_maxegntemp); + strcat(ebuf, buf2); + } + if (me->p_fuel < me->p_ship->s_maxfuel) { + if (me->p_fuel < 400) + sprintf(buf2, "NO FUEL "); + else + sprintf(buf2, "F %d%% ", (100 * me->p_fuel) / me->p_ship->s_maxfuel); + strcat(ebuf, buf2); + } + if ((int) strlen(ebuf) < 12) + strcat(ebuf, " perfect health "); + if (me->p_armies > 0) { + sprintf(buf2, "%d ARMIES!", me->p_armies); + strcat(ebuf, buf2); + } + pmessage(ebuf, idx_to_mask(me->p_teami), MTEAM); +} + + + +void +carry_report() +{ + char ebuf[MSGLEN], *pntr; + double dist, closedist; + struct planet *k, *p = NULL; + + closedist = blk_gwidth; + + for (k = &planets[0]; k < &planets[nplanets]; k++) { + dist = hypot((double) (me->p_x - k->pl_x), + (double) (me->p_y - k->pl_y)); + if (dist < closedist) { + p = k; + closedist = dist; + } + } + if (myship->s_type == STARBASE) + sprintf(ebuf, "Your Starbase is carrying %d armies. ", me->p_armies); + else + sprintf(ebuf, "I am carrying %d armies. ", me->p_armies); + for (pntr = ebuf; *pntr; pntr++); + if (paradise) { + sprintf(pntr, "Sector: %d-%d ", (me->p_x / GRIDSIZE) + 1, + (me->p_y / GRIDSIZE) + 1); + for (; *pntr; pntr++); + } + sprintf(pntr, "%sear %s", (me->p_flags & PFCLOAK) ? "Cloaked n" : "N", + p->pl_name); + pmessage(ebuf, idx_to_mask(me->p_teami), MTEAM); +} + +#ifdef NOWARP +void +message_on() +{ + if (warp) { + W_WarpPointer(messagew); + } +#ifdef TCURSORS + else { + messageon = 1; + W_DefineTextCursor(w); + W_DefineTextCursor(mapw); + } +#endif /* TCURSORS */ +} + +void +message_off() +{ +#ifdef TCURSORS + if (!warp) { + messageon = 0; + W_RevertCursor(w); + W_RevertCursor(mapw); + } +#endif /* TCURSORS */ +} +#endif /* NOWARP */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/socket.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,3380 @@ +/* $Id: socket.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */ + +/* + * Socket.c + * + * Kevin P. Smith 1/29/89 + * UDP stuff v1.0 by Andy McFadden Feb-Apr 1992 + * + * UDP protocol v1.0 + * + * Routines to allow connection to the xtrek server. + */ +#include "copyright2.h" + +/* to see the packets sent/received: [BDyess] */ +#if 0 +#define SHOW_SEND +#define SHOW_RECEIVED +#endif /* 0 */ + +#ifndef GATEWAY +#define USE_PORTSWAP /* instead of using recvfrom() */ +#endif + +#undef USE_PORTSWAP /* recvfrom is a better scheme */ + +#include <stdio.h> +#ifdef __STDC__ +#include <stdlib.h> +#endif +#include <sys/types.h> +#include <sys/time.h> +#ifdef RS6K +#include <sys/select.h> +#endif +#ifndef DNET +#include <sys/socket.h> +#include <netinet/in.h> +#include <netinet/tcp.h> +#include <netdb.h> +#else +#include <devices/timer.h> +#include <dos/dos.h> +#endif /* DNET */ +#include <math.h> +#include <errno.h> +#include <zlib.h> /* for terrain info */ +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "packets.h" +#include "proto.h" +#include "gameconf.h" +#ifdef SOUND +#include "Slib.h" +#endif /* SOUND */ +#include "sound.h" + +#define INCLUDE_SCAN /* include Amdahl scanning beams */ +#define INCLUDE_VISTRACT /* include visible tractor beams */ + +#ifdef GATEWAY +/* + * (these values are now defined in "main.c":) + * char *gw_mach = "charon"; |client gateway; strcmp(serverName) + * int gw_serv_port = 5000; |what to tell the server to use + * int gw_port = 5001; |where we will contact gw + * int gw_local_port = 5100; |where we expect gw to contact us + * + * The client binds to "5100" and sends "5000" to the server (TCP). The + * server sees that and sends a UDP packet to gw on port udp5000, which passes + * it through to port udp5100 on the client. The client-gw gets the server's + * host and port from recvfrom. (The client can't use the same method since + * these sockets are one-way only, so it connect()s to gw_port (udp5001) + * on the gateway machine regardless of what the server sends.) + * + * So all we need in .gwrc is: + * udp 5000 5001 tde.uts 5100 + * + * assuming the client is on tde.uts. Note that a UDP declaration will + * work for ANY server, but you need one per player, and the client has to + * have the port numbers in advance. + * + * If we're using a standard server, we're set. If we're running through a + * gatewayed server, we have to do some unpleasant work on the server side... + */ +#endif + +#ifdef SIZE_LOGGING +int send_total = 0; +int receive_total = 0; +#endif /* SIZE_LOGGING */ + +/* Prototypes */ +static void resetForce P((void)); +static void checkForce P((void)); +#ifdef nodef +static void set_tcp_opts P((int s)); +static void set_udp_opts P((int s)); +#endif /* nodef */ +static int doRead P((int asock)); +static void handleTorp P((struct torp_spacket * packet)); +static void handleTorpInfo P((struct torp_info_spacket * packet)); +static void handleStatus P((struct status_spacket * packet)); +static void handleSelf P((struct you_spacket * packet)); +static void handlePlayer P((struct player_spacket * packet)); +static void handleWarning P((struct warning_spacket * packet)); +void sendServerPacket P((struct player_spacket * packet)); +static void handlePlanet P((struct planet_spacket * packet)); +static void handlePhaser P((struct phaser_spacket * packet)); +void handleMessage P((struct mesg_spacket * packet)); +static void handleQueue P((struct queue_spacket * packet)); +static void handlePickok P((struct pickok_spacket * packet)); +static void handleLogin P((struct login_spacket * packet)); +static void handlePlasmaInfo P((struct plasma_info_spacket * packet)); +static void handlePlasma P((struct plasma_spacket * packet)); +static void handleFlags P((struct flags_spacket * packet)); +static void handleKills P((struct kills_spacket * packet)); +static void handlePStatus P((struct pstatus_spacket * packet)); +static void handleMotd P((struct motd_spacket * packet)); +static void handleMask P((struct mask_spacket * packet)); +static void pickSocket P((int old)); +static void handleBadVersion P((struct badversion_spacket * packet)); +int gwrite P((int fd, char *buf, int bytes)); +static void handleHostile P((struct hostile_spacket * packet)); +static void handlePlyrLogin P((struct plyr_login_spacket * packet)); +static void handleStats P((struct stats_spacket * packet)); +static void handlePlyrInfo P((struct plyr_info_spacket * packet)); +static void handlePlanetLoc P((struct planet_loc_spacket * packet)); +static void handleReserved P((struct reserved_spacket * packet)); + +static void handleScan P((struct scan_spacket * packet)); +static void handleSequence P((struct sequence_spacket * packet)); +static void handleUdpReply P((struct udp_reply_spacket * packet)); +static void informScan P((int p)); +static int openUdpConn P((void)); +#ifdef USE_PORTSWAP +static int connUdpConn P((void)); +#endif +static int recvUdpConn P((void)); +static void printUdpInfo P((void)); +/*static void dumpShip P((struct ship *shipp ));*/ +/*static int swapl P((int in ));*/ +static void handleShipCap P((struct ship_cap_spacket * packet)); +static void handleMotdPic P((struct motd_pic_spacket * packet)); +static void handleStats2 P((struct stats_spacket2 * packet)); +static void handleStatus2 P((struct status_spacket2 * packet)); +static void handlePlanet2 P((struct planet_spacket2 * packet)); +static void handleTerrain2 P((struct terrain_packet2 * pkt)); +static void handleTerrainInfo2 P((struct terrain_info_packet2 *pkt)); +static void handleTempPack P((struct obvious_packet * packet)); +static void handleThingy P((struct thingy_spacket * packet)); +static void handleThingyInfo P((struct thingy_info_spacket * packet)); +static void handleRSAKey P((struct rsa_key_spacket * packet)); +void handlePing(); +static void handleExtension1 P((struct paradiseext1_spacket *)); + +static void handleEmpty(); + + +#ifdef SHORT_PACKETS +void handleShortReply(), handleVPlayer(), handleVTorp(), + handleSelfShort(), handleSelfShip(), handleVPlanet(), handleSWarning(); +void handleVTorpInfo(), handleSMessage(); +#endif + +#ifdef FEATURE +void handleFeature(); /* feature.c */ +#endif + +struct packet_handler handlers[] = { + {NULL}, /* record 0 */ + {handleMessage}, /* SP_MESSAGE */ + {handlePlyrInfo}, /* SP_PLAYER_INFO */ + {handleKills}, /* SP_KILLS */ + {handlePlayer}, /* SP_PLAYER */ + {handleTorpInfo}, /* SP_TORP_INFO */ + {handleTorp}, /* SP_TORP */ + {handlePhaser}, /* SP_PHASER */ + {handlePlasmaInfo}, /* SP_PLASMA_INFO */ + {handlePlasma}, /* SP_PLASMA */ + {handleWarning}, /* SP_WARNING */ + {handleMotd}, /* SP_MOTD */ + {handleSelf}, /* SP_YOU */ + {handleQueue}, /* SP_QUEUE */ + {handleStatus}, /* SP_STATUS */ + {handlePlanet}, /* SP_PLANET */ + {handlePickok}, /* SP_PICKOK */ + {handleLogin}, /* SP_LOGIN */ + {handleFlags}, /* SP_FLAGS */ + {handleMask}, /* SP_MASK */ + {handlePStatus}, /* SP_PSTATUS */ + {handleBadVersion}, /* SP_BADVERSION */ + {handleHostile}, /* SP_HOSTILE */ + {handleStats}, /* SP_STATS */ + {handlePlyrLogin}, /* SP_PL_LOGIN */ + {handleReserved}, /* SP_RESERVED */ + {handlePlanetLoc}, /* SP_PLANET_LOC */ + {handleScan}, /* SP_SCAN (ATM) */ + {handleUdpReply}, /* SP_UDP_STAT */ + {handleSequence}, /* SP_SEQUENCE */ + {handleSequence}, /* SP_SC_SEQUENCE */ + {handleRSAKey}, /* SP_RSA_KEY */ + {handleMotdPic}, /* SP_MOTD_PIC */ + {handleStats2}, /* SP_STATS2 */ + {handleStatus2}, /* SP_STATUS2 */ + {handlePlanet2}, /* SP_PLANET2 */ + {handleTempPack}, /* SP_TEMP_5 */ + {handleThingy}, /* SP_THINGY */ + {handleThingyInfo}, /* SP_THINGY_INFO */ + {handleShipCap}, /* SP_SHIP_CAP */ + +#ifdef SHORT_PACKETS + {handleShortReply}, /* SP_S_REPLY */ + {handleSMessage}, /* SP_S_MESSAGE */ + {handleSWarning}, /* SP_S_WARNING */ + {handleSelfShort}, /* SP_S_YOU */ + {handleSelfShip}, /* SP_S_YOU_SS */ + {handleVPlayer}, /* SP_S_PLAYER */ +#else + {handleEmpty}, /* 40 */ + {handleEmpty}, /* 41 */ + {handleEmpty}, /* 42 */ + {handleEmpty}, /* 43 */ + {handleEmpty}, /* 44 */ + {handleEmpty}, /* 45 */ +#endif + {handlePing}, /* SP_PING */ +#ifdef SHORT_PACKETS + {handleVTorp}, /* SP_S_TORP */ + {handleVTorpInfo}, /* SP_S_TORP_INFO */ + {handleVTorp}, /* SP_S_8_TORP */ + {handleVPlanet}, /* SP_S_PLANET */ +#else + {handleEmpty}, /* 47 */ + {handleEmpty}, + {handleEmpty}, + {handleEmpty}, /* 50 */ +#endif + {handleGameparams}, + {handleExtension1}, + {handleTerrain2}, /* 53 */ + {handleTerrainInfo2}, + {handleEmpty}, + {handleEmpty}, + {handleEmpty}, + {handleEmpty}, + {handleEmpty}, /* 59 */ +#ifdef FEATURE + {handleFeature}, /* SP_FEATURE */ +#else + {handleEmpty}, /* 60 */ +#endif +}; + +#define NUM_HANDLERS (sizeof(handlers)/sizeof(*handlers)) + +#define NUM_PACKETS (sizeof(handlers) / sizeof(handlers[0]) - 1) + +int serverDead = 0; + +int UdpLocalPort = 0; /* do we want a specified local UDP port */ + +#ifdef SIZE_LOGGING +void +print_totals() +/* prints the total number of bytes sent/received. Called when exiting the + client [BDyess] */ +{ + time_t timeSpent = time(NULL) - timeStart; + + /* + printf("Total bytes sent: %d\nTotal bytes received: %d\n", + send_total, receive_total); + */ + /* ftp format [BDyess] */ + if (timeSpent < 600 /* 10 minutes */ ) { + printf("%8d bytes sent in %d seconds (%.3f Kbytes/s)\n", + send_total, timeSpent, + (float) send_total / (1024.0 * timeSpent)); + printf("%8d bytes received in %d seconds (%.3f Kbytes/s)\n", + receive_total, timeSpent, + (float) receive_total / (1024.0 * timeSpent)); + } else { /* number too big for seconds, use minutes */ + printf("%8d bytes sent in %.1f minutes (%.3f Kbytes/s)\n", + send_total, timeSpent / 60.0, + (float) send_total / (1024.0 * timeSpent)); + printf("%8d bytes received in %.1f minutes (%.3f Kbytes/s)\n", + receive_total, timeSpent / 60.0, + (float) receive_total / (1024.0 * timeSpent)); + } +} +#else +#define EXIT exit +#endif /* SIZE_LOGGING */ + +int udpLocalPort = 0; +static int udpServerPort = 0; +static long serveraddr = 0; +static long sequence = 0; +static int drop_flag = 0; +static int chan = -1; /* tells sequence checker where packet is + from */ +static short fSpeed, fDirection, fShield, fOrbit, fRepair, fBeamup, fBeamdown, fCloak, + fBomb, fDockperm, fPhaser, fPlasma, fPlayLock, fPlanLock, fTractor, + fRepress; + +/* reset all the "force command" variables */ +static void +resetForce() +{ + fSpeed = fDirection = fShield = fOrbit = fRepair = fBeamup = fBeamdown = + fCloak = fBomb = fDockperm = fPhaser = fPlasma = fPlayLock = fPlanLock = + fTractor = fRepress = -1; +} + +/* + * If something we want to happen hasn't yet, send it again. + * + * The low byte is the request, the high byte is a max count. When the max + * count reaches zero, the client stops trying. Checking is done with a + * macro for speed & clarity. + */ +#define FCHECK_FLAGS(flag, force, const) { \ + if (force > 0) { \ + if (((me->p_flags & flag) && 1) ^ ((force & 0xff) && 1)) { \ + speedReq.type = const; \ + speedReq.speed = (force & 0xff); \ + sendServerPacket((struct player_spacket *)&speedReq); \ + V_UDPDIAG(("Forced %d:%d\n", const, force & 0xff)); \ + force -= 0x100; \ + if (force < 0x100) force = -1; /* give up */ \ + } else \ + force = -1; \ + } \ +} +#define FCHECK_VAL(value, force, const) { \ + if (force > 0) { \ + if ((value) != (force & 0xff)) { \ + speedReq.type = const; \ + speedReq.speed = (force & 0xff); \ + sendServerPacket((struct player_spacket *)&speedReq); \ + V_UDPDIAG(("Forced %d:%d\n", const, force & 0xff)); \ + force -= 0x100; \ + if (force < 0x100) force = -1; /* give up */ \ + } else \ + force = -1; \ + } \ +} +#define FCHECK_TRACT(flag, force, const) { \ + if (force > 0) { \ + if (((me->p_flags & flag) && 1) ^ ((force & 0xff) && 1)) { \ + tractorReq.type = const; \ + tractorReq.state = ((force & 0xff) >= 0x40); \ + tractorReq.pnum = (force & 0xff) & (~0x40); \ + sendServerPacket((struct player_spacket *)&tractorReq); \ + V_UDPDIAG(("Forced %d:%d/%d\n", const, \ + tractorReq.state, tractorReq.pnum)); \ + force -= 0x100; \ + if (force < 0x100) force = -1; /* give up */ \ + } else \ + force = -1; \ + } \ +} + +static void +checkForce() +{ + struct speed_cpacket speedReq; + struct tractor_cpacket tractorReq; + + /* upgrading kludge [BDyess] */ + if (!upgrading) + FCHECK_VAL(me->p_speed, fSpeed, CP_SPEED); /* almost always repeats */ + FCHECK_VAL(me->p_dir, fDirection, CP_DIRECTION); /* (ditto) */ + FCHECK_FLAGS(PFSHIELD, fShield, CP_SHIELD); + FCHECK_FLAGS(PFORBIT, fOrbit, CP_ORBIT); + FCHECK_FLAGS(PFREPAIR, fRepair, CP_REPAIR); + FCHECK_FLAGS(PFBEAMUP, fBeamup, CP_BEAM); + FCHECK_FLAGS(PFBEAMDOWN, fBeamdown, CP_BEAM); + FCHECK_FLAGS(PFCLOAK, fCloak, CP_CLOAK); + FCHECK_FLAGS(PFBOMB, fBomb, CP_BOMB); + FCHECK_FLAGS(PFDOCKOK, fDockperm, CP_DOCKPERM); + FCHECK_VAL(phasers[me->p_no].ph_status, fPhaser, CP_PHASER); /* bug: dir 0 */ + FCHECK_VAL(plasmatorps[me->p_no].pt_status, fPlasma, CP_PLASMA); /* (ditto) */ + FCHECK_FLAGS(PFPLOCK, fPlayLock, CP_PLAYLOCK); + FCHECK_FLAGS(PFPLLOCK, fPlanLock, CP_PLANLOCK); + +#ifdef HOCKEY + /* kludge to help prevent self-deflects */ + if(! (hockey && me->p_tractor == 'g'-'a'+10 /*puck*/)) { +#endif + FCHECK_TRACT(PFTRACT, fTractor, CP_TRACTOR); + FCHECK_TRACT(PFPRESS, fRepress, CP_REPRESS); +#ifdef HOCKEY + } +#endif +} + + +int +idx_to_mask(i) + int i; +{ + if (i == number_of_teams) + return ALLTEAM; + return 1 << i; +} + +int +mask_to_idx(m) + int m; +{ + int i, j; + for (i = 1, j = -1; m > 0 && i < 5; i++, m >>= 1) + if (m & 1) + j += i; + if (j > number_of_teams) + j = number_of_teams; + return j; +} + + +void +connectToServer(port) + int port; +{ +#ifndef DNET + int s; + struct sockaddr_in addr; + struct sockaddr_in naddr; + int len; + fd_set readfds; + struct timeval timeout; + struct hostent *hp; + + serverDead = 0; + if (sock != -1) { + shutdown(sock, 2); + sock = -1; + } + sleep(3); /* I think this is necessary for some unknown + reason */ + +#ifdef RWATCH + printf("rwatch: Waiting for connection. \n"); +#else + printf("Waiting for connection (port %d). \n", port); +#endif /* RWATCH */ + + if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { +#ifdef RWATCH + printf("rwatch: I can't create a socket\n"); +#else + printf("I can't create a socket\n"); +#endif /* RWATCH */ +#ifdef AUTOKEY + if (autoKey) + W_AutoRepeatOn(); +#endif + + EXIT(2); + } +#ifndef RWATCH +#ifdef nodef /* don't use for now */ + set_tcp_opts(s); +#endif /* nodef */ +#endif /* RWATCH */ + + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_port = htons(port); + + if (bind(s, (struct sockaddr *) & addr, sizeof(addr)) < 0) { + sleep(10); + if (bind(s, (struct sockaddr *) & addr, sizeof(addr)) < 0) { + sleep(10); + if (bind(s, (struct sockaddr *) & addr, sizeof(addr)) < 0) { +#ifdef RWATCH + printf("rwatch: I can't bind to port!\n"); +#else + printf("I can't bind to port!\n"); +#endif /* RWATCH */ +#ifdef AUTOKEY + if (autoKey) + W_AutoRepeatOn(); +#endif + + EXIT(3); + } + } + } + listen(s, 1); + + len = sizeof(naddr); + +tryagain: + timeout.tv_sec = 240; /* four minutes */ + timeout.tv_usec = 0; + FD_ZERO(&readfds); + FD_SET(s, &readfds); + if (select(32, &readfds, NULL, NULL, &timeout) == 0) { +#ifdef RWATCH + printf("rwatch: server died.\n"); +#else + printf("Well, I think the server died!\n"); +#endif /* RWATCH */ +#ifdef AUTOKEY + if (autoKey) + W_AutoRepeatOn(); +#endif + + EXIT(0); + } + sock = accept(s, (struct sockaddr *) & naddr, &len); + + if (sock == -1) { +#ifdef RWATCH + perror("rwatch: accept"); +#else + perror("accept"); +#endif /* RWATCH */ + goto tryagain; + } + close(s); + pickSocket(port); /* new socket != port */ + + + /* + This is strictly necessary; it tries to determine who the caller is, + and set "serverName" and "serveraddr" appropriately. + */ + len = sizeof(struct sockaddr_in); + if (getpeername(sock, (struct sockaddr *) & addr, &len) < 0) { + perror("unable to get peername"); + serverName = "nowhere"; + } else { + serveraddr = addr.sin_addr.s_addr; + hp = gethostbyaddr((char *) &addr.sin_addr.s_addr, sizeof(long), AF_INET); + if (hp != NULL) { + serverName = (char *) malloc(strlen(hp->h_name) + 1); + strcpy(serverName, hp->h_name); + } else { + serverName = (char *) malloc(strlen((char *) inet_ntoa(addr.sin_addr)) + 1); + strcpy(serverName, (char *) inet_ntoa(addr.sin_addr)); + } + } + printf("Connection from server %s (0x%x)\n", serverName, serveraddr); + +#else /* DNET */ + /* + unix end DNet server process connects to the server, on specified * + port + */ + ConnectToDNetServer(port); +#endif /* DNET */ + +} + + +#ifndef DNET +#ifdef nodef +static void +set_tcp_opts(s) + int s; +{ + int optval = 1; + struct protoent *ent; + + ent = getprotobyname("TCP"); + if (!ent) { + fprintf(stderr, "TCP protocol not found.\n"); + return; + } + if (setsockopt(s, ent->p_proto, TCP_NODELAY, &optval, sizeof(int)) < 0) + perror("setsockopt"); +} + +static void +set_udp_opts(s) + int s; +{ + int optval = BUFSIZ; + struct protoent *ent; + ent = getprotobyname("UDP"); + if (!ent) { + fprintf(stderr, "UDP protocol not found.\n"); + return; + } + if (setsockopt(s, ent->p_proto, SO_RCVBUF, &optval, sizeof(int)) < 0) + perror("setsockopt"); +} +#endif /* nodef */ + +#endif /* DNET */ + +void +callServer(port, server) + int port; + char *server; +{ +#ifndef DNET + int s; + struct sockaddr_in addr; + struct hostent *hp; +#endif + serverDead = 0; + + printf("Calling %s on port %d.\n", server, port); +#ifdef DNET + CallDNetServer(server, port); +#else + if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + printf("I can't create a socket\n"); + EXIT(0); + } +#ifndef RWATCH +#ifdef nodef + set_tcp_opts(s); +#endif /* nodef */ +#endif /* RWATCH */ + + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + + if ((addr.sin_addr.s_addr = inet_addr(server)) == -1) { + if ((hp = gethostbyname(server)) == NULL) { + printf("Who is %s?\n", server); + EXIT(0); + } else { + addr.sin_addr.s_addr = *(long *) hp->h_addr; + } + } + serveraddr = addr.sin_addr.s_addr; + + if (connect(s, (struct sockaddr *) & addr, sizeof(addr)) < 0) { + printf("Server not listening!\n"); + EXIT(0); + } + printf("Got connection.\n"); + + sock = s; +#endif /* DNET */ +/* pickSocket is utterly useless with DNet, but the server needs the + packet to tell it the client is ready to start. */ + +#ifdef RECORDER + startRecorder(); +#endif + pickSocket(port); /* new socket != port */ +} + +int +isServerDead() +{ + return (serverDead); +} + +void +socketPause(sec, usec) + int sec, usec; +{ + struct timeval timeout; + fd_set readfds; + +#ifdef RECORDER + if (playback) + return; +#endif +#ifdef DNET + (void) DNetServerPause(sec, usec, 0); +#else + + timeout.tv_sec = sec; + timeout.tv_usec = usec; + FD_ZERO(&readfds); + FD_SET(sock, &readfds); + if (udpSock >= 0) /* new */ + FD_SET(udpSock, &readfds); + select(32, &readfds, 0, 0, &timeout); +#endif /* DNET */ +} + +int +readFromServer() +{ + struct timeval timeout; + fd_set readfds; + int retval = 0, rs; + +#ifdef RECORDER + if (playback) { + while (!pb_update) + doRead(sock); + return 1; + } +#endif + + if (serverDead) + return (0); + if (commMode == COMM_TCP) + drop_flag = 0; /* just in case */ + +#ifndef DNET + timeout.tv_sec = 0; + timeout.tv_usec = 0; + + FD_ZERO(&readfds); + FD_SET(sock, &readfds); + if (udpSock >= 0) + FD_SET(udpSock, &readfds); + if ((rs = select(32, &readfds, 0, 0, &timeout)) != 0) { + if (rs < 0) { + /* NEW */ + perror("select"); + return 0; + } +#else + /* this should have been done before calling the function.. not sure about this, should maybe be doing + DNetServerPause here? -JR*/ + /* sigsPending=Wait(sockMask | udpSockMask | SIGBREAKF_CTRL_C); + */ + if (sigsPending & SIGBREAKF_CTRL_C) { + printf("readFromServer: Ctrl-C break, exiting\n"); + exit(0); + } + /* note for DNet FD_ISSET is redefined. */ +#endif /* DNET */ + /* Read info from the xtrek server */ + if (FD_ISSET(sock, &readfds)) { + chan = sock; + retval += doRead(sock); + } + if (udpSock >= 0 && FD_ISSET(udpSock, &readfds)) { + /* WAS V_ *//* should be! */ + V_UDPDIAG(("Activity on UDP socket\n")); + chan = udpSock; + if (commStatus == STAT_VERIFY_UDP) { + warning("UDP connection established"); + sequence = 0; /* reset sequence #s */ + resetForce(); + + if (udpDebug) + printUdpInfo(); + UDPDIAG(("UDP connection established.\n")); + + commMode = COMM_UDP; + commStatus = STAT_CONNECTED; + commSwitchTimeout = 0; + if (udpClientRecv != MODE_SIMPLE) + sendUdpReq(COMM_MODE + udpClientRecv); + if (udpWin) { + udprefresh(UDP_CURRENT); + udprefresh(UDP_STATUS); + } + } + retval += doRead(udpSock); + } +#ifndef DNET + } +#endif + + /* if switching comm mode, decrement timeout counter */ + if (commSwitchTimeout > 0) { + if (!(--commSwitchTimeout)) { + /* + timed out; could be initial request to non-UDP server (which won't + be answered), or the verify packet got lost en route to the + server. Could also be a request for TCP which timed out (weird), + in which case we just reset anyway. + */ + commModeReq = commMode = COMM_TCP; + commStatus = STAT_CONNECTED; + if (udpSock >= 0) + closeUdpConn(); + if (udpWin) { + udprefresh(UDP_CURRENT); + udprefresh(UDP_STATUS); + } + warning("Timed out waiting for UDP response from server"); + UDPDIAG(("Timed out waiting for UDP response from server\n")); + } + } + /* if we're in a UDP "force" mode, check to see if we need to do something */ + if (commMode == COMM_UDP && udpClientSend > 1) + checkForce(); + + return (retval != 0); /* convert to 1/0 */ +} + + +/* this used to be part of the routine above */ +char buf[BUFSIZ * 2 + 16]; + +static int +doRead(asock) + int asock; +{ + char *bufptr; + int size; + int count; + int temp; +#ifdef HANDLER_TIMES + struct timeval htpre, htpost; + extern void log_time(int, struct timeval *, struct timeval *); +#endif + +#ifndef DNET + struct timeval timeout; + fd_set readfds; + timeout.tv_sec = 0; + timeout.tv_usec = 0; +#endif /* DNET */ + + count = sock_read(asock, buf, 2 * BUFSIZ); +#ifdef DNET + if (count == 0) { /* yuck. */ + return 0; + } +#endif +/* TMP */ +#ifdef nodef + if (asock == udpSock) + printf("read %d bytes\n", count); +#endif /* nodef */ + + if (count <= 0) { + if (asock == udpSock) { +#ifndef DNET + if (errno == ECONNREFUSED) { + struct sockaddr_in addr; + + UDPDIAG(("asock=%d, sock=%d, udpSock=%d, errno=%d\n", + asock, sock, udpSock, errno)); + UDPDIAG(("count=%d\n", count)); + UDPDIAG(("Hiccup(%d)! Reconnecting\n", errno)); + addr.sin_addr.s_addr = serveraddr; + addr.sin_port = htons(udpServerPort); + addr.sin_family = AF_INET; + if (connect(udpSock, (struct sockaddr *) & addr, sizeof(addr)) < 0) { + perror("connect"); + UDPDIAG(("Unable to reconnect\n")); + /* and fall through to disconnect */ + } else { + UDPDIAG(("Reconnect successful\n")); + return (0); + } + } +#endif /* DNET */ + UDPDIAG(("*** UDP disconnected (res=%d, err=%d)\n", + count, errno)); + warning("UDP link severed"); + printUdpInfo(); + closeUdpConn(); + commMode = commModeReq = COMM_TCP; + commStatus = STAT_CONNECTED; + if (udpWin) { + udprefresh(UDP_STATUS); + udprefresh(UDP_CURRENT); + } + return (0); + } +#ifndef RWATCH + printf("1) Got read() of %d. Server dead\n", count); + perror(""); +#endif /* RWATCH */ + serverDead = 1; + return (0); + } + bufptr = buf; + while (bufptr < buf + count) { +#ifdef SHORT_PACKETS +computesize: + if ((*bufptr == SP_S_MESSAGE && (buf + count - bufptr <= 4)) + || (buf + count - bufptr < 4)) { /* last part may only be + needed for DNet...I'm not + so sure any more. + certainly doesn't hurt to + have it.-JR */ + /* + printf("buf+count-bufptr=%d, *bufptr=%d\n",buf + count - + bufptr,*bufptr); + */ + size = 0; /* problem with reads breaking before size + byte for SP_S_MESSAGE has been read. Only + a problem for messages because reads break + on 4 byte boundaries, other size bytes + are always in the first 4. -JR */ + } else +#endif + { + size = size_of_spacket(bufptr); + if (size < 1) { +#if 1 + fprintf(stderr, "Unknown packet %d. Faking it.\n", + *bufptr); + size = 4; +#else + fprintf(stderr, "Unknown packet %d. Aborting.\n", + *bufptr); + return (0); +#endif + } +#ifdef SHOW_RECEIVED + printf("recieved packet type %d, size %d\n", *bufptr, size); +#endif /* SHOW_RECEIVED */ +#ifdef PACKET_LIGHTS + light_receive(); +#endif /* PACKET_LIGHTS */ +#ifdef SIZE_LOGGING + receive_total += size; +#endif /* SIZE_LOGGING */ + } + while (size > count + (buf - bufptr) || size == 0) { + /* + We wait for up to ten seconds for rest of packet. If we don't + get it, we assume the server died. + */ + /* + printf("er, possible packet fragment, waiting for the + rest...\n"); + */ +#ifdef RECORDER + if (!playback) +#endif + { +#ifdef DNET + temp = DNetServerPause(20, 0, asock); +#else /* DNET */ + timeout.tv_sec = 20; + timeout.tv_usec = 0; + FD_ZERO(&readfds); + FD_SET(asock, &readfds); + /* readfds=1<<asock; */ + temp = select(32, &readfds, 0, 0, &timeout); +#endif + if (temp == 0) { + printf("Packet fragment. Server must be dead\n"); + serverDead = 1; + return (0); + } + } +#ifdef SHORT_PACKETS + if (size == 0) + /* 84=largest short packet message - the 4 we have */ + temp = sock_read(asock, buf + count, 84); + else +#endif + temp = sock_read(asock, buf + count, size - (count + (buf - bufptr))); + count += temp; +#ifdef DNET + if (temp < 0) +#else + if (temp <= 0) +#endif /* DNET */ + { +#ifndef RWATCH + printf("2) Got read() of %d. Server is dead\n", temp); +#endif /* RWATCH */ + serverDead = 1; + return (0); + } +#ifdef SHORT_PACKETS + if (size == 0) /* for the SP_S_MESSAGE problem */ + goto computesize; +#endif + } +#ifdef UPDATE_SIZES + totalbytes += size; + packetbytes[*bufptr] += size; +#endif +#ifdef RECORDER + if (playback && (*bufptr == REC_UPDATE)) { + pb_update++; + me->p_tractor = bufptr[1]; + if (me->p_flags & PFPLOCK) + me->p_playerl = bufptr[2]; + else + me->p_planet = bufptr[2]; +/* printf("Read REC_UPDATE pseudo-packet!\n");*/ + } else +#endif + if (*bufptr >= 1 && + *bufptr < NUM_HANDLERS && + handlers[(int) *bufptr].handler != NULL) { + if (asock != udpSock || + (!drop_flag || *bufptr == SP_SEQUENCE || *bufptr == SP_SC_SEQUENCE)) { + if (asock == udpSock) + packets_received++; /* ping stuff */ +#ifdef RECORDER + if (recordGame) + recordPacket(bufptr, size); +#endif +#ifdef HANDLER_TIMES + gettimeofday(&htpre,0); +#endif + (*(handlers[(unsigned char)*bufptr].handler)) (bufptr); +#ifdef HANDLER_TIMES + gettimeofday(&htpost,0); + log_time(*bufptr, &htpre, &htpost); +#endif + /* printf("handled packet %d\n", (unsigned char)*bufptr); */ + } else + UDPDIAG(("Ignored type %d\n", *bufptr)); + } else { + printf("Handler for packet %d not installed...\n", *bufptr); + } + + bufptr += size; + if (bufptr > buf + BUFSIZ) { + bcopy(buf + BUFSIZ, buf, BUFSIZ); + if (count == BUFSIZ * 2) { +#ifdef RECORDER + if (playback) + temp = 0; + else +#endif + { +#ifdef DNET + temp = DNetServerPause(3, 0, asock); +#else + FD_ZERO(&readfds); + FD_SET(asock, &readfds); + /* readfds = 1<<asock; */ + temp = select(32, &readfds, 0, 0, &timeout); +#endif /* DNET */ + } + if (temp != 0) { + temp = sock_read(asock, buf + BUFSIZ, BUFSIZ); + count = BUFSIZ + temp; +#ifdef DNET + if (temp < 0) +#else + if (temp <= 0) +#endif /* DNET */ + { +#ifndef RWATCH + printf("3) Got read() of %d. Server is dead\n", temp); +#endif /* RWATCH */ + serverDead = 1; + return (0); + } + } else { + count = BUFSIZ; + } + } else { + count -= BUFSIZ; + } + bufptr -= BUFSIZ; + } + } + return (1); +} + +#define SANITY_TORPNUM(idx) \ + if ( (unsigned)(idx) >= ntorps*nplayers) { \ + fprintf(stderr, "torp index %d out of bounds\n", (idx)); \ + return; \ + } + +#define SANITY_PNUM(idx) \ + if ( (unsigned)(idx) >= nplayers) { \ + fprintf(stderr, "player number %d out of bounds\n", (idx)); \ + return; \ + } + +#define SANITY_PHASNUM(idx) \ + if ( (unsigned)(idx) >= nplayers*nphasers) { \ + fprintf(stderr, "phaser number %d out of bounds\n", (idx)); \ + return; \ + } + +#define SANITY_PLASNUM(idx) \ + if ( (unsigned)(idx) >= nplayers*nplasmas) { \ + fprintf(stderr, "plasma number %d out of bounds\n", (idx)); \ + return; \ + } + +#define SANITY_THINGYNUM(idx) \ + if ( (unsigned)(idx) >= npthingies*nplayers + ngthingies) { \ + fprintf(stderr, "thingy index %x out of bounds\n", (idx)); \ + return; \ + } + +#define SANITY_PLANNUM(idx) \ + if ( (unsigned)(idx) >= nplanets) { \ + fprintf(stderr, "planet index %d out of bounds\n", (idx)); \ + return; \ + } + +#define SANITY_SHIPNUM(idx) \ + if ( (unsigned)(idx) >= nshiptypes) { \ + fprintf(stderr, "ship type %d out of bounds\n", (idx)); \ + return; \ + } + + +static void +handleTorp(packet) + struct torp_spacket *packet; +{ + struct torp *thetorp; + + SANITY_TORPNUM(ntohs(packet->tnum)); + + thetorp = &torps[ntohs(packet->tnum)]; + thetorp->t_x = ntohl(packet->x); + thetorp->t_y = ntohl(packet->y); + thetorp->t_dir = packet->dir; + +#ifdef ROTATERACE + if (rotate) { + rotate_gcenter(&thetorp->t_x, &thetorp->t_y); + rotate_dir(&thetorp->t_dir, rotate_deg); +#endif +#ifdef BORGTEST + if (bd) + bd_test_torp(ntohs(packet->tnum), thetorp); +#endif + } +} + + +static void +handleTorpInfo(packet) + struct torp_info_spacket *packet; +{ + struct torp *thetorp; + + SANITY_TORPNUM(ntohs(packet->tnum)); + + thetorp = &torps[ntohs(packet->tnum)]; + + if (packet->status == TEXPLODE && thetorp->t_status == TFREE) { + /* FAT: redundant explosion; don't update p_ntorp */ + /* + printf("texplode ignored\n"); + */ + return; + } + + if (thetorp->t_status == TFREE && packet->status) { + players[thetorp->t_owner].p_ntorp++; + thetorp->frame = 0; +#ifdef BORGTEST + if (bd) + bd_new_torp(ntohs(packet->tnum), thetorp); +#endif + + } + if (thetorp->t_status && packet->status == TFREE) { + players[thetorp->t_owner].p_ntorp--; + } + thetorp->t_war = packet->war; + + if (packet->status != thetorp->t_status) { + /* FAT: prevent explosion reset */ + thetorp->t_status = packet->status; + if (thetorp->t_status == TEXPLODE) { + thetorp->t_fuse = NUMDETFRAMES; + } + } +} + +static void +handleStatus(packet) + struct status_spacket *packet; +{ + status->tourn = packet->tourn; + status->armsbomb = ntohl(packet->armsbomb); + status->planets = ntohl(packet->planets); + status->kills = ntohl(packet->kills); + status->losses = ntohl(packet->losses); + status->time = ntohl(packet->time); + status->timeprod = ntohl(packet->timeprod); +} + +static void +handleSelf(packet) + struct you_spacket *packet; +{ + SANITY_PNUM(packet->pnum); + me = (ghoststart ? &players[ghost_pno] : &players[packet->pnum]); + myship = (me->p_ship); + mystats = &(me->p_stats); + me->p_hostile = packet->hostile; + me->p_swar = packet->swar; + me->p_armies = packet->armies; + me->p_flags = ntohl(packet->flags); + me->p_damage = ntohl(packet->damage); + me->p_shield = ntohl(packet->shield); + me->p_fuel = ntohl(packet->fuel); + me->p_etemp = ntohs(packet->etemp); + me->p_wtemp = ntohs(packet->wtemp); + me->p_whydead = ntohs(packet->whydead); + me->p_whodead = ntohs(packet->whodead); + status2->clock = (unsigned long) packet->pad2; + status2->clock += ((unsigned long) packet->pad3) << 8; +#ifdef INCLUDE_VISTRACT + if (packet->tractor & 0x40) + me->p_tractor = (short) packet->tractor & (~0x40); /* ATM - visible trac + tors */ +#ifdef nodef /* tmp */ + else + me->p_tractor = -1; +#endif /* nodef */ +#endif +#ifdef SOUND + S_HandlePFlags(); +#endif + +} + +static void +handlePlayer(packet) + struct player_spacket *packet; +{ + register struct player *pl; + unsigned char newdir; + + SANITY_PNUM(packet->pnum); + + + pl = &players[packet->pnum]; + newdir = packet->dir; +#ifdef ROTATERACE + if (rotate) + rotate_dir(&newdir, rotate_deg); +#endif +#ifdef CHECK_DROPPED + /* Kludge to fix lost uncloak packets! [3/94] -JR */ + if (pl->p_flags & PFCLOAK && pl->p_cloakphase >= (CLOAK_PHASES - 1)) { + if (pl->p_dir != newdir) { /* always sends the same direction + when cloaked! */ + int i, plocked = 0; + + /* + nplayers is for paradise, probably want MAX_PLAYERS for other + clients + */ + for (i = 0; i < nplayers; i++) { /* except when someone has + this person phasered :( */ + if ((phasers[i].ph_status & PHHIT) && (phasers[i].ph_target == packet->pnum)) { + plocked = 1; + break; + } + } + if (!plocked) { + pl->p_flags &= ~(PFCLOAK); + if (reportDroppedPackets) + printf("Uncloak kludge, player %d\n", pl->p_no); + } + } + } +#endif + pl->p_dir = newdir; + pl->p_speed = packet->speed; + pl->p_x = ntohl(packet->x); + pl->p_y = ntohl(packet->y); + if (pl == me) { + extern int my_x, my_y; /* from shortcomm.c */ + my_x = me->p_x; + my_y = me->p_y; + } + redrawPlayer[packet->pnum] = 1; + + if (me == pl) { + extern int my_x, my_y; /* short packets need unrotated co-ords! */ + my_x = pl->p_x; + my_y = pl->p_y; + } +#ifdef ROTATERACE + if (rotate) { + rotate_gcenter(&pl->p_x, &pl->p_y); + } +#endif + +} + + +static void +handleWarning(packet) + struct warning_spacket *packet; +{ + warning((char *) packet->mesg); +} + +static void +handleThingy(packet) + struct thingy_spacket *packet; +{ + struct thingy *thetorp; + + SANITY_THINGYNUM(ntohs(packet->tnum)); + + thetorp = &thingies[ntohs(packet->tnum)]; + thetorp->t_x = ntohl(packet->x); + thetorp->t_y = ntohl(packet->y); + /* printf("drone at %d, %d\n", thetorp->t_x, thetorp->t_y); */ + thetorp->t_dir = packet->dir; + + +#ifdef ROTATERACE + if (rotate) { + rotate_gcenter(&thetorp->t_x, &thetorp->t_y); + rotate_dir(&thetorp->t_dir, rotate_deg); + } +#endif + + if (thetorp->t_shape == SHP_WARP_BEACON) + redrawall = 1; /* shoot, route has changed */ + +} + +static void +handleThingyInfo(packet) + struct thingy_info_spacket *packet; +{ + struct thingy *thetorp; + + SANITY_THINGYNUM(ntohs(packet->tnum)); + + thetorp = &thingies[ntohs(packet->tnum)]; + +#if 1 + thetorp->t_owner = ntohs(packet->owner); +#else + /* we have the gameparam packet now */ +#endif + + if (thetorp->t_shape == SHP_WARP_BEACON) + redrawall = 1; /* redraw the lines, I guess */ + + if (ntohs(packet->shape) == SHP_BOOM && thetorp->t_shape == SHP_BLANK) { + /* FAT: redundant explosion; don't update p_ntorp */ + /* + printf("texplode ignored\n"); + */ + return; + } + + if (thetorp->t_shape == SHP_BLANK && ntohs(packet->shape) != SHP_BLANK) { + players[thetorp->t_owner].p_ndrone++; /* TSH */ + } + if (thetorp->t_shape != SHP_BLANK && ntohs(packet->shape) == SHP_BLANK) { + players[thetorp->t_owner].p_ndrone--; /* TSH */ + } + thetorp->t_war = packet->war; + + if (ntohs(packet->shape) != thetorp->t_shape) { + /* FAT: prevent explosion reset */ + thetorp->t_shape = ntohs(packet->shape); + if (thetorp->t_shape == SHP_BOOM || + thetorp->t_shape == SHP_PBOOM) { + thetorp->t_fuse = NUMDETFRAMES; + } + } +} + +void +sendShortPacket(type, state) + char type, state; +{ + struct speed_cpacket speedReq; + + speedReq.type = type; + speedReq.speed = state; +#ifdef UNIX_SOUND + if (type == CP_SHIELD) play_sound (SND_SHIELD); /* Shields */ +#endif + sendServerPacket((struct player_spacket *) & speedReq); + /* printf("Sending packet #%d\n",type); */ + + /* if we're sending in UDP mode, be prepared to force it */ + if (commMode == COMM_UDP && udpClientSend >= 2) { + switch (type) { + case CP_SPEED: + fSpeed = state | 0x100; + break; + case CP_DIRECTION: + fDirection = state | 0x100; + break; + case CP_SHIELD: + fShield = state | 0xa00; + break; + case CP_ORBIT: + fOrbit = state | 0xa00; + break; + case CP_REPAIR: + fRepair = state | 0xa00; + break; + case CP_CLOAK: + fCloak = state | 0xa00; + break; + case CP_BOMB: + fBomb = state | 0xa00; + break; + case CP_DOCKPERM: + fDockperm = state | 0xa00; + break; + case CP_PLAYLOCK: + fPlayLock = state | 0xa00; + break; + case CP_PLANLOCK: + fPlanLock = state | 0xa00; + break; + case CP_BEAM: + if (state == 1) + fBeamup = 1 | 0x500; + else + fBeamdown = 2 | 0x500; + break; + } + + /* force weapons too? */ + if (udpClientSend >= 3) { + switch (type) { + case CP_PHASER: + fPhaser = state | 0x100; + break; + case CP_PLASMA: + fPlasma = state | 0x100; + break; + } + } + } +} + +void +sendServerPacket(packet) +/* Pick a random type for the packet */ + struct player_spacket *packet; +{ + int size; + +#ifdef RWATCH + return; +#endif /* RWATCH */ + + if (serverDead) + return; + size = size_of_cpacket(packet); + if (size < 1) { + printf("Attempt to send strange packet %d!\n", packet->type); + return; + } +#ifdef SHOW_SEND + printf("sending packet type %d, size %d\n", packet->type, + size); +#endif /* SHOW_SEND */ +#ifdef PACKET_LIGHTS + light_send(); +#endif /* PACKET_LIGHTS */ +#ifdef SIZE_LOGGING + send_total += size; +#endif /* SIZE_LOGGING */ + if (commMode == COMM_UDP) { + /* for now, just sent everything via TCP */ + } + if (commMode == COMM_TCP || !udpClientSend) { + /* special case for verify packet */ + if (packet->type == CP_UDP_REQ) { + if (((struct udp_req_cpacket *) packet)->request == COMM_VERIFY) + goto send_udp; + } + /* + business as usual (or player has turned off UDP transmission) + */ + if (gwrite(sock, (char *) packet, size) != size) { + printf("gwrite failed. Server must be dead\n"); + serverDead = 1; + } + } else { + /* + UDP stuff + */ + switch (packet->type) { + case CP_SPEED: + case CP_DIRECTION: + case CP_PHASER: + case CP_PLASMA: + case CP_TORP: + case CP_QUIT: + case CP_PRACTR: + case CP_REPAIR: + case CP_ORBIT: + case CP_BOMB: + case CP_BEAM: + case CP_DET_TORPS: + case CP_DET_MYTORP: + case CP_TRACTOR: + case CP_REPRESS: + case CP_COUP: + case CP_DOCKPERM: + case CP_SCAN: + case CP_PING_RESPONSE: + case CP_CLOAK: + case CP_SHIELD: + case CP_PLANLOCK: + /* + these are non-critical but don't expire, send with TCP + [BDyess] + */ + /* case CP_REFIT: */ + /* case CP_PLAYLOCK: */ + /* non-critical stuff, use UDP */ + send_udp: + packets_sent++; /* ping stuff */ + + V_UDPDIAG(("Sent %d on UDP port\n", packet->type)); + if (gwrite(udpSock, (char *) packet, size) != size) { + UDPDIAG(("gwrite on UDP failed. Closing UDP connection\n")); + warning("UDP link severed"); + /* serverDead=1; */ + commModeReq = commMode = COMM_TCP; + commStatus = STAT_CONNECTED; + commSwitchTimeout = 0; + if (udpWin) { + udprefresh(UDP_STATUS); + udprefresh(UDP_CURRENT); + } + if (udpSock >= 0) + closeUdpConn(); + } + break; + + default: + /* critical stuff, use TCP */ + if (gwrite(sock, (char *) packet, size) != size) { + printf("gwrite failed. Server must be dead\n"); + serverDead = 1; + } + } + } +} + +static void +handlePlanet(packet) + struct planet_spacket *packet; +{ + struct planet *plan; + /* FAT: prevent excessive redraw */ + int redraw = 0; +#ifdef HOCKEY + int hockey_update = 0; +#endif /*HOCKEY*/ + + SANITY_PLANNUM(packet->pnum); + + plan = &planets[packet->pnum]; + if (plan->pl_owner != packet->owner) { + redraw = 1; +#ifdef HOCKEY + hockey_update = 1; +#endif + } + plan->pl_owner = packet->owner; + + if (plan->pl_owner < (1 << 0) || plan->pl_owner > (1 << (number_of_teams - 1))) + plan->pl_owner = NOBODY; + + if (plan->pl_info != packet->info) + redraw = 1; + plan->pl_info = packet->info; + /* Redraw the planet because it was updated by server */ + + if (plan->pl_flags != (int) ntohs(packet->flags)) + redraw = 1; + plan->pl_flags = (unsigned short) ntohs(packet->flags); + + if (plan->pl_armies != ntohl(packet->armies)) + redraw = 1; + + plan->pl_armies = ntohl(packet->armies); + if (plan->pl_info == 0) { + plan->pl_owner = NOBODY; + } + if (redraw) { + plan->pl_flags |= PLREDRAW; + pl_update[packet->pnum].plu_update = 1; /* used to mean the planet + had moved, now set as a + sign we need to erase AND + redraw. -JR */ + pl_update[packet->pnum].plu_x = planets[packet->pnum].pl_x; + pl_update[packet->pnum].plu_y = planets[packet->pnum].pl_y; + if (infomapped && infotype == PLANETTYPE && + ((struct planet *) infothing)->pl_no == packet->pnum) + infoupdate = 1; +#ifdef HOCKEY + if(hockey_update && hockey) hockeyInit(); +#endif /*HOCKEY*/ + } +} + +static void +handlePhaser(packet) + struct phaser_spacket *packet; +{ + struct phaser *phas; + + SANITY_PHASNUM(packet->pnum); + + phas = &phasers[packet->pnum]; +#ifdef CHECK_DROPPED + /* can't fire weapons cloaked, this guy must be uncloaked.. */ + /* applying this to torps is trickier... -JR */ + if (packet->status != PHFREE) { + if (reportDroppedPackets && (players[packet->pnum].p_flags & PFCLOAK)) + printf("Dropped uncloak, player %d. (fired phaser)\n", packet->pnum); + players[packet->pnum].p_flags &= ~(PFCLOAK); + } else { + if (longest_ph_fuse < phas->ph_fuse) + longest_ph_fuse = phas->ph_fuse; + } +#endif + phas->ph_status = packet->status; + phas->ph_dir = packet->dir; + phas->ph_x = ntohl(packet->x); + phas->ph_y = ntohl(packet->y); + phas->ph_target = ntohl(packet->target); + phas->ph_fuse = 0; + +#ifdef ROTATERACE + if (rotate) { + rotate_gcenter(&phas->ph_x, &phas->ph_y); + rotate_dir(&phas->ph_dir, rotate_deg); + } +#endif +#ifdef SOUND + if ((me->p_no == packet->pnum) && (packet->status != PHFREE)) { + S_PlaySound(S_PHASER); + } +#endif +#ifdef UNIX_SOUND + if ((me->p_no == packet->pnum) && (packet->status != PHFREE)) { + play_sound(SND_PHASER); /* Phasers */ + } +#endif +} + +void +handleMessage(packet) + struct mesg_spacket *packet; +{ + if ((int) packet->m_from >= nplayers) + packet->m_from = 255; + dmessage(packet->mesg, packet->m_flags, packet->m_from, packet->m_recpt); +} + + +static void +handleQueue(packet) + struct queue_spacket *packet; +{ + queuePos = ntohs(packet->pos); + /* printf("Receiving queue position %d\n",queuePos); */ +} + +static void +handleEmpty(ptr) + char *ptr; +{ + printf("Unknown packet type: %d\n", *ptr); + return; +} + +void +sendTeamReq(team, ship) + int team, ship; +{ + struct outfit_cpacket outfitReq; + + outfitReq.type = CP_OUTFIT; + outfitReq.team = team; + outfitReq.ship = ship; + sendServerPacket((struct player_spacket *) & outfitReq); +} + +static void +handlePickok(packet) + struct pickok_spacket *packet; +{ + pickOk = packet->state; +#ifdef RECORDER + if (playback) { /* added when the packet is recorded. */ + extern int lastTeamReq; + lastTeamReq = packet->pad2; + } +#endif +} + +void +sendLoginReq(name, pass, login, query) + char *name, *pass; + char *login; + char query; +{ + struct login_cpacket packet; + + strcpy(packet.name, name); + strcpy(packet.password, pass); + if (strlen(login) > 15) + login[15] = 0; + strcpy(packet.login, login); + packet.type = CP_LOGIN; + packet.query = query; + packet.pad2 = 0x69; /* added 1/19/93 KAO */ + packet.pad3 = 0x43; /* added 1/19/93 KAO *//* was 0x42 3/2/93 */ + sendServerPacket((struct player_spacket *) & packet); +} + +static void +handleLogin(packet) + struct login_spacket *packet; +{ + + + loginAccept = packet->accept; + if ((packet->pad2 == 69) && (packet->pad3 == 42)) + paradise = 1; + else { + /*nshiptypes = 8;*/ + nplayers=20; + nplanets=40; + } + if (packet->accept) { + + /* we no longer accept keymaps from the server */ + + mystats->st_flags = ntohl(packet->flags); + keeppeace = (me->p_stats.st_flags / ST_KEEPPEACE) & 1; + } +} + +void +sendTractorReq(state, pnum) + char state; + char pnum; +{ + struct tractor_cpacket tractorReq; + + tractorReq.type = CP_TRACTOR; + tractorReq.state = state; + tractorReq.pnum = pnum; + sendServerPacket((struct player_spacket *) & tractorReq); + + if (state) + fTractor = pnum | 0x40; + else + fTractor = 0; +} + +void +sendRepressReq(state, pnum) + char state; + char pnum; +{ + struct repress_cpacket repressReq; + + repressReq.type = CP_REPRESS; + repressReq.state = state; + repressReq.pnum = pnum; + sendServerPacket((struct player_spacket *) & repressReq); + + if (state) + fRepress = pnum | 0x40; + else + fRepress = 0; +} + +void +sendDetMineReq(torp) + short torp; +{ + struct det_mytorp_cpacket detReq; + + detReq.type = CP_DET_MYTORP; + detReq.tnum = htons(torp); + sendServerPacket((struct player_spacket *) & detReq); +} + +static void +handlePlasmaInfo(packet) + struct plasma_info_spacket *packet; +{ + struct plasmatorp *thetorp; + + SANITY_PLASNUM(ntohs(packet->pnum)); + + thetorp = &plasmatorps[ntohs(packet->pnum)]; + if (packet->status == PTEXPLODE && thetorp->pt_status == PTFREE) { + /* FAT: redundant explosion; don't update p_nplasmatorp */ + return; + } + if (!thetorp->pt_status && packet->status) { + players[thetorp->pt_owner].p_nplasmatorp++; +#ifdef UNIX_SOUND + play_sound (SND_PLASMA); /* Plasma */ +#endif + } + if (thetorp->pt_status && !packet->status) { + players[thetorp->pt_owner].p_nplasmatorp--; + } + thetorp->pt_war = packet->war; + if (thetorp->pt_status != packet->status) { + /* FAT: prevent explosion timer from being reset */ + thetorp->pt_status = packet->status; + if (thetorp->pt_status == PTEXPLODE) { + thetorp->pt_fuse = NUMDETFRAMES; + } + } +} + +static void +handlePlasma(packet) + struct plasma_spacket *packet; +{ + struct plasmatorp *thetorp; + + SANITY_PLASNUM(ntohs(packet->pnum)); + + thetorp = &plasmatorps[ntohs(packet->pnum)]; + thetorp->pt_x = ntohl(packet->x); + thetorp->pt_y = ntohl(packet->y); + +#ifdef ROTATERACE + if (rotate) { + rotate_gcenter(&thetorp->pt_x, &thetorp->pt_y); + } +#endif +} + +static void +handleFlags(packet) + struct flags_spacket *packet; +{ + SANITY_PNUM(packet->pnum); + + if (players[packet->pnum].p_flags != ntohl(packet->flags) || + players[packet->pnum].p_tractor != ((short) packet->tractor & (~0x40))) { + /* FAT: prevent redundant player update */ + redrawPlayer[packet->pnum] = 1; + } else + return; + +#ifdef CHECK_DROPPED +/* TEST */ +/* For the dropped uncloak kludge, completely ignore uncloaks :-) */ +/* if(players[packet->pnum].p_flags & PFCLOAK) packet->flags |= htonl(PFCLOAK);*/ +/* TEST */ + /* when a player cloaks, clear his phaser */ + if (ntohl(packet->flags) & PFCLOAK) { + if (phasers[packet->pnum].ph_status != PFREE) { + if (reportDroppedPackets) + printf("Lost phaser free packet, player %d. (cloaked)\n", packet->pnum); + phasers[packet->pnum].ph_status = PHFREE; + phasers[packet->pnum].ph_fuse = 0; + } + } +#endif + + players[packet->pnum].p_flags = ntohl(packet->flags); +#ifdef INCLUDE_VISTRACT + if (packet->tractor & 0x40) + players[packet->pnum].p_tractor = (short) packet->tractor & (~0x40); /* ATM - visible + tractors */ + else +#endif /* INCLUDE_VISTRACT */ + players[packet->pnum].p_tractor = -1; +} + +static void +handleKills(packet) + struct kills_spacket *packet; +{ + + SANITY_PNUM(packet->pnum); + + if (players[packet->pnum].p_kills != ntohl(packet->kills) / 100.0) { + players[packet->pnum].p_kills = ntohl(packet->kills) / 100.0; + /* FAT: prevent redundant player update */ + updatePlayer[packet->pnum] |= ALL_UPDATE; + if (infomapped && infotype == PLAYERTYPE && + ((struct player *) infothing)->p_no == packet->pnum) + infoupdate = 1; +#ifdef PLPROF + printf("Got handleKills for %d\n", packet->pnum); +#endif /* PLPROF */ +#ifdef ARMY_SLIDER + if (me == &players[packet->pnum]) { + calibrate_stats(); + redrawStats(); + } +#endif /* ARMY_SLIDER */ + } +} + +static void +handlePStatus(packet) + struct pstatus_spacket *packet; +{ + SANITY_PNUM(packet->pnum); + + if (packet->status == PEXPLODE) { + players[packet->pnum].p_explode = 0; + } + /* + Ignore DEAD status. Instead, we treat it as PEXPLODE. This gives us + time to animate all the frames necessary for the explosions at our own + pace. + */ + if (packet->status == PDEAD) { + packet->status = PEXPLODE; + } + if (players[packet->pnum].p_status != packet->status) { + players[packet->pnum].p_status = packet->status; + redrawPlayer[packet->pnum] = 1; +#ifdef PLPROF + printf("Got handlePStatus for %d\n", packet->pnum); +#endif /* PLPROF */ + updatePlayer[packet->pnum] |= ALL_UPDATE; + if (infomapped && infotype == PLAYERTYPE && + ((struct player *) infothing)->p_no == packet->pnum) + infoupdate = 1; +#ifdef CHECK_DROPPED + if (players[packet->pnum].p_status == POUTFIT) { + int i; + /* clear phasers on this guy */ +#if 0 + for (i = 0; i < nplayers; i++) { + if (phasers[i].ph_target == packet->pnum && phasers[i].ph_status == PHHIT) { + if (reportDroppedPackets) + printf("Lost phaser free packet, player %d->player %d (target not alive)\n", + i, packet->pnum); + phasers[i].ph_status = PHFREE; + } + } +#endif + if (phasers[packet->pnum].ph_status != PHFREE) { + if (reportDroppedPackets) + printf("Lost phaser free packet, player %d (outfitting)\n", packet->pnum); + phasers[packet->pnum].ph_status = PHFREE; /* and his own */ + } + if (reportDroppedPackets && players[packet->pnum].p_ntorp > 1) + /* only report it on 2 or more left, always clear it. */ + printf("Lost torp free packet, (%d torps) player %d (outfitting)\n", + players[packet->pnum].p_ntorp, packet->pnum); + players[packet->pnum].p_ntorp = 0; + for (i = packet->pnum * ntorps; i < (packet->pnum + 1) * ntorps; i++) { + torps[i].t_status = TFREE; + } + } +#endif + } +} + +static void +handleMotd(packet) + struct motd_spacket *packet; +{ + newMotdLine((char *) packet->line); +} + +void +sendMessage(mes, group, indiv) + char *mes; + int group, indiv; +{ + struct mesg_cpacket mesPacket; + +#ifdef SHORT_PACKETS + if (recv_short) { + int size; + size = strlen(mes); + size += 5; /* 1 for '\0', 4 packetheader */ + if ((size % 4) != 0) + size += (4 - (size % 4)); + mesPacket.pad1 = (char) size; + + /* + OH SHIT!!!! sizes[CP_S_MESSAGE] = size; + */ + + mesPacket.type = CP_S_MESSAGE; + } else +#endif + mesPacket.type = CP_MESSAGE; + mesPacket.group = group; + mesPacket.indiv = indiv; + strcpy(mesPacket.mesg, mes); + sendServerPacket((struct player_spacket *) & mesPacket); +} + +static void +handleMask(packet) + struct mask_spacket *packet; +{ + tournMask = packet->mask; +} + +void +sendOptionsPacket() +{ + struct options_cpacket optPacket; + register int i; + long flags; + + optPacket.type = CP_OPTIONS; + flags = ( + ST_NOBITMAPS * (!sendmotdbitmaps) + + ST_KEEPPEACE * keeppeace + + 0 + ); + optPacket.flags = htonl(flags); + /* copy the keymap and make sure no ctrl chars are sent [BDyess] */ + for (i = 32; i < 128; i++) { + optPacket.keymap[i - 32] = + (myship->s_keymap[i] & 128) ? i : myship->s_keymap[i]; + } + /* bcopy(mystats->st_keymap+32, optPacket.keymap,96); */ + sendServerPacket((struct player_spacket *) & optPacket); +} + +static void +pickSocket(old) + int old; +{ + int newsocket; + struct socket_cpacket sockPack; +#ifdef RWATCH + nextSocket = old; +#else + newsocket = (getpid() & 32767); + if (ghoststart) + nextSocket = old; + while (newsocket < 2048 || newsocket == old) { + newsocket = (newsocket + 10687) & 32767; + } + sockPack.type = CP_SOCKET; + sockPack.socket = htonl(newsocket); + sockPack.version = (char) SOCKVERSION; + sockPack.udp_version = (char) UDPVERSION; + sendServerPacket((struct player_spacket *) & sockPack); + /* Did we get new socket # sent? */ + if (serverDead) + return; + nextSocket = newsocket; +#endif /* RWATCH */ +} + +static void +handleBadVersion(packet) + struct badversion_spacket *packet; +{ + switch (packet->why) { + case 0: + printf("Sorry, this is an invalid client version.\n"); + printf("You need a new version of the client code.\n"); + break; + default: + printf("Sorry, but you cannot play xtrek now.\n"); + printf("Try again later.\n"); + break; + } + EXIT(1); +} + +int +gwrite(fd, buf, bytes) + int fd; + char *buf; + register int bytes; +{ + long orig = bytes; + register long n; +#ifdef RECORDER + if (playback) /* pretend all is well */ + return (bytes); +#endif + while (bytes) { + n = sock_write(fd, buf, bytes); + if (n < 0) { + if (fd == udpSock) { + fprintf(stderr, "Tried to write %d, 0x%x, %d\n", + fd, (unsigned int) buf, bytes); + perror("write"); + printUdpInfo(); + } + return (-1); + } + bytes -= n; + buf += n; + } + return (orig); +} + +int +sock_read(sock, data, size) + int sock, size; + char *data; +{ +#ifdef RECORDER + if (playback) + return readRecorded(sock, data, size); +#endif + +#ifndef AMIGA + return read(sock, data, size); +#else +#ifdef DNET + return DNet_Read(sock, data, size); +#else + /* NET_SOCKETS code here */ + /* No idea if this works, old version had it: */ + return recv(sock, data, size, 0); +#endif /* DNET */ +#endif /* AMIGA */ +} + +static void +handleHostile(packet) + struct hostile_spacket *packet; +{ + register struct player *pl; + + SANITY_PNUM(packet->pnum); + + pl = &players[packet->pnum]; + if (pl->p_swar != packet->war || + pl->p_hostile != packet->hostile) { + /* FAT: prevent redundant player update & redraw */ + pl->p_swar = packet->war; + pl->p_hostile = packet->hostile; + /* updatePlayer[packet->pnum]=1; why? */ + redrawPlayer[packet->pnum] = 1; + } +} + +static void +handlePlyrLogin(packet) + struct plyr_login_spacket *packet; +{ + register struct player *pl; + + SANITY_PNUM(packet->pnum); + +#ifdef PLPROF + printf("Got handlPlyrLogin for %d\n", packet->pnum); +#endif /* PLPROF */ + updatePlayer[packet->pnum] |= ALL_UPDATE; + pl = &players[packet->pnum]; + + strcpy(pl->p_name, packet->name); + strcpy(pl->p_monitor, packet->monitor); + strcpy(pl->p_login, packet->login); + pl->p_stats.st_rank = packet->rank; + if (packet->pnum == me->p_no) { + /* This is me. Set some stats */ + if (lastRank == -1) { + if (loggedIn) { + lastRank = packet->rank; + } + } else { + if (lastRank != packet->rank) { + lastRank = packet->rank; + promoted = 1; + } + } + } +} + +static void +handleStats(packet) + struct stats_spacket *packet; +{ + register struct player *pl; + + SANITY_PNUM(packet->pnum); + +#ifdef PLPROF + printf("Got handleStats for %d\n", packet->pnum); +#endif /* PLPROF */ + updatePlayer[packet->pnum] |= LARGE_UPDATE; + if (infomapped && infotype == PLAYERTYPE && + ((struct player *) infothing)->p_no == packet->pnum) + infoupdate = 1; + pl = &players[packet->pnum]; + pl->p_stats.st_tkills = ntohl(packet->tkills); + pl->p_stats.st_tlosses = ntohl(packet->tlosses); + pl->p_stats.st_kills = ntohl(packet->kills); + pl->p_stats.st_losses = ntohl(packet->losses); + pl->p_stats.st_tticks = ntohl(packet->tticks); + pl->p_stats.st_tplanets = ntohl(packet->tplanets); + pl->p_stats.st_tarmsbomb = ntohl(packet->tarmies); + pl->p_stats.st_sbkills = ntohl(packet->sbkills); + pl->p_stats.st_sblosses = ntohl(packet->sblosses); + pl->p_stats.st_armsbomb = ntohl(packet->armies); + pl->p_stats.st_planets = ntohl(packet->planets); + pl->p_stats.st_maxkills = ntohl(packet->maxkills) / 100.0; + pl->p_stats.st_sbmaxkills = ntohl(packet->sbmaxkills) / 100.0; +} + +static void +handlePlyrInfo(packet) + struct plyr_info_spacket *packet; +{ + register struct player *pl; + static int lastship = -1; + + SANITY_PNUM(packet->pnum); + +#ifdef PLPROF + printf("Got PlyrInfo for %d\n", packet->pnum); +#endif /* PLPROF */ + updatePlayer[packet->pnum] |= ALL_UPDATE; + if (infomapped && infotype == PLAYERTYPE && + ((struct player *) infothing)->p_no == packet->pnum) + infoupdate = 1; + pl = &players[packet->pnum]; + pl->p_ship = getship(packet->shiptype); + if (packet->pnum == me->p_no && currentship != packet->shiptype) { + currentship = packet->shiptype; + /* sendOptionsPacket(); */ + } + pl->p_teami = mask_to_idx(packet->team); + pl->p_mapchars[0] = teaminfo[pl->p_teami].letter; + /* printf("team: %d, letter: %c\n",pl->p_teami,pl->p_mapchars[0]); */ + pl->p_mapchars[1] = shipnos[pl->p_no]; + if (me == pl && lastship != currentship) { + lastship = currentship; + redrawTstats(); + calibrate_stats(); + redrawStats(); /* tsh */ + } + redrawPlayer[packet->pnum] = 1; +} + +void +sendUpdatePacket(speed) + long speed; +{ + struct updates_cpacket packet; + + packet.type = CP_UPDATES; + timerDelay = speed; + packet.usecs = htonl(speed); + sendServerPacket((struct player_spacket *) & packet); +#ifdef DEBUG + printf("sent request for an update every %d microseconds (%d/sec)\n",speed,1000000/speed); +#endif +} + +static void +handlePlanetLoc(packet) + struct planet_loc_spacket *packet; +{ + struct planet *pl; + + SANITY_PLANNUM(packet->pnum); + + pl = &planets[packet->pnum]; + pl_update[packet->pnum].plu_x = pl->pl_x; + pl_update[packet->pnum].plu_y = pl->pl_y; + + if (pl_update[packet->pnum].plu_update != -1) { + pl_update[packet->pnum].plu_update = 1; + /* + printf("update: %s, old (%d,%d) new (%d,%d)\n", pl->pl_name, + pl->pl_x, pl->pl_y, ntohl(packet->x),ntohl(packet->y)); + */ + } else { + pl_update[packet->pnum].plu_update = 0; + pl_update[packet->pnum].plu_x = ntohl(packet->x); + pl_update[packet->pnum].plu_y = ntohl(packet->y); + } + pl->pl_x = ntohl(packet->x); + pl->pl_y = ntohl(packet->y); + strcpy(pl->pl_name, packet->name); + pl->pl_namelen = strlen(packet->name); + pl->pl_flags |= PLREDRAW; + if (infomapped && infotype == PLANETTYPE && + ((struct planet *) infothing)->pl_no == packet->pnum) + infoupdate = 1; + reinitPlanets = 1; + if (pl->pl_x > blk_gwidth) { + blk_gwidth = 200000; + blk_windgwidth = ((float) WINSIDE) / blk_gwidth; + } +#ifdef ROTATERACE + if (rotate) { + rotate_gcenter(&pl->pl_x, &pl->pl_y); + } +#endif +} + +#if 0 + +static void +handleReserved(packet) + struct reserved_spacket *packet; +{ + struct reserved_cpacket response; + +#ifndef RWATCH + encryptReservedPacket(packet, &response, serverName, me->p_no); + sendServerPacket((struct player_spacket *) & response); +#endif /* RWATCH */ +} + +#else + + +static void +handleReserved(packet) + struct reserved_spacket *packet; +{ +#ifdef AUTHORIZE + struct reserved_cpacket response; + + response.type = CP_RESERVED; + if (RSA_Client) { /* can use -o option for old blessing */ + warning(RSA_VERSION); + strncpy((char *)response.resp, RSA_VERSION, RESERVED_SIZE); + memcpy(response.data, packet->data, RESERVED_SIZE); + } else { +#if 0 + /* + if we ever go back to reserved.c checking, we'll reactivate this + code. However, our reserved.c module hasn't done any real + computation since paradise 1. + */ + encryptReservedPacket(packet, &response, serverName, me->p_no); +#else + memcpy(response.data, packet->data, 16); + memcpy(response.resp, packet->data, 16); +#endif + } + sendServerPacket((struct player_spacket *) & response); +#endif +} + +static void +handleRSAKey(packet) + struct rsa_key_spacket *packet; +{ +#ifdef AUTHORIZE + struct rsa_key_cpacket response; +#ifndef DNET + struct sockaddr_in saddr; +#endif + unsigned char *data; + int len; + +#ifdef GATEWAY + extern unsigned long netaddr; + extern int serv_port; +#endif + +#ifndef DNET +#ifdef GATEWAY + /* if we didn't get it from -H, go ahead and query the socket */ + if (netaddr == 0) { + len = sizeof(saddr); + if (getpeername(sock, (struct sockaddr *) & saddr, &len) < 0) { + perror("getpeername(sock)"); + exit(1); + } + } else { + saddr.sin_addr.s_addr = netaddr; + saddr.sin_port = htons(serv_port); + } +#else /* GATEWAY */ + /* query the socket to determine the remote host (ATM) */ + len = sizeof(saddr); + if (getpeername(sock, (struct sockaddr *) & saddr, &len) < 0) { + perror("getpeername(sock)"); + exit(1); + } +#endif /* GATEWAY */ + + data = packet->data; + bcopy(&saddr.sin_addr.s_addr, data, sizeof(saddr.sin_addr.s_addr)); + data += sizeof(saddr.sin_addr.s_addr); + bcopy(&saddr.sin_port, data, sizeof(saddr.sin_port)); +#else /* DNET */ + { + extern long netrek_server_addr; + extern unsigned short netrek_server_port; + + data = packet->data; + bcopy(&netrek_server_addr, data, sizeof(netrek_server_addr)); + data += sizeof(netrek_server_addr); + bcopy(&netrek_server_port, data, sizeof(netrek_server_port)); + } +#endif /* DNET */ + +#ifdef DEBUG + { + struct timeval start, end; + gettimeofday(&start, NULL); +#endif + rsa_black_box(response.resp, packet->data, + response.public, response.global); +#ifdef DEBUG + gettimeofday(&end, NULL); + printf("rsa_black_box took %d ms.\n", + (1000 * (end.tv_sec - start.tv_sec) + + (end.tv_usec - start.tv_usec) / 1000)); + } +#endif + response.type = CP_RSA_KEY; + + sendServerPacket((struct player_spacket *) & response); +#ifdef DEBUG + printf("RSA verification requested.\n"); +#endif +#endif /* AUTHORIZE */ +} + +#endif + +#ifdef INCLUDE_SCAN +static void +handleScan(packet) + struct scan_spacket *packet; +{ + struct player *pp; + + SANITY_PNUM(packet->pnum); + + if (packet->success) { + pp = &players[packet->pnum]; + pp->p_fuel = ntohl(packet->p_fuel); + pp->p_armies = ntohl(packet->p_armies); + pp->p_shield = ntohl(packet->p_shield); + pp->p_damage = ntohl(packet->p_damage); + pp->p_etemp = ntohl(packet->p_etemp); + pp->p_wtemp = ntohl(packet->p_wtemp); + informScan(packet->pnum); + } +} + +static void +informScan(p) + int p; +{ +} + +#endif /* INCLUDE_SCAN */ + +/* + * UDP stuff + */ +void +sendUdpReq(req) + int req; +{ + struct udp_req_cpacket packet; +#ifdef RWATCH + return; +#endif /* RWATCH */ + + packet.type = CP_UDP_REQ; + packet.request = req; + + if (req >= COMM_MODE) { + packet.request = COMM_MODE; + packet.connmode = req - COMM_MODE; + sendServerPacket((struct player_spacket *) & packet); + return; + } + if (req == COMM_UPDATE) { +#ifdef SHORT_PACKETS + if (recv_short) { /* not necessary */ +/* Let the client do the work, and not the network :-) */ + register int i; + for (i = 0; i < nplayers * ntorps; i++) + torps[i].t_status = TFREE; + + for (i = 0; i < nplayers * nplasmas; i++) + plasmatorps[i].pt_status = PTFREE; + + for (i = 0; i < nplayers; i++) { + players[i].p_ntorp = 0; + players[i].p_nplasmatorp = 0; + phasers[i].ph_status = PHFREE; + } + } +#endif + sendServerPacket((struct player_spacket *) & packet); + warning("Sent request for full update"); + return; + } + if (req == commModeReq) { + warning("Request is in progress, do not disturb"); + return; + } + if (req == COMM_UDP) { + /* open UDP port */ + if (openUdpConn() >= 0) { + UDPDIAG(("Bound to local port %d on fd %d\n", udpLocalPort, udpSock)); + } else { + UDPDIAG(("Bind to local port %d failed\n", udpLocalPort)); + commModeReq = COMM_TCP; + commStatus = STAT_CONNECTED; + commSwitchTimeout = 0; + if (udpWin) + udprefresh(UDP_STATUS); + warning("Unable to establish UDP connection"); + + return; + } + } + /* send the request */ + packet.type = CP_UDP_REQ; + packet.request = req; + packet.port = htonl(udpLocalPort); +#ifdef GATEWAY + if (!strcmp(serverName, gw_mach)) { + packet.port = htons(gw_serv_port); /* gw port that server should + call */ + UDPDIAG(("+ Telling server to contact us on %d\n", gw_serv_port)); + } +#endif +#ifdef USE_PORTSWAP + packet.connmode = CONNMODE_PORT; /* have him send his port */ +#else + packet.connmode = CONNMODE_PACKET; /* we get addr from packet */ +#endif + sendServerPacket((struct player_spacket *) & packet); + + /* update internal state stuff */ + commModeReq = req; + if (req == COMM_TCP) + commStatus = STAT_SWITCH_TCP; + else + commStatus = STAT_SWITCH_UDP; + commSwitchTimeout = 25; /* wait 25 updates (about five seconds) */ + + UDPDIAG(("Sent request for %s mode\n", (req == COMM_TCP) ? + "TCP" : "UDP")); + +#ifndef USE_PORTSWAP + if ((req == COMM_UDP) && recvUdpConn() < 0) { + UDPDIAG(("Sending TCP reset message\n")); + packet.request = COMM_TCP; + packet.port = 0; + commModeReq = COMM_TCP; + sendServerPacket((struct player_spacket *) & packet); + /* we will likely get a SWITCH_UDP_OK later; better ignore it */ + commModeReq = COMM_TCP; + commStatus = STAT_CONNECTED; + commSwitchTimeout = 0; + closeUdpConn(); + } +#endif + + if (udpWin) + udprefresh(UDP_STATUS); +} + +static void +handleUdpReply(packet) + struct udp_reply_spacket *packet; +{ + struct udp_req_cpacket response; + + UDPDIAG(("Received UDP reply %d\n", packet->reply)); + commSwitchTimeout = 0; + + response.type = CP_UDP_REQ; + + switch (packet->reply) { + case SWITCH_TCP_OK: + if (commMode == COMM_TCP) { + UDPDIAG(("Got SWITCH_TCP_OK while in TCP mode; ignoring\n")); + } else { + commMode = COMM_TCP; + commStatus = STAT_CONNECTED; + warning("Switched to TCP-only connection"); + closeUdpConn(); + UDPDIAG(("UDP port closed\n")); + if (udpWin) { + udprefresh(UDP_STATUS); + udprefresh(UDP_CURRENT); + } + } + break; + case SWITCH_UDP_OK: + if (commMode == COMM_UDP) { + UDPDIAG(("Got SWITCH_UDP_OK while in UDP mode; ignoring\n")); + } else { + /* the server is forcing UDP down our throat? */ + if (commModeReq != COMM_UDP) { + UDPDIAG(("Got unsolicited SWITCH_UDP_OK; ignoring\n")); + } else { +#ifdef USE_PORTSWAP + udpServerPort = ntohl(packet->port); +#ifdef nodef /* simulate calvin error */ + /* XXX TMP */ + udpServerPort = 3333; +#endif + if (connUdpConn() < 0) { + UDPDIAG(("Unable to connect, resetting\n")); + warning("Connection attempt failed"); + commModeReq = COMM_TCP; + commStatus = STAT_CONNECTED; + if (udpSock >= 0) + closeUdpConn(); + if (udpWin) { + udprefresh(UDP_STATUS); + udprefresh(UDP_CURRENT); + } + response.request = COMM_TCP; + response.port = 0; + goto send; + } +#else + /* this came down UDP, so we MUST be connected */ + /* (do the verify thing anyway just for kicks) */ +#endif + UDPDIAG(("Connected to server's UDP port\n")); + commStatus = STAT_VERIFY_UDP; + if (udpWin) + udprefresh(UDP_STATUS); + response.request = COMM_VERIFY; /* send verify request on UDP */ + response.port = 0; + commSwitchTimeout = 25; /* wait 25 updates */ +#ifdef USE_PORTSWAP + send: +#endif /* USE_PORTSWAP */ + sendServerPacket((struct player_spacket *) & response); + } + } + break; + case SWITCH_DENIED: + if (ntohs(packet->port)) { + UDPDIAG(("Switch to UDP failed (different version)\n")); + warning("UDP protocol request failed (bad version)"); + } else { + UDPDIAG(("Switch to UDP denied\n")); + warning("UDP protocol request denied"); + } + commModeReq = commMode; + commStatus = STAT_CONNECTED; + commSwitchTimeout = 0; + if (udpWin) + udprefresh(UDP_STATUS); + if (udpSock >= 0) + closeUdpConn(); + break; + case SWITCH_VERIFY: + UDPDIAG(("Received UDP verification\n")); + break; + default: + fprintf(stderr, "netrek: Got funny reply (%d) in UDP_REPLY packet\n", + packet->reply); + break; + } +} + +#define MAX_PORT_RETRY 10 +static int +openUdpConn() +{ +#ifndef DNET + struct sockaddr_in addr; + struct hostent *hp; + int attempts; + +#ifdef RECORDER + if (playback) + return 0; +#endif + if (udpSock >= 0) { + fprintf(stderr, "netrek: tried to open udpSock twice\n"); + return (0); /* pretend we succeeded (this could be bad) */ + } + if ((udpSock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("netrek: unable to create DGRAM socket"); + return (-1); + } +#ifdef nodef + set_udp_opts(udpSock); +#endif /* nodef */ + + if(UdpLocalPort == 0) { + UdpLocalPort = intDefault("baseUdpLocalPort", 0); + UDPDIAG(("using base port %d\n", UdpLocalPort)); + } + + addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_family = AF_INET; + + errno = 0; + udpLocalPort = (getpid() & 32767) + (random() % 256); + for (attempts = 0; attempts < MAX_PORT_RETRY; attempts++) { + if(UdpLocalPort){ + /* force UDP to be starting at a base address */ + udpLocalPort = UdpLocalPort + attempts; + } else while (udpLocalPort < 2048) { + udpLocalPort = (udpLocalPort + 10687) & 32767; + } +#ifdef GATEWAY + /* we need the gateway to know where to find us */ + if (!strcmp(serverName, gw_mach)) { + UDPDIAG(("+ gateway test: binding to %d\n", gw_local_port)); + udpLocalPort = gw_local_port; + } +#endif + addr.sin_port = htons(udpLocalPort); + if (bind(udpSock, (struct sockaddr *) & addr, sizeof(addr)) >= 0) + break; + } + if (attempts == MAX_PORT_RETRY) { + perror("netrek: bind"); + UDPDIAG(("Unable to find a local port to bind to\n")); + close(udpSock); + udpSock = -1; + return (-1); + } + UDPDIAG(("Local port is %d\n", udpLocalPort)); + if(UdpLocalPort) { + fprintf(stdout, "Local UDP port is %d\n", udpLocalPort); + } + + /* determine the address of the server */ + if (!serveraddr) { + if ((addr.sin_addr.s_addr = inet_addr(serverName)) == -1) { + if ((hp = gethostbyname(serverName)) == NULL) { + printf("Who is %s?\n", serverName); +#ifdef AUTOKEY + if (autoKey) + W_AutoRepeatOn(); +#endif + + EXIT(0); + } else { + addr.sin_addr.s_addr = *(long *) hp->h_addr; + } + } + serveraddr = addr.sin_addr.s_addr; + UDPDIAG(("Found serveraddr == 0x%x\n", (unsigned int) serveraddr)); + } + return (0); +#else /* DNET */ +#ifdef RECORDER + if (playback) + return 0; +#endif + return DNetOpenUDPConn(serverName); +#endif /* DNET */ +} + +#ifdef USE_PORTSWAP +static int +connUdpConn() +{ +#ifndef DNET + struct sockaddr_in addr; + int len; + +#ifdef RECORDER + if (playback) + return 0; +#endif + addr.sin_addr.s_addr = serveraddr; + addr.sin_family = AF_INET; + addr.sin_port = htons(udpServerPort); + + UDPDIAG(("Connecting to host 0x%x on port %d\n", serveraddr, udpServerPort)); + if (connect(udpSock, &addr, sizeof(addr)) < 0) { + fprintf(stderr, "Error %d: "); + perror("netrek: unable to connect UDP socket"); + printUdpInfo(); /* debug */ + return (-1); + } +#ifdef nodef + len = sizeof(addr); + if (getsockname(udpSock, &addr, &len) < 0) { + perror("netrek: unable to getsockname(UDP)"); + UDPDIAG(("Can't get our own socket; connection failed\n")); + close(udpSock); + udpSock = -1; + return -1; + } + printf("udpLocalPort %d, getsockname port %d\n", + udpLocalPort, addr.sin_port); +#endif + + return (0); +#endif /* DNET */ +} +#endif + +#ifndef USE_PORTSWAP +static int +recvUdpConn() +{ +#ifndef DNET + fd_set readfds; + struct timeval to; + struct sockaddr_in from; + int fromlen, res; + +#ifdef RECORDER + if (playback) + return 0; +#endif + bzero(&from, sizeof(from)); /* don't get garbage if really broken */ + + /* we patiently wait until the server sends a packet to us */ + /* (note that we silently eat the first one) */ + UDPDIAG(("Issuing recvfrom() call\n")); + printUdpInfo(); + fromlen = sizeof(from); + FD_ZERO(&readfds); + FD_SET(udpSock, &readfds); + to.tv_sec = 6; /* wait 3 seconds, then abort */ + to.tv_usec = 0; + if ((res = select(32, &readfds, 0, 0, &to)) <= 0) { + if (!res) { + UDPDIAG(("timed out waiting for response")); + warning("UDP connection request timed out"); + return (-1); + } else { + perror("select() before recvfrom()"); + return (-1); + } + } + if (recvfrom(udpSock, buf, BUFSIZ, 0, (struct sockaddr *) & from, &fromlen) < 0) { + perror("recvfrom"); + UDPDIAG(("recvfrom failed, aborting UDP attempt")); + return (-1); + } + if (from.sin_addr.s_addr != serveraddr) { + /* safe? */ + serveraddr = from.sin_addr.s_addr; + UDPDIAG(("Warning: from 0x%x, but server is 0x%x\n", + (unsigned int) from.sin_addr.s_addr, (unsigned int) serveraddr)); + } + if (from.sin_family != AF_INET) { + UDPDIAG(("Warning: not AF_INET (%d)\n", from.sin_family)); + } + udpServerPort = ntohs(from.sin_port); + UDPDIAG(("recvfrom() succeeded; will use server port %d\n", udpServerPort)); +#ifdef GATEWAY + if (!strcmp(serverName, gw_mach)) { + UDPDIAG(("+ actually, I'm going to use %d\n", gw_port)); + udpServerPort = gw_port; + from.sin_port = htons(udpServerPort); + } +#endif + + if (connect(udpSock, (struct sockaddr *) & from, sizeof(from)) < 0) { + perror("netrek: unable to connect UDP socket after recvfrom()"); + close(udpSock); + udpSock = -1; + return (-1); + } + return (0); +#else /* DNET */ +#ifdef RECORDER + if (playback) + return 0; +#endif + return DNetRecvUDPConn(); +#endif /* DNET */ +} +#endif + +int +closeUdpConn() +{ + V_UDPDIAG(("Closing UDP socket\n")); +#ifdef RECORDER + if (playback) + return 0; +#endif + +#ifdef DNET + DNetCloseUDP(); + return 0; +#else + if (udpSock < 0) { + fprintf(stderr, "netrek: tried to close a closed UDP socket\n"); + return (-1); + } + shutdown(udpSock, 2); + close(udpSock); + udpSock = -1; + return 0; +#endif /* DNET */ +} + +static void +printUdpInfo() +{ +#ifndef DNET + struct sockaddr_in addr; + int len; + + len = sizeof(addr); + if (getsockname(udpSock, (struct sockaddr *) & addr, &len) < 0) { +/* perror("printUdpInfo: getsockname");*/ + return; + } + UDPDIAG(("LOCAL: addr=0x%x, family=%d, port=%d\n", + (unsigned int) addr.sin_addr.s_addr, + addr.sin_family, ntohs(addr.sin_port))); + + if (getpeername(udpSock, (struct sockaddr *) & addr, &len) < 0) { +/* perror("printUdpInfo: getpeername");*/ + return; + } + UDPDIAG(("PEER : addr=0x%x, family=%d, port=%d\n", + (unsigned int) addr.sin_addr.s_addr, + addr.sin_family, ntohs(addr.sin_port))); +#endif +} + +static void +handleSequence(packet) + struct sequence_spacket *packet; +{ + static int recent_count = 0, recent_dropped = 0; + long newseq; + + drop_flag = 0; + if (chan != udpSock) + return; /* don't pay attention to TCP sequence #s */ + udpTotal++; + recent_count++; + + /* update percent display every 256 updates (~50 seconds usually) */ + if (!(udpTotal & 0xff)) + if (udpWin) + udprefresh(UDP_DROPPED); + + newseq = (long) ntohs(packet->sequence); +/* printf("read %d - ", newseq);*/ + + if (((unsigned short) sequence) > 65000 && + ((unsigned short) newseq) < 1000) { + /* we rolled, set newseq = 65536+sequence and accept it */ + sequence = ((sequence + 65536) & 0xffff0000) | newseq; + } else { + /* adjust newseq and do compare */ + newseq |= (sequence & 0xffff0000); + + if (!udpSequenceChk) { /* put this here so that turning seq check */ + sequence = newseq; /* on and off doesn't make us think we lost */ + return; /* a whole bunch of packets. */ + } + if (newseq > sequence) { + /* accept */ + if (newseq != sequence + 1) { + udpDropped += (newseq - sequence) - 1; + udpTotal += (newseq - sequence) - 1; /* want TOTAL packets */ + recent_dropped += (newseq - sequence) - 1; + recent_count += (newseq - sequence) - 1; + if (udpWin) + udprefresh(UDP_DROPPED); + UDPDIAG(("sequence=%ld, newseq=%ld, we lost some\n", + sequence, newseq)); + } + sequence = newseq; + } else { + /* reject */ + if (packet->type == SP_SC_SEQUENCE) { + V_UDPDIAG(("(ignoring repeat %ld)\n", newseq)); + } else { + UDPDIAG(("sequence=%ld, newseq=%ld, ignoring transmission\n", + sequence, newseq)); + } + /* + the remaining packets will be dropped and we shouldn't count + the SP_SEQUENCE packet either + */ + packets_received--; + drop_flag = 1; + } + } +/* printf("newseq %d, sequence %d\n", newseq, sequence);*/ + if (recent_count > UDP_RECENT_INTR) { + /* once a minute (at 5 upd/sec), report on how many were dropped */ + /* during the last UDP_RECENT_INTR updates */ + udpRecentDropped = recent_dropped; + recent_count = recent_dropped = 0; + if (udpWin) + udprefresh(UDP_DROPPED); + } +} + + +/* +static void dumpShip(shipp) +struct ship *shipp; +{ + printf("ship stats:\n"); + printf("phaser range = %d\n", shipp->s_phaserrange); + printf("max speed = %d\n", shipp->s_maxspeed); + printf("max shield = %d\n", shipp->s_maxshield); + printf("max damage = %d\n", shipp->s_maxdamage); + printf("max egntemp = %d\n", shipp->s_maxegntemp); + printf("max wpntemp = %d\n", shipp->s_maxwpntemp); + printf("max armies = %d\n", shipp->s_maxarmies); + printf("type = %d\n", shipp->s_type); + printf("torp speed = %d\n", shipp->s_torpspeed); + printf("letter = %c\n", shipp->s_letter); + printf("desig = %2.2s\n", shipp->s_desig); + printf("bitmap = %d\n\n", shipp->s_bitmap); +} +*/ + +static void +handleShipCap(packet) /* SP_SHIP_CAP */ + struct ship_cap_spacket *packet; +{ + struct shiplist *temp; + + /* + What are we supposed to do? + */ + + SANITY_SHIPNUM(ntohs(packet->s_type)); + + if (packet->operation) { /* remove ship from list */ + temp = shiptypes; + if (temp->ship->s_type == (int) ntohs(packet->s_type)) { + shiptypes = temp->next; + shiptypes->prev = NULL; + } + while (temp->next != NULL) { + if (temp->next->ship->s_type == (int) ntohs(packet->s_type)) { + temp = temp->next; + temp->prev->next = temp->next; + if (temp->next) + temp->next->prev = temp->prev; + free(temp->ship); + free(temp); + return; + } else { + temp = temp->next; + } + } + } + /* + Since we're adding the ship, we need to find out if we already have + that ship, and if so, replace it. + */ + + temp = shiptypes; + while (temp != NULL) { + if (temp->ship->s_type == (int) ntohs(packet->s_type)) { + temp->ship->s_type = ntohs(packet->s_type); + temp->ship->s_torpspeed = ntohs(packet->s_torpspeed); + temp->ship->s_phaserrange = ntohs(packet->s_phaserrange); + if (temp->ship->s_phaserrange < 200) /* backward + compatibility */ + temp->ship->s_phaserrange *= PHASEDIST / 100; + temp->ship->s_maxspeed = ntohl(packet->s_maxspeed); + temp->ship->s_maxfuel = ntohl(packet->s_maxfuel); + temp->ship->s_maxshield = ntohl(packet->s_maxshield); + temp->ship->s_maxdamage = ntohl(packet->s_maxdamage); + temp->ship->s_maxwpntemp = ntohl(packet->s_maxwpntemp); + temp->ship->s_maxegntemp = ntohl(packet->s_maxegntemp); + temp->ship->s_maxarmies = ntohs(packet->s_maxarmies); + temp->ship->s_letter = packet->s_letter; + temp->ship->s_desig[0] = packet->s_desig1; + temp->ship->s_desig[1] = packet->s_desig2; + temp->ship->s_bitmap = ntohs(packet->s_bitmap); + buildShipKeymap(temp->ship); +/*dumpShip(temp->ship);*/ + return; + } + temp = temp->next; + } + + /* + Not there, so we need to make a new entry in the list for it. + */ + temp = (struct shiplist *) malloc(sizeof(struct shiplist)); + temp->next = shiptypes; + temp->prev = NULL; + if (shiptypes) + shiptypes->prev = temp; + shiptypes = temp; + temp->ship = (struct ship *) malloc(sizeof(struct ship)); + temp->ship->s_type = ntohs(packet->s_type); + temp->ship->s_torpspeed = ntohs(packet->s_torpspeed); + temp->ship->s_phaserrange = ntohs(packet->s_phaserrange); + temp->ship->s_maxspeed = ntohl(packet->s_maxspeed); + temp->ship->s_maxfuel = ntohl(packet->s_maxfuel); + temp->ship->s_maxshield = ntohl(packet->s_maxshield); + temp->ship->s_maxdamage = ntohl(packet->s_maxdamage); + temp->ship->s_maxwpntemp = ntohl(packet->s_maxwpntemp); + temp->ship->s_maxegntemp = ntohl(packet->s_maxegntemp); + temp->ship->s_maxarmies = ntohs(packet->s_maxarmies); + temp->ship->s_letter = packet->s_letter; + temp->ship->s_desig[0] = packet->s_desig1; + temp->ship->s_desig[1] = packet->s_desig2; + temp->ship->s_bitmap = ntohs(packet->s_bitmap); + buildShipKeymap(temp->ship); +/* dumpShip(temp->ship);*/ +} + +static void +handleMotdPic(packet) /* SP_SHIP_CAP */ + struct motd_pic_spacket *packet; +{ + int x, y, page, width, height; + + x = ntohs(packet->x); + y = ntohs(packet->y); + width = ntohs(packet->width); + height = ntohs(packet->height); + page = ntohs(packet->page); + + newMotdPic(x, y, width, height, (char *) packet->bits, page); +} + +static void +handleStats2(packet) + struct stats_spacket2 *packet; +{ + struct stats2 *p; /* to hold packet's player's stats2 struct */ + + SANITY_PNUM(packet->pnum); + + updatePlayer[packet->pnum] |= LARGE_UPDATE; + if (infomapped && infotype == PLAYERTYPE && + ((struct player *) infothing)->p_no == packet->pnum) + infoupdate = 1; + p = &(players[packet->pnum].p_stats2); /* get player's stats2 struct */ + p->st_genocides = ntohl(packet->genocides); + p->st_tmaxkills = (float) ntohl(packet->maxkills) / 100.0; + p->st_di = (float) ntohl(packet->di) / 100.0; + p->st_tkills = (int) ntohl(packet->kills); + p->st_tlosses = (int) ntohl(packet->losses); + p->st_tarmsbomb = (int) ntohl(packet->armsbomb); + p->st_tresbomb = (int) ntohl(packet->resbomb); + p->st_tdooshes = (int) ntohl(packet->dooshes); + p->st_tplanets = (int) ntohl(packet->planets); + p->st_tticks = (int) ntohl(packet->tticks); + p->st_sbkills = (int) ntohl(packet->sbkills); + p->st_sblosses = (int) ntohl(packet->sblosses); + p->st_sbticks = (int) ntohl(packet->sbticks); + p->st_sbmaxkills = (float) ntohl(packet->sbmaxkills) / 100.0; + p->st_wbkills = (int) ntohl(packet->wbkills); + p->st_wblosses = (int) ntohl(packet->wblosses); + p->st_wbticks = (int) ntohl(packet->wbticks); + p->st_wbmaxkills = (float) ntohl(packet->wbmaxkills) / 100.0; + p->st_jsplanets = (int) ntohl(packet->jsplanets); + p->st_jsticks = (int) ntohl(packet->jsticks); + if (p->st_rank != (int) ntohl(packet->rank) || + p->st_royal != (int) ntohl(packet->royal)) { + p->st_rank = (int) ntohl(packet->rank); + p->st_royal = (int) ntohl(packet->royal); + updatePlayer[packet->pnum] |= ALL_UPDATE; + } +} + +static void +handleStatus2(packet) + struct status_spacket2 *packet; +{ + updatePlayer[me->p_no] |= LARGE_UPDATE; + if (infomapped && infotype == PLAYERTYPE && + ((struct player *) infothing)->p_no == me->p_no) + infoupdate = 1; + status2->tourn = packet->tourn; + status2->dooshes = ntohl(packet->dooshes); + status2->armsbomb = ntohl(packet->armsbomb); + status2->resbomb = ntohl(packet->resbomb); + status2->planets = ntohl(packet->planets); + status2->kills = ntohl(packet->kills); + status2->losses = ntohl(packet->losses); + status2->sbkills = ntohl(packet->sbkills); + status2->sblosses = ntohl(packet->sblosses); + status2->sbtime = ntohl(packet->sbtime); + status2->wbkills = ntohl(packet->wbkills); + status2->wblosses = ntohl(packet->wblosses); + status2->wbtime = ntohl(packet->wbtime); + status2->jsplanets = ntohl(packet->jsplanets); + status2->jstime = ntohl(packet->jstime); + status2->time = ntohl(packet->time); + status2->timeprod = ntohl(packet->timeprod); +} + +static void +handlePlanet2(packet) + struct planet_spacket2 *packet; +{ + SANITY_PLANNUM(packet->pnum); + + planets[packet->pnum].pl_owner = packet->owner; + planets[packet->pnum].pl_info = packet->info; + planets[packet->pnum].pl_flags = ntohl(packet->flags); + planets[packet->pnum].pl_timestamp = ntohl(packet->timestamp); + planets[packet->pnum].pl_armies = ntohl(packet->armies); + planets[packet->pnum].pl_flags |= PLREDRAW; + pl_update[packet->pnum].plu_update = 1; + pl_update[packet->pnum].plu_x = planets[packet->pnum].pl_x; + pl_update[packet->pnum].plu_y = planets[packet->pnum].pl_y; + if (infomapped && infotype == PLANETTYPE && + ((struct planet *) infothing)->pl_no == packet->pnum) + infoupdate = 1; +} + +static void +handleTerrainInfo2(pkt) + struct terrain_info_packet2 *pkt; +{ +#ifdef ZDIAG2 + fprintf( stderr, "Receiving terrain info packet\n" ); + fprintf( stderr, "Terrain dims: %d x %d\n", ntohs(pkt->xdim), ntohs(pkt->ydim) ); +#endif + received_terrain_info = TERRAIN_STARTED; + terrain_x = ntohs(pkt->xdim); + terrain_y = ntohs(pkt->ydim); +} + +static void +handleTerrain2(pkt) + struct terrain_packet2 *pkt; +{ + static int curseq = 0, totbytes = 0, done = 0; + int i, status; + unsigned long dlen; +#ifdef ZDIAG2 + static unsigned char sum = 0; + static unsigned numnz = 0; +#endif + static unsigned char *gzipTerrain = NULL, *orgTerrain = NULL; + +#ifdef ZDIAG2 + fprintf( stderr, "Receiving Terrain packet. This should be %d.\n", curseq+1 ); +#endif + + if( (done == TERRAIN_DONE) && (received_terrain_info == TERRAIN_STARTED ) ){ + /* receiving new terrain info */ + free( gzipTerrain ); + free( orgTerrain ); + free( terrainInfo ); + gzipTerrain = orgTerrain = NULL; + terrainInfo = NULL; + curseq = done = totbytes = 0; + } + + curseq++; + if( (curseq != pkt->sequence) || !(received_terrain_info) ){ + /* Should fill in a list of all packets missed */ + /* or request header packet from server */ + fprintf( stderr, "Blech! Received terrain packet before terrain_info\n" ); + return; + } +#ifdef ZDIAG2 + fprintf( stderr, "Receiving packet %d out of %d\n", curseq, pkt->total_pkts ); +#endif + if( !gzipTerrain ){ + gzipTerrain = (unsigned char *)malloc( pkt->total_pkts << 7 ); +#if defined(ZDIAG) || defined(ZDIAG2) + fprintf( stderr, "Allocating %d bytes for gzipTerrain.\n", pkt->total_pkts << 7 ); +#endif + /* another yukko constant */ + } + if( !orgTerrain ){ + orgTerrain = (unsigned char *)malloc( terrain_x*terrain_y ); + dlen = terrain_x * terrain_y; +#if defined(ZDIAG) || defined(ZDIAG2) + fprintf( stderr, "Allocating %d bytes for orgTerrain.\n", dlen ); +#endif + } + for( i = 0; i < pkt->length; i++ ){ +#ifdef ZDIAG2 + if( !(i%10) ){ + fprintf( stderr, "Params: %d, %d\n", ((curseq-1)<<7)+i, i ); + } +#endif + gzipTerrain[((curseq-1)<<7)+i] = pkt->terrain_type[i]; + } + totbytes += pkt->length; + if( curseq == pkt->total_pkts ){ +#if defined(ZDIAG) || defined(ZDIAG2) + status = uncompress( orgTerrain, &dlen, gzipTerrain, totbytes ); + if( status != Z_OK ){ + if( status == Z_BUF_ERROR ){ + fprintf( stderr, "Unable to uncompress -- Z_BUF_ERROR.\n" ); + } + if( status == Z_MEM_ERROR ){ + fprintf( stderr, "Unable to uncompress -- Z_MEM_ERROR.\n" ); + } + if( status = Z_DATA_ERROR ){ + fprintf( stderr, "Unable to uncompress -- Z_DATA_ERROR!\n" ); + } + } + else{ + fprintf( stderr, "Total zipped terrain received: %d bytes\n", totbytes ); + } +#else + uncompress( orgTerrain, &dlen, gzipTerrain, totbytes ); +#endif + terrainInfo = (struct t_unit *)malloc( dlen * sizeof( struct t_unit ) ); + for( i = 0; i < dlen; i++ ){ + terrainInfo[i].types = orgTerrain[i]; +#ifdef ZDIAG2 + sum |= orgTerrain[i]; + if( orgTerrain[i] != 0 ){ + numnz++; + } +#endif + } + done = received_terrain_info = TERRAIN_DONE; +#ifdef ZDIAG2 + fprintf( stderr, "Sum = %d, numnz = %d\n", sum, numnz ); +#endif + } +} + +static void +handleTempPack(packet) /* SP_SHIP_CAP */ + struct obvious_packet *packet; +{ + struct obvious_packet reply; + /* printf("New MOTD info available\n"); */ + erase_motd(); + reply.type = CP_ASK_MOTD; + sendServerPacket((struct player_spacket *) & reply); +} + +/* handlers for the extension1 packet */ + +int +compute_extension1_size(pkt) + char *pkt; +{ + if (pkt[0] != SP_PARADISE_EXT1) + return -1; + + switch (pkt[1]) { + case SP_PE1_MISSING_BITMAP: + return sizeof(struct pe1_missing_bitmap_spacket); + case SP_PE1_NUM_MISSILES: + return sizeof(struct pe1_num_missiles_spacket); + default: + return -1; + } +} + +static void +handleExtension1(packet) + struct paradiseext1_spacket *packet; +{ + switch (packet->subtype) { + case SP_PE1_MISSING_BITMAP: + { + struct pe1_missing_bitmap_spacket *pkt = + (struct pe1_missing_bitmap_spacket *) packet; + + newMotdPic(ntohs(pkt->x), + ntohs(pkt->y), + ntohs(pkt->width), + ntohs(pkt->height), + 0, + ntohs(pkt->page)); + } + break; + case SP_PE1_NUM_MISSILES: + me->p_totmissiles = ntohs(((struct pe1_num_missiles_spacket *) packet)->num); + /* printf("updated totmissiles to %d\n",me->p_totmissiles); */ + if (me->p_totmissiles < 0) + me->p_totmissiles = 0; /* SB/WB have -1 */ + break; + default: + printf("unknown paradise extension packet 1 subtype = %d\n", + packet->subtype); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sound.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,156 @@ +/* + * sound.c - Platform Independant Sound Support - July 1996 + * Sujal M. Patel (smpatel@umiacs.umd.edu) + * + * + * Copyright (c) 1994-1996, Sujal M. Patel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: sound.c,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ + */ + +#include <stdio.h> +#ifdef __STDC__ +#include <stdlib.h> +#endif +#include <unistd.h> +#include <sys/time.h> +#include <fcntl.h> +#include <signal.h> +#include <sys/stat.h> +#include "data.h" + + + +static int soundfd; +static char audioOK = 1; +static char sound_flags[20]; /* Sound Flag for sound 1-19 */ + + + +void init_sound () +{ + int i, pid, child,fd[2]; + char *argv[4]; + char filename[512]; +#ifdef linux + char *arch = "linux"; +#else +#ifdef __FreeBSD__ + char *arch = "freebsd"; +#else +#ifdef __NetBSD__ + char *arch = "netbsd"; +#else +#ifdef sun + char *arch = "sun"; +#else +#ifdef foo + char *arch = "foobar"; +#else + char *arch = "generic"; +#endif +#endif +#endif +#endif +#endif + + signal(SIGCHLD, SIG_IGN); + + if(unixSoundPath[0] == '?') { + audioOK = 0; + return; + }; + + /* Create a pipe, set the write end to close when we exec the sound server, + and set both (is the write end necessary?) ends to non-blocking */ + pipe(fd); + soundfd=fd[1]; + + if( !(child=fork()) ) { + close(fd[1]); + dup2(fd[0],STDIN_FILENO); + close(fd[0]); + sprintf (filename, "paradise.sndsrv.%s", arch); + argv[0] = filename; + argv[1] = unixSoundPath; + argv[2] = unixSoundDev; + argv[3] = NULL; + execvp(filename, argv); + fprintf (stderr, "Couldn't Execute Sound Server (paradise.sndsrv.%s)!\n", arch); + exit (0); + }; + close(fd[0]); + + sleep(1); + + if (kill(child, 0)) { + audioOK = 0; + close(soundfd); + }; + + for (i = 0; i < 19; i++) sound_flags[i] = 0; +} + +void play_sound (k) +int k; +{ + char c; + + c = k; + if ((playSounds) && (audioOK)) write (soundfd, &c, sizeof (c)); +} + + + +void maybe_play_sound (k) +int k; +{ + char c; + + if (sound_flags[k] & 1) return; + + sound_flags[k] |= 1; + + c = (unsigned char)(k); + if ((playSounds) && (audioOK)) write (soundfd, &c, sizeof (c)); +} + + + +void sound_completed (k) +int k; +{ + sound_flags[k] &= ~1; +} + + + +void kill_sound () +{ + char c; + + c = -1; + if ((playSounds) && (audioOK)) write (soundfd, &c, sizeof (c)); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sound.h Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,52 @@ +/* + * sound.h - Platform Independant Sound Support - July 1996 + * Sujal M. Patel (smpatel@umiacs.umd.edu) + * + * + * Copyright (c) 1994-1996, Sujal M. Patel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $Id: sound.h,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ + */ + + +#define SND_EXPLOSION 0 +#define SND_CLOAK 1 +#define SND_FIRETORP 2 +#define SND_PHASER 3 +#define SND_PLASMA 4 +#define SND_SHIELD 5 +#define SND_TORPHIT 6 +#define SND_EXP_SB 7 +#define SND_PARADISE 8 +#define SND_THERMAL 9 +#define SND_REDALERT 10 + +#ifdef __STDC__ +void init_sound (); /* Init Sound System */ +void play_sound (int k); /* Play a Sound */ +void maybe_play_sound (int k); /* Play sound if the last 'k' sound_completed */ +void sound_completed (int k); /* Complete a sound 'k' */ +void kill_sound (); /* Terminate a sound unpredictably :) */ +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/spopt.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,177 @@ +/* $Id: spopt.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */ + +#ifdef SHORT_PACKETS +/* + */ +#include "copyright.h" + +#include <stdio.h> +#include <ctype.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "packets.h" + +/* + * Refresh item i + */ + +void +sprefresh(i) + int i; +{ + char buf[BUFSIZ]; + + switch (i) { + + case SPK_VFIELD: + sprintf(buf, "%seceive variable and short packets", + recv_short ? "R" : "Don't r"); + break; + case SPK_MFIELD: + sprintf(buf, "%seceive messages", recv_mesg ? "R" : "Don't r"); + break; + case SPK_KFIELD: + sprintf(buf, "%seceive kill messages", recv_kmesg ? "R" : "Don't r"); + break; + case SPK_WFIELD: + sprintf(buf, "%seceive warning messages", recv_warn ? "R" : "Don't r"); + break; + case SPK_TFIELD: + sprintf(buf, "Receive threshold: %s_", recv_threshold_s); + break; + case SPK_WHYFIELD: + sprintf(buf, "%sdd why dead messages", why_dead ? "A" : "Don't a"); + break; + case SPK_DONE: + sprintf(buf, "Done"); + break; + } + + W_WriteText(spWin, 0, i, textColor, buf, strlen(buf), 0); +} + +void +spwindow() +{ + register int i; + + for (i = 0; i < SPK_NUMFIELDS; i++) + sprefresh(i); + + /* Map window */ + W_MapWindow(spWin); +} + +void +spdone() +{ + /* Unmap window */ + W_UnmapWindow(spWin); +} + +void +spaction(data) + W_Event *data; +{ + int v; + register int i; + register char *cp; + + switch (data->y) { + + case SPK_VFIELD: + if (data->type == W_EV_BUTTON) { + if (recv_short) + sendShortReq(SPK_VOFF); + else + sendShortReq(SPK_VON); + } + break; + + case SPK_MFIELD: + if (data->type == W_EV_BUTTON) { + if (recv_mesg) + sendShortReq(SPK_MOFF); + else + sendShortReq(SPK_MON); + } + break; + + case SPK_KFIELD: + if (data->type == W_EV_BUTTON) { + if (recv_kmesg) + sendShortReq(SPK_M_NOKILLS); + else + sendShortReq(SPK_M_KILLS); + } + break; + + case SPK_WFIELD: + if (data->type == W_EV_BUTTON) { + if (recv_warn) + sendShortReq(SPK_M_NOWARN); + else + sendShortReq(SPK_M_WARN); + } + break; + + case SPK_TFIELD: + if (data->type == W_EV_KEY) { + switch (data->key) { + case '\b': + case '\177': + cp = recv_threshold_s; + i = strlen(cp); + if (i > 0) { + cp += i - 1; + *cp = '\0'; + } + break; + case '\025': + case '\030': + recv_threshold_s[0] = '\0'; + break; + + default: + if (data->key >= '0' && data->key <= '9') { + cp = recv_threshold_s; + i = strlen(cp); + if (i < 4) { + cp += i; + cp[1] = '\0'; + cp[0] = data->key; + } + } + break; + } + sprefresh(SPK_TFIELD); + } + break; + + case SPK_WHYFIELD: + if (F_feature_packets && data->type == W_EV_BUTTON) { + if (why_dead) + sendFeature("WHY_DEAD", 'S', 0, 0, 0); + else + sendFeature("WHY_DEAD", 'S', 1, 0, 0); + } + break; + case SPK_DONE: + + if (data->type == W_EV_BUTTON) { + if (sscanf(recv_threshold_s, "%d", &v) != 1) + strcpy(recv_threshold_s, "0"); + else if (recv_threshold != v) { + recv_threshold = v; + sendThreshold(recv_threshold); + } + spdone(); + } + break; + + } +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/starbitmaps.h Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,795 @@ +/* $Id: starbitmaps.h,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */ + +#define star_width 30 +#define star_height 30 +static unsigned char star_bitarray[][120] = { + { + 0x00, 0x20, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x10, 0x02, 0x00, 0x40, 0x30, 0x03, 0x00, 0x00, 0xfc, 0x0f, 0x00, + 0x00, 0x07, 0x1c, 0x00, 0x00, 0x0b, 0x30, 0x00, 0xf8, 0x09, 0x22, 0x00, + 0xc0, 0x18, 0x64, 0x1c, 0x40, 0x11, 0xcc, 0x17, 0x60, 0x03, 0x8c, 0x03, + 0x60, 0x00, 0x86, 0x00, 0x20, 0x04, 0x80, 0x00, 0x20, 0x18, 0xb8, 0x00, + 0x3c, 0x1e, 0xa0, 0x14, 0x7e, 0x00, 0x80, 0x06, 0x72, 0x02, 0xc4, 0x03, + 0x60, 0x40, 0xc8, 0x01, 0x40, 0x40, 0x70, 0x00, 0xc0, 0x40, 0xf0, 0x00, + 0xc0, 0x03, 0xd8, 0x00, 0x80, 0x77, 0xce, 0x03, 0x80, 0xfc, 0x07, 0x06, + 0xc0, 0x40, 0x00, 0x04, 0xc0, 0x60, 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x04, 0x00, + 0x00, 0x10, 0x02, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0xf8, 0x1f, 0x00, + 0x00, 0x06, 0x1c, 0x00, 0x18, 0x0f, 0x30, 0x00, 0xf8, 0x09, 0x26, 0x02, + 0xc0, 0x18, 0x66, 0x1d, 0x40, 0x11, 0xc8, 0x17, 0x60, 0x03, 0x88, 0x13, + 0x60, 0x00, 0x80, 0x00, 0x20, 0x00, 0x80, 0x00, 0x20, 0x0c, 0xb8, 0x00, + 0x3c, 0x1e, 0xa0, 0x10, 0x7e, 0x10, 0x80, 0x06, 0x72, 0x00, 0xc4, 0x03, + 0x62, 0x80, 0xc8, 0x01, 0x44, 0x80, 0x70, 0x00, 0xc0, 0x80, 0xf0, 0x00, + 0xc0, 0x03, 0xd8, 0x00, 0x80, 0x77, 0xce, 0x03, 0x80, 0xfc, 0x07, 0x02, + 0xc0, 0x40, 0x00, 0x00, 0x40, 0x60, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x10, 0x04, 0x00, + 0x00, 0x10, 0x02, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0xfc, 0x1f, 0x00, + 0x00, 0x06, 0x3c, 0x04, 0x1c, 0x0f, 0x30, 0x02, 0xf8, 0x09, 0x26, 0x02, + 0xc0, 0x18, 0x66, 0x1d, 0x40, 0x11, 0xc0, 0x17, 0x60, 0x03, 0x80, 0x11, + 0x60, 0x00, 0x80, 0x08, 0x20, 0x00, 0x80, 0x00, 0x20, 0x1c, 0xb8, 0x00, + 0x2c, 0x16, 0xa0, 0x10, 0x6e, 0x88, 0x80, 0x02, 0x72, 0x80, 0xc4, 0x03, + 0x62, 0x80, 0xc8, 0x01, 0x46, 0x00, 0x50, 0x00, 0xc4, 0x00, 0xf0, 0x00, + 0xc0, 0x03, 0xd8, 0x00, 0x80, 0x77, 0xce, 0x03, 0x80, 0xfc, 0x07, 0x06, + 0x80, 0x40, 0x00, 0x00, 0x40, 0x60, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x04, 0x00, + 0x00, 0x10, 0x02, 0x00, 0x00, 0x30, 0x43, 0x00, 0x00, 0xf8, 0x1f, 0x08, + 0x00, 0x06, 0x38, 0x04, 0x08, 0x0f, 0x32, 0x02, 0xf8, 0x09, 0x25, 0x02, + 0xc0, 0x18, 0x62, 0x19, 0x40, 0x11, 0xc0, 0x13, 0x60, 0x03, 0x80, 0x11, + 0x60, 0x00, 0x80, 0x08, 0x20, 0x00, 0x80, 0x04, 0x20, 0x00, 0xb8, 0x00, + 0x24, 0x1e, 0xa0, 0x18, 0x6e, 0x9c, 0x80, 0x00, 0x62, 0x80, 0xc4, 0x03, + 0x62, 0x82, 0xc8, 0x01, 0x46, 0xc0, 0x70, 0x00, 0xcc, 0x60, 0xf0, 0x00, + 0xd0, 0x23, 0xd8, 0x00, 0x80, 0x77, 0xce, 0x01, 0x80, 0xfc, 0x07, 0x06, + 0x80, 0x40, 0x02, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x10, 0x02, 0x00, 0x00, 0x30, 0x03, 0x08, 0x00, 0xf8, 0x1f, 0x00, + 0x00, 0x06, 0x38, 0x00, 0x00, 0x0f, 0x30, 0x00, 0xe0, 0x09, 0x20, 0x02, + 0xc0, 0x18, 0x60, 0x01, 0x40, 0x11, 0xc0, 0x13, 0x60, 0x03, 0x80, 0x11, + 0x60, 0x00, 0x80, 0x0c, 0x20, 0x00, 0x80, 0x06, 0x20, 0x00, 0xb8, 0x00, + 0x20, 0x1e, 0xa0, 0x0c, 0x66, 0x9e, 0x80, 0x00, 0x62, 0x80, 0xc0, 0x03, + 0x62, 0x80, 0xc0, 0x01, 0x46, 0xc0, 0x70, 0x00, 0xdc, 0x40, 0xf0, 0x00, + 0xf0, 0x03, 0xd8, 0x00, 0x80, 0x77, 0x8e, 0x01, 0x80, 0xfd, 0x07, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x00, + 0x00, 0x00, 0x04, 0x08, 0x00, 0x30, 0x01, 0x00, 0x00, 0xfc, 0x1f, 0x00, + 0x00, 0x07, 0x3c, 0x00, 0x00, 0x0f, 0x30, 0x00, 0xc0, 0x09, 0x66, 0x00, + 0xe0, 0x18, 0xe2, 0x01, 0x40, 0x11, 0xc0, 0x01, 0x60, 0x03, 0x80, 0x11, + 0x60, 0x00, 0x80, 0x16, 0x20, 0x00, 0x80, 0x07, 0x20, 0x10, 0xb8, 0x00, + 0x20, 0x1e, 0xa0, 0x06, 0x62, 0x9c, 0x80, 0x00, 0x60, 0x84, 0xc4, 0x03, + 0x62, 0x80, 0xc8, 0x01, 0x46, 0xc0, 0xf0, 0x00, 0xfc, 0x60, 0x70, 0x00, + 0xf0, 0x23, 0xd8, 0x00, 0x80, 0x77, 0x8e, 0x01, 0x00, 0xfd, 0x07, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x25, 0x10, + 0x00, 0x00, 0x21, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0xfc, 0x1f, 0x00, + 0x00, 0x06, 0x3c, 0x00, 0x00, 0x0f, 0x30, 0x00, 0xe0, 0x09, 0x60, 0x00, + 0xe0, 0x18, 0xe0, 0x01, 0x60, 0x11, 0xc0, 0x01, 0x60, 0x03, 0x80, 0x09, + 0x60, 0x00, 0x80, 0x13, 0x20, 0x00, 0x80, 0x03, 0x20, 0x38, 0xb8, 0x00, + 0x30, 0x3e, 0xa0, 0x03, 0x70, 0x38, 0x80, 0x01, 0x61, 0x02, 0xc1, 0x01, + 0x60, 0x00, 0xc2, 0x01, 0x44, 0x02, 0xe0, 0x00, 0xfc, 0x02, 0x70, 0x00, + 0xf0, 0x43, 0x58, 0x00, 0x40, 0xf7, 0x8e, 0x01, 0x00, 0xfe, 0x0f, 0x00, + 0x00, 0x10, 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x21, 0x00, + 0x00, 0x80, 0x20, 0x00, 0x00, 0xbc, 0x20, 0x00, 0x00, 0xfe, 0x1f, 0x00, + 0x00, 0x07, 0x3c, 0x00, 0x80, 0x0f, 0x34, 0x00, 0xf8, 0x09, 0x60, 0x00, + 0xe0, 0x18, 0xe0, 0x01, 0x60, 0x11, 0xc0, 0x01, 0x60, 0x03, 0x80, 0x01, + 0x60, 0x00, 0x80, 0x01, 0x30, 0x60, 0x80, 0x01, 0x38, 0x7c, 0xb8, 0x00, + 0x30, 0x3e, 0xa0, 0x03, 0x60, 0x10, 0x80, 0x01, 0x60, 0x02, 0xc1, 0x01, + 0x60, 0x00, 0xc2, 0x01, 0x40, 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x70, 0x00, + 0xf0, 0x03, 0xd8, 0x00, 0x40, 0xf7, 0x9f, 0x00, 0x00, 0xfe, 0x0f, 0x00, + 0x00, 0x90, 0x06, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x90, 0x04, 0x00, 0x00, 0xb0, 0x26, 0x00, 0x00, 0xfe, 0x27, 0x00, + 0x00, 0x07, 0x3c, 0x00, 0x80, 0x0f, 0x30, 0x00, 0xf0, 0x09, 0x60, 0x00, + 0xe0, 0x18, 0xe0, 0x06, 0x60, 0x11, 0xc0, 0x06, 0x60, 0x03, 0x80, 0x00, + 0x60, 0x00, 0x83, 0x01, 0x20, 0xc0, 0x81, 0x00, 0x38, 0xdc, 0xb8, 0x00, + 0x3c, 0x1e, 0xa0, 0x02, 0x70, 0x10, 0x80, 0x03, 0x60, 0x02, 0xc4, 0x01, + 0x60, 0x00, 0xc8, 0x01, 0x60, 0x04, 0xe0, 0x00, 0xf0, 0x04, 0x70, 0x00, + 0xc0, 0x07, 0xd8, 0x00, 0xc0, 0x77, 0x8e, 0x01, 0x40, 0xfc, 0x07, 0x00, + 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x04, 0x00, + 0x00, 0x10, 0x04, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 0xfc, 0x07, 0x00, + 0x00, 0x07, 0x1c, 0x00, 0x80, 0x0f, 0x30, 0x00, 0xf0, 0x09, 0x20, 0x00, + 0xc0, 0x18, 0x60, 0x1a, 0x60, 0x11, 0xc4, 0x06, 0x60, 0x03, 0x8c, 0x00, + 0x20, 0x00, 0x86, 0x01, 0x20, 0x00, 0x83, 0x00, 0x3c, 0x18, 0xb8, 0x00, + 0x3e, 0x1e, 0xa0, 0x1c, 0x70, 0x10, 0x80, 0x06, 0x60, 0x02, 0xc4, 0x03, + 0x60, 0x20, 0xc8, 0x01, 0x40, 0x20, 0x60, 0x00, 0xc0, 0x20, 0xf0, 0x00, + 0x80, 0x03, 0xd8, 0x00, 0x80, 0x77, 0x9c, 0x03, 0xc0, 0xfc, 0x07, 0x00, + 0xc0, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + } +}; + +#define wormhole_width 80 +#define wormhole_height 80 +static unsigned char wormhole_bitarray[][867] = {{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x84, 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x80, 0x05, 0x00, 0x00, 0x00, 0x00, 0x04, 0x90, + 0x00, 0xa7, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x96, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0xe0, 0x10, 0x22, 0x07, 0x90, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x06, 0x00, 0x00, 0xc0, 0x30, 0x08, 0x00, 0x00, 0x04, + 0x84, 0xc1, 0x00, 0x00, 0x00, 0x73, 0x04, 0x00, 0x20, 0x00, 0x43, 0x52, + 0x25, 0x00, 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x30, 0x8b, 0x14, 0x02, + 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x20, 0x01, 0x00, 0x72, + 0x00, 0x00, 0x80, 0x10, 0x48, 0x63, 0xe4, 0x51, 0x00, 0x5c, 0x00, 0x04, + 0x00, 0x00, 0x06, 0x00, 0x05, 0x0e, 0x00, 0xa4, 0x00, 0x00, 0x10, 0x00, + 0xc1, 0x55, 0x41, 0x01, 0x25, 0x28, 0x81, 0x04, 0x00, 0x40, 0x3e, 0x2d, + 0xf4, 0x47, 0x01, 0x70, 0x03, 0x00, 0x00, 0x80, 0x90, 0x04, 0x7e, 0x71, + 0x28, 0x60, 0x03, 0x00, 0x00, 0x50, 0x01, 0x10, 0x33, 0x18, 0x41, 0x70, + 0x0c, 0x00, 0x00, 0xa2, 0x00, 0xc0, 0x84, 0x10, 0x5a, 0x60, 0x0a, 0x00, + 0x00, 0x60, 0x00, 0x20, 0x20, 0x02, 0x08, 0x60, 0x08, 0x28, 0x00, 0x50, + 0x10, 0x0f, 0x00, 0xa2, 0x60, 0x60, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x04, + 0x00, 0xc8, 0x40, 0x50, 0x20, 0x00, 0x00, 0x08, 0x50, 0x0a, 0x00, 0x40, + 0xa3, 0x20, 0x20, 0x40, 0x00, 0x20, 0x50, 0x09, 0x20, 0xc0, 0x04, 0xe1, + 0x00, 0x00, 0x00, 0x00, 0xd8, 0x01, 0x00, 0x83, 0x01, 0x40, 0x40, 0x10, + 0x04, 0x0c, 0xca, 0x04, 0x98, 0x00, 0x03, 0xc8, 0xa5, 0x00, 0x00, 0x00, + 0xa2, 0x00, 0xd7, 0x03, 0x02, 0x60, 0x02, 0x04, 0x00, 0x02, 0x05, 0xcd, + 0xef, 0x0f, 0x04, 0x24, 0xc0, 0x00, 0x00, 0x01, 0x68, 0x06, 0xfa, 0x03, + 0x04, 0x04, 0x84, 0x40, 0x00, 0x02, 0x62, 0xa0, 0x1c, 0x20, 0x04, 0x7c, + 0x80, 0x40, 0x40, 0xc4, 0x78, 0xe8, 0x06, 0x40, 0x00, 0x08, 0x86, 0x00, + 0x00, 0x06, 0xf4, 0x74, 0x03, 0x80, 0x06, 0x38, 0x80, 0x00, 0x00, 0x41, + 0xa0, 0x88, 0x00, 0x00, 0x84, 0x48, 0x40, 0x03, 0x80, 0xa3, 0x14, 0x83, + 0x01, 0x00, 0x03, 0x30, 0x02, 0x01, 0x80, 0x80, 0x70, 0x40, 0x01, 0x00, + 0x06, 0x18, 0x06, 0x09, 0x50, 0x20, 0x35, 0x20, 0x00, 0x00, 0x01, 0x18, + 0x12, 0x01, 0x00, 0x41, 0x1c, 0x80, 0x01, 0x00, 0x05, 0x1c, 0x01, 0x03, + 0x00, 0x80, 0x17, 0x20, 0x01, 0x00, 0x43, 0x16, 0x03, 0x0b, 0x00, 0x51, + 0x11, 0xa2, 0x02, 0x80, 0x42, 0x0d, 0x03, 0x03, 0x90, 0xab, 0x23, 0xa0, + 0x03, 0x80, 0x80, 0x0d, 0x80, 0x00, 0x90, 0xc2, 0x09, 0x00, 0x07, 0x00, + 0xb8, 0x88, 0x82, 0x04, 0x00, 0x61, 0x20, 0xa0, 0x05, 0x80, 0x70, 0x4c, + 0xc0, 0x00, 0x80, 0x73, 0x21, 0x60, 0x37, 0x50, 0x0e, 0x0c, 0x00, 0x02, + 0xc0, 0xa2, 0x28, 0x60, 0x47, 0x6f, 0x01, 0x60, 0x04, 0x00, 0x80, 0xc4, + 0x08, 0x40, 0x0e, 0x60, 0x82, 0x02, 0x00, 0x01, 0x20, 0x34, 0xc0, 0x04, + 0x2e, 0x26, 0x00, 0x3a, 0x48, 0x01, 0x44, 0xd6, 0x84, 0x00, 0x12, 0x00, + 0x00, 0x20, 0x00, 0x20, 0x80, 0xe8, 0x09, 0x01, 0x74, 0x01, 0x01, 0x00, + 0x20, 0x00, 0x10, 0x68, 0x02, 0x03, 0x58, 0x00, 0x00, 0x15, 0x00, 0x84, + 0x00, 0xb0, 0x04, 0x05, 0xa0, 0x01, 0x40, 0x06, 0x18, 0x04, 0x00, 0x10, + 0x10, 0x02, 0x50, 0x02, 0x20, 0x03, 0x04, 0x00, 0x00, 0xa0, 0x04, 0x34, + 0x81, 0x09, 0x30, 0x00, 0x08, 0x00, 0x00, 0xa2, 0x0f, 0x40, 0x01, 0x11, + 0x02, 0x08, 0x00, 0x01, 0x08, 0x00, 0x83, 0x68, 0x03, 0xa5, 0x03, 0x00, + 0x04, 0x80, 0x00, 0x10, 0x00, 0x60, 0x3c, 0x7c, 0x00, 0x00, 0x02, 0x00, + 0x10, 0x80, 0x00, 0xc0, 0x91, 0x5d, 0x06, 0x00, 0x48, 0x00, 0x48, 0x50, + 0x06, 0x04, 0x01, 0x80, 0x3f, 0x00, 0x05, 0x08, 0x00, 0x00, 0x02, 0x00, + 0x2f, 0x00, 0xe8, 0x0f, 0x02, 0x02, 0x00, 0x00, 0x82, 0x00, 0x24, 0x00, + 0x00, 0xbc, 0x02, 0x00, 0x00, 0x80, 0x98, 0x00, 0x60, 0x0a, 0x00, 0x28, + 0x00, 0x00, 0x00, 0x10, 0x60, 0x20, 0xc1, 0xe5, 0x06, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x48, 0x00, 0xa0, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x05, 0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0x42, 0x01, 0x25, + 0x00, 0x58, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x02, 0x40, + 0x30, 0x09, 0x02, 0x00, 0x00, 0x00, 0x00, 0x68, 0x02, 0x00, 0x0c, 0x01, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1d, 0x71, 0x21, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0xa0, 0xe0, 0x1b, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0xb0, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x80, 0x02, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x60, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x58, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x14, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x40, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x01, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x3f, 0xca, + 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0xe1, 0xa0, 0x01, 0x84, 0x2d, 0x00, + 0x40, 0x00, 0x00, 0x10, 0x00, 0x18, 0x00, 0x80, 0x64, 0x60, 0x01, 0x00, + 0x00, 0x00, 0x02, 0x67, 0x1a, 0x00, 0xc8, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x41, 0xa9, 0x00, 0x80, 0x01, 0x04, 0x00, 0x00, 0x00, 0xc0, 0x28, + 0x90, 0x04, 0x80, 0x07, 0x00, 0x00, 0x40, 0x00, 0x14, 0x40, 0x04, 0x02, + 0x00, 0x08, 0x12, 0x00, 0x00, 0x00, 0xe8, 0x1c, 0x80, 0x44, 0x00, 0x10, + 0x80, 0x00, 0x00, 0x20, 0x0d, 0x53, 0x51, 0x1e, 0x00, 0x68, 0x04, 0x00, + 0x00, 0x00, 0x16, 0xc9, 0x16, 0x00, 0x01, 0xe0, 0x0a, 0x01, 0x00, 0x00, + 0x0e, 0x40, 0x40, 0xf4, 0x04, 0xb0, 0x81, 0x00, 0x00, 0x80, 0x02, 0x00, + 0x61, 0x1f, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x80, 0x00, 0xb2, 0x7f, + 0x50, 0xc0, 0x07, 0x00, 0x00, 0x40, 0x00, 0x18, 0xa5, 0x01, 0x17, 0x42, + 0x04, 0x00, 0x20, 0x00, 0x81, 0x60, 0x00, 0xc4, 0x03, 0x80, 0x0a, 0x01, + 0x00, 0x10, 0x80, 0x32, 0x00, 0x81, 0x48, 0x81, 0x13, 0x50, 0x00, 0x20, + 0xe0, 0x4a, 0x00, 0x10, 0x10, 0x02, 0x1b, 0x00, 0x00, 0x08, 0x68, 0x27, + 0x00, 0x10, 0xc1, 0x82, 0x1b, 0x20, 0x00, 0x04, 0x08, 0x03, 0x00, 0x40, + 0x46, 0x00, 0x03, 0x00, 0x00, 0x08, 0x94, 0x12, 0x80, 0x00, 0x03, 0x03, + 0x73, 0x80, 0x00, 0x00, 0x20, 0x04, 0x20, 0x0c, 0x0f, 0x81, 0x43, 0x80, + 0x00, 0x8c, 0x85, 0x39, 0x5f, 0x0a, 0x92, 0x42, 0x21, 0x00, 0x00, 0x02, + 0xf0, 0x00, 0xfe, 0x07, 0x06, 0x84, 0xa1, 0x22, 0x00, 0x87, 0xe8, 0x40, + 0xf5, 0x0f, 0x0c, 0x80, 0x80, 0x80, 0xa0, 0x41, 0xc1, 0xd9, 0xf9, 0x1f, + 0x04, 0x80, 0x83, 0x00, 0x00, 0x00, 0x29, 0xe9, 0x0c, 0x00, 0x08, 0x10, + 0x01, 0x00, 0x00, 0x21, 0x61, 0x16, 0x07, 0x40, 0x08, 0xc0, 0x8b, 0x01, + 0x00, 0x40, 0x74, 0x00, 0x01, 0x80, 0x08, 0xc8, 0x44, 0x21, 0x10, 0x81, + 0x1d, 0x40, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x90, 0x5b, 0x17, 0x20, + 0x01, 0x00, 0x0e, 0x78, 0x88, 0x09, 0x80, 0xa3, 0x11, 0x80, 0x00, 0x00, + 0x04, 0x88, 0x00, 0x01, 0xc0, 0xe0, 0x01, 0xa2, 0x01, 0x00, 0x83, 0x38, + 0x06, 0x01, 0xe0, 0x39, 0x04, 0xb0, 0x01, 0x00, 0x06, 0x48, 0x80, 0x40, + 0x40, 0xb1, 0x10, 0xd0, 0x01, 0x00, 0x01, 0x30, 0x80, 0x40, 0x10, 0x52, + 0x10, 0x80, 0x01, 0x80, 0x07, 0x18, 0x42, 0x01, 0x10, 0x62, 0x14, 0xd0, + 0x03, 0xc0, 0x01, 0x1c, 0x06, 0x83, 0xa0, 0x0d, 0x04, 0xb0, 0x02, 0x40, + 0x21, 0x0f, 0x01, 0x01, 0x04, 0x32, 0x10, 0xb0, 0x1b, 0x00, 0xa0, 0x8a, + 0x80, 0x04, 0x00, 0x7a, 0x21, 0x91, 0x11, 0x40, 0xcc, 0x86, 0x81, 0x01, + 0x00, 0x9c, 0x22, 0x80, 0xc3, 0x17, 0x5c, 0x86, 0x81, 0x01, 0x00, 0x2c, + 0x40, 0x80, 0x0b, 0x98, 0x17, 0x07, 0x80, 0x05, 0x01, 0x04, 0xc1, 0x80, + 0x84, 0x19, 0x00, 0x93, 0x40, 0x00, 0x40, 0x94, 0xa2, 0x00, 0x0d, 0x88, + 0x00, 0x02, 0x20, 0x00, 0x00, 0xf0, 0x40, 0x00, 0x4f, 0x00, 0xa0, 0x18, + 0x30, 0x01, 0x00, 0x62, 0x81, 0x02, 0x04, 0x20, 0x80, 0x00, 0x81, 0x00, + 0x10, 0x00, 0x10, 0x24, 0x3a, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x09, + 0x00, 0x2d, 0x40, 0x00, 0x00, 0x04, 0x41, 0x00, 0x00, 0x64, 0x00, 0x6c, + 0x30, 0x01, 0xa0, 0x00, 0x28, 0x00, 0x00, 0x20, 0x00, 0x46, 0x20, 0x00, + 0xcc, 0x02, 0x00, 0x00, 0x00, 0x20, 0x40, 0xdc, 0x53, 0x20, 0x66, 0x00, + 0x04, 0x04, 0x80, 0x09, 0x08, 0x10, 0xc9, 0x3b, 0x00, 0x00, 0x03, 0x20, + 0x00, 0x80, 0x09, 0x30, 0xd8, 0x07, 0x80, 0x40, 0x80, 0x00, 0x10, 0x40, + 0x07, 0xe0, 0x02, 0x25, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, + 0x01, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0c, 0x08, 0x03, 0xe0, + 0x03, 0x40, 0x10, 0x00, 0x04, 0x00, 0x28, 0x00, 0x56, 0x40, 0x03, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x7c, 0x48, 0x00, 0x08, + 0x00, 0x00, 0xe8, 0x00, 0x00, 0x17, 0x60, 0x20, 0x00, 0x00, 0x00, 0x02, + 0xa0, 0x08, 0x00, 0x20, 0xc0, 0x15, 0x40, 0x00, 0x80, 0x00, 0x00, 0x09, + 0x60, 0x00, 0x00, 0x11, 0x10, 0x00, 0x00, 0x08, 0x80, 0x15, 0x00, 0x05, + 0xc8, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x62, 0x00, 0x01, 0x0d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x47, 0xd0, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0xee, 0x35, 0x24, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x04, 0x08, 0x01, 0x80, 0x04, 0x08, 0x04, 0x00, 0x00, 0x08, 0x00, 0x40, + 0x04, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x24, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x80, 0x01, 0x81, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, + 0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 0x00, 0x20, 0x00, + 0x00, 0x00, 0xc4, 0xc0, 0x18, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, + 0x00, 0x78, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, + 0xe0, 0x12, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x6e, 0x0d, + 0x20, 0x24, 0x00, 0x00, 0x00, 0x20, 0x00, 0xe0, 0x11, 0x80, 0x02, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1c, 0x82, 0x71, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x21, 0x06, 0x70, 0x04, 0x80, 0x04, 0x00, 0x00, + 0x24, 0x0d, 0x0c, 0x04, 0x90, 0x08, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xf0, + 0x01, 0x12, 0x00, 0x0d, 0x08, 0x00, 0x00, 0x00, 0xe0, 0x20, 0xca, 0x90, + 0x00, 0x08, 0x04, 0x10, 0x20, 0x00, 0x50, 0x80, 0x28, 0x00, 0x00, 0x38, + 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0xec, 0x4a, 0x04, 0x30, 0x20, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x02, 0xe0, 0x80, 0x40, 0x00, 0x00, + 0x09, 0x08, 0x10, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x84, + 0x80, 0x57, 0x12, 0x80, 0x41, 0x00, 0x00, 0x60, 0x00, 0x14, 0x77, 0xfd, + 0x4d, 0x00, 0x02, 0x0a, 0x00, 0x24, 0x40, 0x96, 0x01, 0xba, 0x03, 0x00, + 0x66, 0x00, 0x00, 0x20, 0x40, 0x79, 0x02, 0x80, 0x00, 0x00, 0x67, 0x00, + 0x04, 0x40, 0x20, 0x38, 0x01, 0x28, 0xa8, 0x00, 0x0a, 0x00, 0x00, 0x68, + 0x00, 0x14, 0x00, 0x00, 0xbe, 0x02, 0x1a, 0x04, 0x00, 0x1c, 0xac, 0x82, + 0x00, 0x80, 0x04, 0x10, 0x3e, 0x00, 0x00, 0x15, 0x42, 0x56, 0x00, 0x40, + 0x40, 0x02, 0x2a, 0x40, 0x00, 0x00, 0xa3, 0xe3, 0x00, 0x04, 0x85, 0x08, + 0x1a, 0x00, 0x00, 0x04, 0x82, 0x03, 0xbc, 0x01, 0x10, 0x13, 0x0c, 0x00, + 0x20, 0x80, 0x92, 0x07, 0x79, 0x31, 0x1c, 0x09, 0x5c, 0x00, 0x20, 0x83, + 0x44, 0x52, 0x55, 0x0e, 0x14, 0x04, 0xee, 0x40, 0x80, 0x27, 0xe9, 0xe5, + 0xe3, 0x1f, 0x2c, 0x04, 0x6c, 0x00, 0x00, 0xab, 0x7f, 0x08, 0xfd, 0x1f, + 0x4c, 0x06, 0x0e, 0x00, 0xe0, 0x81, 0x29, 0x00, 0x0a, 0x7c, 0x18, 0x08, + 0xa6, 0x81, 0x40, 0xe1, 0x13, 0x80, 0x03, 0x00, 0x10, 0x08, 0x87, 0x00, + 0x51, 0x39, 0x01, 0x40, 0x02, 0x00, 0x00, 0x00, 0x81, 0x00, 0x10, 0xb2, + 0x24, 0x02, 0x00, 0x80, 0x10, 0x00, 0x01, 0x01, 0x80, 0xf1, 0x10, 0xa0, + 0x01, 0x80, 0x18, 0x20, 0x07, 0x05, 0xa0, 0x2d, 0x12, 0x50, 0x01, 0x00, + 0x01, 0x00, 0x01, 0x41, 0x02, 0x05, 0x0a, 0x50, 0x01, 0x00, 0x0c, 0x88, + 0x07, 0x00, 0x00, 0x1d, 0x02, 0xc8, 0x01, 0x00, 0x05, 0x48, 0x14, 0x00, + 0x08, 0xbe, 0x08, 0xe8, 0x01, 0x00, 0x03, 0x38, 0x40, 0x01, 0x00, 0x0b, + 0x11, 0x58, 0x01, 0x80, 0x83, 0x48, 0x00, 0x01, 0x2c, 0x00, 0x90, 0xe8, + 0x01, 0x80, 0x00, 0x18, 0x80, 0x20, 0x00, 0x43, 0x10, 0xc8, 0x06, 0xc0, + 0x02, 0x20, 0x82, 0x08, 0x00, 0x2c, 0x30, 0xc0, 0x00, 0xa0, 0x00, 0x38, + 0x84, 0x00, 0x84, 0x38, 0x10, 0xe0, 0x09, 0x20, 0x10, 0x0e, 0xc0, 0x00, + 0x00, 0x78, 0x30, 0x20, 0xe2, 0x12, 0x10, 0x07, 0x41, 0x40, 0x40, 0x02, + 0x00, 0x40, 0x81, 0x0e, 0xa3, 0x87, 0x21, 0x20, 0x00, 0x01, 0xa2, 0xc0, + 0x63, 0x66, 0xb6, 0xc1, 0xc0, 0x00, 0x10, 0x0c, 0x80, 0x80, 0x0a, 0x96, + 0x96, 0x61, 0x44, 0x20, 0x00, 0x04, 0x20, 0x45, 0x01, 0x20, 0x80, 0x60, + 0x60, 0x00, 0x88, 0x04, 0x80, 0x05, 0x07, 0x00, 0xc0, 0x48, 0x20, 0x00, + 0x00, 0x08, 0x88, 0x06, 0x08, 0x08, 0xc4, 0x2c, 0x60, 0x00, 0x00, 0x90, + 0x80, 0x09, 0x06, 0x00, 0x10, 0x01, 0xb0, 0x00, 0x28, 0xe4, 0x00, 0x33, + 0x12, 0x00, 0x10, 0x03, 0x28, 0x00, 0x90, 0x20, 0x00, 0x71, 0x22, 0x00, + 0xc0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x86, 0x08, 0x80, 0x84, 0x20, + 0x24, 0x00, 0x80, 0xc2, 0x10, 0x2e, 0xbd, 0x44, 0x08, 0x00, 0x10, 0x00, + 0x00, 0x40, 0x81, 0x10, 0x78, 0x63, 0x2e, 0x20, 0x00, 0x00, 0x14, 0x80, + 0x01, 0x10, 0x40, 0x00, 0x04, 0x00, 0x05, 0x00, 0x40, 0x00, 0x0e, 0x30, + 0x40, 0x03, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x01, 0xe8, 0x80, 0x03, + 0x08, 0x08, 0x00, 0x00, 0x08, 0x00, 0x4c, 0x20, 0x01, 0x0e, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x10, 0x48, 0x00, 0x08, 0x1a, 0x00, 0x08, 0x04, 0x02, + 0x00, 0x00, 0x18, 0x00, 0x30, 0x30, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x84, 0x01, 0xc1, 0xc1, 0x01, 0x03, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x10, 0x80, 0x1f, 0x34, 0x00, + 0x47, 0x02, 0x00, 0x00, 0x00, 0x10, 0x20, 0x3c, 0x01, 0x00, 0xd5, 0x11, + 0x40, 0x00, 0x00, 0x00, 0x00, 0xc5, 0x07, 0x34, 0x42, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x10, 0xe8, 0x23, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x1c, 0x49, 0x00, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x03, 0x30, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x00, 0xc4, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x20, 0xc8, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa0, 0x18, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x80, 0x20, 0xca, 0xfa, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0x05, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x18, 0x61, 0x02, 0x00, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x5e, 0x86, 0x58, 0x20, 0x0c, 0x20, 0x00, 0x00, 0x00, + 0x80, 0x0c, 0x3c, 0xc1, 0x60, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0xc0, 0x00, 0x44, 0x08, 0x00, 0x00, 0x00, 0x10, 0x01, 0x10, 0x19, + 0x02, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x80, 0x13, 0x03, 0x82, + 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x28, 0x1c, 0x90, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x40, 0x00, 0xa0, 0x00, 0xb0, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x54, 0x09, 0x80, 0x04, 0x80, 0x01, 0x00, 0x00, 0xe4, 0x03, 0xb7, + 0x31, 0x40, 0x6c, 0x80, 0x01, 0x00, 0x00, 0xe8, 0x00, 0x84, 0x9e, 0x7e, + 0x30, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x60, 0xe1, 0x13, 0xc0, 0x03, 0x00, + 0x83, 0x00, 0x00, 0x20, 0x10, 0x84, 0x18, 0xd0, 0x6f, 0x01, 0x0c, 0x02, + 0x84, 0x00, 0x00, 0x12, 0x04, 0x80, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x0c, + 0x12, 0x9e, 0x00, 0x40, 0x11, 0x00, 0x18, 0x84, 0x00, 0x1e, 0x00, 0x9e, + 0x03, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0xa8, 0x10, 0x0f, 0x01, 0x00, + 0xf0, 0x05, 0x30, 0x02, 0x84, 0x87, 0x25, 0x09, 0x50, 0x00, 0xb2, 0x16, + 0x38, 0x19, 0xa0, 0x85, 0xbc, 0xc3, 0xe5, 0x12, 0x00, 0x00, 0xb8, 0x01, + 0x20, 0xc0, 0xd7, 0x11, 0xdf, 0x05, 0x14, 0x41, 0x68, 0x42, 0x0c, 0xe4, + 0x47, 0x00, 0x8e, 0x51, 0x10, 0x02, 0x58, 0x00, 0x40, 0x63, 0x00, 0x00, + 0xf8, 0x1f, 0x70, 0x24, 0xf8, 0x70, 0x00, 0x68, 0x69, 0x00, 0xb4, 0x3f, + 0x10, 0x2c, 0x88, 0x00, 0x00, 0x46, 0x00, 0xc0, 0x05, 0x38, 0x70, 0x20, + 0xa0, 0x00, 0x00, 0x19, 0x14, 0x00, 0x06, 0xf0, 0x18, 0x08, 0xb8, 0x00, + 0x00, 0x3e, 0x1a, 0x20, 0x01, 0x00, 0x90, 0x08, 0xbc, 0x00, 0x30, 0xaf, + 0x00, 0x30, 0x01, 0x00, 0x30, 0x04, 0x98, 0x00, 0x00, 0x28, 0x08, 0x40, + 0x01, 0x80, 0x10, 0x08, 0xdc, 0x00, 0x01, 0x01, 0x18, 0xc8, 0x01, 0x00, + 0x30, 0x10, 0x0c, 0x80, 0x42, 0x04, 0x08, 0xec, 0x00, 0x00, 0x10, 0x00, + 0xc5, 0x21, 0x00, 0x0c, 0x50, 0xec, 0x01, 0x00, 0x09, 0x00, 0x85, 0x01, + 0x20, 0x1c, 0x08, 0xec, 0x00, 0x00, 0x06, 0x20, 0x81, 0x00, 0x40, 0x21, + 0x1c, 0xe0, 0x00, 0x80, 0x05, 0x28, 0x47, 0x00, 0x00, 0x00, 0x18, 0x60, + 0x03, 0x00, 0x01, 0xc8, 0x01, 0x01, 0x04, 0x02, 0x00, 0xf0, 0x00, 0x40, + 0x03, 0xc4, 0x83, 0x04, 0x40, 0x01, 0x08, 0x40, 0x00, 0x60, 0x40, 0x1c, + 0x88, 0x40, 0x00, 0x01, 0x20, 0xd0, 0x19, 0x58, 0x00, 0x34, 0x00, 0x80, + 0x00, 0x02, 0x08, 0x70, 0xa0, 0x00, 0x00, 0x0e, 0xe0, 0x00, 0x0c, 0x06, + 0x70, 0xa1, 0x88, 0x06, 0x00, 0x00, 0x82, 0x00, 0x10, 0x25, 0xb1, 0xf1, + 0x92, 0x41, 0x04, 0x9f, 0x21, 0x00, 0x00, 0x1c, 0xb0, 0x91, 0xc0, 0xdd, + 0xe0, 0x03, 0x61, 0x10, 0x00, 0x04, 0x60, 0x01, 0x01, 0xf4, 0xec, 0x01, + 0x20, 0x82, 0x02, 0x08, 0x60, 0x43, 0x01, 0x04, 0xe3, 0x20, 0x10, 0x40, + 0x00, 0x08, 0x20, 0xce, 0x00, 0x00, 0x20, 0x78, 0x14, 0x00, 0x00, 0x28, + 0xc2, 0x42, 0x02, 0x00, 0x38, 0x08, 0x10, 0x08, 0x04, 0x18, 0xc8, 0x90, + 0x00, 0x80, 0x18, 0x8c, 0x38, 0x08, 0x80, 0xa0, 0x08, 0xb2, 0x00, 0x00, + 0x02, 0x09, 0x08, 0x00, 0x00, 0xb0, 0x00, 0xc1, 0x07, 0x00, 0x01, 0x04, + 0x04, 0x00, 0x00, 0x40, 0x00, 0x83, 0x5f, 0x00, 0x64, 0x00, 0x26, 0x00, + 0x00, 0x40, 0x80, 0x03, 0x34, 0x46, 0x18, 0x00, 0x06, 0x00, 0x00, 0x60, + 0x02, 0x0f, 0x04, 0xc0, 0x08, 0x82, 0x16, 0x00, 0x00, 0x60, 0x01, 0x38, + 0x3c, 0xe0, 0x02, 0x60, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x30, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x80, 0x00, 0x08, 0xc0, 0x60, 0x00, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x1c, 0x88, 0xc1, 0x40, 0x00, 0x28, 0x00, 0x00, + 0x00, 0x80, 0x7c, 0x08, 0xc6, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0x20, 0x04, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x10, 0x15, 0x84, + 0x00, 0x06, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0e, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x0c, 0x0c, 0x20, + 0x01, 0x00, 0x00, 0x00, 0x10, 0x80, 0xd7, 0x14, 0x01, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x13, 0xc0, 0x5e, 0x0f, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x23, 0x22, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x20, 0x20, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x18, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x40, 0x00, 0x28, 0xc0, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x88, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0xfb, + 0x46, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x50, 0x65, 0x80, 0x0e, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xc5, 0xc8, 0x38, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x06, 0x80, 0xc1, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, + 0xc8, 0x24, 0x80, 0x25, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x08, 0x19, 0x00, 0x00, 0x00, 0x00, 0x40, 0x48, 0x00, 0x10, 0x06, + 0x18, 0x44, 0x01, 0x02, 0x00, 0x80, 0x2e, 0x00, 0x10, 0x10, 0x19, 0x8c, + 0x01, 0x00, 0x00, 0x00, 0x08, 0x40, 0x0c, 0x78, 0x02, 0x40, 0x00, 0x00, + 0x00, 0x08, 0x01, 0x12, 0x97, 0xc0, 0x20, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x66, 0x88, 0x11, 0x06, 0xc0, 0x0d, 0x00, 0x00, 0xe0, 0xc0, 0x00, + 0x4c, 0x03, 0x4a, 0x81, 0x80, 0x00, 0x20, 0xc0, 0x90, 0x00, 0x5c, 0x3a, + 0x40, 0x00, 0x0d, 0x00, 0x00, 0x7c, 0xc1, 0xb8, 0x84, 0xa1, 0x43, 0x00, + 0x08, 0x20, 0x00, 0x34, 0x01, 0xf2, 0xa4, 0x00, 0x8a, 0x05, 0x0c, 0x20, + 0x20, 0x11, 0x3e, 0x70, 0x00, 0x80, 0x3c, 0x01, 0x08, 0x00, 0x00, 0x91, + 0xe9, 0x5d, 0x1c, 0x00, 0x7c, 0x01, 0x08, 0x00, 0x00, 0x8c, 0xdf, 0x6f, + 0x10, 0x00, 0x60, 0x03, 0x18, 0x08, 0x02, 0x80, 0x19, 0x0f, 0x44, 0x00, + 0xea, 0x0a, 0x18, 0x00, 0x20, 0xbc, 0x85, 0x41, 0xd4, 0x01, 0x80, 0x10, + 0x30, 0x04, 0x01, 0x94, 0x21, 0x00, 0x9f, 0x0b, 0x00, 0x00, 0x20, 0x00, + 0x10, 0x7c, 0x80, 0x00, 0x38, 0x5b, 0x88, 0x05, 0x20, 0x08, 0x01, 0x7e, + 0x48, 0x00, 0x00, 0x0e, 0xc0, 0x12, 0x40, 0xc0, 0x00, 0x52, 0x25, 0x08, + 0xea, 0xcb, 0x00, 0x08, 0x50, 0x10, 0x04, 0x53, 0x00, 0x00, 0x0a, 0x7e, + 0x41, 0x04, 0xc0, 0x08, 0x40, 0x4c, 0x01, 0x40, 0x0c, 0x78, 0x80, 0x04, + 0x70, 0x00, 0x21, 0x44, 0x10, 0x20, 0x02, 0x70, 0xe0, 0x04, 0x20, 0x26, + 0x00, 0x3c, 0x10, 0x80, 0x03, 0xe0, 0x30, 0x58, 0xc0, 0x86, 0x40, 0x91, + 0x10, 0xc8, 0x00, 0x80, 0xf0, 0x50, 0xb0, 0x04, 0x02, 0x00, 0x08, 0xfc, + 0x01, 0x00, 0xa0, 0x60, 0xc0, 0x00, 0x20, 0x03, 0x1c, 0xec, 0x00, 0x00, + 0xb0, 0x18, 0x50, 0x21, 0xa0, 0x02, 0x14, 0xf4, 0x00, 0x00, 0x30, 0x1c, + 0x70, 0x20, 0x00, 0x80, 0x00, 0x70, 0x00, 0x80, 0x00, 0x00, 0xb0, 0x00, + 0x01, 0x01, 0x04, 0x30, 0x01, 0x80, 0x10, 0x08, 0xb8, 0x00, 0x08, 0x03, + 0x10, 0x78, 0x03, 0x00, 0x08, 0x08, 0xdc, 0x00, 0x40, 0x08, 0x14, 0x28, + 0x00, 0x00, 0x02, 0x00, 0xce, 0x00, 0x04, 0x8e, 0x18, 0x60, 0x00, 0x80, + 0x02, 0x00, 0x06, 0x00, 0x10, 0x01, 0xdc, 0x38, 0x04, 0xa0, 0x00, 0x90, + 0xa3, 0x20, 0x00, 0x01, 0x6c, 0x60, 0x08, 0x14, 0x00, 0x94, 0x80, 0x10, + 0x01, 0x02, 0x48, 0x3c, 0x72, 0x76, 0x00, 0x82, 0x41, 0x00, 0x01, 0x01, + 0x58, 0xa0, 0x84, 0x11, 0x10, 0xf2, 0x20, 0x00, 0x00, 0x45, 0xcc, 0x60, + 0x60, 0x00, 0x00, 0x97, 0x81, 0x00, 0x80, 0x00, 0x88, 0x19, 0x30, 0x02, + 0x81, 0x09, 0x42, 0x01, 0x00, 0x16, 0x19, 0x11, 0x00, 0x96, 0x81, 0x02, + 0x22, 0x41, 0x00, 0x00, 0x00, 0x08, 0x80, 0x35, 0xe0, 0x00, 0x00, 0x20, + 0x00, 0x08, 0x60, 0x52, 0x20, 0xa0, 0x7f, 0xa3, 0x08, 0x20, 0x00, 0x0e, + 0x30, 0x58, 0x00, 0x00, 0x3d, 0x60, 0x30, 0x20, 0x00, 0x52, 0x28, 0x38, + 0x00, 0x00, 0x1e, 0x00, 0x0c, 0x00, 0x00, 0x12, 0x28, 0x70, 0x00, 0x10, + 0x07, 0x04, 0x0c, 0x00, 0x08, 0x60, 0xf0, 0x40, 0x01, 0x80, 0x83, 0x0f, + 0x46, 0x1a, 0x00, 0xc0, 0x80, 0x02, 0x06, 0x20, 0xc1, 0x81, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x60, 0xf0, 0x01, 0x98, 0x18, 0x00, 0x08, 0x00, 0xe0, + 0x00, 0xc0, 0x21, 0x44, 0x02, 0x00, 0x03, 0x04, 0x00, 0x40, 0x47, 0x84, + 0x01, 0x8f, 0x00, 0x80, 0x82, 0x00, 0x10, 0xa8, 0xc3, 0x08, 0x03, 0x86, + 0x00, 0x40, 0x80, 0x00, 0x00, 0x80, 0x00, 0x11, 0x06, 0x00, 0x10, 0x60, + 0x02, 0x00, 0x00, 0x00, 0xb9, 0x20, 0x06, 0x00, 0x00, 0x7c, 0x40, 0x00, + 0x00, 0x00, 0x70, 0x02, 0x04, 0x02, 0x00, 0xa6, 0x00, 0x00, 0x00, 0x40, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, + 0x10, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x0c, 0x30, 0x80, + 0x12, 0x05, 0x01, 0x00, 0x00, 0x02, 0xc0, 0x70, 0x30, 0x00, 0x86, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x53, 0xb0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xb0, 0x40, 0x7c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x00, 0x40, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x03, + 0x01, 0x0a, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x40, 0x24, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x41, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x82, 0x00, 0x01, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x54, 0x23, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xa0, 0x60, 0xcb, 0x02, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x10, 0x18, 0xc0, 0x04, 0x00, + 0x00, 0x00, 0xf1, 0x0f, 0x00, 0x30, 0xe0, 0x01, 0x04, 0x00, 0x00, 0x80, + 0x81, 0x05, 0x00, 0x30, 0xb8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x80, 0x14, 0x86, 0x00, 0x00, 0x00, 0x02, 0x0e, 0x00, 0x08, 0x82, + 0x25, 0x28, 0x00, 0x00, 0x00, 0x40, 0x0e, 0x20, 0x8e, 0x80, 0x60, 0x28, + 0x00, 0x00, 0x00, 0xc0, 0x0f, 0x1c, 0x74, 0x00, 0x03, 0x01, 0x08, 0x00, + 0x00, 0x48, 0x11, 0x09, 0x05, 0x89, 0x13, 0x02, 0x00, 0x00, 0x10, 0x88, + 0x21, 0x05, 0xd4, 0x08, 0xa4, 0x43, 0x00, 0x00, 0x00, 0xa8, 0x60, 0x05, + 0xc1, 0x17, 0x0d, 0x40, 0x00, 0x00, 0x0a, 0x60, 0x3c, 0x21, 0x6f, 0x39, + 0x20, 0x06, 0x10, 0x00, 0x00, 0x00, 0xfc, 0x4b, 0x2f, 0x88, 0xb1, 0x00, + 0x04, 0x00, 0x08, 0xf0, 0xc9, 0xee, 0x23, 0x05, 0xc5, 0x0c, 0x04, 0x00, + 0x00, 0x01, 0x1c, 0x78, 0x62, 0x00, 0x3c, 0x04, 0x0e, 0x01, 0x10, 0xf8, + 0x05, 0x4c, 0xc0, 0x00, 0x10, 0x02, 0x44, 0x00, 0x00, 0xc0, 0x01, 0x00, + 0x09, 0x00, 0x64, 0x06, 0x08, 0x20, 0x00, 0x4d, 0x21, 0x00, 0x12, 0x00, + 0xf0, 0x3d, 0x60, 0x00, 0x00, 0x11, 0x95, 0x01, 0x78, 0x02, 0xe0, 0x00, + 0x48, 0x00, 0x00, 0x18, 0x44, 0x00, 0x60, 0x0e, 0x08, 0x07, 0x20, 0x00, + 0x8c, 0x18, 0x00, 0x00, 0xe0, 0x3c, 0xa0, 0x0b, 0x20, 0x00, 0x08, 0x7a, + 0x20, 0x00, 0x6a, 0x28, 0x01, 0x22, 0x20, 0x00, 0x00, 0x60, 0x21, 0x80, + 0x91, 0x2f, 0x20, 0x40, 0x60, 0x00, 0x40, 0x03, 0x00, 0xc0, 0x10, 0x1c, + 0x10, 0x07, 0x60, 0x20, 0x84, 0x01, 0x98, 0x10, 0x05, 0xfc, 0x03, 0x0d, + 0x40, 0x08, 0x00, 0x00, 0x18, 0x98, 0x02, 0xf0, 0x22, 0x20, 0x80, 0x18, + 0x08, 0x81, 0x1c, 0xf8, 0x03, 0xe0, 0xc0, 0x00, 0x40, 0x00, 0x40, 0x01, + 0x00, 0xec, 0x01, 0xc0, 0x00, 0x48, 0xa0, 0x30, 0x00, 0x01, 0x00, 0xf0, + 0x01, 0x80, 0xe1, 0x05, 0x00, 0x00, 0x00, 0x0f, 0x0a, 0xf0, 0x00, 0x00, + 0xa0, 0x20, 0x81, 0x20, 0x00, 0x41, 0x10, 0x38, 0x00, 0x00, 0xb0, 0x18, + 0xe0, 0x08, 0x80, 0x01, 0x1c, 0xb0, 0x01, 0x80, 0xb0, 0x10, 0xa0, 0x04, + 0x80, 0x01, 0x0c, 0x14, 0x01, 0x80, 0xb0, 0x60, 0x80, 0x06, 0x80, 0x00, + 0x36, 0x34, 0x01, 0x80, 0x10, 0x08, 0xb0, 0x24, 0x90, 0x03, 0x14, 0x1c, + 0x00, 0x80, 0x18, 0x0a, 0xe8, 0x04, 0x00, 0x31, 0x06, 0x16, 0x02, 0x00, + 0x0c, 0x00, 0x80, 0x81, 0x80, 0x05, 0x12, 0x04, 0x04, 0x40, 0x01, 0x00, + 0xb8, 0x00, 0x00, 0x44, 0x26, 0x2c, 0x15, 0xf8, 0x01, 0x04, 0x5e, 0x70, + 0x00, 0x03, 0x76, 0x12, 0x00, 0x4f, 0x00, 0x00, 0x5e, 0x00, 0x80, 0x03, + 0x00, 0x04, 0x78, 0x1c, 0x00, 0x40, 0x67, 0x00, 0x41, 0x01, 0x58, 0x03, + 0x1c, 0x00, 0x00, 0x44, 0x63, 0x40, 0x00, 0x0e, 0xc4, 0x00, 0x20, 0x00, + 0x84, 0xe1, 0x20, 0x00, 0x00, 0x04, 0x05, 0x06, 0xa0, 0x02, 0xc0, 0x60, + 0x20, 0x00, 0x00, 0x08, 0x04, 0x1b, 0xa4, 0x67, 0xc0, 0x5c, 0x30, 0x00, + 0x00, 0x08, 0x1e, 0x0f, 0x00, 0x06, 0x70, 0x29, 0x18, 0x14, 0x80, 0x0c, + 0x00, 0x0e, 0x00, 0xf4, 0x48, 0x23, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x1c, + 0x00, 0xa0, 0x5f, 0x60, 0x10, 0x20, 0x80, 0x13, 0x00, 0x60, 0x00, 0xc0, + 0x4e, 0x00, 0x0c, 0x10, 0x00, 0x38, 0x24, 0x04, 0x00, 0xc1, 0x03, 0x12, + 0x20, 0x00, 0x00, 0x20, 0x44, 0x18, 0x06, 0x7a, 0x00, 0x04, 0x03, 0x40, + 0x00, 0x10, 0xc0, 0x18, 0x06, 0x13, 0xc0, 0x00, 0x02, 0x09, 0x00, 0x80, + 0x09, 0x18, 0x00, 0x00, 0xf8, 0x80, 0x00, 0x00, 0x00, 0x02, 0x02, 0x39, + 0x30, 0x94, 0x1d, 0xc0, 0x00, 0x02, 0x00, 0x00, 0x00, 0x30, 0x70, 0x2c, + 0x88, 0x20, 0x04, 0x00, 0x00, 0x30, 0x04, 0x20, 0x00, 0x05, 0x82, 0x10, + 0x30, 0x00, 0x00, 0x00, 0x11, 0x60, 0x10, 0x00, 0x00, 0x18, 0x80, 0x00, + 0x00, 0x00, 0x72, 0x40, 0x00, 0x80, 0x00, 0x1c, 0x80, 0x00, 0x00, 0x40, + 0xc0, 0x81, 0x00, 0x00, 0x00, 0x03, 0x60, 0x00, 0x00, 0x00, 0x22, 0xc4, + 0x01, 0x40, 0xa8, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, + 0x98, 0x11, 0x00, 0x00, 0x00, 0x80, 0x82, 0x41, 0x01, 0x0a, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x80, 0x00, 0xc0, 0x00, 0x6a, 0x51, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x04, 0x8a, 0x02, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x80, 0x88, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x88, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x86, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0x00, + 0x0e, 0x01, 0x41, 0x00, 0x43, 0x00, 0x00, 0x00, 0x20, 0x7c, 0x22, 0x70, + 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x98, 0x0e, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x80, 0xa4, 0x01, 0x81, 0x0a, 0x06, 0x01, 0x00, + 0x00, 0x40, 0xda, 0x01, 0x00, 0x00, 0xb2, 0x00, 0x40, 0x00, 0x00, 0x11, + 0xfd, 0x01, 0x00, 0x00, 0x84, 0x10, 0x00, 0x00, 0x00, 0x80, 0x30, 0x80, + 0x04, 0x00, 0x06, 0x05, 0x02, 0x00, 0x80, 0x00, 0x10, 0x27, 0xe5, 0x01, + 0x54, 0x14, 0x28, 0x00, 0x00, 0x10, 0x1e, 0x80, 0x00, 0x60, 0x10, 0x3b, + 0x18, 0x00, 0x80, 0x04, 0x44, 0x86, 0x50, 0x1f, 0xd4, 0x22, 0x01, 0x00, + 0x00, 0x10, 0xeb, 0x53, 0x44, 0x00, 0x10, 0xa0, 0x00, 0x00, 0x0c, 0x00, + 0x98, 0x1e, 0x12, 0x1d, 0x20, 0x8a, 0x08, 0x00, 0x20, 0x80, 0x6f, 0xee, + 0x78, 0x8c, 0x38, 0x80, 0x02, 0x00, 0x00, 0x48, 0x0f, 0x61, 0xff, 0xbe, + 0x41, 0x39, 0x02, 0x00, 0x40, 0x2a, 0x0a, 0xc0, 0x33, 0x81, 0x09, 0x0a, + 0x00, 0x00, 0x50, 0x80, 0x08, 0x28, 0x1b, 0x48, 0x80, 0x10, 0x80, 0x00, + 0x00, 0x44, 0xac, 0x11, 0x00, 0x23, 0x0c, 0x00, 0x04, 0x00, 0x04, 0xe8, + 0x14, 0x06, 0x08, 0x07, 0x08, 0x31, 0x4a, 0x00, 0x84, 0xc0, 0x01, 0x02, + 0xc8, 0x00, 0x60, 0x06, 0x00, 0x00, 0x08, 0x8c, 0x84, 0x80, 0x20, 0x00, + 0xe0, 0x60, 0x80, 0x01, 0x00, 0x0a, 0x80, 0x00, 0xc0, 0x0b, 0xa0, 0x50, + 0x20, 0x00, 0x10, 0x00, 0x80, 0x00, 0x80, 0x19, 0x80, 0x19, 0x30, 0x00, + 0x08, 0x02, 0x60, 0x00, 0x08, 0x33, 0xc0, 0x17, 0x78, 0x00, 0x80, 0x02, + 0x31, 0x02, 0xd3, 0x39, 0x20, 0xb3, 0x00, 0x05, 0x11, 0x02, 0x10, 0xa0, + 0x68, 0xb7, 0x00, 0x0e, 0xa0, 0x00, 0x00, 0x0a, 0x28, 0x30, 0x0b, 0xdc, + 0x82, 0x16, 0x20, 0x01, 0x00, 0x01, 0x00, 0x78, 0x05, 0x38, 0x00, 0x34, + 0x00, 0x00, 0x02, 0x41, 0x14, 0xc0, 0x07, 0xe0, 0x61, 0x40, 0x80, 0x40, + 0x80, 0x01, 0x10, 0x60, 0x01, 0xe0, 0x03, 0x02, 0xc0, 0x00, 0x88, 0x02, + 0x1e, 0xf0, 0x01, 0xe0, 0x05, 0x8f, 0x40, 0x00, 0x00, 0x03, 0x0e, 0x7c, + 0x00, 0xc0, 0x21, 0x18, 0xc0, 0x00, 0x80, 0x10, 0x32, 0xb4, 0x00, 0x80, + 0x80, 0x40, 0x40, 0x00, 0x80, 0x11, 0x16, 0x00, 0x01, 0x00, 0x41, 0x20, + 0x80, 0x00, 0x00, 0x02, 0x13, 0xbe, 0x00, 0x00, 0xe0, 0x09, 0x80, 0x20, + 0xa0, 0x21, 0x09, 0x09, 0x00, 0x80, 0x30, 0x04, 0x00, 0x10, 0xa0, 0x00, + 0x13, 0x0e, 0x01, 0x00, 0xd0, 0x20, 0xa0, 0x00, 0x60, 0x00, 0x1a, 0x02, + 0x01, 0x40, 0x10, 0x0c, 0x01, 0x30, 0x18, 0x06, 0x00, 0x55, 0x02, 0x40, + 0x58, 0x50, 0xc0, 0x00, 0x00, 0x00, 0x07, 0x85, 0x02, 0x00, 0x04, 0x24, + 0x70, 0x00, 0x00, 0x43, 0x91, 0x05, 0x04, 0x50, 0x06, 0x15, 0x50, 0x08, + 0x20, 0x82, 0x21, 0x00, 0xce, 0xf7, 0x00, 0x04, 0x48, 0x03, 0x80, 0x80, + 0xc1, 0x04, 0x17, 0x13, 0x00, 0x02, 0x70, 0x03, 0x10, 0x03, 0xc3, 0x02, + 0x00, 0x05, 0x00, 0x01, 0x34, 0x13, 0x40, 0x02, 0xc2, 0x00, 0x18, 0x00, + 0x00, 0x00, 0x7e, 0x20, 0x80, 0x0f, 0xc6, 0x83, 0xa4, 0x00, 0x00, 0x00, + 0x27, 0x00, 0x00, 0x04, 0x80, 0x01, 0xa0, 0x00, 0x01, 0xd0, 0x17, 0x00, + 0x00, 0x81, 0x04, 0x06, 0xc0, 0x0d, 0x70, 0xe1, 0x11, 0x04, 0x20, 0x88, + 0x84, 0x0c, 0x80, 0x00, 0x10, 0x7c, 0x0c, 0xc0, 0x00, 0x18, 0x89, 0x01, + 0x00, 0x0f, 0x9c, 0x0d, 0x0c, 0x00, 0x00, 0xa0, 0x80, 0x23, 0x20, 0xb0, + 0x2e, 0x0b, 0x06, 0x00, 0x00, 0x23, 0x11, 0x61, 0x01, 0xfc, 0x2b, 0x02, + 0x04, 0x10, 0x00, 0x43, 0x90, 0x01, 0x20, 0xff, 0x06, 0x80, 0x83, 0x10, + 0x00, 0x10, 0x00, 0x03, 0x22, 0x07, 0x00, 0x06, 0x40, 0x00, 0x00, 0x92, + 0x00, 0x01, 0x03, 0x00, 0x20, 0x00, 0x81, 0x12, 0x00, 0x02, 0x03, 0x03, + 0x27, 0x00, 0x40, 0xc0, 0x00, 0x01, 0x00, 0x10, 0x02, 0x02, 0x40, 0xcd, + 0x07, 0x18, 0x02, 0x04, 0x00, 0x00, 0x09, 0x82, 0x28, 0xc1, 0x04, 0x20, + 0x00, 0x00, 0x00, 0x16, 0x10, 0x06, 0x00, 0x10, 0x00, 0x14, 0x00, 0x00, + 0x00, 0x30, 0x6c, 0x06, 0x00, 0x00, 0x04, 0x0e, 0x88, 0x00, 0x00, 0x44, + 0x00, 0x07, 0x00, 0x04, 0xc0, 0x01, 0x20, 0x00, 0x00, 0x00, 0x81, 0x05, + 0x00, 0x00, 0x00, 0x30, 0x10, 0x00, 0x00, 0x40, 0x10, 0x02, 0x00, 0x01, + 0x70, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x08, 0xa0, 0x1c, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x01, 0x80, 0x2b, 0xe0, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x78, 0x80, 0x04, 0x62, 0x80, 0x00, 0x00, 0x00, 0x20, + 0x04, 0x80, 0x00, 0x28, 0x08, 0x18, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x04, 0x51, 0x00, 0x01, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x80, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x0e, 0x01, 0x00, 0x84, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, + 0x9c, 0x02, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0x40, 0x77, 0xa9, 0x48, + 0x08, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, 0x2c, 0x60, 0x08, 0x05, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x36, 0x00, 0x40, 0x5e, 0x10, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xaa, 0x10, 0x04, 0x00, 0x00, 0x10, + 0xc1, 0x81, 0x10, 0x00, 0x10, 0x61, 0x00, 0x00, 0x00, 0x00, 0x60, 0x48, + 0xa4, 0x00, 0x40, 0x41, 0x00, 0x00, 0x00, 0x00, 0x90, 0x9d, 0x9a, 0x04, + 0xc0, 0x8c, 0x00, 0x08, 0x00, 0x82, 0x78, 0x7b, 0x01, 0x19, 0xc0, 0x10, + 0x00, 0x00, 0x00, 0x22, 0xe6, 0xe6, 0x01, 0x68, 0xc0, 0x30, 0x20, 0x00, + 0x00, 0x02, 0xd0, 0xd0, 0xa2, 0xe5, 0x85, 0x45, 0x02, 0x00, 0x00, 0xe0, + 0x8c, 0x00, 0x06, 0x01, 0x00, 0x41, 0x00, 0x00, 0x80, 0x08, 0x46, 0x40, + 0xb4, 0xf7, 0x41, 0x6b, 0xc3, 0x00, 0x00, 0x00, 0x26, 0x0d, 0xdf, 0xe7, + 0x08, 0x08, 0x83, 0x02, 0x88, 0x70, 0x8c, 0x80, 0x30, 0xe1, 0x09, 0x23, + 0x92, 0x01, 0x00, 0x40, 0x14, 0x70, 0x80, 0x11, 0x8a, 0x41, 0x06, 0x00, + 0x02, 0x08, 0x00, 0x04, 0x40, 0x48, 0x0c, 0x02, 0x0c, 0x08, 0x00, 0x10, + 0x00, 0x04, 0x40, 0x18, 0x43, 0x92, 0xa9, 0x00, 0x00, 0x08, 0x00, 0x02, + 0x02, 0x13, 0x20, 0x54, 0x11, 0x00, 0x00, 0x08, 0xc4, 0x01, 0x00, 0x03, + 0x40, 0x80, 0x00, 0x00, 0x08, 0x34, 0xa0, 0x08, 0x00, 0x0e, 0x40, 0x0c, + 0x00, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x20, 0x26, 0x80, 0xc1, 0x30, 0x04, + 0x00, 0x06, 0x01, 0x80, 0x4e, 0x6e, 0x80, 0x37, 0x10, 0x00, 0x00, 0x01, + 0x28, 0xe0, 0x80, 0x63, 0x80, 0x82, 0x20, 0x01, 0x00, 0x06, 0x20, 0xf0, + 0x96, 0xed, 0x00, 0x46, 0x01, 0x01, 0x81, 0x01, 0x1c, 0x80, 0x17, 0x58, + 0x01, 0x67, 0x00, 0x02, 0x00, 0x11, 0x3c, 0xc0, 0x0e, 0xf0, 0x41, 0x2f, + 0x80, 0x00, 0x80, 0x01, 0x44, 0xf8, 0x03, 0x30, 0x04, 0xc4, 0xe0, 0x00, + 0xc0, 0x01, 0x36, 0xf0, 0x00, 0xe0, 0x00, 0x5d, 0xc1, 0x00, 0x60, 0x20, + 0x11, 0x34, 0x00, 0xc0, 0x03, 0x28, 0x00, 0x02, 0xc0, 0x00, 0x09, 0x0e, + 0x01, 0xc0, 0xc5, 0x28, 0x40, 0x08, 0x00, 0x83, 0x11, 0xbd, 0x00, 0xc0, + 0x05, 0x20, 0x20, 0x01, 0x00, 0x00, 0x18, 0x8a, 0x00, 0xc0, 0x21, 0x06, + 0x00, 0x00, 0x10, 0x01, 0x12, 0x05, 0x00, 0x80, 0x00, 0x8e, 0x80, 0x21, + 0x00, 0xa1, 0x81, 0x8a, 0x00, 0x00, 0x80, 0x18, 0xc0, 0x00, 0xc8, 0xc0, + 0xc8, 0x62, 0x01, 0x00, 0x60, 0x00, 0x40, 0x00, 0xd0, 0x60, 0x58, 0x42, + 0x01, 0x40, 0xd0, 0x34, 0x40, 0x00, 0x80, 0x80, 0x00, 0x00, 0x03, 0x20, + 0x38, 0x00, 0x40, 0x00, 0xc0, 0x03, 0x71, 0x01, 0x00, 0x10, 0x4c, 0x44, + 0x40, 0x00, 0x00, 0x81, 0xb0, 0xc0, 0x03, 0x00, 0x0c, 0x10, 0x40, 0x00, + 0x48, 0x00, 0x71, 0x80, 0xe9, 0x2f, 0x22, 0x06, 0x20, 0x14, 0x00, 0x11, + 0x60, 0x00, 0xc0, 0xb4, 0x01, 0x54, 0x28, 0x08, 0x00, 0x03, 0xe1, 0x20, + 0x04, 0x05, 0x40, 0x09, 0x20, 0x00, 0x00, 0x24, 0x91, 0x00, 0x05, 0x00, + 0x80, 0x03, 0x38, 0x0c, 0x60, 0x14, 0x91, 0x01, 0x14, 0x00, 0x80, 0x00, + 0x1c, 0x04, 0x40, 0x20, 0x30, 0x00, 0x30, 0x00, 0x40, 0x00, 0x13, 0x00, + 0x00, 0x05, 0x31, 0x00, 0xb0, 0x21, 0x00, 0x00, 0x4a, 0x01, 0x20, 0x01, + 0x32, 0x04, 0x10, 0x00, 0x00, 0x80, 0xdc, 0x00, 0x40, 0x10, 0x20, 0x0c, + 0xe0, 0x00, 0x06, 0xa0, 0x4a, 0x00, 0x00, 0x11, 0x30, 0x10, 0x42, 0x01, + 0x23, 0xf2, 0x0d, 0x42, 0x20, 0x21, 0x10, 0x20, 0x84, 0xc7, 0x83, 0xfd, + 0x02, 0x00, 0xa0, 0x48, 0x10, 0x30, 0xf2, 0xbd, 0x9a, 0x0e, 0x00, 0x00, + 0x80, 0x00, 0x20, 0x70, 0x70, 0xbe, 0xf2, 0xc0, 0x81, 0x04, 0x40, 0x40, + 0x21, 0x00, 0x02, 0x40, 0x22, 0xa0, 0x01, 0x01, 0x00, 0x20, 0x33, 0x44, + 0x0a, 0x00, 0x40, 0x40, 0x00, 0x00, 0x20, 0x00, 0x38, 0x00, 0x5b, 0x00, + 0x20, 0x70, 0x00, 0x00, 0x00, 0x40, 0x12, 0x00, 0x80, 0x6e, 0x4a, 0x08, + 0x80, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x36, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x1c, 0x04, 0x00, 0x80, 0x00, + 0x20, 0x00, 0x10, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x10, 0x80, 0x02, + 0x00, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xac, 0x00, 0x00, + 0xb9, 0x00, 0x14, 0x00, 0x00, 0x04, 0x04, 0xa3, 0x00, 0x00, 0x06, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x8a, 0xc2, 0x01, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x88, 0x3d, 0x82, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x10, 0x38, 0x00, 0x42, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, + 0x80, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x10, + 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x10, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + +#define terrain_width 20 +#define terrain_height 20 +static unsigned char a0000_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, + 0x0e, 0x03, 0x01, 0x0c, 0x06, 0x00, 0x08, 0x02, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x01, + 0x80, 0xc1, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; +static unsigned char a0001_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x81, 0x01, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x60, 0x00, 0x60, 0x30, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; +static unsigned char a0010_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x08, 0x80, 0x01, + 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x0c, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x06, 0x60, 0x00, +}; +static unsigned char a0011_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x30, 0x00, 0x00, 0x20, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0xc0, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x20, 0x00, 0x06, 0x60, 0x00, +}; +static unsigned char a0100_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x40, 0x10, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; +static unsigned char a0101_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x08, 0x03, 0x00, 0x0c, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x10, 0x00, 0x03, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, + 0x00, 0x1c, 0x00, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, +}; +static unsigned char a0110_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x10, 0x00, 0x80, 0x01, 0x00, + 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x60, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, + 0x80, 0x00, 0x08, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x60, 0x00, +}; +static unsigned char a0111_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x0c, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x03, 0x84, 0x00, 0x01, 0x18, 0x00, 0x00, 0x30, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x06, 0x60, 0x00, +}; +static unsigned char a1000_bits[] = { + 0x0c, 0xa0, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x02, 0x00, 0x84, 0x03, 0x00, 0x06, 0x41, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; +static unsigned char a1001_bits[] = { + 0x0c, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, + 0x83, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0xc0, 0x00, 0x00, 0xc0, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; +static unsigned char a1010_bits[] = { + 0x04, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, + 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x40, 0x00, 0x06, 0x60, 0x00, +}; +static unsigned char a1011_bits[] = { + 0x0c, 0x80, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x02, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x03, 0x20, 0x00, + 0x82, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x70, 0x00, +}; +static unsigned char a1100_bits[] = { + 0x3c, 0x80, 0x00, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0xe0, 0x00, 0x00, 0x80, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x80, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, +}; +static unsigned char a1101_bits[] = { + 0x0c, 0xc0, 0x00, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x08, 0x00, 0x40, 0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, + 0x31, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; +static unsigned char a1110_bits[] = { + 0x08, 0xe0, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x02, 0x0c, 0x00, 0x0e, 0x04, 0x30, 0x08, 0x00, + 0x10, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x00, 0x00, 0x20, 0x00, 0x00, 0x02, 0x40, 0x00, 0x06, 0x20, 0x00, +}; +static unsigned char a1111_bits[] = { + 0x0c, 0xe0, 0x00, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x03, 0x00, 0x0c, 0x01, 0x00, 0x08, 0x81, 0x01, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, + 0x00, 0x01, 0x04, 0x01, 0x00, 0x08, 0x05, 0x20, 0x00, 0x06, 0x60, 0x00, +}; + +/* asteroid "fluff" bitmaps */ +static unsigned char a0_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; +static unsigned char a1_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; +static unsigned char a2_bits[] = { + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stats.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,206 @@ +/* $Id: stats.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */ + +/* + * stats.c + */ +#include "copyright.h" + +#include <stdio.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "proto.h" + +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + +#define BX_OFF() ((textWidth + 1) * W_Textwidth + S_IBORDER) +#define BY_OFF(line) ((line) * (W_Textheight + S_IBORDER) + S_IBORDER) +#define TX_OFF(len) ((textWidth - len) * W_Textwidth + S_IBORDER) +#define TY_OFF(line) BY_OFF(line) + +#if 0 +#define STAT_WIDTH 160 +#else +#define STAT_WIDTH st_width +#endif +#define STAT_HEIGHT BY_OFF(NUM_SLIDERS) +#define STAT_BORDER 2 +#define S_IBORDER 5 +#define STAT_X 422 +#define STAT_Y 13 + +#define SL_WID \ + (STAT_WIDTH - 2 * S_IBORDER - (textWidth + 1) * W_Textwidth) +#define SL_HEI (W_Textheight) + +#define NUM_ELS(a) (sizeof (a) / sizeof (*(a))) +#define NUM_SLIDERS NUM_ELS(sliders) + +typedef struct slider { + char *label; + int min, max; + int red; + int yellow; + int label_length; + int diff; + int *var; + int lastVal; +} SLIDER; + +typedef struct record { + int *data; + int last_value; +} RECORD; + +static SLIDER sliders[] = { + {"Shield Cond", 0, 100, 20, 100}, + {"Hull Cond", 0, 100, 0, 0}, + {"Fuel Cond", 0, 10000, 2000, 10000}, + {"Weapon Temp", 0, 1200, 0, 800}, + {"Engine Temp", 0, 1200, 0, 800}, +}; + +static int textWidth = 0; +static int initialized = 0; + +/* Prototypes */ +static void box +P((int filled, int x, int y, int wid, int hei, + W_Color color)); + static void initStats P((void)); + + static int st_width = -1; + + static void initStats() +{ + int i; + + if (initialized) + return; + initialized = 1; + sliders[0].var = &(me->p_shield); + sliders[1].var = &(me->p_damage); + sliders[2].var = &(me->p_fuel); + sliders[3].var = &(me->p_wtemp); + sliders[4].var = &(me->p_etemp); + for (i = 0; i < NUM_SLIDERS; i++) { + sliders[i].label_length = strlen(sliders[i].label); + textWidth = MAX(textWidth, sliders[i].label_length); + sliders[i].diff = sliders[i].max - sliders[i].min; + sliders[i].lastVal = 0; + } + st_width = W_WindowWidth(statwin); +} + +void +redrawStats() +{ + int i; + + W_ClearWindow(statwin); + initStats(); + for (i = 0; i < NUM_SLIDERS; i++) { + sliders[i].lastVal = 0; + } + for (i = 0; i < NUM_SLIDERS; i++) { + W_WriteText(statwin, TX_OFF(sliders[i].label_length), TY_OFF(i), + textColor, sliders[i].label, sliders[i].label_length, + W_RegularFont); + box(0, BX_OFF() - 1, BY_OFF(i) - 1, SL_WID + 2, SL_HEI + 2, borderColor); + sliders[i].lastVal = 0; + } +} + +void +updateStats() +{ + int i, value, new_x; + int r, y, t; + SLIDER *s; + + initStats(); + for (i = 0; i < NUM_SLIDERS; i++) { + s = &sliders[i]; + value = *(s->var); + if ((i == 0) || (i == 2)) + value = s->max - value; + if (value < s->min) + value = s->min; + else if (value > s->max) + value = s->max; +#if 0 + if (value == s->lastVal) + continue; +#endif + new_x = value * SL_WID / s->diff; + y = s->yellow * SL_WID / s->diff; + r = s->red * SL_WID / s->diff; + t = s->max * SL_WID / s->diff; + if (value > s->red) { + box(1, BX_OFF(), BY_OFF(i), y, SL_HEI, gColor); + box(1, BX_OFF() + y, BY_OFF(i), r - y, SL_HEI, yColor); + box(1, BX_OFF() + r, BY_OFF(i), new_x - r, SL_HEI, rColor); + } else if (value > s->yellow) { + box(1, BX_OFF(), BY_OFF(i), y, SL_HEI, gColor); + box(1, BX_OFF() + y, BY_OFF(i), new_x - y, SL_HEI, yColor); + } else { + box(1, BX_OFF(), BY_OFF(i), new_x, SL_HEI, gColor); + } + box(1, BX_OFF() + new_x, BY_OFF(i), t - new_x, SL_HEI, backColor); + } +} + +static void +box(filled, x, y, wid, hei, color) + int filled, x, y, wid, hei; + W_Color color; +{ + if (wid == 0) + return; + + if (filled) { + /* XFIX */ + W_FillArea(statwin, x, y, wid + 1, hei + 1, color); + return; + } + W_MakeLine(statwin, x, y, x + wid, y, color); + W_MakeLine(statwin, x + wid, y, x + wid, y + hei, color); + W_MakeLine(statwin, x + wid, y + hei, x, y + hei, color); + W_MakeLine(statwin, x, y + hei, x, y, color); +} + + +void +calibrate_stats() +{ + register int i; + sliders[0].min = 0; + sliders[0].max = me->p_ship->s_maxshield; + sliders[0].yellow = .33 * ((double) sliders[0].max); + sliders[0].red = .66 * ((double) sliders[0].max); + + sliders[1].min = 0; + sliders[1].max = me->p_ship->s_maxdamage; + sliders[1].yellow = .33 * ((double) sliders[1].max); + sliders[1].red = .66 * ((double) sliders[1].max); + + sliders[2].min = 0; + sliders[2].max = me->p_ship->s_maxfuel; + sliders[2].yellow = .33 * ((double) sliders[2].max); + sliders[2].red = .66 * ((double) sliders[2].max); + + sliders[3].min = 0; + sliders[3].max = 1.0 * ((double) me->p_ship->s_maxwpntemp); + sliders[3].yellow = .33 * ((double) sliders[3].max); + sliders[3].red = .66 * ((double) sliders[3].max); + + sliders[4].min = 0; + sliders[4].max = 1.0 * ((double) me->p_ship->s_maxegntemp); + sliders[4].yellow = .33 * ((double) sliders[4].max); + sliders[4].red = .66 * ((double) sliders[4].max); + + for (i = 0; i < NUM_SLIDERS; i++) + sliders[i].diff = sliders[i].max - sliders[i].min; + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/struct.h Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,810 @@ +/* $Id: struct.h,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */ + +/* + * struct.h for the client of an xtrek socket protocol. + * + * Most of the unneeded stuff in the structures has been thrown away. + */ + +#ifndef struct_h_ +#define struct_h_ + +#include "copyright.h" +#include "Wlib.h" +#include "defs.h" +#include "packets.h" + +#ifdef HOCKEY +/* hockey struct [BDyess] */ +struct hockeyLine { + int vertical; /* vertical or horizontal flag */ + W_Color color; + int pos, end1, end2; /* x or y constant and two endpoints */ +}; +#endif /*HOCKEY*/ + +/* ratings struct [BDyess] */ +struct ratings { + float r_offrat; /* offense rating */ + float r_planetrat; /* planets rating */ + float r_bombrat; /* bombing rating */ + float r_defrat; /* defense rating */ + float r_resrat; /* resource rating */ + float r_dooshrat; /* doosh rating */ + float r_stratrat; /* strategy rating */ + float r_batrat; /* battle rating */ + float r_sbrat; /* sb rating */ + float r_wbrat; /* wb rating */ + float r_jsrat; /* js rating */ + int r_jsplanets; /* js planets */ + int r_resources; /* total resources bombed */ + int r_armies; /* total armies bombed */ + int r_planets; /* total planets taken */ + int r_dooshes; /* total armies dooshed */ + float r_specrat; /* special ship rating */ + float r_di; /* damage inflicted */ + float r_ratio; /* ratio, kills/losses */ + int r_kills; /* kills */ + int r_losses; /* losses */ + float r_ratings; /* total ratings */ + float r_killsPerHour; /* kills/hour */ + float r_lossesPerHour; /* losses/hour */ + float r_maxkills; /* max kills */ + int r_genocides; /* number of genocides */ +}; + +/* messageWindow structure [BDyess] */ +struct messageWin { + W_Window window; + int flags; + struct messageNode *head, *curHead; +}; + +/* stuff yanked from COW-lite for rc_distress [BDyess] */ +struct distress { + unsigned char sender; + unsigned char dam, shld, arms, wtmp, etmp, fuelp, sts; + unsigned char wtmpflag, etempflag, cloakflag, distype, macroflag; + unsigned char close_pl, close_en, tclose_pl, tclose_en, pre_app, i; + unsigned char close_j, close_fr, tclose_j, tclose_fr; + unsigned char cclist[6]; /* allow us some day to cc a message up to 5 + people */ + /* sending this to the server allows the server to do the cc action */ + /* otherwise it would have to be the client ... less BW this way */ + char preappend[80]; /* text which we pre or append */ +}; + +enum dist_type { + /* help me do series */ + take = 1, ogg, bomb, space_control, + save_planet, + base_ogg, + help3, help4, + + /* doing series */ + escorting, ogging, bombing, controlling, + asw, + asbomb, + doing3, doing4, + + /* other info series */ + free_beer, /* ie. player x is totally hosed now */ + no_gas, /* ie. player x has no gas */ + crippled, /* ie. player x is way hurt but may have gas */ + pickup, /* player x picked up armies */ + pop, /* there was a pop somewhere */ + carrying, /* I am carrying */ + other1, other2, + + /* just a generic distress call */ + generic +}; + +/* The General distress has format: + + byte1: 00yzzzzz + where zzzzz is dist_type, and y is 1 if this is a more complicated macro + and not just a simple distress (a simple distress will ONLY send ship + info like shields, armies, status, location, etc.). I guess y=1 can be for ! + future expansion. + + byte2: 1fff ffff - f = percentage fuel remaining (0-100) + byte3: 1ddd dddd - % damage + byte4: 1sss ssss - % shields remaining + byte5: 1eee eeee - % etemp + byte6: 1www wwww - % wtemp + byte7: 100a aaaa - armies carried + byte8: (lsb of me->p_status) & 0x80 + byte9: 1ppp pppp - planet closest to me + byte10: 1eee eeee - enemy closest to me + byte11: 1ppp pppp - planet closest to target + byte12: 1eee eeee - enemy closest to target + byte13: 1ttt tttt - tclose_j + byte14: 1jjj jjjj - close_j + byte15: 1fff ffff - tclose_fr + byte16: 1ccc cccc - close_fr + byte17+: cc list (each player to cc this message to is 11pp ppp) + cc list is terminated by 0x80 (pre-pend) or 0100 0000 (append) ) + byte18++: the text to pre or append .. depending on termination above. + text is null terminated and the last thing in this distress + */ + +struct macro_list { + int type; + char key; + char who; + char *string; +}; + +struct dmacro_list { + unsigned char c; + char *name; + char *macro; +}; +/* end rc_distress stuff [BDyess] */ + +struct status { + unsigned char tourn; /* Tournament mode? */ + /* These stats only updated during tournament mode */ + unsigned int armsbomb, planets, kills, losses, time; + /* Use long for this, so it never wraps */ + unsigned long timeprod; +}; + +struct status2 { /* paradise status struct */ + int active; /* for interfacing with people who */ + unsigned int wait, count; /* want to get into the game */ + unsigned int number, request, answer; + unsigned char tourn; /* Tournament mode? */ + unsigned long dooshes; /* total number of armies dooshed */ + unsigned long armsbomb; /* all t-mode armies bombed */ + unsigned long resbomb; /* resources bombed */ + unsigned long planets; /* all t-mode planets taken */ + unsigned long kills; /* all t-mode kills made */ + unsigned long losses; /* all t-mode losses */ + unsigned long genocides; /* number of genocides */ + unsigned long sbkills; /* total kills in SB's */ + unsigned long sblosses; /* total losses in Sb's */ + unsigned long sbtime; /* total time in SB's */ + unsigned long wbkills; /* kills in warbases */ + unsigned long wblosses; /* losses in warbases */ + unsigned long wbtime; /* total time played in wb's */ + unsigned long jsplanets; /* total planets taken by jump ships */ + unsigned long jstime; /* total time in a jump ship */ + unsigned long time; /* t-mode time */ + unsigned long timeprod; /* t-mode ship ticks--sort of like */ + /* manhours in t-mode */ + int gameup; /* is game up */ + unsigned long clock; /* clock for planet info timestamp */ +}; + + +#ifdef METASERVER +/* metaserver window struct */ +struct servers { + char address[LINE]; + int port; + int time; + int players; + int status; + int RSA_client; + char typeflag; + char hilited; +}; +#endif /* METASERVER */ + +/* MOTD structures */ +struct piclist { + int page; + W_Icon thepic; + int x, y; + int width, height; + struct piclist *next; +}; +struct page { + struct list *text; + struct page *next; + struct page *prev; + int first; + int page; +}; + +#define PFREE 0 +#define POUTFIT 1 +#define PALIVE 2 +#define PEXPLODE 3 +#define PDEAD 4 +#define PTQUEUE 5 +#define POBSERVE 6 + +#define PFSHIELD (1<< 0) /* shields are raised */ +#define PFREPAIR (1<< 1) /* player in repair mode */ +#define PFBOMB (1<< 2) /* player is bombing */ +#define PFORBIT (1<< 3) /* player is orbiting */ +#define PFCLOAK (1<< 4) /* player is cloaked */ +#define PFWEP (1<< 5) /* player is weapon temped */ +#define PFENG (1<< 6) /* player is engine temped */ +#define PFROBOT (1<< 7) /* player is a robot */ +#define PFBEAMUP (1<< 8) /* player is beaming up */ +#define PFBEAMDOWN (1<< 9) /* player is beaming down */ +#define PFSELFDEST (1<<10) /* player is self destructing */ +#define PFGREEN (1<<11) /* player at green alert */ +#define PFYELLOW (1<<12) /* player is at yellow alert */ +#define PFRED (1<<13) /* player is at red alert */ +#define PFPLOCK (1<<14) /* Locked on a player */ +#define PFPLLOCK (1<<15) /* Locked on a planet */ +#define PFCOPILOT (1<<16) /* Allow copilots */ +#define PFWAR (1<<17) /* computer reprogramming for war */ +#define PFPRACTR (1<<18) /* practice type robot (no kills) */ +#define PFDOCK (1<<19) /* true if docked to a starbase */ +#define PFREFIT (1<<20) /* true if about to refit */ +#define PFREFITTING (1<<21) /* true if currently refitting */ +#define PFTRACT (1<<22) /* tractor beam activated */ +#define PFPRESS (1<<23) /* pressor beam activated */ +#define PFDOCKOK (1<<24) /* docking permission */ +#define PFSEEN (1<<25) /* seen by enemy on galactic map? */ +#define PFWARPPREP (1<<26) /* in warp prep [BDyess] */ +#define PFWARP (1<<27) /* ship warping */ +#define PFAFTER (1<<28) /* after burners on */ +#define PFWPSUSPENDED (1<<29) /* warp prep suspended [BDyess] */ +#define PFSNAKE (1<<30) /* it's a space snake */ +#define PFBIRD (1<<31) /* it's a space bird */ + +enum why_dead { + KNOREASON, KQUIT, KTORP, KPHASER, KPLANET, + KSHIP, KDAEMON, KWINNER, KGHOST, KGENOCIDE, + KPROVIDENCE, KPLASMA, KTOURNEND, KOVER, KTOURNSTART, + KBADBIN, KMISSILE, KASTEROID +}; + +#define DEFAULT -1 +#define SCOUT 0 +#define DESTROYER 1 +#define CRUISER 2 +#define BATTLESHIP 3 +#define ASSAULT 4 +#define STARBASE 5 +#define ATT 6 +#define GALAXY 6 /* galaxy ships now supported - they look + extremely similar to flagships :) [BDyess] */ +#define JUMPSHIP 7 +#define FLAGSHIP 8 +#define WARBASE 9 +#define LIGHTCRUISER 10 +#define CARRIER 11 +#define UTILITY 12 +#define PATROL 13 +#define PUCK 14 +/*#define NUM_TYPES 14*/ + +struct shiplist { + struct ship *ship; + struct shiplist *prev, *next; +}; + +struct ship { + int s_phaserrange; + int s_maxspeed; + int s_maxfuel; + int s_maxshield; + int s_maxdamage; + int s_maxegntemp; + int s_maxwpntemp; + short s_maxarmies; + short s_type; + int s_torpspeed; + char s_letter; + /* char s_name[16]; */ + char s_desig[2]; + short s_bitmap; + unsigned char s_keymap[256]; + unsigned char s_buttonmap[12]; +}; + +struct ship_shape { + int nviews; + W_Icon *bmap; + W_Icon shield; + int width, height; +}; + +struct stats { + double st_maxkills; /* max kills ever */ + int st_kills; /* how many kills */ + int st_losses; /* times killed */ + int st_armsbomb; /* armies bombed */ + int st_planets; /* planets conquered */ + int st_ticks; /* Ticks I've been in game */ + int st_tkills; /* Kills in tournament play */ + int st_tlosses; /* Losses in tournament play */ + int st_tarmsbomb; /* Tournament armies bombed */ + int st_tplanets; /* Tournament planets conquered */ + int st_tticks; /* Tournament ticks */ + /* SB stats are entirely separate */ + int st_sbkills; /* Kills as starbase */ + int st_sblosses; /* Losses as starbase */ + int st_sbticks; /* Time as starbase */ + double st_sbmaxkills; /* Max kills as starbase */ + long st_lastlogin; /* Last time this player was played */ + int st_flags; /* Misc option flags */ +#if 0 + unsigned char st_keymap[256]; /* keymap for this player */ +#endif + int st_rank; /* Ranking of the player */ +}; + + +struct stats2 { /* paradise stats */ + int st_genocides; /* number of genocides participated in */ + float st_tmaxkills; /* max kills ever */ + float st_di; /* total destruction inflicted for all time */ + int st_tkills; /* Kills in tournament play */ + int st_tlosses; /* Losses in tournament play */ + int st_tarmsbomb; /* Tournament armies bombed */ + int st_tresbomb; /* resources bombed off */ + int st_tdooshes; /* armies killed while being carried */ + int st_tplanets; /* Tournament planets conquered */ + int st_tticks; /* Tournament ticks */ + /* SB/WB/JS stats are entirely separate */ + int st_sbkills; /* Kills as starbase */ + int st_sblosses; /* Losses as starbase */ + int st_sbticks; /* Time as starbase */ + float st_sbmaxkills; /* Max kills as starbase */ + int st_wbkills; /* Kills as warbase */ + int st_wblosses; /* Losses as warbase */ + int st_wbticks; /* Time as warbase */ + float st_wbmaxkills; /* Max kills as warbase */ + int st_jsplanets; /* planets assisted with in JS */ + int st_jsticks; /* ticks played as a JS */ + long st_lastlogin; /* Last time this player was played */ + int st_flags; /* Misc option flags */ + unsigned char st_keymap[256]; /* keymap for this player */ + int st_rank; /* Ranking of the player */ + int st_royal; /* royaly, specialty, rank */ +}; + +#define ST_NOBITMAPS (1<<0) +#define ST_KEEPPEACE (1<<3) + +struct player { + int p_no; + int p_updates; /* Number of updates ship has survived */ + int p_status; /* Player status */ + unsigned int p_flags; /* Player flags */ + char p_name[16]; + char p_login[16]; + char p_monitor[16]; /* Monitor being played on */ + char p_mapchars[2]; /* Cache for map window image */ + struct ship *p_ship; /* Personal ship statistics */ + int p_x; + int p_y; + unsigned char p_dir; /* Real direction */ + unsigned char p_desdir; /* desired direction */ + int p_subdir; /* fraction direction change */ + int p_speed; /* Real speed */ + short p_desspeed; /* Desired speed */ + int p_subspeed; /* Fractional speed */ + short p_teami; /* Team I'm on */ + int p_damage; /* Current damage */ + int p_subdamage; /* Fractional damage repair */ + int p_shield; /* Current shield power */ + int p_subshield; /* Fractional shield recharge */ + short p_cloakphase; /* Drawing stage of cloaking + engage/disengage. */ + short p_ntorp; /* Number of torps flying */ + short p_ndrone; /* Number of drones .. why was this missing? */ + short p_totmissiles; /* number of total missiles [Bill Dyess] */ + short p_nplasmatorp; /* Number of plasma torps active */ + char p_hostile; /* Who my torps will hurt */ + char p_swar; /* Who am I at sticky war with */ + float p_kills; /* Enemies killed */ + short p_planet; /* Planet orbiting or locked onto */ + short p_playerl; /* Player locked onto */ +#ifdef ARMY_SLIDER + int p_armies; /* XXX: for stats */ +#else + short p_armies; +#endif /* ARMY_SLIDER */ + int p_fuel; + short p_explode; /* Keeps track of final explosion */ + int p_etemp; + short p_etime; + int p_wtemp; + short p_wtime; + short p_whydead; /* Tells you why you died */ + short p_whodead; /* Tells you who killed you */ + struct stats p_stats; /* player statistics */ + struct stats2 p_stats2; /* Paradise stats */ + short p_genoplanets; /* planets taken since last genocide */ + short p_genoarmsbomb; /* armies bombed since last genocide */ + short p_planets; /* planets taken this game */ + short p_armsbomb; /* armies bombed this game */ + int p_docked; /* If starbase, # docked to, else pno base + host */ + int p_port[4]; /* If starbase, pno of ship docked to that + port, else p_port[0] = port # docked to on + host. */ + short p_tractor; /* What player is in tractor lock */ + int p_pos; /* My position in the player file */ +}; + +struct statentry { + char name[16], password[16]; + struct stats stats; +}; + +/* Torpedo states */ + +#define TFREE 0 +#define TMOVE 1 +#define TEXPLODE 2 +#define TDET 3 +#define TOFF 4 +#define TSTRAIGHT 5 /* Non-wobbling torp */ + +struct torp { + int t_no; + int t_status; /* State information */ + int t_owner; + int t_x; + int t_y; + unsigned char t_dir; /* direction */ + short t_turns; /* rate of change of direction if tracking */ + int t_damage; /* damage for direct hit */ + int t_speed; /* Moving speed */ + int t_fuse; /* Life left in current state */ + char t_war; /* enemies */ + char t_team; /* launching team */ + char t_whodet; /* who detonated... */ + char frame; /* frame of animation [BDyess] */ +}; + +struct thingy { + int t_no; + int t_shape; /* State information */ + int t_owner; + int t_x; + int t_y; + unsigned char t_dir; /* direction */ + int t_speed; /* Moving speed */ + int t_fuse; /* Life left in current state */ + char t_war; /* enemies */ +}; + +/* Plasma Torpedo states */ + +#define PTFREE 0 +#define PTMOVE 1 +#define PTEXPLODE 2 +#define PTDET 3 + +struct plasmatorp { + int pt_no; + int pt_status; /* State information */ + int pt_owner; + int pt_x; + int pt_y; + unsigned char pt_dir; /* direction */ + short pt_turns; /* ticks turned per cycle */ + int pt_damage; /* damage for direct hit */ + int pt_speed; /* Moving speed */ + int pt_fuse; /* Life left in current state */ + char pt_war; /* enemies */ + char pt_team; /* launching team */ +}; + +#define PHFREE 0x00 +#define PHHIT 0x01 /* When it hits a person */ +#define PHMISS 0x02 +#define PHHIT2 0x04 /* When it hits a photon */ +#ifdef CHECK_DROPPED +#define PHGHOST 0x80 /* fuse has exceeded longest received so far */ +#endif +struct phaser { + int ph_status; /* What it's up to */ + unsigned char ph_dir; /* direction */ + int ph_target; /* Who's being hit (for drawing) */ + int ph_x, ph_y; /* For when it hits a torp */ + int ph_fuse; /* Life left for drawing */ + int ph_damage; /* Damage inflicted on victim */ +}; + +/* An important note concerning planets: The game assumes that + the planets are in a 'known' order. Ten planets per team, + the first being the home planet. +*/ + + /* defines for the pl_flags field of planet struct */ + +/* + pl_flags is an int of 32 bits: + + bits 16 and 23 currently define the type of the planet. The + interpretation of the other bits is dependent upon the planet + type. + + Here is the interpretation for a planet + bits 0..3 unknown + bits 4..6 planetary facilities (REPAIR,FUEL,AGRI) + bit 7 redraw (archaic, recyclable?) + bits 8..11 old flags (archaic, recyclable?) + bits 12..15 paradise planetary facilities + (REPAIR,FUEL,AGRI,SHIPY) + bit 16 cosmic object type (also bit 23) + bits 17,18 planet atmosphere type + bits 19..21 planetary surface properties + (DILYTH,METAL,ARABLE) + bit 22 paradise planet flag (why?) + bit 23 cosmic object type (also bit 16) + bits 24..31 currently unallocated (8 bits to play with) + + Asteroids are NYI but here is a draft standard: + bits 12,15 facilities + (REPAIR,FUEL,SHIPY) + bit 20 surface properties + (DILYTH,METAL) + other bits currently unallocated + + */ + +/* facilities, bits 4..6 and 12..15 + valid for planets and asteroids */ +#define PLREPAIR ((1<<12) | (1<<4)) /* planet can repair ships */ +#define PLFUEL ((1<<13) | (1<<5)) /* planet has fuel depot */ +#define PLAGRI ((1<<14) | (1<<6)) /* agricultural thingies built here */ +#define PLSHIPYARD ((1<<15)) /* planet has a shipyard on it */ +#define PLORESMASK (0x7<<4) /* mask for original resource flags */ +#define PLRESSHIFT 12 /* bit to shift right by for resources */ +#define PLRESMASK (0xF<<PLRESSHIFT) /* to mask off all but resource bits */ + +#define PLREDRAW (1<<7) /* Player close for redraw */ + +#define PLHOME (1<< 8) /* These 4 flags no longer are */ +#define PLCOUP (1<< 9) /* used in the server */ +#define PLCHEAP (1<<10) +#define PLCORE (1<<11) + +/* cosmic object types, bits 16 and 23, and 24 */ +#define PLPLANET 0 /* object is a planet */ +#define PLSTAR (1<<16) /* object is a star */ +#define PLAST (1<<23) /* object is an asteroid NYI */ +#define PLNEB ((1<<16)|(1<<23)) /* object is a nebula NYI */ +#define PLBHOLE (1<<24) /* object is a black hole NYI */ +#define PLPULSAR ((1<<16)|(1<<24)) /* object is a pulsar NYI */ +#define PLUK1 ((1<<23)|(1<<24)) /* future expansion */ +#define PLWHOLE ((1<<16)|(1<<23)|(1<<24)) /* object is a wormhole */ +#define PLTYPEMASK ((1<<16)|(1<<23)|(1<<24)) /* mask to extract object + type */ +#define PL_TYPE(p) ( (p).pl_flags & PLTYPEMASK ) + +/* Atmosphere Types, bits 17 and 18. + Valid for planets. + */ +#define PLATSHIFT 17 /* number of right bit shifts for atmos bits */ +#define PLPOISON (0<<PLATSHIFT) /* poison atmosphere, no army growth */ +#define PLATYPE3 (1<<PLATSHIFT) /* slightly toxic, very slow army + growth */ +#define PLATYPE2 (2<<PLATSHIFT) /* thin atmosphere, slow army growth */ +#define PLATYPE1 (3<<PLATSHIFT) /* normal human atmosphere, normal + growth */ +#define PLATMASK (0x3<<PLATSHIFT) /* to mask off everything but atmos + bits */ + +/* Surface Properties, bits 19..21 + Valid for planets and asteroids. + */ +#define PLBARREN 0 /* rocky barren surface */ +#define PLSURSHIFT 19 /* number of bit shift to surface */ +#define PLDILYTH (1<<(PLSURSHIFT+0)) /* dilythium deposits on the planet */ +#define PLMETAL (1<<(PLSURSHIFT+1)) /* metal deposits on the planet */ +#define PLARABLE (1<<(PLSURSHIFT+2)) /* planet has farmland */ +#define PLSURMASK (0x7<<PLSURSHIFT) /* number of surface combinations */ + + +#define PLPARADISE (1<<22) /* Paradise server flag set to 1 for P server */ + + +struct planet { + int pl_no; + int pl_flags; /* State information */ + int pl_owner; + int pl_x; + int pl_y; + char pl_name[16]; + int pl_namelen; /* Cuts back on strlen's */ + int pl_armies; + int pl_info; /* Teams which have info on planets */ + int pl_deadtime; /* Time before planet will support life */ + int pl_couptime; /* Time before coup may take place */ + int pl_timestamp; /* time the info was taken */ +}; + +struct t_unit { +/* int alt1;*/ +/* int alt2;*/ /* Terrain types. */ + char types; +}; + +/* Terrain types */ +#define T_EMPTY_SPACE 0x00 +#define T_ASTEROIDS 0x01 +#define T_NEBULA 0x02 +#define T_RADIATION 0x04 +#define T_EXPANSN1 0x08 +#define T_EXPANSN2 0x10 +#define T_EXPANSN3 0x20 +#define T_EXPANSN4 0x40 +#define T_EXPANSN5 0x80 + +struct _clearzone { + int x, y; + int width, height; +}; + +#ifndef SHORT_PACKETS +#define MVALID 0x01 +#define MINDIV 0x02 +#define MTEAM 0x04 +#define MALL 0x08 +#define MGOD 0x10 +#define MCAST 0x18 /* not an offial packet type. only */ + /* used in smessage to stay orthogonal */ +#else +#define MVALID 0x01 +#define MGOD 0x10 +#define MMOO 0x12 + +#ifdef TOOLS +#define MTOOLS 0x14 +#endif + +/* order flags by importance (0x100 - 0x400) */ +/* restructuring of message flags to squeeze them all into 1 byte - jmn */ +/* hopefully quasi-back-compatible: + MVALID, MINDIV, MTEAM, MALL, MGOD use up 5 bits. this leaves us 3 bits. + since the server only checks for those flags when deciding message + related things and since each of the above cases only has 1 flag on at + a time we can overlap the meanings of the flags */ + +#define MINDIV 0x02 +/* these go with MINDIV flag */ +#ifdef STDBG +#define MDBG 0x20 +#endif +#define MCONFIG 0x40 /* config messages from server */ +#define MDIST 0x60 /* flag distress messages - client thing + really but stick it in here for + consistency */ +#define MCAST 0x18 /* not an offial packet type. only */ + /* used in smessage.c to stay orthogonal */ + +#define MTEAM 0x04 +/* these go with MTEAM flag */ +#define MTAKE 0x20 +#define MDEST 0x40 +#define MBOMB 0x60 +#define MCOUP1 0x80 +#define MCOUP2 0xA0 +#define MDISTR 0xC0 + +#define MALL 0x08 +/* these go with MALL flag */ +#define MGENO 0x20 /* MGENO is not used in INL server but + belongs here */ +#define MCONQ 0x20 /* not enought bits to distinguish + MCONQ/MGENO :-( */ +#define MKILLA 0x40 +#define MKILLP 0x60 +#define MKILL 0x80 +#define MLEAVE 0xA0 +#define MJOIN 0xC0 +#define MGHOST 0xE0 +/* MMASK not used in INL server */ + +/* to flag multi-line macros */ +#define MMACRO 0x80 + +#define MWHOMSK 0x1f /* mask with this to find who msg to */ +#define MWHATMSK 0xe0 /* mask with this to find what message about */ + +/* old flags... +#define MVALID 0x01 +#define MINDIV 0x02 +#define MTEAM 0x04 +#define MALL 0x08 +#define MGOD 0x10 + +#define MGENO 0x100 order these by importance (0x100 - 0x400) +#define MCONQ 0x110 +#define MTAKE 0x120 +#define MDEST 0x130 +#define MKILLA 0x200 +#define MBOMB 0x210 +#define MKILLP 0x220 +#define MKILL 0x230 +#define MLEAVE 0x300 +#define MJOIN 0x310 +#define MGHOST 0x320 +#define MCOUP1 0x330 +#define MCOUP2 0x340 end of old flags */ +#endif + +struct message { + int m_no; + int m_flags; + int m_time; + int m_recpt; + char m_data[80]; +}; + +/* message control structure */ + +struct mctl { + int mc_current; +}; + +/* This is a structure used for objects returned by mouse pointing */ + +#define PLANETTYPE 0x1 +#define PLAYERTYPE 0x2 + +struct obtype { + int o_type; + int o_num; +}; + +struct id { + char *name; + int team; + int number; + int type; + char mapstring[4]; +}; + +struct rank { + float hours, ratings, defense; + char *name; +}; + +struct rank2 { /* Paradise ranks */ + int genocides; /* minimum number of genocides */ + float di; /* minimum destruction inflicted */ + float battle; /* minimum battle ratings */ + float strategy; /* minimum strategy ratings */ + float specship; /* minimum total ratings in a specialty */ + /* ship SB + WB + JS */ + char *name; /* name of this rank */ +}; + + +struct royalty { /* Paradise royalty ranks */ + char *name; /* name of rank */ +}; + +struct plupdate { + + int plu_update; + int plu_x, plu_y; +}; + +#ifdef MACROS +#define MACSINGLE 1 +#define MACRCD 2 +#define MACMULTI 4 +struct macro { + char flags; /* WAS isSingleMacro; now, uses above flags */ + INT8 to; /* if to team, rom, etc put here or -1 */ + char specialto; /* player nearest mouse, etc here */ + struct macro *next; /* for multi-line macros, points to a struct + *distress if MACRCD flag set. -JR */ + char *string; /* string to be sent, % escapes intact */ +}; +#endif /* MACROS */ + +struct stringlist { + char *string; + char *value; + struct stringlist *next, *prev; + int searched; +}; +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/time.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,58 @@ +/* $Id: time.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */ + +#ifdef HANDLER_TIMES +#include <stdio.h> +#include <sys/time.h> + +unsigned long avg[70], count[70]; +struct timeval pre, post; + +void print_times(void); +void log_time(int type, struct timeval *pre, struct timeval *post) +{ + static int init=0; + unsigned long usecs; + int i; + + if(!init) { + for(i=0;i<70;i++) + avg[i] = count[i] = 0; + init=1; + atexit(print_times); + } + + usecs = (post->tv_sec * 1000000 + post->tv_usec) - + ( pre->tv_sec * 1000000 + pre->tv_usec); + avg[type] = ((avg[type]*count[type])+usecs)/(count[type]+1); + count[type]++; +} + +void print_times() +{ + int i, t_cnt=0, t_avg=0; + + printf("Packet handler average times:\n"); + printf("Type Count Average time (secs)\n"); + for(i=0;i<70;i++) { + if(count[i]) { + printf(" %2d %5d %8.7f\n",i,count[i],(double)((double)avg[i]/1000000.0)); + t_cnt+=count[i]; + t_avg+=avg[i]; + } + } + t_avg /= t_cnt; + printf("Totals:\n"); + printf(" -- %5d, %8.7f\n", t_cnt, (double)((double)t_avg/1000000.0)); +} + +start_log() +{ + gettimeofday(&pre, 0); +} + +stop_log(int type) +{ + gettimeofday(&post, 0); + log_time(type, &pre, &post); +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,59 @@ +/* $Id: tools.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */ + +/* tools.c - shell escape, graphic toolsw - 10/10/93 + * + * copyright 1993 Kurt Siegl <siegl@risc.uni-linz.ac.at> Free to use, hack, etc. + * Just keep these credits here. Use of this code may be dangerous to your + * health and/or system. Its use is at your own risk. I assume no + * responsibility for damages, real, potential, or imagined, resulting from + * the use of it. + * + */ + +#ifdef TOOLS +#include <stdio.h> +#include "math.h" +#include <signal.h> +#include <sys/types.h> +#include <strings.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" + +void +sendTools(str) +char *str; +{ + char pipebuf[100]; + FILE *pipefp; + int len; + + if (!W_IsMapped(toolsWin)) + showToolsWin(); + signal(SIGCHLD, SIG_DFL); + if (shelltools && (pipefp = popen(str, "r")) != NULL) + { + while (fgets(pipebuf, 80, pipefp) != NULL) + { + len = strlen(pipebuf); + if (pipebuf[len - 1] == '\n') + pipebuf[len - 1] = '\0'; + W_WriteText(toolsWin, 0, 0, textColor, pipebuf, + strlen(pipebuf), W_RegularFont); + } + pclose(pipefp); + } + else + W_WriteText(toolsWin, 0, 0, textColor, str, strlen(str), W_RegularFont); +} + +showToolsWin() +{ + if (W_IsMapped(toolsWin)) + W_UnmapWindow(toolsWin); + else + W_MapWindow(toolsWin); +} + +#endif /* TOOLS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/udpopt.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,227 @@ +/* $Id: udpopt.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */ + +/* + * udpopt.c - present UDP control window + */ +#include "copyright.h" + +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "proto.h" + +#define UDPBORDER 2 +#define UDPLEN 35 + +/* Set up the UDP control window */ +void +udpwindow() +{ + register int i; + + for (i = 0; i < UDP_NUMOPTS; i++) + udprefresh(i); + + /* Map window */ + W_MapWindow(udpWin); +} + +/* + * Refresh item i + */ +void +udprefresh(i) + int i; +{ + char buf[BUFSIZ]; + + switch (i) { + case UDP_CURRENT: + sprintf(buf, "UDP channel is %s", (commMode == COMM_TCP) ? + "CLOSED" : "OPEN"); + break; + case UDP_STATUS: + strcpy(buf, "> Status: "); + switch (commStatus) { + case STAT_CONNECTED: + strcat(buf, "Connected"); + break; + case STAT_SWITCH_UDP: + strcat(buf, "Requesting switch to UDP"); + break; + case STAT_SWITCH_TCP: + strcat(buf, "Requesting switch to TCP"); + break; + case STAT_VERIFY_UDP: + strcat(buf, "Verifying UDP connection"); + break; + default: + fprintf(stderr, "netrek: UDP error: bad commStatus (%d)\n", + commStatus); + } + break; + case UDP_DROPPED: + sprintf(buf, "> UDP trans dropped: %d (%d%% | %d%%)", udpDropped, + udpDropped * 100 / udpTotal, /* (udpTotal always > 0) */ + udpRecentDropped * 100 / UDP_RECENT_INTR); + break; + case UDP_SEQUENCE: + sprintf(buf, "Sequence checking is %s", (udpSequenceChk) ? + "ON" : "OFF"); + break; + case UDP_DEBUG: + sprintf(buf, "Debugging info is "); + switch (udpDebug) { + case 0: + strcat(buf, "OFF"); + break; + case 1: + strcat(buf, "ON (connect msgs only)"); + break; + case 2: + strcat(buf, "ON (verbose output)"); + break; + } + break; + case UDP_SEND: + sprintf(buf, "Sending with "); + switch (udpClientSend) { + case 0: + strcat(buf, "TCP only"); + break; + case 1: + strcat(buf, "simple UDP"); + break; + case 2: + strcat(buf, "enforced UDP (state only)"); + break; + case 3: + strcat(buf, "enforced UDP (state & weap)"); + break; + } + break; + case UDP_RECV: + sprintf(buf, "Receiving with "); + switch (udpClientRecv) { + case MODE_TCP: + strcat(buf, "TCP only"); + break; + case MODE_SIMPLE: + strcat(buf, "simple UDP"); + break; + case MODE_FAT: + strcat(buf, "fat UDP"); + break; +#ifdef DOUBLE_UDP + case MODE_DOUBLE: + strcat(buf, "double UDP"); + break; +#endif /* DOUBLE_UDP */ + } + break; + case UDP_FORCE_RESET: + sprintf(buf, "Force reset to TCP"); + break; + case UDP_UPDATE_ALL: + sprintf(buf, "Request full update (=)"); + break; +#ifdef GATEWAY + case UDP_GW: + sprintf(buf, "gw: %s %d/%d/%d", gw_mach, gw_serv_port, gw_port, + gw_local_port); + break; +#endif + case UDP_DONE: + strcpy(buf, "Done"); + break; + default: + fprintf(stderr, "netrek: UDP error: bad udprefresh(%d) call\n", i); + } + + W_WriteText(udpWin, 0, i, textColor, buf, strlen(buf), 0); +} + +void +udpaction(data) + W_Event *data; +{ + register int i; + + switch (data->y) { + case UDP_CURRENT: + if (commMode == COMM_TCP) + sendUdpReq(COMM_UDP); + else + sendUdpReq(COMM_TCP); + break; + + case UDP_STATUS: + case UDP_DROPPED: + W_Beep(); + break; + case UDP_SEQUENCE: + udpSequenceChk = !udpSequenceChk; + udprefresh(UDP_SEQUENCE); + break; + case UDP_SEND: + udpClientSend++; + if (udpClientSend > 3) + udpClientSend = 0; + udprefresh(UDP_SEND); + break; + case UDP_RECV: + udpClientRecv++; +#ifdef DOUBLE_UDP + if (udpClientRecv > MODE_DOUBLE) + udpClientRecv = 0; +#else + if (udpClientRecv >= MODE_DOUBLE) + udpClientRecv = 0; +#endif + udprefresh(UDP_RECV); + sendUdpReq(COMM_MODE + udpClientRecv); + break; + case UDP_DEBUG: + udpDebug++; + if (udpDebug > 2) + udpDebug = 0; + udprefresh(UDP_DEBUG); + break; + case UDP_FORCE_RESET: + /* clobber UDP */ + UDPDIAG(("*** FORCE RESET REQUESTED\n")); + sendUdpReq(COMM_TCP); + commMode = commModeReq = COMM_TCP; + commStatus = STAT_CONNECTED; + commSwitchTimeout = 0; + udpClientSend = udpClientRecv = udpSequenceChk = udpTotal = 1; + udpDebug = udpDropped = udpRecentDropped = 0; + if (udpSock >= 0) + closeUdpConn(); + for (i = 0; i < UDP_NUMOPTS; i++) + udprefresh(i); + break; + case UDP_UPDATE_ALL: + sendUdpReq(COMM_UPDATE); + break; +#ifdef GATEWAY + case UDP_GW: + W_Beep(); + break; +#endif + case UDP_DONE: + udpdone(); + break; + } +} + +void +udpdone() +{ + /* Unmap window */ + W_UnmapWindow(udpWin); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/util.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,289 @@ +/* $Id: util.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */ + +/* + * util.c + * added functionality to gettarget() - Bill Dyess 10/6/93 + */ +#include "copyright.h" + +#include <stdio.h> +#include <math.h> +#include <signal.h> +#include <stdlib.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "proto.h" +#include "gameconf.h" + +#if 0 +/* +** Provide the angular distance between two angles. +*/ +angdist(x, y) + unsigned char x, y; +{ + register unsigned char res; + + if (x > y) + res = x - y; + else + res = y - x; + if (res > 128) + return (256 - (int) res); + return ((int) res); +} +#endif + +double +hypot2(x, y) + double x, y; +{ + return sqrt(x * x + y * y); +} + +/* + * * Find the object nearest mouse. Returns a pointer to an * obtype + * structure. This is used for info and locking on. * + * + * Because we are never interested in it, this function will * never return + * your own ship as the target. * + * + * Finally, this only works on the two main windows +*/ + +static struct obtype _target; + +struct obtype * +gettarget(ww, x, y, targtype) + W_Window ww; + int x, y; + int targtype; +{ +/* now can get the closest friendly/enemy player or planet. Use + TARG_FRIENDLY or TARG_ENEMY or'd with TARG_PLAYER or TARG_PLANET */ + register int i; + register struct player *j; + register struct planet *k; + int g_x, g_y, friendly; + double dist, closedist; + int slotnum, width; + + if (ww == mapw) { + register gwidth, offsetx, offsety; + if (blk_zoom) { + gwidth = blk_gwidth / 2; + offsetx = zoom_offset(me->p_x); + offsety = zoom_offset(me->p_y); + } else { + gwidth = blk_gwidth; + offsetx = 0; + offsety = 0; + } + g_x = x * (gwidth / WINSIDE) + offsetx; + g_y = y * (gwidth / WINSIDE) + offsety; + + } else if (ww == playerw) { + if (targtype & TARG_PLAYER) { + W_TranslatePoints(playerw, &x, &y); + y -= 2; + if (y < 0) + y = 0; + if (*playerList == 0 || *playerList == ',') { + if (y > 15) + y = 15; + slotnum = y; + width = W_WindowWidth(ww); + if (x > width / 2) + slotnum += 16; + } else { + slotnum = y; + } + if (slot[slotnum] != -1 && + (paradise || !(players[slot[slotnum]].p_flags & PFCLOAK))) { + /* don't show info for cloakers on Bronco servers */ + _target.o_type = PLAYERTYPE; + _target.o_num = slot[slotnum]; + return &_target; + } + return NULL; /* no target found */ + } else { + g_x = me->p_x + ((x - WINSIDE / 2) * SCALE); + g_y = me->p_y + ((y - WINSIDE / 2) * SCALE); + } + } else if (ww) { /* tactical window */ + g_x = me->p_x + ((x - WINSIDE / 2) * SCALE); + g_y = me->p_y + ((y - WINSIDE / 2) * SCALE); + } else { + g_x = x; + g_y = y; + } + closedist = blk_gwidth; + + if (targtype & TARG_ASTRAL) { + for (i = 0, k = &planets[0]; i < nplanets; i++, k++) { + int ptype = 0; + friendly = friendlyPlanet(k); + if (friendly && (targtype & TARG_ENEMY)) + continue; + if (!friendly && (targtype & TARG_FRIENDLY)) + continue; + if (k->pl_owner != idx_to_mask(me->p_teami) && (targtype & TARG_TEAM)) + continue; + switch (PL_TYPE(*k)) { + case PLPLANET: + ptype = TARG_PLANET; + break; + case PLSTAR: + ptype = TARG_STAR; + break; + case PLAST: + ptype = TARG_PLANET; + break; + case PLNEB: + ptype = TARG_NEBULA; + break; + case PLBHOLE: + ptype = TARG_BLACKHOLE; + break; + case PLPULSAR: + ptype = TARG_STAR; + break; + } + if (!(ptype & targtype)) + continue; + dist = hypot((double) (g_x - k->pl_x), (double) (g_y - k->pl_y)); + if (dist < closedist) { + _target.o_type = PLANETTYPE; + _target.o_num = i; + closedist = dist; + } + } + } + if (targtype & TARG_PLAYER) { + for (i = 0, j = &players[i]; i < nplayers; i++, j++) { + if (j->p_status != PALIVE) + continue; + if ((j->p_flags & PFCLOAK) && (!(targtype & TARG_CLOAK)) && j != me) + continue; + if (j == me && !(targtype & TARG_SELF)) + continue; + friendly = friendlyPlayer(j); + if (friendly && (targtype & TARG_ENEMY)) + continue; + if (!friendly && (targtype & TARG_FRIENDLY)) + continue; + if (j->p_teami != me->p_teami && targtype & TARG_TEAM) + continue; + if (!(targtype & (isBase(j->p_ship->s_type) + ? TARG_BASE + : TARG_SHIP))) + continue; + dist = hypot((double) (g_x - j->p_x), (double) (g_y - j->p_y)); + if (dist <= closedist) { + _target.o_type = PLAYERTYPE; + _target.o_num = i; + closedist = dist; + } + } + } + if (closedist == blk_gwidth) { /* Didn't get one. bad news */ + _target.o_type = PLAYERTYPE; + _target.o_num = me->p_no; /* Return myself. Oh well... */ + return (&_target); + } else { + return (&_target); + } +} + +#ifdef hpux + +srandom(foo) + int foo; +{ + rand(foo); +} + +random() +{ + return (rand()); +} + +#include <time.h> +#include <sys/resource.h> + +#include <sys/signal.h> + +void (* + signal(sig, funct)) () + int sig; + void (*funct) (); +{ + struct sigvec vec, oldvec; + + sigvector(sig, 0, &vec); + vec.sv_handler = funct; + sigvector(sig, &vec, (struct sigvec *) 0); +} +#endif /* hpux */ + + +char * +team_bit_string(mask) + int mask; +{ + static char visitorstring[16]; /* better not have more than 16 teams */ + int i; + + for (i = 0; i < number_of_teams; i++) { + visitorstring[i] = (mask & (1 << i)) ? teaminfo[i].letter : ' '; + } + visitorstring[i] = 0; + return visitorstring; +} + +/* getTargetID returns an id stuct containing then name of the object, the + type of object, the number of the object, the + team the object belongs to, and . Used a lot in the macro code. + [BDyess] */ + +struct id * +getTargetID(ww, x, y, targtype) + W_Window ww; + int x, y; + int targtype; +{ + struct obtype *target; + static struct id buf; + struct player *j; + struct planet *k; + + target = gettarget(ww, x, y, targtype); + if (target->o_type == PLAYERTYPE) { + buf.type = PLAYERTYPE; + j = &players[target->o_num]; + buf.name = j->p_name; + buf.number = target->o_num; + buf.team = j->p_teami; + buf.mapstring[0] = j->p_mapchars[0]; + buf.mapstring[1] = j->p_mapchars[1]; + buf.mapstring[2] = 0; + } else if (target->o_type == PLANETTYPE) { + buf.type = PLANETTYPE; + k = &planets[target->o_num]; + buf.name = k->pl_name; + buf.number = target->o_num; + buf.team = mask_to_idx(k->pl_owner); + if (0 == strncmp(k->pl_name, "New ", 4)) { + strncpy(buf.mapstring, k->pl_name + 4, 3); + } else if (0 == strncmp(k->pl_name, "Planet ", 7)) { + strncpy(buf.mapstring, k->pl_name + 7, 3); + } else + strncpy(buf.mapstring, k->pl_name, 3); + buf.mapstring[3] = 0; + } else { /* tried to find something that doesn't exist */ + return NULL; + } + return &buf; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/varydamage.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,103 @@ +/* $Id: varydamage.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */ + +/* + * redraw.c + */ +#include "copyright.h" + +#include <stdio.h> +#include <signal.h> +#include <math.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "packets.h" +#include "proto.h" +#include "gameconf.h" + +void +doShields(dx, dy, ship_bits, j) + int dx, dy; + struct ship_shape *ship_bits; + struct player *j; +{ + if (showShields && (j->p_flags & PFSHIELD)) { + /*-----------Colored shields by shield damage--------*/ + + int color = playerColor(j); + if (show_shield_dam && j == me) { + float ft; + + ft = (float) j->p_shield / (float) j->p_ship->s_maxshield; + if (ft > 0.66) + color = gColor; + else if (ft > 0.33) + color = yColor; + else if (j->p_shield > 5) + color = rColor; + else + color = unColor; + } +#if 0 /* shields the alert color, ick */ + switch (me->p_flags & (PFGREEN | PFYELLOW | PFRED)) { + case PFGREEN: + color = gColor; + break; + case PFYELLOW: + color = yColor; + break; + /* red shield tough to see */ + case PFRED: + color = playerColor(j); + break; + } +#endif + W_WriteBitmap(dx - (ship_bits->width / 2), + dy - (ship_bits->height / 2), + ship_bits->shield, color); + } +} + +#ifdef VARY_HULL +void +doHull(dx, dy, ship_bits, j) + int dx, dy; + struct ship_shape *ship_bits; + struct player *j; +{ + if (j == me && vary_hull) { + int hull_left = (100 * (me->p_ship->s_maxdamage - + me->p_damage)) / me->p_ship->s_maxdamage, hull_num = 7; + int hull_color; + + if (hull_left <= 16) { + hull_num = 0; + hull_color = W_Red; + } else if (hull_left <= 28) { + hull_num = 1; + hull_color = W_Red; + } else if (hull_left <= 40) { + hull_num = 2; + hull_color = W_Red; + } else if (hull_left <= 52) { + hull_num = 3; + hull_color = W_Yellow; + } else if (hull_left <= 64) { + hull_num = 4; + hull_color = W_Yellow; + } else if (hull_left <= 76) { + hull_num = 5; + hull_color = W_Yellow; + } else if (hull_left <= 88) { + hull_num = 6; + hull_color = W_Green; + } else + hull_color = W_Green /* playerColor (j) */ ; + + W_WriteBitmap(dx - (ship_bits->width / 2 + 1), + dy - (ship_bits->height / 2 + 1), + hull[hull_num], hull_color); + } +} +#endif /* VARY_HULL */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/war.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,103 @@ +/* $Id: war.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */ + +/* + * war.c + */ +#include "copyright.h" + +#include <stdio.h> +#include <math.h> +#include <signal.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "packets.h" +#include "proto.h" + +static int newhostile; + +/* Set up the war window and map it */ +static char *feds = "FED - "; +static char *roms = "ROM - "; +static char *klis = "KLI - "; +static char *oris = "ORI - "; +static char *gos = " Re-program"; +static char *exs = " Exit - no change"; +static char *peaces = "Peace"; +static char *hostiles = "Hostile"; +static char *wars = "War"; + +/* Prototypes */ +static void fillwin P((int menunum, char *string, int hostile, int warbits, int team)); +static void warrefresh P((void)); + +void +warwindow() +{ + W_MapWindow(war); + newhostile = me->p_hostile; + warrefresh(); +} + +static void +warrefresh() +{ + fillwin(0, feds, newhostile, me->p_swar, FEDm); + fillwin(1, roms, newhostile, me->p_swar, ROMm); + fillwin(2, klis, newhostile, me->p_swar, KLIm); + fillwin(3, oris, newhostile, me->p_swar, ORIm); + W_WriteText(war, 0, 4, textColor, gos, strlen(gos), 0); + W_WriteText(war, 0, 5, textColor, exs, strlen(exs), 0); +} + +static void +fillwin(menunum, string, hostile, warbits, teammask) + int menunum; + char *string; + int hostile, warbits; + int teammask; +{ + char buf[80]; + + if (teammask & warbits) { + (void) sprintf(buf, " %s%s", string, wars); + W_WriteText(war, 0, menunum, rColor, buf, strlen(buf), 0); + } else if (teammask & hostile) { + (void) sprintf(buf, " %s%s", string, hostiles); + W_WriteText(war, 0, menunum, yColor, buf, strlen(buf), 0); + } else { + (void) sprintf(buf, " %s%s", string, peaces); + W_WriteText(war, 0, menunum, gColor, buf, strlen(buf), 0); + } +} + +void +waraction(data) + W_Event *data; +{ + int enemymask; + + if (data->y == 4) { + W_UnmapWindow(war); + sendWarReq(newhostile); + return; + } + if (data->y == 5) { + W_UnmapWindow(war); + return; + } + enemymask = 1 << data->y; + + if (me->p_swar & enemymask) { + warning("You are already at war!"); + W_Beep(); + } else { + if (idx_to_mask(me->p_teami) == enemymask) { + warning("It would never work ... your crew would have you in the brig in no time."); + } else { + newhostile ^= enemymask; + } + } + warrefresh(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/warning.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,153 @@ +/* $Id: warning.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */ + +/* + * warning.c + */ +#include "copyright.h" + +#include <stdio.h> +#include <math.h> +#include <signal.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#ifdef hupx +#include <time.h> +#else /* hpux */ +#include <sys/time.h> +#endif /* hpux */ +#ifdef RS6K +struct tm { + int tm_sec; /* seconds (0 - 59) */ + int tm_min; /* minutes (0 - 59) */ + int tm_hour; /* hours (0 - 23) */ + int tm_mday; /* day of month (1 - 31) */ + int tm_mon; /* month of year (0 - 11) */ + int tm_year; /* year - 1900 */ + int tm_wday; /* day of week (Sunday = 0) */ + int tm_yday; /* day of year (0 - 365) */ + int tm_isdst; /* flag: daylight savings time in effect */ + long tm_gmtoff; /* offset from GMT in seconds */ + char *tm_zone; /* abbreviation of timezone name */ + +}; + +#endif + +#define W_XOFF 5 +#ifndef AMIGA +#define W_YOFF 5 +#else +#define W_YOFF 1 +#endif + +char * +timeString(t) + time_t t; +/* returns a string of the form hour:minute:second */ +{ + static char *s = NULL; + struct tm *tm; + + if (!s) + s = (char *) malloc(9); + if (t > 24 * 60 * 60) { + tm = localtime(&t); + sprintf(s, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec); + } else + sprintf(s, "%02d:%02d:%02d", (int) (t / (60 * 60)), (int) ((t % (60 * 60)) / 60), + (int) (t % 60)); + return s; +} + +/* + ** The warning in text will be printed in the warning window. + ** The message will last WARNTIME/10 seconds unless another message + ** comes through and overwrites it. + */ + +void +warning(text) + char *text; +{ + /* long curtime; */ + /* char timebuf[10]; */ + /* struct tm *tm; */ + char newtext[91]; /* infinite appending fix - jn */ + int len; + + char *d; + int dmg; + float phasRatio, avgDmg; + int thisHit = 0; + + newtext[0] = '\0'; + warntimer = udcounter + WARNTIME; /* set the line to be cleared */ + + if (warncount > 0) { + /* XFIX */ + W_ClearArea(warnw, W_XOFF, W_YOFF, W_Textwidth * warncount, W_Textheight); + } + warncount = strlen(text); + W_WriteText(warnw, W_XOFF, W_YOFF, textColor, text, warncount, W_RegularFont); + if (strncmp(text, "Phaser", 6) == 0) { + if (strncmp(text + 7, "missed", 6) == 0) { + phasFired++; + if (!logPhaserMissed) + return; + thisHit = 0; + } else if (strncmp(text + 7, "burst", 5) != 0 && + strncmp(text + 7, "shot", 4) != 0) + return; + else { /* a hit! */ + phasFired++; + phasHits++; + thisHit = 1; + } + + if (phaserStats) { + if (thisHit) { + d = &text[strlen(text)]; + + while (!isdigit(*d) && d > text) /* find the last number + in the string, should + be damage */ + d--; + while (d > text && isdigit(*d)) + d--; + + if (d > text) { + dmg = atoi(d); + totalDmg += dmg; + avgDmg = (float) totalDmg / (float) phasHits; + phasRatio = (100 * phasHits) / (float) phasFired; + sprintf(newtext, "Av:%5.2f, Hit:%5.2f%%: ", avgDmg, phasRatio); + } + } else { /* a miss */ + sprintf(newtext, "Hit: %d, Miss: %d, Dmg: %d: ", phasHits, phasFired - phasHits, totalDmg); + } + } else { /* not keeping phaser stats right now */ + phasFired--; + if (thisHit) + phasHits--; + newtext[0] = '\0'; + } + strncat(newtext, text, 80); + len = strlen(newtext); + newtext[len++] = ' '; + strcpy(newtext + len, timeString(time(NULL))); + warncount = warncount + 9; + + dmessage(newtext, 0, 254, 0); + + } else if (strncmp(text, "Missile away", 12) == 0) { + /* missile total kludge. No value until one is shot :( */ + me->p_totmissiles = atoi(text + 13); + } else if (strcmp(text, "Prepping for warp jump") == 0) { + /* keep track of when in warp prep */ + me->p_flags |= PFWARPPREP; + } else if (strcmp(text, "Warp drive aborted") == 0) { + me->p_flags &= ~PFWARPPREP; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wide_plist.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,730 @@ +/* $Id: wide_plist.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */ + + +#ifdef WIDE_PLIST +#define PLIST1 +#define PLIST2 +#define PLIST +/* + * playerlist.c + * + * Fairly substantial re-write to do variable player lists: Sept 93 DRG + * Paradise shoehorning: 2/13/94 [BDyess] + */ +#include "copyright.h" + +#include <stdio.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "gameconf.h" +#include "proto.h" + +static char header[BUFSIZ]; +int header_len=0; +char *old_playerList=NULL; +char **slottext=NULL; /* array of strings shown in each slot + [BDyess] */ +W_Color *slotcolors=NULL; /* array of colors, one per slot [BDyess] */ +int slottext_size=0; /* keep track of the size in case nplayers + changes */ + +/*===========================================================================*/ + +int +playerlistnum() +{ + int num = 0; + char *ptr; + int i; + + ptr = playerList; + header[0] = '\0'; + while (ptr[0] != '\0' && ptr[0] != ',') { + switch (ptr[0]) { + case 'n': /* Ship Number */ + strcat(header, " No"); + num += 3; + break; + case 'T': /* Ship Type */ + strcat(header, " Ty"); + num += 3; + break; + case 'R': /* Rank */ + strcat(header, " Rank "); + num += 11; + break; + case 'N': /* Name */ + strcat(header, " Name "); + num += 17; + break; + case 'K': /* Kills */ + strcat(header, " Kills"); + num += 6; + break; + case 'l': /* Login Name */ + strcat(header, " Login "); + num += 17; + break; + case 'O': /* Offense */ + strcat(header, " Offse"); + num += 6; + break; + case 'W': /* Wins */ + strcat(header, " Wins"); + num += 6; + break; + case 'D': /* Defense */ + strcat(header, " Defse"); + num += 6; + break; + case 'L': /* Losses */ + strcat(header, " Loss"); + num += 6; + break; + case 'S': /* Total Rating (stats) */ + strcat(header, " Stats"); + num += 6; + break; + case 'r': /* Ratio */ + strcat(header, " Ratio"); + num += 6; + break; + case 'd': /* Damage Inflicted (DI) */ + strcat(header, " DI"); + num += 8; + break; + case ' ': /* White Space */ + strcat(header, " "); + num += 1; + break; +#ifdef PLIST1 + case 'B': /* Bombing */ + strcat(header, " Bmbng"); + num += 6; + break; + case 'b': /* Armies Bombed */ + strcat(header, " Bmbed"); + num += 6; + break; + case 'P': /* Planets */ + strcat(header, " Plnts"); + num += 6; + break; + case 'p': /* Planets Taken */ + strcat(header, " Plnts"); + num += 6; + break; + case 'G': /* Doosh rating ('oGGing') [BDyess] */ + strcat(header, " Dshng"); + num += 6; + break; + case 'g': /* number of dooshes [BDyess] */ + strcat(header, " Dshed"); + num += 6; + break; + case 'F': /* Resource rating [BDyess] */ + /* 'F' is from Farming...I'm out of good letters */ + strcat(header, " Resrc"); + num += 6; + break; + case 'f': /* number of Resources bombed [BDyess] */ + strcat(header, " Rsrcs"); + num += 6; + break; + case 'Z': /* SB rating [BDyess] */ + /* 'Z' is the last letter - a SB is the team anchor. :) */ + strcat(header, " SBrat"); + num += 6; + break; + case 'z': /* WB rating (small SB) [BDyess] */ + strcat(header, " WBrat"); + num += 6; + break; + case 'J': /* JS rating - good letter [BDyess] */ + strcat(header, " JSrat"); + num += 6; + break; + case 'j': /* JS planets [BDyess] */ + strcat(header, " JSpls"); + num += 6; + break; + case 'C': /* SpeCial ships rating [BDyess] */ + strcat(header, " Specl"); + num += 6; + break; + case 'E': /* genocides (Endings) [BDyess] */ + strcat(header, " Genos"); + num += 6; + break; + case 'M': /* Display, Host Machine */ + strcat(header, " Host Machine "); + num += 17; + break; + case 'H': /* Hours Played */ + strcat(header, " Hours"); + num += 7; + break; + case 'k': /* Max Kills */ + strcat(header, " Max K"); + num += 6; + break; + case 'V': /* Kills per hour */ + strcat(header, " KPH"); + num += 6; + break; + case 'v': /* Deaths per hour */ + strcat(header, " DPH"); + num += 6; + break; +#endif +#ifdef PLIST2 + case 'w': /* War staus */ + strcat(header, " War Stat"); + num += 9; + break; + case 's': /* Speed */ + strcat(header, " Sp"); + num += 3; + break; +#endif + default: + fprintf(stderr, "%c is not an option for the playerlist\n", ptr[0]); + break; + } + ptr++; + } + + old_playerList = playerList; + header_len = num; + return (num); +} + +/*===========================================================================*/ + +void +wideplayerlist() +{ + int i; + int old_len=header_len; + if (old_playerList != playerList) { + playerlistnum(); + if(resizePlayerList) + W_ResizeText(playerw,header_len,W_WindowHeight(playerw)); + /* init slottext [BDyess] */ + } + for (i = 0; i < nplayers; i++) + slot[i] = -1; + + W_ClearWindow(playerw); + + if (slottext && ((old_len != header_len) || (slottext_size != nplayers))) { + /* free the old one */ + for (i = 0; i < slottext_size; i++) { + free(slottext[i]); + } + free(slottext); + free(slotcolors); + slottext=0; + } + if(!slottext) { + slottext_size = nplayers; + slottext = (char **) malloc(sizeof(char *) * nplayers); + slotcolors = (W_Color *) malloc(sizeof(W_Color) * nplayers); + for (i = 0; i < nplayers; i++) { + /* malloc extra room in case a line runs off the end */ + slottext[i] = (char *) malloc(sizeof(char) * header_len + 30); + slottext[i][0] = 0; + slotcolors[i] = -1; + } + } + W_WriteText(playerw, 0, 1, textColor, header, header_len, W_RegularFont); + + for (i = 0; i < nplayers; i++) { + updatePlayer[i] = 1; + } + + wideplayerlist2(); +} + +/*===========================================================================*/ + +void +writeDiffText(window, x, y, color, orig, new, font) + W_Window window; + int x, y; + W_Color color; + char *orig, *new; + W_Font font; +{ +/* little routine to print just the chars that are different between orig and + new. [BDyess] */ + int i; + char *start; + + for (start = new, i = 0; new[i] && orig[i]; i++) { + if (orig[i] != new[i]) + continue; + if (start == new + i) { + start++; + continue; + } else { + W_WriteText(window, x + start - new, y, color, start, new + i - start, font); + start = new + i + 1; + } + } + if (start != new + i) { + /* finish up any remaining digits */ + W_WriteText(window, x + start - new, y, color, start, new + i - start, font); + } + if (new[i]) { + /* write any text that extends past the old one */ + W_WriteText(window, x + i, y, color, new + i, strlen(new + i), font); + } else if (orig[i]) { + /* print spaces to clear to EOL */ + char *freeme; + int len; + + len = strlen(orig + i); + freeme = (char *) malloc(len); + memset(freeme, ' ', len); + W_WriteText(window, x + i, y, color, freeme, len, font); + } +} + +/*===========================================================================*/ + +void +plist_line(j, pos) + struct player *j; + int pos; +{ + char buf[BUFSIZ]; + char *ptr; + char tmp[30]; + int my_ticks; + struct ratings r; + W_Color color; + + get_ratings(j, &r); + + if (pos < 2) { + printf("bad line position in playerlist\n"); + pos = 2; + } + if (paradise) + my_ticks = j->p_stats2.st_tticks; + else + my_ticks = j->p_stats.st_tticks; + + ptr = playerList; + buf[0] = '\0'; + while (ptr[0] != '\0' && ptr[0] != ',') { + tmp[0] = '\0'; + switch (ptr[0]) { + case 'n': /* Ship Number */ + tmp[0] = ' '; + if (j->p_status != PALIVE) { + tmp[1] = ' '; + } else { + tmp[1] = teaminfo[j->p_teami].letter; + } + tmp[2] = shipnos[j->p_no]; + tmp[3] = '\0'; + strcat(buf, tmp); + break; + case 'T': /* Ship Type */ + tmp[0] = ' '; + switch (j->p_status) { + case PALIVE: + tmp[1] = j->p_ship->s_desig[0]; + tmp[2] = j->p_ship->s_desig[1]; + break; + case PTQUEUE: + tmp[1] = 't'; + tmp[2] = 'q'; + break; + case POUTFIT: + tmp[1] = '-'; + tmp[2] = '-'; + break; + case PEXPLODE: + case PDEAD: + tmp[1] = '*'; + tmp[2] = '*'; + break; + case POBSERVE: + tmp[1] = 'o'; + tmp[2] = 'b'; + break; + default: + tmp[1] = ' '; + tmp[2] = ' '; + } + tmp[3] = '\0'; + strcat(buf, tmp); + break; + case 'R': /* Rank */ + tmp[0] = ' '; + sprintf(tmp + 1, "%-10.10s", get_players_rank_name(j)); + strcat(buf, tmp); + break; + case 'N': /* Name */ + tmp[0] = ' '; + sprintf(tmp + 1, "%-16.16s", j->p_name); + strcat(buf, tmp); + break; + case 'K': /* Kills */ + tmp[0] = ' '; + if ((j->p_kills <= 0 && + (paradise || RSA_Client <= 0) && hideNoKills) + || (j->p_status & ~PALIVE)) + strcpy(tmp + 1, " "); + else + sprintf(tmp + 1, "%5.2f", j->p_kills); + strcat(buf, tmp); + break; + case 'l': /* Login Name */ + tmp[0] = ' '; + sprintf(tmp + 1, "%-16.16s", j->p_login); + strcat(buf, tmp); + break; + case 'O': /* Offense */ + tmp[0] = ' '; + sprintf(tmp + 1, "%5.2f", r.r_offrat); + strcat(buf, tmp); + break; + case 'W': /* Wins */ + tmp[0] = ' '; + sprintf(tmp + 1, "%5d", r.r_kills); + strcat(buf, tmp); + break; + case 'D': /* Defense */ + tmp[0] = ' '; + sprintf(tmp + 1, "%5.2f", r.r_defrat); + strcat(buf, tmp); + break; + case 'L': /* Losses */ + tmp[0] = ' '; + sprintf(tmp + 1, "%5d", r.r_losses); + strcat(buf, tmp); + break; + case 'S': /* Total Rating (stats) */ + tmp[0] = ' '; + sprintf(tmp + 1, "%5.2f", r.r_ratings); + strcat(buf, tmp); + break; + case 'r': /* Ratio */ + tmp[0] = ' '; + sprintf(tmp + 1, "%5.2f", r.r_ratio); + strcat(buf, tmp); + break; + case 'd': /* Damage Inflicted (DI) */ + tmp[0] = ' '; + /* + ftoa (Ratings * (j->p_stats.st_tticks / 36000.0), tmp+1, 0, 4, + 2); + */ + sprintf(tmp + 1, "%7.2f", r.r_di); + strcat(buf, tmp); + break; + case ' ': /* White Space */ + strcat(buf, " "); + break; +#ifdef PLIST1 + case 'B': /* Bombing */ + tmp[0] = ' '; + sprintf(tmp + 1, "%5.2f", r.r_bombrat); + strcat(buf, tmp); + break; + case 'b': /* Armies Bombed */ + tmp[0] = ' '; + sprintf(tmp + 1, "%5d", r.r_armies); + strcat(buf, tmp); + break; + case 'P': /* Planets */ + tmp[0] = ' '; + sprintf(tmp + 1, "%5.2f", r.r_planetrat); + strcat(buf, tmp); + break; + case 'p': /* Planets Taken */ + tmp[0] = ' '; + sprintf(tmp + 1, "%5d", r.r_planets); + strcat(buf, tmp); + break; + case 'G': /* Doosh rating ('oGGing') [BDyess] */ + *tmp = ' '; + sprintf(tmp + 1, "%5.2f", r.r_dooshrat); + strcat(buf, tmp); + break; + case 'g': /* Dooshes [BDyess] */ + *tmp = ' '; + sprintf(tmp + 1, "%5d", r.r_dooshes); + strcat(buf, tmp); + break; + case 'F': /* Resource rating [BDyess] */ + /* 'F' is from Farming...I'm out of good letters */ + *tmp = ' '; + sprintf(tmp + 1, "%5.2f", r.r_resrat); + strcat(buf, tmp); + break; + case 'f': /* number of Resources bombed [BDyess] */ + *tmp = ' '; + sprintf(tmp + 1, "%5d", r.r_resources); + strcat(buf, tmp); + break; + case 'Z': /* SB rating [BDyess] */ + /* 'Z' is the last letter - a SB is the team anchor. :) */ + *tmp = ' '; + sprintf(tmp + 1, "%5.2f", r.r_sbrat); + strcat(buf, tmp); + break; + case 'z': /* WB rating (small SB) [BDyess] */ + *tmp = ' '; + sprintf(tmp + 1, "%5.2f", r.r_wbrat); + strcat(buf, tmp); + break; + case 'J': /* JS rating - good letter [BDyess] */ + *tmp = ' '; + sprintf(tmp + 1, "%5.2f", r.r_jsrat); + strcat(buf, tmp); + break; + case 'j': /* JS planets [BDyess] */ + *tmp = ' '; + sprintf(tmp + 1, "%5d", r.r_jsplanets); + strcat(buf, tmp); + break; + case 'C': /* SpeCial ships rating [BDyess] */ + *tmp = ' '; + sprintf(tmp + 1, "%5.2f", r.r_specrat); + strcat(buf, tmp); + break; + case 'E': /* genocides (Endings) [BDyess] */ + *tmp = ' '; + sprintf(tmp + 1, "%5d", r.r_genocides); + strcat(buf, tmp); + break; + case 'M': /* Display, Host Machine */ + tmp[0] = ' '; + sprintf(tmp + 1, "%-16.16s", j->p_monitor); + strcat(buf, tmp); + break; + case 'H': /* Hours Played */ + tmp[0] = ' '; + sprintf(tmp + 1, "%6.2f", my_ticks / 36000.0); + strcat(buf, tmp); + break; + case 'k': /* Max Kills */ + tmp[0] = ' '; + sprintf(tmp + 1, "%5.2f", r.r_maxkills); + strcat(buf, tmp); + break; + case 'V': /* Kills Per Hour */ + tmp[0] = ' '; + sprintf(tmp + 1, "%5.1f", r.r_killsPerHour); + strcat(buf, tmp); + break; + case 'v': /* Deaths Per Hour */ + tmp[0] = ' '; + sprintf(tmp + 1, "%5.1f", r.r_lossesPerHour); + strcat(buf, tmp); + break; + case 'w': /* War staus */ + if (j->p_swar & idx_to_mask(me->p_teami)) + strcat(buf, " WAR "); + else if (j->p_hostile & idx_to_mask(me->p_teami)) + strcat(buf, " HOSTILE "); + else + strcat(buf, " PEACEFUL"); + break; +#endif +#ifdef PLIST2 + case 's': /* Speed */ + tmp[0] = ' '; + sprintf(tmp + 1, "%2d", j->p_speed); + strcat(buf, tmp); + break; +#endif + default: + break; + } + ptr++; + } + + color = playerColor(j); + if (slot[pos - 2] == j->p_no && slotcolors[pos - 2] == color) { + /* write the line, skipping chars that haven't changed [BDyess] */ + writeDiffText(playerw, 0, pos, color, slottext[pos - 2], buf, + shipFont(j)); + } else { + W_WriteText(playerw, 0, pos, color, buf, strlen(buf), + shipFont(j)); + } + strcpy(slottext[pos - 2], buf); + slotcolors[pos - 2] = color; + slot[pos - 2] = j->p_no; +} + +/*===========================================================================*/ + +void +Sorted_playerlist2() +{ + register int i, h, pos = 1, last, boolflag = 0; + register struct player *j; + static int num; + int numplayers; + + /* 20, not 16, is the max for non-paradise! Mostly the extra 4 are */ + /* robots, but might as well show them and be safe... -JR*/ + numplayers = (paradise) ? nplayers : 20; + + /* + if (++num % 21 == 0) { boolflag = 1; num = 0; } + */ + /* go through the teams in order */ + for (h = 0; h < number_of_teams; h++) { + /* skip my team, I'll come back to it later */ + if (me->p_teami == h) + continue; + + /* go through all the players looking for those on team h */ + for (i = 0, j = &players[0]; i < numplayers; i++, j++) { + if (j->p_teami != h) + continue; + + if (j->p_status == PFREE) + continue; + + if(j->p_status == POUTFIT && !showDead) /* already know team */ + /* is valid.. */ + continue; + + pos++; /* put this AFTER checking for free slots to + get a */ + /* nice compact list... */ + + if (!updatePlayer[i] && slot[pos - 2] == i) + continue; + + updatePlayer[i] = 0; + plist_line(j, pos); + } + } + + /* now go through and do my team. Note: ind players haven't been done */ + if (me->p_teami >= 0 && me->p_teami < number_of_teams) { + for (i = 0, j = &players[i]; i < numplayers; i++, j++) { + if (j->p_teami != me->p_teami) + continue; + + if (j->p_status == PFREE) + continue; + + if(j->p_status == POUTFIT && !showDead) /* already know team */ + /* is valid.. */ + continue; + + pos++; + if (!updatePlayer[i] && slot[pos - 2] == i) + continue; + + updatePlayer[i] = 0; + plist_line(j, pos); + } + } +#if 0 /* this code displays the ind players from + the bottom up. */ + /* not everyone has a 32 line playerlist, so this tends to */ + /* make iggy invisible */ + last = numplayers + 2; + + for (i = numplayers - 1, j = &players[i]; i >= 0; i--, j--) { + if (j->p_teami >=0 && j->p_teami<number_of_teams) + continue; + + if (j->p_status == PFREE) + continue; + + last--; + + if (!updatePlayer[i] && (!boolflag)) + continue; + + updatePlayer[i] = 0; + plist_line(j, last); + } +#endif /* 0 */ + + for (i = 0, j = &players[0]; i < numplayers; i++, j++) { + if (j->p_teami >= 0 && j->p_teami < number_of_teams) + continue; + + if (j->p_status == PFREE) + continue; + + pos++; + + if (!updatePlayer[i] && slot[pos - 2] == i) + continue; + + updatePlayer[i] = 0; + plist_line(j, pos); + } + /* now continue clearing lines until we get to an empty one */ + pos++; + while ((pos - 2) < numplayers && slot[pos - 2] != -1 && slottext[pos - 2][0]) { + W_ClearArea(playerw, 0, pos, header_len, 1); + slot[pos - 2] = -1; + slottext[pos - 2][0] = 0; + pos++; + } + +#if 0 + if (boolflag && (last > (pos + 1))) { + W_ClearArea(playerw, 0, pos + 1, header_len, last - (pos + 1)); + slot[pos - 2] = -1; + } +#endif /* 0 */ +} + +/*===========================================================================*/ + +void +wideplayerlist2() +{ + register int i; + register struct player *j; + int numplayers; + + /* 20, not 16, is the max for non-paradise! Mostly the extra 4 are */ + /* robots, but might as well show them and be safe... -JR */ + numplayers = (paradise) ? nplayers : 20; + + if (old_playerList != playerList) { + wideplayerlist(); /* refresh if playerList changed */ + return; + } + if (!W_IsMapped(playerw)) + return; + + if (sortPlayers) { + Sorted_playerlist2(); + return; + } + for (i = 0, j = &players[i]; i < numplayers; i++, j++) { + if (!updatePlayer[i]) + continue; + + updatePlayer[i] = 0; + + if (j->p_status == PFREE) { + W_ClearArea(playerw, 0, i + 2, header_len, 1); + continue; + } + plist_line(j, i + 2); + } +} + +#endif /* WIDE_PLIST */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wtext.h Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,48 @@ +/* $Id: wtext.h,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */ + +/* Here are all warnings that are send with SP_S_WARNING */ +/* HW 93 */ +/* ab handleTractorReq socket.c */ + +#define TEXTE 0 +#define PHASER_HIT_TEXT 1 +#define BOMB_INEFFECTIVE 2 +#define BOMB_TEXT 3 +#define BEAMUP_TEXT 4 +#define BEAMUP2_TEXT 5 +#define BEAMUPSTARBASE_TEXT 6 +#define BEAMDOWNSTARBASE_TEXT 7 +#define BEAMDOWNPLANET_TEXT 8 +#define SBREPORT 9 +#define ONEARG_TEXT 10 +#define BEAM_D_PLANET_TEXT 11 +#define ARGUMENTS 12 +#define BEAM_U_TEXT 13 +#define LOCKPLANET_TEXT 14 +#define LOCKPLAYER_TEXT 15 +#define SBRANK_TEXT 16 +#define SBDOCKREFUSE_TEXT 17 +#define SBDOCKDENIED_TEXT 18 +#define SBLOCKSTRANGER 19 +#define SBLOCKMYTEAM 20 +/* Daemon messages */ +#define DMKILL 21 +#define KILLARGS 22 +#define DMKILLP 23 +#define DMBOMB 24 +#define DMDEST 25 +#define DMTAKE 26 +#define DGHOSTKILL 27 +/* INL messages */ +#define INLDMKILLP 28 +#define INLDMKILL 29 /* Because of shiptypes */ +#define INLDRESUME 30 +#define INLDTEXTE 31 +/* Variable warning stuff */ +#define STEXTE 32 /* static text that the server needs to send + to the client first */ +#define SHORT_WARNING 33 /* like CP_S_MESSAGE */ +#define STEXTE_STRING 34 +#define KILLARGS2 35 + +#define DINVALID 255
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x11window.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,2532 @@ +/* $Id: x11window.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */ + + +/* x11window.c + * + * Kevin P. Smith 6/11/89 + * Much modified by Jerry Frain and Joe Young + */ + +#include <stdio.h> +#ifdef __STDC__ +#include <stdlib.h> +#endif +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#ifdef RFCURSORS +#include <X11/Xmu/CurUtil.h> +#endif +#include <X11/cursorfont.h> +#include <assert.h> +#include <string.h> +#include "Wlib.h" +#include "defs.h" +#include "struct.h" +#include "data.h" +#include "proto.h" + +#define INVALID_POSITION -10000 /* gotta be a big negative */ +/* XFIX speedup */ +#define MAXCACHE 128 + +/* changes too good to risk leaving out, by Richard Caley (rjc@cstr.ed.ac.uk)*/ +#define RJC +#define FOURPLANEFIX + +/* +#define NORMAL_FONT "-*-fixed-medium-r-*-*-10-*-*-*-*-*-*-*" +#define BOLD_FONT "-*-fixed-medium-r-*-*-10-*-*-*-*-*-*-*" +#define ITALIC_FONT "-*-fixed-medium-r-*-*-10-*-*-*-*-*-*-*" +*/ + +#define NORMAL_FONT "6x10" +#define BOLD_FONT "6x10" +#define BOLD_FONT2 "-*-clean-bold-r-normal--10-100-75-75-c-60-*" +#define ITALIC_FONT "6x10" +#define ITALIC_FONT2 "-*-clean-bold-r-normal--10-100-75-75-c-60-*" +#define BIG_FONT "-adobe-helvetica-bold-r-normal--34-*-*-*-*-*-*-*" +#define IND_FONT "-*-clean-bold-r-normal--10-100-75-75-c-60-*" +/*#define BOLD_FONT2 "-schumacher-clean-bold-r-normal--10-100-75-75-c-60-iso8859-1" +#define ITALIC_FONT2 "-misc-fixed-medium-i-normal--10-100-75-75-c-60-iso8859-1" +#define BIG_FONT "-adobe-helvetica-bold-r-normal--34-*-*-*-*-*-*-*" +*/ + +static char *_nfonts[] = { + NORMAL_FONT, + "-*-clean-medium-r-normal--10-100-75-75-c-60-*", + "fixed", + NULL, +}; +static char *_bfonts[] = { + BOLD_FONT, + "-*-clean-bold-r-normal--10-100-75-75-c-60-*", + "fixed", + NULL, +}; +static char *_ifonts[] = { + ITALIC_FONT, + "-*-clean-bold-r-normal--10-100-75-75-c-60-*", + "fixed", + NULL, +}; +static char *_bgfonts[] = { + BIG_FONT, + "-*-lucidatypewriter-*-*-*-*-40-*-*-*-*-*-*-*", + "fixed", + NULL, +}; + +#define FONTS 4 +#define BITGC 4 + +#define WHITE 0 +#define BLACK 1 +#define RED 2 +#define GREEN 3 +#define YELLOW 4 +#define CYAN 5 +#define GREY 6 + +static int zero = 0; +static int one = 1; +static int two = 2; +static int three = 3; + +int controlkey = 0; +#define BillsScrewyAltMask (Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask) +int altkey = 0; +int W_FastClear = 0; +#ifdef CONTINUOUS_MOUSE +int buttonDown = 0; +#endif /* CONTINUOUS_MOUSE */ +Display *W_Display; +Window W_Root; +Colormap W_Colormap; +int W_Screen; +#ifdef FOURPLANEFIX +Visual *W_Visual; +#endif +W_Font W_BigFont = (W_Font) & zero, W_RegularFont = (W_Font) & one; +W_Font W_HighlightFont = (W_Font) & two, W_UnderlineFont = (W_Font) & three; +W_Color W_White = WHITE, W_Black = BLACK, W_Red = RED, W_Green = GREEN; +W_Color W_Yellow = YELLOW, W_Cyan = CYAN, W_Grey = GREY; +int W_Textwidth, W_Textheight; +char *getdefault(); +char *strdup(); + +int W_in_message = 0; /* jfy -- for Jerry's warp message hack */ + +#ifdef RJC +extern W_Window baseWin; +static XClassHint class_hint = { + "netrek", "Netrek", +}; + +static XWMHints wm_hint = { + InputHint | StateHint, + True, + WithdrawnState, + None, + None, + 0, 0, + None, + None, +}; + +static XSizeHints wm_size_hint; +#endif /* RJC */ + +static W_Event W_myevent; +static int W_isEvent = 0; + +struct fontInfo { + XFontStruct *fontstruct; + int baseline; +}; + +struct colors { + char *name; + GC contexts[FONTS + 1]; + Pixmap pixmap; + long pixelValue; +}; + +struct icon { + Window window; + Pixmap bitmap; + int width, height; + Pixmap pixmap; +}; + +#define WIN_GRAPH 1 +#define WIN_TEXT 2 +#define WIN_MENU 3 +#define WIN_SCROLL 4 + +struct window { + Window window; + int type; + char *data; + int mapped; + int width, height; + char *name; + Cursor cursor; +#ifdef SHORT_PACKETS + int insensitive; +#endif +#if 0 + W_Callback handle_keydown; + W_Callback handle_keyup; + W_Callback handle_button; + W_Callback handle_expose; +#endif /* 0 */ +}; + +struct stringList { + char *string; + W_Color color; + struct stringList *next; +}; + +struct menuItem { + char *string; + W_Color color; + W_Font font; +}; + +struct colors colortable[] = { + {"white"}, + {"black"}, + {"red"}, + {"green"}, + {"yellow"}, + {"cyan"}, + {"light grey"} +}; + +struct windowlist { + struct window *window; + struct windowlist *next; +}; + +#define HASHSIZE 29 +#define hash(x) (((int) (x)) % HASHSIZE) + +struct windowlist *hashtable[HASHSIZE]; +struct fontInfo fonts[FONTS]; + +struct window *newWindow(); +#ifndef NeXT +#ifndef __STDC__ +char *malloc(); +#endif +#endif /* NeXT */ +short *x11tox10bits(); + +struct window myroot; + +#define NCOLORS (sizeof(colortable)/sizeof(colortable[0])) +#define W_Void2Window(win) ((win) ? (struct window *) (win) : &myroot) +#define W_Window2Void(window) ((W_Window) (window)) +#define W_Void2Icon(bit) ((struct icon *) (bit)) +#define W_Icon2Void(bit) ((W_Icon) (bit)) +#define fontNum(font) (*((int *) font)) +#define TILESIDE 16 + +#define WIN_EDGE 5 /* border on l/r edges of text windows */ +#define MENU_PAD 4 /* border on t/b edges of text windows */ +#define MENU_BAR 2 /* width of menu bar */ + +static unsigned char gray[] = { + 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, + 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, + 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, + 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55 +}; + +static unsigned char striped[] = { + 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, + 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, + 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, + 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0 +}; + +static unsigned char solid[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +}; + +/* Prototypes */ +/*static int _myerror P((Display *d , XErrorEvent *e ));*/ +static void GetFonts P((void)); +static XFontStruct *find_font P((char *oldf, char **fonts)); +static void GetColors P((void)); +static void FlushClearAreaCache P((Window win)); +static int W_SpNextEvent P((W_Event * wevent)); +static void FlushLineCache P((Window win, int color)); +static void FlushPointCache P((Window win, int color)); +static struct window *findWindow P((Window window)); +static void addToHash P((struct window * win)); +static void AddToScrolling P((struct window * win, W_Color color, char *str, int len)); +static void redrawScrolling P((struct window * win)); +static void resizeScrolling P((struct window * win, int width, int height)); +static void redrawMenu P((struct window * win)); +static void redrawMenuItem P((struct window * win, int n)); +static void changeMenuItem P((struct window * win, int n, W_Color color, char *str, int len, W_Font font)); +/*static void W_SetTransientForHint P((W_Window w , W_Window pw ));*/ +static void checkGeometry P((char *name, int *x, int *y, int *width, int *height)); +static void checkParent P((char *name, W_Window * parent)); +static void checkCursor P((char *name, char *cursname, Cursor * cursor)); +static void findMouse P((int *x, int *y)); +#ifdef AUTOKEY +static void W_Flush P((void)); +#endif /* AUTOKEY */ +static void deleteWindow P((struct window * window)); + +/* X debugging */ +#if 0 +static int +_myerror(d, e) + Display *d; + XErrorEvent *e; +{ + abort(); +} +#endif /* 0 */ + +void +W_Initialize(str) + char *str; +{ + int i; + +#ifdef DEBUG + printf("Initializing...\n"); +#endif + for (i = 0; i < HASHSIZE; i++) { + hashtable[i] = NULL; + } + if ((W_Display = XOpenDisplay(str)) == NULL) { + fprintf(stderr, "Cannot open display \"%s\"\n", str ? str : "(null)"); + EXIT(1); + } +#if 0 + /* tmp */ + XSynchronize(W_Display, True); + XSetErrorHandler(_myerror); +#endif + + W_Root = DefaultRootWindow(W_Display); +#ifdef FOURPLANEFIX + W_Visual = DefaultVisual(W_Display, DefaultScreen(W_Display)); +#endif + W_Screen = DefaultScreen(W_Display); + W_Colormap = DefaultColormap(W_Display, W_Screen); + myroot.window = W_Root; + myroot.type = WIN_GRAPH; + GetFonts(); + GetColors(); +} + +static void +GetFonts() +{ + Font regular, italic, bold, big; + int i; + XGCValues values; + XFontStruct *fontinfo; + char *fontname; + + fontname = getdefault("font"); + if (fontname == NULL) + fontname = NORMAL_FONT; + fontinfo = XLoadQueryFont(W_Display, fontname); + if (fontinfo == NULL) { + fontinfo = find_font(fontname, _nfonts); + } + if (fontinfo == NULL) { + printf("netrek: Can't find any fonts!\n"); + EXIT(1); + } + regular = fontinfo->fid; + W_Textwidth = fontinfo->max_bounds.width; + W_Textheight = fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent; + fonts[1].baseline = fontinfo->max_bounds.ascent; + fonts[1].fontstruct = fontinfo; + + fontname = getdefault("boldfont"); + if (fontname == NULL) { + if (DisplayCells(W_Display, W_Screen) <= 4) + fontname = BOLD_FONT2; + else + fontname = BOLD_FONT; + } + fontinfo = XLoadQueryFont(W_Display, fontname); + if (fontinfo == NULL) { + fontinfo = find_font(fontname, _bfonts); + } + if (fontinfo == NULL) { + bold = regular; + fonts[2].baseline = fonts[1].baseline; + fonts[2].fontstruct = fonts[1].fontstruct; + } else { + bold = fontinfo->fid; + fonts[2].baseline = fontinfo->max_bounds.ascent; + fonts[2].fontstruct = fontinfo; + if (fontinfo->max_bounds.width > W_Textwidth) + W_Textwidth = fontinfo->max_bounds.width; + if (fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent > W_Textheight) + W_Textheight = fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent; + } + + fontname = getdefault("italicfont"); + if (fontname == NULL) { + if (DisplayCells(W_Display, W_Screen) <= 4) + fontname = ITALIC_FONT2; + else + fontname = ITALIC_FONT; + } + fontinfo = XLoadQueryFont(W_Display, fontname); + if (fontinfo == NULL) { + fontinfo = find_font(fontname, _ifonts); + } + if (fontinfo == NULL) { + italic = regular; + fonts[3].baseline = fonts[1].baseline; + fonts[3].fontstruct = fonts[1].fontstruct; + } else { + italic = fontinfo->fid; + fonts[3].baseline = fontinfo->max_bounds.ascent; + fonts[3].fontstruct = fontinfo; + if (fontinfo->max_bounds.width > W_Textwidth) + W_Textwidth = fontinfo->max_bounds.width; + if (fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent > W_Textheight) + W_Textheight = fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent; + } + + fontname = getdefault("bigfont"); + if (fontname == NULL) + fontname = BIG_FONT; + fontinfo = XLoadQueryFont(W_Display, fontname); + if (fontinfo == NULL) { + fontinfo = find_font(fontname, _bgfonts); + } + if (fontinfo == NULL) { + big = regular; + fonts[0].baseline = fonts[1].baseline; + fonts[0].fontstruct = fonts[1].fontstruct; + } else { + big = fontinfo->fid; + fonts[0].baseline = fontinfo->max_bounds.ascent; + fonts[0].fontstruct = fontinfo; + } + for (i = 0; i < NCOLORS; i++) { + values.font = big; + colortable[i].contexts[0] = XCreateGC(W_Display, W_Root, GCFont, &values); + XSetGraphicsExposures(W_Display, colortable[i].contexts[0], False); + values.font = regular; + colortable[i].contexts[1] = XCreateGC(W_Display, W_Root, GCFont, &values); + XSetGraphicsExposures(W_Display, colortable[i].contexts[1], False); + values.font = bold; + colortable[i].contexts[2] = XCreateGC(W_Display, W_Root, GCFont, &values); + XSetGraphicsExposures(W_Display, colortable[i].contexts[2], False); + values.font = italic; + colortable[i].contexts[3] = XCreateGC(W_Display, W_Root, GCFont, &values); + XSetGraphicsExposures(W_Display, colortable[i].contexts[3], False); + { + static char dl[] = {1, 4}; + XSetLineAttributes(W_Display, colortable[i].contexts[3], + 0, LineOnOffDash, CapButt, JoinMiter); + XSetDashes(W_Display, colortable[i].contexts[3], 0, dl, 2); + } + values.function = GXor; + colortable[i].contexts[BITGC] = XCreateGC(W_Display, W_Root, GCFunction, &values); + XSetGraphicsExposures(W_Display, colortable[i].contexts[BITGC], False); + } +} + +static XFontStruct * +find_font(oldf, fonts) + char *oldf, **fonts; +{ + XFontStruct *fi; + char **f; + fprintf(stderr, "netrek: Can't find font %s. Trying others...\n", + oldf); + for (f = fonts; *f; f++) { + if (strcmp(*f, oldf) != 0) { + if ((fi = XLoadQueryFont(W_Display, *f))) + return fi; + } + } + printf("Error - can't find any font!\n"); + return NULL; +} + +#ifdef FOURPLANEFIX +static unsigned short extrared[8] = {0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xb0, 0xc0}; +static unsigned short extragreen[8] = {0x40, 0x60, 0x80, 0xa0, 0xb0, 0xc0, 0x00, 0x20}; +static unsigned short extrablue[8] = {0x80, 0xa0, 0xb0, 0xc0, 0x00, 0x20, 0x40, 0x60}; +#endif + +int +W_Mono() +{ + return forceMono; +} + +static void +GetColors() +{ + int i, j; + XColor foo; + int white, black; + unsigned long pixel; + unsigned long planes[3]; + char defaultstring[100]; + char *defaults; +#ifdef FOURPLANEFIX + unsigned long extracolors[8]; + XColor colordef; +#endif + extern int forceMono; + forceMono = booleanDefault("forcemono", forceMono); + + if ((DisplayCells(W_Display, W_Screen) <= 4) || forceMono) { + forceMono = 1; + white = WhitePixel(W_Display, W_Screen); + black = BlackPixel(W_Display, W_Screen); + for (i = 0; i < NCOLORS; i++) { + if (i != W_Black) { + colortable[i].pixelValue = white; + } else { + colortable[i].pixelValue = black; + } + if (i == W_Red) { + colortable[i].pixmap = XCreatePixmapFromBitmapData + (W_Display, + W_Root, (char *) striped, TILESIDE, TILESIDE, + white, black, + DefaultDepth(W_Display, W_Screen)); + } else if (i == W_Yellow) { + colortable[i].pixmap = XCreatePixmapFromBitmapData + (W_Display, + W_Root, (char *) gray, TILESIDE, TILESIDE, + white, black, + DefaultDepth(W_Display, W_Screen)); + } else { + colortable[i].pixmap = XCreatePixmapFromBitmapData + (W_Display, + W_Root, (char *) solid, TILESIDE, TILESIDE, + colortable[i].pixelValue, + colortable[i].pixelValue, + DefaultDepth(W_Display, W_Screen)); + } + + /* + We assume white is 0 or 1, and black is 0 or 1. We adjust + graphics function based upon who is who. + */ + if (white == 0) { /* Black is 1 */ + XSetFunction(W_Display, colortable[i].contexts[BITGC], GXand); + } + } + } else if (DefaultVisual(W_Display, W_Screen)->class == TrueColor) { +/* Stuff added by sheldon@iastate.edu 5/28/93 + * This is supposed to detect a TrueColor display, and then do a lookup of + * the colors in default colormap, instead of creating new colormap + */ + for (i = 0; i < NCOLORS; i++) { + sprintf(defaultstring, "color.%s", colortable[i].name); + + defaults = getdefault(defaultstring); + if (defaults == NULL) + defaults = colortable[i].name; + XParseColor(W_Display, W_Colormap, defaults, &foo); + XAllocColor(W_Display, W_Colormap, &foo); + colortable[i].pixelValue = foo.pixel; + colortable[i].pixmap = XCreatePixmapFromBitmapData(W_Display, + W_Root, (char *) solid, TILESIDE, TILESIDE, foo.pixel, foo.pixel, + DefaultDepth(W_Display, W_Screen)); + } + } else { +#ifdef FOURPLANEFIX + if (!XAllocColorCells(W_Display, W_Colormap, False, planes, 3, + &pixel, 1)) { + /* couldn't allocate 3 planes, make a new colormap */ + W_Colormap = XCreateColormap(W_Display, W_Root, W_Visual, AllocNone); + if (!XAllocColorCells(W_Display, W_Colormap, False, planes, 3, + &pixel, 1)) { + fprintf(stderr, "Cannot create new colormap\n"); + EXIT(1); + } + /* + and fill it with at least 8 more colors so when mouse is + inside netrek windows, use might be able to see his other + windows + */ + if (XAllocColorCells(W_Display, W_Colormap, False, NULL, 0, + extracolors, 8)) { + colordef.flags = DoRed | DoGreen | DoBlue; + for (i = 0; i < 8; i++) { + colordef.pixel = extracolors[i]; + colordef.red = extrared[i] << 8; + colordef.green = extragreen[i] << 8; + colordef.blue = extrablue[i] << 8; + XStoreColor(W_Display, W_Colormap, &colordef); + } + } + } +#else + XAllocColorCells(W_Display, W_Colormap, False, planes, 3, &pixel, 1); +#endif + for (i = 0; i < NCOLORS; i++) { + /* + strcpy(defaultstring, "color.%s", colortable[i].name); + */ + sprintf(defaultstring, "color.%s", colortable[i].name); + + defaults = getdefault(defaultstring); + if (defaults == NULL) + defaults = colortable[i].name; + XParseColor(W_Display, W_Colormap, defaults, &foo); + /* + Black must be the color with all the planes off. That is the + only restriction I concerned myself with in the following case + statement. + */ + switch (i) { + case WHITE: + foo.pixel = pixel | planes[0] | planes[1] | planes[2]; + break; + case BLACK: + foo.pixel = pixel; + break; + case RED: + foo.pixel = pixel | planes[0]; + break; + case CYAN: + foo.pixel = pixel | planes[1]; + break; + case YELLOW: + foo.pixel = pixel | planes[2]; + break; + case GREY: + foo.pixel = pixel | planes[0] | planes[1]; + break; + case GREEN: + foo.pixel = pixel | planes[1] | planes[2]; + break; + } + XStoreColor(W_Display, W_Colormap, &foo); + colortable[i].pixelValue = foo.pixel; + colortable[i].pixmap = XCreatePixmapFromBitmapData(W_Display, + W_Root, (char *) solid, TILESIDE, TILESIDE, foo.pixel, foo.pixel, + DefaultDepth(W_Display, W_Screen)); + } + } + for (i = 0; i < NCOLORS; i++) { + for (j = 0; j < FONTS + 1; j++) { + XSetForeground(W_Display, colortable[i].contexts[j], + colortable[i].pixelValue); + XSetBackground(W_Display, colortable[i].contexts[j], + colortable[W_Black].pixelValue); + } + } +} + +void +W_RenameWindow(window, str) + W_Window window; + char *str; +{ + XStoreName(W_Display, ((struct window *) window)->window, str); +} + +static W_Window +w_MakeWindow(name, x, y, width, height, parent, + cursname, border, color, wsort) + char *name; + int x, y, width, height; + W_Window parent; + char *cursname; + int border; + W_Color color; + int wsort; /* WIN_? */ +{ + int gx, gy; + struct window *newwin; + Window wparent; + Cursor cursor; + XSetWindowAttributes attrs; + int pwidth, pheight; /* pixel width and height */ + + + checkGeometry(name, &gx, &gy, &width, &height); + if (gx != INVALID_POSITION) + x = gx; + if (gy != INVALID_POSITION) + y = gy; + + checkParent(name, &parent); + wparent = W_Void2Window(parent)->window; + + checkCursor(name, cursname, &cursor); + attrs.cursor = cursor; + + attrs.border_pixel = colortable[color].pixelValue; + attrs.background_pixel = colortable[W_Black].pixelValue; + + if (wsort == WIN_TEXT || wsort == WIN_SCROLL || wsort == WIN_MENU) { + pwidth = width * W_Textwidth + WIN_EDGE * 2; + if (wsort == WIN_MENU) + pheight = height * (W_Textheight + MENU_PAD * 2 + MENU_BAR) - MENU_BAR; + else + pheight = height * W_Textheight + MENU_PAD * 2; + } else { + pwidth = width; + pheight = height; + } + + switch (wsort) { + case WIN_TEXT: + case WIN_MENU: + attrs.event_mask = KeyPressMask | ButtonPressMask | ExposureMask | ButtonReleaseMask; + attrs.do_not_propagate_mask = ExposureMask | KeyPressMask | ButtonPressMask; + break; + case WIN_GRAPH: + attrs.event_mask = KeyPressMask | ButtonPressMask | ExposureMask | LeaveWindowMask | ButtonReleaseMask | ButtonMotionMask; + attrs.do_not_propagate_mask = ExposureMask; + break; + case WIN_SCROLL: + attrs.event_mask = ResizeRedirectMask | ExposureMask | KeyPressMask | ButtonReleaseMask | ButtonPressMask; + attrs.do_not_propagate_mask = ResizeRedirectMask | ExposureMask; + break; + default: + fprintf(stderr, "x11window.c: w_MakeWindow: unknown wsort %d\n", wsort); + } + +#ifdef AUTOKEY + if (attrs.event_mask & KeyPressMask) + attrs.event_mask |= KeyReleaseMask; +#endif /* AUTOKEY */ + + if (strcmp(name, "netrek_icon") == 0) /* icon should not select for + input */ + attrs.event_mask = ExposureMask; + if (strcmp(name, "wait_icon") == 0) /* same here [BDyess] */ + attrs.event_mask = ExposureMask; + + if (strcmp(name, "info") == 0) /* make info window passthru [BDyess] */ + attrs.event_mask = ExposureMask; + + newwin = newWindow + (XCreateWindow(W_Display, wparent, x, y, pwidth, pheight, border, + CopyFromParent, InputOutput, CopyFromParent, + CWBackPixel | CWBorderPixel | CWEventMask | + (cursor ? CWCursor : 0), + &attrs), + wsort); + + newwin->cursor = cursor; + + { + char *s; + + if (0 == strcmp(name, "wait")) + s = serverName; + else if (0 == strcmp(name, "Motd")) + s = "Motd - [f] forward, [b] back, [tab] sysdefs, [space] unmap"; + else if (0 == strcmp(name, "netrek")) { + if (!title) { + char buf[80]; + sprintf(buf, "Netrek @ %s", serverName); + s = buf; + } else { + /* but title on command line will override */ + /* from -h arg */ + s = title; + } + } else + s = name; + + XStoreName(W_Display, newwin->window, s); + } + + wm_size_hint.width = wm_size_hint.min_width = + wm_size_hint.max_width = wm_size_hint.base_width = pwidth; + wm_size_hint.min_height = wm_size_hint.height = + wm_size_hint.max_height = wm_size_hint.base_height = pheight; + wm_size_hint.flags = USSize | PMinSize | PMaxSize | PBaseSize; + if (gx > INVALID_POSITION || gy > INVALID_POSITION) { + wm_size_hint.flags |= USPosition; + wm_size_hint.x = x; + wm_size_hint.y = y; + } + XSetWMNormalHints(W_Display, newwin->window, &wm_size_hint); + + class_hint.res_name = name; + class_hint.res_class = "Netrek"; + XSetClassHint(W_Display, newwin->window, &class_hint); + + XSetWMHints(W_Display, newwin->window, &wm_hint); + + if (((wparent == W_Root && + baseWin != NULL && + strcmp(name, "wait") != 0) + || wsort == WIN_MENU) && + strcmp(name, "MetaServer List") != 0 && + strcmp(name, "Motd") != 0) { + XSetTransientForHint(W_Display, newwin->window, + W_Void2Window(baseWin)->window); + } + newwin->name = strdup(name); + newwin->width = width; + newwin->height = height; + if (wsort == WIN_MENU) { + int i; + struct menuItem *items; + items = (struct menuItem *) malloc(height * sizeof(struct menuItem)); + for (i = 0; i < height; i++) { + items[i].string = NULL; + items[i].color = W_White; + items[i].font = W_RegularFont; + } + newwin->data = (char *) items; + } else { + newwin->data = 0; + } + + if (wparent != W_Root) + if (checkMapped(name)) + W_MapWindow(W_Window2Void(newwin)); + +#ifdef DEBUG + printf("New graphics window %d, child of %d\n", newwin, parent); +#endif + +#ifdef FOURPLANEFIX + XSetWindowColormap(W_Display, newwin->window, W_Colormap); +#endif + + return (W_Window2Void(newwin)); +} + + + + +W_Window +W_MakeWindow(name, x, y, width, height, parent, cursname, border, color) + char *name; + int x, y, width, height; + W_Window parent; + char *cursname; + int border; + W_Color color; +{ + return w_MakeWindow(name, x, y, width, height, parent, + cursname, border, color, WIN_GRAPH); +} + +void +W_ChangeBorder(window, color) + W_Window window; + int color; +{ +#ifdef DEBUG + printf("Changing border of %d\n", window); +#endif + + /* fix inexplicable color bug */ + if (DisplayCells(W_Display, W_Screen) <= 2) + XSetWindowBorderPixmap(W_Display, W_Void2Window(window)->window, + colortable[color].pixmap); + else + XSetWindowBorder(W_Display, W_Void2Window(window)->window, + colortable[color].pixelValue); +} + +void +W_MapWindow(window) + W_Window window; +{ + struct window *win; + +#ifdef DEBUG + printf("Mapping %d\n", window); +#endif + win = W_Void2Window(window); + if (win->mapped) + return; + win->mapped = 1; + XMapRaised(W_Display, win->window); +} + +void +W_UnmapWindow(window) + W_Window window; +{ + struct window *win; + +#ifdef DEBUG + printf("UnMapping %d\n", window); +#endif + win = W_Void2Window(window); + if (win->mapped == 0) + return; + win->mapped = 0; + XUnmapWindow(W_Display, win->window); +} + +int +W_IsMapped(window) + W_Window window; +{ + struct window *win; + + win = W_Void2Window(window); + if (win == NULL) + return (0); + return (win->mapped); +} + +void +W_FillArea(window, x, y, width, height, color) + W_Window window; + int x, y, width, height; + W_Color color; +{ + struct window *win; + +#ifdef DEBUG + printf("Clearing (%d %d) x (%d %d) with %d on %d\n", x, y, width, height, + color, window); +#endif + win = W_Void2Window(window); + switch (win->type) { + case WIN_GRAPH: + XFillRectangle(W_Display, win->window, colortable[color].contexts[0], + x, y, width, height); + break; + default: + XFillRectangle(W_Display, win->window, colortable[color].contexts[0], + WIN_EDGE + x * W_Textwidth, MENU_PAD + y * W_Textheight, + width * W_Textwidth, height * W_Textheight); + } +} + +/* XFIX */ + +static XRectangle _rcache[MAXCACHE]; +static int _rcache_index; + +static void +FlushClearAreaCache(win) + Window win; +{ + XFillRectangles(W_Display, win, colortable[backColor].contexts[0], + _rcache, _rcache_index); + _rcache_index = 0; +} + +/* local window only */ +void +W_CacheClearArea(window, x, y, width, height) + W_Window window; + int x, y, width, height; +{ + Window win = W_Void2Window(window)->window; + register XRectangle *r; + + if (_rcache_index == MAXCACHE) + FlushClearAreaCache(win); + + r = &_rcache[_rcache_index++]; + r->x = (short) x; + r->y = (short) y; + r->width = (unsigned short) width; + r->height = (unsigned short) height; +} + +void +W_FlushClearAreaCache(window) + W_Window window; +{ + Window win = W_Void2Window(window)->window; + + if (_rcache_index) + FlushClearAreaCache(win); +} + +/* XFIX: clears now instead of filling. */ +void +W_ClearArea(window, x, y, width, height) + W_Window window; + int x, y, width, height; +{ + struct window *win; + +#ifdef DEBUG + printf("Clearing (%d %d) x (%d %d) with %d on %d\n", x, y, width, height, + color, window); +#endif + win = W_Void2Window(window); + switch (win->type) { + case WIN_GRAPH: + /* XFIX: changed */ + XClearArea(W_Display, win->window, x, y, width, height, False); + break; + default: + /* XFIX: changed */ + XClearArea(W_Display, win->window, WIN_EDGE + x * W_Textwidth, + MENU_PAD + y * W_Textheight, width * W_Textwidth, height * W_Textheight, False); + break; + } +} + +void +W_ClearWindow(window) + W_Window window; +{ +#ifdef DEBUG + printf("Clearing %d\n", window); +#endif + XClearWindow(W_Display, W_Void2Window(window)->window); +} + +void +W_GetEvent(wevent) + W_Event *wevent; +{ +/* blocks until an event is received [BDyess] */ + XEvent event; + + if (W_isEvent) { + *wevent = W_myevent; + W_isEvent = 0; + return; + } + XNextEvent(W_Display, &event); + XPutBackEvent(W_Display, &event); + W_SpNextEvent(wevent); +} + +int +W_EventsPending() +{ + if (W_isEvent) + return (1); + while (XPending(W_Display) || buttonDown) { + if (W_SpNextEvent(&W_myevent)) { + W_isEvent = 1; + return (1); + } + } + return (0); +} + +void +W_NextEvent(wevent) + W_Event *wevent; +{ + if (W_isEvent) { + *wevent = W_myevent; + W_isEvent = 0; + return; + } + while (W_SpNextEvent(wevent) == 0); +} + +static int +W_SpNextEvent(wevent) + W_Event *wevent; +{ + XEvent event; + XKeyEvent *key; + XButtonEvent *button; + XExposeEvent *expose; + XResizeRequestEvent *resize; + char ch; + struct window *win; +#ifdef CONTINUOUS_MOUSE + static W_Event buttonEvent; + static int delay, cupd = -1; +#endif /* CONTINUOUS_MOUSE */ + +#ifdef DEBUG + printf("Getting an event...\n"); +#endif + key = (XKeyEvent *) & event; + button = (XButtonEvent *) & event; + expose = (XExposeEvent *) & event; + resize = (XResizeRequestEvent *) & event; + for (;;) { + if (XPending(W_Display)) + XNextEvent(W_Display, &event); +#ifdef CONTINUOUS_MOUSE + else if (buttonDown) { + if (continuousMouse && allowContinuousMouse) { + if (cupd != udcounter) { + cupd = udcounter; + if (delay == 0) { + bcopy(&buttonEvent, wevent, sizeof(W_Event)); + delay = clickDelay; + } else { + delay--; + wevent->type = -1; + } + } else + wevent->type = -1; + exitInputLoop = 1; + } else { + wevent->type = -1; + buttonDown = 0; + } + return (1); + } +#endif + else + return (0); + /* + printf("read an event %d\n", event.type); + */ + win = findWindow(key->window); + if (win == NULL) + return (0); + if ((event.type == KeyPress || event.type == ButtonPress) && + win->type == WIN_MENU) { + if (key->y % (W_Textheight + MENU_PAD * 2 + MENU_BAR) >= + W_Textheight + MENU_PAD * 2) + return (0); + key->y = key->y / (W_Textheight + MENU_PAD * 2 + MENU_BAR); + } + switch ((int) event.type) { + case LeaveNotify: /* for message window -- jfy */ + if (win == (struct window *) messagew) { + W_in_message = 0; + } + return (0); + break; + case KeyPress: + if (key->state & ControlMask) { + controlkey = 1; + key->state &= ~ControlMask; + } else + controlkey = 0; + if (key->state & BillsScrewyAltMask) { + altkey = 1; + key->state &= ~BillsScrewyAltMask; + } else + altkey = 0; + if (XLookupString(key, &ch, 1, NULL, NULL) > 0) { + wevent->type = W_EV_KEY; + wevent->Window = W_Window2Void(win); + wevent->x = key->x; + wevent->y = key->y; + if (controlkey) + wevent->key = (int) ch + 128; + else if (altkey) + wevent->key = (int) ch + 256; + else + wevent->key = ch; + return (1); + } + return (0); + break; +#ifdef AUTOKEY + case KeyRelease: + if (XLookupString(key, &ch, 1, NULL, NULL) > 0) { + wevent->type = W_EV_KEY_OFF; + wevent->Window = W_Window2Void(win); + wevent->x = key->x; + wevent->y = key->y; + wevent->key = ch; + return (1); + } + return (0); + break; +#endif /* AUTOKEY */ + case ButtonPress: + wevent->type = W_EV_BUTTON; + wevent->Window = W_Window2Void(win); + wevent->x = button->x; + wevent->y = button->y; + switch (button->button & 0xf) { + case Button3: + wevent->key = W_RBUTTON; + break; + case Button1: + wevent->key = W_LBUTTON; + break; + case Button2: + wevent->key = W_MBUTTON; + break; + } + if (key->state & ControlMask) + wevent->key += 6; + if (key->state & ShiftMask) + wevent->key += 3; + if (key->state & BillsScrewyAltMask) + wevent->key += 12; /* alt */ +#ifdef CONTINUOUS_MOUSE + if (continuousMouse && allowContinuousMouse && + (wevent->Window == w || wevent->Window == mapw) && + /* + buttonRepeatMask allows only certain buttons to repeat + [BDyess] + */ + (1 << (wevent->key) & buttonRepeatMask)) { + buttonDown = 1; + exitInputLoop = 1; + delay = clickDelay; + bcopy(wevent, &buttonEvent, sizeof(W_Event)); + } + return (1); + case ButtonRelease: + /* bcopy(&buttonEvent,wevent,sizeof(W_Event)); */ + wevent->type = -1; + buttonDown = 0; + return (1); + case MotionNotify: + /* + the !buttonDown ensures that if you press a button and then + press another, release just the second, and then move the + mouse that nothing happens. + */ + if (!(continuousMouse && allowContinuousMouse) || !buttonDown) { + wevent->type = -1; + return (1); + } + wevent->type = W_EV_BUTTON; + wevent->Window = W_Window2Void(win); + wevent->x = button->x; + wevent->y = button->y; + wevent->key = buttonEvent.key; + bcopy(wevent, &buttonEvent, sizeof(W_Event)); + if (cupd == udcounter) + wevent->type = -1; + else + cupd = udcounter; + + return (1); +#else + return (1); +#endif /* CONTINUOUS_MOUSE */ + case Expose: + if (expose->count != 0) + return (0); + if (win->type == WIN_SCROLL) { + redrawScrolling(win); + return (0); + } + if (win->type == WIN_MENU) { + redrawMenu(win); + return (0); + } + wevent->type = W_EV_EXPOSE; + wevent->Window = W_Window2Void(win); + return (1); + case ResizeRequest: + resizeScrolling(win, resize->width, resize->height); + break; + default: + return (0); + break; + } + } +} + +void +W_MakeLine(window, x0, y0, x1, y1, color) + W_Window window; + int x0, y0, x1, y1; + W_Color color; +{ + Window win; + +#ifdef DEBUG + printf("Line on %d\n", window); +#endif + win = W_Void2Window(window)->window; + XDrawLine(W_Display, win, colortable[color].contexts[0], x0, y0, x1, y1); +} + +void +W_DrawPoint(window, x, y, color) + W_Window window; + int x, y; + W_Color color; +{ + Window win; + +#ifdef DEBUG + printf("Point on %d\n", window); +#endif + win = W_Void2Window(window)->window; + XDrawPoint(W_Display, win, colortable[color].contexts[0], x, y); +} + +/* XFIX */ + +static XSegment _lcache[NCOLORS][MAXCACHE]; +static int _lcache_index[NCOLORS]; + +static void +FlushLineCache(win, color) + Window win; + int color; +{ + XDrawSegments(W_Display, win, colortable[color].contexts[0], + _lcache[color], _lcache_index[color]); + _lcache_index[color] = 0; +} + +/* for local window only */ +void +W_CacheLine(window, x0, y0, x1, y1, color) + W_Window window; + int x0, y0, x1, y1, color; +{ + Window win = W_Void2Window(window)->window; + register XSegment *s; + + if (_lcache_index[color] == MAXCACHE) + FlushLineCache(win, color); + + s = &_lcache[color][_lcache_index[color]++]; + s->x1 = (short) x0; + s->y1 = (short) y0; + s->x2 = (short) x1; + s->y2 = (short) y1; +} + +void +W_FlushLineCaches(window) + W_Window window; +{ + Window win = W_Void2Window(window)->window; + register i; + for (i = 0; i < NCOLORS; i++) { + if (_lcache_index[i]) + FlushLineCache(win, i); + } +} + +static XPoint _pcache[NCOLORS][MAXCACHE]; +static int _pcache_index[NCOLORS]; + +static void +FlushPointCache(win, color) + Window win; + int color; +{ + XDrawPoints(W_Display, win, colortable[color].contexts[0], + _pcache[color], _pcache_index[color], CoordModeOrigin); + _pcache_index[color] = 0; +} + +void +W_CachePoint(window, x, y, color) + W_Window window; + int x, y, color; +{ + Window win = W_Void2Window(window)->window; + register XPoint *p; + + if (_pcache_index[color] == MAXCACHE) + FlushPointCache(win, color); + + p = &_pcache[color][_pcache_index[color]++]; + p->x = (short) x; + p->y = (short) y; +} + +void +W_FlushPointCaches(window) + W_Window window; +{ + Window win = W_Void2Window(window)->window; + register i; + for (i = 0; i < NCOLORS; i++) { + if (_pcache_index[i]) + FlushPointCache(win, i); + } +} + +void +W_MakeTractLine(window, x0, y0, x1, y1, color) + W_Window window; + int x0, y0, x1, y1; + W_Color color; +{ + Window win; + +#ifdef DEBUG + printf("Line on %d\n", window); +#endif + win = W_Void2Window(window)->window; + XDrawLine(W_Display, win, colortable[color].contexts[3], x0, y0, x1, y1); +} + +void +W_DrawSectorHighlight(window, x, y, w, h, color) + W_Window window; + int x, y, w, h; + W_Color color; +{ + Window win; +#ifdef YUCK + XRectangle r[2]; + + r[0].x = (short) x; + r[0].y = (short) y; + r[0].width = (unsigned short) w; + r[0].height = (unsigned short) h; + r[1].x = (short) x + 2; + r[1].y = (short) y + 2; + r[1].width = (unsigned short) w - 4; + r[1].height = (unsigned short) h - 4; + + win = W_Void2Window(window)->window; + XDrawRectangles(W_Display, win, colortable[color].contexts[3], + r, 2); +#else + XRectangle r[1]; + + r[0].x = (short) x + 2; + r[0].y = (short) y + 2; + r[0].width = (unsigned short) w - 4; + r[0].height = (unsigned short) h - 4; + + win = W_Void2Window(window)->window; + XDrawRectangles(W_Display, win, colortable[color].contexts[3], + r, 1); +#endif +} + +void +W_WriteTriangle(window, x, y, s, t, color) + W_Window window; + int x, y, s; + int t; + W_Color color; +{ + struct window *win = W_Void2Window(window); + XPoint points[3]; + + if (t == 0) { + points[0].x = x; + points[0].y = y; + points[1].x = x + s; + points[1].y = y - s; + points[2].x = x - s; + points[2].y = y - s; + } else { + points[0].x = x; + points[0].y = y; + points[1].x = x + s; + points[1].y = y + s; + points[2].x = x - s; + points[2].y = y + s; + } + + + XFillPolygon(W_Display, win->window, colortable[color].contexts[0], + points, 3, Convex, CoordModeOrigin); +} + +void +W_WriteText(window, x, y, color, str, len, font) + W_Window window; + int x, y, len; + W_Color color; + W_Font font; + char *str; +{ + struct window *win; + int addr; + + if (!font) + font = W_RegularFont; +#ifdef DEBUG + printf("Text for %d @ (%d, %d) in %d: [%s]\n", window, x, y, color, str); +#endif + win = W_Void2Window(window); + switch (win->type) { + case WIN_GRAPH: + addr = fonts[fontNum(font)].baseline; + XDrawImageString(W_Display, win->window, + colortable[color].contexts[fontNum(font)], x, y + addr, str, len); + break; + case WIN_SCROLL: + if (y<0) { + XCopyArea(W_Display, win->window, win->window, + + colortable[W_White].contexts[0], WIN_EDGE, MENU_PAD, + win->width * W_Textwidth, (win->height - 1) * W_Textheight, + WIN_EDGE, MENU_PAD+W_Textheight); + XClearArea(W_Display, win->window, + WIN_EDGE, MENU_PAD, + W_Textwidth * win->width, W_Textheight, False); + XDrawImageString(W_Display, win->window, + colortable[color].contexts[1], + WIN_EDGE, MENU_PAD + fonts[1].baseline, + str, len); + } else { + XCopyArea(W_Display, win->window, win->window, + colortable[W_White].contexts[0], WIN_EDGE, MENU_PAD + W_Textheight, + win->width * W_Textwidth, (win->height - 1) * W_Textheight, + WIN_EDGE, MENU_PAD); + XClearArea(W_Display, win->window, + WIN_EDGE, MENU_PAD + W_Textheight * (win->height - 1), + W_Textwidth * win->width, W_Textheight, False); + XDrawImageString(W_Display, win->window, + colortable[color].contexts[1], + WIN_EDGE, MENU_PAD + W_Textheight * (win->height - 1) + fonts[1].baseline, + str, len); + } + AddToScrolling(win, color, str, len); + break; + case WIN_MENU: + changeMenuItem(win, y, color, str, len, font); + break; + default: + addr = fonts[fontNum(font)].baseline; + XDrawImageString(W_Display, win->window, + colortable[color].contexts[fontNum(font)], + x * W_Textwidth + WIN_EDGE, MENU_PAD + y * W_Textheight + addr, + str, len); + break; + } +} + +void +W_MaskText(window, x, y, color, str, len, font) + W_Window window; + int x, y, len; + W_Color color; + W_Font font; + char *str; +{ + struct window *win; + int addr; + + addr = fonts[fontNum(font)].baseline; +#ifdef DEBUG + printf("TextMask for %d @ (%d, %d) in %d: [%s]\n", window, x, y, color, str); +#endif + win = W_Void2Window(window); + XDrawString(W_Display, win->window, + colortable[color].contexts[fontNum(font)], x, y + addr, str, len); +} + +W_Icon +W_StoreBitmap(width, height, data, window) + int width, height; + W_Window window; + char *data; +{ + struct icon *newicon; + struct window *win; + +#ifdef DEBUG + printf("Storing bitmap for %d (%d x %d)\n", window, width, height); + fflush(stdout); +#endif + win = W_Void2Window(window); + newicon = (struct icon *) malloc(sizeof(struct icon)); + newicon->width = width; + newicon->height = height; + newicon->bitmap = XCreateBitmapFromData(W_Display, win->window, + data, width, height); + newicon->window = win->window; + newicon->pixmap = 0; + return (W_Icon2Void(newicon)); +} + +void +W_FreeBitmap(bit) + W_Icon bit; +{ + struct icon *icon; + icon = W_Void2Icon(bit); + XFreePixmap(W_Display, icon->bitmap); + free(icon); +} + +void +W_WriteBitmap(x, y, bit, color) + int x, y; + W_Icon bit; + W_Color color; +{ + struct icon *icon; + + icon = W_Void2Icon(bit); +#ifdef DEBUG + printf("Writing bitmap to %d\n", icon->window); +#endif + + XCopyPlane(W_Display, icon->bitmap, icon->window, + colortable[color].contexts[BITGC], 0, 0, icon->width, icon->height, + x, y, 1); + +} + +void +W_WriteWinBitmap(win, x, y, bit, color) + W_Window win; + int x, y; + W_Icon bit; + W_Color color; +{ + struct icon *icon; + Window original; + + icon = W_Void2Icon(bit); + original = icon->window; + icon->window = W_Void2Window(win)->window; + W_WriteBitmap(x, y, bit, color); + icon->window = original; + return; +} + +void +W_TileWindow(window, bit) + W_Window window; + W_Icon bit; +{ + Window win; + struct icon *icon; + +#ifdef DEBUG + printf("Tiling window %d\n", window); +#endif + icon = W_Void2Icon(bit); + win = W_Void2Window(window)->window; + + if (icon->pixmap == 0) { + icon->pixmap = XCreatePixmap(W_Display, W_Root, + icon->width, icon->height, DefaultDepth(W_Display, W_Screen)); + XCopyPlane(W_Display, icon->bitmap, icon->pixmap, + colortable[W_White].contexts[0], 0, 0, icon->width, icon->height, + 0, 0, 1); + } + XSetWindowBackgroundPixmap(W_Display, win, icon->pixmap); + XClearWindow(W_Display, win); + + /* + if (icon->pixmap==0) { icon->pixmap=XMakePixmap(icon->bitmap, + colortable[W_White].pixelValue, colortable[W_Black].pixelValue); } + XChangeBackground(win, icon->pixmap); XClear(win); + */ +} + +void +W_UnTileWindow(window) + W_Window window; +{ + Window win; + +#ifdef DEBUG + printf("Untiling window %d\n", window); +#endif + win = W_Void2Window(window)->window; + + XSetWindowBackground(W_Display, win, colortable[W_Black].pixelValue); + XClearWindow(W_Display, win); +} + +W_Window +W_MakeTextWindow(name, x, y, width, height, parent, cursname, border) + char *name; + int x, y, width, height; + W_Window parent; + char *cursname; + int border; +{ + return w_MakeWindow(name, x, y, width, height, + parent, cursname, border, W_White, WIN_TEXT); +} + +struct window * +newWindow(window, type) + Window window; + int type; +{ + struct window *newwin; + + newwin = (struct window *) malloc(sizeof(struct window)); + newwin->window = window; + newwin->type = type; + newwin->mapped = 0; + newwin->insensitive = 0; + addToHash(newwin); + return (newwin); +} + + +static struct window * +findWindow(window) + Window window; +{ + struct windowlist *entry; + + entry = hashtable[hash(window)]; + while (entry != NULL) { + if (entry->window->window == window) + return (entry->window); + entry = entry->next; + } + return (NULL); +} + +static void +addToHash(win) + struct window *win; +{ + struct windowlist **new; + +#ifdef DEBUG + printf("Adding to %d\n", hash(win->window)); +#endif + new = &hashtable[hash(win->window)]; + while (*new != NULL) { + new = &((*new)->next); + } + *new = (struct windowlist *) malloc(sizeof(struct windowlist)); + (*new)->next = NULL; + (*new)->window = win; +} + +W_Window +W_MakeScrollingWindow(name, x, y, width, height, parent, cursname, border) + char *name; + int x, y, width, height; + W_Window parent; + char *cursname; + int border; +{ + return w_MakeWindow(name, x, y, width, height, parent, cursname, + border, W_White, WIN_SCROLL); +} + +/* Add a string to the string list of the scrolling window. + */ +static void +AddToScrolling(win, color, str, len) + struct window *win; + W_Color color; + char *str; + int len; +{ + struct stringList **strings; + char *newstring; + int count; + + strings = (struct stringList **) & (win->data); + count = 0; + while ((*strings) != NULL) { + count++; + strings = &((*strings)->next); + } + (*strings) = (struct stringList *) malloc(sizeof(struct stringList)); + (*strings)->next = NULL; + (*strings)->color = color; + newstring = (char *) malloc(len + 1); + strncpy(newstring, str, len); + newstring[len] = 0; + (*strings)->string = newstring; + if (count >= 100) { /* Arbitrary large size. */ + struct stringList *temp; + + temp = (struct stringList *) win->data; + free(temp->string); + temp = temp->next; + free((char *) win->data); + win->data = (char *) temp; + } +} + +#ifdef SHORT_PACKETS +void +W_SetSensitive(w, v) + W_Window w; + int v; +{ + struct window *win = W_Void2Window(w); + + win->insensitive = !v; + + if (win->type == WIN_SCROLL) + redrawScrolling(win); +} +#endif + +static void +redrawScrolling(win) + struct window *win; +{ + int count; + struct stringList *list; + int y; + + XClearWindow(W_Display, win->window); + count = 0; + list = (struct stringList *) win->data; + while (list != NULL) { + list = list->next; + count++; + } + list = (struct stringList *) win->data; + while (count > win->height) { + list = list->next; + count--; + } + y = (win->height - count) * W_Textheight + fonts[1].baseline; + if (count == 0) + return; + while (list != NULL) { + XDrawImageString(W_Display, win->window, + colortable[list->color].contexts[1], + WIN_EDGE, MENU_PAD + y, list->string, strlen(list->string)); + list = list->next; + y = y + W_Textheight; + } +} + +static void +resizeScrolling(win, width, height) + struct window *win; + int width, height; +{ + win->height = (height - MENU_PAD * 2) / W_Textheight; + win->width = (width - WIN_EDGE * 2) / W_Textwidth; + XResizeWindow(W_Display, win->window, win->width * W_Textwidth + WIN_EDGE * 2, + win->height * W_Textheight + MENU_PAD * 2); +} + +W_Window +W_MakeMenu(name, x, y, width, height, parent, border) + char *name; + int x, y, width, height; + W_Window parent; + int border; +{ + return w_MakeWindow(name, x, y, width, height, parent, + "left_ptr", border, W_White, WIN_MENU); +} + +static void +redrawMenu(win) + struct window *win; +{ + int count; + + for (count = 1; count < win->height; count++) { + XFillRectangle(W_Display, win->window, + colortable[W_Grey].contexts[0], + 0, count * (W_Textheight + MENU_PAD * 2) + (count - 1) * MENU_BAR, + win->width * W_Textwidth + WIN_EDGE * 2, MENU_BAR); + } + for (count = 0; count < win->height; count++) { + redrawMenuItem(win, count); + } +} + +static void +redrawMenuItem(win, n) + struct window *win; + int n; +{ + struct menuItem *items; + int addr; + + items = (struct menuItem *) win->data; + + XFillRectangle(W_Display, win->window, + colortable[W_Black].contexts[0], + WIN_EDGE, n * (W_Textheight + MENU_PAD * 2 + MENU_BAR) + MENU_PAD, + win->width * W_Textwidth, W_Textheight); + if (items[n].string) { + addr = fonts[fontNum(items[n].font)].baseline; + XDrawImageString(W_Display, win->window, + colortable[items[n].color].contexts[fontNum(items[n].font)], + WIN_EDGE, + n * (W_Textheight + MENU_PAD * 2 + MENU_BAR) + MENU_PAD + addr, + items[n].string, strlen(items[n].string)); + } +} + +static void +changeMenuItem(win, n, color, str, len, font) + struct window *win; + int n; + W_Color color; + char *str; + int len; + W_Font font; +{ + struct menuItem *items; + char *news; + + items = (struct menuItem *) win->data; + if (items[n].string) { + free(items[n].string); + } + news = malloc(len + 1); + strncpy(news, str, len); + news[len] = 0; + items[n].string = news; + items[n].color = color; + items[n].font = font; + redrawMenuItem(win, n); + XFlush(W_Display); +} + +static Cursor +make_cursor(bits, mask, width, height, xhot, yhot) + char *bits, *mask; + int width, height, xhot, yhot; +{ + Pixmap cursbits; + Pixmap cursmask; + XColor whiteCol, blackCol; + Cursor curs; + + whiteCol.pixel = colortable[W_White].pixelValue; + XQueryColor(W_Display, W_Colormap, &whiteCol); + blackCol.pixel = colortable[W_Black].pixelValue; + XQueryColor(W_Display, W_Colormap, &blackCol); + + cursbits = XCreateBitmapFromData(W_Display, DefaultRootWindow(W_Display), + bits, width, height); + cursmask = XCreateBitmapFromData(W_Display, DefaultRootWindow(W_Display), + mask, width, height); + + curs = XCreatePixmapCursor(W_Display, cursbits, cursmask, + &whiteCol, &blackCol, xhot, yhot); + + XFreePixmap(W_Display, cursbits); + XFreePixmap(W_Display, cursmask); + return curs; +} + +#ifdef TCURSORS +#if 1 + +void +W_DefineTCrossCursor(window) + W_Window window; +{ + return; +} + +void +W_DefineTextCursor(window) + W_Window window; +{ + static Cursor new = 0; + struct window *win = W_Void2Window(window); + XColor f, b; + + if (!new) { + f.pixel = colortable[W_Yellow].pixelValue; + b.pixel = colortable[W_Black].pixelValue; + + XQueryColor(W_Display, W_Colormap, &f); + XQueryColor(W_Display, W_Colormap, &b); + + new = XCreateFontCursor(W_Display, XC_xterm); + + XRecolorCursor(W_Display, new, &f, &b); + } + XDefineCursor(W_Display, win->window, new); + + return; +} + +void +W_RevertCursor(window) + W_Window window; +{ + struct window *win = W_Void2Window(window); + + XDefineCursor(W_Display, win->window, win->cursor); + + return; +} + +void +W_DefineCursor(window, width, height, bits, mask, xhot, yhot) + W_Window window; + int width, height, xhot, yhot; + char *bits, *mask; +{ + return; +} + +#else + +#ifdef YUCK +void +W_DefineTCrossCursor(window) + W_Window window; +{ + static + Cursor new; + struct window *win = W_Void2Window(window); + static + XColor f, b; + + if (new) { + XDefineCursor(W_Display, win->window, new); + return; + } + f.pixel = colortable[W_White].pixelValue; + b.pixel = colortable[W_Black].pixelValue; + + XQueryColor(W_Display, W_Colormap, &f); + XQueryColor(W_Display, W_Colormap, &b); + + new = XCreateFontCursor(W_Display, XC_tcross); + XRecolorCursor(W_Display, new, &f, &b); + XDefineCursor(W_Display, win->window, new); +} + +#else +W_DefineTCrossCursor(window) + W_Window window; +{ + W_DefineCursor(window, cross_width, cross_height, + cross_bits, crossmask_bits, cross_x_hot, cross_y_hot); +} + +#endif + +void +W_DefineTextCursor(window) + W_Window window; +{ + static + Cursor new; + struct window *win = W_Void2Window(window); + XColor f, b; + + if (new) { + XDefineCursor(W_Display, win->window, new); + return; + } + f.pixel = colortable[W_Yellow].pixelValue; + b.pixel = colortable[W_Black].pixelValue; + + XQueryColor(W_Display, W_Colormap, &f); + XQueryColor(W_Display, W_Colormap, &b); + + new = XCreateFontCursor(W_Display, XC_xterm); + XRecolorCursor(W_Display, new, &f, &b); + XDefineCursor(W_Display, win->window, new); +} + +void +W_DefineCursor(window, width, height, bits, mask, xhot, yhot) + W_Window window; + int width, height, xhot, yhot; + char *bits, *mask; +{ + static char *oldbits = NULL; + static Cursor curs; + struct window *win; + +#ifdef DEBUG + printf("Defining cursor for %d\n", window); +#endif + win = W_Void2Window(window); + if (!oldbits || oldbits != bits) { + oldbits = bits; + curs = make_cursor(bits, mask, width, height, xhot, yhot); + } + XDefineCursor(W_Display, win->window, curs); +} +#endif +#endif + +void +W_Beep() +{ + XBell(W_Display, 0); +} + +int +W_WindowWidth(window) + W_Window window; +{ + return (W_Void2Window(window)->width); +} + +int +W_WindowHeight(window) + W_Window window; +{ + return (W_Void2Window(window)->height); +} + +int +W_Socket() +{ + return (ConnectionNumber(W_Display)); +} + +void +W_DestroyWindow(window) + W_Window window; +{ + struct window *win; + +#ifdef DEBUG + printf("Destroying %d\n", window); +#endif + win = W_Void2Window(window); + deleteWindow(win); + XDestroyWindow(W_Display, win->window); + free((char *) win); +} + +static void +deleteWindow(window) + struct window *window; +{ + struct windowlist **rm; + struct windowlist *temp; + + rm = &hashtable[hash(window->window)]; + while (*rm != NULL && (*rm)->window != window) { + rm = &((*rm)->next); + } + if (*rm == NULL) { + printf("Attempt to delete non-existent window!\n"); + return; + } + temp = *rm; + *rm = temp->next; + free((char *) temp); +} + +void +W_SetIconWindow(main, icon) + W_Window main; + W_Window icon; +{ + XWMHints hints; + + XSetIconName(W_Display, W_Void2Window(icon)->window, W_Void2Window(main)->name); + + hints.flags = IconWindowHint; + hints.icon_window = W_Void2Window(icon)->window; + XSetWMHints(W_Display, W_Void2Window(main)->window, &hints); +} + +static void +checkGeometry(name, x, y, width, height) + char *name; + int *x, *y, *width, *height; +/* fixed so that it handles negative positions 12/21/93 */ +/* note that this is NOT standard X syntax, but it was requested */ +/* and it's how BRM-Hadley works. [BDyess] */ +{ + char *adefault; + char buf[100]; + char *s; + +#ifdef RJC + *x = *y = INVALID_POSITION; +#endif /* RJC */ + + sprintf(buf, "%s.geometry", name); + adefault = getdefault(buf); + if (adefault == NULL) + return; + /* geometry should be of the form 502x885+1+1, 502x885, or +1+1 */ + s = adefault; + if (*s != '+' && *s != '-') { + while (*s != 'x' && *s != 0) + s++; + *width = atoi(adefault); + if (*s == 0) + return; + s++; + adefault = s; + while (*s != '+' && *s != '-' && *s != 0) + s++; + *height = atoi(adefault); + if (*s == 0) + return; + } + adefault = s; + s++; + if (*s == '-') + s++; /* for the case where they have wxh+-x+y */ + while (*s != '+' && *s != '-' && *s != 0) + s++; + *x = atoi(adefault + 1); + if (*adefault == '-') + *x = -*x; + if (*s == 0) + return; + *y = atoi(s + 1); + if (*s == '-') + *y = -*y; + /* printf("width: %d, height: %d, x: %d, y: %d\n",*width, *height,*x,*y); */ + return; +} + +static void +checkParent(name, parent) + char *name; + W_Window *parent; +{ + char *adefault; + char buf[100]; + int i; + struct windowlist *windows; + + sprintf(buf, "%s.parent", name); + adefault = getdefault(buf); + if (adefault == NULL) + return; + /* parent must be name of other window or "root" */ + if (strcmpi(adefault, "root") == 0) { + *parent = W_Window2Void(&myroot); + return; + } + for (i = 0; i < HASHSIZE; i++) { + windows = hashtable[i]; + while (windows != NULL) { + if (strcmpi(adefault, windows->window->name) == 0) { + *parent = W_Window2Void(windows->window); + return; + } + windows = windows->next; + } + } +} + +#ifdef YUCK +#define cross_width 15 +#define cross_height 15 +#define cross_x_hot 7 +#define cross_y_hot 7 +static unsigned char cross_bits[] = { + 0x00, 0x00, 0xc0, 0x01, 0xa0, 0x02, 0x00, 0x00, 0x80, 0x00, 0x04, 0x10, 0x82, 0x20, 0x56, +0x35, 0x82, 0x20, 0x04, 0x10, 0x80, 0x00, 0x00, 0x00, 0xa0, 0x02, 0xc0, 0x01, 0x00, 0x00}; +static unsigned char crossmask_bits[] = { + 0xe0, 0x03, 0xf0, 0x07, 0xf0, 0x07, 0xf0, 0x07, 0xce, 0x39, 0xcf, 0x79, 0xff, 0x7f, 0xff, +0x7f, 0xff, 0x7f, 0xcf, 0x79, 0xce, 0x39, 0xf0, 0x07, 0xf0, 0x07, 0xf0, 0x07, 0xe0, 0x03}; +#else +#define cross_width 16 +#define cross_height 16 +#define cross_x_hot 7 +#define cross_y_hot 7 +static unsigned char cross_bits[] = { + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xc0, 0x01, 0x80, 0x00, + 0x10, 0x04, 0x3f, 0x7e, 0x10, 0x04, 0x80, 0x00, 0xc0, 0x01, 0x80, 0x00, +0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00}; +static unsigned char crossmask_bits[] = { + 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xe0, 0x03, 0xd0, 0x05, + 0xbf, 0x7e, 0x7f, 0x7f, 0xbf, 0x7e, 0xd0, 0x05, 0xe0, 0x03, 0xc0, 0x01, +0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0x00, 0x00}; +#endif + +static void +checkCursor(name, cursname, cursor) + char *name; + char *cursname; + Cursor *cursor; +{ + char buf[100]; + unsigned cnum; + char *adefault; + + *cursor = 0; + + sprintf(buf, "%s.cursor", name); + adefault = getdefault(buf); + if (adefault == NULL) + adefault = cursname; + if (adefault == NULL) + return; + +#ifdef RFCURSORS + cnum = XmuCursorNameToIndex(adefault); + if (cnum != -1) { + XColor f, b; + *cursor = XCreateFontCursor(W_Display, cnum); + if (cnum == XC_xterm) { + + f.pixel = colortable[W_Yellow].pixelValue; + b.pixel = colortable[W_Black].pixelValue; + + XQueryColor(W_Display, W_Colormap, &f); + XQueryColor(W_Display, W_Colormap, &b); + + XRecolorCursor(W_Display, *cursor, &f, &b); + } else if (cnum == XC_pirate) { + f.pixel = colortable[W_Red].pixelValue; + b.pixel = colortable[W_Black].pixelValue; + + XQueryColor(W_Display, W_Colormap, &f); + XQueryColor(W_Display, W_Colormap, &b); + + XRecolorCursor(W_Display, *cursor, &f, &b); + } + } else +#endif + if (0 == strcmp("bomb here", adefault)) { + static Cursor bomb_here = 0; + if (bomb_here == 0) { + bomb_here = make_cursor(cross_bits, crossmask_bits, + cross_width, cross_height, + cross_x_hot, cross_y_hot); + } + *cursor = bomb_here; + } +} + +int +checkMapped(name) + char *name; +{ + char buf[100]; + + sprintf(buf, "%s.mapped", name); + return (booleanDefault(buf, 0)); +} + +void +W_WarpPointer(window, x, y) + W_Window window; + int x, y; +{ + static int warped_from_x = 0, warped_from_y = 0; + + if (window == NULL) { + if (W_in_message) { + XWarpPointer(W_Display, None, W_Root, 0, 0, 0, 0, warped_from_x, warped_from_y); + W_in_message = 0; + } + } else { + findMouse(&warped_from_x, &warped_from_y); + XWarpPointer(W_Display, None, W_Void2Window(window)->window, 0, 0, 0, 0, 0, 0); + W_in_message = 1; + } +} + +static void +findMouse(x, y) + int *x, *y; +{ + Window theRoot, theChild; + int wX, wY, rootX, rootY, status; + unsigned int wButtons; + + status = XQueryPointer(W_Display, W_Root, &theRoot, &theChild, &rootX, &rootY, &wX, &wY, &wButtons); + if (status == True) { + *x = wX; + *y = wY; + } else { + *x = 0; + *y = 0; + } +} + +int +findMouseInWin(x, y, w) + int *x, *y; + W_Window w; +{ + Window theRoot, theChild; + int wX, wY, rootX, rootY, status; + unsigned int wButtons; + struct window *win = W_Void2Window(w); + Window thisWin = win->window; + + status = XQueryPointer(W_Display, thisWin, &theRoot, &theChild, + &rootX, &rootY, &wX, &wY, &wButtons); + if (status == True) { + /* + if it's in the window we specified then the values returned should + be within the with and height of the window + */ + if (wX <= win->width && wY <= win->height) { + *x = wX; + *y = wY; + return 1; + } + } + *x = 0; + *y = 0; + return 0; +} + +#ifdef AUTOKEY +static void +W_Flush() +{ + XFlush(W_Display); +} + +W_AutoRepeatOff() +{ + XAutoRepeatOff(W_Display); + W_Flush(); +} + +W_AutoRepeatOn() +{ + XAutoRepeatOn(W_Display); + W_Flush(); +} +#endif /* AUTOKEY */ + +/* find the width of a font */ +int +W_StringWidth(string, font) + char string[]; + W_Font font; +{ + int x, y; + + y = strlen(string); + x = XTextWidth(fonts[fontNum(font)].fontstruct, string, y); + return (x); /* just a guess ?? old never returned! WHS + 4/6/93 */ +} + +void +W_TranslatePoints(w, x, y) + int *x, *y; + W_Window w; +{ + struct window *win; + win = W_Void2Window(w); + + if (win->type == WIN_TEXT) { + *y = (*y - MENU_PAD) / W_Textheight; + *x = (*x - MENU_PAD) / W_Textwidth; + } + return; +} + +#if 0 +#define MAKE_WINDOW_GETTER(name, part) \ + W_Callback name(w) \ + W_Window w; \ + { \ + return W_Void2Window(w)->part; \ + } + +#define MAKE_WINDOW_SETTER(name, port) \ + W_Callback name(w, c) \ + W_Window w; \ + W_Callback c; \ + { \ + W_Void2Window(w)->port = c; \ + } + +MAKE_WINDOW_GETTER(W_GetWindowKeyDownHandler, handle_keydown); +MAKE_WINDOW_SETTER(W_SetWindowKeyDownHandler, handle_keydown); + +MAKE_WINDOW_GETTER(W_GetWindowKeyUpHandler, handle_keyup); +MAKE_WINDOW_SETTER(W_SetWindowKeyUpHandler, handle_keyup); + +MAKE_WINDOW_GETTER(W_GetWindowButtonHandler, handle_button); +MAKE_WINDOW_SETTER(W_SetWindowButtonHandler, handle_button); + +MAKE_WINDOW_GETTER(W_GetWindowExposeHandler, handle_expose); +MAKE_WINDOW_SETTER(W_SetWindowExposeHandler, handle_expose); +#endif /* 0 */ + +void +W_ResizeWindow(window, neww, newh) /* TSH 2/93 */ + W_Window window; + int neww, newh; +{ + Window win = W_Void2Window(window)->window; + + XResizeWindow(W_Display, win, (unsigned int) neww, (unsigned int) newh); +} + +void +W_ResizeMenu(window, neww, newh)/* TSH 2/93 */ + W_Window window; + int neww, newh; +{ + W_ResizeWindow(window, neww * W_Textwidth + WIN_EDGE * 2, + newh * (W_Textheight + MENU_PAD * 2) + (newh - 1) * MENU_BAR); +} + +void +W_ResizeText(window, neww, newh)/* TSH 2/93 */ + W_Window window; + int neww, newh; +{ + W_ResizeWindow(window, neww * W_Textwidth + WIN_EDGE * 2, + newh * W_Textheight + MENU_PAD * 2); +} + +void +W_Deiconify(window) + W_Window window; +{ + struct window *win; + win = W_Void2Window(window); + /* according to ICCCM 4.1.4, this is how you deiconify a window. */ + XMapWindow(W_Display, win->window); +} + +W_Icon +W_MakeShieldBitmap(width, height, window) + int width, height; + W_Window window; +{ + static GC pen = 0; + struct window *win; + struct icon *newicon; + + win = W_Void2Window(window); + + newicon = (struct icon *) malloc(sizeof(struct icon)); + newicon->width = width; + newicon->height = height; + newicon->bitmap = XCreatePixmap(W_Display, win->window, width, height, 1); + newicon->window = win->window; + newicon->pixmap = 0; + + pen = XCreateGC(W_Display, newicon->bitmap, 0L, 0); + XSetForeground(W_Display, pen, 0L); + XFillRectangle(W_Display, newicon->bitmap, pen, 0, 0, width, height); + XSetForeground(W_Display, pen, 1L); + XDrawArc(W_Display, newicon->bitmap, pen, 0, 0, width - 1, height - 1, 0, 360 * 64); + XFreeGC(W_Display, pen); + + return W_Icon2Void(newicon); +} + +#ifdef BEEPLITE +void +W_OverlayBitmap(x, y, bit, color) + int x, y; + W_Icon bit; + W_Color color; +{ + struct icon *icon = W_Void2Icon(bit); +#ifdef DEBUG + printf("Overlaying bitmap to %d\n", icon->window); +#endif + XCopyPlane(W_Display, icon->bitmap, icon->window, + colortable[color].contexts[0], 0, 0, icon->width, icon->height, + x, y, 1); +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/ChangeLog Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,92 @@ + ChangeLog file for zlib + +Changes in 0.92 (3 May 95) +- don't assume that char is signed (problem on SGI) +- Clear bit buffer when starting a stored block +- no memcpy on Pyramid +- suppressed inftest.c +- optimized fill_window, put longest_match inline for gcc +- optimized inflate on stored blocks. +- untabify all sources to simplify patches + +Changes in 0.91 (2 May 95) +- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h +- Document the memory requirements in zconf.h +- added "make install" +- fix sync search logic in inflateSync +- deflate(Z_FULL_FLUSH) now works even if output buffer too short +- after inflateSync, don't scare people with just "lo world" +- added support for DJGPP + +Changes in 0.9 (1 May 95) +- don't assume that zalloc clears the allocated memory (the TurboC bug + was Mark's bug after all :) +- let again gzread copy uncompressed data unchanged (was working in 0.71) +- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented +- added a test of inflateSync in example.c +- moved MAX_WBITS to zconf.h because users might want to change that. +- document explicitly that zalloc(64K) on MSDOS must return a normalized + pointer (zero offset) +- added Makefiles for Microsoft C, Turbo C, Borland C++ +- faster crc32() + +Changes in 0.8 (29 April 95) +- added fast inflate (inffast.c) +- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this + is incompatible with previous versions of zlib which returned Z_OK. +- work around a TurboC compiler bug (bad code for b << 0, see infutil.h) + (actually that was not a compiler bug, see 0.81 above) +- gzread no longer reads one extra byte in certain cases +- In gzio destroy(), don't reference a freed structure +- avoid many warnings for MSDOS +- avoid the ERROR symbol which is used by MS Windows + +Changes in 0.71 (14 April 95) +- Fixed more MSDOS compilation problems :( There is still a bug with + TurboC large model. + +Changes in 0.7 (14 April 95) +- Added full inflate support. +- Simplified the crc32() interface. The pre- and post-conditioning + (one's complement) is now done inside crc32(). WARNING: this is + incompatible with previous versions; see zlib.h for the new usage. + +Changes in 0.61 (12 April 95) +- workaround for a bug in TurboC. example and minigzip now work on MSDOS. + +Changes in 0.6 (11 April 95) +- added minigzip.c +- added gzdopen to reopen a file descriptor as gzFile +- added transparent reading of non-gziped files in gzread. +- fixed bug in gzread (don't read crc as data) +- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose). +- don't allocate big arrays in the stack (for MSDOS) +- fix some MSDOS compilation problems + +Changes in 0.5: +- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but + not yet Z_FULL_FLUSH. +- support decompression but only in a single step (forced Z_FINISH) +- added opaque object for zalloc and zfree. +- added deflateReset and inflateReset +- added a variable zlib_version for consistency checking. +- renamed the 'filter' parameter of deflateInit2 as 'strategy'. + Added Z_FILTERED and Z_HUFFMAN_ONLY constants. + +Changes in 0.4: +- avoid "zip" everywhere, use zlib instead of ziplib. +- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush + if compression method == 8. +- added adler32 and crc32 +- renamed deflateOptions as deflateInit2, call one or the other but not both +- added the method parameter for deflateInit2. +- added inflateInit2 +- simplied considerably deflateInit and inflateInit by not supporting + user-provided history buffer. This is supported only in deflateInit2 + and inflateInit2. + +Changes in 0.3: +- prefix all macro names with Z_ +- use Z_FINISH instead of deflateEnd to finish compression. +- added Z_HUFFMAN_ONLY +- added gzerror()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/Makefile Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,72 @@ +# Makefile for zlib +# Copyright (C) 1995 Jean-loup Gailly. +# For conditions of distribution and use, see copyright notice in zlib.h + +CC=cc +CFLAGS=-O +#use -O3 for gcc to take advantage of inlining +#CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" +#CFLAGS=-g -DDEBUG +LDFLAGS=-L. -lgz + +RANLIB=ranlib + +prefix=/usr/local + +OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ + zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o + +TEST_OBJS = example.o minigzip.o + +all: example minigzip + +test: all + ./example + echo hello world | ./minigzip | ./minigzip -d + +install: libgz.a + -@mkdir $(prefix)/include + -@mkdir $(prefix)/lib + cp zlib.h zconf.h $(prefix)/include + chmod 644 $(prefix)/include/zlib.h $(prefix)/include/zconf.h + cp libgz.a $(prefix)/lib + chmod 644 $(prefix)/lib/libgz.a + +libgz.a: $(OBJS) + ar rc $@ $(OBJS) + $(RANLIB) $@ + +example: example.o libgz.a + $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) + +minigzip: minigzip.o libgz.a + $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) + +clean: + rm -f *.o example minigzip libgz.a foo.gz + +zip: + zip -ul9 zlib README ChangeLog Makefile Makefile.??? Makefile.?? *.[ch] + +tgz: + cd ..; tar cfz zlib/zlib.tgz zlib/README zlib/ChangeLog zlib/Makefile \ + zlib/Makefile.??? zlib/Makefile.?? zlib/*.[ch] + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +adler32.o: zutil.h zlib.h zconf.h +compress.o: zlib.h zconf.h +crc32.o: zutil.h zlib.h zconf.h +deflate.o: deflate.h zutil.h zlib.h zconf.h +example.o: zlib.h zconf.h +gzio.o: zutil.h zlib.h zconf.h +infblock.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h +infcodes.o: zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h +inffast.o: zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h +inflate.o: zutil.h zlib.h zconf.h infblock.h +inftrees.o: zutil.h zlib.h zconf.h inftrees.h +infutil.o: zutil.h zlib.h zconf.h inftrees.h infutil.h +minigzip.o: zlib.h zconf.h +trees.o: deflate.h zutil.h zlib.h zconf.h +uncompr.o: zlib.h zconf.h +zutil.o: zutil.h zlib.h zconf.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/Makefile.bor Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,101 @@ +# Makefile for zlib +# Borland C++ ************ UNTESTED *********** + +# To use, do "make -fmakefile.bor" + +# WARNING: the small model is supported but only for small values of +# MAX_WBITS and MAX_MEM_LEVEL. If you wish to reduce the memory +# requirements (default 256K for big objects plus a few K), you can add +# to CFLAGS below: -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14 +# See zconf.h for details about the memory requirements. + +# ------------- Turbo C++, Borland C++ ------------- +MODEL=-ml +CFLAGS=-O2 -Z $(MODEL) +CC=bcc +LD=bcc +LIB=tlib +# replace bcc with tcc for Turbo C++ 1.0 +LDFLAGS=$(MODEL) +O=.obj + +# variables +OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \ + trees$(O) +OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\ + trees$(O) +OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \ + infutil$(O) inffast$(O) +OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\ + infutil$(O)+inffast$(O) + +all: test + +adler32.obj: adler32.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +compress.obj: compress.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +crc32.obj: crc32.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +gzio.obj: gzio.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h\ + infcodes.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h\ + infcodes.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h + $(CC) -c $(CFLAGS) $*.c + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + $(CC) -c $(CFLAGS) $*.c + +infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +uncompr.obj: uncompr.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +example.obj: example.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +minigzip.obj: minigzip.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +# we must cut the command line to fit in the MS/DOS 128 byte limit: +zlib.lib: $(OBJ1) $(OBJ2) + $(LIB) zlib +$(OBJP1) + $(LIB) zlib +$(OBJP2) + +example.exe: example.obj zlib.lib + $(LD) $(LDFLAGS) example.obj zlib.lib + +minigzip.exe: minigzip.obj zlib.lib + $(LD) $(LDFLAGS) minigzip.obj zlib.lib + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +#clean: +# del *.obj +# del *.exe
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/Makefile.msc Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,98 @@ +# Makefile for zlib +# Microsoft C 5.1 or later + +# To use, do "make makefile.msc" + +# WARNING: the small model is supported but only for small values of +# MAX_WBITS and MAX_MEM_LEVEL. If you wish to reduce the memory +# requirements (default 256K for big objects plus a few K), you can add +# to CFLAGS below: -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14 +# See zconf.h for details about the memory requirements. + +# ------------- Microsoft C 5.1 and later ------------- +MODEL=-AL +CFLAGS=-Oait -Gs -nologo -W3 $(MODEL) +#-Ox generates bad code with MSC 5.1 +CC=cl +LD=link +LDFLAGS=/e/st:0x1000/noe +O=.obj + +# variables +OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \ + trees$(O) +OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\ + trees$(O) +OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \ + infutil$(O) inffast$(O) +OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\ + infutil$(O)+inffast$(O) + +adler32.obj: adler32.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +compress.obj: compress.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +crc32.obj: crc32.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +gzio.obj: gzio.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h\ + infcodes.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h\ + infcodes.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h + $(CC) -c $(CFLAGS) $*.c + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + $(CC) -c $(CFLAGS) $*.c + +infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +uncompr.obj: uncompr.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +example.obj: example.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +minigzip.obj: minigzip.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +# we must cut the command line to fit in the MS/DOS 128 byte limit: +zlib.lib: $(OBJ1) $(OBJ2) + lib zlib $(OBJ1); + lib zlib $(OBJ2); + +example.exe: example.obj zlib.lib + $(LD) $(LDFLAGS) example.obj,,,zlib.lib; + +minigzip.exe: minigzip.obj zlib.lib + $(LD) $(LDFLAGS) minigzip.obj,,,zlib.lib; + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +#clean: +# del *.obj +# del *.exe
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/Makefile.tc Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,100 @@ +# Makefile for zlib +# TurboC 2.0 + +# To use, do "make -fmakefile.tc" + +# WARNING: the small model is supported but only for small values of +# MAX_WBITS and MAX_MEM_LEVEL. If you wish to reduce the memory +# requirements (default 256K for big objects plus a few K), you can add +# to CFLAGS below: -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14 +# See zconf.h for details about the memory requirements. + +# ------------- Turbo C 2.0 ------------- +MODEL=-ml +CFLAGS=-O2 -Z $(MODEL) +CC=tcc +LD=tcc +LIB=tlib +LDFLAGS=$(MODEL) +O=.obj + +# variables +OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \ + trees$(O) +OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\ + trees$(O) +OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \ + infutil$(O) inffast$(O) +OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\ + infutil$(O)+inffast$(O) + +all: test + +adler32.obj: adler32.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +compress.obj: compress.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +crc32.obj: crc32.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +gzio.obj: gzio.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h\ + infcodes.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h\ + infcodes.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h + $(CC) -c $(CFLAGS) $*.c + +inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h + $(CC) -c $(CFLAGS) $*.c + +infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h + $(CC) -c $(CFLAGS) $*.c + +inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h + $(CC) -c $(CFLAGS) $*.c + +trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +uncompr.obj: uncompr.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +zutil.obj: zutil.c zutil.h zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +example.obj: example.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +minigzip.obj: minigzip.c zlib.h zconf.h + $(CC) -c $(CFLAGS) $*.c + +# we must cut the command line to fit in the MS/DOS 128 byte limit: +zlib.lib: $(OBJ1) $(OBJ2) + $(LIB) zlib +$(OBJP1) + $(LIB) zlib +$(OBJP2) + +example.exe: example.obj zlib.lib + $(LD) $(LDFLAGS) -eexample.exe example.obj zlib.lib + +minigzip.exe: minigzip.obj zlib.lib + $(LD) $(LDFLAGS) -eminigzip.exe minigzip.obj zlib.lib + +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +#clean: +# del *.obj +# del *.exe
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/README Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,62 @@ +zlib 0.92 is a beta version of a general purpose compression library. + +The data format used by the zlib library is described in the +files zlib-3.1.doc, deflate-1.1.doc and gzip-4.1.doc, available +in ftp.uu.net:/pub/archiving/zip/doc. + +All functions of the compression library are documented in the file +zlib.h. A usage example of the library is given in the file example.c +which also tests that the library is working correctly. + +To compile all files and run the test program, just type: make test +(For MSDOS, use one of the special makefiles such as Makefile.msc.) +To install the zlib library (libgz.a) in /usr/local/lib, type: make install +To install in a different directory, use for example: make install prefix=$HOME +This will install in $HOME/lib instead of /usr/local/lib. + +The changes made in version 0.92 are documented in the file ChangeLog. +The main changes since 0.9 are: +- don't assume that char is signed (problem on SGI) +- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h +- Document the memory requirements in zconf.h +- added "make install" +- added support for DJGPP and Pyramid +- fix an inflate bug for stored blocks. +- various speedups + +On MSDOS, this version works in both large and small model. However +small model compression works only for small values of MAX_MEM_LEVEL +and MAX_WBITS (see zconf.h). Small model decompression should work up +to MAX_WBITS=15. This version of zlib does not support small or +medium model with far allocation of big objects. + + + Copyright (C) 1995 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + gzip@prep.ai.mit.edu madler@cco.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* +receiving lengthy legal documents to sign. The sources are provided +for free but without warranty of any kind. The library has been +entirely written by Jean-loup Gailly and Mark Adler; it does not +include third-party code. + +If you redistribute modified sources, we would appreciate that you include +in the file ChangeLog history information documenting your changes.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/adler32.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,46 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* $Id: adler32.c,v 1.1.1.1 1997/12/06 05:41:35 darius Exp $ */ + +#include "zutil.h" + +#define BASE 65521 /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf) {s1 += *buf++; s2 += s1;} +#define DO2(buf) DO1(buf); DO1(buf); +#define DO4(buf) DO2(buf); DO2(buf); +#define DO8(buf) DO4(buf); DO4(buf); +#define DO16(buf) DO8(buf); DO8(buf); + +/* ========================================================================= */ +uLong adler32(adler, buf, len) + uLong adler; + Byte *buf; + uInt len; +{ + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int k; + + if (buf == Z_NULL) return 1L; + + while (len > 0) { + k = len < NMAX ? len : NMAX; + len -= k; + while (k >= 16) { + DO16(buf); + k -= 16; + } + if (k != 0) do { + DO1(buf); + } while (--k); + s1 %= BASE; + s2 %= BASE; + } + return (s2 << 16) | s1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/compress.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,55 @@ +/* compress.c -- compress a memory buffer + * Copyright (C) 1995 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* $Id: compress.c,v 1.1.1.1 1997/12/06 05:41:35 darius Exp $ */ + +#include "zlib.h" + +/* =========================================================================== + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least 0.1% larger than + sourceLen plus 8 bytes. Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ +int compress (dest, destLen, source, sourceLen) + Byte *dest; + uLong *destLen; + Byte *source; + uLong sourceLen; +{ + z_stream stream; + int err; + + stream.next_in = source; + stream.avail_in = (uInt)sourceLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + + err = deflateInit(&stream, Z_DEFAULT_COMPRESSION); + if (err != Z_OK) return err; + + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = deflateEnd(&stream); + return err; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/crc32.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,113 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* $Id: crc32.c,v 1.1.1.1 1997/12/06 05:41:35 darius Exp $ */ + +#include "zlib.h" + +extern uLong crc_table[]; /* crc table, defined below */ + +#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8); +#define DO2(buf) DO1(buf); DO1(buf); +#define DO4(buf) DO2(buf); DO2(buf); +#define DO8(buf) DO4(buf); DO4(buf); + +/* ========================================================================= */ +uLong crc32(crc, buf, len) + uLong crc; + Byte *buf; + uInt len; +{ + if (buf == Z_NULL) return 0L; + crc = crc ^ 0xffffffffL; + while (len >= 8) + { + DO8(buf); + len -= 8; + } + if (len) do { + DO1(buf); + } while (--len); + return crc ^ 0xffffffffL; +} + +/* ========================================================================= + * Make the crc table. This function is needed only if you want to compute + * the table dynamically. + */ +#ifdef DYNAMIC_CRC_TABLE + +local void make_crc_table() +{ + uLong c; + int n, k; + + for (n = 0; n < 256; n++) + { + c = (uLong)n; + for (k = 0; k < 8; k++) + c = c & 1 ? 0xedb88320L ^ (c >> 1) : c >> 1; + crc_table[n] = c; + } +} +#endif + +/* ======================================================================== + * Table of CRC-32's of all single-byte values (made by make_crc_table) + */ +uLong crc_table[] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/deflate.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,963 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* $Id: deflate.c,v 1.1.1.1 1997/12/06 05:41:35 darius Exp $ */ + +#include "deflate.h" + +char copyright[] = " deflate Copyright 1995 Jean-loup Gailly "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ + +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; +} config; + +local config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0}, /* store only */ +/* 1 */ {4, 4, 8, 4}, /* maximum speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8}, +/* 3 */ {4, 6, 32, 32}, + +/* 4 */ {4, 4, 16, 16}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32}, +/* 6 */ {8, 16, 128, 128}, +/* 7 */ {8, 32, 128, 256}, +/* 8 */ {32, 128, 258, 1024}, +/* 9 */ {32, 258, 258, 4096}}; /* maximum compression */ + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ + +/* =========================================================================== + * Prototypes for local functions. + */ + +local void fill_window __P((deflate_state *s)); +local int deflate_fast __P((deflate_state *s, int flush)); +local int deflate_slow __P((deflate_state *s, int flush)); +local void lm_init __P((deflate_state *s)); +local int longest_match __P((deflate_state *s, IPos cur_match)); +local void putShortMSB __P((deflate_state *s, uInt b)); +local void flush_pending __P((z_stream *strm)); +local int read_buf __P((z_stream *strm, char *buf, unsigned size)); +#ifdef ASMV + void match_init __P((void)); /* asm code initialization */ +#endif + +#ifdef DEBUG +local void check_match __P((deflate_state *s, IPos start, IPos match, + int length)); +#endif + + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask) + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of str are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + MIN_MATCH-1]), \ + s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (str)) + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((char*)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int deflateInit (strm, level) + z_stream *strm; + int level; +{ + return deflateInit2 (strm, level, DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, 0); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int deflateInit2 (strm, level, method, windowBits, memLevel, strategy) + z_stream *strm; + int level; + int method; + int windowBits; + int memLevel; + int strategy; +{ + deflate_state *s; + int noheader = 0; + + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == Z_NULL) strm->zalloc = zcalloc; + if (strm->zfree == Z_NULL) strm->zfree = zcfree; + + if (level == Z_DEFAULT_COMPRESSION) level = 6; + + if (windowBits < 0) { /* undocumented feature: suppress zlib header */ + noheader = 1; + windowBits = -windowBits; + } + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != DEFLATED || + windowBits < 8 || windowBits > 15 || level < 1 || level > 9) { + return Z_STREAM_ERROR; + } + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state *)s; + s->strm = strm; + + s->noheader = noheader; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Byte*) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Pos*) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Pos*) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + s->pending_buf = (uch*) ZALLOC(strm, s->lit_bufsize, 2*sizeof(ush)); + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + strm->msg = z_errmsg[1-Z_MEM_ERROR]; + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->d_buf = (ush*) &(s->pending_buf[s->lit_bufsize]); + s->l_buf = (uch*) &(s->pending_buf[3*s->lit_bufsize]); + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 32 bits (worst case + * is 15+15+13=33). + */ + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= */ +int deflateReset (strm) + z_stream *strm; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR; + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + s->status = s->noheader ? BUSY_STATE : INIT_STATE; + s->adler = 1; + + ct_init(s); + lm_init(s); + + return Z_OK; +} + +/* ========================================================================= + * Put a short the pending_out buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * the pending_out buffer. + */ +local void putShortMSB (s, b) + deflate_state *s; + uInt b; +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. + */ +local void flush_pending(strm) + z_stream *strm; +{ + unsigned len = strm->state->pending; + + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, strm->state->pending_out, len); + strm->next_out += len; + strm->state->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + strm->state->pending -= len; + if (strm->state->pending == 0) { + strm->state->pending_out = strm->state->pending_buf; + } +} + +/* ========================================================================= */ +int deflate (strm, flush) + z_stream *strm; + int flush; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + + if (strm->next_out == Z_NULL || strm->next_in == Z_NULL) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + strm->state->strm = strm; /* just in case */ + + /* Write the zlib header */ + if (strm->state->status == INIT_STATE) { + + uInt header = (DEFLATED + ((strm->state->w_bits-8)<<4)) << 8; + uInt level_flags = (strm->state->level-1) >> 1; + + if (level_flags > 3) level_flags = 3; + header |= (level_flags << 6); + header += 31 - (header % 31); + + strm->state->status = BUSY_STATE; + putShortMSB(strm->state, header); + } + + /* Flush as much pending output as possible */ + if (strm->state->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) return Z_OK; + } + + /* User must not provide more input after the first FINISH: */ + if (strm->state->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || + (flush == Z_FINISH && strm->state->status != FINISH_STATE)) { + int quit; + + if (flush == Z_FINISH) { + strm->state->status = FINISH_STATE; + } + if (strm->state->level <= 3) { + quit = deflate_fast(strm->state, flush); + } else { + quit = deflate_slow(strm->state, flush); + } + if (flush == Z_FULL_FLUSH) { + ct_stored_block(strm->state, (char*)0, 0L, 0); /* special marker */ + flush_pending(strm); + CLEAR_HASH(strm->state); /* forget history */ + if (strm->avail_out == 0) return Z_OK; + } + if (quit) return Z_OK; + } + Assert(strm->avail_out > 0, "bug2"); + + if (flush != Z_FINISH) return Z_OK; + if (strm->state->noheader) return Z_STREAM_END; + + /* Write the zlib trailer (adler32) */ + putShortMSB(strm->state, (uInt)(strm->state->adler >> 16)); + putShortMSB(strm->state, (uInt)(strm->state->adler & 0xffff)); + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + strm->state->noheader = 1; /* write the trailer only once! */ + return strm->state->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int deflateEnd (strm) + z_stream *strm; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + + TRY_FREE(strm, strm->state->window); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->pending_buf); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return Z_OK; +} + +/* ========================================================================= */ +int deflateCopy (dest, source) + z_stream *dest; + z_stream *source; +{ + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + return Z_STREAM_ERROR; + } + *dest = *source; + return Z_STREAM_ERROR; /* to be implemented */ +#if 0 + dest->state = (struct internal_state *) + (*dest->zalloc)(1, sizeof(deflate_state)); + if (dest->state == Z_NULL) return Z_MEM_ERROR; + + *(dest->state) = *(source->state); + return Z_OK; +#endif +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. + */ +local int read_buf(strm, buf, size) + z_stream *strm; + char *buf; + unsigned size; +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + if (!strm->state->noheader) { + strm->state->adler = adler32(strm->state->adler, strm->next_in, len); + } + zmemcpy(buf, strm->next_in, len); + strm->next_in += len; + strm->total_in += len; + + return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) + deflate_state *s; +{ + register unsigned j; + + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->match_length = MIN_MATCH-1; + s->match_available = 0; +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif + + s->ins_h = 0; + for (j=0; j<MIN_MATCH-1; j++) UPDATE_HASH(s, s->ins_h, s->window[j]); + /* If lookahead < MIN_MATCH, ins_h is garbage, but this is + * not important since only literal bytes will be emitted. + */ +} + +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +local INLINE int longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Byte *scan = s->window + s->strstart; /* current string */ + register Byte *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Pos *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Byte *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ush*)scan; + register ush scan_end = *(ush*)(scan+best_len-1); +#else + register Byte *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + Assert(s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2: + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ush*)(match+best_len-1) != scan_end || + *(ush*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + scan++, match++; + do { + } while (*(ush*)(scan+=2) == *(ush*)(match+=2) && + *(ush*)(scan+=2) == *(ush*)(match+=2) && + *(ush*)(scan+=2) == *(ush*)(match+=2) && + *(ush*)(scan+=2) == *(ush*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= s->nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ush*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + return best_len; +} +#endif /* ASMV */ + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (memcmp((char*)s->window + match, + (char*)s->window + start, length) != EQUAL) { + fprintf(stderr, + " start %d, match %d, length %d\n", + start, match, length); + z_error("invalid match"); + } + if (verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + register unsigned n, m; + register Pos *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if strstart == 0 + * and lookahead == 1 (input done one byte at time) + */ + more--; + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + } else if (s->strstart >= wsize+MAX_DIST(s)) { + + /* By the IN assertion, the window is not empty so we can't confuse + * more == 0 with more == 64K on a 16 bit machine. + */ + zmemcpy((char*)s->window, (char*)s->window+wsize, + (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + + s->block_start -= (long) wsize; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage): + */ + n = s->hash_size; + p = &s->head[n-1]; + do { + m = *p; + *p-- = (Pos)(m >= wsize ? m-wsize : NIL); + } while (--n); + + n = wsize; + p = &s->prev[n-1]; + do { + m = *p; + *p-- = (Pos)(m >= wsize ? m-wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); + + more += wsize; + } + if (s->strm->avail_in == 0) return; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, (char*)s->window + s->strstart + s->lookahead, + more); + s->lookahead += n; + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, eof) { \ + ct_flush_block(s, (s->block_start >= 0L ? \ + (char*)&s->window[(unsigned)s->block_start] : \ + (char*)Z_NULL), (long)s->strstart - s->block_start, (eof)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, eof) { \ + FLUSH_BLOCK_ONLY(s, eof); \ + if (s->strm->avail_out == 0) return 1; \ +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return true if + * processing was terminated prematurely (no more input or output space). + * This function does not perform lazy evaluationof matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local int deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + s->prev_length = MIN_MATCH-1; + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) return 1; + + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + INSERT_STRING(s, s->strstart, hash_head); + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + if (s->strategy != Z_HUFFMAN_ONLY) { + s->match_length = longest_match (s, hash_head); + } + /* longest_match() sets match_start */ + + if (s->match_length > s->lookahead) s->match_length = s->lookahead; + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + bflush = ct_tally(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if (s->match_length <= s->max_insert_length) { + s->match_length--; /* string at strstart already in hash table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH + * these bytes are garbage, but it does not matter since + * the next lookahead bytes will be emitted as literals. + */ + } while (--s->match_length != 0); + s->strstart++; + } else { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + bflush = ct_tally (s, 0, s->window[s->strstart]); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return 0; /* normal exit */ +} + +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local int deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) return 1; + + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + INSERT_STRING(s, s->strstart, hash_head); + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + if (s->strategy != Z_HUFFMAN_ONLY) { + s->match_length = longest_match (s, hash_head); + } + /* longest_match() sets match_start */ + if (s->match_length > s->lookahead) s->match_length = s->lookahead; + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED || + (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR))) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + bflush = ct_tally(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH + * these bytes are garbage, but it does not matter since the + * next lookahead bytes will always be emitted as literals. + */ + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + if (ct_tally (s, 0, s->window[s->strstart-1])) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return 1; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + if (s->match_available) { + ct_tally (s, 0, s->window[s->strstart-1]); + s->match_available = 0; + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/deflate.h Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,272 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* $Id: deflate.h,v 1.1.1.1 1997/12/06 05:41:36 darius Exp $ */ + +#include "zutil.h" + +/* =========================================================================== + * Internal compression state. + */ + +/* Data type */ +#define BINARY 0 +#define ASCII 1 +#define UNKNOWN 2 + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define INIT_STATE 42 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} tree_desc; + +typedef ush Pos; +typedef unsigned IPos; +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_stream *strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Byte *pending_buf; /* output still pending */ + Byte *pending_out; /* next pending byte to output to the stream */ + int pending; /* nb of bytes in the pending buffer */ + uLong adler; /* adler32 of uncompressed data */ + int noheader; /* suppress zlib header and adler32 */ + Byte data_type; /* UNKNOWN, BINARY or ASCII */ + Byte method; /* STORED (for zip only) or DEFLATED */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Byte *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Pos *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Pos *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + + ct_data dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + ct_data dyn_dtree[2*D_CODES+1]; /* distance tree */ + ct_data bl_tree[2*BL_CODES+1]; /* Huffman tree for the bit lengths */ + + tree_desc l_desc; /* descriptor for literal tree */ + tree_desc d_desc; /* descriptor for distance tree */ + tree_desc bl_desc; /* descriptor for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uch *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ush *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + ulg compressed_len; /* total bit length of compressed file */ + uInt matches; /* number of string matches in current block */ + +#ifdef DEBUG + ulg bits_sent; /* bit length of the compressed data */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + +} deflate_state; + + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + + /* in trees.c */ +void ct_init __P((deflate_state *s)); +int ct_tally __P((deflate_state *s, int dist, int lc)); +ulg ct_flush_block __P((deflate_state *s, char *buf, ulg stored_len, int eof)); +void ct_stored_block __P((deflate_state *s, char *buf, ulg stored_len, + int eof));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/example.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,290 @@ +/* example.c -- usage example of the zlib compression library + * Copyright (C) 1995 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* $Id: example.c,v 1.1.1.1 1997/12/06 05:41:36 darius Exp $ */ + +#include <stdio.h> +#include "zlib.h" + +#ifdef STDC +# include <string.h> +#endif + +#ifndef __GO32__ +extern void exit __P((int)); +#endif + +#define BUFLEN 4096 + +#define local static +/* For MSDOS and other systems with limitation on stack size. For Unix, + #define local + works also. + */ + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +char *hello = "hello world"; + +void test_compress __P((void)); +void test_gzio __P((char *out, char *in)); +void test_deflate __P((Byte compr[])); +void test_inflate __P((Byte compr[])); +void main __P((int argc, char *argv[])); + +/* =========================================================================== + * Test compress() and uncompress() + */ +void test_compress() +{ + local Byte compr[BUFLEN]; + uLong comprLen = sizeof(compr); + local Byte uncompr[BUFLEN]; + uLong uncomprLen = sizeof(uncompr); + int err; + uLong len = strlen(hello)+1; + + err = compress(compr, &comprLen, (Byte*)hello, len); + CHECK_ERR(err, "compress"); + + strcpy((char*)uncompr, "garbage"); + + err = uncompress(uncompr, &uncomprLen, compr, comprLen); + CHECK_ERR(err, "uncompress"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad uncompress\n"); + } else { + printf("uncompress(): %s\n", uncompr); + } +} + +/* =========================================================================== + * Test read/write of .gz files + */ +void test_gzio(out, in) + char *out; /* output file */ + char *in; /* input file */ +{ + local Byte uncompr[BUFLEN]; + int uncomprLen = sizeof(uncompr); + int err; + int len = strlen(hello)+1; + gzFile file; + + file = gzopen(out, "wb"); + if (file == NULL) { + fprintf(stderr, "gzopen error\n"); + exit(1); + } + + if (gzwrite(file, hello, len) != len) { + fprintf(stderr, "gzwrite err: %s\n", gzerror(file, &err)); + } + gzclose(file); + + file = gzopen(in, "rb"); + if (file == NULL) { + fprintf(stderr, "gzopen error\n"); + } + strcpy((char*)uncompr, "garbage"); + + uncomprLen = gzread(file, uncompr, uncomprLen); + if (uncomprLen != len) { + fprintf(stderr, "gzread err: %s\n", gzerror(file, &err)); + } + gzclose(file); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad gzread\n"); + } else { + printf("gzread(): %s\n", uncompr); + } +} + +/* =========================================================================== + * Test deflate() with small buffers + */ +void test_deflate(compr) + Byte compr[]; +{ + z_stream c_stream; /* compression stream */ + int err; + int len = strlen(hello)+1; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + + err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (Byte*)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != (uLong)len) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + } + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = deflate(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } + + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with small buffers + */ +void test_inflate(compr) + Byte compr[]; +{ + local Byte uncompr[BUFLEN]; + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_in = compr; + d_stream.next_out = uncompr; + + for (;;) { + d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "inflate"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strcmp((char*)uncompr, hello)) { + fprintf(stderr, "bad inflate\n"); + } else { + printf("inflate(): %s\n", uncompr); + } +} + +/* =========================================================================== + * Test deflate() with full flush + */ +void test_flush(compr) + Byte compr[]; +{ + z_stream c_stream; /* compression stream */ + int err; + int len = strlen(hello)+1; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + + err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (Byte*)hello; + c_stream.next_out = compr; + c_stream.avail_in = 3; + c_stream.avail_out = BUFLEN; + err = deflate(&c_stream, Z_FULL_FLUSH); + CHECK_ERR(err, "deflate"); + + compr[3]++; /* force an error in first compressed block */ + c_stream.avail_in = len - 3; + + err = deflate(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + CHECK_ERR(err, "deflate"); + } + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflateSync() + */ +void test_sync(compr) + Byte compr[]; +{ + local Byte uncompr[BUFLEN]; + int err; + z_stream d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + + err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_in = compr; + d_stream.next_out = uncompr; + d_stream.avail_in = 2; /* just read the zlib header */ + d_stream.avail_out = sizeof(uncompr); + + inflate(&d_stream, Z_NO_FLUSH); + CHECK_ERR(err, "inflate"); + + d_stream.avail_in = BUFLEN-2; /* let inflate read all compressed data */ + err = inflateSync(&d_stream); /* skip the damaged part */ + CHECK_ERR(err, "inflateSync"); + + err = inflate(&d_stream, Z_FINISH); + if (err != Z_DATA_ERROR) { + fprintf(stderr, "inflate should report DATA_ERROR\n"); + /* Because of incorrect adler32 */ + } + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + printf("after inflateSync(): hel%s\n", uncompr); +} + +/* =========================================================================== + * Usage: example [output.gz [input.gz]] + */ + +void main(argc, argv) + int argc; + char *argv[]; +{ + local Byte compr[BUFLEN]; + + if (zlib_version[0] != ZLIB_VERSION[0]) { + fprintf(stderr, "incompatible zlib version\n"); + exit(1); + + } else if (strcmp(zlib_version, ZLIB_VERSION) != 0) { + fprintf(stderr, "warning: different zlib version\n"); + } + test_compress(); + + test_gzio((argc > 1 ? argv[1] : "foo.gz"), + (argc > 2 ? argv[2] : "foo.gz")); + + test_deflate(compr); + test_inflate(compr); + + test_flush(compr); + test_sync(compr); + + exit(0); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/gzio.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,469 @@ +/* gzio.c -- IO on .gz files + * Copyright (C) 1995 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* $Id: gzio.c,v 1.1.1.1 1997/12/06 05:41:36 darius Exp $ */ + +#include <stdio.h> + +#include "zutil.h" + +struct internal_state {int dummy;}; /* for buggy compilers */ + +#define Z_BUFSIZE 4096 + +#define ALLOC(size) zcalloc((voidp)0, 1, size) +#define TRYFREE(p) {if (p) zcfree((voidp)0, p);} + +#define GZ_MAGIC_1 0x1f +#define GZ_MAGIC_2 0x8b + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define RESERVED 0xE0 /* bits 5..7: reserved */ + +#ifndef SEEK_CUR +# define SEEK_CUR 1 +#endif + +typedef struct gz_stream { + z_stream stream; + int z_err; /* error code for last stream operation */ + int z_eof; /* set if end of input file */ + FILE *file; /* .gz file */ + Byte *inbuf; /* input buffer */ + Byte *outbuf; /* output buffer */ + uLong crc; /* crc32 of uncompressed data */ + char *msg; /* error message */ + char *path; /* path name for debugging only */ + int transparent; /* 1 if input file is not a .gz file */ + char mode; /* 'w' or 'r' */ +} gz_stream; + + +local int destroy __P((gz_stream *s)); +local gzFile gz_open __P((char *path, char *mode, int fd)); +local void putLong __P((FILE *file, uLong x)); +local uLong getLong __P((Byte *buf)); + + /* =========================================================================== + * Cleanup then free the given gz_stream. Return a zlib error code. + */ +local int destroy (s) + gz_stream *s; +{ + int err = Z_OK; + + if (!s) return Z_STREAM_ERROR; + + TRYFREE(s->inbuf); + TRYFREE(s->outbuf); + TRYFREE(s->path); + TRYFREE(s->msg); + + if (s->stream.state != NULL) { + if (s->mode == 'w') { + err = deflateEnd(&(s->stream)); + } else if (s->mode == 'r') { + err = inflateEnd(&(s->stream)); + } + } + if (s->file != NULL && fclose(s->file)) { + err = Z_ERRNO; + } + if (s->z_err < 0) err = s->z_err; + zcfree((voidp)0, s); + return err; +} + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb"). The file is given either by file descritor + or path name (if fd == -1). + gz_open return NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). +*/ +local gzFile gz_open (path, mode, fd) + char *path; + char *mode; + int fd; +{ + int err; + char *p = mode; + gz_stream *s = (gz_stream *)ALLOC(sizeof(gz_stream)); + + if (!s) return Z_NULL; + + s->stream.zalloc = (alloc_func)0; + s->stream.zfree = (free_func)0; + s->stream.next_in = s->inbuf = Z_NULL; + s->stream.next_out = s->outbuf = Z_NULL; + s->stream.avail_in = s->stream.avail_out = 0; + s->file = NULL; + s->z_err = Z_OK; + s->z_eof = 0; + s->crc = crc32(0L, Z_NULL, 0); + s->msg = NULL; + s->transparent = 0; + + s->path = (char*)ALLOC(strlen(path)+1); + if (s->path == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + strcpy(s->path, path); /* do this early for debugging */ + + s->mode = '\0'; + do { + if (*p == 'r') s->mode = 'r'; + if (*p == 'w') s->mode = 'w'; + } while (*p++); + if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; + + if (s->mode == 'w') { + err = deflateInit2(&(s->stream), Z_DEFAULT_COMPRESSION, + DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, 0); + /* windowBits is passed < 0 to suppress zlib header */ + + s->stream.next_out = s->outbuf = ALLOC(Z_BUFSIZE); + + if (err != Z_OK || s->outbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } else { + err = inflateInit2(&(s->stream), -MAX_WBITS); + s->stream.next_in = s->inbuf = ALLOC(Z_BUFSIZE); + + if (err != Z_OK || s->inbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } + s->stream.avail_out = Z_BUFSIZE; + + errno = 0; + s->file = fd < 0 ? FOPEN(path, mode) : fdopen(fd, mode); + + if (s->file == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + if (s->mode == 'w') { + /* Write a very simple .gz header: + */ + fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", GZ_MAGIC_1, GZ_MAGIC_2, + DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); + } else { + /* Check and skip the header: + */ + Byte c1 = 0, c2 = 0; + Byte method = 0; + Byte flags = 0; + Byte xflags = 0; + Byte time[4]; + Byte osCode; + int c; + + s->stream.avail_in = fread(s->inbuf, 1, 2, s->file); + if (s->stream.avail_in != 2 || s->inbuf[0] != GZ_MAGIC_1 + || s->inbuf[1] != GZ_MAGIC_2) { + s->transparent = 1; + return (gzFile)s; + } + s->stream.avail_in = 0; + fscanf(s->file,"%c%c%4c%c%c", &method, &flags, time, &xflags, &osCode); + + if (method != DEFLATED || feof(s->file) || (flags & RESERVED) != 0) { + s->z_err = Z_DATA_ERROR; + return (gzFile)s; + } + if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ + long len; + fscanf(s->file, "%c%c", &c1, &c2); + len = c1 + ((long)c2<<8); + fseek(s->file, len, SEEK_CUR); + } + if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ + while ((c = getc(s->file)) != 0 && c != EOF) ; + } + if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ + while ((c = getc(s->file)) != 0 && c != EOF) ; + } + if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ + fscanf(s->file, "%c%c", &c1, &c2); + } + if (feof(s->file)) { + s->z_err = Z_DATA_ERROR; + } + } + return (gzFile)s; +} + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. +*/ +gzFile gzopen (path, mode) + char *path; + char *mode; +{ + return gz_open (path, mode, -1); +} + +/* =========================================================================== + Associate a gzFile with the file descriptor fd. +*/ +gzFile gzdopen (fd, mode) + int fd; + char *mode; +{ + char name[20]; + sprintf(name, "<fd:%d>", fd); /* for debugging */ + + return gz_open (name, mode, fd); +} + +/* =========================================================================== + Reads the given number of uncompressed bytes from the compressed file. + gzread returns the number of bytes actually read (0 for end of file). +*/ +int gzread (file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; + + if (s->transparent) { + unsigned n = 0; + Byte *b = (Byte*)buf; + /* Copy the first two (non-magic) bytes if not done already */ + while (s->stream.avail_in > 0 && len > 0) { + *b++ = *s->stream.next_in++; + s->stream.avail_in--; + len--; n++; + } + if (len == 0) return n; + return n + fread(b, 1, len, s->file); + } + if (s->z_err == Z_DATA_ERROR) return -1; /* bad .gz file */ + if (s->z_err == Z_STREAM_END) return 0; /* don't read crc as data */ + + s->stream.next_out = buf; + s->stream.avail_out = len; + + while (s->stream.avail_out != 0) { + + if (s->stream.avail_in == 0 && !s->z_eof) { + + errno = 0; + s->stream.avail_in = + fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + } else if (s->stream.avail_in == (uInt)EOF) { + s->stream.avail_in = 0; + s->z_eof = 1; + s->z_err = Z_ERRNO; + break; + } + s->stream.next_in = s->inbuf; + } + s->z_err = inflate(&(s->stream), Z_NO_FLUSH); + + if (s->z_err == Z_STREAM_END || + s->z_err != Z_OK || s->z_eof) break; + } + len -= s->stream.avail_out; + s->crc = crc32(s->crc, buf, len); + return len; +} + +/* =========================================================================== + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of bytes actually written (0 in case of error). +*/ +int gzwrite (file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.next_in = buf; + s->stream.avail_in = len; + + while (s->stream.avail_in != 0) { + + if (s->stream.avail_out == 0) { + + s->stream.next_out = s->outbuf; + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { + s->z_err = Z_ERRNO; + break; + } + s->stream.avail_out = Z_BUFSIZE; + } + s->z_err = deflate(&(s->stream), Z_NO_FLUSH); + + if (s->z_err != Z_OK) break; + } + s->crc = crc32(s->crc, buf, len); + + return len - s->stream.avail_in; +} + +/* =========================================================================== + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ +int gzflush (file, flush) + gzFile file; + int flush; +{ + uInt len; + int done = 0; + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.avail_in = 0; /* should be zero already anyway */ + + for (;;) { + len = Z_BUFSIZE - s->stream.avail_out; + + if (len != 0) { + if (fwrite(s->outbuf, 1, len, s->file) != len) { + s->z_err = Z_ERRNO; + return Z_ERRNO; + } + s->stream.next_out = s->outbuf; + s->stream.avail_out = Z_BUFSIZE; + } + if (done) break; + s->z_err = deflate(&(s->stream), flush); + + /* deflate has finished flushing only when it hasn't used up + * all the available space in the output buffer: + */ + done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); + + if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; + } + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} + +/* =========================================================================== + Outputs a long in LSB order to the given file +*/ +local void putLong (file, x) + FILE *file; + uLong x; +{ + int n; + for (n = 0; n < 4; n++) { + fputc((int)(x & 0xff), file); + x >>= 8; + } +} + +/* =========================================================================== + Reads a long in LSB order from the given buffer +*/ +local uLong getLong (buf) + Byte *buf; +{ + uLong x = 0; + Byte *p = buf+4; + + do { + x <<= 8; + x |= *--p; + } while (p != buf); + return x; +} + +/* =========================================================================== + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. +*/ +int gzclose (file) + gzFile file; +{ + uInt n; + int err; + gz_stream *s = (gz_stream*)file; + + if (s == NULL) return Z_STREAM_ERROR; + + if (s->mode == 'w') { + err = gzflush (file, Z_FINISH); + if (err != Z_OK) return destroy(file); + + putLong (s->file, s->crc); + putLong (s->file, s->stream.total_in); + + } else if (s->mode == 'r' && s->z_err == Z_STREAM_END) { + + /* slide CRC and original size if they are at the end of inbuf */ + if ((n = s->stream.avail_in) < 8 && !s->z_eof) { + Byte *p = s->inbuf; + Byte *q = s->stream.next_in; + while (n--) { *p++ = *q++; }; + + n = s->stream.avail_in; + n += fread(p, 1, 8, s->file); + s->stream.next_in = s->inbuf; + } + /* check CRC and original size */ + if (n < 8 || + getLong(s->stream.next_in) != s->crc || + getLong(s->stream.next_in + 4) != s->stream.total_out) { + + s->z_err = Z_DATA_ERROR; + } + } + return destroy(file); +} + +/* =========================================================================== + Returns the error message for the last error which occured on the + given compressed file. errnum is set to zlib error number. If an + error occured in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ +char* gzerror (file, errnum) + gzFile file; + int *errnum; +{ + char *m; + gz_stream *s = (gz_stream*)file; + + if (s == NULL) { + *errnum = Z_STREAM_ERROR; + return z_errmsg[1-Z_STREAM_ERROR]; + } + *errnum = s->z_err; + if (*errnum == Z_OK) return ""; + + m = *errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg; + + if (m == NULL || *m == '\0') m = z_errmsg[1-s->z_err]; + + TRYFREE(s->msg); + s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); + strcpy(s->msg, s->path); + strcat(s->msg, ": "); + strcat(s->msg, m); + return s->msg; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/infblock.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,375 @@ +/* infblock.c -- interpret and process block types to last block + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" +#include "inftrees.h" +#include "infcodes.h" +#include "infutil.h" + +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ + +/* Table for deflate from PKZIP's appnote.txt. */ +local uInt border[] = { /* Order of the bit length code lengths */ + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +/* + Notes beyond the 1.93a appnote.txt: + + 1. Distance pointers never point before the beginning of the output + stream. + 2. Distance pointers can point back across blocks, up to 32k away. + 3. There is an implied maximum of 7 bits for the bit length table and + 15 bits for the actual data. + 4. If only one code exists, then it is encoded using one bit. (Zero + would be more efficient, but perhaps a little confusing.) If two + codes exist, they are coded using one bit each (0 and 1). + 5. There is no way of sending zero distance codes--a dummy must be + sent if there are none. (History: a pre 2.0 version of PKZIP would + store blocks with no distance codes, but this was discovered to be + too harsh a criterion.) Valid only for 1.93a. 2.04c does allow + zero distance codes, which is sent as one code of zero bits in + length. + 6. There are up to 286 literal/length codes. Code 256 represents the + end-of-block. Note however that the static length tree defines + 288 codes just to fill out the Huffman codes. Codes 286 and 287 + cannot be used though, since there is no length base or extra bits + defined for them. Similarily, there are up to 30 distance codes. + However, static trees define 32 codes (all 5 bits) to fill out the + Huffman codes, but the last two had better not show up in the data. + 7. Unzip can check dynamic Huffman blocks for complete code sets. + The exception is that a single code would not be complete (see #4). + 8. The five bits following the block type is really the number of + literal codes sent minus 257. + 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits + (1+6+6). Therefore, to output three times the length, you output + three codes (1+1+1), whereas to output four times the same length, + you only need two codes (1+3). Hmm. + 10. In the tree reconstruction algorithm, Code = Code + Increment + only if BitLength(i) is not zero. (Pretty obvious.) + 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) + 12. Note: length code 284 can represent 227-258, but length code 285 + really is 258. The last length deserves its own, short code + since it gets used a lot in very redundant files. The length + 258 is special since 258 - 3 (the min match length) is 255. + 13. The literal/length and distance code bit lengths are read as a + single stream of lengths. It is possible (and advantageous) for + a repeat code (16, 17, or 18) to go across the boundary between + the two sets of lengths. + */ + + +void inflate_blocks_reset(s, z, c) +struct inflate_blocks_state *s; +z_stream *z; +uLong *c; +{ + if (s->checkfn != Z_NULL) + *c = s->check; + if (s->mode == BTREE || s->mode == DTREE) + ZFREE(z, s->sub.trees.blens); + if (s->mode == CODES) + inflate_codes_free(s->sub.codes, z); + s->mode = TYPE; + s->bitk = 0; + s->bitb = 0; + s->read = s->write = s->window; + if (s->checkfn != Z_NULL) + s->check = (*s->checkfn)(0L, Z_NULL, 0); + Trace((stderr, "inflate: blocks reset\n")); +} + + +struct inflate_blocks_state *inflate_blocks_new(z, c, w) +z_stream *z; +check_func c; +uInt w; +{ + struct inflate_blocks_state *s; + + if ((s = (struct inflate_blocks_state *)ZALLOC + (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) + return s; + if ((s->window = (Byte *)ZALLOC(z, 1, w)) == Z_NULL) + { + ZFREE(z, s); + return Z_NULL; + } + s->end = s->window + w; + s->checkfn = c; + s->mode = TYPE; + Trace((stderr, "inflate: blocks allocated\n")); + inflate_blocks_reset(s, z, &s->check); + return s; +} + + +int inflate_blocks(s, z, r) +struct inflate_blocks_state *s; +z_stream *z; +int r; +{ + uInt t; /* temporary storage */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Byte *p; /* input data pointer */ + uInt n; /* bytes available there */ + Byte *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input based on current state */ + while (1) switch (s->mode) + { + case TYPE: + NEEDBITS(3) + t = (uInt)b & 7; + s->last = t & 1; + switch (t >> 1) + { + case 0: /* stored */ + Trace((stderr, "inflate: stored block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + t = k & 7; /* go to byte boundary */ + DUMPBITS(t) + s->mode = LENS; /* get length of stored block */ + break; + case 1: /* fixed */ + Trace((stderr, "inflate: fixed codes block%s\n", + s->last ? " (last)" : "")); + { + uInt bl, bd; + inflate_huft *tl, *td; + + inflate_trees_fixed(&bl, &bd, &tl, &td); + s->sub.codes = inflate_codes_new(bl, bd, tl, td, z); + if (s->sub.codes == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + } + DUMPBITS(3) + s->mode = CODES; + break; + case 2: /* dynamic */ + Trace((stderr, "inflate: dynamic codes block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + s->mode = TABLE; + break; + case 3: /* illegal */ + DUMPBITS(3) + s->mode = BAD; + z->msg = "invalid block type"; + r = Z_DATA_ERROR; + LEAVE + } + break; + case LENS: + NEEDBITS(32) + if ((~b) >> 16 != (b & 0xffff)) + { + s->mode = BAD; + z->msg = "invalid stored block lengths"; + r = Z_DATA_ERROR; + LEAVE + } + s->sub.left = (uInt)b & 0xffff; + k = b = 0; /* dump bits */ + Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); + s->mode = s->sub.left ? STORED : TYPE; + break; + case STORED: + if (n == 0) + LEAVE + NEEDOUT + t = s->sub.left; + if (t > n) t = n; + if (t > m) t = m; + zmemcpy(q, p, t); + p += t; n -= t; + q += t; m -= t; + if ((s->sub.left -= t) != 0) + break; + Tracev((stderr, "inflate: stored end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + s->mode = s->last ? DRY : TYPE; + break; + case TABLE: + NEEDBITS(14) + s->sub.trees.table = t = (uInt)b & 0x3fff; +#ifndef PKZIP_BUG_WORKAROUND + if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) + { + s->mode = BAD; + z->msg = "too many length or distance symbols"; + r = Z_DATA_ERROR; + LEAVE + } +#endif + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); + if (t < 19) + t = 19; + if ((s->sub.trees.blens = (uInt*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + DUMPBITS(14) + s->sub.trees.index = 0; + Tracev((stderr, "inflate: table sizes ok\n")); + s->mode = BTREE; + case BTREE: + while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) + { + NEEDBITS(3) + s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; + DUMPBITS(3) + } + while (s->sub.trees.index < 19) + s->sub.trees.blens[border[s->sub.trees.index++]] = 0; + s->sub.trees.bb = 7; + t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, + &s->sub.trees.tb, z); + if (t != Z_OK) + { + r = t; + if (r == Z_DATA_ERROR) + s->mode = BAD; + LEAVE + } + s->sub.trees.index = 0; + Tracev((stderr, "inflate: bits tree ok\n")); + s->mode = DTREE; + case DTREE: + while (t = s->sub.trees.table, + s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) + { + inflate_huft *h; + uInt i, j, c; + + t = s->sub.trees.bb; + NEEDBITS(t) + h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); + t = h->word.what.Bits; + c = h->more.Base; + if (c < 16) + { + DUMPBITS(t) + s->sub.trees.blens[s->sub.trees.index++] = c; + } + else /* c == 16..18 */ + { + i = c == 18 ? 7 : c - 14; + j = c == 18 ? 11 : 3; + NEEDBITS(t + i) + DUMPBITS(t) + j += (uInt)b & inflate_mask[i]; + DUMPBITS(i) + i = s->sub.trees.index; + t = s->sub.trees.table; + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || + (c == 16 && i < 1)) + { + s->mode = BAD; + z->msg = "invalid bit length repeat"; + r = Z_DATA_ERROR; + LEAVE + } + c = c == 16 ? s->sub.trees.blens[i - 1] : 0; + do { + s->sub.trees.blens[i++] = c; + } while (--j); + s->sub.trees.index = i; + } + } + inflate_trees_free(s->sub.trees.tb, z); + s->sub.trees.tb = Z_NULL; + { + uInt bl, bd; + inflate_huft *tl, *td; + struct inflate_codes_state *c; + + bl = 9; + bd = 6; + t = s->sub.trees.table; + t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), + s->sub.trees.blens, &bl, &bd, &tl, &td, z); + if (t != Z_OK) + { + if (t == (uInt)Z_DATA_ERROR) + s->mode = BAD; + r = t; + LEAVE + } + Tracev((stderr, "inflate: trees ok\n")); + if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) + { + inflate_trees_free(td, z); + inflate_trees_free(tl, z); + r = Z_MEM_ERROR; + LEAVE + } + ZFREE(z, s->sub.trees.blens); + s->sub.codes = c; + } + s->mode = CODES; + case CODES: + UPDATE + if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) + return inflate_flush(s, z, r); + r = Z_OK; + inflate_codes_free(s->sub.codes, z); + LOAD + Tracev((stderr, "inflate: codes end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + if (!s->last) + { + s->mode = TYPE; + break; + } + if (k > 7) /* return unused byte, if any */ + { + Assert(k < 16, "inflate_codes grabbed too many bytes") + k -= 8; + n++; + p--; /* can always return one */ + } + s->mode = DRY; + case DRY: + FLUSH + if (s->read != s->write) + LEAVE + s->mode = DONE; + case DONE: + r = Z_STREAM_END; + LEAVE + case BAD: + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +} + + +int inflate_blocks_free(s, z, c) +struct inflate_blocks_state *s; +z_stream *z; +uLong *c; +{ + inflate_blocks_reset(s, z, c); + ZFREE(z, s->window); + ZFREE(z, s); + Trace((stderr, "inflate: blocks freed\n")); + return Z_OK; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/infblock.h Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,31 @@ +/* infblock.h -- header to use infblock.c + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +struct inflate_blocks_state; + +extern struct inflate_blocks_state * inflate_blocks_new __P(( + z_stream *, + check_func, /* check function */ + uInt)); /* window size */ + +extern int inflate_blocks __P(( + struct inflate_blocks_state *, + z_stream *, + int)); /* initial return code */ + +extern void inflate_blocks_reset __P(( + struct inflate_blocks_state *, + z_stream *, + uLong *)); /* check value on output */ + +extern int inflate_blocks_free __P(( + struct inflate_blocks_state *, + z_stream *, + uLong *)); /* check value on output */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/infcodes.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,238 @@ +/* infcodes.c -- process literals and length/distance pairs + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "infutil.h" +#include "inffast.h" +#include "infcodes.h" + +/* simplify the use of the inflate_huft type with some defines */ +#define base more.Base +#define next more.Next +#define exop word.what.Exop +#define bits word.what.Bits + +/* inflate codes private state */ +struct inflate_codes_state { + + /* mode */ + enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + START, /* x: set up for LEN */ + LEN, /* i: get length/literal/eob next */ + LENEXT, /* i: getting length extra (have base) */ + DIST, /* i: get distance next */ + DISTEXT, /* i: getting distance extra */ + COPY, /* o: copying bytes in window, waiting for space */ + LIT, /* o: got literal, waiting for output space */ + WASH, /* o: got eob, possibly still output waiting */ + END, /* x: got eob and all data flushed */ + BADCODE} /* x: got error */ + mode; /* current inflate_codes mode */ + + /* mode dependent information */ + uInt len; + union { + struct { + inflate_huft *tree; /* pointer into tree */ + uInt need; /* bits needed */ + } code; /* if LEN or DIST, where in tree */ + uInt lit; /* if LIT, literal */ + struct { + uInt get; /* bits to get for extra */ + uInt dist; /* distance back to copy from */ + } copy; /* if EXT or COPY, where and how much */ + } sub; /* submode */ + + /* mode independent information */ + Byte lbits; /* ltree bits decoded per branch */ + Byte dbits; /* dtree bits decoder per branch */ + inflate_huft *ltree; /* literal/length/eob tree */ + inflate_huft *dtree; /* distance tree */ + +}; + + +struct inflate_codes_state *inflate_codes_new(bl, bd, tl, td, z) +uInt bl, bd; +inflate_huft *tl, *td; +z_stream *z; +{ + struct inflate_codes_state *c; + + if ((c = (struct inflate_codes_state *) + ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) + { + c->mode = START; + c->lbits = (Byte)bl; + c->dbits = (Byte)bd; + c->ltree = tl; + c->dtree = td; + Tracev((stderr, "inflate: codes new\n")); + } + return c; +} + + +int inflate_codes(s, z, r) +struct inflate_blocks_state *s; +z_stream *z; +int r; +{ + uInt j; /* temporary storage */ + inflate_huft *t; /* temporary pointer */ + int e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Byte *p; /* input data pointer */ + uInt n; /* bytes available there */ + Byte *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + Byte *f; /* pointer to copy strings from */ + struct inflate_codes_state *c = s->sub.codes; /* codes state */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input and output based on current state */ + while (1) switch (c->mode) + { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + case START: /* x: set up for LEN */ +#ifndef SLOW + if (m >= 258 && n >= 10) + { + UPDATE + r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); + LOAD + if (r != Z_OK) + { + c->mode = r == Z_STREAM_END ? WASH : BADCODE; + break; + } + } +#endif /* !SLOW */ + c->sub.code.need = c->lbits; + c->sub.code.tree = c->ltree; + c->mode = LEN; + case LEN: /* i: get length/literal/eob next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + if ((e = (int)(t->exop)) < 0) + { + if (e == -128) /* invalid code */ + { + c->mode = BADCODE; + z->msg = "invalid literal/length code"; + r = Z_DATA_ERROR; + LEAVE + } + e = -e; + if (e & 64) /* end of block */ + { + Tracevv((stderr, "inflate: end of block\n")); + c->mode = WASH; + break; + } + c->sub.code.need = e; + c->sub.code.tree = t->next; + break; + } + if (e & 16) /* literal */ + { + c->sub.lit = t->base; + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", t->base)); + c->mode = LIT; + break; + } + c->sub.copy.get = e; + c->len = t->base; + c->mode = LENEXT; + case LENEXT: /* i: getting length extra (have base) */ + j = c->sub.copy.get; + NEEDBITS(j) + c->len += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + c->sub.code.need = c->dbits; + c->sub.code.tree = c->dtree; + Tracevv((stderr, "inflate: length %u\n", c->len)); + c->mode = DIST; + case DIST: /* i: get distance next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + if ((e = (int)(t->exop)) < 0) + { + if (e == -128) + { + c->mode = BADCODE; + z->msg = "invalid distance code"; + r = Z_DATA_ERROR; + LEAVE + } + c->sub.code.need = -e; + c->sub.code.tree = t->next; + break; + } + c->sub.copy.dist = t->base; + c->sub.copy.get = e; + c->mode = DISTEXT; + case DISTEXT: /* i: getting distance extra */ + j = c->sub.copy.get; + NEEDBITS(j) + c->sub.copy.dist += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); + c->mode = COPY; + case COPY: /* o: copying bytes in window, waiting for space */ + f = (uInt)(q - s->window) < c->sub.copy.dist ? + s->end - (c->sub.copy.dist - (q - s->window)) : + q - c->sub.copy.dist; + while (c->len) + { + NEEDOUT + OUTBYTE(*f++) + if (f == s->end) + f = s->window; + c->len--; + } + c->mode = START; + break; + case LIT: /* o: got literal, waiting for output space */ + NEEDOUT + OUTBYTE(c->sub.lit) + c->mode = START; + break; + case WASH: /* o: got eob, possibly more output */ + FLUSH + if (s->read != s->write) + LEAVE + c->mode = END; + case END: + r = Z_STREAM_END; + LEAVE + case BADCODE: /* x: got error */ + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +} + + +void inflate_codes_free(c, z) +struct inflate_codes_state *c; +z_stream *z; +{ + inflate_trees_free(c->dtree, z); + inflate_trees_free(c->ltree, z); + ZFREE(z, c); + Tracev((stderr, "inflate: codes free\n")); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/infcodes.h Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,25 @@ +/* infcodes.h -- header to use infcodes.c + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +struct inflate_codes_state; + +extern struct inflate_codes_state *inflate_codes_new __P(( + uInt, uInt, + inflate_huft *, inflate_huft *, + z_stream *)); + +extern int inflate_codes __P(( + struct inflate_blocks_state *, + z_stream *, + int)); + +extern void inflate_codes_free __P(( + struct inflate_codes_state *, + z_stream *));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/inffast.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,156 @@ +/* inffast.c -- process literals and length/distance pairs fast + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "infutil.h" +#include "inffast.h" + +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ + +/* simplify the use of the inflate_huft type with some defines */ +#define base more.Base +#define next more.Next +#define exop word.what.Exop +#define bits word.what.Bits + +/* macros for bit input with no checking and for returning unused bytes */ +#ifdef DEBUG +# undef NEXTBYTE +# define NEXTBYTE (n--?0:fprintf(stderr,"inffast underrun\n"),*p++) +#endif +#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}} +#define UNGRAB {n+=(c=k>>3);p-=c;k&=7;} + +/* Called with number of bytes left to write in window at least 258 + (the maximum string length) and number of input bytes available + at least ten. The ten bytes are six bytes for the longest length/ + distance pair plus four bytes for overloading the bit buffer. */ + +int inflate_fast(bl, bd, tl, td, s, z) +uInt bl, bd; +inflate_huft *tl, *td; +struct inflate_blocks_state *s; +z_stream *z; +{ + inflate_huft *t; /* temporary pointer */ + int e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Byte *p; /* input data pointer */ + uInt n; /* bytes available there */ + Byte *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + uInt ml; /* mask for literal/length tree */ + uInt md; /* mask for distance tree */ + uInt c; /* bytes to copy */ + uInt d; /* distance back to copy from */ + Byte *r; /* copy source pointer */ + + /* load input, output, bit values */ + LOAD + + /* initialize masks in registers */ + ml = inflate_mask[bl]; + md = inflate_mask[bd]; + + /* do until not enough input or output space for fast loop */ + do { /* assume called with m >= 258 && n >= 10 */ + /* get literal/length code */ + GRABBITS(20) /* max bits for literal/length code */ + if ((e = (t = tl + ((uInt)b & ml))->exop) < 0) + do { + if (e == -128) + { + z->msg = "invalid literal/length code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + DUMPBITS(t->bits) + e = -e; + if (e & 64) /* end of block */ + { + Tracevv((stderr, "inflate: * end of block\n")); + UNGRAB + UPDATE + return Z_STREAM_END; + } + } while ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) < 0); + DUMPBITS(t->bits) + + /* process literal or length (end of block already trapped) */ + if (e & 16) /* then it's a literal */ + { + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + } + else /* it's a length */ + { + /* get length of block to copy (already have extra bits) */ + c = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e); + Tracevv((stderr, "inflate: * length %u\n", c)); + + /* decode distance base of block to copy */ + GRABBITS(15); /* max bits for distance code */ + if ((e = (t = td + ((uInt)b & md))->exop) < 0) + do { + if (e == -128) + { + z->msg = "invalid distance code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + DUMPBITS(t->bits) + e = -e; + } while ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) < 0); + DUMPBITS(t->bits) + + /* get extra bits to add to distance base */ + GRABBITS((uInt)e) /* get extra bits (up to 13) */ + d = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv((stderr, "inflate: * distance %u\n", d)); + + /* do the copy */ + m -= c; + if ((uInt)(q - s->window) >= d) /* if offset before destination, */ + { /* just copy */ + r = q - d; + *q++ = *r++; c--; /* minimum count is three, */ + *q++ = *r++; c--; /* so unroll loop a little */ + do { + *q++ = *r++; + } while (--c); + } + else /* else offset after destination */ + { + e = d - (q - s->window); /* bytes from offset to end */ + r = s->end - e; /* pointer to offset */ + if (c > (uInt)e) /* if source crosses, */ + { + c -= e; /* copy to end of window */ + do { + *q++ = *r++; + } while (--e); + r = s->window; /* copy rest from start of window */ + } + do { /* copy all or what's left */ + *q++ = *r++; + } while (--c); + } + } + } while (m >= 258 && n >= 10); + + /* not enough input or output--restore pointers and return */ + UNGRAB + UPDATE + return Z_OK; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/inffast.h Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,17 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +extern int inflate_fast __P(( + uInt, + uInt, + inflate_huft *, + inflate_huft *, + struct inflate_blocks_state *, + z_stream *));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/inflate.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,281 @@ +/* inflate.c -- zlib interface to inflate modules + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" + +struct inflate_blocks_state {int dummy;}; /* for buggy compilers */ + +/* inflate private state */ +struct internal_state { + + /* mode */ + enum { + METHOD, /* waiting for method byte */ + FLAG, /* waiting for flag byte */ + BLOCKS, /* decompressing blocks */ + CHECK4, /* four check bytes to go */ + CHECK3, /* three check bytes to go */ + CHECK2, /* two check bytes to go */ + CHECK1, /* one check byte to go */ + DONE, /* finished check, done */ + BAD} /* got an error--stay here */ + mode; /* current inflate mode */ + + /* mode dependent information */ + union { + uInt method; /* if FLAGS, method byte */ + struct { + uLong was; /* computed check value */ + uLong need; /* stream check value */ + } check; /* if CHECK, check values to compare */ + uInt marker; /* if BAD, inflateSync's marker bytes count */ + } sub; /* submode */ + + /* mode independent information */ + int nowrap; /* flag for no wrapper */ + uInt wbits; /* log2(window size) (8..15, defaults to 15) */ + struct inflate_blocks_state + *blocks; /* current inflate_blocks state */ + +}; + + +int inflateReset(z) +z_stream *z; +{ + uLong c; + + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + z->total_in = z->total_out = 0; + z->msg = Z_NULL; + z->state->mode = z->state->nowrap ? BLOCKS : METHOD; + inflate_blocks_reset(z->state->blocks, z, &c); + Trace((stderr, "inflate: reset\n")); + return Z_OK; +} + + +int inflateEnd(z) +z_stream *z; +{ + uLong c; + + if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->blocks != Z_NULL) + inflate_blocks_free(z->state->blocks, z, &c); + ZFREE(z, z->state); + z->state = Z_NULL; + Trace((stderr, "inflate: end\n")); + return Z_OK; +} + + +int inflateInit2(z, w) +z_stream *z; +int w; +{ + /* initialize state */ + if (z == Z_NULL) + return Z_STREAM_ERROR; + if (z->zalloc == Z_NULL) z->zalloc = zcalloc; + if (z->zfree == Z_NULL) z->zfree = zcfree; + if ((z->state = (struct internal_state *) + ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) + return Z_MEM_ERROR; + z->state->blocks = Z_NULL; + + /* handle undocumented nowrap option (no zlib header or check) */ + z->state->nowrap = 0; + if (w < 0) + { + w = - w; + z->state->nowrap = 1; + } + + /* set window size */ + if (w < 8 || w > 15) + { + inflateEnd(z); + return Z_STREAM_ERROR; + } + z->state->wbits = (uInt)w; + + /* create inflate_blocks state */ + if ((z->state->blocks = + inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w)) + == Z_NULL) + { + inflateEnd(z); + return Z_MEM_ERROR; + } + Trace((stderr, "inflate: allocated\n")); + + /* reset state */ + inflateReset(z); + return Z_OK; +} + + +int inflateInit(z) +z_stream *z; +{ + return inflateInit2(z, DEF_WBITS); +} + + +#define NEEDBYTE {if(z->avail_in==0)return r;r=Z_OK;} +#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) + +int inflate(z, f) +z_stream *z; +int f; +{ + int r = f; /* to avoid warning about unused f */ + uInt b; + + if (z == Z_NULL || z->next_in == Z_NULL) + return Z_STREAM_ERROR; + r = Z_BUF_ERROR; + while (1) switch (z->state->mode) + { + case METHOD: + NEEDBYTE + if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED) + { + z->state->mode = BAD; + z->msg = "unknown compression method"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + if ((z->state->sub.method >> 4) + 8 > z->state->wbits) + { + z->state->mode = BAD; + z->msg = "invalid window size"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + z->state->mode = FLAG; + case FLAG: + NEEDBYTE + if ((b = NEXTBYTE) & 0x20) + { + z->state->mode = BAD; + z->msg = "invalid reserved bit"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + if (((z->state->sub.method << 8) + b) % 31) + { + z->state->mode = BAD; + z->msg = "incorrect header check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Trace((stderr, "inflate: zlib header ok\n")); + z->state->mode = BLOCKS; + case BLOCKS: + r = inflate_blocks(z->state->blocks, z, r); + if (r == Z_DATA_ERROR) + { + z->state->mode = BAD; + z->state->sub.marker = 0; /* can try inflateSync */ + break; + } + if (r != Z_STREAM_END) + return r; + r = Z_OK; + inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); + if (z->state->nowrap) + { + z->state->mode = DONE; + break; + } + z->state->mode = CHECK4; + case CHECK4: + NEEDBYTE + z->state->sub.check.need = (uLong)NEXTBYTE << 24; + z->state->mode = CHECK3; + case CHECK3: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 16; + z->state->mode = CHECK2; + case CHECK2: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 8; + z->state->mode = CHECK1; + case CHECK1: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE; + + if (z->state->sub.check.was != z->state->sub.check.need) + { + z->state->mode = BAD; + z->msg = "incorrect data check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Trace((stderr, "inflate: zlib check ok\n")); + z->state->mode = DONE; + case DONE: + return Z_STREAM_END; + case BAD: + return Z_DATA_ERROR; + default: + return Z_STREAM_ERROR; + } +} + + +int inflateSync(z) +z_stream *z; +{ + uInt n; /* number of bytes to look at */ + Byte *p; /* pointer to bytes */ + uInt m; /* number of marker bytes found in a row */ + uLong r, w; /* temporaries to save total_in and total_out */ + + /* set up */ + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->mode != BAD) + { + z->state->mode = BAD; + z->state->sub.marker = 0; + } + if ((n = z->avail_in) == 0) + return Z_BUF_ERROR; + p = z->next_in; + m = z->state->sub.marker; + + /* search */ + while (n && m < 4) + { + if (*p == (Byte)(m < 2 ? 0 : 0xff)) + m++; + else if (*p) + m = 0; + else + m = 4 - m; + p++, n--; + } + + /* restore */ + z->total_in += p - z->next_in; + z->next_in = p; + z->avail_in = n; + z->state->sub.marker = m; + + /* return no joy or set up to restart on a new block */ + if (m != 4) + return Z_DATA_ERROR; + r = z->total_in; w = z->total_out; + inflateReset(z); + z->total_in = r; z->total_out = w; + z->state->mode = BLOCKS; + return Z_OK; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/inftrees.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,473 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +struct internal_state {int dummy;}; /* for buggy compilers */ + +/* simplify the use of the inflate_huft type with some defines */ +#define base more.Base +#define next more.Next +#define exop word.what.Exop +#define bits word.what.Bits + + +local int huft_build __P(( + uInt *, /* code lengths in bits */ + uInt, /* number of codes */ + uInt, /* number of "simple" codes */ + uInt *, /* list of base values for non-simple codes */ + uInt *, /* list of extra bits for non-simple codes */ + inflate_huft **, /* result: starting table */ + uInt *, /* maximum lookup bits (returns actual) */ + z_stream *)); /* for zalloc function */ + +local voidp falloc __P(( + voidp, /* opaque pointer (not used) */ + uInt, /* number of items */ + uInt)); /* size of item */ + +local void ffree __P(( + voidp q, /* opaque pointer (not used) */ + voidp p)); /* what to free (not used) */ + +/* Tables for deflate from PKZIP's appnote.txt. */ +local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + /* actually lengths - 2; also see note #13 above about 258 */ +local uInt cplext[] = { /* Extra bits for literal codes 257..285 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 128, 128}; /* 128==invalid */ +local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; +local uInt cpdext[] = { /* Extra bits for distance codes */ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + +/* + Huffman code decoding is performed using a multi-level table lookup. + The fastest way to decode is to simply build a lookup table whose + size is determined by the longest code. However, the time it takes + to build this table can also be a factor if the data being decoded + is not very long. The most common codes are necessarily the + shortest codes, so those codes dominate the decoding time, and hence + the speed. The idea is you can have a shorter table that decodes the + shorter, more probable codes, and then point to subsidiary tables for + the longer codes. The time it costs to decode the longer codes is + then traded against the time it takes to make longer tables. + + This results of this trade are in the variables lbits and dbits + below. lbits is the number of bits the first level table for literal/ + length codes can decode in one step, and dbits is the same thing for + the distance codes. Subsequent tables are also less than or equal to + those sizes. These values may be adjusted either when all of the + codes are shorter than that, in which case the longest code length in + bits is used, or when the shortest code is *longer* than the requested + table size, in which case the length of the shortest code in bits is + used. + + There are two different values for the two tables, since they code a + different number of possibilities each. The literal/length table + codes 286 possible values, or in a flat code, a little over eight + bits. The distance table codes 30 possible values, or a little less + than five bits, flat. The optimum values for speed end up being + about one bit more than those, so lbits is 8+1 and dbits is 5+1. + The optimum values may differ though from machine to machine, and + possibly even between compilers. Your mileage may vary. + */ + + +/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ +#define BMAX 15 /* maximum bit length of any code */ +#define N_MAX 288 /* maximum number of codes in any set */ + +#ifdef DEBUG + uInt inflate_hufts; +#endif + +local int huft_build(b, n, s, d, e, t, m, zs) +uInt *b; /* code lengths in bits (all assumed <= BMAX) */ +uInt n; /* number of codes (assumed <= N_MAX) */ +uInt s; /* number of simple-valued codes (0..s-1) */ +uInt *d; /* list of base values for non-simple codes */ +uInt *e; /* list of extra bits for non-simple codes */ +inflate_huft **t; /* result: starting table */ +uInt *m; /* maximum lookup bits, returns actual */ +z_stream *zs; /* for zalloc function */ +/* Given a list of code lengths and a maximum table size, make a set of + tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR + if the given code set is incomplete (the tables are still built in this + case), Z_DATA_ERROR if the input is invalid (all zero length codes or an + over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */ +{ + uInt a; /* counter for codes of length k */ + uInt c[BMAX+1]; /* bit length count table */ + uInt f; /* i repeats in table every f entries */ + int g; /* maximum code length */ + int h; /* table level */ + register uInt i; /* counter, current code */ + register uInt j; /* counter */ + register int k; /* number of bits in current code */ + int l; /* bits per table (returned in m) */ + register uInt *p; /* pointer into c[], b[], or v[] */ + register inflate_huft *q; /* points to current table */ + inflate_huft r; /* table entry for structure assignment */ + inflate_huft *u[BMAX]; /* table stack */ + uInt v[N_MAX]; /* values in order of bit length */ + register int w; /* bits before this table == (l * h) */ + uInt x[BMAX+1]; /* bit offsets, then code stack */ + uInt *xp; /* pointer into x */ + int y; /* number of dummy codes added */ + uInt z; /* number of entries in current table */ + + + /* Generate counts for each bit length */ + p = c; +#define C0 *p++ = 0; +#define C2 C0 C0 C0 C0 +#define C4 C2 C2 C2 C2 + C4 /* clear c[]--assume BMAX+1 is 16 */ + p = b; i = n; + do { + c[*p++]++; /* assume all entries <= BMAX */ + } while (--i); + if (c[0] == n) /* null input--all zero length codes */ + { + *t = (inflate_huft *)Z_NULL; + *m = 0; + return Z_OK; + } + + + /* Find minimum and maximum length, bound *m by those */ + l = *m; + for (j = 1; j <= BMAX; j++) + if (c[j]) + break; + k = j; /* minimum code length */ + if ((uInt)l < j) + l = j; + for (i = BMAX; i; i--) + if (c[i]) + break; + g = i; /* maximum code length */ + if ((uInt)l > i) + l = i; + *m = l; + + + /* Adjust last length count to fill out codes, if needed */ + for (y = 1 << j; j < i; j++, y <<= 1) + if ((y -= c[j]) < 0) + return Z_DATA_ERROR; + if ((y -= c[i]) < 0) + return Z_DATA_ERROR; + c[i] += y; + + + /* Generate starting offsets into the value table for each length */ + x[1] = j = 0; + p = c + 1; xp = x + 2; + while (--i) { /* note that i == g from above */ + *xp++ = (j += *p++); + } + + + /* Make a table of values in order of bit lengths */ + p = b; i = 0; + do { + if ((j = *p++) != 0) + v[x[j]++] = i; + } while (++i < n); + + + /* Generate the Huffman codes and for each, make the table entries */ + x[0] = i = 0; /* first Huffman code is zero */ + p = v; /* grab values in bit order */ + h = -1; /* no tables yet--level -1 */ + w = -l; /* bits decoded == (l * h) */ + u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ + q = (inflate_huft *)Z_NULL; /* ditto */ + z = 0; /* ditto */ + + /* go through the bit lengths (k already is bits in shortest code) */ + for (; k <= g; k++) + { + a = c[k]; + while (a--) + { + /* here i is the Huffman code of length k bits for value *p */ + /* make tables up to required level */ + while (k > w + l) + { + h++; + w += l; /* previous table always l bits */ + + /* compute minimum size table less than or equal to l bits */ + z = (z = g - w) > (uInt)l ? l : z; /* table size upper limit */ + if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ + { /* too few codes for k-w bit table */ + f -= a + 1; /* deduct codes from patterns left */ + xp = c + k; + if (j < z) + while (++j < z) /* try smaller tables up to z bits */ + { + if ((f <<= 1) <= *++xp) + break; /* enough codes to use up j bits */ + f -= *xp; /* else deduct codes from patterns */ + } + } + z = 1 << j; /* table entries for j-bit table */ + + /* allocate and link in new table */ + if ((q = (inflate_huft *)ZALLOC + (zs,z + 1,sizeof(inflate_huft))) == Z_NULL) + { + if (h) + inflate_trees_free(u[0], zs); + return Z_MEM_ERROR; /* not enough memory */ + } +#ifdef DEBUG + inflate_hufts += z + 1; +#endif + *t = q + 1; /* link to list for huft_free() */ + *(t = &(q->next)) = (inflate_huft *)Z_NULL; + u[h] = ++q; /* table starts after link */ + + /* connect to last table, if there is one */ + if (h) + { + x[h] = i; /* save pattern for backing up */ + r.bits = (Byte)l; /* bits to dump before this table */ + r.exop = -(Char)j; /* bits in this table */ + r.next = q; /* pointer to this table */ + j = i >> (w - l); /* (get around Turbo C bug) */ + u[h-1][j] = r; /* connect to last table */ + } + } + + /* set up table entry in r */ + r.bits = (Byte)(k - w); + if (p >= v + n) + r.exop = (Char)(-128); /* out of values--invalid code */ + else if (*p < s) + { + r.exop = (Char)(*p < 256 ? 16 : -64); /* 256 is end-of-block code */ + r.base = *p++; /* simple code is just the value */ + } + else + { + r.exop = (Char)e[*p - s]; /* non-simple--look up in lists */ + r.base = d[*p++ - s]; + } + + /* fill code-like entries with r */ + f = 1 << (k - w); + for (j = i >> w; j < z; j += f) + q[j] = r; + + /* backwards increment the k-bit code i */ + for (j = 1 << (k - 1); i & j; j >>= 1) + i ^= j; + i ^= j; + + /* backup over finished tables */ + while ((i & ((1 << w) - 1)) != x[h]) + { + h--; /* don't need to update q */ + w -= l; + } + } + } + + + /* Return Z_BUF_ERROR if we were given an incomplete table */ + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; +} + + +int inflate_trees_bits(c, bb, tb, z) +uInt *c; /* 19 code lengths */ +uInt *bb; /* bits tree desired/actual depth */ +inflate_huft **tb; /* bits tree result */ +z_stream *z; /* for zfree function */ +{ + int r; + + r = huft_build(c, 19, 19, (uInt*)Z_NULL, (uInt*)Z_NULL, tb, bb, z); + if (r == Z_DATA_ERROR) + z->msg = "oversubscribed dynamic bit lengths tree"; + else if (r == Z_BUF_ERROR) + { + inflate_trees_free(*tb, z); + z->msg = "incomplete dynamic bit lengths tree"; + r = Z_DATA_ERROR; + } + return r; +} + + +int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z) +uInt nl; /* number of literal/length codes */ +uInt nd; /* number of distance codes */ +uInt *c; /* that many (total) code lengths */ +uInt *bl; /* literal desired/actual bit depth */ +uInt *bd; /* distance desired/actual bit depth */ +inflate_huft **tl; /* literal/length tree result */ +inflate_huft **td; /* distance tree result */ +z_stream *z; /* for zfree function */ +{ + int r; + + /* build literal/length tree */ + if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK) + { + if (r == Z_DATA_ERROR) + z->msg = "oversubscribed literal/length tree"; + else if (r == Z_BUF_ERROR) + { + inflate_trees_free(*tl, z); + z->msg = "incomplete literal/length tree"; + r = Z_DATA_ERROR; + } + return r; + } + + /* build distance tree */ + if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK) + { + if (r == Z_DATA_ERROR) + z->msg = "oversubscribed literal/length tree"; + else if (r == Z_BUF_ERROR) { +#ifdef PKZIP_BUG_WORKAROUND + r = Z_OK; + } +#else + inflate_trees_free(*td, z); + z->msg = "incomplete literal/length tree"; + r = Z_DATA_ERROR; + } + inflate_trees_free(*tl, z); + return r; +#endif + } + + /* done */ + return Z_OK; +} + + +/* build fixed tables only once--keep them here */ +local int fixed_lock = 0; +local int fixed_built = 0; +#define FIXEDH 530 /* number of hufts used by fixed tables */ +local uInt fixed_left = FIXEDH; +local inflate_huft fixed_mem[FIXEDH]; +local uInt fixed_bl; +local uInt fixed_bd; +local inflate_huft *fixed_tl; +local inflate_huft *fixed_td; + + +local voidp falloc(q, n, s) +voidp q; /* opaque pointer (not used) */ +uInt n; /* number of items */ +uInt s; /* size of item */ +{ + Assert(s == sizeof(inflate_huft) && n <= fixed_left, + "inflate_trees falloc overflow"); + if (q) s++; /* to make some compilers happy */ + fixed_left -= n; + return (voidp)(fixed_mem + fixed_left); +} + + +local void ffree(q, p) +voidp q; +voidp p; +{ + Assert(0, "inflate_trees ffree called!"); + if (q) q = p; /* to make some compilers happy */ +} + + +int inflate_trees_fixed(bl, bd, tl, td) +uInt *bl; /* literal desired/actual bit depth */ +uInt *bd; /* distance desired/actual bit depth */ +inflate_huft **tl; /* literal/length tree result */ +inflate_huft **td; /* distance tree result */ +{ + /* build fixed tables if not built already--lock out other instances */ + while (++fixed_lock > 1) + fixed_lock--; + if (!fixed_built) + { + int k; /* temporary variable */ + unsigned c[288]; /* length list for huft_build */ + z_stream z; /* for falloc function */ + + /* set up fake z_stream for memory routines */ + z.zalloc = falloc; + z.zfree = ffree; + z.opaque = Z_NULL; + + /* literal table */ + for (k = 0; k < 144; k++) + c[k] = 8; + for (; k < 256; k++) + c[k] = 9; + for (; k < 280; k++) + c[k] = 7; + for (; k < 288; k++) + c[k] = 8; + fixed_bl = 7; + huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z); + + /* distance table */ + for (k = 0; k < 30; k++) + c[k] = 5; + fixed_bd = 5; + huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z); + + /* done */ + fixed_built = 1; + } + fixed_lock--; + *bl = fixed_bl; + *bd = fixed_bd; + *tl = fixed_tl; + *td = fixed_td; + return Z_OK; +} + + +int inflate_trees_free(t, z) +inflate_huft *t; /* table to free */ +z_stream *z; /* for zfree function */ +/* Free the malloc'ed tables built by huft_build(), which makes a linked + list of the tables it made, with the links in a dummy first entry of + each table. */ +{ + register inflate_huft *p, *q; + + /* Don't free fixed trees */ + if (t >= fixed_mem && t <= fixed_mem + FIXEDH) + return Z_OK; + + /* Go through linked list, freeing from the malloced (t[-1]) address. */ + p = t; + while (p != Z_NULL) + { + q = (--p)->next; + ZFREE(z,p); + p = q; + } + return Z_OK; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/inftrees.h Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,68 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Huffman code lookup table entry--this entry is four bytes for machines + that have 16-bit pointers (e.g. PC's in the small or medium model). + Valid extra bits (exop) are 0..13. exop == -64 is EOB (end of block), + exop == 16 means that v is a literal, exop < 0 means that v is a pointer + to the next table, which codes -exop bits, and lastly exop == -128 + indicates an unused code. If a code with exop == -128 is looked up, + this implies an error in the data. */ + +#if defined(STDC) || defined(sgi) +typedef signed char Char; +#else +typedef char Char; /* just hope that char is signed */ +#endif + +typedef struct inflate_huft_s inflate_huft; +struct inflate_huft_s { + union { + struct { + Char Exop; /* number of extra bits or operation */ + Byte Bits; /* number of bits in this code or subcode */ + } what; + Byte *pad; /* pad structure to a power of 2 (4 bytes for */ + } word; /* 16-bit, 8 bytes for 32-bit machines) */ + union { + uInt Base; /* literal, length base, or distance base */ + inflate_huft *Next; /* pointer to next level of table */ + } more; +}; + +#ifdef DEBUG + extern uInt inflate_hufts; +#endif + +extern int inflate_trees_bits __P(( + uInt *, /* 19 code lengths */ + uInt *, /* bits tree desired/actual depth */ + inflate_huft **, /* bits tree result */ + z_stream *)); /* for zalloc, zfree functions */ + +extern int inflate_trees_dynamic __P(( + uInt, /* number of literal/length codes */ + uInt, /* number of distance codes */ + uInt *, /* that many (total) code lengths */ + uInt *, /* literal desired/actual bit depth */ + uInt *, /* distance desired/actual bit depth */ + inflate_huft **, /* literal/length tree result */ + inflate_huft **, /* distance tree result */ + z_stream *)); /* for zalloc, zfree functions */ + +extern int inflate_trees_fixed __P(( + uInt *, /* literal desired/actual bit depth */ + uInt *, /* distance desired/actual bit depth */ + inflate_huft **, /* literal/length tree result */ + inflate_huft **)); /* distance tree result */ + +extern int inflate_trees_free __P(( + inflate_huft *, /* tables to free */ + z_stream *)); /* for zfree function */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/infutil.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,84 @@ +/* inflate_util.c -- data and routines common to blocks and codes + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "infutil.h" + +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ + +/* And'ing with mask[n] masks the lower n bits */ +uInt inflate_mask[] = { + 0x0000, + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff +}; + + +/* copy as much as possible from the sliding window to the output area */ +int inflate_flush(s, z, r) +struct inflate_blocks_state *s; +z_stream *z; +int r; +{ + uInt n; + Byte *p, *q; + + /* local copies of source and destination pointers */ + p = z->next_out; + q = s->read; + + /* compute number of bytes to copy as far as end of window */ + n = (uInt)((q <= s->write ? s->write : s->end) - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + s->check = (*s->checkfn)(s->check, q, n); + + /* copy as far as end of window */ + zmemcpy(p, q, n); + p += n; + q += n; + + /* see if more to copy at beginning of window */ + if (q == s->end) + { + /* wrap pointers */ + q = s->window; + if (s->write == s->end) + s->write = s->window; + + /* compute bytes to copy */ + n = (uInt)(s->write - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + s->check = (*s->checkfn)(s->check, q, n); + + /* copy */ + zmemcpy(p, q, n); + p += n; + q += n; + } + + /* update pointers */ + z->next_out = p; + s->read = q; + + /* done */ + return r; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/infutil.h Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,87 @@ +/* infutil.h -- types and macros common to blocks and codes + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* inflate blocks semi-private state */ +struct inflate_blocks_state { + + /* mode */ + enum { + TYPE, /* get type bits (3, including end bit) */ + LENS, /* get lengths for stored */ + STORED, /* processing stored block */ + TABLE, /* get table lengths */ + BTREE, /* get bit lengths tree for a dynamic block */ + DTREE, /* get length, distance trees for a dynamic block */ + CODES, /* processing fixed or dynamic block */ + DRY, /* output remaining window bytes */ + DONE, /* finished last block, done */ + BAD} /* got a data error--stuck here */ + mode; /* current inflate_block mode */ + + /* mode dependent information */ + union { + uInt left; /* if STORED, bytes left to copy */ + struct { + uInt table; /* table lengths (14 bits) */ + uInt index; /* index into blens (or border) */ + uInt *blens; /* bit lengths of codes */ + uInt bb; /* bit length tree depth */ + inflate_huft *tb; /* bit length decoding tree */ + } trees; /* if DTREE, decoding info for trees */ + struct inflate_codes_state + *codes; /* if CODES, current state */ + } sub; /* submode */ + uInt last; /* true if this block is the last block */ + + /* mode independent information */ + uInt bitk; /* bits in bit buffer */ + uLong bitb; /* bit buffer */ + Byte *window; /* sliding window */ + Byte *end; /* one byte after sliding window */ + Byte *read; /* window read pointer */ + Byte *write; /* window write pointer */ + check_func checkfn; /* check function */ + uLong check; /* check on output */ + +}; + +/* defines for inflate input/output */ +/* update pointers and return */ +#define UPDBITS {s->bitb=b;s->bitk=k;} +#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} +#define UPDOUT {s->write=q;} +#define UPDATE {UPDBITS UPDIN UPDOUT} +#define LEAVE {UPDATE return inflate_flush(s,z,r);} +/* get bytes and bits */ +#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} +#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} +#define NEXTBYTE (n--,*p++) +#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}} +#define DUMPBITS(j) {b>>=(j);k-=(j);} +/* output bytes */ +#define WAVAIL (q<s->read?s->read-q-1:s->end-q) +#define LOADOUT {q=s->write;m=WAVAIL;} +#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}} +#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} +#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} +#define OUTBYTE(a) {*q++=(Byte)(a);m--;} +/* load local pointers */ +#define LOAD {LOADIN LOADOUT} + +/* masks for lower bits */ +extern uInt inflate_mask[]; + +/* copy as much as possible from the sliding window to the output area */ +extern int inflate_flush __P(( + struct inflate_blocks_state *, + z_stream *, + int)); + +struct internal_state {int dummy;}; /* for buggy compilers */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/minigzip.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,227 @@ +/* minigzip.c -- simulate gzip using the zlib compression library + * Copyright (C) 1995 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * minigzip is a minimal implementation of the gzip utility. This is + * only an example of using zlib and isn't meant to replace the + * full-featured gzip. No attempt is made to deal with file systems + * limiting names to 14 or 8+3 characters, etc... Error checking is + * very limited. So use minigzip only for testing; use gzip for the + * real thing. On MSDOS, use only on file names without extension + * or in pipe mode. + */ + +/* $Id: minigzip.c,v 1.1.1.1 1997/12/06 05:41:38 darius Exp $ */ + +#include <stdio.h> +#include "zlib.h" + +#ifndef __GO32__ +extern void exit __P((int)); +#endif +extern int unlink __P((const char *)); + +#ifdef STDC +# include <string.h> +#endif + +#ifdef MSDOS +# include <fcntl.h> +# include <io.h> +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +#define BUFLEN 4096 +#define MAX_NAME_LEN 1024 + +#define local static +/* For MSDOS and other systems with limitation on stack size. For Unix, + #define local + works also. + */ + +char *prog; + +void error __P((char *msg)); +void gz_compress __P((FILE *in, gzFile out)); +void gz_uncompress __P((gzFile in, FILE *out)); +void file_compress __P((char *file)); +void file_uncompress __P((char *file)); +void main __P((int argc, char *argv[])); + +/* =========================================================================== + * Display error message and exit + */ +void error(msg) + char *msg; +{ + fprintf(stderr, "%s: %s\n", prog, msg); + exit(1); +} + +/* =========================================================================== + * Compress input to output then close both files. + */ +void gz_compress(in, out) + FILE *in; + gzFile out; +{ + local char buf[BUFLEN]; + int len; + int err; + + for (;;) { + len = fread(buf, 1, sizeof(buf), in); + if (ferror(in)) { + perror("fread"); + exit(1); + } + if (len == 0) break; + + if (gzwrite(out, buf, len) != len) error(gzerror(out, &err)); + } + fclose(in); + if (gzclose(out) != Z_OK) error("failed gzclose"); +} + +/* =========================================================================== + * Uncompress input to output then close both files. + */ +void gz_uncompress(in, out) + gzFile in; + FILE *out; +{ + local char buf[BUFLEN]; + int len; + int err; + + for (;;) { + len = gzread(in, buf, sizeof(buf)); + if (len < 0) error (gzerror(in, &err)); + if (len == 0) break; + + if (fwrite(buf, 1, len, out) != (uInt)len) error("failed fwrite"); + } + if (fclose(out)) error("failed fclose"); + + if (gzclose(in) != Z_OK) error("failed gzclose"); +} + + +/* =========================================================================== + * Compress the given file: create a corresponding .gz file and remove the + * original. + */ +void file_compress(file) + char *file; +{ + local char outfile[MAX_NAME_LEN]; + FILE *in; + gzFile out; + + strcpy(outfile, file); + strcat(outfile, ".gz"); + + in = fopen(file, "rb"); + if (in == NULL) { + perror(file); + exit(1); + } + out = gzopen(outfile, "wb"); + if (out == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile); + exit(1); + } + gz_compress(in, out); + + unlink(file); +} + + +/* =========================================================================== + * Uncompress the given file and remove the original. + */ +void file_uncompress(file) + char *file; +{ + local char buf[MAX_NAME_LEN]; + char *infile, *outfile; + FILE *out; + gzFile in; + int len = strlen(file); + + strcpy(buf, file); + + if (len > 3 && strcmp(file+len-3, ".gz") == 0) { + infile = file; + outfile = buf; + outfile[len-3] = '\0'; + } else { + outfile = file; + infile = buf; + strcat(infile, ".gz"); + } + in = gzopen(infile, "rb"); + if (in == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, infile); + exit(1); + } + out = fopen(outfile, "wb"); + if (out == NULL) { + perror(file); + exit(1); + } + + gz_uncompress(in, out); + + unlink(infile); +} + + +/* =========================================================================== + * Usage: minigzip [-d] [files...] + */ + +void main(argc, argv) + int argc; + char *argv[]; +{ + int uncompr = 0; + gzFile file; + + prog = argv[0]; + argc--, argv++; + + if (argc > 0) { + uncompr = (strcmp(*argv, "-d") == 0); + if (uncompr) { + argc--, argv++; + } + } + if (argc == 0) { + SET_BINARY_MODE(stdin); + SET_BINARY_MODE(stdout); + if (uncompr) { + file = gzdopen(fileno(stdin), "rb"); + if (file == NULL) error("can't gzdopen stdin"); + gz_uncompress(file, stdout); + } else { + file = gzdopen(fileno(stdout), "wb"); + if (file == NULL) error("can't gzdopen stdout"); + gz_compress(stdin, file); + } + } else { + do { + if (uncompr) { + file_uncompress(*argv); + } else { + file_compress(*argv); + } + } while (argv++, --argc); + } + exit(0); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/trees.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,1060 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* $Id: trees.c,v 1.1.1.1 1997/12/06 05:41:38 darius Exp $ */ + +#include "deflate.h" + +#ifdef DEBUG +# include <ctype.h> +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +#define Buf_size (8 * 2*sizeof(char)) +/* Number of bits used within bi_buf. (bi_buf might be implemented on + * more than 16 bits on some systems.) + */ + +/* =========================================================================== + * Local data. These are initialized only once. + * To do: initialize at compile time to be completely reentrant. ??? + */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see ct_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +local uch dist_code[512]; +/* distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +local uch length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +struct static_tree_desc_s { + ct_data *static_tree; /* static tree or NULL */ + int *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void ct_static_init __P((void)); +local void init_block __P((deflate_state *s)); +local void pqdownheap __P((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen __P((deflate_state *s, tree_desc *desc)); +local void gen_codes __P((ct_data *tree, int max_code, ush bl_count[])); +local void build_tree __P((deflate_state *s, tree_desc *desc)); +local void scan_tree __P((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree __P((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree __P((deflate_state *s)); +local void send_all_trees __P((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block __P((deflate_state *s, ct_data *ltree, + ct_data *dtree)); +local void set_data_type __P((deflate_state *s)); +local void send_bits __P((deflate_state *s, int value, int length)); +local unsigned bi_reverse __P((unsigned value, int length)); +local void bi_windup __P((deflate_state *s)); +local void copy_block __P((deflate_state *s, char *buf, unsigned len, + int header)); + +#ifndef DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG */ +# define send_code(s, c, tree) \ + { if (verbose>1) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +#define d_code(dist) \ + ((dist) < 256 ? dist_code[dist] : dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. dist_code[256] and dist_code[257] are never + * used. + */ + +#define MAX(a,b) (a >= b ? a : b) +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + * To do: do this at compile time. + */ +local void ct_static_init() +{ + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1<<extra_lbits[code]); n++) { + length_code[length++] = (uch)code; + } + } + Assert (length == 256, "ct_static_init: length != 256"); + /* Note that the length 255 (match length 258) can be represented + * in two different ways: code 284 + 5 bits or code 285, so we + * overwrite length_code[255] to use the best encoding: + */ + length_code[length-1] = (uch)code; + + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<<extra_dbits[code]); n++) { + dist_code[dist++] = (uch)code; + } + } + Assert (dist == 256, "ct_static_init: dist != 256"); + dist >>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "ct_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse(n, 5); + } +} + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void ct_init(s) + deflate_state *s; +{ + if (static_dtree[0].Len == 0) { + ct_static_init(); /* To do: at compile time */ + } + + s->compressed_len = 0L; + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + ct_data *stree = desc->stat_desc->static_tree; + int *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if (tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ush bl_count[]; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1, + "inconsistent bit counts"); + Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); + + for (n = 0; n <= max_code; n++) { + int len = tree[n].Len; + if (len == 0) continue; + /* Now reverse the bits */ + tree[n].Code = bi_reverse(next_code[len]++, len); + + Tracec(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", + n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); + } +} + +/* =========================================================================== + * Construct one Huffman tree and assigns the code bit strings and lengths. + * Update the total bit length for the current block. + * IN assertion: the field freq is set for all tree elements. + * OUT assertions: the fields len and code are set to the optimal bit length + * and corresponding code. The length opt_len is updated; static_len is + * also updated if stree is not null. The field max_code is set. + */ +local void build_tree(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node = elems; /* next internal node of the tree */ + int new; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + new = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[new].Freq = 1; + s->depth[new] = 0; + s->opt_len--; if (stree) s->static_len -= stree[new].Len; + /* new is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void ct_stored_block(s, buf, stored_len, eof) + deflate_state *s; + char *buf; /* input block */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ + s->compressed_len = (s->compressed_len + 3 + 7) & ~7L; + s->compressed_len += (stored_len + 4) << 3; + + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. This function + * returns the total compressed length for the file so far. + */ +ulg ct_flush_block(s, buf, stored_len, eof) + deflate_state *s; + char *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Check if the file is ascii or binary */ + if (s->data_type == UNKNOWN) set_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute first the block length in bytes */ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + /* If compression failed and this is the first and last block, + * and if the .zip file can be seeked (to rewrite the local header), + * the whole file is transformed into a stored file: + */ +#ifdef STORED_FILE_OK +# ifdef FORCE_STORED_FILE + if (eof && compressed_len == 0L) { /* force stored file */ +# else + if (stored_len <= opt_lenb && eof && s->compressed_len==0L && seekable()) { +# endif + /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */ + if (buf == (char*)0) error ("block vanished"); + + copy_block(buf, (unsigned)stored_len, 0); /* without header */ + s->compressed_len = stored_len << 3; + s->method = STORED; + } else +#endif /* STORED_FILE_OK */ + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + ct_stored_block(s, buf, stored_len, eof); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+eof, 3); + compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); + s->compressed_len += 3 + s->static_len; + } else { + send_bits(s, (DYN_TREES<<1)+eof, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); + s->compressed_len += 3 + s->opt_len; + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + init_block(s); + + if (eof) { + bi_windup(s); + s->compressed_len += 7; /* align on byte boundary */ + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*eof)); + + return s->compressed_len >> 3; +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int ct_tally (s, dist, lc) + deflate_state *s; + int dist; /* distance of matched string */ + int lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "ct_tally: bad match"); + + s->dyn_ltree[length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + + /* Try to guess if it is profitable to stop the current block here */ + if (s->level > 2 && (s->last_lit & 0xfff) == 0) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)s->strstart - s->block_start; + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + ct_data *ltree; /* literal tree */ + ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); +} + +/* =========================================================================== + * Set the data type to ASCII or BINARY, using a crude approximation: + * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. + * IN assertion: the fields freq of dyn_ltree are set and the total of all + * frequencies does not exceed 64K (to fit in an int on 16 bit machines). + */ +local void set_data_type(s) + deflate_state *s; +{ + int n = 0; + unsigned ascii_freq = 0; + unsigned bin_freq = 0; + while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; + while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; + while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; + s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? BINARY : ASCII); +} + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ +#ifdef DEBUG + Tracev((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; +#endif + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (value << s->bi_valid); + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= value << s->bi_valid; + s->bi_valid += length; + } +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Write out any remaining bits in an incomplete byte. + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) + deflate_state *s; + char *buf; /* the input data */ + unsigned len; /* its length */ + int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG + s->bits_sent += (ulg)len<<3; +#endif + while (len--) { + put_byte(s, *buf++); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/uncompr.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,58 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* $Id: uncompr.c,v 1.1.1.1 1997/12/06 05:41:38 darius Exp $ */ + +#include "zlib.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ +int uncompress (dest, destLen, source, sourceLen) + Byte *dest; + uLong *destLen; + Byte *source; + uLong sourceLen; +{ + z_stream stream; + int err; + + stream.next_in = source; + stream.avail_in = (uInt)sourceLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + + err = inflateInit(&stream); + if (err != Z_OK) return err; + + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + inflateEnd(&stream); + return err; + } + *destLen = stream.total_out; + + err = inflateEnd(&stream); + return err; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/zconf.h Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,90 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* $Id: zconf.h,v 1.1.1.1 1997/12/06 05:41:38 darius Exp $ */ + +#ifndef _ZCONF_H +#define _ZCONF_H + +/* + The library does not install any signal handler. It is recommended to + add at least a handler for SIGSEGV when decompressing; the library checks + the consistency of the input data whenever possible but may go nuts + for some forms of corrupted input. + */ + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#if defined(_GNUC__) && !defined(__32BIT__) +# define __32BIT__ +#endif +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if defined(MSDOS) && !defined(__32BIT__) +# define MAXSEG_64K +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(__STDC__)) +# define STDC +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2 */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + 1 << (windowBits+2) + 1 << (memLevel+9) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef __P /* function prototypes */ +# ifdef STDC +# define __P(args) args +# else +# define __P(args) () +# endif +#endif + +#ifndef Byte + typedef unsigned char Byte; /* 8 bits */ +#endif +#ifndef uInt + typedef unsigned int uInt; /* 16 bits or more */ +#endif +#ifndef uLong + typedef unsigned long uLong; /* 32 bits or more */ +#endif +#ifndef voidp +# ifdef STDC + typedef void *voidp; +# else + typedef Byte *voidp; +# endif +#endif + +#endif /* _ZCONF_H */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/zlib.h Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,615 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 0.92 May 3rd, 1995. + + Copyright (C) 1995 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + gzip@prep.ai.mit.edu madler@cco.caltech.edu + */ + +#ifndef _ZLIB_H +#define _ZLIB_H + +#include "zconf.h" + +#define ZLIB_VERSION "0.92" + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms may be added later and will have the same + stream interface. + + For compression the application must provide the output buffer and + may optionally provide the input buffer for optimization. For decompression, + the application must provide the input buffer and may optionally provide + the output buffer for optimization. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. +*/ + +typedef voidp (*alloc_func) __P((voidp opaque, uInt items, uInt size)); +typedef void (*free_func) __P((voidp opaque, voidp address)); + +struct internal_state; + +typedef struct z_stream_s { + Byte *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Byte *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidp opaque; /* private data object passed to zalloc and zfree */ + + Byte data_type; /* best guess about the data type: ascii or binary */ + +} z_stream; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_FULL_FLUSH 2 +#define Z_FINISH 4 +/* See deflate() below for the usage of these constants */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +/* error codes for the compression/decompression functions */ + +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_DEFAULT_STRATEGY 0 + +#define Z_BINARY 0 +#define Z_ASCII 1 +#define Z_UNKNOWN 2 +/* Used to set the data_type field */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +extern char *zlib_version; +/* The application can compare zlib_version and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + */ + + /* basic functions */ + +extern int deflateInit __P((z_stream *strm, int level)); +/* + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 1 and 9: + 1 gives best speed, 9 gives best compression. Z_DEFAULT_COMPRESSION requests + a default compromise between speed and compression (currently equivalent + to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level. + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +extern int deflate __P((z_stream *strm, int flush)); +/* + Performs one or both of the following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). + + If the parameter flush is set to Z_PARTIAL_FLUSH, the current compression + block is terminated and flushed to the output buffer so that the + decompressor can get all input data available so far. For method 9, a future + variant on method 8, the current block will be flushed but not terminated. + If flush is set to Z_FULL_FLUSH, the compression block is terminated, a + special marker is output and the compression dictionary is discarded; this + is useful to allow the decompressor to synchronize if one compressed block + has been damaged (see inflateSync below). Flushing degrades compression and + so should be used only when necessary. Using Z_FULL_FLUSH too often can + seriously degrade the compression. + + If the parameter flush is set to Z_FINISH, all pending input is processed, + all pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + 0.1% larger than avail_in plus 12 bytes. If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() may update data_type if it can make a good guess about + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible. +*/ + + +extern int deflateEnd __P((z_stream *strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent. In the error case, msg may be set + but then points to a static string (which must not be deallocated). +*/ + + +extern int inflateInit __P((z_stream *strm)); +/* + Initializes the internal stream state for decompression. The fields + zalloc and zfree must be initialized before by the caller. If zalloc and + zfree are set to Z_NULL, deflateInit updates them to use default allocation + functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory. msg is set to null if there is no error message. + inflateInit does not perform any decompression: this will be done by + inflate(). +*/ + + +extern int inflate __P((z_stream *strm, int flush)); +/* + Performs one or both of the following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() always provides as much output as possible + (until no more input data or no more space in the output buffer). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). + + If the parameter flush is set to Z_PARTIAL_FLUSH, inflate flushes as much + output as possible to the output buffer. The flushing behavior of inflate is + not specified for values of the flush parameter other than Z_PARTIAL_FLUSH + and Z_FINISH, but the current implementation actually flushes as much output + as possible anyway. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. + + inflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if the end of the + compressed data has been reached and all uncompressed output has been + produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if + the stream structure was inconsistent (for example if next_in or next_out + was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no + progress is possible or if there was not enough room in the output buffer + when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then + call inflateSync to look for a good compression block. +*/ + + +extern int inflateEnd __P((z_stream *strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +extern int deflateInit2 __P((z_stream *strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); +/* + This is another version of deflateInit with more compression options. The + fields next_in, zalloc and zfree must be initialized before by the caller. + + The method parameter is the compression method. It must be 8 in this + version of the library. (Method 9 will allow a 64K history buffer and + partial block flushes.) + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library (the value 16 will be allowed for method 9). Larger + values of this parameter result in better compression at the expense of + memory usage. The default value is 15 if deflateInit is used instead. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use + the value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data + produced by a filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman + encoding only (no string match). Filtered data consists mostly of small + values with a somewhat random distribution. In this case, the + compression algorithm is tuned to compress them better. The strategy + parameter only affects the compression ratio but not the correctness of + the compressed output even if it is not set appropriately. + + If next_in is not null, the library will use this buffer to hold also + some history information; the buffer must either hold the entire input + data, or have at least 1<<(windowBits+1) bytes and be writable. If next_in + is null, the library will allocate its own history buffer (and leave next_in + null). next_out need not be provided here but must be provided by the + application for the next call of deflate(). + + If the history buffer is provided by the application, next_in must + must never be changed by the application since the compressor maintains + information inside this buffer from call to call; the application + must provide more input only by increasing avail_in. next_in is always + reset by the library in this case. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was + not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as + an invalid method). msg is set to null if there is no error message. + deflateInit2 does not perform any compression: this will be done by + deflate(). +*/ + +extern int deflateCopy __P((z_stream *dest, + z_stream *source)); +/* + Sets the destination stream as a complete copy of the source stream. If + the source stream is using an application-supplied history buffer, a new + buffer is allocated for the destination stream. The compressed output + buffer is always application-supplied. It's the responsibility of the + application to provide the correct values of next_out and avail_out for the + next call of deflate. + + This function is useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +extern int deflateReset __P((z_stream *strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +extern int inflateInit2 __P((z_stream *strm, + int windowBits)); +/* + This is another version of inflateInit with more compression options. The + fields next_out, zalloc and zfree must be initialized before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library (the value 16 will be allowed soon). The + default value is 15 if inflateInit is used instead. If a compressed stream + with a larger window size is given as input, inflate() will return with + the error code Z_DATA_ERROR instead of trying to allocate a larger window. + + If next_out is not null, the library will use this buffer for the history + buffer; the buffer must either be large enough to hold the entire output + data, or have at least 1<<windowBits bytes. If next_out is null, the + library will allocate its own buffer (and leave next_out null). next_in + need not be provided here but must be provided by the application for the + next call of inflate(). + + If the history buffer is provided by the application, next_out must + never be changed by the application since the decompressor maintains + history information inside this buffer from call to call; the application + can only reset next_out to the beginning of the history buffer when + avail_out is zero and all output has been consumed. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was + not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as + windowBits < 8). msg is set to null if there is no error message. + inflateInit2 does not perform any compression: this will be done by + inflate(). +*/ + +extern int inflateSync __P((z_stream *strm)); +/* + Skips invalid compressed data until the special marker (see deflate() + above) can be found, or until all available input is skipped. No output + is provided. + + inflateSync returns Z_OK if the special marker has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no marker has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +extern int inflateReset __P((z_stream *strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level, window size, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +extern int compress __P((Byte *dest, uLong *destLen, + Byte *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least 0.1% larger than + sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +extern int uncompress __P((Byte *dest, uLong *destLen, + Byte *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ + + +typedef voidp gzFile; + +extern gzFile gzopen __P((char *path, char *mode)); +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb"). gzopen can also be used to read a file + which is not in gzip format; in this case gzread will directly read from + the file without decompression. + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). +*/ + +extern gzFile gzdopen __P((int fd, char *mode)); +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, or pipe. + The mode parameter is as in fopen ("rb" or "wb"). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +extern int gzread __P((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +extern int gzwrite __P((gzFile file, voidp buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +extern int gzflush __P((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +extern int gzclose __P((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +extern char* gzerror __P((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +*/ + +extern uLong adler32 __P((uLong adler, Byte *buf, uInt len)); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +extern uLong crc32 __P((uLong crc, Byte *buf, uInt len)); +/* + Update a running crc with the bytes buf[0..len-1] and return the updated + crc. If buf is NULL, this function returns the required initial value + for the crc. Pre- and post-conditioning (one's complement) is performed + within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +#ifndef _Z_UTIL_H + struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +#endif /* _ZLIB_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/zutil.c Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,178 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* $Id: zutil.c,v 1.1.1.1 1997/12/06 05:41:38 darius Exp $ */ + +#include <stdio.h> + +#include "zutil.h" + +#ifndef __GO32__ +extern void exit __P((int)); +#endif + +char *zlib_version = ZLIB_VERSION; + +char *z_errmsg[] = { +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +""}; + + +void z_error (m) + char *m; +{ + fprintf(stderr, "%s\n", m); + exit(1); +} + +#ifndef HAVE_MEMCPY + +void zmemcpy(dest, source, len) + Byte* dest; + Byte* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +void zmemzero(dest, len) + Byte* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + +#if defined(__TURBOC__) && !defined(__SMALL__) + +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidp org_ptr; + voidp new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidp zcalloc (voidp opaque, unsigned items, unsigned size) +{ + voidp buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + if (bsize < 65536L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void zcfree (voidp opaque, voidp ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + z_error("zcfree: ptr not found"); +} +#endif /* __TURBOC__ */ + +#if defined(M_I86CM) || defined(M_I86LM) /* MSC compact or large model */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER < 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidp zcalloc (voidp opaque, unsigned items, unsigned size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void zcfree (voidp opaque, voidp ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* defined(M_I86CM) || defined(M_I86LM) */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef __GO32__ +extern voidp calloc __P((uInt items, uInt size)); +extern void free __P((voidp ptr)); +#endif + +voidp zcalloc (opaque, items, size) + voidp opaque; + unsigned items; + unsigned size; +{ + return calloc(items, size); +} + +void zcfree (opaque, ptr) + voidp opaque; + voidp ptr; +{ + free(ptr); +} + +#endif /* MY_ZCALLOC */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/zlib/zutil.h Sat Dec 06 05:41:29 1997 +0000 @@ -0,0 +1,183 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* $Id: zutil.h,v 1.1.1.1 1997/12/06 05:41:38 darius Exp $ */ + +#ifndef _Z_UTIL_H +#define _Z_UTIL_H + +#include "zlib.h" + +#ifdef __GNUC__ +# define INLINE inline +#else +# define INLINE +#endif + +#ifdef MSDOS +# include <stddef.h> +# include <errno.h> +#else + extern int errno; +#endif +#ifdef STDC +# include <string.h> +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef unsigned short ush; +typedef unsigned long ulg; + +extern char *z_errmsg[]; /* indexed by 1-zlib_error */ + +#define ERR_RETURN(strm,err) return (strm->msg=z_errmsg[1-err], err) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#define DEFLATED 8 + +#define DEF_WBITS 15 +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + + /* target dependencies */ + +#ifdef MSDOS +# define OS_CODE 0x00 +# ifdef __TURBOC__ +# include <alloc.h> +# else /* MSC */ +# include <malloc.h> +# endif +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +#endif + +#ifdef WIN32 /* Windows NT */ +# define OS_CODE 0x0b +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define FOPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#ifdef MACOS +# define OS_CODE 0x07 +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0F +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + + /* Common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef FOPEN +# define FOPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#ifdef HAVE_STRERROR + extern char *strerror __P((int)); +# define zstrerror(errnum) strerror(errnum) +#else +# define zstrerror(errnum) "" +#endif + +#if defined(pyr) && !defined(NO_MEMCPY) +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# define zmemcpy memcpy +# define zmemzero(dest, len) memset(dest, 0, len) +#else + extern void zmemcpy __P((Byte* dest, Byte* source, uInt len)); + extern void zmemzero __P((Byte* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include <stdio.h> +# ifndef verbose +# define verbose 0 +# endif +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) fprintf x +# define Tracev(x) {if (verbose) fprintf x ;} +# define Tracevv(x) {if (verbose>1) fprintf x ;} +# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} +# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +typedef uLong (*check_func) __P((uLong check, Byte *buf, uInt len)); + +extern void z_error __P((char *m)); + +voidp zcalloc __P((voidp opaque, unsigned items, unsigned size)); +void zcfree __P((voidp opaque, voidp ptr)); + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidp)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* _Z_UTIL_H */