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; }
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; }
static void * signal_thread (void * data) { gint signal; while (! sigwait (& signal_set, & signal)) event_queue ("quit", NULL); return NULL; }
void trig_event(bool keep = true) { if (event_cach != EVENT_NULL) { event_queue(event_cach); if (!keep) event_cach = EVENT_NULL; } }
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); }
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; }
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 (); }
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); }
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); }
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; }
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); }
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 (); }
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); }
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 }
/* 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); }
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); }
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); } }
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); }
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; } }
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; }
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; }
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(¶ms_ptr->no_color); set_verbosity(¶ms_ptr->verbosity, ¶ms_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."); }
static enum signal_callback_result timer_signal (enum signal signal, void *aux) { event_queue (); return scr_keep; }
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); }
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); }
gboolean mpris_root_quit(MprisPlayer * obj, GError ** error) { event_queue("quit", NULL); return TRUE; }
gboolean audacious_rc_quit(RemoteObject * obj, GError * *error) { event_queue("quit", NULL); return TRUE; }
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; }