GAMERUN.CPP
上传用户:sycq158
上传日期:2008-10-22
资源大小:15361k
文件大小:16k
源码类别:

游戏

开发平台:

Visual C++

  1. #include <mem.h>
  2. #include <string.h>
  3. #include <stdarg.h>
  4. #include <fstream.h>
  5. #include "utils.h"
  6. #ifdef OS_DOS
  7. #include "mouse.h"
  8. #include <dos.h>
  9. #endif
  10. #include "ray.h"
  11. #include "scrcntl.h"
  12. #include "palette.h"
  13. #include "screen.h"
  14. #include "globals.h"
  15. #include "resnames.h"
  16. #include "waves.h"
  17. #include "voxinter.h"
  18. #include "scrcap.h"
  19. #include "shading.h"
  20. #include "skipping.h"
  21. #include "sound.h"
  22. #include "sprinter.h"
  23. #include "playint.h"
  24. #include "keyinfo.h"
  25. #include "raywidth.h"
  26. #include "loadwor.h"
  27. #include "keyboard.h"
  28. #include "raybuff.h"
  29. #include "timer.h"
  30. #include "gentree.h"
  31. #include "dosfuncs.h"
  32. #include "winfuncs.h"
  33. #include "scrconf.h"
  34. #include "quit.h"
  35. #include "rgobject.h"
  36. #include "ground.h"
  37. #include "closers.h"
  38. #include "visuals.h"
  39. #include "scrmes.h"
  40. #include <stdio.h>
  41. #define _PROGRAMMER_VERSION_
  42. #define UPDATE_SPEED 36.5
  43. #define MAX_ARG_LENGTH 20
  44. #define NORM_ARG 1
  45. #define FILE_ARG 2
  46. #define WTEX_ARG 3
  47. #define FTEX_ARG 4
  48. #define PLAYER_START_X (1925<<SHIFT)
  49. #define PLAYER_START_Y (550<<SHIFT)
  50. #define PLAYER_START_ANGLE ANGLE_180
  51. #define PLAYER_START_Z 8
  52. #ifdef OS_DOS
  53. #define VGA_WIDTH 320
  54. #define VGA_HEIGHT 200
  55. #define SVGA_WIDTH 640
  56. #define SVGA_HEIGHT 480
  57. #endif
  58. #define HURT_TIME 10
  59. #define STANDARD_PAL 0
  60. #define HURT_PAL 1
  61. extern "C" int _argc;
  62. extern "C" char ** _argv;
  63. typedef BOOL dimension_control_type;
  64. #define VERT_CONTROL TRUE
  65. #define HORIZ_CONTROL FALSE
  66. const char DEF_WORLD [F_NAME_LENGTH]="nraymap.dat";
  67. const char FILE_CMD [MAX_ARG_LENGTH]="-file";
  68. const char WTEX_CMD [MAX_ARG_LENGTH]="-wtex";
  69. const char FTEX_CMD [MAX_ARG_LENGTH]="-ftex";
  70. const char NO_SHADE_CMD [MAX_ARG_LENGTH]="-noshade";
  71. const char WAVE_CMD [MAX_ARG_LENGTH]="-wave";
  72. const char DEF_CAPTURE_F_NAME[F_NAME_LENGTH]="scrcap.pcx";
  73. const char END_PICT_NAME[F_NAME_LENGTH]="end.pcx";
  74. const char SKIP_CMD [MAX_ARG_LENGTH]="-fastvox";
  75. BOOL do_waves;
  76. BOOL is_super_vga;
  77.  
  78. ULONG frame_num=0;
  79. void Analyze_Args();
  80. void World_Update(long cur_update_num);
  81. void Setup_Combined_Input();        
  82. void Start_Palette();
  83. extern int raw_key;                  // the global raw keyboard data aquired from the ISR
  84.  
  85. extern int key_table[MAX_TRACKED_INPUTS-1]; // the key state table for the motion keys
  86. void Clear_Input();
  87. #ifdef OS_DOS
  88. void GetMouseInput(); // Routine to set the mouse statement flags
  89. #endif
  90. int mouse_table[MAX_TRACKED_INPUTS-1] = {0,0,0,0,0,0}; // same state table thing but for the mouse
  91. short combined_table[MAX_TRACKED_INPUTS]= {0,0,0,0,0,0,0}; // combination of mouse+keyboard
  92. #ifdef OS_DOS
  93. BOOL hasmouse=FALSE; // Boolean for whether the comp. has a mouse
  94. #endif
  95. dimension_control_type dim_control;
  96. BOOL done;
  97. void startup();
  98. void shutdown();
  99. void Global_Initialize() {
  100. Screen_Message("Initializing Hardware!");
  101. startup(); // Setup hardware stuff, etc.
  102. Screen_Message("Initializign Renderer!");
  103. initRay(); // Setup raycaster
  104. Screen_Message("Loading data!");
  105. Analyze_Args();           
  106. }
  107. extern "C" Shutdown() {
  108. #ifdef OS_DOS
  109. Dos_Close();
  110. #endif
  111. #ifdef OS_WINDOWS
  112. Win_Close();
  113. #endif
  114. }
  115. extern "C" void Error(char * error) {
  116. Shutdown();
  117. printf(error);
  118. printf("n");
  119. exit(1);
  120. }
  121. void Global_Close() {
  122. closeRay(); // Shut down the raycaster
  123. shutdown(); // Clear up memory and reset hardware
  124. }
  125. void Analyze_Args()
  126. {
  127. LONG arg_type;
  128. LONG cur_arg_num;
  129. PCHAR cur_argument;
  130. arg_type=NORM_ARG;
  131. cur_arg_num=1;
  132. do_waves=FALSE;
  133. Set_Player_Input_Buffer(combined_table);
  134. F_Scan_Load((PCHAR)DEF_WORLD);
  135. Set_Shading(SHADING_ON);
  136. Set_Skipping(SKIPPING_OFF);
  137. // go through arguments looking for user specifications
  138. while (cur_arg_num<_argc) {
  139. cur_argument=_argv[cur_arg_num];
  140. // what type of argument is this 
  141. switch (arg_type) {
  142. // normal:
  143. case NORM_ARG:
  144. // is the user specifying a world file name?
  145. if (!strnicmp(cur_argument, FILE_CMD, MAX_ARG_LENGTH))
  146. arg_type=FILE_ARG;
  147. if (!strnicmp(cur_argument, WTEX_CMD, MAX_ARG_LENGTH))
  148. arg_type=WTEX_ARG;
  149. if (!strnicmp(cur_argument, FTEX_CMD, MAX_ARG_LENGTH))
  150. arg_type=FTEX_ARG;
  151. if (!strnicmp(cur_argument, WAVE_CMD, MAX_ARG_LENGTH))
  152. do_waves=TRUE;
  153. if (!strnicmp(cur_argument, NO_SHADE_CMD, MAX_ARG_LENGTH))
  154. Set_Shading(SHADING_OFF);
  155. if (!strnicmp(cur_argument, SKIP_CMD, MAX_ARG_LENGTH))
  156. Set_Skipping(SKIPPING_ON);
  157. break;
  158. // file name:
  159. case FILE_ARG:
  160. Load_World(cur_argument);
  161. arg_type=NORM_ARG;
  162. break;
  163. //wall texture file name
  164. case WTEX_ARG:
  165. F_Spec_Load(1, cur_argument, (PCHAR)WTEX_RES);
  166. arg_type=NORM_ARG;
  167. break;
  168. //floor texture file name
  169. case FTEX_ARG:
  170. F_Spec_Load(1, cur_argument, (PCHAR)FTEX_RES);
  171. arg_type=NORM_ARG;
  172. break;
  173. default:
  174. break;
  175. }
  176. cur_arg_num++;
  177. }  
  178. the_player=Create_Object(PLAYER_START_X, PLAYER_START_Y, PLAYER_START_Z,
  179. PLAYER_START_ANGLE, PLAYER_TYPE, NULL, 3);
  180. Gen_Tree();
  181. Setup_Anim_Tex();
  182. }     
  183. UCHAR paldata[5][768];
  184. void Start_Palette() {
  185. Init_Palette();
  186. fstream fp;
  187. fp.open("standard.pal",ios::binary | ios::in | ios::out);
  188. fp.seekg(0L,ios::beg);
  189. fp.read(paldata[0],768);
  190. fp.close();
  191. fp.open("red.pal", ios::binary | ios::in | ios::out);
  192. fp.seekg(0L,ios::beg);
  193. fp.read(paldata[1],768);
  194. fp.close();
  195. Load_Palette(paldata[0], 0, 256);
  196. }
  197. void Show_Palette(short pal_handle) {
  198. Load_Palette(paldata[pal_handle], 0, 256);
  199. Activate_Palette(TRUE);
  200. }
  201. void startup()      
  202. {
  203. Init_Timer();
  204. Start_Palette();
  205. #ifdef OS_DOS
  206. if (initmouse()) { // Setup mouse
  207. hasmouse=TRUE;
  208. hidemouse();
  209. } else hasmouse=FALSE;
  210. #endif
  211. Init_Sound(); 
  212. Init_Keyboard();
  213. }
  214. void shutdown()
  215. {
  216. Close_Keyboard();
  217. Close_Timer();
  218. Close_Sound();
  219. End_Graphics();
  220. Close_Palette();
  221. }
  222. angle_type cur_vert_angle, last_vert_angle;
  223. long beg_update_num;
  224. void Do_Intro() {
  225. Play_Sound(Load_Sound("yo.wav"));
  226. long abs_z;
  227. RCastGobject picts(4);
  228. long start_update_num;
  229. picts.assigninfile("3.pcx");
  230. picts.load(0);
  231. picts.assigninfile("2.pcx");
  232. picts.load(1);
  233. picts.assigninfile("1.pcx");
  234. picts.load(2);
  235. picts.assigninfile("go.pcx");
  236. picts.load(3);
  237. for (short cur_pict=0; cur_pict<4; cur_pict++) {
  238.   cur_vert_angle=Get_Player_Vert_Angle(the_player);
  239.   if (cur_vert_angle!=last_vert_angle) {
  240.   Set_View_Angle(cur_vert_angle);
  241.   last_vert_angle=cur_vert_angle;
  242.   }
  243.   if (the_player->cur_sec->flags & VOXEL_SECTOR) {
  244. abs_z=the_player->z+Get_Voxel_Alt((PUCHAR)the_player->cur_sec->extra_data,
  245.  the_player->x, the_player->y)+the_player->type->eye_height;
  246. } else {
  247.   abs_z=the_player->z+the_player->cur_sec->floor_height+the_player->type->eye_height;
  248.   }
  249.   Render_Screen(the_player->x, the_player->y, abs_z, the_player->angle);
  250.   picts.transparent_show(buff, Get_Phys_Screen_Width(), 0,0, cur_pict);
  251. #ifdef OS_WINDOWS
  252.   Win_Copy_Buff();
  253. #endif
  254. #ifdef OS_DOS
  255.   Dos_Copy_Buff();
  256. #endif
  257.   // wait a bit
  258.   start_update_num=Get_Update_Num();
  259.   while ((start_update_num+36)>Get_Update_Num()); /* endwhile */
  260. }
  261. Start_Music();
  262. }
  263. void Post_Quit(ULONG game_result) {
  264. long abs_z;
  265. RCastGobject end_scrn;
  266.   Stop_Music();
  267. if (game_result==WINNING_GAME) {
  268.   Play_Sound(Load_Sound("king.wav"));
  269.   end_scrn.assigninfile((PCHAR)END_PICT_NAME);
  270.   end_scrn.load();
  271.   cur_vert_angle=Get_Player_Vert_Angle(the_player);
  272.   if (cur_vert_angle!=last_vert_angle) {
  273.   Set_View_Angle(cur_vert_angle);
  274.   last_vert_angle=cur_vert_angle;
  275.   }
  276.   if (the_player->cur_sec->flags & VOXEL_SECTOR) {
  277. abs_z=the_player->z+Get_Voxel_Alt((PUCHAR)the_player->cur_sec->extra_data,
  278.  the_player->x, the_player->y)+the_player->type->eye_height;
  279. } else {
  280.   abs_z=the_player->z+the_player->cur_sec->floor_height+the_player->type->eye_height;
  281.   }
  282.   Render_Screen(the_player->x, the_player->y, abs_z, the_player->angle);
  283.   end_scrn.transparent_show(buff, Get_Phys_Screen_Width(), 0,0);
  284. #ifdef OS_WINDOWS
  285.   Win_Copy_Buff();
  286. #endif
  287. #ifdef OS_DOS
  288.   Dos_Copy_Buff();
  289. #endif
  290.   raw_key=0;
  291.   long start_update_num;
  292.   start_update_num=Get_Update_Num();
  293.   while ( ((start_update_num+200)>Get_Update_Num()) && (!raw_key) );
  294.  }
  295. if (game_result==DIED_GAME) {
  296. setgmode(0x3);
  297. cout << "Just because you're paranoid, doesn't mean they're not out to get you.n";
  298. delay(5000);
  299. }
  300. done=TRUE;
  301. }
  302. void Do_Shot(PCHAR graphic_filename, PCHAR sound_filename, long time, BOOL back) {
  303. Suspend_Time();
  304. RCastGobject scrn;
  305. scrn.assigninfile(graphic_filename);
  306. scrn.load();
  307. if (back) {
  308. cur_vert_angle=Get_Player_Vert_Angle(the_player);
  309. if (cur_vert_angle!=last_vert_angle) {
  310. Set_View_Angle(cur_vert_angle);
  311. last_vert_angle=cur_vert_angle;
  312. }
  313. Render_Screen(the_player->x, the_player->y, the_player->z+the_player->type->eye_height+
  314. Ground_Height(the_player), the_player->angle);
  315. } else clearBuff();
  316. scrn.transparent_show(buff, Get_Phys_Screen_Width(), 0, 0);
  317. #ifdef OS_WINDOWS
  318. Win_Copy_Buff();
  319. #endif
  320. #ifdef OS_DOS
  321. Dos_Copy_Buff();
  322. #endif
  323. Play_Sound(Load_Sound(sound_filename));
  324. Reset_Timer();
  325. while (Get_Update_Num()<time);
  326. Resume_Time();
  327. }
  328. void Init_Main_Cycle() {
  329. Reset_Timer();
  330. Do_Intro();
  331. Reset_Timer();
  332. #ifdef OS_DOS
  333. if (hasmouse)
  334.   GetMouseInput();
  335. #endif
  336. Clear_Input();
  337. beg_update_num=0;
  338. cur_vert_angle=last_vert_angle=0;
  339. dim_control=VERT_CONTROL;
  340. raw_key=0;
  341. #ifdef OS_DOS
  342. done=FALSE;
  343. #endif
  344. }
  345. BOOL Main_Cycle_Done() {
  346. return done;
  347. }
  348. void Do_Main_Cycle()
  349. {
  350. long abs_z;
  351. long cur_update, end_update_num;
  352.   cur_vert_angle=Get_Player_Vert_Angle(the_player);
  353.   if (cur_vert_angle!=last_vert_angle) {
  354.   Set_View_Angle(cur_vert_angle);
  355.   last_vert_angle=cur_vert_angle;
  356.   }
  357.   if (the_player->cur_sec->flags & VOXEL_SECTOR) {
  358. abs_z=the_player->z+Get_Voxel_Alt((PUCHAR)the_player->cur_sec->extra_data,
  359.  the_player->x, the_player->y)+the_player->type->eye_height;
  360. } else {
  361.   abs_z=the_player->z+the_player->cur_sec->floor_height+the_player->type->eye_height;
  362.   }
  363.   Render_Screen(the_player->x, the_player->y, abs_z, the_player->angle);
  364. #ifdef OS_WINDOWS
  365.   Win_Copy_Buff();
  366. #endif
  367. #ifdef OS_DOS
  368.   Dos_Copy_Buff();
  369. #endif
  370.   frame_num++; 
  371.   end_update_num=Get_Update_Num();
  372.   for (cur_update=beg_update_num; cur_update<end_update_num; cur_update++) {
  373.   World_Update(cur_update);
  374.   }
  375.   beg_update_num=end_update_num;
  376.   // Check other keys that are unrelated to world updates
  377.   switch (raw_key) {
  378.   case ESC_KEY:
  379.  #ifdef OS_DOS
  380.   done=TRUE;
  381. #endif
  382. #ifdef OS_WINDOWS
  383.   PostQuitMessage(0);
  384. #endif
  385.   // end if user is exiting
  386.   break;
  387. #ifdef _PROGRAMMER_VERSION_
  388.   case PLUS_KEY:
  389.   // user pressed "+" key, so increase window size
  390.   if (GetRenderMode()!=MODE_2D) {
  391.   #ifdef OS_DOS
  392.   if (dim_control==VERT_CONTROL)
  393.   setWindowDimensions(WINDOW_HEIGHT+10);
  394.   else if (dim_control==HORIZ_CONTROL)
  395.   Set_Window_Width(WINDOW_WIDTH+10);
  396.   #endif
  397.   } else Map_Scale_Increase();
  398.   break;
  399.   case MINUS_KEY:
  400.   // user pressed "-" key, so decrease window size
  401.   if (GetRenderMode()!=MODE_2D) {
  402.   #ifdef OS_DOS
  403.   if (dim_control==VERT_CONTROL)
  404.   setWindowDimensions(WINDOW_HEIGHT-10);
  405.   else if (dim_control==HORIZ_CONTROL)
  406.   Set_Window_Width(WINDOW_WIDTH-10);
  407.   #endif
  408.   } else Map_Scale_Decrease();
  409.   break;
  410.   case RIGHT_BRACKET:
  411.   // user pressed "]" key, so increase window FOV
  412.  if (dim_control==VERT_CONTROL)
  413.  setWindowFOV(VERTICAL_VIEW_RANGE+ANGLE_5);
  414.  else if (dim_control==HORIZ_CONTROL)
  415.  Set_Horiz_FOV(HORIZ_VIEW_RANGE+ANGLE_5);
  416.  break;
  417.   case LEFT_BRACKET:
  418.  // user pressed "[" key, so decrease window FOV
  419.  if (dim_control==VERT_CONTROL)
  420.  setWindowFOV(VERTICAL_VIEW_RANGE-ANGLE_5);
  421.  else if (dim_control==HORIZ_CONTROL)
  422.  Set_Horiz_FOV(HORIZ_VIEW_RANGE-ANGLE_5);
  423.  break;
  424.  case PGUP_KEY:
  425.  // user wants to make vox terrain seem farther away
  426.  V_Dist_Scale_Inc();
  427.  break;
  428.  case PGDN_KEY:
  429.  // user wants to make vox terrain seem closer
  430.  V_Dist_Scale_Dec();
  431.  break;
  432. #endif
  433. #ifdef OS_DOS
  434.  case F1_KEY:
  435.  // user is changing screen resolution
  436.  if (is_super_vga)
  437.  Change_Screen(VGA_WIDTH, VGA_HEIGHT);
  438.  else Change_Screen(SVGA_WIDTH, SVGA_HEIGHT);
  439.  is_super_vga=(!is_super_vga);
  440.  Update_Palette();
  441.  break;
  442. #endif
  443. #ifdef _PROGRAMMER_VERSION_
  444.  case F2_KEY:
  445.  // user wants to adjust the other dimension of screen
  446.  if (dim_control==VERT_CONTROL)
  447.  dim_control=HORIZ_CONTROL;
  448.  else if (dim_control==HORIZ_CONTROL)
  449.  dim_control=VERT_CONTROL;
  450.  raw_key=0;
  451.  break;
  452. #endif
  453.  case S_KEY:
  454.  // user wants to capture screen
  455.  Screen_Capture((PCHAR)DEF_CAPTURE_F_NAME);
  456.  break;
  457.   case TAB_KEY:
  458.   SwitchRenderMode();
  459.   raw_key=0;
  460.   break;
  461.   default:
  462.  break;
  463.   } /* endswitch */
  464. }
  465. long time_at_hurt;
  466. BOOL is_hurt;
  467. void Init_Visuals() {
  468. time_at_hurt=0;
  469. is_hurt=FALSE;
  470. }
  471. void Visuals_Message(ULONG message, pdata extra_data) {
  472. switch (message) {
  473.   case HURT_MESSAGE:
  474.   Show_Palette(HURT_PAL);
  475.   time_at_hurt=Get_Update_Num();
  476.   is_hurt=TRUE;
  477.   break;
  478.   case VIS_DIE_MSG:
  479.   Do_Shot("dscreen.pcx", "aaah.wav", 90, TRUE);
  480.   the_player->x=PLAYER_START_X;
  481.   the_player->y=PLAYER_START_Y;
  482.   the_player->z=PLAYER_START_Z;
  483.   the_player->stats.current_health=the_player->type->stats.total_health;
  484.   the_player->angle=PLAYER_START_ANGLE;
  485.   default:
  486.   break;
  487. }
  488. }
  489. void Visuals_Update(long cur_update_num) {
  490. if (is_hurt) {
  491.   if (cur_update_num>time_at_hurt+HURT_TIME) {
  492.  is_hurt=FALSE;
  493.  time_at_hurt=0;
  494.  Show_Palette(STANDARD_PAL);
  495.   }
  496. }
  497. }
  498. void World_Update(long cur_update_num) {
  499. #ifdef OS_DOS
  500. if (hasmouse)
  501. GetMouseInput();
  502. #endif
  503. if (do_waves) {
  504. Do_Waves();
  505. } /* endif */
  506. Animate_Textures(cur_update_num);
  507. Setup_Combined_Input();
  508. Update_Objects(cur_update_num);
  509. Visuals_Update(cur_update_num);
  510. }
  511. void GetMouseInput()
  512. {
  513. #ifdef OS_DOS
  514. short x,y; // x,y positions of the mouse relative to last check
  515. mbrel(x,y); // Get them's positions;
  516. if (x<0) { // mouse to left
  517. mouse_table[INDEX_LEFT]=-x;
  518. } else {
  519. if (x>0) { // mouse to right
  520. mouse_table[INDEX_RIGHT]=x;
  521. } else {  // no mouse movement on x
  522. mouse_table[INDEX_LEFT]=0; mouse_table[INDEX_RIGHT]=0;
  523. } /* endif */
  524. } /* endif */
  525. // Note: on the y axis, direction is reversed i.e. a mouse movement up generates a y<0
  526.  
  527. // mouse has different function in fly mode
  528. if (!Is_Flying(the_player)) {
  529. if (y<0) { // mouse is higher than last position
  530. if (y<-the_player->type->stats.base_speed)
  531. y=-the_player->type->stats.base_speed;
  532. mouse_table[INDEX_UP]=-y;
  533. } else {
  534. if (y>0) { // mouse is lower than last position
  535. if (y>the_player->type->stats.base_speed)
  536. y=the_player->type->stats.base_speed;
  537. mouse_table[INDEX_DOWN]=y;
  538. } else { // no mouse movement on y
  539. mouse_table[INDEX_DOWN]=0; mouse_table[INDEX_UP]=0;
  540. } /* endif */
  541. } /* endif */
  542. if (mbpos(x,y)) { // Check for button press
  543. mouse_table[INDEX_GUN]=1;
  544. } else {
  545. mouse_table[INDEX_GUN]=0;
  546. }
  547. } else {
  548. if (y<0) {
  549. mouse_table[LOOK_UP]=-y;
  550. } else {
  551. if (y>0) {
  552. mouse_table[LOOK_DOWN]=y;
  553. } else {
  554. mouse_table[LOOK_UP]=0; mouse_table[LOOK_DOWN]=0;
  555. } /* endif */
  556. } /* endif */
  557. long mb_press=mbpos(x,y);
  558. if (mb_press & ML_BUTTON) {
  559. mouse_table[INDEX_UP]=the_player->type->stats.base_speed;
  560. } else {
  561. if (mb_press & MR_BUTTON) {
  562. mouse_table[INDEX_DOWN]=the_player->type->stats.base_speed;
  563. } else {
  564. mouse_table[INDEX_UP]=0; mouse_table[INDEX_DOWN]=0;
  565. } /* endif */
  566. } /* endif */
  567. } /* endif */
  568. #endif
  569. }
  570. void Setup_Combined_Input()
  571. {
  572. for (short i=0; i<(MAX_TRACKED_INPUTS-1); i++) {
  573. if (key_table[i]>mouse_table[i]) {
  574. combined_table[i]=(short)key_table[i];
  575. } else {
  576. combined_table[i]=(short)mouse_table[i];
  577. } /* endif */
  578. } /* endfor */
  579. combined_table[MAX_TRACKED_INPUTS-1]=raw_key;
  580. }
  581. void Clear_Input() {
  582. for (short i=0; i<(MAX_TRACKED_INPUTS-1); i++) {
  583. key_table[i]=0;
  584. mouse_table[i]=0;
  585. combined_table[i]=0;
  586. }
  587. raw_key=0;
  588. combined_table[MAX_TRACKED_INPUTS-1]=0;
  589. }
  590. void Screen_Message(PCHAR message) {
  591.   printf(message);
  592.   printf("n");
  593. }