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:
2:01588bd27169
Now includes AnalogIn and AnalogOut functions

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tylerwilson 0:3ab1d2d14eb3 1 /* Date/time module for the Pawn Abstract Machine
tylerwilson 0:3ab1d2d14eb3 2 *
tylerwilson 0:3ab1d2d14eb3 3 * Copyright (c) ITB CompuPhase, 2001-2011
tylerwilson 0:3ab1d2d14eb3 4 *
tylerwilson 0:3ab1d2d14eb3 5 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
tylerwilson 0:3ab1d2d14eb3 6 * use this file except in compliance with the License. You may obtain a copy
tylerwilson 0:3ab1d2d14eb3 7 * of the License at
tylerwilson 0:3ab1d2d14eb3 8 *
tylerwilson 0:3ab1d2d14eb3 9 * http://www.apache.org/licenses/LICENSE-2.0
tylerwilson 0:3ab1d2d14eb3 10 *
tylerwilson 0:3ab1d2d14eb3 11 * Unless required by applicable law or agreed to in writing, software
tylerwilson 0:3ab1d2d14eb3 12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
tylerwilson 0:3ab1d2d14eb3 13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
tylerwilson 0:3ab1d2d14eb3 14 * License for the specific language governing permissions and limitations
tylerwilson 0:3ab1d2d14eb3 15 * under the License.
tylerwilson 0:3ab1d2d14eb3 16 *
tylerwilson 0:3ab1d2d14eb3 17 * Version: $Id: amxtime.c 4541 2011-07-21 12:15:13Z thiadmer $
tylerwilson 0:3ab1d2d14eb3 18 */
tylerwilson 0:3ab1d2d14eb3 19 #include <time.h>
tylerwilson 0:3ab1d2d14eb3 20 #include <assert.h>
tylerwilson 0:3ab1d2d14eb3 21 #include "osdefs.h"
tylerwilson 0:3ab1d2d14eb3 22 #include "amx.h"
tylerwilson 0:3ab1d2d14eb3 23 #if defined __WIN32__ || defined _WIN32 || defined _Windows
tylerwilson 0:3ab1d2d14eb3 24 #include <windows.h>
tylerwilson 0:3ab1d2d14eb3 25 #include <mmsystem.h>
tylerwilson 0:3ab1d2d14eb3 26 #endif
tylerwilson 0:3ab1d2d14eb3 27
tylerwilson 0:3ab1d2d14eb3 28 #define CELLMIN (-1 << (8*sizeof(cell) - 1))
tylerwilson 0:3ab1d2d14eb3 29
tylerwilson 2:01588bd27169 30 #define SECONDS_PER_MINUTE 60
tylerwilson 2:01588bd27169 31 #define SECONDS_PER_HOUR 3600
tylerwilson 2:01588bd27169 32 #define SECONDS_PER_DAY 86400
tylerwilson 2:01588bd27169 33 #define SECONDS_PER_YEAR 31556952 /* based on 365.2425 days per year */
tylerwilson 0:3ab1d2d14eb3 34
tylerwilson 0:3ab1d2d14eb3 35 #if !defined CLOCKS_PER_SEC
tylerwilson 0:3ab1d2d14eb3 36 #define CLOCKS_PER_SEC CLK_TCK
tylerwilson 0:3ab1d2d14eb3 37 #endif
tylerwilson 0:3ab1d2d14eb3 38 #if defined __WIN32__ || defined _WIN32 || defined WIN32
tylerwilson 0:3ab1d2d14eb3 39 static int timerset = 0;
tylerwilson 0:3ab1d2d14eb3 40 /* timeGetTime() is more accurate on WindowsNT if timeBeginPeriod(1) is set */
tylerwilson 0:3ab1d2d14eb3 41 #define INIT_TIMER() \
tylerwilson 0:3ab1d2d14eb3 42 if (!timerset) { \
tylerwilson 0:3ab1d2d14eb3 43 timeBeginPeriod(1); \
tylerwilson 0:3ab1d2d14eb3 44 timerset=1; \
tylerwilson 0:3ab1d2d14eb3 45 }
tylerwilson 0:3ab1d2d14eb3 46 #else
tylerwilson 0:3ab1d2d14eb3 47 #define INIT_TIMER()
tylerwilson 0:3ab1d2d14eb3 48 #endif
tylerwilson 0:3ab1d2d14eb3 49 static unsigned long timestamp;
tylerwilson 0:3ab1d2d14eb3 50 static unsigned long timelimit;
tylerwilson 0:3ab1d2d14eb3 51 static int timerepeat;
tylerwilson 0:3ab1d2d14eb3 52
tylerwilson 0:3ab1d2d14eb3 53 static const unsigned char monthdays[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
tylerwilson 0:3ab1d2d14eb3 54
tylerwilson 0:3ab1d2d14eb3 55 static int wrap(int value, int min, int max)
tylerwilson 0:3ab1d2d14eb3 56 {
tylerwilson 0:3ab1d2d14eb3 57 if (value<min)
tylerwilson 0:3ab1d2d14eb3 58 value=max;
tylerwilson 0:3ab1d2d14eb3 59 else if (value>max)
tylerwilson 0:3ab1d2d14eb3 60 value=min;
tylerwilson 0:3ab1d2d14eb3 61 return value;
tylerwilson 0:3ab1d2d14eb3 62 }
tylerwilson 0:3ab1d2d14eb3 63
tylerwilson 0:3ab1d2d14eb3 64 static unsigned long gettimestamp(void)
tylerwilson 0:3ab1d2d14eb3 65 {
tylerwilson 0:3ab1d2d14eb3 66 unsigned long value;
tylerwilson 0:3ab1d2d14eb3 67
tylerwilson 0:3ab1d2d14eb3 68 #if defined __WIN32__ || defined _WIN32 || defined WIN32
tylerwilson 0:3ab1d2d14eb3 69 value=timeGetTime(); /* this value is already in milliseconds */
tylerwilson 0:3ab1d2d14eb3 70 #elif defined __linux || defined __linux__ || defined __LINUX__
tylerwilson 0:3ab1d2d14eb3 71 struct timeval tv;
tylerwilson 0:3ab1d2d14eb3 72 gettimeofday(&tv, NULL);
tylerwilson 0:3ab1d2d14eb3 73 value = ((tv.tv_sec * 1000) + (tv.tv_usec / 1000));
tylerwilson 0:3ab1d2d14eb3 74 #else
tylerwilson 0:3ab1d2d14eb3 75 value=clock();
tylerwilson 0:3ab1d2d14eb3 76 #if CLOCKS_PER_SEC<1000
tylerwilson 0:3ab1d2d14eb3 77 /* convert to milliseconds */
tylerwilson 0:3ab1d2d14eb3 78 value=(cell)((1000L * value) / CLOCKS_PER_SEC);
tylerwilson 0:3ab1d2d14eb3 79 #elif CLOCKS_PER_SEC>1000
tylerwilson 0:3ab1d2d14eb3 80 /* convert to milliseconds */
tylerwilson 0:3ab1d2d14eb3 81 value=(cell)(value/(CLOCKS_PER_SEC/1000));
tylerwilson 0:3ab1d2d14eb3 82 #endif
tylerwilson 0:3ab1d2d14eb3 83 #endif
tylerwilson 0:3ab1d2d14eb3 84 return value;
tylerwilson 0:3ab1d2d14eb3 85 }
tylerwilson 0:3ab1d2d14eb3 86
tylerwilson 0:3ab1d2d14eb3 87 void stamp2datetime(unsigned long sec1970,
tylerwilson 0:3ab1d2d14eb3 88 int *year, int *month, int *day,
tylerwilson 0:3ab1d2d14eb3 89 int *hour, int *minute, int *second)
tylerwilson 0:3ab1d2d14eb3 90 {
tylerwilson 0:3ab1d2d14eb3 91 int days, seconds;
tylerwilson 0:3ab1d2d14eb3 92
tylerwilson 0:3ab1d2d14eb3 93 /* find the year */
tylerwilson 0:3ab1d2d14eb3 94 assert(year!=NULL);
tylerwilson 0:3ab1d2d14eb3 95 for (*year = 1970; ; *year += 1) {
tylerwilson 0:3ab1d2d14eb3 96 days = 365 + ((*year & 0x03) == 0); /* clumsy "leap-year" routine, fails for 2100 */
tylerwilson 0:3ab1d2d14eb3 97 seconds = days * SECONDS_PER_DAY;
tylerwilson 0:3ab1d2d14eb3 98 if ((unsigned long)seconds > sec1970)
tylerwilson 0:3ab1d2d14eb3 99 break;
tylerwilson 0:3ab1d2d14eb3 100 sec1970 -= seconds;
tylerwilson 0:3ab1d2d14eb3 101 } /* if */
tylerwilson 0:3ab1d2d14eb3 102
tylerwilson 0:3ab1d2d14eb3 103 /* find the month */
tylerwilson 0:3ab1d2d14eb3 104 assert(month!=NULL);
tylerwilson 0:3ab1d2d14eb3 105 for (*month = 1; ; *month += 1) {
tylerwilson 0:3ab1d2d14eb3 106 days = monthdays[*month - 1];
tylerwilson 0:3ab1d2d14eb3 107 seconds = days * SECONDS_PER_DAY;
tylerwilson 0:3ab1d2d14eb3 108 if ((unsigned long)seconds > sec1970)
tylerwilson 0:3ab1d2d14eb3 109 break;
tylerwilson 0:3ab1d2d14eb3 110 sec1970 -= seconds;
tylerwilson 0:3ab1d2d14eb3 111 } /* if */
tylerwilson 0:3ab1d2d14eb3 112
tylerwilson 0:3ab1d2d14eb3 113 /* find the day */
tylerwilson 0:3ab1d2d14eb3 114 assert(day!=NULL);
tylerwilson 0:3ab1d2d14eb3 115 for (*day = 1; sec1970 >= SECONDS_PER_DAY; *day += 1)
tylerwilson 0:3ab1d2d14eb3 116 sec1970 -= SECONDS_PER_DAY;
tylerwilson 0:3ab1d2d14eb3 117
tylerwilson 0:3ab1d2d14eb3 118 /* find the hour */
tylerwilson 0:3ab1d2d14eb3 119 assert(hour!=NULL);
tylerwilson 0:3ab1d2d14eb3 120 for (*hour = 0; sec1970 >= SECONDS_PER_HOUR; *hour += 1)
tylerwilson 0:3ab1d2d14eb3 121 sec1970 -= SECONDS_PER_HOUR;
tylerwilson 0:3ab1d2d14eb3 122
tylerwilson 0:3ab1d2d14eb3 123 /* find the minute */
tylerwilson 0:3ab1d2d14eb3 124 assert(minute!=NULL);
tylerwilson 0:3ab1d2d14eb3 125 for (*minute = 0; sec1970 >= SECONDS_PER_MINUTE; *minute += 1)
tylerwilson 0:3ab1d2d14eb3 126 sec1970 -= SECONDS_PER_MINUTE;
tylerwilson 0:3ab1d2d14eb3 127
tylerwilson 0:3ab1d2d14eb3 128 /* remainder is the number of seconds */
tylerwilson 0:3ab1d2d14eb3 129 assert(second!=NULL);
tylerwilson 0:3ab1d2d14eb3 130 *second = (int)sec1970;
tylerwilson 0:3ab1d2d14eb3 131 }
tylerwilson 0:3ab1d2d14eb3 132
tylerwilson 0:3ab1d2d14eb3 133 static void settime(cell hour,cell minute,cell second)
tylerwilson 0:3ab1d2d14eb3 134 {
tylerwilson 0:3ab1d2d14eb3 135 #if defined __WIN32__ || defined _WIN32 || defined WIN32
tylerwilson 0:3ab1d2d14eb3 136 SYSTEMTIME systim;
tylerwilson 0:3ab1d2d14eb3 137
tylerwilson 0:3ab1d2d14eb3 138 GetLocalTime(&systim);
tylerwilson 0:3ab1d2d14eb3 139 if (hour!=CELLMIN)
tylerwilson 0:3ab1d2d14eb3 140 systim.wHour=(WORD)wrap((int)hour,0,23);
tylerwilson 0:3ab1d2d14eb3 141 if (minute!=CELLMIN)
tylerwilson 0:3ab1d2d14eb3 142 systim.wMinute=(WORD)wrap((int)minute,0,59);
tylerwilson 0:3ab1d2d14eb3 143 if (second!=CELLMIN)
tylerwilson 0:3ab1d2d14eb3 144 systim.wSecond=(WORD)wrap((int)second,0,59);
tylerwilson 0:3ab1d2d14eb3 145 SetLocalTime(&systim);
tylerwilson 0:3ab1d2d14eb3 146 #else
tylerwilson 0:3ab1d2d14eb3 147 /* Linux/Unix (and some DOS compilers) have stime(); on Linux/Unix, you
tylerwilson 0:3ab1d2d14eb3 148 * must have "root" permission to call stime()
tylerwilson 0:3ab1d2d14eb3 149 */
tylerwilson 0:3ab1d2d14eb3 150 time_t sec1970;
tylerwilson 0:3ab1d2d14eb3 151 struct tm gtm;
tylerwilson 0:3ab1d2d14eb3 152
tylerwilson 0:3ab1d2d14eb3 153 time(&sec1970);
tylerwilson 0:3ab1d2d14eb3 154 gtm=*localtime(&sec1970);
tylerwilson 0:3ab1d2d14eb3 155 if (hour!=CELLMIN)
tylerwilson 0:3ab1d2d14eb3 156 gtm.tm_hour=wrap((int)hour,0,23);
tylerwilson 0:3ab1d2d14eb3 157 if (minute!=CELLMIN)
tylerwilson 0:3ab1d2d14eb3 158 gtm.tm_min=wrap((int)minute,0,59);
tylerwilson 0:3ab1d2d14eb3 159 if (second!=CELLMIN)
tylerwilson 0:3ab1d2d14eb3 160 gtm.tm_sec=wrap((int)second,0,59);
tylerwilson 0:3ab1d2d14eb3 161 sec1970=mktime(&gtm);
tylerwilson 0:3ab1d2d14eb3 162 stime(&sec1970);
tylerwilson 0:3ab1d2d14eb3 163 #endif
tylerwilson 0:3ab1d2d14eb3 164 }
tylerwilson 0:3ab1d2d14eb3 165
tylerwilson 0:3ab1d2d14eb3 166 static void setdate(cell year,cell month,cell day)
tylerwilson 0:3ab1d2d14eb3 167 {
tylerwilson 0:3ab1d2d14eb3 168 #if defined __WIN32__ || defined _WIN32 || defined WIN32
tylerwilson 2:01588bd27169 169 int maxday;
tylerwilson 0:3ab1d2d14eb3 170 SYSTEMTIME systim;
tylerwilson 0:3ab1d2d14eb3 171
tylerwilson 0:3ab1d2d14eb3 172 GetLocalTime(&systim);
tylerwilson 0:3ab1d2d14eb3 173 if (year!=CELLMIN)
tylerwilson 0:3ab1d2d14eb3 174 systim.wYear=(WORD)wrap((int)year,1970,2099);
tylerwilson 0:3ab1d2d14eb3 175 if (month!=CELLMIN)
tylerwilson 0:3ab1d2d14eb3 176 systim.wMonth=(WORD)wrap((int)month,1,12);
tylerwilson 0:3ab1d2d14eb3 177 maxday=monthdays[systim.wMonth - 1];
tylerwilson 0:3ab1d2d14eb3 178 if (systim.wMonth==2 && ((systim.wYear % 4)==0 && ((systim.wYear % 100)!=0 || (systim.wYear % 400)==0)))
tylerwilson 0:3ab1d2d14eb3 179 maxday++;
tylerwilson 0:3ab1d2d14eb3 180 if (day!=CELLMIN)
tylerwilson 0:3ab1d2d14eb3 181 systim.wDay=(WORD)wrap((int)day,1,maxday);
tylerwilson 0:3ab1d2d14eb3 182 SetLocalTime(&systim);
tylerwilson 0:3ab1d2d14eb3 183 #else
tylerwilson 0:3ab1d2d14eb3 184 /* Linux/Unix (and some DOS compilers) have stime(); on Linux/Unix, you
tylerwilson 0:3ab1d2d14eb3 185 * must have "root" permission to call stime()
tylerwilson 0:3ab1d2d14eb3 186 */
tylerwilson 0:3ab1d2d14eb3 187 time_t sec1970;
tylerwilson 0:3ab1d2d14eb3 188 struct tm gtm;
tylerwilson 0:3ab1d2d14eb3 189
tylerwilson 0:3ab1d2d14eb3 190 time(&sec1970);
tylerwilson 0:3ab1d2d14eb3 191 gtm=*localtime(&sec1970);
tylerwilson 0:3ab1d2d14eb3 192 if (year!=CELLMIN)
tylerwilson 0:3ab1d2d14eb3 193 gtm.tm_year=year-1900;
tylerwilson 0:3ab1d2d14eb3 194 if (month!=CELLMIN)
tylerwilson 0:3ab1d2d14eb3 195 gtm.tm_mon=month-1;
tylerwilson 0:3ab1d2d14eb3 196 if (day!=CELLMIN)
tylerwilson 0:3ab1d2d14eb3 197 gtm.tm_mday=day;
tylerwilson 0:3ab1d2d14eb3 198 sec1970=mktime(&gtm);
tylerwilson 0:3ab1d2d14eb3 199 stime(&sec1970);
tylerwilson 0:3ab1d2d14eb3 200 #endif
tylerwilson 0:3ab1d2d14eb3 201 }
tylerwilson 0:3ab1d2d14eb3 202
tylerwilson 0:3ab1d2d14eb3 203
tylerwilson 0:3ab1d2d14eb3 204 /* settime(hour, minute, second)
tylerwilson 0:3ab1d2d14eb3 205 * Always returns 0
tylerwilson 0:3ab1d2d14eb3 206 */
tylerwilson 0:3ab1d2d14eb3 207 static cell AMX_NATIVE_CALL n_settime(AMX *amx, const cell *params)
tylerwilson 0:3ab1d2d14eb3 208 {
tylerwilson 0:3ab1d2d14eb3 209 (void)amx;
tylerwilson 0:3ab1d2d14eb3 210 settime(params[1],params[2],params[3]);
tylerwilson 0:3ab1d2d14eb3 211 return 0;
tylerwilson 0:3ab1d2d14eb3 212 }
tylerwilson 0:3ab1d2d14eb3 213
tylerwilson 0:3ab1d2d14eb3 214 /* gettime(&hour, &minute, &second)
tylerwilson 0:3ab1d2d14eb3 215 * The return value is the number of seconds since 1 January 1970 (Unix system
tylerwilson 0:3ab1d2d14eb3 216 * time).
tylerwilson 0:3ab1d2d14eb3 217 */
tylerwilson 0:3ab1d2d14eb3 218 static cell AMX_NATIVE_CALL n_gettime(AMX *amx, const cell *params)
tylerwilson 0:3ab1d2d14eb3 219 {
tylerwilson 0:3ab1d2d14eb3 220 time_t sec1970;
tylerwilson 0:3ab1d2d14eb3 221 struct tm gtm;
tylerwilson 0:3ab1d2d14eb3 222 cell *cptr;
tylerwilson 0:3ab1d2d14eb3 223
tylerwilson 0:3ab1d2d14eb3 224 assert(params[0]==(int)(3*sizeof(cell)));
tylerwilson 0:3ab1d2d14eb3 225
tylerwilson 0:3ab1d2d14eb3 226 time(&sec1970);
tylerwilson 0:3ab1d2d14eb3 227
tylerwilson 0:3ab1d2d14eb3 228 /* on DOS/Windows, the timezone is usually not set for the C run-time
tylerwilson 0:3ab1d2d14eb3 229 * library; in that case gmtime() and localtime() return the same value
tylerwilson 0:3ab1d2d14eb3 230 */
tylerwilson 0:3ab1d2d14eb3 231 gtm=*localtime(&sec1970);
tylerwilson 0:3ab1d2d14eb3 232 cptr=amx_Address(amx,params[1]);
tylerwilson 0:3ab1d2d14eb3 233 *cptr=gtm.tm_hour;
tylerwilson 0:3ab1d2d14eb3 234 cptr=amx_Address(amx,params[2]);
tylerwilson 0:3ab1d2d14eb3 235 *cptr=gtm.tm_min;
tylerwilson 0:3ab1d2d14eb3 236 cptr=amx_Address(amx,params[3]);
tylerwilson 0:3ab1d2d14eb3 237 *cptr=gtm.tm_sec;
tylerwilson 0:3ab1d2d14eb3 238
tylerwilson 0:3ab1d2d14eb3 239 /* the time() function returns the number of seconds since January 1 1970
tylerwilson 0:3ab1d2d14eb3 240 * in Universal Coordinated Time (the successor to Greenwich Mean Time)
tylerwilson 0:3ab1d2d14eb3 241 */
tylerwilson 0:3ab1d2d14eb3 242 return (cell)sec1970;
tylerwilson 0:3ab1d2d14eb3 243 }
tylerwilson 0:3ab1d2d14eb3 244
tylerwilson 0:3ab1d2d14eb3 245 /* setdate(year, month, day)
tylerwilson 0:3ab1d2d14eb3 246 * Always returns 0
tylerwilson 0:3ab1d2d14eb3 247 */
tylerwilson 0:3ab1d2d14eb3 248 static cell AMX_NATIVE_CALL n_setdate(AMX *amx, const cell *params)
tylerwilson 0:3ab1d2d14eb3 249 {
tylerwilson 0:3ab1d2d14eb3 250 (void)amx;
tylerwilson 0:3ab1d2d14eb3 251 setdate(params[1],params[2],params[3]);
tylerwilson 0:3ab1d2d14eb3 252 return 0;
tylerwilson 0:3ab1d2d14eb3 253 }
tylerwilson 0:3ab1d2d14eb3 254
tylerwilson 0:3ab1d2d14eb3 255 /* getdate(&year, &month, &day)
tylerwilson 0:3ab1d2d14eb3 256 * The return value is the number of days since the start of the year. January
tylerwilson 0:3ab1d2d14eb3 257 * 1 is day 1 of the year.
tylerwilson 0:3ab1d2d14eb3 258 */
tylerwilson 0:3ab1d2d14eb3 259 static cell AMX_NATIVE_CALL n_getdate(AMX *amx, const cell *params)
tylerwilson 0:3ab1d2d14eb3 260 {
tylerwilson 0:3ab1d2d14eb3 261 time_t sec1970;
tylerwilson 0:3ab1d2d14eb3 262 struct tm gtm;
tylerwilson 0:3ab1d2d14eb3 263 cell *cptr;
tylerwilson 0:3ab1d2d14eb3 264
tylerwilson 0:3ab1d2d14eb3 265 assert(params[0]==(int)(3*sizeof(cell)));
tylerwilson 0:3ab1d2d14eb3 266
tylerwilson 0:3ab1d2d14eb3 267 time(&sec1970);
tylerwilson 0:3ab1d2d14eb3 268
tylerwilson 0:3ab1d2d14eb3 269 gtm=*localtime(&sec1970);
tylerwilson 0:3ab1d2d14eb3 270 cptr=amx_Address(amx,params[1]);
tylerwilson 0:3ab1d2d14eb3 271 *cptr=gtm.tm_year+1900;
tylerwilson 0:3ab1d2d14eb3 272 cptr=amx_Address(amx,params[2]);
tylerwilson 0:3ab1d2d14eb3 273 *cptr=gtm.tm_mon+1;
tylerwilson 0:3ab1d2d14eb3 274 cptr=amx_Address(amx,params[3]);
tylerwilson 0:3ab1d2d14eb3 275 *cptr=gtm.tm_mday;
tylerwilson 0:3ab1d2d14eb3 276
tylerwilson 0:3ab1d2d14eb3 277 return gtm.tm_yday+1;
tylerwilson 0:3ab1d2d14eb3 278 }
tylerwilson 0:3ab1d2d14eb3 279
tylerwilson 0:3ab1d2d14eb3 280 /* tickcount(&granularity)
tylerwilson 0:3ab1d2d14eb3 281 * Returns the number of milliseconds since start-up. For a 32-bit cell, this
tylerwilson 0:3ab1d2d14eb3 282 * count overflows after approximately 24 days of continuous operation.
tylerwilson 0:3ab1d2d14eb3 283 */
tylerwilson 0:3ab1d2d14eb3 284 static cell AMX_NATIVE_CALL n_tickcount(AMX *amx, const cell *params)
tylerwilson 0:3ab1d2d14eb3 285 {
tylerwilson 0:3ab1d2d14eb3 286 cell *cptr;
tylerwilson 0:3ab1d2d14eb3 287
tylerwilson 0:3ab1d2d14eb3 288 assert(params[0]==(int)sizeof(cell));
tylerwilson 0:3ab1d2d14eb3 289
tylerwilson 0:3ab1d2d14eb3 290 INIT_TIMER();
tylerwilson 0:3ab1d2d14eb3 291 cptr=amx_Address(amx,params[1]);
tylerwilson 0:3ab1d2d14eb3 292 #if defined __WIN32__ || defined _WIN32 || defined WIN32
tylerwilson 2:01588bd27169 293 *cptr=1000; /* granularity = 1 ms */
tylerwilson 0:3ab1d2d14eb3 294 #else
tylerwilson 2:01588bd27169 295 *cptr=(cell)CLOCKS_PER_SEC; /* in Unix/Linux, this is often 100 */
tylerwilson 0:3ab1d2d14eb3 296 #endif
tylerwilson 0:3ab1d2d14eb3 297 return gettimestamp() & 0x7fffffff;
tylerwilson 0:3ab1d2d14eb3 298 }
tylerwilson 0:3ab1d2d14eb3 299
tylerwilson 0:3ab1d2d14eb3 300 /* delay(milliseconds)
tylerwilson 0:3ab1d2d14eb3 301 * Pauses for (at least) the requested number of milliseconds.
tylerwilson 0:3ab1d2d14eb3 302 */
tylerwilson 0:3ab1d2d14eb3 303 static cell AMX_NATIVE_CALL n_delay(AMX *amx, const cell *params)
tylerwilson 0:3ab1d2d14eb3 304 {
tylerwilson 0:3ab1d2d14eb3 305 unsigned long stamp;
tylerwilson 0:3ab1d2d14eb3 306
tylerwilson 0:3ab1d2d14eb3 307 (void)amx;
tylerwilson 0:3ab1d2d14eb3 308 assert(params[0]==(int)sizeof(cell));
tylerwilson 0:3ab1d2d14eb3 309
tylerwilson 0:3ab1d2d14eb3 310 INIT_TIMER();
tylerwilson 0:3ab1d2d14eb3 311 stamp=gettimestamp();
tylerwilson 0:3ab1d2d14eb3 312 while (gettimestamp()-stamp < (unsigned long)params[1])
tylerwilson 0:3ab1d2d14eb3 313 /* nothing */;
tylerwilson 0:3ab1d2d14eb3 314 return 0;
tylerwilson 0:3ab1d2d14eb3 315 }
tylerwilson 0:3ab1d2d14eb3 316
tylerwilson 0:3ab1d2d14eb3 317 /* settimer(milliseconds, bool: singleshot = false)
tylerwilson 0:3ab1d2d14eb3 318 * Sets the delay until the @timer() callback is called. The timer may either
tylerwilson 0:3ab1d2d14eb3 319 * be single-shot or repetitive.
tylerwilson 0:3ab1d2d14eb3 320 */
tylerwilson 0:3ab1d2d14eb3 321 static cell AMX_NATIVE_CALL n_settimer(AMX *amx, const cell *params)
tylerwilson 0:3ab1d2d14eb3 322 {
tylerwilson 0:3ab1d2d14eb3 323 (void)amx;
tylerwilson 0:3ab1d2d14eb3 324 assert(params[0]==(int)(2*sizeof(cell)));
tylerwilson 0:3ab1d2d14eb3 325 timestamp=gettimestamp();
tylerwilson 0:3ab1d2d14eb3 326 timelimit=params[1];
tylerwilson 0:3ab1d2d14eb3 327 timerepeat=(int)(params[2]==0);
tylerwilson 0:3ab1d2d14eb3 328 return 0;
tylerwilson 0:3ab1d2d14eb3 329 }
tylerwilson 0:3ab1d2d14eb3 330
tylerwilson 0:3ab1d2d14eb3 331 /* bool: gettimer(&milliseconds, bool: &singleshot = false)
tylerwilson 0:3ab1d2d14eb3 332 * Retrieves the timer set with settimer(); returns true if a timer
tylerwilson 0:3ab1d2d14eb3 333 * was set up, or false otherwise.
tylerwilson 0:3ab1d2d14eb3 334 */
tylerwilson 0:3ab1d2d14eb3 335 static cell AMX_NATIVE_CALL n_gettimer(AMX *amx, const cell *params)
tylerwilson 0:3ab1d2d14eb3 336 {
tylerwilson 0:3ab1d2d14eb3 337 cell *cptr;
tylerwilson 0:3ab1d2d14eb3 338
tylerwilson 0:3ab1d2d14eb3 339 assert(params[0]==(int)(2*sizeof(cell)));
tylerwilson 0:3ab1d2d14eb3 340 cptr=amx_Address(amx,params[1]);
tylerwilson 0:3ab1d2d14eb3 341 *cptr=timelimit;
tylerwilson 0:3ab1d2d14eb3 342 cptr=amx_Address(amx,params[2]);
tylerwilson 0:3ab1d2d14eb3 343 *cptr=timerepeat;
tylerwilson 0:3ab1d2d14eb3 344 return timelimit>0;
tylerwilson 0:3ab1d2d14eb3 345 }
tylerwilson 0:3ab1d2d14eb3 346
tylerwilson 0:3ab1d2d14eb3 347 /* settimestamp(seconds1970) sets the date and time from a single parameter: the
tylerwilson 0:3ab1d2d14eb3 348 * number of seconds since 1 January 1970.
tylerwilson 0:3ab1d2d14eb3 349 */
tylerwilson 0:3ab1d2d14eb3 350 static cell AMX_NATIVE_CALL n_settimestamp(AMX *amx, const cell *params)
tylerwilson 0:3ab1d2d14eb3 351 {
tylerwilson 0:3ab1d2d14eb3 352 #if defined __WIN32__ || defined _WIN32 || defined WIN32
tylerwilson 0:3ab1d2d14eb3 353 int year, month, day, hour, minute, second;
tylerwilson 0:3ab1d2d14eb3 354
tylerwilson 0:3ab1d2d14eb3 355 stamp2datetime(params[1],
tylerwilson 0:3ab1d2d14eb3 356 &year, &month, &day,
tylerwilson 0:3ab1d2d14eb3 357 &hour, &minute, &second);
tylerwilson 0:3ab1d2d14eb3 358 setdate(year, month, day);
tylerwilson 0:3ab1d2d14eb3 359 settime(hour, minute, second);
tylerwilson 0:3ab1d2d14eb3 360 #else
tylerwilson 0:3ab1d2d14eb3 361 /* Linux/Unix (and some DOS compilers) have stime(); on Linux/Unix, you
tylerwilson 0:3ab1d2d14eb3 362 * must have "root" permission to call stime()
tylerwilson 0:3ab1d2d14eb3 363 */
tylerwilson 0:3ab1d2d14eb3 364 time_t sec1970=(time_t)params[1];
tylerwilson 0:3ab1d2d14eb3 365 stime(&sec1970);
tylerwilson 0:3ab1d2d14eb3 366 #endif
tylerwilson 0:3ab1d2d14eb3 367 (void)amx;
tylerwilson 0:3ab1d2d14eb3 368
tylerwilson 0:3ab1d2d14eb3 369 return 0;
tylerwilson 0:3ab1d2d14eb3 370 }
tylerwilson 0:3ab1d2d14eb3 371
tylerwilson 0:3ab1d2d14eb3 372 /* cvttimestamp(seconds1970, &year, &month, &day, &hour, &minute, &second)
tylerwilson 0:3ab1d2d14eb3 373 */
tylerwilson 0:3ab1d2d14eb3 374 static cell AMX_NATIVE_CALL n_cvttimestamp(AMX *amx, const cell *params)
tylerwilson 0:3ab1d2d14eb3 375 {
tylerwilson 0:3ab1d2d14eb3 376 int year, month, day, hour, minute, second;
tylerwilson 0:3ab1d2d14eb3 377
tylerwilson 0:3ab1d2d14eb3 378 (void)amx;
tylerwilson 0:3ab1d2d14eb3 379 stamp2datetime(params[1],
tylerwilson 0:3ab1d2d14eb3 380 &year, &month, &day,
tylerwilson 0:3ab1d2d14eb3 381 &hour, &minute, &second);
tylerwilson 0:3ab1d2d14eb3 382 return 0;
tylerwilson 0:3ab1d2d14eb3 383 }
tylerwilson 0:3ab1d2d14eb3 384
tylerwilson 0:3ab1d2d14eb3 385
tylerwilson 0:3ab1d2d14eb3 386 #if !defined AMXTIME_NOIDLE
tylerwilson 0:3ab1d2d14eb3 387 static AMX_IDLE PrevIdle = NULL;
tylerwilson 0:3ab1d2d14eb3 388 static int idxTimer = -1;
tylerwilson 0:3ab1d2d14eb3 389
tylerwilson 0:3ab1d2d14eb3 390 static int AMXAPI amx_TimeIdle(AMX *amx, int AMXAPI Exec(AMX *, cell *, int))
tylerwilson 0:3ab1d2d14eb3 391 {
tylerwilson 0:3ab1d2d14eb3 392 int err=0;
tylerwilson 0:3ab1d2d14eb3 393
tylerwilson 0:3ab1d2d14eb3 394 assert(idxTimer >= 0);
tylerwilson 0:3ab1d2d14eb3 395
tylerwilson 0:3ab1d2d14eb3 396 if (PrevIdle != NULL)
tylerwilson 0:3ab1d2d14eb3 397 PrevIdle(amx, Exec);
tylerwilson 0:3ab1d2d14eb3 398
tylerwilson 0:3ab1d2d14eb3 399 if (timelimit>0 && (gettimestamp()-timestamp)>=timelimit) {
tylerwilson 0:3ab1d2d14eb3 400 if (timerepeat)
tylerwilson 0:3ab1d2d14eb3 401 timestamp+=timelimit;
tylerwilson 0:3ab1d2d14eb3 402 else
tylerwilson 0:3ab1d2d14eb3 403 timelimit=0; /* do not repeat single-shot timer */
tylerwilson 0:3ab1d2d14eb3 404 err = Exec(amx, NULL, idxTimer);
tylerwilson 0:3ab1d2d14eb3 405 while (err == AMX_ERR_SLEEP)
tylerwilson 0:3ab1d2d14eb3 406 err = Exec(amx, NULL, AMX_EXEC_CONT);
tylerwilson 0:3ab1d2d14eb3 407 } /* if */
tylerwilson 0:3ab1d2d14eb3 408
tylerwilson 0:3ab1d2d14eb3 409 return err;
tylerwilson 0:3ab1d2d14eb3 410 }
tylerwilson 0:3ab1d2d14eb3 411 #endif
tylerwilson 0:3ab1d2d14eb3 412
tylerwilson 0:3ab1d2d14eb3 413
tylerwilson 0:3ab1d2d14eb3 414 #if defined __cplusplus
tylerwilson 0:3ab1d2d14eb3 415 extern "C"
tylerwilson 0:3ab1d2d14eb3 416 #endif
tylerwilson 0:3ab1d2d14eb3 417 const AMX_NATIVE_INFO time_Natives[] = {
tylerwilson 0:3ab1d2d14eb3 418 { "gettime", n_gettime },
tylerwilson 0:3ab1d2d14eb3 419 { "settime", n_settime },
tylerwilson 0:3ab1d2d14eb3 420 { "getdate", n_getdate },
tylerwilson 0:3ab1d2d14eb3 421 { "setdate", n_setdate },
tylerwilson 0:3ab1d2d14eb3 422 { "tickcount", n_tickcount },
tylerwilson 0:3ab1d2d14eb3 423 { "settimer", n_settimer },
tylerwilson 0:3ab1d2d14eb3 424 { "gettimer", n_gettimer },
tylerwilson 0:3ab1d2d14eb3 425 { "delay", n_delay },
tylerwilson 0:3ab1d2d14eb3 426 { "settimestamp", n_settimestamp },
tylerwilson 0:3ab1d2d14eb3 427 { "cvttimestamp", n_cvttimestamp },
tylerwilson 0:3ab1d2d14eb3 428 { NULL, NULL } /* terminator */
tylerwilson 0:3ab1d2d14eb3 429 };
tylerwilson 0:3ab1d2d14eb3 430
tylerwilson 0:3ab1d2d14eb3 431 int AMXEXPORT AMXAPI amx_TimeInit(AMX *amx)
tylerwilson 0:3ab1d2d14eb3 432 {
tylerwilson 0:3ab1d2d14eb3 433 #if !defined AMXTIME_NOIDLE
tylerwilson 0:3ab1d2d14eb3 434 /* see whether there is a @timer() function */
tylerwilson 0:3ab1d2d14eb3 435 if (amx_FindPublic(amx,"@timer",&idxTimer) == AMX_ERR_NONE) {
tylerwilson 0:3ab1d2d14eb3 436 if (amx_GetUserData(amx, AMX_USERTAG('I','d','l','e'), (void**)&PrevIdle) != AMX_ERR_NONE)
tylerwilson 0:3ab1d2d14eb3 437 PrevIdle = NULL;
tylerwilson 0:3ab1d2d14eb3 438 amx_SetUserData(amx, AMX_USERTAG('I','d','l','e'), amx_TimeIdle);
tylerwilson 0:3ab1d2d14eb3 439 } /* if */
tylerwilson 0:3ab1d2d14eb3 440 #endif
tylerwilson 0:3ab1d2d14eb3 441
tylerwilson 0:3ab1d2d14eb3 442 return amx_Register(amx, time_Natives, -1);
tylerwilson 0:3ab1d2d14eb3 443 }
tylerwilson 0:3ab1d2d14eb3 444
tylerwilson 0:3ab1d2d14eb3 445 int AMXEXPORT AMXAPI amx_TimeCleanup(AMX *amx)
tylerwilson 0:3ab1d2d14eb3 446 {
tylerwilson 0:3ab1d2d14eb3 447 (void)amx;
tylerwilson 0:3ab1d2d14eb3 448 #if !defined AMXTIME_NOIDLE
tylerwilson 0:3ab1d2d14eb3 449 PrevIdle = NULL;
tylerwilson 0:3ab1d2d14eb3 450 #endif
tylerwilson 0:3ab1d2d14eb3 451 return AMX_ERR_NONE;
tylerwilson 0:3ab1d2d14eb3 452 }