rnd-19990122-1
[rocksndiamonds.git] / src / tape.c
1 /***********************************************************
2 *  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
3 *----------------------------------------------------------*
4 *  (c) 1995-98 Artsoft Entertainment                       *
5 *              Holger Schemel                              *
6 *              Oststrasse 11a                              *
7 *              33604 Bielefeld                             *
8 *              phone: ++49 +521 290471                     *
9 *              email: aeglos@valinor.owl.de                *
10 *----------------------------------------------------------*
11 *  tape.c                                                  *
12 ***********************************************************/
13
14 #include "tape.h"
15 #include "misc.h"
16 #include "game.h"
17 #include "buttons.h"
18
19 void TapeStartRecording()
20 {
21   time_t zeit1 = time(NULL);
22   struct tm *zeit2 = localtime(&zeit1);
23   int i;
24
25   if (!TAPE_IS_STOPPED(tape))
26     TapeStop();
27
28   tape.level_nr = level_nr;
29   tape.length = 0;
30   tape.counter = 0;
31   tape.pos[tape.counter].delay = 0;
32   tape.recording = TRUE;
33   tape.playing = FALSE;
34   tape.pausing = FALSE;
35   tape.changed = TRUE;
36   tape.date = 10000*(zeit2->tm_year%100) + 100*zeit2->tm_mon + zeit2->tm_mday;
37   tape.random_seed = InitRND(NEW_RANDOMIZE);
38
39   for(i=0; i<MAX_PLAYERS; i++)
40     tape.player_participates[i] = FALSE;
41
42   DrawVideoDisplay(VIDEO_STATE_REC_ON, 0);
43   DrawVideoDisplay(VIDEO_STATE_DATE_ON, tape.date);
44   DrawVideoDisplay(VIDEO_STATE_TIME_ON, 0);
45 }
46
47 void TapeStopRecording()
48 {
49   int i;
50
51   if (!tape.recording)
52     return;
53
54   for(i=0; i<MAX_PLAYERS; i++)
55     tape.pos[tape.counter].action[i] = 0;
56
57   tape.counter++;
58   tape.length = tape.counter;
59   tape.length_seconds = GetTapeLength();
60   tape.recording = FALSE;
61   tape.pausing = FALSE;
62   DrawVideoDisplay(VIDEO_STATE_REC_OFF, 0);
63 }
64
65 void TapeRecordAction(byte joy[MAX_PLAYERS])
66 {
67   int i;
68
69   if (!tape.recording || tape.pausing)
70     return;
71
72   if (tape.counter >= MAX_TAPELEN-1)
73   {
74     TapeStopRecording();
75     return;
76   }
77
78   for(i=0; i<MAX_PLAYERS; i++)
79     tape.pos[tape.counter].action[i] = joy[i];
80
81   tape.counter++;
82   tape.pos[tape.counter].delay = 0;
83 }
84
85 void TapeRecordDelay()
86 {
87   int i;
88
89   if (!tape.recording || tape.pausing)
90     return;
91
92   if (tape.counter >= MAX_TAPELEN)
93   {
94     TapeStopRecording();
95     return;
96   }
97
98   tape.pos[tape.counter].delay++;
99
100   if (tape.pos[tape.counter].delay >= 255)
101   {
102     for(i=0; i<MAX_PLAYERS; i++)
103       tape.pos[tape.counter].action[i] = 0;
104
105     tape.counter++;
106     tape.pos[tape.counter].delay = 0;
107   }
108 }
109
110 void TapeTogglePause()
111 {
112   unsigned long state;
113
114   if (!tape.recording && !tape.playing)
115     return;
116
117   tape.pausing = !tape.pausing;
118   tape.fast_forward = FALSE;
119   tape.pause_before_death = FALSE;
120
121   state = (tape.pausing ? VIDEO_STATE_PAUSE_ON : VIDEO_STATE_PAUSE_OFF);
122   if (tape.playing)
123     state |= VIDEO_STATE_PBEND_OFF;
124
125   DrawVideoDisplay(state, 0);
126 }
127
128 void TapeStartPlaying()
129 {
130   if (TAPE_IS_EMPTY(tape))
131     return;
132
133   if (!TAPE_IS_STOPPED(tape))
134     TapeStop();
135
136   tape.counter = 0;
137   tape.delay_played = 0;
138   tape.pause_before_death = FALSE;
139   tape.recording = FALSE;
140   tape.playing = TRUE;
141   tape.pausing = FALSE;
142   tape.fast_forward = FALSE;
143   InitRND(tape.random_seed);
144
145   DrawVideoDisplay(VIDEO_STATE_PLAY_ON, 0);
146   DrawVideoDisplay(VIDEO_STATE_DATE_ON, tape.date);
147   DrawVideoDisplay(VIDEO_STATE_TIME_ON, 0);
148 }
149
150 void TapeStopPlaying()
151 {
152   if (!tape.playing)
153     return;
154
155   tape.playing = FALSE;
156   tape.pausing = FALSE;
157   DrawVideoDisplay(VIDEO_STATE_PLAY_OFF, 0);
158 }
159
160 byte *TapePlayAction()
161 {
162   static byte joy[MAX_PLAYERS];
163   int i;
164
165   if (!tape.playing || tape.pausing)
166     return(NULL);
167
168   if (tape.counter >= tape.length)
169   {
170     TapeStop();
171     return(NULL);
172   }
173
174   if (tape.delay_played == tape.pos[tape.counter].delay)
175   {
176     tape.delay_played = 0;
177     tape.counter++;
178
179     for(i=0; i<MAX_PLAYERS; i++)
180       joy[i] = tape.pos[tape.counter-1].action[i];
181   }
182   else
183   {
184     for(i=0; i<MAX_PLAYERS; i++)
185       joy[i] = 0;
186   }
187
188   return(joy);
189 }
190
191 boolean TapePlayDelay()
192 {
193   if (!tape.playing || tape.pausing)
194     return(FALSE);
195
196   if (tape.pause_before_death)  /* STOP 10s BEFORE PLAYER GETS KILLED... */
197   {
198     if (!(FrameCounter % 20))
199     {
200       if ((FrameCounter / 20) % 2)
201         DrawVideoDisplay(VIDEO_STATE_PBEND_ON, VIDEO_DISPLAY_LABEL_ONLY);
202       else
203         DrawVideoDisplay(VIDEO_STATE_PBEND_OFF, VIDEO_DISPLAY_LABEL_ONLY);
204     }
205
206     if (TimePlayed > tape.length_seconds - PAUSE_SECONDS_BEFORE_DEATH)
207     {
208       TapeTogglePause();
209       return(FALSE);
210     }
211   }
212
213   if (tape.counter >= tape.length)
214   {
215     TapeStop();
216     return(TRUE);
217   }
218
219   if (tape.delay_played < tape.pos[tape.counter].delay)
220   {
221     tape.delay_played++;
222     return(TRUE);
223   }
224   else
225     return(FALSE);
226 }
227
228 void TapeStop()
229 {
230   TapeStopRecording();
231   TapeStopPlaying();
232
233   DrawVideoDisplay(VIDEO_STATE_PAUSE_OFF,0);
234   if (tape.date && tape.length)
235   {
236     DrawVideoDisplay(VIDEO_STATE_DATE_ON, tape.date);
237     DrawVideoDisplay(VIDEO_STATE_TIME_ON, tape.length_seconds);
238   }
239 }
240
241 void TapeErase()
242 {
243   tape.length = 0;
244 }
245
246 unsigned int GetTapeLength()
247 {
248   unsigned int tape_length = 0;
249   int i;
250
251   if (TAPE_IS_EMPTY(tape))
252     return(0);
253
254   for(i=0;i<tape.length;i++)
255     tape_length += tape.pos[i].delay;
256
257   return(tape_length * GAME_FRAME_DELAY / 1000);
258 }