Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bb43c9aad8 | ||
|
|
9256c513da | ||
|
|
218a1764bc | ||
|
|
ea9ca614e9 | ||
|
|
dd9e04f636 | ||
|
|
f37ee878e1 | ||
|
|
bd0a4294e8 | ||
|
|
9934566414 | ||
|
|
5aeb81e800 | ||
|
|
ec1fe6e0d3 |
Generated
+181
-184
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -4,7 +4,7 @@ description = "An emulator for the Virtual Boy."
|
|||||||
repository = "https://git.virtual-boy.com/PVB/lemur"
|
repository = "https://git.virtual-boy.com/PVB/lemur"
|
||||||
publish = false
|
publish = false
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
version = "0.12.0"
|
version = "0.12.3"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
+11
-11
@@ -13,12 +13,12 @@ COPY install-llvm.sh .
|
|||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
./install-llvm.sh && \
|
./install-llvm.sh && \
|
||||||
apt-get install -y bash bzip2 git make patch xz-utils && \
|
apt-get install -y bash bzip2 git make patch xz-utils && \
|
||||||
ln -s $(which clang-21) /usr/bin/clang && \
|
ln -s $(which clang-22) /usr/bin/clang && \
|
||||||
ln -s $(which clang++-21) /usr/bin/clang++ && \
|
ln -s $(which clang++-22) /usr/bin/clang++ && \
|
||||||
ln -s $(which ld64.lld-21) /usr/bin/ld64.lld && \
|
ln -s $(which ld64.lld-22) /usr/bin/ld64.lld && \
|
||||||
SDK_VERSION=14.5 UNATTENDED=1 ENABLE_COMPILER_RT_INSTALL=1 TARGET_DIR=/osxcross ./build.sh
|
SDK_VERSION=14.5 UNATTENDED=1 ENABLE_COMPILER_RT_INSTALL=1 TARGET_DIR=/osxcross ./build.sh
|
||||||
|
|
||||||
FROM rust:1.94-bookworm
|
FROM rust:1.95-bookworm
|
||||||
ADD --chmod=644 "https://apt.llvm.org/llvm-snapshot.gpg.key" /etc/apt/trusted.gpg.d/apt.llvm.org.asc
|
ADD --chmod=644 "https://apt.llvm.org/llvm-snapshot.gpg.key" /etc/apt/trusted.gpg.d/apt.llvm.org.asc
|
||||||
COPY llvm.sources /etc/apt/sources.list.d/llvm.sources
|
COPY llvm.sources /etc/apt/sources.list.d/llvm.sources
|
||||||
COPY install-llvm.sh .
|
COPY install-llvm.sh .
|
||||||
@@ -31,13 +31,13 @@ RUN rustup target add x86_64-pc-windows-msvc && \
|
|||||||
cargo install cargo-bundle xwin && \
|
cargo install cargo-bundle xwin && \
|
||||||
xwin --accept-license splat --output xwin && \
|
xwin --accept-license splat --output xwin && \
|
||||||
rm -rf .xwin-cache && \
|
rm -rf .xwin-cache && \
|
||||||
ln -s $(which clang-21) /usr/bin/clang && \
|
ln -s $(which clang-22) /usr/bin/clang && \
|
||||||
ln -s $(which clang++-21) /usr/bin/clang++
|
ln -s $(which clang++-22) /usr/bin/clang++
|
||||||
COPY --from=osxcross /osxcross /osxcross
|
COPY --from=osxcross /osxcross /osxcross
|
||||||
|
|
||||||
ENV PATH="/osxcross/bin:$PATH" \
|
ENV PATH="/osxcross/bin:$PATH" \
|
||||||
LD_LIBRARY_PATH="/osxcross/lib" \
|
LD_LIBRARY_PATH="/osxcross/lib" \
|
||||||
CC="clang-21" CXX="clang++-21" AR="llvm-ar-21" \
|
CC="clang-22" CXX="clang++-22" AR="llvm-ar-22" \
|
||||||
CC_x86_64-apple-darwin="o64-clang" \
|
CC_x86_64-apple-darwin="o64-clang" \
|
||||||
CXX_x86_64-apple-darwin="o64-clang++" \
|
CXX_x86_64-apple-darwin="o64-clang++" \
|
||||||
CC_aarch64-apple-darwin="oa64-clang" \
|
CC_aarch64-apple-darwin="oa64-clang" \
|
||||||
@@ -47,11 +47,11 @@ ENV PATH="/osxcross/bin:$PATH" \
|
|||||||
SHROOMS_CFLAGS_x86_64-pc-windows-msvc="-flto" \
|
SHROOMS_CFLAGS_x86_64-pc-windows-msvc="-flto" \
|
||||||
CFLAGS_x86_64-pc-windows-msvc="-I/xwin/crt/include -I/xwin/sdk/include/ucrt -I/xwin/sdk/include/um -I/xwin/sdk/include/shared" \
|
CFLAGS_x86_64-pc-windows-msvc="-I/xwin/crt/include -I/xwin/sdk/include/ucrt -I/xwin/sdk/include/um -I/xwin/sdk/include/shared" \
|
||||||
CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_RUSTFLAGS="-Lnative=/xwin/crt/lib/x86_64 -Lnative=/xwin/sdk/lib/um/x86_64 -Lnative=/xwin/sdk/lib/ucrt/x86_64 -Clinker-plugin-lto -Clink-arg=-fuse-ld=lld" \
|
CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_RUSTFLAGS="-Lnative=/xwin/crt/lib/x86_64 -Lnative=/xwin/sdk/lib/um/x86_64 -Lnative=/xwin/sdk/lib/ucrt/x86_64 -Clinker-plugin-lto -Clink-arg=-fuse-ld=lld" \
|
||||||
CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_LINKER="lld-link-21" \
|
CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_LINKER="lld-link-22" \
|
||||||
CARGO_TARGET_X86_64_APPLE_DARWIN_LINKER="o64-clang" \
|
CARGO_TARGET_X86_64_APPLE_DARWIN_LINKER="o64-clang" \
|
||||||
CARGO_TARGET_X86_64_APPLE_DARWIN_AR="llvm-ar-21" \
|
CARGO_TARGET_X86_64_APPLE_DARWIN_AR="llvm-ar-22" \
|
||||||
CARGO_TARGET_AARCH64_APPLE_DARWIN_LINKER="oa64-clang" \
|
CARGO_TARGET_AARCH64_APPLE_DARWIN_LINKER="oa64-clang" \
|
||||||
CARGO_TARGET_AARCH64_APPLE_DARWIN_AR="llvm-ar-21" \
|
CARGO_TARGET_AARCH64_APPLE_DARWIN_AR="llvm-ar-22" \
|
||||||
RC_PATH="llvm-rc-21" \
|
RC_PATH="llvm-rc-22" \
|
||||||
MACOSX_DEPLOYMENT_TARGET="14.5"
|
MACOSX_DEPLOYMENT_TARGET="14.5"
|
||||||
ENTRYPOINT ["bash"]
|
ENTRYPOINT ["bash"]
|
||||||
|
|||||||
+4
-4
@@ -4,11 +4,11 @@
|
|||||||
# The apt index for these is broken in bookworm, and upgrading to trixie
|
# The apt index for these is broken in bookworm, and upgrading to trixie
|
||||||
# would make them depend on too new of a libc version.
|
# would make them depend on too new of a libc version.
|
||||||
|
|
||||||
# https://apt.llvm.org/bookworm/pool/main/l/llvm-toolchain-21/clang-21_21.1.5~%2B%2B20251023083151%2B45afac62e373-1~exp1~20251023083333.51_amd64.deb
|
# https://apt.llvm.org/bookworm/pool/main/l/llvm-toolchain-22/clang-22_22.1.0~%2B%2B20260223093050%2Bcd5897175d0d-1~exp1~20260223093246.28_amd64.deb
|
||||||
PACKAGES=('clang-21' 'clang-tools-21' 'libclang-common-21-dev' 'libclang-cpp21' 'libclang-rt-21-dev' 'libclang1-21' 'libllvm21' 'lld-21' 'llvm-21' 'llvm-21-dev' 'llvm-21-linker-tools' 'llvm-21-runtime' 'llvm-21-tools')
|
PACKAGES=('clang-22' 'clang-tools-22' 'libclang-common-22-dev' 'libclang-cpp22' 'libclang-rt-22-dev' 'libclang1-22' 'libllvm22' 'lld-22' 'llvm-22' 'llvm-22-dev' 'llvm-22-linker-tools' 'llvm-22-runtime' 'llvm-22-tools')
|
||||||
FILES=()
|
FILES=()
|
||||||
URL='https://apt.llvm.org/bookworm/pool/main/l/llvm-toolchain-21'
|
URL='https://apt.llvm.org/bookworm/pool/main/l/llvm-toolchain-22'
|
||||||
VERSION='21.1.5~%2B%2B20251023083151%2B45afac62e373-1~exp1~20251023083333.51_amd64.deb'
|
VERSION='22.1.0~%2B%2B20260223093050%2Bcd5897175d0d-1~exp1~20260223093246.28_amd64.deb'
|
||||||
|
|
||||||
apt-get install -y curl python3
|
apt-get install -y curl python3
|
||||||
for package in "${PACKAGES[@]}"; do
|
for package in "${PACKAGES[@]}"; do
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
Types: deb deb-src
|
Types: deb deb-src
|
||||||
URIs: http://apt.llvm.org/bookworm/
|
URIs: http://apt.llvm.org/bookworm/
|
||||||
Suites: llvm-toolchain-bookworm-21
|
Suites: llvm-toolchain-bookworm-22
|
||||||
Components: main
|
Components: main
|
||||||
|
|||||||
+11
-8
@@ -288,6 +288,7 @@ impl Application {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let clipped_primitives = self.ctx.tessellate(output.shapes, output.pixels_per_point);
|
let clipped_primitives = self.ctx.tessellate(output.shapes, output.pixels_per_point);
|
||||||
|
viewport.window.pre_present_notify();
|
||||||
self.shared.painter.paint_and_update_textures(
|
self.shared.painter.paint_and_update_textures(
|
||||||
viewport.id,
|
viewport.id,
|
||||||
output.pixels_per_point,
|
output.pixels_per_point,
|
||||||
@@ -296,7 +297,6 @@ impl Application {
|
|||||||
&output.textures_delta,
|
&output.textures_delta,
|
||||||
vec![],
|
vec![],
|
||||||
);
|
);
|
||||||
viewport.window.pre_present_notify();
|
|
||||||
}
|
}
|
||||||
let mut active_viewports = ViewportIdSet::default();
|
let mut active_viewports = ViewportIdSet::default();
|
||||||
for (id, update) in updates {
|
for (id, update) in updates {
|
||||||
@@ -398,22 +398,25 @@ impl ApplicationHandler<UserEvent> for Application {
|
|||||||
if close_requested && viewport_id == ViewportId::ROOT {
|
if close_requested && viewport_id == ViewportId::ROOT {
|
||||||
event_loop.exit();
|
event_loop.exit();
|
||||||
}
|
}
|
||||||
|
if response.repaint {
|
||||||
|
viewport.window.request_redraw();
|
||||||
|
}
|
||||||
if !response.consumed {
|
if !response.consumed {
|
||||||
match event {
|
match event {
|
||||||
WindowEvent::KeyboardInput { event, .. } => {
|
WindowEvent::KeyboardInput { event, .. }
|
||||||
if !self.app.handle_key_event(viewport_id, &event) {
|
if !self.app.handle_key_event(viewport_id, &event) =>
|
||||||
self.controllers.handle_key_event(&event);
|
{
|
||||||
}
|
self.controllers.handle_key_event(&event);
|
||||||
}
|
}
|
||||||
WindowEvent::Focused(new_focused) => {
|
WindowEvent::Focused(new_focused) => {
|
||||||
self.focused = new_focused.then_some(viewport_id);
|
self.focused = new_focused.then_some(viewport_id);
|
||||||
}
|
}
|
||||||
|
WindowEvent::RedrawRequested => {
|
||||||
|
self.repaint_all(event_loop);
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if response.repaint {
|
|
||||||
self.repaint_all(event_loop);
|
|
||||||
}
|
|
||||||
self.check_repaint(event_loop);
|
self.check_repaint(event_loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -1,6 +1,6 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use egui::{Color32, Vec2};
|
use egui::{Color32, Pos2, Vec2};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{emulator::SimId, persistence::Persistence, window::DisplayMode};
|
use crate::{emulator::SimId, persistence::Persistence, window::DisplayMode};
|
||||||
@@ -75,6 +75,8 @@ pub struct SimConfig {
|
|||||||
pub dimensions: Vec2,
|
pub dimensions: Vec2,
|
||||||
#[serde(default = "default_audio_enabled")]
|
#[serde(default = "default_audio_enabled")]
|
||||||
pub audio_enabled: bool,
|
pub audio_enabled: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
pub position: Option<Pos2>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SimConfig {
|
impl SimConfig {
|
||||||
@@ -87,6 +89,7 @@ impl SimConfig {
|
|||||||
colors: COLOR_PRESETS[0],
|
colors: COLOR_PRESETS[0],
|
||||||
dimensions: DisplayMode::Anaglyph.proportions() + Vec2::new(0.0, 22.0),
|
dimensions: DisplayMode::Anaglyph.proportions() + Vec2::new(0.0, 22.0),
|
||||||
audio_enabled: true,
|
audio_enabled: true,
|
||||||
|
position: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+36
-12
@@ -20,10 +20,11 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use anyhow::Context as _;
|
use anyhow::Context as _;
|
||||||
use egui::{
|
use egui::{
|
||||||
Align2, Button, CentralPanel, Color32, Context, Frame, MenuBar, Panel, Ui, Vec2,
|
Align2, Button, CentralPanel, Color32, Context, Frame, MenuBar, Panel, Pos2, Ui, Vec2,
|
||||||
ViewportBuilder, ViewportCommand, ViewportId, ViewportIdMap, Window,
|
ViewportBuilder, ViewportCommand, ViewportId, ViewportIdMap, Window,
|
||||||
};
|
};
|
||||||
use egui_notify::{Anchor, Toast, Toasts};
|
use egui_notify::{Anchor, Toast, Toasts};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use winit::{event::KeyEvent, event_loop::EventLoopProxy};
|
use winit::{event::KeyEvent, event_loop::EventLoopProxy};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
@@ -50,7 +51,7 @@ pub struct GameWindow {
|
|||||||
images: Arc<ImageTextureLoader>,
|
images: Arc<ImageTextureLoader>,
|
||||||
mappings: MappingProvider,
|
mappings: MappingProvider,
|
||||||
children: ViewportIdMap<ChildWindowWrapper>,
|
children: ViewportIdMap<ChildWindowWrapper>,
|
||||||
child_sizes: UiData<ViewportIdMap<Vec2>>,
|
child_states: UiData<ViewportIdMap<ChildState>>,
|
||||||
queued_children: Vec<ChildWindow>,
|
queued_children: Vec<ChildWindow>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +92,7 @@ impl GameWindow {
|
|||||||
images: images.clone(),
|
images: images.clone(),
|
||||||
mappings: mappings.clone(),
|
mappings: mappings.clone(),
|
||||||
children: ViewportIdMap::default(),
|
children: ViewportIdMap::default(),
|
||||||
child_sizes: UiData::new(),
|
child_states: UiData::new(),
|
||||||
queued_children: vec![],
|
queued_children: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -175,8 +176,9 @@ impl GameWindow {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut viewport = child.initial_viewport();
|
let mut viewport = child.initial_viewport();
|
||||||
if let Some(size) = self.child_sizes.get(&viewport_id) {
|
if let Some(state) = self.child_states.get(&viewport_id) {
|
||||||
viewport.inner_size = Some(*size);
|
viewport.position = Some(state.position);
|
||||||
|
viewport.inner_size = Some(state.size);
|
||||||
}
|
}
|
||||||
self.children.insert(
|
self.children.insert(
|
||||||
viewport_id,
|
viewport_id,
|
||||||
@@ -626,18 +628,27 @@ impl AppWindow for GameWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn initial_viewport(&self) -> ViewportBuilder {
|
fn initial_viewport(&self) -> ViewportBuilder {
|
||||||
ViewportBuilder::default()
|
let builder = ViewportBuilder::default()
|
||||||
.with_title("Lemur")
|
.with_title("Lemur")
|
||||||
.with_inner_size(self.config.dimensions)
|
.with_inner_size(self.config.dimensions);
|
||||||
|
if let Some(position) = self.config.position {
|
||||||
|
builder.with_position(position)
|
||||||
|
} else {
|
||||||
|
builder
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show(&mut self, ui: &mut Ui) {
|
fn show(&mut self, ui: &mut Ui) {
|
||||||
self.child_sizes.load(ui);
|
self.child_states.load(ui);
|
||||||
let dimensions = {
|
let dimensions = {
|
||||||
let bounds = ui.content_rect();
|
let bounds = ui.content_rect();
|
||||||
bounds.max - bounds.min
|
bounds.max - bounds.min
|
||||||
};
|
};
|
||||||
self.update_config(|c| c.dimensions = dimensions);
|
let position = ui.input(|i| i.viewport().outer_rect.map(|r| r.min));
|
||||||
|
self.update_config(|c| {
|
||||||
|
c.dimensions = dimensions;
|
||||||
|
c.position = position;
|
||||||
|
});
|
||||||
|
|
||||||
while let Ok(toast) = self.messages.try_recv() {
|
while let Ok(toast) = self.messages.try_recv() {
|
||||||
self.toasts.add(toast);
|
self.toasts.add(toast);
|
||||||
@@ -679,8 +690,15 @@ impl AppWindow for GameWindow {
|
|||||||
let app = child.app.clone();
|
let app = child.app.clone();
|
||||||
let viewport_builder = child.updates.take().unwrap_or_default();
|
let viewport_builder = child.updates.take().unwrap_or_default();
|
||||||
let close_requested = child.close_requested.clone();
|
let close_requested = child.close_requested.clone();
|
||||||
let size = ui.input_for(*id, |v| v.viewport_rect().size());
|
if let Some(rect) = ui.input_for(*id, |inp| inp.viewport().outer_rect) {
|
||||||
self.child_sizes.insert(*id, size);
|
self.child_states.insert(
|
||||||
|
*id,
|
||||||
|
ChildState {
|
||||||
|
position: rect.min,
|
||||||
|
size: rect.size(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
ui.show_viewport_deferred(*id, viewport_builder, move |ui, _| {
|
ui.show_viewport_deferred(*id, viewport_builder, move |ui, _| {
|
||||||
app.lock().unwrap().show(ui);
|
app.lock().unwrap().show(ui);
|
||||||
if ui.input(|s| s.viewport().close_requested()) {
|
if ui.input(|s| s.viewport().close_requested()) {
|
||||||
@@ -689,7 +707,7 @@ impl AppWindow for GameWindow {
|
|||||||
});
|
});
|
||||||
true
|
true
|
||||||
});
|
});
|
||||||
self.child_sizes.save(ui);
|
self.child_states.save(ui);
|
||||||
ui.request_repaint_after(Duration::from_millis(10));
|
ui.request_repaint_after(Duration::from_millis(10));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -795,3 +813,9 @@ impl ChildWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
struct ChildState {
|
||||||
|
position: Pos2,
|
||||||
|
size: Vec2,
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user