Main Page | Data Structures | Directories | File List | Data Fields | Globals

pbar.c

Go to the documentation of this file.
00001 /* pbar.c: handles rate-of-change indicators 
00002  * This file is part of lincity.
00003  * Lincity is copyright (c) I J Peters 1995-1997, (c) Greg Sharp 1997-2001.
00004  * Portions copyright (c) 2001 Corey Keasling.
00005  * ---------------------------------------------------------------------- */
00006 #include "lcconfig.h"
00007 #include <math.h>
00008 #include "cliglobs.h"
00009 #include "lchelp.h"
00010 #include "mouse.h"
00011 #include "shrglobs.h"
00012 #include "pbar.h"
00013 #include "lin-city.h"
00014 #include "lclib.h"
00015 #include "stats.h"
00016 #include "engglobs.h"
00017 
00018 struct pbar_st pbars[NUM_PBARS];
00019 
00020 void
00021 init_pbars (void)
00022 {
00023     int i, p;
00024     for (p = 0; p < NUM_PBARS; p++) {
00025         pbars[p].data_size = 0;
00026         pbars[p].oldtot = 0;
00027         pbars[p].tot = 0;
00028         pbars[p].diff = 0;
00029         for (i = 0; i < PBAR_DATA_SIZE; i++)
00030             pbars[p].data[i] = 0;
00031     }
00032 
00033 }
00034 
00035 void
00036 pbars_full_refresh (void)
00037 {
00038     Rect* pba = &scr.pbar_area;
00039     draw_small_bezel (pba->x+4, pba->y+4, pba->w-8, pba->h-8, yellow(0));
00040     init_pbar_text ();
00041     draw_pbars ();
00042 }
00043 
00044 void
00045 init_pbar_text (void)
00046 {
00047     clear_pbar_text (&scr.pbar_pop);
00048     clear_pbar_text (&scr.pbar_tech);
00049     clear_pbar_text (&scr.pbar_food);
00050     clear_pbar_text (&scr.pbar_jobs);
00051     clear_pbar_text (&scr.pbar_money);
00052     clear_pbar_text (&scr.pbar_coal);
00053     clear_pbar_text (&scr.pbar_goods);
00054     clear_pbar_text (&scr.pbar_ore);
00055     clear_pbar_text (&scr.pbar_steel);
00056 }
00057 
00058 /* ---------------------------------------------------------------------- *
00059  * Pbar drawing function
00060  * ---------------------------------------------------------------------- */
00061 
00062 void 
00063 draw_pbar (Rect* b, char* graphic)
00064 /* XXX: WCK: why not just make the graphic include the black? */
00065 /* GCS: Good idea, but xpicedit is painful to use! */
00066 {
00067     Fgl_fillbox (b->x, b->y, b->w, b->h, 0);
00068     Fgl_putbox (b->x + (b->w / 2) - 8, b->y, 16, 16, graphic);
00069 }
00070 
00071 void
00072 draw_pbars (void)
00073 {
00074     draw_pbar (&scr.pbar_pop, pop_pbar_graphic);
00075     draw_pbar (&scr.pbar_tech, tech_pbar_graphic);
00076     draw_pbar (&scr.pbar_food, food_pbar_graphic);
00077     draw_pbar (&scr.pbar_jobs, jobs_pbar_graphic);
00078     draw_pbar (&scr.pbar_money, money_pbar_graphic);
00079     draw_pbar (&scr.pbar_coal, coal_pbar_graphic);
00080     draw_pbar (&scr.pbar_goods, goods_pbar_graphic);
00081     draw_pbar (&scr.pbar_ore, ore_pbar_graphic);
00082     draw_pbar (&scr.pbar_steel, steel_pbar_graphic);
00083 }
00084 
00085 /* Text functions */
00086 
00087 void
00088 clear_pbar_text (Rect* pbar)
00089 {
00090     Fgl_fillbox (pbar->x + pbar->w + 1, pbar->y, PBAR_TEXT_W, pbar->h, 0);
00091 }
00092 
00093 void 
00094 write_pbar_int (Rect* b, int val)
00095 {
00096     char s[16];
00097     format_number5 (s, pbars[val].data[pbars[val].data_size-1]);
00098     Fgl_setfontcolors (0, 255);
00099     Fgl_write (b->x + b->w + 25, b->y + 4, s);
00100     Fgl_setfontcolors (TEXT_BG_COLOUR, TEXT_FG_COLOUR);
00101 }
00102 
00103 void
00104 write_pbar_text (Rect* b, char * s)
00105 {
00106     Fgl_setfontcolors (0, 255); 
00107     Fgl_write (b->x + b->w + 25, b->y + 4, s);
00108     Fgl_setfontcolors (TEXT_BG_COLOUR, TEXT_FG_COLOUR);
00109 }
00110 
00111 /* XXX: WCK: Macros anyone? */
00112 /* GCS: I thought I might like to change the "sensitivity" of the pbars
00113    on a case-by-case basis, but never got around to it. */
00114 /* WCK: sure, but the preprocessor can still do some of the work, so: */
00115 /* GCS: The new macros look good.  I killed the old code. */
00116 
00117 #define pbar_adjust_pop(diff) 2 * diff
00118 #define pbar_adjust_tech(diff) diff > 0 ? diff / 4 + 1 : -((-diff+1)/ 2)
00119 #define pbar_adjust_food(diff) diff > 0 ? diff / 2 + 1 : diff
00120 #define pbar_adjust_jobs(diff) diff > 0 ? diff / 2 + 1 : diff
00121 #define pbar_adjust_coal(diff) diff > 0 ? diff / 2 + 1 : diff
00122 #define pbar_adjust_goods(diff) diff > 0 ? diff / 2 + 1 : diff
00123 #define pbar_adjust_ore(diff) diff > 0 ? diff / 2 + 1 : diff
00124 #define pbar_adjust_steel(diff) diff > 0 ? diff / 2 + 1 : diff
00125 #define pbar_adjust_money(diff) diff  > 0 ? diff / 800 + 1 : diff / 400 
00126 
00127 
00128 /* XXX: wck: write_pbar_* changes font colours every time its called; only
00129    need to do this once.  Maybe it should be folded in.*/
00130 
00131 void
00132 refresh_population_text (void)
00133 {
00134   /* GCS: This function is kind of a hack, but I need the population 
00135      to be refreshed immediately after the rocket is launched.
00136      Therefore, this function! */
00137     Rect * b;
00138     update_pbar (PPOP, housed_population + people_pool, 0);
00139     b = &scr.pbar_pop;
00140     write_pbar_int (b, PPOP);
00141 }
00142 
00143 void 
00144 refresh_pbars (void)
00145 {
00146     Rect * b;
00147     char s[10];
00148 
00149     /* Population */
00150     b = &scr.pbar_pop;
00151     draw_pbar_new (b, pbar_adjust_pop(pbars[PPOP].diff));
00152     write_pbar_int (b, PPOP);
00153 
00154     /* Technology */
00155     b = &scr.pbar_tech;
00156     draw_pbar_new (b, pbar_adjust_tech(pbars[PTECH].diff));
00157 
00158     snprintf (s, 10, "%5.1f", 
00159               (float) pbars[PTECH].data[pbars[PTECH].data_size - 1] * 
00160               100.0 / MAX_TECH_LEVEL);
00161 
00162     write_pbar_text (b, s);
00163 
00164     /* Food */
00165     b = &scr.pbar_food;
00166     draw_pbar_new (b, pbar_adjust_food(pbars[PFOOD].diff));
00167     write_pbar_int (b, PFOOD);
00168 
00169     /* Jobs */
00170     b = &scr.pbar_jobs;
00171     draw_pbar_new (b, pbar_adjust_jobs(pbars[PFOOD].diff));
00172     write_pbar_int (b, PJOBS);
00173 
00174     /* Coal */
00175     b = &scr.pbar_coal;
00176     draw_pbar_new (b, pbar_adjust_coal(pbars[PCOAL].diff));
00177     write_pbar_int (b, PCOAL);
00178 
00179     /* Goods */
00180     b = &scr.pbar_goods;
00181     draw_pbar_new (b, pbar_adjust_goods(pbars[PGOODS].diff));
00182     write_pbar_int (b, PGOODS);
00183 
00184     /* Ore */
00185     b = &scr.pbar_ore;
00186     draw_pbar_new (b, pbar_adjust_ore(pbars[PORE].diff));
00187     write_pbar_int (b, PORE);
00188 
00189     /* Steel */
00190     b = &scr.pbar_steel;
00191     draw_pbar_new (b, pbar_adjust_steel(pbars[PSTEEL].diff));
00192     write_pbar_int (b, PSTEEL);
00193 
00194     /* Money */
00195     b = &scr.pbar_money;
00196     draw_pbar_new (b, pbar_adjust_money(pbars[PMONEY].diff));
00197     write_pbar_int (b, PMONEY);
00198 }
00199 
00200 
00201 /* 
00202    update_pbar: add a new value to the array used to calculate the
00203    pbar display.  If month_flag is 1, the oldtotal is updated, all
00204    values are shifted up (dropping the first one), and the new value
00205    is added at the end. If 0, the new value replaces the most recently
00206    updated value.  The data is summed and the result compared to the
00207    old total.
00208 
00209 */
00210 
00211 void
00212 update_pbar (int pbar_num, int value, int month_flag)
00213 {
00214 
00215     int i, tot = 0;
00216 
00217     struct pbar_st * pbar = &pbars[pbar_num];
00218 
00219     if (month_flag) {
00220         pbar->oldtot = pbar->tot;
00221 
00222         /* If the dataset isn't full, just add it and forget month_flag */
00223         if (pbar->data_size < PBAR_DATA_SIZE) {
00224             pbar->data_size++;
00225             month_flag = 0;
00226         }
00227     }
00228 
00229     pbar->tot = 0;
00230 
00231     for (i = 0; i < (pbar->data_size - 1); i++) {
00232         if (month_flag) 
00233             pbar->tot += (pbar->data[i] = pbar->data[i+1]);
00234         else
00235             pbar->tot += pbar->data[i];
00236     }
00237 
00238 
00239     pbar->tot += pbar->data[i] = value;
00240     pbar->diff = pbar->tot - pbar->oldtot;
00241 }
00242 
00243 void
00244 update_pbars_daily()
00245 {
00246     update_pbar (PPOP, housed_population + people_pool, 0);
00247     update_pbar (PTECH, tech_level, 0);
00248     update_pbar (PFOOD, food_in_markets / 1000, 0);
00249     update_pbar (PJOBS, jobs_in_markets / 1000, 0);
00250     update_pbar (PCOAL, coal_in_markets / 250, 0);
00251     update_pbar (PGOODS, goods_in_markets / 500, 0);
00252     update_pbar (PORE, ore_in_markets / 500, 0);
00253     update_pbar (PSTEEL, steel_in_markets / 25, 0);
00254     update_pbar (PMONEY, total_money, 0);
00255 }
00256 
00257 void
00258 update_pbars_monthly()
00259 {
00260     update_pbar (PPOP, housed_population + people_pool, 1);
00261     update_pbar (PTECH, tech_level, 1);
00262     update_pbar (PFOOD, tfood_in_markets / data_last_month, 1);
00263     update_pbar (PJOBS, tjobs_in_markets / data_last_month, 1);
00264     update_pbar (PCOAL, tcoal_in_markets / data_last_month, 1);
00265     update_pbar (PGOODS, tgoods_in_markets / data_last_month, 1);
00266     update_pbar (PORE, tore_in_markets / data_last_month, 1);
00267     update_pbar (PSTEEL, tsteel_in_markets / data_last_month, 1);
00268     update_pbar (PMONEY, total_money, 1);
00269 }
00270 
00271 int 
00272 compute_pbar_offset (Rect* b, int val)
00273 {
00274     int offset;
00275     int val_abs = val > 0 ? val : -val;
00276 
00277     if (!val) 
00278         return 0;
00279 
00280     offset = (int) log (val_abs);
00281     if (offset > (b->w / 2) - 8) {
00282         offset = (b->w / 2) - 8;
00283     }
00284     offset = val > 0 ? offset : -offset;
00285 
00286     return offset;
00287 }
00288 
00289 void
00290 draw_pbar_new (Rect* b, int val)
00291 {
00292 
00293     int offset;
00294     int spike_start, spike_end;
00295 
00296     /* offset, oldoffset are the size of spike in pixels */
00297     offset = compute_pbar_offset (b, val);
00298 
00299     /* Clear both sides of the pbar */
00300     Fgl_fillbox (b->x, b->y, b->w / 2 - 8, b->h, 0);
00301     Fgl_fillbox (b->x + (b->w / 2) + 8, b->y, b->w / 2 - 8, b->h, 0);
00302 
00303 
00304     /* Figure out pos/neg and length and draw */
00305     if (offset > 0) {
00306 /* Right/Positive */
00307       spike_start = b->x + (b->w / 2) + 8;
00308       spike_end = spike_start + offset;
00309       Fgl_fillbox (spike_start, b->y+2, spike_end - spike_start, b->h-4, 
00310                    (green(12)));
00311     } else if (offset < 0) {
00312 /* Left/Negative */
00313       spike_end = b->x + (b->w / 2) - 8;
00314       spike_start = spike_end + offset;
00315       Fgl_fillbox (spike_start, b->y+2, spike_end - spike_start, b->h-4, 
00316                    (red(12))); 
00317     } 
00318 }
00319 
00320 
00321 
00322 void
00323 pbar_mouse(int rawx, int rawy, int button) 
00324 {
00325   int x = rawx, y = rawy; /* Eventually might use internal coords */
00326 
00327   if (button != LC_MOUSE_RIGHTBUTTON)
00328     return;
00329 
00330   /* check for help with pbars */
00331   activate_help ("pbar.hlp");
00332 
00333 #if defined (commentout)
00334   if (mouse_in_rect (&scr.pbar_pop,x,y)) {
00335     activate_help ("pbar-pop.hlp");
00336     return;
00337   }
00338   else if (mouse_in_rect (&scr.pbar_tech,x,y)) {
00339     activate_help ("pbar-tech.hlp");
00340     return;
00341   }
00342   else if (mouse_in_rect (&scr.pbar_food,x,y)) {
00343     activate_help ("pbar-food.hlp");
00344     return;
00345   }
00346   else if (mouse_in_rect (&scr.pbar_jobs,x,y)) {
00347     activate_help ("pbar-jobs.hlp");
00348     return;
00349   }
00350   else if (mouse_in_rect (&scr.pbar_money,x,y)) {
00351     activate_help ("pbar-money.hlp");
00352     return;
00353   }
00354   else if (mouse_in_rect (&scr.pbar_coal,x,y)) {
00355     activate_help ("pbar-coal.hlp");
00356     return;
00357   }
00358   else if (mouse_in_rect (&scr.pbar_goods,x,y)) {
00359     activate_help ("pbar-goods.hlp");
00360     return;
00361   }
00362   else if (mouse_in_rect (&scr.pbar_ore,x,y)) {
00363     activate_help ("pbar-ore.hlp");
00364     return;
00365   }
00366   else if (mouse_in_rect (&scr.pbar_steel,x,y)) {
00367     activate_help ("pbar-steel.hlp");
00368     return;
00369   }
00370 #endif
00371 }

Generated on Sun Dec 26 11:23:26 2004 for lincity by  doxygen 1.3.9.1