]> icculus.org git repositories - btb/d2x.git/blob - ui/window.c
no unnecessarily including MS DOS headers
[btb/d2x.git] / ui / window.c
1 /* $Id: window.c,v 1.7 2005-01-25 21:31:45 schaffner Exp $ */
2 /*
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
13 */
14
15 #ifdef RCS
16 static char rcsid[] = "$Id: window.c,v 1.7 2005-01-25 21:31:45 schaffner Exp $";
17 #endif
18
19 #ifdef HAVE_CONFIG_H
20 #include "conf.h"
21 #endif
22
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <stdarg.h>
26 #include <dos.h>
27
28 #include "u_mem.h"
29 #include "fix.h"
30 #include "pstypes.h"
31 #include "gr.h"
32 #include "ui.h"
33 #include "key.h"
34 #include "timer.h"
35
36 #include "mono.h"
37 #include "mouse.h"
38
39
40 #define W_BACKGROUND    (wnd->background )
41 #define W_X             (wnd->x)
42 #define W_Y             (wnd->y)
43 #define W_WIDTH         (wnd->width)
44 #define W_HEIGHT        (wnd->height)
45 #define W_OLDCANVAS     (wnd->oldcanvas)
46 #define W_CANVAS        (wnd->canvas)
47 #define W_GADGET        (wnd->gadget)
48 #define W_TEXT_X        (wnd->text_x)
49 #define W_TEXT_Y        (wnd->text_y)
50 #define W_NEXT          (wnd->next)
51 #define W_PREV          (wnd->prev)
52
53
54 UI_WINDOW * CurWindow = NULL;
55 UI_WINDOW * FirstWindow = NULL;
56 UI_WINDOW * LastWindow = NULL;
57
58 int last_keypress = 0;
59
60 #define BORDER_WIDTH 8
61
62 static unsigned int FrameCount = 0;
63 unsigned int ui_event_counter = 0;
64 unsigned int ui_number_of_events = 0;
65 static UI_EVENT *   EventBuffer = NULL;
66 static int          Record = 0;
67 static int          RecordFlags = 0;
68
69 static short MouseDX=0, MouseDY=0, MouseButtons=0;
70
71 static unsigned char SavedState[256];
72
73 static int PlaybackSpeed = 1;
74
75 extern void ui_draw_frame( short x1, short y1, short x2, short y2 );
76
77 // 1=1x faster, 2=2x faster, etc
78 void ui_set_playback_speed( int speed )
79 {
80         PlaybackSpeed = speed;
81 }
82
83 int ui_record_events( int NumberOfEvents, UI_EVENT * buffer, int Flags )
84 {
85         if ( Record > 0 || buffer==NULL ) return 1;
86
87         RecordFlags = Flags;
88         EventBuffer = buffer;
89         ui_event_counter = 0;
90         FrameCount = 0;
91         ui_number_of_events = NumberOfEvents;
92         Record = 1;
93         return 0;
94 }
95
96 int ui_play_events_realtime( int NumberOfEvents, UI_EVENT * buffer )
97 {       int i;
98         if ( buffer == NULL ) return 1;
99
100         EventBuffer = buffer;
101         FrameCount = 0;
102         ui_event_counter = 0;
103         ui_number_of_events = NumberOfEvents;
104         Record = 2;
105         _disable();
106         keyd_last_released= 0;
107         keyd_last_pressed= 0;
108         for (i=0; i<256; i++ )
109                 SavedState[i] = keyd_pressed[i];
110         _enable();
111         key_flush();
112         return 0;
113 }
114
115 int ui_play_events_fast( int NumberOfEvents, UI_EVENT * buffer )
116 {
117         int i;
118         if ( buffer == NULL ) return 1;
119
120         EventBuffer = buffer;
121         FrameCount = 0;
122         ui_event_counter = 0;
123         ui_number_of_events = NumberOfEvents;
124         Record = 3;
125         _disable();
126         keyd_last_released= 0;
127         keyd_last_pressed= 0;
128
129         //mprintf( 0, "Before: ", i );
130         for (i=0; i<256; i++ )
131         {
132                 //if (keyd_pressed[i]) mprintf( 0, "%d ", i );
133                 SavedState[i] = keyd_pressed[i];
134         }
135         //mprintf( 0, "\n" );
136         _enable();
137         key_flush();
138         return 0;
139 }
140
141 // Returns:  0=Normal, 1=Recording, 2=Playback normal, 3=Playback fast
142 int ui_recorder_status()
143 {
144         return Record;
145 }
146
147 void add_window_to_end( UI_WINDOW * wnd )
148 {
149         if (LastWindow) {
150                 W_PREV = LastWindow;
151                 LastWindow->next = wnd;
152         }
153         LastWindow = wnd;
154         if (!FirstWindow)
155                 FirstWindow = wnd;
156 }
157
158 void add_window_to_beg( UI_WINDOW * wnd )
159 {
160         if (FirstWindow) {
161                 W_NEXT = FirstWindow;
162                 FirstWindow->prev = wnd;
163         }
164         FirstWindow = wnd;
165         if (!LastWindow)
166                 LastWindow = wnd;
167 }
168
169 // Add w1 after w2
170 void add_window_after( UI_WINDOW * w1, UI_WINDOW * w2 )
171 {
172         w1->prev = w2;
173         w1->next = w2->next;
174         w2->next = w1;
175         if (w1->next == NULL )
176                 LastWindow = w1;
177         else
178                 w1->next->prev = w1;
179 }
180
181 void close_all()
182 {
183         UI_WINDOW *sav, *wnd = LastWindow;
184
185         while(wnd)
186         {
187                 sav = W_PREV;
188                 ui_close_window(wnd);
189                 wnd = sav;
190         }
191 }
192
193 void remove_window( UI_WINDOW * wnd )
194 {
195         if (W_NEXT)
196                 W_NEXT->prev = W_PREV;
197         if (W_PREV)
198                 W_PREV->next = W_NEXT;
199         if (FirstWindow == wnd )
200                 FirstWindow = W_NEXT;
201         if (LastWindow == wnd )
202                 LastWindow = W_PREV;
203         W_NEXT = W_PREV = NULL;
204 }
205
206
207
208 UI_WINDOW * ui_open_window( short x, short y, short w, short h, int flags )
209 {
210         UI_WINDOW * wnd;
211         int sw, sh, req_w, req_h;
212
213         wnd = (UI_WINDOW *)malloc(sizeof(UI_WINDOW));
214         if (wnd==NULL) exit(1);
215
216         W_NEXT = NULL;
217         W_PREV = NULL;
218
219         add_window_to_end( wnd );
220
221         sw = grd_curscreen->sc_w;
222         sh = grd_curscreen->sc_h;
223
224         //mouse_set_limits(0, 0, sw - 1, sh - 1);
225
226         req_w = w;
227         req_h = h;
228
229         if (flags & WIN_BORDER)
230         {
231                 x -= BORDER_WIDTH;
232                 y -= BORDER_WIDTH;
233                 w += 2*BORDER_WIDTH;
234                 h += 2*BORDER_WIDTH;
235         }
236
237         if ( x < 0 ) x = 0;
238         if ( (x+w-1) >= sw ) x = sw - w;
239         if ( y < 0 ) y = 0;
240         if ( (y+h-1) >= sh ) y = sh - h;
241
242         W_X = x;
243         W_Y = y;
244         W_WIDTH = w;
245         W_HEIGHT = h;
246         W_OLDCANVAS = grd_curcanv;
247         W_GADGET = NULL;
248         wnd->keyboard_focus_gadget = NULL;
249
250         ui_mouse_hide();
251
252         if (flags & WIN_SAVE_BG)
253         {
254                 W_BACKGROUND = gr_create_bitmap( w, h );
255                 gr_bm_ubitblt(w, h, 0, 0, x, y, &(grd_curscreen->sc_canvas.cv_bitmap), W_BACKGROUND );
256         }
257         else
258                 W_BACKGROUND = NULL;
259
260         if (flags & WIN_BORDER)
261         {
262                 W_CANVAS = gr_create_sub_canvas( &(grd_curscreen->sc_canvas), x+BORDER_WIDTH, y+BORDER_WIDTH, req_w, req_h );
263                 gr_set_current_canvas( NULL );
264                 ui_draw_frame( x, y, x+w-1, y+h-1 );
265         }
266         else
267                 W_CANVAS = gr_create_sub_canvas( &(grd_curscreen->sc_canvas), x, y, req_w, req_h );
268
269         gr_set_current_canvas( W_CANVAS );
270
271         if (flags & WIN_FILLED)
272                 ui_draw_box_out( 0, 0, req_w-1, req_h-1 );
273
274         gr_set_fontcolor( CBLACK, CWHITE );
275
276         selected_gadget = NULL;
277
278         W_TEXT_X = 0;
279         W_TEXT_Y = 0;
280
281         return wnd;
282
283 }
284
285 void ui_close_window( UI_WINDOW * wnd )
286 {
287
288         ui_mouse_hide();
289
290         ui_gadget_delete_all( wnd );
291
292         if (W_BACKGROUND)
293         {
294                 gr_bm_ubitblt(W_WIDTH, W_HEIGHT, W_X, W_Y, 0, 0, W_BACKGROUND, &(grd_curscreen->sc_canvas.cv_bitmap));
295                 gr_free_bitmap( W_BACKGROUND );
296         } else
297         {
298                 gr_set_current_canvas( NULL );
299                 gr_setcolor( CBLACK );
300                 gr_rect( W_X, W_Y, W_X+W_WIDTH-1, W_Y+W_HEIGHT-1 );
301         }
302
303         gr_free_sub_canvas( W_CANVAS );
304
305         gr_set_current_canvas( W_OLDCANVAS );
306
307         selected_gadget = NULL;
308
309         remove_window( wnd );
310
311         if (CurWindow==wnd)
312                 CurWindow = NULL;
313
314         free( wnd );
315
316         ui_mouse_show();
317 }
318
319 void restore_state()
320 {
321         int i;
322         _disable();
323         //mprintf( 0, "After: " );
324         for (i=0; i<256; i++ )
325         {
326                 //if (SavedState[i]) mprintf( 0, "%d ", i );
327                 keyd_pressed[i] = SavedState[i];
328         }
329         //mprintf( 0, "\n" );
330         _enable();
331 }
332
333
334 int last_event = 0;
335
336 void ui_reset_idle_seconds()
337 {
338         last_event = timer_get_fixed_seconds();
339 }
340
341 int ui_get_idle_seconds()
342 {
343         return (timer_get_fixed_seconds() - last_event)/F1_0;
344 }
345
346 void ui_mega_process()
347 {
348         int mx, my;
349         unsigned char k;
350         
351         switch( Record )
352         {
353         case 0:
354                 mouse_get_delta( &mx, &my );
355                 Mouse.new_dx = mx;
356                 Mouse.new_dy = my;
357                 Mouse.new_buttons = mouse_get_btns();
358                 last_keypress = key_inkey();
359
360                 if ( Mouse.new_buttons || last_keypress || Mouse.new_dx || Mouse.new_dy )       {
361                         last_event = TICKER;
362                 }
363
364                 break;
365         case 1:
366
367                 if (ui_event_counter==0 )
368                 {
369                         EventBuffer[ui_event_counter].frame = 0;
370                         EventBuffer[ui_event_counter].type = 7;
371                         EventBuffer[ui_event_counter].data = ui_number_of_events;
372                         ui_event_counter++;
373                 }
374
375
376                 if (ui_event_counter==1 && (RecordFlags & UI_RECORD_MOUSE) )
377                 {
378                         Mouse.new_buttons = 0;
379                         EventBuffer[ui_event_counter].frame = FrameCount;
380                         EventBuffer[ui_event_counter].type = 6;
381                         EventBuffer[ui_event_counter].data = ((Mouse.y & 0xFFFF) << 16) | (Mouse.x & 0xFFFF);
382                         ui_event_counter++;
383                 }
384
385                 mouse_get_delta( &mx, &my );
386                 MouseDX = mx;
387                 MouseDY = my;
388                 MouseButtons = mouse_get_btns();
389
390                 Mouse.new_dx = MouseDX;
391                 Mouse.new_dy = MouseDY;
392
393                 if ((MouseDX != 0 || MouseDY != 0)  && (RecordFlags & UI_RECORD_MOUSE)  )
394                 {
395                         if (ui_event_counter < ui_number_of_events-1 )
396                         {
397                                 EventBuffer[ui_event_counter].frame = FrameCount;
398                                 EventBuffer[ui_event_counter].type = 1;
399                                 EventBuffer[ui_event_counter].data = ((MouseDY & 0xFFFF) << 16) | (MouseDX & 0xFFFF);
400                                 ui_event_counter++;
401                                 //mprintf( 0, "EVENT:%d, Mouse moved %d,%d\n", ui_event_counter, MouseDX, MouseDY );
402                         } else {
403                                 Record = 0;
404                         }
405
406                 }
407
408                 if ( (MouseButtons != Mouse.new_buttons) && (RecordFlags & UI_RECORD_MOUSE) )
409                 {
410                         Mouse.new_buttons = MouseButtons;
411
412                         if (ui_event_counter < ui_number_of_events-1 )
413                         {
414                                 EventBuffer[ui_event_counter].frame = FrameCount;
415                                 EventBuffer[ui_event_counter].type = 2;
416                                 EventBuffer[ui_event_counter].data = MouseButtons;
417                                 ui_event_counter++;
418                                 //mprintf( 0, "EVENT:%d, Mouse buttons changed %d\n", ui_event_counter, MouseButtons );
419                         } else {
420                                 Record = 0;
421                         }
422
423                 }
424
425
426                 if ( keyd_last_pressed && (RecordFlags & UI_RECORD_KEYS) )
427                 {
428                         _disable();
429                         k = keyd_last_pressed;
430                         keyd_last_pressed= 0;
431                         _enable();
432
433                         if (ui_event_counter < ui_number_of_events-1 )
434                         {
435                                 EventBuffer[ui_event_counter].frame = FrameCount;
436                                 EventBuffer[ui_event_counter].type = 3;
437                                 EventBuffer[ui_event_counter].data = k;
438                                 ui_event_counter++;
439                                 //mprintf( 0, "EVENT:%d, Key %d pressed\n", ui_event_counter, k );
440                         } else {
441                                 Record = 0;
442                         }
443
444                 }
445
446                 if ( keyd_last_released && (RecordFlags & UI_RECORD_KEYS) )
447                 {
448                         _disable();
449                         k = keyd_last_released;
450                         keyd_last_released= 0;
451                         _enable();
452
453                         if (ui_event_counter < ui_number_of_events-1 )
454                         {
455                                 EventBuffer[ui_event_counter].frame = FrameCount;
456                                 EventBuffer[ui_event_counter].type = 4;
457                                 EventBuffer[ui_event_counter].data = k;
458                                 ui_event_counter++;
459                                 //mprintf( 0, "EVENT:%d, Key %d released\n", ui_event_counter, k );
460                         } else {
461                                 Record = 0;
462                         }
463                 }
464
465                 last_keypress = key_inkey();
466
467                 if (last_keypress == KEY_F12 )
468                 {
469                         ui_number_of_events = ui_event_counter;
470                         last_keypress = 0;
471                         Record = 0;
472                         break;
473                 }
474
475                 if ((last_keypress != 0) && (RecordFlags & UI_RECORD_KEYS) )
476                 {
477                         if (ui_event_counter < ui_number_of_events-1 )
478                         {
479                                 EventBuffer[ui_event_counter].frame = FrameCount;
480                                 EventBuffer[ui_event_counter].type = 5;
481                                 EventBuffer[ui_event_counter].data = last_keypress;
482                                 ui_event_counter++;
483                                 //mprintf( 0, "EVENT:%d, Keypressed %d\n", ui_event_counter, last_keypress );
484                         } else {
485                                 Record = 0;
486                         }
487                 }
488
489                 FrameCount++;
490
491                 break;
492         case 2:
493         case 3:
494                 Mouse.new_dx = 0;
495                 Mouse.new_dy = 0;
496                 Mouse.new_buttons = 0;
497                 last_keypress = 0;
498
499                 if ( keyd_last_pressed ) {
500                         _disable();                     
501                         k = keyd_last_pressed;
502                         keyd_last_pressed = 0;
503                         _disable();
504                         SavedState[k] = 1;
505                 }
506
507                 if ( keyd_last_released ) 
508                 {
509                         _disable();                     
510                         k = keyd_last_released;
511                         keyd_last_released = 0;
512                         _disable();
513                         SavedState[k] = 0;
514                 }
515                 
516                 if (key_inkey() == KEY_F12 )
517                 {
518                         //mprintf( 0, "Playing stopped.\n" );
519                         restore_state();
520                         Record = 0;
521                         break;
522                 }
523
524                 if (EventBuffer==NULL) {
525                         restore_state();
526                         Record = 0;
527                         break;
528                 }
529
530                 while( (ui_event_counter < ui_number_of_events) && (EventBuffer[ui_event_counter].frame <= FrameCount) )
531                 {
532                         switch ( EventBuffer[ui_event_counter].type )
533                         {
534                         case 1:     // Mouse moved
535                                 Mouse.new_dx = EventBuffer[ui_event_counter].data & 0xFFFF;
536                                 Mouse.new_dy = (EventBuffer[ui_event_counter].data >> 16) & 0xFFFF;
537                                 break;
538                         case 2:     // Mouse buttons changed
539                                 Mouse.new_buttons = EventBuffer[ui_event_counter].data;
540                                 break;
541                         case 3:     // Key moved down
542                                 keyd_pressed[ EventBuffer[ui_event_counter].data ] = 1;
543                                 break;
544                         case 4:     // Key moved up
545                                 keyd_pressed[ EventBuffer[ui_event_counter].data ] = 0;
546                                 break;
547                         case 5:     // Key pressed
548                                 last_keypress = EventBuffer[ui_event_counter].data;
549                                 break;
550                         case 6:     // Initial Mouse X position
551                                 Mouse.x = EventBuffer[ui_event_counter].data & 0xFFFF;
552                                 Mouse.y = (EventBuffer[ui_event_counter].data >> 16) & 0xFFFF;
553                                 break;
554                         case 7:
555                                 break;
556                         }
557                         ui_event_counter++;
558                         if (ui_event_counter >= ui_number_of_events )
559                         {
560                                 Record = 0;
561                                 restore_state();
562                                 //( 0, "Done playing %d events.\n", ui_number_of_events );
563                         }
564                 }
565
566                 switch (Record)
567                 {
568                 case 2:
569                         {
570                                 int next_frame;
571                         
572                                 if ( ui_event_counter < ui_number_of_events )
573                                 {
574                                         next_frame = EventBuffer[ui_event_counter].frame;
575                                         
576                                         if ( (FrameCount+PlaybackSpeed) < next_frame )
577                                                 FrameCount = next_frame - PlaybackSpeed;
578                                         else
579                                                 FrameCount++;
580                                 } else {
581                                         FrameCount++;
582                                 }       
583                         }
584                         break;
585
586                 case 3:                 
587                         if ( ui_event_counter < ui_number_of_events ) 
588                                 FrameCount = EventBuffer[ui_event_counter].frame;
589                         else            
590                                 FrameCount++;
591                         break;
592                 default:                
593                         FrameCount++;
594                 }
595         }
596
597         ui_mouse_process();
598
599 }
600
601 void ui_wprintf( UI_WINDOW * wnd, char * format, ... )
602 {
603         char buffer[1000];
604         va_list args;
605
606         va_start(args, format );
607         vsprintf(buffer,format,args);
608
609         gr_set_current_canvas( W_CANVAS );
610
611         ui_mouse_hide();
612         W_TEXT_X = gr_string( W_TEXT_X, W_TEXT_Y, buffer );
613         ui_mouse_show();
614 }
615
616 void ui_wprintf_at( UI_WINDOW * wnd, short x, short y, char * format, ... )
617 {
618         char buffer[1000];
619         va_list args;
620
621         va_start(args, format );
622         vsprintf(buffer,format,args);
623
624         gr_set_current_canvas( W_CANVAS );
625
626         ui_mouse_hide();
627         gr_string( x, y, buffer );
628         ui_mouse_show();
629
630 }