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:
tylerwilson
Date:
Thu Nov 15 17:41:21 2012 +0000
Revision:
0:3ab1d2d14eb3
Child:
2:01588bd27169
Initial Pawn 4.x interpreter for mbed check-in

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 0:3ab1d2d14eb3 30 #define SECONDS_PER_MINUTE 60
tylerwilson 0:3ab1d2d14eb3 31 #define SECONDS_PER_HOUR 3600
tylerwilson 0:3ab1d2d14eb3 32 #define SECONDS_PER_DAY 86400
tylerwilson 0:3ab1d2d14eb3 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 int maxday;
tylerwilson 0:3ab1d2d14eb3 169
tylerwilson 0:3ab1d2d14eb3 170 #if defined __WIN32__ || defined _WIN32 || defined WIN32
tylerwilson 0:3ab1d2d14eb3 171 SYSTEMTIME systim;
tylerwilson 0:3ab1d2d14eb3 172
tylerwilson 0:3ab1d2d14eb3 173 GetLocalTime(&systim);
tylerwilson 0:3ab1d2d14eb3 174 if (year!=CELLMIN)
tylerwilson 0:3ab1d2d14eb3 175 systim.wYear=(WORD)wrap((int)year,1970,2099);
tylerwilson 0:3ab1d2d14eb3 176 if (month!=CELLMIN)
tylerwilson 0:3ab1d2d14eb3 177 systim.wMonth=(WORD)wrap((int)month,1,12);
tylerwilson 0:3ab1d2d14eb3 178 maxday=monthdays[systim.wMonth - 1];
tylerwilson 0:3ab1d2d14eb3 179 if (systim.wMonth==2 && ((systim.wYear % 4)==0 && ((systim.wYear % 100)!=0 || (systim.wYear % 400)==0)))
tylerwilson 0:3ab1d2d14eb3 180 maxday++;
tylerwilson 0:3ab1d2d14eb3 181 if (day!=CELLMIN)
tylerwilson 0:3ab1d2d14eb3 182 systim.wDay=(WORD)wrap((int)day,1,maxday);
tylerwilson 0:3ab1d2d14eb3 183 SetLocalTime(&systim);
tylerwilson 0:3ab1d2d14eb3 184 #else
tylerwilson 0:3ab1d2d14eb3 185 /* Linux/Unix (and some DOS compilers) have stime(); on Linux/Unix, you
tylerwilson 0:3ab1d2d14eb3 186 * must have "root" permission to call stime()
tylerwilson 0:3ab1d2d14eb3 187 */
tylerwilson 0:3ab1d2d14eb3 188 time_t sec1970;
tylerwilson 0:3ab1d2d14eb3 189 struct tm gtm;
tylerwilson 0:3ab1d2d14eb3 190
tylerwilson 0:3ab1d2d14eb3 191 time(&sec1970);
tylerwilson 0:3ab1d2d14eb3 192 gtm=*localtime(&sec1970);
tylerwilson 0:3ab1d2d14eb3 193 if (year!=CELLMIN)
tylerwilson 0:3ab1d2d14eb3 194 gtm.tm_year=year-1900;
tylerwilson 0:3ab1d2d14eb3 195 if (month!=CELLMIN)
tylerwilson 0:3ab1d2d14eb3 196 gtm.tm_mon=month-1;
tylerwilson 0:3ab1d2d14eb3 197 if (day!=CELLMIN)
tylerwilson 0:3ab1d2d14eb3 198 gtm.tm_mday=day;
tylerwilson 0:3ab1d2d14eb3 199 sec1970=mktime(&gtm);
tylerwilson 0:3ab1d2d14eb3 200 stime(&sec1970);
tylerwilson 0:3ab1d2d14eb3 201 #endif
tylerwilson 0:3ab1d2d14eb3 202 }
tylerwilson 0:3ab1d2d14eb3 203
tylerwilson 0:3ab1d2d14eb3 204
tylerwilson 0:3ab1d2d14eb3 205 /* settime(hour, minute, second)
tylerwilson 0:3ab1d2d14eb3 206 * Always returns 0
tylerwilson 0:3ab1d2d14eb3 207 */
tylerwilson 0:3ab1d2d14eb3 208 static cell AMX_NATIVE_CALL n_settime(AMX *amx, const cell *params)
tylerwilson 0:3ab1d2d14eb3 209 {
tylerwilson 0:3ab1d2d14eb3 210 (void)amx;
tylerwilson 0:3ab1d2d14eb3 211 settime(params[1],params[2],params[3]);
tylerwilson 0:3ab1d2d14eb3 212 return 0;
tylerwilson 0:3ab1d2d14eb3 213 }
tylerwilson 0:3ab1d2d14eb3 214
tylerwilson 0:3ab1d2d14eb3 215 /* gettime(&hour, &minute, &second)
tylerwilson 0:3ab1d2d14eb3 216 * The return value is the number of seconds since 1 January 1970 (Unix system
tylerwilson 0:3ab1d2d14eb3 217 * time).
tylerwilson 0:3ab1d2d14eb3 218 */
tylerwilson 0:3ab1d2d14eb3 219 static cell AMX_NATIVE_CALL n_gettime(AMX *amx, const cell *params)
tylerwilson 0:3ab1d2d14eb3 220 {
tylerwilson 0:3ab1d2d14eb3 221 time_t sec1970;
tylerwilson 0:3ab1d2d14eb3 222 struct tm gtm;
tylerwilson 0:3ab1d2d14eb3 223 cell *cptr;
tylerwilson 0:3ab1d2d14eb3 224
tylerwilson 0:3ab1d2d14eb3 225 assert(params[0]==(int)(3*sizeof(cell)));
tylerwilson 0:3ab1d2d14eb3 226
tylerwilson 0:3ab1d2d14eb3 227 time(&sec1970);
tylerwilson 0:3ab1d2d14eb3 228
tylerwilson 0:3ab1d2d14eb3 229 /* on DOS/Windows, the timezone is usually not set for the C run-time
tylerwilson 0:3ab1d2d14eb3 230 * library; in that case gmtime() and localtime() return the same value
tylerwilson 0:3ab1d2d14eb3 231 */
tylerwilson 0:3ab1d2d14eb3 232 gtm=*localtime(&sec1970);
tylerwilson 0:3ab1d2d14eb3 233 cptr=amx_Address(amx,params[1]);
tylerwilson 0:3ab1d2d14eb3 234 *cptr=gtm.tm_hour;
tylerwilson 0:3ab1d2d14eb3 235 cptr=amx_Address(amx,params[2]);
tylerwilson 0:3ab1d2d14eb3 236 *cptr=gtm.tm_min;
tylerwilson 0:3ab1d2d14eb3 237 cptr=amx_Address(amx,params[3]);
tylerwilson 0:3ab1d2d14eb3 238 *cptr=gtm.tm_sec;
tylerwilson 0:3ab1d2d14eb3 239
tylerwilson 0:3ab1d2d14eb3 240 /* the time() function returns the number of seconds since January 1 1970
tylerwilson 0:3ab1d2d14eb3 241 * in Universal Coordinated Time (the successor to Greenwich Mean Time)
tylerwilson 0:3ab1d2d14eb3 242 */
tylerwilson 0:3ab1d2d14eb3 243 return (cell)sec1970;
tylerwilson 0:3ab1d2d14eb3 244 }
tylerwilson 0:3ab1d2d14eb3 245
tylerwilson 0:3ab1d2d14eb3 246 /* setdate(year, month, day)
tylerwilson 0:3ab1d2d14eb3 247 * Always returns 0
tylerwilson 0:3ab1d2d14eb3 248 */
tylerwilson 0:3ab1d2d14eb3 249 static cell AMX_NATIVE_CALL n_setdate(AMX *amx, const cell *params)
tylerwilson 0:3ab1d2d14eb3 250 {
tylerwilson 0:3ab1d2d14eb3 251 (void)amx;
tylerwilson 0:3ab1d2d14eb3 252 setdate(params[1],params[2],params[3]);
tylerwilson 0:3ab1d2d14eb3 253 return 0;
tylerwilson 0:3ab1d2d14eb3 254 }
tylerwilson 0:3ab1d2d14eb3 255
tylerwilson 0:3ab1d2d14eb3 256 /* getdate(&year, &month, &day)
tylerwilson 0:3ab1d2d14eb3 257 * The return value is the number of days since the start of the year. January
tylerwilson 0:3ab1d2d14eb3 258 * 1 is day 1 of the year.
tylerwilson 0:3ab1d2d14eb3 259 */
tylerwilson 0:3ab1d2d14eb3 260 static cell AMX_NATIVE_CALL n_getdate(AMX *amx, const cell *params)
tylerwilson 0:3ab1d2d14eb3 261 {
tylerwilson 0:3ab1d2d14eb3 262 time_t sec1970;
tylerwilson 0:3ab1d2d14eb3 263 struct tm gtm;
tylerwilson 0:3ab1d2d14eb3 264 cell *cptr;
tylerwilson 0:3ab1d2d14eb3 265
tylerwilson 0:3ab1d2d14eb3 266 assert(params[0]==(int)(3*sizeof(cell)));
tylerwilson 0:3ab1d2d14eb3 267
tylerwilson 0:3ab1d2d14eb3 268 time(&sec1970);
tylerwilson 0:3ab1d2d14eb3 269
tylerwilson 0:3ab1d2d14eb3 270 gtm=*localtime(&sec1970);
tylerwilson 0:3ab1d2d14eb3 271 cptr=amx_Address(amx,params[1]);
tylerwilson 0:3ab1d2d14eb3 272 *cptr=gtm.tm_year+1900;
tylerwilson 0:3ab1d2d14eb3 273 cptr=amx_Address(amx,params[2]);
tylerwilson 0:3ab1d2d14eb3 274 *cptr=gtm.tm_mon+1;
tylerwilson 0:3ab1d2d14eb3 275 cptr=amx_Address(amx,params[3]);
tylerwilson 0:3ab1d2d14eb3 276 *cptr=gtm.tm_mday;
tylerwilson 0:3ab1d2d14eb3 277
tylerwilson 0:3ab1d2d14eb3 278 return gtm.tm_yday+1;
tylerwilson 0:3ab1d2d14eb3 279 }
tylerwilson 0:3ab1d2d14eb3 280
tylerwilson 0:3ab1d2d14eb3 281 /* tickcount(&granularity)
tylerwilson 0:3ab1d2d14eb3 282 * Returns the number of milliseconds since start-up. For a 32-bit cell, this
tylerwilson 0:3ab1d2d14eb3 283 * count overflows after approximately 24 days of continuous operation.
tylerwilson 0:3ab1d2d14eb3 284 */
tylerwilson 0:3ab1d2d14eb3 285 static cell AMX_NATIVE_CALL n_tickcount(AMX *amx, const cell *params)
tylerwilson 0:3ab1d2d14eb3 286 {
tylerwilson 0:3ab1d2d14eb3 287 cell *cptr;
tylerwilson 0:3ab1d2d14eb3 288
tylerwilson 0:3ab1d2d14eb3 289 assert(params[0]==(int)sizeof(cell));
tylerwilson 0:3ab1d2d14eb3 290
tylerwilson 0:3ab1d2d14eb3 291 INIT_TIMER();
tylerwilson 0:3ab1d2d14eb3 292 cptr=amx_Address(amx,params[1]);
tylerwilson 0:3ab1d2d14eb3 293 #if defined __WIN32__ || defined _WIN32 || defined WIN32
tylerwilson 0:3ab1d2d14eb3 294 *cptr=1000; /* granularity = 1 ms */
tylerwilson 0:3ab1d2d14eb3 295 #else
tylerwilson 0:3ab1d2d14eb3 296 *cptr=(cell)CLOCKS_PER_SEC; /* in Unix/Linux, this is often 100 */
tylerwilson 0:3ab1d2d14eb3 297 #endif
tylerwilson 0:3ab1d2d14eb3 298 return gettimestamp() & 0x7fffffff;
tylerwilson 0:3ab1d2d14eb3 299 }
tylerwilson 0:3ab1d2d14eb3 300
tylerwilson 0:3ab1d2d14eb3 301 /* delay(milliseconds)
tylerwilson 0:3ab1d2d14eb3 302 * Pauses for (at least) the requested number of milliseconds.
tylerwilson 0:3ab1d2d14eb3 303 */
tylerwilson 0:3ab1d2d14eb3 304 static cell AMX_NATIVE_CALL n_delay(AMX *amx, const cell *params)
tylerwilson 0:3ab1d2d14eb3 305 {
tylerwilson 0:3ab1d2d14eb3 306 unsigned long stamp;
tylerwilson 0:3ab1d2d14eb3 307
tylerwilson 0:3ab1d2d14eb3 308 (void)amx;
tylerwilson 0:3ab1d2d14eb3 309 assert(params[0]==(int)sizeof(cell));
tylerwilson 0:3ab1d2d14eb3 310
tylerwilson 0:3ab1d2d14eb3 311 INIT_TIMER();
tylerwilson 0:3ab1d2d14eb3 312 stamp=gettimestamp();
tylerwilson 0:3ab1d2d14eb3 313 while (gettimestamp()-stamp < (unsigned long)params[1])
tylerwilson 0:3ab1d2d14eb3 314 /* nothing */;
tylerwilson 0:3ab1d2d14eb3 315 return 0;
tylerwilson 0:3ab1d2d14eb3 316 }
tylerwilson 0:3ab1d2d14eb3 317
tylerwilson 0:3ab1d2d14eb3 318 /* settimer(milliseconds, bool: singleshot = false)
tylerwilson 0:3ab1d2d14eb3 319 * Sets the delay until the @timer() callback is called. The timer may either
tylerwilson 0:3ab1d2d14eb3 320 * be single-shot or repetitive.
tylerwilson 0:3ab1d2d14eb3 321 */
tylerwilson 0:3ab1d2d14eb3 322 static cell AMX_NATIVE_CALL n_settimer(AMX *amx, const cell *params)
tylerwilson 0:3ab1d2d14eb3 323 {
tylerwilson 0:3ab1d2d14eb3 324 (void)amx;
tylerwilson 0:3ab1d2d14eb3 325 assert(params[0]==(int)(2*sizeof(cell)));
tylerwilson 0:3ab1d2d14eb3 326 timestamp=gettimestamp();
tylerwilson 0:3ab1d2d14eb3 327 timelimit=params[1];
tylerwilson 0:3ab1d2d14eb3 328 timerepeat=(int)(params[2]==0);
tylerwilson 0:3ab1d2d14eb3 329 return 0;
tylerwilson 0:3ab1d2d14eb3 330 }
tylerwilson 0:3ab1d2d14eb3 331
tylerwilson 0:3ab1d2d14eb3 332 /* bool: gettimer(&milliseconds, bool: &singleshot = false)
tylerwilson 0:3ab1d2d14eb3 333 * Retrieves the timer set with settimer(); returns true if a timer
tylerwilson 0:3ab1d2d14eb3 334 * was set up, or false otherwise.
tylerwilson 0:3ab1d2d14eb3 335 */
tylerwilson 0:3ab1d2d14eb3 336 static cell AMX_NATIVE_CALL n_gettimer(AMX *amx, const cell *params)
tylerwilson 0:3ab1d2d14eb3 337 {
tylerwilson 0:3ab1d2d14eb3 338 cell *cptr;
tylerwilson 0:3ab1d2d14eb3 339
tylerwilson 0:3ab1d2d14eb3 340 assert(params[0]==(int)(2*sizeof(cell)));
tylerwilson 0:3ab1d2d14eb3 341 cptr=amx_Address(amx,params[1]);
tylerwilson 0:3ab1d2d14eb3 342 *cptr=timelimit;
tylerwilson 0:3ab1d2d14eb3 343 cptr=amx_Address(amx,params[2]);
tylerwilson 0:3ab1d2d14eb3 344 *cptr=timerepeat;
tylerwilson 0:3ab1d2d14eb3 345 return timelimit>0;
tylerwilson 0:3ab1d2d14eb3 346 }
tylerwilson 0:3ab1d2d14eb3 347
tylerwilson 0:3ab1d2d14eb3 348 /* settimestamp(seconds1970) sets the date and time from a single parameter: the
tylerwilson 0:3ab1d2d14eb3 349 * number of seconds since 1 January 1970.
tylerwilson 0:3ab1d2d14eb3 350 */
tylerwilson 0:3ab1d2d14eb3 351 static cell AMX_NATIVE_CALL n_settimestamp(AMX *amx, const cell *params)
tylerwilson 0:3ab1d2d14eb3 352 {
tylerwilson 0:3ab1d2d14eb3 353 #if defined __WIN32__ || defined _WIN32 || defined WIN32
tylerwilson 0:3ab1d2d14eb3 354 int year, month, day, hour, minute, second;
tylerwilson 0:3ab1d2d14eb3 355
tylerwilson 0:3ab1d2d14eb3 356 stamp2datetime(params[1],
tylerwilson 0:3ab1d2d14eb3 357 &year, &month, &day,
tylerwilson 0:3ab1d2d14eb3 358 &hour, &minute, &second);
tylerwilson 0:3ab1d2d14eb3 359 setdate(year, month, day);
tylerwilson 0:3ab1d2d14eb3 360 settime(hour, minute, second);
tylerwilson 0:3ab1d2d14eb3 361 #else
tylerwilson 0:3ab1d2d14eb3 362 /* Linux/Unix (and some DOS compilers) have stime(); on Linux/Unix, you
tylerwilson 0:3ab1d2d14eb3 363 * must have "root" permission to call stime()
tylerwilson 0:3ab1d2d14eb3 364 */
tylerwilson 0:3ab1d2d14eb3 365 time_t sec1970=(time_t)params[1];
tylerwilson 0:3ab1d2d14eb3 366 stime(&sec1970);
tylerwilson 0:3ab1d2d14eb3 367 #endif
tylerwilson 0:3ab1d2d14eb3 368 (void)amx;
tylerwilson 0:3ab1d2d14eb3 369
tylerwilson 0:3ab1d2d14eb3 370 return 0;
tylerwilson 0:3ab1d2d14eb3 371 }
tylerwilson 0:3ab1d2d14eb3 372
tylerwilson 0:3ab1d2d14eb3 373 /* cvttimestamp(seconds1970, &year, &month, &day, &hour, &minute, &second)
tylerwilson 0:3ab1d2d14eb3 374 */
tylerwilson 0:3ab1d2d14eb3 375 static cell AMX_NATIVE_CALL n_cvttimestamp(AMX *amx, const cell *params)
tylerwilson 0:3ab1d2d14eb3 376 {
tylerwilson 0:3ab1d2d14eb3 377 int year, month, day, hour, minute, second;
tylerwilson 0:3ab1d2d14eb3 378
tylerwilson 0:3ab1d2d14eb3 379 (void)amx;
tylerwilson 0:3ab1d2d14eb3 380 stamp2datetime(params[1],
tylerwilson 0:3ab1d2d14eb3 381 &year, &month, &day,
tylerwilson 0:3ab1d2d14eb3 382 &hour, &minute, &second);
tylerwilson 0:3ab1d2d14eb3 383 return 0;
tylerwilson 0:3ab1d2d14eb3 384 }
tylerwilson 0:3ab1d2d14eb3 385
tylerwilson 0:3ab1d2d14eb3 386
tylerwilson 0:3ab1d2d14eb3 387 #if !defined AMXTIME_NOIDLE
tylerwilson 0:3ab1d2d14eb3 388 static AMX_IDLE PrevIdle = NULL;
tylerwilson 0:3ab1d2d14eb3 389 static int idxTimer = -1;
tylerwilson 0:3ab1d2d14eb3 390
tylerwilson 0:3ab1d2d14eb3 391 static int AMXAPI amx_TimeIdle(AMX *amx, int AMXAPI Exec(AMX *, cell *, int))
tylerwilson 0:3ab1d2d14eb3 392 {
tylerwilson 0:3ab1d2d14eb3 393 int err=0;
tylerwilson 0:3ab1d2d14eb3 394
tylerwilson 0:3ab1d2d14eb3 395 assert(idxTimer >= 0);
tylerwilson 0:3ab1d2d14eb3 396
tylerwilson 0:3ab1d2d14eb3 397 if (PrevIdle != NULL)
tylerwilson 0:3ab1d2d14eb3 398 PrevIdle(amx, Exec);
tylerwilson 0:3ab1d2d14eb3 399
tylerwilson 0:3ab1d2d14eb3 400 if (timelimit>0 && (gettimestamp()-timestamp)>=timelimit) {
tylerwilson 0:3ab1d2d14eb3 401 if (timerepeat)
tylerwilson 0:3ab1d2d14eb3 402 timestamp+=timelimit;
tylerwilson 0:3ab1d2d14eb3 403 else
tylerwilson 0:3ab1d2d14eb3 404 timelimit=0; /* do not repeat single-shot timer */
tylerwilson 0:3ab1d2d14eb3 405 err = Exec(amx, NULL, idxTimer);
tylerwilson 0:3ab1d2d14eb3 406 while (err == AMX_ERR_SLEEP)
tylerwilson 0:3ab1d2d14eb3 407 err = Exec(amx, NULL, AMX_EXEC_CONT);
tylerwilson 0:3ab1d2d14eb3 408 } /* if */
tylerwilson 0:3ab1d2d14eb3 409
tylerwilson 0:3ab1d2d14eb3 410 return err;
tylerwilson 0:3ab1d2d14eb3 411 }
tylerwilson 0:3ab1d2d14eb3 412 #endif
tylerwilson 0:3ab1d2d14eb3 413
tylerwilson 0:3ab1d2d14eb3 414
tylerwilson 0:3ab1d2d14eb3 415 #if defined __cplusplus
tylerwilson 0:3ab1d2d14eb3 416 extern "C"
tylerwilson 0:3ab1d2d14eb3 417 #endif
tylerwilson 0:3ab1d2d14eb3 418 const AMX_NATIVE_INFO time_Natives[] = {
tylerwilson 0:3ab1d2d14eb3 419 { "gettime", n_gettime },
tylerwilson 0:3ab1d2d14eb3 420 { "settime", n_settime },
tylerwilson 0:3ab1d2d14eb3 421 { "getdate", n_getdate },
tylerwilson 0:3ab1d2d14eb3 422 { "setdate", n_setdate },
tylerwilson 0:3ab1d2d14eb3 423 { "tickcount", n_tickcount },
tylerwilson 0:3ab1d2d14eb3 424 { "settimer", n_settimer },
tylerwilson 0:3ab1d2d14eb3 425 { "gettimer", n_gettimer },
tylerwilson 0:3ab1d2d14eb3 426 { "delay", n_delay },
tylerwilson 0:3ab1d2d14eb3 427 { "settimestamp", n_settimestamp },
tylerwilson 0:3ab1d2d14eb3 428 { "cvttimestamp", n_cvttimestamp },
tylerwilson 0:3ab1d2d14eb3 429 { NULL, NULL } /* terminator */
tylerwilson 0:3ab1d2d14eb3 430 };
tylerwilson 0:3ab1d2d14eb3 431
tylerwilson 0:3ab1d2d14eb3 432 int AMXEXPORT AMXAPI amx_TimeInit(AMX *amx)
tylerwilson 0:3ab1d2d14eb3 433 {
tylerwilson 0:3ab1d2d14eb3 434 #if !defined AMXTIME_NOIDLE
tylerwilson 0:3ab1d2d14eb3 435 /* see whether there is a @timer() function */
tylerwilson 0:3ab1d2d14eb3 436 if (amx_FindPublic(amx,"@timer",&idxTimer) == AMX_ERR_NONE) {
tylerwilson 0:3ab1d2d14eb3 437 if (amx_GetUserData(amx, AMX_USERTAG('I','d','l','e'), (void**)&PrevIdle) != AMX_ERR_NONE)
tylerwilson 0:3ab1d2d14eb3 438 PrevIdle = NULL;
tylerwilson 0:3ab1d2d14eb3 439 amx_SetUserData(amx, AMX_USERTAG('I','d','l','e'), amx_TimeIdle);
tylerwilson 0:3ab1d2d14eb3 440 } /* if */
tylerwilson 0:3ab1d2d14eb3 441 #endif
tylerwilson 0:3ab1d2d14eb3 442
tylerwilson 0:3ab1d2d14eb3 443 return amx_Register(amx, time_Natives, -1);
tylerwilson 0:3ab1d2d14eb3 444 }
tylerwilson 0:3ab1d2d14eb3 445
tylerwilson 0:3ab1d2d14eb3 446 int AMXEXPORT AMXAPI amx_TimeCleanup(AMX *amx)
tylerwilson 0:3ab1d2d14eb3 447 {
tylerwilson 0:3ab1d2d14eb3 448 (void)amx;
tylerwilson 0:3ab1d2d14eb3 449 #if !defined AMXTIME_NOIDLE
tylerwilson 0:3ab1d2d14eb3 450 PrevIdle = NULL;
tylerwilson 0:3ab1d2d14eb3 451 #endif
tylerwilson 0:3ab1d2d14eb3 452 return AMX_ERR_NONE;
tylerwilson 0:3ab1d2d14eb3 453 }