Skip to content

Commit 1253575

Browse files
committed
Merge pull request #540 from asarium/bmpman/loading
Move texture loading out of graphics code
2 parents be67793 + a1d4647 commit 1253575

File tree

9 files changed

+234
-777
lines changed

9 files changed

+234
-777
lines changed

code/bmpman/bmpman.cpp

Lines changed: 218 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,110 @@ int bm_is_valid(int handle) {
913913
return (bm_bitmaps[handle % MAX_BITMAPS].handle == handle);
914914
}
915915

916+
917+
// Load an image and validate it while retrieving information for later use
918+
// Input: type = current BM_TYPE_*
919+
// n = location in bm_bitmaps[]
920+
// filename = name of the current file
921+
// img_cfp = already open CFILE handle, if available
922+
//
923+
// Output: w = bmp width
924+
// h = bmp height
925+
// bpp = bmp bits per pixel
926+
// c_type = output for an updated BM_TYPE_*
927+
// mm_lvl = number of mipmap levels for the image
928+
// size = size of the data contained in the image
929+
static int bm_load_info(BM_TYPE type, int n, const char *filename, CFILE *img_cfp, int *w, int *h, int *bpp, BM_TYPE *c_type, int *mm_lvl, int *size)
930+
{
931+
int dds_ct;
932+
933+
if (type == BM_TYPE_DDS) {
934+
int dds_error = dds_read_header(filename, img_cfp, w, h, bpp, &dds_ct, mm_lvl, size);
935+
936+
if (dds_error != DDS_ERROR_NONE) {
937+
mprintf(("DDS ERROR: Couldn't open '%s' -- %s\n", filename, dds_error_string(dds_error)));
938+
return -1;
939+
}
940+
941+
switch (dds_ct) {
942+
case DDS_DXT1:
943+
*c_type = BM_TYPE_DXT1;
944+
break;
945+
946+
case DDS_DXT3:
947+
*c_type = BM_TYPE_DXT3;
948+
break;
949+
950+
case DDS_DXT5:
951+
*c_type = BM_TYPE_DXT5;
952+
break;
953+
954+
case DDS_UNCOMPRESSED:
955+
*c_type = BM_TYPE_DDS;
956+
break;
957+
958+
case DDS_CUBEMAP_DXT1:
959+
*c_type = BM_TYPE_CUBEMAP_DXT1;
960+
break;
961+
962+
case DDS_CUBEMAP_DXT3:
963+
*c_type = BM_TYPE_CUBEMAP_DXT3;
964+
break;
965+
966+
case DDS_CUBEMAP_DXT5:
967+
*c_type = BM_TYPE_CUBEMAP_DXT5;
968+
break;
969+
970+
case DDS_CUBEMAP_UNCOMPRESSED:
971+
*c_type = BM_TYPE_CUBEMAP_DDS;
972+
break;
973+
974+
default:
975+
Error(LOCATION, "Bad DDS file compression! Not using DXT1,3,5: %s", filename);
976+
return -1;
977+
}
978+
}
979+
// if its a tga file
980+
else if (type == BM_TYPE_TGA) {
981+
int tga_error = targa_read_header(filename, img_cfp, w, h, bpp, NULL);
982+
if (tga_error != TARGA_ERROR_NONE) {
983+
mprintf(("tga: Couldn't open '%s'\n", filename));
984+
return -1;
985+
}
986+
}
987+
// if its a png file
988+
else if (type == BM_TYPE_PNG) {
989+
int png_error = png_read_header(filename, img_cfp, w, h, bpp, NULL);
990+
if (png_error != PNG_ERROR_NONE) {
991+
mprintf(("png: Couldn't open '%s'\n", filename));
992+
return -1;
993+
}
994+
}
995+
// if its a jpg file
996+
else if (type == BM_TYPE_JPG) {
997+
int jpg_error = jpeg_read_header(filename, img_cfp, w, h, bpp, NULL);
998+
if (jpg_error != JPEG_ERROR_NONE) {
999+
mprintf(("jpg: Couldn't open '%s'\n", filename));
1000+
return -1;
1001+
}
1002+
}
1003+
// if its a pcx file
1004+
else if (type == BM_TYPE_PCX) {
1005+
int pcx_error = pcx_read_header(filename, img_cfp, w, h, bpp, NULL);
1006+
if (pcx_error != PCX_ERROR_NONE) {
1007+
mprintf(("pcx: Couldn't open '%s'\n", filename));
1008+
return -1;
1009+
}
1010+
}
1011+
else {
1012+
Assertion(false, "Unknown file type specified! This is probably a coding error.");
1013+
1014+
return -1;
1015+
}
1016+
1017+
return 0;
1018+
}
1019+
9161020
int bm_load(const char *real_filename) {
9171021
int i, free_slot = -1;
9181022
int w, h, bpp = 8;
@@ -985,7 +1089,7 @@ int bm_load(const char *real_filename) {
9851089
goto Done;
9861090
}
9871091

988-
rc = gr_bm_load(type, free_slot, filename, img_cfp, &w, &h, &bpp, &c_type, &mm_lvl, &bm_size);
1092+
rc = bm_load_info(type, free_slot, filename, img_cfp, &w, &h, &bpp, &c_type, &mm_lvl, &bm_size);
9891093

9901094
if (rc != 0)
9911095
goto Done;
@@ -1111,6 +1215,109 @@ bool bm_load_and_parse_eff(const char *filename, int dir_type, int *nframes, int
11111215
return true;
11121216
}
11131217

1218+
1219+
/**
1220+
* Lock an image files data into memory
1221+
*/
1222+
static int bm_load_image_data(const char *filename, int handle, int bitmapnum, ubyte bpp, ubyte flags, bool nodebug)
1223+
{
1224+
BM_TYPE c_type = BM_TYPE_NONE;
1225+
ubyte true_bpp;
1226+
1227+
bitmap_entry *be = &bm_bitmaps[bitmapnum];
1228+
bitmap *bmp = &be->bm;
1229+
1230+
Assert(!Is_standalone);
1231+
1232+
if (bmp->true_bpp > bpp)
1233+
true_bpp = bmp->true_bpp;
1234+
else
1235+
true_bpp = bpp;
1236+
1237+
// don't do a bpp check here since it could be different in OGL - taylor
1238+
if (bmp->data == 0) {
1239+
Assert(be->ref_count == 1);
1240+
1241+
if (be->type != BM_TYPE_USER && !nodebug) {
1242+
if (bmp->data == 0)
1243+
nprintf(("BmpMan", "Loading %s for the first time.\n", be->filename));
1244+
}
1245+
1246+
if (!Bm_paging) {
1247+
if (be->type != BM_TYPE_USER && !nodebug)
1248+
nprintf(("Paging", "Loading %s (%dx%dx%d)\n", be->filename, bmp->w, bmp->h, true_bpp));
1249+
}
1250+
1251+
// select proper format
1252+
if (flags & BMP_AABITMAP)
1253+
BM_SELECT_ALPHA_TEX_FORMAT();
1254+
else if (flags & BMP_TEX_ANY)
1255+
BM_SELECT_TEX_FORMAT();
1256+
else
1257+
BM_SELECT_SCREEN_FORMAT();
1258+
1259+
// make sure we use the real graphic type for EFFs
1260+
if (be->type == BM_TYPE_EFF) {
1261+
c_type = be->info.ani.eff.type;
1262+
}
1263+
else {
1264+
c_type = be->type;
1265+
}
1266+
1267+
switch (c_type)
1268+
{
1269+
case BM_TYPE_PCX:
1270+
bm_lock_pcx(handle, bitmapnum, be, bmp, true_bpp, flags);
1271+
break;
1272+
1273+
case BM_TYPE_ANI:
1274+
bm_lock_ani(handle, bitmapnum, be, bmp, true_bpp, flags);
1275+
break;
1276+
1277+
case BM_TYPE_TGA:
1278+
bm_lock_tga(handle, bitmapnum, be, bmp, true_bpp, flags);
1279+
break;
1280+
1281+
case BM_TYPE_PNG:
1282+
//libpng handles compression with zlib
1283+
bm_lock_png(handle, bitmapnum, be, bmp, true_bpp, flags);
1284+
break;
1285+
1286+
case BM_TYPE_JPG:
1287+
bm_lock_jpg(handle, bitmapnum, be, bmp, true_bpp, flags);
1288+
break;
1289+
1290+
case BM_TYPE_DDS:
1291+
case BM_TYPE_DXT1:
1292+
case BM_TYPE_DXT3:
1293+
case BM_TYPE_DXT5:
1294+
case BM_TYPE_CUBEMAP_DDS:
1295+
case BM_TYPE_CUBEMAP_DXT1:
1296+
case BM_TYPE_CUBEMAP_DXT3:
1297+
case BM_TYPE_CUBEMAP_DXT5:
1298+
bm_lock_dds(handle, bitmapnum, be, bmp, true_bpp, flags);
1299+
break;
1300+
1301+
case BM_TYPE_USER:
1302+
bm_lock_user(handle, bitmapnum, be, bmp, true_bpp, flags);
1303+
break;
1304+
1305+
default:
1306+
Warning(LOCATION, "Unsupported type in bm_lock -- %d\n", c_type);
1307+
return -1;
1308+
}
1309+
1310+
// always go back to screen format
1311+
BM_SELECT_SCREEN_FORMAT();
1312+
1313+
// make sure we actually did something
1314+
if (!(bmp->data))
1315+
return -1;
1316+
}
1317+
1318+
return 0;
1319+
}
1320+
11141321
int bm_load_animation(const char *real_filename, int *nframes, int *fps, int *keyframe, int can_drop_frames, int dir_type) {
11151322
int i, n;
11161323
anim the_anim;
@@ -1279,7 +1486,7 @@ int bm_load_animation(const char *real_filename, int *nframes, int *fps, int *ke
12791486
sprintf(bm_bitmaps[n + i].info.ani.eff.filename, "%s_%.4d", clean_name, i);
12801487

12811488
// gr_bm_load() returns non-0 on failure
1282-
if (gr_bm_load(eff_type, n + i, bm_bitmaps[n + i].info.ani.eff.filename, NULL, &anim_width, &anim_height, &bpp, &c_type, &mm_lvl, &img_size)) {
1489+
if (bm_load_info(eff_type, n + i, bm_bitmaps[n + i].info.ani.eff.filename, NULL, &anim_width, &anim_height, &bpp, &c_type, &mm_lvl, &img_size)) {
12831490
// if we didn't get anything then bail out now
12841491
if (i == 0) {
12851492
Warning(LOCATION, "EFF: No frame images were found. EFF, %s, is invalid.\n", filename);
@@ -1504,13 +1711,21 @@ bitmap * bm_lock(int handle, ubyte bpp, ubyte flags, bool nodebug) {
15041711
#endif
15051712

15061713
// read the file data
1507-
if (gr_bm_lock(be->filename, handle, bitmapnum, bpp, flags, nodebug) == -1) {
1714+
if (bm_load_image_data(be->filename, handle, bitmapnum, bpp, flags, nodebug) == -1) {
15081715
// oops, this isn't good - reset and return NULL
15091716
bm_unlock( handle );
15101717
bm_unload( handle );
15111718

15121719
return NULL;
15131720
}
1721+
1722+
if (!gr_bm_data(bitmapnum, bmp)) {
1723+
// graphics subsystem failed, reset and return NULL
1724+
bm_unlock( handle );
1725+
bm_unload( handle );
1726+
1727+
return NULL;
1728+
}
15141729

15151730
MONITOR_INC(NumBitmapPage, 1);
15161731
MONITOR_INC(SizeBitmapPage, bmp->w*bmp->h);

code/cmdline/cmdline.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,6 @@ Flag exe_params[] =
146146
{ "-fb_explosions", "Enable Framebuffer Shockwaves", true, EASY_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-fb_explosions", },
147147
{ "-no_deferred", "Disable Deferred Lighting", true, EASY_DEFAULT_MEM, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_deferred"},
148148
{ "-enable_shadows", "Enable Shadows", true, EASY_MEM_ALL_ON, EASY_DEFAULT, "Graphics", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_shadows"},
149-
{ "-img2dds", "Compress non-compressed images", true, 0, EASY_DEFAULT, "Game Speed", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-img2dds", },
150149
{ "-no_vsync", "Disable vertical sync", true, 0, EASY_DEFAULT, "Game Speed", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-no_vsync", },
151150
{ "-cache_bitmaps", "Cache bitmaps between missions", true, 0, EASY_DEFAULT_MEM, "Game Speed", "http://www.hard-light.net/wiki/index.php/Command-Line_Reference#-cache_bitmaps", },
152151

@@ -345,12 +344,10 @@ int Cmdline_no_deferred_lighting = 0;
345344

346345
// Game Speed related
347346
cmdline_parm cache_bitmaps_arg("-cache_bitmaps", NULL, AT_NONE); // Cmdline_cache_bitmaps
348-
cmdline_parm img2dds_arg("-img2dds", NULL, AT_NONE); // Cmdline_img2dds
349347
cmdline_parm no_fpscap("-no_fps_capping", "Don't limit frames-per-second", AT_NONE); // Cmdline_NoFPSCap
350348
cmdline_parm no_vsync_arg("-no_vsync", NULL, AT_NONE); // Cmdline_no_vsync
351349

352350
int Cmdline_cache_bitmaps = 0; // caching of bitmaps between missions (faster loads, can hit swap on reload with <512 Meg RAM though) - taylor
353-
int Cmdline_img2dds = 0;
354351
int Cmdline_NoFPSCap = 0; // Disable FPS capping - kazan
355352
int Cmdline_no_vsync = 0;
356353

@@ -1554,9 +1551,6 @@ bool SetCmdlineParams()
15541551
Cmdline_no_di_mouse = 1;
15551552
}
15561553

1557-
if ( img2dds_arg.found() )
1558-
Cmdline_img2dds = 1;
1559-
15601554
if ( glow_arg.found() )
15611555
Cmdline_glow = 0;
15621556

code/cmdline/cmdline.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ extern int Cmdline_no_deferred_lighting;
8383

8484
// Game Speed related
8585
extern int Cmdline_cache_bitmaps;
86-
extern int Cmdline_img2dds;
8786
extern int Cmdline_NoFPSCap;
8887
extern int Cmdline_no_vsync;
8988

code/graphics/2d.h

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -557,10 +557,9 @@ typedef struct screen {
557557
// Here be the bitmap functions
558558
void (*gf_bm_free_data)(int n, bool release);
559559
void (*gf_bm_create)(int n);
560-
int(*gf_bm_load)(BM_TYPE type, int n, const char *filename, CFILE *img_cfp, int *w, int *h, int *bpp, BM_TYPE *c_type, int *mm_lvl, int *size);
561560
void (*gf_bm_init)(int n);
562561
void (*gf_bm_page_in_start)();
563-
int (*gf_bm_lock)(const char *filename, int handle, int bitmapnum, ubyte bpp, ubyte flags, bool nodebug);
562+
bool (*gf_bm_data)(int n, bitmap* bm);
564563

565564
int (*gf_bm_make_render_target)(int n, int *width, int *height, ubyte *bpp, int *mm_lvl, int flags );
566565
int (*gf_bm_set_render_target)(int n, int face);
@@ -891,12 +890,8 @@ __inline int gr_tcache_set(int bitmap_id, int bitmap_type, float *u_scale, float
891890
#define gr_bm_free_data GR_CALL(*gr_screen.gf_bm_free_data)
892891
#define gr_bm_create GR_CALL(*gr_screen.gf_bm_create)
893892
#define gr_bm_init GR_CALL(*gr_screen.gf_bm_init)
894-
__inline int gr_bm_load(BM_TYPE type, int n, const char *filename, CFILE *img_cfp = NULL, int *w = 0, int *h = 0, int *bpp = 0, BM_TYPE *c_type = 0, int *mm_lvl = 0, int *size = 0)
895-
{
896-
return (*gr_screen.gf_bm_load)(type, n, filename, img_cfp, w, h, bpp, c_type, mm_lvl, size);
897-
}
898893
#define gr_bm_page_in_start GR_CALL(*gr_screen.gf_bm_page_in_start)
899-
#define gr_bm_lock GR_CALL(*gr_screen.gf_bm_lock)
894+
#define gr_bm_data GR_CALL(*gr_screen.gf_bm_data)
900895

901896
#define gr_bm_make_render_target GR_CALL(*gr_screen.gf_bm_make_render_target)
902897

code/graphics/gropengl.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1831,9 +1831,8 @@ void opengl_setup_function_pointers()
18311831
gr_screen.gf_bm_free_data = gr_opengl_bm_free_data;
18321832
gr_screen.gf_bm_create = gr_opengl_bm_create;
18331833
gr_screen.gf_bm_init = gr_opengl_bm_init;
1834-
gr_screen.gf_bm_load = gr_opengl_bm_load;
18351834
gr_screen.gf_bm_page_in_start = gr_opengl_bm_page_in_start;
1836-
gr_screen.gf_bm_lock = gr_opengl_bm_lock;
1835+
gr_screen.gf_bm_data = gr_opengl_bm_data;
18371836
gr_screen.gf_bm_make_render_target = gr_opengl_bm_make_render_target;
18381837
gr_screen.gf_bm_set_render_target = gr_opengl_bm_set_render_target;
18391838

0 commit comments

Comments
 (0)