/************************************************************************** Create a canvas of the given size. **************************************************************************/ struct canvas *canvas_create(int width, int height) { struct canvas *result = fc_malloc(sizeof(*result)); result->surf = create_surf(width, height, SDL_SWSURFACE); return result; }
d_surf * _surf_load_bmp(const char * filename, const char * surfname, REAL minz, REAL maxz, REAL startX, REAL startY, REAL stepX, REAL stepY) { writelog(LOG_MESSAGE, "loading surface from BMP file %s",filename); BMP bmp; if (bmp.ReadFromFile(filename) == false) { writelog(LOG_ERROR,"Error loading surface from bitmap!"); return NULL; } size_t NN = bmp.TellWidth(); size_t MM = bmp.TellHeight(); extvec * coeff = create_extvec( NN*MM, 0, 0, 0); size_t i,j; double gray_color; double alpha; for (j = 0; j < MM; j++) { for (i = 0; i < NN; i++) { gray_color = bmp(i,j)->Red * 0.299 + bmp(i,j)->Green * 0.587 + bmp(i,j)->Blue * 0.114; alpha = bmp(i,j)->Alpha; if (alpha == 255) (*coeff)(i + (MM-1-j)*NN) = undef_value; else { if (minz != maxz) (*coeff)(i + (MM-1-j)*NN) = (maxz-minz)*gray_color/REAL(255) + minz; else (*coeff)(i + (MM-1-j)*NN) = gray_color; } } } d_grid * grd = create_grid(startX, startX + stepX*(NN-1), stepX, startY, startY + stepY*(MM-1), stepY); d_surf * res = create_surf(coeff, grd); if (surfname) res->setName(surfname); else { char * name = get_name(filename); res->setName(name); sstuff_free_char(name); } return res; };
/* ==================================================================== Load terrain types, weather information and hex tile icons. ==================================================================== */ int terrain_load( char *fname ) { int i, j, k; PData *pd, *sub, *subsub, *subsubsub; List *entries, *flags; char path[512], transitionPath[512]; char *flag, *str; char *domain = 0; int count; /* log info */ int log_dot_limit = 40; /* maximum of dots */ char log_str[128]; sprintf( transitionPath, "Scenario/%s", fname ); search_file_name_exact( path, transitionPath, config.mod_name ); if ( ( pd = parser_read_file( fname, path ) ) == 0 ) goto parser_failure; // domain = determine_domain(pd, fname); // locale_load_domain(domain, 0/*FIXME*/); /* get weather */ if ( !parser_get_entries( pd, "weather", &entries ) ) goto parser_failure; weather_type_count = entries->count; weather_types = calloc( weather_type_count, sizeof( Weather_Type ) ); list_reset( entries ); i = 0; while ( ( sub = list_next( entries ) ) ) { weather_types[i].id = strdup( sub->name ); // if ( !parser_get_localized_string( sub, "name", domain, &weather_types[i].name ) ) goto parser_failure; if ( !parser_get_value( sub, "name", &str, 0 ) ) goto parser_failure; weather_types[i].name = strdup( str ); if ( !parser_get_value( sub, "ground_cond", &str, 0 ) ) goto parser_failure; weather_types[i].ground_conditions = strdup( str ); if ( !parser_get_values( sub, "flags", &flags ) ) goto parser_failure; list_reset( flags ); while ( ( flag = list_next( flags ) ) ) weather_types[i].flags |= check_flag( flag, fct_terrain ); i++; } /* hex tile geometry */ if ( !parser_get_int( pd, "hex_width", &hex_w ) ) goto parser_failure; if ( !parser_get_int( pd, "hex_height", &hex_h ) ) goto parser_failure; if ( !parser_get_int( pd, "hex_x_offset", &hex_x_offset ) ) goto parser_failure; if ( !parser_get_int( pd, "hex_y_offset", &hex_y_offset ) ) goto parser_failure; /* terrain icons */ terrain_icons = calloc( 1, sizeof( Terrain_Icons ) ); if ( !parser_get_value( pd, "fog", &str, 0 ) ) goto parser_failure; sprintf( transitionPath, "Graphics/%s", str ); search_file_name_exact( path, transitionPath, config.mod_name ); if ( ( terrain_icons->fog = load_surf( path, SDL_SWSURFACE, 0, 0, 0, 0 ) ) == 0 ) goto failure; if ( !parser_get_value( pd, "danger", &str, 0 ) ) goto parser_failure; sprintf( transitionPath, "Graphics/%s", str ); search_file_name_exact( path, transitionPath, config.mod_name ); if ( ( terrain_icons->danger = load_surf( path, SDL_SWSURFACE, 0, 0, 0, 0 ) ) == 0 ) goto failure; if ( !parser_get_value( pd, "grid", &str, 0 ) ) goto parser_failure; sprintf( transitionPath, "Graphics/%s", str ); search_file_name_exact( path, transitionPath, config.mod_name ); if ( ( terrain_icons->grid = load_surf( path, SDL_SWSURFACE, 0, 0, 0, 0 ) ) == 0 ) goto failure; if ( !parser_get_value( pd, "frame", &str, 0 ) ) goto parser_failure; sprintf( transitionPath, "Graphics/%s", str ); search_file_name_exact( path, transitionPath, config.mod_name ); if ( ( terrain_icons->select = load_surf( path, SDL_SWSURFACE, 0, 0, 0, 0 ) ) == 0 ) goto failure; if ( !parser_get_value( pd, "crosshair", &str, 0 ) ) goto parser_failure; sprintf( transitionPath, "Graphics/%s", str ); search_file_name_exact( path, transitionPath, config.mod_name ); if ( ( terrain_icons->cross = anim_create( load_surf( path, SDL_SWSURFACE, 0, 0, 0, 0 ), 1000/config.anim_speed, hex_w, hex_h, sdl.screen, 0, 0 ) ) == 0 ) goto failure; anim_hide( terrain_icons->cross, 1 ); if ( !parser_get_value( pd, "explosion", &str, 0 ) ) goto parser_failure; sprintf( transitionPath, "Graphics/%s", str ); search_file_name_exact( path, transitionPath, config.mod_name ); if ( ( terrain_icons->expl1 = anim_create( load_surf( path, SDL_SWSURFACE, 0, 0, 0, 0 ), 50/config.anim_speed, hex_w, hex_h, sdl.screen, 0, 0 ) ) == 0 ) goto failure; anim_hide( terrain_icons->expl1, 1 ); if ( ( terrain_icons->expl2 = anim_create( load_surf( path, SDL_SWSURFACE, 0, 0, 0, 0 ), 50/config.anim_speed, hex_w, hex_h, sdl.screen, 0, 0 ) ) == 0 ) goto failure; anim_hide( terrain_icons->expl2, 1 ); /* terrain sounds */ #ifdef WITH_SOUND if ( parser_get_value( pd, "explosion_sound", &str, 0 ) ) { snprintf( transitionPath, 512, "Sound/%s", str ); search_file_name_exact( path, transitionPath, config.mod_name ); terrain_icons->wav_expl = wav_load( path, 2 ); } if ( parser_get_value( pd, "select_sound", &str, 0 ) ) { snprintf( transitionPath, 512, "Sound/%s", str ); search_file_name_exact( path, transitionPath, config.mod_name ); terrain_icons->wav_select = wav_load( path, 1 ); } #endif /* terrain data image columns */ if ( !parser_get_int( pd, "terrain_columns", &terrain_columns ) ) goto parser_failure; /* terrain data image rows */ if ( !parser_get_int( pd, "terrain_rows", &terrain_rows ) ) goto parser_failure; /* each ground condition type got its own image -- if it's named 'default' we point towards the image of weather_type 0 */ terrain_images = calloc( 1, sizeof( Terrain_Images ) ); terrain_images->images = calloc( weather_type_count / 4, sizeof( SDL_Surface* ) ); for ( j = 0; j < weather_type_count / 4; j++ ) { terrain_images->ground_conditions = strdup( weather_types[4*j].ground_conditions ); sprintf( path, "image/%s", weather_types[4*j].ground_conditions ); if ( !parser_get_value( pd, path, &str, 0 ) ) goto parser_failure; if ( STRCMP( "default", str ) && j > 0 ) { /* just a pointer */ terrain_images->images[j] = terrain_images->images[0]; } else { sprintf( transitionPath, "Graphics/%s", str ); search_file_name_exact( path, transitionPath, config.mod_name ); if ( ( terrain_images->images[j] = load_surf( path, SDL_SWSURFACE, 0, 0, 0, 0 ) ) == 0 ) goto parser_failure; SDL_SetColorKey( terrain_images->images[j], SDL_SRCCOLORKEY, get_pixel( terrain_images->images[j], 0, 0 ) ); } } /* fog image */ terrain_images->images_fogged = calloc( weather_type_count / 4, sizeof( SDL_Surface* ) ); for ( j = 0; j < weather_type_count / 4; j++ ) { if ( terrain_images->images[j] == terrain_images->images[0] && j > 0 ) { /* just a pointer */ terrain_images->images_fogged[j] = terrain_images->images_fogged[0]; } else { terrain_images->images_fogged[j] = create_surf( terrain_images->images[j]->w, terrain_images->images[j]->h, SDL_SWSURFACE ); FULL_DEST( terrain_images->images_fogged[j] ); FULL_SOURCE( terrain_images->images[j] ); blit_surf(); count = terrain_images->images[j]->w / hex_w; for ( i = 0; i < terrain_rows; i++ ) for ( k = 0; k < terrain_columns; k++ ) { DEST( terrain_images->images_fogged[j], k * hex_w, i * hex_h, hex_w, hex_h ); SOURCE( terrain_icons->fog, 0, 0 ); alpha_blit_surf( FOG_ALPHA ); } SDL_SetColorKey( terrain_images->images_fogged[j], SDL_SRCCOLORKEY, get_pixel( terrain_images->images_fogged[j], 0, 0 ) ); } } /* terrain types */ if ( !parser_get_entries( pd, "terrain", &entries ) ) goto parser_failure; terrain_type_count = entries->count; terrain_types = calloc( terrain_type_count, sizeof( Terrain_Type ) ); list_reset( entries ); i = 0; while ( ( sub = list_next( entries ) ) ) { /* id */ terrain_types[i].id = sub->name[0]; /* name */ if ( !parser_get_localized_string( sub, "name", domain, &terrain_types[i].name ) ) goto parser_failure; /* spot cost */ terrain_types[i].spt = calloc( weather_type_count, sizeof( int ) ); if ( !parser_get_pdata( sub, "spot_cost", &subsub ) ) goto parser_failure; for ( j = 0; j < weather_type_count; j++ ) if ( !parser_get_int( subsub, weather_types[j].id, &terrain_types[i].spt[j] ) ) goto parser_failure; /* image */ terrain_types[i].images = terrain_images->images; /* fog image */ terrain_types[i].images_fogged = terrain_images->images_fogged; /* mov cost */ terrain_types[i].mov = calloc( mov_type_count * weather_type_count, sizeof( int ) ); if ( !parser_get_pdata( sub, "move_cost", &subsub ) ) goto parser_failure; for ( k = 0; k < mov_type_count; k++ ) { if ( !parser_get_pdata( subsub, mov_types[k].id, &subsubsub ) ) goto parser_failure; for ( j = 0; j < weather_type_count; j++ ) { if ( !parser_get_value( subsubsub, weather_types[j].id, &str, 0 ) ) goto parser_failure; if ( str[0] == 'X' ) terrain_types[i].mov[j + k * weather_type_count] = 0; /* impassable */ else if ( str[0] == 'A' ) terrain_types[i].mov[j + k * weather_type_count] = -1; /* costs all */ else terrain_types[i].mov[j + k * weather_type_count] = atoi( str ); /* normal cost */ } } /* entrenchment */ if ( !parser_get_int( sub, "min_entr", &terrain_types[i].min_entr ) ) goto parser_failure; if ( !parser_get_int( sub, "max_entr", &terrain_types[i].max_entr ) ) goto parser_failure; /* initiative modification */ if ( !parser_get_int( sub, "max_init", &terrain_types[i].max_ini ) ) goto parser_failure; /* flags */ terrain_types[i].flags = calloc( weather_type_count, sizeof( int ) ); if ( !parser_get_pdata( sub, "flags", &subsub ) ) goto parser_failure; for ( j = 0; j < weather_type_count; j++ ) { if ( !parser_get_values( subsub, weather_types[j].id, &flags ) ) goto parser_failure; list_reset( flags ); while ( ( flag = list_next( flags ) ) ) terrain_types[i].flags[j] |= check_flag( flag, fct_terrain ); } /* next terrain */ i++; /* LOG */ strcpy( log_str, " [ ]" ); for ( k = 0; k < i * log_dot_limit / entries->count; k++ ) log_str[3 + k] = '*'; write_text( log_font, sdl.screen, log_x, log_y, log_str, 255 ); SDL_UpdateRect( sdl.screen, log_font->last_x, log_font->last_y, log_font->last_width, log_font->last_height ); } parser_free( &pd ); /* LOG */ write_line( sdl.screen, log_font, log_str, log_x, &log_y ); refresh_screen( 0, 0, 0, 0 ); free(domain); return 1; parser_failure: fprintf( stderr, "%s\n", parser_get_error() ); failure: terrain_delete(); if ( pd ) parser_free( &pd ); free(domain); printf(tr("If data seems to be missing, please re-run the converter lgc-pg.\n")); return 0; }
/************************************************************************** ... **************************************************************************/ static SDL_Surface *create_str16_multi_surf(SDL_String16 * pString) { SDL_Rect des = {0, 0, 0, 0}; SDL_Surface *pText = NULL, **pTmp = NULL; Uint16 i, w = 0, count = 0; Uint32 color; Uint16 *pBuf = pString->text; Uint16 **UniTexts = create_new_line_unistrings(pString->text); while (UniTexts[count]) { count++; } pTmp = fc_calloc(count, sizeof(SDL_Surface *)); for (i = 0; i < count; i++) { pString->text = UniTexts[i]; pTmp[i] = create_str16_surf(pString); } pString->text = pBuf; /* find max len */ for (i = 0; i < count; i++) { if (pTmp[i]->w > w) { w = pTmp[i]->w; } } /* create and fill surface */ color = pTmp[0]->format->colorkey; switch (pString->render) { case 1: pText = create_surf(w, count * pTmp[0]->h, SDL_SWSURFACE); SDL_FillRect(pText, NULL, color); SDL_SetColorKey(pText, SDL_SRCCOLORKEY, color); break; case 2: pText = create_surf_with_format(pTmp[0]->format, w, count * pTmp[0]->h, pTmp[0]->flags); SDL_FillRect(pText, NULL, color); break; default: pText = create_surf(w, count * pTmp[0]->h, SDL_SWSURFACE); SDL_FillRect(pText, NULL, color); break; } /* blit (default: center left) */ for (i = 0; i < count; i++) { if (pString->style & SF_CENTER) { des.x = (w - pTmp[i]->w) / 2; } else { if (pString->style & SF_CENTER_RIGHT) { des.x = w - pTmp[i]->w; } else { des.x = 0; } } alphablit(pTmp[i], NULL, pText, &des); des.y += pTmp[i]->h; } /* Free Memmory */ for (i = 0; i < count; i++) { FC_FREE(UniTexts[i]); FREESURFACE(pTmp[i]); } FC_FREE(pTmp); return pText; }
/**************************************************************** Pops-up the Spy sabotage dialog, upon return of list of available improvements requested by the above function. *****************************************************************/ void popup_sabotage_dialog(struct city *pCity) { struct widget *pWindow = NULL, *pBuf = NULL , *pLast = NULL; struct CONTAINER *pCont; struct unit *pUnit = head_of_units_in_focus(); SDL_String16 *pStr; SDL_Rect area, area2; int n, w = 0, h, imp_h = 0; if (pDiplomat_Dlg || !pUnit || !unit_has_type_flag(pUnit, F_SPY)) { return; } is_unit_move_blocked = TRUE; pDiplomat_Dlg = fc_calloc(1, sizeof(struct diplomat_dialog)); pDiplomat_Dlg->diplomat_id = pUnit->id; pDiplomat_Dlg->diplomat_target_id = pCity->id; pDiplomat_Dlg->pdialog = fc_calloc(1, sizeof(struct ADVANCED_DLG)); pCont = fc_calloc(1, sizeof(struct CONTAINER)); pCont->id0 = pCity->id; pCont->id1 = pUnit->id;/* spy id */ pStr = create_str16_from_char(_("Select Improvement to Sabotage") , adj_font(12)); pStr->style |= TTF_STYLE_BOLD; pWindow = create_window_skeleton(NULL, pStr, 0); pWindow->action = diplomat_dlg_window_callback; set_wstate(pWindow, FC_WS_NORMAL); add_to_gui_list(ID_TERRAIN_ADV_DLG_WINDOW, pWindow); pDiplomat_Dlg->pdialog->pEndWidgetList = pWindow; area = pWindow->area; area.h = MAX(area.h, adj_size(2)); /* ---------- */ /* exit button */ pBuf = create_themeicon(pTheme->Small_CANCEL_Icon, pWindow->dst, WF_WIDGET_HAS_INFO_LABEL | WF_RESTORE_BACKGROUND); pBuf->info_label = create_str16_from_char(_("Close Dialog (Esc)"), adj_font(12)); area.w += pBuf->size.w + adj_size(10); pBuf->action = diplomat_close_callback; set_wstate(pBuf, FC_WS_NORMAL); pBuf->key = SDLK_ESCAPE; add_to_gui_list(ID_TERRAIN_ADV_DLG_EXIT_BUTTON, pBuf); /* ---------- */ create_active_iconlabel(pBuf, pWindow->dst, pStr, _("City Production"), sabotage_impr_callback); pBuf->data.cont = pCont; set_wstate(pBuf, FC_WS_NORMAL); set_wflag(pBuf, WF_FREE_DATA); add_to_gui_list(MAX_ID - 1000, pBuf); area.w = MAX(area.w, pBuf->size.w); area.h += pBuf->size.h; /* separator */ pBuf = create_iconlabel(NULL, pWindow->dst, NULL, WF_FREE_THEME); add_to_gui_list(ID_SEPARATOR, pBuf); area.h += pBuf->next->size.h; /* ------------------ */ n = 0; city_built_iterate(pCity, pImprove) { if (pImprove->sabotage > 0) { create_active_iconlabel(pBuf, pWindow->dst, pStr, (char *) city_improvement_name_translation(pCity, pImprove), sabotage_impr_callback); pBuf->data.cont = pCont; set_wstate(pBuf , FC_WS_NORMAL); add_to_gui_list(MAX_ID - improvement_number(pImprove), pBuf); area.w = MAX(area.w , pBuf->size.w); imp_h += pBuf->size.h; if (!pDiplomat_Dlg->pdialog->pEndActiveWidgetList) { pDiplomat_Dlg->pdialog->pEndActiveWidgetList = pBuf; } if (improvement_number(pImprove) > 9) { set_wflag(pBuf, WF_HIDDEN); } n++; /* ----------- */ } } city_built_iterate_end; pDiplomat_Dlg->pdialog->pBeginActiveWidgetList = pBuf; if (n > 0) { /* separator */ pBuf = create_iconlabel(NULL, pWindow->dst, NULL, WF_FREE_THEME); add_to_gui_list(ID_SEPARATOR, pBuf); area.h += pBuf->next->size.h; /* ------------------ */ } create_active_iconlabel(pBuf, pWindow->dst, pStr, _("At Spy's Discretion"), sabotage_impr_callback); pBuf->data.cont = pCont; set_wstate(pBuf, FC_WS_NORMAL); add_to_gui_list(MAX_ID - B_LAST, pBuf); area.w = MAX(area.w, pBuf->size.w); area.h += pBuf->size.h; /* ----------- */ pLast = pBuf; pDiplomat_Dlg->pdialog->pBeginWidgetList = pLast; pDiplomat_Dlg->pdialog->pActiveWidgetList = pDiplomat_Dlg->pdialog->pEndActiveWidgetList; /* ---------- */ if (n > 10) { imp_h = 10 * pBuf->size.h; n = create_vertical_scrollbar(pDiplomat_Dlg->pdialog, 1, 10, TRUE, TRUE); area.w += n; } /* ---------- */ area.h += imp_h; resize_window(pWindow, NULL, NULL, (pWindow->size.w - pWindow->area.w) + area.w, (pWindow->size.h - pWindow->area.h) + area.h); area = pWindow->area; auto_center_on_focus_unit(); put_window_near_map_tile(pWindow, pWindow->size.w, pWindow->size.h, pUnit->tile); w = area.w; if (pDiplomat_Dlg->pdialog->pScroll) { w -= n; imp_h = pBuf->size.w; } else { imp_h = 0; } /* exit button */ pBuf = pWindow->prev; pBuf->size.x = area.x + area.w - pBuf->size.w - 1; pBuf->size.y = pWindow->size.y + adj_size(2); /* Production sabotage */ pBuf = pBuf->prev; pBuf->size.x = area.x; pBuf->size.y = area.y + 1; pBuf->size.w = w; h = pBuf->size.h; area2.x = adj_size(10); area2.h = adj_size(2); pBuf = pBuf->prev; while(pBuf) { if (pBuf == pDiplomat_Dlg->pdialog->pEndActiveWidgetList) { w -= imp_h; } pBuf->size.w = w; pBuf->size.x = pBuf->next->size.x; pBuf->size.y = pBuf->next->size.y + pBuf->next->size.h; if (pBuf->ID == ID_SEPARATOR) { FREESURFACE(pBuf->theme); pBuf->size.h = h; pBuf->theme = create_surf(w, h, SDL_SWSURFACE); area2.y = pBuf->size.h / 2 - 1; area2.w = pBuf->size.w - adj_size(20); SDL_FillRect(pBuf->theme , &area2, map_rgba(pBuf->theme->format, *get_game_colorRGB(COLOR_THEME_SABOTAGEDLG_SEPARATOR))); } if (pBuf == pLast) { break; } pBuf = pBuf->prev; } if (pDiplomat_Dlg->pdialog->pScroll) { setup_vertical_scrollbar_area(pDiplomat_Dlg->pdialog->pScroll, area.x + area.w, pDiplomat_Dlg->pdialog->pEndActiveWidgetList->size.y, area.y - pDiplomat_Dlg->pdialog->pEndActiveWidgetList->size.y + area.h, TRUE); } /* -------------------- */ /* redraw */ redraw_group(pDiplomat_Dlg->pdialog->pBeginWidgetList, pWindow, 0); widget_flush(pWindow); }