1 /*******************************************************************************
2 * Reverse Polish Notation calculator. *
3 * Copyright (c) 2007-2008, Samuel Fredrickson <kinghajj@gmail.com> *
4 * All rights reserved. *
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. *
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 *
25 ******************************************************************************/
27 /* input.c - input module.
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.
42 typedef struct RPNPSPKey RPNPSPKey
;
44 // The master key map.
45 static RPNPSPKey KeyMap
[] =
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'},
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
, '|', '|'},
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
,
100 {PSP_CTRL_LTRIGGER
| PSP_CTRL_RTRIGGER
| PSP_CTRL_CROSS
| PSP_CTRL_UP
,
102 {PSP_CTRL_LTRIGGER
| PSP_CTRL_RTRIGGER
| PSP_CTRL_CROSS
| PSP_CTRL_RIGHT
,
104 {PSP_CTRL_LTRIGGER
| PSP_CTRL_RTRIGGER
| PSP_CTRL_CROSS
| PSP_CTRL_DOWN
,
106 {PSP_CTRL_LTRIGGER
| PSP_CTRL_RTRIGGER
| PSP_CTRL_CROSS
| PSP_CTRL_LEFT
,
109 {PSP_CTRL_LTRIGGER
| PSP_CTRL_RTRIGGER
| PSP_CTRL_CIRCLE
, 'z', 'Z'},
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()
128 // Wait for a button press.
131 sceCtrlReadBufferPositive(&pad
, 1);
133 // store the buttons.
134 buttons
= pad
.Buttons
;
136 // wait for all buttons to come up, store them.
139 sceCtrlReadBufferPositive(&pad
, 1);
140 buttons
|= pad
.Buttons
;
148 // Returns a key that matches the given buttons. Simple but fast on a small map.
149 static RPNPSPKey
*FindKey(int buttons
)
152 RPNPSPKey
*key
= NULL
;
154 for(i
= 0; KeyMap
[i
].buttons
; ++i
)
155 if(KeyMap
[i
].buttons
== buttons
)
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()
178 for(i
= 0; i
< RPN_BUF_SIZE
; ++i
)
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.
197 kprintf("%c", alternateMode
? key
->alt_chr
: key
->chr
);
198 return alternateMode
? key
->alt_chr
: key
->chr
;
201 else if(buttons
== enter
)
204 else if(buttons
== cancel
)
206 // Switch to alternate?
207 else if(buttons
== alternate
)
208 alternateMode
= alternateMode
? false : true;
213 //! Gets a string of input for the PSP.
214 /** @return The string.
216 char *RPNPSP_GetString()
219 char *retbuf
= buffer
;
221 // Clear the previous buffer before filling it.
224 // Go until the buffer is filled or a newline is returned.
225 for(i
= 0; retbuf
&& i
< RPN_BUF_SIZE
&& c
!= '\n'; i
++)