int main(int argc,char *argv[]) { extern int amx_ConsoleInit(AMX *amx); extern int amx_ConsoleCleanup(AMX *amx); extern int amx_CoreInit(AMX *amx); extern int amx_CoredCleanp(AMX *amx); size_t memsize; void *program; AMX amx; int index, err; cell amx_addr, *phys_addr; char output[128]; if (argc != 4) PrintUsage(argv[0]); if ((memsize = aux_ProgramSize(argv[1])) == 0) PrintUsage(argv[0]); program = malloc(memsize); if (program == NULL) ErrorExit(NULL, AMX_ERR_MEMORY); err = aux_LoadProgram(&amx, argv[1], program); if (err) ErrorExit(&amx, err); amx_ConsoleInit(amx); err = amx_CoreInit(amx); if (err) ErrorExit(&amx, err); err = amx_FindPublic(&amx, argv[2], &index); if (err) ErrorExit(&amx, err); err = amx_Allot(&amx, strlen(argv[3]) + 1, &amx_addr, &phys_addr); if (err) ErrorExit(&amx, err); amx_SetString(phys_addr, argv[3], 0); err = amx_Exec(&amx, NULL, index, 1, amx_addr); if (err) ErrorExit(&amx, err); amx_GetString(output, phys_addr); amx_Release(&amx, amx_addr); printf("%s returns %s\n", argv[1], output); amx_ConsoleCleanup(&amx); amx_CoreCleanup(&amx); amx_Cleanup(&amx); free(program); return 0; }
bool CGamemodeManager::Load(char* gmFile) { if (this->gmIsInit) Unload(); FILE* f = fopen(gmFile, "rb"); if (!f) return false; fclose(f); memset((void*)&(this->gmAMX), 0, sizeof(AMX)); this->gmSleepTime = 0.0f; strcpy(szGameModeFileName, gmFile); int err = aux_LoadProgram(&(this->gmAMX), szGameModeFileName); if (err != AMX_ERR_NONE) { AMXPrintError(this, &(this->gmAMX), err); logprintf("Failed to load '%s' script.", szGameModeFileName); return false; } amx_CoreInit(&(this->gmAMX)); amx_FloatInit(&(this->gmAMX)); amx_StringInit(&(this->gmAMX)); amx_FileInit(&(this->gmAMX)); amx_TimeInit(&(this->gmAMX)); //amx_DGramInit(&(this->gmAMX)); amx_CustomInit(&(this->gmAMX)); amx_sampDbInit(&(this->gmAMX)); __Plugins->DoAmxLoad(&(this->gmAMX)); this->gmIsInit = true; int tmp; if (!amx_FindPublic(&(this->gmAMX), "OnGameModeInit", &tmp)) amx_Exec(&(this->gmAMX), (cell*)&tmp, tmp); __NetGame->filterscriptsManager->OnGameModeInit(); cell ret = 0; err = amx_Exec(&(this->gmAMX), &ret, AMX_EXEC_MAIN); if (err == AMX_ERR_SLEEP) { this->gmIsSleeping = true; this->gmSleepTime = ((float)ret / 1000.0f); } else if (err != AMX_ERR_NONE) { this->gmIsSleeping = false; AMXPrintError(this, &(this->gmAMX), err); } return true; }
int main(int argc, char *argv[]) { size_t memsize; void *program; AMX amx; cell ret = 0; int err; if (argc != 2 || (memsize = aux_ProgramSize(argv[1])) == 0) ErrorExit("Usage: PRUN3 <filename>\n\n" "The filename must include the extension", 0); program = VirtualAlloc(NULL, memsize, MEM_RESERVE, PAGE_READWRITE); if (program == NULL) ErrorExit("Failed to reserve memory", 0); __try { err = aux_LoadProgram(&amx, argv[1], program); if (err != AMX_ERR_NONE) ErrorExit("Load error %d (invalid file format or version mismatch)", err); signal(SIGINT,sigabort); amx_CoreInit(&amx); err = aux_RegisterNatives(&amx); if (err != AMX_ERR_NONE) ErrorExit("The program uses native functions that this run-time does not provide", 0); err = amx_Exec(&amx, &ret, AMX_EXEC_MAIN); while (err == AMX_ERR_SLEEP) err = amx_Exec(&amx, &ret, AMX_EXEC_CONT); if (err != AMX_ERR_NONE) printf("Run time error %d on address %ld\n", err, amx.cip); else if (ret != 0) printf("%s returns %ld\n", argv[1], (long)ret); } __except (aux_CommitMemory(GetExceptionInformation(), program, memsize)) { /* nothing */ } /* try */ /* Decommitting memory that is not committed does not fail, so you can just * decommit all memory. Releasing memory that is partially committed fails, * even if you also include the MEM_RELEASE flag (tested on WIndows98), so * you must call VirtualFree twice in a row. */ VirtualFree(program, memsize, MEM_DECOMMIT); VirtualFree(program, 0, MEM_RELEASE); amx_CoreCleanup(&amx); return 0; }
int main(int argc,char *argv[]) { AMX amx; cell ret = 0; int err; clock_t start,end; if (argc != 2) PrintUsage(argv[0]); /* function "usage" aborts the program */ if ((err = aux_LoadProgram(&amx, argv[1])) == AMX_ERR_NOTFOUND) { /* try adding an extension */ char filename[_MAX_PATH]; strcpy(filename, argv[1]); strcat(filename, ".amx"); err = aux_LoadProgram(&amx, filename); } /* if */ ExitOnError(&amx, err); amx_ConsoleInit(&amx); err = amx_CoreInit(&amx); ExitOnError(&amx, err); start=clock(); err = amx_Exec(&amx, &ret, AMX_EXEC_MAIN); while (err == AMX_ERR_SLEEP) err = amx_Exec(&amx, &ret, AMX_EXEC_CONT); end=clock(); ExitOnError(&amx, err); aux_FreeProgram(&amx); if (ret!=0) printf("\nReturn value: %ld\n", (long)ret); printf("\nRun time: %.2f seconds\n",(double)(end-start)/CLOCKS_PER_SEC); return 0; }
bool CNetwork::LoadScript(char *filename) { size_t memsize = aux_ProgramSize(filename); if(memsize == 0) { printf("Script file not found or corrupted\n"); return false; } memset((void*)&inimod_amx, 0, sizeof(AMX)); void * program = malloc(memsize); if (program == NULL) { printf("Memory allocation for script failed\n"); return false; } if(!LoadProgram(filename,program)) { printf("Loading script into Abstract Machine failed\n"); return false; } amx_CoreInit(&inimod_amx); amx_FloatInit(&inimod_amx); amx_StringInit(&inimod_amx); //amx_FileInit(&inimod_amx); amx_TimeInit(&inimod_amx); return true; }
int main(int argc,char *argv[]) { AMX amx; cell ret = 0; int err, i; clock_t start,end; STACKINFO stackinfo = { 0 }; AMX_IDLE idlefunc; if (argc < 2) PrintUsage(argv[0]); /* function "usage" aborts the program */ #if !defined AMX_NODYNALOAD && defined ENABLE_BINRELOC && (defined __LINUX__ || defined __FreeBSD__ || defined __OpenBSD__) /* see www.autopackage.org for the BinReloc module */ if (br_init(NULL)) { char *libroot=br_find_exe_dir(""); setenv("AMXLIB",libroot,0); free(libroot); } /* if */ #endif /* Load the program and initialize the abstract machine. */ err = aux_LoadProgram(&amx, argv[1]); if (err != AMX_ERR_NONE) { /* try adding an extension */ char filename[_MAX_PATH]; strcpy(filename, argv[1]); strcat(filename, ".amx"); err = aux_LoadProgram(&amx, filename); if (err != AMX_ERR_NONE) PrintUsage(argv[0]); } /* if */ /* To install the debug hook "just-in-time", the signal function needs * a pointer to the abstract machine(s) to abort. There are various ways * to implement this; here I have done so with a simple global variable. */ global_amx = &amx; signal(SIGINT, sigabort); /* Initialize two core extension modules (more extension modules may be * loaded & initialized automatically as DLLs or shared libraries. */ amx_ConsoleInit(&amx); err = amx_CoreInit(&amx); ExitOnError(&amx, err); /* save the idle function, if set by any of the extension modules */ if (amx_GetUserData(&amx, AMX_USERTAG('I','d','l','e'), (void**)&idlefunc) != AMX_ERR_NONE) idlefunc = NULL; for (i = 2; i < argc; i++) { if (strcmp(argv[i],"-stack") == 0) { uint16_t flags; amx_Flags(&amx, &flags); if ((flags & AMX_FLAG_NOCHECKS) != 0) printf("This script was compiled with debug information removed.\n" "Stack monitoring is disfunctional\n\n"); /* Set "user data" with which the debug monitor can monitor stack usage * per abstract machine (in this example, though, there is only one abstract * machine, so a global variable would have sufficed). */ memset(&stackinfo, 0, sizeof stackinfo); err = amx_SetUserData(&amx, AMX_USERTAG('S','t','c','k'), &stackinfo); ExitOnError(&amx, err); /* Install the debug hook, so that we can start monitoring the stack/heap * usage right from the beginning of the script. */ amx_SetDebugHook(&amx, prun_Monitor); } /* if */ } /* for */ start=clock(); /* Run the compiled script and time it. The "sleep" instruction causes the * abstract machine to return in a "restartable" state (it restarts from * the point that it stopped. This allows for a kind of light-weight * cooperative multi-tasking. As native functions (or the debug hook) can * also force an abstract machine to "sleep", you can also use it to create * "latent functions": functions that allow the host application to continue * processing, and/or other abstract machines to run, while they wait for * some resource. */ err = amx_Exec(&amx, &ret, AMX_EXEC_MAIN); while (err == AMX_ERR_SLEEP) { if (idlefunc != NULL) { /* If the abstract machine was put to sleep, we can handle events during * that time. To save the "restart point", we must make a copy of the AMX * (keeping the stack, frame, instruction pointer and other vital * registers), but without cloning the entire abstract machine. * There should be some criterion on when the abstract machine must be * "woken up". In this example run-time, the parameter of the sleep * instruction is taken to be a delay in milliseconds. In your own host * application, you can choose to wait on a resource/semaphore or other. */ AMX nested_amx = amx; clock_t stamp = clock(); while (((clock() - stamp)*1000)/CLOCKS_PER_SEC < amx.pri && (err = idlefunc(&nested_amx,amx_Exec)) == AMX_ERR_NONE) /* nothing */; ExitOnError(&nested_amx, err); } /* if */ err = amx_Exec(&amx, &ret, AMX_EXEC_CONT); } /* while */ if (idlefunc == NULL || err != AMX_ERR_INDEX) ExitOnError(&amx, err); /* event-driven programs may not have main() */ /* For event-driven programs, we also need to loop over the idle/monitor * function that some extension module installed (this could be the console * module, for example). We did this if the main program was put to "sleep", * but we do that here too. */ if (idlefunc != NULL) { while ((err = idlefunc(&amx,amx_Exec)) == AMX_ERR_NONE) /* nothing */; ExitOnError(&amx, err); } /* if */ end=clock(); /* Free the compiled script and resources. This also unloads and DLLs or * shared libraries that were registered automatically by amx_Init(). */ aux_FreeProgram(&amx); /* Print the return code of the compiled script (often not very useful), * its run time, and its stack usage. */ if (ret!=0) printf("\nReturn value: %ld\n", (long)ret); printf("\nRun time: %.2f seconds\n",(double)(end-start)/CLOCKS_PER_SEC); if (stackinfo.maxstack != 0 || stackinfo.maxheap != 0) { printf("Stack usage: %ld cells (%ld bytes)\n", stackinfo.maxstack / sizeof(cell), stackinfo.maxstack); printf("Heap usage: %ld cells (%ld bytes)\n", stackinfo.maxheap / sizeof(cell), stackinfo.maxheap); } /* if */ #if defined AMX_TERMINAL /* This is likely a graphical terminal, which should not be closed * automatically */ { extern int amx_termctl(int,int); while (amx_termctl(4,0)) /* nothing */; } #endif return 0; }
int main(int argc,char *argv[]) { AMX amx; cell ret = 0; int err; if (argc != 2) PrintUsage(argv[0]); /* function "usage" aborts the program */ /* Load the program and initialize the abstract machine. */ err = aux_LoadProgram(&amx, argv[1], NULL, srun_Monitor); if (err != AMX_ERR_NONE) { /* try adding an extension */ char filename[_MAX_PATH]; strcpy(filename, argv[1]); strcat(filename, ".amx"); err = aux_LoadProgram(&amx, filename, NULL, srun_Monitor); if (err != AMX_ERR_NONE) PrintUsage(argv[0]); } /* if */ /* Initialize two core extension modules (more extension modules may be * loaded & initialized automatically as DLLs or shared libraries. */ amx_ConsoleInit(&amx); amx_CoreInit(&amx); /* register functions for the bstring library */ err = amx_Register(&amx, bstring_Natives, -1); ExitOnError(&amx, err); /* Initialize the garbage collector, start with a small table. */ gc_setcallback((GC_FREE)bdestroy); err = gc_settable(7, GC_AUTOGROW); ExitOnError(&amx, err); /* Run the compiled script and time it. The "sleep" instruction causes the * abstract machine to return in a "restartable" state (it restarts from * the point that it stopped. This enables for a kind of light-weight * cooperative multi-tasking. As native functions (or the debug hook) can * also force an abstract machine to "sleep", you can also use it to create * "latent functions": functions that allow the host application to continue * processing, and/or other abstract machines to run, while they wait for * some resource. * In this example, there are no other abstract machines (there is just one) * and this "host" program has nothing else to do than run the abstract * machine. So if it detects a "sleep" it just restarts the abstract machine * immediately. */ err = amx_Exec(&amx, &ret, AMX_EXEC_MAIN, 0); while (err == AMX_ERR_SLEEP) err = amx_Exec(&amx, &ret, AMX_EXEC_CONT, 0); ExitOnError(&amx, err); /* Free the compiled script and resources. This also unloads and DLLs or * shared libraries that were registered automatically by amx_Init(). */ aux_FreeProgram(&amx); /* Free the garbarge collector data and tables. */ gc_settable(0); /* Print the return code of the compiled script (often not very useful). */ if (ret!=0) printf("\nReturn value: %ld\n", (long)ret); #if defined AMX_TERMINAL /* This is likely a graphical terminal, which should not be closed * automatically */ { extern int amx_termctl(int,int); while (amx_termctl(4,0)) /* nothing */; } #endif return 0; }
int loadprogram(const char *filename, char *error, size_t error_size) { FIL *file = &amx_file; FRESULT status = f_open(file, filename, FA_READ); if (status != FR_OK) { snprintf(error, error_size, "Could not open file %s: %d", filename, status); return AMX_ERR_NOTFOUND; } /* Read file header */ memset(&amx, 0, sizeof(amx)); AMX_HEADER hdr; UINT read_count; f_read(file, &hdr, sizeof hdr, &read_count); if (read_count != sizeof hdr || hdr.magic != AMX_MAGIC) return AMX_ERR_FORMAT; if (hdr.flags & AMX_FLAG_OVERLAY) { // Read the header f_lseek(file, 0); f_read(file, vm_data, hdr.cod, &read_count); // Read the data block f_lseek(file, hdr.dat); unsigned dat_size = hdr.hea - hdr.dat; f_read(file, vm_data + hdr.cod, dat_size, &read_count); if (read_count != dat_size) return AMX_ERR_FORMAT; unsigned static_size = (hdr.stp - hdr.dat) + hdr.cod; amx_poolinit(vm_data + static_size, sizeof(vm_data) - static_size); amx.base = vm_data; amx.data = vm_data + hdr.cod; overlay_init(&amx, amx_filename, &amx_file); } else { if (hdr.stp > sizeof(vm_data)) return AMX_ERR_MEMORY; /* Read the actual file, including the header (again) */ f_lseek(file, 0); f_read(file, vm_data, hdr.size, &read_count); if (read_count != hdr.size) return AMX_ERR_FORMAT; } AMXERRORS(amx_Init(&amx, vm_data)); amxinit_display(&amx); amx_CoreInit(&amx); amxinit_string(&amx); amxinit_fixed(&amx); amxinit_wavein(&amx); amxinit_waveout(&amx); amxinit_menu(&amx); amxinit_file(&amx); amxinit_buttons(&amx); amxinit_fourier(&amx); amxinit_time(&amx); amxinit_device(&amx); amxinit_fpga(&amx); // Check that everything has been registered int regstat = amx_Register(&amx, NULL, -1); if (regstat != 0) { // Find out what is missing for (int i = 0; i < NUMENTRIES((AMX_HEADER*)amx.base,natives,libraries); i++) { AMX_FUNCSTUB *func = GETENTRY((AMX_HEADER*)amx.base,natives,i); if (func->address == 0) { snprintf(error, error_size, "Native function not found: %s", GETENTRYNAME((AMX_HEADER*)amx.base,func)); return AMX_ERR_NOTFOUND; } } snprintf(error, error_size, "Error registering native functions"); return regstat; } return 0; }