Timing is correct now! Forgot to update samples_per_tick when parsing the 0xf effect.
[pineappletracker.git] / sdl_gui.c
blobcb09bb3af9298de2fc60bbe57456357112b863d3
1 /*
2 * (C) David Olofson, 2003, 2006
3 * modified by the pineapple team, 2009
4 */
5 #include <SDL/SDL.h>
6 #include <signal.h>
7 #include <stdio.h>
9 #include "sdl_gui.h"
10 #include "gui.h"
11 #include "pineapple.h"
12 #include "filetypes.h"
14 static int die = 0;
15 static SDL_Surface *screen;
16 static SDL_Surface *font = NULL;
17 static Uint32 boxcolor;
19 #define FONT_CW 10
20 #define FONT_CH 16
21 #define WINW 800
22 #define WINH 600
23 #define SP 2 //spacing
24 #define BOXW 1 //box width
26 #define FPS 30
28 // these aren't #define's because doing this in the preprocessor:
29 // #define COLW = (WINW/3)-3
30 // made gcc complain
31 static int voffs;
32 static int colh;
34 //pineapple_tune tune;
36 int main(int argc, char **argv){
37 int tick;
39 //------------------------------------------------------------------\\
40 // args
41 //------------------------------------------------------------------//
42 if(argc==1){
43 tune = pt_empty_tune();
44 }else{
45 tune = lft_loadfile(argv[1]);
48 if(SDL_Init(SDL_INIT_VIDEO)!=0)
49 return 1;
51 voffs = FONT_CH+4;
52 colh = WINH-voffs-SP-BOXW;
54 atexit(SDL_Quit);
55 signal(SIGTERM,breakhandler);
56 signal(SIGINT,breakhandler);
58 screen = SDL_SetVideoMode(WINW,WINH,32,SDL_SWSURFACE);
59 if(screen==NULL){
60 fprintf(stderr,"video init failed");
61 SDL_Quit();
62 return 1;
63 }else{
64 fprintf(stdout,"initialized the surface\n");
67 boxcolor = SDL_MapRGB(screen->format, 255, 0, 255);
68 SDL_WM_SetCaption("pineapple-tracker","pineapple.ico");
69 if(gui_open(screen) != 0){
70 fprintf(stderr, "Couldn't start GUI!\n");
71 SDL_Quit();
72 return -1;
75 draw_main();
76 SDL_Flip(screen);
78 //last_tick=SDL_GetTicks();
79 while(!die){
80 SDL_Event ev;
81 tick = SDL_GetTicks();
82 //int dt = tick - last_tick;
83 //last_tick = tick;
85 /* Handle GUI events */
86 while(SDL_PollEvent(&ev)){
87 switch(ev.type){
88 case SDL_KEYDOWN:
89 switch(currmode){
90 case PM_NORMAL:
91 handle_key_normal(&ev);
92 break;
93 case PM_VISUAL:
94 break;
95 case PM_VISUALLINE:
96 break;
97 case PM_CMDLINE:
98 break;
99 case PM_INSERT:
100 break;
101 case PM_JAMMER:
102 break;
104 break;
105 case SDL_QUIT:
106 die = 1;
107 break;
108 default:
109 break;
113 //update_main(screen);
114 if((SDL_GetTicks() - tick) < 1000/FPS){
115 SDL_Delay( (1000/FPS) - (SDL_GetTicks() - tick));
117 gui_refresh();
120 SDL_Quit();
121 return 0;
124 static void breakhandler(int a){
125 die = 1;
128 static void draw_songed(const int x, const int y, const int w, const int h){
129 int i, k, pos;
130 /*int i;
131 int pos = 0;
133 char buf[1024];
134 int j = 0;
136 for(i=0; (i+y < h)
137 //&&(i < h/FONT_CH)
138 &&(j < tune->songlen);
139 i+=(FONT_CH+2))
141 int space = 0;
142 pos = i/FONT_CH;
143 snprintf(buf, sizeof(buf), "%02x| ", j);
145 /*for(i=0; (i+y < h) &&(i < h/FONT_CH) &&(i < tune->songlen); i+=(FONT_CH))
147 //pos = i/FONT_CH;
148 pos++;
150 snprintf(buf, sizeof(buf),
151 "%02x:__ __:__ __:__ __:__", pos);
153 gui_text(x+SP,i+y+SP,buf,screen);
154 for(k = 0; k < 4; k++){
155 snprintf(buf, sizeof(buf),
156 "%02x:%02x", tune->sng[j].track[k], tune->sng[j].transp[k]);
157 gui_text(x+(space+=40),i+y+SP,buf,screen);
160 fprintf(stderr,"tune->songlen: %i\n", tune->songlen);
161 fprintf(stderr,"i: %i\n", i);
162 fprintf(stderr,"j: %i\n", j);
164 fprintf(stderr, "i: %i\n", i);
165 fprintf(stderr, "pos: %i\n", pos);
166 fprintf(stderr, "songlen: %i\n", tune->songlen);
168 // draw a box if selected
169 if(songy==pos){
170 gui_box(x,i,w,FONT_CH+(SP*2),boxcolor,screen);
172 j++;
174 gui_box(x,y,w,h,boxcolor,screen);
177 static void draw_tracked(const int x, const int y, const int w, const int h){
178 gui_box(x,y,w,h,boxcolor,screen);
181 static void draw_instred(const int x, const int y, const int w, const int h){
182 gui_box(x,y,w,h,boxcolor,screen);
185 static void draw_main(void){
186 gui_text(2,2,"PINEAPPLEtRACKER",screen);
187 draw_songed(SP,voffs,(23*FONT_CW)+(SP*2),colh);
188 draw_tracked((23*FONT_CW)+(SP*4)+(BOXW*2),voffs,(18*FONT_CW)+(SP*2),
189 colh);
190 draw_instred((41*FONT_CW)+(SP*7)+(BOXW*4),voffs,(9*FONT_CW)+(SP*2),
191 colh);
194 static void handle_key_normal(SDL_Event *ev){
195 switch(ev->key.keysym.sym){
196 case SDLK_KP_PLUS:
197 case SDLK_PLUS:
198 case SDLK_KP_MINUS:
199 case SDLK_MINUS:
200 break;
201 case SDLK_h:
202 case SDLK_LEFT:
203 fprintf(stderr,"H\n");
204 fprintf(stderr,"pos: %d, %d\n", songx, songy);
205 act_mvleft();
206 break;
207 case SDLK_l:
208 case SDLK_RIGHT:
209 fprintf(stderr,"J\n");
210 fprintf(stderr,"pos: %d, %d\n", songx, songy);
211 act_mvright();
212 break;
213 case SDLK_k:
214 case SDLK_UP:
215 fprintf(stderr,"K\n");
216 fprintf(stderr,"pos: %d, %d\n", songx, songy);
217 act_mvup();
218 break;
219 case SDLK_j:
220 case SDLK_DOWN:
221 fprintf(stderr,"L\n");
222 fprintf(stderr,"pos: %d, %d\n", songx, songy);
223 act_mvdown();
224 break;
225 case SDLK_PAGEUP:
226 act_bigmvup();
227 break;
228 case SDLK_PAGEDOWN:
229 act_bigmvdown();
230 break;
231 case SDLK_F1:
232 case SDLK_F2:
233 case SDLK_F3:
234 case SDLK_F4:
235 case SDLK_F5:
236 case SDLK_F6:
237 case SDLK_F7:
238 case SDLK_F8:
239 case SDLK_F9:
240 case SDLK_F10:
241 case SDLK_F11:
242 case SDLK_F12:
243 case SDLK_PERIOD:
244 case SDLK_DELETE:
245 case SDLK_BACKSPACE:
246 case SDLK_0:
247 case SDLK_1:
248 case SDLK_2:
249 case SDLK_3:
250 case SDLK_4:
251 case SDLK_5:
252 case SDLK_6:
253 case SDLK_7:
254 case SDLK_8:
255 case SDLK_9:
256 case SDLK_KP0:
257 case SDLK_KP1:
258 case SDLK_KP2:
259 case SDLK_KP3:
260 case SDLK_KP4:
261 case SDLK_KP5:
262 case SDLK_KP6:
263 case SDLK_KP7:
264 case SDLK_KP8:
265 case SDLK_KP9:
266 case SDLK_SPACE:
267 case SDLK_TAB:
268 case SDLK_ESCAPE:
269 default:
270 break;
274 //static void update_main(SDL_Surface *screen){
275 //unsigned int pos;
277 //draw_songed(SP,voffs,230+(SP*2),colh);
278 //draw_tracked(230+(SP*4),voffs,100,colh);
279 //draw_instred(230+100*(SP*8),voffs,100,colh);
283 // \\ // \\ // \\ //
284 // gui_* functions //
285 // \\ // \\ // \\ //
287 void gui_bar(int x, int y, int w, int h, Uint32 c, SDL_Surface *dst){
288 SDL_Rect r;
289 r.x = x;
290 r.y = y;
291 r.w = w;
292 r.h = h;
293 SDL_FillRect(dst, &r, SDL_MapRGB(dst->format, 0, 0, 0));
294 gui_box(x, y, w, h, c, dst);
297 void gui_box(int x, int y, int w, int h, Uint32 c, SDL_Surface *dst){
298 SDL_Rect r;
299 r.x = x;
300 r.y = y;
301 r.w = w;
302 r.h = BOXW;
303 SDL_FillRect(dst, &r, c);
305 r.x = x;
306 r.y = y + h - BOXW;
307 r.w = w;
308 r.h = BOXW;
309 SDL_FillRect(dst, &r, c);
311 r.x = x;
312 r.y = y + BOXW;
313 r.w = BOXW;
314 r.h = h - (BOXW*2);
315 SDL_FillRect(dst, &r, c);
317 r.x = x + w - BOXW;
318 r.y = y + BOXW;
319 r.w = BOXW;
320 r.h = h - (BOXW*2);
321 SDL_FillRect(dst, &r, c);
323 r.x = x;
324 r.y = y;
325 r.w = w;
326 r.h = h;
327 //gui_dirty(&r);
330 void gui_close(void){
331 SDL_FreeSurface(font);
332 font = NULL;
335 SDL_Surface *gui_load_image(const char *fn){
336 SDL_Surface *cvt;
337 SDL_Surface *img = SDL_LoadBMP(fn);
338 if(!img){
339 return NULL;
341 cvt = SDL_DisplayFormat(img);
342 SDL_FreeSurface(img);
343 return cvt;
346 int gui_open(SDL_Surface *scrn){
347 screen = scrn;
348 font = gui_load_image("font.bmp");
349 if(!font){
350 fprintf(stderr, "Couldn't load font!\n");
351 return 1;
353 SDL_EnableKeyRepeat(250, 25);
354 //memset(activity, 0, sizeof(activity));
355 return 0;
358 void gui_refresh(void){
359 SDL_Flip(screen);
362 void gui_text(int x, int y, const char *txt, SDL_Surface *dst){
363 int sx = x;
364 int sy = y;
365 const char *stxt = txt;
366 int highlights = 0;
367 SDL_Rect sr;
368 sr.w = FONT_CW;
369 sr.h = FONT_CH;
370 while(*txt){
371 int c = *txt++;
372 switch(c){
373 case 0: /* terminator */
374 break;
375 case '\n': /* newline */
376 x = sx;
377 y += FONT_CH;
378 break;
379 case '\t': /* tab */
380 x -= sx;
381 x += 8 * FONT_CW;
382 x %= 8 * FONT_CW;
383 x += sx;
384 break;
385 case '\001': /* red highlight */
386 case '\002': /* green highlight */
387 case '\003': /* yellow highlight */
388 case '\004': /* blue highlight */
389 case '\005': /* purple highlight */
390 case '\006': /* cyan highlight */
391 case '\007': /* white highlight */
392 highlights = 1;
393 if(*txt == '\001'){
394 txt += 2;
396 break;
397 case '\021': /* red bullet */
398 case '\022': /* green bullet */
399 case '\023': /* yellow bullet */
400 case '\024': /* blue bullet */
401 case '\025': /* purple bullet */
402 case '\026': /* cyan bullet */
403 case '\027': /* white bullet */
405 SDL_Rect r;
406 int hlr = c & 1 ? 255 : 0;
407 int hlg = c & 2 ? 255 : 0;
408 int hlb = c & 4 ? 255 : 0;
409 Uint32 hlc = SDL_MapRGB(dst->format, hlr, hlg, hlb);
410 r.x = x;
411 r.y = y;
412 r.w = FONT_CW;
413 r.h = FONT_CH;
414 SDL_FillRect(dst, &r,
415 SDL_MapRGB(dst->format, 0, 0, 0));
416 //gui_dirty(&r);
417 r.x = x + 2;
418 r.y = y + 2;
419 r.w = FONT_CW - 6;
420 r.h = FONT_CH - 6;
421 SDL_FillRect(dst, &r, hlc);
422 x += FONT_CW;
423 break;
425 default: /* printables */
427 SDL_Rect dr;
428 if(c < ' ' || c > 127)
429 c = 127;
430 c -= 32;
431 sr.x = (c % (font->w / FONT_CW)) * FONT_CW;
432 sr.y = (c / (font->w / FONT_CW)) * FONT_CH;
433 dr.x = x;
434 dr.y = y;
435 SDL_BlitSurface(font, &sr, dst, &dr);
436 //gui_dirty(&dr);
437 x += FONT_CW;
438 break;
442 if(!highlights){
443 return;
445 x = sx;
446 y = sy;
447 txt = stxt;
448 while(*txt){
449 int c = *txt++;
450 switch(c){
451 case 0: /* terminator */
452 break;
453 case '\n': /* newline */
454 x = sx;
455 y += FONT_CH;
456 break;
457 case '\t': /* tab */
458 x -= sx;
459 x += 8 * FONT_CW;
460 x %= 8 * FONT_CW;
461 x += sx;
462 break;
463 case '\001': /* red highlight */
464 case '\002': /* green highlight */
465 case '\003': /* yellow highlight */
466 case '\004': /* blue highlight */
467 case '\005': /* purple highlight */
468 case '\006': /* cyan highlight */
469 case '\007': /* white highlight */
471 int hlr = c & 1 ? 255 : 0;
472 int hlg = c & 2 ? 255 : 0;
473 int hlb = c & 4 ? 255 : 0;
474 Uint32 hlc = SDL_MapRGB(screen->format, hlr, hlg, hlb);
475 int hlw = 1;
476 if(*txt == '\001'){
477 hlw = txt[1];
478 txt += 2;
480 gui_box(x - 2, y - 2,
481 FONT_CW * hlw + 2, FONT_CH + 2,
482 hlc, dst);
483 break;
485 default: /* printables */
487 x += FONT_CW;
488 break;