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