/** * Searches levels folder for LOF files and adds them to campaign levels list. */ TbBool find_and_load_lof_files(void) { struct TbFileFind fileinfo; unsigned char *buf; char *fname; short result; int rc; long i; SYNCDBG(16,"Starting"); buf = LbMemoryAlloc(MAX_LIF_SIZE); if (buf == NULL) { ERRORLOG("Can't allocate memory for .LOF files parsing."); return false; } result = false; fname = prepare_file_path(FGrp_VarLevels,"*.lof"); rc = LbFileFindFirst(fname, &fileinfo, 0x21u); while (rc != -1) { fname = prepare_file_path(FGrp_VarLevels,fileinfo.Filename); i = LbFileLength(fname); if ((i < 0) || (i >= MAX_LIF_SIZE)) { WARNMSG("File '%s' too long (Max size %d)", fileinfo.Filename, MAX_LIF_SIZE); } else if (LbFileLoadAt(fname, buf) != i) { WARNMSG("Unable to read .LOF file, '%s'", fileinfo.Filename); } else { buf[i] = '\0'; if (level_lof_file_parse(fileinfo.Filename, (char *)buf, i)) result = true; } rc = LbFileFindNext(&fileinfo); } LbFileFindEnd(&fileinfo); LbMemoryFree(buf); return result; }
TbBool load_map_data_file(LevelNumber lv_num) { struct Map *mapblk; unsigned long x,y; unsigned char *buf; unsigned long i; unsigned long n; unsigned short *wptr; long fsize; clear_map(); fsize = 2*(map_subtiles_y+1)*(map_subtiles_x+1); buf = load_single_map_file_to_buffer(lv_num,"dat",&fsize,LMFF_None); if (buf == NULL) return false; i = 0; for (y=0; y < (map_subtiles_y+1); y++) { for (x=0; x < (map_subtiles_x+1); x++) { mapblk = get_map_block_at(x,y); n = -lword(&buf[i]); mapblk->data ^= (mapblk->data ^ n) & 0x7FF; i += 2; } } LbMemoryFree(buf); // Clear some bits and do some other setup for (y=0; y < (map_subtiles_y+1); y++) { for (x=0; x < (map_subtiles_x+1); x++) { mapblk = get_map_block_at(x,y); wptr = &game.lish.subtile_lightness[get_subtile_number(x,y)]; *wptr = 32; mapblk->data &= 0xFFC007FFu; mapblk->data &= ~0x0F000000; mapblk->data &= ~0xF0000000; } } return true; }
TbBool load_action_point_file(LevelNumber lv_num) { struct InitActionPoint iapt; unsigned long i; long k; long total; unsigned char *buf; long fsize; SYNCDBG(5,"Starting"); fsize = 4; buf = load_single_map_file_to_buffer(lv_num,"apt",&fsize,LMFF_None); if (buf == NULL) return false; i = 0; total = llong(&buf[i]); i += 4; // Validate total amount of action points if ((total < 0) || (total > (fsize-4)/sizeof(struct InitActionPoint))) { total = (fsize-4)/sizeof(struct InitActionPoint); WARNMSG("Bad amount of action points in APT file; corrected to %ld.",total); } if (total > ACTN_POINTS_COUNT-1) { WARNMSG("Only %d action points supported, APT file has %ld.",ACTN_POINTS_COUNT-1,total); total = ACTN_POINTS_COUNT-1; } // Create action points for (k=0; k < total; k++) { LbMemoryCopy(&iapt, &buf[i], sizeof(struct InitActionPoint)); if (actnpoint_create_actnpoint(&iapt) == INVALID_ACTION_POINT) { ERRORLOG("Cannot allocate action point %d during APT load",k); } i += sizeof(struct InitActionPoint); } LbMemoryFree(buf); return true; }
TbBool load_map_wlb_file(unsigned long lv_num) { struct SlabMap *slb; unsigned long x,y; unsigned char *buf; unsigned long i; unsigned long n; unsigned long nfixes; long fsize; SYNCDBG(7,"Starting"); nfixes = 0; fsize = map_tiles_y*map_tiles_x; buf = load_single_map_file_to_buffer(lv_num,"wlb",&fsize,LMFF_Optional); if (buf == NULL) return false; i = 0; for (y=0; y < map_tiles_y; y++) for (x=0; x < map_tiles_x; x++) { slb = get_slabmap_block(x,y); n = (buf[i] << 3); n = slb->field_5 ^ ((slb->field_5 ^ n) & 0x18); slb->field_5 = n; n &= (0x08|0x10); if ((n != 0x10) || (slb->kind != SlbT_WATER)) if ((n != 0x08) || (slb->kind != SlbT_LAVA)) if (((n == 0x10) || (n == 0x08)) && (slb->kind != SlbT_BRIDGE)) { nfixes++; slb->field_5 &= ~(0x08|0x10); } i++; } LbMemoryFree(buf); if (nfixes > 0) { ERRORLOG("WLB file is muddled - Fixed values for %lu tiles",nfixes); } return true; }
/** * Loads MCGA graphics files, for low resolution mode. * It is modified version of LbDataLoadAll, optimized for maximum * game speed on very slow machines. * @return Returns true if all files were loaded, false otherwise. */ short LoadMcgaData(void) { struct TbLoadFiles *load_files; void *mem; struct TbLoadFiles *t_lfile; int ferror; int ret_val; int i; load_files = mcga_load_files; LbDataFreeAll(load_files); ferror = 0; i = 0; t_lfile = &load_files[i]; // Allocate some low memory, only to be sure that // it will be free when this function ends mem = LbMemoryAllocLow(0x10000u); while (t_lfile->Start != NULL) { // Don't allow loading flags t_lfile->Flags = 0; ret_val = LbDataLoad(t_lfile); if (ret_val == -100) { ERRORLOG("Can't allocate memory for MCGA files element \"%s\".", t_lfile->FName); ferror++; } else if ( ret_val == -101 ) { ERRORLOG("Can't load MCGA file \"%s\".", t_lfile->FName); ferror++; } i++; t_lfile = &load_files[i]; } if (mem != NULL) LbMemoryFree(mem); return (ferror == 0); }
long load_map_wibble_file(unsigned long lv_num) { struct Map *mapblk; unsigned long stl_x,stl_y; unsigned char *buf; unsigned long i,k; long fsize; fsize = (map_subtiles_y+1)*(map_subtiles_x+1); buf = load_single_map_file_to_buffer(lv_num,"wib",&fsize,LMFF_None); if (buf == NULL) return false; i = 0; for (stl_y=0; stl_y < (map_subtiles_y+1); stl_y++) for (stl_x=0; stl_x < (map_subtiles_x+1); stl_x++) { mapblk = get_map_block_at(stl_x,stl_y); k = buf[i]; set_mapblk_wibble_value(mapblk, k); i++; } LbMemoryFree(buf); return true; }
TbBool load_thing_file(LevelNumber lv_num) { struct InitThing itng; unsigned long i; long k; long total; unsigned char *buf; long fsize; SYNCDBG(5,"Starting"); fsize = 2; buf = load_single_map_file_to_buffer(lv_num,"tng",&fsize,LMFF_None); if (buf == NULL) return false; i = 0; total = lword(&buf[i]); i += 2; // Validate total amount of things if ((total < 0) || (total > (fsize-2)/sizeof(struct InitThing))) { total = (fsize-2)/sizeof(struct InitThing); WARNMSG("Bad amount of things in TNG file; corrected to %d.",(int)total); } if (total > THINGS_COUNT-2) { WARNMSG("Only %d things supported, TNG file has %d.",(int)(THINGS_COUNT-2),(int)total); total = THINGS_COUNT-2; } // Create things for (k=0; k < total; k++) { LbMemoryCopy(&itng, &buf[i], sizeof(struct InitThing)); thing_create_thing(&itng); i += sizeof(struct InitThing); } LbMemoryFree(buf); return true; }
long prepare_hsi_screenshot(unsigned char *buf,unsigned char *palette) { long pos,i; int w,h; short lock_mem; pos=0; w=MyScreenWidth/pixel_size; h=MyScreenHeight/pixel_size; write_int8_buf(buf+pos,'m'); pos++; write_int8_buf(buf+pos,'h'); pos++; write_int8_buf(buf+pos,'w'); pos++; write_int8_buf(buf+pos,'a'); pos++; write_int8_buf(buf+pos,'n'); pos++; write_int8_buf(buf+pos,'h'); pos++; // pos=6 write_int16_be_buf(buf+pos, 4); pos+=2; write_int16_be_buf(buf+pos, w); pos+=2; write_int16_be_buf(buf+pos, h); pos+=2; write_int16_be_buf(buf+pos, 256); pos+=2; // pos=14 write_int16_be_buf(buf+pos, 256); pos+=2; write_int16_be_buf(buf+pos, 256); pos+=2; write_int16_be_buf(buf+pos, 256); pos+=2; // pos=20 for (i=0; i<6; i++) { write_int16_be_buf(buf+pos, 0); pos+=2; } for (i=0; i<768; i+=3) { write_int8_buf(buf+pos,4*palette[i+0]); pos++; write_int8_buf(buf+pos,4*palette[i+1]); pos++; write_int8_buf(buf+pos,4*palette[i+2]); pos++; } lock_mem = LbScreenIsLocked(); if (!lock_mem) { if (LbScreenLock() != Lb_SUCCESS) { ERRORLOG("Can't lock canvas"); LbMemoryFree(buf); return 0; } } for (i=0; i<h; i++) { memcpy(buf+pos, lbDisplay.WScreen + lbDisplay.GraphicsScreenWidth*i, w); pos += w; } if (!lock_mem) LbScreenUnlock(); return pos; }
TbBool cumulative_screen_shot(void) { //_DK_cumulative_screen_shot();return; static long frame_number=0; char fname[255]; const char *fext; int w,h; switch (screenshot_format) { case 1: fext="raw"; break; case 2: fext="bmp"; break; default: ERRORLOG("Screenshot format incorrectly set."); return false; } long i; unsigned char *buf; long ssize; for (i=frame_number; i<10000; i++) { sprintf(fname, "scrshots/scr%05ld.%s", i, fext); if (!LbFileExists(fname)) break; } frame_number = i; if (frame_number >= 10000) { show_onscreen_msg(game.num_fps, "No free filename for screenshot."); return false; } sprintf(fname, "scrshots/scr%05ld.%s", frame_number, fext); w=MyScreenWidth/pixel_size; h=MyScreenHeight/pixel_size; buf = LbMemoryAlloc((w+3)*h+2048); if (buf == NULL) { ERRORLOG("Can't allocate buffer"); return false; } LbPaletteGet(cap_palette); switch (screenshot_format) { case 1: ssize=prepare_hsi_screenshot(buf,cap_palette); break; case 2: ssize=prepare_bmp_screenshot(buf,cap_palette); break; default: ssize=0; break; } if (ssize>0) ssize = LbFileSaveAt(fname, buf, ssize); LbMemoryFree(buf); if (ssize>0) show_onscreen_msg(game.num_fps, "File \"%s\" saved.", fname); else show_onscreen_msg(game.num_fps, "Cannot save \"%s\".", fname); frame_number++; return (ssize>0); }
long prepare_bmp_screenshot(unsigned char *buf,unsigned char *palette) { long pos,i,j; int width,height; short lock_mem; long data_len,pal_len; pos=0; width=MyScreenWidth/pixel_size; height=MyScreenHeight/pixel_size; write_int8_buf(buf+pos,'B'); pos++; write_int8_buf(buf+pos,'M'); pos++; int padding_size=4-(width&3); data_len = (width+padding_size)*height; pal_len = 256*4; write_int32_le_buf(buf+pos, data_len+pal_len+0x36); pos+=4; write_int32_le_buf(buf+pos, 0); pos+=4; write_int32_le_buf(buf+pos, pal_len+0x36); pos+=4; write_int32_le_buf(buf+pos, 40); pos+=4; write_int32_le_buf(buf+pos, width); pos+=4; write_int32_le_buf(buf+pos, height); pos+=4; write_int16_le_buf(buf+pos, 1); pos+=2; write_int16_le_buf(buf+pos, 8); pos+=2; write_int32_le_buf(buf+pos, 0); pos+=4; write_int32_le_buf(buf+pos, 0); pos+=4; write_int32_le_buf(buf+pos, 0); pos+=4; write_int32_le_buf(buf+pos, 0); pos+=4; write_int32_le_buf(buf+pos, 0); pos+=4; write_int32_le_buf(buf+pos, 0); pos+=4; for (i=0; i<768; i+=3) { unsigned int cval; cval=4*(unsigned int)palette[i+2]; if (cval>255) cval=255; write_int8_buf(buf+pos,cval); pos++; cval=4*(unsigned int)palette[i+1]; if (cval>255) cval=255; write_int8_buf(buf+pos,cval); pos++; cval=4*(unsigned int)palette[i+0]; if (cval>255) cval=255; write_int8_buf(buf+pos,cval); pos++; write_int8_buf(buf+pos,0); pos++; } lock_mem = LbScreenIsLocked(); if (!lock_mem) { if (LbScreenLock() != Lb_SUCCESS) { ERRORLOG("Can't lock canvas"); LbMemoryFree(buf); return 0; } } for (i=0; i<height; i++) { memcpy(buf+pos, lbDisplay.WScreen + lbDisplay.GraphicsScreenWidth*(height-i-1), width); pos += width; if ((padding_size&3) > 0) for (j=0; j < padding_size; j++) { write_int8_buf(buf+pos,0); pos++; } } if (!lock_mem) LbScreenUnlock(); return pos; }
TbBool setup_heaps(void) { TbBool low_memory; char snd_fname[2048]; char *spc_fname; long i; SYNCDBG(8,"Starting"); low_memory = false; if (!SoundDisabled) { StopAllSamples(); close_sound_heap(); if (sound_heap_memory != NULL) { LbMemoryFree(sound_heap_memory); sound_heap_memory = NULL; } } if (heap != NULL) { ERRORLOG("Graphics heap already allocated"); LbMemoryFree(heap); heap = NULL; } // Allocate sound heap if (!SoundDisabled) { i = mem_size; while (sound_heap_memory == NULL) { sound_heap_size = get_best_sound_heap_size(i); i = get_smaller_memory_amount(i); sound_heap_memory = LbMemoryAlloc(sound_heap_size); if ((i <= 8) && (sound_heap_memory == NULL)) { low_memory = true; break; } } } // Allocate graphics heap i = mem_size; while (heap == NULL) { heap_size = get_best_sound_heap_size(i); i = get_smaller_memory_amount(i); heap = LbMemoryAlloc(heap_size); if ((i <= 8) && (heap == NULL)) { low_memory = true; break; } } SYNCMSG("GraphicsHeap Size %d", heap_size); if (low_memory) { SYNCDBG(8,"Low memory mode entered on heap allocation."); while (heap != NULL) { if ((!SoundDisabled) && (sound_heap_memory == NULL)) { break; } if (!SoundDisabled) { if (sound_heap_size < heap_size) { heap_size -= 16384; } else if (sound_heap_size == heap_size) { heap_size -= 16384; sound_heap_size -= 16384; } else { sound_heap_size -= 16384; } if (sound_heap_size < 524288) { ERRORLOG("Unable to allocate heaps (small_mem)"); return false; } } else { heap_size -= 16384; } if (heap_size < 524288) { if (sound_heap_memory != NULL) { LbMemoryFree(sound_heap_memory); sound_heap_memory = NULL; } ERRORLOG("Unable to allocate heaps (small_mem)"); return false; } } if (sound_heap_memory != NULL) { LbMemoryFree(sound_heap_memory); sound_heap_memory = NULL; } if (heap != NULL) { LbMemoryFree(heap); heap = NULL; } if (!SoundDisabled) { sound_heap_memory = LbMemoryAlloc(sound_heap_size); } heap = LbMemoryAlloc(heap_size); } if (!SoundDisabled) { SYNCMSG("SoundHeap Size %d", sound_heap_size); // Prepare sound sample bank file names prepare_file_path_buf(snd_fname,FGrp_LrgSound,sound_fname); // language-specific speech file spc_fname = prepare_file_fmtpath(FGrp_LrgSound,"speech_%s.dat",get_language_lwrstr(install_info.lang_id)); // default speech file if (!LbFileExists(spc_fname)) spc_fname = prepare_file_path(FGrp_LrgSound,speech_fname); // speech file for english if (!LbFileExists(spc_fname)) spc_fname = prepare_file_fmtpath(FGrp_LrgSound,"speech_%s.dat",get_language_lwrstr(1)); // Initialize sample banks if (!init_sound_heap_two_banks(sound_heap_memory, sound_heap_size, snd_fname, spc_fname, 1622)) { LbMemoryFree(sound_heap_memory); sound_heap_memory = NULL; SoundDisabled = true; ERRORLOG("Unable to initialize sound heap. Sound disabled."); } } return true; }
void reset_heap_memory(void) { SYNCDBG(8,"Starting"); LbMemoryFree(heap); heap = NULL; }
/** * Loads binary config of cubes. * @deprecated Replaced by text config - remove pending. */ long load_cube_file(void) { char *buf; long len; TbBool result; char *fname; static const char textname[] = "binary cubes config"; fname = prepare_file_path(FGrp_StdData,"cube.dat"); SYNCDBG(0,"%s %s file \"%s\".","Reading",textname,fname); //return _DK_load_cube_file(); clear_cubes(); len = LbFileLengthRnc(fname); if (len < MIN_CONFIG_FILE_SIZE) { WARNMSG("The %s file \"%s\" doesn't exist or is too small.",textname,fname); return false; } if (len > MAX_CONFIG_FILE_SIZE) { WARNMSG("The %s file \"%s\" is too large.",textname,fname); return false; } buf = (char *)LbMemoryAlloc(len+256); if (buf == NULL) return false; // Loading file data len = LbFileLoadAt(fname, buf); result = (len > 0); // Parse the config file if (result) { long i,count; count = *(long *)&buf[0]; if (count > len/sizeof(struct CubeAttribs)) { count = len/sizeof(struct CubeAttribs); WARNMSG("The %s file \"%s\" seem truncated.",textname,fname); } if (count > CUBE_ITEMS_MAX-1) count = CUBE_ITEMS_MAX-1; if (count < 0) count = 0; struct CubeAttribs * cubuf; cubuf = (struct CubeAttribs *)&buf[4]; for (i=0; i < count; i++) { struct CubeAttribs * cubed; cubed = &game.cubes_data[i]; int n; for (n=0; n < CUBE_TEXTURES; n++) { cubed->texture_id[n] = cubuf->texture_id[n]; } for (n=0; n < CUBE_TEXTURES; n++) { cubed->field_C[n] = cubuf->field_C[n]; } cubuf++; } result = true; } //Freeing and exiting LbMemoryFree(buf); return result; }