diff options
Diffstat (limited to 'Src/Plugins/Input/in_midi/seq.cpp')
-rw-r--r-- | Src/Plugins/Input/in_midi/seq.cpp | 852 |
1 files changed, 852 insertions, 0 deletions
diff --git a/Src/Plugins/Input/in_midi/seq.cpp b/Src/Plugins/Input/in_midi/seq.cpp new file mode 100644 index 00000000..f1fb65fb --- /dev/null +++ b/Src/Plugins/Input/in_midi/seq.cpp @@ -0,0 +1,852 @@ +#include "main.h" +#include "seq.h" +#include <commctrl.h> +#include <math.h> +#include "resource.h" + +#ifdef SEQ_HAVE_PANEL + +cfg_int cfg_seq_showpanel("seq_showpanel",0); + +enum +{ + ID_BASE = 0x6543, + MUTE_ID = ID_BASE, + VOL_ID = MUTE_ID+16, + INS_ID_P = VOL_ID+16, + INS_ID_B1 = INS_ID_P+16, + INS_ID_B2 = INS_ID_B1+16, + SPIN_ID = INS_ID_B2 + +}; + +static cfg_int cfg_ctrl_min("ctrl_min",0); + + +static float g_tempo=1; +static BOOL g_novol,g_noins; +static char sysex1[256],sysex2[256]; + +extern BYTE d_GMReset[6]; +extern BYTE d_XGReset[9]; +extern BYTE d_GSReset[11]; +#endif + +#define SEND_MSG(X) seq_shortmsg(preprocess(X)) + +#define _sysex(A,B) seq_sysex(A,B) +#define rsysex(A) seq_sysex(A,sizeof(A)) + +#ifdef SEQ_HAVE_PANEL +void seq_base::set_mute(UINT ch,BOOL st) +{ + if (st) + { + mute_mask|=1<<ch; + seq_shortmsg(0x07B0|ch); + } + else + { + mute_mask&=~(1<<ch); + SEND_MSG(((DWORD)ctrl_tab[ch][7]<<16)|0x07B0|ch); + } +} +#endif + +//debug hack +#if 0 +#define timeGetTime timehack +static DWORD timehack() +{ + static DWORD t; + return t++; +} +#endif + +DWORD seq_base::get_time() +{ +#ifndef SEQ_HAVE_PANEL + return timeGetTime()<<3; +#else + if (!hCtrl) return timeGetTime()<<3;//*8; + EnterCriticalSection(&tm_sec); + DWORD cur_t=timeGetTime(); + if (!last_time_ms) last_time_ms=cur_t; + int d=cur_t-last_time_ms; + if (d<0) d=0; + last_time_ret+=(double)(d*8.0)*tempo; + + last_time_ms=cur_t; + DWORD r=(DWORD)last_time_ret; + LeaveCriticalSection(&tm_sec); + return r; +#endif +} + +#ifdef SEQ_HAVE_PANEL +BOOL CALLBACK seq_base::CtrlProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp) +{ + seq_base* s; + if (msg==WM_INITDIALOG) + { + SetWindowLongPtr(wnd,DWLP_USER,lp); + s=(seq_base*)lp; + if (s) s->hCtrl=wnd; + } + else + { +#if defined(_WIN64) + s = (seq_base*)GetWindowLong(wnd, DWLP_USER); +#else + s = (seq_base*)GetWindowLong(wnd, DWL_USER); +#endif + } + if (s) + { + s->do_msg(msg,wp,lp); + } + return 0; +} + +static float ui2tempo(int x) +{ + return (float)pow(4.0,0.02*(float)(x-50)); +} + +static int tempo2ui(float x) +{ + return 50+(int) ((50.0 / log(4.0)) * log(x) ); +} + +static void do_ttext(HWND w,float t) +{ + char tx[32] = {0}; + _itoa((UINT)(t*100.0),tx,10); + char* p=tx; + while(p && *p) p++; + *(p++)='%'; + *p=0; + SetDlgItemTextA(w,IDC_TDISP,tx); +} + +BYTE* read_sysex_edit(HWND w,UINT *siz); + +void CreateControl(DWORD ex,HWND hCtrl,const char * cls,const char * name,DWORD style,UINT x,UINT y,UINT dx,UINT dy,HINSTANCE hDll,UINT id) +{ + RECT r={(LONG)x,(LONG)y,(LONG)(x+dx),(LONG)(y+dy)}; + MapDialogRect(hCtrl,&r); + HWND w = CreateWindowExA( ex, cls, name, WS_CHILD | WS_VISIBLE | style, r.left, r.top, r.right - r.left, r.bottom - r.top, hCtrl, 0, hDll, 0 ); // Must stay in ANSI + if (w) + { + if (id) SetWindowLong(w,GWL_ID,id); + SendMessage(w,WM_SETFONT,SendMessage(hCtrl,WM_GETFONT,0,0),MAKELONG(0,0)); + } +} + +static cfg_int cfg_ctrl_x("ctrl_x",0x80000000),cfg_ctrl_y("ctrl_y",0x80000000); + +void seq_base::do_msg(UINT msg,WPARAM wp,LPARAM lp) +{ + switch(msg) + { + case WM_CLOSE: + ShowWindow(hCtrl,SW_SHOWMINIMIZED); + break; + case WM_INITDIALOG: + { + HINSTANCE hCCdll=GetModuleHandle(TEXT("comctl32.dll")); + UINT n; + HWND w; + for(n=0;n<16;n++) + { + char tmp[16] = {0}; + itoa(n,tmp,10); + CreateControl(0,hCtrl,TRACKBAR_CLASSA,0,TBS_VERT | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,40+n*28,36,18,80,hCCdll,VOL_ID+n); + CreateControl(0,hCtrl,"STATIC",tmp,0,46+n*28,25,8,8,0,0); + CreateControl(0,hCtrl,"Button",0,BS_AUTOCHECKBOX | WS_TABSTOP,43+28*n,120,9,8,0,MUTE_ID+n); + CreateControl(WS_EX_CLIENTEDGE,hCtrl,"EDIT",0,ES_AUTOHSCROLL | ES_NUMBER,36+28*n,138,26,12,0,INS_ID_P+n); + CreateControl(0,hCtrl,"msctls_updown32",0,UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,0,0,0,0,0,SPIN_ID+n); + CreateControl(WS_EX_CLIENTEDGE,hCtrl,"EDIT",0,ES_AUTOHSCROLL | ES_NUMBER,36+28*n,150,26,12,0,INS_ID_B1+n); + CreateControl(0,hCtrl,"msctls_updown32",0,UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,0,0,0,0,0,SPIN_ID+n+16); + CreateControl(WS_EX_CLIENTEDGE,hCtrl,"EDIT",0,ES_AUTOHSCROLL | ES_NUMBER,36+28*n,162,26,12,0,INS_ID_B2+n); + CreateControl(0,hCtrl,"msctls_updown32",0,UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,0,0,0,0,0,SPIN_ID+n+32); + } + + w=GetDlgItem(hCtrl,IDC_TEMPO); + SendMessage(w,TBM_SETRANGE,0,MAKELONG(0,100)); + SendMessage(w,TBM_SETPOS,1,tempo2ui(tempo)); + do_ttext(hCtrl,tempo); + if (cfg_ctrl_x!=0x80000000 && cfg_ctrl_y!=0x80000000) + { + int max_x=GetSystemMetrics(SM_CXSCREEN)-10,max_y=GetSystemMetrics(SM_CYSCREEN)-10; + if (cfg_ctrl_x>max_x) cfg_ctrl_x=max_x; + if (cfg_ctrl_y>max_y) cfg_ctrl_y=max_y; + SetWindowPos(hCtrl,0,cfg_ctrl_x,cfg_ctrl_y,0,0,SWP_NOZORDER|SWP_NOSIZE); + } + for(n=0;n<16;n++) + { + w=GetDlgItem(hCtrl,VOL_ID+n); + SendMessage(w,TBM_SETRANGE,1,MAKELONG(0,0x7f)); + SendMessage(w,TBM_SETPOS,1,0x7f-90); + } + SendDlgItemMessage(hCtrl,IDC_NOVOL,BM_SETCHECK,novol,0); + SetDlgItemTextA(hCtrl,IDC_SYSEX1,sysex1); + SetDlgItemTextA(hCtrl,IDC_SYSEX2,sysex2); + for(n=0;n<48;n++) + { + SendDlgItemMessage(hCtrl,SPIN_ID+n,UDM_SETRANGE,0,MAKELONG(127,0)); + } + for(n=0;n<16;n++) + { + SendDlgItemMessage(hCtrl,INS_ID_P+n,EM_LIMITTEXT,3,0); + SendDlgItemMessage(hCtrl,INS_ID_B1+n,EM_LIMITTEXT,3,0); + SendDlgItemMessage(hCtrl,INS_ID_B2+n,EM_LIMITTEXT,3,0); + } + initialized=1; + } + break; + case WM_COMMAND: + { + UINT n; + if (HIWORD(wp)==0) + { + if (wp==IDC_SYSEX1_SEND || wp==IDC_SYSEX2_SEND) + { + UINT sl; + BYTE* s=read_sysex_edit(GetDlgItem(hCtrl,(wp==IDC_SYSEX1_SEND)?IDC_SYSEX1:IDC_SYSEX2) , &sl); + if (s) + { + _sysex(s,sl); + free(s); + } + } + else if (wp==IDC_NOVOL) + { + novol=SendMessage((HWND)lp,BM_GETCHECK,0,0); + } + else if (wp==IDC_NOINS) + { + noins=SendMessage((HWND)lp,BM_GETCHECK,0,0); + } + else if (wp==IDC_ALL_ON) + { + UINT n; + for(n=0;n<16;n++) + { + if (mute_mask&(1<<n)) + { + SendDlgItemMessage(hCtrl,MUTE_ID+n,BM_SETCHECK,0,0); + set_mute(n,0); + } + } + } + else if (wp==IDC_ALL_OFF) + { + UINT n; + for(n=0;n<16;n++) + { + if (!(mute_mask&(1<<n))) + { + SendDlgItemMessage(hCtrl,MUTE_ID+n,BM_SETCHECK,1,0); + set_mute(n,1); + } + } + } + else if (wp==IDC_GMRESET) + { + rsysex(d_GMReset); + } + else if (wp==IDC_GSRESET) + { + rsysex(d_GSReset); + } + else if (wp==IDC_XGRESET) + { + rsysex(d_XGReset); + } + else for(n=0;n<16;n++) + { + if (wp==MUTE_ID+n) + { + set_mute(n,SendMessage((HWND)lp,BM_GETCHECK,0,0)); + break; + } + } + } + else if (HIWORD(wp)==EN_CHANGE) + { + if (initialized) + { + wp&=0xFFFF; + UINT n; + for(n=0;n<16;n++) + { + if (wp==INS_ID_P+n) + { + UINT p=GetDlgItemInt(hCtrl,wp,0,0)&0x7F; + if (p!=ins_tab[n]) + { + ins_tab[n]=p; + SEND_MSG(0xC0|n|(p<<8)); + } + break; + } + else if (wp==INS_ID_B1+n) + { + UINT p=GetDlgItemInt(hCtrl,wp,0,0)&0x7F; + if (p!=ctrl_tab[n][0]) + { + ctrl_tab[n][0]=p; + SEND_MSG(0xB0|n|(p<<16)); + SEND_MSG(0xC0|n|(ins_tab[n]<<8)); + } + break; + } + else if (wp==INS_ID_B2+n) + { + UINT p=GetDlgItemInt(hCtrl,wp,0,0)&0x7F; + if (p!=ctrl_tab[n][0x20]) + { + ctrl_tab[n][0x20]=p; + SEND_MSG(0x20B0|n|(p<<16)); + SEND_MSG(0xC0|n|(ins_tab[n]<<8)); + } + break; + } + } + } + } + + } + break; + case WM_VSCROLL: + { + HWND sb=(HWND)lp; + if (sb) + { + UINT id=GetWindowLong(sb,GWL_ID); + UINT n; + for(n=0;n<16;n++) + { + if (id==VOL_ID+n) + { + UINT val=0x7f-SendMessage(sb,TBM_GETPOS,0,0); + ctrl_tab[n][7]=val; + SEND_MSG(0x7B0|n|(val<<16)); + break; + } + + } + } + } + break; + case WM_HSCROLL: + tempo=ui2tempo(SendDlgItemMessage(hCtrl,IDC_TEMPO,TBM_GETPOS,0,0)); + do_ttext(hCtrl,tempo); + break; + } +} +#endif + +seq_base::~seq_base() +{ +#ifdef SEQ_HAVE_PANEL + if (hCtrl) + { + cfg_ctrl_min=!!IsIconic(hCtrl); + RECT r; + GetWindowRect(hCtrl,&r); + cfg_ctrl_x=r.left; + cfg_ctrl_y=r.top; + GetDlgItemTextA(hCtrl,IDC_SYSEX1,sysex1,256); + GetDlgItemTextA(hCtrl,IDC_SYSEX2,sysex2,256); + DestroyWindow(hCtrl); + DeleteCriticalSection(&tm_sec); + } + g_tempo=tempo; + g_novol=novol; + g_noins=noins; +#endif + if (events) free(events); +} + +seq_base::seq_base() +{ + mf=0; + + kill=0;paused=0; + smap=0; + + pan=0;vol=0; + + seek_to=0; + n_events=0; + events=0; + + c_loop=0; + loop_start=0; + memset(¬es,0,sizeof(notes)); + memset(&ctrl_tab,0,sizeof(ctrl_tab)); + memset(&ins_tab,0,sizeof(ins_tab)); + + tm_ofs=0; + p_time=0; + hTrd=0; + + ins_set=0; + +#ifdef SEQ_HAVE_PANEL + hCtrl=0; + + tempo=g_tempo; + novol=g_novol; + noins=g_noins; + + last_time_ms=0; + last_time_ret=0; + + mute_mask=0; + initialized=0; +#endif +} + + +#define GET_TIME get_time()//timeGetTime() + +int IS_SPEC_C(int x) {return (x>=0x60 && x<=0x65) || x==6 || x==26 || x>=120;} + +#define n_sysex smap->pos + + +DWORD seq_base::preprocess(DWORD e) +{ + BYTE t=(BYTE)(e&0xF0); + if (t==0xB0) + { + UINT v=(e>>16)&0xFF; + BYTE c=(BYTE)(e>>8); +#ifdef SEQ_HAVE_PANEL + if (c==7) + { + if (mute_mask&(1<<(e&0xF))) v=0; + } +#endif + e=(e&0xFFFF)|((v&0xFF)<<16); + } + else if (t==0xC0) + { + ins_set|=1<<(e&0xF); + } + return e; +} + +void seq_base::send_sysex(int n) +{ +#ifdef USE_LOG + log_write("send_sysex()"); +#endif + if (!smap || n>=n_sysex) return; + _sysex(smap->data+smap->events[n].ofs,smap->events[n].len); +} + +/* +void seq_base::reset_ins() +{ + UINT n; + for(n=0;n<16;n++) + { + cb->shortmsg(0xC0|n); + } +} +*/ + +BOOL seq_base::do_ctrl(DWORD e) +{ + BYTE tp=(BYTE)(e&0xF0); + BYTE ch=(BYTE)(e&0x0F); + if (tp==0xC0) + { +#ifdef SEQ_HAVE_PANEL + if (noins) return 0; +#endif + //if (!cfg_fctrl && (e>>8)==ins_tab[e&0xF]) return 0; + UINT val=e>>8; + ins_tab[ch]=val; +#ifdef SEQ_HAVE_PANEL + if (hCtrl) SetDlgItemInt(hCtrl,INS_ID_P+ch,val,0); +#endif + } else if (tp==0xB0) + { + UINT cn = (e>>8)&0x7F; + UINT val= (e>>16)&0x7F; +#ifdef SEQ_HAVE_PANEL + if (cn==0) + { + if (noins) return 0; + if (hCtrl) SetDlgItemInt(hCtrl,INS_ID_B1+ch,val,0); + } + else if (cn==0x20) + { + if (noins) return 0; + if (hCtrl) SetDlgItemInt(hCtrl,INS_ID_B2+ch,val,0); + } + else if (cn==7) + { + if (novol) return 0; + if (hCtrl) PostMessage(GetDlgItem(hCtrl,VOL_ID+(e&0xF)),TBM_SETPOS,1,0x7F-val); + } + else if (cn==0x27) + { + if (novol) return 0; + } +#endif + if (!IS_SPEC_C(cn)) ctrl_tab[e&0xF][cn]=val; + } + else if (tp==0x90) + { + if (!(ins_set&(1<<ch))) + { + SEND_MSG(0xC0|ch); + } + } + return 1; +} + +void seq_base::reset() +{ + int not,ch; + for(ch=0;ch<16;ch++) + { + if (ctrl_tab[ch][0x40]) + { + seq_shortmsg(0x40B0|ch); + ctrl_tab[ch][0x40]=0; + } + if (ch==9) continue; + for(not=0;not<128;not++) + { + if (note_state(ch,not)) + { + seq_shortmsg((not<<8)|0x80|ch); + note_off(ch,not); + } + } + } +} + + +int seq_base::note_state(int ch,int note) +{ + UINT pos=(ch<<7)+note; + return notes[pos>>3]&(1<<(pos&0x7)); +} + +void seq_base::note_on(int ch,int note) +{ + UINT pos=(ch<<7)+note; + notes[pos>>3]|=(1<<(pos&0x7)); +} + +void seq_base::note_off(int ch,int note) +{ + UINT pos=(ch<<7)+note; + notes[pos>>3]&=~(1<<(pos&0x7)); +} + +UINT seq_base::do_seek(DWORD n,DWORD p) +{ + UINT m,c; + BYTE _ctrl_tab[16][128] = {0}; + BYTE _ins_tab[16] = {0}; + memcpy(_ctrl_tab,ctrl_tab,sizeof(_ctrl_tab)); + memcpy(_ins_tab,ins_tab,sizeof(_ins_tab)); + + if (n==0) + { + memset(ins_tab,0,sizeof(ins_tab)); + for(m=0;m<16;m++) + { + _ctrl_tab[m][0]=_ctrl_tab[m][0x20]=0; + } + } + + while(n<n_events && p>events[n].tm) + { + DWORD e=events[n].ev; + if (!(e&0x80000000)) + { + if (do_ctrl(e)) + { + if (((e&0xF0)==0xB0) && IS_SPEC_C((e>>8)&0xFF)) + { + seq_shortmsg(e); + } + } + } + n++; + } + for(c=0;c<16;c++) + { + for(m=0;m<128;m++) + { + if (!IS_SPEC_C(m) && _ctrl_tab[c][m]!=ctrl_tab[c][m]) + { + SEND_MSG(((DWORD)ctrl_tab[c][m]<<16)|(m<<8)|0xB0|c); + } + } + if (_ins_tab[c]!=ins_tab[c]) + { + SEND_MSG(((DWORD)ins_tab[c]<<8)|0xC0|c); + } + } + return n; +} + +DWORD WINAPI seq_base::seq_trd(void* p) +{ + ((seq_base*)p)->thread(); + return 0; +} + +void seq_base::sysexfunc(seq_base* cb,BYTE* s,UINT sz) +{ + cb->seq_sysex(s,sz); +} + +void seq_base::thread() +{ + tm_ofs=-1; + if (seq_play_start()) + { + + sysex_startup((SYSEXFUNC)sysexfunc,this); + + tm_ofs=GET_TIME; + DWORD pos=0; + while(!kill) + { + DWORD c_t=GET_TIME-tm_ofs; + if (paused) + { + reset(); + while(paused && !kill) MIDI_callback::Idle(); + if (kill) break; + tm_ofs=GET_TIME-c_t; + } + + if (seek_to!=-1) + { +_seek: + DWORD _p=seek_to > c_t ? pos : 0; + c_t=seek_to; + seek_to=-1; + tm_ofs=GET_TIME-c_t; + reset(); + pos=c_t ? do_seek(_p,c_t) : 0; + } + if (events[pos].tm+1600 < c_t) + { + reset(); + pos=do_seek(pos,c_t); + } + while(pos<n_events && events[pos].tm<=c_t && !kill) + { + DWORD e=events[pos++].ev; + if (e) + { + if (e&0x80000000) + { + send_sysex(e&0x7FFFFFFF); + } + else + { + if ((e&0xF0)==0x90) + { + note_on(e&0xf,(e>>8)&0xFF); + } + else if ((e&0xF0)==0x80) + { + note_off(e&0xf,(e>>8)&0xFF); + } + if (do_ctrl(e)) + SEND_MSG(e); + } + } + } + + if (pos>=n_events || c_t >= events[n_events-1].tm) + { + if (loop_start!=-1 && (--c_loop)) + { + c_t=loop_start; + tm_ofs=GET_TIME-c_t; + pos=do_seek(0,c_t); + continue; + } + if (cfg_eof_delay) + { + DWORD t=timeGetTime(); + do + { + MIDI_callback::Idle(); + } while(!kill && seek_to==-1 && t+cfg_eof_delay>timeGetTime()); + if (seek_to!=-1) { + pos=0; + goto _seek; + } + } + if (!kill) MIDI_core::Eof(); + break; + } + if (kill) break; + + MIDI_callback::Idle(); + } + reset(); + } + seq_play_stop(); +} + +int seq_base::gettime() +{ + if (paused) + return (seek_to==-1) ? seek_to>>3 : p_time; + else + return (GET_TIME-tm_ofs)>>3; +} + +int seq_base::settime(int tm) +{ + seek_to=tm<<3; + return 1; +} + + +void seq_base::pause() +{ + paused=1; + p_time=GET_TIME-tm_ofs; +} + +void seq_base::unpause() +{ + paused=0; +} + +int seq_base::seq_cmd_start(DWORD cflags) +{ + mf=MIDI_core::getFile(); +#ifdef SEQ_HAVE_PANEL + mute_mask=0; +#endif + c_loop=cfg_loop_infinite ? -1 : cfg_loop_count; + memset(notes,0,sizeof(notes)); + memset(ctrl_tab,-1,sizeof(ctrl_tab)); + memset(ins_tab,0,sizeof(ins_tab)); + + UINT n; + for(n=0;n<16;n++) ctrl_tab[n][7]=90; + + events=do_table(mf,8,&n_events,&loop_start,cflags); + if (!events) return 0; + + if (!cfg_nosysex && mf->smap && mf->smap->pos) + { + smap=mf->smap; + } + else smap=0; + + kill=0; + seek_to=-1; + paused=0; + +#ifdef SEQ_HAVE_PANEL + if (cfg_seq_showpanel) + { + InitializeCriticalSection(&tm_sec); + WASABI_API_CREATEDIALOGPARAMW(IDD_EXT_IMM, MIDI_callback::GetMainWindow(), CtrlProc, (LPARAM)this); + ShowWindow(hCtrl,cfg_ctrl_min ? SW_SHOWMINIMIZED : SW_SHOW); + } + else + { + tempo=1; + novol=0; + noins=0; + } +#endif + + DWORD id; + hTrd=CreateThread(0,0,seq_trd,this,CREATE_SUSPENDED,&id); +#ifndef _DEBUG + SetThreadPriority(hTrd,THREAD_PRIORITY_TIME_CRITICAL); +#endif + ResumeThread(hTrd); + return 1; +} + +void seq_base::seq_cmd_stop() +{ +#ifdef USE_LOG + log_write("stopping sequencer"); +#endif + if (hTrd) + { +#ifdef USE_LOG + log_write("killing thread"); +#endif + kill=1; + if (WaitForSingleObject(hTrd,4000)!=WAIT_OBJECT_0) + { +#ifdef USE_LOG + log_write("unable to kill thread"); +#endif + TerminateThread(hTrd,0); + } +#ifdef USE_LOG + else log_write("thread killed normally"); +#endif + CloseHandle(hTrd); + } +} +/* +void seq_base::enum_ins() +{ + DWORD ttab[256]; + memset(ttab,-1,sizeof(ttab)); + UINT tpt=0; + UINT n; + DWORD c_ins[16]; + memset(c_ins,0,sizeof(c_ins)); + c_ins[9]=0x80000000; + for(n=0;n<n_events;n++) + { + DWORD t=events[n].ev; + if (t&0xFF000000) continue; + UINT c=t&0xF0; + UINT ch=events[n].ev&0xF; + if ((t&0xFFF0)==0x20B0) + { + c_ins[ch]=(c_ins[ch]&0xFFFF00FF)|((t>>8)&0xFF00); + } + else if ((t&0xFFF0)==0xB0) + { + c_ins[ch]=(c_ins[ch]&0xFF00FFFF)|(t&0xFF0000); + } + else if ((t&0xF0)==0xC0) + { + c_ins[ch]=(c_ins[ch]&0xFFFFFF00)|((t>>8)&0xFF); + } + else if ((t&0xF0)==0x90) + { + UINT n; + for(n=0;n<256;n++) + { + if (ttab[n]==c_ins[ch]) goto ok; + } + cb->enum_ins(ttab[tpt]=c_ins[ch]); + tpt=(tpt+1)&0xFF; +ok:; + } + } +} +*/ |