コード例 #1
0
ファイル: midi-core.c プロジェクト: CharlesLio/schismtracker
int midi_engine_handle_event(void *ev)
{
        struct key_event kk = {.is_synthetic = 0};
        int *st;
        SDL_Event *e = ev;

        if (e->type != SCHISM_EVENT_MIDI)
                return 0;

        st = e->user.data1;
        if (midi_flags & MIDI_DISABLE_RECORD) {
                free(e->user.data1);
                return 1;
        }

        switch (e->user.code) {
        case SCHISM_EVENT_MIDI_NOTE:
                if (st[0] == MIDI_NOTEON) {
                        kk.state = KEY_PRESS;
                } else {
                        if (!(midi_flags & MIDI_RECORD_NOTEOFF)) {
                                /* don't record noteoff? okay... */
                                break;
                        }
                        kk.state = KEY_RELEASE;
                }
                kk.midi_channel = st[1]+1;
                kk.midi_note = (st[2]+1 + midi_c5note) - 60;
                if (midi_flags & MIDI_RECORD_VELOCITY)
                        kk.midi_volume = st[3];
                else
                        kk.midi_volume = 128;
                kk.midi_volume = (kk.midi_volume * midi_amplification) / 100;
                handle_key(&kk);
                break;
        case SCHISM_EVENT_MIDI_PITCHBEND:
                /* wheel */
                kk.midi_channel = st[1]+1;
                kk.midi_volume = -1;
                kk.midi_note = -1;
                kk.midi_bend = st[0];
                handle_key(&kk);
                break;
        case SCHISM_EVENT_MIDI_CONTROLLER:
                /* controller events */
                break;
        case SCHISM_EVENT_MIDI_SYSTEM:
                switch (st[0]) {
                case 0x8: /* MIDI tick */
                        break;
                case 0xA: /* MIDI start */
                case 0xB: /* MIDI continue */
                        song_start();
                        break;
                case 0xC: /* MIDI stop */
                case 0xF: /* MIDI reset */
                        /* this is helpful when miditracking */
                        song_stop();
                        break;
                };
        case SCHISM_EVENT_MIDI_SYSEX:
                /* but missing the F0 and the stop byte (F7) */
                //len = *((unsigned int *)e->user.data1);
                //sysex = ((char *)e->user.data1)+sizeof(unsigned int);
                break;

        default:
                break;
        }
        free(e->user.data1);

        return 1;
}
コード例 #2
0
ファイル: page.c プロジェクト: HybridDog/schismtracker
/* returns 1 if the key was handled */
static int handle_key_global(struct key_event * k)
{
	int i, ins_mode;

	if (_mp_active == 2 && (k->mouse == MOUSE_CLICK && k->state == KEY_RELEASE)) {
		status.flags |= NEED_UPDATE;
		dialog_destroy_all();
		_mp_active = 0;
		// eat it...
		return 1;
	}
	if ((!_mp_active) && k->state == KEY_PRESS && k->mouse == MOUSE_CLICK) {
		if (k->x >= 63 && k->x <= 77 && k->y >= 6 && k->y <= 7) {
			status.vis_style++;
			status.vis_style %= VIS_SENTINEL;
			status.flags |= NEED_UPDATE;
			return 1;
		} else if (k->y == 5 && k->x == 50) {
			minipop_slide(kbd_get_current_octave(), "Octave", 0, 8,
				kbd_set_current_octave, NULL, 50, 5);
			return 1;
		} else if (k->y == 4 && k->x >= 50 && k->x <= 52) {
			minipop_slide(song_get_current_speed(), "Speed", 1, 255,
				song_set_current_speed, song_set_initial_speed, 51, 4);
			return 1;
		} else if (k->y == 4 && k->x >= 54 && k->x <= 56) {
			minipop_slide(song_get_current_tempo(), "Tempo", 32, 255,
				song_set_current_tempo, song_set_initial_tempo, 55, 4);
			return 1;
		} else if (k->y == 3 && k->x >= 50 && k-> x <= 77) {
			if (page_is_instrument_list(status.current_page)
			    || status.current_page == PAGE_SAMPLE_LIST
			    || (!(status.flags & CLASSIC_MODE)
				&& (status.current_page == PAGE_ORDERLIST_PANNING
				    || status.current_page == PAGE_ORDERLIST_VOLUMES)))
				ins_mode = 0;
			else
				ins_mode = song_is_instrument_mode();
			if (ins_mode) {
				minipop_slide(instrument_get_current(), "!",
					status.current_page == PAGE_INSTRUMENT_LIST ? 1 : 0,
					99 /* FIXME */, instrument_set, NULL, 58, 3);
			} else {
				minipop_slide(sample_get_current(), "@",
					status.current_page == PAGE_SAMPLE_LIST ? 1 : 0,
					99 /* FIXME */, sample_set, NULL, 58, 3);
			}

		} else if (k->y == 7 && k->x >= 11 && k->x <= 17) {
			minipop_slide(get_current_row(), "Row",
				0, song_get_rows_in_pattern(get_current_pattern()),
				set_current_row, NULL, 14, 7);
			return 1;
		} else if (k->y == 6 && k->x >= 11 && k->x <= 17) {
			minipop_slide(get_current_pattern(), "Pattern",
				0, csf_get_num_patterns(current_song),
				set_current_pattern, NULL, 14, 6);
			return 1;
		} else if (k->y == 5 && k->x >= 11 && k->x <= 17) {
			minipop_slide(song_get_current_order(), "Order",
				0, csf_get_num_orders(current_song),
				set_current_order, NULL, 14, 5);
			return 1;
		}
	} else if ((!_mp_active) && k->mouse == MOUSE_DBLCLICK) {
		if (k->y == 4 && k->x >= 11 && k->x <= 28) {
			set_page(PAGE_SAVE_MODULE);
			return 1;
		} else if (k->y == 3 && k->x >= 11 && k->x <= 35) {
			set_page(PAGE_SONG_VARIABLES);
			return 1;
		}
	}

	/* shortcut */
	if (k->mouse != MOUSE_NONE) {
		return 0;
	}

	/* first, check the truly global keys (the ones that still work if
	 * a dialog's open) */
	switch (k->sym) {
	case SDLK_RETURN:
		if ((k->mod & KMOD_CTRL) && k->mod & KMOD_ALT) {
			if (k->state == KEY_PRESS)
				return 1;
			toggle_display_fullscreen();
			return 1;
		}
		break;
	case SDLK_m:
		if (k->mod & KMOD_CTRL) {
			if (k->state == KEY_RELEASE)
				return 1;
			video_mousecursor(MOUSE_CYCLE_STATE);
			return 1;
		}
		break;

	case SDLK_d:
		if (k->mod & KMOD_CTRL) {
			if (k->state == KEY_RELEASE)
				return 1; /* argh */
			i = SDL_WM_GrabInput(SDL_GRAB_QUERY);
			if (i == SDL_GRAB_QUERY)
				i = currently_grabbed;
			currently_grabbed = i = (i != SDL_GRAB_ON ? SDL_GRAB_ON : SDL_GRAB_OFF);
			SDL_WM_GrabInput(i);
			status_text_flash(i
				? "Mouse and keyboard grabbed, press Ctrl+D to release"
				: "Mouse and keyboard released");
			return 1;
		}
		break;

	case SDLK_i:
		/* reset audio stuff? */
		if (k->mod & KMOD_CTRL) {
			if (k->state == KEY_RELEASE)
				return 1;
			audio_reinit();
			return 1;
		}
		break;
	case SDLK_e:
		/* This should reset everything display-related. */
		if (k->mod & KMOD_CTRL) {
			if (k->state == KEY_RELEASE)
				return 1;
			font_init();
			status.flags |= NEED_UPDATE;
			return 1;
		}
		break;
	case SDLK_HOME:
		if (!(k->mod & KMOD_ALT)) break;
		if (status.flags & DISKWRITER_ACTIVE) break;
		if (k->state == KEY_RELEASE)
			return 0;
		kbd_set_current_octave(kbd_get_current_octave() - 1);
		return 1;
	case SDLK_END:
		if (!(k->mod & KMOD_ALT)) break;
		if (status.flags & DISKWRITER_ACTIVE) break;
		if (k->state == KEY_RELEASE)
			return 0;
		kbd_set_current_octave(kbd_get_current_octave() + 1);
		return 1;
	default:
		break;
	}

	/* next, if there's no dialog, check the rest of the keys */
	if (status.flags & DISKWRITER_ACTIVE) return 0;

	switch (k->sym) {
	case SDLK_q:
		if (status.dialog_type != DIALOG_NONE)
			return 0;
		if (k->mod & KMOD_CTRL) {
			_mp_finish(NULL);
			if (k->state == KEY_PRESS)
				show_exit_prompt();
			return 1;
		}
		break;
	case SDLK_n:
		if (status.dialog_type != DIALOG_NONE)
			return 0;
		if (k->mod & KMOD_CTRL) {
			_mp_finish(NULL);
			if (k->state == KEY_PRESS)
				new_song_dialog();
			return 1;
		}
		break;
	case SDLK_g:
		if (status.dialog_type != DIALOG_NONE)
			return 0;
		if (k->mod & KMOD_CTRL) {
			_mp_finish(NULL);
			if (k->state == KEY_PRESS)
				show_song_timejump();
			return 1;
		}
		break;
	case SDLK_p:
		if (status.dialog_type != DIALOG_NONE)
			return 0;
		if (k->mod & KMOD_CTRL) {
			_mp_finish(NULL);
			if (k->state == KEY_PRESS)
				show_song_length();
			return 1;
		}
		break;
	case SDLK_F1:
		if (status.dialog_type != DIALOG_NONE)
			return 0;
		if (k->mod & KMOD_CTRL) {
			_mp_finish(NULL);
			if (k->state == KEY_PRESS)
				set_page(PAGE_CONFIG);
		} else if (k->mod & KMOD_SHIFT) {
			_mp_finish(NULL);
			if (k->state == KEY_PRESS)
				set_page(status.current_page == PAGE_MIDI ? PAGE_MIDI_OUTPUT : PAGE_MIDI);
		} else if (NO_MODIFIER(k->mod)) {
			_mp_finish(NULL);
			if (k->state == KEY_PRESS)
				set_page(PAGE_HELP);
		} else {
			break;
		}
		return 1;
	case SDLK_F2:
		if (k->mod & KMOD_CTRL) {
			if (status.current_page == PAGE_PATTERN_EDITOR) {
				_mp_finish(NULL);
				if (k->state == KEY_PRESS && status.dialog_type == DIALOG_NONE) {
					pattern_editor_length_edit();
				}
				return 1;
			}
			if (status.dialog_type != DIALOG_NONE)
				return 0;
		} else if (NO_MODIFIER(k->mod)) {
			if (status.current_page == PAGE_PATTERN_EDITOR) {
				if (k->state == KEY_PRESS) {
					if (status.dialog_type & DIALOG_MENU) {
						return 0;
					} else if (status.dialog_type != DIALOG_NONE) {
						dialog_yes_NULL();
						status.flags |= NEED_UPDATE;
					} else {
						_mp_finish(NULL);
						pattern_editor_display_options();
					}
				}
			} else {
				if (status.dialog_type != DIALOG_NONE)
					return 0;
				_mp_finish(NULL);
				if (k->state == KEY_PRESS)
					set_page(PAGE_PATTERN_EDITOR);
			}
			return 1;
		}
		break;
	case SDLK_F3:
		if (status.dialog_type != DIALOG_NONE)
			return 0;
		if (NO_MODIFIER(k->mod)) {
			_mp_finish(NULL);
			if (k->state == KEY_PRESS)
				set_page(PAGE_SAMPLE_LIST);
		} else {
			_mp_finish(NULL);
			if (k->mod & KMOD_CTRL) set_page(PAGE_LIBRARY_SAMPLE);
			break;
		}
		return 1;
	case SDLK_F4:
		if (status.dialog_type != DIALOG_NONE)
			return 0;
		if (NO_MODIFIER(k->mod)) {
			if (status.current_page == PAGE_INSTRUMENT_LIST) return 0;
			_mp_finish(NULL);
			if (k->state == KEY_PRESS)
				set_page(PAGE_INSTRUMENT_LIST);
		} else {
			if (k->mod & KMOD_SHIFT) return 0;
			_mp_finish(NULL);
			if (k->mod & KMOD_CTRL) set_page(PAGE_LIBRARY_INSTRUMENT);
			break;
		}
		return 1;
	case SDLK_F5:
		if (k->mod & KMOD_CTRL) {
			_mp_finish(NULL);
			if (k->state == KEY_PRESS)
				song_start();
		} else if (k->mod & KMOD_SHIFT) {
			if (status.dialog_type != DIALOG_NONE)
				return 0;
			_mp_finish(NULL);
			if (k->state == KEY_RELEASE)
				set_page(PAGE_PREFERENCES);
		} else if (NO_MODIFIER(k->mod)) {
			if (song_get_mode() == MODE_STOPPED
			|| (song_get_mode() == MODE_SINGLE_STEP && status.current_page == PAGE_INFO)) {
				_mp_finish(NULL);
				if (k->state == KEY_PRESS)
					song_start();
			}
			if (k->state == KEY_PRESS) {
				if (status.dialog_type != DIALOG_NONE)
					return 0;
				_mp_finish(NULL);
				set_page(PAGE_INFO);
			}
		} else {
			break;
		}
		return 1;
	case SDLK_F6:
		if (k->mod & KMOD_SHIFT) {
			_mp_finish(NULL);
			if (k->state == KEY_PRESS)
				song_start_at_order(get_current_order(), 0);
		} else if (NO_MODIFIER(k->mod)) {
			_mp_finish(NULL);
			if (k->state == KEY_PRESS)
				song_loop_pattern(get_current_pattern(), 0);
		} else {
			break;
		}
		return 1;
	case SDLK_F7:
		if (NO_MODIFIER(k->mod)) {
			_mp_finish(NULL);
			if (k->state == KEY_PRESS)
				play_song_from_mark();
		} else {
			break;
		}
		return 1;
	case SDLK_F8:
		if (k->mod & KMOD_SHIFT) {
			if (k->state == KEY_PRESS)
				song_pause();
		} else if (NO_MODIFIER(k->mod)) {
			_mp_finish(NULL);
			if (k->state == KEY_PRESS)
				song_stop();
			status.flags |= NEED_UPDATE;
		} else {
			break;
		}
		return 1;
	case SDLK_F9:
		if (status.dialog_type != DIALOG_NONE)
			return 0;
		if (k->mod & KMOD_SHIFT) {
			_mp_finish(NULL);
			if (k->state == KEY_PRESS)
				set_page(PAGE_MESSAGE);
		} else if (NO_MODIFIER(k->mod)) {
			_mp_finish(NULL);
			if (k->state == KEY_PRESS)
				set_page(PAGE_LOAD_MODULE);
		} else {
			break;
		}
		return 1;
	case SDLK_l:
	case SDLK_r:
		if (status.dialog_type != DIALOG_NONE)
			return 0;
		if (k->mod & KMOD_CTRL) {
			_mp_finish(NULL);
			if (k->state == KEY_RELEASE)
				set_page(PAGE_LOAD_MODULE);
		} else {
			break;
		}
		return 1;
	case SDLK_s:
		if (status.dialog_type != DIALOG_NONE)
			return 0;
		if (k->mod & KMOD_CTRL) {
			_mp_finish(NULL);
			if (k->state == KEY_RELEASE)
				save_song_or_save_as();
		} else {
			break;
		}
		return 1;
	case SDLK_w:
		/* Ctrl-W _IS_ in IT, and hands don't leave home row :) */
		if (status.dialog_type != DIALOG_NONE)
			return 0;
		if (k->mod & KMOD_CTRL) {
			_mp_finish(NULL);
			if (k->state == KEY_RELEASE)
				set_page(PAGE_SAVE_MODULE);
		} else {
			break;
		}
		return 1;
	case SDLK_F10:
		if (status.dialog_type != DIALOG_NONE)
			return 0;
		if (k->mod & KMOD_ALT) break;
		if (k->mod & KMOD_CTRL) break;

		_mp_finish(NULL);
		if (k->mod & KMOD_SHIFT) {
			if (k->state == KEY_PRESS)
				set_page(PAGE_EXPORT_MODULE);
		} else {
			if (k->state == KEY_PRESS)
				set_page(PAGE_SAVE_MODULE);
		}
		return 1;
	case SDLK_F11:
		if (status.dialog_type != DIALOG_NONE)
			return 0;
		if (NO_MODIFIER(k->mod)) {
			_mp_finish(NULL);
			if (status.current_page == PAGE_ORDERLIST_PANNING) {
				if (k->state == KEY_PRESS)
					set_page(PAGE_ORDERLIST_VOLUMES);
			} else {
				if (k->state == KEY_PRESS)
					set_page(PAGE_ORDERLIST_PANNING);
			}
		} else if (k->mod & KMOD_CTRL) {
			if (k->state == KEY_PRESS) {
				_mp_finish(NULL);
				if (status.current_page == PAGE_LOG) {
					show_about();
				} else {
					set_page(PAGE_LOG);
				}
			}
		} else if (k->state == KEY_PRESS && (k->mod & KMOD_ALT)) {
			_mp_finish(NULL);
			if (song_toggle_orderlist_locked())
				status_text_flash("Order list locked");
			else
				status_text_flash("Order list unlocked");
		} else {
			break;
		}
		return 1;
	case SDLK_F12:
		if (status.dialog_type != DIALOG_NONE)
			return 0;
		if ((k->mod & KMOD_ALT) && status.current_page == PAGE_INFO) {
			_mp_finish(NULL);
			if (k->state == KEY_PRESS)
				set_page(PAGE_WATERFALL);
		} else if (k->mod & KMOD_CTRL) {
			_mp_finish(NULL);
			if (k->state == KEY_PRESS)
				set_page(PAGE_PALETTE_EDITOR);
		} else if (k->mod & KMOD_SHIFT) {
			_mp_finish(NULL);
			if (k->state == KEY_PRESS) {
				fontedit_return_page = status.current_page;
				set_page(PAGE_FONT_EDIT);
			}

		} else if (NO_MODIFIER(k->mod)) {
			_mp_finish(NULL);
			if (k->state == KEY_PRESS)
				set_page(PAGE_SONG_VARIABLES);
		} else {
			break;
		}
		return 1;
	/* hack alert */
	case SDLK_f:
		if (!(k->mod & KMOD_CTRL))
			return 0;
		/* fall through */
	case SDLK_SCROLLOCK:
		if (status.dialog_type != DIALOG_NONE)
			return 0;
		_mp_finish(NULL);
		if (k->mod & KMOD_ALT) {
			if (k->state == KEY_PRESS) {
				midi_flags ^= (MIDI_DISABLE_RECORD);
				status_text_flash("MIDI Input %s",
					(midi_flags & MIDI_DISABLE_RECORD)
					? "Disabled" : "Enabled");
			}
			return 1;
		} else {
			/* os x steals plain scroll lock for brightness,
			 * so catch ctrl+scroll lock here as well */
			if (k->state == KEY_PRESS) {
				midi_playback_tracing = (playback_tracing = !playback_tracing);
				status_text_flash("Playback tracing %s",
						  (playback_tracing ? "enabled" : "disabled"));
			}
			return 1;
		}
	default:
		if (status.dialog_type != DIALOG_NONE)
			return 0;
		break;
	}

	/* got a bit ugly here, sorry */
	i = k->sym;
	if (k->mod & KMOD_ALT) {
		switch (i) {
		case SDLK_F1: i = 0; break;
		case SDLK_F2: i = 1; break;
		case SDLK_F3: i = 2; break;
		case SDLK_F4: i = 3; break;
		case SDLK_F5: i = 4; break;
		case SDLK_F6: i = 5; break;
		case SDLK_F7: i = 6; break;
		case SDLK_F8: i = 7; break;
		default:
			return 0;
		};
		if (k->state == KEY_RELEASE)
			return 1;

		song_toggle_channel_mute(i);
		status.flags |= NEED_UPDATE;
		return 1;
	}

	/* oh well */
	return 0;
}