1 /*
2  * Schism Tracker - a cross-platform Impulse Tracker clone
3  * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
4  * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
5  * copyright (c) 2009 Storlek & Mrs. Brisby
6  * copyright (c) 2010-2012 Storlek
7  * URL: http://schismtracker.org/
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23 
24 #include "headers.h"
25 
26 #include "it.h"
27 #include "page.h"
28 #include "midi.h"
29 #include "song.h"
30 
31 /* --------------------------------------------------------------------- */
32 
33 static struct widget widgets_midiout[33];
34 static int zxx_top = 0;
35 static midi_config_t editcfg;
36 
37 /* --------------------------------------------------------------------- */
38 
midiout_draw_const(void)39 static void midiout_draw_const(void)
40 {
41 	char buf[4] = "SFx";
42 	int i;
43 
44 	draw_text(    "MIDI Start", 6, 13, 0, 2);
45 	draw_text(     "MIDI Stop", 7, 14, 0, 2);
46 	draw_text(     "MIDI Tick", 7, 15, 0, 2);
47 	draw_text(       "Note On", 9, 16, 0, 2);
48 	draw_text(      "Note Off", 8, 17, 0, 2);
49 	draw_text( "Change Volume", 3, 18, 0, 2);
50 	draw_text(    "Change Pan", 6, 19, 0, 2);
51 	draw_text(   "Bank Select", 5, 20, 0, 2);
52 	draw_text("Program Change", 2, 21, 0, 2);
53 
54 	draw_text(   "Macro   SF0", 5, 24, 0, 2);
55 	draw_text(   "Setup   SF1", 5, 25, 0, 2);
56 
57 	for (i = 2; i < 16; i++) {
58 		buf[2] = hexdigits[i];
59 		draw_text(buf, 13, i + 24, 0, 2);
60 	}
61 
62 	draw_box(16, 12, 60, 22, BOX_THIN|BOX_INNER|BOX_INSET);
63 	draw_box(16, 23, 60, 40, BOX_THIN|BOX_INNER|BOX_INSET);
64 	draw_box(16, 41, 60, 49, BOX_THIN|BOX_INNER|BOX_INSET);
65 
66 	for (i = 0; i < 7; i++) {
67 		sprintf(buf, "Z%02X", i + zxx_top + 0x80);
68 		draw_text(buf, 13, i + 42, 0, 2);
69 	}
70 }
71 
copy_out(void)72 static void copy_out(void)
73 {
74 	song_lock_audio();
75 	memcpy(&current_song->midi_config, &editcfg, sizeof(midi_config_t));
76 	song_unlock_audio();
77 }
78 
copy_in(void)79 static void copy_in(void)
80 {
81 	song_lock_audio();
82 	memcpy(&editcfg, &current_song->midi_config, sizeof(midi_config_t));
83 	song_unlock_audio();
84 }
85 
zxx_setpos(int pos)86 static void zxx_setpos(int pos)
87 {
88 	int i;
89 
90 	/* 128 items, scrolled on 7 lines */
91 	pos = CLAMP(pos, 0, 128 - 7);
92 	if (zxx_top == pos)
93 		return;
94 	zxx_top = pos;
95 	for (i = 0; i < 7; i++)
96 		widgets_midiout[25 + i].d.textentry.text = editcfg.zxx[zxx_top + i];
97 
98 	status.flags |= NEED_UPDATE;
99 }
100 
101 
pre_handle_key(struct key_event * k)102 static int pre_handle_key(struct key_event *k)
103 {
104 	if (*selected_widget == 25 && k->sym == SDLK_UP) {
105 		/* scroll up */
106 		if (k->state == KEY_RELEASE)
107 			return 1;
108 		if (zxx_top == 0)
109 			return 0; /* let the normal key handler catch it and change focus */
110 		zxx_setpos(zxx_top - 1);
111 		return 1;
112 	}
113 	if (*selected_widget == 31 && k->sym == SDLK_DOWN) {
114 		/* scroll down */
115 		if (k->state == KEY_RELEASE)
116 			return 1;
117 		zxx_setpos(zxx_top + 1);
118 		return 1;
119 	}
120 	if ((*selected_widget) >= 25) {
121 		switch (k->sym) {
122 		case SDLK_PAGEUP:
123 			if (k->state == KEY_RELEASE)
124 				return 1;
125 			zxx_setpos(zxx_top - 7);
126 			return 1;
127 		case SDLK_PAGEDOWN:
128 			if (k->state == KEY_RELEASE)
129 				return 1;
130 			zxx_setpos(zxx_top + 7);
131 			return 1;
132 		default:
133 			break;
134 		};
135 	}
136 	return 0;
137 }
138 
midiout_set_page(void)139 static void midiout_set_page(void)
140 {
141 	copy_in();
142 }
143 
midiout_load_page(struct page * page)144 void midiout_load_page(struct page *page)
145 {
146 	int i;
147 
148 	page->title = "MIDI Output Configuration";
149 	page->draw_const = midiout_draw_const;
150 	page->set_page = midiout_set_page;
151 	page->pre_handle_key = pre_handle_key;
152 	page->total_widgets = 32;
153 	page->widgets = widgets_midiout;
154 	page->help_index = HELP_MIDI_OUTPUT;
155 
156 	char *editcfg_top[] = {
157 		editcfg.start, editcfg.stop, editcfg.tick, editcfg.note_on, editcfg.note_off,
158 		editcfg.set_volume, editcfg.set_panning, editcfg.set_bank, editcfg.set_program,
159 	};
160 
161 	for (i = 0; i < 9; i++) {
162 		create_textentry(widgets_midiout + i, 17, 13 + i, 43,
163 				(i == 0 ? 0 : (i - 1)), i + 1, 9,
164 				copy_out, editcfg_top[i], 31);
165 	}
166 	for (i = 0; i < 16; i++) {
167 		create_textentry(widgets_midiout + 9 + i, 17, 24 + i, 43,
168 				9 + i - 1, 9 + i + 1, 25,
169 				copy_out, editcfg.sfx[i], 31);
170 	}
171 	for (i = 0; i < 7; i++) {
172 		create_textentry(widgets_midiout + 25 + i, 17, 42 + i, 43,
173 				25 + i - 1, 25 + ((i == 6) ? 6 : (i + 1)), 0,
174 				copy_out, editcfg.zxx[i], 31);
175 	}
176 }
177 
178