1
0
Fork 0
mirror of https://github.com/doukutsu-rs/doukutsu-rs synced 2024-12-28 06:46:43 +00:00

gitignore moment

This commit is contained in:
Alula 2022-11-19 18:27:28 +01:00
parent 17e1156850
commit df467e8764
No known key found for this signature in database
GPG key ID: 3E00485503A1D8BA
26 changed files with 3032 additions and 1 deletions

2
.gitignore vendored
View file

@ -2,7 +2,7 @@
.vscode/
# Cave Story (copyrighted) data files
data/
/data/
# Generated by Cargo
# will have compiled files and executables

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 562 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 621 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View file

@ -0,0 +1,178 @@
{
"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"
}
}

View file

@ -0,0 +1,178 @@
{
"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} を押し続け、カットシーンをスキップ"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 B

View file

@ -0,0 +1,276 @@
# 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Binary file not shown.

BIN
src/data/builtin/touch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

321
src/data/builtin_fs.rs Normal file
View file

@ -0,0 +1,321 @@
use std::{fmt, io};
use std::fmt::Debug;
use std::io::Cursor;
use std::io::ErrorKind;
use std::io::SeekFrom;
use std::path::{Component, Path, PathBuf};
use crate::framework::error::GameError::FilesystemError;
use crate::framework::error::GameResult;
use crate::framework::vfs::{OpenOptions, VFile, VFS, VMetadata};
#[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(
"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());
}

127
src/data/exe_parser.rs Normal file
View file

@ -0,0 +1,127 @@
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);
}
}
}
}

3
src/data/mod.rs Normal file
View file

@ -0,0 +1,3 @@
pub mod builtin_fs;
pub mod exe_parser;
pub mod vanilla;

207
src/data/vanilla.rs Normal file
View file

@ -0,0 +1,207 @@
use std::{
env,
io::{Read, Write},
ops::Range,
path::PathBuf,
};
use byteorder::{LE, WriteBytesExt};
use crate::data::exe_parser::ExeParser;
use crate::framework::{
context::Context,
error::{GameError::ParseError, GameResult},
filesystem,
};
pub struct VanillaExtractor {
exe_buffer: Vec<u8>,
data_base_dir: String,
}
const VANILLA_STAGE_COUNT: u32 = 95;
const VANILLA_STAGE_ENTRY_SIZE: u32 = 0xC8;
const VANILLA_STAGE_OFFSET: u32 = 0x937B0;
const VANILLA_STAGE_TABLE_SIZE: u32 = VANILLA_STAGE_COUNT * VANILLA_STAGE_ENTRY_SIZE;
impl VanillaExtractor {
pub fn from(ctx: &mut Context, exe_name: String, data_base_dir: String) -> Option<Self> {
let mut vanilla_exe_path = env::current_exe().unwrap();
vanilla_exe_path.pop();
vanilla_exe_path.push(exe_name);
if !vanilla_exe_path.is_file() {
return None;
}
log::info!("Found vanilla game executable, attempting to extract resources.");
if filesystem::exists(ctx, format!("{}/stage.sect", data_base_dir.clone())) {
log::info!("Vanilla resources are already extracted, not proceeding.");
return None;
}
let file = std::fs::File::open(vanilla_exe_path);
if file.is_err() {
log::error!("Failed to open vanilla game executable: {}", file.unwrap_err());
return None;
}
let mut exe_buffer = Vec::new();
let result = file.unwrap().read_to_end(&mut exe_buffer);
if result.is_err() {
log::error!("Failed to read vanilla game executable: {}", result.unwrap_err());
return None;
}
Some(Self { exe_buffer, data_base_dir })
}
pub fn extract_data(&self) -> GameResult {
let parser = ExeParser::from(&self.exe_buffer);
if parser.is_err() {
return Err(ParseError("Failed to create vanilla parser.".to_string()));
}
let parser = parser.unwrap();
self.extract_organya(&parser)?;
self.extract_bitmaps(&parser)?;
self.extract_stage_table(&parser)?;
Ok(())
}
fn deep_create_dir_if_not_exists(&self, path: PathBuf) -> GameResult {
if path.is_dir() {
return Ok(());
}
let result = std::fs::create_dir_all(path);
if result.is_err() {
return Err(ParseError(format!("Failed to create directory structure: {}", result.unwrap_err())));
}
Ok(())
}
fn extract_organya(&self, parser: &ExeParser) -> GameResult {
let orgs = parser.get_resource_dir("ORG".to_string());
if orgs.is_err() {
return Err(ParseError("Failed to retrieve Organya resource directory.".to_string()));
}
for org in orgs.unwrap().data_files {
let mut org_path = env::current_exe().unwrap();
org_path.pop();
org_path.push(self.data_base_dir.clone());
org_path.push("Org/");
if self.deep_create_dir_if_not_exists(org_path.clone()).is_err() {
return Err(ParseError("Failed to create directory structure.".to_string()));
}
org_path.push(format!("{}.org", org.name));
let mut org_file = match std::fs::File::create(org_path) {
Ok(file) => file,
Err(_) => {
return Err(ParseError("Failed to create organya file.".to_string()));
}
};
let result = org_file.write_all(&org.bytes);
if result.is_err() {
return Err(ParseError("Failed to write organya file.".to_string()));
}
log::info!("Extracted organya file: {}", org.name);
}
Ok(())
}
fn extract_bitmaps(&self, parser: &ExeParser) -> GameResult {
let bitmaps = parser.get_bitmap_dir();
if bitmaps.is_err() {
return Err(ParseError("Failed to retrieve bitmap directory.".to_string()));
}
for bitmap in bitmaps.unwrap().data_files {
let mut data_path = env::current_exe().unwrap();
data_path.pop();
data_path.push(self.data_base_dir.clone());
if self.deep_create_dir_if_not_exists(data_path.clone()).is_err() {
return Err(ParseError("Failed to create data directory structure.".to_string()));
}
data_path.push(format!("{}.pbm", bitmap.name));
let file = std::fs::File::create(data_path);
if file.is_err() {
return Err(ParseError("Failed to create bitmap file.".to_string()));
}
let mut file = file.unwrap();
file.write_u8(0x42)?; // B
file.write_u8(0x4D)?; // M
file.write_u32::<LE>(bitmap.bytes.len() as u32 + 0xE)?; // Size of BMP file
file.write_u32::<LE>(0)?; // unused null bytes
file.write_u32::<LE>(0x76)?; // Bitmap data offset (hardcoded for now, might wanna get the actual offset)
let result = file.write_all(&bitmap.bytes);
if result.is_err() {
return Err(ParseError("Failed to write bitmap file.".to_string()));
}
log::info!("Extracted bitmap file: {}", bitmap.name);
}
Ok(())
}
fn extract_stage_table(&self, parser: &ExeParser) -> GameResult {
let range = parser.get_named_section_byte_range(".csmap".to_string());
if range.is_err() {
return Err(ParseError("Failed to retrieve stage table from executable.".to_string()));
}
let range = match range.unwrap() {
Some(range) => range,
None => Range { start: VANILLA_STAGE_OFFSET, end: VANILLA_STAGE_OFFSET + VANILLA_STAGE_TABLE_SIZE },
};
let start = range.start as usize;
let end = range.end as usize;
let byte_slice = &self.exe_buffer[start..end];
let mut stage_tbl_path = env::current_exe().unwrap();
stage_tbl_path.pop();
stage_tbl_path.push(self.data_base_dir.clone());
if self.deep_create_dir_if_not_exists(stage_tbl_path.clone()).is_err() {
return Err(ParseError("Failed to create data directory structure.".to_string()));
}
stage_tbl_path.push("stage.sect");
let mut stage_tbl_file = match std::fs::File::create(stage_tbl_path) {
Ok(file) => file,
Err(_) => {
return Err(ParseError("Failed to create stage table file.".to_string()));
}
};
let result = stage_tbl_file.write_all(byte_slice);
if result.is_err() {
return Err(ParseError("Failed to write to stage table file.".to_string()));
}
Ok(())
}
}