ALenum NewThunkEntry(ALuint *index) { void *NewList; ALuint i; ReadLock(&ThunkLock); for(i = 0;i < ThunkArraySize;i++) { if(ATOMIC_EXCHANGE(ALenum, &ThunkArray[i], AL_TRUE, almemory_order_acq_rel) == AL_FALSE) { ReadUnlock(&ThunkLock); *index = i+1; return AL_NO_ERROR; } } ReadUnlock(&ThunkLock); WriteLock(&ThunkLock); /* Double-check that there's still no free entries, in case another * invocation just came through and increased the size of the array. */ for(;i < ThunkArraySize;i++) { if(ATOMIC_EXCHANGE(ALenum, &ThunkArray[i], AL_TRUE, almemory_order_acq_rel) == AL_FALSE) { WriteUnlock(&ThunkLock); *index = i+1; return AL_NO_ERROR; } } NewList = al_calloc(16, ThunkArraySize*2 * sizeof(*ThunkArray)); if(!NewList) { WriteUnlock(&ThunkLock); ERR("Realloc failed to increase to %u entries!\n", ThunkArraySize*2); return AL_OUT_OF_MEMORY; } memcpy(NewList, ThunkArray, ThunkArraySize*sizeof(*ThunkArray)); al_free(ThunkArray); ThunkArray = NewList; ThunkArraySize *= 2; ATOMIC_STORE_SEQ(&ThunkArray[i], AL_TRUE); WriteUnlock(&ThunkLock); *index = i+1; return AL_NO_ERROR; }
void * xrealloc (void *ptr, size_t n) { if (ptr == NULL) return xmalloc (n); if (n == 0) { al_free (ptr); return NULL; } void *_ptr = al_realloc (ptr, n); if (! _ptr) error (-1, 0, "%s (%p, %u): cannot reallocate memory", __func__, ptr, (unsigned int) n); return _ptr; }
static void set_cursor_data(ALLEGRO_DISPLAY_RASPBERRYPI *d, uint32_t *data, int width, int height) { al_free(d->cursor_data); int spitch = sizeof(uint32_t) * width; int dpitch = pot(spitch); d->cursor_data = al_malloc(dpitch * height); int y; for (y = 0; y < height; y++) { uint8_t *p1 = (uint8_t *)d->cursor_data + y * dpitch; uint8_t *p2 = (uint8_t *)data + y * spitch; memcpy(p1, p2, spitch); } d->cursor_width = width; d->cursor_height = height; }
void t3f_destroy_animation(T3F_ANIMATION * ap) { int i; for(i = 0; i < ap->frames; i++) { al_free(ap->frame[i]); } if(!(ap->flags & T3F_ANIMATION_FLAG_EXTERNAL_BITMAPS)) { for(i = 0; i < ap->bitmaps->count; i++) { /* Attempt to destroy resource. If it fails, that means the user * probably constructed the animation manually, so destroy the bitmap * directly. */ if(!t3f_destroy_resource(ap->bitmaps->bitmap[i])) { al_destroy_bitmap(ap->bitmaps->bitmap[i]); } } al_free(ap->bitmaps); } al_free(ap); }
ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *Context) { ALsizei pos; for(pos = 0;pos < Context->EffectSlotMap.size;pos++) { ALeffectslot *temp = Context->EffectSlotMap.array[pos].value; Context->EffectSlotMap.array[pos].value = NULL; DELETE_OBJ(temp->EffectState); FreeThunkEntry(temp->id); memset(temp, 0, sizeof(ALeffectslot)); al_free(temp); } }
/* Test al_ustr_new_from_buffer, al_cstr_dup. */ static void t39(void) { const char s1[] = "Корабът ми на въздушна възглавница\0е пълен със змиорки"; ALLEGRO_USTR *us; char *s2; us = al_ustr_new_from_buffer(s1, sizeof(s1) - 1); /* missing NUL term. */ s2 = al_cstr_dup(us); al_ustr_free(us); CHECK(0 == strcmp(s1, s2)); CHECK(0 == memcmp(s1, s2, sizeof(s1))); /* including NUL terminator */ al_free(s2); }
char menu_enum (struct menu_item *menu, char *prefix) { int i = 0; char *menu_str = NULL, *tmp_str = NULL; while (menu[i].key) { if (menu_str) { tmp_str = menu_str; xasprintf (&menu_str, "%s%c", menu_str, menu[i].key); } else { xasprintf (&menu_str, "%s%c", prefix ? prefix : "", menu[i].key); } if (tmp_str) al_free (tmp_str); i++; } if (menu_str) { tmp_str = menu_str; xasprintf (&menu_str, "%s%c", menu_str, '?'); } if (tmp_str) al_free (tmp_str); char c = menu_opt (menu, menu_str); al_free (menu_str); return c; }
void ImGui_ImplAllegro5_Shutdown() { ImGui_ImplAllegro5_InvalidateDeviceObjects(); g_Display = NULL; g_Time = 0.0; if (g_VertexDecl) al_destroy_vertex_decl(g_VertexDecl); g_VertexDecl = NULL; if (g_ClipboardTextData) al_free(g_ClipboardTextData); g_ClipboardTextData = NULL; }
static void pulseaudio_deallocate_voice(ALLEGRO_VOICE *voice) { PULSEAUDIO_VOICE *pv = voice->extra; /* We do NOT hold the voice mutex here, so this does NOT result in a * deadlock when the thread calls _al_voice_update. */ al_set_thread_should_stop(pv->poll_thread); al_join_thread(pv->poll_thread, NULL); al_destroy_thread(pv->poll_thread); al_destroy_mutex(pv->buffer_mutex); pa_simple_free(pv->s); al_free(pv); }
/* [user thread] */ static void xgtk_destroy_display_hook(ALLEGRO_DISPLAY *display, bool is_last) { ALLEGRO_DISPLAY_XGLX *d = (ALLEGRO_DISPLAY_XGLX *)display; ARGS_DESTROY args; if (!_al_gtk_init_args(&args, sizeof(args))) return; args.display = d; args.is_last = is_last; _al_gtk_wait_for_args(do_destroy_display_hook, &args); al_free(d->gtk); d->gtk = NULL; }
void DeinitEffectSlot(ALeffectslot *slot) { struct ALeffectslotProps *props; props = ATOMIC_LOAD_SEQ(&slot->Update); if(props) { if(props->State) ALeffectState_DecRef(props->State); TRACE("Freed unapplied AuxiliaryEffectSlot update %p\n", props); al_free(props); } ALeffectState_DecRef(slot->Effect.State); if(slot->Params.EffectState) ALeffectState_DecRef(slot->Params.EffectState); }
/* Function: al_destroy_voice */ void al_destroy_voice(ALLEGRO_VOICE *voice) { if (voice) { _al_kcm_unregister_destructor(voice); al_detach_voice(voice); ASSERT(al_get_voice_playing(voice) == false); /* We do NOT lock the voice mutex when calling this method. */ voice->driver->deallocate_voice(voice); al_destroy_mutex(voice->mutex); al_destroy_cond(voice->cond); al_free(voice); } }
static void *al_init(const char *device, unsigned rate, unsigned latency) { al_t *al; (void)device; al = (al_t*)calloc(1, sizeof(al_t)); if (!al) return NULL; al->handle = alcOpenDevice(NULL); if (!al->handle) goto error; al->ctx = alcCreateContext(al->handle, NULL); if (!al->ctx) goto error; alcMakeContextCurrent(al->ctx); al->rate = rate; /* We already use one buffer for tmpbuf. */ al->num_buffers = (latency * rate * 2 * sizeof(int16_t)) / (1000 * BUFSIZE) - 1; if (al->num_buffers < 2) al->num_buffers = 2; RARCH_LOG("[OpenAL]: Using %u buffers of %u bytes.\n", (unsigned)al->num_buffers, BUFSIZE); al->buffers = (ALuint*)calloc(al->num_buffers, sizeof(ALuint)); al->res_buf = (ALuint*)calloc(al->num_buffers, sizeof(ALuint)); if (al->buffers == NULL || al->res_buf == NULL) goto error; alGenSources(1, &al->source); alGenBuffers(al->num_buffers, al->buffers); memcpy(al->res_buf, al->buffers, al->num_buffers * sizeof(ALuint)); al->res_ptr = al->num_buffers; return al; error: al_free(al); return NULL; }
static void *pulse_audio_update_recorder(ALLEGRO_THREAD *t, void *data) { ALLEGRO_AUDIO_RECORDER *r = (ALLEGRO_AUDIO_RECORDER *) data; PULSEAUDIO_RECORDER *pa = (PULSEAUDIO_RECORDER *) r->extra; ALLEGRO_EVENT user_event; uint8_t *null_buffer; unsigned int fragment_i = 0; null_buffer = al_malloc(1024); if (!null_buffer) { ALLEGRO_ERROR("Unable to create buffer for draining PulseAudio.\n"); return NULL; } while (!al_get_thread_should_stop(t)) { al_lock_mutex(r->mutex); if (!r->is_recording) { /* Even if not recording, we still want to read from the PA server. Otherwise it will buffer everything and spit it all out whenever the recording resumes. */ al_unlock_mutex(r->mutex); pa_simple_read(pa->s, null_buffer, 1024, NULL); } else { ALLEGRO_AUDIO_RECORDER_EVENT *e; al_unlock_mutex(r->mutex); if (pa_simple_read(pa->s, r->fragments[fragment_i], r->fragment_size, NULL) >= 0) { user_event.user.type = ALLEGRO_EVENT_AUDIO_RECORDER_FRAGMENT; e = al_get_audio_recorder_event(&user_event); e->buffer = r->fragments[fragment_i]; e->samples = r->samples; al_emit_user_event(&r->source, &user_event, NULL); if (++fragment_i == r->fragment_count) { fragment_i = 0; } } } } al_free(null_buffer); return NULL; };
static void xglx_shutdown_system(void) { ALLEGRO_SYSTEM *s = al_get_system_driver(); ALLEGRO_SYSTEM_XGLX *sx = (void *)s; ALLEGRO_INFO("shutting down.\n"); if (sx->x11display) { /* Events thread only runs if we are connected to an X server. */ _al_thread_join(&sx->thread); } /* Close all open displays. */ while (_al_vector_size(&s->displays) > 0) { ALLEGRO_DISPLAY **dptr = _al_vector_ref(&s->displays, 0); ALLEGRO_DISPLAY *d = *dptr; _al_destroy_display_bitmaps(d); al_destroy_display(d); } _al_vector_free(&s->displays); // Makes sure we wait for any commands sent to the X server when destroying the displays. // Should make sure we don't shutdown before modes are restored. if (sx->x11display) { XSync(sx->x11display, False); } _al_xsys_mmon_exit(sx); if (sx->x11display) { XCloseDisplay(sx->x11display); sx->x11display = None; ALLEGRO_DEBUG("xsys: close x11display.\n"); } if (sx->gfxdisplay) { /* XXX for some reason, crashes if both XCloseDisplay calls are made */ /* XCloseDisplay(sx->gfxdisplay); */ sx->gfxdisplay = None; } al_free(sx); }
static bool ogl_lock_region_nonbb_readwrite_nonfbo( ALLEGRO_BITMAP *bitmap, ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_bitmap, int x, int gl_y, int w, int h, int format) { /* No FBO - fallback to reading the entire texture */ const int pixel_size = al_get_pixel_size(format); const int pitch = ogl_pitch(ogl_bitmap->true_w, pixel_size); GLenum e; bool ok; (void) w; ogl_bitmap->lock_buffer = al_malloc(pitch * ogl_bitmap->true_h); if (ogl_bitmap->lock_buffer == NULL) { return false; } ok = true; glBindTexture(GL_TEXTURE_2D, ogl_bitmap->texture); glGetTexImage(GL_TEXTURE_2D, 0, get_glformat(format, 2), get_glformat(format, 1), ogl_bitmap->lock_buffer); e = glGetError(); if (e) { ALLEGRO_ERROR("glGetTexImage for format %s failed (%s).\n", _al_pixel_format_name(format), _al_gl_error_string(e)); al_free(ogl_bitmap->lock_buffer); ogl_bitmap->lock_buffer = NULL; ok = false; } if (ok) { bitmap->locked_region.data = ogl_bitmap->lock_buffer + pitch * (gl_y + h - 1) + pixel_size * x; bitmap->locked_region.format = format; bitmap->locked_region.pitch = -pitch; bitmap->locked_region.pixel_size = pixel_size; } return ok; }
/* sys_linux_message: * Display a message on our original console. */ static void sys_linux_message (const char *msg) { char *tmp; int ret; ASSERT(msg); tmp = al_malloc(ALLEGRO_MESSAGE_SIZE); msg = uconvert(msg, U_UTF8, tmp, U_ASCII, ALLEGRO_MESSAGE_SIZE); do { ret = write(STDERR_FILENO, msg, strlen(msg)); if ((ret < 0) && (errno != EINTR)) break; } while (ret < (int)strlen(msg)); __al_linux_got_text_message = true; al_free(tmp); }
/* Function: al_emit_user_event */ bool al_emit_user_event(ALLEGRO_EVENT_SOURCE *src, ALLEGRO_EVENT *event, void (*dtor)(ALLEGRO_USER_EVENT *)) { size_t num_queues; bool rc; ASSERT(src); ASSERT(event); ASSERT(ALLEGRO_EVENT_TYPE_IS_USER(event->any.type)); if (dtor) { ALLEGRO_USER_EVENT_DESCRIPTOR *descr = al_malloc(sizeof(*descr)); descr->refcount = 0; descr->dtor = dtor; event->user.__internal__descr = descr; } else { event->user.__internal__descr = NULL; } _al_event_source_lock(src); { ALLEGRO_EVENT_SOURCE_REAL *rsrc = (ALLEGRO_EVENT_SOURCE_REAL *)src; num_queues = _al_vector_size(&rsrc->queues); if (num_queues > 0) { event->user.timestamp = al_get_time(); _al_event_source_emit_event(src, event); rc = true; } else { rc = false; } } _al_event_source_unlock(src); if (dtor && !rc) { dtor(&event->user); al_free(event->user.__internal__descr); } return rc; }
AL_API ALvoid AL_APIENTRY alDeleteAuxiliaryEffectSlots(ALsizei n, const ALuint *effectslots) { ALCcontext *context; ALeffectslot *slot; ALsizei i; context = GetContextRef(); if(!context) return; LockEffectSlotList(context); if(n < 0) SETERR_GOTO(context, AL_INVALID_VALUE, done, "Deleting %d effect slots", n); if(n == 0) goto done; for(i = 0;i < n;i++) { if((slot=LookupEffectSlot(context, effectslots[i])) == NULL) SETERR_GOTO(context, AL_INVALID_NAME, done, "Invalid effect slot ID %u", effectslots[i]); if(ReadRef(&slot->ref) != 0) SETERR_GOTO(context, AL_INVALID_NAME, done, "Deleting in-use effect slot %u", effectslots[i]); } // All effectslots are valid RemoveActiveEffectSlots(effectslots, n, context); for(i = 0;i < n;i++) { if((slot=LookupEffectSlot(context, effectslots[i])) == NULL) continue; VECTOR_ELEM(context->EffectSlotList, effectslots[i]-1) = NULL; DeinitEffectSlot(slot); memset(slot, 0, sizeof(*slot)); al_free(slot); } done: UnlockEffectSlotList(context); ALCcontext_DecRef(context); }
int t3f_animation_delete_frame(T3F_ANIMATION * ap, int frame) { int i; if(frame < ap->frames) { al_free(ap->frame[frame]); } else { return 0; } for(i = frame; i < ap->frames - 1; i++) { ap->frame[i] = ap->frame[i + 1]; } ap->frames--; t3f_animation_build_frame_list(ap); return 1; }
static void _al_win_get_window_center( ALLEGRO_DISPLAY_WIN *win_display, int width, int height, int *out_x, int *out_y) { int a = win_display->adapter; bool *is_fullscreen; ALLEGRO_MONITOR_INFO info; RECT win_size; ALLEGRO_SYSTEM *sys = al_get_system_driver(); unsigned int num; unsigned int i; unsigned int fullscreen_found = 0; num = al_get_num_video_adapters(); is_fullscreen = al_calloc(num, sizeof(bool)); for (i = 0; i < sys->displays._size; i++) { ALLEGRO_DISPLAY **dptr = _al_vector_ref(&sys->displays, i); ALLEGRO_DISPLAY *d = *dptr; if (d->flags & ALLEGRO_FULLSCREEN) { ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *)d; is_fullscreen[win_display->adapter] = true; fullscreen_found++; } } if (fullscreen_found && fullscreen_found < num) { for (i = 0; i < num; i++) { if (is_fullscreen[i] == false) { a = i; break; } } } al_free(is_fullscreen); al_get_monitor_info(a, &info); win_size.left = info.x1 + (info.x2 - info.x1 - width) / 2; win_size.top = info.y1 + (info.y2 - info.y1 - height) / 2; *out_x = win_size.left; *out_y = win_size.top; }
static void xglx_shutdown_system(void) { ALLEGRO_SYSTEM *s = al_get_system_driver(); ALLEGRO_SYSTEM_XGLX *sx = (void *)s; ALLEGRO_INFO("shutting down.\n"); if (sx->have_xevents_thread) { _al_thread_join(&sx->xevents_thread); sx->have_xevents_thread = false; } /* Close all open displays. */ while (_al_vector_size(&s->displays) > 0) { ALLEGRO_DISPLAY **dptr = _al_vector_ref(&s->displays, 0); ALLEGRO_DISPLAY *d = *dptr; al_destroy_display(d); } _al_vector_free(&s->displays); // Makes sure we wait for any commands sent to the X server when destroying the displays. // Should make sure we don't shutdown before modes are restored. if (sx->x11display) { XSync(sx->x11display, False); } _al_xsys_mmon_exit(sx); if (sx->x11display) { XCloseDisplay(sx->x11display); sx->x11display = None; ALLEGRO_DEBUG("xsys: close x11display.\n"); } if (sx->gfxdisplay) { XCloseDisplay(sx->gfxdisplay); sx->gfxdisplay = None; } al_free(sx); }
/* Function: al_open_video */ ALLEGRO_VIDEO *al_open_video(char const *filename) { ALLEGRO_VIDEO *video; video = al_calloc(1, sizeof *video); video->vtable = _al_video_vtable; video->filename = al_create_path(filename); if (!video->vtable->open_video(video)) { al_destroy_path(video->filename); al_free(video); return NULL; } al_init_user_event_source(&video->es); video->es_inited = true; return video; }
static void pulseaudio_deallocate_voice(ALLEGRO_VOICE *voice) { PULSEAUDIO_VOICE *pv = voice->extra; al_lock_mutex(voice->mutex); pv->status = PV_JOIN; al_broadcast_cond(pv->status_cond); al_unlock_mutex(voice->mutex); /* We do NOT hold the voice mutex here, so this does NOT result in a * deadlock when the thread calls _al_voice_update. */ al_join_thread(pv->poll_thread, NULL); al_destroy_thread(pv->poll_thread); al_destroy_cond(pv->status_cond); al_destroy_mutex(pv->buffer_mutex); pa_simple_free(pv->s); al_free(pv); }
/* [user thread] */ static bool wait_for_args(GSourceFunc func, void *data) { ARGS *args = (ARGS *) data; bool response; al_lock_mutex(args->mutex); g_timeout_add(0, func, data); while (args->done == false) { al_wait_cond(args->cond, args->mutex); } al_unlock_mutex(args->mutex); response = args->response; al_destroy_mutex(args->mutex); al_destroy_cond(args->cond); al_free(args); return response; }
ALvoid ReleaseALAuxiliaryEffectSlots(ALCcontext *context) { ALeffectslotPtr *iter = VECTOR_BEGIN(context->EffectSlotList); ALeffectslotPtr *end = VECTOR_END(context->EffectSlotList); size_t leftover = 0; for(;iter != end;iter++) { ALeffectslot *slot = *iter; if(!slot) continue; *iter = NULL; DeinitEffectSlot(slot); memset(slot, 0, sizeof(*slot)); al_free(slot); ++leftover; } if(leftover > 0) WARN("(%p) Deleted "SZFMT" AuxiliaryEffectSlot%s\n", context, leftover, (leftover==1)?"":"s"); }
static bool file_stdio_fclose(ALLEGRO_FILE *f) { USERDATA *userdata = get_userdata(f); bool ret; if (userdata->fp == NULL) { /* This can happen in the middle of al_fopen_fd. */ ret = true; } else if (fclose(userdata->fp) == 0) { ret = true; } else { al_set_errno(errno); ret = false; } al_free(userdata); return ret; }
static ALLEGRO_EXTRA_DISPLAY_SETTINGS* read_pixel_format_old(int fmt, HDC dc) { ALLEGRO_EXTRA_DISPLAY_SETTINGS *eds = NULL; PIXELFORMATDESCRIPTOR pfd; int result; result = DescribePixelFormat(dc, fmt+1, sizeof(pfd), &pfd); if (!result) { ALLEGRO_WARN("DescribePixelFormat() failed. %s\n", get_error_desc(GetLastError())); return NULL; } eds = al_calloc(1, sizeof *eds); if (!decode_pixel_format_old(&pfd, eds)) { al_free(eds); return NULL; } return eds; }
static ALLEGRO_FS_ENTRY *fs_apk_create_entry(const char *path) { ALLEGRO_FS_ENTRY_APK *e; ALLEGRO_USTR *us; e = al_calloc(1, sizeof *e); if (!e) return NULL; e->fs_entry.vtable = &fs_apk_vtable; us = apply_cwd(path); e->path = al_create_path(al_cstr(us)); al_ustr_free(us); if (!e->path) { al_free(e); return NULL; } e->path_cstr = al_path_cstr(e->path, '/'); return &e->fs_entry; }
/* Function: al_destroy_menu */ void al_destroy_menu(ALLEGRO_MENU *menu) { ALLEGRO_MENU_ITEM **slot; size_t i; ASSERT(menu); if (menu->parent) { /* If the menu is attached to a menu item, then this is equivelant to removing that menu item. */ ALLEGRO_MENU *parent = menu->parent->parent; ASSERT(parent); for (i = 0; i < _al_vector_size(&parent->items); ++i) { slot = _al_vector_ref(&parent->items, i); if (*slot == menu->parent) { al_remove_menu_item(parent, 0 - (int) i); return; } } /* Should never get here. */ ASSERT(false); return; } else if (menu->display && !menu->is_popup_menu) { /* This is an active, top-level menu. */ al_remove_display_menu(menu->display); } /* Destroy each item associated with the menu. */ while (_al_vector_size(&menu->items)) { slot = _al_vector_ref_back(&menu->items); destroy_menu_item(*slot); } _al_vector_free(&menu->items); al_disable_menu_event_source(menu); al_free(menu); }