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