00001 /* 00002 $Id: adonthell.cc,v 1.11 2003/01/17 22:05:56 ksterker Exp $ 00003 00004 Copyright (C) 1999/2000/2001 Alexandre Courbot 00005 Part of the Adonthell Project http://adonthell.linuxgames.com 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License. 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY. 00011 00012 See the COPYING file for more details. 00013 */ 00014 00015 00016 /** 00017 * @file adonthell.cc 00018 * 00019 * @author Alexandre Courbot 00020 * @author Kai Sterker 00021 * @brief Implements the adonthell class. 00022 */ 00023 00024 #include "win_manager.h" 00025 #include "gametime.h" 00026 #include "gamedate.h" 00027 #include "adonthell.h" 00028 #include "audio.h" 00029 00030 // Pointer to the active main loop 00031 adonthell *data::engine = NULL; 00032 00033 // constructor 00034 adonthell::adonthell () 00035 { 00036 letsexit = false; 00037 update_map_ = false; 00038 control_active_ = false; 00039 00040 // load the script taking care of additional game commands 00041 control.create_instance ("schedules.control", "control"); 00042 } 00043 00044 // start and execute the game's main loop 00045 void adonthell::main (win_base *wnd, const string name) 00046 { 00047 win_manager mgr; 00048 00049 if (wnd != NULL) 00050 { 00051 mgr.add (wnd /*, name */); 00052 mgr.set_focus (wnd); 00053 } 00054 else 00055 { 00056 mapview_start (); 00057 set_control_active (true); 00058 fade_in (); 00059 } 00060 00061 while (letsexit == false) 00062 { 00063 main_loop (); 00064 00065 // blit the surface to the physical screen 00066 screen::show (); 00067 00068 // perform operations to keep the game's speed constant 00069 gametime::update (); 00070 00071 // update the internal clock 00072 gamedate::update (); 00073 } 00074 00075 // only leave one main loop at a time 00076 letsexit = false; 00077 } 00078 00079 // the main loop 00080 void adonthell::main_loop () 00081 { 00082 input::update (); 00083 00084 // check whether music has finished playing 00085 if (audio::is_background_finished ()) audio::run_schedule (); 00086 00087 // on slower machines, we update several times before drawing, 00088 // i.e. we are skipping frames to keep the game's speed constant 00089 for (int i = 0; i < gametime::frames_to_skip (); i++) 00090 { 00091 // grab any user input and update the internal state of 00092 // all windows of the current level 00093 win_manager::active->input_update (); 00094 if (update_map ()) lmap.update (); 00095 win_manager::active->update (); 00096 if (control_active ()) control.run (); 00097 } 00098 00099 if (!letsexit) 00100 { 00101 // first clear the screen to avoid artifacts 00102 screen::clear (); 00103 00104 // draw everything to our display surface 00105 win_manager::active->draw (); 00106 } 00107 } 00108 00109 // quit the main loop 00110 void adonthell::main_quit () 00111 { 00112 letsexit = true; 00113 } 00114 00115 // fade the screen out 00116 void adonthell::fade_out () 00117 { 00118 s_int16 i = 0; 00119 00120 while (i < 60) 00121 { 00122 gametime::update (); 00123 i += gametime::frames_to_skip () * 2; 00124 if (i > 60) i = 60; 00125 00126 main_loop (); 00127 00128 screen::transition (i * 2); 00129 screen::show (); 00130 } 00131 } 00132 00133 // fade the screen in 00134 void adonthell::fade_in () 00135 { 00136 s_int16 i = 60; 00137 00138 while (i > 0) 00139 { 00140 gametime::update (); 00141 i -= gametime::frames_to_skip () * 2; 00142 if (i < 0) i = 0; 00143 00144 main_loop (); 00145 00146 screen::transition (i * 2); 00147 screen::show (); 00148 } 00149 } 00150 00151 // load the engine state 00152 s_int8 adonthell::get_state (igzstream& file) 00153 { 00154 string name; 00155 00156 // get the current time 00157 gamedate::get_state (file); 00158 00159 // Get the map filename 00160 name << file; 00161 // Load the map from the file 00162 lmap.get (file); 00163 // Load the map state (events) 00164 if (!lmap.get_state (file)) 00165 return false; 00166 00167 view.mapview::attach_map (&lmap); 00168 00169 // Load the mapview state 00170 view.mapview::get_state (file); 00171 view.pack (); 00172 00173 return true; 00174 } 00175 00176 // save the engine state 00177 s_int8 adonthell::put_state (ogzstream& file) 00178 { 00179 // save the current time 00180 gamedate::put_state (file); 00181 00182 // Save the map filename 00183 string name = lmap.filename (); 00184 name >> file; 00185 00186 // Save the map itself 00187 lmap.put (file); 00188 // Save the map state (events) 00189 lmap.put_state (file); 00190 // Save the mapview state 00191 view.mapview::put_state (file); 00192 00193 return 0; 00194 } 00195 00196 void adonthell::mapview_start () 00197 { 00198 set_update_map (true); 00199 00200 view.mapview::resize (screen::length (), screen::height ()); 00201 view.mapview::attach_map (&lmap); 00202 00203 view.set_visible (true); 00204 view.pack (); 00205 00206 win_manager::active->add (&view); 00207 } 00208 00209 void adonthell::mapview_stop () 00210 { 00211 set_update_map (false); 00212 view.mapview::detach_map (); 00213 win_manager::active->remove (&view); 00214 }