X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame.c;h=3f6ec77b97628b366a671484bc2c9f203ebc4886;hb=531605e2e684de4c30a4e9927f9c5107f468b163;hp=f7cb0fe154c970a3e8484c50516e9c303abfc869;hpb=872cf2d86e73d185fcad1fac7b389e7d1dfcb839;p=rocksndiamonds.git diff --git a/src/game.c b/src/game.c index f7cb0fe1..3f6ec77b 100644 --- a/src/game.c +++ b/src/game.c @@ -200,27 +200,43 @@ #define GAME_PANEL_MAGIC_WALL 66 #define GAME_PANEL_MAGIC_WALL_TIME 67 #define GAME_PANEL_GRAVITY_STATE 68 -#define GAME_PANEL_CE_SCORE_1 69 -#define GAME_PANEL_CE_SCORE_2 70 -#define GAME_PANEL_CE_SCORE_3 71 -#define GAME_PANEL_CE_SCORE_4 72 -#define GAME_PANEL_CE_SCORE_5 73 -#define GAME_PANEL_CE_SCORE_6 74 -#define GAME_PANEL_CE_SCORE_7 75 -#define GAME_PANEL_CE_SCORE_8 76 -#define GAME_PANEL_CE_SCORE_1_ELEMENT 77 -#define GAME_PANEL_CE_SCORE_2_ELEMENT 78 -#define GAME_PANEL_CE_SCORE_3_ELEMENT 79 -#define GAME_PANEL_CE_SCORE_4_ELEMENT 80 -#define GAME_PANEL_CE_SCORE_5_ELEMENT 81 -#define GAME_PANEL_CE_SCORE_6_ELEMENT 82 -#define GAME_PANEL_CE_SCORE_7_ELEMENT 83 -#define GAME_PANEL_CE_SCORE_8_ELEMENT 84 -#define GAME_PANEL_PLAYER_NAME 85 -#define GAME_PANEL_LEVEL_NAME 86 -#define GAME_PANEL_LEVEL_AUTHOR 87 - -#define NUM_GAME_PANEL_CONTROLS 88 +#define GAME_PANEL_ELEMENT_1 69 +#define GAME_PANEL_ELEMENT_2 70 +#define GAME_PANEL_ELEMENT_3 71 +#define GAME_PANEL_ELEMENT_4 72 +#define GAME_PANEL_ELEMENT_5 73 +#define GAME_PANEL_ELEMENT_6 74 +#define GAME_PANEL_ELEMENT_7 75 +#define GAME_PANEL_ELEMENT_8 76 +#define GAME_PANEL_CE_SCORE_1 77 +#define GAME_PANEL_CE_SCORE_2 78 +#define GAME_PANEL_CE_SCORE_3 79 +#define GAME_PANEL_CE_SCORE_4 80 +#define GAME_PANEL_CE_SCORE_5 81 +#define GAME_PANEL_CE_SCORE_6 82 +#define GAME_PANEL_CE_SCORE_7 83 +#define GAME_PANEL_CE_SCORE_8 84 +#define GAME_PANEL_CE_SCORE_1_ELEMENT 85 +#define GAME_PANEL_CE_SCORE_2_ELEMENT 86 +#define GAME_PANEL_CE_SCORE_3_ELEMENT 87 +#define GAME_PANEL_CE_SCORE_4_ELEMENT 88 +#define GAME_PANEL_CE_SCORE_5_ELEMENT 89 +#define GAME_PANEL_CE_SCORE_6_ELEMENT 90 +#define GAME_PANEL_CE_SCORE_7_ELEMENT 91 +#define GAME_PANEL_CE_SCORE_8_ELEMENT 92 +#define GAME_PANEL_PLAYER_NAME 93 +#define GAME_PANEL_LEVEL_NAME 94 +#define GAME_PANEL_LEVEL_AUTHOR 95 + +#define NUM_GAME_PANEL_CONTROLS 96 + +struct GamePanelOrderInfo +{ + int nr; + int sort_priority; +}; + +static struct GamePanelOrderInfo game_panel_order[NUM_GAME_PANEL_CONTROLS]; struct GamePanelControlInfo { @@ -232,6 +248,7 @@ struct GamePanelControlInfo int value, last_value; int frame, last_frame; int gfx_frame; + int gfx_random; }; static struct GamePanelControlInfo game_panel_controls[] = @@ -581,6 +598,46 @@ static struct GamePanelControlInfo game_panel_controls[] = &game.panel.gravity_state, TYPE_STRING, }, + { + 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_CE_SCORE_1, &game.panel.ce_score[0], @@ -861,6 +918,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); @@ -1892,6 +1951,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; @@ -1899,9 +1972,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) { @@ -1925,7 +1999,15 @@ 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 UpdateGameControlValues() @@ -2092,21 +2174,21 @@ void UpdateGameControlValues() game_panel_controls[GAME_PANEL_GRAVITY_STATE].value = game.gravity; #endif + 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_CE_SCORE; i++) - { - if (game.panel.ce_score[i].id != EL_UNDEFINED) - { - int ce_score = element_info[game.panel.ce_score[i].id].collect_score; + 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); - game_panel_controls[GAME_PANEL_CE_SCORE_1 + i].value = ce_score; - game_panel_controls[GAME_PANEL_CE_SCORE_1_ELEMENT + i].value = ce_score; - } - else - { - game_panel_controls[GAME_PANEL_CE_SCORE_1 + i].value = 0; - game_panel_controls[GAME_PANEL_CE_SCORE_1_ELEMENT + i].value = 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; @@ -2118,38 +2200,108 @@ void UpdateGameControlValues() 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; @@ -2158,9 +2310,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 || @@ -2179,6 +2328,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)) { @@ -2192,6 +2342,7 @@ void DisplayGameControlValues() ClearRectangleOnBackground(drawto, PANEL_XPOS(pos), PANEL_YPOS(pos), max_width, max_height); } +#endif } } @@ -2204,7 +2355,8 @@ void DisplayGameControlValues() pos->width = size * getFontWidth(font); #endif - DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, size), font); + DrawTextExt(drawto, PANEL_XPOS(pos), PANEL_YPOS(pos), + int2str(value, size), font, mask_mode); } else if (type == TYPE_ELEMENT) { @@ -2215,6 +2367,32 @@ void DisplayGameControlValues() 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); + + 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) { element = (last_value == EL_UNDEFINED ? EL_EMPTY : last_value); @@ -2236,6 +2414,7 @@ void DisplayGameControlValues() 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) { @@ -2252,6 +2431,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); @@ -2264,6 +2444,7 @@ 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); } @@ -2285,7 +2466,8 @@ void DisplayGameControlValues() 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); } @@ -3459,6 +3641,8 @@ void InitGame() emulate_sp = FALSE; InitField(x, y, TRUE); + + ResetGfxAnimation(x, y); } InitBeltMovement(); @@ -15430,6 +15614,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); @@ -15465,6 +15650,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;