WINDOW.C 14 KB

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