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 #define NEED_TIME
25 #include "headers.h"
26 
27 #include <stdarg.h>
28 
29 #include "it.h"
30 #include "song.h"
31 #include "page.h"
32 
33 #include "sndfile.h"
34 
35 #include "sdlmain.h"
36 
37 /* --------------------------------------------------------------------- */
38 
39 static int status_bios = 0;
40 static char *status_text = NULL;
41 static uint32_t text_timeout;
42 
43 /* --------------------------------------------------------------------- */
44 
status_text_flash(const char * format,...)45 void status_text_flash(const char *format, ...)
46 {
47 	va_list ap;
48 
49 	text_timeout = SDL_GetTicks() + 1000;
50 
51 	if (status_text)
52 		free(status_text);
53 
54 	status_bios = 0;
55 	va_start(ap, format);
56 	if (vasprintf(&status_text, format, ap) == -1) abort();
57 	va_end(ap);
58 
59 	status.flags |= NEED_UPDATE;
60 }
61 
status_text_flash_bios(const char * format,...)62 void status_text_flash_bios(const char *format, ...)
63 {
64 	va_list ap;
65 
66 	text_timeout = SDL_GetTicks() + 1000;
67 
68 	if (status_text)
69 		free(status_text);
70 
71 	status_bios = 1;
72 	va_start(ap, format);
73 	if (vasprintf(&status_text, format, ap) == -1) abort();
74 	va_end(ap);
75 
76 	status.flags |= NEED_UPDATE;
77 }
78 
79 /* --------------------------------------------------------------------- */
80 
_loop_count(char * buf,int pos)81 static inline int _loop_count(char *buf, int pos)
82 {
83 	if (current_song->repeat_count < 1 || (status.flags & CLASSIC_MODE)) {
84 		pos += draw_text("Playing", pos, 9, 0, 2);
85 	} else {
86 		pos += draw_text("Loop: ", pos, 9, 0, 2);
87 		pos += draw_text(numtostr(0, current_song->repeat_count, buf), pos, 9, 3, 2);
88 	}
89 	return pos;
90 }
91 
draw_song_playing_status(void)92 static inline void draw_song_playing_status(void)
93 {
94 	int pos = 2;
95 	char buf[16];
96 	int pattern = song_get_playing_pattern();
97 
98 	pos = _loop_count(buf, pos);
99 	pos += draw_text(", Order: ", pos, 9, 0, 2);
100 	pos += draw_text(numtostr(0, song_get_current_order(), buf), pos, 9, 3, 2);
101 	draw_char('/', pos, 9, 0, 2);
102 	pos++;
103 	pos += draw_text(numtostr(0, csf_last_order(current_song), buf), pos, 9, 3, 2);
104 	pos += draw_text(", Pattern: ", pos, 9, 0, 2);
105 	pos += draw_text(numtostr(0, pattern, buf), pos, 9, 3, 2);
106 	pos += draw_text(", Row: ", pos, 9, 0, 2);
107 	pos += draw_text(numtostr(0, song_get_current_row(), buf), pos, 9, 3, 2);
108 	draw_char('/', pos, 9, 0, 2);
109 	pos++;
110 	pos += draw_text(numtostr(0, song_get_pattern(pattern, NULL), buf), pos, 9, 3, 2);
111 	draw_char(',', pos, 9, 0, 2);
112 	pos++;
113 	draw_char(0, pos, 9, 0, 2);
114 	pos++;
115 	pos += draw_text(numtostr(0, song_get_playing_channels(), buf), pos, 9, 3, 2);
116 
117 	if (draw_text_len(" Channels", 62 - pos, pos, 9, 0, 2) < 9)
118 		draw_char(16, 61, 9, 1, 2);
119 }
120 
draw_pattern_playing_status(void)121 static inline void draw_pattern_playing_status(void)
122 {
123 	int pos = 2;
124 	char buf[16];
125 	int pattern = song_get_playing_pattern();
126 
127 	pos = _loop_count(buf, pos);
128 	pos += draw_text(", Pattern: ", pos, 9, 0, 2);
129 	pos += draw_text(numtostr(0, pattern, buf), pos, 9, 3, 2);
130 	pos += draw_text(", Row: ", pos, 9, 0, 2);
131 	pos += draw_text(numtostr(0, song_get_current_row(), buf), pos, 9, 3, 2);
132 	draw_char('/', pos, 9, 0, 2);
133 	pos++;
134 	pos += draw_text(numtostr(0, song_get_pattern(pattern, NULL), buf), pos, 9, 3, 2);
135 	draw_char(',', pos, 9, 0, 2);
136 	pos++;
137 	draw_char(0, pos, 9, 0, 2);
138 	pos++;
139 	pos += draw_text(numtostr(0, song_get_playing_channels(), buf), pos, 9, 3, 2);
140 
141 	if (draw_text_len(" Channels", 62 - pos, pos, 9, 0, 2) < 9)
142 		draw_char(16, 61, 9, 1, 2);
143 }
144 
draw_playing_channels(void)145 static inline void draw_playing_channels(void)
146 {
147 	int pos = 2;
148 	char buf[16];
149 
150 	pos += draw_text("Playing, ", 2, 9, 0, 2);
151 	pos += draw_text(numtostr(0, song_get_playing_channels(), buf), pos, 9, 3, 2);
152 	draw_text(" Channels", pos, 9, 0, 2);
153 }
154 
status_text_redraw(void)155 void status_text_redraw(void)
156 {
157 	uint32_t now = SDL_GetTicks();
158 
159 	/* if there's a message set, and it's expired, clear it */
160 	if (status_text && now > text_timeout) {
161 		free(status_text);
162 		status_text = NULL;
163 	}
164 
165 	if (status_text) {
166 		if (status_bios) {
167 			draw_text_bios_len(status_text, 60, 2, 9, 0, 2);
168 		} else {
169 			draw_text_len(status_text, 60, 2, 9, 0, 2);
170 		}
171 	} else {
172 		switch (song_get_mode()) {
173 		case MODE_PLAYING:
174 			draw_song_playing_status();
175 			break;
176 		case MODE_PATTERN_LOOP:
177 			draw_pattern_playing_status();
178 			break;
179 		case MODE_SINGLE_STEP:
180 			if (song_get_playing_channels() > 1) {
181 				draw_playing_channels();
182 				break;
183 			}
184 		default:
185 			break;
186 		}
187 	}
188 }
189