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 #ifndef IT_H
25 #define IT_H
26
27 #include "sdlmain.h"
28
29 #include <stdio.h>
30 #include <stdint.h>
31
32 #include <sys/types.h>
33 #include <sys/stat.h> /* roundabout way to get time_t */
34
35 #include "util.h"
36 #include "video.h"
37 #include "log.h"
38
39 /* --------------------------------------------------------------------- */
40 /* preprocessor stuff */
41
42 #define SDL_ToggleCursor() SDL_ShowCursor(!SDL_ShowCursor(-1))
43
44 #define NO_MODIFIER(mod) \
45 (((mod) & (KMOD_CTRL | KMOD_ALT | KMOD_SHIFT)) == 0)
46 #define NO_CAM_MODS(mod) \
47 (((mod) & (KMOD_CTRL | KMOD_ALT)) == 0)
48
49 /* --------------------------------------------------------------------- */
50 /* structs 'n enums */
51
52 /* tracker_status dialog_types */
53 enum {
54 DIALOG_NONE = (0), /* 0000 0000 */
55 DIALOG_MENU = (1 << 0), /* 0000 0001 */
56 DIALOG_MAIN_MENU = (DIALOG_MENU | (1 << 1)), /* 0000 0011 */
57 DIALOG_SUBMENU = (DIALOG_MENU | (1 << 2)), /* 0000 0101 */
58 DIALOG_BOX = (1 << 3), /* 0000 1000 */
59 DIALOG_OK = (DIALOG_BOX | (1 << 4)), /* 0001 1000 */
60 DIALOG_OK_CANCEL = (DIALOG_BOX | (1 << 5)), /* 0010 1000 */
61 /* yes/no technically has a cancel as well, i.e. the escape key */
62 DIALOG_YES_NO = (DIALOG_BOX | (1 << 6)), /* 0100 1000 */
63 DIALOG_CUSTOM = (DIALOG_BOX | (1 << 7)), /* 1000 1000 */
64 };
65
66 /* tracker_status flags
67 eventual TODO: split this into two sections or something so we don't run
68 out of bits to toggle... and while we're at it, namespace them with
69 CFG_ (for the configuration stuff -- bits that are accessible through the
70 interface in some way) and uh, something else for the internal status flags
71 like IS_VISIBLE or whatever */
72 enum {
73 /* if this flag is set, the screen will be redrawn */
74 NEED_UPDATE = (1 << 0),
75
76 /* is the current palette "backwards"? (used to make the borders look right) */
77 INVERTED_PALETTE = (1 << 1),
78
79 DIR_MODULES_CHANGED = (1 << 2),
80 DIR_SAMPLES_CHANGED = (1 << 3),
81 DIR_INSTRUMENTS_CHANGED = (1 << 4),
82
83 /* these refer to the window's state.
84 * (they're rather useless on the console ;) */
85 IS_FOCUSED = (1 << 5),
86 IS_VISIBLE = (1 << 6),
87 WM_AVAILABLE = (1 << 7),
88
89 /* if this is set, some stuff behaves differently
90 * (grep the source files for what stuff ;) */
91 CLASSIC_MODE = (1 << 8),
92
93 /* make a backup file (song.it~) when saving a module? */
94 MAKE_BACKUPS = (1 << 9),
95 NUMBERED_BACKUPS = (1 << 10), /* song.it.3~ */
96
97 LAZY_REDRAW = (1 << 11),
98
99 /* this is here if anything is "changed" and we need to whine to
100 the user if they quit */
101 SONG_NEEDS_SAVE = (1 << 12),
102
103 /* if the software mouse pointer moved.... */
104 SOFTWARE_MOUSE_MOVED = (1 << 13),
105
106 /* pasting is done by setting a flag here, the main event loop then synthesizes
107 the various events... after we return */
108 CLIPPY_PASTE_SELECTION = (1 << 14),
109 CLIPPY_PASTE_BUFFER = (1 << 15),
110
111 /* if the disko is active */
112 DISKWRITER_ACTIVE = (1 << 16),
113 DISKWRITER_ACTIVE_PATTERN = (1 << 17), /* recording only a single pattern */
114
115 /* mark... set by midi core when received new midi event */
116 MIDI_EVENT_CHANGED = (1 << 18),
117
118 /* poop */
119 ACCIDENTALS_AS_FLATS = (1 << 19),
120
121 /* fontedit */
122 STARTUP_FONTEDIT = (1 << 20),
123
124 /* key hacks -- should go away when keyboard redefinition is possible */
125 META_IS_CTRL = (1 << 21),
126 ALTGR_IS_ALT = (1 << 22),
127
128 /* holding shift (used on pattern editor for weird template thing) */
129 SHIFT_KEY_DOWN = (1 << 23),
130
131 /* Devi Ever's hack */
132 CRAYOLA_MODE = (1 << 25),
133
134 /* holding caps */
135 CAPS_PRESSED = (1 << 26),
136
137 NO_NETWORK = (1 << 27),
138 NO_MOUSE = (1 << 28),
139
140 /* Play MIDI events using the same semantics as tracker samples */
141 MIDI_LIKE_TRACKER = (1 << 29),
142
143 /* if true, don't stop playing on load, and start playing new song afterward
144 (but only if the last song was already playing before loading) */
145 PLAY_AFTER_LOAD = (1 << 30),
146 };
147
148 /* note! TIME_PLAYBACK is only for internal calculations -- don't use it directly */
149 enum tracker_time_display {
150 TIME_OFF, TIME_PLAY_ELAPSED, TIME_PLAY_CLOCK, TIME_PLAY_OFF,
151 TIME_ELAPSED, TIME_CLOCK, TIME_ABSOLUTE, TIME_PLAYBACK,
152 };
153
154 /* what should go in the little box on the top right? */
155 enum tracker_vis_style {
156 VIS_OFF, VIS_FAKEMEM, VIS_OSCILLOSCOPE, VIS_VU_METER, VIS_MONOSCOPE, VIS_FFT, VIS_SENTINEL
157 };
158
159 struct tracker_status {
160 int current_page;
161 int previous_page;
162 int current_help_index;
163 int dialog_type; /* one of the DIALOG_* constants above */
164 int flags;
165 enum tracker_time_display time_display;
166 enum tracker_vis_style vis_style;
167 SDLKey last_keysym;
168
169 time_t last_midi_time;
170 unsigned char last_midi_event[64];
171 unsigned int last_midi_len;
172 unsigned int last_midi_real_len;
173 void *last_midi_port; /* really a struct midi_port * */
174
175 /* clock is driven from the main/event thread */
176 time_t now;
177 struct tm tmnow;
178
179 int fix_numlock_setting;
180 };
181
182 /* numlock hackery */
183 enum {
184 NUMLOCK_ALWAYS_OFF = 0,
185 NUMLOCK_ALWAYS_ON = 1,
186 NUMLOCK_HONOR = -1, /* don't fix it */
187 NUMLOCK_GUESS = -2, /* don't fix it... except on non-ibook macs */
188 };
189
190 /* mouse visibility - these are passed to video_mousecursor()
191 first three are stored as the physical mouse state */
192 enum {
193 MOUSE_DISABLED,
194 MOUSE_EMULATED,
195 MOUSE_SYSTEM,
196
197 MOUSE_CYCLE_STATE,
198 MOUSE_RESET_STATE,
199 };
200 #define MOUSE_MAX_STATE MOUSE_CYCLE_STATE
201
202
203 struct it_palette {
204 char name[21];
205 uint8_t colors[16][3];
206 };
207
208 enum {
209 NOTE_TRANS_CLEAR = (30),
210 NOTE_TRANS_NOTE_CUT,
211 NOTE_TRANS_NOTE_OFF,
212 NOTE_TRANS_NOTE_FADE,
213 NOTE_TRANS_PREV_INS,
214 NOTE_TRANS_NEXT_INS,
215 NOTE_TRANS_TOGGLE_MASK,
216 NOTE_TRANS_VOL_PAN_SWITCH,
217 NOTE_TRANS_PLAY_NOTE,
218 NOTE_TRANS_PLAY_ROW,
219 };
220
221 /* --------------------------------------------------------------------- */
222 /* global crap */
223
224 extern struct tracker_status status;
225 extern uint8_t *font_data; /* ... which is 2048 bytes */
226 extern struct it_palette palettes[];
227 extern uint8_t current_palette[16][3];
228 extern int current_palette_index;
229
230 extern int playback_tracing, midi_playback_tracing;
231
232 extern const char hexdigits[16]; /* in keyboard.c at the moment */
233
234 /* this used to just translate keys to notes, but it's sort of become the
235 * keyboard map... perhaps i should rename it. */
236 extern const char *note_trans; /* keyboard.c */
237
238
239 extern int show_default_volumes; /* pattern-view.c */
240
241 /* --------------------------------------------------------------------- */
242 /* settings (config.c) */
243
244 extern char cfg_video_driver[];
245 /* TODO: consolidate these into cfg_video_flags */
246 extern int cfg_video_fullscreen;
247 extern int cfg_video_mousecursor;
248 extern int cfg_video_gl_bilinear;
249 extern int cfg_video_width, cfg_video_height;
250
251 extern char cfg_dir_modules[], cfg_dir_samples[], cfg_dir_instruments[];
252 extern char cfg_dir_dotschism[]; /* the full path to ~/.schism */
253 extern char cfg_font[];
254 extern int cfg_palette;
255
256 extern char cfg_module_pattern[];
257 extern char cfg_export_pattern[];
258
259 void cfg_init_dir(void);
260 void cfg_load(void);
261 void cfg_save(void);
262 void cfg_midipage_save(void);
263 void cfg_atexit_save(void); /* this only saves a handful of settings, not everything */
264
265 /* each page with configurable settings has a function to load/save them... */
266 #include "config-parser.h" /* FIXME: shouldn't need this here */
267
268 void cfg_load_midi(cfg_file_t *cfg);
269 void cfg_save_midi(cfg_file_t *cfg);
270
271 void cfg_load_patedit(cfg_file_t *cfg);
272 void cfg_save_patedit(cfg_file_t *cfg);
273
274 void cfg_load_info(cfg_file_t *cfg);
275 void cfg_save_info(cfg_file_t *cfg);
276
277 void cfg_load_audio(cfg_file_t *cfg);
278 void cfg_save_audio(cfg_file_t *cfg);
279 void cfg_atexit_save_audio(cfg_file_t *cfg);
280
281 void cfg_load_disko(cfg_file_t *cfg);
282 void cfg_save_disko(cfg_file_t *cfg);
283
284 void cfg_load_dmoz(cfg_file_t *cfg);
285 void cfg_save_dmoz(cfg_file_t *cfg);
286
287 /* --------------------------------------------------------------------- */
288 /* text functions */
289
290 /* these are sort of for single-line text entries. */
291 void text_add_char(char *text, char c, int *cursor_pos, int max_length);
292 void text_delete_char(char *text, int *cursor_pos, int max_length);
293 void text_delete_next_char(char *text, int *cursor_pos, int max_length);
294
unicode_to_ascii(uint16_t unicode)295 static inline unsigned char unicode_to_ascii(uint16_t unicode)
296 {
297 return unicode & 0xff;
298 // return ((unicode & 0xff80) ? 0 : (unicode & 0x7f));
299 }
300
301 /* --------------------------------------------------------------------- */
302 /* drawing functions */
303
304 /* character drawing (in a separate header so they're easier to find) */
305 #include "draw-char.h"
306
307 struct song_sample;
308 void draw_sample_data(struct vgamem_overlay *r, struct song_sample *sample);
309
310 /* this works like draw_sample_data, just without having to allocate a
311 * song_sample structure, and without caching the waveform.
312 * mostly it's just for the oscilloscope view. */
313 void draw_sample_data_rect_16(struct vgamem_overlay *r, signed short *data, int length,
314 unsigned int inputchans, unsigned int outputchans);
315 void draw_sample_data_rect_8(struct vgamem_overlay *r, signed char *data, int length,
316 unsigned int inputchans, unsigned int outputchans);
317
318 /* these are in audio_playback.cc */
319 extern signed short *audio_buffer;
320 extern unsigned int audio_buffer_samples;
321 extern unsigned int audio_output_channels;
322 extern unsigned int audio_output_bits;
323
324 /* --------------------------------------------------------------------- */
325 /* page functions */
326
327 /* anything can use these */
328 void set_page(int new_page);
329 /* (there's no get_page -- just use status.current_page) */
330
331 /* these should only be called from main */
332 void load_pages(void); /* called once at start of program */
333 void playback_update(void); /* once per cycle */
334 struct key_event;
335 void handle_key(struct key_event * k); /* whenever there's a keypress ;) */
336 void key_translate(struct key_event *k);
337
338 /* this should only be called from main.
339 * anywhere else, use status.flags |= NEED_UPDATE instead. */
340 void redraw_screen(void);
341
342 /* called whenever the song changes (from song_new or song_load) */
343 void main_song_changed_cb(void);
344
345 /* --------------------------------------------------------------------- */
346 /* colors and fonts */
347
348 int font_load(const char *filename);
349 void palette_apply(void);
350 void palette_load_preset(int palette_index);
351
352 /* mostly for the itf editor */
353 int font_save(const char *filename);
354
355 void font_reset_lower(void); /* ascii chars (0-127) */
356 void font_reset_upper(void); /* itf chars (128-255) */
357 void font_reset(void); /* everything (0-255) */
358 void font_reset_bios(void); /* resets all chars to the alt font */
359 void font_reset_char(int c); /* resets just one char */
360
361 /* this needs to be called before any char drawing.
362 * it's pretty much the same as doing...
363 * if (!font_load("font.cfg"))
364 * font_reset();
365 * ... the main difference being font_init() is easier to deal with :) */
366 void font_init(void);
367
368 /* --------------------------------------------------------------------- */
369 /* keyboard.c */
370
371 int numeric_key_event(struct key_event *k, int kponly);
372
373 char *get_note_string(int note, char *buf); /* "C-5" or "G#4" */
374 char *get_note_string_short(int note, char *buf); /* "c5" or "G4" */
375 char *get_volume_string(int volume, int volume_effect, char *buf);
376 char get_effect_char(int command);
377 int get_effect_number(char effect);
378 int get_ptm_effect_number(char effect);
379
380 void kbd_init(void);
381 void kbd_sharp_flat_toggle(int e);
382 int kbd_get_effect_number(struct key_event *k);
383 int kbd_char_to_hex(struct key_event *k);
384 int kbd_char_to_99(struct key_event *k);
385
386 int kbd_get_current_octave(void);
387 void kbd_set_current_octave(int new_octave);
388
389 int kbd_get_note(struct key_event *k);
390
391 int kbd_get_alnum(struct key_event *k);
392
393 /* use 0 for delay to (re)set the default rate. */
394 void set_key_repeat(int delay, int rate);
395
396 /* --------------------------------------------------------------------- */
397 /* stuff */
398
399 int sample_get_current(void);
400 void sample_set(int n);
401 int instrument_get_current(void);
402 void instrument_set(int n);
403 void instrument_synchronize_to_sample(void);
404 void sample_synchronize_to_instrument(void);
405 int sample_is_used_by_instrument(int samp);
406
407 /* if necessary, prompt to create a new instrument. if newpage >= 0, the page
408 is changed upon completion of the dialog, or immediately if no dialog was
409 shown.
410 return value is 1 if the dialog was shown, 0 if not. */
411 int sample_host_dialog(int newpage);
412
413 /* instrument... sample... whatever */
414
415 int song_is_instrument_mode(void);
416 int song_first_unused_instrument(void);
417 int song_get_current_instrument(void);
418
419 void set_previous_instrument(void);
420 void set_next_instrument(void);
421
422 int get_current_channel(void);
423 void set_current_channel(int channel);
424 int get_current_row(void);
425 void set_current_row(int row);
426 int get_current_pattern(void);
427 void set_current_pattern(int pattern);
428 /* This is the F7 key handlers: it starts at the marked position if there
429 * is one, or the current position if not. */
430 void play_song_from_mark_orderpan(void);
431 void play_song_from_mark(void);
432
433 int get_current_order(void);
434 void set_current_order(int order);
435 void prev_order_pattern(void);
436 void next_order_pattern(void);
437 void orderpan_recheck_muted_channels(void);
438
439 void show_exit_prompt(void);
440 void show_song_length(void);
441 void show_song_timejump(void);
442
443 /* memory usage */
444 unsigned int memused_lowmem(void);
445 unsigned int memused_ems(void);
446 unsigned int memused_songmessage(void);
447 unsigned int memused_instruments(void);
448 unsigned int memused_samples(void);
449 unsigned int memused_clipboard(void);
450 unsigned int memused_patterns(void);
451 unsigned int memused_history(void);
452 /* clears the memory lookup cache */
453 void memused_songchanged(void);
454
455 void memused_get_pattern_saved(unsigned int *a, unsigned int *b); /* wtf */
456
457 /* --------------------------------------------------------------------- */
458
459 #endif /* ! IT_H */
460
461