1 #include "stdio.h"
2 #include "stdlib.h"
3 
4 #include "types.h"
5 #include "util.h"
6 
7 #include "Cable.h"
8 #include "Computer.h"
9 #include "Game.h"
10 #include "Network.h"
11 #include "OS.h"
12 #include "Spark.h"
13 #include "UI.h"
14 
15 struct Cable {
16 	int c1, c2;		/* computers connected */
17 	int x1, y1, x2, y2;	/* endpoints of line representing cable */
18 	int x, y;		/* current location of spark */
19 	float fx, fy;		/* needed for line drawing */
20 	int delay;		/* how much time until spark leaves */
21 	int active;		/* is spark moving and from which end */
22 	int index;
23 };
24 
25 #define SWAP(x, y) do {int _t; _t = x; x = y; y = _t;} while(0)
26 
27 static void
reverse(Cable * cable)28 reverse(Cable *cable) {
29 	SWAP(cable->c1, cable->c2);
30 	SWAP(cable->x1, cable->x2);
31 	SWAP(cable->y1, cable->y2);
32 }
33 
34 void
Cable_setup(Cable ** cablep)35 Cable_setup(Cable **cablep) {
36 	Cable *cable;
37 	Computer *comp1, *comp2;
38 	int cwidth, cheight;
39 
40 	cable = xalloc(sizeof *cable);
41 
42 	cable->c1 = RAND(0, Network_num_computers() - 1);
43 	do {
44 		cable->c2 = RAND(0, Network_num_computers() - 1);
45 	} while (cable->c2 == cable->c1);
46 	cable->active = 0;
47 	cable->index = 0;
48 	cable->delay = SPARK_DELAY(Game_level());
49 
50 	comp1 = Network_get_computer(cable->c1);
51 	comp2 = Network_get_computer(cable->c2);
52 	cwidth = Computer_width();
53 	cheight = Computer_height();
54 	cable->x1 = comp1->x + cwidth/3;
55 	cable->x2 = comp2->x + cwidth/3;
56 	cable->y1 = comp1->y + cheight/2;
57 	cable->y2 = comp2->y + cheight/2;
58 
59 	*cablep = cable;
60 }
61 
62 
63 void
Cable_draw(Cable * cable)64 Cable_draw(Cable *cable) {
65 	UI_draw_line(cable->x1, cable->y1, cable->x2, cable->y2);
66 	if (cable->active) {
67 		int rx = cable->x - Spark_width()/2;
68 		int ry = cable->y - Spark_height()/2;
69 		Spark_draw(rx, ry, cable->index);
70 	}
71 }
72 
73 void
Cable_update(Cable * cable)74 Cable_update(Cable *cable) {
75 	Computer *comp1, *comp2;
76 	comp1 = Network_get_computer(cable->c1);
77 	comp2 = Network_get_computer(cable->c2);
78 
79 	if (cable->active) {
80 		if ((comp1->os == OS_WINGDOWS) == (comp2->os == OS_WINGDOWS))
81 			cable->active = 0;
82 		else if (comp1->os == OS_WINGDOWS || comp2->os == OS_WINGDOWS) {
83 			int xdist, ydist;
84 			float sx, sy;
85 
86 			if (comp2->os == OS_WINGDOWS)
87 				reverse(cable);
88 
89 			xdist = cable->x2 - cable->x;
90 			ydist = cable->y2 - cable->y;
91 
92 			sx = xdist >= 0 ? 1.0 : -1.0;
93 			sy = ydist >= 0 ? 1.0 : -1.0;
94 			xdist = abs(xdist);
95 			ydist = abs(ydist);
96 			if (xdist == 0 && ydist == 0) {
97 				if (!comp2->busy) {
98 					int counter;
99 					if (comp2->os == OS_OFF)
100 						counter = NETWORK_COUNTER_OFF;
101 					else
102 						counter = NETWORK_COUNTER_BASE;
103 					Network_inc_counter(counter, -1);
104 					Network_inc_counter(NETWORK_COUNTER_WIN,
105 							    1);
106 					comp2->os = OS_WINGDOWS;
107 				}
108 				cable->active = 0;
109 			}
110 			else if (MAX(xdist, ydist) < SPARK_SPEED) {
111 				cable->x = cable->x2;
112 				cable->y = cable->y2;
113 			}
114 			else {
115 				cable->fx+=(xdist*SPARK_SPEED*sx)/(xdist+ydist);
116 				cable->fy+=(ydist*SPARK_SPEED*sy)/(xdist+ydist);
117 				cable->x = (int)cable->fx;
118 				cable->y = (int)cable->fy;
119 			}
120 			cable->index = 1 - cable->index;
121 		}
122 	}
123 	else {
124 		if ((comp1->os == OS_WINGDOWS) == (comp2->os == OS_WINGDOWS))
125 			;
126 		else if (comp1->os == OS_WINGDOWS || comp2->os == OS_WINGDOWS) {
127 			cable->active = 1;
128 			cable->delay = SPARK_DELAY(Game_level());
129 			if (comp2->os == OS_WINGDOWS)
130 				reverse(cable);
131 			cable->x = cable->x1;
132 			cable->fx = cable->x1;
133 			cable->y = cable->y1;
134 			cable->fy = cable->y1;
135 		}
136 	}
137 }
138 
139 int
Cable_onspark(Cable * cable,int locx,int locy)140 Cable_onspark(Cable *cable, int locx, int locy) {
141 	if (!cable->active)
142 		return 0;
143 	return (abs(locx - cable->x) < Spark_width() &&
144 		abs(locy - cable->y) < Spark_height());
145 }
146 
147 void
Cable_reset(Cable * cable)148 Cable_reset(Cable *cable) {
149 	cable->active = 0;
150 	cable->delay = SPARK_DELAY(Game_level());
151 }
152