Subversion Repositories Games.Descent

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Portions of this file are copyright Rebirth contributors and licensed as
  3.  * described in COPYING.txt.
  4.  * Portions of this file are copyright Parallax Software and licensed
  5.  * according to the Parallax license below.
  6.  * See COPYING.txt for license details.
  7.  
  8. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  9. SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
  10. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  11. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  12. IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  13. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  14. FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  15. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
  16. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
  17. COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  18. */
  19.  
  20. /*
  21.  *
  22.  * Windowing functions and controller.
  23.  *
  24.  */
  25.  
  26. #include <stdlib.h>
  27. #include <stdio.h>
  28. #include <stdarg.h>
  29.  
  30. #include "window.h"
  31. #include "u_mem.h"
  32. #include "maths.h"
  33. #include "pstypes.h"
  34. #include "gr.h"
  35. #include "ui.h"
  36. #include "key.h"
  37. #include "mouse.h"
  38. #include "timer.h"
  39. #include "dxxerror.h"
  40. #include <memory>
  41.  
  42. namespace dcx {
  43.  
  44. #define D_X             (dlg->d_x)
  45. #define D_Y             (dlg->d_y)
  46. #define D_WIDTH         (dlg->d_width)
  47. #define D_HEIGHT        (dlg->d_height)
  48. #define D_GADGET        (dlg->d_gadget)
  49. #define D_TEXT_X        (dlg->d_text_x)
  50. #define D_TEXT_Y        (dlg->d_text_y)
  51.  
  52. #ifndef __MSDOS__
  53. #define _disable()
  54. #define _enable()
  55. #endif
  56.  
  57. #define BORDER_WIDTH 8
  58.  
  59. static void ui_dialog_draw(UI_DIALOG *dlg)
  60. {
  61.         int x, y, w, h;
  62.         int req_w, req_h;
  63.  
  64.         x = D_X;
  65.         y = D_Y;
  66.         w = D_WIDTH;
  67.         h = D_HEIGHT;
  68.  
  69.         req_w = w;
  70.         req_h = h;
  71.        
  72.         if (dlg->d_flags & DF_BORDER)
  73.         {
  74.                 req_w -= 2*BORDER_WIDTH;
  75.                 req_h -= 2*BORDER_WIDTH;
  76.                
  77.                 gr_set_default_canvas();
  78.                 ui_draw_frame(*grd_curcanv, x, y, x + w - 1, y + h - 1);
  79.         }
  80.        
  81.         ui_dialog_set_current_canvas(dlg);
  82.        
  83.         if (dlg->d_flags & DF_FILLED)
  84.                 ui_draw_box_out(*grd_curcanv, 0, 0, req_w-1, req_h-1);
  85.        
  86.         gr_set_fontcolor(*grd_curcanv, CBLACK, CWHITE);
  87. }
  88.  
  89.  
  90. // The dialog handler borrows heavily from the newmenu_handler
  91. static window_event_result ui_dialog_handler(window *wind,const d_event &event, UI_DIALOG *dlg)
  92. {
  93.         window_event_result rval{window_event_result::ignored};
  94.  
  95.         if (event.type == EVENT_WINDOW_ACTIVATED ||
  96.                 event.type == EVENT_WINDOW_DEACTIVATED)
  97.                 return window_event_result::ignored;
  98.        
  99.         if (dlg->d_callback)
  100.                 if ((rval = (*dlg->d_callback)(dlg, event, dlg->d_userdata)) != window_event_result::ignored)
  101.                         return rval;            // event handled
  102.  
  103.         switch (event.type)
  104.         {
  105.                 case EVENT_IDLE:
  106.                         timer_delay2(50);
  107.                         DXX_BOOST_FALLTHROUGH;
  108.                 case EVENT_MOUSE_BUTTON_DOWN:
  109.                 case EVENT_MOUSE_BUTTON_UP:
  110.                 case EVENT_MOUSE_MOVED:
  111.                 case EVENT_KEY_COMMAND:
  112.                 case EVENT_KEY_RELEASE:
  113.                         return ui_dialog_do_gadgets(dlg, event);
  114.                 case EVENT_WINDOW_DRAW:
  115.                 {
  116.                         ui_dialog_draw(dlg);
  117.                         rval = ui_dialog_do_gadgets(dlg, event);
  118.                         if (rval != window_event_result::close)
  119.                         {
  120.                                 d_event event2 = { EVENT_UI_DIALOG_DRAW };
  121.                                 window_send_event(*wind, event2);
  122.                         }
  123.                         return rval;
  124.                 }
  125.  
  126.                 case EVENT_WINDOW_CLOSE:
  127.                         if (rval != window_event_result::deleted)       // check if handler already deleted dialog (e.g. if UI_DIALOG was subclassed)
  128.                                 delete dlg;
  129.                         return window_event_result::ignored;    // free the window in any case (until UI_DIALOG is subclass of window)
  130.                 default:
  131.                         return window_event_result::ignored;
  132.         }
  133. }
  134.  
  135. UI_DIALOG::UI_DIALOG(short x, short y, short w, short h, const enum dialog_flags flags, const ui_subfunction_t<void> callback, void *const userdata, const void *const createdata) :
  136. d_callback(callback), gadget(nullptr), keyboard_focus_gadget(nullptr), d_userdata(userdata), d_text_x(0), d_text_y(0), d_flags(flags)
  137. {
  138.         int sw, sh, req_w, req_h;
  139.  
  140.         auto dlg = this;
  141.         sw = grd_curscreen->get_screen_width();
  142.         sh = grd_curscreen->get_screen_height();
  143.  
  144.         //mouse_set_limits(0, 0, sw - 1, sh - 1);
  145.  
  146.         req_w = w;
  147.         req_h = h;
  148.        
  149.         if (flags & DF_BORDER)
  150.         {
  151.                 x -= BORDER_WIDTH;
  152.                 y -= BORDER_WIDTH;
  153.                 w += 2*BORDER_WIDTH;
  154.                 h += 2*BORDER_WIDTH;
  155.         }
  156.  
  157.         if ( x < 0 ) x = 0;
  158.         if ( (x+w-1) >= sw ) x = sw - w;
  159.         if ( y < 0 ) y = 0;
  160.         if ( (y+h-1) >= sh ) y = sh - h;
  161.  
  162.         D_X = x;
  163.         D_Y = y;
  164.         D_WIDTH = w;
  165.         D_HEIGHT = h;
  166.         selected_gadget = NULL;
  167.  
  168.         dlg->wind = window_create(grd_curscreen->sc_canvas,
  169.                                                  x + ((flags & DF_BORDER) ? BORDER_WIDTH : 0),
  170.                                                  y + ((flags & DF_BORDER) ? BORDER_WIDTH : 0),
  171.                                                  req_w, req_h, ui_dialog_handler, dlg, createdata);
  172.        
  173.         if (!(flags & DF_MODAL))
  174.                 window_set_modal(dlg->wind, 0); // make this window modeless, allowing events to propogate through the window stack
  175. }
  176.  
  177. window *ui_dialog_get_window(UI_DIALOG *dlg)
  178. {
  179.         return dlg->wind;
  180. }
  181.  
  182. void ui_dialog_set_current_canvas(UI_DIALOG *dlg)
  183. {
  184.         gr_set_current_canvas(window_get_canvas(*dlg->wind));
  185. }
  186.  
  187. UI_DIALOG::~UI_DIALOG()
  188. {
  189.         selected_gadget = NULL;
  190. }
  191.  
  192. void ui_close_dialog( UI_DIALOG * dlg )
  193. {
  194.         window_close(dlg->wind);
  195. }
  196.  
  197. #if 0
  198. void restore_state()
  199. {
  200.         _disable();
  201.         range_for (const int i, xrange(256u))
  202.         {
  203.                 keyd_pressed[i] = SavedState[i];
  204.         }
  205.         _enable();
  206. }
  207.  
  208.  
  209. void ui_mega_process()
  210. {
  211.         int mx, my, mz;
  212.         unsigned char k;
  213.        
  214.         event_process();
  215.  
  216.         switch( Record )
  217.         {
  218.         case 0:
  219.                 mouse_get_delta( &mx, &my, &mz );
  220.                 Mouse.new_dx = mx;
  221.                 Mouse.new_dy = my;
  222.                 Mouse.new_buttons = mouse_get_btns();
  223.                 last_keypress = key_inkey();
  224.  
  225.                 if ( Mouse.new_buttons || last_keypress || Mouse.new_dx || Mouse.new_dy )       {
  226.                         last_event = timer_query();
  227.                 }
  228.  
  229.                 break;
  230.         case 1:
  231.  
  232.                 if (ui_event_counter==0 )
  233.                 {
  234.                         EventBuffer[ui_event_counter].frame = 0;
  235.                         EventBuffer[ui_event_counter].type = 7;
  236.                         EventBuffer[ui_event_counter].data = ui_number_of_events;
  237.                         ui_event_counter++;
  238.                 }
  239.  
  240.  
  241.                 if (ui_event_counter==1 && (RecordFlags & UI_RECORD_MOUSE) )
  242.                 {
  243.                         Mouse.new_buttons = 0;
  244.                         EventBuffer[ui_event_counter].frame = FrameCount;
  245.                         EventBuffer[ui_event_counter].type = 6;
  246.                         EventBuffer[ui_event_counter].data = ((Mouse.y & 0xFFFF) << 16) | (Mouse.x & 0xFFFF);
  247.                         ui_event_counter++;
  248.                 }
  249.  
  250.                 mouse_get_delta( &mx, &my, &mz );
  251.                 MouseDX = mx;
  252.                 MouseDY = my;
  253.                 MouseButtons = mouse_get_btns();
  254.  
  255.                 Mouse.new_dx = MouseDX;
  256.                 Mouse.new_dy = MouseDY;
  257.  
  258.                 if ((MouseDX != 0 || MouseDY != 0)  && (RecordFlags & UI_RECORD_MOUSE)  )
  259.                 {
  260.                         if (ui_event_counter < ui_number_of_events-1 )
  261.                         {
  262.                                 EventBuffer[ui_event_counter].frame = FrameCount;
  263.                                 EventBuffer[ui_event_counter].type = 1;
  264.                                 EventBuffer[ui_event_counter].data = ((MouseDY & 0xFFFF) << 16) | (MouseDX & 0xFFFF);
  265.                                 ui_event_counter++;
  266.                         } else {
  267.                                 Record = 0;
  268.                         }
  269.  
  270.                 }
  271.  
  272.                 if ( (MouseButtons != Mouse.new_buttons) && (RecordFlags & UI_RECORD_MOUSE) )
  273.                 {
  274.                         Mouse.new_buttons = MouseButtons;
  275.  
  276.                         if (ui_event_counter < ui_number_of_events-1 )
  277.                         {
  278.                                 EventBuffer[ui_event_counter].frame = FrameCount;
  279.                                 EventBuffer[ui_event_counter].type = 2;
  280.                                 EventBuffer[ui_event_counter].data = MouseButtons;
  281.                                 ui_event_counter++;
  282.                         } else {
  283.                                 Record = 0;
  284.                         }
  285.  
  286.                 }
  287.  
  288.  
  289.                 if ( keyd_last_pressed && (RecordFlags & UI_RECORD_KEYS) )
  290.                 {
  291.                         _disable();
  292.                         k = keyd_last_pressed;
  293.                         keyd_last_pressed= 0;
  294.                         _enable();
  295.  
  296.                         if (ui_event_counter < ui_number_of_events-1 )
  297.                         {
  298.                                 EventBuffer[ui_event_counter].frame = FrameCount;
  299.                                 EventBuffer[ui_event_counter].type = 3;
  300.                                 EventBuffer[ui_event_counter].data = k;
  301.                                 ui_event_counter++;
  302.                         } else {
  303.                                 Record = 0;
  304.                         }
  305.  
  306.                 }
  307.  
  308.                 if ( keyd_last_released && (RecordFlags & UI_RECORD_KEYS) )
  309.                 {
  310.                         _disable();
  311.                         k = keyd_last_released;
  312.                         keyd_last_released= 0;
  313.                         _enable();
  314.  
  315.                         if (ui_event_counter < ui_number_of_events-1 )
  316.                         {
  317.                                 EventBuffer[ui_event_counter].frame = FrameCount;
  318.                                 EventBuffer[ui_event_counter].type = 4;
  319.                                 EventBuffer[ui_event_counter].data = k;
  320.                                 ui_event_counter++;
  321.                         } else {
  322.                                 Record = 0;
  323.                         }
  324.                 }
  325.  
  326.                 last_keypress = key_inkey();
  327.  
  328.                 if (last_keypress == KEY_F12 )
  329.                 {
  330.                         ui_number_of_events = ui_event_counter;
  331.                         last_keypress = 0;
  332.                         Record = 0;
  333.                         break;
  334.                 }
  335.  
  336.                 if ((last_keypress != 0) && (RecordFlags & UI_RECORD_KEYS) )
  337.                 {
  338.                         if (ui_event_counter < ui_number_of_events-1 )
  339.                         {
  340.                                 EventBuffer[ui_event_counter].frame = FrameCount;
  341.                                 EventBuffer[ui_event_counter].type = 5;
  342.                                 EventBuffer[ui_event_counter].data = last_keypress;
  343.                                 ui_event_counter++;
  344.                         } else {
  345.                                 Record = 0;
  346.                         }
  347.                 }
  348.  
  349.                 FrameCount++;
  350.  
  351.                 break;
  352.         case 2:
  353.         case 3:
  354.                 Mouse.new_dx = 0;
  355.                 Mouse.new_dy = 0;
  356.                 Mouse.new_buttons = 0;
  357.                 last_keypress = 0;
  358.  
  359.                 if ( keyd_last_pressed ) {
  360.                         _disable();                    
  361.                         k = keyd_last_pressed;
  362.                         keyd_last_pressed = 0;
  363.                         _disable();
  364.                         SavedState[k] = 1;
  365.                 }
  366.  
  367.                 if ( keyd_last_released )
  368.                 {
  369.                         _disable();                    
  370.                         k = keyd_last_released;
  371.                         keyd_last_released = 0;
  372.                         _disable();
  373.                         SavedState[k] = 0;
  374.                 }
  375.                
  376.                 if (key_inkey() == KEY_F12 )
  377.                 {
  378.                         restore_state();
  379.                         Record = 0;
  380.                         break;
  381.                 }
  382.  
  383.                 if (EventBuffer==NULL) {
  384.                         restore_state();
  385.                         Record = 0;
  386.                         break;
  387.                 }
  388.  
  389.                 while( (ui_event_counter < ui_number_of_events) && (EventBuffer[ui_event_counter].frame <= FrameCount) )
  390.                 {
  391.                         switch ( EventBuffer[ui_event_counter].type )
  392.                         {
  393.                         case 1:     // Mouse moved
  394.                                 Mouse.new_dx = EventBuffer[ui_event_counter].data & 0xFFFF;
  395.                                 Mouse.new_dy = (EventBuffer[ui_event_counter].data >> 16) & 0xFFFF;
  396.                                 break;
  397.                         case 2:     // Mouse buttons changed
  398.                                 Mouse.new_buttons = EventBuffer[ui_event_counter].data;
  399.                                 break;
  400.                         case 3:     // Key moved down
  401.                                 keyd_pressed[ EventBuffer[ui_event_counter].data ] = 1;
  402.                                 break;
  403.                         case 4:     // Key moved up
  404.                                 keyd_pressed[ EventBuffer[ui_event_counter].data ] = 0;
  405.                                 break;
  406.                         case 5:     // Key pressed
  407.                                 last_keypress = EventBuffer[ui_event_counter].data;
  408.                                 break;
  409.                         case 6:     // Initial Mouse X position
  410.                                 Mouse.x = EventBuffer[ui_event_counter].data & 0xFFFF;
  411.                                 Mouse.y = (EventBuffer[ui_event_counter].data >> 16) & 0xFFFF;
  412.                                 break;
  413.                         case 7:
  414.                                 break;
  415.                         }
  416.                         ui_event_counter++;
  417.                         if (ui_event_counter >= ui_number_of_events )
  418.                         {
  419.                                 Record = 0;
  420.                                 restore_state();
  421.                                 //( 0, "Done playing %d events.\n", ui_number_of_events );
  422.                         }
  423.                 }
  424.  
  425.                 switch (Record)
  426.                 {
  427.                 case 2:
  428.                         {
  429.                                 int next_frame;
  430.                        
  431.                                 if ( ui_event_counter < ui_number_of_events )
  432.                                 {
  433.                                         next_frame = EventBuffer[ui_event_counter].frame;
  434.                                        
  435.                                         if ( (FrameCount+PlaybackSpeed) < next_frame )
  436.                                                 FrameCount = next_frame - PlaybackSpeed;
  437.                                         else
  438.                                                 FrameCount++;
  439.                                 } else {
  440.                                         FrameCount++;
  441.                                 }      
  442.                         }
  443.                         break;
  444.  
  445.                 case 3:                
  446.                         if ( ui_event_counter < ui_number_of_events )
  447.                                 FrameCount = EventBuffer[ui_event_counter].frame;
  448.                         else           
  449.                                 FrameCount++;
  450.                         break;
  451.                 default:               
  452.                         FrameCount++;
  453.                 }
  454.         }
  455.  
  456.         ui_mouse_process();
  457.  
  458. }
  459. #endif // 0
  460.  
  461. void (ui_dprintf_at)( UI_DIALOG * dlg, short x, short y, const char * format, ... )
  462. {
  463.         char buffer[1000];
  464.         va_list args;
  465.  
  466.         va_start(args, format );
  467.         vsnprintf(buffer,sizeof(buffer),format,args);
  468.         va_end(args);
  469.  
  470.         ui_dputs_at(dlg, x, y, buffer);
  471. }
  472.  
  473. void ui_dputs_at( UI_DIALOG * dlg, short x, short y, const char * buffer )
  474. {
  475.         ui_dialog_set_current_canvas( dlg );
  476.         gr_string(*grd_curcanv, *grd_curcanv->cv_font, x, y, buffer);
  477. }
  478.  
  479. }
  480.