2021年09月18日

Slash'EM の二刀流

21/09/19 追記: 不十分な記述だったので修正しました. 結論は変わりません.

untwoweap.png

Slash'EM で二刀流するには, 以下の 1 に該当し, さらに 2 か 3 の内, 少なくともいずれかに該当する必要があります. (mondata.h の #define could_twoweap, wield.c の can_twoweapon, monst.c)

  • 1. 現在の種族で, 二刀流が可能である (二度目の攻撃の種類が武器攻撃である). 変化していない場合, ドワーフ, 人間, エルフ, ドロウが該当する.
  • 2. クラスの二刀流スキルの限界が "熟練者 (P_SKILLED)" 以上である.
  • 3. クラスの二刀流スキルの限界が "入門者 (P_BASIC)" 以上であり, 元々の種族がドワーフか人間である.

よって, エルフやドロウの考古学者や野蛮人, (パッチが当たっている場合) ジェダイは, 二刀流できません. 種族が条件で二刀流できない場合, クラスの二刀流スキルの限界が熟練者以上であり, 変化時に二刀流できるモンスター (アレアックス, マリリス等) に変化した状態であれば, 二刀流できてスキルも上げられます.


エルフのジェダイで二刀流できなくてソースを読んだら, まさかの仕様だった.

posted by Takenoko at 14:52| Comment(1) | game | このブログの読者になる | 更新情報をチェックする

2021年09月14日

JSlash'EM-0.0.7E7F3-J0.2.1 Windows 用バイナリ (win32y, mswin&tty) 21/09/14 版を公開しました

タイトルの通りです. 以前のバイナリ に, さらに 3 つのパッチと, ジェダイパッチのタイルを追加しました.

21/09/16 追記: 許可して頂いた ので, ジェダイ用タイルパッチを公開しました. ここ , または下のパッチ一覧からダウンロードできます. また, 新しく当てたパッチの説明が不足していたので追加しました.
22/03/28 追記: mswin & tty 版の新しいバイナリがあります.
22/04/09 追記: 新しいバイナリがあります.


mswin & tty 版 (defaults.nh で切り替え可能)

jedi03.png tty01.png

ダウンロードリンク

Messron 氏 に, ジェダイパッチ関連のタイルを描いて頂きました.

コンパイル時に生成される, ジェダイ関連のタイルも含む全てのタイルの画像です. bmp から png に変換してあります.

tiles.png


win32y 版 (IBMGraphics を表示可能, フォントのサイズに応じてウィンドウのサイズが変わる)

patch_mlist.png patch_paranoid.png

ダウンロードリンク

上の画像の場合, 以下のようなフォント設定になっています.

OPTIONS=win32y_font_width_map:15
OPTIONS=win32y_font_height_map:30
OPTIONS=font_message:MS ゴシック,font_size_message:24
OPTIONS=font_menu:MS ゴシック,font_size_menu:24
OPTIONS=font_text:MS ゴシック,font_size_text:24
OPTIONS=font_status:MS ゴシック,font_size_status:24
OPTIONS=windowcolors:message white/green


上記バイナリは,
slashem-0.0.7E6F3
に,

以上のパッチを当てたものです. パッチの詳細は, リンク先と, http://nekokiss.seesaa.net/article/482964580.html を参照してください.

今回, 新しく当てたパッチは以下の 4 つです.

1) ジェダイパッチにタイルを追加するパッチ

ジェダイパッチ適用後, Messron 氏 に描いて頂いたタイルを追加するパッチです. また, sys/winnt/Makefile.gcc の問題を修正します. 英語版にも適用できると思います.

2) Paranoid Quit Patch

http://old.bamgames.org/Slashem/index.html の S0.0.7E7F1-Paranoid_1.0.txt を日本語化し, paranoid_wand_break オプションを追加したパッチです. #quit したり, 友好的な怪物を攻撃したり, 杖を折ったりといった重大な行為の確認に, y ではなく yes を要求するようにするオプションを追加します.

3) List Monsters Patch

http://old.bamgames.org/Slashem/index.html の S0.0.7E7F1-Listmon_1.0.txt を JSlash'EM-0.0.7E7F3-J0.2.1 に対応したパッチです. メッセージは英語のままです. #mlist と入力すると, #mlist コマンドで, 視認, または探知している怪物のリストを表示します.

4) 乱数発生器にMersenne Twisterを使用するパッチ(3.4.3-0.4用)

その名の通りのパッチです. NetHackの乱数の偏り問題 を読み, 当てる意義があると判断しました.


使用したいバイナリをダウンロードし, 展開し, フォルダ内の jslashem.exe を実行すると開始できます. defaults.nh を編集することで, 設定を変更できます. 詳しいことは, フォルダ内の jreadme.txt, jreadme2.txt, それ以外のテキストファイル, パッチのページ, win32y port のページ などを参考にして下さい.

posted by Takenoko at 15:55| Comment(1) | game | このブログの読者になる | 更新情報をチェックする

2021年09月08日

NetHack 3.4.3 タイル仕様

NetHack 3.4.3 のタイルは, win/share 下の monsters.txt, objects.txt, other.txt に, A から P までの 16 文字に色を割り当て, 幅16, 高さ16 の文字列で描かれています. コンパイル時に, 画像に変換されます.

色の定義

M が背景で, NetHack と Slash'EM では K の色が微妙に異なります.

A = (0, 0, 0)
B = (0, 182, 255)
C = (255, 108, 0)
D = (255, 0, 0)
E = (0, 0, 255)
F = (0, 145, 0)
G = (108, 255, 0)
H = (255, 255, 0)
I = (255, 0, 255)
J = (145, 71, 0)
# NetHack 3.4.3
K = (204, 79, 0)
# Slash'EM 0.0.7E7F3
K = (182, 71, 0)
L = (255, 182, 145)
M = (71, 108, 108)
N = (255, 255, 255)
O = (218, 218, 182)
P = (108, 145, 182)

実際のタイル

いくつかタイルの文字列と, 画像を列挙します. 以下は Slash'EM のもので, NetHack ではタイルが異なる場合があります.

em_giant_ant.png giant ant


  MMMMMMMMMMMMMMMM
  MMMMMMMMMMMMMMMM
  MMMMMMMMMMMMMMMM
  MMMMMMMMMMMMMMMM
  MMMMMMMMMMMMMMMM
  MMMMMMMMMMMMMMMM
  MMMMMMMMMMMMMMMM
  MMMMMMMJAJKKAMMM
  MMMMMJAAAKKJJAMM
  MMMMMAKJJAJJAAMM
  MMMKKAJJJAAAMMMM
  MMBKJAAAAAJJAMMM
  MMJBJAJAJAAMMMMM
  MMMMMAJAMJAMMMMM
  MMMMMMJAMJAMMMMM
  MMMMMMMMMMMMMMMM

em_samurai.png samurai


  MMMMMMMMMMMMMMMM
  MMMMMMMMMMMMMMMM
  MMMMMMMMMAAMMMMM
  MMMMMMMAAAMMMMMM
  MMMMMMAAAAAMMMMM
  MMMMMALFLFAMMMMM
  MMMMMALLLLAMMMMM
  MMMMMMALLAMMMMMM
  MMMMIIIAAIIIAAAM
  MMMMLDIIIIDLAAAM
  MMMMLABBBBALAAAM
  MMMMLABBBBALAAAM
  MMMMMMIDDDAAAAMM
  MMMMMMIDADAAMAMM
  MMMMMIIAMIIAMMMM
  MMMMMMMMMMMMMMMM

em_plate_mail.png plate mail


  MMMMMMMMMMMMMMMM
  MMMMMMMMMMMMMMMM
  MMMNMNNNOOOMOMMM
  MNMNNNNNOOOOOMOM
  MNMNNNNNOOOOOAOA
  MNMNNNNONOOOOAOA
  MMANNNOONNOOOAMA
  MMMNNNOONNOOOAMM
  MMMNNNNONOOOOAMM
  MMMMNNNNOOOOAAMM
  MMMNMNNNOOOAOAMM
  MMNNNANNOOAOOOAM
  MNNNOAMNOAAOOOOA
  MMNOAAMMMMMMOOAM
  MMMMMMMMMMMMMMMM
  MMMMMMMMMMMMMMMM

em_riding_gloves.png riding gloves / gauntlets of power


  MMMMMMMMMMMMMMMM
  MMMMMMMMMMMMMMMM
  MMMMMMMMMMMMMMMM
  MMMMKKJJAMMMMMMM
  MMMKKJJJJAMMMMMM
  MMKJJJJJJJAMMMMM
  MMCJJJJJJJAMMMMM
  MMMJJJJJJJJAMMMM
  MMMMJKJJJJJJAMMM
  MMMKAJJJJJJJAMMM
  MMMKKJJJJJJJJAMM
  MMMMJJJJJJJJJJAM
  MMMMMAAAJJJJJAAM
  MMMMMMMMAJJJAAMM
  MMMMMMMMMAAAMMMM
  MMMMMMMMMMMMMMMM

ラベル:nethack slash'em
posted by Takenoko at 14:26| Comment(0) | game | このブログの読者になる | 更新情報をチェックする

2021年08月18日

JSlash'EM-0.0.7E7F3-J0.2.1 Windows 用バイナリ (win32y, mswin&tty) を公開しました

昨日公開したパッチ と, JEDI パッチ, DUMP パッチを当てたバイナリを公開しました. NetHack のライセンスは, バイナリのソースも公開する必要があるようなので, それもアップロードしました.

21/09/05 追記: タイル版ジェダイパッチの注意点と, win32y 版のフォント設定例を追加した.


win32y 版 (IBMGraphics を表示可能, フォントのサイズに応じてウィンドウのサイズが変わる)

win32y08.png

21/09/14 追記: 新しいバージョンを公開したので, こちらからダウンロードして下さい.

上の画像の場合, 以下のようなフォント設定になっています.

OPTIONS=win32y_font_width_map:15
OPTIONS=win32y_font_height_map:30
OPTIONS=font_message:MS ゴシック,font_size_message:24
OPTIONS=font_menu:MS ゴシック,font_size_menu:24
OPTIONS=font_text:MS ゴシック,font_size_text:24
OPTIONS=font_status:MS ゴシック,font_size_status:24


mswin & tty 版 (defaults.nh で切り替え可能)

mswin02.png tty01.png

21/09/14 追記: 新しいバージョンを公開したので, こちらからダウンロードして下さい.

jreadme.txt には書き忘れたのですが, タイル表示の場合, ジェダイパッチ関連のタイルは "?" と表示されます. パッチにはタイルが含まれておらず, 私は(ドット)絵を描けないためです. 新バージョンでは, ジェダイパッチ関連のタイルも表示されます.



使用したいバイナリをダウンロードし, 展開し, フォルダ内の jslashem.exe を実行すると開始できます. defaults.nh を編集することで, 設定を変更できます. 詳しいことは, フォルダ内の jreadme.txt, jreadme2.txt, それ以外のテキストファイル, パッチのページ, win32y port のページ などを参考にして下さい.

posted by Takenoko at 15:07| Comment(18) | game | このブログの読者になる | 更新情報をチェックする

2021年08月17日

JSlash'EM-0.0.7E7F3-J0.2.1 用パッチを複数アップロードしました

以下のパッチは全て, JSlash'EM-0.0.7E7F3-J0.2.1 用です.
21/08/18 追記: 画像を追加, 説明文も一部追加, 修正.
22/04/09 追記: manypatch を Paranoid パッチを更新したパッチに差し替えた.
22/04/17 追記: autothrust パッチのバグを修正し, それを含む manypatch も更新した.

1) Yet Another Win32 Window Port for JSlash'EM-0.0.7E7F3-J0.2.1

win32y port を, MinGW gcc でコンパイルできるように Makefile を修正し, 他にもいくつか変更したパッチです. 元となったパッチとは違い, sys/winnt/setup.bat を実行する前にパッチを当てて下さい.

gcc (i686-win32-dwarf-rev0, Built by MinGW-W64 project) 8.1.0

でのコンパイルを確認しています.

win32y04.png win32y05.png win32y06.png win32y07.png

2) Autothrust Patch 1.10 for JSlash'EM-0.0.7E7F3-J0.2.1

http://www.phys98.homeip.net/~ide/jnethack.html

の jnethack-3.4.3-0.10-autothrust.patch.bz2 を JSlash'EM に対応したパッチです. このパッチを当てると, 一部キー割り当てが変更されます.

3) JSlash'EM-0.0.7E7F3-J0.2.1 バグ修正パッチ

Long worm crash bug fix 1.0

Acid dropping bug fix 1.0

Deallocated wielded objects bug fix 1.0

以上のパッチと, 衛士のテクニック, "愛馬をなだめる" が機能していないバグを修正するコード (https://github.com/moon-chilled/slashem9 からコピーしたコード) をまとめたパッチです.

4) HP and Pw status bar for JSlash'EM-0.0.7E7F3-J0.2.1

http://kobayasy.com/nethack/

の nethack-3.4.3_hppwbar-1.0.diff を JSlash'EM に対応し, オプション化したパッチです.

hppwbar01.pnghppwbar02.png

名前と称号の表示部分に, HP と PW を表すバーとアンダーラインが表示されるようになります. ただ, Windows 8.1 のコマンドプロンプトと, win32y port ではアンダーラインは表示されないようです. Linux の terminalでは両方表示されます. また, mswin port では, 名前の表示に問題が出るので, ON にしないほうがいいです. Windows 8.1 のコマンドプロンプトでも, ステータス表示のちらつきが目立つようになります.

5) Orange Floating Eye Patch for JSlash'EM-0.0.7E7F3-J0.2.1

"さまよう目" の色を, 青からオレンジに変更するだけのパッチです.

6) Dungeon Map Overview Patch for JSlash'EM-0.0.7E7F3-J0.2.1

http://old.bamgames.org/Slashem/index.html

の S0.0.7E7F2-dungeonmap.txt と

http://sakusha.s26.xrea.com/x/FHS/others.html

の D_OVERVIEW-3.0-J1.0.0.diff を組み合わせて日本語化したパッチです.

jslashem_overview.png

上の画像はウィザードモード時のスクリーンショットで, [mall] や [oracle], [minetn] は通常時は表示されません.

7) Short Item Prefix for JSlash'EM-0.0.7E7F3-J0.2.1

アイテムの修飾語の一部を短縮するパッチです.

8) SortLoot Patch for JSlash'EM-0.0.7E7F3-J0.2.1

https://www.benjamin-schieder.de/patchesslashem.html

の sortloot_0.1.patch と

http://f18.aaacafe.ne.jp/~jnethack/

の jnethack-sortloot-3.4.3-0.7.diff を組み合わせて日本語化したパッチです.

sortloot_none.png sortloot_loot.png

一枚目の画像が sortloot しない場合, 二枚目の画像が sortloot した場合です.

9) Statuscolors and Abbreviation Patch for JSlash'EM-0.0.7E7F3-J0.2.1

https://www.benjamin-schieder.de/patchesslashem.html

の S0.0.7E7F1-Statuscolor_1.0.txt を日本語化し, HP や PW の割合をカラーリングし, さらに表示幅がオーバーする際は表示する項目を少しずつ減らしたり, 言葉を省略するようにしたパッチです.

win32y_sc01.png win32y_sc02.png win32y_sc07.png win32y_sc08.png

下は, 実際にこうなることは無いでしょうが, ソースを書き換えて全部表示してみた画像です.

win32y_sc06.png

Linux の terminal と Windows の windowtype:tty, win32y での動作を確認しています. mswin ではまともに表示されなくなるので ON にしないほうがいいです. Windows 8.1 のコマンドプロンプトでも, ステータス表示のちらつきが目立つようになります.

10) jslashem-0.0.7E7F3-J0.2.1-manypatch_1.20_EUC-JP_LF.patch

上記のパッチの内,

  • jslashem-0.0.7E7F3-J0.2.1-statuscolors_EUC-JP_LF.patch
  • jslashem-0.0.7E7F3-J0.2.1-sortloot_EUC-JP_LF.patch
  • jslashem-0.0.7E7F3-J0.2.1-overview_EUC-JP_LF.patch
  • jslashem-0.0.7E7F3-J0.2.1-shortprefix_EUC-JP_LF.patch
  • jslashem-0.0.7E7F3-J0.2.1-hppwbar_EUC-JP_LF.patch
  • jslashem-0.0.7E7F3-J0.2.1-autothrust_EUC-JP_LF.patch
と, http://jslashem.osdn.jp/ の jslashem-0.0.7E7F3-J0.2.1-dump1.4.diff.gz をまとめたパッチです.

21/09/14 追記: 以下のパッチも追加. こちら で公開しています.

  • jslashem-0.0.7E7F3-J0.2.1-paranoid_EUC-JP_LF.patch
  • jslashem-0.0.7E7F3-J0.2.1-listmon_EUC-JP_LF.patch

posted by Takenoko at 12:45| Comment(0) | game | このブログの読者になる | 更新情報をチェックする

2021年07月25日

JSlash'em にジェダイパッチを適用した Windows バイナリ (win32y) をアップロードしました

win32y01.png

win32y02.png

win32y03.png

Yet Another Win32 Window Port のバイナリも作成しました. 画像のように, IBMGraphics を表示でき, 壁や泉, 溶岩などの見た目が変わります. ただ, 作成環境 (Windows 8.1 Home 64bit) 以外での起動確認ができないので, 動作するかどうか不安です.

21/09/08 追記: 新しいファイルがあるので, ここからダウンロードして下さい.

defaults.nh に, フォントサイズの変更方法などが書いてあります. menucolors を有効にできるようにして, map_mode で選択できるサイズを増やしてあります.

zip 内の jreadme.txt にもありますが, JSLASH'EM-0.0.7E7F3-J0.2.1 に Dump Patch, Jedi Patch を適用し, 衛士のテクニック "愛馬をなだめる" が機能していないバグを修正したものです. 多分直っていると思います. また, セーブデータをロードすると, 二枚目の画像のようにメッセージ表示部の下にゴミが残ります. できれば直します.

Borland C++ Compiler 5.5でのコンパイルしか確認していません

と書いてありましたが, なんとか gcc 8.1.0 でもコンパイルに成功しました. Makefile の勉強になりました.

動作した場合にも, しなかった場合にも, 動作状況と環境の報告をしていただけるとうれしいです.

posted by Takenoko at 10:56| Comment(0) | game | このブログの読者になる | 更新情報をチェックする

2021年07月04日

JSlash'em にジェダイパッチを適用した Windows バイナリ (mswin, tty) をアップロードしました

mswin01.png
mswin_jedi01.png
mswin_tty01.png

タイル表示できるバイナリも作成しました. 上の画像のように文字による表示もできます. ただ, 作成環境 (Windows 8.1 Home 64bit) 以外での起動確認ができないので, 動作するかどうか不安です.

21/09/08 追記: 新しいファイルがあるので, ここからダウンロードして下さい.

zip 内の jreadme.txt にもありますが, JSLASH'EM-0.0.7E7F3-J0.2.1 に Dump Patch, Jedi Patch を適用し, 衛士のテクニック "愛馬をなだめる" が機能していないバグを修正したものです. 多分直っていると思います. また, 残念ながら, タイル表示した場合, ジェダイパッチ関連のタイルは全て '?' と表示されます. パッチ自体にはタイルが用意されておらず, さらに, 私は絵を描けないためです.

動作した場合にも, しなかった場合にも, 動作状況と環境の報告をしていただけるとうれしいです.

2021/07/17 追記
exe に不具合があったため, ファイルを差し替えた.

posted by Takenoko at 16:21| Comment(0) | game | このブログの読者になる | 更新情報をチェックする

2021年06月12日

JSlash'em にジェダイパッチを適用した Windows バイナリをアップロードしました

jedi01.png
jedi02.png

タイトルの通りです. ただ, 作成環境 (Windows 8.1 Home 64bit) 以外での起動確認ができないので, 動作するかどうか不安です. とりあえずは tty のみで, タイル表示はできません. タイル表示できるバイナリも作成しました.

21/09/08 追記: 新しいファイルがあるので, ここからダウンロードして下さい.

zip 内の jreadme.txt にもありますが, JSLASH'EM-0.0.7E7F3-J0.2.1 に Dump Patch, Jedi Patch を適用し, 衛士のテクニック "愛馬をなだめる" が機能していないバグを修正したものです. 多分直っていると思います.

動作した場合にも, しなかった場合にも, 動作状況と環境の報告をしていただけるとうれしいです.


2021/06/13 記事をほぼ書き直した.
2021/07/04 コンパイルの手順を一部修正, zip ファイルを差し替え.
2021/07/17 コンパイルの手順を一部修正, MSWIN 版作成方法を追記, zip ファイルを差し替え, リンク追加.


以下はコンパイルの手順です. 自分でバイナリを作成するのでなければ, 読む必要はありません.

1. MSYS2 をインストールする
https://www.msys2.org/ から
msys2-x86_64-*.exe
をダウンロードし, インストールする.
Path はデフォルトの C:\msys64 とする.
/home は環境変数 HOME の場所となる.
MSYS を起動, pacman で Y/n を問われたら, 全て Y
pacman -Syu
MSYS を閉じ, 再び起動
pacman -Su
MSYS を閉じ, 再び起動
pacman -S gzip
pacman -S tar
pacman -S patch
pacman -S make
wget https://osdn.jp/projects/nkf/downloads/70406/nkf-2.1.5.tar.gz
tar zxvf nkf-2.1.5.tar.gz
cd nkf-2.1.5
make
make install
cd ..

2. mingw-w64 32bit をインストールする
http://mingw-w64.org/doku.php/download/mingw-builds
で, Installation: Sourceforge をクリックするとページ遷移し, インストーラが自動的にダウンロードされます.
mingw-w64-install.exe
を実行し,
Ver 8.10
i686
win32 (posix でもよいが, win32 のが速いらしい)
dwarf (sjlj でもよいが, dwarf のが速いらしい)
0
を選択します.
デフォルトのインストールパスが長いので,
C:\mingw-w64\i686-8.1.0-win32-dwarf-rt_v6-rev0
に変更します.コマンドプロンプトを開き,
set path=C:\mingw-w64\i686-8.1.0-win32-dwarf-rt_v6-rev0\mingw32\bin
gcc --version
と入力し,
gcc (i686-win32-dwarf-rev0, Built by MinGW-W64 project) 8.1.0
と表示されたら成功です.

3. 必要なファイルを用意する
カレントディレクトリが home であることを確認する.
mkdir jslashem
cd jslashem
http://jslashem.osdn.jp/ から
se007e7f3.tar.gz
jslashem-0.0.7E7F3-J0.2.1.diff.gz
jslashem_jedi_0.5.patch
を, https://www.mediafire.com/file/39cjfbg5xsb1dz7/jslashem_tech.patch/file から
jslashem_tech.patch
を home/jslashem にダウンロードする.

MSWIN 版を作成する場合,
https://www.mediafire.com/file/garbvtmofa5zbjv/jslashem-0.0.7E7F3-J0.2.1-jedi_tiles_EUC-JP_LF.patch/file
もダウンロードする.

4. Patch を当てる
tar xfz se007e7f3.tar.gz
mv slashem-0.0.7E7F3 jslashem-build
cd jslashem-build
zcat ../jslashem-0.0.7E7F3-J0.2.1.diff.gz | patch -p1
zcat ../jslashem-0.0.7E7F3-J0.2.1-dump1.4.diff.gz | patch -p1
patch -p1 < ../jslashem_jedi_0.5.patch
nkf -s ../jslashem_tech.patch | patch -p0
# MSWIN版を作成する場合, 以下の一行も実行
nkf -s ../jslashem-0.0.7E7F3-J0.2.1-jedi_tiles_EUC-JP_LF.patch | patch -p1
MSYS を閉じる

5. コンパイル
コマンドプロンプトを起動し, home へ移動
cd jslashem/jslashem-build/sys/winnt
setup.bat

5A. JEDI パッチのエラーを修正 (jslashem-0.0.7E7F3-J0.2.1-jedi_tiles_EUC-JP_LF.patch を当てていない場合)
src/Makefile 1489行目末尾の
 \
の二文字を削除する.

5B. 最適化レベルを上げる (行わなくてもよい)
src/Makefile 216行目を
CFLAGS = -c -O2 -I../include $(DLBFLG)
に変更

5C. TILE 使用準備 (MSWIN 版を作成する場合)
src/Makefile
USE_MSWIN を有効化

include/config.h
#define MSWIN_GRAPHICS
を有効化

win\share\*.txtの改行コードを全てCR-LF(\r\n)に変更。

6. コンパイル
cd ../../src
set path=C:\mingw-w64\i686-8.1.0-win32-dwarf-rt_v6-rev0\mingw32\bin
mingw32-make
mingw32-make install
home/jslashem/jslashem-build/binary ディレクトリを任意の場所に移動してください.

posted by Takenoko at 16:51| Comment(0) | game | このブログの読者になる | 更新情報をチェックする

2020年07月31日

GearHead SDL 版を Linux Mint 18.3 32bit でコンパイルしました

5 年ぶり二度目. あのとき, 手順をメモしておかなかったおかげで, 5 年後の自分が苦労している. もう苦労したくないので, 今度は書いておきます.

参考ページ http://www.fenix.ne.jp/~G-HAL/scribble/gearhead/gearhead1.scribble#build

1. libiconv をインストール
https://www.kkaneko.jp/tools/ubuntu/gcc10.html の "libiconv のインストール" に書いてある通りにします.
以下はコピー.
$ cd /tmp
$ wget https://ftp.gnu.org/gnu/libiconv/libiconv-1.16.tar.gz
$ rm -rf libiconv-1.16
$ tar -xvzof libiconv-1.16.tar.gz
$ cd libiconv-1.16
$ mkdir build
$ cd build
$ ../configure --with-mpfr --with-gmp --prefix=/usr/local --enable-static --enable-shared
$ make -j2
$ sudo make install

2. /usr/local/lib/ 以下のライブラリが使えるようにする
http://weble.org/2011/12/20/ubuntu-ld-so-conf
を参考に作業します. 以下はほぼコピー.
私は vim を使いましたが, 他のエディタでも構いません.
$ sudo vim /etc/ld.so.conf
次の一行を追加.
include /usr/local/lib
設定を反映させる.
$ sudo ldconfig

3. SDL-ttf をインストール
$ sudo apt install libsdl-ttf2.0-dev

4. smpeg をインストール
$ sudo apt install libsmpeg-dev
他にもインストールする必要があるライブラリがあるはずですが,
私の環境ではすでにインストールされていたようです.

5. Free Pascal をインストール.
$ sudo apt install fpc-3.0.0

6. コンパイル
$ cd ~
$ wget https://sourceforge.net/projects/gearhead/files/gearhead/1.100/gh-1100-src.zip/download -O gh-1100-src.zip
$ wget http://www.fenix.ne.jp/~G-HAL/scribble/gearhead/GearHead1-I18N.data.jp.zip
$ wget http://www.fenix.ne.jp/~G-HAL/scribble/gearhead/GearHead1-I18N.image.zip
$ wget http://www.fenix.ne.jp/~G-HAL/scribble/gearhead/GearHead1-I18N.sound.zip
$ wget http://www.fenix.ne.jp/~G-HAL/scribble/gearhead/GearHead1-I18N.src.zip
$ unzip gh-1100-src.zip
$ mv GearHead GH1
$ unzip -d GH1 GearHead1-I18N.src.zip
$ unzip -o GearHead1-I18N.image.zip
$ unzip -o GearHead1-I18N.sound.zip
$ unzip -o GearHead1-I18N.data.jp.zip
$ cd GH1/build/xterm-boxdrawing
$ mv * ../../xterm-boxdrawing
$ cd ..
$ rm -r xterm-boxdrawing
$ mv * ../
$ rm -r build
$ /bin/sh ./build.sh sdl clean build nolibiconv_plug nolibc_iconv
$ mv build.sdl.Linux_athlon/gharena gharena
$ rm -r build.sdl.Linux_athlon

7. 環境変数を設定する
$HOME/.profile に環境変数 GEARHEAD_LANG を追加します.
下の一行は vim を使う場合.
$ vim ~/.profile
以下三行を追加します.

if [ -d "$HOME/GH1" ] ; then
    export GEARHEAD_LANG=ja_JP.UTF-8
fi

GEARHEAD_LANG の値については,
環境によって適切なものを選ぶ必要があるはずです.
以下のコマンドで設定を反映.
$ source ~/.profile

8. gharena.cfg
$ ./gharena
起動すると, ほとんどの文字が四角になっています.
一番下の項目で Enter を押して終了します.
起動したことで $HOME/.config/gharena/ に
gharena.cfg が作製されます.
GH1/gharena.cfg.jp_debianlinux を参考にフォントを変更します.
もう一度
$ ./gharena
と入力し起動すると, 文字化けは解消しているはずです.
linuxgh1title.png

これで完成です.

9. 次回以降の起動方法

$ cd ~
$ cd GH1
$ ./gharena
で起動できます.

posted by Takenoko at 20:59| Comment(0) | game | このブログの読者になる | 更新情報をチェックする

2020年07月26日

Python 3 で, Ogg Vorbis と Wave を再生する Player を書きました 続き

pysoundsample.png

前回 の続きです. 上の画像は, sample の gui です.

Ogg Vorbis ファイルと, Wave ファイルを複数同時に再生できるプレイヤーです. MIT License です. 使用方法は, zip 内の readme.txt と, sample.py に書いてあります. 下にあるコードも, zip 内に全て入っています.

マルチスレッドによるエラーを対策したり, wave の再生終了まで待機できるようにしたりしました. 他の変更点はコード冒頭 update.txt に書いてあります.


'''
thread2.py  v1.1

参考ページ: Python スレッドの停止と再開の簡易サンプル
https://qiita.com/BlueSilverCat/items/44a0a2a3c45fc3e88b19
'''

from threading import Thread, Event

class Thread2(Thread):

    def __init__(self, daemon = True, callback = 0):
        super().__init__(daemon = daemon)
        self.started = Event()
        self.alive = 1
        self.active = 1
        self.callback = callback
        self.start()

    def __del__(self):
        self.kill()

    def begin(self):
        self.started.set()
        self.active = 1

    def end(self):
        self.active = 0
        self.started.clear()
        if callable(self.callback):
            self.callback()

    def kill(self):
        self.started.set()
        self.active = 0
        self.alive = 0
        self.join()




'''
soundthread.py  v1.2
'''

from threading import Lock

from pyaudio import PyAudio

from .thread2 import Thread2

class SoundThread(Thread2):

    __lock = Lock()

    def __init__(self, callback):
        super().__init__(callback = callback)

    def close(self):
        self.stream.stop_stream()
        self.stream.close()
        self.p.terminate()

    def kill(self):
        self.close()
        self.end()
        super().kill()

    def open(self, format, channels, rate):
        SoundThread.__lock.acquire()
        self.p = PyAudio()  # 使い回すとエラーが出ることがある
        self.stream = self.p.open(format = format,
                                  channels = channels,
                                  rate = rate,
                                  output = True)
        SoundThread.__lock.release()

    def run(self):
        while self.active:
            self.play()  # Sub Class で実装すること
            self.started.wait()




'''
player.py  v1.0
'''

class Player:

    def __init__(self, enabled):
        self.__enabled = enabled  # False で関数呼び出しを無視する

    def is_enabled(self):
        return self.__enabled

    def on(self):
        if self.__enabled:
            return
        self.__enabled = 1

    def off(self):
        if not self.__enabled:
            return
        self.__enabled = 0




'''
vorbisplayer.py  v1.3

Copyright (c) 2020 Takenoko (http://nekokiss.seesaa.net/)
Released under the MIT license.
see https://opensource.org/licenses/MIT

PyAudio, PyOgg, audio-metadata が install されている必要があります.
'''

import time
from threading import Event

import pyogg as po
import pyaudio as pa

from .soundthread import SoundThread
from .player import Player

class Vorbis:

    def __init__(self, ogg, chunk, loop, tagloop):
        self.ogg = ogg
        self.loop = loop
        self.file = po.VorbisFile(ogg)
        '''
        bit rate size
        1, 3, 4 等の場合もあるかもしれないが,
        取得方法がわからないので 2 で固定
        '''
        self.sampwidth = 2
        # block size
        self.block = (self.sampwidth
                      * self.file.channels)
        self.format = pa.get_format_from_width(self.sampwidth)
        self.cache = {}
        '''
        Loop Tag
        '''
        self.loopstart = 0
        self.loopend = (self.file.buffer_length
                        * self.block)
        if loop and tagloop:
            import audio_metadata as am
            md = am.load(ogg)
            if 'tags' in md and 'loopstart' in md.tags:
                self.loopstart = int(md.tags.loopstart[0]) * self.block
                if 'looplength' in md.tags:
                    self.loopend = (int(md.tags.looplength[0])
                                    * self.block + self.loopstart)
        self.chunk = chunk
        if self.loopend - self.loopstart < self.chunk:
            self.chunk = self.loopend - self.loopstart

    def getdata(self, start):
        if start not in self.cache:
            end = start + self.chunk
            if end > self.loopend:
                data = self.file.buffer[start:self.loopend]
                if self.loop:
                    end = self.loopstart + end - self.loopend
                    data += self.file.buffer[self.loopstart:end]
                else:
                    end = -1
                self.cache[start] = data, end
            else:
                self.cache[start] = self.file.buffer[start:end], end
        return self.cache[start]


class VorbisThread(SoundThread):

    def __init__(self, vorbis, callback):
        self.vorbis = vorbis
        self.paused = Event()
        super().__init__(callback)

    def rebegin(self):
        self.paused.set()
        if self.active:
            self.end()
            # sleep しないと曲の先頭に戻らないことがある
            time.sleep(0.1)
        self.begin()

    def play(self):
        self.paused.set()
        self.open(self.vorbis.format, self.vorbis.file.channels,
                  self.vorbis.file.frequency)
        start = 0
        while self.active:
            data, start = self.vorbis.getdata(start) 
            self.stream.write(data)
            self.paused.wait()
            if start < 0:
                self.end()
        self.close()


class VorbisPlayer(Player):

    def __init__(self, chunk = 1024, loop = 1, tagloop = 1,
                 enabled = 1):
        super().__init__(enabled)
        self.__chunk = chunk
        self.__vorbises = {}
        self.__thread = 0
        self.__loop = loop        # True で loop する
        self.__tagloop = tagloop  # True で LOOPSTART & LOOPLENGTH を使う

    def off(self):
        super().off()
        self.stop()

    def play(self, ogg, callback = 0):
        if not self.is_enabled():
            return
        if ogg in self.__vorbises:
            v = self.__vorbises[ogg]
        else:
            v = Vorbis(ogg, self.__chunk, self.__loop, self.__tagloop)
            self.__vorbises[ogg] = v
        if self.__thread:
            self.__thread.vorbis = v
            self.__thread.callback = 0
            self.__thread.rebegin()
            self.__thread.callback = callback
        else:
            self.__thread = VorbisThread(v, callback)

    def stop(self):
        if self.__thread and self.__thread.active:
            self.__thread.end()

    def pause(self):
        if not self.is_enabled():
            return
        if self.__thread:
            self.__thread.paused.clear()

    def resume(self):
        if not self.is_enabled():
            return
        if self.__thread:
            self.__thread.paused.set()




'''
waveplayer.py  v1.4

Copyright (c) 2020 Takenoko (http://nekokiss.seesaa.net/)
Released under the MIT license.
see https://opensource.org/licenses/MIT

PyAudio が install されている必要があります.
'''

from threading import Event

import pyaudio as pa
import wave

from .soundthread import SoundThread
from .player import Player

class Wave:

    def __init__(self, wav, chunk):
        self.file = wav
        with wave.open(wav, 'rb') as wf:
            self.format = pa.get_format_from_width(wf.getsampwidth())
            self.channels = wf.getnchannels()
            self.rate = wf.getframerate()
            self.buffer = []
            while 1:
                data = wf.readframes(chunk)
                if len(data) <= 0:
                    break
                self.buffer.append(data)


class WavThread(SoundThread):

    def __init__(self, wp, wav, callback):
        self.wp = wp
        self.wav = wav
        super().__init__(callback)

    def close(self):
        super().close()
        self.wp._WavePlayer__blocked.set()

    def play(self):
        self.open(self.wav.format, self.wav.channels,
                  self.wav.rate)
        for data in self.wav.buffer:
            if self.active:
                self.stream.write(data)
        if self.active:
            self.end()
        self.close()


class WavePlayer(Player):

    def __init__(self, chunk = 1024, maxthreads = 8, enabled = 1):
        super().__init__(enabled)
        self.__chunk = chunk
        self.__waves = {}
        self.__threads = []
        self.__blocked = Event()
        if maxthreads < 1:
            maxthreads = 1
        self.__maxthreads = maxthreads  # 最大同時再生 Thread 数

    def __getwav(self, wav):
        if wav not in self.__waves:
            self.__waves[wav] = Wave(wav, self.__chunk)
        return self.__waves[wav]

    def off(self):
        super().off()
        self.stopall()

    def getmaxthreads(self):
        return self.__maxthreads

    def setmaxthreads(self, v):
        if v < 1:
            return
        over = min(self.__maxthreads, len(self.__threads)) - v
        if over > 0:
            for i in range(over):
                t = self.__threads.pop(0)
                if t.active:
                    t.end()
                self.__threads.append(t)
        self.__maxthreads = v

    def play(self, wav, block = 0, callback = 0):
        if not self.is_enabled():
            return
        if block:
            self.__blocked.clear()
        for i, t in enumerate(self.__threads):
            if i < self.__maxthreads:
                if not t.active:
                    t.wav = self.__getwav(wav)
                    t.callback = callback
                    t.begin()
                    break
        else:
            if len(self.__threads) >= self.__maxthreads:
                t = self.__threads.pop(0)
                t.end()
                t.wav = self.__getwav(wav)
                t.callback = callback
                t.begin()
            else:
                t = WavThread(self, self.__getwav(wav), callback)
            self.__threads.append(t)
        if block:
            self.__blocked.wait()

    def stop(wav):
        for t in self.__threads:
            if t.wav.file == wav and t.active:
                t.end()
                return 1
        return 0

    def stopall(self):
        for t in self.__threads:
            if t.active:
                t.end()



vwp200727.zip

スレッドについて, 少しだけわかった気がします.

20/07/27 追記

ファイルを差し替えました. 更新履歴を, ソースコードではなく update.txt にまとめただけですが. あと, この記事にコードを貼り付けました. コードに問題があった場合, 指摘して頂けるとありがたいです.

20/07/28 追記

説明文を追加.

ラベル:Python download
posted by Takenoko at 09:42| Comment(0) | programming | このブログの読者になる | 更新情報をチェックする

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。


×

この広告は90日以上新しい記事の投稿がないブログに表示されております。