FUNCTION PInput$ (X%, Y%, Limit%, Replace%, StartVal$)
'
' PInput$ - An enhanced INPUT routine (version 2)
'
' This is the second version of PInput$. Special features from Input are:
' Scrolling - Ability to input more than space available, by
' scrolling it on the screen. (Hard to explain. Try running
' a code with a low Limit% to see how it works.)
' Replacing - Replace characters typed with another character on the
' screen. Useful for password prompts and such.
'
' Updates from PInput$ v1 are:
' Location - Ability to move through your input (left and right).
' Scrolling - See above.
' Cleaner code - Easier to edit and fix.
' Faster code - Uses better looping system.
' Commented - Comments make up about 2/3 of the routine's size.
'
' Extra bonus: Reverse compatible with PInput$ v1!
'
' Variables and usage:
' X% - X position on the screen to start prompt (left and right)
' Y% - Y position on the screen to start prompt (up and down)
' Limit% - The maximum amount of characters allowed to be displayed
' before having to scroll.
' Replace% - ASCII code of what character to display on the screen.
' Note: If you are to lazy to look at the ASCII table,
' than you can use ASC(ch$) instead of a number.
' StartVal$ - Value to make the input contain before the user starts
' typing.
'
' Example:
' YourVariable$ = PInput$(5, 5, 40, 42, "")
' What it does: Starts a prompt at 5,5 on the screen. It will start to
' scroll if more than 40 characters are on the screen.
' Characters typed are displayed as *s. Resulting string
' is stored in YourVariable$.
' (Note: ASC("*") is just as acceptable as 42)
'
' More notes!
' ESC cancels the prompt and returns a null string.
' SOUND 3000, 1.8:SOUND 0, .2 is used to inform the user that they are
' trying to do something invalid (read: stupid). This won't
' work on computers without an internal speaker!
' Use VAL(PInput$(x,x,x,x)) to get numeric values instead of strings.
'
Stor$ = StartVal$
LII% = LEN(StartVal$)
DO
LOCATE Y%, X% - 1, 0: PRINT SPACE$(Limit% + 2)
LOCATE Y%, X% - 1
IF INT(LII% / Limit%) <> 0 THEN PRINT CHR$(27); ELSE PRINT CHR$(32);
IF Replace% THEN
PRINT STRING$(LEN(MID$(Stor$, Limit% * INT(LII% / Limit%) + 1, Limit%)), Replace%)
ELSE
PRINT MID$(Stor$, Limit% * INT(LII% / Limit%) + 1, Limit%)
END IF
LOCATE Y%, X% + Limit%
IF LEN(Stor$) > Limit% * (INT(LII% / Limit%) + 1) THEN PRINT CHR$(26)
LOCATE Y%, X% + (LII% MOD Limit%), 1
'All of that is used to make the scrolling and text replacement
'happen. Possibly (read: probably) inefficient but effective
'nonetheless.
DO
Key$ = INKEY$ 'Get a new keypress
LOOP UNTIL Key$ <> ""
SELECT CASE ASC(Key$) 'Figure out what to do
CASE 27 'ESC pressed
Stor$ = "" 'Return null string
LOCATE Y%, X% - 1: PRINT SPACE$(Limit% + 2)
'Make it look like nothing entered
EXIT DO 'Stop processing data
CASE 13 'ENTER pressed
EXIT DO 'Stop processing data
CASE 9 'TAB pressed
Stor$ = LEFT$(Stor$, LII%) + SPACE$(8) + RIGHT$(Stor$, LEN(Stor$) - LII%)
LII% = LII% + 8 'In summary, TAB gives 8 spaces
CASE 8 'BACKSPACE pressed
IF LII% > 0 THEN 'Make sure there's something to del.
Stor$ = LEFT$(Stor$, LII% - 1) + RIGHT$(Stor$, LEN(Stor$) - LII%)
LII% = LII% - 1 'Try to understand the above.
ELSE 'If not something to delete...
SOUND 3000, 1.8: SOUND 0, .2 'Inform the user
END IF
CASE 0 'Extended key pressed
SELECT CASE ASC(RIGHT$(Key$, 1)) 'Find which extended key
CASE 73 'PAGE UP pressed
LII% = LII% + Limit% 'Move cursor location up one "page"
IF LII% > LEN(Stor$) THEN 'Over the input range?
LII% = LEN(Stor$) 'Maximize the input range
SOUND 3000, 1.8: SOUND 0, .2 'Warn the user
END IF
CASE 81 'PAGE DOWN pressed
LII% = LII% - Limit% 'Move cursor location down one "page"
IF LII% < 0 THEN 'Under the input range?
LII% = 0 'Minimize the input range
SOUND 3000, 1.8: SOUND 0, .2 'Warn the user
END IF
CASE 83 'DELETE pressed
IF LII% < LEN(Stor$) THEN 'Make sure there's something to delete
Stor$ = LEFT$(Stor$, LII%) + RIGHT$(Stor$, LEN(Stor$) - LII% - 1)
'Sort of like BACKSPACE, except in the opposite direction.
ELSE 'If not...
SOUND 3000, 1.8: SOUND 0, .2 'Inform the user
END IF
CASE 75 'LEFT pressed
IF LII% > 0 THEN 'Is there a place to move?
LII% = LII% - 1 'If so, move left
ELSE 'If not...
SOUND 3000, 1.8: SOUND 0, .2 'Inform the user
END IF
CASE 77 'RIGHT pressed
IF LII% < LEN(Stor$) THEN 'Is there a place to move?
LII% = LII% + 1 'If so, move right
ELSE 'If not...
SOUND 3000, 1.8: SOUND 0, .2 'Inform the user
END IF
CASE 71 'HOME pressed
IF LII% THEN LII% = 0 ELSE SOUND 3000, 1.8: SOUND 0, .2
'Go back to start of input, inform if already there
CASE 79 'END pressed
IF LII% = LEN(Stor$) THEN SOUND 3000, 1.8: SOUND 0, .2 ELSE LII% = LEN(Stor$)
'Go to end of input, inform if already there
CASE ELSE 'Unknown key pressed
SOUND 3000, 1.8: SOUND 0, .2 'Inform the user
END SELECT
CASE IS > 31, IS < 128 'Keyboard key pressed.
Stor$ = LEFT$(Stor$, LII%) + Key$ + RIGHT$(Stor$, LEN(Stor$) - LII%)
LII% = LII% + LEN(Key$)
'Add the key to the location, update location.
CASE ELSE 'Invalid key pressed.
SOUND 3000, 1.8: SOUND 0, .2 'Inform the user
END SELECT
LOOP
LOCATE CSRLIN + 1, 1, 0 'Fake carriage return, line feed.
'Also turns off flashing cursor.
PInput$ = Stor$ 'Yay! We're done!
END FUNCTION