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-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  18. */
  19.  
  20. /*
  21.  *
  22.  * object selection stuff.
  23.  *
  24.  */
  25.  
  26. #include <memory>
  27. #include <stdlib.h>
  28. #include <stdio.h>
  29. #include "inferno.h"
  30. #include "screens.h"                    // For GAME_SCREEN?????
  31. #include "editor.h"                     // For TMAP_CURBOX??????
  32. #include "gr.h"                         // For canves, font stuff
  33. #include "ui.h"                         // For UI_GADGET stuff
  34. #include "object.h"                     // For robot_bms
  35. #include "event.h"
  36. #include "dxxerror.h"
  37. #include "objpage.h"
  38. #include "bm.h"
  39. #include "player.h"
  40. #include "piggy.h"
  41. #include "cntrlcen.h"
  42. #include "kdefs.h"
  43.  
  44. constexpr std::integral_constant<unsigned, 8> OBJS_PER_PAGE{};
  45.  
  46. static std::array<std::unique_ptr<UI_GADGET_USERBOX>, OBJS_PER_PAGE> ObjBox;
  47. static std::unique_ptr<UI_GADGET_USERBOX> ObjCurrent;
  48.  
  49. static int ObjectPage = 0;
  50.  
  51. #include "vecmat.h"
  52. #include "3d.h"
  53. #include "robot.h"
  54. #include "texmap.h"
  55.  
  56. #include "hostage.h"
  57. #include "powerup.h"
  58.  
  59. namespace {
  60.  
  61. vms_angvec objpage_view_orient;
  62. fix objpage_view_dist;
  63.  
  64. class object_dialog
  65. {
  66. public:
  67.         std::unique_ptr<UI_GADGET_BUTTON> prev_object, next_object, first_object, last_object, dec_pitch, inc_pitch, dec_bank, inc_bank, dec_heading, inc_heading, inc_z, dec_z, reset_orient;
  68. };
  69.  
  70. }
  71.  
  72. static object_dialog objpage_dialog;
  73.  
  74. //this is bad to have the extern, but this snapshot stuff is special
  75.  
  76. //canvas set
  77. void draw_object_picture(grs_canvas &canvas, const unsigned id, const vms_angvec &orient_angles, const unsigned type)
  78. {
  79.  
  80.         if (id >= Num_object_subtypes)
  81.                 return;
  82.  
  83.         auto &Robot_info = LevelSharedRobotInfoState.Robot_info;
  84.         switch (type) {
  85.  
  86.                 case OBJ_HOSTAGE:
  87.                         PIGGY_PAGE_IN(Vclip[Hostage_vclip_num[id]].frames[0]);
  88.                         gr_bitmap(canvas, 0, 0, GameBitmaps[Vclip[Hostage_vclip_num[id]].frames[0].index]);
  89.                         break;
  90.  
  91.                 case OBJ_POWERUP:
  92.                         if ( Powerup_info[id].vclip_num > -1 )  {
  93.                                 PIGGY_PAGE_IN(Vclip[Powerup_info[id].vclip_num].frames[0]);
  94.                                 gr_bitmap(canvas, 0, 0, GameBitmaps[Vclip[Powerup_info[id].vclip_num].frames[0].index]);
  95.                         }
  96.                         break;
  97.  
  98.                 case OBJ_PLAYER:
  99.                         draw_model_picture(canvas, Player_ship->model_num, orient_angles);              // Draw a poly model below
  100.                         break;
  101.  
  102.                 case OBJ_ROBOT:
  103.                         draw_model_picture(canvas, Robot_info[id].model_num, orient_angles);    // Draw a poly model below
  104.                         break;
  105.  
  106.                 case OBJ_CNTRLCEN:
  107.                         draw_model_picture(canvas, get_reactor_model_number(id), orient_angles);
  108.                         break;
  109.                 case OBJ_CLUTTER:
  110.                         draw_model_picture(canvas, id, orient_angles);
  111.                         break;
  112.                 default:
  113.                         //Int3();       // Invalid type!!!
  114.                         return;
  115.         }
  116.  
  117. }
  118.  
  119. static int redraw_current_object()
  120. {
  121.         grs_canvas &cc = *grd_curcanv;
  122.         gr_set_current_canvas(ObjCurrent->canvas);
  123.         draw_object_picture(*grd_curcanv, Cur_object_id, objpage_view_orient, Cur_object_type);
  124.         gr_set_current_canvas(cc);
  125.         return 1;
  126. }
  127.  
  128. static void gr_label_box( int i)
  129. {
  130.         gr_clear_canvas(*grd_curcanv, BM_XRGB(0,0,0));
  131.         draw_object_picture(*grd_curcanv, i, objpage_view_orient, Cur_object_type);
  132.  
  133. //      char s[20];
  134. //      sprintf( s, " %d ", i );
  135. //      gr_clear_canvas( BM_XRGB(0,15,0) );
  136. //      gr_set_fontcolor( CWHITE, BM_XRGB(0,15,0) );
  137. //      ui_string_centered(  grd_curcanv->cv_bitmap.bm_w/2, grd_curcanv->cv_bitmap.bm_h/2, Description[i] );
  138. }
  139.  
  140. int objpage_goto_first()
  141. {
  142.         ObjectPage=0;
  143.         for (int i=0;  i<OBJS_PER_PAGE; i++ ) {
  144.                 gr_set_current_canvas(ObjBox[i]->canvas);
  145.                 if (i+ObjectPage*OBJS_PER_PAGE < Num_object_subtypes ) {
  146.                         //gr_ubitmap(0,0, robot_bms[robot_bm_nums[ i+ObjectPage*OBJS_PER_PAGE ] ] );
  147.                         gr_label_box(i+ObjectPage*OBJS_PER_PAGE );
  148.                 } else
  149.                         gr_clear_canvas(*grd_curcanv, CGREY);
  150.         }
  151.  
  152.         return 1;
  153. }
  154.  
  155. static int objpage_goto_last()
  156. {
  157.         ObjectPage=(Num_object_subtypes)/OBJS_PER_PAGE;
  158.         for (int i=0;  i<OBJS_PER_PAGE; i++ )
  159.         {
  160.                 gr_set_current_canvas(ObjBox[i]->canvas);
  161.                 if (i+ObjectPage*OBJS_PER_PAGE < Num_object_subtypes )
  162.                 {
  163.                         //gr_ubitmap(0,0, robot_bms[robot_bm_nums[ i+ObjectPage*OBJS_PER_PAGE ] ] );
  164.                         gr_label_box(i+ObjectPage*OBJS_PER_PAGE );
  165.                 } else {
  166.                         gr_clear_canvas(*grd_curcanv, CGREY);
  167.                 }
  168.         }
  169.         return 1;
  170. }
  171.  
  172. static int objpage_goto_prev()
  173. {
  174.         if (ObjectPage > 0) {
  175.                 ObjectPage--;
  176.                 for (int i=0;  i<OBJS_PER_PAGE; i++ )
  177.                 {
  178.                         gr_set_current_canvas(ObjBox[i]->canvas);
  179.                         if (i+ObjectPage*OBJS_PER_PAGE < Num_object_subtypes)
  180.                         {
  181.                                 //gr_ubitmap(0,0, robot_bms[robot_bm_nums[ i+ObjectPage*OBJS_PER_PAGE ] ] );
  182.                                 gr_label_box(i+ObjectPage*OBJS_PER_PAGE );
  183.                         } else {
  184.                                 gr_clear_canvas(*grd_curcanv, CGREY);
  185.                         }
  186.                 }
  187.         }
  188.         return 1;
  189. }
  190.  
  191. static int objpage_goto_next()
  192. {
  193.         if ((ObjectPage+1)*OBJS_PER_PAGE < Num_object_subtypes) {
  194.                 ObjectPage++;
  195.                 for (int i=0;  i<OBJS_PER_PAGE; i++ )
  196.                 {
  197.                         gr_set_current_canvas(ObjBox[i]->canvas);
  198.                         if (i+ObjectPage*OBJS_PER_PAGE < Num_object_subtypes)
  199.                         {
  200.                                 //gr_ubitmap(0,0, robot_bms[robot_bm_nums[ i+ObjectPage*OBJS_PER_PAGE ] ] );
  201.                                 gr_label_box(i+ObjectPage*OBJS_PER_PAGE );
  202.                         } else {
  203.                                 gr_clear_canvas(*grd_curcanv, CGREY);
  204.                         }
  205.                 }
  206.         }
  207.         return 1;
  208. }
  209.  
  210. int objpage_grab_current(int n)
  211. {
  212.         if ((n < 0) || (n >= Num_object_subtypes)) return 0;
  213.        
  214.         ObjectPage = n / OBJS_PER_PAGE;
  215.        
  216.         if (ObjectPage*OBJS_PER_PAGE < Num_object_subtypes) {
  217.                 for (int i=0;  i<OBJS_PER_PAGE; i++ )
  218.                 {
  219.                         gr_set_current_canvas(ObjBox[i]->canvas);
  220.                         if (i + ObjectPage*OBJS_PER_PAGE < Num_object_subtypes)
  221.                         {
  222.                                 //gr_ubitmap(0,0, robot_bms[robot_bm_nums[ i+ObjectPage*OBJS_PER_PAGE ] ] );
  223.                                 gr_label_box(i+ObjectPage*OBJS_PER_PAGE );
  224.                         } else {
  225.                                 gr_clear_canvas(*grd_curcanv, CGREY);
  226.                         }
  227.                 }
  228.         }
  229.  
  230.         Cur_object_id = n;
  231.         gr_set_current_canvas(ObjCurrent->canvas);
  232.         //gr_ubitmap(0,0, robot_bms[robot_bm_nums[ Cur_robot_type ] ] );
  233.         gr_label_box(Cur_object_id);
  234.  
  235.         //objpage_display_name( Texture[Cur_robot_type]->filename );
  236.        
  237.         return 1;
  238. }
  239.  
  240. int objpage_goto_next_object()
  241. {
  242.         // there should be a pop-up menu for this
  243.         switch (Cur_object_type)
  244.         {
  245.                 case OBJ_ROBOT:
  246.                         Cur_object_type = OBJ_HOSTAGE;
  247.                         Num_object_subtypes = 1;
  248.                         break;
  249.  
  250.                 case OBJ_HOSTAGE:
  251.                         Cur_object_type = OBJ_PLAYER;
  252.                         Num_object_subtypes = 1;        // can have anarchy/coop, but this is handled automatically
  253.                         break;
  254.  
  255.                 case OBJ_PLAYER:
  256.                         Cur_object_type = OBJ_POWERUP;
  257.                         Num_object_subtypes = N_powerup_types;
  258.                         break;
  259.  
  260.                 case OBJ_POWERUP:
  261.                         Cur_object_type = OBJ_CNTRLCEN;
  262.                         Num_object_subtypes = Num_reactors;
  263.                         break;
  264.  
  265.                 case OBJ_CNTRLCEN:
  266.                 default:
  267.                         Cur_object_type = OBJ_ROBOT;
  268.                         Num_object_subtypes = LevelSharedRobotInfoState.N_robot_types;
  269.                         break;
  270.         }
  271.  
  272.         objpage_grab_current(0);
  273.  
  274.         return 1;
  275.  
  276. }
  277.  
  278. #define OBJBOX_X        (TMAPBOX_X)     //location of first one
  279. #define OBJBOX_Y        (OBJCURBOX_Y - 24 )
  280. #define OBJBOX_W        64
  281. #define OBJBOX_H        64
  282.  
  283. #define DELTA_ANG 0x800
  284.  
  285. template <fixang vms_angvec::*a, fixang v>
  286. static int objpage_change_angle()
  287. {
  288.         objpage_view_orient.*a += v;
  289.         return redraw_current_object();
  290. }
  291.  
  292. #define objpage_increase_pitch objpage_change_angle<&vms_angvec::p, DELTA_ANG>
  293. #define objpage_decrease_pitch objpage_change_angle<&vms_angvec::p, -DELTA_ANG>
  294. #define objpage_increase_heading objpage_change_angle<&vms_angvec::h, DELTA_ANG>
  295. #define objpage_decrease_heading objpage_change_angle<&vms_angvec::h, -DELTA_ANG>
  296. #define objpage_increase_bank objpage_change_angle<&vms_angvec::b, DELTA_ANG>
  297. #define objpage_decrease_bank objpage_change_angle<&vms_angvec::b, -DELTA_ANG>
  298.  
  299. static int objpage_increase_z()
  300. {
  301.         objpage_view_dist -= 0x8000;
  302.         return redraw_current_object();
  303. }
  304.  
  305. static int objpage_decrease_z()
  306. {
  307.         objpage_view_dist += 0x8000;
  308.         return redraw_current_object();
  309. }
  310.  
  311. static int objpage_reset_orient()
  312. {
  313.         objpage_view_orient.p = 0;
  314.         objpage_view_orient.b = 0;
  315.         objpage_view_orient.h = -0x8000;
  316.         //objpage_view_dist = DEFAULT_VIEW_DIST;
  317.         return redraw_current_object();
  318. }
  319.  
  320.  
  321. // INIT TEXTURE STUFF
  322.  
  323. void objpage_init( UI_DIALOG *dlg )
  324. {
  325.         //Num_total_object_types = N_polygon_models + N_hostage_types + N_powerup_types;
  326.         //Assert (N_polygon_models < MAX_POLYGON_MODELS);
  327.         //Assert (Num_total_object_types < MAX_OBJTYPE );
  328.         //Assert (N_hostage_types < MAX_HOSTAGE_TYPES );
  329.         //Assert (N_powerup_types < MAX_POWERUP_TYPES );
  330.  
  331.         auto &o = objpage_dialog;
  332.         o.prev_object = ui_add_gadget_button( dlg, OBJCURBOX_X + 00, OBJCURBOX_Y - 27, 30, 20, "<<", objpage_goto_prev );
  333.         o.next_object = ui_add_gadget_button( dlg, OBJCURBOX_X + 32, OBJCURBOX_Y - 27, 30, 20, ">>", objpage_goto_next );
  334.  
  335.         o.first_object = ui_add_gadget_button( dlg, OBJCURBOX_X + 00, OBJCURBOX_Y - 54, 30, 20, "B", objpage_goto_first );
  336.         o.last_object = ui_add_gadget_button( dlg, OBJCURBOX_X + 32, OBJCURBOX_Y - 54, 30, 20, "E", objpage_goto_last );
  337.  
  338.         o.dec_pitch = ui_add_gadget_button( dlg, OBJCURBOX_X + 25, OBJCURBOX_Y + 62, 22, 13, "P-", objpage_decrease_pitch );
  339.         o.inc_pitch = ui_add_gadget_button( dlg, OBJCURBOX_X + 25, OBJCURBOX_Y + 90, 22, 13, "P+", objpage_increase_pitch );
  340.         o.dec_bank = ui_add_gadget_button( dlg, OBJCURBOX_X + 00, OBJCURBOX_Y + 90, 22, 13, "B-", objpage_decrease_bank );
  341.         o.inc_bank = ui_add_gadget_button( dlg, OBJCURBOX_X + 50, OBJCURBOX_Y + 90, 22, 13, "B+", objpage_increase_bank );
  342.         o.dec_heading = ui_add_gadget_button( dlg, OBJCURBOX_X + 00, OBJCURBOX_Y + 76, 22, 13, "H-", objpage_decrease_heading );
  343.         o.inc_heading = ui_add_gadget_button( dlg, OBJCURBOX_X + 50, OBJCURBOX_Y + 76, 22, 13, "H+", objpage_increase_heading );
  344.         o.inc_z = ui_add_gadget_button( dlg, OBJCURBOX_X + 00, OBJCURBOX_Y + 62, 22, 13, "Z+", objpage_increase_z );
  345.         o.dec_z = ui_add_gadget_button( dlg, OBJCURBOX_X + 50, OBJCURBOX_Y + 62, 22, 13, "Z-", objpage_decrease_z );
  346.         o.reset_orient = ui_add_gadget_button( dlg, OBJCURBOX_X + 25, OBJCURBOX_Y + 76, 22, 13, "R", objpage_reset_orient );
  347.  
  348.         for (int i=0;i<OBJS_PER_PAGE;i++)
  349.                 ObjBox[i] = ui_add_gadget_userbox( dlg, OBJBOX_X + (i/2)*(2+OBJBOX_W), OBJBOX_Y + (i%2)*(2+OBJBOX_H), OBJBOX_W, OBJBOX_H);
  350.         ObjCurrent = ui_add_gadget_userbox( dlg, OBJCURBOX_X, OBJCURBOX_Y-5, 64, 64 );
  351.         objpage_reset_orient();
  352. }
  353.  
  354. void objpage_close()
  355. {
  356.         //gr_free_sub_canvas(ObjnameCanvas);
  357. }
  358.  
  359.  
  360. // DO TEXTURE STUFF
  361.  
  362. int objpage_do(const d_event &event)
  363. {
  364.         if (event.type == EVENT_UI_DIALOG_DRAW)
  365.         {
  366.                 for (int i=0;  i<OBJS_PER_PAGE; i++ )
  367.                 {
  368.                         gr_set_current_canvas(ObjBox[i]->canvas);
  369.                         if (i+ObjectPage*OBJS_PER_PAGE < Num_object_subtypes)
  370.                         {
  371.                                 //gr_ubitmap(0,0, robot_bms[robot_bm_nums[ i+ObjectPage*OBJS_PER_PAGE ] ] );
  372.                                 gr_label_box(i+ObjectPage*OBJS_PER_PAGE );
  373.                         } else {
  374.                                 gr_clear_canvas(*grd_curcanv, CGREY);
  375.                         }
  376.                 }
  377.                
  378.                 // Don't reset robot_type when we return to editor.
  379.                 //      Cur_robot_type = ObjectPage*OBJS_PER_PAGE;
  380.                 gr_set_current_canvas(ObjCurrent->canvas);
  381.                 //gr_ubitmap(0,0, robot_bms[robot_bm_nums[ Cur_robot_type ] ] );
  382.                 gr_label_box(Cur_object_id);
  383.                
  384.                 //ObjnameCanvas = gr_create_sub_canvas(&grd_curscreen->sc_canvas, OBJCURBOX_X , OBJCURBOX_Y + OBJBOX_H + 10, 100, 20);
  385.                 //gr_set_current_canvas( ObjnameCanvas );
  386.                 //gr_set_curfont( ui_small_font );
  387.                 //gr_set_fontcolor( CBLACK, CWHITE );
  388.                 //objpage_display_name( Texture[Cur_robot_type]->filename );
  389.                
  390.                 return 1;
  391.         }
  392.  
  393.         for (int i=0; i<OBJS_PER_PAGE; i++ )
  394.         {
  395.                 if (GADGET_PRESSED(ObjBox[i].get()) && (i+ObjectPage*OBJS_PER_PAGE < Num_object_subtypes))
  396.                 {
  397.                         Cur_object_id = i+ObjectPage*OBJS_PER_PAGE;
  398.                         gr_set_current_canvas(ObjCurrent->canvas);
  399.                         //gr_ubitmap(0,0, robot_bms[robot_bm_nums[ Cur_robot_type ] ] );
  400.                         gr_label_box(Cur_object_id);
  401.                         //objpage_display_name( Texture[Cur_robot_type]->filename );
  402.                         return 1;
  403.                 }
  404.         }
  405.        
  406.         return 0;
  407. }
  408.