ex_chat.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. /* EX_CHAT.C - Example of a multi-window full-screen chat program written */
  2. /* with OpenDoors. See manual for instructions on how to compile */
  3. /* a program using OpenDoors. */
  4. /* */
  5. /* This program shows how to do the following: */
  6. /* */
  7. /* - Replace the standard OpenDoors chat mode with your own */
  8. /* chat mode implementation. See instructions below. */
  9. /* - How to scroll a portion of the screen, leaving the rest */
  10. /* of the screen unaltered. */
  11. /* - How to determine whether input came from the local or */
  12. /* remote keyboard. */
  13. /* - How to display a popup window with a message in it when */
  14. /* the sysop shells to DOS. (DOS version only.) */
  15. /* - How to save and restore the entire contents of the */
  16. /* screen. */
  17. /* */
  18. /* Conditional compilation directives allow this program to */
  19. /* be compiled as a stand-alone chat door, or as a */
  20. /* replacement chat mode to be integrated into any OpenDoors */
  21. /* program. If STANDALONE is #defined, ex_chat.c will be */
  22. /* compiled as a split-screen chat door that can be run like */
  23. /* any door program. If STANDALONE is not #defined, the chat */
  24. /* mode function will be compiled as a replacement chat mode */
  25. /* for the chat mode built into OpenDoors. In this case, the */
  26. /* demo mainline function simply displays a prompt, and will */
  27. /* exit the door as soon as you press the [ENTER] key. While */
  28. /* the program is running, if you invoke chat mode (press */
  29. /* [ALT]-[C]), the current screen will be saved and the */
  30. /* split-screen chat mode will be activated. When you press */
  31. /* [ESC] the split-screen chat mode will end, and the */
  32. /* original screen will be restored. To integrate this chat */
  33. /* mode into your own program, you should simply set */
  34. /* od_control.od_cbefore_chat to point to the */
  35. /* fullscreen_chat function, as shown, and remove the mainline */
  36. /* (main()/WinMain()) function from this file. The compile this */
  37. /* file into your program after removing the #define STANDALONE */
  38. /* line. */
  39. /* Include required header files. */
  40. #include "OpenDoor.h"
  41. #include <string.h>
  42. /* The following #define forces this code to compile as a stand-alone door */
  43. /* program. If you wish to use this code to replace the standard OpenDoors */
  44. /* chat mode in your own program, remove this #define. */
  45. #define STANDALONE
  46. /* Full-screen chat function prototypes. */
  47. void fullscreen_chat(void);
  48. void chat_new_line(void);
  49. void display_shell_window(void);
  50. void remove_shell_window(void);
  51. /* The main() or WinMain() function: program execution begins here. */
  52. #ifdef ODPLAT_WIN32
  53. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  54. LPSTR lpszCmdLine, int nCmdShow)
  55. #else
  56. int main(int argc, char *argv[])
  57. #endif
  58. {
  59. /* Handle standard command-line options and perform other needed setup. */
  60. #ifdef ODPLAT_WIN32
  61. od_control.od_cmd_show = nCmdShow;
  62. od_parse_cmd_line(lpszCmdLine);
  63. #else
  64. od_parse_cmd_line(argc, argv);
  65. #endif
  66. #ifdef STANDALONE /* If compiled as a stand-alone chat program */
  67. od_init(); /* Initialize OpenDoors */
  68. fullscreen_chat(); /* Invoke full-screen chat function */
  69. #else /* If compiled as replacement for OpenDoors chat mode */
  70. /* Setup OpenDoors to use our custom chat mode instead */
  71. od_control.od_cbefore_chat=fullscreen_chat;
  72. od_printf("Press [Enter] to exit door, or invoke chat mode.\n\r");
  73. od_get_answer("\n\r");
  74. #endif
  75. od_exit(0, FALSE); /* Exit program. */
  76. return(0);
  77. }
  78. /* FULL-SCREEN CHAT CUSTOMIZATION OPTIONS */
  79. char window_colour[2]={0x0b,0x0c}; /* Text colour used for each person */
  80. char bar_colour=0x70; /* Colour of window seperation bar */
  81. char top_line[2]={13,1}; /* Specifies location of each window on screen */
  82. char bottom_line[2]={23,11}; /* Line number of bottom of each window */
  83. char bar_line=12; /* Line number of window seperation bar */
  84. char scroll_distance=2; /* Distance to scroll window when required */
  85. char shell_window_title=0x1a; /* Colour of title of DOS shell notice window */
  86. char shell_window_boarder=0x1f; /* Colour of DOS shell window boarder */
  87. char shell_window_text=0x1b; /* Colour of text in DOS shell window */
  88. int cursor_window; /* FULL-SCREEN CHAT INTERNAL VARIABLES */
  89. char current_word[2][81];
  90. int word_length[2];
  91. int cursor_col[2];
  92. int cursor_line[2];
  93. unsigned char key;
  94. int old_chat_key;
  95. void *shell_window;
  96. char *before_shell_text;
  97. char *after_shell_text;
  98. #ifndef STANDALONE /* If compiled as replacement for OpenDoors chat mode */
  99. char screen_buffer[4004];
  100. #endif
  101. /* FULL-SCREEN CHAT FUNCTION */
  102. void fullscreen_chat(void)
  103. {
  104. cursor_window=0; /* Reset working variables */
  105. word_length[0]=word_length[1]=0;
  106. cursor_col[0]=cursor_col[1]=1;
  107. cursor_line[0]=top_line[0];
  108. cursor_line[1]=top_line[1];
  109. /* If ANSI or AVATAR graphics mode is not available */
  110. if(!od_control.user_ansi && !od_control.user_avatar)
  111. { /* Then use OpenDoor's line chat mode instead */
  112. #ifdef STANDALONE /* If compiled as a stand-alone chat program */
  113. od_chat();
  114. #endif
  115. return;
  116. }
  117. od_control.od_cbefore_shell=display_shell_window; /* Set shell settings */
  118. od_control.od_cafter_shell=remove_shell_window;
  119. before_shell_text=od_control.od_before_shell;
  120. after_shell_text=od_control.od_after_shell;
  121. od_control.od_before_shell=NULL;
  122. od_control.od_after_shell=NULL;
  123. od_control.od_chat_active=TRUE;
  124. #ifdef STANDALONE /* If compiled as a stand-alone chat program */
  125. old_chat_key=od_control.key_chat; /* Prevent internal chat mode from */
  126. od_control.key_chat=0; /* being invoked */
  127. #else /* If compiled as replacement for OpenDoors chat mode */
  128. od_save_screen(screen_buffer); /* Save current screen contents. */
  129. #endif
  130. /* DRAW THE CHAT SCREEN */
  131. od_set_attrib(window_colour[0]);
  132. od_clr_scr(); /* Clear the screen */
  133. od_set_cursor(bar_line,1); /* Draw window separation bar */
  134. od_set_attrib(bar_colour);
  135. od_clr_line();
  136. od_set_cursor(bar_line,67);
  137. od_printf("Ctrl-A: Clear");
  138. od_set_cursor(bar_line,1);
  139. od_printf(" Top : %-.28s Bottom : %-.28s ",
  140. od_control.sysop_name, od_control.user_name);
  141. od_set_cursor(top_line[0],1); /* Locate cursor where typing will begin */
  142. od_set_attrib(window_colour[0]); /* Set appropriate text colour */
  143. /* MAIN CHAT LOOP */
  144. for(;;) /* (Repeats for each character typed) */
  145. {
  146. do
  147. {
  148. key=(char)od_get_key(FALSE); /* Get next keystroke from keyboard */
  149. /* CHECK FOR SYSOP ABORT */
  150. if((key==27 && od_control.od_last_input==1) /* If sysop pressed ESC */
  151. || !od_control.od_chat_active)
  152. {
  153. od_set_attrib(0x07); /* Reset display colour */
  154. od_clr_scr(); /* Clear the screen */
  155. od_control.od_cbefore_shell=NULL; /* Restore DOS shell settings */
  156. od_control.od_cafter_shell=NULL;
  157. od_control.od_before_shell=before_shell_text;
  158. od_control.od_after_shell=after_shell_text;
  159. #ifdef STANDALONE /* If compiled as a stand-alone chat program */
  160. od_control.key_chat=old_chat_key;/* Re-enable internal chat mode */
  161. #else /* If compiled as replacement for OpenDoors chat mode */
  162. od_control.od_chat_active=FALSE; /* Turn off chat mode */
  163. od_restore_screen(screen_buffer); /* Restore orignal screen */
  164. #endif
  165. return; /* Exit full-screen chat */
  166. }
  167. } while(key==0);
  168. /* CHECK FOR NEW TYPIST */
  169. if(od_control.od_last_input!=cursor_window)/* If new person typing now */
  170. { /* Switch cursor to appropriate window */
  171. cursor_window=od_control.od_last_input; /* Set current typist */
  172. /* Move cursor to new window */
  173. od_set_cursor(cursor_line[cursor_window],cursor_col[cursor_window]);
  174. od_set_attrib(window_colour[cursor_window]); /* Change text colour */
  175. }
  176. if(key==13 || key==10) /* IF USER PRESSED [ENTER] / [RETURN] */
  177. {
  178. word_length[cursor_window]=0; /* Enter constitutes end of word */
  179. chat_new_line(); /* Move to next line */
  180. }
  181. else if(key==8) /* IF USER PRESS [BACKSPACE] */
  182. {
  183. if(cursor_col[cursor_window] > 1) /* If not at left of screen */
  184. {
  185. --cursor_col[cursor_window]; /* Move cursor back on character */
  186. if(word_length[cursor_window] > 0) --word_length[cursor_window];
  187. od_printf("\b \b"); /* Erase last character from screen */
  188. }
  189. }
  190. else if(key==32) /* IF USER PRESSED [SPACE] */
  191. {
  192. word_length[cursor_window]=0; /* [Space] constitutes end of word */
  193. if(cursor_col[cursor_window]==79) /* If at end of line */
  194. chat_new_line(); /* Move cursor to next line */
  195. else /* If not at end of line */
  196. {
  197. ++cursor_col[cursor_window]; /* Increment cursor position */
  198. od_putch(32); /* Display a space */
  199. }
  200. }
  201. else if(key==1) /* IF USER PRESSED CLEAR WINDOW KEY */
  202. { /* Clear user's window */
  203. od_scroll(1,top_line[cursor_window],79,bottom_line[cursor_window],
  204. bottom_line[cursor_window]-top_line[cursor_window]+1,0);
  205. word_length[cursor_window]=0; /* We are no longer composing a word */
  206. cursor_col[cursor_window]=1; /* Reset cursor position */
  207. cursor_line[cursor_window]=top_line[cursor_window];
  208. od_set_cursor(cursor_line[cursor_window],cursor_col[cursor_window]);
  209. }
  210. else if(key>32) /* IF USER TYPED A PRINTABLE CHARACTER */
  211. { /* PERFORM WORD WRAP IF NECESSARY */
  212. if(cursor_col[cursor_window]==79) /* If cursor is at end of line */
  213. {
  214. /* If there is a word to wrap */
  215. if(word_length[cursor_window]>0 && word_length[cursor_window]<78)
  216. {
  217. /* Move cursor to beginning of word */
  218. od_set_cursor(cursor_line[cursor_window],
  219. cursor_col[cursor_window]-word_length[cursor_window]);
  220. od_clr_line(); /* Erase word from current line */
  221. chat_new_line(); /* Move cursor to next line */
  222. /* Redisplay word */
  223. od_disp(current_word[cursor_window],word_length[cursor_window],
  224. TRUE);
  225. cursor_col[cursor_window]+=word_length[cursor_window];
  226. }
  227. else /* If there is no word to "wrap" */
  228. {
  229. chat_new_line(); /* Move cursor to next line */
  230. word_length[cursor_window]=0; /* Start a new word */
  231. }
  232. }
  233. /* ADD CHARACTER TO CURRENT WORD */
  234. /* If there is room for more character in word */
  235. if(strlen(current_word[cursor_window])<79) /* Add new character */
  236. current_word[cursor_window][word_length[cursor_window]++]=key;
  237. /* DISPLAY NEWLY TYPED CHARACTER */
  238. ++cursor_col[cursor_window];
  239. od_putch(key);
  240. }
  241. }
  242. }
  243. /* FUNCTION USED BY FULL-SCREEN CHAT TO START A NEW INPUT LINE */
  244. void chat_new_line(void)
  245. { /* If cursor is at bottom of window */
  246. if(cursor_line[cursor_window]==bottom_line[cursor_window])
  247. { /* Scroll window up one line on screen */
  248. od_scroll(1,top_line[cursor_window],79, bottom_line[cursor_window],
  249. scroll_distance, 0);
  250. cursor_line[cursor_window]-=(scroll_distance - 1);
  251. }
  252. else /* If cursor is not at bottom of window */
  253. {
  254. ++cursor_line[cursor_window]; /* Move cursor down one line */
  255. }
  256. /* Move cursor's position on screen */
  257. od_set_cursor(cursor_line[cursor_window],cursor_col[cursor_window]=1);
  258. od_set_attrib(window_colour[cursor_window]); /* Change text colour */
  259. }
  260. void display_shell_window(void)
  261. {
  262. if((shell_window=od_window_create(17,9,63,15,"DOS Shell",
  263. shell_window_boarder, shell_window_title,
  264. shell_window_text, 0))==NULL) return;
  265. od_set_attrib(shell_window_text);
  266. od_set_cursor(11,26);
  267. od_printf("The Sysop has shelled to DOS");
  268. od_set_cursor(13,21);
  269. od_printf("He/She will return in a few moments...");
  270. }
  271. void remove_shell_window(void)
  272. {
  273. od_window_remove(shell_window);
  274. od_set_cursor(cursor_line[cursor_window],cursor_col[cursor_window]);
  275. od_set_attrib(window_colour[cursor_window]);
  276. }