mieki256's diary



2024/02/06(火) [n年前の日記]

#1 [basic][xyzzy] FreeBASIC用エディタについて少し試用中

今現在、FreeBASIC用のソースを、xyzzy というエディタで書いている。Visual BASICモードにすれば、そこそこ使えなくもない感じ。ただ、一部の命令が入るとインデントがおかしくなる。「end」が入ると、そこからずれる…。

もうちょっと便利なエディタは無いものか…。

xyzzy関係の設定をメモ :

xyzzy の basic-mode 関係の設定を、一応バックアップ的にメモ。
;; ----------------------------------------
;; VBScript (basic-mode)
(pushnew '("\\.vbs$" . basic-mode) *auto-mode-alist*)

;; ----------------------------------------
;; basicモードの設定
;; C-. でキーワード補完
;; タブをスペースに

(require "basic-mode")

(add-hook 'ed::*basic-mode-hook*
          #'(lambda ()
              (set-tab-columns 4 (selected-buffer))
              (setq ed::*basic-indent-level* 4)
              (make-local-variable 'indent-tabs-mode)
              (setq indent-tabs-mode nil)
              ))

(define-key *basic-mode-map* #\C-. 'ed::basic-completion)

(pushnew '("\\.bi$" . basic-mode) *auto-mode-alist*)

Unicode対応問題 :

FreeBASICのソース内に Unicode(utf8n)で日本語文字列を書くと、エディタによっては正常に表示されない。

EditorUnicodeSJIS日本語入力note
IUP_FB_EDITORGOODGOODGOOD文字コード判別はOS機能に任せてるのでどうしようもないらしい
FbEdit 1.0.7.4BADBADBAD表示も入力も一切できない
WinFBE 3.1.0 x86BADGOODBAD日本語入力できない
FBIde 0.4.6r4BADGOODBADインライン日本語入力できない
Geany 2.0GOODGOOD?インライン入力できるけど変換中の文字が小さくて見辛い
Notepad++ 8.6 32bitGOODGOODGOOD表示も入力も問題無し
Microsoft Visual Studio Code 1.86.0GOODBAD?Unicodeなら入力できる

FreeBASIC用を謳っているエディタの中で、Unicodeも表示できるのは IUP_FB_EDITOR ぐらいのようだなと…。

それぞれの入手先は以下。

_Main - IUP_FB_EDITOR
_FbEdit
_PaulSquires/WinFBE: FreeBASIC Editor for Windows
_FBIde - #1 editor for FreeBASIC
_Home | Geany
_Geany Portable (text editor and basic IDE) | PortableApps.com
_Notepad++

FBIde の「language file missing」 :

FBIde は、コマンドラインオプションでファイル名を渡しても、「language file missing」と警告が表示される。一応ファイルを開いてはいるけど…。

_fb024 Patcher Warning - freebasic.net

FBIde 0.4.6r2 を入手して、FbIdeFix.dll を 0.4.6r2版で置き換えれば、警告が出なくなるらしい。試してみたら、たしかに警告は出なくなった。

#2 [basic] FreeBASICで反転描画。その2

Windows10 x64 22H2 + FreeBASIC 1.10.1 32bit で、標準機能のグラフィック描画で反転描画する方法について調べてる。

_昨日 は、公式掲示板で紹介されていた、色々な実装を動作確認していたわけだけど。その中の imgput() がイイ感じだなと…。

_Put function that does simple transformations - freebasic.net

ただ、透明色を扱わない仕様だったので、透明色有りで動くようにできないかと修正を試みた。

ソース :

実処理部分。オリジナル版と混ざるとアレなので、サブルーチン名は imgput() から imgputt() にしておいた。

_imgputt.bi


imgputt()の使用サンプル。

_imgputt_test.bas
' imgput() sample. RGB = (255, 0, 255) is transparent

#include "imgputt.bi"

#define BPP  32
'#define BPP  16
'#define BPP  8

screenres 512, 288, BPP
Dim As Any Ptr p = ImageCreate(101, 101)
Select Case BPP
Case 8 : Bload "sprite_8bit.bmp", p : color 16, 16 : cls
Case 16 : Bload "sprite_16bit.bmp", p
Case 32 : Bload "sprite_24bit.bmp", p
End Select

Dim As Integer mode = 0  ' 0 Trans, 1 Pset

' Draw
imgputt( p, , 10 + 120 * 0, 10, 0,   mode)
imgputt( p, , 10 + 120 * 1, 10, 90,  mode)
imgputt( p, , 10 + 120 * 2, 10, 180, mode)
imgputt( p, , 10 + 120 * 3, 10, 270, mode)

imgputt( p, , 10 + 120 * 0, 130, TRANSFORM_HFLIP,  mode )
imgputt( p, , 10 + 120 * 1, 130, TRANSFORM_VFLIP,  mode )
imgputt( p, , 10 + 120 * 2, 130, TRANSFORM_D1FLIP, mode )
imgputt( p, , 10 + 120 * 3, 130, TRANSFORM_D2FLIP, mode )

imagedestroy p
sleep


使用画像。

_sprite_24bit.bmp
_sprite_16bit.bmp
_sprite_8bit.bmp

fbc imgputt_test.bas でコンパイル。imgputt_test.exe を実行。

imgputt_test_ss1.png

RGB = (255, 0, 255) の部分が透明になっている。

ベンチマークを取ってみた :

せっかくだから、Put() と比べてどのくらい遅いのか調べてみた。

また、ついでなので、昨日自分が書いた、縦1ライン、もしくは横1ライン毎に Put() を使って逆方向に描画する版( PutEx() )も測ってみた。

_putex.bi

_imgputt_test2.bas
#include "imgputt.bi"
#include "putex.bi"

#define BPP  32
'#define BPP  16
'#define BPP  8

screenres 512, 288, BPP
Dim As Any Ptr p = ImageCreate(101, 101)
Select Case BPP
Case 32 : Bload "sprite_24bit.bmp", p
Case 16 : Bload "sprite_16bit.bmp", p
Case 8 : Bload "sprite_8bit.bmp", p : color 16, 16 : cls
End Select

Dim As Double starttime, t0, t1, t2
Dim As Integer max_count = 3000

Sub sub1(ByVal max_count As Integer, ByVal p As Any Ptr)
    For i As Integer = 0 To max_count
        Put (10, 10), p, Trans
        ' Put (10, 10), p, Pset
    Next i
End Sub

Sub sub2(ByVal max_count As Integer, ByVal p As Any Ptr)
    For i As Integer = 0 To max_count
        'imgputt( p, , 130, 10, TRANSFORM_HFLIP, 0 )
        'imgputt( p, , 130, 10, TRANSFORM_VFLIP, 0 )
        imgputt( p, , 130, 10, TRANSFORM_HFLIP Or TRANSFORM_VFLIP, 0 )
    Next i
End Sub

Sub sub3(ByVal max_count As Integer, ByVal p As Any Ptr)
    For i As Integer = 0 To max_count
        'PutEx(10, 130, p, 0, 0, 101, 101, 1)
        'PutEx(10, 130, p, 0, 0, 101, 101, 2)
        PutEx(10, 130, p, 0, 0, 101, 101, 3)
    Next i
End Sub

starttime = Timer
ScreenLock
sub1(max_count, p)
ScreenUnlock
t0 = Timer - starttime

sleep 1000

starttime = Timer
ScreenLock
sub2(max_count, p)
ScreenUnlock
t1 = Timer - starttime

sleep 1000

starttime = Timer
ScreenLock
sub3(max_count, p)
ScreenUnlock
t2 = Timer - starttime

sleep 1000

Print "Put     : " & t0 & " sec (100%)"
Print "imgputt : " & t1 & " sec (" & int((t1 / t0) * 100) & "%)"
Print "PutEx   : " & t2 & " sec (" & int((t2 / t0) * 100) & "%)"

imagedestroy p
sleep

fbc imgputt_test2.bas でコンパイル。imgputt_test2.exe を実行。

  • imgputt() は、メモリからメモリに値をコピーするものとして処理をしている。
  • PutEx() は、横1ライン、もしくは縦1ライン毎に、Put() を使って逆方向に描画していく。水平垂直反転の時だけ、1ドット単位で Put() を呼んで描画する。

水平反転のみ、垂直反転のみ、水平垂直反転、の3つを測定。

imgputt_test2_ss1.png

imgputt_test2_ss2.png

imgputt_test2_ss3.png


フォントが小さくて読めないかもしれないけれど、大体以下のような結果になった。

  • 水平反転のみ、かつ、透明色有効の場合、Put() と比べて、imgputt() は5倍遅い。PutEx() は6倍遅い。
  • 垂直反転のみ、かつ、透明色有効の場合、Put() と比べて、imgputt() は5倍遅い。PutEx() は2倍遅い。
  • 水平垂直反転、かつ、透明色有効の場合、Put() と比べて、imgputt() は5倍遅い。PutEX() は135倍遅い。

imgputt() は、大体5倍ぐらい遅い。どの反転描画も似たような処理をするので、処理速度は安定している。

ライン単位で Put() を呼んでいく PutEx() はかなり遅いのではないかと思ってたけど、意外とそうでもなかった。imgputt() は5倍遅いけど、PutEx() の水平反転は6倍ちょっと程度。そんなに悪くない。垂直反転に至っては Put() の2倍程度で処理できてるので、5倍遅い imgputt() よりも処理が速かった。これは意外だった。

ただ、PutEx() で水平垂直反転をすると、最悪な結果になる。135倍遅いのは、さすがに…。おそらく、Put() を1回呼ぶたびに、画面をオーバーしてないか等を調べていくのだろうけど、それを1ドットずつやってたら話にならないよなと…。

Put()のソースを眺めてみた :

それにしても、標準描画機能の Put() は異様に速い。どういう処理をしているのだろう。github にC言語で書かれたソースがあったので眺めてみた。

_fbc/src/gfxlib2/gfx_put_trans.c at master - freebasic/fbc

fb_hPutTrans1C()、fb_hPutTrans2C()、fb_hPutTrans4C() があるけれど、それぞれ、色深度8bitモード(パレットモード)、16bitモード(RRRRRGGGGGGBBBB bit)、32bitモード(AARRGGBB byte)なのだろう。

やってることは、imgputt() とさほど変わらない印象。y と x でループを回して、1ドットずつ見ていって、値をコピーするかしないかを決めて、ポインタをしかるべき値で進める。まあ、そうなるよなあ…。

もしかして、+= ではなくて、++ をループ内で使ってるあたりが効いてるのだろうか?

以上、1 日分です。

過去ログ表示

Prev - 2024/02 - 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

カテゴリで表示

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


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

Powered by hns-2.19.6, HyperNikkiSystem Project