So, I figured out how to do it. Finally sat down and drew everything out, which helped immensely.
I'll post the code below in case anyone is interested, and so that this is not an entirely wasted thread.
NOTE: Much better version posted below
Neither of the code pieces below actually REQUIRE MaxGUI. I'm simply using the Desktop() TGadget to pick the user's native resolution, then setting the Globals GW and GH to the native Width and Height (resolution) respectively. If you'd like to compile this without having MaxGUI, just take out the "Import Maxgui.Drivers" line, and then set the globals GW and GH to your desired full screen resolution. Is there a better technique for reading the native resolution without resorting to maxgui?
Anyway, back on topic.. the code..
SuperStrict
Framework BRL.GLMax2D
Import BRL.Random
Import maxgui.drivers
Type obj
Global List:TList
Field X:Float
Field Y:Float
Field Size:Float
Field HalfSize:Float
Field R:Int
Field G:Int
Field B:Int
Method New()
X = Rand(0 , 800)
Y = Rand(0 , 800)
Size = Rnd(0 , 1)
Size = size^2
HalfSize = Size / 2.0
R = Rand(0,255)
G = Rand(0,255)
B = Rand(0 , 255)
If Not List Then List = New TList
List.AddLast(Self)
End Method
Method Draw(ViewOriginX:Float,ViewOriginY:Float,_VIEWSCALE:Float)
SetColor(r,g,b)
Local drawx:Float = ((X- ViewOriginX) * _viewscale)
Local drawy:Float = ((Y- ViewOriginY) * _viewscale)
DrawRect(drawX-HalfSize,drawY-HalfSize,size+1,size+1)
End Method
End Type
Global GW:Int = ClientWidth(Desktop())
Global GH:Int = ClientHeight(Desktop())
Global GHW:Float = GW/2.0
Global GHH:Float = GH/2.0
Global Dragging:Byte = 0
Global MSX:Int
Global MSY:Int
Global Viewscale:Float = 1.0
Global WorldCoord_ViewOriginX:Float = GHW
Global WorldCoord_ViewOriginY:Float = GHH
Global BigViewLastScale:Float
Global BigViewLastX:Float
Global BigViewLastY:Float
Global BigViewZoomScale:Float = 1.0
Global BigViewActive:Byte = False
Global ZoomDuration:Float=250
Global ZoomFactor:Float = 1.5
Global ZoomMouseX:Int
Global ZoomMouseY:Int
Global ZoomMouseBuffer:Int = 5
Global ZoomTimer:Int
Global ZoomFromX:Float
Global ZoomFromY:Float
Global ZoomFromScale:Float
Global ZoomTargetX:Float=GHW
Global ZoomTargetY:Float=GHH
Global ZoomTargetScale:Float = 1
Global ZoomMAX:Float = 40.0
Global ZoomMin:Float = 0.4
SetGraphicsDriver(GLMax2DDriver())
Global GraphicsContext:TGraphics = CreateGraphics(GW,GH,32,60, Graphics_BACKBUFFER)
SetGraphics(GraphicsContext)
AddHook EmitEventHook, EventHook
For Local i:Int = 0 To 2000
Local temp:obj = New obj
Next
While Not KeyHit(KEY_ESCAPE)
Cls
SetOrigin(GHW , GHH)
CalculateViewScale()
SetScale(viewscale , viewscale)
For Local t:obj = EachIn Obj.List
t.draw(WorldCoord_ViewOriginX, WorldCoord_ViewOriginY, viewscale)
Next
SetScale(1 , 1)
SetOrigin(0 , 0)
SetColor(255,255,255)
DrawText("SCALE: " + viewscale , 50 , 50)
DrawText("Draw Origin: [WORLD ]: " + WorldCoord_ViewOriginX + " , " + WorldCoord_ViewOriginY , 50 , 90)
DrawText("Zoom Target: [WORLD ]: " + ZoomTargetX + " , " + ZoomTargetY , 50 , 105)
Flip 0
Wend
Function SetZoomTarget(SX:Int , SY:Int, Direction:Int)
If (ZoomTargetScale < ZoomMax And Direction > 0) Or (ZoomTargetScale > ZoomMin And Direction < 0)
ZoomFromX = WorldCoord_ViewOriginX
ZoomFromY = WorldCoord_ViewOriginY
ZoomFromScale = Viewscale
If Direction > 0
If ((ZoomMouseX > SX + ZoomMouseBuffer) Or (ZoomMouseX < SX - ZoomMouseBuffer) Or (ZoomMouseY > SY + ZoomMouseBuffer) Or (ZoomMouseY < SY - ZoomMouseBuffer))
ZoomTargetX = ((SX - GHW) / viewscale) + WorldCoord_ViewOriginX
ZoomTargetY = ((SY - GHH) / viewscale) + WorldCoord_ViewOriginY
ZoomMouseX = SX
ZoomMouseY = SY
EndIf
ZoomTargetScale:* ZoomFactor
Else
ZoomTargetScale:/ ZoomFactor
EndIf
If ZoomTargetScale > ZoomMax
ZoomTargetScale = ZoomMax
Else If ZoomTargetScale < ZoomMin
ZoomTargetScale = ZoomMin
EndIf
Zoomtimer = MilliSecs()
EndIf
End Function
Function CalculateViewScale()
Local Amount:Float = ((MilliSecs()-ZoomTimer) / ZoomDuration)
If Amount < 1.0
Local FlatAmount:Float = Amount ^ 0.5
Local HalfAmount:Float = Amount/2.0
WorldCoord_ViewOriginX= ZoomFromX + (ZoomTargetX - ZoomFromX) * FlatAmount
WorldCoord_ViewOriginY= ZoomFromY + (ZoomTargetY - ZoomFromY) * FlatAmount
ViewScale = ZoomFromScale + (ZoomTargetScale - ZoomFromScale) * HalfAmount
Else If Amount < 2.0
Local HalfAmount:Float = amount/2.0
ViewScale = ZoomFromScale + (ZoomTargetScale - ZoomFromScale) *HalfAmount
EndIf
SetBlend(LightBlend)
SetAlpha(0.2)
SetColor(255 , 55 , 250)
SetLineWidth(2)
Local X1:Float = ( (ZoomTargetX - WorldCoord_ViewOriginX) * viewscale)
Local Y1:Float = ( (ZoomTargetY - WorldCoord_ViewOriginY) * viewscale)
DrawLine(X1 - 15 , Y1 , X1 + 15 , Y1)
DrawLine(X1 , Y1 - 15 , X1 , Y1 + 15 )
SetLineWidth(1)
SetBlend(SolidBlend)
End Function
Function BigViewMode(State:Byte)
If State
If Viewscale > BigViewZoomScale
BigViewActive = True
BigViewLastScale = Viewscale
BigViewLastX = WorldCoord_ViewOriginX
BigViewLastY = WorldCoord_ViewOriginY
Viewscale = BigViewZoomScale
Zoomtimer = 2.0 * ZoomDuration - MilliSecs()
EndIf
Else
If BigViewActive
ZoomFromX = WorldCoord_ViewOriginX
ZoomFromY = WorldCoord_ViewOriginY
ZoomFromScale = BigViewZoomScale
ZoomTargetX = BigViewLastX
ZoomTargetY = BigViewLastY
BigViewActive = False
Viewscale = BigViewLastScale
Zoomtimer = MilliSecs()
EndIf
EndIf
End Function
Function EventHook:Object(ID:Int , Data:Object , Context:Object)
Local Event:TEvent = TEvent(data)
If Event = Null Then Return event
Select event.id
Case EVENT_MOUSEWHEEL
If Not BigViewActive Then SetZoomTarget(event.x , event.y, event.data)
Case EVENT_APPTERMINATE
End
Case EVENT_KEYDOWN
Select Event.Data
Case KEY_ESCAPE End
Case KEY_LShift , KEY_RShift , KEY_SPACE
BigViewMode(True)
End Select
Case EVENT_KEYUP
Select event.data
Case KEY_LShift , KEY_RShift , KEY_SPACE
BigViewMode(False)
End Select
Case EVENT_MOUSEDOWN
Dragging = 1
MSX = Event.X
MSY = Event.Y
Case EVENT_MOUSEUP
Dragging = 0
Case EVENT_MOUSEMOVE
If Dragging
Local dx:Float = (Event.X-MSX)/viewscale
Local dy:Float = (Event.Y-MSY)/viewscale
WorldCoord_ViewOriginX:- dx
WorldCoord_ViewOriginY:- dy
ZoomTargetX:- dx
ZoomTargetY:- dy
MSX = Event.X
MSY = Event.Y
EndIf
End Select
End Function
Again check out the version below, it's much better.