1 /***********************************************************
2 * Rocks'n'Diamonds -- McDuffin Strikes Back! *
3 *----------------------------------------------------------*
4 * (c) 1995-98 Artsoft Entertainment *
8 * phone: ++49 +521 290471 *
9 * email: aeglos@valinor.owl.de *
10 *----------------------------------------------------------*
12 ***********************************************************/
22 /* tape button identifiers */
23 #define TAPE_CTRL_ID_EJECT 0
24 #define TAPE_CTRL_ID_STOP 1
25 #define TAPE_CTRL_ID_PAUSE 2
26 #define TAPE_CTRL_ID_RECORD 3
27 #define TAPE_CTRL_ID_PLAY 4
29 #define NUM_TAPE_BUTTONS 5
31 /* forward declaration for internal use */
32 static void HandleTapeButtons(struct GadgetInfo *);
34 static struct GadgetInfo *tape_gadget[NUM_TAPE_BUTTONS];
36 void TapeStartRecording()
38 time_t zeit1 = time(NULL);
39 struct tm *zeit2 = localtime(&zeit1);
42 if (!TAPE_IS_STOPPED(tape))
45 tape.level_nr = level_nr;
48 tape.pos[tape.counter].delay = 0;
49 tape.recording = TRUE;
53 tape.date = 10000*(zeit2->tm_year%100) + 100*zeit2->tm_mon + zeit2->tm_mday;
54 tape.random_seed = InitRND(NEW_RANDOMIZE);
56 for(i=0; i<MAX_PLAYERS; i++)
57 tape.player_participates[i] = FALSE;
59 DrawVideoDisplay(VIDEO_STATE_REC_ON, 0);
60 DrawVideoDisplay(VIDEO_STATE_DATE_ON, tape.date);
61 DrawVideoDisplay(VIDEO_STATE_TIME_ON, 0);
64 void TapeStopRecording()
71 for(i=0; i<MAX_PLAYERS; i++)
72 tape.pos[tape.counter].action[i] = 0;
75 tape.length = tape.counter;
76 tape.length_seconds = GetTapeLength();
77 tape.recording = FALSE;
79 DrawVideoDisplay(VIDEO_STATE_REC_OFF, 0);
82 void TapeRecordAction(byte joy[MAX_PLAYERS])
86 if (!tape.recording || tape.pausing)
89 if (tape.counter >= MAX_TAPELEN-1)
95 for(i=0; i<MAX_PLAYERS; i++)
96 tape.pos[tape.counter].action[i] = joy[i];
99 tape.pos[tape.counter].delay = 0;
102 void TapeRecordDelay()
106 if (!tape.recording || tape.pausing)
109 if (tape.counter >= MAX_TAPELEN)
115 tape.pos[tape.counter].delay++;
117 if (tape.pos[tape.counter].delay >= 255)
119 for(i=0; i<MAX_PLAYERS; i++)
120 tape.pos[tape.counter].action[i] = 0;
123 tape.pos[tape.counter].delay = 0;
127 void TapeTogglePause()
131 if (!tape.recording && !tape.playing)
134 tape.pausing = !tape.pausing;
135 tape.fast_forward = FALSE;
136 tape.pause_before_death = FALSE;
138 state = (tape.pausing ? VIDEO_STATE_PAUSE_ON : VIDEO_STATE_PAUSE_OFF);
140 state |= VIDEO_STATE_PBEND_OFF;
142 DrawVideoDisplay(state, 0);
145 void TapeStartPlaying()
147 if (TAPE_IS_EMPTY(tape))
150 if (!TAPE_IS_STOPPED(tape))
154 tape.delay_played = 0;
155 tape.pause_before_death = FALSE;
156 tape.recording = FALSE;
158 tape.pausing = FALSE;
159 tape.fast_forward = FALSE;
160 InitRND(tape.random_seed);
162 DrawVideoDisplay(VIDEO_STATE_PLAY_ON, 0);
163 DrawVideoDisplay(VIDEO_STATE_DATE_ON, tape.date);
164 DrawVideoDisplay(VIDEO_STATE_TIME_ON, 0);
167 void TapeStopPlaying()
172 tape.playing = FALSE;
173 tape.pausing = FALSE;
174 DrawVideoDisplay(VIDEO_STATE_PLAY_OFF, 0);
177 byte *TapePlayAction()
179 static byte joy[MAX_PLAYERS];
182 if (!tape.playing || tape.pausing)
185 if (tape.counter >= tape.length)
191 if (tape.delay_played == tape.pos[tape.counter].delay)
193 tape.delay_played = 0;
196 for(i=0; i<MAX_PLAYERS; i++)
197 joy[i] = tape.pos[tape.counter-1].action[i];
201 for(i=0; i<MAX_PLAYERS; i++)
208 boolean TapePlayDelay()
210 if (!tape.playing || tape.pausing)
213 if (tape.pause_before_death) /* STOP 10s BEFORE PLAYER GETS KILLED... */
215 if (!(FrameCounter % 20))
217 if ((FrameCounter / 20) % 2)
218 DrawVideoDisplay(VIDEO_STATE_PBEND_ON, VIDEO_DISPLAY_LABEL_ONLY);
220 DrawVideoDisplay(VIDEO_STATE_PBEND_OFF, VIDEO_DISPLAY_LABEL_ONLY);
223 if (TimePlayed > tape.length_seconds - PAUSE_SECONDS_BEFORE_DEATH)
230 if (tape.counter >= tape.length)
236 if (tape.delay_played < tape.pos[tape.counter].delay)
250 DrawVideoDisplay(VIDEO_STATE_PAUSE_OFF,0);
251 if (tape.date && tape.length)
253 DrawVideoDisplay(VIDEO_STATE_DATE_ON, tape.date);
254 DrawVideoDisplay(VIDEO_STATE_TIME_ON, tape.length_seconds);
263 unsigned int GetTapeLength()
265 unsigned int tape_length = 0;
268 if (TAPE_IS_EMPTY(tape))
271 for(i=0;i<tape.length;i++)
272 tape_length += tape.pos[i].delay;
274 return(tape_length * GAME_FRAME_DELAY / 1000);
277 /* ---------- new tape button stuff ---------------------------------------- */
279 /* graphic position values for tape buttons */
280 #define TAPE_BUTTON_XSIZE 18
281 #define TAPE_BUTTON_YSIZE 18
282 #define TAPE_BUTTON_XPOS 5
283 #define TAPE_BUTTON_YPOS 77
285 #define TAPE_BUTTON_EJECT_XPOS (TAPE_BUTTON_XPOS + 0 * TAPE_BUTTON_XSIZE)
286 #define TAPE_BUTTON_STOP_XPOS (TAPE_BUTTON_XPOS + 1 * TAPE_BUTTON_XSIZE)
287 #define TAPE_BUTTON_PAUSE_XPOS (TAPE_BUTTON_XPOS + 2 * TAPE_BUTTON_XSIZE)
288 #define TAPE_BUTTON_RECORD_XPOS (TAPE_BUTTON_XPOS + 3 * TAPE_BUTTON_XSIZE)
289 #define TAPE_BUTTON_PLAY_XPOS (TAPE_BUTTON_XPOS + 4 * TAPE_BUTTON_XSIZE)
296 } tapebutton_info[NUM_TAPE_BUTTONS] =
299 TAPE_BUTTON_EJECT_XPOS, TAPE_BUTTON_YPOS,
304 TAPE_BUTTON_STOP_XPOS, TAPE_BUTTON_YPOS,
309 TAPE_BUTTON_PAUSE_XPOS, TAPE_BUTTON_YPOS,
314 TAPE_BUTTON_RECORD_XPOS, TAPE_BUTTON_YPOS,
319 TAPE_BUTTON_PLAY_XPOS, TAPE_BUTTON_YPOS,
325 void CreateTapeButtons()
329 for (i=0; i<NUM_TAPE_BUTTONS; i++)
331 Bitmap gd_bitmap = pix[PIX_DOOR];
332 struct GadgetInfo *gi;
333 int gd_xoffset, gd_yoffset;
334 int gd_x1, gd_x2, gd_y;
337 gd_xoffset = tapebutton_info[i].x;
338 gd_yoffset = tapebutton_info[i].y;
339 gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
340 gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
341 gd_y = DOOR_GFX_PAGEY2 + gd_yoffset;
343 gi = CreateGadget(GDI_CUSTOM_ID, id,
344 GDI_INFO_TEXT, tapebutton_info[i].infotext,
345 GDI_X, VX + gd_xoffset,
346 GDI_Y, VY + gd_yoffset,
347 GDI_WIDTH, TAPE_BUTTON_XSIZE,
348 GDI_HEIGHT, TAPE_BUTTON_YSIZE,
349 GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
350 GDI_STATE, GD_BUTTON_UNPRESSED,
351 GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
352 GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
353 GDI_EVENT_MASK, GD_EVENT_RELEASED,
354 GDI_CALLBACK_ACTION, HandleTapeButtons,
358 Error(ERR_EXIT, "cannot create gadget");
360 tape_gadget[id] = gi;
364 void MapTapeButtons()
368 for (i=0; i<NUM_TAPE_BUTTONS; i++)
369 MapGadget(tape_gadget[i]);
372 void UnmapTapeButtons()
376 for (i=0; i<NUM_TAPE_BUTTONS; i++)
377 UnmapGadget(tape_gadget[i]);
380 static void HandleTapeButtons(struct GadgetInfo *gi)
382 int id = gi->custom_id;
384 if (game_status != MAINMENU && game_status != PLAYING)
389 case TAPE_CTRL_ID_EJECT:
391 if (TAPE_IS_EMPTY(tape))
394 if (TAPE_IS_EMPTY(tape))
395 Request("No tape for this level !", REQ_CONFIRM);
400 SaveTape(tape.level_nr);
403 DrawCompleteVideoDisplay();
406 case TAPE_CTRL_ID_STOP:
410 case TAPE_CTRL_ID_PAUSE:
414 case TAPE_CTRL_ID_RECORD:
415 if (TAPE_IS_STOPPED(tape))
417 TapeStartRecording();
421 SendToServer_StartPlaying();
425 game_status = PLAYING;
429 else if (tape.pausing)
431 if (tape.playing) /* PLAYING -> PAUSING -> RECORDING */
433 tape.pos[tape.counter].delay = tape.delay_played;
434 tape.playing = FALSE;
435 tape.recording = TRUE;
438 DrawVideoDisplay(VIDEO_STATE_PLAY_OFF | VIDEO_STATE_REC_ON,0);
445 case TAPE_CTRL_ID_PLAY:
446 if (TAPE_IS_EMPTY(tape))
449 if (TAPE_IS_STOPPED(tape))
453 game_status = PLAYING;
456 else if (tape.playing)
458 if (tape.pausing) /* PAUSE -> PLAY */
460 else if (!tape.fast_forward) /* PLAY -> FAST FORWARD PLAY */
462 tape.fast_forward = TRUE;
463 DrawVideoDisplay(VIDEO_STATE_FFWD_ON, 0);
465 else if (!tape.pause_before_death) /* FFWD PLAY -> + AUTO PAUSE */
467 tape.pause_before_death = TRUE;
468 DrawVideoDisplay(VIDEO_STATE_PBEND_ON, VIDEO_DISPLAY_LABEL_ONLY);
470 else /* -> NORMAL PLAY */
472 tape.fast_forward = FALSE;
473 tape.pause_before_death = FALSE;
474 DrawVideoDisplay(VIDEO_STATE_FFWD_OFF | VIDEO_STATE_PBEND_OFF, 0);