View difference between Paste ID: yRX9GW4U and 6L1sjgDR
SHOW: | | - or go back to the newest paste.
1-
// Just a backup for my uncompleted tracker program for my sound chip
1+
// Backup #2
2
3
#include <stdio.h>
4
#include <stdlib.h>
5
#include <string.h>
6
#include <time.h>
7
#include <ncurses.h>
8
9
#define NOTE_NULL 0x0
10
#define NOTE_RESET 0x1
11
#define NOTE_ON 0x2
12
#define NOTE_OFF 0x3
13
#define NOTE_C 0x4
14
#define NOTE_Cs 0x5
15
#define NOTE_Db 0x5
16
#define NOTE_D 0x6
17
#define NOTE_Ds 0x7
18
#define NOTE_Eb 0x7
19
#define NOTE_E 0x8
20
#define NOTE_F 0x9
21
#define NOTE_Fs 0xA
22
#define NOTE_Gb 0xA
23
#define NOTE_G 0xB
24
#define NOTE_Gs 0xC
25
#define NOTE_Ab 0xC
26
#define NOTE_A 0xD
27
#define NOTE_As 0xE
28
#define NOTE_Bb 0xE
29
#define NOTE_B 0xF
30
31
#define EFF_ARPEGGIO 0x0
32
#define EFF_PITCH_SLIDE_UP 0x1
33
#define EFF_PITCH_SLIDE_DOWN 0x2
34
#define EFF_PORTAMENTO 0x3
35
#define EFF_VIBRATO 0x4
36
#define EFF_WAVEFORM 0x5
37
#define EFF_DUTY_CYCLE 0x6
38
#define EFF_TREMOLO 0x7
39
#define EFF_PWM 0x8
40
#define EFF_PITCH 0x9
41
#define EFF_VOLUME_SLIDE_UP 0xA
42
#define EFF_VOLUME_SLIDE_DOWN 0xB
43
#define EFF_VOLUME 0xC
44
#define EFF_ENVELOPE_ATTACK_DECAY 0xD
45
#define EFF_ENVELOPE_SUSTAIN_RELEASE 0xE
46
#define EFF_FINE_TUNE 0xF
47
48
FILE *out;
49
char serialPort[255];
50
51
typedef struct
52
{
53
	unsigned char enable;
54
	unsigned char effect;
55
	unsigned char argument;
56
	
57
} Effect;
58
59
typedef struct
60
{
61
	unsigned char note;
62
	unsigned char octave;
63
	unsigned char volume;
64
	unsigned char applyInstrument;
65
	unsigned char instrument;
66
	
67
} NoteCommand;
68
69
typedef struct
70
{
71
	NoteCommand noteCommand;
72
	Effect effect;
73
	
74
} Entry;
75
76
typedef struct
77
{
78
	Entry entries[4];
79
	
80
} Frame;
81
82
typedef struct
83
{
84
	Effect effects[8];
85
	
86
} Instrument;
87
88
typedef struct
89
{
90
	Frame frames[32];
91
	
92
} Order;
93
94
typedef struct
95
{
96
	unsigned char fps;
97
	unsigned char orderCount;
98
	unsigned char repeat;
99
	unsigned char instrumentCount;
100
	Instrument *instruments;
101
	Order *orders;
102
	
103
} Song;
104
105
void printTabs(int tabs)
106
{
107
	int i;
108
	for(i = 0; i < tabs; i++)
109
	{
110
		printf("\t");
111
	}
112
}
113
114
void printEffect(Effect *effect, int tabs)
115
{
116
	int s1, s2;
117
	s1 = (effect->argument) >> 4;
118
	s2 = (effect->argument) & 0x0F;
119
	printTabs(tabs);
120
	if(effect->enable)
121
	{
122
		switch(effect->effect)
123
		{
124
			case 0x0:
125
				if(s1 || s2)
126
				{
127
					printf("Arpeggio: Semitones: %i, %i\n", s1, s2);
128
				}
129
				else
130
				{
131
					printf("Arpeggio Off\n");
132
				}
133
				break;
134
			case 0x1:
135
				printf("Pitch Slide Up: Rate: %i\n", effect->argument);
136
				break;
137
			case 0x2:
138
				printf("Pitch Slide Down: Rate: %i\n", effect->argument);
139
				break;
140
			case 0x3:
141
				if(effect->argument)
142
				{
143
					printf("Portamento: Rate: %i\n", effect->argument);
144
				}
145
				else
146
				{
147
					printf("Portamento Off");
148
				}
149
				break;
150
			case 0x4:
151
				printf("Vibrato: Rate: %i, Depth: %i\n", s1, s2);
152
				break;
153
			case 0x5:
154
				printf("Waveform: ");
155
				switch(effect->argument)
156
				{
157
					case 0:
158
						printf("Pulse\n");
159
						break;
160
					case 1:
161
						printf("Triangle\n");
162
						break;
163
					case 2:
164
						printf("Sawtooth\n");
165
						break;
166
					case 3:
167
						printf("Noise\n");
168
						break;
169
					default:
170
						printf("Unknown\n");
171
				}
172
				break;
173
			case 0x6:
174
				printf("Duty Cycle: %i\%\n", effect->argument / 256 * 100);
175
				break;
176
			case 0x7:
177
				printf("Tremolo: Rate: %i, Depth: %i\n", s1, s2);
178
				break;
179
			case 0x8:
180
				printf("Pulse Width Modulation: Rate: %i, Depth: %i\n", s1, s2);
181
				break;
182
			case 0x9:
183
				printf("Pitch: %i\n", effect->argument);
184
				break;
185
			case 0xA:
186
				printf("Volume Slide Up: Rate: %i\n", effect->argument);
187
				break;
188
			case 0xB:
189
				printf("Volume Slide Down: Rate: %i\n", effect->argument);
190
				break;
191
			case 0xC:
192
				printf("Volume: %i\n", effect->argument);
193
				break;
194
			case 0xD:
195
				printf("Envelope: Attack: %i, Decay: %i\n", s1, s2);
196
				break;
197
			case 0xE:
198
				printf("Envelope: Sustain: %i\%, Release: %i\n", s1 / 16 * 100, s2);
199
				break;
200
			case 0xF:
201
				printf("Fine Tune: %i\n", effect->argument);
202
				break;
203
			default:
204
				printf("Unknown Effect\n");
205
		}
206
	}
207
	else
208
	{
209
		printf("No Effect\n");
210
	}
211
}
212
213
void printInstrumentInfo(Instrument *instrument, int tabs)
214
{
215
	int i;
216
	for(i = 0; i < sizeof(instrument->effects) / sizeof(Effect); i++)
217
	{
218
		printTabs(tabs);
219
		printf("Effect #%i:\n", i + 1);
220
		printEffect(&(instrument->effects[i]), tabs + 1);
221
	}
222
}
223
224
void printNote(unsigned char note, unsigned char octave, int tabs)
225
{
226
	printTabs(tabs);
227
	switch(note)
228
	{
229
		case 0x0:
230
			printf("No Note\n");
231
			break;
232
		case 0x1:
233
			printf("Reset Oscillator Timer\n");
234
			break;
235
		case 0x2:
236
			printf("Enable Oscillator\n");
237
			break;
238
		case 0x3:
239
			printf("Disable Oscillator\n");
240
			break;
241
		case 0x4:
242
			printf("Play Note C%i\n", octave);
243
			break;
244
		case 0x5:
245
			printf("Play Note C#%i\n", octave);
246
			break;
247
		case 0x6:
248
			printf("Play Note D%i\n", octave);
249
			break;
250
		case 0x7:
251
			printf("Play Note D#%i\n", octave);
252
			break;
253
		case 0x8:
254
			printf("Play Note E%i\n", octave);
255
			break;
256
		case 0x9:
257
			printf("Play Note F%i\n", octave);
258
			break;
259
		case 0xA:
260
			printf("Play Note F#%i\n", octave);
261
			break;
262
		case 0xB:
263
			printf("Play Note G%i\n", octave);
264
			break;
265
		case 0xC:
266
			printf("Play Note G#%i\n", octave);
267
			break;
268
		case 0xD:
269
			printf("Play Note A%i\n", octave);
270
			break;
271
		case 0xE:
272
			printf("Play Note A#%i\n", octave);
273
			break;
274
		case 0xF:
275
			printf("Play Note B%i\n", octave);
276
			break;
277
		default:
278
			printf("Unknown Command\n");
279
	}
280
}
281
282
void printVolume(unsigned char volume, int tabs)
283
{
284
	printTabs(tabs);
285
	if(volume)
286
	{
287
		printf("Volume: %i\%\n", volume / 32 * 100);
288
	}
289
	else
290
	{
291
		printf("Ignore Volume\n");
292
	}
293
}
294
295
void printInstrumentID(unsigned char applyInstrument, unsigned char instrument, int tabs)
296
{
297
	printTabs(tabs);
298
	if(applyInstrument)
299
	{
300
		printf("Apply Instrument #%i\n", instrument + 1);
301
	}
302
	else
303
	{
304
		printf("Ignore Instrument\n");
305
	}
306
}
307
308
void printNoteCommand(NoteCommand *noteCommand, int tabs)
309
{
310
	printNote(noteCommand->note, noteCommand->octave, tabs);
311
	printVolume(noteCommand->volume, tabs);
312
	printInstrumentID(noteCommand->applyInstrument, noteCommand->instrument, tabs);
313
}
314
315
void printEntry(Entry *entry, int tabs)
316
{
317
	printNoteCommand(&(entry->noteCommand), tabs);
318
	printEffect(&(entry->effect), tabs);
319
}
320
321
void printFrame(Frame *frame, int tabs)
322
{
323
	int i;
324
	for(i = 0; i < sizeof(frame->entries) / sizeof(Entry); i++)
325
	{
326
		printTabs(tabs);
327
		printf("Channel #%i:\n", i + 1);
328
		printEntry(&(frame->entries[i]), tabs + 1);
329
	}
330
}
331
332
void printOrderInfo(Order *order, int tabs)
333
{
334
	int i;
335
	for(i = 0; i < sizeof(order->frames) / sizeof(Frame); i++)
336
	{
337
		printTabs(tabs);
338
		printf("Frame #%i:\n", i + 1);
339
		printFrame(&(order->frames[i]), tabs + 1);
340
	}
341
}
342
343
void printSongInfo(Song *song)
344
{
345
	printf("Speed: %i FPS\n", song->fps);
346
	printf("Length: %i Orders\n", song->orderCount);
347
	printf("Repeat: Order #%i\n", song->repeat + 1);
348
	printf("Instrument Count: %i\n", song->instrumentCount);
349
	
350
	printf("Instruments:\n");
351
	int i;
352
	for(i = 0; i <  song->instrumentCount; i++)
353
	{
354
		printf("\tInstrument #%i:\n", i + 1);
355
		printInstrumentInfo(&(song->instruments[0]), 2);
356
	}
357
	
358
	printf("Orders:\n");
359
	for(i = 0; i <  song->orderCount; i++)
360
	{
361
		printf("\tOrder #%i:\n", i + 1);
362
		printOrderInfo(&(song->orders[0]), 2);
363
	}
364
}
365
366
void playNote(unsigned char note, unsigned char octave, unsigned char volume, unsigned char osc)
367
{
368
	note &= 0x0F;
369
	octave &= 0b00000111;
370-
	volume &= 0b00011111;
370+
	volume &= 0b00011110; // weird bug causing the last bit to make the octave go really high
371
	osc &= 0b00000011;
372
	
373
	char highByte = (octave >> 1) | (volume << 2) | (1 << 7);
374
	char lowByte = (osc << 1) | (note << 3) | (octave << 7);
375
	
376
	fputc(highByte, out);
377
	fputc(lowByte, out);
378
	fputc(0xFF, out);
379
	
380
	fclose(out);
381
	out = fopen(serialPort, "w");
382
}
383
384
void playEffect(unsigned char effect, unsigned char argument, unsigned char osc)
385
{
386
	effect &= 0x0F;
387
	osc &= 0b00000011;
388
	
389
	char highByte = (argument >> 1) | (1 << 7);
390
	char lowByte = 1 | (osc << 1) | (effect << 3) | (argument << 7);
391
	
392
	fputc(highByte, out);
393
	fputc(lowByte, out);
394
	fputc(0xFF, out);
395
	
396
	fclose(out);
397
	out = fopen(serialPort, "w");
398
}
399
400
void sendEffectCommand(Effect *effect, unsigned char osc)
401
{
402
	if(effect->enable)
403
	{
404
		playEffect(effect->effect, effect->argument, osc);
405
	}
406
}
407
408
void sendNoteCommand(NoteCommand *noteCommand, unsigned char osc)
409
{
410-
	playNote(noteCommand->note, noteCommand->octave, noteCommand->volume, osc);
410+
	if(noteCommand->note || noteCommand->octave || noteCommand->volume)
411-
	//applyInstrument goes here
411+
412
		playNote(noteCommand->note, noteCommand->octave, noteCommand->volume, osc);
413
		//applyInstrument goes here
414
	}
415
}
416
417
void playEntry(Entry *entry, unsigned char osc)
418
{
419
	sendEffectCommand(&entry->effect, osc);
420
	sendNoteCommand(&entry->noteCommand, osc);
421
}
422
423
void playFrame(Frame *frame)
424
{
425
	playEntry(&frame->entries[0], 0);
426
	playEntry(&frame->entries[1], 1);
427
	playEntry(&frame->entries[2], 2);
428
	playEntry(&frame->entries[3], 3);
429
}
430
431
NoteCommand newNoteCommand(unsigned char note, unsigned char octave, unsigned char volume, unsigned char applyInstrument, unsigned char instrument)
432
{
433
	NoteCommand command;
434
	command.note = note;
435
	command.octave = octave;
436
	command.volume = volume;
437
	command.applyInstrument = applyInstrument;
438
	command.instrument = instrument;
439
	return command;
440
}
441
442
NoteCommand newSimpleNoteCommand(unsigned char note, unsigned char octave, unsigned char volume)
443
{
444
	return newNoteCommand(note, octave, volume, 0, 0);
445
}
446
447
NoteCommand newSimplestNoteCommand(unsigned char note, unsigned char octave)
448
{
449
	return newSimpleNoteCommand(note, octave, 0);
450
}
451
452
NoteCommand newNullNoteCommand()
453
{
454
	return newSimplestNoteCommand(NOTE_NULL, 0);
455
}
456
457
NoteCommand newResetNoteCommand()
458
{
459
	return newSimplestNoteCommand(NOTE_RESET, 0);
460
}
461
462
NoteCommand newNoteOnCommand()
463
{
464
	return newSimplestNoteCommand(NOTE_ON, 0);
465
}
466
467
NoteCommand newNoteOffCommand()
468
{
469
	return newSimplestNoteCommand(NOTE_OFF, 0);
470
}
471
472
Effect newEffect(unsigned char effect, unsigned char argument)
473
{
474
	Effect new_effect;
475
	new_effect.enable = 1;
476
	new_effect.effect = effect;
477
	new_effect.argument = argument;
478
	return new_effect;
479
}
480
481
Effect newNullEffect()
482
{
483
	Effect effect;
484
	effect.enable = 0;
485
	effect.effect = 0;
486
	effect.argument = 0;
487
	return effect;
488
}
489
490
Entry newEntry(NoteCommand command, Effect effect)
491
{
492
	Entry entry;
493
	entry.noteCommand = command;
494
	entry.effect = effect;
495
	return entry;
496
}
497
498
Entry newSimpleEntry(NoteCommand command)
499
{
500
	return newEntry(command, newNullEffect());
501
}
502
503
Entry newNullEntry()
504
{
505
	return newEntry(newNullNoteCommand(), newNullEffect());
506
}
507
508
Frame newFrame(Entry entry1, Entry entry2, Entry entry3, Entry entry4)
509
{
510
	Frame frame;
511
	frame.entries[0] = entry1;
512
	frame.entries[1] = entry2;
513
	frame.entries[2] = entry3;
514
	frame.entries[3] = entry4;
515
	return frame;
516
}
517
518
Frame newUnisonFrame(Entry entry)
519
{
520
	return newFrame(entry, entry, entry, entry);
521
}
522
523
Frame newQuietFrame()
524
{
525
	return newUnisonFrame(newSimpleEntry(newNoteOffCommand()));
526
}
527
528
Order *newEmptyOrder()
529
{
530
	Order *order;
531
	
532
	int i;
533
	for(i = 0; i < sizeof(order->frames) / sizeof(Frame); i++)
534
	{
535
		order->frames[i] = newQuietFrame();
536
	}
537
	
538
	return order;
539
}
540
541
WINDOW *orderWindow;
542
WINDOW *instrumentWindow;
543-
		printFrame(&order->frames[i], 0);
543+
544
WINDOW *trackerWindow;
545
546
int w1, w2, h1, h2;
547
548-
	Frame frame = newQuietFrame();
548+
549-
	playFrame(&frame);
549+
550
#define WIN_EFFECT 2
551
#define WIN_TRACKER 3
552
int curWindow = WIN_TRACKER;
553
554
#define MODE_EDIT 0
555
#define MODE_PLAY 1
556
#define MODE_JAM 2
557
int curMode = MODE_EDIT;
558
559
#define MAX_ORDERS 64
560
#define MAX_INSTRUMENTS 16
561
562
Song song;
563
564
int curOrder = 0;
565
int curInstrument = 0;
566
int curEffect = 0;
567
int orderScroll = 0;
568
int instrumentScroll = 0;
569
570
int curOsc = 0;
571
int curFrame = 0;
572
int curCol = 0;
573
574
void placeCursor()
575
{
576
	move(LINES - 1, COLS - 1);
577
}
578
579
void printTitle(WINDOW *window, char *title)
580
{
581-
int curY = 5;
581+
582-
int curX = 5;
582+
583
	wattron(window, A_BOLD);
584
	mvwprintw(window, 0,( w - strlen(title)) / 2, "%s", title);
585
}
586-
	move(curY + h1, curX);
586+
587
void drawOrderWindow()
588
{
589
	wclear(orderWindow);
590
	wattrset(orderWindow, A_NORMAL);
591
	if(curWindow == WIN_ORDER && curMode == MODE_EDIT) wattrset(orderWindow, A_REVERSE);
592
	box(orderWindow, 0, 0);
593
	char t[20];
594
	sprintf(t, "Orders (%i)", song.orderCount);
595
	printTitle(orderWindow, t);
596
	wattrset(orderWindow, A_NORMAL);
597
	
598
	int i;
599
	int a;
600
	for(i = orderScroll; i < song.orderCount && i < h1 - 2 + orderScroll; i++)
601
	{
602
		wattrset(orderWindow, curOrder == i ? A_REVERSE : A_NORMAL);
603
		for(a = 0; a < w1 - 2; a++)
604
		{
605
			mvwprintw(orderWindow, i + 1 - orderScroll, a + 1, " ");
606
		}
607
		mvwprintw(orderWindow, i + 1 - orderScroll, 1, "%c 0x%x: ", song.repeat == i ? '*' : '-', i);
608
	}
609
	
610
	wrefresh(orderWindow);
611
	placeCursor();
612
}
613
614
void drawInstrumentWindow()
615
{
616
	wclear(instrumentWindow);
617-
		mvwprintw(orderWindow, i + 1 - orderScroll, 1, "%c 0x%x", song.repeat == i ? '*' : '-', i);
617+
618
	if(curWindow == WIN_INSTR && curMode == MODE_EDIT) wattrset(instrumentWindow, A_REVERSE);
619
	box(instrumentWindow, 0, 0);
620
	char t[20];
621
	sprintf(t, "Instruments (%i)", song.instrumentCount);
622
	printTitle(instrumentWindow, t);
623
	wattrset(instrumentWindow, A_NORMAL);
624
	
625
	int i;
626
	int a;
627
	for(i = instrumentScroll; i < song.instrumentCount && i < h1 - 2 + instrumentScroll; i++)
628
	{
629
		wattrset(instrumentWindow, curInstrument == i ? A_REVERSE : A_NORMAL);
630
		for(a = 0; a < w1 - 2; a++)
631
		{
632
			mvwprintw(instrumentWindow, i + 1 - instrumentScroll, a + 1, " ");
633
		}
634
		mvwprintw(instrumentWindow, i + 1 - instrumentScroll, 1, "0x%x: ", i);
635
	}
636
	
637
	wrefresh(instrumentWindow);
638
	placeCursor();
639
}
640
641
void drawEffectWindow()
642
{
643
	wclear(effectWindow);
644-
		mvwprintw(instrumentWindow, i + 1 - instrumentScroll, 1, "0x%x", i);
644+
645
	if(curWindow == WIN_EFFECT && curMode == MODE_EDIT) wattrset(effectWindow, A_REVERSE);
646
	box(effectWindow, 0, 0);
647
	printTitle(effectWindow, "Effects");
648
	wattrset(effectWindow, A_NORMAL);
649
	
650
	Instrument *instrument = &song.instruments[curInstrument];
651
	
652
	int i;
653
	int a;
654
	for(i = 0; i < sizeof(instrument->effects) / sizeof(Effect); i++)
655
	{
656
		Effect effect = instrument->effects[i];
657
		wattrset(effectWindow, curEffect == i ? A_REVERSE : A_NORMAL);
658
		for(a = 0; a < w1 - 2; a++)
659
		{
660
			mvwprintw(effectWindow, i + 1, a + 1, " ");
661
		}
662
		if(!effect.enable)
663
		{
664
			mvwprintw(effectWindow, i + 1, 1, "0x%x: DISABLED", i);
665
		}
666
		else
667
		{
668
			char eff[20];
669
			switch(effect.effect)
670
			{
671
				case 0x0:
672
					strcpy(eff, "ARPEGGIO:  ");
673
					break;
674
				case 0x1:
675
					strcpy(eff, "PORT UP:   ");
676
					break;
677
				case 0x2:
678
					strcpy(eff, "PORT DOWN: ");
679
					break;
680
				case 0x3:
681
					strcpy(eff, "PORTAMENTO:");
682
					break;
683
				case 0x4:
684
					strcpy(eff, "VIBRATO:   ");
685
					break;
686
				case 0x5:
687
					strcpy(eff, "WAVEFORM:  ");
688
					break;
689
				case 0x6:
690
					strcpy(eff, "DUTY CYCLE:");
691
					break;
692
				case 0x7:
693
					strcpy(eff, "TREMOLO:   ");
694
					break;
695
				case 0x8:
696
					strcpy(eff, "PWM:       ");
697
					break;
698
				case 0x9:
699
					strcpy(eff, "PITCH:     ");
700
					break;
701
				case 0xA:
702
					strcpy(eff, "VOL UP:    ");
703
					break;
704
				case 0xB:
705
					strcpy(eff, "VOL DOWN:  ");
706
					break;
707
				case 0xC:
708
					strcpy(eff, "SET VOL:   ");
709
					break;
710
				case 0xD:
711
					strcpy(eff, "ATCK/DECAY:");
712
					break;
713
				case 0xE:
714
					strcpy(eff, "SUS/RELEAS:");
715-
					strcpy(eff, "STE VOL:   ");
715+
716
				case 0xF:
717
					strcpy(eff, "FINE TUNE: ");
718
					break;
719
			}
720
			mvwprintw(effectWindow, i + 1, 1, "0x%x: (0x%x) %s 0x%x%x", i, effect.effect, eff, (effect.argument & 0xF0) >> 4, effect.argument & 0xF);
721
		}
722
	}
723
	
724
	wrefresh(effectWindow);
725
	placeCursor();
726
}
727
728
void drawTrackerWindow()
729
{
730
	wclear(trackerWindow);
731
	wattrset(trackerWindow, A_NORMAL);
732
	if(curWindow == WIN_TRACKER && curMode == MODE_EDIT) wattrset(trackerWindow, A_REVERSE);
733
	wattron(trackerWindow, A_BOLD);
734
	box(trackerWindow, 0, 0);
735
	wattroff(trackerWindow, A_BOLD);
736
	printTitle(trackerWindow, "Tracker");
737
	wattrset(trackerWindow, A_NORMAL);
738
	
739
	int i;
740
	for(i = -2; i <= 32 && i < h2 - 4; i++)
741
	{
742
		wattrset(trackerWindow, A_BOLD);
743
		if(i >= 0 && i < 32)
744
		{
745
			if(curFrame == i) wattron(trackerWindow, A_REVERSE);
746
			mvwprintw(trackerWindow, i + 3, 1, "0x%x%x ", (i & 0xF0) >> 4, i & 0xF);
747
		}
748
		else if(i == -2)
749
		{
750
			mvwprintw(trackerWindow, i + 3, 1, "(0x%x)", curOrder);
751
		}
752
		else if(i == -1 || i == 32)
753
		{
754
			wattrset(trackerWindow, A_NORMAL);
755
			wmove(trackerWindow, i + 3, 1);
756
			int a;
757
			for(a = 0; a < 5; a++)
758
			{
759
				waddch(trackerWindow, ACS_HLINE);
760
			}
761
		}
762
		wattrset(trackerWindow, A_NORMAL);
763
		waddch(trackerWindow, ACS_VLINE);
764
		
765
		int a;
766
		for(a = 0; a < 4; a++)
767
		{
768
			if(i == -2)
769
			{
770
				wattrset(trackerWindow, A_BOLD);
771
				if(curOsc == a) wattron(trackerWindow, A_REVERSE);
772
				mvwprintw(trackerWindow, i + 3, a * 10 + 7, "Osc #%i   ", a + 1);
773
				wattrset(trackerWindow, A_NORMAL);
774
			}
775
			else if(i == -1 || i == 32)
776
			{
777
				wmove(trackerWindow, i + 3, a * 10 + 7);
778
				int a;
779
				for(a = 0; a < 9; a++)
780
				{
781
					waddch(trackerWindow, ACS_HLINE);
782
				}
783
			}
784
			else
785
			{
786
				Entry entry = song.orders[curOrder].frames[i].entries[a];
787
				wattrset(trackerWindow, curFrame == i && curOsc == a && curCol == 0 ? A_REVERSE : A_NORMAL);
788
				switch(entry.noteCommand.note)
789
				{
790
					case 0x0:
791
						mvwprintw(trackerWindow, i + 3, a * 10 + 7, "---");
792
						break;
793
					case 0x1:
794
						mvwprintw(trackerWindow, i + 3, a * 10 + 7, "RES");
795
						break;
796
					case 0x2:
797
						mvwprintw(trackerWindow, i + 3, a * 10 + 7, "+++");
798
						break;
799
					case 0x3:
800
						mvwprintw(trackerWindow, i + 3, a * 10 + 7, "xxx");
801
						break;
802
					case 0x4:
803
						mvwprintw(trackerWindow, i + 3, a * 10 + 7, "C-%x", entry.noteCommand.octave);
804
						break;
805
					case 0x5:
806
						mvwprintw(trackerWindow, i + 3, a * 10 + 7, "C#%x", entry.noteCommand.octave);
807
						break;
808
					case 0x6:
809
						mvwprintw(trackerWindow, i + 3, a * 10 + 7, "D-%x", entry.noteCommand.octave);
810
						break;
811
					case 0x7:
812
						mvwprintw(trackerWindow, i + 3, a * 10 + 7, "D#%x", entry.noteCommand.octave);
813
						break;
814
					case 0x8:
815
						mvwprintw(trackerWindow, i + 3, a * 10 + 7, "E-%x", entry.noteCommand.octave);
816
						break;
817
					case 0x9:
818
						mvwprintw(trackerWindow, i + 3, a * 10 + 7, "F-%x", entry.noteCommand.octave);
819
						break;
820
					case 0xA:
821
						mvwprintw(trackerWindow, i + 3, a * 10 + 7, "F#%x", entry.noteCommand.octave);
822
						break;
823
					case 0xB:
824
						mvwprintw(trackerWindow, i + 3, a * 10 + 7, "G-%x", entry.noteCommand.octave);
825
						break;
826
					case 0xC:
827
						mvwprintw(trackerWindow, i + 3, a * 10 + 7, "G#%x", entry.noteCommand.octave);
828
						break;
829
					case 0xD:
830
						mvwprintw(trackerWindow, i + 3, a * 10 + 7, "A-%x", entry.noteCommand.octave);
831
						break;
832
					case 0xE:
833
						mvwprintw(trackerWindow, i + 3, a * 10 + 7, "A#%x", entry.noteCommand.octave);
834
						break;
835
					case 0xF:
836
						mvwprintw(trackerWindow, i + 3, a * 10 + 7, "B-%x", entry.noteCommand.octave);
837
						break;
838
				}
839
				wattrset(trackerWindow, curFrame == i && curOsc == a && curCol == 1 ? A_REVERSE : A_NORMAL);
840
				if(entry.noteCommand.applyInstrument)
841
				{
842
					wprintw(trackerWindow, "%x", entry.noteCommand.instrument);
843
				}
844
				else
845
				{
846
					wprintw(trackerWindow, "-", entry.noteCommand.instrument);
847
				}
848
				wattrset(trackerWindow, curFrame == i && curOsc == a && curCol == 2 ? A_REVERSE : A_NORMAL);
849
				if(entry.noteCommand.volume)
850
				{
851
					wprintw(trackerWindow, "%x%x", entry.noteCommand.volume >> 4, entry.noteCommand.volume & 0xF);
852
				}
853
				else
854
				{
855
					wprintw(trackerWindow, "--");
856
				}
857
				if(entry.effect.enable)
858
				{
859
					wattrset(trackerWindow, curFrame == i && curOsc == a && curCol == 3 ? A_REVERSE : A_NORMAL);
860
					wprintw(trackerWindow, "%x", entry.effect.effect & 0xF);
861
					wattrset(trackerWindow, curFrame == i && curOsc == a && curCol == 4 ? A_REVERSE : A_NORMAL);
862
					wprintw(trackerWindow, "%x%x", entry.effect.argument >> 4, entry.effect.argument & 0xF);
863
				}
864
				else
865
				{
866
					wattrset(trackerWindow, curFrame == i && curOsc == a && curCol == 3 ? A_REVERSE : A_NORMAL);
867
					wprintw(trackerWindow, "-");
868
					wattrset(trackerWindow, curFrame == i && curOsc == a && curCol == 4 ? A_REVERSE : A_NORMAL);
869
					wprintw(trackerWindow, "--");
870
				}
871
			}
872
			wattrset(trackerWindow, A_NORMAL);
873
			waddch(trackerWindow, ACS_VLINE);
874
		}
875
	}
876
	
877
	wrefresh(trackerWindow);
878
	placeCursor();
879
}
880
881
void playOrder(Order *order, int fps)
882
{
883
	int i;
884
	for(i = 0; i < sizeof(order->frames) / sizeof(Frame); i++)
885
	{
886
		curFrame = i;
887
		drawTrackerWindow();
888
		placeCursor();
889
		playFrame(&order->frames[i]);
890
		usleep(1000000 / fps);
891
	}
892
}
893
894
void drawWindows()
895
{
896
	drawOrderWindow();
897
	drawInstrumentWindow();
898
	drawEffectWindow();
899
	drawTrackerWindow();
900
	placeCursor();
901
	refresh();
902
}
903
904
void spam(int c, int y)
905
{
906
	move(y, 0);
907
	int i;
908
	for(i = 0; i < COLS; i++)
909
	{
910
		printw("%c", c);
911
	}
912
}
913
914
void drawStatus()
915
{
916
	char modeString[32];
917
	switch(curMode)
918
	{
919
		case MODE_EDIT:
920
			strcpy(modeString, "Edit");
921
			break;
922
		case MODE_PLAY:
923
			strcpy(modeString, "Play");
924
			break;
925
		case MODE_JAM:
926
			strcpy(modeString, "Jam");
927
			break;
928
	}
929
	attrset(A_NORMAL);
930
	spam(' ', LINES - 1);
931
	mvprintw(LINES - 1, 0, "MODE: %s | SPEED: %i FPS | REPEAT: 0x%x | ORDERS: %i | INSTRUMENTS: %i", modeString, song.fps, song.repeat, song.orderCount, song.instrumentCount);
932
	placeCursor();
933
	refresh();
934
}
935
936
void initWindows()
937
{
938
	w1 = COLS / 3;
939
	h1 = 10;
940
	w2 = w1 * 3;
941
	h2 = LINES - h1 - 1;
942
	orderWindow = newwin(h1, w1, 0, 0);
943
	instrumentWindow = newwin(h1, w1, 0, w1);
944
	effectWindow = newwin(h1, w1, 0, w1 * 2);
945
	trackerWindow = newwin(h2, w2, h1, 0);
946
	
947
	clear();
948
	refresh();
949
	drawWindows();
950
	drawStatus();
951
	placeCursor();
952
	refresh();
953
}
954
955
void editInput(int c)
956
{
957
	Entry *entry = &song.orders[curOrder].frames[curFrame].entries[curOsc];
958
	switch(c)
959
	{
960
		case '\t':
961
			curWindow = (curWindow + 1) % 4;
962
			drawWindows();
963
			break;
964
		default:
965
			switch(curWindow)
966
			{
967
				case WIN_ORDER:
968
					switch(c)
969
					{
970
						case KEY_DOWN:
971
							curOrder = (curOrder + 1) % song.orderCount;
972
							while(curOrder >= orderScroll + h1 - 2)
973
							{
974
								orderScroll++;
975
							}
976
							while(curOrder < orderScroll)
977
							{
978
								orderScroll--;
979
							}
980
							drawOrderWindow();
981
							drawTrackerWindow();
982
							break;
983
						case KEY_UP:
984
							curOrder = (curOrder - 1);
985
							while(curOrder < 0) curOrder += song.orderCount;
986
							while(curOrder >= orderScroll + h1 - 2)
987
							{
988
								orderScroll++;
989
							}
990
							while(curOrder < orderScroll)
991
							{
992
								orderScroll--;
993
							}
994
							drawOrderWindow();
995
							drawTrackerWindow();
996
							break;
997
						case 'r':
998
							song.repeat = curOrder;
999
							drawOrderWindow();
1000-
							curX++;
1000+
1001-
							placeCursor();
1001+
1002
							song.orderCount++;
1003
							if(song.orderCount > MAX_ORDERS) song.orderCount = MAX_ORDERS;
1004-
							curX--;
1004+
1005-
							placeCursor();
1005+
1006
							break;
1007
						case '-':
1008-
							curY++;
1008+
1009-
							placeCursor();
1009+
1010
							if(curOrder >= song.orderCount) curOrder = song.orderCount - 1;
1011
							while(curOrder >= orderScroll + h1 - 2)
1012-
							curY--;
1012+
1013-
							placeCursor();
1013+
1014
							}
1015
							while(curOrder < orderScroll)
1016
							{
1017
								orderScroll--;
1018
							}
1019
							if(song.repeat >= song.orderCount) song.repeat--;
1020
							drawOrderWindow();
1021
							drawStatus();
1022
							break;
1023
					}
1024
					break;
1025
				case WIN_INSTR:
1026
					switch(c)
1027
					{
1028
						case KEY_DOWN:
1029
							curInstrument = (curInstrument + 1) % song.instrumentCount;
1030
							while(curInstrument >= instrumentScroll + h1 - 2)
1031
							{
1032
								instrumentScroll++;
1033
							}
1034
							while(curInstrument < instrumentScroll)
1035
							{
1036
								instrumentScroll--;
1037
							}
1038
							drawInstrumentWindow();
1039
							drawEffectWindow();
1040
							break;
1041
						case KEY_UP:
1042
							curInstrument = (curInstrument - 1);
1043
							while(curInstrument < 0) curInstrument += song.instrumentCount;
1044
							while(curInstrument >= instrumentScroll + h1 - 2)
1045
							{
1046
								instrumentScroll++;
1047
							}
1048
							while(curInstrument < instrumentScroll)
1049
							{
1050
								instrumentScroll--;
1051
							}
1052
							drawInstrumentWindow();
1053
							drawEffectWindow();
1054-
	while(true)
1054+
1055
						case '=':
1056
							song.instrumentCount++;
1057
							if(song.instrumentCount > MAX_INSTRUMENTS) song.instrumentCount = MAX_INSTRUMENTS;
1058
							drawInstrumentWindow();
1059
							drawStatus();
1060
							break;
1061
						case '-':
1062
							song.instrumentCount--;
1063
							if(song.instrumentCount <= 0) song.instrumentCount = 1;
1064
							if(curInstrument >= song.instrumentCount) curInstrument = song.instrumentCount - 1;
1065
							while(curInstrument >= instrumentScroll + h1 - 2)
1066
							{
1067
								orderScroll++;
1068
							}
1069
							while(curInstrument < instrumentScroll)
1070
							{
1071
								instrumentScroll--;
1072
							}
1073
							drawInstrumentWindow();
1074
							drawStatus();
1075
							break;
1076
					}
1077
					break;
1078
				case WIN_EFFECT:
1079
					switch(c)
1080
					{
1081
						case KEY_DOWN:
1082
							curEffect = (curEffect + 1) % 8;
1083
							drawEffectWindow();
1084
							break;
1085
						case KEY_UP:
1086
							curEffect = (curEffect - 1);
1087
							while(curEffect < 0) curEffect += 8;
1088
							drawEffectWindow();
1089
							break;
1090
						case KEY_RIGHT:
1091
							if(song.instruments[curInstrument].effects[curEffect].enable)
1092
							{
1093
								song.instruments[curInstrument].effects[curEffect].effect++;
1094
								if(song.instruments[curInstrument].effects[curEffect].effect > 0xF) song.instruments[curInstrument].effects[curEffect].effect = 0xF;
1095
							}
1096
							else
1097
							{
1098
								song.instruments[curInstrument].effects[curEffect].enable = 1;
1099
							}
1100
							drawEffectWindow();
1101
							break;
1102
						case KEY_LEFT:
1103
							if(song.instruments[curInstrument].effects[curEffect].enable)
1104
							{
1105
								song.instruments[curInstrument].effects[curEffect].effect--;
1106
								if(song.instruments[curInstrument].effects[curEffect].effect > 0xF)
1107
								{
1108
									song.instruments[curInstrument].effects[curEffect].effect = 0;
1109
									song.instruments[curInstrument].effects[curEffect].enable = 0;
1110
								}
1111
								drawEffectWindow();
1112
							}
1113
							break;
1114
						case '=':
1115
							if(song.instruments[curInstrument].effects[curEffect].enable)
1116
							{
1117
								song.instruments[curInstrument].effects[curEffect].argument++;
1118
								drawEffectWindow();
1119
							}
1120
							break;
1121
						case '-':
1122
							if(song.instruments[curInstrument].effects[curEffect].enable)
1123
							{
1124
								song.instruments[curInstrument].effects[curEffect].argument--;
1125
								drawEffectWindow();
1126
							}
1127
							break;
1128
						case ']':
1129
							if(song.instruments[curInstrument].effects[curEffect].enable)
1130
							{
1131
								song.instruments[curInstrument].effects[curEffect].argument += 0x10;
1132
								drawEffectWindow();
1133
							}
1134
							break;
1135
						case '[':
1136
							if(song.instruments[curInstrument].effects[curEffect].enable)
1137
							{
1138
								song.instruments[curInstrument].effects[curEffect].argument -= 0x10;
1139
								drawEffectWindow();
1140
							}
1141
							break;
1142
						}
1143
					break;
1144
				case WIN_TRACKER:
1145
					switch(c)
1146
					{
1147
						case KEY_F(1):
1148
							curOsc = 0;
1149
							drawTrackerWindow();
1150
							break;
1151
						case KEY_F(2):
1152
							curOsc = 1;
1153
							drawTrackerWindow();
1154
							break;
1155
						case KEY_F(3):
1156
							curOsc = 2;
1157
							drawTrackerWindow();
1158
							break;
1159
						case KEY_F(4):
1160
							curOsc = 3;
1161
							drawTrackerWindow();
1162
							break;
1163
						case KEY_RIGHT:
1164
							curCol++;
1165
							if(curCol > 4)
1166
							{
1167
								curCol = 0;
1168
								curOsc = (curOsc + 1) % 4;
1169
							}
1170
							drawTrackerWindow();
1171
							break;
1172
						case KEY_LEFT:
1173
							curCol--;
1174
							if(curCol < 0)
1175
							{
1176
								curCol = 4;
1177
								curOsc--;
1178
								if(curOsc < 0) curOsc = 3;
1179
							}
1180
							drawTrackerWindow();
1181
							break;
1182
						case KEY_DOWN:
1183
							curFrame = (curFrame + 1) % 32;
1184
							drawTrackerWindow();
1185
							break;
1186
						case KEY_UP:
1187
							curFrame--;
1188
							if(curFrame < 0) curFrame = 31;
1189
							drawTrackerWindow();
1190
							break;
1191
						case 'p':
1192
							playEntry(entry, curOsc);
1193
							break;
1194
						default:
1195
							switch(curCol)
1196
							{
1197
								case 0:
1198
									switch(c)
1199
									{
1200
										case KEY_BACKSPACE:
1201
											entry->noteCommand.note = NOTE_NULL;
1202
											break;
1203
										case '`':
1204
											if(entry->noteCommand.note == NOTE_OFF)
1205
											{
1206
												entry->noteCommand.note = NOTE_ON;
1207
											}
1208
											else
1209
											{
1210
												entry->noteCommand.note = NOTE_OFF;
1211
											}
1212
											break;
1213
										case '0':
1214
											entry->noteCommand.octave = 0;
1215
											break;
1216
										case '1':
1217
											entry->noteCommand.octave = 1;
1218
											break;
1219
										case '2':
1220
											entry->noteCommand.octave = 2;
1221
											break;
1222
										case '3':
1223
											entry->noteCommand.octave = 3;
1224
											break;
1225
										case '4':
1226
											entry->noteCommand.octave = 4;
1227
											break;
1228
										case '5':
1229
											entry->noteCommand.octave = 5;
1230
											break;
1231
										case '6':
1232
											entry->noteCommand.octave = 6;
1233
											break;
1234
										case '7':
1235
											entry->noteCommand.octave = 7;
1236
											break;
1237
										case 'a':
1238
											entry->noteCommand.note = NOTE_C;
1239
											break;
1240
										case 'w':
1241
											entry->noteCommand.note = NOTE_Cs;
1242
											break;
1243
										case 's':
1244
											entry->noteCommand.note = NOTE_D;
1245
											break;
1246
										case 'e':
1247
											entry->noteCommand.note = NOTE_Ds;
1248
											break;
1249
										case 'd':
1250
											entry->noteCommand.note = NOTE_E;
1251
											break;
1252
										case 'f':
1253
											entry->noteCommand.note = NOTE_F;
1254
											break;
1255
										case 't':
1256
											entry->noteCommand.note = NOTE_Fs;
1257
											break;
1258
										case 'g':
1259
											entry->noteCommand.note = NOTE_G;
1260
											break;
1261
										case 'y':
1262
											entry->noteCommand.note = NOTE_Gs;
1263
											break;
1264
										case 'h':
1265
											entry->noteCommand.note = NOTE_A;
1266
											break;
1267
										case 'u':
1268
											entry->noteCommand.note = NOTE_As;
1269
											break;
1270
										case 'j':
1271
											entry->noteCommand.note = NOTE_B;
1272
											break;
1273
										case 'k':
1274
											entry->noteCommand.note = NOTE_C;
1275
											break;
1276
										case 'r':
1277
											entry->noteCommand.note = NOTE_RESET;
1278
											break;
1279
										case '=':
1280
											if(entry->noteCommand.note == NOTE_B)
1281
											{
1282
												entry->noteCommand.note = NOTE_C;
1283
												entry->noteCommand.octave = (entry->noteCommand.octave + 1) % 8;
1284
											}
1285
											else if(entry->noteCommand.note > 3)
1286
											{
1287
												entry->noteCommand.note++;
1288
											}
1289
											break;
1290
										case '-':
1291
											if(entry->noteCommand.note == 4)
1292
											{
1293
												entry->noteCommand.note = 15;
1294
												if(entry->noteCommand.octave == 0)
1295
												{
1296
													entry->noteCommand.octave = 7;
1297
												}
1298
												else
1299
												{
1300
													entry->noteCommand.octave--;
1301
												}
1302
											}
1303
											else if(entry->noteCommand.note > 4)
1304
											{
1305
												entry->noteCommand.note--;
1306
											}
1307
											break;
1308
										case ']':
1309
											entry->noteCommand.octave = (entry->noteCommand.octave + 1) % 8;
1310
											break;
1311
										case '[':
1312
											if(entry->noteCommand.octave == 0)
1313
											{
1314
												entry->noteCommand.octave = 7;
1315
											}
1316
											else
1317
											{
1318
												entry->noteCommand.octave--;
1319
											}
1320
											break;
1321
									}
1322
									break;
1323
								case 1:
1324
									switch(c)
1325
									{
1326
										case KEY_BACKSPACE:
1327
											entry->noteCommand.applyInstrument = 0;
1328
											break;
1329
										case '0':
1330
											entry->noteCommand.instrument = 0;
1331
											entry->noteCommand.applyInstrument = 1;
1332
											break;
1333
										case '1':
1334
											entry->noteCommand.instrument = 1;
1335
											entry->noteCommand.applyInstrument = 1;
1336
											break;
1337
										case '2':
1338
											entry->noteCommand.instrument = 2;
1339
											entry->noteCommand.applyInstrument = 1;
1340
											break;
1341
										case '3':
1342
											entry->noteCommand.instrument = 3;
1343
											entry->noteCommand.applyInstrument = 1;
1344
											break;
1345
										case '4':
1346
											entry->noteCommand.instrument = 4;
1347
											entry->noteCommand.applyInstrument = 1;
1348
											break;
1349
										case '5':
1350
											entry->noteCommand.instrument = 5;
1351
											entry->noteCommand.applyInstrument = 1;
1352
											break;
1353
										case '6':
1354
											entry->noteCommand.instrument = 6;
1355
											entry->noteCommand.applyInstrument = 1;
1356
											break;
1357
										case '7':
1358
											entry->noteCommand.instrument = 7;
1359
											entry->noteCommand.applyInstrument = 1;
1360
											break;
1361
										case '=':
1362
											entry->noteCommand.instrument = (entry->noteCommand.instrument + 1) % 8;
1363
											break;
1364
										case '-':
1365
											if(entry->noteCommand.instrument == 0)
1366
											{
1367
												entry->noteCommand.instrument = 7;
1368
											}
1369
											else
1370
											{
1371
												entry->noteCommand.instrument--;
1372
											}
1373
											break;
1374
									}
1375
									break;
1376
								case 2:
1377
									switch(c)
1378
									{
1379
										case KEY_BACKSPACE:
1380
											entry->noteCommand.volume = 0;
1381
											break;
1382
										case '0':
1383
											entry->noteCommand.volume = 0;
1384
											break;
1385
										case '`':
1386
											entry->noteCommand.volume = 31;
1387
											break;
1388
										case '=':
1389
											entry->noteCommand.volume = (entry->noteCommand.volume + 1) % 32;
1390
											break;
1391
										case '-':
1392
											if(entry->noteCommand.volume == 0)
1393
											{
1394
												entry->noteCommand.volume = 31;
1395
											}
1396
											else
1397
											{
1398
												entry->noteCommand.volume--;
1399
											}
1400
											break;
1401
										case ']':
1402
											entry->noteCommand.volume = (entry->noteCommand.volume + 0x10) % 32;
1403
											break;
1404
										case '[':
1405
											if(entry->noteCommand.volume <= 0x10)
1406
											{
1407
												entry->noteCommand.volume = 31;
1408
											}
1409
											else
1410
											{
1411
												entry->noteCommand.volume -= 0x10;
1412
											}
1413
											break;
1414
									}
1415
									break;
1416
								case 3:
1417
									switch(c)
1418
									{
1419
										case KEY_BACKSPACE:
1420
											entry->effect.enable = 0;
1421
											break;
1422
										case '0':
1423
											entry->effect.effect = 0;
1424
											entry->effect.enable = 1;
1425
											break;
1426
										case '1':
1427
											entry->effect.effect = 1;
1428
											entry->effect.enable = 1;
1429
											break;
1430
										case '2':
1431
											entry->effect.effect = 2;
1432
											entry->effect.enable = 1;
1433
											break;
1434
										case '3':
1435
											entry->effect.effect = 3;
1436
											entry->effect.enable = 1;
1437
											break;
1438
										case '4':
1439
											entry->effect.effect = 4;
1440
											entry->effect.enable = 1;
1441
											break;
1442
										case '5':
1443
											entry->effect.effect = 5;
1444
											entry->effect.enable = 1;
1445
											break;
1446
										case '6':
1447
											entry->effect.effect = 6;
1448
											entry->effect.enable = 1;
1449
											break;
1450
										case '7':
1451
											entry->effect.effect = 7;
1452
											entry->effect.enable = 1;
1453
											break;
1454
										case '8':
1455
											entry->effect.effect = 8;
1456
											entry->effect.enable = 1;
1457
											break;
1458
										case '9':
1459
											entry->effect.effect = 9;
1460
											entry->effect.enable = 1;
1461
											break;
1462
										case 'a':
1463
											entry->effect.effect = 0xA;
1464
											entry->effect.enable = 1;
1465
											break;
1466
										case 'b':
1467
											entry->effect.effect = 0xB;
1468
											entry->effect.enable = 1;
1469
											break;
1470
										case 'c':
1471
											entry->effect.effect = 0xC;
1472
											entry->effect.enable = 1;
1473
											break;
1474
										case 'd':
1475
											entry->effect.effect = 0xD;
1476
											entry->effect.enable = 1;
1477
											break;
1478
										case 'e':
1479
											entry->effect.effect = 0xE;
1480
											entry->effect.enable = 1;
1481
											break;
1482
										case 'f':
1483
											entry->effect.effect = 0xF;
1484
											entry->effect.enable = 1;
1485
											break;
1486
										case '=':
1487
											entry->effect.effect = (entry->effect.effect + 1) % 0x10;
1488
											entry->effect.enable = 1;
1489
											break;
1490
										case '-':
1491
											if(entry->effect.effect == 0)
1492
											{
1493
												entry->effect.effect = 0xF;
1494
											}
1495
											else
1496
											{
1497
												entry->effect.effect--;
1498
											}
1499
											entry->effect.enable = 1;
1500
											break;
1501
									}
1502
									break;
1503
								case 4:
1504
									switch(c)
1505
									{
1506
										case KEY_BACKSPACE:
1507
											entry->effect.enable = 0;
1508
											break;
1509
										case '0':
1510
											entry->effect.argument = 0;
1511
											entry->effect.enable = 1;
1512
											break;
1513
										case '=':
1514
											entry->effect.argument++;
1515
											entry->effect.enable = 1;
1516
											break;
1517
										case '-':
1518
											entry->effect.argument--;
1519
											entry->effect.enable = 1;
1520
											break;
1521
										case ']':
1522
											entry->effect.argument += 0x10;
1523
											entry->effect.enable = 1;
1524
											break;
1525
										case '[':
1526
											entry->effect.argument -= 0x10;
1527
											entry->effect.enable = 1;
1528
											break;
1529
									}
1530
									break;
1531
							}
1532
							drawTrackerWindow();
1533
					}
1534
					break;
1535
			}
1536
	}
1537
}
1538
1539
void playInput(int c)
1540
{
1541
	
1542
}
1543
1544
void jamInput(int c)
1545
{
1546
	
1547
}
1548
1549
void editMode()
1550
{
1551
	curMode = MODE_EDIT;
1552
	drawWindows();
1553
	drawStatus();
1554
}
1555
1556
void playMode()
1557
{
1558
	curMode = MODE_PLAY;
1559
	drawWindows();
1560
	drawStatus();
1561
}
1562
1563
void jamMode()
1564
{
1565
	curMode = MODE_JAM;
1566
	drawWindows();
1567
	drawStatus();
1568
}
1569
1570
void broadcastEffect(Effect effect)
1571
{
1572
	sendEffectCommand(&effect, 0);
1573
	sendEffectCommand(&effect, 1);
1574
	sendEffectCommand(&effect, 2);
1575
	sendEffectCommand(&effect, 3);
1576
}
1577
1578
void resetEffects()
1579
{
1580
	broadcastEffect(newEffect(0x0, 0x00));
1581
	broadcastEffect(newEffect(0x1, 0x00));
1582
	broadcastEffect(newEffect(0x2, 0x00));
1583
	broadcastEffect(newEffect(0x3, 0x00));
1584
	broadcastEffect(newEffect(0x4, 0x00));
1585
	broadcastEffect(newEffect(0x5, 0x00));
1586
	broadcastEffect(newEffect(0x6, 0x7F));
1587
	broadcastEffect(newEffect(0x7, 0x00));
1588
	broadcastEffect(newEffect(0x8, 0x00));
1589
	broadcastEffect(newEffect(0x9, 0x00));
1590
	broadcastEffect(newEffect(0xA, 0x00));
1591
	broadcastEffect(newEffect(0xB, 0x00));
1592
	broadcastEffect(newEffect(0xC, 0xFF));
1593
	broadcastEffect(newEffect(0xD, 0x00));
1594
	broadcastEffect(newEffect(0xE, 0xF0));
1595
	broadcastEffect(newEffect(0xF, 0x00));
1596
}
1597
1598
Frame quietFrame;
1599
1600
void reset()
1601
{
1602
	playFrame(&quietFrame);
1603
	resetEffects();
1604
}
1605
1606
void playCurrentFrame()
1607
{
1608
	Frame f = song.orders[curOrder].frames[curFrame];
1609
	playFrame(&f);
1610
}
1611
1612
void playCurrentOrder()
1613
{
1614
	Order o = song.orders[curOrder];
1615
	playOrder(&o, song.fps);
1616
}
1617
1618
void inputLoop()
1619
{
1620
	quietFrame = newQuietFrame();
1621
	int e = 1;
1622
	while(e)
1623
	{
1624
		int c = getch();
1625
		switch(c)
1626
		{
1627
			case KEY_F(5):
1628
				reset();
1629
				break;
1630
			case KEY_F(6):
1631
				playNote(NOTE_C, 3, 0xFF, 0);
1632
				playNote(NOTE_E, 4, 0xFF, 1);
1633
				playNote(NOTE_G, 3, 0xFF, 2);
1634
				playNote(NOTE_Bb, 4, 0xFF, 3);
1635
				break;
1636
			case KEY_F(7):
1637
				playCurrentFrame();
1638
				break;
1639
			case KEY_F(8):
1640
				playCurrentOrder();
1641
				break;
1642
			case 'q':
1643
				e = 0;
1644
				break;
1645
			case KEY_RESIZE:
1646
				initWindows();
1647
				break;
1648
			case '\n':
1649
				if(curMode == MODE_PLAY)
1650
				{
1651
					editMode();
1652
				}
1653
				else
1654
				{
1655
					playMode();
1656
				}
1657
				break;
1658
			case ' ':
1659
				if(curMode == MODE_JAM)
1660
				{
1661
					editMode();
1662
				}
1663
				else
1664
				{
1665
					jamMode();
1666
				}
1667
				break;
1668
			default:
1669
				switch(curMode)
1670
				{
1671
					case MODE_EDIT:
1672
						editInput(c);
1673
						break;
1674
					case MODE_PLAY:
1675
						playInput(c);
1676
						break;
1677
					case MODE_JAM:
1678
						jamInput(c);
1679
						break;
1680
				}
1681
		}
1682
	}
1683
}
1684
1685
void gui()
1686
{
1687
	initscr();
1688
	clear();
1689
	noecho();
1690
	cbreak();
1691
	keypad(stdscr, TRUE);
1692
	nodelay(stdscr, TRUE);
1693
	refresh();
1694
	
1695
	initWindows();
1696
	inputLoop();
1697
	
1698
	endwin();
1699
}
1700
1701
void initSong()
1702
{
1703
	song.fps = 8;
1704
	song.repeat = 0;
1705
	song.orderCount = 1;
1706
	song.instrumentCount = 1;
1707
	
1708
	Order orders[MAX_ORDERS];
1709
	song.orders = orders;
1710
	
1711
	Instrument instruments[MAX_INSTRUMENTS];
1712
	song.instruments = instruments;
1713
}
1714
1715
int main(int argc, char *argv[])
1716
{
1717
	if(argc > 1)
1718
	{
1719
		strcpy(serialPort, argv[1]);
1720
	}
1721
	else
1722
	{
1723
		printf("Enter full path to serial device: ");
1724
		scanf("%s", serialPort);
1725
	}
1726
	
1727
	if(out = fopen(serialPort, "w"))
1728
	{
1729
		initSong();
1730
		reset();
1731
		gui();
1732
		reset();
1733
		fclose(out);
1734
	}
1735
	else
1736
	{
1737
		printf("Unable to open file!\n");
1738
		exit(1);
1739
	}
1740
	
1741
	return 0;
1742
}