Created
October 6, 2025 22:07
-
-
Save bakueikozo/af459c9bc9f2314e26b3bc65ccdcdf4d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #define _GNU_SOURCE | |
| #include<stdio.h> | |
| #include <dlfcn.h> | |
| #include <stdio.h> | |
| #include <stdarg.h> | |
| #include <stdlib.h> | |
| #include <pthread.h> | |
| #include <unistd.h> | |
| #include <stdio.h> | |
| #include <string.h> | |
| #include <sys/time.h> | |
| #include <fcntl.h> | |
| #include <unistd.h> | |
| #include <string.h> | |
| #include <termios.h> | |
| #include <stdarg.h> | |
| #include <sys/types.h> | |
| #include <sys/stat.h> | |
| #include <sys/mman.h> | |
| #include <dlfcn.h> | |
| #include "typedef.h" | |
| #include "scr.h" | |
| #include <stdbool.h> | |
| int keyOffsetY = 400; | |
| int font; | |
| int plane; | |
| int keycanvas; | |
| typedef struct _toneinfo { | |
| int tick; | |
| int ch; | |
| int pitch; | |
| int length; | |
| } toneinfo; | |
| typedef struct _noteOnOffData { | |
| unsigned int tickOn; | |
| unsigned int tickOff; | |
| char pitch; | |
| char velocity; | |
| } noteOnOff; | |
| typedef struct _list { | |
| noteOnOff *chList[16]; | |
| int counts[16]; | |
| } noteList; | |
| typedef struct _chcounter{ | |
| int priority; | |
| int ch; | |
| int count; | |
| int enable; | |
| int program; | |
| int partmode; | |
| int volume; | |
| int remapPart; | |
| int pitchmap[128]; | |
| } chcounter; | |
| enum _remapType { | |
| Bass, | |
| Melody, | |
| Piano, | |
| Guitar, | |
| Strings | |
| }; | |
| typedef struct remapTable { | |
| char tables[32*32]; | |
| } remapTable; | |
| typedef struct beatInfo { | |
| int tick; | |
| char flag; | |
| } beatInfo; | |
| typedef struct _guidePage { | |
| unsigned int start; | |
| unsigned int stop; | |
| } guidePage; | |
| int n_guidePage=-1; | |
| typedef struct _vgmpos { | |
| void *p; | |
| int tick; | |
| int x; | |
| int y; | |
| int pitch; | |
| int last; | |
| } vgmpos; | |
| int vgmredraw = 0; | |
| typedef struct _codeData { | |
| char name[16]; | |
| int count; | |
| } codeData; | |
| int compareByCountDesc(const void *a, const void *b) { | |
| const codeData *data1 = (const codeData *)a; | |
| const codeData *data2 = (const codeData *)b; | |
| return data2->count - data1->count; // 降順 | |
| } | |
| int compareByNameSort(const void *a, const void *b) { | |
| const codeData *data1 = (const codeData *)a; | |
| const codeData *data2 = (const codeData *)b; | |
| return strcmp( data2->name, data1->name ); | |
| } | |
| typedef struct _playingStatus { | |
| remapTable rt; | |
| int lastShowNum; | |
| int lastHideNum; | |
| int updatecount; | |
| // int *keymap_cur; | |
| // int *keymap_last; | |
| // int keyMap[96*128]; | |
| // int keyMap_Stop[96*128]; | |
| // int keyReMap[96*128]; | |
| // int keyReMap_Stop[96*128]; | |
| int lastTime; | |
| noteList nl; | |
| beatInfo beats[10240]; | |
| int n_beats; | |
| toneinfo *pTones; | |
| int numoftones; | |
| int tracknum; | |
| chcounter ncount_ch[128]; | |
| int pitch_min; | |
| int pitch_max; | |
| int click_beats; | |
| int c_beats; | |
| int offset; | |
| char **tgParam; | |
| int guideFlag[128]; | |
| int midimode ; | |
| guidePage page[200]; | |
| vgmpos notepos[2000]; | |
| int vgmnotecount; | |
| int transpose; | |
| uint songnum; | |
| codeData codes[2000]; | |
| int codeCount; | |
| } playingStatus; | |
| playingStatus play_status; | |
| #define FIFO_CAPACITY 4096 // FIFOの容量を指定 | |
| // noteevent構造体 | |
| typedef struct _noteevent { | |
| int tick; | |
| char channel; | |
| char pitch; | |
| char onoff; | |
| } noteevent; | |
| #define MAX_NOTES 11 // 和音に含まれる最大音符数 | |
| // 和音のコード名、構成音の数、および根音を0とした相対的な音程の配列を持つ構造体 | |
| struct Chord { | |
| char chord_name[12]; // 和音のコード名(文字列、5文字まで) | |
| int num_notes; // 構成音の数 | |
| char intervals[MAX_NOTES]; // 根音を0とした相対的な音程を格納する配列 | |
| }; | |
| // 和音のコード名と、相対的な音程をそれぞれの構造体に格納する | |
| struct Chord chords[] = { | |
| {"", 3, {0, 4, 7}}, // メジャーコード | |
| {"m", 3, {0, 3, 7}}, // マイナーコード | |
| {"Aug", 3, {0, 4, 8}}, // オーギュメントコード | |
| {"Dim", 3, {0, 3, 6}}, // ディミニッシュコード | |
| {"m6", 4, {0, 3, 7, 9}}, // マイナーシックスコード | |
| {"7", 4, {0, 4, 7, 10}}, // ドミナントセブンスコード | |
| {"m7", 4, {0, 3, 7, 10}}, // マイナーセブンスコード | |
| {"M7", 4, {0, 4, 7, 11}}, // メジャーセブンスコード | |
| {"mM7", 4, {0, 3, 7, 11}}, // マイナーメジャーセブンスコード | |
| {"Sus4", 3, {0, 5, 7}}, // サスフォーンコード | |
| {"Sus2", 3, {0, 2, 7}}, // サスツーコード | |
| {"M7b5", 4, {0, 4, 6, 11}}, // メジャーセブンフラットファイブスコード | |
| {"M7s2", 5, {0, 2, 4, 7, 11}}, // メジャーセブンサスツーコード | |
| {"M7s4", 4, {0, 5, 7, 11}}, // メジャーセブンサスフォーンコード | |
| {"+9", 4, {0, 4, 7, 14}}, // アドナインスコード | |
| {"m6", 4, {0, 3, 7, 9}}, // マイナーシックススコード | |
| {"6", 4, {0, 4, 7, 9}}, // シックスコード | |
| {"7s4", 4, {0, 5, 7, 10}}, // セブンサスフォーンコード | |
| {"7b5", 4, {0, 4, 6, 10}}, // セブンフラットファイブスコード | |
| {"7#5", 4, {0, 4, 8, 10}}, // セブンシャープファイブスコード | |
| {"m7b5", 4, {0, 3, 6, 10}}, // マイナーセブンフラットファイブスコード | |
| {"M7#5", 4, {0, 4, 8, 11}}, // メジャーセブンシャープファイブスコード | |
| {"aug7", 4, {0, 4, 8, 10}}, // オーギュメントセブンスコード | |
| {"dim7", 4, {0, 3, 6, 9}}, // ディミニッシュセブンスコード | |
| // {"",0,{}} | |
| }; | |
| int *rotate(int *p,int size){ | |
| int n; | |
| int p1=*p; | |
| /* | |
| printf("before rotate "); | |
| for(n=0;n<size;n++){ | |
| printf("%d-",p[n]); | |
| } | |
| printf("\n");*/ | |
| for(n=0;n<size-1;n++){ | |
| p[n]=p[n+1]; | |
| } | |
| p[size-1] = (p1+12); | |
| /* | |
| printf("after rotate "); | |
| for(n=0;n<size;n++){ | |
| printf("%d-",p[n]); | |
| } | |
| printf("\n");*/ | |
| return p; | |
| } | |
| const char* pns[12] = {"C","C#","D","D#","E","F","F#","G","G#","A","A#","B" }; | |
| int getChord(int *map,int root,int trans,int *outRoot){ | |
| int cc = 0; | |
| int ret = -1; | |
| int chordarray[12] ={ 0}; | |
| for(int n=0;n<12;n++){ | |
| if( map[n]!=0 ){ | |
| chordarray[cc]=n; | |
| cc++; | |
| } | |
| if( map[n]!=root ) root = -1; | |
| } | |
| if(cc >= 3){ | |
| int c2; | |
| printf("array:"); | |
| for(int c=0;c<cc; c++){ | |
| printf("%d,",chordarray[c]); | |
| } | |
| //if( cc == 3 ){ | |
| for (int i = 0; i < sizeof(chords) / sizeof(chords[0]); ++i) { | |
| char cn[24]={0}; | |
| int r; | |
| for(r=0;r<cc;r++){ | |
| char arrayOffset[12]={0}; | |
| for(c2=0;c2<cc;c2++){ | |
| arrayOffset[c2]=chordarray[c2]-chordarray[0]; | |
| } | |
| // printf(" offseted="); | |
| for(c2=0;c2<cc;c2++){ | |
| // printf("%d-",arrayOffset[c2]); | |
| } | |
| // printf("\n"); | |
| if (cc== 3 && chords[i].num_notes == 3) { | |
| // triad perfect match | |
| if( memcmp(arrayOffset,chords[i].intervals,cc)== 0 ){ | |
| printf("%s%s",pns[(chordarray[0]+trans+12)%12],chords[i].chord_name); | |
| ret = i; | |
| *outRoot = (chordarray[0]+trans+12)%12; | |
| return ret; | |
| } | |
| } | |
| if (chords[i].num_notes <= 5) { | |
| if( memcmp(arrayOffset,chords[i].intervals,/*chords[i].num_notes*/cc)== 0 ){ | |
| printf("%s%s",pns[(chordarray[0]+trans+12)%12],chords[i].chord_name); | |
| ret = i; | |
| *outRoot = (chordarray[0]+trans+12)%12; | |
| return ret; | |
| } | |
| } | |
| rotate(chordarray,cc); | |
| } | |
| // if( ret != -1){ | |
| // } | |
| // if( cn[0]!=0 ){ | |
| // return strdup(cn); | |
| // } | |
| } | |
| } | |
| return -1; | |
| } | |
| char * _getChord(int *map,int root,int trans){ | |
| int cc = 0; | |
| int chordarray[12] ={ 0}; | |
| for(int n=0;n<12;n++){ | |
| if( map[n]!=0 ){ | |
| chordarray[cc]=n; | |
| cc++; | |
| } | |
| if( map[n]!=root ) root = -1; | |
| } | |
| // printf("array:"); | |
| for(int c=0;c<cc; c++){ | |
| // printf("%d,",chordarray[c]); | |
| } | |
| // printf("\n,numofTones=%d",cc); | |
| if(cc >= 3){ | |
| int c2; | |
| //if( cc == 3 ){ | |
| for (int i = 0; i < sizeof(chords) / sizeof(chords[0]); ++i) { | |
| // for all chords mappint template | |
| char cn[24]={0}; | |
| int r; | |
| for(r=0;r<cc;r++){ | |
| char arrayOffset[12]={0}; | |
| for(c2=0;c2<cc;c2++){ | |
| // printf("%s-",pns[ chordarray[c2]%12 ]); | |
| arrayOffset[c2]=chordarray[c2]-chordarray[0]; | |
| } | |
| // printf(" : "); | |
| // printf(" offseted="); | |
| for(c2=0;c2<cc;c2++){ | |
| // printf("%d-",arrayOffset[c2]); | |
| } | |
| // printf("\n"); | |
| if (cc== 3 && chords[i].num_notes == 3) { | |
| // triad perfect match | |
| if( memcmp(arrayOffset,chords[i].intervals,cc)== 0 ){ | |
| //printf("%s",chords[i].chord_name); | |
| sprintf(cn,"%s%s",pns[(chordarray[0]+trans+12)%12],chords[i].chord_name); | |
| break; | |
| } | |
| } | |
| if (chords[i].num_notes <= 5) { | |
| if( memcmp(arrayOffset,chords[i].intervals,/*chords[i].num_notes*/cc)== 0 ){ | |
| //printf("%s",chords[i].chord_name); | |
| sprintf(cn,"%s%s",pns[(chordarray[0]+trans+12)%12],chords[i].chord_name); | |
| break; | |
| } | |
| } | |
| rotate(chordarray,cc); | |
| } | |
| if( cn[0]!=0 ){ | |
| return strdup(cn); | |
| } | |
| } | |
| } | |
| return NULL; | |
| } | |
| typedef struct { | |
| int head; // 先頭インデックス | |
| int tail; // 末尾インデックス | |
| int size; // 現在の要素数 | |
| } FIFODATA; | |
| // FIFO構造体 | |
| typedef struct { | |
| noteevent buffer[FIFO_CAPACITY]; // noteeventを格納する配列 | |
| FIFODATA fi; | |
| } FIFO; | |
| FIFO notes,bass,vgmelo; | |
| // FIFOの初期化関数 | |
| void fifo_init(FIFO *fifo) { | |
| fifo->fi.head = 0; | |
| fifo->fi.tail = 0; | |
| fifo->fi.size = 0; | |
| } | |
| // FIFOに要素を格納する関数 | |
| bool fifo_push(FIFO *fifo, noteevent event) { | |
| if (fifo->fi.size >= FIFO_CAPACITY) { | |
| // FIFOが満杯の場合 | |
| return false; | |
| } | |
| fifo->buffer[fifo->fi.tail] = event; // 新しい要素を末尾に格納 | |
| fifo->fi.tail = (fifo->fi.tail + 1) % FIFO_CAPACITY; // 循環する末尾インデックス | |
| fifo->fi.size++; // 要素数を更新 | |
| return true; | |
| } | |
| // FIFOから要素を取り出す関数 | |
| bool fifo_pop(FIFO *fifo, noteevent *event) { | |
| if (fifo->fi.size <= 0) { | |
| // FIFOが空の場合 | |
| return false; | |
| } | |
| *event = fifo->buffer[fifo->fi.head]; // 先頭の要素を取得 | |
| fifo->fi.head = (fifo->fi.head + 1) % FIFO_CAPACITY; // 循環する先頭インデックス | |
| fifo->fi.size--; // 要素数を更新 | |
| return true; | |
| } | |
| // FIFOから要素を取り出す関数 | |
| bool fifo_at(FIFO *fifo, noteevent *event,int pos) { | |
| if (fifo->fi.size <= 0) { | |
| // FIFOが空の場合 | |
| return false; | |
| } | |
| *event = fifo->buffer[(fifo->fi.head + pos) % FIFO_CAPACITY]; // 先頭の要素を取得 | |
| return true; | |
| } | |
| // FIFOから要素を取り出す関数 | |
| bool fifo_peek(FIFO *fifo, noteevent *event) { | |
| if (fifo->fi.size <= 0) { | |
| // FIFOが空の場合 | |
| return false; | |
| } | |
| *event = fifo->buffer[fifo->fi.head]; // 先頭の要素を取得 | |
| return true; | |
| } | |
| // FIFOの長さを取得する関数 | |
| int fifo_length(FIFO *fifo) { | |
| return fifo->fi.size; | |
| } | |
| int n_showTargetPage = 0; | |
| int bInit = 0; | |
| unsigned long msqTime=0; | |
| unsigned long msqLastTime = 0; | |
| void dumpParameters(); | |
| void InitPlayStatus(){ | |
| if( font == 0){ | |
| font = osdGetFontSet(0x8001,2); | |
| plane=scrGetPlane(0); | |
| keycanvas = scrGetPlaneCanvas(plane); | |
| scrSelectFont(keycanvas,font); | |
| } | |
| play_status.midimode=0; | |
| printf("Initialize Playing Status\n\n\n"); | |
| play_status.lastTime=0; | |
| play_status.offset = 0; | |
| // memset(play_status.keyMap,96*128*sizeof(int),0); | |
| // memset(play_status.keyMap_Stop,96*128*sizeof(int),0); | |
| // memset(play_status.keyReMap,96*128*sizeof(int),0); | |
| // memset(play_status.keyReMap_Stop,96*128*sizeof(int),0); | |
| memset(play_status.rt.tables,32*32,1); | |
| // if(play_status.keymap_cur == NULL ){ | |
| // play_status.keymap_cur=calloc(sizeof(int)*96*128,1); | |
| // play_status.keymap_last=calloc(sizeof(int)*96*128,1); | |
| // } | |
| // memset(play_status.keymap_cur,96*128*sizeof(int),0); | |
| // memset(play_status.keymap_last,96*128*sizeof(int),0); | |
| play_status.lastShowNum = 0; | |
| if( play_status.pTones != NULL ){ | |
| free(play_status.pTones ); | |
| play_status.pTones=NULL; | |
| } | |
| if( play_status.pTones == NULL ){ | |
| play_status.pTones=calloc(sizeof(toneinfo),10240*16); | |
| play_status.lastShowNum = 0; | |
| play_status.tracknum = 0; | |
| play_status.numoftones=0; | |
| int i; | |
| for(i=0;i<128;i++){ | |
| play_status.ncount_ch[i].ch=i; | |
| play_status.ncount_ch[i].priority=0; | |
| play_status.ncount_ch[i].count=0; | |
| play_status.ncount_ch[i].volume=-1; | |
| play_status.ncount_ch[i].program=0; | |
| if( (i % 16) == 9 ){ | |
| play_status.ncount_ch[i].partmode=1; | |
| play_status.ncount_ch[i].volume=100; | |
| }else{ | |
| play_status.ncount_ch[i].partmode=0; | |
| } | |
| } | |
| } | |
| n_guidePage=0; | |
| n_showTargetPage=-1; | |
| memset(play_status.beats,0,10240); | |
| play_status.n_beats=0; | |
| play_status.c_beats=0; | |
| play_status.click_beats=0; | |
| play_status.vgmnotecount=0; | |
| play_status.tgParam = calloc(sizeof(char*)*2,1); | |
| play_status.tgParam[0]=calloc(0x201000,1); | |
| play_status.tgParam[1]=calloc(0x201000,1); | |
| play_status.transpose = 0; | |
| fifo_init(¬es); | |
| fifo_init(&bass); | |
| fifo_init(&vgmelo); | |
| msqLastTime = 0; | |
| msqTime=0; | |
| bInit=1; | |
| } | |
| char configname[1024]; | |
| char *makeConfigFilename(int tray,int chapter){ | |
| sprintf(configname,"/tango/sdk/%04d_%02d.cnf",tray,chapter); | |
| return configname; | |
| } | |
| #include <stdbool.h> | |
| #define MUTE_SIZE 11 | |
| typedef struct { | |
| int capo; | |
| bool mute_flags[MUTE_SIZE]; | |
| } Config; | |
| Config config; | |
| /** | |
| * 設定をデフォルト値で初期化 | |
| */ | |
| void set_config(Config *config) { | |
| config->capo = 0; // 初期値 | |
| for (int i = 0; i < MUTE_SIZE; i++) { | |
| config->mute_flags[i] = false; | |
| } | |
| } | |
| /** | |
| * 設定をファイルに保存 | |
| */ | |
| void save_config(int tray,int chapter,const Config *config) { | |
| FILE *file = fopen(makeConfigFilename(tray,chapter), "w"); | |
| if (!file) { | |
| perror("Failed to open config file for writing"); | |
| return; | |
| } | |
| fprintf(file, "capo=%d\n", config->capo); | |
| fprintf(file, "mute="); | |
| for (int i = 0; i < MUTE_SIZE; i++) { | |
| fprintf(file, "%d", config->mute_flags[i] ? 1 : 0); | |
| if (i < MUTE_SIZE - 1) fprintf(file, ","); | |
| } | |
| fprintf(file, "\n"); | |
| fclose(file); | |
| } | |
| /** | |
| * 設定をファイルから読み込む | |
| */ | |
| void load_config(int tray,int chapter,Config *config) { | |
| FILE *file = fopen(makeConfigFilename(tray,chapter), "r"); | |
| if (!file) { | |
| printf("Config file not found. Using default settings.\n"); | |
| set_config(config); | |
| return; | |
| } | |
| char line[128]; | |
| while (fgets(line, sizeof(line), file)) { | |
| if (sscanf(line, "capo=%d", &config->capo) == 1) { | |
| continue; | |
| } | |
| if (strncmp(line, "mute=", 5) == 0) { | |
| char *token = strtok(line + 5, ","); | |
| for (int i = 0; i < MUTE_SIZE && token; i++) { | |
| config->mute_flags[i] = atoi(token) ? true : false; | |
| token = strtok(NULL, ","); | |
| } | |
| } | |
| } | |
| fclose(file); | |
| } | |
| /** | |
| * 設定を表示(デバッグ用) | |
| */ | |
| void print_config(const Config *config) { | |
| printf("Capo: %d\n", config->capo); | |
| printf("Mute Flags: "); | |
| for (int i = 0; i < MUTE_SIZE; i++) { | |
| printf("%d ", config->mute_flags[i]); | |
| } | |
| printf("\n"); | |
| } | |
| int drawKeybase(); | |
| pthread_t thread=(pthread_t)NULL; | |
| int psqhandle; | |
| int clkGetClock(uint param_1); | |
| int updateKeyDraw(int clk); | |
| int mywnd=0; | |
| void (*posdClearWindow)(int *param_1,int param_2); | |
| int forceRedraw=0; | |
| void osdClearWindow(int *param_1,int param_2){ | |
| printf("osdClearWindow!\n"); | |
| posdClearWindow=dlsym(RTLD_NEXT,"osdClearWindow"); | |
| posdClearWindow(param_1,param_2); | |
| forceRedraw = 1; | |
| vgmredraw = 1; | |
| } | |
| int whiteWidth = 8; | |
| int blackWidth = 6; | |
| int keyHeight = 40; | |
| int keyLeft = 1920 / 3; | |
| int keycanvas; | |
| int lastpos=0; | |
| int exKeyLeft = 100; | |
| int drawbreak=0; | |
| int isChorus(int p); | |
| int isKB(int p); | |
| int isBell(int p); | |
| int isBass(int p); | |
| int isStrings(int p); | |
| int isBrass(int p); | |
| int isSynth(int p); | |
| int isGuiter(int p); | |
| typedef struct muteinfo { | |
| int togglekey; | |
| int (*func)(int ); | |
| int mute; | |
| const char *name; | |
| } MUTEINFO; | |
| MUTEINFO mi[10]={ | |
| {'1',isChorus,0,"Cho."}, | |
| {'2',isKB,0,"KB."}, | |
| {'3',isBell,0,"BELL"}, | |
| {'4',isBass,0,"BASS"}, | |
| {'5',isStrings,0,"STR."}, | |
| {'6',isBrass,0,"BRAS"}, | |
| {'7',isSynth,0,"SNTH"}, | |
| {'8',isGuiter,0,"Gt."}, | |
| {'9',NULL,0,"Drum"}, | |
| }; | |
| int screenRunning= 0; | |
| void *screentest(void *param){ | |
| int muteSent=0; | |
| undefined4 black_4[2] = { 4, 0xff010101}; | |
| undefined4 white_4[2] = { 4 ,0xfff0f0f0}; | |
| undefined4 gray_4[2] = { 4 ,0xfff808080}; | |
| undefined4 blue_4[2] = { 4, 0xff0000ff}; | |
| undefined4 red_4[2] = { 4 ,0xffff0000}; | |
| undefined4 green_4[2] = { 4 ,0xff00ff00}; | |
| undefined4 null_4[2] = { 4 ,0x0}; | |
| undefined4 black_5[2] = { 5, 0 }; | |
| undefined4 white_5[2] = { 5, 0 }; | |
| undefined4 gray_5[2] = { 5, 0 }; | |
| undefined4 blue_5[2] = { 5, 0 }; | |
| undefined4 red_5[2] = { 5, 0 }; | |
| undefined4 green_5[2] = { 5, 0 }; | |
| undefined4 null_5[2] = { 5, 0 }; | |
| scrConvertColorFormat(black_4,black_5,0); | |
| scrConvertColorFormat(white_4,white_5,0); | |
| scrConvertColorFormat(gray_4,gray_5,0); | |
| scrConvertColorFormat(blue_4,blue_5,0); | |
| scrConvertColorFormat(red_4,red_5,0); | |
| scrConvertColorFormat(green_4,green_5,0); | |
| scrConvertColorFormat(null_4,null_5,0); | |
| drawKeybase(); | |
| int *cc = (int *)osdGetClearColor(); | |
| int *cc2 =(int *)osdGetClearColor(); | |
| int lastBassOct[12] = {0}; | |
| char *pn[] = {"C","C#","D","D#","E","F","F#","G","G#","A","A#","B"}; | |
| char *pn2[] = {"ド","ド#","レ","レ#","ミ","ファ","ファ#","ソ","ソ#","ラ","ラ#","シ"}; | |
| int lastsec=0; | |
| printf("draw thread started songnum=%04d-%02d\n",play_status.songnum >> 8 ,play_status.songnum & 0xff); | |
| load_config(play_status.songnum >> 8 ,play_status.songnum & 0xff,&config); | |
| for(int m=0;m<10;m++){ | |
| mi[m].mute = config.mute_flags[m]; | |
| } | |
| doMute(); | |
| FIFO bassDraw; | |
| fifo_init(&bassDraw); | |
| screenRunning = 1; | |
| while(!drawbreak){ | |
| int cnt = 0; | |
| int clk=0; | |
| int ds=0; | |
| int summap[12]={0}; | |
| int sumup=0; | |
| int n_beat=0; | |
| int lastbassoff = 0; | |
| int lastvgmnote = 0; | |
| int chordMap[12] = { 0 }; | |
| // char lastChordName[16]={0}; | |
| int lastChord = -1; | |
| while(!drawbreak){ | |
| if( forceRedraw) { | |
| drawKeybase(); | |
| //scrSelectFont(keycanvas,font); | |
| scrSetTextColor(keycanvas,white_5,0,black_5); | |
| } | |
| if( (ds=fifo_length(¬es)) == 0 ){ | |
| break; | |
| }else{ | |
| } | |
| int *clkhandle = (int*)(psqhandle + 4); | |
| if( *clkhandle == 0){ | |
| drawbreak=1; | |
| } | |
| clk = clkGetClock(*clkhandle); | |
| if( lastsec != (clk / 1000)){ | |
| if( clk > 5000 && muteSent ==0 ){ | |
| doMute(); | |
| muteSent=1; | |
| } | |
| } | |
| noteevent n; | |
| int changed[16] = {0}; | |
| int subroot = 256; | |
| int root = -1; | |
| int lasttextx=0; | |
| int preDrawTime = 800; | |
| if( clk >= 0 ){ | |
| while(!drawbreak){ | |
| if( play_status.beats[play_status.c_beats].tick < (clk + play_status.offset + preDrawTime) ){ | |
| int bassChange = 0 ; | |
| if( ((play_status.beats[play_status.c_beats].flag)&0xff) == 0xf1 ){ | |
| n_beat = 0; | |
| }else{ | |
| n_beat ++; | |
| } | |
| // scrFillRect(keycanvas, 200 , 800 , 20 *8 , 20 , null_5); | |
| // scrFillRect(keycanvas, 200 + n_beat * 20 , 800 , 20 , 20 , white_5); | |
| //printf("beat %d @ %d",n_beat,play_status.beats[play_status.c_beats].tick); | |
| play_status.c_beats++; | |
| if( fifo_peek(&bass,&n)){ | |
| while( n.tick < clk + play_status.offset + preDrawTime + 3000){ | |
| bassChange = 1; | |
| fifo_pop(&bass,&n); | |
| fifo_push(&bassDraw,n); | |
| if( !fifo_peek(&bass,&n)) break; | |
| } | |
| } | |
| if( fifo_peek(&bassDraw,&n) ){ | |
| while( n.tick < clk + play_status.offset + preDrawTime ){ | |
| bassChange = 1; | |
| fifo_pop(&bassDraw,&n); | |
| if(! fifo_peek(&bassDraw,&n)){ | |
| break; | |
| } | |
| } | |
| } | |
| if( bassChange ){ | |
| int bl=fifo_length(&bassDraw); | |
| scrFillRect(keycanvas, exKeyLeft, 300 + keyOffsetY + 80 , 240 , 300 , null_5); | |
| for(int b=0;b<bl;b++){ | |
| fifo_at(&bassDraw,&n,b); | |
| // printf("Bass: @%dPitch=%d [%s] ch=%d\n",n.tick,n.pitch,pn[n.pitch%12],n.channel); | |
| //printf("%s ",pn[n.pitch%12]); | |
| int xoct = (n.pitch + play_status.transpose - config.capo )/12; | |
| int xmod = (n.pitch + play_status.transpose - config.capo )%12; | |
| int xpos; | |
| int xblack; | |
| GetKeyPos(xmod,&xpos,&xblack); | |
| int xl = exKeyLeft + xpos * (whiteWidth/2*2) + /*7 *2* whiteWidth*/ + 2; | |
| int yt = 300 + 40 + /*( - xblack * 20 )*/ + keyOffsetY + 12 + ( n.tick - (play_status.offset + clk ) ) / 20 ; | |
| if( n.onoff ){ | |
| int highlow = lastBassOct[xmod] > xoct ? ( lastBassOct[xmod] < xoct ? -1 : 0 ) : 1; | |
| lastBassOct[xmod]=xoct; | |
| if( xblack ){ | |
| if(highlow){ | |
| scrFillRect(keycanvas, xl-1, yt-1, 8 , 10 , green_5); | |
| scrFillRect(keycanvas, xl, yt, 6 , 8 , black_5); | |
| }else{ | |
| scrFillRect(keycanvas, xl-1, yt-1, 8 , 10 , black_5); | |
| scrFillRect(keycanvas, xl, yt, 6 , 8 , green_5); | |
| } | |
| }else{ | |
| if(highlow){ | |
| scrFillRect(keycanvas, xl-1, yt-1, 8 , 10 , green_5); | |
| scrFillRect(keycanvas, xl, yt, 6 , 8 , white_5); | |
| }else{ | |
| scrFillRect(keycanvas, xl-1, yt-1, 8 , 10 , white_5); | |
| scrFillRect(keycanvas, xl, yt, 6 , 8 , green_5); | |
| } | |
| } | |
| // printf("n.tick=%d clk=%d offset=%d yt=%d\n",n.tick , clk ,play_status.offset,yt); | |
| } | |
| } | |
| //printf("\n"); | |
| } | |
| } | |
| noteevent *pr=&n; | |
| if( vgmredraw ){ | |
| char tp[128]; | |
| sprintf(tp,"Oke Transpose=%d ,Playing Capo=%d",play_status.transpose,config.capo); | |
| scrFillRect(keycanvas, 0 , 0 , 1910 , 300 ,null_5 ); | |
| scrDrawText((int)keycanvas,tp, 24 , 24 , 1280 , 60 ,/*0x2404*/ 0 ); | |
| vgmredraw = 0; | |
| int lastx=0; | |
| printf("VGM text draw on %d\n",clk); | |
| if( /*play_status.notepos[lastvgmnote].tick < clk + play_status.offset +1000*/ 1 ){ | |
| for(int x=0;x< play_status.vgmnotecount ;x++){ | |
| if (play_status.notepos[x].tick > clk){ | |
| lastvgmnote = x ; | |
| printf("found vgm start point.\n"); | |
| break; | |
| } | |
| } | |
| for(int x=lastvgmnote;x< play_status.vgmnotecount ;x++){ | |
| printf("tick=%d tone=%s XPos=%d\n",play_status.notepos[x].tick,pn[play_status.notepos[x].pitch%12],play_status.notepos[x].x); | |
| scrDrawText((int)keycanvas, pn2[ (play_status.notepos[x].pitch + play_status.transpose - config.capo ) %12], play_status.notepos[x].x * 1920/1280 , play_status.notepos[x].y * 1080 / 720 - 12 | |
| , 200 , 60 ,/*0x2404*/ 0 ); | |
| if (play_status.notepos[x].last){ | |
| printf("stop at last flag.\n"); | |
| lastvgmnote = x+1; | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| fifo_peek(¬es,&n); | |
| if( pr->tick < clk + play_status.offset + preDrawTime /*-1000*/ ){ | |
| fifo_pop(¬es,&n); | |
| int orgch = pr->channel; | |
| int remapCh = 0; | |
| if( orgch < 0 ){ | |
| }else { | |
| remapCh = play_status.ncount_ch[orgch].remapPart; | |
| } | |
| changed[remapCh] = 1; | |
| sumup =1; | |
| int p=pr->pitch; | |
| if( pr->pitch != 0 ){ | |
| int xoct = (p + play_status.transpose - config.capo)/12; | |
| int xmod = (p + play_status.transpose - config.capo)%12; | |
| int xpos; | |
| int xblack; | |
| GetKeyPos(xmod,&xpos,&xblack); | |
| if( remapCh == 3 ){ | |
| if( (play_status.ncount_ch[orgch].program == 87 && pr->pitch < 60 )|| play_status.ncount_ch[orgch].program != 87 ){ | |
| // bass | |
| for(int c2 = 0 ; c2 < 8 ;c2++){ | |
| int xl = keyLeft +(7 * 8 ) * ( xoct -1 ) + xpos * (whiteWidth/2) +1 ; | |
| int yt = ((c2)* keyHeight) + 16 + ( - xblack * 10 ) + keyOffsetY; | |
| if( pr->onoff ){ | |
| scrFillRect(keycanvas, xl, yt, 6 , 8 , c2==3 ? red_5 : green_5); | |
| }else{ | |
| scrFillRect(keycanvas, xl, yt, 6 , 8 ,xblack ? black_5 : white_5); | |
| } | |
| { | |
| int xl2 = exKeyLeft + xpos * (whiteWidth/2*2) + 2 ; | |
| int yt2 = 300 +40 + ( - xblack * 20 ) + keyOffsetY; | |
| if( pr->onoff ){ | |
| scrFillRect(keycanvas, xl2, yt2, 10 , 16 , green_5); | |
| }else{ | |
| scrFillRect(keycanvas, xl2, yt2, 10 , 16 ,xblack ? black_5 : white_5); | |
| } | |
| } | |
| } | |
| if( pr->onoff ){ | |
| //scrFillRect(keycanvas, keyLeft - 300 , 3*keyHeight - 8 + keyOffsetY , 200 , 48 ,null_5); | |
| //scrSelectFont(keycanvas,font); | |
| //scrSetTextColor(keycanvas,white_5,0,black_5); | |
| // bass tone name | |
| //scrDrawText((int)keycanvas, pn[pr->pitch%12], keyLeft - 300 , 3*keyHeight - 8 + keyOffsetY | |
| // , 200 , 60 ,/*0x2404*/ 0 ); | |
| // scrFillRect(keycanvas, exKeyLeft-120 , 3*keyHeight - 8 + keyOffsetY , 120 , 96 ,null_5); | |
| // scrDrawText((int)keycanvas, pn[(pr->pitch + play_status.transpose - config.capo )%12], exKeyLeft - 120 , 3*keyHeight - 8 + keyOffsetY | |
| // , 200 , 60 ,/*0x2404*/ 0 ); | |
| root = pr->pitch; | |
| subroot=256; | |
| }else{ | |
| lastbassoff = clk; | |
| root = -1; | |
| } | |
| } | |
| }else{ | |
| int xl = keyLeft + (7 * 8 ) * ( xoct -1 ) + xpos * (whiteWidth/2) +1 ; | |
| int yt = ( remapCh * keyHeight) + 16 + ( - xblack * 10 ) + keyOffsetY; | |
| if( yt < keyOffsetY) { | |
| // printf("??? : @%d ch=%d pitch=%d\n",pr->tick,pr->channel,pr->pitch); | |
| } | |
| if( pr->onoff ){ | |
| scrFillRect(keycanvas, xl, yt, 6 , 8 , red_5); | |
| play_status.ncount_ch[remapCh].pitchmap[ pr->pitch ]++; | |
| if( subroot > pr->pitch ){ | |
| subroot = pr->pitch; | |
| } | |
| }else{ | |
| scrFillRect(keycanvas, xl, yt, 6 , 8 ,xblack ? black_5 : white_5); | |
| play_status.ncount_ch[remapCh].pitchmap[ pr->pitch ]--; | |
| } | |
| } | |
| if( remapCh < 9 && remapCh > 0){ | |
| summap[ pr->pitch %12] += pr->onoff ? 1 : -1; | |
| } | |
| } // pitch!=0 | |
| } // if intime | |
| else{ | |
| break; | |
| } | |
| }// while | |
| for(int ch=0;ch<9;ch++){ | |
| if( changed[ch] ){ | |
| int map[12]={0}; | |
| int root=-1; | |
| for(int p=0;p<128;p++){ | |
| map[p%12] += play_status.ncount_ch[ch].pitchmap[p]; | |
| if( root == -1 && play_status.ncount_ch[3].pitchmap[p] ){ | |
| root = p; | |
| } | |
| } | |
| // printf("track[%d] chordmap= { ",ch); | |
| char ms[128]={0}; | |
| int cc = 0; | |
| for(int p=0;p<12;p++){ | |
| if(map[p]>0){ | |
| // printf("%s(%d) ",pn[p],map[p]); | |
| strcat(ms,pn[p]); | |
| strcat(ms," "); | |
| cc++; | |
| } | |
| } | |
| // printf("}\n"); | |
| if( ch!=3 ){ | |
| int chordRoot=0; | |
| int chordIndex = getChord(map,root,0,&chordRoot) ; | |
| char p[128]={0}; | |
| if( chordIndex >= 0 ){ | |
| sprintf(p,"%s%s",pns[(chordRoot+play_status.transpose - config.capo+12)%12],chords[chordIndex].chord_name); | |
| } | |
| if( strlen(p) ){ | |
| //scrFillRect(keycanvas, keyLeft-300 , ch*keyHeight - 8 + keyOffsetY , 200 , keyHeight ,null_5); | |
| if( strlen(p )){ | |
| // scrDrawText((int)keycanvas, p , keyLeft - 300 , ch*keyHeight - 8 + keyOffsetY , 200 , 60 ,/*0x2404*/ 0 ); | |
| } | |
| }else{ | |
| if( cc == 0 ){ | |
| // scrFillRect(keycanvas, keyLeft - 300 , ch*keyHeight - 8 + keyOffsetY , 200 , keyHeight ,null_5); | |
| if( strlen(ms)){ | |
| // scrDrawText((int)keycanvas, ms , keyLeft - 300 , ch*keyHeight - 8 + keyOffsetY | |
| // , 200 , 60 ,/*0x2404*/ 0 ); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| if( sumup ){ | |
| int max=0; | |
| int min=255; | |
| int mmap[12]={0}; | |
| for(int n=0;n<12;n++){ | |
| if( max < summap[n] ) max = summap[n]; | |
| if( min > summap[n] ) min = summap[n]; | |
| } | |
| for(int n=0;n<12;n++){ | |
| int xoct = 1; | |
| int xmod = ( n + play_status.transpose + 12 - config.capo ) % 12 ; | |
| int xpos; | |
| int xblack; | |
| GetKeyPos(xmod,&xpos,&xblack); | |
| int xl = exKeyLeft + xpos * (whiteWidth/2*2) + 7 *2* whiteWidth + 2; | |
| int yt = 300 + 40 + ( - xblack * 20 ) + keyOffsetY; | |
| if( summap[n] > 0 ){ | |
| if( max == min ){ | |
| scrFillRect(keycanvas, xl, yt, 10 , 16 , red_5 ); | |
| }else{ | |
| int height = 16 - ( max -summap[n] ) * 2; | |
| int width = 10 - (max - summap[n] ) * 2; | |
| scrFillRect(keycanvas, xl+(10-width)/2, yt+(16-height)/2, width , height , red_5); | |
| } | |
| if(summap[n]>= max/2){ | |
| mmap[n]=1; | |
| } | |
| }else{ | |
| scrFillRect(keycanvas, xl, yt, 10 , 16 ,xblack ? black_5 : white_5); | |
| } | |
| } | |
| if( root == -1 && (lastbassoff + 2000 < clk )){ | |
| if( subroot != 256 ){ | |
| //printf(" ==== root lost draw subroot %d ====\n",subroot); | |
| scrFillRect(keycanvas, exKeyLeft , 300 + 3*keyHeight - 8 + keyOffsetY , 200 , 48 *2 ,null_5); | |
| //scrSelectFont(keycanvas,font); | |
| scrDrawText((int)keycanvas, pn[subroot%12], exKeyLeft , 300 + 4*keyHeight - 8 + keyOffsetY | |
| , 200 , 60 ,/*0x2404*/ 0 ); | |
| //scrSelectFont(keycanvas,0); | |
| } | |
| } | |
| int chordRoot=0; | |
| printf("try summap chord analysis - "); | |
| int chordIndex = getChord(mmap,root,0,&chordRoot) ; | |
| char p[128]={0}; | |
| if( chordIndex >= 0 ){ | |
| sprintf(p,"%s%s",pns[(chordRoot+play_status.transpose - config.capo+12)%12],chords[chordIndex].chord_name); | |
| printf("root=%d index=%d chord : %s\n ",chordRoot,chordIndex,p); | |
| }else{ | |
| printf("no chord\n"); | |
| } | |
| if( strlen(p) ){ | |
| if( lastChord == (chordRoot << 16 + chordIndex ) ){ | |
| int countup=0; | |
| for(int n=0;n<play_status.codeCount;n++){ | |
| if( strcmp( play_status.codes[n].name,p )==0){ | |
| play_status.codes[n].count++; | |
| printf("Chord %s makes count %d\n",p,play_status.codes[n].count); | |
| countup=1; | |
| break; | |
| } | |
| } | |
| if(! countup ){ | |
| strcpy(play_status.codes[play_status.codeCount].name,p); | |
| play_status.codes[play_status.codeCount].count = 0; | |
| printf("first Chord %s\n",p); | |
| scrFillRect(keycanvas, 0, 800 , 1920 , 144 ,blue_5); | |
| play_status.codeCount++; | |
| } | |
| qsort(play_status.codes, play_status.codeCount, sizeof(codeData), compareByNameSort); | |
| } | |
| scrFillRect(keycanvas, exKeyLeft , 300 + keyOffsetY - 48 , 200 , 48 ,null_5); | |
| //scrSelectFont(keycanvas,font); | |
| scrDrawText((int)keycanvas, p, exKeyLeft ,300 + keyOffsetY - 48 , 200,60,0); | |
| for(int n=0;n<play_status.codeCount;n++){ | |
| scrDrawText((int)keycanvas, play_status.codes[n].name , (n%10)*160 , 800 + (n / 10 )*36, 200 , 60 ,/*0x2404*/ 0 ); | |
| } | |
| lastChord == (chordRoot << 16 + chordIndex ); | |
| chordMap[chordRoot] = chordMap[chordRoot] | ( 1 << chordIndex ); | |
| if(0){ | |
| for(int x=0;x<16;x++){ | |
| // M | |
| // m | |
| // ... | |
| scrDrawText((int)keycanvas, chords[x].chord_name , keyLeft - 100- 480 -100 -40 , 400 + (x + 1) * 36 -100 , 300 , 60 ,/*0x2404*/ 0 ); | |
| } | |
| for(int n=0;n<12;n++){ | |
| /// C C# D D# ... | |
| scrDrawText((int)keycanvas, pn[(n+play_status.transpose - config.capo+12)%12] , keyLeft -100 - 400 -100 + n * 36, 400 -100, 200 , 60 ,/*0x2404*/ 0 ); | |
| for(int x=0;x<16;x++) { | |
| if( chordMap[n] & ( 1 << x ) ){ | |
| scrDrawText((int)keycanvas, "*" , keyLeft - 400 -100 -100+ (n * 36 ) , 400 + (x + 1) * 36 -100 , 300 , 60 ,/*0x2404*/ 0 ); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| sumup=0; | |
| } | |
| }else{ | |
| // clk < 0 | |
| } | |
| } | |
| //scrFlush(mywnd,0); | |
| } | |
| drawbreak=0; | |
| screenRunning= 0; | |
| pthread_exit(0); | |
| } | |
| void psqDisplayChannelVolume(int param_1); | |
| int * (*ppsqOpen)(int param_1,int param_2,undefined4 *param_3,int *param_4); | |
| int * psqOpen(int param_1,int param_2,undefined4 *param_3,int *param_4){ | |
| ppsqOpen=dlsym(RTLD_NEXT,"psqOpen"); | |
| int ret = (int)ppsqOpen(param_1,param_2,param_3,param_4); | |
| psqhandle=ret; | |
| printf("------------ psqOpened handle=%p -----------\n",(int*)psqhandle); | |
| return (int*)ret; | |
| } | |
| // MIDIメッセージタイプの定義 | |
| #define NOTE_OFF 0x80 | |
| #define NOTE_ON 0x90 | |
| #define POLY_AFTERTOUCH 0xA0 | |
| #define CONTROL_CHANGE 0xB0 | |
| #define PROGRAM_CHANGE 0xC0 | |
| #define CHANNEL_AFTERTOUCH 0xD0 | |
| #define PITCH_BEND 0xE0 | |
| #define SYSTEM_MESSAGE 0xF0 | |
| // システムメッセージの定義 | |
| #define SYSEX_START 0xF0 | |
| #define SYSEX_END 0xF7 | |
| #define META_EVENT 0xFF | |
| // MIDIメッセージを解析し、内容を表示する関数 | |
| void parse_midi_message(const uint8_t *message, size_t length,int port) { | |
| size_t i = 0; | |
| while (i < length) { | |
| uint8_t status = message[i]; // ステータスバイトの取得 | |
| i++; | |
| if ((status & 0xF0) != SYSTEM_MESSAGE) { | |
| // チャネルメッセージの解析 | |
| uint8_t type = status & 0xF0; | |
| uint8_t channel = status & 0x0F; | |
| switch (type) { | |
| case NOTE_OFF: { | |
| if (i + 1 < length) { | |
| uint8_t note = message[i++]; | |
| uint8_t velocity = message[i++]; | |
| /* | |
| printf("Note Off - Channel: %d, Note: %d, Velocity: %d\n", | |
| channel, note, velocity);*/ | |
| } | |
| break; | |
| } | |
| case NOTE_ON: { | |
| if (i + 1 < length) { | |
| uint8_t note = message[i++]; | |
| uint8_t velocity = message[i++]; | |
| /* | |
| printf("Note On - Channel: %d, Note: %d, Velocity: %d\n", | |
| channel, note, velocity);*/ | |
| } | |
| break; | |
| } | |
| case POLY_AFTERTOUCH: { | |
| if (i + 1 < length) { | |
| uint8_t note = message[i++]; | |
| uint8_t pressure = message[i++]; | |
| printf("Polyphonic Aftertouch - Channel: %d, Note: %d, Pressure: %d\n", | |
| channel, note, pressure); | |
| } | |
| break; | |
| } | |
| case CONTROL_CHANGE: { | |
| if (i + 1 < length) { | |
| uint8_t controller = message[i++]; | |
| uint8_t value = message[i++]; | |
| printf("Control Change - Channel: %d, Controller: %d, Value: %d\n", | |
| channel, controller, value); | |
| if( controller == 7 ){ | |
| //play_status.ncount_ch[channel+port*16].volume=value; | |
| } | |
| } | |
| break; | |
| } | |
| case PROGRAM_CHANGE: { | |
| if (i < length) { | |
| uint8_t program = message[i++]; | |
| printf("Program Change - Channel: %d, Program: %d\n", | |
| channel, program); | |
| } | |
| break; | |
| } | |
| case CHANNEL_AFTERTOUCH: { | |
| if (i < length) { | |
| uint8_t pressure = message[i++]; | |
| printf("Channel Aftertouch - Channel: %d, Pressure: %d\n", | |
| channel, pressure); | |
| } | |
| break; | |
| } | |
| case PITCH_BEND: { | |
| if (i + 1 < length) { | |
| uint8_t lsb = message[i++]; | |
| uint8_t msb = message[i++]; | |
| int bend = ((msb << 7) | lsb) - 8192; // 中心値を0とする | |
| /* | |
| printf("Pitch Bend - Channel: %d, Value: %d\n", | |
| channel, bend);*/ | |
| } | |
| break; | |
| } | |
| default: | |
| printf("Unknown Channel Message: 0x%X\n", status); | |
| break; | |
| } | |
| } else { | |
| // システムメッセージの解析 | |
| switch (status) { | |
| case SYSEX_START: { | |
| printf("SysEx Start: "); | |
| while (i < length && message[i] != SYSEX_END) { | |
| printf("0x%X ", message[i++]); | |
| } | |
| if (i < length && message[i] == SYSEX_END) { | |
| printf("SysEx End\n"); | |
| i++; | |
| } else { | |
| printf("SysEx Incomplete\n"); | |
| } | |
| break; | |
| } | |
| case META_EVENT: { | |
| if (i < length) { | |
| uint8_t meta_type = message[i++]; | |
| uint8_t meta_length = message[i++]; | |
| printf("Meta Event - Type: 0x%X, Length: %d, Data: ", | |
| meta_type, meta_length); | |
| for (int j = 0; j < meta_length && i < length; j++) { | |
| printf("0x%X ", message[i++]); | |
| } | |
| printf("\n"); | |
| } | |
| break; | |
| } | |
| default: | |
| printf("System Message: 0x%X\n", status); | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| undefined4 (*ppsqMidiSendDelayedData)(int param_1,int param_2,int param_3,int param_4,int param_5,int param_6); | |
| int notecount=0; | |
| int midiPtrList[8] = {0}; | |
| int lastClick = 0; | |
| undefined4 psqMidiSendDelayedData(int param_1,int param_2,int param_3,int param_4,int param_5,int param_6){ | |
| if(ppsqMidiSendDelayedData==NULL){ | |
| ppsqMidiSendDelayedData=dlsym(RTLD_NEXT, "psqMidiSendDelayedData"); | |
| } | |
| char *buf=(char *)param_4; | |
| #if 0 | |
| int listAdd=1; | |
| for(int n=0;n<8;n++){ | |
| if( midiPtrList[n] == param_1 ){ | |
| listAdd=0; | |
| break; | |
| } | |
| } | |
| if( listAdd == 1 ){ | |
| for(int n=0;n<8;n++){ | |
| printf("[%d]:%x,",n,midiPtrList[n]); | |
| if( midiPtrList[n] == 0 ){ | |
| midiPtrList[n] = param_1; | |
| printf("--------new midiPtr=%x--------\n",param_1); | |
| printf("\n"); | |
| break; | |
| } | |
| } | |
| } | |
| #endif | |
| /* | |
| printf("[%d]@%d ",notecount,param_6); | |
| for(int n=0;n<param_5;n++){ | |
| printf("%02X ",buf[n]&0xff); | |
| } | |
| printf("\n"); */ | |
| //parse_midi_message(param_4,param_5,param_2); | |
| ppsqMidiSendDelayedData(param_1,param_2,param_3,param_4,param_5,param_6); | |
| #if 0 | |
| if( play_status.beats[play_status.click_beats].tick <= param_6 ){ | |
| printf("psqMidiSendDelayedData(param_1=%x,param_2=%x,param_3=%x,param_4=%x,param_5=%x,param_6=time=%d)\n", | |
| param_1,param_2,param_3,param_4,param_5,param_6); | |
| printf("beat=%d time=%d on %d make click\n",play_status.click_beats,param_6,play_status.beats[play_status.click_beats].tick); | |
| /// psqMidiSendDelayedData(param_1=2b7c4870,param_2=2,param_3=f,param_4=2b7c51f0,param_5=3,param_6=time=37072) | |
| if( ((play_status.beats[play_status.click_beats].flag)&0xff) == 0xf1 ){ | |
| char data[3]={0x95,64,100}; | |
| ppsqMidiSendDelayedData(param_1,2,0xf,data,3,play_status.beats[play_status.click_beats].tick); | |
| // ppsqMidiSendDelayedData(param_1,2,0xf,data,3,play_status.beats[play_status.click_beats].tick+200); | |
| }else{ | |
| char data[3]={0x95,68,100}; | |
| ppsqMidiSendDelayedData(param_1,2,0xf,data,3,play_status.beats[play_status.click_beats].tick); | |
| } | |
| play_status.click_beats++; | |
| } | |
| if (play_status.click_beats > 0){ | |
| if( play_status.beats[play_status.click_beats-1].tick <= (param_6 - 200) ){ | |
| printf("psqMidiSendDelayedData(param_1=%x,param_2=%x,param_3=%x,param_4=%x,param_5=%x,param_6=time=%d)\n", | |
| param_1,param_2,param_3,param_4,param_5,param_6); | |
| printf("beat=%d time=%d on %d make click off\n",play_status.click_beats-1,param_6,play_status.beats[play_status.click_beats-1].tick); | |
| if( ((play_status.beats[play_status.click_beats-1].flag)&0xff) == 0xf1 ){ | |
| char data[3]={0x95,64,0}; | |
| ppsqMidiSendDelayedData(param_1,2,0xf,data,3,play_status.beats[play_status.click_beats-1].tick + 200); | |
| }else{ | |
| char data[3]={0x95,68,0}; | |
| ppsqMidiSendDelayedData(param_1,2,0xf,data,3,play_status.beats[play_status.click_beats-1].tick + 200 ); | |
| } | |
| } | |
| } | |
| #endif | |
| // if( /*param_2== 0x04*/ ){ | |
| const char* pn[12] = {"C","C#","D","D#","E","F","F#","G","G#","A","A#","B" }; | |
| int t; | |
| // if( ((*(char*)(param_4))&0xf0) != 0x90 && ((*(char*)(param_4))&0xf0) != 0x80){ | |
| int n; | |
| // if( (((*(char*)(param_4))&0xf0) != 0x90 && ((*(char*)(param_4))&0xf0) != 0x80) || param_6 < 30000 ){ | |
| for(t=0;t<param_2;t++){ | |
| // printf("\t"); | |
| } | |
| // printf("@%d DL(param2=%02x,param3=%02x):",param_6,param_2,param_3); | |
| for(n=0;n<param_5;n++){ | |
| // printf("%02x ",(*(char*)(param_4+n))&0xff); | |
| } | |
| // } | |
| noteevent note; | |
| if( play_status.midimode == 0) { | |
| int portmap[6] = {-1,-1,0,2,1,3}; | |
| note.channel=((*(char*)(param_4))&0xf) + portmap[param_2] * 16; | |
| }else{ | |
| int portmap[6] = {-1,-1,0,1,2,3}; | |
| note.channel=((*(char*)(param_4))&0xf) + portmap[param_2] * 16; | |
| } | |
| if( ((*(char*)(param_4))&0xf0) == 0x90 || ((*(char*)(param_4))&0xf0) == 0x80 ){ | |
| if( play_status.offset == 0 ){ | |
| play_status.offset = param_6 - 2000; | |
| printf("firstNote = %d\n",play_status.offset); | |
| } | |
| note.tick=param_6; | |
| if( ((*(char*)(param_4))&0xf0) == 0x90 ){ | |
| int pitch = (*(char*)(param_4+1))&0xff; | |
| int vel = (*(char*)(param_4+2))&0xff; | |
| note.pitch=pitch; | |
| if( vel != 0 ){ | |
| note.onoff=1; | |
| if( param_6 < 100000 ){ | |
| //printf("port %d ON(90h)@%d Pitch=%d [%s] ch=%d offset=\n",param_2,param_6,pitch,pn[pitch%12],note.channel,play_status.offset); | |
| } | |
| }else{ | |
| note.onoff=0; | |
| if( param_6 < 100000 ){ | |
| // printf("port %d OFF(90h)@%d Pitch=%d [%s] ch=%d\n",param_2,param_6,pitch,pn[pitch%12],note.channel); | |
| } | |
| } | |
| notecount++; | |
| }else{ | |
| int pitch = (*(char*)(param_4+1))&0xff; | |
| note.onoff=0; | |
| note.pitch=pitch; | |
| if( param_6 < 100000 ){ | |
| // printf("port %d OFF(80h)@%d Pitch=%d [%s] ch=%d\n",param_2,param_6,pitch,pn[pitch%12],note.channel); | |
| } | |
| notecount++; | |
| } | |
| fifo_push(¬es,note); | |
| int orgch = note.channel; | |
| int remapCh = 0; | |
| if( orgch < 0 ){ | |
| }else { | |
| remapCh = play_status.ncount_ch[orgch].remapPart; | |
| } | |
| if( remapCh == 3 ){ | |
| if( (play_status.ncount_ch[orgch].program == 87 && note.pitch < 60 )|| play_status.ncount_ch[orgch].program != 87 ){ | |
| fifo_push(&bass,note); | |
| //printf("port %d ON(90h)@%d Pitch=%d [%s] ch=%d remap=%d\n",param_2,param_6,note.pitch,pn[note.pitch%12],note.channel,remapCh); | |
| } | |
| } | |
| if( remapCh == 0 ){ | |
| printf("port %d Note[%s] @%d Pitch=%d [%s] ch=%d ",param_2,note.onoff?"ON":"OFF",param_6,note.pitch,pn[note.pitch%12],note.channel); | |
| for(int x=0;x< /*play_status.vgmnotecount*/ 200 ;x++){ | |
| // printf("xpos[%d]=%d \n",x,play_status.notepos[x].x); | |
| if( play_status.notepos[x].tick + play_status.offset == param_6 ){ | |
| printf("XPos=%d",play_status.notepos[x].x); | |
| break; | |
| } | |
| } | |
| printf("\n"); | |
| if( note.onoff ){ | |
| fifo_push(&vgmelo,note); | |
| } | |
| } | |
| }else{ | |
| char *p=(char*)(param_4); | |
| /* | |
| if( ( p[0] & 0xf0) == 0xb0 ){ | |
| printf("delayed send volume change to %d,%p,%d,%p,%d,%d : ",param_1,param_2,param_3,param_4,param_5,param_6); | |
| for(int n=0;n<param_5;n++){ | |
| printf("%02x ",(*(char*)(param_4+n))&0xff); | |
| } | |
| printf("\n"); | |
| } | |
| */ | |
| // printf("port %d ev %02x @ %d\n",param_2,*(char*)(param_4)&0xff,param_6); | |
| if( ( p[0] & 0xf0) == 0xc0 ){ | |
| printf("program change %d ev %02x val %02x(%s) @ %d\n",param_2,p[0]&0xff,p[1]&0xff,gm_instruments[p[1]&0xff].name ,param_6); | |
| if( param_2 == 2 || param_2 == 3){ | |
| int ch = ((param_2 -2) * 32 )+ (p[0] & 0x0f); | |
| play_status.ncount_ch[ ch ].program=p[1]&0xff; | |
| char prg=play_status.ncount_ch[ch].program; | |
| char mode=play_status.ncount_ch[ch].partmode; | |
| if( mode == 0 ){ | |
| if( play_status.guideFlag[ch] ){ | |
| play_status.ncount_ch[ch].remapPart = 0; | |
| }else{ | |
| play_status.ncount_ch[ch].remapPart = 8; | |
| // if(isKB(prg)) play_status.ncount_ch[ch].remapPart = 0; | |
| if(isBell(prg)) play_status.ncount_ch[ch].remapPart = 1; | |
| if(isKB(prg)) play_status.ncount_ch[ch].remapPart = 2; | |
| if(isBass(prg)) play_status.ncount_ch[ch].remapPart = 3; | |
| if(isGuiter(prg)) play_status.ncount_ch[ch].remapPart = 4; | |
| if(isStrings(prg)) play_status.ncount_ch[ch].remapPart = 5; | |
| if(isBrass(prg)) play_status.ncount_ch[ch].remapPart = 6; | |
| if(isSynth(prg)) play_status.ncount_ch[ch].remapPart = 7; | |
| } | |
| }else{ | |
| play_status.ncount_ch[ch].remapPart = 9; | |
| } | |
| printf("part[%d] mode=%d Program Number:%d Name=%s remap:%d\n",ch,mode,prg,gm_instruments[prg].name,play_status.ncount_ch[ch].remapPart); | |
| } | |
| } | |
| if( ( p[0] & 0xf0) == 0xb0 ){ | |
| //printf("control change %d ev %02x val %02x @ %d\n",param_2,p[0]&0xff,p[1]&0xff ,param_6); | |
| if( param_2 == 2 || param_2 == 3){ | |
| if( (p[1] & 0xff) == 0x07 ){ | |
| int ch = ((param_2 -2) * 32 )+ (p[0] & 0x0f); | |
| play_status.ncount_ch[ ch ].volume=p[2]&0xff; | |
| printf("Volume:%d\n",play_status.ncount_ch[ ch ].volume); | |
| } | |
| } | |
| } | |
| } | |
| //printf("tick=%d notecount=%d read=%d write=%d\n",param_6,notecount,noteevent_read,noteevent_write); | |
| // int targetSolo = ( pw->tick / 1000 ) % 32; | |
| //if( noteevent_write == noteevent_read ){ | |
| // printf("-------message overrun!!!---------\n"); | |
| // printf("notecount=%d\n",notecount); | |
| //} | |
| // if( pw->channel==0 || pw->channel==10 || pw->channel== 5 + 16){ *(char*)(param_4+2) = 1 ;} | |
| // } | |
| // printf("\n"); | |
| // } | |
| return 0; | |
| } | |
| byte * (*ppsqPutExclusiveMessage)(undefined4 *param_1,char *param_2,int param_3,int param_4); | |
| byte * psqPutExclusiveMessage(undefined4 *param_1,char *param_2,int param_3,int param_4){ | |
| if(ppsqPutExclusiveMessage==NULL){ | |
| ppsqPutExclusiveMessage=dlsym(RTLD_NEXT, "psqPutExclusiveMessage"); | |
| } | |
| //printf("psqPutExclusiveMessage(%p,%p,%d,%d)\n\t",param_1,param_2,param_3,param_4); | |
| char *p=param_2; | |
| int sysexcount = 0; | |
| while(1){ | |
| // printf("%02X ",(*p)&0xff); | |
| // fflush(stdout); | |
| // fflush(stderr); | |
| if( (*p & 0xff) == 0xf7 ){ | |
| break; | |
| } | |
| sysexcount++; | |
| p++; | |
| } | |
| undefined4 *puVar16 = (undefined4 *)*param_1; | |
| /// fflush(stdout); | |
| //fflush(stderr); | |
| int *p1 = (int*)*param_1; | |
| /* | |
| if(( sysexbuf[3] & 0xff) == 0x51){ | |
| deviceId = *param_1; | |
| }*/ | |
| int deviceId=play_status.tracknum; | |
| if( play_status.tracknum == 3 ){ | |
| deviceId = 1; | |
| play_status.midimode=1; | |
| } | |
| // printf("deviceId=%d\n",deviceId); | |
| // printf("%08x,%08x,%08x,%08x,%08x",p1[0],p1[1],p1[2],p1[3],p1[4]); | |
| // printf("\n"); | |
| char *sysexbuf = param_2; | |
| if( ( sysexbuf[3] & 0xff) == 0x31 || ( sysexbuf[3] & 0xff) == 0x51 ){ | |
| // int deviceId = sysexbuf[2] - 0x11; | |
| // int deviceId = *(int*)*param_1; | |
| const int addrtopart[32] = | |
| { 10,1,2,3,4,5,6,7,8,9,11,12,13,14,15 ,16 , | |
| 26,17,18,19,20,21,22,23,24,25,27,28,29,30,31 ,32 | |
| }; | |
| // printf("\nparam data addr = %02x-%02x-%02x\n", sysexbuf[4],sysexbuf[5],sysexbuf[6] ); | |
| int addrBase = ((sysexbuf[4] & 0xff) << 16) | ((sysexbuf[5] & 0xff) << 8) | (sysexbuf[6] & 0xff); | |
| int a=7; | |
| int offset = 0; | |
| // F0 43 11 31 02 01 00 02 00 F7 | |
| for(;a<sysexcount -1 /*&& ((sysexbuf[a]&0xff) != 0xf7 )*/ ;a++){ | |
| int voiceData = ( addrBase + offset ) & 0xff00ff; | |
| switch( voiceData ){ | |
| case 0x040000: | |
| printf("VOICE EFFECT NUMBER : 0x%x\n",sysexbuf[a] & 0xff); | |
| break; | |
| case 0x040001: | |
| printf("VOICE MODE : 0x%x\n",sysexbuf[a] & 0xff); | |
| break; | |
| case 0x040002: | |
| printf("VOICE LEVEL : %d\n",sysexbuf[a] & 0xff); | |
| break; | |
| case 0x040003: | |
| printf("VOICE NAME : %c ",sysexbuf[a] & 0xff); | |
| break; | |
| case 0x040004: | |
| case 0x040005: | |
| case 0x040006: | |
| case 0x040007: | |
| case 0x040008: | |
| case 0x040009: | |
| case 0x04000a: | |
| printf("%c",sysexbuf[a] & 0xff); | |
| break; | |
| } | |
| int addrData = (addrBase + offset) & 0xff00ff; | |
| int chBase = addrtopart[sysexbuf[5] & 0x1f]-1; | |
| //printf("chBase=%d\n",chBase); | |
| switch( addrData ){ | |
| case 0x000004: | |
| printf("Master Volume : %d ch=%d\n",sysexbuf[a] & 0xff,chBase); | |
| break; | |
| case 0x010003: | |
| //printf("Reverve TYPE:%d",sysexbuf[a] & 0xff); | |
| break; | |
| case 0x020000: | |
| //printf("Element Reserve:%d",sysexbuf[a] & 0xff); | |
| break; | |
| case 0x020024: | |
| //printf("Chorus send:%d",sysexbuf[a] & 0xff); | |
| break; | |
| case 0x020025: | |
| //printf("Reverb send:%d",sysexbuf[a] & 0xff); | |
| break; | |
| case 0x020041: | |
| //printf("Bend Pitch:%d",sysexbuf[a] & 0xff); | |
| break; | |
| case 0x020001: | |
| printf("part[%d] Bank Select MSB:%d\n",chBase,sysexbuf[a] & 0xff); | |
| break; | |
| case 0x020002: | |
| printf("part[%d] Bank Select LSB:%d\n",chBase,sysexbuf[a] & 0xff); | |
| break; | |
| case 0x020003: | |
| printf("part[%d] chidx=%d Program Number:%d Name=%s\n",chBase,chBase+deviceId*32,sysexbuf[a] & 0xff,gm_instruments[sysexbuf[a] & 0xff].name); | |
| play_status.ncount_ch[chBase+deviceId*32].volume=100; | |
| play_status.ncount_ch[chBase+deviceId*32].program=sysexbuf[a] & 0xff; | |
| break; | |
| case 0x020017: | |
| //printf("Part Mode:%d\n",sysexbuf[a] & 0xff); | |
| play_status.ncount_ch[chBase+deviceId*32].partmode=sysexbuf[a] & 0xff; | |
| case 0x02001b: | |
| //printf("Volume:%d\n",sysexbuf[a] & 0xff); | |
| play_status.ncount_ch[chBase+deviceId*32].volume=sysexbuf[a] & 0xff; | |
| break; | |
| default: | |
| //printf("param data addr = %08x [%02x]\n",addrBase + offset, sysexbuf[a] & 0xff); | |
| ; | |
| } | |
| if(sysexbuf[2]==0x11 || sysexbuf[2] == 0x12 ){ | |
| int port = sysexbuf[2] - 0x11; | |
| int off = addrBase+offset; | |
| // printf("save param for [%x] : %d @ %x\n",sysexbuf[2],port,off); | |
| *(play_status.tgParam[ port ] + (off)) = sysexbuf[a]; | |
| }else{ | |
| // printf("skip sysexbuf[2]==%x\n",sysexbuf[2]); | |
| } | |
| offset++; | |
| } | |
| } | |
| return ppsqPutExclusiveMessage(param_1,param_2,param_3,param_4); | |
| } | |
| void (*ppsqMidiSendImmediateData)(undefined4 param_1,int param_2,undefined4 param_3,int param_4); | |
| void psqMidiSendImmediateData(undefined4 param_1,int param_2,undefined4 param_3,int param_4){ | |
| // printf("IM\n"); | |
| if(ppsqMidiSendImmediateData==NULL){ | |
| ppsqMidiSendImmediateData=dlsym(RTLD_NEXT, "psqMidiSendImmediateData"); | |
| } | |
| if( ppsqMidiSendImmediateData ){ | |
| /* | |
| if( ( p[0] & 0xf0) == 0xb0 ){ | |
| printf("send volume change to %d,%d : ",param_1,param_2); | |
| for(int n=0;n<param_4;n++){ | |
| printf("%02x ",(*(char*)(param_3+n))&0xff); | |
| } | |
| printf("-----------\n"); | |
| }*/ | |
| #if 0 | |
| printf("sIM(%p,%p,%p,%d)\n",param_1,param_2,param_3,param_4); | |
| //return; | |
| size_t n; | |
| #endif | |
| ppsqMidiSendImmediateData(param_1,param_2,param_3,param_4); | |
| } | |
| } | |
| void (*pokdEnterChunk)(int param_1,int param_2,char *param_3); | |
| void okdEnterChunk(int param_1,int param_2,char *param_3){ | |
| char *p=param_3; | |
| if(memcmp(p,"YKYI",4)==0){ | |
| InitPlayStatus(); | |
| } | |
| pokdEnterChunk=dlsym(RTLD_NEXT,"okdEnterChunk"); | |
| printf("----Enter Chunk [%c%c%c%c] ---- \n",p[0],p[1],p[2],p[3]); | |
| if(memcmp(p,"\xffPR",3)==0){ | |
| printf("PR num %d\n",p[3]); | |
| play_status.tracknum = p[3]; | |
| } | |
| pokdEnterChunk(param_1,param_2,param_3); | |
| } | |
| int osdGetColorSet(int param_1,int param_2,undefined4 *param_3,int param_4,undefined4* param_5); | |
| void GetKeyPos(int xmod,int *xpos,int *xblack){ | |
| int axpos[12] = { 0,1,2,3,4,6,7,8,9,10,11,12}; | |
| int ablack[12] = {0,1,0,1,0,0,1,0,1,0,1,0}; | |
| *xpos= axpos[xmod]; | |
| *xblack = ablack[xmod]; | |
| } | |
| int updateBassRoll(int clk){ | |
| undefined4 black_4[2] = { 4, 0xff010101}; | |
| undefined4 white_4[2] = { 4 ,0xfff0f0f0}; | |
| undefined4 red_4[2] = { 4 ,0xffff0000}; | |
| undefined4 black_5[2] = { 5, 0 }; | |
| undefined4 white_5[2] = { 5, 0 }; | |
| undefined4 red_5[2] = { 5, 0 }; | |
| undefined4 trans[2] = { 5, 0 }; | |
| scrConvertColorFormat(black_4,black_5,0); | |
| scrConvertColorFormat(white_4,white_5,0); | |
| scrConvertColorFormat(red_4,red_5,0); | |
| scrFillRect(keycanvas,0,600,1920,300,white_5); | |
| #if 0 | |
| char buf[128]; | |
| sprintf(buf,"%d",clk); | |
| scrDrawText((int)keycanvas,(int)buf, 0 , 600, 400 , 60 , /*0x2404*/ 0); | |
| sprintf(buf,"%d",clk+480); | |
| scrDrawText(()keycanvas,(int)buf, 300 , 600, 400 , 60 , /*0x2404*/ 0); | |
| sprintf(buf,"%d",clk+960); | |
| scrDrawText((int)keycanvas,(int)buf, 600 , 600, 400 , 60 , /*0x2404*/ 0); | |
| sprintf(buf,"%d",clk+140); | |
| scrDrawText((int)keycanvas,(int)buf, 900 , 600 , 400 , 60 , /*0x2404*/ 0); | |
| #endif | |
| /* | |
| scrFillRect(keycanvas,lastpos,0,200,200,trans); | |
| scrFillRect(keycanvas,lastpos+1,0,200,200,white_5);*/ | |
| lastpos = (lastpos + 1 ) % 1800; | |
| return 0; | |
| } | |
| #if 0 | |
| int updateKeyDraw(int clk){ | |
| int changed[32]={0}; | |
| for(int place = 0 ;place < 32;place ++){ | |
| int ci = place; | |
| for( int p = 0 ; p<128;p++ ){ | |
| int xoct = p /12; | |
| int xmod = p %12; | |
| int xpos; | |
| int xblack; | |
| GetKeyPos(xmod,&xpos,&xblack); | |
| int xl = 100+150+800*(place%2)+(7 * 8 ) * xoct + xpos * 4 +1 ; | |
| int yt = ((place/2)* keyHeight) + 16 + ( - xblack * 10 ) + keyOffsetY; | |
| if( play_status.keyMap[ p + ci * 128 ] == 1 ) { | |
| scrFillRect(keycanvas, xl, yt, 6 , 8 , red_5); | |
| changed[place]=1; | |
| } | |
| if( play_status.keymap_cur[p + ci * 128 ]!= play_status.keymap_last[p + ci * 128 ]){ | |
| if ( play_status.keymap_cur[p + ci * 128 ] > 0 ){ | |
| scrFillRect(keycanvas, xl, yt, 6 , 8 , red_5); | |
| } | |
| if ( play_status.keymap_cur[p + ci * 128 ] < 0 ){ | |
| scrFillRect(keycanvas, xl, yt, 6 , 8 ,xblack ? black_5 : white_5); | |
| } | |
| int *tmp=play_status.keymap_last; | |
| play_status.keymap_last=play_status.keymap_cur; | |
| play_status.keymap_cur=tmp; | |
| } | |
| } | |
| } | |
| return 0; | |
| } | |
| #endif | |
| void dumpColor(undefined4 *color,char *msg){ | |
| printf("%s : %08x\n",msg,*color); | |
| } | |
| int drawKeybase(){ | |
| // return 0; | |
| // colorTest(); | |
| //return 0; | |
| undefined color1[8]; | |
| undefined color2[8]; | |
| osdGetColorSet(0x8001,1,color2,0,color1); | |
| //int font = osdGetFontSet(0x8001,2); | |
| //int plane=scrGetPlane(0); | |
| int *cc = (int *)osdGetClearColor(); | |
| int *cc2 =(int *)osdGetClearColor(); | |
| // int wnd = scrCreateWindow(plane,0,20,100,1900,980); | |
| // scrGetPlaneCanvas(0); | |
| // int canvas = scrGetWindowCanvas(wnd); | |
| // keycanvas= canvas; | |
| // mywnd=wnd; | |
| cc[1]=0xffffffff; | |
| /* | |
| printf("osdcolor1=%08x-%08x\n",*((int*)color1),*( ((int*)color1)+1) ); | |
| printf("osdcolor2=%08x-%08x\n",*((int*)color2),*( ((int*)color2)+1)); | |
| */ | |
| undefined4 black_4[2] = { 4, 0xff010101}; | |
| undefined4 white_4[2] = { 4 ,0xfff0f0f0}; | |
| undefined4 gray_4[2] = { 4 ,0xfff808080}; | |
| undefined4 blue_4[2] = { 4, 0xff0000ff}; | |
| undefined4 red_4[2] = { 4 ,0xffff0000}; | |
| undefined4 green_4[2] = { 4 ,0xff00ff00}; | |
| undefined4 null_4[2] = { 4 ,0x0}; | |
| undefined4 black_5[2] = { 5, 0 }; | |
| undefined4 white_5[2] = { 5, 0 }; | |
| undefined4 gray_5[2] = { 5, 0 }; | |
| undefined4 blue_5[2] = { 5, 0 }; | |
| undefined4 red_5[2] = { 5, 0 }; | |
| undefined4 green_5[2] = { 5, 0 }; | |
| undefined4 null_5[2] = { 5, 0 }; | |
| scrConvertColorFormat(black_4,black_5,0); | |
| scrConvertColorFormat(white_4,white_5,0); | |
| scrConvertColorFormat(gray_4,gray_5,0); | |
| scrConvertColorFormat(blue_4,blue_5,0); | |
| scrConvertColorFormat(red_4,red_5,0); | |
| scrConvertColorFormat(green_4,green_5,0); | |
| scrConvertColorFormat(null_4,null_5,0); | |
| dumpColor(blue_5,"blue_5"); | |
| dumpColor(red_5,"red_5"); | |
| dumpColor(green_5,"green_5"); | |
| dumpColor(null_5,"null_5"); | |
| dumpColor(gray_5,"gray_5"); | |
| scrSetTextColor(keycanvas,white_5,0,black_5); | |
| char *remappart[] = {"Mel","Bel","Key","Bs.","Gt.","Str","Brs","Syn","Oth","Dr."}; | |
| int x,y,p; | |
| int ch=0; | |
| int place=0; | |
| p=0; | |
| char buf[128]; | |
| /// rect { 850 , keyOffsetY = 400 <} | |
| scrFillRect(keycanvas,0 , keyOffsetY - 40 - 120 , 1920 , 24*32+40 - 120 ,null_5); | |
| for(ch=0;ch<10;ch++){ | |
| char prg=play_status.ncount_ch[ch].program; | |
| char mode=play_status.ncount_ch[ch].partmode; | |
| char vol = play_status.ncount_ch[ch].volume; | |
| p= /*place / 16 */ 1; | |
| undefined4 *pc=gray_5; | |
| /* | |
| if( isKB(prg) ){ | |
| pc=blue_5; | |
| } | |
| if( isBass(prg) ){ | |
| pc=red_5; | |
| } | |
| if( isGuiter(prg) ){ | |
| pc=green_5; | |
| }*/ | |
| //scrFillRect(canvas,(int)( 800 * p +100 ), (place%16)*keyHeight - 8 + keyOffsetY , 200 , 60 , pc); | |
| for(x= 0 ;x<8*(7 * 8 + 5 );x+=8){ | |
| scrFillRect(keycanvas,keyLeft + x+1, keyOffsetY + (place%16)*keyHeight+1 , 7 , 23 ,white_5); | |
| } | |
| int step = 0; | |
| for(x= 0;x<8*(7*8 + 5 );x+=8){ | |
| if( step != 2 && step != 6){ | |
| scrFillRect(keycanvas,keyLeft + x+1 + 4 ,keyOffsetY + (place%16)*keyHeight+1 , 6 , 16, black_5); | |
| } | |
| step++; | |
| if( step == 7 ) step = 0; | |
| } | |
| if( bInit ){ | |
| #if 0 | |
| if( mode == 1 ){ | |
| scrDrawText((int)canvas,(int)"Drum", (int)( 800 * p +100 ), (place/2)*keyHeight - 8 + keyOffsetY , 200 , 60 ,/*0x2404*/ 0 ); | |
| }else{ | |
| scrDrawText((int)canvas,(int)gm_instruments[(size_t)prg].short_name, (int)( 800 * p +100 ), (place/2)*keyHeight - 8 + keyOffsetY , 200 , 60 ,/*0x2404*/ 0 ); | |
| } | |
| #endif | |
| if( ch < 9) { | |
| scrDrawText((int)keycanvas,remappart[ch], keyLeft + 500 , (place%16)*keyHeight - 8 + keyOffsetY , 200 , 60 ,/*0x2404*/ 0 ); | |
| } | |
| } | |
| place++; | |
| } | |
| // extra keyboard | |
| for(x= 0 ;x<16*(7 * 2 );x+=16){ | |
| scrFillRect(keycanvas,exKeyLeft + x+1, 300 + keyOffsetY + 1 , 7 * 2 , keyHeight *2 ,white_5); | |
| } | |
| int step = 0; | |
| for(x= 0;x<16*(7*2 );x+=16){ | |
| if( step != 2 && step != 6){ | |
| scrFillRect(keycanvas,exKeyLeft + x + 1 + 8 , 300 + keyOffsetY , 6 * 2 , keyHeight , black_5); | |
| } | |
| step++; | |
| if( step == 7 ) step = 0; | |
| } | |
| char helpline[512]; | |
| *helpline=0; | |
| for(int m=0;m<10;m++){ | |
| if( mi[m].name!=NULL ){ | |
| if( mi[m].mute==0 ) scrSetTextColor(keycanvas,white_5,0,black_5); else scrSetTextColor(keycanvas,black_5,0,white_5); | |
| sprintf(helpline,"%c:%s",mi[m].togglekey,mi[m].name); | |
| scrDrawText((int)keycanvas,helpline, 180 * (m+1), 1000 , 1000 , 60 ,/*0x2404*/ 0 ); | |
| } | |
| } | |
| /* | |
| gray_5[0]= gray_5[0]/2; | |
| gray_5[1]= gray_5[1]/2; | |
| gray_5[2]= gray_5[2]/2; | |
| gray_5[3]= gray_5[3]/2;*/ | |
| // int np[4]={ 100 , 300 , 480 , 270 }; | |
| scrFillRect(keycanvas, 100 , 300 , 480 , 270 ,gray_5); | |
| scrFillRect(keycanvas, 100+10 , 300+10 , 480-20 , 270-20 ,null_5); | |
| //scrFillRect(keycanvas, keyLeft - 100- 480 -100 -40 , 300 , 640 , 640 ,gray_5); | |
| // sprintf(helpline,"Capo = %d",config.capo); | |
| // scrDrawText((int)keycanvas,helpline, 0 , 1000 , 1024 , 60 ,/*0x2404*/ 0 ); | |
| // scrSelectFont(canvas,0); | |
| //scrDestroyFont(font); | |
| // scrShowWindow(wnd,1); | |
| // scrFlush(wnd,0); | |
| // scrFlushCanvas(canvas); | |
| forceRedraw=0; | |
| return 1; | |
| } | |
| // param2 must be 1 | |
| //bool tsaHitokaraModeJudge(undefined4 param_1,undefined4 param_2,undefined4 param_3,undefined4 param_4); | |
| int colorTest(){ | |
| char color1[8]; | |
| char color2[8]; | |
| int plane=scrGetPlane(0); | |
| scrEnablePlane(0,1); | |
| int wnd = scrCreateWindow(plane,0,80,0,1700,1080); | |
| int canvas = scrGetWindowCanvas(wnd); | |
| keycanvas= canvas; | |
| mywnd=wnd; | |
| int r=0,g=0,b=0; | |
| int color[2] = { 4, 0xff000000+ (r << 16) + (g<<8 )+ b}; | |
| int c2[2] = { 5, 0}; | |
| for(int x=0;x<256;x+=4){ | |
| int b = x ; | |
| g=r=0; | |
| color[1] = 0xff000000+ (r << 16) + (g<<8 )+ b; | |
| scrConvertColorFormat(color,c2,0); | |
| printf("--%08x-->%08x\n",color[1],c2[1]); | |
| scrFillRect(canvas,x+512,0,4,256,c2); | |
| } | |
| for(int x=0;x<256;x+=4){ | |
| int g = x; | |
| r=b=0; | |
| color[1] = 0xff000000+ (r << 16) + (g<<8 )+ b; | |
| scrConvertColorFormat(color,c2,0); | |
| printf("--%08x-->%08x\n",color[1],c2[1]); | |
| scrFillRect(canvas,x+256,0,4,256,c2); | |
| } | |
| for(int x=0;x<256;x+=4){ | |
| int r = x ; | |
| g=b=0; | |
| color[1] = 0xff000000+ (r << 16) + (g<<8 )+ b; | |
| scrConvertColorFormat(color,c2,0); | |
| printf("--%08x-->%08x\n",color[1],c2[1]); | |
| scrFillRect(canvas,x,0,4,256,c2); | |
| } | |
| scrShowWindow(wnd,1); | |
| scrShowWindow(wnd,1); | |
| scrShowWindow(wnd,1); | |
| scrFlushCanvas(canvas); | |
| //scrFlush(mywnd,0); | |
| return 0; | |
| } | |
| int (*posdInitPowerOn)(void); | |
| int osdInitPowerOn(void){ | |
| printf("call native osdInitPowerOn()=%p\n",osdInitPowerOn); | |
| posdInitPowerOn=dlsym(RTLD_NEXT,"osdInitPowerOn"); | |
| int ret = posdInitPowerOn(); | |
| return ret; | |
| } | |
| #if 0 | |
| int (*pumsgOut)(int param_1,unsigned int param_2,int param_3,char *param_4,...); | |
| char logtmp[1024]; | |
| char **ymhModStr; | |
| int umsgOut(int param_1,unsigned int param_2,int param_3,char *param_4,...){ | |
| va_list ap; | |
| va_start(ap,param_4); | |
| // vsprintf(logtmp,param_3,ap); | |
| // printf("[%6s](%s,%d)<%d>%s\n",ymhModStr[param_1],param_3,param_4,param_2,logtmp); | |
| // if( pumsgDbgLog ){ | |
| // return pumsgDbgLog(param_1,0,param_3,param_4,logtmp); | |
| // } | |
| vprintf(param_4,ap); | |
| // printf(logtmp); | |
| printf("\n"); | |
| va_end(ap); | |
| // return ret; | |
| return 1; | |
| } | |
| #endif | |
| #if 0 | |
| int (*constructor1)(int app); | |
| int (*constructor2)(int app); | |
| int _ZN16CApologizeMsgAppC1Ev(int app){ | |
| printf("_ZN16CApologizeMsgAppC1Ev\n"); | |
| printf("dlsym prt=%p\n",dlsym); | |
| dlerror(); | |
| constructor1=dlsym(RTLD_NEXT, "_ZN16CApologizeMsgAppC1Ev"); | |
| dlerror(); | |
| printf("func ptr=%p\n",constructor1); | |
| if(constructor1){ | |
| return constructor1(app); | |
| } | |
| return 0; | |
| } | |
| int _ZN16CApologizeMsgAppC2Ev(int app){ | |
| printf("_ZN16CApologizeMsgAppC2Ev\n"); | |
| constructor2=dlsym(RTLD_NEXT, "_ZN16CApologizeMsgAppC2Ev"); | |
| printf("func ptr=%p\n",constructor2); | |
| if(constructor2){ | |
| return constructor2(app); | |
| } | |
| return 0; | |
| } | |
| #endif | |
| int playingPsqHandle=0; | |
| undefined4 (*ppsqStart)(int param_1); | |
| undefined4 (*pmsqOkdGet2CfoClk)(int param_1); | |
| int msqoffset; | |
| undefined4 msqOkdGet2CfoClk(int param_1){ | |
| pmsqOkdGet2CfoClk=dlsym(RTLD_NEXT, "msqOkdGet2CfoClk"); | |
| msqoffset=pmsqOkdGet2CfoClk(param_1); | |
| printf("------- offset=%d\n",msqoffset); | |
| return msqoffset; | |
| } | |
| undefined4 psqStart(int param_1){ | |
| int ret; | |
| int pmsq=param_1+8; | |
| playingPsqHandle=param_1; | |
| ppsqStart=dlsym(RTLD_NEXT, "psqStart"); | |
| printf("\n-------------psqStart!!!!----------------\n"); | |
| ret=ppsqStart(param_1); | |
| struct pstream* ps=(Ppstream*)param_1; | |
| psqDisplayChannelVolume(param_1); | |
| printf("ch guide flag1=%04x\n",ps->chVolumes[0].GUIDE); | |
| printf("ch guide flag2=%04x\n",ps->chVolumes[1].GUIDE); | |
| for(int p=0;p<4;p++){ | |
| for(int n=0;n<16;n++){ | |
| unsigned short g=ps->chVolumes[p].GUIDE; | |
| play_status.guideFlag[n] = (g & (1 << n ))? 1 : 0; | |
| } | |
| } | |
| for(int c=0;c<128;c++){ | |
| if( play_status.guideFlag[c]){ | |
| printf("ch[%d] is guide\n",c); | |
| } | |
| } | |
| #if 0 | |
| FILE *fp = fopen("tgmem.txt","w"); | |
| for(int p=0;p<2;p++){ | |
| for(int n=0;n<0x201000;n++){ | |
| if( play_status.tgParam[p][n]!= 0 ){ | |
| fprintf(fp,"port[%d] 0x%08X : %02x \n",p,n,play_status.tgParam[p][n]); | |
| } | |
| } | |
| } | |
| fclose(fp); | |
| #endif | |
| FILE *fp=fopen("program.txt","w"); | |
| for(int ch=0;ch<128;ch++){ | |
| char prg=play_status.ncount_ch[ch].program; | |
| char mode=play_status.ncount_ch[ch].partmode; | |
| if( mode == 0 ){ | |
| // char *remappart[] = {"Melody","Bell","Keyboard","Bass","Guitar","Strings","Brass","Synth","Other","Drums"}; | |
| if( play_status.guideFlag[ch] ){ | |
| play_status.ncount_ch[ch].remapPart = 0; | |
| }else{ | |
| play_status.ncount_ch[ch].remapPart = 8; | |
| // if(isKB(prg)) play_status.ncount_ch[ch].remapPart = 0; | |
| if(isBell(prg)) play_status.ncount_ch[ch].remapPart = 1; | |
| if(isKB(prg)) play_status.ncount_ch[ch].remapPart = 2; | |
| if(isBass(prg)) play_status.ncount_ch[ch].remapPart = 3; | |
| if(isGuiter(prg)) play_status.ncount_ch[ch].remapPart = 4; | |
| if(isStrings(prg)) play_status.ncount_ch[ch].remapPart = 5; | |
| if(isBrass(prg)) play_status.ncount_ch[ch].remapPart = 6; | |
| if(isSynth(prg)) play_status.ncount_ch[ch].remapPart = 7; | |
| } | |
| }else{ | |
| play_status.ncount_ch[ch].remapPart = 9; | |
| } | |
| fprintf(fp,"part[%d] mode=%d Program Number:%d Name=%s remap:%d\n",ch,mode,prg,gm_instruments[prg].name,play_status.ncount_ch[ch].remapPart); | |
| } | |
| fclose(fp); | |
| drawbreak = 0; | |
| pthread_create(&thread, NULL, screentest, NULL); | |
| return ret; | |
| } | |
| void psqDisplayChannelVolume(int param_1); | |
| undefined4 (*ppsqStop)(int param_1); | |
| undefined4 psqStop(int param_1){ | |
| ppsqStop=dlsym(RTLD_NEXT, "psqStop"); | |
| //pthread_kill(thread,0); | |
| printf("\n-------------psqStop!!!!----------------\n"); | |
| printf("\n killing draw thread\n"); | |
| drawbreak = 1; | |
| while(drawbreak!=0); | |
| printf("\n end\n"); | |
| int ret = ppsqStop(param_1); | |
| InitPlayStatus(); | |
| return ret; | |
| } | |
| byte * (*pmsqCalcDuration)(byte *param_1,uint *param_2); | |
| byte * msqCalcDuration(byte *param_1,uint *param_2){ | |
| pmsqCalcDuration=dlsym(RTLD_NEXT, "msqCalcDuration"); | |
| if( pmsqCalcDuration ){ | |
| byte * ret = pmsqCalcDuration(param_1,param_2); | |
| // printf("ct=%d\n",msqTime); | |
| msqTime += *param_2; | |
| return ret; | |
| } | |
| } | |
| byte * (*pmsqSkipEvent)(char *param_1,undefined *param_2,undefined4 *param_3); | |
| byte * msqSkipEvent(char *param_1,undefined *param_2,undefined4 *param_3){ | |
| int reset = 0; | |
| pmsqSkipEvent=dlsym(RTLD_NEXT, "msqSkipEvent"); | |
| if( pmsqSkipEvent ){ | |
| //printf("@%d msqEvent:%02x,%02x\n",msqTime,param_1[0]&0xff,param_1[1]&0xff); | |
| if ( (param_1[0]&0xff) == 0xf1 && (param_1[1]&0xff) == 0 ){ | |
| reset = 0; | |
| msqLastTime = msqTime; | |
| msqTime = 0; | |
| printf("lastEventTime=%d\n",msqLastTime); | |
| for(int n=0;n<play_status.n_beats;n++) | |
| { | |
| //printf("@%d, %02x\n",play_status.beats[n].tick,play_status.beats[n].flag); | |
| } | |
| } | |
| if( msqLastTime == 0 ){ | |
| if ( (param_1[0]&0xff) == 0xf1 || (param_1[0]&0xff) == 0xf2 ){ | |
| play_status.beats[play_status.n_beats].tick = msqTime; | |
| play_status.beats[play_status.n_beats].flag = param_1[0]; | |
| play_status.n_beats++; | |
| } | |
| if ( (param_1[0]&0xff) == 0xf6 ){ | |
| printf("@%d Ensou Code 0x%02x\n",msqTime,param_1[1]&0xff); | |
| } | |
| if ( (param_1[0]&0xff) == 0xf3 ){ | |
| printf("@%d Sabi Code 0x%02x\n",msqTime,param_1[1]&0xff); | |
| } | |
| if ( (param_1[0]&0xff) == 0xf5 ){ | |
| printf("@%d 2CoFo Code 0x%02x\n",msqTime,param_1[1]&0xff); | |
| } | |
| if ( (param_1[0]&0xff) == 0xf4 ){ | |
| printf("@%d VGM Code 0x%02x\n",msqTime,param_1[1]&0xff); | |
| switch(param_1[1]&0xff){ | |
| case 0: | |
| printf("VGM Start Init\n"); | |
| play_status.page[n_guidePage].start = msqTime; | |
| break; | |
| case 1: | |
| printf("VGM Start Page\n"); | |
| if(play_status.page[n_guidePage].stop==-1){ | |
| play_status.page[n_guidePage].stop = msqTime; | |
| n_guidePage++; | |
| } | |
| play_status.page[n_guidePage].start = msqTime; | |
| play_status.page[n_guidePage].stop = -1; | |
| break; | |
| case 2: | |
| printf("VGM Last Page\n"); | |
| play_status.page[n_guidePage].stop = msqTime; | |
| n_guidePage++; | |
| for(int n=0;n<n_guidePage;n++){ | |
| printf("page[%d] %d-%d\n",n,play_status.page[n].start,play_status.page[n].stop); | |
| } | |
| break; | |
| case 3: | |
| printf("VGM Hide Page\n"); | |
| play_status.page[n_guidePage].stop = msqTime; | |
| n_guidePage++; | |
| play_status.page[n_guidePage].start = msqTime; | |
| break; | |
| } | |
| } | |
| } | |
| play_status.c_beats=0; | |
| byte *ret = pmsqSkipEvent( param_1 ,param_2 ,param_3); | |
| if ( reset ) msqTime = 0; | |
| return ret; | |
| } | |
| return NULL; | |
| } | |
| #include <errno.h> | |
| #include <fcntl.h> | |
| #include <string.h> | |
| #include <termios.h> | |
| #include <unistd.h> | |
| int | |
| set_interface_attribs (int fd, int speed, int parity) | |
| { | |
| struct termios tty; | |
| if (tcgetattr (fd, &tty) != 0) | |
| { | |
| error_message ("error %d from tcgetattr", errno); | |
| return -1; | |
| } | |
| cfsetospeed (&tty, speed); | |
| cfsetispeed (&tty, speed); | |
| tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars | |
| // disable IGNBRK for mismatched speed tests; otherwise receive break | |
| // as \000 chars | |
| tty.c_iflag &= ~IGNBRK; // disable break processing | |
| tty.c_lflag = 0; // no signaling chars, no echo, | |
| // no canonical processing | |
| //tty.c_oflag = 0; // no remapping, no delays | |
| tty.c_cc[VMIN] = 0; // read doesn't block | |
| tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout | |
| tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl | |
| tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls, | |
| // enable reading | |
| tty.c_cflag &= ~(PARENB | PARODD); // shut off parity | |
| tty.c_cflag |= parity; | |
| tty.c_cflag &= ~CSTOPB; | |
| tty.c_cflag &= ~CRTSCTS; | |
| tty.c_oflag &= ~OPOST; | |
| tty.c_oflag &= ~OPOST; | |
| //tty.c_oflag &= ~OPOST; | |
| if (tcsetattr (fd, TCSANOW, &tty) != 0) | |
| { | |
| error_message ("error %d from tcsetattr", errno); | |
| return -1; | |
| } | |
| return 0; | |
| } | |
| void | |
| set_blocking (int fd, int should_block) | |
| { | |
| struct termios tty; | |
| memset (&tty, 0, sizeof tty); | |
| if (tcgetattr (fd, &tty) != 0) | |
| { | |
| error_message ("error %d from tggetattr", errno); | |
| return; | |
| } | |
| tty.c_cc[VMIN] = should_block ? 1 : 0; | |
| tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout | |
| if (tcsetattr (fd, TCSANOW, &tty) != 0) | |
| error_message ("error %d setting term attributes", errno); | |
| } | |
| pthread_t thCui=NULL; | |
| int partswithmode=0; | |
| int tfd; | |
| int doMute(){ | |
| int mutelist[128]={0}; | |
| //printf("make mutelist"); | |
| for(int m=0;m<10;m++){ | |
| if( mi[m].func ){ | |
| for(int p=0;p<128;p++){ | |
| if( mi[m].func(p) && mi[m].mute){ | |
| mutelist[p]=1; | |
| } | |
| } | |
| } | |
| } | |
| for(int n=0;n<128;n++){ | |
| //printf("%d ",mutelist[n]); | |
| if( (n%32) == 0){ | |
| printf("\n"); | |
| } | |
| } | |
| if( bInit ){ | |
| for(int ch=0;ch<64;ch++){ | |
| char prg=play_status.ncount_ch[ch].program; | |
| char mode=play_status.ncount_ch[ch].partmode; | |
| int volume=play_status.ncount_ch[ch].volume; | |
| char buf[3]={0xb0,0x07,0}; | |
| buf[0]=0xb0 + (ch % 16); | |
| if( (mode == 0 && mutelist[prg]) || (mode == 1 && mi[8].mute ) ){ | |
| printf("mute part[%d] mode=%d Program Number:%d Name=%s volume=%d\n",ch,mode,prg,gm_instruments[prg].name,volume); | |
| }else{ | |
| buf[2]=(char)volume; | |
| printf("unmute part[%d] mode=%d Program Number:%d Name=%s volume=%d\n",ch,mode,prg,gm_instruments[prg].name,volume); | |
| } | |
| if( play_status.midimode == 0 ){ | |
| int portmap[4] = { 2,4,3,5 }; | |
| ppsqMidiSendImmediateData(0, portmap[ch/16] ,buf,3); | |
| }else{ | |
| int portmap[4] = { 2,3,4,5 }; | |
| ppsqMidiSendImmediateData(0, portmap[ch/16] ,buf,3); | |
| } | |
| } | |
| } | |
| return 0; | |
| } | |
| int partswitch(){ | |
| char c; | |
| int changed=0; | |
| printf("partswitch mode .\n"); | |
| while(1){ | |
| int n = read (tfd, &c, 1); | |
| if( n ==1 ){ | |
| printf("%c",c); | |
| if( c == 'q' ){ | |
| printf("exit partswitch"); | |
| return 0; | |
| } | |
| if( c== 'u') { | |
| if( config.capo < 12 ) config.capo ++; | |
| printf("capo=%d\n",config.capo); | |
| save_config(play_status.songnum >> 8 ,play_status.songnum &0xff,&config); | |
| } | |
| if( c== 'd') { | |
| if( config.capo > -12 ) config.capo--; | |
| printf("capo=%d\n",config.capo); | |
| save_config(play_status.songnum >> 8 ,play_status.songnum &0xff,&config); | |
| } | |
| for(int m=0;m<10 && mi[m].togglekey!=0 ;m++){ | |
| if( mi[m].togglekey == c ){ | |
| if( mi[m].mute ){ | |
| mi[m].mute=0; | |
| }else{ | |
| mi[m].mute=1; | |
| } | |
| changed = 1; | |
| } | |
| if( mi[m].name ){ | |
| printf("muteinfo %s flag=%d\n",mi[m].name,mi[m].mute); | |
| } | |
| config.mute_flags[m] = mi[m].mute; | |
| } | |
| if( changed ){ | |
| doMute(); | |
| save_config(play_status.songnum >> 8 ,play_status.songnum &0xff,&config); | |
| changed = 0; | |
| } | |
| forceRedraw=1; | |
| vgmredraw = 1; | |
| } | |
| } | |
| } | |
| void cmd(char *p){ | |
| if( strstr(p,"bulkdump")!=NULL){ | |
| } | |
| if( strstr(p,"partswitch")!=NULL){ | |
| partswitch(); | |
| return; | |
| } | |
| if( strstr(p,"redraw")!=NULL ){ | |
| forceRedraw=1; | |
| } | |
| if( strstr(p,"help")!=NULL){ | |
| printf("Help :\n"); | |
| printf("mute n : mute ch n \n"); | |
| printf("mode <drum|chord|melody> \n"); | |
| printf("stat : status song\n"); | |
| } | |
| if( strstr(p,"stat")!=NULL ){ | |
| psqDisplayChannelVolume(playingPsqHandle); | |
| for(int ch=0;ch<32;ch++){ | |
| char prg=play_status.ncount_ch[ch].program; | |
| char mode=play_status.ncount_ch[ch].partmode; | |
| int volume=play_status.ncount_ch[ch].volume; | |
| printf("part[%d] mode=%d Program Number:%d Name=%s volume=%d\n",ch,mode,prg,gm_instruments[prg].name,volume); | |
| } | |
| } | |
| if( strstr(p,"drum")!=NULL ){ | |
| psqDisplayChannelVolume(playingPsqHandle); | |
| for(int ch=0;ch<32;ch++){ | |
| char prg=play_status.ncount_ch[ch].program; | |
| char mode=play_status.ncount_ch[ch].partmode; | |
| int volume=play_status.ncount_ch[ch].volume; | |
| char buf[3]={0xb0,0x07,0}; | |
| buf[0]=0xb0 + (ch % 16); | |
| if( mode == 0 ){ | |
| printf("mute part[%d] mode=%d Program Number:%d Name=%s volume=%d\n",ch,mode,prg,gm_instruments[prg].name,volume); | |
| }else{ | |
| buf[2]=(char)volume; | |
| printf("unmute part[%d] mode=%d Program Number:%d Name=%s volume=%d\n",ch,mode,prg,gm_instruments[prg].name,volume); | |
| } | |
| ppsqMidiSendImmediateData(0,ch/16+2,buf,3); | |
| } | |
| } | |
| if( strstr(p,"db")!=NULL ){ | |
| psqDisplayChannelVolume(playingPsqHandle); | |
| for(int ch=0;ch<32;ch++){ | |
| char prg=play_status.ncount_ch[ch].program; | |
| char mode=play_status.ncount_ch[ch].partmode; | |
| int volume=play_status.ncount_ch[ch].volume; | |
| char buf[3]={0xb0,0x07,0}; | |
| buf[0]=0xb0 + (ch % 16); | |
| if( mode == 0 && !( 32 <= play_status.ncount_ch[ch].program && play_status.ncount_ch[ch].program <= 39)){ | |
| printf("mute part[%d] mode=%d Program Number:%d Name=%s volume=%d\n",ch,mode,prg,gm_instruments[prg].name,volume); | |
| }else{ | |
| buf[2]=(char)volume; | |
| printf("unmute part[%d] mode=%d Program Number:%d Name=%s volume=%d\n",ch,mode,prg,gm_instruments[prg].name,volume); | |
| } | |
| ppsqMidiSendImmediateData(0,ch/16+2,buf,3); | |
| } | |
| } | |
| int chtoport[16] = {9,0,1,2,3,4,5,6,7,8,10,11,12,13,14,15 }; | |
| if( strstr(p,"all")!=NULL ){ | |
| psqDisplayChannelVolume(playingPsqHandle); | |
| for(int ch=0;ch<32;ch++){ | |
| char prg=play_status.ncount_ch[ch].program; | |
| char mode=play_status.ncount_ch[ch].partmode; | |
| int volume=play_status.ncount_ch[ch].volume; | |
| char buf[3]={0xb0,0x07,0}; | |
| buf[0]=0xb0 + (ch % 16); | |
| buf[2]=(char)volume; | |
| printf("restore part[%d] mode=%d Program Number:%d Name=%s volume=%d\n",ch,mode,prg,gm_instruments[prg].name,volume); | |
| ppsqMidiSendImmediateData(0,ch/16+2,buf,3); | |
| } | |
| } | |
| if( strstr(p,"my")!=NULL ){ | |
| psqDisplayChannelVolume(playingPsqHandle); | |
| for(int ch=0;ch<32;ch++){ | |
| char prg=play_status.ncount_ch[ch].program; | |
| char mode=play_status.ncount_ch[ch].partmode; | |
| int volume=play_status.ncount_ch[ch].volume; | |
| char buf[3]={0xb0,0x07,0}; | |
| buf[0]=0xb0 + (ch % 16); | |
| if( mode == 0 && !( 32 <= play_status.ncount_ch[ch].program && play_status.ncount_ch[ch].program <= 39)){ | |
| printf("mute part[%d] mode=%d Program Number:%d Name=%s volume=%d\n",ch,mode,prg,gm_instruments[prg].name,volume); | |
| }else{ | |
| buf[2]=(char)volume; | |
| printf("unmute part[%d] mode=%d Program Number:%d Name=%s volume=%d\n",ch,mode,prg,gm_instruments[prg].name,volume); | |
| } | |
| ppsqMidiSendImmediateData(0,ch/16+2,buf,3); | |
| } | |
| } | |
| } | |
| undefined4 cuiThread(void *p){ | |
| printf("cui Thread replaced for hack\n"); | |
| char *portname = "/dev/ttyS0"; | |
| tfd = open (portname, O_RDWR | O_NOCTTY | O_SYNC); | |
| if (tfd < 0) | |
| { | |
| error_message ("error %d opening %s: %s", errno, portname, strerror (errno)); | |
| return; | |
| } | |
| //set_interface_attribs (fd, B115200, 0); // set speed to 115,200 bps, 8n1 (no parity) | |
| //set_blocking (fd, 0); // set no blocking | |
| // write (fd, "hello!\n", 7); // send 7 character greeting | |
| char linebuf[128]={0}; | |
| int nLine=0; | |
| char buf [100]; | |
| partswitch(); | |
| while(1){ | |
| // usleep ((7 + 25) * 100); // sleep enough to transmit the 7 plus | |
| // receive 25: approx 100 uS per char transmit | |
| int n = read (tfd, buf, sizeof buf); // read up to 100 characters if ready to read | |
| if( n > 0){ | |
| printf("%d",nLine); | |
| for(int x=0;x<n;x++){ | |
| if( buf[x]== '\r') continue; | |
| if( buf[x] == '\n' ){ | |
| printf("cmdline=%s\n",linebuf); | |
| cmd(linebuf); | |
| memset(linebuf,0,128); | |
| nLine=0; | |
| break; | |
| } | |
| write(tfd,buf+x,1); | |
| linebuf[nLine]=buf[x]; | |
| nLine++; | |
| } | |
| }else{ | |
| } | |
| } | |
| } | |
| undefined4 cuiStart(void){ | |
| pthread_create(&thCui,0,cuiThread,0); | |
| return 0; | |
| } | |
| void (*pmsqSendImmidiate)(undefined4 param_1,undefined4 param_2,undefined4 param_3,undefined4 param_4); | |
| void msqSendImmidiate(undefined4 param_1,undefined4 param_2,undefined4 param_3,undefined4 param_4){ | |
| printf("msqSendImmidiate\n"); | |
| pmsqSendImmidiate=dlsym(RTLD_NEXT, "msqSendImmidiate"); | |
| char *p=(char *)*((char **)param_4); | |
| for(int n=0;n<param_2;n++){ | |
| printf(" %02X ",p[n]&0xff); | |
| } | |
| } | |
| #if 0 | |
| int (*pclkSendStream)(uint param_1,undefined4 param_2,undefined4 param_3,int *param_4); | |
| int clkSendStream(uint param_1,undefined4 param_2,undefined4 param_3,int *param_4){ | |
| pclkSendStream=dlsym(RTLD_NEXT, "clkSendStream"); | |
| printf("%02x - %02x - %02x",param_1,param_2,param_3); | |
| } | |
| #endif | |
| int (*pcompressMIDIData)(int param_1,int param_2,undefined *param_3,int *param_4,int *param_5); | |
| #if 0 | |
| int compressMIDIData(int param_1,int param_2,undefined *param_3,int *param_4,int *param_5){ | |
| pcompressMIDIData=dlsym(RTLD_NEXT, "compressMIDIData"); | |
| printf("cmd(%d,%d,%p,%p,%p)\n",param_1,param_2,param_3,param_4,param_5); | |
| return pcompressMIDIData(param_1,param_2,param_3,param_4,param_5); | |
| } | |
| #endif | |
| undefined4 (*ppsqOkdGetPtrackChunk)(int param_1,int param_2); | |
| undefined4 psqOkdGetPtrackChunk(int param_1,int param_2){ | |
| ppsqOkdGetPtrackChunk=dlsym(RTLD_NEXT, "psqOkdGetPtrackChunk"); | |
| printf("psqOkdGetPtrackChunk(%p,%d)\n",param_1,param_2); | |
| play_status.tracknum = param_2; | |
| return ppsqOkdGetPtrackChunk(param_1,param_2); | |
| } | |
| /* | |
| void CVisibleGuideMelody::VgmDrawReference | |
| (_VGM_SONG_DATA *param_1,_VGM_DRAW_ENV *param_2,_VGM_PAGE *param_3,int param_4, | |
| _VGM_CONFIG *param_5) | |
| */ | |
| void (*p_ZN19CVisibleGuideMelody16VgmDrawReferenceEP14_VGM_SONG_DATAP13_VGM_DRAW_ENVP9_VGM_PAGEiP11_VGM_CONFIG)(void *this,void *param_1,void *param_2,void *param_3,int param_4,void *param_5); | |
| _ZN19CVisibleGuideMelody16VgmDrawReferenceEP14_VGM_SONG_DATAP13_VGM_DRAW_ENVP9_VGM_PAGEiP11_VGM_CONFIG(void *this,void *param_1,void *param_2,void *param_3,int param_4,void *param_5){ | |
| printf("CVisibleGuideMelody::VgmDrawReference(%p,%p,%p,%p,%d,%p)\n",this,param_1,param_2,param_3,param_4,param_5); | |
| if (!p_ZN19CVisibleGuideMelody16VgmDrawReferenceEP14_VGM_SONG_DATAP13_VGM_DRAW_ENVP9_VGM_PAGEiP11_VGM_CONFIG ){ | |
| p_ZN19CVisibleGuideMelody16VgmDrawReferenceEP14_VGM_SONG_DATAP13_VGM_DRAW_ENVP9_VGM_PAGEiP11_VGM_CONFIG=dlsym(RTLD_NEXT, "_ZN19CVisibleGuideMelody16VgmDrawReferenceEP14_VGM_SONG_DATAP13_VGM_DRAW_ENVP9_VGM_PAGEiP11_VGM_CONFIG"); | |
| } | |
| p_ZN19CVisibleGuideMelody16VgmDrawReferenceEP14_VGM_SONG_DATAP13_VGM_DRAW_ENVP9_VGM_PAGEiP11_VGM_CONFIG(this,param_1,param_2,param_3,param_4,param_5); | |
| vgmredraw = 1; | |
| } | |
| int drawNoteCount=0; | |
| int vgmnotelastx=0; | |
| int (*p_ZN19CVisibleGuideMelody13CalcNoteDrawXEP9_VGM_PAGElP11_VGM_CONFIG)(void *this,void *param_1,long param_2,void *param_3); | |
| int _ZN19CVisibleGuideMelody13CalcNoteDrawXEP9_VGM_PAGElP11_VGM_CONFIG(void *this,void *param_1,long param_2,void *param_3){ | |
| //printf("CVisibleGuideMelody::CalcNoteDrawX(%p,%p,%d,%p)\n",this,param_1,param_2,param_3); | |
| if(! p_ZN19CVisibleGuideMelody13CalcNoteDrawXEP9_VGM_PAGElP11_VGM_CONFIG ){ | |
| p_ZN19CVisibleGuideMelody13CalcNoteDrawXEP9_VGM_PAGElP11_VGM_CONFIG=dlsym(RTLD_NEXT, "_ZN19CVisibleGuideMelody13CalcNoteDrawXEP9_VGM_PAGElP11_VGM_CONFIG"); | |
| } | |
| int ret= p_ZN19CVisibleGuideMelody13CalcNoteDrawXEP9_VGM_PAGElP11_VGM_CONFIG(this,param_1,param_2,param_3); | |
| // printf("ret=%d\n",ret); | |
| if ( play_status.vgmnotecount < 2000){ | |
| if( vgmnotelastx > ret ){ | |
| if(play_status.vgmnotecount > 0 ){ | |
| play_status.notepos[play_status.vgmnotecount-1].last = 1; | |
| printf("set last flag for last note\n"); | |
| } | |
| } | |
| play_status.notepos[play_status.vgmnotecount].tick =param_2; | |
| play_status.notepos[play_status.vgmnotecount].x = ret; | |
| play_status.notepos[play_status.vgmnotecount].last = 0; | |
| //printf("alloc xpos[%d]=%d for @%d\n",play_status.vgmnotecount,ret,param_2); | |
| vgmnotelastx = ret; | |
| } | |
| return ret; | |
| } | |
| int (*p_ZN19CVisibleGuideMelody13CalcNoteDrawYEP9_VGM_PAGElP11_VGM_CONFIG)(void *this,void *param_1,long param_2,void *param_3); | |
| int _ZN19CVisibleGuideMelody13CalcNoteDrawYEP9_VGM_PAGElP11_VGM_CONFIG(void *this,void *param_1,long param_2,void *param_3){ | |
| //printf("CVisibleGuideMelody::CalcNoteDrawY(%p,%p,%d,%p)\n",this,param_1,param_2,param_3); | |
| if(! p_ZN19CVisibleGuideMelody13CalcNoteDrawYEP9_VGM_PAGElP11_VGM_CONFIG ){ | |
| p_ZN19CVisibleGuideMelody13CalcNoteDrawYEP9_VGM_PAGElP11_VGM_CONFIG=dlsym(RTLD_NEXT, "_ZN19CVisibleGuideMelody13CalcNoteDrawYEP9_VGM_PAGElP11_VGM_CONFIG"); | |
| } | |
| int ret= p_ZN19CVisibleGuideMelody13CalcNoteDrawYEP9_VGM_PAGElP11_VGM_CONFIG(this,param_1,param_2,param_3); | |
| //printf("ret=%d\n",ret); | |
| if ( play_status.vgmnotecount < 2000){ | |
| play_status.notepos[play_status.vgmnotecount].y = ret; | |
| play_status.notepos[play_status.vgmnotecount].pitch = param_2; | |
| //printf("alloc ypos[%d]=%d for @%d\n",play_status.vgmnotecount,ret,param_2); | |
| play_status.vgmnotecount++; | |
| } | |
| return ret; | |
| } | |
| /* | |
| undefined4 __thiscall | |
| CVisibleGuideMelody::VgmDrawStartPage | |
| (CVisibleGuideMelody *this,_VGM_SONG_DATA *param_1,_VGM_DRAW_ENV *param_2, | |
| _VGM_PAGE *param_3,_VGM_CONFIG *param_4) | |
| */ | |
| int (*p_ZN19CVisibleGuideMelody16VgmDrawStartPageEP14_VGM_SONG_DATAP13_VGM_DRAW_ENVP9_VGM_PAGEP11_VGM_CONFIG)(void *this,void *song,void *env,void *page,void *config); | |
| int _ZN19CVisibleGuideMelody16VgmDrawStartPageEP14_VGM_SONG_DATAP13_VGM_DRAW_ENVP9_VGM_PAGEP11_VGM_CONFIG(void *this,void *song,void *env,void *page,void *config){ | |
| printf("CVisibleGuideMelody::VgmDrawStartPage(%p,%p,%p,%p,%p)\n",this,song,env,page,config); | |
| if(! p_ZN19CVisibleGuideMelody16VgmDrawStartPageEP14_VGM_SONG_DATAP13_VGM_DRAW_ENVP9_VGM_PAGEP11_VGM_CONFIG ){ | |
| p_ZN19CVisibleGuideMelody16VgmDrawStartPageEP14_VGM_SONG_DATAP13_VGM_DRAW_ENVP9_VGM_PAGEP11_VGM_CONFIG=dlsym(RTLD_NEXT, "_ZN19CVisibleGuideMelody16VgmDrawStartPageEP14_VGM_SONG_DATAP13_VGM_DRAW_ENVP9_VGM_PAGEP11_VGM_CONFIG"); | |
| } | |
| int ret= p_ZN19CVisibleGuideMelody16VgmDrawStartPageEP14_VGM_SONG_DATAP13_VGM_DRAW_ENVP9_VGM_PAGEP11_VGM_CONFIG(this,song,env,page,config); | |
| printf("ret=%d\n",ret); | |
| return ret; | |
| } | |
| /* | |
| void __thiscall | |
| CVisibleGuideMelody::VgmCreateNoteResource | |
| (CVisibleGuideMelody *this,_VGM_DRAW_RESNOTE *param_1,_VGM_PAGE *param_2,long param_3, | |
| _VGM_CONFIG *param_4,int param_5) | |
| */ | |
| /* | |
| void __thiscall | |
| CVisibleGuideMelody::VgmDrawNewTrack | |
| (CVisibleGuideMelody *this,_VGM_SONG_DATA *param_1,_VGM_DRAW_ENV *param_2, | |
| _VGM_EVAL_NOTE *param_3,_VGM_CONFIG *param_4)*/ | |
| void (*p_ZN19CVisibleGuideMelody15VgmDrawNewTrackEP14_VGM_SONG_DATAP13_VGM_DRAW_ENVP14_VGM_EVAL_NOTEP11_VGM_CONFIG)(void *this,void *param_1,void *param_2,void *param_3,void *param_4); | |
| void _ZN19CVisibleGuideMelody15VgmDrawNewTrackEP14_VGM_SONG_DATAP13_VGM_DRAW_ENVP14_VGM_EVAL_NOTEP11_VGM_CONFIG(void *this,void *param_1,void *param_2,void *param_3,void *param_4){ | |
| printf("CVisibleGuideMelody::VgmDrawNewTrack(%p,%p,%p,%p,%p)\n",this,param_1,param_2,param_3,param_4); | |
| if(! p_ZN19CVisibleGuideMelody15VgmDrawNewTrackEP14_VGM_SONG_DATAP13_VGM_DRAW_ENVP14_VGM_EVAL_NOTEP11_VGM_CONFIG ){ | |
| p_ZN19CVisibleGuideMelody15VgmDrawNewTrackEP14_VGM_SONG_DATAP13_VGM_DRAW_ENVP14_VGM_EVAL_NOTEP11_VGM_CONFIG=dlsym(RTLD_NEXT, "_ZN19CVisibleGuideMelody15VgmDrawNewTrackEP14_VGM_SONG_DATAP13_VGM_DRAW_ENVP14_VGM_EVAL_NOTEP11_VGM_CONFIG"); | |
| } | |
| p_ZN19CVisibleGuideMelody15VgmDrawNewTrackEP14_VGM_SONG_DATAP13_VGM_DRAW_ENVP14_VGM_EVAL_NOTEP11_VGM_CONFIG(this,param_1,param_2,param_3,param_4); | |
| } | |
| int (*pkpseTransposeCtrl)(int param_1,uint param_2); | |
| int kpseTransposeCtrl(int param_1,uint param_2){ | |
| pkpseTransposeCtrl=dlsym(RTLD_NEXT, "kpseTransposeCtrl"); | |
| printf("kpseTransposeCtrl(%d,%d)\n",param_1,param_2); | |
| int ret=pkpseTransposeCtrl(param_1,param_2); | |
| return ret; | |
| } | |
| int (*pspnxMidiSend)(int param_1,void *param_2,size_t param_3); | |
| /* | |
| [0]=f0 | |
| [1]=43 | |
| [2]=7c | |
| [3]=0a | |
| [4]=10 | |
| [5]=00 | |
| [6]=10 | |
| [7]=03 | |
| [8]=41 | |
| [9]=f7 | |
| */ | |
| int spnxMidiSend(int param_1,void *param_2,size_t param_3){ | |
| if( pspnxMidiSend == NULL ){ | |
| pspnxMidiSend = dlsym(RTLD_NEXT,"spnxMidiSend"); | |
| } | |
| if( param_1 == 1 && param_3==10 ) { | |
| char *p=(char *)param_2; | |
| for(int n=0;n<param_3;n++){ | |
| printf("[%d]=%02x\n",n,((char *)param_2)[n]&0xff); | |
| } | |
| if( memcmp(p+5,"\x00\x10\x03",3)==0){ | |
| printf("keycontrol [%d]",p[8]-64); | |
| play_status.transpose=p[8]-64; | |
| } | |
| } | |
| pspnxMidiSend(param_1,param_2,param_3); | |
| } | |
| int (*psaitenApiOpen)(uint *param_1); | |
| int saitenApiOpen(uint *param_1){ | |
| if( psaitenApiOpen == NULL ){ | |
| psaitenApiOpen = dlsym(RTLD_NEXT,"saitenApiOpen"); | |
| } | |
| printf("songnum=%04d-%02d\n", *param_1 >> 8, | |
| *param_1 & 0xff); | |
| play_status.songnum=*param_1; | |
| int ret = psaitenApiOpen(param_1); | |
| return ret; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment