convert line ends
[canaan.git] / prj / cam / src / render / antxloop.cpp
blob62423abab4e26f3c7a12307d79af85b83b9ad739
1 /*
2 @Copyright Looking Glass Studios, Inc.
3 1996,1997,1998,1999,2000 Unpublished Work.
4 */
6 // $Header: r:/t2repos/thief2/src/render/antxloop.cpp,v 1.3 1998/09/08 13:48:24 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 <antxloop.h>
20 #include <antxtype.h>
22 #include <port.h>
23 #include <wrfunc.h>
24 #include <wrdbrend.h>
25 #include <objpos.h>
26 #include <texmem.h>
28 #include <appagg.h>
29 #include <str.h>
30 #include <mprintf.h>
31 #include <ctype.h>
32 #include <string.h>
33 #include <stdlib.h>
35 // Must be last header
36 #include <dbmem.h>
37 #include <tagfile.h>
38 #include <vernum.h>
40 //////////////////
41 // CONSTANTS
45 #define MY_GUID LOOPID_AnimTexture
47 cTexturePatchTable gTexturePatchTable;
48 cTexturePatchTable gTextureInverseTable;
51 // Context data
52 typedef void Context;
55 // State record
56 typedef struct _StateRecord
58 Context* context;
59 } StateRecord;
61 //////////////////////////////////////////////////
62 // tag file structures
64 TagFileTag TexturePatchTag = { "TXTPAT_DB" };
65 TagVersion TexturePatchVersion = { 0, 1 };
67 static ITagFile* tagfile = NULL;
68 static long movefunc(void *buf, size_t elsize, size_t nelem)
70 return ITagFile_Move(tagfile,(char*)buf,elsize*nelem);
73 static BOOL setup_tagfile(ITagFile* file, TagFileTag *tag,
74 TagVersion *version)
76 HRESULT result;
77 TagVersion found_version = *version;
78 tagfile = file;
80 result = file->OpenBlock(tag, &found_version);
81 if (!VersionNumsEqual(&found_version,version))
83 file->CloseBlock();
84 return FALSE;
87 return result == S_OK;
90 static void cleanup_tagfile(ITagFile* file)
92 file->CloseBlock();
95 ////////////////////////////////////////////////////////////
96 // Do the save
98 static void AnimTextureSave(msgDatabaseData *data)
100 int len,val;
101 cTexturePatchTable::cIter iter;
103 // dump the contents of the hashtable out to disk
104 if (setup_tagfile(data->save, &TexturePatchTag,
105 &TexturePatchVersion))
107 len = gTexturePatchTable.nElems();
108 movefunc((void *)&len, sizeof(int), 1);
109 iter = gTexturePatchTable.Iter();
110 while (!iter.Done())
112 val = iter.Key();
113 movefunc((void *)&val, sizeof(int), 1);
114 val = iter.Value();
115 movefunc((void *)&val, sizeof(int), 1);
117 iter.Next();
120 cleanup_tagfile(data->save);
124 ////////////////////////////////////////////////////////////
125 // Actually apply the patches, like craze, detox, etc.
127 void AnimTextureApplyPatches(cTexturePatchTable *pTable)
129 cTexturePatchTable::cIter iter;
130 int cellid,polyid,texval;
131 iter = pTable->Iter();
132 PortalPolygonRenderInfo *ppri;
133 PortalCell *pcell;
135 // for each entry in the patch table, break it down into the cell and renderpoly
136 // ids, then go poke in the correct new values.
137 while (!iter.Done())
139 cellid = iter.Key() >> 8;
140 polyid = iter.Key() & 0xFF;
141 texval = iter.Value();
143 pcell = WR_CELL(cellid);
144 ppri = &pcell->render_list[polyid];
145 ppri->texture_id = texval;
146 iter.Next();
150 ////////////////////////////////////////////////////////////
151 // Do the load
153 static void AnimTextureLoad(msgDatabaseData *data)
155 int len, val, key;
156 int i;
158 // read back in the patch table
159 if (setup_tagfile(data->load, &TexturePatchTag,
160 &TexturePatchVersion))
162 movefunc((void *)&len, sizeof(int), 1);
163 for (i=0; i < len; i++)
165 movefunc((void *)&key, sizeof(int), 1);
166 movefunc((void *)&val, sizeof(int), 1);
167 gTexturePatchTable.Set(key,val);
169 cleanup_tagfile(data->load);
172 // now read through the table and apply the patches
173 AnimTextureApplyPatches(&gTexturePatchTable);
176 ////////////////////////////////////////////////////////////
177 // Database message handler
180 static void db_message(DispatchData* msg)
182 msgDatabaseData data;
183 data.raw = msg->data;
185 switch (DB_MSG(msg->subtype))
187 case kDatabaseReset:
188 case kDatabaseDefault:
189 gTexturePatchTable.Clear();
190 break;
192 case kDatabaseSave:
193 if (msg->subtype & kDBMission)
194 AnimTextureSave(&data);
195 break;
197 case kDatabaseLoad:
198 if (msg->subtype & kDBMission)
199 AnimTextureLoad(&data);
200 break;
204 ////////////////////////////////////////
206 // LOOP/DISPATCH callback
207 // Here's where we do the dirty work.
210 #pragma off(unreferenced)
211 static eLoopMessageResult LGAPI _LoopFunc(void* data, eLoopMessage msg, tLoopMessageData hdata)
213 // useful stuff for most clients
214 eLoopMessageResult result = kLoopDispatchContinue;
215 StateRecord* state = (StateRecord*)data;
216 LoopMsg info;
218 info.raw = hdata;
220 switch(msg)
222 case kMsgAppInit:
223 break;
225 case kMsgAppTerm:
226 break;
228 case kMsgDatabase:
229 db_message(info.dispatch);
230 break;
232 case kMsgEnd:
233 Free(state);
234 break;
236 return result;
239 ////////////////////////////////////////////////////////////
241 // Loop client factory function.
244 #pragma off(unreferenced)
245 static ILoopClient* LGAPI _CreateClient(sLoopClientDesc * pDesc, tLoopClientData data)
247 StateRecord* state;
248 // allocate space for our state, and fill out the fields
249 state = (StateRecord*)Malloc(sizeof(StateRecord));
250 state->context = (Context*)data;
252 return CreateSimpleLoopClient(_LoopFunc,state,pDesc);
254 #pragma on(unreferenced)
257 ///////////////
258 // DESCRIPTOR
261 sLoopClientDesc AnimTextureLoopClientDesc =
263 &MY_GUID,
264 "Animating Texture System",
265 kPriorityNormal,
266 kMsgDatabase | kMsgsAppOuter, // interests
268 kLCF_Callback,
269 _CreateClient,
271 NO_LC_DATA,
274 {kNullConstraint}