/* _al_run_destructors: * Run all the destructors on the list in reverse order. */ void _al_run_destructors(_AL_DTOR_LIST *dtors) { if (!dtors) { return; } /* call the destructors in reverse order */ _al_mutex_lock(&dtors->mutex); { while (!_al_vector_is_empty(&dtors->dtors)) { DTOR *dtor = _al_vector_ref_back(&dtors->dtors); void *object = dtor->object; void (*func)(void *) = dtor->func; ALLEGRO_DEBUG("calling dtor for %s %p, func %p\n", dtor->name, object, func); _al_mutex_unlock(&dtors->mutex); { (*func)(object); } _al_mutex_lock(&dtors->mutex); } } _al_mutex_unlock(&dtors->mutex); }
/* Internal function: _al_event_source_needs_to_generate_event * This function is called by modules that implement event sources * when some interesting thing happens. They call this to check if * they should bother generating an event of the given type, i.e. if * the given event source is actually registered with one or more * event queues. This is an optimisation to avoid allocating and * filling in unwanted event structures. * * The event source must be _locked_ before calling this function. * * [runs in background threads] */ bool _al_event_source_needs_to_generate_event(ALLEGRO_EVENT_SOURCE *es) { ALLEGRO_EVENT_SOURCE_REAL *this = (ALLEGRO_EVENT_SOURCE_REAL *)es; /* We don't consider pausing of event queues, but it does not seem worth * optimising for. */ return !_al_vector_is_empty(&this->queues); }
void _al_d3d_bmp_destroy(void) { while (!_al_vector_is_empty(&created_bitmaps)) _al_vector_delete_at(&created_bitmaps, _al_vector_size(&created_bitmaps)-1); _al_vector_free(&created_bitmaps); _al_vector_init(&created_bitmaps, sizeof(ALLEGRO_SYSTEM_INTERFACE *)); al_free(vt); vt = NULL; }
/* Internal function: _al_event_source_free * Free the resources using by an event source structure. It * automatically unregisters the event source from all the event * queues it is currently registered with. */ void _al_event_source_free(ALLEGRO_EVENT_SOURCE *es) { ALLEGRO_EVENT_SOURCE_REAL *this = (ALLEGRO_EVENT_SOURCE_REAL *)es; /* Unregister from all queues. */ while (!_al_vector_is_empty(&this->queues)) { ALLEGRO_EVENT_QUEUE **slot = _al_vector_ref_back(&this->queues); al_unregister_event_source(*slot, es); } _al_vector_free(&this->queues); _al_mutex_destroy(&this->mutex); }
static void shutdown_system_driver(void) { if (active_sysdrv) { if (active_sysdrv->user_exe_path) al_destroy_path(active_sysdrv->user_exe_path); if (active_sysdrv->vt && active_sysdrv->vt->shutdown_system) active_sysdrv->vt->shutdown_system(); active_sysdrv = NULL; while (!_al_vector_is_empty(&_al_system_interfaces)) _al_vector_delete_at(&_al_system_interfaces, _al_vector_size(&_al_system_interfaces)-1); _al_vector_free(&_al_system_interfaces); _al_vector_init(&_al_system_interfaces, sizeof(ALLEGRO_SYSTEM_INTERFACE *)); } al_destroy_config(sys_config); sys_config = NULL; }
/* Function: al_destroy_event_queue */ void al_destroy_event_queue(ALLEGRO_EVENT_QUEUE *queue) { ASSERT(queue); _al_unregister_destructor(_al_dtor_list, queue); /* Unregister any event sources registered with this queue. */ while (_al_vector_is_nonempty(&queue->sources)) { ALLEGRO_EVENT_SOURCE **slot = _al_vector_ref_back(&queue->sources); al_unregister_event_source(queue, *slot); } ASSERT(_al_vector_is_empty(&queue->sources)); _al_vector_free(&queue->sources); ASSERT(queue->events_head == queue->events_tail); _al_vector_free(&queue->events); _al_cond_destroy(&queue->cond); _al_mutex_destroy(&queue->mutex); al_free(queue); }
/* Internal function: _al_event_source_needs_to_generate_event * This function is called by modules that implement event sources * when some interesting thing happens. They call this to check if * they should bother generating an event of the given type, i.e. if * the given event source is actually registered with one or more * event queues. This is an optimisation to avoid allocating and * filling in unwanted event structures. * * The event source must be _locked_ before calling this function. * * [runs in background threads] */ bool _al_event_source_needs_to_generate_event(ALLEGRO_EVENT_SOURCE *es) { ALLEGRO_EVENT_SOURCE_REAL *this = (ALLEGRO_EVENT_SOURCE_REAL *)es; return !_al_vector_is_empty(&this->queues); }
void _al_d3d_generate_display_format_list(void) { static bool fullscreen = !(al_get_new_display_flags() & ALLEGRO_FULLSCREEN); /* stop warning */ static int adapter = ~al_get_new_display_adapter(); /* stop warning */ int i; if (!_al_vector_is_empty(&eds_list) && (fullscreen == (bool)(al_get_new_display_flags() & ALLEGRO_FULLSCREEN)) && (adapter == al_get_new_display_adapter())) { return; } else if (!_al_vector_is_empty(&eds_list)) { _al_d3d_destroy_display_format_list(); } fullscreen = (al_get_new_display_flags() & ALLEGRO_FULLSCREEN) != 0; adapter = al_get_new_display_adapter(); if (adapter < 0) adapter = 0; _al_vector_init(&eds_list, sizeof(ALLEGRO_EXTRA_DISPLAY_SETTINGS *)); /* Loop through each bit combination of: * bit 0: 16/32 bit * bit 1: single-buffer * bit 2: vsync */ for (i = 0; i < 8; i++) { int format_num = !!(i & 1); int single_buffer = !!(i & 2); int vsync = !!(i & 4); int allegro_format = ALLEGRO_PIXEL_FORMAT_XRGB_8888; if (format_num == 1) allegro_format = ALLEGRO_PIXEL_FORMAT_RGB_565; D3DFORMAT d3d_format = (D3DFORMAT)_al_pixel_format_to_d3d(allegro_format); /* Count available multisample quality levels. */ DWORD quality_levels = 0; if (_al_d3d->CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_HAL, d3d_format, !fullscreen, D3DMULTISAMPLE_NONMASKABLE, &quality_levels) != D3D_OK) { _al_d3d->CheckDeviceMultiSampleType(adapter, D3DDEVTYPE_REF, d3d_format, !fullscreen, D3DMULTISAMPLE_NONMASKABLE, &quality_levels); } /* Loop through available depth/stencil formats. */ for (int j = 0; j < D3D_DEPTH_FORMATS; j++) { if (j == 0 || IsDepthFormatExisting( depth_stencil_formats[j].format, d3d_format)) { DEPTH_STENCIL_DESC *ds = depth_stencil_formats + j; for (int k = 0; k < (int)quality_levels + 1; k++) { ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds, **peds; peds = (ALLEGRO_EXTRA_DISPLAY_SETTINGS **)_al_vector_alloc_back(&eds_list); eds = *peds = (ALLEGRO_EXTRA_DISPLAY_SETTINGS *)al_malloc(sizeof *eds); memset(eds->settings, 0, sizeof(int) * ALLEGRO_DISPLAY_OPTIONS_COUNT); eds->settings[ALLEGRO_COMPATIBLE_DISPLAY] = 1; if (format_num == 0) { eds->settings[ALLEGRO_RED_SIZE] = 8; eds->settings[ALLEGRO_GREEN_SIZE] = 8; eds->settings[ALLEGRO_BLUE_SIZE] = 8; eds->settings[ALLEGRO_RED_SHIFT] = 16; eds->settings[ALLEGRO_GREEN_SHIFT] = 8; eds->settings[ALLEGRO_BLUE_SHIFT] = 0; eds->settings[ALLEGRO_COLOR_SIZE] = 32; } else if (format_num == 1) { eds->settings[ALLEGRO_RED_SIZE] = 5; eds->settings[ALLEGRO_GREEN_SIZE] = 6; eds->settings[ALLEGRO_BLUE_SIZE] = 5; eds->settings[ALLEGRO_RED_SHIFT] = 11; eds->settings[ALLEGRO_GREEN_SHIFT] = 5; eds->settings[ALLEGRO_BLUE_SHIFT] = 0; eds->settings[ALLEGRO_COLOR_SIZE] = 16; } if (single_buffer) { eds->settings[ALLEGRO_SINGLE_BUFFER] = 1; eds->settings[ALLEGRO_UPDATE_DISPLAY_REGION] = 1; } if (vsync) { eds->settings[ALLEGRO_VSYNC] = 1; } eds->settings[ALLEGRO_DEPTH_SIZE] = ds->d; eds->settings[ALLEGRO_STENCIL_SIZE] = ds->s; if (k > 1) { eds->settings[ALLEGRO_SAMPLE_BUFFERS] = 1; // TODO: Is it ok to use the quality level here? eds->settings[ALLEGRO_SAMPLES] = k; } } } } } ALLEGRO_INFO("found %d format combinations\n", _al_vector_size(&eds_list)); }