void CTantalusRay::shootray() { if(m_mustsetup) { CVorticonMapLoader Maploader(mpMap); Maploader.load(2,81, mpMap->m_gamepath, false); while(!m_Object.empty()) { delete m_Object.back(); m_Object.pop_back(); } mpMap->drawAll(); CVorticonSpriteObject* ShootObject = new CRay(mpMap.get(), 4<<CSF, 9<<CSF, RIGHT, OBJ_NONE, 0); ShootObject->solid = false; ShootObject->exists = ShootObject->onscreen = true; m_Object.push_back(ShootObject); mp_ShootObject = m_Object.back(); g_pSound->playSound(SOUND_KEEN_FIRE, PLAY_NOW); m_mustsetup = false; } else { mp_ShootObject->moveRight(SHOT_SPD_X); mp_ShootObject->moveDown(SHOT_SPD_Y); shot_x = mp_ShootObject->getXPosition(); shot_y = mp_ShootObject->getYPosition(); int x = (shot_x>>STC)-160; int y = (shot_y>>STC)-100; if( x>0 && y>0 ) mpMap->gotoPos(x, y); mp_ShootObject->sprite = TANTALUS_SPRITE + m_alternate_sprite; m_alternate_sprite ^= 1; if( (shot_x>>CSF) >= EARTH_COORD_X) { m_Object.pop_back(); m_mustsetup = true; m_step = 0; mp_process = &CTantalusRay::explodeEarth; } } }
void CPreviews::init() { CInfoScene::init(); CExeFile &ExeFile = g_pBehaviorEngine->m_ExeFile; m_episode = ExeFile.getEpisode(); std::string DataDirectory = ExeFile.getDataDirectory(); mpMap.reset(new CMap()); CVorticonMapLoaderBase Maploader(mpMap); Maploader.load(m_episode, 90, DataDirectory); mpMap->gotoPos( 0, 0 ); // draw level map mpMap->drawAll(); m_scene_number = 1; openNextScene(); }
void CTantalusRay::shootray() { if(m_mustsetup) { CVorticonMapLoaderBase Maploader(mpMap); Maploader.load(2,81, mpMap->m_gamepath, false); m_Object.clear(); mpMap->drawAll(); std::unique_ptr<CVorticonSpriteObject> shootObject( new CRay(mpMap.get(), 4<<CSF, 9<<CSF, RIGHT, CENTER, 0, OBJ_NONE, 0) ); shootObject->solid = false; shootObject->exists = shootObject->onscreen = true; m_Object.push_back( move(shootObject) ); g_pSound->playSound(SOUND_KEEN_FIRE, PLAY_NOW); m_mustsetup = false; } else { CVorticonSpriteObject &shootObject = *m_Object.back(); shootObject.moveRight(SHOT_SPD_X); shootObject.moveDown(SHOT_SPD_Y); shot_x = shootObject.getXPosition(); shot_y = shootObject.getYPosition(); int x = (shot_x>>STC)-160; int y = (shot_y>>STC)-100; if( x>0 && y>0 ) mpMap->gotoPos(x, y); shootObject.sprite = TANTALUS_SPRITE + m_alternate_sprite; m_alternate_sprite ^= 1; if( (shot_x>>CSF) >= EARTH_COORD_X) { m_Object.pop_back(); m_mustsetup = true; m_step = 0; mp_process = &CTantalusRay::explodeEarth; } } }
void CAbout::init() { CInfoScene::init(); CExeFile &ExeFile = g_pBehaviorEngine->m_ExeFile; mpMap.reset(new CMap); CVorticonMapLoaderBase Maploader(mpMap); Maploader.load(ExeFile.getEpisode(), 90, ExeFile.getDataDirectory()); mpMap->gotoPos( 1008, 28 ); // Load the SDL_Bitmap if(m_type == "ID") { mp_bmp = g_pGfxEngine->getBitmap("IDLOGO"); // Get the offset where in the data the info is... size_t offset = 0; //m_numberoflines = 11; switch(ExeFile.getEpisode()) { case 1: if(ExeFile.getEXEVersion() == 131) offset = 0x16180-512; break; case 2: if(ExeFile.getEXEVersion() == 131) offset = 0x1A954-512; break; case 3: if(ExeFile.getEXEVersion() == 131) offset = 0x1CA70-512; break; } mpMap->drawAll(); // Read the strings and save them the string array of the class if(offset) { char *startdata; startdata = (char*)ExeFile.getRawData() + offset; std::string buf; for(int i=0 ; i<m_numberoflines ; i++) { char *data = startdata; for(short offset = 0 ; offset<0x28 ; offset++) { if(data[offset] == 0x0A && data[offset+1] == 0x00) break; buf.push_back(data[offset]); } startdata += 0x28; // now check how many new lines we have in buf size_t num_newlines = 0; bool endoftext = false; size_t pos; if((pos = buf.find(0xFE)) != std::string::npos) { buf.erase(pos), endoftext = true; } while((pos = buf.find(0x0A)) != std::string::npos) buf.erase(pos,1), num_newlines++; while((pos = buf.find('\0')) != std::string::npos) buf.erase(pos,1); m_lines.push_back(buf); if(endoftext) break; while(num_newlines > 0) m_lines.push_back(""), num_newlines--; buf.clear(); } } } else if(m_type == "CG") { std::string path = getResourceFilename("gfx/CGLogo.bmp", ExeFile.getDataDirectory(), true, true); mpLogoBMP.reset( SDL_LoadBMP(GetFullFileName(path).c_str()), &SDL_FreeSurface ); m_lines.push_back("Commander Genius is an interpreter"); m_lines.push_back("made with the goal of recreating"); m_lines.push_back("the engine that was used to power"); m_lines.push_back("the Commander Keen series."); m_lines.push_back(""); m_lines.push_back("However, we are also trying to add"); m_lines.push_back("better support for modern systems"); m_lines.push_back("to the games, so they can run more"); m_lines.push_back("smoothly than they did under DOS."); m_lines.push_back(""); m_lines.push_back("Thank you for supporting us by"); m_lines.push_back("downloading Commander Genius and"); m_lines.push_back("we hope you will report any bugs."); } switch(ExeFile.getEpisode()) { case 1: // Change the ugly lower Tiles which are seen, when using 320x240 base resolution for(int i=0; i<30 ; i++) { mpMap->changeTile(22+i, 15, 14*13); mpMap->changeTile(22+i, 16, 14*13+3); } break; } m_logo_rect.x = m_logo_rect.y = 0; m_logo_rect.h = m_logo_rect.w = 0; if(mpLogoBMP) { m_logo_rect.w = mpLogoBMP->w; m_logo_rect.h = mpLogoBMP->h; m_logo_rect.x = 160-m_logo_rect.w/2; m_logo_rect.y = 22; } SDL_Surface *temp = CG_CreateRGBSurface( g_pVideoDriver->getGameResolution().SDLRect() ); #if SDL_VERSION_ATLEAST(2, 0, 0) #else mpDrawSfc.reset(SDL_DisplayFormatAlpha(temp), &SDL_FreeSurface); #endif SDL_FreeSurface(temp); }
COrderingInfo::COrderingInfo( CExeFile &ExeFile ) { std::string datadirectory = ExeFile.getDataDirectory(); char episode = ExeFile.getEpisode(); mp_Scrollsurface = g_pVideoDriver->mp_VideoEngine->getScrollSurface(); CMapLoader Maploader(&m_Map); Maploader.load(episode, 90, datadirectory); m_Map.gotoPos( 22<<4, 32 ); // Get the offset where in the data the info is... size_t offset = 0; switch(episode) { case 1: m_starty = 4; // start of y-coordinate in textheights m_numberoflines = 21; // numberof lines to print if(ExeFile.getEXEVersion() == 131) offset = 0x1652B-512; // Change the ugly lower Tiles which are seen, when using 320x240 base resolution for(int i=0; i<20 ; i++) { m_Map.changeTile(22+i, 15, 14*13); m_Map.changeTile(22+i, 16, 14*13+3); } break; case 2: m_starty = 3; // start of y-coordinate in textheights m_numberoflines = 19; // numberof lines to print m_Map.gotoPos( 22<<4, 28 ); if(ExeFile.getEXEVersion() == 131) offset = 0x1ACD9-512; break; case 3: m_starty = 4; // start of y-coordinate in textheights m_numberoflines = 17; // numberof lines to print if(ExeFile.getEXEVersion() == 131) offset = 0x1CDED-512; break; } m_Map.drawAll(); // Read the strings and save them the string array of the class if(offset) { char *data; data = (char*)ExeFile.getRawData() + offset; std::string buf; for(int i=0 ; i<m_numberoflines ; i++) { if(*data == '\0') { data++; while(*data == '\0') data++; } while(*data != '\n' and *data != '\0') // For the next line { buf.push_back(*data); data++; } data++; m_Textline.push_back(buf); buf.clear(); } } //This just makes them all line up exactly like in the original games. switch(episode) { case 1: m_Textline[1] = " " + m_Textline[1]; m_Textline[2] = m_Textline[2] + " "; m_Textline[3] = m_Textline[3] + " "; m_Textline[4] = " " + m_Textline[4]; m_Textline[5] = " " + m_Textline[5]; m_Textline[6] = " " + m_Textline[6]; m_Textline[8] = m_Textline[8] + " "; m_Textline[9] = m_Textline[9] + " "; m_Textline[10] = m_Textline[10] + " "; m_Textline[11] = m_Textline[11] + " "; m_Textline[13] = m_Textline[13] + " "; m_Textline[14] = m_Textline[14] + " "; m_Textline[15] = m_Textline[15] + " "; m_Textline[20] = m_Textline[20] + " "; break; case 2: m_Textline[2] = m_Textline[2] + " "; m_Textline[4] = m_Textline[4] + " "; m_Textline[5] = m_Textline[5] + " "; m_Textline[6] = m_Textline[6] + " "; m_Textline[7] = m_Textline[7] + " "; m_Textline[8] = m_Textline[8] + " "; m_Textline[10] = m_Textline[10] + " "; m_Textline[11] = m_Textline[11] + " "; m_Textline[12] = m_Textline[12] + " "; m_Textline[13] = m_Textline[13] + " "; m_Textline[15] = m_Textline[15] + " "; m_Textline[16] = m_Textline[16] + " "; break; case 3: m_Textline[0] = m_Textline[0] + " "; m_Textline[1] = m_Textline[1] + " "; m_Textline[2] = m_Textline[2] + " "; m_Textline[4] = m_Textline[4] + " "; m_Textline[5] = m_Textline[5] + " "; m_Textline[6] = m_Textline[6] + " "; m_Textline[7] = m_Textline[7] + " "; m_Textline[8] = m_Textline[8] + " "; m_Textline[10] = m_Textline[10] + " "; m_Textline[11] = m_Textline[11] + " "; m_Textline[12] = m_Textline[12] + " "; m_Textline[13] = m_Textline[13] + " "; m_Textline[16] = m_Textline[16] + " "; break; } }
/////////////////////////// // Game State Management // /////////////////////////// bool CPlayGameVorticon::loadGameState() { CSaveGameController &savedGame = *(gpSaveGameController); // This fills the datablock from CSavedGame object if(savedGame.load()) { // Create the special merge effect (Fadeout) CColorMerge *pColorMergeFX = new CColorMerge(8); // Prepare for loading the new level map and the players. cleanup(); // get the episode, level and difficulty char newLevel; savedGame.decodeData(m_Episode); savedGame.decodeData(newLevel); bool loadmusic = ( m_Level != newLevel || m_Level == 80 ); m_Level = newLevel; savedGame.decodeData(g_pBehaviorEngine->mDifficulty); bool dark, checkpointset; int checkx, checky; savedGame.decodeData(checkpointset); savedGame.decodeData(checkx); savedGame.decodeData(checky); savedGame.decodeData(dark); // Load number of Players savedGame.decodeData(m_NumPlayers); if(!m_Player.empty()) m_Player.clear(); m_Player.assign(m_NumPlayers, CPlayer(m_Episode, m_Level, mp_level_completed, *mMap.get() ) ); for( size_t i=0 ; i < m_Player.size() ; i++ ) { m_Player.at(i).m_index = i; m_Player.at(i).setDatatoZero(); } CVorticonMapLoaderWithPlayer Maploader(mMap, m_Player, mSpriteObjectContainer); m_checkpointset = checkpointset; Maploader.m_checkpointset = m_checkpointset; if(!Maploader.load(m_Episode, m_Level, m_Gamepath, loadmusic, false)) return false; m_checkpoint_x = checkx; m_checkpoint_y = checky; m_level_command = START_LEVEL; std::vector<CPlayer> :: iterator player; for( player=m_Player.begin() ; player != m_Player.end() ; player++ ) { int x, y; player->setupforLevelPlay(); savedGame.decodeData(x); savedGame.decodeData(y); player->moveToForce(VectorD2<int>(x,y)); savedGame.decodeData(player->blockedd); savedGame.decodeData(player->blockedu); savedGame.decodeData(player->blockedl); savedGame.decodeData(player->blockedr); savedGame.decodeData(player->inventory); player->pdie = 0; } // load the number of objects on screen Uint32 size; savedGame.decodeData(size); for( Uint32 i=0 ; i<size ; i++ ) { unsigned int x,y; if(i >= mSpriteObjectContainer.size()) { std::unique_ptr<CVorticonSpriteObject> object( new CVorticonSpriteObject( mMap.get(), 0, 0, OBJ_NONE) ); object->exists = false; mSpriteObjectContainer.push_back(move(object)); } CVorticonSpriteObject &object = *(mSpriteObjectContainer.at(i)); savedGame.decodeData(object.m_type); savedGame.decodeData(x); savedGame.decodeData(y); object.moveToForce(VectorD2<int>(x,y)); savedGame.decodeData(object.dead); savedGame.decodeData(object.onscreen); savedGame.decodeData(object.hasbeenonscreen); savedGame.decodeData(object.exists); savedGame.decodeData(object.blockedd); savedGame.decodeData(object.blockedu); savedGame.decodeData(object.blockedl); savedGame.decodeData(object.blockedr); savedGame.decodeData(object.mHealthPoints); savedGame.decodeData(object.canbezapped); savedGame.decodeData(object.cansupportplayer); savedGame.decodeData(object.inhibitfall); savedGame.decodeData(object.honorPriority); savedGame.decodeData(object.sprite); object.performCollisions(); if(object.m_type == OBJ_DOOR or object.m_type == OBJ_RAY or object.m_type == OBJ_SNDWAVE or object.m_type == OBJ_FIREBALL or object.m_type == OBJ_ICECHUNK or object.m_type == OBJ_ICEBIT or object.m_type == OBJ_GOTPOINTS or object.m_type == OBJ_ANKHSHIELD) // Some objects are really not needed. So don't load them object.exists = false; } // TODO: An algorithm for comparing the number of players saved and we actually have need to be in sync // Load the map_data as it was left last savedGame.decodeData(mMap->m_width); savedGame.decodeData(mMap->m_height); savedGame.readDataBlock( reinterpret_cast<byte*>(mMap->getForegroundData()) ); // Load completed levels savedGame.readDataBlock( (byte*)(mp_level_completed) ); m_Player[0].setMapData(mMap.get()); m_Player[0].setupCameraObject(); m_Player[0].mpCamera->attachObject(&m_Player[0]); while(m_Player[0].mpCamera->m_moving) { m_Player[0].mpCamera->process(); m_Player[0].mpCamera->processEvents(); } mMap->drawAll(); // Create the special merge effect (Fadeout) g_pGfxEngine->setupEffect(pColorMergeFX); mpObjectAI.reset( new CVorticonSpriteObjectAI(mMap.get(), mSpriteObjectContainer, m_Player, m_NumPlayers, m_Episode, m_Level, mMap->m_Dark) ); setupPlayers(); mMap->m_Dark = dark; g_pGfxEngine->Palette.setdark(mMap->m_Dark); return true; } return false; }
void CCredits::init() { CInfoScene::init(); mpMap.reset( new CMap ); //creditFont = gGraphics.getFont(0); //creditFont.tintColor(SDL_MapRGB( creditFont.getSDLSurface()->format, 255, 0, 0) ); CVorticonMapLoaderBase Maploader(mpMap); CExeFile &ExeFile = gKeenFiles.exeFile; Maploader.load( ExeFile.getEpisode(), 90, gKeenFiles.gameDir ); mpMap->gotoPos( 104<<4, 16 ); m_scrolltext[0] = "Commander Genius"; m_scrolltext[1] = "aka CloneKeenPlus"; m_scrolltext[2] = ""; m_scrolltext[3] = ""; m_scrolltext[4] = "based on the engine of"; m_scrolltext[5] = "CloneKeen by Shaw"; m_scrolltext[6] = ""; m_scrolltext[7] = ""; m_scrolltext[8] = ""; m_scrolltext[9] = "Developers:"; m_scrolltext[10] = ""; m_scrolltext[11] = "Main Developers:"; m_scrolltext[12] = "Gerhard Stein (Gerstrong)"; m_scrolltext[13] = "Albert Zeyer"; m_scrolltext[14] = "Chad Ian Anderson (Pizza2004)"; m_scrolltext[15] = "Martin Hauber (Tulip)"; m_scrolltext[16] = "Scott Smith (Pickle)"; m_scrolltext[17] = ""; m_scrolltext[18] = "Handheld Devices:"; m_scrolltext[19] = "Pelya"; m_scrolltext[20] = "Albert Zeyer"; m_scrolltext[21] = ""; m_scrolltext[22] = "Resources:"; m_scrolltext[23] = "DaVince"; m_scrolltext[24] = ""; m_scrolltext[25] = ""; m_scrolltext[26] = "Commander Keen"; m_scrolltext[27] = "Developed by"; m_scrolltext[28] = "ID Software"; m_scrolltext[29] = ""; m_scrolltext[30] = "Tom Hall"; m_scrolltext[31] = ""; m_scrolltext[32] = "John D. Carmack"; m_scrolltext[33] = ""; m_scrolltext[34] = "John Romero"; m_scrolltext[35] = ""; m_scrolltext[36] = "Adrian Carmack"; m_scrolltext[37] = ""; m_scrolltext[38] = "Published by"; m_scrolltext[39] = "Apogee"; m_scrolltext[40] = ""; m_scrolltext[41] = "Scott Miller"; m_scrolltext[42] = ""; m_scrolltext[43] = "Music by"; m_scrolltext[44] = "Bobby Prince"; m_scrolltext[45] = ""; m_scrolltext[46] = "Special Thanks to"; m_scrolltext[47] = "Katy, for making the"; m_scrolltext[48] = "CloneKeen Engine"; m_scrolltext[49] = "in the first place."; m_scrolltext[50] = ""; m_scrolltext[51] = "The Commander Keen"; m_scrolltext[52] = "Community for all of"; m_scrolltext[53] = "the support they give."; m_timer = 0; m_scrolly = -54*8; for(int j=0 ; j<54 ; j++) { m_mid[j] = 160-(m_scrolltext[j].size()*4); } mDrawSfc.createRGBSurface( gVideoDriver.getGameResolution().SDLRect() ); mDrawSfc.makeBlitCompatible(); }
void COrderingInfo::init() { CInfoScene::init(); CExeFile &ExeFile = gKeenFiles.exeFile; std::string datadirectory = gKeenFiles.gameDir; char episode = ExeFile.getEpisode(); mpMap.reset(new CMap); CVorticonMapLoaderBase Maploader(mpMap); Maploader.load(episode, 90, datadirectory); mpMap->gotoPos( 22<<4, 32 ); // Get the offset where in the data the info is... size_t offset = 0; switch(episode) { case 1: m_starty = 4; // start of y-coordinate in textheights m_numberoflines = 21; // numberof lines to print if(ExeFile.getEXEVersion() == 131) offset = 0x1632B; // Change the ugly lower Tiles which are seen, when using 320x240 base resolution for(int i=0; i<20 ; i++) { mpMap->changeTile(22+i, 15, 14*13); mpMap->changeTile(22+i, 16, 14*13+3); } break; case 2: m_starty = 3; // start of y-coordinate in textheights m_numberoflines = 19; // numberof lines to print mpMap->gotoPos( 22<<4, 28 ); if(ExeFile.getEXEVersion() == 131) offset = 0x1AAD9; break; case 3: m_starty = 4; // start of y-coordinate in textheights m_numberoflines = 17; // numberof lines to print if(ExeFile.getEXEVersion() == 131) offset = 0x1CBED; break; } mpMap->drawAll(); // Read the strings and save them the string array of the class if(offset) { char *data; data = (char*)ExeFile.getRawData() + offset; std::string buf; for(int i=0 ; i<m_numberoflines ; i++) { if(*data == '\0') { data++; while(*data == '\0') data++; } while(*data != '\n' and *data != '\0') // For the next line { buf.push_back(*data); data++; } data++; m_Textline.push_back(buf); buf.clear(); } } // This just makes them all line up exactly like in the original games. switch(episode) { case 1: m_Textline[1] = " " + m_Textline[1]; m_Textline[2] = m_Textline[2] + " "; m_Textline[3] = m_Textline[3] + " "; m_Textline[4] = " " + m_Textline[4]; m_Textline[5] = " " + m_Textline[5]; m_Textline[6] = " " + m_Textline[6]; m_Textline[8] = m_Textline[8] + " "; m_Textline[9] = m_Textline[9] + " "; m_Textline[10] = m_Textline[10] + " "; m_Textline[11] = m_Textline[11] + " "; m_Textline[13] = m_Textline[13] + " "; m_Textline[14] = m_Textline[14] + " "; m_Textline[15] = m_Textline[15] + " "; m_Textline[20] = m_Textline[20] + " "; break; case 2: m_Textline[2] = m_Textline[2] + " "; m_Textline[4] = m_Textline[4] + " "; m_Textline[5] = m_Textline[5] + " "; m_Textline[6] = m_Textline[6] + " "; m_Textline[7] = m_Textline[7] + " "; m_Textline[8] = m_Textline[8] + " "; m_Textline[10] = m_Textline[10] + " "; m_Textline[11] = m_Textline[11] + " "; m_Textline[12] = m_Textline[12] + " "; m_Textline[13] = m_Textline[13] + " "; m_Textline[15] = m_Textline[15] + " "; m_Textline[16] = m_Textline[16] + " "; break; case 3: m_Textline[0] = m_Textline[0] + " "; m_Textline[1] = m_Textline[1] + " "; m_Textline[2] = m_Textline[2] + " "; m_Textline[4] = m_Textline[4] + " "; m_Textline[5] = m_Textline[5] + " "; m_Textline[6] = m_Textline[6] + " "; m_Textline[7] = m_Textline[7] + " "; m_Textline[8] = m_Textline[8] + " "; m_Textline[10] = m_Textline[10] + " "; m_Textline[11] = m_Textline[11] + " "; m_Textline[12] = m_Textline[12] + " "; m_Textline[13] = m_Textline[13] + " "; m_Textline[16] = m_Textline[16] + " "; break; } SDL_Surface *temp = CG_CreateRGBSurface( gVideoDriver.getGameResolution().SDLRect() ); //#if SDL_VERSION_ATLEAST(2, 0, 0) //#else mpTextSfc.reset(gVideoDriver.convertThroughBlitSfc(temp), &SDL_FreeSurface); //#endif SDL_FreeSurface(temp); }
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(); }
CCredits::CCredits(const std::string &datadirectory, const char &episode) { mp_Scrollsurface = g_pVideoDriver->mp_VideoEngine->getScrollSurface(); mp_Map = new CMap; CMapLoader Maploader(mp_Map); Maploader.load(episode, 90, datadirectory); mp_Map->gotoPos( 104<<4, 16 ); m_scrolltext[0] = "Commander Genius"; m_scrolltext[1] = "aka CloneKeenPlus"; m_scrolltext[2] = ""; m_scrolltext[3] = ""; m_scrolltext[4] = "based on the engine of"; m_scrolltext[5] = "CloneKeen by Shaw"; m_scrolltext[6] = ""; m_scrolltext[7] = ""; m_scrolltext[8] = ""; m_scrolltext[9] = "Developers:"; m_scrolltext[10] = ""; m_scrolltext[11] = "Main Developers:"; m_scrolltext[12] = "Gerhard Stein (Gerstrong)"; m_scrolltext[13] = "Albert Zeyer"; m_scrolltext[14] = "Chad Ian Anderson (Pizza2004)"; m_scrolltext[15] = "Martin Hauber (Tulip)"; m_scrolltext[16] = "Scott Smith (Pickle)"; m_scrolltext[17] = ""; m_scrolltext[18] = "Handheld Devices:"; m_scrolltext[19] = "Scott Smith (Pickle)"; m_scrolltext[20] = "Albert Zeyer"; m_scrolltext[21] = ""; m_scrolltext[22] = "Resources:"; m_scrolltext[23] = "DaVince"; m_scrolltext[24] = ""; m_scrolltext[25] = ""; m_scrolltext[26] = "Commander Keen"; m_scrolltext[27] = "Developed by"; m_scrolltext[28] = "ID Software"; m_scrolltext[29] = ""; m_scrolltext[30] = "Tom Hall"; m_scrolltext[31] = ""; m_scrolltext[32] = "John D. Carmack"; m_scrolltext[33] = ""; m_scrolltext[34] = "John Romero"; m_scrolltext[35] = ""; m_scrolltext[36] = "Adrian Carmack"; m_scrolltext[37] = ""; m_scrolltext[38] = "Published by"; m_scrolltext[39] = "Apogee"; m_scrolltext[40] = ""; m_scrolltext[41] = "Scott Miller"; m_scrolltext[42] = ""; m_scrolltext[43] = "Music by"; m_scrolltext[44] = "Bobby Prince"; m_scrolltext[45] = ""; m_scrolltext[46] = "Special Thanks to"; m_scrolltext[47] = "Katy, for making the"; m_scrolltext[48] = "CloneKeen Engine"; m_scrolltext[49] = "in the first place."; m_scrolltext[50] = ""; m_scrolltext[51] = "The Commander Keen"; m_scrolltext[52] = "Community for all of"; m_scrolltext[53] = "the support they give."; m_timer = 0; m_scrolly = -54*8; for(int j=0 ; j<54 ; j++) m_mid[j] = 160-(m_scrolltext[j].size()*4); }