示例#1
0
文件: uade.c 项目: Kinglions/modizer
/* if kill_it is zero, uade may switch to next subsong. if kill_it is non-zero
   uade will always switch to next song (if any) */
void uade_song_end(char *reason, int kill_it)
{
  uint8_t space[sizeof(struct uade_msg) + 4 + 256];
  struct uade_msg *um = (struct uade_msg *) space;
  um->msgtype = UADE_REPLY_SONG_END;
  ((uint32_t *) um->data)[0] = htonl(((intptr_t) sndbufpt) - ((intptr_t) sndbuffer));
  ((uint32_t *) um->data)[1] = htonl(kill_it);
  strlcpy((char *) um->data + 8, reason, 256);
  um->size = 8 + strlen(reason) + 1;
  if (uade_send_message(um, &uadeipc)) {
    fprintf(stderr, "uadecore: Could not send song end message.\n");
    exit(-1);
  }
  /* if audio_output is zero (and thus the client is waiting for the first
     sound data block from this song), then start audio output so that the
     clients first sound finishes ASAP and we can go to the next (sub)song.
     uade must finish the pending sound data request (for the client) even if
     the sound core crashed */
  uade_audio_output = 1;
}
示例#2
0
文件: uade.c 项目: Kinglions/modizer
/* last part of the audio system pipeline */
void uade_check_sound_buffers(int bytes)
{
  uint8_t space[UADE_MAX_MESSAGE_SIZE];
  struct uade_msg *um = (struct uade_msg *) space;

//YOYO optimization : no swap since I'm using no network but only buffers
	
  /* transmit in big endian format, so swap if little endian */
//  if (uade_big_endian == 0)
//    uade_swap_buffer_bytes(sndbuffer, bytes);

  /* LED state changes are reported here because we are in send state and
     this place is heavily rate limited. */
  if (old_ledstate != gui_ledstate) {
    old_ledstate = gui_ledstate;
    uade_send_debug("LED is %s", gui_ledstate ? "ON" : "OFF");
  }

  um->msgtype = UADE_REPLY_DATA;
  um->size = bytes;
  memcpy(um->data, sndbuffer, bytes);
  if (uade_send_message(um, &uadeipc)) {
    fprintf(stderr, "uadecore: Could not send sample data.\n");
    exit(-1);
  }

  uade_read_size -= bytes;
  assert(uade_read_size >= 0);

  if (uade_read_size == 0) {
    /* if all requested data has been sent, move to S state */
    if (uade_send_short_message(UADE_COMMAND_TOKEN, &uadeipc)) {
      fprintf(stderr, "uadecore: Could not send token (after samples).\n");
      exit(-1);
    }
    uade_handle_r_state();
  }
}
示例#3
0
文件: uade.c 项目: Kinglions/modizer
void uade_get_amiga_message(void)
{
  uae_u8 *ptr;
  uae_u8 *nameptr;
  FILE *file;
  int x;
  unsigned int mins, maxs, curs;
  int status;
  int src, dst, off, len;
  char tmpstr[256];
  char *srcstr, *dststr;

  uint32_t *u32ptr;
  uint8_t space[256];
  struct uade_msg *um = (struct uade_msg *) space;

  x = uade_get_u32(SCORE_INPUT_MSG);  /* message type from amiga */

  switch (x) {

  case AMIGAMSG_SONG_END:
    uade_song_end("player", 0);
    break;

  case AMIGAMSG_SUBSINFO:
    mins = uade_get_u32(SCORE_MIN_SUBSONG);
    maxs = uade_get_u32(SCORE_MAX_SUBSONG);
    curs = uade_get_u32(SCORE_CUR_SUBSONG);
    /* Brain damage in TFMX BC Kid Despair */
    if (maxs < mins) {
      uade_send_debug("Odd subsongs. Eagleplayer reported (min, cur, max) == (%u, %u, %u)", mins, curs, maxs);
      maxs = mins;
    }
    /* Brain damage in Bubble bobble custom */
    if (curs > maxs) {
      uade_send_debug("Odd subsongs. Eagleplayer reported (min, cur, max) == (%u, %u, %u)", mins, curs, maxs);
      maxs = curs;
    }
    um->msgtype = UADE_REPLY_SUBSONG_INFO;
    um->size = 12;
    u32ptr = (uint32_t *) um->data;
    u32ptr[0] = htonl(mins);
    u32ptr[1] = htonl(maxs);
    u32ptr[2] = htonl(curs);
    if (uade_send_message(um, &uadeipc)) {
      fprintf(stderr, "uadecore: Could not send subsong info message.\n");
      exit(-1);
    }
    break;

  case AMIGAMSG_PLAYERNAME:
    strlcpy(tmpstr, (char *) get_real_address(0x204), sizeof tmpstr);
    uade_send_string(UADE_REPLY_PLAYERNAME, tmpstr, &uadeipc);
    break;

  case AMIGAMSG_MODULENAME:
    strlcpy(tmpstr, (char *) get_real_address(0x204), sizeof tmpstr);
    uade_send_string(UADE_REPLY_MODULENAME, tmpstr, &uadeipc);
    break;

  case AMIGAMSG_FORMATNAME:
    strlcpy(tmpstr, (char *) get_real_address(0x204), sizeof tmpstr);
    uade_send_string(UADE_REPLY_FORMATNAME, tmpstr, &uadeipc);
    break;

  case AMIGAMSG_GENERALMSG:
    uade_send_debug((char *) get_real_address(0x204));
    break;

  case AMIGAMSG_CHECKERROR:
    uade_song_end("module check failed", 1);
    break;

  case AMIGAMSG_SCORECRASH:
    if (uade_debug) {
      fprintf(stderr, "uadecore: Score crashed.\n");
      activate_debugger();
      break;
    }
    uade_song_end("score crashed", 1);
    break;

  case AMIGAMSG_SCOREDEAD:
     if (uade_debug) {
      fprintf(stderr, "uadecore: Score is dead.\n"); 
      activate_debugger();
      break;
    }
     uade_song_end("score died", 1);
    break;

  case AMIGAMSG_LOADFILE:
    /* load a file named at 0x204 (name pointer) to address pointed by
       0x208 and insert the length to 0x20C */
    src = uade_get_u32(0x204);
    if (!uade_valid_string(src)) {
      fprintf(stderr, "uadecore: Load name in invalid address range.\n");
      break;
    }
    nameptr = get_real_address(src);
    if ((file = uade_open_amiga_file((char *) nameptr, uade_player_dir))) {
      dst = uade_get_u32(0x208);
      len = uade_safe_load(dst, file, uade_highmem - dst);
      fclose(file); file = NULL;
      uade_put_long(0x20C, len);
      uade_send_debug("load success: %s ptr 0x%x size 0x%x", nameptr, dst, len);
    } else {
      uade_send_debug("load: file not found: %s", nameptr);
    }
    break;

  case AMIGAMSG_READ:
    src = uade_get_u32(0x204);
    if (!uade_valid_string(src)) {
      fprintf(stderr, "uadecore: Read name in invalid address range.\n");
      break;
    }
    nameptr = get_real_address(src);
    dst = uade_get_u32(0x208);
    off = uade_get_u32(0x20C);
    len = uade_get_u32(0x210);
    if ((file = uade_open_amiga_file((char *) nameptr, uade_player_dir))) {
      if (fseek(file, off, SEEK_SET)) {
	perror("can not fseek to position");
	x = 0;
      } else {
	x = uade_safe_load(dst, file, len);
	if (x > len)
	  x = len;
      }
      fclose(file);
      uade_send_debug("read %s dst 0x%x off 0x%x len 0x%x res 0x%x", nameptr, dst, off, len, x);
      uade_put_long(0x214, x);
    } else {
      uade_send_debug("read: file not found: %s", nameptr);
      uade_put_long(0x214, 0);
    }
    break;

  case AMIGAMSG_FILESIZE:
    src = uade_get_u32(0x204);
    if (!uade_valid_string(src)) {
      fprintf(stderr, "uadecore: Filesize name in invalid address range.\n");
      break;
    }
    nameptr = get_real_address(src);
    if ((file = uade_open_amiga_file((char *) nameptr, uade_player_dir))) {
      fseek(file, 0, SEEK_END);
      len = ftell(file);
      fclose(file);
      uade_put_long(0x208, len);
      uade_put_long(0x20C, -1);
      uade_send_debug("filesize: file %s res 0x%x", nameptr, len);
    } else {
      uade_put_long(0x208, 0);
      uade_put_long(0x20C, 0);
      uade_send_debug("filesize: file not found: %s", nameptr);
    }
    break;

  case AMIGAMSG_TIME_CRITICAL:
    uade_time_critical = uade_get_u32(0x204) ? 1 : 0;
    if (uade_speed_hack < 0) {
      /* a negative value forbids use of speed hack */
      uade_time_critical = 0;
    }
    break;

  case AMIGAMSG_GET_INFO:
    src = uade_get_u32(0x204);
    dst = uade_get_u32(0x208);
    len = uade_get_u32(0x20C);
    if (!uade_valid_string(src)) {
      fprintf(stderr, "uadecore: get info: Invalid src: 0x%x\n", src);
      break;
    }
    if (len <= 0) {
      fprintf(stderr, "uadecore: get info: len = %d\n", len);
      break;
    }
    if (!valid_address(dst, len)) {
      fprintf(stderr, "uadecore: get info: Invalid dst: 0x%x\n", dst);
      break;
    }
    srcstr = (char *) get_real_address(src);
    dststr = (char *) get_real_address(dst);
    uade_send_debug("score issued an info request: %s (maxlen %d)\n", srcstr, len);
    len = get_info_for_ep(dststr, srcstr, len);
    /* Send printable debug */
    do {
      size_t i;
      size_t maxspace = sizeof space;
      if (len <= 0) {
	maxspace = 1;
      } else {
	if (len < maxspace)
	  maxspace = len;
      }
      for (i = 0; i < maxspace; i++) {
	space[i] = dststr[i];
	if (space[i] == 0)
	  space[i] = ' ';
      }
      if (i < maxspace) {
	space[i] = 0;
      } else {
	space[maxspace - 1] = 0;
      }
      uade_send_debug("reply to score: %s (total len %d)\n", space, len);
    } while (0);
    uade_put_long(0x20C, len);
    break;

  case AMIGAMSG_START_OUTPUT:
    uade_audio_output = 1;
    uade_send_debug("Starting audio output at %d", uade_audio_skip);
    break;

  default:
    fprintf(stderr,"uadecore: Unknown message from score (%d)\n", x);
    break;
  }
}
示例#4
0
void uadecore_get_amiga_message(void)
{
  uae_u8 *ptr;
  uae_u8 *nameptr;
  int x;
  unsigned int mins, maxs, curs;
  int status;
  int src, dst, len;
  size_t off;
  char tmpstr[256];
  char *srcstr, *dststr;
  struct uade_file *f;
  uint32_t *u32ptr;
  uint8_t space[256];
  struct uade_msg *um = (struct uade_msg *) space;

  x = amiga_get_u32(SCORE_INPUT_MSG);  /* message type from amiga */

  switch (x) {

  case AMIGAMSG_SONG_END:
    uadecore_song_end("player", 0);
    break;

  case AMIGAMSG_SUBSINFO:
    mins = amiga_get_u32(SCORE_MIN_SUBSONG);
    maxs = amiga_get_u32(SCORE_MAX_SUBSONG);
    curs = amiga_get_u32(SCORE_CUR_SUBSONG);
    /* Brain damage in TFMX BC Kid Despair */
    if (maxs < mins) {
      uadecore_send_debug("Odd subsongs. Eagleplayer reported (min, cur, max) == (%u, %u, %u)", mins, curs, maxs);
      maxs = mins;
    }
    /* Brain damage in Bubble bobble custom */
    if (curs > maxs) {
      uadecore_send_debug("Odd subsongs. Eagleplayer reported (min, cur, max) == (%u, %u, %u)", mins, curs, maxs);
      maxs = curs;
    }
    um->msgtype = UADE_REPLY_SUBSONG_INFO;
    um->size = 12;
    u32ptr = (uint32_t *) um->data;
    u32ptr[0] = htonl(mins);
    u32ptr[1] = htonl(maxs);
    u32ptr[2] = htonl(curs);
    if (uade_send_message(um, &uadecore_ipc)) {
      fprintf(stderr, "uadecore: Could not send subsong info message.\n");
      exit(1);
    }
    break;

  case AMIGAMSG_PLAYERNAME:
    strlcpy(tmpstr, (char *) get_real_address(0x204), sizeof tmpstr);
    uade_send_string(UADE_REPLY_PLAYERNAME, tmpstr, &uadecore_ipc);
    break;

  case AMIGAMSG_MODULENAME:
    strlcpy(tmpstr, (char *) get_real_address(0x204), sizeof tmpstr);
    uade_send_string(UADE_REPLY_MODULENAME, tmpstr, &uadecore_ipc);
    break;

  case AMIGAMSG_FORMATNAME:
    strlcpy(tmpstr, (char *) get_real_address(0x204), sizeof tmpstr);
    uade_send_string(UADE_REPLY_FORMATNAME, tmpstr, &uadecore_ipc);
    break;

  case AMIGAMSG_GENERALMSG:
    uadecore_send_debug((char *) get_real_address(0x204));
    break;

  case AMIGAMSG_CHECKERROR:
    uadecore_song_end("module check failed", 1);
    break;

  case AMIGAMSG_SCORECRASH:
    if (uadecore_debug) {
      fprintf(stderr, "uadecore: Score crashed.\n");
      activate_debugger();
      break;
    }
    uadecore_song_end("score crashed", 1);
    break;

  case AMIGAMSG_SCOREDEAD:
     if (uadecore_debug) {
      fprintf(stderr, "uadecore: Score is dead.\n");
      activate_debugger();
      break;
    }
     uadecore_song_end("score died", 1);
    break;

  case AMIGAMSG_LOADFILE:
    /*
     * Load a file named at 0x204 (name pointer) to address pointed by
     * 0x208 and insert the length to 0x20C.
     * For example, R-Type (TFMX format) uses this.
     */
    src = amiga_get_u32(0x204);
    if (!uade_valid_string(src)) {
	    fprintf(stderr, "uadecore: Load name in invalid address range.\n");
	    break;
    }
    nameptr = get_real_address(src);
    f = lookup_amiga_file_cache((const char *) nameptr);
    if (f == NULL) {
	    uadecore_send_debug("load: request error: %s", nameptr);
	    exit(1);
    }
    if (f->data == NULL) {
	    /* File not found */
	    uadecore_send_debug("load: file not found: %s", nameptr);
	    break;
    }
    dst = amiga_get_u32(0x208);
    len = uade_safe_copy(dst, f->data, f->size);
    if (len == 0 && f->size > 0)
	    uadecore_send_debug("load: too long a file to copy");
    uade_put_long(0x20C, len);
    uadecore_send_debug("load: %s ptr 0x%x size 0x%x", nameptr, dst, len);
    break;

  case AMIGAMSG_READ:
    /* Used by "mdat.Crystal_Palace-1", for example */
    src = amiga_get_u32(0x204);
    if (!uade_valid_string(src)) {
	    fprintf(stderr, "uadecore: Read name in invalid address range.\n");
	    break;
    }
    nameptr = get_real_address(src);
    f = lookup_amiga_file_cache((const char *) nameptr);
    if (f == NULL) {
	    uadecore_send_debug("read: request error: %s", nameptr);
	    exit(1);
    }
    x = 0;
    if (f->data != NULL) {
	    dst = amiga_get_u32(0x208);
	    off = amiga_get_u32(0x20C);
	    len = amiga_get_u32(0x210);
	    if (off >= f->size) {
		    uadecore_send_debug("read: file offset over the file end");
	    } else {
		    size_t endpos = off + ((size_t) len);
		    size_t tocopy = len;
		    if (endpos > f->size)
			    tocopy = f->size - off;
		    x = uade_safe_copy(dst, f->data + off, tocopy);
	    }
	    uadecore_send_debug("read: %s dst 0x%x off 0x%x len 0x%x bytesread 0x%x", nameptr, dst, off, len, x);
    } else {
	    uadecore_send_debug("read: file not found: %s", nameptr);
    }
    uade_put_long(0x214, x);
    break;

  case AMIGAMSG_FILESIZE:
    /* Used by "mdat.Crystal_Palace-1", for example */
    src = amiga_get_u32(0x204);
    if (!uade_valid_string(src)) {
      fprintf(stderr, "uadecore: Filesize name in invalid address range.\n");
      break;
    }
    nameptr = get_real_address(src);
    f = lookup_amiga_file_cache((const char *) nameptr);
    if (f == NULL) {
	    uadecore_send_debug("filesize: request error: %s", nameptr);
	    exit(1);
    }
    len = 0;
    x = 0;
    if (f->data != NULL) {
	    len = f->size;
	    x = -1;
	    uadecore_send_debug("filesize: file %s res 0x%x", nameptr, len);
    } else {
	    /* Note, f->size == -1 if file does not exist */
	    uadecore_send_debug("filesize: file not found: %s", nameptr);
    }
    uade_put_long(0x208, len);
    uade_put_long(0x20C, x);
    break;

  case AMIGAMSG_TIME_CRITICAL:
    uadecore_time_critical = amiga_get_u32(0x204) ? 1 : 0;
    if (speed_hack < 0) {
      /* a negative value forbids use of speed hack */
      uadecore_time_critical = 0;
    }
    break;

  case AMIGAMSG_GET_INFO:
    src = amiga_get_u32(0x204);
    dst = amiga_get_u32(0x208);
    len = amiga_get_u32(0x20C);
    if (!uade_valid_string(src)) {
      fprintf(stderr, "uadecore: get info: Invalid src: 0x%x\n", src);
      break;
    }
    if (len <= 0) {
      fprintf(stderr, "uadecore: get info: len = %d\n", len);
      break;
    }
    if (!valid_address(dst, len)) {
      fprintf(stderr, "uadecore: get info: Invalid dst: 0x%x\n", dst);
      break;
    }
    srcstr = (char *) get_real_address(src);
    dststr = (char *) get_real_address(dst);
    uadecore_send_debug("score issued an info request: %s (maxlen %d)", srcstr, len);
    len = get_info_for_ep(dststr, srcstr, len);
    /* Send printable debug */
    do {
      size_t i;
      size_t maxspace = sizeof space;
      if (len <= 0) {
	maxspace = 1;
      } else {
	if (len < maxspace)
	  maxspace = len;
      }
      for (i = 0; i < maxspace; i++) {
	space[i] = dststr[i];
	if (space[i] == 0)
	  space[i] = ' ';
      }
      if (i < maxspace) {
	space[i] = 0;
      } else {
	space[maxspace - 1] = 0;
      }
      uadecore_send_debug("reply to score: %s (total len %d)", space, len);
    } while (0);
    uade_put_long(0x20C, len);
    break;

  case AMIGAMSG_START_OUTPUT:
    uadecore_audio_output = 1;
    break;

  default:
    fprintf(stderr,"uadecore: Unknown message from score (%d)\n", x);
    break;
  }
}