/***********************************************************
* Rocks'n'Diamonds -- McDuffin Strikes Back! *
*----------------------------------------------------------*
-* (c) 1995-2002 Artsoft Entertainment *
+* (c) 1995-2006 Artsoft Entertainment *
* Holger Schemel *
* Detmolder Strasse 189 *
* 33604 Bielefeld *
/* video display functions */
/* ========================================================================= */
-void DrawVideoDisplay(unsigned long state, unsigned long value)
+void DrawVideoDisplay(unsigned int state, unsigned int value)
{
int i, j, k;
static char *monatsname[12] =
"JAN", "FEB", "MAR", "APR", "MAY", "JUN",
"JUL", "AUG", "SEP", "OCT", "NOV", "DEC"
};
+
+#if 0
static struct
{
int gd_x1, gd_y1;
}
},
};
+#endif
+
+#if 1
+ static struct
+ {
+ int graphic;
+ struct Rect *pos;
+ }
+ video_pos[NUM_TAPE_FUNCTIONS][NUM_TAPE_FUNCTION_PARTS] =
+ {
+ {
+ { IMG_TAPE_LABEL_GFX_PLAY, &tape.label.play },
+ { IMG_TAPE_SYMBOL_GFX_PLAY, &tape.symbol.play },
+ },
+ {
+ { IMG_TAPE_LABEL_GFX_RECORD, &tape.label.record },
+ { IMG_TAPE_SYMBOL_GFX_RECORD, &tape.symbol.record },
+ },
+ {
+ { IMG_TAPE_LABEL_GFX_PAUSE, &tape.label.pause },
+ { IMG_TAPE_SYMBOL_GFX_PAUSE, &tape.symbol.pause },
+ },
+ {
+ { IMG_TAPE_LABEL_GFX_DATE, &tape.label.date },
+ { -1, NULL },
+ },
+ {
+ { IMG_TAPE_LABEL_GFX_TIME, &tape.label.time },
+ { -1, NULL },
+ },
+ {
+ { IMG_TAPE_LABEL_GFX_FAST_FORWARD, &tape.label.fast_forward },
+ { IMG_TAPE_SYMBOL_GFX_FAST_FORWARD, &tape.symbol.fast_forward },
+ },
+ {
+ { IMG_TAPE_LABEL_GFX_PAUSE_BEFORE_END, &tape.label.pause_before_end },
+ { IMG_TAPE_SYMBOL_GFX_PAUSE_BEFORE_END, &tape.symbol.pause_before_end },
+ },
+ {
+ { IMG_TAPE_LABEL_GFX_WARP_FORWARD_BLIND, &tape.label.warp_forward_blind},
+ { IMG_TAPE_SYMBOL_GFX_WARP_FORWARD_BLIND, &tape.symbol.warp_forward_blind},
+ },
+ {
+ { IMG_TAPE_LABEL_GFX_WARP_FORWARD, &tape.label.warp_forward },
+ { IMG_TAPE_SYMBOL_GFX_WARP_FORWARD, &tape.symbol.warp_forward },
+ },
+ {
+ { IMG_TAPE_LABEL_GFX_SINGLE_STEP, &tape.label.single_step },
+ { IMG_TAPE_SYMBOL_GFX_SINGLE_STEP, &tape.symbol.single_step },
+ },
+ };
+
+ for (k = 0; k < NUM_TAPE_FUNCTION_STATES; k++) /* on or off states */
+ {
+ for (i = 0; i < NUM_TAPE_FUNCTIONS; i++) /* record, play, ... */
+ {
+ for (j = 0; j < NUM_TAPE_FUNCTION_PARTS; j++) /* label or symbol */
+ {
+ if (video_pos[i][j].graphic == -1 ||
+ video_pos[i][j].pos->x < 0 ||
+ video_pos[i][j].pos->y < 0)
+ continue;
+
+ if (state & (1 << (i * 2 + k)))
+ {
+ struct GraphicInfo *gfx_bg = &graphic_info[IMG_BACKGROUND_TAPE];
+ struct GraphicInfo *gfx = &graphic_info[video_pos[i][j].graphic];
+ struct Rect *pos = video_pos[i][j].pos;
+ Bitmap *gd_bitmap;
+ int gd_x, gd_y;
+ int skip_value =
+ (j == 0 ? VIDEO_DISPLAY_SYMBOL_ONLY : VIDEO_DISPLAY_LABEL_ONLY);
+
+ if (value == skip_value)
+ continue;
+
+ if (k == 1) /* on */
+ {
+ gd_bitmap = gfx->bitmap;
+ gd_x = gfx->src_x;
+ gd_y = gfx->src_y;
+ }
+ else /* off */
+ {
+ gd_bitmap = gfx_bg->bitmap;
+ gd_x = gfx_bg->src_x + pos->x;
+ gd_y = gfx_bg->src_y + pos->y;
+ }
+
+ /* some tape graphics may be undefined -- only draw if defined */
+ if (gd_bitmap != NULL)
+ BlitBitmap(gd_bitmap, drawto, gd_x, gd_y, gfx->width, gfx->height,
+ VX + pos->x, VY + pos->y);
+ }
+ }
+ }
+ }
+
+#else
for (k = 0; k < NUM_TAPE_FUNCTION_STATES; k++) /* on or off states */
{
}
}
}
+#endif
+
+#if 1
+ if (state & VIDEO_STATE_DATE_ON)
+ {
+ struct TextPosInfo *pos = &tape.text.date;
+ int tag = value % 100;
+ int monat = (value/100) % 100;
+ int jahr = (value/10000);
+
+ DrawText(VX + pos->x, VY + pos->y, int2str(tag, 2), pos->font);
+ DrawText(VX + pos->x + 27, VY + pos->y, monatsname[monat], pos->font);
+ DrawText(VX + pos->x + 64, VY + pos->y, int2str(jahr, 2), pos->font);
+ }
+
+ if (state & VIDEO_STATE_TIME_ON)
+ {
+ struct TextPosInfo *pos = &tape.text.time;
+ int min = value / 60;
+ int sec = value % 60;
+
+ DrawText(VX + pos->x, VY + pos->y, int2str(min, 2), pos->font);
+ DrawText(VX + pos->x + 27, VY + pos->y, int2str(sec, 2), pos->font);
+ }
+
+#else
if (state & VIDEO_STATE_DATE_ON)
{
DrawText(VX + VIDEO_TIME_XPOS + 27, VY + VIDEO_TIME_YPOS,
int2str(sec, 2), FONT_TAPE_RECORDER);
}
+#endif
redraw_mask |= REDRAW_DOOR_2;
}
void DrawCompleteVideoDisplay()
{
+#if 0
+ printf("::: %d, %d / %d, %d [%d] [%d, %d] [%d/%d]\n",
+ VX, VY, EX, EY, game_status, gfx.vx, gfx.vy,
+ tape.date, tape.length);
+#endif
+
BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto,
DOOR_GFX_PAGEX3, DOOR_GFX_PAGEY2,
gfx.vxsize, gfx.vysize, gfx.vx, gfx.vy);
gfx.vx + VIDEO_CONTROL_XPOS, gfx.vy + VIDEO_CONTROL_YPOS);
DrawVideoDisplay(VIDEO_ALL_OFF, 0);
+
+#if 1
+ if (tape.recording)
+ {
+ DrawVideoDisplay(VIDEO_STATE_REC_ON, 0);
+ DrawVideoDisplay(VIDEO_STATE_DATE_ON, tape.date);
+ DrawVideoDisplay(VIDEO_STATE_TIME_ON, tape.length_seconds);
+
+ if (tape.pausing)
+ DrawVideoDisplay(VIDEO_STATE_PAUSE_ON, 0);
+ }
+ else if (tape.playing)
+ {
+ DrawVideoDisplay(VIDEO_STATE_PLAY_ON, 0);
+ DrawVideoDisplay(VIDEO_STATE_DATE_ON, tape.date);
+ DrawVideoDisplay(VIDEO_STATE_TIME_ON, 0);
+
+ if (tape.pausing)
+ DrawVideoDisplay(VIDEO_STATE_PAUSE_ON, 0);
+ }
+ else if (tape.date && tape.length)
+ {
+ DrawVideoDisplay(VIDEO_STATE_DATE_ON, tape.date);
+ DrawVideoDisplay(VIDEO_STATE_TIME_ON, tape.length_seconds);
+ }
+#else
if (tape.date && tape.length)
{
DrawVideoDisplay(VIDEO_STATE_DATE_ON, tape.date);
DrawVideoDisplay(VIDEO_STATE_TIME_ON, tape.length_seconds);
}
+#endif
BlitBitmap(drawto, bitmap_db_door, gfx.vx, gfx.vy, gfx.vxsize, gfx.vysize,
DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
/* tape control functions */
/* ========================================================================= */
-static void TapeSetDate()
+void TapeSetDateFromEpochSeconds(time_t epoch_seconds)
{
- time_t epoch_seconds = time(NULL);
- struct tm *now = localtime(&epoch_seconds);
+ struct tm *lt = localtime(&epoch_seconds);
- tape.date = 10000 * (now->tm_year % 100) + 100 * now->tm_mon + now->tm_mday;
+ tape.date = 10000 * (lt->tm_year % 100) + 100 * lt->tm_mon + lt->tm_mday;
+}
+
+void TapeSetDateFromNow()
+{
+ TapeSetDateFromEpochSeconds(time(NULL));
}
void TapeErase()
{
int i;
- tape.length = 0;
tape.counter = 0;
+ tape.length = 0;
+ tape.length_seconds = 0;
if (leveldir_current)
setString(&tape.level_identifier, leveldir_current->identifier);
tape.pos[tape.counter].delay = 0;
tape.changed = TRUE;
- tape.random_seed = InitRND(NEW_RANDOMIZE);
+ tape.random_seed = InitRND(level.random_seed);
tape.file_version = FILE_VERSION_ACTUAL;
tape.game_version = GAME_VERSION_ACTUAL;
tape.engine_version = level.game_version;
- TapeSetDate();
+ TapeSetDateFromNow();
for (i = 0; i < MAX_PLAYERS; i++)
tape.player_participates[i] = FALSE;
InitRND(tape.random_seed);
}
-static void TapeSetRandomSeed(long random_seed)
+static void TapeSetRandomSeed(int random_seed)
{
tape.random_seed = InitRND(random_seed);
}
-void TapeStartRecording(long random_seed)
+void TapeStartRecording(int random_seed)
{
if (!TAPE_IS_STOPPED(tape))
TapeStop();
DrawVideoDisplay(VIDEO_STATE_REC_ON, 0);
DrawVideoDisplay(VIDEO_STATE_DATE_ON, tape.date);
DrawVideoDisplay(VIDEO_STATE_TIME_ON, 0);
+
MapTapeWarpButton();
SetDrawDeactivationMask(REDRAW_NONE);
static void TapeStartGameRecording()
{
- TapeStartRecording(NEW_RANDOMIZE);
+ TapeStartRecording(level.random_seed);
#if defined(NETWORK_AVALIABLE)
if (options.network)
tape.recording = TRUE;
tape.changed = TRUE;
- TapeSetDate();
+ TapeSetDateFromNow();
DrawVideoDisplay(VIDEO_STATE_DATE_ON, tape.date);
DrawVideoDisplay(VIDEO_STATE_PLAY_OFF | VIDEO_STATE_REC_ON, 0);
+
+#if 1
+ UpdateAndDisplayGameControlValues();
+#endif
}
void TapeHaltRecording()
tape.quick_resume = FALSE;
TapeAppendRecording();
+
+ if (!CheckEngineSnapshot())
+ SaveEngineSnapshot();
}
}
}
DrawVideoDisplay(VIDEO_STATE_PLAY_ON, 0);
DrawVideoDisplay(VIDEO_STATE_DATE_ON, tape.date);
DrawVideoDisplay(VIDEO_STATE_TIME_ON, 0);
+
MapTapeWarpButton();
SetDrawDeactivationMask(REDRAW_NONE);
DrawVideoDisplay(VIDEO_STATE_DATE_ON, tape.date);
DrawVideoDisplay(VIDEO_STATE_TIME_ON, tape.length_seconds);
}
-
-#if 0
- if (tape.auto_play)
- AutoPlayTape(); /* continue automatically playing next tape */
-#endif
}
unsigned int GetTapeLength()
void TapeQuickSave()
{
- if (game_status == GAME_MODE_PLAYING)
+ if (game_status == GAME_MODE_MAIN)
{
- if (tape.recording)
- TapeHaltRecording(); /* prepare tape for saving on-the-fly */
+ Request("No game that can be saved !", REQ_CONFIRM);
- if (TAPE_IS_EMPTY(tape))
- Request("No tape that can be saved !", REQ_CONFIRM);
- else
- SaveTape(tape.level_nr);
+ return;
}
- else if (game_status == GAME_MODE_MAIN)
- Request("No game that can be saved !", REQ_CONFIRM);
+
+ if (game_status != GAME_MODE_PLAYING)
+ return;
+
+ if (tape.recording)
+ TapeHaltRecording(); /* prepare tape for saving on-the-fly */
+
+ if (TAPE_IS_EMPTY(tape))
+ {
+ Request("No tape that can be saved !", REQ_CONFIRM);
+
+ return;
+ }
+
+ if (SaveTapeChecked(tape.level_nr))
+ SaveEngineSnapshot();
}
void TapeQuickLoad()
return;
}
- if (game_status == GAME_MODE_PLAYING || game_status == GAME_MODE_MAIN)
+ if (game_status != GAME_MODE_PLAYING && game_status != GAME_MODE_MAIN)
+ return;
+
+ if (CheckEngineSnapshot())
{
- TapeStop();
- TapeErase();
+ TapeStartGamePlaying();
- LoadTape(level_nr);
- if (!TAPE_IS_EMPTY(tape))
- {
- TapeStartGamePlaying();
- TapeStartWarpForward();
+ LoadEngineSnapshot();
- tape.quick_resume = TRUE;
- }
- else /* this should not happen (basically checked above) */
- {
- int reopen_door = (game_status == GAME_MODE_PLAYING ? REQ_REOPEN : 0);
+ DrawCompleteVideoDisplay();
- Request("No tape for this level !", REQ_CONFIRM | reopen_door);
- }
+ tape.playing = TRUE;
+ tape.pausing = TRUE;
+
+ TapeStopWarpForward();
+ TapeAppendRecording();
+
+ if (FrameCounter > 0)
+ return;
+ }
+
+ TapeStop();
+ TapeErase();
+
+ LoadTape(level_nr);
+
+ if (!TAPE_IS_EMPTY(tape))
+ {
+ TapeStartGamePlaying();
+ TapeStartWarpForward();
+
+ tape.quick_resume = TRUE;
+ }
+ else /* this should not happen (basically checked above) */
+ {
+ int reopen_door = (game_status == GAME_MODE_PLAYING ? REQ_REOPEN : 0);
+
+ Request("No tape for this level !", REQ_CONFIRM | reopen_door);
}
}
static int num_levels_solved = 0;
static int num_tape_missing = 0;
static boolean level_failed[MAX_TAPES_PER_SET];
+#if 0
static boolean tape_missing[MAX_TAPES_PER_SET];
+#endif
int i;
if (autoplay_initialized)
for (i = 0; i < MAX_TAPES_PER_SET; i++)
{
level_failed[i] = FALSE;
+#if 0
tape_missing[i] = FALSE;
+#endif
}
autoplay_initialized = TRUE;
if (tape.no_valid_file)
{
num_tape_missing++;
+#if 0
if (level_nr >= 0 && level_nr < MAX_TAPES_PER_SET)
tape_missing[level_nr] = TRUE;
+#endif
printf("(no tape)\n");
continue;
/* ---------- new tape button stuff ---------------------------------------- */
-/* graphic position values for tape buttons */
-#define TAPE_BUTTON_XSIZE 18
-#define TAPE_BUTTON_YSIZE 18
-#define TAPE_BUTTON_XPOS 5
-#define TAPE_BUTTON_YPOS 77
-
-#define TAPE_BUTTON_EJECT_XPOS (TAPE_BUTTON_XPOS + 0 * TAPE_BUTTON_XSIZE)
-#define TAPE_BUTTON_EXTRA_XPOS (TAPE_BUTTON_XPOS + 0 * TAPE_BUTTON_XSIZE)
-#define TAPE_BUTTON_STOP_XPOS (TAPE_BUTTON_XPOS + 1 * TAPE_BUTTON_XSIZE)
-#define TAPE_BUTTON_PAUSE_XPOS (TAPE_BUTTON_XPOS + 2 * TAPE_BUTTON_XSIZE)
-#define TAPE_BUTTON_RECORD_XPOS (TAPE_BUTTON_XPOS + 3 * TAPE_BUTTON_XSIZE)
-#define TAPE_BUTTON_PLAY_XPOS (TAPE_BUTTON_XPOS + 4 * TAPE_BUTTON_XSIZE)
-
static struct
{
- int x, y;
+ int graphic;
+ struct Rect *pos;
int gadget_id;
char *infotext;
} tapebutton_info[NUM_TAPE_BUTTONS] =
{
{
- TAPE_BUTTON_EJECT_XPOS, TAPE_BUTTON_YPOS,
- TAPE_CTRL_ID_EJECT,
- "eject tape"
+ IMG_TAPE_BUTTON_GFX_EJECT, &tape.button.eject,
+ TAPE_CTRL_ID_EJECT, "eject tape"
},
{
- TAPE_BUTTON_EXTRA_XPOS, TAPE_BUTTON_YPOS,
- TAPE_CTRL_ID_EXTRA,
- "extra functions"
+ /* (same position as "eject" button) */
+ IMG_TAPE_BUTTON_GFX_EXTRA, &tape.button.eject,
+ TAPE_CTRL_ID_EXTRA, "extra functions"
},
{
- TAPE_BUTTON_STOP_XPOS, TAPE_BUTTON_YPOS,
- TAPE_CTRL_ID_STOP,
- "stop tape"
+ IMG_TAPE_BUTTON_GFX_STOP, &tape.button.stop,
+ TAPE_CTRL_ID_STOP, "stop tape"
},
{
- TAPE_BUTTON_PAUSE_XPOS, TAPE_BUTTON_YPOS,
- TAPE_CTRL_ID_PAUSE,
- "pause tape"
+ IMG_TAPE_BUTTON_GFX_PAUSE, &tape.button.pause,
+ TAPE_CTRL_ID_PAUSE, "pause tape"
},
{
- TAPE_BUTTON_RECORD_XPOS, TAPE_BUTTON_YPOS,
- TAPE_CTRL_ID_RECORD,
- "record tape"
+ IMG_TAPE_BUTTON_GFX_RECORD, &tape.button.record,
+ TAPE_CTRL_ID_RECORD, "record tape"
},
{
- TAPE_BUTTON_PLAY_XPOS, TAPE_BUTTON_YPOS,
- TAPE_CTRL_ID_PLAY,
- "play tape"
+ IMG_TAPE_BUTTON_GFX_PLAY, &tape.button.play,
+ TAPE_CTRL_ID_PLAY, "play tape"
}
};
for (i = 0; i < NUM_TAPE_BUTTONS; i++)
{
- Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
+ struct GraphicInfo *gfx = &graphic_info[tapebutton_info[i].graphic];
+ struct Rect *pos = tapebutton_info[i].pos;
struct GadgetInfo *gi;
- int gd_xoffset, gd_yoffset;
- int gd_x1, gd_x2, gd_y;
+ int gd_x = gfx->src_x;
+ int gd_y = gfx->src_y;
+ int gd_xp = gfx->src_x + gfx->pressed_xoffset;
+ int gd_yp = gfx->src_y + gfx->pressed_yoffset;
int id = i;
- gd_xoffset = tapebutton_info[i].x;
- gd_yoffset = tapebutton_info[i].y;
- gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
- gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
- gd_y = DOOR_GFX_PAGEY2 + gd_yoffset;
-
- if (i == TAPE_CTRL_ID_EXTRA)
- {
- gd_x1 = DOOR_GFX_PAGEX6 + gd_xoffset;
- gd_x2 = DOOR_GFX_PAGEX5 + gd_xoffset;
- }
-
gi = CreateGadget(GDI_CUSTOM_ID, id,
GDI_INFO_TEXT, tapebutton_info[i].infotext,
- GDI_X, VX + gd_xoffset,
- GDI_Y, VY + gd_yoffset,
- GDI_WIDTH, TAPE_BUTTON_XSIZE,
- GDI_HEIGHT, TAPE_BUTTON_YSIZE,
+ GDI_X, VX + pos->x,
+ GDI_Y, VY + pos->y,
+ GDI_WIDTH, gfx->width,
+ GDI_HEIGHT, gfx->height,
GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
GDI_STATE, GD_BUTTON_UNPRESSED,
- GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
- GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
+ GDI_DESIGN_UNPRESSED, gfx->bitmap, gd_x, gd_y,
+ GDI_DESIGN_PRESSED, gfx->bitmap, gd_xp, gd_yp,
+ GDI_DIRECT_DRAW, FALSE,
GDI_EVENT_MASK, GD_EVENT_RELEASED,
GDI_CALLBACK_ACTION, HandleTapeButtons,
GDI_END);
UnmapGadget(tape_gadget[i]);
}
-static void HandleTapeButtons(struct GadgetInfo *gi)
+static void HandleTapeButtonsExt(int id)
{
- int id = gi->custom_id;
-
if (game_status != GAME_MODE_MAIN && game_status != GAME_MODE_PLAYING)
return;
{
case TAPE_CTRL_ID_EJECT:
TapeStop();
+
if (TAPE_IS_EMPTY(tape))
{
LoadTape(level_nr);
+
if (TAPE_IS_EMPTY(tape))
Request("No tape for this level !", REQ_CONFIRM);
}
else
{
if (tape.changed)
- SaveTape(tape.level_nr);
+ SaveTapeChecked(tape.level_nr);
+
TapeErase();
}
+
DrawCompleteVideoDisplay();
break;
}
else if (tape.recording)
TapeSingleStep();
+
break;
case TAPE_CTRL_ID_STOP:
break;
}
}
+
+static void HandleTapeButtons(struct GadgetInfo *gi)
+{
+ HandleTapeButtonsExt(gi->custom_id);
+}
+
+void HandleTapeButtonKeys(Key key)
+{
+ boolean eject_button_is_active = TAPE_IS_STOPPED(tape);
+ boolean extra_button_is_active = !eject_button_is_active;
+
+ if (key == setup.shortcut.tape_eject && eject_button_is_active)
+ HandleTapeButtonsExt(TAPE_CTRL_ID_EJECT);
+ else if (key == setup.shortcut.tape_extra && extra_button_is_active)
+ HandleTapeButtonsExt(TAPE_CTRL_ID_EXTRA);
+ else if (key == setup.shortcut.tape_stop)
+ HandleTapeButtonsExt(TAPE_CTRL_ID_STOP);
+ else if (key == setup.shortcut.tape_pause)
+ HandleTapeButtonsExt(TAPE_CTRL_ID_PAUSE);
+ else if (key == setup.shortcut.tape_record)
+ HandleTapeButtonsExt(TAPE_CTRL_ID_RECORD);
+ else if (key == setup.shortcut.tape_play)
+ HandleTapeButtonsExt(TAPE_CTRL_ID_PLAY);
+}