This is the open source Pawn interpreter ported to mbed. See here: http://www.compuphase.com/pawn/pawn.htm and here: http://code.google.com/p/pawnscript/

Dependents:   Pawn4Test

Some instructions:

  • Put the attached include folder next to your source, so when you compile you get all the proper definitions
  • Use the attached main.p as a starting point if you wish
  • Compile your main.p into main.amx - Put your main.amx on the mbed 'drive'
  • Reset and be amazed.

Important Compile Notes:

  • You should use the -S# option to define a smaller default stack size. Start with -S64 and go up from there if needed.
  • To use on the Cortex-M0 version of the mbed (LPC11U24), you MUST include the TARGET=3 command-line option as well, so the pin names are properly defined. In the future this may be handled on the native code side.

Known Issues:

  • At the moment it appears the kbhit() function is not working right - at least on my mac. Will continue testing on Windows. Working fine.

Todo:

  • Add more wrappers for the mbed peripherals
  • Add Pawn overlay support, to allow much larger scripts to run (even on the LPC11U24)
Committer:
Lobo
Date:
Fri May 24 17:49:26 2013 +0000
Revision:
3:185fdbb7ccf0
Parent:
0:3ab1d2d14eb3
Now includes AnalogIn and AnalogOut functions

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tylerwilson 0:3ab1d2d14eb3 1 /* Console output module (terminal I/O) for the Pawn AMX
tylerwilson 0:3ab1d2d14eb3 2 *
tylerwilson 0:3ab1d2d14eb3 3 * Since some of these routines go further than those of standard C, they
tylerwilson 0:3ab1d2d14eb3 4 * cannot always be implemented with portable C functions. In other words,
tylerwilson 0:3ab1d2d14eb3 5 * these routines must be ported to other environments.
tylerwilson 0:3ab1d2d14eb3 6 *
tylerwilson 0:3ab1d2d14eb3 7 * Copyright (c) ITB CompuPhase, 1997-2011
tylerwilson 0:3ab1d2d14eb3 8 *
tylerwilson 0:3ab1d2d14eb3 9 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
tylerwilson 0:3ab1d2d14eb3 10 * use this file except in compliance with the License. You may obtain a copy
tylerwilson 0:3ab1d2d14eb3 11 * of the License at
tylerwilson 0:3ab1d2d14eb3 12 *
tylerwilson 0:3ab1d2d14eb3 13 * http://www.apache.org/licenses/LICENSE-2.0
tylerwilson 0:3ab1d2d14eb3 14 *
tylerwilson 0:3ab1d2d14eb3 15 * Unless required by applicable law or agreed to in writing, software
tylerwilson 0:3ab1d2d14eb3 16 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
tylerwilson 0:3ab1d2d14eb3 17 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
tylerwilson 0:3ab1d2d14eb3 18 * License for the specific language governing permissions and limitations
tylerwilson 0:3ab1d2d14eb3 19 * under the License.
tylerwilson 0:3ab1d2d14eb3 20 *
tylerwilson 0:3ab1d2d14eb3 21 * Version: $Id: amxcons.c 4523 2011-06-21 15:03:47Z thiadmer $
tylerwilson 0:3ab1d2d14eb3 22 */
tylerwilson 0:3ab1d2d14eb3 23
tylerwilson 0:3ab1d2d14eb3 24 #if defined _UNICODE || defined __UNICODE__ || defined UNICODE
tylerwilson 0:3ab1d2d14eb3 25 # if !defined UNICODE /* for Windows */
tylerwilson 0:3ab1d2d14eb3 26 # define UNICODE
tylerwilson 0:3ab1d2d14eb3 27 # endif
tylerwilson 0:3ab1d2d14eb3 28 # if !defined _UNICODE /* for C library */
tylerwilson 0:3ab1d2d14eb3 29 # define _UNICODE
tylerwilson 0:3ab1d2d14eb3 30 # endif
tylerwilson 0:3ab1d2d14eb3 31 #endif
tylerwilson 0:3ab1d2d14eb3 32
tylerwilson 0:3ab1d2d14eb3 33 #include <limits.h>
tylerwilson 0:3ab1d2d14eb3 34 #include <stdio.h>
tylerwilson 0:3ab1d2d14eb3 35 #include <stdlib.h>
tylerwilson 0:3ab1d2d14eb3 36 #include <string.h>
tylerwilson 0:3ab1d2d14eb3 37 #include <assert.h>
tylerwilson 0:3ab1d2d14eb3 38 #if defined __WIN32__ || defined _WIN32 || defined WIN32 || defined __MSDOS__
tylerwilson 0:3ab1d2d14eb3 39 #define HAVE_CONIO
tylerwilson 0:3ab1d2d14eb3 40 #include <conio.h>
tylerwilson 0:3ab1d2d14eb3 41 #include <malloc.h>
tylerwilson 0:3ab1d2d14eb3 42 #endif
tylerwilson 0:3ab1d2d14eb3 43 #if defined USE_CURSES || defined HAVE_CURSES_H
tylerwilson 0:3ab1d2d14eb3 44 #include <curses.h>
tylerwilson 0:3ab1d2d14eb3 45 #if !defined CURSES
tylerwilson 0:3ab1d2d14eb3 46 #define CURSES 1
tylerwilson 0:3ab1d2d14eb3 47 #endif
tylerwilson 0:3ab1d2d14eb3 48 #endif
tylerwilson 0:3ab1d2d14eb3 49 #include "osdefs.h"
tylerwilson 0:3ab1d2d14eb3 50 #if defined __ECOS__
tylerwilson 0:3ab1d2d14eb3 51 /* eCos puts include files in cyg/package_name */
tylerwilson 0:3ab1d2d14eb3 52 #include <cyg/hal/hal_if.h>
tylerwilson 0:3ab1d2d14eb3 53 #include <cyg/infra/diag.h>
tylerwilson 0:3ab1d2d14eb3 54 #include <cyg/hal/hal_diag.h>
tylerwilson 0:3ab1d2d14eb3 55 #include <cyg/pawn/amx.h>
tylerwilson 0:3ab1d2d14eb3 56 #else
tylerwilson 0:3ab1d2d14eb3 57 #include "amx.h"
tylerwilson 0:3ab1d2d14eb3 58 #endif
tylerwilson 0:3ab1d2d14eb3 59 #if defined __WIN32__ || defined _WIN32 || defined WIN32
tylerwilson 0:3ab1d2d14eb3 60 #include <windows.h>
tylerwilson 0:3ab1d2d14eb3 61 #endif
tylerwilson 0:3ab1d2d14eb3 62
tylerwilson 0:3ab1d2d14eb3 63 #if defined _UNICODE
tylerwilson 0:3ab1d2d14eb3 64 # include <tchar.h>
tylerwilson 0:3ab1d2d14eb3 65 #elif !defined __T
tylerwilson 0:3ab1d2d14eb3 66 typedef char TCHAR;
tylerwilson 0:3ab1d2d14eb3 67 # define __T(string) string
tylerwilson 0:3ab1d2d14eb3 68 # define _fgetts fgets
tylerwilson 0:3ab1d2d14eb3 69 # define _puttchar putchar
tylerwilson 0:3ab1d2d14eb3 70 # define _stprintf sprintf
tylerwilson 0:3ab1d2d14eb3 71 # define _tcschr strchr
tylerwilson 0:3ab1d2d14eb3 72 # define _tcscpy strcpy
tylerwilson 0:3ab1d2d14eb3 73 # define _tcsdup strdup
tylerwilson 0:3ab1d2d14eb3 74 # define _tcslen strlen
tylerwilson 0:3ab1d2d14eb3 75 # define _tprintf printf
tylerwilson 0:3ab1d2d14eb3 76 #endif
tylerwilson 0:3ab1d2d14eb3 77 #include "amxcons.h"
tylerwilson 0:3ab1d2d14eb3 78
tylerwilson 0:3ab1d2d14eb3 79 #if defined AMX_TERMINAL
tylerwilson 0:3ab1d2d14eb3 80 #define EOL_CHAR '\r'
tylerwilson 0:3ab1d2d14eb3 81 #endif
tylerwilson 0:3ab1d2d14eb3 82 #if defined __WIN32__ || defined _WIN32 || defined WIN32 || defined __MSDOS__
tylerwilson 0:3ab1d2d14eb3 83 #define EOL_CHAR '\r'
tylerwilson 0:3ab1d2d14eb3 84 #endif
tylerwilson 0:3ab1d2d14eb3 85 #if !defined EOL_CHAR
tylerwilson 0:3ab1d2d14eb3 86 /* if not a "known" operating system, assume Linux/Unix */
tylerwilson 0:3ab1d2d14eb3 87 #define EOL_CHAR '\n'
tylerwilson 0:3ab1d2d14eb3 88 #endif
tylerwilson 0:3ab1d2d14eb3 89
tylerwilson 0:3ab1d2d14eb3 90 #if !defined AMX_STRING_LIB
tylerwilson 0:3ab1d2d14eb3 91
tylerwilson 0:3ab1d2d14eb3 92 #if defined AMX_TERMINAL
tylerwilson 0:3ab1d2d14eb3 93 /* required functions are implemented elsewhere */
tylerwilson 0:3ab1d2d14eb3 94 int amx_putstr(const TCHAR *);
tylerwilson 0:3ab1d2d14eb3 95 int amx_putchar(int);
tylerwilson 0:3ab1d2d14eb3 96 int amx_fflush(void);
tylerwilson 0:3ab1d2d14eb3 97 int amx_getch(void);
tylerwilson 0:3ab1d2d14eb3 98 TCHAR *amx_gets(TCHAR *,int);
tylerwilson 0:3ab1d2d14eb3 99 int amx_termctl(int,int);
tylerwilson 0:3ab1d2d14eb3 100 void amx_clrscr(void);
tylerwilson 0:3ab1d2d14eb3 101 void amx_clreol(void);
tylerwilson 0:3ab1d2d14eb3 102 int amx_gotoxy(int x,int y);
tylerwilson 0:3ab1d2d14eb3 103 void amx_wherexy(int *x,int *y);
tylerwilson 0:3ab1d2d14eb3 104 unsigned int amx_setattr(int foregr,int backgr,int highlight);
tylerwilson 0:3ab1d2d14eb3 105 void amx_console(int columns, int lines, int flags);
tylerwilson 0:3ab1d2d14eb3 106 void amx_viewsize(int *width,int *height);
tylerwilson 0:3ab1d2d14eb3 107 int amx_kbhit(void);
tylerwilson 0:3ab1d2d14eb3 108 #elif defined CURSES && CURSES != 0
tylerwilson 0:3ab1d2d14eb3 109 /* Use the "curses" library to implement the console */
tylerwilson 0:3ab1d2d14eb3 110 static WINDOW *curseswin;
tylerwilson 0:3ab1d2d14eb3 111 #define amx_putstr(s) printw("%s",(s))
tylerwilson 0:3ab1d2d14eb3 112 #define amx_putchar(c) addch(c)
tylerwilson 0:3ab1d2d14eb3 113 #define amx_fflush() refresh()
tylerwilson 0:3ab1d2d14eb3 114 #define amx_getch() getch()
tylerwilson 0:3ab1d2d14eb3 115 #define amx_gets(s,n) getnstr((s),(n))
tylerwilson 0:3ab1d2d14eb3 116 #define amx_clrscr() clear()
tylerwilson 0:3ab1d2d14eb3 117 #define amx_clreol() clrtoeol()
tylerwilson 0:3ab1d2d14eb3 118 #define amx_gotoxy(x,y) move((y)-1,(x)-1)
tylerwilson 0:3ab1d2d14eb3 119 #define amx_console(c,l,f) ((void)(c),(void)(l),(void)(f))
tylerwilson 0:3ab1d2d14eb3 120 unsigned int amx_setattr(int foregr,int backgr,int highlight)
tylerwilson 0:3ab1d2d14eb3 121 {
tylerwilson 0:3ab1d2d14eb3 122 int attribs=A_NORMAL;
tylerwilson 0:3ab1d2d14eb3 123 if (highlight>0)
tylerwilson 0:3ab1d2d14eb3 124 attribs=(attribs & ~A_NORMAL) | A_STANDOUT;
tylerwilson 0:3ab1d2d14eb3 125 attrset(attribs);
tylerwilson 0:3ab1d2d14eb3 126 //??? in future, also handle colours
tylerwilson 0:3ab1d2d14eb3 127 }
tylerwilson 0:3ab1d2d14eb3 128 void CreateConsole(void);
tylerwilson 0:3ab1d2d14eb3 129 int amx_kbhit(void)
tylerwilson 0:3ab1d2d14eb3 130 {
tylerwilson 0:3ab1d2d14eb3 131 int result;
tylerwilson 0:3ab1d2d14eb3 132 CreateConsole();
tylerwilson 0:3ab1d2d14eb3 133 nodelay(curseswin,TRUE); /* enter non-blocking state */
tylerwilson 0:3ab1d2d14eb3 134 result=getch(); /* read key (if any) */
tylerwilson 0:3ab1d2d14eb3 135 nodelay(curseswin,FALSE); /* leave non-blocking state */
tylerwilson 0:3ab1d2d14eb3 136 if (result!=ERR)
tylerwilson 0:3ab1d2d14eb3 137 ungetch(result); /* a key is waiting, push it back */
tylerwilson 0:3ab1d2d14eb3 138 return (result==ERR) ? 0 : 1;
tylerwilson 0:3ab1d2d14eb3 139 }
tylerwilson 0:3ab1d2d14eb3 140 int amx_termctl(int code,int value)
tylerwilson 0:3ab1d2d14eb3 141 {
tylerwilson 0:3ab1d2d14eb3 142 switch (code) {
tylerwilson 0:3ab1d2d14eb3 143 case 0: /* query terminal support */
tylerwilson 0:3ab1d2d14eb3 144 return 1;
tylerwilson 0:3ab1d2d14eb3 145 /* case 1: */ /* switch auto-wrap on/off (not supported in curses!) */
tylerwilson 0:3ab1d2d14eb3 146 /* case 2: */ /* create/switch to another console */
tylerwilson 0:3ab1d2d14eb3 147 case 3: /* set emphasized font */
tylerwilson 0:3ab1d2d14eb3 148 if (value)
tylerwilson 0:3ab1d2d14eb3 149 attron(A_BOLD);
tylerwilson 0:3ab1d2d14eb3 150 else
tylerwilson 0:3ab1d2d14eb3 151 attroff(A_BOLD);
tylerwilson 0:3ab1d2d14eb3 152 return 1;
tylerwilson 0:3ab1d2d14eb3 153 /* case 4: */ /* query whether a terminal is "open" */
tylerwilson 0:3ab1d2d14eb3 154 default:
tylerwilson 0:3ab1d2d14eb3 155 return 0;
tylerwilson 0:3ab1d2d14eb3 156 } /* switch */
tylerwilson 0:3ab1d2d14eb3 157 }
tylerwilson 0:3ab1d2d14eb3 158 void amx_wherexy(int *x,int *y)
tylerwilson 0:3ab1d2d14eb3 159 {
tylerwilson 0:3ab1d2d14eb3 160 int row,col;
tylerwilson 0:3ab1d2d14eb3 161 getyx(curseswin,row,col);
tylerwilson 0:3ab1d2d14eb3 162 if (x!=NULL)
tylerwilson 0:3ab1d2d14eb3 163 *x=col+1;
tylerwilson 0:3ab1d2d14eb3 164 if (y!=NULL)
tylerwilson 0:3ab1d2d14eb3 165 *y=row+1;
tylerwilson 0:3ab1d2d14eb3 166 }
tylerwilson 0:3ab1d2d14eb3 167 void amx_viewsize(int *width,int *height)
tylerwilson 0:3ab1d2d14eb3 168 {
tylerwilson 0:3ab1d2d14eb3 169 int row,col;
tylerwilson 0:3ab1d2d14eb3 170 getmaxyx(curseswin,row,col);
tylerwilson 0:3ab1d2d14eb3 171 if (width!=NULL)
tylerwilson 0:3ab1d2d14eb3 172 *width=col;
tylerwilson 0:3ab1d2d14eb3 173 if (height!=NULL)
tylerwilson 0:3ab1d2d14eb3 174 *height=row;
tylerwilson 0:3ab1d2d14eb3 175 }
tylerwilson 0:3ab1d2d14eb3 176 #elif defined VT100 || defined __LINUX__ || defined ANSITERM || defined __ECOS__
tylerwilson 0:3ab1d2d14eb3 177 /* ANSI/VT100 terminal, or shell emulating "xterm" */
tylerwilson 0:3ab1d2d14eb3 178 #if defined __ECOS__
tylerwilson 0:3ab1d2d14eb3 179 #define AMXCONSOLE_NOIDLE
tylerwilson 0:3ab1d2d14eb3 180 #endif
tylerwilson 0:3ab1d2d14eb3 181
tylerwilson 0:3ab1d2d14eb3 182 #if CYGPKG_PAWN_AMXCONSOLE_DIAG==1
tylerwilson 0:3ab1d2d14eb3 183 /* eCos has basically two ways to make simple exchanges with a terminal:
tylerwilson 0:3ab1d2d14eb3 184 * - with the diag_*() functions (no input provided!)
tylerwilson 0:3ab1d2d14eb3 185 * - with f*() functions (fprintf(),fputs(), etc).
tylerwilson 0:3ab1d2d14eb3 186 */
tylerwilson 0:3ab1d2d14eb3 187 #define amx_fflush()
tylerwilson 0:3ab1d2d14eb3 188
tylerwilson 0:3ab1d2d14eb3 189 static int amx_putstr(TCHAR *s)
tylerwilson 0:3ab1d2d14eb3 190 {
tylerwilson 0:3ab1d2d14eb3 191 diag_write_string(s);
tylerwilson 0:3ab1d2d14eb3 192 return 1;
tylerwilson 0:3ab1d2d14eb3 193 }
tylerwilson 0:3ab1d2d14eb3 194 static int amx_putchar(TCHAR c)
tylerwilson 0:3ab1d2d14eb3 195 {
tylerwilson 0:3ab1d2d14eb3 196 diag_write_char(c);
tylerwilson 0:3ab1d2d14eb3 197 return c;
tylerwilson 0:3ab1d2d14eb3 198 }
tylerwilson 0:3ab1d2d14eb3 199 static char amx_getch(void)
tylerwilson 0:3ab1d2d14eb3 200 {
tylerwilson 0:3ab1d2d14eb3 201 char c=-1;
tylerwilson 0:3ab1d2d14eb3 202 HAL_DIAG_READ_CHAR(c);
tylerwilson 0:3ab1d2d14eb3 203 return c;
tylerwilson 0:3ab1d2d14eb3 204 }
tylerwilson 0:3ab1d2d14eb3 205 #else
tylerwilson 0:3ab1d2d14eb3 206
tylerwilson 0:3ab1d2d14eb3 207 #define amx_putstr(s) fputs((s),stdout)
tylerwilson 0:3ab1d2d14eb3 208 #define amx_putchar(c) putchar(c)
tylerwilson 0:3ab1d2d14eb3 209 #define amx_fflush() fflush(stdout)
tylerwilson 0:3ab1d2d14eb3 210 #define amx_getch() getch()
tylerwilson 0:3ab1d2d14eb3 211 #define amx_gets(s,n) fgets(s,n,stdin)
tylerwilson 0:3ab1d2d14eb3 212 #define amx_kbhit() kbhit()
tylerwilson 0:3ab1d2d14eb3 213 #endif
tylerwilson 0:3ab1d2d14eb3 214
tylerwilson 0:3ab1d2d14eb3 215 int amx_termctl(int code,int value)
tylerwilson 0:3ab1d2d14eb3 216 {
tylerwilson 0:3ab1d2d14eb3 217 switch (code) {
tylerwilson 0:3ab1d2d14eb3 218 case 0: /* query terminal support */
tylerwilson 0:3ab1d2d14eb3 219 return 1;
tylerwilson 0:3ab1d2d14eb3 220
tylerwilson 0:3ab1d2d14eb3 221 case 1: /* switch "auto-wrap" on or off */
tylerwilson 0:3ab1d2d14eb3 222 if (value)
tylerwilson 0:3ab1d2d14eb3 223 amx_putstr("\033[?7h"); /* enable "auto-wrap" */
tylerwilson 0:3ab1d2d14eb3 224 else
tylerwilson 0:3ab1d2d14eb3 225 amx_putstr("\033[?7l"); /* disable "auto-wrap" */
tylerwilson 0:3ab1d2d14eb3 226 return 1;
tylerwilson 0:3ab1d2d14eb3 227
tylerwilson 0:3ab1d2d14eb3 228 #if 0
tylerwilson 0:3ab1d2d14eb3 229 /* next to swapping buffers, more information should be saved and swapped,
tylerwilson 0:3ab1d2d14eb3 230 * such as the cursor position and the current terminal attributes
tylerwilson 0:3ab1d2d14eb3 231 */
tylerwilson 0:3ab1d2d14eb3 232 case 2: /* swap console buffers */
tylerwilson 0:3ab1d2d14eb3 233 amx_fflush();
tylerwilson 0:3ab1d2d14eb3 234 if (value==1) {
tylerwilson 0:3ab1d2d14eb3 235 amx_putstr("\033[?47h");
tylerwilson 0:3ab1d2d14eb3 236 } else {
tylerwilson 0:3ab1d2d14eb3 237 amx_putstr("\033[?47l");
tylerwilson 0:3ab1d2d14eb3 238 } /* if */
tylerwilson 0:3ab1d2d14eb3 239 amx_fflush();
tylerwilson 0:3ab1d2d14eb3 240 return 1;
tylerwilson 0:3ab1d2d14eb3 241 #endif
tylerwilson 0:3ab1d2d14eb3 242
tylerwilson 0:3ab1d2d14eb3 243 case 3: /* set bold/highlighted font */
tylerwilson 0:3ab1d2d14eb3 244 return 0;
tylerwilson 0:3ab1d2d14eb3 245
tylerwilson 0:3ab1d2d14eb3 246 default:
tylerwilson 0:3ab1d2d14eb3 247 return 0;
tylerwilson 0:3ab1d2d14eb3 248 } /* switch */
tylerwilson 0:3ab1d2d14eb3 249 }
tylerwilson 0:3ab1d2d14eb3 250 void amx_clrscr(void)
tylerwilson 0:3ab1d2d14eb3 251 {
tylerwilson 0:3ab1d2d14eb3 252 amx_putstr("\033[2J");
tylerwilson 0:3ab1d2d14eb3 253 amx_fflush(); /* pump through the terminal codes */
tylerwilson 0:3ab1d2d14eb3 254 }
tylerwilson 0:3ab1d2d14eb3 255 void amx_clreol(void)
tylerwilson 0:3ab1d2d14eb3 256 {
tylerwilson 0:3ab1d2d14eb3 257 amx_putstr("\033[K");
tylerwilson 0:3ab1d2d14eb3 258 amx_fflush(); /* pump through the terminal codes */
tylerwilson 0:3ab1d2d14eb3 259 }
tylerwilson 0:3ab1d2d14eb3 260 int amx_gotoxy(int x,int y)
tylerwilson 0:3ab1d2d14eb3 261 {
tylerwilson 0:3ab1d2d14eb3 262 char str[30];
tylerwilson 0:3ab1d2d14eb3 263 _stprintf(str,"\033[%d;%dH",y,x);
tylerwilson 0:3ab1d2d14eb3 264 amx_putstr(str);
tylerwilson 0:3ab1d2d14eb3 265 amx_fflush(); /* pump through the terminal codes */
tylerwilson 0:3ab1d2d14eb3 266 return 1;
tylerwilson 0:3ab1d2d14eb3 267 }
tylerwilson 0:3ab1d2d14eb3 268 void amx_wherexy(int *x,int *y)
tylerwilson 0:3ab1d2d14eb3 269 {
tylerwilson 0:3ab1d2d14eb3 270 int val,i;
tylerwilson 0:3ab1d2d14eb3 271 char str[10];
tylerwilson 0:3ab1d2d14eb3 272
tylerwilson 0:3ab1d2d14eb3 273 assert(x!=NULL && y!=NULL);
tylerwilson 0:3ab1d2d14eb3 274 amx_putstr("\033[6n");
tylerwilson 0:3ab1d2d14eb3 275 amx_fflush();
tylerwilson 0:3ab1d2d14eb3 276 while (amx_getch()!='\033')
tylerwilson 0:3ab1d2d14eb3 277 /* nothing */;
tylerwilson 0:3ab1d2d14eb3 278 val=amx_getch();
tylerwilson 0:3ab1d2d14eb3 279 assert(val=='[');
tylerwilson 0:3ab1d2d14eb3 280 for (i=0; i<8 && (val=amx_getch())!=';'; i++)
tylerwilson 0:3ab1d2d14eb3 281 str[i]=(char)val;
tylerwilson 0:3ab1d2d14eb3 282 str[i]='\0';
tylerwilson 0:3ab1d2d14eb3 283 if (y!=NULL)
tylerwilson 0:3ab1d2d14eb3 284 *y=atoi(str);
tylerwilson 0:3ab1d2d14eb3 285 for (i=0; i<8 && (val=amx_getch())!='R'; i++)
tylerwilson 0:3ab1d2d14eb3 286 str[i]=(char)val;
tylerwilson 0:3ab1d2d14eb3 287 str[i]='\0';
tylerwilson 0:3ab1d2d14eb3 288 if (x!=NULL)
tylerwilson 0:3ab1d2d14eb3 289 *x=atoi(str);
tylerwilson 0:3ab1d2d14eb3 290 #if defined ANSITERM
tylerwilson 0:3ab1d2d14eb3 291 val=amx_getch();
tylerwilson 0:3ab1d2d14eb3 292 assert(val=='\r'); /* ANSI driver adds CR to the end of the command */
tylerwilson 0:3ab1d2d14eb3 293 #endif
tylerwilson 0:3ab1d2d14eb3 294 }
tylerwilson 0:3ab1d2d14eb3 295 unsigned int amx_setattr(int foregr,int backgr,int highlight)
tylerwilson 0:3ab1d2d14eb3 296 {
tylerwilson 0:3ab1d2d14eb3 297 static short current=(0 << 8) | 7;
tylerwilson 0:3ab1d2d14eb3 298 short prev = current;
tylerwilson 0:3ab1d2d14eb3 299 char str[30];
tylerwilson 0:3ab1d2d14eb3 300
tylerwilson 0:3ab1d2d14eb3 301 if (foregr>=0) {
tylerwilson 0:3ab1d2d14eb3 302 _stprintf(str,"\x1b[%dm",foregr+30);
tylerwilson 0:3ab1d2d14eb3 303 amx_putstr(str);
tylerwilson 0:3ab1d2d14eb3 304 current=(current & 0xff00) | (foregr & 0x0f);
tylerwilson 0:3ab1d2d14eb3 305 } /* if */
tylerwilson 0:3ab1d2d14eb3 306 if (backgr>=0) {
tylerwilson 0:3ab1d2d14eb3 307 _stprintf(str,"\x1b[%dm",backgr+40);
tylerwilson 0:3ab1d2d14eb3 308 amx_putstr(str);
tylerwilson 0:3ab1d2d14eb3 309 current=(current & 0x00ff) | ((backgr & 0x0f) << 8);
tylerwilson 0:3ab1d2d14eb3 310 } /* if */
tylerwilson 0:3ab1d2d14eb3 311 if (highlight>=0) {
tylerwilson 0:3ab1d2d14eb3 312 _stprintf(str,"\x1b[%dm",highlight);
tylerwilson 0:3ab1d2d14eb3 313 amx_putstr(str);
tylerwilson 0:3ab1d2d14eb3 314 current=(current & 0x7fff) | ((highlight & 0x01) << 15);
tylerwilson 0:3ab1d2d14eb3 315 } /* if */
tylerwilson 0:3ab1d2d14eb3 316 return prev;
tylerwilson 0:3ab1d2d14eb3 317 }
tylerwilson 0:3ab1d2d14eb3 318 void amx_console(int columns, int lines, int flags)
tylerwilson 0:3ab1d2d14eb3 319 {
tylerwilson 0:3ab1d2d14eb3 320 char str[30];
tylerwilson 0:3ab1d2d14eb3 321
tylerwilson 0:3ab1d2d14eb3 322 (void)flags;
tylerwilson 0:3ab1d2d14eb3 323 /* There is no ANSI code (or VT100/VT220) to set the size of the console
tylerwilson 0:3ab1d2d14eb3 324 * (indeed, the terminal was that of the alphanumeric display). In xterm (a
tylerwilson 0:3ab1d2d14eb3 325 * terminal emulator) we can set the terminal size though, and most
tylerwilson 0:3ab1d2d14eb3 326 * terminals that in use today are in fact emulators.
tylerwilson 0:3ab1d2d14eb3 327 * Putty understands this code too, by many others do not.
tylerwilson 0:3ab1d2d14eb3 328 */
tylerwilson 0:3ab1d2d14eb3 329 sprintf(str,"\033[8;%d;%dt",lines,columns);
tylerwilson 0:3ab1d2d14eb3 330 amx_putstr(str);
tylerwilson 0:3ab1d2d14eb3 331 amx_fflush();
tylerwilson 0:3ab1d2d14eb3 332 }
tylerwilson 0:3ab1d2d14eb3 333 void amx_viewsize(int *width,int *height)
tylerwilson 0:3ab1d2d14eb3 334 {
tylerwilson 0:3ab1d2d14eb3 335 /* a trick to get the size of the terminal is to position the cursor far
tylerwilson 0:3ab1d2d14eb3 336 * away and then read it back
tylerwilson 0:3ab1d2d14eb3 337 */
tylerwilson 0:3ab1d2d14eb3 338 amx_gotoxy(999,999);
tylerwilson 0:3ab1d2d14eb3 339 amx_wherexy(width,height);
tylerwilson 0:3ab1d2d14eb3 340 }
tylerwilson 0:3ab1d2d14eb3 341 #elif defined __WIN32__ || defined _WIN32 || defined WIN32
tylerwilson 0:3ab1d2d14eb3 342 /* Win32 console */
tylerwilson 0:3ab1d2d14eb3 343 #define amx_putstr(s) _tprintf("%s",(s))
tylerwilson 0:3ab1d2d14eb3 344 #define amx_putchar(c) _puttchar(c)
tylerwilson 0:3ab1d2d14eb3 345 #define amx_fflush() fflush(stdout)
tylerwilson 0:3ab1d2d14eb3 346 #define amx_getch() getch()
tylerwilson 0:3ab1d2d14eb3 347 #define amx_gets(s,n) _fgetts(s,n,stdin)
tylerwilson 0:3ab1d2d14eb3 348 #define amx_kbhit() kbhit()
tylerwilson 0:3ab1d2d14eb3 349
tylerwilson 0:3ab1d2d14eb3 350 int amx_termctl(int code,int value)
tylerwilson 0:3ab1d2d14eb3 351 {
tylerwilson 0:3ab1d2d14eb3 352 switch (code) {
tylerwilson 0:3ab1d2d14eb3 353 case 0: /* query terminal support */
tylerwilson 0:3ab1d2d14eb3 354 return 1;
tylerwilson 0:3ab1d2d14eb3 355
tylerwilson 0:3ab1d2d14eb3 356 case 1: { /* switch auto-wrap on/off */
tylerwilson 0:3ab1d2d14eb3 357 /* only works in Windows 2000/XP */
tylerwilson 0:3ab1d2d14eb3 358 HANDLE hConsole=GetStdHandle(STD_OUTPUT_HANDLE);
tylerwilson 0:3ab1d2d14eb3 359 DWORD Flags=ENABLE_PROCESSED_OUTPUT;
tylerwilson 0:3ab1d2d14eb3 360 if (value)
tylerwilson 0:3ab1d2d14eb3 361 Flags |= ENABLE_WRAP_AT_EOL_OUTPUT;
tylerwilson 0:3ab1d2d14eb3 362 SetConsoleMode(hConsole,Flags);
tylerwilson 0:3ab1d2d14eb3 363 return 1;
tylerwilson 0:3ab1d2d14eb3 364 } /* case */
tylerwilson 0:3ab1d2d14eb3 365
tylerwilson 0:3ab1d2d14eb3 366 /* case 2: */ /* create/switch to another console */
tylerwilson 0:3ab1d2d14eb3 367 /* case 3: */ /* set emphasized font */
tylerwilson 0:3ab1d2d14eb3 368 /* case 4: */ /* query whether a terminal is "open" */
tylerwilson 0:3ab1d2d14eb3 369 default:
tylerwilson 0:3ab1d2d14eb3 370 return 0;
tylerwilson 0:3ab1d2d14eb3 371 } /* switch */
tylerwilson 0:3ab1d2d14eb3 372 }
tylerwilson 0:3ab1d2d14eb3 373 void amx_clrscr(void)
tylerwilson 0:3ab1d2d14eb3 374 {
tylerwilson 0:3ab1d2d14eb3 375 COORD coordScreen={0,0};
tylerwilson 0:3ab1d2d14eb3 376 DWORD cCharsWritten;
tylerwilson 0:3ab1d2d14eb3 377 CONSOLE_SCREEN_BUFFER_INFO csbi;
tylerwilson 0:3ab1d2d14eb3 378 DWORD dwConSize;
tylerwilson 0:3ab1d2d14eb3 379 HANDLE hConsole=GetStdHandle(STD_OUTPUT_HANDLE);
tylerwilson 0:3ab1d2d14eb3 380
tylerwilson 0:3ab1d2d14eb3 381 amx_fflush(); /* make sure the I/O buffer is empty */
tylerwilson 0:3ab1d2d14eb3 382 GetConsoleScreenBufferInfo(hConsole,&csbi);
tylerwilson 0:3ab1d2d14eb3 383 dwConSize=csbi.dwSize.X*csbi.dwSize.Y;
tylerwilson 0:3ab1d2d14eb3 384 FillConsoleOutputCharacter(hConsole,' ',dwConSize,coordScreen,&cCharsWritten);
tylerwilson 0:3ab1d2d14eb3 385 FillConsoleOutputAttribute(hConsole,csbi.wAttributes,dwConSize,coordScreen, &cCharsWritten);
tylerwilson 0:3ab1d2d14eb3 386 SetConsoleCursorPosition(hConsole,coordScreen);
tylerwilson 0:3ab1d2d14eb3 387 }
tylerwilson 0:3ab1d2d14eb3 388 void amx_clreol(void)
tylerwilson 0:3ab1d2d14eb3 389 {
tylerwilson 0:3ab1d2d14eb3 390 DWORD cCharsWritten;
tylerwilson 0:3ab1d2d14eb3 391 CONSOLE_SCREEN_BUFFER_INFO csbi;
tylerwilson 0:3ab1d2d14eb3 392 DWORD dwConSize;
tylerwilson 0:3ab1d2d14eb3 393 HANDLE hConsole=GetStdHandle(STD_OUTPUT_HANDLE);
tylerwilson 0:3ab1d2d14eb3 394
tylerwilson 0:3ab1d2d14eb3 395 amx_fflush(); /* make sure all output is written */
tylerwilson 0:3ab1d2d14eb3 396 GetConsoleScreenBufferInfo(hConsole,&csbi);
tylerwilson 0:3ab1d2d14eb3 397 dwConSize=csbi.dwSize.X - csbi.dwCursorPosition.X;
tylerwilson 0:3ab1d2d14eb3 398 FillConsoleOutputCharacter(hConsole,' ',dwConSize,csbi.dwCursorPosition,&cCharsWritten);
tylerwilson 0:3ab1d2d14eb3 399 FillConsoleOutputAttribute(hConsole,csbi.wAttributes,dwConSize,csbi.dwCursorPosition,&cCharsWritten);
tylerwilson 0:3ab1d2d14eb3 400 }
tylerwilson 0:3ab1d2d14eb3 401 int amx_gotoxy(int x,int y)
tylerwilson 0:3ab1d2d14eb3 402 {
tylerwilson 0:3ab1d2d14eb3 403 COORD point;
tylerwilson 0:3ab1d2d14eb3 404 CONSOLE_SCREEN_BUFFER_INFO csbi;
tylerwilson 0:3ab1d2d14eb3 405 HANDLE hConsole=GetStdHandle(STD_OUTPUT_HANDLE);
tylerwilson 0:3ab1d2d14eb3 406
tylerwilson 0:3ab1d2d14eb3 407 GetConsoleScreenBufferInfo(hConsole, &csbi);
tylerwilson 0:3ab1d2d14eb3 408 if (x<=0 || x>csbi.dwSize.X || y<=0 || y>csbi.dwSize.Y)
tylerwilson 0:3ab1d2d14eb3 409 return 0;
tylerwilson 0:3ab1d2d14eb3 410 amx_fflush(); /* make sure all output is written */
tylerwilson 0:3ab1d2d14eb3 411 point.X=(short)(x-1);
tylerwilson 0:3ab1d2d14eb3 412 point.Y=(short)(y-1);
tylerwilson 0:3ab1d2d14eb3 413 SetConsoleCursorPosition(hConsole,point);
tylerwilson 0:3ab1d2d14eb3 414 return 1;
tylerwilson 0:3ab1d2d14eb3 415 }
tylerwilson 0:3ab1d2d14eb3 416 void amx_wherexy(int *x,int *y)
tylerwilson 0:3ab1d2d14eb3 417 {
tylerwilson 0:3ab1d2d14eb3 418 CONSOLE_SCREEN_BUFFER_INFO csbi;
tylerwilson 0:3ab1d2d14eb3 419 amx_fflush(); /* make sure all output is written */
tylerwilson 0:3ab1d2d14eb3 420 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
tylerwilson 0:3ab1d2d14eb3 421 if (x!=NULL)
tylerwilson 0:3ab1d2d14eb3 422 *x=csbi.dwCursorPosition.X+1;
tylerwilson 0:3ab1d2d14eb3 423 if (y!=NULL)
tylerwilson 0:3ab1d2d14eb3 424 *y=csbi.dwCursorPosition.Y+1;
tylerwilson 0:3ab1d2d14eb3 425 }
tylerwilson 0:3ab1d2d14eb3 426 unsigned int amx_setattr(int foregr,int backgr,int highlight)
tylerwilson 0:3ab1d2d14eb3 427 {
tylerwilson 0:3ab1d2d14eb3 428 static int ansi_colours[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
tylerwilson 0:3ab1d2d14eb3 429 CONSOLE_SCREEN_BUFFER_INFO csbi;
tylerwilson 0:3ab1d2d14eb3 430 int f,b,h,prev;
tylerwilson 0:3ab1d2d14eb3 431 HANDLE hConsole=GetStdHandle(STD_OUTPUT_HANDLE);
tylerwilson 0:3ab1d2d14eb3 432
tylerwilson 0:3ab1d2d14eb3 433 amx_fflush(); /* make sure all output is written */
tylerwilson 0:3ab1d2d14eb3 434 GetConsoleScreenBufferInfo(hConsole,&csbi);
tylerwilson 0:3ab1d2d14eb3 435 f=csbi.wAttributes & 0x07;
tylerwilson 0:3ab1d2d14eb3 436 b=(csbi.wAttributes >> 4) & 0x0f;
tylerwilson 0:3ab1d2d14eb3 437 h=(csbi.wAttributes & 0x08) ? 1 : 0;
tylerwilson 0:3ab1d2d14eb3 438 prev=(b << 8) | f | (h << 15);
tylerwilson 0:3ab1d2d14eb3 439 if (foregr>=0 && foregr<8)
tylerwilson 0:3ab1d2d14eb3 440 f=ansi_colours[foregr];
tylerwilson 0:3ab1d2d14eb3 441 if (backgr>=0 && backgr<8)
tylerwilson 0:3ab1d2d14eb3 442 b=ansi_colours[backgr];
tylerwilson 0:3ab1d2d14eb3 443 if (highlight>=0)
tylerwilson 0:3ab1d2d14eb3 444 h=highlight!=0;
tylerwilson 0:3ab1d2d14eb3 445 SetConsoleTextAttribute(hConsole, (WORD)((b << 4) | f | (h << 3)));
tylerwilson 0:3ab1d2d14eb3 446 return prev;
tylerwilson 0:3ab1d2d14eb3 447 }
tylerwilson 0:3ab1d2d14eb3 448 void amx_console(int columns, int lines, int flags)
tylerwilson 0:3ab1d2d14eb3 449 {
tylerwilson 0:3ab1d2d14eb3 450 SMALL_RECT rect;
tylerwilson 0:3ab1d2d14eb3 451 COORD dwSize;
tylerwilson 0:3ab1d2d14eb3 452 (void)flags;
tylerwilson 0:3ab1d2d14eb3 453 dwSize.X=(short)columns;
tylerwilson 0:3ab1d2d14eb3 454 dwSize.Y=(short)lines;
tylerwilson 0:3ab1d2d14eb3 455 SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE),dwSize);
tylerwilson 0:3ab1d2d14eb3 456 rect.Left=0;
tylerwilson 0:3ab1d2d14eb3 457 rect.Top=0;
tylerwilson 0:3ab1d2d14eb3 458 rect.Right=(short)(columns-1);
tylerwilson 0:3ab1d2d14eb3 459 rect.Bottom=(short)(lines-1);
tylerwilson 0:3ab1d2d14eb3 460 SetConsoleWindowInfo(GetStdHandle(STD_OUTPUT_HANDLE),TRUE,&rect);
tylerwilson 0:3ab1d2d14eb3 461 }
tylerwilson 0:3ab1d2d14eb3 462 void amx_viewsize(int *width,int *height)
tylerwilson 0:3ab1d2d14eb3 463 {
tylerwilson 0:3ab1d2d14eb3 464 CONSOLE_SCREEN_BUFFER_INFO csbi;
tylerwilson 0:3ab1d2d14eb3 465 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),&csbi);
tylerwilson 0:3ab1d2d14eb3 466 if (width!=NULL)
tylerwilson 0:3ab1d2d14eb3 467 *width=(int)csbi.dwSize.X;
tylerwilson 0:3ab1d2d14eb3 468 if (height!=NULL)
tylerwilson 0:3ab1d2d14eb3 469 *height=(int)(csbi.srWindow.Bottom-csbi.srWindow.Top+1);
tylerwilson 0:3ab1d2d14eb3 470 }
tylerwilson 0:3ab1d2d14eb3 471 #else
tylerwilson 0:3ab1d2d14eb3 472 /* assume a streaming terminal; limited features (no colour, no cursor
tylerwilson 0:3ab1d2d14eb3 473 * control)
tylerwilson 0:3ab1d2d14eb3 474 */
tylerwilson 0:3ab1d2d14eb3 475 #define amx_putstr(s) printf("%s",(s))
tylerwilson 0:3ab1d2d14eb3 476 #define amx_putchar(c) putchar(c)
tylerwilson 0:3ab1d2d14eb3 477 #define amx_fflush() fflush(stdout)
tylerwilson 0:3ab1d2d14eb3 478 #define amx_gets(s,n) fgets(s,n,stdin)
tylerwilson 0:3ab1d2d14eb3 479 #define amx_clrscr() (void)(0)
tylerwilson 0:3ab1d2d14eb3 480 #define amx_clreol() (void)(0)
tylerwilson 0:3ab1d2d14eb3 481 #define amx_gotoxy(x,y) ((void)(x),(void)(y),(0))
tylerwilson 0:3ab1d2d14eb3 482 #define amx_wherexy(x,y) (*(x)=*(y)=0)
tylerwilson 0:3ab1d2d14eb3 483 #define amx_setattr(c,b,h) ((void)(c),(void)(b),(void)(h),(0))
tylerwilson 0:3ab1d2d14eb3 484 #define amx_termctl(c,v) ((void)(c),(void)(v),(0))
tylerwilson 0:3ab1d2d14eb3 485 #define amx_console(c,l,f) ((void)(c),(void)(l),(void)(f))
tylerwilson 0:3ab1d2d14eb3 486 #define amx_viewsize (*(x)=80,*(y)=25)
tylerwilson 0:3ab1d2d14eb3 487 #if defined HAVE_CONIO
tylerwilson 0:3ab1d2d14eb3 488 #define amx_getch() getch()
tylerwilson 0:3ab1d2d14eb3 489 #define amx_kbhit() kbhit()
tylerwilson 0:3ab1d2d14eb3 490 #else
tylerwilson 0:3ab1d2d14eb3 491 #define amx_getch() getchar()
tylerwilson 0:3ab1d2d14eb3 492 #define amx_kbhit() (0)
tylerwilson 0:3ab1d2d14eb3 493 #endif
tylerwilson 0:3ab1d2d14eb3 494 #endif
tylerwilson 0:3ab1d2d14eb3 495
tylerwilson 0:3ab1d2d14eb3 496 #if !defined AMX_TERMINAL && (defined __WIN32__ || defined _WIN32 || defined WIN32)
tylerwilson 0:3ab1d2d14eb3 497 void CreateConsole(void)
tylerwilson 0:3ab1d2d14eb3 498 { static int createdconsole=0;
tylerwilson 0:3ab1d2d14eb3 499 if (!createdconsole) {
tylerwilson 0:3ab1d2d14eb3 500 AllocConsole();
tylerwilson 0:3ab1d2d14eb3 501 createdconsole=1;
tylerwilson 0:3ab1d2d14eb3 502 } /* if */
tylerwilson 0:3ab1d2d14eb3 503 }
tylerwilson 0:3ab1d2d14eb3 504 #elif defined CURSES && CURSES != 0
tylerwilson 0:3ab1d2d14eb3 505 // The Mac OS X build variant uses curses.
tylerwilson 0:3ab1d2d14eb3 506 void CreateConsole(void)
tylerwilson 0:3ab1d2d14eb3 507 { static int createdconsole=0;
tylerwilson 0:3ab1d2d14eb3 508 if (!createdconsole) {
tylerwilson 0:3ab1d2d14eb3 509 curseswin=initscr();
tylerwilson 0:3ab1d2d14eb3 510 cbreak();
tylerwilson 0:3ab1d2d14eb3 511 noecho();
tylerwilson 0:3ab1d2d14eb3 512 nonl();
tylerwilson 0:3ab1d2d14eb3 513 scrollok(curseswin,TRUE);
tylerwilson 0:3ab1d2d14eb3 514 intrflush(curseswin,FALSE);
tylerwilson 0:3ab1d2d14eb3 515 keypad(curseswin,TRUE);
tylerwilson 0:3ab1d2d14eb3 516 createdconsole=1;
tylerwilson 0:3ab1d2d14eb3 517 } /* if */
tylerwilson 0:3ab1d2d14eb3 518 }
tylerwilson 0:3ab1d2d14eb3 519 #else
tylerwilson 0:3ab1d2d14eb3 520 #define CreateConsole()
tylerwilson 0:3ab1d2d14eb3 521 #endif
tylerwilson 0:3ab1d2d14eb3 522
tylerwilson 0:3ab1d2d14eb3 523 static int cons_putstr(void *dest,const TCHAR *str)
tylerwilson 0:3ab1d2d14eb3 524 {
tylerwilson 0:3ab1d2d14eb3 525 (void)dest;
tylerwilson 0:3ab1d2d14eb3 526 return amx_putstr(str);
tylerwilson 0:3ab1d2d14eb3 527 }
tylerwilson 0:3ab1d2d14eb3 528
tylerwilson 0:3ab1d2d14eb3 529 static int cons_putchar(void *dest,TCHAR ch)
tylerwilson 0:3ab1d2d14eb3 530 {
tylerwilson 0:3ab1d2d14eb3 531 (void)dest;
tylerwilson 0:3ab1d2d14eb3 532 return amx_putchar(ch);
tylerwilson 0:3ab1d2d14eb3 533 }
tylerwilson 0:3ab1d2d14eb3 534
tylerwilson 0:3ab1d2d14eb3 535 #endif /* AMX_STRING_LIB */
tylerwilson 0:3ab1d2d14eb3 536
tylerwilson 0:3ab1d2d14eb3 537 enum {
tylerwilson 0:3ab1d2d14eb3 538 SV_DECIMAL,
tylerwilson 0:3ab1d2d14eb3 539 SV_HEX
tylerwilson 0:3ab1d2d14eb3 540 };
tylerwilson 0:3ab1d2d14eb3 541
tylerwilson 0:3ab1d2d14eb3 542 static TCHAR *reverse(TCHAR *string,int stop)
tylerwilson 0:3ab1d2d14eb3 543 {
tylerwilson 0:3ab1d2d14eb3 544 int start=0;
tylerwilson 0:3ab1d2d14eb3 545 TCHAR temp;
tylerwilson 0:3ab1d2d14eb3 546
tylerwilson 0:3ab1d2d14eb3 547 /* swap the string */
tylerwilson 0:3ab1d2d14eb3 548 stop--; /* avoid swapping the '\0' byte to the first position */
tylerwilson 0:3ab1d2d14eb3 549 while (stop - start > 0) {
tylerwilson 0:3ab1d2d14eb3 550 temp = string[start];
tylerwilson 0:3ab1d2d14eb3 551 string[start] = string[stop];
tylerwilson 0:3ab1d2d14eb3 552 string[stop] = temp;
tylerwilson 0:3ab1d2d14eb3 553 start++;
tylerwilson 0:3ab1d2d14eb3 554 stop--;
tylerwilson 0:3ab1d2d14eb3 555 } /* while */
tylerwilson 0:3ab1d2d14eb3 556 return string;
tylerwilson 0:3ab1d2d14eb3 557 }
tylerwilson 0:3ab1d2d14eb3 558
tylerwilson 0:3ab1d2d14eb3 559 /* Converts an integral value to a string, with optional padding with spaces or
tylerwilson 0:3ab1d2d14eb3 560 * zeros.
tylerwilson 0:3ab1d2d14eb3 561 * The "format" must be decimal or hexadecimal
tylerwilson 0:3ab1d2d14eb3 562 * The number is right-aligned in the field with the size of the absolute value
tylerwilson 0:3ab1d2d14eb3 563 * of the "width" parameter.
tylerwilson 0:3ab1d2d14eb3 564 * If the width value is positive, the string is padded with spaces; if it is
tylerwilson 0:3ab1d2d14eb3 565 * negative, it is padded with zeros.
tylerwilson 0:3ab1d2d14eb3 566 */
tylerwilson 0:3ab1d2d14eb3 567 static TCHAR *amx_strval(TCHAR buffer[], long value, int format, int width)
tylerwilson 0:3ab1d2d14eb3 568 {
tylerwilson 0:3ab1d2d14eb3 569 int start, stop;
tylerwilson 0:3ab1d2d14eb3 570 TCHAR temp;
tylerwilson 0:3ab1d2d14eb3 571
tylerwilson 0:3ab1d2d14eb3 572 start = stop = 0;
tylerwilson 0:3ab1d2d14eb3 573 if (format == SV_DECIMAL) {
tylerwilson 0:3ab1d2d14eb3 574 if (value < 0) {
tylerwilson 0:3ab1d2d14eb3 575 buffer[0] = __T('-');
tylerwilson 0:3ab1d2d14eb3 576 start = stop = 1;
tylerwilson 0:3ab1d2d14eb3 577 value = -value;
tylerwilson 0:3ab1d2d14eb3 578 } /* if */
tylerwilson 0:3ab1d2d14eb3 579 do {
tylerwilson 0:3ab1d2d14eb3 580 buffer[stop++] = (TCHAR)((value % 10) + __T('0'));
tylerwilson 0:3ab1d2d14eb3 581 value /= 10;
tylerwilson 0:3ab1d2d14eb3 582 } while (value > 0);
tylerwilson 0:3ab1d2d14eb3 583 } else {
tylerwilson 0:3ab1d2d14eb3 584 /* hexadecimal */
tylerwilson 0:3ab1d2d14eb3 585 unsigned long v = (unsigned long)value; /* copy to unsigned value for shifting */
tylerwilson 0:3ab1d2d14eb3 586 do {
tylerwilson 0:3ab1d2d14eb3 587 buffer[stop] = (TCHAR)((v & 0x0f) + __T('0'));
tylerwilson 0:3ab1d2d14eb3 588 if (buffer[stop] > __T('9'))
tylerwilson 0:3ab1d2d14eb3 589 buffer[stop] += (TCHAR)(__T('A') - __T('0') - 10);
tylerwilson 0:3ab1d2d14eb3 590 v >>= 4;
tylerwilson 0:3ab1d2d14eb3 591 stop++;
tylerwilson 0:3ab1d2d14eb3 592 } while (v != 0);
tylerwilson 0:3ab1d2d14eb3 593 } /* if */
tylerwilson 0:3ab1d2d14eb3 594
tylerwilson 0:3ab1d2d14eb3 595 /* pad to given width */
tylerwilson 0:3ab1d2d14eb3 596 if (width < 0) {
tylerwilson 0:3ab1d2d14eb3 597 temp = __T('0');
tylerwilson 0:3ab1d2d14eb3 598 width = -width;
tylerwilson 0:3ab1d2d14eb3 599 } else {
tylerwilson 0:3ab1d2d14eb3 600 temp = __T(' ');
tylerwilson 0:3ab1d2d14eb3 601 } /* if */
tylerwilson 0:3ab1d2d14eb3 602 while (stop < width)
tylerwilson 0:3ab1d2d14eb3 603 buffer[stop++] = temp;
tylerwilson 0:3ab1d2d14eb3 604
tylerwilson 0:3ab1d2d14eb3 605 buffer[stop] = __T('\0');
tylerwilson 0:3ab1d2d14eb3 606
tylerwilson 0:3ab1d2d14eb3 607 /* swap the string, and we are done */
tylerwilson 0:3ab1d2d14eb3 608 reverse(buffer+start,stop-start);
tylerwilson 0:3ab1d2d14eb3 609 return buffer;
tylerwilson 0:3ab1d2d14eb3 610 }
tylerwilson 0:3ab1d2d14eb3 611
tylerwilson 0:3ab1d2d14eb3 612 #if defined FIXEDPOINT
tylerwilson 0:3ab1d2d14eb3 613 #define FIXEDMULT 1000
tylerwilson 0:3ab1d2d14eb3 614 #define FIXEDDIGITS 3
tylerwilson 0:3ab1d2d14eb3 615
tylerwilson 0:3ab1d2d14eb3 616 static TCHAR *formatfixed(TCHAR *string,cell value,TCHAR align,int width,TCHAR decpoint,int digits,TCHAR filler)
tylerwilson 0:3ab1d2d14eb3 617 {
tylerwilson 0:3ab1d2d14eb3 618 int i, len;
tylerwilson 0:3ab1d2d14eb3 619 cell ipart,v;
tylerwilson 0:3ab1d2d14eb3 620 TCHAR vsign=__T('\0');
tylerwilson 0:3ab1d2d14eb3 621
tylerwilson 0:3ab1d2d14eb3 622 /* make the value positive (but keep the sign) */
tylerwilson 0:3ab1d2d14eb3 623 if (value<0) {
tylerwilson 0:3ab1d2d14eb3 624 value=-value;
tylerwilson 0:3ab1d2d14eb3 625 vsign=__T('-');
tylerwilson 0:3ab1d2d14eb3 626 } /* if */
tylerwilson 0:3ab1d2d14eb3 627
tylerwilson 0:3ab1d2d14eb3 628 /* "prepare" the value so that when it is truncated to the requested
tylerwilson 0:3ab1d2d14eb3 629 * number of digits, the result is rounded towards the dropped digits
tylerwilson 0:3ab1d2d14eb3 630 */
tylerwilson 0:3ab1d2d14eb3 631 assert(digits<INT_MAX);
tylerwilson 0:3ab1d2d14eb3 632 v=FIXEDMULT/2;
tylerwilson 0:3ab1d2d14eb3 633 for (i=0; i<digits; i++)
tylerwilson 0:3ab1d2d14eb3 634 v/=10;
tylerwilson 0:3ab1d2d14eb3 635 value+=v;
tylerwilson 0:3ab1d2d14eb3 636
tylerwilson 0:3ab1d2d14eb3 637 /* get the integer part and remove it from the value */
tylerwilson 0:3ab1d2d14eb3 638 ipart=value/FIXEDMULT;
tylerwilson 0:3ab1d2d14eb3 639 value-=FIXEDMULT*ipart;
tylerwilson 0:3ab1d2d14eb3 640 assert(ipart>=0);
tylerwilson 0:3ab1d2d14eb3 641 assert(value>=0);
tylerwilson 0:3ab1d2d14eb3 642
tylerwilson 0:3ab1d2d14eb3 643 /* truncate the fractional part to the requested number of digits */
tylerwilson 0:3ab1d2d14eb3 644 for (i=FIXEDDIGITS; i>digits; i--)
tylerwilson 0:3ab1d2d14eb3 645 value/=10;
tylerwilson 0:3ab1d2d14eb3 646
tylerwilson 0:3ab1d2d14eb3 647 string[0]=__T('\0');
tylerwilson 0:3ab1d2d14eb3 648
tylerwilson 0:3ab1d2d14eb3 649 /* add sign */
tylerwilson 0:3ab1d2d14eb3 650 i=_tcslen(string);
tylerwilson 0:3ab1d2d14eb3 651 string[i]=vsign;
tylerwilson 0:3ab1d2d14eb3 652 string[i+1]=__T('\0');
tylerwilson 0:3ab1d2d14eb3 653
tylerwilson 0:3ab1d2d14eb3 654 /* add integer part */
tylerwilson 0:3ab1d2d14eb3 655 amx_strval(string+_tcslen(string),(long)ipart,SV_DECIMAL,0);
tylerwilson 0:3ab1d2d14eb3 656
tylerwilson 0:3ab1d2d14eb3 657 /* add fractional part */
tylerwilson 0:3ab1d2d14eb3 658 if (digits>0) {
tylerwilson 0:3ab1d2d14eb3 659 i=_tcslen(string);
tylerwilson 0:3ab1d2d14eb3 660 string[i]=decpoint;
tylerwilson 0:3ab1d2d14eb3 661 amx_strval(string+i+1,(long)value,SV_DECIMAL,-digits);
tylerwilson 0:3ab1d2d14eb3 662 } /* if */
tylerwilson 0:3ab1d2d14eb3 663
tylerwilson 0:3ab1d2d14eb3 664 len=_tcslen(string);
tylerwilson 0:3ab1d2d14eb3 665 if (len<width) {
tylerwilson 0:3ab1d2d14eb3 666 /* pad to the requested width */
tylerwilson 0:3ab1d2d14eb3 667 for (i=len; i<width; i++)
tylerwilson 0:3ab1d2d14eb3 668 string[i]=filler;
tylerwilson 0:3ab1d2d14eb3 669 string[i]=__T('\0');
tylerwilson 0:3ab1d2d14eb3 670 /* optionally move the padding to the beginning of the string, using the handwaving algorithm */
tylerwilson 0:3ab1d2d14eb3 671 if (align!=__T('-')) {
tylerwilson 0:3ab1d2d14eb3 672 assert(i==(int)_tcslen(string));
tylerwilson 0:3ab1d2d14eb3 673 assert(i>=len);
tylerwilson 0:3ab1d2d14eb3 674 reverse(string,len);
tylerwilson 0:3ab1d2d14eb3 675 reverse(string+len,i-len);
tylerwilson 0:3ab1d2d14eb3 676 reverse(string,i);
tylerwilson 0:3ab1d2d14eb3 677 } /* if */
tylerwilson 0:3ab1d2d14eb3 678 } /* if */
tylerwilson 0:3ab1d2d14eb3 679
tylerwilson 0:3ab1d2d14eb3 680 return string;
tylerwilson 0:3ab1d2d14eb3 681 }
tylerwilson 0:3ab1d2d14eb3 682 #endif
tylerwilson 0:3ab1d2d14eb3 683
tylerwilson 0:3ab1d2d14eb3 684
tylerwilson 0:3ab1d2d14eb3 685 static int dochar(AMX *amx,TCHAR ch,cell param,TCHAR sign,TCHAR decpoint,int width,int digits,TCHAR filler,
tylerwilson 0:3ab1d2d14eb3 686 int (*f_putstr)(void*,const TCHAR *),int (*f_putchar)(void*,TCHAR),void *user)
tylerwilson 0:3ab1d2d14eb3 687 {
tylerwilson 0:3ab1d2d14eb3 688 cell *cptr;
tylerwilson 0:3ab1d2d14eb3 689 TCHAR buffer[40];
tylerwilson 0:3ab1d2d14eb3 690 #if defined FLOATPOINT
tylerwilson 0:3ab1d2d14eb3 691 TCHAR formatstring[40];
tylerwilson 0:3ab1d2d14eb3 692 #endif
tylerwilson 0:3ab1d2d14eb3 693
tylerwilson 0:3ab1d2d14eb3 694 #if !defined FIXEDPOINT && !defined FLOATPOINT
tylerwilson 0:3ab1d2d14eb3 695 (void)decpoint;
tylerwilson 0:3ab1d2d14eb3 696 #endif
tylerwilson 0:3ab1d2d14eb3 697 assert(f_putstr!=NULL);
tylerwilson 0:3ab1d2d14eb3 698 assert(f_putchar!=NULL);
tylerwilson 0:3ab1d2d14eb3 699
tylerwilson 0:3ab1d2d14eb3 700 switch (ch) {
tylerwilson 0:3ab1d2d14eb3 701 case __T('c'):
tylerwilson 0:3ab1d2d14eb3 702 cptr=amx_Address(amx,param);
tylerwilson 0:3ab1d2d14eb3 703 width--; /* single character itself has a with of 1 */
tylerwilson 0:3ab1d2d14eb3 704 if (sign!=__T('-'))
tylerwilson 0:3ab1d2d14eb3 705 while (width-->0)
tylerwilson 0:3ab1d2d14eb3 706 f_putchar(user,filler);
tylerwilson 0:3ab1d2d14eb3 707 f_putchar(user,(TCHAR)*cptr);
tylerwilson 0:3ab1d2d14eb3 708 while (width-->0)
tylerwilson 0:3ab1d2d14eb3 709 f_putchar(user,filler);
tylerwilson 0:3ab1d2d14eb3 710 return 1;
tylerwilson 0:3ab1d2d14eb3 711
tylerwilson 0:3ab1d2d14eb3 712 case __T('d'): {
tylerwilson 0:3ab1d2d14eb3 713 cell value;
tylerwilson 0:3ab1d2d14eb3 714 int length=1;
tylerwilson 0:3ab1d2d14eb3 715 cptr=amx_Address(amx,param);
tylerwilson 0:3ab1d2d14eb3 716 value=*cptr;
tylerwilson 0:3ab1d2d14eb3 717 if (value<0 || sign==__T('+'))
tylerwilson 0:3ab1d2d14eb3 718 length++;
tylerwilson 0:3ab1d2d14eb3 719 if (value<0)
tylerwilson 0:3ab1d2d14eb3 720 value=-value;
tylerwilson 0:3ab1d2d14eb3 721 while (value>=10) {
tylerwilson 0:3ab1d2d14eb3 722 length++;
tylerwilson 0:3ab1d2d14eb3 723 value/=10;
tylerwilson 0:3ab1d2d14eb3 724 } /* while */
tylerwilson 0:3ab1d2d14eb3 725 width-=length;
tylerwilson 0:3ab1d2d14eb3 726 if (sign!=__T('-'))
tylerwilson 0:3ab1d2d14eb3 727 while (width-->0)
tylerwilson 0:3ab1d2d14eb3 728 f_putchar(user,filler);
tylerwilson 0:3ab1d2d14eb3 729 amx_strval(buffer,*cptr,SV_DECIMAL,0);
tylerwilson 0:3ab1d2d14eb3 730 if (sign==__T('+') && *cptr>=0)
tylerwilson 0:3ab1d2d14eb3 731 f_putchar(user,sign);
tylerwilson 0:3ab1d2d14eb3 732 f_putstr(user,buffer);
tylerwilson 0:3ab1d2d14eb3 733 while (width-->0)
tylerwilson 0:3ab1d2d14eb3 734 f_putchar(user,filler);
tylerwilson 0:3ab1d2d14eb3 735 return 1;
tylerwilson 0:3ab1d2d14eb3 736 } /* case */
tylerwilson 0:3ab1d2d14eb3 737
tylerwilson 0:3ab1d2d14eb3 738 #if defined FLOATPOINT
tylerwilson 0:3ab1d2d14eb3 739 case __T('f'): /* 32-bit floating point number */
tylerwilson 0:3ab1d2d14eb3 740 case __T('r'): /* if floating point is enabled, %r == %f */
tylerwilson 0:3ab1d2d14eb3 741 /* build a format string */
tylerwilson 0:3ab1d2d14eb3 742 if (digits==INT_MAX)
tylerwilson 0:3ab1d2d14eb3 743 digits=5;
tylerwilson 0:3ab1d2d14eb3 744 else if (digits>25)
tylerwilson 0:3ab1d2d14eb3 745 digits=25;
tylerwilson 0:3ab1d2d14eb3 746 _tcscpy(formatstring,__T("%"));
tylerwilson 0:3ab1d2d14eb3 747 if (sign!=__T('\0'))
tylerwilson 0:3ab1d2d14eb3 748 _stprintf(formatstring+_tcslen(formatstring),__T("%c"),sign);
tylerwilson 0:3ab1d2d14eb3 749 if (width>0)
tylerwilson 0:3ab1d2d14eb3 750 _stprintf(formatstring+_tcslen(formatstring),__T("%d"),width);
tylerwilson 0:3ab1d2d14eb3 751 _stprintf(formatstring+_tcslen(formatstring),__T(".%df"),digits);
tylerwilson 0:3ab1d2d14eb3 752 cptr=amx_Address(amx,param);
tylerwilson 0:3ab1d2d14eb3 753 #if PAWN_CELL_SIZE == 64
tylerwilson 0:3ab1d2d14eb3 754 _stprintf(buffer,formatstring,*(double*)cptr);
tylerwilson 0:3ab1d2d14eb3 755 #else
tylerwilson 0:3ab1d2d14eb3 756 _stprintf(buffer,formatstring,*(float*)cptr);
tylerwilson 0:3ab1d2d14eb3 757 #endif
tylerwilson 0:3ab1d2d14eb3 758 if (decpoint==__T(',')) {
tylerwilson 0:3ab1d2d14eb3 759 TCHAR *ptr=_tcschr(buffer,__T('.'));
tylerwilson 0:3ab1d2d14eb3 760 if (ptr!=NULL)
tylerwilson 0:3ab1d2d14eb3 761 *ptr=__T(',');
tylerwilson 0:3ab1d2d14eb3 762 } /* if */
tylerwilson 0:3ab1d2d14eb3 763 f_putstr(user,buffer);
tylerwilson 0:3ab1d2d14eb3 764 return 1;
tylerwilson 0:3ab1d2d14eb3 765 #endif
tylerwilson 0:3ab1d2d14eb3 766
tylerwilson 0:3ab1d2d14eb3 767 #if defined FIXEDPOINT
tylerwilson 0:3ab1d2d14eb3 768 #define FIXEDMULT 1000
tylerwilson 0:3ab1d2d14eb3 769 case __T('q'): /* 32-bit fixed point number */
tylerwilson 0:3ab1d2d14eb3 770 #if !defined FLOATPOINT
tylerwilson 0:3ab1d2d14eb3 771 case __T('r'): /* if fixed point is enabled, and floating point is not, %r == %q */
tylerwilson 0:3ab1d2d14eb3 772 #endif
tylerwilson 0:3ab1d2d14eb3 773 cptr=amx_Address(amx,param);
tylerwilson 0:3ab1d2d14eb3 774 /* format the number */
tylerwilson 0:3ab1d2d14eb3 775 if (digits==INT_MAX)
tylerwilson 0:3ab1d2d14eb3 776 digits=3;
tylerwilson 0:3ab1d2d14eb3 777 else if (digits>25)
tylerwilson 0:3ab1d2d14eb3 778 digits=25;
tylerwilson 0:3ab1d2d14eb3 779 formatfixed(buffer,*cptr,sign,width,decpoint,digits,filler);
tylerwilson 0:3ab1d2d14eb3 780 assert(_tcslen(buffer)<sizeof buffer);
tylerwilson 0:3ab1d2d14eb3 781 f_putstr(user,buffer);
tylerwilson 0:3ab1d2d14eb3 782 return 1;
tylerwilson 0:3ab1d2d14eb3 783 #endif
tylerwilson 0:3ab1d2d14eb3 784
tylerwilson 0:3ab1d2d14eb3 785 #if !defined FLOATPOINT && !defined FIXEDPOINT
tylerwilson 0:3ab1d2d14eb3 786 case __T('f'):
tylerwilson 0:3ab1d2d14eb3 787 case __T('q'):
tylerwilson 0:3ab1d2d14eb3 788 case __T('r'):
tylerwilson 0:3ab1d2d14eb3 789 f_putstr(user,__T("(no rational number support)"));
tylerwilson 0:3ab1d2d14eb3 790 return 0; /* flag this as an error */
tylerwilson 0:3ab1d2d14eb3 791 #endif
tylerwilson 0:3ab1d2d14eb3 792
tylerwilson 0:3ab1d2d14eb3 793 case __T('s'): {
tylerwilson 0:3ab1d2d14eb3 794 AMX_FMTINFO info;
tylerwilson 0:3ab1d2d14eb3 795 memset(&info,0,sizeof info);
tylerwilson 0:3ab1d2d14eb3 796 info.length=digits;
tylerwilson 0:3ab1d2d14eb3 797 info.f_putstr=f_putstr;
tylerwilson 0:3ab1d2d14eb3 798 info.f_putchar=f_putchar;
tylerwilson 0:3ab1d2d14eb3 799 info.user=user;
tylerwilson 0:3ab1d2d14eb3 800 cptr=amx_Address(amx,param);
tylerwilson 0:3ab1d2d14eb3 801 amx_printstring(amx,cptr,&info);
tylerwilson 0:3ab1d2d14eb3 802 return 1;
tylerwilson 0:3ab1d2d14eb3 803 } /* case */
tylerwilson 0:3ab1d2d14eb3 804
tylerwilson 0:3ab1d2d14eb3 805 case __T('x'): {
tylerwilson 0:3ab1d2d14eb3 806 ucell value;
tylerwilson 0:3ab1d2d14eb3 807 int length=1;
tylerwilson 0:3ab1d2d14eb3 808 cptr=amx_Address(amx,param);
tylerwilson 0:3ab1d2d14eb3 809 value=*(ucell*)cptr;
tylerwilson 0:3ab1d2d14eb3 810 while (value>=0x10) {
tylerwilson 0:3ab1d2d14eb3 811 length++;
tylerwilson 0:3ab1d2d14eb3 812 value>>=4;
tylerwilson 0:3ab1d2d14eb3 813 } /* while */
tylerwilson 0:3ab1d2d14eb3 814 width-=length;
tylerwilson 0:3ab1d2d14eb3 815 if (sign!=__T('-'))
tylerwilson 0:3ab1d2d14eb3 816 while (width-->0)
tylerwilson 0:3ab1d2d14eb3 817 f_putchar(user,filler);
tylerwilson 0:3ab1d2d14eb3 818 amx_strval(buffer,(long)*cptr,SV_HEX,0);
tylerwilson 0:3ab1d2d14eb3 819 f_putstr(user,buffer);
tylerwilson 0:3ab1d2d14eb3 820 while (width-->0)
tylerwilson 0:3ab1d2d14eb3 821 f_putchar(user,filler);
tylerwilson 0:3ab1d2d14eb3 822 return 1;
tylerwilson 0:3ab1d2d14eb3 823 } /* case */
tylerwilson 0:3ab1d2d14eb3 824
tylerwilson 0:3ab1d2d14eb3 825 } /* switch */
tylerwilson 0:3ab1d2d14eb3 826 /* error in the string format, try to repair */
tylerwilson 0:3ab1d2d14eb3 827 f_putchar(user,ch);
tylerwilson 0:3ab1d2d14eb3 828 return 0;
tylerwilson 0:3ab1d2d14eb3 829 }
tylerwilson 0:3ab1d2d14eb3 830
tylerwilson 0:3ab1d2d14eb3 831 enum {
tylerwilson 0:3ab1d2d14eb3 832 FMT_NONE, /* not in format state; accept '%' */
tylerwilson 0:3ab1d2d14eb3 833 FMT_START, /* found '%', accept '+', '-' (START), '0' (filler; START), digit (WIDTH), '.' (DECIM), or '%' or format letter (done) */
tylerwilson 0:3ab1d2d14eb3 834 FMT_WIDTH, /* found digit after '%' or sign, accept digit (WIDTH), '.' (DECIM) or format letter (done) */
tylerwilson 0:3ab1d2d14eb3 835 FMT_DECIM, /* found digit after '.', accept accept digit (DECIM) or format letter (done) */
tylerwilson 0:3ab1d2d14eb3 836 };
tylerwilson 0:3ab1d2d14eb3 837
tylerwilson 0:3ab1d2d14eb3 838 static int formatstate(TCHAR c,int *state,TCHAR *sign,TCHAR *decpoint,int *width,int *digits,TCHAR *filler)
tylerwilson 0:3ab1d2d14eb3 839 {
tylerwilson 0:3ab1d2d14eb3 840 assert(state!=NULL && sign!=NULL && decpoint!=NULL && width!=NULL && digits!=NULL && filler!=NULL);
tylerwilson 0:3ab1d2d14eb3 841 switch (*state) {
tylerwilson 0:3ab1d2d14eb3 842 case FMT_NONE:
tylerwilson 0:3ab1d2d14eb3 843 if (c==__T('%')) {
tylerwilson 0:3ab1d2d14eb3 844 *state=FMT_START;
tylerwilson 0:3ab1d2d14eb3 845 *sign=__T('\0');
tylerwilson 0:3ab1d2d14eb3 846 *decpoint=__T('.');
tylerwilson 0:3ab1d2d14eb3 847 *width=0;
tylerwilson 0:3ab1d2d14eb3 848 *digits=INT_MAX;
tylerwilson 0:3ab1d2d14eb3 849 *filler=__T(' ');
tylerwilson 0:3ab1d2d14eb3 850 } else {
tylerwilson 0:3ab1d2d14eb3 851 return -1; /* print a single character */
tylerwilson 0:3ab1d2d14eb3 852 } /* if */
tylerwilson 0:3ab1d2d14eb3 853 break;
tylerwilson 0:3ab1d2d14eb3 854 case FMT_START:
tylerwilson 0:3ab1d2d14eb3 855 if (c==__T('+') || c==__T('-')) {
tylerwilson 0:3ab1d2d14eb3 856 *sign=c;
tylerwilson 0:3ab1d2d14eb3 857 } else if (c==__T('0')) {
tylerwilson 0:3ab1d2d14eb3 858 *filler=c;
tylerwilson 0:3ab1d2d14eb3 859 } else if (c>=__T('1') && c<=__T('9')) {
tylerwilson 0:3ab1d2d14eb3 860 *width=(int)(c-__T('0'));
tylerwilson 0:3ab1d2d14eb3 861 *state=FMT_WIDTH;
tylerwilson 0:3ab1d2d14eb3 862 } else if (c==__T('.') || c==__T(',')) {
tylerwilson 0:3ab1d2d14eb3 863 *decpoint=c;
tylerwilson 0:3ab1d2d14eb3 864 *digits=0;
tylerwilson 0:3ab1d2d14eb3 865 *state=FMT_DECIM;
tylerwilson 0:3ab1d2d14eb3 866 } else if (c==__T('%')) {
tylerwilson 0:3ab1d2d14eb3 867 *state=FMT_NONE;
tylerwilson 0:3ab1d2d14eb3 868 return -1; /* print literal '%' */
tylerwilson 0:3ab1d2d14eb3 869 } else {
tylerwilson 0:3ab1d2d14eb3 870 return 1; /* print formatted character */
tylerwilson 0:3ab1d2d14eb3 871 } /* if */
tylerwilson 0:3ab1d2d14eb3 872 break;
tylerwilson 0:3ab1d2d14eb3 873 case FMT_WIDTH:
tylerwilson 0:3ab1d2d14eb3 874 if (c>=__T('0') && c<=__T('9')) {
tylerwilson 0:3ab1d2d14eb3 875 *width=*width*10+(int)(c-__T('0'));
tylerwilson 0:3ab1d2d14eb3 876 } else if (c==__T('.') || c==__T(',')) {
tylerwilson 0:3ab1d2d14eb3 877 *decpoint=c;
tylerwilson 0:3ab1d2d14eb3 878 *digits=0;
tylerwilson 0:3ab1d2d14eb3 879 *state=FMT_DECIM;
tylerwilson 0:3ab1d2d14eb3 880 } else {
tylerwilson 0:3ab1d2d14eb3 881 return 1; /* print formatted character */
tylerwilson 0:3ab1d2d14eb3 882 } /* if */
tylerwilson 0:3ab1d2d14eb3 883 break;
tylerwilson 0:3ab1d2d14eb3 884 case FMT_DECIM:
tylerwilson 0:3ab1d2d14eb3 885 if (c>=__T('0') && c<=__T('9')) {
tylerwilson 0:3ab1d2d14eb3 886 *digits=*digits*10+(int)(c-__T('0'));
tylerwilson 0:3ab1d2d14eb3 887 } else {
tylerwilson 0:3ab1d2d14eb3 888 return 1; /* print formatted character */
tylerwilson 0:3ab1d2d14eb3 889 } /* if */
tylerwilson 0:3ab1d2d14eb3 890 break;
tylerwilson 0:3ab1d2d14eb3 891 } /* switch */
tylerwilson 0:3ab1d2d14eb3 892
tylerwilson 0:3ab1d2d14eb3 893 return 0;
tylerwilson 0:3ab1d2d14eb3 894 }
tylerwilson 0:3ab1d2d14eb3 895
tylerwilson 0:3ab1d2d14eb3 896 int amx_printstring(AMX *amx,cell *cstr,AMX_FMTINFO *info)
tylerwilson 0:3ab1d2d14eb3 897 {
tylerwilson 0:3ab1d2d14eb3 898 int i,paramidx=0;
tylerwilson 0:3ab1d2d14eb3 899 int fmtstate=FMT_NONE,width,digits;
tylerwilson 0:3ab1d2d14eb3 900 TCHAR sign,decpoint,filler;
tylerwilson 0:3ab1d2d14eb3 901 int (*f_putstr)(void*,const TCHAR *);
tylerwilson 0:3ab1d2d14eb3 902 int (*f_putchar)(void*,TCHAR);
tylerwilson 0:3ab1d2d14eb3 903 void *user;
tylerwilson 0:3ab1d2d14eb3 904 int skip,length;
tylerwilson 0:3ab1d2d14eb3 905
tylerwilson 0:3ab1d2d14eb3 906 if (info!=NULL) {
tylerwilson 0:3ab1d2d14eb3 907 f_putstr=info->f_putstr;
tylerwilson 0:3ab1d2d14eb3 908 f_putchar=info->f_putchar;
tylerwilson 0:3ab1d2d14eb3 909 user=info->user;
tylerwilson 0:3ab1d2d14eb3 910 skip=info->skip;
tylerwilson 0:3ab1d2d14eb3 911 length=info->length;
tylerwilson 0:3ab1d2d14eb3 912 } else {
tylerwilson 0:3ab1d2d14eb3 913 f_putstr=NULL;
tylerwilson 0:3ab1d2d14eb3 914 f_putchar=NULL;
tylerwilson 0:3ab1d2d14eb3 915 user=NULL;
tylerwilson 0:3ab1d2d14eb3 916 skip=0;
tylerwilson 0:3ab1d2d14eb3 917 length=INT_MAX;
tylerwilson 0:3ab1d2d14eb3 918 } /* if */
tylerwilson 0:3ab1d2d14eb3 919 #if !defined AMX_STRING_LIB
tylerwilson 0:3ab1d2d14eb3 920 if (f_putstr==NULL)
tylerwilson 0:3ab1d2d14eb3 921 f_putstr=cons_putstr;
tylerwilson 0:3ab1d2d14eb3 922 if (f_putchar==NULL)
tylerwilson 0:3ab1d2d14eb3 923 f_putchar=cons_putchar;
tylerwilson 0:3ab1d2d14eb3 924 #else
tylerwilson 0:3ab1d2d14eb3 925 assert(f_putstr!=NULL && f_putchar!=NULL);
tylerwilson 0:3ab1d2d14eb3 926 #endif
tylerwilson 0:3ab1d2d14eb3 927
tylerwilson 0:3ab1d2d14eb3 928 /* if no placeholders appear, we can use a quicker routine */
tylerwilson 0:3ab1d2d14eb3 929 if (info==NULL || info->params==NULL) {
tylerwilson 0:3ab1d2d14eb3 930
tylerwilson 0:3ab1d2d14eb3 931 TCHAR cache[100];
tylerwilson 0:3ab1d2d14eb3 932 int idx=0;
tylerwilson 0:3ab1d2d14eb3 933
tylerwilson 0:3ab1d2d14eb3 934 if ((ucell)*cstr>UNPACKEDMAX) {
tylerwilson 0:3ab1d2d14eb3 935 int j=sizeof(cell)-sizeof(char);
tylerwilson 0:3ab1d2d14eb3 936 char c;
tylerwilson 0:3ab1d2d14eb3 937 /* the string is packed */
tylerwilson 0:3ab1d2d14eb3 938 i=0;
tylerwilson 0:3ab1d2d14eb3 939 for ( ; ; ) {
tylerwilson 0:3ab1d2d14eb3 940 c=(char)((ucell)cstr[i] >> 8*j);
tylerwilson 0:3ab1d2d14eb3 941 if (c==0)
tylerwilson 0:3ab1d2d14eb3 942 break;
tylerwilson 0:3ab1d2d14eb3 943 if (skip>0) {
tylerwilson 0:3ab1d2d14eb3 944 skip--; /* skip a number of characters */
tylerwilson 0:3ab1d2d14eb3 945 } else {
tylerwilson 0:3ab1d2d14eb3 946 if (length--<=0)
tylerwilson 0:3ab1d2d14eb3 947 break; /* print up to a certain length */
tylerwilson 0:3ab1d2d14eb3 948 assert(idx<sizeof cache);
tylerwilson 0:3ab1d2d14eb3 949 cache[idx++]=c;
tylerwilson 0:3ab1d2d14eb3 950 if (idx==sizeof cache - 1) {
tylerwilson 0:3ab1d2d14eb3 951 cache[idx]=__T('\0');
tylerwilson 0:3ab1d2d14eb3 952 f_putstr(user,cache);
tylerwilson 0:3ab1d2d14eb3 953 idx=0;
tylerwilson 0:3ab1d2d14eb3 954 } /* if */
tylerwilson 0:3ab1d2d14eb3 955 } /* if */
tylerwilson 0:3ab1d2d14eb3 956 if (j==0)
tylerwilson 0:3ab1d2d14eb3 957 i++;
tylerwilson 0:3ab1d2d14eb3 958 j=(j+sizeof(cell)-sizeof(char)) % sizeof(cell);
tylerwilson 0:3ab1d2d14eb3 959 } /* for */
tylerwilson 0:3ab1d2d14eb3 960 } else {
tylerwilson 0:3ab1d2d14eb3 961 /* unpacked string */
tylerwilson 0:3ab1d2d14eb3 962 for (i=0; cstr[i]!=0; i++) {
tylerwilson 0:3ab1d2d14eb3 963 if (skip-->0)
tylerwilson 0:3ab1d2d14eb3 964 continue;
tylerwilson 0:3ab1d2d14eb3 965 assert(idx<sizeof cache);
tylerwilson 0:3ab1d2d14eb3 966 cache[idx++]=(TCHAR)cstr[i];
tylerwilson 0:3ab1d2d14eb3 967 if (idx==sizeof cache - 1) {
tylerwilson 0:3ab1d2d14eb3 968 cache[idx]=__T('\0');
tylerwilson 0:3ab1d2d14eb3 969 f_putstr(user,cache);
tylerwilson 0:3ab1d2d14eb3 970 idx=0;
tylerwilson 0:3ab1d2d14eb3 971 } /* if */
tylerwilson 0:3ab1d2d14eb3 972 } /* for */
tylerwilson 0:3ab1d2d14eb3 973 } /* if */
tylerwilson 0:3ab1d2d14eb3 974 if (idx>0) {
tylerwilson 0:3ab1d2d14eb3 975 cache[idx]=__T('\0');
tylerwilson 0:3ab1d2d14eb3 976 f_putstr(user,cache);
tylerwilson 0:3ab1d2d14eb3 977 } /* if */
tylerwilson 0:3ab1d2d14eb3 978
tylerwilson 0:3ab1d2d14eb3 979 } else {
tylerwilson 0:3ab1d2d14eb3 980
tylerwilson 0:3ab1d2d14eb3 981 /* check whether this is a packed string */
tylerwilson 0:3ab1d2d14eb3 982 if ((ucell)*cstr>UNPACKEDMAX) {
tylerwilson 0:3ab1d2d14eb3 983 int j=sizeof(cell)-sizeof(char);
tylerwilson 0:3ab1d2d14eb3 984 char c;
tylerwilson 0:3ab1d2d14eb3 985 /* the string is packed */
tylerwilson 0:3ab1d2d14eb3 986 i=0;
tylerwilson 0:3ab1d2d14eb3 987 for ( ; ; ) {
tylerwilson 0:3ab1d2d14eb3 988 c=(char)((ucell)cstr[i] >> 8*j);
tylerwilson 0:3ab1d2d14eb3 989 if (c==0)
tylerwilson 0:3ab1d2d14eb3 990 break;
tylerwilson 0:3ab1d2d14eb3 991 switch (formatstate(c,&fmtstate,&sign,&decpoint,&width,&digits,&filler)) {
tylerwilson 0:3ab1d2d14eb3 992 case -1:
tylerwilson 0:3ab1d2d14eb3 993 f_putchar(user,c);
tylerwilson 0:3ab1d2d14eb3 994 break;
tylerwilson 0:3ab1d2d14eb3 995 case 0:
tylerwilson 0:3ab1d2d14eb3 996 break;
tylerwilson 0:3ab1d2d14eb3 997 case 1:
tylerwilson 0:3ab1d2d14eb3 998 assert(info!=NULL && info->params!=NULL);
tylerwilson 0:3ab1d2d14eb3 999 if (paramidx>=info->numparams) /* insufficient parameters passed */
tylerwilson 0:3ab1d2d14eb3 1000 amx_RaiseError(amx, AMX_ERR_NATIVE);
tylerwilson 0:3ab1d2d14eb3 1001 else
tylerwilson 0:3ab1d2d14eb3 1002 paramidx+=dochar(amx,c,info->params[paramidx],sign,decpoint,width,digits,filler,
tylerwilson 0:3ab1d2d14eb3 1003 f_putstr,f_putchar,user);
tylerwilson 0:3ab1d2d14eb3 1004 fmtstate=FMT_NONE;
tylerwilson 0:3ab1d2d14eb3 1005 break;
tylerwilson 0:3ab1d2d14eb3 1006 default:
tylerwilson 0:3ab1d2d14eb3 1007 assert(0);
tylerwilson 0:3ab1d2d14eb3 1008 } /* switch */
tylerwilson 0:3ab1d2d14eb3 1009 if (j==0)
tylerwilson 0:3ab1d2d14eb3 1010 i++;
tylerwilson 0:3ab1d2d14eb3 1011 j=(j+sizeof(cell)-sizeof(char)) % sizeof(cell);
tylerwilson 0:3ab1d2d14eb3 1012 } /* for */
tylerwilson 0:3ab1d2d14eb3 1013 } else {
tylerwilson 0:3ab1d2d14eb3 1014 /* the string is unpacked */
tylerwilson 0:3ab1d2d14eb3 1015 for (i=0; cstr[i]!=0; i++) {
tylerwilson 0:3ab1d2d14eb3 1016 switch (formatstate((TCHAR)cstr[i],&fmtstate,&sign,&decpoint,&width,&digits,&filler)) {
tylerwilson 0:3ab1d2d14eb3 1017 case -1:
tylerwilson 0:3ab1d2d14eb3 1018 f_putchar(user,(TCHAR)cstr[i]);
tylerwilson 0:3ab1d2d14eb3 1019 break;
tylerwilson 0:3ab1d2d14eb3 1020 case 0:
tylerwilson 0:3ab1d2d14eb3 1021 break;
tylerwilson 0:3ab1d2d14eb3 1022 case 1:
tylerwilson 0:3ab1d2d14eb3 1023 assert(info!=NULL && info->params!=NULL);
tylerwilson 0:3ab1d2d14eb3 1024 if (paramidx>=info->numparams) /* insufficient parameters passed */
tylerwilson 0:3ab1d2d14eb3 1025 amx_RaiseError(amx, AMX_ERR_NATIVE);
tylerwilson 0:3ab1d2d14eb3 1026 else
tylerwilson 0:3ab1d2d14eb3 1027 paramidx+=dochar(amx,(TCHAR)cstr[i],info->params[paramidx],sign,decpoint,width,digits,filler,
tylerwilson 0:3ab1d2d14eb3 1028 f_putstr,f_putchar,user);
tylerwilson 0:3ab1d2d14eb3 1029 fmtstate=FMT_NONE;
tylerwilson 0:3ab1d2d14eb3 1030 break;
tylerwilson 0:3ab1d2d14eb3 1031 default:
tylerwilson 0:3ab1d2d14eb3 1032 assert(0);
tylerwilson 0:3ab1d2d14eb3 1033 } /* switch */
tylerwilson 0:3ab1d2d14eb3 1034 } /* for */
tylerwilson 0:3ab1d2d14eb3 1035 } /* if */
tylerwilson 0:3ab1d2d14eb3 1036
tylerwilson 0:3ab1d2d14eb3 1037 } /* if (info==NULL || info->params==NULL) */
tylerwilson 0:3ab1d2d14eb3 1038
tylerwilson 0:3ab1d2d14eb3 1039 return paramidx;
tylerwilson 0:3ab1d2d14eb3 1040 }
tylerwilson 0:3ab1d2d14eb3 1041
tylerwilson 0:3ab1d2d14eb3 1042 #if !defined AMX_STRING_LIB
tylerwilson 0:3ab1d2d14eb3 1043
tylerwilson 0:3ab1d2d14eb3 1044 #if defined AMX_ALTPRINT
tylerwilson 0:3ab1d2d14eb3 1045 /* print(const string[], start=0, end=cellmax) */
tylerwilson 0:3ab1d2d14eb3 1046 static cell AMX_NATIVE_CALL n_print(AMX *amx,const cell *params)
tylerwilson 0:3ab1d2d14eb3 1047 {
tylerwilson 0:3ab1d2d14eb3 1048 cell *cstr;
tylerwilson 0:3ab1d2d14eb3 1049 AMX_FMTINFO info;
tylerwilson 0:3ab1d2d14eb3 1050
tylerwilson 0:3ab1d2d14eb3 1051 memset(&info,0,sizeof info);
tylerwilson 0:3ab1d2d14eb3 1052 info.skip= ((size_t)params[0]>=2*sizeof(cell)) ? (int)params[2] : 0;
tylerwilson 0:3ab1d2d14eb3 1053 info.length= ((size_t)params[0]>=3*sizeof(cell)) ? (int)(params[3]-info.skip) : INT_MAX;
tylerwilson 0:3ab1d2d14eb3 1054
tylerwilson 0:3ab1d2d14eb3 1055 CreateConsole();
tylerwilson 0:3ab1d2d14eb3 1056 cstr=amx_Address(amx,params[1]);
tylerwilson 0:3ab1d2d14eb3 1057 amx_printstring(amx,cstr,&info);
tylerwilson 0:3ab1d2d14eb3 1058 amx_fflush();
tylerwilson 0:3ab1d2d14eb3 1059 return 0;
tylerwilson 0:3ab1d2d14eb3 1060 }
tylerwilson 0:3ab1d2d14eb3 1061 #else
tylerwilson 0:3ab1d2d14eb3 1062 /* print(const string[], foreground=-1, background=-1, highlight=-1) */
tylerwilson 0:3ab1d2d14eb3 1063 static cell AMX_NATIVE_CALL n_print(AMX *amx,const cell *params)
tylerwilson 0:3ab1d2d14eb3 1064 {
tylerwilson 0:3ab1d2d14eb3 1065 cell *cstr;
tylerwilson 0:3ab1d2d14eb3 1066 int oldcolours;
tylerwilson 0:3ab1d2d14eb3 1067
tylerwilson 0:3ab1d2d14eb3 1068 CreateConsole();
tylerwilson 0:3ab1d2d14eb3 1069
tylerwilson 0:3ab1d2d14eb3 1070 /* set the new colours */
tylerwilson 0:3ab1d2d14eb3 1071 oldcolours=amx_setattr((int)params[2],(int)params[3],(int)params[4]);
tylerwilson 0:3ab1d2d14eb3 1072
tylerwilson 0:3ab1d2d14eb3 1073 cstr=amx_Address(amx,params[1]);
tylerwilson 0:3ab1d2d14eb3 1074 amx_printstring(amx,cstr,NULL);
tylerwilson 0:3ab1d2d14eb3 1075
tylerwilson 0:3ab1d2d14eb3 1076 /* reset the colours */
tylerwilson 0:3ab1d2d14eb3 1077 (void)amx_setattr(oldcolours & 0xff,(oldcolours >> 8) & 0x7f,(oldcolours >> 15) & 0x01);
tylerwilson 0:3ab1d2d14eb3 1078 amx_fflush();
tylerwilson 0:3ab1d2d14eb3 1079 return 0;
tylerwilson 0:3ab1d2d14eb3 1080 }
tylerwilson 0:3ab1d2d14eb3 1081 #endif
tylerwilson 0:3ab1d2d14eb3 1082
tylerwilson 0:3ab1d2d14eb3 1083 static cell AMX_NATIVE_CALL n_printf(AMX *amx,const cell *params)
tylerwilson 0:3ab1d2d14eb3 1084 {
tylerwilson 0:3ab1d2d14eb3 1085 cell *cstr;
tylerwilson 0:3ab1d2d14eb3 1086 AMX_FMTINFO info;
tylerwilson 0:3ab1d2d14eb3 1087
tylerwilson 0:3ab1d2d14eb3 1088 memset(&info,0,sizeof info);
tylerwilson 0:3ab1d2d14eb3 1089 info.params=params+2;
tylerwilson 0:3ab1d2d14eb3 1090 info.numparams=(int)(params[0]/sizeof(cell))-1;
tylerwilson 0:3ab1d2d14eb3 1091 info.skip=0;
tylerwilson 0:3ab1d2d14eb3 1092 info.length=INT_MAX;
tylerwilson 0:3ab1d2d14eb3 1093
tylerwilson 0:3ab1d2d14eb3 1094 CreateConsole();
tylerwilson 0:3ab1d2d14eb3 1095 cstr=amx_Address(amx,params[1]);
tylerwilson 0:3ab1d2d14eb3 1096 amx_printstring(amx,cstr,&info);
tylerwilson 0:3ab1d2d14eb3 1097 amx_fflush();
tylerwilson 0:3ab1d2d14eb3 1098 return 0;
tylerwilson 0:3ab1d2d14eb3 1099 }
tylerwilson 0:3ab1d2d14eb3 1100
tylerwilson 0:3ab1d2d14eb3 1101 /* getchar(bool:echo=true) */
tylerwilson 0:3ab1d2d14eb3 1102 static cell AMX_NATIVE_CALL n_getchar(AMX *amx,const cell *params)
tylerwilson 0:3ab1d2d14eb3 1103 {
tylerwilson 0:3ab1d2d14eb3 1104 int c;
tylerwilson 0:3ab1d2d14eb3 1105
tylerwilson 0:3ab1d2d14eb3 1106 (void)amx;
tylerwilson 0:3ab1d2d14eb3 1107 CreateConsole();
tylerwilson 0:3ab1d2d14eb3 1108 c=amx_getch();
tylerwilson 0:3ab1d2d14eb3 1109 if (params[1]) {
tylerwilson 0:3ab1d2d14eb3 1110 #if defined(SUPPRESS_ECHO)
tylerwilson 0:3ab1d2d14eb3 1111 /* For Mac OS X, non-Curses, don't echo the character */
tylerwilson 0:3ab1d2d14eb3 1112 #else
tylerwilson 0:3ab1d2d14eb3 1113 amx_putchar((TCHAR)c);
tylerwilson 0:3ab1d2d14eb3 1114 amx_fflush();
tylerwilson 0:3ab1d2d14eb3 1115 #endif
tylerwilson 0:3ab1d2d14eb3 1116 } /* if */
tylerwilson 0:3ab1d2d14eb3 1117 return c;
tylerwilson 0:3ab1d2d14eb3 1118 }
tylerwilson 0:3ab1d2d14eb3 1119
tylerwilson 0:3ab1d2d14eb3 1120 /* getstring(string[], size=sizeof string, bool:pack=false) */
tylerwilson 0:3ab1d2d14eb3 1121 static cell AMX_NATIVE_CALL n_getstring(AMX *amx,const cell *params)
tylerwilson 0:3ab1d2d14eb3 1122 {
tylerwilson 0:3ab1d2d14eb3 1123 int c,chars,max;
tylerwilson 0:3ab1d2d14eb3 1124 cell *cptr;
tylerwilson 0:3ab1d2d14eb3 1125
tylerwilson 0:3ab1d2d14eb3 1126 (void)amx;
tylerwilson 0:3ab1d2d14eb3 1127 CreateConsole();
tylerwilson 0:3ab1d2d14eb3 1128 chars=0;
tylerwilson 0:3ab1d2d14eb3 1129 max=(int)params[2];
tylerwilson 0:3ab1d2d14eb3 1130 if (max>0) {
tylerwilson 0:3ab1d2d14eb3 1131 #if __STDC_VERSION__ >= 199901L
tylerwilson 0:3ab1d2d14eb3 1132 TCHAR str[max]; /* use C99 feature if available */
tylerwilson 0:3ab1d2d14eb3 1133 #else
tylerwilson 0:3ab1d2d14eb3 1134 TCHAR *str=(TCHAR *)alloca(max*sizeof(TCHAR));
tylerwilson 0:3ab1d2d14eb3 1135 if (str==NULL)
tylerwilson 0:3ab1d2d14eb3 1136 return chars;
tylerwilson 0:3ab1d2d14eb3 1137 #endif
tylerwilson 0:3ab1d2d14eb3 1138
tylerwilson 0:3ab1d2d14eb3 1139 c=amx_getch();
tylerwilson 0:3ab1d2d14eb3 1140 while (c!=EOF && c!=EOL_CHAR && chars<max-1) {
tylerwilson 0:3ab1d2d14eb3 1141 str[chars++]=(TCHAR)c;
tylerwilson 0:3ab1d2d14eb3 1142 #if defined(SUPPRESS_ECHO)
tylerwilson 0:3ab1d2d14eb3 1143 /* For Mac OS X, non-Curses, don't echo the character */
tylerwilson 0:3ab1d2d14eb3 1144 #else
tylerwilson 0:3ab1d2d14eb3 1145 amx_putchar((TCHAR)c);
tylerwilson 0:3ab1d2d14eb3 1146 amx_fflush();
tylerwilson 0:3ab1d2d14eb3 1147 #endif
tylerwilson 0:3ab1d2d14eb3 1148 if (chars<max-1)
tylerwilson 0:3ab1d2d14eb3 1149 c=amx_getch();
tylerwilson 0:3ab1d2d14eb3 1150 } /* while */
tylerwilson 0:3ab1d2d14eb3 1151
tylerwilson 0:3ab1d2d14eb3 1152 if (c==EOL_CHAR)
tylerwilson 0:3ab1d2d14eb3 1153 amx_putchar('\n');
tylerwilson 0:3ab1d2d14eb3 1154 assert(chars<max);
tylerwilson 0:3ab1d2d14eb3 1155 str[chars]='\0';
tylerwilson 0:3ab1d2d14eb3 1156
tylerwilson 0:3ab1d2d14eb3 1157 cptr=amx_Address(amx,params[1]);
tylerwilson 0:3ab1d2d14eb3 1158 amx_SetString(cptr,(char*)str,(int)params[3],sizeof(TCHAR)>1,max);
tylerwilson 0:3ab1d2d14eb3 1159
tylerwilson 0:3ab1d2d14eb3 1160 } /* if */
tylerwilson 0:3ab1d2d14eb3 1161 return chars;
tylerwilson 0:3ab1d2d14eb3 1162 }
tylerwilson 0:3ab1d2d14eb3 1163
tylerwilson 0:3ab1d2d14eb3 1164 static void acceptchar(int c,int *num)
tylerwilson 0:3ab1d2d14eb3 1165 {
tylerwilson 0:3ab1d2d14eb3 1166 switch (c) {
tylerwilson 0:3ab1d2d14eb3 1167 case '\b':
tylerwilson 0:3ab1d2d14eb3 1168 amx_putchar('\b');
tylerwilson 0:3ab1d2d14eb3 1169 *num-=1;
tylerwilson 0:3ab1d2d14eb3 1170 #if defined amx_putchar && (defined __BORLANDC__ || defined __WATCOMC__)
tylerwilson 0:3ab1d2d14eb3 1171 /* the backspace key does not erase the
tylerwilson 0:3ab1d2d14eb3 1172 * character, so do this explicitly */
tylerwilson 0:3ab1d2d14eb3 1173 amx_putchar(' '); /* erase */
tylerwilson 0:3ab1d2d14eb3 1174 amx_putchar('\b'); /* go back */
tylerwilson 0:3ab1d2d14eb3 1175 #endif
tylerwilson 0:3ab1d2d14eb3 1176 break;
tylerwilson 0:3ab1d2d14eb3 1177 case EOL_CHAR:
tylerwilson 0:3ab1d2d14eb3 1178 amx_putchar('\n');
tylerwilson 0:3ab1d2d14eb3 1179 *num+=1;
tylerwilson 0:3ab1d2d14eb3 1180 break;
tylerwilson 0:3ab1d2d14eb3 1181 default:
tylerwilson 0:3ab1d2d14eb3 1182 #if defined(SUPPRESS_ECHO)
tylerwilson 0:3ab1d2d14eb3 1183 /* For Mac OS X, non-Curses, don't echo the character */
tylerwilson 0:3ab1d2d14eb3 1184 #else
tylerwilson 0:3ab1d2d14eb3 1185 amx_putchar((TCHAR)c);
tylerwilson 0:3ab1d2d14eb3 1186 #endif
tylerwilson 0:3ab1d2d14eb3 1187 *num+=1;
tylerwilson 0:3ab1d2d14eb3 1188 } /* switch */
tylerwilson 0:3ab1d2d14eb3 1189 amx_fflush();
tylerwilson 0:3ab1d2d14eb3 1190 }
tylerwilson 0:3ab1d2d14eb3 1191
tylerwilson 0:3ab1d2d14eb3 1192 static int inlist(AMX *amx,int c,const cell *params,int num)
tylerwilson 0:3ab1d2d14eb3 1193 {
tylerwilson 0:3ab1d2d14eb3 1194 int i, key;
tylerwilson 0:3ab1d2d14eb3 1195
tylerwilson 0:3ab1d2d14eb3 1196 (void)amx;
tylerwilson 0:3ab1d2d14eb3 1197 for (i=0; i<num; i++) {
tylerwilson 0:3ab1d2d14eb3 1198 if (i==0) {
tylerwilson 0:3ab1d2d14eb3 1199 /* first key is passed by value, others are passed by reference */
tylerwilson 0:3ab1d2d14eb3 1200 key = (int)params[i];
tylerwilson 0:3ab1d2d14eb3 1201 } else {
tylerwilson 0:3ab1d2d14eb3 1202 cell *cptr;
tylerwilson 0:3ab1d2d14eb3 1203 cptr=amx_Address(amx,params[i]);
tylerwilson 0:3ab1d2d14eb3 1204 key=(int)*cptr;
tylerwilson 0:3ab1d2d14eb3 1205 } /* if */
tylerwilson 0:3ab1d2d14eb3 1206 if (c==key || c==-key)
tylerwilson 0:3ab1d2d14eb3 1207 return key;
tylerwilson 0:3ab1d2d14eb3 1208 } /* for */
tylerwilson 0:3ab1d2d14eb3 1209 return 0;
tylerwilson 0:3ab1d2d14eb3 1210 }
tylerwilson 0:3ab1d2d14eb3 1211
tylerwilson 0:3ab1d2d14eb3 1212 static cell AMX_NATIVE_CALL n_getvalue(AMX *amx,const cell *params)
tylerwilson 0:3ab1d2d14eb3 1213 {
tylerwilson 0:3ab1d2d14eb3 1214 cell value;
tylerwilson 0:3ab1d2d14eb3 1215 int base,sign,c,d;
tylerwilson 0:3ab1d2d14eb3 1216 int chars,n;
tylerwilson 0:3ab1d2d14eb3 1217
tylerwilson 0:3ab1d2d14eb3 1218 CreateConsole();
tylerwilson 0:3ab1d2d14eb3 1219 base=(int)params[1];
tylerwilson 0:3ab1d2d14eb3 1220 if (base<2 || base>36)
tylerwilson 0:3ab1d2d14eb3 1221 return 0;
tylerwilson 0:3ab1d2d14eb3 1222
tylerwilson 0:3ab1d2d14eb3 1223 chars=0;
tylerwilson 0:3ab1d2d14eb3 1224 value=0;
tylerwilson 0:3ab1d2d14eb3 1225 sign=1; /* to avoid a compiler warning (Microsoft Visual C/C++ 6.0) */
tylerwilson 0:3ab1d2d14eb3 1226
tylerwilson 0:3ab1d2d14eb3 1227 c=amx_getch();
tylerwilson 0:3ab1d2d14eb3 1228 while (c!=EOF) {
tylerwilson 0:3ab1d2d14eb3 1229 /* check for sign (if any) */
tylerwilson 0:3ab1d2d14eb3 1230 if (chars==0) {
tylerwilson 0:3ab1d2d14eb3 1231 if (c=='-') {
tylerwilson 0:3ab1d2d14eb3 1232 sign=-1;
tylerwilson 0:3ab1d2d14eb3 1233 acceptchar(c,&chars);
tylerwilson 0:3ab1d2d14eb3 1234 c=amx_getch();
tylerwilson 0:3ab1d2d14eb3 1235 } else {
tylerwilson 0:3ab1d2d14eb3 1236 sign=1;
tylerwilson 0:3ab1d2d14eb3 1237 } /* if */
tylerwilson 0:3ab1d2d14eb3 1238 } /* if */
tylerwilson 0:3ab1d2d14eb3 1239
tylerwilson 0:3ab1d2d14eb3 1240 /* check end of input */
tylerwilson 0:3ab1d2d14eb3 1241 #if EOL_CHAR!='\r'
tylerwilson 0:3ab1d2d14eb3 1242 if (c==EOL_CHAR && inlist(amx,'\r',params+2,(int)params[0]/sizeof(cell)-1)!=0)
tylerwilson 0:3ab1d2d14eb3 1243 c='\r';
tylerwilson 0:3ab1d2d14eb3 1244 #endif
tylerwilson 0:3ab1d2d14eb3 1245 if ((chars>1 || chars>0 && sign>0)
tylerwilson 0:3ab1d2d14eb3 1246 && (n=inlist(amx,c,params+2,(int)params[0]/sizeof(cell)-1))!=0)
tylerwilson 0:3ab1d2d14eb3 1247 {
tylerwilson 0:3ab1d2d14eb3 1248 if (n>0)
tylerwilson 0:3ab1d2d14eb3 1249 acceptchar(c,&chars);
tylerwilson 0:3ab1d2d14eb3 1250 break;
tylerwilson 0:3ab1d2d14eb3 1251 } /* if */
tylerwilson 0:3ab1d2d14eb3 1252 #if EOL_CHAR!='\r'
tylerwilson 0:3ab1d2d14eb3 1253 if (c=='\r')
tylerwilson 0:3ab1d2d14eb3 1254 c=EOL_CHAR;
tylerwilson 0:3ab1d2d14eb3 1255 #endif
tylerwilson 0:3ab1d2d14eb3 1256
tylerwilson 0:3ab1d2d14eb3 1257 /* get value */
tylerwilson 0:3ab1d2d14eb3 1258 d=base; /* by default, do not accept the character */
tylerwilson 0:3ab1d2d14eb3 1259 if (c>='0' && c<='9') {
tylerwilson 0:3ab1d2d14eb3 1260 d=c-'0';
tylerwilson 0:3ab1d2d14eb3 1261 } else if (c>='a' && c<='z') {
tylerwilson 0:3ab1d2d14eb3 1262 d=c-'a'+10;
tylerwilson 0:3ab1d2d14eb3 1263 } else if (c>='A' && c<='Z') {
tylerwilson 0:3ab1d2d14eb3 1264 d=c-'A'+10;
tylerwilson 0:3ab1d2d14eb3 1265 } else if (c=='\b') {
tylerwilson 0:3ab1d2d14eb3 1266 if (chars>0) {
tylerwilson 0:3ab1d2d14eb3 1267 value/=base;
tylerwilson 0:3ab1d2d14eb3 1268 acceptchar(c,&chars);
tylerwilson 0:3ab1d2d14eb3 1269 } /* if */
tylerwilson 0:3ab1d2d14eb3 1270 } /* if */
tylerwilson 0:3ab1d2d14eb3 1271 if (d<base) {
tylerwilson 0:3ab1d2d14eb3 1272 acceptchar(c,&chars);
tylerwilson 0:3ab1d2d14eb3 1273 value=value*base + d;
tylerwilson 0:3ab1d2d14eb3 1274 } /* if */
tylerwilson 0:3ab1d2d14eb3 1275 c=amx_getch();
tylerwilson 0:3ab1d2d14eb3 1276 } /* while */
tylerwilson 0:3ab1d2d14eb3 1277 return sign*value;
tylerwilson 0:3ab1d2d14eb3 1278 }
tylerwilson 0:3ab1d2d14eb3 1279
tylerwilson 0:3ab1d2d14eb3 1280 static cell AMX_NATIVE_CALL n_clrscr(AMX *amx,const cell *params)
tylerwilson 0:3ab1d2d14eb3 1281 {
tylerwilson 0:3ab1d2d14eb3 1282 (void)amx;
tylerwilson 0:3ab1d2d14eb3 1283 (void)params;
tylerwilson 0:3ab1d2d14eb3 1284 CreateConsole();
tylerwilson 0:3ab1d2d14eb3 1285 amx_clrscr();
tylerwilson 0:3ab1d2d14eb3 1286 return 0;
tylerwilson 0:3ab1d2d14eb3 1287 }
tylerwilson 0:3ab1d2d14eb3 1288
tylerwilson 0:3ab1d2d14eb3 1289 static cell AMX_NATIVE_CALL n_clreol(AMX *amx,const cell *params)
tylerwilson 0:3ab1d2d14eb3 1290 {
tylerwilson 0:3ab1d2d14eb3 1291 (void)amx;
tylerwilson 0:3ab1d2d14eb3 1292 (void)params;
tylerwilson 0:3ab1d2d14eb3 1293 CreateConsole();
tylerwilson 0:3ab1d2d14eb3 1294 amx_clreol();
tylerwilson 0:3ab1d2d14eb3 1295 return 0;
tylerwilson 0:3ab1d2d14eb3 1296 }
tylerwilson 0:3ab1d2d14eb3 1297
tylerwilson 0:3ab1d2d14eb3 1298 static cell AMX_NATIVE_CALL n_gotoxy(AMX *amx,const cell *params)
tylerwilson 0:3ab1d2d14eb3 1299 {
tylerwilson 0:3ab1d2d14eb3 1300 (void)amx;
tylerwilson 0:3ab1d2d14eb3 1301 CreateConsole();
tylerwilson 0:3ab1d2d14eb3 1302 return amx_gotoxy((int)params[1],(int)params[2]);
tylerwilson 0:3ab1d2d14eb3 1303 }
tylerwilson 0:3ab1d2d14eb3 1304
tylerwilson 0:3ab1d2d14eb3 1305 static cell AMX_NATIVE_CALL n_wherexy(AMX *amx,const cell *params)
tylerwilson 0:3ab1d2d14eb3 1306 {
tylerwilson 0:3ab1d2d14eb3 1307 cell *px,*py;
tylerwilson 0:3ab1d2d14eb3 1308 int x,y;
tylerwilson 0:3ab1d2d14eb3 1309
tylerwilson 0:3ab1d2d14eb3 1310 (void)amx;
tylerwilson 0:3ab1d2d14eb3 1311 CreateConsole();
tylerwilson 0:3ab1d2d14eb3 1312 amx_wherexy(&x,&y);
tylerwilson 0:3ab1d2d14eb3 1313 px=amx_Address(amx,params[1]);
tylerwilson 0:3ab1d2d14eb3 1314 py=amx_Address(amx,params[2]);
tylerwilson 0:3ab1d2d14eb3 1315 *px=x;
tylerwilson 0:3ab1d2d14eb3 1316 *py=y;
tylerwilson 0:3ab1d2d14eb3 1317 return 0;
tylerwilson 0:3ab1d2d14eb3 1318 }
tylerwilson 0:3ab1d2d14eb3 1319
tylerwilson 0:3ab1d2d14eb3 1320 static cell AMX_NATIVE_CALL n_setattr(AMX *amx,const cell *params)
tylerwilson 0:3ab1d2d14eb3 1321 {
tylerwilson 0:3ab1d2d14eb3 1322 (void)amx;
tylerwilson 0:3ab1d2d14eb3 1323 CreateConsole();
tylerwilson 0:3ab1d2d14eb3 1324 (void)amx_setattr((int)params[1],(int)params[2],(int)params[3]);
tylerwilson 0:3ab1d2d14eb3 1325 return 0;
tylerwilson 0:3ab1d2d14eb3 1326 }
tylerwilson 0:3ab1d2d14eb3 1327
tylerwilson 0:3ab1d2d14eb3 1328 static cell AMX_NATIVE_CALL n_consctrl(AMX *amx,const cell *params)
tylerwilson 0:3ab1d2d14eb3 1329 {
tylerwilson 0:3ab1d2d14eb3 1330 (void)amx;
tylerwilson 0:3ab1d2d14eb3 1331 CreateConsole();
tylerwilson 0:3ab1d2d14eb3 1332 (void)amx_termctl((int)params[1],(int)params[2]);
tylerwilson 0:3ab1d2d14eb3 1333 return 0;
tylerwilson 0:3ab1d2d14eb3 1334 }
tylerwilson 0:3ab1d2d14eb3 1335
tylerwilson 0:3ab1d2d14eb3 1336 static cell AMX_NATIVE_CALL n_console(AMX *amx,const cell *params)
tylerwilson 0:3ab1d2d14eb3 1337 {
tylerwilson 0:3ab1d2d14eb3 1338 (void)amx;
tylerwilson 0:3ab1d2d14eb3 1339 CreateConsole();
tylerwilson 0:3ab1d2d14eb3 1340 amx_console((int)params[1],(int)params[2],(int)params[3]);
tylerwilson 0:3ab1d2d14eb3 1341 return 0;
tylerwilson 0:3ab1d2d14eb3 1342 }
tylerwilson 0:3ab1d2d14eb3 1343
tylerwilson 0:3ab1d2d14eb3 1344
tylerwilson 0:3ab1d2d14eb3 1345 #if !defined AMXCONSOLE_NOIDLE
tylerwilson 0:3ab1d2d14eb3 1346 static AMX_IDLE PrevIdle = NULL;
tylerwilson 0:3ab1d2d14eb3 1347 static int idxKeyPressed = -1;
tylerwilson 0:3ab1d2d14eb3 1348
tylerwilson 0:3ab1d2d14eb3 1349 static int AMXAPI amx_ConsoleIdle(AMX *amx, int AMXAPI Exec(AMX *, cell *, int))
tylerwilson 0:3ab1d2d14eb3 1350 {
tylerwilson 0:3ab1d2d14eb3 1351 int err=0, key;
tylerwilson 0:3ab1d2d14eb3 1352
tylerwilson 0:3ab1d2d14eb3 1353 assert(idxKeyPressed >= 0);
tylerwilson 0:3ab1d2d14eb3 1354
tylerwilson 0:3ab1d2d14eb3 1355 if (PrevIdle != NULL)
tylerwilson 0:3ab1d2d14eb3 1356 PrevIdle(amx, Exec);
tylerwilson 0:3ab1d2d14eb3 1357
tylerwilson 0:3ab1d2d14eb3 1358 if (amx_kbhit()) {
tylerwilson 0:3ab1d2d14eb3 1359 key = amx_getch();
tylerwilson 0:3ab1d2d14eb3 1360 amx_Push(amx, key);
tylerwilson 0:3ab1d2d14eb3 1361 err = Exec(amx, NULL, idxKeyPressed);
tylerwilson 0:3ab1d2d14eb3 1362 while (err == AMX_ERR_SLEEP)
tylerwilson 0:3ab1d2d14eb3 1363 err = Exec(amx, NULL, AMX_EXEC_CONT);
tylerwilson 0:3ab1d2d14eb3 1364 } /* if */
tylerwilson 0:3ab1d2d14eb3 1365
tylerwilson 0:3ab1d2d14eb3 1366 return err;
tylerwilson 0:3ab1d2d14eb3 1367 }
tylerwilson 0:3ab1d2d14eb3 1368 #endif
tylerwilson 0:3ab1d2d14eb3 1369
tylerwilson 0:3ab1d2d14eb3 1370 #if defined __cplusplus
tylerwilson 0:3ab1d2d14eb3 1371 extern "C"
tylerwilson 0:3ab1d2d14eb3 1372 #endif
tylerwilson 0:3ab1d2d14eb3 1373 const AMX_NATIVE_INFO console_Natives[] = {
tylerwilson 0:3ab1d2d14eb3 1374 // { "getchar", n_getchar },
tylerwilson 0:3ab1d2d14eb3 1375 // { "getstring", n_getstring },
tylerwilson 0:3ab1d2d14eb3 1376 // { "getvalue", n_getvalue },
tylerwilson 0:3ab1d2d14eb3 1377 { "print", n_print },
tylerwilson 0:3ab1d2d14eb3 1378 { "printf", n_printf },
tylerwilson 0:3ab1d2d14eb3 1379 // { "clrscr", n_clrscr },
tylerwilson 0:3ab1d2d14eb3 1380 // { "clreol", n_clreol },
tylerwilson 0:3ab1d2d14eb3 1381 // { "gotoxy", n_gotoxy },
tylerwilson 0:3ab1d2d14eb3 1382 // { "wherexy", n_wherexy },
tylerwilson 0:3ab1d2d14eb3 1383 // { "setattr", n_setattr },
tylerwilson 0:3ab1d2d14eb3 1384 // { "console", n_console },
tylerwilson 0:3ab1d2d14eb3 1385 // { "consctrl", n_consctrl },
tylerwilson 0:3ab1d2d14eb3 1386 { NULL, NULL } /* terminator */
tylerwilson 0:3ab1d2d14eb3 1387 };
tylerwilson 0:3ab1d2d14eb3 1388
tylerwilson 0:3ab1d2d14eb3 1389 int AMXEXPORT AMXAPI amx_ConsoleInit(AMX *amx)
tylerwilson 0:3ab1d2d14eb3 1390 {
tylerwilson 0:3ab1d2d14eb3 1391 #if !defined AMXCONSOLE_NOIDLE
tylerwilson 0:3ab1d2d14eb3 1392 /* see whether there is an @keypressed() function */
tylerwilson 0:3ab1d2d14eb3 1393 if (amx_FindPublic(amx, "@keypressed", &idxKeyPressed) == AMX_ERR_NONE) {
tylerwilson 0:3ab1d2d14eb3 1394 if (amx_GetUserData(amx, AMX_USERTAG('I','d','l','e'), (void**)&PrevIdle) != AMX_ERR_NONE)
tylerwilson 0:3ab1d2d14eb3 1395 PrevIdle = NULL;
tylerwilson 0:3ab1d2d14eb3 1396 amx_SetUserData(amx, AMX_USERTAG('I','d','l','e'), (void*)amx_ConsoleIdle);
tylerwilson 0:3ab1d2d14eb3 1397 } /* if */
tylerwilson 0:3ab1d2d14eb3 1398 #endif
tylerwilson 0:3ab1d2d14eb3 1399
tylerwilson 0:3ab1d2d14eb3 1400 return amx_Register(amx, console_Natives, -1);
tylerwilson 0:3ab1d2d14eb3 1401 }
tylerwilson 0:3ab1d2d14eb3 1402
tylerwilson 0:3ab1d2d14eb3 1403 int AMXEXPORT AMXAPI amx_ConsoleCleanup(AMX *amx)
tylerwilson 0:3ab1d2d14eb3 1404 {
tylerwilson 0:3ab1d2d14eb3 1405 (void)amx;
tylerwilson 0:3ab1d2d14eb3 1406 #if !defined AMXCONSOLE_NOIDLE
tylerwilson 0:3ab1d2d14eb3 1407 PrevIdle = NULL;
tylerwilson 0:3ab1d2d14eb3 1408 #endif
tylerwilson 0:3ab1d2d14eb3 1409 return AMX_ERR_NONE;
tylerwilson 0:3ab1d2d14eb3 1410 }
tylerwilson 0:3ab1d2d14eb3 1411
tylerwilson 0:3ab1d2d14eb3 1412 #endif /* AMX_STRING_LIB */