├── .editorconfig
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
└── workflows
│ └── DocFX.yml
├── .gitignore
├── .vscode
└── settings.json
├── CONTRIBUTING.md
├── DocFX
├── API
│ └── index.md
├── Articles
│ ├── Graphics.md
│ ├── Shell.md
│ ├── Temp.md
│ ├── index.md
│ └── toc.yml
├── DocFX.json
├── Templates
│ └── DarkFX
│ │ ├── partials
│ │ ├── affix.tmpl.partial
│ │ ├── footer.tmpl.partial
│ │ └── head.tmpl.partial
│ │ └── styles
│ │ ├── docfx.vendor.css
│ │ ├── doxfx.vendor.js
│ │ ├── main.css
│ │ └── toggle-theme.js
├── index.md
└── toc.yml
├── LICENSE
├── Makefile
├── PrismAPI
├── Audio
│ ├── AudioPlayer.cs
│ └── Synth.cs
├── Filesystem
│ ├── FilesystemManager.cs
│ ├── Filesystems
│ │ ├── EXT4
│ │ │ └── SuperBlock.cs
│ │ ├── TAR
│ │ │ ├── FileTypes.cs
│ │ │ ├── Header.cs
│ │ │ └── TARFile.cs
│ │ └── XFS
│ │ │ ├── README.md
│ │ │ └── Structure
│ │ │ ├── AGFBlock.cs
│ │ │ ├── BTreeBlock.cs
│ │ │ ├── SuperBlock.cs
│ │ │ ├── SuperBlockFlags.cs
│ │ │ └── SuperBlockQuotaFlags.cs
│ └── Formats
│ │ ├── ELF
│ │ ├── ELFClassType.cs
│ │ ├── ELFEndianType.cs
│ │ ├── ELFHeader
│ │ │ ├── ELFHeader32.cs
│ │ │ └── ELFHeader64.cs
│ │ ├── ELFMachineType.cs
│ │ ├── ELFProgramHeader
│ │ │ ├── ELFProgramHeader32.cs
│ │ │ └── ELFProgramHeader64.cs
│ │ ├── ELFProgramType.cs
│ │ ├── ELFSectionFlagsType.cs
│ │ ├── ELFSectionHeader
│ │ │ ├── ELFSectionHeader32.cs
│ │ │ └── ELFSectionHeader64.cs
│ │ ├── ELFSectionType.cs
│ │ ├── ELFSymbolTable
│ │ │ ├── ELFSymbolTable32.cs
│ │ │ └── ELFSymbolTable64.cs
│ │ ├── ELFSystemABIType.cs
│ │ └── ELFType.cs
│ │ └── INI
│ │ └── INIReader.cs
├── Graphics
│ ├── Animation
│ │ ├── AnimationController.cs
│ │ ├── AnimationMode.cs
│ │ └── ColorController.cs
│ ├── Canvas.cs
│ ├── Color.cs
│ ├── Filters.cs
│ ├── Fonts
│ │ ├── Font.cs
│ │ └── Glyph.cs
│ ├── Gradient.cs
│ ├── Image.cs
│ ├── Physics
│ │ ├── Colisions
│ │ │ └── CubeColider.cs
│ │ └── Gravity.cs
│ └── Rasterizer
│ │ ├── Camera.cs
│ │ ├── Engine.cs
│ │ ├── Light.cs
│ │ ├── LightTypes.cs
│ │ ├── Mesh.cs
│ │ └── Triangle.cs
├── Hardware
│ └── GPU
│ │ ├── Display.cs
│ │ ├── VESA
│ │ └── VBECanvas.cs
│ │ └── VMWare
│ │ └── SVGAIICanvas.cs
├── Network
│ ├── HTTP
│ │ ├── HTTPClient.cs
│ │ └── HTTPStatus.cs
│ ├── NetworkManager.cs
│ └── URL.cs
├── PrismAPI.csproj
├── Runtime
│ ├── Executable.cs
│ ├── SSharp
│ │ ├── Binary.cs
│ │ ├── Compiler.cs
│ │ ├── Structure
│ │ │ ├── OPCode.cs
│ │ │ ├── Token.cs
│ │ │ └── TokenType.cs
│ │ └── Tokenizer.cs
│ ├── SShell
│ │ ├── Scripts
│ │ │ ├── CLI.cs
│ │ │ ├── Locker.cs
│ │ │ ├── Script.cs
│ │ │ ├── Status.cs
│ │ │ ├── Unix.cs
│ │ │ └── VEdit.cs
│ │ └── Shell.cs
│ └── SystemCall
│ │ ├── AccessLevel.cs
│ │ ├── Handler.cs
│ │ └── Kind.cs
├── Tools
│ ├── Compression
│ │ ├── DeflateStream.cs
│ │ └── LZW.cs
│ ├── Coordinates.cs
│ ├── Crypt.cs
│ ├── Diagnostics
│ │ ├── Debugger.cs
│ │ └── Severity.cs
│ ├── EventHandler.cs
│ ├── Extentions
│ │ ├── KeyboardEx.cs
│ │ ├── MouseEx.cs
│ │ └── StringEx.cs
│ └── FluentXS
│ │ ├── ArgumentBuilder.cs
│ │ └── PlugArgument.cs
└── UI
│ ├── Animation.cs
│ ├── Config
│ ├── CursorStatus.cs
│ ├── LayoutStyle.cs
│ ├── MenuStyle.cs
│ └── ThemeStyle.cs
│ ├── Control.cs
│ ├── Controls
│ ├── Button.cs
│ ├── Drawable.cs
│ ├── Label.cs
│ └── Textbox.cs
│ ├── DialogBox.cs
│ ├── Window.cs
│ └── WindowManager.cs
├── PrismOS.sln
├── PrismOS
├── Boot.cs
├── Media
│ ├── Audio
│ │ ├── Shutdown-Alt.wav
│ │ ├── Shutdown.wav
│ │ └── Startup.wav
│ ├── Fonts
│ │ └── Malgun_Gothic_32x.psf
│ ├── Images
│ │ ├── Cursor.bmp
│ │ ├── Prism.bmp
│ │ └── Wallpaper.bmp
│ └── Media.cs
├── PrismOS.csproj
└── Program.cs
└── README.md
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.cs]
2 |
3 | # CA2211: Non-constant fields should not be visible
4 | dotnet_diagnostic.CA2211.severity = none
5 |
6 | # CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
7 | dotnet_diagnostic.CS8632.severity = none
8 |
9 | # CS0660: Type defines operator == or operator != but does not override Object.Equals(object o)
10 | dotnet_diagnostic.CS0660.severity = none
11 |
12 | # CS0661: Type defines operator == or operator != but does not override Object.GetHashCode()
13 | dotnet_diagnostic.CS0661.severity = none
14 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | #### Describe the bug
11 |
12 | #### To Reproduce
13 |
14 | #### Expected behavior
15 |
16 | #### Screenshots
17 | If applicable, add screenshots to help explain your problem.
18 |
19 |
20 | #### Additional context
21 | Add any other context about the problem here.
22 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/workflows/DocFX.yml:
--------------------------------------------------------------------------------
1 | name: DocFX
2 |
3 | on:
4 | push:
5 | branches: [ "main" ]
6 |
7 | jobs:
8 | publish-docs:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: Chekout
12 | uses: actions/checkout@v3
13 | - name: Dotnet Setup
14 | uses: actions/setup-dotnet@v3
15 | with:
16 | dotnet-version: 6.x
17 |
18 | - name: Install DocFX
19 | run: dotnet tool update -g docfx
20 |
21 | - name: Install Cosmos
22 | run: |
23 | git clone https://github.com/CosmosOS/Cosmos
24 | cd Cosmos
25 | sudo make
26 | sudo make install
27 | make nuget-install
28 |
29 | - name: Run DocFX
30 | run: docfx DocFX/DocFX.json
31 |
32 | - name: Deploy
33 | uses: peaceiris/actions-gh-pages@v3
34 | with:
35 | github_token: ${{ secrets.GITHUB_TOKEN }}
36 | publish_dir: DocFX/Site
37 | destination_dir: Documentation
38 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | manjarno## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # DocFX old files
14 | */API/toc.yml
15 |
16 | # User-specific files (MonoDevelop/Xamarin Studio)
17 | *.userprefs
18 | obj/
19 |
20 | # unneeded github files
21 | .github
22 |
23 | # Mono auto generated files
24 | mono_crash.*
25 |
26 | #vs files
27 | .vs/
28 |
29 | # Build results
30 | [Dd]ebug/
31 | [Dd]ebugPublic/
32 | [Rr]elease/
33 | [Rr]eleases/
34 | x64/
35 | x86/
36 | [Aa][Rr][Mm]/
37 | [Aa][Rr][Mm]64/
38 | bld/
39 | [Oo]bj/
40 | [Ll]og/
41 | [Ll]ogs/
42 | [Bb]in/
43 |
44 | # DocFX generated files - Don't need in the repo because github actions deploys it automatically.
45 | DocFX/Site
46 | DocFX/API/Prism*.yml
47 | .manifest
48 |
49 | # Visual Studio 2015/2017 cache/options directory
50 | .vs/
51 | # Uncomment if you have tasks that create the project's static files in wwwroot
52 | #wwwroot/
53 |
54 | # Visual Studio 2017 auto generated files
55 | Generated\ Files/
56 |
57 | # MSTest test Results
58 | [Tt]est[Rr]esult*/
59 | [Bb]uild[Ll]og.*
60 |
61 | # NUnit
62 | *.VisualState.xml
63 | TestResult.xml
64 | nunit-*.xml
65 |
66 | # Build Results of an ATL Project
67 | [Dd]ebugPS/
68 | [Rr]eleasePS/
69 | dlldata.c
70 |
71 | # Benchmark Results
72 | BenchmarkDotNet.Artifacts/
73 |
74 | # .NET Core
75 | project.lock.json
76 | project.fragment.lock.json
77 | artifacts/
78 |
79 | # StyleCop
80 | StyleCopReport.xml
81 |
82 | # Files built by Visual Studio
83 | *_i.c
84 | *_p.c
85 | *_h.h
86 | *.ilk
87 | *.meta
88 | *.obj
89 | *.iobj
90 | *.pch
91 | *.pdb
92 | *.ipdb
93 | *.pgc
94 | *.pgd
95 | *.rsp
96 | *.sbr
97 | *.tlb
98 | *.tli
99 | *.tlh
100 | *.tmp
101 | *.tmp_proj
102 | *_wpftmp.csproj
103 | *.log
104 | *.vspscc
105 | *.vssscc
106 | .builds
107 | *.pidb
108 | *.svclog
109 | *.scc
110 |
111 | # Chutzpah Test files
112 | _Chutzpah*
113 |
114 | # Visual C++ cache files
115 | ipch/
116 | *.aps
117 | *.ncb
118 | *.opendb
119 | *.opensdf
120 | *.sdf
121 | *.cachefile
122 | *.VC.db
123 | *.VC.VC.opendb
124 |
125 | # Visual Studio profiler
126 | *.psess
127 | *.vsp
128 | *.vspx
129 | *.sap
130 |
131 | # Visual Studio Trace Files
132 | *.e2e
133 |
134 | # TFS 2012 Local Workspace
135 | $tf/
136 |
137 | # Guidance Automation Toolkit
138 | *.gpState
139 |
140 | # ReSharper is a .NET coding add-in
141 | _ReSharper*/
142 | *.[Rr]e[Ss]harper
143 | *.DotSettings.user
144 |
145 | # TeamCity is a build add-in
146 | _TeamCity*
147 |
148 | # DotCover is a Code Coverage Tool
149 | *.dotCover
150 |
151 | # AxoCover is a Code Coverage Tool
152 | .axoCover/*
153 | !.axoCover/settings.json
154 |
155 | # Visual Studio code coverage results
156 | *.coverage
157 | *.coveragexml
158 |
159 | # NCrunch
160 | _NCrunch_*
161 | .*crunch*.local.xml
162 | nCrunchTemp_*
163 |
164 | # MightyMoose
165 | *.mm.*
166 | AutoTest.Net/
167 |
168 | # Web workbench (sass)
169 | .sass-cache/
170 |
171 | # Installshield output folder
172 | [Ee]xpress/
173 |
174 | # DocProject is a documentation generator add-in
175 | DocProject/buildhelp/
176 | DocProject/Help/*.HxT
177 | DocProject/Help/*.HxC
178 | DocProject/Help/*.hhc
179 | DocProject/Help/*.hhk
180 | DocProject/Help/*.hhp
181 | DocProject/Help/Html2
182 | DocProject/Help/html
183 |
184 | # Click-Once directory
185 | publish/
186 |
187 | # Publish Web Output
188 | *.[Pp]ublish.xml
189 | *.azurePubxml
190 | # Note: Comment the next line if you want to checkin your web deploy settings,
191 | # but database connection strings (with potential passwords) will be unencrypted
192 | *.pubxml
193 | *.publishproj
194 |
195 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
196 | # checkin your Azure Web App publish settings, but sensitive information contained
197 | # in these scripts will be unencrypted
198 | PublishScripts/
199 |
200 | # NuGet Packages
201 | *.nupkg
202 | # NuGet Symbol Packages
203 | *.snupkg
204 | # The packages folder can be ignored because of Package Restore
205 | **/[Pp]ackages/*
206 | # except build/, which is used as an MSBuild target.
207 | !**/[Pp]ackages/build/
208 | # Uncomment if necessary however generally it will be regenerated when needed
209 | #!**/[Pp]ackages/repositories.config
210 | # NuGet v3's project.json files produces more ignorable files
211 | *.nuget.props
212 | *.nuget.targets
213 |
214 | # Microsoft Azure Build Output
215 | csx/
216 | *.build.csdef
217 |
218 | # Microsoft Azure Emulator
219 | ecf/
220 | rcf/
221 |
222 | # Windows Store app package directories and files
223 | AppPackages/
224 | BundleArtifacts/
225 | Package.StoreAssociation.xml
226 | _pkginfo.txt
227 | *.appx
228 | *.appxbundle
229 | *.appxupload
230 |
231 | # Visual Studio cache files
232 | # files ending in .cache can be ignored
233 | *.[Cc]ache
234 | # but keep track of directories ending in .cache
235 | !?*.[Cc]ache/
236 |
237 | # Others
238 | ClientBin/
239 | ~$*
240 | *~
241 | *.dbmdl
242 | *.dbproj.schemaview
243 | *.jfm
244 | *.pfx
245 | *.publishsettings
246 | orleans.codegen.cs
247 |
248 | # Including strong name files can present a security risk
249 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
250 | #*.snk
251 |
252 | # Since there are multiple workflows, uncomment next line to ignore bower_components
253 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
254 | #bower_components/
255 |
256 | # RIA/Silverlight projects
257 | Generated_Code/
258 |
259 | # Backup & report files from converting an old project file
260 | # to a newer Visual Studio version. Backup files are not needed,
261 | # because we have git ;-)
262 | _UpgradeReport_Files/
263 | Backup*/
264 | UpgradeLog*.XML
265 | UpgradeLog*.htm
266 | ServiceFabricBackup/
267 | *.rptproj.bak
268 |
269 | # SQL Server files
270 | *.mdf
271 | *.ldf
272 | *.ndf
273 |
274 | # Business Intelligence projects
275 | *.rdl.data
276 | *.bim.layout
277 | *.bim_*.settings
278 | *.rptproj.rsuser
279 | *- [Bb]ackup.rdl
280 | *- [Bb]ackup ([0-9]).rdl
281 | *- [Bb]ackup ([0-9][0-9]).rdl
282 |
283 | # Microsoft Fakes
284 | FakesAssemblies/
285 |
286 | # GhostDoc plugin setting file
287 | *.GhostDoc.xml
288 |
289 | # Node.js Tools for Visual Studio
290 | .ntvs_analysis.dat
291 | node_modules/
292 |
293 | # Visual Studio 6 build log
294 | *.plg
295 |
296 | # Visual Studio 6 workspace options file
297 | *.opt
298 |
299 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
300 | *.vbw
301 |
302 | # Visual Studio LightSwitch build output
303 | **/*.HTMLClient/GeneratedArtifacts
304 | **/*.DesktopClient/GeneratedArtifacts
305 | **/*.DesktopClient/ModelManifest.xml
306 | **/*.Server/GeneratedArtifacts
307 | **/*.Server/ModelManifest.xml
308 | _Pvt_Extensions
309 |
310 | # Paket dependency manager
311 | .paket/paket.exe
312 | paket-files/
313 |
314 | # FAKE - F# Make
315 | .fake/
316 |
317 | # CodeRush personal settings
318 | .cr/personal
319 |
320 | # Python Tools for Visual Studio (PTVS)
321 | __pycache__/
322 | *.pyc
323 |
324 | # Cake - Uncomment if you are using it
325 | # tools/**
326 | # !tools/packages.config
327 |
328 | # Tabs Studio
329 | *.tss
330 |
331 | # Telerik's JustMock configuration file
332 | *.jmconfig
333 |
334 | # BizTalk build output
335 | *.btp.cs
336 | *.btm.cs
337 | *.odx.cs
338 | *.xsd.cs
339 |
340 | # OpenCover UI analysis results
341 | OpenCover/
342 |
343 | # Azure Stream Analytics local run output
344 | ASALocalRun/
345 |
346 | # MSBuild Binary and Structured Log
347 | *.binlog
348 |
349 | # NVidia Nsight GPU debugger configuration file
350 | *.nvuser
351 |
352 | # MFractors (Xamarin productivity tool) working folder
353 | .mfractor/
354 |
355 | # Local History for Visual Studio
356 | .localhistory/
357 |
358 | # BeatPulse healthcheck temp database
359 | healthchecksdb
360 |
361 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
362 | MigrationBackup/
363 |
364 | # Ionide (cross platform F# VS Code tools) working folder
365 | .ionide/
366 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "explorer.excludeGitIgnore": true,
3 | "explorer.compactFolders": false,
4 | "editor.insertSpaces": false,
5 | }
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | Code agreement and guidelines
4 |
5 |
6 |
7 | ⚠️ PLEASE READ BEFORE CONTINUING ⚠️
8 |
9 |
10 |
11 | Any code that **_you contribute_** will be under _**full
12 | control**_ by the repository maintainers. They may change
13 | it's licensing, the code itself, or use it for whatever
14 | the organization sees as necesarry. This does not mean
15 | rights, you will still have access to and retain full
16 | ownership of your work. This agreement is in place to
17 | prevent attempted project hijacking and legal issues.
18 | Code taken from existing sources do not fall under
19 | these rules, as that would be unethical and illegal.
20 | All code taken from outside sources fall under their
21 | original licese(s) and shall have a reference to it's
22 | orignal license.
23 |
24 |
25 |
26 | Including externaly sourced code
27 |
28 | You are allowed to include source code from external
29 | sources, as long as you make sure it's original license
30 | is compatible with this project's license (GPL - V2).
31 | It is recommended to remove the whole license copy from
32 | the source files (if it has it) and add a comment referencing
33 | the source's original author, source, and short name of the
34 | original license. If the source files themselves do not have a
35 | copy of the license within them, you must add comments showing
36 | the original author, source, and short name of the license.
37 |
38 |
39 |
40 | Spacing & Formatting
41 |
42 | All functions, local and global variables, and
43 | namespaces must be capitalized with the 'PascalCase'
44 | naming Convention, and spelled properly. They
45 | must contain professional and easy to read names,
46 | usually they should describe what the function
47 | does, if possible.
48 |
49 |
50 | Variables and using statements should be clustered Like this, with descending length:
51 |
52 |
53 |
54 | There shall also not be more than one class/struct/enum or namespace
55 | in the same file.
56 |
57 |
58 |
59 | Keep all code as simple as possible and make sure all code is understandable.
60 |
61 |
62 |
63 | Bundling
64 |
65 | If a class has more than one type of data, use `#region` tags like so:
66 |
67 |
68 |
69 |
70 |
71 | Do NOT create hacky methods to get around something unless you know you will change it before you commit. You _will_ regret making something very unreliable then having to re-make it for several hours in a more stable manner)
72 |
73 |
74 |
75 | Always use IF statments "properly" and clearly. and example is if you have many nested IFs, invert the condition and move it to the top, and return it if the condition is met.
76 |
77 |
78 |
79 | Don't define namespaces within namespaces, and always include only one namespace definition _per file_, just below the using statements. They should not use brackets like so:
80 | ```cs
81 | namespace PrismOS;
82 | ```
83 |
84 |
85 |
86 | Licensing
87 |
88 | You must include files from other projects (with compatible licenses) like so:
89 | 
90 |
91 |
92 |
--------------------------------------------------------------------------------
/DocFX/API/index.md:
--------------------------------------------------------------------------------
1 | # Prism OS - API documentation
2 |
3 | This is the landing page for the API documentation for Prism OS. To get started, find the class of interest in the menu to the left. Aditionally you can use the search feature to navigate classes and namespaces faster.
--------------------------------------------------------------------------------
/DocFX/Articles/Shell.md:
--------------------------------------------------------------------------------
1 | > **Warning**:
2 | > This documentation is incomplete.
3 |
4 | ## SystemSharp (S#) V2 documentation
5 |
6 |
7 |
8 | SystemSharp is a high level bytecode language, it currently has no use or goals and is more of a learning experience. SystemSharp is compiled to a custom bytecode that is read and executed by the SystemSharp runtime.
9 |
10 | You are free to make your own ports of the SystemSharp runtime and compiler, it is very simple to do as it is mostly ``for`` loops.
11 |
12 |
13 | ## Available functions
14 |
15 | S# has many functions, here is a list of all of them:
16 |
17 | - Console.WriteLine("String");
18 | > Writes a string to the console and makes a new line.
19 | - Console.Write("String");
20 | > Writes a string to the console.
21 | - Throw("String");
22 | > Throws an exception.
23 | - Exit();
24 | > Exit the application.
25 |
26 |
--------------------------------------------------------------------------------
/DocFX/Articles/Temp.md:
--------------------------------------------------------------------------------
1 | # An idea of a scripting languge
2 |
3 | This is an idea as defined by my (Terminal.cs's) perfered coding style & 'attitude'.
4 | I have not imeplented it because i am not smart enough, but i feel if it were to be a thing, it could make development in almost any programming field easier.
5 |
6 | This 'standard' defines all the syntax, types, and misc implementations that should be included in this language.
7 |
8 |
9 |
10 | ## Syntax, Standard 'library', & naming
11 |
12 | Syntax should be kept mostly minimal, with it being only used to promote cleaner and more understandable structure.
13 | An example of this could be as follows:
14 |
15 | ```cs
16 | import Library; // Standard 'library' name.
17 | import ""; // Imports external assembly, possibly web URLs to projects aswell. The project will be managed by a lightweight manager that should 100% be cross platform and 100% open source.
18 |
19 | namespace "MyNamespace1"; // Define the file's namespace, dis-allow putting multiple namespaces in a single file to dicourage bad design.
20 |
21 | // 'public' and 'static' are keywords to modify how the structure will work. 'public' defines it as available to all external code willing to act on it and 'static' marks it as a initialize-once object.
22 | public static MyStructure1 // Only have one type of structure to prevent confusion and promote good design, it will be a combination of a 'class' and an unsafe 'structure', allowing it to be used for any purpose the programmer sees needed.
23 | {
24 | public MyStructure1 // Allow for static structures to have initializers - This promotes good design and makes organization easier. The visibility level of the constructor cannot be higher than the class itself, and the constructor won't have '()' as static structures cannot be instantiated.
25 | {
26 | // Initialize statics here.
27 | StructurePointer = new(); // Allow pointers to be assigned normally.
28 | V1 = 50;
29 |
30 | StructurePointer->F = string.Empty; // Empty string, but not null.
31 | }
32 |
33 | // Do not allow structures to be defined inside another to promote good design - nested classes add lots of clutter.
34 |
35 | #region Fields // Add regions so that code can be organized in IDEs. Common names to be used should be as followed: Properties, Operators, Methods, and Fields.
36 |
37 | public static MyStructure2* StructurePointer;
38 | public static int V1; // Variables inside the class must be static as it is in a static context, and it's visibility level must not be higher than the class itself.
39 |
40 | #endregion
41 | }
42 |
43 | public MyStructure2 // A structure to be instantiated as an object.
44 | {
45 | public MyStructure2() // Object structures
46 | {
47 | MyProperty = 55;
48 | }
49 |
50 | #region Properties
51 |
52 | public int MyProperty
53 | {
54 | get // Run whenever something tries to get the value.
55 | {
56 | return MyProperty; // Allow a property to define itself so that aditional variable declaratoins are not needed.
57 | }
58 | set // Set, run whenever the property or a value inside of the property is changed, this promotes event-based design and leads to greater performance.
59 | {
60 | MyMethod1(); // run some method
61 | MyProperty = Value; // Value is the name of what the property was set to, and setting the property inside of the property again just sets an automatically internal variable so there is no recursion.
62 | }
63 | }
64 |
65 | #endregion
66 |
67 | #region
68 |
69 | public string F;
70 |
71 | #endregion
72 | }
73 | ```
74 |
75 | ## Naming schemes
76 |
77 | ### Library names
78 |
79 | #### Primitive Types
80 |
81 | - Vector2
82 | - Vector3
83 | - Vector4
84 | - string
85 | - bool
86 | - ulong
87 | - long
88 | - uint
89 | - int
90 | - ushort
91 | - short
92 | - byte
93 | - char
94 | - double
95 | - float
96 |
97 | ### Tools
98 |
99 | - Library.Console
100 | - WriteLine(type ToWrite);
101 | - Write(type ToWrite);
102 | - Clear();
103 | - Library.Math
104 | - Sin();
105 | - SinF
106 | - Cos
107 | - CosF
108 | - Tan
109 | - TanF
110 | - Sqrt
111 | - SqrtF
112 | - Cbrt
113 | - CbrtF,
114 | - PI (constant)
--------------------------------------------------------------------------------
/DocFX/Articles/index.md:
--------------------------------------------------------------------------------
1 | # Welcome to the Prism OS tutorial page!
2 |
3 | To the side are different files for different tutorials for the libraries. These are only for tutorials. If you wish to reserch the API, go [here](../API/index.md) instead.
--------------------------------------------------------------------------------
/DocFX/Articles/toc.yml:
--------------------------------------------------------------------------------
1 | - name: Introduction
2 | href: index.md
3 | - name: Graphics - Basic intro
4 | href: Graphics.md
5 | - name: Shell
6 | href: Shell.md
7 |
--------------------------------------------------------------------------------
/DocFX/DocFX.json:
--------------------------------------------------------------------------------
1 | {
2 | "metadata": [
3 | {
4 | "src": [
5 | {
6 | "files": [
7 | "PrismAPI/PrismAPI.csproj"
8 | ],
9 | "exclude": [
10 | "**/obj/**",
11 | "**/bin/**"
12 | ],
13 | "src": "../"
14 | }
15 | ],
16 | "dest": "API",
17 | "includePrivateMembers": false,
18 | "disableGitFeatures": false,
19 | "disableDefaultFilter": false,
20 | "noRestore": false,
21 | "namespaceLayout": "nested"
22 | }
23 | ],
24 | "build": {
25 | "content": [
26 | {
27 | "files": [
28 | "API/**.yml",
29 | "API/index.md"
30 | ]
31 | },
32 | {
33 | "files": [
34 | "Articles/**.md",
35 | "Articles/**/toc.yml",
36 | "toc.yml",
37 | "*.md"
38 | ]
39 | }
40 | ],
41 | "resource": [
42 | {
43 | "files": [
44 | "Images/**"
45 | ]
46 | }
47 | ],
48 | "overwrite": [
49 | {
50 | "files": [
51 | "APIDoc/**.md"
52 | ],
53 | "exclude": [
54 | "obj/**",
55 | "Site/**"
56 | ]
57 | }
58 | ],
59 | "dest": "Site",
60 | "globalMetadataFiles": [],
61 | "fileMetadataFiles": [],
62 | "template": [
63 | "default",
64 | "Templates/DarkFX"
65 | ],
66 | "postProcessors": [],
67 | "noLangKeyword": false,
68 | "keepFileLink": false,
69 | "disableGitFeatures": false
70 | }
71 | }
--------------------------------------------------------------------------------
/DocFX/Templates/DarkFX/partials/affix.tmpl.partial:
--------------------------------------------------------------------------------
1 | {{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}
2 |
3 |
4 |
5 | {{^_disableContribution}}
6 |
20 | {{/_disableContribution}}
21 |
22 |
23 | ☀
24 |
25 |
26 |
27 |
28 |
29 |
30 | ☾
31 |
32 |
33 |
34 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/DocFX/Templates/DarkFX/partials/footer.tmpl.partial:
--------------------------------------------------------------------------------
1 | {{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}
2 |
3 |
--------------------------------------------------------------------------------
/DocFX/Templates/DarkFX/partials/head.tmpl.partial:
--------------------------------------------------------------------------------
1 | {{!Copyright (c) Oscar Vasquez. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}
2 |
3 |
4 |
5 |
6 | {{#title}}{{title}}{{/title}}{{^title}}{{>partials/title}}{{/title}} {{#_appTitle}}| {{_appTitle}} {{/_appTitle}}
7 |
8 |
9 |
10 | {{#_description}} {{/_description}}
11 |
12 |
13 |
14 |
15 |
16 |
17 | {{#_noindex}} {{/_noindex}}
18 | {{#_enableSearch}} {{/_enableSearch}}
19 | {{#_enableNewTab}} {{/_enableNewTab}}
20 |
--------------------------------------------------------------------------------
/DocFX/Templates/DarkFX/styles/toggle-theme.js:
--------------------------------------------------------------------------------
1 | const sw = document.getElementById("switch-style"), sw_mobile = document.getElementById("switch-style-m"), b = document.body;
2 | if (b) {
3 | function toggleTheme(target, dark) {
4 | target.classList.toggle("dark-theme", dark)
5 | target.classList.toggle("light-theme", !dark)
6 | }
7 |
8 | function switchEventListener() {
9 | toggleTheme(b, this.checked);
10 | if (window.localStorage) {
11 | this.checked ? localStorage.setItem("theme", "dark-theme") : localStorage.setItem("theme", "light-theme")
12 | }
13 | }
14 |
15 | var isDarkTheme = !window.localStorage || !window.localStorage.getItem("theme") || window.localStorage && localStorage.getItem("theme") === "dark-theme";
16 |
17 | if(sw && sw_mobile){
18 | sw.checked = isDarkTheme;
19 | sw_mobile.checked = isDarkTheme;
20 |
21 | sw.addEventListener("change", switchEventListener);
22 | sw_mobile.addEventListener("change", switchEventListener);
23 |
24 | // sync state between switches
25 | sw.addEventListener("change", function() {
26 | sw_mobile.checked = this.checked;
27 | });
28 |
29 | sw_mobile.addEventListener("change", function() {
30 | sw.checked = this.checked;
31 | });
32 | }
33 |
34 | toggleTheme(b, isDarkTheme);
35 | }
--------------------------------------------------------------------------------
/DocFX/index.md:
--------------------------------------------------------------------------------
1 | # Prism OS - Documentation
2 |
3 | ## This is the Prism OS documentation landing page.
4 | Refer to the [API](https://project-prism.github.io/Prism-OS/Documentation/API/index.html) section for API documentation.
5 | Refer to the [Articles](https://project-prism.github.io/Prism-OS/Documentation/Articles/index.html) section for more in-depth details.
6 |
--------------------------------------------------------------------------------
/DocFX/toc.yml:
--------------------------------------------------------------------------------
1 | - name: Articles
2 | href: Articles/
3 | - name: API Documentation
4 | href: API/
5 | homepage: API/index.md
6 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | all: build run
2 |
3 | build:
4 | @dotnet build --no-incremental
5 |
6 | run:
7 | @qemu-system-x86_64 -enable-kvm -m 4G -device e1000,netdev=net0 -netdev user,id=net0 -device ac97 -cdrom ./PrismOS/bin/Debug/net6.0/PrismOS.iso
--------------------------------------------------------------------------------
/PrismAPI/Audio/AudioPlayer.cs:
--------------------------------------------------------------------------------
1 | using PrismAPI.Tools.Diagnostics;
2 | using Cosmos.HAL.Drivers.Audio;
3 | using Cosmos.System.Audio;
4 |
5 | namespace PrismAPI.Audio;
6 |
7 | ///
8 | /// Audio player class for playing audio.
9 | ///
10 | public static class AudioPlayer
11 | {
12 | #region Constructors
13 |
14 | ///
15 | /// Initializes the audio manager uppon app running.
16 | ///
17 | static AudioPlayer()
18 | {
19 | // Initialize objects.
20 | Debugger = new("Audio");
21 | Mixer = new();
22 | AM = new();
23 | }
24 |
25 | #endregion
26 |
27 | #region Properties
28 |
29 | ///
30 | /// A bool defining whether the audio player is available.
31 | ///
32 | public static bool IsAvailable { get; internal set; }
33 |
34 | #endregion
35 |
36 | #region Methods
37 |
38 | ///
39 | /// Attempts to load the audio driver.
40 | /// will become True if the operation was sucessfull.
41 | ///
42 | public static void Init()
43 | {
44 | try
45 | {
46 | Debugger.WritePartial("Initializing audio...");
47 |
48 | // Assign values and initialize audio player.
49 | AM.Output = AC97.Initialize(4096);
50 | AM.Stream = Mixer;
51 | AM.Enable();
52 |
53 | // Inform that audio player is done initializing.
54 | Debugger.Finalize(Severity.Success);
55 | IsAvailable = true;
56 | }
57 | catch
58 | {
59 | Debugger.Finalize(Severity.Fail);
60 | }
61 | }
62 |
63 | ///
64 | /// Plays an audio stream, which can be loaded from any supported format.
65 | /// Idealy should be 16-bit @ 48000hz to prevent slowdowns.
66 | ///
67 | public static void Play(AudioStream Stream)
68 | {
69 | // Add the audio stream to the mixer 'now-playing' list.
70 | Mixer.Streams.Add(Stream);
71 | }
72 |
73 | #endregion
74 |
75 | #region Fields
76 |
77 | private static readonly Debugger Debugger;
78 | public static readonly AudioMixer Mixer;
79 | private static readonly AudioManager AM;
80 |
81 | #endregion
82 | }
--------------------------------------------------------------------------------
/PrismAPI/Audio/Synth.cs:
--------------------------------------------------------------------------------
1 | using Cosmos.System.Audio.IO;
2 | using Cosmos.HAL.Audio;
3 |
4 | namespace PrismAPI.Audio;
5 |
6 | ///
7 | /// A primitive synthesieser class for Prism OS.
8 | ///
9 | public unsafe static class Synth
10 | {
11 | ///
12 | /// Generates a triangle wave based on the given inputs.
13 | ///
14 | /// The audio frequency of the wave.
15 | /// The number of samples, 48000 @4800hz is 1 second.
16 | /// The amplitude/loudness of the audio.
17 | /// Triangle wave as an audio stream.
18 | public static MemoryAudioStream GetTriangleWave(short Frequency, uint Samples = 48000, float Amplitude = 1f)
19 | {
20 | BinaryWriter Writer = new(new MemoryStream());
21 |
22 | // Determine the number of samples per wavelength.
23 | int SamplesPerWavelength = Convert.ToInt32(Samples / (Frequency / 1));
24 |
25 | // Determine the amplitude step for consecutive samples.
26 | short AmpStep = Convert.ToInt16(Amplitude * 2 / SamplesPerWavelength);
27 |
28 | // Temporary sample value, added to as we go through the loop.
29 | short TempSample = (short)-Amplitude;
30 |
31 | for (uint i = 0; i < Samples; i++)
32 | {
33 | // Negate ampstep whenever it hits the amplitude boundary.
34 | if (Math.Abs(TempSample) > Amplitude)
35 | {
36 | AmpStep = (short)-AmpStep;
37 | }
38 |
39 | TempSample += AmpStep;
40 | Writer.Write(TempSample);
41 | }
42 |
43 | return new MemoryAudioStream(new(AudioBitDepth.Bits16, 1, true), Samples, ((MemoryStream)Writer.BaseStream).ToArray());
44 | }
45 |
46 | ///
47 | /// Generates a sawtooth wave based on the given inputs.
48 | ///
49 | /// The audio frequency of the wave.
50 | /// The number of samples, 48000 @4800hz is 1 second.
51 | /// The amplitude/loudness of the audio.
52 | /// Sawtooth wave as an audio stream.
53 | public static MemoryAudioStream GetSawtoothWave(short Frequency, uint Samples = 4800, float Amplitude = 1f)
54 | {
55 | BinaryWriter Writer = new(new MemoryStream());
56 |
57 | // Determine the number of samples per wavelength.
58 | int SamplesPerWavelength = Convert.ToInt32(Samples / (Frequency / 1));
59 |
60 | // Determine the amplitude step for consecutive samples.
61 | short AmpStep = Convert.ToInt16(Amplitude * 2 / SamplesPerWavelength);
62 |
63 | // Total number of samples written so we know when to stop.
64 | int TotalSamplesWritten = 0;
65 |
66 | while (TotalSamplesWritten < Samples)
67 | {
68 | // Temporary sample value, added to as we go through the loop.
69 | short TempSample = (short)-Amplitude;
70 |
71 | for (uint i = 0; i < SamplesPerWavelength && TotalSamplesWritten < Samples; i++)
72 | {
73 | TempSample += AmpStep;
74 | Writer.Write(TempSample);
75 | TotalSamplesWritten++;
76 | }
77 | }
78 |
79 | Console.WriteLine("Finished");
80 |
81 | return new MemoryAudioStream(new(AudioBitDepth.Bits16, 1, true), Samples, ((MemoryStream)Writer.BaseStream).ToArray());
82 | }
83 |
84 | ///
85 | /// Generates a square wave based on the given inputs.
86 | ///
87 | /// The audio frequency of the wave.
88 | /// The number of samples, 48000 @4800hz is 1 second.
89 | /// The amplitude/loudness of the audio.
90 | /// Square wave as an audio stream.
91 | public static MemoryAudioStream GetSquareWave(short Frequency, uint Samples = 48000, float Amplitude = 1f)
92 | {
93 | BinaryWriter Writer = new(new MemoryStream());
94 |
95 | for (uint I = 0; I < Samples; I += 2)
96 | {
97 | Writer.Write(Convert.ToInt16(Amplitude * Math.Sign(Math.Sin(Frequency * I))));
98 | }
99 |
100 | return new MemoryAudioStream(new(AudioBitDepth.Bits16, 1, true), Samples, ((MemoryStream)Writer.BaseStream).ToArray());
101 | }
102 |
103 | ///
104 | /// Generates a sine wave based on the given inputs.
105 | ///
106 | /// The audio frequency of the wave.
107 | /// The number of samples, 48000 @4800hz is 1 second.
108 | /// The amplitude/loudness of the audio.
109 | /// Sine wave as an audio stream.
110 | public static MemoryAudioStream GetSineWave(short Frequency, uint Samples = 48000, float Amplitude = 1f)
111 | {
112 | BinaryWriter Writer = new(new MemoryStream());
113 |
114 | for (uint I = 0; I < Samples; I += 2)
115 | {
116 | Writer.Write(Convert.ToInt16(Amplitude * Math.Sin(Frequency * I)));
117 | }
118 |
119 | return new MemoryAudioStream(new(AudioBitDepth.Bits16, 1, true), Samples, ((MemoryStream)Writer.BaseStream).ToArray());
120 | }
121 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/FilesystemManager.cs:
--------------------------------------------------------------------------------
1 | using Cosmos.System.FileSystem.VFS;
2 | using PrismAPI.Tools.Diagnostics;
3 | using Cosmos.System.FileSystem;
4 | using Cosmos.HAL.BlockDevice;
5 |
6 | namespace PrismAPI.Filesystem;
7 |
8 | ///
9 | /// The Prism OS file syste manager, used to interact with disks.
10 | ///
11 | public static class FilesystemManager
12 | {
13 | #region Constructors
14 |
15 | ///
16 | /// Statically initializes this class when it is first accessed (lazy loading).
17 | /// Should run when is ran.
18 | ///
19 | static FilesystemManager()
20 | {
21 | // Initialize the debugger and VFS.
22 | Debugger = new("Filesystem");
23 | VFS = new();
24 | }
25 |
26 | #endregion
27 |
28 | #region Properties
29 |
30 | public static string Root => $"{VFS.Disks.Count - 1}:\\";
31 |
32 | #endregion
33 |
34 | #region Methods
35 |
36 | ///
37 | /// Formats the specified disk with a single partition.
38 | ///
39 | /// The disk, must be specified. Main disk is typically 0.
40 | /// The format to use, only "FAT32" is currently supported.
41 | public static void Format(int Disk, string Format)
42 | {
43 | // Write format status indicating formatting has begun.
44 | Debugger.WriteFull($"Formatting disk {Disk}...", Severity.Info);
45 |
46 | // Select the proper disk to format.
47 | Disk SelectedDisk = VFS.Disks[Disk];
48 |
49 | // Delete all partitions.
50 | SelectedDisk.Clear();
51 |
52 | // Create MBR and Primary partitions.
53 | SelectedDisk.CreatePartition(512);
54 | SelectedDisk.CreatePartition((SelectedDisk.Size - 512) / 1048576);
55 |
56 | // Create MBR helper instance and write info to the disk.
57 | MBR Helper = new(SelectedDisk.Host);
58 | Helper.CreateMBR(SelectedDisk.Host);
59 | Helper.WritePartitionInformation(SelectedDisk.Partitions[0].Host, 0);
60 |
61 | // Format the primary partition as the requested format.
62 | SelectedDisk.FormatPartition(1, Format, true);
63 | }
64 |
65 | ///
66 | /// Method to initialize all the filesystems for the disks connected to the machine.
67 | ///
68 | public static void Init()
69 | {
70 | try
71 | {
72 | Debugger.WritePartial("Initializing FS...");
73 |
74 | // Initialize the VFS.
75 | VFSManager.RegisterVFS(VFS, false, false);
76 |
77 | // Return success if all is loaded properly.
78 | Debugger.Finalize(Severity.Success);
79 | }
80 | catch
81 | {
82 | Debugger.Finalize(Severity.Fail);
83 | }
84 | }
85 |
86 | #endregion
87 |
88 | #region Fields
89 |
90 | public static Debugger Debugger;
91 | public static CosmosVFS VFS;
92 |
93 | #endregion
94 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Filesystems/EXT4/SuperBlock.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Filesystem.Filesystems.EXT4;
2 |
3 | ///
4 | /// The EXT4 filesystem superblock implementation.
5 | /// Reference: https://wiki.osdev.org/Ext4
6 | ///
7 | public unsafe struct SuperBlock
8 | {
9 | public uint INodeCount;
10 | public uint BlockCount;
11 | public uint ReservedBlockCount;
12 | public uint UnallocatedBlockCount;
13 | public uint UnallocatedINodeCount;
14 | public uint SuperBlockIndex;
15 | public uint BlockSizeShifter;
16 | public uint FragmentSizeShifter;
17 | public uint BlockPerGroup;
18 | public uint FragmentPerGroup;
19 | public uint INodesPerGroup;
20 | public uint LastMountTime;
21 | public uint LastWriteTime;
22 | public ushort TimesMountedSinceFSCK;
23 | public ushort TimesBeforeFSCK;
24 | public ushort MagicSignature;
25 | public ushort Status;
26 | public ushort OnErrorFunction;
27 | public ushort MinorVersion;
28 | public uint LastFSCK;
29 | public uint ForcedIntervalBetweenFSCK;
30 | public uint OSCreationID;
31 | public uint MajorVersion;
32 | public uint ReservedBlocksAllowedUID;
33 | public uint ReservedBlocksAllowedGID;
34 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Filesystems/TAR/FileTypes.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Filesystem.Filesystems.TAR;
2 |
3 | ///
4 | /// The different possible file types in a tar file.
5 | ///
6 | public enum FileTypes
7 | {
8 | NormalFile = 0,
9 | HardLink = 1,
10 | SymbolicLink = 2,
11 | DeviceOrSpecialFile = 3,
12 | BlockDevice = 4,
13 | Directory = 5,
14 | NamedPipe = 6,
15 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Filesystems/TAR/Header.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 |
3 | namespace PrismAPI.Filesystem.Filesystems.TAR;
4 |
5 | ///
6 | /// The header file for posix tar files.
7 | ///
8 | public struct Header
9 | {
10 | ///
11 | /// Creates a new instance of the class.
12 | ///
13 | /// The TAR header.
14 | public Header(byte[] Binary)
15 | {
16 | // Create new reader instance.
17 | BinaryReader Reader = new(new MemoryStream(Binary));
18 |
19 | // Assign all values.
20 | Name = Encoding.ASCII.GetString(Reader.ReadBytes(100)).Trim('\0');
21 | Mode = Reader.ReadBytes(8);
22 | OwnerUID = Reader.ReadBytes(8);
23 | GroupUID = Reader.ReadBytes(8);
24 | Size = Convert.ToInt64(Encoding.ASCII.GetString(Reader.ReadBytes(12)).Trim('\0'), 8);
25 | LastModifyTime = Reader.ReadBytes(12);
26 | HRChecksum = Reader.ReadBytes(8);
27 | TypeFlag = (FileTypes)Reader.ReadByte();
28 |
29 | LinkName = Reader.ReadBytes(100);
30 | Magic = Reader.ReadBytes(6);
31 | Version = Reader.ReadBytes(2);
32 | UName = Reader.ReadBytes(32);
33 | GName = Reader.ReadBytes(32);
34 | DevMajor = Reader.ReadBytes(8);
35 | DevMinor = Reader.ReadBytes(8);
36 | Prefix = Reader.ReadBytes(155);
37 | }
38 |
39 | #region Fields
40 |
41 | // GNU Compatible
42 | public string Name;
43 | public byte[] Mode;
44 | public byte[] OwnerUID;
45 | public byte[] GroupUID;
46 | public long Size;
47 | public byte[] LastModifyTime;
48 | public byte[] HRChecksum;
49 | public FileTypes TypeFlag;
50 |
51 | // Posix Extention
52 | public byte[] LinkName;
53 | public byte[] Magic;
54 | public byte[] Version;
55 | public byte[] UName;
56 | public byte[] GName;
57 | public byte[] DevMajor;
58 | public byte[] DevMinor;
59 | public byte[] Prefix;
60 |
61 | #endregion
62 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Filesystems/TAR/TARFile.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 |
3 | namespace PrismAPI.Filesystem.Filesystems.TAR;
4 |
5 | ///
6 | /// Class used for loading TAR files
7 | ///
8 | ///
9 | public unsafe class TARFile
10 | {
11 | ///
12 | /// Creates a new instance of the class.
13 | ///
14 | /// Raw binary of a tar file.
15 | public TARFile(byte[] Buffer)
16 | {
17 | Reader = new(new MemoryStream(Buffer));
18 | }
19 |
20 | #region Methods
21 |
22 | #region Reading
23 |
24 | ///
25 | /// Reads all text and splits it by \n
26 | ///
27 | /// Name of the file to read.
28 | /// Text of 'File' split by \n.
29 | public string[] ReadAllLines(string File)
30 | {
31 | return ReadAllText(File).Split('\n');
32 | }
33 |
34 | ///
35 | /// Reads all the bytes of the file.
36 | ///
37 | /// Name of the file to read.
38 | /// All bytes of 'File'.
39 | public byte[] ReadAllBytes(string File)
40 | {
41 | // Properly format the path of the input.
42 | File = Format(File);
43 |
44 | // Reset the reader position to be safe.
45 | Reader.BaseStream.Position = 0;
46 |
47 | // Loop over all data.
48 | for (int I = 0; I < Reader.BaseStream.Length; I++)
49 | {
50 | // Get the header for the current file.
51 | Header H = new(Reader.ReadBytes(512));
52 |
53 | // Check if the current file is the target specified.
54 | if (File.StartsWith(H.Name))
55 | {
56 | return Reader.ReadBytes((int)H.Size);
57 | }
58 |
59 | // Increment the reader to skip the data section.
60 | Reader.BaseStream.Position += H.Size;
61 | }
62 |
63 | // Inform user that file does not exist.
64 | throw new FileNotFoundException();
65 | }
66 |
67 | ///
68 | /// Reads all text from the file.
69 | ///
70 | /// file to read from.
71 | /// UTF-8 text read from 'File'.
72 | public string ReadAllText(string File)
73 | {
74 | return Encoding.UTF8.GetString(ReadAllBytes(File));
75 | }
76 |
77 | ///
78 | /// Lists all file names from the tar bundle.
79 | ///
80 | /// Path to search in (Recusrive)
81 | /// All files in the path specified.
82 | public IEnumerable List(string Path)
83 | {
84 | // Reset the reader position to be safe.
85 | Reader.BaseStream.Position = 0;
86 |
87 | // Properly format the path of the input.
88 | Path = Format(Path);
89 |
90 | // Loop over all data.
91 | for (int I = 0; I < Reader.BaseStream.Length; I++)
92 | {
93 | // Get the header for the current file.
94 | Header H = new(Reader.ReadBytes(512));
95 |
96 | // Check if the current file is the target specified.
97 | if (Path.StartsWith(H.Name))
98 | {
99 | yield return H.Name;
100 | }
101 |
102 | // Increment the reader to skip the data section.
103 | Reader.BaseStream.Position += H.Size;
104 | }
105 | }
106 |
107 | #endregion
108 |
109 | #region Writing
110 |
111 | ///
112 | /// Writes all lines in 'Lines' to the file.
113 | ///
114 | /// File to write to.
115 | /// Line to write.
116 | public void WriteAllLines(string File, string[] Lines)
117 | {
118 | // Create stringbuilder instance,
119 | StringBuilder Builder = new();
120 |
121 | for (int I = 0; I < Lines.Length; I++)
122 | {
123 | Builder.AppendLine(Lines[I]);
124 | }
125 |
126 | WriteAllText(File, Builder.ToString());
127 | }
128 |
129 | ///
130 | /// Writes all bytes om 'Binary' to the file.
131 | ///
132 | /// File to write to.
133 | /// Binary to write.
134 | public void WriteAllBytes(string File, byte[] Binary)
135 | {
136 | throw new NotImplementedException();
137 | }
138 |
139 | ///
140 | /// Writes all text in 'Contents' to the file.
141 | ///
142 | /// File to write to.
143 | /// String to write.
144 | public void WriteAllText(string File, string Contents)
145 | {
146 | WriteAllBytes(File, Encoding.UTF8.GetBytes(Contents));
147 | }
148 |
149 | ///
150 | /// Deletes a file.
151 | ///
152 | /// File to delete, must be full path.
153 | public void Delete(string File)
154 | {
155 | throw new NotImplementedException();
156 | }
157 |
158 | ///
159 | /// Creates an empty file, mush be full path.
160 | ///
161 | /// Path to new file.
162 | public void Create(string File)
163 | {
164 | throw new NotImplementedException();
165 | }
166 |
167 | #endregion
168 |
169 | #region Misc
170 |
171 | private static string Format(string Base)
172 | {
173 | while (Base.Contains('\\'))
174 | {
175 | Base = Base.Replace('\\', '/');
176 | }
177 | if (Base.StartsWith('/'))
178 | {
179 | return Base[1..];
180 | }
181 |
182 | return Base;
183 | }
184 |
185 | #endregion
186 |
187 | #endregion
188 |
189 | #region Fields
190 |
191 | public BinaryReader Reader;
192 |
193 | #endregion
194 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Filesystems/XFS/README.md:
--------------------------------------------------------------------------------
1 | # XFS
2 | XFS is Silicon Graphics' "Next Generation Journalled 64-Bit Filesystem With Guaranteed Rate I/O" designed for IRIX based systems. XFS uses the standard inodes, bitmaps and blocks, and is compatible with EFS and NFS filesystems.
3 |
4 | Reference: [XFS FileSystem Structure](http://www.dubeiko.com/development/FileSystems/XFS/xfs_filesystem_structure.pdf)
5 |
6 | [Read More...](https://wiki.osdev.org/XFS)
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Filesystems/XFS/Structure/AGFBlock.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Filesystem.Filesystems.XFS.Structure;
2 |
3 | ///
4 | /// The second sector in an AG contains the information about the two free space B+trees and associated
5 | /// free space information for the AG.The "AG Free Space Block", also knows as the AGF, uses the
6 | /// following structure:
7 | ///
8 | public unsafe struct AGFBlock
9 | {
10 | #region Methods
11 |
12 | public bool IsValid => MagicNumber == 0x58414746;
13 |
14 | #endregion
15 |
16 | #region Fields
17 |
18 | public uint MagicNumber;
19 | public uint VersionNumber;
20 | public uint SequenceNumber;
21 | public uint Length;
22 | public fixed uint Roots[2];
23 | public uint agf_spare0;
24 | public fixed uint Levels[2];
25 | public uint Spare1;
26 | public uint FirstFreeList;
27 | public uint LastFreeList;
28 | public uint FileCount;
29 | public uint FreeBlocks;
30 | public uint Longest;
31 | public uint BTreeBlocks;
32 |
33 | #endregion
34 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Filesystems/XFS/Structure/BTreeBlock.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Filesystem.Filesystems.XFS.Structure;
2 |
3 | ///
4 | /// The two Free Space B+trees store a sorted array of block offset and block counts in the leaves of the
5 | /// B+tree.The first B+tree is sorted by the offset, the second by the count or size.
6 | ///
7 | public unsafe struct BTreeBlock
8 | {
9 | public uint Magic;
10 | public ushort Level;
11 | public ushort NumberOfRecs;
12 | public uint LeftSib;
13 | public uint RightSib;
14 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Filesystems/XFS/Structure/SuperBlock.cs:
--------------------------------------------------------------------------------
1 | // using Cosmos.HAL.BlockDevice;
2 |
3 | namespace PrismAPI.Filesystem.Filesystems.XFS.Structure;
4 |
5 | public unsafe struct SuperBlock
6 | {
7 | /*
8 | ///
9 | /// Creates a new instance of the class from a block device.
10 | ///
11 | /// The device specified to use.
12 | public SuperBlock(BlockDevice Device)
13 | {
14 | MagicNumber = 0x58465342;
15 | BlockSize = (uint)Device.BlockSize;
16 | DBlocks = Device.BlockCount;
17 | RBlocks = 0;
18 | RExtents = 0;
19 | UUID = "";
20 | }
21 | */
22 |
23 | #region Methods
24 |
25 | ///
26 | /// A basic check to see if the magic number is correct.
27 | ///
28 | public bool IsValid => MagicNumber == 0x58465342;
29 |
30 | #endregion
31 |
32 | #region Fields
33 |
34 | public uint MagicNumber;
35 | public uint BlockSize;
36 | public ulong DBlocks;
37 | public ulong RBlocks;
38 | public ulong RExtents;
39 | public string UUID;
40 | public ulong LogStart;
41 | public ulong RootInode;
42 | public ulong RBMInode;
43 | public ulong RsumInode;
44 | public uint RExtentSize;
45 | public uint AGBlocks;
46 | public uint AGCcount;
47 | public uint RBMBlocks;
48 | public uint LogBlocks;
49 | public ushort VersionNumber;
50 | public ushort SectorSize;
51 | public ushort InodeSize;
52 | public uint Inopblock;
53 | public fixed char FNname[12];
54 | public byte BlockLog;
55 | public byte SectorLog;
56 | public byte InodeLog;
57 | public byte InopbLog;
58 | public byte AgblkLog;
59 | public byte RExtentsLog;
60 | public byte InProgress;
61 | public byte IMaxPCT;
62 | public ulong ICount;
63 | public ulong IFree;
64 | public ulong FDBlocks;
65 | public ulong FRExtents;
66 | public ulong Uquotino;
67 | public ulong Gquotino;
68 | public SuperBlockQuotaFlags QFlags;
69 | public SuperBlockFlags Flags;
70 | public byte SharedVN;
71 | public uint InodeAlignment;
72 | public uint Unit;
73 | public uint Width;
74 | public byte DirblkLog;
75 | public byte LogsectorLog;
76 | public ushort LogSectorSize;
77 | public uint LogsUnit;
78 | public uint Features2;
79 |
80 | #endregion
81 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Filesystems/XFS/Structure/SuperBlockFlags.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Filesystem.Filesystems.XFS.Structure;
2 |
3 | public enum SuperBlockFlags : byte
4 | {
5 | VERSION_ATTRBIT,// Set if any inode have extended attributes.
6 | VERSION_NLINKBIT, // Set if any inodes use 32-bit di_nlink values.
7 | VERSION_QUOTABIT, // Set if quotas are enabled on the filesystem. This also brings in the various quota fields in the superblock.
8 | VERSION_ALIGNBIT, // Set if sb_inoalignmt is used.
9 | VERSION_DALIGNBIT, // Set if sb_unit and sb_width are used.
10 | VERSION_SHAREDBIT, // Set if sb_shared_vn is used.
11 | VERSION_LOGV2BIT, // Set if version 2 journaling logs are used.
12 | VERSION_SECTORBIT, // Set if sb_sectsize is not 512.
13 | VERSION_EXTFLGBIT, // Unwritten extents are used. This is always set today.
14 | VERSION_DIRV2BIT, // Version 2 directories are used. This is always set today.
15 | VERSION_MOREBITSBIT, // Set if the sb_features2 field in the superblock contains more flags.
16 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Filesystems/XFS/Structure/SuperBlockQuotaFlags.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Filesystem.Filesystems.XFS.Structure;
2 |
3 | public enum SuperBlockQuotaFlags : ushort
4 | {
5 | UQUOTA_ACCT, // User quota accounting is enabled.
6 | UQUOTA_ENFD, // User quotas are enforced.
7 | UQUOTA_CHKD, // User quotas have been checked and updated on disk.
8 | PQUOTA_ACCT, // Project quota accounting is enabled.
9 | OQUOTA_ENFD, // Other (group/project) quotas are enforced.
10 | OQUOTA_CHKD, // Other (group/project) quotas have been checked.
11 | GQUOTA_ACCT, // Group quota accounting is enabled.
12 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Formats/ELF/ELFClassType.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Filesystem.Formats.ELF;
2 |
3 | ///
4 | /// ELF file class descriptors.
5 | ///
6 | public enum ELFClassType
7 | {
8 | ///
9 | /// Invalid file type.
10 | ///
11 | Invalid,
12 | ///
13 | /// 32-bit file.
14 | ///
15 | Class32,
16 | ///
17 | /// 63-bit file.
18 | ///
19 | Class64,
20 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Formats/ELF/ELFEndianType.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Filesystem.Formats.ELF;
2 |
3 | ///
4 | /// Endian marker enum.
5 | ///
6 | public enum ELFEndianType
7 | {
8 | ///
9 | /// Invalid file type.
10 | ///
11 | Invalid,
12 | ///
13 | /// Least significant first. (Little Endian)
14 | ///
15 | LSB,
16 | ///
17 | /// Most significant first. (Big Endian)
18 | ///
19 | MSB,
20 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Formats/ELF/ELFHeader/ELFHeader32.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace PrismAPI.Filesystem.Formats.ELF.ELFHeader;
4 |
5 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
6 | public unsafe struct ELFHeader32
7 | {
8 | public ELFHeader32(ELFHeader32* Original)
9 | {
10 | MagicNumber = Original->MagicNumber;
11 | ClassType = Original->ClassType;
12 | EndianType = Original->EndianType;
13 | Version = Original->Version;
14 | ABIType = Original->ABIType;
15 | ABIVersion = Original->ABIVersion;
16 |
17 | Type = Original->Type;
18 | MachineType = Original->MachineType;
19 | MachineVersion = Original->MachineVersion;
20 | EntryPoint = Original->EntryPoint;
21 | PHOffset = Original->PHOffset;
22 | SHOffset = Original->SHOffset;
23 | Flags = Original->Flags;
24 | EHSize = Original->EHSize;
25 | PHEntrySize = Original->PHEntrySize;
26 | PHCount = Original->PHCount;
27 | SHEntrySize = Original->SHEntrySize;
28 | SHCount = Original->SHCount;
29 | SHStringIndex = Original->SHStringIndex;
30 | }
31 |
32 | #region Properties
33 |
34 | public bool IsValid => MagicNumber == BitConverter.ToUInt32(new byte[] { 0x7F, 0x45, 0x4C, 0x46 });
35 |
36 | #endregion
37 |
38 | #region Fields
39 |
40 | #region Identifier [14 bytes]
41 |
42 | public uint MagicNumber;
43 | public ELFClassType ClassType;
44 | public ELFEndianType EndianType;
45 | private readonly byte Version;
46 | public ELFSystemABIType ABIType;
47 | public byte ABIVersion;
48 | private fixed char Padding[7];
49 |
50 | #endregion
51 |
52 | public ELFType Type;
53 | public ELFMachineType MachineType;
54 | public uint MachineVersion;
55 | public uint EntryPoint;
56 | public uint PHOffset;
57 | public uint SHOffset;
58 | public uint Flags;
59 | public ushort EHSize;
60 | public ushort PHEntrySize;
61 | public ushort PHCount;
62 | public ushort SHEntrySize;
63 | public ushort SHCount;
64 | public ushort SHStringIndex;
65 |
66 | #endregion
67 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Formats/ELF/ELFHeader/ELFHeader64.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace PrismAPI.Filesystem.Formats.ELF.ELFHeader;
4 |
5 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
6 | public unsafe struct ELFHeader64
7 | {
8 | public ELFHeader64(ELFHeader64* Original)
9 | {
10 | MagicNumber = Original->MagicNumber;
11 | ClassType = Original->ClassType;
12 | EndianType = Original->EndianType;
13 | Version = Original->Version;
14 | ABIType = Original->ABIType;
15 | ABIVersion = Original->ABIVersion;
16 |
17 | Type = Original->Type;
18 | MachineType = Original->MachineType;
19 | MachineVersion = Original->MachineVersion;
20 | EntryPoint = Original->EntryPoint;
21 | PHOffset = Original->PHOffset;
22 | SHOffset = Original->SHOffset;
23 | Flags = Original->Flags;
24 | EHSize = Original->EHSize;
25 | PHEntrySize = Original->PHEntrySize;
26 | PHCount = Original->PHCount;
27 | SHEntrySize = Original->SHEntrySize;
28 | SHCount = Original->SHCount;
29 | SHStringIndex = Original->SHStringIndex;
30 | }
31 |
32 | #region Properties
33 |
34 | public bool IsValid => MagicNumber == 0x7F454C46;
35 |
36 | #endregion
37 |
38 | #region Fields
39 |
40 | #region Identifier [14 bytes]
41 |
42 | public uint MagicNumber;
43 | public ELFClassType ClassType;
44 | public ELFEndianType EndianType;
45 | private readonly byte Version;
46 | public ELFSystemABIType ABIType;
47 | public byte ABIVersion;
48 | private fixed char Padding[7];
49 |
50 | #endregion
51 |
52 | public ELFType Type;
53 | public ELFMachineType MachineType;
54 | public uint MachineVersion;
55 | public ulong EntryPoint;
56 | public ulong PHOffset;
57 | public ulong SHOffset;
58 | public uint Flags;
59 | public ushort EHSize;
60 | public ushort PHEntrySize;
61 | public ushort PHCount;
62 | public ushort SHEntrySize;
63 | public ushort SHCount;
64 | public ushort SHStringIndex;
65 |
66 | #endregion
67 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Formats/ELF/ELFMachineType.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Filesystem.Formats.ELF;
2 |
3 | public enum ELFMachineType : ushort
4 | {
5 | X86 = 0x3,
6 | Mips = 0x8,
7 | Arm = 0x28,
8 | Amd64 = 0x3E,
9 | ArmV8 = 0xB7,
10 | RiscV = 0xF3,
11 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Formats/ELF/ELFProgramHeader/ELFProgramHeader32.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace PrismAPI.Filesystem.Formats.ELF.ELFProgramHeader;
4 |
5 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
6 | public unsafe struct ELFProgramHeader32
7 | {
8 | public ELFProgramHeader32(ELFProgramHeader32* Original)
9 | {
10 | Type = Original->Type;
11 | Offset = Original->Offset;
12 | VAddress = Original->VAddress;
13 | PAddress = Original->PAddress;
14 | FileSize = Original->FileSize;
15 | MemorySize = Original->MemorySize;
16 | Flags = Original->Flags;
17 | Align = Original->Align;
18 | }
19 |
20 | #region Fields
21 |
22 | public ELFProgramType Type;
23 | public uint Offset;
24 | public uint VAddress;
25 | public uint PAddress;
26 | public uint FileSize;
27 | public uint MemorySize;
28 | public uint Flags;
29 | public uint Align;
30 |
31 | #endregion
32 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Formats/ELF/ELFProgramHeader/ELFProgramHeader64.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace PrismAPI.Filesystem.Formats.ELF.ELFProgramHeader;
4 |
5 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
6 | public unsafe struct ELFProgramHeader64
7 | {
8 | public ELFProgramHeader64(ELFProgramHeader64* Original)
9 | {
10 | Type = Original->Type;
11 | Offset = Original->Offset;
12 | VAddress = Original->VAddress;
13 | PAddress = Original->PAddress;
14 | FileSize = Original->FileSize;
15 | MemorySize = Original->MemorySize;
16 | Flags = Original->Flags;
17 | Align = Original->Align;
18 | }
19 |
20 | #region Flags
21 |
22 | public ELFProgramType Type;
23 | public uint Flags;
24 | public ulong Offset;
25 | public ulong VAddress;
26 | public ulong PAddress;
27 | public uint FileSize;
28 | public uint MemorySize;
29 | public uint Align;
30 |
31 | #endregion
32 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Formats/ELF/ELFProgramType.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Filesystem.Formats.ELF;
2 |
3 | public enum ELFProgramType : uint
4 | {
5 | Null,
6 | Load,
7 | Dynamic,
8 | Interperit,
9 | Note,
10 | SHLibrary,
11 | PHeader,
12 | TLS,
13 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Formats/ELF/ELFSectionFlagsType.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Filesystem.Formats.ELF;
2 |
3 | [Flags]
4 | public enum ELFSectionFlagsType : uint
5 | {
6 | None,
7 | Write,
8 | Allocate,
9 | Executable,
10 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Formats/ELF/ELFSectionHeader/ELFSectionHeader32.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace PrismAPI.Filesystem.Formats.ELF.ELFSectionHeader;
4 |
5 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
6 | public unsafe struct ELFSectionHeader32
7 | {
8 | public ELFSectionHeader32(ELFSectionHeader32* Original)
9 | {
10 | Name = Original->Name;
11 | Type = Original->Type;
12 | Flags = Original->Flags;
13 | Address = Original->Address;
14 | Offset = Original->Offset;
15 | Size = Original->Size;
16 | Link = Original->Link;
17 | Info = Original->Info;
18 | AddressAlign = Original->AddressAlign;
19 | EntrySize = Original->EntrySize;
20 | }
21 |
22 | #region Flags
23 |
24 | public uint Name;
25 | public ELFSectionType Type;
26 | public ELFSectionFlagsType Flags;
27 | public uint Address;
28 | public uint Offset;
29 | public uint Size;
30 | public uint Link;
31 | public uint Info;
32 | public uint AddressAlign;
33 | public uint EntrySize;
34 |
35 | #endregion
36 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Formats/ELF/ELFSectionHeader/ELFSectionHeader64.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace PrismAPI.Filesystem.Formats.ELF.ELFSectionHeader;
4 |
5 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
6 | public unsafe struct ELFSectionHeader64
7 | {
8 | public ELFSectionHeader64(ELFSectionHeader64* Original)
9 | {
10 | Name = Original->Name;
11 | Type = Original->Type;
12 | Flags = Original->Flags;
13 | Address = Original->Address;
14 | Offset = Original->Offset;
15 | Size = Original->Size;
16 | Link = Original->Link;
17 | Info = Original->Info;
18 | AddressAlign = Original->AddressAlign;
19 | EntrySize = Original->EntrySize;
20 | }
21 |
22 | #region Fields
23 |
24 | public uint Name;
25 | public ELFSectionType Type;
26 | public ELFSectionFlagsType Flags;
27 | public ulong Address;
28 | public ulong Offset;
29 | public uint Size;
30 | public uint Link;
31 | public uint Info;
32 | public uint AddressAlign;
33 | public uint EntrySize;
34 |
35 | #endregion
36 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Formats/ELF/ELFSectionType.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Filesystem.Formats.ELF;
2 |
3 | public enum ELFSectionType : uint
4 | {
5 | Null,
6 | ProgramBits,
7 | SymbolTable,
8 | StringTable,
9 | RelocationAddress,
10 | Hash,
11 | Dynamic,
12 | Note,
13 | NoBits,
14 | Relocation,
15 | SHLibrary,
16 | DynamicSymbol,
17 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Formats/ELF/ELFSymbolTable/ELFSymbolTable32.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace PrismAPI.Filesystem.Formats.ELF.ELFSymbolTable;
4 |
5 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
6 | public unsafe struct ELFSymbolTable32
7 | {
8 | public ELFSymbolTable32(ELFSymbolTable32* Original)
9 | {
10 | Name = Original->Name;
11 | Value = Original->Value;
12 | Size = Original->Size;
13 | Info = Original->Info;
14 | Other = Original->Other;
15 | SHIndex = Original->SHIndex;
16 | }
17 |
18 | #region Flags
19 |
20 | public uint Name;
21 | public uint Value;
22 | public uint Size;
23 | public char Info;
24 | public char Other;
25 | public ushort SHIndex;
26 |
27 | #endregion
28 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Formats/ELF/ELFSymbolTable/ELFSymbolTable64.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 |
3 | namespace PrismAPI.Filesystem.Formats.ELF.ELFSymbolTable;
4 |
5 | [StructLayout(LayoutKind.Sequential, Pack = 1)]
6 | public unsafe struct ELFSymbolTable64
7 | {
8 | public ELFSymbolTable64(ELFSymbolTable64* Original)
9 | {
10 | Name = Original->Name;
11 | Value = Original->Value;
12 | Size = Original->Size;
13 | Info = Original->Info;
14 | Other = Original->Other;
15 | SHIndex = Original->SHIndex;
16 | }
17 |
18 | #region Fields
19 |
20 | public uint Name;
21 | public ulong Value;
22 | public uint Size;
23 | public char Info;
24 | public char Other;
25 | public ushort SHIndex;
26 |
27 | #endregion
28 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Formats/ELF/ELFSystemABIType.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Filesystem.Formats.ELF;
2 |
3 | public enum ELFSystemABIType
4 | {
5 | None, // (Could be System V)
6 | HPUX,
7 | NetBSD,
8 | Linux,
9 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Formats/ELF/ELFType.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Filesystem.Formats.ELF;
2 |
3 | public enum ELFType : ushort
4 | {
5 | None,
6 | Relocatable,
7 | Executable,
8 | Dynamic,
9 | Core,
10 | }
--------------------------------------------------------------------------------
/PrismAPI/Filesystem/Formats/INI/INIReader.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Filesystem.Formats.INI;
2 |
3 | public class INIReader
4 | {
5 | public INIReader(string Source)
6 | {
7 | this.Source = Source;
8 | }
9 |
10 | #region Methods
11 |
12 | #region Unsigned
13 |
14 | public bool TryReadUShort(string Key, out ushort Value)
15 | {
16 | if (TryReadString(Key, out string S))
17 | {
18 | return ushort.TryParse(S, out Value);
19 | }
20 | Value = 0;
21 | return false;
22 | }
23 | public bool TryReadUInt(string Key, out uint Value)
24 | {
25 | if (TryReadString(Key, out string S))
26 | {
27 | return uint.TryParse(S, out Value);
28 | }
29 | Value = 0;
30 | return false;
31 | }
32 | public bool TryReadULong(string Key, out ulong Value)
33 | {
34 | if (TryReadString(Key, out string S))
35 | {
36 | return ulong.TryParse(S, out Value);
37 | }
38 | Value = 0;
39 | return false;
40 | }
41 |
42 | #endregion
43 |
44 | #region Signed
45 |
46 | public bool TryReadShort(string Key, out short Value)
47 | {
48 | if (TryReadString(Key, out string S))
49 | {
50 | return short.TryParse(S, out Value);
51 | }
52 | Value = 0;
53 | return false;
54 | }
55 | public bool TryReadInt(string Key, out int Value)
56 | {
57 | if (TryReadString(Key, out string S))
58 | {
59 | return int.TryParse(S, out Value);
60 | }
61 | Value = 0;
62 | return false;
63 | }
64 | public bool TryReadLong(string Key, out long Value)
65 | {
66 | if (TryReadString(Key, out string S))
67 | {
68 | return long.TryParse(S, out Value);
69 | }
70 | Value = 0;
71 | return false;
72 | }
73 |
74 | #endregion
75 |
76 | #region General
77 |
78 | public bool TryReadString(string Key, out string Value)
79 | {
80 | for (int I = 0; I < Source.Length; I++)
81 | {
82 | if (Source[I] == '=' && Validate(Key, I))
83 | {
84 | I++;
85 | Value = string.Empty;
86 | while (I < Source.Length && Source[I] != ' ' && Source[I] != '\n' && Source[I] != '\r')
87 | {
88 | Value += Source[I++];
89 | }
90 | return true;
91 | }
92 | }
93 | Value = string.Empty;
94 | return false;
95 | }
96 | public bool TryReadDouble(string Key, out double Value)
97 | {
98 | if (TryReadString(Key, out string S))
99 | {
100 | return double.TryParse(S, out Value);
101 | }
102 | Value = 0;
103 | return false;
104 | }
105 | public bool TryReadFloat(string Key, out float Value)
106 | {
107 | if (TryReadString(Key, out string S))
108 | {
109 | return float.TryParse(S, out Value);
110 | }
111 | Value = 0;
112 | return false;
113 | }
114 | public bool TryReadByte(string Key, out byte Value)
115 | {
116 | if (TryReadString(Key, out string S))
117 | {
118 | return byte.TryParse(S, out Value);
119 | }
120 | Value = 0;
121 | return false;
122 | }
123 | public bool TryReadChar(string Key, out char Value)
124 | {
125 | if (TryReadString(Key, out string S))
126 | {
127 | return char.TryParse(S, out Value);
128 | }
129 | Value = '\0';
130 | return false;
131 | }
132 |
133 | #endregion
134 |
135 | #region Misc
136 |
137 | public bool TryWrite(string Key, object Value)
138 | {
139 | for (int I = 0; I < Source.Length; I++)
140 | {
141 | if (Source[I] == '=' && Validate(Key, I))
142 | {
143 | int II = Source.IndexOfAny(new char[] { '\n', '\r' }, ++I);
144 | Source = Source.Remove(I, II - I);
145 | Source = Source.Insert(I, Value.ToString() + "");
146 | return true;
147 | }
148 | }
149 | return false;
150 | }
151 |
152 | public bool Validate(string Key, int Index)
153 | {
154 | if (Index - Key.Length < 0 || Index + Key.Length >= Source.Length)
155 | { // Return At Invalid Index
156 | return false;
157 | }
158 |
159 | return Source[(Index - Key.Length)..Index] == Key;
160 | }
161 |
162 | public override string ToString()
163 | {
164 | return Source;
165 | }
166 |
167 | #endregion
168 |
169 | #endregion
170 |
171 | #region Fields
172 |
173 | internal string Source;
174 |
175 | #endregion
176 | }
--------------------------------------------------------------------------------
/PrismAPI/Graphics/Animation/AnimationController.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Graphics.Animation;
2 |
3 | ///
4 | /// The class, used to add basic ease animations or transitions to anything.
5 | /// See:
6 | ///
7 | public class AnimationController
8 | {
9 | #region Constructors
10 |
11 | ///
12 | /// Creates a new instance of the class.
13 | ///
14 | /// The starting value.
15 | /// The value to end at.
16 | /// The duration to play the animation over.
17 | /// The ease animation mode.
18 | public AnimationController(float Source, float Target, TimeSpan Duration, AnimationMode Mode)
19 | {
20 | // Assign internal data.
21 | this.Source = Source;
22 | this.Target = Target;
23 | this.Duration = Duration;
24 | this.Mode = Mode;
25 |
26 | // Assign the timer.
27 | Timer = new((_) => Next(), null, DelayMS, 0);
28 | }
29 |
30 | #endregion
31 |
32 | #region Properties
33 |
34 | ///
35 | /// The current animation value - Automatically picked each time this property is accessed.
36 | ///
37 | public float Current => Mode switch
38 | {
39 | AnimationMode.BounceOut => Lerp(Source, Target, BounceOut(ElapsedTime / (float)Duration.TotalMilliseconds)),
40 | AnimationMode.BounceIn => Lerp(Source, Target, BounceIn(ElapsedTime / (float)Duration.TotalMilliseconds)),
41 | AnimationMode.Bounce => Lerp(Source, Target, Bounce(ElapsedTime / (float)Duration.TotalMilliseconds)),
42 | AnimationMode.EaseOut => Lerp(Source, Target, EaseOut(ElapsedTime / (float)Duration.TotalMilliseconds)),
43 | AnimationMode.EaseIn => Lerp(Source, Target, EaseIn(ElapsedTime / (float)Duration.TotalMilliseconds)),
44 | AnimationMode.Ease => Lerp(Source, Target, Ease(ElapsedTime / (float)Duration.TotalMilliseconds)),
45 | AnimationMode.Linear => Lerp(Source, Target, ElapsedTime / (float)Duration.TotalMilliseconds),
46 | _ => throw new NotImplementedException("That mode isn't implemented!"),
47 | };
48 |
49 | ///
50 | /// A boolean to tell if the animation has finished.
51 | ///
52 | public bool IsFinished
53 | {
54 | get => ElapsedTime >= Duration.TotalMilliseconds;
55 | set => ElapsedTime = value ? (float)Duration.TotalMilliseconds : 0;
56 | }
57 |
58 | #endregion
59 |
60 | #region Constants
61 |
62 | ///
63 | /// The delay in MS of each update.
64 | ///
65 | public const int DelayMS = 55; // Limit to 55 for now due to max PIT speed.
66 |
67 | #endregion
68 |
69 | #region Methods
70 |
71 | ///
72 | /// The function used to linearly interpolate between 2 numbers.
73 | ///
74 | /// The number to start with.
75 | /// The number to end with.
76 | /// Any number between 0.0 and 1.0.
77 | /// The value between 'StartValue' and 'EndValue' as marked by 'Index'.
78 | public static float Lerp(float StartValue, float EndValue, float Index)
79 | {
80 | // Ensure 'Index' is between 0.0 and 1.0.
81 | Index = (float)Math.Clamp(Index, 0.0, 1.0);
82 |
83 | return StartValue + ((EndValue - StartValue) * Index);
84 | }
85 |
86 | private static float BounceOut(float T)
87 | {
88 | if (T < 1f / 2.75f)
89 | {
90 | return 7.5625f * T * T;
91 | }
92 | else if (T < 2f / 2.75f)
93 | {
94 | return (7.5625f * (T -= 1.5f / 2.75f) * T) + 0.75f;
95 | }
96 | else if (T < 2.5f / 2.75f)
97 | {
98 | return (7.5625f * (T -= 2.25f / 2.75f) * T) + 0.9375f;
99 | }
100 | else
101 | {
102 | return (7.5625f * (T -= 2.625f / 2.75f) * T) + 0.984375f;
103 | }
104 | }
105 |
106 | private static float BounceIn(float T)
107 | {
108 | return 1f - BounceOut(1f - T);
109 | }
110 |
111 | private static float Bounce(float T)
112 | {
113 | if (T < 0.5f)
114 | {
115 | return BounceIn(T * 2f) * 0.5f;
116 | }
117 | else
118 | {
119 | return (BounceOut((T * 2f) - 1f) * 0.5f) + 0.5f;
120 | }
121 | }
122 |
123 | private static float EaseOut(float T)
124 | {
125 | return Flip((float)Math.Pow(Flip(T), 2));
126 | }
127 |
128 | private static float EaseIn(float T)
129 | {
130 | return T * T;
131 | }
132 |
133 | private static float Ease(float T)
134 | {
135 | return Lerp(EaseIn(T), EaseOut(T), T);
136 | }
137 |
138 | private static float Flip(float X)
139 | {
140 | return 1 - X;
141 | }
142 |
143 | ///
144 | /// Internal method, used by the timer to increment the final value.
145 | ///
146 | /// Thrown when invalid animation is played.
147 | private void Next()
148 | {
149 | if (!IsEnabled)
150 | {
151 | return;
152 | }
153 | if (IsFinished)
154 | {
155 | if (IsContinuous)
156 | {
157 | Invert();
158 | }
159 |
160 | return;
161 | }
162 |
163 | // Increased the elapsed time.
164 | ElapsedTime += DelayMS;
165 | }
166 |
167 | ///
168 | /// Inverts the animation direction.
169 | ///
170 | public void Invert()
171 | {
172 | (Source, Target) = (Target, Source);
173 | Reset();
174 | }
175 |
176 | public void Play()
177 | {
178 | IsEnabled = true;
179 | }
180 |
181 | public void Pause()
182 | {
183 | IsEnabled = false;
184 | }
185 |
186 | public void Stop()
187 | {
188 | IsEnabled = false;
189 | Reset();
190 | }
191 |
192 | ///
193 | /// Resets the progress and plays the new values if new ones were set.
194 | ///
195 | public void Reset()
196 | {
197 | ElapsedTime = 0;
198 | }
199 |
200 | #endregion
201 |
202 | #region Fields
203 |
204 | ///
205 | /// A value marking points in the animation.
206 | ///
207 | public float Source, Target, ElapsedTime;
208 |
209 | ///
210 | /// The animation mode to use.
211 | ///
212 | public AnimationMode Mode;
213 |
214 | ///
215 | /// The duration in which to play the animation over.
216 | ///
217 | public TimeSpan Duration;
218 |
219 | ///
220 | /// A bool to change if the animation is looping/continuous.
221 | ///
222 | public bool IsContinuous;
223 |
224 | ///
225 | /// Defines whether or not the animation is playing. False by default.
226 | ///
227 | public bool IsEnabled;
228 |
229 | ///
230 | /// Animation timer, used to increment the animation every 50 MS.
231 | ///
232 | public Timer Timer;
233 |
234 | #endregion
235 | }
--------------------------------------------------------------------------------
/PrismAPI/Graphics/Animation/AnimationMode.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Graphics.Animation;
2 |
3 | ///
4 | /// This is an enum to keep a list of all the possible fade types.
5 | ///
6 | public enum AnimationMode
7 | {
8 | ///
9 | /// This mode transitions from the starting value normally but begins to bounce the closer it gets to the end.
10 | ///
11 | BounceOut,
12 | ///
13 | /// This mode transitions from the starting value while bouncing but begins to transition normally the closer it gets to the end.
14 | ///
15 | BounceIn,
16 | ///
17 | /// This mode is a combo of and .
18 | ///
19 | Bounce,
20 | ///
21 | /// This mode fades a value in fast but slows down the closer it gets to the target value.
22 | ///
23 | EaseOut,
24 | ///
25 | /// This mode fades a value in slow but speeds the closer it gets to the target value.
26 | ///
27 | EaseIn,
28 | ///
29 | /// This mode is a combo of and .
30 | ///
31 | Ease,
32 | ///
33 | /// This mode is a smooth lear update method that has no speed differences.
34 | ///
35 | Linear,
36 | }
--------------------------------------------------------------------------------
/PrismAPI/Graphics/Animation/ColorController.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Graphics.Animation;
2 |
3 | ///
4 | /// The class, used to add basic ease transitions to colors.
5 | /// See:
6 | ///
7 | public class ColorController : AnimationController
8 | {
9 | #region Constructors
10 |
11 | ///
12 | /// Creates a new instance of the class.
13 | ///
14 | /// The starting value.
15 | /// The value to end at.
16 | /// The duration to play the animation over.
17 | /// The ease animation mode.
18 | public ColorController(Color Source, Color Target, TimeSpan Duration, AnimationMode Mode) : base(0f, 1f, Duration, Mode)
19 | {
20 | // Set-up all controllers for each color channel.
21 | this.Source = Source;
22 | this.Target = Target;
23 | }
24 |
25 | #endregion
26 |
27 | #region Properties
28 |
29 | ///
30 | /// The current color defined by the animation.
31 | ///
32 | public new Color Current => Color.Lerp(Source, Target, base.Current);
33 |
34 | #endregion
35 |
36 | #region Fields
37 |
38 | ///
39 | /// The source color of the animation.
40 | ///
41 | public new Color Source;
42 |
43 | ///
44 | /// The target color of the animation.
45 | ///
46 | public new Color Target;
47 |
48 | #endregion
49 | }
--------------------------------------------------------------------------------
/PrismAPI/Graphics/Fonts/Glyph.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Graphics.Fonts;
2 |
3 | ///
4 | /// The glyph class, used for caching font glyphs.
5 | /// See: https://github.com/Project-Prism/Prism-OS/tree/main/PrismGraphics/Font/README.md#Glyphs
6 | ///
7 | public class Glyph
8 | {
9 | #region Constructors
10 |
11 | ///
12 | /// Creates a new instance of the class.
13 | ///
14 | /// The width of the glyph.
15 | /// The height of the glyph.
16 | public Glyph(ushort Width, ushort Height)
17 | {
18 | this.Height = Height;
19 | this.Width = Width;
20 | Points = new();
21 | }
22 |
23 | #endregion
24 |
25 | #region Fields
26 |
27 | public List<(int X, int Y)> Points;
28 | public ushort Height;
29 | public ushort Width;
30 |
31 | #endregion
32 | }
--------------------------------------------------------------------------------
/PrismAPI/Graphics/Gradient.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Graphics;
2 |
3 | ///
4 | /// Gradient class, used for generating gradients.
5 | /// Reference: https://dev.to/ndesmic/linear-color-gradients-from-scratch-1a0e
6 | ///
7 | public class Gradient : Canvas
8 | {
9 | ///
10 | /// Creates a new gradient drawn on an instance of a object.
11 | ///
12 | /// Width (in pixels) of the gradient.
13 | /// Height (in pixels) of the gradient.
14 | /// The starting color.
15 | /// The end color.
16 | /// A new instance of a graphics object.
17 | public Gradient(ushort Width, ushort Height, Color Start, Color End) : base(Width, Height)
18 | {
19 | for (int I = 0; I < Height; I++)
20 | {
21 | DrawFilledRectangle(0, I, Width, 1, 0, Color.Lerp(Start, End, 1.0f / Height * I));
22 | }
23 | }
24 |
25 | ///
26 | /// Creates a new gradient drawn on an instance of a object.
27 | ///
28 | /// Width (in pixels) of the gradient.
29 | /// Height (in pixels) of the gradient.
30 | /// The colors to generate in the canvas.
31 | /// A new instance of a graphics object.
32 | public Gradient(ushort Width, ushort Height, Color[] Colors) : base(Width, Height)
33 | {
34 | // Calculate the height 'delta', it is the total width per gradient pair.
35 | int HeightDelta = Height / (Colors.Length - 1);
36 |
37 | // Loop over each color to draw in the gradient.
38 | for (int I1 = 0; I1 < Colors.Length - 1; I1++)
39 | {
40 | // Go over each line that the gradient will fill.
41 | for (int I2 = 0; I2 < HeightDelta; I2++)
42 | {
43 | // Get the interpolated color. It's calculated based on 'I1' and delta height index 'I2'.
44 | Color Calculated = Color.Lerp(Colors[I1], Colors[I1 + 1], 1.0f / HeightDelta * I2);
45 |
46 | // Fill this line with the correct color across with 1 pixel height.
47 | DrawFilledRectangle(0, (HeightDelta * I1) + I2, Width, 1, 0, Calculated);
48 | }
49 | }
50 | }
51 |
52 | ///
53 | /// Creates a new gradient drawn on an instance of a object.
54 | ///
55 | /// Width (in pixels) of the gradient.
56 | /// Height (in pixels) of the gradient.
57 | /// The total time passed in the gradient.
58 | /// A new instance of a graphics object.
59 | public Gradient(ushort Width, ushort Height, uint ElapsedMS) : base(Width, Height)
60 | {
61 | // Loop over all pixels.
62 | for (int X = 0; X < Width; X++)
63 | {
64 | for (int Y = 0; Y < Height; Y++)
65 | {
66 | // Normalized pixel coordinates (from 0 to 1)
67 | int UVY = Y / Height;
68 | int UVX = X / Width;
69 |
70 | // Time varying pixel color
71 | float R = 0.5f + (0.5f * MathF.Cos(ElapsedMS + UVX));
72 | float G = 0.5f + (0.5f * MathF.Cos(ElapsedMS + UVY + 2));
73 | float B = 0.5f + (0.5f * MathF.Cos(ElapsedMS + UVY + 4));
74 |
75 | // Output to screen
76 | this[X, Y] = new(255, R * 255, G * 255, B * 255);
77 | }
78 | }
79 | }
80 | }
--------------------------------------------------------------------------------
/PrismAPI/Graphics/Physics/Colisions/CubeColider.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Graphics.Physics.Colisions;
2 |
3 | public class CubeColider
4 | {
5 | // To-Do
6 | }
--------------------------------------------------------------------------------
/PrismAPI/Graphics/Physics/Gravity.cs:
--------------------------------------------------------------------------------
1 | using System.Numerics;
2 |
3 | namespace PrismAPI.Graphics.Physics;
4 |
5 | public class Gravity
6 | {
7 | public Gravity()
8 | {
9 | Velocity = Vector3.Zero;
10 | }
11 |
12 | #region Methods
13 |
14 | public void Next()
15 | {
16 | Velocity += Force - new Vector3(Mass);
17 | Velocity.Z -= 9.80665f;
18 |
19 | Speed = (Velocity.X + Velocity.Y + Velocity.Z) / 3;
20 | }
21 |
22 | #endregion
23 |
24 | #region Fields
25 |
26 | public Vector3 Velocity;
27 | public Vector3 Force;
28 | public float Speed;
29 | public float Mass;
30 |
31 | #endregion
32 | }
--------------------------------------------------------------------------------
/PrismAPI/Graphics/Rasterizer/Camera.cs:
--------------------------------------------------------------------------------
1 | using System.Numerics;
2 |
3 | namespace PrismAPI.Graphics.Rasterizer;
4 |
5 | ///
6 | /// The camera class, only used to represent location and rotation of a camera.
7 | ///
8 | public class Camera
9 | {
10 | #region Constructors
11 |
12 | ///
13 | /// Creates a new instance of the class.
14 | ///
15 | /// The FOV of the camera.
16 | public Camera(float FOV = 75f)
17 | {
18 | MovementSpeed = 10f;
19 | Sensitivity = .75f;
20 | Position = new();
21 | Rotation = new();
22 | Ambient = Color.White;
23 | this.FOV = FOV;
24 | }
25 |
26 | #endregion
27 |
28 | #region Methods
29 |
30 | ///
31 | /// Gets the rotation Quaternion for the camera projection.
32 | ///
33 | /// The rotation Quaternion as specified by the camera's rotation.
34 | public Quaternion GetRotationQuaternion()
35 | {
36 | return Quaternion.CreateFromYawPitchRoll(Rotation.X, Math.Clamp(Rotation.Y, -90f, 90f), Rotation.Z);
37 | }
38 |
39 | ///
40 | /// Gets the mouse to camera movement vector based on mouse inputs.
41 | ///
42 | /// The delta 'X' value of the mouse.
43 | /// The delta 'Y' value of the mouse.
44 | /// The width of the canvas.
45 | /// The height of the canvas.
46 | /// The rotation axis that the camera should add to.
47 | public Vector3 GetRotationAxis(float DeltaX, float DeltaY, ushort Width, ushort Height)
48 | {
49 | return new()
50 | {
51 | X = DeltaX != 0 ? -DeltaX * Sensitivity / Width : 0,
52 | Y = DeltaY != 0 ? DeltaY * Sensitivity / Height : 0,
53 | Z = 0,
54 | };
55 | }
56 |
57 | #endregion
58 |
59 | #region Fields
60 |
61 | public float MovementSpeed;
62 | public float Sensitivity;
63 | public Vector3 Position;
64 | public Vector3 Rotation;
65 | public Color Ambient;
66 | public float FOV;
67 |
68 | #endregion
69 | }
--------------------------------------------------------------------------------
/PrismAPI/Graphics/Rasterizer/Engine.cs:
--------------------------------------------------------------------------------
1 | using System.Numerics;
2 |
3 | namespace PrismAPI.Graphics.Rasterizer;
4 |
5 | ///
6 | /// The class - It is used to render 3D scenes onto a 2D canvas.
7 | ///
8 | /// - See also:
9 | /// - See also:
10 | /// - See also:
11 | /// - See also:
12 | ///
13 | ///
14 | public class Engine : Canvas
15 | {
16 | #region Constructors
17 |
18 | ///
19 | /// Creates a new instance of the class.
20 | ///
21 | /// Width (in pixels) of the canvas.
22 | /// Height (in pixels) of the canvas.
23 | /// The FOV (Field Of View) that the camera will have.
24 | public Engine(ushort Width, ushort Height, float FOV) : base(Width, Height)
25 | {
26 | this.Height = Height;
27 | this.Width = Width;
28 |
29 | SkyColor = Color.GoogleBlue;
30 | Lights = new();
31 | Objects = new();
32 | Camera = new(FOV);
33 | Zoom = 0f;
34 | }
35 |
36 | #endregion
37 |
38 | #region Methods
39 |
40 | ///
41 | /// Renders the whole scene onto the internal canvas.
42 | /// You must draw this object as an image on another canvas to show the output.
43 | ///
44 | public void Render()
45 | {
46 | // Create the camera rotation matrix - This is separate from the object rotation.
47 | Quaternion CameraQ = Camera.GetRotationQuaternion();
48 |
49 | // Create a new projection value. This is equivalent to using a projection matrix, but it is easier.
50 | float Translator = (float)(Width / 2 / Math.Tan((Camera.FOV + Zoom) / 2 * 0.0174532925)); // 0.0174532925 == pi / 180
51 |
52 | // Set the sky color - Make sure to adjust for ambiant color aswell.
53 | Clear(Color.Normalize(SkyColor) * Camera.Ambient);
54 |
55 | // Calculate Objects - Loops over all triangle in every mesh.
56 | foreach (Mesh M in Objects)
57 | {
58 | // Create a rotation matrix for the mesh - Separate from camera rotation.
59 | Matrix4x4 Rotation = M.GetRotationMatrix();
60 |
61 | foreach (Triangle T in M.Triangles)
62 | {
63 | // Create a temporary instance of the triangle that can be modified.
64 | Triangle Temp = T;
65 |
66 | Temp = Triangle.Transform(Temp, Rotation); // Apply object rotation - Separate from camera rotation.
67 | Temp = Triangle.Translate(Temp, M.Position); // Apply object translation - The position it is in 3D.
68 | Temp = Triangle.Transform(Temp, CameraQ); // Apply camera rotation - Rotates the entire world as one mesh.
69 | Temp = Triangle.Translate(Temp, Camera.Position); // Apply camera position - Adjusts the world as one mesh.
70 | Temp = Triangle.Translate(Temp, Translator); // Apply perspective translation - Applies a 3D effect.
71 |
72 | // Check if the triangle doesn't need to be drawn.
73 | if (Temp.GetNormal() < 0)
74 | {
75 | // Moves everything to center - Most 3D renderers do this.
76 | Temp = Triangle.Center(Temp, Width, Height);
77 |
78 | // Normalize lighting & apply ambiance.
79 | Temp.Color = Color.Normalize(Temp.Color);
80 | Temp.Color *= Camera.Ambient;
81 |
82 | // Rasterize the triangle.
83 | DrawFilledTriangle(Temp);
84 | }
85 | }
86 | }
87 | }
88 |
89 | #endregion
90 |
91 | #region Fields
92 |
93 | public List Lights;
94 | public List Objects;
95 | public Color SkyColor;
96 | public Camera Camera;
97 | public float Zoom;
98 |
99 | #endregion
100 | }
--------------------------------------------------------------------------------
/PrismAPI/Graphics/Rasterizer/Light.cs:
--------------------------------------------------------------------------------
1 | using System.Numerics;
2 |
3 | namespace PrismAPI.Graphics.Rasterizer;
4 |
5 | ///
6 | /// The class, used to represent a light's type, position, rotation, and color.
7 | ///
8 | public class Light
9 | {
10 | #region Constructors
11 |
12 | ///
13 | /// Creates a new instance of the class.
14 | ///
15 | /// The position of the light source.
16 | /// The rotation of the light source.
17 | /// The kind of light to render.
18 | /// The color of the light source.
19 | public Light(Vector3 Position, Vector3 Rotation, LightTypes Type, Color Color)
20 | {
21 | this.Position = Position;
22 | this.Rotation = Rotation;
23 | this.Color = Color;
24 | this.Type = Type;
25 | }
26 |
27 | #endregion
28 |
29 | #region Fields
30 |
31 | public Vector3 Position;
32 | public Vector3 Rotation;
33 | public LightTypes Type;
34 | public Color Color;
35 |
36 | #endregion
37 | }
--------------------------------------------------------------------------------
/PrismAPI/Graphics/Rasterizer/LightTypes.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Graphics.Rasterizer;
2 |
3 | ///
4 | /// The enum used to define the possible types of light.
5 | ///
6 | public enum LightTypes
7 | {
8 | Directional,
9 | Fixed,
10 | }
--------------------------------------------------------------------------------
/PrismAPI/Graphics/Rasterizer/Mesh.cs:
--------------------------------------------------------------------------------
1 | using System.Numerics;
2 |
3 | namespace PrismAPI.Graphics.Rasterizer;
4 |
5 | ///
6 | /// The class - Used to generate and load complet 3D shapes. Used in the class.
7 | ///
8 | /// - See also:
9 | /// - See also:
10 | ///
11 | ///
12 | public class Mesh
13 | {
14 | #region Constructors
15 |
16 | ///
17 | /// Creates a new instance of the class.
18 | ///
19 | public Mesh()
20 | {
21 | Triangles = new();
22 | Position = Vector3.Zero;
23 | Rotation = Vector3.Zero;
24 | }
25 |
26 | #endregion
27 |
28 | #region Methods
29 |
30 | ///
31 | /// Creates a new object from a '.obj' 3D file.
32 | /// See: https://docs.fileformat.com/3d/obj/
33 | ///
34 | /// The binary data of the object.
35 | /// A mesh containing the object.
36 | public static Mesh FromObject(byte[] Object, float Scale = 1f)
37 | {
38 | List Vertices = new(); // Create verticies buffer.
39 | Mesh Temp = new(); // Create temporary mesh object.
40 |
41 | // Create stream reader to read the input file.
42 | StreamReader Reader = new(new MemoryStream(Object));
43 |
44 | // Keep reading until the end of the file is reached.
45 | while (Reader.BaseStream.Position < Reader.BaseStream.Length)
46 | {
47 | // Get next line from input.
48 | string? Line = Reader.ReadLine();
49 |
50 | // Skip blank lines and comments
51 | if (string.IsNullOrWhiteSpace(Line) || Line[0] == '#')
52 | {
53 | continue;
54 | }
55 |
56 | // Trim & split input into all correct components.
57 | string[] Components = Line.Trim().Split(' ');
58 |
59 | // Check if line is empty - If so, skip it.
60 | if (Components.Length == 0)
61 | {
62 | continue;
63 | }
64 |
65 | // Check what kind of entry the line is.
66 | switch (Components[0])
67 | {
68 | // Vertex - One point in a triangle.
69 | case "v":
70 | // Throw error when an invalid input is detected.
71 | if (Components.Length != 4)
72 | {
73 | throw new FormatException("Invalid vertex format.");
74 | }
75 |
76 | // Attempt to load all coordinates for the vector into the vertex cache.
77 | try
78 | {
79 | Vertices.Add(new()
80 | {
81 | X = float.Parse(Components[1]) * Scale,
82 | Y = float.Parse(Components[2]) * Scale,
83 | Z = float.Parse(Components[3]) * Scale,
84 | });
85 | }
86 | catch
87 | {
88 | // Invalid vertex format!
89 | continue;
90 | }
91 | break;
92 |
93 | // Face - One triangle in the mesh.
94 | case "F":
95 | // Throw error when an invalid input is detected.
96 | if (Components.Length != 4)
97 | {
98 | throw new FormatException("Invalid face format.");
99 | }
100 |
101 | string[] ComponentsV1 = Components[1].Split('/');
102 | string[] ComponentsV2 = Components[2].Split('/');
103 | string[] ComponentsV3 = Components[3].Split('/');
104 |
105 | // Throw error when an invalid input is detected.
106 | if (ComponentsV1.Length != 1 || ComponentsV2.Length != 1 || ComponentsV3.Length != 1)
107 | {
108 | // Invalid vertex format!
109 | continue;
110 | }
111 |
112 | // Attempt to load proper vertices from the vector cache as a triangle into the mesh.
113 | try
114 | {
115 | Temp.Triangles.Add(new()
116 | {
117 | P1 = Vertices[int.Parse(ComponentsV1[0]) - 1],
118 | P2 = Vertices[int.Parse(ComponentsV2[0]) - 1],
119 | P3 = Vertices[int.Parse(ComponentsV3[0]) - 1],
120 | });
121 | }
122 | catch
123 | {
124 | // Invalid vertex format!
125 | continue;
126 | }
127 | break;
128 | }
129 | }
130 |
131 | // Return the temporary mesh value.
132 | return Temp;
133 | }
134 |
135 | ///
136 | /// Creates a new object that is a 'Cube', with a specifc size.
137 | ///
138 | /// The Width of the cube.
139 | /// The Height of the cube.
140 | /// The Length of the cube.
141 | /// A mesh object that is in the form of a cube, whos size is determined by the input.
142 | public static Mesh GetCube(float Width, float Height, float Length)
143 | {
144 | return new()
145 | {
146 | Triangles = new()
147 | {
148 | // South
149 | new(-(Width / 2), -(Height / 2), -(Length / 2), -(Width / 2), Height / 2, -(Length / 2), Width / 2, Height / 2, -(Length / 2), Color.White),
150 | new(-(Width / 2), -(Height / 2), -(Length / 2), Width / 2, Height / 2, -(Length / 2), Width / 2, -(Height / 2), -(Length / 2), Color.White),
151 |
152 | // East
153 | new(Width / 2, -(Height / 2), -(Length / 2), Width / 2, Height / 2, -(Length / 2), Width / 2, Height / 2, Length / 2, Color.CoolGreen),
154 | new(Width / 2, -(Height / 2), -(Length / 2), Width / 2, Height / 2, Length / 2, Width / 2, -(Height / 2), Length / 2, Color.CoolGreen),
155 |
156 | // North
157 | new(Width / 2, -(Height / 2), Length / 2, Width / 2, Height / 2, Length / 2, -(Width / 2), Height / 2, Length / 2, Color.White),
158 | new(Width / 2, -(Height / 2), Length / 2, -(Width / 2), Height / 2, Length / 2, -(Width / 2), -(Height / 2), Length / 2, Color.White),
159 |
160 | // West
161 | new(-(Width / 2), -(Height / 2), Length / 2, -(Width / 2), Height / 2, Length / 2, -(Width / 2), Height / 2, -(Length / 2), Color.CoolGreen),
162 | new(-(Width / 2), -(Height / 2), Length / 2, -(Width / 2), Height / 2, -(Length / 2), -(Width / 2), -(Height / 2), -(Length / 2), Color.CoolGreen),
163 |
164 | // Top
165 | new(-(Width / 2), Height / 2, -(Length / 2), -(Width / 2), Height / 2, Length / 2, Width / 2, Height / 2, Length / 2, Color.White),
166 | new(-(Width / 2), Height / 2, -(Length / 2), Width / 2, Height / 2, Length / 2, Width / 2, Height / 2, -(Length / 2), Color.White),
167 |
168 | // Bottom
169 | new(Width / 2, -(Height / 2), Length / 2, -(Width / 2), -(Height / 2), Length / 2, -(Width / 2), -(Height / 2), -(Length / 2), Color.White),
170 | new(Width / 2, -(Height / 2), Length / 2, -(Width / 2), -(Height / 2), -(Length / 2), Width / 2, -(Height / 2), -(Length / 2), Color.White),
171 | },
172 | };
173 | }
174 |
175 | ///
176 | /// Creates a new object that is a 'Plane', a specific with and height and 1 pixel tall.
177 | ///
178 | /// The Width of the plane.
179 | /// The Height of the plane.
180 | /// A new mesh plane, whos size is determined by the input.
181 | public static Mesh GetPlane(float Width, float Length)
182 | {
183 | return GetCube(Width, 1, Length);
184 | }
185 |
186 | ///
187 | /// Gets the rotation matrix for the mesh.
188 | ///
189 | /// - See:
190 | ///
191 | ///
192 | /// The rotation matrix based on the mesh's rotation.
193 | public Matrix4x4 GetRotationMatrix()
194 | {
195 | return Matrix4x4.CreateFromYawPitchRoll(Rotation.X, Rotation.Y, Rotation.Z);
196 | }
197 |
198 | public void TestLogic(float ElapsedTime)
199 | {
200 | //Rotation.Y += (DateTime.Now - LTime).TotalSeconds;
201 | //LTime = DateTime.Now;
202 | Rotation.X += ElapsedTime;
203 | }
204 |
205 | #endregion
206 |
207 | #region Fields
208 |
209 | // Vertecies
210 | public List Triangles;
211 | public Vector3 Position;
212 | public Vector3 Rotation;
213 |
214 | #endregion
215 | }
--------------------------------------------------------------------------------
/PrismAPI/Graphics/Rasterizer/Triangle.cs:
--------------------------------------------------------------------------------
1 | using System.Numerics;
2 |
3 | namespace PrismAPI.Graphics.Rasterizer;
4 |
5 | public class Triangle
6 | {
7 | #region Constructors
8 |
9 | public Triangle(float X1, float Y1, float Z1, float X2, float Y2, float Z2, float X3, float Y3, float Z3, Color Color)
10 | {
11 | // Assign current points.
12 | P1 = new(X1, Y1, Z1);
13 | P2 = new(X2, Y2, Z2);
14 | P3 = new(X3, Y3, Z3);
15 |
16 | // Assign the color value.
17 | this.Color = Color;
18 |
19 | // Assign other data.
20 | T1 = Vector3.Zero;
21 | T2 = Vector3.Zero;
22 | T3 = Vector3.Zero;
23 | L1 = Vector3.Zero;
24 | L2 = Vector3.Zero;
25 | L3 = Vector3.Zero;
26 | }
27 | public Triangle(Vector3 P1, Vector3 P2, Vector3 P3, Color Color)
28 | {
29 | // Assign current points.
30 | this.P1 = P1;
31 | this.P2 = P2;
32 | this.P3 = P3;
33 |
34 | // Assign the color value.
35 | this.Color = Color;
36 |
37 | // Assign other data.
38 | T1 = Vector3.Zero;
39 | T2 = Vector3.Zero;
40 | T3 = Vector3.Zero;
41 | L1 = Vector3.Zero;
42 | L2 = Vector3.Zero;
43 | L3 = Vector3.Zero;
44 | }
45 | public Triangle()
46 | {
47 | Color = Color.Black;
48 | P1 = Vector3.Zero;
49 | P2 = Vector3.Zero;
50 | P3 = Vector3.Zero;
51 | T1 = Vector3.Zero;
52 | T2 = Vector3.Zero;
53 | T3 = Vector3.Zero;
54 | L1 = Vector3.Zero;
55 | L2 = Vector3.Zero;
56 | L3 = Vector3.Zero;
57 | }
58 |
59 | #endregion
60 |
61 | #region Properties
62 |
63 | ///
64 | /// The Height in normal screen space of the triangle.
65 | ///
66 | public float Height
67 | {
68 | get
69 | {
70 | // Get the closest top and bottom components.
71 | float Top = MathF.Min(MathF.Min(P1.Y, P2.Y), P3.Y);
72 | float Bottom = MathF.Max(MathF.Max(P1.Y, P2.Y), P3.Y);
73 |
74 | return Bottom - Top;
75 | }
76 | }
77 |
78 | ///
79 | /// The Width in normal screen space of the triangle.
80 | ///
81 | public float Width
82 | {
83 | get
84 | {
85 | // Get the closest left and right components.
86 | float Left = MathF.Min(MathF.Min(P1.X, P2.X), P3.X);
87 | float Right = MathF.Max(MathF.Max(P1.X, P2.X), P3.X);
88 |
89 | return Right - Left;
90 | }
91 | }
92 |
93 | #endregion
94 |
95 | #region Methods
96 |
97 | ///
98 | /// Transforms the triangle with the standard vector transformation formula.
99 | ///
100 | /// The to transform.
101 | /// The to transform with.
102 | /// The transformed triangle.
103 | public static Triangle Transform(Triangle Triangle, Quaternion Transformation)
104 | {
105 | return new()
106 | {
107 | // Assign new point values.
108 | P1 = Vector3.Transform(Triangle.P1, Transformation),
109 | P2 = Vector3.Transform(Triangle.P2, Transformation),
110 | P3 = Vector3.Transform(Triangle.P3, Transformation),
111 |
112 | // Copy existing values.
113 | Color = Triangle.Color,
114 | T1 = Triangle.T1,
115 | T2 = Triangle.T2,
116 | T3 = Triangle.T3,
117 | L1 = Triangle.L1,
118 | L2 = Triangle.L2,
119 | L3 = Triangle.L3,
120 | };
121 | }
122 |
123 | ///
124 | /// Transforms the triangle with the standard vector transformation formula.
125 | ///
126 | /// The to transform.
127 | /// The to transform with.
128 | /// The transformed triangle.
129 | public static Triangle Transform(Triangle Triangle, Matrix4x4 Transformation)
130 | {
131 | return new()
132 | {
133 | // Assign new point values.
134 | P1 = Vector3.Transform(Triangle.P1, Transformation),
135 | P2 = Vector3.Transform(Triangle.P2, Transformation),
136 | P3 = Vector3.Transform(Triangle.P3, Transformation),
137 |
138 | // Copy existing values.
139 | Color = Triangle.Color,
140 | T1 = Triangle.T1,
141 | T2 = Triangle.T2,
142 | T3 = Triangle.T3,
143 | L1 = Triangle.L1,
144 | L2 = Triangle.L2,
145 | L3 = Triangle.L3,
146 | };
147 | }
148 |
149 | ///
150 | /// Translates or "moves" the triangle based on the input translation.
151 | ///
152 | /// The to transform.
153 | /// The translation to move the triangle by.
154 | /// Translated triangle.
155 | public static Triangle Translate(Triangle Triangle, Vector3 Translation)
156 | {
157 | return new()
158 | {
159 | // Assign new point values.
160 | P1 = Vector3.Add(Triangle.P1, Translation),
161 | P2 = Vector3.Add(Triangle.P2, Translation),
162 | P3 = Vector3.Add(Triangle.P3, Translation),
163 |
164 | // Copy existing values.
165 | Color = Triangle.Color,
166 | T1 = Triangle.T1,
167 | T2 = Triangle.T2,
168 | T3 = Triangle.T3,
169 | L1 = Triangle.L1,
170 | L2 = Triangle.L2,
171 | L3 = Triangle.L3,
172 | };
173 | }
174 |
175 | ///
176 | /// Multiplies the triangle by a translator 'matrix' - It is simpler than using a normal matrix.
177 | ///
178 | /// The to transform.
179 | /// The translator to use.
180 | /// A translated triangle, as defined by the input.
181 | public static Triangle Translate(Triangle Triangle, float Translator)
182 | {
183 | float Cache1 = Translator / (Translator + Triangle.P1.Z);
184 | float Cache2 = Translator / (Translator + Triangle.P2.Z);
185 | float Cache3 = Translator / (Translator + Triangle.P3.Z);
186 |
187 | Vector3 M1 = new(Cache1, Cache1, 1);
188 | Vector3 M2 = new(Cache2, Cache2, 1);
189 | Vector3 M3 = new(Cache3, Cache3, 1);
190 |
191 | return new()
192 | {
193 | // Assign new point values.
194 | P1 = Vector3.Multiply(Triangle.P1, M1),
195 | P2 = Vector3.Multiply(Triangle.P2, M2),
196 | P3 = Vector3.Multiply(Triangle.P3, M3),
197 |
198 | // Copy existing values.
199 | Color = Triangle.Color,
200 | T1 = Triangle.T1,
201 | T2 = Triangle.T2,
202 | T3 = Triangle.T3,
203 | L1 = Triangle.L1,
204 | L2 = Triangle.L2,
205 | L3 = Triangle.L3,
206 | };
207 | }
208 |
209 | ///
210 | /// Center the trangle in the screen.
211 | ///
212 | /// The to transform.
213 | /// The render screen pixel width.
214 | /// The render screen pixel height.
215 | /// Centered triangle.
216 | public static Triangle Center(Triangle Triangle, uint Width, uint Height)
217 | {
218 | return new()
219 | {
220 | // Assign new point values.
221 | P1 = Vector3.Add(Triangle.P1, new(Width / 2, Height / 2, 0)),
222 | P2 = Vector3.Add(Triangle.P2, new(Width / 2, Height / 2, 0)),
223 | P3 = Vector3.Add(Triangle.P3, new(Width / 2, Height / 2, 0)),
224 |
225 | // Copy existing values.
226 | Color = Triangle.Color,
227 | T1 = Triangle.T1,
228 | T2 = Triangle.T2,
229 | T3 = Triangle.T3,
230 | L1 = Triangle.L1,
231 | L2 = Triangle.L2,
232 | L3 = Triangle.L3,
233 | };
234 | }
235 |
236 | ///
237 | /// Gets the normal value of the triangle.
238 | ///
239 | /// Normal of the triangle.
240 | public float GetNormal()
241 | {
242 | return
243 | ((P2.X - P1.X) *
244 | (P3.Y - P1.Y)) -
245 | ((P2.Y - P1.Y) *
246 | (P3.X - P1.X));
247 | }
248 |
249 | #endregion
250 |
251 | #region Fields
252 |
253 | ///
254 | /// A point of the triangle.
255 | ///
256 | public Vector3 P1, P2, P3;
257 |
258 | ///
259 | /// A texture point of the triangle.
260 | ///
261 | public Vector3 T1, T2, T3;
262 |
263 | ///
264 | /// A light point of the triangle.
265 | ///
266 | public Vector3 L1, L2, L3;
267 |
268 | ///
269 | /// The Color of the triangle.
270 | ///
271 | public Color Color;
272 |
273 | #endregion
274 | }
--------------------------------------------------------------------------------
/PrismAPI/Hardware/GPU/Display.cs:
--------------------------------------------------------------------------------
1 | using PrismAPI.Hardware.GPU.VMWare;
2 | using PrismAPI.Hardware.GPU.Vesa;
3 | using Cosmos.Core.Multiboot;
4 | using PrismAPI.Graphics;
5 | using Cosmos.System;
6 |
7 | namespace PrismAPI.Hardware.GPU;
8 |
9 | ///
10 | /// The generic display interface. Used to abstract driver classes and get display output.
11 | ///
12 | public abstract class Display : Canvas
13 | {
14 | #region Constructors
15 |
16 | ///
17 | /// A generic constructor used to initialize the FPS counter.
18 | ///
19 | /// The Width of the display.
20 | /// The Height of the display.
21 | internal Display(ushort Width, ushort Height) : base(Width, Height)
22 | {
23 | // Setup the FPS counter timer.
24 | Timer T = new((_) => { _FPS = _Frames; _Frames = 0; }, null, 1000, 0);
25 |
26 | // Set up the mouse manager.
27 | MouseManager.ScreenHeight = Height;
28 | MouseManager.ScreenWidth = Width;
29 | }
30 |
31 | #endregion
32 |
33 | #region Properties
34 |
35 | ///
36 | /// A toggle telling whether the display is enabled or not.
37 | ///
38 | public abstract bool IsEnabled { get; set; }
39 |
40 | #endregion
41 |
42 | #region Methods
43 |
44 | ///
45 | /// Gets a display output, the best mode is automatically chosen.
46 | /// The Width and Height arguments may not always be used.
47 | ///
48 | /// The requested Width of the display.
49 | /// The requested Height of the display.
50 | /// An instance of the display class.
51 | public static Display GetDisplay(ushort Width, ushort Height)
52 | {
53 | if (VMTools.IsVMWare)
54 | {
55 | return new SVGAIICanvas(Width, Height);
56 | }
57 | if (Multiboot2.IsVBEAvailable)
58 | {
59 | return new VBECanvas();
60 | }
61 |
62 | throw new NotImplementedException("No display is available!");
63 | }
64 |
65 | ///
66 | /// Sets the position of the hardware accelerated cursor on the screen.
67 | /// Please note that this may not work on all display methods.
68 | ///
69 | /// The X-axis position.
70 | /// The Y-axis position.
71 | public abstract void SetCursor(uint X, uint Y, bool IsVisible);
72 |
73 | ///
74 | /// Sets the image of the hardware accelerated cursor.
75 | /// Please note that this may not work on all display methods.
76 | ///
77 | /// The image to use as the cursor.
78 | public abstract void DefineCursor(Canvas Cursor);
79 |
80 | ///
81 | /// Gets the display driver's name.
82 | ///
83 | /// the display name.
84 | public abstract string GetName();
85 |
86 | ///
87 | /// Coppies the second buffer to the primary display buffer.
88 | ///
89 | public abstract void Update();
90 |
91 | ///
92 | /// Gets the FPS measurment of the display.
93 | ///
94 | /// The FPS as a uint number.
95 | public uint GetFPS()
96 | {
97 | return _FPS;
98 | }
99 |
100 | #endregion
101 |
102 | #region Fields
103 |
104 | ///
105 | /// The internal frame counter, used for FPS calculation.
106 | ///
107 | internal uint _Frames;
108 |
109 | ///
110 | /// The internal FPS value, returned from .
111 | ///
112 | internal uint _FPS;
113 |
114 | #endregion
115 | }
--------------------------------------------------------------------------------
/PrismAPI/Hardware/GPU/VESA/VBECanvas.cs:
--------------------------------------------------------------------------------
1 | using Cosmos.Core.Multiboot;
2 | using Cosmos.HAL.Drivers.Video.SVGAII;
3 | using PrismAPI.Graphics;
4 |
5 | namespace PrismAPI.Hardware.GPU.Vesa;
6 |
7 | ///
8 | /// The VBE canvas extention class.
9 | ///
10 | public unsafe class VBECanvas : Display
11 | {
12 | #region Constructors
13 |
14 | ///
15 | /// Creates a new instance of the class.
16 | ///
17 | public VBECanvas() : base((ushort)Multiboot2.Framebuffer->Width, (ushort)Multiboot2.Framebuffer->Height) { }
18 |
19 | #endregion
20 |
21 | #region Properties
22 |
23 | public override bool IsEnabled
24 | {
25 | get => Multiboot2.IsVBEAvailable;
26 | set => throw new NotSupportedException("VBE does not offer disabling the display at runtime.");
27 | }
28 |
29 | public new ushort Height => throw new NotSupportedException("VBE does not offer changing the resolution at runtime.");
30 |
31 | public new ushort Width => throw new NotSupportedException("VBE does not offer changing the resolution at runtime.");
32 |
33 | #endregion
34 |
35 | #region Methods
36 |
37 | public override void SetCursor(uint X, uint Y, bool IsVisible)
38 | {
39 | throw new NotSupportedException("VBE does not offer hardware-accelerated cursor support.");
40 | }
41 |
42 | public override void DefineCursor(Canvas Cursor)
43 | {
44 | throw new NotSupportedException("VBE does not offer hardware-accelerated cursor support.");
45 | }
46 |
47 | public override string GetName()
48 | {
49 | return nameof(VBECanvas);
50 | }
51 |
52 | public override void Update()
53 | {
54 | CopyTo((uint*)Multiboot2.Framebuffer->Address);
55 | _Frames++;
56 | }
57 |
58 | #endregion
59 | }
--------------------------------------------------------------------------------
/PrismAPI/Hardware/GPU/VMWare/SVGAIICanvas.cs:
--------------------------------------------------------------------------------
1 | using Cosmos.HAL.Drivers.Video.SVGAII;
2 | using PrismAPI.Graphics;
3 | using Cosmos.Core;
4 | using Cosmos.HAL;
5 |
6 | namespace PrismAPI.Hardware.GPU.VMWare;
7 |
8 | ///
9 | /// The VMWare SVGAII canvas class. Allows for fast(er) graphics.
10 | ///
11 | public unsafe class SVGAIICanvas : Display
12 | {
13 | #region Constructors
14 |
15 | ///
16 | /// Creates a new instance of the class.
17 | ///
18 | /// Total width of the display.
19 | /// Total height of the display.
20 | public SVGAIICanvas(ushort Width, ushort Height) : base(0, 0) // Use 0 so no data is assigned.
21 | {
22 | Device = PCI.GetDevice(VendorID.VMWare, DeviceID.SVGAIIAdapter);
23 | Device.EnableMemory(true);
24 |
25 | uint BasePort = Device.BaseAddressBar[0].BaseAddress;
26 | IndexPort = (ushort)(BasePort + (uint)IOPortOffset.Index);
27 | ValuePort = (ushort)(BasePort + (uint)IOPortOffset.Value);
28 |
29 | WriteRegister(Register.ID, (uint)ID.V2);
30 | if (ReadRegister(Register.ID) != (uint)ID.V2)
31 | {
32 | throw new NotSupportedException("Un-supported SVGAII device! Please consider updating.");
33 | }
34 |
35 | FIFOMemory = new MemoryBlock(ReadRegister(Register.MemStart), ReadRegister(Register.MemSize));
36 | Features = ReadRegister(Register.Capabilities);
37 | InitializeFIFO();
38 |
39 | this.Height = Height;
40 | this.Width = Width;
41 | }
42 |
43 | #endregion
44 |
45 | #region Properties
46 |
47 | public override bool IsEnabled
48 | {
49 | get => ReadRegister(Register.Enable) == 1;
50 | set => WriteRegister(Register.Enable, value ? 1u : 0u);
51 | }
52 |
53 | public new ushort Height
54 | {
55 | get
56 | {
57 | return _Height;
58 | }
59 | set
60 | {
61 | // Memory resizing it already taken care of here.
62 | _Height = value;
63 |
64 | if (_Width != 0)
65 | {
66 | WriteRegister(Register.Width, Width);
67 | WriteRegister(Register.Height, Height);
68 | WriteRegister(Register.BitsPerPixel, 4);
69 | WriteRegister(Register.Enable, 1);
70 | InitializeFIFO();
71 |
72 | ScreenBuffer = (uint*)ReadRegister(Register.FrameBufferStart);
73 | Internal = ScreenBuffer + (Size * 4);
74 | }
75 | }
76 | }
77 |
78 | public new ushort Width
79 | {
80 | get
81 | {
82 | return _Width;
83 | }
84 | set
85 | {
86 | // Memory resizing it already taken care of here.
87 | _Width = value;
88 |
89 | if (_Height != 0)
90 | {
91 | WriteRegister(Register.Width, Width);
92 | WriteRegister(Register.Height, Height);
93 | WriteRegister(Register.BitsPerPixel, 4);
94 | WriteRegister(Register.Enable, 1);
95 | InitializeFIFO();
96 |
97 | ScreenBuffer = (uint*)ReadRegister(Register.FrameBufferStart);
98 | Internal = ScreenBuffer + (Size * 4);
99 | }
100 | }
101 | }
102 |
103 | #endregion
104 |
105 | #region Methods
106 |
107 | ///
108 | /// Write register.
109 | ///
110 | /// A register.
111 | /// A value.
112 | public void WriteRegister(Register register, uint value)
113 | {
114 | IOPort.Write32(IndexPort, (uint)register);
115 | IOPort.Write32(ValuePort, value);
116 | }
117 |
118 | ///
119 | /// Read register.
120 | ///
121 | /// A register.
122 | /// uint value.
123 | public uint ReadRegister(Register register)
124 | {
125 | IOPort.Write32(IndexPort, (uint)register);
126 | return IOPort.Read32(ValuePort);
127 | }
128 |
129 | ///
130 | /// A method that checks if the device has a specific feature.
131 | ///
132 | /// The feature to check for.
133 | /// True if supported, otherwise false.
134 | public bool HasFeature(Capability Feature)
135 | {
136 | return (Features & (uint)Feature) != 0;
137 | }
138 |
139 | ///
140 | /// Set FIFO.
141 | ///
142 | /// Command.
143 | /// Value.
144 | ///
145 | public uint SetFIFO(FIFO cmd, uint value)
146 | {
147 | return FIFOMemory[(uint)cmd] = value;
148 | }
149 |
150 | ///
151 | /// Write to FIFO.
152 | ///
153 | /// Value to write.
154 | public void WriteToFifo(uint value)
155 | {
156 | if ((GetFIFO(FIFO.NextCmd) == GetFIFO(FIFO.Max) - 4 && GetFIFO(FIFO.Stop) == GetFIFO(FIFO.Min)) || GetFIFO(FIFO.NextCmd) + 4 == GetFIFO(FIFO.Stop))
157 | {
158 | WaitForFifo();
159 | }
160 |
161 | SetFIFO((FIFO)GetFIFO(FIFO.NextCmd), value);
162 | SetFIFO(FIFO.NextCmd, GetFIFO(FIFO.NextCmd) + 4);
163 |
164 | if (GetFIFO(FIFO.NextCmd) == GetFIFO(FIFO.Max))
165 | {
166 | SetFIFO(FIFO.NextCmd, GetFIFO(FIFO.Min));
167 | }
168 | }
169 |
170 | ///
171 | /// Get FIFO.
172 | ///
173 | /// FIFO command.
174 | /// uint value.
175 | public uint GetFIFO(FIFO cmd)
176 | {
177 | return FIFOMemory[(uint)cmd];
178 | }
179 |
180 | ///
181 | /// Initialize FIFO.
182 | ///
183 | public void InitializeFIFO()
184 | {
185 | FIFOMemory[(uint)FIFO.Min] = (uint)Register.FifoNumRegisters * sizeof(uint);
186 | FIFOMemory[(uint)FIFO.Max] = FIFOMemory.Size;
187 | FIFOMemory[(uint)FIFO.NextCmd] = FIFOMemory[(uint)FIFO.Min];
188 | FIFOMemory[(uint)FIFO.Stop] = FIFOMemory[(uint)FIFO.Min];
189 | WriteRegister(Register.ConfigDone, 1);
190 | }
191 |
192 | ///
193 | /// Wait for FIFO.
194 | ///
195 | public void WaitForFifo()
196 | {
197 | WriteRegister(Register.Sync, 1);
198 | while (ReadRegister(Register.Busy) != 0) { }
199 | }
200 |
201 | public override void SetCursor(uint X, uint Y, bool IsVisible)
202 | {
203 | WriteRegister(Register.CursorOn, (uint)(IsVisible ? 1 : 0));
204 | WriteRegister(Register.CursorX, X);
205 | WriteRegister(Register.CursorY, Y);
206 | WriteRegister(Register.CursorCount, ReadRegister(Register.CursorCount) + 1);
207 | }
208 |
209 | public override void DefineCursor(Canvas Cursor)
210 | {
211 | if (!HasFeature(Capability.AlphaCursor))
212 | {
213 | throw new NotSupportedException("This device does not have accelerated cursor support.");
214 | }
215 |
216 | WaitForFifo();
217 | WriteToFifo((uint)FIFOCommand.DEFINE_ALPHA_CURSOR);
218 | WriteToFifo(0); // ID
219 | WriteToFifo(0); // Hotspot X
220 | WriteToFifo(0); // Hotspot Y
221 | WriteToFifo(Cursor.Width); // Width
222 | WriteToFifo(Cursor.Height); // Height
223 |
224 | for (uint I = 0; I < Cursor.Size; I++)
225 | {
226 | WriteToFifo(Cursor[I].ARGB);
227 | }
228 |
229 | WaitForFifo();
230 | }
231 |
232 | public override string GetName()
233 | {
234 | return nameof(SVGAIICanvas);
235 | }
236 |
237 | public override void Update()
238 | {
239 | CopyTo(ScreenBuffer);
240 |
241 | WriteToFifo((uint)FIFOCommand.Update);
242 | WriteToFifo(0);
243 | WriteToFifo(0);
244 | WriteToFifo(Width);
245 | WriteToFifo(Height);
246 | WaitForFifo();
247 |
248 | _Frames++;
249 | }
250 |
251 | #endregion
252 |
253 | #region Fields
254 |
255 | public readonly MemoryBlock FIFOMemory;
256 | public readonly PCIDevice Device;
257 | public readonly ushort IndexPort;
258 | public readonly ushort ValuePort;
259 | public readonly uint Features;
260 | public uint* ScreenBuffer;
261 |
262 | #endregion
263 | }
--------------------------------------------------------------------------------
/PrismAPI/Network/HTTP/HTTPClient.cs:
--------------------------------------------------------------------------------
1 | using Cosmos.System.Network.IPv4.TCP;
2 | using Cosmos.System.Network.IPv4;
3 | using System.Text;
4 |
5 | namespace PrismAPI.Network.HTTP;
6 |
7 | public class HTTPClient
8 | {
9 | #region Constructors
10 |
11 | public HTTPClient(string URL)
12 | {
13 | this.URL = new(URL);
14 | }
15 |
16 | public HTTPClient(URL URL)
17 | {
18 | this.URL = URL;
19 | }
20 |
21 | public HTTPClient()
22 | {
23 | URL = new("");
24 | }
25 |
26 | #endregion
27 |
28 | #region Methods
29 |
30 | public byte[] Get()
31 | {
32 | int Port = URL.HasPort ? int.Parse(URL.Port) : 80;
33 |
34 | EndPoint EP = new(URL.Address, (ushort)Port);
35 | string Request =
36 | $"GET {URL.Path} HTTP/1.1\n" +
37 | "Connection: Keep - Alive";
38 |
39 | TcpClient Client = new(URL.Address, Port);
40 | Client.Connect(URL.Address, Port);
41 | Client.Send(Encoding.UTF8.GetBytes(Request));
42 | return Client.Receive(ref EP);
43 | }
44 |
45 | #endregion
46 |
47 | #region Fields
48 |
49 | public URL URL;
50 |
51 | #endregion
52 |
53 | }
--------------------------------------------------------------------------------
/PrismAPI/Network/HTTP/HTTPStatus.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Network.HTTP;
2 |
3 | // Reference: https://loadium.com/blog/the-list-of-http-response-status-codes
4 | public enum HTTPStatus
5 | {
6 | // Infornmational
7 | SwitchingProtocols = 101,
8 | Processing = 102,
9 | EarlyHints = 103,
10 |
11 | // Success
12 | OK = 200,
13 | Created = 201,
14 | Accepted = 202,
15 | NonAuthoritativeInformation = 203,
16 | NoContent = 204,
17 | ResetContent = 205,
18 | PartialContent = 206,
19 | MultiStatus = 207,
20 | AlreadyReported = 208,
21 | IMUsed = 226,
22 |
23 | // Redirection Messages
24 | MultiChoice = 300,
25 | Found = 302,
26 | SeeOther = 303,
27 | NotModified = 304,
28 | UserProxy = 305,
29 | Unused = 306,
30 | TemporaryRedirect = 307,
31 | PermanentRedirect = 308,
32 |
33 | // Client Errors
34 | BadRequest = 400,
35 | Unauthorized = 401,
36 | PaymentRequired = 402,
37 | Forbidden = 403,
38 | NotFound = 404,
39 | MethodNotAllowed = 405,
40 | NotAcceptable = 406,
41 | TemporaryRedirectProxy = 407,
42 | RequestTimeout = 408,
43 | Conflict = 409,
44 | Gone = 410,
45 | LengthRequired = 411,
46 | PreconditionFailed = 412,
47 | PayloadTooLarge = 413,
48 | URITooLong = 414,
49 | UnsupportedMediaType = 415,
50 | RequestedRangeNotSatisfiable = 416,
51 | ExpectationFailed = 417,
52 | ImATeapot = 418,
53 | MisdirectedRequest = 421,
54 | UnprocessableEntity = 422,
55 | Locked = 423,
56 | FailedDependancy = 424,
57 | TooEarly = 425,
58 | UpgradeRequired = 426,
59 | PreconditionRequired = 428,
60 | TooManyRequests = 429,
61 | RequestHeaderFieldsTooLarge = 431,
62 | UnavailableForLegalReasons = 451,
63 |
64 | // Server Error Responses
65 | InternalServerError = 500,
66 | NotImplemented = 501,
67 | BadGateway = 502,
68 | ServiceUnavailable = 503,
69 | GatewayTimeout = 504,
70 | HTTPVersionNotSupported = 505,
71 | VariantAlsoNegotiates = 506,
72 | InsufficientStorage = 507,
73 | LoopDetected = 508,
74 | NotExtended = 510,
75 | NetworkAuthenticationRequired = 511,
76 | }
--------------------------------------------------------------------------------
/PrismAPI/Network/NetworkManager.cs:
--------------------------------------------------------------------------------
1 | using Cosmos.System.Network.IPv4.UDP.DHCP;
2 | using Cosmos.System.Network.IPv4.UDP.DNS;
3 | using Cosmos.System.Network.IPv4.TCP;
4 | using Cosmos.System.Network.IPv4;
5 | using PrismAPI.Tools.Diagnostics;
6 |
7 | namespace PrismAPI.Network;
8 |
9 | public static class NetworkManager
10 | {
11 | #region Methods
12 |
13 | ///
14 | /// Pings an IP address.
15 | ///
16 | ///
17 | /// Time in miliseconds it takes for the server to respond.
18 | public static ulong Ping(Address A)
19 | {
20 | DateTime T = DateTime.Now;
21 | new TcpClient().Connect(A, 80);
22 | return (ulong)(DateTime.Now - T).TotalMilliseconds;
23 | }
24 |
25 | ///
26 | /// Initializes the system networking interface.
27 | ///
28 | public static void Init()
29 | {
30 | try
31 | {
32 | // Initialize the network;
33 | Debugger = new("Network");
34 |
35 | Debugger.WritePartial("Initializing network...");
36 |
37 | // Initialize networking.
38 | _ = new DHCPClient().SendDiscoverPacket();
39 |
40 | // Set-up the DNS (cloudflare).
41 | DNSClient.Connect(new(1, 1, 1, 1));
42 | Debugger.Finalize(Severity.Success);
43 | }
44 | catch
45 | {
46 | Debugger.Finalize(Severity.Fail);
47 | }
48 | }
49 |
50 | #endregion
51 |
52 | #region Fields
53 |
54 | public static DnsClient DNSClient = null!;
55 | public static Debugger Debugger = null!;
56 |
57 | #endregion
58 | }
--------------------------------------------------------------------------------
/PrismAPI/Network/URL.cs:
--------------------------------------------------------------------------------
1 | using Cosmos.System.Network.IPv4;
2 |
3 | namespace PrismAPI.Network;
4 |
5 | ///
6 | /// URL parsing class.
7 | ///
8 | public class URL
9 | {
10 | #region Constructors
11 |
12 | ///
13 | /// Creates a new instance of she class.
14 | ///
15 | ///
16 | public URL(string FullURL)
17 | {
18 | this.FullURL = FullURL;
19 | }
20 |
21 | #endregion
22 |
23 | #region Properties
24 |
25 | public bool HasProtocol => FullURL.Contains(Delimiter);
26 |
27 | public bool HasPort => FullURL.Contains(':');
28 |
29 | public Address Address
30 | {
31 | get
32 | {
33 | NetworkManager.DNSClient.SendAsk(Host);
34 | return NetworkManager.DNSClient.Receive();
35 | }
36 | }
37 |
38 | public string Protocol
39 | {
40 | get
41 | {
42 | if (!HasProtocol)
43 | {
44 | return string.Empty;
45 | }
46 |
47 | return FullURL[..FullURL.IndexOf(Delimiter)];
48 | }
49 | set
50 | {
51 | if (!HasProtocol)
52 | {
53 | return;
54 | }
55 |
56 | FullURL = FullURL.Replace(Protocol + Delimiter, value + Delimiter);
57 | }
58 | }
59 |
60 | public string Host
61 | {
62 | get
63 | {
64 | string Temp = FullURL;
65 |
66 | if (HasProtocol)
67 | {
68 | Temp = Temp.Replace(Protocol + Delimiter, string.Empty);
69 | }
70 |
71 | return Temp.Split('/')[0].Split(':')[0];
72 | }
73 | set
74 | {
75 | FullURL = FullURL.Replace(Delimiter + Host, Delimiter + value);
76 | }
77 | }
78 |
79 | public string Path
80 | {
81 | get
82 | {
83 | string Temp = FullURL;
84 |
85 | if (HasProtocol)
86 | {
87 | Temp = Temp.Replace(Protocol + Delimiter, string.Empty);
88 | }
89 |
90 | return Temp.Split(Host + /*':' + Port +*/ '/')[1];
91 | }
92 | set
93 | {
94 | FullURL = FullURL.Replace(Host + /*':' + Port +*/ '/' + Path, Host + /*':' + Port +*/ '/' + value);
95 | }
96 | }
97 |
98 | public string Port
99 | {
100 | get
101 | {
102 | string Temp = FullURL;
103 |
104 | if (HasProtocol)
105 | {
106 | Temp = Temp.Replace(Protocol + Delimiter, string.Empty);
107 | }
108 |
109 | return Temp.Split('/')[0].Split(':')[1];
110 | }
111 | }
112 |
113 | #endregion
114 |
115 | #region Constants
116 |
117 | public const string Delimiter = "://";
118 |
119 | #endregion
120 |
121 | #region Fields
122 |
123 | public string FullURL;
124 |
125 | #endregion
126 | }
--------------------------------------------------------------------------------
/PrismAPI/PrismAPI.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | GPL-2.0-or-later
7 | false
8 | true
9 | true
10 | false
11 | true
12 | net6.0
13 | enable
14 | true
15 | The Prism Project
16 | true
17 | PrismAPI
18 | none
19 | enable
20 | true
21 | 1.0.3
22 | PrismAPI
23 |
24 |
25 |
26 |
27 | The PrismAPI package, can be used for many purposed in external cosmos projects.
28 | This project offers no waranty (as shown by the license) and is not garunteed to work 100% of the time.
29 | Use within your reasonale needs and give credits where due.
30 |
31 | Full API documentation: https://prism-project.net/Documentation/
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/PrismAPI/Runtime/Executable.cs:
--------------------------------------------------------------------------------
1 | using PrismAPI.Filesystem.Formats.ELF.ELFProgramHeader;
2 | using PrismAPI.Filesystem.Formats.ELF.ELFHeader;
3 | using PrismAPI.Filesystem.Formats.ELF;
4 | using PrismAPI.Runtime.SystemCall;
5 |
6 | namespace PrismAPI.Runtime;
7 |
8 | ///
9 | /// The base abstract level of an executable.
10 | /// Includes a pointer to an entry point and a permissions level indicator.
11 | ///
12 | public unsafe class Executable
13 | {
14 | public Executable()
15 | {
16 | Main = (delegate* unmanaged)0;
17 | Permissions = AccessLevel.User;
18 | }
19 |
20 | #region Methods
21 |
22 | ///
23 | /// Loads an executable from an ELF (32-bit) binary.
24 | ///
25 | /// The input ELF file as binary.
26 | /// An executable with the entry point of the input ELF binary.
27 | /// Thrown when program isn't supported.
28 | public static Executable FromELF32(byte[] Binary)
29 | {
30 | Executable Temp = new();
31 |
32 | fixed (byte* P = Binary)
33 | {
34 | // Load main file header.
35 | ELFHeader32 Header = new((ELFHeader32*)P);
36 |
37 | // Assign entry point.
38 | Temp.Main = (delegate* unmanaged)Header.EntryPoint;
39 |
40 | // Load the first program header.
41 | ELFProgramHeader32* PHeader = (ELFProgramHeader32*)(P + Header.PHOffset);
42 |
43 | // Load all program headers.
44 | for (int I = 0; I < Header.PHCount; I++, PHeader++)
45 | {
46 | switch (PHeader->Type)
47 | {
48 | case ELFProgramType.Null:
49 | break;
50 | case ELFProgramType.Load:
51 | Buffer.MemoryCopy(PHeader + PHeader->Offset, (byte*)PHeader->VAddress, PHeader->FileSize, PHeader->FileSize);
52 | break;
53 | default:
54 | throw new ArgumentException("Unsupported program type!");
55 | }
56 | }
57 | }
58 |
59 | return Temp;
60 | }
61 |
62 | ///
63 | /// Loads an executable from an ELF (64-bit) binary.
64 | ///
65 | /// The input ELF file as binary.
66 | /// An executable with the entry point of the input ELF binary.
67 | /// Thrown when program isn't supported.
68 | public static Executable FromELF64(byte[] Binary)
69 | {
70 | Executable Temp = new();
71 |
72 | fixed (byte* P = Binary)
73 | {
74 | // Load main file header.
75 | ELFHeader64 Header = new((ELFHeader64*)P);
76 |
77 | // Assign entry point.
78 | Temp.Main = (delegate* unmanaged)(Header.EntryPoint + 512);
79 |
80 | // Load the first program header.
81 | ELFProgramHeader64* PHeader = (ELFProgramHeader64*)(P + Header.PHOffset);
82 |
83 | // Load all program headers.
84 | for (int I = 0; I < Header.PHCount; I++, PHeader++)
85 | {
86 | switch (PHeader->Type)
87 | {
88 | case ELFProgramType.Null:
89 | break;
90 | case ELFProgramType.Load:
91 | Buffer.MemoryCopy((byte*)PHeader->VAddress, P + PHeader->Offset, PHeader->FileSize, PHeader->FileSize);
92 | break;
93 | default:
94 | throw new ArgumentException("Unsupported program type!");
95 | }
96 | }
97 | }
98 |
99 | return Temp;
100 | }
101 |
102 | ///
103 | /// Loads an executable from a flat binary.
104 | ///
105 | /// The input flat binary.
106 | /// An executable with the entry point of the input binary.
107 | public static Executable FromBIN(byte[] Binary)
108 | {
109 | Executable Temp = new();
110 |
111 | fixed (byte* P = Binary)
112 | {
113 | // This assigns the delegate pointer to the entry point of the program.
114 | // It is a delegate as it can be called by just using Main as a method.
115 | Temp.Main = (delegate* unmanaged)P;
116 | }
117 |
118 | return Temp;
119 | }
120 |
121 | #endregion
122 |
123 | #region Fields
124 |
125 | public delegate* unmanaged Main;
126 | public AccessLevel Permissions;
127 |
128 | #endregion
129 | }
--------------------------------------------------------------------------------
/PrismAPI/Runtime/SSharp/Binary.cs:
--------------------------------------------------------------------------------
1 | using PrismAPI.Runtime.SSharp.Structure;
2 |
3 | namespace PrismAPI.Runtime.SSharp;
4 |
5 | public unsafe class Binary
6 | {
7 | ///
8 | /// Creates a new instance of the class.
9 | ///
10 | /// Raw executable binary.
11 | public Binary(byte[] Binary)
12 | {
13 | ROM = new(new MemoryStream(Binary));
14 | IsEnabled = true;
15 | }
16 |
17 | #region Methods
18 |
19 | ///
20 | /// Dumps the data as human-readable text to the console.
21 | ///
22 | public void Dump()
23 | {
24 | // Backup and reset position so we can continue later.
25 | long BPoint = ROM.BaseStream.Position;
26 | ROM.BaseStream.Position = 0;
27 |
28 | for (; ROM.BaseStream.Position < ROM.BaseStream.Length - 1;)
29 | {
30 | // Check instruction type.
31 | switch ((OPCode)ROM.ReadByte())
32 | {
33 | case OPCode.System_Runtime_ThrowException:
34 | Console.WriteLine($"System_Runtime_ThrowException: {ROM.ReadString()}");
35 | break;
36 | case OPCode.System_Console_WriteLine:
37 | Console.WriteLine($"System_Console_WriteLine: {ROM.ReadString()}");
38 | break;
39 | case OPCode.System_Console_Write:
40 | Console.WriteLine($"System_Console_Write: {ROM.ReadString()}");
41 | break;
42 | case OPCode.System_Runtime_Exit:
43 | Console.WriteLine("System_Runtime_Exit");
44 | break;
45 | case OPCode.System_Inline_Jump:
46 | Console.WriteLine("System_Inline_Jump");
47 | break;
48 | }
49 | }
50 |
51 | // Return to original position.
52 | ROM.BaseStream.Position = BPoint;
53 | }
54 |
55 | ///
56 | /// Runs next instruction in the executable.
57 | ///
58 | public void Next()
59 | {
60 | // Make sure executable can run.
61 | if (ROM.BaseStream.Position == ROM.BaseStream.Length)
62 | {
63 | IsEnabled = false;
64 | }
65 | if (!IsEnabled)
66 | {
67 | return;
68 | }
69 |
70 | // Check instruction type.
71 | switch ((OPCode)ROM.ReadByte())
72 | {
73 | case OPCode.System_Runtime_ThrowException:
74 | Console.WriteLine($"Exception: {ROM.ReadString()}");
75 | break;
76 | case OPCode.System_Console_WriteLine:
77 | Console.WriteLine(ROM.ReadString());
78 | break;
79 | case OPCode.System_Console_Write:
80 | Console.Write(ROM.ReadString());
81 | break;
82 | case OPCode.System_Runtime_Exit:
83 | IsEnabled = false;
84 | break;
85 | case OPCode.System_Inline_Jump:
86 | ROM.BaseStream.Position = (long)ROM.ReadUInt64();
87 | break;
88 | }
89 | }
90 |
91 | #endregion
92 |
93 | #region Fields
94 |
95 | public BinaryReader ROM;
96 | public bool IsEnabled;
97 |
98 | #endregion
99 | }
--------------------------------------------------------------------------------
/PrismAPI/Runtime/SSharp/Compiler.cs:
--------------------------------------------------------------------------------
1 | using PrismAPI.Runtime.SSharp.Structure;
2 | using PrismAPI.Tools.Diagnostics;
3 | using PrismAPI.Tools.Extentions;
4 |
5 | namespace PrismAPI.Runtime.SSharp;
6 |
7 | public static class Compiler
8 | {
9 | #region Methods
10 |
11 | ///
12 | /// Compiles S# code into a S# runtime-compatable executable.
13 | ///
14 | /// S# Source.
15 | /// S# Executable.
16 | public static Binary Compile(string Input)
17 | {
18 | // Set binary output.
19 | BinaryWriter Output = new(new MemoryStream());
20 |
21 | try
22 | {
23 | // Generate tokens from output
24 | Token[] Tokens = Tokenizer.GetTokens(Input);
25 |
26 | for (int I = 0; I < Tokens.Length; I++)
27 | {
28 | // If tokens are in a call order...
29 | if (Tokens[I].Type == TokenType.Literal && Tokens[I + 1].Type == TokenType.LParenthasis)
30 | {
31 | // Check call name.
32 | switch (Tokens[I++].Value)
33 | {
34 | #region Throw
35 |
36 | case "Throw":
37 | Output.Write((byte)OPCode.System_Runtime_ThrowException);
38 |
39 | // Check for correct (string) type.
40 | if (Tokens[++I].Type != TokenType.String)
41 | {
42 | throw new($"{StringEx.GetLineColumn(Input, Tokens[I].Index)}: Unexpected type '{Tokens[I].Type}'.");
43 | }
44 |
45 | Output.Write(Tokens[I].Value);
46 | Output.Write((byte)OPCode.System_Runtime_Exit);
47 | break;
48 |
49 | #endregion
50 | #region WriteLine
51 |
52 | case "Console.WriteLine":
53 | Output.Write((byte)OPCode.System_Console_WriteLine);
54 |
55 | // Check for correct (string) type.
56 | if (Tokens[++I].Type != TokenType.String)
57 | {
58 | throw new($"{StringEx.GetLineColumn(Input, Tokens[I].Index)}: Unexpected type '{Tokens[I].Type}'.");
59 | }
60 |
61 | Output.Write(Tokens[I].Value);
62 | break;
63 |
64 | #endregion
65 | #region Write
66 |
67 | case "Console.Write":
68 | Output.Write((byte)OPCode.System_Console_Write);
69 |
70 | // Check for correct (string) type.
71 | if (Tokens[++I].Type != TokenType.String)
72 | {
73 | throw new($"{StringEx.GetLineColumn(Input, Tokens[I].Index)}: Unexpected type '{Tokens[I].Type}'.");
74 | }
75 |
76 | Output.Write(Tokens[I].Value);
77 | break;
78 |
79 | #endregion
80 | #region Exit
81 |
82 | case "Exit":
83 | Output.Write((byte)OPCode.System_Runtime_Exit);
84 | break;
85 |
86 | #endregion
87 | #region Jump
88 |
89 | case "Jump":
90 | Output.Write((byte)OPCode.System_Inline_Jump);
91 |
92 | // Check for correct (number) type.
93 | if (Tokens[++I].Type != TokenType.Number)
94 | {
95 | throw new($"{StringEx.GetLineColumn(Input, Tokens[I].Index)}: Unexpected type '{Tokens[I].Type}'.");
96 | }
97 |
98 | Output.Write(ulong.Parse(Tokens[I].Value));
99 | break;
100 |
101 | #endregion
102 | default:
103 | // Error if method does not exist.
104 | throw new($"Unexpected '{Tokens[I - 1].Value}' at {StringEx.GetLineColumn(Input, I - 1)}!");
105 | }
106 | }
107 | }
108 |
109 | // Write final exit code so app does not run forever.
110 | Output.Write((byte)OPCode.System_Runtime_Exit);
111 |
112 | // Return raw executable.
113 | return new(((MemoryStream)Output.BaseStream).ToArray());
114 | }
115 | catch (Exception E)
116 | {
117 | Debugger.WriteFull($"Critical error! ({E.Message}).", Severity.Fail);
118 |
119 | // Return raw executable.
120 | return new(((MemoryStream)Output.BaseStream).ToArray());
121 | }
122 | }
123 |
124 | #endregion
125 |
126 | #region Fields
127 |
128 | public static Debugger Debugger { get; set; } = new("S#");
129 |
130 | #endregion
131 | }
--------------------------------------------------------------------------------
/PrismAPI/Runtime/SSharp/Structure/OPCode.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Runtime.SSharp.Structure;
2 |
3 | public enum OPCode
4 | {
5 | #region Console
6 |
7 | System_Console_WriteLine,
8 | System_Console_Write,
9 |
10 | #endregion
11 |
12 | #region Runtime
13 |
14 | System_Runtime_ThrowException,
15 | System_Runtime_Exit,
16 |
17 | #endregion
18 |
19 | #region Inline
20 |
21 | System_Inline_Jump,
22 |
23 | #endregion
24 | }
--------------------------------------------------------------------------------
/PrismAPI/Runtime/SSharp/Structure/Token.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Runtime.SSharp.Structure;
2 |
3 | public class Token
4 | {
5 | ///
6 | /// Creates a new instance of the class.
7 | ///
8 | /// The type of token.
9 | /// The text value of the token.
10 | /// The index of the token in the source code.
11 | public Token(TokenType Type, string Value, int Index)
12 | {
13 | this.Type = Type;
14 | this.Value = Value;
15 | this.Index = Index;
16 | }
17 |
18 | #region Fields
19 |
20 | public TokenType Type;
21 | public string Value;
22 | public int Index;
23 |
24 | #endregion
25 | }
--------------------------------------------------------------------------------
/PrismAPI/Runtime/SSharp/Structure/TokenType.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Runtime.SSharp.Structure;
2 |
3 | public enum TokenType
4 | {
5 | LParenthasis,
6 | RParenthasis,
7 | LCBracket,
8 | RCBracket,
9 | SemiColon,
10 | LBracket,
11 | RBracket,
12 | Literal,
13 | String,
14 | Number,
15 | Colon,
16 | Comma,
17 | }
--------------------------------------------------------------------------------
/PrismAPI/Runtime/SSharp/Tokenizer.cs:
--------------------------------------------------------------------------------
1 | using PrismAPI.Runtime.SSharp.Structure;
2 | using PrismAPI.Tools.Extentions;
3 |
4 | namespace PrismAPI.Runtime.SSharp;
5 |
6 | public static class Tokenizer
7 | {
8 | ///
9 | /// Generates a list of tokens with values based on the input.
10 | ///
11 | /// Input S# code to get tokens from.
12 | /// Array of tokens.
13 | public static Token[] GetTokens(string Input)
14 | {
15 | List Tokens = new();
16 | string T = string.Empty;
17 |
18 | for (int I = 0; I < Input.Length; I++)
19 | {
20 | // Skip whitespace.
21 | if (char.IsWhiteSpace(Input[I]))
22 | {
23 | continue;
24 | }
25 |
26 | // Check for valid syntax.
27 | if (!char.IsLetter(Input[I]) && (!char.IsNumber(Input[I]) || Input[I] == '.') && Input[I] != '.')
28 | {
29 | // Add literal text if ready.
30 | if (T.Length != 0)
31 | {
32 | if (double.TryParse(T, out double D))
33 | {
34 | Tokens.Add(new(TokenType.Number, D.ToString(), I));
35 | T = string.Empty;
36 | }
37 | else
38 | {
39 | Tokens.Add(new(TokenType.Literal, T, I));
40 | T = string.Empty;
41 | }
42 | }
43 |
44 | switch (Input[I])
45 | {
46 | case '(':
47 | Tokens.Add(new(TokenType.LParenthasis, "(", I));
48 | break;
49 | case ')':
50 | Tokens.Add(new(TokenType.RParenthasis, ")", I));
51 | break;
52 | case '{':
53 | Tokens.Add(new(TokenType.LCBracket, "{", I));
54 | break;
55 | case '}':
56 | Tokens.Add(new(TokenType.RCBracket, "}", I));
57 | break;
58 | case ';':
59 | Tokens.Add(new(TokenType.SemiColon, ";", I));
60 | break;
61 | case '[':
62 | Tokens.Add(new(TokenType.LBracket, "[", I));
63 | break;
64 | case ']':
65 | Tokens.Add(new(TokenType.RBracket, "]", I));
66 | break;
67 | case ':':
68 | Tokens.Add(new(TokenType.Colon, ":", I));
69 | break;
70 | case ',':
71 | Tokens.Add(new(TokenType.Comma, ",", I));
72 | break;
73 | case '"':
74 | Token TK = new(TokenType.String, string.Empty, I);
75 | while (Input[++I] != '"')
76 | {
77 | TK.Value += Input[I];
78 | }
79 | Tokens.Add(TK);
80 | break;
81 | default:
82 | throw new($"Unexpected token at {StringEx.GetLineColumn(Input, I)}");
83 | }
84 |
85 | // Loop
86 | continue;
87 | }
88 |
89 | // Concat literal.
90 | T += Input[I];
91 | }
92 |
93 | return Tokens.ToArray();
94 | }
95 | }
--------------------------------------------------------------------------------
/PrismAPI/Runtime/SShell/Scripts/CLI.cs:
--------------------------------------------------------------------------------
1 | using PrismAPI.Runtime.SSharp;
2 |
3 | namespace PrismAPI.Runtime.SShell.Scripts;
4 |
5 | public class CLI : Script
6 | {
7 | public CLI() : base("CLI", "Starts a SSharp CLI shell instance.")
8 | {
9 | AdvancedDescription =
10 | "CLI [option] [file(s)]\n" +
11 | "======================\n" +
12 | "compile - Compile a file and output to the second file argument.\n" +
13 | "dump - Show instructions in a file as text.";
14 | }
15 |
16 | public override void Invoke(string[] Args)
17 | {
18 | if (Args.Length == 0)
19 | {
20 | Console.WriteLine("SystemSharp CLI interface, v2");
21 | Console.WriteLine("Copyleft PrismProject 2022.\n");
22 |
23 | while (true)
24 | {
25 | try
26 | {
27 | Console.ForegroundColor = ConsoleColor.Magenta;
28 | Console.Write(">>> ");
29 | Console.BackgroundColor = ConsoleColor.Gray;
30 | Console.ForegroundColor = ConsoleColor.Black;
31 |
32 | string? Input = Console.ReadLine();
33 | Console.ResetColor();
34 |
35 | if (string.IsNullOrEmpty(Input))
36 | {
37 | continue;
38 | }
39 |
40 | switch (Input)
41 | {
42 | case "Exit();":
43 | return;
44 | default:
45 | Binary EXE = Compiler.Compile(Input);
46 |
47 | while (EXE.IsEnabled)
48 | {
49 | EXE.Next();
50 | }
51 | break;
52 | }
53 | }
54 | catch (Exception E)
55 | {
56 | Console.WriteLine(E.Message);
57 | }
58 | }
59 | }
60 |
61 | if (Args[0] == "compile")
62 | {
63 | if (Args.Length < 3)
64 | {
65 | Console.WriteLine("Missing arguments!");
66 | return;
67 | }
68 |
69 | Console.WriteLine("Compiling " + Args[1] + "...");
70 | Binary EXE = Compiler.Compile(File.ReadAllText(Args[1]));
71 |
72 | File.WriteAllBytes(Args[2], ((MemoryStream)EXE.ROM.BaseStream).ToArray());
73 | }
74 | if (Args[0] == "dump")
75 | {
76 | new Binary(File.ReadAllBytes(Args[1])).Dump();
77 | return;
78 | }
79 | }
80 | }
--------------------------------------------------------------------------------
/PrismAPI/Runtime/SShell/Scripts/Locker.cs:
--------------------------------------------------------------------------------
1 | using PrismAPI.Tools;
2 |
3 | namespace PrismAPI.Runtime.SShell.Scripts;
4 |
5 | public class Locker : Script
6 | {
7 | public Locker() : base(nameof(Locker).ToLower(), "Encrypt, hash, and decrypt data.")
8 | {
9 | AdvancedDescription = $"{ScriptName} [option] [file] [key]\n-e : Encrypt\n-d : Decrypt\n-h : Hash";
10 | }
11 |
12 | public override void Invoke(string[] Args)
13 | {
14 | switch (Args[0])
15 | {
16 | case "-e":
17 | if (Args.Length != 3)
18 | {
19 | Console.WriteLine("Not enough args.");
20 | return;
21 | }
22 |
23 | File.WriteAllBytes(Args[1], Crypt.Encrypt(Args[2], File.ReadAllBytes(Args[1])));
24 | break;
25 | case "-d":
26 | if (Args.Length != 3)
27 | {
28 | Console.WriteLine("Not enough args.");
29 | return;
30 | }
31 |
32 | File.WriteAllBytes(Args[1], Crypt.Decrypt(Args[2], File.ReadAllBytes(Args[1])));
33 | break;
34 | case "-h":
35 | if (Args.Length != 2)
36 | {
37 | Console.WriteLine("Not enough args.");
38 | return;
39 | }
40 |
41 | Console.WriteLine(Crypt.Hash(Args[1]));
42 | break;
43 | default:
44 | return;
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/PrismAPI/Runtime/SShell/Scripts/Script.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Runtime.SShell.Scripts;
2 |
3 | ///
4 | /// This is the base class all commands must inherit.
5 | ///
6 | public abstract class Script
7 | {
8 | internal Script(string ScriptName, string BasicDescription)
9 | {
10 | AdvancedDescription = string.Empty;
11 | this.BasicDescription = BasicDescription;
12 | this.ScriptName = ScriptName;
13 | }
14 |
15 | #region Methods
16 |
17 | public abstract void Invoke(string[] Args);
18 |
19 | #endregion
20 |
21 | #region Fields
22 |
23 | public string AdvancedDescription { get; set; }
24 | public string BasicDescription { get; set; }
25 | public string ScriptName { get; set; }
26 |
27 | #endregion
28 | }
--------------------------------------------------------------------------------
/PrismAPI/Runtime/SShell/Scripts/Status.cs:
--------------------------------------------------------------------------------
1 | using Cosmos.Core.Memory;
2 |
3 | namespace PrismAPI.Runtime.SShell.Scripts;
4 |
5 | public class Status : Script
6 | {
7 | public Status() : base("status", "Print statistics about certain system properties.")
8 | {
9 | AdvancedDescription =
10 | "status [property]\n" +
11 | "=================\n" +
12 | "ram - RAM usage\n" +
13 | "net - Network status";
14 | }
15 |
16 | public override void Invoke(string[] Args)
17 | {
18 | if (Args.Length < 1)
19 | {
20 | Console.WriteLine("Insufficient arguments!");
21 | return;
22 | }
23 |
24 | switch (Args[0])
25 | {
26 | case "ram":
27 | if (Args.Length > 1 && Args[1] == "collect")
28 | {
29 | Heap.Collect();
30 | }
31 |
32 | Console.WriteLine($"{Cosmos.Core.GCImplementation.GetUsedRAM() / 1024 / 1024}/{Cosmos.Core.CPU.GetAmountOfRAM()} MB used.");
33 | break;
34 | case "net":
35 | foreach (var N in Cosmos.System.Network.Config.NetworkConfiguration.NetworkConfigs)
36 | {
37 | Console.WriteLine($"{N.Device.Name} : {(N.Device.Ready ? "Ready" : "Not ready")}");
38 | }
39 | break;
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/PrismAPI/Runtime/SShell/Scripts/VEdit.cs:
--------------------------------------------------------------------------------
1 | namespace PrismAPI.Runtime.SShell.Scripts;
2 |
3 | public class VEdit : Script
4 | {
5 | public VEdit() : base("vedit", "A basic text editor.")
6 | {
7 | AdvancedDescription = "vedit [file name]";
8 | }
9 |
10 | public override void Invoke(string[] Args)
11 | {
12 | string Buffer = string.Empty;
13 | Console.Clear();
14 |
15 | if (File.Exists(Args[0]))
16 | {
17 | Buffer = File.ReadAllText(Args[0]);
18 | Console.Write(Buffer);
19 | }
20 |
21 | while (true)
22 | {
23 | ConsoleKeyInfo Key = Console.ReadKey();
24 |
25 | if (Key.Key == ConsoleKey.Backspace)
26 | {
27 | if (Key.Modifiers == ConsoleModifiers.Control)
28 | {
29 | while (Buffer[^1] != ' ')
30 | {
31 | if (Buffer.Length > 0)
32 | {
33 | Buffer = Buffer[..^1];
34 | }
35 | }
36 |
37 | Console.Clear();
38 | Console.Write(Buffer);
39 | continue;
40 | }
41 |
42 | if (Buffer.Length > 0)
43 | {
44 | Buffer = Buffer[..^1];
45 | Console.Clear();
46 | Console.Write(Buffer);
47 | }
48 | continue;
49 | }
50 | if (Key.Key == ConsoleKey.Escape)
51 | {
52 | if (File.Exists(Args[0]))
53 | {
54 | File.Delete(Args[0]);
55 | }
56 | File.WriteAllBytes(Args[0], System.Text.Encoding.UTF8.GetBytes(Buffer));
57 | Console.Clear();
58 | return;
59 | }
60 | if (Key.Key == ConsoleKey.Enter)
61 | {
62 | Console.Write('\n');
63 | Buffer += '\n';
64 | continue;
65 | }
66 |
67 | Buffer += Key.KeyChar;
68 | Console.Write(Key.KeyChar);
69 | }
70 | }
71 | }
--------------------------------------------------------------------------------
/PrismAPI/Runtime/SShell/Shell.cs:
--------------------------------------------------------------------------------
1 | using PrismAPI.Filesystem.Formats.ELF.ELFHeader;
2 | using PrismAPI.Runtime.SShell.Scripts;
3 | using PrismAPI.Tools.Diagnostics;
4 | using PrismAPI.Runtime.SSharp;
5 |
6 | namespace PrismAPI.Runtime.SShell;
7 |
8 | public static unsafe class Shell
9 | {
10 | static Shell()
11 | {
12 | Debugger = new("SShell");
13 |
14 | // Initialize all commands.
15 | Scripts = new()
16 | {
17 | new Unix.PowerOff(),
18 | new Unix.HexDump(),
19 | new Unix.ReadELF(),
20 | new Unix.Reboot(),
21 | //new Unix.LSBLK(),
22 | new Unix.Clear(),
23 | new Unix.MKDir(),
24 | new Unix.Touch(),
25 | //new Unix.MKFS(),
26 | new Unix.Halt(),
27 | new Unix.Cat(),
28 | new Unix.Man(),
29 | new Unix.PWD(),
30 | new Unix.CP(),
31 | new Unix.CD(),
32 | new Unix.LS(),
33 | new Unix.RM(),
34 | new Status(),
35 | new Locker(),
36 | new VEdit(),
37 | new CLI()
38 | };
39 | }
40 |
41 | #region Methods
42 |
43 | ///
44 | /// Invokes a command if it exists.
45 | ///
46 | /// Arguments to the command.
47 | public static void Invoke(string[] VS)
48 | {
49 | // Skip if there are no commands to run.
50 | if (Scripts.Count == 0)
51 | {
52 | Debugger.WriteFull("Command interperiter not initialized!", Severity.Warn);
53 | return;
54 | }
55 |
56 | for (int I = 0; I < Scripts.Count; I++)
57 | {
58 | // Check if command exists.
59 | if (Scripts[I].ScriptName == VS[0])
60 | {
61 | string[] T = new string[VS.Length - 1];
62 |
63 | for (int I2 = 0; I2 < T.Length; I2++)
64 | {
65 | T[I2] = VS[I2 + 1];
66 | }
67 |
68 | Scripts[I].Invoke(T);
69 | return;
70 | }
71 | }
72 |
73 | if (File.Exists($"0:\\{VS[0]}") || File.Exists(VS[0]))
74 | {
75 | // Read the program's running data.
76 | byte[] ROM = File.ReadAllBytes(VS[0]);
77 |
78 | // Check if the file isn't an ELF. Run as a SSharp program if it isn't.
79 | if (ROM.Length < sizeof(ELFHeader32))
80 | {
81 | Binary EXE = new(File.ReadAllBytes(VS[0]));
82 |
83 | while (EXE.IsEnabled)
84 | {
85 | EXE.Next();
86 | }
87 |
88 | return;
89 | }
90 | // Run an elf file when it's detected.
91 | else
92 | {
93 | // Create a new header, then run it.
94 | Executable E = Executable.FromELF32(ROM);
95 | E.Main();
96 | return;
97 | }
98 | }
99 |
100 | Debugger.WriteFull("Command not found!", Severity.Warn);
101 | }
102 |
103 | ///
104 | /// Main method for the shell.
105 | ///
106 | public static void Main()
107 | {
108 | Debugger.WriteFull("Droping to recovery shell...", Severity.Warn);
109 | Console.WriteLine("Type \"man\" to get a list of commands.");
110 |
111 | while (true)
112 | {
113 | Console.Write($"{Environment.CurrentDirectory}> ");
114 |
115 | string? Input = Console.ReadLine();
116 |
117 | if (Input == null)
118 | {
119 | continue;
120 | }
121 |
122 | Invoke(Input.Split(' '));
123 | }
124 | }
125 |
126 | #endregion
127 |
128 | #region Fields
129 |
130 | internal static Debugger Debugger;
131 | internal static List