void loadProgram(String program); #include "nrf.h" #include "ble.h" #include #define aBtnBorder 22936 #define aBtnIncBorder 500 btnMatrix btns(25,26,27,14 ,34,35,32,33); //animation Store struct animation{ unsigned int totaltime; String data; }; animation A_store[NUM_BTNS * 4]; struct buttonlink{ byte clock; //0 system, 1 own, 2 own + reset unsigned int offset; byte id; }; buttonlink B_store [NUM_BTNS][4]; //notused,released,pressed,changing //running byte A_programId[NUM_BTNS]; byte A_state[NUM_BTNS]; //0-3 2-Dim in B_store //round String A_program[NUM_BTNS]; unsigned long A_clock[NUM_BTNS]; //begin of the time byte A_clocktype[NUM_BTNS]; //wich time should be used unsigned int A_offset[NUM_BTNS]; //time offset unsigned int A_totalroundtime[NUM_BTNS]; //total time unsigned int A_roundtime[NUM_BTNS]; //time passed //step boolean A_slow[NUM_BTNS]; unsigned int A_steptime[NUM_BTNS]; CRGB A_color[NUM_BTNS]; boolean A_next_slow[NUM_BTNS]; unsigned int A_next_steptime[NUM_BTNS]; CRGB A_next_color[NUM_BTNS]; //read in bool state[64]; int values[64]; //btns bool lastState[NUM_BTNS]; //first interpreter bool switchState[NUM_BTNS]; byte buttonaction[NUM_BTNS][7]; //analog int16_t lastValue[NUM_ANALOG]; double analogCalibrate[NUM_ANALOG][3]; byte analogaction[NUM_ANALOG][5]; /*analog -> btns 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0: lx rx lt rt sy 1 5 9 16: ly ry lr rr sy 2 6 10 32: lt rt ll rl tl 3 7 48: lr rr lb rb tr 4 8 0-1 analog 2-3 HAT 4 2xsys 2xtrigger 5-7 10x btn buttons: hat left -> hat right -> (l->r) trigger -> left to right bottom btn */ boolean readBTN(byte i){ //const byte pos[] = {2,18,34,50, 3,19,35,51, 36,52, 5,21,37,53,6,22,38,54,7,23}; const byte pos[] = {36, 2,18,34,50, 5,21,37,53,6,22,38,54,7,23, 51,19,35,3,/*3,19,35,51,*/ 52}; return state[pos[i]]; } double readAnalog(byte i, bool raw = false){ const byte pos[] = {0,16,32,48, 1,17,33,49}; byte j = pos[i]; double value = values[j]; return raw?value:(value*value*analogCalibrate[i][0]+value*analogCalibrate[i][1]+analogCalibrate[i][2]); } void pressBTN(byte amode, byte value){ if(amode==0)return; if(mode==mode_radio&&value<32){ NRFpress(value); } if(mode==mode_bluetooth){ BLEpress(amode,value); } } void releaseBTN(byte amode, byte value){ if(amode==0)return; if(mode==mode_radio&&value<32){ NRFrelese(value); } if(mode==mode_bluetooth){ BLErelese(amode,value); } } void increseAxis(byte analog_num, int16_t value){ if(mode==mode_radio){ NRFincreseAxis(analog_num,value/**currentTime/1000*/); } if(mode==mode_bluetooth){ BLEincreseAxis(analog_num,value/**currentTime/1000*/); } } void setAxis(byte analog_num, int16_t value){ if(mode==mode_radio){ NRFsetAxis(analog_num,value); } if(mode==mode_bluetooth){ BLEsetAxis(analog_num,value); } } void datasend(){ if(mode==mode_radio){ NRFsend(); //BLEnotsend(); } if(mode==mode_bluetooth){ BLEsend(); NRFnotsend(); } } void innerModeClick(){ if(mode==mode_radio){ NRFclick(); } if(mode==mode_bluetooth){ BLEclick(); } } void load_next_step(byte i){ unsigned int cutpos = 0; cutpos = cutcheck(A_program[i].indexOf(","),A_program[i].length()); String now = A_program[i].substring(0,cutpos); A_program[i] = A_program[i].substring(cutpos+1); //add roundtime A_roundtime[i] += A_steptime[i]; //move old A_slow[i] = A_next_slow[i]; A_steptime[i] = A_next_steptime[i]; A_color[i] = A_next_color[i]; //load new //slow? cutpos = cutcheck(now.indexOf(" "),now.length()); String nowin = now.substring(0,cutpos); now = now.substring(cutpos+1); A_next_slow[i]=false; if(nowin.startsWith("1")){ A_next_slow[i]=true; } //time cutpos = cutcheck(now.indexOf(" "),now.length()); nowin = now.substring(0,cutpos); now = now.substring(cutpos+1); A_next_steptime[i] = nowin.toInt(); //color cutpos = cutcheck(now.indexOf(" "),now.length()); nowin = now.substring(0,cutpos); now = now.substring(cutpos+1); A_next_color[i] = hextocolor(nowin); if(A_program[i].length()<2){ A_program[i] = A_store[A_programId[i]].data; } } void loadC(byte state,byte i){ A_state[i] = state; buttonlink B_now = B_store[i][state]; A_programId[i] = B_now.id > 255?0:B_now.id; animation A_now = A_store[A_programId[i]]; A_totalroundtime[i] = A_now.totaltime; A_offset[i] = B_now.offset; A_clocktype[i] = B_now.clock; if(B_now.clock>0){ A_clock[i] = millis(); } A_program[i] = A_now.data; load_next_step(i); load_next_step(i); leds[i] = A_color[i]; A_roundtime[i] = 0; } float lastBright = getBrightness(); void animateBTNs(){ for (int i = 0; i < NUM_BTNS; i++) { unsigned long time = millis()-(A_clocktype[i]==0?0:A_clock[i])+A_offset[i]; unsigned int roundtime = time%A_totalroundtime[i]; if(roundtime=A_roundtime[i]+A_steptime[i]){ load_next_step(i); leds[i] = A_color[i]; } if(A_roundtime[i]>=A_totalroundtime[i])A_roundtime[i]=0; if(A_slow[i]){ float per = 100.0*(roundtime-A_roundtime[i])/((float) A_steptime[i]); leds[i] = CRGB( round((float)(A_color[i][0] * (100.0-per)/100.0) + (A_next_color[i][0] * per/100.0)), round((float)(A_color[i][1] * (100.0-per)/100.0) + (A_next_color[i][1] * per/100.0)), round((float)(A_color[i][2] * (100.0-per)/100.0) + (A_next_color[i][2] * per/100.0)) ); } } lastBright = lastBright * 0.999 + getBrightness() * 0.001; FastLED.setBrightness(lastBright); FastLED.show(); } void handelInput(){ unsigned long nowTime = millis(); currentTime = nowTime-lastTime; lastTime = nowTime; btns.readAll(state,values,8); btns.analogGlide(values,0,0.3); btns.analogGlide(values,1,0.3); btns.analogGlide(values,0,0.1); btns.analogGlide(values,1,0.1); for(int i = 0; i < NUM_ANALOG; i++){ if(analogaction[i][0]>0){ double analoginR = readAnalog(i); int16_t analogin; if(analoginR>32767){ analogin = 32767; }else if(analoginR<-32767){ analogin = -32767; }else{ analogin = (int16_t)analoginR; } if(analogaction[i][0]==1){ //press up if(analogin>=aBtnBorder&&lastValue[i]-aBtnBorder)pressBTN(analogaction[i][3],analogaction[i][4]); //release up if(analogin=aBtnBorder)releaseBTN(analogaction[i][1],analogaction[i][2]); //release down if(analogin>-aBtnBorder&&lastValue[i]<=-aBtnBorder)releaseBTN(analogaction[i][3],analogaction[i][4]); } if(analogaction[i][0]==2){ setAxis(analogaction[i][1],analogin); } if(analogaction[i][0]==3){ if(abs(analogin)>aBtnIncBorder) increseAxis(analogaction[i][1],round((double)analogin * ((double) ((int16_t)((analogaction[i][2]<<8)+analogaction[i][3])) )/32767.0) ); } lastValue[i] = analogin; } } for (int i = 0; i < NUM_BTNS; i++) { boolean btnstate = readBTN(i); if(buttonaction[i][0]==1){ if(btnstate&&!lastState[i]){ loadC(2,i); pressBTN(buttonaction[i][1],buttonaction[i][2]); pressBTN(buttonaction[i][3],buttonaction[i][4]); pressBTN(buttonaction[i][5],buttonaction[i][6]); } if(!btnstate&&lastState[i]){ loadC(1,i); releaseBTN(buttonaction[i][1],buttonaction[i][2]); releaseBTN(buttonaction[i][3],buttonaction[i][4]); releaseBTN(buttonaction[i][5],buttonaction[i][6]); } } if(buttonaction[i][0]==2){ if(btnstate&&!lastState[i]){ loadC(3,i); pressBTN(buttonaction[i][1],buttonaction[i][2]); pressBTN(buttonaction[i][3],buttonaction[i][4]); pressBTN(buttonaction[i][5],buttonaction[i][6]); } if(!btnstate&&lastState[i]){ switchState[i]=!switchState[i]; if(switchState[i]){ loadC(2,i); }else{ loadC(1,i); } releaseBTN(buttonaction[i][1],buttonaction[i][2]); releaseBTN(buttonaction[i][3],buttonaction[i][4]); releaseBTN(buttonaction[i][5],buttonaction[i][6]); } } if(buttonaction[i][0]==3){ if(btnstate&&!lastState[i]){ loadC(3,i); } if(!btnstate&&lastState[i]){ switchState[i]=!switchState[i]; if(switchState[i]){ loadC(2,i); pressBTN(buttonaction[i][1],buttonaction[i][2]); pressBTN(buttonaction[i][3],buttonaction[i][4]); pressBTN(buttonaction[i][5],buttonaction[i][6]); }else{ loadC(1,i); releaseBTN(buttonaction[i][1],buttonaction[i][2]); releaseBTN(buttonaction[i][3],buttonaction[i][4]); releaseBTN(buttonaction[i][5],buttonaction[i][6]); } } } if(buttonaction[i][0]==4){ if(btnstate&&!lastState[i]){ loadC(2,i); } if(!btnstate&&lastState[i]){ loadC(1,i); } if(btnstate){ setAxis(buttonaction[i][1],(buttonaction[i][2]<<8)+buttonaction[i][3]); } } if(buttonaction[i][0]==5){ if(btnstate&&!lastState[i]){ loadC(2,i); } if(!btnstate&&lastState[i]){ loadC(1,i); } if(btnstate){ increseAxis(buttonaction[i][1],(buttonaction[i][2]<<8)+buttonaction[i][3]); } } lastState[i] = btnstate; } animateBTNs(); datasend(); } void LEDsetShutdown(){ for (int i = 0; i < NUM_LEDS; i++) { leds[i] = CRGB(100,0,0); } FastLED.show(); } void loadProgram(String program){ unsigned int cutpos = 0; cutpos = cutcheck(program.indexOf(";"),program.length()); String btns = program.substring(0,cutpos); String analog = program.substring(cutpos+1); int i = 0; for(i = 0; i < NUM_BTNS; i++){ lastState[i] = false; switchState[i] = false; buttonaction[i][0] = 0; buttonaction[i][1] = 0; buttonaction[i][2] = 0; buttonaction[i][3] = 0; buttonaction[i][4] = 0; buttonaction[i][5] = 0; buttonaction[i][6] = 0; } i=0; while(btns.length()>1){ if(i>=NUM_BTNS)break; cutpos = cutcheck(btns.indexOf(","),btns.length()); String now = btns.substring(0,cutpos); btns = btns.substring(cutpos+1); /*Serial.print("signle btn: "); Serial.println(now);*/ int j = 0; if(now.startsWith("00")){ loadC(0,i); }else{ loadC(1,i); } while(now.length()>j*2+1&&j<7){ String now2 = now.substring(j*2,j*2+2); /*Serial.print("read ["); Serial.print(i); Serial.print("] ["); Serial.print(j); Serial.print("] : ");*/ buttonaction[i][j] = hextonum(now2); /*Serial.print(buttonaction[i][j]); Serial.print(" ("); Serial.print(now2); Serial.println(")");*/ j++; } i++; } //analog for(i = 0; i < NUM_ANALOG; i++){ lastValue[i] = 0; analogaction[i][0] = 0; analogaction[i][1] = 0; analogaction[i][2] = 0; analogaction[i][3] = 0; analogaction[i][4] = 0; } i = 0; while(analog.length()>1){ if(i>=NUM_ANALOG)break; cutpos = cutcheck(analog.indexOf(","),analog.length()); String now = analog.substring(0,cutpos); analog = analog.substring(cutpos+1); int j = 0; while(now.length()>j*2+1&&j<5){ String now2 = now.substring(j*2,j*2+2); analogaction[i][j] = hextonum(now2); j++; } i++; } } void loadLEDProgram(String program){ preferences.putString("LEDProgram",program); unsigned int cutpos = 0; cutpos = cutcheck(program.indexOf("|"),program.length()); String prog = program.substring(0,cutpos); String links = program.substring(cutpos+1); byte i = 0; while(prog.length()>2&&i2&&i2&&j<4){ cutpos = cutcheck(btn.indexOf(","),btn.length()); String now = btn.substring(0,cutpos); btn = btn.substring(cutpos+1); cutpos = cutcheck(now.indexOf(" "),now.length()); String nowin = now.substring(0,cutpos); now = now.substring(cutpos+1); B_store[i][j].clock = nowin=="0"?(0):(nowin=="2"?(2):(1)); cutpos = cutcheck(now.indexOf(" "),now.length()); nowin = now.substring(0,cutpos); now = now.substring(cutpos+1); B_store[i][j].offset = nowin.toInt(); cutpos = cutcheck(now.indexOf(" "),now.length()); nowin = now.substring(0,cutpos); now = now.substring(cutpos+1); B_store[i][j].id = (byte) nowin.toInt(); j++; } i++; } } void loadCalibrationData(String data){ unsigned int cutpos = 0; int i = 0; while(data.length()>1){ if(i>=NUM_ANALOG)break; cutpos = cutcheck(data.indexOf(";"),data.length()); String now = data.substring(0,cutpos); data = data.substring(cutpos+1); for (int j = 0; j < 3; j++) { if(now.length()>0){ cutpos = cutcheck(now.indexOf(","),now.length()); String now2 = now.substring(0,cutpos); now = now.substring(cutpos+1); analogCalibrate[i][j] = now2.toFloat(); } } i++; } preferences.putBytes("analogCalib",analogCalibrate, sizeof(analogCalibrate)); } void iniInput(){ if(firstLaunch){ //loadProgram("010500,02020b,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00;00,00,00,00,00,00,00,00"); //loadProgram("010304,010400,010401,010403,010402,01040a,010408,01020e,01020d,02020b,02020a,010209,010208,010409,01040b,0103000,010301,010302,010303,010305;0208,0209,00,00,020b,020a,00,00"); loadCalibrationData( (String)"0.00016901909683607273,23.823860249481648,-41965.23905167896;"+ "0.0032568361858686832,14.552576203914427,-35492.98520912674;"+ "-0.0000019086881625810545,16.011234881444572,-32767;"+ "-0.0000019086881625810545,16.011234881444572,-32767;"+ "-0.00019162251342654416,20.605461485605023,-35751.76305206794;"+ "-0.0008308262876500306,22.692086412128443,-35479.08647091325;"+ "-0.0000019086881625810545,16.011234881444572,-32767;"+ "-0.0000019086881625810545,16.011234881444572,-32767;" ); }else{ preferences.getBytes("analogCalib",analogCalibrate, sizeof(analogCalibrate)); } loadLEDProgram(preferences.getString("LEDProgram","10000:1 5000 880000,1 5000 004444;2000:1 1000 ff0000,1 1000 dd1111;2000:1 1000 00ff00,1 1000 11dd11;2000:1 1000 eeee00,1 1000 bb2222;|0 0 0,0 0 1,0 0 2,0 0 3;0 500 0,0 0 1,0 0 2,0 0 3;0 1000 0,0 0 1,0 0 2,0 0 3;0 1500 0,0 0 1,0 0 2,0 0 3;0 2000 0,0 0 1,0 0 2,0 0 3;0 2500 0,0 0 1,0 0 2,0 0 3;0 3000 0,0 0 1,0 0 2,0 0 3;0 3500 0,0 0 1,0 0 2,0 0 3;0 4000 0,0 0 1,0 0 2,0 0 3;0 4500 0,0 0 1,0 0 2,0 0 3;0 5000 0,0 0 1,0 0 2,0 0 3;0 5500 0,0 0 1,0 0 2,0 0 3;0 6000 0,0 0 1,0 0 2,0 0 3;0 6500 0,0 0 1,0 0 2,0 0 3;0 7000 0,0 0 1,0 0 2,0 0 3;0 7500 0,0 0 1,0 0 2,0 0 3;0 8000 0,0 0 1,0 0 2,0 0 3;0 8500 0,0 0 1,0 0 2,0 0 3;0 9000 0,0 0 1,0 0 2,0 0 3;0 9500 0,0 0 1,0 0 2,0 0 3;")); BLEProgramCache[0] = preferences.getString("BLEPchache_0","010304,010400,010401,010403,010402,01040a,010408,01020e,01020d,02020b,02020a,010209,010208,010409,01040b,0103000,010301,010302,010303,010305;0208,0209,00,00,020b,020a,00,00"); BLEProgramCache[1] = preferences.getString("BLEPchache_1",""); BLEProgramCache[2] = preferences.getString("BLEPchache_2",""); BLEProgramCache[3] = preferences.getString("BLEPchache_3",""); BLEProgramCache[4] = preferences.getString("BLEPchache_4",""); FastLED.addLeds(leds, NUM_LEDS); FastLED.setBrightness(100); } /* analogCalibrate Date: wert_0_0,wert_0_1,wert_0_2; */ /* empty Program 010500,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00;00,00,00,00,00,00,00,00 */ /* //all numbers are in hexadecimal mode submode value //for btns [0] //not unsed [1] //normal btns --> see btns --> see btns --> see btns [2] //seemingly switch --> see btns --> see btns --> see btns [3] //switch --> see btns --> see btns --> see btns [4] //setAnaloge [0-11] //analoge Values [-32767 - 32767] [5] //incrementalchange [0-11] //analoge Values [-32767 - 32767] //for analog [0] //not unsed [1] //normal btns //min 70% --> see btns (up) --> see btns (down) [2] //setAnaloge [0-11] //analoge Values [3] //incrementalchange [0-11] //analoge Values [-32767 - 32767] //multiplayer of in (-1 to 1) --> btns [0] empty //ble [1] //scancode [0-255] [2] //MediaKey [0-15] [3] //Gamepadbtns [0-13] [4] //HAT [0-3] [5] //Mouse [0-4] //nrf [ff] //bool chanels [0-31] --> analoge //ble -> lx, ly, rx, ry, lt, rt, lr, rr, mx, my, sm, sh //nrf -> 0-11 raw send //saved as float rounded for send to int16_t */ /* nrfpackage [4] reserved [4] 32x btns [24] 12x 2byte analoge outputs == 32 */ /* new animation idea from 0x00: 1000:1 500 880000,1 500 004444; //totaltime:slow steptime color, slow steptime color, ...; 0x01: 1000:1 500 880000,1 500 004444; .... 0x50: 1000:1 500 880000,1 500 004444; to max 0x50 (80) | 0x00 0 0 0,1 0 1,0 0 2,0 0 3; //clock offset id,clock offset id,clock offset id,clock offset id; 0x01 0 0 0,1 0 1,0 0 2,0 0 3; 0x14 0 0 0,1 0 1,0 0 2,0 0 3; detail specs, look old structur v */ /* animation: { totaltime, [in ms] clock, [0: systemclock, 1 (and else): Button clock, 2 Button clock with reset] offset: posnumber, data:[ slow, [1: slow, 0: hard] time, color ] } */ /* "10000:1 5000 880000,1 5000 004444;"+ "2000:1 1000 ff0000,1 1000 dd1111;"+ "2000:1 1000 00ff00,1 1000 11dd11;"+ "2000:1 1000 eeee00,1 1000 bb2222;"+ "|"+ "0 0 0,0 0 1,0 0 2,0 0 3;"+ "0 500 0,0 0 1,0 0 2,0 0 3;"+ "0 1000 0,0 0 1,0 0 2,0 0 3;"+ "0 1500 0,0 0 1,0 0 2,0 0 3;"+ "0 2000 0,0 0 1,0 0 2,0 0 3;"+ "0 2500 0,0 0 1,0 0 2,0 0 3;"+ "0 3000 0,0 0 1,0 0 2,0 0 3;"+ "0 3500 0,0 0 1,0 0 2,0 0 3;"+ "0 4000 0,0 0 1,0 0 2,0 0 3;"+ "0 4500 0,0 0 1,0 0 2,0 0 3;"+ "0 5000 0,0 0 1,0 0 2,0 0 3;"+ "0 5500 0,0 0 1,0 0 2,0 0 3;"+ "0 6000 0,0 0 1,0 0 2,0 0 3;"+ "0 6500 0,0 0 1,0 0 2,0 0 3;"+ "0 7000 0,0 0 1,0 0 2,0 0 3;"+ "0 7500 0,0 0 1,0 0 2,0 0 3;"+ "0 8000 0,0 0 1,0 0 2,0 0 3;"+ "0 8500 0,0 0 1,0 0 2,0 0 3;"+ "0 9000 0,0 0 1,0 0 2,0 0 3;"+ "0 9500 0,0 0 1,0 0 2,0 0 3;" */ /* example: 1000:0:0:1 500 880000,1 500 004444; 10000:0:0:0 10000 ff0000; 10000:0:0:0 10000 00ff00; 10000:0:0:0 10000 eeee00| "10000:0:0:1 5000 880000,1 5000 004444;10000:0:0:0 10000 ff0000;10000:0:0:0 10000 00ff00;10000:0:0:0 10000 eeee00|"+ "10000:0:500:1 5000 880000,1 5000 004444;10000:0:0:0 10000 ff0000;10000:0:0:0 10000 00ff00;10000:0:0:0 10000 eeee00|"+ "10000:0:1000:1 5000 880000,1 5000 004444;10000:0:0:0 10000 ff0000;10000:0:0:0 10000 00ff00;10000:0:0:0 10000 eeee00|"+ "10000:0:1500:1 5000 880000,1 5000 004444;10000:0:0:0 10000 ff0000;10000:0:0:0 10000 00ff00;10000:0:0:0 10000 eeee00|"+ "10000:0:2000:1 5000 880000,1 5000 004444;10000:0:0:0 10000 ff0000;10000:0:0:0 10000 00ff00;10000:0:0:0 10000 eeee00|"+ "10000:0:2500:1 5000 880000,1 5000 004444;10000:0:0:0 10000 ff0000;10000:0:0:0 10000 00ff00;10000:0:0:0 10000 eeee00|"+ "10000:0:3000:1 5000 880000,1 5000 004444;10000:0:0:0 10000 ff0000;10000:0:0:0 10000 00ff00;10000:0:0:0 10000 eeee00|"+ "10000:0:3500:1 5000 880000,1 5000 004444;10000:0:0:0 10000 ff0000;10000:0:0:0 10000 00ff00;10000:0:0:0 10000 eeee00|"+ "10000:0:4000:1 5000 880000,1 5000 004444;10000:0:0:0 10000 ff0000;10000:0:0:0 10000 00ff00;10000:0:0:0 10000 eeee00|"+ "10000:0:4500:1 5000 880000,1 5000 004444;10000:0:0:0 10000 ff0000;10000:0:0:0 10000 00ff00;10000:0:0:0 10000 eeee00|"+ "10000:0:5000:1 5000 880000,1 5000 004444;10000:0:0:0 10000 ff0000;10000:0:0:0 10000 00ff00;10000:0:0:0 10000 eeee00|"+ "10000:0:5500:1 5000 880000,1 5000 004444;10000:0:0:0 10000 ff0000;10000:0:0:0 10000 00ff00;10000:0:0:0 10000 eeee00|"+ "10000:0:6000:1 5000 880000,1 5000 004444;10000:0:0:0 10000 ff0000;10000:0:0:0 10000 00ff00;10000:0:0:0 10000 eeee00|"+ "10000:0:6500:1 5000 880000,1 5000 004444;10000:0:0:0 10000 ff0000;10000:0:0:0 10000 00ff00;10000:0:0:0 10000 eeee00|"+ "10000:0:7000:1 5000 880000,1 5000 004444;10000:0:0:0 10000 ff0000;10000:0:0:0 10000 00ff00;10000:0:0:0 10000 eeee00|"+ "10000:0:7500:1 5000 880000,1 5000 004444;10000:0:0:0 10000 ff0000;10000:0:0:0 10000 00ff00;10000:0:0:0 10000 eeee00|"+ "10000:0:8000:1 5000 880000,1 5000 004444;10000:0:0:0 10000 ff0000;10000:0:0:0 10000 00ff00;10000:0:0:0 10000 eeee00|"+ "10000:0:8500:1 5000 880000,1 5000 004444;10000:0:0:0 10000 ff0000;10000:0:0:0 10000 00ff00;10000:0:0:0 10000 eeee00|"+ "10000:0:9000:1 5000 880000,1 5000 004444;10000:0:0:0 10000 ff0000;10000:0:0:0 10000 00ff00;10000:0:0:0 10000 eeee00|"+ "10000:0:9500:1 5000 880000,1 5000 004444;10000:0:0:0 10000 ff0000;10000:0:0:0 10000 00ff00;10000:0:0:0 10000 eeee00|" */