Add projects including README.md(s), .gitignore(s) and the actual project files.

Signed-off-by: Michael Fabian Dirks <michael.dirks@project-kube.de>
This commit is contained in:
Michael Fabian Dirks
2014-11-24 18:18:24 +01:00
parent 934da62076
commit 8f3114e377
170 changed files with 22028 additions and 3 deletions
@@ -0,0 +1,124 @@
Strict
Import BRL.Stream
Import BRL.Retro
Function FileMD5$(filePath$, bufferSize=$400000)
Assert (bufferSize & 63) = 0 Else "bufferSize must be a multiple of 64 bytes"
Local h0 = $67452301, h1 = $EFCDAB89, h2 = $98BADCFE, h3 = $10325476
Local r[] = [7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,..
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,..
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,..
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21]
Local k[] = [$D76AA478, $E8C7B756, $242070DB, $C1BDCEEE, $F57C0FAF, $4787C62A,..
$A8304613, $FD469501, $698098D8, $8B44F7AF, $FFFF5BB1, $895CD7BE,..
$6B901122, $FD987193, $A679438E, $49B40821, $F61E2562, $C040B340,..
$265E5A51, $E9B6C7AA, $D62F105D, $02441453, $D8A1E681, $E7D3FBC8,..
$21E1CDE6, $C33707D6, $F4D50D87, $455A14ED, $A9E3E905, $FCEFA3F8,..
$676F02D9, $8D2A4C8A, $FFFA3942, $8771F681, $6D9D6122, $FDE5380C,..
$A4BEEA44, $4BDECFA9, $F6BB4B60, $BEBFBC70, $289B7EC6, $EAA127FA,..
$D4EF3085, $04881D05, $D9D4D039, $E6DB99E5, $1FA27CF8, $C4AC5665,..
$F4292244, $432AFF97, $AB9423A7, $FC93A039, $655B59C3, $8F0CCC92,..
$FFEFF47D, $85845DD1, $6FA87E4F, $FE2CE6E0, $A3014314, $4E0811A1,..
$F7537E82, $BD3AF235, $2AD7D2BB, $EB86D391]
Local fileStream:TStream = OpenStream(filePath$, True, False)
If fileStream = Null Then Return
Local buffer:Byte Ptr = MemAlloc(bufferSize)
Local bitCount:Long, dataTop = bufferSize
Repeat
Local bytesRead = fileStream.Read(buffer, bufferSize)
If fileStream.EOF()
dataTop = (((bytesRead + 8) Shr 6) + 1) Shl 6
If dataTop > bufferSize
buffer = MemExtend(buffer, bufferSize, dataTop)
EndIf
bitCount :+ (bytesRead Shl 3)
For Local b = (bytesRead + 1) Until (dataTop - 8)
buffer[b] = 0
Next
buffer[bytesRead] = $80
LEPokeLong(buffer, dataTop - 8, bitCount)
Else
bitCount :+ (bufferSize Shl 3)
EndIf
For Local chunkStart=0 Until (dataTop Shr 2) Step 16
Local a = h0, b = h1, c = h2, d = h3
For Local i=0 To 15
Local f = d ~ (b & (c ~ d))
Local t = d
d = c ; c = b
b = Rol((a + f + k[i] + LEPeekInt(buffer, (chunkStart + i) Shl 2)), r[i]) + b
a = t
Next
For Local i=16 To 31
Local f = c ~ (d & (b ~ c))
Local t = d
d = c ; c = b
b = Rol((a + f + k[i] + LEPeekInt(buffer, (chunkStart + (((5 * i) + 1) & 15)) Shl 2)), r[i]) + b
a = t
Next
For Local i=32 To 47
Local f = b ~ c ~ d
Local t = d
d = c ; c = b
b = Rol((a + f + k[i] + LEPeekInt(buffer, (chunkStart + (((3 * i) + 5) & 15)) Shl 2)), r[i]) + b
a = t
Next
For Local i=48 To 63
Local f = c ~ (b | ~d)
Local t = d
d = c ; c = b
b = Rol((a + f + k[i] + LEPeekInt(buffer, (chunkStart + ((7 * i) & 15)) Shl 2)), r[i]) + b
a = t
Next
h0 :+ a ; h1 :+ b
h2 :+ c ; h3 :+ d
Next
Until fileStream.EOF()
fileStream.Close()
MemFree(buffer)
Return (LEHex(h0) + LEHex(h1) + LEHex(h2) + LEHex(h3)).ToLower()
End Function
Function Rol(val, shift)
Return (val Shl shift) | (val Shr (32 - shift))
End Function
Function LEPeekInt(buffer:Byte Ptr, offset)
Return (buffer[offset + 3] Shl 24) | (buffer[offset + 2] Shl 16) | ..
(buffer[offset + 1] Shl 8) | buffer[offset]
End Function
Function LEPokeLong(buffer:Byte Ptr, offset, value:Long)
For Local b=7 To 0 Step -1
buffer[offset + b] = (value Shr (b Shl 3)) & $ff
Next
End Function
Function LEHex$(val)
Local out$ = Hex(val)
Return out$[6..8] + out$[4..6] + out$[2..4] + out$[0..2]
End Function
@@ -0,0 +1,197 @@
'Function DebugProgressCB:Int(data:Object,dltotal:Double,dlnow:Double,ultotal:Double,ulnow:Double)
' DebugLog "dltotal="+Int(dltotal)+",dlnow="+Int(dlnow)+",ultotal="+Int(ultotal)+",ulnow="+Int(ulnow)
'EndFunction
Rem
Type TTaskPatchCheck Extends TTaskPatch
Field m_stFile:String
Field m_stHash:String
Field l_bValid:Byte = True
Method Run()
' Retrieve Hash
Local stHash:String = FileMD5(m_stFile).ToUpper();l_fProgress = 0.5
' Compare Hash
If stHash <> m_stHash Then
l_bValid = False
oPatchListMutex.Lock()
oPatchList.AddLast(m_stFile)
oPatchListMutex.Unlock()
EndIf
l_fProgress = 1.0
EndMethod
Function Create:TTask(File:String, Hash:String)
Local oTask:TTaskPatchCheck = New TTaskPatchCheck
oTask.m_stFile = File
oTask.m_stHash = Hash
Return oTask
EndFunction
EndType
Type TTaskPatchFile Extends TTaskPatch
Field m_stFile:String
Method Run()
Local oCurl:TCurlEasy = New TCurlEasy
oCurl.setOptInt(CURLOPT_FOLLOWLOCATION, 1)
oCurl.setOptString(CURLOPT_USERAGENT, "Sirius Online Launcher")
oCurl.setOptString(CURLOPT_REFERER, TPatcher_Server)
oCurl.setOptString(CURLOPT_URL, TPatcher_Server + m_stFile)
oCurl.setWriteString()
EndMethod
Function Create:TTask(File:String)
Local oTask:TTaskPatchFile = New TTaskPatchFile
oTask.m_stFile = File
Return oTask
EndFunction
EndType
Rem
Import BRL.LinkedList
Const TPatcher_MaxParallelTasks:Int = 4
Const TPatcher_Server:String = "http://sirius-online.us.to/patch/"
Type TPatcher
' TCurlMulti Instance for non-blocking IO.
Field oCurlMulti:TCurlMulti = TCurlMulti.Create()
' List of available tasks and active tasks.
Field oTasks:TList = (New TList)
Field oTaskSlots:TTaskSlot[] = New TTaskSlot[TPatcher_MaxParallelTasks]
Field oTasksDone:TList = (New TList)
Method New()
For Local i:Int = 0 Until TPatcher_MaxParallelTasks
oTaskSlots[i].oCurl = oCurlMulti.newEasy()
next
oTasks.AddLast(TTask_PatchInfo.Create())
EndMethod
' Main loop for TPatcher
Method Perform()
Local runningHandles:Int
If oTaskSlots[0].oTask <> Null or oTaskSlots[1].oTask <> Null or oTaskSlots[2].oTask <> Null or oTaskSlots[3].oTask <> Null Then
Local iResult:Int = CURLM_OK
Repeat
iResult = oCurlMulti.multiPerform(runningHandles)
For Local slot:Int = 0 Until TPatcher_MaxParallelTasks
If oTaskSlots[slot].oTask = Null And oTasks.Count() > 0 Then
oTaskSlots[slot].oTask = TTask(oTasks.RemoveLast())
oTaskSlots[slot].oTask.Initialize(Self, oTaskSlots[slot].oCurl)
ElseIf oTaskSlots[slot].oTask <> Null Then
If oTaskSlots[slot].oTask.bComplete = True Then
oTasksDone.AddLast(oTaskSlots[slot].oTask)
oTaskSlots[slot].oTask = Null
' Restore TCurlEasy to useable state.
oCurlMulti.multiRemove(oTaskSlots[slot].oCurl)
oTaskSlots[slot].oCurl.cleanup()
oCurlMulti.multiAdd(oTaskSlots[slot].oCurl)
EndIf
Endif
Next
Until iResult <> CURLM_CALL_MULTI_PERFORM
Else
oCurlMulti.cleanup()
EndIf
EndMethod
EndType
Type TTaskSlot
Field oTask:TTask
Field oCurl:TCurlEasy
EndType
Type TTask Abstract
Field oPatcher:TPatcher = Null
Field stName:String = "Unknown"
Field bComplete:Byte = False
Field fProgress:Float = 0.0
Method Initialize(oPatcher:TPatcher, oCurl:TCurlEasy)
Self.oPatcher = oPatcher
oCurl.setWriteCallback(_HandleWriteCallback, Self)
oCurl.setProgressCallback(_HandleProgressCallback, Self)
EndMethod
Method HandleProgressCallback:Int(dltotal:Double, dlnow:Double, ultotal:Double, ulnow:Double)
fProgress = dlnow / dltotal
If dlnow = dltotal Then bComplete = True
EndMethod
Method HandleWriteCallback:Int(buffer:Byte Ptr, size:Int)
EndMethod
Function _HandleProgressCallback:Int(Data:Object, dltotal:Double, dlnow:Double, ultotal:Double, ulnow:Double)
Local Task:TTask = TTask(Data)
Return Task.HandleProgressCallback(dltotal, dlnow, ultotal, ulnow)
EndFunction
Function _HandleWriteCallback(buffer:Byte Ptr, size:Int, Data:Object)
Local Task:TTask = TTask(Data)
Return Task.HandleWriteCallback(buffer, size)
EndFunction
EndType
Type TTask_PatchInfo Extends TTask
Method New()
Self.stName = "Retrieving Patch Information"
EndMethod
Method Initialize(oPatcher:TPatcher, oCurl:TCurlEasy)
Super.Initialize(oPatcher, oCurl)
oCurl.setOptInt(CURLOPT_FOLLOWLOCATION, 1)
oCurl.setOptString(CURLOPT_USERAGENT, "Sirius Online Launcher")
oCurl.setOptString(CURLOPT_REFERER, TPatcher_Server)
oCurl.setOptString(CURLOPT_URL, TPatcher_Server + "info")
oCurl.setWriteString()
EndMethod
Method HandleProgressCallback:Int(dltotal:Double, dlnow:Double, ultotal:Double, ulnow:Double)
Super.HandleProgressCallback()
If bComplete = True Then
EndIf
EndMethod
Function Create:TTask()
Return (New TTask_PatchInfo)
EndFunction
EndType
Type TTask_File Extends TTask
Field stHash:String
Field stFile:String
Method Initialize(oPatcher:TPatcher, oCurl:TCurlEasy)
Super.Initialize(oPatcher, oCurl)
oCurl.setOptInt(CURLOPT_FOLLOWLOCATION, 1)
oCurl.setOptString(CURLOPT_USERAGENT, "Sirius Online Launcher")
oCurl.setOptString(CURLOPT_REFERER, TPatcher_Server + "info")
'Local oFileStream:TStream =
oCurl.setWriteString()
EndMethod
Method HandleProgressCallback:Int(dltotal:Double, dlnow:Double, ultotal:Double, ulnow:Double)
Super.HandleProgressCallback()
EndMethod
Function Create:TTask(File:String, Hash:String)
Local oTask:TTask_File = New TTask_File
oTask.stHash = Hash
oTask.stFile = File
oCurl.setOptString(CURLOPT_URL, TPatcher_Server + oTask.File)
Return oTask
EndFunction
EndType
EndRem
@@ -0,0 +1,242 @@
SuperStrict
Import BRL.Threads
Import BRL.LinkedList
Import BRL.StandardIO
Const DEF_THREADPOOL_MINTHREADS:Int = 1
Const DEF_THREADPOOL_MAXTHREADS:Int = 4
Type TThreadPool
' Threads
Field m_oThreads:TList = New TList
Field m_iMinThreads:Int = DEF_THREADPOOL_MINTHREADS
Field m_iMaxThreads:Int = DEF_THREADPOOL_MAXTHREADS
' Task Queue
Field m_oTaskList:TList = New TList
Field m_oTaskMutex:TMutex = TMutex.Create()
' Construction
Function Create:TThreadPool(iMinThreads:Int = DEF_THREADPOOL_MINTHREADS, iMaxThreads:Int = DEF_THREADPOOL_MAXTHREADS)
Local oThreadPool:TThreadPool = New TThreadPool
oThreadPool.SetLimits(iMinThreads, iMaxThreads)
Return oThreadPool
EndFunction
' Destruction
Method Destroy()
For Local oThreadWorker:TThreadWorker = EachIn m_oThreads
oThreadWorker.ForceDestroy()
Next
m_oThreads.Clear()
m_oTaskList.Clear()
EndMethod
' Change the thread limits, for example when the game configuration changes. Effective immediately or after
Method SetLimits(iMinThreads:Int = DEF_THREADPOOL_MINTHREADS, iMaxThreads:Int = DEF_THREADPOOL_MAXTHREADS)
m_iMinThreads = iMinThreads
If (iMaxThreads < iMinThreads) Then iMaxThreads = iMinThreads
m_iMaxThreads = iMaxThreads
EndMethod
' Add new Task to the queue.
Method AddTask(oTask:TTask)
m_oTaskMutex.Lock()
m_oTaskList.AddLast(oTask)
m_oTaskMutex.Unlock()
EndMethod
' Distributes work across threads, destroys and spawns threads
Method Update:Int()
Local iThreadCount:Int = m_oThreads.Count()
' Spawn more Threads if we don't have at least m_iMinThreads
If iThreadCount < m_iMinThreads Then
Local iSpawnCount:Int = m_iMinThreads - iThreadCount
For Local spawn:Int = 1 To iSpawnCount
m_oThreads.AddLast(New TThreadWorker)
iThreadCount :+ 1
Next
EndIf
For Local oThreadWorker:TThreadWorker = EachIn m_oThreads
' Loosely enforce m_iMaxThreads by destroying unused Threads.
If iThreadCount > m_iMaxThreads And oThreadWorker.m_oAvailable.TryLock() = True Then
If oThreadWorker.m_oTask = Null Then
oThreadWorker.m_oAvailable.Unlock()
oThreadWorker.Destroy()
m_oThreads.Remove(oThreadWorker)
iThreadCount :- 1
Exit
EndIf
EndIf
' Distribute available work.
m_oTaskMutex.Lock()
If m_oTaskList.Count() > 0 And oThreadWorker.m_oAvailable.TryLock() = True Then
oThreadWorker.m_oAvailable.Unlock()
Local oTask:TTask = TTask(m_oTaskList.RemoveFirst())
If oThreadWorker.AssignTask(oTask) = False Then m_oTaskList.AddLast(oTask)
EndIf
m_oTaskMutex.Unlock()
' Destroy Threads that have been waiting too long on Work, given that they are unneeded.
If iThreadCount > m_iMinThreads And oThreadWorker.m_oAvailable.TryLock() = True Then
oThreadWorker.m_oAvailable.Unlock()
If oThreadWorker.m_oTask = Null And (MilliSecs() - oThreadWorker.m_lTaskTime) > 5000 Then
m_oThreads.Remove(oThreadWorker)
oThreadWorker.Destroy()
iThreadCount :- 1
EndIf
EndIf
Next
' Spawn more Threads if we did not hit m_iMaxThreads and there is still work left.
m_oTaskMutex.Lock()
If m_oTaskList.Count() > 0 And iThreadCount < m_iMaxThreads Then
Local iSpawnCount:Int = Min(m_oTaskList.Count(), m_iMaxThreads - iThreadCount)
For Local spawn:Int = 1 To iSpawnCount
m_oThreads.AddLast(New TThreadWorker)
iThreadCount :+ 1
Next
EndIf
m_oTaskMutex.Unlock()
Return iThreadCount
EndMethod
Method CountTasks:Int()
Local retVal:Int = 0
m_oTaskMutex.Lock()
retVal = m_oTaskList.Count()
m_oTaskMutex.Unlock()
Return retVal
EndMethod
Method CountActiveTasks:Int()
Local retVal:Int = 0
For Local oThreadWorker:TThreadWorker = EachIn m_oThreads
oThreadWorker.m_oAvailable.Lock()
If oThreadWorker.m_oTask <> Null Then retVal :+ 1
oThreadWorker.m_oAvailable.Unlock()
Next
Return retVal
EndMethod
EndType
Type TThreadWorker
Field m_oThread:TThread
' Used to make the Thread sleep and work.
Field m_oAvailable:TMutex
Field m_oCondVar:TCondVar
' Contains Task and the time it was assigned at.
Field m_oTask:TTask
Field m_lTaskTime:Long
Field d_iCount:Int
' Construction
Method New()
m_oAvailable = TMutex.Create()
m_oCondVar = TCondVar.Create()
m_oThread = TThread.Create(Execute, Self)
m_lTaskTime = MilliSecs()
EndMethod
' Destruction
Method Destroy()
While AssignTask(oTaskTerminate) = False
Delay 10
Wend
m_oThread.Wait() 'broken?
m_oThread.Detach()
EndMethod
Method ForceDestroy()
m_oThread.Detach()
EndMethod
' Task Management
Method AssignTask:Int(oTask:TTask)
If m_oAvailable.TryLock() = True And m_oTask = Null Then
m_oTask = oTask
m_lTaskTime = MilliSecs()
m_oAvailable.Unlock()
m_oCondVar.Signal()
Return True
EndIf
Return False
EndMethod
' Thread Wrapper Function
Function Execute:Object(Data:Object)
Local oThreadWorker:TThreadWorker = TThreadWorker(Data)
Local oTask:TTask = Null
oThreadWorker.m_oAvailable.Lock()
Repeat
oThreadWorker.m_oCondVar.Wait(oThreadWorker.m_oAvailable)
If oThreadWorker.m_oTask <> Null Then
oThreadWorker.d_iCount :+ 1
oTask = oThreadWorker.m_oTask
oThreadWorker.m_oAvailable.Unlock()
oTask.Run()
oThreadWorker.m_oAvailable.Lock()
oThreadWorker.m_oTask = Null
EndIf
Until oTask = oTaskTerminate
oThreadWorker.m_oAvailable.Unlock()
EndFunction
EndType
Type TTask Abstract
' Called when a thread is working on this item.
Method Run()
EndMethod
EndType
Type TTaskTerminate Extends TTask
EndType
Global oTaskTerminate:TTask = New TTaskTerminate
Type TTaskPtr Extends TTask
Field m_pFunc:Object(data:Object)
Field m_pData:Object
Field m_pReturn:Object
' Construction
Function Create:TTask(pFunc:Object(data:Object), pData:Object)
Local oTWPtr:TTaskPtr = New TTaskPtr
oTWPtr.SetFunction(pFunc)
oTWPtr.SetData(pData)
Return oTWPtr
EndFunction
' Called when a thread is working on this item.
Method Run()
m_pReturn = m_pFunc(m_pData)
EndMethod
' Set the Function executed by Run()
Method SetFunction(pFunc:Object(data:Object))
m_pFunc = pFunc
EndMethod
' Set the Data passed to the Function.
Method SetData(pData:Object)
m_pData = pData
EndMethod
' Retrieve the return value of the executed Function
Method GetReturn:Object()
Return m_pReturn
EndMethod
EndType
Global PrintMutex:TMutex = TMutex.Create()
Function _Print(Str:String)
PrintMutex.Lock()
Print(Str)
PrintMutex.Unlock()
EndFunction
+14
View File
@@ -0,0 +1,14 @@
#include <brl.mod/blitz.mod/blitz.h>
#include <time.h>
int getClocksPerSecond_() {
return CLOCKS_PER_SEC;
}
int getClock_() {
return (int)clock();
}
int getClockDiff_(int clockStart, int clockEnd) {
return ((clock_t)clockEnd - (clock_t)clockStart);
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 817 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 677 KiB

@@ -0,0 +1,488 @@
SuperStrict
' Modules and Includes -----------------------------------------------------------------------------------------------------------------------------------------
Framework BRL.Blitz
Import BRL.StandardIO
Import BRL.Timer
Import BRL.Max2D
Import BRL.GLMax2D
Import BRL.Event
Import BRL.EventQueue
Import PUB.FreeProcess
Import MaxGUI.MaxGUI
Import MaxGUI.Drivers
' Libraries
Import "TGUI.bmx"
Import "Max2DExtended.bmx"
' Resources -----------------------------------------------------------------------------------------------------------------------------------------------------
' Binary Resources
Incbin "GFX/LNC/GUIxSTYLE.png"
Incbin "SFX/M/launcher.ogg"
' Initialization ------------------------------------------------------------------------------------------------------------------------------------------------
SetGraphicsDriver(GLMax2DDriver())
' Create Timers to reduce CPU load.
Global tmrRender:TTimer = CreateTimer(20) ' One for rendering the GUI
Global tmrUpdate:TTimer = CreateTimer(100) ' And one for working.
' Create the Window and Canvas for the Patcher, set the Graphics Driver to OpenGL and enable polled input.
Global gdgPatcher:TGadget = CreateWindow("Sirius Online", 0, 0, 720, 460, Desktop(), WINDOW_CLIENTCOORDS | WINDOW_CENTER | WINDOW_HIDDEN)
Global gdgCanvas:TGadget = CreateCanvas(0, 0, ClientWidth(gdgPatcher), ClientHeight(gdgPatcher), gdgPatcher)
SetGraphics(gdgCanvas) ' Change OpenGL Context to the Canvas.
EnablePolledInput(gdgCanvas) ' Enable input handling for the Canvas.
DebugLog TShader.CheckCompatability()
End
Rem
' Load our GUI Style and split it into the required images.
Global guiStyle:TPixmap = LoadPixmap("GFX/LNC/GUIxSTYLE.png")
If guiStyle = Null Then guiStyle = LoadPixmap("incbin::GFX/LNC/GUIxSTYLE.png")
Global guiWindowBackground:TImage = LoadImage(guiStyle.Window(0, 0, 32, 32), FILTEREDIMAGE)
Global guiWindowShade:TImage[] = New TImage[2]
guiWindowShade[0] = LoadImage(guiStyle.Window(32, 0, 16, 16), FILTEREDIMAGE)
guiWindowShade[1] = LoadImage(guiStyle.Window(32, 16, 16, 16), FILTEREDIMAGE)
Global guiWindowTitleBar:TImage[] = New TImage[2]
guiWindowTitleBar[0] = LoadImage(guiStyle.Window(48, 0, 16, 16), FILTEREDIMAGE)
guiWindowTitleBar[1] = LoadImage(guiStyle.Window(48, 16, 16, 16), FILTEREDIMAGE)
Global guiSymbols:TImage[] = New TImage[8]
guiSymbols[0] = LoadImage(guiStyle.Window(64, 0, 16, 16), FILTEREDIMAGE) 'Close
guiSymbols[1] = LoadImage(guiStyle.Window(80, 0, 16, 16), FILTEREDIMAGE) 'Minimize
guiSymbols[2] = LoadImage(guiStyle.Window(96, 0, 16, 16), FILTEREDIMAGE) 'Maximize
guiSymbols[3] = LoadImage(guiStyle.Window(112, 0, 16, 16), FILTEREDIMAGE) 'Restore
guiSymbols[4] = LoadImage(guiStyle.Window(64, 16, 16, 16), FILTEREDIMAGE)
guiSymbols[5] = LoadImage(guiStyle.Window(80, 16, 16, 16), FILTEREDIMAGE)
guiSymbols[6] = LoadImage(guiStyle.Window(96, 16, 16, 16), FILTEREDIMAGE)
guiSymbols[7] = LoadImage(guiStyle.Window(112, 16, 16, 16), FILTEREDIMAGE)
Global guiButtonNormal:TImage[] = New TImage[3]
guiButtonNormal[0] = LoadImage(guiStyle.Window(0, 32, 16, 16), FILTEREDIMAGE)
guiButtonNormal[1] = LoadImage(guiStyle.Window(0, 48, 16, 16), FILTEREDIMAGE)
guiButtonNormal[2] = LoadImage(guiStyle.Window(0, 64, 16, 16), FILTEREDIMAGE)
Global guiButtonShaped:TImage[] = New TImage[3]
guiButtonShaped[0] = LoadImage(guiStyle.Window(16, 32, 16, 16), FILTEREDIMAGE)
guiButtonShaped[1] = LoadImage(guiStyle.Window(16, 48, 16, 16), FILTEREDIMAGE)
guiButtonShaped[2] = LoadImage(guiStyle.Window(16, 64, 16, 16), FILTEREDIMAGE)
Global guiProgressBar:TImage[] = New TImage[3]
guiProgressBar[0] = LoadImage(guiStyle.Window(16, 80, 16, 16), FILTEREDIMAGE)
guiProgressBar[1] = LoadImage(guiStyle.Window(16, 96, 16, 16), FILTEREDIMAGE)
guiProgressBar[2] = LoadImage(guiStyle.Window(16, 112, 16, 16), FILTEREDIMAGE)
EndRem
' Show the Patcher Window
ShowGadget gdgPatcher
' GUI Values
Const guiTitleHeight:Int = 24
Global guiWidth:Int = ClientWidth(gdgPatcher)
Global guiHeight:Int = ClientHeight(gdgPatcher)
Global guiActive:Int = True
' Main Loop -----------------------------------------------------------------------------------------------------------------------------------------------------
Repeat
WaitEvent()
Select EventSource()
Case tmrRender
SetGraphics CanvasGraphics(gdgCanvas);Cls
Rem
' Draw GUI
SetColor(255, 255, 255); SetAlpha(1.0); SetBlend(SOLIDBLEND); SetScale(1.0, 1.0); SetRotation(0.0)
' Title Bar and Title
DrawTiledImage guiWindowTitleBar[guiActive], 0, 0, guiWidth, guiTitleHeight, 0, 0, 16, 16,,,,4,4,4,4, True, MODE_SCALEUPX | MODE_SCALEUPY
DrawText(GadgetText(gdgPatcher), 4, guiTitleHeight / 2 - (12 / 2))
' Content Background
DrawSubImageRectEx guiWindowBackground, 0, guiTitleHeight, guiWidth, guiHeight - guiTitleHeight, 0, 0, 32, 32,,,, MODE_REPEATX | MODE_REPEATY
SetBlend SHADEBLEND
DrawTiledImage guiContent[guiActive], 0, guiTitleHeight, guiWidth, guiHeight - guiTitleHeight, 0, 0, 16, 16,,,, 4, 4, 4, 4, True, MODE_REPEATX | MODE_REPEATY | MODE_SCALEUPX | MODE_SCALEUPY
EndRem
' Show the now rendered GUI
Flip False
Case gdgPatcher
Select EventID()
Case EVENT_WINDOWMODE, EVENT_WINDOWSIZE
' Update GUI Values {
guiWidth = ClientWidth(gdgPatcher)
guiHeight = ClientWidth(gdgPatcher)
' }
End Select
End Select
Forever
End
Rem
' Files
Import "Patcher.bmx"
'=====> Constants
?Win32
Const LAUNCHER_NAME:String = "Launcher.exe"
?Linux
Const LAUNCHER_NAME:String = "Launcher.bin"
?MacOS
Const LAUNCHER_NAME:String = "Launcher.app"
?
'=====> Parse Arguments
Global stProgram:String = AppArgs[0]
Global stProgramPath:String = ExtractDir(AppArgs[0])
Global stProgramName:String = StripDir(AppArgs[0])
Global bPatchLauncher:Byte = False
Global iPatchRetries:Int = 30
For Local stArgument:String = EachIn AppArgs[1..]
Local stArgName:String, stArgValue:String
' Skip arguments not starting with a dash
If stArgument[0..1] <> "-" Then Continue
Local iValuePos:Int = stArgument.Find("=")
If iValuePos >= 0 Then
stArgName = stArgument[1..iValuePos]
stArgValue = stArgument[iValuePos..]
Else
stArgName = stArgument[1..]
stArgValue = "1"
EndIf
Select stArgName
Case "patch"
bPatchLauncher = Byte(stArgValue)
Case "retry"
iPatchRetries = Int(stArgValue)
End Select
Next
'=====> Use parsed Arguments
'--> Patch the Launcher
If bPatchLauncher = True Then
Local iRetryCount:Int = 0
Local oRetryTimer:TTimer = TTimer.Create(10)
' Copy the newly downloaded Launcher file
If stProgramName <> LAUNCHER_NAME Then
If FileType(LAUNCHER_NAME) = FILETYPE_FILE Then
Repeat
oRetryTimer.Wait()
iRetryCount :+ 1
Until (DeleteFile(LAUNCHER_NAME) = True) or (iRetryCount > iPatchRetries)
EndIf
If FileType(LAUNCHER_NAME) = 0 Then
Repeat
oRetryTimer.Wait()
iRetryCount :+ 1
Until (CopyFile(stProgramName, LAUNCHER_NAME) = True) or (iRetryCount > iPatchRetries)
If FileType(LAUNCHER_NAME) = FILETYPE_FILE Then
Local oProcess:TProcess = CreateProcess(LAUNCHER_NAME)
TProcess.ProcessList.Remove oProcess
End
Else
Notify("Error: Failed to replace Launcher", True)
End
EndIf
Else
Notify("Error: Failed to delete old Launcher", True)
End
EndIf
EndIf
EndIf
' Resources: Create Variables that store resources.
Global riMainBackground:Int, imMainBackground:TImage;LoadResource("GFX/LNC/LAUxPATxB.png",, imMainBackground, riMainBackground)
Global riMainForeground:Int, imMainForeground:TImage;LoadResource("GFX/LNC/LAUxPATxA.png",, imMainForeground, riMainForeground)
Global riProgressBar:Int, imProgressBar:TImage; LoadResource("GFX/LNC/BARxPROGRESS.png",, imProgressBar, riProgressBar)
Global riButtonClose:Int, imButtonClose:TImage; LoadResource("GFX/LNC/BTNxCLOSE.png",, imButtonClose, riButtonClose)
Global riButtonAccount:Int, imButtonAccount:TImage; LoadResource("GFX/LNC/BTNxACCOUNT.png",, imButtonAccount, riButtonAccount)
Global riButtonWebsite:Int, imButtonWebsite:TImage; LoadResource("GFX/LNC/BTNxWEBSITE.png",, imButtonWebsite, riButtonWebsite)
Global riButtonSupport:Int, imButtonSupport:TImage; LoadResource("GFX/LNC/BTNxSUPPORT.png",, imButtonSupport, riButtonSupport)
Global riButtonEULATOS:Int, imButtonEULATOS:TImage; LoadResource("GFX/LNC/BTNxEULATOS.png",, imButtonEULATOS, riButtonEULATOS)
Global riButtonCheck:Int, imButtonCheck:TImage; LoadResource("GFX/LNC/BTNxCHECK.png",, imButtonCheck, riButtonCheck)
Global riButtonPatch:Int, imButtonPatch:TImage; LoadResource("GFX/LNC/BTNxPATCH.png",, imButtonPatch, riButtonPatch)
Global riButtonPlay:Int, imButtonPlay:TImage; LoadResource("GFX/LNC/BTNxPLAY.png",, imButtonPlay, riButtonPlay)
Global riButtonRestart:Int, imButtonRestart:TImage; LoadResource("GFX/LNC/BTNxRESTART.png",, imButtonRestart, riButtonRestart)
Global rfSmallFont:Int, fnSmallFont:TImageFont; LoadFontResource("GFX/FNT/TranscencsGames.otf", 10,, fnSmallFont, rfSmallFont)
Global rfMediumFont:Int, fnMediumFont:TImageFont;LoadFontResource("GFX/FNT/TranscencsGames.otf", 12,, fnMediumFont, rfMediumFont)
Global rfBigFont:Int, fnBigFont:TImageFont; LoadFontResource("GFX/FNT/TranscencsGames.otf", 14,, fnBigFont, rfBigFont)
' Buttons
Const BTN_STT_NORMAL:Int = 0, BTN_STT_HOVER:Int = 1, BTN_STT_DOWN:Int = 2, BTN_STT_ACTION:Int = 3
Global stButtonClose:Int = BTN_STT_NORMAL
Global stButtonAccount:Int = BTN_STT_NORMAL
Global stButtonWebsite:Int = BTN_STT_NORMAL
Global stButtonSupport:Int = BTN_STT_NORMAL
Global stButtonEULATOS:Int = BTN_STT_NORMAL
Global stButtonCheck:Int = BTN_STT_NORMAL
Global stButtonPatch:Int = BTN_STT_NORMAL
Global stButtonPlay:Int = BTN_STT_NORMAL
Global stButtonRestart:Int = BTN_STT_NORMAL
' PatchLog
Global oPatchLog:TList = New TList
' Patcher
Global oPatcher:TPatcher = TPatcher.Create()
ShowGadget(gdPatcherWindow)
EndRem
Rem
'=====> Mainloop
Local relMouseX:Int, relMouseY:Int, bDragging:Byte
Repeat
WaitEvent()
Select EventSource()
Case tmTimer ' Core timer that is basically our main loop.
'=====> User-input
Local MX:Int = MouseX(), MY:Int = MouseY()
Local MD1:Int = MouseDown(1), MH1:Int = MouseHit(1)
stButtonClose = GetButtonState(stButtonClose, 684, 0, 24, 18, MX, MY, MD1)
stButtonWebsite = GetButtonState(stButtonWebsite, 618, 330, 96, 16, MX, MY, MD1)
stButtonSupport = GetButtonState(stButtonSupport, 618, 348, 96, 16, MX, MY, MD1)
stButtonAccount = GetButtonState(stButtonAccount, 618, 366, 96, 16, MX, MY, MD1)
stButtonEULATOS = GetButtonState(stButtonEULATOS, 618, 384, 96, 16, MX, MY, MD1)
' React on the close button by sending a WindowCloseEvent
If stButtonClose = BTN_STT_ACTION Then PostEvent(TEvent.Create(EVENT_WINDOWCLOSE, gdPatcherWindow, 0, 0, 0, 0, Null))
If stButtonWebsite = BTN_STT_ACTION Then OpenURL("http://www.sirius.vektor-studios.com/")
If stButtonSupport = BTN_STT_ACTION Then OpenURL("http://www.sirius.vektor-studios.com/#contact")
If stButtonAccount = BTN_STT_ACTION Then OpenURL("http://www.sirius.vektor-studios.com/")
If stButtonEULATOS = BTN_STT_ACTION Then OpenURL("http://www.sirius.vektor-studios.com/")
' State based checking
Select oPatcher.GetState()
Case TPatcher.STATE_PATCHINFO
stButtonCheck = GetButtonState(stButtonCheck, 312, 441, 96, 16, MX, MY, MD1)
If stButtonCheck = BTN_STT_ACTION Then oPatcher.Advance()
Case TPatcher.STATE_PREPATCH
stButtonPatch = GetButtonState(stButtonPatch, 312, 441, 96, 16, MX, MY, MD1)
If stButtonPatch = BTN_STT_ACTION Then oPatcher.Advance()
Case TPatcher.STATE_COMPLETE
stButtonPlay = GetButtonState(stButtonPlay, 312, 441, 96, 16, MX, MY, MD1)
If stButtonPlay = BTN_STT_ACTION Then oPatcher.Advance()
Case TPatcher.STATE_LAUNCHER
stButtonRestart = GetButtonState(stButtonRestart, 312, 441, 96, 16, MX, MY, MD1)
If stButtonRestart = BTN_STT_ACTION Then oPatcher.Advance()
EndSelect
' Window Dragging
If bDragging = False And (MH1 = True And (MY >= 0 And MY < 32) And (MX >= 0 And MX < 720)) Then
bDragging = True
relMouseX = MX;relMouseY = MY
ElseIf bDragging = True And MD1 = True Then
SetGadgetShape(gdPatcherWindow, GadgetX(gdPatcherWindow) - (relMouseX - MX), GadgetY(gdPatcherWindow) - (relMouseY - MY), 720, 460)
relMouseX = MX + (relMouseX - MX);relMouseY = MY + (relMouseY - MY) 'Magic o.o - I don't understand why this works this way, but not when using :+ notation.
Else
bDragging = False
EndIf
'=====> Rendering
SetGraphics CanvasGraphics(gdRenderCanvas)
Cls
' Draw Back- & Foreground
SetBlend ALPHABLEND;SetMaskColor 0, 0, 0
SetColor 255, 255, 255;SetAlpha 1.0
SetOrigin 0, 0;SetTransform 0, 1, 1
If imMainBackground <> Null Then DrawImage(imMainBackground, 0, 0)
If imMainForeground <> Null Then DrawImage(imMainForeground, 0, 0)
' Window Close Button
DrawButtonState(stButtonClose, 684, 0, 24, 18, imButtonClose, "X")
' Buttons
DrawButtonState(stButtonWebsite, 618, 330, 96, 16, imButtonWebsite, "Website")
DrawButtonState(stButtonSupport, 618, 348, 96, 16, imButtonSupport, "Support")
DrawButtonState(stButtonAccount, 618, 366, 96, 16, imButtonAccount, "Account")
DrawButtonState(stButtonEULATOS, 618, 384, 96, 16, imButtonEULATOS, "EULA/TOS")
' State based drawing.
Select oPatcher.GetState()
Case TPatcher.STATE_PATCHINFO
DrawButtonState(stButtonCheck, 312, 441, 96, 16, imButtonCheck, "Check")
Case TPatcher.STATE_PREPATCH
DrawButtonState(stButtonPatch, 312, 441, 96, 16, imButtonPatch, "Patch")
Case TPatcher.STATE_COMPLETE
DrawButtonState(stButtonPlay, 312, 441, 96, 16, imButtonPlay, "Play")
Case TPatcher.STATE_LAUNCHER
DrawButtonState(stButtonRestart, 312, 441, 96, 16, imButtonRestart, "Restart")
Case TPatcher.STATE_PATCHINFO, TPatcher.STATE_CHECKING, TPatcher.STATE_PATCHING
DrawProgressBar(8, 442, 704, 12, oPatcher.GetProgress(), imProgressBar)
EndSelect
' Draw Patcher Tasklog
SetBlend ALPHABLEND;SetMaskColor 0, 0, 0
SetColor 255, 255, 255;SetAlpha 0.66;SetImageFont fnSmallFont
SetOrigin 0, 0;SetTransform 0, 1, 1
SetViewport 11, 332, 600, 100
Local iLogNum:Int = 1, oLogEntry:TLink = oPatcher.m_oTaskList.FirstLink()
While (iLogNum < 9) And (oLogEntry <> Null)
Local stLine:String = String(oLogEntry.Value())
If stLine[0..1] = "n" Then SetColor 204, 244, 255
If stLine[0..1] = "e" Then SetColor 255, 222, 204
If stLine[0..1] = "g" Then SetColor 204, 255, 204
If stLine[0..1] = "h" Then SetColor 222, 222, 255
DrawText stLine[1..], 11, 430 - iLogNum * 12
oLogEntry = oLogEntry.NextLink()
iLogNum :+ 1
Wend
SetViewport 0, 0, 720, 460; SetColor 255,255,255; SetImageFont Null
Flip False
Case tmPatch
'=====> Patcher
oPatcher.Update()
If oPatcher.GetShutdown() <> Null Then
Local oProcess:TProcess = CreateProcess(oPatcher.GetShutdown())
TProcess.ProcessList.Remove oProcess
PostEvent(TEvent.Create(EVENT_WINDOWCLOSE, gdPatcherWindow, 0, 0, 684, 0, Null))
EndIf
Case tmResource
LoadResource("GFX/LNC/LAUxPATxB.png",, imMainBackground, riMainBackground)
LoadResource("GFX/LNC/LAUxPATxA.png",, imMainForeground, riMainForeground)
LoadResource("GFX/LNC/BARxPROGRESS.png",, imProgressBar, riProgressBar)
LoadResource("GFX/LNC/BTNxCLOSE.png",, imButtonClose, riButtonClose)
LoadResource("GFX/LNC/BTNxACCOUNT.png",, imButtonAccount, riButtonAccount)
LoadResource("GFX/LNC/BTNxWEBSITE.png",, imButtonWebsite, riButtonWebsite)
LoadResource("GFX/LNC/BTNxSUPPORT.png",, imButtonSupport, riButtonSupport)
LoadResource("GFX/LNC/BTNxEULATOS.png",, imButtonEULATOS, riButtonEULATOS)
LoadResource("GFX/LNC/BTNxCHECK.png",, imButtonCheck, riButtonCheck)
LoadResource("GFX/LNC/BTNxPATCH.png",, imButtonPatch, riButtonPatch)
LoadResource("GFX/LNC/BTNxPLAY.png",, imButtonPlay, riButtonPlay)
LoadFontResource("GFX/FNT/TranscencsGames.otf", 10,, fnSmallFont, rfSmallFont)
LoadFontResource("GFX/FNT/TranscencsGames.otf", 12,, fnMediumFont, rfMediumFont)
LoadFontResource("GFX/FNT/TranscencsGames.otf", 14,, fnBigFont, rfBigFont)
Case gdPatcherWindow
Select EventID()
Case EVENT_WINDOWCLOSE
'=====> End the patcher.
End
End Select
EndSelect
Forever
'=====> Functions
Function PointInsideRect:Byte(PX:Int, PY:Int, RX:Int, RY:Int, RW:Int, RH:Int)
If PX >= RX And PX < RX + RW Then
If PY >= RY And PY < RY + RH Then
Return True
EndIf
EndIf
Return False
EndFunction
Function GetButtonState:Byte(BS:Int, BX:Int, BY:Int, BW:Int, BH:Int, MX:Int, MY:Int, MB:Int)
Local retVal:Int = BS
If PointInsideRect(MX, MY, BX, BY, BW, BH) = True Then
If BS = BTN_STT_NORMAL Then
retVal = BTN_STT_HOVER
ElseIf BS = BTN_STT_HOVER And MB = True Then
retVal = BTN_STT_DOWN
ElseIf BS = BTN_STT_DOWN And MB = False Then
retVal = BTN_STT_ACTION
ElseIf BS = BTN_STT_ACTION Then
retVal = BTN_STT_HOVER
EndIf
Else
retVal = BTN_STT_NORMAL
EndIf
Return retVal
EndFunction
Function DrawBorder(X:Int, Y:Int, W:Int, H:Int)
DrawLine X, Y, X+W, Y
DrawLine X+W, Y, X+W, Y+H
DrawLine X+W, Y+H, X, Y+H
DrawLine X, Y+H, X, Y
EndFunction
Function DrawButtonState(BS:Int, BX:Int, BY:Int, BW:Int, BH:Int, imButton:TImage, Text:String = "")
SetBlend ALPHABLEND; SetAlpha 1.0; SetColor 255, 255, 255
SetTransform 0, 1, 1;SetOrigin 0, 0; SetImageFont Null
Select BS
Case BTN_STT_NORMAL
If imButton <> Null Then
DrawSubImageRect(imButton, BX, BY, BW, BH, 0, 0, BW, BH, 0, 0, 0)
Else
SetColor 0, 0, 0;DrawRect BX, BY, BW, BH
SetColor 255, 255, 255;DrawBorder(BX,BY,BW,BH)
DrawText Text, BX + BW/2 - TextWidth(Text)/2, BY + BH/2 - TextHeight(Text)/2
EndIf
Case BTN_STT_HOVER
If imButton <> Null Then
DrawSubImageRect(imButton, BX, BY, BW, BH, 0, BH, BW, BH, 0, 0, 0)
Else
SetColor 0, 0, 0;DrawRect BX, BY, BW, BH
SetColor 204, 225, 255;DrawBorder(BX,BY,BW,BH)
DrawText Text, BX + BW/2 - TextWidth(Text)/2, BY + BH/2 - TextHeight(Text)/2
EndIf
Case BTN_STT_DOWN, BTN_STT_ACTION
If imButton <> Null Then
DrawSubImageRect(imButton, BX, BY, BW, BH, 0, BH*2, BW, BH, 0, 0, 0)
Else
SetColor 0, 0, 0;DrawRect BX, BY, BW, BH
SetColor 102, 123, 188;DrawBorder(BX,BY,BW,BH)
DrawText Text, BX + BW/2 - TextWidth(Text)/2, BY + BH/2 - TextHeight(Text)/2
EndIf
EndSelect
EndFunction
Function DrawProgressBar(X:Int, Y:Int, W:Int, H:Int, fProgress:Float, imProgressBar:TImage)
SetBlend ALPHABLEND; SetAlpha 1.0; SetColor 255, 255, 255
SetTransform 0, 1, 1;SetOrigin 0, 0
If imProgressBar = Null Then
SetColor 255, 255, 255;DrawBorder(X,Y,W,H)
SetColor 0, 0, 0;DrawRect X+1,Y+1,W-2,H-2
SetColor 204, 225, 255;SetAlpha 0.75 + Sin(MilliSecs()/5) * 0.25;DrawRect X, Y, W * fProgress, H
Else
DrawSubImageRect(imProgressBar, X, Y, W, H, 0, 0, W, H, 0, 0, 0)
SetAlpha 0.75 + Sin(MilliSecs()/5) * 0.25
Local iLength:Int = (W-6) * fProgress
DrawSubImageRect(imProgressBar, X, Y, 3, H, 0, H, 3, H, 0, 0, 0)
DrawSubImageRect(imProgressBar, X+3, Y, iLength, H, 3, H, iLength, H, 0, 0, 0)
DrawSubImageRect(imProgressBar, X+3+iLength, Y, 3, H, W-3, H, 3, H, 0, 0, 0)
EndIf
EndFunction
Function LoadResource(URL:String, Flags:Int = - 1, ImagePtr:TImage Var, InfoPtr:Int Var)
Local iModTime:Int = FileTime(URL)
If iModTime <> InfoPtr Then
ImagePtr = LoadImage(URL, Flags)
InfoPtr = iModTime
EndIf
EndFunction
Function LoadFontResource(URL:String, Size:Int, Style:Int = SMOOTHFONT, FontPtr:TImageFont Var, InfoPtr:Int Var)
Local iModTime:Int = FileTime(URL)
If iModTime <> InfoPtr Then
FontPtr = LoadImageFont(URL, Size, Style)
InfoPtr = iModTime
EndIf
EndFunction
EndRem
@@ -0,0 +1,300 @@
SuperStrict
Import BRL.Max2D
Import BRL.TextStream
Import PUB.OpenGL
Import PUB.Glew
Const MODE_REPEATX:Byte = $00000001 ' Repeat.
Const MODE_REPEATY:Byte = $00000010
Const MODE_MIRRORX:Byte = $00000100 ' Mirror every second repeat.
Const MODE_MIRRORY:Byte = $00001000
Const MODE_SCALEUPX:Byte = $00010000 ' Scale up to fit the destination area if the source doesn't fit exactly in.
Const MODE_SCALEUPY:Byte = $00100000
Const MODE_SCALEDOWNX:Byte = $01000000 ' Similar to MODE_SCALEUP*, except that it scales down to fit.
Const MODE_SCALEDOWNY:Byte = $10000000
Function DrawSubImageRectEx:Int(img:TImage, ..
dstX:Float, dstY:Float, dstW:Float, dstH:Float, ..
srcX:Float, srcY:Float, srcW:Float, srcH:Float, ..
hndX:Float=0, hndY:Float=0, frame:Int=0, bFlags:Byte=0)
Assert img <> Null Else "Image does Not exist"
Local bRepeatX:Byte = ((bFlags & MODE_REPEATX) <> 0)
Local bRepeatY:Byte = ((bFlags & MODE_REPEATY) <> 0)
Local bMirrorX:Byte = ((bFlags & MODE_MIRRORX) <> 0)
Local bMirrorY:Byte = ((bFlags & MODE_MIRRORY) <> 0)
Local bScaleUpX:Byte = ((bFlags & MODE_SCALEUPX) <> 0)
Local bScaleUpY:Byte = ((bFlags & MODE_SCALEUPY) <> 0)
Local bScaleDownX:Byte = ((bFlags & MODE_SCALEDOWNX) <> 0)
Local bScaleDownY:Byte = ((bFlags & MODE_SCALEDOWNY) <> 0)
Local lXRepeat:Float = 1, lXScale:Float = 1
If bRepeatX Then
lXRepeat = dstW / srcW
If bScaleUpX Then
lXRepeat = Floor(lXRepeat)
lXScale = (dstW / srcW) / lXRepeat
ElseIf bScaleDownX Then
lXRepeat = Ceil(lXRepeat)
lXScale = (dstW / srcW) / lXRepeat
EndIf
Else
lXScale = dstW / srcW
EndIf
Local lYRepeat:Float = 1, lYScale:Float = 1
If bRepeatY Then
lYRepeat = dstH / srcH
If bScaleUpY Then
lYRepeat = Floor(lYRepeat)
lYScale = (dstH / srcH) / lYRepeat
ElseIf bScaleDownY Then
lYRepeat = Ceil(lYRepeat)
lYScale = (dstH / srcH) / lYRepeat
EndIf
Else
lYScale = dstH / srcH
EndIf
Local lXSize:Float = srcW * lXScale, lYSize:Float = srcH * lYScale
Local lM2DScaleXOrig:Float, lM2DScaleYOrig:Float
Local lM2DScaleX:Float, lM2DScaleY:Float
GetScale(lM2DScaleXOrig, lM2DScaleYOrig)
GetScale(lM2DScaleX, lM2DScaleY)
' Cache some variables, so that we don't waste CPU time
Local lXRepeatFl:Int = Floor(lXRepeat), lXRepeatOverflow:Float = lXRepeat - lXRepeatFl
Local lYRepeatFl:Int = Floor(lYRepeat), lYRepeatOverflow:Float = lYRepeat - lYRepeatFl
For Local lYIndex:Int = 0 To lYRepeatFl
Local lYSizeMul:Float = 1
Local lYPos:Float = dstY + lYIndex * lYSize
If bMirrorY Then lM2DScaleY :* -1
If (lYIndex = lYRepeatFl) Then lYSizeMul = lYRepeatOverflow
For Local lXIndex:Int = 0 To lXRepeatFl
Local lXSizeMul:Float = 1
Local lXPos:Float = dstX + lXIndex * lXSize
If bMirrorX Then lM2DScaleX :* -1
If (lXIndex = lXRepeatFl) Then lXSizeMul = lXRepeatOverflow
SetScale lM2DScaleX, lM2DScaleY
DrawSubImageRect(img, lXPos, lYPos, lXSize * lXSizeMul, lYSize * lYSizeMul, srcX, srcY, srcW * lXSizeMul, srcH * lYSizeMul, hndX, hndY, frame)
Next
Next
SetScale(lM2DScaleXOrig, lM2DScaleYOrig)
EndFunction
Function DrawTiledImage:Int(img:TImage, dstX:Float, dstY:Float, dstW:Float, dstH:Float, srcX:Float, srcY:Float, srcW:Float, srcH:Float, hndX:Float=0, hndY:Float=0, frame:Int=0, lft:Float, top:Float, rgt:Float, btm:Float, bBackground:Byte=True, bFlags:Byte=MODE_REPEATX | MODE_REPEATY)
DrawSubImageRect(img, dstX, dstY, lft, top, srcX, srcY, lft, top, hndX, hndY, frame)
DrawSubImageRect(img, dstX + dstW - rgt, dstY, rgt, top, srcX + srcW - rgt, srcY, rgt, top, hndX, hndY, frame)
DrawSubImageRect(img, dstX, dstY + dstH - btm, lft, top, srcX, srcY + srcH - btm, lft, btm, hndX, hndY, frame)
DrawSubImageRect(img, dstX + dstW - rgt, dstY + dstH - btm, rgt, top, srcX + srcW - rgt, srcY + srcH - btm, rgt, btm, hndX, hndY, frame)
' Left
DrawSubImageRectEx(img, dstX, dstY + top, lft, dstH - top - btm, srcX, srcY + top, lft, srcH - top - btm, hndX, hndY, frame, bFlags)
' Right
DrawSubImageRectEx(img, dstX + dstW - rgt, dstY + top, rgt, dstH - top - btm, srcX + srcW - rgt, srcY + top, rgt, srcH - top - btm, hndX, hndY, frame, bFlags)
' Top
DrawSubImageRectEx(img, dstX + lft, dstY, dstW - lft - rgt, top, srcX + lft, srcY, srcW - lft - rgt, top, hndX, hndY, frame, bFlags)
' Bottom
DrawSubImageRectEx(img, dstX + lft, dstY + dstH - btm, dstW - lft - rgt, btm, srcX + lft, srcY + srcH - btm, srcW - lft - rgt, btm, hndX, hndY, frame, bFlags)
If bBackground Then DrawSubImageRectEx(img, dstX + lft, dstY + top, dstW - lft - rgt, dstH - top - btm, srcX + lft, srcY + top, srcW - lft - rgt, srcH - top - btm, hndX, hndY, frame, bFlags)
End Function
' Max2D Shader Support ---------------------------------------------------------
Type TShader
' Functions ----------------------------------------------------------------
Function Create:TShader()
Return (New TShader)
EndFunction
Function CreateVertex:TShader(oVertexCode:String)
Local oShader:TShader = TShader.Create()
oShader.Load(oVertexCode, True)
Return oShader
EndFunction
Function CreateFragement:TShader(oFragmentCode:String)
Local oShader:TShader = TShader.Create()
oShader.Load(oFragmentCode, True)
Return oShader
EndFunction
Function CreateCombined:TShader(oVertexCode:String, oFragmentCode:String)
Local oShader:TShader = TShader.Create()
oShader.Load(oVertexCode, True)
oShader.Load(oFragmentCode, False)
Return oShader
EndFunction
Function CheckForErrors:Int(ShaderObject:Int, ErrorString:String Var, Compiled:Int = True)
Local Successful:Int
If Compiled Then
glGetShaderiv (ShaderObject, GL_COMPILE_STATUS, Varptr Successful)
Else
glGetProgramiv(ShaderObject, GL_LINK_STATUS, Varptr Successful)
EndIf
If Not Successful Then
Local ErrorLength:Int
glGetObjectParameterivARB(ShaderObject, GL_OBJECT_INFO_LOG_LENGTH_ARB, Varptr ErrorLength)
Local Message:Byte Ptr = MemAlloc(ErrorLength), Dummy:Int
glGetInfoLogARB(ShaderObject, ErrorLength, Varptr Dummy, Message)
ErrorString = String.FromCString(Message)
MemFree(Message)
Return True
EndIf
Return False
End Function
Function CheckCompatability:Int()
Local Extensions:String = String.FromCString(Byte Ptr glGetString(GL_EXTENSIONS))
Local GLVersion:String = String.FromCString(Byte Ptr glGetString(GL_VERSION))
Local GLVersionInt:Int = GLVersion[.. 3].Replace(".", "").ToInt()
DebugLog Extensions
If Extensions.Find("GL_ARB_shader_objects" ) >= 0 And ..
Extensions.Find("GL_ARB_vertex_shader" ) >= 0 And ..
Extensions.Find("GL_ARB_fragment_shader") >= 0 or GLVersionInt >= 20 Then
Return True
EndIf
Return False
End Function
' Variables ----------------------------------------------------------------
Field iProgramObject:Int ' Shader Program Object
Field tError:String ' Shader Compile Errors & Warnings
' Members ------------------------------------------------------------------
Method New()
Self.iProgramObject = glCreateProgram()
EndMethod
Method Delete()
glDeleteProgram(Self.iProgramObject)
EndMethod
'' Retrieves the error that happened during loading or linking.
' @return <String> Error log retrieved from the
Method GetError:String()
Return Self.tError
EndMethod
'' Loads a new shader and, if successful, attaches it to the program.
' @param <String> tShaderCode A string containing the shader code.
' @param <Bool> bIsVertexShader Is this code a vertex Shader
' @return <Bool> Success
Method Load:Byte(tShaderCode:String, bIsVertexShader:Byte = True)
Local liShaderObject:Int
If tShaderCode = Null Then Return False
If tShaderCode.length = 0 Then Return False
' Create a new Shader Object, either for Vertex or Fragment processing.
If bIsVertexShader Then
liShaderObject = glCreateShader(GL_VERTEX_SHADER)
Else
liShaderObject = glCreateShader(GL_FRAGMENT_SHADER)
EndIf
If liShaderObject = 0 Then Return False
' Load the shader source into the compiler.
Local lbShaderCodePtr:Byte Ptr = tShaderCode.ToCString()
Local liShaderLength:Int = tShaderCode.length
glShaderSource(liShaderObject, 1, VarPtr lbShaderCodePtr, VarPtr liShaderLength)
MemFree(lbShaderCodePtr)
' Compile the shader and check for errors
glCompileShader(liShaderObject)
If (TShader.CheckForErrors(liShaderObject, Self.tError, True) = False) Then
glAttachShader(iProgramObject, liShaderObject)
glDeleteShader(liShaderObject)
Return True
EndIf
glDeleteShader(liShaderObject)
EndMethod
'' Links the attached shaders to the program, if successful.
' @return <Bool> Success
Method Link:Byte()
glLinkProgramARB(Self.iProgramObject)
Return (TShader.CheckForErrors(Self.iProgramObject, Self.tError, False) = False)
EndMethod
'' Enable the this program and disable all other programs.
' @return <Bool> Success
Method Enable:Byte()
glUseProgramObjectARB(Self.iProgramObject)
Return (TShader.CheckForErrors(Self.iProgramObject, Self.tError, False) = False)
End Method
'' Disable the all programs.
' @return <Bool> Success
Method Disable:Byte()
glUseProgramObjectARB(0)
Return (TShader.CheckForErrors(Self.iProgramObject, Self.tError, False) = False)
End Method
'' Uniform Management
Method GetUniformLocation:Int(tUniform:String)
Return glGetUniformLocationARB(Self.iProgramObject, tUniform)
End Method
Method SetUniform1F(tUniform:String, fValue1:Float)
glUniform1f(GetUniformLocation(tUniform), fValue1)
EndMethod
Method SetUniform2F(tUniform:String, fValue1:Float, fValue2:Float)
glUniform2f(GetUniformLocation(tUniform), fValue1, fValue2)
EndMethod
Method SetUniform3F(tUniform:String, fValue1:Float, fValue2:Float, fValue3:Float)
glUniform3f(GetUniformLocation(tUniform), fValue1, fValue2, fValue3)
EndMethod
Method SetUniform4F(tUniform:String, fValue1:Float, fValue2:Float, fValue3:Float, fValue4:Float)
glUniform4f(GetUniformLocation(tUniform), fValue1, fValue2, fValue3, fValue4)
EndMethod
Method SetUniform1I(tUniform:String, iValue1:Int)
glUniform1i(GetUniformLocation(tUniform), iValue1)
EndMethod
Method SetUniform2I(tUniform:String, iValue1:Int, iValue2:Int)
glUniform2i(GetUniformLocation(tUniform), iValue1, iValue2)
EndMethod
Method SetUniform3I(tUniform:String, iValue1:Int, iValue2:Int, iValue3:Int)
glUniform3i(GetUniformLocation(tUniform), iValue1, iValue2, iValue3)
EndMethod
Method SetUniform4I(tUniform:String, iValue1:Int, iValue2:Int, iValue3:Int, iValue4:Int)
glUniform4i(GetUniformLocation(tUniform), iValue1, iValue2, iValue3, iValue4)
EndMethod
Method SetUniform1UI(tUniform:String, iValue1:Int)
glUniform1ui(GetUniformLocation(tUniform), iValue1)
EndMethod
Method SetUniform2UI(tUniform:String, iValue1:Int, iValue2:Int)
glUniform2ui(GetUniformLocation(tUniform), iValue1, iValue2)
EndMethod
Method SetUniform3UI(tUniform:String, iValue1:Int, iValue2:Int, iValue3:Int)
glUniform3ui(GetUniformLocation(tUniform), iValue1, iValue2, iValue3)
EndMethod
Method SetUniform4UI(tUniform:String, iValue1:Int, iValue2:Int, iValue3:Int, iValue4:Int)
glUniform4ui(GetUniformLocation(tUniform), iValue1, iValue2, iValue3, iValue4)
EndMethod
EndType
@@ -0,0 +1,9 @@
Sirius Online Launcher
=======================
Originally supposed to be the official launcher, it was later dumped as contact died off to the lead developer due to him going from 100mbit to potato quality internet. He didn't like the idea that it would check for an update and download it, instead of letting you play directly. Neither did he like the way the updates were handled, hash based checking for new files seemed to not go over well to him.
The project contains some things from the forums for BlitzMax, as well as my try at adding some extra support to Max2D. Remember Blitz3D? The 2D system in BlitzMax is basically the same, except worse.
License
=======
Sirius Online Launcher by Michael Fabian Dirks is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/4.0/.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+285
View File
@@ -0,0 +1,285 @@
Strict
Import BRL.Retro
Function MD5$(in:String Var)
Local h0 = $67452301, h1 = $EFCDAB89, h2 = $98BADCFE, h3 = $10325476
Local r[] = [7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,..
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,..
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,..
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21]
Local k[] = [$D76AA478, $E8C7B756, $242070DB, $C1BDCEEE, $F57C0FAF, $4787C62A,..
$A8304613, $FD469501, $698098D8, $8B44F7AF, $FFFF5BB1, $895CD7BE,..
$6B901122, $FD987193, $A679438E, $49B40821, $F61E2562, $C040B340,..
$265E5A51, $E9B6C7AA, $D62F105D, $02441453, $D8A1E681, $E7D3FBC8,..
$21E1CDE6, $C33707D6, $F4D50D87, $455A14ED, $A9E3E905, $FCEFA3F8,..
$676F02D9, $8D2A4C8A, $FFFA3942, $8771F681, $6D9D6122, $FDE5380C,..
$A4BEEA44, $4BDECFA9, $F6BB4B60, $BEBFBC70, $289B7EC6, $EAA127FA,..
$D4EF3085, $04881D05, $D9D4D039, $E6DB99E5, $1FA27CF8, $C4AC5665,..
$F4292244, $432AFF97, $AB9423A7, $FC93A039, $655B59C3, $8F0CCC92,..
$FFEFF47D, $85845DD1, $6FA87E4F, $FE2CE6E0, $A3014314, $4E0811A1,..
$F7537E82, $BD3AF235, $2AD7D2BB, $EB86D391]
Local intCount = (((in$.length + 8) Shr 6) + 1) Shl 4
Local data[intCount]
For Local c=0 Until in$.length
data[c Shr 2] = data[c Shr 2] | ((in$[c] & $FF) Shl ((c & 3) Shl 3))
Next
data[in$.length Shr 2] = data[in$.length Shr 2] | ($80 Shl ((in$.length & 3) Shl 3))
data[data.length - 2] = (Long(in$.length) * 8) & $FFFFFFFF
data[data.length - 1] = (Long(in$.length) * 8) Shr 32
For Local chunkStart=0 Until intCount Step 16
Local a = h0, b = h1, c = h2, d = h3
For Local i=0 To 15
Local f = d ~ (b & (c ~ d))
Local t = d
d = c ; c = b
b = Rol((a + f + k[i] + data[chunkStart + i]), r[i]) + b
a = t
Next
For Local i=16 To 31
Local f = c ~ (d & (b ~ c))
Local t = d
d = c ; c = b
b = Rol((a + f + k[i] + data[chunkStart + (((5 * i) + 1) & 15)]), r[i]) + b
a = t
Next
For Local i=32 To 47
Local f = b ~ c ~ d
Local t = d
d = c ; c = b
b = Rol((a + f + k[i] + data[chunkStart + (((3 * i) + 5) & 15)]), r[i]) + b
a = t
Next
For Local i=48 To 63
Local f = c ~ (b | ~d)
Local t = d
d = c ; c = b
b = Rol((a + f + k[i] + data[chunkStart + ((7 * i) & 15)]), r[i]) + b
a = t
Next
h0 :+ a ; h1 :+ b
h2 :+ c ; h3 :+ d
Next
Return (LEHex(h0) + LEHex(h1) + LEHex(h2) + LEHex(h3))
End Function
Function MD5Bank:String(inbank:TBank Var)
Local h0 = $67452301, h1 = $EFCDAB89, h2 = $98BADCFE, h3 = $10325476
Local r[] = [7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,..
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,..
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,..
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21]
Local k[] = [$D76AA478, $E8C7B756, $242070DB, $C1BDCEEE, $F57C0FAF, $4787C62A,..
$A8304613, $FD469501, $698098D8, $8B44F7AF, $FFFF5BB1, $895CD7BE,..
$6B901122, $FD987193, $A679438E, $49B40821, $F61E2562, $C040B340,..
$265E5A51, $E9B6C7AA, $D62F105D, $02441453, $D8A1E681, $E7D3FBC8,..
$21E1CDE6, $C33707D6, $F4D50D87, $455A14ED, $A9E3E905, $FCEFA3F8,..
$676F02D9, $8D2A4C8A, $FFFA3942, $8771F681, $6D9D6122, $FDE5380C,..
$A4BEEA44, $4BDECFA9, $F6BB4B60, $BEBFBC70, $289B7EC6, $EAA127FA,..
$D4EF3085, $04881D05, $D9D4D039, $E6DB99E5, $1FA27CF8, $C4AC5665,..
$F4292244, $432AFF97, $AB9423A7, $FC93A039, $655B59C3, $8F0CCC92,..
$FFEFF47D, $85845DD1, $6FA87E4F, $FE2CE6E0, $A3014314, $4E0811A1,..
$F7537E82, $BD3AF235, $2AD7D2BB, $EB86D391]
Local intCount = (((inbank.Size() + 8) Shr 6) + 1) Shl 4
Local data[intCount]
Local inPtr:Byte Ptr = inbank.Buf()
For Local c=0 Until inbank.Size()
data[c Shr 2] = data[c Shr 2] | ((inPtr[c] & $FF) Shl ((c & 3) Shl 3))
Next
data[inbank.Size() Shr 2] = data[inbank.Size() Shr 2] | ($80 Shl ((inbank.Size() & 3) Shl 3))
data[data.length - 2] = (Long(inbank.Size()) * 8) & $FFFFFFFF
data[data.length - 1] = (Long(inbank.Size()) * 8) Shr 32
For Local chunkStart=0 Until intCount Step 16
Local a = h0, b = h1, c = h2, d = h3
For Local i=0 To 15
Local f = d ~ (b & (c ~ d))
Local t = d
d = c ; c = b
b = Rol((a + f + k[i] + data[chunkStart + i]), r[i]) + b
a = t
Next
For Local i=16 To 31
Local f = c ~ (d & (b ~ c))
Local t = d
d = c ; c = b
b = Rol((a + f + k[i] + data[chunkStart + (((5 * i) + 1) & 15)]), r[i]) + b
a = t
Next
For Local i=32 To 47
Local f = b ~ c ~ d
Local t = d
d = c ; c = b
b = Rol((a + f + k[i] + data[chunkStart + (((3 * i) + 5) & 15)]), r[i]) + b
a = t
Next
For Local i=48 To 63
Local f = c ~ (b | ~d)
Local t = d
d = c ; c = b
b = Rol((a + f + k[i] + data[chunkStart + ((7 * i) & 15)]), r[i]) + b
a = t
Next
h0 :+ a ; h1 :+ b
h2 :+ c ; h3 :+ d
Next
Return (LEHex(h0) + LEHex(h1) + LEHex(h2) + LEHex(h3))
End Function
Function SHA1$(in$)
Local h0 = $67452301, h1 = $EFCDAB89, h2 = $98BADCFE, h3 = $10325476, h4 = $C3D2E1F0
Local intCount = (((in$.length + 8) Shr 6) + 1) Shl 4
Local data[intCount]
For Local c=0 Until in$.length
data[c Shr 2] = (data[c Shr 2] Shl 8) | (in$[c] & $FF)
Next
data[in$.length Shr 2] = ((data[in$.length Shr 2] Shl 8) | $80) Shl ((3 - (in$.length & 3)) Shl 3)
data[data.length - 2] = (Long(in$.length) * 8) Shr 32
data[data.length - 1] = (Long(in$.length) * 8) & $FFFFFFFF
For Local chunkStart=0 Until intCount Step 16
Local a = h0, b = h1, c = h2, d = h3, e = h4
Local w[] = data[chunkStart..chunkStart + 16]
w = w[..80]
For Local i=16 To 79
w[i] = Rol(w[i - 3] ~ w[i - 8] ~ w[i - 14] ~ w[i - 16], 1)
Next
For Local i=0 To 19
Local t = Rol(a, 5) + (d ~ (b & (c ~ d))) + e + $5A827999 + w[i]
e = d ; d = c
c = Rol(b, 30)
b = a ; a = t
Next
For Local i=20 To 39
Local t = Rol(a, 5) + (b ~ c ~ d) + e + $6ED9EBA1 + w[i]
e = d ; d = c
c = Rol(b, 30)
b = a ; a = t
Next
For Local i=40 To 59
Local t = Rol(a, 5) + ((b & c) | (d & (b | c))) + e + $8F1BBCDC + w[i]
e = d ; d = c
c = Rol(b, 30)
b = a ; a = t
Next
For Local i=60 To 79
Local t = Rol(a, 5) + (b ~ c ~ d) + e + $CA62C1D6 + w[i]
e = d ; d = c
c = Rol(b, 30)
b = a ; a = t
Next
h0 :+ a ; h1 :+ b ; h2 :+ c
h3 :+ d ; h4 :+ e
Next
Return (Hex(h0) + Hex(h1) + Hex(h2) + Hex(h3) + Hex(h4)).ToLower()
End Function
Function SHA256$(in$)
Local h0 = $6A09E667, h1 = $BB67AE85, h2 = $3C6EF372, h3 = $A54FF53A
Local h4 = $510E527F, h5 = $9B05688C, h6 = $1F83D9AB, h7 = $5BE0CD19
Local k[] = [$428A2F98, $71374491, $B5C0FBCF, $E9B5DBA5, $3956C25B, $59F111F1,..
$923F82A4, $AB1C5ED5, $D807AA98, $12835B01, $243185BE, $550C7DC3,..
$72BE5D74, $80DEB1FE, $9BDC06A7, $C19BF174, $E49B69C1, $EFBE4786,..
$0FC19DC6, $240CA1CC, $2DE92C6F, $4A7484AA, $5CB0A9DC, $76F988DA,..
$983E5152, $A831C66D, $B00327C8, $BF597FC7, $C6E00BF3, $D5A79147,..
$06CA6351, $14292967, $27B70A85, $2E1B2138, $4D2C6DFC, $53380D13,..
$650A7354, $766A0ABB, $81C2C92E, $92722C85, $A2BFE8A1, $A81A664B,..
$C24B8B70, $C76C51A3, $D192E819, $D6990624, $F40E3585, $106AA070,..
$19A4C116, $1E376C08, $2748774C, $34B0BCB5, $391C0CB3, $4ED8AA4A,..
$5B9CCA4F, $682E6FF3, $748F82EE, $78A5636F, $84C87814, $8CC70208,..
$90BEFFFA, $A4506CEB, $BEF9A3F7, $C67178F2]
Local intCount = (((in$.length + 8) Shr 6) + 1) Shl 4
Local data[intCount]
For Local c=0 Until in$.length
data[c Shr 2] = (data[c Shr 2] Shl 8) | (in$[c] & $FF)
Next
data[in$.length Shr 2] = ((data[in$.length Shr 2] Shl 8) | $80) Shl ((3 - (in$.length & 3)) Shl 3)
data[data.length - 2] = (Long(in$.length) * 8) Shr 32
data[data.length - 1] = (Long(in$.length) * 8) & $FFFFFFFF
For Local chunkStart=0 Until intCount Step 16
Local a = h0, b = h1, c = h2, d = h3, e = h4, f = h5, g = h6, h = h7
Local w[] = data[chunkStart..chunkStart + 16]
w = w[..64]
For Local i=16 To 63
w[i] = w[i - 16] + (Ror(w[i - 15], 7) ~ Ror(w[i - 15], 18) ~ (w[i - 15] Shr 3))..
+ w[i - 7] + (Ror(w[i - 2], 17) ~ Ror(w[i - 2], 19) ~ (w[i - 2] Shr 10))
Next
For Local i=0 To 63
Local t0 = (Ror(a, 2) ~ Ror(a, 13) ~ Ror(a, 22)) + ((a & b) | (b & c) | (c & a))
Local t1 = h + (Ror(e, 6) ~ Ror(e, 11) ~ Ror(e, 25)) + ((e & f) | (~e & g)) + k[i] + w[i]
h = g ; g = f ; f = e ; e = d + t1
d = c ; c = b ; b = a ; a = t0 + t1
Next
h0 :+ a ; h1 :+ b ; h2 :+ c ; h3 :+ d
h4 :+ e ; h5 :+ f ; h6 :+ g ; h7 :+ h
Next
Return (Hex(h0) + Hex(h1) + Hex(h2) + Hex(h3) + Hex(h4) + Hex(h5) + Hex(h6) + Hex(h7)).ToLower()
End Function
Function Rol(val, shift)
Return (val Shl shift) | (val Shr (32 - shift))
End Function
Function Ror(val, shift)
Return (val Shr shift) | (val Shl (32 - shift))
End Function
Function LEHex$(val)
Local out$ = Hex(val)
Return out$[6..8] + out$[4..6] + out$[2..4] + out$[0..2]
End Function
+184
View File
@@ -0,0 +1,184 @@
SuperStrict
Import BRL.LinkedList
Import BRL.Map
Import BRL.Graphics
Import BRL.GLGraphics
Import BRL.Max2D
Import BRL.GLMax2D
Import BRL.Pixmap
Import Pub.OpenGL
Import "Max2DExtended.bmx"
Import BRL.BMPLoader
Import BRL.JPGLoader
Import BRL.PNGLoader
Import BRL.TGALoader
'-------------------------------------------------------------------------------
Type TGUI
' Variables ----------------------------------------------------------------
' Skinning
Field oSkinImageSet:TPixmap = Null
' GUI Area
Field oRootGadget:TGUIGadget = New TGUIGadget
' Functions ----------------------------------------------------------------
Function Create:TGUI(X:Float, Y:Float, W:Float, H:Float, Skin:Object)
Local loGUI:TGUI = New TGUI
Return loGUI
EndFunction
' Members ------------------------------------------------------------------
Method New()
Self.oRootGadget = (New TGUIGadget)
EndMethod
Method Destroy()
Self.oRootGadget = Null
EndMethod
Method Update:Int(fDelta:Float)
oRootGadget.Update(fDelta)
EndMethod
Method Render:Int(fDelta:Float)
oRootGadget.Render(fDelta)
EndMethod
'' Changes the
Method SetRootGadget:TGUIGadget(oRootGadget:TGUIGadget)
If oRootGadget = Null Or oRootGadget.Insane() Then Return Null
Local loRootWindow:TGUIGadget = Self.oRootGadget
Self.oRootGadget = oRootGadget
Return loRootWindow
EndMethod
Method GetRootGadget:TGUIGadget()
Return oRootGadget
EndMethod
EndType
'-------------------------------------------------------------------------------
Type TGUIGadget
' Constants ----------------------------------------------------------------
Const COORD_ABSOLUTE:Byte = 0
Const COORD_RELATIVE:Byte = 1
' Variables ----------------------------------------------------------------
' Gadget Coordinates
Field bLocalCoordType:Byte[] = New Byte[4]
Field dLocalCoord:Double[] = New Double[4]
Field dCoord:Double[] = New Double[4]
' Parent and Childs
Field oParentGUI:TGUI = Null
Field oParent:TGUIGadget = Null
Field oChildList:TList = New TList
' Members ------------------------------------------------------------------
'' Deconstructor for TGUIGadget
' Automatically removed itself from the parent and releases all pointers to chils
Method Delete()
' Unregister from parent gadget and release all pointers to childs.
SetParent(Null)
Self.oChildList.Clear()
' Destroy objects in reverse order.
Self.bCoordType = Null
Self.dCoord = Null
Self.dLocalCoord = Null
Self.oChildList = Null
EndMethod
'' Checks if the Gadget went insane due to invalid usage or other influence.
' @return <Bool> True if the TGUIGadget went insane, otherwise false.
Method Insane:Byte()
If Self.bCoordType = Null Then Return True
If Self.dCoord = Null Then Return True
If Self.dLocalCoord = Null Then Return True
If Self.oChildList = Null Then Return True
EndMethod
'' Updates the GUIGadget and any other objects in it.
' @return <Int>
Method Update:Int(fDelta:Float)
EndMethod
Method Render:Int(fDelta:Float)
EndMethod
' Parent Management
Method SetParent(oParent:TGUIGadget)
If Self.oParent <> Null Then Self.oParent.RemoveChild(Self)
If oParent <> Null Then oParent.AddChild(Self)
EndMethod
Method GetParent:TGUIGadget()
Return Self.oParent
EndMethod
' Child Management
Method IsChild:Int(oChild:TGUIGadget)
If oChild = Null Then Return False
Return Self.oChildList.Contains(oChild)
EndMethod
Method AddChild:Int(oChild:TGUIGadget)
If oChild <> Null Then
If IsChild(oChild) Then
Return True
Else
Return (Self.oChildList.AddLast(oChild) <> Null)
EndIf
EndIf
EndMethod
Method RemoveChild:Int(oChild:TGUIGadget)
If oChild <> Null Then
If IsChild(oChild) Then
Return True
Else
Return Self.oChildList.Remove(oChild)
EndIf
EndIf
EndMethod
Method GetChildAtIndex:TGUIGadget(iIndex:Int)
If iIndex <> -1 Then
Local liChildCount:Int = Self.oChildList.Count()
If iIndex >= 0 And iIndex < liChildCount Then
Return Self.oChildList.ValueAtIndex(iIndex)
Else
Return Null
EndIf
Else
Return Self.oChildList.Last()
EndIf
EndMethod
Method SetChildIndex:Int(oChild:TGUIGadget, iIndex:Int)
If oChild <> Null Then
If IsChild(oChild) Then
Local liChildCount:Int = Self.oChildList.Count()
If iIndex >= 0 And iIndex < liChildCount Then
'Local loChild:TGUIGadget = Self.oChildList.ValueAtIndex(iIndex)
'Local lChild:TGUIGadget = Self.oChildList.ValueAtIndex(iIndex)
'Self.oChildList.Insert
EndIf
EndIf
EndIf
EndMethod
' Signal Handlers ----------------------------------------------------------
EndType
'-------------------------------------------------------------------------------
Public
Type TGUIWindow Extends TGUIGadget
'-------------------------------------------------------------------------------
EndType
@@ -0,0 +1,435 @@
SuperStrict
Import BaH.libcurl
Import BRL.Bank
Import BRL.FileSystem
Import BRL.LinkedList
Import BRL.StandardIO
Import BRL.Stream
Import BRL.Timer
Import "Clock.c"
Import "Digest.bmx"
Type TPatcher
Const STATE_DEFAULT:Byte = 0
Const STATE_PATCHINFO:Byte = 1
Const STATE_CHECKING:Byte = 2
Const STATE_PREPATCH:Byte = 3
Const STATE_PATCHING:Byte = 4
Const STATE_COMPLETE:Byte = 5
Const STATE_LAUNCHER:Byte = 6
Const SSTATE_ENTER:Byte = 0
Const SSTATE_WORK:Byte = 1
Const SSTATE_LEAVE:Byte = 2
Const SERVER:String = "http://sirius-online.us.to/patch/"
' State-based Patcher
Field m_bState:Byte = TPatcher.STATE_DEFAULT
Field m_bSubState:Byte = TPatcher.SSTATE_ENTER
' lib/cURL is used for downloading of data.
Field m_oCurlMulti:TCurlMulti = Null
Field m_oCurl:TCurlEasy = Null
Field m_fCurlProgress:Float
' State: All
Field m_oTaskList:TList = New TList
Field m_fProgress:Float = 0
' State: Patchinfo, Checking, Patching
Field m_oFileHashList:TList = New TList
Field m_iFileCount:Int = 0
' State: Checking, Patching
Field m_oFileLoader:TAsyncLoader = New TAsyncLoader
Field m_oFileHashPair:TFileHash = Null
' State: Patching
Field m_oFileList:TList = New TList
Field m_oFile:String, m_oFileDL:String
Field m_oFileStream:TStream
' Construction
Method New()
EndMethod
Function Create:TPatcher()
Local oPatcher:TPatcher = New TPatcher
Return oPatcher
EndFunction
' Deconstruction
Method Destroy()
m_oCurlMulti.multiCleanup()
m_oCurl.cleanup()
EndMethod
' Basically the Main Loop of the Patcher, handles everything. Call GetShutdown:String() if you want to know when the patcher is telling you to run an executable and close.
Method Update()
' Check
Select m_bState
Case TPatcher.STATE_DEFAULT
If m_bSubState = TPatcher.SSTATE_ENTER Then
m_oCurlMulti = TCurlMulti.Create()
m_oCurl = m_oCurlMulti.newEasy()
m_oCurl.setOptInt(CURLOPT_FOLLOWLOCATION, 1)
m_oCurl.setOptInt(CURLOPT_CRLF, False)
m_oCurl.setOptString(CURLOPT_USERAGENT, "Sirius Online Launcher")
m_oCurl.setOptString(CURLOPT_REFERER, TPatcher.SERVER)
m_oCurl.setOptString(CURLOPT_URL, TPatcher.SERVER + "info")
m_oCurl.setProgressCallback(TPatcher.ProgressCallback, Self)
m_oCurl.setWriteString()
m_oTaskList.AddFirst("n[WAIT] Getting patch information...")
m_bSubState = TPatcher.SSTATE_WORK
EndIf
If m_bSubState = TPatcher.SSTATE_WORK Then
Local iResult:Int = Perform()
m_fProgress = m_fCurlProgress
m_oTaskList.RemoveFirst()
m_oTaskList.AddFirst("g[" + RSet(String(Int(m_fProgress * 100)), 3) + "%] Retrieving patch information...")
If iResult = CURLM_OK Then
If m_fCurlProgress = 1.0 And m_iCurlMultiHandles = 0 Then
m_bSubState = TPatcher.SSTATE_LEAVE
EndIf
Else
m_oTaskList.RemoveFirst()
m_oTaskList.AddFirst("g[FAIL] Retrieving patch information... ("+CurlError(iResult)+")")
SetState(TPatcher.STATE_COMPLETE)
EndIf
EndIf
If m_bSubState = TPatcher.SSTATE_LEAVE Then
m_oCurlMulti.multiRemove(m_oCurl)
m_oCurlMulti.multiCleanup()
m_oCurlMulti = Null
Local oCurlRCode:Int = m_oCurl.getInfo().responseCode()
Local stResult:String = m_oCurl.toString()
m_oCurl.cleanup()
m_oCurl = Null
If oCurlRCode <> 404 Then
m_oFileHashList.Clear()
If stResult.length > 0 Then
Local stFileHashArr:String[] = stResult.Split("~n")
For Local stFileHashPair:String = EachIn stFileHashArr
If stFileHashPair.length > 0 And stFileHashPair[0..1] <> "#" Then ' Ignore Comments
Local stPairArr:String[] = stFileHashPair.Split(":")
m_oFileHashList.AddLast(TFileHash.Create(stPairArr[0], stPairArr[1]))
EndIf
Next
m_iFileCount = m_oFileHashList.Count()
m_oFileList.Clear()
SetState(TPatcher.STATE_PATCHINFO) ' Got Patchinfo, and it had information.
m_oTaskList.RemoveFirst()
m_oTaskList.AddFirst("g[ OK ] Retrieving patch information... done.")
Else
SetState(TPatcher.STATE_COMPLETE)
m_oTaskList.RemoveFirst()
m_oTaskList.AddFirst("e[FAIL] Retrieving patch information... invalid information file.")
EndIf
Else
SetState(TPatcher.STATE_COMPLETE)
m_oTaskList.RemoveFirst()
m_oTaskList.AddFirst("e[FAIL] Retrieving patch information... file not found.")
EndIf
EndIf
Case TPatcher.STATE_CHECKING
If m_bSubState = TPatcher.SSTATE_ENTER Then ' Used to load a new File
m_oFileHashPair = TFileHash(m_oFileHashList.RemoveFirst())
If m_oFileHashPair <> Null Then
m_oFileLoader.Initialize(m_oFileHashPair.stName)
m_oTaskList.AddFirst("n[WAIT] Checking '" + m_oFileHashPair.stName + "'...")
m_bSubState = TPatcher.SSTATE_WORK
Else
m_bSubState = TPatcher.SSTATE_LEAVE
EndIf
EndIf
If m_bSubState = TPatcher.SSTATE_WORK Then
If m_oFileLoader.m_bComplete = 0 Then
m_oFileLoader.Process(2, 1024)
m_fProgress = ((m_iFileCount - (m_oFileHashList.Count() + 1)) / Float(m_iFileCount)) + m_oFileLoader.m_fProgress * (1.0 / m_iFileCount)
m_oTaskList.RemoveFirst()
m_oTaskList.AddFirst("g[" + RSet(String(Int(m_fProgress * 100)), 3) + "%] Checking '" + m_oFileHashPair.stName + "'...")
Else
If m_oFileLoader.m_bComplete = 1
If m_oFileLoader.m_oBank <> Null Then
Local stHash:String = MD5Bank(m_oFileLoader.m_oBank).ToUpper()
If stHash <> m_oFileHashPair.stHash Then
m_oFileList.AddLast(m_oFileHashPair.stName)
m_oTaskList.RemoveFirst()
m_oTaskList.AddFirst("h[ OK ] Checking '" + m_oFileHashPair.stName + "'... requires update.")
Else
m_oTaskList.RemoveFirst()
m_oTaskList.AddFirst("g[ OK ] Checking '" + m_oFileHashPair.stName + "'... up to date.")
EndIf
Else
m_oTaskList.RemoveFirst()
m_oTaskList.AddFirst("e[FAIL] Checking '" + m_oFileHashPair.stName + "'... (File in use?)")
EndIf
Else
m_oFileList.AddLast(m_oFileHashPair.stName)
m_oTaskList.RemoveFirst()
m_oTaskList.AddFirst("h[ OK ] Checking '" + m_oFileHashPair.stName + "'... missing.")
EndIf
m_bSubState = TPatcher.SSTATE_ENTER
m_oFileLoader.Cleanup()
EndIf
EndIf
If m_bSubState = TPatcher.SSTATE_LEAVE Then
If m_oFileList.Count() > 0 Then
m_iFileCount = m_oFileList.Count()
SetState(TPatcher.STATE_PREPATCH)
Else
SetState(TPatcher.STATE_COMPLETE)
EndIf
EndIf
Case TPatcher.STATE_PATCHING
If m_bSubState = TPatcher.SSTATE_ENTER Then
Local m_oEntry:Object = m_oFileList.RemoveFirst()
If m_oEntry <> Null Then
m_oFile = String(m_oEntry);m_oFileDL = m_oFile + ".part"
CreateDir(ExtractDir(m_oFile), True)
m_oFileStream = WriteFile(m_oFileDL)
If m_oFileStream <> Null Then
m_oCurlMulti = TCurlMulti.Create()
m_oCurl = m_oCurlMulti.newEasy()
m_oCurl.setOptInt(CURLOPT_FOLLOWLOCATION, 1)
m_oCurl.setOptInt(CURLOPT_CRLF, False)
m_oCurl.setOptString(CURLOPT_USERAGENT, "Sirius Online Launcher")
m_oCurl.setOptString(CURLOPT_REFERER, TPatcher.SERVER + "info")
m_oCurl.setOptString(CURLOPT_URL, TPatcher.SERVER + m_oFile)
m_oCurl.setWriteStream(m_oFileStream)
m_oCurl.setProgressCallback(TPatcher.ProgressCallback, Self)
m_oTaskList.AddFirst("n[WAIT] Downloading '" + m_oFile + "'...")
m_bSubState = TPatcher.SSTATE_WORK
EndIf
Else
SetState(TPatcher.STATE_DEFAULT)
EndIf
EndIf
If m_bSubState = TPatcher.SSTATE_WORK Then
Local iResult:Int = Perform()
m_fProgress = ((m_iFileCount - (m_oFileList.Count() + 1)) / Float(m_iFileCount)) + m_fCurlProgress * (1.0 / m_iFileCount)
If iResult = CURLM_OK Then
m_oFileStream.Flush()
If m_fCurlProgress = 1.0 And m_iCurlMultiHandles = 0 Then
m_oCurlMulti.multiRemove(m_oCurl)
m_oCurlMulti.multiCleanup()
Local oCurlRCode:Int = m_oCurl.getInfo().responseCode()
m_oCurl.cleanup()
' Cleanup(1)
m_oCurl = Null
m_oCurlMulti = Null
m_oFileStream.Close()
m_oFileStream = Null
If oCurlRCode <> 404 Then
m_oTaskList.RemoveFirst()
m_oTaskList.AddFirst("g[ OK ] Downloading '" + m_oFile + "'...")
' Rename files
If m_oFile <> "Launcher.exe" Then
RenameFile(m_oFile, m_oFile + ".old")
If RenameFile(m_oFileDL, m_oFile) Then
DeleteFile(m_oFile + ".old")
Else
RenameFile(m_oFile + ".old", m_oFile)
EndIf
Else' If we patched the launcher, tell the parent program to start the new one.
RenameFile(m_oFileDL, "-" + m_oFile)
m_oFileList.Clear() ' Clear the list to be sure
SetState(TPatcher.STATE_LAUNCHER)
EndIf
Else
DeleteFile(m_oFileDL)
m_oTaskList.RemoveFirst()
m_oTaskList.AddFirst("e[FAIL] Downloading '" + m_oFile + "'... file not found.")
EndIf
'Cleanup (2)
m_oFileDL = Null
m_oFile = Null
If m_oFileList.Count() = 0 Then
m_bSubState = TPatcher.SSTATE_LEAVE
Else
m_bSubState = TPatcher.SSTATE_ENTER
EndIf
Else
m_oTaskList.RemoveFirst()
m_oTaskList.AddFirst("n[" + RSet(String(Int(m_fCurlProgress * 100)), 3) + "%] Downloading '" + m_oFile + "'...")
EndIf
Else
m_oFileStream.Close()
m_oTaskList.RemoveFirst()
m_oTaskList.AddFirst("e[FAIL] Downloading '" + m_oFile + "'... " + CurlError(iResult))
EndIf
EndIf
If m_bSubState = TPatcher.SSTATE_LEAVE And m_bState = TPatcher.STATE_PATCHING Then
SetState(TPatcher.STATE_DEFAULT)
EndIf
EndSelect
EndMethod
Method Advance()
Select m_bState
Case TPatcher.STATE_PATCHINFO
SetState(TPatcher.STATE_CHECKING)
Case TPatcher.STATE_PREPATCH
SetState(TPatcher.STATE_PATCHING)
Case TPatcher.STATE_COMPLETE
m_stProcessToRun = "ExeFile.exe"
Case TPatcher.STATE_LAUNCHER
m_stProcessToRun = "-Launcher.exe 1"
EndSelect
EndMethod
Field m_iCurlMultiHandles:Int, m_bCurlMultiState:Byte = 0
Method Perform:Int()
Local iResult:Int = 0
iResult = MultiPerform()
Select m_bCurlMultiState
Case 0, 2
m_bCurlMultiState = (m_bCurlMultiState + 1) Mod 3
Case 1
If m_oCurlMulti.multiSelect(0.1) <> -1 And m_iCurlMultiHandles Then
iResult = MultiPerform()
If m_iCurlMultiHandles = 0 Then m_bCurlMultiState = 2
EndIf
EndSelect
Return iResult
EndMethod
Method MultiPerform:Int()
Local iResult:Int = m_oCurlMulti.multiPerform(m_iCurlMultiHandles)
While iResult = CURLM_CALL_MULTI_PERFORM
iResult = m_oCurlMulti.multiPerform(m_iCurlMultiHandles)
Wend
Return iResult
EndMethod
' State Management
Method SetState(bState:Byte)
m_bState = bState
m_bSubState = TPatcher.SSTATE_ENTER
m_fProgress = 0.0
EndMethod
Method GetState:Byte()
Return m_bState
EndMethod
' Information
Method GetProgress:Float()
Return m_fProgress
EndMethod
Field m_stProcessToRun:String = NUll
Method GetShutdown:String()
Return m_stProcessToRun
EndMethod
' Callbacks
Function ProgressCallback:Int(oPatcherObj:Object, dDownloadTotal:Double, dDownloadNow:Double, dUploadTotal:Double, dUploadNow:Double)
If dDownloadTotal = 0 And dDownloadNow = 0 And dUploadTotal = 0 And dUploadNow = 0 Then TPatcher(oPatcherObj).m_fCurlProgress = 0.0;Return 0
TPatcher(oPatcherObj).m_fCurlProgress = (dDownloadNow / dDownloadTotal)
EndFunction
EndType
Type TFileHash
Field stName:String, stHash:String
Function Create:TFileHash(stName:String, stHash:String)
Local oFH:TFileHash = New TFileHash
oFH.stName = stName
oFH.stHash = stHash
Return oFH
EndFunction
EndType
Type TAsyncLoader
Field m_oBank:TBank
Field m_oStream:TStream, m_iFileSize:Int
Field m_fProgress:Float, m_bComplete:Byte
Method Initialize(stFile:String)
If FileType(stFile) = FILETYPE_FILE Then
m_oStream = ReadFile(stFile)
If m_oStream <> Null Then
m_iFileSize = FileSize(stFile)
m_oBank = CreateBank(m_iFileSize)
If m_oBank <> Null Then
m_fProgress = 0.0
m_bComplete = False
Else
m_oStream.Close()
EndIf
Else
m_fProgress = 1.0
m_bComplete = -2
EndIf
Else
m_fProgress = 1.0
m_bComplete = -2
EndIf
EndMethod
Method Process(iMs:Float, iBufferSize:Int = 1024)
Local iClockStart:Int = getClock()
If (m_oStream <> Null And m_oBank <> Null) And m_oStream.Eof() = False Then
Local iClockNow:Int = getClock()
Repeat
Local iRemaining:Int = Min(m_iFileSize - m_oStream.Pos(), iBufferSize)
m_oBank.Read(m_oStream, m_oStream.Pos(), iRemaining)
iClockNow = getClock()
Until m_oStream.Eof() = True or getClockDiff(iClockStart, iClockNow) > (iMs / 1000.0 * getClocksPerSecond())
m_fProgress = m_oStream.Pos() / Float(m_iFileSize)
m_bComplete = m_oStream.Eof()
If m_oStream.Eof() = True Then
m_oStream.Close()
m_oStream = Null
EndIf
ElseIf m_bComplete = 0 Then
m_fProgress = 1.0
m_bComplete = -1
EndIf
EndMethod
Method Cleanup()
m_oBank = Null
EndMethod
EndType
Function DebugClock(Text:String)
DebugLog getClock() + ":" + Text
EndFunction
Extern "c"
Function getClocksPerSecond:Int()="getClocksPerSecond_"
Function getClock:Int()="getClock_"
Function getClockDiff:Int(clockStart:Int, clockEnd:Int)="getClockDiff_"
EndExtern