home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 January / Chip_2002-01_cd1.bin / oddech / eracer / cApplication.cls < prev    next >
Text File  |  2001-02-25  |  36KB  |  839 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4.   Persistable = 0  'NotPersistable
  5.   DataBindingBehavior = 0  'vbNone
  6.   DataSourceBehavior  = 0  'vbNone
  7.   MTSTransactionMode  = 0  'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "cApplication"
  10. Attribute VB_GlobalNameSpace = False
  11. Attribute VB_Creatable = True
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = False
  14. ' OPTION SETTINGS ...
  15.  
  16.     ' Enforce variable declaration
  17.     Option Explicit
  18.  
  19. ' PRIVATE TYPES ...
  20.  
  21.     ' Input state type
  22.     Private Type tInputState
  23.          MousePX       As Long            ' Mouse screen position
  24.          MousePY       As Long            '
  25.          MouseDX       As Long            ' Mouse position delta
  26.          MouseDY       As Long            '
  27.          MouseB1       As Boolean         ' Mouse button 1
  28.          MouseB2       As Boolean         ' Mouse button 2
  29.          KeyEscape     As Boolean         ' Keyboard key
  30.          KeyArrowU     As Boolean         '
  31.          KeyArrowD     As Boolean         '
  32.          KeyArrowL     As Boolean         '
  33.          KeyArrowR     As Boolean         '
  34.          KeySpace      As Boolean         '
  35.          KeyCtrl       As Boolean         '
  36.          KeyPlus       As Boolean         '
  37.          KeyMinus      As Boolean         '
  38.          KeyP          As Boolean         '
  39.     End Type
  40.  
  41. ' PROPERTY VARIABLES ...
  42.  
  43.     Public DXInstance           As DirectX7                  ' Instance of DirectX
  44.     Public DDInstance           As DirectDraw4               ' Instance of DirectDraw
  45.     Public D3Instance           As Direct3DRM3               ' Instance of Direct3DRM
  46.     Public DSInstance           As DirectSound               ' Instance of DirectSound
  47.  
  48.     Public DDPrimary            As DirectDrawSurface4        ' Primary display device
  49.     Public DDSurface            As DirectDrawSurface4        ' Backbuffer for rendering
  50.  
  51.     Public D3Frame              As Direct3DRMFrame3          ' Root frame of D3DRM hierarchy
  52.     Public D3Camera             As Direct3DRMFrame3          ' Camera frame
  53.     Public D3Device             As Direct3DRMDevice3         ' D3DRM Device
  54.     Public D3Viewport           As Direct3DRMViewport2       ' D3DRM Viewport
  55.     
  56.     Public DSBPrimary          As DirectSoundBuffer          ' Primary sound buffer
  57.     Public DSListener          As DirectSound3DListener      ' Listener to the primary buffer
  58.     
  59.     Public FrameCount           As Long
  60.     Public FrameRate            As Single
  61.     Public FrameLimit           As Long
  62.     
  63.     Public CursorX              As Long
  64.     Public CursorY              As Long
  65.     
  66.     Public Terminating          As Boolean
  67.     
  68. ' SUBCLASS INSTANCES ...
  69.  
  70.     Public Shots            As cShots                    ' Shots in game
  71.     Public Effects          As cEffects                  ' Effects in game
  72.     Public Enemies          As cEnemies                  ' Enemies in game
  73.     Public Particles        As cParticles                ' Particles in game
  74.     Public Player           As cPlayer                   ' Player in game
  75.     Public Environment      As cEnvironment              ' Game environment
  76.     Public Interface        As cInterface                ' User interface display
  77.     
  78.     Public WaterMessage     As Boolean
  79.     Public FuelMessage      As Boolean
  80.     
  81.     Public SoundEnabled     As Boolean
  82.     
  83.  
  84.     '
  85.     ' INITIALIZE: Initializes application
  86.     '
  87.     Public Sub Initialize()
  88.     
  89.         ' Declare local variables ...
  90.         
  91.             Dim L_dDDSD         As DDSURFACEDESC2           ' Surface descriptor for creating primary and bbuffer
  92.  
  93.         ' Code ...
  94.             
  95.             ' Prepare windows environment ...
  96.                 
  97.                 ' Hide cursor
  98.                 ShowCursor 0
  99.                 
  100.             ' Create DirectX instances ...
  101.                 
  102.                 ' DirectX
  103.                 On Error Resume Next
  104.                 Set DXInstance = New DirectX7
  105.                 If Err.Number <> 0 Then
  106.                     MsgBox "This program requires Microsoft DirectX7.", vbOKOnly + vbCritical, "ERacer"
  107.                     End
  108.                 End If
  109.                 On Error GoTo 0
  110.                 
  111.                 ' DirectDraw
  112.                 Set DDInstance = DXInstance.DirectDraw4Create("")
  113.     
  114.                 ' DirectSound (optional)
  115.                 On Error Resume Next
  116.                 Set DSInstance = DXInstance.DirectSoundCreate("")
  117.                 On Error GoTo 0
  118.                  
  119.             ' Prepare DirectX states ...
  120.                 
  121.                 ' Cooperative level (draw)
  122.                 DDInstance.SetCooperativeLevel fER.hWnd, DDSCL_FULLSCREEN Or DDSCL_EXCLUSIVE
  123.                 
  124.                 ' Display size and color depth
  125.                 DDInstance.SetDisplayMode 640, 480, 16, 0&, DDSDM_DEFAULT
  126.                 
  127.                 ' Cooperative level (sound)
  128.                 If Not DSInstance Is Nothing Then DSInstance.SetCooperativeLevel fER.hWnd, DSSCL_PRIORITY
  129.                 
  130.             ' Create primary ...
  131.                             
  132.                 With L_dDDSD
  133.                     .lFlags = DDSD_CAPS
  134.                     .ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE Or DDSCAPS_VIDEOMEMORY
  135.                 End With
  136.                 Set DDPrimary = DDInstance.CreateSurface(L_dDDSD)
  137.     
  138.             ' Create backbuffer ...
  139.                             
  140.                 ' Create
  141.                 With L_dDDSD
  142.                     .lFlags = DDSD_CAPS Or DDSD_WIDTH Or DDSD_HEIGHT
  143.                     .ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN Or DDSCAPS_3DDEVICE Or DDSCAPS_VIDEOMEMORY
  144.                     .lWidth = 640
  145.                     .lHeight = 480
  146.                 End With
  147.                 Set DDSurface = DDInstance.CreateSurface(L_dDDSD)
  148.                     
  149.                 ' Set properties
  150.                 With DDSurface
  151.                     .SetFont fER.Font
  152.                     .SetFontTransparency True
  153.                     .SetForeColor RGB(128, 128, 128)
  154.                 End With
  155.                     
  156.             ' Initialize Direct3DRM ...
  157.             
  158.                 ' Create and initalize D3DRM objects ...
  159.  
  160.                     ' Create D3DRM instance
  161.                     Set D3Instance = DXInstance.Direct3DRMCreate
  162.                     
  163.                     ' Create D3DRM device
  164.                      Set D3Device = D3Instance.CreateDeviceFromSurface("IID_IDirect3DHALDevice", DDInstance, DDSurface, D3DRMDEVICE_DEFAULT)
  165.     
  166.                     ' Set texture search path
  167.                     D3Instance.SetSearchPath App.Path + "\gfx"
  168.                     
  169.                     ' Create and initialize D3DRM frame for world
  170.                     Set D3Frame = D3Instance.CreateFrame(Nothing)
  171.                     D3Frame.SetSceneBackgroundRGB 0.1, 0.2, 0.4
  172.                     
  173.                     ' Create D3DRM frame for camera: Moves with racer (smooth)
  174.                     Set D3Camera = D3Instance.CreateFrame(D3Frame)
  175.                     
  176.                     ' Create and initialize D3DRM viewport
  177.                     Set D3Viewport = D3Instance.CreateViewport(D3Device, D3Camera, 0, 0, 640, 480)
  178.  
  179.                 ' Initialize D3DRM states ...
  180.                 
  181.                     ' Set alphatranslucency enable
  182.                     D3Device.SetRenderMode D3DRMRENDERMODE_BLENDEDTRANSPARENCY Or D3DRMRENDERMODE_SORTEDTRANSPARENCY
  183.                 
  184.                     ' Set gouraud shading, texture mapping and lighting enable
  185.                     D3Device.SetQuality D3DRMRENDER_GOURAUD
  186.                                      
  187.                     ' Set texture quality to full
  188.                     D3Device.SetTextureQuality D3DRMTEXTURE_LINEARMIPLINEAR
  189.                     
  190.                     ' Set fog off (not supported, looks funny on many cards that support it)
  191.                     D3Frame.SetSceneFogEnable D_FALSE
  192.                                                     
  193.             ' Initialize sound system ...
  194.                 
  195.                 If Not DSInstance Is Nothing Then
  196.                     
  197.                     Dim L_dWF As WAVEFORMATEX
  198.                     Dim L_ddsbd As DSBUFFERDESC
  199.                     
  200.                     DSInstance.SetSpeakerConfig DSSPEAKER_HEADPHONE Or DSSPEAKER_STEREO
  201.                     L_dWF = GetWaveFileFormat(App.Path + "\snd\fmt.wav")
  202.                     With L_ddsbd
  203.                         .lBufferBytes = 0
  204.                         .lFlags = DSBCAPS_CTRL3D Or DSBCAPS_PRIMARYBUFFER
  205.                     End With
  206.                     Set DSBPrimary = Application.DSInstance.CreateSoundBuffer(L_ddsbd, L_dWF)
  207.                     Set DSListener = Application.DSBPrimary.GetDirectSound3DListener
  208.                                                             
  209.                     With DSListener
  210.                         .SetDistanceFactor 1, DS3D_IMMEDIATE
  211.                         .SetDopplerFactor 1, DS3D_IMMEDIATE
  212.                         .SetRolloffFactor 1, DS3D_IMMEDIATE
  213.                         .SetVelocity 0, 0, 0, DS3D_IMMEDIATE
  214.                     End With
  215.                     
  216.                 End If
  217.                 
  218.                    
  219.             ' Initialize general data ...
  220.             
  221.                 FrameCount = 0
  222.                 FrameRate = 0
  223.                 FrameLimit = 50
  224.                 
  225.             ' Initialize subclasses ...
  226.             
  227.                 Set Interface = New cInterface
  228.                 Interface.Initialize
  229.                 Interface.Render True
  230.                 
  231.                 Set Environment = New cEnvironment
  232.                 Environment.Initialize
  233.                 
  234.                 Set Shots = New cShots
  235.                 Shots.Initialize
  236.                 
  237.                 Set Effects = New cEffects
  238.                 Effects.Initialize
  239.                 
  240.                 Set Enemies = New cEnemies
  241.                 Enemies.Initialize
  242.                 
  243.                 Set Particles = New cParticles
  244.                 Particles.Initialize
  245.                 
  246.                 Set Player = New cPlayer
  247.                 Player.Initialize
  248.  
  249.     End Sub
  250.  
  251.     '
  252.     ' EXECUTE: Application main loop
  253.     '
  254.     Public Sub Execute()
  255.     
  256.         ' Declare local variables ...
  257.         
  258.             Dim L_nNextFrame    As Long     ' Time at which to advance to next frame
  259.             Dim L_nNextRate     As Long     ' Time at which to calculate next frame rate
  260.             Dim L_nFrameRate    As Long     ' Local frame rate counter
  261.             
  262.         ' Code ...
  263.         
  264.             ' Master loop
  265.             Do
  266.                 
  267.                 ' Execute frame timing calculations
  268.                 
  269.                     L_nNextFrame = timeGetTime + (1000 \ FrameLimit)
  270.                     FrameCount = FrameCount + 1
  271.                     
  272.                     L_nFrameRate = L_nFrameRate + 1
  273.                     If timeGetTime > L_nNextRate Then
  274.                         FrameRate = L_nFrameRate
  275.                         L_nFrameRate = 0
  276.                         L_nNextRate = timeGetTime + 1000
  277.                     End If
  278.                 
  279.                 ' React to user input
  280.                     Interact
  281.                     
  282.                 ' Update state
  283.                     Update
  284.                     
  285.                 ' Render next frame
  286.                     Render
  287.                 
  288.                 ' React to windows events
  289.                     If FrameCount Mod 5 = 0 Then DoEvents
  290.                     
  291.                 ' Wait until frame time is over
  292.                 Do
  293.                 Loop Until timeGetTime >= L_nNextFrame
  294.                 
  295.             Loop Until Application.Terminating
  296.     
  297.     End Sub
  298.  
  299.     '
  300.     ' TERMINATE: Cleans up application
  301.     '
  302.     Public Sub Terminate()
  303.     
  304.         ' Restore DirectDraw windows states ...
  305.         
  306.             DDInstance.RestoreDisplayMode
  307.             DDInstance.SetCooperativeLevel fER.hWnd, DDSCL_NORMAL
  308.             
  309.         ' Terminate Direct3DRM ...
  310.             
  311.             ' Terminate viewport
  312.             Set D3Viewport = Nothing
  313.             
  314.             ' Terminate device
  315.             Set D3Device = Nothing
  316.             
  317.             ' Terminate instance
  318.             Set D3Instance = Nothing
  319.             
  320.         ' Terminate DirectDraw ...
  321.     
  322.             Set DDSurface = Nothing
  323.             Set DDPrimary = Nothing
  324.             
  325.         ' Terminate DirectSound ...
  326.         
  327.             Set DSInstance = Nothing
  328.             
  329.         ' Terminate DirectX ...
  330.           
  331.             Set DXInstance = Nothing
  332.             
  333.         ' Restore windows environment ...
  334.         
  335.             ' Show cursor
  336.             ShowCursor -1
  337.                 
  338.     End Sub
  339.  
  340.     '
  341.     ' UPDATE: Update gamestate
  342.     '
  343.     Public Sub Update()
  344.     
  345.             
  346.         ' Update enemies
  347.         
  348.             Enemies.Update
  349.             
  350.         ' Update player
  351.         
  352.             Player.Update
  353.             
  354.         ' Update environment
  355.         
  356.             Environment.Update
  357.                  
  358.         ' Update shots
  359.         
  360.             Shots.Update
  361.             
  362.         ' Update effects
  363.         
  364.             Effects.Update
  365.             
  366.         ' Update particles
  367.         
  368.             Particles.Update
  369.             
  370.         ' Update initial messages
  371.         
  372.             If Application.FrameCount = 1 Then Application.Interface.DisplayMessage "welcome to ERACER ..."
  373.             If Application.FrameCount = 300 And (Not Application.Enemies.Active) Then Application.Interface.DisplayMessage "demonstrating industrial quality 3D using visual basic ..."
  374.             If Application.FrameCount = 800 And (Not Application.Enemies.Active) Then Application.Interface.DisplayMessage "use arrow keys to steer, space to jump, ctrl to fire ..."
  375.             If Application.FrameCount = 1300 And (Not Application.Enemies.Active) Then Application.Interface.DisplayMessage "use menu buttons to change environment and start combat ..."
  376.          
  377.     End Sub
  378.  
  379.     '
  380.     ' INTERACT: Gather and process user input
  381.     '
  382.     Public Sub Interact()
  383.     
  384.         ' Declare local variables ...
  385.         
  386.             Static S_nKeyDelay          As Long         ' Delay for keys
  387.             Static S_dMousePos          As POINTAPI     ' Mouse position now
  388.             Static S_dMouseOld          As POINTAPI     ' Old mouse position
  389.             Static S_dInputState        As tInputState  ' State of input controls
  390.             Dim L_dJoy                  As JOYINFOEX
  391.             Dim L_bJoy                  As Boolean
  392.             
  393.         ' Code ...
  394.         
  395.             ' Gather input ...
  396.             
  397.                 ' Joy
  398.                     
  399.                     L_dJoy.dwSize = Len(L_dJoy)
  400.                     L_dJoy.dwFlags = 131
  401.                     L_bJoy = (joyGetPosEx(0, L_dJoy) = 0)
  402.                     
  403.                 ' Gather mouse input...
  404.                         
  405.                     ' Get position
  406.                     GetCursorPos S_dMousePos
  407.                     
  408.                     ' Calculate derived values
  409.                     S_dInputState.MouseDX = S_dMousePos.X - 320
  410.                     S_dInputState.MouseDY = S_dMousePos.Y - 240
  411.                     S_dInputState.MousePX = S_dMousePos.X
  412.                     S_dInputState.MousePY = S_dMousePos.Y
  413.                                                     
  414.                     ' Get button state
  415.                     S_dInputState.MouseB1 = (GetAsyncKeyState(&H1) <= -32767)
  416.                     S_dInputState.MouseB2 = (GetAsyncKeyState(&H2) <= -32767)
  417.                                                     
  418.                 ' Gather keyboard input (continuous keys)
  419.                           
  420.                     ' ARROW UP
  421.                     If (GetAsyncKeyState(&H26) <= -32767) Then
  422.                         S_dInputState.KeyArrowU = True
  423.                     Else
  424.                         S_dInputState.KeyArrowU = False
  425.                     End If
  426.                                 
  427.                     ' ARROW DOWN
  428.                     If (GetAsyncKeyState(&H28) <= -32767) Then
  429.                         S_dInputState.KeyArrowD = True
  430.                     Else
  431.                         S_dInputState.KeyArrowD = False
  432.                     End If
  433.                     
  434.                     ' ARROW LEFT
  435.                     If (GetAsyncKeyState(&H25) <= -32767) Then
  436.                         S_dInputState.KeyArrowL = True
  437.                     Else
  438.                         S_dInputState.KeyArrowL = False
  439.                     End If
  440.                                 
  441.                     ' ARROW RIGHT
  442.                     If (GetAsyncKeyState(&H27) <= -32767) Then
  443.                         S_dInputState.KeyArrowR = True
  444.                     Else
  445.                         S_dInputState.KeyArrowR = False
  446.                     End If
  447.                     
  448.                     ' SPACE
  449.                     If (GetAsyncKeyState(&H20) <= -32767) Or (L_bJoy And (L_dJoy.dwButtonNumber = 2)) Then
  450.                         S_dInputState.KeySpace = True
  451.                     Else
  452.                         S_dInputState.KeySpace = False
  453.                     End If
  454.                     
  455.                 ' Gather keyboard input (event keys)
  456.                 
  457.                     If S_nKeyDelay = 0 Then
  458.                                         
  459.                          ' ESCAPE
  460.                         If (GetAsyncKeyState(&H1B) <= -32767) Then
  461.                             S_dInputState.KeyEscape = True
  462.                             S_nKeyDelay = 10
  463.                         Else
  464.                             S_dInputState.KeyEscape = False
  465.                         End If
  466.                         
  467.                         ' PLUS
  468.                         If (GetAsyncKeyState(&H6B) <= -32767) Then
  469.                             S_dInputState.KeyPlus = True
  470.                             S_nKeyDelay = 10
  471.                         Else
  472.                             S_dInputState.KeyPlus = False
  473.                         End If
  474.                         
  475.                         ' MINUS
  476.                         If (GetAsyncKeyState(&H6D) <= -32767) Then
  477.                             S_dInputState.KeyMinus = True
  478.                             S_nKeyDelay = 10
  479.                         Else
  480.                             S_dInputState.KeyMinus = False
  481.                         End If
  482.                         
  483.                        
  484.                         ' CTRL
  485.                         If (GetAsyncKeyState(&H11) <= -32767) Or (L_bJoy And (L_dJoy.dwButtonNumber = 1)) Then
  486.                             S_dInputState.KeyCtrl = True
  487.                             S_nKeyDelay = 10
  488.                         Else
  489.                             S_dInputState.KeyCtrl = False
  490.                         End If
  491.                         
  492.                     Else
  493.                         
  494.                         ' Reset states ...
  495.                         
  496.                             S_dInputState.KeyEscape = False
  497.                             S_dInputState.KeyPlus = False
  498.                             S_dInputState.KeyMinus = False
  499.                             S_dInputState.KeyCtrl = False
  500.                             S_nKeyDelay = S_nKeyDelay - 1
  501.                         
  502.                     End If
  503.                     If L_bJoy Then
  504.                         S_dInputState.KeyArrowL = S_dInputState.KeyArrowL Or (L_dJoy.dwXpos < 32767& - 15000)
  505.                         S_dInputState.KeyArrowR = S_dInputState.KeyArrowR Or (L_dJoy.dwXpos > 32767& + 15000)
  506.                         S_dInputState.KeyArrowU = S_dInputState.KeyArrowU Or (L_dJoy.dwYpos < 32767& - 15000)
  507.                         S_dInputState.KeyArrowD = S_dInputState.KeyArrowD Or (L_dJoy.dwYpos > 32767& + 15000)
  508.                     End If
  509.                     
  510.             ' Process input ...
  511.                 
  512.                 ' General functions ...
  513.                 
  514.                     ' ESCAPE: Leave game
  515.                     If S_dInputState.KeyEscape Then
  516.                         Terminating = True
  517.                     End If
  518.                     
  519.                    
  520.                     ' PLUS: Increase viewport size
  521.                     If S_dInputState.KeyPlus Then
  522.                         If Interface.ViewportSize > 0 Then
  523.                             Interface.ViewportSize = Interface.ViewportSize - 1
  524.                         End If
  525.                     End If
  526.                          
  527.                     ' MINUS: Decrease viewport size
  528.                     If S_dInputState.KeyMinus Then
  529.                         If Interface.ViewportSize < 20 Then
  530.                             Interface.ViewportSize = Interface.ViewportSize + 1
  531.                         End If
  532.                     End If
  533.                     
  534.                     ' Mouse on menu ...
  535.                     
  536.                         ' Only when left button click
  537.                         If S_dInputState.MouseB1 Then
  538.                         
  539.                             
  540.                             ' Change flyer
  541.                             If S_dInputState.MousePX > 480 + 57 And S_dInputState.MousePX < 480 + 57 + 22 Then
  542.                                 If S_dInputState.MousePY > 390 + 9 And S_dInputState.MousePY < 390 + 9 + 22 Then
  543.                                     If S_nKeyDelay = 0 Then
  544.                                             S_nKeyDelay = 10
  545.                                             Player.ChangeRacer
  546.                                             Application.Enemies.Active = False
  547.                                             Application.Reset
  548.                                             Application.Interface.DisplayMessage "new fighter arrived ... " & IIf(Application.Player.Model = rmJaguar, "Jaguar", "Warthog")
  549.                                     End If
  550.                                 End If
  551.                             End If
  552.                             
  553.                             ' Change daytime
  554.                             If S_dInputState.MousePX > 480 + 32 And S_dInputState.MousePX < 480 + 32 + 22 Then
  555.                                 If S_dInputState.MousePY > 390 + 34 And S_dInputState.MousePY < 390 + 34 + 22 Then
  556.                                     If S_nKeyDelay = 0 Then
  557.                                             S_nKeyDelay = 10
  558.                                             Environment.ChangeDaytime
  559.                                             Application.Enemies.Active = False
  560.                                             Application.Reset
  561.                                             Application.Interface.DisplayMessage "daytime changed"
  562.                                     End If
  563.                                 End If
  564.                             End If
  565.                         
  566.                             ' Change island
  567.                             If S_dInputState.MousePX > 480 + 7 And S_dInputState.MousePX < 480 + 7 + 22 Then
  568.                                 If S_dInputState.MousePY > 390 + 59 And S_dInputState.MousePY < 390 + 59 + 22 Then
  569.                                     If S_nKeyDelay = 0 Then
  570.                                             S_nKeyDelay = 10
  571.                                             Interface.Render True
  572.                                             If (Not Application.DSInstance Is Nothing) And Application.SoundEnabled Then
  573.                                                 DSListener.SetPosition 0, 0, -1000, DS3D_IMMEDIATE
  574.                                             End If
  575.                                             Environment.ChangeMap
  576.                                             Application.Enemies.Active = False
  577.                                             Application.Reset
  578.                                             Application.Interface.DisplayMessage "new island selected ... " & Application.Environment.IslandName
  579.                                     End If
  580.                                 End If
  581.                             End If
  582.                             
  583.                             ' Change screen size (+)
  584.                             If S_dInputState.MousePX > 480 + 100 And S_dInputState.MousePX < 480 + 100 + 22 Then
  585.                                 If S_dInputState.MousePY > 390 + 9 And S_dInputState.MousePY < 390 + 9 + 22 Then
  586.                                     If Interface.ViewportSize < 20 Then
  587.                                         Interface.ViewportSize = Interface.ViewportSize + 1
  588.                                     End If
  589.                                 End If
  590.                             End If
  591.                             
  592.                             ' Change screen size (-)
  593.                             If S_dInputState.MousePX > 480 + 130 And S_dInputState.MousePX < 480 + 130 + 22 Then
  594.                                 If S_dInputState.MousePY > 390 + 9 And S_dInputState.MousePY < 390 + 9 + 22 Then
  595.                                     If Interface.ViewportSize > 0 Then
  596.                                         Interface.ViewportSize = Interface.ViewportSize - 1
  597.                                     End If
  598.                                 End If
  599.                             End If
  600.                             
  601.                             ' Exit
  602.                             If S_dInputState.MousePX > 480 + 130 And S_dInputState.MousePX < 480 + 130 + 22 Then
  603.                                 If S_dInputState.MousePY > 390 + 60 And S_dInputState.MousePY < 390 + 60 + 22 Then
  604.                                     Terminating = True
  605.                                 End If
  606.                             End If
  607.                             
  608.                             ' Combat
  609.                             If S_dInputState.MousePX > 480 + 40 And S_dInputState.MousePX < 480 + 70 + 40 Then
  610.                                 If S_dInputState.MousePY > 390 + 40 And S_dInputState.MousePY < 390 + 43 + 40 Then
  611.                                     If S_nKeyDelay = 0 Then
  612.                                         Enemies.Active = Not Enemies.Active
  613.                                         Application.Interface.DisplayMessage IIf(Enemies.Active, "incoming fighters detected, protect station ...", "sector clear, no enemy activity reported ...")
  614.                                         Application.Reset
  615.                                         S_nKeyDelay = 10
  616.                                     End If
  617.                                 End If
  618.                             End If
  619.                             
  620.                             ' Sound
  621.                             If S_dInputState.MousePX > 480 + 114 And S_dInputState.MousePX < 480 + 118 + 17 Then
  622.                                 If S_dInputState.MousePY > 390 + 33 And S_dInputState.MousePY < 390 + 33 + 17 Then
  623.                                     If S_nKeyDelay = 0 Then
  624.                                         If Not (Application.DSInstance Is Nothing) Then
  625.                                             Application.SoundEnabled = Not Application.SoundEnabled
  626.                                             Application.Enemies.ToggleSound
  627.                                             Application.Player.ToggleSound
  628.                                         End If
  629.                                         S_nKeyDelay = 10
  630.                                     End If
  631.                                 End If
  632.                             End If
  633.                             
  634.                         End If
  635.                         
  636.                 ' Racer control ...
  637.                     
  638.                     ' UP: Accellerate
  639.                     If S_dInputState.KeyArrowU Then Player.Command pcAccellerate
  640.                     
  641.                     ' DOWN: Decellerate
  642.                     If S_dInputState.KeyArrowD Then Player.Command pcDecellerate
  643.                            
  644.                     ' LEFT: Bank left
  645.                     If S_dInputState.KeyArrowR Then Player.Command pcBankLeft
  646.                     
  647.                     ' RIGHT: Bank right
  648.                     If S_dInputState.KeyArrowL Then Player.Command pcBankRight
  649.                     
  650.                     ' SPACE: Jump
  651.                     If S_dInputState.KeySpace Then
  652.                         Player.Command pcJump
  653.                         If Not Me.FuelMessage Then
  654.                             If Not Application.Enemies.Active Then Application.Interface.DisplayMessage "jumps use up lots of fuel, watch the blue fuel bar ..."
  655.                             Me.FuelMessage = True
  656.                         End If
  657.                     End If
  658.                     
  659.                     ' CTRL: Shoot
  660.                     If S_dInputState.KeyCtrl Then Player.Command pcShoot
  661.             
  662.             ' Limit cursor to menu, remember cursor position ...
  663.             
  664.                 If S_dInputState.MousePX < 470 Then S_dInputState.MousePX = 470
  665.                 If S_dInputState.MousePY < 380 Then S_dInputState.MousePY = 380
  666.                 If S_dInputState.MousePX > 624 Then S_dInputState.MousePX = 624
  667.                 If S_dInputState.MousePY > 464 Then S_dInputState.MousePY = 464
  668.                 SetCursorPos S_dInputState.MousePX, S_dInputState.MousePY
  669.                 
  670.                 CursorX = S_dInputState.MousePX
  671.                 CursorY = S_dInputState.MousePY
  672.             
  673.     End Sub
  674.  
  675.     '
  676.     ' RENDER: Render frame
  677.     '
  678.     Public Sub Render()
  679.     
  680.         ' Declare local variables ...
  681.         
  682.             Dim L_dArea         As RECT                 ' Area from/to which to render
  683.             Dim L_dDDSD         As DDSURFACEDESC2       ' Descriptor for loading static surfaces
  684.             Dim L_dDDCK         As DDCOLORKEY           ' Colorkey for making static surfaces transparent
  685.             Static S_oDDSCursor As DirectDrawSurface4   ' Surface holding cursor
  686.             Static S_oDDSLogo   As DirectDrawSurface4   ' Surface holding logo
  687.             Static S_oDDSEracer As DirectDrawSurface4   ' Surface holding game logo
  688.             
  689.         ' Code ...
  690.         
  691.             ' Load static surfaces ...
  692.             
  693.                 ' Cursor ...
  694.                                         
  695.                     If S_oDDSCursor Is Nothing Then
  696.                         
  697.                         ' Prepare surface descriptor
  698.                         With L_dDDSD
  699.                             .lFlags = DDSD_CAPS Or DDSD_WIDTH Or DDSD_HEIGHT
  700.                             .ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN
  701.                             .lWidth = 16
  702.                             .lHeight = 16
  703.                         End With
  704.                         
  705.                         ' Load
  706.                         Set S_oDDSCursor = Application.DDInstance.CreateSurfaceFromFile(App.Path + "\gfx\cursor.bmp", L_dDDSD)
  707.                 
  708.                         ' Make transparent
  709.                         With L_dDDCK
  710.                             .low = 0
  711.                             .high = 0
  712.                         End With
  713.                         S_oDDSCursor.SetColorKey DDCKEY_SRCBLT, L_dDDCK
  714.                         
  715.                     End If
  716.                     
  717.                 ' Logo ...
  718.                 
  719.                     If S_oDDSLogo Is Nothing Then
  720.                         
  721.                         ' Prepare surface descriptor
  722.                         With L_dDDSD
  723.                             .lFlags = DDSD_CAPS Or DDSD_WIDTH Or DDSD_HEIGHT
  724.                             .ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN
  725.                             .lWidth = 359
  726.                             .lHeight = 59
  727.                         End With
  728.                         
  729.                         ' Load
  730.                         Set S_oDDSLogo = Application.DDInstance.CreateSurfaceFromFile(App.Path + "\gfx\nls.bmp", L_dDDSD)
  731.                 
  732.                     End If
  733.         
  734.                 ' Eracer Logo ...
  735.                 
  736.                     If S_oDDSEracer Is Nothing Then
  737.                         
  738.                         ' Prepare surface descriptor
  739.                         With L_dDDSD
  740.                             .lFlags = DDSD_CAPS Or DDSD_WIDTH Or DDSD_HEIGHT
  741.                             .ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN
  742.                             .lWidth = 240
  743.                             .lHeight = 60
  744.                         End With
  745.                         
  746.                         ' Load
  747.                         Set S_oDDSEracer = Application.DDInstance.CreateSurfaceFromFile(App.Path + "\gfx\logo.bmp", L_dDDSD)
  748.                 
  749.                     End If
  750.         
  751.             ' Clear cursor area ...
  752.             
  753.                 With L_dArea
  754.                     .Left = 470
  755.                     .Top = 380
  756.                     .Right = 640
  757.                     .Bottom = 480
  758.                 End With
  759.                 Application.DDSurface.BltColorFill L_dArea, 0
  760.                
  761.             ' Render background if necessary
  762.             If Interface.ViewportSizeChanged Then
  763.             
  764.                 ' Reset
  765.                 Interface.ViewportSizeChanged = False
  766.                 
  767.                 ' Logo ...
  768.                 
  769.                     With L_dArea
  770.                         .Left = 0
  771.                         .Top = 0
  772.                         .Right = 359
  773.                         .Bottom = 59
  774.                     End With
  775.                     Application.DDSurface.BltFast 5, 415, S_oDDSLogo, L_dArea, DDBLTFAST_NOCOLORKEY Or DDBLTFAST_WAIT
  776.                    
  777.                 ' Sign ...
  778.                 
  779.                     With L_dArea
  780.                         .Left = 0
  781.                         .Top = 0
  782.                         .Right = 240
  783.                         .Bottom = 60
  784.                     End With
  785.                     Application.DDSurface.BltFast 360, 40, S_oDDSEracer, L_dArea, DDBLTFAST_NOCOLORKEY Or DDBLTFAST_WAIT
  786.                 
  787.                 End If
  788.                 
  789.             ' Render 3D ...
  790.  
  791.                 ' Clear
  792.                 D3Viewport.Clear D3DRMCLEAR_TARGET Or D3DRMCLEAR_ZBUFFER
  793.  
  794.                 ' Render
  795.                 D3Instance.Tick 1
  796.             
  797.             ' Render 2D interface ...
  798.                 
  799.                 ' Render
  800.                 Interface.Render
  801.                
  802.             ' Render Cursor ...
  803.             
  804.                 With L_dArea
  805.                     .Left = 0
  806.                     .Top = 0
  807.                     .Right = 16
  808.                     .Bottom = 16
  809.                 End With
  810.                 DDSurface.BltFast CursorX, CursorY, S_oDDSCursor, L_dArea, DDBLTFAST_SRCCOLORKEY Or DDBLTFAST_WAIT
  811.                
  812.             ' Render backbuffer onto primary ...
  813.             
  814.                 ' Set source area
  815.                 With L_dArea
  816.                     .Left = 0
  817.                     .Top = 0
  818.                     .Right = 640
  819.                     .Bottom = 480
  820.                 End With
  821.                 
  822.                 ' Render backbuffer onto primary
  823.                 DDPrimary.BltFast 0, 0, DDSurface, L_dArea, DDBLTFAST_NOCOLORKEY Or DDBLTFAST_WAIT
  824.                 
  825.     End Sub
  826.     
  827.     '
  828.     ' RESET: Reset states on all subclasses
  829.     '
  830.     Public Sub Reset()
  831.         Player.Reset
  832.         Environment.Reset
  833.         Effects.Reset
  834.         Particles.Reset
  835.         Enemies.Reset
  836.         Shots.Reset
  837.     End Sub
  838.  
  839.