source: golgotha/src/i4/app/app.cc @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 11 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: 6.4 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 "window/wmanager.hh"
10#include "app/app.hh"
11#include "time/profile.hh"
12#include "app/registry.hh"
13#include "threads/threads.hh"
14
15i4_profile_class pf_app_calc_model("app::calc_model");
16i4_profile_class pf_app_refresh("app::refresh");
17i4_profile_class pf_app_get_input("app::get_input");
18
19i4_application_class *i4_current_app=0;
20
21i4_parent_window_class *i4_application_class::get_root_window()
22{
23  return wm;
24}
25
26i4_graphical_style_class *i4_application_class::get_style()
27{
28  if (wm)
29    return wm->get_style();
30  else return 0;
31}
32
33void i4_application_class::receive_event(i4_event *ev)
34{
35  if (ev->type()==i4_event::DISPLAY_CLOSE)
36    finished=i4_T;
37}
38
39void i4_application_class::run()
40
41  i4_current_app=this;
42  init();
43  finished=i4_F;
44  int restore_priority=0;
45
46  do
47  {
48    pf_app_calc_model.start();
49    calc_model();   
50    pf_app_calc_model.stop();
51
52    pf_app_refresh.start();
53    refresh();
54    pf_app_refresh.stop();
55
56    if (restore_priority)
57    {
58      i4_set_thread_priority(i4_get_thread_id(), I4_THREAD_PRIORITY_NORMAL);
59      restore_priority=0;
60    }
61
62    pf_app_get_input.start();
63    int repeat;
64    i4_kernel.events_sent=0;
65    do
66    {
67      repeat=0;
68      get_input();
69      if (!finished)
70      {
71        if (display->display_busy() ||
72            (idle() && i4_kernel.events_sent==0 &&
73             !wm->need_redraw() &&
74             display->get_context()->both_dirty->empty()))
75        {
76          repeat=1;
77          if (!restore_priority)
78          {
79            restore_priority=1;
80            i4_set_thread_priority(i4_get_thread_id(), I4_THREAD_PRIORITY_LOW);
81          }
82          i4_thread_yield();
83        }
84      }
85    }
86    while (repeat);
87
88    pf_app_get_input.stop();
89
90
91  } while (!finished);
92  uninit();
93  i4_current_app=0;
94}
95
96
97void i4_application_class::calc_model()
98{}
99
100// get_input polls the hardware for changes and reports them as events to event_handlers
101void i4_application_class::get_input()
102{
103  i4_kernel.process_events();
104
105}
106
107void i4_application_class::refresh()
108{
109  wm->root_draw();
110}
111
112
113// if an exact match is not found the closest width and height are return
114i4_display_class::mode *i4_application_class::find_mode(w16 &width, w16 &height, int driver_id)
115{
116  sw32 closest_dist=0xfffffff;
117  w16 closest_width=0,
118      closest_height=0;
119
120  i4_display_class::mode *use=display->get_first_mode(driver_id);
121  if (!use)
122    return 0;
123
124  do
125  {
126
127    // if we are opening a window and we can set the xres and yres,
128    //   then make them fit as best we can to the suggested width and height
129
130    if (use->flags & i4_display_class::mode::RESOLUTION_DETERMINED_ON_OPEN)
131    {
132      use->xres=width;
133      use->yres=height;
134    }
135     
136
137    if (width==use->xres &&     // did we find a matching mode?
138        height==use->yres)
139      return use;
140
141
142    // see how far off we are
143    sw32 dist=((sw32)use->xres-(sw32)width)*((sw32)use->xres-(sw32)width)+
144              ((sw32)use->yres-(sw32)height)*((sw32)use->yres-(sw32)height);
145    if (dist<closest_dist)
146    {
147      closest_dist=dist;
148      closest_width=use->xres;
149      closest_height=use->yres;
150    }
151
152    use=display->get_next_mode();
153  } while (use);
154
155  width=closest_width;
156  height=closest_height;
157
158  return 0;
159}
160
161i4_application_class::~i4_application_class()
162{
163
164}
165
166void i4_application_class::memory_init()
167{
168  i4_init();
169}
170
171
172void i4_application_class::resource_init(char *resource_file,
173                                         void *resource_buffer)
174{
175  i4_string_man.load("resource/i4.res");
176
177  if (resource_buffer)
178    i4_string_man.load_buffer(resource_buffer,
179                              "internal_buffer");
180  else
181    i4_string_man.load(resource_file);
182}
183
184
185void i4_application_class::handle_no_displays()
186{
187  i4_error("Could not find a display!");
188}
189
190
191static char *i4_display_key="SOFTWARE\\Crack dot Com\\I4\\1.0";
192
193i4_bool i4_application_class::get_display_name(char *name, int max_len)
194{
195  return i4_get_registry(I4_REGISTRY_MACHINE, i4_display_key, "display", name, max_len);
196}
197
198void i4_application_class::display_init()
199{
200  char name[256];
201
202  i4_display_list_struct *d, *found=0;
203
204  if (get_display_name(name, 256))
205  {
206    for (d=i4_display_list; d; d=d->next)
207      if (strcmp(d->name, name)==0)
208        found=d;
209  }
210 
211  if (!found)
212    found=i4_display_list;
213
214  if (!found)
215    handle_no_displays();
216   
217
218  w16 width=640, height=480;
219
220  // first try to find mode specified in the resource file
221  i4_const_str xres=i4gets("default_xres", i4_F);
222  i4_const_str yres=i4gets("default_yres", i4_F);
223 
224  if (!xres.null() && !yres.null())
225  {
226    i4_const_str::iterator xres_str=xres.begin(),
227      yres_str=yres.begin();
228
229    width=xres_str.read_number();
230    height=yres_str.read_number();
231  }
232
233  w16 found_width=width,
234      found_height=height;
235
236  display=found->display;
237
238  i4_display_class::mode *use=find_mode(found_width, found_height, found->driver_id);
239  if (!use)
240  {
241    i4_warning("Unable to find an exact match for mode %dx%d, using %dx%d instead\n",
242        width,height,
243        found_width,found_height);
244
245    use=find_mode(found_width, found_height, found->driver_id);
246
247    if (!use)
248      i4_error("What? Could not find that mode either");
249  }
250
251  if (!display->initialize_mode())
252    handle_no_displays();
253
254  wm=new i4_window_manager_class();
255  wm->prepare_for_mode(display, use);
256
257  i4_kernel.request_events(this,i4_device_class::FLAG_DISPLAY_CLOSE);
258}
259
260
261
262void i4_application_class::init()
263{
264  memory_init();
265  resource_init("resource.res",0);
266  display_init();
267}
268
269void i4_application_class::uninit()
270{
271  display_uninit();
272
273  i4_uninit();
274}
275
276void i4_application_class::display_uninit()
277{
278  i4_kernel.process_events();
279  delete wm;
280  wm=0;
281 
282  i4_kernel.unrequest_events(this, i4_device_class::FLAG_DISPLAY_CLOSE);
283  display->close();
284  display=0;
285}
Note: See TracBrowser for help on using the repository browser.