Refactoring time
59
Cargo.toml
|
@ -1,9 +1,9 @@
|
|||
[package]
|
||||
name = "doukutsu-rs"
|
||||
description = "A re-implementation of Cave Story (Doukutsu Monogatari) engine"
|
||||
version = "0.99.0"
|
||||
version = "0.100.0"
|
||||
authors = ["Alula", "dawnDus"]
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
|
@ -25,7 +25,7 @@ opt-level = 3
|
|||
[package.metadata.bundle]
|
||||
name = "doukutsu-rs"
|
||||
identifier = "io.github.doukutsu_rs"
|
||||
version = "0.99.0"
|
||||
version = "0.100.0"
|
||||
resources = ["data"]
|
||||
copyright = "Copyright (c) 2020-2022 doukutsu-rs dev team"
|
||||
category = "Game"
|
||||
|
@ -33,15 +33,14 @@ osx_minimum_system_version = "10.12"
|
|||
|
||||
[features]
|
||||
default = ["default-base", "backend-sdl", "render-opengl", "exe"]
|
||||
default-base = ["scripting-lua", "ogg-playback", "netplay"]
|
||||
default-base = ["ogg-playback"]
|
||||
ogg-playback = ["lewton"]
|
||||
backend-sdl = ["sdl2", "sdl2-sys"]
|
||||
backend-glutin = ["winit", "glutin", "render-opengl"]
|
||||
render-opengl = []
|
||||
scripting-lua = ["lua-ffi"]
|
||||
netplay = ["tokio", "serde_cbor"]
|
||||
netplay = ["serde_cbor"]
|
||||
editor = []
|
||||
hooks = ["libc"]
|
||||
exe = []
|
||||
android = []
|
||||
|
||||
|
@ -51,42 +50,40 @@ android = []
|
|||
#winit = { path = "./3rdparty/winit", optional = true, default_features = false, features = ["x11"] }
|
||||
#sdl2 = { path = "./3rdparty/rust-sdl2", optional = true, features = ["unsafe_textures", "bundled", "static-link"] }
|
||||
#sdl2-sys = { path = "./3rdparty/rust-sdl2/sdl2-sys", optional = true, features = ["bundled", "static-link"] }
|
||||
bitvec = "0.20"
|
||||
byteorder = "1.4"
|
||||
case_insensitive_hashmap = "1.0.0"
|
||||
chrono = "0.4"
|
||||
cpal = "0.13"
|
||||
cpal = "0.14"
|
||||
directories = "3"
|
||||
downcast = "0.11"
|
||||
funty = "=1.1.0" # https://github.com/bitvecto-rs/bitvec/issues/105
|
||||
glutin = { git = "https://github.com/doukutsu-rs/glutin.git", rev = "8dd457b9adb7dbac7ade337246b6356c784272d9", optional = true, default_features = false, features = ["x11"] }
|
||||
imgui = "0.8.0"
|
||||
image = { version = "0.23", default-features = false, features = ["png", "bmp"] }
|
||||
#glutin = { git = "https://github.com/doukutsu-rs/glutin.git", rev = "8dd457b9adb7dbac7ade337246b6356c784272d9", optional = true, default_features = false, features = ["x11"] }
|
||||
glutin = { version = "0.30", optional = true, default_features = false, features = ["x11"] }
|
||||
imgui = "0.8"
|
||||
image = { version = "0.24", default-features = false, features = ["png", "bmp"] }
|
||||
itertools = "0.10"
|
||||
lazy_static = "1.4.0"
|
||||
lewton = { version = "0.10.2", optional = true }
|
||||
libc = { version = "0.2", optional = true }
|
||||
lazy_static = "1.4"
|
||||
lewton = { version = "0.10", optional = true }
|
||||
log = "0.4"
|
||||
lua-ffi = { git = "https://github.com/doukutsu-rs/lua-ffi.git", rev = "e0b2ff5960f7ef9974aa9675cebe4907bee0134f", optional = true }
|
||||
num-derive = "0.3.2"
|
||||
num-traits = "0.2.12"
|
||||
paste = "1.0.0"
|
||||
pelite = "0.9.1"
|
||||
num-derive = "0.3"
|
||||
num-traits = "0.2"
|
||||
paste = "1.0"
|
||||
pelite = ">=0.9.2"
|
||||
sdl2 = { git = "https://github.com/doukutsu-rs/rust-sdl2.git", rev = "95bcf63768abf422527f86da41da910649b9fcc9", optional = true, features = ["unsafe_textures", "bundled", "static-link"] }
|
||||
sdl2-sys = { git = "https://github.com/doukutsu-rs/rust-sdl2.git", rev = "95bcf63768abf422527f86da41da910649b9fcc9", optional = true, features = ["bundled", "static-link"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_derive = "1"
|
||||
serde_cbor = { version = "0.11.2", optional = true }
|
||||
serde_cbor = { version = "0.11", optional = true }
|
||||
serde_json = "1.0"
|
||||
simple_logger = { version = "1.16", features = ["colors", "threads"] }
|
||||
strum = "0.20"
|
||||
strum_macros = "0.20"
|
||||
tokio = { version = "1.12.0", features = ["net"], optional = true }
|
||||
strum = "0.24"
|
||||
strum_macros = "0.24"
|
||||
# remove and replace when drain_filter is in stable
|
||||
vec_mut_scan = "0.4"
|
||||
webbrowser = "0.5.5"
|
||||
winit = { git = "https://github.com/alula/winit.git", rev = "6acf76ff192dd8270aaa119b9f35716c03685f9f", optional = true, default_features = false, features = ["x11"] }
|
||||
xmltree = "0.10.3"
|
||||
webbrowser = "0.8"
|
||||
#winit = { git = "https://github.com/alula/winit.git", rev = "6acf76ff192dd8270aaa119b9f35716c03685f9f", optional = true, default_features = false, features = ["x11"] }
|
||||
winit = { version = "0.27", optional = true, default_features = false, features = ["x11"] }
|
||||
xmltree = "0.10"
|
||||
|
||||
[target.'cfg(target_os = "windows")'.dependencies]
|
||||
winapi = { version = "0.3", features = ["winuser"] }
|
||||
|
@ -95,10 +92,10 @@ winapi = { version = "0.3", features = ["winuser"] }
|
|||
winres = "0.1"
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
objc = "0.2.7"
|
||||
objc = "0.2"
|
||||
|
||||
[target.'cfg(target_os = "android")'.dependencies]
|
||||
ndk = "0.3"
|
||||
ndk-glue = "0.3"
|
||||
ndk-sys = "0.2"
|
||||
jni = "0.19"
|
||||
ndk = "0.7"
|
||||
ndk-glue = "0.7"
|
||||
ndk-sys = "0.4"
|
||||
jni = "0.20"
|
||||
|
|
Before Width: | Height: | Size: 276 KiB |
Before Width: | Height: | Size: 447 B |
Before Width: | Height: | Size: 456 B |
Before Width: | Height: | Size: 562 B |
Before Width: | Height: | Size: 621 B |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 3.9 KiB |
|
@ -1,197 +0,0 @@
|
|||
{
|
||||
"name": "English",
|
||||
"font": "csfont.fnt",
|
||||
"font_scale": "0.5",
|
||||
|
||||
"common": {
|
||||
"name": "doukutsu-rs",
|
||||
"back": "< Back",
|
||||
"yes": "Yes",
|
||||
"no": "No",
|
||||
"on": "ON",
|
||||
"off": "OFF"
|
||||
},
|
||||
|
||||
"menus": {
|
||||
"main_menu": {
|
||||
"start": "Start Game",
|
||||
"challenges": "Challenges",
|
||||
"options": "Options",
|
||||
"editor": "Editor",
|
||||
"jukebox": "Jukebox",
|
||||
"quit": "Quit"
|
||||
},
|
||||
|
||||
"pause_menu": {
|
||||
"resume": "Resume",
|
||||
"retry": "Retry",
|
||||
"options": "Options",
|
||||
"title": "Title",
|
||||
"title_confirm": "Title?",
|
||||
"quit": "Quit",
|
||||
"quit_confirm": "Quit?",
|
||||
"add_player2": "Add Player 2",
|
||||
"drop_player2": "Drop Player 2"
|
||||
},
|
||||
|
||||
"save_menu": {
|
||||
"new": "New Save",
|
||||
"delete_info": "Press Right to Delete",
|
||||
"delete_confirm": "Delete?",
|
||||
"invalid_save": "Invalid Save"
|
||||
},
|
||||
|
||||
"difficulty_menu": {
|
||||
"title": "Select Difficulty",
|
||||
"easy": "Easy",
|
||||
"normal": "Normal",
|
||||
"hard": "Hard"
|
||||
},
|
||||
|
||||
"coop_menu": {
|
||||
"title": "Select Number of Players",
|
||||
"one": "Single Player",
|
||||
"two": "Two Players"
|
||||
},
|
||||
"skin_menu": {
|
||||
"title": "Select Player 2's appearance",
|
||||
"label": "Appearance:"
|
||||
},
|
||||
|
||||
"challenge_menu": {
|
||||
"start": "Start",
|
||||
"no_replay": "No Replay",
|
||||
"replay_best": "Replay Best",
|
||||
"replay_last": "Replay Last",
|
||||
"delete_replay": "Delete Best Replay"
|
||||
},
|
||||
|
||||
"options_menu": {
|
||||
"graphics": "Graphics...",
|
||||
"graphics_menu": {
|
||||
"window_mode": {
|
||||
"entry": "Display mode:",
|
||||
"windowed": "Windowed",
|
||||
"fullscreen": "Fullscreen"
|
||||
},
|
||||
"lighting_effects": "Lighting effects:",
|
||||
"weapon_light_cone": "Weapon light cone:",
|
||||
"screen_shake": {
|
||||
"entry": "Screen shake intensity:",
|
||||
"full": "1x",
|
||||
"half": "0.5x",
|
||||
"off": "Off"
|
||||
},
|
||||
"motion_interpolation": "Motion interpolation:",
|
||||
"subpixel_scrolling": "Subpixel scrolling:",
|
||||
"original_textures": "Original textures:",
|
||||
"seasonal_textures": "Seasonal textures:",
|
||||
"renderer": "Renderer:",
|
||||
"vsync_mode": {
|
||||
"entry": "V-Sync:",
|
||||
"uncapped": "Uncapped",
|
||||
"uncapped_desc": "V-Sync Off.",
|
||||
"vsync": "Enabled",
|
||||
"vsync_desc": "V-Sync On.",
|
||||
"vrr_1x": "Variable Refresh Rate (1x)",
|
||||
"vrr_1x_desc": "Uses (G-/Free)Sync if available.",
|
||||
"vrr_2x": "Variable Refresh Rate (2x)",
|
||||
"vrr_2x_desc": "Uses (G-/Free)Sync if available.",
|
||||
"vrr_3x": "Variable Refresh Rate (3x)",
|
||||
"vrr_3x_desc": "Uses (G-/Free)Sync if available."
|
||||
}
|
||||
},
|
||||
|
||||
"sound": "Sound...",
|
||||
"sound_menu": {
|
||||
"music_volume": "Music Volume",
|
||||
"effects_volume": "Effects Volume",
|
||||
"bgm_interpolation": {
|
||||
"entry": "BGM Interpolation:",
|
||||
"linear": "Linear",
|
||||
"linear_desc": "Fast, similar to freeware on Vista+",
|
||||
"cosine": "Cosine",
|
||||
"cosine_desc": "Cosine interpolation",
|
||||
"cubic": "Cubic",
|
||||
"cubic_desc": "Cubic interpolation",
|
||||
"linear_lp": "Linear+LP",
|
||||
"linear_lp_desc": "Slowest, similar to freeware on XP",
|
||||
"nearest": "Nearest",
|
||||
"nearest_desc": "Fastest, lowest quality"
|
||||
},
|
||||
"soundtrack": "Soundtrack: {soundtrack}"
|
||||
},
|
||||
|
||||
"controls": "Controls...",
|
||||
|
||||
"language": "Language...",
|
||||
|
||||
"behavior": "Behavior...",
|
||||
"behavior_menu": {
|
||||
"game_timing": {
|
||||
"entry": "Game timing:",
|
||||
"50tps": "50tps (freeware)",
|
||||
"60tps": "60tps (CS+)"
|
||||
},
|
||||
"pause_on_focus_loss": "Pause on focus loss:",
|
||||
"cutscene_skip_method": {
|
||||
"entry": "Cutscene Skip:",
|
||||
"hold": "Hold to Skip",
|
||||
"fastforward": "Fast-Forward"
|
||||
}
|
||||
},
|
||||
|
||||
"links": "Links..."
|
||||
},
|
||||
|
||||
"controls_menu": {
|
||||
"select_player": {
|
||||
"entry": "Select player:",
|
||||
"player_1": "Player 1",
|
||||
"player_2": "Player 2"
|
||||
},
|
||||
"controller": {
|
||||
"entry": "Controller...",
|
||||
"keyboard": "Keyboard"
|
||||
},
|
||||
"rebind": "Rebind...",
|
||||
"rebind_menu": {
|
||||
"up": "Up",
|
||||
"down": "Down",
|
||||
"left": "Left",
|
||||
"right": "Right",
|
||||
"jump": "Jump",
|
||||
"shoot": "Shoot",
|
||||
"prev_weapon": "Previous weapon",
|
||||
"next_weapon": "Next weapon",
|
||||
"inventory": "Inventory",
|
||||
"map": "Map system",
|
||||
"skip": "Skip",
|
||||
"strafe": "Strafe",
|
||||
"menu_ok": "Menu select/confirm",
|
||||
"menu_back": "Menu back/cancel"
|
||||
},
|
||||
|
||||
"rebind_confirm_menu": {
|
||||
"title": "Press button for \"{control}\"",
|
||||
"cancel": "(Esc to cancel)"
|
||||
},
|
||||
|
||||
"rumble": "Rumble:",
|
||||
|
||||
"reset_confirm": "Reset...",
|
||||
"reset_confirm_menu_title": "Reset controls?"
|
||||
}
|
||||
},
|
||||
|
||||
"soundtrack": {
|
||||
"organya": "Organya",
|
||||
"remastered": "Remastered",
|
||||
"new": "New",
|
||||
"famitracks": "Famitracks"
|
||||
},
|
||||
|
||||
"game": {
|
||||
"cutscene_skip": "Hold {key} to skip the cutscene"
|
||||
}
|
||||
}
|
|
@ -1,187 +0,0 @@
|
|||
{
|
||||
"name": "Japanese",
|
||||
"font": "csfontjp.fnt",
|
||||
"font_scale": "0.5",
|
||||
|
||||
"common": {
|
||||
"name": "doukutsu-rs",
|
||||
"back": "< 戻る",
|
||||
"yes": "はい",
|
||||
"no": "いいえ",
|
||||
"on": "オン",
|
||||
"off": "オフ"
|
||||
},
|
||||
"menus": {
|
||||
"main_menu": {
|
||||
"start": "ゲームスタート",
|
||||
"challenges": "チャレンジ",
|
||||
"options": "オプション",
|
||||
"editor": "レベルエディタ",
|
||||
"jukebox": "ジュークボックス",
|
||||
"quit": "辞める"
|
||||
},
|
||||
"pause_menu": {
|
||||
"resume": "再開",
|
||||
"retry": "リトライ",
|
||||
"options": "設定",
|
||||
"title": "メインメニュー",
|
||||
"title_confirm": "メインメニュー?",
|
||||
"quit": "辞める",
|
||||
"quit_confirm": "辞める?",
|
||||
"add_player2": "プレーヤー2を追加",
|
||||
"drop_player2": "プレーヤー2を削除"
|
||||
},
|
||||
"save_menu": {
|
||||
"new": "新しいデータ",
|
||||
"delete_info": "右矢印キーで削除",
|
||||
"delete_confirm": "消去?",
|
||||
"invalid_save": "無効な保存"
|
||||
},
|
||||
"difficulty_menu": {
|
||||
"title": "難易度選択",
|
||||
"easy": "簡単",
|
||||
"normal": "普通",
|
||||
"hard": "難しい"
|
||||
},
|
||||
"coop_menu": {
|
||||
"title": "プレイヤー数を選択",
|
||||
"one": "1人プレイ",
|
||||
"two": "2人プレイ"
|
||||
},
|
||||
"skin_menu": {
|
||||
"title": "プレーヤー2の外観を選択します",
|
||||
"label": "外観:"
|
||||
},
|
||||
"challenge_menu": {
|
||||
"start": "スタート",
|
||||
"no_replay": "ノーリプレイ",
|
||||
"replay_best": "ベストプレイを再生",
|
||||
"replay_last": "最後のプレイを再生",
|
||||
"delete_replay": "ベストリプレイを削除"
|
||||
},
|
||||
"options_menu": {
|
||||
"graphics": "グラフィック",
|
||||
"graphics_menu": {
|
||||
"window_mode": {
|
||||
"entry": "画面表示:",
|
||||
"windowed": "ウィンドウ",
|
||||
"fullscreen": "フルスクリーン"
|
||||
},
|
||||
"lighting_effects": "ライティング効果:",
|
||||
"weapon_light_cone": "兵器のライトコーン:",
|
||||
"screen_shake": {
|
||||
"entry": "画面の揺れ:",
|
||||
"full": "1x",
|
||||
"half": "0.5x",
|
||||
"off": "オフ"
|
||||
},
|
||||
"motion_interpolation": "モーション補間:",
|
||||
"subpixel_scrolling": "サブピクセルスクロール:",
|
||||
"original_textures": "オリジナルテクスチャ:",
|
||||
"seasonal_textures": "季節ものテクスチャ:",
|
||||
"renderer": "レンダラ:",
|
||||
"vsync_mode": {
|
||||
"entry": "V-Sync:",
|
||||
"uncapped": "Uncapped",
|
||||
"uncapped_desc": "V-Sync Off.",
|
||||
"vsync": "Enabled",
|
||||
"vsync_desc": "V-Sync On.",
|
||||
"vrr_1x": "Variable Refresh Rate (1x)",
|
||||
"vrr_1x_desc": "Uses (G-/Free)Sync if available.",
|
||||
"vrr_2x": "Variable Refresh Rate (2x)",
|
||||
"vrr_2x_desc": "Uses (G-/Free)Sync if available.",
|
||||
"vrr_3x": "Variable Refresh Rate (3x)",
|
||||
"vrr_3x_desc": "Uses (G-/Free)Sync if available."
|
||||
}
|
||||
},
|
||||
"sound": "サウンド",
|
||||
"sound_menu": {
|
||||
"music_volume": "BGM音量",
|
||||
"effects_volume": "サウンド音量",
|
||||
"bgm_interpolation": {
|
||||
"entry": "BGM内挿:",
|
||||
"linear": "線形補間",
|
||||
"linear_desc": "速い、フリーウェア版に近い(Vista+)",
|
||||
"cosine": "余弦",
|
||||
"cosine_desc": "余弦補間",
|
||||
"cubic": "立方体",
|
||||
"cubic_desc": "立方体補間",
|
||||
"linear_lp": "線形補間+LP",
|
||||
"linear_lp_desc": "最も遅い、フリーウェア版に近い(XP)",
|
||||
"nearest": "最近傍",
|
||||
"nearest_desc": "最速、最低品質"
|
||||
},
|
||||
"soundtrack": "サウンドトラック: {soundtrack}"
|
||||
},
|
||||
|
||||
"controls": "ボタン変更",
|
||||
|
||||
"language": "言語",
|
||||
|
||||
"behavior": "動作",
|
||||
"behavior_menu": {
|
||||
"game_timing": {
|
||||
"entry": "ゲームのタイミング:",
|
||||
"50tps": "50tps (freeware)",
|
||||
"60tps": "60tps (CS+)"
|
||||
},
|
||||
"pause_on_focus_loss": "フォーカスが外れた時のポーズ:",
|
||||
"cutscene_skip_method": {
|
||||
"entry": "カットシーンをスキップ",
|
||||
"hold": "を押し続け",
|
||||
"fastforward": "はやおくり"
|
||||
}
|
||||
},
|
||||
"links": "リンク"
|
||||
},
|
||||
|
||||
"controls_menu": {
|
||||
"select_player": {
|
||||
"entry": "プレイヤーを選択:",
|
||||
"player_1": "プレーヤー 1",
|
||||
"player_2": "プレーヤー 2"
|
||||
},
|
||||
"controller": {
|
||||
"entry": "コントローラ",
|
||||
"keyboard": "キーボード"
|
||||
},
|
||||
"rebind": "再バインド",
|
||||
"rebind_menu": {
|
||||
"up": "うえ",
|
||||
"down": "した",
|
||||
"left": "ひだり",
|
||||
"right": "みぎ",
|
||||
"jump": "ジャンプ",
|
||||
"shoot": "ショット",
|
||||
"prev_weapon": "前の武器",
|
||||
"next_weapon": "次の武器",
|
||||
"inventory": "在庫",
|
||||
"map": "マップシステム",
|
||||
"skip": "スキップ",
|
||||
"strafe": "ストレイフ",
|
||||
"menu_ok": "メニュー選択/OK",
|
||||
"menu_back": "メニュー残す/キャンセル"
|
||||
},
|
||||
|
||||
"rebind_confirm_menu": {
|
||||
"title": "新しい「ジャンプ」ボタンを押す",
|
||||
"cancel": "(Escキーを押してキャンセル)"
|
||||
},
|
||||
|
||||
"rumble": "ランブル",
|
||||
|
||||
"reset_confirm": "リセット",
|
||||
"reset_confirm_menu_title": "ボタンをリセットしますか?"
|
||||
}
|
||||
},
|
||||
|
||||
"soundtrack": {
|
||||
"organya": "オルガーニャ",
|
||||
"remastered": "リマスター",
|
||||
"new": "新",
|
||||
"famitracks": "ファミトラック"
|
||||
},
|
||||
"game": {
|
||||
"cutscene_skip": "{key} を押し続け、カットシーンをスキップ"
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 130 B |
|
@ -1,276 +0,0 @@
|
|||
# AngelCode Bitmap Font Generator configuration file
|
||||
fileVersion=1
|
||||
|
||||
# font settings
|
||||
fontName=JF Dot k12x10
|
||||
fontFile=JF-Dot-k12x10.ttf
|
||||
charSet=0
|
||||
fontSize=10
|
||||
aa=1
|
||||
scaleH=100
|
||||
useSmoothing=0
|
||||
isBold=0
|
||||
isItalic=0
|
||||
useUnicode=1
|
||||
disableBoxChars=1
|
||||
outputInvalidCharGlyph=1
|
||||
dontIncludeKerningPairs=0
|
||||
useHinting=1
|
||||
renderFromOutline=0
|
||||
useClearType=1
|
||||
autoFitNumPages=0
|
||||
autoFitFontSizeMin=0
|
||||
autoFitFontSizeMax=0
|
||||
|
||||
# character alignment
|
||||
paddingDown=0
|
||||
paddingUp=0
|
||||
paddingRight=0
|
||||
paddingLeft=0
|
||||
spacingHoriz=1
|
||||
spacingVert=1
|
||||
useFixedHeight=0
|
||||
forceZero=0
|
||||
widthPaddingFactor=0.00
|
||||
|
||||
# output file
|
||||
outWidth=512
|
||||
outHeight=512
|
||||
outBitDepth=8
|
||||
fontDescFormat=2
|
||||
fourChnlPacked=0
|
||||
textureFormat=png
|
||||
textureCompression=0
|
||||
alphaChnl=0
|
||||
redChnl=4
|
||||
greenChnl=4
|
||||
blueChnl=4
|
||||
invA=0
|
||||
invR=0
|
||||
invG=0
|
||||
invB=0
|
||||
|
||||
# outline
|
||||
outlineThickness=0
|
||||
|
||||
# selected chars
|
||||
chars=32-126,160,167-168,176-177,180,182,215,247,913-929,931-937,945-961,963-969,1025,1040-1103,1105,8208
|
||||
chars=8213,8216-8217,8229-8230,8251,8451,8470,8481,8491,8544-8553,8592-8595,8658,8660,8722,8730,8733-8734
|
||||
chars=9312-9331,9472-9475,9484,9487-9488,9491-9492,9495-9496,9499-9501,9504,9507-9509,9512,9515-9516,9519
|
||||
chars=9520,9523-9524,9527-9528,9531-9532,9535,9538,9547,9632-9633,9650-9651,9660-9661,9670-9671,9675,9678
|
||||
chars=9679,9711,9733-9734,9792,9794,9834,9837,9839,12288-12291,12293-12309,12316-12317,12319,12353-12435
|
||||
chars=12443-12446,12449-12534,12539-12542,12849-12850,12857,12964-12968,13059,13069,13076,13080,13090
|
||||
chars=13091,13094-13095,13099,13110,13115,13129-13130,13133,13137,13143,13179-13182,13198-13199,13212
|
||||
chars=13213-13214,13217,13252,13261,19968-19969,19971,19975-19979,19981-19982,19984-19985,19988-19993
|
||||
chars=19998,20001,20006,20010,20013,20017-20018,20022,20024-20025,20027-20028,20031,20034-20035,20037
|
||||
chars=20043,20045-20047,20053-20057,20061-20063,20066,20081,20083,20094,20096,20098,20101-20102,20104
|
||||
chars=20105-20108,20110,20113-20114,20116-20117,20120-20121,20123-20124,20126-20130,20132-20134,20136
|
||||
chars=20139-20142,20144,20147,20150,20154,20160-20162,20164,20166-20167,20170-20171,20173-20175,20180
|
||||
chars=20181-20185,20189-20191,20195-20197,20205-20206,20208,20210,20214-20215,20219,20225,20233-20234
|
||||
chars=20237-20241,20250,20252-20253,20271-20272,20276,20278,20280,20282,20284-20285,20291,20294-20295
|
||||
chars=20301-20305,20307,20309,20311,20313-20318,20329,20335-20336,20339,20341-20342,20347-20348,20351
|
||||
chars=20355,20358,20360,20363,20365,20367,20369,20374,20376,20379,20381,20384-20385,20395,20397-20399
|
||||
chars=20405-20406,20415,20418-20420,20426,20430,20432-20433,20436,20439-20440,20442-20443,20445,20447
|
||||
chars=20449,20451-20453,20462-20463,20467,20469-20470,20472,20474,20478,20485-20486,20489,20491,20493
|
||||
chars=20495,20497-20498,20500,20502,20505-20506,20511,20513,20515-20518,20520-20525,20534,20537,20547
|
||||
chars=20551-20553,20559-20560,20565-20566,20570,20572,20581,20588,20594,20596-20598,20600,20605,20608
|
||||
chars=20613,20621,20625,20632-20634,20652-20653,20658-20661,20663,20670,20674,20677,20681-20682,20685
|
||||
chars=20687,20689,20693-20694,20698,20702,20707,20709,20711,20717-20718,20725,20729,20731,20736-20738
|
||||
chars=20740,20745,20754,20756-20758,20760,20762,20767,20769,20778,20786,20791,20794-20796,20799-20801
|
||||
chars=20803-20809,20811-20814,20816,20818,20820,20826,20828,20834,20837,20840-20846,20849,20853-20856
|
||||
chars=20860,20864,20866,20869-20870,20873-20874,20876-20877,20879-20883,20885-20887,20889,20896,20898
|
||||
chars=20900-20902,20904-20908,20912-20919,20925,20932-20934,20937,20939-20941,20950,20955-20957,20960
|
||||
chars=20961,20966-20967,20969-20970,20973,20976-20977,20981-20982,20984-20986,20989-20990,20992,20995
|
||||
chars=20996,20998-21000,21002-21003,21006,21009,21012,21015,21021,21028-21029,21031,21033-21034,21038
|
||||
chars=21040,21043,21046-21051,21059-21060,21063,21066-21069,21071,21076,21078,21083,21086,21091-21093
|
||||
chars=21097-21098,21103-21109,21117,21119,21123,21127-21129,21133,21137-21138,21140,21147,21151-21152
|
||||
chars=21155,21161-21165,21169,21172-21173,21177,21180,21182,21185,21187,21189,21191,21193,21197,21202
|
||||
chars=21205,21207-21209,21213-21216,21218-21220,21222-21223,21234-21235,21237,21240-21242,21246-21247
|
||||
chars=21249-21250,21253-21254,21256,21261,21263-21264,21269-21271,21273-21274,21277,21280-21281,21283
|
||||
chars=21290,21295,21297,21299,21304-21307,21311-21313,21315,21317-21322,21325,21329-21332,21335-21336
|
||||
chars=21338,21340,21342,21344,21350,21353,21358-21361,21363-21365,21367-21368,21371,21375,21378,21380
|
||||
chars=21398,21400,21402,21407-21408,21413-21414,21416-21417,21421-21422,21424,21427,21430,21435,21442
|
||||
chars=21443,21448-21454,21460,21462-21463,21465,21467,21471,21473-21477,21480-21491,21494-21496,21498
|
||||
chars=21505,21507-21508,21512-21521,21531,21533,21535-21536,21542,21545,21547-21550,21558,21560-21561
|
||||
chars=21563-21566,21568,21570,21574,21576-21578,21582,21585,21599,21608,21610,21616-21617,21619,21621
|
||||
chars=21622-21623,21627-21629,21632,21636,21638,21643-21644,21646-21648,21650,21666,21668-21669,21672
|
||||
chars=21675-21676,21679,21682-21683,21688,21692-21694,21696-21698,21700,21703-21705,21720,21729-21730
|
||||
chars=21733-21734,21736-21737,21741-21742,21746,21754,21757,21764,21766-21767,21775-21776,21780,21782
|
||||
chars=21806-21807,21809,21811,21816-21817,21822,21824,21828-21830,21836,21839,21843,21846-21847,21852
|
||||
chars=21853,21859,21883-21884,21886,21888,21891-21892,21895,21897-21899,21912-21914,21916-21919,21927
|
||||
chars=21928-21932,21934,21936,21942,21956-21957,21959,21972,21978,21980,21983,21987-21988,22007,22009
|
||||
chars=22013-22014,22022,22025,22036,22038-22040,22043,22057,22063,22065-22066,22068,22070,22072,22082
|
||||
chars=22092,22094,22096,22107,22116,22120,22122-22124,22132,22136,22138,22144,22150-22151,22154,22159
|
||||
chars=22164,22176,22178,22181,22190,22196,22198,22204,22208-22211,22216,22222,22225,22227,22231-22232
|
||||
chars=22234-22235,22238,22240,22243,22254,22256,22258-22259,22265-22266,22269,22271-22272,22275-22276
|
||||
chars=22280-22281,22283,22285,22287,22290-22291,22294,22296,22300,22303,22310-22312,22317,22320,22327
|
||||
chars=22328,22331,22336,22338,22343,22346,22350-22353,22369,22372,22374,22377-22378,22399,22402,22408
|
||||
chars=22409,22411,22419,22432,22434-22436,22442,22448,22451,22464,22467,22470,22475,22478,22482-22484
|
||||
chars=22486,22492,22495-22496,22499,22516,22519,22521-22522,22524,22528,22530,22533-22534,22538-22539
|
||||
chars=22549,22553,22557,22561,22564,22570,22575-22577,22580-22581,22586,22589,22592-22593,22602-22603
|
||||
chars=22609-22610,22612,22615-22618,22622,22626,22633,22635,22640,22642,22645,22649,22654,22659,22661
|
||||
chars=22675,22679,22684,22687,22696,22699,22702,22707,22712-22715,22718,22721,22725,22727,22730,22732
|
||||
chars=22737,22739,22741,22743-22745,22748,22750-22751,22756-22757,22763-22764,22766-22770,22775,22777
|
||||
chars=22778-22781,22786,22793-22794,22799-22800,22805-22806,22808-22812,22818,22821,22823,22825-22830
|
||||
chars=22833-22834,22839-22840,22846,22852,22855-22857,22862-22865,22868-22869,22871-22872,22874,22880
|
||||
chars=22882,22885,22887-22890,22892,22894,22899-22900,22904,22909,22913-22916,22922,22925,22931,22934
|
||||
chars=22937,22939,22941,22947,22949,22952,22956,22962,22969,22971,22974,22982,22985,22987,22992-22993
|
||||
chars=22995-22996,23001-23002,23004,23013-23014,23016,23018-23019,23030,23035,23039,23041,23043,23049
|
||||
chars=23057,23064,23066,23068,23071-23072,23077,23081,23087,23093-23094,23100,23104-23105,23110,23113
|
||||
chars=23130,23138,23142,23146,23148,23167,23186,23194-23195,23228-23230,23233-23234,23241,23243-23244
|
||||
chars=23248,23254-23255,23265,23267,23270,23273,23290-23291,23305,23307-23308,23318,23330,23338,23340
|
||||
chars=23344,23346,23350,23358,23360,23363,23365,23376-23377,23380-23381,23383-23384,23386-23389,23391
|
||||
chars=23395-23398,23401,23403,23408-23409,23411,23413,23416,23418,23424,23427,23429,23431-23433,23435
|
||||
chars=23436-23437,23439,23445,23447-23453,23455,23458-23462,23470,23472,23475-23478,23480-23481,23487
|
||||
chars=23490-23495,23497,23500,23504,23506-23508,23515,23517-23519,23521-23522,23524-23529,23531,23534
|
||||
chars=23536,23539,23541-23542,23544,23546,23550-23551,23553-23554,23556-23563,23565-23567,23569,23571
|
||||
chars=23574,23578,23584,23586,23588,23592,23597,23601,23608-23617,23621-23622,23624,23626-23627,23629
|
||||
chars=23630-23633,23635,23637,23646,23648-23649,23652-23653,23660,23662-23663,23665,23670,23673,23692
|
||||
chars=23696-23697,23700,23713,23720-23721,23723-23724,23729,23731,23734-23736,23739-23740,23742,23749
|
||||
chars=23751,23769,23776-23777,23784-23786,23789,23791-23792,23798,23802-23803,23805,23815,23819,23822
|
||||
chars=23825,23828-23835,23839,23842,23849,23883-23884,23886,23888,23890,23900,23913,23916,23919,23923
|
||||
chars=23926,23938,23940,23943,23947-23948,23952,23965,23970,23980,23982,23991,23994,23996-23997,24009
|
||||
chars=24012-24013,24018-24019,24022,24027,24029-24030,24033,24035,24037-24040,24043,24046,24049-24053
|
||||
chars=24055,24059,24061-24062,24066-24067,24070,24075-24076,24081,24086,24089-24091,24093,24101,24107
|
||||
chars=24109,24111-24112,24115,24118-24120,24125,24128,24131-24133,24135,24140,24142,24148-24149,24151
|
||||
chars=24159,24161-24164,24178-24182,24184-24191,24193,24195-24196,24199,24202,24207,24213-24215,24218
|
||||
chars=24220,24224,24230-24231,24235,24237,24245-24248,24257-24259,24264-24266,24271-24272,24275,24278
|
||||
chars=24282-24283,24285,24287-24291,24296-24297,24300,24304-24305,24307-24308,24310-24312,24314-24316
|
||||
chars=24318-24319,24321,24323-24324,24329-24333,24335-24337,24339-24344,24347,24351,24357-24359,24361
|
||||
chars=24365,24367,24369,24373,24375-24376,24380,24382,24385,24392,24394,24396,24398,24401,24403,24406
|
||||
chars=24407,24409,24412-24413,24417-24418,24422,24425-24429,24432-24433,24435,24439,24441,24444,24447
|
||||
chars=24448-24453,24455-24456,24458-24460,24464-24467,24471-24473,24478,24480-24481,24488-24490,24493
|
||||
chars=24494,24499-24500,24505,24508-24509,24515,24517,24524-24525,24534-24537,24540-24541,24544,24548
|
||||
chars=24555,24560-24561,24565,24568,24571,24573,24575,24590-24592,24594,24597-24598,24601,24603-24605
|
||||
chars=24608-24609,24613-24619,24623,24625,24634,24641-24643,24646,24650-24651,24653,24656,24658,24661
|
||||
chars=24665-24666,24671-24672,24674-24677,24680-24685,24687-24688,24693,24695,24705,24707-24708,24713
|
||||
chars=24715-24717,24722,24724,24726-24727,24730-24731,24735-24736,24739,24742-24743,24745-24746,24754
|
||||
chars=24755-24758,24760,24764-24765,24773-24775,24785,24787,24792,24794,24796,24799-24801,24803,24807
|
||||
chars=24808,24816-24817,24819-24820,24822-24823,24825-24827,24832-24833,24835,24838,24840-24841,24845
|
||||
chars=24846-24847,24853,24858-24859,24863,24865,24871-24872,24876,24884,24892-24895,24898,24900,24903
|
||||
chars=24904,24906-24910,24915,24917,24920-24922,24925,24927,24930-24931,24933,24935-24936,24939,24942
|
||||
chars=24943-24945,24947-24951,24958,24962,24967,24970,24974,24976-24977,24980,24982,24985-24986,24996
|
||||
chars=24999,25001,25003-25004,25006,25010,25014,25018,25022,25027,25030-25037,25040,25059,25062,25074
|
||||
chars=25076,25078-25080,25082,25084-25088,25096-25098,25100-25102,25104-25106,25108,25110,25114-25115
|
||||
chars=25117-25119,25121,25126,25130,25134-25136,25138-25140,25144,25147,25151-25153,25159-25161,25163
|
||||
chars=25165-25166,25171,25173,25176,25179,25182,25184,25187,25192,25198,25201,25206,25209,25212,25214
|
||||
chars=25215-25216,25218-25220,25225-25226,25233-25240,25243-25244,25246,25259-25260,25265,25269,25273
|
||||
chars=25275-25277,25282,25285-25290,25292-25293,25295-25300,25303-25305,25307-25309,25312-25313,25324
|
||||
chars=25325-25327,25329,25331,25333-25335,25342-25343,25345-25346,25351-25353,25356,25361,25369,25375
|
||||
chars=25383-25384,25387,25391,25402,25405-25407,25417,25420-25421,25423-25424,25429,25431,25436,25447
|
||||
chars=25448-25449,25451,25454,25458,25462-25463,25466-25467,25472,25475,25480-25481,25484,25486-25487
|
||||
chars=25490,25494,25496,25499,25503-25507,25509,25511-25516,25522,25524-25525,25531,25534,25536,25539
|
||||
chars=25540,25542,25545,25551-25552,25554,25558,25562-25563,25569,25571,25577,25582,25588,25590,25594
|
||||
chars=25606,25613,25615,25619,25622-25623,25628,25638,25640,25644-25645,25652,25654,25658,25662,25666
|
||||
chars=25678,25688,25703,25705,25711,25718,25720,25722,25731,25736,25746-25747,25749,25754,25758,25764
|
||||
chars=25765,25769,25771,25773-25774,25776,25778,25785,25787-25788,25793-25794,25797,25799,25805,25810
|
||||
chars=25812,25816,25818,25824-25827,25830-25831,25836,25839,25841-25842,25844,25846,25850,25853-25854
|
||||
chars=25856,25861,25880,25884-25885,25891-25892,25898-25900,25903,25908-25913,25915,25918-25919,25925
|
||||
chars=25928,25933,25935,25937,25941-25945,25949-25950,25954-25955,25958,25964,25968,25970,25972-25973
|
||||
chars=25975-25976,25986-25987,25991-25993,25996,25998,26000-26001,26007,26009,26011-26012,26015,26017
|
||||
chars=26020-26021,26023,26027-26029,26031-26032,26039,26041,26044-26045,26049,26051-26054,26059-26060
|
||||
chars=26063,26066,26071,26073,26075,26080-26082,26085-26089,26092-26093,26097,26106-26107,26114-26115
|
||||
chars=26118-26119,26122,26124,26126-26127,26131-26132,26140,26143-26144,26149,26151-26152,26157,26159
|
||||
chars=26164-26166,26172,26175,26177-26180,26185,26187,26191,26194,26205-26207,26210,26212,26214-26217
|
||||
chars=26222-26224,26228,26230,26234,26241,26243-26244,26247-26249,26254,26257,26262-26264,26269,26274
|
||||
chars=26278,26283,26286,26292,26296-26297,26300,26302,26305,26308,26311,26313,26326,26329-26330,26332
|
||||
chars=26333,26336,26342,26345,26352,26354-26357,26359-26361,26364-26368,26371,26376-26377,26379,26381
|
||||
chars=26383,26388-26391,26395,26397-26399,26406-26408,26410-26414,26417,26420,26422-26424,26426,26429
|
||||
chars=26431,26433,26438,26441,26446-26449,26451,26454,26457,26460,26462-26469,26474,26477,26479-26483
|
||||
chars=26485,26487,26492,26494-26495,26501,26503,26505,26507-26508,26512,26517,26519,26522,26524-26525
|
||||
chars=26528-26530,26534,26537,26543,26547-26548,26550-26553,26561,26564,26566,26570,26574-26577,26579
|
||||
chars=26580,26584,26586,26589-26590,26594,26596,26599,26601,26604,26606-26607,26609,26611-26613,26619
|
||||
chars=26622-26623,26626-26628,26643,26646-26647,26654,26657-26658,26665-26667,26674,26676,26680-26681
|
||||
chars=26684-26685,26688-26691,26694,26696,26701-26702,26704-26705,26707-26708,26713,26716-26717,26719
|
||||
chars=26723,26727,26740,26742-26743,26750-26751,26753,26755,26757,26765,26767,26771-26772,26775,26779
|
||||
chars=26781,26783-26784,26786,26790-26792,26797,26799-26801,26803,26805-26806,26809-26810,26812,26820
|
||||
chars=26822,26825-26827,26829,26834,26836-26837,26839-26840,26842,26847-26849,26851,26855,26862-26863
|
||||
chars=26866,26873-26874,26880-26881,26884-26885,26888,26891-26895,26898,26905-26908,26913-26915,26917
|
||||
chars=26918,26920,26922,26928,26932,26934,26937,26941,26943,26954,26963-26965,26969-26970,26972-26974
|
||||
chars=26976-26978,26986-26987,26989-26991,26995-26997,26999-27001,27004-27006,27009-27010,27018,27022
|
||||
chars=27025,27028-27029,27035-27036,27040,27047,27054,27057-27058,27060,27067,27070-27071,27073,27075
|
||||
chars=27079,27082-27086,27088,27091,27096-27097,27101-27102,27111-27112,27115,27117,27122,27129,27131
|
||||
chars=27133,27135,27138,27141,27146-27148,27154-27156,27159,27161,27163,27166-27167,27169-27171,27177
|
||||
chars=27178-27179,27182,27189-27190,27192-27194,27197,27204,27207-27208,27211,27224-27225,27231,27233
|
||||
chars=27234,27238,27250,27256,27263-27264,27268,27277-27278,27280,27287,27292,27296,27298-27299,27306
|
||||
chars=27308,27310,27315,27320,27323,27329-27331,27345,27347,27354-27355,27358-27359,27368,27370,27386
|
||||
chars=27387,27396-27397,27402,27410,27414,27421,27423-27425,27427,27431,27442,27447-27450,27453-27454
|
||||
chars=27459,27463,27465,27468,27470,27472,27475-27476,27481,27483,27487,27489-27492,27494,27497-27498
|
||||
chars=27503,27507-27508,27512-27513,27515,27519-27520,27523-27524,27526,27529-27531,27533,27541-27542
|
||||
chars=27544,27550,27556,27562-27563,27567,27569-27573,27575,27578-27580,27583-27584,27589-27590,27595
|
||||
chars=27597-27598,27602-27604,27608,27611,27615,27627-27628,27631,27635,27656,27663,27665,27667-27668
|
||||
chars=27671,27675,27683-27684,27700,27703-27704,27710,27712-27714,27726,27728,27733,27735,27738,27741
|
||||
chars=27742-27744,27746,27752,27754,27760,27762-27763,27770,27773-27774,27777-27779,27784,27788-27789
|
||||
chars=27792,27794-27795,27798,27801-27803,27809-27810,27819,27822,27825,27827,27832-27839,27841,27844
|
||||
chars=27845,27849-27850,27852,27859,27861,27863,27865,27867,27869,27873-27875,27877,27880,27882,27887
|
||||
chars=27888-27889,27891,27915,27922,27927,27934,27941,27946,27963,27966,27969,27972-27973,27996,28006
|
||||
chars=28009-28010,28014,28020,28023-28024,28040,28057,28079,28082,28092,28096,28129,28145,28147,28151
|
||||
chars=28155,28165,28167-28169,28171,28187,28193,28198,28201,28204,28207,28246,28248,28263,28271,28286
|
||||
chars=28287-28288,28304,28310,28316-28317,28322,28342,28357,28363,28369,28381-28382,28402,28404,28417
|
||||
chars=28418,28431,28436,28448,28450,28459-28460,28500,28508,28511,28516,28526,28528,28548,28580,28608
|
||||
chars=28609,28611,28641,28655,28716,28779,28783-28784,28796-28797,28809-28810,28814,28818,28844-28845
|
||||
chars=28857-28858,28872,28954,28961,28966,28982,28988,29017,29031,29033,29038,29053,29066,29087,29105
|
||||
chars=29123,29157,29165,29173,29190,29226,29238,29242,29245,29255-29256,29273,29275,29282,29287,29289
|
||||
chars=29298,29305,29344,29356,29359,29366,29378,29401,29417,29420-29421,29436,29467,29471,29482-29483
|
||||
chars=29486,29494,29503,29508,29539,29554,29572,29575,29577,29579,29645,29664,29677,29694,29699,29702
|
||||
chars=29705,29730,29748,29790,29863,29872,29926,29942,29976,29983,29987,29992,30000-30003,30007,30010
|
||||
chars=30011,30028,30033,30041,30044,30053,30058,30064,30067,30079,30094,30097,30123,30130,30142,30149
|
||||
chars=30151,30169,30171,30185,30196,30202,30221,30274,30284,30290,30294,30330-30331,30333-30334,30340
|
||||
chars=30342-30343,30382,30394,30399,30406,30410,30423,30427,30431,30435-30436,30439,30446,30450,30452
|
||||
chars=30456,30462,30465,30473,30475-30476,30494-30496,30505,30522,30524,30528,30561,30563,30568,30609
|
||||
chars=30636,30643,30652,30683,30690,30693,30697,30701,30703,30707,30722,30740-30741,30770,30772,30813
|
||||
chars=30828,30849,30906,30913,30952,30990,31034,31036,31038,31048-31049,31062,31069-31070,31077,31080
|
||||
chars=31085,31105,31119,31168-31169,31179,31185-31186,31192,31199,31209,31216,31227,31232,31243,31246
|
||||
chars=31258,31278,31282,31292-31293,31295,31298,31309,31311,31339,31348,31350,31354,31361,31363,31379
|
||||
chars=31391,31406,31435,31452,31456,31461,31471,31478,31481,31499,31505,31515,31520,31526,31532,31545
|
||||
chars=31558,31560-31561,31563,31570,31572,31574,31623,31639,31649,31665,31672,31680,31684,31687,31689
|
||||
chars=31761,31777,31807,31821,31840,31859,31881,31883,31890,31896,31911,31934,31958,31966,31975,31992
|
||||
chars=31995,32000,32004-32005,32011,32013,32016,32020,32025-32027,32032,32034,32043,32047-32048,32051
|
||||
chars=32057-32058,32066,32068,32070,32076,32080,32094,32097,32102,32113,32117-32118,32121,32153-32154
|
||||
chars=32173,32177-32178,32180,32186-32187,32190-32191,32202,32207,32209-32210,32218,32224,32232-32233
|
||||
chars=32239,32244,32257,32260,32283,32294,32302,32318,32321,32330-32331,32340,32368,32566,32608,32618
|
||||
chars=32622,32624,32626,32645,32650,32654,32676,32680-32681,32701,32709,32716,32722,32724,32763-32764
|
||||
chars=32769,32771,32773,32784,32791,32819,32854,32862,32865,32884,32887,32905,32908,32918,32925,32929
|
||||
chars=32930,32933,32937-32938,32943,32946,32954,32963,32966,32972,32974,32990,32993,33016,33021,33026
|
||||
chars=33029-33032,33050,33073,33075,33104,33107,33109,33131,33136,33144-33146,33178,33180-33181,33192
|
||||
chars=33222,33235,33251,33256,33258,33261,33267-33268,33288,33292,33294,33296,33303,33307,33310-33311
|
||||
chars=33322,33324,33337,33351,33382,33391,33394,33398,33437,33446,33455,33457,33459,33464,33469,33495
|
||||
chars=33499,33509-33510,33521,33538,33540,33576,33590,33609,33618,33624,33655,33707,33733,33738,33740
|
||||
chars=33747,33756,33775,33777,33804,33853,33865,33879,33883,33891,33900,33945,33976,33980,33988,33995
|
||||
chars=34001,34030,34101,34109,34126,34180,34183,34196,34199,34214,34219-34220,34253,34276,34281,34299
|
||||
chars=34311,34349,34382,34384,34394,34411,34425,34442,34503,34509,34521,34678,34701,34811,34821,34880
|
||||
chars=34886,34892,34899,34903,34907,34909,34913,34915,34920,34928,34955,34966,34987,35009-35010,35013
|
||||
chars=35023,35029,35036,35064,35069-35070,35079,35090,35186,35199,35201,35206-35207,35211,35215,35222
|
||||
chars=35223,35226,35239,35242,35251,35282,35299,35302,35328,35330,35336,35338,35342,35347,35351-35352
|
||||
chars=35357,35359,35363,35370,35373,35377,35379-35380,35386,35388,35408,35413,35422,35430,35433,35435
|
||||
chars=35438,35440-35443,35463,35465,35468-35469,35475,35477,35480,35486,35488,35492,35500-35501,35504
|
||||
chars=35506,35519,35527,35531,35542,35558,35565-35566,35576,35582,35584,35598,35609,35611,35613,35617
|
||||
chars=35672,35676,35686,35696,35698,35703,35728,35895,35910,35914,35930,35937,35946,35980,35997-35998
|
||||
chars=36000-36002,36007-36009,36011-36012,36015-36016,36020,36022-36024,36027-36028,36031-36032,36035
|
||||
chars=36039,36042,36049,36059,36062,36064,36066,36074,36077,36092,36101,36104,36196,36198,36208,36212
|
||||
chars=36215,36229,36234,36259,36275,36317,36321,36335,36339,36341,36362,36367,36468,36487,36490,36493
|
||||
chars=36523,36554,36556-36557,36562,36575,36578,36600,36605,36611,36617,36628,36637,36649-36650,36664
|
||||
chars=36676,36763,36766,36784-36786,36794-36796,36799,36804-36805,36814,36817,36820,36843,36848,36855
|
||||
chars=36861,36864-36865,36867,36870,36879,36884,36889-36890,36893,36895-36896,36899,36910,36913-36914
|
||||
chars=36920,36930,36933,36935,36938-36939,36941-36942,36947-36949,36960-36961,36963,36965,36969,36973
|
||||
chars=36974,36981,36983-36984,36986,36989,36991,36996,37027,37030,37034,37048,37066,37070,37089,37096
|
||||
chars=37101,37109,37111,37117,37197-37198,37202,37204,37218,37228,37237,37239-37240,37266,37276,37284
|
||||
chars=37320,37324-37327,37329,37340-37341,37347,37351,37389,37428,37444,37474,37489,37504,37507,37509
|
||||
chars=37528,37549,37613,37628,37679,37682,37707,37723,37749,37772,37782,37806,37857,37912,37969,38263
|
||||
chars=38272,38275,38281,38283,38291,38306-38307,38309,38322,38343,38346,38360,38428,38442,38450,38459
|
||||
chars=38463-38464,38477,38480,38498-38501,38506,38512,38515,38518,38520,38522,38525,38533-38534,38538
|
||||
chars=38542-38543,38548,38553,38555-38556,38560,38563,38583,38588,38592,38596-38599,38609,38626-38627
|
||||
chars=38632,38634,38640,38642,38646-38647,38651,38656,38663,38666,38686,38695,38706,38738,38742,38745
|
||||
chars=38750,38754,38761,38772,38788,38867,38899,38907,38911,38913-38915,38917-38918,38920,38928-38929
|
||||
chars=38931,38936,38956-38957,38967,38971-38972,38988-38990,38996-38997,39000,39006,39015,39080,39082
|
||||
chars=39131,39135,39138,39151,39154,39156,39164-39166,39171,39173,39178,39180,39208,39318,39321,39340
|
||||
chars=39348,39364-39366,39376,39378,39423,39438,39442-39443,39449,39472,39514,39592,39608,39640,39658
|
||||
chars=39661,39706,39729,39740,39745-39746,39749,39764,39770,39791,39854,39881,40165,40169,40180,40335
|
||||
chars=40372,40441,40474-40475,40478,40565,40568-40569,40573,40575,40577,40584,40587-40588,40593-40595
|
||||
chars=40597,40599,40605,40607,40613-40614,40617-40618,40621,40632-40636,40638-40639,40644,40652-40656
|
||||
chars=40658,40660,40664-40665,40667-40670,40672,40677,40680,40687,40692,40694-40695,40697,40699-40701
|
||||
chars=40711-40712,40718,40723,40725,40736-40737,40748,40763,40766,40778-40779,40782-40783,40786,40788
|
||||
chars=40799-40803,40806-40807,40810,40812,40818,40822-40823,40845,40853,40860-40861,40864,65281,65283
|
||||
chars=65284-65286,65288-65374,65377-65439,65504-65507,65509
|
||||
|
||||
# imported icon images
|
Before Width: | Height: | Size: 90 KiB |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 16 KiB |
|
@ -1,330 +0,0 @@
|
|||
use std::fmt::Debug;
|
||||
use std::io::Cursor;
|
||||
use std::io::ErrorKind;
|
||||
use std::io::SeekFrom;
|
||||
use std::path::{Component, Path, PathBuf};
|
||||
use std::{fmt, io};
|
||||
|
||||
use crate::framework::error::GameError::FilesystemError;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::framework::vfs::{OpenOptions, VFile, VMetadata, VFS};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BuiltinFile(Cursor<&'static [u8]>);
|
||||
|
||||
impl BuiltinFile {
|
||||
pub fn from(buf: &'static [u8]) -> Box<dyn VFile> {
|
||||
Box::new(BuiltinFile(Cursor::new(buf)))
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Read for BuiltinFile {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.0.read(buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Seek for BuiltinFile {
|
||||
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
|
||||
self.0.seek(pos)
|
||||
}
|
||||
}
|
||||
|
||||
impl io::Write for BuiltinFile {
|
||||
fn write(&mut self, _buf: &[u8]) -> io::Result<usize> {
|
||||
Err(io::Error::new(ErrorKind::PermissionDenied, "Built-in file system is read-only."))
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Err(io::Error::new(ErrorKind::PermissionDenied, "Built-in file system is read-only."))
|
||||
}
|
||||
}
|
||||
|
||||
struct BuiltinMetadata {
|
||||
is_dir: bool,
|
||||
size: u64,
|
||||
}
|
||||
|
||||
impl VMetadata for BuiltinMetadata {
|
||||
fn is_dir(&self) -> bool {
|
||||
self.is_dir
|
||||
}
|
||||
|
||||
fn is_file(&self) -> bool {
|
||||
!self.is_dir
|
||||
}
|
||||
|
||||
fn len(&self) -> u64 {
|
||||
self.size
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
enum FSNode {
|
||||
File(&'static str, &'static [u8]),
|
||||
Directory(&'static str, Vec<FSNode>),
|
||||
}
|
||||
|
||||
impl FSNode {
|
||||
fn get_name(&self) -> &'static str {
|
||||
match self {
|
||||
FSNode::File(name, _) => name,
|
||||
FSNode::Directory(name, _) => name,
|
||||
}
|
||||
}
|
||||
|
||||
fn to_file(&self) -> GameResult<Box<dyn VFile>> {
|
||||
match self {
|
||||
FSNode::File(_, buf) => Ok(BuiltinFile::from(buf)),
|
||||
FSNode::Directory(name, _) => Err(FilesystemError(format!("{} is a directory.", name))),
|
||||
}
|
||||
}
|
||||
|
||||
fn to_metadata(&self) -> Box<dyn VMetadata> {
|
||||
match self {
|
||||
FSNode::File(_, buf) => Box::new(BuiltinMetadata { is_dir: false, size: buf.len() as u64 }),
|
||||
FSNode::Directory(_, _) => Box::new(BuiltinMetadata { is_dir: true, size: 0 }),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BuiltinFS {
|
||||
root: Vec<FSNode>,
|
||||
}
|
||||
|
||||
impl BuiltinFS {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
root: vec![FSNode::Directory(
|
||||
"builtin",
|
||||
vec![
|
||||
FSNode::File("builtin_font.fnt", include_bytes!("builtin/builtin_font.fnt")),
|
||||
FSNode::File("builtin_font_0.png", include_bytes!("builtin/builtin_font_0.png")),
|
||||
FSNode::File("builtin_font_1.png", include_bytes!("builtin/builtin_font_1.png")),
|
||||
FSNode::File("gamecontrollerdb.txt", include_bytes!("builtin/gamecontrollerdb.txt")),
|
||||
FSNode::File(
|
||||
"organya-wavetable-doukutsu.bin",
|
||||
include_bytes!("builtin/organya-wavetable-doukutsu.bin"),
|
||||
),
|
||||
FSNode::File("touch.png", include_bytes!("builtin/touch.png")),
|
||||
FSNode::Directory(
|
||||
"builtin_data",
|
||||
vec![
|
||||
FSNode::File("buttons.png", include_bytes!("builtin/builtin_data/buttons.png")),
|
||||
FSNode::File("triangles.png", include_bytes!("builtin/builtin_data/triangles.png")),
|
||||
FSNode::Directory(
|
||||
"headband",
|
||||
vec![
|
||||
FSNode::Directory(
|
||||
"ogph",
|
||||
vec![
|
||||
FSNode::File(
|
||||
"Casts.png",
|
||||
include_bytes!("builtin/builtin_data/headband/ogph/Casts.png"),
|
||||
),
|
||||
FSNode::Directory(
|
||||
"Npc",
|
||||
vec![
|
||||
FSNode::File(
|
||||
"NpcGuest.png",
|
||||
include_bytes!(
|
||||
"builtin/builtin_data/headband/ogph/Npc/NpcGuest.png"
|
||||
),
|
||||
),
|
||||
FSNode::File(
|
||||
"NpcMiza.png",
|
||||
include_bytes!(
|
||||
"builtin/builtin_data/headband/ogph/Npc/NpcMiza.png"
|
||||
),
|
||||
),
|
||||
FSNode::File(
|
||||
"NpcRegu.png",
|
||||
include_bytes!(
|
||||
"builtin/builtin_data/headband/ogph/Npc/NpcRegu.png"
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
FSNode::Directory(
|
||||
"plus",
|
||||
vec![
|
||||
FSNode::File(
|
||||
"Casts.png",
|
||||
include_bytes!("builtin/builtin_data/headband/plus/casts.png"),
|
||||
),
|
||||
FSNode::Directory(
|
||||
"Npc",
|
||||
vec![
|
||||
FSNode::File(
|
||||
"NpcGuest.png",
|
||||
include_bytes!(
|
||||
"builtin/builtin_data/headband/plus/npc/npcguest.png"
|
||||
),
|
||||
),
|
||||
FSNode::File(
|
||||
"NpcMiza.png",
|
||||
include_bytes!(
|
||||
"builtin/builtin_data/headband/plus/npc/npcmiza.png"
|
||||
),
|
||||
),
|
||||
FSNode::File(
|
||||
"NpcRegu.png",
|
||||
include_bytes!(
|
||||
"builtin/builtin_data/headband/plus/npc/npcregu.png"
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
FSNode::Directory(
|
||||
"locale",
|
||||
vec![
|
||||
FSNode::File("en.json", include_bytes!("builtin/builtin_data/locale/en.json")),
|
||||
FSNode::File("jp.json", include_bytes!("builtin/builtin_data/locale/jp.json")),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
FSNode::Directory(
|
||||
"shaders",
|
||||
vec![
|
||||
// FSNode::File("basic_150.vert.glsl", include_bytes!("builtin/shaders/basic_150.vert.glsl")),
|
||||
// FSNode::File("water_150.frag.glsl", include_bytes!("builtin/shaders/water_150.frag.glsl")),
|
||||
// FSNode::File("basic_es300.vert.glsl", include_bytes!("builtin/shaders/basic_es300.vert.glsl")),
|
||||
// FSNode::File("water_es300.frag.glsl", include_bytes!("builtin/shaders/water_es300.frag.glsl")),
|
||||
],
|
||||
),
|
||||
FSNode::Directory(
|
||||
"lightmap",
|
||||
vec![FSNode::File("spot.png", include_bytes!("builtin/lightmap/spot.png"))],
|
||||
),
|
||||
],
|
||||
)],
|
||||
}
|
||||
}
|
||||
|
||||
fn get_node(&self, path: &Path) -> GameResult<FSNode> {
|
||||
let mut iter = path.components().peekable();
|
||||
|
||||
if let Some(Component::RootDir) = iter.next() {
|
||||
let mut curr_dir = &self.root;
|
||||
|
||||
if iter.peek().is_none() {
|
||||
return Ok(FSNode::Directory("", self.root.clone()));
|
||||
}
|
||||
|
||||
while let Some(comp) = iter.next() {
|
||||
let comp_name = comp.as_os_str().to_string_lossy();
|
||||
|
||||
for file in curr_dir {
|
||||
match file {
|
||||
FSNode::File(name, _) if comp_name.eq(name) => {
|
||||
return if iter.peek().is_some() {
|
||||
Err(FilesystemError(format!("Expected a directory, found a file: {:?}", path)))
|
||||
} else {
|
||||
Ok(file.clone())
|
||||
};
|
||||
}
|
||||
FSNode::Directory(name, contents) if comp_name.eq(name) => {
|
||||
if iter.peek().is_some() {
|
||||
curr_dir = contents;
|
||||
break;
|
||||
} else {
|
||||
return Ok(file.clone());
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Err(FilesystemError("Path must be absolute.".to_string()));
|
||||
}
|
||||
|
||||
Err(FilesystemError("File not found.".to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for BuiltinFS {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
write!(f, "<BuiltinFS>")
|
||||
}
|
||||
}
|
||||
|
||||
impl VFS for BuiltinFS {
|
||||
fn open_options(&self, path: &Path, open_options: OpenOptions) -> GameResult<Box<dyn VFile>> {
|
||||
if open_options.write || open_options.create || open_options.append || open_options.truncate {
|
||||
let msg = format!("Cannot alter file {:?} in root {:?}, filesystem read-only", path, self);
|
||||
return Err(FilesystemError(msg));
|
||||
}
|
||||
|
||||
self.get_node(path)?.to_file()
|
||||
}
|
||||
|
||||
fn mkdir(&self, _path: &Path) -> GameResult<()> {
|
||||
Err(FilesystemError("Tried to make directory {} but FS is read-only".to_string()))
|
||||
}
|
||||
|
||||
fn rm(&self, _path: &Path) -> GameResult<()> {
|
||||
Err(FilesystemError("Tried to remove file {} but FS is read-only".to_string()))
|
||||
}
|
||||
|
||||
fn rmrf(&self, _path: &Path) -> GameResult<()> {
|
||||
Err(FilesystemError("Tried to remove file/dir {} but FS is read-only".to_string()))
|
||||
}
|
||||
|
||||
fn exists(&self, path: &Path) -> bool {
|
||||
self.get_node(path).is_ok()
|
||||
}
|
||||
|
||||
fn metadata(&self, path: &Path) -> GameResult<Box<dyn VMetadata>> {
|
||||
self.get_node(path).map(|v| v.to_metadata())
|
||||
}
|
||||
|
||||
fn read_dir(&self, path: &Path) -> GameResult<Box<dyn Iterator<Item = GameResult<PathBuf>>>> {
|
||||
match self.get_node(path) {
|
||||
Ok(FSNode::Directory(_, contents)) => {
|
||||
let mut vec = Vec::new();
|
||||
for node in contents {
|
||||
vec.push(Ok(PathBuf::from(node.get_name())))
|
||||
}
|
||||
|
||||
Ok(Box::new(vec.into_iter()))
|
||||
}
|
||||
Ok(FSNode::File(_, _)) => Err(FilesystemError(format!("Expected a directory, found a file: {:?}", path))),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
fn to_path_buf(&self) -> Option<PathBuf> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_builtin_fs() {
|
||||
let fs = BuiltinFS {
|
||||
root: vec![
|
||||
FSNode::File("test.txt", &[]),
|
||||
FSNode::Directory(
|
||||
"memes",
|
||||
vec![
|
||||
FSNode::File("nothing.txt", &[]),
|
||||
FSNode::Directory("secret stuff", vec![FSNode::File("passwords.txt", b"12345678")]),
|
||||
],
|
||||
),
|
||||
FSNode::File("test2.txt", &[]),
|
||||
],
|
||||
};
|
||||
|
||||
println!("{:?}", fs.get_node(Path::new("/")).unwrap());
|
||||
println!("{:?}", fs.get_node(Path::new("/test.txt")).unwrap());
|
||||
println!("{:?}", fs.get_node(Path::new("/memes")).unwrap());
|
||||
println!("{:?}", fs.get_node(Path::new("/memes/nothing.txt")).unwrap());
|
||||
println!("{:?}", fs.get_node(Path::new("/memes/secret stuff/passwords.txt")).unwrap());
|
||||
}
|
|
@ -3,12 +3,12 @@ use std::time::{SystemTime, UNIX_EPOCH};
|
|||
|
||||
use lazy_static::lazy_static;
|
||||
use num_traits::{abs, Num};
|
||||
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
||||
use serde::de::{SeqAccess, Visitor};
|
||||
use serde::ser::SerializeTupleStruct;
|
||||
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
use crate::bitfield;
|
||||
use crate::texture_set::G_MAG;
|
||||
use crate::graphics::texture_set::G_MAG;
|
||||
|
||||
/// Multiply cave story degrees (0-255, which corresponds to 0°-360°) with this constant to get
|
||||
/// respective value in radians.
|
||||
|
@ -302,8 +302,8 @@ impl<T: Num + PartialOrd + Copy> Rect<T> {
|
|||
|
||||
impl<T: Num + PartialOrd + Copy + Serialize> Serialize for Rect<T> {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let mut state = serializer.serialize_tuple_struct("Rect", 4)?;
|
||||
state.serialize_field(&self.left)?;
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
use crate::common::{Color, Rect};
|
||||
use crate::frame::Frame;
|
||||
use crate::stage::{BackgroundType, Stage, StageTexturePaths};
|
||||
use crate::{graphics, Context, GameResult, SharedGameState};
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::framework::graphics;
|
||||
use crate::game::frame::Frame;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::game::stage::{BackgroundType, Stage, StageTexturePaths};
|
||||
|
||||
pub struct Background {
|
||||
pub tick: usize,
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use crate::common::Rect;
|
||||
use crate::entity::GameEntity;
|
||||
use crate::frame::Frame;
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::boss::BossNPC;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::game::frame::Frame;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::game::npc::boss::BossNPC;
|
||||
use crate::game::npc::list::NPCList;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(u8)]
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use crate::common::{Color, Rect};
|
||||
use crate::entity::GameEntity;
|
||||
use crate::frame::Frame;
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::framework::graphics;
|
||||
use crate::scripting::tsc::text_script::IllustrationState;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::game::frame::Frame;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::game::scripting::tsc::text_script::IllustrationState;
|
||||
|
||||
pub struct Credits {}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::common::Rect;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
|
||||
#[derive(Debug, EnumIter, PartialEq, Eq, Hash, Copy, Clone)]
|
||||
pub enum Alignment {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use crate::common::{FadeDirection, FadeState, Rect};
|
||||
use crate::entity::GameEntity;
|
||||
use crate::frame::Frame;
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::game::frame::Frame;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
|
||||
pub struct Fade;
|
||||
|
||||
|
|
|
@ -2,12 +2,12 @@ use std::ops::Deref;
|
|||
|
||||
use crate::common::{Color, Rect};
|
||||
use crate::entity::GameEntity;
|
||||
use crate::frame::Frame;
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::graphics;
|
||||
use crate::scripting::tsc::text_script::TextScriptExecutionState;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::framework::graphics;
|
||||
use crate::game::frame::Frame;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::game::scripting::tsc::text_script::TextScriptExecutionState;
|
||||
|
||||
pub struct FallingIsland {}
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use crate::common::{Color, Rect};
|
||||
use crate::entity::GameEntity;
|
||||
use crate::frame::Frame;
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::framework::graphics;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::game::frame::Frame;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
|
||||
pub enum FlashState {
|
||||
None,
|
||||
|
@ -83,7 +83,7 @@ impl GameEntity<()> for Flash {
|
|||
left: 0,
|
||||
top: ((cen_y - width) * state.scale) as isize,
|
||||
right: (state.canvas_size.0 * state.scale) as isize,
|
||||
bottom: ((cen_y + width) * state.scale) as isize
|
||||
bottom: ((cen_y + width) * state.scale) as isize,
|
||||
};
|
||||
|
||||
graphics::draw_rect(ctx, rect, WHITE)?;
|
||||
|
@ -93,7 +93,7 @@ impl GameEntity<()> for Flash {
|
|||
left: ((cen_x - width) * state.scale) as isize,
|
||||
top: 0,
|
||||
right: ((cen_x + width) * state.scale) as isize,
|
||||
bottom: (state.canvas_size.1 * state.scale) as isize
|
||||
bottom: (state.canvas_size.1 * state.scale) as isize,
|
||||
};
|
||||
|
||||
graphics::draw_rect(ctx, rect, WHITE)?;
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
use crate::common::Rect;
|
||||
use crate::components::draw_common::{draw_number, Alignment};
|
||||
use crate::components::draw_common::{Alignment, draw_number};
|
||||
use crate::entity::GameEntity;
|
||||
use crate::frame::Frame;
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::framework::graphics::screen_insets_scaled;
|
||||
use crate::inventory::Inventory;
|
||||
use crate::player::Player;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::weapon::WeaponType;
|
||||
use crate::game::frame::Frame;
|
||||
use crate::game::inventory::Inventory;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::weapon::WeaponType;
|
||||
|
||||
pub struct HUD {
|
||||
pub alignment: Alignment,
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
use crate::common::Rect;
|
||||
use crate::components::draw_common::{draw_number, Alignment};
|
||||
use crate::components::draw_common::{Alignment, draw_number};
|
||||
use crate::components::hud::HUD;
|
||||
use crate::entity::GameEntity;
|
||||
use crate::frame::Frame;
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::game::frame::Frame;
|
||||
use crate::game::inventory::Inventory;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::input::touch_controls::TouchControlType;
|
||||
use crate::inventory::Inventory;
|
||||
use crate::player::Player;
|
||||
use crate::scripting::tsc::text_script::{ScriptMode, TextScriptExecutionState};
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::weapon::{WeaponLevel, WeaponType};
|
||||
use crate::game::player::Player;
|
||||
use crate::game::scripting::tsc::text_script::{ScriptMode, TextScriptExecutionState};
|
||||
use crate::game::weapon::{WeaponLevel, WeaponType};
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
#[repr(u8)]
|
||||
|
@ -91,9 +91,9 @@ impl GameEntity<(&mut Context, &mut Player, &mut Inventory, &mut HUD)> for Inven
|
|||
|
||||
if state.control_flags.control_enabled()
|
||||
&& (player.controller.trigger_inventory()
|
||||
|| player.controller.trigger_menu_back()
|
||||
|| (player.controller.trigger_menu_ok() && self.focus == InventoryFocus::Weapons)
|
||||
|| (state.settings.touch_controls && state.touch_controls.consume_click_in(slot_rect)))
|
||||
|| player.controller.trigger_menu_back()
|
||||
|| (player.controller.trigger_menu_ok() && self.focus == InventoryFocus::Weapons)
|
||||
|| (state.settings.touch_controls && state.touch_controls.consume_click_in(slot_rect)))
|
||||
{
|
||||
state.control_flags.set_ok_button_disabled(false);
|
||||
self.exit(state, player, inventory, hud);
|
||||
|
|
|
@ -4,12 +4,12 @@ use crate::common::{Color, Rect};
|
|||
use crate::framework::backend::{BackendTexture, SpriteBatchCommand};
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::graphics;
|
||||
use crate::framework::graphics;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::game::stage::Stage;
|
||||
use crate::input::touch_controls::TouchControlType;
|
||||
use crate::player::Player;
|
||||
use crate::scripting::tsc::text_script::TextScriptExecutionState;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::stage::Stage;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::scripting::tsc::text_script::TextScriptExecutionState;
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||
pub enum MapSystemState {
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
use byteorder::{ReadBytesExt, WriteBytesExt, LE};
|
||||
use byteorder::{LE, ReadBytesExt, WriteBytesExt};
|
||||
|
||||
use crate::common::Rect;
|
||||
use crate::components::draw_common::{draw_number, draw_number_zeros, Alignment};
|
||||
use crate::components::draw_common::{Alignment, draw_number, draw_number_zeros};
|
||||
use crate::entity::GameEntity;
|
||||
use crate::frame::Frame;
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::framework::filesystem;
|
||||
use crate::framework::vfs::OpenOptions;
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::scripting::tsc::text_script::TextScriptExecutionState;
|
||||
use crate::shared_game_state::{SharedGameState, TimingMode};
|
||||
use crate::game::frame::Frame;
|
||||
use crate::game::shared_game_state::{SharedGameState, TimingMode};
|
||||
use crate::game::player::Player;
|
||||
use crate::game::scripting::tsc::text_script::TextScriptExecutionState;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct NikumaruCounter {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use crate::common::{interpolate_fix9_scale, Rect};
|
||||
use crate::entity::GameEntity;
|
||||
use crate::frame::Frame;
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::game::frame::Frame;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct NumberPopup {
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
use std::io::{Cursor, Read};
|
||||
|
||||
use byteorder::{ReadBytesExt, WriteBytesExt, LE};
|
||||
use byteorder::{LE, ReadBytesExt, WriteBytesExt};
|
||||
|
||||
use crate::entity::GameEntity;
|
||||
use crate::frame::Frame;
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::framework::filesystem;
|
||||
use crate::framework::keyboard::ScanCode;
|
||||
use crate::framework::vfs::OpenOptions;
|
||||
use crate::game::frame::Frame;
|
||||
use crate::game::shared_game_state::{ReplayKind, ReplayState, SharedGameState};
|
||||
use crate::input::replay_player_controller::{KeyState, ReplayController};
|
||||
use crate::player::Player;
|
||||
use crate::shared_game_state::{ReplayKind, ReplayState, SharedGameState};
|
||||
use crate::game::player::Player;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Replay {
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
|
||||
use crate::common::Rect;
|
||||
use crate::entity::GameEntity;
|
||||
use crate::frame::Frame;
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::game::frame::Frame;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::input::touch_controls::TouchControlType;
|
||||
use crate::player::Player;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::scripting::tsc::text_script::ScriptMode;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::scripting::tsc::text_script::ScriptMode;
|
||||
|
||||
pub struct StageSelect {
|
||||
pub current_teleport_slot: u8,
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
use crate::common::{Color, Rect};
|
||||
use crate::engine_constants::AnimatedFace;
|
||||
use crate::entity::GameEntity;
|
||||
use crate::frame::Frame;
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::graphics;
|
||||
use crate::graphics::draw_rect;
|
||||
use crate::scripting::tsc::text_script::{ConfirmSelection, TextScriptExecutionState, TextScriptLine};
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::framework::graphics;
|
||||
use crate::game::frame::Frame;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::game::scripting::tsc::text_script::{ConfirmSelection, TextScriptExecutionState, TextScriptLine};
|
||||
|
||||
pub struct TextBoxes {
|
||||
pub slide_in: u8,
|
||||
|
@ -284,7 +283,7 @@ impl GameEntity<()> for TextBoxes {
|
|||
};
|
||||
x += left_pos + text_offset + 14.0;
|
||||
|
||||
draw_rect(
|
||||
graphics::draw_rect(
|
||||
ctx,
|
||||
Rect::new_size(
|
||||
(x * state.scale) as isize,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use crate::common::Rect;
|
||||
use crate::frame::Frame;
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::shared_game_state::{SharedGameState, TileSize};
|
||||
use crate::stage::{BackgroundType, Stage, StageTexturePaths};
|
||||
use crate::game::frame::Frame;
|
||||
use crate::game::shared_game_state::{SharedGameState, TileSize};
|
||||
use crate::game::stage::{BackgroundType, Stage, StageTexturePaths};
|
||||
|
||||
pub struct Tilemap {
|
||||
tick: u32,
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
use std::cell::RefCell;
|
||||
|
||||
use crate::common::{Color, Rect};
|
||||
use crate::frame::Frame;
|
||||
use crate::framework::backend::{BackendShader, SpriteBatchCommand, VertexData};
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::framework::graphics;
|
||||
use crate::graphics::BlendMode;
|
||||
use crate::map::{WaterParamEntry, WaterParams, WaterRegionType};
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::physics::PhysicalEntity;
|
||||
use crate::player::Player;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::stage::{BackgroundType, Stage};
|
||||
use crate::framework::graphics::BlendMode;
|
||||
use crate::game::frame::Frame;
|
||||
use crate::game::map::{WaterParamEntry, WaterParams, WaterRegionType};
|
||||
use crate::game::physics::PhysicalEntity;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::game::stage::{BackgroundType, Stage};
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::player::Player;
|
||||
|
||||
const TENSION: f32 = 0.03;
|
||||
const DAMPENING: f32 = 0.01;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use crate::common::{interpolate_fix9_scale, Direction, Rect};
|
||||
use crate::common::{Direction, interpolate_fix9_scale, Rect};
|
||||
use crate::entity::GameEntity;
|
||||
use crate::frame::Frame;
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::player::{Player, TargetPlayer};
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::weapon::bullet::{Bullet, BulletManager};
|
||||
use crate::game::frame::Frame;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::game::player::{Player, TargetPlayer};
|
||||
use crate::game::weapon::bullet::{Bullet, BulletManager};
|
||||
|
||||
pub struct WhimsicalStar {
|
||||
pub star: [Star; 3],
|
||||
|
|
|
@ -4,12 +4,12 @@ use std::rc::Rc;
|
|||
|
||||
use imgui::{Image, MouseButton, Window, WindowFlags};
|
||||
|
||||
use crate::{Context, GameResult, graphics, I_MAG, SharedGameState};
|
||||
use crate::common::{Color, Rect};
|
||||
use crate::components::background::Background;
|
||||
use crate::components::tilemap::{TileLayer, Tilemap};
|
||||
use crate::frame::Frame;
|
||||
use crate::stage::{Stage, StageTexturePaths};
|
||||
use crate::{graphics, Context, GameResult, SharedGameState, I_MAG};
|
||||
use crate::game::frame::Frame;
|
||||
use crate::game::stage::{Stage, StageTexturePaths};
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||
pub enum CurrentTool {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::collections::HashMap;
|
||||
use std::io::{BufRead, BufReader, Cursor, Read};
|
||||
|
||||
use byteorder::{ReadBytesExt, LE};
|
||||
use byteorder::{LE, ReadBytesExt};
|
||||
use case_insensitive_hashmap::CaseInsensitiveHashMap;
|
||||
use xmltree::Element;
|
||||
|
||||
|
@ -12,11 +12,11 @@ use crate::framework::context::Context;
|
|||
use crate::framework::error::GameResult;
|
||||
use crate::framework::filesystem;
|
||||
use crate::framework::gamepad::{Axis, Button};
|
||||
use crate::game::settings::Settings;
|
||||
use crate::game::shared_game_state::{FontData, Season};
|
||||
use crate::i18n::Locale;
|
||||
use crate::player::ControlMode;
|
||||
use crate::scripting::tsc::text_script::TextScriptEncoding;
|
||||
use crate::settings::Settings;
|
||||
use crate::shared_game_state::{FontData, Season};
|
||||
use crate::game::player::ControlMode;
|
||||
use crate::game::scripting::tsc::text_script::TextScriptEncoding;
|
||||
use crate::sound::pixtone::{Channel, Envelope, PixToneParameters, Waveform};
|
||||
use crate::sound::SoundManager;
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@ use std::fmt::Debug;
|
|||
use std::marker::PhantomData;
|
||||
use std::ops::Index;
|
||||
|
||||
use serde::de::{Error, SeqAccess, Visitor};
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use serde::de::{Error, SeqAccess, Visitor};
|
||||
|
||||
use crate::common::Rect;
|
||||
use crate::macros::fmt::Formatter;
|
||||
|
@ -14,8 +14,8 @@ pub struct SafeNPCRect<const T: usize>(pub [Rect<u16>; T]);
|
|||
impl<const T: usize> Serialize for SafeNPCRect<T> {
|
||||
#[inline]
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
self.0.serialize(serializer)
|
||||
}
|
||||
|
@ -31,8 +31,8 @@ impl<'de, const T: usize> Visitor<'de> for SafeNPCRectArrayVisitor<T> {
|
|||
}
|
||||
|
||||
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||
where
|
||||
A: SeqAccess<'de>,
|
||||
where
|
||||
A: SeqAccess<'de>,
|
||||
{
|
||||
let mut rects = [Rect::default(); T];
|
||||
for (i, rect) in rects.iter_mut().enumerate() {
|
||||
|
@ -46,8 +46,8 @@ impl<'de, const T: usize> Visitor<'de> for SafeNPCRectArrayVisitor<T> {
|
|||
|
||||
impl<'de, const T: usize> Deserialize<'de> for SafeNPCRect<T> {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_seq(SafeNPCRectArrayVisitor(PhantomData)).map(SafeNPCRect)
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use crate::common::interpolate_fix9_scale;
|
||||
use crate::frame::Frame;
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::game::frame::Frame;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
|
||||
pub trait GameEntity<C> {
|
||||
fn tick(&mut self, state: &mut SharedGameState, custom: C) -> GameResult;
|
||||
|
|
|
@ -1,127 +0,0 @@
|
|||
use std::ops::Range;
|
||||
|
||||
use pelite::{
|
||||
image::RT_BITMAP,
|
||||
pe32::{headers::SectionHeaders, Pe, PeFile},
|
||||
resources::{Directory, Entry, Name, Resources},
|
||||
};
|
||||
|
||||
use crate::framework::error::{GameError::ParseError, GameResult};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DataFile {
|
||||
pub bytes: Vec<u8>,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl DataFile {
|
||||
pub fn from(name: String, bytes: Vec<u8>) -> Self {
|
||||
Self { name, bytes }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ExeResourceDirectory {
|
||||
pub name: String,
|
||||
pub data_files: Vec<DataFile>,
|
||||
}
|
||||
|
||||
impl ExeResourceDirectory {
|
||||
pub fn new(name: String) -> Self {
|
||||
Self { name, data_files: Vec::new() }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ExeParser<'a> {
|
||||
pub resources: Resources<'a>,
|
||||
pub section_headers: Box<&'a SectionHeaders>,
|
||||
}
|
||||
|
||||
impl<'a> ExeParser<'a> {
|
||||
pub fn from(file: &'a Vec<u8>) -> GameResult<Self> {
|
||||
let pe = PeFile::from_bytes(file);
|
||||
|
||||
return match pe {
|
||||
Ok(pe) => {
|
||||
let resources = pe.resources();
|
||||
|
||||
if resources.is_err() {
|
||||
return Err(ParseError("Failed to parse resources.".to_string()));
|
||||
}
|
||||
|
||||
let section_headers = pe.section_headers();
|
||||
|
||||
Ok(Self { resources: resources.unwrap(), section_headers: Box::new(section_headers) })
|
||||
}
|
||||
Err(_) => Err(ParseError("Failed to parse PE file".to_string())),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn get_resource_dir(&self, name: String) -> GameResult<ExeResourceDirectory> {
|
||||
let mut dir_data = ExeResourceDirectory::new(name.to_owned());
|
||||
|
||||
let path = format!("/{}", name.to_owned());
|
||||
let dir = self.resources.find_dir(&path);
|
||||
|
||||
return match dir {
|
||||
Ok(dir) => {
|
||||
self.read_dir(dir, &mut dir_data, "unknown".to_string());
|
||||
Ok(dir_data)
|
||||
}
|
||||
Err(_) => return Err(ParseError("Failed to find resource directory.".to_string())),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn get_bitmap_dir(&self) -> GameResult<ExeResourceDirectory> {
|
||||
let mut dir_data = ExeResourceDirectory::new("Bitmap".to_string());
|
||||
|
||||
let root = self.resources.root().unwrap();
|
||||
let dir = root.get_dir(Name::Id(RT_BITMAP.into()));
|
||||
|
||||
return match dir {
|
||||
Ok(dir) => {
|
||||
self.read_dir(dir, &mut dir_data, "unknown".to_string());
|
||||
Ok(dir_data)
|
||||
}
|
||||
Err(_) => return Err(ParseError("Failed to open bitmap directory.".to_string())),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn get_named_section_byte_range(&self, name: String) -> GameResult<Option<Range<u32>>> {
|
||||
let section_header = self.section_headers.by_name(name.as_bytes());
|
||||
return match section_header {
|
||||
Some(section_header) => Ok(Some(section_header.file_range())),
|
||||
None => Ok(None),
|
||||
};
|
||||
}
|
||||
|
||||
fn read_dir(&self, directory: Directory, dir_data: &mut ExeResourceDirectory, last_dir_name: String) {
|
||||
for dir in directory.entries() {
|
||||
let raw_entry = dir.entry();
|
||||
|
||||
if raw_entry.is_err() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Entry::Directory(entry) = raw_entry.unwrap() {
|
||||
let dir_name = dir.name();
|
||||
let name = match dir_name {
|
||||
Ok(name) => name.to_string(),
|
||||
Err(_) => last_dir_name.to_owned(),
|
||||
};
|
||||
self.read_dir(entry, dir_data, name);
|
||||
}
|
||||
|
||||
if let Entry::DataEntry(entry) = raw_entry.unwrap() {
|
||||
let entry_bytes = entry.bytes();
|
||||
if entry_bytes.is_err() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let bytes = entry_bytes.unwrap();
|
||||
let data_file = DataFile::from(last_dir_name.to_owned(), bytes.to_vec());
|
||||
dir_data.data_files.push(data_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
use imgui::DrawData;
|
||||
use std::any::Any;
|
||||
|
||||
use imgui::DrawData;
|
||||
|
||||
use crate::common::{Color, Rect};
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::framework::graphics::BlendMode;
|
||||
use crate::graphics::VSyncMode;
|
||||
use crate::Game;
|
||||
use crate::framework::graphics::{BlendMode, VSyncMode};
|
||||
use crate::game::Game;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
|
@ -102,14 +102,14 @@ pub fn init_backend(headless: bool, size_hint: (u16, u16)) -> GameResult<Box<dyn
|
|||
}
|
||||
|
||||
#[cfg(all(feature = "backend-glutin"))]
|
||||
{
|
||||
return crate::framework::backend_glutin::GlutinBackend::new();
|
||||
}
|
||||
{
|
||||
return crate::framework::backend_glutin::GlutinBackend::new();
|
||||
}
|
||||
|
||||
#[cfg(feature = "backend-sdl")]
|
||||
{
|
||||
return crate::framework::backend_sdl2::SDL2Backend::new(size_hint);
|
||||
}
|
||||
{
|
||||
return crate::framework::backend_sdl2::SDL2Backend::new(size_hint);
|
||||
}
|
||||
|
||||
log::warn!("No backend compiled in, using null backend instead.");
|
||||
crate::framework::backend_null::NullBackend::new()
|
||||
|
|
|
@ -4,12 +4,13 @@ use std::mem;
|
|||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
use glutin::{Api, ContextBuilder, GlProfile, GlRequest, PossiblyCurrent, WindowedContext};
|
||||
use glutin::event::{ElementState, Event, TouchPhase, VirtualKeyCode, WindowEvent};
|
||||
use glutin::event_loop::{ControlFlow, EventLoop};
|
||||
use glutin::window::WindowBuilder;
|
||||
use glutin::{Api, ContextBuilder, GlProfile, GlRequest, PossiblyCurrent, WindowedContext};
|
||||
use imgui::{DrawCmdParams, DrawData, DrawIdx, DrawVert};
|
||||
|
||||
use crate::{Game, GAME_SUSPENDED};
|
||||
use crate::common::Rect;
|
||||
use crate::framework::backend::{Backend, BackendEventLoop, BackendRenderer, BackendTexture, SpriteBatchCommand};
|
||||
use crate::framework::context::Context;
|
||||
|
@ -18,7 +19,6 @@ use crate::framework::gl;
|
|||
use crate::framework::keyboard::ScanCode;
|
||||
use crate::framework::render_opengl::{GLContext, OpenGLRenderer};
|
||||
use crate::input::touch_controls::TouchPoint;
|
||||
use crate::{Game, GAME_SUSPENDED};
|
||||
|
||||
pub struct GlutinBackend;
|
||||
|
||||
|
@ -58,7 +58,7 @@ impl GlutinEventLoop {
|
|||
let windowed_context = ContextBuilder::new();
|
||||
let windowed_context = windowed_context.with_gl(GlRequest::Specific(Api::OpenGl, (3, 0)));
|
||||
#[cfg(target_os = "android")]
|
||||
let windowed_context = windowed_context.with_gl(GlRequest::Specific(Api::OpenGlEs, (2, 0)));
|
||||
let windowed_context = windowed_context.with_gl(GlRequest::Specific(Api::OpenGlEs, (2, 0)));
|
||||
|
||||
let windowed_context = windowed_context
|
||||
.with_gl_profile(GlProfile::Core)
|
||||
|
@ -67,10 +67,10 @@ impl GlutinEventLoop {
|
|||
.with_vsync(true);
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
use glutin::platform::windows::WindowBuilderExtWindows;
|
||||
window = window.with_drag_and_drop(false);
|
||||
}
|
||||
{
|
||||
use glutin::platform::windows::WindowBuilderExtWindows;
|
||||
window = window.with_drag_and_drop(false);
|
||||
}
|
||||
|
||||
window = window.with_title("doukutsu-rs");
|
||||
|
||||
|
@ -159,10 +159,10 @@ impl BackendEventLoop for GlutinEventLoop {
|
|||
|
||||
match event {
|
||||
Event::WindowEvent { event: WindowEvent::CloseRequested, window_id }
|
||||
if window_id == window.window().id() =>
|
||||
{
|
||||
state_ref.shutdown();
|
||||
}
|
||||
if window_id == window.window().id() =>
|
||||
{
|
||||
state_ref.shutdown();
|
||||
}
|
||||
Event::Resumed => {
|
||||
{
|
||||
let mut mutex = GAME_SUSPENDED.lock().unwrap();
|
||||
|
@ -187,74 +187,74 @@ impl BackendEventLoop for GlutinEventLoop {
|
|||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
unsafe {
|
||||
unsafe {
|
||||
window.surface_destroyed();
|
||||
}
|
||||
|
||||
state_ref.sound_manager.pause();
|
||||
}
|
||||
Event::WindowEvent { event: WindowEvent::Resized(size), window_id }
|
||||
if window_id == window.window().id() =>
|
||||
{
|
||||
if let Some(renderer) = &ctx.renderer {
|
||||
if let Ok(imgui) = renderer.imgui() {
|
||||
imgui.io_mut().display_size = [size.width as f32, size.height as f32];
|
||||
if window_id == window.window().id() =>
|
||||
{
|
||||
if let Some(renderer) = &ctx.renderer {
|
||||
if let Ok(imgui) = renderer.imgui() {
|
||||
imgui.io_mut().display_size = [size.width as f32, size.height as f32];
|
||||
}
|
||||
|
||||
ctx.real_screen_size = (size.width, size.height);
|
||||
ctx.screen_size = get_scaled_size(size.width.max(1), size.height.max(1));
|
||||
state_ref.handle_resize(ctx).unwrap();
|
||||
}
|
||||
|
||||
ctx.real_screen_size = (size.width, size.height);
|
||||
ctx.screen_size = get_scaled_size(size.width.max(1), size.height.max(1));
|
||||
state_ref.handle_resize(ctx).unwrap();
|
||||
}
|
||||
}
|
||||
Event::WindowEvent { event: WindowEvent::Touch(touch), window_id }
|
||||
if window_id == window.window().id() =>
|
||||
{
|
||||
let mut controls = &mut state_ref.touch_controls;
|
||||
let scale = state_ref.scale as f64;
|
||||
let loc_x = (touch.location.x * ctx.screen_size.0 as f64 / ctx.real_screen_size.0 as f64) / scale;
|
||||
let loc_y = (touch.location.y * ctx.screen_size.1 as f64 / ctx.real_screen_size.1 as f64) / scale;
|
||||
if window_id == window.window().id() =>
|
||||
{
|
||||
let mut controls = &mut state_ref.touch_controls;
|
||||
let scale = state_ref.scale as f64;
|
||||
let loc_x = (touch.location.x * ctx.screen_size.0 as f64 / ctx.real_screen_size.0 as f64) / scale;
|
||||
let loc_y = (touch.location.y * ctx.screen_size.1 as f64 / ctx.real_screen_size.1 as f64) / scale;
|
||||
|
||||
match touch.phase {
|
||||
TouchPhase::Started | TouchPhase::Moved => {
|
||||
if let Some(point) = controls.points.iter_mut().find(|p| p.id == touch.id) {
|
||||
point.last_position = point.position;
|
||||
point.position = (loc_x, loc_y);
|
||||
} else {
|
||||
controls.touch_id_counter = controls.touch_id_counter.wrapping_add(1);
|
||||
match touch.phase {
|
||||
TouchPhase::Started | TouchPhase::Moved => {
|
||||
if let Some(point) = controls.points.iter_mut().find(|p| p.id == touch.id) {
|
||||
point.last_position = point.position;
|
||||
point.position = (loc_x, loc_y);
|
||||
} else {
|
||||
controls.touch_id_counter = controls.touch_id_counter.wrapping_add(1);
|
||||
|
||||
let point = TouchPoint {
|
||||
id: touch.id,
|
||||
touch_id: controls.touch_id_counter,
|
||||
position: (loc_x, loc_y),
|
||||
last_position: (0.0, 0.0),
|
||||
};
|
||||
controls.points.push(point);
|
||||
let point = TouchPoint {
|
||||
id: touch.id,
|
||||
touch_id: controls.touch_id_counter,
|
||||
position: (loc_x, loc_y),
|
||||
last_position: (0.0, 0.0),
|
||||
};
|
||||
controls.points.push(point);
|
||||
|
||||
if touch.phase == TouchPhase::Started {
|
||||
controls.clicks.push(point);
|
||||
if touch.phase == TouchPhase::Started {
|
||||
controls.clicks.push(point);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
TouchPhase::Ended | TouchPhase::Cancelled => {
|
||||
controls.points.retain(|p| p.id != touch.id);
|
||||
controls.clicks.retain(|p| p.id != touch.id);
|
||||
TouchPhase::Ended | TouchPhase::Cancelled => {
|
||||
controls.points.retain(|p| p.id != touch.id);
|
||||
controls.clicks.retain(|p| p.id != touch.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Event::WindowEvent { event: WindowEvent::KeyboardInput { input, .. }, window_id }
|
||||
if window_id == window.window().id() =>
|
||||
{
|
||||
if let Some(keycode) = input.virtual_keycode {
|
||||
if let Some(drs_scan) = conv_keycode(keycode) {
|
||||
let key_state = match input.state {
|
||||
ElementState::Pressed => true,
|
||||
ElementState::Released => false,
|
||||
};
|
||||
if window_id == window.window().id() =>
|
||||
{
|
||||
if let Some(keycode) = input.virtual_keycode {
|
||||
if let Some(drs_scan) = conv_keycode(keycode) {
|
||||
let key_state = match input.state {
|
||||
ElementState::Pressed => true,
|
||||
ElementState::Released => false,
|
||||
};
|
||||
|
||||
ctx.keyboard_context.set_key(drs_scan, key_state);
|
||||
ctx.keyboard_context.set_key(drs_scan, key_state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Event::RedrawRequested(id) if id == window.window().id() => {
|
||||
{
|
||||
let mutex = GAME_SUSPENDED.lock().unwrap();
|
||||
|
@ -264,16 +264,16 @@ impl BackendEventLoop for GlutinEventLoop {
|
|||
}
|
||||
|
||||
#[cfg(not(target_os = "android"))]
|
||||
{
|
||||
if let Err(err) = game.draw(ctx) {
|
||||
log::error!("Failed to draw frame: {}", err);
|
||||
{
|
||||
if let Err(err) = game.draw(ctx) {
|
||||
log::error!("Failed to draw frame: {}", err);
|
||||
}
|
||||
|
||||
window.window().request_redraw();
|
||||
}
|
||||
|
||||
window.window().request_redraw();
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
request_android_redraw();
|
||||
request_android_redraw();
|
||||
}
|
||||
Event::MainEventsCleared => {
|
||||
if state_ref.shutdown {
|
||||
|
@ -292,20 +292,20 @@ impl BackendEventLoop for GlutinEventLoop {
|
|||
game.update(ctx).unwrap();
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
{
|
||||
match get_insets() {
|
||||
Ok(insets) => {
|
||||
ctx.screen_insets = insets;
|
||||
{
|
||||
match get_insets() {
|
||||
Ok(insets) => {
|
||||
ctx.screen_insets = insets;
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Failed to update insets: {}", e);
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Failed to update insets: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(err) = game.draw(ctx) {
|
||||
log::error!("Failed to draw frame: {}", err);
|
||||
if let Err(err) = game.draw(ctx) {
|
||||
log::error!("Failed to draw frame: {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if state_ref.next_scene.is_some() {
|
||||
mem::swap(&mut game.scene, &mut state_ref.next_scene);
|
||||
|
@ -320,7 +320,7 @@ impl BackendEventLoop for GlutinEventLoop {
|
|||
});
|
||||
}
|
||||
|
||||
fn new_renderer(&self, _ctx: *mut Context) -> GameResult<Box<dyn BackendRenderer>> {
|
||||
fn new_renderer(&self, ctx: *mut Context) -> GameResult<Box<dyn BackendRenderer>> {
|
||||
let mut imgui = imgui::Context::create();
|
||||
imgui.io_mut().display_size = [640.0, 480.0];
|
||||
|
||||
|
@ -359,7 +359,7 @@ impl BackendEventLoop for GlutinEventLoop {
|
|||
*user_data = Rc::into_raw(refs) as *mut c_void;
|
||||
}
|
||||
|
||||
let gl_context = GLContext { gles2_mode: true, get_proc_address, swap_buffers, user_data };
|
||||
let gl_context = GLContext { gles2_mode: true, is_sdl: false, get_proc_address, swap_buffers, user_data, ctx };
|
||||
|
||||
Ok(Box::new(OpenGLRenderer::new(gl_context, UnsafeCell::new(imgui))))
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ use crate::framework::backend::{
|
|||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::framework::graphics::BlendMode;
|
||||
use crate::Game;
|
||||
use crate::game::Game;
|
||||
|
||||
pub struct NullBackend;
|
||||
|
||||
|
|
|
@ -7,9 +7,10 @@ use std::ptr::{null, null_mut};
|
|||
use std::rc::Rc;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use imgui::{ConfigFlags, DrawCmd, DrawData, DrawIdx, DrawVert, Key, MouseCursor, TextureId, Ui};
|
||||
use imgui::internal::RawWrapper;
|
||||
use imgui::sys::{ImGuiKey_Backspace, ImGuiKey_Delete, ImGuiKey_Enter};
|
||||
use imgui::{ConfigFlags, DrawCmd, DrawData, DrawIdx, DrawVert, Key, MouseCursor, TextureId, Ui};
|
||||
use sdl2::{controller, EventPump, GameControllerSubsystem, keyboard, pixels, Sdl, VideoSubsystem};
|
||||
use sdl2::controller::GameController;
|
||||
use sdl2::event::{Event, WindowEvent};
|
||||
use sdl2::keyboard::Scancode;
|
||||
|
@ -19,7 +20,6 @@ use sdl2::render::{Texture, TextureCreator, TextureQuery, WindowCanvas};
|
|||
use sdl2::video::GLProfile;
|
||||
use sdl2::video::Window;
|
||||
use sdl2::video::WindowContext;
|
||||
use sdl2::{controller, keyboard, pixels, EventPump, GameControllerSubsystem, Sdl, VideoSubsystem};
|
||||
|
||||
use crate::common::{Color, Rect};
|
||||
use crate::framework::backend::{
|
||||
|
@ -27,18 +27,15 @@ use crate::framework::backend::{
|
|||
};
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::{GameError, GameResult};
|
||||
use crate::framework::filesystem;
|
||||
use crate::framework::gamepad::{Axis, Button};
|
||||
use crate::framework::graphics::BlendMode;
|
||||
use crate::framework::keyboard::ScanCode;
|
||||
use crate::framework::render_opengl::{GLContext, OpenGLRenderer};
|
||||
use crate::framework::ui::init_imgui;
|
||||
use crate::graphics::VSyncMode;
|
||||
use crate::shared_game_state::WindowMode;
|
||||
use crate::Game;
|
||||
use crate::GameError::RenderError;
|
||||
use crate::GAME_SUSPENDED;
|
||||
|
||||
use super::filesystem;
|
||||
use crate::game::Game;
|
||||
use crate::game::GAME_SUSPENDED;
|
||||
use crate::game::shared_game_state::WindowMode;
|
||||
|
||||
pub struct SDL2Backend {
|
||||
context: Sdl,
|
||||
|
@ -170,7 +167,7 @@ impl SDL2EventLoop {
|
|||
window.resizable();
|
||||
|
||||
#[cfg(feature = "render-opengl")]
|
||||
window.opengl();
|
||||
window.opengl();
|
||||
|
||||
let window = window.build().map_err(|e| GameError::WindowError(e.to_string()))?;
|
||||
let opengl_available = if let Ok(v) = std::env::var("CAVESTORY_NO_OPENGL") { v != "1" } else { true };
|
||||
|
@ -212,7 +209,7 @@ impl BackendEventLoop for SDL2EventLoop {
|
|||
|
||||
loop {
|
||||
#[cfg(target_os = "macos")]
|
||||
unsafe {
|
||||
unsafe {
|
||||
use objc::*;
|
||||
|
||||
// no UB: fields are initialized by SDL_GetWindowWMInfo
|
||||
|
@ -409,19 +406,19 @@ impl BackendEventLoop for SDL2EventLoop {
|
|||
|
||||
fn new_renderer(&self, ctx: *mut Context) -> GameResult<Box<dyn BackendRenderer>> {
|
||||
#[cfg(feature = "render-opengl")]
|
||||
{
|
||||
let mut refs = self.refs.borrow_mut();
|
||||
match refs.window.window().gl_create_context() {
|
||||
Ok(gl_ctx) => {
|
||||
refs.window.window().gl_make_current(&gl_ctx).map_err(|e| GameError::RenderError(e.to_string()))?;
|
||||
refs.gl_context = Some(gl_ctx);
|
||||
}
|
||||
Err(err) => {
|
||||
*self.opengl_available.borrow_mut() = false;
|
||||
log::error!("Failed to initialize OpenGL context, falling back to SDL2 renderer: {}", err);
|
||||
{
|
||||
let mut refs = self.refs.borrow_mut();
|
||||
match refs.window.window().gl_create_context() {
|
||||
Ok(gl_ctx) => {
|
||||
refs.window.window().gl_make_current(&gl_ctx).map_err(|e| GameError::RenderError(e.to_string()))?;
|
||||
refs.gl_context = Some(gl_ctx);
|
||||
}
|
||||
Err(err) => {
|
||||
*self.opengl_available.borrow_mut() = false;
|
||||
log::error!("Failed to initialize OpenGL context, falling back to SDL2 renderer: {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "render-opengl")]
|
||||
if *self.opengl_available.borrow() {
|
||||
|
@ -671,7 +668,7 @@ impl BackendRenderer for SDL2Renderer {
|
|||
let sdl2_texture = texture
|
||||
.as_any()
|
||||
.downcast_ref::<SDL2Texture>()
|
||||
.ok_or(RenderError("This texture was not created by SDL2 backend.".to_string()))?;
|
||||
.ok_or(GameError::RenderError("This texture was not created by SDL2 backend.".to_string()))?;
|
||||
|
||||
unsafe {
|
||||
if let Some(target) = &sdl2_texture.texture {
|
||||
|
@ -866,7 +863,7 @@ impl BackendRenderer for SDL2Renderer {
|
|||
texture
|
||||
.as_any()
|
||||
.downcast_ref::<SDL2Texture>()
|
||||
.ok_or(RenderError("This texture was not created by SDL2 backend.".to_string()))?
|
||||
.ok_or(GameError::RenderError("This texture was not created by SDL2 backend.".to_string()))?
|
||||
.texture
|
||||
.as_ref()
|
||||
.map_or(null_mut(), |t| t.raw())
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use crate::framework::backend::{init_backend, BackendRenderer};
|
||||
use crate::framework::backend::{BackendRenderer, init_backend};
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::framework::filesystem::Filesystem;
|
||||
use crate::framework::gamepad::GamepadContext;
|
||||
use crate::framework::graphics::VSyncMode;
|
||||
use crate::framework::keyboard::KeyboardContext;
|
||||
use crate::graphics::VSyncMode;
|
||||
use crate::Game;
|
||||
use crate::game::Game;
|
||||
|
||||
pub struct Context {
|
||||
pub headless: bool,
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::string::FromUtf8Error;
|
||||
use std::sync::mpsc::SendError;
|
||||
use std::sync::{Arc, PoisonError};
|
||||
use std::sync::mpsc::SendError;
|
||||
|
||||
/// An enum containing all kinds of game framework errors.
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
|
@ -160,7 +160,7 @@ impl Filesystem {
|
|||
pub(crate) fn user_read_dir<P: AsRef<path::Path>>(
|
||||
&self,
|
||||
path: P,
|
||||
) -> GameResult<Box<dyn Iterator<Item = path::PathBuf>>> {
|
||||
) -> GameResult<Box<dyn Iterator<Item=path::PathBuf>>> {
|
||||
let itr = self
|
||||
.user_vfs
|
||||
.read_dir(path.as_ref())?
|
||||
|
@ -175,7 +175,7 @@ impl Filesystem {
|
|||
pub(crate) fn read_dir<P: AsRef<path::Path>>(
|
||||
&self,
|
||||
path: P,
|
||||
) -> GameResult<Box<dyn Iterator<Item = path::PathBuf>>> {
|
||||
) -> GameResult<Box<dyn Iterator<Item=path::PathBuf>>> {
|
||||
let itr = self
|
||||
.vfs
|
||||
.read_dir(path.as_ref())?
|
||||
|
@ -303,7 +303,7 @@ pub fn user_is_dir<P: AsRef<path::Path>>(ctx: &Context, path: P) -> bool {
|
|||
pub fn user_read_dir<P: AsRef<path::Path>>(
|
||||
ctx: &Context,
|
||||
path: P,
|
||||
) -> GameResult<Box<dyn Iterator<Item = path::PathBuf>>> {
|
||||
) -> GameResult<Box<dyn Iterator<Item=path::PathBuf>>> {
|
||||
ctx.filesystem.user_read_dir(path)
|
||||
}
|
||||
|
||||
|
@ -339,7 +339,7 @@ pub fn is_dir<P: AsRef<path::Path>>(ctx: &Context, path: P) -> bool {
|
|||
/// in no particular order.
|
||||
///
|
||||
/// Lists the base directory if an empty path is given.
|
||||
pub fn read_dir<P: AsRef<path::Path>>(ctx: &Context, path: P) -> GameResult<Box<dyn Iterator<Item = path::PathBuf>>> {
|
||||
pub fn read_dir<P: AsRef<path::Path>>(ctx: &Context, path: P) -> GameResult<Box<dyn Iterator<Item=path::PathBuf>>> {
|
||||
ctx.filesystem.read_dir(path)
|
||||
}
|
||||
|
||||
|
@ -347,7 +347,7 @@ pub fn read_dir_find<P: AsRef<path::Path>>(
|
|||
ctx: &Context,
|
||||
roots: &Vec<String>,
|
||||
path: P,
|
||||
) -> GameResult<Box<dyn Iterator<Item = path::PathBuf>>> {
|
||||
) -> GameResult<Box<dyn Iterator<Item=path::PathBuf>>> {
|
||||
let mut files = Vec::new();
|
||||
|
||||
for root in roots {
|
||||
|
|
|
@ -3,10 +3,9 @@ use std::collections::{HashMap, HashSet};
|
|||
use sdl2::controller::GameController;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::{common::Rect, engine_constants::EngineConstants, framework::context::Context};
|
||||
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
|
||||
const QUAKE_RUMBLE_LOW_FREQ: u16 = 0x3000;
|
||||
const QUAKE_RUMBLE_HI_FREQ: u16 = 0;
|
||||
|
|
4698
src/framework/gl.rs
|
@ -178,7 +178,7 @@ pub fn prepare_draw(ctx: &mut Context) -> GameResult {
|
|||
|
||||
pub fn supports_vertex_draw(ctx: &Context) -> GameResult<bool> {
|
||||
if let Some(renderer) = ctx.renderer.as_ref() {
|
||||
return Ok(renderer.supports_vertex_draw())
|
||||
return Ok(renderer.supports_vertex_draw());
|
||||
}
|
||||
|
||||
Err(GameError::RenderError("Rendering backend hasn't been initialized yet.".to_string()))
|
||||
|
|
|
@ -17,9 +17,9 @@ use crate::framework::error::GameError::RenderError;
|
|||
use crate::framework::error::GameResult;
|
||||
use crate::framework::gl;
|
||||
use crate::framework::gl::types::*;
|
||||
use crate::framework::graphics::BlendMode;
|
||||
use crate::framework::graphics::{BlendMode, VSyncMode};
|
||||
use crate::framework::util::{field_offset, return_param};
|
||||
use crate::graphics::VSyncMode;
|
||||
use crate::game::GAME_SUSPENDED;
|
||||
|
||||
pub struct GLContext {
|
||||
pub gles2_mode: bool,
|
||||
|
@ -774,7 +774,7 @@ impl BackendRenderer for OpenGLRenderer {
|
|||
|
||||
fn present(&mut self) -> GameResult {
|
||||
{
|
||||
let mutex = crate::GAME_SUSPENDED.lock().unwrap();
|
||||
let mutex = GAME_SUSPENDED.lock().unwrap();
|
||||
if *mutex {
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -826,7 +826,7 @@ impl BackendRenderer for OpenGLRenderer {
|
|||
}
|
||||
|
||||
#[cfg(feature = "backend-sdl")]
|
||||
unsafe {
|
||||
unsafe {
|
||||
let ctx = &mut *self.refs.ctx;
|
||||
|
||||
match mode {
|
||||
|
|
|
@ -5,11 +5,10 @@ use imgui::sys::*;
|
|||
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::framework::graphics::{imgui_context, render_imgui};
|
||||
use crate::graphics::prepare_imgui;
|
||||
use crate::framework::graphics::{imgui_context, prepare_imgui, render_imgui};
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::live_debugger::LiveDebugger;
|
||||
use crate::scene::Scene;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
|
||||
pub struct UI {
|
||||
pub components: Components,
|
||||
|
@ -23,11 +22,7 @@ pub struct Components {
|
|||
pub fn init_imgui() -> GameResult<imgui::Context> {
|
||||
let mut imgui = imgui::Context::create();
|
||||
imgui.set_ini_filename(None);
|
||||
imgui.fonts().add_font(&[
|
||||
FontSource::DefaultFontData {
|
||||
config: Some(FontConfig::default()),
|
||||
},
|
||||
]);
|
||||
imgui.fonts().add_font(&[FontSource::DefaultFontData { config: Some(FontConfig::default()) }]);
|
||||
|
||||
imgui.style_mut().window_padding = [4.0, 6.0];
|
||||
imgui.style_mut().frame_padding = [8.0, 6.0];
|
||||
|
@ -109,16 +104,11 @@ pub fn init_imgui() -> GameResult<imgui::Context> {
|
|||
|
||||
impl UI {
|
||||
pub fn new(_ctx: &mut Context) -> GameResult<Self> {
|
||||
Ok(Self {
|
||||
components: Components {
|
||||
live_debugger: LiveDebugger::new(),
|
||||
},
|
||||
last_frame: Instant::now(),
|
||||
})
|
||||
Ok(Self { components: Components { live_debugger: LiveDebugger::new() }, last_frame: Instant::now() })
|
||||
}
|
||||
|
||||
pub fn draw(&mut self, state: &mut SharedGameState, ctx: &mut Context, scene: &mut Box<dyn Scene>) -> GameResult {
|
||||
let ctx2 = unsafe { &mut *(ctx as *const Context as *mut Context)};
|
||||
let ctx2 = unsafe { &mut *(ctx as *const Context as *mut Context) };
|
||||
let imgui = imgui_context(ctx)?;
|
||||
let io = imgui.io_mut();
|
||||
let now = Instant::now();
|
||||
|
|
|
@ -128,7 +128,7 @@ pub trait VFS: Debug {
|
|||
fn metadata(&self, path: &Path) -> GameResult<Box<dyn VMetadata>>;
|
||||
|
||||
/// Retrieve all file and directory entries in the given directory.
|
||||
fn read_dir(&self, path: &Path) -> GameResult<Box<dyn Iterator<Item = GameResult<PathBuf>>>>;
|
||||
fn read_dir(&self, path: &Path) -> GameResult<Box<dyn Iterator<Item=GameResult<PathBuf>>>>;
|
||||
|
||||
/// Retrieve the actual location of the VFS root, if available.
|
||||
fn to_path_buf(&self) -> Option<PathBuf>;
|
||||
|
@ -376,7 +376,7 @@ impl VFS for PhysicalFS {
|
|||
}
|
||||
|
||||
/// Retrieve the path entries in this path
|
||||
fn read_dir(&self, path: &Path) -> GameResult<Box<dyn Iterator<Item = GameResult<PathBuf>>>> {
|
||||
fn read_dir(&self, path: &Path) -> GameResult<Box<dyn Iterator<Item=GameResult<PathBuf>>>> {
|
||||
self.create_root()?;
|
||||
let p = self.to_absolute(path)?;
|
||||
// This is inconvenient because path() returns the full absolute
|
||||
|
@ -511,7 +511,7 @@ impl VFS for OverlayFS {
|
|||
}
|
||||
|
||||
/// Retrieve the path entries in this path
|
||||
fn read_dir(&self, path: &Path) -> GameResult<Box<dyn Iterator<Item = GameResult<PathBuf>>>> {
|
||||
fn read_dir(&self, path: &Path) -> GameResult<Box<dyn Iterator<Item=GameResult<PathBuf>>>> {
|
||||
// This is tricky 'cause we have to actually merge iterators together...
|
||||
// Doing it the simple and stupid way works though.
|
||||
let mut v = Vec::new();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::common::{Condition, Direction, Rect, CDEG_RAD};
|
||||
use crate::common::{CDEG_RAD, Condition, Direction, Rect};
|
||||
use crate::engine_constants::EngineConstants;
|
||||
use crate::rng::RNG;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
#[derive(Debug, EnumIter, PartialEq, Eq, Hash, Copy, Clone)]
|
||||
pub enum CaretType {
|
|
@ -1,7 +1,7 @@
|
|||
use crate::common::{fix9_scale, interpolate_fix9_scale};
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::stage::Stage;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::game::stage::Stage;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(u8)]
|
|
@ -1,10 +1,10 @@
|
|||
use std::cmp::Ordering;
|
||||
|
||||
use crate::engine_constants::EngineConstants;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::weapon::{Weapon, WeaponLevel, WeaponType};
|
||||
use crate::player::{Player, TargetPlayer};
|
||||
use crate::weapon::bullet::BulletManager;
|
||||
use crate::game::player::{Player, TargetPlayer};
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::game::weapon::{Weapon, WeaponLevel, WeaponType};
|
||||
use crate::game::weapon::bullet::BulletManager;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
/// (id, amount)
|
|
@ -3,16 +3,16 @@ use std::io;
|
|||
use std::io::{BufRead, BufReader, Cursor, Read};
|
||||
use std::sync::Arc;
|
||||
|
||||
use byteorder::{ReadBytesExt, LE};
|
||||
use byteorder::{LE, ReadBytesExt};
|
||||
|
||||
use crate::common::{Color, Rect};
|
||||
use crate::encoding::read_cur_shift_jis;
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameError::ResourceLoadError;
|
||||
use crate::framework::error::{GameError, GameResult};
|
||||
use crate::framework::error::GameError::ResourceLoadError;
|
||||
use crate::framework::filesystem;
|
||||
use crate::shared_game_state::TileSize;
|
||||
use crate::stage::{PxPackScroll, PxPackStageData, StageData};
|
||||
use crate::game::shared_game_state::TileSize;
|
||||
use crate::game::stage::{PxPackScroll, PxPackStageData, StageData};
|
||||
use crate::util::encoding::read_cur_shift_jis;
|
||||
|
||||
static SUPPORTED_PXM_VERSIONS: [u8; 1] = [0x10];
|
||||
static SUPPORTED_PXE_VERSIONS: [u8; 2] = [0, 0x10];
|
||||
|
@ -211,7 +211,7 @@ impl Map {
|
|||
log::warn!("Map attribute data is shorter than 256 bytes!");
|
||||
}
|
||||
} else if let Ok(mut attrib_data) =
|
||||
filesystem::open_find(ctx, roots, ["Stage/", &tileset_fg, ".pxattr"].join(""))
|
||||
filesystem::open_find(ctx, roots, ["Stage/", &tileset_fg, ".pxattr"].join(""))
|
||||
{
|
||||
attrib_data.read_exact(&mut magic)?;
|
||||
|
||||
|
@ -549,7 +549,7 @@ impl WaterParams {
|
|||
}
|
||||
|
||||
pub fn load_from<R: io::Read>(&mut self, data: R) -> GameResult {
|
||||
fn next_u8<'a>(s: &mut impl Iterator<Item = &'a str>, error_msg: &str) -> GameResult<u8> {
|
||||
fn next_u8<'a>(s: &mut impl Iterator<Item=&'a str>, error_msg: &str) -> GameResult<u8> {
|
||||
match s.next() {
|
||||
None => Err(GameError::ParseError("Out of range.".to_string())),
|
||||
Some(v) => v.trim().parse::<u8>().map_err(|_| GameError::ParseError(error_msg.to_string())),
|
329
src/game/mod.rs
Normal file
|
@ -0,0 +1,329 @@
|
|||
use std::cell::UnsafeCell;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Mutex;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
use scripting::tsc::text_script::ScriptMode;
|
||||
|
||||
use crate::data::builtin_fs::BuiltinFS;
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::framework::filesystem::{mount_user_vfs, mount_vfs};
|
||||
use crate::framework::graphics;
|
||||
use crate::framework::graphics::VSyncMode;
|
||||
use crate::framework::ui::UI;
|
||||
use crate::framework::vfs::PhysicalFS;
|
||||
use crate::game::shared_game_state::{Fps, SharedGameState, TimingMode};
|
||||
use crate::graphics::texture_set::{G_MAG, I_MAG};
|
||||
use crate::scene::loading_scene::LoadingScene;
|
||||
use crate::scene::Scene;
|
||||
|
||||
pub mod caret;
|
||||
pub mod frame;
|
||||
pub mod inventory;
|
||||
pub mod map;
|
||||
pub mod physics;
|
||||
pub mod profile;
|
||||
pub mod settings;
|
||||
pub mod shared_game_state;
|
||||
pub mod stage;
|
||||
pub mod npc;
|
||||
pub mod player;
|
||||
pub mod weapon;
|
||||
pub mod scripting;
|
||||
|
||||
pub struct LaunchOptions {
|
||||
pub server_mode: bool,
|
||||
pub editor: bool,
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
pub static ref GAME_SUSPENDED: Mutex<bool> = Mutex::new(false);
|
||||
}
|
||||
|
||||
pub struct Game {
|
||||
pub(crate) scene: Option<Box<dyn Scene>>,
|
||||
pub(crate) state: UnsafeCell<SharedGameState>,
|
||||
ui: UI,
|
||||
start_time: Instant,
|
||||
last_tick: u128,
|
||||
next_tick: u128,
|
||||
pub(crate) loops: u32,
|
||||
next_tick_draw: u128,
|
||||
present: bool,
|
||||
fps: Fps,
|
||||
}
|
||||
|
||||
impl Game {
|
||||
fn new(ctx: &mut Context) -> GameResult<Game> {
|
||||
let s = Game {
|
||||
scene: None,
|
||||
ui: UI::new(ctx)?,
|
||||
state: UnsafeCell::new(SharedGameState::new(ctx)?),
|
||||
start_time: Instant::now(),
|
||||
last_tick: 0,
|
||||
next_tick: 0,
|
||||
loops: 0,
|
||||
next_tick_draw: 0,
|
||||
present: true,
|
||||
fps: Fps::new(),
|
||||
};
|
||||
|
||||
Ok(s)
|
||||
}
|
||||
|
||||
pub(crate) fn update(&mut self, ctx: &mut Context) -> GameResult {
|
||||
if let Some(scene) = &mut self.scene {
|
||||
let state_ref = unsafe { &mut *self.state.get() };
|
||||
|
||||
let speed =
|
||||
if state_ref.textscript_vm.mode == ScriptMode::Map && state_ref.textscript_vm.flags.cutscene_skip() {
|
||||
4.0 * state_ref.settings.speed
|
||||
} else {
|
||||
1.0 * state_ref.settings.speed
|
||||
};
|
||||
|
||||
match state_ref.settings.timing_mode {
|
||||
TimingMode::_50Hz | TimingMode::_60Hz => {
|
||||
let last_tick = self.next_tick;
|
||||
|
||||
while self.start_time.elapsed().as_nanos() >= self.next_tick && self.loops < 10 {
|
||||
if (speed - 1.0).abs() < 0.01 {
|
||||
self.next_tick += state_ref.settings.timing_mode.get_delta() as u128;
|
||||
} else {
|
||||
self.next_tick += (state_ref.settings.timing_mode.get_delta() as f64 / speed) as u128;
|
||||
}
|
||||
self.loops += 1;
|
||||
}
|
||||
|
||||
if self.loops == 10 {
|
||||
log::warn!("Frame skip is way too high, a long system lag occurred?");
|
||||
self.last_tick = self.start_time.elapsed().as_nanos();
|
||||
self.next_tick =
|
||||
self.last_tick + (state_ref.settings.timing_mode.get_delta() as f64 / speed) as u128;
|
||||
self.loops = 0;
|
||||
}
|
||||
|
||||
if self.loops != 0 {
|
||||
scene.draw_tick(state_ref)?;
|
||||
self.last_tick = last_tick;
|
||||
}
|
||||
|
||||
for _ in 0..self.loops {
|
||||
scene.tick(state_ref, ctx)?;
|
||||
}
|
||||
self.fps.tick_count = self.fps.tick_count.saturating_add(self.loops as u32);
|
||||
}
|
||||
TimingMode::FrameSynchronized => {
|
||||
scene.tick(state_ref, ctx)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn draw(&mut self, ctx: &mut Context) -> GameResult {
|
||||
let state_ref = unsafe { &mut *self.state.get() };
|
||||
|
||||
match ctx.vsync_mode {
|
||||
VSyncMode::Uncapped | VSyncMode::VSync => {
|
||||
self.present = true;
|
||||
}
|
||||
_ => unsafe {
|
||||
self.present = false;
|
||||
|
||||
let divisor = match ctx.vsync_mode {
|
||||
VSyncMode::VRRTickSync1x => 1,
|
||||
VSyncMode::VRRTickSync2x => 2,
|
||||
VSyncMode::VRRTickSync3x => 3,
|
||||
_ => std::hint::unreachable_unchecked(),
|
||||
};
|
||||
|
||||
let delta = (state_ref.settings.timing_mode.get_delta() / divisor) as u64;
|
||||
|
||||
let now = self.start_time.elapsed().as_nanos();
|
||||
if now > self.next_tick_draw + delta as u128 * 4 {
|
||||
self.next_tick_draw = now;
|
||||
}
|
||||
|
||||
while self.start_time.elapsed().as_nanos() >= self.next_tick_draw {
|
||||
self.next_tick_draw += delta as u128;
|
||||
self.present = true;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
if !self.present {
|
||||
std::thread::sleep(Duration::from_millis(2));
|
||||
self.loops = 0;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if ctx.headless {
|
||||
self.loops = 0;
|
||||
state_ref.frame_time = 1.0;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if state_ref.settings.timing_mode != TimingMode::FrameSynchronized {
|
||||
let mut elapsed = self.start_time.elapsed().as_nanos();
|
||||
|
||||
// Even with the non-monotonic Instant mitigation at the start of the event loop, there's still a chance of it not working.
|
||||
// This check here should trigger if that happens and makes sure there's no panic from an underflow.
|
||||
if elapsed < self.last_tick {
|
||||
elapsed = self.last_tick;
|
||||
}
|
||||
|
||||
let n1 = (elapsed - self.last_tick) as f64;
|
||||
let n2 = (self.next_tick - self.last_tick) as f64;
|
||||
state_ref.frame_time = if state_ref.settings.motion_interpolation { n1 / n2 } else { 1.0 };
|
||||
}
|
||||
unsafe {
|
||||
G_MAG = if state_ref.settings.subpixel_coords { state_ref.scale } else { 1.0 };
|
||||
I_MAG = state_ref.scale;
|
||||
}
|
||||
self.loops = 0;
|
||||
|
||||
graphics::prepare_draw(ctx)?;
|
||||
graphics::clear(ctx, [0.0, 0.0, 0.0, 1.0].into());
|
||||
|
||||
if let Some(scene) = &mut self.scene {
|
||||
scene.draw(state_ref, ctx)?;
|
||||
if state_ref.settings.touch_controls {
|
||||
state_ref.touch_controls.draw(
|
||||
state_ref.canvas_size,
|
||||
state_ref.scale,
|
||||
&state_ref.constants,
|
||||
&mut state_ref.texture_set,
|
||||
ctx,
|
||||
)?;
|
||||
}
|
||||
|
||||
if state_ref.settings.fps_counter {
|
||||
self.fps.act(state_ref, ctx, self.start_time.elapsed().as_nanos())?;
|
||||
}
|
||||
|
||||
self.ui.draw(state_ref, ctx, scene)?;
|
||||
}
|
||||
|
||||
graphics::present(ctx)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(options: LaunchOptions) -> GameResult {
|
||||
let _ = simple_logger::SimpleLogger::new()
|
||||
.without_timestamps()
|
||||
.with_colors(true)
|
||||
.with_level(log::Level::Info.to_level_filter())
|
||||
.init();
|
||||
|
||||
#[cfg(not(target_os = "android"))]
|
||||
let resource_dir = if let Ok(data_dir) = std::env::var("CAVESTORY_DATA_DIR") {
|
||||
PathBuf::from(data_dir)
|
||||
} else {
|
||||
let mut resource_dir = std::env::current_exe()?;
|
||||
if resource_dir.file_name().is_some() {
|
||||
let _ = resource_dir.pop();
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
let mut bundle_dir = resource_dir.clone();
|
||||
let _ = bundle_dir.pop();
|
||||
let mut bundle_exec_dir = bundle_dir.clone();
|
||||
let mut csplus_data_dir = bundle_dir.clone();
|
||||
let _ = csplus_data_dir.pop();
|
||||
let _ = csplus_data_dir.pop();
|
||||
let mut csplus_data_base_dir = csplus_data_dir.clone();
|
||||
csplus_data_base_dir.push("data");
|
||||
csplus_data_base_dir.push("base");
|
||||
|
||||
bundle_exec_dir.push("MacOS");
|
||||
bundle_dir.push("Resources");
|
||||
|
||||
if bundle_exec_dir.is_dir() && bundle_dir.is_dir() {
|
||||
log::info!("Running in macOS bundle mode");
|
||||
|
||||
if csplus_data_base_dir.is_dir() {
|
||||
log::info!("Cave Story+ Steam detected");
|
||||
resource_dir = csplus_data_dir;
|
||||
} else {
|
||||
resource_dir = bundle_dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource_dir.push("data");
|
||||
resource_dir
|
||||
};
|
||||
|
||||
#[cfg(not(target_os = "android"))]
|
||||
log::info!("Resource directory: {:?}", resource_dir);
|
||||
log::info!("Initializing engine...");
|
||||
|
||||
let mut context = Context::new();
|
||||
#[cfg(not(target_os = "android"))]
|
||||
mount_vfs(&mut context, Box::new(PhysicalFS::new(&resource_dir, true)));
|
||||
|
||||
#[cfg(not(target_os = "android"))]
|
||||
let project_dirs = match directories::ProjectDirs::from("", "", "doukutsu-rs") {
|
||||
Some(dirs) => dirs,
|
||||
None => {
|
||||
use crate::framework::error::GameError;
|
||||
return Err(GameError::FilesystemError(String::from("No valid home directory path could be retrieved.")));
|
||||
}
|
||||
};
|
||||
#[cfg(target_os = "android")]
|
||||
{
|
||||
let mut data_path =
|
||||
PathBuf::from(ndk_glue::native_activity().internal_data_path().to_string_lossy().to_string());
|
||||
let mut user_path = data_path.clone();
|
||||
|
||||
data_path.push("data");
|
||||
user_path.push("saves");
|
||||
|
||||
let _ = std::fs::create_dir_all(&data_path);
|
||||
let _ = std::fs::create_dir_all(&user_path);
|
||||
|
||||
log::info!("Android data directories: data_path={:?} user_path={:?}", &data_path, &user_path);
|
||||
|
||||
mount_vfs(&mut context, Box::new(PhysicalFS::new(&data_path, true)));
|
||||
mount_user_vfs(&mut context, Box::new(PhysicalFS::new(&user_path, false)));
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "android"))]
|
||||
{
|
||||
if crate::framework::filesystem::open(&context, "/.drs_localstorage").is_ok() {
|
||||
let mut user_dir = resource_dir.clone();
|
||||
user_dir.push("_drs_profile");
|
||||
|
||||
let _ = std::fs::create_dir_all(&user_dir);
|
||||
mount_user_vfs(&mut context, Box::new(PhysicalFS::new(&user_dir, false)));
|
||||
} else {
|
||||
mount_user_vfs(&mut context, Box::new(PhysicalFS::new(project_dirs.data_local_dir(), false)));
|
||||
}
|
||||
}
|
||||
|
||||
mount_vfs(&mut context, Box::new(BuiltinFS::new()));
|
||||
|
||||
if options.server_mode {
|
||||
log::info!("Running in server mode...");
|
||||
context.headless = true;
|
||||
}
|
||||
|
||||
let game = UnsafeCell::new(Game::new(&mut context)?);
|
||||
let state_ref = unsafe { &mut *((&mut *game.get()).state.get()) };
|
||||
#[cfg(feature = "scripting-lua")]
|
||||
{
|
||||
state_ref.lua.update_refs(unsafe { (&*game.get()).state.get() }, &mut context as *mut Context);
|
||||
}
|
||||
|
||||
state_ref.next_scene = Some(Box::new(LoadingScene::new()));
|
||||
context.run(unsafe { &mut *game.get() })?;
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,9 +1,10 @@
|
|||
use crate::common::Direction;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::{GameResult, SharedGameState};
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n254_helicopter(&mut self, state: &mut SharedGameState, npc_list: &NPCList) -> GameResult {
|
|
@ -1,14 +1,14 @@
|
|||
use num_traits::clamp;
|
||||
|
||||
use crate::caret::CaretType;
|
||||
use crate::common::{Direction, CDEG_RAD};
|
||||
use crate::common::{CDEG_RAD, Direction};
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::stage::Stage;
|
||||
use crate::game::caret::CaretType;
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::game::stage::Stage;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n009_balrog_falling_in(
|
|
@ -1,9 +1,8 @@
|
|||
use crate::framework::error::GameResult;
|
||||
|
||||
use crate::common::Direction;
|
||||
use crate::npc::NPC;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n113_professor_booster(&mut self, state: &mut SharedGameState) -> GameResult {
|
|
@ -1,11 +1,10 @@
|
|||
use crate::framework::error::GameResult;
|
||||
|
||||
use crate::caret::CaretType;
|
||||
use crate::common::Direction;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::game::caret::CaretType;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n093_chaco(&mut self, state: &mut SharedGameState, players: [&mut Player; 2]) -> GameResult {
|
|
@ -2,11 +2,11 @@ use num_traits::{abs, clamp};
|
|||
|
||||
use crate::common::Direction;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n029_cthulhu(&mut self, state: &mut SharedGameState, players: [&mut Player; 2]) -> GameResult {
|
|
@ -1,14 +1,14 @@
|
|||
use num_traits::{abs, clamp};
|
||||
|
||||
use crate::caret::CaretType;
|
||||
use crate::common::{Direction, Rect};
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::{Player, TargetPlayer};
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::weapon::bullet::BulletManager;
|
||||
use crate::game::caret::CaretType;
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::{Player, TargetPlayer};
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::game::weapon::bullet::BulletManager;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n117_curly(
|
||||
|
@ -581,12 +581,12 @@ impl NPC {
|
|||
} else {
|
||||
self.x = parent.x
|
||||
+ if parent.direction == Direction::Left {
|
||||
self.direction = Direction::Left;
|
||||
-0x1000
|
||||
} else {
|
||||
self.direction = Direction::Right;
|
||||
0x1000
|
||||
};
|
||||
self.direction = Direction::Left;
|
||||
-0x1000
|
||||
} else {
|
||||
self.direction = Direction::Right;
|
||||
0x1000
|
||||
};
|
||||
self.y = parent.y;
|
||||
self.anim_num = 0;
|
||||
}
|
||||
|
@ -675,12 +675,12 @@ impl NPC {
|
|||
} else {
|
||||
self.x = parent.x
|
||||
+ if parent.direction == Direction::Left {
|
||||
self.direction = Direction::Left;
|
||||
-0x1000
|
||||
} else {
|
||||
self.direction = Direction::Right;
|
||||
0x1000
|
||||
};
|
||||
self.direction = Direction::Left;
|
||||
-0x1000
|
||||
} else {
|
||||
self.direction = Direction::Right;
|
||||
0x1000
|
||||
};
|
||||
self.y = parent.y;
|
||||
self.anim_num = 0;
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
use crate::common::{Direction, Rect, CDEG_RAD};
|
||||
use crate::common::{CDEG_RAD, Direction, Rect};
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::stage::Stage;
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::game::stage::Stage;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n139_doctor(&mut self, state: &mut SharedGameState) -> GameResult {
|
|
@ -1,14 +1,14 @@
|
|||
use num_traits::{abs, clamp};
|
||||
|
||||
use crate::caret::CaretType;
|
||||
use crate::common::{Direction, Rect, CDEG_RAD};
|
||||
use crate::common::{CDEG_RAD, Direction, Rect};
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::{Player, TargetPlayer};
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::weapon::bullet::BulletManager;
|
||||
use crate::game::caret::CaretType;
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::{Player, TargetPlayer};
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::game::weapon::bullet::BulletManager;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n002_behemoth(&mut self, state: &mut SharedGameState, npc_list: &NPCList) -> GameResult {
|
|
@ -2,10 +2,10 @@ use num_traits::clamp;
|
|||
|
||||
use crate::common::Direction;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n059_eye_door(&mut self, state: &mut SharedGameState, players: [&mut Player; 2]) -> GameResult {
|
|
@ -1,13 +1,13 @@
|
|||
use num_traits::abs;
|
||||
use num_traits::clamp;
|
||||
|
||||
use crate::caret::CaretType;
|
||||
use crate::common::{Direction, Rect};
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::{NPCList, NPC};
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::game::caret::CaretType;
|
||||
use crate::game::npc::{NPC, NPCList};
|
||||
use crate::game::player::Player;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n024_power_critter(
|
||||
|
@ -834,7 +834,7 @@ impl NPC {
|
|||
&& self.action_num != 3
|
||||
&& self.action_counter > 10
|
||||
&& ((self.shock > 0)
|
||||
|| (abs(self.x - player.x) < 0x14000 && abs(self.y - player.y) < 0x8000) && self.rng.range(0..50) == 2)
|
||||
|| (abs(self.x - player.x) < 0x14000 && abs(self.y - player.y) < 0x8000) && self.rng.range(0..50) == 2)
|
||||
{
|
||||
self.direction = if self.x >= player.x { Direction::Left } else { Direction::Right };
|
||||
self.action_num = 10;
|
||||
|
@ -1176,7 +1176,7 @@ impl NPC {
|
|||
&& self.action_num != 3
|
||||
&& self.action_counter > 10
|
||||
&& ((self.shock > 0)
|
||||
|| (abs(self.x - player.x) < 0x14000 && abs(self.y - player.y) < 0x8000) && self.rng.range(0..50) == 2)
|
||||
|| (abs(self.x - player.x) < 0x14000 && abs(self.y - player.y) < 0x8000) && self.rng.range(0..50) == 2)
|
||||
{
|
||||
self.direction = if self.x >= player.x { Direction::Left } else { Direction::Right };
|
||||
self.action_num = 10;
|
||||
|
@ -1219,9 +1219,9 @@ impl NPC {
|
|||
let player = self.get_closest_player_mut(players);
|
||||
if self.shock != 0
|
||||
|| (player.x < self.x + 0xc000
|
||||
&& player.x > self.x - 0xc000
|
||||
&& player.y < self.y + 0x4000
|
||||
&& player.y > self.y - 0xc000)
|
||||
&& player.x > self.x - 0xc000
|
||||
&& player.y < self.y + 0x4000
|
||||
&& player.y > self.y - 0xc000)
|
||||
{
|
||||
self.action_num = 10;
|
||||
}
|
|
@ -1,11 +1,12 @@
|
|||
use crate::caret::CaretType;
|
||||
use crate::common::Direction;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::stage::Stage;
|
||||
use crate::{GameResult, SharedGameState};
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::game::caret::CaretType;
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::game::stage::Stage;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n337_numahachi(&mut self, state: &mut SharedGameState) -> GameResult {
|
||||
|
@ -264,7 +265,7 @@ impl NPC {
|
|||
|
||||
if (player.y > self.y - 0x14000 && player.y < self.y + 0x14000)
|
||||
&& ((self.direction == Direction::Left && player.x > self.x - 0x28000 && player.x < self.x)
|
||||
|| (self.direction != Direction::Left && player.x > self.x && player.x < self.x + 0x28000))
|
||||
|| (self.direction != Direction::Left && player.x > self.x && player.x < self.x + 0x28000))
|
||||
{
|
||||
self.action_num = 10;
|
||||
}
|
||||
|
@ -511,9 +512,9 @@ impl NPC {
|
|||
let player = self.get_closest_player_ref(&players);
|
||||
if self.action_counter > 20
|
||||
&& ((self.direction == Direction::Left && self.x <= player.x + 0x4000)
|
||||
|| (self.direction == Direction::Up && self.y <= player.y + 0x4000)
|
||||
|| (self.direction == Direction::Right && self.x <= player.x - 0x4000)
|
||||
|| (self.direction == Direction::Bottom && self.y <= player.y - 0x4000))
|
||||
|| (self.direction == Direction::Up && self.y <= player.y + 0x4000)
|
||||
|| (self.direction == Direction::Right && self.x <= player.x - 0x4000)
|
||||
|| (self.direction == Direction::Bottom && self.y <= player.y - 0x4000))
|
||||
{
|
||||
self.action_num = 10
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
use crate::common::{Direction, CDEG_RAD};
|
||||
use crate::common::{CDEG_RAD, Direction};
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n083_igor_cutscene(&mut self, state: &mut SharedGameState) -> GameResult {
|
|
@ -1,10 +1,9 @@
|
|||
use crate::framework::error::GameResult;
|
||||
|
||||
use crate::caret::CaretType;
|
||||
use crate::common::Direction;
|
||||
use crate::npc::NPC;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::game::caret::CaretType;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n298_intro_doctor(&mut self, state: &mut SharedGameState) -> GameResult {
|
|
@ -1,11 +1,11 @@
|
|||
use crate::caret::CaretType;
|
||||
use crate::common::Direction;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::game::caret::CaretType;
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n241_critter_red(
|
|
@ -1,11 +1,11 @@
|
|||
use crate::caret::CaretType;
|
||||
use crate::common::{Direction, CDEG_RAD};
|
||||
use crate::common::{CDEG_RAD, Direction};
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::game::caret::CaretType;
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n147_critter_purple(
|
|
@ -4,13 +4,13 @@ use num_traits::{abs, clamp};
|
|||
|
||||
use crate::common::Direction;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::{Player, TargetPlayer};
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::stage::Stage;
|
||||
use crate::weapon::bullet::BulletManager;
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::{Player, TargetPlayer};
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::game::stage::Stage;
|
||||
use crate::game::weapon::bullet::BulletManager;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n069_pignon(&mut self, state: &mut SharedGameState) -> GameResult {
|
|
@ -1,16 +1,16 @@
|
|||
use std::hint::unreachable_unchecked;
|
||||
|
||||
use crate::caret::CaretType;
|
||||
use crate::common::{Direction, Rect};
|
||||
use crate::components::flash::Flash;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::boss::BossNPC;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::{NPCLayer, NPC};
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::{GameDifficulty, SharedGameState};
|
||||
use crate::stage::Stage;
|
||||
use crate::game::caret::CaretType;
|
||||
use crate::game::npc::{NPC, NPCLayer};
|
||||
use crate::game::npc::boss::BossNPC;
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::shared_game_state::{GameDifficulty, SharedGameState};
|
||||
use crate::game::stage::Stage;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n000_null(&mut self) -> GameResult {
|
||||
|
@ -624,9 +624,9 @@ impl NPC {
|
|||
self.action_counter += 1;
|
||||
if self.action_counter > 10
|
||||
&& (self.flags.hit_left_wall()
|
||||
|| self.flags.hit_right_wall()
|
||||
|| self.flags.hit_bottom_wall()
|
||||
|| self.flags.in_water())
|
||||
|| self.flags.hit_right_wall()
|
||||
|| self.flags.hit_bottom_wall()
|
||||
|| self.flags.in_water())
|
||||
{
|
||||
// hit something
|
||||
self.cond.set_alive(false);
|
||||
|
@ -2180,11 +2180,11 @@ impl NPC {
|
|||
npc.cond.set_alive(true);
|
||||
npc.x = self.x
|
||||
+ if player.equip.has_booster_2_0() {
|
||||
self.rng.range(-14..14)
|
||||
} else {
|
||||
self.rng.range(-11..11)
|
||||
} * state.tile_size.as_int()
|
||||
* 0x200;
|
||||
self.rng.range(-14..14)
|
||||
} else {
|
||||
self.rng.range(-11..11)
|
||||
} * state.tile_size.as_int()
|
||||
* 0x200;
|
||||
npc.y = player.y - 0x1C000;
|
||||
npc.direction = if self.rng.range(0..10) & 1 != 0 { Direction::Left } else { Direction::Right };
|
||||
|
|
@ -2,17 +2,17 @@ use std::hint::unreachable_unchecked;
|
|||
|
||||
use num_traits::clamp;
|
||||
|
||||
use crate::caret::CaretType;
|
||||
use crate::common::{Direction, CDEG_RAD};
|
||||
use crate::common::{CDEG_RAD, Direction};
|
||||
use crate::components::flash::Flash;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::boss::BossNPC;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::stage::Stage;
|
||||
use crate::game::caret::CaretType;
|
||||
use crate::game::npc::boss::BossNPC;
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::game::stage::Stage;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n066_misery_bubble(&mut self, state: &mut SharedGameState, npc_list: &NPCList) -> GameResult {
|
||||
|
@ -845,10 +845,10 @@ impl NPC {
|
|||
if let Some(parent) = self.get_parent_ref_mut(npc_list) {
|
||||
self.x = parent.x
|
||||
+ self.action_counter as i32 * ((self.action_counter2 as f64 * CDEG_RAD).cos() * -512.0) as i32
|
||||
/ 4;
|
||||
/ 4;
|
||||
self.y = parent.y
|
||||
+ self.action_counter as i32 * ((self.action_counter2 as f64 * CDEG_RAD).sin() * -512.0) as i32
|
||||
/ 4;
|
||||
/ 4;
|
||||
|
||||
if parent.action_num == 151 {
|
||||
self.action_num = 10;
|
28
src/game/npc/ai/mod.rs
Normal file
|
@ -0,0 +1,28 @@
|
|||
pub(crate) mod balcony;
|
||||
pub(crate) mod balrog;
|
||||
pub(crate) mod booster;
|
||||
pub(crate) mod chaco;
|
||||
pub(crate) mod characters;
|
||||
pub(crate) mod curly;
|
||||
pub(crate) mod doctor;
|
||||
pub(crate) mod egg_corridor;
|
||||
pub(crate) mod first_cave;
|
||||
pub(crate) mod grasstown;
|
||||
pub(crate) mod hell;
|
||||
pub(crate) mod igor;
|
||||
pub(crate) mod intro;
|
||||
pub(crate) mod last_cave;
|
||||
pub(crate) mod maze;
|
||||
pub(crate) mod mimiga_village;
|
||||
pub(crate) mod misc;
|
||||
pub(crate) mod misery;
|
||||
pub(crate) mod outer_wall;
|
||||
pub(crate) mod pickups;
|
||||
pub(crate) mod plantation;
|
||||
pub(crate) mod quote;
|
||||
pub(crate) mod sand_zone;
|
||||
pub(crate) mod santa;
|
||||
pub(crate) mod sue;
|
||||
pub(crate) mod toroko;
|
||||
pub(crate) mod weapon_trail;
|
||||
pub(crate) mod wind_fortress;
|
|
@ -2,11 +2,11 @@ use num_traits::abs;
|
|||
|
||||
use crate::common::Direction;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n212_sky_dragon(
|
|
@ -1,9 +1,9 @@
|
|||
use crate::common::Direction;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::NPC;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::stage::{Stage, BackgroundType};
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::game::stage::{BackgroundType, Stage};
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n001_experience(&mut self, state: &mut SharedGameState, stage: &mut Stage) -> GameResult {
|
|
@ -1,11 +1,11 @@
|
|||
use crate::caret::CaretType;
|
||||
use crate::common::{Direction, CDEG_RAD};
|
||||
use crate::common::{CDEG_RAD, Direction};
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::game::caret::CaretType;
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n220_shovel_brigade(&mut self, state: &mut SharedGameState) -> GameResult {
|
|
@ -1,11 +1,10 @@
|
|||
use crate::framework::error::GameResult;
|
||||
|
||||
use crate::common::Direction;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub fn tick_n111_quote_teleport_out(
|
|
@ -1,14 +1,14 @@
|
|||
use num_traits::{abs, clamp};
|
||||
|
||||
use crate::caret::CaretType;
|
||||
use crate::common::{Direction, CDEG_RAD};
|
||||
use crate::common::{CDEG_RAD, Direction};
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::weapon::bullet::BulletManager;
|
||||
use crate::game::caret::CaretType;
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::game::weapon::bullet::BulletManager;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n044_polish(&mut self, state: &mut SharedGameState, npc_list: &NPCList) -> GameResult {
|
|
@ -2,10 +2,10 @@ use num_traits::abs;
|
|||
|
||||
use crate::common::Direction;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n040_santa(&mut self, state: &mut SharedGameState, players: [&mut Player; 2]) -> GameResult {
|
|
@ -1,12 +1,12 @@
|
|||
use crate::common::Direction;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::boss::BossNPC;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::stage::Stage;
|
||||
use crate::game::npc::boss::BossNPC;
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::game::stage::Stage;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub fn tick_n042_sue(
|
|
@ -1,12 +1,12 @@
|
|||
use crate::caret::CaretType;
|
||||
use crate::common::Direction;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::weapon::bullet::BulletManager;
|
||||
use crate::game::caret::CaretType;
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::game::weapon::bullet::BulletManager;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n060_toroko(&mut self, state: &mut SharedGameState, players: [&mut Player; 2]) -> GameResult {
|
|
@ -1,11 +1,10 @@
|
|||
use crate::framework::error::GameResult;
|
||||
|
||||
use crate::npc::NPC;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::common::Direction;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n127_machine_gun_trail_l2(&mut self, state: &mut SharedGameState ) -> GameResult {
|
||||
pub(crate) fn tick_n127_machine_gun_trail_l2(&mut self, state: &mut SharedGameState) -> GameResult {
|
||||
self.anim_counter += 1;
|
||||
if self.anim_counter > 0 {
|
||||
self.anim_counter = 0;
|
||||
|
@ -30,7 +29,7 @@ impl NPC {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn tick_n128_machine_gun_trail_l3(&mut self, state: &mut SharedGameState ) -> GameResult {
|
||||
pub(crate) fn tick_n128_machine_gun_trail_l3(&mut self, state: &mut SharedGameState) -> GameResult {
|
||||
self.anim_counter += 1;
|
||||
if self.anim_counter > 0 {
|
||||
self.anim_counter = 0;
|
|
@ -1,11 +1,11 @@
|
|||
use crate::caret::CaretType;
|
||||
use crate::common::{Direction, CDEG_RAD};
|
||||
use crate::common::{CDEG_RAD, Direction};
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::game::caret::CaretType;
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
// Gaudi from room 2
|
|
@ -1,13 +1,12 @@
|
|||
use crate::common::{CDEG_RAD, Direction, Rect};
|
||||
use crate::framework::error::GameResult;
|
||||
|
||||
use crate::caret::CaretType;
|
||||
use crate::common::{Direction, Rect, CDEG_RAD};
|
||||
use crate::npc::boss::BossNPC;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::game::caret::CaretType;
|
||||
use crate::game::npc::boss::BossNPC;
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n108_balfrog_projectile(&mut self, state: &mut SharedGameState) -> GameResult {
|
|
@ -1,14 +1,14 @@
|
|||
use crate::caret::CaretType;
|
||||
use crate::common::{Direction, Rect, CDEG_RAD};
|
||||
use crate::common::{CDEG_RAD, Direction, Rect};
|
||||
use crate::components::flash::Flash;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::boss::BossNPC;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::stage::Stage;
|
||||
use crate::game::caret::CaretType;
|
||||
use crate::game::npc::boss::BossNPC;
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::game::stage::Stage;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n331_ballos_bone_projectile(&mut self, state: &mut SharedGameState) -> GameResult {
|
|
@ -1,13 +1,13 @@
|
|||
use crate::caret::CaretType;
|
||||
use crate::common::{Direction, CDEG_RAD};
|
||||
use crate::common::{CDEG_RAD, Direction};
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::boss::BossNPC;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::stage::Stage;
|
||||
use crate::game::caret::CaretType;
|
||||
use crate::game::npc::boss::BossNPC;
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::game::stage::Stage;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n178_core_blade_projectile(&mut self, state: &mut SharedGameState) -> GameResult {
|
||||
|
@ -93,7 +93,7 @@ impl BossNPC {
|
|||
let mut flag = false;
|
||||
// i will refactor that one day
|
||||
#[allow(mutable_transmutes)]
|
||||
let flash_counter: &mut u16 = unsafe { std::mem::transmute(&self.parts[19].action_counter3) };
|
||||
let flash_counter: &mut u16 = unsafe { std::mem::transmute(&self.parts[19].action_counter3) };
|
||||
|
||||
match self.parts[0].action_num {
|
||||
0 => {
|
|
@ -1,11 +1,11 @@
|
|||
use crate::common::{Direction, Rect};
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::boss::BossNPC;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::NPC;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::stage::Stage;
|
||||
use crate::game::npc::boss::BossNPC;
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::game::stage::Stage;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n325_heavy_press_lightning(
|
|
@ -1,11 +1,11 @@
|
|||
use crate::common::{Direction, Rect};
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::boss::BossNPC;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::Player;
|
||||
use crate::rng::RNG;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::game::npc::boss::BossNPC;
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::util::rng::RNG;
|
||||
|
||||
impl NPC {
|
||||
pub(crate) fn tick_n196_ironhead_wall(&mut self, state: &mut SharedGameState) -> GameResult {
|
|
@ -1,18 +1,18 @@
|
|||
use std::mem::{transmute, MaybeUninit};
|
||||
use std::mem::{MaybeUninit, transmute};
|
||||
use std::ops::Deref;
|
||||
|
||||
use crate::common::{interpolate_fix9_scale, Direction};
|
||||
use crate::common::{Direction, interpolate_fix9_scale};
|
||||
use crate::components::flash::Flash;
|
||||
use crate::entity::GameEntity;
|
||||
use crate::frame::Frame;
|
||||
use crate::framework::context::Context;
|
||||
use crate::framework::error::GameResult;
|
||||
use crate::npc::list::NPCList;
|
||||
use crate::npc::NPC;
|
||||
use crate::player::Player;
|
||||
use crate::shared_game_state::SharedGameState;
|
||||
use crate::stage::Stage;
|
||||
use crate::weapon::bullet::BulletManager;
|
||||
use crate::game::frame::Frame;
|
||||
use crate::game::npc::list::NPCList;
|
||||
use crate::game::npc::NPC;
|
||||
use crate::game::player::Player;
|
||||
use crate::game::shared_game_state::SharedGameState;
|
||||
use crate::game::stage::Stage;
|
||||
use crate::game::weapon::bullet::BulletManager;
|
||||
|
||||
pub mod balfrog;
|
||||
pub mod ballos;
|