mieki256's diary



2024/01/29(月) [n年前の日記]

#1 [basic] FreeBASICでSDL 1.xを使ってみたかった

_昨日、 FreeBASIC + ゲーム制作用ライブラリ raylib を試用してみたけれど。ゲーム制作用ライブラリなら SDL があるのではないか、FreeBASIC から SDL も使えるらしいのでそちらを使うのもアリではないのかと思えてきた。

でも、本当に FreeBASIC からSDLを使えるのだろうか。気になったので、少し試してみた。

環境は Windows10 x64 22H2 + FreeBASIC 1.10.1 32bit。

サンプルファイルの在処 :

FreeBASICには、SDL 1.x/2.xを使うサンプルファイルが同梱されてる。examples/graphics/SDL/*.bas がサンプルファイル群。

_fbc/examples/graphics/SDL at master - freebasic/fbc

コレが動けば、FreeBASIC + SDL が使える状態になっていると言えそう。

ちなみに、サンプル中の、sdl2-hello.bas だけが SDL2 を使うサンプルで、それ以外は SDL 1.x を使っているサンプルになっている。

要求されるバージョン :

FreeBASICインストールフォルダ/inc/SDL/ に、SDL 1.x用のヘッダーファイルがある。

_fbc/inc/SDL at master - freebasic/fbc

各ヘッダーファイル内に、当時対象にしていたのであろう、SDLのバージョンが書いてあったのでメモしておく。バージョンを合わせておいたほうがハマらずに済みそう。

SDL.bi       : SDL-1.2.15
SDL_image.bi : SDL_image-1.2.12
SDL_mixer.bi : SDL_mixer-1.2.12
SDL_ttf.bi   : SDL_ttf-2.0.11
SDL_net.bi   : SDL_net-1.2.8

SDL_gfx_framerate.bi       : SDL_gfx-2.0.26
SDL_gfx_imageFilter.bi     : SDL_gfx-2.0.26 
SDL_gfx_primitives.bi      : SDL_gfx-2.0.26
SDL_gfx_primitives_font.bi : SDL_gfx-2.0.26
SDL_gfx_rotozoom.bi        : SDL_gfx-2.0.26


ついでなので、SDL2用ヘッダーファイルに書かれていた SDL2のバージョンもメモしておく。

_fbc/inc/SDL2 at master - freebasic/fbc

SDL.bi       : SDL2-2.0.14
SDL_image.bi : SDL2_image-2.0.5
SDL_Mixer.bi : SDL2_mixer-2.0.4
SDL_net.bi   : SDL2_net-2.0.1
SDL_ttf.bi   : SDL2_ttf-2.0.15

SDL2_gfx_framerate.bi       : SDL2_gfx-1.0.4
SDL2_gfx_imageFilter.bi     : SDL2_gfx-1.0.4
SDL2_gfx_primitives.bi      : SDL2_gfx-1.0.4
SDL2_gfx_primitives_font.bi : SDL2_gfx-1.0.4
SDL2_gfx_rotozoom.bi        : SDL2_gfx-1.0.4

必要になるファイル :

FreeBASICから SDL 1.x/2.x を使うためには、MinGW用ライブラリファイル libsdl*.a と、SDLのランタイムファイル SDL*.dll が必要になる。

ランタイムファイル SDL*.dll については、公式サイトで配布されているので容易に入手できる。

_SDL - Index of /release
_SDL_image - Index of /projects/SDL_image/release
_SDL_mixer - Index of /projects/SDL_mixer/release
_SDL_ttf - Index of /projects/SDL_ttf/release
_SDL_net - Index of /projects/SDL_net/release

例えば SDL 1.2.15 の場合、以下の2つのファイルに .dll が入っている。x64とついているのが 64bit版。ついてないのが 32bit版。
SDL-1.2.15-win32.zip
SDL-1.2.15-win32-x64.zip
SDL_image や SDL_mixer 等も、上記と似たようなファイル名になっている。


問題は、MinGW用ライブラリ、libsdl*.a。このファイルの入手が難しい…。

配布ファイル名が「SDL*-devel-*-mingw*.tar.gz」になってたら、そのファイルの中にMinGW用ライブラリが入ってる可能性が高い。例えば以下のファイルには、MinGW用ライブラリが入ってる。
SDL-devel-1.2.15-mingw32.tar.gz
SDL2-devel-2.0.14-mingw.tar.gz
SDL2_image-devel-2.0.5-mingw.tar.gz

しかし…。
  • SDL2.x用ならMinGW用ライブラリも配布されているけれど、SDL 1.x 用は配布されてない。
  • SDL 1.x 本体だけは上記のように配布されているけれど、それ以外、SDL_image や SDL_Mixer等は用意されてない。
SDL 1.x 関係は、ソースファイル、ランタイム、Visual C++用ライブラリファイルしか入手できない。

知識のある人なら、MinGW や MSYS2 を使って、ソースファイルからビルドしてライブラリファイルをゲットできるのだろうけど…。

結論を先に書く。Visual C++用ライブラリ(*.lib)を、MinGW用ライブラリ(*.a)に変換できる reimp.exe というツールがMinGWに用意されてるので、ソレを使って MinGW用ライブラリを用意するのが一番楽。かもしれない。たぶん。

とりあえず、reimp を使って .lib から .a に変換した、SDL関連 MinGW用ライブラリ一式(32bit版のみ)を、zipでまとめて置いておきます。

_sdl_1x_win32_x86_lib_to_a.zip

これを解凍して、*.a と *.dll を、FreeBASIC + SDL 1.x を使うプロジェクトフォルダにごっそりコピーすればどうにかなるかなと…。

動作確認 :

こうして用意できた .a と .dll 群を、examples/graphics/SDL/ の中にコピーして、fbc32 xxxx.bas でコンパイルしていった。

_fbc/examples/graphics/SDL at master - freebasic/fbc

mouse.bas 以外はコンパイルが通って、動作してくれた。

mouse.bas だけコンパイルできない点は少し気になるけど…。ほとんどは動いてくれたから、まあいいか…。

reimpについて :

以降は、自分で lib*.a を用意したい場合の作業メモ。

Visual C++用ライブラリは拡張子が .lib。MinGW用ライブラリは拡張子が .a。そのままでは Visual C++ のライブラリを MinGW で使えない。 *1

しかし、MinGW の mingw-utils の中に、reimp.exe というツールがあって、コレを使うと .lib を .a に変換できる(可能性がある)と知った。

_MinGW - Minimalist GNU for Windows - Browse /MinGW/Extension/mingw-utils at SourceForge.net
_ohai日誌(2007-03-05)
_ソフトに関する雑記

ただ、注意点がある。mingw-utils は 0.4-1 以外を使うこと。

今回、手元の環境に mingw-utils-0.4-1 が入っていたので、reimp が使えるか試してみたのだけど、変換できないと言われてしまった。
> reimp SDL_mixer.lib
reimp: SDL_mixer.lib: invalid or corrupt import library

どの .lib も全く変換できないのでおかしいなと思ったら、mingw-utils-0.4-1 に入ってる版はバグがあるそうで…。

_MinGW GCC toolchain (Win) - TrinityCore - Confluence
If you are getting errors with the reimp command, you may need to rebuild the mingw-utils-0.4-1 package from source as the binary distribution contains a bug.

MinGW GCC toolchain (Win) - TrinityCore - Confluence より


mingw-utils-0.3 (mingw-utils-0.3.tar.gz) を入手して、その中に入っている reimp.exe を使ってみたら、あっさり .lib から .a に変換できてしまった…。こんな罠があるとは…。

SDL 1.x関連の.libを変換 :

以下のSDL関連ファイルを入手して、中に入っていた .libを変換した。
SDL_image-devel-1.2.12-VC.zip
SDL_mixer-devel-1.2.12-VC.zip
SDL_net-devel-1.2.8-VC.zip
SDL_ttf-devel-2.0.11-VC.zip

reimp SDL_image.lib
reimp SDL_mixer.lib
reimp SDL_net.lib
reimp SDL_ttf.lib

変換すると、.a と .def が生成される。
  • .a がMinGW用ライブラリ。
  • .def は、dlltool というツール用のファイル。

dlltool に .defファイルを渡してやることで、.dll の各機能を呼び出すためのライブラリ(lib*.a)を生成できるらしい。今回は lib*.a が reimp で得られたから、.def は必要ないとは思うけど…。

_dllからインポートライブラリを作成する方法

SDL本体は公式配布版を使う :

SDL本体だけはMinGW用ライブラリが配布されていたので、ソレをそのまま使うことにした。
SDL-devel-1.2.15-mingw32.tar.gz

_SDL - Index of /release

以下の2つのファイルを使う。
libSDL.dll.a
libSDLmain.a

余談。前述のファイルを解凍すると、ファイル名の先頭が「.」になってるファイルがたくさん入ってた。たぶんコレ、Mac用じゃないかなと…。無視して構わない。

SDL_gfxだけはビルドした :

SDL_gfx は Visual C++用ライブラリすら無かったので、MinGW (gcc 6.3.0) を使ってビルドした。

本来は .a と .dll の両方が必要になるけれど、FreeBASIC 1.10.1 32bit版の lib/ には、標準状態でも、libSDL_gfx.dll.a だけは同梱されていた。だから、プロジェクトフォルダ内に SDL_gfx.dll だけ置いておけば SDL_gfx を使える。つまり今回は SDL_gfx.dll を得るためだけにビルドする。

_SDL_gfx / SDL2_gfx - ferzkopp.net

SDL_gfx-2.0.26.tar.gz を入手して解凍。

中に Makefile.mingw という、MinGW用の Makefile があるのでソレを使ってビルドする。ただ、何ヶ所か修正しないといけない。
  • prefix には MinGWインストールフォルダを指定しないといけない。…もしかして make に渡すオプションで変更できたりする?
  • SDL_gfxBlitFunc.o というファイルもコンパイルしてリンクしてやる。

> diff Makefile.mingw.orig Makefile.mingw -u
--- Makefile.mingw.orig Tue Dec 22 12:00:31 2009
+++ Makefile.mingw      Mon Jan 29 05:16:00 2024
@@ -2,7 +2,7 @@
 AR=ar rc
 RANLIB=ranlib

-prefix=c:/dev
+prefix=D:/MinGW
 bin_dir=$(prefix)/bin
 include_dir=$(prefix)/include
 lib_dir=$(prefix)/lib
@@ -10,7 +10,7 @@
 CFLAGS = -O3 -march=athlon-xp -mmmx -msse -m3dnow -DBUILD_DLL -DWIN32 -I$(include_dir)/SDL
 LIBS = -L$(lib_dir) -lSDL

-OBJS = SDL_framerate.o SDL_gfxPrimitives.o SDL_imageFilter.o SDL_rotozoom.o
+OBJS = SDL_framerate.o SDL_gfxBlitFunc.o SDL_gfxPrimitives.o SDL_imageFilter.o SDL_rotozoom.o

 STATIC_LIB=libSDL_gfx.a
 IMPORT_LIB=libSDL_gfx.dll.a
@@ -49,13 +49,14 @@

 install: $(STATIC_LIB) $(SHARED_LIB)
        cp $(STATIC_LIB) $(SHARED_LIB) $(IMPORT_LIB) $(lib_dir)
-       cp SDL_framerate.h SDL_gfxPrimitives.h SDL_imageFilter.h SDL_rotozoom.h $(include_dir)/SDL
+       cp SDL_framerate.h SDL_gfxBlitFunc.h SDL_gfxPrimitives.h SDL_imageFilter.h SDL_rotozoom.h $(include_dir)/SDL

 uninstall:
        rm -f $(lib_dir)/$(STATIC_LIB)
        rm -f $(lib_dir)/$(SHARED_LIB)
        rm -f $(lib_dir)/$(IMPORT_LIB)
        rm -f $(include_dir)/SDL/SDL_framerate.h
+       rm -f $(include_dir)/SDL/SDL_gfxBlitFunc.h
        rm -f $(include_dir)/SDL/SDL_gfxPrimitives.h
        rm -f $(include_dir)/SDL/SDL_imageFilter.h
        rm -f $(include_dir)/SDL/SDL_rotozoom.h

このあたりは以下に情報があった。

_windows 7 - SDL_gfx 2.0.24 DLL is not build, using MinGW - Stack Overflow

修正できたら、以下でビルド。
make -f Makefile.mingw

SDL_gfx.dll が生成されているので、FreeBASICでは、この .dll を使う。

MinGWから使う予定があるなら、MinGWにインストール。
make -f Makefile.mingw install

*1: という話だったけど今は状況が違ってたりする、という話もどこかで見かけた記憶もあって…。どこで目にしたのだったか…。

#2 [prog] SDL 1.xをMinGWでビルドしようとしたけれど途中で挫折した

Windows + FreeBASICで SDL 1.x を使うためには、MinGW用ライブラリファイル libsdl*.a が必要になる。しかし、SDLの公式配布版は、Visual C++用ライブラリファイルはあっても、MinGW用は配布していない。

であればと、ソースを入手して、MinGWでビルドできるか試してみた。環境は Windows10 x64 22H2 + MinGW (gcc 6.3.0)。

ただ、途中で手詰まりになって、結局目的のファイル群は得られなかった…。そこから reimp を使って .lib を .a に変換して使う方向に切り替えた。とは言え、途中まではビルドできたので、何かのヒントぐらいにはなるかもしれない。一応作業メモを残しておく。

余談。MSYS2 なら SDL 1.x も SLD 2.x もパッケージで用意されてるので、MSYS2 を使う分にはSDL関連をわざわざビルドする必要はないです。

configureのオプション :

configure を使って Makefile を作る際、渡すオプションが色々あるらしい…? ググっていて見かけたものを一応メモしておく。
./configure --prefix=/mingw --disable-shared --disable-assembly
./configure --prefix=/mingw --disable-shared
./configure --prefix=/mingw
./configure --build=i686-pc-mingw32 --disable-shared
./configure --host=i686-pc-mingw32 --disable-shared
./configure --prefix=/mingw --without-png

  • --prefix=/mingw は、MinGW用だよと指定しているのだろう。たぶん。
  • --disable-shared は、DLLを作らない指定なのでは。スタティックリンク用のライブラリだけを作れ、ということかなと…。
  • --disable-assembly は謎。
  • --build=i686-pc-mingw32 は、Windows 32bit版を作れという指定だろうか。
  • --without-png は、pngをサポートしない版を作れ、ということだろうか。

ソースの入手 :

以下のファイルを入手して解凍。ちなみに、これではまだ足りない。jpeg や tiff関連のファイルも必要なはずなので…。
SDL-1.2.15.tar.gz
freetype-2.7.1.tar.gz
SDL_ttf-2.0.11.tar.gz
SDL_net-1.2.7.tar.gz
smpeg-0.4.4.tar.gz
libogg-1.1.3.tar.gz
libvorbis-1.2.0.tar.gz
SDL_mixer-1.2.12.tar.gz
SDL_image-1.2.12.tar.gz
SDL_gfx-2.0.26.tar.gz

入手先は以下。

_SDL - Index of /release
_SDL_image - Index of /projects/SDL_image/release
_SDL_mixer - Index of /projects/SDL_mixer/release
_SDL_ttf - Index of /projects/SDL_ttf/release
_SDL_net - Index of /projects/SDL_net/release
_SDL_gfx / SDL2_gfx - ferzkopp.net
_SDL_gfx - Browse Files at SourceForge.net
_Index of /releases/freetype/
_smpeg - mirrors.dotsrc.org
_Xiph.org: Downloads
_Ftp - /pub/xiph/releases/ogg/ :: Oregon State University Open Source Lab
_Ftp - /pub/xiph/releases/vorbis/ :: Oregon State University Open Source Lab

ビルドに挑戦 :

MinGW が使える状態、かつ、configure を使う関係で、bash を起動して、その上で作業していった。

ちなみに、tra zxvf hoge.tar.gz と打てば解凍できるはずなので、事前に解凍しておく必要はなかったかもしれない…。

SDL 1.2 のビルド。
cd SDL-1.2.15
./configure --prefix=/mingw
make
make install


SDL_ttf は freetype2 を必要とするので、freetype2 をビルド。--without-png で、pngはサポートしなくて良い、と指定してる。らしい。
cd ../freetype-2.7.1
./configure --prefix=/mingw --without-png
make
make install

SDL_ttf をビルド。
cd ../SDL_ttf-2.0.11
./configure --prefix=/mingw
make
make install


SDL_net をビルド。--disable-gui とつけて、GUI関係を無効にしてるのだろうか。
cd ../SDL_net-1.2.7
./configure --prefix=/mingw --disable-gui
make
make install


SDL_mixer は、smpeg、libogg、libvorbis が必要と言う話を見かけた。smpeg をビルド。
cd ../smpeg-0.4.4
./configure --prefix=/mingw

Makefile ができているので、147行目を修正。最後に -lstdc++ を追加。
LIBS = -L/usr/lib -lmingw32 -lSDLmain -lSDL -mwindows -lm -lstdc++

make
make install

しかし、make すると、MPEGaudio.cpp で Play_MPEGaudioSDL や Decode_MPEGaudio が無いとエラーが出る。以下を参考にして修正。

_smpegのコンパイル

MPEGaudio.h の最後に以下を追加。
void Play_MPEGaudioSDL(void *udata, Uint8 *stream, int len);  
int Play_MPEGaudio(MPEGaudio *audio, Uint8 *stream, int len);  
#ifdef THREADED_AUDIO  
int Decode_MPEGaudio(void *udata);  
#endif

audio/huffmantable.cpp でもエラーが出る。
huffmantable.cpp:587:1: error: narrowing conversion of '-1' from 'int' to 'unsigned int' inside { } [-Wnarrowing]
huffmantable.cpp:587:1: error: narrowing conversion of '-1' from 'int' to 'unsigned int' inside { } [-Wnarrowing]
huffmantable.cpp:587:1: error: narrowing conversion of '-1' from 'int' to 'unsigned int' inside { } [-Wnarrowing]
huffmantable.cpp:587:1: error: narrowing conversion of '-1' from 'int' to 'unsigned int' inside { } [-Wnarrowing]
huffmantable.cpp:587:1: error: narrowing conversion of '-1' from 'int' to 'unsigned int' inside { } [-Wnarrowing]

const HUFFMANCODETABLE MPEGaudio::ht[HTN] の中で、unsigned int 値を書かなきゃいけないところで、マイナス値を書いてしまっている部分がある。

「0-1」を 「(unsigned int)(0-1)」としてみたら、コンパイルが通るようになった。

audio/.libs/ の中に、libaudio.a, libaudio.la が生成されたが、make install で MinGWインストールフォルダ/lib/ にコピーしてくれなかった。手作業でコピーしておいた。


liboggをビルド。
cd ../libogg-1.1.3
./configure --prefix=/mingw --disable-shared
make
make install


libvorbisをビルド。
cd ./libvorbis-1.2.0
./configure --prefix=/mingw --disable-shared
make
make install

configure を実行した段階で、oggが無いと言われてエラーになってしまった。ついさっき、libogg をインストールしたはずだけど…。おかしい…。

...
checking for pthread_create in -lpthread... yes
checking for pkg-config... yes
checking for pkg-config... /d/Perls/strawberry/5.32.1.1-x64/perl/bin/pkg-config
checking for ogg >= 1.0... checking for Ogg... no
*** Could not run Ogg test program, checking why...
*** The test program failed to compile or link. See the file config.log for the
*** exact error that occured. This usually means Ogg was incorrectly installed
*** or that you have moved Ogg since it was installed. In the latter case, you
*** may want to edit the ogg-config script:
configure: error: must have Ogg installed!

このあたりで手詰まり。

参考ページ :

原因が分かってきた :

ビルドできなかった原因が少し分かってきた。

原因その1。ビルド中に、MinGWが持ってないはずのツールが呼び出されてた。

例えば、pkg-config というツールを MinGW は持っていないのだけど、環境変数 PATH の中に登録されていた Strawberry Perl の bin/ の中に pkg-config が存在していて、configure を実行した際に「pkg-config…持ってるね!」と処理されてた。

一時的に Perlの入っているフォルダ名をリネームして参照されないようにしたところ、動作が少し変わった。

原因その2。素人考えで bash を単独で起動させて、その上で作業してたのが間違いだった。

msys.bat を実行して、その上で作業していけばすんなりビルドできた…。例えば、今までは make: write error と表示されていた場面でも、エラーが出ずに進むようになった。

以下のページを目にして、msys.bat の実行が絡んでそうと気づいた…。

_DirectSoundとRubyのプログラミング その7 - mirichiの日記


ということは、今まで行った作業も何か怪しいことになってる可能性があるなと…。SDL のビルドからやり直してみた。

しかし今度は、smpeg のビルドで大量のエラーが出る…。またしても手詰まり。

以上、1 日分です。

過去ログ表示

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