void OSBB10::initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver) { data_dir = getenv("HOME"); //Create a screen context that will be used to create an EGL surface to to receive libscreen events screen_create_context(&screen_cxt,0); //Initialize BPS library bps_initialize(); //Use utility code to initialize EGL for 2D rendering with GL ES 1.1 enum RENDERING_API api = GL_ES_2; #ifdef BB10_LGLES_OVERRIDE api = GL_ES_1; #endif if (EXIT_SUCCESS != bbutil_init(screen_cxt, api)) { bbutil_terminate(); screen_destroy_context(screen_cxt); return; }; EGLint surface_width, surface_height; eglQuerySurface(egl_disp, egl_surf, EGL_WIDTH, &surface_width); eglQuerySurface(egl_disp, egl_surf, EGL_HEIGHT, &surface_height); printf("screen size: %ix%i\n", surface_width, surface_height); VideoMode mode; mode.width = surface_width; mode.height = surface_height; mode.fullscreen = true; mode.resizable = false; set_video_mode(mode); //Signal BPS library that navigator and screen events will be requested screen_request_events(screen_cxt); navigator_request_events(0); virtualkeyboard_request_events(0); audiodevice_request_events(0); #ifdef DEBUG_ENABLED bps_set_verbosity(3); #endif accel_supported = accelerometer_is_supported(); if (accel_supported) accelerometer_set_update_frequency(FREQ_40_HZ); pitch = 0; roll = 0; #ifdef BB10_LGLES_OVERRIDE rasterizer = memnew( RasterizerGLES1(false) ); #else rasterizer = memnew( RasterizerGLES2(false, false) ); #endif visual_server = memnew( VisualServerRaster(rasterizer) ); visual_server->init(); visual_server->cursor_set_visible(false, 0); audio_driver = memnew(AudioDriverBB10); audio_driver->set_singleton(); audio_driver->init(NULL); physics_server = memnew( PhysicsServerSW ); physics_server->init(); physics_2d_server = memnew( Physics2DServerSW ); physics_2d_server->init(); input = memnew( InputDefault ); #ifdef PAYMENT_SERVICE_ENABLED payment_service = memnew(PaymentService); Globals::get_singleton()->add_singleton(Globals::Singleton("InAppStore", payment_service)); #endif }
int main(int argc, char **argv) { FILE *file; int samples; char *sample_buffer; int rtn, final_return_code = -1, exit_application = 0; int bsize, bytes_read, total_written = 0; fd_set rfds, wfds; char input_file[PATH_MAX]; char cwd[PATH_MAX]; /* * Before we can listen for events from the BlackBerry Tablet OS platform * services, we need to initialize the BPS infrastructure */ bps_initialize(); if (setup_screen() != EXIT_SUCCESS) { printf("Unable to set up the screen. Exiting."); exit(-1); } /* * Once the BPS infrastructure has been initialized we can register for * events from the various BlackBerry Tablet OS platform services. The * Navigator service manages and delivers application life cycle and * visibility events. * * For this sample, we request Navigator events so we can track when * the system is terminating the application (NAVIGATOR_EXIT event). * This allows us to clean up application resources. * * We request Audio Device events because we want to make sure that * we properly handle changes in audio output. * * We request dialog events to properly initialize the dialog * subsystem in order to display status and error messages. */ if (BPS_SUCCESS != navigator_request_events(0)) { fprintf(stderr, "Error requesting navigator events: %s", strerror(errno)); exit(-1); } if (BPS_SUCCESS != dialog_request_events(0)) { fprintf(stderr, "Error requesting dialog events: %s", strerror(errno)); exit(-1); } if (BPS_SUCCESS != audiodevice_request_events(0)) { fprintf(stderr, "Error requesting audio device events: %s", strerror(errno)); exit(-1); } /* * Create and display the dialog. */ create_dialog(); /* * Open and check the input file. */ getcwd(cwd, PATH_MAX); rtn = snprintf(input_file, PATH_MAX, "%s/%s", cwd, WAV_RELATIVE_PATH); if (rtn > PATH_MAX - 1) { err("File name and path too long"); goto fail1; } if ((file = fopen(input_file, "r")) == 0) { err("File open failed"); goto fail1; } if (check_hdr(file) == -1) { err("check_hdr failed"); goto fail2; } /* * Parse the headers in the wav file to figure out what kind of data we * are dealing with in the file. */ samples = find_tag(file, "fmt "); fread(&wav_header, sizeof(wav_header), 1, file); fseek(file,(samples - sizeof(wave_hdr)), SEEK_CUR); sample_rate = ENDIAN_LE32(wav_header.samples_per_sec); sample_channels = ENDIAN_LE16(wav_header.channels); sample_bits = ENDIAN_LE16(wav_header.bits_per_sample); snprintf(msg, MSG_SIZE, "SampleRate = %d, channels = %d, SampleBits = %d\n", sample_rate, sample_channels, sample_bits); show_dialog_message(msg); if (setup_snd(NULL)) { goto fail2; } bsize = setup.buf.block.frag_size; samples = find_tag(file, "data"); sample_buffer = malloc(bsize); if (!sample_buffer) { goto fail3; } FD_ZERO(&rfds); FD_ZERO(&wfds); bytes_read = 1; while (total_written < samples && bytes_read > 0 ) { bps_event_t *event = NULL; while (BPS_SUCCESS == bps_get_event(&event, 0) && event) { /* * If it is a NAVIGATOR_EXIT event then we are done so stop * processing events, clean up and exit */ if (bps_event_get_domain(event) == navigator_get_domain()) { if (NAVIGATOR_EXIT == bps_event_get_code(event)) { exit_application = 1; goto success; } } if (bps_event_get_domain(event) == audiodevice_get_domain()) { /* * If it is a audio device event then it means a new audio device * has been enabled and a switch is required. We close the old, * open the new audio device using the path and get the card number so * that we can close and re-open the mixer with the new card * number. */ const char * audiodevice_path = audiodevice_event_get_path(event); if (NULL == audiodevice_path) { snprintf(msg, MSG_SIZE, "audiodevice_event_get_path failed: %s\n", snd_strerror(rtn)); show_dialog_message(msg); goto fail5; } if ((rtn = snd_mixer_close(mixer_handle)) < 0) { snprintf(msg, MSG_SIZE, "snd_mixer_close failed: %s\n", snd_strerror(rtn)); show_dialog_message(msg); goto fail4; } if ((rtn = snd_pcm_close(pcm_handle)) < 0) { snprintf(msg, MSG_SIZE, "snd_pcm_close failed: %s\n", snd_strerror(rtn)); show_dialog_message(msg); goto fail3; } if (setup_snd(audiodevice_path)) { /* * setup_snd() closes pcm and mixer handles in the case of error so we * skip clean up of the handles in the case of failure. */ goto fail3; } } } if (tcgetpgrp(0) == getpid()) FD_SET(STDIN_FILENO, &rfds); FD_SET(snd_mixer_file_descriptor(mixer_handle), &rfds); FD_SET(snd_pcm_file_descriptor(pcm_handle, SND_PCM_CHANNEL_PLAYBACK), &wfds); rtn = max(snd_mixer_file_descriptor(mixer_handle), snd_pcm_file_descriptor(pcm_handle, SND_PCM_CHANNEL_PLAYBACK)); if (select(rtn + 1, &rfds, &wfds, NULL, NULL) == -1) { err("select"); goto fail5; } if (FD_ISSET(snd_pcm_file_descriptor(pcm_handle, SND_PCM_CHANNEL_PLAYBACK), &wfds)) { snd_pcm_channel_status_t status; int written = 0; if ((bytes_read = fread(sample_buffer, 1, min(samples - total_written, bsize), file)) <= 0) continue; written = snd_pcm_plugin_write(pcm_handle, sample_buffer, bytes_read); if (written < bytes_read) { memset(&status, 0, sizeof(status)); status.channel = SND_PCM_CHANNEL_PLAYBACK; if (snd_pcm_plugin_status(pcm_handle, &status) < 0) { show_dialog_message("underrun: playback channel status error\n"); goto fail5; } if (status.status == SND_PCM_STATUS_READY || status.status == SND_PCM_STATUS_UNDERRUN) { if (snd_pcm_plugin_prepare(pcm_handle, SND_PCM_CHANNEL_PLAYBACK) < 0) { show_dialog_message("underrun: playback channel prepare error\n"); goto fail5; } } if (written < 0) written = 0; written += snd_pcm_plugin_write(pcm_handle, sample_buffer + written, bytes_read - written); } total_written += written; } } success: bytes_read = snd_pcm_plugin_flush(pcm_handle, SND_PCM_CHANNEL_PLAYBACK); final_return_code = 0; /* * there are return codes to these close calls, but we would do the same * thing regardless of error or success so we do not check the return codes. */ fail5: snd_mixer_close(mixer_handle); fail4: snd_pcm_close(pcm_handle); fail3: free(sample_buffer); sample_buffer = NULL; fail2: fclose(file); fail1: while (!exit_application) { /* * Something went wrong so there is probably an error message and * we don't want to exit right away because we want the user to see * the message in the dialog. * * Using a negative timeout (-1) in the call to bps_get_event(...) * ensures that we don't busy wait by blocking until an event is * available. */ bps_event_t *event = NULL; bps_get_event(&event, -1); if (event) { /* * If it is a NAVIGATOR_EXIT event then we are done so stop * processing events, clean up and exit */ if (bps_event_get_domain(event) == navigator_get_domain()) { if (NAVIGATOR_EXIT == bps_event_get_code(event)) { exit_application = 1; } } } } /* * Destroy the dialog, if it exists and cleanup screen resources. */ destroy_dialog(); cleanup_screen(); bps_shutdown(); return final_return_code; }