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

Last change on this file since 492 was 492, checked in by Sam Hocevar, 12 years ago

lisp: rename core classes to slightly shorter names (LispObject? -> LObject).

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