; Bonus Enumeration Order must be the same like #Spr_ Enumeration BonusType #Bonus_Health ; Add Health #Bonus_Time ; Slowest Time #Bonus_EarthQuake ; Check Bench and pieces Fall #Bonus_Dead ; All points X2 #Bonus_JewelBlue ; #Bonus_JewelRed ; #Bonus_JewelGreen ; #Bonus_Eye #Bonus_Hammer #Bonus_Remove #Bonus_Gravity #Bonus_Freeze #Bonus_X2 ; All points X4 #Bonus_End EndEnumeration Enumeration Level #Level_Novice #Level_Normal #Level_Hard #Level_Madness EndEnumeration Enumeration Mode #Mode_record #Mode_Intro #Mode_Menu #Mode_Options #Mode_Graphics #Mode_Audios #Mode_Game_Init #Mode_Game_Run #Mode_Game_Wait #Mode_GameOver #Mode_GameOver_End #Mode_EnterYourName #Mode_HallOfFame #Mode_Credits #Mode_JukeBox EndEnumeration Structure Table Sprite.l Selected.l BonusOnThisCase.b EndStructure Structure Difficulty NbLife.l Timer.l TimerDownValue.l WaitMissed.l EarthQuakeTimer.l NbPieceEarthQuake.l DeadBonusWaitTimer.l DeadBonusDuration.l BonusHammerDuration.l BonusRemoveDuration.l NbLittlePiece.l DeadCounter.l ; EndStructure Structure HoF Pseudo.s Score.s PiecesPerMinute.s LoopsPerMinute.s Duration.s Id.s EndStructure Structure ScoreData Pseudo.s Difficulty.l ;Before DifficultyMode Score.l Duration.l PiecesPerMinute.f LoopsPerMinute.f AveragePiecesPerLoop.f NbLoop.l BigestLoopSize.l Bonus_JewelBlue.l Bonus_JewelRed.l Bonus_JewelGreen.l BenchIsEmpty.l Fps_Max.l Fps_Min.l Resolution.s Os.s GameVersion.s ComputerName.s UserName.s PlayerKey.s EndStructure Structure Path BX.l BY.l EndStructure Global NewList LoopPath.Path() Structure Game ;DifficultyMode.l Array Difficulty.Difficulty(#Level_Madness) Array GameTable.Table(#MaxTableWidth+1,#MaxTableHeight+1) BlockMouseX.l ; BlockMouseY.l ; FluidCursor.l ; #True or #False (not .b use .l to be compatible with Option menu) VolumeMusic.l VolumeSfx.l CurrentMusic.l ; Music Id played NextShape.l SelectedShape.l Mode.l ;See enumeration mode ComeFromMode.l ;Last Mode ToggleMode.l LastChangeModeTimer.l WaitTimer.l DisplayMouse.b ; #True or #False Timer.l NextTime.l ;Server ConnectToServer.l ;#True / #False ServerAddress.s List Hof.Hof() LastInsertIdLocal.l LastInsertIdServer.l ;Score ScoreData.ScoreData Life.l Combo.l NbPiecesOnBench.l UnfinishedLoopCount.l NbCross.l ;Display Part DrawMenu.b DrawScore.b DrawBench.b DisplayEarthQuakeFall.b DrawBonus.b DrawTimer.b DisplayMessage.b DisplayCursor.b ;Other DisplayFps.b CaptureMouse.b JukeBoxIndex.l HallOfFameDifficultyMode.l LittlePieceCounter.l StartCalculBonus.b ; #False / #True Wait End Game Over Animation Before Calcul Bonus Warning.s ; Contain Error et Important Message See Mode #Mode_Warning WarningBackMode.l *ObjetVinyl.SpriteData *ObjetBlueJewel.SpriteData *ObjetBlueJewelValue.TextData *ObjetRedJewel.SpriteData *ObjetRedJewelValue.TextData *ObjetGreenJewel.SpriteData *ObjetGreenJewelValue.TextData *ObjetText.TextData[10] EndStructure Global Game.Game Game\LastInsertIdLocal=13 Game\ScoreData\Difficulty=#Level_Normal Game\Difficulty(#Level_Novice)\NbLife=5 Game\Difficulty(#Level_Novice)\Timer=6000 Game\Difficulty(#Level_Novice)\TimerDownValue=20 Game\Difficulty(#Level_Novice)\WaitMissed=3000 Game\Difficulty(#Level_Novice)\EarthQuakeTimer=100000 Game\Difficulty(#Level_Novice)\NbPieceEarthQuake=5 ;Max Nb Piece Fall after EarthQuake Game\Difficulty(#Level_Novice)\DeadBonusWaitTimer=60000 Game\Difficulty(#Level_Novice)\DeadBonusDuration=10000 Game\Difficulty(#Level_Novice)\BonusHammerDuration=20000 Game\Difficulty(#Level_Novice)\BonusRemoveDuration=10000 Game\Difficulty(#Level_Novice)\NbLittlePiece=5 Game\Difficulty(#Level_Novice)\DeadCounter=100 Game\Difficulty(#Level_Normal)\NbLife=3 Game\Difficulty(#Level_Normal)\timer=5000 Game\Difficulty(#Level_Normal)\TimerDownValue=20 Game\Difficulty(#Level_Normal)\WaitMissed=2000 Game\Difficulty(#Level_Normal)\EarthQuakeTimer=60000 Game\Difficulty(#Level_Normal)\NbPieceEarthQuake=10 ;Max Nb Piece Fall after EarthQuake Game\Difficulty(#Level_Normal)\DeadBonusWaitTimer=45000 Game\Difficulty(#Level_Normal)\DeadBonusDuration=20000 Game\Difficulty(#Level_Normal)\BonusHammerDuration=10000 Game\Difficulty(#Level_Normal)\BonusRemoveDuration=8000 Game\Difficulty(#Level_Normal)\NbLittlePiece=4 Game\Difficulty(#Level_Normal)\DeadCounter=60 Game\Difficulty(#Level_Hard)\NbLife=2 Game\Difficulty(#Level_Hard)\timer=4200 Game\Difficulty(#Level_Hard)\TimerDownValue=50 Game\Difficulty(#Level_Hard)\WaitMissed=1000 Game\Difficulty(#Level_Hard)\EarthQuakeTimer=45000 Game\Difficulty(#Level_Hard)\NbPieceEarthQuake=15 ;Max Nb Piece Fall after EarthQuake Game\Difficulty(#Level_Hard)\DeadBonusWaitTimer=30000 Game\Difficulty(#Level_Hard)\DeadBonusDuration=30000 Game\Difficulty(#Level_Hard)\BonusHammerDuration=10000 Game\Difficulty(#Level_Hard)\BonusRemoveDuration=6000 Game\Difficulty(#Level_Hard)\NbLittlePiece=3 Game\Difficulty(#Level_Hard)\DeadCounter=30 Game\Difficulty(#Level_Madness)\NbLife=1 Game\Difficulty(#Level_Madness)\timer=3800 Game\Difficulty(#Level_Madness)\TimerDownValue=50 Game\Difficulty(#Level_Madness)\WaitMissed=500 Game\Difficulty(#Level_Madness)\EarthQuakeTimer=30000 Game\Difficulty(#Level_Madness)\NbPieceEarthQuake=20 ;Max Nb Piece Fall after EarthQuake Game\Difficulty(#Level_Madness)\DeadBonusWaitTimer=20000 Game\Difficulty(#Level_Madness)\DeadBonusDuration=25000 Game\Difficulty(#Level_Madness)\BonusHammerDuration=5000 Game\Difficulty(#Level_Madness)\BonusRemoveDuration=4000 Game\Difficulty(#Level_Madness)\NbLittlePiece=2 Game\Difficulty(#Level_Madness)\DeadCounter=10 Structure Stats StartGameTimer.q StartLoopTimer.q List PieceTime.l() List LoopTime.l() List NbPieces.l() Array NbItemByGroup.l(7) Array NbBonus.l(#Bonus_End) ;To calcul Bonus BigestLoopSize.l NbLoop.l Bonus_JewelBlue.l Bonus_JewelRed.l Bonus_JewelGreen.l BenchIsEmpty.l EndStructure Global Stats.Stats Procedure.s BoolToString(B.b) If B=#True ProcedureReturn "True" Else ProcedureReturn "False" EndIf EndProcedure Procedure.b StringToBool(String.s) String=Trim(UCase(String)) If String="YES" Or String="1" Or String="ENABLE" Or String="TRUE" ProcedureReturn #True Else ProcedureReturn #False EndIf EndProcedure Procedure InitNewResolution() If SelectElement(GUI\ScreenResolution(),GUI\ScreenResolutionIndex) Debug "InitNewReoslution() Screenresolution:"+GUI\ScreenResolution() If LCase(GUI\ScreenResolution())="auto" If ExamineScreenModes() While NextScreenMode() GUI\ScreenResolutionWidth=ScreenModeWidth() GUI\ScreenResolutionHeight=ScreenModeHeight() GUI\ScreenResolutionDepth=ScreenModeDepth() Wend EndIf Else GUI\ScreenResolutionWidth=Val(StringField(GUI\ScreenResolution(),1,"x")) GUI\ScreenResolutionHeight=Val(StringField(GUI\ScreenResolution(),2,"x")) GUI\ScreenResolutionDepth=Val(StringField(StringField(GUI\ScreenResolution(),1,"@"),3,"x")) EndIf EndIf If SelectElement(GUI\WindowResolution(),GUI\WindowResolutionIndex) GUI\WindowResolutionWidth=Val(StringField(GUI\WindowResolution(),1,"x")) GUI\WindowResolutionHeight=Val(StringField(GUI\WindowResolution(),2,"x")) EndIf EndProcedure Procedure.s GetScreenPrint() Protected n.l Protected string.s="" For n=0 To ExamineDesktops()-1 string+DesktopName(n)+":"+DesktopWidth(n)+"x"+DesktopHeight(n)+"x"+DesktopDepth(n)+"@"+DesktopFrequency(n)+"PosX="+DesktopX(n)+"&PosY="+DesktopY(n) Next ProcedureReturn StringFingerprint(string, #PB_Cipher_MD5) EndProcedure Procedure LoadPrefs() If FileSize(GetPDataDirectory("Loopz.ini"))=-1 If CreatePreferences(GetPDataDirectory("Loopz.ini")) Debug "LoadPrefs() Create Loopz.ini >"+GetPDataDirectory("Loopz.ini") WritePreferenceString("FullScreen","True") WritePreferenceString("ScreenResolution","Auto") WritePreferenceString("VolumeMusic","70") WritePreferenceString("VolumeSfx","100") WritePreferenceLong("LastInsertIdServer",-1) WritePreferenceLong("LastInsertIdLocal",-1) WritePreferenceString ("LastPseudoUsed","") WritePreferenceString ("PlayerKey","") ClosePreferences() Else Debug "LoadPrefs() Can't Create Loopz.ini >"+GetPDataDirectory("Loopz.ini") EndIf EndIf If OpenPreferences(GetPDataDirectory("Loopz.ini")) Debug "LoadPrefs() Load Loopz.ini >"+GetPDataDirectory("Loopz.ini") GUI\FullScreen=StringToBool(ReadPreferenceString("FullScreen","True")) Protected.l ScreenResolution.s,WindowResolution.s ScreenResolution=ReadPreferenceString("ScreenResolution","Auto") Game\FluidCursor=StringToBool(ReadPreferenceString("FluidCursor","True")) Game\VolumeMusic=Int(ReadPreferenceLong("VolumeMusic",100)/10) Game\VolumeSfx=Int(ReadPreferenceLong("VolumeSfx",100)/10) Game\LastInsertIdServer=ReadPreferenceLong("LastInsertIdServer",-1) Game\LastInsertIdLocal=ReadPreferenceLong("LastInsertIdLocal",-1) Game\ScoreData\Pseudo=ReadPreferenceString ("LastPseudoUsed","") Game\ScoreData\PlayerKey=ReadPreferenceString ("PlayerKey","") ;Set Resolution If LCase(ScreenResolution)="auto" Protected.l SWidth,SHeight,SDepth,SFreq If ExamineScreenModes() ;Select Last ScreenMode (Higer) While NextScreenMode() SWidth=ScreenModeWidth() SHeight=ScreenModeHeight() SDepth=ScreenModeDepth() SFreq=ScreenModeRefreshRate() Wend EndIf ScreenResolution=Str(SWidth)+"x"+Str(SHeight)+"x"+Str(SDepth)+"@"+Str(SFreq)+"Hz" GUI\ScreenResolutionIndex=0 ;If resolution is defined Like WidthxHeightxDepth@FreqHz Else GUI\ScreenResolutionIndex=-1 ;Check If resolution exist in ForEach GUI\ScreenResolution() If LCase(GUI\ScreenResolution())=LCase(ScreenResolution) GUI\ScreenResolutionIndex=ListIndex(GUI\ScreenResolution()) Break EndIf Next ;If No ScreenResolution No Found If GUI\ScreenResolutionIndex=-1 GUI\ScreenResolutionIndex=0 EndIf EndIf If SelectElement(GUI\ScreenResolution(),GUI\ScreenResolutionIndex) Debug "LoadPrefs() Screenresolution:"+GUI\ScreenResolution() Else Debug "LoadPrefs() Screenresolution:Error" EndIf ;Window PreferenceGroup("ConfigScreens:"+GetScreenPrint()) GUI\WindowX=Val(ReadPreferenceString ("WindowX","-1" )) GUI\WindowY=Val(ReadPreferenceString("WindowY","-1" )) Debug "LoadPrefs() WindowX="+Str(GUI\WindowX) Debug "LoadPrefs() WindowY="+Str(GUI\WindowY) WindowResolution=ReadPreferenceString("WindowResolution","1024x576") GUI\WindowResolutionIndex=-1 ForEach GUI\WindowResolution() If LCase(GUI\WindowResolution())=LCase(WindowResolution) GUI\WindowResolutionIndex=ListIndex(GUI\WindowResolution()) Break EndIf Next If GUI\WindowResolutionIndex=-1 GUI\WindowResolutionIndex=2 ; default 1024x576 EndIf PreferenceGroup("Server") CompilerIf #UsePreProdServer=#True Game\ServerAddress=#PreProdServerURL CompilerElse Game\ServerAddress=ReadPreferenceString ("URL","https://loopzdb.thyphoon.net/LoopzServer.php" ) CompilerEndIf Game\ConnectToServer=StringToBool(ReadPreferenceString ("ConnectToServer","True" )) InitNewResolution() ClosePreferences() EndIf EndProcedure Procedure SavePrefs() Debug "SavePref():"+GetPDataDirectory("Loopz.ini") If OpenPreferences(GetPDataDirectory("Loopz.ini")) WritePreferenceString ("FullScreen", BoolToString(GUI\FullScreen)) If SelectElement(GUI\ScreenResolution(),GUI\ScreenResolutionIndex) WritePreferenceString ("ScreenResolution", GUI\ScreenResolution()) Debug "SavePrefs() ScreenResolution="+GUI\ScreenResolution() Else Debug "ERROR: SavePrefs() GUI\ScreenResolutionIndex="+Str(GUI\ScreenResolutionIndex) EndIf WritePreferenceString ("FluidCursor", BoolToString(Game\FluidCursor)) WritePreferenceLong("VolumeMusic",Game\VolumeMusic*10) WritePreferenceLong("VolumeSfx",Game\VolumeSfx*10) WritePreferenceLong("LastInsertIdServer",Game\LastInsertIdServer) WritePreferenceLong("LastInsertIdLocal",Game\LastInsertIdLocal) WritePreferenceString ("LastPseudoUsed",Game\ScoreData\Pseudo) PreferenceGroup("ConfigScreens:"+GetScreenPrint()) Debug "Prefs ScreenPrint:"+GetScreenPrint() If SelectElement(GUI\WindowResolution(),GUI\WindowResolutionIndex) WritePreferenceString ("WindowResolution", GUI\WindowResolution()) Debug "SavePrefs() WindowResolution="+GUI\WindowResolution() Else Debug "ERROR: SavePrefs() GUI\WindowResolutionIndex="+Str(GUI\WindowResolutionIndex) EndIf WritePreferenceLong ("WindowX", GUI\WindowX) WritePreferenceLong("WindowY", GUI\WindowY) PreferenceGroup("Server") WritePreferenceString ("URL",Game\ServerAddress) WritePreferenceString ("ConnectToServer",BoolToString(Game\ConnectToServer)) ClosePreferences() Else MessageRequester("Prefs Error","Can't Save "+GetPDataDirectory("Loopz.ini")) EndIf EndProcedure ;Bonus random Position ; https://stackoverflow.com/questions/196017/unique-non-repeating-random-numbers-in-o1 #TableWidht=#MaxTableWidth+1 #TableHeight=#MaxTableHeight+1 #TableIndexMax=#TableWidht*#TableHeight-1 Structure RandomUniq Array DataList.l(#TableIndexMax) Index.l EndStructure Global RandomUniq.RandomUniq Procedure RandUniq() ;Randomize datas Protected Max.l,Index.l If RandomUniq\Index=0 For Max=#TableIndexMax To 0 Step -1 Swap RandomUniq\DataList(Max),RandomUniq\DataList(Random(#TableIndexMax)) Next RandomUniq\Index=#TableIndexMax EndIf Index=RandomUniq\Index RandomUniq\Index-1 ProcedureReturn RandomUniq\DataList(Index) EndProcedure Define n.l For n=0 To #TableIndexMax RandomUniq\DataList(n)=n Next ; IDE Options = PureBasic 6.11 LTS (Windows - x64) ; CursorPosition = 398 ; FirstLine = 394 ; Folding = -- ; EnableXP ; DPIAware