X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=7d83c63f8800dca7c19354af58e6c83de955348f;hb=7e7bea870822b12f26c2266d0bcc23db6a1684f4;hp=2a9eabb016a0ca6c1ac2e69424e736a30cdb9044;hpb=e77c26313b1a1e3ddd884cdda005cb6758c1a100;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index 2a9eabb0..7d83c63f 100644 --- a/src/game.c +++ b/src/game.c @@ -131,8 +131,8 @@ #if 1 /* game panel display and control definitions */ -#define GAME_PANEL_LEVEL_NUMBER 0 -#define GAME_PANEL_GEMS 1 +#define GAME_PANEL_LEVEL_NUMBER 0 +#define GAME_PANEL_GEMS 1 #define GAME_PANEL_INVENTORY_COUNT 2 #define GAME_PANEL_INVENTORY_FIRST_1 3 #define GAME_PANEL_INVENTORY_FIRST_2 4 @@ -161,7 +161,7 @@ #define GAME_PANEL_KEY_WHITE 27 #define GAME_PANEL_KEY_WHITE_COUNT 28 #define GAME_PANEL_SCORE 29 -#define GAME_PANEL_TIME 30 +#define GAME_PANEL_TIME 30 #define GAME_PANEL_TIME_HH 31 #define GAME_PANEL_TIME_MM 32 #define GAME_PANEL_TIME_SS 33 @@ -169,13 +169,13 @@ #define GAME_PANEL_SHIELD_NORMAL_TIME 35 #define GAME_PANEL_SHIELD_DEADLY 36 #define GAME_PANEL_SHIELD_DEADLY_TIME 37 -#define GAME_PANEL_EXIT 38 +#define GAME_PANEL_EXIT 38 #define GAME_PANEL_EMC_MAGIC_BALL 39 #define GAME_PANEL_EMC_MAGIC_BALL_SWITCH 40 -#define GAME_PANEL_LIGHT_SWITCH 41 +#define GAME_PANEL_LIGHT_SWITCH 41 #define GAME_PANEL_LIGHT_SWITCH_TIME 42 #define GAME_PANEL_TIMEGATE_SWITCH 43 -#define GAME_PANEL_TIMEGATE_SWITCH_TIME 44 +#define GAME_PANEL_TIMEGATE_SWITCH_TIME 44 #define GAME_PANEL_SWITCHGATE_SWITCH 45 #define GAME_PANEL_EMC_LENSES 46 #define GAME_PANEL_EMC_LENSES_TIME 47 @@ -188,23 +188,71 @@ #define GAME_PANEL_PENGUINS 54 #define GAME_PANEL_SOKOBAN_OBJECTS 55 #define GAME_PANEL_SOKOBAN_FIELDS 56 -#define GAME_PANEL_ROBOT_WHEEL 57 +#define GAME_PANEL_ROBOT_WHEEL 57 #define GAME_PANEL_CONVEYOR_BELT_1 58 -#define GAME_PANEL_CONVEYOR_BELT_1_SWITCH 59 -#define GAME_PANEL_CONVEYOR_BELT_2 60 -#define GAME_PANEL_CONVEYOR_BELT_2_SWITCH 61 -#define GAME_PANEL_CONVEYOR_BELT_3 62 -#define GAME_PANEL_CONVEYOR_BELT_3_SWITCH 63 -#define GAME_PANEL_CONVEYOR_BELT_4 64 +#define GAME_PANEL_CONVEYOR_BELT_2 59 +#define GAME_PANEL_CONVEYOR_BELT_3 60 +#define GAME_PANEL_CONVEYOR_BELT_4 61 +#define GAME_PANEL_CONVEYOR_BELT_1_SWITCH 62 +#define GAME_PANEL_CONVEYOR_BELT_2_SWITCH 63 +#define GAME_PANEL_CONVEYOR_BELT_3_SWITCH 64 #define GAME_PANEL_CONVEYOR_BELT_4_SWITCH 65 #define GAME_PANEL_MAGIC_WALL 66 #define GAME_PANEL_MAGIC_WALL_TIME 67 #define GAME_PANEL_GRAVITY_STATE 68 -#define GAME_PANEL_PLAYER_NAME 69 -#define GAME_PANEL_LEVEL_NAME 70 -#define GAME_PANEL_LEVEL_AUTHOR 71 +#define GAME_PANEL_GRAPHIC_1 69 +#define GAME_PANEL_GRAPHIC_2 70 +#define GAME_PANEL_GRAPHIC_3 71 +#define GAME_PANEL_GRAPHIC_4 72 +#define GAME_PANEL_GRAPHIC_5 73 +#define GAME_PANEL_GRAPHIC_6 74 +#define GAME_PANEL_GRAPHIC_7 75 +#define GAME_PANEL_GRAPHIC_8 76 +#define GAME_PANEL_ELEMENT_1 77 +#define GAME_PANEL_ELEMENT_2 78 +#define GAME_PANEL_ELEMENT_3 79 +#define GAME_PANEL_ELEMENT_4 80 +#define GAME_PANEL_ELEMENT_5 81 +#define GAME_PANEL_ELEMENT_6 82 +#define GAME_PANEL_ELEMENT_7 83 +#define GAME_PANEL_ELEMENT_8 84 +#define GAME_PANEL_ELEMENT_COUNT_1 85 +#define GAME_PANEL_ELEMENT_COUNT_2 86 +#define GAME_PANEL_ELEMENT_COUNT_3 87 +#define GAME_PANEL_ELEMENT_COUNT_4 88 +#define GAME_PANEL_ELEMENT_COUNT_5 89 +#define GAME_PANEL_ELEMENT_COUNT_6 90 +#define GAME_PANEL_ELEMENT_COUNT_7 91 +#define GAME_PANEL_ELEMENT_COUNT_8 92 +#define GAME_PANEL_CE_SCORE_1 93 +#define GAME_PANEL_CE_SCORE_2 94 +#define GAME_PANEL_CE_SCORE_3 95 +#define GAME_PANEL_CE_SCORE_4 96 +#define GAME_PANEL_CE_SCORE_5 97 +#define GAME_PANEL_CE_SCORE_6 98 +#define GAME_PANEL_CE_SCORE_7 99 +#define GAME_PANEL_CE_SCORE_8 100 +#define GAME_PANEL_CE_SCORE_1_ELEMENT 101 +#define GAME_PANEL_CE_SCORE_2_ELEMENT 102 +#define GAME_PANEL_CE_SCORE_3_ELEMENT 103 +#define GAME_PANEL_CE_SCORE_4_ELEMENT 104 +#define GAME_PANEL_CE_SCORE_5_ELEMENT 105 +#define GAME_PANEL_CE_SCORE_6_ELEMENT 106 +#define GAME_PANEL_CE_SCORE_7_ELEMENT 107 +#define GAME_PANEL_CE_SCORE_8_ELEMENT 108 +#define GAME_PANEL_PLAYER_NAME 109 +#define GAME_PANEL_LEVEL_NAME 110 +#define GAME_PANEL_LEVEL_AUTHOR 111 + +#define NUM_GAME_PANEL_CONTROLS 112 + +struct GamePanelOrderInfo +{ + int nr; + int sort_priority; +}; -#define NUM_GAME_PANEL_CONTROLS 72 +static struct GamePanelOrderInfo game_panel_order[NUM_GAME_PANEL_CONTROLS]; struct GamePanelControlInfo { @@ -216,6 +264,7 @@ struct GamePanelControlInfo int value, last_value; int frame, last_frame; int gfx_frame; + int gfx_random; }; static struct GamePanelControlInfo game_panel_controls[] = @@ -237,82 +286,82 @@ static struct GamePanelControlInfo game_panel_controls[] = }, { GAME_PANEL_INVENTORY_FIRST_1, - &game.panel.inventory_first_1, + &game.panel.inventory_first[0], TYPE_ELEMENT, }, { GAME_PANEL_INVENTORY_FIRST_2, - &game.panel.inventory_first_2, + &game.panel.inventory_first[1], TYPE_ELEMENT, }, { GAME_PANEL_INVENTORY_FIRST_3, - &game.panel.inventory_first_3, + &game.panel.inventory_first[2], TYPE_ELEMENT, }, { GAME_PANEL_INVENTORY_FIRST_4, - &game.panel.inventory_first_4, + &game.panel.inventory_first[3], TYPE_ELEMENT, }, { GAME_PANEL_INVENTORY_FIRST_5, - &game.panel.inventory_first_5, + &game.panel.inventory_first[4], TYPE_ELEMENT, }, { GAME_PANEL_INVENTORY_FIRST_6, - &game.panel.inventory_first_6, + &game.panel.inventory_first[5], TYPE_ELEMENT, }, { GAME_PANEL_INVENTORY_FIRST_7, - &game.panel.inventory_first_7, + &game.panel.inventory_first[6], TYPE_ELEMENT, }, { GAME_PANEL_INVENTORY_FIRST_8, - &game.panel.inventory_first_8, + &game.panel.inventory_first[7], TYPE_ELEMENT, }, { GAME_PANEL_INVENTORY_LAST_1, - &game.panel.inventory_last_1, + &game.panel.inventory_last[0], TYPE_ELEMENT, }, { GAME_PANEL_INVENTORY_LAST_2, - &game.panel.inventory_last_2, + &game.panel.inventory_last[1], TYPE_ELEMENT, }, { GAME_PANEL_INVENTORY_LAST_3, - &game.panel.inventory_last_3, + &game.panel.inventory_last[2], TYPE_ELEMENT, }, { GAME_PANEL_INVENTORY_LAST_4, - &game.panel.inventory_last_4, + &game.panel.inventory_last[3], TYPE_ELEMENT, }, { GAME_PANEL_INVENTORY_LAST_5, - &game.panel.inventory_last_5, + &game.panel.inventory_last[4], TYPE_ELEMENT, }, { GAME_PANEL_INVENTORY_LAST_6, - &game.panel.inventory_last_6, + &game.panel.inventory_last[5], TYPE_ELEMENT, }, { GAME_PANEL_INVENTORY_LAST_7, - &game.panel.inventory_last_7, + &game.panel.inventory_last[6], TYPE_ELEMENT, }, { GAME_PANEL_INVENTORY_LAST_8, - &game.panel.inventory_last_8, + &game.panel.inventory_last[7], TYPE_ELEMENT, }, { @@ -512,42 +561,42 @@ static struct GamePanelControlInfo game_panel_controls[] = }, { GAME_PANEL_CONVEYOR_BELT_1, - &game.panel.conveyor_belt_1, + &game.panel.conveyor_belt[0], TYPE_ELEMENT, }, { - GAME_PANEL_CONVEYOR_BELT_1_SWITCH, - &game.panel.conveyor_belt_1_switch, + GAME_PANEL_CONVEYOR_BELT_2, + &game.panel.conveyor_belt[1], TYPE_ELEMENT, }, { - GAME_PANEL_CONVEYOR_BELT_2, - &game.panel.conveyor_belt_2, + GAME_PANEL_CONVEYOR_BELT_3, + &game.panel.conveyor_belt[2], TYPE_ELEMENT, }, { - GAME_PANEL_CONVEYOR_BELT_2_SWITCH, - &game.panel.conveyor_belt_2_switch, + GAME_PANEL_CONVEYOR_BELT_4, + &game.panel.conveyor_belt[3], TYPE_ELEMENT, }, { - GAME_PANEL_CONVEYOR_BELT_3, - &game.panel.conveyor_belt_3, + GAME_PANEL_CONVEYOR_BELT_1_SWITCH, + &game.panel.conveyor_belt_switch[0], TYPE_ELEMENT, }, { - GAME_PANEL_CONVEYOR_BELT_3_SWITCH, - &game.panel.conveyor_belt_3_switch, + GAME_PANEL_CONVEYOR_BELT_2_SWITCH, + &game.panel.conveyor_belt_switch[1], TYPE_ELEMENT, }, { - GAME_PANEL_CONVEYOR_BELT_4, - &game.panel.conveyor_belt_4, + GAME_PANEL_CONVEYOR_BELT_3_SWITCH, + &game.panel.conveyor_belt_switch[2], TYPE_ELEMENT, }, { GAME_PANEL_CONVEYOR_BELT_4_SWITCH, - &game.panel.conveyor_belt_4_switch, + &game.panel.conveyor_belt_switch[3], TYPE_ELEMENT, }, { @@ -565,6 +614,206 @@ static struct GamePanelControlInfo game_panel_controls[] = &game.panel.gravity_state, TYPE_STRING, }, + { + GAME_PANEL_GRAPHIC_1, + &game.panel.graphic[0], + TYPE_ELEMENT, + }, + { + GAME_PANEL_GRAPHIC_2, + &game.panel.graphic[1], + TYPE_ELEMENT, + }, + { + GAME_PANEL_GRAPHIC_3, + &game.panel.graphic[2], + TYPE_ELEMENT, + }, + { + GAME_PANEL_GRAPHIC_4, + &game.panel.graphic[3], + TYPE_ELEMENT, + }, + { + GAME_PANEL_GRAPHIC_5, + &game.panel.graphic[4], + TYPE_ELEMENT, + }, + { + GAME_PANEL_GRAPHIC_6, + &game.panel.graphic[5], + TYPE_ELEMENT, + }, + { + GAME_PANEL_GRAPHIC_7, + &game.panel.graphic[6], + TYPE_ELEMENT, + }, + { + GAME_PANEL_GRAPHIC_8, + &game.panel.graphic[7], + TYPE_ELEMENT, + }, + { + GAME_PANEL_ELEMENT_1, + &game.panel.element[0], + TYPE_ELEMENT, + }, + { + GAME_PANEL_ELEMENT_2, + &game.panel.element[1], + TYPE_ELEMENT, + }, + { + GAME_PANEL_ELEMENT_3, + &game.panel.element[2], + TYPE_ELEMENT, + }, + { + GAME_PANEL_ELEMENT_4, + &game.panel.element[3], + TYPE_ELEMENT, + }, + { + GAME_PANEL_ELEMENT_5, + &game.panel.element[4], + TYPE_ELEMENT, + }, + { + GAME_PANEL_ELEMENT_6, + &game.panel.element[5], + TYPE_ELEMENT, + }, + { + GAME_PANEL_ELEMENT_7, + &game.panel.element[6], + TYPE_ELEMENT, + }, + { + GAME_PANEL_ELEMENT_8, + &game.panel.element[7], + TYPE_ELEMENT, + }, + { + GAME_PANEL_ELEMENT_COUNT_1, + &game.panel.element_count[0], + TYPE_INTEGER, + }, + { + GAME_PANEL_ELEMENT_COUNT_2, + &game.panel.element_count[1], + TYPE_INTEGER, + }, + { + GAME_PANEL_ELEMENT_COUNT_3, + &game.panel.element_count[2], + TYPE_INTEGER, + }, + { + GAME_PANEL_ELEMENT_COUNT_4, + &game.panel.element_count[3], + TYPE_INTEGER, + }, + { + GAME_PANEL_ELEMENT_COUNT_5, + &game.panel.element_count[4], + TYPE_INTEGER, + }, + { + GAME_PANEL_ELEMENT_COUNT_6, + &game.panel.element_count[5], + TYPE_INTEGER, + }, + { + GAME_PANEL_ELEMENT_COUNT_7, + &game.panel.element_count[6], + TYPE_INTEGER, + }, + { + GAME_PANEL_ELEMENT_COUNT_8, + &game.panel.element_count[7], + TYPE_INTEGER, + }, + { + GAME_PANEL_CE_SCORE_1, + &game.panel.ce_score[0], + TYPE_INTEGER, + }, + { + GAME_PANEL_CE_SCORE_2, + &game.panel.ce_score[1], + TYPE_INTEGER, + }, + { + GAME_PANEL_CE_SCORE_3, + &game.panel.ce_score[2], + TYPE_INTEGER, + }, + { + GAME_PANEL_CE_SCORE_4, + &game.panel.ce_score[3], + TYPE_INTEGER, + }, + { + GAME_PANEL_CE_SCORE_5, + &game.panel.ce_score[4], + TYPE_INTEGER, + }, + { + GAME_PANEL_CE_SCORE_6, + &game.panel.ce_score[5], + TYPE_INTEGER, + }, + { + GAME_PANEL_CE_SCORE_7, + &game.panel.ce_score[6], + TYPE_INTEGER, + }, + { + GAME_PANEL_CE_SCORE_8, + &game.panel.ce_score[7], + TYPE_INTEGER, + }, + { + GAME_PANEL_CE_SCORE_1_ELEMENT, + &game.panel.ce_score_element[0], + TYPE_ELEMENT, + }, + { + GAME_PANEL_CE_SCORE_2_ELEMENT, + &game.panel.ce_score_element[1], + TYPE_ELEMENT, + }, + { + GAME_PANEL_CE_SCORE_3_ELEMENT, + &game.panel.ce_score_element[2], + TYPE_ELEMENT, + }, + { + GAME_PANEL_CE_SCORE_4_ELEMENT, + &game.panel.ce_score_element[3], + TYPE_ELEMENT, + }, + { + GAME_PANEL_CE_SCORE_5_ELEMENT, + &game.panel.ce_score_element[4], + TYPE_ELEMENT, + }, + { + GAME_PANEL_CE_SCORE_6_ELEMENT, + &game.panel.ce_score_element[5], + TYPE_ELEMENT, + }, + { + GAME_PANEL_CE_SCORE_7_ELEMENT, + &game.panel.ce_score_element[6], + TYPE_ELEMENT, + }, + { + GAME_PANEL_CE_SCORE_8_ELEMENT, + &game.panel.ce_score_element[7], + TYPE_ELEMENT, + }, { GAME_PANEL_PLAYER_NAME, &game.panel.player_name, @@ -647,6 +896,9 @@ static struct GamePanelControlInfo game_panel_controls[] = (be) + (e) - EL_SELF > EL_CUSTOM_END ? EL_CUSTOM_END : \ (be) + (e) - EL_SELF) +#define GET_PLAYER_FROM_BITS(p) \ + (EL_PLAYER_1 + ((p) != PLAYER_BITS_ANY ? log_2(p) : 0)) + #define GET_TARGET_ELEMENT(be, e, ch, cv, cs) \ ((e) == EL_TRIGGER_PLAYER ? (ch)->actual_trigger_player : \ (e) == EL_TRIGGER_ELEMENT ? (ch)->actual_trigger_element : \ @@ -765,6 +1017,8 @@ static struct GamePanelControlInfo game_panel_controls[] = static void CreateField(int, int, int); +static void ResetGfxAnimation(int, int); + static void SetPlayerWaiting(struct PlayerInfo *, boolean); static void AdvanceFrameAndPlayerCounters(int); @@ -1796,6 +2050,20 @@ static int get_inventory_element_from_pos(struct PlayerInfo *player, int pos) } } +static int compareGamePanelOrderInfo(const void *object1, const void *object2) +{ + const struct GamePanelOrderInfo *gpo1 = (struct GamePanelOrderInfo *)object1; + const struct GamePanelOrderInfo *gpo2 = (struct GamePanelOrderInfo *)object2; + int compare_result; + + if (gpo1->sort_priority != gpo2->sort_priority) + compare_result = gpo1->sort_priority - gpo2->sort_priority; + else + compare_result = gpo1->nr - gpo2->nr; + + return compare_result; +} + void InitGameControlValues() { int i; @@ -1803,9 +2071,10 @@ void InitGameControlValues() for (i = 0; game_panel_controls[i].nr != -1; i++) { struct GamePanelControlInfo *gpc = &game_panel_controls[i]; + struct GamePanelOrderInfo *gpo = &game_panel_order[i]; + struct TextPosInfo *pos = gpc->pos; int nr = gpc->nr; int type = gpc->type; - struct TextPosInfo *pos = gpc->pos; if (nr != i) { @@ -1829,22 +2098,64 @@ void InitGameControlValues() pos->width = pos->size; pos->height = pos->size; } + + /* fill structure for game panel draw order */ + gpo->nr = gpc->nr; + gpo->sort_priority = pos->sort_priority; + } + + /* sort game panel controls according to sort_priority and control number */ + qsort(game_panel_order, NUM_GAME_PANEL_CONTROLS, + sizeof(struct GamePanelOrderInfo), compareGamePanelOrderInfo); +} + +void UpdatePlayfieldElementCount() +{ + int i, j, x, y; + + for (i = 0; i < MAX_NUM_ELEMENTS; i++) + element_info[i].element_count = 0; + + SCAN_PLAYFIELD(x, y) + { + element_info[Feld[x][y]].element_count++; } + + for (i = 0; i < NUM_GROUP_ELEMENTS; i++) + for (j = 0; j < MAX_NUM_ELEMENTS; j++) + if (IS_IN_GROUP(j, i)) + element_info[EL_GROUP_START + i].element_count += + element_info[j].element_count; } void UpdateGameControlValues() { int i, k; - int time = (level.time == 0 ? TimePlayed : TimeLeft); - int score = (local_player->LevelSolved ? local_player->score_final : + int time = (local_player->LevelSolved ? + local_player->LevelSolved_CountingTime : + level.game_engine_type == GAME_ENGINE_TYPE_EM ? + level.native_em_level->lev->time : + level.time == 0 ? TimePlayed : TimeLeft); + int score = (local_player->LevelSolved ? + local_player->LevelSolved_CountingScore : + level.game_engine_type == GAME_ENGINE_TYPE_EM ? + level.native_em_level->lev->score : local_player->score); - int exit_closed = (local_player->gems_still_needed > 0 || + int gems = (level.game_engine_type == GAME_ENGINE_TYPE_EM ? + level.native_em_level->lev->required : + local_player->gems_still_needed); + int exit_closed = (level.game_engine_type == GAME_ENGINE_TYPE_EM ? + level.native_em_level->lev->required > 0 : + local_player->gems_still_needed > 0 || local_player->sokobanfields_still_needed > 0 || local_player->lights_still_needed > 0); + UpdatePlayfieldElementCount(); + + /* update game panel control values */ + game_panel_controls[GAME_PANEL_LEVEL_NUMBER].value = level_nr; - game_panel_controls[GAME_PANEL_GEMS].value = - local_player->gems_still_needed; + game_panel_controls[GAME_PANEL_GEMS].value = gems; game_panel_controls[GAME_PANEL_INVENTORY_COUNT].value = 0; for (i = 0; i < MAX_NUM_KEYS; i++) @@ -1857,12 +2168,24 @@ void UpdateGameControlValues() for (i = 0; i < MAX_PLAYERS; i++) { for (k = 0; k < MAX_NUM_KEYS; k++) - if (stored_player[i].key[k]) + { + if (level.game_engine_type == GAME_ENGINE_TYPE_EM) + { + if (level.native_em_level->ply[i]->keys & (1 << k)) + game_panel_controls[GAME_PANEL_KEY_1 + k].value = + get_key_element_from_nr(k); + } + else if (stored_player[i].key[k]) game_panel_controls[GAME_PANEL_KEY_1 + k].value = get_key_element_from_nr(k); + } - game_panel_controls[GAME_PANEL_INVENTORY_COUNT].value += - stored_player[i].inventory_size; + if (level.game_engine_type == GAME_ENGINE_TYPE_EM) + game_panel_controls[GAME_PANEL_INVENTORY_COUNT].value += + level.native_em_level->ply[i]->dynamite; + else + game_panel_controls[GAME_PANEL_INVENTORY_COUNT].value += + stored_player[i].inventory_size; if (stored_player[i].num_white_keys > 0) game_panel_controls[GAME_PANEL_KEY_WHITE].value = @@ -1877,12 +2200,24 @@ void UpdateGameControlValues() int player_nr = game.centered_player_nr; for (k = 0; k < MAX_NUM_KEYS; k++) - if (stored_player[player_nr].key[k]) + { + if (level.game_engine_type == GAME_ENGINE_TYPE_EM) + { + if (level.native_em_level->ply[player_nr]->keys & (1 << k)) + game_panel_controls[GAME_PANEL_KEY_1 + k].value = + get_key_element_from_nr(k); + } + else if (stored_player[player_nr].key[k]) game_panel_controls[GAME_PANEL_KEY_1 + k].value = get_key_element_from_nr(k); + } - game_panel_controls[GAME_PANEL_INVENTORY_COUNT].value += - stored_player[player_nr].inventory_size; + if (level.game_engine_type == GAME_ENGINE_TYPE_EM) + game_panel_controls[GAME_PANEL_INVENTORY_COUNT].value += + level.native_em_level->ply[player_nr]->dynamite; + else + game_panel_controls[GAME_PANEL_INVENTORY_COUNT].value += + stored_player[player_nr].inventory_size; if (stored_player[player_nr].num_white_keys > 0) game_panel_controls[GAME_PANEL_KEY_WHITE].value = EL_DC_KEY_WHITE; @@ -1891,7 +2226,7 @@ void UpdateGameControlValues() stored_player[player_nr].num_white_keys; } - for (i = 0; i < 8; i++) + for (i = 0; i < NUM_PANEL_INVENTORY; i++) { game_panel_controls[GAME_PANEL_INVENTORY_FIRST_1 + i].value = get_inventory_element_from_pos(local_player, i); @@ -1975,26 +2310,14 @@ void UpdateGameControlValues() game_panel_controls[GAME_PANEL_ROBOT_WHEEL].value = (game.robot_wheel_active ? EL_ROBOT_WHEEL_ACTIVE : EL_ROBOT_WHEEL); - game_panel_controls[GAME_PANEL_CONVEYOR_BELT_1].value = - (game.belt_dir[0] != MV_NONE ? EL_CONVEYOR_BELT_1_MIDDLE_ACTIVE : - EL_CONVEYOR_BELT_1_MIDDLE); - game_panel_controls[GAME_PANEL_CONVEYOR_BELT_1_SWITCH].value = - getBeltSwitchElementFromBeltNrAndBeltDir(0, game.belt_dir[0]); - game_panel_controls[GAME_PANEL_CONVEYOR_BELT_2].value = - (game.belt_dir[1] != MV_NONE ? EL_CONVEYOR_BELT_2_MIDDLE_ACTIVE : - EL_CONVEYOR_BELT_2_MIDDLE); - game_panel_controls[GAME_PANEL_CONVEYOR_BELT_2_SWITCH].value = - getBeltSwitchElementFromBeltNrAndBeltDir(1, game.belt_dir[1]); - game_panel_controls[GAME_PANEL_CONVEYOR_BELT_3].value = - (game.belt_dir[2] != MV_NONE ? EL_CONVEYOR_BELT_3_MIDDLE_ACTIVE : - EL_CONVEYOR_BELT_3_MIDDLE); - game_panel_controls[GAME_PANEL_CONVEYOR_BELT_3_SWITCH].value = - getBeltSwitchElementFromBeltNrAndBeltDir(2, game.belt_dir[2]); - game_panel_controls[GAME_PANEL_CONVEYOR_BELT_4].value = - (game.belt_dir[3] != MV_NONE ? EL_CONVEYOR_BELT_4_MIDDLE_ACTIVE : - EL_CONVEYOR_BELT_4_MIDDLE); - game_panel_controls[GAME_PANEL_CONVEYOR_BELT_4_SWITCH].value = - getBeltSwitchElementFromBeltNrAndBeltDir(3, game.belt_dir[3]); + for (i = 0; i < NUM_BELTS; i++) + { + game_panel_controls[GAME_PANEL_CONVEYOR_BELT_1 + i].value = + (game.belt_dir[i] != MV_NONE ? EL_CONVEYOR_BELT_1_MIDDLE_ACTIVE : + EL_CONVEYOR_BELT_1_MIDDLE) + i; + game_panel_controls[GAME_PANEL_CONVEYOR_BELT_1_SWITCH + i].value = + getBeltSwitchElementFromBeltNrAndBeltDir(i, game.belt_dir[i]); + } game_panel_controls[GAME_PANEL_MAGIC_WALL].value = (game.magic_wall_active ? EL_MAGIC_WALL_ACTIVE : EL_MAGIC_WALL); @@ -2008,48 +2331,145 @@ void UpdateGameControlValues() game_panel_controls[GAME_PANEL_GRAVITY_STATE].value = game.gravity; #endif + for (i = 0; i < NUM_PANEL_GRAPHICS; i++) + game_panel_controls[GAME_PANEL_GRAPHIC_1 + i].value = EL_GRAPHIC_1 + i; + + for (i = 0; i < NUM_PANEL_ELEMENTS; i++) + game_panel_controls[GAME_PANEL_ELEMENT_1 + i].value = + (IS_DRAWABLE_ELEMENT(game.panel.element[i].id) ? + game.panel.element[i].id : EL_UNDEFINED); + + for (i = 0; i < NUM_PANEL_ELEMENTS; i++) + game_panel_controls[GAME_PANEL_ELEMENT_COUNT_1 + i].value = + (IS_VALID_ELEMENT(game.panel.element_count[i].id) ? + element_info[game.panel.element_count[i].id].element_count : + EL_UNDEFINED); + + for (i = 0; i < NUM_PANEL_CE_SCORE; i++) + game_panel_controls[GAME_PANEL_CE_SCORE_1 + i].value = + (IS_CUSTOM_ELEMENT(game.panel.ce_score[i].id) ? + element_info[game.panel.ce_score[i].id].collect_score : 0); + + for (i = 0; i < NUM_PANEL_CE_SCORE; i++) + game_panel_controls[GAME_PANEL_CE_SCORE_1_ELEMENT + i].value = + (IS_CUSTOM_ELEMENT(game.panel.ce_score_element[i].id) ? + element_info[game.panel.ce_score_element[i].id].collect_score : + EL_UNDEFINED); + game_panel_controls[GAME_PANEL_PLAYER_NAME].value = 0; game_panel_controls[GAME_PANEL_LEVEL_NAME].value = 0; game_panel_controls[GAME_PANEL_LEVEL_AUTHOR].value = 0; + /* update game panel control frames */ + for (i = 0; game_panel_controls[i].nr != -1; i++) { struct GamePanelControlInfo *gpc = &game_panel_controls[i]; if (gpc->type == TYPE_ELEMENT) { + int last_anim_random_frame = gfx.anim_random_frame; + int element = gpc->value; + int graphic = el2panelimg(element); + if (gpc->value != gpc->last_value) + { gpc->gfx_frame = 0; + gpc->gfx_random = INIT_GFX_RANDOM(); + } else + { gpc->gfx_frame++; + if (ANIM_MODE(graphic) == ANIM_RANDOM && + IS_NEXT_FRAME(gpc->gfx_frame, graphic)) + gpc->gfx_random = INIT_GFX_RANDOM(); + } + + if (ANIM_MODE(graphic) == ANIM_RANDOM) + gfx.anim_random_frame = gpc->gfx_random; + + if (ANIM_MODE(graphic) == ANIM_CE_SCORE) + gpc->gfx_frame = element_info[element].collect_score; + gpc->frame = getGraphicAnimationFrame(el2panelimg(gpc->value), gpc->gfx_frame); + + if (ANIM_MODE(graphic) == ANIM_RANDOM) + gfx.anim_random_frame = last_anim_random_frame; } } } void DisplayGameControlValues() { + boolean redraw_panel = FALSE; int i; + for (i = 0; game_panel_controls[i].nr != -1; i++) + { + struct GamePanelControlInfo *gpc = &game_panel_controls[i]; + + if (PANEL_DEACTIVATED(gpc->pos)) + continue; + + if (gpc->value == gpc->last_value && + gpc->frame == gpc->last_frame) + continue; + + redraw_panel = TRUE; + } + + if (!redraw_panel) + return; + + /* copy default game door content to main double buffer */ + BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, + DOOR_GFX_PAGEX5, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE, DX, DY); + + /* redraw game control buttons */ +#if 1 + RedrawGameButtons(); +#else + UnmapGameButtons(); + MapGameButtons(); +#endif + game_status = GAME_MODE_PSEUDO_PANEL; +#if 1 + for (i = 0; i < NUM_GAME_PANEL_CONTROLS; i++) +#else for (i = 0; game_panel_controls[i].nr != -1; i++) +#endif { +#if 1 + int nr = game_panel_order[i].nr; + struct GamePanelControlInfo *gpc = &game_panel_controls[nr]; +#else struct GamePanelControlInfo *gpc = &game_panel_controls[i]; int nr = gpc->nr; - int type = gpc->type; +#endif struct TextPosInfo *pos = gpc->pos; + int type = gpc->type; int value = gpc->value; int frame = gpc->frame; +#if 0 int last_value = gpc->last_value; int last_frame = gpc->last_frame; +#endif int size = pos->size; int font = pos->font; + boolean draw_masked = pos->draw_masked; + int mask_mode = (draw_masked ? BLIT_MASKED : BLIT_OPAQUE); + + if (PANEL_DEACTIVATED(pos)) + continue; +#if 0 if (value == last_value && frame == last_frame) continue; +#endif gpc->last_value = value; gpc->last_frame = frame; @@ -2058,9 +2478,6 @@ void DisplayGameControlValues() printf("::: value %d changed from %d to %d\n", nr, last_value, value); #endif - if (PANEL_DEACTIVATED(pos)) - continue; - if (type == TYPE_INTEGER) { if (nr == GAME_PANEL_LEVEL_NUMBER || @@ -2079,6 +2496,7 @@ void DisplayGameControlValues() size = (value < value_change ? size1 : size2); font = (value < value_change ? font1 : font2); +#if 0 /* clear background if value just changed its size (dynamic digits) */ if ((last_value < value_change) != (value < value_change)) { @@ -2092,32 +2510,86 @@ void DisplayGameControlValues() ClearRectangleOnBackground(drawto, PANEL_XPOS(pos), PANEL_YPOS(pos), max_width, max_height); } +#endif } - - pos->width = size * getFontWidth(font); } - DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, size), font); +#if 1 + /* correct text size if "digits" is zero or less */ + if (size <= 0) + size = strlen(int2str(value, size)); + + /* dynamically correct text alignment */ + pos->width = size * getFontWidth(font); +#endif + + DrawTextExt(drawto, PANEL_XPOS(pos), PANEL_YPOS(pos), + int2str(value, size), font, mask_mode); } else if (type == TYPE_ELEMENT) { + int element, graphic; + Bitmap *src_bitmap; + int src_x, src_y; + int width, height; int dst_x = PANEL_XPOS(pos); int dst_y = PANEL_YPOS(pos); +#if 1 + if (value != EL_UNDEFINED && value != EL_EMPTY) + { + element = value; + graphic = el2panelimg(value); + + // printf("::: %d, '%s' [%d]\n", element, EL_NAME(element), size); + +#if 1 + if (element >= EL_GRAPHIC_1 && element <= EL_GRAPHIC_8 && size == 0) + size = TILESIZE; +#endif + + getSizedGraphicSource(graphic, frame, size, &src_bitmap, + &src_x, &src_y); + + width = graphic_info[graphic].width * size / TILESIZE; + height = graphic_info[graphic].height * size / TILESIZE; + + if (draw_masked) + { + SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc, + dst_x - src_x, dst_y - src_y); + BlitBitmapMasked(src_bitmap, drawto, src_x, src_y, width, height, + dst_x, dst_y); + } + else + { + BlitBitmap(src_bitmap, drawto, src_x, src_y, width, height, + dst_x, dst_y); + } + } +#else if (value == EL_UNDEFINED || value == EL_EMPTY) { - int src_x = DOOR_GFX_PAGEX5 + ALIGNED_TEXT_XPOS(pos); - int src_y = DOOR_GFX_PAGEY1 + ALIGNED_TEXT_YPOS(pos); + element = (last_value == EL_UNDEFINED ? EL_EMPTY : last_value); + graphic = el2panelimg(element); - BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, src_x, src_y, - size, size, dst_x, dst_y); + src_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap; + src_x = DOOR_GFX_PAGEX5 + ALIGNED_TEXT_XPOS(pos); + src_y = DOOR_GFX_PAGEY1 + ALIGNED_TEXT_YPOS(pos); } else { - int graphic = el2panelimg(value); + element = value; + graphic = el2panelimg(value); - DrawSizedGraphicExt(drawto, dst_x, dst_y, graphic, frame, size); + getSizedGraphicSource(graphic, frame, size, &src_bitmap, &src_x,&src_y); } + + width = graphic_info[graphic].width * size / TILESIZE; + height = graphic_info[graphic].height * size / TILESIZE; + + BlitBitmap(src_bitmap, drawto, src_x, src_y, width, height, dst_x, dst_y); +#endif } else if (type == TYPE_STRING) { @@ -2134,6 +2606,7 @@ void DisplayGameControlValues() { int font1 = pos->font; /* (used for normal state) */ int font2 = pos->font_alt; /* (used for active state) */ +#if 0 int size1 = strlen(state_normal); int size2 = strlen(state_active); int width1 = size1 * getFontWidth(font1); @@ -2146,27 +2619,30 @@ void DisplayGameControlValues() /* clear background for values that may have changed its size */ ClearRectangleOnBackground(drawto, PANEL_XPOS(pos), PANEL_YPOS(pos), max_width, max_height); +#endif font = (active ? font2 : font1); } -#if 1 - /* as with numbers, don't truncate output if "chars" is zero or less */ - size = (size > 0 ? size : strlen(s)); -#endif - if (s != NULL) { - char *s_cut = getStringCopyN(s, size); + char *s_cut; -#if 0 - /* (not needed anymore with above correction of "size" value) */ - size = strlen(s_cut); /* string size may be smaller than "chars" */ +#if 1 + if (size <= 0) + { + /* don't truncate output if "chars" is zero or less */ + size = strlen(s); + + /* dynamically correct text alignment */ + pos->width = size * getFontWidth(font); + } #endif - pos->width = size * getFontWidth(font); + s_cut = getStringCopyN(s, size); - DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), s_cut, font); + DrawTextExt(drawto, PANEL_XPOS(pos), PANEL_YPOS(pos), + s_cut, font, mask_mode); free(s_cut); } @@ -2861,6 +3337,7 @@ static void InitGameEngine() { ei->change_page[j].actual_trigger_element = EL_EMPTY; ei->change_page[j].actual_trigger_player = EL_PLAYER_1; + ei->change_page[j].actual_trigger_player_bits = CH_PLAYER_1; ei->change_page[j].actual_trigger_side = CH_SIDE_NONE; ei->change_page[j].actual_trigger_ce_value = 0; ei->change_page[j].actual_trigger_ce_score = 0; @@ -3225,6 +3702,8 @@ void InitGame() player->LevelSolved_PanelOff = FALSE; player->LevelSolved_SaveTape = FALSE; player->LevelSolved_SaveScore = FALSE; + player->LevelSolved_CountingTime = 0; + player->LevelSolved_CountingScore = 0; } network_player_action_received = FALSE; @@ -3340,6 +3819,8 @@ void InitGame() emulate_sp = FALSE; InitField(x, y, TRUE); + + ResetGfxAnimation(x, y); } InitBeltMovement(); @@ -3647,8 +4128,10 @@ void InitGame() local_player->jy - MIDPOSY); } +#if 0 /* do not use PLAYING mask for fading out from main screen */ game_status = GAME_MODE_MAIN; +#endif StopAnimation(); @@ -3674,7 +4157,9 @@ void InitGame() FadeOut(REDRAW_FIELD); #endif +#if 0 game_status = GAME_MODE_PLAYING; +#endif /* !!! FIX THIS (START) !!! */ if (level.game_engine_type == GAME_ENGINE_TYPE_EM) @@ -3978,6 +4463,9 @@ static void PlayerWins(struct PlayerInfo *player) player->score_final = (level.game_engine_type == GAME_ENGINE_TYPE_EM ? level.native_em_level->lev->score : player->score); + + player->LevelSolved_CountingTime = (level.time == 0 ? TimePlayed : TimeLeft); + player->LevelSolved_CountingScore = player->score_final; } void GameWon() @@ -4033,6 +4521,9 @@ void GameWon() score = score_final; #if 1 + local_player->LevelSolved_CountingTime = time; + local_player->LevelSolved_CountingScore = score; + game_panel_controls[GAME_PANEL_TIME].value = time; game_panel_controls[GAME_PANEL_SCORE].value = score; @@ -4115,6 +4606,9 @@ void GameWon() score += time_count_steps * level.score[SC_TIME_BONUS]; #if 1 + local_player->LevelSolved_CountingTime = time; + local_player->LevelSolved_CountingScore = score; + game_panel_controls[GAME_PANEL_TIME].value = time; game_panel_controls[GAME_PANEL_SCORE].value = score; @@ -9527,11 +10021,15 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page) action_mode, action_arg_number, action_arg_number_min, action_arg_number_max); +#if 1 + int trigger_player_bits = change->actual_trigger_player_bits; +#else int trigger_player_bits = (change->actual_trigger_player >= EL_PLAYER_1 && change->actual_trigger_player <= EL_PLAYER_4 ? (1 << (change->actual_trigger_player - EL_PLAYER_1)) : PLAYER_BITS_ANY); +#endif int action_arg_player_bits = (action_arg >= CA_ARG_PLAYER_1 && @@ -10037,6 +10535,7 @@ static boolean ChangeElement(int x, int y, int element, int page) /* reset actual trigger element, trigger player and action element */ change->actual_trigger_element = EL_EMPTY; change->actual_trigger_player = EL_PLAYER_1; + change->actual_trigger_player_bits = CH_PLAYER_1; change->actual_trigger_side = CH_SIDE_NONE; change->actual_trigger_ce_value = 0; change->actual_trigger_ce_score = 0; @@ -10417,7 +10916,8 @@ static boolean CheckTriggeredElementChangeExt(int trigger_x, int trigger_y, IS_EQUAL_OR_IN_GROUP(trigger_element, change->trigger_element)) { change->actual_trigger_element = trigger_element; - change->actual_trigger_player = EL_PLAYER_1 + log_2(trigger_player); + change->actual_trigger_player = GET_PLAYER_FROM_BITS(trigger_player); + change->actual_trigger_player_bits = trigger_player; change->actual_trigger_side = trigger_side; change->actual_trigger_ce_value = CustomValue[trigger_x][trigger_y]; change->actual_trigger_ce_score = GET_CE_SCORE(trigger_element); @@ -10536,7 +11036,8 @@ static boolean CheckElementChangeExt(int x, int y, IS_EQUAL_OR_IN_GROUP(trigger_element, change->trigger_element))) { change->actual_trigger_element = trigger_element; - change->actual_trigger_player = EL_PLAYER_1 + log_2(trigger_player); + change->actual_trigger_player = GET_PLAYER_FROM_BITS(trigger_player); + change->actual_trigger_player_bits = trigger_player; change->actual_trigger_side = trigger_side; change->actual_trigger_ce_value = CustomValue[x][y]; change->actual_trigger_ce_score = GET_CE_SCORE(trigger_element); @@ -15311,6 +15812,7 @@ void CreateGameButtons() GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y1, GDI_ALT_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y2, GDI_ALT_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2, + GDI_DIRECT_DRAW, FALSE, GDI_EVENT_MASK, event_mask, GDI_CALLBACK_ACTION, HandleGameButtons, GDI_END); @@ -15346,6 +15848,14 @@ void UnmapGameButtons() UnmapGadget(game_gadget[i]); } +void RedrawGameButtons() +{ + int i; + + for (i = 0; i < NUM_GAME_BUTTONS; i++) + RedrawGadget(game_gadget[i]); +} + static void HandleGameButtons(struct GadgetInfo *gi) { int id = gi->custom_id;