summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Stålnacke <joel@saker.fi>2026-03-19 22:30:56 +0200
committerJoel Stålnacke <joel@saker.fi>2026-03-19 22:30:56 +0200
commit745406dc65aecc438a53f96badc387a32b7a338f (patch)
treecc597855dac943efe627fce160782585e27feadf
parent3b60cd682120947119f442bb71ab2a5e98decccc (diff)
Add Mibo project
The Djup project is DesktopGL project
-rw-r--r--.config/dotnet-tools.json36
-rw-r--r--Djup.Native/scripts/AddRuntimeTargetsToDepsJson.targets (renamed from Djup.Native/AddRuntimeTargetsToDepsJson.targets)0
-rwxr-xr-xDjup.Native/scripts/patch-deps.sh (renamed from Djup.Native/patch-deps.sh)0
-rw-r--r--Djup.Native/src/Constants.cs (renamed from Djup.Native/Constants.cs)0
-rw-r--r--Djup.Native/src/Djup.Native.csproj (renamed from Djup.Native/Djup.Native.csproj)3
-rw-r--r--Djup.Native/src/LibDjup.cs (renamed from Djup.Native/LibDjup.cs)0
-rw-r--r--Djup.Native/src/Program.cs (renamed from Djup.Native/Program.cs)0
-rw-r--r--Djup.Native/src/Types.cs (renamed from Djup.Native/Types.cs)0
-rw-r--r--Djup.Native/src/packages.lock.json6
-rw-r--r--Djup.Testing/src/Djup.Testing.fsproj1
-rw-r--r--Djup.Testing/src/packages.lock.json31
-rw-r--r--Djup.slnx9
-rw-r--r--Djup/src/Content/Content.mgcb14
-rw-r--r--Djup/src/Djup.fsproj32
-rw-r--r--Djup/src/Icon.bmpbin0 -> 262282 bytes
-rw-r--r--Djup/src/Icon.icobin0 -> 147541 bytes
-rw-r--r--Djup/src/Program.fs153
-rw-r--r--Djup/src/app.manifest29
-rw-r--r--Djup/src/packages.lock.json72
19 files changed, 384 insertions, 2 deletions
diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
new file mode 100644
index 0000000..a4ce7f6
--- /dev/null
+++ b/.config/dotnet-tools.json
@@ -0,0 +1,36 @@
+{
+ "version": 1,
+ "isRoot": true,
+ "tools": {
+ "dotnet-mgcb": {
+ "version": "3.8.4",
+ "commands": ["mgcb"],
+ "rollForward": false
+ },
+ "dotnet-mgcb-editor": {
+ "version": "3.8.4",
+ "commands": ["mgcb-editor"],
+ "rollForward": false
+ },
+ "dotnet-mgcb-editor-linux": {
+ "version": "3.8.4",
+ "commands": ["mgcb-editor-linux"],
+ "rollForward": false
+ },
+ "dotnet-mgcb-editor-windows": {
+ "version": "3.8.4",
+ "commands": ["mgcb-editor-windows"],
+ "rollForward": false
+ },
+ "dotnet-mgcb-editor-mac": {
+ "version": "3.8.4",
+ "commands": ["mgcb-editor-mac"],
+ "rollForward": false
+ },
+ "fantomas": {
+ "version": "7.0.2",
+ "commands": ["fantomas"],
+ "rollForward": false
+ }
+ }
+}
diff --git a/Djup.Native/AddRuntimeTargetsToDepsJson.targets b/Djup.Native/scripts/AddRuntimeTargetsToDepsJson.targets
index fbb4c43..fbb4c43 100644
--- a/Djup.Native/AddRuntimeTargetsToDepsJson.targets
+++ b/Djup.Native/scripts/AddRuntimeTargetsToDepsJson.targets
diff --git a/Djup.Native/patch-deps.sh b/Djup.Native/scripts/patch-deps.sh
index 8015323..8015323 100755
--- a/Djup.Native/patch-deps.sh
+++ b/Djup.Native/scripts/patch-deps.sh
diff --git a/Djup.Native/Constants.cs b/Djup.Native/src/Constants.cs
index 90692be..90692be 100644
--- a/Djup.Native/Constants.cs
+++ b/Djup.Native/src/Constants.cs
diff --git a/Djup.Native/Djup.Native.csproj b/Djup.Native/src/Djup.Native.csproj
index f3c2781..a581a58 100644
--- a/Djup.Native/Djup.Native.csproj
+++ b/Djup.Native/src/Djup.Native.csproj
@@ -5,10 +5,11 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
</PropertyGroup>
<PropertyGroup>
- <BuildDir>$(MSBuildThisFileDirectory)../lib/build</BuildDir>
+ <BuildDir>$(MSBuildThisFileDirectory)../../lib/build</BuildDir>
</PropertyGroup>
<ItemGroup Condition=" '$(Configuration)'=='Release' ">
diff --git a/Djup.Native/LibDjup.cs b/Djup.Native/src/LibDjup.cs
index 15dcdad..15dcdad 100644
--- a/Djup.Native/LibDjup.cs
+++ b/Djup.Native/src/LibDjup.cs
diff --git a/Djup.Native/Program.cs b/Djup.Native/src/Program.cs
index 1b374b8..1b374b8 100644
--- a/Djup.Native/Program.cs
+++ b/Djup.Native/src/Program.cs
diff --git a/Djup.Native/Types.cs b/Djup.Native/src/Types.cs
index 7d9c41e..7d9c41e 100644
--- a/Djup.Native/Types.cs
+++ b/Djup.Native/src/Types.cs
diff --git a/Djup.Native/src/packages.lock.json b/Djup.Native/src/packages.lock.json
new file mode 100644
index 0000000..4a91a8c
--- /dev/null
+++ b/Djup.Native/src/packages.lock.json
@@ -0,0 +1,6 @@
+{
+ "version": 1,
+ "dependencies": {
+ "net10.0": {}
+ }
+} \ No newline at end of file
diff --git a/Djup.Testing/src/Djup.Testing.fsproj b/Djup.Testing/src/Djup.Testing.fsproj
index 91a3a4c..706d8fe 100644
--- a/Djup.Testing/src/Djup.Testing.fsproj
+++ b/Djup.Testing/src/Djup.Testing.fsproj
@@ -3,6 +3,7 @@
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
+ <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
</PropertyGroup>
<ItemGroup>
diff --git a/Djup.Testing/src/packages.lock.json b/Djup.Testing/src/packages.lock.json
new file mode 100644
index 0000000..ad79414
--- /dev/null
+++ b/Djup.Testing/src/packages.lock.json
@@ -0,0 +1,31 @@
+{
+ "version": 1,
+ "dependencies": {
+ "net10.0": {
+ "FsCheck": {
+ "type": "Direct",
+ "requested": "[3.3.2, )",
+ "resolved": "3.3.2",
+ "contentHash": "JlK719ZlP/ofbsN0qXYrfqbe2SCgp4D1BEyJynkzyurMI2JqUkWgZHXgEu0pXVdj35zU/GWsXrGYA68sSdAmHQ==",
+ "dependencies": {
+ "FSharp.Core": "5.0.2"
+ }
+ },
+ "FSharp.Core": {
+ "type": "Direct",
+ "requested": "[10.1.201, )",
+ "resolved": "10.1.201",
+ "contentHash": "s5w9LWYurZ9yZdIppoIaYLkRadyT5s3u0wbQCb0J4bQd3ubIlIWQ3Nd5+ll1y3pv5OnTS373dP8T1S/BP46QXg=="
+ },
+ "Fuchu": {
+ "type": "Direct",
+ "requested": "[1.1.0, )",
+ "resolved": "1.1.0",
+ "contentHash": "PNiweqWAt+ONHX6QUtFlbm4+xDbvwYTi5Vv67C0IFd6M+K2Qm9bTXLqNBqZTpIX5dPLpwW1SmARPawaXxdc9jw==",
+ "dependencies": {
+ "FSharp.Core": "4.3.4"
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Djup.slnx b/Djup.slnx
index befed83..11b7b93 100644
--- a/Djup.slnx
+++ b/Djup.slnx
@@ -1,7 +1,14 @@
<Solution>
+ <Folder Name="/Djup.Native/" />
+ <Folder Name="/Djup.Native/src/">
+ <Project Path="Djup.Native/src/Djup.Native.csproj" />
+ </Folder>
<Folder Name="/Djup.Testing/" />
<Folder Name="/Djup.Testing/src/">
<Project Path="Djup.Testing/src/Djup.Testing.fsproj" />
</Folder>
- <Project Path="Djup.Native/Djup.Native.csproj" />
+ <Folder Name="/Djup/" />
+ <Folder Name="/Djup/src/">
+ <Project Path="Djup/src/Djup.fsproj" />
+ </Folder>
</Solution>
diff --git a/Djup/src/Content/Content.mgcb b/Djup/src/Content/Content.mgcb
new file mode 100644
index 0000000..8b0866b
--- /dev/null
+++ b/Djup/src/Content/Content.mgcb
@@ -0,0 +1,14 @@
+
+#----------------------------- Global Properties ----------------------------#
+
+/outputDir:bin/$(Platform)
+/intermediateDir:obj/$(Platform)
+/platform:DesktopGL
+/config:
+/profile:Reach
+/compress:False
+
+#-------------------------------- References --------------------------------#
+
+
+#---------------------------------- Content ---------------------------------#
diff --git a/Djup/src/Djup.fsproj b/Djup/src/Djup.fsproj
new file mode 100644
index 0000000..dad45e9
--- /dev/null
+++ b/Djup/src/Djup.fsproj
@@ -0,0 +1,32 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <OutputType>WinExe</OutputType>
+ <TargetFramework>net10.0</TargetFramework>
+ <RollForward>Major</RollForward>
+ <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
+ <PublishReadyToRun>false</PublishReadyToRun>
+ <TieredCompilation>false</TieredCompilation>
+ <ApplicationManifest>app.manifest</ApplicationManifest>
+ <ApplicationIcon>Icon.ico</ApplicationIcon>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <Compile Include="Program.fs" />
+ <EmbeddedResource Include="Icon.ico" />
+ <EmbeddedResource Include="Icon.bmp" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Mibo" Version="1.*" />
+ <PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.*" />
+ <PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.*" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <MonoGameContentReference Include="Content/Content.mgcb" />
+ </ItemGroup>
+
+ <Import Project="../../Djup.Native/scripts/AddRuntimeTargetsToDepsJson.targets" />
+
+</Project>
diff --git a/Djup/src/Icon.bmp b/Djup/src/Icon.bmp
new file mode 100644
index 0000000..2b48165
--- /dev/null
+++ b/Djup/src/Icon.bmp
Binary files differ
diff --git a/Djup/src/Icon.ico b/Djup/src/Icon.ico
new file mode 100644
index 0000000..7d9dec1
--- /dev/null
+++ b/Djup/src/Icon.ico
Binary files differ
diff --git a/Djup/src/Program.fs b/Djup/src/Program.fs
new file mode 100644
index 0000000..2427252
--- /dev/null
+++ b/Djup/src/Program.fs
@@ -0,0 +1,153 @@
+module Djup.Program
+
+open System
+open Microsoft.Xna.Framework
+open Microsoft.Xna.Framework.Graphics
+open Microsoft.Xna.Framework.Input
+open Mibo.Elmish
+open Mibo.Elmish.Graphics2D
+open Mibo.Input
+
+// ─────────────────────────────────────────────────────────────
+// Input
+// ─────────────────────────────────────────────────────────────
+
+type GameAction =
+ | MoveLeft
+ | MoveRight
+ | MoveUp
+ | MoveDown
+
+let inputMap =
+ InputMap.empty
+ |> InputMap.key MoveLeft Keys.Left
+ |> InputMap.key MoveLeft Keys.A
+ |> InputMap.key MoveRight Keys.Right
+ |> InputMap.key MoveRight Keys.D
+ |> InputMap.key MoveUp Keys.Up
+ |> InputMap.key MoveUp Keys.W
+ |> InputMap.key MoveDown Keys.Down
+ |> InputMap.key MoveDown Keys.S
+
+// ─────────────────────────────────────────────────────────────
+// Model
+// ─────────────────────────────────────────────────────────────
+
+type Model = {
+ Position: Vector2
+ Velocity: Vector2
+ Input: ActionState<GameAction>
+}
+
+// ─────────────────────────────────────────────────────────────
+// Messages
+// ─────────────────────────────────────────────────────────────
+
+type Msg =
+ | Tick of GameTime
+ | InputChanged of ActionState<GameAction>
+
+// ─────────────────────────────────────────────────────────────
+// Init
+// ─────────────────────────────────────────────────────────────
+
+let init(ctx: GameContext) : struct (Model * Cmd<Msg>) =
+ let model = {
+ Position = Vector2(400.f, 300.f)
+ Velocity = Vector2(200.f, 150.f)
+ Input = ActionState.empty
+ }
+
+ model, Cmd.none
+
+// ─────────────────────────────────────────────────────────────
+// Update
+// ─────────────────────────────────────────────────────────────
+
+let update (msg: Msg) (model: Model) : struct (Model * Cmd<Msg>) =
+ match msg with
+ | InputChanged input -> { model with Input = input }, Cmd.none
+
+ | Tick gt ->
+ let dt = float32 gt.ElapsedGameTime.TotalSeconds
+
+ // Manual movement
+ let speed = 200.f
+ let mutable manualVelocity = Vector2.Zero
+
+ if model.Input.Held.Contains MoveLeft then
+ manualVelocity.X <- manualVelocity.X - speed
+
+ if model.Input.Held.Contains MoveRight then
+ manualVelocity.X <- manualVelocity.X + speed
+
+ if model.Input.Held.Contains MoveUp then
+ manualVelocity.Y <- manualVelocity.Y - speed
+
+ if model.Input.Held.Contains MoveDown then
+ manualVelocity.Y <- manualVelocity.Y + speed
+
+ // Bouncing logic
+ let mutable velocity = model.Velocity
+
+ let mutable position =
+ model.Position + (velocity * dt) + (manualVelocity * dt)
+
+ if position.X < 0.f || position.X > 800.f - 32.f then
+ velocity.X <- -velocity.X
+
+ if position.Y < 0.f || position.Y > 600.f - 32.f then
+ velocity.Y <- -velocity.Y
+
+ {
+ model with
+ Position = position
+ Velocity = velocity
+ },
+ Cmd.none
+
+// ─────────────────────────────────────────────────────────────
+// View
+// ─────────────────────────────────────────────────────────────
+
+let view (ctx: GameContext) (model: Model) (buffer: RenderBuffer<RenderCmd2D>) =
+ // Draw player (using a 1x1 pixel texture if no asset loaded, or load one)
+ let pixel =
+ Assets.getOrCreate
+ "pixel"
+ (fun gd ->
+ let t = new Texture2D(gd, 1, 1)
+ t.SetData([| Color.White |])
+ t)
+ ctx
+
+ Draw2D.sprite
+ pixel
+ (Rectangle(int model.Position.X, int model.Position.Y, 32, 32))
+ |> Draw2D.withColor Color.Red
+ |> Draw2D.submit buffer
+
+// ─────────────────────────────────────────────────────────────
+// Program
+// ─────────────────────────────────────────────────────────────
+
+[<EntryPoint>]
+let main _ =
+ let program =
+ Program.mkProgram init update
+ |> Program.withAssets
+ |> Program.withRenderer(fun g -> Batch2DRenderer.create g view)
+ |> Program.withInput
+ |> Program.withSubscription(fun ctx _ ->
+ InputMapper.subscribeStatic inputMap InputChanged ctx)
+ |> Program.withTick Tick
+ |> Program.withConfig(fun (game, graphics) ->
+ game.Content.RootDirectory <- "Content"
+ game.Window.Title <- "Mibo 2D Game"
+ game.IsMouseVisible <- true
+ graphics.PreferredBackBufferWidth <- 800
+ graphics.PreferredBackBufferHeight <- 600)
+
+ use game = new ElmishGame<Model, Msg>(program)
+ game.Run()
+ 0
diff --git a/Djup/src/app.manifest b/Djup/src/app.manifest
new file mode 100644
index 0000000..b27ce83
--- /dev/null
+++ b/Djup/src/app.manifest
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
+ <assemblyIdentity version="1.0.0.0" name="Djup"/>
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
+ <security>
+ <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
+ <requestedExecutionLevel level="asInvoker" uiAccess="false" />
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+
+ <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+ <application>
+ <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />
+ <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
+ <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />
+ <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />
+ <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
+ </application>
+ </compatibility>
+
+ <application xmlns="urn:schemas-microsoft-com:asm.v3">
+ <windowsSettings>
+ <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
+ <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">permonitorv2,permonitor</dpiAwareness>
+ </windowsSettings>
+ </application>
+
+</assembly>
diff --git a/Djup/src/packages.lock.json b/Djup/src/packages.lock.json
new file mode 100644
index 0000000..64ca908
--- /dev/null
+++ b/Djup/src/packages.lock.json
@@ -0,0 +1,72 @@
+{
+ "version": 1,
+ "dependencies": {
+ "net10.0": {
+ "FSharp.Core": {
+ "type": "Direct",
+ "requested": "[10.1.201, )",
+ "resolved": "10.1.201",
+ "contentHash": "s5w9LWYurZ9yZdIppoIaYLkRadyT5s3u0wbQCb0J4bQd3ubIlIWQ3Nd5+ll1y3pv5OnTS373dP8T1S/BP46QXg=="
+ },
+ "Mibo": {
+ "type": "Direct",
+ "requested": "[1.*, )",
+ "resolved": "1.6.0",
+ "contentHash": "HcElja4XxQ8E1vJc93+78Sb/lQB6jTy0VyOuMQRqwQfHeo4tQMx+6JkLj2OJVaeWE4BhC/P+C5tcONLnW3RGfg==",
+ "dependencies": {
+ "FSharp.Core": "10.0.102",
+ "FSharp.UMX": "1.1.0",
+ "JDeck": "1.0.0"
+ }
+ },
+ "MonoGame.Content.Builder.Task": {
+ "type": "Direct",
+ "requested": "[3.8.*, )",
+ "resolved": "3.8.4.1",
+ "contentHash": "jf6IZXMiOhuybRaWQt//u+804yzMRGk3ZRvlBJG/0iusRwTunJsQvA6tMMJJc7gjUrY6rUkzRqwinKWXugyHfA=="
+ },
+ "MonoGame.Framework.DesktopGL": {
+ "type": "Direct",
+ "requested": "[3.8.*, )",
+ "resolved": "3.8.4.1",
+ "contentHash": "YybxIIT5+Ky78E/XdkS0glyluMr2EeDZwx2LqXULAOCqiKt1+aDrjPZaqLL5qpNgBcMEHUeZJ4YjWe4TAZlWLw==",
+ "dependencies": {
+ "MonoGame.Library.OpenAL": "1.24.3.2",
+ "MonoGame.Library.SDL": "2.32.2.1",
+ "NVorbis": "0.10.4"
+ }
+ },
+ "FSharp.UMX": {
+ "type": "Transitive",
+ "resolved": "1.1.0",
+ "contentHash": "0+4w4/yBL5z7w1/k198ooPbfMqkzMSXPRVZEVingnwAdjM//QIFG25eJbB3RtoSQAusBwV5B3VcSudxJejd5Bg==",
+ "dependencies": {
+ "FSharp.Core": "4.3.4"
+ }
+ },
+ "JDeck": {
+ "type": "Transitive",
+ "resolved": "1.0.0",
+ "contentHash": "a4d+USHnlc3+zPZb7MOKXD58BbVMaO1sajROxPQH5m+g08QtqVcr4PlNs6cT5QuP13lKpHlw9X+9UlAcXmguYA==",
+ "dependencies": {
+ "FSharp.Core": "9.0.100"
+ }
+ },
+ "MonoGame.Library.OpenAL": {
+ "type": "Transitive",
+ "resolved": "1.24.3.2",
+ "contentHash": "nGRsXQXs+NSUC3C5w90hFQfyKdZPpBnHnyg2w+Dw/2pUH7s+CoRWTJNYbzzdJf3+aeUvfvG4rTbFvMKDDj5olA=="
+ },
+ "MonoGame.Library.SDL": {
+ "type": "Transitive",
+ "resolved": "2.32.2.1",
+ "contentHash": "T4E2ppGlSTC2L9US1rxtdg3qTbarRzNId31xZoumUW9cf9Nq8nRQPMu9GzvZGrhfSySf0+UWPEj1rlicps+P/w=="
+ },
+ "NVorbis": {
+ "type": "Transitive",
+ "resolved": "0.10.4",
+ "contentHash": "WYnil3DhQHzjCY0dM9I2B3r1vWip90AOuQd25KE4NrjPQBg0tBJFluRLm5YPnO5ZLDmwrfosY8jCQGQRmWI/Pg=="
+ }
+ }
+ }
+} \ No newline at end of file