Announcement

Collapse
No announcement yet.

Car PC Software

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Car PC Software

    I've been working on some software for my Car PC, I'd just like to take this opportunity to show off some screenshots:










    It's written in vb6, all transitions are animated, you can't really see that in the screenshots though. The map and chart downloading is threaded so there's no lag on multithreaded processors when it needs to download maps, it caches the maps locally so after a bit of time it doesn't need internet access.

    I still need to work out how to program a radio, and perhaps how to interface with my phone in accepting and sending calls/sms. Let me know what you guys think.

  • #2
    Your on to something very cool visually. Nice that it doesn't overwhelm your nice dashboard. If you want a designer to cents, the speaker icon could be cooler. Think something retro like the watch.

    Like to hear more about your programming.

    Regards, D

    Comment


    • #3
      nice stuff man, i am a fan of the work! ive been writing my own stuff for years now, im on to my 3rd carputer vehicle, and am also a vb6 programmer. the screenshots make me think youre using directx for the graphics, something im just starting to learn. been with vb since 3.0 though. i recently sat down and figured out the serial communication between a hdradio addin box and its faceplate, so maybe i can help you figure out a radio solution. nice work, and im glad to see im not the only person that wont settle for whats out there and decides to create my own interface to suit my needs

      Comment


      • #4
        Gold eh? Physical or futures contracts? LOL.

        What do you use for your stock data source?
        Former author of LinuxICE, nghost, nobdy.
        Current author of Automotive Message Broker (AMB).
        Works on Tizen IVI. Does not represent anyone or anything but himself.

        Comment


        • #5
          nice stuff man, i am a fan of the work! ive been writing my own stuff for years now, im on to my 3rd carputer vehicle, and am also a vb6 programmer. the screenshots make me think youre using directx for the graphics, something im just starting to learn. been with vb since 3.0 though. i recently sat down and figured out the serial communication between a hdradio addin box and its faceplate, so maybe i can help you figure out a radio solution. nice work, and im glad to see im not the only person that wont settle for whats out there and decides to create my own interface to suit my needs
          Thanks for the feedback, it uses DirectX 8, one problem is my Car PC is an old Lenovo Idea Pad (Atom based with Intel graphics), it's very slow though I'll be upgrading it to a Core i3 system soon enough. I'm happy to share my code if you're interested in working from it - it's coded in a way that's easy to add new features without needing any knowledge of DirectX.

          It now has multiple monitor support which allows it to render individual instances alongside each other (even at different resolutions) as I plan to install rear headrest monitors in my car. I can customize the default screen for each display too, e.g. I can make a small screen for just volume control, or a little GPS speedometer to install on my dashboard, etc.

          Unfortunately that just broke the movie player (as I use vlc in full screen mode to play movies and when you do anything on another monitor it will close the full screen mode).



          Originally posted by tripzero View Post
          Gold eh? Physical or futures contracts? LOL.

          What do you use for your stock data source?
          NY Spot, the charts are from: http://www.freegoldcharts.com/

          Comment


          • #6
            VB6 is the way to go, that way you can cut out most of the bloatware in installing the whole .net framework just to run the software...

            I don't have windows 8 so don't know if VB6 is compatiable or not with that one, and I'm sure MS will try their best to stop older software from being used on newer platforms...

            And directX 8 i believe won't even run on windows 7 for the same reason...

            I haven't tried installing dx8 on w7, though i believe from memory it's not possible?

            I know all my older programs and games in vb6/dx8 won't run on w7...

            Comment


            • #7
              You can just copy across the dx8 vb library straight onto Windows 7, register it and it'll work.

              Comment


              • #8
                Fair enough.

                I'm actually also writing a custom interface for the car pc using vb6, mainly because of its easy of use plus no need to rely on .net or having java installed, keeping the system requirements to the bare minimum.

                Instead of using DX, I have written a graphics library DLL in c++ to speed up the graphical effects like fading, transparencies etc...

                I also noticed you have lots of merc icons in the pics, so does that change for people who don't drive mercs or is it just for yourself?

                Comment


                • #9
                  It's easily customised for other schemes (all the config stuff is stored outside of the exe), those screenshots are just for my car. I've customised a copy for my other car (a '96 Audi A6) which will be the test bed. I'm having a 10" Liliput touchscreen installed that I bought from our host, hopefully it'll all be up and running in 2 weeks and I'll post up a video of it.

                  Comment


                  • #10
                    Source code

                    shukamanon, wprime, I would love to get a copy of your source code.

                    I've been wanting to write code for a very long time but I just can't seem to find the time to sit down and learn the basics. Looking at your code would save me a ton of time with that so I can "get right into it".

                    Thanks
                    "Imagination is more important than knowledge." -AE

                    Comment


                    • #12
                      Hey bambam, if you don't know the basics of programming, then seeing a complete source code project will just go straight over your head. Especially my code as it has no commented lines to explain anything and I do lots of shortcuts and low level stuff which can easily freeze the whole computer up if not used correctly, you know lovely things like memory stomping :$ Not for the faint hearted.

                      It's a very steep learning curve and it's not for everyone. You best bet is first learn the basics from tutorials until you grasp an understanding of how everything works, otherwise it will be like reading chinese...

                      VB6 is a great language to start off with, as it's not so in-your-face as .net is, and it still allows you to do some 'oop' type programming.

                      FreeIce i believe is open source? if you are after an example of code, though i am sure none of it will make sense to you. :P

                      Comment


                      • #13
                        Here's the Maps class:

                        Code:
                        Option Explicit
                        
                        Dim ma As Object
                        Dim view_X As Double, view_Y As Double, view_Z As Double
                        Dim dView_X As Double, dView_Y As Double, dView_Z As Double
                        Dim aim_view_z As Double
                        
                        Dim fade As Single
                        Dim fade_rate As Single
                        Private Const default_fade_rate = 0.2
                        
                        Private Const Min_Zoom = 4
                        Private Const Max_Zoom = 21
                        Private Const aim_view_step = 0.1
                        
                        Private Const Dynamic_Map_Sizing = True
                        
                        Private Const menuSizeX = 300
                        Private Const menuSizeY = 170
                        Private Const menuSizeShortY = 90
                        Private Const border = 10
                        Private Const inner_border = 15
                        Private Const title_border = border + inner_border
                        
                        Dim map_cache As New dictionary
                        
                        Private Const pi = 3.14159265358979
                        Private Const r = 6378.1
                        Private Const mercRatioX As Double = 6.38011715438025E-03
                        Private Const mercRatioY As Double = 6.38532710916024E-03
                        
                        Private Const scrollborder = 10
                        
                        Dim snap_location As Boolean, snap_zoom As Boolean
                        
                        Private Type mappos
                            X As Double
                            Y As Double
                            zoom As Double
                        End Type
                        
                        Private Type sRECT
                            Left As Single
                            Top As Single
                            Right As Single
                            Bottom As Single
                        End Type
                        
                        Private Const text_height = 35
                        
                        Private Const icon_size = 32
                        Private Const car_glow = "jpg/carlight.jpg"
                        Private Const car_icon = "jpg/caricon.jpg"
                        Private Const default_car_fade_rate = 4
                        Dim car_fade_rate As Long
                        Dim car_fade_stage As Long
                        
                        
                        Private Const back_arrow = "jpg/backarrow.jpg"
                        Private Const back_arrow_size = 60
                        Private Const back_border_x = 20
                        Private Const back_border_y = 30
                        
                        Dim themeDarkR As Long, themeDarkG As Long, themeDarkB As Long
                        Dim themeR As Long, themeG As Long, themeB As Long
                        Dim clicked As Boolean, clickX As Single, clickY As Single
                        
                        Dim menuShowTimeout As Long, menuShowTimeout_rate As Long
                        Private Const menuShowTimeout_Max = 500
                        Private Const menuShowTimeout_MinShow = 50
                        Dim settings As Object
                        
                        Private Const zoom_panel_x = 206
                        Private Const zoom_panel_y = 70
                        Dim cGrammar As New Collection
                        Dim lastMove As Integer
                        
                        Public Property Get icon() As String
                            icon = "jpg/maps-320.jpg"
                        End Property
                        
                        Public Property Get caption() As String
                            caption = "Maps"
                        End Property
                        
                        Public Property Get ClassName() As String
                            ClassName = "CarPC.Maps"
                        End Property
                        
                        Sub Class_Load()
                            Set settings = CreateObject("CarPC.Settings")
                            settings.loadfile TypeName(Me)
                            Set ma = CreateObject("CarPC.MapAid")
                            ma.Init
                            If Val(settings.var("GPS_Enabled")) = 1 Then
                                ma.connectGPS Val(settings.var("GPS_Port")), Val(settings.var("GPS_Baud"))
                            End If
                            themeDarkR = Val(settings.var("themeDarkR"))
                            themeDarkG = Val(settings.var("themeDarkG"))
                            themeDarkB = Val(settings.var("themeDarkB"))
                            themeR = Val(settings.var("themeR"))
                            themeG = Val(settings.var("themeG"))
                            themeB = Val(settings.var("themeB"))
                            view_X = Val(settings.var("longitude"))
                            view_Y = Val(settings.var("latitude"))
                            view_Z = Val(settings.var("zoom"))
                            cGrammar.Add "Locate"
                            cGrammar.Add "Zoom in"
                            cGrammar.Add "Zoom out"
                            cGrammar.Add "Pan left"
                            cGrammar.Add "Pan right"
                            cGrammar.Add "Pan up"
                            cGrammar.Add "Pan down"
                            cGrammar.Add "More"
                            cGrammar.Add "Max"
                            cGrammar.Add "Menu"
                        End Sub
                        
                        Public Property Get grammar() As Collection
                            Set grammar = cGrammar
                        End Property
                        
                        Sub Class_KeyDown(windows As Object, keycode As Integer)
                            If keycode = 27 Or keycode = 8 Then
                                windows.moveClassDown Me
                                settings.savefile
                            End If
                            If keycode = 189 Then
                                dView_Z = dView_Z - 0.05
                                snap_zoom = False
                            End If
                            If keycode = 187 Then
                                dView_Z = dView_Z + 0.05
                                snap_zoom = False
                            End If
                            If keycode = 37 Then
                                dView_X = dView_X - 10
                                snap_location = False
                            End If
                            If keycode = 39 Then
                                dView_X = dView_X + 10
                                snap_location = False
                            End If
                            If keycode = 38 Then
                                dView_Y = dView_Y + 10
                                snap_location = False
                            End If
                            If keycode = 40 Then
                                dView_Y = dView_Y - 10
                                snap_location = False
                            End If
                            If keycode = 13 Then
                                snap_location = True
                                snap_zoom = True
                                If Not ma.gpsEnabled Then
                                    If Val(settings.var("GPS_Enabled")) = 1 Then
                                        ma.connectGPS Val(settings.var("GPS_Port")), Val(settings.var("GPS_Baud"))
                                    End If
                                End If
                                menuShowTimeout_rate = 2
                            End If
                        End Sub
                        
                        Sub Class_blt(windows As Object, graphics As Object)
                            If windows.getLeadingWindow Is Me Then
                                fade_rate = default_fade_rate
                            Else
                                fade_rate = -default_fade_rate
                            End If
                            fade = fade + fade_rate
                            If fade < 0 Then fade = 0
                            If fade > 1 Then fade = 1
                            If fade > 0 Then
                                If ma.satelites >= 3 And snap_location Then
                                    view_X = ma.longitude
                                    view_Y = ma.latitude
                                End If
                                If ma.satelites >= 7 And snap_zoom Then
                                    If ma.speed > 150 Then
                                        aim_view_z = 13
                                    ElseIf ma.speed > 100 And ma.speed < 140 Then
                                        aim_view_z = 14
                                    ElseIf ma.speed > 70 And ma.speed < 90 Then
                                        aim_view_z = 15
                                    ElseIf ma.speed > 40 And ma.speed < 60 Then
                                        aim_view_z = 16
                                    ElseIf ma.speed < 30 And ma.speed > 10 Then
                                        aim_view_z = 17
                                    Else
                                        aim_view_z = 15
                                    End If
                                Else
                                    aim_view_z = 0
                                End If
                                If dView_X <> 0 Or dView_Y <> 0 Then
                                    Dim pt As mappos
                                    pt.X = view_X
                                    pt.Y = view_Y
                                    pt.zoom = view_Z
                                    pt = radialToPixel(pt)
                                    pt.X = pt.X + dView_X
                                    pt.Y = pt.Y + dView_Y
                                    pt = pixelToRadial(pt)
                                    view_X = pt.X
                                    view_Y = pt.Y
                                End If
                                If dView_Z <> 0 Then view_Z = view_Z + dView_Z
                                dView_X = dView_X * 0.92
                                dView_Y = dView_Y * 0.92
                                dView_Z = dView_Z * 0.92
                                If Abs(dView_X) < 0.001 Then dView_X = 0
                                If Abs(dView_Y) < 0.001 Then dView_Y = 0
                                If Abs(dView_Z) < 0.001 Then dView_Z = 0
                                If aim_view_z > 0 Then
                                    If aim_view_z > view_Z Then
                                        view_Z = view_Z + aim_view_step
                                    End If
                                    If aim_view_z < view_Z Then
                                        view_Z = view_Z - aim_view_step
                                    End If
                                    If Abs(aim_view_z - view_Z) < aim_view_step Then view_Z = aim_view_z
                                End If
                                If view_Z > Max_Zoom Then view_Z = Max_Zoom
                                If view_Z < Min_Zoom Then view_Z = Min_Zoom
                                Dim use_zoom As Long
                                use_zoom = floor(view_Z)
                                Dim rendered As Boolean, insufficient_map_data As Boolean
                                Do Until rendered Or use_zoom < Min_Zoom
                                    Dim render_width As Double, render_height As Double
                                    render_width = graphics.resX * (2 ^ view_Z / 2 ^ (use_zoom))
                                    render_height = graphics.resY * (2 ^ view_Z / 2 ^ (use_zoom))
                                    Dim px As mappos
                                    px.X = view_X
                                    px.Y = view_Y
                                    px.zoom = use_zoom
                                    px = radialToPixel(px)
                                    Dim phase As mappos
                                    phase.X = px.X
                                    phase.Y = px.Y
                                    px.X = Round(px.X / ma.store_width) * ma.store_width
                                    px.Y = Round(px.Y / ma.store_height) * ma.store_height
                                    phase.X = (phase.X - px.X) / ma.store_width * graphics.resX
                                    phase.Y = (phase.Y - px.Y) / ma.store_height * graphics.resY
                                    Dim maps(0 To 3) As mappos, map_path(0 To 3) As String
                                    maps(0).X = px.X - ma.store_width / 2
                                    maps(0).Y = px.Y + ma.store_height / 2
                                    maps(1).X = px.X + ma.store_width / 2
                                    maps(1).Y = px.Y + ma.store_height / 2
                                    maps(2).X = px.X - ma.store_width / 2
                                    maps(2).Y = px.Y - ma.store_height / 2
                                    maps(3).X = px.X + ma.store_width / 2
                                    maps(3).Y = px.Y - ma.store_height / 2
                                    Dim i As Long
                                    Dim drawPoints(0 To 3) As sRECT
                                    drawPoints(0).Left = graphics.resX / 2 - phase.X - graphics.resX
                                    drawPoints(0).Top = graphics.resY / 2 + phase.Y - graphics.resY
                                    drawPoints(0).Right = graphics.resX / 2 - phase.X + graphics.resX - graphics.resX
                                    drawPoints(0).Bottom = graphics.resY / 2 + phase.Y + graphics.resY - graphics.resY
                                    drawPoints(1).Left = graphics.resX / 2 - phase.X
                                    drawPoints(1).Top = graphics.resY / 2 + phase.Y - graphics.resY
                                    drawPoints(1).Right = graphics.resX / 2 - phase.X + graphics.resX
                                    drawPoints(1).Bottom = graphics.resY / 2 + phase.Y + graphics.resY - graphics.resY
                                    drawPoints(2).Left = graphics.resX / 2 - phase.X - graphics.resX
                                    drawPoints(2).Top = graphics.resY / 2 + phase.Y
                                    drawPoints(2).Right = graphics.resX / 2 - phase.X + graphics.resX - graphics.resX
                                    drawPoints(2).Bottom = graphics.resY / 2 + phase.Y + graphics.resY
                                    drawPoints(3).Left = graphics.resX / 2 - phase.X
                                    drawPoints(3).Top = graphics.resY / 2 + phase.Y
                                    drawPoints(3).Right = graphics.resX / 2 - phase.X + graphics.resX
                                    drawPoints(3).Bottom = graphics.resY / 2 + phase.Y + graphics.resY
                                    insufficient_map_data = False
                                    Dim mC As String
                                    For i = 0 To 3
                                        maps(i).zoom = use_zoom
                                        maps(i) = pixelToRadial(maps(i))
                                        mC = map_cache.Item(maps(i).X & "," & maps(i).Y & "," & use_zoom)
                                        If mC <> "" Then
                                            map_path(i) = mC
                                        Else
                                            map_path(i) = ma.getMap(maps(i).X, maps(i).Y, use_zoom)
                                        End If
                                        drawPoints(i).Top = (drawPoints(i).Top - graphics.resY / 2) / 2 ^ use_zoom * 2 ^ view_Z + graphics.resY / 2
                                        drawPoints(i).Bottom = (drawPoints(i).Bottom - graphics.resY / 2) / 2 ^ use_zoom * 2 ^ view_Z + graphics.resY / 2
                                        drawPoints(i).Left = (drawPoints(i).Left - graphics.resX / 2) / 2 ^ use_zoom * 2 ^ view_Z + graphics.resX / 2
                                        drawPoints(i).Right = (drawPoints(i).Right - graphics.resX / 2) / 2 ^ use_zoom * 2 ^ view_Z + graphics.resX / 2
                                        If map_path(i) = "" Then
                                            insufficient_map_data = True
                                        Else
                                            map_cache.Item(maps(i).X & "," & maps(i).Y & "," & use_zoom) = map_path(i)
                                        End If
                                    Next
                                    insufficient_map_data = insufficient_map_data And Dynamic_Map_Sizing
                                    If Not insufficient_map_data Then
                                        rendered = True
                                        For i = 0 To 3
                                            graphics.BitBlt map_path(i), drawPoints(i).Left, drawPoints(i).Top, drawPoints(i).Right, drawPoints(i).Bottom, fade * 255, fade * 255, fade * 255
                                        Next
                                    Else
                                        use_zoom = use_zoom - 1
                                    End If
                                Loop
                                If ma.satelites >= 3 Then
                                    Dim iconLocation As mappos
                                    Dim mapLocation As mappos
                                    iconLocation.X = ma.longitude
                                    iconLocation.Y = ma.latitude
                                    iconLocation.zoom = view_Z
                                    mapLocation.X = view_X
                                    mapLocation.Y = view_Y
                                    mapLocation.zoom = view_Z
                                    iconLocation = radialToPixel(iconLocation)
                                    mapLocation = radialToPixel(mapLocation)
                                    graphics.BitBlt car_glow, graphics.resX / 2 + (-mapLocation.X + iconLocation.X) * graphics.resX / ma.store_width - icon_size, _
                                                              graphics.resY / 2 + (mapLocation.Y - iconLocation.Y) * graphics.resY / ma.store_height - icon_size, _
                                                              graphics.resX / 2 + (-mapLocation.X + iconLocation.X) * graphics.resX / ma.store_width + icon_size, _
                                                              graphics.resY / 2 + (mapLocation.Y - iconLocation.Y) * graphics.resY / ma.store_height + icon_size, _
                                                              themeR * car_fade_stage / 255, themeG * car_fade_stage / 255, themeB * car_fade_stage / 255
                                    graphics.BitBlt car_icon, graphics.resX / 2 + (-mapLocation.X + iconLocation.X) * graphics.resX / ma.store_width - icon_size / 2, _
                                                              graphics.resY / 2 + (mapLocation.Y - iconLocation.Y) * graphics.resY / ma.store_height - icon_size / 2, _
                                                              graphics.resX / 2 + (-mapLocation.X + iconLocation.X) * graphics.resX / ma.store_width + icon_size / 2, _
                                                              graphics.resY / 2 + (mapLocation.Y - iconLocation.Y) * graphics.resY / ma.store_height + icon_size / 2, _
                                                              255, 255, 255
                                    car_fade_stage = car_fade_stage + car_fade_rate
                                    If car_fade_stage <= 0 Then
                                        car_fade_stage = 0
                                        car_fade_rate = default_car_fade_rate
                                    ElseIf car_fade_stage >= 255 Then
                                        car_fade_stage = 255
                                        car_fade_rate = -default_car_fade_rate
                                    End If
                                End If
                                Dim y_phase As Single, y_fade As Single
                                menuShowTimeout = menuShowTimeout + menuShowTimeout_rate
                                If menuShowTimeout >= menuShowTimeout_Max Then
                                    menuShowTimeout_rate = -2
                                ElseIf menuShowTimeout <= 0 Then
                                    menuShowTimeout_rate = 0
                                End If
                                y_phase = menuShowTimeout / menuShowTimeout_MinShow
                                If y_phase > 1 Then y_phase = 1
                                y_fade = y_phase
                                y_phase = graphics.resY * (1 - y_phase)
                                Dim back_button_phase As Long
                                If (windows.input_type And 2) Or (windows.input_type And 8) Then
                                    back_button_phase = back_arrow_size + border
                                End If
                                If Not ma.gpsEnabled Then
                                    graphics.BitBlt "jpg/maps-menu-short.jpg", border, border + border - y_phase, border + menuSizeX, menuSizeShortY + border - y_phase, themeR, themeG, themeB
                                    If (windows.input_type And 2) Or (windows.input_type And 8) Then
                                        graphics.BitBlt back_arrow, back_border_x, back_border_y - y_phase, back_border_x + back_arrow_size, back_border_y + back_arrow_size - y_phase, themeR, themeG, themeB
                                    End If
                                    graphics.bltText "No GPS Detected", back_border_x + border + back_button_phase, back_border_y - y_phase + back_arrow_size + border - text_height * 2, back_border_x - 2 * border + menuSizeX, back_border_y - y_phase + back_arrow_size + border - text_height, vbAlignLeft, themeR, themeG, themeB
                                ElseIf ma.satelites = 0 Then
                                    graphics.BitBlt "jpg/maps-menu-short.jpg", border, border + border - y_phase, border + menuSizeX, menuSizeShortY + border - y_phase, themeR, themeG, themeB
                                    If (windows.input_type And 2) Or (windows.input_type And 8) Then
                                        graphics.BitBlt back_arrow, back_border_x, back_border_y - y_phase, back_border_x + back_arrow_size, back_border_y + back_arrow_size - y_phase, themeR, themeG, themeB
                                    End If
                                    graphics.bltText "No GPS Signal", back_border_x + border + back_button_phase, back_border_y - y_phase + back_arrow_size + border - text_height * 2, back_border_x - 2 * border + menuSizeX, back_border_y - y_phase + back_arrow_size + border - text_height, vbAlignLeft, themeR, themeG, themeB
                                Else
                                    graphics.BitBlt "jpg/maps-menu.jpg", border, border + border - y_phase, border + menuSizeX, menuSizeY + border - y_phase, themeR, themeG, themeB
                                    If (windows.input_type And 2) Or (windows.input_type And 8) Then
                                        graphics.BitBlt back_arrow, back_border_x, back_border_y - y_phase, back_border_x + back_arrow_size, back_border_y + back_arrow_size - y_phase, themeR, themeG, themeB
                                    End If
                                    graphics.bltText "Longitude: ", back_border_x + border, back_border_y - y_phase + back_arrow_size + border, back_border_x - 2 * border + menuSizeX, back_border_y - y_phase + back_arrow_size + border + text_height, vbAlignLeft, themeR, themeG, themeB
                                    graphics.bltText "Latitude: ", back_border_x + border, back_border_y - y_phase + back_arrow_size + border + text_height, back_border_x - 2 * border + menuSizeX, back_border_y - y_phase + back_arrow_size + border + text_height * 2, vbAlignLeft, themeR, themeG, themeB
                                    graphics.bltText "" & formatDegree(ma.longitude), back_border_x + border, back_border_y - y_phase + back_arrow_size + border, back_border_x - 2 * border + menuSizeX, back_border_y - y_phase + back_arrow_size + border + text_height, vbAlignRight, themeR, themeG, themeB
                                    graphics.bltText "" & formatDegree(ma.latitude), back_border_x + border, back_border_y - y_phase + back_arrow_size + border + text_height, back_border_x - 2 * border + menuSizeX, back_border_y - y_phase + back_arrow_size + border + text_height * 2, vbAlignRight, themeR, themeG, themeB
                                    graphics.bltText "Speed: ", back_border_x + border + back_button_phase, back_border_y - y_phase + back_arrow_size + border - text_height, back_border_x - 2 * border + menuSizeX, back_border_y - y_phase + back_arrow_size + border + text_height * 0, vbAlignLeft, themeR, themeG, themeB
                                    graphics.bltText "" & Round(ma.speed) & " kph", back_border_x + border + back_arrow_size + border, back_border_y - y_phase + back_arrow_size + border - text_height, back_border_x - 2 * border + menuSizeX, back_border_y - y_phase + back_arrow_size + border + text_height * 0, vbAlignRight, themeR, themeG, themeB
                                    graphics.bltText "Satelites: ", back_border_x + border + back_button_phase, back_border_y - y_phase + back_arrow_size + border - text_height * 2, back_border_x - 2 * border + menuSizeX, back_border_y - y_phase + back_arrow_size + border - text_height, vbAlignLeft, themeR, themeG, themeB
                                    graphics.bltText "" & ma.satelites, back_border_x + border + back_arrow_size + border, back_border_y - y_phase + back_arrow_size + border - text_height * 2, back_border_x - 2 * border + menuSizeX, back_border_y - y_phase + back_arrow_size + border - text_height, vbAlignRight, themeR, themeG, themeB
                                End If
                                If (windows.input_type And 2) Or (windows.input_type And 8) Then
                                    graphics.BitBlt "jpg/zoom.jpg", graphics.resX - zoom_panel_x - border - border, border + border - y_phase, graphics.resX - border - border, zoom_panel_y + border + border - y_phase, themeR, themeG, themeB
                                End If
                                graphics.BitBlt "jpg/map-scroll-up.jpg", 0, 0, graphics.resX, scrollborder, themeR * y_fade, themeG * y_fade, themeB * y_fade
                                graphics.BitBlt "jpg/map-scroll-down.jpg", 0, graphics.resY - scrollborder, graphics.resX, graphics.resY, themeR * y_fade, themeG * y_fade, themeB * y_fade
                                graphics.BitBlt "jpg/map-scroll-left.jpg", 0, 0, scrollborder, graphics.resY, themeR * y_fade, themeG * y_fade, themeB * y_fade
                                graphics.BitBlt "jpg/map-scroll-right.jpg", graphics.resX - scrollborder, 0, graphics.resX, graphics.resY, themeR * y_fade, themeG * y_fade, themeB * y_fade
                                If clicked Then
                                    If distance(back_border_x + back_arrow_size / 2, back_border_y + back_arrow_size / 2, graphics.resX * clickX, graphics.resY * clickY) < back_arrow_size / 2 Then
                                        Class_KeyDown windows, 27
                                    End If
                                    If distance(graphics.resX - zoom_panel_x + back_arrow_size / 2 - border - 3 + 132, border * 2 + 5 - y_phase + back_arrow_size / 2, graphics.resX * clickX, graphics.resY * clickY) < back_arrow_size / 2 Then
                                        Class_KeyDown windows, 13
                                    End If
                                    If distance(graphics.resX - zoom_panel_x + back_arrow_size / 2 - border - 3 + 66, border * 2 + 5 - y_phase + back_arrow_size / 2, graphics.resX * clickX, graphics.resY * clickY) < back_arrow_size / 2 Then
                                        Class_KeyDown windows, 189
                                    End If
                                    If distance(graphics.resX - zoom_panel_x + back_arrow_size / 2 - border - 3, border * 2 + 5 - y_phase + back_arrow_size / 2, graphics.resX * clickX, graphics.resY * clickY) < back_arrow_size / 2 Then
                                        Class_KeyDown windows, 187
                                    End If
                                    If graphics.resX * clickX <= scrollborder Then
                                        Class_KeyDown windows, 37
                                    End If
                                    If graphics.resY * clickY <= scrollborder Then
                                        Class_KeyDown windows, 38
                                    End If
                                    If graphics.resX * clickX >= graphics.resX - scrollborder Then
                                        Class_KeyDown windows, 39
                                    End If
                                    If graphics.resY * clickY >= graphics.resY - scrollborder Then
                                        Class_KeyDown windows, 40
                                    End If
                                    clickX = 0
                                    clickY = 0
                                    clicked = False
                                End If
                            End If
                            settings.var("longitude") = view_X
                            settings.var("latitude") = view_Y
                            settings.var("zoom") = view_Z
                        End Sub
                        
                        Private Function distance(x1 As Single, y1 As Single, x2 As Single, y2 As Single) As Single
                            distance = Sqr((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1))
                        End Function
                        
                        Private Function floor(v As Double) As Double
                            floor = Round(v - 0.49)
                        End Function
                        
                        Private Function radialToPixel(pos As mappos) As mappos
                            radialToPixel.X = ((pos.X - 85) / 180 * pi) * r * (2 ^ pos.zoom) * mercRatioX
                            radialToPixel.Y = r * Log(((1 + Sin(pos.Y / 180 * pi)) / Cos(pos.Y / 180 * pi))) * (2 ^ pos.zoom) * mercRatioY
                            radialToPixel.zoom = pos.zoom
                        End Function
                        
                        Private Function pixelToRadial(pos As mappos) As mappos
                            pixelToRadial.X = (pos.X / mercRatioX) / (2 ^ pos.zoom) / r * 180 / pi + 85
                            pixelToRadial.Y = (2 * Atn(Exp(pos.Y / r / (2 ^ pos.zoom) / mercRatioY)) - pi / 2) * 180 / pi
                            pixelToRadial.zoom = pos.zoom
                        End Function
                        
                        Sub Class_Click(windows As Object, X As Single, Y As Single)
                            clickX = X
                            clickY = Y
                            clicked = True
                            menuShowTimeout_rate = 2
                        
                        End Sub
                        
                        Sub Class_Speak(windows As Object, phrase As String)
                            If phrase = "Locate" Then
                                Class_KeyDown windows, 13
                                lastMove = 0
                            ElseIf phrase = "Menu" Then
                                Class_KeyDown windows, 8
                                lastMove = 0
                            ElseIf phrase = "Zoom in" Then
                                Class_KeyDown windows, 187
                                lastMove = 187
                            ElseIf phrase = "Zoom out" Then
                                Class_KeyDown windows, 189
                                lastMove = 189
                            ElseIf phrase = "Pan left" Then
                                Class_KeyDown windows, 37
                                lastMove = 37
                            ElseIf phrase = "Pan right" Then
                                Class_KeyDown windows, 39
                                lastMove = 39
                            ElseIf phrase = "Pan up" Then
                                Class_KeyDown windows, 38
                                lastMove = 38
                            ElseIf phrase = "Pan down" Then
                                Class_KeyDown windows, 40
                                lastMove = 40
                            ElseIf phrase = "More" Then
                                If lastMove > 0 Then Class_KeyDown windows, lastMove
                            ElseIf phrase = "Max" Then
                                If lastMove = 187 Then
                                    dView_Z = dView_Z + 1
                                    snap_zoom = False
                                ElseIf lastMove = 189 Then
                                    dView_Z = dView_Z - 1
                                    snap_zoom = False
                                End If
                            End If
                            
                        End Sub
                        It's designed to be simple enough that anyone can program classes for it, with classes being able to be completely independent (they can even exist in separate executables) with event calls for various user input such as touchscreen, keyboard and speech with Class_Click, Class_KeyDown and Class_Speak plus a blt call for painting refreshes.

                        Comment

                        Working...
                        X