├── .gitignore ├── ExeRunner ├── ExeRunner.rc ├── ExeRunner.vcxproj ├── icon.ico ├── icon1.ico ├── main.cpp └── resource.h ├── LICENSE ├── NodeBuild.bat ├── OpenRoads.sln ├── OpenRoads ├── GameMain.js ├── GameMain.js.map ├── GameMain.ts ├── Images │ └── ico.png ├── JsLibs │ ├── tsm-0.7.js │ └── tsm-node.js ├── Libs │ ├── GLFW.d.ts │ ├── tsm-0.7.d.ts │ └── webaudio.d.ts ├── NodeAudioProcess.js ├── NodeAudioProcess.ts ├── NodeMain.js ├── NodeMain.js.map ├── NodeMain.ts ├── Notes │ ├── All Levels.htm │ ├── All Levels_files │ │ ├── app.css │ │ ├── roads.js │ │ └── tsm-0.7.js │ ├── BPs.txt │ ├── CARS.LZS.txt │ ├── DEMO.REC.txt │ ├── DrumRotator.py │ ├── Fonts.txt │ ├── GamePlay.txt │ ├── INTOR.SND.txt │ ├── MUZAX.LCS.txt │ ├── OPLCorrectPitch.txt │ ├── OXY_DISP.DAT.txt │ ├── Rendering.txt │ ├── RenderingEqs.txt │ ├── RenderingPts.txt │ ├── Todo.txt │ ├── matFromEqs.py │ ├── matFromPts.py │ ├── oplRevised.txt │ ├── oplRevised2.txt │ ├── sound.txt │ └── sub_5D4E.txt ├── OpenRoads.csproj ├── PhysicsTestMain.js ├── PhysicsTestMain.ts ├── Plz ReadMe.txt ├── Shaders │ ├── basic_2d.fs │ ├── basic_2d.vs │ ├── color_3d.fs │ ├── color_3d.vs │ ├── sprite_3d.fs │ ├── sprite_3d.vs │ ├── texture_p3d.fs │ ├── texture_p3d.vs │ ├── title_2d.fs │ └── title_2d.vs ├── app.css ├── faq.html ├── index.html ├── physics_test.html ├── update_glfw.bat ├── update_node_deps.bat └── vr.html ├── OpenRoadsLib ├── Libs │ ├── GLFW.d.ts │ ├── Promise.ts │ ├── tsm-0.7.d.ts │ └── webaudio.d.ts ├── OpenRoadsLib.csproj └── Src │ ├── Configurations │ ├── Node.ts │ └── NodeAudio.ts │ ├── Controls │ ├── CombinedControlSource.ts │ ├── ConditionWatcher.ts │ ├── ControlSource.ts │ ├── GLFWJoystick.ts │ ├── Joystick.ts │ ├── JoystickControlSource.ts │ ├── KeyboardControlSource.ts │ └── NavigatorJoystick.ts │ ├── Data │ ├── ArrayBitStream.js │ ├── ArrayBitStream.js.map │ ├── ArrayBitStream.ts │ ├── ArrayByteStream.js │ ├── ArrayByteStream.js.map │ ├── BinaryReader.js │ ├── BinaryReader.js.map │ ├── BinaryReader.ts │ ├── BitStream.js │ ├── BitStream.js.map │ ├── BitStream.ts │ ├── ByteStream.js │ ├── ByteStream.js.map │ ├── Color.js │ ├── Color.js.map │ ├── Color.ts │ ├── CompressedByteStream.js │ ├── CompressedByteStream.js.map │ └── CompressedByteStream.ts │ ├── Drawing │ ├── CanvasProvider.ts │ ├── HTMLCanvasProvider.ts │ ├── Mesh.ts │ ├── NodeCanvasProvider.ts │ ├── Sprite.ts │ ├── TextHelper.ts │ └── TextureFragment.ts │ ├── Engine │ ├── BrowserDocumentProvider.ts │ ├── CameraState.ts │ ├── ClassicState2DDrawer.ts │ ├── ClassicState3DDrawer.ts │ ├── Clock.ts │ ├── DocumentProvider.ts │ ├── FrameManager.ts │ ├── KeyboardManager.ts │ ├── NodeDocumentProvider.ts │ ├── State2D.ts │ ├── State3D.ts │ ├── VRState2DDrawer.ts │ └── VRState3DDrawer.ts │ ├── Events │ └── EventBus.ts │ ├── ExeData │ ├── ExeDataManager.ts │ └── ExeReader.ts │ ├── Game │ ├── CarSprite.ts │ ├── Controller.ts │ ├── Dashboard.ts │ ├── DemoController.ts │ ├── Events │ │ ├── ShipBouncedEvent.ts │ │ ├── ShipBumpedWallEvent.ts │ │ ├── ShipExplodedEvent.ts │ │ └── ShipRefilledEvent.ts │ ├── FPMath.ts │ ├── FixedRateSnapshotProvider.ts │ ├── GameSnapshot.ts │ ├── GameSnapshotProvider.ts │ ├── InterpolatingSnapshotProvider.ts │ ├── KeyboardController.ts │ ├── Ship.ts │ └── StateManager.ts │ ├── Images │ ├── Loader.ts │ └── Preloader.ts │ ├── Levels │ ├── Level.js │ ├── Level.js.map │ ├── Level.ts │ ├── LevelToTableRenderer.ts │ ├── Loader.js │ ├── Loader.js.map │ ├── Loader.ts │ └── MeshBuilder.ts │ ├── Managers │ ├── ManagerSet.ts │ ├── SettingsManager.ts │ ├── ShaderManager.ts │ ├── SoundManager.ts │ ├── StreamManager.ts │ └── TextureManager.ts │ ├── Music │ ├── MusicPlayer.ts │ ├── OPL.ts │ └── OPLConstants.ts │ ├── RefPhysics │ ├── RefShip.ts │ └── RefStateManager.ts │ ├── Shaders │ ├── ClassicShaderProvider.ts │ ├── ShaderProvider.ts │ └── VRShaderProvider.ts │ ├── Sounds │ ├── AudioProvider.ts │ ├── ChildProcessAudioProvider.ts │ ├── ChildProcessAudioServer.ts │ ├── InThreadAudioProvider.ts │ ├── LowLevelAudioProvider.ts │ ├── PortAudioAudioProvider.ts │ ├── Sound.ts │ └── WebAPIAudioProvider.ts │ ├── States │ ├── ControlsState.ts │ ├── EmptyState.ts │ ├── FadeState2D.ts │ ├── FadeState3D.ts │ ├── GLStateHelper.ts │ ├── GameState.ts │ ├── GoMenuState.ts │ ├── HelpState.ts │ ├── Intro.ts │ └── MainMenuState.ts │ ├── Storage │ ├── AJAXFileProvider.ts │ ├── FSStore.ts │ ├── FileProvider.ts │ ├── KVStore.ts │ ├── LocalFileProvider.ts │ └── LocalStorageStore.ts │ ├── TestRuns │ ├── TestCar.ts │ ├── TestDats.ts │ ├── TestImages.ts │ ├── TestLevels.ts │ ├── TestSounds.ts │ └── TestTrakDat.ts │ ├── UI │ ├── BooleanSetting.ts │ ├── NumberSetting.ts │ └── Setting.ts │ ├── VR │ ├── NodeVRProvider.ts │ └── VRProvider.ts │ ├── Vertices │ ├── Vertex2D.ts │ └── Vertex3DC.ts │ └── WGL │ ├── Attrib.ts │ ├── Buffer.ts │ ├── Framebuffer.ts │ ├── Renderable.ts │ ├── RenderableTexture.ts │ ├── Renderbuffer.ts │ ├── Shader.ts │ ├── ShaderUniform.ts │ ├── Texture.ts │ └── VertexDescriptor.ts ├── README.md └── WebBuild.bat /ExeRunner/ExeRunner.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anprogrammer/OpenRoads/67f0946d2c1bf3450cb64607b2b60a77d7dc7e63/ExeRunner/ExeRunner.rc -------------------------------------------------------------------------------- /ExeRunner/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anprogrammer/OpenRoads/67f0946d2c1bf3450cb64607b2b60a77d7dc7e63/ExeRunner/icon.ico -------------------------------------------------------------------------------- /ExeRunner/icon1.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anprogrammer/OpenRoads/67f0946d2c1bf3450cb64607b2b60a77d7dc7e63/ExeRunner/icon1.ico -------------------------------------------------------------------------------- /ExeRunner/main.cpp: -------------------------------------------------------------------------------- 1 | #ifdef CLASSIC 2 | #define ARG_NAME "classic" 3 | #endif 4 | 5 | #ifdef XMAS 6 | #define ARG_NAME "xmas" 7 | #endif 8 | 9 | #ifndef ARG_NAME 10 | #define ARG_NAME "unset" 11 | #endif 12 | 13 | #include 14 | int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) { 15 | ::SetCurrentDirectory(L"Node"); 16 | ::system("node.exe NodeMain.js " ARG_NAME); 17 | } -------------------------------------------------------------------------------- /ExeRunner/resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anprogrammer/OpenRoads/67f0946d2c1bf3450cb64607b2b60a77d7dc7e63/ExeRunner/resource.h -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 anprogrammer 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /OpenRoads/GameMain.js: -------------------------------------------------------------------------------- 1 | /// 2 | window.onload = function () { 3 | runGame(); 4 | }; 5 | 6 | function runGame() { 7 | var cvs = document.getElementById('cvs'); 8 | var gl = cvs.getContext('webgl') || cvs.getContext('experimental-webgl'); 9 | if (!gl) { 10 | document.getElementById('error_webgl').style.display = ''; 11 | return; 12 | } 13 | 14 | var actx = null; 15 | try { 16 | actx = new webkitAudioContext(); 17 | } catch (e) { 18 | } 19 | try { 20 | actx = new AudioContext(); 21 | } catch (e) { 22 | } 23 | 24 | if (!actx) { 25 | document.getElementById('error_webaudio').style.display = ''; 26 | } 27 | 28 | var isXMas = window.location.search.indexOf('xmas=1') >= 0; 29 | 30 | var manager = new Managers.StreamManager(new Stores.AJAXFileProvider(), isXMas ? 'Data.XMas/' : 'Data/'), shaderManager = new Managers.ShaderManager(manager); 31 | var managers = new Managers.ManagerSet(manager, shaderManager); 32 | managers.Sounds = new Managers.SoundManager(managers); 33 | 34 | var src = new Controls.CombinedControlSource(); 35 | src.addSource(new Controls.KeyboardControlSource(new Engine.KeyboardManager(document.body))); 36 | src.addSource(new Controls.JoystickControlSource(new Controls.NavigatorJoystick(navigator))); 37 | managers.Controls = src; 38 | managers.Settings = new Managers.SettingsManager(new Stores.LocalStorageStore(isXMas ? 'xmas' : 'classic')); 39 | managers.Graphics = new Shaders.ClassicShaderProvider(); 40 | managers.Textures = new Managers.TextureManager(managers); 41 | managers.Canvas = new Drawing.HTMLCanvasProvider(); 42 | managers.VR = null; 43 | managers.SnapshotProvider = managers.Settings.UseInterpolation ? new Game.InterpolatingSnapshoptProvider() : new Game.FixedRateSnapshotProvider(); 44 | 45 | //managers.Graphics = new Shaders.VRShaderProvider(); 46 | manager.loadMultiple([ 47 | "Shaders/basic_2d.fs", "Shaders/basic_2d.vs", 'Shaders/title_2d.fs', 'Shaders/title_2d.vs', 'Shaders/color_3d.vs', 'Shaders/color_3d.fs', 48 | "Data/SKYROADS.EXE", 49 | "Data/ANIM.LZS", 50 | "Data/CARS.LZS", 51 | "Data/DASHBRD.LZS", 52 | "Data/DEMO.REC", 53 | "Data/FUL_DISP.DAT", 54 | "Data/GOMENU.LZS", 55 | "Data/HELPMENU.LZS", 56 | "Data/INTRO.LZS", 57 | "Data/INTRO.SND", 58 | "Data/MAINMENU.LZS", 59 | "Data/MUZAX.LZS", 60 | "Data/OXY_DISP.DAT", 61 | "Data/ROADS.LZS", 62 | "Data/SETMENU.LZS", 63 | "Data/SFX.SND", 64 | "Data/SPEED.DAT", 65 | "Data/TREKDAT.LZS", 66 | "Data/WORLD0.LZS", 67 | "Data/WORLD1.LZS", 68 | "Data/WORLD2.LZS", 69 | "Data/WORLD3.LZS", 70 | "Data/WORLD4.LZS", 71 | "Data/WORLD5.LZS", 72 | "Data/WORLD6.LZS", 73 | "Data/WORLD7.LZS", 74 | "Data/WORLD8.LZS", 75 | "Data/WORLD9.LZS" 76 | ]).done(function () { 77 | var exe = new ExeData.ExeDataLoader(managers); 78 | exe.load(); 79 | 80 | var audioProvider = new Sounds.WebAPIAudioProvider(actx); 81 | var opl = new Music.OPL(audioProvider); 82 | var player = new Music.Player(opl, managers); 83 | opl.setSource(player); 84 | 85 | managers.Audio = new Sounds.InThreadAudioProvider(audioProvider, player); 86 | 87 | document.getElementById('loading').style.display = 'none'; 88 | cvs.style.display = 'block'; 89 | 90 | var demoCon = new Game.DemoController(manager.getRawArray('DEMO.REC')); 91 | var state = new States.Intro(managers); 92 | 93 | //var state = new States.GoMenu(managers); 94 | //var state = new States.MainMenu(managers); 95 | managers.Frames = new Engine.FrameManager(new Engine.BrowserDocumentProvider(), cvs, managers, state, new Engine.Clock()); 96 | }); 97 | } 98 | //# sourceMappingURL=GameMain.js.map 99 | -------------------------------------------------------------------------------- /OpenRoads/GameMain.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"GameMain.js","sourceRoot":"","sources":["GameMain.ts"],"names":["runGame"],"mappings":"AAAA,sCAAsC;AACtC,MAAM,CAAC,MAAM,GAAG;IACZ,OAAO,CAAC,CAAC;AACb,CAAC;;AAED,SAAS,OAAO;IACZA,IAAIA,GAAGA,GAAsBA,QAAQA,CAACA,cAAcA,CAACA,KAAKA,CAACA;IAC3DA,IAAIA,EAAEA,GAAGA,GAAGA,CAACA,UAAUA,CAACA,OAAOA,CAACA,IAAIA,GAAGA,CAACA,UAAUA,CAACA,oBAAoBA,CAACA;IACxEA,IAAIA,CAACA,EAAEA,CAAEA;QACLA,QAAQA,CAACA,cAAcA,CAACA,aAAaA,CAACA,CAACA,KAAKA,CAACA,OAAOA,GAAGA,EAAEA;QACzDA,MAAOA;KACVA;;IAEDA,IAAIA,IAAIA,GAAiBA,IAAIA;IAC7BA,IAAIA;QACAA,IAAIA,GAAGA,IAAIA,kBAAkBA,CAACA,CAACA;KAClCA,CAACA,OAAOA,CAACA,CAAEA;KACXA;IACDA,IAAIA;QACAA,IAAIA,GAAGA,IAAIA,YAAYA,CAACA,CAACA;KAC5BA,CAACA,OAAOA,CAACA,CAAEA;KACXA;;IAEDA,IAAIA,CAACA,IAAIA,CAAEA;QACPA,QAAQA,CAACA,cAAcA,CAACA,gBAAgBA,CAACA,CAACA,KAAKA,CAACA,OAAOA,GAAGA,EAAEA;KAC/DA;;IAEDA,IAAIA,MAAMA,GAAGA,MAAMA,CAACA,QAAQA,CAACA,MAAMA,CAACA,OAAOA,CAACA,QAAQA,CAACA,IAAIA,CAACA;;IAG1DA,IAAIA,OAAOA,GAAGA,IAAIA,QAAQA,CAACA,aAAaA,CAACA,IAAIA,MAAMA,CAACA,gBAAgBA,CAACA,CAACA,EAAEA,MAAMA,GAAGA,YAAYA,GAAGA,OAAOA,CAACA,EAAEA,aAAaA,GAAGA,IAAIA,QAAQA,CAACA,aAAaA,CAACA,OAAOA,CAACA;IAC7JA,IAAIA,QAAQA,GAAGA,IAAIA,QAAQA,CAACA,UAAUA,CAACA,OAAOA,EAAEA,aAAaA,CAACA;IAC9DA,QAAQA,CAACA,MAAMA,GAAGA,IAAIA,QAAQA,CAACA,YAAYA,CAACA,QAAQA,CAACA;;IAErDA,IAAIA,GAAGA,GAAGA,IAAIA,QAAQA,CAACA,qBAAqBA,CAACA,CAACA;IAC9CA,GAAGA,CAACA,SAASA,CAACA,IAAIA,QAAQA,CAACA,qBAAqBA,CAACA,IAAIA,MAAMA,CAACA,eAAeA,CAACA,QAAQA,CAACA,IAAIA,CAACA,CAACA,CAACA;IAC5FA,GAAGA,CAACA,SAASA,CAACA,IAAIA,QAAQA,CAACA,qBAAqBA,CAACA,IAAIA,QAAQA,CAACA,iBAAiBA,CAAMA,SAASA,CAACA,CAACA,CAACA;IACjGA,QAAQA,CAACA,QAAQA,GAAGA,GAAGA;IACvBA,QAAQA,CAACA,QAAQA,GAAGA,IAAIA,QAAQA,CAACA,eAAeA,CAACA,IAAIA,MAAMA,CAACA,iBAAiBA,CAACA,MAAMA,GAAGA,MAAMA,GAAGA,SAASA,CAACA,CAACA;IAC3GA,QAAQA,CAACA,QAAQA,GAAGA,IAAIA,OAAOA,CAACA,qBAAqBA,CAACA,CAACA;IACvDA,QAAQA,CAACA,QAAQA,GAAGA,IAAIA,QAAQA,CAACA,cAAcA,CAACA,QAAQA,CAACA;IACzDA,QAAQA,CAACA,MAAMA,GAAGA,IAAIA,OAAOA,CAACA,kBAAkBA,CAACA,CAACA;IAClDA,QAAQA,CAACA,EAAEA,GAAGA,IAAIA;IAClBA,QAAQA,CAACA,gBAAgBA,GAAGA,QAAQA,CAACA,QAAQA,CAACA,gBAAgBA,GAAGA,IAAIA,IAAIA,CAACA,8BAA8BA,CAACA,CAACA,GAAGA,IAAIA,IAAIA,CAACA,yBAAyBA,CAACA,CAACA;;IAEjJA,qDAAqDA;IAErDA,OAAOA,CAACA,YAAYA,CAACA;QAACA,qBAAqBA,EAAEA,qBAAqBA,EAAEA,qBAAqBA,EAAEA,qBAAqBA,EAAEA,qBAAqBA,EAAEA,qBAAqBA;QAC1JA,mBAAmBA;QACnBA,eAAeA;QACfA,eAAeA;QACfA,kBAAkBA;QAClBA,eAAeA;QACfA,mBAAmBA;QACnBA,iBAAiBA;QACjBA,mBAAmBA;QACnBA,gBAAgBA;QAChBA,gBAAgBA;QAChBA,mBAAmBA;QACnBA,gBAAgBA;QAChBA,mBAAmBA;QACnBA,gBAAgBA;QAChBA,kBAAkBA;QAClBA,cAAcA;QACdA,gBAAgBA;QAChBA,kBAAkBA;QAClBA,iBAAiBA;QACjBA,iBAAiBA;QACjBA,iBAAiBA;QACjBA,iBAAiBA;QACjBA,iBAAiBA;QACjBA,iBAAiBA;QACjBA,iBAAiBA;QACjBA,iBAAiBA;QACjBA,iBAAiBA;QACjBA,iBAAiBA;KACpBA,CAACA,CAACA,IAAIA,CAACA;QACAA,IAAIA,GAAGA,GAAGA,IAAIA,OAAOA,CAACA,aAAaA,CAACA,QAAQA,CAACA;QAC7CA,GAAGA,CAACA,IAAIA,CAACA,CAACA;;QAEVA,IAAIA,aAAaA,GAAGA,IAAIA,MAAMA,CAACA,mBAAmBA,CAACA,IAAIA,CAACA;QACxDA,IAAIA,GAAGA,GAAGA,IAAIA,KAAKA,CAACA,GAAGA,CAACA,aAAaA,CAACA;QACtCA,IAAIA,MAAMA,GAAGA,IAAIA,KAAKA,CAACA,MAAMA,CAACA,GAAGA,EAAEA,QAAQA,CAACA;QAC5CA,GAAGA,CAACA,SAASA,CAACA,MAAMA,CAACA;;QAErBA,QAAQA,CAACA,KAAKA,GAAGA,IAAIA,MAAMA,CAACA,qBAAqBA,CAACA,aAAaA,EAAEA,MAAMA,CAACA;;QAExEA,QAAQA,CAACA,cAAcA,CAACA,SAASA,CAACA,CAACA,KAAKA,CAACA,OAAOA,GAAGA,MAAMA;QACzDA,GAAGA,CAACA,KAAKA,CAACA,OAAOA,GAAGA,OAAOA;;QAE3BA,IAAIA,OAAOA,GAAGA,IAAIA,IAAIA,CAACA,cAAcA,CAACA,OAAOA,CAACA,WAAWA,CAACA,UAAUA,CAACA,CAACA;QACtEA,IAAIA,KAAKA,GAAGA,IAAIA,MAAMA,CAACA,KAAKA,CAACA,QAAQA,CAACA;;QACtCA,0CAA0CA;QAC1CA,4CAA4CA;QAC5CA,QAAQA,CAACA,MAAMA,GAAGA,IAAIA,MAAMA,CAACA,YAAYA,CAACA,IAAIA,MAAMA,CAACA,uBAAuBA,CAACA,CAACA,EAAEA,GAAGA,EAAEA,QAAQA,EAAEA,KAAKA,EAAEA,IAAIA,MAAMA,CAACA,KAAKA,CAACA,CAACA,CAACA;IAC7HA,CAACA,CAACA;AACVA,CAACA"} -------------------------------------------------------------------------------- /OpenRoads/Images/ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anprogrammer/OpenRoads/67f0946d2c1bf3450cb64607b2b60a77d7dc7e63/OpenRoads/Images/ico.png -------------------------------------------------------------------------------- /OpenRoads/Libs/GLFW.d.ts: -------------------------------------------------------------------------------- 1 | declare module GLFW { 2 | export class GLFW { 3 | enableHMD(disableVsync: boolean): boolean; 4 | getHMDTargetSize(): number[]; 5 | getHMDFboId(gl: WebGLRenderingContext): number; 6 | getEyeViewAdjust(n: number): number[]; 7 | getEyeViewport(n: number): number[]; 8 | getHeadPosition(n: number): number[]; 9 | getHeadOrientation(n: number): number[]; 10 | getProjectionMatrix(n: number): number[]; 11 | getJoystickAxes(): string; 12 | getJoystickButtons(): string; 13 | startVREye(n: number): void; 14 | endVREye(n: number): void; 15 | isVRSafetyWarningVisible(): boolean; 16 | resetVROrientation(): void; 17 | getMonitorCount(): number; 18 | destroyWindow(window: HTMLCanvasElement): void; 19 | } 20 | } -------------------------------------------------------------------------------- /OpenRoads/NodeAudioProcess.js: -------------------------------------------------------------------------------- 1 | var rl = require('./RoadsLib'); 2 | GLOBAL.TSM = require('./JsLibs/tsm-node'); 3 | rl.Configurations.runNodeAudio(); 4 | //# sourceMappingURL=NodeAudioProcess.js.map 5 | -------------------------------------------------------------------------------- /OpenRoads/NodeAudioProcess.ts: -------------------------------------------------------------------------------- 1 | declare function require(s: string): any; 2 | declare var GLOBAL: any; 3 | declare var process: any; 4 | var rl = require('./RoadsLib'); 5 | GLOBAL.TSM = require('./JsLibs/tsm-node'); 6 | rl.Configurations.runNodeAudio(); -------------------------------------------------------------------------------- /OpenRoads/NodeMain.js: -------------------------------------------------------------------------------- 1 | var rl = require('./RoadsLib'); 2 | GLOBAL.TSM = require('./JsLibs/tsm-node'); 3 | rl.Configurations.runNode(process.argv[2]); 4 | //# sourceMappingURL=NodeMain.js.map 5 | -------------------------------------------------------------------------------- /OpenRoads/NodeMain.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"NodeMain.js","sourceRoot":"","sources":["NodeMain.ts"],"names":[],"mappings":"AAGA,IAAI,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC;AAC9B,MAAM,CAAC,GAAG,GAAG,OAAO,CAAC,mBAAmB,CAAC;AACzC,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC"} -------------------------------------------------------------------------------- /OpenRoads/NodeMain.ts: -------------------------------------------------------------------------------- 1 | declare function require(s: string): any; 2 | declare var GLOBAL: any; 3 | declare var process: any; 4 | var rl = require('./RoadsLib'); 5 | GLOBAL.TSM = require('./JsLibs/tsm-node'); 6 | rl.Configurations.runNode(process.argv[2]); -------------------------------------------------------------------------------- /OpenRoads/Notes/All Levels_files/app.css: -------------------------------------------------------------------------------- 1 | html { 2 | margin: 0; 3 | padding: 0; 4 | width: 100%; 5 | height: 100%; 6 | } 7 | 8 | body { 9 | font-family: 'Segoe UI', sans-serif; 10 | margin: 0; 11 | padding: 0; 12 | overflow: hidden; 13 | width: 100%; 14 | height: 100%; 15 | background: #3075ba; /* Old browsers */ 16 | 17 | background: -moz-linear-gradient(top, #3075ba 0%, #000000 100%); /* FF3.6+ */ 18 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#3075ba), color-stop(100%,#000000)); /* Chrome,Safari4+ */ 19 | background: -webkit-linear-gradient(top, #3075ba 0%,#000000 100%); /* Chrome10+,Safari5.1+ */ 20 | background: -o-linear-gradient(top, #3075ba 0%,#000000 100%); /* Opera 11.10+ */ 21 | background: -ms-linear-gradient(top, #3075ba 0%,#000000 100%); /* IE10+ */ 22 | background: linear-gradient(to bottom, #3075ba 0%,#000000 100%); /* W3C */ 23 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#3075ba', endColorstr='#000000',GradientType=0 ); /* IE6-9 */ 24 | } 25 | 26 | canvas { 27 | position: absolute; 28 | border: none; 29 | border-left: 1px solid black; 30 | border-right: 1px solid black; 31 | } 32 | 33 | span { 34 | font-style: italic; 35 | } 36 | 37 | .debugTable { 38 | padding: 0; 39 | margin: 0; 40 | border-spacing: 0; 41 | } 42 | 43 | .debugTable tr { 44 | margin: 0; 45 | padding: 0; 46 | } 47 | .debugTable td { 48 | padding: 0; 49 | margin: 0; 50 | margin: 1px solid black; 51 | } 52 | 53 | .debugTable div { 54 | margin: 0; 55 | } -------------------------------------------------------------------------------- /OpenRoads/Notes/BPs.txt: -------------------------------------------------------------------------------- 1 | SM 1A2:224 E9 E3 00 2 | 3 | BP 1A2:2308 4 | BPVAR 0 Ident DEAD 5 | BPVAR 0 InAccel [DS:933C] 6 | BPVAR 0 InTurn [DS:9600] 7 | BPVAR 0 InJump [DS:5488] 8 | BPVAR 0 CurrentX [DS:AF2C] 9 | BPVAR 0 CurrentY [DS:AF3C] 10 | BPVAR 0 CurrentZHigh [DS:962A] 11 | BPVAR 0 CurrentZLow [DS:9628] 12 | BPVAR 0 XMovementBase [DS:4576] 13 | BPVAR 0 YVelocity [DS:9342] 14 | BPVAR 0 ZVelocity [DS:54B8] 15 | BPVAR 0 ExpectedX [DS:BP-1A] 16 | BPVAR 0 ExpectedY [DS:BP-1C] 17 | BPVAR 0 ExpectedZHigh [DS:BP-1E] 18 | BPVAR 0 ExpectedZLow [DS:BP-20] 19 | 20 | BP 1A2:2369 21 | BPVAR 0 Ident BEEF 22 | BPVAR 0 TouchEffect 23 | 24 | BP 1A2:26C7 25 | BPVAR 0 Ident CAFE 26 | BPVAR 0 InAccel [DS:933C] 27 | BPVAR 0 InTurn [DS:9600] 28 | BPVAR 0 InJump [DS:5488] 29 | BPVAR 0 CurrentX [DS:AF2C] 30 | BPVAR 0 CurrentY [DS:AF3C] 31 | BPVAR 0 CurrentZHigh [DS:962A] 32 | BPVAR 0 CurrentZLow [DS:9628] 33 | BPVAR 0 XMovementBase [DS:4576] 34 | BPVAR 0 YVelocity [DS:9342] 35 | BPVAR 0 ZVelocity [DS:54B8] 36 | BPVAR 0 ExpectedX [DS:BP-1A] 37 | BPVAR 0 ExpectedY [DS:BP-1C] 38 | BPVAR 0 ExpectedZHigh [DS:BP-1E] 39 | BPVAR 0 ExpectedZLow [DS:BP-20] 40 | 41 | BP 1A2:26CD 42 | BPVAR 0 Ident FEED 43 | BPVAR 0 InAccel [DS:933C] 44 | BPVAR 0 InTurn [DS:9600] 45 | BPVAR 0 InJump [DS:5488] 46 | BPVAR 0 CurrentX [DS:AF2C] 47 | BPVAR 0 CurrentY [DS:AF3C] 48 | BPVAR 0 CurrentZHigh [DS:962A] 49 | BPVAR 0 CurrentZLow [DS:9628] 50 | BPVAR 0 XMovementBase [DS:4576] 51 | BPVAR 0 YVelocity [DS:9342] 52 | BPVAR 0 ZVelocity [DS:54B8] 53 | BPVAR 0 ExpectedX [DS:BP-1A] 54 | BPVAR 0 ExpectedY [DS:BP-1C] 55 | BPVAR 0 ExpectedZHigh [DS:BP-1E] 56 | BPVAR 0 ExpectedZLow [DS:BP-20] -------------------------------------------------------------------------------- /OpenRoads/Notes/CARS.LZS.txt: -------------------------------------------------------------------------------- 1 | Each frame is 30px tall 2 | -------------------------------------------------------------------------------- /OpenRoads/Notes/DEMO.REC.txt: -------------------------------------------------------------------------------- 1 | Craft position stored in fixed point format: 2 | Tile position:(tile position/0xFFFF) 3 | 4 | If you take this, and divide by 0x666: 5 | Tile Position * 0xFFFF / 0x666, use as byte index into DEMO.REC: 6 | 7 | (al & 3) - 1 = Accelerate_Decelrater 8 | ((al >>= 2) & 3) - 1 = Left_Right 9 | ((al >>= 4) & 1) -1 = Jump 10 | -------------------------------------------------------------------------------- /OpenRoads/Notes/DrumRotator.py: -------------------------------------------------------------------------------- 1 | def ROR(x, n): 2 | mask = (2**n) - 1 3 | mask_bits = x & mask 4 | return (x >> n) | (mask_bits << (8 - n)) 5 | 6 | for i in range(0,15): 7 | print bin(ROR(0xEF, i)) 8 | -------------------------------------------------------------------------------- /OpenRoads/Notes/Fonts.txt: -------------------------------------------------------------------------------- 1 | Number-set starts at 0x13C 2 | Each character 0x14 units long. 5 Tall, 4 wide. Numbers should be seperated by a space. 3 | Gravity drawn starting at: 96, 156 4 | 5 | Number is (gravity-num - 3) * 100 6 | 7 | Jump-o-master starts at 0x204, each img is 26 wide, 5 tall 8 | Draw to: 203, 156 9 | 10 | Progress indicators is 29 pixels wide, starts at 42 pixels from left of screen, 143 from top. 11 | You go from 0-% * 29, start at pixel (x, 143), work up until no longer purple. Then work your way down, filling in purple, until you hit non-purple again. Easy-peezy-like 12 | 13 | For flashing O2: 14 | Inside 7x7 pixel box at 0xA0, 0xA1 swap all red pixels for white and vice-versa 15 | For flashing Fuel: 16 | Inside 16x5 pixel box at 0x9B, 0xA9 swap all red pixels for white and vice-versa 17 | 18 | 19 | CraftState: 20 | 5 = OutOfOxygen 21 | 4 = OutOfFuel 22 | 3 = FallingToDeath 23 | 1 = Exploded 24 | 2 = NotSure 25 | 0 = Alive -------------------------------------------------------------------------------- /OpenRoads/Notes/GamePlay.txt: -------------------------------------------------------------------------------- 1 | Oxygen: 2 | OxygenLevel -= 0x7530 / (0x24 * LevelOxygenVal) (per frame) 3 | 4 | 5 | Y values: 6 | 0x2800 == on ground 7 | 0x3200 == On l1 8 | 0x3c00 == on l2 9 | 0x3700 == On l3 10 | 11 | Center X 0x8000 12 | Min: 0x2F80 13 | Max: 0xD080 14 | 15 | After death the game waits 108 frames before resetting -------------------------------------------------------------------------------- /OpenRoads/Notes/INTOR.SND.txt: -------------------------------------------------------------------------------- 1 | Both sound files are literally a stream of 8 - bit audio Data 2 | Need to find "split" locations in SFX.SND 3 | Intro just play at start -------------------------------------------------------------------------------- /OpenRoads/Notes/MUZAX.LCS.txt: -------------------------------------------------------------------------------- 1 | Top of file is 6 - byte headers 2 | 2 - bytes(location in file to decompress from) 3 | 2 - Offset into decompressed stream to start "playing" from (* 0x10) 4 | 2 - Length to decompress 5 | 6 | 7 | First sends to OPL 8 | 40 <- 3F 9 | F4 <- 0 (waveform select sine wave) 10 | 11 | 12 | (func 0 example. End note config sequence) 13 | Example from song 1: 14 | Start from 0x90 15 | Load EAX = 8A00 16 | BX == 0 (LowestThreeBits) 17 | EAX = 0x8A00 18 | Tells interrupt that is all notes for now 19 | 20 | 21 | (func 1 example) 22 | 0x0301 is second word loaded: 23 | BX == 1 24 | AH == 0x03 25 | AL == 0x01 26 | 27 | (func 2. Drum or note off) -------------------------------------------------------------------------------- /OpenRoads/Notes/OXY_DISP.DAT.txt: -------------------------------------------------------------------------------- 1 | Low numbers indicate colors 2 | 0-Transparent 3 | 1-Dark purple 4 | 2-Light purple 5 | 6 | First one of these is at offset 14 7 | Bytes 0x179 and onwards represent the last "sector" of oxy display 8 | bytes 0x177 & 0x178 are w & h of section 9 | short 0x175 is offset from pixel 0 10 | 11 | 12 | For OXY_DISP.DAT & FUL_DISP.DAT: Starts @ 0x14: 13 | Uint16: for position 14 | Uint8: w, h 15 | W*H Uint8: 0 transparent, 1 dark, 2 light -------------------------------------------------------------------------------- /OpenRoads/Notes/Rendering.txt: -------------------------------------------------------------------------------- 1 | Left-most tile starts at x=-3.5, ends at x=2.5 2 | 3 | 4 | XP = A * (X + B) / Z + C 5 | YP = D * (Y + E) / Z + F 6 | 7 | XP = A * X / Z + B / Z + C 8 | YP = D * Y / Z + E / Z + F 9 | 10 | 24 = A * 23 / 2 + B / 2 + C 11 | 102 = C * 80 / 2 + E / 2 + F 12 | 13 | 15 = A * 23 / 3 + C 14 | 76 = C * 80 / 3 + F 15 | 16 | 10 = A * 23 / 4 + B 17 | 61 = C * 80 / 4 + D 18 | 19 | 7 = A * 23 / 5 + B 20 | 52 = C * 80 / 5 + D 21 | 22 | 5 = A * 23 / 6 + B 23 | 46 = C * 80 / 6 + D 24 | 25 | lbfgs([%o1,%o2,%o3,%o4,%o5,%o6,%o7,%o8],[A,B,C,D],[0,0,0,0],1e-4,[1,0]); -------------------------------------------------------------------------------- /OpenRoads/Notes/RenderingEqs.txt: -------------------------------------------------------------------------------- 1 | 1.057 56.322 -8.860 300239975158032.000 -24019198012642400.000 20.000 2 | 24 = A * 23 / 2 + B / 2 + C 3 | 102 = C * 80 / 2 + E / 2 + F 4 | 5 | 15 = A * 23 / 3 + B / 3 + C 6 | 76 = C * 80 / 3 + E / 3 + F 7 | 8 | 10 = A * 23 / 4 + B / 4 + C 9 | 61 = C * 80 / 4 + E / 4 + F 10 | 11 | 7 = A * 23 / 5 + B / 5 + C 12 | 52 = D * 80 / 5 + E / 5 + F 13 | 14 | 5 = A * 23 / 6 + B / 6 + C 15 | 46 = D * 80 / 6 + E / 6 + F 16 | 17 | 70 = A * 69 / 2 + B / 2 + C 18 | 102 = D * 80 / 2 + E / 2 + F 19 | 20 | 44 = A * 69 / 3 + B / 3 + C 21 | 76 = D * 80 / 3 + E / 3 + F 22 | 23 | 5 = A * 69 / 8 + B / 8 + C 24 | 37 = D * 80 / 8 + B / 8 + F 25 | 26 | 70 = A * 115 / 2 + B / 2 + C 27 | 102 = C * 80 / 2 + E / 2 + F 28 | -------------------------------------------------------------------------------- /OpenRoads/Notes/RenderingPts.txt: -------------------------------------------------------------------------------- 1 | 23,80,2 -> 24,102 2 | 23,80,3 -> 15,76 3 | 23,80,4 -> 10,61 4 | 23,80,5 -> 7,52 5 | 23,80,6 -> 5,46 6 | 69,80,2 -> 70,102 7 | 69,80,3 -> 44,76 8 | 69,80,8 -> 5,37 9 | 115,80,2 -> 70,102 10 | -------------------------------------------------------------------------------- /OpenRoads/Notes/Todo.txt: -------------------------------------------------------------------------------- 1 | Fix audio problems 2 | 3 | Replace video with actual video 4 | 5 | GO LIVE VERSION! 6 | Improve music accuracy 7 | Fix "ANIM" missing ship parts -------------------------------------------------------------------------------- /OpenRoads/Notes/matFromEqs.py: -------------------------------------------------------------------------------- 1 | f = open('RenderingEqs.txt') 2 | l1 = f.readline() 3 | data = f.readlines() 4 | 5 | a, b, c, d, e, f = [float(x) for x in l1.split(' ')] 6 | 7 | def splitEq(eq, a, b, c): 8 | eq = eq.split(' ') 9 | res = int(eq[0]) 10 | off = int(eq[4]) 11 | z = int(eq[6]) 12 | 13 | actual = a * off / z + b / z + c 14 | print("ERR: {2} FROM {0} <> {1}".format(actual, res, abs(actual - res))) 15 | return eq[0], "{0} {1} 1".format(off / z, 1.0 / z) 16 | 17 | xMat = "" 18 | xRes = "" 19 | 20 | yMat = "" 21 | yRes = "" 22 | 23 | for i in range(0, len(data), 3): 24 | xR, xM = splitEq(data[i], a, b, c) 25 | xRes += xR + "\n" 26 | xMat += xM + "\n" 27 | 28 | yR, yM = splitEq(data[i + 1], d, e, f) 29 | yRes += yR + "\n" 30 | yMat += yM + "\n" 31 | 32 | print ("xLeft") 33 | print (xMat) 34 | print ("xRight") 35 | print (xRes) 36 | 37 | print ("yLeft") 38 | print (yMat) 39 | 40 | print ("yRight") 41 | print (yRes) 42 | 43 | -------------------------------------------------------------------------------- /OpenRoads/Notes/matFromPts.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | # (x,y,z) -> xp,yp 3 | # (x - xo) / z = xp 4 | # (y - yo) / z = yp 5 | 6 | #Constants x/z 1.0 / z 7 | 8 | # Solving gets us nz and ox * nz 9 | # ox = ox * nz / nz 10 | 11 | def parsePt(pt): 12 | return tuple([float(x) for x in pt.split(',')]) 13 | def parseLine(pts): 14 | return tuple([parsePt(pt) for pt in pts.split(' -> ')]) 15 | 16 | data = open('RenderingPts.txt', 'r').readlines() 17 | pts = [parseLine(ln) for ln in data] 18 | 19 | xrs = [] 20 | xls = [] 21 | 22 | yrs = [] 23 | yls = [] 24 | for (x, y, z), (xp, yp) in pts: 25 | xrs.append([x / z, 1.0 / z]) 26 | yrs.append([y / z, 1.0 / z]) 27 | xls.append(xp) 28 | yls.append(yp) 29 | 30 | resx = np.linalg.lstsq(xrs, xls)[0] 31 | resy = np.linalg.lstsq(yrs, yls)[0] 32 | 33 | nzx = resx[0] 34 | ox = resx[1] / nzx 35 | nzy = resy[0] 36 | oy = resy[1] / nzy 37 | 38 | for (x, y, z), (xp, yp) in pts: 39 | xp2 = (x + ox) * nzx / z 40 | yp2 = (y + oy) * nzy / z 41 | xe = xp2 - xp 42 | ye = yp2 - yp 43 | print("Error: {0} from {1} + {2}".format(abs(xe) + abs(ye), xe, ye)) 44 | 45 | print("OX: {0}, NZX: {1}".format(ox, nzx)) 46 | print("OY: {0}, NZY: {1}".format(oy, nzy)) -------------------------------------------------------------------------------- /OpenRoads/Notes/sound.txt: -------------------------------------------------------------------------------- 1 | createBuffer() 2 | getChannelData(0).set 3 | -------------------------------------------------------------------------------- /OpenRoads/Notes/sub_5D4E.txt: -------------------------------------------------------------------------------- 1 | ax = arg_6 2 | if (arg_6 != 0) { 3 | ax = arg_0; 4 | dx = arg_2; 5 | bx = arg_4; 6 | cx = arg_6; 7 | 8 | shrunk20 = arg_2:arg_0 >> numbits(arg6); 9 | shrunk64 = arg_6:arg_4 >> numbits(arg6); 10 | 11 | ratio = shrunk20 / shrunk64; 12 | dx:cx = (shrunk20 / shrunk64) * arg_6; 13 | dx:ax = arg_4 * ratio; 14 | 15 | dx += cx; 16 | 17 | if (overflowed || dx > arg_2 || (dx == arg_2 && ax <= arg_0)) { 18 | ratio--; 19 | } 20 | 21 | return 0:ratio 22 | } else if (arg_6 == 0) { 23 | return (arg_2 / arg_4):(arg_0 / arg_4) //DX:AX 24 | } -------------------------------------------------------------------------------- /OpenRoads/Plz ReadMe.txt: -------------------------------------------------------------------------------- 1 | Thank you for downloading SkyRoads VR, a modern VR engine for the classic game SkyRoads http://www.bluemoon.ee/history/skyroads/ 2 | Try to drive to the end of a track and through the tunnel. Don't fall, crash, or touch pink tiles! 3 | http://www.openroadsgame.com/ 4 | https://github.com/anprogrammer/OpenRoads 5 | CrazyNorman@gmail.com 6 | 7 | Be sure to set your Rift to Extended Mode. I'll add Direct Mode support once some Win8/AMD/OpenGL issues are worked out. If the game appears on your monitor instead of your Rift, press F9 to change displays. Be sure to have the Rift set as your primary display device or else you may encounter unpleasent judder. 8 | 9 | Controls: 10 | You can use either an X-Box 360 controller or a keyboard. Other game-pads may work, I haven't tested them. 11 | Keyboard: 12 | Arrow Keys, WASD -- Turn/Speed-up/Slow down 13 | Spacebar to Jump 14 | Escape to Exit/Go-Back 15 | 'r' to reset Rift orientation 16 | F9 to change displays (restarts game) 17 | X-Box 360 Controller: 18 | Use any joystick, triggers, or d-pad to turn, slow-down, speed-up 19 | A to jump/enter a menu 20 | B to exit 21 | X to reset Rift orientation 22 | 23 | Common Issues: 24 | 1. I'm way to close to the dashboard 25 | Be sure to reset your orientation using "X" on a gamepad or 'r' on your keyboard 26 | 2. I get a missing DLL error. 27 | Be sure to install the x86/32-bit version of the Visual C++ Redistributable Packages for Visual Studio 2013 from http://www.microsoft.com/en-us/download/details.aspx?id=40784 28 | 3. I have no sound 29 | Open the "Manage Audio Devices" screen (can be accessed via Start Menu or right-clicking the speaker icon in the System Tray), and verify that your headphones are set as the "Default Device". If setting them as the "Default Device" does not resolve the issue please e-mail me with a screenshot of your audio devices at 30 | CrazyNorman@gmail.com. I'm still trying to track down some audio issues. -------------------------------------------------------------------------------- /OpenRoads/Shaders/basic_2d.fs: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision highp float; 3 | #endif 4 | 5 | uniform sampler2D uSampler; 6 | uniform float uAlpha; 7 | uniform float uBrightness; 8 | 9 | varying vec2 vTexCoord; 10 | 11 | void main(void) { 12 | gl_FragColor = texture2D(uSampler, vTexCoord) * vec4(uBrightness, uBrightness, uBrightness, uAlpha); 13 | } -------------------------------------------------------------------------------- /OpenRoads/Shaders/basic_2d.vs: -------------------------------------------------------------------------------- 1 | attribute vec2 aPos; 2 | varying vec2 vTexCoord; 3 | 4 | uniform vec3 uPos; 5 | uniform vec2 uSize, uLow, uHigh, vLow, vHigh; 6 | uniform mat4 uViewMatrix; 7 | 8 | void main(void) { 9 | vTexCoord = aPos.x * (uHigh - uLow) + uLow + aPos.y * (vHigh - vLow) + vLow; 10 | vec2 screenPos = aPos * uSize + uPos.xy; 11 | vec4 nPos = uViewMatrix * vec4(uPos, 1.0); 12 | 13 | vec2 percentPos = screenPos / vec2(320.0, 200.0); 14 | gl_Position = vec4((percentPos * 2.0 - 1.0) * vec2(1.0, -1.0), 2.0 / 20.0, 1.0); 15 | } 16 | -------------------------------------------------------------------------------- /OpenRoads/Shaders/color_3d.fs: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision highp float; 3 | #endif 4 | 5 | varying vec3 vColor; 6 | 7 | void main(void) { 8 | gl_FragColor = vec4(vColor, 1.0); 9 | } -------------------------------------------------------------------------------- /OpenRoads/Shaders/color_3d.vs: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision highp float; 3 | #endif 4 | 5 | attribute vec3 aPos; 6 | attribute vec3 aColor; 7 | attribute vec2 aTexCoord; 8 | 9 | varying vec3 vColor; 10 | 11 | uniform mat4 uViewMatrix; 12 | void main(void) { 13 | vec4 pos = uViewMatrix * vec4(aPos + vec3(0.0, 0.0, 1.0 * 46.0), 1.0); 14 | //sy = (80.0 - X) * nz / z 15 | vColor = aColor; 16 | float z = -(pos.z) / 46.0; 17 | 18 | float x = aPos.x; 19 | float y = aPos.y; 20 | 21 | float targetX = x; 22 | float targetY = (80.0 - y) + 102.0; 23 | float matchZ = 3.0; 24 | 25 | float farX = x / 46.0; 26 | float farY = 32.0 + (80.0 - y) / 46.0; 27 | 28 | /* 29 | float zpF = 1.0 - (z - matchZ) / (farZ - matchZ); 30 | float zp = 1.0 - pow(zpF, 2.4018172794575); 31 | float xp = (farX - targetX) * zp + targetX; 32 | float yp = (farY - targetY) * zp + targetY; 33 | */ 34 | 35 | float zPercent = (z - 1.0) / 9.0; 36 | /* 37 | float zp = 91.59466959 * pow(zPercent, 9.0) - 305.4138054 * pow(zPercent, 8.0) + 305.7508309 * pow(zPercent, 7.0) + 73.07343228 * pow(zPercent, 6.0) - 38 | 391.7440574 * pow(zPercent, 5.0) + 351.6411708 * pow(zPercent, 4.0) - 165.0705506 * pow(zPercent, 3.0) + 49.44913238 * pow(zPercent, 2.0) - 11.08081692 * zPercent + 1.79997551; 39 | */ 40 | float zp = max(-0.02, 1.707075344*exp(-4.119718377*zPercent) - 0.08); 41 | zp = 1.0 - zp; 42 | float xp = (farX - targetX) * zp + targetX; 43 | float yp = (farY - targetY) * zp + targetY; 44 | 45 | gl_Position = vec4(xp / 160.0, -(yp - 100.0) / 100.0, z / 20.0, 1.0); 46 | } 47 | -------------------------------------------------------------------------------- /OpenRoads/Shaders/sprite_3d.fs: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision highp float; 3 | #endif 4 | 5 | 6 | uniform sampler2D uSampler; 7 | 8 | varying vec3 vColor; 9 | varying vec2 vTexCoord; 10 | 11 | void main(void) { 12 | gl_FragColor = texture2D(uSampler, vTexCoord); 13 | } -------------------------------------------------------------------------------- /OpenRoads/Shaders/sprite_3d.vs: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision highp float; 3 | #endif 4 | 5 | attribute vec2 aPos; 6 | attribute vec3 aColor; 7 | attribute vec2 aTexCoord; 8 | 9 | varying vec3 vColor; 10 | varying vec2 vTexCoord; 11 | 12 | uniform vec3 uPos; 13 | uniform vec2 uSize, uLow, uHigh, vLow, vHigh; 14 | 15 | uniform mat4 uViewMatrix; 16 | uniform mat4 uModelMatrix; 17 | uniform mat4 uProjectionMatrix; 18 | 19 | void main(void) { 20 | vec2 screenPos = (vec2(1.0, -1.0) * aPos) * uSize + uPos.xy * vec2(1.0, -1.0) - vec2(160.0, -102.0 - 80.0); 21 | 22 | vec4 res = uProjectionMatrix * uViewMatrix * uModelMatrix * vec4(screenPos.xy, uPos.z, 1.0); 23 | gl_Position = res; 24 | vColor = aColor; 25 | vTexCoord = aPos.x * (uHigh - uLow) + uLow + aPos.y * (vHigh - vLow) + vLow; 26 | } 27 | -------------------------------------------------------------------------------- /OpenRoads/Shaders/texture_p3d.fs: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision highp float; 3 | #endif 4 | 5 | 6 | uniform sampler2D uSampler; 7 | 8 | varying vec3 vColor; 9 | varying vec2 vTexCoord; 10 | 11 | void main(void) { 12 | gl_FragColor = texture2D(uSampler, vTexCoord) * vec4(vColor, 1.0); 13 | } -------------------------------------------------------------------------------- /OpenRoads/Shaders/texture_p3d.vs: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision highp float; 3 | #endif 4 | 5 | attribute vec3 aPos; 6 | attribute vec3 aColor; 7 | attribute vec2 aTexCoord; 8 | 9 | varying vec3 vColor; 10 | varying vec2 vTexCoord; 11 | 12 | uniform mat4 uViewMatrix; 13 | uniform mat4 uModelMatrix; 14 | uniform mat4 uProjectionMatrix; 15 | uniform float uScale; 16 | 17 | void main(void) { 18 | gl_Position = uProjectionMatrix * uViewMatrix * uModelMatrix * vec4(aPos.xyz, 1.0); 19 | vColor = aColor; 20 | vTexCoord = aTexCoord.xy; 21 | } 22 | -------------------------------------------------------------------------------- /OpenRoads/Shaders/title_2d.fs: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision highp float; 3 | #endif 4 | 5 | uniform sampler2D uSampler; 6 | uniform float uAlpha; 7 | uniform float uBrightness; 8 | uniform vec2 uSize; 9 | 10 | varying vec2 vTexCoord; 11 | 12 | void main(void) { 13 | float direction = uBrightness; 14 | float totalProgress = uAlpha; 15 | 16 | vec4 color = texture2D(uSampler, vTexCoord); 17 | 18 | if (totalProgress < 0.29) { 19 | float pixY = uSize.y * vTexCoord.y; 20 | float row = mod(pixY, 2.0); 21 | float alphaMul = ((row < 1.0) == (uBrightness < 0.0)) ? 1.0 : 0.0; 22 | 23 | float avg = (color.r + color.g + color.b) / 3.0; 24 | gl_FragColor = vec4(avg * 0.5, avg * 0.75, avg, color.a * alphaMul); 25 | } else if (totalProgress < 0.43) { 26 | float fadeWhiteProgress = (totalProgress - 0.29) / 0.14; 27 | float avg = (color.r + color.g + color.b) / 3.0; 28 | gl_FragColor = vec4(avg * 0.5 + fadeWhiteProgress, avg * 0.75 + fadeWhiteProgress, avg + fadeWhiteProgress, color.a); 29 | } else if (totalProgress < 1.0) { 30 | float fadeWhiteProgress = 2.0 * (1.0 - (totalProgress - 0.43) / 0.57); 31 | gl_FragColor = vec4(color.r + fadeWhiteProgress, color.g + fadeWhiteProgress, color.b + fadeWhiteProgress, color.a); 32 | } else { 33 | gl_FragColor = color; 34 | } 35 | } -------------------------------------------------------------------------------- /OpenRoads/Shaders/title_2d.vs: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision highp float; 3 | #endif 4 | 5 | attribute vec2 aPos; 6 | varying vec2 vTexCoord; 7 | 8 | uniform vec3 uPos; 9 | uniform vec2 uSize; 10 | uniform float uAlpha; 11 | uniform float uBrightness; 12 | 13 | uniform vec2 uLow, uHigh, vLow, vHigh; 14 | 15 | void main(void) { 16 | float direction = uBrightness; 17 | float totalProgress = uAlpha; 18 | float animProgress = clamp(totalProgress / 0.29, 0.0, 1.0); 19 | 20 | float endX = uPos.x; 21 | float startX = (uBrightness < 0.0) ? -uSize.x : 320.0; 22 | 23 | vTexCoord = aPos.x * (uHigh - uLow) + uLow + aPos.y * (vHigh - vLow) + vLow; 24 | vec2 screenPos = aPos * uSize + vec2((endX - startX) * animProgress + startX, uPos.y); 25 | vec2 percentPos = screenPos / vec2(320.0, 200.0); 26 | gl_Position = vec4((percentPos * 2.0 - 1.0) * vec2(1.0, -1.0), uPos.z / 20.0, 1.0); 27 | } 28 | -------------------------------------------------------------------------------- /OpenRoads/app.css: -------------------------------------------------------------------------------- 1 | html { 2 | margin: 0; 3 | padding: 0; 4 | width: 100%; 5 | height: 100%; 6 | } 7 | 8 | body { 9 | font-family: 'Segoe UI', sans-serif; 10 | margin: 0; 11 | padding: 0; 12 | overflow: hidden; 13 | width: 100%; 14 | height: 100%; 15 | background-color: #000000; 16 | } 17 | 18 | div#loading { 19 | color: #FFFFFF; 20 | font: 48px arial bold; 21 | text-align: center; 22 | vertical-align: middle; 23 | position: absolute; 24 | top: 50%; 25 | left: 0; 26 | width: 100%; 27 | margin-top: -48px; 28 | } 29 | 30 | canvas { 31 | position: absolute; 32 | border: none; 33 | left: 0; 34 | top: 0; 35 | } 36 | 37 | span { 38 | font-style: italic; 39 | } 40 | 41 | .debugTable { 42 | padding: 0; 43 | margin: 0; 44 | border-spacing: 0; 45 | } 46 | 47 | .debugTable tr { 48 | margin: 0; 49 | padding: 0; 50 | } 51 | .debugTable td { 52 | padding: 0; 53 | margin: 0; 54 | margin: 1px solid black; 55 | } 56 | 57 | .debugTable div { 58 | margin: 0; 59 | } 60 | 61 | div#links { 62 | position: absolute; 63 | bottom: 0; 64 | right: 0; 65 | border-bottom: none; 66 | border-right: none; 67 | } 68 | 69 | div#vr { 70 | position: absolute; 71 | top: 0; 72 | left: 0; 73 | border-top: none; 74 | border-left: none; 75 | } 76 | 77 | div.error { 78 | position: absolute; 79 | width: 400px; 80 | left: 50%; 81 | margin: 0 -200px; 82 | top: 0; 83 | border: 1px solid #FF7777; 84 | color: #FF7777; 85 | } 86 | 87 | div.info_pane { 88 | color: #FFFFFF; 89 | padding: 5px; 90 | z-index: 5; 91 | font-size: 8pt; 92 | text-align: left; 93 | background-color: #000000; 94 | border: 1px solid #7777FF; 95 | border-left: 1px solid #7777FF; 96 | } 97 | 98 | img#oc_logo { 99 | display: block; 100 | margin: 0 auto; 101 | padding-top:3px; 102 | } 103 | 104 | a { 105 | color: #7777FF; 106 | font-weight: bold; 107 | text-decoration: none; 108 | border-style: none; 109 | } 110 | 111 | a:hover { 112 | color: #FFFFFF; 113 | } 114 | 115 | a.closediv { 116 | color: #FF7777; 117 | } 118 | 119 | h1, h2, li { 120 | color: #FFFFFF; 121 | } 122 | 123 | p { 124 | color: #FFFFFF; 125 | } 126 | 127 | ol { 128 | display: inline-block; 129 | text-align: left; 130 | } 131 | 132 | div.qa { 133 | text-align: left; 134 | width: 800px; 135 | margin: 5px auto; 136 | border: 1px solid #777777; 137 | padding: 5px; 138 | } 139 | 140 | div.qa span { 141 | font-weight: bold; 142 | } 143 | 144 | div.qa div.question, div.qa div.question p { 145 | color: #FF7777; 146 | } 147 | 148 | div.qa div.answer, div.qa div.answer p { 149 | color: #7777FF; 150 | } -------------------------------------------------------------------------------- /OpenRoads/faq.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | OpenRoads 7 | 8 | 9 | 10 |
11 | (X)
12 | Back to the Game 13 |
14 |

F.A.Q.

15 |
16 |
17 |

Q: What is the Jump-o Master?

18 |
19 |
20 |

21 | A: The Jump-o Master is a simple AI, part of your ship, which assists you on your mission. If it detects that you are going to fall into nothingness, it can instantly alter your speed 22 | so that you don't undershoot or overshoot your landing. 23 |

24 |

25 | It has limitations in how much it can alter your speed, and also won't save you from crashing into a block or tunnel. 26 |

27 |
28 |
29 |
30 |
31 |

Q: Why won't my X-Box 360 controller work?

32 |
33 |
34 |

35 | A: As a security feature, some browsers won't allow us to use your X-Box 360 controller until you press the "A" button to enable it. 36 |

37 |
38 |
39 |
40 |
41 |

Q: I found a bug. How do I report it?

42 |
43 |
44 |

45 | A: Feel free to log an issue on the OpenRoads GitHub. 46 | I will do my best to address it. 47 |

48 |

49 | Keep in mind that OpenRoads is open source, so if you are an included developer you can always fix the bug and submit a pull request. 50 |

51 |
52 |
53 |
54 |
55 |

Q: I'd like to make a donation.

56 |
57 |
58 |

59 | A: You caught me, this is neither a question nor has anyone every asked it. 60 |

61 |

Consider donating to the DosBox project instead. It's a great project run by great people (pretty much for free), 62 | and was absolutely integral to the creation of OpenRoads.

63 |
64 |
65 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /OpenRoads/index.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | OpenRoads 7 | 8 | 9 | 10 | 11 | 12 | 13 |
Loading
14 | 15 |
16 | (X)
17 | Need more challenge?
18 | SkyRoads XMas Edition 19 |

20 | Have a question?
21 | Check Out our F.A.Q. 22 |

23 | Have a DK1 or DK2?
24 | VR! VR! VR!
25 | 26 | Play in VR with Oculus Rift
27 |
28 |
29 | 36 | 43 | 59 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /OpenRoads/physics_test.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | OpenRoads 7 | 8 | 9 | 10 | 11 | 12 | 13 |
Loading
14 | 15 |
16 | (X)
17 | Need more challenge?
18 | SkyRoads XMas Edition 19 |

20 | Have a question?
21 | Check Out our F.A.Q. 22 |

23 | Have a DK1 or DK2?
24 | 25 | Play in VR with Oculus Rift
26 | 27 |
28 |
29 | 36 | 43 | 59 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /OpenRoads/update_glfw.bat: -------------------------------------------------------------------------------- 1 | PUSHD 2 | cd Node 3 | cd node_modules\node-webgl-ovr 4 | cmd /C "npm install F:\Documents\GitHub\node-glfw-ovr" 5 | cd node_modules\node-glfw-ovr\build\Release\ 6 | copy F:\Libs\AntTweakBar\lib\AntTweakBar.dll . 7 | copy F:\Libs\glfw-3.0.4\src\Release\glfw3.dll . 8 | POPD -------------------------------------------------------------------------------- /OpenRoads/update_node_deps.bat: -------------------------------------------------------------------------------- 1 | PUSHD 2 | cd Node 3 | cmd /C "npm install F:\Documents\GitHub\node-webgl-ovr" 4 | cd node_modules\node-webgl-ovr 5 | copy F:\Libs\FreeImage\Release\*.dll build\Release 6 | cmd /C "npm install F:\Documents\GitHub\node-glfw-ovr" 7 | cd node_modules\node-glfw-ovr\build\Release\ 8 | copy F:\Libs\AntTweakBar\lib\AntTweakBar.dll . 9 | copy F:\Libs\glfw-3.0.4\src\Release\glfw3.dll . 10 | POPD -------------------------------------------------------------------------------- /OpenRoads/vr.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | OpenRoads 7 | 8 | 9 | 10 |
11 | (X)
12 | Back to the Game 13 |
14 |

Play SkyRoads in Virtual Reality

15 |

16 | OpenRoads supports the Oculus Rift DK2 and DK1 using NodeJS. Download the premade bundle for Windows (32-bit and 64-bit) to try it out. 17 | Linux and OSX support are planned once the Oculus SDK supports them. 18 |

19 | 20 |
21 | Click Here to Download SkyRoads VR 22 |

How to Play

23 |
    24 |
  1. Download SkyRoads VR
  2. 25 |
  3. Extract the ZIP Archive
  4. 26 |
  5. Install the x86/32-bit Visual C++ Redistributable Packages for Visual Studio 2013 if you do not have them already.
  6. 27 |
  7. Inside your freshly extracted SkyRoadsVR folder, run either Skyroads VR or Skyroads XMas VR
  8. 28 |
  9. Enjoy!
  10. 29 |
30 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /OpenRoadsLib/Libs/GLFW.d.ts: -------------------------------------------------------------------------------- 1 | declare module GLFW { 2 | export class GLFW { 3 | enableHMD(disableVsync: boolean): boolean; 4 | getHMDTargetSize(): number[]; 5 | getHMDFboId(gl: WebGLRenderingContext): number; 6 | getEyeViewAdjust(n: number): number[]; 7 | getEyeViewport(n: number): number[]; 8 | getHeadPosition(n: number): number[]; 9 | getHeadOrientation(n: number): number[]; 10 | getProjectionMatrix(n: number): number[]; 11 | getJoystickAxes(): string; 12 | getJoystickButtons(): string; 13 | startVREye(n: number): void; 14 | endVREye(n: number): void; 15 | isVRSafetyWarningVisible(): boolean; 16 | resetVROrientation(): void; 17 | getMonitorCount(): number; 18 | destroyWindow(window: HTMLCanvasElement): void; 19 | } 20 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Configurations/NodeAudio.ts: -------------------------------------------------------------------------------- 1 | module Configurations { 2 | export function runNodeAudio() { 3 | var manager = new Managers.StreamManager(new Stores.LocalFileProvider(), 'Data/'); 4 | var managers = new Managers.ManagerSet(manager, null); 5 | 6 | manager.loadMultiple(['Data/MUZAX.LZS']).done(() => { 7 | var audioProvider = new Sounds.PortAudioAudioProvider(); 8 | var opl = new Music.OPL(audioProvider); 9 | var player = new Music.Player(opl, managers); 10 | opl.setSource(player); 11 | 12 | 13 | var server = new Sounds.ChildProcessAudioServer(audioProvider, player); 14 | }); 15 | } 16 | } 17 | 18 | 19 | declare var exports: any; 20 | if (typeof exports !== 'undefined') { 21 | exports.Configurations = { 22 | runNode: Configurations.runNode, 23 | runNodeAudio: Configurations.runNodeAudio 24 | }; 25 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Controls/CombinedControlSource.ts: -------------------------------------------------------------------------------- 1 | module Controls { 2 | export class CombinedControlSource implements ControlSource { 3 | private sources: Controls.ControlSource[] = []; 4 | 5 | public addSource(src: Controls.ControlSource) { 6 | this.sources.push(src); 7 | } 8 | 9 | private foldVal(gvFunc: (src: ControlSource) => T) { 10 | var val: T = null; 11 | for (var i = 0; i < this.sources.length; i++) { 12 | val = val || gvFunc(this.sources[i]); 13 | } 14 | return val; 15 | } 16 | 17 | update(): void { 18 | for (var i = 0; i < this.sources.length; i++) { 19 | this.sources[i].update(); 20 | } 21 | } 22 | 23 | getTurnAmount(): number { 24 | return this.foldVal((src) => src.getTurnAmount()); 25 | } 26 | 27 | getAccelAmount(): number { 28 | return this.foldVal((src) => src.getAccelAmount()); 29 | } 30 | 31 | getJump(): boolean { 32 | return this.foldVal((src) => src.getJump()); 33 | } 34 | 35 | getLeft(): boolean { 36 | return this.foldVal((src) => src.getLeft()); 37 | } 38 | 39 | getRight(): boolean { 40 | return this.foldVal((src) => src.getRight()); 41 | } 42 | 43 | getUp(): boolean { 44 | return this.foldVal((src) => src.getUp()); 45 | } 46 | 47 | getDown(): boolean { 48 | return this.foldVal((src) => src.getDown()); 49 | } 50 | 51 | getEnter(): boolean { 52 | return this.foldVal((src) => src.getEnter()); 53 | } 54 | 55 | getExit(): boolean { 56 | return this.foldVal((src) => src.getExit()); 57 | } 58 | 59 | getSwitchMonitor(): boolean { 60 | return this.foldVal((src) => src.getSwitchMonitor()); 61 | } 62 | 63 | getResetOrientation(): boolean { 64 | return this.foldVal((src) => src.getResetOrientation()); 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Controls/ConditionWatcher.ts: -------------------------------------------------------------------------------- 1 | module Controls { 2 | export class ConditionWatcher { 3 | private enabled: boolean = false; 4 | private repeating: boolean = true; 5 | private heldTime: number = 0; 6 | private repeatRate: number; 7 | private repeatWait: number; 8 | private keyCode: number; 9 | private condition: () => boolean; 10 | private cb: Function; 11 | 12 | constructor(cond: () => boolean, cb: Function) { 13 | this.repeatWait = 0.5; 14 | this.repeatRate = 0.1; 15 | this.condition = cond; 16 | this.cb = cb; 17 | } 18 | 19 | public update(time: Engine.FrameTimeInfo) { 20 | if (this.condition()) { 21 | if (!this.enabled) { 22 | this.enabled = true; 23 | this.repeating = false; 24 | this.heldTime = 0; 25 | this.cb(); 26 | } else { 27 | this.heldTime += time.getPhysicsStep(); 28 | var interval = this.repeating ? this.repeatRate : this.repeatWait; 29 | 30 | if (this.heldTime >= interval) { 31 | this.heldTime -= interval; 32 | this.cb(); 33 | this.repeating = true; 34 | } 35 | } 36 | } else { 37 | this.enabled = false; 38 | } 39 | } 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Controls/ControlSource.ts: -------------------------------------------------------------------------------- 1 | module Controls { 2 | export interface ControlSource { 3 | update(): void; 4 | 5 | getTurnAmount(): number; 6 | getAccelAmount(): number; 7 | getJump(): boolean; 8 | 9 | getLeft(): boolean; 10 | getRight(): boolean; 11 | getUp(): boolean; 12 | getDown(): boolean; 13 | 14 | getEnter(): boolean; 15 | getExit(): boolean; 16 | 17 | getSwitchMonitor(): boolean; 18 | 19 | getResetOrientation(): boolean; 20 | } 21 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Controls/GLFWJoystick.ts: -------------------------------------------------------------------------------- 1 | module Controls { 2 | export class GLFWJoystick implements Joystick { 3 | private glfw: GLFW.GLFW; 4 | private buttons: boolean[]; 5 | private axis: number[]; 6 | 7 | constructor(glfw: GLFW.GLFW) { 8 | this.glfw = glfw; 9 | } 10 | 11 | update(): void { 12 | this.buttons = this.glfw.getJoystickButtons().split(',').map(function (b) { 13 | return b === "1"; 14 | }); 15 | 16 | this.axis = this.glfw.getJoystickAxes().split(',').map(function (b) { 17 | return parseFloat(b); 18 | }); 19 | } 20 | 21 | getButton(n: number): boolean { 22 | return n < this.buttons.length ? this.buttons[n] : false; 23 | } 24 | 25 | getAxis(n: number): number { 26 | return n < this.axis.length ? this.axis[n] : 0.0; 27 | } 28 | 29 | getTurnChannels(): number[] { 30 | return [0, 4]; 31 | } 32 | getLeftButtons(): number[] { 33 | return [4, 13]; 34 | } 35 | getRightButtons(): number[] { 36 | return [5, 11]; 37 | } 38 | 39 | getAccelChannels(): number[] { 40 | return [1, 2, 3]; 41 | } 42 | getFasterButtons(): number[] { 43 | return [10]; 44 | } 45 | getSlowerButtons(): number[] { 46 | return [12]; 47 | } 48 | 49 | getJumpButtons(): number[] { 50 | return [0]; 51 | } 52 | getEnterButtons(): number[] { 53 | return [0, 7]; 54 | } 55 | 56 | getExitButtons(): number[] { 57 | return [1, 6]; 58 | } 59 | 60 | getResetOrientationButtons(): number[] { 61 | return [2]; 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Controls/Joystick.ts: -------------------------------------------------------------------------------- 1 | module Controls { 2 | export interface Joystick { 3 | update(): void; 4 | getButton(n: number): boolean; 5 | getAxis(n: number): number; 6 | 7 | getTurnChannels(): number[]; 8 | getLeftButtons(): number[]; 9 | getRightButtons(): number[]; 10 | 11 | getAccelChannels(): number[]; 12 | getFasterButtons(): number[]; 13 | getSlowerButtons(): number[]; 14 | 15 | getJumpButtons(): number[]; 16 | getEnterButtons(): number[]; 17 | getExitButtons(): number[]; 18 | 19 | getResetOrientationButtons(): number[]; 20 | } 21 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Controls/JoystickControlSource.ts: -------------------------------------------------------------------------------- 1 | module Controls { 2 | export class JoystickControlSource implements ControlSource { 3 | private deadZone = 0.3; 4 | private joystick: Joystick; 5 | 6 | constructor(stick: Joystick) { 7 | this.joystick = stick; 8 | } 9 | 10 | private channelWithDeadZone(n: number): number { 11 | var v = this.joystick.getAxis(n); 12 | if (Math.abs(v) < this.deadZone) { 13 | return 0.0; 14 | } else { 15 | return v; 16 | } 17 | } 18 | 19 | private buttonAsChannel(n: number, v: number) { 20 | return this.joystick.getButton(n) ? v : 0.0; 21 | } 22 | 23 | private largest(ns: number[]) { 24 | var v = 0.0; 25 | for (var i = 0; i < ns.length; i++) { 26 | if (Math.abs(ns[i]) > Math.abs(v)) { 27 | v = ns[i]; 28 | } 29 | } 30 | 31 | return v; 32 | } 33 | 34 | private getValuesFromChannelsAndButtons(channels: number[], buttonsNeg: number[], buttonsPos: number[]) { 35 | var values: number[] = []; 36 | for (var i = 0; i < channels.length; i++) { 37 | values.push(this.channelWithDeadZone(channels[i])); 38 | } 39 | for (var i = 0; i < buttonsNeg.length; i++) { 40 | values.push(this.buttonAsChannel(buttonsNeg[i], -1)); 41 | } 42 | for (var i = 0; i < buttonsPos.length; i++) { 43 | values.push(this.buttonAsChannel(buttonsPos[i], 1)); 44 | } 45 | return this.largest(values); 46 | } 47 | 48 | public update(): void { 49 | this.joystick.update(); 50 | } 51 | 52 | public getTurnAmount(): number { 53 | return this.getValuesFromChannelsAndButtons(this.joystick.getTurnChannels(), this.joystick.getLeftButtons(), this.joystick.getRightButtons()); 54 | } 55 | 56 | public getAccelAmount(): number { 57 | return -this.getValuesFromChannelsAndButtons(this.joystick.getAccelChannels(), this.joystick.getFasterButtons(), this.joystick.getSlowerButtons()); 58 | } 59 | 60 | public getJump(): boolean { 61 | return this.getValuesFromChannelsAndButtons([], [], this.joystick.getJumpButtons()) > 0.5; 62 | } 63 | 64 | public getLeft(): boolean { 65 | return this.getTurnAmount() < -0.5; 66 | } 67 | 68 | public getRight(): boolean { 69 | return this.getTurnAmount() > 0.5; 70 | } 71 | 72 | public getUp(): boolean { 73 | return this.getAccelAmount() > 0.5; 74 | } 75 | 76 | public getDown(): boolean { 77 | return this.getAccelAmount() < -0.5; 78 | } 79 | 80 | public getEnter(): boolean { 81 | return this.getValuesFromChannelsAndButtons([], [], this.joystick.getEnterButtons()) > 0.5; 82 | } 83 | 84 | public getSwitchMonitor(): boolean { 85 | return false; 86 | } 87 | 88 | public getExit(): boolean { 89 | return this.getValuesFromChannelsAndButtons([], [], this.joystick.getExitButtons()) > 0.5; 90 | } 91 | 92 | public getResetOrientation(): boolean { 93 | return this.getValuesFromChannelsAndButtons([], [], this.joystick.getResetOrientationButtons()) > 0.5; 94 | } 95 | } 96 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Controls/KeyboardControlSource.ts: -------------------------------------------------------------------------------- 1 | module Controls { 2 | export class KeyboardControlSource implements ControlSource { 3 | private kbd: Engine.KeyboardManager; 4 | constructor(kbd: Engine.KeyboardManager) { 5 | this.kbd = kbd; 6 | } 7 | 8 | public update(): void { } 9 | 10 | public getTurnAmount(): number { 11 | if (this.getLeft()) { 12 | return -1; 13 | } else if (this.getRight()) { 14 | return 1; 15 | } else { 16 | return 0; 17 | } 18 | } 19 | 20 | public getAccelAmount(): number { 21 | if (this.getUp()) { 22 | return 1; 23 | } else if (this.getDown()) { 24 | return -1; 25 | } else { 26 | return 0; 27 | } 28 | } 29 | 30 | public getJump(): boolean { 31 | return this.kbd.isDown(32); 32 | } 33 | 34 | public getLeft(): boolean { 35 | return this.kbd.isDown(37) || this.kbd.isDown(65); 36 | } 37 | 38 | public getRight(): boolean { 39 | return this.kbd.isDown(39) || this.kbd.isDown(68); 40 | } 41 | public getUp(): boolean { 42 | return this.kbd.isDown(38) || this.kbd.isDown(87); 43 | } 44 | 45 | public getDown(): boolean { 46 | return this.kbd.isDown(40) || this.kbd.isDown(83); 47 | } 48 | 49 | public getEnter(): boolean { 50 | return this.kbd.isDown(32) || this.kbd.isDown(13); 51 | } 52 | 53 | public getExit(): boolean { 54 | return this.kbd.isDown(27); 55 | } 56 | 57 | public getSwitchMonitor(): boolean { 58 | return this.kbd.isDown(123); 59 | } 60 | 61 | public getResetOrientation(): boolean { 62 | return this.kbd.isDown(82); 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Controls/NavigatorJoystick.ts: -------------------------------------------------------------------------------- 1 | module Controls { 2 | export declare class Gamepad { 3 | public buttons: { pressed: boolean }[]; 4 | public axes: number[]; 5 | } 6 | 7 | export declare class GamepadProvider { 8 | public getGamepads(): Gamepad[]; 9 | } 10 | 11 | export class NavigatorJoystick implements Joystick { 12 | private provider: GamepadProvider; 13 | private gamepad: Gamepad = null; 14 | 15 | constructor(provider: GamepadProvider) { 16 | this.provider = provider; 17 | } 18 | 19 | public update(): void { 20 | var pads = this.provider.getGamepads ? this.provider.getGamepads() : []; 21 | if (pads.length > 0 && pads[0]) { 22 | this.gamepad = pads[0]; 23 | } else { 24 | this.gamepad = null; 25 | } 26 | } 27 | 28 | public getButton(n: number): boolean { 29 | return this.gamepad !== null && n < this.gamepad.buttons.length ? this.gamepad.buttons[n].pressed : false; 30 | } 31 | 32 | public getAxis(n: number): number { 33 | return this.gamepad !== null && n < this.gamepad.axes.length ? this.gamepad.axes[n] : 0; 34 | } 35 | 36 | getTurnChannels(): number[]{ 37 | return [0, 2]; 38 | } 39 | 40 | getLeftButtons(): number[]{ 41 | return [4, 14]; 42 | } 43 | 44 | getRightButtons(): number[]{ 45 | return [5, 15]; 46 | } 47 | 48 | getAccelChannels(): number[]{ 49 | return [1, 3]; 50 | } 51 | 52 | getFasterButtons(): number[]{ 53 | return [7, 12]; 54 | } 55 | 56 | getSlowerButtons(): number[]{ 57 | return [6, 13]; 58 | } 59 | 60 | getJumpButtons(): number[] { 61 | return [0]; 62 | } 63 | 64 | getEnterButtons(): number[]{ 65 | return [0, 9]; 66 | } 67 | 68 | getExitButtons(): number[]{ 69 | return [1, 8]; 70 | } 71 | 72 | getResetOrientationButtons(): number[]{ 73 | return [2]; 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Data/ArrayBitStream.js: -------------------------------------------------------------------------------- 1 | var Data; 2 | (function (Data) { 3 | var ArrayBitStream = (function () { 4 | function ArrayBitStream(data) { 5 | this.data = data; 6 | this.idx = 0; 7 | } 8 | ArrayBitStream.prototype.getBit = function () { 9 | var idx = this.idx; 10 | this.idx++; 11 | 12 | var byteIdx = Math.floor(idx / 8), bitIdx = 7 - (idx % 8); 13 | 14 | return (this.data[byteIdx] & (1 << bitIdx)) >> bitIdx; 15 | }; 16 | 17 | ArrayBitStream.prototype.setPosition = function (idx) { 18 | this.idx = idx; 19 | }; 20 | 21 | ArrayBitStream.prototype.getPosition = function () { 22 | return this.idx; 23 | }; 24 | 25 | ArrayBitStream.prototype.eof = function () { 26 | return this.idx >= (this.data.length * 8); 27 | }; 28 | 29 | ArrayBitStream.prototype.getLength = function () { 30 | return this.data.length * 8; 31 | }; 32 | return ArrayBitStream; 33 | })(); 34 | Data.ArrayBitStream = ArrayBitStream; 35 | })(Data || (Data = {})); 36 | -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Data/ArrayBitStream.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"ArrayBitStream.js","sourceRoot":"","sources":["ArrayBitStream.ts"],"names":["Data","Data.ArrayBitStream","Data.ArrayBitStream.constructor","Data.ArrayBitStream.getBit","Data.ArrayBitStream.setPosition","Data.ArrayBitStream.eof"],"mappings":"AAAA,qCAAqC;AACrC,IAAO,IAAI;AA2BV,CA3BD,UAAO,IAAI;IACPA;QAGIC,wBAAYA,IAAcA;YACtBC,IAAIA,CAACA,IAAIA,GAAGA,IAAIA;YAChBA,IAAIA,CAACA,GAAGA,GAAGA,CAACA;QAChBA,CAACA;QAEDD,kCAAAA;YACIE,IAAIA,GAAGA,GAAGA,IAAIA,CAACA,GAAGA;YAClBA,IAAIA,CAACA,GAAGA,EAAEA;;YAEVA,IAAIA,OAAOA,GAAGA,IAAIA,CAACA,KAAKA,CAACA,GAAGA,GAAGA,CAACA,CAACA,EAC7BA,MAAMA,GAAGA,GAAGA,GAAGA,CAACA;;YAEpBA,OAAOA,CAACA,IAAIA,CAACA,IAAIA,CAACA,OAAOA,CAACA,GAAGA,CAACA,CAACA,IAAIA,MAAMA,CAACA,CAACA,IAAIA,MAAMA;QACzDA,CAACA;;QAEDF,uCAAAA,UAAmBA,GAAWA;YAC1BG,IAAIA,CAACA,GAAGA,GAAGA,GAAGA;QAClBA,CAACA;;QAEDH,+BAAAA;YACII,OAAOA,IAAIA,CAACA,GAAGA,IAAIA,CAACA,IAAIA,CAACA,IAAIA,CAACA,MAAMA,GAAGA,CAACA,CAACA;QAC7CA,CAACA;QACLJ,sBAACA;IAADA,CAACA,IAAAD;IAzBDA,qCAyBCA;AACLA,CAACA,uBAAA"} -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Data/ArrayBitStream.ts: -------------------------------------------------------------------------------- 1 | /// 2 | module Data { 3 | export class ArrayBitStream implements RandomAccessBitStream { 4 | private data: number[]; 5 | private idx: number; 6 | constructor(data: number[]) { 7 | this.data = data; 8 | this.idx = 0; 9 | } 10 | 11 | public getBit(): number { 12 | var idx = this.idx; 13 | this.idx++; 14 | 15 | var byteIdx = Math.floor(idx / 8), 16 | bitIdx = 7 - (idx % 8); 17 | 18 | return (this.data[byteIdx] & (1 << bitIdx)) >> bitIdx; 19 | } 20 | 21 | public setPosition(idx: number) { 22 | this.idx = idx; 23 | } 24 | 25 | public getPosition(): number { 26 | return this.idx; 27 | } 28 | 29 | public eof(): boolean { 30 | return this.idx >= (this.data.length * 8); 31 | } 32 | 33 | public getLength(): number { 34 | return this.data.length * 8; 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Data/ArrayByteStream.js: -------------------------------------------------------------------------------- 1 | /// 2 | var Data; 3 | (function (Data) { 4 | var ArrayByteStream = (function () { 5 | function ArrayByteStream(data) { 6 | this.data = data; 7 | this.idx = 0; 8 | } 9 | ArrayByteStream.prototype.getUint8 = function () { 10 | return this.data[this.idx++]; 11 | }; 12 | 13 | ArrayByteStream.prototype.eof = function () { 14 | return this.idx == this.data.length; 15 | }; 16 | return ArrayByteStream; 17 | })(); 18 | Data.ArrayByteStream = ArrayByteStream; 19 | })(Data || (Data = {})); 20 | //# sourceMappingURL=ArrayByteStream.js.map 21 | -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Data/ArrayByteStream.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"ArrayByteStream.js","sourceRoot":"","sources":["ArrayByteStream.ts"],"names":["Data","Data.ArrayByteStream","Data.ArrayByteStream.constructor","Data.ArrayByteStream.getUint8","Data.ArrayByteStream.eof"],"mappings":"AAAA,sCAAsC;AACtC,IAAO,IAAI;AAiBV,CAjBD,UAAO,IAAI;IACPA;QAGIC,yBAAYA,IAAgBA;YACxBC,IAAIA,CAACA,IAAIA,GAAGA,IAAIA;YAChBA,IAAIA,CAACA,GAAGA,GAAGA,CAACA;QAChBA,CAACA;QAEDD,qCAAAA;YACIE,OAAOA,IAAIA,CAACA,IAAIA,CAACA,IAAIA,CAACA,GAAGA,EAAEA,CAACA;QAChCA,CAACA;;QAEDF,gCAAAA;YACIG,OAAOA,IAAIA,CAACA,GAAGA,IAAIA,IAAIA,CAACA,IAAIA,CAACA,MAAMA;QACvCA,CAACA;QACLH,uBAACA;IAADA,CAACA,IAAAD;IAfDA,uCAeCA;AACLA,CAACA,uBAAA"} -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Data/BinaryReader.js: -------------------------------------------------------------------------------- 1 | var Data; 2 | (function (Data) { 3 | var BinaryReader = (function () { 4 | function BinaryReader(stream) { 5 | this.stream = stream; 6 | } 7 | BinaryReader.prototype.getBit = function () { 8 | return this.stream.getBit(); 9 | }; 10 | 11 | BinaryReader.prototype.getBits = function (n) { 12 | var byte = 0; 13 | for (var i = 0; i < n; i++) { 14 | byte |= this.getBit() * (1 << (n - i - 1)); 15 | } 16 | return byte; 17 | }; 18 | 19 | BinaryReader.prototype.getUint8 = function () { 20 | return this.getBits(8); 21 | }; 22 | 23 | BinaryReader.prototype.getUint16 = function () { 24 | return this.getUint8() | (this.getUint8() << 8); 25 | }; 26 | 27 | BinaryReader.prototype.getUint32 = function () { 28 | return this.getUint16() | (this.getUint16() << 16); 29 | }; 30 | 31 | BinaryReader.prototype.getFixedLengthString = function (len) { 32 | var s = ''; 33 | for (var i = 0; i < len; i++) { 34 | s += String.fromCharCode(this.getUint8()); 35 | } 36 | return s; 37 | }; 38 | 39 | BinaryReader.prototype.eof = function () { 40 | return this.stream.eof(); 41 | }; 42 | return BinaryReader; 43 | })(); 44 | Data.BinaryReader = BinaryReader; 45 | })(Data || (Data = {})); 46 | -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Data/BinaryReader.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"BinaryReader.js","sourceRoot":"","sources":["BinaryReader.ts"],"names":["Data","Data.BinaryReader","Data.BinaryReader.constructor","Data.BinaryReader.getBit","Data.BinaryReader.getBits","Data.BinaryReader.getUint8","Data.BinaryReader.getUint16","Data.BinaryReader.getUint32","Data.BinaryReader.eof"],"mappings":"AAAA,sCAAsC;AACtC,IAAO,IAAI;AAoCV,CApCD,UAAO,IAAI;IACPA;QAGIC,sBAAYA,MAAiBA;YACzBC,IAAIA,CAACA,MAAMA,GAAGA,MAAMA;QACxBA,CAACA;QAEDD,gCAAAA;YACIE,OAAOA,IAAIA,CAACA,MAAMA,CAACA,MAAMA,CAACA,CAACA;QAC/BA,CAACA;;QAEDF,iCAAAA,UAAeA,CAASA;YACpBG,IAAIA,IAAIA,GAAWA,CAACA;YACpBA,KAAKA,IAAIA,CAACA,GAAWA,CAACA,EAAEA,CAACA,GAAGA,CAACA,EAAEA,CAACA,EAAEA,CAAEA;gBAChCA,IAAIA,IAAIA,IAAIA,CAACA,MAAMA,CAACA,CAACA,GAAGA,CAACA,CAACA,IAAIA,CAACA,CAACA;aACnCA;YACDA,OAAOA,IAAIA;QACfA,CAACA;;QAEDH,kCAAAA;YACII,OAAOA,IAAIA,CAACA,OAAOA,CAACA,CAACA,CAACA;QAC1BA,CAACA;;QAEDJ,mCAAAA;YACIK,OAAOA,IAAIA,CAACA,QAAQA,CAACA,CAACA,GAAGA,CAACA,IAAIA,CAACA,QAAQA,CAACA,CAACA,IAAIA,CAACA,CAACA;QACnDA,CAACA;;QAEDL,mCAAAA;YACIM,OAAOA,IAAIA,CAACA,SAASA,CAACA,CAACA,GAAGA,CAACA,IAAIA,CAACA,SAASA,CAACA,CAACA,IAAIA,EAAEA,CAACA;QACtDA,CAACA;;QAEDN,6BAAAA;YACIO,OAAOA,IAAIA,CAACA,MAAMA,CAACA,GAAGA,CAACA,CAACA;QAC5BA,CAACA;QACLP,oBAACA;IAADA,CAACA,IAAAD;IAlCDA,iCAkCCA;AACLA,CAACA,uBAAA"} -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Data/BinaryReader.ts: -------------------------------------------------------------------------------- 1 | /// 2 | module Data { 3 | export class BinaryReader implements BitStream { 4 | private stream: BitStream; 5 | 6 | constructor(stream: BitStream) { 7 | this.stream = stream; 8 | } 9 | 10 | public getBit(): number { 11 | return this.stream.getBit(); 12 | } 13 | 14 | public getBits(n: number): number { 15 | var byte: number = 0; 16 | for (var i: number = 0; i < n; i++) { 17 | byte |= this.getBit() * (1 << (n - i - 1)); 18 | } 19 | return byte; 20 | } 21 | 22 | public getUint8(): number { 23 | return this.getBits(8); 24 | } 25 | 26 | public getUint16(): number { 27 | return this.getUint8() | (this.getUint8() << 8); 28 | } 29 | 30 | public getUint32(): number { 31 | return this.getUint16() | (this.getUint16() << 16); 32 | } 33 | 34 | public getFixedLengthString(len: number) { 35 | var s = ''; 36 | for (var i = 0; i < len; i++) { 37 | s += String.fromCharCode(this.getUint8()); 38 | } 39 | return s; 40 | } 41 | 42 | public eof(): boolean { 43 | return this.stream.eof(); 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Data/BitStream.js: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Data/BitStream.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"BitStream.js","sourceRoot":"","sources":["BitStream.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Data/BitStream.ts: -------------------------------------------------------------------------------- 1 | module Data { 2 | export interface BitStream { 3 | getBit(): number; 4 | eof(): boolean; 5 | } 6 | export interface RandomAccessBitStream extends BitStream { 7 | setPosition(bit: number): void; 8 | getPosition(): number; 9 | } 10 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Data/ByteStream.js: -------------------------------------------------------------------------------- 1 | //# sourceMappingURL=ByteStream.js.map 2 | -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Data/ByteStream.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"ByteStream.js","sourceRoot":"","sources":["ByteStream.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Data/Color.js: -------------------------------------------------------------------------------- 1 | var Data; 2 | (function (Data) { 3 | var Color = (function () { 4 | function Color(r, g, b) { 5 | this.R = r; 6 | this.G = g; 7 | this.B = b; 8 | } 9 | Color.prototype.negative = function () { 10 | return new Color(255 - this.R, 255 - this.G, 255 - this.B); 11 | }; 12 | 13 | Color.prototype.scale = function (n) { 14 | return new Color(Math.floor(this.R * n), Math.floor(this.G * n), Math.floor(this.B * n)); 15 | }; 16 | 17 | Color.prototype.toCss = function () { 18 | return 'rgb(' + this.R + ',' + this.G + ',' + this.B + ')'; 19 | }; 20 | 21 | Color.prototype.toVec3 = function () { 22 | return new TSM.vec3([this.R / 255.0, this.G / 255.0, this.B / 255.0]); 23 | }; 24 | 25 | Color.prototype.equals = function (b) { 26 | return this.R === b.R && this.G === b.G && this.B === b.B; 27 | }; 28 | return Color; 29 | })(); 30 | Data.Color = Color; 31 | })(Data || (Data = {})); 32 | -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Data/Color.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"Color.js","sourceRoot":"","sources":["Color.ts"],"names":["Data","Data.Color","Data.Color.constructor"],"mappings":"AAAA,IAAO,IAAI;AAWV,CAXD,UAAO,IAAI;IACPA;QAIIC,eAAYA,CAASA,EAAEA,CAASA,EAAEA,CAASA;YACvCC,IAAIA,CAACA,CAACA,GAAGA,CAACA;YACVA,IAAIA,CAACA,CAACA,GAAGA,CAACA;YACVA,IAAIA,CAACA,CAACA,GAAGA,CAACA;QACdA,CAACA;QACLD,aAACA;IAADA,CAACA,IAAAD;IATDA,mBASCA;AACLA,CAACA,uBAAA"} -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Data/Color.ts: -------------------------------------------------------------------------------- 1 | module Data { 2 | export class Color { 3 | public R: number; 4 | public G: number; 5 | public B: number; 6 | constructor(r: number, g: number, b: number) { 7 | this.R = r; 8 | this.G = g; 9 | this.B = b; 10 | } 11 | 12 | negative(): Color { 13 | return new Color(255 - this.R, 255 - this.G, 255 - this.B); 14 | } 15 | 16 | scale(n: number): Color { 17 | return new Color(Math.floor(this.R * n), Math.floor(this.G * n), Math.floor(this.B * n)); 18 | } 19 | 20 | toCss(): string { 21 | return 'rgb(' + this.R + ',' + this.G + ',' + this.B + ')'; 22 | } 23 | 24 | toVec3(): TSM.vec3 { 25 | return new TSM.vec3([this.R / 255.0, this.G / 255.0, this.B / 255.0]); 26 | } 27 | 28 | public equals(b: Color): boolean { 29 | return this.R === b.R && this.G === b.G && this.B === b.B; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Data/CompressedByteStream.js: -------------------------------------------------------------------------------- 1 | var Data; 2 | (function (Data) { 3 | var CompressedByteStream = (function () { 4 | function CompressedByteStream(stream) { 5 | this.buffer = []; 6 | this.source = stream; 7 | this.len1 = this.source.getUint8(); 8 | this.len2 = this.source.getUint8(); 9 | this.len3 = this.source.getUint8(); 10 | this.len4 = (1 << this.len2); 11 | this.outputStream = new Data.ArrayBitStream(this.buffer); 12 | } 13 | CompressedByteStream.prototype.copySet = function (offset) { 14 | var copyStart = this.buffer.length - 2 - offset; 15 | var bytesToCopy = this.source.getBits(this.len1) + 1; 16 | for (var i = 0; i <= bytesToCopy; i++) { 17 | this.buffer.push(this.buffer[copyStart + i]); 18 | } 19 | }; 20 | 21 | CompressedByteStream.prototype.advanceBuffer = function () { 22 | if (this.source.getBit() == 1) { 23 | if (this.source.getBit() == 1) { 24 | this.buffer.push(this.source.getUint8()); 25 | } else { 26 | var copySize = this.source.getBits(this.len3) + this.len4; 27 | this.copySet(copySize); 28 | } 29 | } else { 30 | var copySize = this.source.getBits(this.len2); 31 | this.copySet(copySize); 32 | } 33 | }; 34 | 35 | CompressedByteStream.prototype.getBit = function () { 36 | if (this.outputStream.eof()) { 37 | this.advanceBuffer(); 38 | } 39 | return this.outputStream.getBit(); 40 | }; 41 | 42 | CompressedByteStream.prototype.eof = function () { 43 | return this.source.eof(); 44 | }; 45 | return CompressedByteStream; 46 | })(); 47 | Data.CompressedByteStream = CompressedByteStream; 48 | })(Data || (Data = {})); 49 | -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Data/CompressedByteStream.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"CompressedByteStream.js","sourceRoot":"","sources":["CompressedByteStream.ts"],"names":["Data","Data.CompressedByteStream","Data.CompressedByteStream.constructor","Data.CompressedByteStream.copySet","Data.CompressedByteStream.advanceBuffer","Data.CompressedByteStream.getBit","Data.CompressedByteStream.eof"],"mappings":"AAAA,qCAAqC;AACrC,0CAA0C;AAC1C,IAAO,IAAI;AAqDV,CArDD,UAAO,IAAI;IACPA;QAUIC,8BAAYA,MAAoBA;YAHhCC,KAAQA,MAAMA,GAAaA,EAAEA,CAACA;YAI1BA,IAAIA,CAACA,MAAMA,GAAGA,MAAMA;YACpBA,IAAIA,CAACA,IAAIA,GAAGA,IAAIA,CAACA,MAAMA,CAACA,QAAQA,CAACA,CAACA;YAClCA,IAAIA,CAACA,IAAIA,GAAGA,IAAIA,CAACA,MAAMA,CAACA,QAAQA,CAACA,CAACA;YAClCA,IAAIA,CAACA,IAAIA,GAAGA,IAAIA,CAACA,MAAMA,CAACA,QAAQA,CAACA,CAACA;YAClCA,IAAIA,CAACA,IAAIA,GAAGA,CAACA,CAACA,IAAIA,IAAIA,CAACA,IAAIA,CAACA;YAC5BA,IAAIA,CAACA,YAAYA,GAAGA,IAAIA,mBAAcA,CAACA,IAAIA,CAACA,MAAMA,CAACA;QACvDA,CAACA;QAEDD,yCAAAA,UAAgBA,MAAcA;YAC1BE,IAAIA,SAASA,GAAGA,IAAIA,CAACA,MAAMA,CAACA,MAAMA,GAAGA,CAACA,GAAGA,MAAMA;YAC/CA,IAAIA,WAAWA,GAAGA,IAAIA,CAACA,MAAMA,CAACA,OAAOA,CAACA,IAAIA,CAACA,IAAIA,CAACA,GAAGA,CAACA;YACpDA,KAAKA,IAAIA,CAACA,GAAWA,CAACA,EAAEA,CAACA,IAAIA,WAAWA,EAAEA,CAACA,EAAEA,CAAEA;gBAC3CA,IAAIA,CAACA,MAAMA,CAACA,IAAIA,CAACA,IAAIA,CAACA,MAAMA,CAACA,SAASA,GAAGA,CAACA,CAACA,CAACA;aAC/CA;QACLA,CAACA;;QAEDF,+CAAAA;YACIG,IAAIA,IAAIA,CAACA,MAAMA,CAACA,MAAMA,CAACA,CAACA,IAAIA,CAACA,CAAEA;gBAC3BA,IAAIA,IAAIA,CAACA,MAAMA,CAACA,MAAMA,CAACA,CAACA,IAAIA,CAACA,CAAEA;oBAC3BA,IAAIA,CAACA,MAAMA,CAACA,IAAIA,CAACA,IAAIA,CAACA,MAAMA,CAACA,QAAQA,CAACA,CAACA,CAACA;iBAC3CA,KAAMA;oBACHA,IAAIA,QAAQA,GAAWA,IAAIA,CAACA,MAAMA,CAACA,OAAOA,CAACA,IAAIA,CAACA,IAAIA,CAACA,GAAGA,IAAIA,CAACA,IAAIA;oBACjEA,IAAIA,CAACA,OAAOA,CAACA,QAAQA,CAACA;iBACzBA;aACJA,KAAMA;gBACHA,IAAIA,QAAQA,GAAWA,IAAIA,CAACA,MAAMA,CAACA,OAAOA,CAACA,IAAIA,CAACA,IAAIA,CAACA;gBACrDA,IAAIA,CAACA,OAAOA,CAACA,QAAQA,CAACA;aACzBA;QACLA,CAACA;;QAEDH,wCAAAA;YACII,IAAIA,IAAIA,CAACA,YAAYA,CAACA,GAAGA,CAACA,CAACA,CAAEA;gBACzBA,IAAIA,CAACA,aAAaA,CAACA,CAACA;aACvBA;YACDA,OAAOA,IAAIA,CAACA,YAAYA,CAACA,MAAMA,CAACA,CAACA;QACrCA,CAACA;;QAEDJ,qCAAAA;YACIK,OAAOA,IAAIA,CAACA,MAAMA,CAACA,GAAGA,CAACA,CAACA;QAC5BA,CAACA;QACLL,4BAACA;IAADA,CAACA,IAAAD;IAnDDA,iDAmDCA;AACLA,CAACA,uBAAA"} -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Data/CompressedByteStream.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | module Data { 4 | export class CompressedByteStream implements BitStream { 5 | private source: BinaryReader; 6 | 7 | private len1: number; 8 | private len2: number; 9 | private len3: number; 10 | private len4: number; 11 | private buffer: number[] = []; 12 | private outputStream: BitStream; 13 | 14 | constructor(stream: BinaryReader) { 15 | this.source = stream; 16 | this.len1 = this.source.getUint8(); 17 | this.len2 = this.source.getUint8(); 18 | this.len3 = this.source.getUint8(); 19 | this.len4 = (1 << this.len2); 20 | this.outputStream = new ArrayBitStream(this.buffer); 21 | } 22 | 23 | private copySet(offset: number) { 24 | var copyStart = this.buffer.length - 2 - offset; 25 | var bytesToCopy = this.source.getBits(this.len1) + 1; 26 | for (var i: number = 0; i <= bytesToCopy; i++) { 27 | this.buffer.push(this.buffer[copyStart + i]); 28 | } 29 | } 30 | 31 | private advanceBuffer(): void { 32 | if (this.source.getBit() == 1) { 33 | if (this.source.getBit() == 1) { //Raw byte follows 34 | this.buffer.push(this.source.getUint8()); 35 | } else { //Large copy 36 | var copySize: number = this.source.getBits(this.len3) + this.len4; 37 | this.copySet(copySize); 38 | } 39 | } else { 40 | var copySize: number = this.source.getBits(this.len2); 41 | this.copySet(copySize); 42 | } 43 | } 44 | 45 | public getBit(): number { 46 | if (this.outputStream.eof()) { 47 | this.advanceBuffer(); 48 | } 49 | return this.outputStream.getBit(); 50 | } 51 | 52 | public eof(): boolean { 53 | return this.source.eof(); 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Drawing/CanvasProvider.ts: -------------------------------------------------------------------------------- 1 | module Drawing { 2 | export interface CanvasProvider { 3 | getCanvas(): HTMLCanvasElement; 4 | }; 5 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Drawing/HTMLCanvasProvider.ts: -------------------------------------------------------------------------------- 1 | module Drawing { 2 | export class HTMLCanvasProvider implements CanvasProvider { 3 | public getCanvas(): HTMLCanvasElement { 4 | return document.createElement('canvas'); 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Drawing/Mesh.ts: -------------------------------------------------------------------------------- 1 | /// 2 | module Drawing { 3 | export class Mesh extends WGL.Renderable { 4 | public Texture: WGL.Texture; 5 | 6 | public ProjectionMatrix: TSM.mat4; 7 | public ModelMatrix: TSM.mat4; 8 | public ViewMatrix: TSM.mat4; 9 | public Scale: number; 10 | 11 | private uSampler: WGL.ShaderUniform; 12 | private uProjectionMatrix: WGL.ShaderUniform; 13 | private uModelMatrix: WGL.ShaderUniform; 14 | private uViewMatrix: WGL.ShaderUniform; 15 | private uScale: WGL.ShaderUniform; 16 | 17 | constructor(gl: WebGLRenderingContext, managers: Managers.ManagerSet, vertices: Vertices.Vertex3DC[], shader: WGL.Shader = null) { 18 | this.Scale = 1.0; 19 | this.ModelMatrix = TSM.mat4.identity.copy(); 20 | this.ViewMatrix = TSM.mat4.identity.copy(); 21 | this.ProjectionMatrix = TSM.mat4.perspective(80.0, 320.0 / 200.0, 0.1, 1000.0); 22 | this.Texture = managers.Textures.getTexture(gl, 'WHITE').Texture; 23 | 24 | shader = shader || managers.Shaders.getShader(gl, managers.Shaders.Shaders.Color3D); 25 | var vertDesc = Vertices.Vertex3DC.getDescriptor(gl); 26 | 27 | var state = new WGL.GLState(gl); 28 | state.EnableBlend = false; 29 | state.EnableDepthTest = true; 30 | 31 | var buffer = new WGL.Buffer(gl); 32 | buffer.loadData(vertDesc.buildArray(vertices)); 33 | 34 | this.uModelMatrix = shader.getUniform("uModelMatrix"); 35 | this.uViewMatrix = shader.getUniform("uViewMatrix"); 36 | this.uProjectionMatrix = shader.getUniform("uProjectionMatrix"); 37 | this.uScale = shader.getUniform("uScale"); 38 | this.uSampler = shader.getUniform("uSampler"); 39 | 40 | super(gl, state, vertDesc, shader, buffer); 41 | } 42 | 43 | public preDraw(gl: WebGLRenderingContext, shader: WGL.Shader) { 44 | if (this.uProjectionMatrix !== null) { 45 | this.uProjectionMatrix.setMat4(this.ProjectionMatrix); 46 | } 47 | if (this.uModelMatrix !== null) { 48 | this.uModelMatrix.setMat4(this.ModelMatrix); 49 | } 50 | if (this.uViewMatrix !== null) { 51 | this.uViewMatrix.setMat4(this.ViewMatrix); 52 | } 53 | if (this.uSampler !== null && this.Texture !== null) { 54 | this.Texture.attachToUniform(this.uSampler); 55 | } 56 | if (this.uScale !== null) { 57 | this.uScale.set1f(this.Scale); 58 | } 59 | } 60 | 61 | public postDraw(gl: WebGLRenderingContext, shader: WGL.Shader) { 62 | if (this.uSampler !== null && this.Texture !== null) { 63 | this.Texture.detachFromUniform(); 64 | } 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Drawing/NodeCanvasProvider.ts: -------------------------------------------------------------------------------- 1 | module Drawing { 2 | var canvas: any = null; 3 | if (typeof document === 'undefined' && typeof require !== 'undefined') { 4 | canvas = require('./Node/node_modules/node-canvas'); 5 | } 6 | 7 | export class NodeCanvasProvider { 8 | public getCanvas(): HTMLCanvasElement { 9 | return new canvas(1, 1); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Drawing/TextHelper.ts: -------------------------------------------------------------------------------- 1 | module Drawing { 2 | export class TextHelper { 3 | private managers: Managers.ManagerSet; 4 | constructor(managers: Managers.ManagerSet) { 5 | this.managers = managers; 6 | } 7 | 8 | getSpriteFromText(gl: WebGLRenderingContext, managers: Managers.ManagerSet, text: string, font: string, height: number, force2D: boolean = false): Drawing.Sprite { 9 | var cvs = managers.Canvas.getCanvas(); 10 | var ctx = cvs.getContext('2d'); 11 | cvs.width = 600; 12 | cvs.height = 600; 13 | ctx.font = font; 14 | var size = ctx.measureText(text); 15 | cvs.width = size.width + 1; 16 | cvs.height = height; 17 | ctx.fillStyle = '#FFFFFF'; 18 | ctx.textBaseline = 'middle'; 19 | ctx.font = font; 20 | ctx.fillText(text, 0.5, cvs.height / 2 + 0.5); 21 | 22 | var tex = new WGL.Texture(gl); 23 | tex.setFilters(gl.NEAREST, gl.NEAREST); 24 | tex.loadData(cvs); 25 | 26 | var tf = new TextureFragment(tex, 0, 0, cvs.width, cvs.height); 27 | 28 | return force2D ? managers.Graphics.get2DSprite(gl, managers, tf) : managers.Graphics.get3DSprite(gl, managers, tf); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Drawing/TextureFragment.ts: -------------------------------------------------------------------------------- 1 | module Drawing { 2 | export class TextureFragment { 3 | public Texture: WGL.Texture; 4 | public XOffset: number; 5 | public YOffset: number; 6 | public Width: number; 7 | public Height: number; 8 | 9 | constructor(tex: WGL.Texture, x: number, y: number, w: number, h: number) { 10 | this.Texture = tex; 11 | this.XOffset = x; 12 | this.YOffset = y; 13 | this.Width = w; 14 | this.Height = h; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Engine/BrowserDocumentProvider.ts: -------------------------------------------------------------------------------- 1 | module Engine { 2 | export class BrowserDocumentProvider implements DocumentProvider { 3 | getSize(): TSM.vec2 { 4 | return new TSM.vec2([document.body.clientWidth, document.body.clientHeight]) 5 | } 6 | 7 | setResizeCb(cb: (size: TSM.vec2) => void): void { 8 | window.onresize = () => { 9 | cb(this.getSize()); 10 | }; 11 | } 12 | 13 | requestAnimationFrame(cb: () => void): void { 14 | requestAnimationFrame(cb); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Engine/CameraState.ts: -------------------------------------------------------------------------------- 1 | module Engine { 2 | export class CameraState { 3 | constructor(headPosition: TSM.vec3, headOrientation: TSM.quat, eyeOffset: TSM.vec3, projectionMatrix: TSM.mat4) { 4 | this.HeadPosition = headPosition; 5 | this.HeadOrientation = headOrientation; 6 | this.EyeOffset = eyeOffset; 7 | this.ProjectionMatrix = projectionMatrix; 8 | } 9 | 10 | public HeadPosition: TSM.vec3; 11 | public HeadOrientation: TSM.quat; 12 | public EyeOffset: TSM.vec3; 13 | public ProjectionMatrix: TSM.mat4; 14 | } 15 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Engine/ClassicState2DDrawer.ts: -------------------------------------------------------------------------------- 1 | module Engine { 2 | export class ClassicState2DDrawer implements State2DDrawer { 3 | draw(gl: WebGLRenderingContext, canvas: HTMLCanvasElement, frameManager: FrameManager, frameTimeInfo: FrameTimeInfo, cam: CameraState, state: State2D): void { 4 | var helper = new States.ClassicGLStateHelper(); 5 | helper.startFrame(gl, canvas); 6 | state.drawFrame2D(gl, canvas, frameManager, frameTimeInfo, cam); 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Engine/ClassicState3DDrawer.ts: -------------------------------------------------------------------------------- 1 | module Engine { 2 | export class ClassicState3DDrawer implements State3DDrawer { 3 | draw(gl: WebGLRenderingContext, canvas: HTMLCanvasElement, frameManager: FrameManager, frameTimeInfo: FrameTimeInfo, cam: CameraState, state: State3D): void { 4 | var helper = new States.ClassicGLStateHelper(); 5 | helper.startFrame(gl, canvas); 6 | state.drawFrame3D(gl, canvas, frameManager, frameTimeInfo, cam); 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Engine/Clock.ts: -------------------------------------------------------------------------------- 1 | module Engine { 2 | export class FrameTimeInfo { 3 | private frameTime: number; 4 | 5 | public constructor(frameTime: number) { 6 | this.frameTime = frameTime; 7 | } 8 | 9 | public getPhysicsStep(): number { 10 | return 1.0 / 30.0; 11 | } 12 | 13 | public getFPS(): number { 14 | return 30.0; 15 | } 16 | 17 | public getFrameTime(): number { 18 | return this.frameTime; 19 | } 20 | } 21 | 22 | export class Clock { 23 | private lastTime: number; 24 | 25 | public constructor() { 26 | this.lastTime = Date.now(); 27 | } 28 | 29 | public nextFrame(): FrameTimeInfo { 30 | var newTime = Date.now(); 31 | var duration = (newTime - this.lastTime) / 1000.0; 32 | this.lastTime = newTime; 33 | 34 | return new FrameTimeInfo(duration); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Engine/DocumentProvider.ts: -------------------------------------------------------------------------------- 1 | module Engine { 2 | export interface DocumentProvider { 3 | getSize(): TSM.vec2; 4 | setResizeCb(cb: (size: TSM.vec2) => void): void; 5 | requestAnimationFrame(cb: () => void): void; 6 | } 7 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Engine/KeyboardManager.ts: -------------------------------------------------------------------------------- 1 | module Engine { 2 | export class KeyboardManager { 3 | private keys: boolean[] = []; 4 | 5 | constructor(element: HTMLElement) { 6 | for (var i = 0; i < 256; i++) { 7 | this.keys.push(false); 8 | } 9 | 10 | element.onkeydown = (evt) => this.onDown(evt); 11 | element.onkeyup = (evt) => this.onUp(evt); 12 | } 13 | 14 | public isDown(n: number): boolean { 15 | return this.keys[n]; 16 | } 17 | 18 | private onDown(evt: KeyboardEvent) { 19 | this.keys[evt.keyCode] = true; 20 | } 21 | 22 | private onUp(evt: KeyboardEvent) { 23 | this.keys[evt.keyCode] = false; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Engine/NodeDocumentProvider.ts: -------------------------------------------------------------------------------- 1 | module Engine { 2 | export class NodeDocumentProvider implements DocumentProvider { 3 | private doc: any; 4 | private cvs: HTMLCanvasElement; 5 | 6 | constructor(doc: any, cvs: HTMLCanvasElement) { 7 | this.doc = doc; 8 | this.cvs = cvs; 9 | } 10 | 11 | getSize(): TSM.vec2 { 12 | return new TSM.vec2([this.cvs.width, this.cvs.height]); 13 | } 14 | 15 | setResizeCb(cb: (size: TSM.vec2) => void): void { 16 | this.cvs.onresize = function (evt: any) { 17 | cb(new TSM.vec2([evt.width, evt.height])); 18 | }; 19 | } 20 | 21 | requestAnimationFrame(cb: () => void): void { 22 | this.doc.requestAnimationFrame(cb); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Engine/State2D.ts: -------------------------------------------------------------------------------- 1 | module Engine { 2 | export interface State2DDrawer { 3 | draw(gl: WebGLRenderingContext, canvas: HTMLCanvasElement, frameManager: FrameManager, frameTimeInfo: FrameTimeInfo, cam: CameraState, state: State2D) : void; 4 | } 5 | 6 | export class State2D implements GameState { 7 | private drawer: State2DDrawer; 8 | private managers: Managers.ManagerSet; 9 | 10 | constructor(managers: Managers.ManagerSet) { 11 | this.managers = managers; 12 | } 13 | 14 | load(gl: WebGLRenderingContext): void { 15 | this.drawer = this.managers.Graphics.getState2DDrawer(gl, this.managers); 16 | } 17 | 18 | unload(): void { 19 | } 20 | 21 | updatePhysics(frameManager: FrameManager, frameTimeInfo: FrameTimeInfo): void { 22 | } 23 | 24 | drawFrame(gl: WebGLRenderingContext, canvas: HTMLCanvasElement, frameManager: FrameManager, frameTimeInfo: FrameTimeInfo, cam: CameraState): void { 25 | this.drawer.draw(gl, canvas, frameManager, frameTimeInfo, cam, this); 26 | } 27 | 28 | drawFrame2D(gl: WebGLRenderingContext, canvas: HTMLCanvasElement, frameManager: FrameManager, frameTimeInfo: FrameTimeInfo, cam: CameraState): void { 29 | throw "drawFrame2D NOT IMPLEMENTED"; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Engine/State3D.ts: -------------------------------------------------------------------------------- 1 | module Engine { 2 | export interface State3DDrawer { 3 | draw(gl: WebGLRenderingContext, canvas: HTMLCanvasElement, frameManager: FrameManager, frameTimeInfo: FrameTimeInfo, cam: CameraState, state: State3D): void; 4 | } 5 | 6 | export class State3D implements GameState { 7 | private drawer: State3DDrawer; 8 | private managers: Managers.ManagerSet; 9 | 10 | constructor(managers: Managers.ManagerSet) { 11 | this.managers = managers; 12 | } 13 | 14 | load(gl: WebGLRenderingContext): void { 15 | this.drawer = this.managers.Graphics.getState3DDrawer(gl, this.managers); 16 | } 17 | 18 | unload(): void { 19 | } 20 | 21 | updatePhysics(frameManager: FrameManager, frameTimeInfo: FrameTimeInfo): void { 22 | } 23 | 24 | drawFrame(gl: WebGLRenderingContext, canvas: HTMLCanvasElement, frameManager: FrameManager, frameTimeInfo: FrameTimeInfo, cam: CameraState): void { 25 | this.drawer.draw(gl, canvas, frameManager, frameTimeInfo, cam, this); 26 | } 27 | 28 | drawFrame3D(gl: WebGLRenderingContext, canvas: HTMLCanvasElement, frameManager: FrameManager, frameTimeInfo: FrameTimeInfo, cam: CameraState): void { 29 | throw "drawFrame3D NOT IMPLEMENTED"; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Engine/VRState2DDrawer.ts: -------------------------------------------------------------------------------- 1 | module Engine { 2 | export class VRState2DDrawer implements State2DDrawer { 3 | private managers: Managers.ManagerSet; 4 | 5 | constructor(managers: Managers.ManagerSet) { 6 | this.managers = managers; 7 | } 8 | 9 | private static initialized: boolean = false; 10 | private static target: WGL.RenderableTexture = null; 11 | private static screenMesh: Drawing.Mesh = null; 12 | private ensureObjects(gl: WebGLRenderingContext): void { 13 | if (VRState2DDrawer.initialized) { 14 | return; 15 | } 16 | VRState2DDrawer.target = WGL.RenderableTexture.Create(gl, 1024, 1024); 17 | VRState2DDrawer.initialized = true; 18 | 19 | var color = new TSM.vec3([1.0, 1.0, 1.0]); 20 | var w = 1.0; 21 | var h = w * 200.0 / 320.0; 22 | var z = 0.0; 23 | 24 | var verts = [ 25 | new Vertices.Vertex3DC(new TSM.vec3([-w, -h, z]), color, new TSM.vec2([0.0, 0.0])), 26 | new Vertices.Vertex3DC(new TSM.vec3([w, -h, z]), color, new TSM.vec2([1.0, 0.0])), 27 | new Vertices.Vertex3DC(new TSM.vec3([w, h, z]), color, new TSM.vec2([1.0, 1.0])), 28 | 29 | new Vertices.Vertex3DC(new TSM.vec3([w, h, z]), color, new TSM.vec2([1.0, 1.0])), 30 | new Vertices.Vertex3DC(new TSM.vec3([-w, h, z]), color, new TSM.vec2([0.0, 1.0])), 31 | new Vertices.Vertex3DC(new TSM.vec3([-w, -h, z]), color, new TSM.vec2([0.0, 0.0])) 32 | ]; 33 | 34 | VRState2DDrawer.screenMesh = this.managers.Graphics.getMesh(gl, this.managers, verts); 35 | VRState2DDrawer.screenMesh.Texture = VRState2DDrawer.target.Texture; 36 | 37 | 38 | VRState2DDrawer.screenMesh.ModelMatrix.translate(new TSM.vec3([0.0, 0.0, -12.0])); 39 | } 40 | 41 | draw(gl: WebGLRenderingContext, canvas: HTMLCanvasElement, frameManager: FrameManager, frameTimeInfo: FrameTimeInfo, cam: CameraState, state: State2D): void { 42 | this.ensureObjects(gl); 43 | 44 | var helper = new States.VRGLStateHelper(this.managers.VR); 45 | VRState2DDrawer.target.bindForDrawing(); 46 | gl.viewport(0, 0, 1024, 1024); 47 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 48 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 49 | state.drawFrame2D(gl, canvas, frameManager, frameTimeInfo, cam); 50 | 51 | helper.startFrame(gl); 52 | VRState2DDrawer.target.Texture.generateMipmap(); 53 | 54 | VRState2DDrawer.screenMesh.ModelMatrix.setIdentity(); 55 | VRState2DDrawer.screenMesh.ModelMatrix.translate(new TSM.vec3([0.0, 0.0, -this.managers.Settings.MenuDistance.getValue()])); 56 | 57 | var scale = this.managers.Settings.MenuSize.getValue(); 58 | VRState2DDrawer.screenMesh.ModelMatrix.scale(new TSM.vec3([scale, scale, 1.0])); 59 | 60 | var me = this; 61 | function runPass(eyeNum: number) { 62 | var base = me.managers.VR.getHeadCameraState(eyeNum); 63 | VRState2DDrawer.screenMesh.ViewMatrix.setIdentity(); 64 | VRState2DDrawer.screenMesh.ViewMatrix.translate(base.EyeOffset); 65 | VRState2DDrawer.screenMesh.ViewMatrix.multiply(base.HeadOrientation.inverse().toMat4()); 66 | VRState2DDrawer.screenMesh.ViewMatrix.translate(base.HeadPosition.scale(-1)); 67 | 68 | VRState2DDrawer.screenMesh.ProjectionMatrix = base.ProjectionMatrix; 69 | VRState2DDrawer.screenMesh.draw(); 70 | } 71 | 72 | helper.startEye(gl, 0); 73 | runPass(0); 74 | helper.endEye(gl, 0); 75 | 76 | helper.startEye(gl, 1); 77 | runPass(1); 78 | helper.endEye(gl, 1); 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Engine/VRState3DDrawer.ts: -------------------------------------------------------------------------------- 1 | module Engine { 2 | export class VRState3DDrawer implements State3DDrawer { 3 | private managers: Managers.ManagerSet; 4 | 5 | constructor(managers: Managers.ManagerSet) { 6 | this.managers = managers; 7 | } 8 | 9 | private static initialized: boolean = false; 10 | 11 | draw(gl: WebGLRenderingContext, canvas: HTMLCanvasElement, frameManager: FrameManager, frameTimeInfo: FrameTimeInfo, cam: CameraState, state: State3D): void { 12 | var helper = new States.VRGLStateHelper(this.managers.VR); 13 | helper.startFrame(gl); 14 | 15 | var me = this; 16 | function getCam(eyeNum: number): Engine.CameraState { 17 | var base = me.managers.VR.getHeadCameraState(eyeNum); 18 | return base; 19 | } 20 | 21 | helper.startEye(gl, 0); 22 | var camLeft = getCam(0); 23 | state.drawFrame3D(gl, canvas, frameManager, frameTimeInfo, camLeft); 24 | helper.endEye(gl, 0); 25 | 26 | helper.startEye(gl, 1); 27 | var camRight = getCam(1); 28 | state.drawFrame3D(gl, canvas, frameManager, frameTimeInfo, camRight); 29 | helper.endEye(gl, 1); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Events/EventBus.ts: -------------------------------------------------------------------------------- 1 | module Events { 2 | export class EventBus { 3 | constructor() { 4 | } 5 | 6 | private handlers: { [s: string]: any[] } = {}; 7 | 8 | private getClassName(event: T): string { 9 | var evt = event; 10 | return evt.constructor.name; 11 | } 12 | 13 | public fire(event: T): void { 14 | var name = this.getClassName(event); 15 | if (name in this.handlers) { 16 | var handlers: { (event: T): void }[] = this.handlers[name]; 17 | for (var i = 0; i < handlers.length; i++) { 18 | handlers[i](event); 19 | } 20 | } 21 | } 22 | 23 | public register(event: T, handler: (event: T) => void): void { 24 | var name = this.getClassName(event); 25 | if (!(name in this.handlers)) { 26 | this.handlers[name] = []; 27 | } 28 | this.handlers[name].push(handler); 29 | } 30 | 31 | public unregister(event: T, handler: (event: T) => void): void { 32 | var name = this.getClassName(event); 33 | if (name in this.handlers) { 34 | var handlers: { (event: T): void }[] = this.handlers[name]; 35 | for (var i = 0; i < handlers.length; i++) { 36 | if (handlers[i] === handler) { 37 | handlers.splice(i, 1); 38 | i--; 39 | } 40 | } 41 | } 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/ExeData/ExeDataManager.ts: -------------------------------------------------------------------------------- 1 | module ExeData { 2 | export class ExeDataLoader { 3 | private managers: Managers.ManagerSet; 4 | constructor(managers: Managers.ManagerSet) { 5 | this.managers = managers; 6 | } 7 | 8 | public load(): void { 9 | var managers: Managers.ManagerSet = this.managers; 10 | 11 | var src = new ExeReader(managers.Streams.getStream('SKYROADS.EXE')); 12 | var dst = managers.Textures; 13 | 14 | var dash = dst.getImage('DASHBRD.LZS'); 15 | 16 | var loader = new Images.DirectImageLoader(this.managers); 17 | var pi = 5; 18 | var palette: Data.Color[] = [new Data.Color(0, 0, 0), dash.Palette[pi]]; 19 | while (palette.length < 255) { 20 | palette.push(dash.Palette[pi + 1]); 21 | } 22 | 23 | dst.setImages('NUMBERS', loader.loadFromStream(src, 0x13C * 8, palette, 10, 0, 0, 4, 5)); 24 | dst.setImages('JUMPMASTER', loader.loadFromStream(src, 0x204 * 8, palette, 2, 203, 156, 26, 5)); 25 | 26 | //Calculate O2 for flash 27 | dst.setImages('O2_RED', [this.imageByChangingColor(dash, 160, 161, 7, 7, new Data.Color(216, 224, 224), new Data.Color(255, 0, 0))]); 28 | 29 | //Calculate Fuel for flashing 30 | dst.setImages('FUEL_RED', [this.imageByChangingColor(dash, 155, 169, 16, 5, new Data.Color(216, 224, 224), new Data.Color(255, 0, 0))]); 31 | 32 | //Calculate progress indicator 33 | var progressImgs: Images.ImageFragment[] = []; 34 | for (var i = 1; i < 29; i++) { 35 | progressImgs.push(this.imageByChangingColor(dash, 42, 130, i, 20, new Data.Color(72, 0, 68), new Data.Color(113, 0, 101))); 36 | } 37 | 38 | dst.setImages('PROGRESS_INDICATOR', progressImgs); 39 | 40 | var cvs = managers.Canvas.getCanvas(); 41 | cvs.width = 32; 42 | cvs.height = 32; 43 | var ctx = cvs.getContext('2d'); 44 | ctx.fillStyle = '#FFFFFF'; 45 | ctx.fillRect(0, 0, 32, 32); 46 | dst.setImages('WHITE', [new Images.ImageFragment(cvs, [], 0, 0)]); 47 | } 48 | 49 | private imageByChangingColor(src: Images.ImageFragment, xPos: number, yPos: number, w: number, h: number, colorA: Data.Color, colorB: Data.Color): Images.ImageFragment { 50 | var ctxSrc = src.Canvas.getContext('2d'); 51 | var dataSrc = ctxSrc.getImageData(xPos - src.XOffset, yPos - src.YOffset, w, h); 52 | 53 | var cvsDst = this.managers.Canvas.getCanvas(); 54 | cvsDst.width = w; 55 | cvsDst.height = h; 56 | 57 | var ctxDst = cvsDst.getContext('2d'); 58 | var dataDst = ctxDst.getImageData(0, 0, w, h); 59 | 60 | for (var i = 0; i < dataSrc.data.length; i += 4) { 61 | var color = new Data.Color(dataSrc.data[i + 0], dataSrc.data[i + 1], dataSrc.data[i + 2]); 62 | var alpha = dataSrc.data[i + 3]; 63 | if (color.equals(colorA)) { 64 | color = colorB; 65 | } else if (color.equals(colorB)) { 66 | color = colorA; 67 | } 68 | 69 | dataDst.data[i + 0] = color.R; 70 | dataDst.data[i + 1] = color.G; 71 | dataDst.data[i + 2] = color.B; 72 | dataDst.data[i + 3] = alpha; 73 | } 74 | 75 | ctxDst.putImageData(dataDst, 0, 0); 76 | 77 | return new Images.ImageFragment(cvsDst, src.Palette, xPos, yPos); 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/ExeData/ExeReader.ts: -------------------------------------------------------------------------------- 1 | module ExeData { 2 | export class ExeReader implements Data.RandomAccessBitStream { 3 | private stream: Data.RandomAccessBitStream; 4 | private offset: number; 5 | 6 | constructor(stream: Data.RandomAccessBitStream) { 7 | this.stream = stream; 8 | var reader = new Data.BinaryReader(stream); 9 | stream.setPosition(8 * 8); 10 | this.offset = reader.getUint16() * 16 + 0x66E * 16; 11 | this.setPosition(0); 12 | } 13 | 14 | public getBit(): number { 15 | return this.stream.getBit(); 16 | } 17 | 18 | public eof(): boolean { 19 | return this.stream.eof(); 20 | } 21 | 22 | public setPosition(bit: number): void { 23 | this.stream.setPosition(bit + this.offset * 8); 24 | } 25 | 26 | public getPosition(): number { 27 | return this.stream.getPosition() - this.offset * 8; 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Game/CarSprite.ts: -------------------------------------------------------------------------------- 1 | module Game { 2 | export class CarSprite { 3 | private sprite: Drawing.Sprite; 4 | private frame: number; 5 | private playedDeath: boolean; 6 | private finishedDeath: boolean; 7 | constructor(gl: WebGLRenderingContext, managers: Managers.ManagerSet) { 8 | this.sprite = managers.Graphics.get3DSprite(gl, managers, managers.Textures.getTexture(gl, "CARS.LZS")); 9 | this.sprite.VHigh.x = 1.0; 10 | this.sprite.VHigh.y = 0.0; 11 | 12 | this.sprite.ULow.y = 0.0; 13 | this.sprite.UHigh.x = 0.0; 14 | 15 | this.sprite.Size.x = 30; 16 | this.sprite.Size.y = this.sprite.Texture.Width; 17 | this.sprite.State.EnableDepthTest = true; 18 | this.frame = 0; 19 | this.playedDeath = false; 20 | this.finishedDeath = false; 21 | } 22 | 23 | public updateAnimation(snap: GameSnapshot, level: Levels.Level): void { 24 | this.frame++; 25 | } 26 | 27 | public updatePosition(snap: GameSnapshot, level: Levels.Level): void { 28 | var frame = Math.max(0, this.frame - 1); 29 | 30 | this.sprite.Position.x = snap.Position.x - 95 - this.sprite.Size.x / 2; 31 | this.sprite.Position.y = 102 - (snap.Position.y - 80) - this.sprite.Texture.Width; 32 | this.sprite.Position.z = -(snap.Position.z) * 46.0 + 1.0; 33 | 34 | var minX = 95, maxX = 417; 35 | var xp = (snap.Position.x - minX) / (maxX - minX); 36 | var idx = 14 + Math.floor(xp * 7) * 9 + frame % 3; 37 | 38 | var gravityAccel = level.getGravityAcceleration(); 39 | if (snap.Velocity.y > -gravityAccel * 4) { 40 | idx += 3; 41 | } else if (snap.Velocity.y < gravityAccel * 4) { 42 | idx += 6; 43 | } 44 | 45 | if (snap.CraftState === ShipState.Exploded) { 46 | if (!this.playedDeath) { 47 | this.playedDeath = true; 48 | this.frame = 0; 49 | frame = 0; 50 | } 51 | 52 | var deathFNum = 14; 53 | idx = Math.min(deathFNum, Math.floor(frame / 2.0)); 54 | if (idx === deathFNum) { 55 | this.finishedDeath = true; 56 | } 57 | } 58 | 59 | this.sprite.ULow.y = idx * 30 / this.sprite.Texture.Height; 60 | this.sprite.UHigh.y = ((idx + 1) * 30 - 1) / this.sprite.Texture.Height; 61 | } 62 | 63 | public draw(view: TSM.mat4, cam: Engine.CameraState): void { 64 | if (!this.finishedDeath) { 65 | this.sprite.ModelMatrix.setIdentity(); 66 | view.copy(this.sprite.ViewMatrix); 67 | cam.ProjectionMatrix.copy(this.sprite.ProjectionMatrix); 68 | 69 | this.sprite.draw(); 70 | } 71 | } 72 | 73 | public hasAnimationFinished(): boolean { 74 | return this.finishedDeath; 75 | } 76 | } 77 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Game/Controller.ts: -------------------------------------------------------------------------------- 1 | module Game { 2 | export class ControllerState { 3 | constructor(turn: number, accel: number, jump: boolean) { 4 | if (turn >= -1 && turn <= 1) { 5 | this.TurnInput = turn; 6 | } else { 7 | throw "Invalid TurnInput"; 8 | } 9 | 10 | if (accel >= -1 && accel <= 1) { 11 | this.AccelInput = accel; 12 | } else { 13 | throw "Invalid accel"; 14 | } 15 | 16 | this.JumpInput = jump; 17 | } 18 | 19 | public TurnInput: number; 20 | public AccelInput: number; 21 | public JumpInput: boolean; 22 | } 23 | 24 | export interface Controller { 25 | update(ship: Position): ControllerState; 26 | } 27 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Game/DemoController.ts: -------------------------------------------------------------------------------- 1 | module Game { 2 | export class DemoController implements Controller { 3 | private static TilePositionToDemoPosition: number = 0x10000 / 0x666; 4 | 5 | private demo: Uint8Array; 6 | constructor(demo: Uint8Array) { 7 | this.demo = demo; 8 | } 9 | 10 | public update(ship: Position): ControllerState { 11 | var idx = Math.floor(ship.getZPosition() * DemoController.TilePositionToDemoPosition); 12 | if (idx >= this.demo.length) 13 | return new ControllerState(0, 0, false); 14 | var val = this.demo[idx]; 15 | 16 | return new ControllerState(((val >> 2) & 3) - 1, (val & 3) - 1, ((val >> 4) & 1) > 0); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Game/Events/ShipBouncedEvent.ts: -------------------------------------------------------------------------------- 1 | module Game.ShipEvents { 2 | export class ShipBouncedEvent { 3 | } 4 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Game/Events/ShipBumpedWallEvent.ts: -------------------------------------------------------------------------------- 1 | module Game.ShipEvents { 2 | export class ShipBumpedWallEvent { 3 | } 4 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Game/Events/ShipExplodedEvent.ts: -------------------------------------------------------------------------------- 1 | module Game.ShipEvents { 2 | export class ShipExplodedEvent { 3 | } 4 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Game/Events/ShipRefilledEvent.ts: -------------------------------------------------------------------------------- 1 | module Game.ShipEvents { 2 | export class ShipRefilledEvent { 3 | } 4 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Game/FPMath.ts: -------------------------------------------------------------------------------- 1 | module Game { 2 | export class FPMath { 3 | public round32(n: number): number { 4 | return Math.floor(n * 0x10000) / 0x10000; 5 | } 6 | 7 | public round16(n: number): number { 8 | return Math.floor(n * 0x80) / 0x80; 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Game/FixedRateSnapshotProvider.ts: -------------------------------------------------------------------------------- 1 |  module Game { 2 | export class FixedRateSnapshotProvider implements GameSnapshotProvider { 3 | private snapshot: GameSnapshot = null; 4 | 5 | reset(): void { 6 | this.snapshot = null; 7 | } 8 | 9 | pushSnapshot(s: GameSnapshot): void { 10 | this.snapshot = s; 11 | } 12 | 13 | getSnapshot(): GameSnapshot { 14 | return this.snapshot; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Game/GameSnapshot.ts: -------------------------------------------------------------------------------- 1 | module Game { 2 | export class GameSnapshot { 3 | public Position: TSM.vec3; 4 | public Velocity: TSM.vec3; 5 | public CraftState: ShipState; 6 | public OxygenPercent: number; 7 | public FuelPercent: number; 8 | public JumpOMasterInUse: boolean; 9 | public JumpOMasterVelocityDelta: number; 10 | } 11 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Game/GameSnapshotProvider.ts: -------------------------------------------------------------------------------- 1 | module Game { 2 | export interface GameSnapshotProvider { 3 | reset(): void; 4 | pushSnapshot(s: GameSnapshot): void; 5 | getSnapshot(): GameSnapshot; 6 | } 7 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Game/InterpolatingSnapshotProvider.ts: -------------------------------------------------------------------------------- 1 | module Game { 2 | export class InterpolatingSnapshoptProvider { 3 | private first: GameSnapshot = null; 4 | private firstTime: number; 5 | private second: GameSnapshot = null; 6 | private secondTime: number; 7 | 8 | private tempState = new GameSnapshot(); 9 | 10 | reset(): void { 11 | this.first = null; 12 | this.second = null; 13 | this.tempState.Position = new TSM.vec3(); 14 | this.tempState.Velocity = new TSM.vec3(); 15 | } 16 | 17 | pushSnapshot(s: GameSnapshot): void { 18 | this.second = this.first; 19 | this.secondTime = this.firstTime; 20 | 21 | this.first = s; 22 | this.firstTime = Date.now(); 23 | } 24 | 25 | getSnapshot(): GameSnapshot { 26 | if (this.second === null) { 27 | return this.first; 28 | } 29 | 30 | var timeSince = Date.now() - this.firstTime; 31 | var percent = Math.max(0, Math.min(1.0, timeSince / (this.firstTime - this.secondTime))); 32 | 33 | var first = this.first; 34 | var second = this.second; 35 | var temp = this.tempState; 36 | temp.CraftState = first.CraftState; 37 | temp.FuelPercent = first.FuelPercent; 38 | temp.JumpOMasterInUse = first.JumpOMasterInUse; 39 | temp.JumpOMasterVelocityDelta = first.JumpOMasterVelocityDelta; 40 | temp.OxygenPercent = first.OxygenPercent; 41 | temp.Position = first.Position.copy().subtract(second.Position).scale(percent).add(second.Position); 42 | temp.Velocity = first.Velocity.copy().subtract(second.Velocity).scale(percent).add(second.Velocity); 43 | 44 | return temp; 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Game/KeyboardController.ts: -------------------------------------------------------------------------------- 1 | module Game { 2 | export class ControlSourceController implements Controller { 3 | private static TilePositionToDemoPosition: number = 0x10000 / 0x666; 4 | 5 | private controlSource: Controls.ControlSource; 6 | constructor(source: Controls.ControlSource) { 7 | this.controlSource = source; 8 | } 9 | 10 | public update(ship: Position): ControllerState { 11 | return new ControllerState(this.controlSource.getTurnAmount(), this.controlSource.getAccelAmount(), this.controlSource.getJump()); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Game/StateManager.ts: -------------------------------------------------------------------------------- 1 | module Game { 2 | function sFloor(n: number) { 3 | var s = n >= 0 ? 1 : -1; 4 | return Math.floor(n * s) * s; 5 | } 6 | 7 | export class StateManager { 8 | private level: Levels.Level = null; 9 | private controller: Controller = null; 10 | 11 | private current: Ship; 12 | private expected: Ship; 13 | 14 | public didWin: boolean = false; 15 | 16 | constructor(managers: Managers.ManagerSet, level: Levels.Level, controller: Controller) { 17 | this.level = level; 18 | this.controller = controller; 19 | 20 | this.resetStateVars(); 21 | } 22 | 23 | private resetStateVars(): void { 24 | this.current = new Ship({ 25 | xPosition: 0x8000 / 0x80, 26 | yPosition: 0x2800 / 0x80, 27 | zPosition: 3.0, 28 | 29 | slideAmount: 0, 30 | slidingAccel: 0, 31 | xMovementBase: 0, 32 | yVelocity: 0, 33 | zVelocity: 0, 34 | 35 | offsetAtWhichNotInsideTile: 0, 36 | 37 | isOnGround: true, 38 | isOnDecelPad: false, 39 | isOnSlidingTile: false, 40 | isGoingUp: false, 41 | 42 | fuelRemaining: 0x7530, 43 | oxygenRemaining: 0x7530, 44 | 45 | jumpedFromYPosition: 0, 46 | 47 | state: ShipState.Alive, 48 | 49 | hasRunJumpOMaster: false, 50 | jumpOMasterInUse: false, 51 | jumpOMasterVelocityDelta: 0 52 | }); 53 | 54 | this.expected = this.current.clone(); 55 | } 56 | 57 | public getLevel() { 58 | return this.level; 59 | } 60 | 61 | public runFrame(eventBus: Events.EventBus): GameSnapshot { 62 | var controls = this.controller.update(this.current); 63 | this.current.update(this.level, this.expected, controls, eventBus); 64 | 65 | 66 | 67 | if (this.current.getZPosition() >= this.level.getLength() - 0.5 && this.level.isInsideTunnel(this.current.getXPosition(), this.current.getYPosition(), this.current.getZPosition())) { 68 | this.didWin = true; 69 | } 70 | 71 | var result = new GameSnapshot(); 72 | result.Position = new TSM.vec3([this.current.getXPosition(), this.current.getYPosition(), this.current.getZPosition()]); 73 | result.Velocity = new TSM.vec3([0.0, 0.0, this.current.getZVelocity() + this.current.getJumpOMasterVelocityDelta()]); 74 | result.CraftState = this.current.getState(); 75 | result.FuelPercent = this.current.getFuelRemaining() / 0x7530; 76 | result.OxygenPercent = this.current.getOxygenRemaining() / 0x7530; 77 | result.JumpOMasterInUse = this.current.getJumpOMasterInUse(); 78 | result.JumpOMasterVelocityDelta = this.current.getJumpOMasterVelocityDelta(); 79 | return result; 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Images/Preloader.ts: -------------------------------------------------------------------------------- 1 | module Images { 2 | export class Preloader { 3 | public preloadData(gl: WebGLRenderingContext, managers: Managers.ManagerSet): void { 4 | this.compress(managers, 'OXY_DISP.DAT'); 5 | this.compress(managers, 'FUL_DISP.DAT'); 6 | this.compress(managers, 'SPEED.DAT'); 7 | this.compress(managers, 'PROGRESS_INDICATOR'); 8 | 9 | managers.Sounds.getMultiEffect('SFX.SND'); 10 | ['CARS.LZS', 'DASHBRD.LZS', 'GOMENU.LZS', 'HELPMENU.LZS', 'INTRO.LZS', 'MAINMENU.LZS', 'SETMENU.LZS', 11 | 'WORLD0.LZS', 'WORLD1.LZS', 'WORLD2.LZS', 'WORLD3.LZS', 'WORLD4.LZS', 'WORLD5.LZS', 'WORLD6.LZS', 'WORLD7.LZS', 'WORLD8.LZS', 'WORLD9.LZS'] 12 | .map((fname) => managers.Textures.getTexture(gl, fname)); 13 | } 14 | 15 | private compress(managers: Managers.ManagerSet, name: string) { 16 | var parts = managers.Textures.getImages(name); 17 | var combinedParts: ImageFragment[] = parts.map((part, idx) => this.compressPart(managers, parts, idx)); 18 | managers.Textures.setImages(name, combinedParts); 19 | } 20 | 21 | private compressPart(managers: Managers.ManagerSet, parts: ImageFragment[], upTo: number): ImageFragment { 22 | var minX = Infinity, maxX = -Infinity; 23 | var minY = Infinity, maxY = -Infinity; 24 | for (var i = 0; i <= upTo; i++) { 25 | var p = parts[i]; 26 | minX = Math.min(p.XOffset, minX); 27 | maxX = Math.max(p.XOffset + p.Canvas.width, maxX); 28 | minY = Math.min(p.YOffset, minY); 29 | maxY = Math.max(p.YOffset + p.Canvas.height, maxY); 30 | } 31 | 32 | var cvs = managers.Canvas.getCanvas(); 33 | cvs.width = maxX - minX; 34 | cvs.height = maxY - minY; 35 | 36 | var ctx = cvs.getContext('2d'); 37 | for (var i = 0; i <= upTo; i++) { 38 | var p = parts[i]; 39 | ctx.drawImage(p.Canvas, p.XOffset - minX, p.YOffset - minY); 40 | } 41 | 42 | return new ImageFragment(cvs, parts[0].Palette, minX, minY); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Levels/Level.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"Level.js","sourceRoot":"","sources":["Level.ts"],"names":["Levels","Levels.Level","Levels.Level.constructor"],"mappings":"AAAA,yCAAyC;AACzC,IAAO,MAAM;AAeZ,CAfD,UAAO,MAAM;IACTA;QAMIC,eAAYA,OAAeA,EAAEA,IAAYA,EAAEA,MAAcA,EAAEA,MAAoBA,EAAEA,KAAeA;YAC5FC,IAAIA,CAACA,OAAOA,GAAGA,OAAOA;YACtBA,IAAIA,CAACA,IAAIA,GAAGA,IAAIA;YAChBA,IAAIA,CAACA,MAAMA,GAAGA,MAAMA;YACpBA,IAAIA,CAACA,MAAMA,GAAGA,MAAMA;YACpBA,IAAIA,CAACA,KAAKA,GAAGA,KAAKA;QACtBA,CAACA;QACLD,aAACA;IAADA,CAACA,IAAAD;IAbDA,qBAaCA;AACLA,CAACA,2BAAA"} -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Levels/LevelToTableRenderer.ts: -------------------------------------------------------------------------------- 1 | module Levels { 2 | interface lookup { 3 | [idx: string]: string; 4 | } 5 | export class LevelToTableRenderer { 6 | convertColors(l: Level): HTMLTableElement { 7 | var table: HTMLTableElement = document.createElement('table'); 8 | var row: HTMLTableRowElement = table.insertRow(-1); 9 | for (var i: number = 0; i < l.Colors.length; i++) { 10 | var cell: HTMLTableCellElement = row.insertCell(-1); 11 | cell.style.backgroundColor = l.Colors[i].toCss(); 12 | cell.style.color = l.Colors[i].negative().toCss(); 13 | cell.innerHTML = '' + i; 14 | } 15 | 16 | return table; 17 | } 18 | 19 | convert(l: Level): HTMLTableElement { 20 | //Color(0): No tile 21 | //Color(128): Slidey gray 22 | //Color(160): Accelerator 23 | //Color(10): Accelerator 24 | //Color(12): Kill 25 | var labels: lookup = { 26 | '1': '1', //Tunnel 27 | '2': '2', //Raised by one whole unit (must jump) 28 | '4': '3', //Raised by two units 29 | '8': '4', 30 | '16': '5', 31 | '32': '6', 32 | '64': '7', 33 | '128': '8' 34 | }; 35 | function assignColors(el: HTMLElement, cols: CubeColors) { 36 | el.style.color = cols.Top.negative().toCss(); 37 | el.style.backgroundColor = cols.Top.toCss(); 38 | el.style.borderRight = el.style.borderLeft = '1px solid ' + cols.Front.toCss(); 39 | el.style.borderTop = '1px solid ' + cols.Left.toCss(); 40 | el.style.borderBottom = '1px solid ' + cols.Right.toCss(); 41 | } 42 | 43 | var table: HTMLTableElement = document.createElement('table'); 44 | table.className = 'debugTable'; 45 | for (var x = 0; x < l.width(); x++) { 46 | var row: HTMLTableRowElement = table.insertRow(-1); 47 | 48 | for (var y = 0; y < l.length(); y++) { 49 | var cell: Cell = l.Cells[x][y]; 50 | var ttcell = row.insertCell(-1); 51 | var tcell = document.createElement('div'); 52 | ttcell.appendChild(tcell); 53 | tcell.innerHTML = ' '; 54 | tcell.style.backgroundColor = '#000'; 55 | tcell.style.color = '#000'; 56 | tcell.style.width = '100px'; 57 | if (cell.Tile != null) { 58 | assignColors(tcell, cell.Tile.Colors); 59 | tcell.innerHTML = '' + cell.CI; 60 | } 61 | if (cell.Tunnel != null) { 62 | var tDiv = document.createElement('div'); 63 | tDiv.innerHTML = 'T'; 64 | tDiv.style.display = 'inline-block'; 65 | tDiv.style.backgroundColor = cell.Tunnel.TunnelColors[3].toCss(); 66 | tDiv.style.color = cell.Tunnel.TunnelColors[3].negative().toCss(); 67 | tcell.appendChild(tDiv); 68 | } 69 | if (cell.Cube != null) { 70 | var cDiv = document.createElement('div'); 71 | cDiv.style.display = 'inline-block'; 72 | assignColors(cDiv, cell.Cube.Colors); 73 | cDiv.innerHTML = 'C' + cell.Cube.Height; 74 | tcell.appendChild(cDiv); 75 | } 76 | } 77 | } 78 | return table; 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Levels/Loader.js: -------------------------------------------------------------------------------- 1 | var Levels; 2 | (function (Levels) { 3 | var LevelLoader = (function () { 4 | function LevelLoader(levelNumber, levelStartByte, levelSize) { 5 | this.levelNumber = levelNumber; 6 | this.levelStartByte = levelStartByte; 7 | this.levelSize = levelSize; 8 | } 9 | LevelLoader.prototype.load = function (stream) { 10 | stream.setPosition(this.levelStartByte * 8); 11 | var reader = new Data.BinaryReader(stream); 12 | var gravity = reader.getUint16(); 13 | var fuel = reader.getUint16(); 14 | var oxygen = reader.getUint16(); 15 | 16 | var colors = []; 17 | for (var i = 0; i < 72; i++) { 18 | colors.push(new Data.Color(reader.getUint8() * 4, reader.getUint8() * 4, reader.getUint8() * 4)); 19 | } 20 | 21 | var bytes = []; 22 | var stream2 = new Data.BinaryReader(new Data.CompressedByteStream(reader)); 23 | for (var i = 0; i < this.levelSize; i++) { 24 | bytes.push(stream2.getUint8()); 25 | } 26 | 27 | var levelWidth = 7, levelLength = bytes.length / 2 / levelWidth; 28 | 29 | var level = new Levels.Level(this.levelNumber > 0 ? 'Level ' + this.levelNumber : 'Demo Level', gravity, fuel, oxygen, colors); 30 | var cells = []; 31 | for (var x = 0; x < levelWidth; x++) { 32 | var col = []; 33 | cells.push(col); 34 | for (var y = 0; y < levelLength; y++) { 35 | var idx = x * 2 + y * 14; 36 | var colorLow = bytes[idx] & 0xF, colorHigh = bytes[idx] >> 4, color = colorLow || colorHigh; 37 | col.push(new Levels.Cell(level, colorLow, colorHigh, bytes[idx], bytes[idx + 1])); 38 | } 39 | } 40 | level.Cells = cells; 41 | return level; 42 | }; 43 | return LevelLoader; 44 | })(); 45 | Levels.LevelLoader = LevelLoader; 46 | 47 | var MultiLevelLoader = (function () { 48 | function MultiLevelLoader(stream) { 49 | this.Levels = []; 50 | var reader = new Data.BinaryReader(stream); 51 | var l1Start = reader.getUint16(), l1Size = reader.getUint16(); 52 | var level1StartBit = l1Start * 8; 53 | 54 | var levels = []; 55 | levels.push(new LevelLoader(0, l1Start, l1Size)); 56 | for (var i = 0; stream.getPosition() < level1StartBit; i++) { 57 | levels.push(new LevelLoader(i + 1, reader.getUint16(), reader.getUint16())); 58 | } 59 | 60 | for (var i = 0; i < levels.length; i++) { 61 | this.Levels.push(levels[i].load(stream)); 62 | } 63 | } 64 | return MultiLevelLoader; 65 | })(); 66 | Levels.MultiLevelLoader = MultiLevelLoader; 67 | })(Levels || (Levels = {})); 68 | -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Levels/Loader.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"Loader.js","sourceRoot":"","sources":["Loader.ts"],"names":["Levels","Levels.LevelLoader","Levels.LevelLoader.constructor","Levels.LevelLoader.load","Levels.MultiLevelLoader","Levels.MultiLevelLoader.constructor"],"mappings":"AAAA,6CAA6C;AAC7C,gDAAgD;AAChD,IAAO,MAAM;AAoDZ,CApDD,UAAO,MAAM;IACTA;QAKIC,qBAAYA,WAAmBA,EAAEA,cAAsBA,EAAEA,SAAiBA;YACtEC,IAAIA,CAACA,WAAWA,GAAGA,WAAWA;YAC9BA,IAAIA,CAACA,cAAcA,GAAGA,cAAcA;YACpCA,IAAIA,CAACA,SAASA,GAAGA,SAASA;QAC9BA,CAACA;QAEDD,6BAAAA,UAAYA,MAAkCA;YAC1CE,MAAMA,CAACA,WAAWA,CAACA,IAAIA,CAACA,cAAcA,GAAGA,CAACA,CAACA;YAC3CA,IAAIA,MAAMA,GAAGA,IAAIA,IAAIA,CAACA,YAAYA,CAACA,MAAMA,CAACA;YAC1CA,IAAIA,OAAOA,GAAWA,MAAMA,CAACA,SAASA,CAACA,CAACA;YACxCA,IAAIA,IAAIA,GAAWA,MAAMA,CAACA,SAASA,CAACA,CAACA;YACrCA,IAAIA,MAAMA,GAAWA,MAAMA,CAACA,SAASA,CAACA,CAACA;;YAEvCA,IAAIA,MAAMA,GAAiBA,EAAEA;YAC7BA,KAAKA,IAAIA,CAACA,GAAGA,CAACA,EAAEA,CAACA,GAAGA,EAAEA,EAAEA,CAACA,EAAEA,CAAEA;gBACzBA,MAAMA,CAACA,IAAIA,CAACA,IAAIA,IAAIA,CAACA,KAAKA,CAACA,MAAMA,CAACA,QAAQA,CAACA,CAACA,GAAGA,CAACA,EAAEA,MAAMA,CAACA,QAAQA,CAACA,CAACA,GAAGA,CAACA,EAAEA,MAAMA,CAACA,QAAQA,CAACA,CAACA,GAAGA,CAACA,CAACA,CAACA;aACnGA;;YAEDA,IAAIA,KAAKA,GAAaA,EAAEA;YACxBA,IAAIA,OAAOA,GAAGA,IAAIA,IAAIA,CAACA,YAAYA,CAACA,IAAIA,IAAIA,CAACA,oBAAoBA,CAACA,MAAMA,CAACA,CAACA;YAC1EA,KAAKA,IAAIA,CAACA,GAAGA,CAACA,EAAEA,CAACA,GAAGA,IAAIA,CAACA,SAASA,EAAEA,CAACA,EAAEA,CAAEA;gBACrCA,KAAKA,CAACA,IAAIA,CAACA,OAAOA,CAACA,QAAQA,CAACA,CAACA,CAACA;aACjCA;;YAEDA,OAAOA,IAAIA,YAAKA,CAACA,OAAOA,EAAEA,IAAIA,EAAEA,MAAMA,EAAEA,MAAMA,EAAEA,KAAKA,CAACA;QAC1DA,CAACA;QACLF,mBAACA;IAADA,CAACA,IAAAD;IA/BDA,iCA+BCA;IACDA;QAEII,0BAAYA,MAAkCA;YAD9CC,KAAOA,MAAMA,GAAYA,EAAEA,CAACA;YAExBA,IAAIA,MAAMA,GAAGA,IAAIA,IAAIA,CAACA,YAAYA,CAACA,MAAMA,CAACA;YAC1CA,IAAIA,OAAOA,GAAWA,MAAMA,CAACA,SAASA,CAACA,CAACA,EACpCA,MAAMA,GAAWA,MAAMA,CAACA,SAASA,CAACA,CAACA;YACvCA,IAAIA,oBAAoBA,GAAGA,OAAOA,GAAGA,CAACA;;YAEtCA,IAAIA,MAAMA,GAAkBA,EAAEA;YAC9BA,MAAMA,CAACA,IAAIA,CAACA,IAAIA,WAAWA,CAACA,CAACA,EAAEA,OAAOA,EAAEA,MAAMA,CAACA,CAACA;YAChDA,KAAKA,IAAIA,CAACA,GAAWA,CAACA,EAAEA,CAACA,GAAGA,oBAAoBA,EAAEA,CAACA,EAAEA,CAAEA;gBACnDA,MAAMA,CAACA,IAAIA,CAACA,IAAIA,WAAWA,CAACA,CAACA,GAAGA,CAACA,EAAEA,OAAOA,EAAEA,MAAMA,CAACA,CAACA;aACvDA;;YAEDA,KAAKA,IAAIA,CAACA,GAAWA,CAACA,EAAEA,CAACA,GAAGA,MAAMA,CAACA,MAAMA,EAAEA,CAACA,EAAEA,CAAEA;gBAC5CA,IAAIA,CAACA,MAAMA,CAACA,IAAIA,CAACA,MAAMA,CAACA,CAACA,CAACA,CAACA,IAAIA,CAACA,MAAMA,CAACA,CAACA;aAC3CA;QACLA,CAACA;QACLD,wBAACA;IAADA,CAACA,IAAAJ;IAlBDA,2CAkBCA;AACLA,CAACA,2BAAA"} -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Levels/Loader.ts: -------------------------------------------------------------------------------- 1 | module Levels { 2 | export class LevelLoader { 3 | private levelNumber: number; 4 | private levelStartByte: number; 5 | private levelSize: number; 6 | 7 | constructor(levelNumber: number, levelStartByte: number, levelSize: number) { 8 | this.levelNumber = levelNumber; 9 | this.levelStartByte = levelStartByte; 10 | this.levelSize = levelSize; 11 | } 12 | 13 | public load(stream: Data.RandomAccessBitStream): Level { 14 | stream.setPosition(this.levelStartByte * 8); 15 | var reader = new Data.BinaryReader(stream); 16 | var gravity: number = reader.getUint16(); 17 | var fuel: number = reader.getUint16(); 18 | var oxygen: number = reader.getUint16(); 19 | 20 | var colors: Data.Color[] = []; 21 | for (var i = 0; i < 72; i++) { 22 | colors.push(new Data.Color(reader.getUint8() * 4, reader.getUint8() * 4, reader.getUint8() * 4)); 23 | } 24 | 25 | var bytes: number[] = []; 26 | var stream2 = new Data.BinaryReader(new Data.CompressedByteStream(reader)); 27 | for (var i = 0; i < this.levelSize; i++) { 28 | bytes.push(stream2.getUint8()); 29 | } 30 | 31 | var levelWidth: number = 7, 32 | levelLength: number = bytes.length / 2 / levelWidth; 33 | 34 | var level = new Level(this.levelNumber > 0 ? 'Level ' + this.levelNumber : 'Demo Level', gravity, fuel, oxygen, colors); 35 | var cells: Cell[][] = []; 36 | for (var x: number = 0; x < levelWidth; x++) { 37 | var col: Cell[] = []; 38 | cells.push(col); 39 | for (var y: number = 0; y < levelLength; y++) { 40 | var idx = x * 2 + y * 14; 41 | var colorLow = bytes[idx] & 0xF, colorHigh = bytes[idx] >> 4, color = colorLow || colorHigh; 42 | col.push(new Cell(level,colorLow, colorHigh, bytes[idx], bytes[idx + 1])); 43 | } 44 | } 45 | level.Cells = cells; 46 | return level; 47 | } 48 | } 49 | 50 | export class MultiLevelLoader { 51 | public Levels: Level[] = []; 52 | constructor(stream: Data.RandomAccessBitStream) { 53 | var reader = new Data.BinaryReader(stream); 54 | var l1Start: number = reader.getUint16(), 55 | l1Size: number = reader.getUint16(); 56 | var level1StartBit = l1Start * 8; 57 | 58 | var levels: LevelLoader[] = []; 59 | levels.push(new LevelLoader(0, l1Start, l1Size)); 60 | for (var i: number = 0; stream.getPosition() < level1StartBit; i++) { 61 | levels.push(new LevelLoader(i + 1, reader.getUint16(), reader.getUint16())); 62 | } 63 | 64 | for (var i: number = 0; i < levels.length; i++) { 65 | this.Levels.push(levels[i].load(stream)); 66 | } 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Managers/ManagerSet.ts: -------------------------------------------------------------------------------- 1 | module Managers { 2 | export class ManagerSet { 3 | public Streams: StreamManager; 4 | public Shaders: ShaderManager; 5 | public Textures: TextureManager; 6 | public Sounds: SoundManager; 7 | public Frames: Engine.FrameManager; 8 | public Controls: Controls.ControlSource; 9 | public Settings: Managers.SettingsManager; 10 | public Graphics: Shaders.ShaderProvider; 11 | public Canvas: Drawing.CanvasProvider; 12 | public Audio: Sounds.AudioProvider; 13 | public VR: VR.VRProvider; 14 | public SnapshotProvider: Game.GameSnapshotProvider; 15 | 16 | constructor(streams: StreamManager, shaders: ShaderManager) { 17 | this.Streams = streams; 18 | this.Shaders = shaders; 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Managers/SettingsManager.ts: -------------------------------------------------------------------------------- 1 | module Managers { 2 | export class Setting { 3 | private name: string; 4 | private value: T; 5 | private store: Stores.KVStore; 6 | constructor(store: Stores.KVStore, name: string, defaultValue: T) { 7 | this.store = store; 8 | this.name = name; 9 | this.value = JSON.parse(store.getValue(name) || JSON.stringify(defaultValue)); 10 | } 11 | 12 | public getValue(): T { 13 | return this.value; 14 | } 15 | 16 | public setValue(val: T) { 17 | this.value = val; 18 | this.store.setValue(this.name, JSON.stringify(val)); 19 | } 20 | } 21 | 22 | export class NumberSetting extends Setting { 23 | constructor(store: Stores.KVStore, name: string, defaultValue: number) { 24 | super(store, name, defaultValue); 25 | } 26 | } 27 | 28 | export class BooleanSetting extends Setting { 29 | constructor(store: Stores.KVStore, name: string, defaultValue: boolean) { 30 | super(store, name, defaultValue); 31 | } 32 | } 33 | 34 | 35 | export class SettingsManager { 36 | public MonitorIdx: NumberSetting; 37 | 38 | public EffectVolume: NumberSetting; 39 | public MusicVolume: NumberSetting; 40 | public MenuDistance: NumberSetting; 41 | public MenuSize: NumberSetting; 42 | 43 | public UseInterpolation: BooleanSetting; 44 | public EnableVSync: BooleanSetting; 45 | 46 | public WorldScale: NumberSetting; 47 | public HudScale: NumberSetting; 48 | public HudHeight: NumberSetting; 49 | public HudDist: NumberSetting; 50 | public ShowHud: BooleanSetting; 51 | public EyeHeight: NumberSetting; 52 | public VRDistanceFromShip: NumberSetting; 53 | public BackgroundScale: NumberSetting; 54 | 55 | private store: Stores.KVStore; 56 | 57 | constructor(store: Stores.KVStore) { 58 | this.store = store; 59 | this.MonitorIdx = new NumberSetting(store, 'monitorIdx', 0); 60 | this.EffectVolume = new NumberSetting(store, 'effectVolume', 0.5); 61 | this.MusicVolume = new NumberSetting(store, 'musicVolume', 0.5); 62 | this.MenuDistance = new NumberSetting(store, 'menuDistance', 1.6); 63 | this.MenuSize = new NumberSetting(store, 'menuSize', 1.0); 64 | 65 | this.UseInterpolation = new BooleanSetting(store, 'useInterpolation', true); 66 | this.EnableVSync = new BooleanSetting(store, 'useVsync', true); 67 | 68 | this.WorldScale = new NumberSetting(store, 'worldScale', 44.0); 69 | this.HudScale = new NumberSetting(store, 'hudScale', 0.21); 70 | this.HudHeight = new NumberSetting(store, 'hudPosHeight', 46.6); 71 | this.HudDist = new NumberSetting(store, 'hudPosDist', 33.0); 72 | this.EyeHeight = new NumberSetting(store, 'eyeHeight', 154.0); 73 | this.VRDistanceFromShip = new NumberSetting(store, 'eyeDistance', 1.76); 74 | this.ShowHud = new BooleanSetting(store, 'showHud', true); 75 | 76 | this.BackgroundScale = new NumberSetting(store, 'backgroundScale', 3456.0); 77 | } 78 | 79 | public wonLevelCount(levelNum: number): number { 80 | var c = this.store.getValue('wonlevel_' + levelNum); 81 | return parseInt(c) || 0; 82 | } 83 | 84 | public incrementWonLevelCount(levelNum: number): void { 85 | this.store.setValue('wonlevel_' + levelNum, '' + (this.wonLevelCount(levelNum) + 1)); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Managers/ShaderManager.ts: -------------------------------------------------------------------------------- 1 | module Managers { 2 | export class ShaderManager { 3 | private shaders: { [s: string]: WGL.Shader } = {}; 4 | public Shaders = { 5 | Basic2D: 'basic_2d.', 6 | TitleEffect2D: 'title_2d.', 7 | Color3D: 'color_3d.', 8 | TexturedPerspective: 'texture_p3d.', 9 | Sprite3D: 'sprite_3d.' 10 | }; 11 | 12 | private streamManager: StreamManager; 13 | constructor(streamManager: StreamManager) { 14 | this.streamManager = streamManager; 15 | } 16 | 17 | public getShader(gl: WebGLRenderingContext, shaderName: string) { 18 | if (!(shaderName in this.shaders)) { 19 | this.shaders[shaderName] = new WGL.Shader(gl, this.streamManager.getText(shaderName + 'vs'), this.streamManager.getText(shaderName + 'fs')); 20 | } 21 | return this.shaders[shaderName]; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Managers/SoundManager.ts: -------------------------------------------------------------------------------- 1 | module Managers { 2 | export class SoundManager { 3 | private sounds: { [s: string]: Sounds.SoundEffect } = {}; 4 | private multiSounds: { [s: string]: Sounds.SoundEffect[] } = {}; 5 | public Sounds = { 6 | Intro: 'INTRO.SND' 7 | }; 8 | 9 | private streamManager: StreamManager; 10 | private managers: ManagerSet; 11 | constructor(managers: ManagerSet) { 12 | this.streamManager = managers.Streams; 13 | this.managers = managers; 14 | } 15 | 16 | public getSound(soundName: string) { 17 | soundName = soundName.toUpperCase(); 18 | if (!(soundName in this.sounds)) { 19 | this.sounds[soundName] = new Sounds.SoundEffect(this.managers, this.streamManager.getStream(soundName)); 20 | } 21 | return this.sounds[soundName]; 22 | } 23 | 24 | public getMultiEffect(soundName: string): Sounds.SoundEffect[] { 25 | soundName = soundName.toUpperCase(); 26 | if (!(soundName in this.multiSounds)) { 27 | 28 | var data = this.streamManager.getStream(soundName); 29 | var reader = new Data.BinaryReader(data); 30 | var sfx: Sounds.SoundEffect[] = []; 31 | var starts = [reader.getUint16()]; 32 | for (var i = 4; i < starts[0]; i += 2) { 33 | starts.push(reader.getUint16()); 34 | } 35 | 36 | for (var i = 0; i < starts.length; i++) { 37 | if (i < starts.length - 1) { 38 | sfx.push(new Sounds.SoundEffect(this.managers, data, starts[i], starts[i + 1])); 39 | } else { 40 | sfx.push(new Sounds.SoundEffect(this.managers, data, starts[i])); 41 | } 42 | } 43 | this.multiSounds[soundName] = sfx; 44 | } 45 | return this.multiSounds[soundName]; 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Managers/StreamManager.ts: -------------------------------------------------------------------------------- 1 | module Managers { 2 | export class StreamManager { 3 | private streams: { [s: string]: Uint8Array } = {}; 4 | private filterBasePath: string = 'Data/'; 5 | private basePath: string = 'Data/'; 6 | private provider: Stores.FileProvider; 7 | 8 | constructor(provider: Stores.FileProvider, basePath: string = 'Data/') { 9 | this.provider = provider; 10 | this.basePath = basePath; 11 | } 12 | 13 | load(filename: string): P.Promise { 14 | var p = P.defer(); 15 | this.provider.load(filename.replace(this.filterBasePath, this.basePath), (result) => { 16 | this.streams[filename.toUpperCase().split('/')[1]] = result; 17 | p.resolve(result); 18 | }); 19 | 20 | return p.promise(); 21 | } 22 | 23 | loadMultiple(filenames: string[]): P.Promise { 24 | var promises = filenames.map((f) => this.load(f)); 25 | return P.when.apply(null, promises); 26 | } 27 | 28 | getStream(filename: string) { 29 | filename = filename.toUpperCase(); 30 | if (!(filename in this.streams)) { 31 | throw filename + " not loaded"; 32 | } 33 | return new Data.ArrayBitStream(this.streams[filename]); 34 | } 35 | 36 | getRawArray(filename: string): Uint8Array { 37 | filename = filename.toUpperCase(); 38 | if (!(filename in this.streams)) { 39 | throw filename + " not loaded"; 40 | } 41 | return this.streams[filename]; 42 | } 43 | 44 | getText(filename: string) { 45 | filename = filename.toUpperCase(); 46 | if (!(filename in this.streams)) { 47 | throw filename + " not loaded"; 48 | } 49 | return String.fromCharCode.apply(null, this.streams[filename]); 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Managers/TextureManager.ts: -------------------------------------------------------------------------------- 1 | module Managers { 2 | export class TextureManager { 3 | private managers: ManagerSet; 4 | private streamManager: StreamManager; 5 | private textures: { [s: string]: Drawing.TextureFragment[][] } = {}; 6 | private images: { [s: string]: Images.ImageFragment[][] } = {}; 7 | 8 | constructor(managers: Managers.ManagerSet) { 9 | this.managers = managers; 10 | this.streamManager = managers.Streams; 11 | } 12 | 13 | public getImage(filename: string): Images.ImageFragment { 14 | return this.getImages(filename)[0]; 15 | } 16 | 17 | public getImages(filename: string): Images.ImageFragment[] { 18 | filename = filename.toUpperCase(); 19 | if (!(filename in this.images)) { 20 | var images: Images.ImageFragment[] = null; 21 | 22 | var stream = this.streamManager.getStream(filename); 23 | if (filename.split('.')[1].toUpperCase() == 'LZS') { 24 | var imgLoader = new Images.ImageSetLoader(this.managers); 25 | images = imgLoader.load(stream); 26 | } else { 27 | var datLoader = new Images.DatLoader(this.managers); 28 | images = datLoader.load(stream); 29 | } 30 | this.images[filename] = [images]; 31 | } 32 | return this.images[filename][0]; 33 | } 34 | 35 | public getTexture(gl: WebGLRenderingContext, filename: string): Drawing.TextureFragment { 36 | return this.getTextures(gl, filename)[0]; 37 | } 38 | 39 | public getTextures(gl: WebGLRenderingContext, filename: string): Drawing.TextureFragment[]{ 40 | filename = filename.toUpperCase(); 41 | if (!(filename in this.textures)) { 42 | this.textures[filename] = [this.imageFragmentsToTextureFragments(gl, this.getImages(filename))]; 43 | } 44 | return this.textures[filename][0]; 45 | } 46 | 47 | public getAnim(gl: WebGLRenderingContext, filename: string): Drawing.TextureFragment[][]{ 48 | filename = filename.toUpperCase(); 49 | if (!(filename in this.textures)) { 50 | var stream = this.streamManager.getStream(filename); 51 | var loader = new Images.AnimLoader(this.managers); 52 | var anim = loader.load(stream); 53 | this.textures[filename] = anim.map((images) => this.imageFragmentsToTextureFragments(gl, images)); 54 | } 55 | return this.textures[filename]; 56 | } 57 | 58 | public setImages(filename: string, imgs: Images.ImageFragment[]): void { 59 | this.images[filename] = [imgs]; 60 | } 61 | 62 | private imageFragmentsToTextureFragments(gl: WebGLRenderingContext, imgs: Images.ImageFragment[]): Drawing.TextureFragment[]{ 63 | return imgs.map((img) => { 64 | var tex = new WGL.Texture(gl); 65 | tex.loadData(img.Canvas); 66 | tex.setFilters(gl.NEAREST, gl.NEAREST); 67 | return new Drawing.TextureFragment(tex, img.XOffset, img.YOffset, img.Canvas.width, img.Canvas.height); 68 | }); 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/RefPhysics/RefShip.ts: -------------------------------------------------------------------------------- 1 | module RefPhysics { 2 | export interface Position { 3 | getXPosition(): number; 4 | getYPosition(): number; 5 | getZPosition(): number; 6 | } 7 | 8 | export class Ship implements Position { 9 | private xPosition: number; 10 | private yPosition: number; 11 | private zPosition: number; 12 | constructor(xPosition: number, yPosition: number, zPosition: number) { 13 | this.xPosition = xPosition; 14 | this.yPosition = yPosition; 15 | this.zPosition = zPosition; 16 | } 17 | 18 | public getXPosition(): number { 19 | return this.xPosition; 20 | } 21 | 22 | public getYPosition(): number { 23 | return this.yPosition; 24 | } 25 | 26 | public getZPosition(): number { 27 | return this.zPosition; 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Shaders/ClassicShaderProvider.ts: -------------------------------------------------------------------------------- 1 | module Shaders { 2 | export class ClassicShaderProvider implements ShaderProvider { 3 | get2DSprite(gl: WebGLRenderingContext, managers: Managers.ManagerSet, texture: Drawing.TextureFragment): Drawing.Sprite { 4 | return new Drawing.Sprite(gl, managers, texture); 5 | } 6 | 7 | get3DSprite(gl: WebGLRenderingContext, managers: Managers.ManagerSet, texture: Drawing.TextureFragment): Drawing.Sprite { 8 | return new Drawing.Sprite(gl, managers, texture); 9 | } 10 | 11 | getMesh(gl: WebGLRenderingContext, managers: Managers.ManagerSet, vertices: Vertices.Vertex3DC[]): Drawing.Mesh { 12 | return new Drawing.Mesh(gl, managers, vertices); 13 | } 14 | 15 | getState2DDrawer(gl: WebGLRenderingContext): Engine.ClassicState2DDrawer { 16 | return new Engine.ClassicState2DDrawer(); 17 | } 18 | 19 | getState3DDrawer(gl: WebGLRenderingContext): Engine.ClassicState3DDrawer { 20 | return new Engine.ClassicState3DDrawer(); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Shaders/ShaderProvider.ts: -------------------------------------------------------------------------------- 1 | module Shaders { 2 | export interface ShaderProvider { 3 | get2DSprite(gl: WebGLRenderingContext, managers: Managers.ManagerSet, texture: Drawing.TextureFragment): Drawing.Sprite; 4 | get3DSprite(gl: WebGLRenderingContext, managers: Managers.ManagerSet, texture: Drawing.TextureFragment): Drawing.Sprite; 5 | getMesh(gl: WebGLRenderingContext, managers: Managers.ManagerSet, vertices: Vertices.Vertex3DC[]): Drawing.Mesh; 6 | getState2DDrawer(gl: WebGLRenderingContext, managers: Managers.ManagerSet): Engine.State2DDrawer; 7 | getState3DDrawer(gl: WebGLRenderingContext, managers: Managers.ManagerSet): Engine.State3DDrawer; 8 | } 9 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Shaders/VRShaderProvider.ts: -------------------------------------------------------------------------------- 1 | module Shaders { 2 | export class VRShaderProvider implements ShaderProvider { 3 | get2DSprite(gl: WebGLRenderingContext, managers: Managers.ManagerSet, texture: Drawing.TextureFragment): Drawing.Sprite { 4 | return new Drawing.Sprite(gl, managers, texture); 5 | } 6 | 7 | get3DSprite(gl: WebGLRenderingContext, managers: Managers.ManagerSet, texture: Drawing.TextureFragment): Drawing.Sprite { 8 | return new Drawing.Sprite(gl, managers, texture, managers.Shaders.getShader(gl, managers.Shaders.Shaders.Sprite3D)); 9 | } 10 | 11 | getMesh(gl: WebGLRenderingContext, managers: Managers.ManagerSet, vertices: Vertices.Vertex3DC[]): Drawing.Mesh { 12 | return new Drawing.Mesh(gl, managers, vertices, managers.Shaders.getShader(gl, managers.Shaders.Shaders.TexturedPerspective)); 13 | } 14 | 15 | getState2DDrawer(gl: WebGLRenderingContext, managers: Managers.ManagerSet): Engine.ClassicState2DDrawer { 16 | return new Engine.VRState2DDrawer(managers); 17 | } 18 | 19 | getState3DDrawer(gl: WebGLRenderingContext, managers: Managers.ManagerSet): Engine.ClassicState3DDrawer { 20 | return new Engine.VRState3DDrawer(managers); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Sounds/AudioProvider.ts: -------------------------------------------------------------------------------- 1 | module Sounds { 2 | export interface AudioProvider { 3 | createPlayable(buffer: Float32Array): Playable; 4 | playSong(n: number): void; 5 | setEffectsGain(gain: number): void; 6 | setMusicGain(gain: number): void; 7 | } 8 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Sounds/ChildProcessAudioProvider.ts: -------------------------------------------------------------------------------- 1 | module Sounds { 2 | export declare class ChildProcess { 3 | send(data: any): void; 4 | } 5 | 6 | class ChildProcessPlayable implements Playable { 7 | private id: number; 8 | private worker: ChildProcess; 9 | 10 | constructor(id: number, worker: ChildProcess) { 11 | this.id = id; 12 | this.worker = worker; 13 | } 14 | 15 | play(): void { 16 | try { 17 | this.worker.send(new PlayPlayableCommand(this.id)); 18 | } catch (ex) { 19 | console.log('Audio exception on play'); 20 | console.log(ex); 21 | } 22 | } 23 | } 24 | 25 | class ChildProcessDummyPlayable implements Playable { 26 | play(): void { 27 | } 28 | } 29 | 30 | export class ChildProcessAudioProvider implements AudioProvider { 31 | private worker: ChildProcess; 32 | private static pId = 0; 33 | 34 | constructor(worker: ChildProcess) { 35 | this.worker = worker; 36 | } 37 | 38 | createPlayable(buffer: Float32Array): Playable { 39 | var id = ChildProcessAudioProvider.pId; 40 | ChildProcessAudioProvider.pId++; 41 | 42 | try { 43 | var playable = new ChildProcessPlayable(id, this.worker); 44 | this.worker.send(new CreatePlayableCommand(id, buffer)); 45 | return playable; 46 | } catch (ex) { 47 | console.log('Audio exception on createPlayable'); 48 | console.log(ex); 49 | return new ChildProcessDummyPlayable(); 50 | } 51 | } 52 | 53 | playSong(n: number): void { 54 | try { 55 | this.worker.send(new PlaySongCommand(n)); 56 | } catch (ex) { 57 | console.log('Audio exception on playSong'); 58 | console.log(n); 59 | } 60 | } 61 | 62 | setEffectsGain(gain: number): void { 63 | try { 64 | this.worker.send(new SetEffectGainCommand(gain)); 65 | } catch (ex) { 66 | console.log('Audio exception on setGain'); 67 | console.log(ex); 68 | } 69 | } 70 | 71 | setMusicGain(gain: number): void { 72 | try { 73 | this.worker.send(new SetMusicGainCommand(gain)); 74 | } catch (ex) { 75 | console.log('Audio exception on setGain'); 76 | console.log(ex); 77 | } 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Sounds/ChildProcessAudioServer.ts: -------------------------------------------------------------------------------- 1 | module Sounds { 2 | var playSongCommand = 'PlaySong'; 3 | var createPlayableCommand = 'CreatePlayable'; 4 | var playPlayableCommand = 'PlayPlayable'; 5 | var setEffectGainCommand = 'SetEGain'; 6 | var setMusicGainCommand = 'SetMGain'; 7 | 8 | export class SetEffectGainCommand { 9 | private Command: string = setEffectGainCommand; 10 | public Gain: number; 11 | 12 | constructor(gain: number) { 13 | this.Gain = gain; 14 | } 15 | } 16 | 17 | export class SetMusicGainCommand { 18 | private Command: string = setMusicGainCommand; 19 | public Gain: number; 20 | 21 | constructor(gain: number) { 22 | this.Gain = gain; 23 | } 24 | } 25 | 26 | export class PlaySongCommand { 27 | private Command: string = playSongCommand; 28 | public SongNumber: number = 0; 29 | 30 | constructor(songNumber: number) { 31 | this.SongNumber = songNumber; 32 | } 33 | } 34 | 35 | export class CreatePlayableCommand { 36 | private Command: string = createPlayableCommand; 37 | public Buffer: Float32Array; 38 | public Id: number; 39 | constructor(id: number, buffer: Float32Array) { 40 | this.Id = id; 41 | this.Buffer = buffer; 42 | } 43 | } 44 | 45 | export class PlayPlayableCommand { 46 | private Command: string = playPlayableCommand; 47 | public Id: number; 48 | constructor(id: number) { 49 | this.Id = id; 50 | } 51 | } 52 | 53 | declare class ProcessCommand { 54 | Command: string; 55 | } 56 | 57 | declare class Process { 58 | on(eventName: string, cb: (event: ProcessCommand) => void): void; 59 | } 60 | 61 | declare var process: Process; 62 | 63 | export class ChildProcessAudioServer { 64 | private provider: LowLevelAudioProvider; 65 | private musicPlayer: Music.Player; 66 | private playables: { [idx: number]: Playable } = {}; 67 | 68 | constructor(baseProvider: LowLevelAudioProvider, musicPlayer: Music.Player) { 69 | this.provider = baseProvider; 70 | this.musicPlayer = musicPlayer; 71 | 72 | process.on('message', (evt) => { 73 | switch (evt.Command) { 74 | case playSongCommand: 75 | var psEvt = evt; 76 | this.musicPlayer.loadSong(psEvt.SongNumber); 77 | break; 78 | case createPlayableCommand: 79 | var cpEvt = evt; 80 | var p = this.provider.createPlayable(cpEvt.Buffer); 81 | this.playables[cpEvt.Id] = p; 82 | break; 83 | case playPlayableCommand: 84 | var ppEvt = evt; 85 | if (ppEvt.Id in this.playables) { 86 | this.playables[ppEvt.Id].play(); 87 | } 88 | break; 89 | case setEffectGainCommand: 90 | var sgEvt = evt; 91 | this.provider.setEffectsGain(sgEvt.Gain); 92 | break; 93 | case setMusicGainCommand: 94 | var smEvt = evt; 95 | this.musicPlayer.setGain(smEvt.Gain); 96 | break; 97 | } 98 | }); 99 | } 100 | } 101 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Sounds/InThreadAudioProvider.ts: -------------------------------------------------------------------------------- 1 | module Sounds { 2 | export class InThreadAudioProvider implements AudioProvider { 3 | private base: LowLevelAudioProvider; 4 | private player: Music.Player; 5 | 6 | constructor(base: LowLevelAudioProvider, player: Music.Player) { 7 | this.base = base; 8 | this.player = player; 9 | } 10 | 11 | createPlayable(buffer: Float32Array): Playable { 12 | return this.base.createPlayable(buffer); 13 | } 14 | 15 | playSong(n: number): void { 16 | this.player.loadSong(n); 17 | } 18 | 19 | setEffectsGain(gain: number): void { 20 | this.base.setEffectsGain(gain); 21 | } 22 | 23 | setMusicGain(gain: number): void { 24 | this.player.setGain(gain); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Sounds/LowLevelAudioProvider.ts: -------------------------------------------------------------------------------- 1 | module Sounds { 2 | export interface Playable { 3 | play(): void; 4 | } 5 | 6 | export interface PlayerAudioSource { 7 | fillAudioBuffer(buffer: Float32Array): boolean; 8 | } 9 | 10 | export interface LowLevelAudioProvider { 11 | createPlayable(buffer: Float32Array): Playable; 12 | runPlayer(player: PlayerAudioSource, useGain: boolean): void; 13 | setEffectsGain(gain: number): void; 14 | } 15 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Sounds/Sound.ts: -------------------------------------------------------------------------------- 1 | module Sounds { 2 | export class SoundEffect { 3 | private playable: Sounds.Playable; 4 | private managers: Managers.ManagerSet; 5 | constructor(managers: Managers.ManagerSet, stream: Data.ArrayBitStream, start: number = 0, end: number = 0) { 6 | 7 | this.managers = managers; 8 | 9 | var numBytes = (end || stream.getLength() / 8) - start; 10 | stream.setPosition(start * 8); 11 | var reader = new Data.BinaryReader(stream); 12 | 13 | 14 | var scaledLength = Math.floor(numBytes * 44100 / 8000); 15 | 16 | var bufferArr = new Float32Array(numBytes); 17 | for (var i = 0; i < numBytes; i++) { 18 | bufferArr[i] = (reader.getUint8() - 127) / 128.0; 19 | } 20 | 21 | var scaledBufferArr = new Float32Array(scaledLength); 22 | for (var i = 0; i < scaledBufferArr.length; i++) { 23 | scaledBufferArr[i] = bufferArr[Math.floor(i * numBytes / scaledLength)]; 24 | } 25 | 26 | this.playable = managers.Audio.createPlayable(scaledBufferArr); 27 | } 28 | 29 | public play(): void { 30 | this.playable.play(); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Sounds/WebAPIAudioProvider.ts: -------------------------------------------------------------------------------- 1 | module Sounds { 2 | class WebAPIPlayable implements Playable { 3 | private ctx: AudioContext; 4 | private dst: AudioNode; 5 | private buffer: AudioBuffer; 6 | 7 | constructor(ctx: AudioContext, buff: Float32Array, dst: AudioNode) { 8 | if (ctx) { 9 | var buffer = ctx.createBuffer(1, buff.length, 44100); 10 | buffer.getChannelData(0).set(buff); 11 | 12 | this.ctx = ctx; 13 | this.buffer = buffer; 14 | this.dst = dst; 15 | } 16 | } 17 | 18 | play(): void { 19 | if (this.ctx) { 20 | var source: AudioBufferSourceNode = this.ctx.createBufferSource(); 21 | source.buffer = this.buffer; 22 | source.connect(this.dst); 23 | source.start(0); 24 | } 25 | } 26 | } 27 | 28 | export class WebAPIAudioProvider implements LowLevelAudioProvider { 29 | private ctx: AudioContext; 30 | private dest: GainNode; 31 | private players: PlayerAudioSource[] = []; 32 | private playerNodes: ScriptProcessorNode[] = []; 33 | 34 | constructor(ctx: AudioContext) { 35 | this.ctx = ctx; 36 | if (this.ctx) { 37 | this.dest = ctx.createGain(); 38 | this.dest.gain.value = 0.0; 39 | this.dest.connect(ctx.destination); 40 | } 41 | } 42 | 43 | createPlayable(buffer: Float32Array): Playable { 44 | return new WebAPIPlayable(this.ctx, buffer, this.dest); 45 | } 46 | 47 | runPlayer(player: PlayerAudioSource, useGain: boolean): void { 48 | if (this.ctx) { 49 | var node = this.ctx.createScriptProcessor(1024, 1, 1); 50 | node.onaudioprocess = (evt: Event) => player.fillAudioBuffer((evt).outputBuffer.getChannelData(0)); 51 | node.connect(useGain ? this.dest : this.ctx.destination); 52 | this.players.push(player); 53 | this.playerNodes.push(node); 54 | } 55 | } 56 | 57 | setEffectsGain(gain: number): void { 58 | if (this.ctx) { 59 | this.dest.gain.value = gain; 60 | } 61 | } 62 | }; 63 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/States/EmptyState.ts: -------------------------------------------------------------------------------- 1 | module States { 2 | export class EmptyState implements Engine.GameState { 3 | private managers: Managers.ManagerSet; 4 | 5 | constructor(managers: Managers.ManagerSet) { 6 | this.managers = managers; 7 | } 8 | 9 | load(gl: WebGLRenderingContext): void { 10 | var managers = this.managers; 11 | } 12 | 13 | unload(): void { 14 | } 15 | 16 | 17 | 18 | updatePhysics(frameManager: Engine.FrameManager, frameTimeInfo: Engine.FrameTimeInfo): void { 19 | } 20 | 21 | drawFrame(gl: WebGLRenderingContext, canvas: HTMLCanvasElement, frameManager: Engine.FrameManager, frameTimeInfo: Engine.FrameTimeInfo): void { 22 | var helper = new ClassicGLStateHelper(); 23 | helper.startFrame(gl, canvas); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/States/FadeState2D.ts: -------------------------------------------------------------------------------- 1 | module States { 2 | export class Fade2D extends Engine.State2D implements Engine.GameState { 3 | private myManagers: Managers.ManagerSet; 4 | private position: number; 5 | private direction: number; 6 | private drawState: Engine.State2D; 7 | private back: Drawing.Sprite; 8 | private firstFrame: boolean; 9 | 10 | constructor(managers: Managers.ManagerSet, start: number, drawState: Engine.State2D, runPhysicsFirst: boolean) { 11 | super(managers); 12 | this.myManagers = managers; 13 | this.position = start; 14 | this.direction = start > 0.5 ? -1.0 : 1.0; 15 | this.drawState = drawState; 16 | this.firstFrame = runPhysicsFirst; 17 | } 18 | 19 | load(gl: WebGLRenderingContext): void { 20 | super.load(gl); 21 | 22 | var blackTex = new WGL.Texture(gl); 23 | var cvs = this.myManagers.Canvas.getCanvas(); 24 | cvs.width = 32; 25 | cvs.height = 32; 26 | 27 | 28 | var ctx = cvs.getContext('2d'); 29 | ctx.fillStyle = '#000000'; 30 | ctx.fillRect(0, 0, cvs.width, cvs.height); 31 | 32 | blackTex.loadData(cvs); 33 | blackTex.setFilters(gl.NEAREST, gl.NEAREST); 34 | 35 | var blackFrag = new Drawing.TextureFragment(blackTex, 0, 0, 320, 200); 36 | this.back = new Drawing.Sprite(gl, this.myManagers, blackFrag); 37 | this.back.Alpha = 1.0 - this.position; 38 | } 39 | 40 | unload(): void { 41 | 42 | } 43 | 44 | updatePhysics(frameManager: Engine.FrameManager, frameTimeInfo: Engine.FrameTimeInfo): void { 45 | this.position += this.direction * frameTimeInfo.getPhysicsStep(); 46 | if (this.position <= 0.0 || this.position >= 1.0) { 47 | frameManager.popState(); 48 | } else { 49 | this.back.Alpha = 1.0 - this.position; 50 | } 51 | if (this.firstFrame) { 52 | this.drawState.updatePhysics(frameManager, frameTimeInfo); 53 | this.firstFrame = false; 54 | } 55 | } 56 | 57 | drawFrame2D(gl: WebGLRenderingContext, canvas: HTMLCanvasElement, frameManager: Engine.FrameManager, frameTimeInfo: Engine.FrameTimeInfo, cam: Engine.CameraState): void { 58 | this.drawState.drawFrame2D(gl, canvas, frameManager, frameTimeInfo, cam); 59 | this.back.draw(); 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/States/FadeState3D.ts: -------------------------------------------------------------------------------- 1 | module States { 2 | //TODO: Refactor out the common logic between Fade3D and Fade2D 3 | export class Fade3D extends Engine.State3D implements Engine.GameState { 4 | private myManagers: Managers.ManagerSet; 5 | private position: number; 6 | private direction: number; 7 | private drawState: Engine.State3D; 8 | private back: Drawing.Sprite; 9 | private firstFrame: boolean; 10 | 11 | constructor(managers: Managers.ManagerSet, start: number, drawState: Engine.State3D, runPhysicsFirst: boolean) { 12 | super(managers); 13 | this.myManagers = managers; 14 | this.position = start; 15 | this.direction = start > 0.5 ? -1.0 : 1.0; 16 | this.drawState = drawState; 17 | this.firstFrame = runPhysicsFirst; 18 | } 19 | 20 | load(gl: WebGLRenderingContext): void { 21 | super.load(gl); 22 | 23 | var blackTex = new WGL.Texture(gl); 24 | var cvs = this.myManagers.Canvas.getCanvas(); 25 | cvs.width = 32; 26 | cvs.height = 32; 27 | 28 | 29 | var ctx = cvs.getContext('2d'); 30 | ctx.fillStyle = '#000000'; 31 | ctx.fillRect(0, 0, cvs.width, cvs.height); 32 | 33 | blackTex.loadData(cvs); 34 | blackTex.setFilters(gl.NEAREST, gl.NEAREST); 35 | 36 | var blackFrag = new Drawing.TextureFragment(blackTex, 0, 0, 320, 200); 37 | this.back = new Drawing.Sprite(gl, this.myManagers, blackFrag); 38 | this.back.Alpha = 1.0 - this.position; 39 | } 40 | 41 | unload(): void { 42 | 43 | } 44 | 45 | updatePhysics(frameManager: Engine.FrameManager, frameTimeInfo: Engine.FrameTimeInfo): void { 46 | this.position += this.direction * frameTimeInfo.getPhysicsStep(); 47 | if (this.position <= 0.0 || this.position >= 1.0) { 48 | frameManager.popState(); 49 | } else { 50 | this.back.Alpha = 1.0 - this.position; 51 | } 52 | if (this.firstFrame) { 53 | this.drawState.updatePhysics(frameManager, frameTimeInfo); 54 | this.firstFrame = false; 55 | } 56 | } 57 | 58 | drawFrame3D(gl: WebGLRenderingContext, canvas: HTMLCanvasElement, frameManager: Engine.FrameManager, frameTimeInfo: Engine.FrameTimeInfo, cam: Engine.CameraState): void { 59 | this.drawState.drawFrame3D(gl, canvas, frameManager, frameTimeInfo, cam); 60 | this.back.draw(); 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/States/GLStateHelper.ts: -------------------------------------------------------------------------------- 1 | module States { 2 | export class ClassicGLStateHelper { 3 | constructor() { 4 | } 5 | 6 | public startFrame(gl: WebGLRenderingContext, canvas: HTMLCanvasElement) { 7 | var bw = canvas.width, bh = canvas.height; 8 | var w = 320, h = 200, ratio = w / h; 9 | var cw = Math.min(bw, bh * ratio), ch = cw / ratio; 10 | var ox = bw / 2 - cw / 2, oy = bh / 2 - ch / 2; 11 | gl.viewport(Math.floor(ox), Math.floor(oy), Math.floor(cw), Math.floor(ch)); 12 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 13 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 14 | } 15 | } 16 | 17 | export class VRGLStateHelper { 18 | private vr: VR.VRProvider; 19 | constructor(vrProvider: VR.VRProvider) { 20 | this.vr = vrProvider; 21 | } 22 | 23 | public startFrame(gl: WebGLRenderingContext) { 24 | var fb = this.vr.getTargetFboId(gl); 25 | gl.bindFramebuffer(gl.FRAMEBUFFER, fb); 26 | var sz = this.vr.getTargetResolution(); 27 | gl.viewport(0, 0, sz.x, sz.y); 28 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 29 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 30 | } 31 | 32 | public startEye(gl: WebGLRenderingContext, eyeNum: number) { 33 | this.vr.startEye(eyeNum); 34 | var vp = this.vr.getEyeViewport(eyeNum); 35 | gl.viewport(vp.x, vp.y, vp.z, vp.w); 36 | } 37 | 38 | public endEye(gl: WebGLRenderingContext, eyeNum: number) { 39 | this.vr.endEye(eyeNum); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/States/HelpState.ts: -------------------------------------------------------------------------------- 1 | module States { 2 | export class Help extends Engine.State2D implements Engine.GameState { 3 | private myManagers: Managers.ManagerSet; 4 | private frames: Drawing.Sprite[]; 5 | private watchers: Controls.ConditionWatcher[] = []; 6 | private frameNum: number = 0; 7 | private fadeDir: number = 0; 8 | 9 | constructor(managers: Managers.ManagerSet) { 10 | super(managers); 11 | this.myManagers = managers; 12 | } 13 | 14 | load(gl: WebGLRenderingContext): void { 15 | super.load(gl); 16 | var managers = this.myManagers; 17 | this.frames = managers.Textures.getTextures(gl, "HELPMENU.LZS").map((tf) => new Drawing.Sprite(gl, managers, tf)); 18 | 19 | var controls = this.myManagers.Controls; 20 | this.watchers.push(new Controls.ConditionWatcher(() => controls.getExit(), () => this.exit())); 21 | this.watchers.push(new Controls.ConditionWatcher(() => controls.getEnter(), () => this.next())); 22 | } 23 | 24 | unload(): void { 25 | } 26 | 27 | private exit(): void { 28 | this.myManagers.Frames.popState(); 29 | } 30 | 31 | private next(): void { 32 | if (this.frameNum === this.frames.length - 1) { 33 | this.myManagers.Frames.popState(); 34 | } else { 35 | this.fadeDir = -1.0; 36 | } 37 | } 38 | 39 | updatePhysics(frameManager: Engine.FrameManager, frameTimeInfo: Engine.FrameTimeInfo): void { 40 | for (var i = 0; i < this.watchers.length; i++) { 41 | this.watchers[i].update(frameTimeInfo); 42 | } 43 | this.frames[this.frameNum].Brightness += this.fadeDir * frameTimeInfo.getPhysicsStep(); 44 | if (this.frames[this.frameNum].Brightness <= 0.0) { 45 | this.frames[this.frameNum].Brightness = 0.0; 46 | this.frameNum++; 47 | this.frames[this.frameNum].Brightness = 0.0; 48 | this.fadeDir = 1.0; 49 | } else if (this.frames[this.frameNum].Brightness >= 1.0) { 50 | this.frames[this.frameNum].Brightness = 1.0; 51 | this.fadeDir = 0.0; 52 | } 53 | } 54 | 55 | drawFrame2D(gl: WebGLRenderingContext, canvas: HTMLCanvasElement, frameManager: Engine.FrameManager, frameTimeInfo: Engine.FrameTimeInfo): void { 56 | this.frames[this.frameNum].draw(); 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Storage/AJAXFileProvider.ts: -------------------------------------------------------------------------------- 1 | module Stores { 2 | export class AJAXFileProvider implements FileProvider { 3 | public load(filename: string, cb: (data: Uint8Array) => void): void { 4 | var oReq = new XMLHttpRequest(); 5 | oReq.open("GET", filename, true); 6 | oReq.responseType = "arraybuffer"; 7 | oReq.onload = (oEvent) => { 8 | var arrayBuffer = oReq.response; 9 | var result = new Uint8Array(arrayBuffer); 10 | cb(result); 11 | }; 12 | oReq.send(null); 13 | } 14 | }; 15 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Storage/FSStore.ts: -------------------------------------------------------------------------------- 1 | module Stores { 2 | export class FSStore implements KVStore { 3 | private filename: string; 4 | private fs: any; 5 | private opts: { [s: string]: string } = {}; 6 | constructor(prefix: string) { 7 | this.filename = 'Data/settings-' + prefix + '.json'; 8 | this.fs = require('fs'); 9 | try { 10 | this.opts = JSON.parse(this.fs.readFileSync(this.filename, 'utf-8')); 11 | } catch (e) { 12 | } 13 | } 14 | 15 | public getValue(k: string): string { 16 | return (k in this.opts) ? this.opts[k] : null; 17 | } 18 | 19 | public setValue(k: string, v: string): void { 20 | this.opts[k] = v; 21 | this.fs.writeFileSync(this.filename, JSON.stringify(this.opts)); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Storage/FileProvider.ts: -------------------------------------------------------------------------------- 1 | module Stores { 2 | export interface FileProvider { 3 | load(filename: string, cb: (data: Uint8Array) => void): void; 4 | }; 5 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Storage/KVStore.ts: -------------------------------------------------------------------------------- 1 | module Stores { 2 | export interface KVStore { 3 | setValue(k: string, v: string): void; 4 | getValue(k: string): string; 5 | } 6 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Storage/LocalFileProvider.ts: -------------------------------------------------------------------------------- 1 | module Stores { 2 | export class LocalFileProvider implements FileProvider { 3 | private fs: any; 4 | 5 | constructor() { 6 | this.fs = require('fs'); 7 | } 8 | 9 | public load(filename: string, cb: (data: Uint8Array) => void): void { 10 | this.fs.readFile(filename, function (err: any, data: any) { 11 | cb(data); 12 | }); 13 | } 14 | }; 15 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Storage/LocalStorageStore.ts: -------------------------------------------------------------------------------- 1 | module Stores { 2 | export class LocalStorageStore implements KVStore { 3 | private prefix: string; 4 | constructor(prefix: string) { 5 | this.prefix = prefix; 6 | } 7 | 8 | setValue(k: string, v: string): void { 9 | localStorage.setItem(this.prefix + '-' + k, v); 10 | } 11 | getValue(k: string): string { 12 | return localStorage.getItem(this.prefix + '-' + k); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/TestRuns/TestCar.ts: -------------------------------------------------------------------------------- 1 | module TestRuns { 2 | export function TestCar(): void { 3 | var manager = new Managers.StreamManager(new Stores.AJAXFileProvider()), shaderManager = new Managers.ShaderManager(manager); 4 | var managers = new Managers.ManagerSet(manager, shaderManager); 5 | managers.Sounds = new Managers.SoundManager(managers); 6 | managers.Textures = new Managers.TextureManager(managers); 7 | 8 | manager.loadMultiple(["Data/CARS.LZS"]).done(() => { 9 | var cvs = document.getElementById('cvs'); 10 | cvs.style.display = 'block'; 11 | cvs.width = 320; 12 | cvs.height = 200; 13 | cvs.style.width = '640px'; 14 | cvs.style.height = '400px'; 15 | cvs.style.position = 'static'; 16 | var isl = new Images.ImageSetLoader(managers); 17 | var car = isl.load(managers.Streams.getStream('Data/CARS.LZS'))[0]; 18 | 19 | var ctx = cvs.getContext('2d'); 20 | var ix = 0; 21 | var bin = document.createElement('input'); 22 | bin.value = '0'; 23 | document.body.appendChild(bin); 24 | var top = document.createElement('input'); 25 | top.value = '3'; 26 | document.body.appendChild(top); 27 | var f = 0; 28 | function drawFrame() { 29 | var base = parseInt(bin.value) || 0; 30 | var num = parseInt(top.value) || 3; 31 | f++; 32 | 33 | if (f % 2 == 0) { 34 | ix = ((ix + 1) % num); 35 | } 36 | 37 | ctx.setTransform(1, 0, 0, 1, 0, 0); 38 | ctx.fillStyle = '#000000'; 39 | ctx.fillRect(0, 0, 1000, 1000); 40 | ctx.translate(160, 100); 41 | ctx.rotate(Math.PI / 2.0); 42 | ctx.drawImage(car.Canvas, car.XOffset, (ix + base) * 30, car.Canvas.width, 30, 0, 0, car.Canvas.width, 30); 43 | requestAnimationFrame(drawFrame); 44 | } 45 | requestAnimationFrame(drawFrame); 46 | }); 47 | } 48 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/TestRuns/TestDats.ts: -------------------------------------------------------------------------------- 1 | module TestRuns { 2 | export function TestDats() { 3 | function loadStream(name: string, cb: (bs: Data.ArrayBitStream) => void) { 4 | var oReq = new XMLHttpRequest(); 5 | oReq.open("GET", name, true); 6 | oReq.responseType = "arraybuffer"; 7 | oReq.onload = function (oEvent) { 8 | var arrayBuffer = oReq.response; // Note: not oReq.responseText 9 | cb(new Data.ArrayBitStream((new Uint8Array(arrayBuffer)))); 10 | }; 11 | oReq.send(null); 12 | } 13 | 14 | var managers: Managers.ManagerSet = null; 15 | 16 | loadStream('Data/WORLD0.LZS', function (backBS) { 17 | loadStream('Data/DASHBRD.LZS', function (dashBS) { 18 | loadStream('Data/OXY_DISP.DAT', function (dat1BS) { 19 | loadStream('Data/FUL_DISP.DAT', function (dat2BS) { 20 | loadStream('Data/SPEED.DAT', function (dat3BS) { 21 | var back = new Images.ImageSetLoader(managers).load(backBS)[0]; 22 | var dash = new Images.ImageSetLoader(managers).load(dashBS)[0]; 23 | var oxys = [new Images.DatLoader(managers).load(dat1BS), new Images.DatLoader(managers).load(dat2BS), new Images.DatLoader(managers).load(dat3BS)]; 24 | 25 | var canvas = document.createElement('canvas'); 26 | canvas.width = 320; 27 | canvas.height = 200; 28 | 29 | document.body.appendChild(canvas); 30 | 31 | var ctx: CanvasRenderingContext2D = canvas.getContext('2d'); 32 | 33 | var i = 0; 34 | function drawFrame() { 35 | ctx.clearRect(0, 0, canvas.width, canvas.height); 36 | ctx.drawImage(back.Canvas, 0, 0); 37 | ctx.drawImage(dash.Canvas, dash.XOffset, dash.YOffset); 38 | 39 | for (var k = 0; k < oxys.length; k++) { 40 | var oxy = oxys[k]; 41 | for (var j = 0; j < (i % oxy.length + 1); j++) { 42 | ctx.drawImage(oxy[j].Canvas, oxy[j].XOffset, oxy[j].YOffset); 43 | } 44 | } 45 | 46 | requestAnimationFrame(drawFrame); 47 | } 48 | setInterval(function () { 49 | i++; 50 | }, 500); 51 | requestAnimationFrame(drawFrame); 52 | }); 53 | }); 54 | }); 55 | }); 56 | }); 57 | } 58 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/TestRuns/TestImages.ts: -------------------------------------------------------------------------------- 1 | module TestRuns { 2 | export function TestAnims() { 3 | function loadStream(name: string, cb: (bs: Data.ArrayBitStream) => void) { 4 | var oReq = new XMLHttpRequest(); 5 | oReq.open("GET", name, true); 6 | oReq.responseType = "arraybuffer"; 7 | oReq.onload = function (oEvent) { 8 | var arrayBuffer = oReq.response; // Note: not oReq.responseText 9 | cb(new Data.ArrayBitStream((new Uint8Array(arrayBuffer)))); 10 | }; 11 | oReq.send(null); 12 | } 13 | 14 | 15 | var managers: Managers.ManagerSet = null; 16 | var f = 'Data/SETMENU.LZS'; 17 | loadStream(f, function (bsIntro) { 18 | loadStream(f, function (bsAnim) { 19 | var parts = new Images.ImageSetLoader(managers).load(bsIntro); 20 | var anim = new Images.ImageSetLoader(managers).load(bsAnim); 21 | var canvas = document.createElement('canvas'); 22 | canvas.width = 320; 23 | canvas.height = 200; 24 | document.body.appendChild(canvas); 25 | 26 | var i = 0; 27 | var ctx: CanvasRenderingContext2D = canvas.getContext('2d'); 28 | 29 | function drawFrame() { 30 | ctx.fillStyle = '#000000'; 31 | ctx.fillRect(0, 0, canvas.width, canvas.height); 32 | document.title = 'IMG: ' + i; 33 | ctx.drawImage(parts[i].Canvas, parts[i].XOffset, parts[i].YOffset); 34 | requestAnimationFrame(drawFrame); 35 | } 36 | requestAnimationFrame(drawFrame); 37 | setInterval(function () { 38 | i = (i + 1) % parts.length; 39 | }, 1000); 40 | }); 41 | }); 42 | }; 43 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/TestRuns/TestLevels.ts: -------------------------------------------------------------------------------- 1 | module TestRuns { 2 | export function TestLevel() { 3 | var oReq = new XMLHttpRequest(); 4 | oReq.open("GET", "Data/ROADS.LZS", true); 5 | oReq.responseType = "arraybuffer"; 6 | 7 | oReq.onload = function (oEvent) { 8 | var arrayBuffer = oReq.response; // Note: not oReq.responseText 9 | if (arrayBuffer) { 10 | var byteArray: any = new Uint8Array(arrayBuffer); 11 | var ll = new Levels.MultiLevelLoader(new Data.ArrayBitStream(byteArray)); 12 | var lToT = new Levels.LevelToTableRenderer(); 13 | var levels = ll.Levels; 14 | for (var i = 0; i < levels.length; i++) { 15 | var l = levels[i]; 16 | var h = document.createElement('h1'); 17 | h.innerHTML = l.Name; 18 | document.body.appendChild(h); 19 | var h2 = document.createElement('h2'); 20 | h2.innerHTML = 'Gravity: ' + l.Gravity + '\tOxygen: ' + l.Oxygen + '\tFuel: ' + l.Fuel; 21 | document.body.appendChild(h2); 22 | document.body.appendChild(lToT.convertColors(l)); 23 | document.body.appendChild(lToT.convert(l)); 24 | } 25 | } 26 | }; 27 | 28 | oReq.send(null); 29 | }; 30 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/TestRuns/TestSounds.ts: -------------------------------------------------------------------------------- 1 | module TestRuns { 2 | export function TestSounds(): void { 3 | var manager = new Managers.StreamManager(new Stores.AJAXFileProvider()), shaderManager = new Managers.ShaderManager(manager); 4 | var managers = new Managers.ManagerSet(manager, shaderManager); 5 | managers.Sounds = new Managers.SoundManager(managers); 6 | manager.loadMultiple(["Data/SFX.SND"]).done(() => { 7 | var snd1 = managers.Sounds.getMultiEffect('SFX.SND'); 8 | snd1[1].play(); 9 | //0 - Mild bump but didn't explode? 10 | //1 - Bounce 11 | //2 - Explosion? 12 | //3 - Out of oxygen (or fuel) 13 | //4 - Re-fueled 14 | //5 - Nothin 15 | }); 16 | } 17 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/UI/BooleanSetting.ts: -------------------------------------------------------------------------------- 1 | module UI { 2 | export class BooleanSetting implements SettingUI { 3 | private name: string; 4 | 5 | private setting: Managers.BooleanSetting; 6 | 7 | private value: boolean; 8 | 9 | constructor(name: string, 10 | setting: Managers.BooleanSetting) { 11 | this.name = name; 12 | 13 | this.setting = setting; 14 | 15 | this.value = setting.getValue(); 16 | } 17 | 18 | public drawAndUpdate(cvs: HTMLCanvasElement, ctx: CanvasRenderingContext2D, fti: Engine.FrameTimeInfo, yPos: number, selected: boolean, action: SettingAction): void { 19 | var P = 4; 20 | 21 | var d = 0.0; 22 | if (action === SettingAction.Decrease) { 23 | d = -1.0; 24 | } else if (action === SettingAction.Increase) { 25 | d = 1.0; 26 | } 27 | 28 | if (d !== 0.0) { 29 | this.value = d < 0 ? false : true; 30 | this.setting.setValue(this.value); 31 | } 32 | 33 | var bright = selected ? '#FFFF77' : '#FFFFFF'; 34 | var dark = selected ? '#777777' : '#444444'; 35 | 36 | ctx.fillStyle = bright; 37 | ctx.font = '12pt Arial bold'; 38 | ctx.textAlign = 'center'; 39 | ctx.textBaseline = 'middle'; 40 | ctx.fillText(this.name, cvs.width / 4, yPos); 41 | 42 | var BH = 5; 43 | var X = cvs.width / 2 + P; 44 | var W = cvs.width / 2 - P * 2; 45 | ctx.fillStyle = bright; 46 | ctx.fillRect(X + (this.value ? W / 2 : 0), yPos - BH, W / 2, BH * 2); 47 | 48 | ctx.strokeStyle = bright; 49 | ctx.strokeRect(X, yPos - BH, W, BH * 2); 50 | 51 | ctx.fillStyle = this.value ? bright : dark; 52 | ctx.fillText('Off', 5 * cvs.width / 8, yPos); 53 | 54 | ctx.fillStyle = this.value ? dark : bright; 55 | ctx.fillText('On', 7 * cvs.width / 8, yPos); 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/UI/NumberSetting.ts: -------------------------------------------------------------------------------- 1 | module UI { 2 | export class NumberSetting implements SettingUI { 3 | private name: string; 4 | 5 | private min: number; 6 | private max: number; 7 | private minLabel: string; 8 | private maxLabel: string; 9 | 10 | private setting: Managers.NumberSetting; 11 | 12 | private value: number; 13 | 14 | constructor(name: string, 15 | min: number, max: number, 16 | setting: Managers.NumberSetting) { 17 | this.name = name; 18 | 19 | this.min = min; 20 | this.max = max; 21 | 22 | this.setting = setting; 23 | 24 | this.value = setting.getValue(); 25 | } 26 | 27 | public drawAndUpdate(cvs: HTMLCanvasElement, ctx: CanvasRenderingContext2D, fti: Engine.FrameTimeInfo, yPos: number, selected: boolean, action: SettingAction): void { 28 | var P = 4; 29 | 30 | var d = 0.0; 31 | if (action === SettingAction.Decrease) { 32 | d = -1.0; 33 | } else if (action === SettingAction.Increase) { 34 | d = 1.0; 35 | } 36 | 37 | if (d !== 0.0) { 38 | this.value = Math.min(this.max, Math.max(this.min, this.value + fti.getPhysicsStep() * (this.max - this.min) * d / 2.0)); 39 | this.setting.setValue(this.value); 40 | } 41 | 42 | var bright = selected ? '#FFFF77' : '#FFFFFF'; 43 | var dark = selected ? '#777777' : '#444444'; 44 | 45 | ctx.fillStyle = bright; 46 | ctx.font = '12pt Arial bold'; 47 | ctx.textAlign = 'center'; 48 | ctx.textBaseline = 'middle'; 49 | ctx.fillText(this.name, cvs.width / 4, yPos); 50 | 51 | var percent = (this.value - this.min) / (this.max - this.min); 52 | var BH = 5; 53 | ctx.fillStyle = dark; 54 | ctx.fillRect(cvs.width / 2 + P, yPos - BH, (cvs.width / 2 - P * 2), BH * 2); 55 | ctx.fillStyle = bright; 56 | ctx.fillRect(cvs.width / 2 + P, yPos - BH, (cvs.width / 2 - P * 2) * percent, BH * 2); 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/UI/Setting.ts: -------------------------------------------------------------------------------- 1 | module UI { 2 | export enum SettingAction { 3 | None, 4 | Increase, 5 | Decrease 6 | } 7 | 8 | export interface SettingUI { 9 | drawAndUpdate(cvs: HTMLCanvasElement, ctx: CanvasRenderingContext2D, fti: Engine.FrameTimeInfo, yPos: number, selected: boolean, action: SettingAction): void; 10 | } 11 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/VR/VRProvider.ts: -------------------------------------------------------------------------------- 1 | module VR { 2 | export interface VRProvider { 3 | enable(disableVsync: boolean): boolean; 4 | getTargetResolution(): TSM.vec2; 5 | getTargetFboId(gl: WebGLRenderingContext): number; 6 | getHeadCameraState(eyeNum: number): Engine.CameraState; 7 | getEyeViewport(eyeNum: number): TSM.vec4; 8 | isVRSafetyWarningVisible(): boolean; 9 | 10 | startEye(eyeNum: number): void; 11 | endEye(eyeNum: number): void; 12 | 13 | resetOrientation(): void; 14 | 15 | handlePlatformKeys(controls: Controls.ControlSource): void; 16 | 17 | exit(): void; 18 | } 19 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Vertices/Vertex2D.ts: -------------------------------------------------------------------------------- 1 | module Vertices { 2 | export class Vertex2D implements WGL.VertexObject { 3 | public static getDescriptor(gl: WebGLRenderingContext): WGL.VertexDescriptor { 4 | return new WGL.VertexDescriptor([ 5 | new WGL.VertexAttributeDescription(gl, "aPos", 2, gl.FLOAT, true, 8, 0) 6 | ]); 7 | } 8 | 9 | public X: number; 10 | public Y: number; 11 | 12 | constructor(x: number, y: number) { 13 | this.X = x; 14 | this.Y = y; 15 | } 16 | 17 | getComponent(name: String): number[]{ 18 | if (name == "aPos") { 19 | return [this.X, this.Y]; 20 | } else { 21 | throw "Bad component: " + name; 22 | } 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/Vertices/Vertex3DC.ts: -------------------------------------------------------------------------------- 1 | module Vertices { 2 | export class Vertex3DC implements WGL.VertexObject { 3 | public static getDescriptor(gl: WebGLRenderingContext): WGL.VertexDescriptor { 4 | return new WGL.VertexDescriptor([ 5 | new WGL.VertexAttributeDescription(gl, "aPos", 3, gl.FLOAT, true, 32, 0), 6 | new WGL.VertexAttributeDescription(gl, "aColor", 3, gl.FLOAT, true, 32, 12), 7 | new WGL.VertexAttributeDescription(gl, "aTexCoord", 2, gl.FLOAT, true, 32, 24) 8 | ]); 9 | } 10 | 11 | public Position: TSM.vec3; 12 | public Color: TSM.vec3; 13 | public UV: TSM.vec2; 14 | constructor(pos: TSM.vec3, color: TSM.vec3, uv: TSM.vec2 = new TSM.vec2([0.0, 0.0])) { 15 | this.Position = pos; 16 | this.Color = color; 17 | this.UV = uv; 18 | } 19 | 20 | getComponent(name: String): number[] { 21 | if (name == "aPos") { 22 | return this.Position.xyz; 23 | } else if (name == "aColor") { 24 | return this.Color.xyz; 25 | } else if (name === "aTexCoord") { 26 | return this.UV.xy; 27 | } else { 28 | throw "Bad component: " + name; 29 | } 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/WGL/Attrib.ts: -------------------------------------------------------------------------------- 1 | module WGL { 2 | export class VertexAttribute { 3 | public gl: WebGLRenderingContext; 4 | public location: number; 5 | constructor(gl: WebGLRenderingContext, location: number) { 6 | if (location == -1) { 7 | throw "Invalid attrib"; 8 | } 9 | 10 | this.gl = gl; 11 | this.location = location; 12 | } 13 | 14 | public enable() { 15 | this.gl.enableVertexAttribArray(this.location); 16 | } 17 | 18 | public disable() { 19 | this.gl.disableVertexAttribArray(this.location); 20 | } 21 | 22 | public attribPointer(size: number, type: number, normalized: boolean, stride: number, offset: number): void { 23 | this.gl.vertexAttribPointer(this.location, size, type, normalized, stride, offset); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/WGL/Buffer.ts: -------------------------------------------------------------------------------- 1 | module WGL { 2 | export class Buffer { 3 | private gl: WebGLRenderingContext; 4 | private buffer: WebGLBuffer; 5 | private bufferType: number; 6 | private size: number; 7 | 8 | constructor(gl: WebGLRenderingContext, bufferType: number = -1) { 9 | if (bufferType === -1) { 10 | bufferType = gl.ARRAY_BUFFER; 11 | } 12 | this.gl = gl; 13 | this.buffer = gl.createBuffer(); 14 | this.bufferType = bufferType; 15 | this.size = -1; 16 | } 17 | 18 | public bind(): void { 19 | this.gl.bindBuffer(this.bufferType, this.buffer); 20 | } 21 | 22 | public loadData(data: Float32Array, usage: number = -1) { 23 | if (usage === -1) { 24 | usage = this.gl.STATIC_DRAW; 25 | } 26 | this.bind(); 27 | this.gl.bufferData(this.bufferType, data, usage); 28 | this.size = data.length; 29 | } 30 | 31 | public getNumElements(): number { 32 | return this.size; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/WGL/Framebuffer.ts: -------------------------------------------------------------------------------- 1 | module WGL { 2 | export class Framebuffer { 3 | private gl: WebGLRenderingContext; 4 | 5 | private buffer: WebGLFramebuffer; 6 | 7 | 8 | constructor(gl: WebGLRenderingContext) { 9 | this.buffer = gl.createFramebuffer(); 10 | this.gl = gl; 11 | } 12 | 13 | public bind(): void { 14 | this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.buffer); 15 | } 16 | 17 | public unbind(): void { 18 | this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null); 19 | } 20 | 21 | public setTexture(tex: Texture) { 22 | this.bind(); 23 | tex.bind(); 24 | 25 | var gl = this.gl; 26 | gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex.getGLTexture(), 0); 27 | } 28 | 29 | public setRenderbuffer(rb: Renderbuffer) { 30 | this.bind(); 31 | rb.bind(); 32 | 33 | var gl = this.gl; 34 | gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rb.getGLRenderbuffer()); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/WGL/Renderable.ts: -------------------------------------------------------------------------------- 1 | module WGL { 2 | export class GLState { 3 | constructor(gl: WebGLRenderingContext) { 4 | this.BlendSrc = gl.SRC_ALPHA; 5 | this.BlendDst = gl.ONE_MINUS_SRC_ALPHA; 6 | } 7 | public EnableBlend: boolean = false; 8 | public EnableDepthTest: boolean = false; 9 | public BlendSrc: number = 0 10 | public BlendDst: number = 0; 11 | } 12 | 13 | export class Renderable { 14 | private gl: WebGLRenderingContext; 15 | public State: GLState; 16 | private vertex: VertexDescriptor; 17 | private shader: Shader; 18 | private buffer: Buffer; 19 | 20 | constructor(gl: WebGLRenderingContext, glState: GLState, vertexDescriptor: VertexDescriptor, shader: Shader, buffer: Buffer) { 21 | this.gl = gl; 22 | this.State = glState; 23 | this.vertex = vertexDescriptor; 24 | this.shader = shader; 25 | this.buffer = buffer; 26 | } 27 | 28 | 29 | public configureState(state: GLState): void { 30 | var gl = this.gl; 31 | if (state.EnableBlend) { 32 | gl.enable(gl.BLEND); 33 | } else { 34 | gl.disable(gl.BLEND); 35 | } 36 | gl.blendFunc(state.BlendSrc, state.BlendDst); 37 | 38 | if (state.EnableDepthTest) { 39 | gl.enable(gl.DEPTH_TEST); 40 | } else { 41 | gl.disable(gl.DEPTH_TEST); 42 | } 43 | } 44 | 45 | public preDraw(gl: WebGLRenderingContext, shader: Shader) { 46 | } 47 | 48 | public postDraw(gl: WebGLRenderingContext, shader: Shader) { 49 | } 50 | 51 | public draw(): void { 52 | this.buffer.bind(); 53 | this.shader.use(); 54 | this.vertex.enableAndConfigureVertexAttributes(this.shader); 55 | this.configureState(this.State); 56 | this.preDraw(this.gl, this.shader); 57 | this.vertex.drawContiguous(this.gl, this.buffer); 58 | this.postDraw(this.gl, this.shader); 59 | this.vertex.disableVertexAttributes(this.shader); 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/WGL/RenderableTexture.ts: -------------------------------------------------------------------------------- 1 | module WGL { 2 | export class RenderableTexture { 3 | public Framebuffer: Framebuffer; 4 | public Texture: Texture; 5 | 6 | constructor(fb: Framebuffer, tex: Texture) { 7 | this.Framebuffer = fb; 8 | this.Texture = tex; 9 | } 10 | 11 | public static Create(gl: WebGLRenderingContext, width: number, height: number): RenderableTexture { 12 | var fb = new Framebuffer(gl); 13 | fb.bind(); 14 | 15 | var tex = new Texture(gl); 16 | tex.createEmpty(width, height); 17 | tex.setFilters(gl.LINEAR, gl.LINEAR); 18 | tex.generateMipmap(); 19 | 20 | var rb = new Renderbuffer(gl); 21 | rb.setSize(width, height); 22 | 23 | fb.setTexture(tex); 24 | fb.setRenderbuffer(rb); 25 | 26 | rb.unbind(); 27 | tex.unbind(); 28 | fb.unbind(); 29 | 30 | return new RenderableTexture(fb, tex); 31 | } 32 | 33 | public bindForDrawing(): void { 34 | this.Framebuffer.bind(); 35 | } 36 | 37 | public unbindForDrawing(): void { 38 | this.Framebuffer.unbind(); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/WGL/Renderbuffer.ts: -------------------------------------------------------------------------------- 1 | module WGL { 2 | export class Renderbuffer { 3 | private gl: WebGLRenderingContext; 4 | private buffer: WebGLRenderbuffer; 5 | 6 | 7 | constructor(gl: WebGLRenderingContext) { 8 | this.buffer = gl.createRenderbuffer(); 9 | this.gl = gl; 10 | } 11 | 12 | public bind(): void { 13 | this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, this.buffer); 14 | } 15 | 16 | public unbind(): void { 17 | this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, null); 18 | } 19 | 20 | public setSize(width: number, height: number): void { 21 | var gl = this.gl; 22 | this.bind(); 23 | gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height); 24 | } 25 | 26 | public getGLRenderbuffer(): WebGLRenderbuffer { 27 | return this.buffer; 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/WGL/Shader.ts: -------------------------------------------------------------------------------- 1 | module WGL { 2 | export class Shader { 3 | private gl: WebGLRenderingContext; 4 | private program: WebGLProgram; 5 | private attributes: { [name: string]: VertexAttribute } = {}; 6 | private uniforms: { [name: string]: ShaderUniform } = {}; 7 | 8 | constructor(gl: WebGLRenderingContext, vertexSource: string, fragmentSource: string) { 9 | function getShader(src: string, type: number): WebGLShader { 10 | var shader = gl.createShader(type); 11 | 12 | gl.shaderSource(shader, src); 13 | gl.compileShader(shader); 14 | 15 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { 16 | console.log(src); 17 | console.log(gl.getShaderInfoLog(shader)); 18 | throw "Shader failed to compile."; 19 | } 20 | 21 | return shader; 22 | } 23 | 24 | var vertShader = getShader(vertexSource, gl.VERTEX_SHADER); 25 | var fragShader = getShader(fragmentSource, gl.FRAGMENT_SHADER); 26 | 27 | var program = gl.createProgram(); 28 | gl.attachShader(program, vertShader); 29 | gl.attachShader(program, fragShader); 30 | gl.linkProgram(program); 31 | 32 | if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { 33 | console.log(vertexSource); 34 | console.log(fragmentSource); 35 | console.log(gl.getProgramInfoLog(program)); 36 | throw "Shader failed to link."; 37 | } 38 | 39 | this.gl = gl; 40 | this.program = program; 41 | } 42 | 43 | public use(): void { 44 | this.gl.useProgram(this.program); 45 | } 46 | 47 | public getVertexAttribute(name: string): VertexAttribute { 48 | if (!(name in this.attributes)) { 49 | var gl = this.gl; 50 | this.use(); 51 | var attrib = gl.getAttribLocation(this.program, name); 52 | this.attributes[name] = attrib !== -1 ? new VertexAttribute(gl, attrib) : null; 53 | } 54 | return this.attributes[name]; 55 | } 56 | 57 | public getUniform(name: string): ShaderUniform { 58 | if (!(name in this.uniforms)) { 59 | var gl = this.gl; 60 | this.use(); 61 | var loc = gl.getUniformLocation(this.program, name); 62 | this.uniforms[name] = loc !== null ? new ShaderUniform(gl, loc) : null; 63 | } 64 | return this.uniforms[name]; 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/WGL/ShaderUniform.ts: -------------------------------------------------------------------------------- 1 | module WGL { 2 | export class ShaderUniform { 3 | private gl: WebGLRenderingContext; 4 | private location: WebGLUniformLocation; 5 | constructor(gl: WebGLRenderingContext, location: WebGLUniformLocation) { 6 | if (location == null) { 7 | throw "InvalidUniformName"; 8 | } 9 | 10 | this.gl = gl; 11 | this.location = location; 12 | } 13 | 14 | set1i(i: number) { 15 | this.gl.uniform1i(this.location, i); 16 | } 17 | 18 | set1f(f: number) { 19 | this.gl.uniform1f(this.location, f); 20 | } 21 | 22 | setVec2(v: TSM.vec2) { 23 | this.gl.uniform2f(this.location, v.x, v.y); 24 | } 25 | 26 | setVec3(v: TSM.vec3) { 27 | this.gl.uniform3f(this.location, v.x, v.y, v.z); 28 | } 29 | 30 | setMat4(m: TSM.mat4) { 31 | var nums: number[] = []; 32 | //Hack for node-webgl. Should fix there instead. 33 | var marr = m.all(); 34 | for (var i = 0; i < marr.length; i++) { 35 | nums.push(marr[i]); 36 | } 37 | this.gl.uniformMatrix4fv(this.location, false, marr); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/WGL/Texture.ts: -------------------------------------------------------------------------------- 1 | module WGL { 2 | export class Texture { 3 | private static textureUnitAvailable: boolean[] = [true, true, true, true]; 4 | 5 | private texture: WebGLTexture; 6 | private gl: WebGLRenderingContext; 7 | private boundTo: number = -1; 8 | 9 | public Width: number; 10 | public Height: number; 11 | 12 | 13 | constructor(gl: WebGLRenderingContext) { 14 | this.texture = gl.createTexture(); 15 | this.gl = gl; 16 | this.setFilters(gl.NEAREST, gl.NEAREST); 17 | } 18 | 19 | public bind(): void { 20 | this.gl.bindTexture(this.gl.TEXTURE_2D, this.texture); 21 | } 22 | 23 | public unbind(): void { 24 | this.gl.bindTexture(this.gl.TEXTURE_2D, null); 25 | } 26 | 27 | public loadData(image: HTMLCanvasElement): void { 28 | this.Width = image.width; 29 | this.Height = image.height; 30 | 31 | var gl = this.gl; 32 | this.bind(); 33 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); 34 | } 35 | 36 | public createEmpty(width: number, height: number): void { 37 | this.Width = width; 38 | this.Height = height; 39 | var gl = this.gl; 40 | this.bind(); 41 | 42 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); 43 | } 44 | 45 | public setFilters(minFilter: number, magFilter: number): void { 46 | var gl = this.gl; 47 | this.bind(); 48 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter); 49 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter); 50 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 51 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 52 | } 53 | 54 | public generateMipmap(): void { 55 | var gl = this.gl; 56 | this.bind(); 57 | gl.generateMipmap(gl.TEXTURE_2D); 58 | } 59 | 60 | public attachToUniform(uniform: ShaderUniform): void { 61 | for (var i = 0; i < Texture.textureUnitAvailable.length; i++) { 62 | if (Texture.textureUnitAvailable[i]) { 63 | this.attachToUniformExplicit(uniform, i); 64 | return; 65 | } 66 | } 67 | 68 | throw "All texture units in use"; 69 | } 70 | 71 | private attachToUniformExplicit(uniform: ShaderUniform, activeTextureNum: number) { 72 | var gl = this.gl; 73 | 74 | if (!Texture.textureUnitAvailable[activeTextureNum]) { 75 | throw "Texture unit " + activeTextureNum + "already in use!"; 76 | } 77 | this.boundTo = activeTextureNum; 78 | Texture.textureUnitAvailable[activeTextureNum] = false; 79 | 80 | gl.activeTexture(activeTextureNum + gl.TEXTURE0); 81 | this.bind(); 82 | uniform.set1i(activeTextureNum); 83 | } 84 | 85 | public detachFromUniform() { 86 | if (this.boundTo == -1) { 87 | throw "Texture not currently bound"; 88 | } 89 | 90 | Texture.textureUnitAvailable[this.boundTo] = true; 91 | this.boundTo = -1; 92 | } 93 | 94 | public getGLTexture(): WebGLTexture { 95 | return this.texture; 96 | } 97 | } 98 | } -------------------------------------------------------------------------------- /OpenRoadsLib/Src/WGL/VertexDescriptor.ts: -------------------------------------------------------------------------------- 1 | module WGL { 2 | export interface VertexObject { 3 | getComponent(name: String): number[]; 4 | } 5 | export class VertexAttributeDescription { 6 | public Name: string; 7 | public NumComponents: number; 8 | public TypeOfData: number; 9 | public Normalize: boolean; 10 | public Stride: number; 11 | public Offset: number; 12 | public Size: number; 13 | 14 | constructor(gl: WebGLRenderingContext, name: string, numComponents: number, typeOfData: number = -1, normalize: boolean = false, stride: number = 0, offset: number = 0) { 15 | this.Name = name; 16 | this.NumComponents = numComponents; 17 | this.TypeOfData = typeOfData >= 0 ? typeOfData : gl.FLOAT; 18 | this.Normalize = normalize; 19 | this.Stride = stride; 20 | this.Offset = offset; 21 | switch (typeOfData) { 22 | case gl.FLOAT: 23 | this.Size = 4 * this.NumComponents; 24 | break; 25 | default: 26 | throw "Invalid typeOfData"; 27 | } 28 | } 29 | } 30 | 31 | export class VertexDescriptor { 32 | private attributes: VertexAttributeDescription[]; 33 | private vertexSize: number; 34 | constructor(attributes: VertexAttributeDescription[]) { 35 | this.attributes = attributes; 36 | this.vertexSize = 0; 37 | attributes.forEach((a) => this.vertexSize += a.Size); 38 | } 39 | 40 | buildArray(verts: VertexObject[], array: Float32Array = null): Float32Array { 41 | if (array == null) { 42 | array = new Float32Array(verts.length * this.vertexSize / 4.0); 43 | } 44 | 45 | var attrs = this.attributes; 46 | var pos = 0; 47 | for (var i = 0; i < verts.length; i++) { 48 | for (var j = 0; j < attrs.length; j++) { 49 | var comp = verts[i].getComponent(attrs[j].Name); 50 | if (comp.length != attrs[j].NumComponents) { 51 | throw "InvalidVertexFormat"; 52 | } 53 | for (var k = 0; k < comp.length; k++) { 54 | array[pos++] = comp[k]; 55 | } 56 | } 57 | } 58 | 59 | return array; 60 | } 61 | 62 | enableAndConfigureVertexAttributes(shader: Shader): void { 63 | shader.use(); 64 | var attrs = this.attributes; 65 | var offset = 0; 66 | var stride = this.vertexSize; 67 | for (var i = 0; i < attrs.length; i++) { 68 | var attrDesc = attrs[i]; 69 | var vertAttr = shader.getVertexAttribute(attrDesc.Name); 70 | if (vertAttr !== null) { 71 | vertAttr.enable(); 72 | vertAttr.attribPointer(attrDesc.NumComponents, attrDesc.TypeOfData, attrDesc.Normalize, stride, offset); 73 | } 74 | offset += attrDesc.Size; 75 | } 76 | } 77 | 78 | drawContiguous(gl: WebGLRenderingContext, buffer: Buffer) { 79 | gl.drawArrays(gl.TRIANGLES, 0, buffer.getNumElements() / (this.vertexSize / 4)); 80 | } 81 | 82 | public disableVertexAttributes(shader: Shader) { 83 | shader.use(); 84 | var attrs = this.attributes; 85 | for (var i = 0; i < attrs.length; i++) { 86 | var vertAttr = shader.getVertexAttribute(attrs[i].Name); 87 | if (vertAttr !== null) { 88 | vertAttr.disable(); 89 | } 90 | } 91 | } 92 | } 93 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | OpenRoads 2 | ========= 3 | 4 | A modern implementation of the classic game SkyRoads. Supports all of the original data-files (art, music, levels), and tries to remain faithful to the original. It is written in TypeScript, and uses HTML5 technologies. It also runs in NodeJS with Oculus Rift support. 5 | -------------------------------------------------------------------------------- /WebBuild.bat: -------------------------------------------------------------------------------- 1 | RMDIR Website /S /Q 2 | MKDIR Website 3 | xcopy OpenRoads\index.html Website 4 | xcopy OpenRoads\vr.html Website 5 | xcopy OpenRoads\faq.html Website 6 | xcopy OpenRoads\GameMain.js Website 7 | xcopy OpenRoads\GameMainXMas.js Website 8 | xcopy OpenRoads\RoadsLib.js Website 9 | xcopy OpenRoads\app.css Website 10 | 11 | mkdir Website\Data 12 | mkdir Website\Data.XMas 13 | mkdir Website\JsLibs 14 | mkdir Website\Shaders 15 | mkdir Website\Images 16 | 17 | xcopy OpenRoads\Data Website\Data /E 18 | xcopy OpenRoads\Data.XMas Website\Data.XMas /E 19 | xcopy OpenRoads\Images Website\Images /E 20 | xcopy OpenRoads\JsLibs Website\JsLibs /E 21 | xcopy OpenRoads\Shaders Website\Shaders /E 22 | --------------------------------------------------------------------------------