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/
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)
amxtime.c@0:3ab1d2d14eb3, 2012-11-15 (annotated)
- 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?
User | Revision | Line number | New 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(>m); |
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(>m); |
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 | } |