1 //**************************************************************************
3 //** ## ## ## ## ## #### #### ### ###
4 //** ## ## ## ## ## ## ## ## ## ## #### ####
5 //** ## ## ## ## ## ## ## ## ## ## ## ## ## ##
6 //** ## ## ######## ## ## ## ## ## ## ## ### ##
7 //** ### ## ## ### ## ## ## ## ## ##
8 //** # ## ## # #### #### ## ##
10 //** Copyright (C) 1999-2006 Jānis Legzdiņš
11 //** Copyright (C) 2018-2023 Ketmar Dark
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.
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.
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/>.
25 //**************************************************************************
27 //native static final int fsysAppendDir (string path, optional string pfx);
28 IMPLEMENT_FREE_FUNCTION(VObject
, fsysAppendDir
) {
31 vobjGetParam(fname
, pfx
);
32 //fprintf(stderr, "pakid(%d)=%d; fname=<%s>\n", (int)specified_pakid, pakid, *fname);
34 RET_INT(fsysAppendDir(fname
, pfx
));
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
) {
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
));
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
) {
65 // remove all packs from pakid and later
66 //native static final void fsysRemovePaksFrom (int pakid);
67 IMPLEMENT_FREE_FUNCTION(VObject
, fsysRemovePaksFrom
) {
70 fsysRemovePaksFrom(pakid
);
74 //native static final int fsysFindPakByPrefix (string pfx);
75 IMPLEMENT_FREE_FUNCTION(VObject
, fsysFindPakByPrefix
) {
78 RET_BOOL(fsysFindPakByPrefix(pfx
));
81 //native static final bool fsysFileExists (string fname, optional int pakid);
82 IMPLEMENT_FREE_FUNCTION(VObject
, fsysFileExists
) {
84 VOptParamInt
pakid(-1);
85 vobjGetParam(fname
, pakid
);
86 if (pakid
.specified
) {
87 RET_BOOL(fsysFileExists(fname
, pakid
));
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
) {
97 VOptParamInt
pakid(-1);
98 vobjGetParam(fname
, pakid
);
99 if (pakid
.specified
) {
100 RET_STR(fsysFileFindAnyExt(fname
, pakid
));
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
) {
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
) {
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
) {
137 fsysKillCommonZipPrefix
= v
;
141 // native final void appSetName (string appname);
142 IMPLEMENT_FREE_FUNCTION(VObject
, appSetName
) {
149 #ifdef SERIALIZER_USE_LIBHA
150 static const char *LHABinStorageSignature
= "VaVoom C Binary Data Storage V0"; // 32 bytes
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;
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;
179 static libha_io_t lhaiostrm
{
187 //native final static bool appSaveOptions (Object optobj, optional string optfile, optional bool packit);
188 IMPLEMENT_FREE_FUNCTION(VObject
, appSaveOptions
) {
190 VOptParamStr optfile
;
191 VOptParamBool
packit(true);
192 vobjGetParam(optobj
, optfile
, 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
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());
213 libha_t lha
= libha_alloc(&lhaiostrm
, &data
);
217 VStream::Destroy(strm
);
221 auto herr
= libha_pack(lha
);
225 VStream::Destroy(strm
);
226 RET_BOOL(herr
== LIBHA_ERR_OK
);
229 VStream::Destroy(strm
);
233 ObjectSaver
saver(*strm
, svmap
);
234 bool res
= saver
.saveAll();
235 bool err
= saver
.IsError();
236 VStream::Destroy(strm
);
237 RET_BOOL(res
&& !err
);
240 ObjectSaver
saver(*strm
, svmap
);
241 bool res
= saver
.saveAll();
242 bool err
= saver
.IsError();
244 RET_BOOL(res
&& !err
);
249 //native final static spawner Object appLoadOptions (class cls, optional string optfile);
250 IMPLEMENT_FREE_FUNCTION(VObject
, appLoadOptions
) {
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
263 strm
->Serialise(sign
, 32);
264 if (!strm
->IsError() && memcmp(sign
, LHABinStorageSignature
, 32) == 0) {
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
);
276 auto rds
= new VStreamMemRead(xbuf
, sz
);
277 auto wrs
= new VStreamMemWrite();
281 libha_t lha
= libha_alloc(&lhaiostrm
, &data
);
289 auto herr
= libha_unpack(lha
);
291 if (herr
!= LIBHA_ERR_OK
) {
300 rds
= new VStreamMemRead(wrs
->getData(), wrs
->Tell());
301 ObjectLoader
ldr(*rds
, cls
);
302 bool uerr
= !ldr
.loadAll();
310 RET_REF(ldr
.objarr
[1]); // 0 is `none`
311 } else if (!strm
->IsError() && memcmp(sign
, BinStorageSignature
, 32) == 0) {
314 ObjectLoader
ldr(*strm
, cls
);
315 if (!ldr
.loadAll()) {
316 VStream::Destroy(strm
);
321 VStream::Destroy(strm
);
322 RET_REF(ldr
.objarr
[1]); // 0 is `none`
325 VStream::Destroy(strm
);
329 ObjectLoader
ldr(*strm
, cls
);
330 if (!ldr
.loadAll()) {
331 VStream::Destroy(strm
);
336 VStream::Destroy(strm
);
337 //fprintf(stderr, "%p\n", ldr.objarr[1]);
338 RET_REF(ldr
.objarr
[1]); // 0 is `none`
343 //static final void PostQuitEvent (int code);
344 IMPLEMENT_FREE_FUNCTION(VObject
, PostQuitEvent
) {
347 ::PostQuitEvent(code
);
351 //static final int RunMainEventLoop (optional ref event_t qevent);
352 IMPLEMENT_FREE_FUNCTION(VObject
, RunMainEventLoop
) {
353 VOptParamPtr
<event_t
> 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
) {
364 vobjGetParam(mstimeout
);
365 RET_INT(::VCC_SetTimer(mstimeout
));
368 //native static final int vccSetInterval (int mstimeout);
369 IMPLEMENT_FREE_FUNCTION(VObject
, vccSetInterval
) {
371 vobjGetParam(mstimeout
);
372 RET_INT(::VCC_SetInterval(mstimeout
));
375 //native static final void vccCancelInterval (int iid);
376 IMPLEMENT_FREE_FUNCTION(VObject
, vccCancelInterval
) {
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
) {
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());
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
) {
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();