source: abuse/trunk/src/automap.cpp @ 115

Last change on this file since 115 was 115, checked in by Sam Hocevar, 11 years ago
  • Add lock() and unlock() methods to jimage objects. They're no-ops, but the Win32/DirectX version uses them all over the place because it uses DirectDraw? surfaces. One day we may wish to merge Abuse Win32's video output, or to use the SDL blending functions. You never know.
File size: 5.7 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 "automap.hpp"
13#include "game.hpp"
14
15automap *current_automap=0;
16
17void automap::draw()
18{
19  if (!automap_window) return ;
20  image *screen=automap_window->screen;
21 
22  long sx,ex,sy,ey,x,y,window_xstart,window_ystart,
23                       window_xend,window_yend,centerx,centery,
24                       draw_xstart,draw_ystart,
25                       i,j;
26 
27  x=the_game->first_view->x_center();
28  y=the_game->first_view->y_center();
29
30 
31  window_xstart=automap_window->x1();       
32  window_ystart=automap_window->y1();
33  window_xend=automap_window->x2();       
34  window_yend=automap_window->y2();
35  centerx=(window_xstart+window_xend)/2;
36  centery=(window_ystart+window_yend)/2;
37   
38  sx=x/f_wid-w/2;                // start drawing with this foretile 
39  sy=y/f_hi-h/2;
40  ex=sx+w;
41  ey=sy+h; 
42
43  if (sx<0)                       // does the map scroll past the left side ?
44  { sx=0;                         // yes, start drawing at 0 
45    draw_xstart=centerx-(x*AUTOTILE_WIDTH/f_wid);
46  }
47  else
48    draw_xstart=centerx-(x*AUTOTILE_WIDTH/f_wid-sx*AUTOTILE_WIDTH);
49                           
50  if (sy<0)
51  {
52    sy=0;   
53    draw_ystart=centery-(y*AUTOTILE_HEIGHT/f_hi);
54  }
55  else
56    draw_ystart=centery-(y*AUTOTILE_HEIGHT/f_hi-sy*AUTOTILE_HEIGHT);
57
58  // if view position hasn't changed, only update the binking dot and return
59  if (draw_xstart==old_dx && draw_ystart==old_dy) 
60  {
61   automap_window->screen->lock();
62   automap_window->screen->add_dirty(centerx,centery,centerx,centery);
63    if ((tick++)&4)
64      automap_window->screen->putpixel(centerx,centery,255);
65    else
66      automap_window->screen->putpixel(centerx,centery,27);
67   automap_window->screen->unlock();
68    return ;   
69  }
70
71  old_dx=draw_xstart;
72  old_dy=draw_ystart; 
73
74
75  if (ex>=cur_lev->foreground_width()) 
76    ex=cur_lev->foreground_width()-1;
77  if (ey>=cur_lev->foreground_height())
78    ey=cur_lev->foreground_height()-1;
79
80
81  screen->bar(window_xstart,window_ystart,draw_xstart,window_yend,0);
82  screen->bar(window_xstart,window_ystart,window_xend,draw_ystart,0);
83 
84
85/*  if (ex>=cur_lev->foreground_width())
86  {   
87    draw_xend=center
88    ex=foreground_width()-1; */
89
90   
91
92
93  // we are going to redraw the whole map, so make the dirty rect work easier by marking
94  // everything dirty
95  screen->add_dirty(window_xstart,window_ystart,window_xend,window_yend);
96
97 
98
99
100  // draw the tiles that will be around the border of the automap with put_image
101  // because it handles clipping, but for ths reason is slower, the rest
102  // we will slam on as fast as possible
103
104  screen->set_clip(window_xstart,window_ystart,window_xend,window_yend);
105/*  for (i=draw_xstart,j=draw_ystart,x=sx,y=sy;y<=ey;j+=AUTOTILE_HEIGHT,y++)
106    foretiles[cur_lev->get_fg(x,y)]->micro_image->put_image(screen,i,j,0);
107
108  for (i=draw_xstart+ex*AUTOTILE_WIDTH,j=draw_ystart,y=sy,x=ex;y<=ey;j+=AUTOTILE_HEIGHT,y++)
109    foretiles[cur_lev->get_fg(x,y)]->micro_image->put_image(screen,i,j,0);
110
111  for (i=draw_xstart,j=draw_ystart,x=sx,y=sy;x<=ex;i+=AUTOTILE_WIDTH,x++)
112    foretiles[cur_lev->get_fg(x,y)]->micro_image->put_image(screen,i,j,0);
113
114  for (i=draw_xstart,j=draw_ystart+ey*AUTOTILE_HEIGHT,x=sx,y=ex;x<=ex;i+=AUTOTILE_WIDTH,x++)
115    foretiles[cur_lev->get_fg(x,y)]->micro_image->put_image(screen,i,j,0); */
116
117
118   
119  unsigned short *fgline;
120  for (j=draw_ystart,y=sy;y<=ey;j+=AUTOTILE_HEIGHT,y++)
121  {   
122    fgline=cur_lev->get_fgline(y)+sx;
123    for (i=draw_xstart,x=sx;x<=ex;i+=AUTOTILE_WIDTH,x++,fgline++)
124    {
125      if ((*fgline)&0x8000)
126      {
127        int id=foretiles[ (*fgline)&0x7fff];
128        if (id>=0)
129          cash.foret(id)->micro_image->put_image(screen,i,j,0);
130        else
131          cash.foret(foretiles[0])->micro_image->put_image(screen,i,j,0);
132      }
133      else
134        screen->bar(i,j,i+AUTOTILE_WIDTH-1,j+AUTOTILE_HEIGHT-1,0);
135
136
137    }
138
139  }
140
141
142  // draw the person as a dot, no need to add a dirty because we marked the
143  // whole screen already
144  automap_window->screen->lock();
145  if ((tick++)&4)
146    automap_window->screen->putpixel(centerx,centery,255);
147  else
148    automap_window->screen->putpixel(centerx,centery,27);
149  automap_window->screen->unlock();
150
151  // set the clip back to full window size because soemthing else could mess with the area
152  automap_window->screen->set_clip(0,0,screen->width()-1,screen->height()-1); 
153}
154
155
156void automap::toggle_window()
157{
158    if (automap_window)
159    {   
160        wm->close_window(automap_window);
161        automap_window = NULL;
162    }
163    else
164    {   
165        old_dx = -1000; // make sure the map gets drawn the first time
166        old_dy = -1000;
167
168        automap_window = wm->new_window(0, 0, w * AUTOTILE_WIDTH,
169                                        h * AUTOTILE_HEIGHT, NULL, "Map");
170        automap_window->screen->bar(17, 1, 17 + 8 * 6 + 3, 6,
171                                    wm->medium_color());   
172        wm->font()->put_string(automap_window->screen, 20, 2, "Automap",
173                               wm->dark_color());
174        draw();   
175    } 
176}
177
178
179automap::automap(level *l, int width, int height)
180{
181  w=width;
182  h=height;
183 
184  tick=0; 
185  cur_lev=l;
186  automap_window=NULL;
187  toggle_window();   
188}
189
190void automap::handle_event(event &ev)
191{
192
193  //only respond to stuff in our window or on the main screen
194  if (ev.window==NULL || ev.window==automap_window)
195  {
196    switch (ev.type)
197    {
198      case EV_KEY :
199        switch(ev.key)
200        {
201          case 'A' :   
202          case 'a' :
203            toggle_window();
204            break;         
205        } 
206        break; 
207      case EV_CLOSE_WINDOW :
208        wm->close_window(automap_window);
209        automap_window=NULL;
210        break;               
211    }   
212  }     
213}
214
215
216
217
218
219
220
Note: See TracBrowser for help on using the repository browser.