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,23 @@
Global sTestTxt$
sTestTxt$ = sTestTxt$ + "|fFF0000H|fFF7E00a|fFFFF00l|f7EFF00l|f00FF00o |f00FF7EW|f00FFFFe|f007EFFl|f0000FFt|f7E00FF!|fFF00FF!|fFF007E!"+Chr(10)
sTestTxt$ = sTestTxt$ + Chr(10)
sTestTxt$ = sTestTxt$ + "|fFFFFFFDies ist ein Text der |fFF0000Rot |f00FF00Grün |fFFFFFFund |f0000FFBlau |fFFFFFFist." + Chr(10)
sTestTxt$ = sTestTxt$ + "|f33FF33Man kann alle mögli|f0000FFchen Farben machen!" + Chr(10)
sTestTxt$ = sTestTxt$ + "|f000000|bFF0000Sogar|b-1-1-1 |bFF7E00der|b-1-1-1 |bFFFF00Hinter|b7EFF00grund|b-1-1-1 |b00FF00kann|b-1-1-1 |b00FF7Egesetzt|b-1-1-1 |b00FFFFwerden|b-1-1-1!" + Chr(10)
sTestTxt$ = sTestTxt$ + "|fAAAAFF|b-1-1-1Dies kann für mehr|f444400|bAAAAFFzeilige Selektion|fAAAAFF|b-1-1-1 verwendet werden!" + Chr(10)
sTestTxt$ = sTestTxt$ + "|fFFFFFFD|fFF7E00amit wäre der |b7E7E7E|fFFFFFFB|fFF7E00eispieltext|b-1-1-1 beendet|fFFFFFF!"
Graphics 400,300,32,2
SetBuffer BackBuffer()
Global timer = CreateTimer(30)
While Not KeyHit(1)
Cls
AdvText(200,150, sTestTxt, MouseX()/200.0, MouseY()/150.0, 1)
Flip 0
WaitTimer timer
Wend
Include "AdvText.bb"
+193
View File
@@ -0,0 +1,193 @@
;AdvText Function
Dim SplittedString$(0)
Dim sTextLines$(0,1)
Global SplitCount, AdvText_X, AdvText_Y, AdvText_Width, AdvText_Height
Function AdvText(iX, iY, sText$, iCenterX#=0, iCenterY#=0, fLineSpace#=1)
Local iTextLines = 1, iLine = 0
AdvText_X = 0:AdvText_Y = 0:AdvText_Width = 0:AdvText_Height = 0
SplitString(sText, Chr(10))
iTextLines = SplitCount-1
Dim sTextLines$(iTextLines,1)
For iLine = 0 To iTextLines
sTextLines(iLine, 0) = SplittedString$(iLine)
Next
;Parse the Text so that we get only the visible text into the second slot.
Local iLastClr = 1, tabLength = 0
For iLine = 0 To iTextLines
iLastClr = 1
For iPos = 1 To Len(sTextLines(iLine,0))
sChar$ = Mid(sTextLines(iLine,0), iPos, 1)
If sChar = "|" And (Mid(sTextLines(iLine,0), iPos+1, 1) = "f" Or Mid(sTextLines(iLine,0), iPos+1, 1) = "b")
sTextLines(iLine,1) = sTextLines(iLine,1) + Mid(sTextLines(iLine,0),iLastClr,iPos-iLastClr)
iLastClr = iPos+8
ElseIf sChar = Chr(9)
sTextLines(iLine,1) = sTextLines(iLine,1) + Mid(sTextLines(iLine,0),iLastClr,iPos-iLastClr)
iLastClr = iPos
;Remove Tab Character
sTextLines(iLine,0) = Left(sTextLines(iLine,0), iPos-1) + Right(sTextLines(iLine,0), Len(sTextLines(iLine,0))-iPos)
tabLength = (4-(Len(sTextLines(iLine,1)) Mod 4))
For iTabSpace = 1 To tabLength
sTextLines(iLine,0) = Left(sTextLines(iLine,0), iPos-1) + " " + Right(sTextLines(iLine,0), Len(sTextLines(iLine,0))-iPos+1)
Next
ElseIf sChar = Chr(11)
sTextLines(iLine,1) = sTextLines(iLine,1) + Mid(sTextLines(iLine,0),iLastClr,iPos-iLastClr)
iLastClr = iPos
;Remove Tab Character
sTextLines(iLine,0) = Left(sTextLines(iLine,0), iPos-1) + Right(sTextLines(iLine,0), Len(sTextLines(iLine,0))-iPos)
tabLength = (8-(Len(sTextLines(iLine,1)) Mod 8))
For iTabSpace = 1 To tabLength
sTextLines(iLine,0) = Left(sTextLines(iLine,0), iPos-1) + " " + Right(sTextLines(iLine,0), Len(sTextLines(iLine,0))-iPos+1)
Next
ElseIf iPos = Len(sTextLines(iLine,0))
sTextLines(iLine,1) = sTextLines(iLine,1) + Mid(sTextLines(iLine,0),iLastClr,iPos-iLastClr+1)
EndIf
Next
; Return width.
If (AdvText_Width < StringWidth(sTextLines(iLine,1))) Then AdvText_Width = StringWidth(sTextLines(iLine,1))
Next
; Return Height
If (AdvText_Height < (FontHeight()*(iTextLines+1)*fLineSpace)) Then AdvText_Height = (FontHeight()*(iTextLines+1)*fLineSpace)
;Real Text Processing
Local iRedO = ColorRed(), iGreenO = ColorGreen(), iBlueO = ColorBlue() ; Original Foreground Color
Local iRed = ColorRed(), iGreen = ColorGreen(), iBlue = ColorBlue() ;Foreground
Local iBGRed = -1, iBGGreen = -1, iBGBlue = -1 ;Background
Local icX, icY, icsX, scText$, iRealPos
For iLine = 0 To iTextLines
sText$ = sTextLines(iLine,0)
icsX = -(StringWidth(sTextLines(iLine,1))*0.5)*iCenterX
icX = icsX
icY = ( -(FontHeight()*(iTextLines+1)*0.5*fLineSpace*iCenterY) + (iLine * FontHeight() * fLineSpace) )
; Return X and Y starting point.
If (AdvText_X > iX + icX) Then AdvText_X = iX + icX
If (AdvText_Y > iY + icY) Then AdvText_Y = iY + icY
iRealPos = 1
For iPos = 1 To Len(sText)
sChar$ = Mid(sText, iPos, 1)
If sChar = "|" And Mid(sText, iPos+1, 1) = "f" ;Foreground Change
If iBGRed > -1 And iBGGreen > -1 And iBGBlue > -1
Color iBGRed, iBGGreen, iBGBlue
Rect iX+icX, iY+icY, StringWidth(scText), FontHeight()*fLineSpace
EndIf
Color iRed, iGreen, iBlue
Text iX+icX, iY+icY, scText$
icX = icX + StringWidth(scText$)
scText = ""
If Mid(sText, iPos+2, 2) = "-1"
iRed = iRedO
iGreen = iGreenO
iBlue = iBlueO
Else
iRed = HexB(Mid(sText, iPos+2, 2))
iGreen = HexB(Mid(sText, iPos+4, 2))
iBlue = HexB(Mid(sText, iPos+6, 2))
EndIf
sText = Left(sText, iPos)+Mid(sText, iPos+8)
ElseIf sChar = "|" And Mid(sText, iPos+1, 1) = "b" ;Background Change
If iBGRed > -1 And iBGGreen > -1 And iBGBlue > -1
Color iBGRed, iBGGreen, iBGBlue
Rect iX+icX, iY+icY, StringWidth(scText), FontHeight()*fLineSpace
EndIf
Color iRed, iGreen, iBlue
Text iX+icX, iY+icY, scText$
icX = icX + StringWidth(scText$)
scText = ""
If Mid(sText, iPos+2, 2) = "-1"
iBGRed = -1
iBGGreen = -1
iBGBlue = -1
Else
iBGRed = HexB(Mid(sText, iPos+2, 2))
iBGGreen = HexB(Mid(sText, iPos+4, 2))
iBGBlue = HexB(Mid(sText, iPos+6, 2))
EndIf
sText = Left(sText, iPos)+Mid(sText, iPos+8)
Else
scText$ = scText$ + sChar$
iRealPos = iRealPos + 1
EndIf
If iPos = Len(sText)
If iBGRed > -1 And iBGGreen > -1 And iBGBlue > -1
Color iBGRed, iBGGreen, iBGBlue
Rect iX+icX, iY+icY, StringWidth(scText), FontHeight()*fLineSpace
EndIf
Color iRed, iGreen, iBlue
Text iX+icX, iY+icY, scText
scText = ""
EndIf
Next
scText$ = ""
Next
End Function
Function HexB#(Hexzahl$)
Local Integer_Result#
If Left$(Hexzahl$,1)="$" Then Hexzahl$=Mid$(Hexzahl$,2)
For i=1 To Len(Hexzahl$)
tmp1$=Upper$(Mid$(Hexzahl$,i,1)):tmp2=tmp1$
If tmp2=0 And tmp1$<>"0" Then tmp2=Asc(tmp1$)-55
Integer_Result=Integer_Result*16:Integer_Result=Integer_Result+tmp2
Next
Return Integer_Result
End Function
Function SplitString(In$, StringSplitter$ = "|")
Local InLength% = Len(In)
Local SplitLength% = Len(StringSplitter)
Local CountPos%, InPos%, SplitIndex%
Local SplitTest$, LineText$
; Count how many Lines there are and resize Dim.
SplitCount = 0
For CountPos = 1 To InLength-(SplitLength-1)
SplitTest = Mid(In,CountPos,1)
If SplitTest = StringSplitter Then SplitCount = SplitCount + 1
Next
Dim SplittedString(SplitCount)
; Split the Text onto multiple lines.
While Not InPos = Len(In)
; Increment Position
InPos = InPos + 1
; Grab a piece of the text.
SplitTest = Mid(In, InPos, SplitLength)
Local Char$ = Left(SplitTest, 1)
; Check if the current Text matches the splitter or if we are near the end.
If SplitTest = StringSplitter Or InPos = InLength
; Append the current character if it doesn't match the Splitter.
If InPos = InLength And SplitTest <> StringSplitter Then LineText = LineText + Char
; Store the Line.
SplittedString(SplitIndex) = LineText
; Increment split index.
SplitIndex = SplitIndex + 1
; Reset LineText
LineText = ""
Else
LineText = LineText + Char
EndIf
Wend
End Function
;~IDEal Editor Parameters:
;~C#Blitz3D
+8
View File
@@ -0,0 +1,8 @@
Advanced Text
=======================
This project adds an advanced text function to BlitzBasic. While somewhat slower, it supports many features and if you cache the result you can get quite good results. It was written for a project that needed such features in the chat, but has been abandoned.
License
=======
Advanced Text 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/.
@@ -0,0 +1,258 @@
;----------------------------------------------------------------
;-- Types
;----------------------------------------------------------------
Type TList
Field FirstEntry.TListEntry
Field LastEntry.TListEntry
Field Iterator.TListEntry
End Type
Type TListEntry
Field Value%
Field PreviousEntry.TListEntry
Field NextEntry.TListEntry
End Type
;----------------------------------------------------------------
;-- Functions
;----------------------------------------------------------------
Function TList_Create.TList()
Local lList.TList = New TList
lList\FirstEntry = Null
lList\LastEntry = Null
lList\Iterator = Null
Return lList
End Function
Function TList_Destroy(pList.TList)
If pList = Null Then RuntimeError "TList: Tried to destroy non-existing list."
; Delete all entries
pList\Iterator = pList\FirstEntry
While pList\Iterator <> Null
Local lNextEntry.TListEntry = pList\Iterator\NextEntry
Delete pList\Iterator
pList\Iterator = lNextEntry
Wend
End Function
Function TList_Reset(pList.TList)
If pList = Null Then RuntimeError "TList: Tried to reset non-existing list."
pList\Iterator = Null
End Function
Function TList_First%(pList.TList)
If pList = Null Then RuntimeError "TList: Tried to iterate non-existing list."
pList\Iterator = pList\FirstEntry
If pList\Iterator <> Null Then Return pList\Iterator\Value
End Function
Function TList_Last%(pList.TList)
If pList = Null Then RuntimeError "TList: Tried to iterate non-existing list."
pList\Iterator = pList\LastEntry
If pList\Iterator <> Null Then Return pList\Iterator\Value
End Function
Function TList_Next%(pList.TList)
If pList = Null Then RuntimeError "TList: Tried to iterate non-existing list."
If pList\Iterator <> Null Then
pList\Iterator = pList\Iterator\NextEntry
Else
pList\Iterator = pList\FirstEntry
EndIf
If pList\Iterator <> Null Then Return pList\Iterator\Value
End Function
Function TList_Previous%(pList.TList)
If pList = Null Then RuntimeError "TList: Tried to iterate non-existing list."
If pList\Iterator <> Null Then
pList\Iterator = pList\Iterator\PreviousEntry
Else
pList\Iterator = pList\LastEntry
EndIf
If pList\Iterator <> Null Then Return pList\Iterator\Value
End Function
Function TList_HasFirst(pList.TList)
If pList = Null Then RuntimeError "TList: Tried to iterate non-existing list."
Return (pList\FirstEntry <> Null)
End Function
Function TList_HasLast(pList.TList)
If pList = Null Then RuntimeError "TList: Tried to iterate non-existing list."
Return (pList\LastEntry <> Null)
End Function
Function TList_HasNext(pList.TList)
If pList = Null Then RuntimeError "TList: Tried to iterate non-existing list."
If pList\Iterator <> Null Then
Return (pList\Iterator\NextEntry <> Null)
Else
Return (pList\FirstEntry <> Null)
EndIf
End Function
Function TList_HasPrevious(pList.TList)
If pList = Null Then RuntimeError "TList: Tried to iterate non-existing list."
If pList\Iterator <> Null Then
Return (pList\Iterator\PreviousEntry <> Null)
Else
Return (pList\LastEntry <> Null)
EndIf
End Function
Function TList_AddFirst(pList.TList, Value%)
If pList = Null Then RuntimeError "TList: Tried to insert into non-existing list."
Local lEntry.TListEntry = New TListEntry
lEntry\Value = Value
If pList\FirstEntry <> Null Then
lEntry\NextEntry = pList\FirstEntry
lEntry\NextEntry\PreviousEntry = lEntry
EndIf
pList\FirstEntry = lEntry
If pList\LastEntry = Null Then pList\LastEntry = lEntry
End Function
Function TList_AddLast(pList.TList, Value%)
If pList = Null Then RuntimeError "TList: Tried to insert into non-existing list."
Local lEntry.TListEntry = New TListEntry
lEntry\Value = Value
If pList\LastEntry <> Null Then
lEntry\PreviousEntry = pList\LastEntry
lEntry\PreviousEntry\NextEntry = lEntry
EndIf
If pList\FirstEntry = Null pList\FirstEntry = lEntry
pList\LastEntry = lEntry
End Function
Function TList_InsertBefore(pList.TList, Value%)
If pList = Null Then RuntimeError "TList: Tried to insert into non-existing list."
If pList\Iterator = Null Then RuntimeError "TList: TList: Tried to change non-existing list entry."
Local lEntry.TListEntry = New TListEntry
lEntry\Value = Value
If pList\Iterator\PreviousEntry <> Null Then
lEntry\PreviousEntry = pList\Iterator\PreviousEntry
pList\Iterator\PreviousEntry\NextEntry = lEntry
Else
pList\FirstEntry = lEntry
EndIf
pList\Iterator\PreviousEntry = lEntry
If pList\Iterator\NextEntry = Null Then
pList\LastEntry = lEntry
EndIf
lEntry\NextEntry = pList\Iterator
End Function
Function TList_InsertAfter(pList.TList, Value%)
If pList = Null Then RuntimeError "TList: Tried to insert into non-existing list."
If pList\Iterator = Null Then RuntimeError "TList: TList: Tried to change non-existing list entry."
Local lEntry.TListEntry = New TListEntry
lEntry\Value = Value
If pList\Iterator\NextEntry <> Null Then
lEntry\NextEntry = pList\Iterator\NextEntry
pList\Iterator\NextEntry\PreviousEntry = lEntry
Else
pList\LastEntry = lEntry
EndIf
pList\Iterator\NextEntry = lEntry
If pList\Iterator\PreviousEntry = Null Then
pList\FirstEntry = lEntry
EndIf
lEntry\PreviousEntry = pList\Iterator
End Function
Function TList_Replace(pList.TList, Value%)
If pList = Null Then RuntimeError "TList: Tried to insert into non-existing list."
If pList\Iterator = Null Then RuntimeError "TList: TList: Tried to change non-existing list entry."
pList\Iterator\Value = Value
End Function
Function TList_DeleteFirst(pList.TList)
If pList = Null Then RuntimeError "TList: Tried to insert into non-existing list."
If pList\FirstEntry = Null Then RuntimeError "TList: TList: Tried to change non-existing list entry."
Local lEntry.TListEntry = pList\FirstEntry
pList\FirstEntry\NextEntry\PreviousEntry = Null
pList\FirstEntry = pList\FirstEntry\NextEntry
Delete lEntry
If pList\FirstEntry <> Null Then Return pList\FirstEntry\Value
End Function
Function TList_DeleteLast(pList.Tlist)
If pList = Null Then RuntimeError "TList: Tried to insert into non-existing list."
If pList\LastEntry = Null Then RuntimeError "TList: TList: Tried to change non-existing list entry."
Local lEntry.TListEntry = pList\LastEntry
pList\LastEntry\PreviousEntry\NextEntry = Null
pList\LastEntry = pList\LastEntry\PreviousEntry
Delete lEntry
If pList\LastEntry <> Null Then Return pList\LastEntry\Value
End Function
Function TList_Delete(pList.TList)
If pList = Null Then RuntimeError "TList: Tried to insert into non-existing list."
If pList\Iterator = Null Then RuntimeError "TList: TList: Tried to change non-existing list entry."
If pList\FirstEntry = pList\Iterator Then pList\FirstEntry = pList\Iterator\NextEntry
If pList\LastEntry = pList\Iterator Then pList\LastEntry = pList\Iterator\PreviousEntry
If pList\Iterator\NextEntry <> Null Then pList\Iterator\NextEntry\PreviousEntry = pList\Iterator\PreviousEntry
If pList\Iterator\PreviousEntry <> Null Then pList\Iterator\PreviousEntry\NextEntry = pList\Iterator\NextEntry
Local lEntry.TListEntry = pList\Iterator
pList\Iterator = pList\Iterator\NextEntry
Delete lEntry
If pList\Iterator <> Null Then Return pList\Iterator\Value
End Function
Function TList_DeleteValue(pList.TList, Value%)
If pList = Null Then RuntimeError "TList: Tried to insert into non-existing list."
If pList\FirstEntry <> Null Then
Local lEntry.TListEntry = pList\FirstEntry
While lEntry <> Null
If lEntry\Value = Value Then
If lEntry\PreviousEntry <> Null Then lEntry\PreviousEntry\NextEntry = lEntry\NextEntry
If lEntry\NextEntry <> Null Then lEntry\NextEntry\PreviousEntry = lEntry\PreviousEntry
If pList\FirstEntry = lEntry Then pList\FirstEntry = lEntry\NextEntry
If pList\LastEntry = lEntry Then pList\LastEntry = lEntry\PreviousEntry
Local lDelEntry.TListEntry = lEntry
lEntry = lEntry\NextEntry
Delete lDelEntry
Else
lEntry = lEntry\NextEntry
EndIf
Wend
EndIf
End Function
@@ -0,0 +1,9 @@
LinkedList Emulation
=======================
Since the early BlitzBasic languages didn't have any kind of lists aside from the global ones, I had to make something out of nothing. This library adds the ability to have linked lists inside of those languages.
It was initially ment to use FastPointer or a similar library, but that failed horrifically, as I wasn't able to cast back into the original type and memory leaks happened. It's somewhat fast, but solutions tailored to a single type still work faster 90% of the time.
License
=======
LinkedList Emulation 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/.
+258
View File
@@ -0,0 +1,258 @@
;----------------------------------------------------------------
;-- Types
;----------------------------------------------------------------
Type TList
Field FirstEntry.TListEntry
Field LastEntry.TListEntry
Field Iterator.TListEntry
End Type
Type TListEntry
Field Value%
Field PreviousEntry.TListEntry
Field NextEntry.TListEntry
End Type
;----------------------------------------------------------------
;-- Functions
;----------------------------------------------------------------
Function TList_Create.TList()
Local lList.TList = New TList
lList\FirstEntry = Null
lList\LastEntry = Null
lList\Iterator = Null
Return lList
End Function
Function TList_Destroy(pList.TList)
If pList = Null Then RuntimeError "TList: Tried to destroy non-existing list."
; Delete all entries
pList\Iterator = pList\FirstEntry
While pList\Iterator <> Null
Local lNextEntry.TListEntry = pList\Iterator\NextEntry
Delete pList\Iterator
pList\Iterator = lNextEntry
Wend
End Function
Function TList_Reset(pList.TList)
If pList = Null Then RuntimeError "TList: Tried to reset non-existing list."
pList\Iterator = Null
End Function
Function TList_First%(pList.TList)
If pList = Null Then RuntimeError "TList: Tried to iterate non-existing list."
pList\Iterator = pList\FirstEntry
If pList\Iterator <> Null Then Return pList\Iterator\Value
End Function
Function TList_Last%(pList.TList)
If pList = Null Then RuntimeError "TList: Tried to iterate non-existing list."
pList\Iterator = pList\LastEntry
If pList\Iterator <> Null Then Return pList\Iterator\Value
End Function
Function TList_Next%(pList.TList)
If pList = Null Then RuntimeError "TList: Tried to iterate non-existing list."
If pList\Iterator <> Null Then
pList\Iterator = pList\Iterator\NextEntry
Else
pList\Iterator = pList\FirstEntry
EndIf
If pList\Iterator <> Null Then Return pList\Iterator\Value
End Function
Function TList_Previous%(pList.TList)
If pList = Null Then RuntimeError "TList: Tried to iterate non-existing list."
If pList\Iterator <> Null Then
pList\Iterator = pList\Iterator\PreviousEntry
Else
pList\Iterator = pList\LastEntry
EndIf
If pList\Iterator <> Null Then Return pList\Iterator\Value
End Function
Function TList_HasFirst(pList.TList)
If pList = Null Then RuntimeError "TList: Tried to iterate non-existing list."
Return (pList\FirstEntry <> Null)
End Function
Function TList_HasLast(pList.TList)
If pList = Null Then RuntimeError "TList: Tried to iterate non-existing list."
Return (pList\LastEntry <> Null)
End Function
Function TList_HasNext(pList.TList)
If pList = Null Then RuntimeError "TList: Tried to iterate non-existing list."
If pList\Iterator <> Null Then
Return (pList\Iterator\NextEntry <> Null)
Else
Return (pList\FirstEntry <> Null)
EndIf
End Function
Function TList_HasPrevious(pList.TList)
If pList = Null Then RuntimeError "TList: Tried to iterate non-existing list."
If pList\Iterator <> Null Then
Return (pList\Iterator\PreviousEntry <> Null)
Else
Return (pList\LastEntry <> Null)
EndIf
End Function
Function TList_AddFirst(pList.TList, Value%)
If pList = Null Then RuntimeError "TList: Tried to insert into non-existing list."
Local lEntry.TListEntry = New TListEntry
lEntry\Value = Value
If pList\FirstEntry <> Null Then
lEntry\NextEntry = pList\FirstEntry
lEntry\NextEntry\PreviousEntry = lEntry
EndIf
pList\FirstEntry = lEntry
If pList\LastEntry = Null Then pList\LastEntry = lEntry
End Function
Function TList_AddLast(pList.TList, Value%)
If pList = Null Then RuntimeError "TList: Tried to insert into non-existing list."
Local lEntry.TListEntry = New TListEntry
lEntry\Value = Value
If pList\LastEntry <> Null Then
lEntry\PreviousEntry = pList\LastEntry
lEntry\PreviousEntry\NextEntry = lEntry
EndIf
If pList\FirstEntry = Null pList\FirstEntry = lEntry
pList\LastEntry = lEntry
End Function
Function TList_InsertBefore(pList.TList, Value%)
If pList = Null Then RuntimeError "TList: Tried to insert into non-existing list."
If pList\Iterator = Null Then RuntimeError "TList: TList: Tried to change non-existing list entry."
Local lEntry.TListEntry = New TListEntry
lEntry\Value = Value
If pList\Iterator\PreviousEntry <> Null Then
lEntry\PreviousEntry = pList\Iterator\PreviousEntry
pList\Iterator\PreviousEntry\NextEntry = lEntry
Else
pList\FirstEntry = lEntry
EndIf
pList\Iterator\PreviousEntry = lEntry
If pList\Iterator\NextEntry = Null Then
pList\LastEntry = lEntry
EndIf
lEntry\NextEntry = pList\Iterator
End Function
Function TList_InsertAfter(pList.TList, Value%)
If pList = Null Then RuntimeError "TList: Tried to insert into non-existing list."
If pList\Iterator = Null Then RuntimeError "TList: TList: Tried to change non-existing list entry."
Local lEntry.TListEntry = New TListEntry
lEntry\Value = Value
If pList\Iterator\NextEntry <> Null Then
lEntry\NextEntry = pList\Iterator\NextEntry
pList\Iterator\NextEntry\PreviousEntry = lEntry
Else
pList\LastEntry = lEntry
EndIf
pList\Iterator\NextEntry = lEntry
If pList\Iterator\PreviousEntry = Null Then
pList\FirstEntry = lEntry
EndIf
lEntry\PreviousEntry = pList\Iterator
End Function
Function TList_Replace(pList.TList, Value%)
If pList = Null Then RuntimeError "TList: Tried to insert into non-existing list."
If pList\Iterator = Null Then RuntimeError "TList: TList: Tried to change non-existing list entry."
pList\Iterator\Value = Value
End Function
Function TList_DeleteFirst(pList.TList)
If pList = Null Then RuntimeError "TList: Tried to insert into non-existing list."
If pList\FirstEntry = Null Then RuntimeError "TList: TList: Tried to change non-existing list entry."
Local lEntry.TListEntry = pList\FirstEntry
pList\FirstEntry\NextEntry\PreviousEntry = Null
pList\FirstEntry = pList\FirstEntry\NextEntry
Delete lEntry
If pList\FirstEntry <> Null Then Return pList\FirstEntry\Value
End Function
Function TList_DeleteLast(pList.Tlist)
If pList = Null Then RuntimeError "TList: Tried to insert into non-existing list."
If pList\LastEntry = Null Then RuntimeError "TList: TList: Tried to change non-existing list entry."
Local lEntry.TListEntry = pList\LastEntry
pList\LastEntry\PreviousEntry\NextEntry = Null
pList\LastEntry = pList\LastEntry\PreviousEntry
Delete lEntry
If pList\LastEntry <> Null Then Return pList\LastEntry\Value
End Function
Function TList_Delete(pList.TList)
If pList = Null Then RuntimeError "TList: Tried to insert into non-existing list."
If pList\Iterator = Null Then RuntimeError "TList: TList: Tried to change non-existing list entry."
If pList\FirstEntry = pList\Iterator Then pList\FirstEntry = pList\Iterator\NextEntry
If pList\LastEntry = pList\Iterator Then pList\LastEntry = pList\Iterator\PreviousEntry
If pList\Iterator\NextEntry <> Null Then pList\Iterator\NextEntry\PreviousEntry = pList\Iterator\PreviousEntry
If pList\Iterator\PreviousEntry <> Null Then pList\Iterator\PreviousEntry\NextEntry = pList\Iterator\NextEntry
Local lEntry.TListEntry = pList\Iterator
pList\Iterator = pList\Iterator\NextEntry
Delete lEntry
If pList\Iterator <> Null Then Return pList\Iterator\Value
End Function
Function TList_DeleteValue(pList.TList, Value%)
If pList = Null Then RuntimeError "TList: Tried to insert into non-existing list."
If pList\FirstEntry <> Null Then
Local lEntry.TListEntry = pList\FirstEntry
While lEntry <> Null
If lEntry\Value = Value Then
If lEntry\PreviousEntry <> Null Then lEntry\PreviousEntry\NextEntry = lEntry\NextEntry
If lEntry\NextEntry <> Null Then lEntry\NextEntry\PreviousEntry = lEntry\PreviousEntry
If pList\FirstEntry = lEntry Then pList\FirstEntry = lEntry\NextEntry
If pList\LastEntry = lEntry Then pList\LastEntry = lEntry\PreviousEntry
Local lDelEntry.TListEntry = lEntry
lEntry = lEntry\NextEntry
Delete lDelEntry
Else
lEntry = lEntry\NextEntry
EndIf
Wend
EndIf
End Function
+27
View File
@@ -0,0 +1,27 @@
Global Logger_Stream
Function Logger_Initialize(File$)
File = "Logs/" + File
CreateDir("./Logs/")
If FileType("./Logs/") <> 2 Then RuntimeError("Unable To create Log File."+Chr(10)+" If the program is running in a protected directory,"+Chr(10)+" consider running it as an administrator.")
Logger_Stream = OpenFile(File)
If Logger_Stream = 0
Logger_Stream = WriteFile(File)
If Logger_Stream = 0 Then RuntimeError("Unable to create log file."+Chr(10)+" If the program is running in a protected directory,"+Chr(10)+" consider running it as an administrator.")
EndIf
End Function
Function Logger_Info(Module$, Message$)
WriteLine Logger_Stream, "[" + CurrentTime() + "] [Info] " + Module + ": " + Message
End Function
Function Logger_Warning(Module$, Message$)
WriteLine Logger_Stream, "[" + CurrentTime() + "] [Warn] " + Module + ": " + Message
End Function
Function Logger_Error(Module$, Message$)
WriteLine Logger_Stream, "[" + CurrentTime() + "] [Errr] " + Module + ": " + Message
End Function
;~IDEal Editor Parameters:
;~C#Blitz3D
+665
View File
@@ -0,0 +1,665 @@
;----------------------------------------------------------------
;-- Packet Descriptors
;----------------------------------------------------------------
;-- Any Packet
;Off Size Desc
; 0 1 Packet Id
;-- Login
;Off Size Desc
; 1 2 Unique Id (Server) / UDP Port (Client)
; 3 2 Version
; 5 16 Name (Always 16B, Only allows bytes above 32)
; 21 4F Initial Position X
; 25 4F Initial Position Y
; 29 4F Initial Position Z
; 33 4F Initial Rotation X
; 37 4F Initial Rotation Y
; 41 4F Initial Rotation Z
;-- Logout
;Off Size Desc
; 1 2 Unique Id
;-- Kick
;Off Size Desc
; 1 2 Reason Length
; 3 ^ Reason
;-- Data
; 1 2 Unique Id
; 3 1 Data Flags (See BNET_DATAFLAG_*)
;... 4F Position X
;... 4F Position Y
;... 4F Position Z
;... 2 Rotation X
;... 2 Rotation Y
;... 2 Rotation Z
;... 2 Velocity X
;... 2 Velocity Y
;... 2 Velocity Z
;... 2 Aim X
;... 2 Aim Y
;-- Action (Yet Unsupported)
;----------------------------------------------------------------
;-- Constants
;----------------------------------------------------------------
; BlitzNet Version
Const BNET_VERSION_MAJOR% = 0
Const BNET_VERSION_MINOR% = 1
; Size of Buffer for Network Packets, 64KB should be enough for now.
Const BNET_BUFFER_SIZE% = (64 * 1024)
; Flags for data changes. Only when the bit is set this data is available.
Const BNET_DATAFLAG_POSX = $00000001
Const BNET_DATAFLAG_POSY = $00000010
Const BNET_DATAFLAG_POSZ = $00000100
Const BNET_DATAFLAG_ROTX = $00001000
Const BNET_DATAFLAG_ROTY = $00010000
Const BNET_DATAFLAG_ROTZ = $00100000
Const BNET_DATAFLAG_VELOCITY = $01000000
Const BNET_DATAFLAG_AIM = $10000000
; Packet Ids, for identification of each one.
Const BNET_PACKET_LOGIN = 0
Const BNET_PACKET_LOGOUT = 1
Const BNET_PACKET_KICK = 2
Const BNET_PACKET_DATA = 3
Const BNET_PACKET_ACTION = 4
; How many updates should we send out each minute?
Const BNET_DATA_COUNT = 150
; How many keyframes should we send out each minute?
Const BNET_DATA_COUNT_KEYFRAME = 3
; How much has the value to change to be considered different?
Const BNET_DATA_THRESHOLD_POS# = 1.0
Const BNET_DATA_THRESHOLD_ROT# = 1.0
Const BNET_DATA_THRESHOLD_VEL# = 1.0
Const BNET_DATA_THRESHOLD_AIM# = 1.0
;----------------------------------------------------------------
;-- Globals
;----------------------------------------------------------------
; Connections to Sector Servers.
Global BNet_Sector_TCP% = 0
Global BNet_Sector_UDP% = 0
; Our UniqueId and Player instance so we know which Player is us.
Global BNet_UniqueId% = -1
Global BNet_Player.BNetPlayer = Null
; Buffer for Network Packets.
Global BNet_Buffer% = CreateBank(BNET_BUFFER_SIZE)
; Set to true when Kicked from the server, or similar.
Global BNet_Kick% = False
Global BNet_Kick_Reason$ = "Not Kicked"
; Update Times
Global BNet_Data_Time = 60000 / BNET_DATA_COUNT
Global BNet_Data_Time_KeyFrame = 60000 / BNET_DATA_COUNT_KEYFRAME
Global BNet_Data_LastUpdate = 0
Global BNet_Data_LastKeyFrame = 0
; Array for all known players. Makes access a bit faster.
Dim BNet_Players.BNetPlayer(65535)
;----------------------------------------------------------------
;-- Types
;----------------------------------------------------------------
Type BNetPlayer
Field Name$ = "Invalid Player"
; Position, Rotation, Velocity and Aim
Field PositionX#, PositionY#, PositionZ#
Field RotationX#, RotationY#, RotationZ#
Field VelocityX#, VelocityY#, VelocityZ#
Field AimX#, AimY#
; Internal Data
Field m_UniqueId%
End Type
;----------------------------------------------------------------
;-- Functions
;----------------------------------------------------------------
Function BNet_Initialize()
TCPTimeouts 100, 100
End Function
Function BNet_Connect(Ip$ = "127.0.0.1", IPort% = 27000, DPort = 27001)
BNet_Kick% = False
BNet_Kick_Reason$ = "Not Kicked"
BNet_Sector_TCP = OpenTCPStream(Ip, IPort)
If BNet_Sector_TCP Then
BNet_Sector_UDP = CreateUDPStream()
If BNet_Sector_UDP Then
Return True
Else
CloseTCPStream BNet_Sector_TCP
BNet_Sector_UDP = 0
BNet_Sector_TCP = 0
EndIf
Else
BNet_Sector_UDP = 0
BNet_Sector_TCP = 0
EndIf
Return False
End Function
Function BNet_Disconnect()
If BNet_UniqueId > -1 Then
; Remove all existing players
For Player.BNetPlayer = Each BNetPlayer
Local UniqueId = Player\m_UniqueId
CB_BNet_DeletePlayer(UniqueId, Player)
Delete BNet_Players(UniqueId):BNet_Players(UniqueId) = Null
Next
; Logout
BNet_Logout()
BNet_UniqueId = -1
EndIf
If BNet_Sector_UDP Then CloseUDPStream(BNet_Sector_UDP):BNet_Sector_UDP = 0
If BNet_Sector_TCP Then CloseTCPStream(BNet_Sector_TCP):BNet_Sector_TCP = 0
End Function
Function BNet_Connected()
If BNet_Sector_TCP = 0 Then Return False
If BNet_Sector_UDP = 0 Then Return False
If Eof(BNet_Sector_TCP) <> 0 Then Return False
Return True
End Function
Function BNet_Login(Name$, PosX# = 0, PosY# = 0, PosZ# = 0, RotX# = 0, RotY# = 0, RotZ# = 0)
If BNet_Connected() And BNet_UniqueId = -1 Then
; Packet Id: Login
PokeByte BNet_Buffer, 0, BNET_PACKET_LOGIN
; Write UDP Port
PokeShort BNet_Buffer, 1, UDPStreamPort(BNet_Sector_UDP)
; Write Client Version
PokeShort BNet_Buffer, 3, BNET_VERSION_MAJOR Shl 8 + BNET_VERSION_MINOR
; Write Name
Local NameLength% = Len(Name)
For NamePos = 1 To NameLength:PokeByte BNet_Buffer, (5 + NamePos - 1), Asc(Mid(Name, NamePos, 1)):Next
For NamePos = NameLength To 16:PokeByte BNet_Buffer, (5 + NamePos - 1), 0:Next
; Write Initial Position
PokeFloat BNet_Buffer, 21, PosX
PokeFloat BNet_Buffer, 25, PosY
PokeFloat BNet_Buffer, 29, PosZ
; Write Initial Rotation
PokeFloat BNet_Buffer, 33, RotX
PokeFloat BNet_Buffer, 37, RotX
PokeFloat BNet_Buffer, 41, RotX
; Write to Stream
WriteBytes BNet_Buffer, BNet_Sector_TCP, 0, 47
Return True
Else
Return False
EndIf
End Function
Function BNet_Logout()
If BNet_Connected() And BNet_UniqueId > -1 Then
; Packet Id: Logout
PokeByte BNet_Buffer, 0, BNET_PACKET_LOGOUT
; Write our own UniqueId
PokeShort BNet_Buffer, 1, BNet_UniqueId
; Write to Stream
WriteBytes BNet_Buffer, BNet_Sector_TCP, 0, 3
Return True
Else
Return False
EndIf
End Function
Function BNet_Update()
Local UniqueId, PacketSize, PacketId, DataFlags, Offset, TempPlayer.BNetPlayer
If BNet_Connected() Then
; TCP
While Not Eof(BNet_Sector_TCP) And ReadAvail(BNet_Sector_TCP) > 0
PacketSize = ReadAvail(BNet_Sector_TCP)
If PacketSize > BNET_BUFFER_SIZE Then PacketSize = BNET_BUFFER_SIZE
ReadBytes(BNet_Buffer, BNet_Sector_TCP, 0, PacketSize)
PacketId = PeekByte(BNet_Buffer, 0)
Select PacketId
Case BNET_PACKET_LOGIN
UniqueId = PeekShort(BNet_Buffer, 1)
BNet_Players(UniqueId) = New BNetPlayer
; Read Name
For NamePos = 1 To 16
Local NameChar = PeekByte(BNet_Buffer, (5 + NamePos - 1))
If NameChar < 32 Then Exit
BNet_Players(UniqueId)\Name$ = BNet_Players(UniqueId)\Name$ + Chr(NameChar)
Next
; Read initital Position
BNet_Players(UniqueId)\PositionX = PeekFloat(BNet_Buffer, 21)
BNet_Players(UniqueId)\PositionY = PeekFloat(BNet_Buffer, 25)
BNet_Players(UniqueId)\PositionZ = PeekFloat(BNet_Buffer, 29)
; Read initial Rotation
BNet_Players(UniqueId)\RotationX = PeekFloat(BNet_Buffer, 33)
BNet_Players(UniqueId)\RotationY = PeekFloat(BNet_Buffer, 37)
BNet_Players(UniqueId)\RotationZ = PeekFloat(BNet_Buffer, 41)
; Assign Unique Id
BNet_Players(UniqueId)\m_UniqueId = UniqueId
; Assign local UniqueId if we don't have one.
If BNet_UniqueId > -1 Then
BNet_UniqueId = UniqueId
Else
CB_BNet_CreatePlayer(UniqueId, BNet_Players(BNet_UniqueId))
EndIf
Case BNET_PACKET_LOGOUT
UniqueId = PeekShort(BNet_Buffer, 1)
; A logout packet for ourselves will make us logout.
If BNet_UniqueId = UniqueId Then
BNet_Disconnect():Return True
ElseIf BNet_Players(UniqueId) <> Null Then
; Otherwise, it is another player removed from visible space.
CB_BNet_DeletePlayer(Unique, BNet_Players(UniqueId))
Delete BNet_Players(UniqueId):BNet_Players(UniqueId) = Null
Else
DebugLog "BNet: Logout for non-existing player."
EndIf
Case BNET_PACKET_KICK
BNet_Kick = True
; Read reason for Kick
Local ReasonLength% = PeekShort(BNet_Buffer, 1)
For ReasonPos = 1 To ReasonLength
Local ReasonChar = PeekByte(BNet_Buffer, (3 + ReasonPos - 1))
If ReasonChar < 32 Then Exit
BNet_Kick_Reason = BNet_Kick_Reason + Chr(NameChar)
Next
BNet_Disconnect():Return True
End Select
Wend
; UDP
While Not Eof(BNet_Sector_UDP) And ReadAvail(BNet_Sector_UDP) > 0
PacketSize = ReadAvail(BNet_Sector_UDP)
If PacketSize > BNET_BUFFER_SIZE Then PacketSize = BNET_BUFFER_SIZE
ReadBytes(BNet_Buffer, BNet_Sector_UDP, 0, PacketSize)
PacketId = PeekByte(BNet_Buffer, 0)
Select PacketId
Case BNET_PACKET_DATA
If BNet_UniqueId > -1 Then
UniqueId = PeekShort(BNet_Buffer, 1)
If BNet_Players(UniqueId) <> Null Then
DataFlags = PeekShort(BNet_Buffer, 3)
Offset% = 5
If DataFlags And BNET_DATAFLAGS_POSX Then BNet_Players(UniqueId)\PositionX = PeekInt(BNet_Buffer, Offset):Offset = Offset + 4
If DataFlags And BNET_DATAFLAGS_POSY Then BNet_Players(UniqueId)\PositionY = PeekInt(BNet_Buffer, Offset):Offset = Offset + 4
If DataFlags And BNET_DATAFLAGS_POSZ Then BNet_Players(UniqueId)\PositionZ = PeekInt(BNet_Buffer, Offset):Offset = Offset + 4
If DataFlags And BNET_DATAFLAGS_ROTX Then BNet_Players(UniqueId)\RotationX = BNet_FloatFromShort(PeekShort(BNet_Buffer, Offset)) * 360.0:Offset = Offset + 2
If DataFlags And BNET_DATAFLAGS_ROTY Then BNet_Players(UniqueId)\RotationY = BNet_FloatFromShort(PeekShort(BNet_Buffer, Offset)) * 360.0:Offset = Offset + 2
If DataFlags And BNET_DATAFLAGS_ROTZ Then BNet_Players(UniqueId)\RotationZ = BNet_FloatFromShort(PeekShort(BNet_Buffer, Offset)) * 360.0:Offset = Offset + 2
If DataFlags And BNET_DATAFLAGS_VELOCITY Then
BNet_Players(UniqueId)\VelocityX = BNet_FloatFromShort(PeekShort(BNet_Buffer, Offset)) * 255.0
BNet_Players(UniqueId)\VelocityY = BNet_FloatFromShort(PeekShort(BNet_Buffer, Offset)) * 255.0
BNet_Players(UniqueId)\VelocityZ = BNet_FloatFromShort(PeekShort(BNet_Buffer, Offset)) * 255.0
Offset = Offset + 6
EndIf
If DataFlags And BNET_DATAFLAGS_AIM Then
BNet_Players(UniqueId)\AimX = BNet_FloatFromShort(PeekShort(BNet_Buffer, Offset)) * 360.0
BNet_Players(UniqueId)\AimY = BNet_FloatFromShort(PeekShort(BNet_Buffer, Offset)) * 360.0
Offset = Offset + 4
EndIf
; Tell Client to update visual stuff
CB_BNet_UpdatePlayer(UniqueId, BNet_Players(UniqueId))
EndIf
EndIf
; Case BNET_PACKET_ACTION
; If BNet_UniqueId > -1 Then
;
; EndIf
End Select
Wend
; If we are logged in, tell the server our current data.
If BNet_UniqueId > -1 Then
Local Time = MilliSecs()
; Send out whatever is needed.
If Time - BNet_Data_LastKeyFrame > BNet_Data_Time_KeyFrame Then
; Force Client to update Player object
CB_BNet_SendUpdate(BNet_UniqueId, BNet_Player)
; Packet Id
PokeByte BNet_Buffer, 0, BNET_PACKET_DATA
; Unique Id
PokeShort BNet_Buffer, 1, BNet_UniqueId
; Data Flags (KeyFrame always has this at 255, since it contains all data)
PokeByte BNet_Buffer, 3, $11111111
; Position
PokeFloat BNet_Buffer, 4, BNet_Player\PositionX
PokeFloat BNet_Buffer, 8, BNet_Player\PositionY
PokeFloat BNet_Buffer,12, BNet_Player\PositionZ
; Rotation
PokeShort BNet_Buffer,16, BNet_ShortFromFloat(BNet_Player\RotationX / 360.0)
PokeShort BNet_Buffer,18, BNet_ShortFromFloat(BNet_Player\RotationY / 360.0)
PokeShort BNet_Buffer,20, BNet_ShortFromFloat(BNet_Player\RotationZ / 360.0)
; Velocity
PokeShort BNet_Buffer,22, BNet_ShortFromFloat(BNet_Player\VelocityX / 256.0)
PokeShort BNet_Buffer,24, BNet_ShortFromFloat(BNet_Player\VelocityY / 256.0)
PokeShort BNet_Buffer,26, BNet_ShortFromFloat(BNet_Player\VelocityZ / 256.0)
; Aim
PokeShort BNet_Buffer,28, BNet_ShortFromFloat(BNet_Player\AimX / 360.0)
PokeShort BNet_Buffer,30, BNet_ShortFromFloat(BNet_Player\AimY / 360.0)
; Send Packet
WriteBytes BNet_Buffer, BNet_Sector_UDP, 0, 32
; Swap Player objects.
TempPlayer = BNet_Player
BNet_Player = BNet_Players(BNet_UniqueId)
BNet_Players(BNet_UnqiueId) = TempPlayer
; Set last keyframe and update time to now.
BNet_Data_LastKeyFrame = Time
BNet_Data_LastUpdate = Time
ElseIf Time - BNet_Data_LastUpdate > BNet_Data_Time Then
DataFlags = 0
Offset = 4
; Force Client to update Player object
CB_BNet_SendUpdate(BNet_UniqueId, BNet_Player)
; Packet Id
PokeByte BNet_Buffer, 0, BNET_PACKET_DATA
; Unique Id
PokeShort BNet_Buffer, 1, BNet_UniqueId
; Position
If Abs(BNet_Player\PositionX - BNet_Players(BNet_UniqueId)\PositionX) > BNET_DATA_THRESHOLD_POS Then
DataFlags = DataFlags Or BNET_DATAFLAG_POSX
PokeFloat BNet_Buffer, Offset, BNet_Player\PositionX:Offset = Offset + 4
EndIf
If Abs(BNet_Player\PositionY - BNet_Players(BNet_UniqueId)\PositionY) > BNET_DATA_THRESHOLD_POS Then
DataFlags = DataFlags Or BNET_DATAFLAG_POSY
PokeFloat BNet_Buffer, Offset, BNet_Player\PositionY:Offset = Offset + 4
EndIf
If Abs(BNet_Player\PositionZ - BNet_Players(BNet_UniqueId)\PositionZ) > BNET_DATA_THRESHOLD_POS Then
DataFlags = DataFlags Or BNET_DATAFLAG_POSZ
PokeFloat BNet_Buffer, Offset, BNet_Player\PositionZ:Offset = Offset + 4
EndIf
; Rotation
If Abs(BNet_Player\RotationX - BNet_Players(BNet_UniqueId)\RotationX) > BNET_DATA_THRESHOLD_POS Then
DataFlags = DataFlags Or BNET_DATAFLAG_ROTX
PokeFloat BNet_Buffer, Offset, BNet_ShortFromFloat(BNet_Player\RotationX / 360.0):Offset = Offset + 2
EndIf
If Abs(BNet_Player\RotationY - BNet_Players(BNet_UniqueId)\RotationY) > BNET_DATA_THRESHOLD_POS Then
DataFlags = DataFlags Or BNET_DATAFLAG_ROTY
PokeFloat BNet_Buffer, Offset, BNet_ShortFromFloat(BNet_Player\RotationY / 360.0):Offset = Offset + 2
EndIf
If Abs(BNet_Player\RotationZ - BNet_Players(BNet_UniqueId)\RotationZ) > BNET_DATA_THRESHOLD_POS Then
DataFlags = DataFlags Or BNET_DATAFLAG_ROTZ
PokeFloat BNet_Buffer, Offset, BNet_ShortFromFloat(BNet_Player\RotationZ / 360.0):Offset = Offset + 2
EndIf
; Velocity
If Abs(BNet_Player\VelocityX - BNet_Players(BNet_UniqueId)\VelocityX) + Abs(BNet_Player\VelocityY - BNet_Players(BNet_UniqueId)\VelocityY) + Abs(BNet_Player\VelocityZ - BNet_Players(BNet_UniqueId)\VelocityZ) > BNET_DATA_THRESHOLD_VEL Then
DataFlags = DataFlags Or BNET_DATAFLAG_VELOCITY
PokeFloat BNet_Buffer, Offset, BNet_ShortFromFloat(BNet_Player\VelocityX / 256.0):Offset = Offset + 2
PokeFloat BNet_Buffer, Offset, BNet_ShortFromFloat(BNet_Player\VelocityY / 256.0):Offset = Offset + 2
PokeFloat BNet_Buffer, Offset, BNet_ShortFromFloat(BNet_Player\VelocityZ / 256.0):Offset = Offset + 2
EndIf
; Aim
If Abs(BNet_Player\AimX - BNet_Players(BNet_UniqueId)\AimX) + Abs(BNet_Player\AimY - BNet_Players(BNet_UniqueId)\AimY) > BNET_DATA_THRESHOLD_AIM Then
DataFlags = DataFlags Or BNET_DATAFLAG_AIM
PokeFloat BNet_Buffer, Offset, BNet_ShortFromFloat(BNet_Player\AimX / 360.0):Offset = Offset + 2
PokeFloat BNet_Buffer, Offset, BNet_ShortFromFloat(BNet_Player\AimY / 360.0):Offset = Offset + 2
EndIf
; Data Flags
PokeByte BNet_Buffer, 3, DataFlags
; Send Packet
WriteBytes BNet_Buffer, BNet_Sector_UDP, 0, Offset
; Swap Player objects.
TempPlayer = BNet_Player
BNet_Player = BNet_Players(BNet_UniqueId)
BNet_Players(BNet_UnqiueId) = TempPlayer
; Set last update time to now.
BNet_Data_LastUpdate = Time
EndIf
EndIf
Else
Return False
EndIf
End Function
Function BNet_FloatFromShort#(Value%)
Return BNet_Math_ClipF((Value / 65536.0), 0.0, 1.0)
End Function
Function BNet_ShortFromFloat%(Value#)
Return BNet_Math_ClipF((Value * 65536.0), 0.0, 1.0)
End Function
Function BNet_Math_MinimumF#(Value#, Min#)
If Value < Min Then Return Min
Return Value
End Function
Function BNet_Math_MaximumF#(Value#, Max#)
If Value > Max Then Return Max
Return Value
End Function
Function BNet_Math_ClampF#(Value#, Min#, Max#)
If Value < Min Then Return Min
If Value > Max Then Return Max
Return Value
End Function
Function BNet_Math_ClipF#(Value#, Min#, Max#)
Local Out#, Diff#
Diff = Max - Min:Out = Value - Min
If (Out >= Diff) Or (Out < 0) Then Out = Out - (Floor(Out/Diff) * Diff)
Return Min + Out
End Function
;----------------------------------------------------------------
;-- Callbacks
;----------------------------------------------------------------
;Function CB_BNet_CreatePlayer(UniqueId, Player.BNetPlayer)
;End Function
;Function CB_BNet_UpdatePlayer(UniqueId, Player.BNetPlayer)
;End Function
;Function CB_BNet_DeletePlayer(UniqueId, Player.BNetPlayer)
;End Function
;Function CB_BNet_SendUpdate(UniqueId, Player.BNetPlayer)
;End Function
;----------------------------------------------------------------
;-- Example
;----------------------------------------------------------------
Graphics3D 800, 600, 32, 2
SetBuffer BackBuffer()
SeedRnd MilliSecs()
Local FrameTimer = CreateTimer(60)
Local TimeToLogin = MilliSecs()
Dim Players.TPlayer(65535)
Local Player.TPlayer = Null
Global TestX#, TestY#, TestZ#
Global TestRX#, TestRY#, TestRZ#
Global TestVX#, TestVY#, TestVZ#
Global TestAX#, TestAY#
Local ShipVeloLR#, ShipVeloUD#, ShipVeloFB#
Const ShipMaxVeloLR# = 5.0, ShipMaxVeloUD# = 5.0, ShipMaxVeloFB = 30.0
; Init
TestX = Rnd(-2048, 2048)
TestY = Rnd(-2048, 2048)
TestZ = Rnd(-2048, 2048)
TestRX = Rnd(0, 360)
TestRY = Rnd(0, 360)
TestRZ = Rnd(0, 360)
TestVX = 0
TestVY = 0
TestVZ = 0
TestAX = 0
TestAY = 0
Local Cam = CreateCamera()
Local Conv = CreatePivot()
Print "[INF] Connecting..."
BNet_Initialize()
BNet_Connect()
If BNet_Connected() Then
Print "[INF] Logging in..."
BNet_Login("Test " + Rand(0, 65535), TestX, TestY, TestZ, TestRX, TestRY, TestRZ)
Local LoopExit = False
Local Load = False
Repeat
If Load = False And BNet_UniqueId = -1 And (MilliSecs() - TimeToLogin > 30000) Then
Print "[ERR] Failed to login."
LoopExit = True
ElseIf Load = False And BNet_UniqueId > -1 Then
Print "[INF] Logged in."
Player = New TPlayer
Player\Mesh = CreateCone()
Player\Player = BNet_Player
Players(BNet_UniqueId) = Player
EntityParent Cam, Player\Mesh
Load = True
ElseIf Load = True And BNet_UniqueId > -1
; Player Input
; Velocity
ShipVeloFB = BNet_Math_ClampF(ShipVeloFB + (KeyDown(17) - KeyDown(31)) * 2.5, -ShipMaxVeloFB, ShipMaxVeloFB)
ShipVeloLR = BNet_Math_ClampF(ShipVeloLR + (KeyDown(32) - KeyDown(30)) * 1.5, -ShipMaxVeloLR, ShipMaxVeloLR)
ShipVeloUD = BNet_Math_ClampF(ShipVeloUD + (KeyDown(19) - KeyDown(33)) * 1.5, -ShipMaxVeloUD, ShipMaxVeloUD)
; Rotation
If KeyDown(57) Then
If KeyHit(57) Then MoveMouse 512, 384
TestRX = TestRX + ((MouseX() / 512) - 1.0)
TestRY = TestRY + ((MouseY() / 384) - 1.0)
EndIf
TestRZ = TestRZ + (KeyDown(18) - KeyDown(16)) * 1.0
; Update Game
; Slowly scale down Velocity.
ShipVeloFB = ShipVeloFB * 0.9
ShipVeloLR = ShipVeloLR * 0.8
ShipVeloUD = ShipVeloUD * 0.8
; Convert Local Velocity to Global Velocity
TFormPoint ShipVeloLR, ShipVeloUD, ShipVeloFB, Player\Mesh, Conv
TestVX = TFormedX()
TestVY = TFormedY()
TestVZ = TFormedZ()
; Move player by Velocity.
TestX = TestX + TestVX
TestY = TestY + TestVY
TestZ = TestZ + TestVZ
; Draw Game
; Update Local Mesh
PositionEntity Player\Mesh, TestX, TestY, TestZ
RotateEntity Player\Mesh, TestRX, TestRY, TestRZ
; Update conversion point
PositionEntity Conv, TestX, TestY, TestZ
RenderWorld
Flip 0
EndIf
If BNet_Update() Then
LoopExit = True
EndIf
WaitTimer FrameTimer
Until (LoopExit = True)
If BNet_Kick = True Then Print "[INF] Kicked: " + BNet_Kick_Reason Else Print "Logging out."
BNet_Disconnect()
Else
Print "[ERR] Failed to connect."
EndIf
End
Function CB_BNet_CreatePlayer(UniqueId, Player.BNetPlayer)
DebugLog "[INF] New Player: " + Player\Name + "[" + UniqueId + "]"
DebugLog " Pos: " + Player\PositionX + ", " + Player\PositionY + ", " + Player\PositionZ
DebugLog " Rot: " + Player\RotationX + ", " + Player\RotationY + ", " + Player\RotationZ
If Players(UniqueId) = Null Then Players(UniqueId) = New TPlayer
If Players(UniqueId)\Mesh <> 0 Then Players(UniqueId)\Mesh = CreateCone()
Players(UniqueId)\Player = Player
PositionEntity Players(UniqueId)\Mesh, Player\PositionX, Player\PositionY, Player\PositionZ
RotateEntity Players(UniqueId)\Mesh, Player\RotationX, Player\RotationY, Player\RotationZ
End Function
Function CB_BNet_UpdatePlayer(UniqueId, Player.BNetPlayer)
If Players(UniqueId) <> Null Then
DebugLog "[INF] Update Player: " + Player\Name + "[" + UniqueId + "]"
DebugLog " Pos: " + Player\PositionX + ", " + Player\PositionY + ", " + Player\PositionZ
DebugLog " Rot: " + Player\RotationX + ", " + Player\RotationY + ", " + Player\RotationZ
PositionEntity Players(UniqueId)\Mesh, Player\PositionX, Player\PositionY, Player\PositionZ
RotateEntity Players(UniqueId)\Mesh, Player\RotationX, Player\RotationY, Player\RotationZ
Else
DebugLog "[ERR] Player does not exist: " + Player\Name + "[" + UniqueId + "]"
EndIf
End Function
Function CB_BNet_DeletePlayer(UniqueId, Player.BNetPlayer)
If Players(UniqueId) <> Null Then
DebugLog "[INF] Delete Player: " + UniqueId + "," + Player\Name
FreeEntity Players(UniqueId)\Mesh
Delete Players(UniqueId)
Else
DebugLog "[ERR] Player does not exist: " + Player\Name + "[" + UniqueId + "]"
EndIf
End Function
Function CB_BNet_SendUpdate(UniqueId, Player.BNetPlayer)
DebugLog "[INF] Update Self"
Player\PositionX = TestX
Player\PositionY = TestY
Player\PositionZ = TestZ
Player\VelocityX = TestVX
Player\VelocityY = TestVY
Player\VelocityZ = TestVZ
Player\RotationX = TestRX
Player\RotationY = TestRY
Player\RotationZ = TestRZ
Player\AimX = TestAX
Player\AimY = TestAY
End Function
Type TPlayer
Field Mesh
Field Player.BNetPlayer
End Type
+8
View File
@@ -0,0 +1,8 @@
Random Stuff
=======================
Contains remaining projects that don't require their own folder or were modified to fit a specific project. Most of this is from Sirius Online and BlitzHit, so expect nothing to work.
License
=======
Random Stuff 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/.
+44
View File
@@ -0,0 +1,44 @@
AppTitle "TrueMotion"
Include "TrueMotion.bb"
Graphics3D 1024,768,0,2
SetBuffer BackBuffer()
SeedRnd MilliSecs()
Local eCamera = CreateCamera()
Local tCube = CreateTexture(128,128)
SetBuffer TextureBuffer(tCube)
Color 255, 255, 0
Rect 0, 0, 64, 64
Rect 64, 64, 64, 64
Color 0, 127, 255
Rect 64, 0, 64, 64
Rect 0, 64, 64, 64
SetBuffer BackBuffer()
Local eCube = CreateCube()
PositionEntity eCube, 0, 0, 3
EntityTexture eCube, tCube
Local tInstance.TrueMotion = TrueMotion_Create(eCamera)
Timer = CreateTimer(60)
Global Msec
While Not KeyHit(1)
Cls
Msec = Msec + 10
RotateEntity eCube, Cos(Msec/4.0)*30, 0, EntityRoll(eCube) + 16
PositionEntity eCube, 0, Sin(Msec/4.0)*2, 4
TrueMotion_RenderWorld(tInstance)
Flip
WaitTimer(Timer)
Wend
End
;~IDEal Editor Parameters:
;~C#Blitz3D
+207
View File
@@ -0,0 +1,207 @@
Type Tradelane
Field P1.TVector, P2.TVector, Dir.TVector
Field From$, Target$
Field FromSpot.Spotmark, TargetSpot.Spotmark
Field Gates.TList, Lasers.TList
Field RingsTop.TList, RingsBot.TList
Field RingsInnerTop.TList, RingsInnerBot.TList
Field TubesTop.TList, TubesBot.TList
Field PivotTubes
Field PivotRings
Field MeshA, MeshB, OBBa, OBBb
Field XTubeA, XTubeB
Field Range
End Type
Const Tradelane_Speed# = 50.0
Const Tradelane_SpeedForce# = 0.125
Const Tradelane_Force# = 0.1
Const Tradelane_GateDistance# = 5000.0
Const Tradelane_Offset# = 144
Const Tradelane_Size# = 115
Function CreateTradelane(StartX,StartY,StartZ, EndX,EndY,EndZ, From$, Target$)
Local T.Tradelane = New Tradelane
Local TempVec.TVector
; Information
T\From = From:T\Target = Target
; Start, End and Direction Vector
T\P1 = TVector_Create(StartX, StartY, StartZ)
T\P2 = TVector_Create(EndX, EndY, EndZ)
TempVec = TVector_Subtract(T\P2, T\P1)
T\Dir = TVector_Normalize(TempVec):Delete TempVec
Local Range# = TVector_Distance(T\P1, T\P2)
; Initialize LinkedLists
T\Gates = TList_Create()
T\Lasers = TList_Create()
T\RingsTop = TList_Create()
T\RingsBot = TList_Create()
T\RingsInnerTop = TList_Create()
T\RingsInnerBot = TList_Create()
T\TubesTop = TList_Create()
T\TubesBot = TList_Create()
T\PivotRings = CreatePivot(PVTxEFFECT)
T\PivotTubes = CreatePivot(PVTxEFFECT)
; Create Spots
T\FromSpot.Spotmark = CreateSpot(T\P1\X, T\P1\Y, T\P1\Z, 21, (From + ">>>" + Target))
T\FromSpot.Spotmark = CreateSpot(T\P2\X, T\P2\Y, T\P2\Z, 21, (Target + ">>>" + From))
; Create OBB Collisions
TVector_Angle(T\Dir)
Local TX#, TY#, TZ#
TX = (T\P1\X + T\P2\X) / 2.0
TY = (T\P1\Y + T\P2\Y) / 2.0
TZ = (T\P1\Z + T\P2\Z) / 2.0
Local TVecUp.TVector = TVector_Rotate(T\Dir, -90, 0, 0)
T\OBBa=CreateOBB(TX, TY, TZ, TVector_Pitch-90, TVector_Yaw, 0, 115, 115, Range/2)
T\OBBb=CreateOBB(TX, TY, TZ, TVector_Pitch-90, TVector_Yaw, 0, 115, 115, Range/2)
MoveEntity T\OBBa, 0, Tradelane_Offset, 0
MoveEntity T\OBBb, 0, -Tradelane_Offset, 0
Delete TVecUp
; Create Gates, Sprites and Rings
Local Count = Ceil(Range / Tradelane_GateDistance)
Local Stp# = Range / Count
For n = 0 To Count
; Calculate Position
TempVec = TVector_MultiplyScalar(T\Dir, n*Stp)
Local Pos.TVector = TVector_Add(T\P1, TempVec)
; Create Mesh
Local Mesh = CopyEntity(TLxMSH, PVTxNORMAL)
PositionEntity Mesh, Pos\X, Pos\Y, Pos\Z
AlignToVector Mesh, T\Dir\X, T\Dir\Y, T\Dir\Z, 0, 1
RotateEntity Mesh, EntityPitch(Mesh, 1), EntityYaw(Mesh, 1), 0, 1
EntityAutoFade Mesh,14500,15000
TList_AddLast(T\Gates, Mesh)
; Create Laser
Local Laser = CopyEntity(TLxMSX, Mesh)
EntityAutoFade Laser,9500,10000
TList_AddLast(T\Lasers, Laser)
; Create Rings
Local RingTop = CopyEntity(TLxENT, Mesh)
Local RingBot = CopyEntity(TLxENT, Mesh)
MoveEntity RingTop, 0, Tradelane_Offset, 0
MoveEntity RingBot, 0, -Tradelane_Offset, 0
ScaleSprite RingTop, 125, 125:SpriteViewMode RingTop, 2:EntityColor RingTop, 64, 198, 255:EntityAlpha RingTop, 0.5:EntityAutoFade RingTop, 4500, 5000:EntityBlend RingTop, 3:EntityFX RingTop, 1+16
ScaleSprite RingBot, 125, 125:SpriteViewMode RingBot, 2:EntityColor RingBot, 255, 0, 0:EntityAlpha RingBot, 0.5:EntityAutoFade RingBot, 4500, 5000:EntityBlend RingBot, 3:EntityFX RingBot, 1+16
TList_AddLast(T\RingsTop, RingTop)
TList_AddLast(T\RingsBot, RingBot)
Local RingInTop = CopyEntity(TLxENT2, Mesh)
Local RingInBot = CopyEntity(TLxENT2, Mesh)
MoveEntity RingInTop, 0, Tradelane_Offset, 0
MoveEntity RingInBot, 0, -Tradelane_Offset, 0
ScaleSprite RingInTop, 125, 125:SpriteViewMode RingInTop, 2:EntityAlpha RingInTop, 0.5:EntityAutoFade RingInTop, 4500, 5000:EntityBlend RingInTop, 3:EntityFX RingInTop, 1+16
ScaleSprite RingInBot, 125, 125:SpriteViewMode RingInBot, 2:EntityAlpha RingInBot, 0.5:EntityAutoFade RingInBot, 4500, 5000:EntityBlend RingInBot, 3:EntityFX RingInBot, 1+16
TList_AddLast(T\RingsInnerTop, RingInTop)
TList_AddLast(T\RingsInnerBot, RingInBot)
; Create Refraction Tubes
If n < Count
Local Tube
Tube = CreateCylinder(24, 0, RingInTop)
ScaleEntity Tube, Tradelane_Size, Stp/2, Tradelane_Size
TurnEntity Tube, -90, 0, 0
MoveEntity Tube, 0, -Stp/2, 0
EntityParent Tube, T\PivotTubes
EntityAutoFade Tube, 5000, 10000
EntityFX Tube, 1+8+16
EntityTexture Tube,StarBTex,0,0
EntityTexture Tube,ProjectTex,0,1
EntityAlpha Tube, 0.35
TList_AddLast(T\TubesTop, Tube)
Tube = CreateCylinder(24, 0, RingInBot)
ScaleEntity Tube, Tradelane_Size, Stp/2, Tradelane_Size
TurnEntity Tube, 90, 0, 0
MoveEntity Tube, 0, Stp/2, 0
EntityParent Tube, T\PivotTubes
EntityAutoFade Tube, 5000, 10000
EntityFX Tube, 1+8+16
EntityTexture Tube,StarBTex,0,0
EntityTexture Tube,ProjectTex,0,1
EntityAlpha Tube, 0.35
TList_AddLast(T\TubesBot, Tube)
EndIf
; Delete remaining temporary data
Delete Pos:Delete TempVec
Next
End Function
Function UpdateTradelane()
;set test on
TLxTST=0
; Create Camera Vector
Local vCam.TVector = New TVector
Local vGate.TVector = New TVector
Local vTmp.TVector = Null
Local vTmp2.TVector = Null
vCam\X = EntityX(cCamera, 1)
vCam\Y = EntityY(cCamera, 1)
vCam\Z = EntityZ(cCamera, 1)
For TL.Tradelane = Each Tradelane
; Rings
TList_Reset(TL\RingsTop):TList_Reset(TL\RingsInnerTop)
TList_Reset(TL\RingsBot):TList_Reset(TL\RingsInnerBot)
TList_Reset(TL\Gates)
While TList_HasNext(TL\Gates)
Local RT = TList_Next(TL\RingsTop)
Local RTI = TList_Next(TL\RingsInnerTop)
Local RB = TList_Next(TL\RingsBot)
Local RBI = TList_Next(TL\RingsInnerBot)
Local Gate = TList_Next(TL\Gates)
TurnEntity RT, 0, 0, -.1
TurnEntity RB, 0, 0, .1
vGate\X = EntityX(Gate, 1)
vGate\Y = EntityY(Gate, 1)
vGate\Z = EntityZ(Gate, 1)
vTmp = TVector_Subtract(vGate, vCam)
vTmp2 = TVector_Normalize(vTmp):Delete vTmp
Local Dot# = TVector_Dot(TL\Dir, vTmp2):Delete vTmp2
If Dot >= 0 Then
EntityColor RT, 64, 198, 255
EntityColor RB, 255, 0, 0
Else
EntityColor RB, 64, 198, 255
EntityColor RT, 255, 0, 0
EndIf
Wend
; Traveling
If EntityInOBB(TL\OBBa,pvShip)
AlignToVector pvShip, TL\Dir\X, TL\Dir\Y, TL\Dir\Z, 0, Tradelane_Force
ShipSpeedZ = (ShipSpeedZ * (1-Tradelane_SpeedForce)) + (Tradelane_Speed * Tradelane_SpeedForce)
TLxTST=1
EndIf
If EntityInOBB(TL\OBBB,pvShip)
AlignToVector pvShip, -TL\Dir\X, -TL\Dir\Y, -TL\Dir\Z, 0, Tradelane_Force
ShipSpeedZ = (ShipSpeedZ * (1-Tradelane_SpeedForce)) + (Tradelane_Speed * Tradelane_SpeedForce)
TLxTST=1
EndIf
Next
Delete vCam:Delete vGate
PositionTexture StarBTex, Sin(MilliSecs() / 10000.0), (MilliSecs() / 10000.0) Mod 1
End Function
;~IDEal Editor Parameters:
+51
View File
@@ -0,0 +1,51 @@
Type TrueMotion
Field Camera% = 0
Field Mesh% = 0
End Type
Function TrueMotion_Create.TrueMotion(Camera%)
;Create TrueMotion Instance
tInstance.TrueMotion = New TrueMotion
; Camera can't be Null or invalid
If Camera = 0 Then
RuntimeError "TrueMotion: Camera is Null."
Else
If EntityClass(Camera) <> "Camera" Then
RuntimeError "TrueMotion: Camera is not of type <Camera>."
Else
tInstance\Camera = Camera
EndIf
EndIf
; Create Mesh
tInstance\Mesh = CreateMesh(tInstance\Camera)
sSurface = CreateSurface(tInstance\Mesh)
AddVertex(sSurface, -1, 1, 0, 0, 0)
AddVertex(sSurface, 1, 1, 0, 1, 0)
AddVertex(sSurface, 1, -1, 0, 1, 1)
AddVertex(sSurface, -1, -1, 0, 0, 1)
AddTriangle(sSurface, 0, 1, 2)
AddTriangle(sSurface, 0, 2, 3)
EntityOrder(tInstance\Mesh, -1)
EntityColor(tInstance\Mesh, 0, 0, 0)
PositionEntity(tInstance\Mesh, 0, 0, 1)
HideEntity(tInstance\Mesh)
Return tInstance
End Function
; Call this before after you have done your changes. It is a good practice to only let this effect affect nearby entities.
Function TrueMotion_RenderWorld(tInstance.TrueMotion, Steps%=12)
ShowEntity(tInstance\Mesh)
EntityAlpha(tInstance\Mesh, 1.0/Steps)
CameraClsMode(tInstance\Camera, 0, 1)
For curStep = 0 To Steps - 1
RenderWorld curStep/Float(Steps)
Next
HideEntity(tInstance\Mesh)
RenderWorld 1
CameraClsMode(tInstance\Camera, 1, 1)
CaptureWorld
End Function
+161
View File
@@ -0,0 +1,161 @@
;VectorMath.bb
Type TVector
Field X#,Y#,Z#
End Type
Global VectorForward.TVector = TVector_Create( 0, 0, 1)
Global VectorBackward.TVector = TVector_Create( 0, 0, -1)
Global VectorLeft.TVector = TVector_Create(-1, 0, 0)
Global VectorRight.TVector = TVector_Create( 1, 0, 0)
Global VectorUp.TVector = TVector_Create( 0, 1, 0)
Global VectorDown.TVector = TVector_Create( 0, -1, 0)
Function TVector_Create.TVector(X#,Y#,Z#)
Local R.TVector = New TVector
R\X = X
R\Y = Y
R\Z = Z
Return R
End Function
Function TVector_Copy.TVector(A.TVector)
Return TVector_Create(A\X,A\Y,A\Z)
End Function
Function TVector_Add.TVector(A.TVector, B.TVector)
Local R.TVector = New TVector
R\X = A\X + B\X
R\Y = A\Y + B\Y
R\Z = A\Z + B\Z
Return R
End Function
Function TVector_AddScalar.TVector(A.TVector, B#)
Local R.TVector = New TVector
R\X = A\X + B
R\Y = A\Y + B
R\Z = A\Z + B
Return R
End Function
Function TVector_Subtract.TVector(A.TVector, B.TVector)
Local R.TVector = New TVector
R\X = A\X - B\X
R\Y = A\Y - B\Y
R\Z = A\Z - B\Z
Return R
End Function
Function TVector_SubtractScalar.TVector(A.TVector, B#)
Local R.TVector = New TVector
R\X = A\X - B
R\Y = A\Y - B
R\Z = A\Z - B
Return R
End Function
Function TVector_Multiply.TVector(A.TVector, B.TVector)
Local R.TVector = New TVector
R\X = A\X * B\X
R\Y = A\Y * B\Y
R\Z = A\Z * B\Z
Return R
End Function
Function TVector_MultiplyScalar.TVector(A.TVector, B#)
Local R.TVector = New TVector
R\X = A\X * B
R\Y = A\Y * B
R\Z = A\Z * B
Return R
End Function
Function TVector_Divide.TVector(A.TVector, B.TVector)
Local R.TVector = New TVector
R\X = A\X / B\X
R\Y = A\Y / B\Y
R\Z = A\Z / B\Z
Return R
End Function
Function TVector_DivideScalar.TVector(A.TVector, B#)
Local R.TVector = New TVector
R\X = A\X / B
R\Y = A\Y / B
R\Z = A\Z / B
Return R
End Function
Function TVector_Normalize.TVector(A.TVector, MultiPass%=True)
Local R1.TVector, R.TVector
R = TVector_DivideScalar(A, TVector_Length(A))
If MultiPass Then
R1 = R
R = TVector_DivideScalar(R1, TVector_Length(R1))
Delete R1
EndIf
Return R
End Function
Function TVector_Rotate.TVector(A.TVector, Pitch#, Yaw#, Roll#)
Local M1.TVector = TVector_Create(Cos(Roll) * Cos(Yaw), -Sin(Roll), Sin(Yaw))
Local M2.TVector = TVector_Create(Sin(Roll), Cos(Roll) * Cos(Pitch), -Sin(Pitch))
Local M3.TVector = TVector_Create(-Sin(Yaw), Sin(Pitch), Cos(Yaw) * Cos(Pitch))
Local R.TVector = New TVector
R\X = (A\X * M1\X) + (A\Y * M1\Y) + (A\Z * M1\Z)
R\Y = (A\X * M2\X) + (A\Y * M2\Y) + (A\Z * M2\Z)
R\Z = (A\X * M3\X) + (A\Y * M3\Y) + (A\Z * M3\Z)
Delete M1:Delete M2:Delete M3:Return R
End Function
Function TVector_RotateAround.TVector(A.TVector, B.TVector, Pitch#, Yaw#, Roll#)
Local R1.TVector = TVector_Subtract(A, B)
Local R2.TVector = TVector_Rotate(R1, Pitch, Yaw, Roll)
Local R3.TVector = TVector_Add(R2, B)
Delete R1:Delete R2:Return R3
End Function
Function TVector_RotateAroundScalar.TVector(A.TVector, X#, Y#, Z#, Pitch#, Yaw#, Roll#)
Local B.TVector = TVector_Create(X,Y,Z)
Local R.TVector = TVector_RotateAround(A, B, Pitch, Yaw, Roll)
Delete B:Return R
End Function
Function TVector_Dot#(A.TVector, B.TVector)
Return ((A\X*B\X)+(A\Y*B\Y)+(A\Z*B\Z))
End Function
Function TVector_Cross.TVector(A.TVector, B.TVector)
Local R.TVector = New TVector
R\X = (A\Y*B\Z) - (A\Z*B\Y)
R\Y = (A\Z*B\X) - (A\X*B\Z)
R\Z = (A\X*B\Y) - (A\Y*B\X)
Return R
End Function
Global TVector_Pitch#, TVector_Yaw#
Function TVector_Angle(A.TVector) ; X
TVector_Pitch = VectorPitch(A\X, A\Y, A\Z);-ATan2(A\Y, Sqr((A\X*A\X) + (A\Z*A\Z))) + 90
TVector_Yaw# = VectorYaw(A\X, A\Y, A\Z);ATan2(A\Z, A\X) - 90
End Function
Function TVector_PitchFrom#(A.TVector, B.TVector) ; X
;Return ATan2(A\Y-B\Y, A\Z-B\Z)
Return VectorPitch(A\X-B\X, A\Y-B\Y, A\Z-B\Z)
End Function
Function TVector_YawFrom#(A.TVector, B.TVector) ; Y
;Return ATan2(A\Z-B\Z, A\X-B\X)
Return VectorYaw(A\X-B\X, A\Y-B\Y, A\Z-B\Z)
End Function
;Function TVector_RollFrom#(A.TVector, B.TVector) ; Z
; Return ATan2(A\Y-B\Y, A\X-B\X)
;End Function
Function TVector_Length#(A.TVector)
Return Sqr((A\X*A\X)+(A\Y*A\Y)+(A\Z*A\Z))
End Function
Function TVector_Distance#(A.TVector, B.TVector)
Local X# = (A\X-B\X)
Local Y# = (A\Y-B\Y)
Local Z# = (A\Z-B\Z)
Return Sqr(X*X+Y*Y+Z*Z)
End Function
Function TVector_ToString$(A.TVector)
Return "{X:"+A\X+";Y:"+A\Y+";Z:"+A\Z+"}"
End Function
;~IDEal Editor Parameters:
;~C#Blitz3D
@@ -0,0 +1,8 @@
Sirius Online Inventory
=======================
This was ment to be in the Sirius Online project, but the lead devloper never got further than complaining. So it has the side-effect of not working.I planned to optimize it to use as little memory and network bandwidth as possible, but the project was abandoned before I could go that far. Right now, it probably doesn't even work.
License
=======
Sirius Online Inventory 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/.
@@ -0,0 +1,407 @@
;----------------------------------------------------------------
;-- Constants
;----------------------------------------------------------------
Const ITEM_MAXIMUMID = 65535
; Item Classes
Const ITEM_CLASS_WEAPON = 1
Const ITEM_CLASS_SHIELD = 2
Const ITEM_CLASS_ARMOR = 3
Const ITEM_CLASS_ENGINE = 4
Const ITEM_CLASS_POWERCORE = 5
Const ITEM_CLASS_RESOURCE = 6
Const ITEM_CLASS_UPGRADE = 7
Const ITEM_CLASS_MININGMODULE = 8
Const ITEM_CLASS_ELITIUM = 255
; Return Codes
Const INVENTORY_RC_OK = 0
Const INVENTORY_RC_INVALIDID = -1
Const INVENTORY_RC_INVALIDAMOUNT = -2
Const INVENTORY_RC_UNKNOWNITEM = -3
Const INVENTORY_RC_ITEMTOOBIG = -4
Const INVENTORY_RC_ITEMNOTFOUND = -5
;----------------------------------------------------------------
;-- Types
;----------------------------------------------------------------
; Item Definition
Type TItem
Field ID%
Field Name$ ; Name of the Item
Field Description$ ; Description of the Item
Field Image ; Handle of the Image for the Item
Field Size% ; Size in cubic decimeters. Divide by 1000 to get the size in cube meters, which is displayed.
Field Rarity% ; Rarity
Field Class% ; Class of the Item.
Field AttributeID0%
Field AttributeID1%
Field AttributeID2%
Field AttributeID3%
; Attributes for Class: Weapon
; - Short/255 Electric Damage (Attribute 0 High)
; - Short/255 Physical Damage (Attribute 0 Low)
; - Short/255 Rate of Fire (Attribute 1 High)
; - Short Energy (Attribute 3 High)
; - Short/255 CPU (Attribute 3 Low)
; Attributes for Class: Shield
; - Int Shield Maximum (Attribute 0)
; - Short/255 Electric Resist (Attribute 1 High)
; - Short/255 Physical Resist (Attribute 1 Low)
; - Short Recharge Amount (Attribute 2 High)
; - Short Recharge Rate (Attribute 2 Low)
; - Short/255 CPU (Attribute 3 Low)
; Attributes for Class: Armor
; - Int Armor Maximum (Attribute 0)
; - Short/255 Speed Modifier (Attribute 1 High)
; - Short/255 Turn Modifier (Attribute 1 Low)
; - Short/255 Signature Mod. (Attribute 2 High)
; Attributes for Class: Engine
; - Short/255 Maximum Speed (Attribute 0 High)
; - Short/255 Maximum Boost (Attribute 0 Low)
; - Short Trace Type (Attribute 2 High)
; - Short/255 Trace Threshold (Attribute 2 Low)
; - Short Energy (Attribute 3 High)
; - Short/255 CPU (Attribute 3 Low)
; Attributes for Class: PowerCore
; - Int Energy Maximum (Attribute 0)
; - Short Energy Amount (Attribute 1 High)
; - Short Energy Rate (Attribute 1 Low)
; - Byte Elec. Signature (Attribute 2 High 1)
; - Byte Scramble Str. (Attribute 2 High 0)
; - Short/255 CPU (Attribute 3 Low)
; Attributes for Class: Resource
; - Byte Processing Tier (Attribute 0 Low 1)
; - Byte Load Type (Attribute 0 Low 0)
; - Int Half-life Time (Attribute 3)
; Attributes for Class: Upgrade
; - Byte/127 Armor Bonus (Attribute 0 High 1)
; - Byte/127 Shield Bonus (Attribute 0 High 0)
; - Byte/127 Speed Bonus (Attribute 0 Low 1)
; - Byte/127 Cargo Bonus (Attribute 0 Low 0)
; - Byte/127 Elec. Sig. Mod. (Attribute 1 High 1)
; - Byte/127 Grav. Sig. Mod. (Attribute 1 High 0)
; - Byte/127 Elec. Dmg. Mod. (Attribute 1 Low 1)
; - Byte/127 Phys. Dmg. Mod. (Attribute 1 Low 0)
; - Byte/127 El. ShRes Mod. (Attribute 2 High 1)
; - Byte/127 Ph. ShRes Mod. (Attribute 2 High 0)
; - Byte/127 El. ArRes Mod. (Attribute 2 Low 1)
; - Byte/127 Ph. ArRes Mod. (Attribute 2 Low 0)
; - Byte Scramble Str. (Attribute 3 High 1)
; - Byte/127 Yield Bonus (Attribute 3 High 0)
; - Byte Energy Max (Attribute 3 Low 1)
; - Byte/127 CPU Modifier (Attribute 3 Low 0)
; Attributes for Class: Mining Module
; -
; Attributes for Class: Elitium
; -
End Type
Dim Items.TItem(ITEM_MAXIMUMID)
; Inventory
Type TInventory
Field Size% ; Size in cubic meters. Divide by 1000 to get the size in cube meters, which is displayed.
Field Used% ; Used space in cubic decimeters. Divide by 1000 to get the size in cube meters, which is displayed.
; Array containing all Items using their ItemID as index.
Field Items.TInventoryItem[ITEM_MAXIMUMID]
End Type
Type TInventoryItem
Field Amount% ; How many of this Item are stored?
End Type
;----------------------------------------------------------------
;-- Functions
;----------------------------------------------------------------
; Create a new inventory.
Function TInventory_Create.TInventory(Size%)
If Size <= 0 Then RuntimeError "TInventory: Size is equal to or less than 0."
Local lInventory.TInventory = New TInventory
lInventory\Size = Size
lInventory\Used = 0
Return lInventory
End Function
; Safely destroy an existing inventory.
Function TInventory_Destroy(pInventory.TInventory)
If pInventory = Null Then RuntimeError "TInventory: Inventory does not exist."
For lIndex = 0 To (ITEM_MAXIMUMID - 1)
If pInventory\Items[lIndex] <> Null Then
Delete pInventory\Items[lIndex]
pInventory\Items[lIndex] = Null
EndIf
Next
Delete pInventory
End Function
; Retrieve the amount of items in the inventory with the given ItemID.
Function TInventory_GetItemAmount(pInventory.TInventory, ItemID%)
If pInventory = Null Then RuntimeError "TInventory: Inventory does not exist."
If ItemID >= 0 And ItemID < ITEM_MAXIMUMID Then
If Items(ItemID) <> Null Then
If pInventory\Items[ItemID] <> Null
Return pInventory\Items[ItemID]\Amount
Else
Return INVENTORY_RC_ITEMNOTFOUND
EndIf
Else
Return INVENTORY_RC_UNKNOWNITEM
EndIf
Else
Return INVENTORY_RC_INVALIDID
EndIf
End Function
; Set the amount of items in the inventory with the given ItemID.
Function TInventory_SetItemAmount(pInventory.TInventory, ItemID%, Amount%)
If pInventory = Null Then RuntimeError "TInventory: Inventory does not exist."
If Amount < 0 Then Return INVENTORY_RC_INVALIDAMOUNT
If ItemID >= 0 And ItemID < ITEM_MAXIMUMID Then
If Items(ItemID) <> Null Then
; Remove current Amount and Size from Inventory
If pInventory\Items[ItemID] <> Null Then
pInventory\Used = pInventory\Used - (Items(ItemID)\Size * pInventory\Items[ItemID]\Amount)
If Amount = 0 Then
Delete pInventory\Items[ItemID]
pInventory\Items[ItemID] = Null
EndIf
EndIf
If Amount > 0
If pInventory\Items[ItemID] = Null pInventory\Items[ItemID] = New TInventoryItem
Local lAmount = Amount
If pInventory\Used + (Items(ItemID)\Size * lAmount) > PInventory\Size Then lAmount = (pInventory\Size - pInventory\Used) / Items(ItemID)\Size
pInventory\Items[ItemID]\Amount = lAmount
pInventory\Used = pInventory\Used + (Items(ItemID)\Size * lAmount)
Return lAmount
Else
Return INVENTORY_RC_OK
EndIf
If pInventory\Items[ItemID] <> Null Then lSize = lSize - (Items(ItemID)\Size * pInventory\Items[ItemID]\Amount)
Else
Return INVENTORY_RC_UNKNOWNITEM
EndIf
Else
Return INVENTORY_RC_INVALIDID
EndIf
End Function
; Add an item to the inventory.
; Returns the amount of items added or a negative value (error code)
Function TInventory_AddItem(pInventory.TInventory, ItemID%, Amount%=1)
If pInventory = Null Then RuntimeError "TInventory: Inventory does not exist."
If Amount <= 0 Then Return INVENTORY_RC_INVALIDAMOUNT
If ItemID >= 0 And ItemID < ITEM_MAXIMUMID Then
If Items(ItemID ) <> Null Then
Local lAmount = Amount
If pInventory\Used + (lAmount * Items(ItemID)\Size) > pInventory\Size Then lAmount = (pInventory\Size - pInventory\Used) / Items(ItemID)\Size
If lAmount > 0 Then
If pInventory\Items[ItemID] = Null Then pInventory\Items[ItemID] = New TInventoryItem
pInventory\Items[ItemID]\Amount = pInventory\Items[ItemID]\Amount + lAmount
pInventory\Used = pInventory\Used + (lAmount * Items(ItemID)\Size)
EndIf
Return lAmount
Else
Return INVENTORY_RC_UNKNOWNITEM
EndIf
Else
Return INVENTORY_RC_INVALIDID
EndIf
End Function
; Remove an item from the inventory.
; Returns the amount of items removed or a negative value (error code).
Function TInventory_RemoveItem(pInventory.TInventory, ItemID%, Amount%=1)
If pInventory = Null Then RuntimeError "TInventory: Inventory does not exist."
If Amount <= 0 Then Return INVENTORY_RC_INVALIDAMOUNT
If ItemID >= 0 And ItemID < ITEM_MAXIMUMID Then
If Items(ItemID) <> Null Then
If pInventory\Items[ItemID] <> Null Then
Local lAmount = pInventory\Items[ItemID]\Amount
pInventory\Items[ItemID]\Amount = pInventory\Items[ItemID]\Amount - Amount
If pInventory\Items[ItemID]\Amount <= 0 Then
pInventory\Used = pInventory\Used - (lAmount * Items(ItemID)\Size)
; Delete Item Entry (Reduces Memory Usage)
Delete pInventory\Items[ItemID]:pInventory\Items[ItemID] = Null
Return lAmount
Else
pInventory\Used = pInventory\Used - (Amount * Items(ItemID)\Size)
Return Amount
EndIf
Else
Return INVENTORY_RC_ITEMNOTFOUND
EndIf
Else
Return INVENTORY_RC_UNKNOWNITEM
EndIf
Else
Return INVENTORY_RC_INVALIDID
EndIf
End Function
; For when you edit the inventory without using the above functions.
Function TInventory_RecalculateUsedSpace(pInventory.TInventory)
If pInventory = Null Then RuntimeError "TInventory: Inventory does not exist."
pInventory\Used = 0
For lIndex = 0 To (ITEM_MAXIMUMID - 1)
If Items(lIndex) <> Null And pInventory\Items[lIndex] <> Null Then
pInventory\Used = pInventory\Used + (pInventory\Items[lIndex]\Amount * Items(lIndex)\Size)
EndIf
Next
End Function
;----------------------------------------------------------------
;-- Extras - Require 'LinkedListEmulation.bb'!
;----------------------------------------------------------------
;Type TInventoryItemLink
; Field ItemID%
; Field Amount%
;End Type
;
; ; Retrieve a LinkedList containing all items in this inventory.
; ; The returned list must be deleted using TInventory_DeleteItemList(...).
; ; Modifications on this list can only be applied to the inventory using TInventory_SetItemList(...).
;Function TInventory_GetItemList.TList(pInventory.TInventory)
; If pInventory = Null Then RuntimeError "TInventory: Inventory does not exist."
;
; Local lList.TList = TList_Create()
; For lIndex = 0 To (ITEM_MAXIMUMID - 1)
; If Items(lIndex) <> Null And pInventory\Items[lIndex] <> Null Then
; Local lInvItemLink.TInventoryItemLink = New TInventoryItemLink
; lInvItemLink\ItemID = lIndex
; lInvItemLink\Amount = pInventory\Items[lIndex]\Amount
; TList_AddLast(lInvItemLink)
; EndIf
; Next
;
; Return lList
;End Function
;
;Function TInventory_SetItemList(pInventory.TInventory, pList.TList)
; If pInventory = Null Then RuntimeError "TInventory: Inventory does not exist."
; If pList = Null Then RuntimeError "TInventory: List does not exist."
;
; pInventory\Used = 0
; For lIndex = 0 To (ITEM_MAXIMUMID - 1)
; If Items(lIndex) <> Null And pInventory\Items[lIndex] <> Null Then
; Delete pInventory\Items[lIndex]
; pInventory\Items[lIndex] = Null
; EndIf
; Next
;
; Local lInvItemLink.TInventoryItemLink = Object.TInventoryItemLink(TList_First(pList))
; While lInvItemLink <> Null
; If lInvItemLink\ItemID >= 0 And lInvItemLink\ItemID < ITEM_MAXIMUMID Then
; If Items(lInvItemLink\ItemID) <> Null And lInvItemLink\Amount > 0 Then
; pInventory\Items[lInvItemLink\ItemID] = New TInventoryItem
; pInventory\Items[lInvItemLink\ItemID]\Amount = lInvItemLink\Amount
;
; pInventory\Used = pInventory\Used + (lInvItemLink\Amount * Items(lInvItemLink\ItemID)\Size)
; EndIf
; EndIf
; lInvItemLink = Object.TInventoryItemLink(TList_Next(pList))
; Wend
;End Function
;
;Function TInventory_DeleteItemList(pList.TList)
; If pList = Null Then RuntimeError "TInventory: List does not exist."
;
; Local lInvItemLink.TInventoryItemLink = Object.TInventoryItemLink(TList_First(pList))
; While lInvItemLink <> Null
; Delete lInvItemLink
; lInvItemLink = Object.TInventoryItemLink(TList_Delete(pList))
; Wend
;
; TList_Destroy(pList)
;End Function
;----------------------------------------------------------------
;-- Example
;----------------------------------------------------------------
SeedRnd(MilliSecs())
; Test Item
Items(0) = New TItem
Items(0)\Name = "1dm³ Item"
Items(0)\Description = ""
Items(0)\Size = 1
; Test Item
Items(1) = New TItem
Items(1)\Name = "10dm3 Item"
Items(1)\Description = ""
Items(1)\Size = 10
; Test Item
Items(2) = New TItem
Items(2)\Name = "100dm3 Item"
Items(2)\Description = ""
Items(2)\Size = 100
; Test Item
Items(3) = New TItem
Items(3)\Name = "1000dm3 Item"
Items(3)\Description = ""
Items(3)\Size = 1000
Local MyInv.TInventory = TInventory_Create(10000)
While Not KeyHit(1)
Cls
Locate 0,0
PrintInv(MyInv)
If Rand(0,1000) Mod 4 < 2
TInventory_AddItem(MyInv, Rand(0,3), Rand(0,100))
TInventory_RemoveItem(MyInv, Rand(0,3), Rand(0,100))
Else
TInventory_SetItemAmount(MyInv, Rand(0,3), Rand(0,100))
TInventory_SetItemAmount(MyInv, Rand(0,3), Rand(0,100))
EndIf
WaitKey()
Flip 0
Wend
TInventory_Destroy(MyInv)
End
Function PrintInv(Inv.TInventory)
Print "Inventory " + Handle(Inv)
Print " Size: " + (Inv\Size/1000) + "." + (Inv\Size Mod 1000) + ""
Print " Used: " + (Inv\Used/1000) + "." + (Inv\Used Mod 1000) + " m³ / " + Int((Inv\Used/Float(Inv\Size))*100) + "%"
Print " Remaining: " + ((Inv\Size - Inv\Used)/1000) + "." + ((Inv\Size - Inv\Used) Mod 1000) + " m³ / " + Int(((Inv\Size - Inv\Used)/Float(Inv\Size))*100) + "%"
Print " Items:"
For lIndex = 0 To (ITEM_MAXIMUMID - 1)
If Items(lIndex) <> Null And TInventory_GetItemAmount(Inv, lIndex) > 0 Then
Print " - " + Items(lIndex)\Name + " x" + TInventory_GetItemAmount(Inv, lIndex)
EndIf
Next
; Alternatively, using Extras
;Local lList.TList = TInventory_GetItemList(Inv)
;Local lEntry.TInventoryItemLink = Object.TInventoryItemLink(TList_First(lList))
;While lEntry <> Null
; Print " - " + Items(lEntry\ItemID)\Name + " x" + lEntry\Amount
; lEntry = Object.TInventoryItemLink(TList_Next(lList))
;Wend
;TInventory_DestroyItemList(lList)
End Function