mieki256's diary



2024/04/24(水) [n年前の日記]

#1 [comic] 「ダンジョン飯」12-14巻を読んだ

あまりに面白くて、とうとう最終巻まで読んでしまった…。色んな面でタイトルに偽り無し、だった気がする…。しかしよくまあこんな設定を思いつくもんだなと…。着眼点も、思考の方向性も、非凡極まりない…。それはともかく、これって最後までアニメ化できるんだろうか…。

2023/04/24(月) [n年前の日記]

#1 [cg_tools] 画像生成AIで着色処理をしたい

画像生成AI、Stable Diffusion web UIを使って、線画に着色処理をしてみたい。

環境は以下。
着色処理をするには、ControlNet を Stable Diffusion web UI にインストールしておく必要があるらしい。

ControlNet用の、canny か Anime Lineart の追加データが必要らしいので、それも入手して、(Stable Diffusion web UIインストールフォルダ)\extensions\sd-webui-controlnet\models\ 以下にコピーしておく。

線画を生成してみる :

着色処理をするためには線画が必要だけど、線画も Stable Diffusion web UI で生成できてしまうらしい。

_【画像生成AI】線画描画LoRAを使おう!(Anime Lineart Style LoRA)|ステスロス|note
_【Stable Diffusion】線画を生成できるLoRA | ジコログ
_Anime Lineart / Manga-like (...) Style - v3.0 manga-like | Stable Diffusion LoRA | Civitai
_andite/anything-v4.0 - Hugging Face

Anime Lineart / Manga-like Style というLORAデータ(追加学習モデルデータ)があれば、線画の生成ができる模様。

このLORAは、学習モデルデータ、Anything V4.5 に最適化しているとのことなので、そちらのモデルデータも入手する。つまり、以下のファイルをDLすることになる。
  • anything-v4.5.safetensors : (Stable Diffusion web UIインストールフォルダ)\models\Stable-diffusion\ にコピー。
  • anything-v4.0.vae.pt : (Stable Diffusion web UIインストールフォルダ)\models\VAE\ にコピー。
  • animeLineartMangaLike_v30MangaLike.safetensors : (Stable Diffusion web UIインストールフォルダ)\models\Lora\ にコピー。

Stable Diffusion web UI を起動して、以下のモデルデータ、VAEにしておく。
  • 学習モデルデータ : anything-v4.5.safetensors
  • VAE : anything-v4.0.vae.pt

とりあえず、txt2img上で、生成できるかテスト。

00063-3871747518_anything-v4.5.png
1 girl, city background,
Negative prompt: EasyNegative, (worst quality:1.4), (low quality:1.4), (normal quality:1.4), lowers,
Steps: 20, Sampler: DPM++ SDE Karras, CFG scale: 5, Seed: 3871747518, Size: 512x512, Model hash: 1d1e459f9f, Model: anything-v4.5

フツーに色がついてる状態で生成された。


Anime Lineart Style を有効にして線画が生成されるか確認してみる。プロンプトに <lora:animeLineartMangaLike_v30MangaLike:1> を入れて有効化。かつ、トリガーワードの lineart を入れてみた。

00064-3871747518_animelineartmangalike_v30.png
1 girl, city background, <lora:animeLineartMangaLike_v30MangaLike:1>, lineart,
Negative prompt: EasyNegative, (worst quality:1.4), (low quality:1.4), (normal quality:1.4), lowers,
Steps: 20, Sampler: DPM++ SDE Karras, CFG scale: 5, Seed: 3871747518, Size: 512x512, Model hash: 1d1e459f9f, Model: anything-v4.5

さすがに構図等は変わってしまったけど、めっちゃ線画っぽくなった。


何度か生成してみたけど、どれもイイ感じ。とりあえず、今回は以下の生成画像を使って着色処理をしてみたい。

00072-2228530729_animelineartmangalike_v30.png
1 girl, school uniform, upper body, in room, from side, <lora:animeLineartMangaLike_v30MangaLike:1.0>, lineart,
Negative prompt: EasyNegative, (worst quality:1.4), (low quality:1.4), (normal quality:1.4), lowers,
Steps: 40, Sampler: DPM++ SDE Karras, CFG scale: 5, Seed: 2228530729, Size: 512x512, Model hash: 1d1e459f9f, Model: anything-v4.5

着色処理 :

得られた線画を元にして、着色処理を試してみる。以下のページが参考になった。

_「ControlNet」の『openpose』と『canny』を知ってしまった回。【Stable Diffusion web UI】 | note_lilish
_【ControlNet】自分の作画をAIで自動着彩!cannyを堪能しまくった回。(Stable Diffusion) | note_lilish
_AIで適当な線画を清書し、さらに色を塗って高品質なイラストに仕上げる方法【ControlNet活用術】 | くろくまそふと

txt2imgタブで、ControlNet の画像入力欄に、先ほど生成した線画をドラッグアンドドロップ。
  • ControlNetを有効化。
  • プリプロセッサ (Preprocessor) : invert (from white bg & black line)、もしくは canny
  • モデル (Model) : control_v11p_sd15_canny

線画が、線が黒、背景が白の場合、プリプロセッサで、invert を選んで白黒を反転する必要があるらしい。本来、ControlNet には、背景画が黒、線が白を渡さないといかんようだなと…。ただ、プリプロセッサで canny を選んだ場合も、それらしい結果を生成できた。

以下は、プリプロセッサで「canny」を選んだ場合。

00073-1628600786_controlnet_canny.png
1 girl, school uniform, upper body, in room, from side,
Negative prompt: EasyNegative, (worst quality:1.4), (low quality:1.4), (normal quality:1.4), lowers,
Steps: 40, Sampler: DPM++ SDE Karras, CFG scale: 5, Seed: 1628600786, Size: 512x512, Model hash: 1d1e459f9f, Model: anything-v4.5, ControlNet Enabled: True, ControlNet Module: canny, ControlNet Model: control_v11p_sd15_canny [d14c016b], ControlNet Weight: 1, ControlNet Guidance Start: 0, ControlNet Guidance End: 1


以下は、プリプロセッサで「invert」を選んだ場合。

00075-2086267769_controlnet_canny.png
1 girl, school uniform, upper body, in room, from side,
Negative prompt: EasyNegative, (worst quality:1.4), (low quality:1.4), (normal quality:1.4), lowers,
Steps: 40, Sampler: DPM++ SDE Karras, CFG scale: 5, Seed: 2086267769, Size: 512x512, Model hash: 1d1e459f9f, Model: anything-v4.5, ControlNet Enabled: True, ControlNet Module: invert (from white bg & black line), ControlNet Model: control_v11p_sd15_canny [d14c016b], ControlNet Weight: 1, ControlNet Guidance Start: 0, ControlNet Guidance End: 1


ということで、Stable Diffusion web UI + ControlNet + cannyモデルデータを使って、線画に着色できることがわかった。

実写寄りにしてみたい :

せっかくだから、ここから実写寄りの画像を生成できるか試してみたい。学習モデルデータを実写寄りのデータに切り替えてみる。

  • Model : chilloutmix_.safetensors
  • VAE : vae-ft-mse-840000-ema-pruned.safetensors

txt2imgタブ上で作業する。ControlNet に、前述の線画を渡しておいて、プリプロセッサで「canny」を選んでみた。

00104-3050420311_t2i_canny_canny.png
1 girl, school uniform, upper body, in room, from side, masterpiece, best quality, highres,
Negative prompt: EasyNegative, (worst quality:1.4), (low quality:1.4), (normal quality:1.4), lowers,
Steps: 25, Sampler: DPM++ SDE Karras, CFG scale: 5, Seed: 3050420311, Face restoration: CodeFormer, Size: 512x512, Model hash: a757fe8b3d, Model: chilloutmix_, ControlNet Enabled: True, ControlNet Module: canny, ControlNet Model: control_v11p_sd15_canny [d14c016b], ControlNet Weight: 1, ControlNet Guidance Start: 0, ControlNet Guidance End: 1

漫画的な線画に引き摺られてしまったのか、キモい感じの画像が生成されてしまった…。これはこれでアリな絵柄なのかもしれんけど…。


プリプロセッサを「invert」にしてみた。

00101-41314358_t2i_invert_canny.png
1 girl, school uniform, upper body, in room, from side,
Negative prompt: EasyNegative, (worst quality:1.4), (low quality:1.4), (normal quality:1.4), lowers,
Steps: 25, Sampler: DPM++ SDE Karras, CFG scale: 5, Seed: 41314358, Face restoration: CodeFormer, Size: 512x512, Model hash: a757fe8b3d, Model: chilloutmix_, ControlNet Enabled: True, ControlNet Module: invert (from white bg & black line), ControlNet Model: control_v11p_sd15_canny [d14c016b], ControlNet Weight: 1, ControlNet Guidance Start: 0, ControlNet Guidance End: 1

00103-2960943004_t2i_invert_canny.png

こちらはなかなかイイ感じなのではなかろうか。


ただ、ここまで来ると、img2imgタブ上で処理したほうが良いのかもしれない。以下は、img2img に着色済み画像を渡して生成してみた事例。元の線画から結構かけ離れてしまったけど、見た目は随分自然な感じになった。

00075-2086267769-00011-3832661318.i2i.png
1 girl, school uniform, upper body, in room, from side, masterpiece, best quality, highres,
Negative prompt: EasyNegative, (worst quality:1.4), (low quality:1.4), (normal quality:1.4), lowers,
Steps: 25, Sampler: DPM++ SDE Karras, CFG scale: 5, Seed: 3832661318, Face restoration: CodeFormer, Size: 512x512, Model hash: a757fe8b3d, Model: chilloutmix_, Denoising strength: 0.6

余談 :

線画を実写風に変換するところまで作業してみて思ったけど、ひょっとして、画像生成AIを使えば、机の前に座りながら実写風の漫画作品も作れてしまうのではなかろうか…? いやまあ、既に誰かが挑戦してそうな気もするけど。

そこまで来ると、ネームを描いて構成して最終原稿を召喚した人に著作権がちゃんと発生しそうな気もするけど、どうなんだろう。

2023/04/25追記 :

実写風の漫画が作れるのでは、などと書いてみたものの、その後色々試してるうちに、考えが甘かったことに気づいた。画像生成AIは、絵柄、というかキャラの顔立ちを統一させるのが難しいから、漫画やアニメのようなメディアではキャラの描画に使えないよな…。ある程度絵柄が統一されてないと、その手のジャンルでは使い物にならない…。

2022/04/24() [n年前の日記]

#1 [python] PyAutoGUIを少しだけ試用

Python + PyAutoGUI でも操作の自動化ができるという話をどこかで見かけたので手元の環境で少し試用。

環境は Windows10 x64 21H2 + Python 3.9.12 64bit。

インストール。 :

インストールは以下。
pip install pyautogui
PyAutoGUI 0.9.53 がインストールされた。

また、以下のモジュールも依存関係でインストールされた。
  • MouseInfo 0.1.3
  • PyGetWindow 0.0.9
  • PyMsgBox 1.0.9
  • pyperclip 1.8.2
  • PyRect 0.2.0
  • PyScreeze 0.1.28
  • pytweening 1.0.4

PDFの自動翻訳をしやすくする処理が書けた。 :

色々試していたところ、昨日、AutoIt を使って作成したスクリプトと似たような処理を、PyAutoGUI でも書けた気がする。

_英文PDFの自動翻訳をAutoIt3を使って少し快適にした

_04_copypaste.py
import pyautogui as ag
import pygetwindow as gw
import pyperclip
import sys
import time

pdfviewer = "Reader DC"
deepl = "DeepL "


def activate_window(w):
    """Activate appli window."""
    try:
        w.activate()
    except Exception:
        w.minimize()
        w.restore()
    time.sleep(0.35)


def get_window(name):
    hwnds = gw.getWindowsWithTitle(name)
    w = None
    if hwnds != []:
        w = hwnds[0]
    else:
        print("Error: Not found %s" % name)
    return w


def main():
    w = get_window(pdfviewer)
    if w is None:
        sys.exit()

    activate_window(w)
    ag.hotkey("ctrl", "c")
    time.sleep(0.25)

    # replace CRLF to space
    txt = pyperclip.paste()
    newtxt = " ".join(txt.splitlines())
    # newtxt = txt.replace("\n", " ")
    pyperclip.copy(newtxt)

    # print(newtxt)

    w = get_window(deepl)
    if w is None:
        sys.exit()

    activate_window(w)
    ag.hotkey("ctrl", "a")
    time.sleep(0.25)
    ag.hotkey("delete")
    time.sleep(0.25)
    ag.hotkey("ctrl", "v")
    time.sleep(0.25)


if __name__ == '__main__':
    main()

後は、このPythonスクリプトを、何かしらのランチャーに登録して起動できるようにすれば、1クリックでPDF上の選択テキストを自動翻訳できるのではないかな…。

一応、tkinter も使って、GUI版も書いてみた。

_05_copypaste_gui.pyw

実行するとGUIウインドウとボタンが表示されるので、ランチャーに登録等をしなくても使えるかもしれない。

ウインドウのアクティブ化でハマった。 :

これは PyAutoGUI というより PyGetWindow の問題っぽいけど…。Windows10 x64 21H2上では、既に起動しているアプリのウインドウをアクティブにできないことに気づいた。.activate() を呼ぶと、タスクバー上のアプリアイコンは点滅するものの、アプリウインドウが最前面になってくれない。エラーを吐く。

Python 3.9.12 (tags/v3.9.12:b28265d, Mar 23 2022, 23:52:46) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.

>>> import pyautogui as ag
>>> import pygetwindow as gw
>>> w = gw.getWindowsWithTitle("Chrome")[0]
>>> w.activate()
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    w.activate()
  File "C:\Python\Python39-64\lib\site-packages\pygetwindow\_pygetwindow_win.py", line 246, in activate
    _raiseWithLastError()
  File "C:\Python\Python39-64\lib\site-packages\pygetwindow\_pygetwindow_win.py", line 99, in _raiseWithLastError
    raise PyGetWindowException('Error code from Windows: %s - %s' % (errorCode, _formatMessage(errorCode)))
pygetwindow.PyGetWindowException: Error code from Windows: 0 - この操作を正しく終了しました。
>>> 

以下の、最大化、最小化は動いたから、ウインドウのID?を取得し損ねているわけではないのだろう…。
>>> w.minimize()
>>> w.maximize()

ググったところ、「Windows上ではアプリウインドウのアクティブ化はできないから、最小化+最大化で目的を果たせ」という話も見かけた。AutoIt と比べると厳しいな…。

一応、以下の投稿によると、最小化+復元すれば目的が果たせるらしい。

_.activate() sometimes throw error - Issue #31 - asweigart/PyGetWindow - GitHub
_Activate does not work - Issue #36 - asweigart/PyGetWindow - GitHub
_When using IPython, window.activate() raises error. - Issue #29 - asweigart/PyGetWindow - GitHub

>>> w.minimize()
>>> w.restore()

目標のアプリウインドウを間違えてしまう問題。 :

スクリプト作成中に、間違ったアプリウインドウを取得されてしまってハマった。ウインドウタイトルに「DeepL」という文字列を含んだ他のアプリがあると、そのアプリに文字列を貼り付けようとしてしまう。今回は、「copypaste_deepl.py」という名前のファイルを Visual Studio Code (vscode) で編集しながら動作確認していたら、vscode上のソースを全部消されてしまって焦った…。

アプリウインドウを、ウインドウタイトルだけで探すのはちょっと問題があるようだなと…。

でもまあ、とりあえず今回は、"DeepL" じゃなくて "DeepL " でウインドウタイトルを検索させれば誤魔化せるかな…。

改行コードの置換で悩んだ。 :

クリップボード内の、改行コードを複数含んだ文字列に対して、改行コードをスペースに置換するあたりでハマった。replace() を使ったら、何故か上手く置換できなくて…。

とりあえず、splitlines() と join() でどうにかしてみたけれど…。replace() では処理できないのだろうか…?

    # replace CRLF to space
    txt = pyperclip.paste()
    newtxt = " ".join(txt.splitlines())
    pyperclip.copy(newtxt)

もしかして、"\n" と "\r\n" が混ざってしまっているのかな。

以下のページによると、改行コードの種類が不明な場合は .splitlines() と .join() を使うのもアリ、らしい。であれば、これでもいいのかな…。

_Pythonで改行を含む文字列の出力、連結、分割、削除、置換 | note.nkmk.me

2021/04/24() [n年前の日記]

#1 [pc] 小容量でHDD代わりになるストレージって無いのかな

自分、手元で余ってるPC達に、Linuxをインストールして動かしていたりするのだけど。Linuxを起動させるだけなら、ストレージ容量は32GB程度あれば十分で。しかし、それらPCに入れてるHDDが500GBとかだったりするので、なんだか容量的にアレだなと。32GBとか64GBぐらいで、HDDよりアクセスが速くて、物理的なサイズも比較的小さいストレージって無いのかなと。

そのくらいの容量となると、eMMC、SDカード、USBメモリあたりが妥当だろうか。てな感じで、そのあたりの速度その他をググって眺めていたのだけど…。

eMMCは最初から基板に搭載されているもので、別途入手してPCに後から追加できるものではないし。SDカードは速度が厳しいし。USBメモリはUSB2.0ポートが遅いからやはり速度的に厳しいだろうしで。USB3.0ポートを使えれば速度が期待できるかもしれないけれど、何せ手元で余ってるぐらいに古いパーツを使ったPC達だから、USB3.0ポートなんて持ってるはずもなく。

結局、SSD か HDDを搭載するのが、速度面でもコスト面でも妥当という話になってしまうなと…。Raspberry Piシリーズのように、microSDをストレージとして利用、みたいなことができたらちょっと面白いかなとも思ったのだけど。

2020/04/24(金) [n年前の日記]

#1 [godot] カメラ情報から自機の移動範囲を求めるソレがたぶんできた気がする

Godoto Engine 3.2.1 上で、カメラ情報から自機の移動範囲を求めることができないかと考えていたけれど。たぶんなんとかなったような気がする。

図を再掲。要は、カメラから見える範囲 ―― 以下の赤い範囲を求めたい。

3dareacheck_ss03.png

以下のような手順で考えれば、範囲を求められるんじゃないかなと…。

fov_calc_02_1.png

  1. カメラの位置が原点にあると仮定して、カメラの四隅、左上と右下の線分を作る。
  2. その線分を、x軸に沿って回転させる。
  3. zx面、xy面で考えて、自機が移動する平面(y座標が一定)との交点を求める。z値とx値が得られる。

試しにPythonを使って仮で計算してみた。

_calc_fov_area.py
import math

def get_rot_pos(x, y, ang):
    a = math.radians(ang)
    xr = x * math.cos(a) - y * math.sin(a)
    yr = x * math.sin(a) + y * math.cos(a)
    return xr, yr

def dump_pos(p, s):
    print("%s = (%f, %f, %f)" % (s, p[0], p[1], p[2]))

def get_fov_area(cx, cy, cz, cxrot, fov, w, h):
    print("Camera pos = (%f, %f, %f)" % (cx, cy, cz))
    print("Camera x rot = %f" % cxrot)
    print("Camera fov = %f" % fov)
    print("Window size = %d x %d" % (w, h))
    
    d = (h/2) / math.tan(math.radians(fov/2))
    p1 = (-w/2, h/2, -d)
    p2 = (w/2, -h/2, -d)
    
    # Rotate by Camera angle
    z, y = get_rot_pos(p1[2], p1[1], -cxrot)
    p1r = (p1[0], y, z)
    z, y = get_rot_pos(p2[2], p2[1], -cxrot)
    p2r = (p2[0], y, z)
    
    y = -cy
    xr, yr, zr = p1r
    z = y * zr / yr + cz
    x = y * xr / yr
    topleft = (x, 0, z)

    xr, yr, zr = p2r
    z = y * zr / yr + cz
    x = y * xr / yr
    bottomright = (x, 0, z)

    dump_pos(p1, "p1")
    dump_pos(p2, "p2")
    dump_pos(p1r, "p1r")
    dump_pos(p2r, "p2r")
    dump_pos(topleft, "topleft")
    dump_pos(bottomright, "bottomright")

get_fov_area(0, 40, 12, -65, 60, 1280, 720)


> python calc_fov_area.py

Camera pos = (0.000000, 40.000000, 12.000000)
Camera x rot = -65.000000
Camera fov = 60.000000
Window size = 1280 x 720
p1 = (-640.000000, 360.000000, -623.538291)
p2 = (640.000000, -360.000000, -623.538291)
p1r = (-640.000000, -412.975034, -589.789472)
p2r = (640.000000, -717.260183, 62.752135)
topleft = (-61.989219, 0.000000, -45.125920)
bottomright = (35.691372, 0.000000, 15.499547)

求めた値を使って、Godot Engine で自機の位置を変えてみたけど、カメラの隅に配置できてる感じに見えたので、たぶん計算は合ってるんじゃないかな…。

Godot Engine の GDScript で書くと、以下のような感じ。
var camera:Camera
var btopleft = Vector3()
var bbottomright = Vector3()

func _ready():
    camera = get_tree().root.get_node("Level-Spatial/Camera")

    # get project display width and height
    disparea = Vector2(
        ProjectSettings.get_setting("display/window/size/width"),
        ProjectSettings.get_setting("display/window/size/height")
        )

    _calc_move_area(camera, disparea.x, disparea.y)

func _get_rot_pos(x, y, ang):
    var a = deg2rad(ang)
    var xr = x * cos(a) - y * sin(a)
    var yr = x * sin(a) + y * cos(a)
    return Vector2(xr, yr)

func _get_border(p:Vector3, rotx, y, cz):
    var v2:Vector2 = _get_rot_pos(p.z, p.y, rotx)
    var pr = Vector3(p.x, v2.y, v2.x)
    return Vector3(
        y * pr.x / pr.y,
        0,
        y * pr.z / pr.y + cz
        )

func _calc_move_area(camera:Camera, w, h):
    var cpos:Vector3 = camera.translation
    var crot:Vector3 = camera.rotation_degrees
    var fov = camera.fov
    var d = (h/2) / tan(deg2rad(fov/2))
    var p1 = Vector3(-w/2, h/2, -d)
    var p2 = Vector3(w/2, -h/2, -d)
    var q1:Vector3 = _get_border(p1, -crot.x, -cpos.y, cpos.z)
    var q2:Vector3 = _get_border(p2, -crot.x, -cpos.y, cpos.z)
    btopleft = q1
    bbottomright = q2

btopleft と bbottomright に、自機の移動範囲の左上座標、右下座標が入る。みたいな。

x軸に沿って回転させるあたり、おそらく Godot Engine はソレ用のメソッドを持ってると思うのだけど、どれがソレなのか分からなかったので、sinとcosで計算してしまった…。

何にせよ、やはり中学レベルの数学で全然解ける問題だったなと…。

しかしコレ、もっと簡単に求める方法は無いのだろうか。なんとなくだけど、ありそうな気がする。

2019/04/24(水) [n年前の日記]

#1 [pc] KM-BASIC 0.8.2の動作確認をしてみたり

MZ-80K/1200/700上で動作するBASIC、KM-BASIC の不具合を修正したと作者様から連絡していただけたので、KM-BASIC 0.8.2 の動作確認をしてみたり。環境は、Windows10 x64 1803 + MZ700WIN 0.56 + KM-BASIC 0.8.2。

_Katsumi (電子工作好き)さんのツイート: KM-BASIC for MZ-80K/MZ-700 ver 0.8.2を、OSDNにアップロード...
_Z80 File Downloads on Chamber Katsumi - OSDN

文字列型変数と SGN() の挙動は、修正されていることを確認できました。対応ありがとうございます。感謝します。

しかし、REM文を使うと LIST の結果がおかしくなる不具合を見つけてしまいました…。なんだか小出し(?)に見つけてしまってスミマセン…。まあ、REM文(コメント文)なので、使わないという手もあるかもですが…。

REM文の挙動。 :

REM文の挙動について一応メモ。

以下のような感じで REM文を入れると、LIST をした際に妙な挙動になる模様。
  • REM に続く文字列が表示されない。
  • REM文の次行の冒頭が妙な表示になる。
kmbasic082_ss10_rem_fail.png

kmbasic082_ss11_rem_fail.png

ちなみに、KM-BASIC 0.6.8 で確認したところ、そちらでも同じ結果になりました。
kmbasic082_ss12_rem_fail_kmb068.png

ただ、LISTの表示がおかしくなるだけで、プログラムの実行はできるようです。

その他の命令の動作確認。 :

一応、その他の命令についても動作確認したので結果をメモ。他の命令に関しては、問題無く動いてるように見えました。

FOR - NEXT, GOSUB, IF - THEN - ELSE はOK。
kmbasic082_ss01_forgosub.png

文字列型変数もOK。
kmbasic082_ss02_str1.png

kmbasic082_ss03_str2.png

演算子もOK。
kmbasic082_ss04_op.png

DIM(配列)もOK。
kmbasic082_ss05_dim.png

SGN(), ABS(), NOT() もOK。
kmbasic082_ss06_sgn.png

INKEY() (押されたキーのアスキーコードを取得)もOK。
kmbasic082_ss07_inkey.png

INPUT$() (入力文字列+ENTERの取得)もOK。
kmbasic082_ss08_input.png

PEEK() (メモリの読み込み)、POKE (メモリへ書き込み)もOK。
kmbasic082_ss09_peekpoke.png

念のため、動作確認に使ったプログラム (.mzt) も zip にして置いておきます。

_apicheck_20190424.zip

せっかくだから少し遊んだり。 :

動作確認だけではアレなので、せっかくだから少し遊んでみたり。

KM-BASICには、メモリの読み込みと書き込みができる、PEEK, POKE文があって。
 PEEK(メモリアドレス)    : 指定メモリアドレスから1バイト読み込んで値を返す。
 POKE メモリアドレス,値  : 指定メモリアドレスに1バイトの値を書き込む。
この命令を使うと、ちょっと面白いことができる。

例えば、MZ-700 は、$D000番地からVRAMが割り当てられているので…。

_Programming MZ-700: Display

$D000 - $D3E7 の間に、何かディスプレイコードを書き込むと、画面のその位置に文字を表示することができるので、ソレを使って色々遊べる。とメモ。

例えば、以下は、画面上をキャラが行ったり来たりする例。
kmbasic082_ss14_pingpong.png

kmbasic082_ss15_pingpong.gif

以下は、キャラをカーソルキーで移動、Qキーでプログラムを終了させる例。
kmbasic082_ss16.png

kmbasic082_ss17.gif

以下で、MZ-700のメモリマップその他が説明されてるので、この手のソレには参考になりそうな予感。ありがたや。

_Programming MZ-700
_Programming MZ-700: Memory
_Programming MZ-700: Keyboard
_Programming MZ-700: Sound
_Programming MZ-700: Interrupt

INKEY()を利用した際の返り値をメモ。 :

KM-BASIC は、INKEY() を使うと、その時に押しているキーのアスキーコードを取得できる。どのキーを押すと何が返ってくるのか、少し調べたのでメモ。環境は MZ700WIN 0.53b。

KEYASCII CODE
17
18
19
20
SPC32
Z90
X88
A65
S83
Q81

例えば _TIC-80 などは、カーソルキー, Z, X, A, S (要は、十字キー + A, B, X, Yボタン)だけでアクションゲームを作ろうとしてるノリがあるので、このくらいのキーさえ判定できればなんとかなるのではないか。

でも、MZシリーズって、同時押しを取得できるキー種類に制限があったり、したかな。どうだったかな。むしろ制限が無かったほうだったろうか。

FM-7あたりは、サブCPUがキーボードを制御してる関係で何か制限があった気もするけれど、具体的な内容をもう覚えてないや…。 *1

などと、ちょっと悩んでみたけれど、ふと気が付いた。そもそも KM-BASIC の INKEY() は一つの値しか返さないのだから、キーを同時押しされても取得できないわな…。悩む必要がなかった…。

*1: テンキーの5キーでキャラ移動を止められる、とかだっけ。それはキーを離した瞬間を取得できないから、だったかな。同時押しとは別の問題か。

この記事へのツッコミ

Re: KM-BASIC 0.8.2の動作確認をしてみたり by 名無しさん    2019/04/29 11:19
ver 0.8.3をアップロードしました。REM文に関しての挙動は、直っていると思います。また何か発見しましたら、お知らせ頂けると嬉しいです。
Re: KM-BASIC 0.8.2の動作確認をしてみたり by mieki256    2019/05/08 21:23
> ver 0.8.3をアップロードしました。

0.8.3を試したところ、REM文が正常表示されることを確認できました。
対応・修正していただき感謝します。ありがとうございます。

2018/04/24(火) [n年前の日記]

#1 [nitijyou] PICのほうが高くつくのかも

Arduino と PIC なら、PICで作ったほうが安く済むのかなとぼんやり思っていたけれど、考えてみたら PIC の場合、プログラムを書き込むためのハードウェアが必要になるのではと気が付いて。調べてみたら、PICkit3 なるツールがあるけれど、6,000円ぐらいするのだな…。公式版の Arduino が 2〜3個購入できてしまう。互換機なら何個買えることか…。

もちろん、PIC を使った何かしらを大量に作れば PIC を使ったほうが安くなるだろうけど、1つ2つしか作らないなら、Arduino を使ったほうが安く済みそうだなと。もっとも、Arduino を使うと、完成品のサイズに関しては制限を受けそうだけど。Arduino より小さくできないし…。

#2 [linux][ubuntu] Linux Mint機で名前解決ができなくて悩んだり

階下に置いてあるノートPC、Gateway M-2408j は、既にサポート切れの Windows Vista がプリインストールされているため、HDDのパーティションを分けて Linux Mint 18.3 もインストールしてあるのだけど。親父さんからの質問で、Linux Mint機から自宅サーバにアクセスできないことに気づいた。ping 自宅サーバ名、と打っても「そんなホストは知らねえ」と言われてしまう。

結論から先に書くと、libnss-winbind のインストールと /etc/nsswitch.conf の書き換えで直った。

sudo apt install winbind libnss-winbind
sudo vi /etc/nsswitch.conf

hosts:          files wins dns mdns4_minimal mdns4 [NOTFOUND=return]

試したこと。 :

ssh、samba、winbind を入れた。
sudo aptitude install ssh samba winbind

samba を設定。Windows機から、LinuxMint機に向けて ping が通ること、及び、Windows機上の putty から LinuxMint機に ssh でアクセスできることも確認。

しかし相変わらず、LinuxMint機から自宅サーバが見えない。nmblookup -f 自宅サーバ名、で、IPアドレスは確認できるのだけど…。

cat /etc/resolv.conf で、nameserver 127.0.1.1 が出てくるのが気になった。

_[覚書]/etc/resolv.confのnameserver 127.0.1.1って何?うざいんですけど。やっぱり犯人はNetworkManagerと | Deginzabi163's Blog
_Ubuntu 16.10: /etc/resolv.confのnameserver 127.0.0.1を防ぐ - Narrow Escape

dnsmasq とやらが関係してるらしい。
sudo vi /etc/NetworkManager/NetworkManager.conf
dns=dnsmasq
↓
# dns=dnsmasq
sudo reboot で再起動。

$ cat /etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 192.168.x.x
nameserver は変わったが、相変わらず自宅サーバに繋がらない。

ググっていたら、libnss-winbind なるものが気になった。

_winbindで名前解決: たわごと
_Winbind をインストールしたのに NetBIOS nameでアクセスできない on Ubuntu 13.10 | 穀風

/etc/nsswitch.conf の書き換えと、libnss-winbind のインストールで、ようやく ping 自宅サーバ、が通るようになった。

2017/04/24(月) [n年前の日記]

#1 [python] pysdl2について調べていたり

pygame_sdl2 についてアレコレ調べていたけど、どうも筋が悪い気がしてきたので、pysdl2について調べ始めたり。

pysdl2てのは…。Pythonから、SDL2というマルチメディア向けのライブラリを呼び出して使えるライブラリ。要するにゲームが作れるライブラリ。

pysdl2の概要を一応メモ。 :

公式ドキュメントによると、pysdl2は2つのパッケージで構成されているそうで。
  • sdl2。SDL2のAPI(機能?)と1:1で対応してる。
  • sdl2.ext。sdl2だけでは各機能が低レベル過ぎて記述が面倒臭くなるので、もう少し簡単に書けるようにsdl2を拡張する。

更に、「全部 Python で実装してある」とも書いてあった。Cで書いてあるわけじゃないから、例えば sdl2.ext を極力使ったほうが処理時間が短くなる、というわけでもないらしい。

チュートリアルを勉強。 :

とりあえず、公式ドキュメントのチュートリアルから ―― hello world から始めたり。まずはウインドウを表示する。できれば画像も表示する。

_Hello World - PySDL2 0.9.5 documentation

公式ドキュメントのソレは sdl2.ext を利用した版になっている。日本語コメントをガシガシ追加しつつ写経。

もし、このスクリプトを動かしたい人が居たら…。動作には画像が必要なので、 _hello.png をDLして、res というフォルダを作ってその中に入れといてもらえれば、と。

_helloworld_pysdl2_ext.py
u"""
PySDL2 (pysdl2.ext) のテスト.

ウインドウを表示して画像(スプライト)を表示

動作確認環境:
Windows10 x64 + Python 2.7.13 32bit + PySDL2 0.9.5
"""

import sdl2.ext

# sdl2.ext.Resource() で、リソース(画像等)の格納場所を指定できる
# res という名前のフォルダを作って、中に画像(hello.png)を入れた
RESOURCES = sdl2.ext.Resources(__file__, "res")

# PySDL2 の初期化
sdl2.ext.init()

# ウインドウを作成。タイトル文字列とウインドウサイズを指定
window = sdl2.ext.Window("Hello World", size=(640, 480))

# 作成したウインドウを表示
window.show()

# スプライトを作成。hello.png を読み込んで渡す
factory = sdl2.ext.SpriteFactory(sdl2.ext.SOFTWARE)
sprite = factory.from_image(RESOURCES.get_path("hello.png"))

# スプライトの表示位置を指定
sprite.position = 24, 24

# スプライトを描画
spriterenderer = factory.create_sprite_render_system(window)
spriterenderer.render(sprite)

# イベントループ。閉じるボタンが押されるまで待つ(ループする)
processor = sdl2.ext.TestEventProcessor()
processor.run(window)

# 終了処理。今まで確保したアレコレを破棄する
sdl2.ext.quit()

以下で実行。
python helloworld_pysdl2_ext.py
helloworld_pysdl2_ext_ss.png

ウインドウが表示されて、画像も表示された。また、閉じるボタンをクリックすれば、ウインドウを閉じることができた。

ところで、ソースを眺めると…。

「sdl2.ext.SpriteFactory()って何だ?」
「factory.create_sprite_render_system()って何?」
「sdl2.ext.TestEventProcessor()って何なの? 何をしてくれるの?」

という気分になりませんかね。自分はなりました。

sdl2だけで書いてみる。 :

sdl2.extを使わずに、sdl2だけで書いてみたり。pysdl2をインストールしたフォルダ内の、examples\sdl2hello.py が参考になるかと。

ちなみに、公式のサンプルはbmpファイルを読み込んでいたので sdl2 だけで処理ができていたのだけど。欲を出して(?)、うっかり png を読み込もうとしたら…。pngの読み込みには、SDL2_image.dll が必要になるのですな…。

_helloworld_pysdl2.py
u"""
PySDL2 のテスト.

ウインドウを表示して画像(スプライト)を表示
sdl2.ext は使わず、sdl2 を使って処理をしてみる。
ソフトウェア的に画像転送してるので処理としては遅いらしい。

png画像の読み込みには sdl2.sdlimage が利用できるらしい?

動作確認環境:
Windows10 x64 + Python 2.7.13 32bit + PySDL2 0.9.5
"""

import sdl2
import sdl2.sdlimage
import ctypes
import os


# PySDL2 の初期化
sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO)

# ウインドウを作成して表示。
# タイトル文字列、表示位置、ウインドウサイズを指定している
window = sdl2.SDL_CreateWindow(b"Hello World",
                               sdl2.SDL_WINDOWPOS_CENTERED,
                               sdl2.SDL_WINDOWPOS_CENTERED,
                               640, 480,
                               sdl2.SDL_WINDOW_SHOWN)

# ウインドウのサーフェイスを取得
windowsurface = sdl2.SDL_GetWindowSurface(window)

# 画像ファイルのパスを取得
filepath = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                        "res", "hello.png")

# 画像を読み込み
# image = sdl2.SDL_LoadBMP(filepath.encode("utf-8"))
image = sdl2.sdlimage.IMG_Load(filepath.encode("utf-8"))

# 画像サイズを取得してみる
# ctypes を利用しているため、
# image には SDL_Surface ではなく LP_SDL_Surface が入ってる
# 故に image.w では取得できないが image.contents.w にすれば取得できる
w = image.contents.w
h = image.contents.h
print("w, h = %d, %d" % (w, h))

# 画像の転送先領域を指定
x = 24
y = 36
w = image.contents.w
h = image.contents.h
dst_rect = sdl2.rect.SDL_Rect(x, y, w, h)

# 画像を、ウインドウサーフェイスに転送
sdl2.SDL_BlitSurface(image, None, windowsurface, dst_rect)

# ウインドウサーフェイスを更新
sdl2.SDL_UpdateWindowSurface(window)

# RGBサーフェイスを解放
sdl2.SDL_FreeSurface(image)

# イベントループ。閉じるボタンが押されるまで待つ(ループする)
event = sdl2.SDL_Event()
running = True
while running:
    while sdl2.SDL_PollEvent(ctypes.byref(event)) != 0:
        if event.type == sdl2.SDL_QUIT:
            running = False
            break
    sdl2.SDL_Delay(10)

# 終了処理。今まで確保したアレコレを破棄する
sdl2.SDL_DestroyWindow(window)
sdl2.SDL_Quit()

実行してみる。
python helloworld_pysdl2.py
helloworld_pysdl2_ss.png

画像が表示された。

sdl2.ext を使った版と比べると、sdl2 だけで書いた版は、やっぱり面倒臭い感が。画像をサーフェイスに読み込むだけで一体何行書くんだよ、みたいな。

かといって、そこ(画像の読み込みと描画)を「sdl2.ext.SpriteFactory()」でまとめられても、ちと困るよなと…。

こっちは画像をサーフェイスに読み込みたいわけで、スプライトが欲しいわけではないのですよ。なのにどうしてそこでスプライト云々のクラスが登場するのかと。しかもそのスプライトって一体何ができるスプライトなのか、そこもわかんねーよ、みたいな。まとめ過ぎ・包み過ぎだろうと。

印象。 :

pysdl2 も pysdl2 で、ちと筋が悪いような気もしてきたり。

sdl2は、SDL2の各機能を呼び出すことだけを目的にして作ってあるので、これはこれで問題無いのだけど。

sdl2.extは、個人的にどうもしっくりこない…。と言うのも、ゲームプログラムのロジック部分まで無頓着にまとめてしまっている上に、各クラスやメソッドが中で何をしてくれそうなのかよく分からなくて。

結果、謎の呪文だらけのブラックボックス、それも、sdl2.extの作者さんが想定した範囲内でしか使い道がないのであろう、頭が固いガチガチなライブラリになってしまっている気配が…。いやまあ、せっかくPythonで書いてあるのだから、どんどんソースを見て何をしてるか理解すればいいんだろうけど。逆に言うと、ソース見なきゃ役割が分からない、ってのもどうなんだと。

おまじない満載の「これしかできません」的ブラックボックスを使いたいなら、それこそUnityでも使ったほうが…。ウンザリするほどおまじないを暗記させられるけど、その分リターンも期待できそうだよなと。

しかし、Unity 利用時のようなゲーム映像が得られるならともかく、Python + SDL2 程度で、そこでしか通用しないおまじないを覚えさせてみてどうするんだと。コレの使い方を覚えたところで、他で使い道が無い。汎用性が無い。発展が期待できない。使い方を勉強することの旨味が少ない…。 *1

さりとて、sdl2.ext をスルーして sdl2 だけで書こうとすると、やっぱりアレコレ面倒臭いと感じてしまうのも間違いなくて。いやまあ、PythonからSDL2を呼べるだけでも有難いことだけど、でもやっぱりまどろっこしい。画像を一つ出すだけなのにどうしてこんなに行数が必要に、みたいなところが。

もっともこのあたり、DXRuby を普段使わせてもらっているから感じてしまうのだろうけど…。DXRubyに触れてなかったら「この手のライブラリはこんなもんだ」とうっかり思い込んでいたかもしれず。

それにしても…。DXRubyに比べると、SDL や SDL2 を呼び出す系のライブラリは、えてしてラップの仕方・包み方がおかしいところがあるなと。「何故ここを包まない?」と「どうしてここまで包むんだ?」が時々出現してしまう、そんな印象が。(※ 感想には個人差があります。) *2

pongのチュートリアルも勉強。 :

一応、pong game のチュートリアルも写経したので、もったいないから貼っときます。

_The Pong Game - PySDL2 0.9.5 documentation

_pong_pysdl2_6.py
u"""
PySDL2 のテスト.

ポンゲーム。

動作確認環境:
Windows10 x64 + Python 2.7.13 32bit + PySDL2 0.9.5
"""

# sdl2 の全機能にアクセスしたいので、sdl2 もインポートする

import sys
import sdl2
import sdl2.ext

# 白色を定義
WHITE = sdl2.ext.Color(255, 255, 255)


class SoftwareRenderer(sdl2.ext.SoftwareSpriteRenderSystem):

    u"""ソフトウェアレンダラークラス."""

    def __init__(self, window):
        u"""コンストラクタ."""
        super(SoftwareRenderer, self).__init__(window)

    def render(self, components):
        u"""描画処理."""
        # 画面全体を黒く塗りつぶしてから、本来の描画処理を行うようにしている
        sdl2.ext.fill(self.surface, sdl2.ext.Color(0, 0, 0))
        super(SoftwareRenderer, self).render(components)


class MovementSystem(sdl2.ext.Applicator):

    u"""各スプライトの移動処理を担当するクラス."""

    def __init__(self, minx, miny, maxx, maxy):
        u"""コンストラクタ."""
        super(MovementSystem, self).__init__()
        self.componenttypes = Velocity, sdl2.ext.Sprite
        self.minx = minx
        self.miny = miny
        self.maxx = maxx
        self.maxy = maxy

    def process(self, world, componentsets):
        u"""スプライトの移動処理."""
        for velocity, sprite in componentsets:
            # 速度を持っているスプライトに対して、
            # 画面内から飛び出さないように位置を変更する
            swidth, sheight = sprite.size
            sprite.x += velocity.vx
            sprite.y += velocity.vy

            sprite.x = max(self.minx, sprite.x)
            sprite.y = max(self.miny, sprite.y)

            pmaxx = sprite.x + swidth
            pmaxy = sprite.y + sheight
            if pmaxx > self.maxx:
                sprite.x = self.maxx - swidth
            if pmaxy > self.maxy:
                sprite.y = self.maxy - sheight


class CollisionSystem(sdl2.ext.Applicator):

    u"""アタリ処理クラス."""

    def __init__(self, minx, miny, maxx, maxy):
        u"""コンストラクタ."""
        super(CollisionSystem, self).__init__()
        self.componenttypes = Velocity, sdl2.ext.Sprite
        self.ball = None
        self.minx = minx
        self.miny = miny
        self.maxx = maxx
        self.maxy = maxy

    def _overlap(self, item):
        u"""ボールがプレイヤー(パドル)と当たってるか調べて返す."""
        pos, sprite = item
        if sprite == self.ball.sprite:
            # 見ている相手がボールなのでアタリ判定はしない
            return False

        # 相手の範囲とボールの範囲を取得
        left, top, right, bottom = sprite.area
        bleft, btop, bright, bbottom = self.ball.sprite.area

        return (bleft < right and bright > left and
                btop < bottom and bbottom > top)

    def process(self, world, componentsets):
        u"""アタリ判定処理."""
        # ボールと当たってるスプライトを返す
        collitems = [comp for comp in componentsets if self._overlap(comp)]
        if collitems:
            # 何かに(プレイヤーに)当たったらボールのx速度を反転する
            self.ball.velocity.vx = -self.ball.velocity.vx

            # 当たった位置でy速度を変更
            sprite = collitems[0][1]
            ballcentery = self.ball.sprite.y + self.ball.sprite.size[1] // 2
            halfheight = sprite.size[1] // 2
            stepsize = halfheight // 10
            degrees = 0.7
            paddlecentery = sprite.y + halfheight
            if ballcentery < paddlecentery:
                factor = (paddlecentery - ballcentery) // stepsize
                self.ball.velocity.vy = -int(round(factor * degrees))
            elif ballcentery > paddlecentery:
                factor = (ballcentery - paddlecentery) // stepsize
                self.ball.velocity.vy = int(round(factor * degrees))
            else:
                self.ball.velocity.vy = - self.ball.velocity.vy

        # ボールが上下の壁に当たったらボールのy速度を反転
        if (self.ball.sprite.y <= self.miny or
                self.ball.sprite.y + self.ball.sprite.size[1] >= self.maxy):
            self.ball.velocity.vy = - self.ball.velocity.vy

        if (self.ball.sprite.x <= self.minx or
                self.ball.sprite.x + self.ball.sprite.size[0] >= self.maxx):
            self.ball.velocity.vx = - self.ball.velocity.vx


class Velocity(object):

    u"""速度保持クラス.

    コレを持っているクラスは速度があるので、位置が変化するものとして扱われる。
    """

    def __init__(self):
        u"""コンストラクタ."""
        super(Velocity, self).__init__()
        self.vx = 0
        self.vy = 0


class TrackingAIController(sdl2.ext.Applicator):

    u"""敵の思考ルーチン."""

    def __init__(self, miny, maxy):
        u"""コンストラクタ."""
        super(TrackingAIController, self).__init__()
        self.componenttypes = PlayerData, Velocity, sdl2.ext.Sprite
        self.miny = miny
        self.maxy = maxy
        self.ball = None

    def process(self, world, componentsets):
        u"""思考処理."""
        for pdata, vel, sprite in componentsets:
            if not pdata.ai:
                continue

            centery = sprite.y + sprite.size[1] // 2
            if self.ball.velocity.vx < 0:
                # ball is moving away from the AI
                if centery < self.maxy // 2:
                    vel.vy = 3
                elif centery > self.maxy // 2:
                    vel.vy = -3
                else:
                    vel.vy = 0
            else:
                bcentery = self.ball.sprite.y + self.ball.sprite.size[1] // 2
                if bcentery < centery:
                    vel.vy = -3
                elif bcentery > centery:
                    vel.vy = 3
                else:
                    vel.vy = 0


class PlayerData(object):

    u"""パドルががCPUかプレイヤーかを保持するクラス."""

    def __init__(self):
        u"""コンストラクタ."""
        super(PlayerData, self).__init__()
        self.ai = False


class Player(sdl2.ext.Entity):

    u"""プレイヤー(パドル)クラス."""

    def __init__(self, world, sprite, posx=0, posy=0, ai=False):
        u"""コンストラクタ."""
        self.sprite = sprite
        self.sprite.position = posx, posy  # スプライトの位置を設定
        self.velocity = Velocity()         # 速度を持たせる
        self.playerdata = PlayerData()
        self.playerdata.ai = ai            # プレイヤーにするか、CPUにするかを指定


class Ball(sdl2.ext.Entity):

    u"""ボールクラス."""

    def __init__(self, world, sprite, posx=0, posy=0):
        u"""コンストラクタ."""
        self.sprite = sprite
        self.sprite.position = posx, posy
        self.velocity = Velocity()


def run():
    u"""メイン処理."""
    # PySDL2 の初期化
    sdl2.ext.init()

    # ウインドウ作成と表示
    window = sdl2.ext.Window("The Pong Game", size=(800, 600))
    window.show()

    # ワールド作成
    world = sdl2.ext.World()

    # 移動処理担当クラスを生成。左上と右下の座標を渡している
    movement = MovementSystem(0, 0, 800, 600)

    # アタリ判定処理クラスを生成。左上と右下の座標を渡している
    collision = CollisionSystem(0, 0, 800, 600)

    # ソフトウェアレンダラーを生成
    spriterenderer = SoftwareRenderer(window)

    # 敵AI制御クラスを生成
    aicontroller = TrackingAIController(0, 600)

    # 敵AI制御クラス、移動処理担当クラス、
    # アタリ判定クラス、レンダラーをワールドに追加
    world.add_system(aicontroller)
    world.add_system(movement)
    world.add_system(collision)
    world.add_system(spriterenderer)

    # 白色のスプライトを3つ作成
    factory = sdl2.ext.SpriteFactory(sdl2.ext.SOFTWARE)
    sp_paddle1 = factory.from_color(WHITE, size=(20, 100))  # プレイヤー1
    sp_paddle2 = factory.from_color(WHITE, size=(20, 100))  # プレイヤー2
    sp_ball = factory.from_color(WHITE, size=(20, 20))   # ボール

    # プレイヤーを2つ生成
    player1 = Player(world, sp_paddle1, 0, 250)
    player2 = Player(world, sp_paddle2, 780, 250, True)

    # ボールを生成
    ball = Ball(world, sp_ball, 390, 290)
    ball.velocity.vx = -3

    collision.ball = ball
    aicontroller.ball = ball

    running = True     # ループ管理用フラグ

    # メインループ
    while running:
        events = sdl2.ext.get_events()  # イベント取得
        for event in events:
            if event.type == sdl2.SDL_QUIT:
                # 閉じるボタンが押されたらメインループを終了させる
                running = False
                break
            if event.type == sdl2.SDL_KEYDOWN:
                # キーが押された
                if event.key.keysym.sym == sdl2.SDLK_UP:
                    # 上キーだった
                    player1.velocity.vy = -3
                elif event.key.keysym.sym == sdl2.SDLK_DOWN:
                    # 下キーだった
                    player1.velocity.vy = 3
            elif event.type == sdl2.SDL_KEYUP:
                # キーが離された
                if event.key.keysym.sym in (sdl2.SDLK_UP, sdl2.SDLK_DOWN):
                    # 上キーか下キーだった
                    player1.velocity.vy = 0

        # 時間待ち
        sdl2.SDL_Delay(10)

        # ワールドの処理
        world.process()

        # ウインドウのグラフィックバッファを更新
        # window.refresh()

    sdl2.ext.quit()  # SDL2関係の終了処理

    return 0         # 終了コードを返す

if __name__ == "__main__":
    # このスクリプトが単体で呼ばれた時に、ここが処理される
    ret = run()    # メイン処理呼び出し
    sys.exit(ret)  # pythonスクリプトを終了

実行。
python pong_pysdl2_6.py
pong_pysdl2_6_ss.png

これもソースを眺めると…。

「sdl2.ext.World()って何だよ?」
「sdl2.ext.Applicator って何?」

という気分に。やっぱり筋が悪い気が…。いやまあ、「だったら sdl2 だけ使って書いてりゃいいだろ!」って言われるのは分かってますけど。

チュートリアルなのに、ソフトウェアレンダラーを使ってる気配がするのも、なんだか…。だったら pygame でいいじゃん…。SDL2の旨味って、ハードウェア描画が使いやすくなったことじゃなかったのか…。ライブラリの売りを自らスポイルしていくチュートリアルってのも、意味が分からん…。

*1: 例えば、HTMLタグを覚えれば何かしら応用が利くけど、ホームページビルダーの使い方を覚えてもそこから発展しないじゃん、みたいな話かも。
*2: とは言え自分もそのへん全然言えないですけど。クラスを一つ作るたびに「このメソッドの引数はよくない…が、もっとヨサゲなまとめ方が思いつかない…」と悩んだりするわけで。

#2 [prog][dxruby][neta] pysdl2の作者さんがDXRubyを作っていたら

もし、pysdl2の作者さんが DXRuby を作っていたら…。「ウインドウを表示して、閉じるボタンをクリックしたらウインドウが閉じる」だけのスクリプトも、こうなっていたかもな、などと妄想を。
require 'dxruby'

dxruby.ext.init
window = dxruby.ext.window("Hello world", 640, 480)
window.show

world = dxruby.world

running = true
while running do
  dxruby.ext.get_events.each do |event|
    if event.type == dxruby.DXRUBY_QUIT:
      running = false
      break
    end
  end

  world.process

  window.update
  dxruby.ext.delay(16)
end

dxruby.ext.quit

実際の DXRuby ではこうなりますけど。
require 'dxruby'

Window.loop do
  # game main routine
end

なんというか…。このあたり、スクリプトを書く側の思考をシミュレーションしてるかしてないか、という違いがあるように思えてくるわけで。

「俺、ウインドウを表示したいんだ」 ―― そりゃそうだろう。ゲーム画面を表示するためにはウインドウを表示しなきゃいけないし。

「メインループが欲しいなあ」 ―― そりゃそうだろう。60FPSのフレームベースで動くゲームを作りたかったら、メインループは必須だし。

「閉じるボタンをクリックしたらウインドウが閉じてほしい」 ―― そりゃそうだろう。閉じるボタンをクリックしても無反応ではユーザが困惑するよ。

「ウインドウを表示する」「メインループがある」「閉じるボタンをクリックしたらウインドウが閉じる」 ―― こんなの当たり前に実現していて欲しいことで。

そのあたりを考えると…。

ライブラリの初期化、ウインドウの生成、ウインドウの表示、スクリプト終了時の後始末をわざわざ書くのはどうなのだろうと。スクリプトを書く側は、「ゲーム画面を表示できるウインドウが欲しい」のであって、「ライブラリを初期化」「ウインドウ生成」「ウインドウの表示を明示的に指定」「終了時の後始末」をしたいわけじゃないよなと。

while ループをメインループにして、60FPSで回るように時間待ち、てなあたりをわざわざ書かせるのはどうなのかと。昔風の2Dゲームを作りたいならメインループは必須だし、60FPSに調整する処理も必須だよなと。

イベントを取得して、イベントの種類を調べて、閉じるボタンがクリックされたか判別して処理を終了するあたりを毎回書かせるのもどうなのかと。閉じるボタンをクリックしたらフツーはウインドウが閉じることを誰でも期待するもんじゃないのかと。

ということで、DXRuby のソレは、実に当たり前に感じられる仕様だよなと。フツーにそこにあって当たり前のことは、ライブラリ側で済ませてあるというか。

スクリプトを書く側は、メインループの中身を書きたいと思ってるはずで。そこに何を書くかで悩むあたりが、ゲームプログラムを書く時に一番楽しいところだし。プログラマーは、ウインドウ生成表示だの、時間待ち処理だの、イベント種類の判別だの、そのあたりを書きたくて書きたくてたまんねえと思ってるわけでもないし…。

でも、初期化だの、イベント種類の判別だの、アレコレ明示的に書くことを要求するライブラリが多いんですよね…。なんでだろ。 *1

何にせよ、pysdl2 を触っていたら、「DXRuby って良くできてるなー」と再認識してしまったというか。DXRuby、素晴らしい。
*1: もちろんソレは、「デフォルトサイズ以外のウインドウを生成したい」「ウインドウを複数作りたい」「各ウインドウの表示・非表示を制御したい」「メインループを複数作りたい」「閉じるボタンをクリックしたらいきなり閉じずに何かさせたい」等々、「こういう要求があったらどうしよう」と想像して「だったらこうしておくか」となったのだろうと想像するのですが。どんな要求にも応えられる汎用性を持たせた結果、冗長な部分がどんどん増えていく、みたいな。でも、どうもそれだけではないような気もしていたり。「昔風の2Dゲームならフツーはこういう仕様だろう」てな絞り込みや、「2Dゲームアプリなら、このあたりの仕様は実装されてて当然でしょ」てな洗い出しを、そもそも最初から放棄してるのでは、と邪推したりもして…。

2016/04/24() [n年前の日記]

#1 [prog] three.jsをまだまだ勉強中

延々と続く一本道をポリゴンを並べて作って、カメラを動かして走っていくように見えるところまでは出来た感じ。

_roadmake1.html (DEMO)

ただ、時々変なポリゴンが描画されてしまう。何故こんな状態に…。

ポリゴンの座標を決める際に、どこか捻じれたポリゴンができてしまっておかしくなるのだろうか。そうであるなら…。

捻じれたポリゴンが出てきたら、つまりは四角形ポリゴンを構成する線分が交差したら、頂点座標を一部入れ替えて解決を図る処理を入れてみたり。しかし、それでも事態は改善せず。うーん。

cameraの動かし方。 :

最初、カメラの動かし方が分からなかったけど。あちこちの解説ページを見ながらコピペして試していたら、以下のような記述で動いてくれた。
    camera.lookAt({ x: tgtx, y: tgty, z: tgtz });
    camera.position.set(camposx, camposy, camposz);
    camera.up.set(0, 1, 0);
lookAt() で注視点を、position.set() で位置を、up.set() で向き? 天井がどちらにあるか? を指定してるらしい。

geometryの頂点座標が変化する時。 :

例えば、var geom = new THREE.Geometry(); でジオメトリを作って、そこに頂点や面を自分で追加して。そのジオメトリ内の頂点座標が後で変化する場合、そのままではレンダラーに渡した時の座標値のままで変化しない・固定された状態になるらしい。

頂点座標その他が変化した時は、ジオメトリを更新しないといけないようで。関係ありそうなところだけ抜き出してみると…。

レンダリング前に、.dynamic = true; を1回設定してから…。
    // Mesh生成
    function initMesh(scene) {

      // メッシュ作成
      geom = new THREE.Geometry();
      road = new Road(geom);

      geom.mergeVertices();

      // 法線ベクトル生成(自動計算)
      geom.computeFaceNormals();
      geom.computeVertexNormals();
      geom.computeBoundingSphere();

      // メッシュをシーンに追加
      var mesh = new THREE.Mesh(geom, material);
      scene.add(mesh);

      // 頂点座標が一部変化するのでGeometryを更新可能にしておく
      geom.dynamic = true;
    };

頂点座標が更新される度に、*NeedUpdate = true; を設定するようで。
      function rendering() {
        // 前フレームからの経過時間を取得
        var lastTime = getTime();
        var dt = (lastTime - startTime) / 1000.0;

        // 時間を進める
        gTime += dt * 6;
        if (gTime >= 1.0) {
          road.incIndex();
          gTime -= 1.0;

          // 頂点座標が一部変化するのでGeometryを更新
          geom.verticesNeedUpdate = true;
          geom.elementsNeedUpdate = true;
          geom.normalsNeedUpdate = true;
          geom.uvsNeedUpdate = true;

          // 法線ベクトル等を再計算
          geom.computeFaceNormals();
          geom.computeVertexNormals();
          geom.computeBoundingSphere();
        }

        renderer.clear();
        renderer.render(scene, camera);

        startTime = lastTime;
        requestAnimationFrame(rendering);
      }
      rendering();

テクスチャがぼける問題。 :

テクスチャ読み込み後、minFilter や magFilter の種類を変更したらぼけなくなった。

    // テクスチャ読み込み
    function loadTexture() {
      var loader = new THREE.TextureLoader();
      texture = loader.load('images/tex2.png');
      texture.minFilter = THREE.LinearFilter;
      texture.magFilter = THREE.LinearFilter;
    };

2015/04/24(金) [n年前の日記]

#1 [pc] VirtualBoxとVagrantをインストール

Windows7 x64 上に、VirtualBox-4.3.26-98988-Win.exe をインストール。 _2014/07/15 あたりの日記を読み返しながら作業。

_2014/10/01 の日記を読み返しながら vagrant-hostsupdater をインストールしようとしたらエラーが。どうやら Ruby の Nokogiri がインストールできないと vagrant-hostsupdater がインストールできないようで。

ところが、Ruby 2.1.6 (Rubyinstaller、mingw32版) 上で gem install nokogiri をしてもインストールができず。仕方ないので Ruby 2.1.6 ではなく、Ruby 2.0.0 p645 を常用することにして、Ruby 2.0.0 で nokogiri をインストールしてから vagrant plugin install vagrant-hostsupdater でインストール。

#2 [ruby] Ruby 2.1.6にしたら少し問題が

gem関係で少し問題が。

Nokogiriがインストールできない。 :

Nokogiri がインストールできない。途中でコンパイルエラーっぽいメッセージがずらずらと。変だな…。Ruby mingw32版上では、Nokogiri ってバイナリ込みのモノを落としてきて入れてくれるのではなかったかしらん。

以下のページのやり方でインストールできるようになった。ありがたや。

_Windows7でNokogiriを使えるようになるまで〜RubyInstaller | Scimpr Blog

要するに rubygems を更新しないとダメと。
gem update --system
gem install mini-portile
gem install nokogiri
これならインストールできた。

pryがインストールできない。 :

gem install pry をすると404と言われてしまう。

以下のページに解決策があった。ありがたや。

_pryをWindows8-64bitに入れる - kenmituoの日記

gem が 2.4.6 だったのがダメだったらしい。2.4.4 まで落とさないといかんのだとか。
gem update --system 2.4.4
gem install pry pry-doc
これならインストールできた。

Ruby 2.0.0 に落としておくことにする。 :

こういうのがちょくちょく出ると面倒だなと思えてきたので、常用する Ruby のバージョンを 2.0.0 に落としておこうかなと。2.1.x の常用は、自分のような素人には早過ぎるのかも。

Ruby公式サイトでは Ruby 2.2.x が現行版で 2.1.x は一つ前の版と書かれてるけど、一つ前の版ですらこういう状態なのかと…。いや、*NIX上で使う分にはたぶん問題無いのだろうけど。

#3 [cg_tools] IpeとLaTeXDrawをインストール

過去の日記を検索しながら作業してたらIpeとLaTeXDrawについてのメモが目に入って、ググってみたらバージョンが新しくなってたので試しにインストールしてみようかと。ipe-7.1.7-win.zip と LaTeXDraw-3.3.1-bin.zip をDL。環境は WIndows7 x64。

Ipe は解凍して bin\ipe.exe を実行したら動いた。

LaTeXDraw は、解凍して、管理者権限でDOS窓を開いて install_windows.vbs を実行するとインストールできる。

ただ、LaTeXDraw インストール時に Java関係のエラーが出て。JRE 1.8 しか入ってないよ、JRE 1.7 が必要だよと言われてしまって。jre-7u79-windows-i586.exe、jre-7u80-windows-i586.exe をインストールしたり、環境変数 JAVA_HOME に JDKのパスを指定したり、PATH の順番を変更してみたら動いてくれた。

#4 [nitijyou] 自転車で買い物に

夕飯当番なのでおかずを買いにヨークベニマルまで。帰ってきてから犬の散歩。

2014/04/24(木) [n年前の日記]

#1 [windows] IE11のエンタープライズモードについて調べたり

デフォルトでは有効にできないらしい。gpedit.msc を起動して設定を変更するか、レジストリを書き換えて有効にするのだとか。

_IE11 の新機能 ・ エンタープライズ モード | Hebikuzure's Tech Memo
_Internet Explorer 11 向けエンタープライズ モードを利用して常に最新の環境を確保 - IEBlog 日本語 - Site Home - MSDN Blogs

以下は、Windows 7 Professional x64版での操作。
  1. スタートボタンをクリックして、gpedit.msc で検索、起動。
  2. コンピューターの構成、または、ユーザーの構成 → 管理用テンプレート → Windows コンポーネント → Internet Explorer。
  3. 「[ツール] メニューからエンタープライズ モードを有効にして使用できるようにする」を右クリックして「編集」。
  4. 有効にして、OKボタンをクリック。

IE11起動後、Altキーを押すと上部メニューが表示されるので、ツール → エンタープライズモードを選択。これで、IE11がエンタープライズモードで動くらしい。

URLによって、自動で件のモードを切り替えることも可能らしい。 _Enterprise Mode Site List Manager (EMSLM) をDL・インストール。
  1. EMSLM を使って、「このURLはこのモードで動作せよ」てなリストを作成して、xmlとしてどこかに保存。例えば、http://hogehoge.com/fuga/ なら、hogehoge.com/fuga/ を入力・登録すればいいのかな。たぶん。
  2. gpedit.msc を起動。
  3. コンピューターの構成、または、ユーザーの構成 → 管理用テンプレート → Windows コンポーネント → Internet Explorer。
  4. 「エンタープライズ モード IE の Web サイト一覧を使用する」を右クリックして「編集」。
  5. 有効にして、xmlのPathを指定して、OKボタンをクリック。
手元の環境で試してみた。登録したURLをIE11で開くと、アドレスバーのところに「エンタープライズモードで動いてるよ」的なアイコンが表示された。ちゃんと反映されてるっぽい。

つまり、サーバ上にxmlを置いといて、各PCがそのxmlを参照するようにすれば集中管理ができるよ、という仕組みらしい。

ただ、解説ページを眺めると、ツール → エンタープライズモードを選んだ場合も、次回からはそのページをどのモードで開くか覚えてくれる、と書いてあった。それが本当の話で、かつ、利用する場面が少ないなら、IEを使ってる人にモード切替をお願いしちゃう感じでもOKかもしれない。

2013/04/24(水) [n年前の日記]

#1 [prog] DXRubyを勉強中

PyGame スクリプトと似たような動作をする DXRuby のスクリプトを書いて動作速度を確認してみようかなと。

とりあえず、PyGame版も、DXRuby版も、640x480ドットでBG1枚べた書き + 64x64ドット x 512枚 + ogg再生をさせてみたり。メインPC ―― i5 2500 + 9800GTGE では、すんなり60FPS出てる。

PyGame 版は、py2exe で、DXRuby版は OCRA で、exe化した。

Atom搭載ネットブック、Lenovo IdeaPad S10-2 に持っていったら、どちらも14FPS前後だった。話にならないな…。Python も Ruby も、おそらくインタプリタ(?)本体の処理速度は違ってるだろうから、仮に本体の処理速度に起因して処理が重くなっているなら結果が違ってきそうなものだけど。実際にはどちらも同じ程度のフレームレートしか出ていないので、描画処理時間が原因なのかなあ、という気がしていたり。

#2 [prog] DXRubyで気になるところ

2点ほど気になるところが。

DXRuby はフルスクリーン表示ができないみたい。 :

メインPC(Windows7 x64 + 9800GTGE)で、DXRuby のフルスクリーン表示をすると、画面が激しく点滅・チラついてしまって、実用にならない。Window.real_fps の値も、40FPSぐらいが表示されてしまう。なんでだろ。

PyGame で同じことをすると、そういう状態にはならないので、もしかすると Ruby + SDL系のライブラリなら回避できるのだろうか…? それとも環境によって結果が違ってくるのだろうか。後で少し試してみたい気もする。

例えば 1920x1080のデスクトップ上で、640x480のウインドウ表示でゲームをプレイ、なんて状態はちょっと拷問に近い感じがするわけで。できればフルスクリーン表示をする機能もつけておきたい、と思うわけですが…。まあ、他にも、処理が重くならない範囲でウインドウサイズを大きくできる方法があるのであれば、それを使うのもアリだろうな、とも思うのですけど。小さい小さいウインドウに顔を近づけて凝視しながらプレイ、なんて事態だけは避けたいなと。

DXRuby は ogg のループ再生ができない。 :

DXRuby + Vox.rb (Vox.dll) で、ループ再生が前提の ogg を鳴らしてみたら、ループする際に音が途切れてしまった。困った。これが PyGame なら、同じ ogg を鳴らしても、ちゃんとループして聞こえるのだけど。

もしかすると、DXRuby + bass.rb を使えばループ再生できるのかもしれない。が、Bass は状況によってライセンス料を支払わないといかんらしいので、怖くて試してなかったり。

マズい。このままでは、DXRuby はゲームのBGMすらろくに鳴らせない、ということになる。困った。

まあ、回避策はありそうだけど。
  • 大昔(20年ぐらい前?)の、PCエンジンのCD-ROMゲームのように、3〜5分ぐらいの長さで、ループ時は音が途切れること前提で曲データを作る。でも、毎回ループ時に音楽が一旦終わるのって、今では興醒めな感も。
  • 頑張ってMIDIデータを作る。でも、以前試したら、MIDIが鳴らなかった記憶もあるので、どうも環境によっては結構ハマりそうな予感。それに、鳴るとしても、えてして MSGS だろうから、とても悲しいことになりそう。それでなくても昨今の Windows は、MIDI関連に冷たいし…。

などと困っていたのだけど。 _開発者様のblog で、DXRuby + Ayame.dll を使う方法が紹介されていた。試したところ、ループ再生時に音が途切れていない。素晴らしい。ありがたや。

この、Ayame.dll、Ayame.so についても、 _DXRuby プロジェクトWiki - ファイル置き場 あたりに置いといてもらうわけにはいかんのだろうか…。

余談。 :

プレステ1の頃は、イントロ+ループ部分で構成された波形データを鳴らしてたような記憶があるなあ…。CD-ROMから波形データをチビチビ読んで処理してるので、毎フレーム、このサウンド関連処理をする関数を呼び出してね、とか言われたような…。自分はサウンドプログラマじゃなかったから、どうやって実現していたのか中身は全然分からないのだけど。「凄いことしてるなあ」と感動したっけ。道理で、青いプレステをトイレットペーパーの上に乗せて扇風機で風を当てながらデバッグしてたわけで…。サウンドさんの部屋は音楽機材が多いせいか発熱が凄くて大変。1〜2回お邪魔したけど入った瞬間モワーッとして「うわあ」って感じで。そこでさらにチップもドライブも酷使するんだから、そりゃ冷却で苦労するよなと…。

今になって考えると、どうやってそんな波形データを作っていたのか、その手順も気になる…。イントロ部分で鳴った音の余韻が、ループ部分の頭に混入しそうだし。ループ部分の終わりで鳴った音の余韻も、ループ部分の頭に混ぜておかないといかんような気もするし。

波形編集ソフトを使って、手作業で調整してたのだろうか。それとも、曲の作り方を工夫して、あらかじめ余韻が入らないようにしていたのだろうか。そのあたり自動化するツールを作ってあったのかなあ…。

2012/04/24(火) [n年前の日記]

#1 [nitijyou] 自転車で買い物に

親父さんの電動自転車を借りて以下略。ヨークベニマル店内のセリアに行ってIdeaPad A1用にアレコレ購入。かつ、夜食やジュースを購入。

#2 [android] セリアでタッチペンその他を購入

Lenovo IdeaPad A1 用に購入。 短いほうのタッチペンはそこそこ反応するのだけど、長いほうのタッチペンはほとんど反応しなかった。先端はどちらも似たような手触りなのだけど。不思議。

フォルダーは、7インチサイズのソレには小さ過ぎた感じ。縦にして立てかけると倒れそうになる。

マルチホルダーLは、微妙に縦が足りなかった。マジックテープで蓋をするタイプだけど、ギリギリかろうじてくっついている感じ。

ステレオイヤホンマイクは、イヤホン端子の検証用に。おそらく IdeaPad A1のソレは、マイクも接続できるようになっているのではないか、そのせいで普通のヘッドフォンを接続するとノイズだらけになるのでは、と想像したわけで。しかし、接続してみたが、そもそも出てくる音が小さくて、ノイズが含まれているのかどうかよく分からず。何にせよ、繋ぐヘッドフォンによって、ノイズの有無が変わりそうな印象。…しかしコレ、ヘッドホン側のマイクは反応していない気がする。もしかしてマイク端子も兼ねるソレではないということなんだろうか。よく分からない。

#3 [android] IdeaPad A1が起動しなくなった

充電が終わった状態で放置していたら、電源ボタンを押しても起動しなくなった。何故。

音量+ボタンを押しながら電源ボタンを長押ししたら、起動してくれた模様。ただ、その後、セーフモードなるメッセージが画面に表示される。何が起きているのやら。

2011/04/24() [n年前の日記]

#1 [pc] メインPCにFirefox4をインストールしてみた

IdeaPadのほうには既にFirefox4をインストールしてあるのだけど。この際メインPCにもインストールしてみることに。ただし、Firefox3.6が入っていた環境なので、プロファイルを作成し直して、別フォルダにインストールすることに。

3.6で使えていた拡張がいくつか使えず。代替になりそうな拡張を探したり。

Googleブックマークを使ってみた。 :

今回、日常的に使うPCを変えざるを得ないという体験をしたので、メインPC以外からもブックマーク等が使えるようにしなければいけないなと。そこで、Googleブックマークを使ってみることにした。Firefoxの場合、GMarksという拡張をインストールすれば、サイドバー上にGoogleブックマークを表示することができるようになるので、ローカルのブックマークと似たような感じで使えるはず。

Googleブックマークに、Firefoxのブックマークをインポートしてみたが、ラベル名(おそらくタグに相当)がめちゃくちゃになった。数が多かったので、まとめて修正する方法を知りたかったけど、そのような方法は見つからず。とりあえず数時間かけて手作業で修正したけれど、どうにかならないものか。こういうところは不便。

2010/04/24() [n年前の日記]

#1 [pc] 無線キーボードが時々反応しなくなる

サンワサプライ SKB-WL12BK なのですが。稀ではあるけど、キーを打っても無反応になることが。その都度、USB接続の受信機のほうを引っこ抜いて差し直して復旧してるあたり、キーボード本体ではなく受信機のほうに何か問題があるような気がしていたり。しかしどういう条件で無反応になるのかが分からず。頻繁に無反応になるなら、不良品・故障品と判断できるのだろうけど、基本的には大体正常に使えてる感じで動いてるので困る。まあ、サンワサプライだからなあ…。

Microsoft や Logicool のキーボードがまともならそっちを購入して使うのだけど。何故かどちらも無線キーボードになると、デザイン等に関して余計な事をしてしまって使いづらい製品にしてしまう。ESCやファンクションキーが見分け難くて押し辛くなるとか、カーソルキーが使いづらい形・大きさになるとか、滅多に使わないマルチメディア系のキーを増やして邪魔になるとか。有線キーボードの、一番安くてフツーのヤツをそのまま無線にしてくれれば十分なのに…。

有線キーボードの形そのままで無線にする、みたいなことをやってくれるのは現状サンワサプライぐらいしかない。ELECOMは有線無線に関係なく製品ごとにてんでばらばらなデザイン・仕様にしてしまうし。しかしサンワサプライは、前述のように非常に基本的なところで妙な動き・怪しい動きをする製品を出してくるわけで。まあ、ほとんどがOEMだったりするのだろうから、アタリの製品を引けば不満を持たずに済むのだろうけど、そこに到達するまでにいくつ製品を買わなければいけないのかと…。

この際もっと不満を書く。 :

そもそも自分はテンキーが要らないのですが。しかし「テンキーレス」という言葉を聞くと、何故か各メーカーは思考停止でもしたかのように、ノートPCのキーボードのごとく四角いスペースにギッチリアレもコレも詰め込んでFnキー併用でHomeやEndやPgUpやPgDownを打つタイプのキーボードばかり出してくる。

そうじゃないんだ。フルキーボードのテンキーのところだけ切り落としてくれればいいんだ。まあ、一応そういうキーボードも存在はしてるけど、カチャカチャと音がするタイプのやたらと高級なスイッチ・高額なキーボードになってしまう。違う違う。もっと静かに打ちたいんだ。つまり、えてして一番安いキーボードに使ってるようなヘコヘコした感触のメンブレンタイプのほうが助かるんだ。でもそういうキーボードはどこも出してこない。

テンキーは後からUSB接続で増やせるので無くてもどうにかなるのだが。カーソルキーその他をメインキー側に無理矢理埋め込まれるとそこで手詰まりになる。にも関わらず、どうして各メーカはノートPCみたいなものばかり出してくるのだろう。

まあ、今時はノートPC使うのが一般的なPCユーザ、と思われていて、ノートPCのあの感じをデスクトップ機でも、という理由でそういうキーボードばかり出てくるのかもしれないけど。

2009/04/24(金) [n年前の日記]

#1 [nitijyou] 部屋を掃除

GWに弟が帰省すると聞いたので、部屋を片付け。NSK1480の入ってたダンボール箱や、Sycomから届いた際のダンボール箱の中に、アレコレ詰め直し。EIZO FlexScan T731 を修理に出す可能性を考えて、箱をずっと取っておいてその中にアレコレ入れてたのだけど。さすがにもう修理に出すことはないだろう・壊れたら電気代その他を考えて液晶ディスプレイを買うべきだろうな、と思ったのでこの際中身を出して箱を捨てることに。

何を入れてたのかすっかり忘れてたけど。PC-98用やWin95用のエロゲの箱が大量に出てきた。うーむ…。まあ、そういうのを集めてた時期もあったなあ…。それはともかく、その手のソフトの箱は無駄にサイズがでかいので邪魔。しかし、もはや時期的に中古ゲームソフト屋さんに売れる品とも思えない。WinXPでは動かないのも結構混ざってるだろうし。かといって不燃ゴミとして出すのもなんだかもったいない。もったいないのだが、今後プレイすることはまずないだろうとも思える。どうしたもんか。中途半端なコレクター属性が未だにくすぶっていると、こういう時に面倒。

T731の箱が無くなっただけで、結構部屋がガランとした、ような気もする。気がするだけだった。よく考えてみたら、箱の中に入ってた緩衝材の発泡スチロールが減っただけかもしれず。

色々なPCパーツも発掘された。CW-7502B その他で合計4台のCD-Rドライブとか。corega Ether PCI-T(10BASE-T LANカード)とか。たぶん Celeron ?Mhz + FC-PGA→Slot1変換下駄 MSI MS-6905 とか。40ピンのIDEケーブル多数とか。おそらく光学ドライブやLANカードに関しては、「Linuxを動かすなら枯れたハードで」を念頭に残しておいた気がするけど。しかしいくらなんでも、もう使わないよな。ゴミ袋に突っ込んだ。

カウボーイビバップが表紙のNewtypeも発掘。うーむ。

2008/04/24(木) [n年前の日記]

#1 [iappli] 対応機種リストや不正終了バグ報告が届いた

対応機種リストを眺めていたら、ちとマズイことに気づいた。サウンドデータの系統について不明な機種がいくつかある。昨今の機種なので、音源チップは、メーカを問わず、おそらく同一のものを使ってるのではないかと想像するのだけど…。 *1 ひとまず、最新のサウンド割り振り資料がないか相手先にメールで打診。そのファイルに機種の記載があれば、対応できるだろうと予想。…資料がない場合はどうしよう。やけっぱちで何かしらのサウンドデータを割り振る以外にないけれど、動作に関しては何も保証できんわけで。や、現状で保証があるのかというとそれもまたアレなんだけど。受け取った資料に基づいて割り振りをしてるだけだし…。

特定機種で不正終了バグがあるらしい。リジューム時に問題が発生。メッセージを見る限り、どうやらサウンド関係で落ちてるらしい。

分数計算を追加せよ、てな要求も来て、頭を抱える。分数計算ってどうやるんだろう…。計算結果に分数を含めるということは、約分もしないといかんのだろうな。
*1: 昔と違って最近の機種は、同じ音源チップを使用する方向になってきている、という話をどこかで見た記憶が。

2007/04/24(火) [n年前の日記]

#1 [nitijyou] メガネを踏んづけてしまった

フレームがひん曲がってしまった。ラジオペンチで調整してみたものの、微妙に周囲が歪んで見える。いや、今まで慣れていた歪み方から別の歪み方になっただけ、と言えるのだろうけど。

…なんだか頭痛もしてきた。しかし、どのへんを調整すれば今までと同じ見え方になるのかも判らない。うーむ。

#2 [nitijyou] EDGE2のライセンス代金を振り込んできた

夕方だったので実際の振込は明日。

MS-officeの振込もしたかったけど。窓口は閉まってた。実際の振込は明日だとしても、せめて受付だけはしてもらえないか。と思って街中まで行ってみたが、やっぱりどこの銀行も窓口は閉まってた。

帰りに食料買出し。動けるときに買いだめしておかないと。

#3 [zatta] 交差点に入ってからウインカーを出すドライバーは免許剥奪してほしいなぁ。

ウインカーを出してないから「直進なんだろう」と思って自転車乗ってる自分が交差点に入ると、ヤツラ、交差点に入ったタイミングで左折 or 右折しながらその時にウインカーを出しやがる。さらに、歩行者・自転車優先ではない感じのスピードで突っ込んでくる。しかも、一日で3台見かけた。何を考えてるんだお前等って何も考えてないから直前でウインカー出すのか。…まあ、出さないよりはマシかもしれんけど。<ってオイ。

ウインカーってのは、「俺はこれからこっちに曲がろうとしてるから周囲の皆さんそのことを認識して動いてくださいよ」「さて、俺は伝えるべき情報は伝えたんだから、何か問題が起きたとしたら責任はお前らにあるからな俺じゃねえぞ」的情報伝達なわけで。その情報を出さずして・手遅れなタイミングで出してたんではあかんやろと。いかにして事故を防いでいくか試みねばなるまいという姿勢そのものが最初からそこには存在してないのではと思いたくもなる。こういうドライバーからはどんどん免許を剥奪してもらわないと困るって免許を剥奪する手段が用意されてないからどうしようもないのかトホホ。

真面目なドライバーだけで道路を走っていても何かの折に事故は起きてしまうわけで。それくらい危険な場に、事故を防ごうという意識そのものが欠落してるドライバーを参加させる余裕なんて、これっぽっちもないはずなんだが…。どうにかならんものか。つーかそういう事態を防止するための免許制度のはずなのに。おかしいよなぁ。

免許更新の際に、講習受けるだけで終わり、ってのがおかしい気もする。コンピュータ技術がこれだけ発達してきた現状があるんだから、PS2でもズラリと並べて、クイズソフトや運転シミュレーションソフトを動かして、交通ルールが判ってなかったり、運転シミュレーション中に事故を起こしたら、免許剥奪。とかそんな具合にやれないものであろうか。常日頃から交通安全を意識してるドライバーなら痛くも痒くもない試験のはずだし、落ちたら落ちたで「俺にはまだ至らない点があったのだな。これを機にもちっと勉強し直して安全運転を心がけられるようになろう」と反省して再挑戦するだろうし。再挑戦するたびにお金も取れるとなればどこぞの財源も潤うし。皆ハッピー。…無免許運転する人間が増えるか。なら、無免許運転の罰則を厳しく・罰金を多くすればいいか。罰金を多くすればこれまた微妙に財源も潤うかも。みたいな。車を徴収(?)してしまうのもいいかもしれん。お金をかけてカスタマイズしてきた車があっさり国や自治体に取られてしまう。となれば多少はルールを守ろうという気にならないか。

そういうアレな展開が嫌なら、せめてウインカーぐらいはちゃんと出しましょうや。みたいな。

#4 [iappli] 仕様変更メールが届いた

PalettedImage 関連部分は、別途グレーアウト済みの画像が届いて、それを表示するように仕様が変更された。助かった…。容量的に何も入れられない・修正できない状態を脱することができそう。

2006/04/24(月) [n年前の日記]

#1 [anime] セイザーX、まとめてBGV

カブト虫の人が悩む回。悩んでるときの演技が凄いことになってる。素晴らしい。風邪をひいて高熱でうなされてるときのような異常さが。…舞原監督担当回だけど、そのせいかしら。たしか、セーラームーン実写版でほとんどメイン監督同然だったという話を聞いた記憶もあるわけで。登場人物の感情を映像に定着させるその手段に、強いこだわりを持ってる監督、かもしれず。などと勝手に妄想。

サッカーの回。サッカーだな。うむ。

ドリル戦艦変形の回。胸にドリル。これぞ直球デザイン。素晴らしい。

3人が捕まってしまう回。「OK、艦長」の人がめちゃくちゃ喋ってる! <オイ。さらにダンスまで! それにしても、「OK、艦長」の人は、そこに居るだけでスゴイ存在感。…カブト虫のサポートメンバーがあんな属性の宇宙人だったとは。…中身が戻るシーンで、どうやって作ってるのかわからなくて感心。空気を入れた後、自然に動き出してる。中身なしと中身ありをカメラ位置を変えずに撮ってるとしても、必ずズレが出てきそうだけどなぁ。どうやって作ったんだろう。

雷将軍登場の回、前編・後編。赤ボスの語りで始まるあたりや、納豆ほしさにヒーローの一般家庭に侵入するあたり、脚本段階での構成の巧みさ・ネタの混ぜ方に感心してしまったり。さておき、敵の巨大ロボが大魔神。グー。

#2 [prog][cg_tools] パレット管理用ツールを検索

gif画像の透明部分が指定されてない…。画像も結構数があるし、一つずつファイルを開いてチェックしてくのも面倒。何かヨサゲなツールはないものか。ということで検索。

_PaletteScope - インデックスカラー画像用カラーパレット編集ツール
_Palette Sort - ゲーム作成をする際のビットマップのパレットの管理を視覚的に行う
_彩屋 - 16色、256色のパレットエディタ

なんか…違う…。そもそも gif を開けなかったりするし。

透過gif画像にするツールを検索 :

_かんたん透過くん - イメージの透過したい色をクリックするだけで簡単に画像透過&GIF変換

一括処理する際に、左下のドットの色を透過色として扱ってくれるらしい。が、出力画像が256色の画像になってしまう…。iアプリ用の画像だから、16色で収めたいのだけどな。

OPTPiXの一括処理でできないかと思ったが。 :

共通パレット生成にチェックを入れて、一括処理で減色&gif保存すれば、複数の画像に対して決まったパレットの並びになってくれた。が、そこから先が…。

ヘルプを見たら、
バッチ処理では、領域指定による透過色指定はできません。バッチ処理で透過色オプションを指定した場合は、パレット番号0が透過色となります。なお、パレット番号0には、黒(その画像の中で最も輝度の低い色)が割り当てられます。
と書いてあった。うーむ。黒は非透過色として使ってるから、それじゃあかんのですよ…。

_人力検索はてな - ImageMagickはgifの圧縮に対応していますか? :

ImageMagickはgifの圧縮に対応していますか? ImageMagickが吐いたgifのサイズが大きすぎるという現象が起こっています。やはり特許の関係でだめなのでしょうか? GDはどうなのでしょうか? また圧縮ができるこういったソフトはないでしょうか?

人力検索はてな - ImageMagickはgifの圧縮に対応していますか? ImageMagickが吐いたgifのサイズが大きすぎるという現象が 起こっています。 やはり特許の関係でだめなのでしょうか? GDはど.. より

ImageMagick でどうにかできないかと思ったが圧縮してないのでは、うーむ。

IrfanViewなら直接何番目のパレット番号を透過色として扱うか指定ができるみたい。 :

インデックスカラーの画像に対してはパレット表示もできるし。gif画像として保存する際に、何番目のパレット番号を透過色として扱うかの指定もできる。かつ、複数の画像に対して一括で処理することもできるし。ということで、IrfanView を使ってどうにか。

UNIX 文化圏・Linuxユーザの人はどうやって透過gifを作るのやら。 :

圧縮されてない gif画像で我慢するしかないのかしら。

まあ、ImageMagick のバイナリを作る際に、--enable-lzw をつければ圧縮されたgifも出力できるっぽいのだけど。UNIX文化圏はコンパイルしてバイナリを入手するのがデフォルト、という話もちらほら聞くし、さほど苦でもないのかな。

この記事へのツッコミ

Re: パレット管理用ツールを検索 by otsune    2006/04/29 06:56
>UNIX 文化圏・Linuxユーザの人はどうやって透過gifを作るのやら
たぶん「GIFなどという邪悪な物は使わない」が正解か?
非圧縮なGIFならユニシス特許に引っかからなかったけど。特許が切れた今でも、別に見向きもしていない感じはする。
Webページ用ならPNGで事足りますしねえ by mieki256    2006/05/01 18:19
> たぶん「GIFなどという邪悪な物は使わない」が正解

ですかね、やはり。
Webページ上で、GIF相当のインデックスカラー画像を使いたいなら、
PNGを使えばいいわけだし…。あえてGIFを使う理由が無いしなぁ。

iアプリでは「圧縮された、透明色を持ったGIF」がないと困るので、
(容量が厳しいし、透過画像を使うにはそれしかないし)
透過・圧縮されたGIFを作れるツールが必須…なのですが、
UNIX文化圏にはiモード端末エミュレータからして存在しないだろうから、
「UNIX文化圏の環境でiアプリ制作」をイメージすること自体無意味ですね。

そもそもiモード自体が邪悪だろうし。

#3 [zatta] 「紡木たく」って「つむぎたく」と読むのだな

自分、「つむらぎたく」と読むのかと思ってたよ。

や。高校生が女子中学生を殺した事件を見て、「なんか紡木たくの世界っぽい」と思ってしまっただけなんだけど。

_はてな - 紡木たくとは :

#4 [iappli] 自機と、動く足場objが同期しない

自機が足場objに1フレームだけめりこんでしまう症状は、自機のx,y座標を求めるタイミングがおかしかったから、と判ったのだけど。自機と、動く足場objの移動が同期しない。自機のほうが1フレーム遅れて移動する。うーむ。

1フレームめりこむのは、下のような順序にしてしまってたから。
  1. 足場obj速度を決定。
  2. 足場obj座標に速度加算。
  3. アタリチェック。
  4. 自機速度を決定。足場objと当たってたら補正。
  5. 自機座標に速度加算。
  6. 描画。
これだと、足場objと自機が重なった x,y座標が最後に出てきて、それで描画をしてしまうので、1フレームめりこむ画が出てきてしまう。

で。下のような順序に修正。
  1. 足場obj座標に速度加算。
  2. 自機座標に速度加算。
  3. アタリチェック。
  4. 足場obj速度を決定。
  5. 自機速度を決定。足場objと当たってたら補正。
  6. 描画。
めりこまなくなった。が、動きが同期しない。

あ。判った。自機速度の決定時に、自機座標に足場objの速度を加算してたのがまずかった。自機座標に速度加算する際に、足場objの速度を反映。…ずれなくなった。ように見える。

#5 [game] プレイヤーキャラがジャンプするときに予備動作は必要なのだろうか

絵描きさんの感覚だと、「ジャンプするんだから予備動作(一旦沈み込む・足を折り曲げる)は必要だろう」という感じなのかもしれないけど…。実際に、そのポーズを表示するプログラムを作ってテストプレイしてみると、ジャンプボタンを押した瞬間から飛んでくれないのでちょっとイライラしてくる。なんつーか、レスポンスが悪い。

まあ、これが3D格闘ゲームあたりだと、前に踏み出すにしても、ジャンプするにしても、予備動作を入れてあってもさほどおかしくないのかもしれんのだけど。2Dアクションゲームの場合は、ボタンを押した瞬間に飛んでくれるほうが、気持ちよくプレイできそうな予感。もし、アニメのパターンを入れたいなら、ジャンプ中に意味もなくくるくると回転するとか、スカートがひらひらするとか、上昇中と下降中で見た目を変えるとか、そういった、空中を飛んでる最中に入れるのがいいのではないか、と思わないでもない。のだけど。もっさりした動きにすることで難易度調整もできるのかもしれんからアレなのかなぁ…。

そういやマリオってどんなジャンプだったろう。押した瞬間に飛んだだろうか。それとも予備動作が入っただろうか。…覚えてないや。手元にもないので確認もできないし。…マリオの、ボタンを押してる時間の長さでジャンプの高さが変わるあたりは、トリガーが入ってから一定時間内にボタンが押されたままなら初速度を維持する、ということでできてるように見える。これがもし、予備動作が入る場合はどうやってそのへん変えるんだろう。予備動作中にボタンを押してる時間を計っておいて、それを反映させるのかな。その場合、初速度そのものを変更できるから自然な放物線になるという利点がありそう。とはいっても、ジャンプし始めの瞬間より、もっとも高い位置で放物線っぽく動いてるかどうかのほうが注目されるような気もするけど。

この記事へのツッコミ

Re: プレイヤーキャラがジャンプするときに予備動作は必要なのだろうか by otsune    2006/04/25 03:58
http://miyao-ka.com/index.php?SuperMarioJump
『スーパーマリオブラザーズ』のジャンプについてのメモ

が参考に成ります。

あとゲームの動きとアニメの動きは全然違いますよね。
真面目にアニメっぽいモーションをゲームに適用するとモッサリしがち。
Re: プレイヤーキャラがジャンプするときに予備動作は必要なのだろうか by けいと    2006/04/25 23:39
> マリオってどんなジャンプ

スーパーマリオのジャンプ、
何一つ疑問を持たずに遊んでましたが結構奥が深いですねぇ

体感的にはパラシュートを背負っている感じなんですけどね。
ジャンプで上昇するときは普通に重力に逆らうけど
下降するときはパラシュート開きながら下降しているというか、
月面飛行士みたいにふわーっと下降しているというか。

> それとも予備動作が入っただろうか

北斗の拳のアニメーション作成を思い出してしまいました。
1コマずつ左右の拳を交互に繰り出しても迫力が出なかった。
だから、1コマに複数の拳が…とかいう話だったような。

あと、別の意味で思い出したのがプリンスオブペルシャ(ゲームね)
妙にくねくねリアルに動くキャラだったなぁ。
上の階に登るのも、いちいちジャンプして上の階の床に手をかけて
もそもそとよじ登るアニメーションしてましたし。
マリオの奥深さ by mieki256    2006/04/27 15:00
> 『スーパーマリオブラザーズ』のジャンプについてのメモ

これは! 素晴らしい! しかも動作サンプルまで。
たしかに、非常に参考になりますな…。
やはりマリオは凄かった…。

> ゲームの動きとアニメの動きは全然違いますよね。

たしかに…。とはいえ3D主体になってから、
そのへんのミックス加減が課題になったような気もしますです。
たしかにパラシュートですな by mieki256    2006/04/27 15:21
> 体感的にはパラシュートを背負っている感じ

落下速度が一定の速度を超えないようになってるから、
たしかにそういう感覚ですな。
そうしないと、遊びにくい・キャラを操作しにくいのもありますが、
最高速度を設けたほうが、アタリ処理で問題が置きにくいという…
(地面や敵と衝突せずに、スコッと抜けちゃう状態を回避しやすくなる…。
もっとも、線分の情報で計算すればそういう症状も置きにくいだろうけど、
ファミコンのCPUには掛け算命令があるのかどうかすら…うーむ。)

> 1コマに複数の拳が…

そういや、聖闘士星矢で、
「ペガサス流星拳は『音速を超えるパンチ』(だったか?)という触れ込み」
→「1/24秒にxx発打たないと音速を超えないはず」
と真面目に計算して、1コマに何発描くか決めてたらしいですな。
素晴らしいアプローチ。

そのへん、2Dゲームだと「オバケ」あたりと絡んでるのかな。
(「オバケ」はアニメのほうの表現ですが。)
3D主体だと、プログラムでブラーを作るあたりに相当しそう…

> プリンスオブペルシャ

懐かしい…!
アレは、究極まで予備動作を表現・追求することで
新たな価値を生み出したゲームですなぁ。
色々やり方はある、ということですかな。
Re: たしかにパラシュートですな by otsune    2006/04/28 09:38
>ファミコンのCPUには掛け算命令があるのかどうかすら…うーむ。)

ファミコンが使用していた6502には、かけ算命令は有りません。
それどころかADD命令すらなくADCで代用したりしてます。

#6 [digital] 携帯でT9入力方式というのを試してみた

N506iS の内蔵iアプリに、ミッキーマウスが登場するタイピング練習ソフトが入ってた。T9入力方式なるものを練習するのだとか。試してみたけど、なるほどたしかに、場面によっては結構楽そうな。

PCの文字入力に応用できないかな。と思ったけどそもそもカナ入力してる人にとってはメリットはないな。…いや待て。ローマ字入力時には結構楽になるところがあるかもしれん。「kwsk」と打つと「くわしく」と出てくるとか。…まあ、どこかが既に作ってる・販売してそうだけど。ていうか特許でおいそれと手は出せないか。

_Mobile:「N504i」の日本語入力を解剖する :

例えば「携帯」と入力したいときは、読みを[2][1][4][1]、すなわち「かあたあ」と入力する。すると読み候補表示画面に「こうつう」「けいたい」などの候補が現れ、先頭の候補が入力位置に置かれる。目的の読みが先頭候補ならそのまま[決定]ボタンを押し、そうでないときは[下]ボタンを押して候補表示画面からカーソルボタンで目的の読みを選ぶ。読みが決定したら[下]ボタンでかな漢字変換を行う。

Mobile:「N504i」の日本語入力を解剖する より

デフォルトの入力方式で「けいたい」と打ち込むと、2,2,2,2,1,1,4,1,1 と打ち込むから…9回押すのか。それが4回になるわけで。

T9は一見画期的な入力方式だが、良いことづくめではない。メリットの裏には必ずデメリットがある。それは同音語の問題だ。

Mobile:「N504i」の日本語入力を解剖する より

例えば、「置いてたの」「ウェットな」「生い立ちに」はいずれも「ああたたな」と入力することになるが、このとき表示される読みは169種類にもなる。とても選べるものではない。

Mobile:「N504i」の日本語入力を解剖する より

なるほどなぁ…。

#7 [zatta] 先日書いたアニメ関係の記事でコメント欄が盛り上がっててビックリ

「アニメ業界をかばうならMSもかばえ。でないとダブルスタンダードだ」という話には、なるほどなと。MSのプログラマーも、大変そうだもんなぁ。…と言っても床で寝てたり風呂に入れないMSのプログラマーの図というのはちょっとイメージが湧かないんだけど。いや、実際はそういう目にあってるのかもしれんのでアレだけど。

「制作進行事故」「ちゃんと家に帰れるアニメーターも居る」という話を聞いて、たしかにそのへんは作画云々より制作進行のあたりが絡んでそうだなとも。特に後者は、おそらく優秀な制作進行の方が居るんだろうと。…でも、Pあたりも関係してるのだろうか。…何にせよ、作業をしてる個人に集約される話ではなく、システム的な問題のような気もする。

「サムライトルーパー」の話を聞いて、「ああ! そういやそういう事件もあった」と懐かしく思ったり。あれはたしかに放送事故、だよなぁ。

この記事へのツッコミ

Re: 先日書いたアニメ関係の記事でコメント欄が盛り上がっててビックリ by けいと    2006/04/25 15:02
> 床で寝てたり風呂に入れないMSのプログラマーの図

さすがにそこまで泥臭くはないですけど、
ちょっと違う意味で過酷なことは過酷…

10年以上前の古い本ですが、
これ↓
http://www.amazon.co.jp/exec/obidos/ASIN/4822740161/qid=1145944815/sr=1-2/ref=sr_1_10_2/249-5371160-0916353
を読むと結構大変だという様子が書かれています。
時代がNTなので今はもう違うかもしれませんけどね。
なるほどNT開発か… by mieki256    2006/04/27 15:06
> 闘うプログラマー〈上〉―ビル・ゲイツの野望を担った男達

あー、なるほど。その事例か…。
たしかに、NT開発は大変だったらしいと、どこかで聞いた記憶も。
や、文献とかまったく読んでない自分なので、
実状はまったく知らないのですが。

そうか…MSのプログラマーも、苦労してるのだな…
…いや、コレだけてんこもりになってくると、
苦労してないわけがないのだけど。
よくまあここまで作ったなと、改めてしみじみと…。

2005/04/24() [n年前の日記]

#1 [linux] _Ctrl+Alt+Delを使ったシャットダウンの無効化

_Ctrl+Alt+Delによるシャットダウンを無効に
なるほど。こんな方法があったとは…。

/etc/inittab 中の、「ca::ctrlaltdel:/sbin/shutdown -t3 -r now」の行をコメントアウトして、「init q」でリロードすればよいらしく。φ(..)メモメモ

でも、これだとrootも含めて使用できなくなるらしく。利用できるユーザを限定するような設定にしたほうがヨサゲ。「ca::ctrlaltdel:/sbin/shutdown -a -t3 -r now」のように、-a をつけて、/etc/shutdown.allow を参照するように指定。/etc/shutdown.allow に、shutdown を利用できるユーザ名を記述してみた。

_Manpage of PROC :

/proc/sys/kernel/ctrl-alt-del というファイルがあるらしく。
このファイルはキーボードの Ctrl-Alt-Del の扱いを制御する。

このファイルにある値が 0 の場合、 Ctrl-Alt-Del が捕捉されると init(1) プログラムに送られて、正しく再起動される。

値が 0 より大きい場合、Vulcan Nerve Pinch (tm) に反応して、 Linux はダーティバッファを同期させることなく、すぐに再起動を行う。

注意: プログラム (dosemu など) に 'raw' モードのキーボードがある場合、 ctrl-alt-del はカーネルの tty レイヤーに到達する前にプログラムに遮断され、プログラムに送られてどのように扱うかが決められる。

_/procファイルシステムを使ってシステムを管理する
/proc/sys/kernel/ctrl-alt-del

このファイルには、ctrl+alt+deleteのキーの組み合わせを受けたときのシステムの反応を制御するためのバイナリー値が保持されます。2通りの値の意味は以下のとおりです。

1. 値0は、ctrl+alt+deleteがトラップされinitプログラムに送られることを意味します。この値にすると、システムはシャットダウン・コマンドがタイプされたかのように礼儀正しくシャットダウンを行い、リスタートを行うことになります。
2. 値1は、ctrl+alt+deleteがトラップされず、電源がオフにされたときのように、きれいなシャットダウンが行われないことを意味します。

デフォルトの設定値: 0
なるほど。で、init が呼び出されると、/etc/inittab の内容に従って…という感じなのかしら。

2004/04/24() [n年前の日記]

#1 [pc] C3

_こちらのページ を見て驚いた。C3-1GHzって放熱板だけで動くのか。うーむ。

_C3が動くM/Bのリスト :

_こちらのページ から。 _こちらのページ ではファンレス化可能なCPUについて記述がある。C3の低消費電力は魅力的。
_VIA CPU動作報告

_静音Linuxマシンの製作2 :

―― というかCLE266はNehemiahチップの使用で ―― 高い性能を発揮するという。じっさいこの2号機はDVDの再生もアプリケーション ―― xemacsやOpenofficeなど ―― の起動も速い。Celeron 1.2Gの1号機よりも速いのである。
C3=低性能とばかり思ってたけど、チップセットの組み合わせによっては結果が異なる場合もあるのか。うーむ。

と思ったらベンチマーク結果では下手するとCeleronの半分程度。やっぱり低性能なのか。C3 1GHz ≒ Celeron 500MHz と考えればいいのかな。 *1 しかし、 _TDP とやらでは、C3 1GHz は Celeron 1GHz の 1/3 。つまり、C3 1GHz は、Celeron 1GHz に比べ、1/3 の TDP で 50% の性能を出すと。

と思ったけど、Coppermine Celeron 533MHz の TDP を見ると、Nehemiah C3 1GHz と同じくらい。ということは、C3 1GHz を使うより Coppermine Celeron 500MHz を使うほうがいいのか。でも、Ezra-T C3 1GHz なら Coppermine Celeron 1GHz の 1/2 の TDP らしいし、Ezra-T C3 1GHz のほうが FSB 100MHz なのでちょっと判断が難しい。ちなみに、Mendocino Celeron 500MHz では TDP が跳ね上がるので、Coppermine Celeron や Nehemiah C3 が入手・利用できるなら Mendocino を使う意味はない。ということになるのかしら。うーむ。

_VIA C3 などで 2.4 kernel が正常に起動しない :

メモ。i586のkernelを入れないとダメらしい。

_EPIA-C800のページ :

_ケース全体がヒートシンクになった完全ファンレスPC「Hush Mini-ITX」 :

_静音研究室 :


*1: Celeron 1GHz / 2 ≠ Celeron 500MHz なので、C3 1GHz ≒ Celeron 500MHz は間違ってるんだけど。

この記事へのツッコミ

Re: C3 by Y    2004/04/25 18:13
C3のシステムを新規で組むのはちょっと予算的に
厳しいですよね。
投資に対する効果が消費電力&静音以外に無い
割に性能がイマイチですし。
動作確認されたM/Bで既に組んでいて、CPUのみ
換装の場合でしたら良いのですが・・・。

それと圧縮&展開等のファイル処理が遅い為、
OSのインストに凄く時間がかかるとかって
情報も耳にしますね。

個人的に凄く興味のあるCPUなので私も欲しい
と思って情報を調べていたのですが、買うとな
ると中々難しいです。
Re: C3 by mieki256    2004/04/26 09:20
> 消費電力&静音

C3を導入するとすればサーバ機用途なんで、
この点は非常に魅力的なんですが…

> 圧縮&展開等のファイル処理が遅い

うぐぅ。マジですか。それはキツイ。
ウチの自宅サーバ機、圧縮しながらデータ送ってたりするし。
てきめんに処理が遅くなりそう。
(いや、今使ってるCPUよりはおそらく速いんだろうけど…
 ますます持って新規購入する意義が薄れてしまう。)

たしかに、なかなか難しいですな>C3
Re: C3 by 名無しさん    2004/05/31 00:36
C3 Ezra 1GHz→C3 Nehemiah 1GHzにかえて使用していますが、
インストールはそれほど遅くなかったです。
現在WindoesXP sp1で使用していますが、それ程重たくないです。。。
といいたいところですが、実行するソフトによっては、
体感がP3の500程度と同じようなときもあり、
実用レベルかどうかは人それぞれかも。。。

で、興味深いのは、Ezraコアでフル稼働させてた処理をNehemiahでさせると、
フル稼働にならないので、総合的に見ると諸費電力が下がったというのが・・・。
EzraコアでPC全体で42Wくらい使用していたのが、同じソフトをずっと使用していて、
Nehemiahは36Wです。最高では44Wになることもありますが、
ちょっと重たい目のソフトを動かすならNehemiahがよろしいかと。
ちなみに来週ごろにはNehemiah1.2GHzに換装予定です。
Re: C3 by mieki256    2004/05/31 23:34
> C3 Ezra 1GHz→C3 Nehemiah 1GHzにかえて使用していますが

おお! 体験談が! ありがたいです。

> 実行するソフトによっては、体感がP3の500程度と同じようなときもあり

なるほど。やはりそのぐらいの性能として見ておいたほうがいいのか…。

> 同じソフトをずっと使用していて、Nehemiahは36Wです

なんと。
てっきりEzraのほうが、そのあたりの性能(?)はいいのかと思ってました。
実際に駆動させた場合、そう単純な結果(?)にはならないのですね。
たしかに興味深い…。

#2 [pc] カグスベールのフリーシートタイプ

を昨日買ってきてマウスの底面に張ったのだけど。フリーシートタイプは細かく分割されたシールタイプとは違って妙に厚みがあるようで。マウスとマウスパッドの間の空間が広がる → マウスのボール部分が接地しない → マウスが動かず。ガックリ。

#3 [anime] プラネテスが終わってしまって

毎週楽しみなアニメがなくなってしまった。寂しい。

この記事へのツッコミ

Re: プラネテスが終わってしまって by (楼)    2004/04/28 02:55
ご視聴、ありがとー! 前作もそうだったけど、
視聴できない人が多いので、見てくれているだけ
で、とても嬉しいです。
次は来年1月放映番組になる予定。
今度は、ぐっと軟派になります(笑)。
Re: プラネテスが終わってしまって by mieki256    2004/04/29 18:24
> ご視聴、ありがとー!

わあ。忙しいでしょうにわざわざカキコありがとーであります。
めっちゃ楽しめた作品でしたですよ。
個人的には、EVA、∀、カレカノ以来の、
毎週の放映が待ち遠しかった作品でした。

> 視聴できない人が多いので

NHK地上波で流さないものですかねぇ。あれだけのクオリティなんだから、
地上波で全国放送したら爆発的人気に繋がりそうな。
(正直、火の鳥より人気出そうだけどなぁ <マズイ発言かもしれず)
もっともDVD販売等も考えた場合、地上波で流すより、
BSやケーブルTV等で流したほうがいいのかしら…

それはともかく、次回作が楽しみであります(ニヤリ
…個人的にはTV東京系でないことを祈りつつ (;´Д`)
福島じゃTV東京系は流れないからなぁ。

2003/04/24(木) [n年前の日記]

#1 修理工場に行って話を聞いてきた

親父さんと共に修理工場に出向き、シビックがどんな状況なのか工場の人から話を聞いてきた。かなりヤバイ状況。部分部分を取り替えれば修理は終わり、というわけにいかず、本体後部そのものが歪んでるのでかなりの修理費がかかりそうとの事。しかし、元々が中古車、年式も古いので、それだけの修理費を保険屋さんが出すかどうか怪しい感じ、との話。

仮に修理するとしたら :

仮に、とにかく修理しようという話になった場合、「保険屋さんは修理費全額は出さない」→「誰が足りない分を負担するのか」→「ぶつけてきた相手が自腹を切ればいいが『保険に入ってるのになんで?』とゴネまくる可能性が大」→「かといってこっちが出費してたらバカだ。こちらには何一つ非は無いのだから」という話になってトラブル発生確実。

全損扱いにするとしたら :

仮に、全損扱いにするとした場合、同等の中古車を買えるだけの額を相手の保険屋が出してくる可能性は低いかも、との事。そもそも以前、何かの折に、シビックを売るとしたらいくらになるか見積もってもらったら、タダでも売れない、逆に廃車料を請求するぐらい、との話だったし。そんな車に金にシビアな保険屋がどれだけの金額を出すだろうか。

酷い話だ…どうしたもんか :

ついさっきまで、ちゃんと乗れて、しっかり走っていた車を、100%向こうのミスでお釈迦にされて、しかし車は戻って来ないし、代わりの車も貰えない…それではこっちも怒らずには居られないではないか。かといって怒ったところで事態が好転する可能性がそうそうあるようにも思えず。これは困った。参った。

条件はそんなに厳しくないと思うんだが :

こちらは、事故を起こされる前の状況が戻ってくればいいだけの話で。別に車の車種にはこだわってないし。ちゃんと走って、エアコンとカーステ(カセットデッキとラジオ程度)がついてて、エアコンをONにすると坂道が登れないような弱まったエンジンでなければ、車は何だっていい。中古車でも構わないし、条件さえ満たしてれば、相手の家族・友人知人のお下がりでも構わないが。しかしそんな事を望む事すら無理な相談なのか。一体どうしろと。

首周りもなんか変なんだよな :

これでムチウチとかになってたら泣きっ面に蜂だが、ついさっき、首を傾ける角度によっては胸のあたりがギューッと苦しくなってくる事に気づいて今現在ちょっとドキドキしてたり。大丈夫かよ…。ひとまずムチウチの症例について検索してみようか。

2002/04/24(水) [n年前の日記]

#1 XPの遠隔操作

犬の散歩をしていた近所のNさんと立ち話、つか、PC談義。
XPの遠隔操作(リモートデスクトップ機能?)の話を聞いてビックリ。
そ、そ、そんなことが出来たのですカー!? ??( ̄□ ̄;)!! >XP
それは面白そう、というか便利そうだ…

DVD-RAMドライブは便利だ、快適だ、と力説されたけど…自分にとっては高いッス (T_T)
もっとも、自分が昔、CD-Rドライブ買ったときの値段とそう変わらないんですよね。
まあ、あと数年すれば、今のCD-Rドライブ並みの値段になるだろう…
どの規格がデファクトスタンダードになりそうか、今より明確になってるだろうし。

話を聞いてて、ちょっと気になったのは…
「メールに添付されてきたアップデートプログラムを開いてウイルス対処した」とか言ってた…
…アップデートプログラムをメールで送るメーカ・プロバイダなんてあるだろうか…
…ソレ…ウイルスなんじゃ…
東京に居る幼なじみのHくん…遠隔操作でこまめにチェックしてあげてください…


従姉夫婦が、赤ちゃん連れて来訪。
ウオオォ!! 赤ちゃん、カ、カ、カワイイー!! (*^▽^*)
ニコッと笑った時の顔が、もうなんともいえないナリ!! たまらん!!

抱っこさせてもらったけど、なんつーかこう…
温かさ、ふにゃふにゃ具合が、とっても気持ちいい。幸せ気分満喫… (´▽`)

2001/04/24(火) [n年前の日記]

#1 動画再生必要スペック

「逮捕」のOP、EDをMPEG4V2に変換していたり。

OPは、24fps化したらちゃんと再生されたんですけど。
EDが、ビデオ処理バリバリ使用。故に30fpsで変換したら…
これがまともに再生されない。音と絵がずれる。
途中から再生すると終わりがピタッと合うので、データ自身はちゃんとしてるらしい。
絵の再生が追いつかず、音より遅れちゃう模様。
セレ700MHzじゃ、640x480,30fpsは再生キツイですか。トホホ

2000/04/24(月) [n年前の日記]

#1 (NoTitle)狂犬病の予防注射をし...

狂犬病の予防注射をしてもらいに、犬を近所の公会堂まで連れていったです。
予想通り、地獄をみました。
ウチの犬は他の犬を見るとやたらと興奮して大暴れするため、綱をグイグイ引っ張って手が痛いのなんの。しかも、ところかまわず何回も糞をするし。糞を後片付けしてる間も綱を引っ張ってもう大変。この畜生めが。散歩に付き合う人間の様々な事情を少しは思いやるだけの想像力を持ちつつ糞に関してもせめて回数を減らすために常に体調を整えるよう努力することぐらいできないのか、ってそういうの犬に要求してもなぁ。
もうグッタリ。

i-mode対応ページを作ってみようと、以前書いた2つのエミュをインストールしてみたです。

使えん尿…

i-TOOLのほうは、表示が今一つ。
IEのモジュールを流用しているため、色々不具合があるとは聞いてましたが、これほどとは。
i-mode専用絵文字のうち表示されない文字がいくつかあったり、横スクロールバーが出てしまってレイアウト(?)が明らかに変わってしまったり、文字の装飾表示が有効になってしまったり…
とにかくi-mode対応と言われるページを実際に表示してみれば、「うーむ、これではねぇ」という感じがすぐわかってもらえると思うです。
かなり期待してたんですけどねぇ…

UP.simulatorなるエミュは、そもそもi-mode対応ページを表示できないので問題外でした。
インストール苦労しましたです。ある程度深いフォルダ階層からインストールの為の自動解凍をしようとすると途中でエラーを出すようで。おかげで「ファイルが壊れているのでは」と何度もDLする羽目に。ルートから一段下のフォルダにファイルコピーして作業したらスンナリ行きましたよ。トホホ
しかもコレ、インストールしただけで、リソース減らしちゃう。なんで?
酷い事に、そのリソース、アンインストールしても戻らない。
只でさえ少ないWin98のリソースが減ったまま。もう最低。
ただでさえ色々と怪しいWin98が、これでますます破滅へと近づいてしまった…

これはもう、dB-SOFTのHOTALLでも買うしかないのかな。
確かソレならi-mode対応ページを作れる仕様があるはず。
ということで値段を調べてみたり。¥17000前後ですか…
アホか。
そこまでしてやってられるかーい!! ヽ(`Д´)/ キーッ!
ということで、現時点では完全に諦めました >i-mode対応ページの作成
本家HPのHTMLを書く作業が、現在お金をかけずに出来ているのに、i-mode対応の為だけに出費するのはバカバカしい。
ちゃんと表示されてるかどうかもわからないHPなぞ作る気になりませんしね… (´Д`;)

もちろん、フリーで使えるi-modeエミュが入手できれば再検討するのですけど。
どこかに無いものですかねぇ…
でも考えてみたら、例のGIF問題でフリーで作るというわけにはいかないのか。どひぃ

1999/04/24() [n年前の日記]

#1 (NoTitle)「シルバーガン」を猿...

「シルバーガン」を猿のようにプレイ。これがまたアツイんですよ。アツクテシヌゼ!みたいな。(意味不明) 声優さんの演技がまたいい味出してる。「ゲキガンガーッ!」って感じ。
このゲーム、パワーアップ状態をゲームオーバー時にセーブし、次のプレイ時にその状態から始める、という仕様があるのですが、これが非常に助かります。私のようなヘボプレイヤーでも時間をかければ先に進むことができますんで。(それでも難しいですが。(T_T) )
でもこのゲーム、売れてるのかなぁ…なんか売れそうな気がしない。どうなんだろ。
…ああ、こうしている間にも禁断症状が…もう一回プレイしよ〜っと。
そういえば。「トラブルメーカーズ」でも前述の御二人、お仕事していたことをすっかり失念していました。メンゴ。何はともあれ良かった良かった(<だから何が?)

以上、26 日分です。

過去ログ表示

Prev - 2024/12 - Next
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project