source: golgotha/src/i4/video/win32/gdi_draw.cc @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 14 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 8.0 KB
Line 
1/********************************************************************** <BR>
2  This file is part of Crack dot Com's free source code release of
3  Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
4  information about compiling & licensing issues visit this URL</a>
5  <PRE> If that doesn't help, contact Jonathan Clark at
6  golgotha_source@usa.net (Subject should have "GOLG" in it)
7***********************************************************************/
8
9#include "video/win32/win32.hh"
10#include "device/event.hh"
11#include "main/win_main.hh"
12
13class gdi_accelerator_class : public win32_accelerator_class
14{
15  I4_SCREEN_TYPE  *back_buffer;
16  BITMAPINFOHEADER back_buffer_bmp;
17  BITMAPINFO       dc_bmpinfo;
18  i4_bool          win_is_open;
19  HBITMAP          bitmap;
20
21public:
22  class gdi_mode : public i4_display_class::mode
23  {
24  public:
25    gdi_accelerator_class *assoc;      // pointer to use, so we can confirm we created this mode
26
27  };
28  gdi_mode amode, cur_mode;
29
30
31  virtual w16 width() const
32  {
33    return back_buffer->width();
34  }
35 
36  virtual w16 height() const
37  {
38    return back_buffer->height();
39  }
40 
41  void setup_back_buffer_bmp(w32 width, w32 height)
42  {
43    if (back_buffer)
44    {
45      delete back_buffer;
46      DeleteObject(bitmap);
47    }
48
49    HDC         dc;
50    dc=GetDC(win32_display_instance.window_handle);
51
52    memset(&back_buffer_bmp,0,sizeof(back_buffer_bmp));
53    back_buffer_bmp.biSize=sizeof(back_buffer_bmp);
54    back_buffer_bmp.biWidth=width;
55    back_buffer_bmp.biHeight=-height;
56    back_buffer_bmp.biPlanes=1;
57    back_buffer_bmp.biBitCount=I4_BYTES_PER_PIXEL*8;
58    back_buffer_bmp.biCompression=BI_RGB;
59    back_buffer_bmp.biSizeImage=width*height*I4_BYTES_PER_PIXEL;
60
61    memcpy(&dc_bmpinfo.bmiHeader,&back_buffer_bmp,sizeof(back_buffer_bmp));
62
63    void *bmp_data_address;
64     
65    bitmap=CreateDIBSection(dc,
66                            &dc_bmpinfo,DIB_RGB_COLORS,
67                            &bmp_data_address,           // where bitmap's data will be stored
68                            0,                           // don't use a file
69                            0);
70    if (!bitmap)
71      i4_error("Error CreateDIBSection failed!");
72
73    i4_pal_handle_class pal;
74
75#if (I4_SCREEN_DEPTH==15 || I4_SCREEN_DEPTH==16)
76    pal.set_type(i4_pal_handle_class::ID_16BIT);
77#else
78#error add code here
79#endif
80   
81    back_buffer=new I4_SCREEN_TYPE(width,height,
82                                   pal,
83                                   width*I4_BYTES_PER_PIXEL,   // bytes per line
84                                   (w8 *)bmp_data_address);
85    if (context)
86      delete context;
87
88    context=new i4_draw_context_class(0,0,width-1,height-1);
89    context->both_dirty=new i4_rect_list_class;
90    context->both_dirty->add_area(0,0,width-1,height-1);
91    context->single_dirty=new i4_rect_list_class;
92  }
93 
94  virtual void init()
95  {
96    back_buffer=0;
97    win32_accelerator_class::init();
98  }
99 
100  // called when windows gives us a WM_MOVE message, this tells everyone else interested
101  virtual void move_screen(i4_coord x, i4_coord y)               
102  {
103    // We don't care about moves in this case
104    // Because we are drawing an off-screen buffer, window moves don't affect anything
105  }
106 
107  // called when windows gives us a WM_MOVE message, this tells everyone else interested
108  virtual void resize_screen(i4_coord w, i4_coord h)             
109  {
110    // If the window resizes, we need to resize our off-screen buffer and send a message
111    // to everyone who is interested
112    setup_back_buffer_bmp(w,h);
113
114    delete context;
115    context=new i4_draw_context_class(0,0,w-1,h-1);
116    context->both_dirty=new i4_rect_list_class;
117    context->both_dirty->add_area(0,0,w-1,h-1);
118    context->single_dirty=new i4_rect_list_class;
119
120    i4_display_change_event_class ev(&win32_display_instance,i4_display_change_event_class::SIZE_CHANGE);
121    win32_display_instance.input.send_event_to_agents(&ev,i4_device_class::FLAG_DISPLAY_CHANGE);
122  }
123 
124
125  virtual mode *current_mode()
126  {
127    return &cur_mode;
128  }
129
130  virtual i4_display_class::mode *get_first_mode()
131  {
132    memset(&amode,0,sizeof(amode));
133    strcpy(amode.name,"Win32 GDI window");
134    amode.flags=i4_display_class::mode::RESOLUTION_DETERMINED_ON_OPEN;
135
136    amode.red_mask=(31<<10);
137    amode.green_mask=(31<<5);
138    amode.blue_mask=(31<<0);
139
140    amode.bits_per_pixel=16;
141
142    amode.xres=640;
143    amode.yres=480;
144
145    amode.assoc=this;          // so we know in 'initialize_mode' that we created this mode
146
147    return &amode;
148  }
149 
150  virtual i4_display_class::mode *get_next_mode(i4_display_class::mode *last_mode)
151  {
152    return 0;
153  }
154 
155  virtual i4_bool initialize_mode(i4_display_class::mode *which_one)
156  {
157    if (!back_buffer)
158    {
159      memcpy(&cur_mode, which_one, sizeof(cur_mode));
160      win32_display_instance.window_handle = CreateWindowEx(
161                                                            0,
162                                                            //                                                             WS_EX_TOPMOST,
163                                                            win32_display_instance.class_name(),
164                                                            win32_display_instance.class_name(),
165                                                            WS_OVERLAPPEDWINDOW,
166                                                            0,
167                                                            0,
168                                                            which_one->xres,
169                                                            which_one->yres,
170                                                            NULL,
171                                                            NULL,
172                                                            i4_win32_instance,
173                                                            NULL );
174
175
176      ShowWindow( win32_display_instance.window_handle, SW_SHOW );
177      UpdateWindow( win32_display_instance.window_handle );
178
179      setup_back_buffer_bmp(which_one->xres,
180                            which_one->yres);
181     
182
183      return i4_T;
184    }
185    else
186      return i4_F;
187  }
188 
189  virtual i4_bool close()
190  {
191    if (back_buffer)
192    {
193      DestroyWindow(win32_display_instance.window_handle);
194      delete back_buffer;
195      back_buffer=0;
196      return i4_T;
197    } else return i4_F;
198  }
199 
200  virtual i4_image_class *get_screen()
201  {
202    return back_buffer;
203  }
204 
205  virtual void flush()
206  {
207    PAINTSTRUCT paint_s;
208    HDC         dc;
209    dc=GetDC(win32_display_instance.window_handle);
210
211
212    SelectObject(dc,bitmap);
213
214    HDC hdcMem = CreateCompatibleDC(dc);
215    bitmap = SelectObject(hdcMem,bitmap);
216
217
218    for (i4_rect_list_class::area_iter a=context->single_dirty->list.begin();
219         a!=context->single_dirty->list.end();
220         ++a)
221      context->both_dirty->add_area(a->x1, a->y1, a->x2, a->y2);
222
223    context->single_dirty->delete_list();
224
225    context->both_dirty->intersect_area(0,0,width()-1,height()-1);
226
227
228
229    a=context->both_dirty->list.begin();
230    for (;a!=context->both_dirty->list.end();++a)
231      BitBlt(dc,a->x1,a->y1,
232             a->x2-a->x1+1,a->y2-a->y1+1,
233             hdcMem,a->x1,a->y1,SRCCOPY);
234
235    // this is to reduce the flicker of the mouse cursor
236    POINT p;
237    GetCursorPos(&p);
238    SetCursorPos(p.x, p.y);
239 
240    context->both_dirty->delete_list();
241    bitmap = SelectObject(hdcMem,bitmap);         // windows says to do this
242
243    DeleteDC(hdcMem);
244   
245    ReleaseDC(win32_display_instance.window_handle,dc);
246  }
247 
248  virtual i4_bool set_mouse_shape(i4_cursor_class *cursor)
249  {
250    return i4_F;
251  }
252 
253  virtual i4_bool realize_palette(i4_pal_handle_class pal_id)
254  {
255    return i4_T;   // pretend like this works for now
256  }
257 
258  virtual w32 priority()
259  {
260    return 1;
261  }
262 
263  gdi_accelerator_class() { context=0; }
264};
265
266static gdi_accelerator_class gdi_accelerator_instance;
267
268
269
270
Note: See TracBrowser for help on using the repository browser.