Пример #1
0
static void flush_frame(void) {
	audio_info_t device_info;
	int samples_left;
	Sample *fill_to = buffer + FRAME_SIZE;
	while (wrptr < fill_to)
		*(wrptr++) = lastsample;
	frame_cycle_base += FRAME_CYCLES;
	frame_cycle = 0;
	flush_event->at_cycle = frame_cycle_base + FRAME_CYCLES;
	event_queue(&MACHINE_EVENT_LIST, flush_event);
	wrptr = buffer;
	ioctl(sound_fd, AUDIO_GETINFO, &device_info);
	if (xroar_noratelimit) {
		ioctl(sound_fd, I_FLUSH, FLUSHW);
		samples_written = device_info.play.samples;
		return;
	}
	samples_left = samples_written - device_info.play.samples;
	if (samples_left > FRAME_SIZE) {
		int sleep_ms = ((samples_left - FRAME_SIZE) * 1000)/SAMPLE_RATE;
		struct timespec elapsed, tv;
		int errcode;
		sleep_ms -= 10;
		elapsed.tv_sec = sleep_ms / 1000;
		elapsed.tv_nsec = (sleep_ms % 1000) * 1000000;
		do {
			errno = 0;
			tv.tv_sec = elapsed.tv_sec;
			tv.tv_nsec = elapsed.tv_nsec;
			errcode = nanosleep(&tv, &elapsed);
		} while ( errcode && (errno == EINTR) );
	}
	write(sound_fd, buffer, FRAME_SIZE);
	samples_written += FRAME_SIZE;
}
Пример #2
0
static int init(void) {
	LOG_DEBUG(2,"Initialising NDS audio (ARM9 side)\n");
	flush_event = event_new();
	flush_event->dispatch = flush_frame;

	memset(buf, 0x80, sizeof(buf));
	writing_buf = 0;
	frame_base = buf;
	wrptr = buf;

	frame_cycle_base = current_cycle;
	frame_cycle = 0;
	flush_event->at_cycle = frame_cycle_base + FRAME_CYCLES;
	event_queue(&MACHINE_EVENT_LIST, flush_event);
	lastsample = 0x80; //0;

	/* handshake with ARM7 to pass sound buffer address */
	REG_IPC_FIFO_CR = (1 << 3) | (1 << 15);  /* enable FIFO, clear sendq */
	REG_IPC_SYNC = (14 << 8);
	while ((REG_IPC_SYNC & 15) != 14);
	REG_IPC_FIFO_TX = (uint32_t)buf;
	REG_IPC_SYNC = (1 << 14) | (0 << 8);  /* IRQ on sync */
	irqEnable(IRQ_IPC_SYNC);
	
	/* now wait for ARM7 to be playing frame 1 */
	while ((REG_IPC_SYNC & 1) != 1) {
		swiIntrWait(1, IRQ_IPC_SYNC);
	}
	return 0;
}
Пример #3
0
static void * signal_thread (void * data)
{
    gint signal;

    while (! sigwait (& signal_set, & signal))
        event_queue ("quit", NULL);

    return NULL;
}
Пример #4
0
void trig_event(bool keep = true)
{
	if (event_cach != EVENT_NULL)
	{
		event_queue(event_cach);
		
		if (!keep) event_cach = EVENT_NULL;
	}
}
Пример #5
0
static void update_cb (void * hook_data, void * user_data)
{
    g_return_if_fail (playing);

    if (GPOINTER_TO_INT (hook_data) < PLAYLIST_UPDATE_METADATA || ! playback_get_ready ())
        return;

    if (update_from_playlist ())
        event_queue ("title change", NULL);
}
Пример #6
0
static int init(void) {
	LOG_DEBUG(2,"Initialising null audio driver\n");
	last_pause_cycle = current_cycle;
	last_pause_ms = current_time();
	flush_event = event_new();
	flush_event->dispatch = flush_frame;
	flush_event->at_cycle = current_cycle + (10 * CYCLES_PER_MS);
	event_queue(&MACHINE_EVENT_LIST, flush_event);
	return 0;
}
Пример #7
0
static void timer_io_read (sexpr sx, struct sexpr_io *io, void *aux)
{
    if (eofp (sx))
    {
        output_remove (io);
        return;
    }

    event_add   (sx);
    event_queue ();
}
Пример #8
0
static void set_params (InputPlayback * p, int bitrate, int samplerate,
 int channels)
{
    g_return_if_fail (playing);

    current_bitrate = bitrate;
    current_samplerate = samplerate;
    current_channels = channels;

    if (playback_get_ready ())
        event_queue ("info change", NULL);
}
Пример #9
0
static void set_pb_ready (InputPlayback * p)
{
    g_return_if_fail (playing);
    pthread_mutex_lock (& ready_mutex);

    update_from_playlist ();
    ready_flag = TRUE;

    pthread_cond_signal (& ready_cond);
    pthread_mutex_unlock (& ready_mutex);

    event_queue ("playback ready", NULL);
}
Пример #10
0
static int init(void) {
	unsigned int rate = SAMPLE_RATE;
	audio_info_t device_info;
	const char *device = "/dev/audio";

	LOG_DEBUG(2,"Initialising Sun audio driver\n");
	channels = CHANNELS;
	sound_fd = open(device, O_WRONLY);
	if (sound_fd == -1) {
		LOG_ERROR("Couldn't open audio device %s: %s!\n", device, strerror(errno));
		return 1;
	}
	AUDIO_INITINFO(&device_info);
	device_info.play.sample_rate = SAMPLE_RATE;
	device_info.play.channels = CHANNELS;
	device_info.play.precision = 8;
	device_info.play.encoding = AUDIO_ENCODING_LINEAR;
	if (ioctl(sound_fd, AUDIO_SETINFO, &device_info) < 0) {
		LOG_ERROR("Failed to configure audio device %s: %s",
				device, strerror(errno));
		return 1;
	}
	if (device_info.play.channels != channels) {
		LOG_ERROR("Couldn't set desired (%d) audio channels.  Got %d.\n", channels, device_info.play.channels);
		return 1;
	}
	if (device_info.play.encoding != AUDIO_ENCODING_LINEAR) {
		LOG_ERROR("Couldn't set desired audio format.\n");
		return 1;
	}
	if (device_info.play.sample_rate != rate) {
		LOG_ERROR("Couldn't set desired (%dHz) audio rate.  Got %dHz.\n", rate, device_info.play.sample_rate);
		return 1;
	}
	LOG_DEBUG(2, "Set up audio device at %dHz, %d channels.\n", rate, channels);
	buffer = (Sample *)malloc(FRAME_SIZE * sizeof(Sample));
	flush_event = event_new();
	flush_event->dispatch = flush_frame;

	memset(buffer, 0x80, FRAME_SIZE);
	wrptr = buffer;
	frame_cycle_base = current_cycle;
	frame_cycle = 0;
	flush_event->at_cycle = frame_cycle_base + FRAME_CYCLES;
	event_queue(&MACHINE_EVENT_LIST, flush_event);
	lastsample = 0x00;
	ioctl(sound_fd, I_FLUSH, FLUSHW);
	ioctl(sound_fd, AUDIO_GETINFO, &device_info);
	samples_written = device_info.play.samples;
	return 0;
}
Пример #11
0
static void flush_frame(void) {
	Sample *fill_to = buffer[writing_frame] + frame_size;
	while (wrptr < fill_to)
		*(wrptr++) = lastsample;
	frame_cycle_base += frame_cycles;
	frame_cycle = 0;
	flush_event->at_cycle = frame_cycle_base + frame_cycles;
	event_queue(&MACHINE_EVENT_LIST, flush_event);
	writing_frame ^= 1;
	wrptr = buffer[writing_frame];
	if (xroar_noratelimit)
		return;
	while ((rDCSRC2 >= (unsigned)buffer[1]) == writing_frame);
}
Пример #12
0
static void event_dispatch
    (struct event *e, struct event **p, unsigned long long ts)
{
    sexpr t = e->then;
    e->queue_time = dt_from_unix (ts);
    output (e->output);
    event_repeat (e, p);

    if (!eolp (t))
    {
        event_add (t);
    }

    event_queue ();
}
Пример #13
0
void set_string (const char * section, const char * name, const char * value)
{
    g_return_if_fail (defaults && keyfile);
    g_return_if_fail (name && value);
    pthread_mutex_lock (& mutex);

    if (! section)
        section = DEFAULT_SECTION;

    const char * def = get_default (section, name);
    bool_t changed = FALSE;

    if (! strcmp (value, def))
    {
        if (g_key_file_has_key (keyfile, section, name, NULL))
        {
            g_key_file_remove_key (keyfile, section, name, NULL);
            changed = TRUE;
        }
    }
    else
    {
        char * old = g_key_file_has_key (keyfile, section, name, NULL) ?
         g_key_file_get_value (keyfile, section, name, NULL) : NULL;

        if (! old || strcmp (value, old))
        {
            g_key_file_set_value (keyfile, section, name, value);
            changed = TRUE;
        }

        g_free (old);
    }

    if (changed)
    {
        modified = TRUE;

        if (! strcmp (section, DEFAULT_SECTION))
        {
            char * event = g_strdup_printf ("set %s", name);
            event_queue (event, NULL);
            g_free (event);
        }
    }

    pthread_mutex_unlock (& mutex);
}
Пример #14
0
void vdg_reset(void) {
	video_module->vdg_vsync();
	scanline = 0;
	scanline_start = current_cycle;
	hs_fall_event.at_cycle = current_cycle + VDG_LINE_DURATION;
	event_queue(&MACHINE_EVENT_LIST, &hs_fall_event);
	vdg_set_mode();
	frame = 0;
	SET_BEAM_POS(0);
#ifndef FAST_VDG
	inhibit_mode_change = 0;
#endif
#ifdef HAVE_NDS
	scanline_data_ptr = scanline_data;
#endif
}
Пример #15
0
/* Called when the PIA bus containing STROBE is changed */
void printer_strobe(_Bool strobe, int data) {
	/* Ignore if this is not a transition to high */
	if (strobe == strobe_state) return;
	strobe_state = strobe;
	if (!strobe_state) return;
	/* Open stream for output if it's not already */
	if (!stream_dest) return;
	if (!stream) open_stream();
	/* Print byte */
	if (stream) {
		fputc(data, stream);
	}
	/* ACK, and schedule !ACK */
	DELEGATE_SAFE_CALL1(printer_signal_ack, 1);
	ack_clear_event.at_tick = event_current_tick + (OSCILLATOR_RATE / 150000);
	event_queue(&MACHINE_EVENT_LIST, &ack_clear_event);
}
Пример #16
0
void *listener_thread_start(void *port) {
	int listener_fd;
	puts("Listener thread started.");

	listener_fd = open_socket((char *) port);

	for (;;) {
		int new_connection;
		if ((new_connection = accept(listener_fd, NULL, 0)) != -1) {
			event_queue(new_connection_event(new_connection));
		}
	}

	puts("Listener thread exiting.");

	pthread_exit(NULL);
}
Пример #17
0
static void flush_frame(void) {
	uint8_t *fill_to = frame_base + FRAME_SIZE;
	while (wrptr < fill_to)
		*(wrptr++) = lastsample;
	DC_FlushRange(frame_base, FRAME_SIZE);
	frame_cycle_base += FRAME_CYCLES;
	frame_cycle = 0;
	flush_event->at_cycle = frame_cycle_base + FRAME_CYCLES;
	event_queue(&MACHINE_EVENT_LIST, flush_event);
	writing_buf ^= 1;
	frame_base = buf + (writing_buf * FRAME_SIZE);
	wrptr = frame_base;
	/* wait here */
	if ((REG_IPC_SYNC & 1) == writing_buf) {
		swiIntrWait(1, IRQ_IPC_SYNC);
	}
}
Пример #18
0
static void flush_frame(void) {
	Cycle elapsed_cycles = current_cycle - last_pause_cycle;
	unsigned int expected_elapsed_ms = elapsed_cycles / CYCLES_PER_MS;
	unsigned int actual_elapsed_ms, difference_ms;
	actual_elapsed_ms = current_time() - last_pause_ms;
	difference_ms = expected_elapsed_ms - actual_elapsed_ms;
	if (difference_ms >= 10) {
		if (xroar_noratelimit || difference_ms > 1000) {
			last_pause_ms = current_time();
			last_pause_cycle = current_cycle;
		} else {
			sleep_ms(difference_ms);
			difference_ms = current_time() - last_pause_ms;
			last_pause_ms += difference_ms;
			last_pause_cycle += difference_ms * CYCLES_PER_MS;
		}
	}
	flush_event->at_cycle = current_cycle + (10 * CYCLES_PER_MS);
	event_queue(&MACHINE_EVENT_LIST, flush_event);
}
Пример #19
0
static void flush_frame(void) {
    int8_t *source = buffer;
    Sample *fill_to = buffer + FRAME_SIZE;
    while (wrptr < fill_to)
        *(wrptr++) = lastsample;
    frame_cycle_base += FRAME_CYCLES;
    frame_cycle = 0;
    flush_event->at_cycle = frame_cycle_base + FRAME_CYCLES;
    event_queue(&MACHINE_EVENT_LIST, flush_event);
    wrptr = buffer;
    if (xroar_noratelimit)
        return;
    /* Convert buffer and write to device */
    if (format == AFMT_S8) {
        int8_t *dest = convbuf;
        int8_t tmp;
        int i, j;
        for (i = FRAME_SIZE; i; i--) {
            tmp = *(source++);
            for (j = 0; j < channels; j++)
                *(dest++) = tmp;
        }
        write(sound_fd, convbuf, FRAME_SIZE * channels);
        return;
    }
    if (format == AFMT_S16_NE) {
        int16_t *dest = (int16_t *)convbuf;
        int16_t tmp;
        int i, j;
        for (i = FRAME_SIZE; i; i--) {
            tmp = *(source++) << 8;
            for (j = 0; j < channels; j++)
                *(dest++) = tmp;
        }
        write(sound_fd, convbuf, FRAME_SIZE * channels * 2);
        return;
    }
}
Пример #20
0
static int init(void) {
	sample_rate = 22050;
	gpsound_init(PCLK, &sample_rate);
	sample_cycles = OSCILLATOR_RATE / sample_rate;
	//frame_size = CYCLES_PER_FRAME / sample_cycles;
	frame_size = 512;
	frame_cycles = sample_cycles * frame_size;
	buffer = gpsound_buffers(frame_size);
	gpsound_start();
	flush_event = event_new();
	flush_event->dispatch = flush_frame;

	memset(buffer[0], 0, frame_size * sizeof(Sample));
	memset(buffer[1], 0, frame_size * sizeof(Sample));
	wrptr = buffer[1];
	writing_frame = 1;
	frame_cycle_base = current_cycle;
	frame_cycle = 0;
	flush_event->at_cycle = frame_cycle_base + frame_cycles;
	event_queue(&MACHINE_EVENT_LIST, flush_event);
	lastsample = 0;
	return 0;
}
Пример #21
0
static int init(void) {
    const char *device = "/dev/dsp";
    int fragment_param, tmp;

    LOG_DEBUG(2,"Initialising OSS audio driver\n");
    sound_fd = open(device, O_WRONLY);
    if (sound_fd == -1)
        goto failed;
    /* The order these ioctls are tried (format, channels, sample rate)
     * is important: OSS docs say setting format can affect channels and
     * sample rate, and setting channels can affect sample rate. */
    /* Set audio format.  Only support AFMT_S8 (signed 8-bit) and
     * AFMT_S16_NE (signed 16-bit, host-endian) */
    if (ioctl(sound_fd, SNDCTL_DSP_GETFMTS, &format) == -1)
        goto failed;
    if ((format & (AFMT_S8 | AFMT_S16_NE)) == 0) {
        LOG_ERROR("No desired audio formats supported by device\n");
        return 1;
    }
    if (format & AFMT_S8) {
        format = AFMT_S8;
        bytes_per_sample = 1;
    } else {
        format = AFMT_S16_NE;
        bytes_per_sample = 2;
    }
    if (ioctl(sound_fd, SNDCTL_DSP_SETFMT, &format) == -1)
        goto failed;
    /* Set device to mono if possible */
    channels = 0;
    if (ioctl(sound_fd, SNDCTL_DSP_STEREO, &channels) == -1)
        goto failed;
    channels++;
    /* Attempt to set sample_rate to 44.1kHz, but live with whatever
     * we get */
    sample_rate = 44100;
    if (ioctl(sound_fd, SNDCTL_DSP_SPEED, &sample_rate) == -1)
        goto failed;
    /* Set number of fragments low */
    fragment_param = 0;
    tmp = FRAME_SIZE * bytes_per_sample * channels;
    while (tmp > 1) {
        tmp >>= 1;
        fragment_param++;
    }
    fragment_param |= (FRAGMENTS << 16);
    tmp = fragment_param;
    if (ioctl(sound_fd, SNDCTL_DSP_SETFRAGMENT, &fragment_param) == -1)
        goto failed;

    /* TODO: Need to abstract this logging out */
    LOG_DEBUG(2, "\t");
    if (format & AFMT_U8) LOG_DEBUG(2, "8-bit unsigned, ");
    else if (format & AFMT_S16_LE) LOG_DEBUG(2, "16-bit signed little-endian, ");
    else if (format & AFMT_S16_BE) LOG_DEBUG(2, "16-bit signed big-endian, ");
    else if (format & AFMT_S8) LOG_DEBUG(2, "8-bit signed, ");
    else if (format & AFMT_U16_LE) LOG_DEBUG(2, "16-bit unsigned little-endian, ");
    else if (format & AFMT_U16_BE) LOG_DEBUG(2, "16-bit unsigned big-endian, ");
    else LOG_DEBUG(2, "Unknown format, ");
    switch (channels) {
    case 1:
        LOG_DEBUG(2, "mono, ");
        break;
    case 2:
        LOG_DEBUG(2, "stereo, ");
        break;
    default:
        LOG_DEBUG(2, "%d channel, ", channels);
        break;
    }
    LOG_DEBUG(2, "%dHz\n", sample_rate);

    if (tmp != fragment_param)
        LOG_WARN("Couldn't set desired buffer parameters: sync to audio might not be ideal\n");
    buffer = malloc(FRAME_SIZE * sizeof(Sample));
    convbuf = malloc(FRAME_SIZE * bytes_per_sample * channels);
    flush_event = event_new();
    flush_event->dispatch = flush_frame;

    ioctl(sound_fd, SNDCTL_DSP_RESET, 0);
    memset(buffer, 0, FRAME_SIZE * sizeof(Sample));
    wrptr = buffer;
    frame_cycle_base = current_cycle;
    frame_cycle = 0;
    flush_event->at_cycle = frame_cycle_base + FRAME_CYCLES;
    event_queue(&MACHINE_EVENT_LIST, flush_event);
    lastsample = 0;
    return 0;
failed:
    LOG_ERROR("Failed to initialise OSS audio driver\n");
    return 1;
}
Пример #22
0
void saldl(saldl_params *params_ptr) {
  /* Definitions */
  info_s info = DEF_INFO_S;
  info.params = params_ptr;

  /* Handle signals */
  info_global = &info;
  saldl_handle_signals();

  /* Need to be set as early as possible */
  set_color(&params_ptr->no_color);
  set_verbosity(&params_ptr->verbosity, &params_ptr->libcurl_verbosity);

  /* Check if loaded libcurl is recent enough */
  info.curl_info = curl_version_info(CURLVERSION_NOW);
  check_libcurl(info.curl_info);

  /* Library initializations, should run only once */
  SALDL_ASSERT(!curl_global_init(CURL_GLOBAL_ALL));
  SALDL_ASSERT(!evthread_use_pthreads());

  /* get/set initial info */
  main_msg("URL", "%s", params_ptr->start_url);
  check_url(params_ptr->start_url);
  get_info(&info);
  set_info(&info);
  check_remote_file_size(&info);

  /* initialize chunks early for extra_resume() */
  chunks_init(&info);

  if (params_ptr->resume) {
    check_resume(&info);
  }

  print_chunk_info(&info);
  global_progress_init(&info);

  /* exit here if dry_run was set */
  if ( params_ptr->dry_run  ) {
    saldl_free_all(&info);
    finish_msg_and_exit("Dry-run done.");
  }

  check_files_and_dirs(&info);

  /* Check if download was interrupted after all data was merged */
  if (info.already_finished) {
    goto saldl_all_data_merged;
  }

  /* threads, needed by set_modes() */
  info.threads = saldl_calloc(params_ptr->num_connections, sizeof(thread_s));
  set_modes(&info);

  /* 1st iteration */
  for (size_t counter = 0; counter < params_ptr->num_connections; counter++) {
    queue_next_chunk(&info, counter, 1);
  }

  /* Create event pthreads */
  saldl_pthread_create(&info.trigger_events_pth, NULL, events_trigger_thread, &info);

  if (!params_ptr->read_only && !params_ptr->to_stdout) {
    saldl_pthread_create(&info.sync_ctrl_pth, NULL, sync_ctrl, &info);
  }

  if (info.chunk_count != 1) {
    saldl_pthread_create(&info.status_display_pth, NULL, status_display, &info);
    saldl_pthread_create(&info.queue_next_pth, NULL, queue_next_thread, &info);
    saldl_pthread_create(&info.merger_pth, NULL, merger_thread, &info);
  }

  /* Now that everything is initialized */
  info.session_status = SESSION_IN_PROGRESS;

  /* Avoid race in joining event threads if the session was interrupted, or finishing without downloading if single_mode */
  do {
    usleep(100000);
  } while (params_ptr->single_mode ? info.chunks[0].progress != PRG_FINISHED : info.global_progress.complete_size != info.file_size);

  /* Join event pthreads */
  if (!params_ptr->read_only && !params_ptr->to_stdout) {
    join_event_pth(&info.ev_ctrl ,&info.sync_ctrl_pth);
  }

  if (info.chunk_count !=1) {
    join_event_pth(&info.ev_status, &info.status_display_pth);
    join_event_pth(&info.ev_queue, &info.queue_next_pth);
    join_event_pth(&info.ev_merge, &info.merger_pth);
  }

  info.events_queue_done = true;
  event_queue(&info.ev_trigger, NULL);
  join_event_pth(&info.ev_trigger ,&info.trigger_events_pth);

saldl_all_data_merged:

  /* Remove tmp_dirname */
  if (!params_ptr->read_only && !params_ptr->mem_bufs && !params_ptr->single_mode) {
    if ( rmdir(info.tmp_dirname) ) {
      err_msg(FN, "Failed to delete %s: %s", info.tmp_dirname, strerror(errno) );
    }
  }

  /*** Final Steps ***/

  /* One last check  */
  if (info.file_size && !params_ptr->no_remote_info &&
      !params_ptr->read_only && !params_ptr->to_stdout &&
      (!info.remote_info.content_encoded || params_ptr->no_decompress)) {
    off_t saved_file_size = saldl_fsizeo(info.part_filename, info.file);
    if (saved_file_size != info.file_size) {
      pre_fatal(FN, "Unexpected saved file size (%"SAL_JU"!=%"SAL_JU").", saved_file_size, info.file_size);
      pre_fatal(FN, "This could happen if you're downloading from a dynamic site.");
      pre_fatal(FN, "If that's the case and the download is small, retry with --no-remote-info");
      fatal(FN, "If you think that's a bug in saldl, report it: https://github.com/saldl/saldl/issues");
    }
  }
  else {
    debug_msg(FN, "Strict check for finished file size skipped.");
  }

  if (!params_ptr->read_only && !params_ptr->to_stdout) {
    saldl_fclose(info.part_filename, info.file);
    if (rename(info.part_filename, params_ptr->filename) ) {
      err_msg(FN, "Failed to rename now-complete %s to %s: %s", info.part_filename, params_ptr->filename, strerror(errno));
    }

    saldl_fclose(info.ctrl_filename, info.ctrl_file);
    if ( remove(info.ctrl_filename) ) {
      err_msg(FN, "Failed to remove %s: %s", info.ctrl_filename, strerror(errno));
    }
  }

  /* cleanups */
  curl_cleanup(&info);
  saldl_free_all(&info);

  finish_msg_and_exit("Download Finished.");
}
Пример #23
0
static enum signal_callback_result timer_signal (enum signal signal, void *aux)
{
    event_queue ();

    return scr_keep;
}
Пример #24
0
static void do_hs_fall(void *data) {
	struct MC6847_private *vdg = data;
	// Finish rendering previous scanline
	if (vdg->frame == 0) {
		if (vdg->scanline < VDG_ACTIVE_AREA_START) {
			if (vdg->scanline == 0) {
				memset(vdg->pixel_data + VDG_LEFT_BORDER_START, vdg->border_colour, VDG_tAVB);
			}
			video_module->render_scanline(vdg->pixel_data);
		} else if (vdg->scanline >= VDG_ACTIVE_AREA_START && vdg->scanline < VDG_ACTIVE_AREA_END) {
			render_scanline(vdg);
			vdg->row++;
			if (vdg->row > 11)
				vdg->row = 0;
			video_module->render_scanline(vdg->pixel_data);
			vdg->pixel = vdg->pixel_data + VDG_LEFT_BORDER_START;
		} else if (vdg->scanline >= VDG_ACTIVE_AREA_END) {
			if (vdg->scanline == VDG_ACTIVE_AREA_END) {
				memset(vdg->pixel_data + VDG_LEFT_BORDER_START, vdg->border_colour, VDG_tAVB);
			}
			video_module->render_scanline(vdg->pixel_data);
		}
	}

	// HS falling edge.
	DELEGATE_CALL1(vdg->public.signal_hs, 0);

	vdg->scanline_start = vdg->hs_fall_event.at_tick;
	// Next HS rise and fall
	vdg->hs_rise_event.at_tick = vdg->scanline_start + VDG_CYCLES(VDG_HS_RISING_EDGE);
	vdg->hs_fall_event.at_tick = vdg->scanline_start + VDG_CYCLES(VDG_LINE_DURATION);

	/* On PAL machines, the clock to the VDG is interrupted at two points
	 * in every frame to fake up some extra scanlines, padding the signal
	 * from 262 lines to 312 lines.  Dragons do not generate an HS-related
	 * interrupt signal during this time, CoCos do.  The positioning and
	 * duration of each interruption differs also. */

	if (IS_PAL && IS_COCO) {
		if (vdg->scanline == SCANLINE(VDG_ACTIVE_AREA_END + 25)) {
			vdg->pal_padding = 26;
			vdg->hs_fall_event.delegate.func = do_hs_fall_pal_coco;
		} else if (vdg->scanline == SCANLINE(VDG_ACTIVE_AREA_END + 47)) {
			vdg->pal_padding = 24;
			vdg->hs_fall_event.delegate.func = do_hs_fall_pal_coco;
		}
	} else if (IS_PAL && IS_DRAGON) {
		if (vdg->scanline == SCANLINE(VDG_ACTIVE_AREA_END + 24)
		    || vdg->scanline == SCANLINE(VDG_ACTIVE_AREA_END + 32)) {
				vdg->hs_rise_event.at_tick += 25 * VDG_CYCLES(VDG_PAL_PADDING_LINE);
				vdg->hs_fall_event.at_tick += 25 * VDG_CYCLES(VDG_PAL_PADDING_LINE);
		}
	}

	event_queue(&MACHINE_EVENT_LIST, &vdg->hs_rise_event);
	event_queue(&MACHINE_EVENT_LIST, &vdg->hs_fall_event);

	// Next scanline
	vdg->scanline = SCANLINE(vdg->scanline + 1);
	vdg->beam_pos = 0;
	vdg->vram_nbytes = 0;
	vdg->vram_ptr = vdg->vram;
	vdg->vram_bit = 0;
	vdg->lborder_remaining = VDG_tLB;
	vdg->vram_remaining = vdg->is_32byte ? 32 : 16;
	vdg->rborder_remaining = VDG_tRB;

	if (vdg->scanline == VDG_ACTIVE_AREA_START) {
		vdg->row = 0;
	}

	if (vdg->scanline == VDG_ACTIVE_AREA_END) {
		// FS falling edge
		DELEGATE_CALL1(vdg->public.signal_fs, 0);
	}
Пример #25
0
static void do_hs_fall(void) {
	/* Finish rendering previous scanline */
#ifdef HAVE_GP32
	/* GP32 renders 4 scanlines at once */
	if (frame == 0 && scanline >= VDG_ACTIVE_AREA_START
			&& scanline < VDG_ACTIVE_AREA_END
			&& (scanline & 3) == ((VDG_ACTIVE_AREA_START+3)&3)
			) {
		video_module->render_scanline();
	}
#elif defined (HAVE_NDS)
	if (scanline >= VDG_ACTIVE_AREA_START
			&& scanline < VDG_ACTIVE_AREA_END) {
		render_scanline();
		sam_vdg_hsync();
	}
#elif !defined(HAVE_NDS)  /* NDS video module does its own thing */
	/* Normal code */
	if (frame == 0 && scanline >= (VDG_TOP_BORDER_START + 1)) {
		if (scanline < VDG_ACTIVE_AREA_START) {
			video_module->render_border();
		} else if (scanline < VDG_ACTIVE_AREA_END) {
			render_scanline();
			sam_vdg_hsync();
			video_module->hsync();
		} else if (scanline < (VDG_BOTTOM_BORDER_END - 2)) {
			video_module->render_border();
		}
	}
#endif
	/* Next scanline */
	scanline = (scanline + 1) % VDG_FRAME_DURATION;
	scanline_start = hs_fall_event.at_cycle;
	SET_BEAM_POS(0);
	PIA_RESET_Cx1(PIA0.a);
#ifdef FAST_VDG
	/* Faster, less accurate timing for GP32/NDS */
	PIA_SET_Cx1(PIA0.a);
#else
	/* Everything else schedule HS rise for later */
	hs_rise_event.at_cycle = scanline_start + VDG_HS_RISING_EDGE;
	event_queue(&MACHINE_EVENT_LIST, &hs_rise_event);
#endif
	hs_fall_event.at_cycle = scanline_start + VDG_LINE_DURATION;
	/* Frame sync */
	if (scanline == SCANLINE(VDG_VBLANK_START)) {
		sam_vdg_fsync();
#ifndef HAVE_NDS
		frame--;
		if (frame < 0)
			frame = xroar_frameskip;
		if (frame == 0)
			video_module->vdg_vsync();
#else
		scanline_data_ptr = scanline_data;
#endif
	}
#ifndef FAST_VDG
	/* Enable mode changes at beginning of active area */
	if (scanline == SCANLINE(VDG_ACTIVE_AREA_START)) {
		inhibit_mode_change = 0;
		vdg_set_mode();
	}
#endif
	/* FS falling edge at end of this scanline */
	if (scanline == SCANLINE(VDG_ACTIVE_AREA_END - 1)) {
#ifdef HAVE_NDS
		nds_update_screen = 1;
#endif
		fs_fall_event.at_cycle = scanline_start + VDG_LINE_DURATION;
		event_queue(&MACHINE_EVENT_LIST, &fs_fall_event);
	}
#ifndef FAST_VDG
	/* Disable mode changes after end of active area */
	if (scanline == SCANLINE(VDG_ACTIVE_AREA_END)) {
		inhibit_mode_change = 1;
	}
#endif
	/* PAL delay 24 lines after FS falling edge */
	if (IS_PAL && (scanline == SCANLINE(VDG_ACTIVE_AREA_END + 23))) {
		hs_fall_event.at_cycle += 25 * VDG_PAL_PADDING_LINE;
	}
	/* FS rising edge at end of this scanline */
	if (scanline == SCANLINE(VDG_ACTIVE_AREA_END + 31)) {
		/* Fig. 8, VDG data sheet: tWFS = 32 * (227.5 * 1/f) */
		fs_rise_event.at_cycle = scanline_start + VDG_LINE_DURATION;
		event_queue(&MACHINE_EVENT_LIST, &fs_rise_event);
		/* PAL delay after FS rising edge */
		if (IS_PAL) {
			hs_fall_event.at_cycle += 25 * VDG_PAL_PADDING_LINE;
		}
	}
	event_queue(&MACHINE_EVENT_LIST, &hs_fall_event);
}
Пример #26
0
gboolean mpris_root_quit(MprisPlayer * obj, GError ** error)
{
    event_queue("quit", NULL);
    return TRUE;
}
Пример #27
0
gboolean audacious_rc_quit(RemoteObject * obj, GError * *error)
{
    event_queue("quit", NULL);
    return TRUE;
}
Пример #28
0
static int init(void) {
	int valid, i;

	LOG_DEBUG(2,"Initialising SDL joystick driver\n");

	poll_event = event_new();
	if (poll_event == NULL) {
		LOG_WARN("Couldn't create joystick polling event.\n");
		return 1;
	}
	poll_event->dispatch = do_poll;

	SDL_InitSubSystem(SDL_INIT_JOYSTICK);

	num_sdl_joysticks = SDL_NumJoysticks();
	if (num_sdl_joysticks < 1) {
		LOG_WARN("No joysticks attached.\n");
		return 1;
	}

	/* If only one joystick attached, change the right joystick defaults */
	if (num_sdl_joysticks == 1) {
		control_config[INPUT_JOY_RIGHT_X].joy_num = control_config[INPUT_JOY_RIGHT_Y].joy_num
			= control_config[INPUT_JOY_RIGHT_FIRE].joy_num = 0;
		control_config[INPUT_JOY_RIGHT_X].control_num = 3;
		control_config[INPUT_JOY_RIGHT_Y].control_num = 2;
		control_config[INPUT_JOY_RIGHT_FIRE].control_num = 1;
	}

	if (xroar_opt_joy_right) {
		parse_joystick_def(xroar_opt_joy_right, 0);
	}
	if (xroar_opt_joy_left) {
		parse_joystick_def(xroar_opt_joy_left, 3);
	}

	valid = 0;
	for (i = 0; i < 6; i++) {
		struct joy *j = find_joy(control_config[i].joy_num);
		control[i].joy = j;
		control[i].control_num = control_config[i].control_num;
		control[i].invert = control_config[i].invert;
		if (j && (i % 3) < 2) {
			if (control_config[i].control_num >= j->num_axes) {
				LOG_WARN("Axis %d not found on joystick %d\n", control_config[i].control_num, control_config[i].joy_num);
				control[i].joy = NULL;
			}
		} else if (j && (i % 3) == 2) {
			if (control_config[i].control_num >= j->num_buttons) {
				LOG_WARN("Button %d not found on joystick %d\n", control_config[i].control_num, control_config[i].joy_num);
				control[i].joy = NULL;
			}
		} else {
			LOG_WARN("Joystick %d not found\n", control_config[i].joy_num);
			control[i].joy = NULL;
		}
		if (control[i].joy)
			valid++;
	}

	/* No point scheduling joystick reads if we don't have any */
	if (valid) {
		poll_event->at_cycle = current_cycle + (OSCILLATOR_RATE / 100);
		event_queue(&UI_EVENT_LIST, poll_event);
	} else {
		LOG_WARN("No valid joystick mappings made.\n");
	}
	return 0;
}