1 #include <time.h>
2 #include <sys/time.h>
3 #include <unistd.h>
4
5
6 #include "globals.h"
7 #include "sound.h"
8 #include "netvariables.h"
9 #include "netdata.h"
10 #include "network.h"
11 #include "thread.h"
12 #include "status.h"
13 #include "object.h"
14 #include "ship.h"
15 #include "screen.h"
16 #include "key.h"
17
18
19 struct timeval LastTime;
20 struct timeval UpdateTime;
21
22
RunFrame()23 void RunFrame()
24 {
25 int i, j, RunTime;
26 struct timezone tz;
27 struct timeval now;
28 float AgeTime;
29
30 // Play the boom sounds
31 NextBoom--;
32 if (NextBoom == 0) {
33 if (BoomPhase) {
34 playsound(Boom1);
35 BoomPhase = 0;
36 } else {
37 playsound(Boom2);
38 BoomPhase = 1;
39 }
40 NextBoom = BoomDelay;
41 }
42
43 // Update looping sounds
44 if (Ships[myShip]) {
45 if (!Ships[myShip]->Alive || !Ships[myShip]->Shield) {
46 if (ShieldSoundNum!=-1) {
47 stopsoundinloop(ShieldSoundNum);
48 ShieldSoundNum=-1;
49 }
50 } else {
51 if (KeyValues.ShieldKey && ShieldSoundNum==-1) {
52 ShieldSoundNum=playsoundinloop(ShieldOnSound);
53 }
54 }
55 if (!Ships[myShip]->Alive) {
56 if (ThrustSoundNum!=-1) {
57 stopsoundinloop(ThrustSoundNum);
58 ThrustSoundNum=-1;
59 }
60 } else {
61 if (KeyValues.zForwardKey && ThrustSoundNum==-1) {
62 ThrustSoundNum=playsoundinloop(ThrustSound);
63 }
64 }
65 } else {
66 if (ShieldSoundNum!=-1) {
67 stopsoundinloop(ShieldSoundNum);
68 ShieldSoundNum=-1;
69 }
70 if (ThrustSoundNum!=-1) {
71 stopsoundinloop(ThrustSoundNum);
72 ThrustSoundNum=-1;
73 }
74 }
75
76 // Display object and ship sprites
77 gettimeofday(&now, &tz);
78
79 // Send out update every second
80 if (now.tv_sec!=UpdateTime.tv_sec) {
81 SendUpdate();
82 memcpy(&UpdateTime, &now, sizeof(struct timeval));
83 }
84
85 if (Ships[myShip]) {
86 DrawStatus();
87 for (i=0; i<MAX_PLAYERS; i++) {
88 if (Ships[i] && i!=myShip && Ships[i]->Alive) {
89 DrawObject(Ships[i]);
90 }
91 }
92
93 InitTransparencyQueue();
94
95 for (i=0; i<MAX_OBJECTS; i++) {
96 if (Objects[i]) {
97 if (Objects[i]->Type==ASTEROID_TYPE || Objects[i]->Type==SHOT_TYPE || Objects[i]->Type==NUKE_TYPE) {
98 DrawObject(Objects[i]);
99 } else if (Objects[i]->Type==SHIELD_POWERUP_TYPE || Objects[i]->Type==ARMOR_POWERUP_TYPE ||
100 Objects[i]->Type==NUKE_POWERUP_TYPE || Objects[i]->Type==HYPERWARP_POWERUP_TYPE) {
101 DrawPowerup(Objects[i]);
102 QueueTransparency(&Objects[i]->Position, i, 3);
103 } else if (Objects[i]->Type==NUKE_EXPLOSION_TYPE) {
104 QueueTransparency(&Objects[i]->Position, i, 4);
105 }
106 }
107 }
108
109 EnableTransparency();
110
111 for (i=0; i<MAX_OBJECTS; i++) {
112 if (Objects[i]) {
113 if ((Objects[i]->Type==EXPLOSION_TYPE || Objects[i]->Type==BIG_EXPLOSION_TYPE) && Objects[i]->Age < 1.0) {
114 QueueTransparency(&Objects[i]->Position, i, 1);
115 }
116 }
117 }
118
119 for (i=0; i<MAX_PLAYERS; i++) {
120 if (Ships[i] && i!=myShip && Ships[i]->ShieldOn) {
121 QueueTransparency(&Ships[i]->Position, i, 2);
122 }
123 }
124
125 DrawTransparencies();
126
127 DrawCrosshairs();
128
129 DrawTest();
130
131 DisableTransparency();
132 }
133
134 #ifdef DEBUG
135 printf("Game Thread Sleeping\n");
136 #endif
137 pthread_mutex_unlock(&ClientLock);
138 /*
139 We need to sleep to accomplish the following:
140
141 Make sure that each frame update takes the same amount of time
142 Handle the sound correctly
143 Allow other threads to update the data
144 Not be too much of a CPU hog
145 */
146 RunTime=(now.tv_sec-LastTime.tv_sec)*1000000+(now.tv_usec-LastTime.tv_usec);
147 LastTime.tv_sec=now.tv_sec;
148 LastTime.tv_usec=now.tv_usec;
149
150 // The Cygwin usleep and gettimeofday functions appear to be broken,
151 // so this is a workaround
152 #ifndef CYGWIN
153 if (RunTime<FRAME_DELAY*1000 && RunTime>0) {
154 usleep(FRAME_DELAY*1000-RunTime);
155 AgeTime=0.15;
156 } else {
157 AgeTime=0.15*((float)RunTime/(float)(FRAME_DELAY*1000));
158 }
159 #else
160 usleep(FRAME_DELAY*1000);
161 AgeTime=0.15;
162 #endif
163 for (i=0; i<MAX_OBJECTS; i++) {
164 if (Objects[i]) {
165 if (Objects[i]->Type==EXPLOSION_TYPE) {
166 Objects[i]->Age+=AgeTime;
167 } else if (Objects[i]->Type==BIG_EXPLOSION_TYPE) {
168 Objects[i]->Age+=AgeTime/6.0;
169 }
170 }
171 }
172
173 gettimeofday(&LastTime, &tz);
174
175 pthread_mutex_lock(&ClientLock);
176 #ifdef DEBUG
177 printf("Game Thread Awake\n");
178 #endif
179 }
180