DeSmuMEで組み込まれているLua用API　非公式リファレンス　～guiライブラリ～

この記事はニンテンドーDS向けエミュレータの一つである「DeSmuME」（以降Desmume）のLua用APIの非公式日本語リファレンスです。今回はguiライブラリについてのリファレンスです。

:::note warn
このリファレンスは非公式の日本語リファレンスです。そもそも英語のリファレンスも公式のリファレンスもありません。
さらに詳細の仕様を確認したい場合はDesmumeのソースコードを参照することを推奨します。
→https://github.com/TASEmulators/desmume/blob/master/desmume/src/lua-engine.cpp
:::

---
`gui.register()`
エミュレータの描画（≠ゲームの描画）が更新される毎に引数の関数を呼び出す

<details><summary>引数</summary>

`string`型
呼び出したい関数

</details>

<details><summary>戻り値</summary>

無し　nil

</details>

``` lua: example.lua
local function Fn()

gui.text(0,10,string.format("Hello World!"))

end
gui.register(Fn)
```

---

`gui.text()`
エミュレータの画面上に文字列表示する。

<details><summary>引数</summary>

第一引数　X座標
範囲：`int`型
0~255が画面内　それ以外の値は画面外のため描画されません。

第二引数　Y座標
範囲：`int`型
-192~192が画面内　それ以外の値は画面外のため描画されません。

第三引数　メッセージ
`string`型
string.formatなど文字列操作を組み合わせることも可能

[第四引数：オプション]　文字色
`string`型　もしくは `int`型
0xRRGGBBAAで指定　`red` `orange`などメジャーな色の名前で指定も可能
省略時は`white`が指定される

[第五引数：オプション]　輪郭色
`string`型　もしくは `int`型
0xRRGGBBAAで指定　`red` `orange`などメジャーな色の名前で指定も可能
省略時は`black`が指定される

:::note warn
色指定に関して
Desmumeを含むほとんどのエミュレータでは80red glitchと言って0x7FFFFFFFF以上の値を指定すると描画が行われなくなるバグがあります。色の指定時には注意が必要です。
:::


</details>

<details><summary>戻り値</summary>

無し　nil

</details>

``` lua: example.lua
local function Fn()
local X = 100
local Y = 200

gui.text(0,10,"X: "..X)
gui.text(0,20,"Y: "..Y,"green","blue")

end
gui.register(Fn)
```

---

`gui.box()`
エミュレータの画面上にボックスを描画する

<details><summary>引数</summary>

第一引数　X座標起点
範囲：`int`型
0~255が画面内　それ以外の値は画面外のため描画されません。

第二引数　Y座標起点
範囲：`int`型
-192~192が画面内　それ以外の値は画面外のため描画されません。

第三引数　X座標終点
範囲：`int`型
0~255が画面内　それ以外の値は画面外のため描画されません。

第四引数　Y座標終点
範囲：`int`型
-192~192が画面内　それ以外の値は画面外のため描画されません。

[第五引数：オプション]　塗りつぶし色
`string`型　もしくは `int`型
0xRRGGBBAAで指定　`red` `orange`などメジャーな色の名前で指定も可能
省略時は`0xFFFFFF3F`が指定される
第六引数を省略した場合は第五引数色が枠線になり、その半透明色が第五引数に指定される。

[第六引数：オプション]　枠線
`string`型　もしくは `int`型
0xRRGGBBAAで指定　`red` `orange`などメジャーな色の名前で指定も可能
省略時は第五引数色が指定される。

:::note warn
色指定に関して
Desmumeを含むほとんどのエミュレータでは80red glitchと言って0x7FFFFFFFF以上の値を指定すると描画が行われなくなるバグがあります。色の指定時には注意が必要です。
:::

</details>

<details><summary>戻り値</summary>

無し　nil

</details>

``` lua: example.lua
local function Fn()

gui.box(0,0,30,30)
gui.box(60,60,100,100,"green","orange")

end
gui.register(Fn)
```

---

`gui.line()`
エミュレータの画面上に線分を描画する

<details><summary>引数</summary>

第一引数　X座標起点
範囲：`int`型
0~255が画面内　それ以外の値は画面外のため描画されません。

第二引数　Y座標起点
範囲：`int`型
-192~192が画面内　それ以外の値は画面外のため描画されません。

第三引数　X座標終点
範囲：`int`型
0~255が画面内　それ以外の値は画面外のため描画されません。

第四引数　Y座標終点
範囲：`int`型
-192~192が画面内　それ以外の値は画面外のため描画されません。

第五引数　色
`string`型　もしくは `int`型
0xRRGGBBAAで指定　`red` `orange`などメジャーな色の名前で指定も可能
省略時は`white`が指定される。

:::note warn
色指定に関して
Desmumeを含むほとんどのエミュレータでは80red glitchと言って0x7FFFFFFFF以上の値を指定すると描画が行われなくなるバグがあります。色の指定時には注意が必要です。
:::


</details>

<details><summary>戻り値</summary>

無し　nil

</details>

``` lua: example.lua
local function Fn()

gui.line(0,0,30,30)
gui.line(60,60,100,100,"green")

end
gui.register(Fn)
```

---

`gui.pixel()`
エミュレータの画面上に1pixel描画する。

<details><summary>引数</summary>

第一引数　X座標
範囲：`int`型
0~255が画面内　それ以外の値は画面外のため描画されません。

第二引数　Y座標
範囲：`int`型
-192~192が画面内　それ以外の値は画面外のため描画されません。

第三引数　色
`string`型　もしくは `int`型
0xRRGGBBAAで指定　`red` `orange`などメジャーな色の名前で指定も可能
省略時は`white`が指定される。

:::note warn
色指定に関して
Desmumeを含むほとんどのエミュレータでは80red glitchと言って0x7FFFFFFFF以上の値を指定すると描画が行われなくなるバグがあります。色の指定時には注意が必要です。
:::


</details>

<details><summary>戻り値</summary>

無し　nil

</details>

``` lua: example.lua
local function Fn()

gui.pixel(10,10,"green")

end
gui.register(Fn)
```

---

`gui.getpixel()`
描画されたゲーム画面の任意座標のRGB情報を取得する


<details><summary>引数</summary>


第一引数　X座標
範囲：`int`型
0~255が画面内　

第二引数　Y座標
範囲：`int`型
-192~192が画面内　

</details>

<details><summary>戻り値</summary>

第一戻り値　R値
`int`型

第二戻り値　G値
`int`型

第三戻り値　B値
`int`型

</details>

``` lua: example.lua
local function Fn()
local r,g,b

r,g,b = gui.getpixel(30,30)

gui.text(0,10,"R: "..r)
gui.text(0,20,"G: "..g)
gui.text(0,30,"B "..b)

end
gui.register(Fn)
```

---

`gui.opacity()`
その後に呼び出される関数の不透明度を設定する。

<details><summary>引数</summary>

`float`型　`int`型
0~1
0　＝　透明度1
1　＝　不透明

</details>

<details><summary>戻り値</summary>

無し nil

</details>

``` lua: example.lua
local function Fn()
local X = 100

gui.opacity(0.5)
gui.text(0,10,"X: "..X)

end
gui.register(Fn)
```
:::note info
透明度はこの関数を使用しなくても、各関数で設定可能です。　グローバルで一括設定したい場合などに利用するのが便利です。
:::

---

`gui.transparency()`
その後に呼び出される関数の不透明度を設定する。　レガシーな範囲版

<details><summary>引数</summary>

`float`型　`int`型
0~4

0　＝　透明度1
4　＝　不透明

</details>

<details><summary>戻り値</summary>

無し nil

</details>

``` lua: example.lua
local function Fn()
local X = 100

gui.transparency(2)
gui.text(0,10,"X: "..X)

end
gui.register(Fn)
```

:::note info
透明度はこの関数を使用しなくても、各関数で設定可能です。　グローバルで一括設定したい場合などに利用するのが便利です。
:::


---

`gui.popup()`
ポップアップウィンドウを表示させる

<details><summary>引数</summary>

`string`型

</details>

<details><summary>戻り値</summary>

無し　nil

</details>

``` lua: example.lua
gui.popup(string.format("Hello World!"))
```

---

`gui.parsecolor()`
引数のRGBA情報を返します。

<details><summary>引数</summary>

`string`型　もしくは `int`型
0xRRGGBBAAで指定　`red` `orange`などメジャーな色の名前で指定も可能
省略時は`white`が指定される。


</details>

<details><summary>戻り値</summary>

第一戻り値　R値
`int`型

第二戻り値　G値
`int`型

第三戻り値　B値
`int`型

第四戻り値　A値
`int`型

</details>

``` lua: example.lua
local function Fn()
local r,g,b

r,g,b,a = gui.parsecolor("green")

gui.text(0,10,"R: "..r)
gui.text(0,20,"G: "..g)
gui.text(0,30,"B: "..b)
gui.text(0,40,"A: "..a)

end
gui.register(Fn)
```

---

`gui.setlayermask()`
任意のレイヤーを非表示にする。

<details><summary>引数</summary>

第一引数 メイン画面（上画面）レイヤー
`int`型
0~31

bitが立っているものが表示

0(00000) 無し hides all layer
1(00001) Main BG0
2(00010) Main BG1
4(00100) Main BG2
8(01000) Main BG3
16(10000) Main OBJ
31(11111) 全表示

第二引数　サブ画面（下画面）レイヤー
`int`型
0~31

bitが立っているものが表示

0(00000) 無し hides all layer
1(00001) Sub BG0
2(00010) Sub BG1
4(00100) Sub BG2
8(01000) Sub BG3
16(10000) Sub OBJ
31(11111) 全表示

</details>

<details><summary>戻り値</summary>

無し　nil

</details>

``` lua: example.lua
local function Fn()

gui.setlayermask(16,16)

end
gui.register(Fn)
```
:::note warn
ソースコードを読む限り32bit版のDesmumeでしか動かない可能性があります。
64bit版では上のコード動きません。（サンプルコードが間違っているかも？）
またWindows版限定のAPIです。
:::


---

`gui.gdscreenshot()`
スクリーンショットを取得する。

<details><summary>引数</summary>

[第一引数：オプション]　画面選択
`both`:上画面下画面両方
`top`:上画面
`bottom`:下画面
省略した場合`both`が指定される

</details>

<details><summary>戻り値</summary>

`string`型
11byteのヘッダー+4byte(ARGB)/pixelの文字列

</details>

``` lua: example.lua
require "gd"
gd.createFromGdStr(gui.gdscreenshot()):png("outputimage.png")

```

:::note warn
gd.dll (32bit/64bit)をエミュレーターがあるディレクトリに配置しないと上のコードは動きません。
:::


---

`gui.gdoverlay()`
gdstr 形式の gd 画像を画面上に重ね書きする

<details><summary>引数</summary>

[第一引数：オプション]　起点X座標
`int`型
0~255
省略した場合0が指定される

[第二引数：オプション]　起点Y座標
`int`型
-192~192
省略した場合0が指定される

第三引数　画像
`string`型
gdstr形式である必要がある

[第四引数:オプション]　画像起点X座標
`int`型
省略した場合0が指定される

[第五引数:オプション]　画像起点Y座標
`int`型
省略した場合0が指定される

[第六引数:オプション]　width
`int`型

[第七引数:オプション]　height
`int`型

[第八引数：オプション]　透明度
`float`型
省略した場合は1.0が指定される

:::note warn
第四引数から第七引数はどれかを指定した場合は全て省略不可
:::


</details>

<details><summary>戻り値</summary>

無し nil

</details>

``` lua: example.lua
local function Fn()

require "gd"
gui.gdoverlay(gd.createFromPng("hogehoge.png"):gdStr())

end
gui.register(Fn)
```

---

`gui.redraw()`
画面を再読み込み&描画

<details><summary>引数</summary>

無し　nil

</details>

<details><summary>戻り値</summary>

無し　nil

</details>

``` lua: example.lua
gui.redraw()
```

:::note warn
guiライブラリと勘違いされがちですがemuライブラリです。　代替名として用意されているだけです。
:::


---

`gui.osdtext()`
画面上に直接文字列を描画する

<details><summary>引数</summary>

第一引数　X座標
範囲：`int`型
0~255が画面内　それ以外の値は画面外のため描画されません。

第二引数　Y座標
範囲：`int`型
-192~192が画面内　それ以外の値は画面外のため描画されません。

第三引数　メッセージ
`string`型
string.formatなど文字列操作を組み合わせることも可能

</details>

<details><summary>戻り値</summary>

無し　nil

</details>

``` lua: example.lua
local function Fn()

gui.osdtext(0,10,"Hello World!")

end
gui.register(Fn)
```

:::note alert
これを実行すると手元の環境ではDeSmuMEがクラッシュします　回避法が不明
:::


---

代替名一覧
以下の関数でコードを書いても右側の関数として認識されます。

`drawtext`→`gui.text()`
`drawbox`→`gui.box()`
`drawline`→`gui.line()`
`drawpixel`→`gui.pixel()`
`setpixel`→`gui.pixel()`
`writepixel`→`gui.pixel()`
`readpixel`→`gui.getpixel()`
`rect`→`gui.box()`
`drawrect`→`gui.box()`
`drawimage`→`gui.gdoverlay()`
`image`→`gui.gdoverlay()`