convert line ends
[canaan.git] / prj / cam / src / engfeat / quesloop.cpp
blob491e8b0a9ff2800f0024696f04ed4bbf3dc7b9a3
1 /*
2 @Copyright Looking Glass Studios, Inc.
3 1996,1997,1998,1999,2000 Unpublished Work.
4 */
6 // $Header: r:/t2repos/thief2/src/engfeat/quesloop.cpp,v 1.9 1998/10/27 12:20:38 mahk Exp $
8 #include <lg.h>
9 #include <loopapi.h>
11 #include <loopmsg.h>
12 #include <dispatch.h>
13 #include <dispbase.h>
14 #include <dbasemsg.h>
15 #include <iobjsys.h>
16 #include <objnotif.h>
17 #include <objdef.h>
19 #include <quesloop.h>
20 #include <quesedit.h>
22 #include <appagg.h>
23 #include <questapi.h>
24 #include <str.h>
25 #include <mprintf.h>
26 #include <ctype.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #include <command.h>
30 #include <simpwrap.h>
31 #include <quesfile.h>
33 #include <campaign.h>
34 #include <cmpgnmsg.h>
35 #include <dspchdef.h>
37 #include <sdesc.h>
38 #include <sdesbase.h>
39 #include <isdesced.h>
40 #include <isdescst.h>
42 // Must be last header
43 #include <dbmem.h>
44 #include <tagfile.h>
45 #include <vernum.h>
47 //////////////////
48 // CONSTANTS
52 #define MY_GUID LOOPID_Quest
55 // Context data
56 typedef void Context;
59 // State record
60 typedef struct _StateRecord
62 Context* context;
63 } StateRecord;
65 //////////////////////////////////////////////////
66 // Quest system tag file structures
68 TagFileTag QuestSystemTags[2] = { { "QUEST_DB" }, {"QUEST_CMP" } };
69 TagVersion QuestSystemVersion = { 0, 1 };
71 static ITagFile* tagfile = NULL;
72 static long movefunc(void *buf, size_t elsize, size_t nelem)
74 return ITagFile_Move(tagfile,(char*)buf,elsize*nelem);
77 static BOOL setup_tagfile(ITagFile* file, TagFileTag *tag,
78 TagVersion *version)
80 HRESULT result;
81 TagVersion found_version = *version;
82 tagfile = file;
84 result = file->OpenBlock(tag, &found_version);
85 if (!VersionNumsEqual(&found_version,version))
87 file->CloseBlock();
88 return FALSE;
91 return result == S_OK;
95 static void cleanup_tagfile(ITagFile* file)
97 file->CloseBlock();
101 EXTERN void QuestDataLoadTagFile(eQuestDataType type, ITagFile* file)
103 if (setup_tagfile(file, &QuestSystemTags[type],
104 &QuestSystemVersion))
106 AutoAppIPtr(QuestData);
107 pQuestData->Load(movefunc, type);
108 cleanup_tagfile(file);
112 EXTERN void QuestDataSaveTagFile(eQuestDataType type, ITagFile* File)
115 if (setup_tagfile(File, &QuestSystemTags[type],
116 &QuestSystemVersion))
118 AutoAppIPtr(QuestData);
119 pQuestData->Save(movefunc, type);
120 cleanup_tagfile(File);
125 ////////////////////////////////////////////////////////////
126 // Database message handler
129 static void db_message(DispatchData* msg)
131 AutoAppIPtr(QuestData);
132 msgDatabaseData data;
133 data.raw = msg->data;
135 switch (DB_MSG(msg->subtype))
137 case kDatabaseReset:
138 // Hey, the campaign isn't a part of this, OK?
139 pQuestData->DeleteAllType(kQuestDataMission);
140 pQuestData->UnsubscribeAll();
141 break;
143 case kDatabaseDefault:
144 break;
146 case kDatabaseSave:
147 if (msg->subtype & kDBMission)
148 QuestDataSaveTagFile(kQuestDataMission,data.save);
150 break;
152 case kDatabaseLoad:
153 if (msg->subtype & kDBMission)
154 QuestDataLoadTagFile(kQuestDataMission,data.load);
156 break;
160 ////////////////////////////////////////
162 // LOOP/DISPATCH callback
163 // Here's where we do the dirty work.
166 void setup_campaign();
168 #pragma off(unreferenced)
169 static eLoopMessageResult LGAPI _LoopFunc(void* data, eLoopMessage msg, tLoopMessageData hdata)
171 // useful stuff for most clients
172 eLoopMessageResult result = kLoopDispatchContinue;
173 StateRecord* state = (StateRecord*)data;
174 LoopMsg info;
176 info.raw = hdata;
178 switch(msg)
180 case kMsgAppInit:
181 setup_campaign();
182 #ifdef EDITOR
183 QuestEditInit();
184 #endif
185 break;
187 case kMsgAppTerm:
188 break;
190 case kMsgDatabase:
191 db_message(info.dispatch);
192 break;
194 case kMsgEnd:
195 Free(state);
196 break;
198 return result;
201 ////////////////////////////////////////////////////////////
203 // Loop client factory function.
206 #pragma off(unreferenced)
207 static ILoopClient* LGAPI _CreateClient(sLoopClientDesc * pDesc, tLoopClientData data)
209 StateRecord* state;
210 // allocate space for our state, and fill out the fields
211 state = (StateRecord*)Malloc(sizeof(StateRecord));
212 state->context = (Context*)data;
214 return CreateSimpleLoopClient(_LoopFunc,state,pDesc);
216 #pragma on(unreferenced)
218 ///////////////
219 // DESCRIPTOR
222 sLoopClientDesc QuestLoopClientDesc =
224 &MY_GUID,
225 "Quest Data System",
226 kPriorityNormal,
227 kMsgDatabase | kMsgsAppOuter | kMsgEnd, // interests
229 kLCF_Callback,
230 _CreateClient,
232 NO_LC_DATA,
235 {kNullConstraint}
239 ////////////////////////////////////////////////////////////
240 // CAMPAIGN LISTENER
243 static void campaign_cb(const sDispatchMsg* dmsg, const sDispatchListenerDesc* desc)
245 AutoAppIPtr(QuestData);
246 sCampaignMsg* msg = (sCampaignMsg*)dmsg;
247 switch(msg->kind)
249 case kCampaignReset:
250 pQuestData->DeleteAllType(kQuestDataCampaign);
251 break;
253 case kCampaignSave:
254 QuestDataSaveTagFile(kQuestDataCampaign,msg->file);
255 break;
257 case kCampaignLoad:
258 QuestDataLoadTagFile(kQuestDataCampaign,msg->file);
259 break;
264 static sDispatchListenerDesc camp_desc =
266 &MY_GUID, // guid
267 kCampaignAll,
268 campaign_cb,
269 NULL,
272 static void setup_campaign()
274 AutoAppIPtr(Campaign);
275 pCampaign->Listen(&camp_desc);