/* joystick_dinput_exit: [primary thread] * Shuts down the DirectInput joystick devices. */ static void joystick_dinput_exit(void) { int i, j; /* unacquire the devices */ wnd_call_proc(joystick_dinput_unacquire); /* destroy the devices */ for (i=0; i<dinput_joy_num; i++) { IDirectInputDevice2_Release(dinput_joystick[i].device); for (j=0; j<dinput_joystick[i].num_axes; j++) { if (dinput_joystick[i].axis_name[j]) _AL_FREE(dinput_joystick[i].axis_name[j]); } if (dinput_joystick[i].caps & JOYCAPS_HASPOV) _AL_FREE(dinput_joystick[i].hat_name); for (j=0; j<dinput_joystick[i].num_buttons; j++) _AL_FREE(dinput_joystick[i].button_name[j]); } /* destroy the DirectInput interface */ IDirectInput_Release(joystick_dinput); win_remove_all_joysticks(); dinput_joy_num = 0; }
/* _xdga2_fetch_mode_list: * Creates list of available DGA2 video modes. */ static GFX_MODE_LIST *_xdga2_private_fetch_mode_list(void) { XDGAMode *mode; int bpp, num_modes, stored_modes, i, j, already_there; GFX_MODE_LIST *mode_list; GFX_MODE *tmp; mode = XDGAQueryModes(_xwin.display, _xwin.screen, &num_modes); if (!mode) return NULL; mode_list = _AL_MALLOC(sizeof(GFX_MODE_LIST)); if (!mode_list) goto error; mode_list->mode = NULL; stored_modes = 0; for (i=0; i<num_modes; i++) { bpp = (mode[i].depth == 24) ? mode[i].bitsPerPixel : mode[i].depth; already_there = FALSE; for (j=0; j<stored_modes; j++) { if ((mode_list->mode[j].width == mode[i].viewportWidth) && (mode_list->mode[j].height == mode[i].viewportHeight) && (mode_list->mode[j].bpp == bpp)) { already_there = TRUE; break; } } if (!already_there) { tmp = _AL_REALLOC(mode_list->mode, sizeof(GFX_MODE) * (stored_modes + 1)); if (!tmp) goto error; mode_list->mode = tmp; mode_list->mode[stored_modes].width = mode[i].viewportWidth; mode_list->mode[stored_modes].height = mode[i].viewportHeight; mode_list->mode[stored_modes].bpp = bpp; stored_modes++; } } tmp = _AL_REALLOC(mode_list->mode, sizeof(GFX_MODE) * (stored_modes + 1)); if (!tmp) goto error; mode_list->mode = tmp; mode_list->mode[stored_modes].width = 0; mode_list->mode[stored_modes].height = 0; mode_list->mode[stored_modes].bpp = 0; mode_list->num_modes = stored_modes; XFree(mode); return mode_list; error: if (mode_list) { _AL_FREE(mode_list->mode); _AL_FREE(mode_list); } XFree(mode); return NULL; }
/* gfx_directx_destroy_system_bitmap: */ void gfx_directx_destroy_system_bitmap(BITMAP *bmp) { /* Special case: use normal destroy_bitmap() for subbitmaps of system * bitmaps. Checked here rather than in destroy_bitmap() because that * function should not make assumptions about the relation between system * bitmaps and subbitmaps thereof. This duplicates code though and a * different solution would be better. */ if (is_sub_bitmap(bmp)) { if (system_driver->destroy_bitmap) { if (system_driver->destroy_bitmap(bmp)) return; } if (bmp->dat) _AL_FREE(bmp->dat); _AL_FREE(bmp); return; } /* destroy the surface */ gfx_directx_destroy_surface(DDRAW_SURFACE_OF(bmp)); _AL_FREE(bmp); }
/* gfx_directx_destroy_video_bitmap: */ void gfx_directx_destroy_video_bitmap(BITMAP *bmp) { DDRAW_SURFACE *surf, *tail_page; surf = DDRAW_SURFACE_OF(bmp); if ((surf == flipping_page[0]) || (surf == flipping_page[1]) || (surf == flipping_page[2])) { /* handle surfaces belonging to the flipping chain */ if (--n_flipping_pages > 0) { tail_page = flipping_page[n_flipping_pages]; /* If the surface attached to the bitmap is not the tail page * that is to be destroyed, attach it to the bitmap whose * attached surface is the tail page. */ if (surf != tail_page) { surf->parent_bmp = tail_page->parent_bmp; surf->parent_bmp->extra = surf; } /* remove the tail page from the flipping chain */ recreate_flipping_chain(n_flipping_pages); _AL_FREE(tail_page); } flipping_page[n_flipping_pages] = NULL; } else { /* destroy the surface */ gfx_directx_destroy_surface(surf); } _AL_FREE(bmp); }
/* stretch_blit_to_hdc: * Blits an Allegro BITMAP to a Windows DC. Has a syntax similar to * stretch_blit(). */ static void local_stretch_blit_to_hdc(ALLEGRO_BITMAP *bitmap, HDC dc, int src_x, int src_y, int src_w, int src_h, int dest_x, int dest_y, int dest_w, int dest_h) { const int bitmap_h = al_get_bitmap_height(bitmap); const int bottom_up_src_y = bitmap_h - src_y - src_h; BYTE *pixels; BITMAPINFO *bi; bi = get_bitmap_info(bitmap); pixels = get_dib_from_bitmap_32(bitmap); /* Windows treats all source bitmaps as bottom-up when using StretchDIBits * unless the source (x,y) is (0,0). To work around this buggy behavior, we * can use negative heights to reverse the direction of the blits. * * See <http://wiki.allegro.cc/StretchDIBits> for a detailed explanation. */ if (bottom_up_src_y == 0 && src_x == 0 && src_h != bitmap_h) { StretchDIBits(dc, dest_x, dest_h+dest_y-1, dest_w, -dest_h, src_x, bitmap_h - src_y + 1, src_w, -src_h, pixels, bi, DIB_RGB_COLORS, SRCCOPY); } else { StretchDIBits(dc, dest_x, dest_y, dest_w, dest_h, src_x, bottom_up_src_y, src_w, src_h, pixels, bi, DIB_RGB_COLORS, SRCCOPY); } _AL_FREE(pixels); _AL_FREE(bi); }
/* destroy_gfx_mode_list: * Removes the mode list created by get_gfx_mode_list() from memory. */ void destroy_gfx_mode_list(GFX_MODE_LIST *gfx_mode_list) { if (gfx_mode_list) { if (gfx_mode_list->mode) _AL_FREE(gfx_mode_list->mode); _AL_FREE(gfx_mode_list); } }
static void joy_exit(void) { int i, j; for (i = 0; i < num_joysticks; i++) { close(joy_fd[i]); for (j = 0; j < joy[i].num_sticks; j++) _AL_FREE((void *)joy[i].stick[j].name); for (j = 0; j < joy[i].num_buttons; j++) _AL_FREE((void *)joy[i].button[j].name); } }
/* font_filetype_destructor: * Since we only want to destroy the whole list when we *actually* * quit, not just when allegro_exit() is called, we need to use a * destructor to accomplish this. */ static void font_filetype_destructor(void) { FONT_TYPE_INFO *iter = font_type_list, *next; while (iter) { next = iter->next; _AL_FREE(iter->ext); _AL_FREE(iter); iter = next; } font_type_list = NULL; _remove_exit_func(register_font_file_type_exit); }
/* ljoy_release_joystick: [primary thread] * * Close the device for a joystick then free the joystick structure. */ static void ljoy_release_joystick(ALLEGRO_JOYSTICK *joy_) { ALLEGRO_JOYSTICK_LINUX *joy = (ALLEGRO_JOYSTICK_LINUX *) joy_; int i; _al_unix_stop_watching_fd(joy->fd); _al_event_source_free(&joy->parent.es); close(joy->fd); for (i = 0; i < joy->parent.info.num_sticks; i++) _AL_FREE((void *)joy->parent.info.stick[i].name); for (i = 0; i < joy->parent.info.num_buttons; i++) _AL_FREE((void *)joy->parent.info.button[i].name); _AL_FREE(joy); }
/* bitmap_filetype_destructor: * Since we only want to destroy the whole list when we *actually* * quit, not just when allegro_exit() is called, we need to use a * destructor to accomplish this. */ static void bitmap_filetype_destructor(void) { BITMAP_TYPE_INFO *iter = bitmap_type_list, *next; while (iter) { next = iter->next; _AL_FREE(iter->ext); _AL_FREE(iter); iter = next; } bitmap_type_list = NULL; _remove_exit_func(register_bitmap_file_type_exit); }
/* Function: al_destroy_path */ void al_destroy_path(ALLEGRO_PATH *path) { unsigned i; if (!path) { return; } if (path->drive) { al_ustr_free(path->drive); path->drive = NULL; } if (path->filename) { al_ustr_free(path->filename); path->filename = NULL; } for (i = 0; i < _al_vector_size(&path->segments); i++) { al_ustr_free(get_segment(path, i)); } _al_vector_free(&path->segments); if (path->basename) { al_ustr_free(path->basename); path->basename = NULL; } if (path->full_string) { al_ustr_free(path->full_string); path->full_string = NULL; } _AL_FREE(path); }
/* _unregister_switch_bitmap: * Removes a bitmap from the list of things that need to be saved. */ void _unregister_switch_bitmap(BITMAP *bmp) { BITMAP_INFORMATION *info, **head; if (system_driver->display_switch_lock) system_driver->display_switch_lock(TRUE, FALSE); info = find_switch_bitmap(&info_list, bmp, &head); if (!info) goto getout; /* all the sub-bitmaps should be destroyed before we get to here */ ASSERT(!info->child); /* it's not cool to destroy things that have important state */ ASSERT(!info->other); *head = info->sibling; _AL_FREE(info); getout: if (system_driver->display_switch_lock) system_driver->display_switch_lock(FALSE, FALSE); }
/* modex_exit: * Frees the magic bank switch buffer. */ static void modex_exit(BITMAP *b) { #ifdef ALLEGRO_DOS /* free conventional memory buffer */ if (_x_magic_buffer_addr) { __dpmi_free_dos_memory(magic_sel); magic_sel = 0; _x_magic_buffer_addr = 0; } #else /* free normal memory buffer */ if (_x_magic_buffer_addr) { _AL_FREE((void *)_x_magic_buffer_addr); _x_magic_buffer_addr = 0; } #endif _unset_vga_mode(); /* see modexsms.c */ _split_modex_screen_ptr = NULL; }
/* close_fli: * Shuts down the FLI player at the end of the file. */ void close_fli(void) { remove_int(fli_timer_callback); if (fli_file) { pack_fclose(fli_file); fli_file = NULL; } if (fli_filename) { _AL_FREE(fli_filename); fli_filename = NULL; } if (fli_bitmap) { destroy_bitmap(fli_bitmap); fli_bitmap = NULL; } fli_mem_data = NULL; fli_mem_pos = 0; reset_fli_variables(); fli_status = FLI_NOT_OPEN; }
/* add_vram_block: * Creates a video memory bitmap out of the specified region * of the larger screen surface, returning a pointer to it. */ static BITMAP *add_vram_block(int x, int y, int w, int h) { VRAM_BITMAP *b, *new_b; VRAM_BITMAP **last_p; new_b = _AL_MALLOC(sizeof(VRAM_BITMAP)); if (!new_b) return NULL; new_b->x = x; new_b->y = y; new_b->w = w; new_b->h = h; new_b->bmp = create_sub_bitmap(screen, x, y, w, h); if (!new_b->bmp) { _AL_FREE(new_b); return NULL; } /* find sorted y-position */ last_p = &vram_bitmap_list; for (b = vram_bitmap_list; b && (b->y < new_b->y); b = b->next_y) last_p = &b->next_y; /* insert */ *last_p = new_b; new_b->next_y = b; return new_b->bmp; }
/* gfx_gdi_exit: */ static void gfx_gdi_exit(struct BITMAP *bmp) { _enter_critical(); _enter_gfx_critical(); if (bmp) { save_window_pos(); clear_bitmap(bmp); } /* stop timer */ remove_int(render_proc); CloseHandle(vsync_event); /* disconnect from the system driver */ win_gfx_driver = NULL; /* destroy dirty lines array */ _AL_FREE(gdi_dirty_lines); gdi_dirty_lines = NULL; /* destroy screen surface */ _AL_FREE(screen_surf); gdi_screen = NULL; /* destroy mouse bitmaps */ if (wgdi_mouse_sprite) { destroy_bitmap(wgdi_mouse_sprite); wgdi_mouse_sprite = NULL; destroy_bitmap(mouse_frontbuffer); mouse_frontbuffer = NULL; destroy_bitmap(mouse_backbuffer); mouse_backbuffer = NULL; } _exit_gfx_critical(); /* before restoring video mode, hide window */ set_display_switch_mode(SWITCH_PAUSE); system_driver->restore_console_state(); restore_window_style(); _exit_critical(); }
/* To be called when stream is destroyed */ static void ogg_stream_close(ALLEGRO_AUDIO_STREAM *stream) { AL_OV_DATA *extra = (AL_OV_DATA *) stream->extra; ALLEGRO_EVENT quit_event; quit_event.type = _KCM_STREAM_FEEDER_QUIT_EVENT_TYPE; al_emit_user_event(al_get_audio_stream_event_source(stream), &quit_event, NULL); al_join_thread(stream->feed_thread, NULL); al_destroy_thread(stream->feed_thread); ov_clear(extra->vf); _AL_FREE(extra->vf); _AL_FREE(extra); stream->extra = NULL; stream->feed_thread = NULL; }
/* _unix_destroy_mutex: * Destroys a mutex. */ void _unix_destroy_mutex(void *handle) { struct my_mutex *mx = (struct my_mutex *)handle; pthread_mutex_destroy(&mx->actual_mutex); _AL_FREE(mx); }
/* al_findclose: * Cleans up after a directory search. */ void al_findclose(struct al_ffblk *info) { struct FF_DATA *ff_data = (struct FF_DATA *) info->ff_data; if (ff_data) { _findclose(ff_data->handle); _AL_FREE(ff_data); info->ff_data = NULL; } }
/* sys_directx_get_executable_name: * Returns full path to the current executable. */ static void sys_directx_get_executable_name(char *output, int size) { char *temp = _AL_MALLOC_ATOMIC(size); if (GetModuleFileName(allegro_inst, temp, size)) do_uconvert(temp, U_ASCII, output, U_CURRENT, size); else usetc(output, 0); _AL_FREE(temp); }
/* _al_sane_realloc: * _AL_REALLOC() substitution with guaranteed behaviour. */ void *_al_sane_realloc(void *ptr, size_t size) { void *tmp_ptr; tmp_ptr = NULL; if (ptr && size) { tmp_ptr = _AL_REALLOC(ptr, size); if (!tmp_ptr && ptr) _AL_FREE(ptr); } else if (!size) { tmp_ptr = NULL; if (ptr) _AL_FREE(ptr); } else if (!ptr) { tmp_ptr = _AL_MALLOC(size); } return tmp_ptr; }
static void gp2xwiz_destroy_display_fb(ALLEGRO_DISPLAY *d) { ALLEGRO_SYSTEM_GP2XWIZ *s = (void *)al_get_system_driver(); ALLEGRO_DISPLAY_GP2XWIZ_FB *wiz_disp = (void *)d; _al_vector_find_and_delete(&s->system.displays, &d); /* All bitmaps are memory bitmaps, no need to do anything */ _al_vector_free(&d->bitmaps); _al_event_source_free(&d->es); wiz_disp->backbuffer->memory = wiz_disp->screen_mem; al_destroy_bitmap(wiz_disp->backbuffer); _AL_FREE(d->vertex_cache); _AL_FREE(d); set_gfx_mode = false; }
/* Internal function: _al_vector_free * * Free the space used by the vector. You really must do this at some * stage. It is not enough to delete all the items in the vector (which you * should usually do also). */ void _al_vector_free(_AL_VECTOR *vec) { ASSERT(vec); if (vec->_items != NULL) { _AL_FREE(vec->_items); vec->_items = NULL; } vec->_size = 0; vec->_unused = 0; }
/* _dos_irq_exit: * Routine for freeing the interrupt handler stacks. */ void _dos_irq_exit(void) { int c; for (c=0; c<IRQ_STACKS; c++) { if (_irq_stack[c]) { _irq_stack[c] -= STACK_SIZE - 32; _AL_FREE(_irq_stack[c]); _irq_stack[c] = NULL; } } }
/* Function: al_destroy_native_dialog */ void al_destroy_native_dialog(ALLEGRO_NATIVE_DIALOG *fd) { if (!fd) return; if (fd->paths) { size_t i; for (i = 0; i < fd->count; i++) { al_destroy_path(fd->paths[i]); } } _AL_FREE(fd->paths); if (fd->initial_path) al_destroy_path(fd->initial_path); al_ustr_free(fd->title); al_ustr_free(fd->heading); al_ustr_free(fd->patterns); al_ustr_free(fd->text); al_ustr_free(fd->buttons); al_destroy_cond(fd->cond); _AL_FREE(fd); }
void _al_win_destroy_mouse_cursor(ALLEGRO_DISPLAY *display, ALLEGRO_MOUSE_CURSOR *cursor) { ALLEGRO_DISPLAY_WIN *win_display = (ALLEGRO_DISPLAY_WIN *) display; ALLEGRO_MOUSE_CURSOR_WIN *win_cursor = (ALLEGRO_MOUSE_CURSOR_WIN *) cursor; ASSERT(win_cursor); if (win_cursor->hcursor == win_display->mouse_selected_hcursor) { _al_win_set_system_mouse_cursor(display, ALLEGRO_SYSTEM_MOUSE_CURSOR_ARROW); } DestroyIcon(win_cursor->hcursor); _AL_FREE(win_cursor); }
/* register_bitmap_file_type_exit: * Free list of registered bitmap file types. */ static void register_bitmap_file_type_exit(void) { BITMAP_TYPE_INFO *iter = bitmap_type_list, *next; while (iter) { next = iter->next; _AL_FREE(iter->ext); _AL_FREE(iter); iter = next; } bitmap_type_list = NULL; /* If we are using a destructor, then we only want to prune the list * down to valid modules. So we clean up as usual, but then reinstall * the internal modules. */ #ifdef ALLEGRO_USE_CONSTRUCTOR _register_bitmap_file_type_init(); #endif _remove_exit_func(register_bitmap_file_type_exit); }
/* al_findclose: * Cleans up after a directory search. */ void al_findclose(struct al_ffblk *info) { struct FF_DATA *ff_data = (struct FF_DATA *) info->ff_data; if (ff_data) { if (ff_data->dir) { closedir(ff_data->dir); } _AL_FREE(ff_data); info->ff_data = NULL; /* to avoid leaking memory */ ff_match(NULL, NULL); } }
/* _free_win_midi_driver_list: * Helper function for freeing the dynamically generated driver list. */ void _free_win_midi_driver_list(void) { int i = 0; if (driver_list) { while (driver_list[i].driver) { if (driver_list[i].id != MIDI_DIGMID) _AL_FREE(driver_list[i].driver); i++; } _destroy_driver_list(driver_list); driver_list = NULL; } }
/* sys_directx_message: * Displays a message. */ static void sys_directx_message(AL_CONST char *msg) { char *tmp1 = _AL_MALLOC_ATOMIC(ALLEGRO_MESSAGE_SIZE); char tmp2[WND_TITLE_SIZE*2]; HWND allegro_wnd = win_get_window(); while ((ugetc(msg) == '\r') || (ugetc(msg) == '\n')) msg += uwidth(msg); MessageBoxW(allegro_wnd, (unsigned short *)uconvert(msg, U_CURRENT, tmp1, U_UNICODE, ALLEGRO_MESSAGE_SIZE), (unsigned short *)uconvert(wnd_title, U_ASCII, tmp2, U_UNICODE, sizeof(tmp2)), MB_OK); _AL_FREE(tmp1); }