static void draw_player_name( void) { struct player_data *player= get_player_data(current_player_index); screen_rectangle *player_name_rect= get_interface_rectangle(_player_name_rect); _draw_screen_text(player->name, player_name_rect, _center_vertical | _center_horizontal, _player_name_font, player->color+PLAYER_COLOR_BASE_INDEX); }
static void draw_inventory_item( char *text, short count, short offset, boolean erase_first, boolean valid_in_this_environment) { screen_rectangle destination, text_destination; char count_text[10]; short color; calculate_inventory_rectangle_from_offset(&destination, offset); /* Select the color for the text.. */ color= (valid_in_this_environment) ? (_inventory_text_color) : (_invalid_weapon_color); /* Erase on items that changed only in count.. */ if(erase_first) { _fill_rect(&destination, _inventory_background_color); } else { /* Unfortunately, we must always erase the numbers.. */ text_destination= destination; text_destination.right= text_destination.left+NAME_OFFSET+TEXT_INSET; _fill_rect(&text_destination, _inventory_background_color); } /* Draw the text name.. */ text_destination= destination; text_destination.left+= NAME_OFFSET+TEXT_INSET; _draw_screen_text(text, &text_destination, _center_vertical, _interface_font, color); /* Draw the text count-> Change the font!! */ text_destination= destination; text_destination.left+= TEXT_INSET; sprintf(count_text, "%3d", count); _draw_screen_text(count_text, &text_destination, _center_vertical, _interface_item_count_font, color); }
/* far left. Headers also have their backgrounds erased first */ static void draw_inventory_header( char *text, short offset) { screen_rectangle destination; calculate_inventory_rectangle_from_offset(&destination, offset); /* Erase.. */ _fill_rect(&destination, _inventory_header_background_color); /* Now draw the text. */ destination.left+= TEXT_INSET; _draw_screen_text(text, &destination, _center_vertical, _interface_font, _inventory_text_color); return; }
/* This should probably go to a gworld first, or something */ static void update_inventory_panel( boolean force_redraw) { short section_items[NUMBER_OF_ITEMS]; short section_counts[NUMBER_OF_ITEMS]; short section_count, loop; short item_type, current_row; if(INVENTORY_IS_DIRTY(current_player) || force_redraw) { screen_rectangle *destination= get_interface_rectangle(_inventory_rect); screen_rectangle text_rectangle; short total_inventory_line_count= count_inventory_lines(current_player_index); short max_lines= max_displayable_inventory_lines(); /* Recalculate and redraw.. */ item_type= GET_CURRENT_INVENTORY_SCREEN(current_player); /* Reset the row.. */ current_row= 0; if(item_type!=_network_statistics) { /* Get the types and names */ calculate_player_item_array(current_player_index, item_type, section_items, section_counts, §ion_count); } /* Draw the header. */ get_header_name(temporary, item_type); draw_inventory_header(temporary, current_row++); /* Draw the network time elapsed if timed game. */ if (item_type==_network_statistics && dynamic_world->game_information.game_time_remaining<60*60*TICKS_PER_SECOND) { long seconds= dynamic_world->game_information.game_time_remaining/TICKS_PER_SECOND; screen_rectangle destination; sprintf(temporary, "% 2d:%02d", seconds/60, seconds%60); calculate_inventory_rectangle_from_offset(&destination, current_row-1); destination.top -= 2; //<6/17/96 AMR> Sick hack destination.bottom -= 2; /* Now draw the text. */ destination.left+= TEXT_INSET; _draw_screen_text(temporary, &destination, _right_justified, _interface_font, _inventory_text_color); } /* Erase the panel.. */ text_rectangle= *destination; text_rectangle.top+= _get_font_line_height(_interface_font); _fill_rect(&text_rectangle, _inventory_background_color); if(item_type==_network_statistics) { struct player_ranking_data rankings[MAXIMUM_NUMBER_OF_PLAYERS]; calculate_player_rankings(rankings); /* Calculate the network statistics. */ for(loop= 0; loop<dynamic_world->player_count; ++loop) { screen_rectangle dest_rect; struct player_data *player= get_player_data(rankings[loop].player_index); short width; calculate_inventory_rectangle_from_offset(&dest_rect, current_row++); calculate_ranking_text(temporary, rankings[loop].ranking); /* Draw the player name.. */ width= _text_width(temporary, _interface_font); dest_rect.right-= width; dest_rect.left+= TEXT_INSET; _draw_screen_text(player->name, &dest_rect, _center_vertical, _interface_font, PLAYER_COLOR_BASE_INDEX+player->color); /* Now draw the ranking_text */ dest_rect.right+= width; dest_rect.left= dest_rect.right-width; _draw_screen_text(temporary, &dest_rect, _center_vertical, _interface_font, PLAYER_COLOR_BASE_INDEX+player->color); } } else { /* Draw the items. */ for(loop= 0; loop<section_count && current_row<max_lines; ++loop) { boolean valid_in_this_environment; /* Draw the item */ get_item_name(temporary, section_items[loop], (section_counts[loop]!=1)); valid_in_this_environment= item_valid_in_current_environment(section_items[loop]); draw_inventory_item(temporary, section_counts[loop], current_row++, FALSE, valid_in_this_environment); } } SET_INVENTORY_DIRTY_STATE(current_player, FALSE); } return; }
/* A change of weapon has occurred, change the weapon display panel */ static void update_weapon_panel( boolean force_redraw) { if(force_redraw || interface_state.weapon_is_dirty) { char weapon_name[90]; struct weapon_interface_data *definition; screen_rectangle *destination= get_interface_rectangle(_weapon_display_rect); screen_rectangle source; short desired_weapon= get_player_desired_weapon(current_player_index); /* Now we have to erase, because the panel won't do it for us.. */ _fill_rect(destination, _inventory_background_color); if(desired_weapon != NONE) { assert(desired_weapon>=0 && desired_weapon<MAXIMUM_WEAPON_INTERFACE_DEFINITIONS); definition= weapon_interface_definitions+desired_weapon; /* Check if it is a multi weapon - actually special cased for the magnum... */ if(definition->multi_weapon) { #define MAGNUM_DELTA_X 97 if(definition->item_id==_i_magnum) { /* Either way, draw the single */ _draw_screen_shape_at_x_y(definition->weapon_panel_shape, definition->standard_weapon_panel_left, definition->standard_weapon_panel_top); if(current_player->items[definition->item_id]>1) { _draw_screen_shape_at_x_y( BUILD_DESCRIPTOR(_collection_interface, _left_magnum), definition->standard_weapon_panel_left-MAGNUM_DELTA_X, definition->standard_weapon_panel_top); } else { /* Draw the empty one.. */ _draw_screen_shape_at_x_y( BUILD_DESCRIPTOR(_collection_interface, _left_magnum_unusable), definition->standard_weapon_panel_left-MAGNUM_DELTA_X, definition->standard_weapon_panel_top); } } else if(definition->item_id==_i_shotgun) { if(current_player->items[definition->item_id]>1) { _draw_screen_shape_at_x_y( BUILD_DESCRIPTOR(_collection_interface, _double_shotgun), definition->standard_weapon_panel_left, definition->standard_weapon_panel_top-12); } else { _draw_screen_shape_at_x_y(definition->weapon_panel_shape, definition->standard_weapon_panel_left, definition->standard_weapon_panel_top); } } } else { /* Slam it to the screen! */ if(definition->weapon_panel_shape != NONE) { _draw_screen_shape_at_x_y(definition->weapon_panel_shape, definition->standard_weapon_panel_left, definition->standard_weapon_panel_top); } } /* Get the weapon name.. */ if(desired_weapon != _weapon_ball) { #define strWEAPON_NAME_LIST 137 getcstr(weapon_name, strWEAPON_NAME_LIST, desired_weapon); } else { short item_index; /* Which ball do they actually have? */ for(item_index= BALL_ITEM_BASE; item_index<BALL_ITEM_BASE+MAXIMUM_NUMBER_OF_PLAYERS; ++item_index) { if(current_player->items[item_index]>0) break; } assert(item_index != BALL_ITEM_BASE+MAXIMUM_NUMBER_OF_PLAYERS); get_item_name(weapon_name, item_index, FALSE); } /* Draw the weapon name.. */ source= *destination; source.top= definition->weapon_name_start_y; source.bottom= definition->weapon_name_end_y; if(definition->weapon_name_start_x != NONE) { source.left= definition->weapon_name_start_x; } if(definition->weapon_name_end_x != NONE) { source.right= definition->weapon_name_end_x; } _draw_screen_text(weapon_name, &source, _center_horizontal|_center_vertical|_wrap_text, _weapon_name_font, _inventory_text_color); /* And make sure that the ammo knows it needs to update */ interface_state.ammo_is_dirty= TRUE; } interface_state.weapon_is_dirty= FALSE; } }
void HUD_SW_Class::DrawText(const char *text, screen_rectangle *dest, short flags, short font_id, short text_color) { _draw_screen_text(text, dest, flags, font_id, text_color); }
/* This expects a cstring. Draws to the current port*/ void _draw_screen_text( char *text, screen_rectangle *destination, short flags, short font_id, short text_color) { TextSpec old_font; short x, y; RGBColor old_color, new_color; char text_to_draw[256]; assert(font_id>=0 && font_id<NUMBER_OF_INTERFACE_FONTS); GetFont(&old_font); SetFont(&interface_fonts.fonts[font_id]); GetForeColor(&old_color); _get_interface_color(text_color, &new_color); RGBForeColor(&new_color); /* Copy the text to draw.. */ strcpy(text_to_draw, text); /* Check for wrapping, and if it occurs, be recursive... */ if(flags & _wrap_text) { /*еее WHAT IS THE INTERNATIONALIZED WAY OF DETERMINING NON-PRINTING CHARACTERS? IE SPACES? */ short last_non_printing_character; short text_width; short count= 0; text_width= 0; last_non_printing_character= 0; count= 0; while(count<strlen(text_to_draw) && text_width<RECTANGLE_WIDTH(destination)) { text_width+= CharWidth(text_to_draw[count]); if(text_to_draw[count]==' ') last_non_printing_character= count; count++; } if(count!=strlen(text_to_draw)) { char remaining_text_to_draw[256]; screen_rectangle new_destination; /* If we ever have to wrap text, we can't also center vertically. Sorry */ flags &= ~_center_vertical; flags |= _top_justified; /* Pass the rest of it back in, recursively, on the next line.. */ BlockMove(&text_to_draw[last_non_printing_character+1], remaining_text_to_draw, strlen(&text_to_draw[last_non_printing_character+1])+1); new_destination= *destination; new_destination.top+= interface_fonts.line_spacing[font_id]; _draw_screen_text(remaining_text_to_draw, &new_destination, flags, font_id, text_color); /* now truncate our text to draw...*/ text_to_draw[last_non_printing_character]= 0; } } /* Handle the horizontal stuff. */ if(flags & _center_horizontal || flags & _right_justified) { short text_width; text_width= TextWidth(text_to_draw, 0, strlen(text_to_draw)); if(text_width>RECTANGLE_WIDTH(destination)) { short length; short trunc_code; /* Truncate the puppy.. */ x= destination->left; length= strlen(text); trunc_code= TruncText(RECTANGLE_WIDTH(destination), text_to_draw, &length, truncEnd); text_to_draw[length]= 0; /* Now recenter it.. */ text_width= TextWidth(text_to_draw, 0, strlen(text_to_draw)); if (flags & _center_horizontal) x= destination->left+(((destination->right-destination->left)-text_width)>>1); else
void _draw_screen_text(const char *text, screen_rectangle *destination, short flags, short font_id, short text_color) { int x, y; // Find font information assert(font_id >= 0 && font_id < NUMBER_OF_INTERFACE_FONTS); uint16 style = InterfaceFonts[font_id].Style; const font_info *font = InterfaceFonts[font_id].Info; if (font == NULL) return; // Get color SDL_Color color; _get_interface_color(text_color, &color); // Copy the text to draw char text_to_draw[256]; strncpy(text_to_draw, text, 256); text_to_draw[255] = 0; // Check for wrapping, and if it occurs, be recursive if (flags & _wrap_text) { int last_non_printing_character = 0, text_width = 0; unsigned count = 0; while (count < strlen(text_to_draw) && text_width < RECTANGLE_WIDTH(destination)) { text_width += char_width(text_to_draw[count], font, style); if (text_to_draw[count] == ' ') last_non_printing_character = count; count++; } if( count != strlen(text_to_draw)) { char remaining_text_to_draw[256]; screen_rectangle new_destination; // If we ever have to wrap text, we can't also center vertically. Sorry. flags &= ~_center_vertical; flags |= _top_justified; // Pass the rest of it back in, recursively, on the next line memcpy(remaining_text_to_draw, text_to_draw + last_non_printing_character + 1, strlen(text_to_draw + last_non_printing_character + 1) + 1); new_destination = *destination; new_destination.top += InterfaceFonts[font_id].LineSpacing; _draw_screen_text(remaining_text_to_draw, &new_destination, flags, font_id, text_color); // Now truncate our text to draw text_to_draw[last_non_printing_character] = 0; } } // Truncate text if necessary int t_width = text_width(text_to_draw, font, style); if (t_width > RECTANGLE_WIDTH(destination)) { text_to_draw[trunc_text(text_to_draw, RECTANGLE_WIDTH(destination), font, style)] = 0; t_width = text_width(text_to_draw, font, style); } // Horizontal positioning if (flags & _center_horizontal) x = destination->left + (((destination->right - destination->left) - t_width) / 2); else if (flags & _right_justified) x = destination->right - t_width; else x = destination->left; // Vertical positioning int t_height = InterfaceFonts[font_id].Height; if (flags & _center_vertical) { if (t_height > RECTANGLE_HEIGHT(destination)) y = destination->top; else { y = destination->bottom; int offset = RECTANGLE_HEIGHT(destination) - t_height; y -= (offset / 2) + (offset & 1) + 1; } } else if (flags & _top_justified) { if (t_height > RECTANGLE_HEIGHT(destination)) y = destination->bottom; else y = destination->top + t_height; } else y = destination->bottom; // Now draw it draw_text(text_to_draw, x, y, SDL_MapRGB(draw_surface->format, color.r, color.g, color.b), font, style); }