bool RocketRenderingInterface::GenerateTexture(TextureHandle& texture_handle, const Rocket::Core::byte* source, const Vector2i& source_dimensions) { GR_DEBUG_SCOPE("libRocket::GenerateTexture"); auto size = (size_t)(source_dimensions.x * source_dimensions.y * 4); // RGBA format std::unique_ptr<uint8_t[]> buffer(new uint8_t[size]); memcpy(buffer.get(), source, size); auto id = bm_create(32, source_dimensions.x, source_dimensions.y, buffer.get()); if (id < 0) { return false; } auto* tex = new Texture(); tex->handle = id; tex->data = std::move(buffer); texture_handle = get_texture_handle(tex); return true; }
int init(const char *appTitle, int flags) { flags |= SDL_WINDOW_SHOWN; rlog("Creating Window."); win = SDL_CreateWindow(appTitle, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, screenWidth, screenHeight, flags); if(!win) { rerror("SDL_CreateWindow: %s", SDL_GetError()); return 0; } ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); if(!ren) { rerror("SDL_CreateRenderer: %s", SDL_GetError()); return 0; } SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, filter); rlog("Window Created."); if(SDL_ShowCursor(show_cursor) < 0) { rerror("SDL_ShowCursor: %s", SDL_GetError()); } bmp = bm_create(virt_width, virt_height); tex = SDL_CreateTexture(ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, bmp->w, bmp->h); if(!tex) { rerror("SDL_CreateTexture: %s", SDL_GetError()); return 0; } rlog("Texture Created."); reset_keys(); return 1; }
static void set_unset_test() { printf("Set/Unset Tests\n"); bitmask bm; bm_create(&bm); int bit, hi, low; hi = 0; low = 0; assert_int_equals(hi, bm_gethibit(&bm), "Basic Test Hi 1"); assert_int_equals(low, bm_getlowbit(&bm), "Basic Test Low 1"); bit = 5; hi = 5; low = 5; bm_set(&bm, bit); assert_int_equals(hi, bm_gethibit(&bm), "Basic Test Hi 1"); assert_int_equals(low, bm_getlowbit(&bm), "Basic Test Low 1"); assert_true(bm_isset(&bm, bit), "Basic Test isset 1"); bit = 10; hi = 10; low = 5; bm_set(&bm, bit); assert_int_equals(hi, bm_gethibit(&bm), "Basic Test Hi 2"); assert_int_equals(low, bm_getlowbit(&bm), "Basic Test Low 2"); assert_true(bm_isset(&bm, bit), "Basic Test isset 2"); bit = 7; hi = 10; low = 5; bm_set(&bm, bit); assert_int_equals(hi, bm_gethibit(&bm), "Basic Test Hi 3"); assert_int_equals(low, bm_getlowbit(&bm), "Basic Test Low 2"); assert_true(bm_isset(&bm, bit), "Basic Test isset 3"); bit = 5; hi = 10; low = 7; bm_unset(&bm, bit); assert_int_equals(hi, bm_gethibit(&bm), "Basic Test Hi 3"); assert_int_equals(low, bm_getlowbit(&bm), "Basic Test Low 2"); assert_false(bm_isset(&bm, bit), "Basic Test isset 4"); }
BMCanvas::BMCanvas(int x, int y, int w, int h, const char *label) : Fl_Widget(x, y, w, h, label), _zoom(1.0) { bmp = bm_create(w, h); }
void BMCanvas::resize(int x, int y, int w, int h) { bm_free(bmp); bmp = bm_create(w, h); Fl_Widget::resize(x, y, w, h); }
int gr_opengl_save_screen() { int i; ubyte *sptr = NULL, *dptr = NULL; ubyte *opengl_screen_tmp = NULL; int width_times_pixel; gr_opengl_reset_clip(); if (GL_saved_screen || GL_screen_pbo) { // already have a screen saved so just bail... return -1; } GL_saved_screen = (ubyte*)vm_malloc( gr_screen.max_w * gr_screen.max_h * 4, memory::quiet_alloc); if (!GL_saved_screen) { mprintf(( "Couldn't get memory for saved screen!\n" )); return -1; } GLboolean save_state = GL_state.DepthTest(GL_FALSE); glReadBuffer(GL_FRONT_LEFT); if ( Use_PBOs ) { GLubyte *pixels = NULL; glGenBuffers(1, &GL_screen_pbo); if (!GL_screen_pbo) { if (GL_saved_screen) { vm_free(GL_saved_screen); GL_saved_screen = NULL; } return -1; } glBindBuffer(GL_PIXEL_PACK_BUFFER, GL_screen_pbo); glBufferData(GL_PIXEL_PACK_BUFFER, gr_screen.max_w * gr_screen.max_h * 4, NULL, GL_STATIC_READ); glReadPixels(0, 0, gr_screen.max_w, gr_screen.max_h, GL_read_format, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); pixels = (GLubyte*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY); width_times_pixel = (gr_screen.max_w * 4); sptr = (ubyte *)pixels; dptr = (ubyte *)&GL_saved_screen[gr_screen.max_w * gr_screen.max_h * 4]; for (i = 0; i < gr_screen.max_h; i++) { dptr -= width_times_pixel; memcpy(dptr, sptr, width_times_pixel); sptr += width_times_pixel; } glUnmapBuffer(GL_PIXEL_PACK_BUFFER); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); glDeleteBuffers(1, &GL_screen_pbo); GL_screen_pbo = 0; GL_saved_screen_id = bm_create(32, gr_screen.max_w, gr_screen.max_h, GL_saved_screen, 0); } else { opengl_screen_tmp = (ubyte*)vm_malloc( gr_screen.max_w * gr_screen.max_h * 4, memory::quiet_alloc); if (!opengl_screen_tmp) { if (GL_saved_screen) { vm_free(GL_saved_screen); GL_saved_screen = NULL; } mprintf(( "Couldn't get memory for temporary saved screen!\n" )); GL_state.DepthTest(save_state); return -1; } glReadPixels(0, 0, gr_screen.max_w, gr_screen.max_h, GL_read_format, GL_UNSIGNED_INT_8_8_8_8_REV, opengl_screen_tmp); sptr = (ubyte *)&opengl_screen_tmp[gr_screen.max_w * gr_screen.max_h * 4]; dptr = (ubyte *)GL_saved_screen; width_times_pixel = (gr_screen.max_w * 4); for (i = 0; i < gr_screen.max_h; i++) { sptr -= width_times_pixel; memcpy(dptr, sptr, width_times_pixel); dptr += width_times_pixel; } vm_free(opengl_screen_tmp); GL_saved_screen_id = bm_create(32, gr_screen.max_w, gr_screen.max_h, GL_saved_screen, 0); } GL_state.DepthTest(save_state); return GL_saved_screen_id; }
/** * @brief This function is called to blit the next frame of an anim instance to the screen. * This is normally called by the anim_render_all() function. * * @param instance Pointer to animation instance * @param frametime Time elapsed since last call, in seconds */ int anim_show_next_frame(anim_instance *instance, float frametime) { int bitmap_id, bitmap_flags=0, new_frame_num, frame_diff=0, i, n_frames=0,frame_save; float percent_through, time; vertex image_vertex; int aabitmap = 0; int bpp = 16; Assert( instance != NULL ); instance->time_elapsed += frametime; // Advance to the next frame, if we determine enough time has elapsed. if(instance->direction == ANIM_DIRECT_FORWARD) n_frames = instance->stop_at - instance->start_at + 1; else if(instance->direction == ANIM_DIRECT_REVERSE) n_frames = instance->start_at - instance->stop_at + 1; time = n_frames / i2fl(instance->parent->fps); percent_through = instance->time_elapsed / time; if(instance->direction == ANIM_DIRECT_FORWARD) new_frame_num = instance->start_at - 1 + fl2i(percent_through * n_frames + 0.5f); else new_frame_num = instance->start_at - 1 - fl2i(percent_through * n_frames + 0.5f); frame_save = instance->frame_num; // If framerate independent, use the new_frame_num... unless instance->skip_frames is // FALSE, then only advance a maximum of one frame (this is needed since some big animations // should just play slower rather than taking the hit of decompressing multiple frames and // creating an even greater slowdown if (instance->framerate_independent) { if(instance->direction == ANIM_DIRECT_FORWARD){ if ( new_frame_num > instance->last_frame_num) { if ( instance->skip_frames ) instance->frame_num = new_frame_num; else instance->frame_num++; } } else if(instance->direction == ANIM_DIRECT_REVERSE){ if( new_frame_num < instance->last_frame_num) { if ( instance->skip_frames ) instance->frame_num = new_frame_num; else instance->frame_num--; } } } else { if(instance->direction == ANIM_DIRECT_FORWARD){ if ( new_frame_num > instance->last_frame_num) { instance->frame_num++; } } else if(instance->direction == ANIM_DIRECT_REVERSE){ if ( new_frame_num < instance->last_frame_num) { instance->frame_num--; } } } if(instance->direction == ANIM_DIRECT_FORWARD){ if ( instance->frame_num < instance->start_at ) { instance->frame_num = instance->start_at; } } else if(instance->direction == ANIM_DIRECT_REVERSE){ if ( instance->frame_num > instance->start_at ) { instance->frame_num = instance->start_at; } } if ( instance->stop_now == TRUE ) { return -1; } // If past the last frame, clamp to the last frame and then set the stop_now flag in the // anim instance. The next iteration, the animation will stop. if(instance->direction == ANIM_DIRECT_FORWARD){ if (instance->frame_num >= instance->stop_at ) { if (instance->looped) { // looped animations instance->frame_num = instance->stop_at; instance->time_elapsed = 0.0f; } else if(instance->ping_pong) { // pingponged animations instance->frame_num = instance->stop_at; anim_reverse_direction(instance); } else { // one-shot animations instance->frame_num = instance->stop_at; instance->last_frame_num = instance->frame_num; instance->stop_now = TRUE; } } } else if(instance->direction == ANIM_DIRECT_REVERSE){ if (instance->frame_num <= instance->stop_at ) { if (instance->looped) { // looped animations instance->frame_num = instance->stop_at; instance->time_elapsed = 0.0f; } else if(instance->ping_pong) { // pingponged animations instance->frame_num = instance->stop_at; anim_reverse_direction(instance); } else { // one-shot animations instance->frame_num = instance->stop_at+1; instance->last_frame_num = instance->frame_num; instance->stop_now = TRUE; } } } if(instance->direction == ANIM_DIRECT_FORWARD){ if( instance->last_frame_num >= instance->start_at ) { frame_diff = instance->frame_num - instance->last_frame_num; } else { frame_diff = 1; } } else if(instance->direction == ANIM_DIRECT_REVERSE){ if( instance->last_frame_num <= instance->start_at ) { frame_diff = instance->last_frame_num - instance->frame_num; } else { frame_diff = 1; } } Assert(frame_diff >= 0); Assert( instance->frame_num >= 0 && instance->frame_num < instance->parent->total_frames ); // if the anim is paused, ignore all the above changes and still display this frame if(instance->paused || Anim_paused){ instance->frame_num = frame_save; instance->time_elapsed -= frametime; frame_diff = 0; } if (instance->parent->flags & ANF_XPARENT){ bitmap_flags = 0; } bpp = 16; if(instance->aa_color != NULL){ bitmap_flags |= BMP_AABITMAP; aabitmap = 1; bpp = 8; } if ( frame_diff > 0 ) { instance->last_frame_num = instance->frame_num; t1 = timer_get_fixed_seconds(); for ( i = 0; i < frame_diff; i++ ) { anim_check_for_palette_change(instance); // if we're playing backwards, every frame must be a keyframe and we set the data ptr here if(instance->direction == ANIM_DIRECT_REVERSE){ if ( anim_instance_is_streamed(instance) ) { instance->file_offset = instance->parent->file_offset + instance->parent->keys[instance->frame_num-1].offset; } else { instance->data = instance->parent->data + instance->parent->keys[instance->frame_num-1].offset; } } ubyte *temp = NULL; int temp_file_offset = -1; // if we're using bitmap polys BM_SELECT_TEX_FORMAT(); if ( anim_instance_is_streamed(instance) ) { if ( instance->xlate_pal ){ temp_file_offset = unpack_frame_from_file(instance, instance->frame, instance->parent->width*instance->parent->height, instance->parent->palette_translation, aabitmap, bpp); } else { temp_file_offset = unpack_frame_from_file(instance, instance->frame, instance->parent->width*instance->parent->height, NULL, aabitmap, bpp); } } else { if ( instance->xlate_pal ){ temp = unpack_frame(instance, instance->data, instance->frame, instance->parent->width*instance->parent->height, instance->parent->palette_translation, aabitmap, bpp); } else { temp = unpack_frame(instance, instance->data, instance->frame, instance->parent->width*instance->parent->height, NULL, aabitmap, bpp); } } // always go back to screen format BM_SELECT_SCREEN_FORMAT(); // see if we had an error during decode (corrupted anim stream) if ( (temp == NULL) && (temp_file_offset < 0) ) { mprintf(("ANI: Fatal ERROR at frame %i!! Aborting playback of \"%s\"...\n", instance->frame_num, instance->parent->name)); // return -1 to end all playing of this anim instanc return -1; } if(instance->direction == ANIM_DIRECT_FORWARD){ if ( anim_instance_is_streamed(instance) ) { instance->file_offset = temp_file_offset; } else { instance->data = temp; } } } t2 = timer_get_fixed_seconds(); } else { t2=t1=0; } // this only happens when the anim is being looped, we need to reset the last_frame_num if ( (instance->time_elapsed == 0) && (instance->looped) ) { instance->last_frame_num = -1; instance->frame_num = -1; instance->data = instance->parent->data; instance->file_offset = instance->parent->file_offset; instance->loop_count++; } t1 = timer_get_fixed_seconds(); if ( frame_diff == 0 && instance->last_bitmap != -1 ) { bitmap_id = instance->last_bitmap; } else { if ( instance->last_bitmap != -1 ){ bm_release(instance->last_bitmap); } bitmap_id = bm_create(bpp, instance->parent->width, instance->parent->height, instance->frame, bitmap_flags); } if ( bitmap_id == -1 ) { // anim has finsished playing, free the instance frame data anim_release_render_instance(instance); return -1; // NOTE: there is no need to free the instance, since it was pre-allocated as // part of the anim_free_list } else { gr_set_bitmap(bitmap_id); // determine x,y to display the bitmap at if ( instance->world_pos == NULL ) { int old_max_w_unscaled = gr_screen.max_w_unscaled; int old_max_h_unscaled = gr_screen.max_h_unscaled; int old_max_w_unscaled_zoomed = gr_screen.max_w_unscaled_zoomed; int old_max_h_unscaled_zoomed = gr_screen.max_h_unscaled_zoomed; gr_set_screen_scale(instance->base_w, instance->base_h); gr_set_clip(0, 0, instance->base_w, instance->base_h, GR_RESIZE_MENU); if ( instance->aa_color == NULL ) { gr_bitmap(instance->x, instance->y, GR_RESIZE_MENU_NO_OFFSET); } else { gr_set_color_fast( (color*)instance->aa_color ); gr_aabitmap(instance->x, instance->y, GR_RESIZE_MENU_NO_OFFSET); } gr_set_screen_scale(old_max_w_unscaled, old_max_h_unscaled, old_max_w_unscaled_zoomed, old_max_h_unscaled_zoomed); gr_reset_clip(); } else { g3_rotate_vertex(&image_vertex,instance->world_pos); Assert(instance->radius != 0.0f); //g3_draw_bitmap(&image_vertex, 0, instance->radius*1.5f, TMAP_FLAG_TEXTURED | TMAP_HTL_2D); material mat_params; material_set_unlit(&mat_params, bitmap_id, 1.0f, false, false); g3_render_rect_screen_aligned_2d(&mat_params, &image_vertex, 0, instance->radius*1.5f); } instance->last_bitmap = bitmap_id; } t2 = timer_get_fixed_seconds(); return 0; }
int generic_anim_stream(generic_anim *ga, const bool cache) { CFILE *img_cfp = NULL; int anim_fps = 0; char full_path[MAX_PATH]; int size = 0, offset = 0; const int NUM_TYPES = 3; const ubyte type_list[NUM_TYPES] = {BM_TYPE_EFF, BM_TYPE_ANI, BM_TYPE_PNG}; const char *ext_list[NUM_TYPES] = {".eff", ".ani", ".png"}; int rval = -1; int bpp; ga->type = BM_TYPE_NONE; rval = cf_find_file_location_ext(ga->filename, NUM_TYPES, ext_list, CF_TYPE_ANY, sizeof(full_path) - 1, full_path, &size, &offset, 0); // could not be found, or is invalid for some reason if ( (rval < 0) || (rval >= NUM_TYPES) ) return -1; //make sure we can open it img_cfp = cfopen_special(full_path, "rb", size, offset, CF_TYPE_ANY); if (img_cfp == NULL) { return -1; } strcat_s(ga->filename, ext_list[rval]); ga->type = type_list[rval]; //seek to the end cfseek(img_cfp, 0, CF_SEEK_END); cfclose(img_cfp); if(ga->type == BM_TYPE_ANI) { bpp = ANI_BPP_CHECK; if(ga->use_hud_color) bpp = 8; if (ga->ani.animation == nullptr) { ga->ani.animation = anim_load(ga->filename, CF_TYPE_ANY, 0); } if (ga->ani.instance == nullptr) { ga->ani.instance = init_anim_instance(ga->ani.animation, bpp); } #ifndef NDEBUG // for debug of ANI sizes strcpy_s(ga->ani.animation->name, ga->filename); #endif ga->num_frames = ga->ani.animation->total_frames; anim_fps = ga->ani.animation->fps; ga->height = ga->ani.animation->height; ga->width = ga->ani.animation->width; ga->buffer = ga->ani.instance->frame; ga->bitmap_id = bm_create(bpp, ga->width, ga->height, ga->buffer, (bpp==8)?BMP_AABITMAP:0); ga->ani.instance->last_bitmap = -1; ga->ani.instance->file_offset = ga->ani.animation->file_offset; ga->ani.instance->data = ga->ani.animation->data; ga->previous_frame = -1; } else if (ga->type == BM_TYPE_PNG) { if (ga->png.anim == nullptr) { try { ga->png.anim = new apng::apng_ani(ga->filename, cache); } catch (const apng::ApngException& e) { mprintf(("Failed to load apng: %s\n", e.what() )); delete ga->png.anim; ga->png.anim = nullptr; return -1; } nprintf(("apng", "apng read OK (%ix%i@%i) duration (%f)\n", ga->png.anim->w, ga->png.anim->h, ga->png.anim->bpp, ga->png.anim->anim_time)); } ga->png.anim->goto_start(); ga->current_frame = 0; ga->png.previous_frame_time = 0.0f; ga->num_frames = ga->png.anim->nframes; ga->height = ga->png.anim->h; ga->width = ga->png.anim->w; ga->previous_frame = -1; ga->buffer = ga->png.anim->frame.data.data(); ga->bitmap_id = bm_create(ga->png.anim->bpp, ga->width, ga->height, ga->buffer, 0); } else { bpp = 32; if(ga->use_hud_color) bpp = 8; bm_load_and_parse_eff(ga->filename, CF_TYPE_ANY, &ga->num_frames, &anim_fps, &ga->keyframe, 0); char *p = strrchr( ga->filename, '.' ); if ( p ) *p = 0; char frame_name[MAX_FILENAME_LEN]; snprintf(frame_name, MAX_FILENAME_LEN, "%s_0000", ga->filename); ga->bitmap_id = bm_load(frame_name); if(ga->bitmap_id < 0) { mprintf(("Cannot find first frame for eff streaming. eff Filename: %s", ga->filename)); return -1; } snprintf(frame_name, MAX_FILENAME_LEN, "%s_0001", ga->filename); ga->eff.next_frame = bm_load(frame_name); bm_get_info(ga->bitmap_id, &ga->width, &ga->height); ga->previous_frame = 0; } // keyframe info if (ga->type == BM_TYPE_ANI) { //we only care if there are 2 keyframes - first frame, other frame to jump to for ship/weapons //mainhall door anis hav every frame as keyframe, so we don't care //other anis only have the first frame if(ga->ani.animation->num_keys == 2) { int key1 = ga->ani.animation->keys[0].frame_num; int key2 = ga->ani.animation->keys[1].frame_num; if (key1 < 0 || key1 >= ga->num_frames) key1 = -1; if (key2 < 0 || key2 >= ga->num_frames) key2 = -1; // some retail anis have their keyframes reversed // and some have their keyframes out of bounds if (key1 >= 0 && key1 >= key2) { ga->keyframe = ga->ani.animation->keys[0].frame_num; ga->keyoffset = ga->ani.animation->keys[0].offset; } else if (key2 >= 0 && key2 >= key1) { ga->keyframe = ga->ani.animation->keys[1].frame_num; ga->keyoffset = ga->ani.animation->keys[1].offset; } } } ga->streaming = 1; if (ga->type == BM_TYPE_PNG) { ga->total_time = ga->png.anim->anim_time; } else { if (anim_fps == 0) { Error(LOCATION, "animation (%s) has invalid fps of zero, fix this!", ga->filename); } ga->total_time = ga->num_frames / (float) anim_fps; } ga->done_playing = 0; ga->anim_time = 0.0f; return 0; }
/** * @return -1 if couldn't init font, otherwise returns the font id number. */ int gr_create_font(char * typeface) { CFILE *fp; font *fnt; int n, fontnum; fnt = Fonts; n = -1; for (fontnum=0; fontnum<Num_fonts; fontnum++ ) { if (fnt->id != 0 ) { if ( !_strnicmp( fnt->filename, typeface, MAX_FILENAME_LEN ) ) { return fontnum; } } else { if ( n < 0 ) { n = fontnum; } } fnt++; } if ( fontnum == MAX_FONTS ) { Warning( LOCATION, "Too many fonts!\nSee John, or change MAX_FONTS in Graphics\\Font.h\n" ); return -1; } if ( fontnum == Num_fonts ) { Num_fonts++; } bool localize = true; fp = cfopen( typeface, "rb", CFILE_NORMAL, CF_TYPE_ANY, localize ); if ( fp == NULL ) return -1; strncpy( fnt->filename, typeface, MAX_FILENAME_LEN ); cfread( &fnt->id, 4, 1, fp ); cfread( &fnt->version, sizeof(int), 1, fp ); cfread( &fnt->num_chars, sizeof(int), 1, fp ); cfread( &fnt->first_ascii, sizeof(int), 1, fp ); cfread( &fnt->w, sizeof(int), 1, fp ); cfread( &fnt->h, sizeof(int), 1, fp ); cfread( &fnt->num_kern_pairs, sizeof(int), 1, fp ); cfread( &fnt->kern_data_size, sizeof(int), 1, fp ); cfread( &fnt->char_data_size, sizeof(int), 1, fp ); cfread( &fnt->pixel_data_size, sizeof(int), 1, fp ); fnt->id = INTEL_SHORT( fnt->id ); //-V570 fnt->version = INTEL_INT( fnt->version ); //-V570 fnt->num_chars = INTEL_INT( fnt->num_chars ); //-V570 fnt->first_ascii = INTEL_INT( fnt->first_ascii ); //-V570 fnt->w = INTEL_INT( fnt->w ); //-V570 fnt->h = INTEL_INT( fnt->h ); //-V570 fnt->num_kern_pairs = INTEL_INT( fnt->num_kern_pairs ); //-V570 fnt->kern_data_size = INTEL_INT( fnt->kern_data_size ); //-V570 fnt->char_data_size = INTEL_INT( fnt->char_data_size ); //-V570 fnt->pixel_data_size = INTEL_INT( fnt->pixel_data_size ); //-V570 if ( fnt->kern_data_size ) { fnt->kern_data = (font_kernpair *)vm_malloc( fnt->kern_data_size ); Assert(fnt->kern_data!=NULL); cfread( fnt->kern_data, fnt->kern_data_size, 1, fp ); } else { fnt->kern_data = NULL; } if ( fnt->char_data_size ) { fnt->char_data = (font_char *)vm_malloc( fnt->char_data_size ); Assert( fnt->char_data != NULL ); cfread( fnt->char_data, fnt->char_data_size, 1, fp ); for (int i=0; i<fnt->num_chars; i++) { fnt->char_data[i].spacing = INTEL_INT( fnt->char_data[i].spacing ); //-V570 fnt->char_data[i].byte_width = INTEL_INT( fnt->char_data[i].byte_width ); //-V570 fnt->char_data[i].offset = INTEL_INT( fnt->char_data[i].offset ); //-V570 fnt->char_data[i].kerning_entry = INTEL_INT( fnt->char_data[i].kerning_entry ); //-V570 fnt->char_data[i].user_data = INTEL_SHORT( fnt->char_data[i].user_data ); //-V570 } } else { fnt->char_data = NULL; } if ( fnt->pixel_data_size ) { fnt->pixel_data = (ubyte *)vm_malloc( fnt->pixel_data_size ); Assert(fnt->pixel_data!=NULL); cfread( fnt->pixel_data, fnt->pixel_data_size, 1, fp ); } else { fnt->pixel_data = NULL; } cfclose(fp); // Create a bitmap for hardware cards. // JAS: Try to squeeze this into the smallest square power of two texture. // This should probably be done at font generation time, not here. int w, h; if ( fnt->pixel_data_size*4 < 64*64 ) { w = h = 64; } else if ( fnt->pixel_data_size*4 < 128*128 ) { w = h = 128; } else if ( fnt->pixel_data_size*4 < 256*256 ) { w = h = 256; } else if ( fnt->pixel_data_size*4 < 512*512 ) { w = h = 512; } else { w = h = 1024; } fnt->bm_w = w; fnt->bm_h = h; fnt->bm_data = (ubyte *)vm_malloc(fnt->bm_w*fnt->bm_h); fnt->bm_u = (int *)vm_malloc(sizeof(int)*fnt->num_chars); fnt->bm_v = (int *)vm_malloc(sizeof(int)*fnt->num_chars); memset( fnt->bm_data, 0, fnt->bm_w * fnt->bm_h ); int i,x,y; x = y = 0; for (i=0; i<fnt->num_chars; i++ ) { ubyte * ubp; int x1, y1; ubp = &fnt->pixel_data[fnt->char_data[i].offset]; if ( x + fnt->char_data[i].byte_width >= fnt->bm_w ) { x = 0; y += fnt->h + 2; if ( y+fnt->h > fnt->bm_h ) { Error( LOCATION, "Font too big!\n" ); } } fnt->bm_u[i] = x; fnt->bm_v[i] = y; for( y1=0; y1<fnt->h; y1++ ) { for (x1=0; x1<fnt->char_data[i].byte_width; x1++ ) { uint c = *ubp++; if ( c > 14 ) c = 14; fnt->bm_data[(x+x1)+(y+y1)*fnt->bm_w] = (unsigned char)(c); } } x += fnt->char_data[i].byte_width + 2; } fnt->bitmap_id = bm_create( 8, fnt->bm_w, fnt->bm_h, fnt->bm_data, BMP_AABITMAP ); return fontnum; }