Fixed found Valgrind issues.
[rpn.git] / src / psp / input.c
blob811574b2fae68d524df186daa87447290138b10b
1 /*******************************************************************************
2 * Reverse Polish Notation calculator. *
3 * Copyright (c) 2007-2008, Samuel Fredrickson <kinghajj@gmail.com> *
4 * All rights reserved. *
5 * *
6 * Redistribution and use in source and binary forms, with or without *
7 * modification, are permitted provided that the following conditions are met: *
8 * * Redistributions of source code must retain the above copyright *
9 * notice, this list of conditions and the following disclaimer. *
10 * * Redistributions in binary form must reproduce the above copyright *
11 * notice, this list of conditions and the following disclaimer in the *
12 * documentation and/or other materials provided with the distribution. *
13 * *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS *
15 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED *
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
17 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY *
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR *
20 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER *
21 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT *
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY *
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH *
24 * DAMAGE. *
25 ******************************************************************************/
27 /* input.c - input module.
30 #include "rpn.h"
32 #ifndef DOXYGEN_SKIP
34 //! Holds information on how a certain button press on the PSP maps to
35 //! characters. The alternate form is accessed by pressing the right trigger.
36 struct RPNPSPKey
38 int buttons;
39 char chr;
40 char alt_chr;
42 typedef struct RPNPSPKey RPNPSPKey;
44 // The master key map.
45 static RPNPSPKey KeyMap[] =
47 // Numbers
48 {PSP_CTRL_CROSS, '0', '0'},
49 {PSP_CTRL_CROSS | PSP_CTRL_UP, '1', '1'},
50 {PSP_CTRL_CROSS | PSP_CTRL_RIGHT, '2', '2'},
51 {PSP_CTRL_CROSS | PSP_CTRL_DOWN, '3', '3'},
52 {PSP_CTRL_CROSS | PSP_CTRL_LEFT, '4', '4'},
54 {PSP_CTRL_CIRCLE, '5', '5'},
55 {PSP_CTRL_CIRCLE | PSP_CTRL_UP, '6', '6'},
56 {PSP_CTRL_CIRCLE | PSP_CTRL_RIGHT, '7', '7'},
57 {PSP_CTRL_CIRCLE | PSP_CTRL_DOWN, '8', '8'},
58 {PSP_CTRL_CIRCLE | PSP_CTRL_LEFT, '9', '9'},
60 // Special characters
61 {PSP_CTRL_SQUARE, '.', '='},
62 {PSP_CTRL_SQUARE | PSP_CTRL_UP, '+', '+'},
63 {PSP_CTRL_SQUARE | PSP_CTRL_RIGHT, '-', '-'},
64 {PSP_CTRL_SQUARE | PSP_CTRL_DOWN, '*', '*'},
65 {PSP_CTRL_SQUARE | PSP_CTRL_LEFT, '/', '/'},
67 {PSP_CTRL_TRIANGLE, ' ', ' '},
68 {PSP_CTRL_TRIANGLE | PSP_CTRL_UP, '%', '%'},
69 {PSP_CTRL_TRIANGLE | PSP_CTRL_RIGHT, '^', '^'},
70 {PSP_CTRL_TRIANGLE | PSP_CTRL_DOWN, '&', '&'},
71 {PSP_CTRL_TRIANGLE | PSP_CTRL_LEFT, '|', '|'},
73 // The alphabet
74 {PSP_CTRL_LTRIGGER | PSP_CTRL_CROSS, 'a', 'A'},
75 {PSP_CTRL_LTRIGGER | PSP_CTRL_CROSS | PSP_CTRL_UP, 'b', 'B'},
76 {PSP_CTRL_LTRIGGER | PSP_CTRL_CROSS | PSP_CTRL_RIGHT, 'c', 'C'},
77 {PSP_CTRL_LTRIGGER | PSP_CTRL_CROSS | PSP_CTRL_DOWN, 'd', 'D'},
78 {PSP_CTRL_LTRIGGER | PSP_CTRL_CROSS | PSP_CTRL_LEFT, 'e', 'E'},
80 {PSP_CTRL_LTRIGGER | PSP_CTRL_CIRCLE, 'f', 'F'},
81 {PSP_CTRL_LTRIGGER | PSP_CTRL_CIRCLE | PSP_CTRL_UP, 'g', 'G'},
82 {PSP_CTRL_LTRIGGER | PSP_CTRL_CIRCLE | PSP_CTRL_RIGHT, 'h', 'H'},
83 {PSP_CTRL_LTRIGGER | PSP_CTRL_CIRCLE | PSP_CTRL_DOWN, 'i', 'I'},
84 {PSP_CTRL_LTRIGGER | PSP_CTRL_CIRCLE | PSP_CTRL_LEFT, 'j', 'J'},
86 {PSP_CTRL_LTRIGGER | PSP_CTRL_SQUARE, 'k', 'K'},
87 {PSP_CTRL_LTRIGGER | PSP_CTRL_SQUARE | PSP_CTRL_UP, 'l', 'L'},
88 {PSP_CTRL_LTRIGGER | PSP_CTRL_SQUARE | PSP_CTRL_RIGHT, 'm', 'M'},
89 {PSP_CTRL_LTRIGGER | PSP_CTRL_SQUARE | PSP_CTRL_DOWN, 'n', 'N'},
90 {PSP_CTRL_LTRIGGER | PSP_CTRL_SQUARE | PSP_CTRL_LEFT, 'o', 'O'},
92 {PSP_CTRL_LTRIGGER | PSP_CTRL_TRIANGLE, 'p', 'P'},
93 {PSP_CTRL_LTRIGGER | PSP_CTRL_TRIANGLE | PSP_CTRL_UP, 'q', 'Q'},
94 {PSP_CTRL_LTRIGGER | PSP_CTRL_TRIANGLE | PSP_CTRL_RIGHT, 'r', 'R'},
95 {PSP_CTRL_LTRIGGER | PSP_CTRL_TRIANGLE | PSP_CTRL_DOWN, 's', 'S'},
96 {PSP_CTRL_LTRIGGER | PSP_CTRL_TRIANGLE | PSP_CTRL_LEFT, 't', 'T'},
98 {PSP_CTRL_LTRIGGER | PSP_CTRL_RTRIGGER | PSP_CTRL_CROSS,
99 'u', 'U'},
100 {PSP_CTRL_LTRIGGER | PSP_CTRL_RTRIGGER | PSP_CTRL_CROSS | PSP_CTRL_UP,
101 'v', 'V'},
102 {PSP_CTRL_LTRIGGER | PSP_CTRL_RTRIGGER | PSP_CTRL_CROSS | PSP_CTRL_RIGHT,
103 'w', 'W'},
104 {PSP_CTRL_LTRIGGER | PSP_CTRL_RTRIGGER | PSP_CTRL_CROSS | PSP_CTRL_DOWN,
105 'x', 'X'},
106 {PSP_CTRL_LTRIGGER | PSP_CTRL_RTRIGGER | PSP_CTRL_CROSS | PSP_CTRL_LEFT,
107 'y', 'Y'},
109 {PSP_CTRL_LTRIGGER | PSP_CTRL_RTRIGGER | PSP_CTRL_CIRCLE, 'z', 'Z'},
111 {0},
114 #endif // DOXYGEN_SKIP
116 //! Gets button pushes.
118 * This reports multiple button pushes, so this does not return until all
119 * buttons have been released.
121 * @return An integer with button press flags.
123 static int GetButtonPushes()
125 int buttons;
126 SceCtrlData pad;
128 // Wait for a button press.
129 pad.Buttons = 0;
130 while(!pad.Buttons)
131 sceCtrlReadBufferPositive(&pad, 1);
133 // store the buttons.
134 buttons = pad.Buttons;
136 // wait for all buttons to come up, store them.
137 while(pad.Buttons)
139 sceCtrlReadBufferPositive(&pad, 1);
140 buttons |= pad.Buttons;
143 return buttons;
146 #ifndef DOXYGEN_SKIP
148 // Returns a key that matches the given buttons. Simple but fast on a small map.
149 static RPNPSPKey *FindKey(int buttons)
151 int i;
152 RPNPSPKey *key = NULL;
154 for(i = 0; KeyMap[i].buttons; ++i)
155 if(KeyMap[i].buttons == buttons)
156 key = &KeyMap[i];
158 return key;
161 // 64 characters is a reasonable limit for the buffer.
162 #define RPN_BUF_SIZE 64
163 static char buffer[RPN_BUF_SIZE];
164 // To press "enter", press the triggers simultaneously.
165 static int enter = PSP_CTRL_LTRIGGER | PSP_CTRL_RTRIGGER;
166 // To cancel input, press the left trigger.
167 static int cancel = PSP_CTRL_LTRIGGER;
168 // To switch to alternate characters, press the right trigger.
169 static int alternate = PSP_CTRL_RTRIGGER;
170 // Don't start in alternate mode.
171 bool alternateMode = false;
173 // Clear the buffer to remove previous inputs.
174 static void clearInputBuffer()
176 int i;
178 for(i = 0; i < RPN_BUF_SIZE; ++i)
179 buffer[i] = 0;
182 #endif // DOXYGEN_SKIP
184 //! Get one character; map special characters so they can be handled later.
187 * @return The typed character or 0 if invalid.
189 static char GetCharacter()
191 int buttons = GetButtonPushes();
192 RPNPSPKey *key = FindKey(buttons);
194 // Was a valid combination pressed? The print the character, then return it.
195 if(key)
197 kprintf("%c", alternateMode ? key->alt_chr : key->chr);
198 return alternateMode ? key->alt_chr : key->chr;
200 // Enter?
201 else if(buttons == enter)
202 return '\n';
203 // Cancel?
204 else if(buttons == cancel)
205 return '\b';
206 // Switch to alternate?
207 else if(buttons == alternate)
208 alternateMode = alternateMode ? false : true;
209 // What happened?
210 return 0;
213 //! Gets a string of input for the PSP.
214 /** @return The string.
216 char *RPNPSP_GetString()
218 int i, c = 0;
219 char *retbuf = buffer;
221 // Clear the previous buffer before filling it.
222 clearInputBuffer();
224 // Go until the buffer is filled or a newline is returned.
225 for(i = 0; retbuf && i < RPN_BUF_SIZE && c != '\n'; i++)
227 c = GetCharacter();
228 // Backspace?
229 if(c == '\b')
231 kprintf("\n");
232 retbuf = NULL;
234 // Real character?
235 else if(c)
236 buffer[i] = c;
237 // No; stay back.
238 else
239 i--;
242 kprintf("\n");
243 return retbuf;