… | |
… | |
42 | #define MODULEAPI |
42 | #define MODULEAPI |
43 | #endif |
43 | #endif |
44 | |
44 | |
45 | #include <plugin_common.h> |
45 | #include <plugin_common.h> |
46 | #include <sounds.h> |
46 | #include <sounds.h> |
47 | |
|
|
48 | #include <stdarg.h> |
47 | #include <cstdarg> |
49 | |
|
|
50 | #include <sproto.h> |
48 | #include <sproto.h> |
51 | |
49 | |
52 | //#include "EventAPI.h" |
50 | #include "cfperl.h" |
|
|
51 | |
53 | #include "perlxsi.c" |
52 | #include "perlxsi.c" |
54 | |
53 | |
55 | static void *globalEventListener (int *type, ...); |
54 | static void *globalEventListener (int *type, ...); |
56 | |
55 | |
57 | extern sint64 *levels; // the experience table |
56 | extern sint64 *levels; // the experience table |
… | |
… | |
216 | else |
215 | else |
217 | return 0; |
216 | return 0; |
218 | } |
217 | } |
219 | |
218 | |
220 | static SV * |
219 | static SV * |
221 | newSVcfapi (int type, ...) |
220 | newSVdt_va (va_list &ap, data_type type) |
222 | { |
221 | { |
223 | SV *sv; |
222 | SV *sv; |
224 | |
|
|
225 | va_list args; |
|
|
226 | va_start (args, type); |
|
|
227 | |
223 | |
228 | switch (type) |
224 | switch (type) |
229 | { |
225 | { |
230 | #if 0 |
|
|
231 | case CFAPI_INT16: |
226 | case DT_INT: |
232 | sv = newSViv (*va_arg (args, sint16_t *)); |
227 | sv = newSViv (*va_arg (ap, int *)); |
233 | break; |
228 | break; |
234 | #endif |
|
|
235 | |
229 | |
236 | case CFAPI_INT: |
230 | case DT_LONG: |
237 | sv = newSViv (*va_arg (args, int *)); |
231 | sv = newSVval64 ((val64)*va_arg (ap, sint64 *)); |
238 | break; |
232 | break; |
239 | |
233 | |
240 | case CFAPI_LONG: |
234 | case DT_DOUBLE: |
241 | sv = newSVval64 ((val64)*va_arg (args, sint64 *)); |
235 | sv = newSVnv (*va_arg (ap, double *)); |
242 | break; |
236 | break; |
243 | |
237 | |
244 | case CFAPI_DOUBLE: |
|
|
245 | sv = newSVnv (*va_arg (args, double *)); |
|
|
246 | break; |
|
|
247 | |
|
|
248 | case CFAPI_STRING: |
238 | case DT_STRING: |
249 | { |
239 | { |
250 | char *str = va_arg (args, char *); |
240 | char *str = va_arg (ap, char *); |
251 | sv = str ? newSVpv (str, 0) : &PL_sv_undef; |
241 | sv = str ? newSVpv (str, 0) : &PL_sv_undef; |
252 | } |
242 | } |
253 | break; |
243 | break; |
254 | |
244 | |
255 | case CFAPI_POBJECT: |
245 | case DT_DATA: |
256 | { |
246 | { |
|
|
247 | char *str = (char *)va_arg (ap, void *); |
|
|
248 | int len = va_arg (ap, int); |
|
|
249 | sv = str ? newSVpv (str, len) : &PL_sv_undef; |
|
|
250 | } |
|
|
251 | break; |
|
|
252 | |
|
|
253 | case DT_OBJECT: |
|
|
254 | { |
257 | object *obj = va_arg (args, object *); |
255 | object *obj = va_arg (ap, object *); |
258 | |
256 | |
259 | if (!obj) |
257 | if (!obj) |
260 | sv = &PL_sv_undef; |
258 | sv = &PL_sv_undef; |
261 | else |
259 | else |
262 | switch (obj->type) |
260 | switch (obj->type) |
… | |
… | |
274 | break; |
272 | break; |
275 | } |
273 | } |
276 | } |
274 | } |
277 | break; |
275 | break; |
278 | |
276 | |
279 | case CFAPI_PMAP: |
277 | case DT_MAP: |
280 | sv = newSVptr (va_arg (args, mapstruct *), "cf::map::wrap"); |
278 | sv = newSVptr (va_arg (ap, mapstruct *), "cf::map::wrap"); |
281 | break; |
279 | break; |
282 | |
280 | |
283 | case CFAPI_PPLAYER: |
281 | case DT_PLAYER: |
284 | sv = newSVptr (va_arg (args, player *), "cf::player::wrap"); |
282 | sv = newSVptr (va_arg (ap, player *), "cf::player::wrap"); |
285 | break; |
283 | break; |
286 | |
284 | |
287 | case CFAPI_PARCH: |
285 | case DT_ARCH: |
288 | sv = newSVptr (va_arg (args, archetype *), "cf::arch::wrap"); |
286 | sv = newSVptr (va_arg (ap, archetype *), "cf::arch::wrap"); |
289 | break; |
287 | break; |
290 | |
288 | |
291 | case CFAPI_PPARTY: |
289 | case DT_PARTY: |
292 | sv = newSVptr (va_arg (args, partylist *), "cf::party::wrap"); |
290 | sv = newSVptr (va_arg (ap, partylist *), "cf::party::wrap"); |
293 | break; |
291 | break; |
294 | |
292 | |
295 | case CFAPI_PREGION: |
293 | case DT_REGION: |
296 | sv = newSVptr (va_arg (args, region *), "cf::region::wrap"); |
294 | sv = newSVptr (va_arg (ap, region *), "cf::region::wrap"); |
297 | break; |
295 | break; |
|
|
296 | |
|
|
297 | default: |
|
|
298 | assert (("unhandled type in newSVdt_va", 0)); |
|
|
299 | } |
|
|
300 | |
|
|
301 | return sv; |
|
|
302 | } |
|
|
303 | |
|
|
304 | static SV * |
|
|
305 | newSVdt (data_type type, ...) |
|
|
306 | { |
|
|
307 | va_list ap; |
|
|
308 | |
|
|
309 | va_start (ap, type); |
|
|
310 | SV *sv = newSVdt_va (ap, type); |
|
|
311 | va_end (ap); |
|
|
312 | |
|
|
313 | return sv; |
|
|
314 | } |
|
|
315 | |
|
|
316 | static SV * |
|
|
317 | newSVcfapi (int type, ...) |
|
|
318 | { |
|
|
319 | SV *sv; |
|
|
320 | |
|
|
321 | va_list ap; |
|
|
322 | va_start (ap, type); |
|
|
323 | |
|
|
324 | switch (type) |
|
|
325 | { |
|
|
326 | case CFAPI_INT: sv = newSVdt_va (ap, DT_INT ); break; |
|
|
327 | case CFAPI_LONG: sv = newSVdt_va (ap, DT_LONG ); break; |
|
|
328 | case CFAPI_DOUBLE: sv = newSVdt_va (ap, DT_DOUBLE); break; |
|
|
329 | case CFAPI_STRING: sv = newSVdt_va (ap, DT_STRING); break; |
|
|
330 | case CFAPI_POBJECT: sv = newSVdt_va (ap, DT_OBJECT); break; |
|
|
331 | case CFAPI_PMAP: sv = newSVdt_va (ap, DT_MAP ); break; |
|
|
332 | case CFAPI_PPLAYER: sv = newSVdt_va (ap, DT_PLAYER); break; |
|
|
333 | case CFAPI_PARCH: sv = newSVdt_va (ap, DT_ARCH ); break; |
|
|
334 | case CFAPI_PPARTY: sv = newSVdt_va (ap, DT_PARTY ); break; |
|
|
335 | case CFAPI_PREGION: sv = newSVdt_va (ap, DT_REGION); break; |
298 | |
336 | |
299 | default: |
337 | default: |
300 | assert (("unhandled type in newSVcfapi", 0)); |
338 | assert (("unhandled type in newSVcfapi", 0)); |
301 | } |
339 | } |
302 | |
340 | |
303 | va_end (args); |
341 | va_end (ap); |
304 | |
342 | |
305 | return sv; |
343 | return sv; |
306 | } |
344 | } |
307 | |
345 | |
308 | ///////////////////////////////////////////////////////////////////////////// |
346 | ///////////////////////////////////////////////////////////////////////////// |
… | |
… | |
701 | return &rv; |
739 | return &rv; |
702 | } |
740 | } |
703 | |
741 | |
704 | extern "C" int cfperl_closePlugin () |
742 | extern "C" int cfperl_closePlugin () |
705 | { |
743 | { |
706 | printf (PLUGIN_VERSION " closing\n"); |
|
|
707 | |
|
|
708 | if (perl) |
|
|
709 | { |
|
|
710 | perl_destruct (perl); |
|
|
711 | perl_free (perl); |
|
|
712 | perl = 0; |
|
|
713 | } |
|
|
714 | |
|
|
715 | return 0; |
744 | return 0; |
716 | } |
745 | } |
717 | |
746 | |
718 | void cfperl_main () |
747 | void cfperl_main () |
719 | { |
748 | { |
720 | dSP; |
749 | dSP; |
721 | |
750 | |
722 | PUSHMARK (SP); |
751 | PUSHMARK (SP); |
723 | PUTBACK; |
752 | PUTBACK; |
724 | call_pv ("cf::run", G_DISCARD | G_VOID); |
753 | call_pv ("cf::run", G_DISCARD | G_VOID); |
|
|
754 | } |
|
|
755 | |
|
|
756 | int cfperl_invoke (const char *klass, event_type event, ...) |
|
|
757 | { |
|
|
758 | dSP; |
|
|
759 | va_list ap; |
|
|
760 | |
|
|
761 | ENTER; |
|
|
762 | SAVETMPS; |
|
|
763 | |
|
|
764 | va_start (ap, event); |
|
|
765 | PUSHMARK (SP); |
|
|
766 | EXTEND (SP, 2); |
|
|
767 | PUSHs (sv_2mortal (newSViv (event))); |
|
|
768 | |
|
|
769 | for (;;) |
|
|
770 | { |
|
|
771 | data_type dt = (data_type) va_arg (ap, int); |
|
|
772 | |
|
|
773 | if (dt == DT_END) |
|
|
774 | break; |
|
|
775 | |
|
|
776 | PUSHs (sv_2mortal (newSVdt_va (ap, dt))); |
|
|
777 | } |
|
|
778 | |
|
|
779 | va_end (ap); |
|
|
780 | |
|
|
781 | PUTBACK; |
|
|
782 | int count = call_pv (klass, G_SCALAR | G_EVAL); |
725 | SPAGAIN; |
783 | SPAGAIN; |
726 | PUTBACK; |
784 | |
|
|
785 | count = count > 0 ? POPi : 0; |
|
|
786 | |
|
|
787 | FREETMPS; |
|
|
788 | LEAVE; |
|
|
789 | |
|
|
790 | return count; |
727 | } |
791 | } |
728 | |
792 | |
729 | MODULE = cf PACKAGE = cf PREFIX = cf_ |
793 | MODULE = cf PACKAGE = cf PREFIX = cf_ |
730 | |
794 | |
731 | BOOT: |
795 | BOOT: |
… | |
… | |
1218 | newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); |
1282 | newCONSTSUB (stash, (char *)civ->name, newSViv (civ->iv)); |
1219 | |
1283 | |
1220 | static const struct { |
1284 | static const struct { |
1221 | const char *name; |
1285 | const char *name; |
1222 | IV iv; |
1286 | IV iv; |
|
|
1287 | } *eiv, event_iv[] = { |
|
|
1288 | # define def(name) { # name, (IV)EV_ ## name }, |
|
|
1289 | # include "eventinc.h" |
|
|
1290 | # undef def |
|
|
1291 | }; |
|
|
1292 | |
|
|
1293 | AV *av = get_av ("cf::EVENT", 1); |
|
|
1294 | |
|
|
1295 | for (eiv = event_iv + sizeof (event_iv) / sizeof (event_iv [0]); eiv-- > event_iv; ) |
|
|
1296 | av_store (av, eiv->iv, newSVpv ((char *)eiv->name, 0)); |
|
|
1297 | |
|
|
1298 | static const struct { |
|
|
1299 | const char *name; |
|
|
1300 | IV iv; |
1223 | } *event, event_list[] = { |
1301 | } *event, event_list[] = { |
1224 | # define const_event(name) { # name, (IV)EVENT_ ## name }, |
1302 | # define const_event(name) { # name, (IV)EVENT_ ## name }, |
1225 | const_event (NONE) |
1303 | const_event (NONE) |
1226 | const_event (APPLY) |
1304 | const_event (APPLY) |
1227 | const_event (ATTACK) |
1305 | const_event (ATTACK) |
… | |
… | |
1265 | const_event (FIND_UNARMED_SKILL) |
1343 | const_event (FIND_UNARMED_SKILL) |
1266 | const_event (EXTCMD) |
1344 | const_event (EXTCMD) |
1267 | //const_event (FREE_OB) |
1345 | //const_event (FREE_OB) |
1268 | }; |
1346 | }; |
1269 | |
1347 | |
1270 | AV *av = get_av ("cf::EVENT", 1); |
1348 | av = get_av ("cf::PLUGIN_EVENT", 1); |
1271 | |
1349 | |
1272 | for (event = event_list + sizeof (event_list) / sizeof (event_list [0]); event-- > event_list; ) |
1350 | for (event = event_list + sizeof (event_list) / sizeof (event_list [0]); event-- > event_list; ) |
1273 | av_store (av, event->iv, newSVpv ((char *)event->name, 0)); |
1351 | av_store (av, event->iv, newSVpv ((char *)event->name, 0)); |
1274 | |
1352 | |
1275 | static const struct { |
1353 | static const struct { |