· 8 years ago · May 04, 2018, 04:26 AM
1
2version="1.1.7"
3print "autoplay script version ";version;" started"
4
5REM
6REM autoplayer
7REM May 14, 2007
8REM Copyright (c) 2006-2007 Roku, LLC.
9REM
10REM This BrightScript detects and autoplay's media as follows:
11REM 1. If the video file autoplay.vob exists, it will play and loop forever.
12REM 2. If a playlist file autoplay.bsp is found, the playlist is executed in "play list" mode
13REM 3. If a coma-seperated-value file autoplay.csv exists, it will autoplay in "state machine" mode
14REM
15REM If more than one autoplay file exists, then the behavior is non-deterministic.
16REM
17
18
19REM
20REM Init some constants
21REM
22debug=-1 'set to -1 to turn on debug prints; 0 to turn them off
23root="\\"
24
25LED1=2 ^ 18:LED2=2 ^ 19:LED3=2 ^ 20:LEDM=2 ^ 21
26MEDEN=8 'media end
27
28REM audio_ouput values:
29ANALOG=0
30USB=1
31SPDIF=2
32
33REM audio_mode values, (Options 0 and 1 only apply to video files; 2 applies to all audio sources)
34SURROUND=0
35STEREO=1
36NOAUDIO=2
37
38REM
39REM scan the files in the root directory and look for an autoplay file
40REM
41rem dir = ListDir(root)
42rem if dir.Count()=0 then print"Unexpected Empty Directory":stop
43rem for i=1 to dir.Count()
44rem file=dir.RemoveHead()
45rem if debug then print "file: ";file
46rem if file="autoplay.vob" or file="autoplay.mpg" then play_vid
47rem if file="autoplay.csv" then play_csv
48rem if file="autoplay.bsp" then play_bsp
49rem next
50rem print "An autoplay file was not found."
51rem stop ' nothing to play file=ReadAsciiFile("autoplay.csv")
52
53
54 file=ReadAsciiFile("autoplay.csv") ' does file exist?
55 if file<>"" then play_csv
56
57 file=ReadAsciiFile("autoplay.bsp") ' does file exist?
58 if file<>"" then play_bsp
59
60 goto play_vid 'assume there is video file
61
62REM
63REM ******************************************************************
64REM ******************************************************************
65REM autoplay.vob (simple video loop)
66REM ******************************************************************
67REM ******************************************************************
68REM
69play_vid:
70 if debug then print "play_vid entered"
71 video=CreateObject("roVideoPlayer")
72 p=CreateObject("roMessagePort")
73 video.SetLoopMode(true)
74 okay=video.PlayFile(root+"autoplay.mpg")
75 if okay=0 then
76 okay=video.PlayFile(root+"autoplay.vob")
77 if okay=0 then
78 print "Error finding autoplay file"
79 stop
80 endif
81 endif
82 msg=wait(0, p) ' wait forever
83
84REM
85REM ******************************************************************
86REM ******************************************************************
87REM autoplay.bsp(BrightSign Playlist -- simple text file of files)
88REM ******************************************************************
89REM ******************************************************************
90REM
91play_bsp:
92 if debug then print "play_bsp entered: ";f$
93
94 mode=0
95 image=0
96 video=0
97
98REM
99REM create the message port
100REM In BrightScript, objects can send events (such as video finished playing) to a message port.
101REM The BrightScript can then Wait on the port for a message.
102REM
103 p=CreateObject("roMessagePort")
104REM
105REM Create the videomode object. It is used to set the display resolution, eg. 1024x768
106REM
107 mode=CreateObject("roVideoMode")
108 if type(mode)="rotINT32" then print "Unexpected error creating roVideoMode":stop
109REM
110REM create the GPIO control object (for testing buttons and setting lights)
111REM
112 sw = CreateObject("roGpioControlPort")
113 swp = CreateObject("roMessagePort")
114 sw.SetPort(swp)
115
116
117REM
118REM set audio to be analog out of audio out 1
119REM
120 audiomode=STEREO
121 audiochan=2
122 audiooutput=ANALOG
123 audiovolume=100
124REM
125REM Keep looping the autoplay.bsp file forever
126REM
127call_count=0
128file="" ' sets type to string, from RO
129forever:
130 f$="autoplay.bsp"
131 gosub play_bsp2
132 goto forever
133
134REM
135REM play_bsp2 handles the playback of a single playlist: filename passed in f$
136REM It is a subroutine that can be called recursivly
137REM
138play_bsp2:
139 if debug then print "Starting at top of playlist file."
140 if call_count>9 then print "Error: Too many nested playlist files":stop
141 save_file(call_count) = file
142 save_posn(call_count) = posn
143 call_count=call_count+1
144 posn=1
145 file=ReadAsciiFile(f$)
146 if file="" then print "Unexpected error reading '";f$;"'":stop
147
148REM
149REM Detect end of line type (Windows/Dos, Linux, and Mac are all different)
150REM
151 eol$=chr(13)+chr(10) '/r/n, Windows/DOS File
152 if instr(1, file, eol$)=0 then
153 eol$=chr(13) '/r, Mac
154 if instr(1, file, eol$)=0 then
155 eol$=chr(10) '/n, Linux
156 if instr(1, file, eol$)=0 then
157 'print "No EOL found in file 'autoplay.bsp'":stop
158 if debug then print "No EOL found in file 'autoplay.bsp'"
159 eol$=chr(13)+chr(10) '/r/n, Windows/DOS File
160 endif
161 endif
162 endif
163
164 eoln=len(eol$)
165
166 REM double check the file has not got an unexpected eol char
167 if debug then
168 if eoln=1 then
169 if eol$=chr(13) then
170 if instr(1,file,chr(10))>0 then
171 print "unsupported line termination sequence (unexpected /n)"
172 stop
173 endif
174 else
175 if instr(1,file,chr(13))>0 then
176 print "unsupported line termination sequence (unexpected /r)"
177 stop
178 endif
179 endif
180 endif
181 endif
182
183REM
184REM setup video object to play video if needed
185REM
186 if type(video)<>"roVideoPlayer" then
187 if instr(1, file, ".mpg")>0 or instr(1, file, ".vob")>0 then
188 video=CreateObject("roVideoPlayer")
189 if type(video)="rotINT32" then print "Unexpected error creating roVideoPlayer":stop
190 if debug then print "video object created"
191 video.SetLoopMode(false)
192 video.SetPort(p)
193 gosub setaudiomode 'using defaults set earlier
194 endif
195 endif
196REM
197REM setup audio object to play audio if needed
198REM
199 if type(audio)<>"roAudioPlayer" then
200 if instr(1, file, ".mp3")>0 then
201 audio=CreateObject("roAudioPlayer")
202 if type(audio)="rotINT32" 0 then print "Unexpected error creating roAudioPlayer":stop
203 if debug then print "audio object created"
204 audio.SetLoopMode(false)
205 audio.SetPort(p)
206 gosub setaudiomode 'using defaults set earlier
207 endif
208 endif
209
210REM
211REM setup image object to play files if needed
212REM
213 if type(image)<>"roImagePlayer" then
214 if instr(1, file, ".bmp")>0 then
215 image=CreateObject("roImagePlayer")
216 if type(image)="rotINT32" then print "Unexpected error creating roImagePlayer":stop
217 if debug then print "image object created"
218 slideinterval=3000 'default 3 seconds
219 endif
220 endif
221
222REM
223REM main playlist loop starts here.
224REM scan through the playlist, find each line in the playlist, and see if it is a built in
225REM command (eg "debug" or "print"). If not, try and play it as a media file.
226REM
227
228bsp_lp:
229 line_end=instr(posn, file, eol$)
230 if line_end=0 then 'eof reached with no eol
231 remaining_string=mid(file, posn)
232 if len(remaining_string)>0 then 'check for a string beyond the last eol
233 tk$=remaining_string
234 posn=posn+len(remaining_string)
235 goto bsp_strip
236 endif
237 call_count=call_count-1
238 posn=save_posn(call_count)
239 file=save_file(call_count)
240 return ' exit subroutine afer popping saved posn/file (to allow recursion)
241 endif
242 tk$=mid(file, posn, line_end-posn)
243 posn=line_end+eoln ' point to next line start
244bsp_strip:
245 if right(tk$,1)=" " then tk$=left(tk$, len(tk$)-1):goto bsp_strip 'strip any spaces at end of line
246 if len(tk$)=0 then bsp_lp 'ignore blank lines
247
248 f$=root+tk$ ' f$ now contains the complete path to the file to play
249
250 REM
251 REM handle built in keyword/commands
252 REM
253 if tk$="debug" then debug=-1:goto bsp_lp
254 if left(tk$, 3)="rem" then bsp_lp ' skip rem (arks)
255 if left(tk$, 3)="REM" then bsp_lp ' skip REM (arks)
256 if left(tk$, 6)="print " then print mid(tk$, 7):goto bsp_lp ' print to console
257 if left(tk$, 10)="audiomode " then audiomode=val(mid(tk$, 11)):gosub setaudiomode:goto bsp_lp
258 if left(tk$, 12)="audiooutput " then audiooutput=val(mid(tk$, 13)):gosub setaudiomode:goto bsp_lp
259 if left(tk$, 10)="audiochan " then audiochan=val(mid(tk$, 11)):gosub setaudiomode:goto bsp_lp
260 if left(tk$, 7)="volume " then audiovolume=val(mid(tk$, 7)):gosub setaudiomode:goto bsp_lp
261 if left(tk$, 10)="videomode " then videomode$=mid(tk$, 11):gosub setvideomode:goto bsp_lp
262 if left(tk$, 10)="imagemode " then imagemode=val(mid(tk$, 11)):gosub setimagemode:goto bsp_lp
263 if left(tk$, 13)="slideinterval" then slideinterval=val(mid(tk$, 14))*1000:goto bsp_lp
264 if left(tk$, 8)="lighton " then sw.SetOutputState(val(mid(tk$, 9)), 1):goto bsp_lp
265 if left(tk$, 9)="lightoff " then sw.SetOutputState(val(mid(tk$, 10)), 0):goto bsp_lp
266 if left(tk$, 13)="waitbuttonany" then gosub clear_btn_queue:wait(0, swp):goto bsp_lp
267 if left(tk$, 6)="pause " then sleep(val(mid(tk$, 7))*1000):goto bsp_lp ' pause (seconds)
268
269REM add asyncplay? idea: file.bmp, file.mp (triggers them both?)
270
271 if debug print "playing file: ";f$
272
273REM
274REM video file?
275REM
276 if right(f$,4)=".mpg" or right(f$,4)=".vob" then
277 okay=video.PlayFile(f$)
278 if okay=0 then
279 print "VID: Error trying to play file: ";"'";f$;"'"
280 if debug stop
281 endif
282bspmsglp:
283 msg=wait(0, p) ' wait for video end
284 if type(msg)="roVideoEvent" then if msg.GetInt() = MEDEN then bsp_lp
285 goto bspmsglp
286
287REM
288REM audio file?
289REM
290 else if right(f$,4)=".mp3" then
291 okay=audio.PlayFile(f$)
292 if okay=0 then
293 print "AUD: Error trying to play file: ";"'";f$;"'"
294 if debug stop
295 endif
296bspmsglp2:
297 msg=wait(0, p) ' wait for file end
298 if type(msg)="roAudioEvent" and msg.GetInt() = MEDEN then bsp_lp
299 goto bspmsglp2
300REM
301REM bitmap file?
302REM
303 else if right(f$,4)=".bmp" then
304 if debug then print "Display Image::";f$;"::";" (";slideinterval;")"
305 okay=image.DisplayFile(f$)
306 if okay=0 then
307 print "BMP: Error trying to display file: ";"'";f$;"'"
308 if debug stop
309 endif
310 sleep(slideinterval)
311 goto bsp_lp
312
313REM
314REM playlist file?
315REM
316 else if right(f$,4)=".bsp" then
317 gosub play_bsp2
318 goto bsp_lp
319
320 else
321 print "Unsupported file type in file: ";f$
322 if debug stop
323 endif
324
325 goto bsp_lp
326
327REM
328REM Playlist code helper functions
329REM
330
331setvideomode:
332 if debug then print "VIDEOMODE Set to: ";videomode$
333 ok=mode.SetMode(videomode$)
334 if ok=0 then print "Error: Can't set VIDEOMODE to ::";videomode$;"::":'stop REMOVE REM
335 return
336
337setimagemode:
338 if type(image)="roImagePlayer" then
339 if debug then print "IMAGEMODE Set to: ";imagemode
340 ok=image.SetDefaultMode(imagemode)
341 if ok=0 then print "Error: Can't set IMAGEMODE to ";imagemode:stop
342 endif
343 return
344
345setaudiomode:
346 if type(video)="roVideoPlayer" then
347 if debug then print "AUDIOMODE (VID): am";audiomode;", ao: ";audiooutput;", ac: ";audiochan;", vol: ";audiovolume
348 video.SetAudioMode(audiomode)
349 video.SetAudioOutput(audiooutput)
350 video.MapStereoOutput(audiochan) ' 2 == audio 0
351 video.SetVolume(audiovolume)
352 endif
353
354 if type(audio)="roAudioPlayer" then
355 if debug then print "AUDIOMODE (AUD): am";audiomode;", ao: ";audiooutput;", ac: ";audiochan;", vol: ";audiovolume
356 audio.SetAudioOutput(audiooutput)
357 audio.MapStereoOutput(audiochan) ' 2 == audio 0
358 audio.SetVolume(audiovolume)
359 endif
360
361 return
362
363clear_btn_queue:
364 msg=swp.GetMessage():if type(msg)<>"rotINT32" then clear_btn_queue
365 return
366
367
368REM
369REM ******************************************************************
370REM ******************************************************************
371REM autoplay.csv(state machine created in Excel and saved in CSV format)
372REM ******************************************************************
373REM ******************************************************************
374REM
375play_csv:
376 if debug then print "play_csv entered"
377
378REM
379REM create objects and ports
380REM
381 p = CreateObject("roMessagePort")
382 sw = CreateObject("roGpioControlPort")
383 sw.SetPort(p)
384 video= CreateObject("roVideoPlayer")
385 video.SetPort(p)
386 image=CreateObject("roImagePlayer")
387
388 ser = CreateObject("roSerialPort", 0, 38400)
389 ser.SetLineEventPort(p)
390
391
392REM
393REM Set Audio Port that audio will come out of
394REM
395 video.SetAudioMode(STEREO)
396 video.SetAudioOutput(ANALOG)
397 video.MapStereoOutput(2) ' 2 == audio 0
398 video.SetVolume(100)
399
400 preloadedimage=""
401 istouch=false
402
403REM
404REM Main State Machine Starts Now
405REM
406 gosub read_state_file
407 state="" ' forces state to be type string. Works around a bug in BrightScript that the next line will trigger w/o this line.
408 state=state_table(1,1) ' first state/file name
409
410new_state:
411 if debug then print "new_state: state=";state
412 gosub lookup_state
413 if debug then print"after lookup_state: state=";state;", idx=";stateidx
414
415 playfile$=state_table(stateidx, 1)
416 lm=1 ' default to loop on
417 tiut=0 ' default timout off
418
419 rem a timeout "goto stateidx" indicates video should timeout
420 if toevent>0 then if state_table(stateidx, toevent)<>"" then tiut=toval
421
422 rem a "video finish event" indicates video should not loop
423 if videndevent>0 then if state_table(stateidx, videndevent)<>"" then lm=0
424
425 if right(playfile$, 4)=".bmp" then
426 gosub play_image
427 else if right(playfile$, 4)=".mpg" or right(playfile$, 4)=".vob" then
428 gosub play_video
429 video.StopClear()
430 else
431 print "Error: Unknown file type: ";playfile$:stop
432 endif
433
434 if timeouted<>0 then
435 state=state_table(stateidx, toevent)
436 else if vidfinished<>0 then
437 state=state_table(stateidx, videndevent)
438 else if butpressed <> -1 then
439 state=state_table(stateidx, bu(butpressed))
440 else if touchpressed <> 0 then
441 state=state_table(stateidx, touchpressed)
442 endif
443
444 goto new_state
445
446REM
447REM Read the state file
448REM
449read_state_file:
450 dim bu(12)
451 dim state_table(100, 25)
452 dim eloev(25)
453 state_table(0,0)="" ' force typomatic array to "string". This works around a BrightScript bug.
454 pp=1
455 flipelo=0
456
457 file=ReadAsciiFile("autoplay.csv")
458 if file="" then print "Unexpected error reading 'autoplay.csv'":stop
459
460skip_blank:
461 gosub get_next
462 if nxtstr="" then skip_blank
463 if nxtstr="END" then
464 print "Error: Incomplete .csv file":stop
465 else if nxtstr="VIDEOMODE" then
466 gosub get_next
467 if debug then print "VIDEOMODE Set to: ";nxtstr
468 mode=CreateObject("roVideoMode")
469 mode.SetMode(nxtstr)
470 else if nxtstr="IMAGEMODE" then
471 gosub get_next
472 if debug then print "IMAGEMODE Set to: ";val(nxtstr)
473 ok=image.SetDefaultMode(val(nxtstr))
474 if ok=0 then print "Error: Can't set IMAGEMODE to ";val(nxtstr):stop
475 else if nxtstr="FLIPELO" then
476 if debug then print "FLIPELO set"
477 flipelo=1
478 else if nxtstr="EVENTS" then
479 if debug then print "Reading events"
480 goto do_event_line
481 endif
482 goto skip_blank
483
484do_event_line:
485 gosub get_next
486 if nxtstr<>"" then print "Error: cell after EVENTS should be blank.":stop
487 numevents=1
488scan_events:
489 gosub get_next
490 if nxtstr="STATE" then scan_state
491 numevents=numevents+1
492 if left(nxtstr, 4)="elo:" then gosub add_elo_r:goto scan_events
493 if left(nxtstr, 5)="elor:" then gosub add_elo_rect:goto scan_events
494 if left(nxtstr, 5)="eloc:" then gosub add_elo_circle:goto scan_events
495 if left(nxtstr, 6)="relor:" then gosub add_elo_rect_rollover:goto scan_events
496 if left(nxtstr, 6)="reloc:" then gosub add_elo_circle_rollover:goto scan_events
497 if left(nxtstr, 7)="button:" then gosub add_button:goto scan_events
498 if left(nxtstr, 8)="timeout:" then gosub add_timeout:goto scan_events
499 if left(nxtstr, 8)="videoend" then gosub add_videoend:goto scan_events
500 print "Error: unknown event type in EVENTS line":stop
501 goto scan_events
502
503scan_state:
504 numstates=0
505next_row:
506 event_num=0
507 numstates=numstates+1
508
509next_ev:
510 event_num=event_num+1
511 gosub get_next
512 if nxtstr="STATE" or nxtstr="END" then
513 if event_num < numevents then
514 for i=event_num to numevents
515 state_table(numstates, i)=""
516 if debug then print "numstates=";numstates;", i=";i
517 next
518 endif
519 if nxtstr="END" then state_table(numstates+1, 1)="":return ' the ="" is to avoid a runtime error (bug) in is_okay_to_preload
520 goto next_row
521 endif
522 state_table(numstates, event_num) = nxtstr
523 if (event_num > numevents) then print "Error: state table has destination states without an event trigger":stop
524 goto next_ev
525
526
527add_elo_r:
528 if istouch=false then
529 istouch=true
530 t=CreateObject("roTouchScreen")
531 t.SetPort(p)
532 REM Puts up a cursor if a mouse is attached
533 REM The cursor must be a 32 x 32 BMP
534 REM The x,y position is the “hot spot†point
535 t.SetCursorBitmap(root+"cursor.bmp", 16, 16)
536 t.SetResolution(1024, 768)
537 t.SetCursorPosition(512, 512)
538 endif
539 yp=instr(5, nxtstr, ":")+1
540 wp=instr(yp, nxtstr, ":")+1
541 hp=instr(wp, nxtstr, ":")+1
542 if yp=0 or wp=0 or hp=0 then print "Error: Invalid touch coordinates for ELO event":stop
543 xval=val(mid(nxtstr, 5, yp-5-1))
544 yval=val(mid(nxtstr, yp, wp-yp-1))
545 wval=val(mid(nxtstr, wp, hp-wp-1))
546 hval=val(mid(nxtstr, hp))
547 if flipelo=1 then
548 xval=1024-(xval+wval)
549 yval=768-(yval+hval)
550 endif
551 t.AddRectangleRegion(xval,yval,wval,hval, numevents)
552 eloev(numevents)=-1 ' remember where the touch events are in the columns for use in play_video and play_image
553 return
554
555add_elo_rect:
556 if istouch=false then
557 istouch=true
558 t=CreateObject("roTouchScreen")
559 t.SetPort(p)
560 REM Puts up a cursor if a mouse is attached
561 REM The cursor must be a 32 x 32 BMP
562 REM The x,y position is the “hot spot†point
563 t.SetCursorBitmap(root+"cursor.bmp", 16, 16)
564 t.SetResolution(1024, 768)
565 t.SetCursorPosition(512, 512)
566 endif
567 yp=instr(6, nxtstr, ":")+1
568 wp=instr(yp, nxtstr, ":")+1
569 hp=instr(wp, nxtstr, ":")+1
570 if yp=0 or wp=0 or hp=0 then print "Error: Invalid touch coordinates for ELO event":stop
571 xval=val(mid(nxtstr, 6, yp-6-1))
572 yval=val(mid(nxtstr, yp, wp-yp-1))
573 wval=val(mid(nxtstr, wp, hp-wp-1))
574 hval=val(mid(nxtstr, hp))
575 if flipelo=1 then
576 xval=1024-(xval+wval)
577 yval=768-(yval+hval)
578 endif
579 t.AddRectangleRegion(xval,yval,wval,hval, numevents)
580 eloev(numevents)=-1 ' remember where the touch events are in the columns for use in play_video and play_image
581 return
582
583add_elo_rect_rollover:
584 if istouch=false then
585 istouch=true
586 t=CreateObject("roTouchScreen")
587 t.SetPort(p)
588 REM Puts up a cursor if a mouse is attached
589 REM The cursor must be a 32 x 32 BMP
590 REM The x,y position is the “hot spot†point
591 t.SetCursorBitmap(root+"cursor.bmp", 16, 16)
592 t.SetResolution(1024, 768)
593 t.SetCursorPosition(512, 512)
594 endif
595 yp=instr(7, nxtstr, ":")+1
596 wp=instr(yp, nxtstr, ":")+1
597 hp=instr(wp, nxtstr, ":")+1
598 rp=instr(hp, nxtstr, ":")+1
599 rohip=instr(rp, nxtstr, ":")+1
600 rolop=instr(rohip, nxtstr, ":")+1
601 oxp=instr(rolop, nxtstr, ":")+1
602 oyp=instr(oxp, nxtstr, ":")+1
603
604 if yp=0 or wp=0 or hp=0 or rp=0 or rohip=0 or rolop=0 or oxp=0 or oyp=0 then print "Error: Invalid touch coordinates for ELO event":stop
605 xval=val(mid(nxtstr, 7, yp-7-1))
606 yval=val(mid(nxtstr, yp, wp-yp-1))
607 wval=val(mid(nxtstr, wp, hp-wp-1))
608 hval=val(mid(nxtstr, hp))
609 roval=val(mid(nxtstr, rp, rohip-rp-1))
610 rohival=mid(nxtstr, rohip, rolop-rohip-1)
611 roloval=mid(nxtstr, rolop, oxp-rolop-1)
612 oxval=val(mid(nxtstr, oxp, oyp-oxp-1))
613 oyval=val(mid(nxtstr, oyp))
614
615 if flipelo=1 then
616 xval=1024-(xval+wval)
617 yval=768-(yval+hval)
618 endif
619 t.AddRectangleRegion(xval,yval,wval,hval, numevents)
620 if roval=1 then
621 t.EnableRollOver(numevents, rohival, roloval, true)
622 t.SetRollOverOrigin(numevents, oxval, oyval)
623 endif
624 eloev(numevents)=-1 ' remember where the touch events are in the columns for use in play_video and play_image
625 return
626
627add_elo_circle:
628 if istouch=false then
629 istouch=true
630 t=CreateObject("roTouchScreen")
631 t.SetPort(p)
632 REM Puts up a cursor if a mouse is attached
633 REM The cursor must be a 32 x 32 BMP
634 REM The x,y position is the “hot spot†point
635 t.SetCursorBitmap(root+"cursor.bmp", 16, 16)
636 t.SetResolution(1024, 768)
637 t.SetCursorPosition(512, 512)
638 endif
639 yp=instr(6, nxtstr, ":")+1
640 radiusp=instr(yp, nxtstr, ":")+1
641 rp=instr(radiusp, nxtstr, ":")+1
642 if yp=0 or radiusp=0 or rp=0 then print "Error: Invalid touch coordinates for ELO circle event":stop
643 xval=val(mid(nxtstr, 6, yp-6-1))
644 yval=val(mid(nxtstr, yp, radiusp-yp-1))
645 radiusval=val(mid(nxtstr, radiusp, rp-radiusp-1))
646 if flipelo=1 then
647 xval=1024-xval
648 yval=768-yval
649 endif
650 t.AddCircleRegion(xval,yval,radiusval, numevents)
651 eloev(numevents)=-1 ' remember where the touch events are in the columns for use in play_video and play_image
652 return
653
654add_elo_circle_rollover:
655 if istouch=false then
656 istouch=true
657 t=CreateObject("roTouchScreen")
658 t.SetPort(p)
659 REM Puts up a cursor if a mouse is attached
660 REM The cursor must be a 32 x 32 BMP
661 REM The x,y position is the “hot spot†point
662 t.SetCursorBitmap(root+"cursor.bmp", 16, 16)
663 t.SetResolution(1024, 768)
664 t.SetCursorPosition(512, 512)
665 endif
666 yp=instr(7, nxtstr, ":")+1
667 radiusp=instr(yp, nxtstr, ":")+1
668 rp=instr(radiusp, nxtstr, ":")+1
669 rohip=instr(rp, nxtstr, ":")+1
670 rolop=instr(rohip, nxtstr, ":")+1
671 oxp=instr(rolop, nxtstr, ":")+1
672 oyp=instr(oxp, nxtstr, ":")+1
673
674 if yp=0 or radiusp=0 or rp=0 or rohip=0 or rolop=0 or oxp=0 or oyp=0 then print "Error: Invalid touch coordinates for ELO circle event":stop
675 xval=val(mid(nxtstr, 7, yp-7-1))
676 yval=val(mid(nxtstr, yp, radiusp-yp-1))
677 radiusval=val(mid(nxtstr, radiusp, rp-radiusp-1))
678 roval=val(mid(nxtstr, rp, rohip-rp-1))
679 rohival=mid(nxtstr, rohip, rolop-rohip-1)
680 roloval=mid(nxtstr, rolop, oxp-rolop-1)
681 oxval=val(mid(nxtstr, oxp, oyp-oxp-1))
682 oyval=val(mid(nxtstr, oyp))
683 if flipelo=1 then
684 xval=1024-xval
685 yval=768-yval
686 endif
687 t.AddCircleRegion(xval,yval,radiusval, numevents)
688 if roval=1 then
689'MUST RESOLVE is flipelo required?
690 t.EnableRollOver(numevents, rohival, roloval, true)
691 t.SetRollOverOrigin(numevents, oxval, oyval)
692 endif
693 eloev(numevents)=-1 ' remember where the touch events are in the columns for use in play_video and play_image
694 return
695
696add_button:
697 bn=val(mid(nxtstr, 8))
698 if bn<0 or bn>12 then print "Error: invalid button number":stop
699 if bu(bn)<>0 then print "Error: Button event used more than once":stop
700 bu(bn) = numevents
701 if debug then print "add_button: ";bn
702 return
703
704add_timeout:
705 toval=val(mid(nxtstr, 9))*1000
706 if toval<0 or toval>1000000 then print "Error: invalid timeout value":stop
707 if toevent<>0 then print "Error: Only one timeout event allowed":stop
708 toevent = numevents
709 if debug then print "add_timeout: ";toval
710 return
711
712add_videoend:
713 if videndevent<>0 then print "Error: Only one videoend event allowed":stop
714 videndevent = numevents
715 if debug then print "add_videoend: "
716 return
717
718
719get_next:
720 np=instr(pp, file, ",")+1
721 if np=1 then
722 if pp >= len(file) nxtstr="END":goto dognreturn
723 np=len(file)+1:goto okay
724 endif
725 pvm=instr(pp+1, file, "VIDEOMODE"):if pvm<>0 and pvm < np then np=pvm:goto okay
726 pim=instr(pp+1, file, "IMAGEMODE"):if pim<>0 and pim < np then np=pim:goto okay
727 pfe=instr(pp+1, file, "FLIPELO"):if pfe<>0 and pfe < np then np=pfe:goto okay
728 pev=instr(pp+1, file, "EVENTS"):if pev<>0 and pev < np then np=pev:goto okay
729 pst=instr(pp+1, file, "STATE"):if pst<>0 and pst < np then np=pst
730okay:
731 nxtstr=mid(file, pp, np-pp-1)
732 pp=np
733
734 strip1:
735 if left(nxtstr,1)=" " then nxtstr=mid(nxtstr, 1): goto strip1
736
737 strip2:
738 if right(nxtstr,1)=chr(13) or right(nxtstr,1)=chr(10) then nxtstr=left(nxtstr, len(nxtstr)-1): goto strip2
739
740dognreturn:
741 ' if debug then print "nxtstr: ";nxtstr
742 return
743
744
745
746REM
747REM General Video Play Routine
748REM Call Parameters:
749REM lm 1 or 0 (loop mode on or off)
750REM playfile$ file path of video file to play
751REM tiut length of timeout in ms
752REM esc m-3 1 if button allowed, or zero if not
753REM
754
755play_video:
756 if debug then print "Enter VideoPlay: ";playfile$;", loop=";lm;", timeout=";tiut
757 butpressed=-1
758 vidfinished=0
759 timeouted=0
760 touchpressed=0
761 video.SetLoopMode(lm)
762REM the following didn't work - why??
763' if istouch=true then
764 REM Enable mouse cursor if there is a touch event active in this state
765 REM One touch event we assume to be an exit touch
766 regioncount = 0
767 for i=1 to numevents
768 if eloev(i) and state_table(stateidx, i)<>"" then
769 regioncount = regioncount + 1
770 t.EnableRegion(i, true)
771 else
772 if istouch=true then
773 t.EnableRegion(i, false)
774 endif
775 endif
776 next
777
778 if regioncount > 1 then
779 t.EnableCursor(true)
780 if debug then print "Cursor Enabled"
781 else
782 if istouch=true then
783 t.EnableCursor(false)
784 endif
785 if debug then print "Cursor Disabled"
786 endif
787' endif
788
789labxx:
790 tmp$=""
791 if left(playfile$, len(root))<>root then tmp$=root
792 tmp$=tmp$+playfile$
793 ok=video.PlayFile(tmp$)
794 if ok=0 print "Error Playing File: ";tmp$:stop
795
796 clear_queue:
797 msg=p.GetMessage():if type(msg)<>"rotINT32" then clear_queue
798
799 gosub is_okay_to_preload
800 if preloadedimage<>"" then
801 if left(preloadedimage, len(root))<>root then preloadedimage=root+preloadedimage
802 ok=image.PreloadFile(preloadedimage)
803 if ok=0 print "Error PreloadFile: ";preloadedimage:stop
804 if debug then print "PreloadFile: ";preloadedimage
805 endif
806
807 vp_msg_loop:
808 msg=wait(tiut, p)
809 if type(msg)="roVideoEvent" then
810 if debug then print "Video Event";msg.GetInt()
811 if lm=0 AND msg.GetInt() = MEDEN then
812 if debug then print "VideoFinished"
813 vidfinished=1
814 return
815 endif
816 else if type(msg)="roTouchEvent" then
817 if debug then print "Touch Event";msg
818 if state_table(stateidx, msg)<>"" then touchpressed=msg:return
819 else if type(msg)="roGpioButton" then
820 if debug then print "Button Press";msg
821 if bu(msg)>0 and state_table(stateidx, bu(msg))<>"" then butpressed=msg:return
822 else if type(msg)="roStreamLineEvent" then
823 if debug then print "Serial String";msg
824 if bu(val(msg))>0 and state_table(stateidx, bu(val(msg)))<>"" then butpressed=val(msg):return
825 else if type(msg)="rotINT32" then
826 if debug then print "TimeOut"
827 timeouted=1
828 return
829 else
830 if debug then print "Unhandeled Event type: ";type(msg)
831 endif
832
833 goto vp_msg_loop
834
835play_image:
836 if debug then print "Enter Play image: ";playfile$;", loop=";lm;", timeout=";tiut
837 butpressed=-1
838 vidfinished=0
839 timeouted=0
840 touchpressed=0
841 regioncount=0
842REM the following didn't work - why??
843' if istouch then
844 REM Enable mouse cursor if there is a touch event active in this state
845 REM Only enable touch regions that are active for this state
846 for i=1 to numevents
847 if eloev(i) and state_table(stateidx, i)<>"" then
848 regioncount = regioncount + 1
849 t.EnableRegion(i, true)
850 else
851 if istouch then
852 t.EnableRegion(i, false)
853 endif
854 endif
855 next
856
857 if regioncount > 0 then
858 if playfile$<>"01_a.bmp" then t.EnableCursor(true)
859 if debug then print "Cursor ENABLED"
860 else
861 if istouch then
862 t.EnableCursor(false)
863 endif
864 if debug then print "Cursor Disabled"
865 endif
866' endif
867
868labyy:
869 tmp$=""
870 if left(playfile$, len(root))<>root then tmp$=root
871 tmp$=tmp$+playfile$
872 if preloadedimage<>tmp$ then
873 preloadedimage=tmp$
874 ok=image.PreloadFile(preloadedimage)
875 if ok then ok=image.DisplayPreload()
876 else
877 ok=image.DisplayPreload()
878 endif
879 if ok=0 print "Error Playing File: ";preloadedimage:stop
880
881 clear_queue2:
882 msg=p.GetMessage():if type(msg)<>"rotINT32" then clear_queue2
883
884 gosub is_okay_to_preload
885 if preloadedimage<>"" then
886 if left(preloadedimage, len(root))<>root then preloadedimage=root+preloadedimage
887 ok=image.PreloadFile(preloadedimage)
888 if ok=0 print "Error PreloadFile: ";preloadedimage:stop
889 if debug then print "PreloadFile: ";preloadedimage
890 endif
891
892 ip_msg_loop:
893 msg=wait(tiut, p)
894 if type(msg)="roTouchEvent" then
895 if debug then print "Touch Event #";msg;" at ";msg.GetX()", ";msg.GetY()
896 if state_table(stateidx, msg)<>"" then touchpressed=msg:return
897 else if type(msg)="roGpioButton" then
898 if debug then print "Button Press";msg
899 if bu(msg)>0 and state_table(stateidx, bu(msg))<>"" then butpressed=msg:return
900 else if type(msg)="roStreamLineEvent" then
901 if debug then print "Serial String";msg
902 if bu(val(msg))>0 and state_table(stateidx, bu(val(msg)))<>"" then butpressed=val(msg):return
903 else if type(msg)="rotINT32" then
904 if debug then print "TimeOut"
905 timeouted=1
906 return
907 else
908 if debug then print "Unhandeled Event type: ";type(msg)
909 endif
910
911 goto ip_msg_loop
912
913
914REM
915REM given a state name string, find its index
916REM
917lookup_state:
918 for i=1 to numstates
919 if state_table(i, 1)=state then stateidx=i:return
920 next
921 print "Error in lookup_state. State Not Found: ";state
922 stop
923
924REM
925REM A. If this state only has one possible next bmp state, then preload it.
926REM B. If this state has more than one possible next bmp state, but one of them is the next row in the
927REM state table, then it is preloaded.
928REM
929is_okay_to_preload:
930prek=0
931pokay=0
932 for i=2 to numevents
933 if right(state_table(stateidx, i), 4)=".bmp" then
934 prek=prek+1
935 if prek=1 then
936 preloadedimage=state_table(stateidx, i)
937 pokay=-1
938 else
939 if preloadedimage<>state_table(stateidx, i) then pokay=0
940 endif
941 endif
942 next
943
944 if pokay then return
945
946 for i=2 to numevents
947 if right(state_table(stateidx, i), 4)=".bmp" and state_table(stateidx, i) = state_table(stateidx+1, 1) then
948 preloadedimage=state_table(stateidx+1, 1)
949 return
950 endif
951 next
952
953 preloadedimage=""
954 return