app.cc 6.4 KB

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