Initial commit

This commit is contained in:
2025-07-17 20:36:20 +02:00
commit 069402c4ec
37 changed files with 7849 additions and 0 deletions

478
GameStructure.pbi Normal file
View File

@@ -0,0 +1,478 @@

; 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