Ejemplo n.º 1
0
int pawnLoad( Pawn * p, const char * fileName )
{
  FILE *fp;
  AMX_HEADER hdr;
  int result, i;
  int32_t size;
  unsigned char * datablock;
  #define OVLPOOLSIZE 1024

  // open the file, read and check the header
  if ((fp = fopen(fileName, "rb")) == NULL)
    return AMX_ERR_NOTFOUND;
  p->fp = fp;

  fread(&hdr, sizeof hdr, 1, fp);
  amx_Align16(&hdr.magic);
  amx_Align16((uint16_t *)&hdr.flags);
  amx_Align32((uint32_t *)&hdr.size);
  amx_Align32((uint32_t *)&hdr.cod);
  amx_Align32((uint32_t *)&hdr.dat);
  amx_Align32((uint32_t *)&hdr.hea);
  amx_Align32((uint32_t *)&hdr.stp);
  if (hdr.magic != AMX_MAGIC) {
    fclose(fp);
    return AMX_ERR_FORMAT;
  } // if

  if ((hdr.flags & AMX_FLAG_OVERLAY) != 0)
    // allocate the block for the data + stack/heap, plus the complete file
    // header, plus the overlay pool
    size = (hdr.stp - hdr.dat) + hdr.cod + POOL_SZ;
  else
    size = hdr.stp;

  if( size > (STACK_SZ + POOL_SZ) )
  {
      fclose(fp);
      return AMX_ERR_MEMORY;
  }
  datablock = p->datablock;
  p->header = datablock;
  p->stack  = datablock + hdr.cod;
  p->pool   = datablock + hdr.cod + (hdr.stp - hdr.dat);

  // save the filename, for optionally reading the debug information (we could
  // also have read it here immediately); for reading overlays, we also need
  // the filename (and in this case, note that amx_Init() already browses
  // through all overlays)
  
  // read in the file, in two parts; first the header and then the data section
  rewind(fp);
  if ((hdr.flags & AMX_FLAG_OVERLAY) != 0) {
      // read the entire header
      fread(datablock, 1, hdr.cod, fp);
      // read the data section, put it behind the header in the block
      fseek(fp, hdr.dat, SEEK_SET);
      fread(datablock + hdr.cod, 1, hdr.hea - hdr.dat, fp);
      // initialize the overlay pool
      amx_poolinit(datablock + (hdr.stp - hdr.dat) + hdr.cod, OVLPOOLSIZE);
  } else {
    fread(datablock, 1, (size_t)hdr.size, fp);
  } // if
  //fclose(fp);

  // initialize the abstract machine
  for ( i=0; i<sizeof(p->amx); i++ )
      ((unsigned char *)&p->amx)[i] = 0;
  if ((hdr.flags & AMX_FLAG_OVERLAY) != 0)
  {
    p->amx.data = datablock + hdr.cod;
    p->amx.overlay = prun_Overlay;
  }
  else
  {
    fread(datablock, 1, (size_t)hdr.size, fp);
  }
  result = amx_Init( &p->amx, datablock);

  // free the memory block on error, if it was allocated here
  if (result != AMX_ERR_NONE)
  {
    p->amx.base = NULL;                   // avoid a double free
  } // if

  return result;

    /*AMX_HEADER hdr;
    int i;
    if ( !(p->fp = fopen( fileName, "rb" ) ) )
        return PAWN_ERR_FILE_OPEN;
    g_fp = p->fp;
    fread( &hdr, sizeof(hdr), 1, p->fp );
    amx_Align16( &hdr.magic );
    amx_Align16((uint16_t *)&hdr.flags);
    amx_Align32((uint32_t *)&hdr.size);
    amx_Align32((uint32_t *)&hdr.cod);
    amx_Align32((uint32_t *)&hdr.dat);
    amx_Align32((uint32_t *)&hdr.hea);
    amx_Align32((uint32_t *)&hdr.stp);
    if ( hdr.magic != AMX_MAGIC )
    {
        fclose( p->fp );
        return PAWN_ERR_FORMAT;
    }

    rewind( p->fp );
    fread( p->header, 1, hdr.cod, p->fp );
    fseek( p->fp, hdr.dat, SEEK_SET );
    fread( p->stack, 1, hdr.hea - hdr.dat, p->fp );

    amx_poolinit( p->pool, POOL_SZ );

    for ( i=0; i<sizeof(p->amx); i++ )
        ((unsigned char *)&p->amx)[i] = 0;
    p->amx.data    = p->stack;
    p->amx.overlay = prun_Overlay;
    i = amx_Init( &p->amx, p->header );
    return ( i == AMX_ERR_NONE ) ? PAWN_OK : PAWN_ERR_INIT;*/
}
Ejemplo n.º 2
0
/* aux_LoadProgram()
 * Load a compiled Pawn script into memory and initialize the abstract machine.
 * This function is extracted out of AMXAUX.C.
 */
int AMXAPI aux_LoadProgram(AMX *amx, char *filename)
{
  FILE *fp;
  AMX_HEADER hdr;
  int result;
  int32_t size;
  unsigned char *datablock;
  #define OVLPOOLSIZE 4096

  /* open the file, read and check the header */
  if ((fp = fopen(filename, "rb")) == NULL)
    return AMX_ERR_NOTFOUND;
  fread(&hdr, sizeof hdr, 1, fp);
  amx_Align16(&hdr.magic);
  amx_Align16((uint16_t *)&hdr.flags);
  amx_Align32((uint32_t *)&hdr.size);
  amx_Align32((uint32_t *)&hdr.cod);
  amx_Align32((uint32_t *)&hdr.dat);
  amx_Align32((uint32_t *)&hdr.hea);
  amx_Align32((uint32_t *)&hdr.stp);
  if (hdr.magic != AMX_MAGIC) {
    fclose(fp);
    return AMX_ERR_FORMAT;
  } /* if */

  if ((hdr.flags & AMX_FLAG_OVERLAY) != 0) {
    /* allocate the block for the data + stack/heap, plus the complete file
     * header, plus the overlay pool
     */
    #if defined AMXOVL
      size = (hdr.stp - hdr.dat) + hdr.cod + OVLPOOLSIZE;
    #else
      return AMX_ERR_OVERLAY;
    #endif
  } else {
    size = hdr.stp;
  } /* if */
  if ((datablock = malloc(size)) == NULL) {
    fclose(fp);
    return AMX_ERR_MEMORY;
  } /* if */

  /* save the filename, for optionally reading the debug information (we could
   * also have read it here immediately); for reading overlays, we also need
   * the filename (and in this case, note that amx_Init() already browses
   * through all overlays)
   */
  strcpy(g_filename, filename);

  /* read in the file, in two parts; first the header and then the data section */
  rewind(fp);
  if ((hdr.flags & AMX_FLAG_OVERLAY) != 0) {
    #if defined AMXOVL
      /* read the entire header */
      fread(datablock, 1, hdr.cod, fp);
      /* read the data section, put it behind the header in the block */
      fseek(fp, hdr.dat, SEEK_SET);
      fread(datablock + hdr.cod, 1, hdr.hea - hdr.dat, fp);
      /* initialize the overlay pool */
      amx_poolinit(datablock + (hdr.stp - hdr.dat) + hdr.cod, OVLPOOLSIZE);
    #endif
  } else {
    fread(datablock, 1, (size_t)hdr.size, fp);
  } /* if */
  fclose(fp);

  /* initialize the abstract machine */
  memset(amx, 0, sizeof *amx);
  #if defined AMXOVL
    if ((hdr.flags & AMX_FLAG_OVERLAY) != 0) {
      amx->data = datablock + hdr.cod;
      amx->overlay = prun_Overlay;
    } /* if */
  #endif
  result = amx_Init(amx, datablock);

  /* free the memory block on error, if it was allocated here */
  if (result != AMX_ERR_NONE) {
    free(datablock);
    amx->base = NULL;                   /* avoid a double free */
  } /* if */

  return result;
}
Ejemplo n.º 3
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;
}