// This method returns the name of the slot std::string CSaveGameController::getSlotName(const std::string &filename) { char version; std::ifstream StateFile; std::string SlotName; OpenGameFileR( StateFile, filename, std::ofstream::binary ); // Check Savegame version version = StateFile.get(); if(version != SAVEGAMEVERSION) { SlotName = "- File Incompatible -"; } else { // read the slot name Uint32 size = StateFile.get(); std::vector<char> buf(size + 1); readData( &buf[0], size, StateFile); buf[size] = '\0'; SlotName = &buf[0]; } StateFile.close(); return SlotName; }
/** * \brief This will load for you a text from a file into memory and of course automatically format it for you :-) * \parm filename filename to open */ bool CTextViewer::loadTextfromFile(const std::string &filename) { std::string text; std::ifstream endfile; OpenGameFileR(endfile, filename); if (endfile.is_open()) { while(!endfile.eof()) { text.push_back(endfile.get()); } endfile.close(); text.push_back('\0'); } else { g_pLogFile->textOut("Error reading \"" + filename + "\". Check if this file is in your directory!"); return false; } formatText(text); return true; }
bool CSaveGameController::load() { Uint32 size; std::ifstream StateFile; std::string fullpath = GetFullFileName(m_statefilename); OpenGameFileR( StateFile, m_statefilename, std::ofstream::binary ); if (!StateFile.is_open()) { g_pLogFile->textOut("Error loading \"" + fullpath + "\". Please check the status of that file.\n" ); return false; } // Skip the header as we already chose the game StateFile.get(); // Skip the version info size = StateFile.get(); // get the size of the slotname and... for(Uint32 i=0 ; i<size ; i++) // skip that name string StateFile.get(); while(!StateFile.eof()) // read it everything in m_datablock.push_back(StateFile.get()); // TODO: Decompression has still to be done! // Now write all the data to the file StateFile.close(); // Done! g_pLogFile->textOut("File \""+ fullpath +"\" was sucessfully loaded. Size: "+itoa(m_datablock.size())+"\n"); m_offset = 0; m_statefilename.clear(); m_statename.clear(); return true; }
bool CMusic::LoadfromMusicTable(const std::string &gamepath, const std::string &levelfilename) { bool fileloaded = false; std::ifstream Tablefile; std::string musicpath = getResourceFilename(JoinPaths("music", "table.cfg"), gamepath, false, true); if(musicpath != "") fileloaded = OpenGameFileR(Tablefile, musicpath); if(fileloaded) { std::string str_buf; while(!Tablefile.eof()) { getline(Tablefile, str_buf, ' '); str_buf.erase(0, str_buf.find_first_not_of('\n')); if( str_buf == levelfilename ) // found the level! Load the song! { // Get the song filename and load it! getline(Tablefile, str_buf); TrimSpaces(str_buf); std::string filename = getResourceFilename(JoinPaths("music", str_buf), gamepath, false, true); if( load(filename) ) play(); return true; } Tablefile.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); } } return false; }
bool CHuffman::readDictionaryFromFile( const std::string &filename ) { std::ifstream file; if(!OpenGameFileR(file, filename, std::ios::binary)) { return false; } file.read(reinterpret_cast<char*>(m_nodes), DICT_SIZE*sizeof(nodestruct)); return true; }
// This function checks if the file we want to read or save already exists bool CSaveGameController::alreadyExits() { std::ifstream StateFile; std::string fullpath = GetFullFileName(m_statefilename); OpenGameFileR( StateFile, m_statefilename, std::ofstream::binary ); if (!StateFile.is_open()) return false; else { StateFile.close(); return true; } }
void CGameLauncher::getLabels() { bool found; Uint16 i; std::string line, dir; std::ifstream gamescfg; m_Names.clear(); m_Paths.clear(); OpenGameFileR(gamescfg, GAMESCFG); if (gamescfg.is_open()) { while ( !gamescfg.eof() ) { getline(gamescfg,line); if (strncmp(line.c_str(),GAMESCFG_DIR,strlen(GAMESCFG_DIR)) == 0) { dir = line.substr(strlen(GAMESCFG_DIR)); // Check for duplicates found = false; for ( i=0; i<m_Paths.size(); i++ ) { if (strncmp(m_Paths.at(i).c_str(),dir.c_str(),dir.length()) == 0) { found = true; break; } } // If not a duplicate get the custom name if (!found) { getline(gamescfg,line); if (strncmp(line.c_str(),GAMESCFG_NAME,strlen(GAMESCFG_NAME)) == 0) { m_Paths.push_back( dir ); std::string gamePath = line.substr(strlen(GAMESCFG_NAME)); m_Names.push_back( filterGameName(gamePath) ); } } } } gamescfg.close(); } }
bool CMusic::LoadfromSonglist(const std::string &gamepath, const int &level) { bool fileloaded = false; std::ifstream Tablefile; std::string musicpath = getResourceFilename("songlist.lst", gamepath, false, false); if(musicpath != "") fileloaded = OpenGameFileR(Tablefile, musicpath); if(fileloaded) { std::string str_buf; std::string music_filename; int detected_level=-1; size_t next_pos = 0; while(!Tablefile.eof()) { getline(Tablefile, str_buf); next_pos = str_buf.find(' ')+1; str_buf = str_buf.substr(next_pos); next_pos = str_buf.find(' '); // Get level number detected_level = atoi(str_buf.substr(0, next_pos).c_str()); str_buf = str_buf.substr(next_pos); next_pos = str_buf.find('"')+1; str_buf = str_buf.substr(next_pos); next_pos = str_buf.find('"'); // Get the music filename to be read music_filename = str_buf.substr(0, next_pos); if( detected_level == level ) // found the level! Load the song! { // Get the song filename and load it! std::string filename = getResourceFilename( music_filename, gamepath, false, true); if( load(filename) ) play(); return true; } } } return false; }
CHelp::CHelp(CExeFile &ExeFile, const std::string &type) : mp_TextViewer(NULL) { std::string Text; std::string DataDirectory = ExeFile.getDataDirectory(); char episode = ExeFile.getEpisode(); // Read the Storytext if(type == "Game") { if(episode==1) { // We suppose that we are using version 131. Maybe it must be extended std::string filename = DataDirectory; if(DataDirectory != "") filename += "/"; filename += "helptext.ck1"; std::ifstream File; OpenGameFileR(File, filename, std::ios::binary); if(!File) return; while(!File.eof()) Text.push_back(File.get()); File.close(); Text.erase(Text.size()-1); } else { // Here the Text file is within the EXE-File unsigned long startflag=0, endflag=0; unsigned char *text_data = NULL; if(!ExeFile.getHeaderData()) return; if(episode == 2) { startflag = 0x15DC0; endflag = 0x1659F; } else // Episode 3 { startflag = 0x17BD0; endflag = 0x1839B; } text_data = ExeFile.getRawData(); for(unsigned long i=startflag ; i<endflag ; i++ ) Text.push_back(text_data[i]); } } else { std::string filename = "HELPTEXT.CKP"; std::ifstream File; OpenGameFileR(File, filename, std::ios::binary); if(!File) return; while(!File.eof()) Text.push_back(File.get()); File.close(); Text.erase(Text.size()-1); } // Create the Text ViewerBox and stores the text there! mp_TextViewer = new CTextViewer(g_pVideoDriver->mp_VideoEngine->getFGLayerSurface(), 0, 8, 320, 160); mp_TextViewer->formatText(Text); }
bool gusOpenGameFileR(std::ifstream& f, const std::string& path, std::ios_base::openmode mode) { return OpenGameFileR(f, path, mode); }
bool CExeFile::readData(const char episode, const std::string& datadirectory) { crc32_init(); std::string filename = datadirectory + "/keen" + itoa(episode) + ".exe"; std::ifstream File; OpenGameFileR(File, filename, std::ios::binary); if(!File) { // try another filename (Used in Episode 4-6) filename = datadirectory + "/keen" + itoa(episode) + "e.exe"; OpenGameFileR(File, filename, std::ios::binary); } if(!File) { // try another filename (Used in Episode 4-6) for demo versions filename = datadirectory + "/k" + itoa(episode) + "demo.exe"; OpenGameFileR(File, filename, std::ios::binary); } if(!File) return false; m_filename = filename; m_episode = episode; m_datadirectory = datadirectory; if( m_datadirectory != "") if(*(m_datadirectory.end()-1) != '/') m_datadirectory += "/"; File.seekg(0,std::ios::end); m_datasize = File.tellg(); File.seekg(0,std::ios::beg); SAFE_DELETE_ARRAY(m_data); unsigned char* m_data_temp = new unsigned char[m_datasize]; File.read((char*)m_data_temp, m_datasize); File.close(); Cunlzexe UnLZEXE; std::vector<unsigned char> decdata; if(UnLZEXE.decompress(m_data_temp, decdata)) { m_datasize = decdata.size(); m_data = new unsigned char[m_datasize]; m_headersize = UnLZEXE.HeaderSize(); memcpy(m_data, &decdata[0], m_datasize); } else { m_data = new unsigned char[m_datasize]; memcpy(m_data, m_data_temp,m_datasize); } m_headerdata = m_data; m_headersize = UnLZEXE.HeaderSize(); if(!m_headersize) m_headersize = 512; m_rawdata = m_data + m_headersize; const size_t offset_map[] = { /*Dummy:*/ 0x0, /*Keen 1:*/ 0x13050, /*Keen 2:*/ 0x17780, /*Keen 3:*/ 0x19820, /*Keen 4:*/ 0x2EE70, /*Keen 5:*/ 0x30340, /*Keen 6:*/ 0x30D30, /*Keen D:*/ 0x23A70 }; m_data_segment = m_rawdata+offset_map[m_episode]; delete[] m_data_temp; m_crc = getcrc32( m_data, m_datasize ); g_pLogFile->ftextOut( "EXE processed with size of %d and crc of %X\n", m_datasize, m_crc ); return true; }
void CStory::init() { CInfoScene::init(); CExeFile &ExeFile = gKeenFiles.exeFile; const char episode = ExeFile.getEpisode(); std::string DataDirectory = gKeenFiles.gameDir; mpMap.reset(new CMap()); CVorticonMapLoaderBase Maploader(mpMap); std::string Text; // Read the Storytext if(episode==1) { // We suppose that we are using version 131. Maybe it must be extended std::string filename = DataDirectory; if(DataDirectory != "") filename += "/"; filename += "storytxt.ck1"; std::ifstream File; OpenGameFileR(File, filename, std::ios::binary); if(!File) return; while(!File.eof()) Text.push_back(File.get()); File.close(); Text.erase(Text.size()-1); } else { // Here the Text file is within the EXE-File unsigned long startflag=0, endflag=0; unsigned char *text_data = NULL; if(episode == 2) { startflag = 0x16CC0-512; endflag = 0x17958-512; } else // Episode 3 { startflag = 0x18DD0-512; endflag = 0x199F3-512; } text_data = ExeFile.getRawData(); if(!text_data) return; for(unsigned long i=startflag ; i<endflag ; i++ ) Text.push_back(text_data[i]); } Maploader.load(episode, 90, DataDirectory, false); // Create the Text ViewerBox and stores the text there! mpTextViewer.reset(new CTextViewer(0, 0, 320, 136)); mpTextViewer->formatText(Text); // Scroll to the map where you see Keen with his rocket. mpMap->gotoPos( 32+2*320, 32 ); mpMap->drawAll(); }
bool LieroXLevelLoader::load(CMap* level, std::string const& path) { std::ifstream f; OpenGameFileR(f, path, std::ios::binary); if(!f) return false; static const char magic[] = "LieroX Level"; char check[sizeof(magic)]; f.read(check, sizeof(check)); if(memcmp(check, magic, sizeof(magic))) return false; //File magic check failed long width = 0, height = 0; //long has to be at least 32-bit, static_assert? f.seekg(0x64); //Level size position f.read((char *)&width, 4); f.read((char *)&height, 4); //TODO: Read level name f.seekg(0x9c); //Level data position const size_t ChunkBits = 14; const size_t ChunkSize = 1 << ChunkBits; size_t have; z_stream strm; unsigned char in[ChunkSize]; // allocate inflate state strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.avail_in = 0; strm.next_in = Z_NULL; int ret = inflateInit(&strm); if (ret != Z_OK) return false; size_t totalDataSize = (2 * 3 + 1) * (width * height); // Add an extra chunk size to be sure not to overflow totalDataSize = totalDataSize + ChunkSize; std::vector<unsigned char> data(totalDataSize); unsigned char *p = &data[0]; do { f.read((char *)in, ChunkSize); strm.avail_in = (uInt)f.gcount(); if (strm.avail_in == 0) break; strm.next_in = (Bytef *)in; // run inflate() on input until output buffer not full do { if(totalDataSize < ChunkSize) return false; // We got too much data from the stream strm.avail_out = ChunkSize; strm.next_out = (Bytef *)p; ret = inflate(&strm, Z_NO_FLUSH); switch (ret) { case Z_NEED_DICT: case Z_DATA_ERROR: case Z_MEM_ERROR: case Z_STREAM_ERROR: inflateEnd(&strm); return false; } have = ChunkSize - strm.avail_out; totalDataSize -= have; p += have; } while (strm.avail_out == 0); } while (ret != Z_STREAM_END); inflateEnd(&strm); // Clean up level->material = create_bitmap_ex(8, width, height); #ifndef DEDICATED_ONLY level->image = create_bitmap(width, height); level->background = create_bitmap(width, height); #endif unsigned char *pbackground = &data[0]; unsigned char *pimage = pbackground + width*height*3; unsigned char *pmaterial = pimage + width*height*3; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { #ifndef DEDICATED_ONLY int backgroundc = makecol(pbackground[0], pbackground[1], pbackground[2]); #endif int m = pmaterial[0]; #ifndef DEDICATED_ONLY if(m == 1) putpixel(level->image, x, y, backgroundc); else { int imagec = makecol(pimage[0], pimage[1], pimage[2]); putpixel(level->image, x, y, imagec); } putpixel(level->background, x, y, backgroundc); #endif switch(m) { default: m = 1; break; // Background case 2: m = 2; break; // Dirt case 4: m = 0; break; // Rock } putpixel(level->material, x, y, m); #ifndef DEDICATED_ONLY pimage += 3; pbackground += 3; #endif ++pmaterial; } } level->loaderSucceeded(); return true; }
bool CVorticonMapLoaderBase::loadBase( Uint8 episode, Uint8 level, const std::string& path, bool loadNewMusic ) { std::vector<Uint16> planeitems; std::string levelname = "level"; if(level < 10) levelname += "0"; levelname += itoa(level) + ".ck" + itoa(episode); mpMap->resetScrolls(); mpMap->m_gamepath = path; mpMap->m_worldmap = (level == 80); // HQ Music. Load Music for a level if you have HQP if(loadNewMusic) { gMusicPlayer.stop(); // If no music from the songlist could be loaded try the normal table which // has another format. It is part of HQP if(!gMusicPlayer.LoadfromSonglist(path, level)) gMusicPlayer.LoadfromMusicTable(path, levelname); } // decompress map RLEW data std::ifstream MapFile; bool fileopen = OpenGameFileR(MapFile, getResourceFilename(levelname,path,true,false), std::ios::binary); if (!fileopen) { // only record this error message on build platforms that log errors // to a file and not to the screen. gLogging.ftextOut("MapLoader: unable to open file %s<br>", levelname.c_str()); return false; } gLogging.ftextOut("MapLoader: file %s opened. Loading...<br>", levelname.c_str()); MapFile.seekg (0, std::ios::beg); // load the compressed data into the memory std::vector<Uint8> compdata; while( !MapFile.eof() ) { compdata.push_back(static_cast<Uint8>(MapFile.get())); } MapFile.close(); CRLE RLE; RLE.expandSwapped(planeitems, compdata, 0xFEFE); // Here goes the memory allocation function const Uint16 w = planeitems.at(1); const Uint16 h = planeitems.at(2); mpMap->setupEmptyDataPlanes(3, w, h); unsigned int planesize = 0; planesize = planeitems.at(8); planesize /= 2; // We have two planes blitPlaneToMap( planeitems, planesize, 0, 0); blitPlaneToMap( planeitems, planesize, 0, 1); blitPlaneToMap( planeitems, planesize, 1, 2); mpMap->collectBlockersCoordiantes(); mpMap->setupAnimationTimer(); return true; }
// Loads the map into the memory bool CMapLoader::load( Uint8 episode, Uint8 level, const std::string& path, bool loadNewMusic, bool stategame ) { std::string levelname = "level"; if(level < 10) levelname += "0"; levelname += itoa(level) + ".ck" + itoa(episode); mp_map->resetScrolls(); mp_map->m_gamepath = path; mp_map->m_worldmap = (level == 80); // HQ Music. Load Music for a level if you have HQP if(loadNewMusic) { g_pMusicPlayer->stop(); // If no music from the songlist could be loaded try the normal table which // has another format. It is part of HQP if(!g_pMusicPlayer->LoadfromSonglist(path, level)) g_pMusicPlayer->LoadfromMusicTable(path, levelname); } // decompress map RLEW data std::ifstream MapFile; bool fileopen = OpenGameFileR(MapFile, getResourceFilename(levelname,path,true,false), std::ios::binary); if (!fileopen) { // only record this error message on build platforms that log errors // to a file and not to the screen. g_pLogFile->ftextOut("MapLoader: unable to open file %s<br>", levelname.c_str()); return 0; } g_pLogFile->ftextOut("MapLoader: file %s opened. Loading...<br>", levelname.c_str()); MapFile.seekg (0, std::ios::beg); // load the compressed data into the memory std::vector<Uint8> compdata; while( !MapFile.eof() ) { compdata.push_back(static_cast<Uint8>(MapFile.get())); } MapFile.close(); CRLE RLE; std::vector<Uint16> planeitems; RLE.expandSwapped(planeitems,compdata, 0xFEFE); // Here goes the memory allocation function mp_map->createEmptyDataPlane(1, planeitems.at(1), planeitems.at(2)); int t; unsigned int planesize = 0; unsigned int curmapx=0, curmapy=0; planesize = planeitems.at(8); planesize /= 2; // Size of two planes, but we only need one const char &fixlevel_error = g_pBehaviorEngine->m_option[OPT_FIXLEVELERRORS].value; Uint32 c; for( c=17 ; c<planesize+17 ; c++ ) // Check against Tilesize { t = planeitems.at(c); if( fixlevel_error ) fixLevelTiles(t, curmapx, curmapy, episode, level); addTile(t, curmapx, curmapy); curmapx++; if (curmapx >= mp_map->m_width) { curmapx = 0; curmapy++; if (curmapy >= mp_map->m_height) break; } if(t > 255) t=0; // If there are some invalid values in the file } // now do the sprites // get sprite data int resetcnt, resetpt; curmapx = curmapy = 0; resetcnt = resetpt = 0; if(mp_objvect && stategame == false) { std::vector<CObject*>::iterator obj = mp_objvect->begin(); for( ; obj != mp_objvect->end() ; obj++ ) { delete *obj; mp_objvect->pop_back(); } mp_objvect->reserve(2000); for( c=planesize+17 ; c<2*planesize+16 ; c++ ) { // in case the planesizes are bigger than the actual file content itself if(planeitems.size() <= c) break; t = planeitems.at(c); if (mp_map->m_worldmap) addWorldMapObject(t, curmapx, curmapy, episode ); else addEnemyObject(t, curmapx, curmapy, episode, level); curmapx++; if (curmapx >= mp_map->m_width) { curmapx = 0; curmapy++; if (curmapy >= mp_map->m_height) break; } if (++resetcnt==resetpt) curmapx = curmapy = 0; } } planeitems.clear(); // Do some post calculations // Limit the scroll screens so the blocking (blue in EP1) tiles are3 never seen SDL_Rect gamerect = g_pVideoDriver->getGameResolution(); mp_map->m_maxscrollx = (mp_map->m_width<<4) - gamerect.w - 32; mp_map->m_maxscrolly = (mp_map->m_height<<4) - gamerect.h - 32; // Set Scrollbuffer g_pVideoDriver->setScrollBuffer(&mp_map->m_scrollx_buf, &mp_map->m_scrolly_buf); return true; }
bool CMapLoaderGalaxy::loadMap(CMap &Map, Uint8 level) { // Get the MAPHEAD Location from within the Exe File or an external file std::vector<char> mapHeadContainer; const std::string &path = gKeenFiles.gameDir; // Set Map position and some flags for the freshly loaded level Map.gotoPos(0,0); Map.setLevel(level); Map.isSecret = false; Map.mNumFuses = 0; // In case no external file was read, let's use data from the embedded data byte *Maphead = gKeenFiles.exeFile.getRawData() + getMapheadOffset(); // In case there is an external file read it into the container and replace the pointer const std::string mapHeadFilename = gKeenFiles.mapheadFilename; std::ifstream MapHeadFile; if(OpenGameFileR(MapHeadFile, getResourceFilename(mapHeadFilename,path,true,false), std::ios::binary)) { // get length of file: MapHeadFile.seekg (0, std::ios::end); unsigned int length = MapHeadFile.tellg(); MapHeadFile.seekg (0, std::ios::beg); mapHeadContainer.resize(length); MapHeadFile.read(&mapHeadContainer[0],length*sizeof(char)); Maphead = reinterpret_cast<byte*>(&mapHeadContainer[0]); } word magic_word; longword level_offset; // Get the magic number of the level data from MAPHEAD Located in the EXE-File. // This is used for the decompression. magic_word = READWORD(Maphead); // Get location of the level data from MAPHEAD Located in the EXE-File. Maphead += level*sizeof(longword); level_offset = READLONGWORD(Maphead); // Open the Gamemaps file std::string gamemapfile = gKeenFiles.gamemapsFilename; std::ifstream MapFile; if(OpenGameFileR(MapFile, getResourceFilename(gamemapfile,path,true,false), std::ios::binary)) { if(level_offset == 0 && mapHeadContainer.empty()) { MapFile.close(); gLogging.textOut("This Level doesn't exist in GameMaps"); return false; } // Then jump to that location and read the level map data MapFile.seekg (level_offset, std::ios::beg); int headbegin; // Get the level plane header if(gotoNextSignature(MapFile)) { /* * Plane Offsets: Long[3] Offset within GAMEMAPS to the start of the plane. The first offset is for the background plane, the * second for the foreground plane, and the third for the info plane (see below). * Plane Lengths: Word[3] Length (in bytes) of the compressed plane data. The first length is for the background plane, the * second for the foreground plane, and the third for the info plane (see below). * Width: Word Level width (in tiles). * Height: Word Level height (in tiles). Together with Width, this can be used to calculate the uncompressed * size of plane data, by multiplying Width by Height and multiplying the result by sizeof(Word). * Name: Byte[16] Null-terminated string specifying the name of the level. This name is used only by TED5, not by Keen. * Signature: Byte[4] Marks the end of the Level Header. Always "!ID!". */ int jumpback = 3*sizeof(longword) + 3*sizeof(word) + 2*sizeof(word) + 16*sizeof(byte) + 4*sizeof(byte); headbegin = static_cast<int>(MapFile.tellg()) - jumpback; } else { MapFile.clear(); headbegin = level_offset; } MapFile.seekg( headbegin, std::ios_base::beg); // Get the header of level data longword Plane_Offset[3]; longword Plane_Length[3]; word Width, Height; char name[17]; // Get the plane offsets Plane_Offset[0] = fgetl(MapFile); Plane_Offset[1] = fgetl(MapFile); Plane_Offset[2] = fgetl(MapFile); // Get the dimensions of the level Plane_Length[0] = fgetw(MapFile); Plane_Length[1] = fgetw(MapFile); Plane_Length[2] = fgetw(MapFile); Width = fgetw(MapFile); Height = fgetw(MapFile); if(Width>1024 || Height>1024) { gLogging.textOut("Sorry, but I cannot uncompress this map and must give up." "Please report this to the developers and send that version to them in order to fix it.<br>" ); return false; } for(int c=0 ; c<16 ; c++) { name[c] = MapFile.get(); } name[16] = '\0'; // Get and check the signature gLogging.textOut("Loading the Level \"" + static_cast<std::string>(name) + "\" (Level No. "+ itoa(level) + ")<br>" ); Map.setLevelName(name); mLevelName = name; // Then decompress the level data using rlew and carmack gLogging.textOut("Decompressing the Map...<br>" ); // Start with the Background Map.createEmptyDataPlane(0, Width, Height); Map.createEmptyDataPlane(1, Width, Height); Map.createEmptyDataPlane(2, Width, Height); unpackPlaneData(MapFile, Map, 0, Plane_Offset[0], Plane_Length[0], magic_word); unpackPlaneData(MapFile, Map, 1, Plane_Offset[1], Plane_Length[1], magic_word); unpackPlaneData(MapFile, Map, 2, Plane_Offset[2], Plane_Length[2], magic_word); Map.collectBlockersCoordiantes(); MapFile.close(); // Now that we have all the 3 planes (Background, Foreground, Foes) unpacked... // We only will show the first two of them in the screen, because the Foes one // is the one which will be used for spawning the foes (Keen, platforms, enemies, etc.) spawnFoes(Map); } else { return false; } // Set Scrollbuffer Map.drawAll(); gVideoDriver.updateScrollBuffer(Map.m_scrollx, Map.m_scrolly); return true; }
bool LOSPFontLoader::load(Font* font, std::string const& path) { font->free(); std::ifstream f; OpenGameFileR(f, path, std::ios::binary); if(!f) return false; long bitmapWidth = 0, bitmapHeight = 0; f.read((char *)&bitmapWidth, 4); f.read((char *)&bitmapHeight, 4); if(!f) return false; bool full = false; if(bitmapWidth < 0) { bitmapWidth = -bitmapWidth; full = true; } font->m_bitmap = create_bitmap_ex(8, bitmapWidth, bitmapHeight); if(!font->m_bitmap) return false; font->m_supportColoring = true; int max = 224; if(full) { max = 256; } else font->m_chars.assign(32, Font::CharInfo(Rect(0, 0, 1, 1), 0)); for(int i = 0; i < max; ++i) { int x, y, w, h; f.read((char *)&x, 4); f.read((char *)&y, 4); f.read((char *)&w, 4); f.read((char *)&h, 4); if(!f) return false; font->m_chars.push_back(Font::CharInfo(Rect(x, y, x + w, y + h), 0)); } if(!full) font->m_chars[11] = font->m_chars[(unsigned char)'^']; for(int y = 0; y < bitmapWidth; ++y) { for(int x = 0; x < bitmapHeight; ++x) { char v; if(!f.get(v)) return false; int c = (unsigned char)v; putpixel(font->m_bitmap, x, y, c); } } font->buildSubBitmaps(); return true; }