📄 moxc.c
字号:
* m_restuntil* Inputs:* int time: call time to rest until* Effect: * Waits until the specified time has been reached (absolute time).* Other "caused" calls will take place during the rest provided* this routine is called from "mainscore" (see m_rest description).****************************************************************************/void m_restuntil(time) time_type time;{ time = virt_to_real(timebase, time); while(time > gettime()) { moxcwait(time); }}/***************************************************************************** m_rest* Inputs:* int time: Amount of time to rest* Effect: * Waits until the amount of time specified has lapsed* Assumes:* Must not be called from a "caused" routine. Must only be called* from "mainscore" or a routine called directly or indirectly from* "mainscore" without using "cause".****************************************************************************/void m_rest(time) time_type time;{ m_restuntil(time + real_to_virt(timebase, gettime())); }/***************************************************************************** moxcinit* Inputs:* int argc: number of command line arguments* char * argv: command line argument array* Effect: initializes moxc system****************************************************************************/boolean moxcinit(argc, argv) int argc; char * argv[];{ meminit(); io_init();#ifdef AMIGA pub_port_signal = AllocSignal(-1L); pub_port.mp_Node.ln_Type = NT_MSGPORT; pub_port.mp_SigBit = pub_port_signal; pub_port.mp_SigTask = FindTask(0L); pub_port.mp_Flags = PA_SIGNAL; pub_port.mp_Node.ln_Name = "CMTcmdport"; pub_port.mp_MsgList.lh_Head = (struct Node *)&pub_port.mp_MsgList.lh_Tail; pub_port.mp_MsgList.lh_TailPred = (struct Node *)&pub_port.mp_MsgList.lh_Head; event_mask |= (1L << pub_port_signal); AddPort(&pub_port);#endif cu_register((cu_fn_type) moxcterm, NULL); cl_syntax(midifns_syntax); cl_syntax("debug<s>Enable verbose debugging;\ moxc<s>Enable moxc debug mode;"); cl_syntax(app_syntax); if (!cl_init(argv, argc)) { /* make sure user gets to read the error message(s): */ gprintf(TRANS, "Type anything to exit...");#ifdef DOS wait_ascii();#else ggetchar();#endif return FALSE; } debug = cl_switch("debug"); moxcdebug = cl_switch("moxc"); timebase = default_base = timebase_create(100); default_base->rate = 2560L; eventtime = 0L; next_wakeup = MAXTIME; musicinit();#ifdef POSICIONADOR_3D ptInit();#endif moxcdone = 0; return TRUE;}/***************************************************************************** moxcwait* Input:* -1 => wait for next keyboard or midi event or queued event* 0 => don't wait* T => wait up to T for next keyboard or midi event or queued event* (this is used by m_restuntil)* Assume: there is work to do (npending > 0 || evqueue) ??* Effect: dispatch on user inputs, cause calls****************************************************************************/void moxcwait(dateoftimeout) time_type dateoftimeout;{ time_type maxtime = dateoftimeout; if (timebase_queue) { if ((timebase_queue->next_time >> 8) < maxtime) maxtime = (timebase_queue->next_time) >> 8; } eventwait(maxtime); decode();} /***************************************************************************** decode* Effect: dispatch on user inputs, cause calls****************************************************************************/private void decode(){ /* It is important that midi_data is on a word boundary because we copy to it by doing a word transfer. */ byte midi_data[4]; time_type now; byte code; char k;#ifdef AMIGA struct cmd_msg *cmd;#endif now = gettime(); timebase = default_base; eventtime = now; virttime = 0L;/* gprintf(GDEBUG, "decode at time %ld\n", now); *//*********************************************** poll for and decode midi keyboard input ***********************************************/ while (getbuf(FALSE, midi_data)) { /* only divide if necessary, divides take 100us on 8MHz 68000: */ if (virttime == 0) virttime = real_to_virt(default_base, now); /* short-circuit midi decoding */ if (!mididecode) { midievent(midi_data); continue; } code = midi_data[0] & MIDI_CODE_MASK; if (code == MIDI_ON_NOTE) { if (midi_data[2] == 0) { /* velocity 0 -> note off */ keyup(1+(midi_data[0] & MIDI_CHN_MASK), midi_data[1]); } else { keydown((midi_data[0] & MIDI_CHN_MASK)+1, midi_data[1], midi_data[2]); } } else if (code == MIDI_OFF_NOTE) { keyup((midi_data[0] & MIDI_CHN_MASK)+1, midi_data[1]); } else if (code == MIDI_TOUCH) { touchchange((midi_data[0] & MIDI_CHN_MASK)+1,midi_data[1]); } else if (code == MIDI_BEND) { bendchange((midi_data[0] & MIDI_CHN_MASK)+1, midi_data[1] + (midi_data[2] << 7)); } else if (code == MIDI_CTRL && midi_data[1] == SUSTAIN) { if (midi_data[2] == 0) pedup((midi_data[0] & MIDI_CHN_MASK) + 1); else peddown((midi_data[0] & MIDI_CHN_MASK) + 1); } else if (code == MIDI_CTRL) { ctrlchange((midi_data[0] & MIDI_CHN_MASK) + 1, midi_data[1], midi_data[2]); } else if (code == MIDI_CH_PROGRAM) { prgmchange((midi_data[0] & MIDI_CHN_MASK) + 1, midi_data[1] + 1);/* think C midi driver doesn't handle sysex the way the Amiga drivers do (yet) */#ifndef MACINTOSH } else if (code == MIDI_SYSEX) { sysex();#endif } }/*********************************************** poll for ASCII keyboard input ***********************************************/ while (get_ascii(&k)) { virttime = real_to_virt(default_base, now); asciievent(k); /* if user doesn't handle abort char in asciievent, we should exit now to avoid an infinite loop */ if (abort_flag) EXIT(1); }#ifdef POSICIONADOR_3D/*********************************************** poll for posicionador tridimensionale input**********************************************/ { pt_value pt_data; while (ptGetValue(&pt_data)) { /* only divide if necessary, divides take 100us on 8MHz 68000: */ if (virttime == 0) virttime = real_to_virt(default_base, now); ptevent(&pt_data); } }#endif /* POSICIONADOR_3D */#ifdef AMIGA/*********************************************** poll for proportional controller port **********************************************/ if (prop_1_events) { int events; Disable(); events = prop_1_events; prop_1_events = 0; Enable(); if (events & BUTTON_1_RIGHT_CHANGE) buttonchange(3, prop_1_right_button); if (events & BUTTON_1_LEFT_CHANGE) buttonchange(2, prop_1_left_button); if (events & PROP_1_LEFT_CHANGE) propchange(2, prop_1_left_data); if (events & PROP_1_RIGHT_CHANGE) propchange(3, prop_1_right_data); }/*********************************************** poll for input from public command port***********************************************/ while (cmd = (struct cmd_msg *) GetMsg(&pub_port)) { struct symb_descr *desc = &HASHENTRY(lookup(cmd->symbol_name));/* gprintf(TRANS, "got %lx (%s) from pub_port\n", cmd, cmd->symbol_name); */ virttime = real_to_virt(default_base, now); if (!desc) { gprintf(TRANS, "Error, symbol %s undefined.\n", cmd->symbol_name); } else if (desc->symb_type != cmd->symb_type) { gprintf(TRANS, "Error, wrong type for symbol %s\n", cmd->symbol_name); } else if (cmd->symb_type == fn_symb_type) {/* gprintf(TRANS, "Calling routine\n"); */ (*(desc->ptr.routine))( (int) cmd->the_args[0], (int) cmd->the_args[1], (int) cmd->the_args[2], (int) cmd->the_args[3], (int) cmd->the_args[4], (int) cmd->the_args[5], (int) cmd->the_args[6], (int) cmd->the_args[7] ); } else if (cmd->symb_type == var_symb_type) { *(desc->ptr.intptr) = (int) cmd->the_args[0]; } else if (cmd->symb_type == vec_symb_type) { if (cmd->the_args[0] >= desc->size) { gprintf(TRANS, "Error: Vector %s is of size %d\n", cmd->symbol_name, desc->size); } else { (desc->ptr.intptr)[cmd->the_args[0]] = cmd->the_args[1];/* gprintf(TRANS, "vec: setting %lx\n", &(desc->ptr.intptr)[cmd->the_args[0]]); */ } } else gprintf(TRANS, "Symbol Type Error\n"); ReplyMsg(&(cmd->msg)); }#endif/*********************************************** poll for next call in queue***********************************************/ now = (now + 1) << 8; /* shift because next_time is also scaled, * add 256 because next_time has added priority */ if (debug) gprintf(TRANS, "now %ld next_time %ld\n", now, (timebase_queue ? timebase_queue->next_time : 1234)); /* give pending events priority, but every 100 events, loop to allow input processing (user may want to give a "quit" command) */ for (k = 0; k < 100 && timebase_queue && (now > timebase_queue->next_time); k++) { callrun(); }/******************** flush text output ********************/#ifdef MACINTOSH_OR_UNIX gflush();#endif}/***************************************************************************** quit* Effect: tells moxc to shut down****************************************************************************/void quit(){ moxcdone = TRUE;}/* moxcrun -- schedule events until done *//**/void moxcrun(){ moxcdone = FALSE; while (!moxcdone && !abort_flag) { /* test for finish */ if (!timebase_queue) moxcdone = TRUE; else moxcwait(MAXTIME); /* do work */ }}/* moxcterm -- clean up after moxcinit *//**/private void moxcterm(){#ifdef AMIGA FreeSignal((long) pub_port_signal); RemPort(&pub_port);#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -