script, ui: added "sv_min_startmap_health" cvar
[k8vavoom.git] / vccrun / vcc_run_vobj.cpp
blob576b32f02979a6c83dd8e34ae04dba20d0d4581f
1 //**************************************************************************
2 //**
3 //** ## ## ## ## ## #### #### ### ###
4 //** ## ## ## ## ## ## ## ## ## ## #### ####
5 //** ## ## ## ## ## ## ## ## ## ## ## ## ## ##
6 //** ## ## ######## ## ## ## ## ## ## ## ### ##
7 //** ### ## ## ### ## ## ## ## ## ##
8 //** # ## ## # #### #### ## ##
9 //**
10 //** Copyright (C) 1999-2006 Jānis Legzdiņš
11 //** Copyright (C) 2018-2023 Ketmar Dark
12 //**
13 //** This program is free software: you can redistribute it and/or modify
14 //** it under the terms of the GNU General Public License as published by
15 //** the Free Software Foundation, version 3 of the License ONLY.
16 //**
17 //** This program is distributed in the hope that it will be useful,
18 //** but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 //** GNU General Public License for more details.
21 //**
22 //** You should have received a copy of the GNU General Public License
23 //** along with this program. If not, see <http://www.gnu.org/licenses/>.
24 //**
25 //**************************************************************************
27 //native static final int fsysAppendDir (string path, optional string pfx);
28 IMPLEMENT_FREE_FUNCTION(VObject, fsysAppendDir) {
29 VOptParamStr pfx;
30 VStr fname;
31 vobjGetParam(fname, pfx);
32 //fprintf(stderr, "pakid(%d)=%d; fname=<%s>\n", (int)specified_pakid, pakid, *fname);
33 if (pfx.specified) {
34 RET_INT(fsysAppendDir(fname, pfx));
35 } else {
36 RET_INT(fsysAppendDir(fname));
41 // append archive to the list of archives
42 // it will be searched in the current dir, and then in `fsysBaseDir`
43 // returns pack id or 0
44 //native static final int fsysAppendPak (string fname, optional int pakid);
45 IMPLEMENT_FREE_FUNCTION(VObject, fsysAppendPak) {
46 VStr fname;
47 VOptParamInt pakid(-1);
48 vobjGetParam(fname, pakid);
49 //fprintf(stderr, "pakid(%d)=%d; fname=<%s>\n", (int)specified_pakid, pakid, *fname);
50 if (pakid.specified) {
51 RET_INT(fsysAppendPak(fname, pakid));
52 } else {
53 RET_INT(fsysAppendPak(fname));
57 // remove given pack from pack list
58 //native static final void fsysRemovePak (int pakid);
59 IMPLEMENT_FREE_FUNCTION(VObject, fsysRemovePak) {
60 int pakid;
61 vobjGetParam(pakid);
62 fsysRemovePak(pakid);
65 // remove all packs from pakid and later
66 //native static final void fsysRemovePaksFrom (int pakid);
67 IMPLEMENT_FREE_FUNCTION(VObject, fsysRemovePaksFrom) {
68 int pakid;
69 vobjGetParam(pakid);
70 fsysRemovePaksFrom(pakid);
73 // 0: no such pack
74 //native static final int fsysFindPakByPrefix (string pfx);
75 IMPLEMENT_FREE_FUNCTION(VObject, fsysFindPakByPrefix) {
76 VStr pfx;
77 vobjGetParam(pfx);
78 RET_BOOL(fsysFindPakByPrefix(pfx));
81 //native static final bool fsysFileExists (string fname, optional int pakid);
82 IMPLEMENT_FREE_FUNCTION(VObject, fsysFileExists) {
83 VStr fname;
84 VOptParamInt pakid(-1);
85 vobjGetParam(fname, pakid);
86 if (pakid.specified) {
87 RET_BOOL(fsysFileExists(fname, pakid));
88 } else {
89 RET_BOOL(fsysFileExists(fname));
93 // find file with any extension
94 //native static final string fsysFileFindAnyExt (string fname, optional int pakid);
95 IMPLEMENT_FREE_FUNCTION(VObject, fsysFileFindAnyExt) {
96 VStr fname;
97 VOptParamInt pakid(-1);
98 vobjGetParam(fname, pakid);
99 if (pakid.specified) {
100 RET_STR(fsysFileFindAnyExt(fname, pakid));
101 } else {
102 RET_STR(fsysFileFindAnyExt(fname));
107 // return pack file path for the given pack id (or empty string)
108 //native static final string fsysGetPakPath (int pakid);
109 IMPLEMENT_FREE_FUNCTION(VObject, fsysGetPakPath) {
110 int pakid;
111 vobjGetParam(pakid);
112 RET_STR(fsysGetPakPath(pakid));
115 // return pack prefix for the given pack id (or empty string)
116 //native static final string fsysGetPakPrefix (int pakid);
117 IMPLEMENT_FREE_FUNCTION(VObject, fsysGetPakPrefix) {
118 int pakid;
119 vobjGetParam(pakid);
120 RET_STR(fsysGetPakPrefix(pakid));
124 //native static final int fsysGetLastPakId ();
125 IMPLEMENT_FREE_FUNCTION(VObject, fsysGetLastPakId) {
126 RET_INT(fsysGetLastPakId());
130 IMPLEMENT_FREE_FUNCTION(VObject, get_fsysKillCommonZipPrefix) {
131 RET_BOOL(fsysKillCommonZipPrefix);
134 IMPLEMENT_FREE_FUNCTION(VObject, set_fsysKillCommonZipPrefix) {
135 bool v;
136 vobjGetParam(v);
137 fsysKillCommonZipPrefix = v;
141 // native final void appSetName (string appname);
142 IMPLEMENT_FREE_FUNCTION(VObject, appSetName) {
143 VStr aname;
144 vobjGetParam(aname);
145 appName = aname;
149 #ifdef SERIALIZER_USE_LIBHA
150 static const char *LHABinStorageSignature = "VaVoom C Binary Data Storage V0"; // 32 bytes
152 struct LHAIOData {
153 VStream *sin;
154 VStream *sout;
157 extern "C" {
158 // return number of bytes read; 0: EOF; <0: error; can be less than buf_len
159 static int lhaRead (void *buf, int buf_len, void *udata) {
160 LHAIOData *dd = (LHAIOData *)udata;
161 if (dd->sin->IsError()) return -1;
162 auto left = dd->sin->TotalSize()-dd->sin->Tell();
163 if (left == 0) return 0;
164 if (buf_len > left) buf_len = left;
165 dd->sin->Serialise(buf, buf_len);
166 if (dd->sin->IsError()) return -1;
167 return buf_len;
170 // result != buf_len: error
171 static int lhaWrite (const void *buf, int buf_len, void *udata) {
172 LHAIOData *dd = (LHAIOData *)udata;
173 if (dd->sout->IsError()) return -1;
174 dd->sout->Serialise(buf, buf_len);
175 if (dd->sout->IsError()) return -1;
176 return buf_len;
179 static libha_io_t lhaiostrm {
180 .bread = &lhaRead,
181 .bwrite = &lhaWrite,
184 #endif
187 //native final static bool appSaveOptions (Object optobj, optional string optfile, optional bool packit);
188 IMPLEMENT_FREE_FUNCTION(VObject, appSaveOptions) {
189 VObject *optobj;
190 VOptParamStr optfile;
191 VOptParamBool packit(true);
192 vobjGetParam(optobj, optfile, packit);
193 (void)packit;
194 if (appName.isEmpty() || !optobj) { RET_BOOL(false); return; }
195 if (optobj->GetClass()->Name == NAME_Object) { RET_BOOL(false); return; }
196 ObjectSaveMap svmap(optobj);
197 if (svmap.wasError) { RET_BOOL(false); return; }
198 auto fname = buildConfigName(optfile);
199 if (fname.isEmpty()) { RET_BOOL(false); return; }
200 auto strm = fsysOpenDiskFileWrite(fname);
201 if (!strm) { RET_BOOL(false); return; }
202 #ifdef SERIALIZER_USE_LIBHA
203 if (packit) {
204 auto wrs = new VStreamMemWrite();
205 ObjectSaver saver(*wrs, svmap);
206 bool res = saver.saveAll();
207 if (res && !saver.IsError()) {
208 strm->Serialise(LHABinStorageSignature, 32);
209 auto rds = new VStreamMemRead(wrs->getData(), wrs->Tell());
210 LHAIOData data;
211 data.sin = rds;
212 data.sout = strm;
213 libha_t lha = libha_alloc(&lhaiostrm, &data);
214 if (!lha) {
215 delete rds;
216 delete wrs;
217 VStream::Destroy(strm);
218 RET_BOOL(false);
219 return;
221 auto herr = libha_pack(lha);
222 libha_free(lha);
223 delete rds;
224 delete wrs;
225 VStream::Destroy(strm);
226 RET_BOOL(herr == LIBHA_ERR_OK);
227 } else {
228 delete wrs;
229 VStream::Destroy(strm);
230 RET_BOOL(false);
232 } else {
233 ObjectSaver saver(*strm, svmap);
234 bool res = saver.saveAll();
235 bool err = saver.IsError();
236 VStream::Destroy(strm);
237 RET_BOOL(res && !err);
239 #else
240 ObjectSaver saver(*strm, svmap);
241 bool res = saver.saveAll();
242 bool err = saver.IsError();
243 delete strm;
244 RET_BOOL(res && !err);
245 #endif
249 //native final static spawner Object appLoadOptions (class cls, optional string optfile);
250 IMPLEMENT_FREE_FUNCTION(VObject, appLoadOptions) {
251 VClass *cls;
252 VOptParamStr optfile;
253 vobjGetParam(cls, optfile);
254 if (!cls) { RET_REF(nullptr); return; }
255 if (cls->Name == NAME_Object) { RET_REF(nullptr); return; }
256 if (appName.isEmpty()) { RET_REF(nullptr); return; }
257 auto fname = buildConfigName(optfile);
258 if (fname.isEmpty()) { RET_REF(nullptr); return; }
259 auto strm = fsysOpenDiskFile(fname);
260 if (!strm) { RET_REF(nullptr); return; }
261 #ifdef SERIALIZER_USE_LIBHA
262 char sign[32];
263 strm->Serialise(sign, 32);
264 if (!strm->IsError() && memcmp(sign, LHABinStorageSignature, 32) == 0) {
265 // packed data
266 auto sz = strm->TotalSize()-strm->Tell();
267 auto xbuf = new vuint8[sz];
268 strm->Serialise(xbuf, sz);
269 bool rerr = strm->IsError();
270 VStream::Destroy(strm);
271 if (rerr) {
272 delete xbuf;
273 RET_REF(nullptr);
274 return;
276 auto rds = new VStreamMemRead(xbuf, sz);
277 auto wrs = new VStreamMemWrite();
278 LHAIOData data;
279 data.sin = rds;
280 data.sout = wrs;
281 libha_t lha = libha_alloc(&lhaiostrm, &data);
282 if (!lha) {
283 delete rds;
284 delete wrs;
285 delete xbuf;
286 RET_REF(nullptr);
287 return;
289 auto herr = libha_unpack(lha);
290 libha_free(lha);
291 if (herr != LIBHA_ERR_OK) {
292 delete rds;
293 delete wrs;
294 delete xbuf;
295 RET_REF(nullptr);
296 return;
298 delete rds;
299 delete [] xbuf;
300 rds = new VStreamMemRead(wrs->getData(), wrs->Tell());
301 ObjectLoader ldr(*rds, cls);
302 bool uerr = !ldr.loadAll();
303 delete rds;
304 delete wrs;
305 if (uerr) {
306 ldr.clear();
307 RET_REF(nullptr);
308 return;
310 RET_REF(ldr.objarr[1]); // 0 is `none`
311 } else if (!strm->IsError() && memcmp(sign, BinStorageSignature, 32) == 0) {
312 // unpacked data
313 strm->Seek(0);
314 ObjectLoader ldr(*strm, cls);
315 if (!ldr.loadAll()) {
316 VStream::Destroy(strm);
317 ldr.clear();
318 RET_REF(nullptr);
319 return;
321 VStream::Destroy(strm);
322 RET_REF(ldr.objarr[1]); // 0 is `none`
323 } else {
324 // wutafuck?
325 VStream::Destroy(strm);
326 RET_REF(nullptr);
328 #else
329 ObjectLoader ldr(*strm, cls);
330 if (!ldr.loadAll()) {
331 VStream::Destroy(strm);
332 ldr.clear();
333 RET_REF(nullptr);
334 return;
336 VStream::Destroy(strm);
337 //fprintf(stderr, "%p\n", ldr.objarr[1]);
338 RET_REF(ldr.objarr[1]); // 0 is `none`
339 #endif
343 //static final void PostQuitEvent (int code);
344 IMPLEMENT_FREE_FUNCTION(VObject, PostQuitEvent) {
345 int code;
346 vobjGetParam(code);
347 ::PostQuitEvent(code);
351 //static final int RunMainEventLoop (optional ref event_t qevent);
352 IMPLEMENT_FREE_FUNCTION(VObject, RunMainEventLoop) {
353 VOptParamPtr<event_t> qevt;
354 vobjGetParam(qevt);
355 RET_INT(::VCC_RunEventLoop(qevt.value));
359 // timer API for non-SDL apps
360 // `vccSetTimer` and `vccSetInterval` returns timer id, or 0 on error
361 //native static final int vccSetTimer (int mstimeout);
362 IMPLEMENT_FREE_FUNCTION(VObject, vccSetTimer) {
363 int mstimeout;
364 vobjGetParam(mstimeout);
365 RET_INT(::VCC_SetTimer(mstimeout));
368 //native static final int vccSetInterval (int mstimeout);
369 IMPLEMENT_FREE_FUNCTION(VObject, vccSetInterval) {
370 int mstimeout;
371 vobjGetParam(mstimeout);
372 RET_INT(::VCC_SetInterval(mstimeout));
375 //native static final void vccCancelInterval (int iid);
376 IMPLEMENT_FREE_FUNCTION(VObject, vccCancelInterval) {
377 int mstimeout;
378 vobjGetParam(mstimeout);
379 ::VCC_CancelInterval(mstimeout);
383 // returns `false` if TTY is not available at all
384 //native static bool ttyIsAvailable () noexcept;
385 IMPLEMENT_FREE_FUNCTION(VObject, ttyIsAvailable) {
386 RET_BOOL(ttyIsAvailable());
389 // returns `true` if TTY is good and supports fancy features
390 // if TTY is not good, no other API will work, and calling 'em is UB
391 //native static bool ttyIsGood () noexcept;
392 IMPLEMENT_FREE_FUNCTION(VObject, ttyIsGood) {
393 RET_BOOL(ttyIsGood());
396 // switch TTY to raw or to normal mode
397 // returns `false` if failed
398 // WARNING! calls are not counted! i.e. two disables and then one enable will enable
399 //native static bool ttySetRawMode (bool enable) noexcept;
400 IMPLEMENT_FREE_FUNCTION(VObject, ttySetRawMode) {
401 bool enable;
402 vobjGetParam(enable);
403 //if (!enable) ttySetWaitKey(true);
404 ttySetWaitKey(!enable);
405 RET_BOOL(ttySetRawMode(enable));
406 //if (!enable) ttySetWaitKey(false);
409 // returns current TTY mode as was previously set by `ttySetRawMode()`
410 //native static bool ttyIsInRawMode () noexcept;
411 IMPLEMENT_FREE_FUNCTION(VObject, ttyIsInRawMode) {
412 RET_BOOL(ttyIsInRawMode());
415 // returns TTY size
416 //native static int ttyGetWidth () noexcept;
417 IMPLEMENT_FREE_FUNCTION(VObject, ttyGetWidth) {
418 RET_INT(ttyGetWidth());
421 //native static int ttyGetHeight () noexcept;
422 IMPLEMENT_FREE_FUNCTION(VObject, ttyGetHeight) {
423 RET_INT(ttyGetHeight());
426 //native static final void ttyRawWrite (string format, ...) [printf,1];
427 IMPLEMENT_FREE_FUNCTION(VObject, ttyRawWrite) {
428 VStr s = VObject::PF_FormatString();
429 if (!s.isEmpty()) ttyRawWrite("%s", *s);
432 //native static final void ttyBeep ();
433 IMPLEMENT_FREE_FUNCTION(VObject, ttyBeep) {
434 ttyBeep();
437 //native static final void ttyEnableBracketedPaste ();
438 IMPLEMENT_FREE_FUNCTION(VObject, ttyEnableBracketedPaste) {
439 ttyEnableBracketedPaste();
442 //native static final void ttyDisableBracketedPaste ();
443 IMPLEMENT_FREE_FUNCTION(VObject, ttyDisableBracketedPaste) {
444 ttyDisableBracketedPaste();
447 //native static final void ttyEnableFocusReports ();
448 IMPLEMENT_FREE_FUNCTION(VObject, ttyEnableFocusReports) {
449 ttyEnableFocusReports();
452 //native static final void ttyDisableFocusReports ();
453 IMPLEMENT_FREE_FUNCTION(VObject, ttyDisableFocusReports) {
454 ttyDisableFocusReports();
457 //native static final void ttyEnableMouseReports ();
458 IMPLEMENT_FREE_FUNCTION(VObject, ttyEnableMouseReports) {
459 ttyEnableMouseReports();
462 //native static final void ttyDisableMouseReports ();
463 IMPLEMENT_FREE_FUNCTION(VObject, ttyDisableMouseReports) {
464 ttyDisableMouseReports();