\ 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