Linux makefiles
[canaan.git] / prj / cam / src / shock / shksloop.cpp
blobe32d3ba66316f435d3714402f8332178d002f7b9
1 /*
2 @Copyright Looking Glass Studios, Inc.
3 1996,1997,1998,1999,2000 Unpublished Work.
4 */
6 // $Header: r:/t2repos/thief2/src/shock/shksloop.cpp,v 1.57 1999/11/19 14:58:22 adurant Exp $
8 #include <lg.h>
9 #include <loopapi.h>
10 #include <config.h>
11 #include <res.h>
13 #include <dispbase.h>
14 #include <loopmsg.h>
15 //#include <objmsg.h>
16 #include <dbasemsg.h>
18 #include <netman.h>
20 #include <ailoop.h>
21 #include <biploop.h>
22 #include <simloop.h>
23 #include <shkloop.h>
24 #include <physloop.h>
25 #include <plyrloop.h>
26 #include <objloop.h>
27 #include <gen_bind.h>
28 #include <scrnmode.h>
30 #include <uiloop.h>
31 #include <netloop.h>
32 #include <gamemode.h>
33 #include <transmod.h>
35 #include <headmove.h>
36 #include <shkgame.h>
37 #include <playrobj.h>
38 #include <simstate.h>
39 #include <simflags.h>
40 #include <prjctile.h>
41 //#include <netcfg.h>
42 #include <gamemode.h>
43 #include <shkmulti.h>
44 #include <shknet.h>
45 #include <frobctrl.h>
46 #include <shkammov.h>
48 #include <prjctile.h>
49 #include <particle.h>
51 //#include <appnet.h>
52 //#include <pklogin.h>
54 #include <label.h>
55 #include <hpprop.h>
56 #include <dmgprop.h>
57 #include <slitprop.h>
58 #include <doorprop.h>
60 #include <shkplayr.h>
61 #include <gunprop.h>
62 #include <shkpsapi.h>
63 #include <shkpsipw.h>
64 #include <shkctrl.h>
65 #include <shkprop.h>
66 #include <shkinv.h>
67 #include <scrptprp.h>
68 #include <shkpgapi.h>
69 #include <shkreact.h>
70 #include <shkcmapi.h>
71 #include <shkplcst.h>
72 #include <shkcmobj.h>
73 #include <shkiface.h>
74 #include <shkifstr.h>
75 #include <shkutils.h>
77 // E3 DEMO
78 #include <shkhacks.h>
80 // Must be last header
81 #include <dbmem.h>
83 /////////////////////////////////////////////////////////////
84 // SHOCK SIMULATION LOOP CLIENT
85 ////////////////////////////////////////////////////////////
87 static bool gMode;
89 //////////////////
90 // CONSTANTS
92 // These are just here to separate out boiler-plate code and leave it untouched
96 #define MY_FACTORY ShockSimLoopFactory
97 #define MY_GUID LOOPID_ShockSim
99 // My context data
100 typedef void Context;
102 // My state
103 typedef struct _StateRecord
105 Context* context; // a pointer to the context data I got.
106 BOOL in_game_mode;
107 // State fields go here
108 } StateRecord;
110 static IPlayerGun *g_pPlayerGun = NULL;
111 static IShockCamera *g_pShockCamera = NULL;
113 ////////////////////////////////////////
115 // LOOP/DISPATCH callback
116 // Here's where we do the dirty work.
119 static void db_message(DispatchData* msg)
121 msgDatabaseData data;
122 data.raw = msg->data;
124 switch (DB_MSG(msg->subtype))
126 case kDatabaseReset:
127 PsiPowersReset();
129 AutoAppIPtr(PlayerGun);
130 pPlayerGun->Off();
132 break;
133 case kDatabasePostLoad:
134 case kDatabaseDefault:
135 InitProjectileArchetype();
136 InitParticleArchetype();
137 ShockInvReset();
138 //gChar->ClearEquip();
139 ShockReactionsPostLoad();
141 // Clear some variables that will get awkward if we begin running
142 // frames without the sim on (which will happen in multiplayer).
143 frobWorldSelectObj = OBJ_NULL;
144 g_ifaceFocusObj = OBJ_NULL;
145 gHelpString[0] = '\0';
146 break;
150 void EquipWeapon(void)
152 if (PlayerObjectExists())
154 ObjID gunobj;
155 //AutoAppIPtr(PlayerGun);
156 AutoAppIPtr(ShockPlayer);
157 gunobj = pShockPlayer->GetEquip(PlayerObject(),kEquipWeapon);
158 //pPlayerGun->Set(gunobj);
159 pShockPlayer->SetWeaponModel(gunobj,FALSE);
160 ShockAmmoRefreshButtons();
164 void UnequipWeapon(void)
166 if (PlayerObjectExists())
168 AutoAppIPtr(ShockPlayer);
169 pShockPlayer->SetWeaponModel(OBJ_NULL,FALSE);
173 #pragma off(unreferenced)
174 static eLoopMessageResult LGAPI _LoopFunc(void* data, eLoopMessage msg, tLoopMessageData hdata)
176 // useful stuff for most clients
177 eLoopMessageResult result = kLoopDispatchContinue;
178 StateRecord* state = (StateRecord*)data;
179 LoopMsg info;
181 info.raw = hdata;
183 AutoAppIPtr(ShockPlayer);
185 switch(msg)
187 case kMsgAppInit:
189 shock_init_game();
190 //ResOpenFile("shkres.res");
191 g_pPlayerGun = AppGetObj(IPlayerGun);
192 g_pShockCamera = AppGetObj(IShockCamera);
193 ShockNetInit();
195 break;
197 case kMsgAppTerm:
198 // gee, maybe we should terminate some stuff here
199 // well, now we do!
200 shock_term_game();
201 SafeRelease(g_pPlayerGun);
202 SafeRelease(g_pShockCamera);
203 ShockNetTerm();
204 break;
206 case kMsgEnterMode:
207 state->in_game_mode = IsEqualGUID(*info.mode->to.pID,LOOPID_GameMode);
208 if (state->in_game_mode)
210 // @HACK: start player with pistol and shotgun
212 gChar->AddGun(0, (Label*)"Pistol");
213 gChar->AddGun(1, (Label*)"Shotgun");
214 gChar->SelectGun(0);
216 // E3 DEMO
217 shock_init_hacks();
218 // center so mouse look around will work
219 headmoveInit();
220 EquipWeapon();
221 shock_start_gamemode();
222 // since we may have updated the difficulty level
223 pShockPlayer->RecalcData(PlayerObject());
225 break;
226 case kMsgExitMode:
227 if (state->in_game_mode)
229 shock_end_gamemode();
230 shock_kill_hacks();
231 UnequipWeapon();
233 break;
235 case kMsgNormalFrame:
236 if (SimStateCheckFlags(kSimGameSpec))
238 shock_check_keys();
239 AutoAppIPtr(PlayerPsi);
240 pPlayerPsi->Frame(info.frame->dTicks);
241 g_pShockCamera->Frame();
242 g_pPlayerGun->Frame(info.frame->dTicks);
243 AutoAppIPtr(CameraObjects);
244 pCameraObjects->Frame(info.frame->dTicks);
246 shock_sim_update_frame(info.frame->dTicks);
248 // The player started a quicksave, and we've delayed a frame
249 // in order to display a message:
250 if (gQuickSaveHack > 0)
252 gQuickSaveHack--;
253 if (gQuickSaveHack == 0)
254 ShockQuickSave();
257 // We've changed levels, so let's do a save now:
258 if (gTransSaveHack)
260 gTransSaveHack = FALSE;
262 // If we're networked, then only the host decides to save.
263 // As a side-effect, this will tell everyone else to save
264 // as well.
265 AutoAppIPtr(NetManager);
266 if (!pNetManager->IsNetworkGame() ||
267 pNetManager->AmDefaultHost())
269 char temp[255];
270 ShockStringFetch(temp,sizeof(temp),"QuickSaveName","misc");
271 ShockSaveGame(-1,temp);
276 // Some other player initiated a save, and we've delayed a frame
277 // in order to display a message. This will *often* happen when
278 // the sim is paused...
279 if (gRemoteSaveHack > 0)
281 gRemoteSaveHack--;
282 if (gRemoteSaveHack == 0)
284 DoShockSaveGame(gRemoteSaveSlot, gpRemoteSaveDesc);
285 if (gpRemoteSaveDesc)
287 free(gpRemoteSaveDesc);
288 gpRemoteSaveDesc = NULL;
292 break;
294 case kMsgDatabase:
295 db_message(info.dispatch);
296 break;
298 // MAHK 7/2/99 Why is suspend/resume totally divergent from exit/enter?
299 // I am fixing this so that it does nothing in non-game modes,
300 // since our db_message implies that we are in the base mode.
301 // I bet there are other suspend/resume bugs, but fuck, we
302 // were supposed to ship this yesterday.
303 case kMsgSuspendMode:
304 if (state->in_game_mode)
306 if (shock_mouse)
308 gMode = TRUE;
309 MouseMode(FALSE,FALSE);
311 else
312 gMode = FALSE;
313 UnequipWeapon();
315 break;
316 case kMsgResumeMode:
317 if (state->in_game_mode)
319 if (gMode)
321 MouseMode(TRUE,FALSE);
322 gMode = FALSE;
324 else
326 sScrnMode smode;
327 int centerx,centery;
328 ScrnModeGet(&smode);
329 centerx = smode.w / 2; //grd_visible_canvas->bm.w / 2;
330 centery = smode.h / 2; //grd_visible_canvas->bm.h / 2;
331 mouse_put_xy(centerx, centery);
333 EquipWeapon();
334 // since we may have updated the difficulty level
335 pShockPlayer->RecalcData(PlayerObject());
337 break;
338 case kMsgEnd:
339 Free(state);
340 break;
342 return result;
345 ////////////////////////////////////////////////////////////
347 // Loop client factory function.
350 #pragma off(unreferenced)
351 static ILoopClient* LGAPI _CreateClient(const sLoopClientDesc* desc, tLoopClientData data)
353 StateRecord* state;
354 // allocate space for our state, and fill out the fields
355 state = (StateRecord*)Malloc(sizeof(StateRecord));
356 state->context = (Context*)data;
358 return CreateSimpleLoopClient(_LoopFunc,state,desc);
360 #pragma on(unreferenced)
362 ///////////////
363 // DESCRIPTOR
366 sLoopClientDesc ShockSimLoopClientDesc =
368 &MY_GUID, // GUID
369 "Shock Simulation", // NAME
370 kPriorityNormal, // PRIORITY
371 kMsgEnd | kMsgsMode | kMsgsFrameMid | kMsgsAppOuter | kMsgDatabase, // INTERESTS
373 kLCF_Callback,
374 _CreateClient,
376 NO_LC_DATA,
379 {kConstrainAfter, &LOOPID_Physics, kMsgsFrame},
380 {kConstrainBefore, &LOOPID_SimFinish, kMsgsFrame},
381 {kConstrainAfter, &LOOPID_UI, kMsgsMode},
382 {kConstrainAfter, &LOOPID_Game, kMsgsMode},
383 {kConstrainAfter, &LOOPID_Biped, kMsgsAppOuter},
384 {kConstrainBefore, &LOOPID_Biped, kMsgsFrame},
385 {kConstrainAfter, &LOOPID_Player, kMsgsFrame},
386 {kConstrainBefore, &LOOPID_AI, kMsgsAppOuter},
387 //{kConstrainAfter, &LOOPID_Render, kMsgsFrame},
388 // @Note (toml 04-13-98) dark has the following constraint for the equivalent client:
389 {kConstrainAfter, &LOOPID_ObjSys, kMsgDatabase},
390 {kNullConstraint} // terminator