source: abuse/trunk/src/statbar.cpp @ 512

Last change on this file since 512 was 512, checked in by Sam Hocevar, 8 years ago

imlib: use vec2i for image::size and unroll all necessary changes
everywhere else in the code.

File size: 8.4 KB
Line 
1/*
2 *  Abuse - dark 2D side-scrolling platform game
3 *  Copyright (c) 1995 Crack dot Com
4 *  Copyright (c) 2005-2011 Sam Hocevar <sam@hocevar.net>
5 *
6 *  This software was released into the Public Domain. As with most public
7 *  domain software, no warranty is made or implied by Crack dot Com or
8 *  Jonathan Clark.
9 */
10
11#include "config.h"
12
13#include "common.h"
14
15#include "sbar.h"
16#include "view.h"
17#include "lisp.h"
18#include "cache.h"
19#include "demo.h"
20#include "chars.h"
21#include "objects.h"
22#include "game.h"
23#include "clisp.h"
24
25status_bar sbar;
26
27status_bar::status_bar()
28{
29  v=NULL;
30  need_rf=1;
31  changed_cursor=0;
32  icon_in_selection=-1;  // the weapon the mouse cursor is on top of, -1 if none
33  currently_selected_weapon=-1;
34}
35
36// defined in dev.c
37void scale_put_trans(image *im, image *screen, int x, int y, short new_width, short new_height);
38void scale_put(image *im, image *screen, int x, int y, short new_width, short new_height);
39extern image *small_render;
40
41
42void status_bar::load()
43{
44  char sbname[100];
45  char iname[20];
46  void *l_name = LSymbol::FindOrCreate("sbar_file");
47  if (symbol_value(l_name)!=l_undefined)
48    strcpy(sbname,lstring_value(symbol_value(l_name)));
49  else strcpy(sbname,"art/statbar.spe");
50
51  int i;
52  for (i=0; i<TOTAL_WEAPONS; i++)
53  {
54    sprintf(iname,"bweap%04d.pcx",i+1);
55    bweap[i]=cache.reg(sbname,iname,SPEC_IMAGE);
56
57    sprintf(iname,"dweap%04d.pcx",i+1);
58    dweap[i]=cache.reg(sbname,iname,SPEC_IMAGE);
59  }
60
61  for (i=0; i<30; i++)
62  {
63    sprintf(iname,"bnum%02d",i);
64    bnum[i]=cache.reg(sbname,iname,SPEC_IMAGE);
65  }
66
67
68  sbar=cache.reg(sbname,"sbar",SPEC_IMAGE);
69  sbar_select=cache.reg(sbname,"sbar_select",SPEC_IMAGE);
70  sbar_numpad=cache.reg(sbname,"sbar_numpad",SPEC_IMAGE);
71}
72
73void status_bar::draw_num(image *screen, int x, int y, int num, int *offset)
74{
75  if (num<0 || num>999)
76  {
77    printf("bad number for statbar\n");
78    return ;
79  }
80
81  image *im=cache.img(*offset);
82  int dw=small_render ? im->Size().x*2 : im->Size().x;
83  int dh=small_render ? im->Size().y*2 : im->Size().y;
84
85  int n=num/100;
86  scale_put(cache.img(offset[n]),screen,x,y,dw,dh);
87  num-=n*100;
88
89  x+=dw; n=num/10;
90  scale_put(cache.img(offset[n]),screen,x,y,dw,dh);
91  num-=n*10;
92
93  x+=dw;
94  scale_put(cache.img(offset[num]),screen,x,y,dw,dh);
95}
96
97void status_bar::redraw(image *screen)
98{
99  need_rf=0;
100  if (!v) return ;
101
102  if (total_weapons)
103  {
104    if (!playing_state(the_game->state)) return ;
105
106    image *sb=cache.img(sbar);
107
108    // status bar width & height
109    int sb_w=(small_render ? sb->Size().x*2 : sb->Size().x),
110    sb_h=(small_render ? sb->Size().y*2 : sb->Size().y);
111
112    // status bar x & y position
113    int sx=xres/2-sb_w/2,sy=yres-sb_h;
114
115    // weapon x offset, and x add increment
116    int wx=small_render ? 80 : 40,wa=small_render ? 34*2 : 34;
117
118    // weapon icon width & height
119    int ww=small_render ? cache.img(bweap[0])->Size().x*2 : cache.img(bweap[0])->Size().x;
120    int wh=small_render ? cache.img(bweap[0])->Size().y*2 : cache.img(bweap[0])->Size().y;
121
122
123    // numpad y offset
124    int np_yo=small_render ? 42 : 21;
125    int np_w=small_render ? cache.img(sbar_numpad)->Size().x*2 : cache.img(sbar_numpad)->Size().x;
126    int np_h=small_render ? cache.img(sbar_numpad)->Size().y*2 : cache.img(sbar_numpad)->Size().y;
127
128    // selection bar width * height
129    int sel_w=small_render ? cache.img(sbar_select)->Size().x*2 : cache.img(sbar_select)->Size().x;
130    int sel_h=small_render ? cache.img(sbar_select)->Size().y*2 : cache.img(sbar_select)->Size().y;
131
132    int sel_off=small_render ?  8 : 4;
133    scale_put(sb,screen,sx,sy,sb_w,sb_h);
134
135    if (v->focus)
136      draw_num(screen,sx+(small_render ? 17*2 : 17),sy+(small_render ? 11*2 : 11),v->focus->hp(),bnum);
137
138    int ammo_x,ammo_y;
139    if (small_render)
140    {
141      ammo_x=sx+52*2;
142      ammo_y=sy+25*2;
143    } else { ammo_x=sx+52; ammo_y=sy+25; }
144
145    int i,x_on=sx+wx,t=TOTAL_WEAPONS;
146    if (t>=total_weapons) t=total_weapons;
147    for (i=0; i<t; i++,x_on+=wa,ammo_x+=wa)
148    {
149      if (v->has_weapon(i))
150      {
151    if (v->current_weapon==i)
152        scale_put_trans(cache.img(bweap[i]),screen,x_on,sy,ww,wh);
153    else
154        scale_put_trans(cache.img(dweap[i]),screen,x_on,sy,ww,wh);
155
156    scale_put_trans(cache.img(sbar_numpad),screen,x_on-2,sy+np_yo,np_w,np_h);
157
158    if (v->current_weapon==i)
159          draw_num(screen,ammo_x,ammo_y,v->weapon_total(i),bnum+20);
160    else
161          draw_num(screen,ammo_x,ammo_y,v->weapon_total(i),bnum+10);
162
163    if (i==icon_in_selection)
164        scale_put_trans(cache.img(sbar_select),screen,x_on+sel_off,sy,sel_w,sel_h);
165      }
166    }
167  }
168}
169
170void status_bar::area(int &x1, int &y1, int &x2, int &y2)
171{
172  if (sbar<=0 || !total_weapons)
173  {
174    x2=xres;
175    y2=yres;
176    x1=x2;
177    y1=y2;
178    return ;
179  }
180
181  image *sb=cache.img(sbar);
182
183  // status bar width & height
184  int sb_w=sb->Size().x,
185      sb_h=sb->Size().y;
186
187  if (small_render) { sb_w*=2; sb_h*=2; }
188
189  x1=xres/2-sb_w/2;
190  x2=xres/2+sb_w/2;
191  y1=yres-sb_h;
192  y2=yres;
193}
194
195
196void status_bar::draw_health(image *screen,int amount)
197{
198  if (total_weapons)
199  {
200    int x1,y1,x2,y2;
201    area(x1,y1,x2,y2);
202    draw_num(screen,x1+(small_render ? 17*2 : 17),y1+(small_render ? 11*2 : 11),amount,bnum);
203  }
204}
205
206
207void status_bar::draw_ammo(image *screen, int weapon_num, int amount, int light)
208{
209  if (total_weapons)
210  {
211    int x1,y1,x2,y2;
212    area(x1,y1,x2,y2);
213    draw_num(screen,
214        x1+(small_render ? 52*2+weapon_num*34*2 : 52+weapon_num*34),
215        y1+(small_render ? 25*2 : 25),amount,bnum+(light ? 20 : 10));
216  }
217}
218
219
220int status_bar::mouse_in_area()
221{
222  if (!v) return 0;
223  int x1,y1,x2,y2;
224  area(x1,y1,x2,y2);
225
226  int mx,my;
227  if (small_render)
228  {
229    mx=(v->pointer_x-v->cx1)*2+v->cx1;
230    my=(v->pointer_y-v->cy1)*2+v->cy1;
231  } else
232  {
233    mx=v->pointer_x;
234    my=v->pointer_y;
235  }
236
237  if (mx>=x1 && my>=y1 && mx<=x2 && my<=y2)
238    return 1;
239  else return 0;
240}
241
242
243void status_bar::draw_update()
244{
245  if (total_weapons && v)
246  {
247    if (DEFINEDP(symbol_value(l_mouse_can_switch)) && symbol_value(l_mouse_can_switch) &&
248    mouse_in_area())
249    {
250      if ((current_level->tick_counter()&4)==0)
251        wm->set_mouse_shape(cache.img(c_mouse1)->copy(),4,4);
252      else wm->set_mouse_shape(cache.img(c_mouse2)->copy(),4,4);
253      changed_cursor=1;
254    } else if (changed_cursor)
255    {
256      if (!(dev&EDIT_MODE))
257        wm->set_mouse_shape(cache.img(c_target)->copy(),8,8);
258      else
259        wm->set_mouse_shape(cache.img(c_normal)->copy(),1,1);
260      changed_cursor=0;
261    }
262
263    if (need_rf)
264      redraw(screen);
265  }
266}
267
268
269void status_bar::step()
270{
271  if (!v) return ;
272  if (!DEFINEDP(symbol_value(l_mouse_can_switch)) || !symbol_value(l_mouse_can_switch)) return ;
273
274  int sb_w,sb_h;
275  if (sbar>0 && total_weapons)
276  {
277    image *sb=cache.img(sbar);
278
279    // status bar width & height
280    sb_w=sb->Size().x;
281    sb_h=sb->Size().y;
282  }
283
284  // see if the mouse is in the sbar region (demo_x already corrected for small_render)
285  int sx1,sy1,sx2,sy2;
286  area(sx1,sy1,sx2,sy2);
287
288  int view_y2=small_render ? (v->cy2-v->cy1+1)*2+v->cy1 : v->cy2;
289  if (sy1<view_y2)     // tell view to shrink if it is overlapping the status bar
290  {
291    v->suggest.send_view=1;
292    v->suggest.cx1=v->cx1;
293    v->suggest.cy1=v->cy1;
294    v->suggest.cx2=v->cx2;
295    v->suggest.cy2=small_render ? (sy1-v->cy1-2)/2+v->cy1 : sy1-2;
296  }
297
298  if (sbar<=0 || !total_weapons) return ;
299
300
301  int mx=small_render ? (last_demo_mx-v->cx1)*2+v->cx1 : last_demo_mx;
302  int my=small_render ? (last_demo_my-v->cy1)*2+v->cy1 : last_demo_my;
303
304
305  if (mx>sx1 && my>sy1 && mx<sx2 && my<sy2)
306  {
307
308    int new_target;
309
310    mx-=sx1;
311    if (small_render) mx/=2;
312
313
314    mx-=47;
315    if (mx<0) new_target=0;
316    else
317    {
318      new_target=mx/33;
319      if (new_target>=TOTAL_WEAPONS)
320        new_target=TOTAL_WEAPONS-1;
321      if (new_target>=total_weapons)
322        new_target=total_weapons-1;
323    }
324
325    if (v->has_weapon(new_target) && new_target!=icon_in_selection)
326    {
327      icon_in_selection=new_target;
328      need_refresh();
329    }
330
331    if (last_demo_mbut==2 && icon_in_selection!=v->current_weapon &&
332    icon_in_selection!=-1) // the user requested a weapon change
333    {
334      v->suggest.send_weapon_change=1;
335      v->suggest.new_weapon=icon_in_selection;
336    }
337
338  } else
339  {
340    if (icon_in_selection!=-1)
341    {
342      icon_in_selection=-1;
343      need_refresh();
344    }
345  }
346
347  // see if a new weapon has been selected other than the one
348  // we think is selected, if so redraw the status bar
349  if (currently_selected_weapon!=v->current_weapon)
350  {
351    currently_selected_weapon=v->current_weapon;
352    need_refresh();
353  }
354
355
356}
357
358
359
360
361
Note: See TracBrowser for help on using the repository browser.