1 /* NetHack 3.7	mhinput.c	$NHDT-Date: 1596498350 2020/08/03 23:45:50 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */
2 /* Copyright (C) 2001 by Alex Kompel 	 */
3 /* NetHack may be freely redistributed.  See license for details. */
4 
5 #include <assert.h>
6 #include "winMS.h"
7 #include "mhinput.h"
8 
9 /* nethack input queue functions */
10 
11 #define NH_INPUT_BUFFER_SIZE 64
12 
13 /* as it stands right now we need only one slot
14    since events are processed almost the same time as
15    they occur but I like large round numbers */
16 
17 static MSNHEvent nhi_input_buffer[NH_INPUT_BUFFER_SIZE];
18 static int nhi_init_input = 0;
19 static int nhi_read_pos = 0;
20 static int nhi_write_pos = 0;
21 
22 /* initialize input queue */
23 void
mswin_nh_input_init(void)24 mswin_nh_input_init(void)
25 {
26     if (!nhi_init_input) {
27         nhi_init_input = 1;
28 
29         ZeroMemory(nhi_input_buffer, sizeof(nhi_input_buffer));
30         nhi_read_pos = 0;
31         nhi_write_pos = 0;
32     }
33 }
34 
35 /* check for input */
36 int
mswin_have_input(void)37 mswin_have_input(void)
38 {
39     return
40 #ifdef SAFERHANGUP
41         /* we always have input (ESC) if hangup was requested */
42         g.program_state.done_hup ||
43 #endif
44         (nhi_read_pos != nhi_write_pos);
45 }
46 
47 /* add event to the queue */
48 void
mswin_input_push(PMSNHEvent event)49 mswin_input_push(PMSNHEvent event)
50 {
51     int new_write_pos;
52 
53     if (!nhi_init_input)
54         mswin_nh_input_init();
55 
56     new_write_pos = (nhi_write_pos + 1) % NH_INPUT_BUFFER_SIZE;
57 
58     if (new_write_pos != nhi_read_pos) {
59         memcpy(nhi_input_buffer + nhi_write_pos, event, sizeof(*event));
60         nhi_write_pos = new_write_pos;
61     }
62 }
63 
64 /* get event from the queue and delete it */
65 PMSNHEvent
mswin_input_pop(void)66 mswin_input_pop(void)
67 {
68     PMSNHEvent retval;
69 
70 #ifdef SAFERHANGUP
71     /* always return ESC when hangup was requested */
72     if (g.program_state.done_hup) {
73         static MSNHEvent hangup_event;
74         hangup_event.type = NHEVENT_CHAR;
75         hangup_event.ei.kbd.ch = '\033';
76         return &hangup_event;
77     }
78 #endif
79 
80     if (!nhi_init_input)
81         mswin_nh_input_init();
82 
83     if (nhi_read_pos != nhi_write_pos) {
84         retval = &nhi_input_buffer[nhi_read_pos];
85         nhi_read_pos = (nhi_read_pos + 1) % NH_INPUT_BUFFER_SIZE;
86     } else {
87         retval = NULL;
88     }
89 
90     return retval;
91 }
92 
93 /* get event from the queue but leave it there */
94 PMSNHEvent
mswin_input_peek(void)95 mswin_input_peek(void)
96 {
97     PMSNHEvent retval;
98 
99 #ifdef SAFERHANGUP
100     /* always return ESC when hangup was requested */
101     if (g.program_state.done_hup) {
102         static MSNHEvent hangup_event;
103         hangup_event.type = NHEVENT_CHAR;
104         hangup_event.ei.kbd.ch = '\033';
105         return &hangup_event;
106     }
107 #endif
108 
109     if (!nhi_init_input)
110         mswin_nh_input_init();
111 
112     if (nhi_read_pos != nhi_write_pos) {
113         retval = &nhi_input_buffer[nhi_read_pos];
114     } else {
115         retval = NULL;
116     }
117     return retval;
118 }
119