/* get_config_gfx_driver: * Helper function for set_gfx_mode: it reads the gfx_card* config variables and * tries to set the graphics mode if a matching driver is found. Returns TRUE if * at least one matching driver was found, FALSE otherwise. */ static int get_config_gfx_driver(char *gfx_card, int w, int h, int v_w, int v_h, int flags, _DRIVER_INFO *driver_list) { char buf[512], tmp[64]; GFX_DRIVER *drv; int found = FALSE; int card, n; /* try the drivers that are listed in the config file */ for (n=-2; n<255; n++) { switch (n) { case -2: /* example: gfx_card_640x480x16 = */ uszprintf(buf, sizeof(buf), uconvert_ascii("%s_%dx%dx%d", tmp), gfx_card, w, h, _color_depth); break; case -1: /* example: gfx_card_24bpp = */ uszprintf(buf, sizeof(buf), uconvert_ascii("%s_%dbpp", tmp), gfx_card, _color_depth); break; case 0: /* example: gfx_card = */ uszprintf(buf, sizeof(buf), uconvert_ascii("%s", tmp), gfx_card); break; default: /* example: gfx_card1 = */ uszprintf(buf, sizeof(buf), uconvert_ascii("%s%d", tmp), gfx_card, n); break; } card = get_config_id(uconvert_ascii("graphics", tmp), buf, 0); if (card) { drv = get_gfx_driver_from_id(card, driver_list); if (drv && gfx_driver_is_valid(drv, flags)) { found = TRUE; screen = init_gfx_driver(drv, w, h, v_w, v_h); if (screen) break; } } else { /* Stop searching the gfx_card#n (n>0) family at the first missing member, * except gfx_card1 which could have been identified with gfx_card. */ if (n > 1) break; } } return found; }
/* mouse_init: * Here we open the mouse device, initialise anything that needs it, * and chain to the framework init routine. */ static int mouse_init (void) { char tmp1[128], tmp2[128]; AL_CONST char *udevice; /* Set the current tool */ current_tool = default_tool; /* Find the device filename */ udevice = get_config_string (uconvert_ascii ("mouse", tmp1), uconvert_ascii ("mouse_device", tmp2), NULL); /* Open mouse device. Devices are cool. */ if (udevice) { TRACE(PREFIX_I "Trying %s device\n", udevice); intdrv.device = open_mouse_device (uconvert_toascii (udevice, tmp1)); if (intdrv.device < 0) { uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("Unable to open %s: %s"), udevice, ustrerror (errno)); return -1; } } else { /* If not specified in the config file, try several /dev/input/event<n> * devices. */ const char *device_name[] = { "/dev/input/event0", "/dev/input/event1", "/dev/input/event2", "/dev/input/event3", NULL }; int i; TRACE(PREFIX_I "Trying /dev/input/event[0-3] devices\n"); for (i=0; device_name[i]; i++) { intdrv.device = open_mouse_device (device_name[i]); if (intdrv.device >= 0) { break; } } if (!device_name[i]) { uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("Unable to open a mouse device: %s"), ustrerror (errno)); return -1; } } intdrv.num_buttons = get_num_buttons(intdrv.device); /* Init the tablet data */ init_tablet(intdrv.device); return __al_linux_mouse_init (&intdrv); }
static int logg_open_file_for_streaming(LOGG_Stream* s) { FILE* file; vorbis_info* vi; file = fopen(s->filename, "rb"); if (!file) { uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, "Unable to open file: %s", s->filename); return 1; } if (ov_open_callbacks(file, &s->ovf, 0, 0, OV_CALLBACKS_DEFAULT) != 0) { strncpy(allegro_error, "ov_open_callbacks failed.", ALLEGRO_ERROR_SIZE); fclose(file); return 1; } vi = ov_info(&s->ovf, -1); s->bits = 16; s->stereo = vi->channels > 1 ? 1 : 0; s->freq = vi->rate; s->len = ov_pcm_total(&s->ovf, -1); return 0; }
int info2(void) { char buf[256]; /* query the textlist proc */ uszprintf(buf, sizeof buf, "Item number %i is selected!", the_dialog[TEXTLIST_OBJECT].d1); alert("Info about the text list:", NULL, buf, "Ok", NULL, 0, 0); return D_O_K; }
int info3(void) { char buf[256]; /* query the slider proc */ uszprintf(buf, sizeof buf, "Slider position is %i!", the_dialog[SLIDER_OBJECT].d2); alert("Info about the slider:", NULL, buf, "Ok", NULL, 0, 0); return D_O_K; }
SAMPLE* logg_load(const char* filename) { OggVorbis_File ovf; FILE* file; vorbis_info* vi; SAMPLE* samp; int numRead; int offset = 0; int bitstream; char *buf = malloc(logg_bufsize); file = fopen(filename, "rb"); if (!file) { uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, "Unable to open file: %s", filename); free(buf); return 0; } if (ov_open_callbacks(file, &ovf, 0, 0, OV_CALLBACKS_DEFAULT) != 0) { strncpy(allegro_error, "ov_open_callbacks failed.", ALLEGRO_ERROR_SIZE); fclose(file); free(buf); return 0; } vi = ov_info(&ovf, -1); samp = (SAMPLE*)_al_malloc(sizeof(SAMPLE)); if (!samp) { ov_clear(&ovf); free(buf); return 0; } samp->bits = 16; samp->stereo = vi->channels > 1 ? 1 : 0; samp->freq = vi->rate; samp->priority = 128; samp->len = ov_pcm_total(&ovf, -1); samp->loop_start = 0; samp->loop_end = samp->len; samp->data = _al_malloc(sizeof(unsigned short) * samp->len * 2); while ((numRead = ov_read(&ovf, buf, logg_bufsize, ENDIANNESS, 2, 0, &bitstream)) != 0) { memcpy((unsigned char*)samp->data+offset, buf, numRead); offset += numRead; } ov_clear(&ovf); free(buf); return samp; }
/* used to probe and to configure the device. don't use sio_start() here. */ static int open_sndio_device(int input) { hdl = sio_open(NULL, (input ? SIO_REC : SIO_PLAY), 0); if (hdl == NULL) { uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("sio_opn failed")); return -1; } sio_initpar(&par); par.bits = (_sound_bits == 8) ? 8 : 16; par.sig = (_sound_bits == 8) ? 0 : 1; if (input) par.rchan = (_sound_stereo) ? 2 : 1; else par.pchan = (_sound_stereo) ? 2 : 1; par.rate = (_sound_freq > 0) ? _sound_freq : 48000; par.le = SIO_LE_NATIVE; /* allegro wants small blocks */ par.round = 512; par.appbufsz = par.rate / 10; if (!sio_setpar(hdl, &par) || !sio_getpar(hdl, &par) || (par.bits != 8 && par.bits != 16) || (par.bits == 8 && par.sig) || (par.bits == 16 && !par.sig) || (par.bits == 16 && par.le != SIO_LE_NATIVE) || (input && (par.rchan != 1 && par.rchan != 2)) || (!input && (par.pchan != 1 && par.pchan != 2))) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("could not set sndio parameters")); sio_close(hdl); return -1; } _sound_bits = par.bits; _sound_stereo = input ? par.rchan == 2 : par.pchan == 2; _sound_freq = par.rate; if (input) { sndio_rec_round = par.round; sndio_rec_appbufsz = par.appbufsz; sndio_rec_bufsize = par.round * par.bps * par.rchan; } else { sndio_play_round = par.round; sndio_play_appbufsz = par.appbufsz; sndio_play_bufsize = sndio_play_round * par.bps * par.pchan; } sndio_signed = par.sig ? 1 : 0; return 0; }
/* read_key_table: * Reads a specific keymapping table from the config file. */ static void read_key_table(unsigned short *out, unsigned short *in, char *section) { char tmp1[64], tmp2[128], name[128]; char *fmt = uconvert_ascii("key%d", tmp1); char *sec = uconvert_ascii(section, tmp2); int i; for (i=0; i<KEY_MAX; i++) { uszprintf(name, sizeof(name), fmt, i); out[i] = get_config_int(sec, name, in[i]); } }
/* init_axis: * initialize an AXIS structure, from the device and the config file */ static void init_axis(int fd, AXIS *axis, AL_CONST char *name, AL_CONST char *section, int type) { char tmp1[256]; /* config string */ char tmp2[256]; /* format string */ char tmp3[256]; /* Converted 'name' */ int abs[5]; /* values given by the input */ int config_speed; uszprintf(tmp1, sizeof(tmp1), uconvert_ascii("ev_min_%s", tmp2), uconvert_ascii(name, tmp3)); axis->in_min = get_config_int(section, tmp1, 0); uszprintf(tmp1, sizeof(tmp1), uconvert_ascii("ev_max_%s", tmp2), uconvert_ascii(name, tmp3)); axis->in_max = get_config_int(section, tmp1, 0); uszprintf(tmp1, sizeof(tmp1), uconvert_ascii("ev_abs_to_rel_%s", tmp2), uconvert_ascii(name, tmp3)); config_speed = get_config_int(section, tmp1, 1); if (config_speed<=0) config_speed = 1; axis->scale = 1; /* Ask the input */ if (ioctl(fd, EVIOCGABS(type), abs)>=0) { if (axis->in_min==0) axis->in_min=abs[1]; if (axis->in_max==0) axis->in_max=abs[2]; axis->in_abs = abs[0]; axis->scale = 320.0*config_speed/IN_RANGE(*axis); } if (axis->in_min>axis->in_max) { axis->in_min = axis->in_max = 0; axis->scale = 1; } axis->out_min = 0; axis->out_max = 0; axis->speed = 1; axis->mickeys = 0; }
/* These three functions demonstrate how to query dialog elements. */ int info1(void) { char buf1[256]; char buf2[256] = ""; int i, s = 0, n; listbox_getter(-1, &n); /* query the list proc */ for (i = 0; i < n; i++) { if (sel[i]) { uszprintf(buf1, sizeof buf1, "%i ", i); ustrzcat(buf2, sizeof buf2, buf1); s = 1; } } if (s) ustrzcat(buf2, sizeof buf2, "are in the multiple selection!"); else ustrzcat(buf2, sizeof buf2, "There is no multiple selection!"); uszprintf(buf1, sizeof buf1, "Item number %i is selected!", the_dialog[LIST_OBJECT].d1); alert("Info about the list:", buf1, buf2, "Ok", NULL, 0, 0); return D_O_K; }
/* handle the save command */ static void save_key_map(void) { int i; char *section, *option_format, option[80], tmp1[80], tmp2[80]; set_config_file("xkeymap.cfg"); section = uconvert_ascii("xkeymap", tmp1); option_format = uconvert_ascii("keycode%d", tmp2); for (i = 0; i < 256; i++) { if (keycode_to_scancode[i] > 0) { uszprintf(option, sizeof(option), option_format, i); set_config_int(section, option, keycode_to_scancode[i]); } } }
/* Updates the key descriptions from the ASCII values. */ static void update_key_descriptions(void) { char str[64]; int i; for (i = 0; i < KEY_MAX; i++) { int ascii = scancode_to_ascii (i); if (_pckeys_names[i]) _AL_FREE(_pckeys_names[i]); if (ascii > ' ') { uszprintf(str, sizeof str, "%c", ascii); _pckeys_names[i] = strdup (str); } else { _pckeys_names[i] = strdup(_keyboard_common_names[i]); } } }
/* mouse_init: * Here we open the mouse device, initialise anything that needs it, * and chain to the framework init routine. */ static int mouse_init (void) { char tmp1[128], tmp2[128], tmp3[128]; AL_CONST char *udevice; /* Find the device filename */ udevice = get_config_string (uconvert_ascii ("mouse", tmp1), uconvert_ascii ("mouse_device", tmp2), uconvert_ascii (DEVICE_FILENAME, tmp3)); /* Open mouse device. Devices are cool. */ intdrv.device = open (uconvert_toascii (udevice, tmp1), O_RDONLY | O_NONBLOCK); if (intdrv.device < 0) { uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("Unable to open %s: %s"), udevice, ustrerror (errno)); return -1; } /* Discard any garbage, so the next thing we read is a packet header */ sync_mouse (intdrv.device); return __al_linux_mouse_init (&intdrv); }
/* _xdga2_gfxdrv_init_drv: * Initializes driver and creates screen bitmap. */ static BITMAP *_xdga2_private_gfxdrv_init_drv(GFX_DRIVER *drv, int w, int h, int vw, int vh, int depth, int accel) { int dga_error_base, dga_major_version, dga_minor_version; int mode, mask, red_shift = 0, green_shift = 0, blue_shift = 0; long input_mask; char tmp1[128], tmp2[128]; BITMAP *bmp; /* This is just to test if the system driver has been installed properly */ if (_xwin.window == None) return NULL; /* Test that display is local. */ if (!_xdga2_private_display_is_local()) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("This driver needs local display")); return NULL; } /* Choose convenient size. */ if ((w == 0) && (h == 0)) { w = 640; h = 480; } if ((w < 80) || (h < 80) || (w > 4096) || (h > 4096)) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported screen size")); return NULL; } if (vw < w) vw = w; if (vh < h) vh = h; if (1 #ifdef ALLEGRO_COLOR8 && (depth != 8) #endif #ifdef ALLEGRO_COLOR16 && (depth != 15) && (depth != 16) #endif #ifdef ALLEGRO_COLOR24 && (depth != 24) #endif #ifdef ALLEGRO_COLOR32 && (depth != 32) #endif ) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported color depth")); return NULL; } /* Checks presence of DGA extension */ if (!XDGAQueryExtension(_xwin.display, &dga_event_base, &dga_error_base) || !XDGAQueryVersion(_xwin.display, &dga_major_version, &dga_minor_version)) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("DGA extension is not supported")); return NULL; } /* Works only with DGA 2.0 or newer */ if (dga_major_version < 2) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("DGA 2.0 or newer is required")); return NULL; } /* Attempts to access the framebuffer */ if (!XDGAOpenFramebuffer(_xwin.display, _xwin.screen)) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not open framebuffer")); return NULL; } /* Finds suitable video mode number */ mode = _xdga2_find_mode(w, h, vw, vh, depth); if (!mode) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Resolution not supported")); return NULL; } /* Sets DGA video mode */ dga_device = XDGASetMode(_xwin.display, _xwin.screen, mode); if (dga_device == NULL) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not switch to DGA mode")); return NULL; } _xwin.in_dga_mode = 2; _set_current_refresh_rate(dga_device->mode.verticalRefresh); set_display_switch_mode(SWITCH_NONE); /* Installs DGA color map */ if (_dga_cmap) { XFreeColormap(_xwin.display, _dga_cmap); _dga_cmap = 0; } if ((dga_device->mode.visualClass == PseudoColor) || (dga_device->mode.visualClass == GrayScale) || (dga_device->mode.visualClass == DirectColor)) _dga_cmap = XDGACreateColormap(_xwin.display, _xwin.screen, dga_device, AllocAll); else _dga_cmap = XDGACreateColormap(_xwin.display, _xwin.screen, dga_device, AllocNone); XDGAInstallColormap(_xwin.display, _xwin.screen, _dga_cmap); /* Sets up direct color shifts */ if (depth != 8) { for (mask = dga_device->mode.redMask, red_shift = 0; (mask & 1) == 0; mask >>= 1, red_shift++); for (mask = dga_device->mode.greenMask, green_shift = 0; (mask & 1) == 0; mask >>= 1, green_shift++); for (mask = dga_device->mode.blueMask, blue_shift = 0; (mask & 1) == 0; mask >>= 1, blue_shift++); } switch (depth) { case 15: _rgb_r_shift_15 = red_shift; _rgb_g_shift_15 = green_shift; _rgb_b_shift_15 = blue_shift; break; case 16: _rgb_r_shift_16 = red_shift; _rgb_g_shift_16 = green_shift; _rgb_b_shift_16 = blue_shift; break; case 24: _rgb_r_shift_24 = red_shift; _rgb_g_shift_24 = green_shift; _rgb_b_shift_24 = blue_shift; break; case 32: _rgb_r_shift_32 = red_shift; _rgb_g_shift_32 = green_shift; _rgb_b_shift_32 = blue_shift; break; } /* Enables input */ XSync(_xwin.display, True); input_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask; XDGASelectInput(_xwin.display, _xwin.screen, input_mask); if (_xwin_keyboard_focused) { (*_xwin_keyboard_focused)(FALSE, 0); keyboard_got_focus = TRUE; } _mouse_on = TRUE; /* Creates screen bitmap */ drv->linear = TRUE; bmp = _make_bitmap(dga_device->mode.imageWidth, dga_device->mode.imageHeight, (uintptr_t)dga_device->data, drv, depth, dga_device->mode.bytesPerScanline); if (!bmp) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Not enough memory")); return NULL; } drv->w = bmp->cr = w; drv->h = bmp->cb = h; drv->vid_mem = dga_device->mode.imageWidth * dga_device->mode.imageHeight * BYTES_PER_PIXEL(depth); if (accel) { /* Hardware acceleration has been requested */ /* Updates line switcher to accommodate framebuffer synchronization */ #ifdef ALLEGRO_NO_ASM bmp->write_bank = _xdga2_write_line; bmp->read_bank = _xdga2_write_line; #else bmp->write_bank = _xdga2_write_line_asm; bmp->read_bank = _xdga2_write_line_asm; #endif _screen_vtable.acquire = _xdga2_acquire; /* Checks for hardware acceleration support */ if (dga_device->mode.flags & XDGASolidFillRect) { /* XDGAFillRectangle is available */ _orig_hline = _screen_vtable.hline; _orig_vline = _screen_vtable.vline; _orig_rectfill = _screen_vtable.rectfill; _screen_vtable.hline = _xaccel_hline; _screen_vtable.vline = _xaccel_vline; _screen_vtable.rectfill = _xaccel_rectfill; _screen_vtable.clear_to_color = _xaccel_clear_to_color; gfx_capabilities |= (GFX_HW_HLINE | GFX_HW_FILL); } if (dga_device->mode.flags & XDGABlitRect) { /* XDGACopyArea is available */ _screen_vtable.blit_to_self = _xaccel_blit_to_self; _screen_vtable.blit_to_self_forward = _xaccel_blit_to_self; _screen_vtable.blit_to_self_backward = _xaccel_blit_to_self; gfx_capabilities |= GFX_HW_VRAM_BLIT; } if (dga_device->mode.flags & XDGABlitTransRect) { /* XDGACopyTransparentArea is available */ _orig_draw_sprite = _screen_vtable.draw_sprite; _orig_masked_blit = _screen_vtable.masked_blit; _screen_vtable.masked_blit = _xaccel_masked_blit; _screen_vtable.draw_sprite = _xaccel_draw_sprite; if (_screen_vtable.color_depth == 8) _screen_vtable.draw_256_sprite = _xaccel_draw_sprite; gfx_capabilities |= GFX_HW_VRAM_BLIT_MASKED; } RESYNC(); } /* Checks for triple buffering */ if (dga_device->mode.viewportFlags & XDGAFlipRetrace) gfx_capabilities |= GFX_CAN_TRIPLE_BUFFER; /* Sets up driver description */ uszprintf(_xdga2_driver_desc, sizeof(_xdga2_driver_desc), uconvert_ascii("X-Windows DGA 2.0 graphics%s", tmp1), uconvert_ascii(accel ? (gfx_capabilities ? " (accelerated)" : "") : " (software only)", tmp2)); drv->desc = _xdga2_driver_desc; return bmp; }
/* jack_init: * JACK init routine. */ static int jack_init(int input, int voices) { const char **ports; char tmp[128]; if (!jack_detect(input)) return -1; jack_bufsize = get_config_int("sound", "jack_buffer_size", jack_bufsize); if (jack_bufsize == -1) jack_bufsize = jack_get_buffer_size (jack_client); /* Those are already read in from the config file by Allegro. */ jack_16bit = (_sound_bits == 16 ? 1 : 0); jack_stereo = (_sound_stereo ? 1 : 0); /* Let Allegro mix in its native unsigned format. */ jack_signed = 0; jack_set_process_callback (jack_client, jack_process, NULL); output_left = jack_port_register (jack_client, jack_stereo ? "left" : "mono", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); if (jack_stereo) output_right = jack_port_register (jack_client, "right", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); jack_rate = jack_get_sample_rate (jack_client); jack_buffer = _AL_MALLOC_ATOMIC(jack_bufsize * (1 + jack_16bit) * (1 + jack_stereo)); if (!jack_buffer) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text( "Cannot allocate audio buffer")); jack_exit (input); return -1; } digi_jack.voices = voices; if (_mixer_init(jack_bufsize * (1 + jack_stereo), jack_rate, jack_stereo, jack_16bit, &digi_jack.voices)) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text( "Cannot init software mixer")); jack_exit (input); return -1; } _mix_some_samples((uintptr_t) jack_buffer, 0, jack_signed); if (jack_activate (jack_client)) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text( "Cannot activate Jack client")); jack_exit (input); return 1; } /* Try to connect the ports. Failure to connect is not critical, since with * JACK, users may connect/disconnect ports anytime, without Allegro caring. */ if ((ports = jack_get_ports (jack_client, NULL, NULL, JackPortIsPhysical|JackPortIsInput)) == NULL) { TRACE (PREFIX_I "Cannot find any physical playback ports"); } if (ports) { if (ports[0]) { if (jack_connect (jack_client, jack_port_name (output_left), ports[0]) == 0) TRACE (PREFIX_I "Connected left playback port to %s", ports[0]); } if (jack_stereo && ports[1]) { if (jack_connect (jack_client, jack_port_name (output_right), ports[1]) == 0) TRACE (PREFIX_I "Connected right playback port to %s", ports[1]); } _AL_FREE (ports); } uszprintf(jack_desc, sizeof(jack_desc), get_config_text ("Jack, client '%s': %d bits, %s, %d bps, %s"), jack_client_name, jack_16bit ? 16 : 8, uconvert_ascii((jack_signed ? "signed" : "unsigned"), tmp), jack_rate, uconvert_ascii((jack_stereo ? "stereo" : "mono"), tmp)); return 0; }
int eof_add_silence_recode_mp3(char * oggfn, unsigned long ms) { char sys_command[1024] = {0}; char backupfn[1024] = {0}; char wavfn[1024] = {0}; char soggfn[1024] = {0}; char mp3fn[1024] = {0}; SAMPLE * decoded = NULL; SAMPLE * combined = NULL; int bits; int stereo; int freq; unsigned long samples; int channels; unsigned long ctr,index; eof_log("eof_add_silence_recode_mp3() entered", 1); if(!oggfn || (ms == 0) || eof_silence_loaded) { return 21; //Return error: Invalid parameters } set_window_title("Adjusting Silence..."); /* back up original file */ (void) snprintf(backupfn, sizeof(backupfn) - 1, "%s.backup", oggfn); if(!exists(backupfn)) { (void) eof_copy_file(oggfn, backupfn); } /* decode MP3 */ (void) replace_filename(wavfn, eof_song_path, "decode.wav", 1024); (void) replace_filename(mp3fn, eof_song_path, "original.mp3", 1024); (void) uszprintf(sys_command, (int) sizeof(sys_command) - 1, "lame --decode \"%s\" \"%s\"", mp3fn, wavfn); (void) eof_system(sys_command); /* insert silence */ decoded = load_sample(wavfn); if(!decoded) { allegro_message("Error opening file.\nMake sure there are no Unicode or extended ASCII characters in this chart's file path."); return 22; //Return failure: Could not load decoded MP3 file } bits = decoded->bits; stereo = decoded->stereo; freq = decoded->freq; samples = (decoded->freq * ms) / 1000; //Calculate this manually instead of using msec_to_samples() because that function assumes the sample rate matches the current chart audio, and this may not be the case with the original MP3 file the user provided channels = stereo ? 2 : 1; combined = create_sample(bits,stereo,freq,samples+decoded->len); //Create a sample array long enough for the silence and the OGG file if(combined == NULL) { destroy_sample(decoded); return 23; //Return failure: Could not create a sample array for the combined audio } /* Add the PCM data for the silence */ if(bits == 8) { //Create 8 bit PCM data for(ctr=0,index=0;ctr < samples * channels;ctr++) { ((unsigned char *)(combined->data))[index++] = 0x80; } } else { //Create 16 bit PCM data for(ctr=0,index=0;ctr < samples * channels;ctr++) { ((unsigned short *)(combined->data))[index++] = 0x8000; } } /* Add the decoded OGG PCM data*/ if(bits == 8) { //Copy 8 bit PCM data for(ctr=0;ctr < decoded->len * channels;ctr++) { ((unsigned char *)(combined->data))[index++] = ((unsigned char *)(decoded->data))[ctr]; } } else { //Copy 16 bit PCM data for(ctr=0;ctr < decoded->len * channels;ctr++) { ((unsigned short *)(combined->data))[index++] = ((unsigned short *)(decoded->data))[ctr]; } } /* save combined WAV */ (void) replace_filename(wavfn, eof_song_path, "encode.wav", 1024); if(!save_wav(wavfn, combined)) { destroy_sample(decoded); //This is no longer needed destroy_sample(combined); //This is no longer needed return 24; //Return failure: Could not create the combined audio WAV file } /* destroy samples */ destroy_sample(decoded); //This is no longer needed destroy_sample(combined); //This is no longer needed /* encode the audio */ printf("%s\n%s\n", eof_song_path, wavfn); (void) replace_filename(soggfn, eof_song_path, "encode.ogg", 1024); #ifdef ALLEGRO_WINDOWS (void) uszprintf(sys_command, (int) sizeof(sys_command) - 1, "oggenc2 -o \"%s\" -b %d \"%s\"", soggfn, alogg_get_bitrate_ogg(eof_music_track) / 1000, wavfn); #else (void) uszprintf(sys_command, (int) sizeof(sys_command) - 1, "oggenc -o \"%s\" -b %d \"%s\"", soggfn, alogg_get_bitrate_ogg(eof_music_track) / 1000, wavfn); #endif (void) snprintf(eof_log_string, sizeof(eof_log_string) - 1, "\tCalling oggenc as follows: %s", sys_command); eof_log(eof_log_string, 1); if(eof_system(sys_command)) { //If oggenc failed, retry again by specifying a quality level (specifying bitrate can fail in some circumstances) eof_log("\t\toggenc failed. Retrying by specifying a quality level instead of a target bitrate", 1); #ifdef ALLEGRO_WINDOWS (void) uszprintf(sys_command, (int) sizeof(sys_command) - 1, "oggenc2 -o \"%s\" -q 9 \"%s\"", soggfn, wavfn); #else (void) uszprintf(sys_command, (int) sizeof(sys_command) - 1, "oggenc -o \"%s\" -q 9 \"%s\"", soggfn, wavfn); #endif (void) snprintf(eof_log_string, sizeof(eof_log_string) - 1, "\tCalling oggenc as follows: %s", sys_command); eof_log(eof_log_string, 1); if(eof_system(sys_command)) { //If oggenc failed again char tempfname[30] = {0}; char redirect[35] = {0}; if(eof_validate_temp_folder()) { //Ensure the correct working directory and presence of the temporary folder eof_log("\tCould not validate working directory and temp folder", 1); return 25; //Return failure: Could not validate cwd and temp folder } (void) snprintf(tempfname, sizeof(tempfname) - 1, "%soggenc.log", eof_temp_path_s); (void) snprintf(redirect, sizeof(redirect) - 1, " 2> %s", tempfname); (void) ustrzcat(sys_command, (int) sizeof(sys_command) - 1, redirect); //Append a redirection to the command to capture the output of oggenc if(eof_system(sys_command)) { //Run one last time to catch the error output (void) snprintf(eof_log_string, sizeof(eof_log_string) - 1, "\tOggenc failed. Please see %s for any errors it gave.", tempfname); eof_log(eof_log_string, 1); eof_fix_window_title(); return 26; //Return failure: Could not encode combined audio } } } /* replace the current OGG file with the new file */ (void) eof_copy_file(soggfn, oggfn); //Copy encode.ogg to the filename of the original OGG /* clean up */ (void) replace_filename(wavfn, eof_song_path, "decode.wav", 1024); (void) delete_file(wavfn); //Delete decode.wav (void) replace_filename(wavfn, eof_song_path, "encode.wav", 1024); (void) delete_file(wavfn); //Delete encode.wav (void) delete_file(soggfn); //Delete encode.ogg if(eof_load_ogg(oggfn, 0)) { //If the combined audio was loaded eof_fix_waveform_graph(); eof_fix_spectrogram(); eof_fix_window_title(); eof_chart_length = eof_music_length; return 0; //Return success } eof_fix_window_title(); return 27; //Return error: Could not load new audio }
int eof_add_silence_recode(char * oggfn, unsigned long ms) { char sys_command[1024] = {0}; char backupfn[1024] = {0}; char wavfn[1024] = {0}; char soggfn[1024] = {0}; ALOGG_OGG *oggfile = NULL; SAMPLE *decoded = NULL, *combined = NULL; int bits; int stereo; int freq; unsigned long samples; int channels; unsigned long ctr,index; void * oggbuffer = NULL; int bitrate; eof_log("eof_add_silence_recode() entered", 1); if(!oggfn || (ms == 0) || eof_silence_loaded) { return 41; //Return failure: Invalid parameters } set_window_title("Adjusting Silence..."); /* back up original file */ (void) snprintf(backupfn, sizeof(backupfn) - 1, "%s.backup", oggfn); if(!exists(backupfn)) { (void) eof_copy_file(oggfn, backupfn); } /* Decode the OGG file into memory */ //Load OGG file into memory oggbuffer = eof_buffer_file(oggfn, 0); //Decode the OGG from buffer instead of from file because the latter cannot support special characters in the file path due to limitations with fopen() if(!oggbuffer) { (void) snprintf(eof_log_string, sizeof(eof_log_string) - 1, "\tError reading OGG: \"%s\"", strerror(errno)); //Get the Operating System's reason for the failure eof_log(eof_log_string, 1); return 42; //Return failure: Could not buffer chart audio into memory } oggfile=alogg_create_ogg_from_buffer(oggbuffer, (int)file_size_ex(oggfn)); if(oggfile == NULL) { eof_log("ALOGG failed to open input audio file", 1); free(oggbuffer); return 43; //Return failure: Could not process buffered chart audio } //Decode OGG into memory decoded=alogg_create_sample_from_ogg(oggfile); if(decoded == NULL) { alogg_destroy_ogg(oggfile); free(oggbuffer); return 44; //Return failure: Could not decode chart audio to memory } /* Create a SAMPLE array large enough for the leading silence and the decoded OGG */ bits = alogg_get_wave_bits_ogg(oggfile); stereo = alogg_get_wave_is_stereo_ogg(oggfile); freq = alogg_get_wave_freq_ogg(oggfile); alogg_destroy_ogg(oggfile); //This is no longer needed oggfile = NULL; samples = msec_to_samples(ms); channels = stereo ? 2 : 1; combined = create_sample(bits,stereo,freq,samples+decoded->len); //Create a sample array long enough for the silence and the OGG file if(combined == NULL) { destroy_sample(decoded); return 45; //Return failure: Could not create a sample array for the combined audio } /* Add the PCM data for the silence */ if(bits == 8) { //Create 8 bit PCM data for(ctr=0,index=0;ctr < samples * channels;ctr++) { ((unsigned char *)(combined->data))[index++] = 0x80; } } else { //Create 16 bit PCM data for(ctr=0,index=0;ctr < samples * channels;ctr++) { ((unsigned short *)(combined->data))[index++] = 0x8000; } } /* Add the decoded OGG PCM data*/ if(bits == 8) { //Copy 8 bit PCM data for(ctr=0;ctr < decoded->len * channels;ctr++) { ((unsigned char *)(combined->data))[index++] = ((unsigned char *)(decoded->data))[ctr]; } } else { //Copy 16 bit PCM data for(ctr=0;ctr < decoded->len * channels;ctr++) { ((unsigned short *)(combined->data))[index++] = ((unsigned short *)(decoded->data))[ctr]; } } /* encode the audio */ destroy_sample(decoded); //This is no longer needed free(oggbuffer); (void) replace_filename(wavfn, eof_song_path, "encode.wav", 1024); (void) save_wav(wavfn, combined); destroy_sample(combined); //This is no longer needed (void) replace_filename(soggfn, eof_song_path, "encode.ogg", 1024); bitrate = alogg_get_bitrate_ogg(eof_music_track) / 1000; if(!bitrate) { //A user found that in an audio file with a really high sample rate (ie. 96KHz), alogg_get_bitrate_ogg() may return zero instead of an expected value bitrate = 256; //In case this happens, use a bitrate of 256Kbps, which should be good enough for a very high quality file } #ifdef ALLEGRO_WINDOWS (void) uszprintf(sys_command, (int) sizeof(sys_command) - 1, "oggenc2 -o \"%s\" -b %d \"%s\"", soggfn, bitrate, wavfn); #else (void) uszprintf(sys_command, (int) sizeof(sys_command) - 1, "oggenc -o \"%s\" -b %d \"%s\"", soggfn, bitrate, wavfn); #endif (void) snprintf(eof_log_string, sizeof(eof_log_string) - 1, "\tCalling oggenc as follows: %s", sys_command); eof_log(eof_log_string, 1); if(eof_system(sys_command)) { //If oggenc failed, retry again by specifying a quality level (specifying bitrate can fail in some circumstances) eof_log("\t\toggenc failed. Retrying by specifying a quality level instead of a target bitrate", 1); #ifdef ALLEGRO_WINDOWS (void) uszprintf(sys_command, (int) sizeof(sys_command) - 1, "oggenc2 -o \"%s\" -q 9 \"%s\"", soggfn, wavfn); #else (void) uszprintf(sys_command, (int) sizeof(sys_command) - 1, "oggenc -o \"%s\" -q 9 \"%s\"", soggfn, wavfn); #endif (void) snprintf(eof_log_string, sizeof(eof_log_string) - 1, "\tCalling oggenc as follows: %s", sys_command); eof_log(eof_log_string, 1); if(eof_system(sys_command)) { //If oggenc failed again char tempfname[30] = {0}; char redirect[35] = {0}; if(eof_validate_temp_folder()) { //Ensure the correct working directory and presence of the temporary folder eof_log("\tCould not validate working directory and temp folder", 1); return 46; //Return failure: Could not validate cwd and temp folder } (void) snprintf(tempfname, sizeof(tempfname) - 1, "%soggenc.log", eof_temp_path_s); (void) snprintf(redirect, sizeof(redirect) - 1, " 2> %s", tempfname); (void) ustrzcat(sys_command, (int) sizeof(sys_command) - 1, redirect); //Append a redirection to the command to capture the output of oggenc if(eof_system(sys_command)) { //Run one last time to catch the error output (void) snprintf(eof_log_string, sizeof(eof_log_string) - 1, "\tOggenc failed. Please see %s for any errors it gave.", tempfname); eof_log(eof_log_string, 1); eof_fix_window_title(); return 47; //Return failure: Could not encode combined audio } } } /* replace the current OGG file with the new file */ (void) eof_copy_file(soggfn, oggfn); //Copy encode.ogg to the filename of the original OGG /* clean up */ (void) delete_file(soggfn); //Delete encode.ogg (void) delete_file(wavfn); //Delete encode.wav if(eof_load_ogg(oggfn, 0)) { //If the combined audio was loaded eof_fix_waveform_graph(); eof_fix_spectrogram(); eof_fix_window_title(); eof_chart_length = eof_music_length; return 0; //Return success } eof_fix_window_title(); return 48; //Return error: Could not load new audio }
int eof_add_silence(char * oggfn, unsigned long ms) { char sys_command[1024] = {0}; char backupfn[1024] = {0}; //The file path of the backup of the target audio file char wavfn[1024] = {0}; //The file path of the silent WAV file created char soggfn[1024] = {0}; //The file path of the silent OGG file created char oggcfn[1024] = {0}; //The file path to the oggCat utility char old_wd[1024] = {0}; //Store working directory before changing it so we can get back char *rel_oggfn; //Relative file path to the target audio file char *rel_backupfn; //Relative file path to the backup of the target audio file SAMPLE * silence_sample; int retval; if(!oggfn || (ms == 0) || eof_silence_loaded) { return 1; //Return error: Invalid parameters } eof_log("eof_add_silence() entered", 1); set_window_title("Adjusting Silence..."); /* back up original file */ (void) snprintf(backupfn, sizeof(backupfn) - 1, "%s.backup", oggfn); if(!exists(backupfn)) { (void) eof_copy_file(oggfn, backupfn); } (void) delete_file(oggfn); silence_sample = create_silence_sample(ms); if(!silence_sample) { eof_fix_window_title(); return 2; //Return error: Couldn't create silent audio } (void) replace_filename(wavfn, eof_song_path, "silence.wav", 1024); (void) save_wav(wavfn, silence_sample); destroy_sample(silence_sample); (void) replace_filename(soggfn, eof_song_path, "silence.ogg", 1024); #ifdef ALLEGRO_WINDOWS (void) uszprintf(sys_command, (int) sizeof(sys_command) - 1, "oggenc2 -o \"%s\" -b %d \"%s\"", soggfn, alogg_get_bitrate_ogg(eof_music_track) / 1000, wavfn); #else (void) uszprintf(sys_command, (int) sizeof(sys_command) - 1, "oggenc -o \"%s\" -b %d \"%s\"", soggfn, alogg_get_bitrate_ogg(eof_music_track) / 1000, wavfn); #endif if(eof_system(sys_command)) { eof_fix_window_title(); return 3; //Return error: Could not encode silent audio } /* stitch the original file to the silence file */ if(!getcwd(old_wd, 1024)) { //If the current working directory could not be obtained eof_fix_window_title(); return 4; //Return error: Could not obtain current working directory } (void) eof_chdir(eof_song_path); //Change directory to the project's folder, since oggCat does not support paths that have any Unicode/extended ASCII, relative paths will be given #ifdef ALLEGRO_WINDOWS get_executable_name(oggcfn, 1024); (void) replace_filename(oggcfn, oggcfn, "oggCat.exe", 1024); //Build the full path to oggCat #else ustrzcpy(oggcfn, 1024, "oggCat"); #endif rel_oggfn = get_filename(oggfn); //Get the relative path to the target OGG file rel_backupfn = get_filename(backupfn); //Get the relative path to the backup of the target OGG file //Call oggCat while the current working directory is the project folder. This way, if the project folder's path contains any Unicode or extended ASCII, oggCat won't fail #ifdef ALLEGRO_WINDOWS //For some reason, the Windows build needs extra quotation marks to enclose the entire command if the command begins with a full executable path in quote marks (void) uszprintf(sys_command, (int) sizeof(sys_command) - 1, "\"\"%s\" \"%s\" \"silence.ogg\" \"%s\"\"", oggcfn, rel_oggfn, rel_backupfn); #else (void) uszprintf(sys_command, (int) sizeof(sys_command) - 1, "\"%s\" \"%s\" \"silence.ogg\" \"%s\"", oggcfn, rel_oggfn, rel_backupfn); //Use oggCat to overwrite the target OGG file with the silent audio concatenated with the backup of the target OGG file #endif retval = eof_system(sys_command); /* change back to the program folder */ if(eof_chdir(old_wd)) { allegro_message("Could not change directory to EOF's program folder!\n%s", backupfn); return 5; //Return error: Could not set working directory } if(retval) { //If the command failed (void) snprintf(eof_log_string, sizeof(eof_log_string) - 1, "\tError issuing command \"%s\" from path \"%s\"", sys_command, eof_song_path); eof_log(eof_log_string, 1); (void) eof_copy_file(backupfn, oggfn); //Restore the original OGG file eof_fix_window_title(); return 6; //Return error: oggCat failed } /* clean up */ (void) delete_file(wavfn); //Delete silence.wav (void) delete_file(soggfn); //Delete silence.ogg if(eof_load_ogg(oggfn, 0)) { //If the combined audio was loaded eof_fix_waveform_graph(); eof_fix_spectrogram(); eof_fix_window_title(); eof_chart_length = eof_music_length; return 0; //Return success } eof_fix_window_title(); //If this part of the function is reached, the OGG failed to load if(exists(oggfn)) return 7; //Return error: Could not load new audio, but audio file exists return 8; //Return error: Could not load new audio, file does not exist }
/* mpu_detect: * Detects the presence of an MPU-401 compatible midi interface. */ static int mpu_detect(int input) { char *blaster = getenv("BLASTER"); char tmp1[64], tmp2[64]; int i; _mpu_port = get_config_hex(uconvert_ascii("sound", tmp1), uconvert_ascii("mpu_port", tmp2), -1); _mpu_irq = get_config_hex(uconvert_ascii("sound", tmp1), uconvert_ascii("mpu_irq", tmp2), -1); /* only bother with the detection if we aren't already active */ if (!mpu_output_mode) { /* parse BLASTER env */ if ((blaster) && (_mpu_port < 0)) { while (*blaster) { while ((*blaster == ' ') || (*blaster == '\t')) blaster++; if (((*blaster == 'p') || (*blaster == 'P')) && (_mpu_port < 0)) _mpu_port = strtol(blaster+1, NULL, 16); if (((*blaster == 'i') || (*blaster == 'I')) && (_mpu_irq < 0)) _mpu_irq = strtol(blaster+1, NULL, 10); while ((*blaster) && (*blaster != ' ') && (*blaster != '\t')) blaster++; } } /* if that didn't work, guess :-) */ if (_mpu_port < 0) _mpu_port = 0x330; if (_mpu_irq < 0) { if (_sound_irq > 0) _mpu_irq = _sound_irq; else _mpu_irq = 7; } mpu_int = _map_irq(_mpu_irq); /* check whether the MPU is there */ outportb(_mpu_port+1, 0xFF); mpu_input(); if (wait_for_mpu(0x40, _mpu_port+1) != 0) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("MPU-401 not found")); return FALSE; } uszprintf(mpu_desc, sizeof(mpu_desc), get_config_text("MPU-401 MIDI interface on port %X, using IRQ %d"), _mpu_port, _mpu_irq); midi_mpu401.desc = mpu_desc; } /* can we handle input? */ if (input) { static int conflicts[] = { DIGI_SB10, DIGI_SB15, DIGI_SB20, DIGI_SBPRO, DIGI_SB16, DIGI_AUDIODRIVE, 0 }; mpu_piggyback = FALSE; for (i=0; conflicts[i]; i++) { if (digi_card == conflicts[i]) { if (_sound_irq == _mpu_irq) { mpu_piggyback = TRUE; if (digi_card != DIGI_SB16) { uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("MPU-401 and %s conflict over IRQ %d"), digi_driver->name, _mpu_irq); return FALSE; } } break; } } } return TRUE; }
/* be_gfx_bwindow_init: * Initializes specified video mode. */ extern "C" struct BITMAP *be_gfx_bwindow_init(int w, int h, int v_w, int v_h, int color_depth) { BITMAP *bmp; if (1 #ifdef ALLEGRO_COLOR8 && (color_depth != 8) #endif #ifdef ALLEGRO_COLOR16 && (color_depth != 15) && (color_depth != 16) #endif #ifdef ALLEGRO_COLOR32 && (color_depth != 32) #endif ) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported color depth")); return NULL; } if ((!v_w) && (!v_h)) { v_w = w; v_h = h; } if ((w != v_w) || (h != v_h)) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported virtual resolution")); return NULL; } set_display_switch_mode(SWITCH_PAUSE); _be_allegro_window = new BeAllegroWindow(BRect(0, 0, w-1, h-1), wnd_title, B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, B_NOT_RESIZABLE | B_NOT_ZOOMABLE, B_CURRENT_WORKSPACE, v_w, v_h, color_depth); _be_window = _be_allegro_window; if (!_be_allegro_window->buffer->IsValid() || ((color_depth == 8) && (!_be_allegro_window->aux_buffer->IsValid()))) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Not enough memory")); goto cleanup; } _be_mouse_view = new BView(_be_allegro_window->Bounds(), "allegro mouse view", B_FOLLOW_ALL_SIDES, 0); _be_allegro_window->Lock(); _be_allegro_window->AddChild(_be_mouse_view); _be_allegro_window->Unlock(); _be_mouse_window = _be_allegro_window; _be_mouse_window_mode = true; release_sem(_be_mouse_view_attached); _be_allegro_window->MoveTo(6, 25); _be_allegro_window->Show(); gfx_beos_bwindow.w = w; gfx_beos_bwindow.h = h; gfx_beos_bwindow.linear = TRUE; gfx_beos_bwindow.vid_mem = _be_allegro_window->buffer->BitsLength(); bmp = _make_bitmap(v_w, v_h, (unsigned long)_be_allegro_window->buffer->Bits(), &gfx_beos_bwindow, color_depth, _be_allegro_window->buffer->BytesPerRow()); if (!bmp) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Not enough memory")); goto cleanup; } #ifdef ALLEGRO_NO_ASM bmp->read_bank = (void *)_be_gfx_bwindow_read_write_bank; bmp->write_bank = (void *)_be_gfx_bwindow_read_write_bank; _screen_vtable.unwrite_bank = (void *)_be_gfx_bwindow_unwrite_bank; #else bmp->read_bank = _be_gfx_bwindow_read_write_bank_asm; bmp->write_bank = _be_gfx_bwindow_read_write_bank_asm; _screen_vtable.unwrite_bank = _be_gfx_bwindow_unwrite_bank_asm; #endif _screen_vtable.acquire = be_gfx_bwindow_acquire; _screen_vtable.release = be_gfx_bwindow_release; _be_gfx_set_truecolor_shifts(); uszprintf(driver_desc, sizeof(driver_desc), get_config_text("BWindow object, %d bit BBitmap framebuffer"), color_depth); gfx_beos_bwindow.desc = driver_desc; snooze(50000); _be_gfx_initialized = true; return bmp; cleanup: be_gfx_bwindow_exit(NULL); return NULL; }
/* x_get_keyboard_mapping: * Generate a mapping from X11 keycodes to Allegro KEY_* codes. We have * two goals: Every keypress should be mapped to a distinct Allegro KEY_* * code. And we want the KEY_* codes to match the pressed * key to some extent. To do the latter, the X11 KeySyms produced by a key * are examined. If a match is found in the table above, the mapping is * added to the mapping table. If no known KeySym is found for a key (or * the same KeySym is found for more keys) - the remaining keys are * distributed arbitrarily to the remaining KEY_* codes. * * In a future version, this could be simplified by mapping *all* the X11 * KeySyms to KEY_* codes. */ void _xwin_get_keyboard_mapping(void) { int i; int count; int missing = 0; memset(used, 0, sizeof used); memset(_xwin.keycode_to_scancode, 0, sizeof _xwin.keycode_to_scancode); XLOCK(); XDisplayKeycodes(_xwin.display, &min_keycode, &max_keycode); count = 1 + max_keycode - min_keycode; if (keysyms) { XFree(keysyms); } keysyms = XGetKeyboardMapping(_xwin.display, min_keycode, count, &sym_per_key); TRACE (PREFIX_I "%i keys, %i symbols per key.\n", count, sym_per_key); missing = 0; for (i = min_keycode; i <= max_keycode; i++) { KeySym sym = keysyms[sym_per_key * (i - min_keycode)]; KeySym sym2 = keysyms[sym_per_key * (i - min_keycode) + 1]; char *sym_str, *sym2_str; int allegro_key = 0; sym_str = XKeysymToString(sym); sym2_str = XKeysymToString(sym2); TRACE (PREFIX_I "key [%i: %s %s]", i, sym_str ? sym_str : "NULL", sym2_str ? sym2_str : "NULL"); /* Hack for French keyboards, to correctly map KEY_0 to KEY_9. */ if (sym2 >= XK_0 && sym2 <= XK_9) { allegro_key = find_allegro_key(sym2); } if (!allegro_key) { if (sym != NoSymbol) { allegro_key = find_allegro_key(sym); if (allegro_key == 0) { missing++; TRACE (" defering.\n"); } } else { /* No KeySym for this key - ignore it. */ _xwin.keycode_to_scancode[i] = -1; TRACE (" not assigned.\n"); } } if (allegro_key) { if (used[allegro_key]) { TRACE(" *double*"); } _xwin.keycode_to_scancode[i] = allegro_key; key_names[allegro_key] = XKeysymToString(keysyms[sym_per_key * (i - min_keycode)]); used[allegro_key] = 1; TRACE(" assigned to %i.\n", allegro_key); } } if (missing) { /* The keys still not assigned are just assigned arbitrarily now. */ for (i = min_keycode; i <= max_keycode; i++) { if (_xwin.keycode_to_scancode[i] == 0) { find_unknown_key_assignment(i); } } } if (xmodmap) XFreeModifiermap(xmodmap); xmodmap = XGetModifierMapping(_xwin.display); for (i = 0; i < 8; i++) { int j; TRACE (PREFIX_I "Modifier %d:", i + 1); for (j = 0; j < xmodmap->max_keypermod; j++) { KeySym sym = XKeycodeToKeysym(_xwin.display, xmodmap->modifiermap[i * xmodmap->max_keypermod + j], 0); char *sym_str = XKeysymToString(sym); TRACE(" %s", sym_str ? sym_str : "NULL"); } TRACE("\n"); } /* The [xkeymap] section can be useful, e.g. if trying to play a * game which has X and Y hardcoded as KEY_X and KEY_Y to mean * left/right movement, but on the X11 keyboard X and Y are far apart. * For normal use, a user never should have to touch [xkeymap] anymore * though, and proper written programs will not hardcode such mappings. */ { char *section, *option_format; char option[128], tmp1[128], tmp2[128]; section = uconvert_ascii("xkeymap", tmp1); option_format = uconvert_ascii("keycode%d", tmp2); for (i = min_keycode; i <= max_keycode; i++) { int scancode; uszprintf(option, sizeof(option), option_format, i); scancode = get_config_int(section, option, -1); if (scancode > 0) { _xwin.keycode_to_scancode[i] = scancode; TRACE(PREFIX_I "User override: KeySym %i assigned to %i.\n", i, scancode); } } } XUNLOCK(); }
/* alsa_init: * ALSA init routine. */ static int alsa_init(int input, int voices) { int ret = 0; char tmp1[128], tmp2[128]; int format = 0; unsigned int numfrags = 0; snd_pcm_uframes_t fragsize; if (input) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Input is not supported")); return -1; } ALSA9_CHECK(snd_output_stdio_attach(&snd_output, stdout, 0)); alsa_device = get_config_string(uconvert_ascii("sound", tmp1), uconvert_ascii("alsa_device", tmp2), alsa_device); alsa_mixer_device = get_config_string(uconvert_ascii("sound", tmp1), uconvert_ascii("alsa_mixer_device", tmp2), alsa_mixer_device); fragsize = get_config_int(uconvert_ascii("sound", tmp1), uconvert_ascii("alsa_fragsize", tmp2), 0); numfrags = get_config_int(uconvert_ascii("sound", tmp1), uconvert_ascii("alsa_numfrags", tmp2), ALSA_DEFAULT_NUMFRAGS); ret = snd_pcm_open(&pcm_handle, alsa_device, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); if (ret < 0) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not open card/pcm device")); return -1; } snd_mixer_open(&alsa_mixer, 0); if (alsa_mixer && snd_mixer_attach(alsa_mixer, alsa_mixer_device) >= 0 && snd_mixer_selem_register (alsa_mixer, NULL, NULL) >= 0 && snd_mixer_load(alsa_mixer) >= 0) { const char *alsa_mixer_elem_name = get_config_string(uconvert_ascii("sound", tmp1), uconvert_ascii("alsa_mixer_elem", tmp2), "PCM"); alsa_mixer_elem = snd_mixer_first_elem(alsa_mixer); while (alsa_mixer_elem) { const char *name = snd_mixer_selem_get_name(alsa_mixer_elem); if (strcasecmp(name, alsa_mixer_elem_name) == 0) { snd_mixer_selem_get_playback_volume_range(alsa_mixer_elem, &alsa_mixer_elem_min, &alsa_mixer_elem_max); alsa_mixer_allegro_ratio = (double) (alsa_mixer_elem_max - alsa_mixer_elem_min) / (double) 255; break; } alsa_mixer_elem = snd_mixer_elem_next(alsa_mixer_elem); } } /* Set format variables. */ alsa_bits = (_sound_bits == 8) ? 8 : 16; alsa_stereo = (_sound_stereo) ? 1 : 0; alsa_rate = (_sound_freq > 0) ? _sound_freq : 44100; alsa_signed = 0; format = ((alsa_bits == 16) ? SND_PCM_FORMAT_U16_NE : SND_PCM_FORMAT_U8); switch (format) { case SND_PCM_FORMAT_U8: alsa_bits = 8; break; case SND_PCM_FORMAT_U16_NE: if (sizeof(short) != 2) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported sample format")); goto Error; } break; default: ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported sample format")); goto Error; } alsa_sample_size = (alsa_bits / 8) * (alsa_stereo ? 2 : 1); if (fragsize == 0) { unsigned int size = alsa_rate * ALSA_DEFAULT_BUFFER_MS / 1000 / numfrags; fragsize = 1; while (fragsize < size) fragsize <<= 1; } snd_pcm_hw_params_malloc(&hwparams); snd_pcm_sw_params_malloc(&swparams); ALSA9_CHECK(snd_pcm_hw_params_any(pcm_handle, hwparams)); ALSA9_CHECK(snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)); ALSA9_CHECK(snd_pcm_hw_params_set_format(pcm_handle, hwparams, format)); ALSA9_CHECK(snd_pcm_hw_params_set_channels(pcm_handle, hwparams, alsa_stereo + 1)); ALSA9_CHECK(snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &alsa_rate, NULL)); ALSA9_CHECK(snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams, &fragsize, NULL)); ALSA9_CHECK(snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &numfrags, NULL)); ALSA9_CHECK(snd_pcm_hw_params(pcm_handle, hwparams)); ALSA9_CHECK(snd_pcm_hw_params_get_period_size(hwparams, &alsa_bufsize, NULL)); ALSA9_CHECK(snd_pcm_hw_params_get_periods(hwparams, &alsa_fragments, NULL)); TRACE (PREFIX_I "alsa_bufsize = %ld, alsa_fragments = %d\n", alsa_bufsize, alsa_fragments); ALSA9_CHECK(snd_pcm_sw_params_current(pcm_handle, swparams)); ALSA9_CHECK(snd_pcm_sw_params_set_start_threshold(pcm_handle, swparams, alsa_bufsize)); ALSA9_CHECK(snd_pcm_sw_params_set_avail_min(pcm_handle, swparams, fragsize)); ALSA9_CHECK(snd_pcm_sw_params_set_xfer_align(pcm_handle, swparams, 1)); ALSA9_CHECK(snd_pcm_sw_params(pcm_handle, swparams)); /* Allocate mixing buffer. */ alsa_bufdata = _AL_MALLOC_ATOMIC(alsa_bufsize * alsa_sample_size); if (!alsa_bufdata) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not allocate audio buffer")); goto Error; } /* Initialise mixer. */ digi_alsa.voices = voices; if (_mixer_init(alsa_bufsize * (alsa_stereo ? 2 : 1), alsa_rate, alsa_stereo, ((alsa_bits == 16) ? 1 : 0), &digi_alsa.voices) != 0) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not init software mixer")); goto Error; } snd_pcm_prepare(pcm_handle); pdc = snd_pcm_poll_descriptors_count (pcm_handle); if (pdc <= 0) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Invalid poll descriptors count")); goto Error; } ufds = _AL_MALLOC(sizeof(struct pollfd) * pdc); if (ufds == NULL) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Not enough memory for poll descriptors")); goto Error; } ALSA9_CHECK(snd_pcm_poll_descriptors(pcm_handle, ufds, pdc)); poll_next = 0; _mix_some_samples((uintptr_t) alsa_bufdata, 0, alsa_signed); /* Add audio interrupt. */ _unix_bg_man->register_func(alsa_update); uszprintf(alsa_desc, sizeof(alsa_desc), get_config_text ("Alsa 0.9, Device '%s': %d bits, %s, %d bps, %s"), alsa_device, alsa_bits, uconvert_ascii((alsa_signed ? "signed" : "unsigned"), tmp1), alsa_rate, uconvert_ascii((alsa_stereo ? "stereo" : "mono"), tmp2)); digi_driver->desc = alsa_desc; return 0; Error: if (pcm_handle) { snd_pcm_close(pcm_handle); pcm_handle = NULL; } return -1; }
void initialize() { char buf[1024]; int i; // Do the libxml binary compatibility check initXML(); // Initialise Allegro allegro_init(); install_keyboard(); install_mouse(); install_timer(); set_config_file("rpgedit.cfg"); int grph_drv = (get_config_int("video", "fullscreen", 1)) ? GFX_AUTODETECT_FULLSCREEN : GFX_AUTODETECT_WINDOWED; int screen_w = get_config_int("video", "width", 800); int screen_h = get_config_int("video", "height", 600); if (get_config_int("tile_zoom", "grid", 1)) { showTileGrid = true; } set_color_conversion( (COLORCONV_TOTAL & ~( COLORCONV_32A_TO_8 | COLORCONV_32A_TO_15 | COLORCONV_32A_TO_16 | COLORCONV_32A_TO_24 )) ); int colordepth = 0; if (grph_drv == GFX_AUTODETECT_WINDOWED) { colordepth = desktop_color_depth(); } if (colordepth == 0) { colordepth = 16; } set_color_depth(colordepth); if (set_gfx_mode(grph_drv, screen_w, screen_h, 0, 0) != 0) { set_color_depth(15); if (set_gfx_mode(grph_drv, screen_w, screen_h, 0, 0) != 0) { set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); allegro_message("Unable to set graphic mode\n%s\n", allegro_error); exit(1); } } buffer = create_bitmap(SCREEN_W, SCREEN_H); // Initialize GUI look and feel stuff agup_init(aphoton_theme); gui_fg_color = agup_fg_color; gui_bg_color = agup_bg_color; gui_shadow_box_proc = d_agup_shadow_box_proc; gui_button_proc = d_agup_button_proc; gui_edit_proc = d_agup_edit_proc; gui_text_list_proc = d_agup_text_list_proc; engine_data = load_datafile("gui.dat"); DATAFILE* font_data = find_datafile_object(engine_data, "SmallFont"); if (font_data) font = (FONT*)font_data->dat; engine_font = font; DATAFILE* mouse_pointer = find_datafile_object(engine_data, "_MS_STD_BMP"); if (mouse_pointer) set_mouse_sprite((BITMAP*)mouse_pointer->dat); DATAFILE* logo = find_datafile_object(engine_data, "MoonlightLogo"); if (logo) about_dlg[1].dp = (BITMAP*)logo->dat; else console.log(CON_QUIT, CON_ALWAYS, "Error loading MoonlightLogo"); console.log(CON_LOG, CON_ALWAYS, "Loading module \"data\"..."); module = new Module("data"); // Lua initialisation console.log(CON_LOG, CON_ALWAYS, "Initialising scripting environment..."); initScripting(); D_AUTOTEXT_STATUS.dp2 = status_message; D_AUTOTEXT_MAPINFO.dp2 = status_mapinfo; set_dialog_color(main_dlg, agup_fg_color, agup_bg_color); set_dialog_color(newmap_dlg, agup_fg_color, agup_bg_color); set_dialog_color(import_tileset_dlg, agup_fg_color, agup_bg_color); set_dialog_color(export_tileset_dlg, agup_fg_color, agup_bg_color); set_dialog_color(resizemap_dlg, agup_fg_color, agup_bg_color); set_dialog_color(about_dlg, agup_fg_color, agup_bg_color); // Position the dialogs on the screen int margin = 6; int zoom_w = get_config_int("tile_zoom", "zoom_width", 120) - 1; int zoom_h = get_config_int("tile_zoom", "zoom_height", 120) - 1; int x, y, w, h; // Main (back + menu) set_dialog_size(&main_dlg[0], -2, -2, SCREEN_W + 4, SCREEN_H + 4); set_dialog_size(&main_dlg[1], 0, 0, SCREEN_W, 15); // Status bars set_dialog_size(&main_dlg[6], 0, SCREEN_H - 17, SCREEN_W - 256, 17); set_dialog_size(&main_dlg[7], SCREEN_W - 256, SCREEN_H - 17, 256, 17); set_dialog_size(&main_dlg[8], 3, SCREEN_H - 14, SCREEN_W - 262, 11); set_dialog_size(&main_dlg[9], SCREEN_W - 253, SCREEN_H - 14, 250, 11); // Edit tile area w = zoom_w + 4; h = zoom_h + 4; x = margin; y = main_dlg[6].y - margin - h; set_dialog_size(&edit_tile_layer[0], x, y, w, h); set_dialog_size(&edit_tile_layer[1], x + 2, y + 2, w - 4, h - 4); set_dialog_size(&edit_tile_layer[2], x + margin + w, y + h - 14, 50, 14); // Color sliders x += w + margin; w = 128; set_dialog_size(&edit_tile_layer[8], x, y, 16, 8); set_dialog_size(&edit_tile_layer[9], x, y + 16, 16, 8); set_dialog_size(&edit_tile_layer[10], x, y + 32, 16, 8); set_dialog_size(&edit_tile_layer[11], x, y + 48 + 8, 16, 8); set_dialog_size(&edit_tile_layer[12], x, y + 64 + 8, 16, 8); set_dialog_size(&edit_tile_layer[3], x + 16, y, w, 8); set_dialog_size(&edit_tile_layer[4], x + 16, y + 16, w, 8); set_dialog_size(&edit_tile_layer[5], x + 16, y + 32, w, 8); set_dialog_size(&edit_tile_layer[6], x + 16, y + 48 + 8, w, 8); set_dialog_size(&edit_tile_layer[7], x + 16, y + 64 + 8, w, 8); set_dialog_size(&edit_tile_layer[13], x + 16 + w + 4, y - 1, 11, 10); set_dialog_size(&edit_tile_layer[14], x + 16 + w + 4, y + 16 - 1, 11, 10); set_dialog_size(&edit_tile_layer[15], x + 16 + w + 4, y + 32 - 1, 11, 10); set_dialog_size(&edit_tile_layer[20], x + 16 + w + 18, y + 4, 18, 32); // Select tile area x = edit_tile_layer[20].x + edit_tile_layer[20].w + margin; w = SCREEN_W - x - margin; set_dialog_size(&edit_tile_layer[16], x, y, 104, h); set_dialog_size(&edit_tile_layer[17], x + 104, y, w - 104, h); set_dialog_size(&edit_tile_layer[18], x + 104 + 2, y + 2, w - 104 - 4 - 11, h - 4); set_dialog_size(&edit_tile_layer[19], x + w - 14, y, 14, h); // Obstacle edit stuff w = 24; h = 24; x = margin; y = main_dlg[6].y - margin - h; for (i = 0; i < 5; i++) { set_dialog_size(&edit_obstacle_layer[i], x + i*(w+margin), y, w, h); set_dialog_size(&edit_obstacle_layer[i+5], x + i*(w+margin) + 2, y + 2, w - 4, h - 4); } // Edit map area x = margin; y = 16 + margin; w = SCREEN_W - 2 * margin; h = edit_obstacle_layer[0].y - margin - y; set_dialog_size(&main_dlg[2], x, y, w, h); set_dialog_size(&main_dlg[3], x + 2, y + 2, w - 15, h - 15); set_dialog_size(&main_dlg[4], x + w - 14, y, 14, h - 11); set_dialog_size(&main_dlg[5], x, y + h - 14, w - 11, 14); set_dialog_size(&main_dlg[10], x + w - 12, y + h - 12, 10, 10); // Edit objects area w = 160; h = 120; x = margin; y = main_dlg[6].y - margin - h; set_dialog_size(&edit_objects_layer[0], x, y, w, h); set_dialog_size(&edit_objects_layer[1], w + margin * 2, main_dlg[6].y - margin - 14, 97, 14); // Initialize map and tile stuff tileRepository = new TileRepository(); // Import tilesets specified in rpgedit.cfg i = 1; while (i > 0) { uszprintf(buf, sizeof buf, "tileset%d", i); const char* filename = get_config_string(buf, "filename", NULL); int tile_w = get_config_int(buf, "tile_w", 16); int tile_h = get_config_int(buf, "tile_h", 16); int tile_spacing = get_config_int(buf, "tile_spacing", 0); if (filename) { if (tile_w > 0 && tile_h > 0 && tile_spacing >= 0) { import_tile_bitmap(filename, tile_w, tile_h, tile_spacing); } else { allegro_message("Error, incorrect parameters for automatic tile import (%s)!", filename); // Print warning in log file } i++; } else { i = -1; } } currentMap = new SquareMap(TILES_W, TILES_H); ustrcpy(map_filename, "untitled.tmx"); // Load map specified in rpgedit.cfg const char* filename = get_config_string("startup", "load_map", NULL); if (filename) { if (!currentMap->loadMap(filename)) { ustrcpy(map_filename, filename); object_message(&D_MAP, MSG_NEW_MAP, 0); set_map_changed(false); } else { console.log(CON_LOG, CON_ALWAYS, "Error while loading default map (%s)!\n", filename); } } update_window_title(); map_edit_mode = EM_TILE; menu_item_edit_objects(); //activate_mode(edit_objects_layer); }
static int joy_init(void) { JOYSTICK_INFO *j; AL_CONST char *device_name = NULL; char tmp[128], tmp1[128], tmp2[128]; unsigned int raw_version; struct { unsigned char build, minor, major; } version; char num_axes, num_buttons; int throttle; int i, s, a, b; for (i = 0; i < MAX_JOYSTICKS; i++) { /* Check for a user override on the device to use. */ uszprintf(tmp, sizeof(tmp), uconvert_ascii("joystick_device_%d", tmp1), i); device_name = get_config_string(uconvert_ascii("joystick", tmp1), tmp, NULL); /* Special case for the first joystick. */ if (!device_name && (i == 0)) device_name = get_config_string(uconvert_ascii("joystick", tmp1), uconvert_ascii("joystick_device", tmp2), NULL); if (device_name) { joy_fd[i] = open(uconvert_toascii(device_name, tmp), O_RDONLY|O_NONBLOCK); if (joy_fd[i] == -1) break; } else { snprintf(tmp, sizeof(tmp), "/dev/input/js%d", i); tmp[sizeof(tmp)-1] = 0; joy_fd[i] = open(tmp, O_RDONLY|O_NONBLOCK); if (joy_fd[i] == -1) { snprintf(tmp, sizeof(tmp), "/dev/js%d", i); tmp[sizeof(tmp)-1] = 0; joy_fd[i] = open(tmp, O_RDONLY|O_NONBLOCK); if (joy_fd[i] == -1) break; } } if (ioctl(joy_fd[i], JSIOCGVERSION, &raw_version) < 0) { /* NOTE: IOCTL fails if the joystick API is version 0.x */ uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Your Linux joystick API is version 0.x which is unsupported.")); return -1; } version.major = (raw_version & 0xFF0000) >> 16; version.minor = (raw_version & 0xFF00) >> 8; version.build = (raw_version & 0xFF); ioctl(joy_fd[i], JSIOCGAXES, &num_axes); ioctl(joy_fd[i], JSIOCGBUTTONS, &num_buttons); if (num_axes > TOTAL_JOYSTICK_AXES) num_axes = TOTAL_JOYSTICK_AXES; if (num_buttons > MAX_JOYSTICK_BUTTONS) num_buttons = MAX_JOYSTICK_BUTTONS; /* User is allowed to override our simple assumption of which * axis number (kernel) the throttle is located at. */ uszprintf(tmp, sizeof(tmp), uconvert_ascii("throttle_axis_%d", tmp1), i); throttle = get_config_int(uconvert_ascii("joystick", tmp1), tmp, -1); if (throttle == -1) { throttle = get_config_int(uconvert_ascii("joystick", tmp1), uconvert_ascii("throttle_axis", tmp2), -1); } /* Each pair of axes is assumed to make up a stick unless it * is the sole remaining axis, or has been user specified, in * which case it is a throttle. */ j = &joy[i]; j->flags = JOYFLAG_ANALOGUE; for (s = 0, a = 0; (s < MAX_JOYSTICK_STICKS) && (a < num_axes); s++) { if ((a == throttle) || (a == num_axes-1)) { /* One axis throttle */ j->stick[s].flags = JOYFLAG_ANALOGUE | JOYFLAG_UNSIGNED; j->stick[s].num_axis = 1; j->stick[s].axis[0].name = get_config_text("Throttle"); j->stick[s].name = ustrdup(j->stick[s].axis[0].name); axis[i][a++] = &j->stick[s].axis[0]; } else { /* Two axis stick. */ j->stick[s].flags = JOYFLAG_ANALOGUE | JOYFLAG_SIGNED; j->stick[s].num_axis = 2; j->stick[s].axis[0].name = get_config_text("X"); j->stick[s].axis[1].name = get_config_text("Y"); j->stick[s].name = _AL_MALLOC_ATOMIC(32); ASSERT(j->stick[s].name); uszprintf((char *)j->stick[s].name, 32, get_config_text("Stick %d"), s+1); axis[i][a++] = &j->stick[s].axis[0]; axis[i][a++] = &j->stick[s].axis[1]; } } j->num_sticks = s; for (b = 0; b < num_buttons; b++) { j->button[b].name = _AL_MALLOC_ATOMIC(16); ASSERT(j->button[b].name); uszprintf((char *)j->button[b].name, 16, uconvert_ascii("%c", tmp), 'A' + b); } j->num_buttons = num_buttons; } num_joysticks = i; if (num_joysticks == 0) { uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unable to open %s: %s"), device_name ? device_name : uconvert_ascii("/dev/js0", tmp), ustrerror(errno)); return -1; } return 0; }
/* _unix_get_executable_name: * Return full path to the current executable, use proc fs if available. */ void _unix_get_executable_name(char *output, int size) { #ifdef ALLEGRO_HAVE_SV_PROCFS_H struct prpsinfo psinfo; int fd; #endif char linkname[1024]; char filename[1024]; struct stat finfo; FILE *pipe; pid_t pid; int len; #ifdef ALLEGRO_HAVE_GETEXECNAME { const char *s = getexecname(); if (s) { if (s[0] == '/') { /* Absolute path */ do_uconvert (s, U_ASCII, output, U_CURRENT, size); return; } else { /* Not an absolute path */ if (_find_executable_file(s, output, size)) return; } } } #endif /* We need the PID in order to query procfs */ pid = getpid(); /* Try a Linux-like procfs */ /* get symolic link to executable from proc fs */ sprintf (linkname, "/proc/%d/exe", (int)pid); if (stat (linkname, &finfo) == 0) { len = readlink (linkname, filename, sizeof(filename)-1); if (len>-1) { filename[len] = '\0'; do_uconvert (filename, U_ASCII, output, U_CURRENT, size); return; } } /* Use System V procfs calls if available */ #ifdef ALLEGRO_HAVE_SV_PROCFS_H sprintf (linkname, "/proc/%d/exe", (int)pid); fd = open(linkname, O_RDONLY); if (!fd == -1) { ioctl(fd, PIOCPSINFO, &psinfo); close(fd); /* Use argv[0] directly if we can */ #ifdef ALLEGRO_HAVE_PROCFS_ARGCV if (psinfo.pr_argv && psinfo.pr_argc) { if (_find_executable_file(psinfo.pr_argv[0], output, size)) return; } else #endif { /* Emulate it */ /* We use the pr_psargs field to find argv[0] * This is better than using the pr_fname field because we need * the additional path information that may be present in argv[0] */ /* Skip other args */ char *s = strchr(psinfo.pr_psargs, ' '); if (s) s[0] = '\0'; if (_find_executable_file(psinfo.pr_psargs, output, size)) return; } /* Try the pr_fname just for completeness' sake if argv[0] fails */ if (_find_executable_file(psinfo.pr_fname, output, size)) return; } #endif /* Last resort: try using the output of the ps command to at least find */ /* the name of the file if not the full path */ uszprintf (linkname, sizeof(linkname), "ps -p %d", (int)pid); do_uconvert (linkname, U_CURRENT, filename, U_ASCII, size); pipe = popen(filename, "r"); if (pipe) { /* The first line of output is a header */ fgets(linkname, sizeof(linkname), pipe); /* The information we want is in the last column; find it */ len = strlen(linkname); while (linkname[len] != ' ' && linkname[len] != '\t') len--; /* The second line contains the info we want */ fgets(linkname, sizeof(linkname), pipe); pclose(pipe); /* Treat special cases: filename between [] and - for login shell */ if (linkname[len] == '-') len++; if (linkname[len] == '[' && linkname[strlen(linkname)] == ']') { len++; linkname[strlen(linkname)] = '\0'; } /* Now, the filename should be in the last column */ _al_sane_strncpy (filename, linkname+len+1, strlen(linkname)-len+1); if (_find_executable_file(filename, output, size)) return; /* Just return the output from ps... */ do_uconvert (filename, U_ASCII, output, U_CURRENT, size); return; } #ifdef ALLEGRO_WITH_MAGIC_MAIN /* Try the captured argv[0] */ if (_find_executable_file(__crt0_argv[0], output, size)) return; #endif /* Give up; return empty string */ do_uconvert ("", U_ASCII, output, U_CURRENT, size); }
/* init_console: * Initialises this subsystem. */ static int init_console(void) { char tmp[256]; /* Find our tty's VT number */ __al_linux_vt = get_tty(STDIN_FILENO); if (__al_linux_vt < 0) { uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Error finding our VT: %s"), ustrerror(errno)); return 1; } if (__al_linux_vt != 0) { /* Open our current console */ if ((__al_linux_console_fd = open("/dev/tty", O_RDWR)) < 0) { uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unable to open %s: %s"), uconvert_ascii("/dev/tty", tmp), ustrerror(errno)); return 1; } } else { int tty, console_fd, fd, child; unsigned short mask; char tty_name[16]; struct vt_stat vts; /* Now we need to find a VT we can use. It must be readable and * writable by us, if we're not setuid root. VT_OPENQRY itself * isn't too useful because it'll only ever come up with one * suggestion, with no guarrantee that we actually have access * to it. * * At some stage I think this is a candidate for config * file overriding, but for now we'll stat the first N consoles * to see which ones we can write to (hopefully at least one!), * so that we can use that one to do ioctls. We used to use * /dev/console for that purpose but it looks like it's not * always writable by enough people. * * Having found and opened a writable device, we query the state * of the first sixteen (fifteen really) consoles, and try * opening each unused one in turn. */ if ((console_fd = open ("/dev/console", O_WRONLY)) < 0) { int n; uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, uconvert_ascii("%s /dev/console: %s", tmp), get_config_text("Unable to open"), ustrerror (errno)); /* Try some ttys instead... */ for (n = 1; n <= 24; n++) { snprintf (tty_name, sizeof(tty_name), "/dev/tty%d", n); tty_name[sizeof(tty_name)-1] = 0; if ((console_fd = open (tty_name, O_WRONLY)) >= 0) break; } if (n > 24) return 1; /* leave the error message about /dev/console */ } /* Get the state of the console -- in particular, the free VT field */ if (ioctl (console_fd, VT_GETSTATE, &vts)) { uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, uconvert_ascii("VT_GETSTATE: %s", tmp), ustrerror (errno)); close (console_fd); return 1; } __al_linux_prev_vt = vts.v_active; /* We attempt to set our euid to 0; if we were run with euid 0 to * start with, we'll be able to do this now. Otherwise, we'll just * ignore the error returned since it might not be a problem if the * ttys we look at are owned by the user running the program. */ seteuid(0); /* tty0 is not really a console, so start counting at 2. */ fd = -1; for (tty = 1, mask = 2; mask; tty++, mask <<= 1) { if (!(vts.v_state & mask)) { snprintf (tty_name, sizeof(tty_name), "/dev/tty%d", tty); tty_name[sizeof(tty_name)-1] = 0; if ((fd = open (tty_name, O_RDWR)) != -1) { close (fd); break; } } } seteuid (getuid()); if (!mask) { ustrzcpy (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("Unable to find a usable VT")); close (console_fd); return 1; } /* OK, now fork into the background, detach from the current console, * and attach to the new one. */ child = fork(); if (child < 0) { /* fork failed */ uszprintf (allegro_error, ALLEGRO_ERROR_SIZE, uconvert_ascii ("fork: %s", tmp), ustrerror (errno)); close (console_fd); return 1; } if (child) { /* We're the parent -- write a note to the user saying where the * app went, then quit */ fprintf (stderr, "Allegro application is running on VT %d\n", tty); exit (0); } /* We're the child. Detach from our controlling terminal, and start * a new session. */ close (console_fd); ioctl (0, TIOCNOTTY, 0); setsid(); /* Open the new one again. It becomes our ctty, because we started a * new session above. */ seteuid(0); fd = open (tty_name, O_RDWR); seteuid(getuid()); if (fd == -1) { ustrzcpy (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("Unable to reopen new console")); return 1; } /* Try to switch to it -- should succeed, since it's our ctty */ ioctl (fd, VT_ACTIVATE, tty); __al_linux_vt = tty; __al_linux_console_fd = fd; /* Check we can reliably wait until we have the display */ if (__al_linux_wait_for_display()) { close (fd); ustrzcpy (allegro_error, ALLEGRO_ERROR_SIZE, get_config_text ("VT_WAITACTIVE failure")); return 1; } /* dup2 it to stdin, stdout and stderr if necessary */ if (isatty(0)) dup2 (fd, 0); if (isatty(1)) dup2 (fd, 1); if (isatty(2)) dup2 (fd, 2); } /* Get termio settings and make a working copy */ tcgetattr(__al_linux_console_fd, &__al_linux_startup_termio); __al_linux_work_termio = __al_linux_startup_termio; return 0; }
static int sndio_init(int input, int voices) { char tmp1[128], tmp2[128]; if (input) { digi_driver->rec_cap_bits = 16; digi_driver->rec_cap_stereo = TRUE; return 0; } if (open_sndio_device(0) != 0) return -1; sndio_play_bufdata = _AL_MALLOC_ATOMIC(sndio_play_bufsize); if (sndio_play_bufdata == 0) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not allocate audio buffer")); sio_close(hdl); return -1; } sndio_realpos = sndio_playpos = 0; sio_onmove(hdl, movecb, NULL); sndio_volume = 127; sio_onvol(hdl, volcb, NULL); if (!sio_start(hdl)) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not start sndio")); sio_close(hdl); return -1; } digi_sndio.voices = voices; /* first arg is total number of samples */ if (_mixer_init(sndio_play_round * (_sound_stereo ? 2 : 1), _sound_freq, _sound_stereo, ((_sound_bits == 16) ? 1 : 0), &digi_sndio.voices) != 0) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not init software mixer")); sio_close(hdl); return -1; } _mix_some_samples((uintptr_t) sndio_play_bufdata, 0, sndio_signed); /* Add audio interrupt. */ _unix_bg_man->register_func(sndio_update); uszprintf(sndio_desc, sizeof(sndio_desc), get_config_text("%s: %d bits, %s, %d Hz, %s"), "sndio device", _sound_bits, uconvert_ascii((sndio_signed ? "signed" : "unsigned"), tmp1), _sound_freq, uconvert_ascii((par.pchan == 2 ? "stereo" : "mono"), tmp2)); digi_driver->desc = sndio_desc; return 0; }
/* be_midi_init: * Initializes the BeOS MIDI driver. */ extern "C" int be_midi_init(int input, int voices) { char tmp[256], tmp2[128], tmp3[128] = EMPTY_STRING; char *sound = uconvert_ascii("sound", tmp); int mode, freq, quality, reverb; synth_mode sm = B_BIG_SYNTH; interpolation_mode im = B_2_POINT_INTERPOLATION; char *reverb_name[] = { "no", "closet", "garage", "ballroom", "cavern", "dungeon" }; if (input) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Input is not supported")); return -1; } _be_midisynth = new BMidiSynth(); if (!_be_midisynth) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Not enough memory")); return -1; } /* Checks if instruments are available */ mode = CLAMP(0, get_config_int(sound, uconvert_ascii("be_midi_quality", tmp), 1), 1); if (mode) sm = B_BIG_SYNTH; else sm = B_LITTLE_SYNTH; if ((be_synth->LoadSynthData(sm) != B_OK) || (!be_synth->IsLoaded())) { delete _be_midisynth; _be_midisynth = NULL; ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not load MIDI instruments data file")); return -1; } /* Sets up synthetizer and loads instruments */ _be_midisynth->EnableInput(true, true); /* Prevents other apps from changing instruments on the fly */ _be_midisynth->FlushInstrumentCache(true); /* Reverberation is cool */ reverb = CLAMP(0, get_config_int(sound, uconvert_ascii("be_midi_reverb", tmp), 0), 5); if (reverb) { be_synth->SetReverb((reverb_mode)reverb); be_synth->EnableReverb(true); } else be_synth->EnableReverb(false); /* Sets sampling rate and sample interpolation method */ freq = get_config_int(sound, uconvert_ascii("be_midi_freq", tmp), 22050); quality = CLAMP(0, get_config_int(sound, uconvert_ascii("be_midi_interpolation", tmp), 1), 2); be_synth->SetSamplingRate(freq); switch (quality) { case 0: im = B_DROP_SAMPLE; break; case 1: im = B_2_POINT_INTERPOLATION; do_uconvert("fast", U_ASCII, tmp3, U_CURRENT, sizeof(tmp3)); break; case 2: im = B_LINEAR_INTERPOLATION; do_uconvert("linear", U_ASCII, tmp3, U_CURRENT, sizeof(tmp3)); break; } be_synth->SetInterpolation(im); /* Sets up driver description */ uszprintf(be_midi_driver_desc, sizeof(be_midi_driver_desc), uconvert_ascii("BeOS %s quality synth, %s %d kHz, %s reverberation", tmp), uconvert_ascii(mode ? "high" : "low", tmp2), tmp3, (be_synth->SamplingRate() / 1000), reverb_name[reverb]); midi_beos.desc = be_midi_driver_desc; return 0; }
/* digi_psp_init: * Initializes the PSP digital sound driver. */ static int digi_psp_init(int input, int voices) { char digi_psp_desc[512] = EMPTY_STRING; char tmp1[256]; if (input) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Input is not supported")); return -1; } hw_channel = sceAudioChReserve(PSP_AUDIO_NEXT_CHANNEL, SAMPLES_PER_BUFFER, PSP_AUDIO_FORMAT_STEREO); if (hw_channel < 0) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Failed reserving hardware sound channel")); return -1; } psp_audio_on = TRUE; audio_thread_UID = sceKernelCreateThread("psp_audio_thread", (void *)&psp_audio_channel_thread, 0x19, 0x10000, 0, NULL); if (audio_thread_UID < 0) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Cannot create audio thread")); digi_psp_exit(FALSE); return -1; } if (sceKernelStartThread(audio_thread_UID, 0, NULL) != 0) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Cannot start audio thread")); digi_psp_exit(FALSE); return -1; } /* Allegro sound state variables */ _sound_bits = 16; _sound_stereo = TRUE; _sound_freq = 44100; digi_psp.voices = voices; if (_mixer_init(SAMPLES_PER_BUFFER * 2, _sound_freq, _sound_stereo, (_sound_bits == 16), &digi_psp.voices)) { ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Error initializing mixer")); digi_psp_exit(FALSE); return -1; } uszprintf(digi_psp_desc, sizeof(digi_psp_desc), get_config_text("%d bits, %d bps, %s"), _sound_bits, _sound_freq, uconvert_ascii(_sound_stereo ? "stereo" : "mono", tmp1)); digi_psp.desc = digi_psp_desc; return 0; }