\ io
\
\ io_top
\ top level file for io.
\
\
\ this file defines the top level, global functions. The global control
\ procedures (IO.START, IO.STOP, etc) that are declared in the file io_glob,
\ are defined here.
\
\ the overall interaction of the major components can be represented as
\ follows. (see relevant files for details.)
\
\ io_input ====> io_matrix ===> io_hp =======> io_output io_top
\ ^^^^^^^^ ^^^^^^^^^ ^^^^^ ^^^^^^^^^ ^^^^^^
\ parser ----------------------> hp.noteon
\ -----> hp.noteoff
\ pTracker ----------------------------------> player
\
\ banalyzer ================================================> io.start
\ =====> io.stop
\
\ in addition the components io_ui and, if loaded, io_screen will call the
\ control procedures (IO.START, IO.STOP, etc), and alter or reconfigure the
\ input and output components.
\
\
\ we imagine that if io could _want_, or feel gratitude, it would want to
\ thank the following people (listed in alphabetical order of the penultimate
\ letter of the first name) for its existence: Han, Murray, Nick, Nick,
\ Jean-Claude, Joel, Mel, Leo, Peter, Peter, David, Phil, Gabriele, Jos,
\ Willow, Sara, Mark, Pedro, Jesse, Paul, the nice people at the Do-It Center,
\ the knuckle-heads at Radio Shack, and the engineers in lab coats at Yamaha
\ and Roland.
\
\ but io can't want, or want to thank anyone.
\
\
\ constructor: Han-earl Park
\ copyright 2008 buster & friends' C-ALTO Labs
\
\ www.busterandfriends.com/io
\
\ (Edinburgh, November 1996 -
\ (London, August 1997 -
\ (Den Haag, October 1997 -
\ (Valencia, March 1999 -
\ (Southampton, May 2000 -
\ (Cork, April 2006 -
\
\ (Cork, October 2008 -
\
\ REV: 0.0.1 alpha (Southampton, October 2000)
\ REV: 0.0.1 beta (Southampton, November 2000)
\ REV: 0.0.1 alpha++ (Southampton, July 2004)
\ REV: 0.0.1 beta++ (Cork, May 2010)
\
\
\ MOD: HeP 03/05/99 Started project afresh!
\ This version keeps most of the "intelligence" in the
\ objects, while the piece specific elements are kept to a
\ minimum. It is also a test for the "laurie" project.
\ MOD: HeP 01/22/00 Trash the file io_util.
\ MOD: HeP 02/21/00 Add the global control word IO.STANDBY and corresponding
\ words to each component.
\ MOD: HeP 04/18/00 Change load order of the major io components.
\ MOD: HeP 04/30 00 Build and freeup hierarchy in this file.
\ MOD: HeP 06/01/00 Add IO.PLAY to the set of global control words.
\ modules:io_script may be loaded. See file io_screen.
\ MOD: HeP 06/04/00 Remove the highest level morph, io-coll.
\ MOD: HeP 06/22/00 There's a bug with IO.HP.START and IO.HP.STOP. See the
\ io_hp and io_output files for more details.
\ MOD: HeP 06/23/00 Bug fix (see modules:io_interp).
\ MOD: HeP 06/24/00 Remove half the IO.GR... words. Note that these words now
\ call the corresponding global control procedures in
\ addition to changing the gui state.
\ MOD: HeP 09/19/00 Spin off modules:io_menus from io_screen. This results in
\ redesign of how the screen menu is updated. The menu
\ control code is now called from io_top.
\ MOD: HeP 10/13/00 Add provisions for error reporting in turnkeyed app.
\ Add IT.MUST.BE.NEARLY.FINISHED to the system control words
\ and corresponding subsystem words.
\ REV: 0.0.1 alpha __________________________________________________________
\ MOD: HeP 11/02/00 Update doc and comments.
\ REV: 0.0.1 beta __________________________________________________________
\ MOD: HeP 01/18/01 No longer set midi manager client id in io_glob.
\ MOD: HeP 01/21/00 Set value of rand-seed in (IO.STANDBY) for turnkeyed
\ application.
\ MOD: HeP 01/22/00 Decided that the idea of io as a determinate machine is
\ pretty attractive. rand-seed is only reset in (IO.RESET).
\ MOD: HeP 03-22-04 If not testing turnkeyed app calls RUN.FASTER during init.
\ MOD: HeP 04-13-04 Defer UNSAVED.CHANGE if io_file? and io_tunrkey? are true.
\ MOD: HeP 04-14-04 Add SAVED.CHANGE.
\ MOD: HeP 04-15-04 Trash io_script? which wasn't being used.
\ MOD: HeP 05-01-04 Move all includes (and conditional includes) from the
\ individual files to load_io.
\ MOD: HeP 05-03-04 Add SELECT.SCENE, NEXT.SCENE and PREV.SCENE. (I hope this
\ is not the start of io getting hopelessly complicated.)
\ MOD: HeP 05-14-04 Add ADD.SCENE and DELETE.SCENE.
\ MOD: HeP 05-16-04 Modify words that track file save state (SAVED.CHANGE,
\ etc) to use OB.IO.SCENE's save state.
\ MOD: HeP 05-23-04 The new version of FADE.OUT (in modules:io_interp) results
\ in having to call IO.OUTPUT.STOP earlier, since it keeps
\ morphs alive during the FADE.OUT, in the IO.STOP chain.
\ MOD: HeP 07-02-04 IO.DEFAULT will attempt to open the "io preferences" file.
\ MOD: HeP 07-03-04 IO.STOP will switch to next "scene."
\ (IO.GR.DEFAULT) will only call IO.SCREEN.DEFAULT if
\ "io preferences" file open failed.
\ Each component's .INIT function no longer calls the
\ corresponding .DEFAULT function. Instead these are all
\ called at the end of IO.INIT.
\ REV: 0.0.1 a ++ __________________________________________________________
\ REV: 0.0.1 b ++ __________________________________________________________
\ Version for performance at Blackrock Castle Observatory,
\ Cork, Ireland, May 25, 2010.
\
\
\ ToDo: IO.PLAY doesn't _need_ to be a deferred word to be defined later, why
\ not just define it in io_glob?
\ ToDo: More consistent and comprehensive error reporting.
anew task-io_top
\ top level control
: (IO.DEFAULT) ( -- )
top" IO.DEFAULT"
\
io.glob.default
io.hp.default
io.matrix.default
io.input.default
io.output.default
\
io.ui.default
io.menus.default
;
io_file? .IF
\ redefine (IO.DEFAULT). Attempt to load "io preferences" file. If
\ unsuccessful, uses the compiled default settings. See modules:io_file.
: IO.MAYBE.FILE.DEFAULT ( -- flag )
(io.default)
io.file.default \ -- flag
;
: (IO.DEFAULT) ( -- )
io.file.default drop
;
.THEN
: (IO.RESET) ( -- )
top" IO.RESET"
\
gr.save.text gr.reset.text
\
?shift NOT
IF time@ rand-seed ! \ set randome number seed
THEN
\
io.glob.reset
io.hp.reset
io.matrix.reset
io.input.reset
io.output.reset
\
io.ui.reset
io.menus.reset
\
gr.restore.text
;
: (IO.UPDATE) ( -- )
top" IO.UPDATE"
\
io.glob.update
io.hp.update
io.matrix.update
io.input.update
io.output.update
\
io.ui.update
io.menus.update
;
: (IO.PANIC) ( -- )
top" IO.PANIC"
\
gr.save.text gr.panic.text
\
io.glob.panic
io.hp.panic
io.matrix.panic
io.input.panic
io.output.panic
\
io.ui.panic
io.menus.panic
\
gr.restore.text
;
: (IO.STANDBY) ( -- )
top" IO.STANDBY"
\
setup.output.patch
\
io.glob.standby
io.hp.standby
io.matrix.standby
io.input.standby
io.output.standby
io.menus.standby
\
io.ui.standby
;
: (IO.START) ( -- )
top" IO.START"
\
io.glob.start
io.hp.start
io.matrix.start
io.input.start
io.output.start
io.menus.start
\
io.ui.start
;
: (IMBNF) ( -- , it must be nearly finished )
top" IT.MUST.BE.NEARLY.FINISHED"
\
glob.imbnf
hp.imbnf
matrix.imbnf
input.imbnf
output.imbnf
menus.imbnf
\
ui.imbnf
;
: (IO.STOP) ( -- )
top" IO.STOP"
\
gr.stopped.text
\
io.glob.stop
\
io.output.stop \ during fade out, this keeps morphs alive, so call first
\
io.hp.stop
io.matrix.stop
io.input.stop
io.menus.stop
io.ui.stop
\
[ io_file? .IF ]
\
\ switch to next "scene." See modules:io_file.
\
next.scene
[ .THEN ]
;
: (IO.PAUSE) ( -- )
top" IO.PAUSE"
\
io.glob.pause
io.hp.pause
io.matrix.pause
io.input.pause
io.output.pause
io.menus.pause
\
io.ui.pause
;
: (IO.RESUME) ( -- )
top" IO.RESUME"
\
io.glob.resume
io.hp.resume
io.matrix.resume
io.input.resume
io.output.resume
io.menus.resume
\
io.ui.resume
;
: (IO.PLAY) ( -- )
top" IO.PLAY"
\
io-pdur-mode @ strict_pdur =
IF
(io.standby)
(io.start)
ELSE
(io.standby)
THEN
;
\ words that additionally control graphics
io_file? .IF
: (IO.GR.DEFAULT) ( -- )
io.maybe.file.default
0=
IF
io.screen.default \ only do this if file open failed
THEN
;
.ELSE
: (IO.GR.DEFAULT) ( -- )
(io.default)
io.screen.default
;
.THEN
: (IO.GR.PLAY) ( -- )
io.screen.play
(io.play)
;
: (IO.GR.STOP) ( -- )
(io.stop)
io.screen.stop
;
: (IO.GR.PAUSE) ( -- )
(io.pause)
io.screen.pause
;
: (IO.GR.RESUME) ( -- )
io.screen.resume
(io.resume)
;
\ setup deferred words
: IO.VECTORS.INIT ( -- )
sub" io.vectors.init"
\
\ meta-alert-matrix functions (see: io_matrix)
\
'c (modify.time.advance) is MODIFY.TIME.ADVANCE
'c (modify.interp) is MODIFY.INTERP
'c (modify.patch) is MODIFY.PATCH
\
\ global control procedures (see: io_glob)
\
'c (io.default) is IO.DEFAULT
'c (io.reset) is IO.RESET
'c (io.update) is IO.UPDATE
'c (io.panic) is IO.PANIC
\
'c (io.standby) is IO.STANDBY
'c (io.start) is IO.START
'c (imbnf) is IT.MUST.BE.NEARLY.FINISHED
'c (io.stop) is IO.STOP
\
'c (io.pause) is IO.PAUSE
'c (io.resume) is IO.RESUME
\
'c (io.play) is IO.PLAY
\
'c (io.gr.default) is IO.GR.DEFAULT
\
'c (io.gr.play) is IO.GR.PLAY
'c (io.gr.stop) is IO.GR.STOP
'c (io.gr.pause) is IO.GR.PAUSE
'c (io.gr.resume) is IO.GR.RESUME
\
[ io_file? .IF ]
\
\ these are defined in modules:io_file, or, if io_turnkey? is true,
\ redefined in modules:io_menus.
\
'c (select.scene) is SELECT.SCENE
\
'c (next.scene) is NEXT.SCENE
'c (prev.scene) is PREV.SCENE
\
'c (add.scene) is ADD.SCENE
'c (delete.scene) is DELETE.SCENE
\
'c (unsaved.change) is UNSAVED.CHANGE
'c (saved.change) is SAVED.CHANGE
\
'c (unsaved.change?) is UNSAVED.CHANGE?
\
[ .THEN ]
;
: IO.VECTORS.TERM ( -- )
sub" io.vectors.term"
\
'c noop is MODIFY.TIME.ADVANCE
'c noop is MODIFY.INTERP
'c noop is MODIFY.PATCH
\
'c noop is IO.RESET
'c noop is IO.UPDATE
'c noop is IO.PANIC
\
'c noop is IO.STANDBY
'c noop is IO.START
'c noop is IO.STOP
'c noop is IO.PAUSE
'c noop is IO.RESUME
\
'c noop is IO.PLAY
\
'c noop is IO.GR.DEFAULT
\
'c noop is IO.GR.PLAY
'c noop is IO.GR.STOP
'c noop is IO.GR.PAUSE
'c noop is IO.GR.RESUME
\
[ io_file? .IF ]
\
'c drop is SELECT.SCENE
\
'c noop is NEXT.SCENE
'c noop is PREV.SCENE
\
'c noop is ADD.SCENE
'c noop is DELETE.SCENE
\
'c noop is UNSAVED.CHANGE
'c noop is SAVED.CHANGE
\
'c false is UNSAVED.CHANGE?
\
[ .THEN ]
;
\ setup & clearup
: IO.INIT ( -- )
top" IO.INIT"
\
[ io_test? NOT io_turnkey? AND .IF ]
run.faster \ turn off ODE error checking
[ .THEN ]
\
io.interp.table.init \ see file modules:io_interp_tables
\
io.vectors.init
\
io.config.init
io.glob.init
\
io.hp.init
io.matrix.init
io.input.init
io.output.init
\
io.ui.init
io.screen.init
\
[ io_file? .IF ]
io.file.init
[ .THEN ]
\
io.menus.init
\
\ each component's .INIT function no longer calls the corresponding .DEFAULT
\ thus we have to call IO.GR.DEFAULT here.
\
io.gr.default \ added MOD: 07-03-04
;
: IO.TERM ( -- )
top" IO.TERM"
\
[ io_file? .IF ]
io.file.term
[ .THEN ]
\
IO.INTERP.TABLE.TERM \ see file modules:io_interp_tables
\
io.vectors.term
\
io.config.term
io.glob.term
\
io.hp.term
io.matrix.term
io.input.term
io.output.term
\
io.ui.term
io.screen.term
io.menus.term
;
if.forgotten io.term
: IO ( -- )
io.init hmsl io.term
;
io_turnkey? .IF
'io_' -> midim_client \ set midi manager client id
: INIT ( -- )
cls
0 init-#errors !
false init-error? !
\
hmsl.init user.init cls
io.init
\
." Ready...."
;
: PLAY ( -- )
init-error? @
IF
init-#errors @ 1 =
IF
init-error? @
ELSE
" Sorry, more than one error occured during initialization (maybe a memory error). Quit and try restarting the program."
THEN
dialog.a
ELSE
io.open hmsl
THEN
;
: TERM ( -- )
io.term
user.term hmsl.term
;
.THEN
io_test? .IF
: IO.PRINT ( -- )
>newline
." IO" cr
\
io.config.print ?pause cr
io.glob.print ?pause cr
io.output.print ?pause cr
io.hp.print ?pause cr
io.matrix.print ?pause cr
io.input.print ?pause cr
io.screen.print cr
;
cr io.config.print
.THEN
cr io.title $. cr
io_turnkey? .IF
cr
." Ready to be turnkeyed!" cr cr
." Enter: include hsys:turnkey.f" cr
." 'c init 'c play 'c term turnkey" cr
." Add all necessary resources!" cr cr
.ELSE
cr
." Enter 'io' to awake this actor..." cr cr
cr
.THEN