diff --git a/programmer_readme.txt b/programmer_readme.txt index 3f2bfab..9817468 100644 --- a/programmer_readme.txt +++ b/programmer_readme.txt @@ -9,7 +9,7 @@ Dink Smallwood HD * By default, Proton SDK's main.cpp is setup to compile for iPhone most likely. Assuming you'd rather not have an iPhone build, search the project for "//WORK: Change device emulation here" and right under that, change it from string desiredVideoMode = "iPhone Landscape"; or whatever it was to "string desiredVideoMode = "Windows"; instead. (this is where you can emulate many devices and sizes) * Set the profile to "Release GL" and "Win32". (or "Debug GL" is ok too) Compile. If it worked, you should have a dink.exe created in DinkHD/bin. -* Install DinkHD from rtsoft.com. (media is not svn, so this is a way to get it..) Overwrite its dink.exe with your new one. It should run! +* Install DinkHD from rtsoft.com. (media is not svn, so this is a way to get it..) Overwrite its dink.exe and fmod.dll (as that is probably different now) with your new one. It should run! diff --git a/script/win_installer/readme.txt b/script/win_installer/readme.txt index 75e2793..10edf7a 100644 --- a/script/win_installer/readme.txt +++ b/script/win_installer/readme.txt @@ -21,6 +21,11 @@ Escape - Bring up menu NOTE: If you have a controller (like an xbox 360 pad) plugged in when you start the game, you can use that instead of keyboard, but you still need to use the mouse to navigate the initial menus to start the game +Supported command line options: + +-game (Example: dink.exe -game c:\dmods\island ) (this also sets -dmodpath automatically to the dmods parent directory) +-dmodpath (Example: dink.exe -game c:\dmods ) + ------------- BETA VERSION ----------------- @@ -86,3 +91,11 @@ www.rtsoft.com * (Windows) Handles alt-tab and clicking on a different monitor while in native fullscreen modes better * Added "Ghost walk toggle" to in-game cheat menu. Allows you to walk through solid objects and screenlocks * (DinkC) Added support for Dan's load_tile() command +* (Windows) Added support for -game parm to load a DMOD from anywhere on your HD. It also sets + the active DMOD dir to the DMODs parent directory for that session. Automatic state autosave, save/continue and quicksave/quickload work as expected by saving data to its directory +* (bugfix) Save states now properly load even if the DMOD directory has been cut and pasted to a new place +* (bugfix) Full state saves now properly setup backgrounds with correct vision modifications instead of assuming it was 0 +- Due to minor changes in the save state stuff, I've versioned it so the game will refuse to load old versions (as always, this doesn't affect the normal save files, just the full state saves HD does) +* (DinkC) fill_screen works better and colors 0 and 255 are no longer sometimes reversed +* (bugfix) M can now be used to turn off the map, previously it only worked to turn it on +* (bugfix) Status no longer incorrectly draws over full screen bitmaps (like the map in Mystery Island) and is properly reconstructed in full save states diff --git a/source/App.cpp b/source/App.cpp index 617db7e..c7bfd4b 100644 --- a/source/App.cpp +++ b/source/App.cpp @@ -516,6 +516,7 @@ if (GetEmulatedPlatformID() == PLATFORM_ID_IOS) GetAudioManager()->Preload("audio/click.wav"); InitDinkPaths(GetBaseAppPath(), "dink", ""); + GetBaseApp()->m_sig_pre_enterbackground.connect(1, boost::bind(&App::OnPreEnterBackground, this, _1)); diff --git a/source/GUI/AboutMenu.cpp b/source/GUI/AboutMenu.cpp index b6a3f6b..85d2c8b 100644 --- a/source/GUI/AboutMenu.cpp +++ b/source/GUI/AboutMenu.cpp @@ -224,7 +224,7 @@ if (IsDesktop()) "\n`wAuto Save:`` Your game is automatically saved every five minutes to save slot 10 as long as you have more than 30% health.\n"\ "\n`wQuick save/load:`` In addition to the full auto state save whenever you exit the game, and the normal save system, you can use `wQuick Save/Load`` from the pause menu. It's very useful to beat a tough boss. Each add-on you install will also remember its own unique save states as well.\n"\ - "\n`wTo use an existing DMOD directory:`` Start the game with a command line parm of `w-dmodpath `` to use it instead of the default dmod directory.\n"\ + "\n`wTo use an existing DMOD directory:`` Start the game with a command line parm of `w-dmodpath `` to use it instead of the default dmod directory. `w-game `` is also supported to jump right into a dmod.\n"\ ""; } else if (GetEmulatedPlatformID() == PLATFORM_ID_ANDROID) diff --git a/source/GUI/DMODMenu.cpp b/source/GUI/DMODMenu.cpp index 6e2796c..7355ff7 100644 --- a/source/GUI/DMODMenu.cpp +++ b/source/GUI/DMODMenu.cpp @@ -101,6 +101,7 @@ void DMODMenuOnSelect(VariantList *pVList) //0=vec2 point of click, 1=entity sen PopUpCreate(pMenu, "This add-on appears to be missing or damaged. Delete and re-install.", "", "cancel", "Continue", "", "", true); return; } + InitDinkPaths(GetBaseAppPath(), "dink", dmoddir); pMenu = GetEntityRoot()->GetEntityByName("DMODMenu"); @@ -254,7 +255,7 @@ void AddDMODBar(Entity *pParent, float &x, float &y, string title, string descri //processing the icon image might be slow, lets do it a bit later, sequencing the timing by using the y, which should be going up pBG->GetFunction("SetupExtra")->sig_function.connect(&DMODSetupExtra); VariantList vList(pBG); - GetMessageManager()->CallEntityFunction(pBG, 800+count*200, "SetupExtra", &vList); + GetMessageManager()->CallEntityFunction(pBG, 300+count*50, "SetupExtra", &vList); //the delete icon part bool bCanDelete = true; @@ -315,6 +316,7 @@ if (bCanDelete) //add animation effect ZoomToPositionFromThisOffsetEntity(pBG, CL_Vec2f(GetScreenSizeXf(), 0), 500, INTERPOLATE_EASE_TO, 10); } + void GetParsedDMODInfo(string dmodPath, string &nameOut, float versionOut, string ©right, string &dmodwebsite, string &description) { diff --git a/source/GUI/GameMenu.cpp b/source/GUI/GameMenu.cpp index 0e67c04..eab2755 100644 --- a/source/GUI/GameMenu.cpp +++ b/source/GUI/GameMenu.cpp @@ -367,9 +367,6 @@ void OnGameProcessHWKey(VariantList *pVList) { if (pVList->Get(0).GetFloat() != MESSAGE_TYPE_GUI_CHAR) return; - if (DinkCanRunScriptNow()) - { - char c = toupper(char(pVList->Get(2).GetUINT32())); if (c > 28 && c < 255) @@ -386,10 +383,13 @@ void OnGameProcessHWKey(VariantList *pVList) break; default: - DinkLoadPlayerScript(string("key-"+toString(int(c)))); + if (DinkCanRunScriptNow()) + { + DinkLoadPlayerScript(string("key-" + toString(int(c)))); + } } } - } + //LogMsg("Got a %c (%d)", char(pVList->Get(2).GetUINT32()), pVList->Get(2).GetUINT32()); } @@ -1324,6 +1324,7 @@ void GameLoadPiece(VariantList *pVList) if (!bSuccess) { RemoveFile(stateToLoad, false); + WriteLastPathSaved(""); Entity *pMenu = DinkQuitGame(); PopUpCreate(pMenu, "Error loading save state. Probably an older version, sorry.", "", "cancel", "Continue", "", "", true); return; diff --git a/source/GUI/MainMenu.cpp b/source/GUI/MainMenu.cpp index 291801b..6f11597 100644 --- a/source/GUI/MainMenu.cpp +++ b/source/GUI/MainMenu.cpp @@ -19,6 +19,7 @@ bool g_bMainMenuFirstTime = true; bool g_bDidVersionCheck = false; Entity * VersionShowScoreMessage(Entity *pMenu, string msg); +void GetParsedDMODInfo(string dmodPath, string &nameOut, float versionOut, string ©right, string &dmodwebsite, string &description); void ReloadMainMenu(VariantList *pVList) { @@ -41,6 +42,7 @@ void OnVersionDownloadError(VariantList *pVList) //kill current menu GetMessageManager()->CallEntityFunction(pMenu, 1000, "OnDelete", NULL); + pMenu->SetName("MainMenuDelete"); //reload the main menu in a bit @@ -108,6 +110,7 @@ void OnVersionDownloadHTTPFinish(VariantList *pVList) //kill current menu GetMessageManager()->CallEntityFunction(pMenu, 1000, "OnDelete", NULL); + pMenu->SetName("MainMenuDelete"); //reload the main menu in a bit @@ -131,6 +134,7 @@ void MainMenuOnSelect(VariantList *pVList) //0=vec2 point of click, 1=entity sen //slide it off the screen and then kill the whole menu tree SlideScreen(pEntClicked->GetParent(), false); GetMessageManager()->CallEntityFunction(pEntClicked->GetParent(), 500, "OnDelete", NULL); + GameCreate(pEntClicked->GetParent()->GetParent(), 0, ""); GetApp()->GetVar("showViewHint")->Set(uint32(0)); //so this won't be shown here @@ -234,6 +238,7 @@ void MainOnStartLoading(VariantList *pVList) DisableAllButtonsEntity(pBG); SlideScreen(pBG, false); GetMessageManager()->CallEntityFunction(pBG, 500, "OnDelete", NULL); + pBG->SetName("MainMenuDelete"); string fName = GetNextDMODToInstall(); if (!fName.empty()) @@ -246,6 +251,82 @@ void MainOnStartLoading(VariantList *pVList) } +void MainMenuDMODMenuOnSessionNew(VariantList *pVList) +{ + Entity *pMenu = pVList->Get(0).GetEntity(); + + DisableAllButtonsEntity(pMenu); + SlideScreen(pMenu, false); + GetMessageManager()->CallEntityFunction(pMenu, 500, "OnDelete", NULL); + pMenu->SetName("MainMenuDelete"); + + GameCreate(pMenu->GetParent(), 0, ""); +} + +void MainMenuDMODMenuOnSessionContinue(VariantList *pVList) +{ + Entity *pMenu = pVList->Get(0).GetEntity(); + + DisableAllButtonsEntity(pMenu); + SlideScreen(pMenu, false); + GetMessageManager()->CallEntityFunction(pMenu, 500, "OnDelete", NULL); + pMenu->SetName("MainMenuDelete"); + + GameCreate(pMenu->GetParent(), 0, g_dglo.m_savePath + "continue_state.dat"); +} + +void MainMenuDMODCancel(VariantList *pVList) +{ + Entity *pMenu = pVList->Get(0).GetEntity(); + + DisableAllButtonsEntity(pMenu); + SlideScreen(pMenu, false); + GetMessageManager()->CallEntityFunction(pMenu, 500, "OnDelete", NULL); + pMenu->SetName("MainMenuDelete"); + //reload the main menu + MainMenuCreate(pMenu->GetParent()); +} + +void MainOnStartLoadingDMOD(VariantList *pVList) +{ + Entity *pBG = pVList->m_variant[0].GetEntity(); + + string fileName = pVList->m_variant[1].GetString(); + + + //first check to see if it's a valid dmod + string dmoddir = pBG->GetVar("start_full_dmod_dir")->GetString(); + + if (!FileExists(dmoddir + "/dmod.diz")) + { + //don't look valid.. + PopUpCreate(pBG, "The DMOD at "+dmoddir+" appears to be missing or damaged. Ignoring it.", "", "CancelDMODLoad", "Continue", "", "", true); + return; + } + + string dmodName, dmodCopyright, dmodwebsite, description; + float version = 0; + GetParsedDMODInfo(dmoddir, dmodName, version, dmodCopyright, dmodwebsite, description); + + InitDinkPaths(GetBaseAppPath(), "dink", dmoddir); + + //next, see if there is a save-on-quit save state existing for this dmod + if (FileExists(g_dglo.m_savePath + "/continue_state.dat")) + { + PopUpCreate(pBG, "Continue your last session in "+ dmodName+"?", "", "CancelDMODLoad", "Cancel", "SessionContinue", "Continue", true, "SessionNew", "New Game"); + return; + } + + DisableAllButtonsEntity(pBG); + SlideScreen(pBG, false); + GetMessageManager()->CallEntityFunction(pBG, 500, "OnDelete", NULL); + pBG->SetName("MainMenuDelete"); + + GameCreate(pBG->GetParent(), 0, "", "Loading "+dmodName); + +} + + void ImportSaveFileIfApplicable(string fName) { if (GetFileExtension(fName) != "dat") return; @@ -305,6 +386,8 @@ void CheckForImportedSavedGames() } } + + void MainMenuContinueLast(VariantList *pVList) { Entity *pBG = pVList->Get(0).GetEntity(); @@ -321,12 +404,13 @@ void MainMenuContinueLastNewStyle(VariantList *pVList) { Entity *pBG = pVList->Get(0).GetEntity(); + //ClearCommandLineParms(); pBG->GetFunction("OnStartLoading")->sig_function.connect(&MainOnStartLoading); VariantList vList(pBG, ReadLastPathSaved()+string("continue_state.dat")); GetMessageManager()->CallEntityFunction(pBG, 1000, "OnStartLoading", &vList); g_bMainMenuFirstTime = false; - WriteLastPathSaved(""); - LogMsg("Contining"); + //WriteLastPathSaved(""); + LogMsg("Continuing"); } void MainMenuCancelLast(VariantList *pVList) @@ -338,6 +422,7 @@ void MainMenuCancelLast(VariantList *pVList) //kill current menu GetMessageManager()->CallEntityFunction(pMenu, 0, "OnDelete", NULL); + pMenu->SetName("MainMenuDelete"); //reload the main menu MainMenuCreate(pMenu->GetParent()); @@ -452,8 +537,7 @@ Entity * MainMenuCreate( Entity *pParentEnt, bool bFadeIn ) vAboutButPt = CL_Vec2f(512, 454); vOptionsButPt = CL_Vec2f(716, 455); } - - + #ifdef RT_IS_BETA Entity *pText = CreateTextLabelEntity(pBG, "text", GetScreenSizeXf()/2, GetScreenSizeYf()-20, @@ -486,8 +570,36 @@ Entity * MainMenuCreate( Entity *pParentEnt, bool bFadeIn ) SetTouchPaddingEntity(pButtonEntity, CL_Rectf(0, 0, 0, -10)); //no padding, it overlaps other buttons.. pButtonEntity->GetShared()->GetFunction("OnButtonSelected")->sig_function.connect(&MainMenuOnSelect); FadeInEntity(pButtonEntity, false, 300, 1000); + + static bool bOneTimeDMODLoaded = false; + if (!bOneTimeDMODLoaded) + { + bOneTimeDMODLoaded = true; + string dmodfilename; + string dmodDir = GetDMODRootPath(&dmodfilename); + + if (dmodfilename != "") + { + //jump start a DMOD load + pBG->GetFunction("OnStartLoadingDMOD")->sig_function.connect(&MainOnStartLoadingDMOD); + pBG->GetVar("start_full_dmod_dir")->Set(dmodDir + dmodfilename); + pBG->GetVar("start_dmod_dir")->Set(dmodfilename); + + VariantList vList(pBG, string("")); + GetMessageManager()->CallEntityFunction(pBG, 1000, "OnStartLoadingDMOD", &vList); + + pBG->GetFunction("SessionNew")->sig_function.connect(&MainMenuDMODMenuOnSessionNew); + pBG->GetFunction("SessionContinue")->sig_function.connect(&MainMenuDMODMenuOnSessionContinue); + pBG->GetFunction("CancelDMODLoad")->sig_function.connect(&MainMenuDMODCancel); + + return pBG; + } + } + + + if ( ! GetNextDMODToInstall().empty()) { pBG->GetFunction("OnStartLoading")->sig_function.connect(&MainOnStartLoading); @@ -501,13 +613,17 @@ Entity * MainMenuCreate( Entity *pParentEnt, bool bFadeIn ) { PopUpCreate(pBG, "Continue your last session?", "", "CancelLast", "Cancel", "ContinueLast", "Continue", true); return pBG; - } else if (!ReadLastPathSaved().empty()) - { - PopUpCreate(pBG, "Continue your last session?", "", "CancelLast", "Cancel", "ContinueLastNewStyle", "Continue", true); - return pBG; - } else + }; + + if (!ReadLastPathSaved().empty()) { + string lastDMOD = ReadLastPathSaved(); + + PopUpCreate(pBG, "Continue your last session?", "", "CancelLast", "Cancel", "ContinueLastNewStyle", "Continue", true); + return pBG; + } + if (g_bMainMenuFirstTime) { #ifdef RT_MOGA_ENABLED @@ -555,9 +671,8 @@ Entity * MainMenuCreate( Entity *pParentEnt, bool bFadeIn ) pButtonEntity->GetShared()->GetFunction("OnButtonSelected")->sig_function.connect(&MainMenuOnSelect); SetTouchPaddingEntity(pButtonEntity, CL_Rectf(0,0,0,0)); FadeInEntity(pButtonEntity, false, 500, 1500); - DestroyUnusedTextures(); - } + //pButtonEntity = CreateTextButtonEntity(pBG, "Debug", x, y, "Debug and MP3 Music"); y += ySpacer; //pButtonEntity->GetShared()->GetFunction("OnButtonSelected")->sig_function.connect(&MainMenuOnSelect); diff --git a/source/dink/dink.cpp b/source/dink/dink.cpp index e0d43df..73598b4 100644 --- a/source/dink/dink.cpp +++ b/source/dink/dink.cpp @@ -16,7 +16,7 @@ bool pre_figure_out(const char *line, int load_seq, bool bLoadSpriteOnly); #define C_DINK_SCREEN_TRANSITION_TIME_MS 400 -const float SAVE_FORMAT_VERSION = 1.9f; +const float SAVE_FORMAT_VERSION = 2.0f; const int C_DINK_FADE_TIME_MS = 300; const float G_TRANSITION_SCALE_TRICK = 1.01f; @@ -142,7 +142,7 @@ void get_word(char line[300], int word, char *crap); void run_script (int script); void program_idata(void); -void BuildScreenBackground( bool bFullRebuild = true); +void BuildScreenBackground( bool bFullRebuild = true, bool buildImageFromScratch = true); int realhard(int tile); void kill_repeat_sounds_all( void ); int process_line (int script, char *s, bool doelse); @@ -762,9 +762,9 @@ void DrawCollision() } -bool LoadTileScreenIfNeeded(int h, bool &bRequireRebuild) +bool LoadTileScreenIfNeeded(int h, bool &bRequireRebuildOut) { - bRequireRebuild = false; + bRequireRebuildOut = false; string fName = "tiles/ts"; if (h < 10) fName += "0"; @@ -816,7 +816,12 @@ LogMsg("Loading tilescreen %s", fName.c_str()); delete lpDDSBackGround; lpDDSBackGround = InitOffscreenSurface(C_DINK_SCREENSIZE_X, C_DINK_SCREENSIZE_Y, IDirectDrawSurface::MODE_SHADOW_GL, true); - bRequireRebuild = true; + + DDBLTFX ddbltfx; + ddbltfx.dwFillColor = g_dglos.last_fill_screen_palette_color; + lpDDSBackGround->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); + + bRequireRebuildOut = true; } @@ -836,7 +841,11 @@ LogMsg("Loading tilescreen %s", fName.c_str()); //switch it delete lpDDSBackGround; lpDDSBackGround = InitOffscreenSurface(C_DINK_SCREENSIZE_X, C_DINK_SCREENSIZE_Y, IDirectDrawSurface::MODE_SHADOW_GL, true); - bRequireRebuild = true; + bRequireRebuildOut = true; + + DDBLTFX ddbltfx; + ddbltfx.dwFillColor = g_dglos.last_fill_screen_palette_color; + lpDDSBackGround->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); } @@ -906,7 +915,7 @@ void load_map(const int num) // fp = fopen( GetFileLocationString(g_dglos.current_map).c_str(), "rb"); - + //g_dglos.last_fill_screen_palette_color = 0; //it's ok to forget the last fillscreen command if (!pFile) { @@ -934,13 +943,8 @@ void load_map(const int num) while (holdme > 0) { int bytesRead = pFile->Read((byte*)buffer, rt_min(holdme, bufferSize)); - holdme -= bytesRead; - - } - - //Msg("Trying to read %d bytes with offset of %d",lsize,holdme); pFile->Read((byte*)&g_dglos.g_smallMap, lsize); @@ -954,6 +958,7 @@ void load_map(const int num) g_sprite[1].move_nohard = false; g_sprite[1].freeze = false; g_dglos.screenlock = 0; + *pvision = 0; //reset vision fill_whole_hard(); fix_dead_sprites(); check_midi(); @@ -2656,6 +2661,7 @@ void draw_mlevel(int percent, bool bDraw) void draw_status_all(void) { + ClearBitmapCopy(); g_dglos.g_guiStrength = *pstrength; g_dglos.g_guiMagic = *pmagic; @@ -2692,7 +2698,7 @@ void BlitGUIOverlay() if (GetDinkSubGameMode() == DINK_SUB_GAME_MODE_SHOWING_BMP) return; - + if (g_dglos.status_might_not_require_update == 1) return; rtRect32 rcRect; rcRect.left = 0; @@ -5078,16 +5084,24 @@ void draw_sprite_game(LPDIRECTDRAWSURFACE lpdest,int h) LPDIRECTDRAWSURFACE pNewSurf = InitOffscreenSurface(C_DINK_SCREENSIZE_X, C_DINK_SCREENSIZE_Y, IDirectDrawSurface::MODE_SHADOW_GL, true, lpdest->m_pSurf); + + LogMsg("Detected high color bmps that need to drawn to the static landscape, converting backbuffers to 32 bit on the fly."); delete lpDDSBackGround; lpdest = lpDDSBackGround = pNewSurf; + + DDBLTFX ddbltfx; + ddbltfx.dwFillColor = g_dglos.last_fill_screen_palette_color; + lpDDSBackGround->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); + if (lpDDSBuffer->m_pSurf->GetSurfaceType() == SoftSurface::SURFACE_PALETTE_8BIT) { //this one too delete lpDDSBuffer; lpDDSBuffer = InitOffscreenSurface(C_DINK_SCREENSIZE_X, C_DINK_SCREENSIZE_Y, IDirectDrawSurface::MODE_SHADOW_GL, true); lpDDSBuffer->m_pGLSurf->SetUsesAlpha(true); + } } @@ -5515,8 +5529,14 @@ void place_sprites_game(bool bBackgroundOnly ) //Msg("Ok, rank[%d] is %d.",oo,rank[oo]); j = rank[oo]; - - +#ifdef _DEBUG + if (g_dglos.g_smallMap.sprite[j].seq == 66) + { + LogMsg("Garden"); + //bScaledBackgroundSpritesRequired = true; + //continue; + } +#endif if (g_dglos.g_smallMap.sprite[j].active == true) if ( ( g_dglos.g_smallMap.sprite[j].vision == 0) || (g_dglos.g_smallMap.sprite[j].vision == *pvision)) { @@ -5526,11 +5546,16 @@ void place_sprites_game(bool bBackgroundOnly ) if ( (g_dglos.g_smallMap.sprite[j].type == 0) || (g_dglos.g_smallMap.sprite[j].type == 2) ) { + + //make it part of the background (much faster) sprite = add_sprite_dumb(g_dglos.g_smallMap.sprite[j].x,g_dglos.g_smallMap.sprite[j].y,0, g_dglos.g_smallMap.sprite[j].seq,g_dglos.g_smallMap.sprite[j].frame, g_dglos.g_smallMap.sprite[j].size); - //Msg("Background sprite %d has hard of %d..", j, pam.sprite[j].hard); + + + + //("Background sprite %d has hard of %d..", j, pam.sprite[j].hard); g_sprite[sprite].hard = g_dglos.g_smallMap.sprite[j].hard; g_sprite[sprite].sp_index = j; g_sprite[sprite].alt = g_dglos.g_smallMap.sprite[j].alt; @@ -5544,7 +5569,7 @@ void place_sprites_game(bool bBackgroundOnly ) bScaledBackgroundSpritesRequired = true; } - if (bScaledBackgroundSpritesRequired) + if (bScaledBackgroundSpritesRequired) { g_dglo.m_bgSpriteMan.Add(sprite); @@ -5561,6 +5586,7 @@ void place_sprites_game(bool bBackgroundOnly ) add_hardness(sprite,100+j); } + g_sprite[sprite].active = false; } @@ -5671,6 +5697,27 @@ crazy:; } +void SetBitmapCopy(char *pFileName) +{ + + g_dglos.status_might_not_require_update = 1; + strncpy(g_dglos.copy_bmp_to_screen, pFileName, C_SHOWN_BITMAP_SIZE); + +} + +void ClearBitmapCopy() +{ + g_dglos.status_might_not_require_update = 0; + g_dglos.copy_bmp_to_screen[0] = 0; +} + +bool IsBitmapCopySet() +{ + return g_dglos.copy_bmp_to_screen[0] != 0; +} + + + void CopyBitmapToBackBuffer (char *pName) { @@ -5734,7 +5781,7 @@ void copy_bmp( char *pName) if (lpDDSBuffer && lpDDSBuffer->m_pSurf && lpDDSBuffer->m_pSurf->GetSurfaceType() == SoftSurface::SURFACE_RGBA || lpDDSBuffer->m_pSurf->GetSurfaceType() == SoftSurface::SURFACE_RGB) { LogMsg("Warning, losing high color back buffer"); - assert(0); + //assert(0); } SAFE_DELETE(lpDDSBuffer); @@ -5748,10 +5795,17 @@ void copy_bmp( char *pName) ddrval = lpDDSBack->BltFast( 0, 0, lpDDSBuffer, &rcRect, DDBLTFAST_NOCOLORKEY); - assert(!"Clear this?"); + //assert(!"Clear this?"); ddrval = lpDDSBackGround->BltFast( 0, 0, lpDDSBuffer, &rcRect, DDBLTFAST_NOCOLORKEY); - + + /* + g_dglos.g_bShowingBitmap.active = true; + g_dglos.g_bShowingBitmap.showdot = showdot; + g_dglos.g_bShowingBitmap.script = script; + strncpy(g_dglos.g_lastBitmapShown, pNam, C_SHOWN_BITMAP_SIZE - 1); + */ + } @@ -6120,11 +6174,11 @@ bool InitSound() return true; } /* InitSound */ -void BuildScreenBackground( bool bFullRebuild ) +void BuildScreenBackground( bool bFullRebuild, bool bBuildImageFromScratch ) { rtRect32 rcRect; int pa, cool; - *pvision = 0; +// *pvision = 0; //this was bad because save stats call this. Moved to where new maps are loaded if (g_forceRebuildBackground) { @@ -6134,6 +6188,7 @@ void BuildScreenBackground( bool bFullRebuild ) if (bFullRebuild) { + bBuildImageFromScratch = true; #ifdef _DEBUG LogMsg("Doing full rebuild of screen background..."); #endif @@ -6141,35 +6196,53 @@ void BuildScreenBackground( bool bFullRebuild ) kill_repeat_sounds(); kill_all_scripts(); g_dglo.m_bgSpriteMan.Clear(); + + } + + if (bBuildImageFromScratch) + { + + if (lpDDSBackGround) + { + DDBLTFX ddbltfx; + ddbltfx.dwFillColor = g_dglos.last_fill_screen_palette_color; + lpDDSBackGround->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); + } } restart: - int tileScreenID; - - for (int x=0; x<96; x++) + + if (g_dglos.g_gameMode > 2) { - cool = g_dglos.g_smallMap.t[x].num / 128; - pa = g_dglos.g_smallMap.t[x].num - (cool * 128); - rcRect.left = (pa * 50- (pa / 12) * 600); - rcRect.top = (pa / 12) * 50; - rcRect.right = rcRect.left + 50; - rcRect.bottom = rcRect.top + 50; + //we want to render tiles to the BG too - tileScreenID = cool+1; + int tileScreenID; - bool bRequireRebuild; - - if (!LoadTileScreenIfNeeded(tileScreenID, bRequireRebuild)) + for (int x = 0; x < 96; x++) { - continue; - } - - if (bRequireRebuild) goto restart; + cool = g_dglos.g_smallMap.t[x].num / 128; + pa = g_dglos.g_smallMap.t[x].num - (cool * 128); + rcRect.left = (pa * 50 - (pa / 12) * 600); + rcRect.top = (pa / 12) * 50; + rcRect.right = rcRect.left + 50; + rcRect.bottom = rcRect.top + 50; + + tileScreenID = cool + 1; + + bool bRequireRebuild; + + if (!LoadTileScreenIfNeeded(tileScreenID, bRequireRebuild)) + { + continue; + } + + if (bRequireRebuild) goto restart; g_tileScreens[tileScreenID]->UpdateLastUsedTime(); - - lpDDSBackGround->BltFast( (x * 50 - ((x / 12) * 600))+g_gameAreaLeftOffset, (x / 12) * 50, g_tileScreens[tileScreenID], - &rcRect, DDBLTFAST_NOCOLORKEY| DDBLTFAST_WAIT ); + + lpDDSBackGround->BltFast((x * 50 - ((x / 12) * 600)) + g_gameAreaLeftOffset, (x / 12) * 50, g_tileScreens[tileScreenID], + &rcRect, DDBLTFAST_NOCOLORKEY | DDBLTFAST_WAIT); + } } if (bFullRebuild) @@ -6332,12 +6405,13 @@ void add_item(char name[10], int mseq, int mframe, bool magic) void fill_screen(int num) { - //assert(!"Seth, fix this"); - +#ifdef _DEBUG + LogMsg("Filling screen with %d", num); +#endif DDBLTFX ddbltfx; ddbltfx.dwFillColor = num; lpDDSBackGround->Blt(NULL ,NULL,NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); - + /* DDBLTFX ddbltfx; @@ -7027,9 +7101,12 @@ pass: LogMsg("copying BMP"); h = &h[strlen(ev[1])]; int32 p[20] = {2,0,0,0,0,0,0,0,0,0}; + + if (get_parms(ev[1], script, h, p)) { copy_bmp(slist[0]); + SetBitmapCopy(slist[0]); } strcpy(pLineIn, h); @@ -7782,8 +7859,11 @@ pass: int32 p[20] = {1,0,0,0,0,0,0,0,0,0}; if (get_parms(ev[1], script, h, p)) { + g_dglos.last_fill_screen_palette_color = g_nlist[0]; + fill_screen(g_nlist[0]); - g_dglos.m_bRenderBackgroundOnLoad = false; + SetBitmapCopy(""); //no bitmap, but it will trigger the no status bar rendering until "something happens" + g_dglos.m_bRenderBackgroundOnLoad = true; } @@ -10395,7 +10475,9 @@ void init_scripts(void) { if (locate(k,"main")) { - if (debug_mode) LogMsg("Screendraw: running main of script %s..", g_scriptInstance[k]->name); +#ifdef _DEBUG + LogMsg("Screendraw: running main of script %s..", g_scriptInstance[k]->name); +#endif run_script(k); } } @@ -15537,87 +15619,27 @@ void updateFrame() if (g_sprite[i].active) cur = i; } assert(cur <= g_dglos.last_sprite_created); - - //LogMsg("Script: %d, callbacks: %d", GetScriptsActive(), GetCallbacksActive()); - //check_seq_status(18); - //check_seq_status(102); - //check_seq_status(104); - - //FreeSequence(); #endif - bool bSpeedUp = false; - -if (IsDesktop()) -{ - - -#ifdef WIN32 - - //skip the slow ass transition if TAB is held, useful for testing - /* - if (GetAsyncKeyState(9)) + if (DinkGetSpeedUpMode()) { bSpeedUp = true; } - */ -#endif -/* - if (GetAsyncKeyState(VK_F1)) + + if (bSpeedUp) + { + if (!GetApp()->GetGameTickPause()) { - SaveStateWithExtra(); + GetApp()->SetGameTick(GetApp()->GetGameTick() + GetApp()->GetDeltaTick() * 5); } - - if (GetAsyncKeyState(VK_F8)) - { - string fName = DinkGetSavePath()+"quicksave.dat"; - - if (FileExists(fName)) - { - LoadStateWithExtra(); - } else - { - ShowQuickMessage("No state to load yet."); - } - - } -*/ -} -#ifdef _DEBUG -/* - if (GetAsyncKeyState('C')) - { - LogMsg("Writing and loading state"); - - SaveState(GetSavePath()+"state.dat"); - LoadState(GetSavePath()+"state.dat", false); - //DinkUnloadGraphicsCache(); - - } -*/ - - #endif - - - if (DinkGetSpeedUpMode()) - { - bSpeedUp = true; - } - - if (bSpeedUp) - { - if (!GetApp()->GetGameTickPause()) - { - GetApp()->SetGameTick(GetApp()->GetGameTick()+GetApp()->GetDeltaTick()*5); - } - } - byte state[256]; + } + byte state[256]; rtRect32 rcRect; bool bCaptureScreen = false; - int h,j; + int h, j; bool bs[C_MAX_SPRITES_AT_ONCE]; int highest_sprite; @@ -15625,23 +15647,20 @@ if (IsDesktop()) g_abort_this_flip = false; ProcessGraphicGarbageCollection(); - //620 - - + SetOrthoRenderSize(g_dglo.m_orthoRenderRect.right, g_dglo.m_orthoRenderRect.GetHeight(), -g_dglo.m_orthoRenderRect.left, -g_dglo.m_orthoRenderRect.top); - if (5 > 9) + + if (5 > 9) //I'm sorry about this { trigger_start: g_bInitiateScreenMove = false; bCaptureScreen = true; } - check_joystick(); #ifdef C_DINK_KEYBOARD_INPUT - if (GetApp()->GetCheatsEnabled()) { if ( (GetKeyboard(68)) && (GetKeyboard(18)) ) @@ -15665,7 +15684,6 @@ if (GetApp()->GetCheatsEnabled()) } } - #endif if (g_dglos.g_gameMode == 1) @@ -15681,8 +15699,6 @@ if (GetApp()->GetCheatsEnabled()) } - - #ifdef _WIN32 static int LastWindowsTimer = 0; @@ -15718,7 +15734,6 @@ LastWindowsTimer = GetTickCount(); g_dglos.lastTickCount = g_dglos.g_dinkTick; g_dglos.g_dinkTick = GetBaseApp()->GetGameTick(); - int fps_final = g_dglos.g_dinkTick - g_dglos.lastTickCount; @@ -15769,8 +15784,6 @@ LastWindowsTimer = GetTickCount(); update_sound(); - - //TODO Animated tiles //if (IsDesktop()) { @@ -15783,7 +15796,6 @@ LastWindowsTimer = GetTickCount(); //figure out frame rate - if (g_itemScreenActive) { process_item(); @@ -15799,7 +15811,6 @@ LastWindowsTimer = GetTickCount(); ProcessTransition(); - if (g_dglos.process_upcycle) { up_cycle(); @@ -15861,9 +15872,20 @@ LastWindowsTimer = GetTickCount(); // lpDDSBack->BltFast( 0, 0, lpDDSBackGround, &rcRect, DDBLTFAST_NOCOLORKEY); { - rtRect32 rcRectGameArea(g_dglo.m_gameArea.left, g_dglo.m_gameArea.top, g_dglo.m_gameArea.right, g_dglo.m_gameArea.bottom); - lpDDSBack->BltFast(g_dglo.m_gameArea.left, g_dglo.m_gameArea.top, lpDDSBackGround, - &rcRectGameArea, DDBLTFAST_NOCOLORKEY); + +// rtRect32 rcRectGameArea(g_dglo.m_gameArea.left, g_dglo.m_gameArea.top, g_dglo.m_gameArea.right, g_dglo.m_gameArea.bottom); + + //rtRect32 rcRectGameArea(g_dglo.m_nativeGameArea.left, g_dglo.m_nativeGameArea.top, g_dglo.m_nativeGameArea.right, g_dglo.m_nativeGameArea.bottom); + + //rtRect32 rcRectGameArea(g_dglo.m_orthoRenderRect.left, g_dglo.m_nativeGameArea.top, g_dglo.m_nativeGameArea.right, g_dglo.m_nativeGameArea.bottom); + + // lpDDSBack->BltFast(g_dglo.m_gameArea.left, g_dglo.m_gameArea.top, lpDDSBackGround, + // &rcRectGameArea, DDBLTFAST_NOCOLORKEY); + + + lpDDSBack->BltFast(0, 0, lpDDSBackGround, + &g_dglo.m_orthoRenderRect, DDBLTFAST_NOCOLORKEY); + } @@ -16080,6 +16102,7 @@ void SetDefaultVars(bool bFullClear) memset(g_dglo.m_dirInputFinished, 0, sizeof(DINK_INPUT_COUNT*sizeof(bool))); clear_talk(); + no_transition = false; g_abort_this_flip = false; g_dglos.screenlock = 0; @@ -16119,6 +16142,9 @@ void SetDefaultVars(bool bFullClear) g_dglos.cycle_script = 0; g_dglos.but_timer = 0; g_dglo.m_bgSpriteMan.Clear(); + g_dglos.last_fill_screen_palette_color = 0; + g_dglos.copy_bmp_to_screen[0] = 0; + g_dglos.status_might_not_require_update = 0; no_cheat = !GetApp()->GetCheatsEnabled(); g_itemScreenActive = false; @@ -16171,9 +16197,20 @@ string GetDMODStaticRootPath() } -string GetDMODRootPath() +void ClearCommandLineParms() { + + GetBaseApp()->GetCommandLineParms().clear(); +} + +string GetDMODRootPath(string *pDMODNameOutOrNull) +{ + if (pDMODNameOutOrNull) + { + *pDMODNameOutOrNull = ""; + } + #if defined(WIN32) || defined(PLATFORM_HTML5) string dmodpath = "dmods/"; @@ -16204,6 +16241,45 @@ string GetDMODRootPath() } } + if (parms[i] == "-game") + { + if (parms.size() > i + 1) + { + + dmodpath = ""; + for (int n = i + 1; n < parms.size(); n++) + { + dmodpath += parms[n]; + if (n < parms.size() - 1) + { + dmodpath += " "; + } + } + StringReplace("\\", "/", dmodpath); + if (dmodpath[dmodpath.size() - 1] != '/') dmodpath += '/'; //need a trailing slash + + + int len = dmodpath.find_last_of("/", dmodpath.length()-2); + if (len == string::npos) + { + //no demod dir? Weird but ok + if (pDMODNameOutOrNull) + *pDMODNameOutOrNull = dmodpath; + dmodpath = ""; + } + else + { + if (pDMODNameOutOrNull) + *pDMODNameOutOrNull = dmodpath.substr(len + 1, dmodpath.length()); + dmodpath = dmodpath.substr(0, len+1); + } + } + else + { + LogMsg("-game used wrong"); + } + } + } return dmodpath; @@ -16222,10 +16298,10 @@ void InitDinkPaths(string gamePath, string gameDir, string dmodGameDir) string dmodPath; if (!dmodGameDir.empty()) { - dmodPath = RemoveTrailingBackslash(GetPathFromString(dmodGameDir)); + dmodPath = RemoveTrailingBackslash(GetPathFromString(RemoveTrailingBackslash(dmodGameDir))); dmodPath += "/"; //fixing problem with multiple slashes showing up on some OS's and am too lazy to "realyl" fix it or even correct that typo I just made - dmodGameDir = RemoveTrailingBackslash (GetFileNameFromString(dmodGameDir)); + dmodGameDir = RemoveTrailingBackslash (GetFileNameFromString(RemoveTrailingBackslash(dmodGameDir))); if (dmodPath == dmodGameDir) { @@ -16291,8 +16367,10 @@ bool LoadGameChunk(int gameIDToLoad, float &progressOut) //init back buffer at 8 bit, if highcolor is needed later it will auto convert lpDDSBackGround = InitOffscreenSurface(C_DINK_SCREENSIZE_X, C_DINK_SCREENSIZE_Y, IDirectDrawSurface::MODE_SHADOW_GL, false); - fill_screen(0); //fill background with blank to start things off - + DDBLTFX ddbltfx; + ddbltfx.dwFillColor = g_dglos.last_fill_screen_palette_color; + lpDDSBackGround->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); + lpDDSBuffer = InitOffscreenSurface(C_DINK_SCREENSIZE_X, C_DINK_SCREENSIZE_Y, IDirectDrawSurface::MODE_SHADOW_GL); @@ -16721,9 +16799,18 @@ bool LoadHeader(FILE *fp) return false; } + string tempGameDir = g_dglo.m_dmodGameDir; + LoadFromFile(g_dglo.m_dmodGameDir, fp); LoadFromFile(g_dglo.m_gameDir, fp); + if (!FileExists(g_dglo.m_dmodGameDir + "dmod.diz")) + { + LogMsg("DMOD directory invalid. Trying original directory %s instead", g_dglo.m_savePath.c_str()); + g_dglo.m_dmodGameDir = g_dglo.m_savePath; + } + + uint32 gameTime; LoadFromFile(gameTime, fp); GetApp()->SetGameTick(gameTime); @@ -17058,9 +17145,9 @@ bool LoadState(string const &path, bool bLoadPathsOnly) return false; } - if ( g_dglos.g_gameMode > 2 || g_dglos.m_bRenderBackgroundOnLoad) +// if ( g_dglos.g_gameMode > 2 || g_dglos.m_bRenderBackgroundOnLoad) { - BuildScreenBackground(false); + BuildScreenBackground(false, true); } if (g_dglos.g_bShowingBitmap.active) @@ -17322,7 +17409,11 @@ void DinkReInitSurfacesAfterVideoChange() bHighColor = true; SAFE_DELETE(lpDDSBackGround); + LogMsg("Initting Surface after video change"); lpDDSBackGround = InitOffscreenSurface(C_DINK_SCREENSIZE_X, C_DINK_SCREENSIZE_Y, IDirectDrawSurface::MODE_SHADOW_GL, bHighColor); + DDBLTFX ddbltfx; + ddbltfx.dwFillColor = g_dglos.last_fill_screen_palette_color; + lpDDSBackGround->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); g_onePixelSurf.HardKill(); } @@ -17359,6 +17450,10 @@ void DinkOnForeground() { CopyBitmapToBackBuffer(g_dglos.g_lastBitmapShown); } + if (g_dglos.copy_bmp_to_screen[0] != 0) + { + copy_bmp(g_dglos.copy_bmp_to_screen); + } } } diff --git a/source/dink/dink.h b/source/dink/dink.h index c00f5ec..d009f1e 100644 --- a/source/dink/dink.h +++ b/source/dink/dink.h @@ -16,12 +16,14 @@ bool InitDinkEngine(); bool LoadGameChunk(int gameIDToLoad, float &progressOut); //0 for new game void updateFrame(); void finiObjects(); +void ClearCommandLineParms(); + struct SpriteStruct; //finished loading is used with g_dglo.m_curLoadState to fake the loader out #define FINISHED_LOADING 100 - +void ClearBitmapCopy(); enum eDinkInput { @@ -702,7 +704,12 @@ struct DinkGlobalsStatic char g_lastBitmapShown[C_SHOWN_BITMAP_SIZE]; - char m_bufferForExpansion[4968]; + int32 last_fill_screen_palette_color; + + char copy_bmp_to_screen[C_SHOWN_BITMAP_SIZE]; + int32 status_might_not_require_update; + + char m_bufferForExpansion[4835]; }; @@ -720,7 +727,7 @@ bool load_game_small(int num, char * line, int *mytime); void InitDinkPaths(string gamePath, string gameDir, string dmodGameDir); void DinkUnloadGraphicsCache(); void ProcessGraphicGarbageCollection(); -string GetDMODRootPath(); //where dmods are stored +string GetDMODRootPath(string *pDMODNameOutOrNull = NULL); //where dmods are stored bool DinkIsWaitingForSkippableDialog(); bool DinkSkipDialogLine(); //returns true if a line was actually skipped void DinkSetCursorPosition(CL_Vec2f vPos); diff --git a/source/video_gl.cpp b/source/video_gl.cpp index 4e4965a..40ad46b 100644 --- a/source/video_gl.cpp +++ b/source/video_gl.cpp @@ -17,7 +17,7 @@ bool InitializeVideoSystem() g_palette.Init(8,8, SoftSurface::SURFACE_PALETTE_8BIT); g_palette.SetPaletteFromBMP("dink/tiles/palette.bmp", SoftSurface::COLOR_KEY_NONE); - + return true; } @@ -186,6 +186,22 @@ int IDirectDrawSurface::Blt( rtRect32 *pDestRect, IDirectDrawSurface * pSrcSurf, { assert(pFX); assert(pDestRect == NULL && "Well, we only support modifying the entire screen"); + + //don't ask me why, but the original directx had these backwards. Palette is correct + + if (m_pSurf->GetSurfaceType() == SoftSurface::SURFACE_RGB || m_pSurf->GetSurfaceType() == SoftSurface::SURFACE_RGBA) + { + if (pFX->dwFillColor == 0) + { + pFX->dwFillColor = 255; + } + else if (pFX->dwFillColor == 255) + { + pFX->dwFillColor = 0; + } + } + + m_pSurf->FillColor(g_palette.GetPalette()[pFX->dwFillColor]); return DD_OK; } diff --git a/windows_vs2017/winRTDink.vcxproj.user b/windows_vs2017/winRTDink.vcxproj.user index 32afb05..4b1a4fe 100644 --- a/windows_vs2017/winRTDink.vcxproj.user +++ b/windows_vs2017/winRTDink.vcxproj.user @@ -7,5 +7,7 @@ $(ProjectDir) WindowsLocalDebugger + + \ No newline at end of file