- A public function automatically becomes an event procedure.
- CreateProxyOfEventProcedure creates a native wrapper for the specified eventproc (meaning the proxy uses the firmware's calling convention). In the firmwares I checked, 20 such proxies can be created.
Combining the above two, it's possible to make a task in CBasic.
Keyboard can be intercepted by creating a controller and making it top level.
Following test script displays logical events passed to the UI (it's hard to read, but I could not come up with a better way to display). 16 events are displayed (4x4), first event is the most recent.
The script should run on newer cams.
dim inited=0, startcnt=0
dim disp0, disp1, disp2, disp3, disp4, msgstr
dim chandle=0, cncall=0, cbuf
dim dbg2=0, dbg1=0, plug=1, alt=0
public function mycontroller(p1, p2, p3)
cncall = cncall + 1
' fifo for events
for n=0 to 14
m = 14-n
m = m * 4
nn = 15-n
nn = nn * 4
Poke32(cbuf + nn, Peek32(cbuf + m))
next
Poke32(cbuf, p2)
' return code 0 = events are swallowed here, 1 = events are passed on to the rest of UI
mycontroller=1
end function
private sub myinit()
'System.Create() ' already done in Initialize
UI.Create() ' for named button events and more
'UI.CreatePublic() ' UI.Create makes this redundant
SS.Create() ' PT_ eventprocs for capt_seq feedback, and more
'ExportToEventProcedure("unregevproc",0xFF889100) ' not an eventproc on newer cams, addr is cam specific
msgstr = AllocateMemory(40 * 5)
cbuf = AllocateMemory(32 * 4)
disp0 = LCDMsg_Create(10,1,"Init",2)
disp1 = LCDMsg_Create(10,41,"1",2)
disp2 = LCDMsg_Create(10,81,"2",2)
disp3 = LCDMsg_Create(10,121,"3",2)
disp4 = LCDMsg_Create(10,161,"4",2)
LCDMsg_ChangeColor(disp0, 2)
adr=CreateProxyOfEventProcedure("mycontroller")
chandle = CreateController(adr, 0) ' 2nd param 0 or 1, meaning unknown
MoveControllerToTopOfZOrder(chandle)
end sub
private sub myuninit()
DeleteController(chandle)
DeleteProxyOfEventProcedure("mycontroller")
DeleteProxyOfEventProcedure("mytask")
LCDMsg_Delete(disp0)
LCDMsg_Delete(disp1)
LCDMsg_Delete(disp2)
LCDMsg_Delete(disp3)
LCDMsg_Delete(disp4)
FreeMemory(msgstr)
FreeMemory(cbuf)
end sub
private sub redraw(row)
' string length is limited (32 on a3200), FAILED is displayed when too long
if row = 0 then
LCDMsg_SetStr(disp0,msgstr)
end if
if row = 1 then
LCDMsg_SetStr(disp1,msgstr+40)
end if
if row = 2 then
LCDMsg_SetStr(disp2,msgstr+40 * 2)
end if
if row = 3 then
LCDMsg_SetStr(disp3,msgstr+40 * 3)
end if
if row = 4 then
LCDMsg_SetStr(disp4,msgstr+40 * 4)
end if
end sub
public function mytask()
myinit()
cyc=0
prevcnt=0
curcnt=cncall
do while plug=1
Wait(100)
if curcnt<>prevcnt then
sprintf(msgstr,"Controller called: %d",cncall)
sprintf(msgstr+40, "%04x, %04x, %04x, %04x",Peek32(cbuf),Peek32(cbuf+4),Peek32(cbuf+8),Peek32(cbuf+12))
sprintf(msgstr+80, "%04x, %04x, %04x, %04x",Peek32(cbuf+16),Peek32(cbuf+20),Peek32(cbuf+24),Peek32(cbuf+28))
sprintf(msgstr+120,"%04x, %04x, %04x, %04x",Peek32(cbuf+32),Peek32(cbuf+36),Peek32(cbuf+40),Peek32(cbuf+44))
sprintf(msgstr+160,"%04x, %04x, %04x, %04x",Peek32(cbuf+48),Peek32(cbuf+52),Peek32(cbuf+56),Peek32(cbuf+60))
redraw(0)
redraw(1)
redraw(2)
redraw(3)
redraw(4)
end if
if (cyc & 4)>0 then
MoveControllerToTopOfZOrder(chandle)
end if
cyc = cyc + 1
prevcnt=curcnt
curcnt=cncall
loop
Wait(1000)
LCDMsg_SetStr(disp0,"Script finished")
Wait(1000)
end function
public sub isloaded()
isloaded = inited
end sub
private sub Initialize()
if isloaded()=1 then
startcnt = startcnt + 1
exit sub
end if
inited=1
System.Create()
adr=CreateProxyOfEventProcedure("mytask")
CreateTask("cbasic1", 0x19, 0x2000, adr, 0)
end sub
private sub terminate()
' does not execute when a task is started from this same script
' even if that task exits
plug = 0
LCDMsg_SetStr(disp0,"terminate")
Wait(2200)
myuninit()
end sub
This script only consists of a single file, extend.m .
edit:
script modified to display correctly on old DryOS cameras (LCDMsg can't be positioned to zero coordinates on those)
edit2:
fix controller z order adjustment regularity