Mercurial > ~darius > hgwebdir.cgi > paradise_client
diff redraw.c @ 3:5a977ccbc7a9 default tip
Empty changelog
author | darius |
---|---|
date | Sat, 06 Dec 1997 05:41:29 +0000 |
parents | |
children |
line wrap: on
line diff
--- /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