diff --git a/.gitignore b/.gitignore
index 94e7b259..96c2109d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,4 +17,7 @@
*.vs
*.ps
*.opendb
+*.iobj
+*.ipdb
+*.VC.db
/test/output/
diff --git a/kuin.sln b/kuin.sln
index 291d1f8f..7a26d651 100644
--- a/kuin.sln
+++ b/kuin.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
-VisualStudioVersion = 14.0.25123.0
+VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "compiler", "src\compiler\compiler.vcxproj", "{386064E7-EF36-4A2C-BAA1-0085F547AE60}"
EndProject
@@ -30,6 +30,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_math", "src\lib_math\li
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_net", "src\lib_net\lib_net.vcxproj", "{804409A7-FFE4-4BBE-8FCF-6FE250BCDC56}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_draw2d", "src\lib_draw2d\lib_draw2d.vcxproj", "{9136E651-D063-49FD-AD03-4F21EC347407}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -81,6 +83,12 @@ Global
{804409A7-FFE4-4BBE-8FCF-6FE250BCDC56}.Release_dbg|x64.Build.0 = Release_dbg|x64
{804409A7-FFE4-4BBE-8FCF-6FE250BCDC56}.Release_rls|x64.ActiveCfg = Release_rls|x64
{804409A7-FFE4-4BBE-8FCF-6FE250BCDC56}.Release_rls|x64.Build.0 = Release_rls|x64
+ {9136E651-D063-49FD-AD03-4F21EC347407}.Debug|x64.ActiveCfg = Debug|x64
+ {9136E651-D063-49FD-AD03-4F21EC347407}.Debug|x64.Build.0 = Debug|x64
+ {9136E651-D063-49FD-AD03-4F21EC347407}.Release_dbg|x64.ActiveCfg = Release_dbg|x64
+ {9136E651-D063-49FD-AD03-4F21EC347407}.Release_dbg|x64.Build.0 = Release_dbg|x64
+ {9136E651-D063-49FD-AD03-4F21EC347407}.Release_rls|x64.ActiveCfg = Release_rls|x64
+ {9136E651-D063-49FD-AD03-4F21EC347407}.Release_rls|x64.Build.0 = Release_rls|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/package/readme.txt b/package/readme.txt
index cc8f4ba6..9239611f 100644
--- a/package/readme.txt
+++ b/package/readme.txt
@@ -1,6 +1,6 @@
-------------------------------------------------------------------------------
Kuin Programming Language
-v.2018.7.17
+v.2019.9.17
(C) Kuina-chan
-------------------------------------------------------------------------------
@@ -11,8 +11,8 @@ v.2018.7.17
「くいなちゃん」が制作するプログラミング言語「Kuin」へようこそ。
Kuinは、簡単で高速な実用プログラミング言語です。
- 初めて触れる方は「チュートリアル( http://kuina.ch/kuin/a101 )」に沿ってお進
- めください。
+ 初めて触れる方は「チュートリアル( http://kuina.ch/kuin/tutorial1 )」に
+ 沿ってお進めください。
また、Kuinの詳細については「Kuinドキュメント( http://kuina.ch/kuin )」をご覧
ください。
@@ -43,6 +43,150 @@ v.2018.7.17
4. 変更履歴
-------------------------------------------------------------------------------
+v.2019.9.17
+ - 3D描画の環境光の計算の不具合の修正
+ - 影を描画する機能と、フラットに描画する機能の追加
+ - 細かな機能追加
+ - sql@Sql.getBlob、sql@Sql.errMsgメソッドの追加
+
+v.2019.8.17
+ - 画面を視覚的に作成できる機能の操作性の向上
+
+v.2019.6.17
+ - 任意のファイルをdataフォルダ以下に自動コピーできる機能をエディタに追加
+ - sndライブラリで、ストリーミング再生時にもsetPosやgetPosが行えるように拡張
+ - 画面を視覚的に作成できる機能を大幅に改善
+ - スニペット機能を大幅に改善
+ - 細かな機能追加
+ - テキストの拡縮描画が行えるdraw@Font.drawScaleメソッドの追加
+ - draw@Blendに%exclusion(除外)の追加
+ - BGM再生に特化したbgmライブラリ、カーソル処理を行うcursorライブラリの
+ 追加
+
+v.2019.5.17
+ - 細かな機能追加
+ - エディタの操作感の改善
+ - テクスチャや画像のサイズを取得するdraw@Tex.width、draw@Tex.height、
+ draw@Tex.imgWidth、draw@Tex.imgHeightメソッドの追加
+ - cui@delimiter、cui@inputLetter、cui@inputInt、cui@inputFloat、
+ cui@inputChar、cui@inputStr、math@fibonacci関数の追加
+ - num@BigInt、num@BigFloat、num@Complexクラスの追加
+ - 細かな不具合の修正
+ - 「条件式?(null,参照型)」とすると、参照型の値がまれに壊れることがある
+ 不具合の修正
+ - 継承元クラスにaliasを指定するとコンパイルエラーが発生する不具合の修正
+
+v.2019.4.17
+ - 細かな機能追加
+ - エディタの操作感の改善
+ - エディタの関数のヒント表示を分かりやすく改善
+ - エディタのメニューに「最近使ったファイル」の追加
+ - 小さいバッファを作成して荒いドットで描画できるwnd@makeDrawReduced関数
+ の追加
+ - 細かな不具合の修正
+ - エディタで変更していないときに保存を促すメッセージが出ることがある
+ 不具合の修正
+ - エディタのスクロールバー上でマウスカーソルがちらつく問題の修正
+ - :+演算子等の左辺値が2回評価される不具合の修正
+
+v.2019.3.17
+ - 一部のビデオカードを使用した環境で、文字の描画が崩れる問題の修正
+ - 細かな機能追加
+ - draw@makePlane、draw@makeBox、draw@makeSphere関数の追加
+ - 3D描画の大幅な改善
+ - サンプルの修正
+
+v.2019.2.17
+ - 細かな機能追加
+ - kuincl.exeに「-a」オプションが指定できない不具合の修正
+ - dbg@printで出力したテキストに合わせてスクロールバーを自動でスクロール
+ するように改善
+
+v.2019.1.17
+ - ウインドウを視覚的に作成する機能の操作性の改善
+ - 2D描画を視覚的に作成する機能の追加
+ - file@Readerがリリースビルド時にresフォルダ内のファイルを読み込めない不具合
+ の修正
+ - 細かな機能追加
+ - draw@Font.setHeight、draw@Font.getHeight、draw@Font.calcSize、
+ draw@Font.alignメソッドの追加
+ - draw@Font.drawメソッドで、文字列に'\n'が含まれていたときに改行する
+ ように改善
+ - []char.toIntメソッドで、「0x」から始まる場合には16進数として変換する
+ ように改善
+
+v.2018.12.17
+ - ウインドウを視覚的に作成する機能を全面的に作り直し
+ - エディタ上でファイルを保存することなくファイルの追加ができるように改善
+ - 互換性が失われる変更
+ - wnd@ListViewに画像を設定できるようにし、それに伴い引数等の変更
+
+v.2018.11.17
+ - ローカルなデータベース(SQLite)が構築できるsqlライブラリの追加
+ - 高度な2D図形が描画できるdraw2dライブラリの追加
+ - 互換性が失われる変更
+ - dict.getの引数で存在の有無が取得できるように、引数を変更
+ - []char.toInt、[]char.toFloatの引数をdict.getと同じ形に変更
+ - 細かな機能追加
+ - file@setCurDir、file@getCurDir、lib@countUp、draw@capture、
+ file@moveDir、file@fullPath、zip@unzip関数の追加
+ - dict.delメソッドの追加
+ - 細かな不具合の修正
+ - カレントディレクトリがexeの位置に書き換わっていたのを、書き換えない
+ ように修正
+ - file@makeDir関数が相対パスでは正しく動作しない不具合の修正
+ - int型の^演算子で、結果がintの範囲内になるにもかかわらず
+ オーバーフローの例外が発生することがある不具合の修正
+ - game@Map.setとgame@Map.findが正しく動作していなかった不具合の修正
+ - 配列.find、配列.findLastの第2引数に-1以外を指定したときの動作が
+ おかしくなっていた不具合の修正
+
+v.2018.10.17
+ - ピクセル単位で色の読み書きができるwnd@DrawEditableクラスと、使い方を示す
+ 0014_edit_pixelsサンプルの追加
+ - エディタの補完時に強制終了することがある不具合の修正
+ - エディタの補完時の挙動を改善
+ - 互換性が失われる変更
+ - file@Reader.delimiterに'\n'を登録しない場合に、改行を区切り文字と
+ みなさないように変更
+ - 細かな機能追加
+ - 「#」「##」「$>」「$<」演算子が使えないクラスにこれらを使うと、
+ コンパイル時にエラーにするように改善
+ - デバック実行の終了後にエディタウインドウをアクティブにするように改善
+ - wnd@Drawクラスのクリアが手動で行える、draw@autoClear、draw@clear関数
+ の追加
+ - wnd@fileDialogDir、draw@circleLine、draw@poly、draw@polyLine関数の
+ 追加
+ - draw@circle関数の描画結果にアンチエイリアスがかかるように改善
+ - 細かな不具合の修正
+ - 要素数が0のdict型のtoBinメソッドを呼ぶと例外が発生する不具合の修正
+ - resフォルダが存在しないときにkuincl.exeがログに「Failure.」を出力
+ する不具合の修正
+ - クラスの参照が巡回しているときにコンパイルに失敗することがある
+ 不具合の修正
+
+v.2018.9.17
+ - エディタの補完機能を改善
+ - エディタのカーソル表示が消えたり残像が残ったりする問題の改善
+ - エディタにブレークポイント機能を追加
+ - 例外が発生したときの位置を行単位で特定するように改善
+ - 細かな不具合の修正
+ - エディタで検索ウインドウを表示せずにF3を押すと終了する不具合の修正
+ - class内にclassを定義するとエディタが終了する不具合の修正
+ - リリースビルド時にresフォルダ内のxmlファイルがxml@makeXml関数で
+ 読み込めない不具合の修正
+
+v.2018.8.17
+ - エディタにすべてのドキュメントや選択範囲から検索や置換ができる機能を追加
+ - エディタに「res」フォルダを開く機能を追加
+ - エディタにファイルをドロップして開く機能を追加
+ - game@ライブラリの追加
+ - game@ライブラリに2Dマップチップと衝突判定を扱うクラスの追加
+ - game@ライブラリにシューティングゲームのステージやスタッフロールを扱う
+ クラスの追加
+ - 粒子を描画するdraw@Particleクラスの追加
+ - 2Dゲーム用のフリー素材を添付
+
v.2018.7.17
- よく使うコードを簡単に挿入できる、スニペット機能の追加
- 互換性が失われる変更
diff --git a/package/samples/0000_kuinvaders/res/title.jpg b/package/samples/0000_kuinvaders/res/title.jpg
index a5f05050..9e842314 100644
Binary files a/package/samples/0000_kuinvaders/res/title.jpg and b/package/samples/0000_kuinvaders/res/title.jpg differ
diff --git a/package/samples/0002_draw_2d/main.kn b/package/samples/0002_draw_2d/main.kn
index cb611fff..2d5e6591 100644
--- a/package/samples/0002_draw_2d/main.kn
+++ b/package/samples/0002_draw_2d/main.kn
@@ -8,11 +8,14 @@ func main()
var fontMonospace: draw@Font :: draw@makeFont(null, 32, false, false, false, 40.0) {等幅フォントの生成}
do draw@clearColor(0xFF333333) {背景色の設定}
while(wnd@act())
- do draw@line(100.0, 100.0, 200.0, 200.0, 0xFFFF3333) {線分}
- do draw@rectLine(300.0, 100.0, 100.0, 100.0, 0xFF33FF33) {四角形の枠線}
- do draw@rect(500.0, 100.0, 100.0, 100.0, 0xFF3333FF) {四角形}
- do draw@circle(750.0, 150.0, 50.0, 50.0, 0xFFFFFF33) {円}
- do draw@tri(950.0, 100.0, 900.0, 200.0, 1000.0, 200.0, 0xFFFF33FF) {三角形}
+ do draw2d@line(100.0, 100.0, 200.0, 200.0, 3.0, 0xFFFF3333) {線分}
+ do draw2d@rectLine(250.0, 100.0, 100.0, 100.0, 3.0, 0xFF33FF33) {四角形の枠線}
+ do draw2d@rect(400.0, 100.0, 100.0, 100.0, 0xFF3333FF) {四角形}
+ do draw2d@circle(600.0, 150.0, 50.0, 50.0, 0xFFFFFF33) {円}
+ do draw2d@circleLine(750.0, 150.0, 50.0, 50.0, 3.0, 0xFFFFFF33) {円}
+ do draw2d@tri(900.0, 100.0, 850.0, 200.0, 950.0, 200.0, 0xFFFF33FF) {三角形}
+ do draw@polyLine([1000.0, 1000.0, 1100.0, 1100.0, 1000.0], [100.0, 200.0, 100.0, 200.0, 100.0], [0xFF33FFFF, 0xFFFFFFFF, 0xFF33FFFF, 0xFFFFFFFF, 0xFF33FFFF]) {多角形}
+ do draw@poly([1150.0, 1150.0, 1200.0, 1200.0, 1250.0, 1250.0], [100.0, 200.0, 150.0, 150.0, 100.0, 200.0], [0xFF33FFFF, 0xFF33FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF33FFFF, 0xFF33FFFF]) {多角形}
for i(0, 3)
do texKuin.draw(100.0 + i $ float * 200.0, 300.0, 0.0, 0.0, 150.0, 150.0, draw@white) {画像}
end for
@@ -26,8 +29,16 @@ func main()
do draw@blend(%alpha)
do texKuin.drawScale(100.0, 500.0, 300.0, 300.0, 0.0, 0.0, 150.0, 150.0, draw@white) {拡大}
do texKuin.drawRot(500.0, 575.0, 150.0, 150.0, 0.0, 0.0, 150.0, 150.0, 75.0, 75.0, -draw@cnt() $ float * lib@pi / 60.0, draw@white) {回転}
- do fontProportional.draw(1100.0, 100.0, "Proportional", draw@white) {プロポーショナルフォント}
- do fontMonospace.draw(1100.0, 200.0, "Monospace", draw@white) {等幅フォント}
+ var width: float
+ var height: float
+ do fontProportional.align(%center, %top)
+ do fontMonospace.align(%center, %top)
+ do fontProportional.calcSize(&width, &height, "Propor\ntional")
+ do fontProportional.draw(1100.0, 300.0, "Propor\ntional", draw@white) {プロポーショナルフォント}
+ do draw@rect(1100.0, 300.0, width, height, 0x7FFF0000)
+ do fontMonospace.calcSize(&width, &height, "Mono\nspace")
+ do fontMonospace.draw(1100.0, 400.0, "Mono\nspace", draw@white) {等幅フォント}
+ do draw@rect(1100.0, 400.0, width, height, 0x7FFF0000)
do draw@render(60)
end while
end func
diff --git a/package/samples/0003_draw_3d/main.kn b/package/samples/0003_draw_3d/main.kn
index 07c519e9..638220c9 100644
--- a/package/samples/0003_draw_3d/main.kn
+++ b/package/samples/0003_draw_3d/main.kn
@@ -10,7 +10,7 @@ func main()
var objSphere: draw@Obj :: draw@makeObj("res/sphere.knobj") {球モデルの読み込み}
var texSphere: draw@Tex :: draw@makeTex("res/sphere.png") {球モデル用のテクスチャの読み込み}
var objCone: draw@Obj :: draw@makeObj("res/cone.knobj") {コーンモデルの読み込み}
- var texCone: draw@Tex :: draw@makeTexEvenArgb(1.0, 0.7, 0.2, 0.1)
+ var texCone: draw@Tex :: draw@makeTexEvenArgb(1.0, 0.35, 0.1, 0.05)
var texConeSpecular: draw@Tex :: draw@makeTexEvenArgb(2.0, 0.3, 0.3, 0.3)
do draw@clearColor(0xFF999999) {背景色の設定}
do draw@depth(true, true) {Zバッファの設定}
diff --git a/package/samples/0003_draw_3d/main.knprop b/package/samples/0003_draw_3d/main.knprop
index 6cd4386b..b406c8d8 100644
--- a/package/samples/0003_draw_3d/main.knprop
+++ b/package/samples/0003_draw_3d/main.knprop
@@ -2,5 +2,8 @@
wnd
+ 5
+ 1
+
diff --git a/package/samples/0003_draw_3d/res/board.knobj b/package/samples/0003_draw_3d/res/board.knobj
index 588dc75b..490513d6 100644
Binary files a/package/samples/0003_draw_3d/res/board.knobj and b/package/samples/0003_draw_3d/res/board.knobj differ
diff --git a/package/samples/0003_draw_3d/res/box.knobj b/package/samples/0003_draw_3d/res/box.knobj
index 32b85840..07d3d95c 100644
Binary files a/package/samples/0003_draw_3d/res/box.knobj and b/package/samples/0003_draw_3d/res/box.knobj differ
diff --git a/package/samples/0003_draw_3d/res/cone.knobj b/package/samples/0003_draw_3d/res/cone.knobj
index c65cf255..8dc44c18 100644
Binary files a/package/samples/0003_draw_3d/res/cone.knobj and b/package/samples/0003_draw_3d/res/cone.knobj differ
diff --git a/package/samples/0003_draw_3d/res/sphere.knobj b/package/samples/0003_draw_3d/res/sphere.knobj
index 39415c8d..61c7eceb 100644
Binary files a/package/samples/0003_draw_3d/res/sphere.knobj and b/package/samples/0003_draw_3d/res/sphere.knobj differ
diff --git a/package/samples/0009_file/main.kn b/package/samples/0009_file/main.kn
index 8ebe106f..3eef0b57 100644
--- a/package/samples/0009_file/main.kn
+++ b/package/samples/0009_file/main.kn
@@ -45,7 +45,7 @@ func main()
; ファイルをカンマ区切りで読み込む
var reader: file@Reader :: file@makeReader(@fileName) {ファイルを読み込みモードで開く}
- do reader.delimiter([',']) {区切り文字を指定}
+ do reader.delimiter(['\n', ',']) {区切り文字を指定}
while(!reader.term()) {ファイル終端までループ}
do str :~ reader.readStr() ~ "\n" {区切った文字列を読み込み}
end while
diff --git a/package/samples/0012_kuina_chan_model/main.kn b/package/samples/0012_kuina_chan_model/main.kn
index 20b437c2..b46dfdc7 100644
--- a/package/samples/0012_kuina_chan_model/main.kn
+++ b/package/samples/0012_kuina_chan_model/main.kn
@@ -8,6 +8,7 @@ func main()
var texNormal: draw@Tex :: draw@makeTexArgb("res/normal.png") {くいなちゃんモデル用の法線マップテクスチャの読み込み}
do draw@clearColor(0xFFEEEEEE) {背景色の設定}
do draw@depth(true, true) {Zバッファの設定}
+ do draw@ambLight(0.9, 0.9, 1.0, 1.0, 0.9, 0.9) {環境光の設定}
do obj.pos(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0) {くいなちゃんモデルの位置設定}
var angle: float :: 0.0 {カメラの角度}
do draw@proj(lib@pi / 180.0 * 27.0, 16.0, 9.0, 0.1, 100.0) {プロジェクションの設定}
diff --git a/package/samples/0012_kuina_chan_model/main.knprop b/package/samples/0012_kuina_chan_model/main.knprop
index 6cd4386b..b406c8d8 100644
--- a/package/samples/0012_kuina_chan_model/main.knprop
+++ b/package/samples/0012_kuina_chan_model/main.knprop
@@ -2,5 +2,8 @@
wnd
+ 5
+ 1
+
diff --git a/package/samples/0012_kuina_chan_model/res/kuina_chan.knobj b/package/samples/0012_kuina_chan_model/res/kuina_chan.knobj
index 947575e4..0b102740 100644
Binary files a/package/samples/0012_kuina_chan_model/res/kuina_chan.knobj and b/package/samples/0012_kuina_chan_model/res/kuina_chan.knobj differ
diff --git a/package/samples/0013_collision_and_particles/main.kn b/package/samples/0013_collision_and_particles/main.kn
new file mode 100644
index 00000000..af3d5b6b
--- /dev/null
+++ b/package/samples/0013_collision_and_particles/main.kn
@@ -0,0 +1,71 @@
+; Collision and Particles Sample (C)Kuina-chan
+
+func main()
+ class Item(game@Rect)
+ +var weight: float
+ end class
+
+ const itemNum: int :: 15
+ var wndMain: wnd@Wnd :: wnd@makeWnd(null, %aspect, 1600, 900, "Collision and Particles Sample") {ウインドウの生成}
+ var drawMain: wnd@Draw :: wnd@makeDraw(wndMain, 0, 0, 1600, 900, %scale, %scale, false) {ドローコントロールの生成}
+ var particle: draw@Particle :: draw@makeParticle()
+ do particle.lifespan :: 30
+ do particle.color2 :: 0x00FFFFFF
+ var texParticle: draw@Tex :: draw@makeTex("res/tex_particle.png")
+ var rects: []Item :: #[itemNum]Item
+ for i(0, itemNum - 1)
+ do rects[i] :: #Item
+ end for
+ do rects[0].x :: 0.0
+ do rects[0].y :: 450.0
+ do rects[0].width :: 50.0
+ do rects[0].height :: 900.0
+ do rects[1].x :: 800.0
+ do rects[1].y :: 0.0
+ do rects[1].width :: 1600.0
+ do rects[1].height :: 50.0
+ do rects[2].x :: 1600.0
+ do rects[2].y :: 450.0
+ do rects[2].width :: 50.0
+ do rects[2].height :: 900.0
+ do rects[3].x :: 800.0
+ do rects[3].y :: 900.0
+ do rects[3].width :: 1600.0
+ do rects[3].height :: 50.0
+ for i(0, 3)
+ do rects[i].weight :: inf
+ end for
+ for i(4, itemNum - 1)
+ do rects[i].x :: lib@rndFloat(100.0, 1500.0)
+ do rects[i].y :: lib@rndFloat(100.0, 800.0)
+ do rects[i].width :: 80.0
+ do rects[i].height :: 80.0
+ do rects[i].veloX :: lib@rndFloat(-10.0, 10.0)
+ do rects[i].veloY :: lib@rndFloat(-10.0, 10.0)
+ do rects[i].weight :: 1.0
+ end for
+
+ do draw@clearColor(0xFF333333) {背景色の設定}
+ while(wnd@act())
+ do draw@blend(%add)
+ do particle.draw2d(texParticle)
+ do draw@blend(%alpha)
+ for i(0, itemNum - 1)
+ do rects[i].move(0.0)
+ end for
+ for i(0, itemNum - 1)
+ for j(0, i - 1)
+ if(game@hitRectRect(rects[i], rects[j], rects[i].weight, rects[j].weight, 1.0, 0.0) <> %none)
+ for k(0, 19)
+ do particle.emit(rects[i].x, rects[i].y, 0.0, lib@rndFloat(-3.0, 3.0), lib@rndFloat(-3.0, 3.0), 0.0, 150.0, 0.5, 0.0, lib@rndFloat(-lib@pi / 30.0, lib@pi / 30.0))
+ end for
+ end if
+ end for
+ end for
+ for i(0, itemNum - 1)
+ do rects[i].update()
+ do draw@rect(rects[i].x - rects[i].width / 2.0, rects[i].y - rects[i].height / 2.0, rects[i].width, rects[i].height, 0xFF9999FF)
+ end for
+ do draw@render(60)
+ end while
+end func
diff --git a/package/samples/0013_collision_and_particles/main.knprop b/package/samples/0013_collision_and_particles/main.knprop
new file mode 100644
index 00000000..6cd4386b
--- /dev/null
+++ b/package/samples/0013_collision_and_particles/main.knprop
@@ -0,0 +1,6 @@
+
+
+
+ wnd
+
+
diff --git a/package/samples/0013_collision_and_particles/res/tex_particle.png b/package/samples/0013_collision_and_particles/res/tex_particle.png
new file mode 100644
index 00000000..7c03dc18
Binary files /dev/null and b/package/samples/0013_collision_and_particles/res/tex_particle.png differ
diff --git a/package/samples/0014_edit_pixels/main.kn b/package/samples/0014_edit_pixels/main.kn
new file mode 100644
index 00000000..be4921da
--- /dev/null
+++ b/package/samples/0014_edit_pixels/main.kn
@@ -0,0 +1,50 @@
+; Edit Pixels Sample (C)Kuina-chan
+
+var x: int
+var y: int
+var vx: int
+var vy: int
+
+func main()
+ var wndMain: wnd@Wnd :: wnd@makeWnd(null, %fix, 640, 707, "Edit Pixels Sample") {ウインドウの生成}
+ var drawMain: wnd@DrawEditable :: wnd@makeDrawEditable(wndMain, 0, 0, 640, 707) {編集可能なドローコントロールの生成}
+ do draw@autoClear(false)
+
+ ; 明示的にクリア
+ do draw@clearColor(0xFF111111)
+ do draw@clear()
+
+ do @x :: 0
+ do @y :: 0
+ do @vx :: 1
+ do @vy :: 1
+ while(wnd@act())
+ do draw@editPixels(@updatePixels)
+ do draw@render(60)
+ end while
+end func
+
+func updatePixels(width: int, height: int, pixels: []bit32)
+ for(1, 20)
+ do @x :+ @vx
+ do @y :+ @vy
+ if(@x < 0)
+ do @x :: 0
+ do @vx :: 1
+ end if
+ if(@x >= width)
+ do @x :: width - 1
+ do @vx :: -1
+ end if
+ if(@y < 0)
+ do @y :: 0
+ do @vy :: 1
+ end if
+ if(@y >= height)
+ do @y :: height - 1
+ do @vy :: -1
+ end if
+
+ do pixels[@y * width + @x] :: 0xFF000000b32 + (lib@rnd(0, 0xFFFFFF) $ bit32)
+ end for
+end func
diff --git a/package/samples/0014_edit_pixels/main.knprop b/package/samples/0014_edit_pixels/main.knprop
new file mode 100644
index 00000000..6cd4386b
--- /dev/null
+++ b/package/samples/0014_edit_pixels/main.knprop
@@ -0,0 +1,6 @@
+
+
+
+ wnd
+
+
diff --git a/package/samples/free_resources/bgm_sample.ogg b/package/samples/free_resources/bgm_sample.ogg
new file mode 100644
index 00000000..ce08880a
Binary files /dev/null and b/package/samples/free_resources/bgm_sample.ogg differ
diff --git a/package/samples/free_resources/dot_back_side.png b/package/samples/free_resources/dot_back_side.png
new file mode 100644
index 00000000..e662f556
Binary files /dev/null and b/package/samples/free_resources/dot_back_side.png differ
diff --git a/package/samples/free_resources/dot_kuina_chan.png b/package/samples/free_resources/dot_kuina_chan.png
new file mode 100644
index 00000000..e98099fc
Binary files /dev/null and b/package/samples/free_resources/dot_kuina_chan.png differ
diff --git a/package/samples/free_resources/dot_map_chips_side.png b/package/samples/free_resources/dot_map_chips_side.png
new file mode 100644
index 00000000..47aa7ca8
Binary files /dev/null and b/package/samples/free_resources/dot_map_chips_side.png differ
diff --git a/package/samples/free_resources/map_sample_racing.txt b/package/samples/free_resources/map_sample_racing.txt
new file mode 100644
index 00000000..cc7c7d75
--- /dev/null
+++ b/package/samples/free_resources/map_sample_racing.txt
@@ -0,0 +1,21 @@
+20,20
+ -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1
+ -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1
+ -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1
+ -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1
+ -1, 0, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0, -1, -1
+ -1, 0, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1
+ -1, 0, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1
+ 0, -1, -1, -1, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1
+ 0, -1, -1, -1, 0, -1, -1, -1, 0, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, -1
+ 0, -1, -1, 0, -1, -1, -1, -1, 0, -1, -1, -1, -1, 0, 0, -1, -1, 0, -1, -1
+ 0, -1, -1, 0, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0
+ 0, -1, -1, 0, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0
+ 0, -1, -1, 0, -1, -1, 0, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0
+ 0, -1, -1, 0, -1, -1, 0, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0
+ 0, -1, -1, 0, -1, -1, 0, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0
+ 0, -1, -1, 0, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0
+ 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0
+ 0, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0
+ 0, -1, -1, -1, -1, -1, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0
+ -1, 0, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
diff --git a/package/samples/free_resources/map_sample_side.txt b/package/samples/free_resources/map_sample_side.txt
new file mode 100644
index 00000000..4629d2de
--- /dev/null
+++ b/package/samples/free_resources/map_sample_side.txt
@@ -0,0 +1,16 @@
+26,15
+ 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0
+ 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1
+ 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1
+ 1, -1, 0, -1, 0, -1, -1, -1, -1, -1, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1
+ 1, -1, 1, -1, 1, -1, -1, -1, -1, 6, 6, 6, 6, 6, -1, -1, 6, 6, 6, 6, -1, -1, -1, -1, -1, 1
+ 1, -1, 1, 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1
+ 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1
+ 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1
+ 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 0, 0, -1, -1, -1, 1
+ 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 0, 0, 1, 1, 1, -1, -1, -1, 1
+ 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1
+ 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1
+ 1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1
+ 1, -1, -1, -1, -1, 0, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
diff --git a/package/samples/free_resources/obj_car.fbx b/package/samples/free_resources/obj_car.fbx
new file mode 100644
index 00000000..c9cc8163
Binary files /dev/null and b/package/samples/free_resources/obj_car.fbx differ
diff --git a/package/samples/free_resources/tex_car_albedo.png b/package/samples/free_resources/tex_car_albedo.png
new file mode 100644
index 00000000..636c1bf8
Binary files /dev/null and b/package/samples/free_resources/tex_car_albedo.png differ
diff --git a/package/samples/free_resources/tex_field_albedo.jpg b/package/samples/free_resources/tex_field_albedo.jpg
new file mode 100644
index 00000000..84c4f656
Binary files /dev/null and b/package/samples/free_resources/tex_field_albedo.jpg differ
diff --git a/package/samples/free_resources/tex_sky_albedo.png b/package/samples/free_resources/tex_sky_albedo.png
new file mode 100644
index 00000000..23a483c7
Binary files /dev/null and b/package/samples/free_resources/tex_sky_albedo.png differ
diff --git a/package/samples/free_resources/tex_wall_albedo.jpg b/package/samples/free_resources/tex_wall_albedo.jpg
new file mode 100644
index 00000000..09f9b45d
Binary files /dev/null and b/package/samples/free_resources/tex_wall_albedo.jpg differ
diff --git a/package/samples/free_resources/uv_box.png b/package/samples/free_resources/uv_box.png
new file mode 100644
index 00000000..2919894f
Binary files /dev/null and b/package/samples/free_resources/uv_box.png differ
diff --git a/package/samples/free_resources/uv_plane.png b/package/samples/free_resources/uv_plane.png
new file mode 100644
index 00000000..d2c80640
Binary files /dev/null and b/package/samples/free_resources/uv_plane.png differ
diff --git a/package/samples/free_resources/uv_sphere.png b/package/samples/free_resources/uv_sphere.png
new file mode 100644
index 00000000..c27aa69d
Binary files /dev/null and b/package/samples/free_resources/uv_sphere.png differ
diff --git a/package/sys/bgm.kn b/package/sys/bgm.kn
new file mode 100644
index 00000000..91d2adb6
--- /dev/null
+++ b/package/sys/bgm.kn
@@ -0,0 +1,150 @@
+enum Mode
+ stop
+ play
+ fadeOut
+ cross
+end enum
+
+var frontSnd: snd@Snd
+var backSnd: snd@Snd
+var mode: @Mode
+var path: []char
+var cnt: int
+var fadeStartPos: float
+var fadeLoopPos: float
+var fadeTime: int
+var bgmVolume: float
+
++func play(path: []char, startPos: float, loopPos: float): float
+ if(@path <>& null & path = @path)
+ ret 0.0
+ end if
+ var result: float :: @stop()
+ do @frontSnd :: snd@makeSnd(path, true)
+ do @frontSnd.volume(1.0 + @bgmVolume)
+ do @frontSnd.setPos(startPos)
+ do @frontSnd.playLoop(loopPos)
+ do @mode :: %play
+ do @cnt :: 0
+ do @path :: path
+ ret result
+end func
+
++func playFade(path: []char, startPos: float, loopPos: float, fadeTime: int): float
+ if(@path <>& null & path = @path)
+ ret 0.0
+ end if
+ do @backToFront()
+ if(@frontSnd =& null)
+ do @play(path, startPos, loopPos)
+ end if
+ do @backSnd :: snd@makeSnd(path, true)
+ do @frontSnd.volume(1.0 + @bgmVolume)
+ do @mode :: %fadeOut
+ do @cnt :: 0
+ do @fadeStartPos :: startPos
+ do @fadeLoopPos :: loopPos
+ do @fadeTime :: fadeTime
+ do @path :: path
+ ret @frontSnd.getPos()
+end func
+
++func playCross(path: []char, startPos: float, loopPos: float, fadeTime: int): float
+ if(@path <>& null & path = @path)
+ ret 0.0
+ end if
+ do @backToFront()
+ if(@frontSnd =& null)
+ do @play(path, startPos, loopPos)
+ end if
+ do @backSnd :: snd@makeSnd(path, true)
+ do @backSnd.volume(0.0)
+ do @backSnd.setPos(startPos)
+ do @backSnd.playLoop(loopPos)
+ do @frontSnd.volume(1.0 + @bgmVolume)
+ do @mode :: %cross
+ do @cnt :: 0
+ do @fadeTime :: fadeTime
+ do @path :: path
+ ret @frontSnd.getPos()
+end func
+
++func stop(): float
+ do @path :: null
+ var result: float :: 0.0
+ if(@frontSnd <>& null)
+ do result :: @frontSnd.getPos()
+ do @frontSnd :: null
+ end if
+ do @backSnd :: null
+ do @mode :: %stop
+ do @cnt :: 0
+ ret result
+end func
+
++func stopFade(fadeTime: int): float
+ if(@mode = %fadeOut & @backSnd =& null)
+ ret 0.0
+ end if
+ do @backToFront()
+ do @path :: null
+ do @fadeTime :: fadeTime
+ if(@frontSnd =& null)
+ do @mode :: %stop
+ do @cnt :: 0
+ ret 0.0
+ end if
+ do @frontSnd.volume(1.0 + @bgmVolume)
+ do @mode :: %fadeOut
+ ret @frontSnd.getPos()
+end func
+
++func update()
+ switch(@mode)
+ case %fadeOut
+ do @cnt :+ 1
+ do @frontSnd.volume((1.0 - @cnt $ float / @fadeTime $ float) * (1.0 + @bgmVolume))
+ if(@cnt = @fadeTime)
+ if(@backSnd =& null)
+ do @stop()
+ else
+ do @frontSnd :: @backSnd
+ do @backSnd :: null
+ do @frontSnd.volume(1.0 + @bgmVolume)
+ do @frontSnd.setPos(@fadeStartPos)
+ do @frontSnd.playLoop(@fadeLoopPos)
+ do @mode :: %play
+ do @cnt :: 0
+ end if
+ end if
+ case %cross
+ do @cnt :+ 1
+ do @frontSnd.volume((1.0 - @cnt $ float / @fadeTime $ float) * (1.0 + @bgmVolume))
+ do @backSnd.volume((@cnt $ float / @fadeTime $ float) * (1.0 + @bgmVolume))
+ if(@cnt = @fadeTime)
+ do @frontSnd :: @backSnd
+ do @backSnd :: null
+ do @frontSnd.volume(1.0 + @bgmVolume)
+ do @mode :: %play
+ do @cnt :: 0
+ end if
+ end switch
+end func
+
++func volume(value: float)
+ assert 0.0 <= value & value <= 1.0
+ do value :- 1.0
+ if(@bgmVolume <> value)
+ do @bgmVolume :: value
+ if(@mode = %play & @frontSnd <>& null)
+ do @frontSnd.volume(1.0 + @bgmVolume)
+ end if
+ end if
+end func
+
+func backToFront()
+ if(@backSnd <>& null)
+ do @frontSnd :: @backSnd
+ do @backSnd :: null
+ end if
+end func
diff --git a/package/sys/cui.kn b/package/sys/cui.kn
index a35f973b..057275e8 100644
--- a/package/sys/cui.kn
+++ b/package/sys/cui.kn
@@ -4,8 +4,29 @@ end func
func [d0002.knd] _fin()
end func
++func [d0002.knd, _delimiter] delimiter(delimiters: []char)
+end func
+
+func [d0002.knd, _print] print(str: []char)
end func
++func [d0002.knd, _flush] flush()
+end func
+
++func [d0002.knd, _inputLetter] inputLetter(): char
+end func
+
++func [d0002.knd, _inputInt] inputInt(): int
+end func
+
++func [d0002.knd, _inputFloat] inputFloat(): float
+end func
+
++func [d0002.knd, _inputChar] inputChar(): char
+end func
+
++func [d0002.knd, _inputStr] inputStr(): []char
+end func
+
+func [d0002.knd, _input] input(): []char
end func
diff --git a/package/sys/cursor.kn b/package/sys/cursor.kn
new file mode 100644
index 00000000..f736e295
--- /dev/null
+++ b/package/sys/cursor.kn
@@ -0,0 +1,51 @@
++class Cursor()
+ +func set(num: int, pos: int, horizontal: bool, ring: bool)
+ if(dbg)
+ if(num < 1 | pos < 0 | num <= pos)
+ throw 0xE9170006
+ end if
+ end if
+ do me.num :: num
+ do me.pos :: pos
+ do me.horizontal :: horizontal
+ do me.ring :: ring
+ end func
+
+ +func update()
+ if(me.horizontal)
+ if(input@pad(0, %left) = 1)
+ do me.pos :- 1
+ elif(input@pad(0, %right) = 1)
+ do me.pos :+ 1
+ end if
+ else
+ if(input@pad(0, %up) = 1)
+ do me.pos :- 1
+ elif(input@pad(0, %down) = 1)
+ do me.pos :+ 1
+ end if
+ end if
+ if(me.pos < 0)
+ if(me.ring)
+ do me.pos :: me.num - 1
+ else
+ do me.pos :: 0
+ end if
+ elif(me.pos >= me.num)
+ if(me.ring)
+ do me.pos :: 0
+ else
+ do me.pos :: me.num - 1
+ end if
+ end if
+ end func
+
+ +func get(): int
+ ret me.pos
+ end func
+
+ var num: int
+ var pos: int
+ var horizontal: bool
+ var ring: bool
+end class
diff --git a/package/sys/dbg/d1000.knd b/package/sys/dbg/d1000.knd
index 1b4be410..1f854e01 100644
Binary files a/package/sys/dbg/d1000.knd and b/package/sys/dbg/d1000.knd differ
diff --git a/package/sys/dbg/d1001.knd b/package/sys/dbg/d1001.knd
index 3a45138f..475df8d3 100644
Binary files a/package/sys/dbg/d1001.knd and b/package/sys/dbg/d1001.knd differ
diff --git a/package/sys/dbg/d1002.knd b/package/sys/dbg/d1002.knd
index 3accfa56..fe4a57f3 100644
Binary files a/package/sys/dbg/d1002.knd and b/package/sys/dbg/d1002.knd differ
diff --git a/package/sys/dbg/d1003.knd b/package/sys/dbg/d1003.knd
index 11daf079..606d1747 100644
Binary files a/package/sys/dbg/d1003.knd and b/package/sys/dbg/d1003.knd differ
diff --git a/package/sys/dbg/d1004.knd b/package/sys/dbg/d1004.knd
new file mode 100644
index 00000000..1f0c1429
Binary files /dev/null and b/package/sys/dbg/d1004.knd differ
diff --git a/package/sys/dbg/d1005.knd b/package/sys/dbg/d1005.knd
new file mode 100644
index 00000000..ab21ec21
Binary files /dev/null and b/package/sys/dbg/d1005.knd differ
diff --git a/package/sys/dbg/d1006.knd b/package/sys/dbg/d1006.knd
new file mode 100644
index 00000000..68380a82
Binary files /dev/null and b/package/sys/dbg/d1006.knd differ
diff --git a/package/sys/draw.kn b/package/sys/draw.kn
index 4d58ac79..194e1e83 100644
--- a/package/sys/draw.kn
+++ b/package/sys/draw.kn
@@ -10,10 +10,10 @@ end func
+func [d0001.knd, _cnt] cnt(): int
end func
-+func [d0001.knd, _viewport] viewport(x: float, y: float, w: float, h: float)
++func [d0001.knd, _screenWidth] screenWidth(): int
end func
-+func [d0001.knd, _resetViewport] resetViewport()
++func [d0001.knd, _screenHeight] screenHeight(): int
end func
+func [d0001.knd, _depth] depth(test: bool, write: bool)
@@ -25,6 +25,7 @@ end func
add
sub
mul
+ exclusion
end enum
+func [d0001.knd, _blend] blend(kind: @Blend)
@@ -41,21 +42,42 @@ end func
+func [d0001.knd, _clearColor] clearColor(color: int)
end func
++func [d0001.knd, _autoClear] autoClear(enabled: bool)
+end func
+
++func [d0001.knd, _clear] clear()
+end func
+
++func [d0001.knd, _editPixels] editPixels(callback: func<(int, int, []bit32)>)
+end func
+
++func [d0001.knd, _capture] capture(path: []char): bool
+end func
+
+func [d0001.knd, _tri] tri(x1: float, y1: float, x2: float, y2: float, x3: float, y3: float, color: int)
end func
+func [d0001.knd, _line] line(x1: float, y1: float, x2: float, y2: float, color: int)
end func
-+func [d0001.knd, _rect] rect(x: float, y: float, w: float, h: float, color: int)
++func [d0001.knd, _rect] rect(x: float, y: float, width: float, height: float, color: int)
end func
-+func [d0001.knd, _rectLine] rectLine(x: float, y: float, w: float, h: float, color: int)
++func [d0001.knd, _rectLine] rectLine(x: float, y: float, width: float, height: float, color: int)
end func
+func [d0001.knd, _circle, _1] circle(x: float, y: float, radiusX: float, radiusY: float, color: int)
end func
++func [d0001.knd, _circleLine, _1] circleLine(x: float, y: float, radiusX: float, radiusY: float, color: int)
+end func
+
++func [d0001.knd, _poly, _4] poly(x: []float, y: []float, color: []int)
+end func
+
++func [d0001.knd, _polyLine, _4] polyLine(x: []float, y: []float, color: []int)
+end func
+
+func [d0001.knd, _filterNone] filterNone()
end func
@@ -66,16 +88,16 @@ end func
*func [d0001.knd, _texDtor, _force] _dtor()
end func
- *func [_force] _copy(): kuin@Class
- throw 0xE9170005
+ +func [d0001.knd, _texWidth] width(): int
+ end func
+
+ +func [d0001.knd, _texHeight] height(): int
end func
- *func [_force] _toBin(): []bit8
- throw 0xE9170005
+ +func [d0001.knd, _texImgWidth] imgWidth(): int
end func
- *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class
- throw 0xE9170005
+ +func [d0001.knd, _texImgHeight] imgHeight(): int
end func
+func [d0001.knd, _texDraw] draw(dstX: float, dstY: float, srcX: float, srcY: float, srcW: float, srcH: float, color: int)
@@ -88,6 +110,7 @@ end func
end func
var size: int
+ var imgSize: int
var tex: int
var view: int
end class
@@ -104,39 +127,55 @@ end func
+func [d0001.knd, _makeTexEvenColor, _make_instance] makeTexEvenColor(me2: @Tex, color: int): @Tex
end func
++enum AlignHorizontal
+ left
+ center
+ right
+end enum
+
++enum AlignVertical
+ top
+ center
+ bottom
+end enum
+
+class Font()
*func [d0001.knd, _fontDtor, _force] _dtor()
end func
- *func [_force] _copy(): kuin@Class
- throw 0xE9170005
+ +func [d0001.knd, _fontDraw] draw(dstX: float, dstY: float, text: []char, color: int)
end func
- *func [_force] _toBin(): []bit8
- throw 0xE9170005
+ +func [d0001.knd, _fontDrawScale] drawScale(dstX: float, dstY: float, dstScaleX: float, dstScaleY: float, text: []char, color: int)
end func
- *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class
- throw 0xE9170005
+ +func [d0001.knd, _fontMaxWidth] maxWidth(): float
end func
- +func [d0001.knd, _fontDraw] draw(dstX: float, dstY: float, text: []char, color: int)
+ +func [d0001.knd, _fontMaxHeight] maxHeight(): float
end func
- +func [d0001.knd, _fontMaxWidth] maxWidth(): float
+ +func [d0001.knd, _fontCalcWidth] calcWidth(text: []char): float
end func
- +func [d0001.knd, _fontMaxHeight] maxHeight(): float
+ +func [d0001.knd, _fontCalcSize] calcSize(width: &float, height: &float, text: []char)
end func
- +func [d0001.knd, _fontCalcWidth] calcWidth(text: []char): float
+ +func [d0001.knd, _fontSetHeight] setHeight(height: float)
+ end func
+
+ +func [d0001.knd, _fontGetHeight] getHeight(): float
+ end func
+
+ +func [d0001.knd, _fontAlign] align(horizontal: @AlignHorizontal, vertical: @AlignVertical)
end func
var tex: int
var view: int
var cellSize: int
var cellSizeAligned: int
- var advance: int
+ var advance: float
+ var height: float
var proportional: int
var font: int
var charMap: int
@@ -160,25 +199,22 @@ end func
*func [d0001.knd, _objDtor, _force] _dtor()
end func
- *func [_force] _copy(): kuin@Class
- throw 0xE9170005
+ +func [d0001.knd, _objDraw, _5] draw(element: int, frame: float, diffuse: @Tex, specular: @Tex, normal: @Tex)
end func
- *func [_force] _toBin(): []bit8
- throw 0xE9170005
+ +func [d0001.knd, _objDrawToon, _5] drawToon(element: int, frame: float, diffuse: @Tex, specular: @Tex, normal: @Tex)
end func
- *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class
- throw 0xE9170005
+ +func [d0001.knd, _objDrawFlat, _5] drawFlat(element: int, frame: float, diffuse: @Tex)
end func
- +func [d0001.knd, _objDraw] draw(element: int, frame: float, diffuse: @Tex, specular: @Tex, normal: @Tex)
+ +func [d0001.knd, _objDrawOutline, _6] drawOutline(element: int, frame: float, width: float, color: int)
end func
- +func [d0001.knd, _objDrawToon] drawToon(element: int, frame: float, diffuse: @Tex, specular: @Tex, normal: @Tex)
+ +func [d0001.knd, _objDrawWithShadow, _5] drawWithShadow(element: int, frame: float, diffuse: @Tex, specular: @Tex, normal: @Tex, shadow: @Shadow)
end func
- +func [d0001.knd, _objDrawOutline] drawOutline(element: int, frame: float, width: float, color: int)
+ +func [d0001.knd, _objDrawToonWithShadow, _5] drawToonWithShadow(element: int, frame: float, diffuse: @Tex, specular: @Tex, normal: @Tex, shadow: @Shadow)
end func
+func [d0001.knd, _objMat] mat(mat_: []float, normMat: []float)
@@ -217,6 +253,15 @@ end class
+func [d0001.knd, _makeObj, _make_instance] makeObj(me2: @Obj, path: []char): @Obj
end func
++func [d0001.knd, _makeBox, _make_instance] makeBox(me2: @Obj): @Obj
+end func
+
++func [d0001.knd, _makeSphere, _make_instance] makeSphere(me2: @Obj): @Obj
+end func
+
++func [d0001.knd, _makePlane, _make_instance] makePlane(me2: @Obj): @Obj
+end func
+
+func [d0001.knd, _ambLight] ambLight(topR: float, topG: float, topB: float, bottomR: float, bottomG: float, bottomB: float)
end func
@@ -226,5 +271,59 @@ end func
+func [d0001.knd, _argbToColor] argbToColor(a: float, r: float, g: float, b: float): int
end func
-+func [d0001.knd, _colorToArgb] colorToArgb(color: int, a: &float, r: &float, g: &float, b: &float)
++func [d0001.knd, _colorToArgb] colorToArgb(a: &float, r: &float, g: &float, b: &float, color: int)
+end func
+
++class Particle()
+ *func [d0001.knd, _particleDtor, _force] _dtor()
+ end func
+
+ +func [d0001.knd, _particleDraw] draw(tex: @Tex)
+ end func
+
+ +func [d0001.knd, _particleDraw2d] draw2d(tex: @Tex)
+ end func
+
+ +func [d0001.knd, _particleEmit] emit(x: float, y: float, z: float, veloX: float, veloY: float, veloZ: float, size: float, sizeVelo: float, rot: float, rotVelo: float)
+ end func
+
+ var lifespan: int
+ var buf1: int
+ var buf2: int
+ var buf3: int
+ var buf4: int
+ var buf5: int
+ var buf6: int
+ var buf7: int
+ var buf8: int
+ var particlePtr: int
+ var texSet: int
+ var texTmp: int
+ var draw1To2: int
+end class
+
++func [d0001.knd, _makeParticle, _make_instance, _3] makeParticle(me2: @Particle, lifeSpan: int, color1: int, color2: int, friction: float, accelX: float, accelY: float, accelZ: float, sizeAccel: float, rotAccel: float): @Particle
+end func
+
++class Shadow()
+ *func [d0001.knd, _shadowDtor, _force] _dtor()
+ end func
+
+ +func [d0001.knd, _shadowBeginRecord] beginRecord(x: float, y: float, z: float, radius: float)
+ end func
+
+ +func [d0001.knd, _shadowEndRecord] endRecord()
+ end func
+
+ +func [d0001.knd, _shadowAdd] add(obj: @Obj, element: int, frame: float)
+ end func
+
+ var depthTex: int
+ var depthView: int
+ var depthResView: int
+ var depthSize: int
+ var shadowProjView: int
+end class
+
++func [d0001.knd, _makeShadow, _make_instance, _5] makeShadow(me2: @Shadow, width: int, height: int): @Shadow
end func
diff --git a/package/sys/draw2d.kn b/package/sys/draw2d.kn
new file mode 100644
index 00000000..41514595
--- /dev/null
+++ b/package/sys/draw2d.kn
@@ -0,0 +1,93 @@
+func [d0005.knd, _init] _init()
+end func
+
+func [d0005.knd] _fin()
+end func
+
++func [d0005.knd, _line] line(x1: float, y1: float, x2: float, y2: float, strokeWidth: float, color: int)
+end func
+
++func [d0005.knd, _rect] rect(x: float, y: float, width: float, height: float, color: int)
+end func
+
++func [d0005.knd, _rectLine] rectLine(x: float, y: float, width: float, height: float, strokeWidth: float, color: int)
+end func
+
++func [d0005.knd, _circle] circle(x: float, y: float, radiusX: float, radiusY: float, color: int)
+end func
+
++func [d0005.knd, _circleLine] circleLine(x: float, y: float, radiusX: float, radiusY: float, strokeWidth: float, color: int)
+end func
+
++func [d0005.knd, _roundRect] roundRect(x: float, y: float, width: float, height: float, radiusX: float, radiusY: float, color: int)
+end func
+
++func [d0005.knd, _roundRectLine] roundRectLine(x: float, y: float, width: float, height: float, radiusX: float, radiusY: float, strokeWidth: float, color: int)
+end func
+
++func [d0005.knd, _tri] tri(x1: float, y1: float, x2: float, y2: float, x3: float, y3: float, color: int)
+end func
+
++class StrokeStyle()
+ var strokeStyle: int
+end class
+
++class Brush()
+ *func [_force] _dtor()
+ end func
+
+ +func [d0005.knd, _brushLine] line(x1: float, y1: float, x2: float, y2: float, strokeWidth: float, strokeStyle: @StrokeStyle)
+ end func
+
+ var brush: int
+end class
+
++class BrushLinearGradient(@Brush)
+ *func [d0005.knd, _brushLinearGradientDtor, _force] _dtor()
+ end func
+end class
+
++class Geometry()
+ var geometry: int
+
+ +func [d0005.knd, _geometryDraw] draw(color: int)
+ end func
+
+ +func [d0005.knd, _geometryDrawLine] drawLine(strokeWidth: float, color: int)
+ end func
+end class
+
++class GeometryPath(@Geometry)
+ *func [d0005.knd, _geometryPathDtor, _force] _dtor()
+ end func
+
+ +func [d0005.knd, _geometryPathOpen] open()
+ end func
+
+ +func [d0005.knd, _geometryPathClose] close()
+ end func
+
+ +func [d0005.knd, _geometryPathOpenFigure] openFigure(x: float, y: float, filled: bool)
+ end func
+
+ +func [d0005.knd, _geometryPathCloseFigure] closeFigure(closedPath: bool)
+ end func
+
+ +func [d0005.knd, _geometryPathAddArc] addArc(x: float, y: float, radiusX: float, radiusY: float, angle: float, ccw: bool, largeArg: bool)
+ end func
+
+ +func [d0005.knd, _geometryPathAddBezier] addBezier(x1: float, y1: float, x2: float, y2: float, x3: float, y3: float)
+ end func
+
+ +func [d0005.knd, _geometryPathAddLine] addLine(x: float, y: float)
+ end func
+
+ +func [d0005.knd, _geometryPathAddQuadraticBezier] addQuadraticBezier(x1: float, y1: float, x2: float, y2: float)
+ end func
+end class
+
++func [d0005.knd, _makeBrushLinearGradient, _make_instance] makeBrushLinearGradient(me2: @BrushLinearGradient, x1: float, y1: float, x2: float, y2: float, colorPosition: []float, color: []int): @BrushLinearGradient
+end func
+
++func [d0005.knd, _makeGeometryPath, _make_instance] makeGeometryPath(me2: @GeometryPath): @GeometryPath
+end func
diff --git a/package/sys/drawex.kn b/package/sys/drawex.kn
new file mode 100644
index 00000000..afe5b524
--- /dev/null
+++ b/package/sys/drawex.kn
@@ -0,0 +1,248 @@
++class Obj()
+ +func draw()
+ end func
+
+ +func init(x: float, y: float, width: float, height: float, visible: bool)
+ do me.x :: x
+ do me.y :: y
+ do me.width :: width
+ do me.height :: height
+ do me.visible :: visible
+ end func
+
+ +func fin(resCacheDraw: @ResCacheDraw)
+ end func
+
+ +var x: float
+ +var y: float
+ +var width: float
+ +var height: float
+ +var visible: bool
+end class
+
++class ObjRect(@Obj)
+ +*func draw()
+ if(!me.visible)
+ ret
+ end if
+ if(me.colorFill <> 0)
+ do draw2d@rect(me.x, me.y, me.width, me.height, me.colorFill)
+ end if
+ if(me.colorStroke <> 0)
+ do draw2d@rectLine(me.x, me.y, me.width, me.height, me.strokeWidth, me.colorStroke)
+ end if
+ end func
+
+ +var colorFill: int
+ +var colorStroke: int
+ +var strokeWidth: float
+end class
+
++class ObjCircle(@Obj)
+ +*func draw()
+ if(!me.visible)
+ ret
+ end if
+ var halfWidth: float :: me.width / 2.0
+ var halfHeight: float :: me.height / 2.0
+ if(me.colorFill <> 0)
+ do draw2d@circle(me.x + halfWidth, me.y + halfHeight, halfWidth, halfHeight, me.colorFill)
+ end if
+ if(me.colorStroke <> 0)
+ do draw2d@circleLine(me.x + halfWidth, me.y + halfHeight, halfWidth, halfHeight, me.strokeWidth, me.colorStroke)
+ end if
+ end func
+
+ +var colorFill: int
+ +var colorStroke: int
+ +var strokeWidth: float
+end class
+
++class ObjText(@Obj)
+ +*func draw()
+ if(!me.visible)
+ ret
+ end if
+ if(me.color <> 0 & me.font <>& null)
+ do me.font.align(me.alignHorizontal, me.alignVertical)
+ var x: float
+ var y: float
+ switch(me.alignHorizontal)
+ case %left
+ do x :: me.x
+ case %center
+ do x :: me.x + me.width / 2.0
+ case %right
+ do x :: me.x + me.width
+ default
+ assert false
+ end switch
+ switch(me.alignVertical)
+ case %top
+ do y :: me.y
+ case %center
+ do y :: me.y + me.height / 2.0
+ case %bottom
+ do y :: me.y + me.height
+ default
+ assert false
+ end switch
+ do me.font.draw(x, y, me.text, me.color)
+ end if
+ end func
+
+ +*func fin(resCacheDraw: @ResCacheDraw)
+ if(me.font <>& null)
+ do resCacheDraw.del(me.font)
+ do me.font :: null
+ end if
+ end func
+
+ +func setFont(resCacheDraw: @ResCacheDraw, fontName: []char, fontSize: int, bold: bool, italic: bool, proportional: bool, advance: float)
+ if(me.font <>& null)
+ do resCacheDraw.del(me.font)
+ do me.font :: null
+ end if
+ do me.font :: resCacheDraw.makeFont(fontName, fontSize, bold, italic, proportional, advance)
+ end func
+
+ var font: draw@Font
+ +var text: []char
+ +var color: int
+ +var alignHorizontal: draw@AlignHorizontal
+ +var alignVertical: draw@AlignVertical
+end class
+
++class ObjImg(@Obj)
+ +*func draw()
+ if(!me.visible)
+ ret
+ end if
+ if(me.color <> 0 & me.tex <>& null)
+ do me.tex.drawScale(me.x, me.y, me.width, me.height, me.srcX, me.srcY, me.srcWidth, me.srcHeight, me.color)
+ end if
+ end func
+
+ +*func fin(resCacheDraw: @ResCacheDraw)
+ if(me.tex <>& null)
+ do resCacheDraw.del(me.tex)
+ do me.tex :: null
+ end if
+ end func
+
+ +func setTex(resCacheDraw: @ResCacheDraw, texPath: []char)
+ if(me.tex <>& null)
+ do resCacheDraw.del(me.tex)
+ do me.tex :: null
+ end if
+ do me.tex :: resCacheDraw.makeTex(texPath)
+ end func
+
+ var tex: draw@Tex
+ +var srcX: float
+ +var srcY: float
+ +var srcWidth: float
+ +var srcHeight: float
+ +var color: int
+end class
+
++class ObjRoundRect(@Obj)
+ +*func draw()
+ if(!me.visible)
+ ret
+ end if
+ if(me.colorFill <> 0)
+ do draw2d@roundRect(me.x, me.y, me.width, me.height, me.radiusX, me.radiusY, me.colorFill)
+ end if
+ if(me.colorStroke <> 0)
+ do draw2d@roundRectLine(me.x, me.y, me.width, me.height, me.radiusX, me.radiusY, me.strokeWidth, me.colorStroke)
+ end if
+ end func
+
+ +var colorFill: int
+ +var colorStroke: int
+ +var radiusX: float
+ +var radiusY: float
+ +var strokeWidth: float
+end class
+
++class ObjParticle(@Obj)
+ +*func draw()
+ if(!me.visible)
+ ret
+ end if
+ if(me.color <> 0 & me.particle <>& null)
+ do me.particle.emit(me.x, me.y, 0.0, 0.0, 0.0, 0.0, me.width, 0.0, 0.0, 0.0)
+ do me.particle.draw2d(me.tex)
+ end if
+ end func
+
+ +*func fin(resCacheDraw: @ResCacheDraw)
+ if(me.particle <>& null)
+ do resCacheDraw.del(me.particle)
+ do me.particle :: null
+ end if
+ if(me.tex <>& null)
+ do resCacheDraw.del(me.tex)
+ do me.tex :: null
+ end if
+ end func
+
+ +func setParticle(resCacheDraw: @ResCacheDraw, lifeSpan: int, color1: int, color2: int, friction: float, accelX: float, accelY: float, accelZ: float, sizeAccel: float, rotAccel: float)
+ if(me.particle <>& null)
+ do resCacheDraw.del(me.particle)
+ do me.particle :: null
+ end if
+ do me.particle :: resCacheDraw.makeParticle(lifeSpan, color1, color2, friction, accelX, accelY, accelZ, sizeAccel, rotAccel)
+ end func
+
+ +func setTex(resCacheDraw: @ResCacheDraw, texPath: []char)
+ if(me.tex <>& null)
+ do resCacheDraw.del(me.tex)
+ do me.tex :: null
+ end if
+ do me.tex :: resCacheDraw.makeTex(texPath)
+ end func
+
+ var particle: draw@Particle
+ var tex: draw@Tex
+ +var srcX: float
+ +var srcY: float
+ +var srcWidth: float
+ +var srcHeight: float
+ +var color: int
+end class
+
++class ResCacheDraw(rescache@ResCache)
+ +func makeFont(fontName: []char, size: int, bold: bool, italic: bool, proportional: bool, advance: float): draw@Font
+ var instance: rescache@Instance :: me.add("font,\{fontName},\{size},\{bold},\{italic},\{proportional},\{advance}")
+ if(instance.instance =& null)
+ do instance.instance :: draw@makeFont(fontName, size, bold, italic, proportional, advance)
+ end if
+ ret instance.instance $ draw@Font
+ end func
+
+ +func makeTex(texPath: []char): draw@Tex
+ var instance: rescache@Instance :: me.add("tex,\{texPath}")
+ if(instance.instance =& null)
+ do instance.instance :: draw@makeTex(me.baseDir ~ texPath)
+ end if
+ ret instance.instance $ draw@Tex
+ end func
+
+ +func makeParticle(lifeSpan: int, color1: int, color2: int, friction: float, accelX: float, accelY: float, accelZ: float, sizeAccel: float, rotAccel: float): draw@Particle
+ var instance: rescache@Instance :: me.add("particle,\{lifeSpan},\{color1},\{color2},\{friction},\{accelX},\{accelY},\{accelZ},\{sizeAccel},\{rotAccel}")
+ if(instance.instance =& null)
+ do instance.instance :: draw@makeParticle(lifeSpan, color1, color2, friction, accelX, accelY, accelZ, sizeAccel, rotAccel)
+ end if
+ ret instance.instance $ draw@Particle
+ end func
+end class
+
++func draw(objs: list<@Obj>)
+ do objs.head()
+ while(!objs.term())
+ do objs.get().draw()
+ do objs.next()
+ end while
+end func
diff --git a/package/sys/excpt.kn b/package/sys/excpt.kn
index b504c3d6..cc353876 100644
--- a/package/sys/excpt.kn
+++ b/package/sys/excpt.kn
@@ -1,4 +1,4 @@
-+const userMin: int :: 0x00000000
++const userMin: int :: 0x00000001
+const userMax: int :: 0x0000FFFF
+const accessViolation: int :: 0xC0000005
+const noMem: int :: 0xC0000017
@@ -11,7 +11,6 @@
+const dbgArrayIdxOutOfRange: int :: 0xE9170002
+const dbgIntOverflow: int :: 0xE9170003
+const invalidCmp: int :: 0xE9170004
-+const libClassInvalidOperation: int :: 0xE9170005
+const dbgArgOutDomain: int :: 0xE9170006
+const fileReadFailed: int :: 0xE9170007
+const invalidDataFmt: int :: 0xE9170008
diff --git a/package/sys/excpt.knd b/package/sys/excpt.knd
index 95caf0c0..9935f699 100644
--- a/package/sys/excpt.knd
+++ b/package/sys/excpt.knd
@@ -4,6 +4,9 @@ Unknown exception.
none
ユーザ定義例外です。
User defined exception.
+80000003
+ブレークポイントにより停止しました。
+Stopped due to a breakpoint.
c0000005
不正なメモリアドレスを参照しました。
Access violation.
diff --git a/package/sys/file.kn b/package/sys/file.kn
index cdfc57ca..b07de429 100644
--- a/package/sys/file.kn
+++ b/package/sys/file.kn
@@ -5,58 +5,46 @@
end enum
+class Reader()
- *func [d0000.knd, _streamDtor, _force] _dtor()
+ *func [d0000.knd, _readerDtor, _force] _dtor()
end func
- *func [_force] _copy(): kuin@Class
- throw 0xE9170005
+ +func [d0000.knd, _readerFin] fin()
end func
- *func [_force] _toBin(): []bit8
- throw 0xE9170005
+ +func [d0000.knd, _readerSetPos] setPos(origin: @Origin, pos: int)
end func
- *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class
- throw 0xE9170005
+ +func [d0000.knd, _readerGetPos] getPos(): int
end func
- +func [d0000.knd, _streamFin] fin()
+ +func [d0000.knd, _readerDelimiter] delimiter(delimiters: []char)
end func
- +func [d0000.knd, _streamSetPos] setPos(origin: @Origin, pos: int)
+ +func [d0000.knd, _readerRead] read(size: int): []bit8
end func
- +func [d0000.knd, _streamGetPos] getPos(): int
+ +func [d0000.knd, _readerReadLetter] readLetter(): char
end func
- +func [d0000.knd, _streamDelimiter] delimiter(delimiters: []char)
+ +func [d0000.knd, _readerReadInt] readInt(): int
end func
- +func [d0000.knd, _streamRead] read(size: int): []bit8
+ +func [d0000.knd, _readerReadFloat] readFloat(): float
end func
- +func [d0000.knd, _streamReadLetter] readLetter(): char
+ +func [d0000.knd, _readerReadChar] readChar(): char
end func
- +func [d0000.knd, _streamReadInt] readInt(): int
+ +func [d0000.knd, _readerReadStr] readStr(): []char
end func
- +func [d0000.knd, _streamReadFloat] readFloat(): float
+ +func [d0000.knd, _readerReadLine] readLine(): []char
end func
- +func [d0000.knd, _streamReadChar] readChar(): char
+ +func [d0000.knd, _readerFileSize] fileSize(): int
end func
- +func [d0000.knd, _streamReadStr] readStr(): []char
- end func
-
- +func [d0000.knd, _streamReadLine] readLine(): []char
- end func
-
- +func [d0000.knd, _streamFileSize] fileSize(): int
- end func
-
- +func [d0000.knd, _streamTerm] term(): bool
+ +func [d0000.knd, _readerTerm] term(): bool
end func
var handle: int
@@ -66,49 +54,37 @@ end enum
end class
+class Writer()
- *func [d0000.knd, _streamDtor, _force] _dtor()
- end func
-
- *func [_force] _copy(): kuin@Class
- throw 0xE9170005
- end func
-
- *func [_force] _toBin(): []bit8
- throw 0xE9170005
+ *func [d0000.knd, _writerDtor, _force] _dtor()
end func
- *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class
- throw 0xE9170005
+ +func [d0000.knd, _writerFin] fin()
end func
- +func [d0000.knd, _streamFin] fin()
+ +func [d0000.knd, _writerSetPos] setPos(origin: @Origin, pos: int)
end func
- +func [d0000.knd, _streamSetPos] setPos(origin: @Origin, pos: int)
+ +func [d0000.knd, _writerGetPos] getPos(): int
end func
- +func [d0000.knd, _streamGetPos] getPos(): int
+ +func [d0000.knd, _writerWrite] write(bin: []bit8)
end func
- +func [d0000.knd, _streamWrite] write(bin: []bit8)
+ +func [d0000.knd, _writerWriteInt] writeInt(n: int)
end func
- +func [d0000.knd, _streamWriteInt] writeInt(n: int)
+ +func [d0000.knd, _writerWriteFloat] writeFloat(n: float)
end func
- +func [d0000.knd, _streamWriteFloat] writeFloat(n: float)
+ +func [d0000.knd, _writerWriteChar] writeChar(n: char)
end func
- +func [d0000.knd, _streamWriteChar] writeChar(n: char)
+ +func [d0000.knd, _writerWriteStr] writeStr(n: []char)
end func
- +func [d0000.knd, _streamWriteStr] writeStr(n: []char)
+ +func [d0000.knd, _writerFlush] flush()
end func
var handle: int
- var delimiterNum: int
- var delimiter: int
- var fileSize_: int
end class
+func [d0000.knd, _makeReader, _make_instance] makeReader(me2: @Reader, path: []char): @Reader
@@ -147,6 +123,9 @@ end func
+func [d0000.knd, _copyFile] copyFile(dst: []char, src: []char): bool
end func
++func [d0000.knd, _moveDir] moveDir(dst: []char, src: []char): bool
+end func
+
+func [d0000.knd, _moveFile] moveFile(dst: []char, src: []char): bool
end func
@@ -159,6 +138,9 @@ end func
+func [d0000.knd, _fileName] fileName(path: []char): []char
end func
++func [d0000.knd, _fullPath] fullPath(path: []char): []char
+end func
+
+func [d0000.knd, _delExt] delExt(path: []char): []char
end func
@@ -171,3 +153,8 @@ end func
+func [d0000.knd, _fileSize] fileSize(path: []char): int
end func
++func [d0000.knd, _setCurDir] setCurDir(path: []char)
+end func
+
++func [d0000.knd, _getCurDir] getCurDir(): []char
+end func
diff --git a/package/sys/game.kn b/package/sys/game.kn
new file mode 100644
index 00000000..5ed4fbc2
--- /dev/null
+++ b/package/sys/game.kn
@@ -0,0 +1,164 @@
+func [d1004.knd, _init] _init()
+end func
+
++class Rect()
+ +func [d1004.knd, _rectMove] move(maxVelo: float)
+ end func
+
+ +func [d1004.knd, _rectUpdate] update()
+ end func
+
+ +func [d1004.knd, _rectBackFriction] backFriction(backFriction: float)
+ end func
+
+ +func [d1004.knd, _rectFluidFriction] fluidFriction(fluidFriction: float)
+ end func
+
+ +func hitLeft(): bool
+ ret me.flags.and(0x01b64) <> 0b64
+ end func
+
+ +func hitTop(): bool
+ ret me.flags.and(0x02b64) <> 0b64
+ end func
+
+ +func hitRight(): bool
+ ret me.flags.and(0x04b64) <> 0b64
+ end func
+
+ +func hitBottom(): bool
+ ret me.flags.and(0x08b64) <> 0b64
+ end func
+
+ +var width: float
+ +var height: float
+ +var x: float
+ +var y: float
+ +var veloX: float
+ +var veloY: float
+ var flags: bit64
+ var buf0: float
+ var buf1: float
+ var buf2: float
+ var buf3: float
+ var buf4: float
+ var buf5: float
+ var buf6: float
+ var buf7: float
+ var buf8: float
+end class
+
++class Map()
+ *func [d1004.knd, _mapDtor, _force] _dtor()
+ end func
+
+ +func [d1004.knd, _mapGet] get(x: int, y: int): int
+ end func
+
+ +func [d1004.knd, _mapSet] set(x: int, y: int, value: int)
+ end func
+
+ +func [d1004.knd, _mapFind] find(x: &int, y: &int, value: int): bool
+ end func
+
+ var mapWidth: int
+ var mapHeight: int
+ var buf: int
+ var chipWidth: float
+ var chipHeight: float
+end class
+
++func makeMap(path: []char, chipWidth: float, chipHeight: float): @Map
+ var handle: file@Reader :: file@makeReader(path)
+ do handle.delimiter("\n,")
+ var mapWidth: int :: handle.readInt()
+ var mapHeight: int :: handle.readInt()
+ var buf: []int :: #[mapWidth * mapHeight]int
+ for i(0, mapWidth * mapHeight - 1)
+ do buf[i] :: handle.readInt()
+ end for
+ ret makeMapImpl(mapWidth, mapHeight, buf, chipWidth, chipHeight)
+
+ func [d1004.knd, _makeMapImpl, _make_instance] makeMapImpl(me2: @Map, mapWidth: int, mapHeight: int, data: []int, chipWidth: float, chipHeight: float): @Map
+ end func
+end func
+
++func [d1004.knd, _makeMapEmpty, _make_instance] makeMapEmpty(me2: @Map, mapWidth: int, mapHeight: int, chipWidth: float, chipHeight: float): @Map
+end func
+
++enum Shape
+ none
+ rect
+ triLeftTop
+ triRightTop
+ triLeftBottom
+ triRightBottom
+ oneWayLeft
+ oneWayTop
+ oneWayRight
+ oneWayBottom
+end enum
+
++class ChipInfo()
+ +var shape: @Shape
+ +var backFriction: float
+ +var solidFriction: float
+ +var fluidFriction: float
+ +var repulsion: float
+ +var flowX: float
+ +var flowY: float
+end class
+
++enum Direction
+ none :: 0
+ left :: 1
+ top :: 2
+ right :: 4
+ bottom :: 8
+end enum
+
++func hitMapRect(map: @Map, rect: @Rect, chipInfoCallback: func<(int, @ChipInfo)>, hitCallback: func<(int, int, @Direction)>)
+ do hitMapRectImpl(map, rect, chipInfoCallback, hitCallback)
+
+ func [d1004.knd, _hitMapRectImpl, _make_instance] hitMapRectImpl(me2: @ChipInfo, map: @Map, rect: @Rect, chipInfoCallback: func<(int, @ChipInfo)>, hitCallback: func<(int, int, @Direction)>): @ChipInfo
+ end func
+end func
+
++func [d1004.knd, _hitRectRect] hitRectRect(rect1: @Rect, rect2: @Rect, weight1: float, weight2: float, repulsion: float, solidFriction: float): @Direction
+end func
+
++class Roll()
+ *func [d1004.knd, _rollDtor, _force] _dtor()
+ end func
+
+ +func [d1004.knd, _rollProceed] proceed(speed: float): bool
+ end func
+
+ +func [d1004.knd, _rollReset] reset()
+ end func
+
+ var rollCallback: func<(float, [][]char)>
+ var pos_: float
+ var buf: int
+ var idx: int
+end class
+
++func makeRoll(path: []char, rollCallback: func<(float, [][]char)>): @Roll
+ var handle: file@Reader :: file@makeReader(path)
+ do handle.delimiter("\n,")
+ var itemNum: int :: handle.readInt()
+ var timings: []float :: #[itemNum]float
+ var params: [][][]char :: #[itemNum][][]char
+ for i(0, itemNum - 1)
+ do timings[i] :: handle.readFloat()
+ var paramsNum: int :: handle.readInt()
+ do params[i] :: #[paramsNum][]char
+ for j(0, paramsNum - 1)
+ do params[i][j] :: handle.readStr()
+ end for
+ end for
+ ret makeRollImpl(timings, params, rollCallback)
+
+ func [d1004.knd, _makeRollImpl, _make_instance] makeRollImpl(me2: @Roll, timings: []float, params: [][][]char, rollCallback: func<(float, [][]char)>): @Roll
+ end func
+end func
diff --git a/package/sys/kuin.kn b/package/sys/kuin.kn
index c43e8920..82b3bd1a 100644
--- a/package/sys/kuin.kn
+++ b/package/sys/kuin.kn
@@ -152,10 +152,13 @@ end func
func [d0000.knd, _any_type, _ret_me] _repeat(me_: []bit8, type: int, len: int): int
end func
-func [d0000.knd] _toInt(me_: []char, value: &int): bool
+func [d0000.knd] _toInt(me_: []char, success: &bool): int
end func
-func [d0000.knd] _toFloat(me_: []char, value: &float): bool
+func [d0000.knd] _toFloat(me_: []char, success: &bool): float
+end func
+
+func [d0000.knd] _toBit64(me_: []char, success: &bool): bit64
end func
func [d0000.knd] _lower(me_: []char): []char
@@ -212,7 +215,7 @@ end func
func [d0000.knd, _any_type, _ret_child] _getQueue(me_: []bit8, type: int): int
end func
-func [d0000.knd, _any_type, _take_child, _ret_child] _getDict(me_: []bit8, type: int, key: []bit8): int
+func [d0000.knd, _any_type, _take_child, _ret_child] _getDict(me_: []bit8, type: int, key: []bit8, existed: &bool): int
end func
func [d0000.knd, _any_type, _ret_child] _getOffset(me_: []bit8, type: int, offset: int): int
@@ -265,3 +268,19 @@ end func
func [d0000.knd, _any_type, _take_key_value_func] _forEach(me_: []bit8, type: int, callback: int, data: @Class): bool
end func
+
+func [d0000.knd, _any_type, _take_child] _delDict(me_: []bit8, type: int, key: []bit8)
+end func
+
+func [d0000.knd, _any_type] _idx(me_: []bit8, type: int): int
+end func
+
++class ListPtr()
+ var ptr: int
+end class
+
+func [d0000.knd, _any_type, _make_instance] _getPtr(me_: []bit8, type: int, me2: @ListPtr): @ListPtr
+end func
+
+func [d0000.knd, _any_type] _setPtr(me_: []bit8, type: int, ptr: @ListPtr)
+end func
diff --git a/package/sys/launcher.bat b/package/sys/launcher.bat
deleted file mode 100644
index 2e9d66c5..00000000
--- a/package/sys/launcher.bat
+++ /dev/null
@@ -1,4 +0,0 @@
-@echo off
-%1
-echo;
-pause
diff --git a/package/sys/lib.kn b/package/sys/lib.kn
index a4029c2e..da562ecc 100644
--- a/package/sys/lib.kn
+++ b/package/sys/lib.kn
@@ -18,18 +18,6 @@ end func
*func [d0000.knd, _rndDtor, _force] _dtor()
end func
- *func [_force] _copy(): kuin@Class
- throw 0xE9170005
- end func
-
- *func [_force] _toBin(): []bit8
- throw 0xE9170005
- end func
-
- *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class
- throw 0xE9170005
- end func
-
+func [d0000.knd, _rndRnd] rnd(min: int, max: int): int
end func
@@ -39,9 +27,6 @@ end func
+func [d0000.knd, _rndRndBit64] rndBit64(): bit64
end func
- +func [d0000.knd, _rndRndUuid] rndUuid(): []char
- end func
-
var rndState: int
end class
@@ -132,6 +117,12 @@ end func
+func [d0000.knd, _same] same(n1: float, n2: float): bool
end func
++func [d0000.knd, _toBit64Forcibly] toBit64Forcibly(x: float): bit64
+end func
+
++func [d0000.knd, _toFloatForcibly] toFloatForcibly(x: bit64): float
+end func
+
+func [d0000.knd, _toRad] toRad(degree: float): float
end func
@@ -175,18 +166,6 @@ end func
*func [d0000.knd, _bmSearchDtor, _force] _dtor()
end func
- *func [_force] _copy(): kuin@Class
- throw 0xE9170005
- end func
-
- *func [_force] _toBin(): []bit8
- throw 0xE9170005
- end func
-
- *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class
- throw 0xE9170005
- end func
-
+func [d0000.knd, _bmSearchFind] find(text: []char, start: int): int
end func
@@ -228,6 +207,21 @@ end func
+func [d0000.knd] sleep(ms: int)
end func
++func [d0000.knd, _countUp] countUp(min: int, max: int): []int
+end func
+
++func [d0000.knd, _addChkOverflow] addChkOverflow(overflowed: &bool, n1: int, n2: int): int
+end func
+
++func [d0000.knd, _subChkOverflow] subChkOverflow(overflowed: &bool, n1: int, n2: int): int
+end func
+
++func [d0000.knd, _mulChkOverflow] mulChkOverflow(overflowed: &bool, n1: int, n2: int): int
+end func
+
++func [d0000.knd, _addr] addr(class_: kuin@Class): bit64
+end func
+
+class Int()
+*func cmp(t: @Int): int
ret (me.value - t.value).sign()
diff --git a/package/sys/math.kn b/package/sys/math.kn
index fc19c111..a418fd88 100644
--- a/package/sys/math.kn
+++ b/package/sys/math.kn
@@ -28,6 +28,9 @@ end func
+func [d0003.knd, _factInt] factInt(n: int): int
end func
++func [d0003.knd, _fibonacci] fibonacci(n: int): int
+end func
+
+func [d0003.knd, _knapsack] knapsack(weights: []int, values: []int, maxWeight: int, reuse: bool): int
end func
@@ -44,18 +47,6 @@ end func
*func [d0003.knd, _matDtor, _force] _dtor()
end func
- *func [_force] _copy(): kuin@Class
- throw 0xE9170005
- end func
-
- *func [_force] _toBin(): []bit8
- throw 0xE9170005
- end func
-
- *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class
- throw 0xE9170005
- end func
-
var row: int
var col: int
var buf: int
diff --git a/package/sys/msg.knd b/package/sys/msg.knd
index 996fb146..5499163c 100644
--- a/package/sys/msg.knd
+++ b/package/sys/msg.knd
@@ -445,3 +445,9 @@ EA0064
EA0065
alias「%s」の定義が循環しています。
---
+EA0066
+「#」「##」「$<」「$>」演算子が使えないクラス「%s」にこれらが使われました。
+---
+EA0067
+関数呼び出しの%d番目の参照渡しの引数に、参照を取れない値が渡されました。
+---
diff --git a/package/sys/net.kn b/package/sys/net.kn
index 66607ceb..ad5a089c 100644
--- a/package/sys/net.kn
+++ b/package/sys/net.kn
@@ -1,25 +1,13 @@
func [d0004.knd, _init] _init()
end func
-func [d0004.knd, _fin] _fin()
+func [d0004.knd] _fin()
end func
+class TcpServer()
*func [d0004.knd, _tcpServerDtor, _force] _dtor()
end func
- *func [_force] _copy(): kuin@Class
- throw 0xE9170005
- end func
-
- *func [_force] _toBin(): []bit8
- throw 0xE9170005
- end func
-
- *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class
- throw 0xE9170005
- end func
-
+func [d0004.knd, _tcpServerFin] fin()
end func
@@ -41,18 +29,6 @@ end func
*func [d0004.knd, _tcpDtor, _force] _dtor()
end func
- *func [_force] _copy(): kuin@Class
- throw 0xE9170005
- end func
-
- *func [_force] _toBin(): []bit8
- throw 0xE9170005
- end func
-
- *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class
- throw 0xE9170005
- end func
-
+func [d0004.knd, _tcpFin] fin()
end func
@@ -80,18 +56,6 @@ end func
*func [d0004.knd, _httpDtor, _force] _dtor()
end func
- *func [_force] _copy(): kuin@Class
- throw 0xE9170005
- end func
-
- *func [_force] _toBin(): []bit8
- throw 0xE9170005
- end func
-
- *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class
- throw 0xE9170005
- end func
-
+func [d0004.knd, _httpFin] fin()
end func
diff --git a/package/sys/num.kn b/package/sys/num.kn
new file mode 100644
index 00000000..e528d279
--- /dev/null
+++ b/package/sys/num.kn
@@ -0,0 +1,263 @@
+func [d1006.knd, _init] _init()
+end func
+
++class BigInt()
+ *func [d1006.knd, _bigIntDtor, _force] _dtor()
+ end func
+
+ +*func [d1006.knd, _bigIntCmp] cmp(t: @BigInt): int
+ end func
+
+ +*func [d1006.knd, _bigIntToStr] toStr(): []char
+ end func
+
+ +func [d1006.knd, _bigIntFromStr] fromStr(value: []char): bool
+ end func
+
+ +func [d1006.knd, _bigIntToInt] toInt(): int
+ end func
+
+ +func [d1006.knd, _bigIntFromInt] fromInt(value: int)
+ end func
+
+ +func [d1006.knd, _bigIntAdd] add(value: @BigInt): @BigInt
+ end func
+
+ +func [d1006.knd, _bigIntAddInt] addInt(value: int): @BigInt
+ end func
+
+ +func [d1006.knd, _bigIntSub] sub(value: @BigInt): @BigInt
+ end func
+
+ +func [d1006.knd, _bigIntSubInt] subInt(value: int): @BigInt
+ end func
+
+ +func [d1006.knd, _bigIntMul] mul(value: @BigInt): @BigInt
+ end func
+
+ +func [d1006.knd, _bigIntMulInt] mulInt(value: int): @BigInt
+ end func
+
+ +func [d1006.knd, _bigIntDiv] div(value: @BigInt): @BigInt
+ end func
+
+ +func [d1006.knd, _bigIntDivInt] divInt(value: int): @BigInt
+ end func
+
+ +func [d1006.knd, _bigIntMod] mod(value: @BigInt): @BigInt
+ end func
+
+ +func [d1006.knd, _bigIntModInt] modInt(value: int): @BigInt
+ end func
+
+ +func [d1006.knd, _bigIntPowInt] powInt(value: int): @BigInt
+ end func
+
+ +func [d1006.knd, _bigIntAbs] abs(): @BigInt
+ end func
+end class
+
++func [d1006.knd, _makeBigInt, _make_instance] makeBigInt(me2: @BigInt): @BigInt
+end func
+
++class BigFloat()
+ *func [d1006.knd, _bigFloatDtor, _force] _dtor()
+ end func
+
+ +*func [d1006.knd, _bigFloatCmp] cmp(t: @BigFloat): int
+ end func
+
+ +*func [d1006.knd, _bigFloatToStr] toStr(): []char
+ end func
+
+ +func [d1006.knd, _bigFloatFromStr] fromStr(value: []char): bool
+ end func
+
+ +func [d1006.knd, _bigFloatToFloat] toFloat(): int
+ end func
+
+ +func [d1006.knd, _bigFloatFromFloat] fromFloat(value: float)
+ end func
+
+ +func [d1006.knd, _bigFloatAdd] add(value: @BigFloat): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatAddFloat] addFloat(value: float): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatSub] sub(value: @BigFloat): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatSubFloat] subFloat(value: float): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatMul] mul(value: @BigFloat): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatMulFloat] mulFloat(value: float): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatDiv] div(value: @BigFloat): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatDivFloat] divFloat(value: float): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatMod] mod(value: @BigFloat): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatModFloat] modFloat(value: float): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatPow] pow(value: @BigFloat): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatPowFloat] powFloat(value: float): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatExp] exp(): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatLn] ln(): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatSqrt] sqrt(): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatFloor] floor(): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatCeil] ceil(): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatCos] cos(): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatSin] sin(): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatTan] tan(): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatAcos] acos(): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatAsin] asin(): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatAtan] atan(): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatCosh] cosh(): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatSinh] sinh(): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatTanh] tanh(): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatAcosh] acosh(): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatAsinh] asinh(): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatAtanh] atanh(): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatAbs] abs(): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatPi] pi(): @BigFloat
+ end func
+
+ +func [d1006.knd, _bigFloatE] e(): @BigFloat
+ end func
+end class
+
++func [d1006.knd, _makeBigFloat, _make_instance] makeBigFloat(me2: @BigFloat): @BigFloat
+end func
+
++class Complex()
+ *func [d1006.knd, _complexDtor, _force] _dtor()
+ end func
+
+ +*func [d1006.knd, _complexToStr] toStr(): []char
+ end func
+
+ +func [d1006.knd, _complexRe] re(): float
+ end func
+
+ +func [d1006.knd, _complexIm] im(): float
+ end func
+
+ +func [d1006.knd, _complexSet] set(re: float, im: float): @Complex
+ end func
+
+ +func [d1006.knd, _complexAdd] add(value: @Complex): @Complex
+ end func
+
+ +func [d1006.knd, _complexSub] sub(value: @Complex): @Complex
+ end func
+
+ +func [d1006.knd, _complexMul] mul(value: @Complex): @Complex
+ end func
+
+ +func [d1006.knd, _complexDiv] div(value: @Complex): @Complex
+ end func
+
+ +func [d1006.knd, _complexPow] pow(value: @Complex): @Complex
+ end func
+
+ +func [d1006.knd, _complexExp] exp(): @Complex
+ end func
+
+ +func [d1006.knd, _complexLn] ln(): @Complex
+ end func
+
+ +func [d1006.knd, _complexSqrt] sqrt(): @Complex
+ end func
+
+ +func [d1006.knd, _complexCos] cos(): @Complex
+ end func
+
+ +func [d1006.knd, _complexSin] sin(): @Complex
+ end func
+
+ +func [d1006.knd, _complexTan] tan(): @Complex
+ end func
+
+ +func [d1006.knd, _complexAcos] acos(): @Complex
+ end func
+
+ +func [d1006.knd, _complexAsin] asin(): @Complex
+ end func
+
+ +func [d1006.knd, _complexAtan] atan(): @Complex
+ end func
+
+ +func [d1006.knd, _complexCosh] cosh(): @Complex
+ end func
+
+ +func [d1006.knd, _complexSinh] sinh(): @Complex
+ end func
+
+ +func [d1006.knd, _complexTanh] tanh(): @Complex
+ end func
+
+ +func [d1006.knd, _complexAcosh] acosh(): @Complex
+ end func
+
+ +func [d1006.knd, _complexAsinh] asinh(): @Complex
+ end func
+
+ +func [d1006.knd, _complexAtanh] atanh(): @Complex
+ end func
+
+ +func [d1006.knd, _complexAbs] abs(): @Complex
+ end func
+end class
+
++func [d1006.knd, _makeComplex, _make_instance] makeComplex(me2: @Complex): @Complex
+end func
diff --git a/package/sys/regex.kn b/package/sys/regex.kn
index d664f61b..3d7f28b3 100644
--- a/package/sys/regex.kn
+++ b/package/sys/regex.kn
@@ -5,18 +5,6 @@ end func
*func [d1002.knd, _regexDtor, _force] _dtor()
end func
- *func [_force] _copy(): kuin@Class
- throw 0xE9170005
- end func
-
- *func [_force] _toBin(): []bit8
- throw 0xE9170005
- end func
-
- *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class
- throw 0xE9170005
- end func
-
+func [d1002.knd, _regexFind] find(pos: &int, text: []char, start: int): [][]char
end func
diff --git a/package/sys/rescache.kn b/package/sys/rescache.kn
new file mode 100644
index 00000000..ba9935fe
--- /dev/null
+++ b/package/sys/rescache.kn
@@ -0,0 +1,59 @@
++class Instance()
+ +var instance: kuin@Class
+ +var cnt: int
+end class
+
++class ResCache()
+ *func ctor()
+ do me.instances :: #dict<[]char, @Instance>
+ do me.baseDir :: ""
+ end func
+
+ +func add(key: []char): @Instance
+ var success: bool
+ var instance: @Instance :: me.instances.get(key, &success)
+ if(success)
+ do instance.cnt :+ 1
+ ret instance
+ end if
+ do instance :: #@Instance
+ do instance.instance :: null
+ do instance.cnt :: 1
+ do me.instances.add(key, instance)
+ ret instance
+ end func
+
+ +func del(instance: kuin@Class)
+ class Data()
+ +var target: kuin@Class
+ +var key: []char
+ end class
+
+ var data: Data :: #Data
+ do data.target :: instance
+ do data.key :: null
+ do me.instances.forEach(freeRecursion, data)
+ if(data.key <>& null)
+ do me.instances.del(data.key)
+ end if
+
+ func freeRecursion(key: []char, value: @Instance, data: Data): bool
+ if(value.instance <>& data.target)
+ ret true
+ end if
+
+ do value.cnt :- 1
+ if(value.cnt = 0)
+ do data.key :: key
+ end if
+ ret false
+ end func
+ end func
+
+ +func setBaseDir(dir: []char)
+ do me.baseDir :: dir
+ end func
+
+ var instances: dict<[]char, @Instance>
+ var baseDir: []char
+end class
diff --git a/package/sys/rls/d1000.knd b/package/sys/rls/d1000.knd
index 117cc2d3..a1b6389f 100644
Binary files a/package/sys/rls/d1000.knd and b/package/sys/rls/d1000.knd differ
diff --git a/package/sys/rls/d1001.knd b/package/sys/rls/d1001.knd
index 353da02d..59c192e7 100644
Binary files a/package/sys/rls/d1001.knd and b/package/sys/rls/d1001.knd differ
diff --git a/package/sys/rls/d1002.knd b/package/sys/rls/d1002.knd
index 32cbe703..cb51fc0a 100644
Binary files a/package/sys/rls/d1002.knd and b/package/sys/rls/d1002.knd differ
diff --git a/package/sys/rls/d1003.knd b/package/sys/rls/d1003.knd
index f9883f15..98af5cf8 100644
Binary files a/package/sys/rls/d1003.knd and b/package/sys/rls/d1003.knd differ
diff --git a/package/sys/rls/d1004.knd b/package/sys/rls/d1004.knd
new file mode 100644
index 00000000..6b157300
Binary files /dev/null and b/package/sys/rls/d1004.knd differ
diff --git a/package/sys/rls/d1005.knd b/package/sys/rls/d1005.knd
new file mode 100644
index 00000000..f4496c33
Binary files /dev/null and b/package/sys/rls/d1005.knd differ
diff --git a/package/sys/rls/d1006.knd b/package/sys/rls/d1006.knd
new file mode 100644
index 00000000..1a36d69f
Binary files /dev/null and b/package/sys/rls/d1006.knd differ
diff --git a/package/sys/snd.kn b/package/sys/snd.kn
index a3a47a52..c7007b43 100644
--- a/package/sys/snd.kn
+++ b/package/sys/snd.kn
@@ -11,18 +11,6 @@ end func
*func [d0001.knd, _sndDtor, _force] _dtor()
end func
- *func [_force] _copy(): kuin@Class
- throw 0xE9170005
- end func
-
- *func [_force] _toBin(): []bit8
- throw 0xE9170005
- end func
-
- *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class
- throw 0xE9170005
- end func
-
+func [d0001.knd, _sndPlay] play()
end func
@@ -62,8 +50,11 @@ end func
var freq2: bit32
var streaming: bit32
var thread: int
+ var atomic: int
var volume2: float
var handle: int
var funcClose: int
var funcRead: int
+ var funcSetPos: int
+ var funcGetPos: int
end class
diff --git a/package/sys/snippet.knd b/package/sys/snippet.knd
index 35db43ec..dfb97099 100644
--- a/package/sys/snippet.knd
+++ b/package/sys/snippet.knd
@@ -2,10 +2,10 @@
mainと空のウインドウ
- var wndMain: wnd@Wnd
+ var {{wndMain}}: wnd@Wnd
func main()
-do @wndMain :: wnd@makeWnd(null, %normal, 800, 450, "Title")
+do @{{wndMain}} :: wnd@makeWnd(null, %normal, 800, 450, "{{Title}}")
while(wnd@act())
end while
@@ -14,12 +14,12 @@ end func
mainとdrawコントロール
- var wndMain: wnd@Wnd
-var drawMain: wnd@Draw
+ var {{wndMain}}: wnd@Wnd
+var {{drawMain}}: wnd@Draw
func main()
-do @wndMain :: wnd@makeWnd(null, %aspect, 1600, 900, "Title")
-do @drawMain :: wnd@makeDraw(@wndMain, 0, 0, 1600, 900, %scale, %scale, false)
+do @{{wndMain}} :: wnd@makeWnd(null, %aspect, 1600, 900, "{{Title}}")
+do @{{drawMain}} :: wnd@makeDraw(@{{wndMain}}, 0, 0, 1600, 900, %scale, %scale, false)
while(wnd@act())
do draw@render(60)
@@ -29,19 +29,19 @@ end func
listの走査
- do _0.head()
-while(!_0.term())
-var _1: _2 :: _0.get()
+ do {{x}}.head()
+while(!{{x}}.term())
+var {{item}}: {{itemType}} :: {{x}}.get()
-do _0.next()
+do {{x}}.next()
end while
dictの走査
- do _0.forEach(_1, null)
+ do {{x}}.forEach({{callback}}, null)
-func _1(key: _2, value: _3, data: kuin@Class): bool
+func {{callback}}(key: {{keyType}}, value: {{valueType}}, data: kuin@Class): bool
ret true
end func
diff --git a/package/sys/sql.kn b/package/sys/sql.kn
new file mode 100644
index 00000000..ca2217e0
--- /dev/null
+++ b/package/sys/sql.kn
@@ -0,0 +1,59 @@
+func [d1005.knd, _init] _init()
+end func
+
++class Sql()
+ *func [d1005.knd, _sqlDtor, _force] _dtor()
+ end func
+
+ +func [d1005.knd, _sqlFin] fin()
+ end func
+
+ +func [d1005.knd, _sqlExec] exec(cmd: []char): bool
+ end func
+
+ +func [d1005.knd, _sqlPrepare] prepare(cmd: []char): bool
+ end func
+
+ +func [d1005.knd, _sqlSetInt] setInt(col: int, value: int): bool
+ end func
+
+ +func [d1005.knd, _sqlSetFloat] setFloat(col: int, value: float): bool
+ end func
+
+ +func [d1005.knd, _sqlSetStr] setStr(col: int, value: []char): bool
+ end func
+
+ +func [d1005.knd, _sqlSetBlob] setBlob(col: int, value: []bit8): bool
+ end func
+
+ +func [d1005.knd, _sqlGetInt] getInt(col: int): int
+ end func
+
+ +func [d1005.knd, _sqlGetFloat] getFloat(col: int): float
+ end func
+
+ +func [d1005.knd, _sqlGetStr] getStr(col: int): []char
+ end func
+
+ +func [d1005.knd, _sqlCurrent] current(): bool
+ end func
+
+ +func [d1005.knd, _sqlNext] next(): bool
+ end func
+
+ +func [d1005.knd, _sqlApply] apply(): bool
+ end func
+
+ +func [d1005.knd, _sqlGetBlob] getBlob(col: int): []bit8
+ end func
+
+ +func [d1005.knd, _sqlErrMsg] errMsg(): []char
+ end func
+
+ var db: int
+ var statement: int
+ var result: int
+end class
+
++func [d1005.knd, _makeSql, _make_instance] makeSql(me2: @Sql, path: []char): @Sql
+end func
diff --git a/package/sys/task.kn b/package/sys/task.kn
index 65b9b06f..504cbe25 100644
--- a/package/sys/task.kn
+++ b/package/sys/task.kn
@@ -2,23 +2,22 @@
*func [d0000.knd, _processDtor, _force] _dtor()
end func
- *func [_force] _copy(): kuin@Class
- throw 0xE9170005
+ +func [d0000.knd, _processRun] run(waitUntilExit: bool): int
end func
- *func [_force] _toBin(): []bit8
- throw 0xE9170005
+ +func [d0000.knd, _processFin] fin()
end func
- *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class
- throw 0xE9170005
+ +func [d0000.knd, _processRunning] running(exitCode: &int): bool
end func
- +func [d0000.knd, _processRun] run(waitUntilExit: bool): int
+ +func [d0000.knd, _processReadPipe] readPipe(): []char
end func
var processHandle: int
var threadHandle: int
+ var readPipeHandle: int
+ var writePipeHandle: int
end class
+func [d0000.knd, _makeProcess, _make_instance] makeProcess(me2: @Process, path: []char, cmdLine: []char): @Process
@@ -31,18 +30,6 @@ end func
*func [d0000.knd, _threadDtor, _force] _dtor()
end func
- *func [_force] _copy(): kuin@Class
- throw 0xE9170005
- end func
-
- *func [_force] _toBin(): []bit8
- throw 0xE9170005
- end func
-
- *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class
- throw 0xE9170005
- end func
-
+func [d0000.knd, _threadRun] run()
end func
@@ -62,18 +49,6 @@ end func
*func [d0000.knd, _mutexDtor, _force] _dtor()
end func
- *func [_force] _copy(): kuin@Class
- throw 0xE9170005
- end func
-
- *func [_force] _toBin(): []bit8
- throw 0xE9170005
- end func
-
- *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class
- throw 0xE9170005
- end func
-
+func [d0000.knd, _mutexLock] lock()
end func
diff --git a/package/sys/undo.kn b/package/sys/undo.kn
index 2d6a5fc3..fb8878e7 100644
--- a/package/sys/undo.kn
+++ b/package/sys/undo.kn
@@ -13,7 +13,6 @@ end class
+func recordBegin()
if(dbg & me.state <> 0)
- do wnd@msgBox(null, "a", "piyo", %none, %ok)
throw 0xE917000A
end if
do me.state :: 1
@@ -21,7 +20,6 @@ end class
+func add(undo: @Cmd, redo: @Cmd)
if(dbg & me.state = 0)
- do wnd@msgBox(null, "b", "piyo", %none, %ok)
throw 0xE917000A
end if
do me.bufPtr :: me.bufPtrNext(me.bufPtr)
@@ -32,7 +30,6 @@ end class
+func recordEnd()
if(dbg & me.state = 0)
- do wnd@msgBox(null, "c", "piyo", %none, %ok)
throw 0xE917000A
end if
if(me.state = 2)
@@ -52,7 +49,6 @@ end class
+func undo()
if(dbg & me.state <> 0)
- do wnd@msgBox(null, "d", "piyo", %none, %ok)
throw 0xE917000A
end if
if(me.undoBuf[me.bufPtrPrev(me.bufPtr)] =& null)
@@ -69,7 +65,6 @@ end class
+func redo()
if(dbg & me.state <> 0)
- do wnd@msgBox(null, "e", "piyo", %none, %ok)
throw 0xE917000A
end if
if(me.redoBuf[me.bufPtrNext(me.bufPtr)] =& null)
diff --git a/package/sys/wipe.kn b/package/sys/wipe.kn
new file mode 100644
index 00000000..f67ea472
--- /dev/null
+++ b/package/sys/wipe.kn
@@ -0,0 +1,54 @@
++enum Type
+ none
+ fade
+ centerCircle
+end enum
+
+var state: float
+var type: @Type
+var speed: float
+var colorR: float
+var colorG: float
+var colorB: float
+
++func set(type: @Type, in: bool, time: int, color: int)
+ do @state :: 0.0
+ do @type :: type
+ do @speed :: 1.0 / (time $ float)
+ if(!in)
+ do @state :: 1.0
+ do @speed :: -@speed
+ end if
+ do draw@colorToArgb(&, &@colorR, &@colorG, &@colorB, color)
+end func
+
++func draw(): bool
+ do @state :+ @speed
+ if(@state < 0.0 & @speed < 0.0)
+ do @state :: 0.0
+ do @type :: %none
+ do @speed :: 0.0
+ elif(@state > 1.0 & @speed > 0.0)
+ do @state :: 1.0
+ do @type :: %none
+ do @speed :: 0.0
+ end if
+
+ var width: float :: draw@screenWidth() $ float
+ var height: float :: draw@screenHeight() $ float
+ if(@state = 0.0)
+ do draw@rect(0.0, 0.0, width, height, draw@argbToColor(1.0, @colorR, @colorG, @colorB))
+ ret true
+ elif(@state = 1.0)
+ ret true
+ else
+ switch(@type)
+ case %fade
+ do draw@rect(0.0, 0.0, width, height, draw@argbToColor(1.0 - @state, @colorR, @colorG, @colorB))
+ case %centerCircle
+ var radius: float :: lib@dist(0.0, 0.0, width / 2.0, height / 2.0) * (1.0 - @state)
+ do draw2d@circle(width / 2.0, height / 2.0, radius, radius, draw@argbToColor(1.0, @colorR, @colorG, @colorB))
+ end switch
+ ret false
+ end if
+end func
diff --git a/package/sys/wnd.kn b/package/sys/wnd.kn
index 454599dd..b4b99baa 100644
--- a/package/sys/wnd.kn
+++ b/package/sys/wnd.kn
@@ -12,12 +12,7 @@ end func
fix
aspect
popup
-{
- mdi
- mdiChild
- dock
- dockChild
-}
+ dialog
layered :: 0x10000
noMinimize :: 0x20000
end enum
@@ -32,18 +27,6 @@ end enum
*func [d0001.knd, _wndBaseDtor, _force] _dtor()
end func
- *func [_force] _copy(): kuin@Class
- throw 0xE9170005
- end func
-
- *func [_force] _toBin(): []bit8
- throw 0xE9170005
- end func
-
- *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class
- throw 0xE9170005
- end func
-
+func [d0001.knd, _wndBaseGetPos] getPos(x: &int, y: &int, width: &int, height: &int)
end func
@@ -117,6 +100,7 @@ end enum
var defaultWndProc: int
var ctrlFlag: int
var defaultRect: int
+ var redrawEnabled: int
+var children: list
end class
@@ -160,6 +144,12 @@ end class
+func [d0001.knd, _wndGetAlpha] getAlpha(): int
end func
+ +func [d0001.knd, _wndAcceptDraggedFiles] acceptDraggedFiles(isAccepted: bool)
+ end func
+
+ +func [d0001.knd, _wndUpdateMenu] updateMenu()
+ end func
+
+func modal()
do me.setModalLock()
while(@act() & me.modalLock)
@@ -173,6 +163,8 @@ end class
+var onClose: func<(@WndBase): bool>
+var onActivate: func<(@WndBase, bool, bool)>
+var onPushMenu: func<(@WndBase, int)>
+ +var onDropFiles: func<(@WndBase, [][]char)>
+ +var onResize: func<(@WndBase)>
var modalLock: bool
end class
@@ -198,6 +190,9 @@ end enum
+func [d0001.knd, _drawMoveCaret] moveCaret(x: int, y: int)
end func
+ +func [d0001.knd, _drawMouseCapture] mouseCapture(enabled: bool)
+ end func
+
var equalMagnification: int
var drawBuf: int
+var onPaint: func<(@WndBase, int, int)>
@@ -222,6 +217,11 @@ end enum
+var onSetMouseImg: func<(@WndBase): @MouseImg>
end class
++class DrawEditable(@Draw)
+ *func [d0001.knd, _drawDtor, _force] _dtor()
+ end func
+end class
+
+class Btn(@WndBase)
*func [d0001.knd, _wndBaseDtor, _force] _dtor()
end func
@@ -290,16 +290,23 @@ end class
end func
+var onChange: func<(@WndBase)>
+ +var onFocus: func<(@WndBase, bool)>
end class
+class Edit(@EditBase)
*func [d0001.knd, _wndBaseDtor, _force] _dtor()
end func
+
+ +func [d0001.knd, _editRightAligned] rightAligned(enabled: bool)
+ end func
end class
+class EditMulti(@EditBase)
*func [d0001.knd, _wndBaseDtor, _force] _dtor()
end func
+
+ +func [d0001.knd, _editMultiAddText] addText(text: []char)
+ end func
end class
+class List(@WndBase)
@@ -340,10 +347,32 @@ end class
+class Combo(@WndBase)
*func [d0001.knd, _wndBaseDtor, _force] _dtor()
end func
-end class
-+class ComboList(@WndBase)
- *func [d0001.knd, _wndBaseDtor, _force] _dtor()
+ +func [d0001.knd, _comboClear] clear()
+ end func
+
+ +func [d0001.knd, _comboAdd] add(text: []char)
+ end func
+
+ +func [d0001.knd, _comboIns] ins(idx: int, text: []char)
+ end func
+
+ +func [d0001.knd, _comboDel] del(idx: int)
+ end func
+
+ +func [d0001.knd, _comboLen] len(): int
+ end func
+
+ +func [d0001.knd, _comboSetSel] setSel(idx: int)
+ end func
+
+ +func [d0001.knd, _comboGetSel] getSel(): int
+ end func
+
+ +func [d0001.knd, _comboSetText] setText(idx: int, text: []char)
+ end func
+
+ +func [d0001.knd, _comboGetText] getText(idx: int): []char
end func
end class
@@ -404,6 +433,15 @@ end class
end func
end class
++enum ListViewStyle
+ large
+ report
+ small
+ list_
+ chk
+ hideHeader :: 0x4000
+end enum
+
+class ListView(@WndBase)
*func [d0001.knd, _wndBaseDtor, _force] _dtor()
end func
@@ -411,10 +449,10 @@ end class
+func [d0001.knd, _listViewClear] clear()
end func
- +func [d0001.knd, _listViewAdd] add(text: []char)
+ +func [d0001.knd, _listViewAdd] add(text: []char, img: int)
end func
- +func [d0001.knd, _listViewIns] ins(idx: int, text: []char)
+ +func [d0001.knd, _listViewIns] ins(idx: int, text: []char, img: int)
end func
+func [d0001.knd, _listViewDel] del(idx: int)
@@ -435,13 +473,13 @@ end class
+func [d0001.knd, _listViewLenColumn] lenColumn(): int
end func
- +func [d0001.knd, _listViewClearColumn] clearColumn()
+ +func [d0001.knd, _listViewClearAll] clearAll()
end func
- +func [d0001.knd, _listViewSetText] setText(idx: int, column: int, text: []char)
+ +func [d0001.knd, _listViewSetText] setText(idx: int, column: int, text: []char, img: int)
end func
- +func [d0001.knd, _listViewGetText] getText(idx: int, column: int): []char
+ +func [d0001.knd, _listViewGetText] getText(img: &int, idx: int, column: int): []char
end func
+func [d0001.knd, _listViewAdjustWidth] adjustWidth()
@@ -453,9 +491,30 @@ end class
+func [d0001.knd, _listViewGetSel] getSel(): int
end func
+ +func [d0001.knd, _listViewSetSelMulti] setSelMulti(idx: int, value: bool)
+ end func
+
+ +func [d0001.knd, _listViewGetSelMulti] getSelMulti(idx: int): bool
+ end func
+
+ +func [d0001.knd, _listViewStyle] style(listViewStyle: @ListViewStyle)
+ end func
+
+ +func [d0001.knd, _listViewDraggable] draggable(enabled: bool)
+ end func
+
+ +func [d0001.knd, _listViewSetChk] setChk(idx: int, value: bool)
+ end func
+
+ +func [d0001.knd, _listViewGetChk] getChk(idx: int): bool
+ end func
+
+var onSel: func<(@WndBase)>
+var onMouseDoubleClick: func<(@WndBase)>
+var onMouseClick: func<(@WndBase)>
+ +var onMoveNode: func<(@WndBase)>
+ var draggable_: int
+ var draggingImage: int
end class
+class Pager(@WndBase)
@@ -485,7 +544,7 @@ end class
+var onSel: func<(@WndBase)>
end class
-+class TreeBase(@WndBase)
++class Tree(@WndBase)
*func [d0001.knd, _wndBaseDtor, _force] _dtor()
end func
@@ -504,42 +563,16 @@ end class
+func [d0001.knd, _treeAllowDraggingToRoot] allowDraggingToRoot(enabled: bool)
end func
- var draggable_: int
- var draggingItem: int
- +var onSel: func<(@WndBase)>
- +var onMoveNode: func<(@WndBase)>
-end class
-
-+class Tree(@TreeBase)
- *func [d0001.knd, _wndBaseDtor, _force] _dtor()
- end func
-
+func [d0001.knd, _treeSetSel] setSel(node: @TreeNode)
end func
+func [d0001.knd, _treeGetSel, _make_instance] getSel(me2: @TreeNode): @TreeNode
end func
-end class
-
-+class TreeMulti(@TreeBase)
- *func [d0001.knd, _wndBaseDtor, _force] _dtor()
- end func
-
- +func [d0001.knd, _treeMultiSetSel] setSel(nodes: []@TreeNode)
- end func
-
- +func getSel(): []@TreeNode
- var result: list<@TreeNode> :: #list<@TreeNode>
- var node: @TreeNode :: me.getSelImpl(null)
- while(node <>& null)
- do result.add(node)
- do node :: me.getSelImpl(node)
- end while
- ret result.toArray()
- end func
- func [d0001.knd, _treeMultiGetSel, _make_instance] getSelImpl(me2: @TreeNode, node: @TreeNode): @TreeNode
- end func
+ var draggable_: int
+ var draggingItem: int
+ +var onSel: func<(@WndBase)>
+ +var onMoveNode: func<(@WndBase)>
end class
+class TreeNode()
@@ -547,18 +580,6 @@ end class
ret me.item - t.item
end func
- *func [_force] _copy(): kuin@Class
- throw 0xE9170005
- end func
-
- *func [_force] _toBin(): []bit8
- throw 0xE9170005
- end func
-
- *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class
- throw 0xE9170005
- end func
-
+func [d0001.knd, _treeNodeAddChild, _make_instance] addChild(me2: @TreeNode, name: []char): @TreeNode
end func
@@ -653,7 +674,10 @@ end enum
continue
end enum
-+func [d0001.knd, _onKeyPress] onKeyPress(onKeyPressFunc: func<(@Key, @ShiftCtrl): bool>)
++func [d0001.knd, _setOnKeyPress] setOnKeyPress(onKeyPressFunc: func<(@Key, @ShiftCtrl): bool>)
+end func
+
++func [d0001.knd, _getOnKeyPress] getOnKeyPress(): func<(@Key, @ShiftCtrl): bool>
end func
+func [d0001.knd, _msgBox] msgBox(parent: @Wnd, text: []char, title: []char, icon: @MsgBoxIcon, btn: @MsgBoxBtn): @MsgBoxResult
@@ -665,6 +689,12 @@ end func
+func [d0001.knd, _saveFileDialog] saveFileDialog(parent: @Wnd, filter: [][]char, defaultFilter: int, defaultExt: []char): []char
end func
++func [d0001.knd, _fileDialogDir] fileDialogDir(defaultDir: []char)
+end func
+
++func [d0001.knd, _colorDialog] colorDialog(parent: @Wnd, defaultColor: int): int
+end func
+
+func [d0001.knd, _setClipboardStr] setClipboardStr(str: []char)
end func
@@ -689,6 +719,18 @@ end func
end if
end func
++func [d0001.knd, _makeDrawReduced, _make_instance] makeDrawReduced(me2: @Draw, parent: @WndBase, x: int, y: int, width: int, height: int, anchorX: @Anchor, anchorY: @Anchor, equalMagnification: bool, split: int): @Draw
+ if(parent <>& null)
+ do parent.addChild(me2)
+ end if
+end func
+
++func [d0001.knd, _makeDrawEditable, _make_instance] makeDrawEditable(me2: @DrawEditable, parent: @WndBase, x: int, y: int, width: int, height: int): @DrawEditable
+ if(parent <>& null)
+ do parent.addChild(me2)
+ end if
+end func
+
+func [d0001.knd, _makeBtn, _make_instance] makeBtn(me2: @Btn, parent: @WndBase, x: int, y: int, width: int, height: int, anchorX: @Anchor, anchorY: @Anchor, text: []char): @Btn
if(parent <>& null)
do parent.addChild(me2)
@@ -731,12 +773,6 @@ end func
end if
end func
-+func [d0001.knd, _makeComboList, _make_instance] makeComboList(me2: @ComboList, parent: @WndBase, x: int, y: int, width: int, height: int, anchorX: @Anchor, anchorY: @Anchor): @ComboList
- if(parent <>& null)
- do parent.addChild(me2)
- end if
-end func
-
+func [d0001.knd, _makeLabel, _make_instance] makeLabel(me2: @Label, parent: @WndBase, x: int, y: int, width: int, height: int, anchorX: @Anchor, anchorY: @Anchor, text: []char): @Label
if(parent <>& null)
do parent.addChild(me2)
@@ -791,7 +827,7 @@ end func
end if
end func
-+func [d0001.knd, _makeListView, _make_instance] makeListView(me2: @ListView, parent: @WndBase, x: int, y: int, width: int, height: int, anchorX: @Anchor, anchorY: @Anchor): @ListView
++func [d0001.knd, _makeListView, _make_instance] makeListView(me2: @ListView, parent: @WndBase, x: int, y: int, width: int, height: int, anchorX: @Anchor, anchorY: @Anchor, multiSel: bool, smallImgs: [][]char, largeImgs: [][]char): @ListView
if(parent <>& null)
do parent.addChild(me2)
end if
@@ -815,12 +851,6 @@ end func
end if
end func
-+func [d0001.knd, _makeTreeMulti, _make_instance] makeTreeMulti(me2: @TreeMulti, parent: @WndBase, x: int, y: int, width: int, height: int, anchorX: @Anchor, anchorY: @Anchor): @TreeMulti
- if(parent <>& null)
- do parent.addChild(me2)
- end if
-end func
-
+func [d0001.knd, _makeSplitX, _make_instance] makeSplitX(me2: @SplitX, parent: @WndBase, x: int, y: int, width: int, height: int, anchorX: @Anchor, anchorY: @Anchor): @SplitX
if(parent <>& null)
do parent.addChild(me2)
@@ -849,26 +879,27 @@ end func
*func [d0001.knd, _menuDtor, _force] _dtor()
end func
- *func [_force] _copy(): kuin@Class
- throw 0xE9170005
+ +func [d0001.knd, _menuAdd] add(id: int, text: []char)
end func
- *func [_force] _toBin(): []bit8
- throw 0xE9170005
+ +func [d0001.knd, _menuAddLine] addLine()
end func
- *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class
- throw 0xE9170005
+ +func [d0001.knd, _menuAddPopup] addPopup(text: []char, popup: @Popup)
+ do me.children.add(popup)
end func
- +func [d0001.knd, _menuAdd] add(id: int, text: []char)
+ +func [d0001.knd, _menuIns] ins(targetId: int, id: int, text: []char)
end func
- +func [d0001.knd, _menuAddLine] addLine()
+ +func [d0001.knd, _menuInsPopup] insPopup(target: @Popup, text: []char, popup: @Popup)
+ do me.children.add(popup)
end func
- +func [d0001.knd, _menuAddPopup] addPopup(text: []char, popup: @Popup)
- do me.children.add(popup)
+ +func [d0001.knd, _menuDel] del(id: int)
+ end func
+
+ +func [d0001.knd, _menuDelPopup] delPopup(popup: @Popup)
end func
var handle: int
@@ -892,16 +923,7 @@ end func
end func
+class TabOrder()
- *func [_force] _copy(): kuin@Class
- throw 0xE9170005
- end func
-
- *func [_force] _toBin(): []bit8
- throw 0xE9170005
- end func
-
- *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class
- throw 0xE9170005
+ *func [_force] _dtor()
end func
+func [d0001.knd, _tabOrderChk] chk(key: @Key, shiftCtrl: @ShiftCtrl): bool
@@ -987,6 +1009,10 @@ end func
f10
f11
f12
+ plus :: 0xBB
+ comma
+ minus
+ period
end enum
+enum MouseImg
@@ -995,8 +1021,8 @@ end enum
wait
cross
upArrow
- resizeLTRD :: 32642
- resizeRTLD
+ resizeLTRB :: 32642
+ resizeRTLB
resizeH
resizeV
move
diff --git a/package/sys/wndex.kn b/package/sys/wndex.kn
index 65a92db2..547d2e4d 100644
--- a/package/sys/wndex.kn
+++ b/package/sys/wndex.kn
@@ -7,7 +7,7 @@ var inputBoxValidate: func<([]char):bool>
var inputBoxResult: []char
+func inputBox(parent: wnd@Wnd, text: []char, title: []char, defaultValue: []char, validate: func<([]char):bool>): []char
- do @inputBoxWndMain :: wnd@makeWnd(parent, (%fix $ wnd@WndStyle).or(%noMinimize), 353, 120, title)
+ do @inputBoxWndMain :: wnd@makeWnd(parent, (%dialog $ wnd@WndStyle).or(%noMinimize), 353, 120, title)
var screenWidth: int
var screenHeight: int
do wnd@screenSize(&screenWidth, &screenHeight)
@@ -21,12 +21,19 @@ var inputBoxResult: []char
do @inputBoxBtnCancel :: wnd@makeBtn(@inputBoxWndMain, 281, 41, 60, 23, %fix, %fix, "Cancel")
do @inputBoxBtnCancel.onPush :: btnCancelOnPush
do @inputBoxEditInput :: wnd@makeEdit(@inputBoxWndMain, 12, 89, 329, 19, %fix, %fix)
+ do @inputBoxEditInput.focus()
if(defaultValue <>& null)
do @inputBoxEditInput.setText(defaultValue)
end if
+ do @inputBoxEditInput.setSel(0, -1)
do @inputBoxValidate :: validate
do @inputBoxResult :: null
+
+ var oldOnKeyPress: func<(wnd@Key, wnd@ShiftCtrl): bool> :: wnd@getOnKeyPress()
+ do wnd@setOnKeyPress(onKeyPress)
do @inputBoxWndMain.modal()
+ do wnd@setOnKeyPress(oldOnKeyPress)
+
var result: []char :: @inputBoxResult
do @inputBoxWndMain :: null
do @inputBoxLabelText :: null
@@ -37,6 +44,17 @@ var inputBoxResult: []char
do @inputBoxResult :: null
ret result
+ func onKeyPress(key: wnd@Key, shiftCtrl: wnd@ShiftCtrl): bool
+ if(shiftCtrl = %none)
+ switch(key)
+ case %enter
+ do btnOkOnPush(null)
+ case %esc
+ do btnCancelOnPush(null)
+ end switch
+ end if
+ end func
+
func btnOkOnPush(wnd: wnd@Btn)
var text: []char :: @inputBoxEditInput.getText()
if(@inputBoxValidate =& null | @inputBoxValidate(text))
@@ -90,7 +108,7 @@ end func
case "list"
do result :: wnd@makeList(parent, x, y, width, height, anchorX, anchorY)
case "list_view"
- do result :: wnd@makeListView(parent, x, y, width, height, anchorX, anchorY)
+ do result :: wnd@makeListView(parent, x, y, width, height, anchorX, anchorY, false, null, null)
case "draw"
do result :: wnd@makeDraw(parent, x, y, width, height, anchorX, anchorY, parseBool(node, "equal_magnification"))
case "radio"
@@ -137,7 +155,9 @@ end func
ret 0
end if
var result: int
- if(attr.toInt(&result))
+ var existed: bool
+ do result :: attr.toInt(&existed)
+ if(existed)
ret result
else
ret 0
diff --git a/package/sys/xml.kn b/package/sys/xml.kn
index 051b37b2..09da645d 100644
--- a/package/sys/xml.kn
+++ b/package/sys/xml.kn
@@ -5,18 +5,6 @@ end func
*func [d1003.knd, _xmlDtor, _force] _dtor()
end func
- *func [_force] _copy(): kuin@Class
- throw 0xE9170005
- end func
-
- *func [_force] _toBin(): []bit8
- throw 0xE9170005
- end func
-
- *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class
- throw 0xE9170005
- end func
-
+func [d1003.knd, _xmlSave] save(path: []char, compact: bool): bool
end func
@@ -42,18 +30,6 @@ end func
*func [d1003.knd, _xmlNodeDtor, _force] _dtor()
end func
- *func [_force] _copy(): kuin@Class
- throw 0xE9170005
- end func
-
- *func [_force] _toBin(): []bit8
- throw 0xE9170005
- end func
-
- *func [_force] _fromBin(bin: []bit8, idx: &int): kuin@Class
- throw 0xE9170005
- end func
-
+func [d1003.knd, _xmlNodeSetName] setName(name: []char)
end func
diff --git a/package/sys/zip.kn b/package/sys/zip.kn
index 518ce59e..ef17d66b 100644
--- a/package/sys/zip.kn
+++ b/package/sys/zip.kn
@@ -1,2 +1,8 @@
+func [d1001.knd, _init] _init()
+end func
+
+func [d1001.knd, _zip] zip(dst: []char, src: []char, compressionLevel: int): bool
end func
+
++func [d1001.knd, _unzip] unzip(dst: []char, src: []char): bool
+end func
diff --git a/package/tools/knobj_maker.exe b/package/tools/knobj_maker.exe
new file mode 100644
index 00000000..4b84ba4a
Binary files /dev/null and b/package/tools/knobj_maker.exe differ
diff --git a/src/additional_libs/additional_libs.sln b/src/additional_libs/additional_libs.sln
new file mode 100644
index 00000000..3de1c5ec
--- /dev/null
+++ b/src/additional_libs/additional_libs.sln
@@ -0,0 +1,72 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.24720.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_regex", "..\lib_regex\lib_regex.vcxproj", "{CBFC1A36-CC6C-487E-B3D4-4E1351D4141A}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_game", "..\lib_game\lib_game.vcxproj", "{7CA2B257-7CBE-4934-A176-533374E47F7A}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_ogg", "..\lib_ogg\lib_ogg.vcxproj", "{4E33C07A-3A9E-47AF-A0E5-B97EBDFC95D5}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_sql", "..\lib_sql\lib_sql.vcxproj", "{FBC3E3AB-6B81-4950-9099-52CB1F78447B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_xml", "..\lib_xml\lib_xml.vcxproj", "{22E28BB9-5741-47CC-9152-C7F6E2DBA53F}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_zip", "..\lib_zip\lib_zip.vcxproj", "{DE354C81-BC60-442E-A729-52A48D550A06}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_math_boost", "..\lib_math_boost\lib_math_boost.vcxproj", "{C4024A39-66F3-43D0-BAAE-755737DD29A5}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Release_dbg|x64 = Release_dbg|x64
+ Release_rls|x64 = Release_rls|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {CBFC1A36-CC6C-487E-B3D4-4E1351D4141A}.Debug|x64.ActiveCfg = Debug|x64
+ {CBFC1A36-CC6C-487E-B3D4-4E1351D4141A}.Debug|x64.Build.0 = Debug|x64
+ {CBFC1A36-CC6C-487E-B3D4-4E1351D4141A}.Release_dbg|x64.ActiveCfg = Release_dbg|x64
+ {CBFC1A36-CC6C-487E-B3D4-4E1351D4141A}.Release_dbg|x64.Build.0 = Release_dbg|x64
+ {CBFC1A36-CC6C-487E-B3D4-4E1351D4141A}.Release_rls|x64.ActiveCfg = Release_rls|x64
+ {CBFC1A36-CC6C-487E-B3D4-4E1351D4141A}.Release_rls|x64.Build.0 = Release_rls|x64
+ {7CA2B257-7CBE-4934-A176-533374E47F7A}.Debug|x64.ActiveCfg = Debug|x64
+ {7CA2B257-7CBE-4934-A176-533374E47F7A}.Debug|x64.Build.0 = Debug|x64
+ {7CA2B257-7CBE-4934-A176-533374E47F7A}.Release_dbg|x64.ActiveCfg = Release_dbg|x64
+ {7CA2B257-7CBE-4934-A176-533374E47F7A}.Release_dbg|x64.Build.0 = Release_dbg|x64
+ {7CA2B257-7CBE-4934-A176-533374E47F7A}.Release_rls|x64.ActiveCfg = Release_rls|x64
+ {7CA2B257-7CBE-4934-A176-533374E47F7A}.Release_rls|x64.Build.0 = Release_rls|x64
+ {4E33C07A-3A9E-47AF-A0E5-B97EBDFC95D5}.Debug|x64.ActiveCfg = Debug|x64
+ {4E33C07A-3A9E-47AF-A0E5-B97EBDFC95D5}.Debug|x64.Build.0 = Debug|x64
+ {4E33C07A-3A9E-47AF-A0E5-B97EBDFC95D5}.Release_dbg|x64.ActiveCfg = Release_dbg|x64
+ {4E33C07A-3A9E-47AF-A0E5-B97EBDFC95D5}.Release_dbg|x64.Build.0 = Release_dbg|x64
+ {4E33C07A-3A9E-47AF-A0E5-B97EBDFC95D5}.Release_rls|x64.ActiveCfg = Release_rls|x64
+ {4E33C07A-3A9E-47AF-A0E5-B97EBDFC95D5}.Release_rls|x64.Build.0 = Release_rls|x64
+ {FBC3E3AB-6B81-4950-9099-52CB1F78447B}.Debug|x64.ActiveCfg = Debug|x64
+ {FBC3E3AB-6B81-4950-9099-52CB1F78447B}.Debug|x64.Build.0 = Debug|x64
+ {FBC3E3AB-6B81-4950-9099-52CB1F78447B}.Release_dbg|x64.ActiveCfg = Release_dbg|x64
+ {FBC3E3AB-6B81-4950-9099-52CB1F78447B}.Release_dbg|x64.Build.0 = Release_dbg|x64
+ {FBC3E3AB-6B81-4950-9099-52CB1F78447B}.Release_rls|x64.ActiveCfg = Release_rls|x64
+ {FBC3E3AB-6B81-4950-9099-52CB1F78447B}.Release_rls|x64.Build.0 = Release_rls|x64
+ {22E28BB9-5741-47CC-9152-C7F6E2DBA53F}.Debug|x64.ActiveCfg = Debug|x64
+ {22E28BB9-5741-47CC-9152-C7F6E2DBA53F}.Debug|x64.Build.0 = Debug|x64
+ {22E28BB9-5741-47CC-9152-C7F6E2DBA53F}.Release_dbg|x64.ActiveCfg = Release_dbg|x64
+ {22E28BB9-5741-47CC-9152-C7F6E2DBA53F}.Release_dbg|x64.Build.0 = Release_dbg|x64
+ {22E28BB9-5741-47CC-9152-C7F6E2DBA53F}.Release_rls|x64.ActiveCfg = Release_rls|x64
+ {22E28BB9-5741-47CC-9152-C7F6E2DBA53F}.Release_rls|x64.Build.0 = Release_rls|x64
+ {DE354C81-BC60-442E-A729-52A48D550A06}.Debug|x64.ActiveCfg = Debug|x64
+ {DE354C81-BC60-442E-A729-52A48D550A06}.Debug|x64.Build.0 = Debug|x64
+ {DE354C81-BC60-442E-A729-52A48D550A06}.Release_dbg|x64.ActiveCfg = Release_dbg|x64
+ {DE354C81-BC60-442E-A729-52A48D550A06}.Release_dbg|x64.Build.0 = Release_dbg|x64
+ {DE354C81-BC60-442E-A729-52A48D550A06}.Release_rls|x64.ActiveCfg = Release_rls|x64
+ {DE354C81-BC60-442E-A729-52A48D550A06}.Release_rls|x64.Build.0 = Release_rls|x64
+ {C4024A39-66F3-43D0-BAAE-755737DD29A5}.Debug|x64.ActiveCfg = Debug|x64
+ {C4024A39-66F3-43D0-BAAE-755737DD29A5}.Debug|x64.Build.0 = Debug|x64
+ {C4024A39-66F3-43D0-BAAE-755737DD29A5}.Release_dbg|x64.ActiveCfg = Release_dbg|x64
+ {C4024A39-66F3-43D0-BAAE-755737DD29A5}.Release_dbg|x64.Build.0 = Release_dbg|x64
+ {C4024A39-66F3-43D0-BAAE-755737DD29A5}.Release_rls|x64.ActiveCfg = Release_rls|x64
+ {C4024A39-66F3-43D0-BAAE-755737DD29A5}.Release_rls|x64.Build.0 = Release_rls|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/src/bin_to_text/main.c b/src/bin_to_text/main.c
index f79cb63f..40471684 100644
--- a/src/bin_to_text/main.c
+++ b/src/bin_to_text/main.c
@@ -55,11 +55,36 @@ int wmain(int argc, Char** argv)
ptr++;
}
}
+
+ Char upper_name[MAX_PATH];
+ {
+ const Char* ptr = name;
+ Char* ptr2 = upper_name;
+ Bool first = True;
+ while (*ptr != L'\0')
+ {
+ if (*ptr == '_')
+ {
+ first = True;
+ ptr++;
+ continue;
+ }
+ if (first && 'a' <= *ptr && *ptr <= 'z')
+ *ptr2 = *ptr - 'a' + 'A';
+ else
+ *ptr2 = *ptr;
+ first = False;
+ ptr++;
+ ptr2++;
+ }
+ *ptr2 = L'\0';
+ }
+
wcscat(path, L".c");
file_ptr2 = _wfopen(path, L"w, ccs=UTF-8");
fwprintf(file_ptr2, L"#include \"../common.h\"\n");
fwprintf(file_ptr2, L"\n");
- fwprintf(file_ptr2, L"const U8* GetBin(size_t* size)\n");
+ fwprintf(file_ptr2, L"const U8* Get%s(size_t* size)\n", upper_name);
fwprintf(file_ptr2, L"{\n");
fwprintf(file_ptr2, L"\tstatic const U8 %s[0x%08x] =\n", name, (U32)size);
fwprintf(file_ptr2, L"\t{\n");
diff --git a/src/common.c b/src/common.c
index d5d43b98..eea870ed 100644
--- a/src/common.c
+++ b/src/common.c
@@ -21,33 +21,115 @@ typedef struct SFile
U64 Key;
} SFile;
-void* Heap;
-S64* HeapCnt;
-S64 AppCode;
-const U8* UseResFlags;
-HINSTANCE Instance;
+SEnvVars EnvVars;
#if !defined(DBG)
static SFile* OpenPackFile(const Char* path);
#endif
static U8 GetKey(U64 key, U8 data, U64 pos);
+Bool InitEnvVars(void* heap, S64* heap_cnt, S64 app_code, const U8* use_res_flags)
+{
+ if (EnvVars.Heap != NULL)
+ return False;
+
+ EnvVars.Heap = heap;
+#if defined(_DEBUG)
+ EnvVars.HeapCnt = heap_cnt;
+#else
+ UNUSED(heap_cnt);
+#endif
+ EnvVars.AppCode = app_code;
+ EnvVars.UseResFlags = use_res_flags;
+
+ // The resource root directory.
+#if defined(DBG)
+ {
+ Char cur_dir_path[KUIN_MAX_PATH + 12 + 1];
+ GetModuleFileName(NULL, cur_dir_path, KUIN_MAX_PATH);
+ {
+ Char* ptr = wcsrchr(cur_dir_path, L'\\');
+ if (ptr != NULL)
+ *(ptr + 1) = L'\0';
+ }
+ wcscat(cur_dir_path, L"_curdir_.txt");
+ if (PathFileExists(cur_dir_path))
+ {
+ Char path[KUIN_MAX_PATH + 1];
+ FILE* file_ptr = _wfopen(cur_dir_path, L"r, ccs=UTF-8");
+ fgetws(path, KUIN_MAX_PATH, file_ptr);
+ {
+ Char* ptr = path;
+ while (ptr[1] != L'\0')
+ ptr++;
+ while (ptr >= path && (*ptr == L'\n' || *ptr == L'\r'))
+ {
+ *ptr = L'\0';
+ ptr--;
+ }
+ }
+ wcscpy(EnvVars.ResRoot, path);
+ }
+ else
+ {
+ Char* ptr;
+ GetModuleFileName(NULL, EnvVars.ResRoot, KUIN_MAX_PATH);
+ ptr = wcsrchr(EnvVars.ResRoot, L'\\');
+ if (ptr != NULL)
+ *(ptr + 1) = L'\0';
+ ptr = EnvVars.ResRoot;
+ while (*ptr != L'\0')
+ {
+ if (*ptr == L'\\')
+ *ptr = L'/';
+ ptr++;
+ }
+ }
+ }
+#else
+ {
+ Char* ptr;
+ GetModuleFileName(NULL, EnvVars.ResRoot, KUIN_MAX_PATH);
+ ptr = wcsrchr(EnvVars.ResRoot, L'\\');
+ if (ptr != NULL)
+ *(ptr + 1) = L'\0';
+ ptr = EnvVars.ResRoot;
+ while (*ptr != L'\0')
+ {
+ if (*ptr == L'\\')
+ *ptr = L'/';
+ ptr++;
+ }
+ }
+#endif
+
+ return True;
+}
+
void* AllocMem(size_t size)
{
- void* result = HeapAlloc(Heap, HEAP_GENERATE_EXCEPTIONS, (SIZE_T)size);
+ void* result = HeapAlloc(EnvVars.Heap, HEAP_GENERATE_EXCEPTIONS, (SIZE_T)size);
#if defined(_DEBUG)
memset(result, 0xcd, size);
- (*HeapCnt)++;
+ (*EnvVars.HeapCnt)++;
#endif
return result;
}
+void* ReAllocMem(void* ptr, size_t size)
+{
+ if (ptr == NULL)
+ return HeapAlloc(EnvVars.Heap, HEAP_GENERATE_EXCEPTIONS, (SIZE_T)size);
+ else
+ return HeapReAlloc(EnvVars.Heap, HEAP_GENERATE_EXCEPTIONS, ptr, (SIZE_T)size);
+}
+
void FreeMem(void* ptr)
{
- HeapFree(Heap, 0, ptr);
+ HeapFree(EnvVars.Heap, 0, ptr);
#if defined(_DEBUG)
- (*HeapCnt)--;
- ASSERT(*HeapCnt >= 0);
+ (*EnvVars.HeapCnt)--;
+ ASSERT(*EnvVars.HeapCnt >= 0);
#endif
}
@@ -59,7 +141,7 @@ void ThrowImpl(U32 code)
void* LoadFileAll(const Char* path, size_t* size)
{
#if !defined(DBG)
- if (path[0] == L'r' || path[1] == L'e' || path[2] == L's' || path[3] == L'/')
+ if (path[0] == L'r' && path[1] == L'e' && path[2] == L's' && path[3] == L'/')
{
SFile* handle = OpenPackFile(path + 4);
if (handle == NULL)
@@ -82,7 +164,20 @@ void* LoadFileAll(const Char* path, size_t* size)
else
#endif
{
+#if defined(DBG)
+ FILE* file_ptr;
+ if (path[0] == L'r' && path[1] == L'e' && path[2] == L's' && path[3] == L'/')
+ {
+ Char path2[KUIN_MAX_PATH * 2 + 1];
+ wcscpy(path2, EnvVars.ResRoot);
+ wcscat(path2, path);
+ file_ptr = _wfopen(path2, L"rb");
+ }
+ else
+ file_ptr = _wfopen(path, L"rb");
+#else
FILE* file_ptr = _wfopen(path, L"rb");
+#endif
if (file_ptr == NULL)
return NULL;
_fseeki64(file_ptr, 0, SEEK_END);
@@ -103,7 +198,7 @@ void* LoadFileAll(const Char* path, size_t* size)
void* OpenFileStream(const Char* path)
{
#if !defined(DBG)
- if (path[0] == L'r' || path[1] == L'e' || path[2] == L's' || path[3] == L'/')
+ if (path[0] == L'r' && path[1] == L'e' && path[2] == L's' && path[3] == L'/')
{
SFile* handle = OpenPackFile(path + 4);
if (handle == NULL)
@@ -113,7 +208,20 @@ void* OpenFileStream(const Char* path)
else
#endif
{
+#if defined(DBG)
+ FILE* file_ptr;
+ if (path[0] == L'r' && path[1] == L'e' && path[2] == L's' && path[3] == L'/')
+ {
+ Char path2[KUIN_MAX_PATH * 2 + 1];
+ wcscpy(path2, EnvVars.ResRoot);
+ wcscat(path2, path);
+ file_ptr = _wfopen(path2, L"rb");
+ }
+ else
+ file_ptr = _wfopen(path, L"rb");
+#else
FILE* file_ptr = _wfopen(path, L"rb");
+#endif
if (file_ptr == NULL)
return NULL;
{
@@ -253,6 +361,11 @@ Bool IsPowerOf2(U64 n)
return (n & (n - 1)) == 0;
}
+U32 MakeSeed(U32 key)
+{
+ return (U32)(time(NULL)) ^ (U32)timeGetTime() ^ key;
+}
+
U32 XorShift(U32* seed)
{
U32 x = *seed;
@@ -263,6 +376,35 @@ U32 XorShift(U32* seed)
return x;
}
+U64 XorShift64(U32* seed)
+{
+ U32 a = XorShift(seed);
+ U32 b = XorShift(seed);
+ return ((U64)a << 32) | (U64)b;
+}
+
+S64 XorShiftInt(U32* seed, S64 min, S64 max)
+{
+ U64 n = (U64)(max - min + 1);
+ U64 m = 0 - ((0 - n) % n);
+ U64 r;
+ if (m == 0)
+ r = XorShift64(seed);
+ else
+ {
+ do
+ {
+ r = XorShift64(seed);
+ } while (m <= r);
+ }
+ return (S64)(r % n) + min;
+}
+
+double XorShiftFloat(U32* seed, double min, double max)
+{
+ return (double)(XorShift64(seed)) / 18446744073709551616.0 * (max - min) + min;
+}
+
char* Utf16ToUtf8(const U8* str)
{
if (str == NULL)
@@ -302,15 +444,21 @@ Bool IsResUsed(EUseResFlagsKind kind)
{
S64 idx = (S64)kind;
ASSERT(1 <= idx && (idx - 1) / 8 < USE_RES_FLAGS_LEN);
- return (UseResFlags[(idx - 1) / 8] & (1 << ((idx - 1) % 8))) != 0;
+ return (EnvVars.UseResFlags[(idx - 1) / 8] & (1 << ((idx - 1) % 8))) != 0;
}
#if !defined(DBG)
static SFile* OpenPackFile(const Char* path)
{
- FILE* file_ptr = _wfopen(L"res.knd", L"rb");
- if (file_ptr == NULL)
- return NULL;
+ FILE* file_ptr;
+ {
+ Char path2[KUIN_MAX_PATH + 1];
+ wcscpy(path2, EnvVars.ResRoot);
+ wcscat(path2, L"res.knd");
+ file_ptr = _wfopen(path2, L"rb");
+ if (file_ptr == NULL)
+ return NULL;
+ }
SFile* handle = (SFile*)AllocMem(sizeof(SFile));
handle->Pack = True;
handle->Handle = file_ptr;
@@ -321,7 +469,7 @@ static SFile* OpenPackFile(const Char* path)
U64 len;
{
fread(&key, sizeof(U64), 1, file_ptr);
- key ^= (U64)AppCode * 0x9271ac8394027acb + 0x35718394ca72849e;
+ key ^= (U64)EnvVars.AppCode * 0x9271ac8394027acb + 0x35718394ca72849e;
handle->Key = key;
}
{
diff --git a/src/common.h b/src/common.h
index dbe12c5e..1a4e411e 100644
--- a/src/common.h
+++ b/src/common.h
@@ -32,6 +32,19 @@
#define EXPORT _declspec(dllexport)
#define EXPORT_CPP extern "C" _declspec(dllexport)
#define KUIN_MAX_PATH (512)
+#define STACK_STRING_BUF_SIZE (1024) // Default size of string buffer on stack.
+
+#define EXCPT_ACCESS_VIOLATION (0xc0000005)
+#define EXCPT_DBG_ASSERT_FAILED (0xe9170000)
+#define EXCPT_CLASS_CAST_FAILED (0xe9170001)
+#define EXCPT_DBG_ARRAY_IDX_OUT_OF_RANGE (0xe9170002)
+#define EXCPT_DBG_INT_OVERFLOW (0xe9170003)
+#define EXCPT_INVALID_CMP (0xe9170004)
+#define EXCPT_DBG_ARG_OUT_DOMAIN (0xe9170006)
+#define EXCPT_FILE_READ_FAILED (0xe9170007)
+#define EXCPT_INVALID_DATA_FMT (0xe9170008)
+#define EXCPT_DEVICE_INIT_FAILED (0xe9170009)
+#define EXCPT_DBG_INOPERABLE_STATE (0xe917000a)
#if defined(_DEBUG)
#define ASSERT(cond) _ASSERTE((cond))
@@ -69,22 +82,54 @@ typedef struct SClass
static const S64 DefaultRefCntFunc = 0; // Just before exiting the function, this is incremented for 'GcInstance'.
static const S64 DefaultRefCntOpe = 1; // For 'GcInstance'.
-static void* DummyPtr = (void*)1i64; // An invalid pointer used to point to non-NULL.
+static const void* DummyPtr = (void*)1i64; // An invalid pointer used to point to non-NULL.
typedef enum EUseResFlagsKind
{
UseResFlagsKind_Draw_Circle = 1,
- UseResFlagsKind_Draw_FilterMonotone,
+ UseResFlagsKind_Draw_FilterMonotone = 2,
+ UseResFlagsKind_Draw_Particle = 3,
+ UseResFlagsKind_Draw_Poly = 4,
+ UseResFlagsKind_Draw_ObjDraw = 5,
+ UseResFlagsKind_Draw_ObjDrawOutline = 6,
} EUseResFlagsKind;
#define USE_RES_FLAGS_LEN (1)
-extern void* Heap;
-extern S64* HeapCnt;
-extern S64 AppCode;
-extern const U8* UseResFlags;
-extern HINSTANCE Instance;
+/*
+ Uncommitted libraries:
+ d0000.knd common
+ d0001.knd wnd
+ d0002.knd cui
+ d0003.knd math
+ d0004.knd net
+ d0005.knd draw2d
+ d0917.knd compiler
+
+ Committed additional libraries:
+ d1000.knd ogg
+ d1001.knd zip
+ d1002.knd regex(boost)
+ d1003.knd xml
+ d1004.knd game
+ d1005.knd sql
+ d1006.knd math_boost
+*/
+
+typedef struct SEnvVars
+{
+ void* Heap;
+#if defined(_DEBUG)
+ S64* HeapCnt;
+#endif
+ S64 AppCode;
+ const U8* UseResFlags;
+ Char ResRoot[KUIN_MAX_PATH];
+} SEnvVars;
+extern SEnvVars EnvVars;
+Bool InitEnvVars(void* heap, S64* heap_cnt, S64 app_code, const U8* use_res_flags);
void* AllocMem(size_t size);
+void* ReAllocMem(void* ptr, size_t size);
void FreeMem(void* ptr);
void ThrowImpl(U32 code);
void* LoadFileAll(const Char* path, size_t* size);
@@ -99,7 +144,11 @@ U16 SwapEndianU16(U16 n);
U32 SwapEndianU32(U32 n);
U64 SwapEndianU64(U64 n);
Bool IsPowerOf2(U64 n);
+U32 MakeSeed(U32 key);
U32 XorShift(U32* seed);
+U64 XorShift64(U32* seed);
+S64 XorShiftInt(U32* seed, S64 min, S64 max);
+double XorShiftFloat(U32* seed, double min, double max);
char* Utf16ToUtf8(const U8* str);
U8* Utf8ToUtf16(const char* str);
Bool IsResUsed(EUseResFlagsKind kind);
diff --git a/src/compiler/analyze.c b/src/compiler/analyze.c
index ed5c7ff7..00dc6bc6 100644
--- a/src/compiler/analyze.c
+++ b/src/compiler/analyze.c
@@ -13,7 +13,7 @@ static const Char* BuildInFuncs[] =
L"clamp\0 \x0b",
L"clampMax\0 \x0b",
L"clampMin\0 \x0b",
- L"del\0 \x09",
+ L"del\0 \x0f",
L"delNext\0 \x09",
L"endian\0 \x04",
L"exist\0 \x0d",
@@ -27,7 +27,9 @@ static const Char* BuildInFuncs[] =
L"forEach\0 \x0d",
L"get\0 \x08",
L"getOffset\0 \x09",
+ L"getPtr\0 \x09",
L"head\0 \x09",
+ L"idx\0 \x09",
L"ins\0 \x09",
L"join\0 \x0c",
L"lower\0 \x06",
@@ -44,6 +46,7 @@ static const Char* BuildInFuncs[] =
L"replace\0 \x06",
L"reverse\0 \x05",
L"sar\0 \x04",
+ L"setPtr\0 \x09",
L"shl\0 \x04",
L"shr\0 \x04",
L"shuffle\0 \x05",
@@ -58,6 +61,7 @@ static const Char* BuildInFuncs[] =
L"toArray\0 \x09",
L"toArrayKey\0 \x0d",
L"toArrayValue\0 \x0d",
+ L"toBit64\0 \x06",
L"toFloat\0 \x06",
L"toInt\0 \x06",
L"toStr\0 \x01",
@@ -84,6 +88,8 @@ static U64 BitCast(int size, U64 n);
static SAstFunc* AddSpecialFunc(SAstClass* class_, const Char* name);
static SAst* SearchStdItem(const Char* src, const Char* identifier, Bool make_expr_ref);
static SAstExprDot* MakeMeDot(SAstClass* class_, SAstArg* arg, const Char* name);
+static SAstExprValue* MakeExprNull(const SPos* pos);
+static SAstExpr* CacheSubExpr(SList* stats, SAstExpr* ast, const SPos* pos);
static void AddDllFunc(const Char* dll_name, const Char* func_name);
static int GetBuildInFuncType(const Char* name);
static S64 GetEnumElementValue(SAstExprValue* ast, SAstEnum* enum_);
@@ -316,7 +322,10 @@ static void ResolveIdentifierRecursion(const Char* src, const SAst* scope)
else
{
if (ast->RefName[0] != L'\0')
+ {
Err(L"EA0000", ast->Pos, ast->RefName);
+ ast->TypeId = AstTypeId_Ast;
+ }
ast->RefItem = NULL;
}
}
@@ -453,7 +462,7 @@ static Bool CmpType(const SAstType* type1, const SAstType* type2)
}
return ((SAst*)type1)->RefItem == ((SAst*)type2)->RefItem;
}
- if ((type_id1 == AstTypeId_TypeUser && ((SAst*)type1)->RefItem->TypeId == AstTypeId_Enum || type_id1 == AstTypeId_TypeEnumElement) && (type_id2 == AstTypeId_TypeUser && ((SAst*)type2)->RefItem->TypeId == AstTypeId_Enum || type_id2 == AstTypeId_TypeEnumElement))
+ if ((type_id1 == AstTypeId_TypeUser && ((SAst*)type1)->RefItem->TypeId == AstTypeId_Enum || type_id1 == AstTypeId_TypeEnumElement) && (type_id2 == AstTypeId_TypeUser && ((SAst*)type2)->RefItem->TypeId == AstTypeId_Enum || type_id2 == AstTypeId_TypeEnumElement) && !(type_id1 == AstTypeId_TypeEnumElement && type_id2 == AstTypeId_TypeEnumElement))
return True;
return False;
}
@@ -493,6 +502,7 @@ static SAstFunc* AddSpecialFunc(SAstClass* class_, const Char* name)
((SAst*)func)->Name = name;
func->AddrTop = NewAddr();
func->AddrBottom = -1;
+ func->PosRowBottom = -1;
func->DllName = NULL;
func->DllFuncName = NULL;
func->FuncAttr = FuncAttr_None;
@@ -595,6 +605,61 @@ static SAstExprDot* MakeMeDot(SAstClass* class_, SAstArg* arg, const Char* name)
return dot;
}
+static SAstExprValue* MakeExprNull(const SPos* pos)
+{
+ SAstExprValue* value = (SAstExprValue*)Alloc(sizeof(SAstExprValue));
+ InitAstExpr((SAstExpr*)value, AstTypeId_ExprValue, pos);
+ *(S64*)value->Value = 0;
+ {
+ SAstTypeNull* null_ = (SAstTypeNull*)Alloc(sizeof(SAstTypeNull));
+ InitAst((SAst*)null_, AstTypeId_TypeNull, pos);
+ ((SAstExpr*)value)->Type = (SAstType*)null_;
+ }
+ return value;
+}
+
+static SAstExpr* CacheSubExpr(SList* stats, SAstExpr* ast, const SPos* pos)
+{
+ if (ast == NULL)
+ return NULL;
+ if (((SAst*)ast)->TypeId == AstTypeId_ExprRef || ((SAst*)ast)->TypeId == AstTypeId_ExprValue)
+ return ast;
+ SAstExpr* ref = (SAstExpr*)Alloc(sizeof(SAstExpr));
+ InitAstExpr(ref, AstTypeId_ExprRef, pos);
+ ((SAst*)ref)->RefName = L"$";
+ ref->VarKind = AstExprVarKind_LocalVar;
+ ((SAst*)ref)->AnalyzedCache = (SAst*)ref;
+ {
+ SAstArg* arg = (SAstArg*)Alloc(sizeof(SAstArg));
+ InitAst((SAst*)arg, AstTypeId_Arg, pos);
+ arg->Addr = NewAddr();
+ arg->Kind = AstArgKind_LocalVar;
+ arg->RefVar = False;
+ arg->Type = ast->Type;
+ arg->Expr = NULL;
+ ((SAst*)arg)->AnalyzedCache = (SAst*)arg;
+ ((SAst*)ref)->RefItem = (SAst*)arg;
+ ref->Type = arg->Type;
+ }
+ {
+ SAstStatDo* do_stat = (SAstStatDo*)Alloc(sizeof(SAstStatDo));
+ InitAst((SAst*)do_stat, AstTypeId_StatDo, pos);
+ ((SAstStat*)do_stat)->AsmTop = NULL;
+ ((SAstStat*)do_stat)->AsmBottom = NULL;
+ ((SAstStat*)do_stat)->PosRowBottom = pos->Row;
+ {
+ SAstExpr2* expr_assign = (SAstExpr2*)Alloc(sizeof(SAstExpr2));
+ InitAstExpr((SAstExpr*)expr_assign, AstTypeId_Expr2, pos);
+ expr_assign->Kind = AstExpr2Kind_Assign;
+ expr_assign->Children[0] = ref;
+ expr_assign->Children[1] = ast;
+ do_stat->Expr = (SAstExpr*)expr_assign;
+ }
+ ListAdd(stats, RebuildDo(do_stat));
+ }
+ return ref;
+}
+
static void AddDllFunc(const Char* dll_name, const Char* func_name)
{
SDict* dll = (SDict*)DictSearch(Dlls, dll_name);
@@ -647,10 +712,15 @@ static const void* AddInitFuncs(const Char* key, const void* value, void* param)
if (key[0] == L'\\')
return value;
SList* funcs = (SList*)param;
- if (wcscmp(key, L"math") == 0 ||
+ if (wcscmp(key, L"draw2d") == 0 ||
+ wcscmp(key, L"game") == 0 ||
+ wcscmp(key, L"math") == 0 ||
wcscmp(key, L"net") == 0 ||
+ wcscmp(key, L"num") == 0 ||
wcscmp(key, L"regex") == 0 ||
- wcscmp(key, L"xml") == 0)
+ wcscmp(key, L"sql") == 0 ||
+ wcscmp(key, L"xml") == 0 ||
+ wcscmp(key, L"zip") == 0)
{
ListAdd(funcs, SearchStdItem(key, L"_init", False));
}
@@ -662,7 +732,8 @@ static const void* AddFinFuncs(const Char* key, const void* value, void* param)
if (key[0] == L'\\')
return value;
SList* funcs = (SList*)param;
- if (wcscmp(key, L"net") == 0)
+ if (wcscmp(key, L"draw2d") == 0 ||
+ wcscmp(key, L"net") == 0)
ListAdd(funcs, SearchStdItem(key, L"_fin", False));
return value;
}
@@ -676,6 +747,7 @@ static SAstFunc* Rebuild(const SAstFunc* main_func)
((SAst*)func)->Name = L"$";
func->AddrTop = NewAddr();
func->AddrBottom = -1;
+ func->PosRowBottom = -1;
func->DllName = NULL;
func->DllFuncName = NULL;
func->FuncAttr = FuncAttr_None;
@@ -686,6 +758,9 @@ static SAstFunc* Rebuild(const SAstFunc* main_func)
{
SAstStatTry* try_ = (SAstStatTry*)Alloc(sizeof(SAstStatTry));
InitAst((SAst*)try_, AstTypeId_StatTry, pos);
+ ((SAstStat*)try_)->AsmTop = NULL;
+ ((SAstStat*)try_)->AsmBottom = NULL;
+ ((SAstStat*)try_)->PosRowBottom = -1;
{
SAstArg* var = (SAstArg*)Alloc(sizeof(SAstArg));
InitAst((SAst*)var, AstTypeId_Arg, pos);
@@ -706,6 +781,9 @@ static SAstFunc* Rebuild(const SAstFunc* main_func)
{
SAstStatBlock* block = (SAstStatBlock*)Alloc(sizeof(SAstStatBlock));
InitAst((SAst*)block, AstTypeId_StatBlock, pos);
+ ((SAstStat*)block)->AsmTop = NULL;
+ ((SAstStat*)block)->AsmBottom = NULL;
+ ((SAstStat*)block)->PosRowBottom = -1;
((SAst*)block)->Name = L"$";
((SAstStatBreakable*)block)->BlockVar = NULL;
((SAstStatBreakable*)block)->BreakPoint = NULL;
@@ -716,6 +794,9 @@ static SAstFunc* Rebuild(const SAstFunc* main_func)
{
SAstStatBlock* block = (SAstStatBlock*)Alloc(sizeof(SAstStatBlock));
InitAst((SAst*)block, AstTypeId_StatBlock, pos);
+ ((SAstStat*)block)->AsmTop = NULL;
+ ((SAstStat*)block)->AsmBottom = NULL;
+ ((SAstStat*)block)->PosRowBottom = -1;
((SAst*)block)->Name = L"$";
((SAstStatBreakable*)block)->BlockVar = NULL;
((SAstStatBreakable*)block)->BreakPoint = NULL;
@@ -747,6 +828,9 @@ static SAstFunc* Rebuild(const SAstFunc* main_func)
{
SAstStatDo* do_ = (SAstStatDo*)Alloc(sizeof(SAstStatDo));
InitAst((SAst*)do_, AstTypeId_StatDo, pos);
+ ((SAstStat*)do_)->AsmTop = NULL;
+ ((SAstStat*)do_)->AsmBottom = NULL;
+ ((SAstStat*)do_)->PosRowBottom = -1;
{
SAstExprCall* call = (SAstExprCall*)Alloc(sizeof(SAstExprCall));
InitAstExpr((SAstExpr*)call, AstTypeId_ExprCall, pos);
@@ -767,10 +851,16 @@ static SAstFunc* Rebuild(const SAstFunc* main_func)
{
SAstStatCatch* catch_ = (SAstStatCatch*)Alloc(sizeof(SAstStatCatch));
InitAst((SAst*)catch_, AstTypeId_StatCatch, pos);
+ ((SAstStat*)catch_)->AsmTop = NULL;
+ ((SAstStat*)catch_)->AsmBottom = NULL;
+ ((SAstStat*)catch_)->PosRowBottom = -1;
catch_->Conds = ListNew();
{
SAstStatBlock* block = (SAstStatBlock*)Alloc(sizeof(SAstStatBlock));
InitAst((SAst*)block, AstTypeId_StatBlock, pos);
+ ((SAstStat*)block)->AsmTop = NULL;
+ ((SAstStat*)block)->AsmBottom = NULL;
+ ((SAstStat*)block)->PosRowBottom = -1;
((SAst*)block)->Name = L"$";
((SAstStatBreakable*)block)->BlockVar = NULL;
((SAstStatBreakable*)block)->BreakPoint = NULL;
@@ -809,6 +899,9 @@ static SAstFunc* Rebuild(const SAstFunc* main_func)
// Make the program to call 'err'.
SAstStatDo* do_ = (SAstStatDo*)Alloc(sizeof(SAstStatDo));
InitAst((SAst*)do_, AstTypeId_StatDo, pos);
+ ((SAstStat*)do_)->AsmTop = NULL;
+ ((SAstStat*)do_)->AsmBottom = NULL;
+ ((SAstStat*)do_)->PosRowBottom = -1;
{
SAstExprCall* call = (SAstExprCall*)Alloc(sizeof(SAstExprCall));
InitAstExpr((SAstExpr*)call, AstTypeId_ExprCall, pos);
@@ -822,7 +915,7 @@ static SAstFunc* Rebuild(const SAstFunc* main_func)
{
SAstExprCallArg* excpt = (SAstExprCallArg*)Alloc(sizeof(SAstExprCallArg));
excpt->RefVar = False;
- excpt->SkipVar = NULL;
+ excpt->SkipVar = False;
{
SAstExpr* ref_ = (SAstExpr*)Alloc(sizeof(SAstExpr));
InitAstExpr(ref_, AstTypeId_ExprRef, pos);
@@ -861,6 +954,9 @@ static SAstFunc* Rebuild(const SAstFunc* main_func)
{
SAstStatDo* do_ = (SAstStatDo*)Alloc(sizeof(SAstStatDo));
InitAst((SAst*)do_, AstTypeId_StatDo, pos);
+ ((SAstStat*)do_)->AsmTop = NULL;
+ ((SAstStat*)do_)->AsmBottom = NULL;
+ ((SAstStat*)do_)->PosRowBottom = -1;
{
SAstExprCall* call = (SAstExprCall*)Alloc(sizeof(SAstExprCall));
InitAstExpr((SAstExpr*)call, AstTypeId_ExprCall, pos);
@@ -930,6 +1026,9 @@ static void RebuildRoot(SAstRoot* ast)
{
SAstStatDo* do_ = (SAstStatDo*)Alloc(sizeof(SAstStatDo));
InitAst((SAst*)do_, AstTypeId_StatDo, ((SAst*)ast)->Pos);
+ ((SAstStat*)do_)->AsmTop = NULL;
+ ((SAstStat*)do_)->AsmBottom = NULL;
+ ((SAstStat*)do_)->PosRowBottom = -1;
{
SAstExpr2* assign = (SAstExpr2*)Alloc(sizeof(SAstExpr2));
InitAstExpr((SAstExpr*)assign, AstTypeId_Expr2, ((SAst*)ast)->Pos);
@@ -952,6 +1051,9 @@ static void RebuildRoot(SAstRoot* ast)
// Add finalization processing of global variables to '_finVars'.
SAstStatDo* do_ = (SAstStatDo*)Alloc(sizeof(SAstStatDo));
InitAst((SAst*)do_, AstTypeId_StatDo, ((SAst*)ast)->Pos);
+ ((SAstStat*)do_)->AsmTop = NULL;
+ ((SAstStat*)do_)->AsmBottom = NULL;
+ ((SAstStat*)do_)->PosRowBottom = -1;
{
SAstExpr2* assign = (SAstExpr2*)Alloc(sizeof(SAstExpr2));
InitAstExpr((SAstExpr*)assign, AstTypeId_Expr2, ((SAst*)ast)->Pos);
@@ -963,17 +1065,7 @@ static void RebuildRoot(SAstRoot* ast)
((SAst*)ref_)->RefItem = (SAst*)var->Var;
assign->Children[0] = ref_;
}
- {
- SAstExprValue* value = (SAstExprValue*)Alloc(sizeof(SAstExprValue));
- InitAstExpr((SAstExpr*)value, AstTypeId_ExprValue, ((SAst*)ast)->Pos);
- *(S64*)value->Value = 0;
- {
- SAstTypeNull* null_ = (SAstTypeNull*)Alloc(sizeof(SAstTypeNull));
- InitAst((SAst*)null_, AstTypeId_TypeNull, ((SAst*)ast)->Pos);
- ((SAstExpr*)value)->Type = (SAstType*)null_;
- }
- assign->Children[1] = (SAstExpr*)value;
- }
+ assign->Children[1] = (SAstExpr*)MakeExprNull(((SAst*)ast)->Pos);
do_->Expr = (SAstExpr*)assign;
}
ListAdd(fin_vars->Stats, RebuildStat((SAstStat*)do_, NULL, NULL));
@@ -1063,7 +1155,20 @@ static void RebuildClass(SAstClass* ast)
return;
((SAst*)ast)->AnalyzedCache = (SAst*)ast;
if (((SAst*)ast)->RefItem != NULL)
- RebuildClass((SAstClass*)((SAst*)ast)->RefItem);
+ {
+ SAst* parent = ((SAst*)ast)->RefItem;
+ if (parent->TypeId == AstTypeId_Alias)
+ {
+ RebuildAlias((SAstAlias*)parent, NULL);
+ ((SAst*)ast)->RefItem = ((SAst*)((SAstAlias*)parent)->Type)->RefItem;
+ ASSERT(((SAst*)ast)->RefItem->TypeId == AstTypeId_Class);
+ }
+ else
+ {
+ ASSERT(parent->TypeId == AstTypeId_Class);
+ RebuildClass((SAstClass*)parent);
+ }
+ }
{
// Make sure that the class references do not circulate.
SAstClass* parent = ast;
@@ -1185,6 +1290,24 @@ static void RebuildClass(SAstClass* ast)
item->ParentItem = parent_item;
}
}
+ ptr = ptr->Next;
+ }
+ }
+ {
+ SListNode* ptr = ast->Items->Top;
+ while (ptr != NULL)
+ {
+ SAstClassItem* item = (SAstClassItem*)ptr->Data;
+ const Char* member_name;
+ {
+ SAst* def = item->Def;
+ if (def->TypeId == AstTypeId_Var)
+ member_name = ((SAst*)((SAstVar*)def)->Var)->Name;
+ else if (def->TypeId == AstTypeId_Const)
+ member_name = ((SAst*)((SAstConst*)def)->Var)->Name;
+ else
+ member_name = def->Name;
+ }
if (wcscmp(member_name, L"_dtor") == 0 || wcscmp(member_name, L"_copy") == 0 || wcscmp(member_name, L"_toBin") == 0 || wcscmp(member_name, L"_fromBin") == 0)
{
ASSERT(item->Def->TypeId == AstTypeId_Func);
@@ -1195,7 +1318,11 @@ static void RebuildClass(SAstClass* ast)
}
switch (member_name[1])
{
- case L'd': dtor = (SAstFunc*)item->Def; break;
+ case L'd':
+ dtor = (SAstFunc*)item->Def;
+ if (item->Override)
+ ast->IndirectCreation = True;
+ break;
case L'c': copy = (SAstFunc*)item->Def; break;
case L't': to_bin = (SAstFunc*)item->Def; break;
case L'f': from_bin = (SAstFunc*)item->Def; break;
@@ -1203,9 +1330,8 @@ static void RebuildClass(SAstClass* ast)
ASSERT(False);
}
// Skip 'RebuildFunc' to add the contents later.
- ptr = ptr->Next;
- continue;
}
+ else
{
// Analyze functions and variables in classes because they can be referred to as instances.
SAst* def = item->Def;
@@ -1301,22 +1427,15 @@ static void RebuildClass(SAstClass* ast)
{
SAstStatDo* do_ = (SAstStatDo*)Alloc(sizeof(SAstStatDo));
InitAst((SAst*)do_, AstTypeId_StatDo, ((SAst*)ast)->Pos);
+ ((SAstStat*)do_)->AsmTop = NULL;
+ ((SAstStat*)do_)->AsmBottom = NULL;
+ ((SAstStat*)do_)->PosRowBottom = -1;
{
SAstExpr2* assign = (SAstExpr2*)Alloc(sizeof(SAstExpr2));
InitAstExpr((SAstExpr*)assign, AstTypeId_Expr2, ((SAst*)ast)->Pos);
assign->Kind = AstExpr2Kind_Assign;
assign->Children[0] = (SAstExpr*)MakeMeDot(ast, (SAstArg*)dtor->Args->Top->Data, ((SAst*)((SAstVar*)item->Def)->Var)->Name);
- {
- SAstExprValue* value = (SAstExprValue*)Alloc(sizeof(SAstExprValue));
- InitAstExpr((SAstExpr*)value, AstTypeId_ExprValue, ((SAst*)ast)->Pos);
- *(S64*)value->Value = 0;
- {
- SAstTypeNull* null = (SAstTypeNull*)Alloc(sizeof(SAstTypeNull));
- InitAst((SAst*)null, AstTypeId_TypeNull, ((SAst*)ast)->Pos);
- ((SAstExpr*)value)->Type = (SAstType*)null;
- }
- assign->Children[1] = (SAstExpr*)value;
- }
+ assign->Children[1] = (SAstExpr*)MakeExprNull(((SAst*)ast)->Pos);
do_->Expr = (SAstExpr*)assign;
}
ListAdd(dtor->Stats, RebuildStat((SAstStat*)do_, dtor->Ret, dtor));
@@ -1327,11 +1446,15 @@ static void RebuildClass(SAstClass* ast)
}
}
// The '_copy' function.
+ if (!ast->IndirectCreation)
{
SAstExpr* result;
{
SAstStatVar* var = (SAstStatVar*)Alloc(sizeof(SAstStatVar));
InitAst((SAst*)var, AstTypeId_StatVar, ((SAst*)ast)->Pos);
+ ((SAstStat*)var)->AsmTop = NULL;
+ ((SAstStat*)var)->AsmBottom = NULL;
+ ((SAstStat*)var)->PosRowBottom = -1;
{
SAstVar* var2 = (SAstVar*)Alloc(sizeof(SAstVar));
InitAst((SAst*)var2, AstTypeId_Var, ((SAst*)ast)->Pos);
@@ -1351,6 +1474,7 @@ static void RebuildClass(SAstClass* ast)
SAstExprNew* new_ = (SAstExprNew*)Alloc(sizeof(SAstExprNew));
InitAstExpr((SAstExpr*)new_, AstTypeId_ExprNew, ((SAst*)ast)->Pos);
new_->ItemType = arg->Type;
+ new_->AutoCreated = True;
arg->Expr = (SAstExpr*)new_;
}
var2->Var = arg;
@@ -1385,6 +1509,9 @@ static void RebuildClass(SAstClass* ast)
{
SAstStatDo* do_ = (SAstStatDo*)Alloc(sizeof(SAstStatDo));
InitAst((SAst*)do_, AstTypeId_StatDo, ((SAst*)ast)->Pos);
+ ((SAstStat*)do_)->AsmTop = NULL;
+ ((SAstStat*)do_)->AsmBottom = NULL;
+ ((SAstStat*)do_)->PosRowBottom = -1;
{
SAstExpr2* assign = (SAstExpr2*)Alloc(sizeof(SAstExpr2));
InitAstExpr((SAstExpr*)assign, AstTypeId_Expr2, ((SAst*)ast)->Pos);
@@ -1397,19 +1524,21 @@ static void RebuildClass(SAstClass* ast)
dot->ClassItem = NULL;
assign->Children[0] = (SAstExpr*)dot;
}
+ if (IsRef(member->Type))
{
- SAstExprDot* dot = MakeMeDot(ast, (SAstArg*)copy->Args->Top->Data, ((SAst*)member)->Name);
- if (IsRef(member->Type))
+ if (IsClass(member->Type) && ((SAstClass*)((SAst*)member->Type)->RefItem)->IndirectCreation)
+ assign->Children[1] = (SAstExpr*)MakeExprNull(((SAst*)ast)->Pos);
+ else
{
SAstExpr1* copy2 = (SAstExpr1*)Alloc(sizeof(SAstExpr1));
InitAstExpr((SAstExpr*)copy2, AstTypeId_Expr1, ((SAst*)ast)->Pos);
copy2->Kind = AstExpr1Kind_Copy;
- copy2->Child = (SAstExpr*)dot;
+ copy2->Child = (SAstExpr*)MakeMeDot(ast, (SAstArg*)copy->Args->Top->Data, ((SAst*)member)->Name);
assign->Children[1] = (SAstExpr*)copy2;
}
- else
- assign->Children[1] = (SAstExpr*)dot;
}
+ else
+ assign->Children[1] = (SAstExpr*)MakeMeDot(ast, (SAstArg*)copy->Args->Top->Data, ((SAst*)member)->Name);
do_->Expr = (SAstExpr*)assign;
}
ListAdd(copy->Stats, RebuildStat((SAstStat*)do_, copy->Ret, copy));
@@ -1423,6 +1552,9 @@ static void RebuildClass(SAstClass* ast)
{
SAstStatRet* ret = (SAstStatRet*)Alloc(sizeof(SAstStatRet));
InitAst((SAst*)ret, AstTypeId_StatRet, ((SAst*)ast)->Pos);
+ ((SAstStat*)ret)->AsmTop = NULL;
+ ((SAstStat*)ret)->AsmBottom = NULL;
+ ((SAstStat*)ret)->PosRowBottom = -1;
{
SAstExprAs* as = (SAstExprAs*)Alloc(sizeof(SAstExprAs));
InitAstExpr((SAstExpr*)as, AstTypeId_ExprAs, ((SAst*)ast)->Pos);
@@ -1435,11 +1567,15 @@ static void RebuildClass(SAstClass* ast)
}
}
// The '_toBin' function.
+ if (!ast->IndirectCreation)
{
SAstExpr* result;
{
SAstStatVar* var = (SAstStatVar*)Alloc(sizeof(SAstStatVar));
InitAst((SAst*)var, AstTypeId_StatVar, ((SAst*)ast)->Pos);
+ ((SAstStat*)var)->AsmTop = NULL;
+ ((SAstStat*)var)->AsmBottom = NULL;
+ ((SAstStat*)var)->PosRowBottom = -1;
{
SAstVar* var2 = (SAstVar*)Alloc(sizeof(SAstVar));
InitAst((SAst*)var2, AstTypeId_Var, ((SAst*)ast)->Pos);
@@ -1515,11 +1651,20 @@ static void RebuildClass(SAstClass* ast)
{
SAstStatDo* do_ = (SAstStatDo*)Alloc(sizeof(SAstStatDo));
InitAst((SAst*)do_, AstTypeId_StatDo, ((SAst*)ast)->Pos);
+ ((SAstStat*)do_)->AsmTop = NULL;
+ ((SAstStat*)do_)->AsmBottom = NULL;
+ ((SAstStat*)do_)->PosRowBottom = -1;
{
SAstExpr2* assign = (SAstExpr2*)Alloc(sizeof(SAstExpr2));
InitAstExpr((SAstExpr*)assign, AstTypeId_Expr2, ((SAst*)ast)->Pos);
assign->Kind = AstExpr2Kind_AssignCat;
assign->Children[0] = result;
+ if (IsClass(member->Type) && ((SAstClass*)((SAst*)member->Type)->RefItem)->IndirectCreation)
+ {
+ ptr2 = ptr2->Next;
+ continue;
+ }
+ else
{
SAstExprToBin* expr = (SAstExprToBin*)Alloc(sizeof(SAstExprToBin));
InitAstExpr((SAstExpr*)expr, AstTypeId_ExprToBin, ((SAst*)ast)->Pos);
@@ -1550,16 +1695,23 @@ static void RebuildClass(SAstClass* ast)
{
SAstStatRet* ret = (SAstStatRet*)Alloc(sizeof(SAstStatRet));
InitAst((SAst*)ret, AstTypeId_StatRet, ((SAst*)ast)->Pos);
+ ((SAstStat*)ret)->AsmTop = NULL;
+ ((SAstStat*)ret)->AsmBottom = NULL;
+ ((SAstStat*)ret)->PosRowBottom = -1;
ret->Value = result;
ListAdd(to_bin->Stats, RebuildStat((SAstStat*)ret, to_bin->Ret, to_bin));
}
}
// The '_fromBin' function.
+ if (!ast->IndirectCreation)
{
SAstExpr* result;
{
SAstStatVar* var = (SAstStatVar*)Alloc(sizeof(SAstStatVar));
InitAst((SAst*)var, AstTypeId_StatVar, ((SAst*)ast)->Pos);
+ ((SAstStat*)var)->AsmTop = NULL;
+ ((SAstStat*)var)->AsmBottom = NULL;
+ ((SAstStat*)var)->PosRowBottom = -1;
{
SAstVar* var2 = (SAstVar*)Alloc(sizeof(SAstVar));
InitAst((SAst*)var2, AstTypeId_Var, ((SAst*)ast)->Pos);
@@ -1574,6 +1726,7 @@ static void RebuildClass(SAstClass* ast)
SAstExprNew* new_ = (SAstExprNew*)Alloc(sizeof(SAstExprNew));
InitAstExpr((SAstExpr*)new_, AstTypeId_ExprNew, ((SAst*)ast)->Pos);
new_->ItemType = arg->Type;
+ new_->AutoCreated = True;
arg->Expr = (SAstExpr*)new_;
}
var2->Var = arg;
@@ -1608,6 +1761,9 @@ static void RebuildClass(SAstClass* ast)
{
SAstStatDo* do_ = (SAstStatDo*)Alloc(sizeof(SAstStatDo));
InitAst((SAst*)do_, AstTypeId_StatDo, ((SAst*)ast)->Pos);
+ ((SAstStat*)do_)->AsmTop = NULL;
+ ((SAstStat*)do_)->AsmBottom = NULL;
+ ((SAstStat*)do_)->PosRowBottom = -1;
{
SAstExpr2* assign = (SAstExpr2*)Alloc(sizeof(SAstExpr2));
InitAstExpr((SAstExpr*)assign, AstTypeId_Expr2, ((SAst*)ast)->Pos);
@@ -1620,6 +1776,9 @@ static void RebuildClass(SAstClass* ast)
dot->Member = ((SAst*)member)->Name;
assign->Children[0] = (SAstExpr*)dot;
}
+ if (IsClass(member->Type) && ((SAstClass*)((SAst*)member->Type)->RefItem)->IndirectCreation)
+ assign->Children[1] = (SAstExpr*)MakeExprNull(((SAst*)ast)->Pos);
+ else
{
SAstExprFromBin* expr = (SAstExprFromBin*)Alloc(sizeof(SAstExprFromBin));
InitAstExpr((SAstExpr*)expr, AstTypeId_ExprFromBin, ((SAst*)ast)->Pos);
@@ -1651,6 +1810,9 @@ static void RebuildClass(SAstClass* ast)
{
SAstStatRet* ret = (SAstStatRet*)Alloc(sizeof(SAstStatRet));
InitAst((SAst*)ret, AstTypeId_StatRet, ((SAst*)ast)->Pos);
+ ((SAstStat*)ret)->AsmTop = NULL;
+ ((SAstStat*)ret)->AsmBottom = NULL;
+ ((SAstStat*)ret)->PosRowBottom = -1;
ret->Value = result;
ListAdd(from_bin->Stats, RebuildStat((SAstStat*)ret, from_bin->Ret, from_bin));
}
@@ -1746,6 +1908,8 @@ static void RebuildArg(SAstArg* ast)
static SAstStat* RebuildStat(SAstStat* ast, SAstType* ret_type, SAstFunc* parent_func)
{
+ if (ast == NULL)
+ return NULL;
switch (((SAst*)ast)->TypeId)
{
case AstTypeId_StatFunc:
@@ -1787,6 +1951,9 @@ static SAstStat* RebuildStat(SAstStat* ast, SAstType* ret_type, SAstFunc* parent
// Replace initializers with assignment operators.
SAstStatDo* ast_do = (SAstStatDo*)Alloc(sizeof(SAstStatDo));
InitAst((SAst*)ast_do, AstTypeId_StatDo, ((SAst*)ast)->Pos);
+ ((SAstStat*)ast_do)->AsmTop = NULL;
+ ((SAstStat*)ast_do)->AsmBottom = NULL;
+ ((SAstStat*)ast_do)->PosRowBottom = ((SAst*)ast_do)->Pos->Row;
{
SAstExpr2* ast_assign = (SAstExpr2*)Alloc(sizeof(SAstExpr2));
InitAst((SAst*)ast_assign, AstTypeId_Expr2, ((SAst*)ast)->Pos);
@@ -1879,6 +2046,9 @@ static SAstStat* RebuildIf(SAstStatIf* ast, SAstType* ret_type, SAstFunc* parent
{
SAstStatBlock* block = (SAstStatBlock*)Alloc(sizeof(SAstStatBlock));
InitAst((SAst*)block, AstTypeId_StatBlock, ((SAst*)ast)->Pos);
+ ((SAstStat*)block)->AsmTop = NULL;
+ ((SAstStat*)block)->AsmBottom = NULL;
+ ((SAstStat*)block)->PosRowBottom = -1;
((SAst*)block)->AnalyzedCache = (SAst*)block;
((SAst*)block)->Name = L"$";
((SAstStatBreakable*)block)->BlockVar = NULL;
@@ -2077,6 +2247,64 @@ static SAstStat* RebuildDo(SAstStatDo* ast)
if (((SAst*)ast)->AnalyzedCache != NULL)
return (SAstStat*)((SAst*)ast)->AnalyzedCache;
((SAst*)ast)->AnalyzedCache = (SAst*)ast;
+ if (ast->Expr != NULL && ((SAst*)ast->Expr)->TypeId == AstTypeId_Expr2)
+ {
+ SAstExpr2* expr = (SAstExpr2*)ast->Expr;
+ // Replace all assignment operators that are not '::' with '::'
+ {
+ EAstExpr2Kind kind = AstExpr2Kind_Assign;
+ switch (expr->Kind)
+ {
+ case AstExpr2Kind_AssignAdd: kind = AstExpr2Kind_Add; break;
+ case AstExpr2Kind_AssignSub: kind = AstExpr2Kind_Sub; break;
+ case AstExpr2Kind_AssignMul: kind = AstExpr2Kind_Mul; break;
+ case AstExpr2Kind_AssignDiv: kind = AstExpr2Kind_Div; break;
+ case AstExpr2Kind_AssignMod: kind = AstExpr2Kind_Mod; break;
+ case AstExpr2Kind_AssignPow: kind = AstExpr2Kind_Pow; break;
+ case AstExpr2Kind_AssignCat: kind = AstExpr2Kind_Cat; break;
+ }
+ if (kind != AstExpr2Kind_Assign)
+ {
+ SAstStatBlock* block = (SAstStatBlock*)Alloc(sizeof(SAstStatBlock));
+ InitAst((SAst*)block, AstTypeId_StatBlock, ((SAst*)ast)->Pos);
+ ((SAstStat*)block)->AsmTop = NULL;
+ ((SAstStat*)block)->AsmBottom = NULL;
+ ((SAstStat*)block)->PosRowBottom = -1;
+ ((SAst*)block)->AnalyzedCache = (SAst*)block;
+ ((SAst*)block)->Name = L"$";
+ ((SAstStatBreakable*)block)->BlockVar = NULL;
+ ((SAstStatBreakable*)block)->BreakPoint = NULL;
+ block->Stats = ListNew();
+ {
+ SAstExpr* lhs = RebuildExpr(expr->Children[0], False);
+ if (lhs == NULL)
+ return NULL;
+ if (((SAst*)lhs)->TypeId == AstTypeId_ExprDot)
+ ((SAstExprDot*)lhs)->Var = CacheSubExpr(block->Stats, ((SAstExprDot*)lhs)->Var, ((SAst*)ast)->Pos);
+ else if (((SAst*)lhs)->TypeId == AstTypeId_ExprArray)
+ {
+ ((SAstExprArray*)lhs)->Var = CacheSubExpr(block->Stats, ((SAstExprArray*)lhs)->Var, ((SAst*)ast)->Pos);
+ ((SAstExprArray*)lhs)->Idx = CacheSubExpr(block->Stats, ((SAstExprArray*)lhs)->Idx, ((SAst*)ast)->Pos);
+ }
+ SAstExpr2* expr_assign = (SAstExpr2*)Alloc(sizeof(SAstExpr2));
+ InitAstExpr((SAstExpr*)expr_assign, AstTypeId_Expr2, ((SAst*)ast)->Pos);
+ expr_assign->Kind = AstExpr2Kind_Assign;
+ expr_assign->Children[0] = lhs;
+ {
+ SAstExpr2* expr_ope = (SAstExpr2*)Alloc(sizeof(SAstExpr2));
+ InitAst((SAst*)expr_ope, AstTypeId_Expr2, ((SAst*)ast)->Pos);
+ expr_ope->Kind = kind;
+ expr_ope->Children[0] = lhs;
+ expr_ope->Children[1] = expr->Children[1];
+ expr_assign->Children[1] = (SAstExpr*)expr_ope;
+ }
+ ast->Expr = RebuildExpr((SAstExpr*)expr_assign, True);
+ ListAdd(block->Stats, ast);
+ }
+ return (SAstStat*)block;
+ }
+ }
+ }
ast->Expr = RebuildExpr(ast->Expr, True);
if (ast->Expr == NULL)
return NULL;
@@ -2183,7 +2411,7 @@ static SAstType* RebuildType(SAstType* ast, SAstAlias* parent_alias)
((SAstTypeDict*)ast)->ItemTypeValue = RebuildType(((SAstTypeDict*)ast)->ItemTypeValue, parent_alias);
break;
default:
- ASSERT(type == AstTypeId_TypeBit || type == AstTypeId_TypePrim || type == AstTypeId_TypeNull);
+ ASSERT(type == AstTypeId_Ast /* Error */ || type == AstTypeId_TypeBit || type == AstTypeId_TypePrim || type == AstTypeId_TypeNull);
break;
}
}
@@ -2196,6 +2424,7 @@ static SAstExpr* RebuildExpr(SAstExpr* ast, Bool nullable)
return NULL;
switch (((SAst*)ast)->TypeId)
{
+ case AstTypeId_Ast: return NULL;
case AstTypeId_Expr1: ast = RebuildExpr1((SAstExpr1*)ast); break;
case AstTypeId_Expr2: ast = RebuildExpr2((SAstExpr2*)ast); break;
case AstTypeId_Expr3: ast = RebuildExpr3((SAstExpr3*)ast); break;
@@ -2292,7 +2521,16 @@ static SAstExpr* RebuildExpr1(SAstExpr1* ast)
}
break;
case AstExpr1Kind_Copy:
- if (((SAst*)ast->Child->Type)->TypeId == AstTypeId_TypeArray || ((SAst*)ast->Child->Type)->TypeId == AstTypeId_TypeGen || ((SAst*)ast->Child->Type)->TypeId == AstTypeId_TypeDict || IsClass(ast->Child->Type))
+ if (IsClass(ast->Child->Type))
+ {
+ if (((SAstClass*)((SAst*)ast->Child->Type)->RefItem)->IndirectCreation)
+ {
+ Err(L"EA0066", ((SAst*)ast)->Pos, ((SAst*)ast->Child->Type)->RefItem->Name);
+ return NULL;
+ }
+ ((SAstExpr*)ast)->Type = ast->Child->Type;
+ }
+ else if (((SAst*)ast->Child->Type)->TypeId == AstTypeId_TypeArray || ((SAst*)ast->Child->Type)->TypeId == AstTypeId_TypeGen || ((SAst*)ast->Child->Type)->TypeId == AstTypeId_TypeDict)
((SAstExpr*)ast)->Type = ast->Child->Type;
break;
case AstExpr1Kind_Len:
@@ -2322,37 +2560,6 @@ static SAstExpr* RebuildExpr2(SAstExpr2* ast)
if (((SAst*)ast)->AnalyzedCache != NULL)
return (SAstExpr*)((SAst*)ast)->AnalyzedCache;
((SAst*)ast)->AnalyzedCache = (SAst*)ast;
- // Replace all assignment operators that are not '::' with '::'
- {
- EAstExpr2Kind kind = AstExpr2Kind_Assign;
- switch (ast->Kind)
- {
- case AstExpr2Kind_AssignAdd: kind = AstExpr2Kind_Add; break;
- case AstExpr2Kind_AssignSub: kind = AstExpr2Kind_Sub; break;
- case AstExpr2Kind_AssignMul: kind = AstExpr2Kind_Mul; break;
- case AstExpr2Kind_AssignDiv: kind = AstExpr2Kind_Div; break;
- case AstExpr2Kind_AssignMod: kind = AstExpr2Kind_Mod; break;
- case AstExpr2Kind_AssignPow: kind = AstExpr2Kind_Pow; break;
- case AstExpr2Kind_AssignCat: kind = AstExpr2Kind_Cat; break;
- }
- if (kind != AstExpr2Kind_Assign)
- {
- SAstExpr2* expr_assign = (SAstExpr2*)Alloc(sizeof(SAstExpr2));
- InitAstExpr((SAstExpr*)expr_assign, AstTypeId_Expr2, ((SAst*)ast)->Pos);
- expr_assign->Kind = AstExpr2Kind_Assign;
- expr_assign->Children[0] = ast->Children[0];
- {
- SAstExpr2* expr_ope = (SAstExpr2*)Alloc(sizeof(SAstExpr2));
- InitAst((SAst*)expr_ope, AstTypeId_Expr2, ((SAst*)ast)->Pos);
- expr_ope->Kind = kind;
- expr_ope->Children[0] = ast->Children[0];
- expr_ope->Children[1] = ast->Children[1];
- expr_assign->Children[1] = (SAstExpr*)expr_ope;
- }
- ((SAst*)ast)->AnalyzedCache = (SAst*)RebuildExpr((SAstExpr*)expr_assign, True);
- return (SAstExpr*)((SAst*)ast)->AnalyzedCache;
- }
- }
ast->Children[0] = RebuildExpr(ast->Children[0], False);
if (ast->Children[0] == NULL)
return NULL;
@@ -2798,7 +3005,6 @@ static SAstExpr* RebuildExpr2(SAstExpr2* ast)
}
break;
default:
- ASSERT(False);
break;
}
if (!correct)
@@ -2852,7 +3058,7 @@ static SAstExpr* RebuildExpr3(SAstExpr3* ast)
}
else if (((SAst*)ast->Children[2]->Type)->TypeId == AstTypeId_TypeEnumElement)
RebuildEnumElement(ast->Children[2], ast->Children[1]->Type);
- ((SAstExpr*)ast)->Type = ast->Children[1]->Type;
+ ((SAstExpr*)ast)->Type = ((SAst*)ast->Children[1]->Type)->TypeId == AstTypeId_TypeNull ? ast->Children[2]->Type : ast->Children[1]->Type;
((SAstExpr*)ast)->VarKind = AstExprVarKind_Value;
return (SAstExpr*)ast;
}
@@ -2865,7 +3071,15 @@ static SAstExpr* RebuildExprNew(SAstExprNew* ast)
ast->ItemType = RebuildType(ast->ItemType, NULL);
if (ast->ItemType == NULL)
return NULL;
- if (!(((SAst*)ast->ItemType)->TypeId == AstTypeId_TypeGen || ((SAst*)ast->ItemType)->TypeId == AstTypeId_TypeDict || IsClass(ast->ItemType)))
+ if (IsClass(ast->ItemType))
+ {
+ if (!ast->AutoCreated && ((SAstClass*)((SAst*)ast->ItemType)->RefItem)->IndirectCreation)
+ {
+ Err(L"EA0066", ((SAst*)ast)->Pos, ((SAst*)ast->ItemType)->RefItem->Name);
+ return NULL;
+ }
+ }
+ else if (!(((SAst*)ast->ItemType)->TypeId == AstTypeId_TypeGen || ((SAst*)ast->ItemType)->TypeId == AstTypeId_TypeDict))
{
Err(L"EA0044", ((SAst*)ast)->Pos);
return NULL;
@@ -3075,6 +3289,14 @@ static SAstExpr* RebuildExprToBin(SAstExprToBin* ast)
Err(L"EA0056", ((SAst*)ast)->Pos);
return NULL;
}
+ if (IsClass(ast->Child->Type))
+ {
+ if (((SAstClass*)((SAst*)ast->Child->Type)->RefItem)->IndirectCreation)
+ {
+ Err(L"EA0066", ((SAst*)ast)->Pos, ((SAst*)ast->Child->Type)->RefItem->Name);
+ return NULL;
+ }
+ }
if (((SAst*)ast->ChildType)->TypeId != AstTypeId_TypeArray || ((SAst*)((SAstTypeArray*)ast->ChildType)->ItemType)->TypeId != AstTypeId_TypeBit || ((SAstTypeBit*)((SAstTypeArray*)ast->ChildType)->ItemType)->Size != 1)
{
Err(L"EA0056", ((SAst*)ast)->Pos);
@@ -3098,6 +3320,14 @@ static SAstExpr* RebuildExprFromBin(SAstExprFromBin* ast)
Err(L"EA0056", ((SAst*)ast)->Pos);
return NULL;
}
+ if (IsClass(ast->ChildType))
+ {
+ if (((SAstClass*)((SAst*)ast->ChildType)->RefItem)->IndirectCreation)
+ {
+ Err(L"EA0066", ((SAst*)ast)->Pos, ((SAst*)ast->ChildType)->RefItem->Name);
+ return NULL;
+ }
+ }
((SAstExpr*)ast)->Type = ast->ChildType;
((SAstExpr*)ast)->VarKind = AstExprVarKind_Value;
ast->Offset = RebuildExpr(ast->Offset, False);
@@ -3123,10 +3353,11 @@ static SAstExpr* RebuildExprCall(SAstExprCall* ast)
SAstExprNew* expr = (SAstExprNew*)Alloc(sizeof(SAstExprNew));
InitAstExpr((SAstExpr*)expr, AstTypeId_ExprNew, ((SAst*)ast)->Pos);
expr->ItemType = type->Ret;
+ expr->AutoCreated = True;
value_type->Arg = RebuildExpr((SAstExpr*)expr, False);
}
value_type->RefVar = False;
- value_type->SkipVar = NULL;
+ value_type->SkipVar = False;
ListIns(ast->Args, ast->Args->Top, value_type);
}
if (((SAst*)ast->Func)->TypeId == AstTypeId_ExprDot && ((SAst*)ast->Func->Type)->TypeId == AstTypeId_TypeFunc)
@@ -3135,7 +3366,7 @@ static SAstExpr* RebuildExprCall(SAstExprCall* ast)
SAstExprCallArg* me = (SAstExprCallArg*)Alloc(sizeof(SAstExprCallArg));
me->Arg = ((SAstExprDot*)ast->Func)->Var;
me->RefVar = False;
- me->SkipVar = NULL;
+ me->SkipVar = False;
ListIns(ast->Args, ast->Args->Top, me);
}
if ((type->FuncAttr & FuncAttr_AnyType) != 0)
@@ -3155,7 +3386,7 @@ static SAstExpr* RebuildExprCall(SAstExprCall* ast)
me_type->Arg = RebuildExpr((SAstExpr*)expr, False);
}
me_type->RefVar = False;
- me_type->SkipVar = NULL;
+ me_type->SkipVar = False;
ListIns(ast->Args, ast->Args->Top->Next, me_type);
}
if ((type->FuncAttr & FuncAttr_TakeKeyValue) != 0)
@@ -3175,7 +3406,7 @@ static SAstExpr* RebuildExprCall(SAstExprCall* ast)
value_type->Arg = RebuildExpr((SAstExpr*)expr, False);
}
value_type->RefVar = False;
- value_type->SkipVar = NULL;
+ value_type->SkipVar = False;
ListIns(ast->Args, ast->Args->Top->Next->Next, value_type);
}
}
@@ -3202,11 +3433,16 @@ static SAstExpr* RebuildExprCall(SAstExprCall* ast)
{
SAstExprCallArg* arg_expr = (SAstExprCallArg*)ptr_expr->Data;
SAstTypeFuncArg* arg_type = (SAstTypeFuncArg*)ptr_type->Data;
- if (arg_expr->SkipVar != NULL)
- arg_expr->SkipVar->Type = arg_type->Arg;
+ if (arg_expr->SkipVar)
+ ((SAstArg*)((SAst*)arg_expr->Arg)->RefItem)->Type = arg_type->Arg;
arg_expr->Arg = RebuildExpr(arg_expr->Arg, False);
if (arg_expr->Arg != NULL)
{
+ if (arg_expr->RefVar && !arg_expr->SkipVar && arg_expr->Arg->VarKind == AstExprVarKind_Value)
+ {
+ Err(L"EA0067", ((SAst*)ast)->Pos, n + 1);
+ return NULL;
+ }
if (arg_expr->RefVar != arg_type->RefVar || !CmpType(arg_expr->Arg->Type, arg_type->Arg))
{
Err(L"EA0048", ((SAst*)ast)->Pos, n + 1, arg_type->RefVar ? L"&" : L"", GetTypeNameNew(arg_type->Arg), arg_expr->RefVar ? L"&" : L"", GetTypeNameNew(arg_expr->Arg->Type));
@@ -3473,6 +3709,15 @@ static SAstExpr* RebuildExprDot(SAstExprDot* ast)
ASSERT(False);
}
break;
+ case 0x000f:
+ if (((SAst*)var_type)->TypeId == AstTypeId_TypeGen && ((SAstTypeGen*)var_type)->Kind == AstTypeGenKind_List)
+ correct = True;
+ else if (((SAst*)var_type)->TypeId == AstTypeId_TypeDict)
+ {
+ member = L"delDict";
+ correct = True;
+ }
+ break;
}
if (correct)
{
diff --git a/src/compiler/asm.c b/src/compiler/asm.c
index b56777f0..4c43b242 100644
--- a/src/compiler/asm.c
+++ b/src/compiler/asm.c
@@ -143,6 +143,11 @@ SAsmLabel* AsmLabel(void)
SAsmLabel* asm_ = (SAsmLabel*)Alloc(sizeof(SAsmLabel));
((SAsm*)asm_)->TypeId = AsmTypeId_Label;
((SAsm*)asm_)->Addr = NewAddr();
+#if defined(_DEBUG)
+ static int cnt = 0;
+ asm_->Cnt = cnt;
+ cnt++;
+#endif
return asm_;
}
@@ -1231,7 +1236,11 @@ void Dump2(const Char* path, const SList* asms)
switch (asm_->TypeId)
{
case AsmTypeId_Label:
+#if defined(_DEBUG)
+ fwprintf(file_ptr, L"%08XH: (label=%d)\n", (U32)(U64)asm_->Addr, ((SAsmLabel*)asm_)->Cnt);
+#else
fwprintf(file_ptr, L"%08XH:\n", (U32)(U64)asm_->Addr);
+#endif
ptr = ptr->Next;
continue;
case AsmTypeId_Machine:
diff --git a/src/compiler/asm.h b/src/compiler/asm.h
index 7b288283..0241d1fd 100644
--- a/src/compiler/asm.h
+++ b/src/compiler/asm.h
@@ -187,6 +187,9 @@ typedef struct SAsm
typedef struct SAsmLabel
{
SAsm Asm;
+#if defined(_DEBUG)
+ int Cnt;
+#endif
} SAsmLabel;
typedef struct SAsmMachine
diff --git a/src/compiler/assemble.c b/src/compiler/assemble.c
index 05ce411b..90052761 100644
--- a/src/compiler/assemble.c
+++ b/src/compiler/assemble.c
@@ -131,6 +131,7 @@ static int SetTypeIdRecursion(U8* ptr, int idx, const SAstType* type);
static void SetTypeIdForFromBin(EReg reg, const SAstType* type);
static void SetTypeIdForFromBinRecursion(int* idx_type, U8* data_type, int* idx_class, S64** data_class, const SAstType* type);
static void ExpandMe(SAstExprDot* dot, int reg_i);
+static void SetStatAsm(SAstStat* ast, SListNode* asms_top, SListNode* asms_bottom);
static void AssembleFunc(SAstFunc* ast, Bool entry);
static void AssembleStats(SList* asts);
static void AssembleIf(SAstStatIf* ast);
@@ -199,6 +200,7 @@ void Assemble(SPackAsm* pack_asm, const SAstFunc* entry, const SOption* option,
((SAst*)func)->AnalyzedCache = (SAst*)func;
((SAstFunc*)func)->AddrTop = NewAddr();
((SAstFunc*)func)->AddrBottom = -1;
+ ((SAstFunc*)func)->PosRowBottom = -1;
((SAstFunc*)func)->DllName = NULL;
((SAstFunc*)func)->DllFuncName = NULL;
((SAstFunc*)func)->FuncAttr = FuncAttr_None;
@@ -933,6 +935,7 @@ static void GcDec(int reg_i, int reg_f, const SAstType* type)
ListAdd(PackAsm->Asms, AsmJE(ValImm(4, RefValueAddr(((SAsm*)lbl1)->Addr, True))));
ListAdd(PackAsm->Asms, AsmDEC(ValMemS(8, ValReg(8, RegI[reg_i]), NULL, 0x00)));
#if defined(_DEBUG)
+ /*
{
// Since reference counters rarely exceeds 0x10, it is regarded as memory corruption.
SAsmLabel* lbl2 = AsmLabel();
@@ -941,6 +944,7 @@ static void GcDec(int reg_i, int reg_f, const SAstType* type)
ListAdd(PackAsm->Asms, AsmINT(ValImmU(8, 0x03)));
ListAdd(PackAsm->Asms, lbl2);
}
+ */
#endif
ListAdd(PackAsm->Asms, AsmCMP(ValMemS(8, ValReg(8, RegI[reg_i]), NULL, 0x00), ValImmU(8, 0x00)));
ListAdd(PackAsm->Asms, AsmJNE(ValImm(4, RefValueAddr(((SAsm*)lbl1)->Addr, True))));
@@ -1036,7 +1040,7 @@ static void ChkOverflow(void)
{
SAsmLabel* lbl1 = AsmLabel();
ListAdd(PackAsm->Asms, AsmJNO(ValImm(4, RefValueAddr(((SAsm*)lbl1)->Addr, True))));
- RaiseExcpt(0xe9170003);
+ RaiseExcpt(EXCPT_DBG_INT_OVERFLOW);
ListAdd(PackAsm->Asms, lbl1);
}
}
@@ -1551,6 +1555,19 @@ static void ExpandMe(SAstExprDot* dot, int reg_i)
ListAdd(PackAsm->Asms, AsmADD(ValReg(8, RegI[reg_i]), ValMemS(8, ValReg(8, RegI[reg_i]), NULL, 0x00)));
}
+static void SetStatAsm(SAstStat* ast, SListNode* asms_top, SListNode* asms_bottom)
+{
+ if (asms_top == NULL || asms_top->Next == NULL)
+ {
+ if (PackAsm->Asms->Top != NULL)
+ ast->AsmTop = (SAsm*)PackAsm->Asms->Top->Data;
+ }
+ else
+ ast->AsmTop = (SAsm*)asms_top->Next->Data;
+ if (asms_bottom != NULL)
+ ast->AsmBottom = (SAsm*)asms_bottom->Data;
+}
+
static void AssembleFunc(SAstFunc* ast, Bool entry)
{
ASSERT(((SAst*)ast)->AnalyzedCache != NULL);
@@ -1602,7 +1619,7 @@ static void AssembleFunc(SAstFunc* ast, Bool entry)
}
}
else
- ListAdd(PackAsm->Asms, AsmSUB(ValReg(4, Reg_SP), ValImm(4, RefValueAddr(var_size, False))));
+ ListAdd(PackAsm->Asms, AsmSUB(ValReg(8, Reg_SP), ValImm(4, RefValueAddr(var_size, False))));
ListAdd(PackAsm->Asms, table->PostPrologue);
if (((SAst*)ast)->TypeId != AstTypeId_FuncRaw)
{
@@ -1877,6 +1894,7 @@ static void AssembleFunc(SAstFunc* ast, Bool entry)
((SAst*)func)->AnalyzedCache = (SAst*)func;
((SAstFunc*)func)->AddrTop = NewAddr();
((SAstFunc*)func)->AddrBottom = -1;
+ ((SAstFunc*)func)->PosRowBottom = -1;
((SAstFunc*)func)->DllName = NULL;
((SAstFunc*)func)->DllFuncName = NULL;
((SAstFunc*)func)->FuncAttr = FuncAttr_None;
@@ -2014,6 +2032,7 @@ static void AssembleStats(SList* asts)
while (ptr != NULL)
{
SAstStat* ast = (SAstStat*)ptr->Data;
+ SListNode* asms_bottom = PackAsm->Asms->Bottom;
switch (((SAst*)ast)->TypeId)
{
case AstTypeId_StatIf: AssembleIf((SAstStatIf*)ast); break;
@@ -2032,6 +2051,8 @@ static void AssembleStats(SList* asts)
ASSERT(False);
break;
}
+ if (((SAst*)ast)->TypeId != AstTypeId_StatBlock)
+ SetStatAsm(ast, asms_bottom, PackAsm->Asms->Bottom);
ptr = ptr->Next;
}
}
@@ -2444,6 +2465,7 @@ static void AssembleTry(SAstStatTry* ast)
((SAst*)func)->AnalyzedCache = (SAst*)func;
((SAstFunc*)func)->AddrTop = NewAddr();
((SAstFunc*)func)->AddrBottom = -1;
+ ((SAstFunc*)func)->PosRowBottom = -1;
((SAstFunc*)func)->DllName = NULL;
((SAstFunc*)func)->DllFuncName = NULL;
((SAstFunc*)func)->FuncAttr = FuncAttr_None;
@@ -2531,6 +2553,7 @@ static void AssembleTry(SAstStatTry* ast)
((SAst*)func)->AnalyzedCache = (SAst*)func;
((SAstFunc*)func)->AddrTop = NewAddr();
((SAstFunc*)func)->AddrBottom = -1;
+ ((SAstFunc*)func)->PosRowBottom = -1;
((SAstFunc*)func)->DllName = NULL;
((SAstFunc*)func)->DllFuncName = NULL;
((SAstFunc*)func)->FuncAttr = FuncAttr_None;
@@ -2565,10 +2588,12 @@ static void AssembleThrow(SAstStatThrow* ast)
static void AssembleBlock(SAstStatBlock* ast)
{
ASSERT(((SAst*)ast)->AnalyzedCache != NULL);
+ SListNode* asms_bottom = PackAsm->Asms->Bottom;
AssembleStats(ast->Stats);
SAsmLabel* break_point = ((SAstStatBreakable*)ast)->BreakPoint;
if (break_point != NULL)
ListAdd(PackAsm->Asms, break_point);
+ SetStatAsm((SAstStat*)ast, asms_bottom, PackAsm->Asms->Bottom);
}
static void AssembleRet(SAstStatRet* ast)
@@ -2609,7 +2634,7 @@ static void AssembleAssert(SAstStatAssert* ast)
ToValue(ast->Cond, 0, 0);
ListAdd(PackAsm->Asms, AsmCMP(ValReg(1, RegI[0]), ValImmU(1, 0x00)));
ListAdd(PackAsm->Asms, AsmJNE(ValImm(4, RefValueAddr(((SAsm*)lbl1)->Addr, True))));
- ListAdd(PackAsm->Asms, AsmMOV(ValReg(4, Reg_CX), ValImmU(4, 0xe9170000)));
+ ListAdd(PackAsm->Asms, AsmMOV(ValReg(4, Reg_CX), ValImmU(4, EXCPT_DBG_ASSERT_FAILED)));
ListAdd(PackAsm->Asms, AsmXOR(ValReg(4, Reg_DX), ValReg(4, Reg_DX)));
ListAdd(PackAsm->Asms, AsmXOR(ValReg(4, Reg_R8), ValReg(4, Reg_R8)));
ListAdd(PackAsm->Asms, AsmXOR(ValReg(4, Reg_R9), ValReg(4, Reg_R9)));
@@ -3412,7 +3437,10 @@ static void AssembleExprAs(SAstExprAs* ast, int reg_i, int reg_f)
SAsmLabel* lbl1 = AsmLabel();
SAsmLabel* lbl2 = AsmLabel();
SAsmLabel* lbl3 = AsmLabel();
+ SAsmLabel* lbl4 = AsmLabel();
ASSERT(IsClass(t1));
+ ListAdd(PackAsm->Asms, AsmCMP(ValReg(8, RegI[reg_i]), ValImmU(8, 0x00)));
+ ListAdd(PackAsm->Asms, AsmJE(ValImm(4, RefValueAddr(((SAsm*)lbl4)->Addr, True))));
ListAdd(PackAsm->Asms, AsmMOV(ValReg(8, Reg_SI), ValReg(8, RegI[reg_i])));
ListAdd(PackAsm->Asms, AsmMOV(ValReg(8, RegI[reg_i]), ValMemS(8, ValReg(8, RegI[reg_i]), NULL, 0x08)));
ListAdd(PackAsm->Asms, lbl1);
@@ -3428,9 +3456,10 @@ static void AssembleExprAs(SAstExprAs* ast, int reg_i, int reg_f)
ListAdd(PackAsm->Asms, AsmADD(ValReg(8, RegI[reg_i]), ValReg(8, Reg_DI)));
ListAdd(PackAsm->Asms, AsmJMP(ValImm(4, RefValueAddr(((SAsm*)lbl1)->Addr, True))));
ListAdd(PackAsm->Asms, lbl2);
- RaiseExcpt(0xe9170001);
+ RaiseExcpt(EXCPT_CLASS_CAST_FAILED);
ListAdd(PackAsm->Asms, lbl3);
ListAdd(PackAsm->Asms, AsmMOV(ValReg(8, RegI[reg_i]), ValReg(8, Reg_SI)));
+ ListAdd(PackAsm->Asms, lbl4);
}
}
break;
@@ -3566,7 +3595,7 @@ static void AssembleExprCall(SAstExprCall* ast, int reg_i, int reg_f)
{
ToRef(arg->Arg, RegI[0], RegI[0]);
tmp_args[idx] = MakeTmpVar(8, NULL);
- if (arg->SkipVar != NULL)
+ if (arg->SkipVar)
{
int size = GetSize(arg->Arg->Type);
ListAdd(PackAsm->Asms, AsmMOV(ValMemS(size, ValReg(8, RegI[0]), NULL, 0x00), ValImmU(size, 0x00)));
@@ -3703,7 +3732,7 @@ static void AssembleExprArray(SAstExprArray* ast, int reg_i, int reg_f)
#if defined(_DEBUG)
ListAdd(PackAsm->Asms, AsmINT(ValImmU(8, 0x03)));
#endif
- RaiseExcpt(0xe9170002);
+ RaiseExcpt(EXCPT_DBG_ARRAY_IDX_OUT_OF_RANGE);
ListAdd(PackAsm->Asms, lbl2);
}
ASSERT(((SAst*)ast->Var->Type)->TypeId == AstTypeId_TypeArray);
@@ -3870,6 +3899,7 @@ static void AssembleExprRef(SAstExpr* ast, int reg_i, int reg_f)
ASSERT(ast2->Name != NULL && wcscmp(ast2->Name, L"$") != 0);
{
S64* addr = AddWritableData(NewStr(NULL, L"%s@%s", ast2->Pos->SrcName, ast2->Name), size);
+ ((SAstArg*)ast2)->Addr = addr;
ListAdd(PackAsm->Asms, AsmLEA(ValReg(8, RegI[reg_i]), ValRIP(8, RefValueAddr(addr, True))));
}
break;
diff --git a/src/compiler/ast.c b/src/compiler/ast.c
index ac87b391..be56f808 100644
--- a/src/compiler/ast.c
+++ b/src/compiler/ast.c
@@ -120,7 +120,7 @@ Bool IsRef(const SAstType* type)
Bool IsNullable(const SAstType* type)
{
EAstTypeId type_id = ((SAst*)type)->TypeId;
- return (type_id | AstTypeId_TypeNullable) != 0 && !(((SAst*)type)->TypeId == AstTypeId_TypeUser && ((SAst*)type)->RefItem->TypeId == AstTypeId_Enum);
+ return (type_id & AstTypeId_TypeNullable) != 0 && !(((SAst*)type)->TypeId == AstTypeId_TypeUser && ((SAst*)type)->RefItem->TypeId == AstTypeId_Enum);
}
Bool IsClass(const SAstType* type)
diff --git a/src/compiler/ast.h b/src/compiler/ast.h
index ac65296d..4ce8415d 100644
--- a/src/compiler/ast.h
+++ b/src/compiler/ast.h
@@ -125,6 +125,7 @@ typedef struct SAstFunc
SAst Ast;
S64* AddrTop;
S64 AddrBottom;
+ S64 PosRowBottom;
const Char* DllName;
const Char* DllFuncName;
EFuncAttr FuncAttr;
@@ -176,6 +177,7 @@ typedef struct SAstClass
int VarSize;
int FuncSize;
SList* Items;
+ Bool IndirectCreation;
} SAstClass;
typedef struct SAstEnum
@@ -207,6 +209,9 @@ typedef struct SAstArg
typedef struct SAstStat
{
SAst Ast;
+ SAsm* AsmTop;
+ SAsm* AsmBottom;
+ S64 PosRowBottom;
} SAstStat;
typedef struct SAstStatBreakable
@@ -516,6 +521,7 @@ typedef struct SAstExprNew
{
SAstExpr AstExpr;
SAstType* ItemType;
+ Bool AutoCreated;
} SAstExprNew;
typedef struct SAstExprNewArray
@@ -559,7 +565,7 @@ typedef struct SAstExprCallArg
{
SAstExpr* Arg;
Bool RefVar;
- SAstArg* SkipVar;
+ Bool SkipVar;
} SAstExprCallArg;
typedef struct SAstExprCall
diff --git a/src/compiler/deploy.c b/src/compiler/deploy.c
index 75c13ced..bd16fdee 100644
--- a/src/compiler/deploy.c
+++ b/src/compiler/deploy.c
@@ -6,7 +6,7 @@
static const void* CopyDlls(const Char* key, const void* value, void* param);
static void CopyKuinFile(const Char* name, const SOption* option);
-void Deploy(U64 app_code, const SOption* option, SDict* dlls)
+void Deploy(U64 app_code, const SOption* option, SDict* dlls, const void* related_files)
{
#if defined(_DEBUG)
// When doing tests, the program uses debugging Dlls so do not copy these.
@@ -25,10 +25,33 @@ void Deploy(U64 app_code, const SOption* option, SDict* dlls)
}
DictForEach(dlls, CopyDlls, (void*)option);
#endif
+
+ if (related_files != NULL)
+ {
+ const void* cur = *(const void**)((const U8*)related_files + 0x10);
+ while (cur != NULL)
+ {
+ const Char* path = (const Char*)((const U8*)*(const void**)((const U8*)cur + 0x10) + 0x10);
+ const Char* name = wcsrchr(path, L'/');
+ if (name != NULL)
+ {
+ Char dst[KUIN_MAX_PATH + 1];
+ wcscpy(dst, option->OutputDir);
+ wcscat(dst, L"data/");
+ wcscat(dst, name);
+ if (CopyFile(path, dst, FALSE) == 0)
+ Err(L"EK0013", NULL, path, dst);
+ }
+ cur = *(const void**)((const U8*)cur + 0x08);
+ }
+ }
}
static const void* CopyDlls(const Char* key, const void* value, void* param)
{
+ size_t key_len = wcslen(key);
+ if (!(key_len > 4 && key[key_len - 4] == L'.' && key[key_len - 3] == L'k' && key[key_len - 2] == L'n' && key[key_len - 1] == L'd'))
+ return value;
const SOption* option = (SOption*)param;
{
Char src[KUIN_MAX_PATH + 1];
diff --git a/src/compiler/deploy.h b/src/compiler/deploy.h
index 042682d7..99114497 100644
--- a/src/compiler/deploy.h
+++ b/src/compiler/deploy.h
@@ -5,4 +5,4 @@
#include "dict.h"
#include "option.h"
-void Deploy(U64 app_code, const SOption* option, SDict* dlls);
+void Deploy(U64 app_code, const SOption* option, SDict* dlls, const void* related_files);
diff --git a/src/compiler/log.c b/src/compiler/log.c
index c46aeebe..876e9c2f 100644
--- a/src/compiler/log.c
+++ b/src/compiler/log.c
@@ -3,7 +3,7 @@
#include "mem.h"
#include "util.h"
-#define MSG_NUM (447 / 3)
+#define MSG_NUM (453 / 3)
#define MSG_MAX (128)
#define LANG_NUM (2)
diff --git a/src/compiler/main.c b/src/compiler/main.c
index 1bbc4339..02607e9c 100644
--- a/src/compiler/main.c
+++ b/src/compiler/main.c
@@ -25,7 +25,7 @@
#pragma comment(lib, "DbgHelp.lib")
-#define MSG_NUM (57 / 3)
+#define MSG_NUM (60 / 3)
#define FUNC_NAME_MAX (128)
#define MSG_MAX (128)
#define LANG_NUM (2)
@@ -92,6 +92,12 @@ typedef struct SKeywordListCallbackParam
EAstTypeId ParentType;
} SKeywordListCallbackParam;
+typedef struct SBreakPointAddr
+{
+ U64 Addr;
+ U8 Ope;
+} SBreakPointAddr;
+
static const void*(*FuncGetSrc)(const U8*) = NULL;
static void(*FuncLog)(const void*, S64, S64) = NULL;
static const void* Src = NULL;
@@ -105,6 +111,11 @@ static Char HintBuf[HINT_MSG_NUM][0x08 + HINT_MSG_MAX + 1];
static Char HintSrcBuf[0x08 + KUIN_MAX_PATH + 1];
static int KeywordListNum = 0;
static const SKeywordListItem** KeywordList = NULL;
+static S64 GlobalHeapCnt = 0;
+static S64 BreakPointNum = 0;
+static SPos* BreakPointPoses = NULL;
+static int BreakPointAddrNum = 0;
+static SBreakPointAddr* BreakPointAddrs = NULL;
// Assembly functions.
void* Call0Asm(void* func);
@@ -114,7 +125,7 @@ void* Call3Asm(void* arg1, void* arg2, void* arg3, void* func);
static void LoadExcptMsg(S64 lang);
static void DecSrc(void);
-static Bool Build(FILE*(*func_wfopen)(const Char*, const Char*), int(*func_fclose)(FILE*), U16(*func_fgetwc)(FILE*), size_t(*func_size)(FILE*), const Char* path, const Char* sys_dir, const Char* output, const Char* icon, Bool rls, const Char* env, void(*func_log)(const Char* code, const Char* msg, const Char* src, int row, int col), S64 lang, S64 app_code, Bool not_deploy);
+static Bool Build(FILE*(*func_wfopen)(const Char*, const Char*), int(*func_fclose)(FILE*), U16(*func_fgetwc)(FILE*), size_t(*func_size)(FILE*), const Char* path, const Char* sys_dir, const Char* output, const Char* icon, const void* related_files, Bool rls, const Char* env, void(*func_log)(const Char* code, const Char* msg, const Char* src, int row, int col), S64 lang, S64 app_code, Bool not_deploy);
static FILE* BuildMemWfopen(const Char* file_name, const Char* mode);
static int BuildMemFclose(FILE* file_ptr);
static U16 BuildMemFgetwc(FILE* file_ptr);
@@ -123,6 +134,10 @@ static void BuildMemLog(const Char* code, const Char* msg, const Char* src, int
static size_t BuildFileGetSize(FILE* file_ptr);
static SPos* AddrToPos(U64 addr, Char* name);
static const void* AddrToPosCallback(U64 key, const void* value, void* param);
+static SPos* AddrToPosCallbackRecursion(const SList* stats, U64 addr);
+static U64 PosToAddr(const SPos* pos);
+static const void* PosToAddrCallback(U64 key, const void* value, void* param);
+static U64 PosToAddrCallbackRecursion(const SList* stats, const SPos* target_pos);
static SArchiveFileList* SearchFiles(int* len, const Char* src);
static Bool SearchFilesRecursion(int* len, size_t src_base_len, const Char* src, SArchiveFileList** top, SArchiveFileList** bottom);
static U8 GetKey(U64 key, U8 data, U64 pos);
@@ -130,6 +145,9 @@ static void MakeKeywordList(SDict* asts);
static const void* MakeKeywordListCallback(const Char* key, const void* value, void* param);
static void MakeKeywordListRecursion(SKeywordListCallbackParam* param, const SAst* ast);
static int CmpKeywordListItem(const void* a, const void* b);
+static void FreeBreakPoints(void);
+static void SetBreakPointOpes(HANDLE process_handle);
+static void UnsetBreakPointOpes(HANDLE process_handle);
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
{
@@ -141,17 +159,28 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
EXPORT void InitCompiler(S64 lang)
{
+ if (!InitEnvVars(GetProcessHeap(), &GlobalHeapCnt, 0, NULL))
+ return;
+
InitAllocator();
if (lang >= 0)
LoadExcptMsg(lang);
+
+ BreakPointNum = 0;
+ BreakPointPoses = NULL;
+ BreakPointAddrs = NULL;
}
EXPORT void FinCompiler(void)
{
+ if (BreakPointAddrs != NULL)
+ FreeMem(BreakPointAddrs);
+ FreeBreakPoints();
+
FinAllocator();
}
-EXPORT Bool BuildMem(const U8* path, const void*(*func_get_src)(const U8*), const U8* sys_dir, const U8* output, const U8* icon, Bool rls, const U8* env, void(*func_log)(const void* args, S64 row, S64 col), S64 lang, S64 app_code)
+EXPORT Bool BuildMem(const U8* path, const void*(*func_get_src)(const U8*), const U8* sys_dir, const U8* output, const U8* icon, const void* related_files, Bool rls, const U8* env, void(*func_log)(const void* args, S64 row, S64 col), S64 lang, S64 app_code)
{
// This function is for the Kuin Editor.
Bool result;
@@ -166,7 +195,7 @@ EXPORT Bool BuildMem(const U8* path, const void*(*func_get_src)(const U8*), cons
if (icon2[0] == L'\0')
icon2 = NULL;
}
- result = Build(BuildMemWfopen, BuildMemFclose, BuildMemFgetwc, BuildMemGetSize, (const Char*)(path + 0x10), sys_dir == NULL ? NULL : (const Char*)(sys_dir + 0x10), output == NULL ? NULL : (const Char*)(output + 0x10), icon2, rls, env == NULL ? NULL : (const Char*)(env + 0x10), BuildMemLog, lang, app_code, False);
+ result = Build(BuildMemWfopen, BuildMemFclose, BuildMemFgetwc, BuildMemGetSize, (const Char*)(path + 0x10), sys_dir == NULL ? NULL : (const Char*)(sys_dir + 0x10), output == NULL ? NULL : (const Char*)(output + 0x10), icon2, related_files, rls, env == NULL ? NULL : (const Char*)(env + 0x10), BuildMemLog, lang, app_code, False);
FuncGetSrc = NULL;
FuncLog = NULL;
DecSrc();
@@ -176,12 +205,12 @@ EXPORT Bool BuildMem(const U8* path, const void*(*func_get_src)(const U8*), cons
return result;
}
-EXPORT Bool BuildFile(const Char* path, const Char* sys_dir, const Char* output, const Char* icon, Bool rls, const Char* env, void(*func_log)(const Char* code, const Char* msg, const Char* src, int row, int col), S64 lang, S64 app_code, Bool not_deploy)
+EXPORT Bool BuildFile(const Char* path, const Char* sys_dir, const Char* output, const Char* icon, const void* related_files, Bool rls, const Char* env, void(*func_log)(const Char* code, const Char* msg, const Char* src, int row, int col), S64 lang, S64 app_code, Bool not_deploy)
{
// This function is for 'kuincl'.
Bool result;
InitAllocator();
- result = Build(_wfopen, fclose, fgetwc, BuildFileGetSize, path, sys_dir, output, icon, rls, env, func_log, lang, app_code, not_deploy);
+ result = Build(_wfopen, fclose, fgetwc, BuildFileGetSize, path, sys_dir, output, icon, related_files, rls, env, func_log, lang, app_code, not_deploy);
FinAllocator();
return result;
}
@@ -252,8 +281,8 @@ EXPORT Bool Interpret2(const U8* path, const void*(*func_get_src)(const U8*), co
EXPORT void Version(S64* major, S64* minor, S64* micro)
{
- *major = 2018;
- *minor = 7;
+ *major = 2019;
+ *minor = 9;
*micro = 17;
}
@@ -264,7 +293,7 @@ EXPORT void ResetMemAllocator(void)
KeywordList = NULL;
}
-EXPORT void GetKeywords(void* src, const U8* src_name, S64 x, S64 y, void* callback)
+EXPORT void* GetKeywords(void* src, const U8* src_name, S64 x, S64 y, void* callback)
{
void* str = *(void**)((U8*)src + 0x10);
// void* comment_level = *(void**)((U8*)src + 0x20);
@@ -276,10 +305,10 @@ EXPORT void GetKeywords(void* src, const U8* src_name, S64 x, S64 y, void* callb
const Char* str3 = (Char*)((U8*)*str2 + 0x10);
- GetKeywordsRoot(&str3, str3 + x + 1, (const Char*)(src_name + 0x10), (int)x, (int)y, flags2, callback, KeywordListNum, (const void*)KeywordList);
+ return GetKeywordsRoot(&str3, str3 + x + 1, (const Char*)(src_name + 0x10), (int)x, (int)y, flags2, callback, KeywordListNum, (const void*)KeywordList);
}
-EXPORT Bool RunDbg(const U8* path, const U8* cmd_line, void* idle_func, void* event_func)
+EXPORT Bool RunDbg(const U8* path, const U8* cmd_line, void* idle_func, void* event_func, void* break_points_func, void* break_func, void* dbg_func)
{
const Char* path2 = (const Char*)(path + 0x10);
Char cur_dir[KUIN_MAX_PATH + 1];
@@ -314,172 +343,210 @@ EXPORT Bool RunDbg(const U8* path, const U8* cmd_line, void* idle_func, void* ev
free(cmd_line_buf);
{
- DEBUG_EVENT debug_event;
+ DEBUG_EVENT debug_event = { 0 };
Bool end = False;
DbgStartAddr = 0;
ResumeThread(process_info.hThread);
- S64 excpt_last_occurred = _time64(NULL) - 2;
- Char dbg_code = L'\0';
while (!end)
{
DWORD continue_status = DBG_EXCEPTION_NOT_HANDLED;
Call0Asm(idle_func);
- WaitForDebugEvent(&debug_event, 0);
+ Sleep(1);
+ for (; ; )
+ {
+ WaitForDebugEvent(&debug_event, 0);
+ if (debug_event.dwProcessId != process_info.dwProcessId)
+ {
+ ContinueDebugEvent(debug_event.dwProcessId, debug_event.dwThreadId, DBG_EXCEPTION_NOT_HANDLED);
+ continue;
+ }
+ break;
+ }
switch (debug_event.dwDebugEventCode)
{
case CREATE_PROCESS_DEBUG_EVENT:
DbgStartAddr = (U64)debug_event.u.CreateProcessInfo.lpBaseOfImage;
- CloseHandle(debug_event.u.CreateProcessInfo.hFile);
+ if (debug_event.u.CreateProcessInfo.hFile != 0)
+ CloseHandle(debug_event.u.CreateProcessInfo.hFile);
+ Call0Asm(break_points_func);
+ SetBreakPointOpes(process_info.hProcess);
break;
case LOAD_DLL_DEBUG_EVENT:
- CloseHandle(debug_event.u.LoadDll.hFile);
+ if (debug_event.u.LoadDll.hFile != 0)
+ {
+ __try
+ {
+ CloseHandle(debug_event.u.LoadDll.hFile);
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER)
+ {
+ // Do nothing.
+ }
+ }
break;
case EXIT_PROCESS_DEBUG_EVENT:
end = True;
break;
case EXCEPTION_DEBUG_EVENT:
- /*
- if (debug_event.u.Exception.ExceptionRecord.ExceptionCode == 0x80000003)
- break;
- */
- if ((debug_event.u.Exception.ExceptionRecord.ExceptionCode & 0xffff0000) != 0xc0000000 && (debug_event.u.Exception.ExceptionRecord.ExceptionCode & 0xffff0000) != 0xe9170000)
- break;
- if (_time64(NULL) - excpt_last_occurred < 2)
- break;
{
- Char str[EXCPT_MSG_MAX + 1];
- size_t len2;
- CONTEXT context;
- STACKFRAME64 stack;
- IMAGEHLP_SYMBOL64 symbol;
- memset(&context, 0, sizeof(context));
- context.ContextFlags = CONTEXT_FULL;
- if (!GetThreadContext(process_info.hThread, &context))
+ const DWORD excpt_code = debug_event.u.Exception.ExceptionRecord.ExceptionCode;
+ if (excpt_code == EXCEPTION_SINGLE_STEP)
+ {
+ CONTEXT context;
+ context.ContextFlags = CONTEXT_CONTROL;
+ GetThreadContext(process_info.hThread, &context);
+ Call0Asm(break_points_func);
+ SetBreakPointOpes(process_info.hProcess);
+ context.EFlags &= ~0x00000100;
+ SetThreadContext(process_info.hThread, &context);
+ continue_status = DBG_CONTINUE;
break;
- memset(&stack, 0, sizeof(stack));
- stack.AddrPC.Offset = context.Rip;
- stack.AddrPC.Mode = AddrModeFlat;
- stack.AddrStack.Offset = context.Rsp;
- stack.AddrStack.Mode = AddrModeFlat;
- stack.AddrFrame.Offset = context.Rbp;
- stack.AddrFrame.Mode = AddrModeFlat;
- SymInitialize(process_info.hProcess, NULL, TRUE);
+ }
+ int break_point_idx = -1;
+ if (excpt_code == EXCEPTION_BREAKPOINT)
{
- DWORD code = debug_event.u.Exception.ExceptionRecord.ExceptionCode;
-#if defined(_DEBUG)
- PVOID addr = debug_event.u.Exception.ExceptionRecord.ExceptionAddress;
-#endif
- const Char* text = ExcptMsgs[0].Msg;
- if (code <= 0x0000ffff)
- text = ExcptMsgs[1].Msg;
- else
+ if (BreakPointAddrs != NULL)
{
- int min = 0;
- int max = MSG_NUM - 1;
- int found = -1;
- while (min <= max)
+ int i;
+ for (i = 0; i < BreakPointAddrNum; i++)
{
- int mid = (min + max) / 2;
- if ((S64)code < ExcptMsgs[mid].Code)
- max = mid - 1;
- else if ((S64)code > ExcptMsgs[mid].Code)
- min = mid + 1;
- else
+ if (BreakPointAddrs[i].Addr != 0 && BreakPointAddrs[i].Addr == (U64)debug_event.u.Exception.ExceptionRecord.ExceptionAddress)
{
- found = mid;
+ break_point_idx = i;
break;
}
}
- if (found != -1)
- text = ExcptMsgs[found].Msg;
}
-#if defined(_DEBUG)
- len2 = swprintf(str, EXCPT_MSG_MAX, L"An exception '0x%08X' occurred at '0x%016I64X'.\r\n\r\n> %s\r\n\r\n", code, (U64)addr, text);
-#else
- len2 = swprintf(str, EXCPT_MSG_MAX, L"An exception '0x%08X' occurred.\r\n\r\n> %s\r\n\r\n", code, text);
-#endif
}
-
- for (; ; )
+ if (break_point_idx == -1 && (excpt_code & 0xffff0000) != 0xc0000000 && (excpt_code & 0xffff0000) != 0xe9170000)
+ break;
+ Call3Asm((void*)0, NULL, NULL, dbg_func);
{
- if (!StackWalk64(IMAGE_FILE_MACHINE_AMD64, process_info.hProcess, process_info.hThread, &stack, &context, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL))
+ Char str_buf[0x08 + EXCPT_MSG_MAX + 1];
+ Char* str = str_buf + 0x08;
+ CONTEXT context;
+ CONTEXT context2;
+ STACKFRAME64 stack;
+ IMAGEHLP_SYMBOL64 symbol;
+ memset(&context, 0, sizeof(context));
+ context.ContextFlags = CONTEXT_FULL;
+ if (!GetThreadContext(process_info.hThread, &context))
break;
-
-#if defined(_DEBUG)
- if (len2 < EXCPT_MSG_MAX)
- len2 += swprintf(str + len2, EXCPT_MSG_MAX - len2, L"0x%016I64X: \t", context.Rip);
-#endif
-
- symbol.SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
- symbol.MaxNameLength = 255;
- DWORD64 displacement;
- if (SymGetSymFromAddr64(process_info.hProcess, (DWORD64)stack.AddrPC.Offset, &displacement, &symbol))
+ context2 = context;
+ memset(&stack, 0, sizeof(stack));
+ stack.AddrPC.Offset = context2.Rip;
+ stack.AddrPC.Mode = AddrModeFlat;
+ stack.AddrStack.Offset = context2.Rsp;
+ stack.AddrStack.Mode = AddrModeFlat;
+ stack.AddrFrame.Offset = context2.Rbp;
+ stack.AddrFrame.Mode = AddrModeFlat;
+ SymInitialize(process_info.hProcess, NULL, TRUE);
{
-#if defined(_DEBUG)
- char name[1024];
- UnDecorateSymbolName(symbol.Name, (PSTR)name, 1024, UNDNAME_COMPLETE);
+ const Char* text = ExcptMsgs[0].Msg;
+ if (excpt_code <= 0x0000ffff)
+ text = ExcptMsgs[1].Msg;
+ else
{
- char* src = name;
- if (len2 < EXCPT_MSG_MAX)
- {
- str[len2] = L'(';
- len2++;
- }
- while (*src != L'\0')
- {
- if (len2 < EXCPT_MSG_MAX)
- str[len2] = (Char)*src;
- len2++;
- src++;
- }
- if (len2 < EXCPT_MSG_MAX)
- {
- str[len2] = L')';
- len2++;
- }
- if (len2 < EXCPT_MSG_MAX)
+ int min = 0;
+ int max = MSG_NUM - 1;
+ int found = -1;
+ while (min <= max)
{
- str[len2] = L'\r';
- len2++;
- }
- if (len2 < EXCPT_MSG_MAX)
- {
- str[len2] = L'\n';
- len2++;
+ int mid = (min + max) / 2;
+ if ((S64)excpt_code < ExcptMsgs[mid].Code)
+ max = mid - 1;
+ else if ((S64)excpt_code > ExcptMsgs[mid].Code)
+ min = mid + 1;
+ else
+ {
+ found = mid;
+ break;
+ }
}
+ if (found != -1)
+ text = ExcptMsgs[found].Msg;
}
-#endif
+ swprintf(str, EXCPT_MSG_MAX, L"%s\nAn exception '0x%08X' occurred.", text, excpt_code);
}
- else
+
+ SPos* excpt_pos = NULL;
+ for (; ; )
{
- Char name[256];
- SPos* pos = AddrToPos((U64)context.Rip, name);
- if (pos != NULL)
+ if (!StackWalk64(IMAGE_FILE_MACHINE_AMD64, process_info.hProcess, process_info.hThread, &stack, &context2, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL))
+ break;
+ symbol.SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
+ symbol.MaxNameLength = 255;
+ DWORD64 displacement;
+ if (SymGetSymFromAddr64(process_info.hProcess, (DWORD64)stack.AddrPC.Offset, &displacement, &symbol))
{
- if (len2 < EXCPT_MSG_MAX)
- len2 += swprintf(str + len2, EXCPT_MSG_MAX - len2, L"%s (%s: %d, %d)\r\n", name, pos->SrcName, pos->Row, pos->Col);
+ /*
+ char name[1024];
+ UnDecorateSymbolName(symbol.Name, (PSTR)name, 1024, UNDNAME_COMPLETE);
+ */
}
else
{
- if (len2 < EXCPT_MSG_MAX)
+ Char name[256];
+ SPos* pos = AddrToPos((U64)context2.Rip, name);
+ if (excpt_pos == NULL)
{
- str[len2] = L'\r';
- len2++;
+ if (wcschr(name, L'@') == NULL)
+ break;
+ else
+ excpt_pos = pos;
}
- if (len2 < EXCPT_MSG_MAX)
+ if (pos != NULL)
{
- str[len2] = L'\n';
- len2++;
+ Char buf[0x08 + 1024];
+ swprintf(buf + 0x08, 1024, L"%s (%s: %d, %d)", name, pos->SrcName, pos->Row, pos->Col);
+ ((S64*)buf)[0] = 2;
+ ((S64*)buf)[1] = (S64)wcslen(buf + 0x08);
+ Call3Asm((void*)2, buf, NULL, dbg_func);
}
}
+ if (stack.AddrPC.Offset == 0)
+ break;
+ }
+ if (excpt_pos != NULL)
+ {
+ GetDbgVars(KeywordListNum, KeywordList, excpt_pos->SrcName, excpt_pos->Row, process_info.hProcess, DbgStartAddr, &context, dbg_func);
+ {
+ void* pos_ptr = NULL;
+ Char pos_name[0x08 + 256];
+ U8 pos_buf[0x28];
+ {
+ size_t pos_name_len = wcslen(excpt_pos->SrcName);
+ ((S64*)pos_name)[0] = 1;
+ ((S64*)pos_name)[1] = (S64)pos_name_len;
+ memcpy((U8*)pos_name + 0x10, excpt_pos->SrcName, sizeof(Char) * (pos_name_len + 1));
+
+ ((S64*)pos_buf)[0] = 2;
+ ((S64*)pos_buf)[1] = 0;
+ ((void**)pos_buf)[2] = pos_name;
+ ((S64*)pos_buf)[3] = excpt_pos->Row;
+ ((S64*)pos_buf)[4] = excpt_pos->Col;
+ pos_ptr = pos_buf;
+ }
+ ((S64*)str_buf)[0] = 2;
+ ((S64*)str_buf)[1] = wcslen(str);
+ Call3Asm((void*)(U64)excpt_code, pos_ptr, str_buf, break_func);
+ }
+ UnsetBreakPointOpes(process_info.hProcess);
+ }
+ if (break_point_idx != -1)
+ {
+ context.Rip--;
+ context.EFlags |= 0x00000100;
+ SetThreadContext(process_info.hThread, &context);
+ continue_status = DBG_CONTINUE;
+ }
+ else
+ {
+ Call0Asm(break_points_func);
+ SetBreakPointOpes(process_info.hProcess);
}
- if (stack.AddrPC.Offset == 0)
- break;
}
- str[len2] = L'\0';
- MessageBox(NULL, str, NULL, MB_ICONEXCLAMATION | MB_SETFOREGROUND);
}
- excpt_last_occurred = _time64(NULL);
break;
case OUTPUT_DEBUG_STRING_EVENT:
{
@@ -511,17 +578,15 @@ EXPORT Bool RunDbg(const U8* path, const U8* cmd_line, void* idle_func, void* ev
((S64*)buf)[1] = (S64)debug_event.u.DebugString.nDebugStringLength - 1;
}
*((S64*)buf) = 2;
- if (((S64*)buf)[1] >= 5)
+ if (((S64*)buf)[1] >= 4)
{
const Char* ptr = (const Char*)((U8*)buf + 0x10);
- if (ptr[0] == L'd' && ptr[1] == L'b' && ptr[2] == L'g' && L'0' <= ptr[3] && ptr[3] <= L'9' && ptr[3] != dbg_code && ptr[4] == L'!')
- {
- dbg_code = ptr[3];
+ if (ptr[0] == L'd' && ptr[1] == L'b' && ptr[2] == L'g' && ptr[3] == L'!')
Call2Asm(0, buf, event_func);
- }
}
free(buf);
}
+ continue_status = DBG_CONTINUE;
break;
}
ContinueDebugEvent(debug_event.dwProcessId, debug_event.dwThreadId, continue_status);
@@ -540,6 +605,65 @@ EXPORT Bool RunDbg(const U8* path, const U8* cmd_line, void* idle_func, void* ev
return True;
}
+EXPORT void SetBreakPoints(const void* break_points)
+{
+ S64 len = ((S64*)break_points)[1];
+ FreeBreakPoints();
+ BreakPointNum = len;
+ BreakPointPoses = (SPos*)AllocMem(sizeof(SPos) * (size_t)len);
+
+ void** ptr = (void**)((U8*)break_points + 0x10);
+ S64 i;
+ for (i = 0; i < len; i++)
+ {
+ Char* src_name = (Char*)((U8*)*(void**)((U8*)ptr[i] + 0x10) + 0x10);
+ int row = (int)*(S64*)((U8*)ptr[i] + 0x18);
+ int col = (int)*(S64*)((U8*)ptr[i] + 0x20);
+ S64 name_len = ((S64*)*(void**)((U8*)ptr[i] + 0x10))[1];
+
+ Bool success = False;
+ for (; ; )
+ {
+ Char name[256];
+ U64 addr;
+ SPos pos;
+ pos.SrcName = src_name;
+ pos.Row = row;
+ pos.Col = col;
+ addr = PosToAddr(&pos);
+ if (addr != 0)
+ {
+ SPos* pos2 = AddrToPos(addr, name);
+ if (pos2 != NULL && wcscmp(pos.SrcName, pos2->SrcName) == 0)
+ {
+ if (pos.Row != pos2->Row)
+ {
+ row = pos2->Row;
+ *(S64*)((U8*)ptr[i] + 0x18) = (S64)pos2->Row;
+ continue;
+ }
+ success = True;
+ }
+ }
+ break;
+ }
+ if (!success)
+ {
+ BreakPointPoses[i].SrcName = L"";
+ BreakPointPoses[i].Row = -1;
+ BreakPointPoses[i].Col = -1;
+ *(S64*)((U8*)ptr[i] + 0x18) = -1;
+ continue;
+ }
+
+ Char* buf = (Char*)AllocMem(sizeof(Char) * (size_t)(name_len + 1));
+ memcpy(buf, src_name, sizeof(Char) * (size_t)(name_len + 1));
+ BreakPointPoses[i].SrcName = buf;
+ BreakPointPoses[i].Row = row;
+ BreakPointPoses[i].Col = col;
+ }
+}
+
EXPORT Bool Archive(const U8* dst, const U8* src, S64 app_code)
{
FILE* file_ptr = _wfopen((const Char*)(dst + 0x10), L"wb");
@@ -690,7 +814,7 @@ static void DecSrc(void)
}
}
-static Bool Build(FILE*(*func_wfopen)(const Char*, const Char*), int(*func_fclose)(FILE*), U16(*func_fgetwc)(FILE*), size_t(*func_size)(FILE*), const Char* path, const Char* sys_dir, const Char* output, const Char* icon, Bool rls, const Char* env, void(*func_log)(const Char* code, const Char* msg, const Char* src, int row, int col), S64 lang, S64 app_code, Bool not_deploy)
+static Bool Build(FILE*(*func_wfopen)(const Char*, const Char*), int(*func_fclose)(FILE*), U16(*func_fgetwc)(FILE*), size_t(*func_size)(FILE*), const Char* path, const Char* sys_dir, const Char* output, const Char* icon, const void* related_files, Bool rls, const Char* env, void(*func_log)(const Char* code, const Char* msg, const Char* src, int row, int col), S64 lang, S64 app_code, Bool not_deploy)
{
SOption option;
SDict* asts;
@@ -726,6 +850,8 @@ static Bool Build(FILE*(*func_wfopen)(const Char*, const Char*), int(*func_fclos
entry = Analyze(asts, &option, &dlls);
if (ErrOccurred())
goto ERR;
+ if (!option.Rls)
+ MakeKeywordList(asts);
Err(L"IK0002", NULL, (double)(timeGetTime() - begin_time) / 1000.0);
Assemble(&PackAsm, entry, &option, dlls, app_code, use_res_flags);
if (ErrOccurred())
@@ -736,7 +862,7 @@ static Bool Build(FILE*(*func_wfopen)(const Char*, const Char*), int(*func_fclos
goto ERR;
Err(L"IK0004", NULL, (double)(timeGetTime() - begin_time) / 1000.0);
if (!option.NotDeploy)
- Deploy(PackAsm.AppCode, &option, dlls);
+ Deploy(PackAsm.AppCode, &option, dlls, related_files);
if (ErrOccurred())
goto ERR;
Err(L"IK0005", NULL, (double)(timeGetTime() - begin_time) / 1000.0);
@@ -867,6 +993,7 @@ static size_t BuildFileGetSize(FILE* file_ptr)
static SPos* AddrToPos(U64 addr, Char* name)
{
+ name[0] = '\0';
SPos* result = NULL;
void* params[3];
params[0] = (void*)&result;
@@ -883,18 +1010,266 @@ static const void* AddrToPosCallback(U64 key, const void* value, void* param)
SPos** result = (SPos**)params[0];
U64 addr = (U64)params[1];
Char* name = (Char*)params[2];
- UNUSED(value);
if ((U64)*func->AddrTop + DbgStartAddr <= addr && addr <= (U64)func->AddrBottom + DbgStartAddr)
{
*result = (SPos*)((SAst*)func)->Pos;
- if (*result != NULL)
- swprintf(name, 255, L"%s@%s", (*result)->SrcName, ((SAst*)func)->Name);
- else
- wcscpy(name, ((SAst*)func)->Name);
+ {
+ SPos* result2 = AddrToPosCallbackRecursion(func->Stats, addr);
+ if (result2 != NULL)
+ {
+ *result = result2;
+ swprintf(name, 255, L"%s@%s", (*result)->SrcName, ((SAst*)func)->Name);
+ }
+ else
+ wcscpy(name, ((SAst*)func)->Name);
+ }
}
return value;
}
+static SPos* AddrToPosCallbackRecursion(const SList* stats, U64 addr)
+{
+ SListNode* ptr = stats->Top;
+ while (ptr != NULL)
+ {
+ SAstStat* stat = (SAstStat*)ptr->Data;
+ SPos* result;
+ if (stat->AsmTop != NULL && stat->AsmBottom != NULL && stat->AsmTop->Addr != NULL && stat->AsmBottom->Addr != NULL && (U64)*stat->AsmTop->Addr + DbgStartAddr <= addr && addr <= (U64)*stat->AsmBottom->Addr + DbgStartAddr)
+ {
+ SListNode* ptr2;
+ switch (((SAst*)stat)->TypeId)
+ {
+ case AstTypeId_StatIf:
+ {
+ SAstStatIf* stat2 = (SAstStatIf*)stat;
+ result = AddrToPosCallbackRecursion(stat2->StatBlock->Stats, addr);
+ if (result != NULL)
+ return result;
+ ptr2 = stat2->ElIfs->Top;
+ while (ptr2 != NULL)
+ {
+ SAstStatElIf* elif = (SAstStatElIf*)ptr2->Data;
+ result = AddrToPosCallbackRecursion(elif->StatBlock->Stats, addr);
+ if (result != NULL)
+ return result;
+ ptr2 = ptr2->Next;
+ }
+ if (stat2->ElseStatBlock != NULL)
+ {
+ result = AddrToPosCallbackRecursion(stat2->ElseStatBlock->Stats, addr);
+ if (result != NULL)
+ return result;
+ }
+ }
+ break;
+ case AstTypeId_StatSwitch:
+ {
+ SAstStatSwitch* stat2 = (SAstStatSwitch*)stat;
+ ptr2 = stat2->Cases->Top;
+ while (ptr2 != NULL)
+ {
+ SAstStatCase* case_ = (SAstStatCase*)ptr2->Data;
+ result = AddrToPosCallbackRecursion(case_->StatBlock->Stats, addr);
+ if (result != NULL)
+ return result;
+ ptr2 = ptr2->Next;
+ }
+ if (stat2->DefaultStatBlock != NULL)
+ {
+ result = AddrToPosCallbackRecursion(stat2->DefaultStatBlock->Stats, addr);
+ if (result != NULL)
+ return result;
+ }
+ }
+ break;
+ case AstTypeId_StatWhile:
+ {
+ SAstStatWhile* stat2 = (SAstStatWhile*)stat;
+ result = AddrToPosCallbackRecursion(stat2->Stats, addr);
+ if (result != NULL)
+ return result;
+ }
+ break;
+ case AstTypeId_StatFor:
+ {
+ SAstStatFor* stat2 = (SAstStatFor*)stat;
+ result = AddrToPosCallbackRecursion(stat2->Stats, addr);
+ if (result != NULL)
+ return result;
+ }
+ break;
+ case AstTypeId_StatTry:
+ {
+ SAstStatTry* stat2 = (SAstStatTry*)stat;
+ result = AddrToPosCallbackRecursion(stat2->StatBlock->Stats, addr);
+ if (result != NULL)
+ return result;
+ ptr2 = stat2->Catches->Top;
+ while (ptr2 != NULL)
+ {
+ SAstStatCatch* catch_ = (SAstStatCatch*)ptr2->Data;
+ result = AddrToPosCallbackRecursion(catch_->StatBlock->Stats, addr);
+ if (result != NULL)
+ return result;
+ ptr2 = ptr2->Next;
+ }
+ if (stat2->FinallyStatBlock != NULL)
+ {
+ result = AddrToPosCallbackRecursion(stat2->FinallyStatBlock->Stats, addr);
+ if (result != NULL)
+ return result;
+ }
+ }
+ break;
+ case AstTypeId_StatBlock:
+ {
+ SAstStatBlock* stat2 = (SAstStatBlock*)stat;
+ result = AddrToPosCallbackRecursion(stat2->Stats, addr);
+ if (result != NULL)
+ return result;
+ }
+ break;
+ }
+ return (SPos*)((SAst*)stat)->Pos;
+ }
+ ptr = ptr->Next;
+ }
+ return NULL;
+}
+
+static U64 PosToAddr(const SPos* pos)
+{
+ U64 addr = 0;
+ void* params[2];
+ params[0] = &addr;
+ params[1] = (void*)pos;
+ DictIForEach(PackAsm.FuncAddrs, PosToAddrCallback, params);
+ return addr;
+}
+
+static const void* PosToAddrCallback(U64 key, const void* value, void* param)
+{
+ SAstFunc* func = (SAstFunc*)key;
+ void** params = (void**)param;
+ U64* addr = (U64*)params[0];
+ const SPos* pos = (const SPos*)params[1];
+ const SPos* func_pos = ((SAst*)func)->Pos;
+ if (*addr == 0 && func_pos != NULL && wcscmp(func_pos->SrcName, pos->SrcName) == 0 && func_pos->Row <= pos->Row && pos->Row <= func->PosRowBottom)
+ *addr = PosToAddrCallbackRecursion(func->Stats, pos);
+ return value;
+}
+
+static U64 PosToAddrCallbackRecursion(const SList* stats, const SPos* target_pos)
+{
+ SListNode* ptr = stats->Top;
+ while (ptr != NULL)
+ {
+ SAstStat* stat = (SAstStat*)ptr->Data;
+ const SPos* stat_pos = ((SAst*)stat)->Pos;
+ if (stat->AsmTop != NULL && stat_pos != NULL && wcscmp(stat_pos->SrcName, target_pos->SrcName) == 0 && stat_pos->Row <= target_pos->Row && target_pos->Row <= stat->PosRowBottom)
+ {
+ U64 result;
+ SListNode* ptr2;
+ switch (((SAst*)stat)->TypeId)
+ {
+ case AstTypeId_StatIf:
+ {
+ SAstStatIf* stat2 = (SAstStatIf*)stat;
+ result = PosToAddrCallbackRecursion(stat2->StatBlock->Stats, target_pos);
+ if (result != 0)
+ return result;
+ ptr2 = stat2->ElIfs->Top;
+ while (ptr2 != NULL)
+ {
+ SAstStatElIf* elif = (SAstStatElIf*)ptr2->Data;
+ result = PosToAddrCallbackRecursion(elif->StatBlock->Stats, target_pos);
+ if (result != 0)
+ return result;
+ ptr2 = ptr2->Next;
+ }
+ if (stat2->ElseStatBlock != NULL)
+ {
+ result = PosToAddrCallbackRecursion(stat2->ElseStatBlock->Stats, target_pos);
+ if (result != 0)
+ return result;
+ }
+ }
+ break;
+ case AstTypeId_StatSwitch:
+ {
+ SAstStatSwitch* stat2 = (SAstStatSwitch*)stat;
+ ptr2 = stat2->Cases->Top;
+ while (ptr2 != NULL)
+ {
+ SAstStatCase* case_ = (SAstStatCase*)ptr2->Data;
+ result = PosToAddrCallbackRecursion(case_->StatBlock->Stats, target_pos);
+ if (result != 0)
+ return result;
+ ptr2 = ptr2->Next;
+ }
+ if (stat2->DefaultStatBlock != NULL)
+ {
+ result = PosToAddrCallbackRecursion(stat2->DefaultStatBlock->Stats, target_pos);
+ if (result != 0)
+ return result;
+ }
+ }
+ break;
+ case AstTypeId_StatWhile:
+ {
+ SAstStatWhile* stat2 = (SAstStatWhile*)stat;
+ result = PosToAddrCallbackRecursion(stat2->Stats, target_pos);
+ if (result != 0)
+ return result;
+ }
+ break;
+ case AstTypeId_StatFor:
+ {
+ SAstStatFor* stat2 = (SAstStatFor*)stat;
+ result = PosToAddrCallbackRecursion(stat2->Stats, target_pos);
+ if (result != 0)
+ return result;
+ }
+ break;
+ case AstTypeId_StatTry:
+ {
+ SAstStatTry* stat2 = (SAstStatTry*)stat;
+ result = PosToAddrCallbackRecursion(stat2->StatBlock->Stats, target_pos);
+ if (result != 0)
+ return result;
+ ptr2 = stat2->Catches->Top;
+ while (ptr2 != NULL)
+ {
+ SAstStatCatch* catch_ = (SAstStatCatch*)ptr2->Data;
+ result = PosToAddrCallbackRecursion(catch_->StatBlock->Stats, target_pos);
+ if (result != 0)
+ return result;
+ ptr2 = ptr2->Next;
+ }
+ if (stat2->FinallyStatBlock != NULL)
+ {
+ result = PosToAddrCallbackRecursion(stat2->FinallyStatBlock->Stats, target_pos);
+ if (result != 0)
+ return result;
+ }
+ }
+ break;
+ case AstTypeId_StatBlock:
+ {
+ SAstStatBlock* stat2 = (SAstStatBlock*)stat;
+ result = PosToAddrCallbackRecursion(stat2->Stats, target_pos);
+ if (result != 0)
+ return result;
+ }
+ break;
+ }
+ return (U64)*stat->AsmTop->Addr + DbgStartAddr;
+ }
+ ptr = ptr->Next;
+ }
+ return 0;
+}
+
static SArchiveFileList* SearchFiles(int* len, const Char* src)
{
SArchiveFileList* top = NULL;
@@ -1033,6 +1408,8 @@ static void MakeKeywordListRecursion(SKeywordListCallbackParam* param, const SAs
case AstTypeId_Class:
if (ast->TypeId == AstTypeId_Arg || ast->TypeId == AstTypeId_Func)
keyword->Name = NewStr(NULL, L".%s", ast->Name);
+ else
+ keyword->Name = ast->Name;
break;
default:
keyword->Name = ast->Name;
@@ -1086,3 +1463,58 @@ static int CmpKeywordListItem(const void* a, const void* b)
}
return cmp;
}
+
+static void FreeBreakPoints(void)
+{
+ if (BreakPointPoses != NULL)
+ {
+ S64 i;
+ for (i = 0; i < BreakPointNum; i++)
+ {
+ if (BreakPointPoses[i].SrcName[0] != L'\0')
+ FreeMem((void*)BreakPointPoses[i].SrcName);
+ }
+ FreeMem(BreakPointPoses);
+ }
+}
+
+static void SetBreakPointOpes(HANDLE process_handle)
+{
+ if (BreakPointAddrs != NULL)
+ FreeMem(BreakPointAddrs);
+ BreakPointAddrNum = (int)BreakPointNum;
+ BreakPointAddrs = (SBreakPointAddr*)AllocMem(sizeof(SBreakPointAddr) * (size_t)(BreakPointNum));
+ S64 i;
+ for (i = 0; i < BreakPointNum; i++)
+ {
+ U64 addr = PosToAddr(&BreakPointPoses[i]);
+ if (addr == 0)
+ {
+ BreakPointAddrs[i].Addr = 0;
+ BreakPointAddrs[i].Ope = 0;
+ continue;
+ }
+ U8 old_code;
+ U8 int3_code = 0xcc;
+ ReadProcessMemory(process_handle, (LPVOID)addr, &old_code, 1, NULL);
+ WriteProcessMemory(process_handle, (LPVOID)addr, &int3_code, 1, NULL);
+ BreakPointAddrs[i].Addr = addr;
+ BreakPointAddrs[i].Ope = old_code;
+ }
+ FlushInstructionCache(process_handle, NULL, 0);
+}
+
+static void UnsetBreakPointOpes(HANDLE process_handle)
+{
+ if (BreakPointAddrs == NULL)
+ return;
+ S64 i;
+ for (i = BreakPointNum - 1; i >= 0; i--)
+ {
+ if (BreakPointAddrs[i].Addr == 0)
+ continue;
+ U8 new_code = BreakPointAddrs[i].Ope;
+ WriteProcessMemory(process_handle, (LPVOID)BreakPointAddrs[i].Addr, &new_code, 1, NULL);
+ }
+ FlushInstructionCache(process_handle, NULL, 0);
+}
diff --git a/src/compiler/main.h b/src/compiler/main.h
index 7a47f430..926b99cb 100644
--- a/src/compiler/main.h
+++ b/src/compiler/main.h
@@ -4,12 +4,13 @@
EXPORT void InitCompiler(S64 lang);
EXPORT void FinCompiler(void);
-EXPORT Bool BuildMem(const U8* path, const void*(*func_get_src)(const U8*), const U8* sys_dir, const U8* output, const U8* icon, Bool rls, const U8* env, void(*func_log)(const void* args, S64 row, S64 col), S64 lang, S64 app_code);
-EXPORT Bool BuildFile(const Char* path, const Char* sys_dir, const Char* output, const Char* icon, Bool rls, const Char* env, void(*func_log)(const Char* code, const Char* msg, const Char* src, int row, int col), S64 lang, S64 app_code, Bool not_deploy);
+EXPORT Bool BuildMem(const U8* path, const void*(*func_get_src)(const U8*), const U8* sys_dir, const U8* output, const U8* icon, const void* related_files, Bool rls, const U8* env, void(*func_log)(const void* args, S64 row, S64 col), S64 lang, S64 app_code);
+EXPORT Bool BuildFile(const Char* path, const Char* sys_dir, const Char* output, const Char* icon, const void* related_files, Bool rls, const Char* env, void(*func_log)(const Char* code, const Char* msg, const Char* src, int row, int col), S64 lang, S64 app_code, Bool not_deploy);
EXPORT void Interpret1(void* src, S64 line, void* me, void* replace_func, S64 cursor_x, S64 cursor_y, S64* new_cursor_x, S64 old_line, S64 new_line);
EXPORT Bool Interpret2(const U8* path, const void*(*func_get_src)(const U8*), const U8* sys_dir, const U8* env, void(*func_log)(const void* args, S64 row, S64 col), S64 lang);
EXPORT void Version(S64* major, S64* minor, S64* micro);
EXPORT void ResetMemAllocator(void);
-EXPORT void GetKeywords(void* src, const U8* src_name, S64 x, S64 y, void* callback);
-EXPORT Bool RunDbg(const U8* path, const U8* cmd_line, void* idle_func, void* event_func);
+EXPORT void* GetKeywords(void* src, const U8* src_name, S64 x, S64 y, void* callback);
+EXPORT Bool RunDbg(const U8* path, const U8* cmd_line, void* idle_func, void* event_func, void* break_points_func, void* break_func, void* dbg_func);
+EXPORT void SetBreakPoints(const void* break_points);
EXPORT Bool Archive(const U8* dst, const U8* src, S64 app_code);
diff --git a/src/compiler/parse.c b/src/compiler/parse.c
index 151e07cb..4c33d408 100644
--- a/src/compiler/parse.c
+++ b/src/compiler/parse.c
@@ -34,6 +34,7 @@ static const Char* Reserved[] =
L"else",
L"end",
L"enum",
+ L"env",
L"false",
L"finally",
L"float",
@@ -92,6 +93,12 @@ typedef struct SKeywordListItem
int* Last;
} SKeywordListItem;
+typedef struct SKeywordTypeList
+{
+ struct SKeywordTypeList* Next;
+ Char* Type;
+} SKeywordTypeList;
+
// Assembly functions.
void* Call0Asm(void* func);
void* Call1Asm(void* arg1, void* func);
@@ -126,7 +133,11 @@ static U64 GetKeywordsFlags;
static void* GetKeywordsCallback;
static int GetKeywordsKeywordListNum;
static const SKeywordListItem** GetKeywordsKeywordList;
+static SKeywordTypeList* KeywordTypeListTop;
+static SKeywordTypeList* KeywordTypeListBottom;
+static SAstFunc* KeywordHintFunc;
+static void GetKeywordsRootImpl(const Char** str, const Char* end, const Char* src_name, int x, int y, U64 flags, void* callback, int keyword_list_num, const void* keyword_list);
static const void* ParseSrc(const Char* src_name, const void* ast, void* param);
static Char ReadBuf(void);
static Char Read(void);
@@ -214,23 +225,30 @@ static Char GetKeywordsReadStrict(const Char** str);
static Bool GetKeywordsReadIdentifier(Char* buf, const Char** str, Bool skip_spaces, Bool ref);
static Bool GetKeywordsReadUntil(const Char** str, Char c);
static void GetKeywordsAdd(const Char* str);
-static Bool GetKeywordsReadType(const Char** str);
-static Bool GetKeywordsReadExpr(const Char** str);
-static Bool GetKeywordsReadExprThree(const Char** str);
-static Bool GetKeywordsReadExprOr(const Char** str);
-static Bool GetKeywordsReadExprAnd(const Char** str);
-static Bool GetKeywordsReadExprCmp(const Char** str);
-static Bool GetKeywordsReadExprCat(const Char** str);
-static Bool GetKeywordsReadExprAdd(const Char** str);
-static Bool GetKeywordsReadExprMul(const Char** str);
-static Bool GetKeywordsReadExprPlus(const Char** str);
-static Bool GetKeywordsReadExprPow(const Char** str);
-static Bool GetKeywordsReadExprCall(const Char** str);
-static Bool GetKeywordsReadExprValue(const Char** str);
-static Bool GetKeywordsReadExprNumber(const Char** str, Char c);
+static Bool GetKeywordsReadType(const Char** str, Char** type);
+static Bool GetKeywordsReadExpr(const Char** str, Char** type);
+static Bool GetKeywordsReadExprThree(const Char** str, Char** type);
+static Bool GetKeywordsReadExprOr(const Char** str, Char** type);
+static Bool GetKeywordsReadExprAnd(const Char** str, Char** type);
+static Bool GetKeywordsReadExprCmp(const Char** str, Char** type);
+static Bool GetKeywordsReadExprCat(const Char** str, Char** type);
+static Bool GetKeywordsReadExprAdd(const Char** str, Char** type);
+static Bool GetKeywordsReadExprMul(const Char** str, Char** type);
+static Bool GetKeywordsReadExprPlus(const Char** str, Char** type);
+static Bool GetKeywordsReadExprPow(const Char** str, Char** type);
+static Bool GetKeywordsReadExprCall(const Char** str, Char** type);
+static Bool GetKeywordsReadExprValue(const Char** str, Char** type);
+static Bool GetKeywordsReadExprNumber(const Char** str, Char** type, Char c);
static void GetKeywordsAddEnum(void);
-static void GetKeywordsAddMember(void);
+static void GetKeywordsAddMember(const Char* type);
static void GetKeywordsAddKeywords(Char kind);
+static Char* NewKeywordType(const Char* keyword_type);
+static Char* CatKeywordType(const Char* keyword_type1, const Char* keyword_type2);
+static Char* GetKeywordType(const Char* identifier);
+static Char* GetKeywordTypeRecursion(const SAstType* type);
+static void PtrToStr(Char* str, const void* ptr);
+static void StrToPtr(void* ptr, const Char* str);
+static void GetKeywordHintTypeNameRecursion(size_t* len, Char* buf, const SAstType* type);
SDict* Parse(FILE*(*func_wfopen)(const Char*, const Char*), int(*func_fclose)(FILE*), U16(*func_fgetwc)(FILE*), size_t(*func_size)(FILE*), const SOption* option, U8* use_res_flags)
{
@@ -345,7 +363,7 @@ Bool InterpretImpl1(void* str, void* color, void* comment_level, void* flags, S6
flags2 = (U64*)((U8*)flags + 0x10 + 0x08 * (size_t)i);
}
*comment_level2 = comment_level_context;
- *flags2 = flags_context;
+ *flags2 = (*flags2 & 0x02) | flags_context;
{
int ptr = 0;
@@ -373,7 +391,204 @@ Bool InterpretImpl1(void* str, void* color, void* comment_level, void* flags, S6
return True;
}
-void GetKeywordsRoot(const Char** str, const Char* end, const Char* src_name, int x, int y, U64 flags, void* callback, int keyword_list_num, const void* keyword_list)
+void* GetKeywordsRoot(const Char** str, const Char* end, const Char* src_name, int x, int y, U64 flags, void* callback, int keyword_list_num, const void* keyword_list)
+{
+ SKeywordTypeList* item = (SKeywordTypeList*)AllocMem(sizeof(SKeywordTypeList));
+ item->Next = NULL;
+ item->Type = (Char*)AllocMem(sizeof(Char));
+ item->Type[0] = L'\0';
+ KeywordTypeListTop = item;
+ KeywordTypeListBottom = item;
+ KeywordHintFunc = NULL;
+ GetKeywordsRootImpl(str, end, src_name, x, y, flags, callback, keyword_list_num, keyword_list);
+ SKeywordTypeList* ptr = KeywordTypeListTop;
+ while (ptr != NULL)
+ {
+ SKeywordTypeList* ptr2 = ptr;
+ ptr = ptr->Next;
+ FreeMem(ptr2->Type);
+ FreeMem(ptr2);
+ }
+ if (KeywordHintFunc != NULL)
+ {
+ Char hint[AUXILIARY_BUF_SIZE + 1];
+ size_t len = 0;
+ len += swprintf(hint + len, AUXILIARY_BUF_SIZE, L"func %s@%s(", ((SAst*)KeywordHintFunc)->Pos->SrcName, ((SAst*)KeywordHintFunc)->Name);
+ SListNode* ptr2 = KeywordHintFunc->Args->Top;
+ if ((KeywordHintFunc->FuncAttr & FuncAttr_MakeInstance) != 0 && ptr2 != NULL)
+ ptr2 = ptr2->Next;
+ Bool first = True;
+ while (ptr2 != NULL)
+ {
+ const SAstArg* arg = (const SAstArg*)ptr2->Data;
+ if (first)
+ first = False;
+ else if (len < AUXILIARY_BUF_SIZE)
+ len += swprintf(hint + len, AUXILIARY_BUF_SIZE - len, L", ");
+ if (len < AUXILIARY_BUF_SIZE)
+ len += swprintf(hint + len, AUXILIARY_BUF_SIZE - len, L"%s: ", ((SAst*)arg)->Name);
+ GetKeywordHintTypeNameRecursion(&len, hint, arg->Type);
+ ptr2 = ptr2->Next;
+ }
+ if (len < AUXILIARY_BUF_SIZE)
+ len += swprintf(hint + len, AUXILIARY_BUF_SIZE - len, L")");
+ if (KeywordHintFunc->Ret != NULL)
+ {
+ if (len < AUXILIARY_BUF_SIZE)
+ len += swprintf(hint + len, AUXILIARY_BUF_SIZE - len, L": ");
+ GetKeywordHintTypeNameRecursion(&len, hint, KeywordHintFunc->Ret);
+ }
+ KeywordHintFunc = NULL;
+ U8* result = (U8*)AllocMem(0x10 + sizeof(Char) * (len + 1));
+ ((S64*)result)[0] = 1;
+ ((S64*)result)[1] = len;
+ memcpy(result + 0x10, hint, sizeof(Char) * (len + 1));
+ return result;
+ }
+ return NULL;
+}
+
+void GetDbgVars(int keyword_list_num, const void* keyword_list, const Char* pos_name, int pos_row, HANDLE process_handle, U64 start_addr, const CONTEXT* context, void* callback)
+{
+ const SKeywordListItem** keyword_list2 = (const SKeywordListItem**)keyword_list;
+ int i;
+ Char buf1[0x08 + 256];
+ Char buf2[0x08 + 1024];
+ Char* str1 = buf1 + 0x08;
+ Char* str2 = buf2 + 0x08;
+ U64 addr;
+ for (i = 0; i < keyword_list_num; i++)
+ {
+ const SKeywordListItem* item = keyword_list2[i];
+ if (item->Name[0] == L'%' || item->Name[0] == L'.' || item->Ast->TypeId != AstTypeId_Arg)
+ continue;
+ if (item->Name[0] == L'@')
+ {
+ if (wcscmp(pos_name, item->Ast->Pos->SrcName) == 0)
+ wcscpy(str1, item->Name);
+ else
+ {
+ if (!item->Ast->Public)
+ continue;
+ wcscpy(str1, item->Ast->Pos->SrcName);
+ wcscat(str1, item->Name);
+ }
+ }
+ else if (wcscmp(pos_name, item->Ast->Pos->SrcName) == 0 && *item->First <= pos_row && pos_row <= *item->Last)
+ wcscpy(str1, item->Name);
+ else
+ continue;
+ const SAstArg* arg = (const SAstArg*)item->Ast;
+ switch (arg->Kind)
+ {
+ case AstArgKind_Global:
+ addr = start_addr + *arg->Addr;
+ break;
+ case AstArgKind_LocalArg:
+ case AstArgKind_LocalVar:
+ addr = context->Rsp + *arg->Addr;
+ break;
+ default:
+ continue;
+ }
+ switch (((SAst*)arg->Type)->TypeId)
+ {
+ case AstTypeId_TypePrim:
+ switch (((SAstTypePrim*)arg->Type)->Kind)
+ {
+ case AstTypePrimKind_Int:
+ {
+ S64 value = 0;
+ ReadProcessMemory(process_handle, (LPVOID)addr, &value, sizeof(value), NULL);
+ swprintf(str2, 1024, L"%I64d (0x%016I64X)", value, (U64)value);
+ }
+ break;
+ case AstTypePrimKind_Float:
+ {
+ double value = 0.0;
+ ReadProcessMemory(process_handle, (LPVOID)addr, &value, sizeof(value), NULL);
+ swprintf(str2, 1024, L"%g", value);
+ }
+ break;
+ case AstTypePrimKind_Char:
+ {
+ Char value = 0;
+ ReadProcessMemory(process_handle, (LPVOID)addr, &value, sizeof(value), NULL);
+ swprintf(str2, 1024, L"'%c' %d (0x%04X)", value, value, value);
+ }
+ break;
+ case AstTypePrimKind_Bool:
+ {
+ Bool value = 0;
+ ReadProcessMemory(process_handle, (LPVOID)addr, &value, sizeof(value), NULL);
+ swprintf(str2, 1024, L"%s", value ? L"true" : L"false");
+ }
+ break;
+ default:
+ ASSERT(False);
+ break;
+ }
+ break;
+ case AstTypeId_TypeBit:
+ switch (((SAstTypeBit*)arg->Type)->Size)
+ {
+ case 1:
+ {
+ U8 value = 0;
+ ReadProcessMemory(process_handle, (LPVOID)addr, &value, sizeof(value), NULL);
+ swprintf(str2, 1024, L"%u (0x%02X)", value, value);
+ }
+ break;
+ case 2:
+ {
+ U16 value = 0;
+ ReadProcessMemory(process_handle, (LPVOID)addr, &value, sizeof(value), NULL);
+ swprintf(str2, 1024, L"%u (0x%04X)", value, value);
+ }
+ break;
+ case 4:
+ {
+ U32 value = 0;
+ ReadProcessMemory(process_handle, (LPVOID)addr, &value, sizeof(value), NULL);
+ swprintf(str2, 1024, L"%u (0x%08X)", value, value);
+ }
+ break;
+ case 8:
+ {
+ U64 value = 0;
+ ReadProcessMemory(process_handle, (LPVOID)addr, &value, sizeof(value), NULL);
+ swprintf(str2, 1024, L"%I64u (0x%016I64X)", value, value);
+ }
+ break;
+ default:
+ ASSERT(False);
+ break;
+ }
+ break;
+ default:
+ if (IsEnum(arg->Type))
+ {
+ U64 value = 0;
+ ReadProcessMemory(process_handle, (LPVOID)addr, &value, sizeof(value), NULL);
+ swprintf(str2, 1024, L"%I64d (0x%016I64X)", value, value);
+ }
+ else
+ {
+ U64 value = 0;
+ ReadProcessMemory(process_handle, (LPVOID)addr, &value, sizeof(value), NULL);
+ swprintf(str2, 1024, L"0x%016I64X", value);
+ }
+ break;
+ }
+ ((S64*)buf1)[0] = 2;
+ ((S64*)buf1)[1] = (S64)wcslen(str1);
+ ((S64*)buf2)[0] = 2;
+ ((S64*)buf2)[1] = (S64)wcslen(str2);
+ Call3Asm((void*)1, buf1, buf2, callback);
+ }
+}
+
+static void GetKeywordsRootImpl(const Char** str, const Char* end, const Char* src_name, int x, int y, U64 flags, void* callback, int keyword_list_num, const void* keyword_list)
{
GetKeywordsEnd = end;
GetKeywordsSrcName = src_name;
@@ -431,8 +646,11 @@ void GetKeywordsRoot(const Char** str, const Char* end, const Char* src_name, in
return;
if (GetKeywordsReadUntil(str, L':'))
return;
- if (GetKeywordsReadType(str))
- return;
+ {
+ Char* tmp_type = L"";
+ if (GetKeywordsReadType(str, &tmp_type))
+ return;
+ }
c = GetKeywordsReadChar(str);
if (c == L'\0')
return;
@@ -447,7 +665,8 @@ void GetKeywordsRoot(const Char** str, const Char* end, const Char* src_name, in
return;
if (c == L':')
{
- if (GetKeywordsReadType(str))
+ Char* tmp_type = L"";
+ if (GetKeywordsReadType(str, &tmp_type))
return;
}
}
@@ -492,14 +711,20 @@ void GetKeywordsRoot(const Char** str, const Char* end, const Char* src_name, in
return;
if (GetKeywordsReadUntil(str, L':'))
return;
- if (GetKeywordsReadType(str))
- return;
+ {
+ Char* tmp_type = L"";
+ if (GetKeywordsReadType(str, &tmp_type))
+ return;
+ }
if (GetKeywordsReadUntil(str, L':'))
return;
if (GetKeywordsReadUntil(str, L':'))
return;
- if (GetKeywordsReadExpr(str))
- return;
+ {
+ Char* tmp_type = L"";
+ if (GetKeywordsReadExpr(str, &tmp_type))
+ return;
+ }
}
else if (wcscmp(buf, L"alias") == 0)
{
@@ -507,8 +732,11 @@ void GetKeywordsRoot(const Char** str, const Char* end, const Char* src_name, in
return;
if (GetKeywordsReadUntil(str, L':'))
return;
- if (GetKeywordsReadType(str))
- return;
+ {
+ Char* tmp_type = L"";
+ if (GetKeywordsReadType(str, &tmp_type))
+ return;
+ }
}
else if (wcscmp(buf, L"class") == 0)
{
@@ -518,14 +746,14 @@ void GetKeywordsRoot(const Char** str, const Char* end, const Char* src_name, in
return;
if (GetKeywordsReadIdentifier(buf, str, True, True))
{
- GetKeywordsAdd(L"class_name");
GetKeywordsAddKeywords(L'c');
return;
}
}
else if (wcscmp(buf, L"do") == 0 || wcscmp(buf, L"assert") == 0 || wcscmp(buf, L"elif") == 0 || wcscmp(buf, L"throw") == 0 || wcscmp(buf, L"ret") == 0)
{
- if (GetKeywordsReadExpr(str))
+ Char* tmp_type = L"";
+ if (GetKeywordsReadExpr(str, &tmp_type))
return;
}
else if (wcscmp(buf, L"case") == 0 || wcscmp(buf, L"catch") == 0)
@@ -533,8 +761,11 @@ void GetKeywordsRoot(const Char** str, const Char* end, const Char* src_name, in
Char c;
for (; ; )
{
- if (GetKeywordsReadExpr(str))
- return;
+ {
+ Char* tmp_type = L"";
+ if (GetKeywordsReadExpr(str, &tmp_type))
+ return;
+ }
c = GetKeywordsReadChar(str);
if (c == L'\0')
return;
@@ -556,16 +787,25 @@ void GetKeywordsRoot(const Char** str, const Char* end, const Char* src_name, in
return;
if (GetKeywordsReadUntil(str, L'('))
return;
- if (GetKeywordsReadExpr(str))
- return;
+ {
+ Char* tmp_type = L"";
+ if (GetKeywordsReadExpr(str, &tmp_type))
+ return;
+ }
if (GetKeywordsReadUntil(str, L','))
return;
- if (GetKeywordsReadExpr(str))
- return;
+ {
+ Char* tmp_type = L"";
+ if (GetKeywordsReadExpr(str, &tmp_type))
+ return;
+ }
if (GetKeywordsReadUntil(str, L','))
return;
- if (GetKeywordsReadExpr(str))
- return;
+ {
+ Char* tmp_type = L"";
+ if (GetKeywordsReadExpr(str, &tmp_type))
+ return;
+ }
}
else if (wcscmp(buf, L"while") == 0)
{
@@ -573,8 +813,11 @@ void GetKeywordsRoot(const Char** str, const Char* end, const Char* src_name, in
return;
if (GetKeywordsReadUntil(str, L'('))
return;
- if (GetKeywordsReadExpr(str))
- return;
+ {
+ Char* tmp_type = L"";
+ if (GetKeywordsReadExpr(str, &tmp_type))
+ return;
+ }
if (GetKeywordsReadUntil(str, L','))
return;
if (GetKeywordsReadIdentifier(buf, str, True, False))
@@ -589,11 +832,12 @@ void GetKeywordsRoot(const Char** str, const Char* end, const Char* src_name, in
return;
if (GetKeywordsReadUntil(str, L'('))
return;
- if (GetKeywordsReadExpr(str))
- return;
+ {
+ Char* tmp_type = L"";
+ if (GetKeywordsReadExpr(str, &tmp_type))
+ return;
+ }
}
- else
- return;
}
static const void* ParseSrc(const Char* src_name, const void* ast, void* param)
@@ -1237,6 +1481,8 @@ static SAstStatBlock* ParseDummyBlock(SAstStat** out_stat, EAstTypeId* out_type_
{
SAstStatBlock* ast = (SAstStatBlock*)Alloc(sizeof(SAstStatBlock));
InitAst((SAst*)ast, AstTypeId_StatBlock, NewPos(SrcName, Row, Col), NULL, False, True);
+ ((SAstStat*)ast)->AsmTop = NULL;
+ ((SAstStat*)ast)->AsmBottom = NULL;
((SAstStatBreakable*)ast)->BlockVar = NULL;
((SAstStatBreakable*)ast)->BreakPoint = NULL;
ast->Stats = ListNew();
@@ -1356,6 +1602,7 @@ static SAstStatBlock* ParseDummyBlock(SAstStat** out_stat, EAstTypeId* out_type_
}
ListAdd(ast->Stats, stat);
}
+ ((SAstStat*)ast)->PosRowBottom = Row - 1;
AddEndPosScope();
Scope = StackPop(Scope);
return ast;
@@ -1586,6 +1833,9 @@ static SAstFunc* ParseFunc(const Char* parent_class, Bool overridden)
SAstStatVar* stat_var = (SAstStatVar*)Alloc(sizeof(SAstStatVar));
{
InitAst((SAst*)stat_var, AstTypeId_StatVar, ((SAst*)ast)->Pos, NULL, False, False);
+ ((SAstStat*)stat_var)->AsmTop = NULL;
+ ((SAstStat*)stat_var)->AsmBottom = NULL;
+ ((SAstStat*)stat_var)->PosRowBottom = -1;
SAstVar* var = (SAstVar*)Alloc(sizeof(SAstVar));
{
InitAst((SAst*)var, AstTypeId_Var, ((SAst*)ast)->Pos, NULL, False, False);
@@ -1638,6 +1888,7 @@ static SAstFunc* ParseFunc(const Char* parent_class, Bool overridden)
break;
ListAdd(ast->Stats, stat);
}
+ ast->PosRowBottom = Row - 1;
AddEndPosScope();
Scope = StackPop(Scope);
return ast;
@@ -1692,6 +1943,7 @@ static SAstClass* ParseClass(void)
ast->VarSize = 0;
ast->FuncSize = 0;
ast->Items = ListNew();
+ ast->IndirectCreation = False;
AssertNextChar(L'(', True);
{
Char c = ReadChar();
@@ -1996,6 +2248,9 @@ static SAstStat* ParseStatEnd(int row, int col, SAst* block)
{
SAstStat* ast = (SAstStat*)Alloc(sizeof(SAstStat));
InitAst((SAst*)ast, AstTypeId_StatEnd, NewPos(SrcName, row, col), NULL, False, False);
+ ast->AsmTop = NULL;
+ ast->AsmBottom = NULL;
+ ast->PosRowBottom = row;
{
const Char* s = ReadIdentifier(True, False);
Bool err = False;
@@ -2047,6 +2302,9 @@ static SAstStat* ParseStatFunc(void)
{
SAstStatFunc* ast = (SAstStatFunc*)Alloc(sizeof(SAstStatFunc));
InitAst((SAst*)ast, AstTypeId_StatFunc, NULL, NULL, False, False);
+ ((SAstStat*)ast)->AsmTop = NULL;
+ ((SAstStat*)ast)->AsmBottom = NULL;
+ ((SAstStat*)ast)->PosRowBottom = -1;
ast->Def = ParseFunc(NULL, False);
return (SAstStat*)ast;
}
@@ -2055,6 +2313,9 @@ static SAstStat* ParseStatVar(void)
{
SAstStatVar* ast = (SAstStatVar*)Alloc(sizeof(SAstStatVar));
InitAst((SAst*)ast, AstTypeId_StatVar, NULL, NULL, False, False);
+ ((SAstStat*)ast)->AsmTop = NULL;
+ ((SAstStat*)ast)->AsmBottom = NULL;
+ ((SAstStat*)ast)->PosRowBottom = -1;
ast->Def = ParseVar(AstArgKind_LocalVar, NULL);
return (SAstStat*)ast;
}
@@ -2063,6 +2324,9 @@ static SAstStat* ParseStatConst(void)
{
SAstStatConst* ast = (SAstStatConst*)Alloc(sizeof(SAstStatConst));
InitAst((SAst*)ast, AstTypeId_StatConst, NULL, NULL, False, False);
+ ((SAstStat*)ast)->AsmTop = NULL;
+ ((SAstStat*)ast)->AsmBottom = NULL;
+ ((SAstStat*)ast)->PosRowBottom = -1;
ast->Def = ParseConst();
return (SAstStat*)ast;
}
@@ -2071,6 +2335,9 @@ static SAstStat* ParseStatAlias(void)
{
SAstStatAlias* ast = (SAstStatAlias*)Alloc(sizeof(SAstStatAlias));
InitAst((SAst*)ast, AstTypeId_StatAlias, NULL, NULL, False, False);
+ ((SAstStat*)ast)->AsmTop = NULL;
+ ((SAstStat*)ast)->AsmBottom = NULL;
+ ((SAstStat*)ast)->PosRowBottom = -1;
ast->Def = ParseAlias();
return (SAstStat*)ast;
}
@@ -2079,6 +2346,9 @@ static SAstStat* ParseStatClass(void)
{
SAstStatClass* ast = (SAstStatClass*)Alloc(sizeof(SAstStatClass));
InitAst((SAst*)ast, AstTypeId_StatClass, NULL, NULL, False, False);
+ ((SAstStat*)ast)->AsmTop = NULL;
+ ((SAstStat*)ast)->AsmBottom = NULL;
+ ((SAstStat*)ast)->PosRowBottom = -1;
ast->Def = ParseClass();
return (SAstStat*)ast;
}
@@ -2087,6 +2357,9 @@ static SAstStat* ParseStatEnum(void)
{
SAstStatEnum* ast = (SAstStatEnum*)Alloc(sizeof(SAstStatEnum));
InitAst((SAst*)ast, AstTypeId_StatEnum, NULL, NULL, False, False);
+ ((SAstStat*)ast)->AsmTop = NULL;
+ ((SAstStat*)ast)->AsmBottom = NULL;
+ ((SAstStat*)ast)->PosRowBottom = -1;
ast->Def = ParseEnum();
return (SAstStat*)ast;
}
@@ -2094,7 +2367,9 @@ static SAstStat* ParseStatEnum(void)
static SAstStat* ParseStatIf(void)
{
SAstStatIf* ast = (SAstStatIf*)Alloc(sizeof(SAstStatIf));
- InitAst((SAst*)ast, AstTypeId_StatIf, NULL, NULL, False, True);
+ InitAst((SAst*)ast, AstTypeId_StatIf, NewPos(SrcName, Row, Col), NULL, False, True);
+ ((SAstStat*)ast)->AsmTop = NULL;
+ ((SAstStat*)ast)->AsmBottom = NULL;
((SAstStatBreakable*)ast)->BlockVar = NULL;
((SAstStatBreakable*)ast)->BreakPoint = AsmLabel();
ast->StatBlock = NULL;
@@ -2119,6 +2394,7 @@ static SAstStat* ParseStatIf(void)
ast->ElseStatBlock = ParseDummyBlock(&stat, &type_id, AstTypeId_StatElse, (SAst*)ast);
ASSERT(type_id == AstTypeId_StatEnd);
}
+ ((SAstStat*)ast)->PosRowBottom = Row - 1;
AddEndPosScope();
Scope = StackPop(Scope);
return (SAstStat*)ast;
@@ -2128,6 +2404,9 @@ static SAstStat* ParseStatElIf(int row, int col, const SAst* block)
{
SAstStatElIf* ast = (SAstStatElIf*)Alloc(sizeof(SAstStatElIf));
InitAst((SAst*)ast, AstTypeId_StatElIf, NULL, NULL, False, False);
+ ((SAstStat*)ast)->AsmTop = NULL;
+ ((SAstStat*)ast)->AsmBottom = NULL;
+ ((SAstStat*)ast)->PosRowBottom = -1;
ast->StatBlock = NULL;
if (block->TypeId != AstTypeId_StatIf)
{
@@ -2146,6 +2425,9 @@ static SAstStat* ParseStatElse(int row, int col, const SAst* block)
{
SAstStat* ast = (SAstStat*)Alloc(sizeof(SAstStat));
InitAst((SAst*)ast, AstTypeId_StatElse, NULL, NULL, False, False);
+ ast->AsmTop = NULL;
+ ast->AsmBottom = NULL;
+ ast->PosRowBottom = -1;
if (block->TypeId != AstTypeId_StatIf)
{
Err(L"EP0043", NewPos(SrcName, row, col));
@@ -2159,7 +2441,9 @@ static SAstStat* ParseStatElse(int row, int col, const SAst* block)
static SAstStat* ParseStatSwitch(int row, int col)
{
SAstStatSwitch* ast = (SAstStatSwitch*)Alloc(sizeof(SAstStatSwitch));
- InitAst((SAst*)ast, AstTypeId_StatSwitch, NULL, NULL, False, True);
+ InitAst((SAst*)ast, AstTypeId_StatSwitch, NewPos(SrcName, Row, Col), NULL, False, True);
+ ((SAstStat*)ast)->AsmTop = NULL;
+ ((SAstStat*)ast)->AsmBottom = NULL;
((SAstStatBreakable*)ast)->BlockVar = MakeBlockVar(row, col);
((SAstStatBreakable*)ast)->BreakPoint = AsmLabel();
ast->Cases = ListNew();
@@ -2197,6 +2481,7 @@ static SAstStat* ParseStatSwitch(int row, int col)
ast->DefaultStatBlock = ParseDummyBlock(&stat, &type_id, AstTypeId_StatDefault, (SAst*)ast);
ASSERT(type_id == AstTypeId_StatEnd);
}
+ ((SAstStat*)ast)->PosRowBottom = Row - 1;
AddEndPosScope();
Scope = StackPop(Scope);
return (SAstStat*)ast;
@@ -2206,6 +2491,9 @@ static SAstStat* ParseStatCase(int row, int col, const SAst* block)
{
SAstStatCase* ast = (SAstStatCase*)Alloc(sizeof(SAstStatCase));
InitAst((SAst*)ast, AstTypeId_StatCase, NULL, NULL, False, False);
+ ((SAstStat*)ast)->AsmTop = NULL;
+ ((SAstStat*)ast)->AsmBottom = NULL;
+ ((SAstStat*)ast)->PosRowBottom = -1;
ast->Conds = ListNew();
ast->StatBlock = NULL;
if (block->TypeId != AstTypeId_StatSwitch)
@@ -2260,6 +2548,9 @@ static SAstStat* ParseStatDefault(int row, int col, const SAst* block)
{
SAstStat* ast = (SAstStat*)Alloc(sizeof(SAstStat));
InitAst((SAst*)ast, AstTypeId_StatDefault, NULL, NULL, False, False);
+ ast->AsmTop = NULL;
+ ast->AsmBottom = NULL;
+ ast->PosRowBottom = -1;
if (block->TypeId != AstTypeId_StatSwitch)
{
Err(L"EP0048", NewPos(SrcName, row, col));
@@ -2273,7 +2564,9 @@ static SAstStat* ParseStatDefault(int row, int col, const SAst* block)
static SAstStat* ParseStatWhile(void)
{
SAstStatWhile* ast = (SAstStatWhile*)Alloc(sizeof(SAstStatWhile));
- InitAst((SAst*)ast, AstTypeId_StatWhile, NULL, NULL, False, True);
+ InitAst((SAst*)ast, AstTypeId_StatWhile, NewPos(SrcName, Row, Col), NULL, False, True);
+ ((SAstStat*)ast)->AsmTop = NULL;
+ ((SAstStat*)ast)->AsmBottom = NULL;
((SAstStatBreakable*)ast)->BlockVar = NULL;
((SAstStatBreakable*)ast)->BreakPoint = AsmLabel();
((SAstStatSkipable*)ast)->SkipPoint = AsmLabel();
@@ -2310,6 +2603,7 @@ static SAstStat* ParseStatWhile(void)
break;
ListAdd(ast->Stats, stat);
}
+ ((SAstStat*)ast)->PosRowBottom = Row - 1;
AddEndPosScope();
Scope = StackPop(Scope);
return (SAstStat*)ast;
@@ -2318,7 +2612,9 @@ static SAstStat* ParseStatWhile(void)
static SAstStat* ParseStatFor(int row, int col)
{
SAstStatFor* ast = (SAstStatFor*)Alloc(sizeof(SAstStatFor));
- InitAst((SAst*)ast, AstTypeId_StatFor, NULL, NULL, False, True);
+ InitAst((SAst*)ast, AstTypeId_StatFor, NewPos(SrcName, Row, Col), NULL, False, True);
+ ((SAstStat*)ast)->AsmTop = NULL;
+ ((SAstStat*)ast)->AsmBottom = NULL;
((SAstStatBreakable*)ast)->BlockVar = MakeBlockVar(row, col);
((SAstStatBreakable*)ast)->BreakPoint = AsmLabel();
((SAstStatSkipable*)ast)->SkipPoint = AsmLabel();
@@ -2361,6 +2657,7 @@ static SAstStat* ParseStatFor(int row, int col)
break;
ListAdd(ast->Stats, stat);
}
+ ((SAstStat*)ast)->PosRowBottom = Row - 1;
AddEndPosScope();
Scope = StackPop(Scope);
return (SAstStat*)ast;
@@ -2369,7 +2666,9 @@ static SAstStat* ParseStatFor(int row, int col)
static SAstStat* ParseStatTry(int row, int col)
{
SAstStatTry* ast = (SAstStatTry*)Alloc(sizeof(SAstStatTry));
- InitAst((SAst*)ast, AstTypeId_StatTry, NULL, NULL, False, True);
+ InitAst((SAst*)ast, AstTypeId_StatTry, NewPos(SrcName, Row, Col), NULL, False, True);
+ ((SAstStat*)ast)->AsmTop = NULL;
+ ((SAstStat*)ast)->AsmBottom = NULL;
((SAstStatBreakable*)ast)->BlockVar = MakeBlockVar(row, col);
((SAstStatBreakable*)ast)->BreakPoint = AsmLabel();
ast->StatBlock = NULL;
@@ -2408,6 +2707,7 @@ static SAstStat* ParseStatTry(int row, int col)
ast->FinallyStatBlock = ParseDummyBlock(&stat, &type_id, AstTypeId_StatFinally, (SAst*)ast);
ASSERT(type_id == AstTypeId_StatEnd);
}
+ ((SAstStat*)ast)->PosRowBottom = Row - 1;
AddEndPosScope();
Scope = StackPop(Scope);
return (SAstStat*)ast;
@@ -2417,6 +2717,9 @@ static SAstStat* ParseStatCatch(int row, int col, const SAst* block)
{
SAstStatCatch* ast = (SAstStatCatch*)Alloc(sizeof(SAstStatCatch));
InitAst((SAst*)ast, AstTypeId_StatCatch, NULL, NULL, False, False);
+ ((SAstStat*)ast)->AsmTop = NULL;
+ ((SAstStat*)ast)->AsmBottom = NULL;
+ ((SAstStat*)ast)->PosRowBottom = -1;
ast->Conds = ListNew();
ast->StatBlock = NULL;
if (block->TypeId != AstTypeId_StatTry)
@@ -2483,6 +2786,9 @@ static SAstStat* ParseStatFinally(int row, int col, const SAst* block)
{
SAstStat* ast = (SAstStat*)Alloc(sizeof(SAstStat));
InitAst((SAst*)ast, AstTypeId_StatFinally, NULL, NULL, False, False);
+ ast->AsmTop = NULL;
+ ast->AsmBottom = NULL;
+ ast->PosRowBottom = -1;
if (block->TypeId != AstTypeId_StatTry)
{
Err(L"EP0052", NewPos(SrcName, row, col));
@@ -2496,7 +2802,10 @@ static SAstStat* ParseStatFinally(int row, int col, const SAst* block)
static SAstStat* ParseStatThrow(void)
{
SAstStatThrow* ast = (SAstStatThrow*)Alloc(sizeof(SAstStatThrow));
- InitAst((SAst*)ast, AstTypeId_StatThrow, NULL, NULL, False, False);
+ InitAst((SAst*)ast, AstTypeId_StatThrow, NewPos(SrcName, Row, Col), NULL, False, False);
+ ((SAstStat*)ast)->AsmTop = NULL;
+ ((SAstStat*)ast)->AsmBottom = NULL;
+ ((SAstStat*)ast)->PosRowBottom = Row;
ast->Code = ParseExpr();
AssertNextChar(L'\n', True);
return (SAstStat*)ast;
@@ -2505,7 +2814,9 @@ static SAstStat* ParseStatThrow(void)
static SAstStat* ParseStatBlock(void)
{
SAstStatBlock* ast = (SAstStatBlock*)Alloc(sizeof(SAstStatBlock));
- InitAst((SAst*)ast, AstTypeId_StatBlock, NULL, NULL, False, True);
+ InitAst((SAst*)ast, AstTypeId_StatBlock, NewPos(SrcName, Row, Col), NULL, False, True);
+ ((SAstStat*)ast)->AsmTop = NULL;
+ ((SAstStat*)ast)->AsmBottom = NULL;
((SAstStatBreakable*)ast)->BlockVar = NULL;
((SAstStatBreakable*)ast)->BreakPoint = AsmLabel();
ast->Stats = ListNew();
@@ -2536,6 +2847,7 @@ static SAstStat* ParseStatBlock(void)
break;
ListAdd(ast->Stats, stat);
}
+ ((SAstStat*)ast)->PosRowBottom = Row - 1;
AddEndPosScope();
Scope = StackPop(Scope);
return (SAstStat*)ast;
@@ -2544,7 +2856,10 @@ static SAstStat* ParseStatBlock(void)
static SAstStat* ParseStatRet(void)
{
SAstStatRet* ast = (SAstStatRet*)Alloc(sizeof(SAstStatRet));
- InitAst((SAst*)ast, AstTypeId_StatRet, NULL, NULL, False, False);
+ InitAst((SAst*)ast, AstTypeId_StatRet, NewPos(SrcName, Row, Col), NULL, False, False);
+ ((SAstStat*)ast)->AsmTop = NULL;
+ ((SAstStat*)ast)->AsmBottom = NULL;
+ ((SAstStat*)ast)->PosRowBottom = Row;
{
Char c = ReadChar();
if (c != L'\n')
@@ -2562,7 +2877,10 @@ static SAstStat* ParseStatRet(void)
static SAstStat* ParseStatDo(void)
{
SAstStatDo* ast = (SAstStatDo*)Alloc(sizeof(SAstStatDo));
- InitAst((SAst*)ast, AstTypeId_StatDo, NULL, NULL, False, False);
+ InitAst((SAst*)ast, AstTypeId_StatDo, NewPos(SrcName, Row, Col), NULL, False, False);
+ ((SAstStat*)ast)->AsmTop = NULL;
+ ((SAstStat*)ast)->AsmBottom = NULL;
+ ((SAstStat*)ast)->PosRowBottom = Row;
ast->Expr = ParseExpr();
AssertNextChar(L'\n', True);
return (SAstStat*)ast;
@@ -2571,7 +2889,10 @@ static SAstStat* ParseStatDo(void)
static SAstStat* ParseStatBreak(void)
{
SAstStat* ast = (SAstStat*)Alloc(sizeof(SAstStat));
- InitAst((SAst*)ast, AstTypeId_StatBreak, NULL, NULL, False, False);
+ InitAst((SAst*)ast, AstTypeId_StatBreak, NewPos(SrcName, Row, Col), NULL, False, False);
+ ast->AsmTop = NULL;
+ ast->AsmBottom = NULL;
+ ast->PosRowBottom = Row;
((SAst*)ast)->RefName = ReadIdentifier(True, False);
AddScopeRefeds((SAst*)ast);
AssertNextChar(L'\n', True);
@@ -2581,7 +2902,10 @@ static SAstStat* ParseStatBreak(void)
static SAstStat* ParseStatSkip(void)
{
SAstStat* ast = (SAstStat*)Alloc(sizeof(SAstStat));
- InitAst((SAst*)ast, AstTypeId_StatSkip, NULL, NULL, False, False);
+ InitAst((SAst*)ast, AstTypeId_StatSkip, NewPos(SrcName, Row, Col), NULL, False, False);
+ ast->AsmTop = NULL;
+ ast->AsmBottom = NULL;
+ ast->PosRowBottom = Row;
((SAst*)ast)->RefName = ReadIdentifier(True, False);
AddScopeRefeds((SAst*)ast);
AssertNextChar(L'\n', True);
@@ -2591,7 +2915,10 @@ static SAstStat* ParseStatSkip(void)
static SAstStat* ParseStatAssert(void)
{
SAstStatAssert* ast = (SAstStatAssert*)Alloc(sizeof(SAstStatAssert));
- InitAst((SAst*)ast, AstTypeId_StatAssert, NULL, NULL, False, False);
+ InitAst((SAst*)ast, AstTypeId_StatAssert, NewPos(SrcName, Row, Col), NULL, False, False);
+ ((SAstStat*)ast)->AsmTop = NULL;
+ ((SAstStat*)ast)->AsmBottom = NULL;
+ ((SAstStat*)ast)->PosRowBottom = Row;
ast->Cond = ParseExpr();
AssertNextChar(L'\n', True);
return (SAstStat*)ast;
@@ -3190,6 +3517,7 @@ static SAstExpr* ParseExprPlus(void)
SAstExprNew* ast2 = (SAstExprNew*)Alloc(sizeof(SAstExprNew));
InitAstExpr((SAstExpr*)ast2, AstTypeId_ExprNew, NewPos(SrcName, row, col));
ast2->ItemType = ParseType();
+ ast2->AutoCreated = False;
ast = (SAstExpr*)ast2;
}
}
@@ -3280,18 +3608,18 @@ static SAstExpr* ParseExprCall(void)
else
arg->RefVar = False;
FileBuf = c;
+ arg->SkipVar = skip_var;
if (skip_var)
{
SAstExpr* ast3 = (SAstExpr*)Alloc(sizeof(SAstExpr));
- arg->SkipVar = MakeBlockVar(row, col);
+ SAstArg* tmp_var = MakeBlockVar(row, col);
InitAstExpr(ast3, AstTypeId_ExprRef, ((SAst*)ast2)->Pos);
((SAst*)ast3)->RefName = L"$";
- ((SAst*)ast3)->RefItem = (SAst*)arg->SkipVar;
+ ((SAst*)ast3)->RefItem = (SAst*)tmp_var;
arg->Arg = ast3;
}
else
{
- arg->SkipVar = NULL;
arg->Arg = ParseExpr();
}
ListAdd(ast2->Args, arg);
@@ -3619,6 +3947,11 @@ static SAstExpr* ParseExprValue(void)
U64 value = Option->Rls ? 0 : 1;
return (SAstExpr*)ObtainPrimValue(pos, AstTypePrimKind_Bool, &value);
}
+ if (wcscmp(s, L"env") == 0)
+ {
+ U64 value = 0;
+ return (SAstExpr*)ObtainPrimValue(pos, AstTypePrimKind_Int, &value);
+ }
{
SAstExpr* ast = (SAstExpr*)Alloc(sizeof(SAstExpr));
InitAstExpr(ast, AstTypeId_ExprRef, pos);
@@ -3859,8 +4192,6 @@ static void InterpretImpl1Color(int* ptr, int str_level, const Char* str, U8* co
{
if (str_level > 0 && c == L'}')
{
- color[*ptr] = CharColor_Str;
- (*ptr)++;
break;
}
else if (c == L' ' || c == L'\t')
@@ -4142,8 +4473,6 @@ static void InterpretImpl1Align(int* ptr_buf, int* ptr_str, Char* buf, const Cha
InterpretImpl1Write(ptr_buf, buf, L'\t');
}
{
- if (new_cursor_x != NULL)
- *new_cursor_x = (S64)*ptr_buf;
if (access_public != -1)
{
if (new_cursor_x != NULL && cursor_x == (S64)access_public)
@@ -4240,9 +4569,6 @@ static void InterpretImpl1AlignRecursion(int* ptr_buf, int* ptr_str, int str_lev
if (str_level > 0 && c == L'}')
{
*prev = AlignmentToken_None;
- Interpret1Impl1UpdateCursor(cursor_x, new_cursor_x, ptr_str, ptr_buf);
- InterpretImpl1Write(ptr_buf, buf, str[*ptr_str]);
- (*ptr_str)++;
break;
}
else if (type_level > 0 && c == L'>')
@@ -4884,19 +5210,21 @@ static void GetKeywordsAdd(const Char* str)
Call1Asm(buf, GetKeywordsCallback);
}
-static Bool GetKeywordsReadType(const Char** str)
+static Bool GetKeywordsReadType(const Char** str, Char** type)
{
Char c = GetKeywordsReadChar(str);
if (c == L'\0')
return True;
if (c == L'[')
{
+ Char* tmp_type = L"";
if (GetKeywordsReadUntil(str, L']'))
return True;
- if (GetKeywordsReadType(str))
+ if (GetKeywordsReadType(str, &tmp_type))
return True;
+ *type = CatKeywordType(L"&a", tmp_type);
}
- else if (L'a' <= c && c <= L'z' || L'A' <= c && c <= L'Z' || c == L'_')
+ else if (L'a' <= c && c <= L'z' || L'A' <= c && c <= L'Z' || c == L'_' || c == L'\\' || c == L'@')
{
(*str)--;
Char buf[129];
@@ -4917,29 +5245,80 @@ static Bool GetKeywordsReadType(const Char** str)
GetKeywordsAdd(L"stack");
GetKeywordsAddKeywords(L't');
}
- else if (wcscmp(buf, L"int") == 0 || wcscmp(buf, L"float") == 0 || wcscmp(buf, L"char") == 0 || wcscmp(buf, L"bool") == 0 || wcscmp(buf, L"bit8") == 0 || wcscmp(buf, L"bit16") == 0 || wcscmp(buf, L"bit32") == 0 || wcscmp(buf, L"bit64") == 0)
+ else if (wcscmp(buf, L"int") == 0)
+ {
+ *type = L"int";
+ return False;
+ }
+ else if (wcscmp(buf, L"float") == 0)
+ {
+ *type = L"float";
+ return False;
+ }
+ else if (wcscmp(buf, L"char") == 0)
+ {
+ *type = L"char";
+ return False;
+ }
+ else if (wcscmp(buf, L"bool") == 0)
+ {
+ *type = L"bool";
+ return False;
+ }
+ else if (wcscmp(buf, L"bit8") == 0)
+ {
+ *type = L"bit8";
+ return False;
+ }
+ else if (wcscmp(buf, L"bit16") == 0)
+ {
+ *type = L"bit16";
+ return False;
+ }
+ else if (wcscmp(buf, L"bit32") == 0)
+ {
+ *type = L"bit32";
return False;
+ }
+ else if (wcscmp(buf, L"bit64") == 0)
+ {
+ *type = L"bit64";
+ return False;
+ }
else if (wcscmp(buf, L"list") == 0 || wcscmp(buf, L"stack") == 0 || wcscmp(buf, L"queue") == 0)
{
+ Char* tmp_type = L"";
if (GetKeywordsReadUntil(str, L'<'))
return True;
- if (GetKeywordsReadType(str))
+ if (GetKeywordsReadType(str, &tmp_type))
return True;
if (GetKeywordsReadUntil(str, L'>'))
return True;
+ Char prefix[3];
+ prefix[0] = L'&';
+ prefix[1] = buf[0];
+ prefix[2] = L'\0';
+ *type = CatKeywordType(prefix, tmp_type);
}
else if (wcscmp(buf, L"dict") == 0)
{
+ Char* tmp_type1 = L"";
+ Char* tmp_type2 = L"";
if (GetKeywordsReadUntil(str, L'<'))
return True;
- if (GetKeywordsReadType(str))
+ if (GetKeywordsReadType(str, &tmp_type1))
return True;
if (GetKeywordsReadUntil(str, L','))
return True;
- if (GetKeywordsReadType(str))
+ if (GetKeywordsReadType(str, &tmp_type2))
return True;
if (GetKeywordsReadUntil(str, L'>'))
return True;
+ Char new_type[1024] = L"&d";
+ wcscat(new_type, tmp_type1);
+ wcscat(new_type, L"|");
+ wcscat(new_type, tmp_type2);
+ *type = NewKeywordType(new_type);
}
else if (wcscmp(buf, L"func") == 0)
{
@@ -4952,7 +5331,8 @@ static Bool GetKeywordsReadType(const Char** str)
{
for (; ; )
{
- if (GetKeywordsReadType(str))
+ Char* tmp_type = L"";
+ if (GetKeywordsReadType(str, &tmp_type))
return True;
c = GetKeywordsReadChar(str);
if (c == L'\0')
@@ -4969,9 +5349,11 @@ static Bool GetKeywordsReadType(const Char** str)
c = GetKeywordsReadChar(str);
if (c == L':')
{
- if (GetKeywordsReadType(str))
+ Char* tmp_type = L"";
+ if (GetKeywordsReadType(str, &tmp_type))
return True;
}
+ *type = L"";
}
else
return False;
@@ -4979,9 +5361,9 @@ static Bool GetKeywordsReadType(const Char** str)
return False;
}
-static Bool GetKeywordsReadExpr(const Char** str)
+static Bool GetKeywordsReadExpr(const Char** str, Char** type)
{
- if (GetKeywordsReadExprThree(str))
+ if (GetKeywordsReadExprThree(str, type))
return True;
Char c = GetKeywordsReadChar(str);
if (c == L'\0')
@@ -5002,7 +5384,7 @@ static Bool GetKeywordsReadExpr(const Char** str)
case L'^':
case L'~':
case L'$':
- if (GetKeywordsReadExpr(str))
+ if (GetKeywordsReadExpr(str, type))
return True;
break;
default:
@@ -5015,9 +5397,9 @@ static Bool GetKeywordsReadExpr(const Char** str)
return False;
}
-static Bool GetKeywordsReadExprThree(const Char** str)
+static Bool GetKeywordsReadExprThree(const Char** str, Char** type)
{
- if (GetKeywordsReadExprOr(str))
+ if (GetKeywordsReadExprOr(str, type))
return True;
for (; ; )
{
@@ -5028,11 +5410,11 @@ static Bool GetKeywordsReadExprThree(const Char** str)
{
if (GetKeywordsReadUntil(str, L'('))
return True;
- if (GetKeywordsReadExpr(str))
+ if (GetKeywordsReadExpr(str, type))
return True;
if (GetKeywordsReadUntil(str, L','))
return True;
- if (GetKeywordsReadExpr(str))
+ if (GetKeywordsReadExpr(str, type))
return True;
if (GetKeywordsReadUntil(str, L')'))
return True;
@@ -5046,9 +5428,9 @@ static Bool GetKeywordsReadExprThree(const Char** str)
return False;
}
-static Bool GetKeywordsReadExprOr(const Char** str)
+static Bool GetKeywordsReadExprOr(const Char** str, Char** type)
{
- if (GetKeywordsReadExprAnd(str))
+ if (GetKeywordsReadExprAnd(str, type))
return True;
for (; ; )
{
@@ -5057,7 +5439,7 @@ static Bool GetKeywordsReadExprOr(const Char** str)
return True;
if (c == L'|')
{
- if (GetKeywordsReadExprAnd(str))
+ if (GetKeywordsReadExprAnd(str, type))
return True;
}
else
@@ -5069,9 +5451,9 @@ static Bool GetKeywordsReadExprOr(const Char** str)
return False;
}
-static Bool GetKeywordsReadExprAnd(const Char** str)
+static Bool GetKeywordsReadExprAnd(const Char** str, Char** type)
{
- if (GetKeywordsReadExprCmp(str))
+ if (GetKeywordsReadExprCmp(str, type))
return True;
for (; ; )
{
@@ -5080,7 +5462,7 @@ static Bool GetKeywordsReadExprAnd(const Char** str)
return True;
if (c == L'&')
{
- if (GetKeywordsReadExprCmp(str))
+ if (GetKeywordsReadExprCmp(str, type))
return True;
}
else
@@ -5092,9 +5474,9 @@ static Bool GetKeywordsReadExprAnd(const Char** str)
return False;
}
-static Bool GetKeywordsReadExprCmp(const Char** str)
+static Bool GetKeywordsReadExprCmp(const Char** str, Char** type)
{
- if (GetKeywordsReadExprCat(str))
+ if (GetKeywordsReadExprCat(str, type))
return True;
Bool end_flag = False;
do
@@ -5110,7 +5492,7 @@ static Bool GetKeywordsReadExprCmp(const Char** str)
return True;
if (c == L'=')
{
- if (GetKeywordsReadExprCat(str))
+ if (GetKeywordsReadExprCat(str, type))
return True;
}
else if (c == L'>')
@@ -5120,27 +5502,29 @@ static Bool GetKeywordsReadExprCmp(const Char** str)
return True;
if (c == L'&')
{
- if (GetKeywordsReadExprCat(str))
+ if (GetKeywordsReadExprCat(str, type))
return True;
}
else if (c == L'$')
{
- if (GetKeywordsReadType(str))
+ Char* tmp_type = L"";
+ if (GetKeywordsReadType(str, &tmp_type))
return True;
}
else
{
(*str)--;
- if (GetKeywordsReadExprCat(str))
+ if (GetKeywordsReadExprCat(str, type))
return True;
}
}
else
{
(*str)--;
- if (GetKeywordsReadExprCat(str))
+ if (GetKeywordsReadExprCat(str, type))
return True;
}
+ *type = L"bool";
break;
case L'>':
c = GetKeywordsReadChar(str);
@@ -5148,8 +5532,9 @@ static Bool GetKeywordsReadExprCmp(const Char** str)
return True;
if (c != L'=')
(*str)--;
- if (GetKeywordsReadExprCat(str))
+ if (GetKeywordsReadExprCat(str, type))
return True;
+ *type = L"bool";
break;
case L'=':
c = GetKeywordsReadChar(str);
@@ -5157,20 +5542,22 @@ static Bool GetKeywordsReadExprCmp(const Char** str)
return True;
if (c == L'&')
{
- if (GetKeywordsReadExprCat(str))
+ if (GetKeywordsReadExprCat(str, type))
return True;
}
else if (c == L'$')
{
- if (GetKeywordsReadType(str))
+ Char* tmp_type = L"";
+ if (GetKeywordsReadType(str, &tmp_type))
return True;
}
else
{
(*str)--;
- if (GetKeywordsReadExprCat(str))
+ if (GetKeywordsReadExprCat(str, type))
return True;
}
+ *type = L"bool";
break;
default:
(*str)--;
@@ -5181,9 +5568,9 @@ static Bool GetKeywordsReadExprCmp(const Char** str)
return False;
}
-static Bool GetKeywordsReadExprCat(const Char** str)
+static Bool GetKeywordsReadExprCat(const Char** str, Char** type)
{
- if (GetKeywordsReadExprAdd(str))
+ if (GetKeywordsReadExprAdd(str, type))
return True;
for (; ; )
{
@@ -5192,7 +5579,7 @@ static Bool GetKeywordsReadExprCat(const Char** str)
return True;
if (c == L'~')
{
- if (GetKeywordsReadExprAdd(str))
+ if (GetKeywordsReadExprAdd(str, type))
return True;
}
else
@@ -5204,9 +5591,9 @@ static Bool GetKeywordsReadExprCat(const Char** str)
return False;
}
-static Bool GetKeywordsReadExprAdd(const Char** str)
+static Bool GetKeywordsReadExprAdd(const Char** str, Char** type)
{
- if (GetKeywordsReadExprMul(str))
+ if (GetKeywordsReadExprMul(str, type))
return True;
for (; ; )
{
@@ -5215,7 +5602,7 @@ static Bool GetKeywordsReadExprAdd(const Char** str)
return True;
if (c == L'+' || c == L'-')
{
- if (GetKeywordsReadExprMul(str))
+ if (GetKeywordsReadExprMul(str, type))
return True;
}
else
@@ -5227,9 +5614,9 @@ static Bool GetKeywordsReadExprAdd(const Char** str)
return False;
}
-static Bool GetKeywordsReadExprMul(const Char** str)
+static Bool GetKeywordsReadExprMul(const Char** str, Char** type)
{
- if (GetKeywordsReadExprPlus(str))
+ if (GetKeywordsReadExprPlus(str, type))
return True;
Bool end_flag = False;
do
@@ -5242,7 +5629,7 @@ static Bool GetKeywordsReadExprMul(const Char** str)
case L'*':
case L'/':
case L'%':
- if (GetKeywordsReadExprPlus(str))
+ if (GetKeywordsReadExprPlus(str, type))
return True;
default:
(*str)--;
@@ -5253,10 +5640,10 @@ static Bool GetKeywordsReadExprMul(const Char** str)
return False;
}
-static Bool GetKeywordsReadExprPlus(const Char** str)
+static Bool GetKeywordsReadExprPlus(const Char** str, Char** type)
{
const Char* old = *str;
- if (GetKeywordsReadExprPow(str))
+ if (GetKeywordsReadExprPow(str, type))
return True;
if (old != *str)
return False;
@@ -5285,19 +5672,25 @@ static Bool GetKeywordsReadExprPlus(const Char** str)
return False;
}
}
- if (GetKeywordsReadType(str))
- return True;
+ {
+ Char* tmp_type = L"";
+ if (GetKeywordsReadType(str, &tmp_type))
+ return True;
+ *type = CatKeywordType(L"&a", tmp_type);
+ }
}
else if (c == L'#')
{
- if (GetKeywordsReadExprPlus(str))
+ if (GetKeywordsReadExprPlus(str, type))
return True;
}
else
{
(*str)--;
- if (GetKeywordsReadType(str))
+ Char* tmp_type = L"";
+ if (GetKeywordsReadType(str, &tmp_type))
return True;
+ *type = tmp_type;
}
}
break;
@@ -5305,7 +5698,7 @@ static Bool GetKeywordsReadExprPlus(const Char** str)
case L'-':
case L'!':
case L'^':
- if (GetKeywordsReadExprPlus(str))
+ if (GetKeywordsReadExprPlus(str, type))
return True;
break;
default:
@@ -5315,10 +5708,10 @@ static Bool GetKeywordsReadExprPlus(const Char** str)
return False;
}
-static Bool GetKeywordsReadExprPow(const Char** str)
+static Bool GetKeywordsReadExprPow(const Char** str, Char** type)
{
const Char* old = *str;
- if (GetKeywordsReadExprCall(str))
+ if (GetKeywordsReadExprCall(str, type))
return True;
if (old == *str)
return False; // Interpret as a unary operator.
@@ -5327,7 +5720,7 @@ static Bool GetKeywordsReadExprPow(const Char** str)
return True;
if (c == L'^')
{
- if (GetKeywordsReadExprPlus(str))
+ if (GetKeywordsReadExprPlus(str, type))
return True;
}
else
@@ -5335,10 +5728,10 @@ static Bool GetKeywordsReadExprPow(const Char** str)
return False;
}
-static Bool GetKeywordsReadExprCall(const Char** str)
+static Bool GetKeywordsReadExprCall(const Char** str, Char** type)
{
const Char* old = *str;
- if (GetKeywordsReadExprValue(str))
+ if (GetKeywordsReadExprValue(str, type))
return True;
if (old == *str)
return False;
@@ -5351,6 +5744,12 @@ static Bool GetKeywordsReadExprCall(const Char** str)
switch (c)
{
case L'(':
+ if ((*type)[0] == L'&' && (*type)[1] == L'F')
+ {
+ void* type_ptr;
+ StrToPtr(&type_ptr, (*type) + 2);
+ KeywordHintFunc = (SAstFunc*)type_ptr;
+ }
c = GetKeywordsReadChar(str);
if (c == L'\0')
return True;
@@ -5374,7 +5773,8 @@ static Bool GetKeywordsReadExprCall(const Char** str)
(*str)--;
if (!skip_var)
{
- if (GetKeywordsReadExpr(str))
+ Char* tmp_type = L"";
+ if (GetKeywordsReadExpr(str, &tmp_type))
return True;
}
c = GetKeywordsReadChar(str);
@@ -5385,25 +5785,54 @@ static Bool GetKeywordsReadExprCall(const Char** str)
if (c != L',')
{
(*str)--;
+ *type = L"";
return False;
}
}
}
+ if ((*type)[0] == L'&' && (*type)[1] == L'F')
+ {
+ void* type_ptr;
+ StrToPtr(&type_ptr, (*type) + 2);
+ SAstType* ret_type = ((SAstFunc*)type_ptr)->Ret;
+ if (ret_type == NULL)
+ *type = L"";
+ else
+ *type = GetKeywordTypeRecursion(ret_type);
+ }
+ else if ((*type)[0] == L'&' && (*type)[1] == L'f')
+ {
+ void* type_ptr;
+ StrToPtr(&type_ptr, (*type) + 2);
+ SAstType* ret_type = ((SAstTypeFunc*)type_ptr)->Ret;
+ if (ret_type == NULL)
+ *type = L"";
+ else
+ *type = GetKeywordTypeRecursion(ret_type);
+ }
+ else
+ *type = L"";
break;
case L'[':
- if (GetKeywordsReadExpr(str))
- return True;
- if (GetKeywordsReadUntil(str, L']'))
- return True;
- break;
+ {
+ Char* tmp_type = L"";
+ if (GetKeywordsReadExpr(str, &tmp_type))
+ return True;
+ if (GetKeywordsReadUntil(str, L']'))
+ return True;
+ if ((*type)[0] == L'&' && (*type)[1] == L'a')
+ *type = NewKeywordType((*type) + 2);
+ break;
+ }
case L'.':
{
Char buf[129];
if (GetKeywordsReadIdentifier(buf, str, True, False))
{
- GetKeywordsAddMember();
+ GetKeywordsAddMember(*type);
return True;
}
+ *type = L"";
}
break;
case L'$':
@@ -5412,14 +5841,18 @@ static Bool GetKeywordsReadExprCall(const Char** str)
return True;
if (c == L'>' || c == L'<')
{
- if (GetKeywordsReadType(str))
+ Char* tmp_type = L"";
+ if (GetKeywordsReadType(str, &tmp_type))
return True;
+ *type = tmp_type;
}
else
{
(*str)--;
- if (GetKeywordsReadType(str))
+ Char* tmp_type = L"";
+ if (GetKeywordsReadType(str, &tmp_type))
return True;
+ *type = tmp_type;
}
break;
default:
@@ -5431,8 +5864,9 @@ static Bool GetKeywordsReadExprCall(const Char** str)
return False;
}
-static Bool GetKeywordsReadExprValue(const Char** str)
+static Bool GetKeywordsReadExprValue(const Char** str, Char** type)
{
+ const Char* old = *str;
Char c = GetKeywordsReadChar(str);
if (c == L'\0')
return True;
@@ -5450,7 +5884,8 @@ static Bool GetKeywordsReadExprValue(const Char** str)
{
if (c == L'{')
{
- if (GetKeywordsReadExpr(str))
+ Char* tmp_type = L"";
+ if (GetKeywordsReadExpr(str, &tmp_type))
return True;
if (GetKeywordsReadUntil(str, L'}'))
return True;
@@ -5463,6 +5898,7 @@ static Bool GetKeywordsReadExprValue(const Char** str)
if (c == L'\\')
escape = True;
}
+ *type = L"&achar";
}
return False;
case L'\'':
@@ -5483,10 +5919,11 @@ static Bool GetKeywordsReadExprValue(const Char** str)
if (c == L'\\')
escape = True;
}
+ *type = L"char";
}
return False;
case L'(':
- if (GetKeywordsReadExpr(str))
+ if (GetKeywordsReadExpr(str, type))
return True;
if (GetKeywordsReadUntil(str, L')'))
return True;
@@ -5500,8 +5937,11 @@ static Bool GetKeywordsReadExprValue(const Char** str)
(*str)--;
for (; ; )
{
- if (GetKeywordsReadExpr(str))
+ Char* tmp_type = L"";
+ if (GetKeywordsReadExpr(str, &tmp_type))
return True;
+ if ((*type)[0] == L'\0' && tmp_type[0] != L'\0')
+ *type = CatKeywordType(L"&a", tmp_type);
c = GetKeywordsReadStrict(str);
if (c == L'\0')
return True;
@@ -5523,11 +5963,12 @@ static Bool GetKeywordsReadExprValue(const Char** str)
GetKeywordsAddEnum();
return True;
}
+ *type = L"&e";
}
return False;
default:
if (L'0' <= c && c <= L'9')
- return GetKeywordsReadExprNumber(str, c);
+ return GetKeywordsReadExprNumber(str, type, c);
else if (L'a' <= c && c <= L'z' || L'A' <= c && c <= L'Z' || c == L'_' || c == L'@' || c == L'\\')
{
(*str)--;
@@ -5535,6 +5976,7 @@ static Bool GetKeywordsReadExprValue(const Char** str)
if (GetKeywordsReadIdentifier(buf, str, True, True))
{
GetKeywordsAdd(L"dbg");
+ GetKeywordsAdd(L"env");
GetKeywordsAdd(L"false");
GetKeywordsAdd(L"inf");
GetKeywordsAdd(L"null");
@@ -5543,20 +5985,37 @@ static Bool GetKeywordsReadExprValue(const Char** str)
GetKeywordsAddKeywords(L'e');
return True;
}
+ if (buf[0] == L'd' && buf[1] == L'b' && buf[2] == L'g')
+ *type = L"bool";
+ else if (buf[0] == L'f' && buf[1] == L'a' && buf[2] == L'l' && buf[3] == L's' && buf[4] == L'e')
+ *type = L"bool";
+ else if (buf[0] == L'i' && buf[1] == L'n' && buf[2] == L'f')
+ *type = L"float";
+ else if (buf[0] == L'n' && buf[1] == L'u' && buf[2] == L'l' && buf[3] == L'l')
+ *type = L"";
+ else if (buf[0] == L's' && buf[1] == L'u' && buf[2] == L'p' && buf[3] == L'e' && buf[4] == L'r')
+ *type = L"";
+ else if (buf[0] == L't' && buf[1] == L'r' && buf[2] == L'u' && buf[3] == L'e')
+ *type = L"bool";
+ else
+ *type = GetKeywordType(buf);
return False;
}
break;
}
- (*str)--;
+ *str = old;
return False;
}
-static Bool GetKeywordsReadExprNumber(const Char** str, Char c)
+static Bool GetKeywordsReadExprNumber(const Char** str, Char** type, Char c)
{
+ *type = L"int";
for (; ; )
{
if (!(c == L'x' || c == L'.' || L'0' <= c && c <= L'9' || L'A' <= c && c <= L'F'))
break;
+ if (c == L'.')
+ *type = L"float";
c = GetKeywordsRead(str);
if (c == L'\0')
return True;
@@ -5585,18 +6044,22 @@ static Bool GetKeywordsReadExprNumber(const Char** str, Char c)
switch (c)
{
case L'8':
+ *type = L"bit8";
break;
case L'1':
if (GetKeywordsReadUntil(str, L'6'))
return True;
+ *type = L"bit16";
break;
case L'3':
if (GetKeywordsReadUntil(str, L'2'))
return True;
+ *type = L"bit32";
break;
case L'6':
if (GetKeywordsReadUntil(str, L'4'))
return True;
+ *type = L"bit64";
break;
default:
(*str)--;
@@ -5622,21 +6085,157 @@ static void GetKeywordsAddEnum(void)
}
}
-static void GetKeywordsAddMember(void)
+static void GetKeywordsAddMember(const Char* type)
{
- // TODO:
- /*
- if (GetKeywordsKeywordList == NULL)
+ if (type[0] == L'\0')
return;
- int i;
- for (i = 0; i < GetKeywordsKeywordListNum; i++)
+ if (type[0] == L'b' && type[1] == L'i' && type[2] == L't')
+ {
+ if (type[3] == L'1' && type[4] == L'6' || type[3] == L'3' && type[4] == L'2' || type[3] == L'6' && type[4] == L'4' || type[3] == L'8')
+ {
+ GetKeywordsAdd(L"and");
+ GetKeywordsAdd(L"endian");
+ GetKeywordsAdd(L"not");
+ GetKeywordsAdd(L"or");
+ GetKeywordsAdd(L"sar");
+ GetKeywordsAdd(L"shl");
+ GetKeywordsAdd(L"shr");
+ GetKeywordsAdd(L"toStr");
+ GetKeywordsAdd(L"xor");
+ }
+ }
+ else if (type[0] == L'b' && type[1] == L'o' && type[2] == L'o' && type[3] == L'l')
+ GetKeywordsAdd(L"toStr");
+ else if (type[0] == L'c' && type[1] == L'h' && type[2] == L'a' && type[3] == L'r')
{
- const SKeywordListItem* item = GetKeywordsKeywordList[i];
- if (item->Name[0] != L'.')
- continue;
- GetKeywordsAdd(GetKeywordsKeywordList[i]->Name);
+ GetKeywordsAdd(L"offset");
+ GetKeywordsAdd(L"toStr");
+ }
+ else if (type[0] == L'f' && type[1] == L'l' && type[2] == L'o' && type[3] == L'a' && type[4] == L't')
+ {
+ GetKeywordsAdd(L"abs");
+ GetKeywordsAdd(L"clamp");
+ GetKeywordsAdd(L"clampMax");
+ GetKeywordsAdd(L"clampMin");
+ GetKeywordsAdd(L"sign");
+ GetKeywordsAdd(L"toStr");
+ GetKeywordsAdd(L"toStrFmt");
+ }
+ else if (type[0] == L'i' && type[1] == L'n' && type[2] == L't')
+ {
+ GetKeywordsAdd(L"abs");
+ GetKeywordsAdd(L"clamp");
+ GetKeywordsAdd(L"clampMax");
+ GetKeywordsAdd(L"clampMin");
+ GetKeywordsAdd(L"sign");
+ GetKeywordsAdd(L"toStr");
+ GetKeywordsAdd(L"toStrFmt");
+ }
+ else if (type[0] == L'&')
+ {
+ if (type[1] == L'a')
+ {
+ if (type[2] == L'c' && type[3] == L'h' && type[4] == L'a' && type[5] == L'r')
+ {
+ GetKeywordsAdd(L"findStr");
+ GetKeywordsAdd(L"findStrEx");
+ GetKeywordsAdd(L"findStrLast");
+ GetKeywordsAdd(L"lower");
+ GetKeywordsAdd(L"replace");
+ GetKeywordsAdd(L"split");
+ GetKeywordsAdd(L"toBit64");
+ GetKeywordsAdd(L"toFloat");
+ GetKeywordsAdd(L"toInt");
+ GetKeywordsAdd(L"toStr");
+ GetKeywordsAdd(L"trim");
+ GetKeywordsAdd(L"trimLeft");
+ GetKeywordsAdd(L"trimRight");
+ GetKeywordsAdd(L"upper");
+ }
+ else if (type[2] == L'&' && type[3] == L'a' && type[4] == L'c' && type[5] == L'h' && type[6] == L'a' && type[7] == L'r')
+ GetKeywordsAdd(L"join");
+ GetKeywordsAdd(L"fill");
+ GetKeywordsAdd(L"find");
+ GetKeywordsAdd(L"findBin");
+ GetKeywordsAdd(L"findLast");
+ GetKeywordsAdd(L"max");
+ GetKeywordsAdd(L"min");
+ GetKeywordsAdd(L"repeat");
+ GetKeywordsAdd(L"reverse");
+ GetKeywordsAdd(L"shuffle");
+ GetKeywordsAdd(L"sort");
+ GetKeywordsAdd(L"sortDesc");
+ GetKeywordsAdd(L"sub");
+ }
+ else if (type[1] == L'c')
+ {
+ void* ast_ptr;
+ StrToPtr(&ast_ptr, type + 2);
+ SAstClass* ast = (SAstClass*)ast_ptr;
+ SListNode* ptr = ast->Items->Top;
+ while (ptr != NULL)
+ {
+ const SAstClassItem* item = (const SAstClassItem*)ptr->Data;
+ if (item->Public)
+ {
+ const Char* name;
+ if (item->Def->TypeId == AstTypeId_Var)
+ name = ((SAst*)((SAstVar*)item->Def)->Var)->Name;
+ else if (item->Def->TypeId == AstTypeId_Const)
+ name = ((SAst*)((SAstConst*)item->Def)->Var)->Name;
+ else
+ name = item->Def->Name;
+ if (name != NULL)
+ GetKeywordsAdd(name);
+ }
+ ptr = ptr->Next;
+ }
+ }
+ else if (type[1] == L'd')
+ {
+ GetKeywordsAdd(L"add");
+ GetKeywordsAdd(L"del");
+ GetKeywordsAdd(L"exist");
+ GetKeywordsAdd(L"forEach");
+ GetKeywordsAdd(L"get");
+ GetKeywordsAdd(L"toArrayKey");
+ GetKeywordsAdd(L"toArrayValue");
+ }
+ else if (type[1] == L'e')
+ {
+ GetKeywordsAdd(L"and");
+ GetKeywordsAdd(L"not");
+ GetKeywordsAdd(L"or");
+ GetKeywordsAdd(L"xor");
+ }
+ else if (type[1] == L'l')
+ {
+ GetKeywordsAdd(L"add");
+ GetKeywordsAdd(L"del");
+ GetKeywordsAdd(L"delNext");
+ GetKeywordsAdd(L"find");
+ GetKeywordsAdd(L"findLast");
+ GetKeywordsAdd(L"get");
+ GetKeywordsAdd(L"getOffset");
+ GetKeywordsAdd(L"head");
+ GetKeywordsAdd(L"ins");
+ GetKeywordsAdd(L"moveOffset");
+ GetKeywordsAdd(L"next");
+ GetKeywordsAdd(L"prev");
+ GetKeywordsAdd(L"sort");
+ GetKeywordsAdd(L"sortDesc");
+ GetKeywordsAdd(L"tail");
+ GetKeywordsAdd(L"term");
+ GetKeywordsAdd(L"termOffset");
+ GetKeywordsAdd(L"toArray");
+ }
+ else if (type[1] == L'q' || type[1] == L's')
+ {
+ GetKeywordsAdd(L"add");
+ GetKeywordsAdd(L"get");
+ GetKeywordsAdd(L"peek");
+ }
}
- */
}
static void GetKeywordsAddKeywords(Char kind)
@@ -5652,15 +6251,15 @@ static void GetKeywordsAddKeywords(Char kind)
continue;
switch (kind)
{
- case L't':
+ case L't': // Types
if (item->Ast->TypeId != AstTypeId_Class && item->Ast->TypeId != AstTypeId_Enum && item->Ast->TypeId != AstTypeId_Alias)
continue;
break;
- case L'e':
+ case L'e': // Expressions
if (item->Ast->TypeId == AstTypeId_Class || item->Ast->TypeId == AstTypeId_Enum || item->Ast->TypeId == AstTypeId_Alias)
continue;
break;
- case L'c':
+ case L'c': // Class Names
if (item->Ast->TypeId != AstTypeId_Class)
continue;
break;
@@ -5682,6 +6281,282 @@ static void GetKeywordsAddKeywords(Char kind)
}
}
else if (wcscmp(GetKeywordsSrcName, item->Ast->Pos->SrcName) == 0 && *item->First - 1 <= GetKeywordsCursorY && GetKeywordsCursorY <= *item->Last - 1)
- GetKeywordsAdd(GetKeywordsKeywordList[i]->Name);
+ GetKeywordsAdd(item->Name);
+ }
+}
+
+static Char* NewKeywordType(const Char* keyword_type)
+{
+ size_t len = wcslen(keyword_type);
+ Char* buf = (Char*)AllocMem(sizeof(Char) * (len + 1));
+ memcpy(buf, keyword_type, sizeof(Char) * (len + 1));
+ SKeywordTypeList* item = (SKeywordTypeList*)AllocMem(sizeof(SKeywordTypeList));
+ item->Next = NULL;
+ item->Type = buf;
+ KeywordTypeListBottom->Next = item;
+ KeywordTypeListBottom = item;
+ return buf;
+}
+
+static Char* CatKeywordType(const Char* keyword_type1, const Char* keyword_type2)
+{
+ Char keyword_type[1024];
+ wcscpy(keyword_type, keyword_type1);
+ wcscat(keyword_type, keyword_type2);
+ return NewKeywordType(keyword_type);
+}
+
+static Char* GetKeywordType(const Char* identifier)
+{
+ if (GetKeywordsKeywordList == NULL)
+ return L"";
+ const SAst* ast = NULL;
+ int i;
+ for (i = 0; i < GetKeywordsKeywordListNum; i++)
+ {
+ const SKeywordListItem* item = GetKeywordsKeywordList[i];
+ if (item->Name[0] == L'.' || item->Name[0] == L'%')
+ continue;
+ if (item->Name[0] == L'@')
+ {
+ if (wcscmp(GetKeywordsSrcName, item->Ast->Pos->SrcName) == 0)
+ {
+ if (wcscmp(identifier, item->Name) == 0)
+ {
+ ast = item->Ast;
+ break;
+ }
+ }
+ else
+ {
+ if (!item->Ast->Public)
+ continue;
+ Char buf[1024];
+ wcscpy(buf, item->Ast->Pos->SrcName);
+ wcscat(buf, item->Name);
+ if (wcscmp(identifier, buf) == 0)
+ {
+ ast = item->Ast;
+ break;
+ }
+ }
+ }
+ else if (wcscmp(GetKeywordsSrcName, item->Ast->Pos->SrcName) == 0 && *item->First - 1 <= GetKeywordsCursorY && GetKeywordsCursorY <= *item->Last - 1 && wcscmp(identifier, item->Name) == 0)
+ {
+ ast = item->Ast;
+ break;
+ }
+ }
+ if (ast == NULL)
+ return L"";
+ SAstType* type = NULL;
+ if (ast->TypeId == AstTypeId_Arg)
+ type = ((SAstArg*)ast)->Type;
+ else if (ast->TypeId == AstTypeId_Class)
+ {
+ Char buf[1024];
+ buf[0] = L'&';
+ buf[1] = L'c';
+ PtrToStr(buf + 2, &ast);
+ buf[10] = L'\0';
+ return NewKeywordType(buf);
+ }
+ else if (ast->TypeId == AstTypeId_Func)
+ {
+ Char buf[1024];
+ buf[0] = L'&';
+ buf[1] = L'F';
+ PtrToStr(buf + 2, &ast);
+ buf[10] = L'\0';
+ return NewKeywordType(buf);
+ }
+ if (type == NULL)
+ return L"";
+ return GetKeywordTypeRecursion(type);
+}
+
+static Char* GetKeywordTypeRecursion(const SAstType* type)
+{
+ switch (((SAst*)type)->TypeId)
+ {
+ case AstTypeId_TypeArray:
+ return CatKeywordType(L"&a", GetKeywordTypeRecursion(((SAstTypeArray*)type)->ItemType));
+ case AstTypeId_TypeBit:
+ switch (((SAstTypeBit*)type)->Size)
+ {
+ case 1:
+ return L"bit8";
+ case 2:
+ return L"bit16";
+ case 4:
+ return L"bit32";
+ case 8:
+ return L"bit64";
+ }
+ break;
+ case AstTypeId_TypeFunc:
+ {
+ Char buf[1024];
+ buf[0] = L'&';
+ buf[1] = L'f';
+ PtrToStr(buf + 2, type);
+ buf[10] = L'\0';
+ return NewKeywordType(buf);
+ }
+ case AstTypeId_TypeGen:
+ switch (((SAstTypeGen*)type)->Kind)
+ {
+ case AstTypeGenKind_List:
+ return CatKeywordType(L"&l", GetKeywordTypeRecursion(((SAstTypeGen*)type)->ItemType));
+ case AstTypeGenKind_Stack:
+ return CatKeywordType(L"&s", GetKeywordTypeRecursion(((SAstTypeGen*)type)->ItemType));
+ case AstTypeGenKind_Queue:
+ return CatKeywordType(L"&q", GetKeywordTypeRecursion(((SAstTypeGen*)type)->ItemType));
+ }
+ break;
+ case AstTypeId_TypeDict:
+ {
+ Char buf[1024];
+ wcscpy(buf, L"&d");
+ wcscat(buf, GetKeywordTypeRecursion(((SAstTypeDict*)type)->ItemTypeKey));
+ wcscpy(buf, L"|");
+ wcscat(buf, GetKeywordTypeRecursion(((SAstTypeDict*)type)->ItemTypeValue));
+ return NewKeywordType(buf);
+ }
+ case AstTypeId_TypePrim:
+ switch (((SAstTypePrim*)type)->Kind)
+ {
+ case AstTypePrimKind_Int: return L"int";
+ case AstTypePrimKind_Float: return L"float";
+ case AstTypePrimKind_Char: return L"char";
+ case AstTypePrimKind_Bool: return L"bool";
+ }
+ break;
+ case AstTypeId_TypeUser:
+ return GetKeywordType(((SAst*)type)->RefName);
+ }
+ return L"";
+}
+
+static void PtrToStr(Char* str, const void* ptr)
+{
+ const U8* src = (const U8*)ptr;
+ U8* dst = (U8*)str;
+ int i;
+ for (i = 0; i < 8; i++)
+ {
+ U8 value = src[i];
+ dst[i * 2 + 0] = ((value & 0x0f) << 4) | 0x0f;
+ dst[i * 2 + 1] = (value & 0xf0) | 0x0f;
+ }
+}
+
+static void StrToPtr(void* ptr, const Char* str)
+{
+ const U8* src = (const U8*)str;
+ U8* dst = (U8*)ptr;
+ int i;
+ for (i = 0; i < 8; i++)
+ dst[i] = (src[i * 2 + 0] >> 4) | (src[i * 2 + 1] & 0xf0);
+}
+
+static void GetKeywordHintTypeNameRecursion(size_t* len, Char* buf, const SAstType* type)
+{
+ switch (((SAst*)type)->TypeId)
+ {
+ case AstTypeId_TypeArray:
+ if (*len < AUXILIARY_BUF_SIZE)
+ *len += swprintf(buf + *len, AUXILIARY_BUF_SIZE - *len, L"[]");
+ GetKeywordHintTypeNameRecursion(len, buf, ((SAstTypeArray*)type)->ItemType);
+ return;
+ case AstTypeId_TypeBit:
+ if (*len < AUXILIARY_BUF_SIZE)
+ *len += swprintf(buf + *len, AUXILIARY_BUF_SIZE - *len, L"bit%d", ((SAstTypeBit*)type)->Size * 8);
+ return;
+ case AstTypeId_TypeFunc:
+ if (*len < AUXILIARY_BUF_SIZE)
+ *len += swprintf(buf + *len, AUXILIARY_BUF_SIZE - *len, L"func<(");
+ {
+ SListNode* ptr = ((SAstTypeFunc*)type)->Args->Top;
+ while (ptr != NULL)
+ {
+ if (ptr != ((SAstTypeFunc*)type)->Args->Top)
+ {
+ if (*len < AUXILIARY_BUF_SIZE)
+ *len += swprintf(buf + *len, AUXILIARY_BUF_SIZE - *len, L", ");
+ }
+ SAstTypeFuncArg* arg = (SAstTypeFuncArg*)ptr->Data;
+ GetKeywordHintTypeNameRecursion(len, buf, arg->Arg);
+ ptr = ptr->Next;
+ }
+ }
+ if (*len < AUXILIARY_BUF_SIZE)
+ *len += swprintf(buf + *len, AUXILIARY_BUF_SIZE - *len, L")");
+ if (((SAstTypeFunc*)type)->Ret != NULL)
+ {
+ if (*len < AUXILIARY_BUF_SIZE)
+ *len += swprintf(buf + *len, AUXILIARY_BUF_SIZE - *len, L": ");
+ GetKeywordHintTypeNameRecursion(len, buf, ((SAstTypeFunc*)type)->Ret);
+ }
+ if (*len < AUXILIARY_BUF_SIZE)
+ *len += swprintf(buf + *len, AUXILIARY_BUF_SIZE - *len, L">");
+ return;
+ case AstTypeId_TypeGen:
+ switch (((SAstTypeGen*)type)->Kind)
+ {
+ case AstTypeGenKind_List:
+ if (*len < AUXILIARY_BUF_SIZE)
+ *len += swprintf(buf + *len, AUXILIARY_BUF_SIZE - *len, L"list<");
+ break;
+ case AstTypeGenKind_Stack:
+ if (*len < AUXILIARY_BUF_SIZE)
+ *len += swprintf(buf + *len, AUXILIARY_BUF_SIZE - *len, L"stack<");
+ break;
+ case AstTypeGenKind_Queue:
+ if (*len < AUXILIARY_BUF_SIZE)
+ *len += swprintf(buf + *len, AUXILIARY_BUF_SIZE - *len, L"queue<");
+ break;
+ }
+ GetKeywordHintTypeNameRecursion(len, buf, ((SAstTypeGen*)type)->ItemType);
+ if (*len < AUXILIARY_BUF_SIZE)
+ *len += swprintf(buf + *len, AUXILIARY_BUF_SIZE - *len, L">");
+ return;
+ case AstTypeId_TypeDict:
+ {
+ if (*len < AUXILIARY_BUF_SIZE)
+ *len += swprintf(buf + *len, AUXILIARY_BUF_SIZE - *len, L"dict<");
+ GetKeywordHintTypeNameRecursion(len, buf, ((SAstTypeDict*)type)->ItemTypeKey);
+ if (*len < AUXILIARY_BUF_SIZE)
+ *len += swprintf(buf + *len, AUXILIARY_BUF_SIZE - *len, L", ");
+ GetKeywordHintTypeNameRecursion(len, buf, ((SAstTypeDict*)type)->ItemTypeValue);
+ if (*len < AUXILIARY_BUF_SIZE)
+ *len += swprintf(buf + *len, AUXILIARY_BUF_SIZE - *len, L">");
+ return;
+ }
+ case AstTypeId_TypePrim:
+ switch (((SAstTypePrim*)type)->Kind)
+ {
+ case AstTypePrimKind_Int:
+ if (*len < AUXILIARY_BUF_SIZE)
+ *len += swprintf(buf + *len, AUXILIARY_BUF_SIZE - *len, L"int");
+ return;
+ case AstTypePrimKind_Float:
+ if (*len < AUXILIARY_BUF_SIZE)
+ *len += swprintf(buf + *len, AUXILIARY_BUF_SIZE - *len, L"float");
+ return;
+ case AstTypePrimKind_Char:
+ if (*len < AUXILIARY_BUF_SIZE)
+ *len += swprintf(buf + *len, AUXILIARY_BUF_SIZE - *len, L"char");
+ return;
+ case AstTypePrimKind_Bool:
+ if (*len < AUXILIARY_BUF_SIZE)
+ *len += swprintf(buf + *len, AUXILIARY_BUF_SIZE - *len, L"bool");
+ return;
+ }
+ break;
+ case AstTypeId_TypeUser:
+ if (*len < AUXILIARY_BUF_SIZE)
+ *len += swprintf(buf + *len, AUXILIARY_BUF_SIZE - *len, L"%s", ((SAst*)type)->RefName);
+ return;
}
}
diff --git a/src/compiler/parse.h b/src/compiler/parse.h
index 00762a29..4e57c693 100644
--- a/src/compiler/parse.h
+++ b/src/compiler/parse.h
@@ -7,4 +7,5 @@
SDict* Parse(FILE*(*func_wfopen)(const Char*, const Char*), int(*func_fclose)(FILE*), U16(*func_fgetwc)(FILE*), size_t(*func_size)(FILE*), const SOption* option, U8* use_res_flags);
Bool InterpretImpl1(void* str, void* color, void* comment_level, void* flags, S64 line, void* me, void* replace_func, S64 cursor_x, S64 cursor_y, S64* new_cursor_x, S64 old_line, S64 new_line);
-void GetKeywordsRoot(const Char** str, const Char* end, const Char* src_name, int x, int y, U64 flags, void* callback, int keyword_list_num, const void* keyword_list);
+void* GetKeywordsRoot(const Char** str, const Char* end, const Char* src_name, int x, int y, U64 flags, void* callback, int keyword_list_num, const void* keyword_list);
+void GetDbgVars(int keyword_list_num, const void* keyword_list, const Char* pos_name, int pos_row, HANDLE process_handle, U64 start_addr, const CONTEXT* context, void* callback);
diff --git a/src/knobj_maker/knobj_maker.vcxproj b/src/knobj_maker/knobj_maker.vcxproj
index ad6ccac1..406c0afb 100644
--- a/src/knobj_maker/knobj_maker.vcxproj
+++ b/src/knobj_maker/knobj_maker.vcxproj
@@ -85,6 +85,9 @@
true
true
+
+ echo F | xcopy /y /r $(TargetPath) $(ProjectDir)..\..\package\tools\knobj_maker.exe
+
diff --git a/src/knobj_maker/main.cpp b/src/knobj_maker/main.cpp
index bf4e6dd3..e6f3d100 100644
--- a/src/knobj_maker/main.cpp
+++ b/src/knobj_maker/main.cpp
@@ -15,7 +15,14 @@
#include "main.h"
#include "fbxsdk.h"
+#include
+#include
+
+// 0 = 'Ja', 1 = 'En'.
+#define LANG (0)
+
static const Bool Mirror = False; // Invert the Z axis.
+static const int JointInfluenceMax = 2;
struct SPoint
{
@@ -25,15 +32,22 @@ struct SPoint
double TangentX, TangentY, TangentZ;
// double BinormalX, BinormalY, BinormalZ;
double TexU, TexV;
- double JointWeight[4];
- int Joint[4];
+ double JointWeight[JointInfluenceMax];
+ int Joint[JointInfluenceMax];
+};
+
+enum EFormat
+{
+ Format_HasTangent = 0x01,
+ Format_HasJoint = 0x02,
};
static FbxManager* Manager = NULL;
static FbxScene* Scene = NULL;
static FILE* FilePtr = NULL;
+static int Format = 0;
-static void Err(const char* msg);
+static void Warn(const char* msg_ja, const char* msg_en);
static void Normalize(double* vec);
static void CalcTangent(double* tangents, double* binormals, const double* normals, const double* ps, const double* uvs);
static SPoint MirrorPoint(const SPoint* p);
@@ -43,10 +57,13 @@ static void WriteInt(int n);
static void WriteFloat(double n);
static void WriteNode(FbxNode* root);
-static void Err(const char* msg)
+static void Warn(const char* msg_ja, const char* msg_en)
{
- printf("%s\n", msg);
- exit(1);
+#if LANG == 0
+ printf("%s\n", msg_ja);
+#else
+ printf("%s\n", msg_en);
+#endif
}
static void Normalize(double* vec)
@@ -138,7 +155,7 @@ static Bool CmpPoints(const SPoint* a, const SPoint* b)
*/
flag &= Same(a->TexU, b->TexU);
flag &= Same(a->TexV, b->TexV);
- for (int i = 0; i < 4; i++)
+ for (int i = 0; i < JointInfluenceMax; i++)
{
flag &= Same(a->JointWeight[i], b->JointWeight[i]);
flag &= Same(a->Joint[i], b->Joint[i]);
@@ -159,6 +176,9 @@ static void WriteFloat(double n)
static void WriteNode(FbxNode* root)
{
+ WriteInt(1); // Version.
+ WriteInt(Format);
+
int child_num = root->GetChildCount();
{
int cnt = 0;
@@ -167,19 +187,22 @@ static void WriteNode(FbxNode* root)
FbxNode* node = root->GetChild(child);
FbxNodeAttribute* attr = node->GetNodeAttribute();
if (attr == NULL)
- Err("Wrong element.");
+ {
+ Warn("Agr[g̖m[h܂B", "There is a node which has no attributes.");
+ continue;
+ }
switch (attr->GetAttributeType())
{
- case FbxNodeAttribute::eMesh:
- cnt++;
- break;
- case FbxNodeAttribute::eSkeleton:
- case FbxNodeAttribute::eCamera:
- case FbxNodeAttribute::eLight:
- // Do not count.
- break;
- default:
- break;
+ case FbxNodeAttribute::eMesh:
+ cnt++;
+ break;
+ case FbxNodeAttribute::eSkeleton:
+ case FbxNodeAttribute::eCamera:
+ case FbxNodeAttribute::eLight:
+ // Do not count.
+ break;
+ default:
+ break;
}
}
WriteInt(cnt);
@@ -189,372 +212,445 @@ static void WriteNode(FbxNode* root)
FbxNode* node = root->GetChild(child);
FbxNodeAttribute* attr = node->GetNodeAttribute();
if (attr == NULL)
- Err("Wrong element.");
+ continue;
switch (attr->GetAttributeType())
{
- case FbxNodeAttribute::eMesh:
+ case FbxNodeAttribute::eMesh:
+ {
+ WriteInt(0); // Polygon.
+ FbxMesh* mesh = static_cast(attr);
+
+ // Get number of vertices.
+ int vertex_num = mesh->GetPolygonCount() * 3;
+ WriteInt(vertex_num);
+ int* indices = static_cast(malloc(sizeof(int) * static_cast(vertex_num)));
+ for (int i = 0; i < vertex_num / 3; i++)
+ {
+ if (mesh->GetPolygonSize(i) != 3)
{
- WriteInt(0); // Polygon.
- FbxMesh* mesh = static_cast(attr);
-
- // Get number of vertices.
- int vertex_num = mesh->GetPolygonCount() * 3;
- WriteInt(vertex_num);
- int* indices = static_cast(malloc(sizeof(int) * static_cast(vertex_num)));
- for (int i = 0; i < vertex_num / 3; i++)
- {
- if (mesh->GetPolygonSize(i) != 3)
- Err("Wrong number of polygons.");
- for (int j = 0; j < 3; j++)
- indices[i * 3 + j] = mesh->GetPolygonVertex(i, j);
- }
+ Warn("_3ȊÕ|S܂B", "There is a polygon which has non-three vertices.");
+ for (int j = 0; j < 3; j++)
+ indices[i * 3 + j] = 0;
+ continue;
+ }
+ for (int j = 0; j < 3; j++)
+ indices[i * 3 + j] = mesh->GetPolygonVertex(i, j);
+ }
- // Get a normal.
- FbxGeometryElementNormal* normal = mesh->GetElementNormal();
- FbxGeometryElementNormal::EMappingMode normal_mapping = normal->GetMappingMode();
- FbxGeometryElementNormal::EReferenceMode normal_ref = normal->GetReferenceMode();
+ // Get a normal.
+ FbxGeometryElementNormal* normal = mesh->GetElementNormal();
+ FbxGeometryElementNormal::EMappingMode normal_mapping = normal->GetMappingMode();
+ FbxGeometryElementNormal::EReferenceMode normal_ref = normal->GetReferenceMode();
- // Get a UV.
- FbxGeometryElementUV* uv = mesh->GetElementUV();
- FbxGeometryElementNormal::EMappingMode uv_mapping = uv->GetMappingMode();
- FbxGeometryElementNormal::EReferenceMode uv_ref = uv->GetReferenceMode();
+ // Get a UV.
+ FbxGeometryElementUV* uv = mesh->GetElementUV();
+ FbxGeometryElementNormal::EMappingMode uv_mapping = uv->GetMappingMode();
+ FbxGeometryElementNormal::EReferenceMode uv_ref = uv->GetReferenceMode();
- // Get joints.
- int ctrl_point_num = mesh->GetControlPointsCount();
- int joint_num = 0;
- double* joints = NULL;
+ // Get joints.
+ int ctrl_point_num = mesh->GetControlPointsCount();
+ int joint_num = 0;
+ double* joints = NULL;
+ {
+ int skin_num = mesh->GetDeformerCount(FbxDeformer::eSkin);
+ if (skin_num != 0)
+ {
+ FbxSkin* skin = static_cast(mesh->GetDeformer(0, FbxDeformer::eSkin));
+ joint_num = skin->GetClusterCount();
+ joints = static_cast(malloc(sizeof(double) * static_cast(ctrl_point_num * joint_num)));
+ for (int i = 0; i < ctrl_point_num * joint_num; i++)
+ joints[i] = 0.0;
+ for (int i = 0; i < joint_num; i++)
{
- int skin_num = mesh->GetDeformerCount(FbxDeformer::eSkin);
- if (skin_num != 0)
- {
- FbxSkin* skin = static_cast(mesh->GetDeformer(0, FbxDeformer::eSkin));
- joint_num = skin->GetClusterCount();
- joints = static_cast(malloc(sizeof(double) * static_cast(ctrl_point_num * joint_num)));
- for (int i = 0; i < ctrl_point_num * joint_num; i++)
- joints[i] = 0.0;
- for (int i = 0; i < joint_num; i++)
- {
- FbxCluster* cluster = skin->GetCluster(i);
- int cluster_point_num = cluster->GetControlPointIndicesCount();
- int* cluster_points = cluster->GetControlPointIndices();
- double* cluster_weights = cluster->GetControlPointWeights();
- for (int j = 0; j < cluster_point_num; j++)
- joints[cluster_points[j] * joint_num + i] = cluster_weights[j];
- }
- }
+ FbxCluster* cluster = skin->GetCluster(i);
+ int cluster_point_num = cluster->GetControlPointIndicesCount();
+ int* cluster_points = cluster->GetControlPointIndices();
+ double* cluster_weights = cluster->GetControlPointWeights();
+ for (int j = 0; j < cluster_point_num; j++)
+ joints[cluster_points[j] * joint_num + i] = cluster_weights[j];
}
+ }
+ }
- // Get vertices.
- SPoint* points = static_cast(malloc(sizeof(SPoint) * static_cast(vertex_num)));
- FbxVector4* vertices = mesh->GetControlPoints();
- for (int i = 0; i < vertex_num; i++)
- {
- points[i].Unique = True;
+ // Get vertices.
+ SPoint* points = static_cast(malloc(sizeof(SPoint) * static_cast(vertex_num)));
+ FbxVector4* vertices = mesh->GetControlPoints();
+ for (int i = 0; i < vertex_num; i++)
+ {
+ points[i].Unique = True;
- points[i].PosX = vertices[indices[i]][0];
- points[i].PosY = vertices[indices[i]][1];
- points[i].PosZ = vertices[indices[i]][2];
+ points[i].PosX = vertices[indices[i]][0];
+ points[i].PosY = vertices[indices[i]][1];
+ points[i].PosZ = vertices[indices[i]][2];
- if (normal == NULL)
- Err("No normals were found.");
- else
- {
- int v_idx = normal_mapping == FbxGeometryElementNormal::eByPolygonVertex ? i : indices[i];
- int idx = normal_ref == FbxGeometryElementNormal::eDirect ? v_idx : normal->GetIndexArray().GetAt(v_idx);
- FbxVector4 vec = normal->GetDirectArray().GetAt(idx);
- points[i].NormalX = vec[0];
- points[i].NormalY = vec[1];
- points[i].NormalZ = vec[2];
- }
+ if (normal == NULL)
+ {
+ Warn("@̖_܂B", "There is a vertex which has no normals.");
+ points[i].NormalX = 0.0f;
+ points[i].NormalY = 1.0f;
+ points[i].NormalZ = 0.0f;
+ }
+ else
+ {
+ int v_idx = normal_mapping == FbxGeometryElementNormal::eByPolygonVertex ? i : indices[i];
+ int idx = normal_ref == FbxGeometryElementNormal::eDirect ? v_idx : normal->GetIndexArray().GetAt(v_idx);
+ FbxVector4 vec = normal->GetDirectArray().GetAt(idx);
+ points[i].NormalX = vec[0];
+ points[i].NormalY = vec[1];
+ points[i].NormalZ = vec[2];
+ }
- if (uv == NULL)
- Err("No UVs were found.");
- {
- int v_idx = uv_mapping == FbxGeometryElementNormal::eByPolygonVertex ? i : indices[i];
- int idx = uv_ref == FbxGeometryElementNormal::eDirect ? v_idx : uv->GetIndexArray().GetAt(v_idx);
- FbxVector2 vec = uv->GetDirectArray().GetAt(idx);
- points[i].TexU = vec[0];
- points[i].TexV = 1.0 - vec[1]; // Top = 0.0, Bottom is 1.0
- }
+ if (uv == NULL)
+ {
+ Warn("UV̖_܂B", "There is a vertex which has no UVs.");
+ points[i].TexU = 0.0f;
+ points[i].TexV = 0.0f;
+ }
+ else
+ {
+ int v_idx = uv_mapping == FbxGeometryElementNormal::eByPolygonVertex ? i : indices[i];
+ int idx = uv_ref == FbxGeometryElementNormal::eDirect ? v_idx : uv->GetIndexArray().GetAt(v_idx);
+ FbxVector2 vec = uv->GetDirectArray().GetAt(idx);
+ points[i].TexU = vec[0];
+ points[i].TexV = 1.0 - vec[1]; // Top = 0.0, Bottom is 1.0
+ }
- if (joints == NULL)
- {
- if (joint_num != 0)
- Err("No joints were found.");
- for (int j = 0; j < 4; j++)
- {
- points[i].JointWeight[j] = 0.0;
- points[i].Joint[j] = 0;
- }
- }
- else
+ if (joints == NULL || (Format & Format_HasJoint) == 0)
+ {
+ for (int j = 0; j < JointInfluenceMax; j++)
+ {
+ points[i].JointWeight[j] = 0.0;
+ points[i].Joint[j] = 0;
+ }
+ }
+ else
+ {
+ for (int j = 0; j < JointInfluenceMax; j++)
+ {
+ // Get four bones in descending order of weights by selection sort.
+ int joint = -1;
+ double max = 0.0;
+ for (int k = 0; k < joint_num; k++)
{
- for (int j = 0; j < 4; j++)
+ if (max < joints[indices[i] * joint_num + k])
{
- // Get four bones in descending order of weights by selection sort.
- int joint = -1;
- double max = 0.0;
- for (int k = 0; k < joint_num; k++)
{
+ Bool skip = False;
+ for (int l = 0; l < j; l++)
{
- Bool skip = False;
- for (int l = 0; l < j; l++)
+ if (points[i].Joint[l] == k)
{
- if (points[i].Joint[l] == k)
- {
- skip = True;
- break;
- }
+ skip = True;
+ break;
}
- if (skip)
- continue;
- }
- if (max < joints[indices[i] * joint_num + k])
- {
- joint = k;
- max = joints[indices[i] * joint_num + k];
}
+ if (skip)
+ continue;
}
- if (max == 0.0)
- {
- points[i].JointWeight[j] = 0.0;
- points[i].Joint[j] = 0;
- }
- else
- {
- points[i].JointWeight[j] = joints[indices[i] * joint_num + joint];
- points[i].Joint[j] = joint;
- }
- }
- // Normalize weights.
- {
- double sum = 0.0;
- for (int j = 0; j < 4; j++)
- sum += points[i].JointWeight[j];
- if (sum == 0.0)
- Err("The sum of weights must not be zero.");
- for (int j = 0; j < 4; j++)
- points[i].JointWeight[j] /= sum;
+ joint = k;
+ max = joints[indices[i] * joint_num + k];
}
}
- }
-
- // Calculate the tangent and the binormal.
- for (int i = 0; i < vertex_num / 3; i++)
- {
- double tangents[9], binormals[9];
- double normals[9] =
- {
- points[i * 3 + 0].NormalX, points[i * 3 + 0].NormalY, points[i * 3 + 0].NormalZ,
- points[i * 3 + 1].NormalX, points[i * 3 + 1].NormalY, points[i * 3 + 1].NormalZ,
- points[i * 3 + 2].NormalX, points[i * 3 + 2].NormalY, points[i * 3 + 2].NormalZ,
- };
- double ps[9] =
+ if (max == 0.0)
{
- points[i * 3 + 0].PosX, points[i * 3 + 0].PosY, points[i * 3 + 0].PosZ,
- points[i * 3 + 1].PosX, points[i * 3 + 1].PosY, points[i * 3 + 1].PosZ,
- points[i * 3 + 2].PosX, points[i * 3 + 2].PosY, points[i * 3 + 2].PosZ,
- };
- double uvs[6] =
+ points[i].JointWeight[j] = 0.0;
+ points[i].Joint[j] = 0;
+ }
+ else
{
- points[i * 3 + 0].TexU, points[i * 3 + 0].TexV,
- points[i * 3 + 1].TexU, points[i * 3 + 1].TexV,
- points[i * 3 + 2].TexU, points[i * 3 + 2].TexV,
- };
- CalcTangent(tangents, binormals, normals, ps, uvs);
- points[i * 3 + 0].TangentX = tangents[0];
- points[i * 3 + 0].TangentY = tangents[1];
- points[i * 3 + 0].TangentZ = tangents[2];
- points[i * 3 + 1].TangentX = tangents[3];
- points[i * 3 + 1].TangentY = tangents[4];
- points[i * 3 + 1].TangentZ = tangents[5];
- points[i * 3 + 2].TangentX = tangents[6];
- points[i * 3 + 2].TangentY = tangents[7];
- points[i * 3 + 2].TangentZ = tangents[8];
- /*
- points[i * 3 + 0].BinormalX = binormals[0];
- points[i * 3 + 0].BinormalY = binormals[1];
- points[i * 3 + 0].BinormalZ = binormals[2];
- points[i * 3 + 1].BinormalX = binormals[3];
- points[i * 3 + 1].BinormalY = binormals[4];
- points[i * 3 + 1].BinormalZ = binormals[5];
- points[i * 3 + 2].BinormalX = binormals[6];
- points[i * 3 + 2].BinormalY = binormals[7];
- points[i * 3 + 2].BinormalZ = binormals[8];
- */
+ points[i].JointWeight[j] = joints[indices[i] * joint_num + joint];
+ points[i].Joint[j] = joint;
+ }
}
-
- // Invert the Z axis.
- if (Mirror)
+ // Normalize weights.
{
- for (int i = 0; i < vertex_num / 3; i++)
- {
- points[i * 3] = MirrorPoint(&points[i * 3]);
- SPoint p1 = MirrorPoint(&points[i * 3 + 1]);
- SPoint p2 = MirrorPoint(&points[i * 3 + 2]);
- points[i * 3 + 1] = p2;
- points[i * 3 + 2] = p1;
- }
+ double sum = 0.0;
+ for (int j = 0; j < JointInfluenceMax; j++)
+ sum += points[i].JointWeight[j];
+ if (sum == 0.0)
+ Warn("WCg̏d݂̘a0ȊOłȂȂ܂B", "The sum of weights of joints must not be zero.");
+ for (int j = 0; j < JointInfluenceMax; j++)
+ points[i].JointWeight[j] /= sum;
}
+ }
+ }
- // Write the indices.
- int idx_num = 0;
- for (int i = 0; i < vertex_num; i++)
+ // Calculate the tangent and the binormal.
+ if ((Format & Format_HasTangent) != 0)
+ {
+ for (int i = 0; i < vertex_num / 3; i++)
+ {
+ double tangents[9], binormals[9];
+ double normals[9] =
{
- int idx = 0;
- for (int j = 0; j < i; j++)
- {
- if (!points[j].Unique)
- continue;
- if (CmpPoints(&points[i], &points[j]))
- {
- points[i].Unique = False;
- break;
- }
- idx++;
- }
- if (points[i].Unique)
- idx_num++;
- WriteInt(idx);
+ points[i * 3 + 0].NormalX, points[i * 3 + 0].NormalY, points[i * 3 + 0].NormalZ,
+ points[i * 3 + 1].NormalX, points[i * 3 + 1].NormalY, points[i * 3 + 1].NormalZ,
+ points[i * 3 + 2].NormalX, points[i * 3 + 2].NormalY, points[i * 3 + 2].NormalZ,
+ };
+ double ps[9] =
+ {
+ points[i * 3 + 0].PosX, points[i * 3 + 0].PosY, points[i * 3 + 0].PosZ,
+ points[i * 3 + 1].PosX, points[i * 3 + 1].PosY, points[i * 3 + 1].PosZ,
+ points[i * 3 + 2].PosX, points[i * 3 + 2].PosY, points[i * 3 + 2].PosZ,
+ };
+ double uvs[6] =
+ {
+ points[i * 3 + 0].TexU, points[i * 3 + 0].TexV,
+ points[i * 3 + 1].TexU, points[i * 3 + 1].TexV,
+ points[i * 3 + 2].TexU, points[i * 3 + 2].TexV,
+ };
+ CalcTangent(tangents, binormals, normals, ps, uvs);
+ points[i * 3 + 0].TangentX = tangents[0];
+ points[i * 3 + 0].TangentY = tangents[1];
+ points[i * 3 + 0].TangentZ = tangents[2];
+ points[i * 3 + 1].TangentX = tangents[3];
+ points[i * 3 + 1].TangentY = tangents[4];
+ points[i * 3 + 1].TangentZ = tangents[5];
+ points[i * 3 + 2].TangentX = tangents[6];
+ points[i * 3 + 2].TangentY = tangents[7];
+ points[i * 3 + 2].TangentZ = tangents[8];
+ /*
+ points[i * 3 + 0].BinormalX = binormals[0];
+ points[i * 3 + 0].BinormalY = binormals[1];
+ points[i * 3 + 0].BinormalZ = binormals[2];
+ points[i * 3 + 1].BinormalX = binormals[3];
+ points[i * 3 + 1].BinormalY = binormals[4];
+ points[i * 3 + 1].BinormalZ = binormals[5];
+ points[i * 3 + 2].BinormalX = binormals[6];
+ points[i * 3 + 2].BinormalY = binormals[7];
+ points[i * 3 + 2].BinormalZ = binormals[8];
+ */
+ }
+ }
+ else
+ {
+ for (int i = 0; i < vertex_num; i++)
+ {
+ points[i].TangentX = 0.0;
+ points[i].TangentY = 0.0;
+ points[i].TangentZ = 0.0;
+ }
+ }
+
+ // Invert the Z axis.
+ if (Mirror)
+ {
+ for (int i = 0; i < vertex_num / 3; i++)
+ {
+ points[i * 3] = MirrorPoint(&points[i * 3]);
+ SPoint p1 = MirrorPoint(&points[i * 3 + 1]);
+ SPoint p2 = MirrorPoint(&points[i * 3 + 2]);
+ points[i * 3 + 1] = p2;
+ points[i * 3 + 2] = p1;
+ }
+ }
+
+ // Write the indices.
+ int idx_num = 0;
+ for (int i = 0; i < vertex_num; i++)
+ {
+ int idx = 0;
+ for (int j = 0; j < i; j++)
+ {
+ if (!points[j].Unique)
+ continue;
+ if (CmpPoints(&points[i], &points[j]))
+ {
+ points[i].Unique = False;
+ break;
}
+ idx++;
+ }
+ if (points[i].Unique)
+ idx_num++;
+ WriteInt(idx);
+ }
- // Write the vertices.
- WriteInt(idx_num);
+ // Write the vertices.
+ WriteInt(idx_num);
+ {
+ for (int i = 0; i < vertex_num; i++)
+ {
+ if (!points[i].Unique)
+ continue;
+ WriteFloat(points[i].PosX);
+ WriteFloat(points[i].PosY);
+ WriteFloat(points[i].PosZ);
+
+ WriteFloat(points[i].NormalX);
+ WriteFloat(points[i].NormalY);
+ WriteFloat(points[i].NormalZ);
+
+ if ((Format & Format_HasTangent) != 0)
{
- for (int i = 0; i < vertex_num; i++)
- {
- if (!points[i].Unique)
- continue;
- WriteFloat(points[i].PosX);
- WriteFloat(points[i].PosY);
- WriteFloat(points[i].PosZ);
-
- WriteFloat(points[i].NormalX);
- WriteFloat(points[i].NormalY);
- WriteFloat(points[i].NormalZ);
-
- WriteFloat(points[i].TangentX);
- WriteFloat(points[i].TangentY);
- WriteFloat(points[i].TangentZ);
-
- /*
- WriteFloat(points[i].BinormalX);
- WriteFloat(points[i].BinormalY);
- WriteFloat(points[i].BinormalZ);
- */
-
- WriteFloat(points[i].TexU);
- WriteFloat(points[i].TexV);
-
- for (int j = 0; j < 4; j++)
- WriteFloat(points[i].JointWeight[j]);
- for (int j = 0; j < 4; j++)
- WriteInt(points[i].Joint[j]);
- }
+ WriteFloat(points[i].TangentX);
+ WriteFloat(points[i].TangentY);
+ WriteFloat(points[i].TangentZ);
}
- // Write the joints.
- WriteInt(joint_num);
- if (joints == NULL)
+ /*
+ WriteFloat(points[i].BinormalX);
+ WriteFloat(points[i].BinormalY);
+ WriteFloat(points[i].BinormalZ);
+ */
+
+ WriteFloat(points[i].TexU);
+ WriteFloat(points[i].TexV);
+
+ if ((Format & Format_HasJoint) != 0)
{
- WriteInt(0);
- WriteInt(1);
+ for (int j = 0; j < JointInfluenceMax; j++)
+ WriteFloat(points[i].JointWeight[j]);
+ for (int j = 0; j < JointInfluenceMax; j++)
+ WriteInt(points[i].Joint[j]);
}
- else
+ }
+ }
+
+ // Write the joints.
+ WriteInt(joint_num);
+ if (joints == NULL)
+ {
+ WriteInt(0);
+ WriteInt(1);
+ }
+ else
+ {
+ FbxSkin* skin = static_cast(mesh->GetDeformer(0, FbxDeformer::eSkin));
+ FbxTime::EMode time_mode = Scene->GetGlobalSettings().GetTimeMode();
+ if (time_mode != FbxTime::eFrames30 && time_mode != FbxTime::eFrames60)
+ {
+ Warn("^C[h30FPS60FPSłȂȂ܂B", "The time mode must be 30 FPS or 60 FPS.");
+ time_mode = FbxTime::eFrames60;
+ }
+ int begin = 0, end = 0;
+ FbxTime period;
+ {
+ period.SetTime(0, 0, 0, 1, 0, 0, time_mode);
+ FbxArray array_;
+ Scene->FillAnimStackNameArray(array_);
+ int num = array_.GetCount();
+ for (int i = 0; i < num; i++)
{
- FbxSkin* skin = static_cast(mesh->GetDeformer(0, FbxDeformer::eSkin));
- FbxTime::EMode time_mode = Scene->GetGlobalSettings().GetTimeMode();
- if (time_mode != FbxTime::eFrames30 && time_mode != FbxTime::eFrames60)
- Err("Wrong time mode.");
- int begin = 0, end = 0;
- FbxTime period;
+ FbxTakeInfo* info = Scene->GetTakeInfo(*(array_[i]));
+ if (info == NULL)
{
- period.SetTime(0, 0, 0, 1, 0, 0, time_mode);
- FbxArray array_;
- Scene->FillAnimStackNameArray(array_);
- int num = array_.GetCount();
- for (int i = 0; i < num; i++)
- {
- FbxTakeInfo* info = Scene->GetTakeInfo(*(array_[i]));
- if (info == NULL)
- Err("No animations were found.");
- begin = static_cast(info->mLocalTimeSpan.GetStart().Get() / period.Get());
- end = static_cast(info->mLocalTimeSpan.GetStop().Get() / period.Get());
- }
- FbxArrayDelete(array_);
+ Warn("Aj[V܂B", "No animations were found.");
+ begin = 0;
+ end = 0;
}
-
- WriteInt(begin - 1);
- WriteInt(end - 1);
- for (int i = 0; i < joint_num; i++)
+ else
{
- FbxCluster* cluster = skin->GetCluster(i);
+ begin = static_cast(info->mLocalTimeSpan.GetStart().Get() / period.Get());
+ end = static_cast(info->mLocalTimeSpan.GetStop().Get() / period.Get());
+ }
+ }
+ FbxArrayDelete(array_);
+ }
+
+ WriteInt(begin - 1);
+ WriteInt(end - 1);
+ for (int i = 0; i < joint_num; i++)
+ {
+ FbxCluster* cluster = skin->GetCluster(i);
- // Inverse matrix of initial pose.
- FbxAMatrix default_mat;
- cluster->GetTransformLinkMatrix(default_mat);
- default_mat = default_mat.Inverse();
+ // Inverse matrix of initial pose.
+ FbxAMatrix default_mat;
+ cluster->GetTransformLinkMatrix(default_mat);
+ default_mat = default_mat.Inverse();
- // Write animations.
- for (int j = begin; j <= end; j++)
- {
- FbxAMatrix mat;
- mat = cluster->GetLink()->GetAnimationEvaluator()->GetNodeGlobalTransform(cluster->GetLink(), period * j);
- mat = mat * default_mat;
- for (int k = 0; k < 4; k++)
- {
- for (int l = 0; l < 4; l++)
- WriteFloat((Mirror && (k == 2 || l == 2) && k != l ? -1.0 : 1.0) * mat[k][l]);
- }
- }
+ // Write animations.
+ for (int j = begin; j <= end; j++)
+ {
+ FbxAMatrix mat;
+ mat = cluster->GetLink()->GetAnimationEvaluator()->GetNodeGlobalTransform(cluster->GetLink(), period * j);
+ mat = mat * default_mat;
+ for (int k = 0; k < 4; k++)
+ {
+ for (int l = 0; l < 4; l++)
+ WriteFloat((Mirror && (k == 2 || l == 2) && k != l ? -1.0 : 1.0) * mat[k][l]);
}
}
-
- free(joints);
- free(points);
- free(indices);
}
- if (node->GetChildCount() != 0)
- Err("Wrong format.");
- break;
- case FbxNodeAttribute::eSkeleton:
- // Do nothing.
- break;
- case FbxNodeAttribute::eCamera:
- // TODO: Write a camera.
- break;
- case FbxNodeAttribute::eLight:
- // TODO: Write a light.
- break;
- default:
- break;
+ }
+
+ free(joints);
+ free(points);
+ free(indices);
+ }
+ if (node->GetChildCount() != 0)
+ Warn("bVɎqm[h܂Aǂݍ߂܂B", "There is a mesh which has child nodes, but it cannot be read.");
+ break;
+ case FbxNodeAttribute::eSkeleton:
+ // Do nothing.
+ break;
+ case FbxNodeAttribute::eCamera:
+ // TODO: Write a camera.
+ break;
+ case FbxNodeAttribute::eLight:
+ // TODO: Write a light.
+ break;
+ default:
+ break;
}
}
}
int main(int argc, char** argv)
{
- if (argc < 2)
- Err("Usage: knobj_maker [fbx file1] [fbx file2] [...]");
+ if (argc < 3)
+ {
+ const char* usage = "Usage: knobj_maker format [fbx file1] [fbx file2] [...]";
+ Warn(usage, usage);
+ return 0;
+ }
Manager = FbxManager::Create();
if (Manager == NULL)
- Err("Initialization failed.");
+ {
+ Warn("knobj_maker ̏Ɏs܂B", "knobj_maker initialization failed.");
+ return 1;
+ }
Manager->SetIOSettings(FbxIOSettings::Create(Manager, IOSROOT));
Manager->LoadPluginsDirectory(FbxGetApplicationDirectory().Buffer());
Scene = FbxScene::Create(Manager, "");
if (Scene == NULL)
- Err("Initialization failed.");
+ {
+ Warn("knobj_maker ̏Ɏs܂B", "knobj_maker initialization failed.");
+ return 1;
+ }
+
+ Format = atoi(argv[1]);
- for (int i = 1; i < argc; i++)
+ for (int i = 2; i < argc; i++)
{
+ Warn("Ro[gJnł:", "Conversion starts:");
printf("%s\n", argv[i]);
+ if (!PathFileExistsA(argv[i]))
+ {
+ Warn("t@C܂B", "File not found.");
+ continue;
+ }
{
char path[1024];
- strcpy(path, argv[i]);
+ char* pos = strrchr(argv[i], '.');
+ if (pos == NULL)
+ {
+ strcpy(path, argv[i]);
+ }
+ else
+ {
+ strncpy(path, argv[i], pos - argv[i]);
+ path[pos - argv[i]] = '\0';
+ }
strcat(path, ".knobj");
FilePtr = fopen(path, "wb");
+ if (FilePtr == NULL)
+ {
+ Warn("t@C̍쐬Ɏs܂B", "File creation failed.");
+ continue;
+ }
}
{
@@ -567,8 +663,9 @@ int main(int argc, char** argv)
{
FbxNode* root = Scene->GetRootNode();
if (root->GetNodeAttribute() != NULL)
- Err("Wrong format.");
- WriteNode(root);
+ Warn("Agr[g̖m[h܂B", "There is a node which has no attributes.");
+ else
+ WriteNode(root);
}
fclose(FilePtr);
@@ -576,5 +673,6 @@ int main(int argc, char** argv)
Manager->Destroy();
- printf("Success.\n");
+ printf("Done.\n");
+ return 0;
}
diff --git a/src/kuin_editor/add_file.kn b/src/kuin_editor/add_file.kn
index 39eee3a3..957410af 100644
--- a/src/kuin_editor/add_file.kn
+++ b/src/kuin_editor/add_file.kn
@@ -2,57 +2,44 @@ var wndAddFile: wnd@Wnd
var wndAddFileResuiltFile: []char
var wndAddFileResuiltType: int
var wndAddFileEditFile: wnd@Edit
-var wndAddFileListType: wnd@List
+var wndAddFileListType: wnd@ListView
+func addNewFile()
- if(\src@mainSrcDir = "")
- do wnd@msgBox(\form@wndMain, \common@langEn ?("The main source file must be saved before adding another file.", "ファイルを追加する前にメインソースファイルを保存しなければなりません。"), \common@title, %err, %ok)
- ret
- end if
- do @wndAddFile :: wnd@makeWnd(\form@wndMain, (%fix $ wnd@WndStyle).or(%noMinimize), 640, 480, \common@langEn?("Add New File", "新しいファイルを追加"))
+ do @wndAddFile :: wnd@makeWnd(\form@wndMain, (%fix $ wnd@WndStyle).or(%noMinimize), 640, 405, \common@langEn ?("Add New File", "新しいファイルを追加"))
do @wndAddFileResuiltFile :: null
do @wndAddFileResuiltType :: 0
- do @wndAddFileListType :: wnd@makeList(@wndAddFile, 12, 12, 616, 100, %fix, %scale)
- do @wndAddFileListType.add(\common@langEn?("Source Code", "ソースコード"))
- do @wndAddFileListType.add(\common@langEn?("Window", "ウインドウ"))
+ do @wndAddFileListType :: wnd@makeListView(@wndAddFile, 12, 12, 616, 320, %fix, %scale, false, null, ["res/kn.png", "res/wnd.png", "res/draw2d.png"])
+ do @wndAddFileListType.add(\common@langEn?("Source Code", "ソースコード"), 0)
+ do @wndAddFileListType.add(\common@langEn?("Window", "ウインドウ"), 1)
+ do @wndAddFileListType.add(\common@langEn?("2D Draw", "2D描画"), 2)
do @wndAddFileListType.setSel(0)
- do @wndAddFileEditFile :: wnd@makeEdit(@wndAddFile, 12, 118, 510, 19, %fix, %fix)
- var btnFile: wnd@Btn :: wnd@makeBtn(@wndAddFile, 528, 118, 100, 23, %fix, %fix, \common@langEn ?("Browse...", "参照..."))
- do btnFile.onPush :: btnFileOnPush
- var btnAdd: wnd@Btn :: wnd@makeBtn(@wndAddFile, 12, 143, 100, 23, %fix, %fix, \common@langEn ?("Add", "追加"))
+ do @wndAddFileListType.style(%large)
+ do @wndAddFileListType.onSel :: wndAddFileListTypeOnSel
+ do wnd@makeLabel(@wndAddFile, 12, 338, 80, 12, %fix, %fix, \common@langEn ?("File Name:", "ファイル名:"))
+ do @wndAddFileEditFile :: wnd@makeEdit(@wndAddFile, 98, 338, 530, 19, %fix, %fix)
+ do @wndAddFileEditFile.setText(uniqueName(0))
+ do wnd@makeLabel(@wndAddFile, 12, 363, 510, 12, %fix, %fix, \common@langEn ?("If you enter \"abc\" the file will be saved like \"\\abc.kn\"", "「abc」と入力すると「\\abc.kn」のようなファイルで保存され、"))
+ do wnd@makeLabel(@wndAddFile, 12, 381, 510, 12, %fix, %fix, \common@langEn ?("and if you enter \"abc\\def\" it will be \"\\abc\\def.kn\".", "「abc\\def」と入力すると「\\abc\\def.kn」になります。"))
+ var btnAdd: wnd@Btn :: wnd@makeBtn(@wndAddFile, 528, 370, 100, 23, %fix, %fix, \common@langEn ?("Add", "追加"))
do btnAdd.onPush :: btnAddOnPush
do @wndAddFile.modal()
- if(@wndAddFileResuiltFile <>& null & @wndAddFileResuiltFile <> "")
- var ext: []char :: file@ext(@wndAddFileResuiltFile).lower()
+ if(@wndAddFileResuiltFile <>& null)
var doc: \doc@Doc :: null
- var doc2: \doc@Doc :: null
switch(@wndAddFileResuiltType)
case 0
- if(ext = "kn")
- do doc :: #\doc_src@DocSrc
- do doc2 :: #\doc_src@DocSrc
- end if
+ do doc :: #\doc_src@DocSrc
case 1
- if(ext = "knwnd")
- do doc :: #\doc_ar_wnd@DocArWnd
- do doc2 :: #\doc_ar_wnd@DocArWnd
- end if
+ do doc :: #\doc_gen@DocGen
+ do (doc $ \doc_gen@DocGen).create(#\doc_ar_wnd@DocArWnd)
+ case 2
+ do doc :: #\doc_gen@DocGen
+ do (doc $ \doc_gen@DocGen).create(#\doc_ar_2d@DocAr2d)
end switch
if(doc <>& null)
- if(\src@saveImpl(@wndAddFileResuiltFile, doc) & \src@loadFileToDocs(@wndAddFileResuiltFile, doc2))
- do \src@setCurSrc(doc2)
- do \prop@changeProp()
- else
- var msg: []char
- if(\common@langEn)
- do msg :: "Loading failed. " ~ @wndAddFileResuiltFile
- else
- do msg :: "読み込みに失敗しました。 " ~ @wndAddFileResuiltFile
- end if
- do wnd@msgBox(\form@wndMain, msg, \common@title, %err, %ok)
- end if
- else
- do wnd@msgBox(\form@wndMain, \common@langEn ?("An invalid extension was specified.", "不正な拡張子が指定されました。"), \common@title, %err, %ok)
+ do doc.setChanged(true)
+ do \src@docs.add(@wndAddFileResuiltFile, doc)
+ do \src@setCurSrc(doc)
+ do \prop@changeProp()
end if
end if
do @wndAddFile :: null
@@ -60,39 +47,77 @@ var wndAddFileListType: wnd@List
do @wndAddFileEditFile :: null
do @wndAddFileListType :: null
- func btnFileOnPush(wnd: wnd@WndBase)
- var filter: [][]char
- var ext: []char
- switch(@wndAddFileListType.getSel())
- case -1, 0
- do filter :: [\common@langEn ?("Kuin source code (*.kn)", "Kuinソースコード (*.kn)"), "*.kn"]
- do ext :: "kn"
+ func uniqueName(kind: int): []char
+ var name: []char :: null
+ switch(kind)
+ case 0
+ do name :: "src"
case 1
- do filter :: [\common@langEn ?("Kuin window (*.knwnd)", "Kuinウインドウ (*.knwnd)"), "*.knwnd"]
- do ext :: "knwnd"
+ do name :: "wnd"
+ case 2
+ do name :: "draw2d"
+ default
+ ret null
end switch
- var path: []char :: wnd@saveFileDialog(@wndAddFile, filter, 0, ext)
- if(path <>& null)
- do @wndAddFileEditFile.setText(path)
+ var n: int :: 1
+ while(\src@docs.exist("\\" ~ name ~ n.toStr()))
+ do n :+ 1
+ end while
+ ret name ~ n.toStr()
+ end func
+
+ func wndAddFileListTypeOnSel(wnd: wnd@WndBase)
+ var name: []char :: uniqueName(@wndAddFileListType.getSel())
+ if(name <>& null)
+ do @wndAddFileEditFile.setText(name)
end if
end func
func btnAddOnPush(wnd: wnd@WndBase)
- do @wndAddFileResuiltFile :: @wndAddFileEditFile.getText().replace("\\", "/")
+ do @wndAddFileResuiltFile :: @wndAddFileEditFile.getText().trim()
do @wndAddFileResuiltType :: @wndAddFileListType.getSel()
- do @wndAddFile.close()
+ if(@wndAddFileResuiltType = -1)
+ ret
+ end if
+ if(valid(@wndAddFileResuiltFile))
+ do @wndAddFileResuiltFile :: "\\" ~ @wndAddFileResuiltFile
+ if(!\src@docs.exist(@wndAddFileResuiltFile))
+ do @wndAddFile.close()
+ else
+ do wnd@msgBox(\form@wndMain, \common@langEn ?("The file name is already existed.", "そのファイル名は既に存在します。"), \common@title, %err, %ok)
+ do @wndAddFileResuiltFile :: null
+ end if
+ else
+ do wnd@msgBox(\form@wndMain, \common@langEn ?("The file name is invalid.", "ファイル名が不正です。"), \common@title, %err, %ok)
+ do @wndAddFileResuiltFile :: null
+ end if
+
+ func valid(name: []char): bool
+ if(^name = 0)
+ ret false
+ end if
+ if(!('a' <= name[0] & name[0] <= 'z' | name[0] = '_'))
+ ret false
+ end if
+ for i(1, ^name - 1)
+ if(!('a' <= name[i] & name[i] <= 'z' | '0' <= name[i] & name[i] <= '9' | name[i] = '_' | name[i] = '.' | name[i] = '\\'))
+ ret false
+ end if
+ end for
+ ret true
+ end func
end func
end func
+func addExistingFile()
- if(\src@mainSrcDir = "")
- do wnd@msgBox(\form@wndMain, \common@langEn ?("The main source file must be saved before adding another file.", "ファイルを追加する前にメインソースファイルを保存しなければなりません。"), \common@title, %err, %ok)
+ if(\src@mainSrcDir = \common@defaultDir)
+ do wnd@msgBox(\form@wndMain, \common@langEn ?("The main source file must be saved before adding another existed file.", "既存のファイルを追加する前にメインソースファイルを保存しなければなりません。"), \common@title, %err, %ok)
ret
end if
- var file: []char :: wnd@openFileDialog(\form@wndMain, [\common@langEn ?("Kuin supported file (*.kn,*.knwnd)", "Kuinがサポートするファイル (*.kn,*.knwnd)"), "*.kn;*.knwnd"], 0)
+ var file: []char :: wnd@openFileDialog(\form@wndMain, [\common@langEn ?("Kuin supported file (*.kn,*.kngen)", "Kuinがサポートするファイル (*.kn,*.kngen)"), "*.kn;*.kngen"], 0)
if(file <>& null)
- var doc: \doc@Doc :: \src@makeDoc(file)
- if(doc <>& null & \src@loadFileToDocs(file, doc))
+ var doc: \doc@Doc :: \src@loadFileToDocs(file)
+ if(doc <>& null)
do \src@setCurSrc(doc)
do \prop@changeProp()
else
diff --git a/src/kuin_editor/color_sel.kn b/src/kuin_editor/color_sel.kn
new file mode 100644
index 00000000..a17567c6
--- /dev/null
+++ b/src/kuin_editor/color_sel.kn
@@ -0,0 +1,30 @@
+var wndColorSel: wnd@Wnd
+var result: bool
+var color: int
+
++func show(parent: wnd@Wnd, color: int): []char
+ do @color :: color.clamp(0, 0xFFFFFFFF)
+
+ do @wndColorSel :: wnd@makeWnd(\form@wndMain, (%fix $ wnd@WndStyle).or(%noMinimize), 300, 300, \common@langEn ?("Color Selection", "色の選択"))
+
+ var btnOk: wnd@Btn :: wnd@makeBtn(@wndColorSel, 72, 265, 75, 23, %fix, %fix, "OK")
+ do btnOk.onPush :: btnOkOnPush
+ var btnCancel: wnd@Btn :: wnd@makeBtn(@wndColorSel, 153, 265, 75, 23, %fix, %fix, \common@langEn ?("Cancel", "キャンセル"))
+ do btnCancel.onPush :: btnCancelOnPush
+
+ do @result :: false
+ do @wndColorSel.modal()
+
+ do @wndColorSel :: null
+
+ ret @result ?("0x" ~ @color.toStrFmt("08X"), null)
+
+ func btnOkOnPush(wnd: wnd@WndBase)
+ do @result :: true
+ do @wndColorSel.close()
+ end func
+
+ func btnCancelOnPush(wnd: wnd@WndBase)
+ do @wndColorSel.close()
+ end func
+end func
diff --git a/src/kuin_editor/common.kn b/src/kuin_editor/common.kn
index 921dfb42..cd290c03 100644
--- a/src/kuin_editor/common.kn
+++ b/src/kuin_editor/common.kn
@@ -2,9 +2,9 @@
+const cellWidth: int :: 9
+const cellHeight: int :: 18
+const langEn: bool :: false
-+const untitledSrcName: []char :: "_untitled_.kn"
-+const untitledInternalName: []char :: "\\_untitled_"
+const colorBack: int :: 0xFFFFF5F5
++const colorBackLocked: int :: 0xFFFFFFF5
++const defaultDir: []char :: "./"
+var title: []char
+var font: draw@Font
diff --git a/src/kuin_editor/completion.kn b/src/kuin_editor/completion.kn
index 6dc275ba..06175fd5 100644
--- a/src/kuin_editor/completion.kn
+++ b/src/kuin_editor/completion.kn
@@ -3,11 +3,15 @@ var wndCompletionListKeywords: wnd@List
var wndCompletionEditFunc: wnd@EditMulti
var oldX: int
var oldY: int
+var shownX: int
+var shownY: int
var keywords: list<[]char>
+func init()
do @oldX :: -1
do @oldY :: -1
+ do @shownX :: -1
+ do @shownY :: -1
end func
+func show(src: kuin@Class, srcName: []char, posX: int, posY: int, word: []char)
@@ -19,11 +23,19 @@ end func
end if
if(@wndCompletion =& null)
do @keywords :: #list<[]char>
- do \dll@getKeywords(src, srcName, posX, posY, getKeywordsCallback)
+ var funcHint: []char :: \dll@getKeywords(src, srcName, posX, posY, getKeywordsCallback)
+ if(funcHint <>& null & ^funcHint <> 0)
+ do \form@editHint.setText(funcHint)
+ end if
+ if(word =& null | ^word = 0)
+ do @close()
+ ret
+ end if
if(^@keywords = 0)
do @close()
ret
end if
+
do @keywords.sort()
do @wndCompletion :: wnd@makeWnd(\form@wndMain, (%popup $ wnd@WndStyle).or(%layered), 250, 82, null)
@@ -34,17 +46,7 @@ end func
do @wndCompletionListKeywords.onMouseDoubleClick :: @wndCompletionListKeywordsOnMouseDoubleClick
do @wndCompletionEditFunc :: wnd@makeEditMulti(@wndCompletion, 0, 52, 250, 30, %fix, %fix)
do @wndCompletionEditFunc.readonly(true)
- {
- ; TODO:
- if(^funcHint = 0)
- }
- do @wndCompletionEditFunc.setText(\common@langEn ?("Select...Up/Down\nDecide...Enter, Cancel...Esc, Transmit...Ctrl", "選択...Up/Down\n確定...Enter, キャンセル...Esc, 透過...Ctrl"))
- {
- ; TODO:
- else
- do @wndCompletionEditFunc.setText(funcHint)
- end if
- }
+ do @wndCompletionEditFunc.setText(\common@langEn ?("Select...Up/Down\nDecide...Enter, Cancel...Esc, Transmit...Ctrl", "選択...Up/Down\n確定...Enter, キャンセル...Esc, 透過...Ctrl"))
do @wndCompletionListKeywords.setRedraw(false)
do @wndCompletionListKeywords.clear()
@@ -54,6 +56,11 @@ end func
do @keywords.next()
end while
do @wndCompletionListKeywords.setRedraw(true)
+ else
+ if(word =& null | ^word = 0)
+ do @close()
+ ret
+ end if
end if
do @oldX :: posX
@@ -77,19 +84,7 @@ end func
do @wndCompletionListKeywords.setRedraw(true)
end block
- block
- var x: int
- var y: int
- do wnd@getCaretPos(&x, &y)
- if(x < 0 | y < 0)
- ret
- end if
- var x2: int
- var y2: int
- do \form@drawEditor.getPosScreen(&x2, &y2, &, &)
- do @wndCompletion.setPos(x + x2, y + y2 + \common@cellHeight * 2, 250, 82)
- do \form@focusDrawEditor()
- end block
+ do @updatePos()
func wndCompletionOnClose(wnd: wnd@Wnd): bool
do @wndCompletion :: null
@@ -105,6 +100,32 @@ end func
end func
end func
++func updatePos()
+ if(@wndCompletion =& null)
+ ret
+ end if
+
+ var x: int
+ var y: int
+ do wnd@getCaretPos(&x, &y)
+ if(x < 0 | y < 0)
+ ret
+ end if
+ var x2: int
+ var y2: int
+ do \form@drawEditor.getPosScreen(&x2, &y2, &, &)
+ var x3: int :: x + x2
+ var y3: int :: y + y2
+ if(@shownX = x3 & @shownY = y3)
+ do \form@focusDrawEditor()
+ ret
+ end if
+ do @shownX :: x3
+ do @shownY :: y3
+ do @wndCompletion.setPos(x3, y3 + \common@cellHeight * 2, 250, 82)
+ do \form@focusDrawEditor()
+end func
+
+func wndCompletionListKeywordsOnSel(wnd: wnd@List)
{
; TODO:
@@ -141,6 +162,8 @@ end func
end if
do @oldX :: -1
do @oldY :: -1
+ do @shownX :: -1
+ do @shownY :: -1
do @keywords :: null
end func
diff --git a/src/kuin_editor/dbgwnd.kn b/src/kuin_editor/dbgwnd.kn
new file mode 100644
index 00000000..d7336898
--- /dev/null
+++ b/src/kuin_editor/dbgwnd.kn
@@ -0,0 +1,73 @@
+class CallStack()
+end class
+
+class Watch()
+end class
+
++var wndDbg: wnd@Wnd
+var wndDbgEditMsg: wnd@EditMulti
+var wndDbgListCallStack: wnd@List
+var wndDbgListWatch: wnd@ListView
+var callStacks: list<@CallStack>
+var watchs: list<@Watch>
+
++func show()
+ var x: int
+ var y: int
+ var w: int
+ do \form@drawEditor.getPosScreen(&x, &y, &w, &)
+ if(@wndDbg =& null)
+ do @wndDbg :: wnd@makeWnd(\form@wndMain, (%fix $ wnd@WndStyle).or(%noMinimize), 480, 392, \common@langEn ?("Debug", "デバッグ"))
+ do @wndDbg.onClose :: wndDbgOnClose
+ do @wndDbgEditMsg :: wnd@makeEditMulti(@wndDbg, 12, 12, 456, 42, %scale, %fix)
+ do @wndDbgEditMsg.readonly(true)
+ do @wndDbgListCallStack :: wnd@makeList(@wndDbg, 12, 60, 225, 320, %fix, %scale)
+ do @wndDbgListWatch :: wnd@makeListView(@wndDbg, 243, 60, 225, 320, %scale, %scale, false, null, null)
+ do @wndDbgListWatch.addColumn(\common@langEn ?("Variable Name", "変数名"))
+ do @wndDbgListWatch.addColumn(\common@langEn ?("Value", "値"))
+ end if
+
+ func wndDbgOnClose(wnd: wnd@Wnd): bool
+ do @wndDbg :: null
+ do @wndDbgListCallStack :: null
+ do @wndDbgListWatch :: null
+ do @callStacks :: null
+ do @watchs :: null
+ ret true
+ end func
+end func
+
++func clear()
+ if(@wndDbg =& null)
+ ret
+ end if
+
+ do @wndDbgEditMsg.setText("")
+ do @wndDbgListCallStack.clear()
+ do @wndDbgListWatch.clear()
+end func
+
++func setMsg(str: []char)
+ if(@wndDbg =& null)
+ ret
+ end if
+
+ do @wndDbgEditMsg.setText(str)
+end func
+
++func addCallStack(str: []char)
+ if(@wndDbg =& null)
+ ret
+ end if
+
+ do @wndDbgListCallStack.add(str)
+end func
+
++func addWatch(str1: []char, str2: []char)
+ if(@wndDbg =& null)
+ ret
+ end if
+
+ do @wndDbgListWatch.add(str1, -1)
+ do @wndDbgListWatch.setText(@wndDbgListWatch.len() - 1, 1, str2, -1)
+end func
diff --git a/src/kuin_editor/dll.kn b/src/kuin_editor/dll.kn
index 5af3f2e5..7951d65d 100644
--- a/src/kuin_editor/dll.kn
+++ b/src/kuin_editor/dll.kn
@@ -4,13 +4,13 @@ end func
+func [d0917.knd, FinCompiler] finCompiler()
end func
-+func [d0917.knd, BuildMem] build(path: []char, funcGetSrc: func<([]char): [][]char>, sysDir: []char, output: []char, icon: []char, rls_: bool, env: []char, funcLog: func<([][]char, int, int)>, lang: int, appCode: int): bool
++func [d0917.knd, BuildMem] build(path: []char, funcGetSrc: func<([]char): [][]char>, sysDir: []char, output: []char, icon: []char, relatedFiles: list<[]char>, rls_: bool, env_: []char, funcLog: func<([][]char, int, int)>, lang: int, appCode: int): bool
end func
+func [d0917.knd, Interpret1] interpret1(src: kuin@Class, line: int, me_: kuin@Class, replaceFunc: func<(kuin@Class, int, []char)>, cursorX: int, cursorY: int, newCursorX: &int, oldLine: int, newLine: int)
end func
-+func [d0917.knd, Interpret2] interpret2(path: []char, funcGetSrc: func<([]char): [][]char>, sysDir: []char, env: []char, funcLog: func<([][]char, int, int)>, lang: int): bool
++func [d0917.knd, Interpret2] interpret2(path: []char, funcGetSrc: func<([]char): [][]char>, sysDir: []char, env_: []char, funcLog: func<([][]char, int, int)>, lang: int): bool
end func
+func [d0917.knd, Version] version(major: &int, minor: &int, micro: &int)
@@ -22,10 +22,13 @@ end func
; TODO: +func [d0917.knd, GetHint] getHint(bufIdx: int, src: []char, row: int, keyword: []char, hintSrc: &[]char, hintRow: &int, hintCol: &int): []char
; end func
-+func [d0917.knd, GetKeywords] getKeywords(src: kuin@Class, srcName: []char, x: int, y: int, callback: func<([]char)>)
++func [d0917.knd, GetKeywords] getKeywords(src: kuin@Class, srcName: []char, x: int, y: int, callback: func<([]char)>): []char
end func
-+func [d0917.knd, RunDbg] runDbg(name: []char, cmdLine: []char, idleFunc: func<()>, eventFunc: func<(int, []char): int>): bool
++func [d0917.knd, RunDbg] runDbg(name: []char, cmdLine: []char, idleFunc: func<()>, eventFunc: func<(int, []char): int>, breakPointsFunc: func<()>, breakFunc: func<(int, \src@Pos, []char)>, dbgFunc: func<(int, []char, []char)>): bool
+end func
+
++func [d0917.knd, SetBreakPoints] setBreakPoints(breakPoints: []\src@Pos)
end func
+func [d0917.knd, Archive] archive(dst: []char, src: []char, appCode: int): bool
diff --git a/src/kuin_editor/doc.kn b/src/kuin_editor/doc.kn
index e55d3615..85cad139 100644
--- a/src/kuin_editor/doc.kn
+++ b/src/kuin_editor/doc.kn
@@ -1,7 +1,5 @@
+class Doc()
*func ctor()
- do me.undo :: #undo@Undo
- do me.undo.init(1024)
do me.changed :: false
end func
@@ -9,7 +7,7 @@
do me.undo :: null
end func
- +func update()
+ +func fix()
end func
+func load(path: []char): bool
@@ -18,34 +16,10 @@
+func save(path: []char): bool
end func
- +func draw(width: int, height: int)
- end func
-
- +func updateProp(listView: wnd@ListView)
- end func
-
- +func updateTree(tree: wnd@TreeMulti)
- end func
-
- +func updateList(list_: wnd@List)
- end func
-
- +func treeItemOnSel()
- end func
-
- +func treeItemOnMoveNode()
- end func
-
- +func listObjOnSel()
- end func
-
- +func listPropOnSel(listView: wnd@ListView)
+ +func getSrc(): [][]char
end func
- +func listPropOnMouseClick(listView: wnd@ListView)
- end func
-
- +func listPropOnMouseDoubleClick(listView: wnd@ListView)
+ +func draw(width: int, height: int)
end func
+func mouseDownL(x: int, y: int)
@@ -63,6 +37,9 @@
+func focus(isFocus: bool)
end func
+ +func updateScrollBar()
+ end func
+
+func keyDown(key: wnd@Key, shiftCtrl: wnd@ShiftCtrl): bool
end func
@@ -114,10 +91,42 @@
+func getSelCode(): []char
end func
- +var changed: bool
+ +func getCursorWord(): []char
+ ret null
+ end func
+
+ +func updateUi()
+ end func
+
+ +func onEvent(event: @Event)
+ end func
+
+ +func getChanged(): bool
+ ret me.changed
+ end func
+
+ +func setChanged(value: bool)
+ do me.changed :: value
+ end func
+
+ var changed: bool
var undo: undo@Undo
end class
++enum Event
+ listLtOnMouseClick
+ listLbOnMouseClick
+ listLbOnMoveNode
+ listRbOnMouseClick
+ editRbArNameOnKillFocus
+ chkRbArVisibleOnPush
+ editRbArXOnKillFocus
+ editRbArYOnKillFocus
+ editRbArWidthOnKillFocus
+ editRbArHeightOnKillFocus
+ btnRbArPropOnPush
+end enum
+
+class UndoCmd(undo@Cmd)
+var doc: @Doc
end class
diff --git a/src/kuin_editor/doc_ar.kn b/src/kuin_editor/doc_ar.kn
index 94ba8f3d..d2818af3 100644
--- a/src/kuin_editor/doc_ar.kn
+++ b/src/kuin_editor/doc_ar.kn
@@ -1,461 +1,363 @@
-+class DocArBase(\doc@Doc)
++class DocAr(\doc_gen@DocDesigner)
*func ctor()
do super(me)
+ do me.undo :: #undo@Undo
+ do me.undo.init(1024)
+
+ do me.nodes :: #list<@Obj>
+ do me.holds :: #list<@Obj>
+ do me.clipboard :: #list<@Obj>
do me.scrollOffsetX :: 10
do me.scrollOffsetY :: 40
do me.pageX :: -me.scrollOffsetX
do me.pageY :: -me.scrollOffsetY
do me.mode :: %none
- do me.holds :: #list<@Obj2d>
- do me.ctrl :: 0
- end func
-
- +*func update()
- end func
-
- +*func load(path: []char): bool
- try
- var xml: xml@Xml :: xml@makeXml(path)
- var node: xml@Node :: xml.root().lastChild()
- do loadRecursion(me, node, me.obj2dRoot)
- catch
- ret false
- end try
- ret true
-
- func loadRecursion(doc: @DocArBase, xmlNode: xml@Node, obj2dNode: @Obj2d)
- do obj2dNode.load(xmlNode)
- var node: xml@Node :: xmlNode.firstChild()
- while(node <>& null)
- var newObj2dNode: @Obj2d :: doc.makeObj2d(node.getName())
- do loadRecursion(doc, node, newObj2dNode)
- do newObj2dNode.parent :: obj2dNode
- do obj2dNode.children.add(newObj2dNode)
- do node :: node.next()
- end while
- end func
+ do me.updatingProp :: false
end func
- +*func save(path: []char): bool
- try
- var xml: xml@Xml :: xml@makeXmlEmpty()
- var root: xml@Node :: xml.root()
- do saveRecursion(root, me.obj2dRoot)
- do xml.save(path, false)
- catch
- ret false
- end try
- ret true
-
- func saveRecursion(xmlParentNode: xml@Node, obj2dNode: @Obj2d)
- var node: xml@Node :: xmlParentNode.addChild(obj2dNode.getName())
- do obj2dNode.save(node)
- do obj2dNode.children.head()
- while(!obj2dNode.children.term())
- do saveRecursion(node, obj2dNode.children.get())
- do obj2dNode.children.next()
- end while
- end func
+ +*func getSrc(): [][]char
+ ret me.src
end func
+*func draw(width: int, height: int)
do draw@rect(0.0, 0.0, width $ float, height $ float, \common@colorBack)
- do drawRecursion(me.obj2dRoot, me.pageX, me.pageY, me.holds)
- if(me.mode = %select)
- do draw@rectLine((me.holdOffsetX - me.pageX) $ float, (me.holdOffsetY - me.pageY) $ float, (me.selectOffsetX - me.holdOffsetX) $ float, (me.selectOffsetY - me.holdOffsetY) $ float, 0xFF6666FF)
- end if
-
- func drawRecursion(obj: @Obj2d, pageX: int, pageY: int, holds: list<@Obj2d>)
- do holds.head()
- if(holds.find(obj))
- do draw@rectLine((obj.absX - 3 - pageX) $ float, (obj.absY - 3 - pageY) $ float, (obj.width + 6) $ float, (obj.height + 6) $ float, 0xFF6666FF)
- do draw@rectLine((obj.absX - 4 - pageX) $ float, (obj.absY - 4 - pageY) $ float, (obj.width + 8) $ float, (obj.height + 8) $ float, 0xFF6666FF)
- end if
- do obj.draw(pageX, pageY)
- do obj.children.head()
- while(!obj.children.term())
- do drawRecursion(obj.children.get(), pageX, pageY, holds)
- do obj.children.next()
- end while
- end func
- end func
-
- +*func updateProp(listView: wnd@ListView)
- do me.holds.head()
- while(!me.holds.term())
- var obj: @Obj2d :: me.holds.get()
- var parent: @Obj2d :: obj.parent
- var x: int :: 0
- var y: int :: 0
- if(parent <>& null)
- do x :: parent.absX
- do y :: parent.absY
- end if
- do obj.updateProp(listView, x, y)
- do me.holds.next()
- end while
- end func
-
- +*func updateTree(tree: wnd@TreeMulti)
- var sels: list :: #list
- do updateTreeRecursion(me.holds, tree.root(), me.obj2dRoot, sels)
- do tree.setSel(sels.toArray())
-
- func updateTreeRecursion(holds: list<@Obj2d>, node: wnd@TreeNode, obj: @Obj2d, sels: list)
- var node2: wnd@TreeNode :: node.addChild(obj.objName)
- do holds.head()
- if(holds.find(obj))
- do sels.add(node2)
- end if
- do obj.children.head()
- while(!obj.children.term())
- do updateTreeRecursion(holds, node2, obj.children.get(), sels)
- do obj.children.next()
- end while
- end func
- end func
-
- +*func updateList(list_: wnd@List)
- do me.addCtrlList(list_)
- do list_.setSel(me.ctrl)
- end func
-
- +*func treeItemOnSel()
- var sels: []wnd@TreeNode :: \form@treeItem.getSel()
- do me.holds :: #list<@Obj2d>
- do selRecursion(\form@treeItem.root().firstChild(), me.obj2dRoot, sels, me.holds)
- do \form@paintDrawEditor()
-
- func selRecursion(node: wnd@TreeNode, obj: @Obj2d, sels: []wnd@TreeNode, holds: list<@Obj2d>)
- if(sels.find(node, 0) <> -1)
- do holds.add(obj)
- end if
- do obj.children.head()
- var node2: wnd@TreeNode :: node.firstChild()
- while(!obj.children.term() & node2 <>& null)
- do selRecursion(node2, obj.children.get(), sels, holds)
- do node2 :: node2.next()
- do obj.children.next()
- end while
- end func
- end func
-
- +*func treeItemOnMoveNode()
- do delParentRecursion(me.obj2dRoot)
- do me.obj2dRoot :: updateObjRecursion(\form@treeItem.root().firstChild(), me.obj2dRoot) $ @Obj2dRoot
- do me.changed :: true
- do \form@updateTree()
- do \form@paintDrawEditor()
-
- func delParentRecursion(obj: @Obj2d)
- do obj.parent :: null
- do obj.children.head()
- while(!obj.children.term())
- do delParentRecursion(obj.children.get())
- do obj.children.next()
- end while
- end func
-
- func updateObjRecursion(node: wnd@TreeNode, objRoot: @Obj2d): @Obj2d
- var obj: @Obj2d :: searchRecursion(node.getName(), objRoot)
- var newObj: @Obj2d :: ##obj
- do newObj.parent :: null
- do newObj.children :: #list<@Obj2d>
- var node2: wnd@TreeNode :: node.firstChild()
- while(node2 <>& null)
- var child: @Obj2d :: updateObjRecursion(node2, objRoot)
- do child.parent :: newObj
- do newObj.children.add(child)
- do node2 :: node2.next()
- end while
- ret newObj
-
- func searchRecursion(name: []char, obj: @Obj2d): @Obj2d
- if(name = obj.objName)
- ret obj
- end if
- do obj.children.head()
- while(!obj.children.term())
- var result: @Obj2d :: searchRecursion(name, obj.children.get())
- if(result <>& null)
- ret result
- end if
- do obj.children.next()
- end while
- ret null
- end func
- end func
- end func
-
- +*func listObjOnSel()
- var sel: int :: \form@listObj.getSel()
- do me.ctrl :: sel < 0 ?(0, sel)
- end func
-
- +*func listPropOnSel(listView: wnd@ListView)
- end func
-
- +*func listPropOnMouseClick(listView: wnd@ListView)
- end func
-
- +*func listPropOnMouseDoubleClick(listView: wnd@ListView)
- if(^me.holds = 0)
- ret
- end if
- var sel: int :: listView.getSel()
- if(sel = -1)
- ret
- end if
- var prop: []char :: listView.getText(sel, 0)
- var value: []char :: listView.getText(sel, 1)
- do me.holds.head()
- do value :: wndex@inputBox(\form@wndMain, me.holds.get().objName ~ "." ~ prop, \common@title, value, null)
- if(value =& null)
- ret
- end if
-
- do me.holds.head()
-
- var value2: int
- switch(prop)
- case "x"
- if(value.toInt(&value2))
- var parentValue: int
- if(me.holds.get().parent =& null)
- do parentValue :: 0
- else
- do parentValue :: me.holds.get().parent.absX
+ block
+ if(^me.holds = 0)
+ var objX: int
+ var objY: int
+ var objWidth: int
+ var objHeight: int
+ do me.resizeObj(me.root, me.curOriginX, me.curOriginY, &objX, &objY, &objWidth, &objHeight)
+ var x: float :: (objX - me.pageX) $ float
+ var y: float :: (objY - me.pageY) $ float
+ var width2: float :: objWidth $ float
+ var height2: float :: objHeight $ float
+ if(me.root.visible)
+ do me.root.draw(x, y, width2, height2, \form@zoom)
end if
- do value :: (value2 + parentValue).toStr()
+ do draw@rectLine((x - 3.0) * \form@zoom, (y - 3.0) * \form@zoom, (width2 + 6.0) * \form@zoom, (height2 + 6.0) * \form@zoom, 0xFF6666FF)
+ do draw@rectLine((x - 4.0) * \form@zoom, (y - 4.0) * \form@zoom, (width2 + 8.0) * \form@zoom, (height2 + 8.0) * \form@zoom, 0xFF6666FF)
+ do draw@rectLine(x * \form@zoom, y * \form@zoom, width2 * \form@zoom, height2 * \form@zoom, 0x80000000)
else
- ret
+ var x: float :: (me.root.x - me.pageX) $ float
+ var y: float :: (me.root.y - me.pageY) $ float
+ var width2: float :: me.root.width $ float
+ var height2: float :: me.root.height $ float
+ if(me.root.visible)
+ do me.root.draw(x, y, width2, height2, \form@zoom)
+ end if
+ do draw@rectLine(x * \form@zoom, y * \form@zoom, width2 * \form@zoom, height2 * \form@zoom, 0x80000000)
end if
- case "y"
- if(value.toInt(&value2))
- var parentValue: int
- if(me.holds.get().parent =& null)
- do parentValue :: 0
- else
- do parentValue :: me.holds.get().parent.absY
+ end block
+ do me.nodes.head()
+ while(!me.nodes.term())
+ var node: @Obj :: me.nodes.get()
+ do me.holds.head()
+ if(me.holds.find(node))
+ var objX: int
+ var objY: int
+ var objWidth: int
+ var objHeight: int
+ do me.resizeObj(node, me.curOriginX, me.curOriginY, &objX, &objY, &objWidth, &objHeight)
+ var x: float :: (objX - me.pageX) $ float
+ var y: float :: (objY - me.pageY) $ float
+ var width2: float :: objWidth $ float
+ var height2: float :: objHeight $ float
+ if(node.visible)
+ do node.draw(x, y, width2, height2, \form@zoom)
end if
- do value :: (value2 + parentValue).toStr()
+ do draw@rectLine((x - 3.0) * \form@zoom, (y - 3.0) * \form@zoom, (width2 + 6.0) * \form@zoom, (height2 + 6.0) * \form@zoom, 0xFF6666FF)
+ do draw@rectLine((x - 4.0) * \form@zoom, (y - 4.0) * \form@zoom, (width2 + 8.0) * \form@zoom, (height2 + 8.0) * \form@zoom, 0xFF6666FF)
+ do draw@blend(%exclusion)
+ do draw@rectLine(x * \form@zoom, y * \form@zoom, width2 * \form@zoom, height2 * \form@zoom, 0xFF808080)
+ do draw@blend(%alpha)
else
- ret
+ var x: float :: (node.x - me.pageX) $ float
+ var y: float :: (node.y - me.pageY) $ float
+ var width2: float :: node.width $ float
+ var height2: float :: node.height $ float
+ if(node.visible)
+ do node.draw(x, y, width2, height2, \form@zoom)
+ end if
+ do draw@blend(%exclusion)
+ do draw@rectLine(x * \form@zoom, y * \form@zoom, width2 * \form@zoom, height2 * \form@zoom, 0xFF808080)
+ do draw@blend(%alpha)
end if
- case "absolute_x"
- do prop :: "x"
- case "absolute_y"
- do prop :: "y"
- end switch
-
- while(!me.holds.term())
- do me.holds.get().setProp(prop, value)
- do me.holds.next()
+ do me.nodes.next()
end while
- do me.changed :: true
- do \form@updateProp()
- do \form@paintDrawEditor()
+
+ if(me.mode = %sel)
+ do draw@rectLine((me.holdOriginX - me.pageX) $ float * \form@zoom, (me.holdOriginY - me.pageY) $ float * \form@zoom, (me.curOriginX - me.holdOriginX) $ float * \form@zoom, (me.curOriginY - me.holdOriginY) $ float * \form@zoom, 0xFF6666FF)
+ end if
end func
+*func mouseDownL(x: int, y: int)
- var x2: int :: x + me.pageX
- var y2: int :: y + me.pageY
- if(me.ctrl <= 0)
- var obj: @Obj2d :: selRecursion(me.obj2dRoot, x2, y2)
-
- do me.holdOffsetX :: x2
- do me.holdOffsetY :: y2
- if(obj <>& null & obj.absX + obj.width - resizeArea <= x2 & obj.absY + obj.height - resizeArea <= y2)
- do me.mode :: %resize
- elif(obj =& null | obj =& me.obj2dRoot)
- do me.mode :: %select
- do me.selectOffsetX :: x2
- do me.selectOffsetY :: y2
- else
- do me.mode :: %move
+ var x2: int :: (x $ float / \form@zoom) $ int + me.pageX
+ var y2: int :: (y $ float / \form@zoom) $ int + me.pageY
+ do me.holdOriginX :: x2
+ do me.holdOriginY :: y2
+ do me.curOriginX :: x2
+ do me.curOriginY :: y2
+
+ var idx: int :: \form@listLt.getSel()
+ if(idx <= 0)
+ var sel: @Obj :: null
+ do me.nodes.tail()
+ while loop(!me.nodes.term())
+ var obj: @Obj :: me.nodes.get()
+ if(obj.x <= x2 & x2 <= obj.x + obj.width & obj.y <= y2 & y2 <= obj.y + obj.height)
+ do sel :: obj
+ break loop
+ end if
+ do me.nodes.prev()
+ end while
+ if(sel =& null & me.root.x <= x2 & x2 <= me.root.x + me.root.width & me.root.y <= y2 & y2 <= me.root.y + me.root.height)
+ do sel :: me.root
end if
- if(obj =& null)
- do obj :: me.obj2dRoot
+ if(sel =& null)
+ do me.mode :: %sel
+ elif(sel <> me.root)
+ var resizeAreaX: int
+ var resizeAreaY: int
+ do @getResizeArea(&resizeAreaX, &resizeAreaY, sel.width, sel.height)
+ if(sel.x + sel.width - resizeAreaX <= x2)
+ if (\form@getLockingEditor())
+ do \form@showMsgRunning()
+ ret
+ end if
+ if(sel.y + sel.height - resizeAreaY <= y2)
+ do me.mode :: %resizeRB
+ elif(y2 <= sel.y + resizeAreaY)
+ do me.mode :: %resizeRT
+ else
+ do me.mode :: %resizeR
+ end if
+ elif(x2 <= sel.x + resizeAreaX)
+ if (\form@getLockingEditor())
+ do \form@showMsgRunning()
+ ret
+ end if
+ if(sel.y + sel.height - resizeAreaY <= y2)
+ do me.mode :: %resizeLB
+ elif(y2 <= sel.y + resizeAreaY)
+ do me.mode :: %resizeLT
+ else
+ do me.mode :: %resizeL
+ end if
+ elif(sel.y + sel.height - resizeAreaY <= y2)
+ if (\form@getLockingEditor())
+ do \form@showMsgRunning()
+ ret
+ end if
+ do me.mode :: %resizeB
+ elif(y2 <= sel.y + resizeAreaY)
+ if (\form@getLockingEditor())
+ do \form@showMsgRunning()
+ ret
+ end if
+ do me.mode :: %resizeT
+ else
+ do me.mode :: %move
+ end if
+ else
+ var resizeAreaX: int
+ var resizeAreaY: int
+ do @getResizeArea(&resizeAreaX, &resizeAreaY, sel.width, sel.height)
+ if(sel.x + sel.width - resizeAreaX <= x2)
+ if (\form@getLockingEditor())
+ do \form@showMsgRunning()
+ ret
+ end if
+ if(sel.y + sel.height - resizeAreaY <= y2)
+ do me.mode :: %resizeRB
+ else
+ do me.mode :: %resizeR
+ end if
+ elif(sel.y + sel.height - resizeAreaY <= y2)
+ if (\form@getLockingEditor())
+ do \form@showMsgRunning()
+ ret
+ end if
+ do me.mode :: %resizeB
+ else
+ do me.mode :: %sel
+ end if
end if
- var found: bool :: me.holds.find(obj)
- if(!wnd@key(%shift) & !wnd@key(%ctrl) & !found)
- do me.holds :: #list<@Obj2d>
+ if(sel =& me.root)
+ do sel :: null
end if
- if(!found)
- do me.holds.add(obj)
+ if(sel =& null)
+ if(!wnd@key(%shift) & !wnd@key(%ctrl))
+ do me.holds :: #list<@Obj>
+ end if
+ else
+ do me.holds.head()
+ if (!me.holds.find(sel))
+ if(wnd@key(%shift) | wnd@key(%ctrl))
+ do me.holds.add(sel)
+ else
+ do me.holds :: #list<@Obj>
+ do me.holds.add(sel)
+ end if
+ end if
end if
+ do \form@updateUi()
else
if (\form@getLockingEditor())
do \form@showMsgRunning()
ret
end if
- var name: []char :: \form@listObj.getText(me.ctrl)
- do me.mode :: %put
- do me.holdOffsetX :: x2
- do me.holdOffsetY :: y2
- var obj: @Obj2d :: me.makeObj2d(name)
- var minWidth: int
- var minHeight: int
- do obj.getMinMaxSize(&minWidth, &minHeight, &, &)
- do obj.init(me.getDefaultName(name), x2, y2, minWidth, minHeight)
- if(^me.holds = 0)
- do obj.parent :: me.obj2dRoot
- do me.obj2dRoot.children.add(obj)
- else
- do me.holds.head()
- do obj.parent :: me.holds.get()
- do me.holds.get().children.add(obj)
+ var name: []char :: \form@listLt.getText(&, idx, 0)
+ var parent: []char :: null
+ if(^me.holds > 0)
+ do me.holds.tail()
+ do me.nodes.head()
+ if(me.nodes.find(me.holds.get()))
+ do me.nodes.next()
+ if(!me.nodes.term())
+ do parent :: me.nodes.get().name
+ end if
+ end if
end if
- do me.holds :: #list<@Obj2d>
+ do me.mode :: %put
+ do me.undo.recordBegin()
+ do me.holds :: #list<@Obj>
+ var objX: int
+ var objY: int
+ var objWidth: int
+ var objHeight: int
+ var obj: @Obj :: me.put(parent, name, @getDefaultName(name.lower(), me.nodes), true, x2, y2, -1, -1, null, true)
do me.holds.add(obj)
+ do me.resizeObj(obj, 0, 0, &objX, &objY, &objWidth, &objHeight)
+ do me.move(obj.name, objX, objY, objWidth, objHeight, true)
+ do me.undo.recordEnd()
+ do \form@updateUi()
end if
- do me.changed :: true
do \form@paintDrawEditor()
-
- func selRecursion(obj: @Obj2d, x: int, y: int): @Obj2d
- var result: @Obj2d :: null
- if(obj.absX <= x & x <= obj.absX + obj.width & obj.absY <= y & y <= obj.absY + obj.height)
- do result :: obj
- end if
- do obj.children.head()
- while(!obj.children.term())
- var result2: @Obj2d :: selRecursion(obj.children.get(), x, y)
- if(result2 <>& null)
- do result :: result2
- end if
- do obj.children.next()
- end while
- ret result
- end func
end func
+*func mouseUpL(x: int, y: int)
switch(me.mode)
- case %put
+ case %put, %move, %resizeLT, %resizeRT, %resizeLB, %resizeRB, %resizeL, %resizeT, %resizeR, %resizeB
if (\form@getLockingEditor())
do \form@showMsgRunning()
ret
end if
- do me.resizeObj2d(x + me.pageX, y + me.pageY)
- do me.mode :: %none
- do me.ctrl :: 0
- do me.holds :: #list<@Obj2d>
- do \form@updateTree()
- do \form@updateProp()
- do \form@paintDrawEditor()
- case %move
- if (\form@getLockingEditor())
- do \form@showMsgRunning()
- ret
+ var arrangedX: int :: (x $ float / \form@zoom) $ int + me.pageX
+ var arrangedY: int :: (y $ float / \form@zoom) $ int + me.pageY
+ do me.arrange(&arrangedX, &arrangedY)
+ do me.undo.recordBegin()
+ var objX: int
+ var objY: int
+ var objWidth: int
+ var objHeight: int
+ if(^me.holds = 0)
+ do me.resizeObj(me.root, arrangedX, arrangedY, &objX, &objY, &objWidth, &objHeight)
+ do me.move(null, objX, objY, objWidth, objHeight, true)
+ else
+ do me.holds.head()
+ while(!me.holds.term())
+ var obj: @Obj :: me.holds.get()
+ do me.resizeObj(obj, arrangedX, arrangedY, &objX, &objY, &objWidth, &objHeight)
+ do me.move(obj.name, objX, objY, objWidth, objHeight, true)
+ do me.holds.next()
+ end while
end if
- do me.moveObj2d(x + me.pageX, y + me.pageY)
+ do me.undo.recordEnd()
do me.mode :: %none
- do \form@updateTree()
- do \form@updateProp()
- do \form@paintDrawEditor()
- case %resize
- if (\form@getLockingEditor())
- do \form@showMsgRunning()
- ret
+ if(me.mode = %put)
+ do \form@listLt.setSel(0)
end if
- do me.resizeObj2d(x + me.pageX, y + me.pageY)
- do me.mode :: %none
- do \form@updateTree()
- do \form@updateProp()
+ do \form@updateUi()
do \form@paintDrawEditor()
- case %select
- var x1: int :: me.holdOffsetX
- var y1: int :: me.holdOffsetY
- var x2: int :: x + me.pageX
- var y2: int :: y + me.pageY
+ case %sel
+ var x1: int :: me.holdOriginX
+ var y1: int :: me.holdOriginY
+ var x2: int :: (x $ float / \form@zoom) $ int + me.pageX
+ var y2: int :: (y $ float / \form@zoom) $ int + me.pageY
if(x1 > x2)
do x1 :$ x2
end if
if(y1 > y2)
do y1 :$ y2
end if
- do me.holds :: #list<@Obj2d>
- do selRecursion(me.obj2dRoot, me.obj2dRoot, x1, y1, x2, y2, me.holds)
- if(^me.holds = 0)
- do me.holds.add(me.obj2dRoot)
+ if(!wnd@key(%shift) & !wnd@key(%ctrl))
+ do me.holds :: #list<@Obj>
end if
+ do me.nodes.head()
+ while(!me.nodes.term())
+ var node: @Obj :: me.nodes.get()
+ if(node.x <= x2 & x1 <= node.x + node.width & node.y <= y2 & y1 <= node.y + node.height)
+ do me.holds.add(node)
+ end if
+ do me.nodes.next()
+ end while
do me.mode :: %none
- do \form@updateTree()
- do \form@updateProp()
+ do \form@updateUi()
do \form@paintDrawEditor()
end switch
-
- func selRecursion(root: @Obj2d, obj: @Obj2d, x: int, y: int, x2: int, y2: int, sels: list<@Obj2d>)
- var result: @Obj2d :: null
- if(obj <>& root & obj.absX <= x2 & x <= obj.absX + obj.width & obj.absY <= y2 & y <= obj.absY + obj.height)
- do sels.add(obj)
- end if
- do obj.children.head()
- while(!obj.children.term())
- do selRecursion(root, obj.children.get(), x, y, x2, y2, sels)
- do obj.children.next()
- end while
- end func
end func
+*func mouseDoubleClick(x: int, y: int)
- ; TODO:
end func
+*func mouseMove(x: int, y: int)
switch(me.mode)
- case %put
- if (\form@getLockingEditor())
- do \form@showMsgRunning()
- ret
- end if
- do me.resizeObj2d(x + me.pageX, y + me.pageY)
- do me.holdOffsetX :: x + me.pageX
- do me.holdOffsetY :: y + me.pageY
- do \form@paintDrawEditor()
- case %move
- if (\form@getLockingEditor())
- do \form@showMsgRunning()
- ret
- end if
- do me.moveObj2d(x + me.pageX, y + me.pageY)
- do me.holdOffsetX :: x + me.pageX
- do me.holdOffsetY :: y + me.pageY
- do \form@paintDrawEditor()
- case %resize
+ case %put, %move, %resizeLT, %resizeRT, %resizeLB, %resizeRB, %resizeL, %resizeT, %resizeR, %resizeB
if (\form@getLockingEditor())
do \form@showMsgRunning()
ret
end if
- do me.resizeObj2d(x + me.pageX, y + me.pageY)
- do me.holdOffsetX :: x + me.pageX
- do me.holdOffsetY :: y + me.pageY
+ var arrangedX: int :: (x $ float / \form@zoom) $ int + me.pageX
+ var arrangedY: int :: (y $ float / \form@zoom) $ int + me.pageY
+ do me.arrange(&arrangedX, &arrangedY)
+ do me.curOriginX :: arrangedX
+ do me.curOriginY :: arrangedY
+ do me.updateProp()
do \form@paintDrawEditor()
- case %select
- do me.selectOffsetX :: x + me.pageX
- do me.selectOffsetY :: y + me.pageY
+ case %sel
+ do me.curOriginX :: (x $ float / \form@zoom) $ int + me.pageX
+ do me.curOriginY :: (y $ float / \form@zoom) $ int + me.pageY
do \form@paintDrawEditor()
end switch
end func
+*func focus(isFocus: bool)
if(isFocus)
- do me.refreshScroll()
+ do me.updateScrollBar()
end if
end func
+ +*func updateScrollBar()
+ var padding: int :: (50.0 / \form@zoom) $ int
+ var screenWidth: int
+ var screenHeight: int
+ do \form@drawEditor.getPos(&, &, &screenWidth, &screenHeight)
+ if(me.pageX > me.root.width + padding - me.scrollOffsetX - ((screenWidth $ float / \form@zoom) $ int - me.scrollOffsetX))
+ do me.pageX :: me.root.width + padding - me.scrollOffsetX - ((screenWidth $ float / \form@zoom) $ int - me.scrollOffsetX)
+ end if
+ if (me.pageX < -me.scrollOffsetX)
+ do me.pageX :: -me.scrollOffsetX
+ end if
+ if(me.pageY > me.root.height + padding - me.scrollOffsetY - ((screenHeight $ float / \form@zoom) $ int - me.scrollOffsetY))
+ do me.pageY :: me.root.height + padding - me.scrollOffsetY - ((screenHeight $ float / \form@zoom) $ int - me.scrollOffsetY)
+ end if
+ if (me.pageY < -me.scrollOffsetY)
+ do me.pageY :: -me.scrollOffsetY
+ end if
+ do \form@scrollXSrc.setState(me.root.x, me.root.width + padding, (screenWidth $ float / \form@zoom) $ int - me.scrollOffsetX, me.pageX + me.scrollOffsetX)
+ do \form@scrollYSrc.setState(me.root.y, me.root.height + padding, (screenHeight $ float / \form@zoom) $ int - me.scrollOffsetY, me.pageY + me.scrollOffsetY)
+ end func
+
+*func keyDown(key: wnd@Key, shiftCtrl: wnd@ShiftCtrl): bool
- ; TODO:
end func
+*func keyUp(key: wnd@Key, shiftCtrl: wnd@ShiftCtrl)
- ; TODO:
end func
+*func keyChar(key: char)
- ; TODO:
end func
+*func scrollX(pos: int)
@@ -469,43 +371,87 @@
end func
+*func wheelX(wheel: int)
- ; TODO:
end func
+*func wheelY(wheel: int)
- ; TODO:
end func
+*func setMouseImg(): wnd@MouseImg
switch(me.mode)
case %none
- if(^me.holds <> 0)
- var x: int
- var y: int
- do input@mousePos(&x, &y)
- do \form@drawEditor.screenToClient(&x, &y, x, y)
- do x :+ me.pageX
- do y :+ me.pageY
- do me.holds.head()
- while(!me.holds.term())
- var obj: @Obj2d :: me.holds.get()
- if(obj.absX <= x & obj.absY <= y & x <= obj.absX + obj.width & y <= obj.absY + obj.height)
- if(obj.absX + obj.width - resizeArea <= x & obj.absY + obj.height - resizeArea <= y)
- ret %resizeLTRD
+ var x: int
+ var y: int
+ do input@mousePos(&x, &y)
+ do \form@drawEditor.screenToClient(&x, &y, x, y)
+ do x :: (x $ float / \form@zoom) $ int + me.pageX
+ do y :: (y $ float / \form@zoom) $ int + me.pageY
+ do me.nodes.tail()
+ while(!me.nodes.term())
+ var obj: @Obj :: me.nodes.get()
+ if(obj.x <= x & x <= obj.x + obj.width & obj.y <= y & y <= obj.y + obj.height)
+ var resizeAreaX: int
+ var resizeAreaY: int
+ do @getResizeArea(&resizeAreaX, &resizeAreaY, obj.width, obj.height)
+ if(obj.x + obj.width - resizeAreaX <= x)
+ if(obj.y + obj.height - resizeAreaY <= y)
+ ret %resizeLTRB
+ end if
+ if(y <= obj.y + resizeAreaY)
+ ret %resizeRTLB
end if
- ret %move
+ ret %resizeH
end if
- do me.holds.next()
- end while
+ if(x <= obj.x + resizeAreaX)
+ if(obj.y + obj.height - resizeAreaY <= y)
+ ret %resizeRTLB
+ end if
+ if(y <= obj.y + resizeAreaY)
+ ret %resizeLTRB
+ end if
+ ret %resizeH
+ end if
+ if(obj.y + obj.height - resizeAreaY <= y)
+ ret %resizeV
+ end if
+ if(y <= obj.y + resizeAreaY)
+ ret %resizeV
+ end if
+ ret %move
+ end if
+ do me.nodes.prev()
+ end while
+ if(me.root.x <= x & x <= me.root.x + me.root.width & me.root.y <= y & y <= me.root.y + me.root.height)
+ var resizeAreaX: int
+ var resizeAreaY: int
+ do @getResizeArea(&resizeAreaX, &resizeAreaY, me.root.width, me.root.height)
+ if(me.root.x + me.root.width - resizeAreaX <= x)
+ if(me.root.y + me.root.height - resizeAreaY <= y)
+ ret %resizeLTRB
+ end if
+ ret %resizeH
+ end if
+ if(me.root.y + me.root.height - resizeAreaY <= y)
+ ret %resizeV
+ end if
end if
ret %arrow
case %put
ret %cross
case %move
ret %move
- case %resize
- ret %resizeLTRD
- case %select
+ case %resizeLT,%resizeRB
+ ret %resizeLTRB
+ case %resizeRT,%resizeLB
+ ret %resizeRTLB
+ case %resizeL
+ ret %resizeH
+ case %resizeT
+ ret %resizeV
+ case %resizeR
+ ret %resizeH
+ case %resizeB
+ ret %resizeV
+ case %sel
ret %cross
default
assert false
@@ -513,315 +459,1080 @@
end func
+*func cmdUndo()
- ; TODO:
+ if(\form@getLockingEditor())
+ do \form@showMsgRunning()
+ ret
+ end if
+ do me.undo.undo()
+ do \form@updateUi()
+ do \form@paintDrawEditor()
end func
+*func cmdRedo()
- ; TODO:
+ if(\form@getLockingEditor())
+ do \form@showMsgRunning()
+ ret
+ end if
+ do me.undo.redo()
+ do \form@updateUi()
+ do \form@paintDrawEditor()
end func
+*func cmdCut()
- ; TODO:
+ if(^me.holds = 0)
+ ret
+ end if
+ do me.cmdCopy()
+ do me.cmdDel()
end func
+*func cmdCopy()
- ; TODO:
+ if(^me.holds = 0)
+ ret
+ end if
+ do me.clipboard :: #list<@Obj>
+ do me.holds.head()
+ while(!me.holds.term())
+ do me.clipboard.add(me.cloneObj(me.holds.get()))
+ do me.holds.next()
+ end while
end func
+*func cmdPaste()
- ; TODO:
+ if(^me.clipboard = 0)
+ ret
+ end if
+ do me.undo.recordBegin()
+ do me.clipboard.head()
+ do me.holds :: #list<@Obj>
+ while(!me.clipboard.term())
+ var obj: @Obj :: me.clipboard.get()
+ var kind: []char :: obj.kind()
+ do me.holds.add(me.put(null, kind, @getDefaultName(kind.lower(), me.nodes), obj.visible, obj.x, obj.y, obj.width, obj.height, ##obj.props, true))
+ do me.clipboard.next()
+ end while
+ do me.undo.recordEnd()
+ do \form@updateUi()
+ do \form@paintDrawEditor()
end func
+*func cmdDel()
- if(^me.holds = 0)
+ do me.undo.recordBegin()
+ do me.holds.head()
+ while(!me.holds.term())
+ do me.del(me.holds.get().name, true)
+ do me.holds.del()
+ end while
+ do me.undo.recordEnd()
+ do \form@updateUi()
+ do \form@paintDrawEditor()
+ end func
+
+ +*func cmdSelAll()
+ do me.holds :: #list<@Obj>
+ do me.nodes.head()
+ while(!me.nodes.term())
+ do me.holds.add(me.nodes.get())
+ do me.nodes.next()
+ end while
+ do \form@updateUi()
+ do \form@paintDrawEditor()
+ end func
+
+ +*func undoImpl(undo2: \doc@UndoCmd)
+ if(undo2 =$ UndoArPut)
+ var undo3: UndoArPut :: undo2 $ UndoArPut
+ do me.holds :: #list<@Obj>
+ do me.holds.add(me.put(undo3.parent, undo3.kind, undo3.name, undo3.visible, undo3.x, undo3.y, undo3.width, undo3.height, undo3.props, false))
+ elif(undo2 =$ UndoArDel)
+ var undo3: UndoArDel :: undo2 $ UndoArDel
+ do me.del(undo3.name, false)
+ elif(undo2 =$ UndoArMove)
+ var undo3: UndoArMove :: undo2 $ UndoArMove
+ do me.move(undo3.name, undo3.x, undo3.y, undo3.width, undo3.height, false)
+ elif(undo2 =$ UndoArOrder)
+ var undo3: UndoArOrder :: undo2 $ UndoArOrder
+ do me.order(undo3.names, false)
+ elif(undo2 =$ UndoArRename)
+ var undo3: UndoArRename :: undo2 $ UndoArRename
+ do me.rename(undo3.name, undo3.newName, false)
+ elif(undo2 =$ UndoArVisible)
+ var undo3: UndoArVisible :: undo2 $ UndoArVisible
+ do me.visible(undo3.name, undo3.value, false)
+ elif(undo2 =$ UndoArProp)
+ var undo3: UndoArProp :: undo2 $ UndoArProp
+ do me.prop(undo3.name, undo3.prop, undo3.value, false)
+ else
+ assert false
+ end if
+ end func
+
+ +*func getSelCode(): []char
+ ret null
+ end func
+
+ +*func updateUi()
+ do \form@listLt.setRedraw(false)
+ do \form@listLt.clear()
+ do \form@listLt.style(%large)
+ do \form@listLt.add(\common@langEn ?("Pointer", "ポインタ"), 0)
+ do me.updateLt()
+ do \form@listLt.setRedraw(true)
+
+ do \form@listLb.setRedraw(false)
+ do \form@listLb.clear()
+ do \form@listLb.style(%list_)
+ var parentStack: stack<@Obj> :: #stack<@Obj>
+ do me.nodes.head()
+ while(!me.nodes.term())
+ var obj: @Obj :: me.nodes.get()
+ do @getParent(parentStack, obj)
+ do \form@listLb.add(">".repeat(^parentStack) ~ obj.name, obj.icon())
+ if(obj.becomeParent())
+ do parentStack.add(obj)
+ end if
+ do me.holds.head()
+ if(me.holds.find(obj))
+ do \form@listLb.setSelMulti(\form@listLb.len() - 1, true)
+ end if
+ do me.nodes.next()
+ end while
+ do \form@listLb.setRedraw(true)
+
+ do me.updateProp()
+ end func
+
+ +*func onEvent(event: \doc@Event)
+ if(me.updatingProp)
ret
end if
- do delRecursion(\form@treeItem.root().firstChild(), me.obj2dRoot, me.holds)
- do me.changed :: true
- do \form@updateTree()
- do \form@updateProp()
- do \form@paintDrawEditor()
+ switch(event)
+ case %listLtOnMouseClick
+ case %listLbOnMouseClick
+ do me.holds :: #list<@Obj>
+ var len: int :: \form@listLb.len()
+ for i(0, len - 1)
+ if(\form@listLb.getSelMulti(i))
+ var name: []char :: @removePrefix(\form@listLb.getText(&, i, 0))
+ do me.find(me.nodes, name)
+ do me.holds.add(me.nodes.get())
+ end if
+ end for
+ do me.updateProp()
+ do \form@paintDrawEditor()
+ case %listLbOnMoveNode
+ var len: int :: \form@listLb.len()
+ var names: [][]char :: #[len][]char
+ for i(0, len - 1)
+ do names[i] :: @removePrefix(\form@listLb.getText(&, i, 0))
+ end for
+ do me.undo.recordBegin()
+ do me.order(names, true)
+ do me.undo.recordEnd()
+ do \form@paintDrawEditor()
+ do \form@updateUi()
+ case %listRbOnMouseClick
+ case %editRbArNameOnKillFocus
+ if(^me.holds <> 1)
+ ret
+ end if
+ do me.holds.head()
+ var obj: @Obj :: me.holds.get()
+ var name: []char :: \form@editRbArName.getText().trim()
+ do me.find(me.nodes, name)
+ if(me.nodes.term() & me.root.name <> name)
+ do me.undo.recordBegin()
+ do me.rename(obj.name, name, true)
+ do me.undo.recordEnd()
+ do \form@paintDrawEditor()
+ end if
+ do \form@updateUi()
+ case %chkRbArVisibleOnPush
+ var data: lib@Bool :: #lib@Bool
+ do data.value :: \form@chkRbArVisible.getChk()
+ do me.updateMultiple(chk, apply, data)
+
+ func chk(obj: @Obj, data: lib@Bool): bool
+ ret obj.visible <> data.value
+ end func
- func delRecursion(node: wnd@TreeNode, obj: @Obj2d, holds: list<@Obj2d>): bool
- var node2: wnd@TreeNode :: node.firstChild()
- do obj.children.head()
- while(!obj.children.term() & node2 <>& null)
- var childObj: @Obj2d :: obj.children.get()
- do holds.head()
- if(holds.find(childObj))
- do node.delChild(node2)
- do obj.children.del()
- ret true
+ func apply(me_: @DocAr, obj: @Obj, data: lib@Bool)
+ do me_.visible(obj =& me_.root ?(null, obj.name), data.value, true)
+ end func
+ case %editRbArXOnKillFocus
+ if(^me.holds = 0)
+ do \form@updateUi()
+ ret
+ end if
+ var success: bool
+ var value: int :: \form@editRbArX.getText().trim().toInt(&success)
+ if(success)
+ if(value < 0)
+ do value :: 0
end if
- if(delRecursion(node2, childObj, holds))
- ret true
+ var data: lib@Int :: #lib@Int
+ do data.value :: value
+ do me.updateMultiple(chk, apply, data)
+ else
+ do \form@updateUi()
+ end if
+
+ func chk(obj: @Obj, data: lib@Int): bool
+ ret obj.x <> data.value
+ end func
+
+ func apply(me_: @DocAr, obj: @Obj, data: lib@Int)
+ do me_.move(obj =& me_.root ?(null, obj.name), data.value, obj.y, obj.width, obj.height, true)
+ end func
+ case %editRbArYOnKillFocus
+ if(^me.holds = 0)
+ do \form@updateUi()
+ ret
+ end if
+ var success: bool
+ var value: int :: \form@editRbArY.getText().trim().toInt(&success)
+ if(success)
+ if(value < 0)
+ do value :: 0
end if
- do node2 :: node2.next()
- do obj.children.next()
- end while
- ret false
- end func
+ var data: lib@Int :: #lib@Int
+ do data.value :: value
+ do me.updateMultiple(chk, apply, data)
+ else
+ do \form@updateUi()
+ end if
+
+ func chk(obj: @Obj, data: lib@Int): bool
+ ret obj.y <> data.value
+ end func
+
+ func apply(me_: @DocAr, obj: @Obj, data: lib@Int)
+ do me_.move(obj =& me_.root ?(null, obj.name), obj.x, data.value, obj.width, obj.height, true)
+ end func
+ case %editRbArWidthOnKillFocus
+ var success: bool
+ var value: int :: \form@editRbArWidth.getText().trim().toInt(&success)
+ if(success)
+ var data: lib@Int :: #lib@Int
+ do data.value :: value
+ do me.updateMultiple(chk, apply, data)
+ else
+ do \form@updateUi()
+ end if
+
+ func chk(obj: @Obj, data: lib@Int): bool
+ var value: int :: data.value
+ var minValue: int
+ var maxValue: int
+ do obj.getMinMax(&minValue, &, &maxValue, &)
+ if(value < minValue)
+ do value :: minValue
+ elif(value > maxValue)
+ do value :: maxValue
+ end if
+ ret obj.width <> value
+ end func
+
+ func apply(me_: @DocAr, obj: @Obj, data: lib@Int)
+ var value: int :: data.value
+ var minValue: int
+ var maxValue: int
+ do obj.getMinMax(&minValue, &, &maxValue, &)
+ if(value < minValue)
+ do value :: minValue
+ elif(value > maxValue)
+ do value :: maxValue
+ end if
+ do me_.move(obj =& me_.root ?(null, obj.name), obj.x, obj.y, value, obj.height, true)
+ end func
+ case %editRbArHeightOnKillFocus
+ var success: bool
+ var value: int :: \form@editRbArHeight.getText().trim().toInt(&success)
+ if(success)
+ var data: lib@Int :: #lib@Int
+ do data.value :: value
+ do me.updateMultiple(chk, apply, data)
+ else
+ do \form@updateUi()
+ end if
+
+ func chk(obj: @Obj, data: lib@Int): bool
+ var value: int :: data.value
+ var minValue: int
+ var maxValue: int
+ do obj.getMinMax(&, &minValue, &, &maxValue)
+ if(value < minValue)
+ do value :: minValue
+ elif(value > maxValue)
+ do value :: maxValue
+ end if
+ ret obj.height <> value
+ end func
+
+ func apply(me_: @DocAr, obj: @Obj, data: lib@Int)
+ var value: int :: data.value
+ var minValue: int
+ var maxValue: int
+ do obj.getMinMax(&, &minValue, &, &maxValue)
+ if(value < minValue)
+ do value :: minValue
+ elif(value > maxValue)
+ do value :: maxValue
+ end if
+ do me_.move(obj =& me_.root ?(null, obj.name), obj.x, obj.y, obj.width, value, true)
+ end func
+ case %btnRbArPropOnPush
+ var objs: []@Obj
+ if(^me.holds = 0)
+ do objs :: [me.root]
+ else
+ do objs :: me.holds.toArray()
+ end if
+ if(\obj_prop@show(objs))
+ do me.changed :: true
+ for i(0, ^objs - 1)
+ do objs[i].reloadRes()
+ end for
+ end if
+ do \form@updateUi()
+ do \form@paintDrawEditor()
+ end switch
end func
- +*func cmdSelAll()
- ; TODO:
+ +*func loadImpl(xmlNode: xml@Node)
+ var root: xml@Node :: xmlNode.findChild("root").firstChild()
+ do me.root :: me.makeObj(root.getName())
+ do me.root.load(root)
+ var child: xml@Node :: xmlNode.findChild("children").firstChild()
+ do me.nodes :: #list<@Obj>
+ while(child <>& null)
+ var node: @Obj :: me.makeObj(child.getName())
+ do node.load(child)
+ do me.nodes.add(node)
+ do child :: child.next()
+ end while
end func
- +*func undoImpl(undo2: \doc@UndoCmd)
- ; TODO:
+ +*func saveImpl(xmlNode: xml@Node)
+ var root: xml@Node :: xmlNode.addChild("root")
+ block
+ var node: xml@Node :: root.addChild(me.root.kind())
+ do me.root.save(node)
+ end block
+ var children: xml@Node :: xmlNode.addChild("children")
+ do me.nodes.head()
+ while(!me.nodes.term())
+ var obj: @Obj :: me.nodes.get()
+ var node: xml@Node :: children.addChild(obj.kind())
+ do obj.save(node)
+ do me.nodes.next()
+ end while
+ end func
+
+ func makeObj(name: []char): @Obj
end func
- const padding: int :: 32
- const resizeArea: int :: 6
- const stickingArea: int :: 6
+ func updateLt()
+ end func
enum Mode
none
put
move
- resize
- select
+ resizeLT
+ resizeRT
+ resizeLB
+ resizeRB
+ resizeL
+ resizeT
+ resizeR
+ resizeB
+ sel
end enum
var src: [][]char
- var obj2dRoot: @Obj2dRoot
+ +var root: @Obj
+ var nodes: list<@Obj>
+ var holds: list<@Obj>
+ var clipboard: list<@Obj>
+ var scrollOffsetX: int
+ var scrollOffsetY: int
+ var holdOriginX: int
+ var holdOriginY: int
+ var curOriginX: int
+ var curOriginY: int
var pageX: int
var pageY: int
var mode: Mode
- var holds: list<@Obj2d>
- var ctrl: int
- var holdOffsetX: int
- var holdOffsetY: int
- var scrollOffsetX: int
- var scrollOffsetY: int
- var selectOffsetX: int
- var selectOffsetY: int
+ var updatingProp: bool
- +func makeObj2d(name: []char): @Obj2d
- end func
+ func resizeObj(obj: @Obj, x: int, y: int, objX: &int, objY: &int, objWidth: &int, objHeight: &int)
+ var x2: int :: x - me.holdOriginX
+ var y2: int :: y - me.holdOriginY
+ var modX: int
+ var modY: int
+ switch(me.mode)
+ case %none, %sel
+ do objX :: obj.x
+ do objY :: obj.y
+ do objWidth :: obj.width
+ do objHeight :: obj.height
+ ret
+ case %put
+ do objX :: round(&, obj.x)
+ do objY :: round(&, obj.y)
+ do objWidth :: round(&, obj.width)
+ do objHeight :: round(&, obj.height)
+ case %move
+ do objX :: round(&, obj.x + x2)
+ do objY :: round(&, obj.y + y2)
+ do objWidth :: obj.width
+ do objHeight :: obj.height
+ case %resizeLT
+ do objX :: round(&modX, obj.x + x2)
+ do objY :: round(&modY, obj.y + y2)
+ do objWidth :: obj.width - x2 + modX
+ do objHeight :: obj.height - y2 + modY
+ case %resizeRT
+ do objX :: obj.x
+ do objY :: round(&modY, obj.y + y2)
+ do objWidth :: round(&, obj.width + x2)
+ do objHeight :: obj.height - y2 + modY
+ case %resizeLB
+ do objX :: round(&modX, obj.x + x2)
+ do objY :: obj.y
+ do objWidth :: obj.width - x2 + modX
+ do objHeight :: round(&, obj.height + y2)
+ case %put, %resizeRB
+ do objX :: obj.x
+ do objY :: obj.y
+ do objWidth :: round(&, obj.width + x2)
+ do objHeight :: round(&, obj.height + y2)
+ case %resizeL
+ do objX :: round(&modX, obj.x + x2)
+ do objY :: obj.y
+ do objWidth :: obj.width - x2 + modX
+ do objHeight :: obj.height
+ case %resizeT
+ do objX :: obj.x
+ do objY :: round(&modY, obj.y + y2)
+ do objWidth :: obj.width
+ do objHeight :: obj.height - y2 + modY
+ case %resizeR
+ do objX :: obj.x
+ do objY :: obj.y
+ do objWidth :: round(&, obj.width + x2)
+ do objHeight :: obj.height
+ case %resizeB
+ do objX :: obj.x
+ do objY :: obj.y
+ do objWidth :: obj.width
+ do objHeight :: round(&, obj.height + y2)
+ end switch
- func addCtrlList(ctrlList: wnd@List)
- do ctrlList.add(\common@langEn ?("none", "なし"))
- end func
+ var minWidth: int
+ var minHeight: int
+ var maxWidth: int
+ var maxHeight: int
+ do obj.getMinMax(&minWidth, &minHeight, &maxWidth, &maxHeight)
+ if(objX < 0)
+ do objX :: 0
+ end if
+ if(objY < 0)
+ do objY :: 0
+ end if
+ if(objWidth < minWidth)
+ do objWidth :: minWidth
+ elif(objWidth > maxWidth)
+ do objWidth :: maxWidth
+ end if
+ if(objHeight < minHeight)
+ do objHeight :: minHeight
+ elif(objHeight > maxHeight)
+ do objHeight :: maxHeight
+ end if
- func refreshScroll()
- var screenWidth: int
- var screenHeight: int
- do \form@drawEditor.getPos(&, &, &screenWidth, &screenHeight)
- do \form@scrollXSrc.setState(me.obj2dRoot.absX, me.obj2dRoot.width + padding, screenWidth, me.pageX + me.scrollOffsetX)
- do \form@scrollYSrc.setState(me.obj2dRoot.absY, me.obj2dRoot.height + padding, screenHeight, me.pageY + me.scrollOffsetY)
+ func round(mod: &int, value: int): int
+ if(\form@snap)
+ do mod :: value % \form@snapValue
+ ret value / \form@snapValue * \form@snapValue
+ else
+ do mod :: 0
+ ret value
+ end if
+ end func
end func
- func getDefaultName(name: []char): []char
- var num: int :: 1
- var newName: []char
- while loop(true)
- do newName :: name ~ num.toStr()
- if(!searchRecursion(newName, me.obj2dRoot))
- break loop
+ func arrange(x: &int, y: &int)
+ if(wnd@key(%shift))
+ if((x - me.holdOriginX).abs() > (y - me.holdOriginY).abs())
+ do y :: me.holdOriginY
+ else
+ do x :: me.holdOriginX
end if
- do num :+ 1
- end while
- ret newName
+ end if
+ end func
- func searchRecursion(name: []char, obj: @Obj2d): bool
- if(name = obj.objName)
- ret true
+ class UndoAr(\doc@UndoCmd)
+ +*func cmd()
+ do me.doc.undoImpl(me)
+ end func
+ end class
+
+ class UndoArPut(UndoAr)
+ +var parent: []char
+ +var kind: []char
+ +var name: []char
+ +var visible: bool
+ +var x: int
+ +var y: int
+ +var width: int
+ +var height: int
+ +var props: dict<[]char, []char>
+ end class
+
+ class UndoArDel(UndoAr)
+ +var name: []char
+ end class
+
+ class UndoArMove(UndoAr)
+ +var name: []char
+ +var x: int
+ +var y: int
+ +var width: int
+ +var height: int
+ end class
+
+ class UndoArOrder(UndoAr)
+ +var names: [][]char
+ end class
+
+ class UndoArRename(UndoAr)
+ +var name: []char
+ +var newName: []char
+ end class
+
+ class UndoArVisible(UndoAr)
+ +var name: []char
+ +var value: bool
+ end class
+
+ class UndoArProp(UndoAr)
+ +var name: []char
+ +var prop: []char
+ +var value: []char
+ end class
+
+ func updateProp()
+ do me.updatingProp :: true
+
+ var name: []char
+ var visible: bool
+ var objXStr: []char
+ var objYStr: []char
+ var objWidthStr: []char
+ var objHeightStr: []char
+ if(^me.holds <= 1)
+ var obj: @Obj
+ if(^me.holds = 0)
+ do obj :: me.root
+ else
+ do me.holds.head()
+ do obj :: me.holds.get()
end if
- do obj.children.head()
- while(!obj.children.term())
- if(searchRecursion(name, obj.children.get()))
- ret true
+ do name :: obj.name
+ do visible :: obj.visible
+ var objX: int
+ var objY: int
+ var objWidth: int
+ var objHeight: int
+ do me.resizeObj(obj, me.curOriginX, me.curOriginY, &objX, &objY, &objWidth, &objHeight)
+ do objXStr :: objX.toStr()
+ do objYStr :: objY.toStr()
+ do objWidthStr :: objWidth.toStr()
+ do objHeightStr :: objHeight.toStr()
+ else
+ var obj: @Obj
+ do name :: \common@langEn ?("(Multiple)", "(複数)")
+ var sameVisible: bool :: true
+ var sameX: bool :: true
+ var sameY: bool :: true
+ var sameWidth: bool :: true
+ var sameHeight: bool :: true
+ var objX: int
+ var objY: int
+ var objWidth: int
+ var objHeight: int
+ do me.holds.head()
+ do obj :: me.holds.get()
+ do visible :: obj.visible
+ do me.resizeObj(obj, me.curOriginX, me.curOriginY, &objX, &objY, &objWidth, &objHeight)
+ do me.holds.next()
+ while(!me.holds.term())
+ var objX2: int
+ var objY2: int
+ var objWidth2: int
+ var objHeight2: int
+ do obj :: me.holds.get()
+ do me.resizeObj(obj, me.curOriginX, me.curOriginY, &objX2, &objY2, &objWidth2, &objHeight2)
+ if(visible <> obj.visible)
+ do sameVisible :: false
+ end if
+ if(objX <> objX2)
+ do sameX :: false
end if
- do obj.children.next()
+ if(objY <> objY2)
+ do sameY :: false
+ end if
+ if(objWidth <> objWidth2)
+ do sameWidth :: false
+ end if
+ if(objHeight <> objHeight2)
+ do sameHeight :: false
+ end if
+ do me.holds.next()
end while
- ret false
- end func
+ do visible :: sameVisible ?(visible, false)
+ do objXStr :: sameX ?(objX.toStr(), "*")
+ do objYStr :: sameY ?(objY.toStr(), "*")
+ do objWidthStr :: sameWidth ?(objWidth.toStr(), "*")
+ do objHeightStr :: sameHeight ?(objHeight.toStr(), "*")
+ end if
+ do \form@groupRbAr.setVisible(true)
+ do \form@groupRbAr.setRedraw(false)
+ do \form@editRbArName.setText(name)
+ do \form@chkRbArVisible.setChk(visible)
+ do \form@editRbArX.setText(objXStr)
+ do \form@editRbArY.setText(objYStr)
+ do \form@editRbArWidth.setText(objWidthStr)
+ do \form@editRbArHeight.setText(objHeightStr)
+ do \form@groupRbAr.setRedraw(true)
+
+ do me.updatingProp :: false
end func
- func resizeObj2d(x: int, y: int)
- do me.stick(&x, &y)
- do me.holds.head()
- while(!me.holds.term())
- var obj: @Obj2d :: me.holds.get()
- var width: int :: obj.width + x - me.holdOffsetX
- var height: int :: obj.height + y - me.holdOffsetY
- var minWidth: int
- var minHeight: int
- var maxWidth: int
- var maxHeight: int
- do obj.getMinMaxSize(&minWidth, &minHeight, &maxWidth, &maxHeight)
- if(width < minWidth)
- do width :: minWidth
- end if
- if(width > maxWidth)
- do width :: maxWidth
- end if
- if(height < minHeight)
- do height :: minHeight
- end if
- if(height > maxHeight)
- do height :: maxHeight
- end if
- do obj.width :: width
- do obj.height :: height
- do me.holds.next()
+ func find(nodes: list<@Obj>, name: []char)
+ do nodes.head()
+ while(!nodes.term())
+ if(nodes.get().name = name)
+ ret
+ end if
+ do nodes.next()
end while
end func
- func moveObj2d(x: int, y: int)
- do me.holds.head()
- while(!me.holds.term())
- var obj: @Obj2d :: me.holds.get()
- do obj.absX :+ x - me.holdOffsetX
- do obj.absY :+ y - me.holdOffsetY
- do me.stick(&obj.absX, &obj.absY)
- do me.holds.next()
- end while
+ func put(parent: []char, kind: []char, name: []char, visible: bool, x: int, y: int, width: int, height: int, props: dict<[]char, []char>, recordUndo: bool): @Obj
+ if(recordUndo)
+ var undo: UndoArDel :: #UndoArDel
+ do undo.doc :: me
+ do undo.name :: name
+ var redo: UndoArPut :: #UndoArPut
+ do redo.doc :: me
+ do redo.parent :: parent
+ do redo.kind :: kind
+ do redo.name :: name
+ do redo.visible :: visible
+ do redo.x :: x
+ do redo.y :: y
+ do redo.width :: width
+ do redo.height :: height
+ do redo.props :: props
+ do me.undo.add(undo, redo)
+ end if
+ var obj: @Obj :: me.makeObj(kind)
+ if(width = -1 & height = -1)
+ do obj.getDefaultSize(&width, &height)
+ end if
+ do obj.init(name, visible, x, y, width, height, props)
+ if(props <>& null)
+ do obj.props :: props
+ do obj.reloadRes()
+ end if
+ if(parent =& null)
+ do me.nodes.add(obj)
+ else
+ do me.find(me.nodes, parent)
+ do me.nodes.ins(obj)
+ end if
+ do me.changed :: true
+ ret obj
end func
- func stick(x: &int, y: &int)
- {
- var parent: @Obj2d :: me.holds.parent
- if(parent =& null)
+ func del(name: []char, recordUndo: bool)
+ do me.find(me.nodes, name)
+ if(recordUndo)
+ var obj: @Obj :: me.nodes.get()
+ var parent: @Obj
+ if(me.nodes.termOffset(1))
+ do parent :: null
+ else
+ do parent :: me.nodes.getOffset(1)
+ end if
+ var undo: UndoArPut :: #UndoArPut
+ do undo.doc :: me
+ do undo.parent :: parent =& null ?(null, parent.name)
+ do undo.kind :: obj.kind()
+ do undo.name :: obj.name
+ do undo.visible :: obj.visible
+ do undo.x :: obj.x
+ do undo.y :: obj.y
+ do undo.width :: obj.width
+ do undo.height :: obj.height
+ do undo.props :: obj.props
+ var redo: UndoArDel :: #UndoArDel
+ do redo.doc :: me
+ do redo.name :: obj.name
+ do me.undo.add(undo, redo)
+ end if
+ do me.nodes.get().fin()
+ do me.nodes.del()
+ do me.changed :: true
+ end func
+
+ +func move(name: []char, x: int, y: int, width: int, height: int, recordUndo: bool)
+ var obj: @Obj
+ if(name =& null)
+ do obj :: me.root
+ else
+ do me.find(me.nodes, name)
+ do obj :: me.nodes.get()
+ end if
+ if(obj.x = x & obj.y = y & obj.width = width & obj.height = height)
ret
end if
- if((x - parent.absX).abs() <= stickingArea)
- do x :: parent.absX
+ if(recordUndo)
+ var undo: UndoArMove :: #UndoArMove
+ do undo.doc :: me
+ do undo.name :: name
+ do undo.x :: obj.x
+ do undo.y :: obj.y
+ do undo.width :: obj.width
+ do undo.height :: obj.height
+ var redo: UndoArMove :: #UndoArMove
+ do redo.doc :: me
+ do redo.name :: name
+ do redo.x :: x
+ do redo.y :: y
+ do redo.width :: width
+ do redo.height :: height
+ do me.undo.add(undo, redo)
end if
- if((y - parent.absY).abs() <= stickingArea)
- do y :: parent.absY
+ do obj.x :: x
+ do obj.y :: y
+ do obj.width :: width
+ do obj.height :: height
+ do me.changed :: true
+ end func
+
+ func order(names: [][]char, recordUndo: bool)
+ if(recordUndo)
+ var oldNames: [][]char :: #[^me.nodes][]char
+ do me.nodes.head()
+ var i: int :: 0
+ while(!me.nodes.term())
+ do oldNames[i] :: me.nodes.get().name
+ do i :+ 1
+ do me.nodes.next()
+ end while
+ var undo: UndoArOrder :: #UndoArOrder
+ do undo.doc :: me
+ do undo.names :: oldNames
+ var redo: UndoArOrder :: #UndoArOrder
+ do redo.doc :: me
+ do redo.names :: names
+ do me.undo.add(undo, redo)
end if
- if((x - (parent.absX + parent.width)).abs() <= stickingArea)
- do x :: parent.absX + parent.width
+ var newNodes: list<@Obj> :: #list<@Obj>
+ for i(0, ^names - 1)
+ do me.find(me.nodes, names[i])
+ do newNodes.add(me.nodes.get())
+ end for
+ do me.nodes :: newNodes
+ do me.changed :: true
+ end func
+
+ func rename(name: []char, newName: []char, recordUndo: bool)
+ if(recordUndo)
+ var undo: UndoArRename :: #UndoArRename
+ do undo.doc :: me
+ do undo.name :: newName
+ do undo.newName :: name
+ var redo: UndoArRename :: #UndoArRename
+ do redo.doc :: me
+ do redo.name :: name
+ do redo.newName :: newName
+ do me.undo.add(undo, redo)
end if
- if((y - (parent.absY + parent.height)).abs() <= stickingArea)
- do y :: parent.absY + parent.height
+ do me.find(me.nodes, name)
+ do me.nodes.get().name :: newName
+ do me.changed :: true
+ end func
+
+ +func visible(name: []char, value: bool, recordUndo: bool)
+ var obj: @Obj
+ if(name =& null)
+ do obj :: me.root
+ else
+ do me.find(me.nodes, name)
+ do obj :: me.nodes.get()
end if
- do parent.children.head()
- while(!parent.children.term())
- var child: @Obj2d :: parent.children.get()
- if(child <>& me.holds)
- if((x - child.absX).abs() <= stickingArea)
- do x :: child.absX
- end if
- if((y - child.absY).abs() <= stickingArea)
- do y :: child.absY
- end if
- if((x - (child.absX + child.width)).abs() <= stickingArea)
- do x :: child.absX + child.width
- end if
- if((y - (child.absY + child.height)).abs() <= stickingArea)
- do y :: child.absY + child.height
+ if(recordUndo)
+ var undo: UndoArVisible :: #UndoArVisible
+ do undo.doc :: me
+ do undo.name :: name
+ do undo.value :: obj.visible
+ var redo: UndoArVisible :: #UndoArVisible
+ do redo.doc :: me
+ do redo.name :: name
+ do redo.value :: value
+ do me.undo.add(undo, redo)
+ end if
+ do obj.visible :: value
+ do me.changed :: true
+ end func
+
+ func prop(name: []char, prop: []char, value: []char, recordUndo: bool)
+ end func
+
+ func cloneObj(src: @Obj): @Obj
+ var dst: @Obj :: me.makeObj(src.kind())
+ do dst.name :: src.name
+ do dst.visible :: src.visible
+ do dst.x :: src.x
+ do dst.y :: src.y
+ do dst.width :: src.width
+ do dst.height :: src.height
+ do dst.props :: ##src.props
+ ret dst
+ end func
+
+ func updateMultiple(chk: func<(@Obj, kuin@Class): bool>, apply: func<(@DocAr, @Obj, kuin@Class)>, data: kuin@Class)
+ if(^me.holds <= 1)
+ var obj: @Obj
+ if(^me.holds = 0)
+ do obj :: me.root
+ else
+ do me.holds.head()
+ do obj :: me.holds.get()
+ end if
+ if(chk(obj, data))
+ do me.undo.recordBegin()
+ do apply(me, obj, data)
+ do me.undo.recordEnd()
+ do \form@paintDrawEditor()
+ end if
+ else
+ var diff: bool :: false
+ do me.holds.head()
+ while loop(!me.holds.term())
+ if(chk(me.holds.get(), data))
+ do diff :: true
+ break loop
end if
+ do me.holds.next()
+ end while
+ if(diff)
+ do me.undo.recordBegin()
+ do me.holds.head()
+ while loop(!me.holds.term())
+ var obj: @Obj :: me.holds.get()
+ if(chk(obj, data))
+ do apply(me, obj, data)
+ end if
+ do me.holds.next()
+ end while
+ do me.undo.recordEnd()
+ do \form@paintDrawEditor()
end if
- do parent.children.next()
- end while
- }
-
+ end if
+ do \form@updateUi()
end func
end class
-+class Obj2d()
- *func ctor()
- do super(me)
- do me.init("root", 0, 0, 800, 450)
- end func
-
++enum PropType
+ str
+ int_
+ float_
+ bool_
+ enum_
+ color
+ file
+end enum
+
++class Obj()
+*func cmp(t: kuin@Class): int
ret t =& me ?(0, 1)
end func
- +func init(objName: []char, x: int, y: int, width: int, height: int)
- do me.parent :: null
- do me.children :: #list
- do me.objName :: objName
- do me.absX :: x
- do me.absY :: y
- do me.width :: width
- do me.height :: height
+ +func load(node: xml@Node)
+ var props: dict<[]char, []char> :: #dict<[]char, []char>
+ var propsNames: [][]char :: me.propsNames()
+ var propsTypes: []@PropType :: me.propsTypes()
+ for i(0, ^propsNames - 1)
+ var attr: []char :: node.getAttr(propsNames[i])
+ if(attr =& null)
+ switch(propsTypes[i])
+ case %str
+ do props.add(propsNames[i], "")
+ end switch
+ else
+ do props.add(propsNames[i], attr)
+ end if
+ end for
+ do me.init(node.getAttr("name"), node.getAttr("visible") = "true", node.getAttr("x").toInt(&), node.getAttr("y").toInt(&), node.getAttr("width").toInt(&), node.getAttr("height").toInt(&), props)
+ do me.reloadRes()
end func
- +func getName(): []char
+ +func save(node: xml@Node)
+ do node.setAttr("name", me.name)
+ do node.setAttr("visible", me.visible ?("true", "false"))
+ do node.setAttr("x", me.x.toStr())
+ do node.setAttr("y", me.y.toStr())
+ do node.setAttr("width", me.width.toStr())
+ do node.setAttr("height", me.height.toStr())
+ var propsNames: [][]char :: me.propsNames()
+ for i(0, ^propsNames - 1)
+ do node.setAttr(propsNames[i], me.props.get(propsNames[i], &))
+ end for
+ end func
+
+ +func draw(x: float, y: float, width: float, height: float, zoom: float)
end func
- +func getMinMaxSize(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
+ +func getMinMax(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
do minWidth :: 10
do minHeight :: 10
do maxWidth :: lib@intMax
do maxHeight :: lib@intMax
end func
- +func load(node: xml@Node)
- do me.parent :: null
- do me.children :: #list
- do me.setProps(node, ["name", "x", "y", "width", "height"])
+ +func getDefaultSize(width: &int, height: &int)
+ do width :: 10
+ do height :: 10
end func
- +func save(node: xml@Node)
- do node.setAttr("name", me.objName)
- do node.setAttr("x", me.absX.toStr())
- do node.setAttr("y", me.absY.toStr())
- do node.setAttr("width", me.width.toStr())
- do node.setAttr("height", me.height.toStr())
+ +func kind(): []char
end func
- +func draw(pageX: int, pageY: int)
- end func
-
- +func updateProp(listView: wnd@ListView, x: int, y: int)
- var idx: int :: listView.len()
- do listView.add("name")
- do listView.setText(idx + 0, 1, me.objName)
- do listView.add("x")
- do listView.setText(idx + 1, 1, (me.absX - x).toStr())
- do listView.add("y")
- do listView.setText(idx + 2, 1, (me.absY - y).toStr())
- do listView.add("absolute_x")
- do listView.setText(idx + 3, 1, me.absX.toStr())
- do listView.add("absolute_y")
- do listView.setText(idx + 4, 1, me.absY.toStr())
- do listView.add("width")
- do listView.setText(idx + 5, 1, me.width.toStr())
- do listView.add("height")
- do listView.setText(idx + 6, 1, me.height.toStr())
- end func
-
- +func setProp(prop: []char, value: []char)
- switch(prop)
- case "name"
- do me.objName :: value
- case "x"
- do value.toInt(&me.absX)
- case "y"
- do value.toInt(&me.absY)
- case "width"
- do value.toInt(&me.width)
- case "height"
- do value.toInt(&me.height)
- end switch
+ +func icon(): int
+ ret -1
end func
- +var parent: @Obj2d
- +var children: list<@Obj2d>
- +var objName: []char
- +var absX: int
- +var absY: int
- +var width: int
- +var height: int
+ +func init(name: []char, visible: bool, x: int, y: int, width: int, height: int, props: dict<[]char, []char>)
+ do me.name :: name
+ do me.visible :: visible
+ do me.x :: x
+ do me.y :: y
+ do me.width :: width
+ do me.height :: height
+ do me.props :: props =& null ?(#dict<[]char, []char>, props)
+ end func
- func setProps(node: xml@Node, props: [][]char)
- for i(0, ^props - 1)
- var attr: []char :: node.getAttr(props[i])
- if(attr <>& null)
- do me.setProp(props[i], attr)
- end if
- end for
+ +func fin()
+ end func
+
+ +func becomeParent(): bool
+ ret false
+ end func
+
+ +func propsNames(): [][]char
+ end func
+
+ +func propsTypes(): []@PropType
end func
-end class
-+class Obj2dRoot(@Obj2d)
- +*func getName(): []char
- ret "root"
+ +func propsTypeDatas(): [][][]char
end func
+
+ +func reloadRes()
+ end func
+
+ +var name: []char
+ +var visible: bool
+ +var x: int
+ +var y: int
+ +var width: int
+ +var height: int
+ +var props: dict<[]char, []char>
end class
+
+func getResizeArea(resizeAreaX: &int, resizeAreaY: &int, width: int, height: int)
+ const resizeArea: int :: 8
+ const padding: int :: 4
+ do resizeAreaX :: resizeArea
+ if(resizeAreaX > width / 2 - padding)
+ do resizeAreaX :: width / 2 - padding
+ end if
+ do resizeAreaY :: resizeArea
+ if(resizeAreaY > height / 2 - padding)
+ do resizeAreaY :: height / 2 - padding
+ end if
+end func
+
+func removePrefix(name: []char): []char
+ if(name[0] <> '>')
+ ret name
+ end if
+ var idx: int :: 1
+ while(name[idx] = '>')
+ do idx :+ 1
+ end while
+ ret name.sub(idx, -1)
+end func
+
++func getParent(parentStack: stack<@Obj>, obj: @Obj): @Obj
+ while(^parentStack > 0)
+ var parent: @Obj :: parentStack.peek()
+ if(parent.x <= obj.x & obj.x + obj.width <= parent.x + parent.width & parent.y <= obj.y & obj.y + obj.height <= parent.y + parent.height)
+ ret parent
+ end if
+ do parentStack.get()
+ end while
+ ret null
+end func
+
++func getPropAsInt(props: dict<[]char, []char>, name: []char): int
+ var success: bool
+ var value: []char :: props.get(name, &success)
+ if(!success)
+ ret 0
+ end if
+ var value2: int :: value.toInt(&success)
+ if(!success)
+ ret 0
+ end if
+ ret value2
+end func
+
++func getPropAsFloat(props: dict<[]char, []char>, name: []char): float
+ var success: bool
+ var value: []char :: props.get(name, &success)
+ if(!success)
+ ret 0.0
+ end if
+ var value2: float :: value.toFloat(&success)
+ if(!success)
+ ret 0.0
+ end if
+ ret value2
+end func
+
+func getDefaultName(name: []char, nodes: list<@Obj>): []char
+ var n: int :: 1
+ while loop(true)
+ var newName: []char :: name ~ n.toStr()
+ var found: bool :: false
+ do nodes.head()
+ while loop2(!nodes.term())
+ if(nodes.get().name = newName)
+ do found :: true
+ break loop2
+ end if
+ do nodes.next()
+ end while
+ if(!found)
+ ret newName
+ end if
+ do n :+ 1
+ end while
+end func
diff --git a/src/kuin_editor/doc_ar_2d.kn b/src/kuin_editor/doc_ar_2d.kn
new file mode 100644
index 00000000..ba95ccfb
--- /dev/null
+++ b/src/kuin_editor/doc_ar_2d.kn
@@ -0,0 +1,684 @@
+var resCacheDraw: drawex@ResCacheDraw
+
++func updateMainSrcDir(dir: []char)
+ if(@resCacheDraw =& null)
+ do @resCacheDraw :: #drawex@ResCacheDraw
+ end if
+ do @resCacheDraw.setBaseDir(dir)
+end func
+
++class DocAr2d(\doc_ar@DocAr)
+ *func ctor()
+ do super(me)
+ do me.root :: #@ObjLayer
+ var width: int
+ var height: int
+ do me.root.getDefaultSize(&width, &height)
+ do me.root.init("layer", true, 0, 0, width, height, null)
+ if(@resCacheDraw =& null)
+ do @resCacheDraw :: #drawex@ResCacheDraw
+ end if
+ end func
+
+ +*func fix()
+ var lines: list<[]char> :: #list<[]char>
+ do lines.add("+var resCacheDraw: drawex@ResCacheDraw")
+ do lines.add("+var \{me.root.name}: list")
+
+ do me.nodes.head()
+ while(!me.nodes.term())
+ var node: @ObjAr2d :: me.nodes.get() $ @ObjAr2d
+ do lines.add("+var \{node.name}: \{node.type()}")
+ do me.nodes.next()
+ end while
+
+ do lines.add("")
+ do lines.add("+func init()")
+ do lines.add("\tif(@\{me.root.name} <>& null)")
+ do lines.add("\t\tdo @fin()")
+ do lines.add("\tend if")
+ do lines.add("\tdo @resCacheDraw :: #drawex@ResCacheDraw")
+ do lines.add("\tdo @\{me.root.name} :: #list")
+
+ do me.nodes.head()
+ while(!me.nodes.term())
+ var node: @ObjAr2d :: me.nodes.get() $ @ObjAr2d
+ do lines.add("\tdo @\{node.name} :: #\{node.type()}")
+ do node.getSrcInit(1, lines)
+ do lines.add("\tdo @\{me.root.name}.add(@\{node.name})")
+ do me.nodes.next()
+ end while
+
+ do lines.add("end func")
+ do lines.add("")
+ do lines.add("+func fin()")
+ do lines.add("\tdo @\{me.root.name} :: null")
+
+ do me.nodes.head()
+ while(!me.nodes.term())
+ var node: @ObjAr2d :: me.nodes.get() $ @ObjAr2d
+ do lines.add("\tdo @\{node.name} :: null")
+ do me.nodes.next()
+ end while
+
+ do lines.add("end func")
+ do lines.add("")
+ do lines.add("+func draw()")
+ do lines.add("\tdo drawex@draw(@\{me.root.name})")
+ do lines.add("end func")
+ do me.src :: lines.toArray()
+ end func
+
+ *func makeObj(name: []char): \doc_ar@Obj
+ switch(name)
+ case "Layer"
+ ret #@ObjLayer
+ case "Rect"
+ ret #@ObjRect
+ case "RoundRect"
+ ret #@ObjRoundRect
+ case "Circle"
+ ret #@ObjCircle
+ case "Text"
+ ret #@ObjText
+ case "Img"
+ ret #@ObjImg
+ case "Particle"
+ ret #@ObjParticle
+ end switch
+ ret null
+ end func
+
+ *func updateLt()
+ do \form@listLt.add("Rect", 6)
+ do \form@listLt.add("RoundRect", 10)
+ do \form@listLt.add("Circle", 7)
+ do \form@listLt.add("Text", 8)
+ do \form@listLt.add("Img", 9)
+ do \form@listLt.add("Particle", 11)
+ end func
+end class
+
+class ObjAr2d(\doc_ar@Obj)
+ +func type(): []char
+ end func
+
+ +func getSrcInit(indent: int, lines: list<[]char>)
+ end func
+end class
+
+class ObjLayer(@ObjAr2d)
+ +*func draw(x: float, y: float, width: float, height: float, zoom: float)
+ do draw@rect(x * zoom, y * zoom, width * zoom, height * zoom, 0xFF000000)
+ end func
+
+ +*func getMinMax(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
+ do minWidth :: 50
+ do minHeight :: 50
+ do maxWidth :: lib@intMax
+ do maxHeight :: lib@intMax
+ end func
+
+ +*func getDefaultSize(width: &int, height: &int)
+ do width :: 640
+ do height :: 480
+ end func
+
+ +*func kind(): []char
+ ret "Layer"
+ end func
+
+ +*func init(name: []char, visible: bool, x: int, y: int, width: int, height: int, props: dict<[]char, []char>)
+ do super(me, name, visible, x, y, width, height, props)
+ if(props <>& null)
+ ret
+ end if
+ do me.reloadRes()
+ end func
+
+ +*func propsNames(): [][]char
+ ret #[0][]char
+ end func
+
+ +*func propsTypes(): []\doc_ar@PropType
+ ret #[0]\doc_ar@PropType
+ end func
+
+ +*func propsTypeDatas(): [][][]char
+ ret #[0][][]char
+ end func
+end class
+
+class ObjRect(@ObjAr2d)
+ +*func draw(x: float, y: float, width: float, height: float, zoom: float)
+ var colorFill: int :: \doc_ar@getPropAsInt(me.props, "colorFill")
+ if(colorFill <> 0)
+ do draw2d@rect(x * zoom, y * zoom, width * zoom, height * zoom, colorFill)
+ end if
+ var colorStroke: int :: \doc_ar@getPropAsInt(me.props, "colorStroke")
+ if(colorStroke <> 0)
+ do draw2d@rectLine(x * zoom, y * zoom, width * zoom, height * zoom, \doc_ar@getPropAsFloat(me.props, "strokeWidth") * zoom, colorStroke)
+ end if
+ end func
+
+ +*func getMinMax(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
+ do minWidth :: 1
+ do minHeight :: 1
+ do maxWidth :: lib@intMax
+ do maxHeight :: lib@intMax
+ end func
+
+ +*func getDefaultSize(width: &int, height: &int)
+ do width :: 100
+ do height :: 100
+ end func
+
+ +*func kind(): []char
+ ret "Rect"
+ end func
+
+ +*func icon(): int
+ ret 5
+ end func
+
+ +*func init(name: []char, visible: bool, x: int, y: int, width: int, height: int, props: dict<[]char, []char>)
+ do super(me, name, visible, x, y, width, height, props)
+ if(props <>& null)
+ ret
+ end if
+ do me.props.add("colorFill", "0xFFFFFFFF")
+ do me.props.add("colorStroke", "0x00000000")
+ do me.props.add("strokeWidth", "1.0")
+ do me.reloadRes()
+ end func
+
+ +*func propsNames(): [][]char
+ ret ["colorFill", "colorStroke", "strokeWidth"]
+ end func
+
+ +*func propsTypes(): []\doc_ar@PropType
+ ret [%color $ \doc_ar@PropType, %color, %float_]
+ end func
+
+ +*func propsTypeDatas(): [][][]char
+ ret #[3][][]char
+ end func
+
+ +*func type(): []char
+ ret "drawex@ObjRect"
+ end func
+
+ +*func getSrcInit(indent: int, lines: list<[]char>)
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.init(\{me.x} $ float, \{me.y} $ float, \{me.width} $ float, \{me.height} $ float, \{me.visible})")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.colorFill :: \{me.props.get("colorFill", &)}")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.colorStroke :: \{me.props.get("colorStroke", &)}")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.strokeWidth :: \{me.props.get("strokeWidth", &)}")
+ end func
+end class
+
+class ObjCircle(@ObjAr2d)
+ +*func draw(x: float, y: float, width: float, height: float, zoom: float)
+ var halfWidth: float :: width / 2.0
+ var halfHeight: float :: height / 2.0
+ var colorFill: int :: \doc_ar@getPropAsInt(me.props, "colorFill")
+ if(colorFill <> 0)
+ do draw2d@circle((x + halfWidth) * zoom, (y + halfHeight) * zoom, halfWidth * zoom, halfHeight * zoom, colorFill)
+ end if
+ var colorStroke: int :: \doc_ar@getPropAsInt(me.props, "colorStroke")
+ if(colorStroke <> 0)
+ do draw2d@circleLine((x + halfWidth) * zoom, (y + halfHeight) * zoom, halfWidth * zoom, halfHeight * zoom, \doc_ar@getPropAsFloat(me.props, "strokeWidth") * zoom, colorStroke)
+ end if
+ end func
+
+ +*func getMinMax(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
+ do minWidth :: 1
+ do minHeight :: 1
+ do maxWidth :: lib@intMax
+ do maxHeight :: lib@intMax
+ end func
+
+ +*func getDefaultSize(width: &int, height: &int)
+ do width :: 100
+ do height :: 100
+ end func
+
+ +*func kind(): []char
+ ret "Circle"
+ end func
+
+ +*func icon(): int
+ ret 6
+ end func
+
+ +*func init(name: []char, visible: bool, x: int, y: int, width: int, height: int, props: dict<[]char, []char>)
+ do super(me, name, visible, x, y, width, height, props)
+ if(props <>& null)
+ ret
+ end if
+ do me.props.add("colorFill", "0xFFFFFFFF")
+ do me.props.add("colorStroke", "0x00000000")
+ do me.props.add("strokeWidth", "1.0")
+ do me.reloadRes()
+ end func
+
+ +*func propsNames(): [][]char
+ ret ["colorFill", "colorStroke", "strokeWidth"]
+ end func
+
+ +*func propsTypes(): []\doc_ar@PropType
+ ret [%color $ \doc_ar@PropType, %color, %float_]
+ end func
+
+ +*func propsTypeDatas(): [][][]char
+ ret #[3][][]char
+ end func
+
+ +*func type(): []char
+ ret "drawex@ObjCircle"
+ end func
+
+ +*func getSrcInit(indent: int, lines: list<[]char>)
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.init(\{me.x} $ float, \{me.y} $ float, \{me.width} $ float, \{me.height} $ float, \{me.visible})")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.colorFill :: \{me.props.get("colorFill", &)}")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.colorStroke :: \{me.props.get("colorStroke", &)}")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.strokeWidth :: \{me.props.get("strokeWidth", &)}")
+ end func
+end class
+
+class ObjText(@ObjAr2d)
+ +*func draw(x: float, y: float, width: float, height: float, zoom: float)
+ var color: int :: \doc_ar@getPropAsInt(me.props, "color")
+ if(color = 0 | me.font =& null)
+ ret
+ end if
+
+ var alignHorizontal: draw@AlignHorizontal
+ var alignVertical: draw@AlignVertical
+ var x2: float
+ var y2: float
+ switch(me.props.get("alignHorizontal", &))
+ case "%center"
+ do alignHorizontal :: %center
+ do x2 :: x + width / 2.0
+ case "%right"
+ do alignHorizontal :: %right
+ do x2 :: x + width
+ default
+ do alignHorizontal :: %left
+ do x2 :: x
+ end switch
+ switch(me.props.get("alignVertical", &))
+ case "%center"
+ do alignVertical :: %center
+ do y2 :: y + height / 2.0
+ case "%bottom"
+ do alignVertical :: %bottom
+ do y2 :: y + height
+ default
+ do alignVertical :: %top
+ do y2 :: y
+ end switch
+
+ do me.font.align(alignHorizontal, alignVertical)
+ do me.font.drawScale(x2 * zoom, y2 * zoom, zoom, zoom, me.props.get("text", &), color)
+ do me.font.align(%left, %top)
+ end func
+
+ +*func getMinMax(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
+ do minWidth :: 1
+ do minHeight :: 1
+ do maxWidth :: lib@intMax
+ do maxHeight :: lib@intMax
+ end func
+
+ +*func getDefaultSize(width: &int, height: &int)
+ do width :: 100
+ do height :: 100
+ end func
+
+ +*func kind(): []char
+ ret "Text"
+ end func
+
+ +*func icon(): int
+ ret 7
+ end func
+
+ +*func init(name: []char, visible: bool, x: int, y: int, width: int, height: int, props: dict<[]char, []char>)
+ do super(me, name, visible, x, y, width, height, props)
+ if(props <>& null)
+ ret
+ end if
+ do me.props.add("text", name)
+ do me.props.add("color", "0xFFFFFFFF")
+ do me.props.add("alignHorizontal", "%left")
+ do me.props.add("alignVertical", "%top")
+ do me.props.add("fontName", "")
+ do me.props.add("fontSize", "30")
+ do me.props.add("bold", "false")
+ do me.props.add("italic", "false")
+ do me.props.add("proportional", "true")
+ do me.props.add("advance", "0.0")
+ do me.reloadRes()
+ end func
+
+ +*func fin()
+ if(me.font <>& null)
+ do @resCacheDraw.del(me.font)
+ do me.font :: null
+ end if
+ end func
+
+ +*func propsNames(): [][]char
+ ret ["text", "color", "alignHorizontal", "alignVertical", "fontName", "fontSize", "bold", "italic", "proportional", "advance"]
+ end func
+
+ +*func propsTypes(): []\doc_ar@PropType
+ ret [%str $ \doc_ar@PropType, %color, %enum_, %enum_, %str, %int_, %bool_, %bool_, %bool_, %float_]
+ end func
+
+ +*func propsTypeDatas(): [][][]char
+ ret [null, null, ["%left", "%center", "%right"], ["%top", "%center", "%bottom"], null, null, null, null, null, null]
+ end func
+
+ +*func reloadRes()
+ if(me.font <>& null)
+ do @resCacheDraw.del(me.font)
+ do me.font :: null
+ end if
+ try
+ do me.font :: @resCacheDraw.makeFont(me.props.get("fontName", &), me.props.get("fontSize", &).toInt(&), me.props.get("bold", &) = "true", me.props.get("italic", &) = "true", me.props.get("proportional", &) = "true", me.props.get("advance", &).toFloat(&))
+ catch
+ do me.font :: null
+ end try
+ end func
+
+ +*func type(): []char
+ ret "drawex@ObjText"
+ end func
+
+ +*func getSrcInit(indent: int, lines: list<[]char>)
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.init(\{me.x} $ float, \{me.y} $ float, \{me.width} $ float, \{me.height} $ float, \{me.visible})")
+ var fontName: []char :: me.props.get("fontName", &)
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.text :: \"\{me.props.get("text", &)}\"")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.color :: \{me.props.get("color", &)}")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.alignHorizontal :: \{me.props.get("alignHorizontal", &)}")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.alignVertical :: \{me.props.get("alignVertical", &)}")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.setFont(@resCacheDraw, \"\{fontName =& "" ?("null", fontName)}\", \{me.props.get("fontSize", &)}, \{me.props.get("bold", &)}, \{me.props.get("italic", &)}, \{me.props.get("proportional", &)}, \{me.props.get("advance", &)})")
+ end func
+
+ var font: draw@Font
+end class
+
+class ObjImg(@ObjAr2d)
+ +*func draw(x: float, y: float, width: float, height: float, zoom: float)
+ var color: int :: \doc_ar@getPropAsInt(me.props, "color")
+ if(color = 0 | me.tex =& null)
+ ret
+ end if
+
+ do me.tex.drawScale(x * zoom, y * zoom, width * zoom, height * zoom, \doc_ar@getPropAsInt(me.props, "srcX") $ float, \doc_ar@getPropAsInt(me.props, "srcX") $ float, \doc_ar@getPropAsInt(me.props, "srcWidth") $ float, \doc_ar@getPropAsInt(me.props, "srcHeight") $ float, color)
+ end func
+
+ +*func getMinMax(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
+ do minWidth :: 1
+ do minHeight :: 1
+ do maxWidth :: lib@intMax
+ do maxHeight :: lib@intMax
+ end func
+
+ +*func getDefaultSize(width: &int, height: &int)
+ do width :: 100
+ do height :: 100
+ end func
+
+ +*func kind(): []char
+ ret "Img"
+ end func
+
+ +*func icon(): int
+ ret 8
+ end func
+
+ +*func init(name: []char, visible: bool, x: int, y: int, width: int, height: int, props: dict<[]char, []char>)
+ do super(me, name, visible, x, y, width, height, props)
+ if(props <>& null)
+ ret
+ end if
+ do me.props.add("texPath", "")
+ do me.props.add("srcX", "0")
+ do me.props.add("srcY", "0")
+ do me.props.add("srcWidth", "100")
+ do me.props.add("srcHeight", "100")
+ do me.props.add("color", "0xFFFFFFFF")
+ do me.reloadRes()
+ end func
+
+ +*func fin()
+ if(me.tex <>& null)
+ do @resCacheDraw.del(me.tex)
+ do me.tex :: null
+ end if
+ end func
+
+ +*func propsNames(): [][]char
+ ret ["texPath", "srcX", "srcY", "srcWidth", "srcHeight", "color"]
+ end func
+
+ +*func propsTypes(): []\doc_ar@PropType
+ ret [%str $ \doc_ar@PropType, %int_, %int_, %int_, %int_, %color]
+ end func
+
+ +*func propsTypeDatas(): [][][]char
+ ret #[6][][]char
+ end func
+
+ +*func reloadRes()
+ if(me.tex <>& null)
+ do @resCacheDraw.del(me.tex)
+ do me.tex :: null
+ end if
+ try
+ do me.tex :: @resCacheDraw.makeTex(me.props.get("texPath", &))
+ catch
+ do me.tex :: null
+ end try
+ end func
+
+ +*func type(): []char
+ ret "drawex@ObjImg"
+ end func
+
+ +*func getSrcInit(indent: int, lines: list<[]char>)
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.init(\{me.x} $ float, \{me.y} $ float, \{me.width} $ float, \{me.height} $ float, \{me.visible})")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.srcX :: \{me.props.get("srcX", &)} $ float")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.srcY :: \{me.props.get("srcY", &)} $ float")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.srcWidth :: \{me.props.get("srcWidth", &)} $ float")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.srcHeight :: \{me.props.get("srcHeight", &)} $ float")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.color :: \{me.props.get("color", &)}")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.setTex(@resCacheDraw, \"\{me.props.get("texPath", &).replace("\\", "\\\\")}\")")
+ end func
+
+ var tex: draw@Tex
+end class
+
+class ObjRoundRect(@ObjAr2d)
+ +*func draw(x: float, y: float, width: float, height: float, zoom: float)
+ var radiusX: float :: \doc_ar@getPropAsInt(me.props, "radiusX") $ float
+ var radiusY: float :: \doc_ar@getPropAsInt(me.props, "radiusY") $ float
+ var colorFill: int :: \doc_ar@getPropAsInt(me.props, "colorFill")
+ if(colorFill <> 0)
+ do draw2d@roundRect(x * zoom, y * zoom, width * zoom, height * zoom, radiusX * zoom, radiusY * zoom, colorFill)
+ end if
+ var colorStroke: int :: \doc_ar@getPropAsInt(me.props, "colorStroke")
+ if(colorStroke <> 0)
+ do draw2d@roundRectLine(x * zoom, y * zoom, width * zoom, height * zoom, radiusX * zoom, radiusY * zoom, \doc_ar@getPropAsFloat(me.props, "strokeWidth") * zoom, colorStroke)
+ end if
+ end func
+
+ +*func getMinMax(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
+ do minWidth :: 1
+ do minHeight :: 1
+ do maxWidth :: lib@intMax
+ do maxHeight :: lib@intMax
+ end func
+
+ +*func getDefaultSize(width: &int, height: &int)
+ do width :: 100
+ do height :: 100
+ end func
+
+ +*func kind(): []char
+ ret "RoundRect"
+ end func
+
+ +*func icon(): int
+ ret 9
+ end func
+
+ +*func init(name: []char, visible: bool, x: int, y: int, width: int, height: int, props: dict<[]char, []char>)
+ do super(me, name, visible, x, y, width, height, props)
+ if(props <>& null)
+ ret
+ end if
+ do me.props.add("colorFill", "0xFFFFFFFF")
+ do me.props.add("colorStroke", "0x00000000")
+ do me.props.add("radiusX", "20")
+ do me.props.add("radiusY", "20")
+ do me.props.add("strokeWidth", "1.0")
+ do me.reloadRes()
+ end func
+
+ +*func propsNames(): [][]char
+ ret ["colorFill", "colorStroke", "radiusX", "radiusY", "strokeWidth"]
+ end func
+
+ +*func propsTypes(): []\doc_ar@PropType
+ ret [%color $ \doc_ar@PropType, %color, %int_, %int_, %float_]
+ end func
+
+ +*func propsTypeDatas(): [][][]char
+ ret #[5][][]char
+ end func
+
+ +*func type(): []char
+ ret "drawex@ObjRoundRect"
+ end func
+
+ +*func getSrcInit(indent: int, lines: list<[]char>)
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.init(\{me.x} $ float, \{me.y} $ float, \{me.width} $ float, \{me.height} $ float, \{me.visible})")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.colorFill :: \{me.props.get("colorFill", &)}")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.colorStroke :: \{me.props.get("colorStroke", &)}")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.radiusX :: \{me.props.get("radiusX", &)} $ float")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.radiusY :: \{me.props.get("radiusY", &)} $ float")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.strokeWidth :: \{me.props.get("strokeWidth", &)}")
+ end func
+end class
+
+class ObjParticle(@ObjAr2d)
+ +*func draw(x: float, y: float, width: float, height: float, zoom: float)
+ if(me.particle =& null | me.tex =& null)
+ ret
+ end if
+
+ do me.particle.emit(x * zoom, y * zoom, 0.0, 0.0, 0.0, 0.0, width * zoom, 0.0, 0.0, 0.0)
+
+ do me.particle.draw2d(me.tex)
+ end func
+
+ +*func getMinMax(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
+ do minWidth :: 50
+ do minHeight :: 50
+ do maxWidth :: 50
+ do maxHeight :: 50
+ end func
+
+ +*func getDefaultSize(width: &int, height: &int)
+ do width :: 50
+ do height :: 50
+ end func
+
+ +*func kind(): []char
+ ret "Particle"
+ end func
+
+ +*func icon(): int
+ ret 10
+ end func
+
+ +*func init(name: []char, visible: bool, x: int, y: int, width: int, height: int, props: dict<[]char, []char>)
+ do super(me, name, visible, x, y, width, height, props)
+ if(props <>& null)
+ ret
+ end if
+ do me.props.add("lifespan", "60")
+ do me.props.add("friction", "0.0")
+ do me.props.add("accelX", "0.0")
+ do me.props.add("accelY", "0.0")
+ do me.props.add("color1", "0xFFFFFFFF")
+ do me.props.add("color2", "0xFFFFFFFF")
+ do me.props.add("sizeAccel", "0.0")
+ do me.props.add("rotAccel", "0.0")
+ do me.props.add("texPath", "")
+ do me.reloadRes()
+ end func
+
+ +*func fin()
+ if(me.particle <>& null)
+ do @resCacheDraw.del(me.particle)
+ do me.particle :: null
+ end if
+ if(me.tex <>& null)
+ do @resCacheDraw.del(me.tex)
+ do me.tex :: null
+ end if
+ end func
+
+ +*func propsNames(): [][]char
+ ret ["lifespan", "friction", "accelX", "accelY", "color1", "color2", "sizeAccel", "rotAccel", "texPath"]
+ end func
+
+ +*func propsTypes(): []\doc_ar@PropType
+ ret [%int_ $ \doc_ar@PropType, %float_, %float_, %float_, %color, %color, %float_, %float_, %str]
+ end func
+
+ +*func propsTypeDatas(): [][][]char
+ ret #[9][][]char
+ end func
+
+ +*func reloadRes()
+ if(me.particle <>& null)
+ do @resCacheDraw.del(me.particle)
+ do me.particle :: null
+ end if
+ if(me.tex <>& null)
+ do @resCacheDraw.del(me.tex)
+ do me.tex :: null
+ end if
+ try
+ do me.particle :: @resCacheDraw.makeParticle(\doc_ar@getPropAsInt(me.props, "lifespan"), \doc_ar@getPropAsInt(me.props, "color1"), \doc_ar@getPropAsInt(me.props, "color2"), \doc_ar@getPropAsFloat(me.props, "friction"), \doc_ar@getPropAsFloat(me.props, "accelX"), \doc_ar@getPropAsFloat(me.props, "accelY"), \doc_ar@getPropAsFloat(me.props, "accelZ"), \doc_ar@getPropAsFloat(me.props, "sizeAccel"), \doc_ar@getPropAsFloat(me.props, "rotAccel"))
+ catch
+ do me.particle :: null
+ end try
+ try
+ do me.tex :: @resCacheDraw.makeTex(me.props.get("texPath", &))
+ catch
+ do me.tex :: null
+ end try
+ end func
+
+ +*func type(): []char
+ ret "drawex@ObjParticle"
+ end func
+
+ +*func getSrcInit(indent: int, lines: list<[]char>)
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.init(\{me.x} $ float, \{me.y} $ float, \{me.width} $ float, \{me.height} $ float, \{me.visible})")
+ var texPath: []char :: me.props.get("texPath", &)
+ do texPath :: texPath = "" ?("null", "\"" ~ texPath.replace("\\", "\\\\") ~ "\"")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.setParticle(@resCacheDraw, \{me.props.get("lifespan", &)}, \{me.props.get("color1", &)}, \{me.props.get("color2", &)}, \{me.props.get("friction", &)}, \{me.props.get("accelX", &)}, \{me.props.get("accelY", &)}, 0.0, \{me.props.get("sizeAccel", &)}, \{me.props.get("rotAccel", &)})")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.setTex(@resCacheDraw, \{texPath})")
+ end func
+
+ var particle: draw@Particle
+ var tex: draw@Tex
+end class
diff --git a/src/kuin_editor/doc_ar_wnd.kn b/src/kuin_editor/doc_ar_wnd.kn
index 44e64f1e..69ea2827 100644
--- a/src/kuin_editor/doc_ar_wnd.kn
+++ b/src/kuin_editor/doc_ar_wnd.kn
@@ -1,789 +1,597 @@
-+class DocArWnd(\doc_ar@DocArBase)
++class DocArWnd(\doc_ar@DocAr)
*func ctor()
do super(me)
- do me.obj2dRoot :: #@Obj2dWnd
- end func
-
- +*func makeObj2d(name: []char): \doc_ar@Obj2d
+ do me.root :: #@ObjWnd
+ var width: int
+ var height: int
+ do me.root.getDefaultSize(&width, &height)
+ do me.root.init("wndMain", true, 0, 0, width, height, null)
+ end func
+
+ +*func fix()
+ var lines: list<[]char> :: #list<[]char>
+ do lines.add("+var \{me.root.name}: \{(me.root $ @ObjArWnd).type()}")
+
+ do me.nodes.head()
+ while(!me.nodes.term())
+ var node: @ObjArWnd :: me.nodes.get() $ @ObjArWnd
+ do lines.add("+var \{node.name}: \{node.type()}")
+ do me.nodes.next()
+ end while
+
+ do lines.add("")
+ do lines.add("+func show()")
+ do lines.add("\tif(@\{me.root.name} <>& null)")
+ do lines.add("\t\tret")
+ do lines.add("\tend if")
+ do (me.root $ @ObjArWnd).getSrcMake(1, lines, "null")
+ if(!me.root.visible)
+ do lines.add("\tdo @\{me.root.name}.setVisible(false)")
+ end if
+
+ var parentStack: stack<\doc_ar@Obj> :: #stack<\doc_ar@Obj>
+ do me.nodes.head()
+ while(!me.nodes.term())
+ var obj: @ObjArWnd :: me.nodes.get() $ @ObjArWnd
+ var parent: \doc_ar@Obj :: \doc_ar@getParent(parentStack, obj)
+ if(parent =& null)
+ do obj.getSrcMake(1, lines, "@" ~ me.root.name)
+ else
+ var x: int :: obj.x
+ var y: int :: obj.y
+ do obj.x :- parent.x
+ do obj.y :- parent.y
+ do obj.getSrcMake(1, lines, "@" ~ parent.name)
+ do obj.x :: x
+ do obj.y :: y
+ end if
+ if(obj.becomeParent())
+ do parentStack.add(obj)
+ end if
+ if(!obj.visible)
+ do lines.add("\tdo @\{obj.name}.setVisible(false)")
+ end if
+ do me.nodes.next()
+ end while
+
+ do lines.add("end func")
+ do lines.add("")
+ do lines.add("+func close()")
+ do lines.add("\tif(@\{me.root.name} =& null)")
+ do lines.add("\t\tret")
+ do lines.add("\tend if")
+ do lines.add("\tdo @\{me.root.name}.close()")
+ do lines.add("\tdo @\{me.root.name} :: null")
+
+ do me.nodes.head()
+ while(!me.nodes.term())
+ do lines.add("\tdo @\{me.nodes.get().name} :: null")
+ do me.nodes.next()
+ end while
+
+ do lines.add("end func")
+ do me.src :: lines.toArray()
+ end func
+
+ *func makeObj(name: []char): \doc_ar@Obj
switch(name)
- case "button"
- ret #@Obj2dBtn
- case "check"
- ret #@Obj2dChk
- case "group"
- ret #@Obj2dGroup
- case "label"
- ret #@Obj2dLabel
- case "list"
- ret #@Obj2dList
- case "list_view"
- ret #@Obj2dListView
- case "draw"
- ret #@Obj2dDraw
- case "radio"
- ret #@Obj2dRadio
- case "edit"
- ret #@Obj2dEdit
- case "edit_multi"
- ret #@Obj2dEditMulti
- case "tree"
- ret #@Obj2dTree
+ case "Wnd"
+ ret #@ObjWnd
+ case "Btn"
+ ret #@ObjBtn
+ case "Edit"
+ ret #@ObjEdit
+ case "Label"
+ ret #@ObjLabel
+ case "Chk"
+ ret #@ObjChk
+ case "Group"
+ ret #@ObjGroup
+ case "EditMulti"
+ ret #@ObjEditMulti
end switch
- assert(false)
ret null
end func
- *func addCtrlList(ctrlList: wnd@List)
- do super(me, ctrlList)
- do ctrlList.add("button")
- do ctrlList.add("check")
- do ctrlList.add("group")
- do ctrlList.add("label")
- do ctrlList.add("list")
- do ctrlList.add("list_view")
- do ctrlList.add("draw")
- do ctrlList.add("radio")
- do ctrlList.add("edit")
- do ctrlList.add("edit_multi")
- do ctrlList.add("tree")
+ *func updateLt()
+ do \form@listLt.add("Btn", 1)
+ do \form@listLt.add("Chk", 2)
+ do \form@listLt.add("Edit", 3)
+ do \form@listLt.add("Label", 4)
+ do \form@listLt.add("Group", 5)
+ do \form@listLt.add("EditMulti", 12)
end func
end class
-class Obj2dWnd(\doc_ar@Obj2dRoot)
- *func ctor()
- do super(me)
- do me.style :: 0
- do me.layered :: false
- do me.noMinimize :: false
- do me.text :: "Untitled"
+class ObjArWnd(\doc_ar@Obj)
+ +func type(): []char
end func
- +*func getMinMaxSize(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
- do minWidth :: 50
- do minHeight :: 50
- do maxWidth :: lib@intMax
- do maxHeight :: lib@intMax
+ +func getSrcMake(indent: int, lines: list<[]char>, parent: []char)
end func
- +*func load(node: xml@Node)
- do super(me, node)
- do me.setProps(node, ["style", "layered", "no_minimize", "text"])
- end func
-
- +*func save(node: xml@Node)
- do super(me, node)
- do node.setAttr("style", me.style.toStr())
- do node.setAttr("layered", me.layered.toStr())
- do node.setAttr("no_minimize", me.noMinimize.toStr())
- do node.setAttr("text", me.text)
- end func
-
- +*func draw(pageX: int, pageY: int)
- var x: float :: (me.absX - pageX) $ float
- var y: float :: (me.absY - pageY) $ float
- var width: float :: me.width $ float
- var height: float :: me.height $ float
- do draw@rect(x, y, width, height, 0xFFF0F0F0)
- do draw@rect(x, y - 30.0, width, 30.0, 0xFFFFFFFF)
- do draw@rectLine(x - 1.0, y - 31.0, width + 2.0, height + 32.0, 0xFF1883D7)
- do \common@fontP.draw(x + 30.0, y - 30.0 + 6.0, me.text, draw@black)
- end func
-
- +*func updateProp(listView: wnd@ListView, x: int, y: int)
- do super(me, listView, x, y)
- var idx: int :: listView.len()
- do listView.add("style")
- do listView.setText(idx + 0, 1, style(me.style))
- do listView.add("layered")
- do listView.setText(idx + 1, 1, me.layered.toStr())
- do listView.add("no_minimize")
- do listView.setText(idx + 2, 1, me.noMinimize.toStr())
- do listView.add("text")
- do listView.setText(idx + 3, 1, me.text)
-
- func style(value: int): []char
- switch(value)
- case 1
- ret "fix"
- case 2
- ret "aspect"
- case 3
- ret "popup"
- default
- ret "normal"
- end switch
- end func
- end func
-
- +*func setProp(prop: []char, value: []char)
- do super(me, prop, value)
- switch(prop)
- case "style"
- do me.style :: style(value)
- case "layered"
- do me.layered :: value = "true"
- case "no_minimize"
- do me.noMinimize :: value = "true"
- case "text"
- do me.text :: value
- end switch
-
- func style(value: []char): int
- switch(value)
- case "fix"
- ret 1
- case "aspect"
- ret 2
- case "popup"
- ret 3
- default
- ret 0
- end switch
- end func
- end func
-
- +var style: int
- +var layered: bool
- +var noMinimize: bool
- +var text: []char
-end class
-
-class Obj2dWndBase(\doc_ar@Obj2d)
- *func ctor()
- do super(me)
- do me.anchorX :: 0
- do me.enabled :: true
- do me.visible :: true
- end func
-
- +*func load(node: xml@Node)
- do super(me, node)
- do me.setProps(node, ["anchor_x", "anchor_y", "enabled", "visible"])
- end func
-
- +*func save(node: xml@Node)
- do super(me, node)
- do node.setAttr("anchor_x", me.anchorX.toStr())
- do node.setAttr("anchor_y", me.anchorY.toStr())
- do node.setAttr("enabled", me.enabled.toStr())
- do node.setAttr("visible", me.visible.toStr())
- end func
-
- +*func updateProp(listView: wnd@ListView, x: int, y: int)
- do super(me, listView, x, y)
- var idx: int :: listView.len()
- do listView.add("anchor_x")
- do listView.setText(idx + 0, 1, anchor(me.anchorX))
- do listView.add("anchor_y")
- do listView.setText(idx + 1, 1, anchor(me.anchorY))
- do listView.add("enabled")
- do listView.setText(idx + 2, 1, me.enabled.toStr())
- do listView.add("visible")
- do listView.setText(idx + 3, 1, me.visible.toStr())
-
- func anchor(value: int): []char
- switch(value)
- case 1
- ret "move"
- case 2
- ret "scale"
- default
- ret "fix"
- end switch
- end func
- end func
-
- +*func setProp(prop: []char, value: []char)
- do super(me, prop, value)
- switch(prop)
- case "anchor_x"
- do me.anchorX :: anchor(value)
- case "anchor_y"
- do me.anchorY :: anchor(value)
- case "enabled"
- do me.enabled :: value = "true"
- case "visible"
- do me.visible :: value = "true"
- end switch
-
- func anchor(value: []char): int
- switch(value)
- case "move"
- ret 1
- case "scale"
- ret 2
- default
- ret 0
- end switch
- end func
- end func
-
- +var anchorX: int
- +var anchorY: int
- +var enabled: bool
- +var visible: bool
-end class
-
-class Obj2dBtn(@Obj2dWndBase)
- *func ctor()
- do super(me)
- do me.text :: "button"
+ func addEvent(indent: int, lines: list<[]char>, name: []char)
+ var value: []char :: me.props.get(name, &)
+ if(value = "" | value = "null")
+ ret
+ end if
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.\{name} :: \{value}")
end func
+end class
- +*func getName(): []char
- ret "button"
+class ObjWnd(@ObjArWnd)
+ +*func draw(x: float, y: float, width: float, height: float, zoom: float)
+ do draw@rect(x * zoom, y * zoom, width * zoom, height * zoom, 0xFFF0F0F0)
+ do draw@rect(x * zoom, (y - 30.0) * zoom, width * zoom, 30.0 * zoom, 0xFFFFFFFF)
+ do draw@rectLine((x - 1.0) * zoom, (y - 31.0) * zoom, (width + 2.0) * zoom, (height + 32.0) * zoom, 0xFF1883D7)
+ do \common@fontP.drawScale((x + 30.0) * zoom, (y - 30.0 + 6.0) * zoom, zoom, zoom, me.props.get("text", &), draw@black)
end func
- +*func getMinMaxSize(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
- do minWidth :: 10
- do minHeight :: 23
+ +*func getMinMax(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
+ do minWidth :: 50
+ do minHeight :: 50
do maxWidth :: lib@intMax
do maxHeight :: lib@intMax
end func
- +*func load(node: xml@Node)
- do super(me, node)
- do me.setProps(node, ["text"])
+ +*func getDefaultSize(width: &int, height: &int)
+ do width :: 640
+ do height :: 480
end func
- +*func save(node: xml@Node)
- do super(me, node)
- do node.setAttr("text", me.text)
+ +*func kind(): []char
+ ret "Wnd"
end func
- +*func draw(pageX: int, pageY: int)
- var x: float :: (me.absX - pageX) $ float
- var y: float :: (me.absY - pageY) $ float
- var width: float :: me.width $ float
- var height: float :: me.height $ float
- do draw@rect(x, y, width, height, 0xFFE1E1E1)
- do draw@rectLine(x, y, width, height, 0xFFADADAD)
- do \common@fontP.draw(lib@floor(x + (width - \common@fontP.calcWidth(me.text)) / 2.0), lib@floor(y + (height - \common@fontP.maxHeight()) / 2.0), me.text, draw@black)
+ +*func init(name: []char, visible: bool, x: int, y: int, width: int, height: int, props: dict<[]char, []char>)
+ do super(me, name, visible, x, y, width, height, props)
+ if(props <>& null)
+ ret
+ end if
+ do me.props.add("style", "%normal")
+ do me.props.add("text", me.name)
+ do me.props.add("onClose", "")
+ do me.props.add("onActivate", "")
+ do me.props.add("onPushMenu", "")
+ do me.props.add("onDropFiles", "")
+ do me.props.add("onResize", "")
+ do me.reloadRes()
end func
- +*func updateProp(listView: wnd@ListView, x: int, y: int)
- do super(me, listView, x, y)
- var idx: int :: listView.len()
- do listView.add("text")
- do listView.setText(idx + 0, 1, me.text)
+ +*func propsNames(): [][]char
+ ret ["style", "text", "onClose", "onActivate", "onPushMenu", "onDropFiles", "onResize"]
end func
- +*func setProp(prop: []char, value: []char)
- do super(me, prop, value)
- switch(prop)
- case "text"
- do me.text :: value
- end switch
+ +*func propsTypes(): []\doc_ar@PropType
+ ret [%enum_ $ \doc_ar@PropType, %str, %str, %str, %str, %str, %str]
end func
- +var text: []char
-end class
-
-class Obj2dChk(@Obj2dWndBase)
- *func ctor()
- do super(me)
- do me.text :: "check"
+ +*func propsTypeDatas(): [][][]char
+ ret [["%normal", "%fix", "%aspect", "%popup"], null, null, null, null, null, null]
end func
- +*func getName(): []char
- ret "check"
+ +*func type(): []char
+ ret "wnd@Wnd"
end func
- +*func getMinMaxSize(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
- do minWidth :: 16
- do minHeight :: 16
- do maxWidth :: lib@intMax
- do maxHeight :: lib@intMax
+ +*func getSrcMake(indent: int, lines: list<[]char>, parent: []char)
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name} :: wnd@makeWnd(\{parent}, \{me.props.get("style", &)}, \{me.width}, \{me.height}, \"\{me.props.get("text", &)}\")")
+ do me.addEvent(indent, lines, "onClose")
+ do me.addEvent(indent, lines, "onActivate")
+ do me.addEvent(indent, lines, "onPushMenu")
+ do me.addEvent(indent, lines, "onDropFiles")
+ do me.addEvent(indent, lines, "onResize")
end func
+end class
- +*func load(node: xml@Node)
- do super(me, node)
- do me.setProps(node, ["text"])
+class ObjBtn(@ObjArWnd)
+ +*func draw(x: float, y: float, width: float, height: float, zoom: float)
+ do draw@rect(x * zoom, y * zoom, width * zoom, height * zoom, 0xFFE1E1E1)
+ do draw@rectLine(x * zoom, y * zoom, width * zoom, height * zoom, 0xFFADADAD)
+ var text: []char :: me.props.get("text", &)
+ do \common@fontP.drawScale(lib@floor(x + (width - \common@fontP.calcWidth(text)) / 2.0) * zoom, lib@floor(y + (height - \common@fontP.maxHeight()) / 2.0) * zoom, zoom, zoom, text, draw@black)
end func
- +*func save(node: xml@Node)
- do super(me, node)
- do node.setAttr("text", me.text)
+ +*func getMinMax(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
+ do minWidth :: 10
+ do minHeight :: 23
+ do maxWidth :: lib@intMax
+ do maxHeight :: lib@intMax
end func
- +*func draw(pageX: int, pageY: int)
- var x: float :: (me.absX - pageX) $ float
- var y: float :: (me.absY - pageY) $ float
- var width: float :: me.width $ float
- var height: float :: me.height $ float
- do draw@rect(x, lib@floor(y + (height - 13.0) / 2.0), 13.0, 13.0, 0xFFFFFFFF)
- do draw@rectLine(x, lib@floor(y + (height - 13.0) / 2.0), 13.0, 13.0, 0xFF333333)
- do \common@fontP.draw(x + 18.0, lib@floor(y + (height - \common@fontP.maxHeight()) / 2.0), me.text, draw@black)
+ +*func getDefaultSize(width: &int, height: &int)
+ do width :: 75
+ do height :: 23
end func
- +*func updateProp(listView: wnd@ListView, x: int, y: int)
- do super(me, listView, x, y)
- var idx: int :: listView.len()
- do listView.add("text")
- do listView.setText(idx + 0, 1, me.text)
+ +*func kind(): []char
+ ret "Btn"
end func
- +*func setProp(prop: []char, value: []char)
- do super(me, prop, value)
- switch(prop)
- case "text"
- do me.text :: value
- end switch
+ +*func icon(): int
+ ret 0
end func
- +var text: []char
-end class
-
-class Obj2dGroup(@Obj2dWndBase)
- *func ctor()
- do super(me)
- do me.text :: "group"
+ +*func init(name: []char, visible: bool, x: int, y: int, width: int, height: int, props: dict<[]char, []char>)
+ do super(me, name, visible, x, y, width, height, props)
+ if(props <>& null)
+ ret
+ end if
+ do me.props.add("anchorX", "%fix")
+ do me.props.add("anchorY", "%fix")
+ do me.props.add("text", me.name)
+ do me.props.add("onPush", "")
+ do me.reloadRes()
end func
- +*func getName(): []char
- ret "group"
+ +*func propsNames(): [][]char
+ ret ["anchorX", "anchorY", "text", "onPush"]
end func
- +*func getMinMaxSize(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
- do minWidth :: 60
- do minHeight :: 24
- do maxWidth :: lib@intMax
- do maxHeight :: lib@intMax
+ +*func propsTypes(): []\doc_ar@PropType
+ ret [%enum_ $ \doc_ar@PropType, %enum_, %str, %str]
end func
- +*func load(node: xml@Node)
- do super(me, node)
- do me.setProps(node, ["text"])
+ +*func propsTypeDatas(): [][][]char
+ ret [["%fix", "%move", "%scale"], ["%fix", "%move", "%scale"], null, null]
end func
- +*func save(node: xml@Node)
- do super(me, node)
- do node.setAttr("text", me.text)
+ +*func type(): []char
+ ret "wnd@Btn"
end func
- +*func draw(pageX: int, pageY: int)
- var x: float :: (me.absX - pageX) $ float
- var y: float :: (me.absY - pageY) $ float
- var width: float :: me.width $ float
- var height: float :: me.height $ float
- do draw@rectLine(x, y + 6.0, width, height - 6.0, 0xFFDCDCDC)
- do \common@fontP.draw(x + 8.0, y + 0.0, me.text, draw@black)
+ +*func getSrcMake(indent: int, lines: list<[]char>, parent: []char)
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name} :: wnd@makeBtn(\{parent}, \{me.x}, \{me.y}, \{me.width}, \{me.height}, \{me.props.get("anchorX", &)}, \{me.props.get("anchorY", &)}, \"\{me.props.get("text", &)}\")")
+ do me.addEvent(indent, lines, "onPush")
end func
+end class
- +*func updateProp(listView: wnd@ListView, x: int, y: int)
- do super(me, listView, x, y)
- var idx: int :: listView.len()
- do listView.add("text")
- do listView.setText(idx + 0, 1, me.text)
+class ObjEdit(@ObjArWnd)
+ +*func draw(x: float, y: float, width: float, height: float, zoom: float)
+ do draw@rect(x * zoom, y * zoom, width * zoom, height * zoom, 0xFFFFFFFF)
+ do draw@rectLine(x * zoom, y * zoom, width * zoom, height * zoom, 0xFF7A7A7A)
+ var text: []char :: me.props.get("text", &)
+ var rightAligned: bool :: me.props.get("rightAligned", &) <> "false"
+ if(rightAligned)
+ var textWidth: float :: \common@fontP.calcWidth(text)
+ do \common@fontP.drawScale((x + width - 5.0 - textWidth) * zoom, (y + 3.0) * zoom, zoom, zoom, text, draw@black)
+ else
+ do \common@fontP.drawScale((x + 5.0) * zoom, (y + 3.0) * zoom, zoom, zoom, text, draw@black)
+ end if
+ end func
+
+ +*func getMinMax(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
+ do minWidth :: 10
+ do minHeight :: 19
+ do maxWidth :: lib@intMax
+ do maxHeight :: 19
end func
- +*func setProp(prop: []char, value: []char)
- do super(me, prop, value)
- switch(prop)
- case "text"
- do me.text :: value
- end switch
+ +*func getDefaultSize(width: &int, height: &int)
+ do width :: 100
+ do height :: 19
end func
- +var text: []char
-end class
-
-class Obj2dLabel(@Obj2dWndBase)
- *func ctor()
- do super(me)
- do me.text :: "label"
+ +*func kind(): []char
+ ret "Edit"
end func
- +*func getName(): []char
- ret "label"
+ +*func icon(): int
+ ret 2
end func
- +*func getMinMaxSize(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
- do minWidth :: 10
- do minHeight :: 12
- do maxWidth :: lib@intMax
- do maxHeight :: lib@intMax
+ +*func init(name: []char, visible: bool, x: int, y: int, width: int, height: int, props: dict<[]char, []char>)
+ do super(me, name, visible, x, y, width, height, props)
+ if(props <>& null)
+ ret
+ end if
+ do me.props.add("anchorX", "%fix")
+ do me.props.add("anchorY", "%fix")
+ do me.props.add("readonly", "false")
+ do me.props.add("rightAligned", "false")
+ do me.props.add("text", "")
+ do me.props.add("onChange", "")
+ do me.props.add("onFocus", "")
+ do me.reloadRes()
end func
- +*func load(node: xml@Node)
- do super(me, node)
- do me.setProps(node, ["text"])
+ +*func propsNames(): [][]char
+ ret ["anchorX", "anchorY", "readonly", "rightAligned", "text", "onChange", "onFocus"]
end func
- +*func save(node: xml@Node)
- do super(me, node)
- do node.setAttr("text", me.text)
+ +*func propsTypes(): []\doc_ar@PropType
+ ret [%enum_ $ \doc_ar@PropType, %enum_, %bool_, %bool_, %str, %str, %str]
end func
- +*func draw(pageX: int, pageY: int)
- var x: float :: (me.absX - pageX) $ float
- var y: float :: (me.absY - pageY) $ float
- var width: float :: me.width $ float
- var height: float :: me.height $ float
- do draw@rect(x, y, width, height, 0xFFEEEEEE)
- do \common@fontP.draw(x, y, me.text, draw@black)
+ +*func propsTypeDatas(): [][][]char
+ ret [["%fix", "%move", "%scale"], ["%fix", "%move", "%scale"], null, null, null, null, null]
end func
- +*func updateProp(listView: wnd@ListView, x: int, y: int)
- do super(me, listView, x, y)
- var idx: int :: listView.len()
- do listView.add("text")
- do listView.setText(idx + 0, 1, me.text)
+ +*func type(): []char
+ ret "wnd@Edit"
end func
- +*func setProp(prop: []char, value: []char)
- do super(me, prop, value)
- switch(prop)
- case "text"
- do me.text :: value
- end switch
+ +*func getSrcMake(indent: int, lines: list<[]char>, parent: []char)
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name} :: wnd@makeEdit(\{parent}, \{me.x}, \{me.y}, \{me.width}, \{me.height}, \{me.props.get("anchorX", &)}, \{me.props.get("anchorY", &)})")
+ var readonly: []char :: me.props.get("readonly", &)
+ if(readonly <> "false")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.readonly(\{readonly})")
+ end if
+ var rightAligned: []char :: me.props.get("rightAligned", &)
+ if(rightAligned <> "false")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.rightAligned(\{rightAligned})")
+ end if
+ var text: []char :: me.props.get("text", &)
+ if(^text > 0)
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.setText(\"\{text}\")")
+ end if
+ do me.addEvent(indent, lines, "onChange")
+ do me.addEvent(indent, lines, "onFocus")
end func
-
- +var text: []char
end class
-class Obj2dList(@Obj2dWndBase)
- *func ctor()
- do super(me)
- end func
-
- +*func getName(): []char
- ret "list"
+class ObjEditMulti(@ObjArWnd)
+ +*func draw(x: float, y: float, width: float, height: float, zoom: float)
+ do draw@rect(x * zoom, y * zoom, width * zoom, height * zoom, 0xFFFFFFFF)
+ do draw@rectLine(x * zoom, y * zoom, width * zoom, height * zoom, 0xFF7A7A7A)
+ var text: []char :: me.props.get("text", &)
+ do \common@fontP.drawScale((x + 5.0) * zoom, (y + 3.0) * zoom, zoom, zoom, text, draw@black)
end func
- +*func getMinMaxSize(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
- do minWidth :: 60
+ +*func getMinMax(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
+ do minWidth :: 10
do minHeight :: 19
do maxWidth :: lib@intMax
do maxHeight :: lib@intMax
end func
- +*func load(node: xml@Node)
- do super(me, node)
+ +*func getDefaultSize(width: &int, height: &int)
+ do width :: 100
+ do height :: 19
end func
- +*func save(node: xml@Node)
- do super(me, node)
+ +*func kind(): []char
+ ret "EditMulti"
end func
- +*func draw(pageX: int, pageY: int)
- var x: float :: (me.absX - pageX) $ float
- var y: float :: (me.absY - pageY) $ float
- var width: float :: me.width $ float
- var height: float :: me.height $ float
- do draw@rect(x, y, width, height, 0xFFFFFFFF)
- do draw@rectLine(x, y, width, height, 0xFF828790)
- do \common@fontP.draw(x + 5.0, y + 3.0, "list", draw@black)
+ +*func icon(): int
+ ret 11
end func
- +*func updateProp(listView: wnd@ListView, x: int, y: int)
- do super(me, listView, x, y)
+ +*func init(name: []char, visible: bool, x: int, y: int, width: int, height: int, props: dict<[]char, []char>)
+ do super(me, name, visible, x, y, width, height, props)
+ if(props <>& null)
+ ret
+ end if
+ do me.props.add("anchorX", "%fix")
+ do me.props.add("anchorY", "%fix")
+ do me.props.add("readonly", "false")
+ do me.props.add("text", "")
+ do me.props.add("onChange", "")
+ do me.props.add("onFocus", "")
+ do me.reloadRes()
end func
- +*func setProp(prop: []char, value: []char)
- do super(me, prop, value)
+ +*func propsNames(): [][]char
+ ret ["anchorX", "anchorY", "readonly", "text", "onChange", "onFocus"]
end func
-end class
-class Obj2dListView(@Obj2dWndBase)
- *func ctor()
- do super(me)
+ +*func propsTypes(): []\doc_ar@PropType
+ ret [%enum_ $ \doc_ar@PropType, %enum_, %bool_, %str, %str, %str]
end func
- +*func getName(): []char
- ret "list_view"
+ +*func propsTypeDatas(): [][][]char
+ ret [["%fix", "%move", "%scale"], ["%fix", "%move", "%scale"], null, null, null, null]
end func
- +*func getMinMaxSize(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
- do minWidth :: 60
- do minHeight :: 19
- do maxWidth :: lib@intMax
- do maxHeight :: lib@intMax
+ +*func type(): []char
+ ret "wnd@EditMulti"
end func
- +*func load(node: xml@Node)
- do super(me, node)
+ +*func getSrcMake(indent: int, lines: list<[]char>, parent: []char)
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name} :: wnd@makeEditMulti(\{parent}, \{me.x}, \{me.y}, \{me.width}, \{me.height}, \{me.props.get("anchorX", &)}, \{me.props.get("anchorY", &)})")
+ var readonly: []char :: me.props.get("readonly", &)
+ if(readonly <> "false")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.readonly(\{readonly})")
+ end if
+ var text: []char :: me.props.get("text", &)
+ if(^text > 0)
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.setText(\"\{text}\")")
+ end if
+ do me.addEvent(indent, lines, "onChange")
+ do me.addEvent(indent, lines, "onFocus")
end func
+end class
- +*func save(node: xml@Node)
- do super(me, node)
+class ObjLabel(@ObjArWnd)
+ +*func draw(x: float, y: float, width: float, height: float, zoom: float)
+ do draw@rect(x * zoom, y * zoom, width * zoom, height * zoom, 0xFFEEEEEE)
+ var text: []char :: me.props.get("text", &)
+ do \common@fontP.drawScale(x * zoom, y * zoom, zoom, zoom, text, draw@black)
end func
- +*func draw(pageX: int, pageY: int)
- var x: float :: (me.absX - pageX) $ float
- var y: float :: (me.absY - pageY) $ float
- var width: float :: me.width $ float
- var height: float :: me.height $ float
- do draw@rect(x, y, width, height, 0xFFFFFFFF)
- do draw@rectLine(x, y, width, height, 0xFF828790)
- do \common@fontP.draw(x + 5.0, y + 3.0, "list_view", draw@black)
+ +*func getMinMax(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
+ do minWidth :: 10
+ do minHeight :: 12
+ do maxWidth :: lib@intMax
+ do maxHeight :: 12
end func
- +*func updateProp(listView: wnd@ListView, x: int, y: int)
- do super(me, listView, x, y)
+ +*func getDefaultSize(width: &int, height: &int)
+ do width :: 35
+ do height :: 12
end func
- +*func setProp(prop: []char, value: []char)
- do super(me, prop, value)
+ +*func kind(): []char
+ ret "Label"
end func
-end class
-class Obj2dDraw(@Obj2dWndBase)
- *func ctor()
- do super(me)
- do me.equalMagnification :: false
+ +*func icon(): int
+ ret 3
end func
- +*func getName(): []char
- ret "draw"
+ +*func init(name: []char, visible: bool, x: int, y: int, width: int, height: int, props: dict<[]char, []char>)
+ do super(me, name, visible, x, y, width, height, props)
+ if(props <>& null)
+ ret
+ end if
+ do me.props.add("anchorX", "%fix")
+ do me.props.add("anchorY", "%fix")
+ do me.props.add("text", me.name)
+ do me.reloadRes()
end func
- +*func getMinMaxSize(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
- do minWidth :: 10
- do minHeight :: 10
- do maxWidth :: lib@intMax
- do maxHeight :: lib@intMax
+ +*func propsNames(): [][]char
+ ret ["anchorX", "anchorY", "text"]
end func
- +*func load(node: xml@Node)
- do super(me, node)
- do me.setProps(node, ["equal_magnification"])
+ +*func propsTypes(): []\doc_ar@PropType
+ ret [%enum_ $ \doc_ar@PropType, %enum_, %str]
end func
- +*func save(node: xml@Node)
- do super(me, node)
- do node.setAttr("equal_magnification", me.equalMagnification.toStr())
+ +*func propsTypeDatas(): [][][]char
+ ret [["%fix", "%move", "%scale"], ["%fix", "%move", "%scale"], null]
end func
- +*func draw(pageX: int, pageY: int)
- var x: float :: (me.absX - pageX) $ float
- var y: float :: (me.absY - pageY) $ float
- var width: float :: me.width $ float
- var height: float :: me.height $ float
- do draw@rect(x, y, width, height, 0xFF000000)
+ +*func type(): []char
+ ret "wnd@Label"
end func
- +*func updateProp(listView: wnd@ListView, x: int, y: int)
- do super(me, listView, x, y)
- var idx: int :: listView.len()
- do listView.add("equal_magnification")
- do listView.setText(idx + 0, 1, me.equalMagnification.toStr())
+ +*func getSrcMake(indent: int, lines: list<[]char>, parent: []char)
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name} :: wnd@makeLabel(\{parent}, \{me.x}, \{me.y}, \{me.width}, \{me.height}, \{me.props.get("anchorX", &)}, \{me.props.get("anchorY", &)}, \"\{me.props.get("text", &)}\")")
end func
-
- +*func setProp(prop: []char, value: []char)
- do super(me, prop, value)
- switch(prop)
- case "equal_magnification"
- do me.equalMagnification :: value = "true"
- end switch
- end func
-
- +var equalMagnification: bool
end class
-class Obj2dRadio(@Obj2dWndBase)
- *func ctor()
- do super(me)
- do me.text :: "radio"
- end func
-
- +*func getName(): []char
- ret "radio"
+class ObjChk(@ObjArWnd)
+ +*func draw(x: float, y: float, width: float, height: float, zoom: float)
+ do draw@rect(x * zoom, lib@floor(y + (height - 13.0) / 2.0) * zoom, 13.0 * zoom, 13.0 * zoom, 0xFFFFFFFF)
+ do draw@rectLine(x * zoom, lib@floor(y + (height - 13.0) / 2.0) * zoom, 13.0 * zoom, 13.0 * zoom, 0xFF333333)
+ var text: []char :: me.props.get("text", &)
+ do \common@fontP.drawScale((x + 18.0) * zoom, lib@floor(y + (height - \common@fontP.maxHeight()) / 2.0) * zoom, zoom, zoom, text, draw@black)
end func
- +*func getMinMaxSize(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
+ +*func getMinMax(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
do minWidth :: 16
do minHeight :: 16
do maxWidth :: lib@intMax
- do maxHeight :: lib@intMax
- end func
-
- +*func load(node: xml@Node)
- do super(me, node)
- do me.setProps(node, ["text"])
- end func
-
- +*func save(node: xml@Node)
- do super(me, node)
- do node.setAttr("text", me.text)
- end func
-
- +*func draw(pageX: int, pageY: int)
- var x: float :: (me.absX - pageX) $ float
- var y: float :: (me.absY - pageY) $ float
- var width: float :: me.width $ float
- var height: float :: me.height $ float
- do draw@circle(x + 6.5, y + height / 2.0, 6.5, 6.5, 0xFF333333)
- do draw@circle(x + 6.5, y + height / 2.0, 5.5, 5.5, 0xFFFFFFFF)
- do \common@fontP.draw(x + 18.0, lib@floor(y + (height - \common@fontP.maxHeight()) / 2.0), me.text, draw@black)
- end func
-
- +*func updateProp(listView: wnd@ListView, x: int, y: int)
- do super(me, listView, x, y)
- var idx: int :: listView.len()
- do listView.add("text")
- do listView.setText(idx + 0, 1, me.text)
+ do maxHeight :: 16
end func
- +*func setProp(prop: []char, value: []char)
- do super(me, prop, value)
- switch(prop)
- case "text"
- do me.text :: value
- end switch
+ +*func getDefaultSize(width: &int, height: &int)
+ do width :: 80
+ do height :: 16
end func
- +var text: []char
-end class
-
-class Obj2dEdit(@Obj2dWndBase)
- *func ctor()
- do super(me)
- do me.readonly :: false
+ +*func kind(): []char
+ ret "Chk"
end func
- +*func getName(): []char
- ret "edit"
+ +*func icon(): int
+ ret 1
end func
- +*func getMinMaxSize(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
- do minWidth :: 10
- do minHeight :: 19
- do maxWidth :: lib@intMax
- do maxHeight :: lib@intMax
+ +*func init(name: []char, visible: bool, x: int, y: int, width: int, height: int, props: dict<[]char, []char>)
+ do super(me, name, visible, x, y, width, height, props)
+ if(props <>& null)
+ ret
+ end if
+ do me.props.add("anchorX", "%fix")
+ do me.props.add("anchorY", "%fix")
+ do me.props.add("chk", "false")
+ do me.props.add("text", me.name)
+ do me.props.add("onPush", "")
+ do me.reloadRes()
end func
- +*func load(node: xml@Node)
- do super(me, node)
- do me.setProps(node, ["readonly"])
+ +*func propsNames(): [][]char
+ ret ["anchorX", "anchorY", "chk", "text", "onPush"]
end func
- +*func save(node: xml@Node)
- do super(me, node)
- do node.setAttr("readonly", me.readonly.toStr())
+ +*func propsTypes(): []\doc_ar@PropType
+ ret [%enum_ $ \doc_ar@PropType, %enum_, %bool_, %str, %str]
end func
- +*func draw(pageX: int, pageY: int)
- var x: float :: (me.absX - pageX) $ float
- var y: float :: (me.absY - pageY) $ float
- var width: float :: me.width $ float
- var height: float :: me.height $ float
- do draw@rect(x, y, width, height, 0xFFFFFFFF)
- do draw@rectLine(x, y, width, height, 0xFF7A7A7A)
- do \common@fontP.draw(x + 5.0, y + 3.0, "edit", draw@black)
+ +*func propsTypeDatas(): [][][]char
+ ret [["%fix", "%move", "%scale"], ["%fix", "%move", "%scale"], null, null, null]
end func
- +*func updateProp(listView: wnd@ListView, x: int, y: int)
- do super(me, listView, x, y)
- var idx: int :: listView.len()
- do listView.add("readonly")
- do listView.setText(idx + 0, 1, me.readonly.toStr())
+ +*func type(): []char
+ ret "wnd@Chk"
end func
- +*func setProp(prop: []char, value: []char)
- do super(me, prop, value)
- switch(prop)
- case "readonly"
- do me.readonly :: value = "true"
- end switch
+ +*func getSrcMake(indent: int, lines: list<[]char>, parent: []char)
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name} :: wnd@makeChk(\{parent}, \{me.x}, \{me.y}, \{me.width}, \{me.height}, \{me.props.get("anchorX", &)}, \{me.props.get("anchorY", &)}, \"\{me.props.get("text", &)}\")")
+ var chk: []char :: me.props.get("chk", &)
+ if(chk <> "false")
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name}.setChk(\{chk})")
+ end if
+ do me.addEvent(indent, lines, "onPush")
end func
-
- +var readonly: bool
end class
-class Obj2dEditMulti(@Obj2dWndBase)
- *func ctor()
- do super(me)
- do me.readonly :: false
- end func
-
- +*func getName(): []char
- ret "edit_multi"
+class ObjGroup(@ObjArWnd)
+ +*func draw(x: float, y: float, width: float, height: float, zoom: float)
+ var text: []char :: me.props.get("text", &)
+ do draw@line((x + 7.0) * zoom, (y + 6.0) * zoom, x * zoom, (y + 6.0) * zoom, 0xFFDCDCDC)
+ do draw@line(x * zoom, (y + 6.0) * zoom, x * zoom, (y + height) * zoom, 0xFFDCDCDC)
+ do draw@line(x * zoom, (y + height) * zoom, (x + width) * zoom, (y + height) * zoom, 0xFFDCDCDC)
+ do draw@line((x + width) * zoom, (y + height) * zoom, (x + width) * zoom, (y + 6.0) * zoom, 0xFFDCDCDC)
+ do draw@line((x + width) * zoom, (y + 6.0) * zoom, (x + 7.0 + \common@fontP.calcWidth(text)) * zoom, (y + 6.0) * zoom, 0xFFDCDCDC)
+ do \common@fontP.drawScale((x + 7.0) * zoom, y * zoom, zoom, zoom, text, draw@black)
end func
- +*func getMinMaxSize(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
- do minWidth :: 60
- do minHeight :: 19
+ +*func getMinMax(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
+ do minWidth :: 10
+ do minHeight :: 10
do maxWidth :: lib@intMax
do maxHeight :: lib@intMax
end func
- +*func load(node: xml@Node)
- do super(me, node)
- do me.setProps(node, ["readonly"])
- end func
-
- +*func save(node: xml@Node)
- do super(me, node)
- do node.setAttr("readonly", me.readonly.toStr())
- end func
-
- +*func draw(pageX: int, pageY: int)
- var x: float :: (me.absX - pageX) $ float
- var y: float :: (me.absY - pageY) $ float
- var width: float :: me.width $ float
- var height: float :: me.height $ float
- do draw@rect(x, y, width, height, 0xFFFFFFFF)
- do draw@rectLine(x, y, width, height, 0xFF7A7A7A)
- do \common@fontP.draw(x + 5.0, y + 3.0, "edit_multi", draw@black)
- end func
-
- +*func updateProp(listView: wnd@ListView, x: int, y: int)
- do super(me, listView, x, y)
- var idx: int :: listView.len()
- do listView.add("readonly")
- do listView.setText(idx + 0, 1, me.readonly.toStr())
+ +*func getDefaultSize(width: &int, height: &int)
+ do width :: 200
+ do height :: 100
end func
- +*func setProp(prop: []char, value: []char)
- do super(me, prop, value)
- switch(prop)
- case "readonly"
- do me.readonly :: value = "true"
- end switch
+ +*func kind(): []char
+ ret "Group"
end func
- +var readonly: bool
-end class
-
-class Obj2dTree(@Obj2dWndBase)
- *func ctor()
- do super(me)
+ +*func icon(): int
+ ret 4
end func
- +*func getName(): []char
+ +*func init(name: []char, visible: bool, x: int, y: int, width: int, height: int, props: dict<[]char, []char>)
+ do super(me, name, visible, x, y, width, height, props)
+ if(props <>& null)
+ ret
+ end if
+ do me.props.add("anchorX", "%fix")
+ do me.props.add("anchorY", "%fix")
+ do me.props.add("text", me.name)
+ do me.reloadRes()
end func
- +*func getMinMaxSize(minWidth: &int, minHeight: &int, maxWidth: &int, maxHeight: &int)
- do minWidth :: 60
- do minHeight :: 19
- do maxWidth :: lib@intMax
- do maxHeight :: lib@intMax
+ +*func becomeParent(): bool
+ ret true
end func
- +*func load(node: xml@Node)
- do super(me, node)
+ +*func propsNames(): [][]char
+ ret ["anchorX", "anchorY", "text"]
end func
- +*func save(node: xml@Node)
- do super(me, node)
+ +*func propsTypes(): []\doc_ar@PropType
+ ret [%enum_ $ \doc_ar@PropType, %enum_, %str]
end func
- +*func draw(pageX: int, pageY: int)
- var x: float :: (me.absX - pageX) $ float
- var y: float :: (me.absY - pageY) $ float
- var width: float :: me.width $ float
- var height: float :: me.height $ float
- do draw@rect(x, y, width, height, 0xFFFFFFFF)
- do draw@rectLine(x, y, width, height, 0xFF828790)
- do \common@fontP.draw(x + 5.0, y + 3.0, "tree", draw@black)
+ +*func propsTypeDatas(): [][][]char
+ ret [["%fix", "%move", "%scale"], ["%fix", "%move", "%scale"], null]
end func
- +*func updateProp(listView: wnd@ListView, x: int, y: int)
- do super(me, listView, x, y)
+ +*func type(): []char
+ ret "wnd@Group"
end func
- +*func setProp(prop: []char, value: []char)
- do super(me, prop, value)
+ +*func getSrcMake(indent: int, lines: list<[]char>, parent: []char)
+ do lines.add("\t".repeat(indent) ~ "do @\{me.name} :: wnd@makeGroup(\{parent}, \{me.x}, \{me.y}, \{me.width}, \{me.height}, \{me.props.get("anchorX", &)}, \{me.props.get("anchorY", &)}, \"\{me.props.get("text", &)}\")")
end func
end class
diff --git a/src/kuin_editor/doc_gen.kn b/src/kuin_editor/doc_gen.kn
new file mode 100644
index 00000000..7e861e25
--- /dev/null
+++ b/src/kuin_editor/doc_gen.kn
@@ -0,0 +1,233 @@
++class DocGen(\doc@Doc)
+ +*func fin()
+ do me.src.fin()
+ do me.designer.fin()
+ end func
+
+ +*func fix()
+ do me.designer.fix()
+ end func
+
+ +*func load(path: []char): bool
+ try
+ var xml: xml@Xml :: xml@makeXml(path)
+ var root: xml@Node :: xml.root()
+ switch(root.findChild("type").getValue())
+ case "wnd"
+ do me.create(#\doc_ar_wnd@DocArWnd)
+ case "g2d"
+ do me.create(#\doc_ar_2d@DocAr2d)
+ default
+ ret false
+ end switch
+ do me.designer.loadImpl(root)
+ do me.designer.fix()
+ catch
+ ret false
+ end try
+ ret true
+ end func
+
+ +*func save(path: []char): bool
+ try
+ var xml: xml@Xml :: xml@makeXmlEmpty()
+ var root: xml@Node :: xml.root()
+ var type: xml@Node :: root.addChild("type")
+ if(me.designer =$ \doc_ar_wnd@DocArWnd)
+ do type.setValue("wnd")
+ elif(me.designer =$ \doc_ar_2d@DocAr2d)
+ do type.setValue("g2d")
+ else
+ do type.setValue("unknown")
+ end if
+ do me.designer.saveImpl(root)
+ do xml.save(path, false)
+ catch
+ ret false
+ end try
+ ret true
+ end func
+
+ +*func getSrc(): [][]char
+ ret me.designer.getSrc()
+ end func
+
+ +*func draw(width: int, height: int)
+ do me.cur.draw(width, height)
+ end func
+
+ +*func mouseDownL(x: int, y: int)
+ do me.cur.mouseDownL(x, y)
+ end func
+
+ +*func mouseUpL(x: int, y: int)
+ do me.cur.mouseUpL(x, y)
+ end func
+
+ +*func mouseDoubleClick(x: int, y: int)
+ do me.cur.mouseDoubleClick(x, y)
+ end func
+
+ +*func mouseMove(x: int, y: int)
+ do me.cur.mouseMove(x, y)
+ end func
+
+ +*func focus(isFocus: bool)
+ do me.cur.focus(isFocus)
+ end func
+
+ +*func updateScrollBar()
+ do me.cur.updateScrollBar()
+ end func
+
+ +*func keyDown(key: wnd@Key, shiftCtrl: wnd@ShiftCtrl): bool
+ ret me.cur.keyDown(key, shiftCtrl)
+ end func
+
+ +*func keyUp(key: wnd@Key, shiftCtrl: wnd@ShiftCtrl)
+ do me.cur.keyUp(key, shiftCtrl)
+ end func
+
+ +*func keyChar(key: char)
+ do me.cur.keyChar(key)
+ end func
+
+ +*func scrollX(pos: int)
+ do me.cur.scrollX(pos)
+ end func
+
+ +*func scrollY(pos: int)
+ do me.cur.scrollY(pos)
+ end func
+
+ +*func wheelX(wheel: int)
+ do me.cur.wheelX(wheel)
+ end func
+
+ +*func wheelY(wheel: int)
+ do me.cur.wheelY(wheel)
+ end func
+
+ +*func setMouseImg(): wnd@MouseImg
+ ret me.cur.setMouseImg()
+ end func
+
+ +*func cmdUndo()
+ do me.cur.cmdUndo()
+ end func
+
+ +*func cmdRedo()
+ do me.cur.cmdRedo()
+ end func
+
+ +*func cmdCut()
+ do me.cur.cmdCut()
+ end func
+
+ +*func cmdCopy()
+ do me.cur.cmdCopy()
+ end func
+
+ +*func cmdPaste()
+ do me.cur.cmdPaste()
+ end func
+
+ +*func cmdDel()
+ do me.cur.cmdDel()
+ end func
+
+ +*func cmdSelAll()
+ do me.cur.cmdSelAll()
+ end func
+
+ +*func undoImpl(undo2: \doc@UndoCmd)
+ do me.cur.undoImpl(undo2)
+ end func
+
+ +*func getSelCode(): []char
+ ret me.cur.getSelCode()
+ end func
+
+ +*func updateUi()
+ do \form@btnCode.setRedraw(false)
+ if(me.cur =& me.src)
+ do \form@btnCode.setText(\common@langEn ?("Show Designer", "デザイナを表示"))
+ else
+ do \form@btnCode.setText(\common@langEn ?("Show Code", "コードを表示"))
+ end if
+ do \form@btnCode.setEnabled(true)
+ do \form@btnCode.setRedraw(true)
+
+ if(me.cur =& me.src)
+ do \form@listLt.setVisible(true)
+ do \form@listLt.setRedraw(false)
+ do \form@listLt.clear()
+ do \form@listLt.style(%list_)
+ do \form@listLt.setRedraw(true)
+
+ do \form@treeLb.setVisible(true)
+ do \form@treeLb.setRedraw(false)
+ do \form@treeLb.clear()
+ do \form@treeLb.expand(true)
+ do \form@treeLb.setRedraw(true)
+
+ do \form@listLb.setVisible(false)
+
+ do \form@listRb.setVisible(true)
+ do \form@listRb.setRedraw(false)
+ do \form@listRb.clearAll()
+ do \form@listRb.setRedraw(true)
+
+ do \form@groupRbAr.setVisible(false)
+ else
+ do \form@listLt.setVisible(true)
+
+ do \form@treeLb.setVisible(false)
+
+ do \form@listLb.setVisible(true)
+
+ do \form@listRb.setVisible(false)
+
+ do me.designer.updateUi()
+ end if
+ end func
+
+ +*func onEvent(event: \doc@Event)
+ do me.cur.onEvent(event)
+ end func
+
+ +*func getChanged(): bool
+ ret me.designer.getChanged()
+ end func
+
+ +*func setChanged(value: bool)
+ do me.designer.setChanged(value)
+ end func
+
+ +func create(designer: @DocDesigner)
+ do me.src :: #\doc_src@DocSrc
+ do me.src.setLock(true)
+ do me.designer :: designer
+ do me.cur :: me.designer
+ end func
+
+ +func swapMode()
+ do me.cur :: me.cur =& me.src ?(me.designer $ \doc@Doc, me.src $ \doc@Doc)
+ if(me.cur =& me.src)
+ do me.designer.fix()
+ do me.src.setSrc(me.designer.getSrc())
+ end if
+ end func
+
+ var src: \doc_src@DocSrc
+ +var designer: @DocDesigner
+ var cur: \doc@Doc
+end class
+
++class DocDesigner(\doc@Doc)
+ +func loadImpl(xmlNode: xml@Node)
+ end func
+
+ +func saveImpl(xmlNode: xml@Node)
+ end func
+end class
diff --git a/src/kuin_editor/doc_src.kn b/src/kuin_editor/doc_src.kn
index 875b41d6..005b1020 100644
--- a/src/kuin_editor/doc_src.kn
+++ b/src/kuin_editor/doc_src.kn
@@ -40,6 +40,9 @@ end func
+class DocSrc(\doc@Doc)
*func ctor()
do super(me)
+ do me.undo :: #undo@Undo
+ do me.undo.init(1024)
+
do me.src :: #Src
do me.src.src :: null
do me.src.color :: null
@@ -56,11 +59,14 @@ end func
do me.resetListInfoItem()
do me.dirtyLine :: -1
do me.dirtyLineForce :: false
+ do me.caretX :: -1
+ do me.caretY :: -1
+ do me.caretShown :: false
end func
- +*func update()
+ +*func fix()
do me.dirtyLineForce :: true
- do me.interpret1SetDirty(-1, false)
+ do me.interpret1SetDirty(-1, false, false)
end func
+*func load(path: []char): bool
@@ -95,8 +101,12 @@ end func
ret true
end func
+ +*func getSrc(): [][]char
+ ret me.src.src
+ end func
+
+*func draw(width: int, height: int)
- do draw@rect(0.0, 0.0, width $ float, height $ float, \common@colorBack)
+ do draw@rect(0.0, 0.0, width $ float, height $ float, \form@getLockingEditor() | me.lock ?(\common@colorBackLocked, \common@colorBack))
var lineX: float :: (me.lineNumWidth - 2) $ float
do draw@line(lineX, 0.0, lineX, height $ float, colorLineNum)
for i(0, ^me.src.src - 1 - me.pageY)
@@ -105,7 +115,19 @@ end func
skip i
end if
var str: []char :: (me.pageY + i + 1).toStr()
- do \common@font.draw((me.lineNumWidth - (^str + 1) * \common@cellWidth + \common@cellWidth / 2) $ float, y, str, colorLineNum)
+ var flags: LineFlag :: me.pageY + i >= ^me.src.flags ?(%none, me.src.flags[me.pageY + i])
+ if(flags.and(%breakPoint) <> %none)
+ do draw@rect(1.0, y + 1.0, lineX - 2.0, \common@cellHeight $ float - 2.0, colorBreakPointBack)
+ if(\src@breakPos <>& null & \src@breakPos.src = \src@curDocName & \src@breakPos.row = me.pageY + i + 1)
+ do draw@rect(1.0, y + 1.0, (lineX - 2.0) / 2.0, \common@cellHeight $ float - 2.0, colorBreakBack)
+ end if
+ do \common@font.draw((me.lineNumWidth - (^str + 1) * \common@cellWidth + \common@cellWidth / 2) $ float, y, str, colorBreakPoint)
+ else
+ if(\src@breakPos <>& null & \src@breakPos.src = \src@curDocName & \src@breakPos.row = me.pageY + i + 1)
+ do draw@rect(1.0, y + 1.0, (lineX - 2.0) / 2.0, \common@cellHeight $ float - 2.0, colorBreakBack)
+ end if
+ do \common@font.draw((me.lineNumWidth - (^str + 1) * \common@cellWidth + \common@cellWidth / 2) $ float, y, str, colorLineNum)
+ end if
end for
var areaX1: int :: me.areaX
@@ -181,64 +203,8 @@ end func
end if
end for
end for
- end func
-
- +*func updateProp(listView: wnd@ListView)
- do me.errList.sort()
- do me.errList.head()
- while(!me.errList.term())
- do listView.add(me.errList.get().text)
- do me.errList.next()
- end while
- end func
-
- +*func updateTree(tree: wnd@TreeMulti)
- ; TODO:
- end func
-
- +*func updateList(list_: wnd@List)
- do \snippet@updateList(list_)
- end func
- +*func treeItemOnSel()
- ; TODO:
- end func
-
- +*func treeItemOnMoveNode()
- ; TODO:
- end func
-
- +*func listObjOnSel()
- var sel: int :: \form@listObj.getSel()
- if(sel = -1)
- ret
- end if
- var code: []char :: \snippet@getCode(\form@listObj.getText(sel))
- if(code =& null)
- do \form@updateList()
- ret
- end if
- do me.undo.recordBegin()
- if(me.areaSel())
- do me.delAreaStr()
- end if
- do me.ins(me.cursorX, me.cursorY, code, true)
- do me.interpret1SetDirty(me.cursorY, true)
- do me.undo.recordEnd()
- do me.refreshCursor(false, true)
- do \form@paintDrawEditor()
- end func
-
- +*func listPropOnSel(listView: wnd@ListView)
- end func
-
- +*func listPropOnMouseClick(listView: wnd@ListView)
- var sel: int :: listView.getSel()
- if(sel <> -1 & sel < ^me.errList)
- do me.errList.head()
- var item: @ErrListItem :: me.errList.getOffset(sel)
- do \src@jumpSrc(item.pos)
- end if
+ do draw@rect(me.caretX $ float, me.caretY $ float, 2.0, \common@cellHeight $ float, 0xFF000000)
end func
+*func mouseDownL(x: int, y: int)
@@ -249,7 +215,8 @@ end func
do me.areaX :: me.cursorX
do me.areaY :: me.cursorY
end if
- do me.interpret1SetDirty(me.cursorY, false)
+ do me.interpret1SetDirty(me.cursorY, false, false)
+ do \completion@close()
do \form@paintDrawEditor()
end func
@@ -277,7 +244,7 @@ end func
do me.cursorX :+ 1
end while
end if
- do me.interpret1SetDirty(me.cursorY, false)
+ do me.interpret1SetDirty(me.cursorY, false, false)
do \form@paintDrawEditor()
end func
@@ -285,20 +252,24 @@ end func
if(\form@dragging())
do me.mousePosToCharPos(x, y)
do me.refreshCursor(false, true)
- do me.interpret1SetDirty(me.cursorY, false)
+ do me.interpret1SetDirty(me.cursorY, false, false)
do \form@paintDrawEditor()
end if
end func
+*func focus(isFocus: bool)
if(isFocus)
- do \form@drawEditor.showCaret(\common@cellHeight, \common@font)
- do me.refreshCursor(false, true)
+ do me.caretShown :: true
+ do me.updateScrollBar()
else
- do \form@drawEditor.hideCaret()
+ do me.caretShown :: false
end if
end func
+ +*func updateScrollBar()
+ do me.refreshCursor(false, true)
+ end func
+
+*func keyDown(key: wnd@Key, shiftCtrl: wnd@ShiftCtrl): bool
switch(key)
case %ctrl
@@ -307,8 +278,7 @@ end func
end if
ret true
case %bs
- if (\form@getLockingEditor())
- do \form@showMsgRunning()
+ if(me.locked())
ret true
end if
if(shiftCtrl = %none)
@@ -318,7 +288,7 @@ end func
else
do me.bs(me.cursorX, me.cursorY, 1, true)
end if
- do me.interpret1SetDirty(me.cursorY, true)
+ do me.interpret1SetDirty(me.cursorY, true, false)
do me.undo.recordEnd()
do me.refreshCursor(false, true)
do \form@paintDrawEditor()
@@ -327,14 +297,13 @@ end func
case %tab
switch(shiftCtrl)
case %none
- if (\form@getLockingEditor())
- do \form@showMsgRunning()
+ if(me.locked())
ret true
end if
if(!me.areaSel())
do me.undo.recordBegin()
do me.ins(me.cursorX, me.cursorY, "\t", true)
- do me.interpret1SetDirty(me.cursorY, true)
+ do me.interpret1SetDirty(me.cursorY, true, false)
do me.undo.recordEnd()
do me.refreshCursor(false, true)
do \form@paintDrawEditor()
@@ -345,8 +314,7 @@ end func
end if
ret true
case %shift
- if (\form@getLockingEditor())
- do \form@showMsgRunning()
+ if(me.locked())
ret true
end if
if(me.areaSel())
@@ -357,8 +325,7 @@ end func
ret true
end switch
case %enter
- if (\form@getLockingEditor())
- do \form@showMsgRunning()
+ if(me.locked())
ret true
end if
if(shiftCtrl = %none)
@@ -368,7 +335,7 @@ end func
do me.delAreaStr()
end if
do me.ins(me.cursorX, me.cursorY, "\n", true)
- do me.interpret1SetDirty(me.cursorY, true)
+ do me.interpret1SetDirty(me.cursorY, true, false)
do me.undo.recordEnd()
do me.refreshCursor(false, true)
do \form@paintDrawEditor()
@@ -387,8 +354,9 @@ end func
do me.cursorY :- height / \common@cellHeight
do me.setAbsoluteX(absoluteX)
do me.refreshCursor(false, true)
- do me.interpret1SetDirty(me.cursorY, false)
+ do me.interpret1SetDirty(me.cursorY, false, false)
end if
+ do \form@paintDrawEditor()
ret true
end block
case %pageDown
@@ -403,8 +371,9 @@ end func
do me.cursorY :+ height / \common@cellHeight
do me.setAbsoluteX(absoluteX)
do me.refreshCursor(false, true)
- do me.interpret1SetDirty(me.cursorY, false)
+ do me.interpret1SetDirty(me.cursorY, false, false)
end if
+ do \form@paintDrawEditor()
ret true
end block
case %end_
@@ -414,7 +383,9 @@ end func
do me.cursorY :: lib@intMax
end if
do me.refreshCursor(false, true)
- do me.interpret1SetDirty(me.cursorY, false)
+ do \completion@close()
+ do \form@paintDrawEditor()
+ do me.interpret1SetDirty(me.cursorY, false, false)
ret true
case %home
do me.setArea(shiftCtrl)
@@ -423,7 +394,9 @@ end func
do me.cursorY :: 0
end if
do me.refreshCursor(false, true)
- do me.interpret1SetDirty(me.cursorY, false)
+ do \completion@close()
+ do \form@paintDrawEditor()
+ do me.interpret1SetDirty(me.cursorY, false, false)
ret true
case %left
if(shiftCtrl = %ctrl)
@@ -432,21 +405,25 @@ end func
do me.setArea(shiftCtrl)
do me.cursorX :- 1
do me.refreshCursor(false, true)
- do me.interpret1SetDirty(me.cursorY, false)
+ do me.interpret1SetDirty(me.cursorY, false, false)
end if
+ do \completion@close()
+ do \form@paintDrawEditor()
ret true
case %up
if(shiftCtrl = %none & \completion@displayed() & \completion@moveCursorUp())
; Do nothing.
elif(shiftCtrl = %ctrl)
do me.scrollPageY(-1)
+ do \form@paintDrawEditor()
else
do me.setArea(shiftCtrl)
var absoluteX: int :: me.getAbsoluteX()
do me.cursorY :- 1
do me.setAbsoluteX(absoluteX)
do me.refreshCursor(false, true)
- do me.interpret1SetDirty(me.cursorY, false)
+ do me.interpret1SetDirty(me.cursorY, false, false)
+ do \form@paintDrawEditor()
end if
ret true
case %right
@@ -456,21 +433,25 @@ end func
do me.setArea(shiftCtrl)
do me.cursorX :+ 1
do me.refreshCursor(true, true)
- do me.interpret1SetDirty(me.cursorY, false)
+ do me.interpret1SetDirty(me.cursorY, false, false)
end if
+ do \completion@close()
+ do \form@paintDrawEditor()
ret true
case %down
if(shiftCtrl = %none & \completion@displayed() & \completion@moveCursorDown())
; Do nothing.
elif(shiftCtrl = %ctrl)
do me.scrollPageY(1)
+ do \form@paintDrawEditor()
else
do me.setArea(shiftCtrl)
var absoluteX: int :: me.getAbsoluteX()
do me.cursorY :+ 1
do me.setAbsoluteX(absoluteX)
do me.refreshCursor(false, true)
- do me.interpret1SetDirty(me.cursorY, false)
+ do me.interpret1SetDirty(me.cursorY, false, false)
+ do \form@paintDrawEditor()
end if
ret true
case %ins
@@ -486,12 +467,10 @@ end func
do \completion@setAlpha(230)
end if
end switch
- do \form@paintDrawEditor()
end func
+*func keyChar(key: char)
- if (\form@getLockingEditor())
- do \form@showMsgRunning()
+ if(me.locked())
ret
end if
if(key = '\t' | me.charWidth(key, 0) = 0)
@@ -505,7 +484,7 @@ end func
do me.delAreaStr()
end if
do me.ins(me.cursorX, me.cursorY, [key], true)
- do me.interpret1SetDirty(me.cursorY, true)
+ do me.interpret1SetDirty(me.cursorY, true, true)
do me.undo.recordEnd()
do me.refreshCursor(false, true)
do \form@paintDrawEditor()
@@ -536,8 +515,7 @@ end func
end func
+*func cmdUndo()
- if (\form@getLockingEditor())
- do \form@showMsgRunning()
+ if(me.locked())
ret
end if
if(me.areaSel())
@@ -549,8 +527,7 @@ end func
end func
+*func cmdRedo()
- if (\form@getLockingEditor())
- do \form@showMsgRunning()
+ if(me.locked())
ret
end if
if(me.areaSel())
@@ -562,15 +539,14 @@ end func
end func
+*func cmdCut()
- if (\form@getLockingEditor())
- do \form@showMsgRunning()
+ if(me.locked())
ret
end if
if(me.areaSel())
do me.copyAreaStr()
do me.undo.recordBegin()
do me.delAreaStr()
- do me.interpret1SetDirty(me.cursorY, true)
+ do me.interpret1SetDirty(me.cursorY, true, false)
do me.undo.recordEnd()
do me.refreshCursor(false, true)
do \form@paintDrawEditor()
@@ -584,8 +560,7 @@ end func
end func
+*func cmdPaste()
- if (\form@getLockingEditor())
- do \form@showMsgRunning()
+ if(me.locked())
ret
end if
var str: []char :: wnd@getClipboardStr()
@@ -595,7 +570,7 @@ end func
do me.delAreaStr()
end if
do me.ins(me.cursorX, me.cursorY, str, true)
- do me.interpret1SetDirty(me.cursorY, true)
+ do me.interpret1SetDirty(me.cursorY, true, false)
do me.undo.recordEnd()
do me.refreshCursor(false, true)
do \form@paintDrawEditor()
@@ -603,8 +578,7 @@ end func
end func
+*func cmdDel()
- if (\form@getLockingEditor())
- do \form@showMsgRunning()
+ if(me.locked())
ret
end if
do me.undo.recordBegin()
@@ -613,7 +587,7 @@ end func
else
do me.del(me.cursorX, me.cursorY, 1, true)
end if
- do me.interpret1SetDirty(me.cursorY, true)
+ do me.interpret1SetDirty(me.cursorY, true, false)
do me.undo.recordEnd()
do me.refreshCursor(false, true)
do \form@paintDrawEditor()
@@ -625,7 +599,7 @@ end func
do me.cursorX :: lib@intMax
do me.cursorY :: lib@intMax
do me.refreshCursor(false, true)
- do me.interpret1SetDirty(me.cursorY, false)
+ do me.interpret1SetDirty(me.cursorY, false, false)
do \form@paintDrawEditor()
end func
@@ -677,7 +651,136 @@ end func
ret str
end func
- func setSrc(src: [][]char)
+ +*func getCursorWord(): []char
+ if(me.areaSel())
+ var x1: int :: me.areaX
+ var y1: int :: me.areaY
+ var x2: int :: me.cursorX
+ var y2: int :: me.cursorY
+ if(y1 > y2 | y1 = y2 & x1 > x2)
+ do x1 :$ x2
+ do y1 :$ y2
+ end if
+ if(y1 = y2)
+ ret me.src.src[y1].sub(x1, x2 - x1).trim()
+ else
+ ret me.src.src[y1].sub(x1, -1).trim()
+ end if
+ else
+ var x1: int :: me.cursorX
+ var x2: int :: x1
+ var y1: int :: me.cursorY
+ while loop(x1 > 0)
+ var c: char :: me.src.src[y1][x1 - 1]
+ if(!('a' <= c & c <= 'z' | 'A' <= c & c <= 'Z' | '0' <= c & c <= '9' | c = '@' | c = '_' | c = '\\'))
+ break loop
+ end if
+ do x1 :- 1
+ end while
+ while loop(x2 < ^me.src.src[y1])
+ var c: char :: me.src.src[y1][x2]
+ if(!('a' <= c & c <= 'z' | 'A' <= c & c <= 'Z' | '0' <= c & c <= '9' | c = '@' | c = '_' | c = '\\'))
+ break loop
+ end if
+ do x2 :+ 1
+ end while
+ ret x1 = x2 ?(null, me.src.src[y1].sub(x1, x2 - x1).trim())
+ end if
+ end func
+
+ +*func updateUi()
+ do \form@btnCode.setText(\common@langEn ?("Show Designer", "デザイナを表示"))
+ do \form@btnCode.setEnabled(false)
+
+ do \form@listLt.setVisible(true)
+ do \form@listLt.setRedraw(false)
+ do \form@listLt.clear()
+ do \form@listLt.style(%list_)
+ do \snippet@updateList(\form@listLt)
+ do \form@listLt.setRedraw(true)
+
+ do \form@treeLb.setVisible(true)
+ do \form@treeLb.setRedraw(false)
+ do \form@treeLb.clear()
+ do \form@treeLb.expand(true)
+ do \form@treeLb.setRedraw(true)
+
+ do \form@listLb.setVisible(false)
+
+ do \form@listRb.setVisible(true)
+ do \form@listRb.setRedraw(false)
+ do \form@listRb.clearAll()
+ do \form@listRb.addColumn(\common@langEn ?("Error", "エラー"))
+ do \form@listRb.adjustWidth()
+ do me.errList.sort()
+ do me.errList.head()
+ while(!me.errList.term())
+ do \form@listRb.add(me.errList.get().text, -1)
+ do me.errList.next()
+ end while
+ do \form@listRb.setRedraw(true)
+
+ do \form@groupRbAr.setVisible(false)
+ end func
+
+ +*func onEvent(event: \doc@Event)
+ switch(event)
+ case %listLtOnMouseClick
+ var sel: int :: \form@listLt.getSel()
+ if(sel = -1)
+ ret
+ end if
+ var code: []char :: \snippet@showPlace(\form@listLt.getText(&, sel, 0))
+ if(code =& null)
+ ret
+ end if
+ do me.undo.recordBegin()
+ if(me.areaSel())
+ do me.delAreaStr()
+ end if
+ do me.ins(me.cursorX, me.cursorY, code, true)
+ do me.interpret1SetDirty(me.cursorY, true, false)
+ do me.undo.recordEnd()
+ do me.refreshCursor(false, true)
+ do \form@paintDrawEditor()
+ case %listRbOnMouseClick
+ var sel: int :: \form@listRb.getSel()
+ if(sel <> -1 & sel < ^me.errList)
+ do me.errList.head()
+ var item: @ErrListItem :: me.errList.getOffset(sel)
+ do \src@jumpSrc(item.pos)
+ end if
+ end switch
+ end func
+
+ +*func getChanged(): bool
+ ret me.changed
+ end func
+
+ +func toggleBreakPoint()
+ if(0 <= me.cursorY & me.cursorY < ^me.src.flags)
+ if(me.src.flags[me.cursorY].and(%breakPoint) = %none)
+ do me.src.flags[me.cursorY] :: me.src.flags[me.cursorY].or(%breakPoint)
+ else
+ do me.src.flags[me.cursorY] :: me.src.flags[me.cursorY].and((%breakPoint $ LineFlag).not())
+ end if
+ do \form@paintDrawEditor()
+ end if
+ end func
+
+ +func setBreakPoint(y: int)
+ if(0 <= y & y < ^me.src.flags)
+ do me.src.flags[y] :: me.src.flags[y].or(%breakPoint)
+ end if
+ end func
+
+ +func unsetBreakPoint(y: int)
+ if(0 <= y & y < ^me.src.flags)
+ do me.src.flags[y] :: me.src.flags[y].and((%breakPoint $ LineFlag).not())
+ end if
+ end func
+
+ +func setSrc(src: [][]char)
if(src =& null | ^src = 0)
do me.src.src :: [""]
do me.src.color :: [#[0]bit8]
@@ -696,10 +799,6 @@ end func
end if
end func
- +func getSrc(): [][]char
- ret me.src.src
- end func
-
+func findPrev(pattern: []char, distinguishCase: bool, onlyWord: bool, regularExpression: bool): bool
var findBeginX: int :: (me.areaX <> -1 & me.areaX < me.cursorX ?(me.areaX, me.cursorX))
var findBeginY: int :: me.cursorY
@@ -720,7 +819,7 @@ end func
do me.cursorX :: pos + ^found
do me.cursorY :: i
do me.refreshCursor(false, true)
- do me.interpret1SetDirty(me.cursorY, false)
+ do me.interpret1SetDirty(me.cursorY, false, false)
do \form@paintDrawEditor()
ret true
end if
@@ -733,7 +832,7 @@ end func
do me.cursorX :: pos + ^found
do me.cursorY :: i
do me.refreshCursor(false, true)
- do me.interpret1SetDirty(me.cursorY, false)
+ do me.interpret1SetDirty(me.cursorY, false, false)
do \form@paintDrawEditor()
ret true
end if
@@ -761,7 +860,7 @@ end func
do me.cursorX :: pos + ^found
do me.cursorY :: i
do me.refreshCursor(false, true)
- do me.interpret1SetDirty(me.cursorY, false)
+ do me.interpret1SetDirty(me.cursorY, false, false)
do \form@paintDrawEditor()
ret true
end if
@@ -774,7 +873,7 @@ end func
do me.cursorX :: pos + ^found
do me.cursorY :: i
do me.refreshCursor(false, true)
- do me.interpret1SetDirty(me.cursorY, false)
+ do me.interpret1SetDirty(me.cursorY, false, false)
do \form@paintDrawEditor()
ret true
end if
@@ -782,6 +881,67 @@ end func
ret false
end func
+ +func findSel(list_: wnd@List, poses: list<\src@Pos>, srcName: []char, pattern: []char, distinguishCase: bool, onlyWord: bool, regularExpression: bool)
+ if(!me.areaSel())
+ ret
+ end if
+ var areaX1: int :: me.cursorX
+ var areaY1: int :: me.cursorY
+ var areaX2: int :: me.areaX
+ var areaY2: int :: me.areaY
+ if(areaY1 > areaY2 | areaY1 = areaY2 & areaX1 > areaX2)
+ do areaX1 :$ areaX2
+ do areaY1 :$ areaY2
+ end if
+ do me.cursorX :: areaX1
+ do me.cursorY :: areaY1
+ do me.areaX :: -1
+ do me.areaY :: -1
+ while loop(true)
+ var oldX: int :: me.cursorX < me.areaX ?(me.cursorX, me.areaX)
+ var oldY: int :: me.cursorY
+ if(!me.findNext(pattern, distinguishCase, onlyWord, regularExpression))
+ break loop
+ end if
+ var newX: int :: me.cursorX < me.areaX ?(me.cursorX, me.areaX)
+ var newY: int :: me.cursorY
+ if(newY < oldY | newY = oldY & newX <= oldX | newY > areaY2 | newY = areaY2 & newX + ^pattern > areaX2)
+ break loop
+ end if
+ do list_.add("[" ~ srcName ~ ": " ~ (newY + 1).toStr() ~ ", " ~ (newX + 1).toStr() ~ "]")
+ var pos: \src@Pos :: #\src@Pos
+ do pos.src :: srcName
+ do pos.row :: newY + 1
+ do pos.col :: newX + 1
+ do poses.add(pos)
+ end while
+ end func
+
+ +func findAll(list_: wnd@List, poses: list<\src@Pos>, srcName: []char, pattern: []char, distinguishCase: bool, onlyWord: bool, regularExpression: bool)
+ do me.cursorX :: 0
+ do me.cursorY :: 0
+ do me.areaX :: -1
+ do me.areaY :: -1
+ while loop(true)
+ var oldX: int :: me.cursorX < me.areaX ?(me.cursorX, me.areaX)
+ var oldY: int :: me.cursorY
+ if(!me.findNext(pattern, distinguishCase, onlyWord, regularExpression))
+ break loop
+ end if
+ var newX: int :: me.cursorX < me.areaX ?(me.cursorX, me.areaX)
+ var newY: int :: me.cursorY
+ if(newY < oldY | newY = oldY & newX <= oldX)
+ break loop
+ end if
+ do list_.add("[" ~ srcName ~ ": " ~ (newY + 1).toStr() ~ ", " ~ (newX + 1).toStr() ~ "]")
+ var pos: \src@Pos :: #\src@Pos
+ do pos.src :: srcName
+ do pos.row :: newY + 1
+ do pos.col :: newX + 1
+ do poses.add(pos)
+ end while
+ end func
+
+func replaceOne(pattern: []char, replaceStr: []char, distinguishCase: bool, onlyWord: bool, regularExpression: bool)
if(!me.areaSel() | me.areaY <> me.cursorY)
ret
@@ -807,11 +967,45 @@ end func
do me.undo.recordBegin()
do me.del(x1, me.cursorY, ^found, true)
do me.ins(x1, me.cursorY, replaceStr, true)
- do me.interpret1SetDirty(me.cursorY, true)
+ do me.interpret1SetDirty(me.cursorY, true, false)
do me.undo.recordEnd()
end if
end func
+ +func replaceSel(pattern: []char, replaceStr: []char, distinguishCase: bool, onlyWord: bool, regularExpression: bool): int
+ if(!me.areaSel())
+ ret 0
+ end if
+ var areaX1: int :: me.cursorX
+ var areaY1: int :: me.cursorY
+ var areaX2: int :: me.areaX
+ var areaY2: int :: me.areaY
+ if(areaY1 > areaY2 | areaY1 = areaY2 & areaX1 > areaX2)
+ do areaX1 :$ areaX2
+ do areaY1 :$ areaY2
+ end if
+ do me.cursorX :: areaX1
+ do me.cursorY :: areaY1
+ do me.areaX :: -1
+ do me.areaY :: -1
+ var cnt: int :: 0
+ while loop(true)
+ var oldX: int :: me.cursorX < me.areaX ?(me.cursorX, me.areaX)
+ var oldY: int :: me.cursorY
+ if(!me.findNext(pattern, distinguishCase, onlyWord, regularExpression))
+ break loop
+ end if
+ var newX: int :: me.cursorX < me.areaX ?(me.cursorX, me.areaX)
+ var newY: int :: me.cursorY
+ if(newY < oldY | newY = oldY & newX <= oldX | newY > areaY2 | newY = areaY2 & newX + ^pattern > areaX2)
+ break loop
+ end if
+ do me.replaceOne(pattern, replaceStr, distinguishCase, onlyWord, regularExpression)
+ do cnt :+ 1
+ end while
+ ret cnt
+ end func
+
+func replaceAll(pattern: []char, replaceStr: []char, distinguishCase: bool, onlyWord: bool, regularExpression: bool): int
do me.cursorX :: 0
do me.cursorY :: 0
@@ -841,7 +1035,7 @@ end func
do me.areaX :: -1
do me.areaY :: -1
do me.refreshCursor(false, true)
- do me.interpret1SetDirty(me.cursorY, false)
+ do me.interpret1SetDirty(me.cursorY, false, false)
end func
+func complementDecision(): bool
@@ -866,13 +1060,33 @@ end func
end if
end func
+ +func getBreakPoints(srcName: []char, poses: list<\src@Pos>)
+ for i(0, ^me.src.flags - 1)
+ if(me.src.flags[i].and(%breakPoint) <> %none)
+ var pos: \src@Pos :: #\src@Pos
+ do pos.src :: srcName
+ do pos.row :: i + 1
+ do pos.col :: 1
+ do poses.add(pos)
+ end if
+ end for
+ end func
+
+ +func setLock(enabled: bool)
+ do me.lock :: enabled
+ end func
+
const colorLineNum: int :: 0xFFFF7F7F
const colorAreaBack: int :: 0xFF808080
const colorErrBack: int :: 0xFFFF3333
+ const colorBreakPointBack: int :: 0xFFFF9999
+ const colorBreakPoint: int :: 0xFFFFFFFF
+ const colorBreakBack: int :: 0xFFCCCC99
enum LineFlag
none :: 0x00
nextLine :: 0x01
+ breakPoint :: 0x02
end enum
class Src()
@@ -919,6 +1133,10 @@ end func
+var errList: list<@ErrListItem>
var dirtyLine: int
var dirtyLineForce: bool
+ var caretX: int
+ var caretY: int
+ var caretShown: bool
+ var lock: bool
func areaSel(): bool
ret me.areaX <> -1 & (me.areaX <> me.cursorX | me.areaY <> me.cursorY)
@@ -954,6 +1172,9 @@ end func
func mousePosToCharPos(mouseX: int, mouseY: int)
do me.cursorY :: me.pageY + mouseY / \common@cellHeight
+ if(me.cursorY < 0)
+ do me.cursorY :: 0
+ end if
if(me.cursorY >= ^me.src.src)
do me.cursorX :: 0
ret
@@ -1061,12 +1282,18 @@ end func
do x :: me.lineNumWidth + (x - me.pageX) * \common@cellWidth
var y: int :: (me.cursorY - me.pageY) * \common@cellHeight
if(x + 2 <= 0 | scrWidth - 17 <= x | y + \common@cellHeight <= 0 | scrHeight - 17 <= y)
+ do me.caretX :: -1
+ do me.caretY :: -1
do \form@drawEditor.moveCaret(-1, -1)
else
+ do me.caretX :: x
+ do me.caretY :: y
do \form@drawEditor.moveCaret(x, y)
end if
end block
+ do \completion@updatePos()
+
func log10(n: int): int
var result: int :: 0
var m: int :: 1
@@ -1187,7 +1414,7 @@ end func
do me.ins(0, i, "\t", true)
end if
end for
- do me.interpret1SetDirty(y2, true)
+ do me.interpret1SetDirty(y2, true, false)
do me.undo.recordEnd()
do me.areaX :: oldAreaX
do me.areaY :: oldAreaY
@@ -1224,7 +1451,7 @@ end func
do me.del(0, i, 1, true)
end if
end for
- do me.interpret1SetDirty(y2, true)
+ do me.interpret1SetDirty(y2, true, false)
do me.undo.recordEnd()
do me.areaX :: oldAreaX
do me.areaY :: oldAreaY
@@ -1397,7 +1624,7 @@ end func
ret x = ^me.src.src[y] ?(-1, x)
end func
- func interpret1SetDirty(line: int, modified: bool)
+ func interpret1SetDirty(line: int, modified: bool, showCompletion: bool)
var record: bool :: !me.undo.recording()
if(record)
do me.undo.recordBegin()
@@ -1421,7 +1648,7 @@ end func
do \src@resetErrList()
try
- do \dll@interpret2(\src@mainSrcName, \src@getSrc, null, \form@getEnv(), \form@logForInterpret, \common@langEn ?(1, 0))
+ do \dll@interpret2(\src@mainSrcPath, \src@getSrc, null, \form@getEnv(), \form@logForInterpret, \common@langEn ?(1, 0))
catch
end try
do \src@updateErrList()
@@ -1445,14 +1672,12 @@ end func
do me.undo.recordEnd()
end if
- if(modified)
+ if(showCompletion & modified)
var first: int
var word: []char :: me.parseWord(me.cursorX, me.cursorY, &first)
- if(word =& null)
- do \completion@close()
- else
- do \completion@show(me.src, \src@curDocInternalName, first, me.cursorY, word)
- end if
+ do \form@drawEditor.showCaret(\common@cellHeight, \common@font)
+ do \completion@show(me.src, \src@curDocName, first, me.cursorY, word)
+ do \form@drawEditor.hideCaret()
end if
end func
@@ -1462,7 +1687,7 @@ end func
do first :- 1
end while
if(first = ^me.src.color[y] | !keyword(me.src.color[y][first]))
- do first :: -1
+ do first :: x
ret null
end if
var last: int :: x
@@ -1498,6 +1723,14 @@ end func
do \completion@close()
ret true
end func
+
+ func locked(): bool
+ if(\form@getLockingEditor())
+ do \form@showMsgRunning()
+ ret true
+ end if
+ ret me.lock
+ end func
end class
func findStr(found: &[]char, text: []char, fromLast: bool, first: int, last: int, pattern: []char, distinguishCase: bool, onlyWord: bool, regex: regex@Regex): int
diff --git a/src/kuin_editor/find.kn b/src/kuin_editor/find.kn
index 51515069..8884b504 100644
--- a/src/kuin_editor/find.kn
+++ b/src/kuin_editor/find.kn
@@ -19,6 +19,9 @@ var wndFindChkDistinguishCaseLast: bool
var wndFindChkOnlyWordLast: bool
var wndFindChkRegularExpressionLast: bool
var tabOrderFind: wnd@TabOrder
+var wndResult: wnd@Wnd
+var wndResultListItems: wnd@List
+var resultPoses: list<\src@Pos>
+func init()
do @wndFindEditPatternLast :: ""
@@ -26,13 +29,13 @@ var tabOrderFind: wnd@TabOrder
do @wndFindChkDistinguishCaseLast :: true
end func
-+func show(replace: bool)
++func show(replace: bool, defaultWord: []char)
var x: int
var y: int
var w: int
do \form@drawEditor.getPosScreen(&x, &y, &w, &)
if(@wndFind =& null)
- do @wndFind :: wnd@makeWnd(\form@wndMain, (%fix $ wnd@WndStyle).or(%noMinimize), 380, 332, \common@langEn ?("Find and Replace", "検索と置換"))
+ do @wndFind :: wnd@makeWnd(\form@wndMain, %fix $ wnd@WndStyle, 380, 332, \common@langEn ?("Find and Replace", "検索と置換"))
do @wndFind.setPos(x + w - 380 - 17, y, 380, 332)
do @wndFind.onClose :: wndFindOnClose
do @wndFindTabFind :: wnd@makeTab(@wndFind, 12, 12, 356, 308, %scale, %scale)
@@ -42,6 +45,9 @@ end func
do wnd@makeLabel(@wndFindTabFind, 6, 28, 324, 12, %fix, %fix, \common@langEn ?("Find what:", "検索する文字列:"))
do @wndFindEditPattern :: wnd@makeEdit(@wndFindTabFind, 6, 46, 344, 19, %scale, %fix)
do @wndFindEditPattern.onChange :: wndFindEditPatternOnChange
+ if(defaultWord <>& null)
+ do @wndFindEditPattern.setText(defaultWord)
+ end if
do wnd@makeLabel(@wndFindTabFind, 6, 71, 324, 12, %fix, %fix, \common@langEn ?("Replace with:", "置換後の文字列:"))
do @wndFindEditReplace :: wnd@makeEdit(@wndFindTabFind, 6, 89, 344, 19, %scale, %fix)
do @wndFindEditReplace.onChange :: wndFindEditReplaceOnChange
@@ -49,6 +55,9 @@ end func
do @wndFindRadioDoc :: wnd@makeRadio(groupTarget, 6, 18, 312, 16, %fix, %fix, \common@langEn ?("Current document", "現在のドキュメント"))
do @wndFindRadioAll :: wnd@makeRadio(groupTarget, 6, 40, 312, 16, %fix, %fix, \common@langEn ?("All documents", "すべてのドキュメント"))
do @wndFindRadioSel :: wnd@makeRadio(groupTarget, 6, 62, 312, 16, %fix, %fix, \common@langEn ?("Selection", "選択範囲"))
+ do @wndFindRadioDoc.onPush :: wndFindRadioDocAllSelOnPush
+ do @wndFindRadioAll.onPush :: wndFindRadioDocAllSelOnPush
+ do @wndFindRadioSel.onPush :: wndFindRadioDocAllSelOnPush
do @wndFindChkDistinguishCase :: wnd@makeChk(@wndFindTabFind, 6, 204, 166, 16, %fix, %fix, \common@langEn ?("Match case", "大文字と小文字を区別する"))
do @wndFindChkDistinguishCase.onPush :: wndFindChkDistinguishCaseOnPush
do @wndFindChkOnlyWord :: wnd@makeChk(@wndFindTabFind, 6, 226, 166, 16, %fix, %fix, \common@langEn ?("Match whole word", "単語単位"))
@@ -87,17 +96,11 @@ end func
do @wndFind.activate()
end if
do @wndFindTabFind.setSel(replace ?(1, 0))
- do @wndFindEditReplace.setEnabled(replace)
- do @wndFindBtnReplace.setEnabled(replace)
- do @wndFindBtnReplaceAll.setEnabled(replace)
+ do updateUi()
do wndFindChkRegularExpressionOnPush(null)
do @wndFindEditPattern.focus()
do @wndFindEditPattern.setSel(0, -1)
- ; TODO:
- do @wndFindRadioAll.setEnabled(false)
- do @wndFindRadioSel.setEnabled(false)
-
func wndFindOnClose(wnd: wnd@Wnd): bool
do @tabOrderFind :: null
@@ -132,14 +135,7 @@ end func
end func
func wndFindTabFindOnSel(wnd: wnd@Tab)
- var sel: int :: @wndFindTabFind.getSel()
- if(sel = -1)
- ret
- end if
- var replace: bool :: sel = 1
- do @wndFindEditReplace.setEnabled(replace)
- do @wndFindBtnReplace.setEnabled(replace)
- do @wndFindBtnReplaceAll.setEnabled(replace)
+ do updateUi()
end func
func wndFindEditPatternOnChange(wnd: wnd@Edit)
@@ -150,6 +146,10 @@ end func
do @wndFindEditReplaceLast :: @wndFindEditReplace.getText()
end func
+ func wndFindRadioDocAllSelOnPush(wnd: wnd@Radio)
+ do updateUi()
+ end func
+
func wndFindChkDistinguishCaseOnPush(wnd: wnd@Chk)
do @wndFindChkDistinguishCaseLast :: @wndFindChkDistinguishCase.getChk()
end func
@@ -170,15 +170,88 @@ end func
end func
func wndFindBtnReplaceAllOnPush(wnd: wnd@Btn)
- do @replaceAll(@wndFindEditPatternLast, @wndFindEditReplaceLast, @wndFindChkDistinguishCaseLast, @wndFindChkOnlyWordLast, @wndFindChkRegularExpressionLast)
+ if(@wndFindRadioDoc.getChk())
+ do @replaceAll(@wndFindEditPatternLast, @wndFindEditReplaceLast, @wndFindChkDistinguishCaseLast, @wndFindChkOnlyWordLast, @wndFindChkRegularExpressionLast)
+ elif(@wndFindRadioAll.getChk())
+ do @replaceAllInAllDocs(@wndFindEditPatternLast, @wndFindEditReplaceLast, @wndFindChkDistinguishCaseLast, @wndFindChkOnlyWordLast, @wndFindChkRegularExpressionLast)
+ else
+ do @replaceSel(@wndFindEditPatternLast, @wndFindEditReplaceLast, @wndFindChkDistinguishCaseLast, @wndFindChkOnlyWordLast, @wndFindChkRegularExpressionLast)
+ end if
do \form@focusDrawEditor()
end func
+
+ func updateUi()
+ var replace: bool :: @wndFindTabFind.getSel() = 1
+ if(@wndFindRadioDoc.getChk())
+ do @wndFindBtnPrev.setEnabled(true)
+ do @wndFindBtnNext.setText(\common@langEn ?("Find Next", "次を検索"))
+ do @wndFindBtnReplace.setEnabled(replace)
+ else
+ do @wndFindBtnPrev.setEnabled(false)
+ do @wndFindBtnNext.setText(\common@langEn ?("Find All", "すべて検索"))
+ do @wndFindBtnReplace.setEnabled(false)
+ end if
+ do @wndFindEditReplace.setEnabled(replace)
+ do @wndFindBtnReplaceAll.setEnabled(replace)
+ end func
end func
func wndFindBtnNextOnPush(wnd: wnd@Btn)
+ class FindData()
+ +var list_: wnd@List
+ +var poses: list<\src@Pos>
+ +var pattern: []char
+ +var distinguishCase: bool
+ +var onlyWord: bool
+ +var regularExpression: bool
+ end class
+
if(@wndFindEditPatternLast <>& null)
- do @findNext()
+ if(@wndFindRadioDoc.getChk())
+ do @findNext()
+ else
+ if(@wndResult <>& null)
+ do @wndResult.exit()
+ end if
+ do @wndResult :: wnd@makeWnd(\form@wndMain, (%fix $ wnd@WndStyle).or(%noMinimize), 300, 400, \common@langEn ?("Search Results of \"\{@wndFindEditPatternLast}\"", "「\{@wndFindEditPatternLast}」の検索結果"))
+ do @wndResultListItems :: wnd@makeList(@wndResult, 12, 12, 276, 376, %scale, %scale)
+ do @wndResultListItems.onSel :: wndResultListItemsOnSel
+ do @resultPoses :: #list<\src@Pos>
+ if(@wndFindRadioAll.getChk())
+ var data: FindData :: #FindData
+ do data.list_ :: @wndResultListItems
+ do data.poses :: @resultPoses
+ do data.pattern :: @wndFindEditPatternLast
+ do data.distinguishCase :: @wndFindChkDistinguishCaseLast
+ do data.onlyWord :: @wndFindChkOnlyWordLast
+ do data.regularExpression :: @wndFindChkRegularExpressionLast
+ do \src@docs.forEach(findAll, data)
+ elif(\src@curDoc =$ \doc_src@DocSrc)
+ do (\src@curDoc $ \doc_src@DocSrc).findSel(@wndResultListItems, @resultPoses, \src@curDocName, @wndFindEditPatternLast, @wndFindChkDistinguishCaseLast, @wndFindChkOnlyWordLast, @wndFindChkRegularExpressionLast)
+ end if
+ do \form@focusDrawEditor()
+ end if
end if
+
+ func findAll(key: []char, value: \doc@Doc, data: FindData): bool
+ if(value <>$ \doc_src@DocSrc)
+ ret true
+ end if
+ if(key[0] <> '\\')
+ ret true
+ end if
+ do (value $ \doc_src@DocSrc).findAll(data.list_, data.poses, key, data.pattern, data.distinguishCase, data.onlyWord, data.regularExpression)
+ ret true
+ end func
+
+ func wndResultListItemsOnSel(wnd: wnd@List)
+ var sel: int :: wnd.getSel()
+ if(sel = -1)
+ ret
+ end if
+ do @resultPoses.head()
+ do \src@jumpSrc(@resultPoses.getOffset(sel))
+ end func
end func
func wndFindBtnPrevOnPush(wnd: wnd@Btn)
@@ -188,6 +261,9 @@ func wndFindBtnPrevOnPush(wnd: wnd@Btn)
end func
+func findNext()
+ if(@wndFindRadioDoc <>& null & !@wndFindRadioDoc.getChk())
+ ret
+ end if
do @findNextImpl(@wndFindEditPatternLast, @wndFindChkDistinguishCaseLast, @wndFindChkOnlyWordLast, @wndFindChkRegularExpressionLast)
do \form@focusDrawEditor()
end func
@@ -240,6 +316,73 @@ func replaceAll(pattern: []char, replaceStr: []char, distinguishCase: bool, only
end if
end func
+func replaceSel(pattern: []char, replaceStr: []char, distinguishCase: bool, onlyWord: bool, regularExpression: bool)
+ if(\src@curDoc =$ \doc_src@DocSrc)
+ var doc: \doc_src@DocSrc :: \src@curDoc $ \doc_src@DocSrc
+ var msg: []char
+ if(\common@langEn)
+ do msg :: "Do you want to replace all \"" ~ pattern ~ "\" with \"" ~ replaceStr ~ "\" in current selection range?"
+ else
+ do msg :: "現在の選択範囲の「" ~ pattern ~ "」を「" ~ replaceStr ~ "」に、すべて置換しますか?"
+ end if
+ if(wnd@msgBox(@wndFind, msg, \common@title, %warn, %yesNoCancel) = %yes)
+ var cnt: int :: doc.replaceSel(pattern, replaceStr, distinguishCase, onlyWord, regularExpression)
+ if(\common@langEn)
+ do msg :: cnt.toStr() ~ " string(s) have been replaced."
+ else
+ do msg :: cnt.toStr() ~ "個の文字列を置換しました。"
+ end if
+ do wnd@msgBox(@wndFind, msg, \common@title, %info, %ok)
+ end if
+ end if
+end func
+
+func replaceAllInAllDocs(pattern: []char, replaceStr: []char, distinguishCase: bool, onlyWord: bool, regularExpression: bool)
+ class FindData()
+ +var cnt: int
+ +var pattern_: []char
+ +var replaceStr_: []char
+ +var distinguishCase_: bool
+ +var onlyWord_: bool
+ +var regularExpression_: bool
+ end class
+
+ var msg: []char
+ if(\common@langEn)
+ do msg :: "Do you want to replace all \"" ~ pattern ~ "\" with \"" ~ replaceStr ~ "\" in all documents?"
+ else
+ do msg :: "すべてのドキュメントの「" ~ pattern ~ "」を「" ~ replaceStr ~ "」に、すべて置換しますか?"
+ end if
+ if(wnd@msgBox(@wndFind, msg, \common@title, %warn, %yesNoCancel) <> %yes)
+ ret
+ end if
+ var data: FindData :: #FindData
+ do data.cnt :: 0
+ do data.pattern_ :: pattern
+ do data.replaceStr_ :: replaceStr
+ do data.distinguishCase_ :: distinguishCase
+ do data.onlyWord_ :: onlyWord
+ do data.regularExpression_ :: regularExpression
+ do \src@docs.forEach(replaceAll, data)
+ if(\common@langEn)
+ do msg :: data.cnt.toStr() ~ " string(s) have been replaced."
+ else
+ do msg :: data.cnt.toStr() ~ "個の文字列を置換しました。"
+ end if
+ do wnd@msgBox(@wndFind, msg, \common@title, %info, %ok)
+
+ func replaceAll(key: []char, value: \doc@Doc, data: FindData): bool
+ if(value <>$ \doc_src@DocSrc)
+ ret true
+ end if
+ if(key[0] <> '\\')
+ ret true
+ end if
+ do data.cnt :+ (value $ \doc_src@DocSrc).replaceAll(data.pattern_, data.replaceStr_, data.distinguishCase_, data.onlyWord_, data.regularExpression_)
+ ret true
+ end func
+end func
+
+func runTabOrder(key: wnd@Key, shiftCtrl: wnd@ShiftCtrl): bool
if(@tabOrderFind <>& null & @tabOrderFind.chk(key, shiftCtrl))
ret true
diff --git a/src/kuin_editor/form.kn b/src/kuin_editor/form.kn
index ebe71d1d..f6c95ddf 100644
--- a/src/kuin_editor/form.kn
+++ b/src/kuin_editor/form.kn
@@ -1,91 +1,287 @@
+var wndMain: wnd@Wnd
-+var treeItem: wnd@TreeMulti
-+var listObj: wnd@List
++var listLt: wnd@ListView
++var treeLb: wnd@Tree
++var listLb: wnd@ListView
++var btnCode: wnd@Btn
var editFile: wnd@Edit
+var drawEditor: wnd@Draw
+var scrollXSrc: wnd@ScrollX
+var scrollYSrc: wnd@ScrollY
-var listProp: wnd@ListView
++var editHint: wnd@Edit
++var listRb: wnd@ListView
++var groupRbAr: wnd@Group
+
++var labelRbArName: wnd@Label
++var editRbArName: wnd@Edit
++var chkRbArVisible: wnd@Chk
++var labelRbArPos: wnd@Label
++var editRbArX: wnd@Edit
++var labelRbArMul1: wnd@Label
++var editRbArY: wnd@Edit
++var labelRbArSub: wnd@Label
++var editRbArWidth: wnd@Edit
++var labelRbArMul2: wnd@Label
++var editRbArHeight: wnd@Edit
++var btnRbArProp: wnd@Btn
+var chkRbArSnap: wnd@Chk
+var editRbArSnap: wnd@Edit
+var labelRbArZoom: wnd@Label
+var editRbArZoom: wnd@Edit
+var btnRbArZoomOut: wnd@Btn
+var btnRbArZoomIn: wnd@Btn
+var tabOrderRbAr: wnd@TabOrder
+
var editLog: wnd@EditMulti
var btnCompile: wnd@Btn
var groupConfig: wnd@Group
var groupEnv: wnd@Group
var radioEnvWnd: wnd@Radio
var radioEnvCui: wnd@Radio
-var labelIcon: wnd@Label
-var editIcon: wnd@Edit
-var btnIcon: wnd@Btn
+var btnProjSettings: wnd@Btn
var btnRls: wnd@Btn
+var listFile: wnd@List
+var btnFileAdd: wnd@Btn
+var btnFileDel: wnd@Btn
var menuMain: wnd@Menu
var popupMainEdit: wnd@Popup
var popupMainFile: wnd@Popup
var popupMainBuild: wnd@Popup
+var popupMainDbg: wnd@Popup
+var popupMainTools: wnd@Popup
var popupMainHelp: wnd@Popup
+var popupMainArranger: wnd@Popup
++var popupRecentFiles: wnd@Popup
var lockingEditor: bool
-var lockPropOnChange: bool
-var lockTreeItemOnSel: bool
-var textLog: []char
+var lockUi: bool
var drag: bool
++var snap: bool
++var snapValue: int
++var zoom: float
++var iconPath: []char
++var relatedFiles: list<[]char>
+func makeWnd()
+ do @lockUi :: true
+
do @wndMain :: wnd@makeWnd(null, %normal, 1224, 768, \common@title)
do @wndMain.minMax(930, 640, -1, -1)
+ do @wndMain.acceptDraggedFiles(true)
do @wndMain.onClose :: @wndMainOnClose
do @wndMain.onActivate :: @wndMainOnActivate
do @wndMain.onPushMenu :: @wndMainOnPushMenu
- do @treeItem :: wnd@makeTreeMulti(@wndMain, 12, 290, 244, 466, %fix, %scale)
- do @treeItem.draggable(true)
- do @treeItem.allowDraggingToRoot(false)
- do @treeItem.onSel :: @treeItemOnSel
- do @treeItem.onMoveNode :: @treeItemOnMoveNode
- do @listObj :: wnd@makeList(@wndMain, 12, 12, 244, 272, %fix, %fix)
- do @listObj.onSel :: @listObjOnSel
- do @editFile :: wnd@makeEdit(@wndMain, 262, 12, 759, 15, %scale, %fix)
+ do @wndMain.onDropFiles :: @wndMainOnDropFiles
+ do @wndMain.onResize :: @wndMainOnResize
+ do @listLt :: wnd@makeListView(@wndMain, 12, 12, 244, 272, %fix, %fix, false, null, ["res/obj_none.png", "res/obj_btn.png", "res/obj_chk.png", "res/obj_edit.png", "res/obj_label.png", "res/obj_group.png", "res/obj_rect.png", "res/obj_circle.png", "res/obj_text.png", "res/obj_img.png", "res/obj_roundrect.png", "res/obj_particle.png", "res/obj_edit_multi.png"])
+ do @listLt.setVisible(false)
+ do @listLt.onMouseClick :: listLtOnMouseClick
+
+ func listLtOnMouseClick(wnd: wnd@WndBase)
+ do \src@curDoc.onEvent(%listLtOnMouseClick)
+ end func
+
+ do @listLt.style(%list_)
+ do @treeLb :: wnd@makeTree(@wndMain, 12, 290, 244, 466, %fix, %scale)
+ do @treeLb.setVisible(false)
+ do @listLb :: wnd@makeListView(@wndMain, 12, 290, 244, 466, %fix, %scale, true, ["res/obj_btn.png", "res/obj_chk.png", "res/obj_edit.png", "res/obj_label.png", "res/obj_group.png", "res/obj_rect.png", "res/obj_circle.png", "res/obj_text.png", "res/obj_img.png", "res/obj_roundrect.png", "res/obj_particle.png", "res/obj_edit_multi.png"], null)
+ do @listLb.setVisible(false)
+ do @listLb.draggable(true)
+ do @listLb.onMouseClick :: listLbOnMouseClick
+
+ func listLbOnMouseClick(wnd: wnd@WndBase)
+ do \src@curDoc.onEvent(%listLbOnMouseClick)
+ end func
+
+ do @listLb.onMoveNode :: listLbOnMoveNode
+
+ func listLbOnMoveNode(wnd: wnd@WndBase)
+ do \src@curDoc.onEvent(%listLbOnMoveNode)
+ end func
+
+ do @btnCode :: wnd@makeBtn(@wndMain, 262, 12, 100, 23, %fix, %fix, \common@langEn ?("Show Designer", "デザイナを表示"))
+ do @btnCode.setEnabled(false)
+ do @btnCode.onPush :: @btnCodeOnPush
+ do @editFile :: wnd@makeEdit(@wndMain, 368, 20, 653, 15, %scale, %fix)
do @editFile.readonly(true)
- do @drawEditor :: wnd@makeDraw(@wndMain, 262, 33, 759, 582, %scale, %scale, true)
- do @scrollXSrc :: wnd@makeScrollX(@drawEditor, 0, 565, 742, 17, %scale, %move)
+ do @drawEditor :: wnd@makeDraw(@wndMain, 262, 41, 759, 553, %scale, %scale, true)
+ do @scrollXSrc :: wnd@makeScrollX(@drawEditor, 0, 536, 742, 17, %scale, %move)
do @scrollXSrc.setState(0, 0, 1, 0)
- do @scrollYSrc :: wnd@makeScrollY(@drawEditor, 742, 0, 17, 565, %move, %scale)
+ do @scrollYSrc :: wnd@makeScrollY(@drawEditor, 742, 0, 17, 536, %move, %scale)
do @scrollYSrc.setState(0, 0, 1, 0)
- do @listProp :: wnd@makeListView(@wndMain, 262, 621, 391, 135, %scale, %move)
- do @listProp.onSel :: @listPropOnSel
- do @listProp.onMouseDoubleClick :: @listPropOnMouseDoubleClick
- do @listProp.onMouseClick :: @listPropOnMouseClick
+ do @editHint :: wnd@makeEdit(@wndMain, 262, 600, 759, 15, %scale, %move)
+ do @editHint.readonly(true)
+ do @listRb :: wnd@makeListView(@wndMain, 262, 621, 391, 135, %scale, %move, false, null, null)
+ do @listRb.setVisible(false)
+ do @listRb.onMouseClick :: listRbOnMouseClick
+
+ func listRbOnMouseClick(wnd: wnd@WndBase)
+ do \src@curDoc.onEvent(%listRbOnMouseClick)
+ end func
+
+ do @groupRbAr :: wnd@makeGroup(@wndMain, 262, 621, 391, 135, %scale, %move, "")
+ do @groupRbAr.setVisible(false)
+
+ do @labelRbArName :: wnd@makeLabel(@groupRbAr, 6, 21, 35, 12, %fix, %fix, \common@langEn ?("Name", "名前"))
+ do @editRbArName :: wnd@makeEdit(@groupRbAr, 65, 18, 95, 19, %fix, %fix)
+ do @editRbArName.onFocus :: editRbArNameOnFocus
+ do @chkRbArVisible :: wnd@makeChk(@groupRbAr, 183, 20, 80, 16, %fix, %fix, \common@langEn ?("Visible", "表示"))
+ do @chkRbArVisible.onPush :: chkRbArVisibleOnPush
+ do @labelRbArPos :: wnd@makeLabel(@groupRbAr, 6, 46, 35, 12, %fix, %fix, \common@langEn ?("Position", "位置"))
+ do @editRbArX :: wnd@makeEdit(@groupRbAr, 65, 43, 36, 19, %fix, %fix)
+ do @editRbArX.onFocus :: editRbArXOnFocus
+ do @labelRbArMul1 :: wnd@makeLabel(@groupRbAr, 107, 46, 11, 12, %fix, %fix, "x")
+ do @editRbArY :: wnd@makeEdit(@groupRbAr, 124, 43, 36, 19, %fix, %fix)
+ do @editRbArY.onFocus :: editRbArYOnFocus
+ do @labelRbArSub :: wnd@makeLabel(@groupRbAr, 166, 46, 11, 12, %fix, %fix, "-")
+ do @editRbArWidth :: wnd@makeEdit(@groupRbAr, 183, 43, 36, 19, %fix, %fix)
+ do @editRbArWidth.onFocus :: editRbArWidthOnFocus
+ do @labelRbArMul2 :: wnd@makeLabel(@groupRbAr, 225, 46, 11, 12, %fix, %fix, "x")
+ do @editRbArHeight :: wnd@makeEdit(@groupRbAr, 242, 43, 36, 19, %fix, %fix)
+ do @editRbArHeight.onFocus :: editRbArHeightOnFocus
+ do @btnRbArProp :: wnd@makeBtn(@groupRbAr, 6, 68, 152, 23, %fix, %fix, \common@langEn ?("Edit Properties...", "プロパティの編集..."))
+ do @btnRbArProp.onPush :: btnRbArPropOnPush
+ do @chkRbArSnap :: wnd@makeChk(@groupRbAr, 6, 110, 112, 16, %fix, %fix, \common@langEn ?("Snap to Grid:", "グリッドに吸着:"))
+ do @chkRbArSnap.onPush :: chkRbArSnapOnPush
+ do @editRbArSnap :: wnd@makeEdit(@groupRbAr, 124, 110, 36, 19, %fix, %fix)
+ do @editRbArSnap.onFocus :: editRbArSnapOnFocus
+ do @labelRbArZoom :: wnd@makeLabel(@groupRbAr, 186, 110, 50, 16, %fix, %fix, \common@langEn ?("Zoom:", "ズーム:"))
+ do @editRbArZoom :: wnd@makeEdit(@groupRbAr, 242, 110, 36, 19, %fix, %fix)
+ do @editRbArZoom.onFocus :: editRbArZoomOnFocus
+ do @btnRbArZoomOut :: wnd@makeBtn(@groupRbAr, 278, 110, 23, 23, %fix, %fix, "-")
+ do @btnRbArZoomOut.onPush :: btnRbArZoomOutOnPush
+ do @btnRbArZoomIn :: wnd@makeBtn(@groupRbAr, 301, 110, 23, 23, %fix, %fix, "+")
+ do @btnRbArZoomIn.onPush :: btnRbArZoomInOnPush
+ do @tabOrderRbAr :: wnd@makeTabOrder([@editRbArName $ wnd@WndBase, @editRbArX, @editRbArY, @editRbArWidth, @editRbArHeight, @editRbArSnap, @editRbArZoom])
+
+ func editRbArNameOnFocus(wnd: wnd@WndBase, focused: bool)
+ if(!focused)
+ do \src@curDoc.onEvent(%editRbArNameOnKillFocus)
+ end if
+ end func
+
+ func chkRbArVisibleOnPush(wnd: wnd@WndBase)
+ do \src@curDoc.onEvent(%chkRbArVisibleOnPush)
+ end func
+
+ func editRbArXOnFocus(wnd: wnd@WndBase, focused: bool)
+ if(!focused)
+ do \src@curDoc.onEvent(%editRbArXOnKillFocus)
+ end if
+ end func
+
+ func editRbArYOnFocus(wnd: wnd@WndBase, focused: bool)
+ if(!focused)
+ do \src@curDoc.onEvent(%editRbArYOnKillFocus)
+ end if
+ end func
+
+ func editRbArWidthOnFocus(wnd: wnd@WndBase, focused: bool)
+ if(!focused)
+ do \src@curDoc.onEvent(%editRbArWidthOnKillFocus)
+ end if
+ end func
+
+ func editRbArHeightOnFocus(wnd: wnd@WndBase, focused: bool)
+ if(!focused)
+ do \src@curDoc.onEvent(%editRbArHeightOnKillFocus)
+ end if
+ end func
+
+ func btnRbArPropOnPush(wnd: wnd@WndBase)
+ do \src@curDoc.onEvent(%btnRbArPropOnPush)
+ end func
+
+ func chkRbArSnapOnPush(wnd: wnd@WndBase)
+ do @snap :: @chkRbArSnap.getChk()
+ do \prop@changeProp()
+ do @updateUi()
+ end func
+
+ func editRbArSnapOnFocus(wnd: wnd@WndBase, focused: bool)
+ if(!focused)
+ var success: bool
+ var value: int :: @editRbArSnap.getText().trim().toInt(&success)
+ if(success)
+ if(value < 1)
+ do value :: 1
+ end if
+ if(@snapValue <> value)
+ do @snapValue :: value
+ do \prop@changeProp()
+ end if
+ end if
+ do @updateUi()
+ end if
+ end func
+
+ func editRbArZoomOnFocus(wnd: wnd@WndBase, focused: bool)
+ if(!focused)
+ var success: bool
+ var value: float :: @editRbArZoom.getText().trim().toFloat(&success)
+ if(success)
+ if(value < 0.1)
+ do value :: 0.1
+ end if
+ if(value > 8.0)
+ do value :: 8.0
+ end if
+ if(@zoom <> value)
+ do @zoom :: value
+ do \prop@changeProp()
+ do @paintDrawEditor()
+ end if
+ end if
+ do @updateUi()
+ end if
+ end func
+
+ func btnRbArZoomOutOnPush(wnd: wnd@WndBase)
+ do @wndMainOnPushMenu(@wndMain, 0x0051)
+ end func
+
+ func btnRbArZoomInOnPush(wnd: wnd@WndBase)
+ do @wndMainOnPushMenu(@wndMain, 0x0050)
+ end func
+
do @editLog :: wnd@makeEditMulti(@wndMain, 659, 621, 553, 135, %move, %move)
do @editLog.readonly(true)
do @btnCompile :: wnd@makeBtn(@wndMain, 1027, 12, 185, 23, %move, %fix, \common@langEn ?("Compile && Run", "コンパイル&実行"))
do @btnCompile.onPush :: @btnCompileOnPush
- do @groupConfig :: wnd@makeGroup(@wndMain, 1027, 41, 185, 125, %move, %fix, \common@langEn ?("Configuration", "設定"))
+ do @groupConfig :: wnd@makeGroup(@wndMain, 1027, 41, 185, 115, %move, %fix, \common@langEn ?("Configuration", "設定"))
do @groupEnv :: wnd@makeGroup(@wndMain, 1033, 59, 173, 62, %move, %fix, \common@langEn ?("Environment", "実行環境"))
do @radioEnvWnd :: wnd@makeRadio(@groupEnv, 6, 18, 161, 16, %fix, %fix, \common@langEn ?("Window", "ウインドウ"))
do @radioEnvWnd.setChk(true)
do @radioEnvWnd.onPush :: @radioEnvOnPush
do @radioEnvCui :: wnd@makeRadio(@groupEnv, 6, 40, 161, 16, %fix, %fix, \common@langEn ?("CUI", "CUI"))
do @radioEnvCui.onPush :: @radioEnvOnPush
- do @labelIcon :: wnd@makeLabel(@groupConfig, 6, 85, 173, 12, %fix, %fix, \common@langEn ?("Icon", "アイコン"))
- do @editIcon :: wnd@makeEdit(@wndMain, 1033, 144, 92, 16, %move, %fix)
- do @editIcon.onChange :: @editIconOnChange
- do @btnIcon :: wnd@makeBtn(@wndMain, 1131, 137, 75, 23, %move, %fix, \common@langEn ?("Browse...", "参照..."))
- do @btnIcon.onPush :: @btnIconOnPush
- do @btnRls :: wnd@makeBtn(@wndMain, 1027, 172, 185, 23, %move, %fix, \common@langEn ?("Release Build...", "リリースビルド..."))
+ do @btnProjSettings :: wnd@makeBtn(@wndMain, 1033, 127, 120, 23, %move, %fix, \common@langEn ?("Other Settings...", "その他の設定..."))
+ do @btnProjSettings.onPush :: btnProjSettingsOnPush
+ do @btnRls :: wnd@makeBtn(@wndMain, 1027, 162, 185, 23, %move, %fix, \common@langEn ?("Release Build...", "リリースビルド..."))
do @btnRls.onPush :: @btnRlsOnPush
- do @listFile :: wnd@makeList(@wndMain, 1027, 255, 185, 360, %move, %scale)
+ do @listFile :: wnd@makeList(@wndMain, 1027, 255, 185, 337, %move, %scale)
do @listFile.onSel :: @listFileOnSel
+ do @btnFileAdd :: wnd@makeBtn(@wndMain, 1027, 592, 60, 23, %move, %move, \common@langEn ?("Add", "追加"))
+ do @btnFileAdd.onPush :: btnFileAddOnPush
+ do @btnFileDel :: wnd@makeBtn(@wndMain, 1087, 592, 60, 23, %move, %move, \common@langEn ?("Remove", "削除"))
+ do @btnFileDel.onPush :: btnFileDelOnPush
do @menuMain :: wnd@makeMenu()
do @popupMainFile :: wnd@makePopup()
do @popupMainFile.add(0x0001, \common@langEn ?("&New\tCtrl+N", "新規作成(&N)\tCtrl+N"))
- do @popupMainFile.add(0x0002, \common@langEn ?("&Load...\tCtrl+O", "開く(&O)\tCtrl+O"))
+ do @popupMainFile.add(0x0002, \common@langEn ?("&Load...\tCtrl+O", "開く(&O)...\tCtrl+O"))
do @popupMainFile.addLine()
do @popupMainFile.add(0x0003, \common@langEn ?("&Save All\tCtrl+S", "すべて保存(&S)\tCtrl+S"))
- do @popupMainFile.add(0x0004, \common@langEn ?("Save &As...\tCtrl+Shift+S", "名前を付けて保存(&A)\tCtrl+Shift+S"))
+ do @popupMainFile.add(0x0004, \common@langEn ?("Save &As...\tCtrl+Shift+S", "名前を付けて保存(&A)...\tCtrl+Shift+S"))
+ do @popupMainFile.addLine()
+ do @popupRecentFiles :: wnd@makePopup()
+ do @popupMainFile.addPopup(\common@langEn ?("Recent &Files", "最近使ったファイル(&F)"), @popupRecentFiles)
do @popupMainFile.addLine()
do @popupMainFile.add(0x0005, \common@langEn ?("E&xit\tCtrl+Q", "終了(&E)\tCtrl+Q"))
do @menuMain.addPopup(\common@langEn ?("&File", "ファイル(&F)"), @popupMainFile)
do @popupMainEdit :: wnd@makePopup()
- do @popupMainEdit.add(0x0030, \common@langEn ?("Add Ne&w File\tCtrl+Shift+A", "新しいファイルを追加(&W)\tCtrl+Shift+A"))
- do @popupMainEdit.add(0x0031, \common@langEn ?("Add Existin&g File", "既存のファイルを追加(&G)"))
+ do @popupMainEdit.add(0x0030, \common@langEn ?("Add Ne&w File...\tCtrl+Shift+A", "新しいファイルを追加(&W)...\tCtrl+Shift+A"))
+ do @popupMainEdit.add(0x0031, \common@langEn ?("Add Existin...&g File", "既存のファイルを追加(&G)..."))
+ do @popupMainEdit.addLine()
+ do @popupMainEdit.add(0x003E, \common@langEn ?("&Open \"res\" Folder...\tCtrl+Shift+R", "「res」フォルダを開く(&O)...\tCtrl+Shift+R"))
do @popupMainEdit.addLine()
do @popupMainEdit.add(0x0032, \common@langEn ?("&Undo\tCtrl+Z", "元に戻す(&U)\tCtrl+Z"))
do @popupMainEdit.add(0x0033, \common@langEn ?("&Redo\tCtrl+Shift+Z, Ctrl+Y", "やり直し(&R)\tCtrl+Shift+Z, Ctrl+Y"))
@@ -96,18 +292,27 @@ var drag: bool
do @popupMainEdit.add(0x0037, \common@langEn ?("&Delete\tDel", "削除(&D)\tDel"))
do @popupMainEdit.add(0x0038, \common@langEn ?("Select &All\tCtrl+A", "すべて選択(&A)\tCtrl+A"))
do @popupMainEdit.addLine()
- do @popupMainEdit.add(0x003D, \common@langEn ?("Add &Selection To Snippet", "選択範囲をスニペットに追加(&S)"))
+ do @popupMainEdit.add(0x003D, \common@langEn ?("Add &Selection To Snippets...", "選択範囲をスニペットに追加(&S)..."))
+ do @popupMainEdit.add(0x003F, \common@langEn ?("&Edit Snippets...", "スニペットの編集(&E)..."))
do @popupMainEdit.addLine()
- do @popupMainEdit.add(0x0039, \common@langEn ?("&Find\tCtrl+F", "検索(&F)\tCtrl+F"))
- do @popupMainEdit.add(0x003A, \common@langEn ?("&Replace\tCtrl+H", "置換(&R)\tCtrl+H"))
+ do @popupMainEdit.add(0x0039, \common@langEn ?("&Find...\tCtrl+F", "検索(&F)...\tCtrl+F"))
+ do @popupMainEdit.add(0x003A, \common@langEn ?("&Replace...\tCtrl+H", "置換(&R)...\tCtrl+H"))
do @popupMainEdit.add(0x003B, \common@langEn ?("Find Pre&vious\tShift+F3", "前を検索(&V)\tShift+F3"))
do @popupMainEdit.add(0x003C, \common@langEn ?("Find &Next\tF3", "次を検索(&N)\tF3"))
+ do @popupMainEdit.addLine()
+ do @popupMainEdit.add(0x0060, \common@langEn ?("Other Settings...", "その他の設定..."))
do @menuMain.addPopup(\common@langEn ?("&Edit", "編集(&E)"), @popupMainEdit)
do @popupMainBuild :: wnd@makePopup()
do @popupMainBuild.add(0x0020, \common@langEn ?("&Compile && Run\tF5", "コンパイル&実行(&C)\tF5"))
do @popupMainBuild.addLine()
do @popupMainBuild.add(0x0021, \common@langEn ?("&Release Build...\tCtrl+Shift+B", "リリースビルド(&R)...\tCtrl+Shift+B"))
do @menuMain.addPopup(\common@langEn ?("&Build", "ビルド(&B)"), @popupMainBuild)
+ do @popupMainDbg :: wnd@makePopup()
+ do @popupMainDbg.add(0x0040, \common@langEn ?("Toggle &Breakpoint\tF9", "ブレークポイントの設定/解除(&B)\tF9"))
+ do @menuMain.addPopup(\common@langEn ?("&Debug", "デバッグ(&D)"), @popupMainDbg)
+ do @popupMainTools :: wnd@makePopup()
+ do @popupMainTools.add(0x0070, \common@langEn ?("3D &Model Converter...", "3D モデルコンバータ(&M)..."))
+ do @menuMain.addPopup(\common@langEn ?("&Tools", "ツール(&T)"), @popupMainTools)
do @popupMainHelp :: wnd@makePopup()
do @popupMainHelp.add(0x0010, \common@langEn ?("&View Help\tF1", "ヘルプの表示(&V)\tF1"))
do @popupMainHelp.addLine()
@@ -115,13 +320,44 @@ var drag: bool
do @menuMain.addPopup(\common@langEn ?("&Help", "ヘルプ(&H)"), @popupMainHelp)
do @wndMain.setMenu(@menuMain)
- do wnd@onKeyPress(@onKeyPress)
+ do @popupMainArranger :: wnd@makePopup()
+ do @popupMainArranger.add(0x0050, \common@langEn ?("Zoom &In\tCtrl++", "ズームイン(&I)\tCtrl++"))
+ do @popupMainArranger.add(0x0051, \common@langEn ?("Zoom &Out\tCtrl+-", "ズームアウト(&O)\tCtrl+-"))
+ do @popupMainArranger.add(0x0052, "&100%\tCtrl+1")
+
+ do wnd@setOnKeyPress(@onKeyPress)
do @lockingEditor :: false
- do @lockPropOnChange :: false
- do @lockTreeItemOnSel :: false
- do @textLog :: ""
+ do @lockUi :: false
+ do @editLog.setText("")
do @drag :: false
+ do @snap :: true
+ do @snapValue :: 5
+ do @zoom :: 1.0
+ do @iconPath :: ""
+ do @relatedFiles :: #list<[]char>
+
+ func btnFileAddOnPush(wnd: wnd@WndBase)
+ do @wndMainOnPushMenu(@wndMain, 0x0030)
+ end func
+
+ func btnFileDelOnPush(wnd: wnd@WndBase)
+ if("\\" ~ file@delExt(file@fileName(\src@mainSrcPath)) = \src@curDocName)
+ do wnd@msgBox(@wndMain, \common@langEn ?("The main source file cannot be deleted.", "メインのソースファイルは削除できません。"), \common@title, %err, %ok)
+ ret
+ end if
+ if(wnd@msgBox(@wndMain, \common@langEn ?("Do you want to remove the file '\{\src@curDocName}' from the list?", "リストからファイル「\{\src@curDocName}」を削除しますか?"), \common@title, %none, %yesNoCancel) <> %yes)
+ ret
+ end if
+ if(\src@chkChanged())
+ do \src@docs.del(\src@getDocName(\src@curDoc))
+ do \src@setCurSrc(\src@mainDoc())
+ end if
+ end func
+
+ func btnProjSettingsOnPush(wnd: wnd@WndBase)
+ do @wndMainOnPushMenu(@wndMain, 0x0060)
+ end func
end func
+func init()
@@ -178,7 +414,8 @@ func onKeyPress(key: wnd@Key, shiftCtrl: wnd@ShiftCtrl): bool
ret true
end if
elif(@wndMain.focusedWnd() | \completion@focused())
- var editFocused: bool :: @editIcon.focused()
+ var editRbArFocused: bool :: @editRbArName.focused() | @editRbArX.focused() | @editRbArY.focused() | @editRbArWidth.focused() | @editRbArHeight.focused() | @editRbArSnap.focused() | @editRbArZoom.focused()
+ var editFocused: bool :: @editFile.focused() | @editHint.focused() | editRbArFocused
switch(shiftCtrl)
case %none
switch(key)
@@ -204,17 +441,28 @@ func onKeyPress(key: wnd@Key, shiftCtrl: wnd@ShiftCtrl): bool
case %f5
do @wndMainOnPushMenu(@wndMain, 0x0020)
ret true
+ case %f9
+ do @wndMainOnPushMenu(@wndMain, 0x0040)
+ ret true
case %f12
var definitionPos: \src@Pos :: \completion@getDefinitionPos()
if(definitionPos <>& null & \src@jumpSrc(definitionPos))
ret true
end if
+ case %tab, %enter
+ if(editRbArFocused & @tabOrderRbAr.chk(%tab, shiftCtrl))
+ ret true
+ end if
end switch
case %shift
switch(key)
case %f3
do @wndMainOnPushMenu(@wndMain, 0x003B)
ret true
+ case %tab, %enter
+ if(editRbArFocused & @tabOrderRbAr.chk(%tab, shiftCtrl))
+ ret true
+ end if
end switch
case %ctrl
switch(key)
@@ -266,14 +514,33 @@ func onKeyPress(key: wnd@Key, shiftCtrl: wnd@ShiftCtrl): bool
do @wndMainOnPushMenu(@wndMain, 0x0032)
ret true
end if
+ case %plus
+ if(!editFocused)
+ do @wndMainOnPushMenu(@wndMain, 0x0050)
+ ret true
+ end if
+ case %minus
+ if(!editFocused)
+ do @wndMainOnPushMenu(@wndMain, 0x0051)
+ ret true
+ end if
+ case %_1
+ if(!editFocused)
+ do @wndMainOnPushMenu(@wndMain, 0x0052)
+ ret true
+ end if
end switch
case (%shift $ wnd@ShiftCtrl).or(%ctrl)
switch(key)
case %a
do @wndMainOnPushMenu(@wndMain, 0x0030)
+ ret true
case %b
do @wndMainOnPushMenu(@wndMain, 0x0021)
ret true
+ case %r
+ do @wndMainOnPushMenu(@wndMain, 0x003E)
+ ret true
case %s
do @wndMainOnPushMenu(@wndMain, 0x0004)
ret true
@@ -333,12 +600,13 @@ func wndMainOnPushMenu(wnd: wnd@WndBase, id: int)
var file: []char :: wnd@openFileDialog(@wndMain, [\common@langEn ?("Kuin source code (*.kn)", "Kuinソースコード (*.kn)"), "*.kn"], 0)
if(file <>& null)
do \src@openMainSrc(file)
+ do \recent@save(file)
end if
end if
case 0x0003
- do \src@saveAll()
+ do \src@save(false)
case 0x0004
- do \src@saveMainSrc()
+ do \src@save(true)
case 0x0005
do @wndMain.close()
case 0x0010
@@ -352,10 +620,6 @@ func wndMainOnPushMenu(wnd: wnd@WndBase, id: int)
do wnd@msgBox(@wndMain, "Kuin Programming Language\nVersion \{major}.\{minor}.\{micro}\n(C)Kuina-chan", \common@title, %info, %ok)
end block
case 0x0020
- if(@lockingEditor)
- do @showMsgRunning()
- ret
- end if
do @btnCompileOnPush(@btnCompile)
case 0x0021
if(@lockingEditor)
@@ -390,32 +654,123 @@ func wndMainOnPushMenu(wnd: wnd@WndBase, id: int)
case 0x0038
do \src@curDoc.cmdSelAll()
case 0x0039
- do \find@show(false)
+ do \find@show(false, \src@curDoc.getCursorWord())
case 0x003A
- do \find@show(true)
+ do \find@show(true, \src@curDoc.getCursorWord())
case 0x003B
do \find@findPrev()
case 0x003C
do \find@findNext()
case 0x003D
do \snippet@add(\src@curDoc.getSelCode())
- do @updateList()
+ do \src@curDoc.fix()
+ case 0x003E
+ if(@lockingEditor)
+ do @showMsgRunning()
+ ret
+ end if
+ do @openResFolder()
+ case 0x003F
+ do \snippet@showSnippet()
+ case 0x0040
+ if (\src@curDoc =$ \doc_src@DocSrc)
+ if(\src@breakPos =& null & @lockingEditor)
+ do @showMsgRunning()
+ ret
+ end if
+ do (\src@curDoc $ \doc_src@DocSrc).toggleBreakPoint()
+ end if
+ case 0x0050
+ if(@zoom < 0.25)
+ do @zoom :: 0.25
+ elif(@zoom < 0.33)
+ do @zoom :: 0.33
+ elif(@zoom < 0.5)
+ do @zoom :: 0.5
+ elif(@zoom < 1.0)
+ do @zoom :: 1.0
+ elif(@zoom < 2.0)
+ do @zoom :: 2.0
+ elif(@zoom < 4.0)
+ do @zoom :: 4.0
+ elif(@zoom < 8.0)
+ do @zoom :: 8.0
+ end if
+ do \prop@changeProp()
+ do @paintDrawEditor()
+ do @updateUi()
+ case 0x0051
+ if(@zoom > 4.0)
+ do @zoom :: 4.0
+ elif(@zoom > 2.0)
+ do @zoom :: 2.0
+ elif(@zoom > 1.0)
+ do @zoom :: 1.0
+ elif(@zoom > 0.5)
+ do @zoom :: 0.5
+ elif(@zoom > 0.33)
+ do @zoom :: 0.33
+ elif(@zoom > 0.25)
+ do @zoom :: 0.25
+ elif(@zoom > 0.1)
+ do @zoom :: 0.1
+ end if
+ do \prop@changeProp()
+ do @paintDrawEditor()
+ do @updateUi()
+ case 0x0052
+ if(@zoom <> 1.0)
+ do @zoom :: 1.0
+ do \prop@changeProp()
+ do @paintDrawEditor()
+ end if
+ do @updateUi()
+ case 0x0060
+ if(@lockingEditor)
+ do @showMsgRunning()
+ ret
+ end if
+ do \proj_settings@show()
+ case 0x0070
+ do \knobj_maker@show()
+ case 0x0400 to 0x04FF
+ do \recent@sel(id)
end switch
end func
-func treeItemOnSel(wnd: wnd@WndBase)
- if(@lockTreeItemOnSel)
+func wndMainOnDropFiles(wnd: wnd@WndBase, files: [][]char)
+ if(^files <= 0 | file@ext(files[0]) <> "kn")
+ ret
+ end if
+ if(@lockingEditor)
+ do @showMsgRunning()
ret
end if
- do \src@curDoc.treeItemOnSel()
+ if (\src@chkChanged())
+ do \src@openMainSrc(files[0])
+ do \recent@save(files[0])
+ end if
end func
-func treeItemOnMoveNode(wnd: wnd@WndBase)
- do \src@curDoc.treeItemOnMoveNode()
+func wndMainOnResize(wnd: wnd@WndBase)
+ if(!@lockUi)
+ do @updateUi()
+ end if
end func
-func listObjOnSel(wnd: wnd@WndBase)
- do \src@curDoc.listObjOnSel()
+var test: bool
+
+func btnCodeOnPush(wnd: wnd@WndBase)
+ if(@lockUi)
+ ret
+ end if
+ do @lockUi :: true
+ if(\src@curDoc =$ \doc_gen@DocGen)
+ do (\src@curDoc $ \doc_gen@DocGen).swapMode()
+ end if
+ do @lockUi :: false
+ do @updateUi()
+ do @paintDrawEditor()
end func
func drawEditorOnPaint(wnd: wnd@WndBase, width: int, height: int)
@@ -426,11 +781,13 @@ end func
func drawEditorOnMouseDownL(wnd: wnd@WndBase, x: int, y: int)
do @drag :: true
do \src@curDoc.mouseDownL(x, y)
+ do @drawEditor.mouseCapture(true)
end func
func drawEditorOnMouseUpL(wnd: wnd@WndBase, x: int, y: int)
do @drag :: false
do \src@curDoc.mouseUpL(x, y)
+ do @drawEditor.mouseCapture(false)
end func
func drawEditorOnMouseDoubleClick(wnd: wnd@WndBase, x: int, y: int)
@@ -477,20 +834,12 @@ func drawEditorOnSetMouseImg(wnd: wnd@WndBase): wnd@MouseImg
ret \src@curDoc.setMouseImg()
end func
-func listPropOnSel(wnd: wnd@WndBase)
- do \src@curDoc.listPropOnSel(@listProp)
-end func
-
-func listPropOnMouseClick(wnd: wnd@WndBase)
- do \src@curDoc.listPropOnMouseClick(@listProp)
-end func
-
-func listPropOnMouseDoubleClick(wnd: wnd@WndBase)
- do \src@curDoc.listPropOnMouseDoubleClick(@listProp)
-end func
-
func btnCompileOnPush(wnd: wnd@WndBase)
if(@lockingEditor)
+ if(\src@breakPos <>& null)
+ do \src@breakPos :: null
+ ret
+ end if
do @showMsgRunning()
ret
end if
@@ -510,34 +859,24 @@ func btnCompileOnPush(wnd: wnd@WndBase)
ret
end try
do \dll@resetMemAllocator()
- do @textLog :: ""
- do @updateLog()
- var cmd: []char
- var cmdLine: []char
- if(@radioEnvWnd.getChk())
- do cmd :: out
- do cmdLine :: null
- elif(@radioEnvCui.getChk())
- do cmd :: file@sysDir(%system32) ~ "cmd.exe"
- do cmdLine :: "/C \"\"" ~ file@exeDir().replace("/", "\\") ~ "sys\\launcher.bat\" \"" ~ out.replace("/", "\\") ~ "\"\""
- end if
+ do @editLog.setText("")
+ var cmd: []char :: out
try
do \src@resetErrList()
- if(\dll@build(\src@mainSrcName, \src@getSrc, null, out, @editIcon.getText().trim(), false, @getEnv(), @log, \common@langEn ?(1, 0), 0))
- if (\src@mainSrcName <> \common@untitledSrcName)
+ do \src@docs.forEach(fixAll, null)
+ if(\dll@build(\src@mainSrcPath, \src@getSrc, null, out, @iconPath, @relatedFiles, false, @getEnv(), @log, \common@langEn ?(1, 0), 0))
+ if (\src@mainSrcDir <> \common@defaultDir)
var filePtr: file@Writer :: file@makeWriter(tmp ~ "_curdir_.txt", false)
- do filePtr.writeStr(file@dir(\src@mainSrcName))
+ do filePtr.writeStr(\src@mainSrcDir)
do filePtr.writeChar('\n')
do filePtr.fin()
end if
- do @textLog :~ \common@langEn ?("IK9999: Run.", "IK9999: 実行。\n")
- do @updateLog()
- if(\dll@runDbg(cmd, cmdLine, idleFunc, eventFunc))
- do @textLog :~ \common@langEn ?("\nIK9999: Succees.\n", "\nIK9999: 正常終了。\n")
- do @updateLog()
+ do @editLog.addText(\common@langEn ?("IK9999: Run.", "IK9999: 実行。\n"))
+ do \dbgwnd@show()
+ if(\dll@runDbg(cmd, null, idleFunc, eventFunc, breakPointsFunc, breakFunc, dbgFunc))
+ do @editLog.addText(\common@langEn ?("\nIK9999: Succees.\n", "\nIK9999: 正常終了。\n"))
else
- do @textLog :~ \common@langEn ?("\nIK9999: Failure.\n", "\nIK9999: 実行失敗。\n")
- do @updateLog()
+ do @editLog.addText(\common@langEn ?("\nIK9999: Failure.\n", "\nIK9999: 実行失敗。\n"))
do wnd@msgBox(@wndMain, \common@langEn ?("Could not run.", "実行できませんでした。"), \common@title, %err, %ok)
end if
do \src@delRunningFiles()
@@ -546,8 +885,17 @@ func btnCompileOnPush(wnd: wnd@WndBase)
catch
do wnd@msgBox(@wndMain, \common@langEn ?("Unexpected error.", "予期せぬエラーです。"), \common@title, %err, %ok)
end try
+ if(\dbgwnd@wndDbg <>& null)
+ do \dbgwnd@wndDbg.close()
+ end if
do @updateUi()
do @lockEditor(false)
+ do @wndMain.activate()
+
+ func fixAll(key: []char, value: \doc@Doc, data: kuin@Class): bool
+ do value.fix()
+ ret true
+ end func
func idleFunc()
do wnd@act()
@@ -556,32 +904,80 @@ func btnCompileOnPush(wnd: wnd@WndBase)
func eventFunc(type: int, str: []char): int
switch(type)
case 0
- do @textLog :~ str.sub(5, -1)
- do @updateLog()
+ do @editLog.addText(str.sub(4, -1))
end switch
end func
-end func
-func radioEnvOnPush(wnd: wnd@WndBase)
- if(@lockPropOnChange)
- ret
- end if
- do \prop@changeProp()
-end func
+ func breakPointsFunc()
+ class BreakPoint()
+ +var items: list<\src@Pos>
+ end class
-func editIconOnChange(wnd: wnd@WndBase)
- if(@lockPropOnChange)
- ret
- end if
- do \prop@changeProp()
+ var breakPoint: BreakPoint :: #BreakPoint
+ do breakPoint.items :: #list<\src@Pos>
+ do \src@docs.forEach(callback, breakPoint)
+ var itemsArray: []\src@Pos :: breakPoint.items.toArray()
+ for i(0, ^itemsArray - 1)
+ do (\src@docs.get(itemsArray[i].src, &) $ \doc_src@DocSrc).unsetBreakPoint(itemsArray[i].row - 1)
+ end for
+ do \dll@setBreakPoints(itemsArray)
+ for i(0, ^itemsArray - 1)
+ if(itemsArray[i].row <> -1)
+ do (\src@docs.get(itemsArray[i].src, &) $ \doc_src@DocSrc).setBreakPoint(itemsArray[i].row - 1)
+ end if
+ end for
+ do @paintDrawEditor()
+
+ func callback(key: []char, value: \doc@Doc, data: BreakPoint): bool
+ if(value =$ \doc_src@DocSrc & key[0] = '\\')
+ do (value $ \doc_src@DocSrc).getBreakPoints(key, data.items)
+ end if
+ ret true
+ end func
+ end func
+
+ func breakFunc(code: int, pos: \src@Pos, msg: []char)
+ do \dbgwnd@setMsg(msg)
+ if(code <> 0x80000003)
+ do wnd@msgBox(@wndMain, msg, \common@title, %err, %ok)
+ end if
+ if(pos =& null)
+ ret
+ end if
+ var pos2: \src@Pos :: #\src@Pos
+ do pos2.src :: ##pos.src
+ do pos2.row :: pos.row
+ do pos2.col :: pos.col
+ do \src@breakPos :: pos2
+ do @btnCompile.setText(\common@langEn ?("Continue", "続行"))
+ do @btnCompile.setEnabled(true)
+ if (!\src@jumpSrc(pos))
+ do @paintDrawEditor()
+ do @focusDrawEditor()
+ end if
+ while(\src@breakPos <>& null & wnd@act())
+ end while
+ do @btnCompile.setEnabled(false)
+ do @btnCompile.setText(\common@langEn ?("Compile && Run", "コンパイル&実行"))
+ end func
+
+ func dbgFunc(mode: int, str1: []char, str2: []char)
+ switch(mode)
+ case 0
+ do \dbgwnd@clear()
+ case 1
+ do \dbgwnd@addWatch(str1, str2)
+ case 2
+ do \dbgwnd@addCallStack(str1)
+ end switch
+ end func
end func
-func btnIconOnPush(wnd: wnd@WndBase)
- var file: []char :: wnd@openFileDialog(@wndMain, [\common@langEn ?("Icon (*.ico,*.icon)", "アイコン (*.ico,*.icon)"), "*.ico;*.icon"], 0)
- if(file =& null)
+func radioEnvOnPush(wnd: wnd@WndBase)
+ if(@lockUi)
ret
end if
- do @editIcon.setText(file)
+ do \prop@changeProp()
end func
func btnRlsOnPush(wnd: wnd@WndBase)
@@ -610,17 +1006,16 @@ func btnRlsOnPush(wnd: wnd@WndBase)
ret
end try
do \dll@resetMemAllocator()
- do @textLog :: ""
- do @updateLog()
+ do @editLog.setText("")
try
do \src@resetErrList()
var appCode: int :: lib@rnd(1, lib@intMax) * (lib@rnd(0, 1) = 0 ?(1, -1))
if(appCode = 0)
do appCode :: 1 {Since it is not convenient when 'AppCode' becomes 0, it is set to 1.}
end if
- if(\dll@build(\src@mainSrcName, \src@getSrc, null, out, @editIcon.getText().trim(), true, @getEnv(), @log, \common@langEn ?(1, 0), appCode))
- if(\src@mainSrcName <> \common@untitledSrcName)
- var resSrc: []char :: file@dir(\src@mainSrcName) ~ "res/"
+ if(\dll@build(\src@mainSrcPath, \src@getSrc, null, out, @iconPath, @relatedFiles, true, @getEnv(), @log, \common@langEn ?(1, 0), appCode))
+ if(\src@mainSrcDir <> \common@defaultDir)
+ var resSrc: []char :: \src@mainSrcDir ~ "res/"
if(file@exist(resSrc))
var resDst: []char :: tmp ~ "res.knd"
if(!\dll@archive(resDst, resSrc, appCode))
@@ -660,10 +1055,9 @@ end func
+func listFileOnSel(wnd: wnd@WndBase)
var sel: int :: @listFile.getSel()
if(sel <> -1)
- var internalName: []char :: \src@removePrefix(@listFile.getText(sel))
- if(^internalName > 0 & (internalName[0] = '\\' | internalName[0] = '!'))
- var src: []char :: \src@internalNameToSrcName(internalName)
- var doc: \doc@Doc :: \src@docs.get(src)
+ var src: []char :: \src@removePrefix(@listFile.getText(sel))
+ if(^src > 0 & src[0] = '\\')
+ var doc: \doc@Doc :: \src@docs.get(src, &)
if(doc <>& null)
do \src@setCurSrc(doc)
end if
@@ -672,10 +1066,6 @@ end func
do @updateUi()
end func
-func updateLog()
- do @editLog.setText(@textLog)
-end func
-
+func updateFile()
do @editFile.setText("")
@@ -685,16 +1075,18 @@ end func
do @listFile.setRedraw(true)
func callback(src: []char, doc: \doc@Doc, data: kuin@Class): bool
+ if(src[0] <> '\\')
+ ret true
+ end if
var prefix: []char :: ""
- var internalName: []char :: \src@srcNameToInternalName(src)
if(doc =& \src@curDoc)
do prefix :~ ">"
- do @editFile.setText(internalName)
+ do @editFile.setText(src)
end if
- if(doc.changed)
+ if(doc.getChanged())
do prefix :~ "*"
end if
- do @listFile.add(prefix ~ internalName)
+ do @listFile.add(prefix ~ src)
if(doc =& \src@curDoc)
do @listFile.setSel(@listFile.len() - 1)
end if
@@ -702,57 +1094,31 @@ end func
end func
end func
-+func updateProp()
- do @listProp.setRedraw(false)
- do @listProp.clear()
- do @listProp.clearColumn()
- if(\src@curDoc =$ \doc_src@DocSrc)
- do @listProp.addColumn(\common@langEn ?("Error", "エラー"))
- else
- do @listProp.addColumn(\common@langEn ?("Property", "プロパティ"))
- do @listProp.addColumn(\common@langEn ?("Value", "値"))
- end if
- do \src@curDoc.updateProp(@listProp)
- do @listProp.adjustWidth()
- do @listProp.setRedraw(true)
-end func
-
-+func updateTree()
- do @lockTreeItemOnSel :: true
- do @treeItem.setRedraw(false)
- do @treeItem.clear()
- do \src@curDoc.updateTree(@treeItem)
- do @treeItem.expand(true)
- do @treeItem.setRedraw(true)
- do @lockTreeItemOnSel :: false
-end func
-
-+func updateList()
- do @listObj.setRedraw(false)
- do @listObj.clear()
- do \src@curDoc.updateList(@listObj)
- do @listObj.setRedraw(true)
-end func
-
+func updateUi()
+ do @lockUi :: true
do @updateFile()
- do @updateProp()
- do @updateTree()
- do @updateList()
+ do \src@curDoc.updateUi()
+ do \src@curDoc.updateScrollBar()
+ do @chkRbArSnap.setChk(@snap)
+ do @editRbArSnap.setEnabled(@snap)
+ do @editRbArSnap.setText(@snapValue.toStr())
+ do @editRbArZoom.setText(@zoom.toStr())
+
+ do @menuMain.delPopup(@popupMainArranger)
+ if(\src@curDoc =$ \doc_gen@DocGen)
+ if((\src@curDoc $ \doc_gen@DocGen).designer =$ \doc_ar@DocAr)
+ do @menuMain.insPopup(@popupMainHelp, \common@langEn ?("&Arranger", "アレンジャー(&A)"), @popupMainArranger)
+ end if
+ end if
+ do @wndMain.updateMenu()
+
+ do @lockUi :: false
end func
func lockEditor(lock: bool)
do @lockingEditor :: lock
do @btnCompile.setEnabled(!lock)
do @btnRls.setEnabled(!lock)
- do @editIcon.setEnabled(!lock)
- do @btnIcon.setEnabled(!lock)
-end func
-
-+func setEditIconDirectly(icon: []char)
- do @lockPropOnChange :: true
- do @editIcon.setText(icon)
- do @lockPropOnChange :: false
end func
+func paintDrawEditor()
@@ -772,27 +1138,26 @@ end func
ret "wnd"
end func
-+func setEnvDirectly(env: []char)
- do @lockPropOnChange :: true
++func setEnvDirectly(env_: []char)
+ do @lockUi :: true
do @radioEnvWnd.setChk(false)
do @radioEnvCui.setChk(false)
- switch(env)
+ switch(env_)
case "wnd"
do @radioEnvWnd.setChk(true)
case "cui"
do @radioEnvCui.setChk(true)
end switch
- do @lockPropOnChange :: false
+ do @lockUi :: false
end func
func log(args: [][]char, row: int, col: int)
var msg: []char :: \common@nullStr(args[0]) ~ ": " ~ \common@nullStr(args[1])
if(args[2] =& null)
- do @textLog :~ msg ~ "\n"
+ do @editLog.addText(msg ~ "\n")
else
- do @textLog :~ msg ~ " (" ~ \common@nullStr(args[2]) ~ ": " ~ row.toStr() ~ ", " ~ col.toStr() ~ ")\n"
+ do @editLog.addText(msg ~ " (" ~ \common@nullStr(args[2]) ~ ": " ~ row.toStr() ~ ", " ~ col.toStr() ~ ")\n")
end if
- do @updateLog()
var pos: \src@Pos :: #\src@Pos
do pos.src :: args[2] =& null ?("", ##args[2])
do pos.row :: row
@@ -820,6 +1185,17 @@ end func
ret @drag
end func
-+func getIconPath(): []char
- ret @editIcon.getText()
+func openResFolder()
+ if(\src@mainSrcDir = \common@defaultDir)
+ do wnd@msgBox(@wndMain, \common@langEn ?("The main source file must be saved before adding another file.", "ファイルを追加する前にメインソースファイルを保存しなければなりません。"), \common@title, %err, %ok)
+ ret
+ end if
+ var path: []char :: file@dir(\src@mainSrcDir) ~ "res/"
+ if(!file@exist(path))
+ if(!file@makeDir(path))
+ do wnd@msgBox(@wndMain, \common@langEn ?("Failed to create res folder.", "resフォルダの作成に失敗しました。"), \common@title, %err, %ok)
+ ret
+ end if
+ end if
+ do task@open(path)
end func
diff --git a/src/kuin_editor/knobj_maker.kn b/src/kuin_editor/knobj_maker.kn
new file mode 100644
index 00000000..31d249d7
--- /dev/null
+++ b/src/kuin_editor/knobj_maker.kn
@@ -0,0 +1,92 @@
+var wndKnobjMaker: wnd@Wnd
+var editPathInput: wnd@Edit
+var chkTangentBinormal: wnd@Chk
+var chkJoint: wnd@Chk
+var editLog: wnd@EditMulti
+var btnConvert: wnd@Btn
+var btnClose: wnd@Btn
+
++func show()
+ if(@wndKnobjMaker <>& null)
+ do @wndKnobjMaker.activate()
+ ret
+ end if
+
+ do @wndKnobjMaker :: wnd@makeWnd(\form@wndMain, %fix, 300, 265, \common@langEn ?("3D Model Converter", "3D モデルコンバータ"))
+ do @wndKnobjMaker.onClose :: wndKnobjMakerOnClose
+
+ var labelPathInput: wnd@Label :: wnd@makeLabel(@wndKnobjMaker, 12, 12, 100, 12, %fix, %fix, \common@langEn ?("Input", "入力"))
+ do @editPathInput :: wnd@makeEdit(@wndKnobjMaker, 12, 30, 246, 19, %fix, %fix)
+ var btnPathInput: wnd@Btn :: wnd@makeBtn(@wndKnobjMaker, 258, 30, 30, 19, %fix, %fix, "...")
+ do btnPathInput.onPush :: btnPathInputOnPush
+ do @chkTangentBinormal :: wnd@makeChk(@wndKnobjMaker, 12, 55, 276, 16, %fix, %fix, \common@langEn ?("Write Tangents and Binormals", "タンジェントとバイノーマルを書き込む"))
+ do @chkJoint :: wnd@makeChk(@wndKnobjMaker, 12, 77, 276, 16, %fix, %fix, \common@langEn ?("Write Joints", "ジョイントを書き込む"))
+ do @editLog :: wnd@makeEditMulti(@wndKnobjMaker, 12, 99, 276, 125, %fix, %fix)
+ do @editLog.readonly(true)
+
+ do @btnConvert :: wnd@makeBtn(@wndKnobjMaker, 82, 230, 100, 23, %fix, %fix, \common@langEn ?("Convert", "コンバート"))
+ do @btnConvert.onPush :: btnConvertOnPush
+ do @btnClose :: wnd@makeBtn(@wndKnobjMaker, 188, 230, 100, 23, %fix, %fix, \common@langEn ?("Close", "閉じる"))
+ do @btnClose.onPush :: btnCloseOnPush
+
+ func wndKnobjMakerOnClose(wnd: wnd@Wnd): bool
+ do @wndKnobjMaker :: null
+ do @editPathInput :: null
+ do @chkTangentBinormal :: null
+ do @chkJoint :: null
+ do @editLog :: null
+ do @btnConvert :: null
+ do @btnClose :: null
+ ret true
+ end func
+
+ func btnPathInputOnPush(wnd: wnd@WndBase)
+ var file: []char :: wnd@openFileDialog(@wndKnobjMaker, [\common@langEn ?("FBX File (*.fbx)", "FBX ファイル (*.fbx)"), "*.fbx"], 0)
+ if(file =& null)
+ ret
+ end if
+ do @editPathInput.setText(file)
+ end func
+
+ func btnConvertOnPush(wnd: wnd@WndBase)
+ do @btnConvert.setEnabled(false)
+ do @btnClose.setEnabled(false)
+ do @editLog.setText("")
+ do wnd@act()
+ var format: bit32 :: 0b32
+ var inputPath: []char :: @editPathInput.getText().trim()
+ if(inputPath = "")
+ ret
+ end if
+ if(@chkTangentBinormal.getChk())
+ do format :: format.or(0x01b32)
+ end if
+ if(@chkJoint.getChk())
+ do format :: format.or(0x02b32)
+ end if
+ var process: task@Process :: task@makeProcess(file@exeDir() ~ "tools/knobj_maker.exe", "\{format $ int} \"\{inputPath}\"")
+ do process.run(false)
+ while(process.running(&), skip)
+ var log: []char :: process.readPipe()
+ if(log <>& null)
+ do @editLog.setText(log)
+ end if
+ do wnd@act()
+ do lib@sleep(100)
+ end while
+ block
+ var log: []char :: process.readPipe()
+ if(log <>& null)
+ do @editLog.setText(log)
+ end if
+ end block
+ do process.fin()
+ do wnd@msgBox(@wndKnobjMaker, \common@langEn ?("The conversion is complete.", "コンバートが完了しました。"), \common@title, %none, %ok)
+ do @btnConvert.setEnabled(true)
+ do @btnClose.setEnabled(true)
+ end func
+
+ func btnCloseOnPush(wnd: wnd@WndBase)
+ do @wndKnobjMaker.close()
+ end func
+end func
diff --git a/src/kuin_editor/kuin_editor.kn b/src/kuin_editor/kuin_editor.kn
index 9a18b374..8774d2ec 100644
--- a/src/kuin_editor/kuin_editor.kn
+++ b/src/kuin_editor/kuin_editor.kn
@@ -9,12 +9,14 @@ func main()
do \find@init()
do \snippet@load()
do \form@makeWnd()
+ do \recent@load()
do \doc_src@init()
do \src@init()
if(^lib@cmdLine() > 0)
do \src@openMainSrc(lib@cmdLine()[0].replace("\\", "/"))
- else
+ end if
+ if(\src@curDoc =& null)
do \src@newMainSrc()
end if
diff --git a/src/kuin_editor/obj_prop.kn b/src/kuin_editor/obj_prop.kn
new file mode 100644
index 00000000..c4124014
--- /dev/null
+++ b/src/kuin_editor/obj_prop.kn
@@ -0,0 +1,184 @@
+var wndObjProp: wnd@Wnd
+var result: bool
+
+class PropInfo()
+ +var name: []char
+ +var type: \doc_ar@PropType
+ +var typeDatas: [][]char
+ +var value: []char
+ +var label: wnd@Label
+ +var ctrls: []wnd@WndBase
+ +var same: bool
+ +var btnReset: wnd@Btn
+end class
+
+var propInfos: []@PropInfo
+var targets: []\doc_ar@Obj
+
+func getPropInfos(objs: []\doc_ar@Obj): []@PropInfo
+ var propsNames: [][]char :: objs[0].propsNames()
+ var propsTypes: []\doc_ar@PropType :: objs[0].propsTypes()
+ var propsTypeDatas: [][][]char :: objs[0].propsTypeDatas()
+ assert ^propsNames = ^propsTypes & ^propsTypes = ^propsTypeDatas
+ var propInfos: dict<[]char, @PropInfo> :: #dict<[]char, @PropInfo>
+ for i(0, ^propsNames - 1)
+ var propInfo: @PropInfo :: #@PropInfo
+ do propInfo.name :: propsNames[i]
+ do propInfo.type :: propsTypes[i]
+ do propInfo.typeDatas :: propsTypeDatas[i]
+ do propInfo.value :: null
+ var same: bool :: true
+ for j(0, ^objs - 1)
+ var success: bool
+ var value: []char :: objs[j].props.get(propInfo.name, &success)
+ if(!success)
+ skip i
+ end if
+ if(propInfo.value <>& null & propInfo.value <> value)
+ do same :: false
+ break j
+ end if
+ do propInfo.value :: value
+ end for
+ do propInfo.same :: same
+ if(!same)
+ do propInfo.value :: ""
+ end if
+ do propInfos.add(propsNames[i], propInfo)
+ end for
+ ret propInfos.toArrayValue()
+end func
+
++func show(objs: []\doc_ar@Obj): bool
+ do @targets :: objs
+ do @wndObjProp :: wnd@makeWnd(\form@wndMain, (%fix $ wnd@WndStyle).or(%noMinimize), 300, 480, ^objs = 1 ?(objs[0].name, \common@langEn ?("Multiple Objects", "複数のオブジェクト")))
+
+ do @propInfos :: @getPropInfos(objs)
+ for i(0, ^@propInfos - 1)
+ do @propInfos[i].label :: wnd@makeLabel(@wndObjProp, 12, 15 + 25 * i, 60, 12, %fix, %fix, @propInfos[i].name)
+ switch(@propInfos[i].type)
+ case %str, %int_, %float_
+ var edit: wnd@Edit :: wnd@makeEdit(@wndObjProp, 92, 12 + 25 * i, 180, 19, %fix, %fix)
+ do edit.setText(@propInfos[i].value)
+ do @propInfos[i].ctrls :: [edit]
+ case %bool_
+ var chk: wnd@Chk :: wnd@makeChk(@wndObjProp, 92, 12 + 25 * i, 180, 16, %fix, %fix, @propInfos[i].name)
+ do chk.setChk(@propInfos[i].value = "true")
+ do @propInfos[i].ctrls :: [chk]
+ case %enum_
+ var combo: wnd@Combo :: wnd@makeCombo(@wndObjProp, 92, 12 + 25 * i, 180, 20, %fix, %fix)
+ var value: []char :: @propInfos[i].value
+ var empty: bool :: value = ""
+ for j(0, ^@propInfos[i].typeDatas - 1)
+ do combo.add(@propInfos[i].typeDatas[j])
+ if(empty & j = 0 | @propInfos[i].typeDatas[j] = value)
+ do combo.setSel(j)
+ end if
+ end for
+ do @propInfos[i].ctrls :: [combo]
+ case %color
+ var edit: wnd@Edit :: wnd@makeEdit(@wndObjProp, 92, 12 + 25 * i, 105, 19, %fix, %fix)
+ do edit.setText(@propInfos[i].value)
+ var btn: wnd@Btn :: wnd@makeBtn(@wndObjProp, 197, 12 + 25 * i, 75, 23, %fix, %fix, \common@langEn ?("Browse...", "参照..."))
+ do btn.onPush :: btnColorOnPush
+ do @propInfos[i].ctrls :: [edit $ wnd@WndBase, btn $ wnd@WndBase]
+ case %file
+ var edit: wnd@Edit :: wnd@makeEdit(@wndObjProp, 92, 12 + 25 * i, 105, 19, %fix, %fix)
+ do edit.setText(@propInfos[i].value)
+ var btn: wnd@Btn :: wnd@makeBtn(@wndObjProp, 197, 12 + 25 * i, 75, 23, %fix, %fix, \common@langEn ?("Browse...", "参照..."))
+ do @propInfos[i].ctrls :: [edit $ wnd@WndBase, btn $ wnd@WndBase]
+ end switch
+
+ if(!@propInfos[i].same)
+ var btnReset: wnd@Btn :: wnd@makeBtn(@wndObjProp, 92, 12 + 25 * i, 100, 23, %fix, %fix, \common@langEn ?("Edit Values", "複数の編集"))
+ do btnReset.onPush :: btnResetOnPush
+ do @propInfos[i].btnReset :: btnReset
+ for j(0, ^@propInfos[i].ctrls - 1)
+ do @propInfos[i].ctrls[j].setVisible(false)
+ end for
+ end if
+ end for
+
+ var btnOk: wnd@Btn :: wnd@makeBtn(@wndObjProp, 72, 445, 75, 23, %fix, %fix, "OK")
+ do btnOk.onPush :: btnOkOnPush
+ var btnCancel: wnd@Btn :: wnd@makeBtn(@wndObjProp, 153, 445, 75, 23, %fix, %fix, \common@langEn ?("Cancel", "キャンセル"))
+ do btnCancel.onPush :: btnCancelOnPush
+
+ do @result :: false
+ do @wndObjProp.modal()
+
+ do @wndObjProp :: null
+ do @propInfos :: null
+ do @targets :: null
+
+ ret @result
+
+ func btnOkOnPush(wnd: wnd@WndBase)
+ for i(0, ^@propInfos - 1)
+ if(!@propInfos[i].same)
+ skip i
+ end if
+ var value: []char
+ switch(@propInfos[i].type)
+ case %str
+ do value :: (@propInfos[i].ctrls[0] $ wnd@Edit).getText()
+ case %int_
+ var value2: int :: (@propInfos[i].ctrls[0] $ wnd@Edit).getText().toInt(&)
+ do value :: value2.toStr()
+ case %float_
+ var value2: float :: (@propInfos[i].ctrls[0] $ wnd@Edit).getText().toFloat(&)
+ do value :: value2.toStr()
+ if(value.find('.', -1) = -1)
+ do value :~ ".0"
+ end if
+ case %bool_
+ do value :: (@propInfos[i].ctrls[0] $ wnd@Chk).getChk() ?("true", "false")
+ case %enum_
+ var combo: wnd@Combo :: @propInfos[i].ctrls[0] $ wnd@Combo
+ var sel: int :: (combo).getSel()
+ do value :: sel = -1 ?("", combo.getText(sel))
+ case %color
+ var value2: int :: (@propInfos[i].ctrls[0] $ wnd@Edit).getText().toInt(&)
+ do value :: "0x" ~ value2.toStrFmt("08X")
+ case %file
+ do value :: (@propInfos[i].ctrls[0] $ wnd@Edit).getText()
+ end switch
+ for j(0, ^@targets - 1)
+ do @targets[j].props.add(@propInfos[i].name, value)
+ end for
+ end for
+ do @result :: true
+ do @wndObjProp.close()
+ end func
+
+ func btnCancelOnPush(wnd: wnd@WndBase)
+ do @wndObjProp.close()
+ end func
+
+ func btnColorOnPush(wnd: wnd@WndBase)
+ for i(0, ^@propInfos - 1)
+ if(^@propInfos[i].ctrls >= 2 & @propInfos[i].ctrls[1] =& wnd)
+ var edit: wnd@Edit :: @propInfos[i].ctrls[0] $ wnd@Edit
+ var color: int :: edit.getText().toInt(&)
+ ; var value: []char :: \color_sel@show(@wndObjProp, color)
+ do color :: wnd@colorDialog(@wndObjProp, color.clamp(0, 0xFFFFFFFF) % 0x1000000)
+ if(color <> -1)
+ do edit.setText("0xFF" ~ color.toStrFmt("06X"))
+ end if
+ ret
+ end if
+ end for
+ end func
+
+ func btnResetOnPush(wnd: wnd@WndBase)
+ for i(0, ^@propInfos - 1)
+ if(@propInfos[i].btnReset =& wnd)
+ do @propInfos[i].btnReset.setVisible(false)
+ for j(0, ^@propInfos[i].ctrls - 1)
+ do @propInfos[i].ctrls[j].setVisible(true)
+ end for
+ do @propInfos[i].same :: true
+ end if
+ end for
+ end func
+end func
diff --git a/src/kuin_editor/proj_settings.kn b/src/kuin_editor/proj_settings.kn
new file mode 100644
index 00000000..e92e54e5
--- /dev/null
+++ b/src/kuin_editor/proj_settings.kn
@@ -0,0 +1,74 @@
+var wndProjSettings: wnd@Wnd
+var editIcon: wnd@Edit
+var listRelatedFile: wnd@List
+
++func show()
+ do @wndProjSettings :: wnd@makeWnd(\form@wndMain, (%fix $ wnd@WndStyle).or(%noMinimize), 640, 405, \common@langEn ?("Other Settings", "その他の設定"))
+ var labelIcon: wnd@Label :: wnd@makeLabel(@wndProjSettings, 6, 6, 35, 12, %fix, %fix, \common@langEn ?("Icon", "アイコン"))
+ do @editIcon :: wnd@makeEdit(@wndProjSettings, 47, 6, 243, 19, %move, %fix)
+ do @editIcon.setText(\form@iconPath)
+ var btnIcon: wnd@Btn :: wnd@makeBtn(@wndProjSettings, 290, 6, 30, 19, %move, %fix, "...")
+ do btnIcon.onPush :: btnIconOnPush
+
+ var labelRelatedFile: wnd@Label :: wnd@makeLabel(@wndProjSettings, 6, 35, 314, 12, %fix, %fix, \common@langEn ?("Related Files (They are copied into the data folder.)", "関連ファイル (dataフォルダ以下にコピーされます)"))
+ do @listRelatedFile :: wnd@makeList(@wndProjSettings, 6, 53, 314, 311, %fix, %fix)
+ do \form@relatedFiles.head()
+ while(!\form@relatedFiles.term())
+ do @listRelatedFile.add(\form@relatedFiles.get())
+ do \form@relatedFiles.next()
+ end while
+ var btnAddRelatedFile: wnd@Btn :: wnd@makeBtn(@wndProjSettings, 6, 370, 80, 23, %fix, %fix, \common@langEn ?("Add...", "追加..."))
+ do btnAddRelatedFile.onPush :: btnAddRelatedFileOnPush
+ var btnDelRelatedFile: wnd@Btn :: wnd@makeBtn(@wndProjSettings, 92, 370, 80, 23, %fix, %fix, \common@langEn ?("Remove", "削除"))
+ do btnDelRelatedFile.onPush :: btnDelRelatedFileOnPush
+
+ var btnOk: wnd@Btn :: wnd@makeBtn(@wndProjSettings, 422, 370, 100, 23, %fix, %fix, "OK")
+ do btnOk.onPush :: btnOkOnPush
+ var btnCancel: wnd@Btn :: wnd@makeBtn(@wndProjSettings, 528, 370, 100, 23, %fix, %fix, "キャンセル")
+ do btnCancel.onPush :: btnCancelOnPush
+
+ do @wndProjSettings.modal()
+ do @wndProjSettings :: null
+ do @editIcon :: null
+ do @listRelatedFile :: null
+
+ func btnIconOnPush(wnd: wnd@WndBase)
+ var file: []char :: wnd@openFileDialog(@wndProjSettings, [\common@langEn ?("Icon (*.ico,*.icon)", "アイコン (*.ico,*.icon)"), "*.ico;*.icon"], 0)
+ if(file =& null)
+ ret
+ end if
+ do @editIcon.setText(file)
+ end func
+
+ func btnAddRelatedFileOnPush(wnd: wnd@WndBase)
+ var file: []char :: wnd@openFileDialog(@wndProjSettings, [\common@langEn ?("All Files (*.*)", "すべてのファイル (*.*)"), "*.*"], 0)
+ if(file =& null)
+ ret
+ end if
+ do @listRelatedFile.add(file)
+ end func
+
+ func btnDelRelatedFileOnPush(wnd: wnd@WndBase)
+ var sel: int :: @listRelatedFile.getSel()
+ if(sel = -1)
+ ret
+ end if
+ do @listRelatedFile.del(sel)
+ end func
+
+ func btnOkOnPush(wnd: wnd@WndBase)
+ do \form@iconPath :: @editIcon.getText().trim()
+ do \form@relatedFiles :: #list<[]char>
+ var len: int :: @listRelatedFile.len()
+ for i(0, len - 1)
+ do \form@relatedFiles.add(@listRelatedFile.getText(i))
+ end for
+ do \form@relatedFiles.sort()
+ do \prop@changeProp()
+ do @wndProjSettings.close()
+ end func
+
+ func btnCancelOnPush(wnd: wnd@WndBase)
+ do @wndProjSettings.close()
+ end func
+end func
diff --git a/src/kuin_editor/prop.kn b/src/kuin_editor/prop.kn
index 2b2262b0..90cff76f 100644
--- a/src/kuin_editor/prop.kn
+++ b/src/kuin_editor/prop.kn
@@ -1,47 +1,87 @@
+func save()
- var path: []char :: file@delExt(\src@mainSrcName) ~ ".knprop"
+ var path: []char :: file@delExt(\src@mainSrcPath) ~ ".knprop"
do file@delFile(path)
var prop: xml@Xml :: xml@makeXmlEmpty()
var root: xml@Node :: prop.root()
var cfg: xml@Node :: root.addChild("configuration")
- do cfg.addChild("icon").setValue(\form@getIconPath())
+ do cfg.addChild("icon").setValue(\form@iconPath)
do cfg.addChild("env").setValue(\form@getEnv())
- var reses: xml@Node :: cfg.addChild("resources")
- do \src@docs.forEach(callback, reses)
+ do cfg.addChild("snap").setValue((\form@snap ?(\form@snapValue, 0)).toStr())
+ do cfg.addChild("zoom").setValue(\form@zoom.toStr())
+ var relatedFiles: xml@Node :: cfg.addChild("related_files")
+ do \form@relatedFiles.head()
+ while(!\form@relatedFiles.term())
+ do relatedFiles.addChild("path").setValue(\form@relatedFiles.get())
+ do \form@relatedFiles.next()
+ end while
+
+ class Data()
+ +var reses: xml@Node
+ +var curDoc: \doc@Doc
+ end class
+ var data: Data :: #Data
+ do data.reses :: cfg.addChild("resources")
+ do data.curDoc :: \src@mainDoc()
+ do \src@docs.forEach(callback, data)
do prop.save(path, false)
- func callback(src: []char, doc: \doc@Doc, reses: xml@Node): bool
- if(^\src@mainSrcDir <= ^src & \src@mainSrcDir = src.sub(0, ^\src@mainSrcDir) & file@ext(src).lower() <> "kn")
- do reses.addChild("resource").setValue(src.sub(^\src@mainSrcDir, -1))
+ func callback(src: []char, doc: \doc@Doc, data: Data): bool
+ if(doc <>& data.curDoc & src[0] = '\\')
+ do data.reses.addChild("resource").setValue(src.sub(1, -1) ~ \src@getExt(doc))
end if
ret true
end func
end func
+func load()
+ if(\src@mainSrcDir = \common@defaultDir)
+ ret
+ end if
try
- var prop: xml@Xml :: xml@makeXml(file@delExt(\src@mainSrcName) ~ ".knprop")
+ var prop: xml@Xml :: xml@makeXml(file@delExt(\src@mainSrcPath) ~ ".knprop")
if(prop =& null)
ret
end if
var root: xml@Node :: prop.root()
var cfg: xml@Node :: root.findChild("configuration")
try
- do \form@setEditIconDirectly(cfg.findChild("icon").getValue())
+ do \form@iconPath :: cfg.findChild("icon").getValue()
catch
end try
try
do \form@setEnvDirectly(cfg.findChild("env").getValue())
catch
end try
+ try
+ var success: bool
+ var snap: int :: cfg.findChild("snap").getValue().toInt(&success)
+ if(success)
+ do \form@snap :: snap <> 0
+ do \form@snapValue :: snap < 1 ?(5, snap)
+ end if
+ catch
+ end try
+ try
+ var success: bool
+ var zoom: float :: cfg.findChild("zoom").getValue().toFloat(&success)
+ if(success)
+ do \form@zoom :: zoom
+ end if
+ catch
+ end try
+ try
+ do \form@relatedFiles :: #list<[]char>
+ var relatedFiles: xml@Node :: cfg.findChild("related_files").firstChild()
+ while (relatedFiles <>& null)
+ do \form@relatedFiles.add(relatedFiles.getValue())
+ do relatedFiles :: relatedFiles.next()
+ end while
+ catch
+ end try
try
var reses: xml@Node :: cfg.findChild("resources").firstChild()
while(reses <>& null)
- var path2: []char :: \src@mainSrcDir ~ reses.getValue()
- var doc: \doc@Doc :: \src@makeDoc(path2)
- if(doc <>& null)
- do \src@loadFileToDocs(path2, doc)
- end if
+ do \src@loadFileToDocs(\src@mainSrcDir ~ reses.getValue())
do reses :: reses.next()
end while
catch
@@ -52,6 +92,6 @@ end func
+func changeProp()
var doc: \doc@Doc :: \src@mainDoc()
- do doc.changed :: true
+ do doc.setChanged(true)
do \form@updateFile()
end func
diff --git a/src/kuin_editor/recent.kn b/src/kuin_editor/recent.kn
new file mode 100644
index 00000000..5bce5648
--- /dev/null
+++ b/src/kuin_editor/recent.kn
@@ -0,0 +1,95 @@
+var recent: list<[]char>
+const itemCountMax: int :: 20
+
++func load()
+ do @recent :: #list<[]char>
+ try
+ var prop: xml@Xml :: xml@makeXml(file@exeDir() ~ "sys/recent.knd")
+ if(prop =& null)
+ ret
+ end if
+ var root: xml@Node :: prop.root()
+ var recentFiles: xml@Node :: root.findChild("recent_files")
+ var node: xml@Node :: recentFiles.firstChild()
+ while(node <>& null)
+ do @recent.add(node.getValue())
+ do node :: node.next()
+ end while
+ catch
+ end try
+
+ do @updateUi()
+end func
+
++func save(fileName: []char)
+ do @recent.head()
+ if(@recent.term())
+ do @recent.add(fileName)
+ else
+ do @recent.ins(fileName)
+ end if
+ var newRecent: list<[]char> :: #list<[]char>
+ do @recent.head()
+ for i(0, @itemCountMax - 1)
+ if(@recent.term())
+ break i
+ end if
+ var file: []char :: @recent.get()
+ do newRecent.head()
+ var found: bool :: false
+ while loop(!newRecent.term())
+ if(newRecent.get() = file)
+ do found :: true
+ break loop
+ end if
+ do newRecent.next()
+ end while
+ if(!found)
+ do newRecent.add(file)
+ end if
+ do @recent.next()
+ end for
+ do @recent :: newRecent
+
+ do file@delFile(file@exeDir() ~ "sys/recent.knd")
+ var prop: xml@Xml :: xml@makeXmlEmpty()
+ var root: xml@Node :: prop.root()
+ var recentFiles: xml@Node :: root.addChild("recent_files")
+ do @recent.head()
+ while(!@recent.term())
+ do recentFiles.addChild("recent_file").setValue(@recent.get())
+ do @recent.next()
+ end while
+ do prop.save(file@exeDir() ~ "sys/recent.knd", false)
+
+ do @updateUi()
+end func
+
++func sel(id: int)
+ do @recent.head()
+ do @recent.moveOffset(id - 0x0400)
+ if(@recent.term())
+ ret
+ end if
+ var file: []char :: @recent.get()
+
+ if (\src@chkChanged())
+ do \src@openMainSrc(file)
+ do @save(file)
+ end if
+end func
+
+func updateUi()
+ for i(0, @itemCountMax - 1)
+ do \form@popupRecentFiles.del(0x0400 + i)
+ end for
+ do @recent.head()
+ for i(0, @itemCountMax - 1)
+ if(@recent.term())
+ break i
+ end if
+ do \form@popupRecentFiles.add(0x0400 + i, @recent.get())
+ do @recent.next()
+ end for
+ do \form@wndMain.updateMenu()
+end func
diff --git a/src/kuin_editor/res/draw2d.png b/src/kuin_editor/res/draw2d.png
new file mode 100644
index 00000000..61ee0b78
Binary files /dev/null and b/src/kuin_editor/res/draw2d.png differ
diff --git a/src/kuin_editor/res/kn.png b/src/kuin_editor/res/kn.png
new file mode 100644
index 00000000..648f9f09
Binary files /dev/null and b/src/kuin_editor/res/kn.png differ
diff --git a/src/kuin_editor/res/obj_btn.png b/src/kuin_editor/res/obj_btn.png
new file mode 100644
index 00000000..0f0a6c39
Binary files /dev/null and b/src/kuin_editor/res/obj_btn.png differ
diff --git a/src/kuin_editor/res/obj_chk.png b/src/kuin_editor/res/obj_chk.png
new file mode 100644
index 00000000..dc51bc1a
Binary files /dev/null and b/src/kuin_editor/res/obj_chk.png differ
diff --git a/src/kuin_editor/res/obj_circle.png b/src/kuin_editor/res/obj_circle.png
new file mode 100644
index 00000000..b0726c1c
Binary files /dev/null and b/src/kuin_editor/res/obj_circle.png differ
diff --git a/src/kuin_editor/res/obj_edit.png b/src/kuin_editor/res/obj_edit.png
new file mode 100644
index 00000000..8dc996c2
Binary files /dev/null and b/src/kuin_editor/res/obj_edit.png differ
diff --git a/src/kuin_editor/res/obj_edit_multi.png b/src/kuin_editor/res/obj_edit_multi.png
new file mode 100644
index 00000000..6655171a
Binary files /dev/null and b/src/kuin_editor/res/obj_edit_multi.png differ
diff --git a/src/kuin_editor/res/obj_group.png b/src/kuin_editor/res/obj_group.png
new file mode 100644
index 00000000..eb9424ad
Binary files /dev/null and b/src/kuin_editor/res/obj_group.png differ
diff --git a/src/kuin_editor/res/obj_img.png b/src/kuin_editor/res/obj_img.png
new file mode 100644
index 00000000..9ae28e8a
Binary files /dev/null and b/src/kuin_editor/res/obj_img.png differ
diff --git a/src/kuin_editor/res/obj_label.png b/src/kuin_editor/res/obj_label.png
new file mode 100644
index 00000000..d0dc05f6
Binary files /dev/null and b/src/kuin_editor/res/obj_label.png differ
diff --git a/src/kuin_editor/res/obj_none.png b/src/kuin_editor/res/obj_none.png
new file mode 100644
index 00000000..e74e19fb
Binary files /dev/null and b/src/kuin_editor/res/obj_none.png differ
diff --git a/src/kuin_editor/res/obj_particle.png b/src/kuin_editor/res/obj_particle.png
new file mode 100644
index 00000000..e8cf2a9f
Binary files /dev/null and b/src/kuin_editor/res/obj_particle.png differ
diff --git a/src/kuin_editor/res/obj_rect.png b/src/kuin_editor/res/obj_rect.png
new file mode 100644
index 00000000..b6124ba1
Binary files /dev/null and b/src/kuin_editor/res/obj_rect.png differ
diff --git a/src/kuin_editor/res/obj_roundrect.png b/src/kuin_editor/res/obj_roundrect.png
new file mode 100644
index 00000000..cee7c635
Binary files /dev/null and b/src/kuin_editor/res/obj_roundrect.png differ
diff --git a/src/kuin_editor/res/obj_text.png b/src/kuin_editor/res/obj_text.png
new file mode 100644
index 00000000..afd615a9
Binary files /dev/null and b/src/kuin_editor/res/obj_text.png differ
diff --git a/src/kuin_editor/res/wnd.png b/src/kuin_editor/res/wnd.png
new file mode 100644
index 00000000..6b6b9443
Binary files /dev/null and b/src/kuin_editor/res/wnd.png differ
diff --git a/src/kuin_editor/snippet.kn b/src/kuin_editor/snippet.kn
index 3aba77ae..0cc2def8 100644
--- a/src/kuin_editor/snippet.kn
+++ b/src/kuin_editor/snippet.kn
@@ -1,3 +1,14 @@
+var wndSnippet: wnd@Wnd
+var wndSnippetListSnippets: wnd@ListView
+var wndSnippetEditName: wnd@Edit
+var wndSnippetEditCode: wnd@EditMulti
+
+var wndPlace: wnd@Wnd
+var wndPlaceResult: []char
+var regexVariableSearch: regex@Regex
+var wndPlaceVariables: dict<[]char, wnd@Edit>
+var wndPlaceSnippetCode: []char
+
var snippets: list<@Snippet>
class Snippet()
@@ -6,6 +17,233 @@ class Snippet()
+var code: []char
end class
++func showSnippet()
+ do @wndSnippet :: wnd@makeWnd(\form@wndMain, (%fix $ wnd@WndStyle).or(%noMinimize), 640, 405, \common@langEn ?("Edit Snippets", "スニペットの編集"))
+ do @wndSnippetListSnippets :: wnd@makeListView(@wndSnippet, 12, 12, 250, 352, %fix, %scale, false, null, null)
+ do @wndSnippetListSnippets.style(%list_)
+ do @wndSnippetListSnippets.draggable(true)
+ do @snippets.head()
+ while(!@snippets.term())
+ var snippet: @Snippet :: @snippets.get()
+ if(snippet.removable)
+ do @wndSnippetListSnippets.add(snippet.name, -1)
+ end if
+ do @snippets.next()
+ end while
+ do @wndSnippetListSnippets.onSel :: listSnippetsOnSel
+ do @wndSnippetListSnippets.onMoveNode :: listSnippetsOnMoveNode
+ var labelName: wnd@Label :: wnd@makeLabel(@wndSnippet, 268, 12, 35, 12, %fix, %fix, \common@langEn ?("Name", "名前"))
+ do @wndSnippetEditName :: wnd@makeEdit(@wndSnippet, 268, 30, 360, 19, %fix, %fix)
+ do @wndSnippetEditName.onFocus :: editNameOnFocus
+ var labelCode: wnd@Label :: wnd@makeLabel(@wndSnippet, 268, 55, 35, 12, %fix, %fix, \common@langEn ?("Code", "コード"))
+ do @wndSnippetEditCode :: wnd@makeEditMulti(@wndSnippet, 268, 73, 360, 291, %fix, %fix)
+ do @wndSnippetEditCode.onFocus :: editCodeOnFocus
+ var btnAdd: wnd@Btn :: wnd@makeBtn(@wndSnippet, 12, 370, 100, 23, %fix, %fix, \common@langEn ?("Add", "追加"))
+ do btnAdd.onPush :: btnAddOnPush
+ var btnDel: wnd@Btn :: wnd@makeBtn(@wndSnippet, 118, 370, 100, 23, %fix, %fix, \common@langEn ?("Delete", "削除"))
+ do btnDel.onPush :: btnDelOnPush
+ var btnOk: wnd@Btn :: wnd@makeBtn(@wndSnippet, 528, 370, 100, 23, %fix, %fix, "OK")
+ do btnOk.onPush :: btnOkOnPush
+
+ do @wndSnippet.modal()
+ do @wndSnippet :: null
+ do @wndSnippetListSnippets :: null
+ do @wndSnippetEditName :: null
+ do @wndSnippetEditCode :: null
+ do @save()
+ do \form@updateUi()
+
+ func listSnippetsOnSel(wnd: wnd@WndBase)
+ var snippet: @Snippet :: @findSelSnippet()
+ if(snippet =& null)
+ do @wndSnippetEditName.setText("")
+ do @wndSnippetEditCode.setText("")
+ else
+ do @wndSnippetEditName.setText(snippet.name)
+ do @wndSnippetEditCode.setText(snippet.code)
+ end if
+ end func
+
+ func listSnippetsOnMoveNode(wnd: wnd@WndBase)
+ var newSnippets: list<@Snippet> :: #list<@Snippet>
+ do @snippets.head()
+ while(!@snippets.term())
+ var snippet: @Snippet :: @snippets.get()
+ if(!snippet.removable)
+ do newSnippets.add(snippet)
+ end if
+ do @snippets.next()
+ end while
+ for i(0, @wndSnippetListSnippets.len() - 1)
+ var name: []char :: @wndSnippetListSnippets.getText(&, i, 0)
+ do @snippets.head()
+ while loop(!@snippets.term())
+ var snippet: @Snippet :: @snippets.get()
+ if(snippet.removable & snippet.name = name)
+ do newSnippets.add(snippet)
+ break loop
+ end if
+ do @snippets.next()
+ end while
+ end for
+ do @snippets :: newSnippets
+ end func
+
+ func editNameOnFocus(wnd: wnd@WndBase, focused: bool)
+ if(!focused)
+ var snippet: @Snippet :: @findSelSnippet()
+ if(snippet =& null)
+ ret
+ end if
+ var name: []char :: @wndSnippetEditName.getText().trim()
+ if(@validate(name))
+ do snippet.name :: name
+ do @wndSnippetListSnippets.setText(@wndSnippetListSnippets.getSel(), 0, name, -1)
+ end if
+ do @wndSnippetEditName.setText(snippet.name)
+ end if
+ end func
+
+ func editCodeOnFocus(wnd: wnd@WndBase, focused: bool)
+ if(!focused)
+ var snippet: @Snippet :: @findSelSnippet()
+ if(snippet =& null)
+ ret
+ end if
+ do snippet.code :: @wndSnippetEditCode.getText()
+ end if
+ end func
+
+ func btnAddOnPush(wnd: wnd@WndBase)
+ var unique: int :: 1
+ while(true)
+ var name: []char :: "Snippet" ~ unique.toStr()
+ var found: bool :: false
+ do @snippets.head()
+ while loop(!@snippets.term())
+ var snippet: @Snippet :: @snippets.get()
+ if(snippet.removable & snippet.name = name)
+ do found :: true
+ break loop
+ end if
+ do @snippets.next()
+ end while
+ if(!found)
+ var snippet: @Snippet :: #@Snippet
+ do snippet.name :: name
+ do snippet.removable :: true
+ do snippet.code :: ""
+ do @snippets.add(snippet)
+ do @wndSnippetListSnippets.add(name, -1)
+ do @wndSnippetListSnippets.setSel(@wndSnippetListSnippets.len() - 1)
+ ret
+ end if
+ do unique :+ 1
+ end while
+ end func
+
+ func btnDelOnPush(wnd: wnd@WndBase)
+ var sel: int :: @wndSnippetListSnippets.getSel()
+ if(sel = -1)
+ ret
+ end if
+ var name: []char :: @wndSnippetListSnippets.getText(&, sel, 0)
+ if(wnd@msgBox(@wndSnippet, \common@langEn ?("Do you want to remove the snippet '\{name}'?", "スニペット「\{name}」を削除しますか?"), \common@title, %none, %yesNoCancel) <> %yes)
+ ret
+ end if
+ do @snippets.head()
+ while loop(!@snippets.term())
+ var snippet: @Snippet :: @snippets.get()
+ if(snippet.removable & snippet.name = name)
+ do @snippets.del()
+ break loop
+ end if
+ do @snippets.next()
+ end while
+ do @wndSnippetListSnippets.del(sel)
+ end func
+
+ func btnOkOnPush(wnd: wnd@WndBase)
+ do @wndSnippet.close()
+ end func
+end func
+
++func showPlace(name: []char): []char
+ if(^name >= 1 & name[0] = '\\')
+ do name :: name.sub(1, -1)
+ end if
+ var snippet: @Snippet :: null
+ do @snippets.head()
+ while loop(!@snippets.term())
+ var item: @Snippet :: @snippets.get()
+ if(item.name = name)
+ do snippet :: item
+ break loop
+ end if
+ do @snippets.next()
+ end while
+ if(snippet =& null)
+ ret null
+ end if
+ do @wndPlaceSnippetCode :: snippet.code
+
+ do @wndPlace :: wnd@makeWnd(\form@wndMain, (%fix $ wnd@WndStyle).or(%noMinimize), 600, 400, \common@langEn ?("Place Snippet \"\{snippet.name}\"", "スニペット「\{snippet.name}」の配置"))
+ var labelCode: wnd@Label :: wnd@makeLabel(@wndPlace, 12, 12, 276, 12, %fix, %fix, \common@langEn ?("The following code will be placed.", "以下のコードが配置されます。"))
+ var editCode: wnd@EditMulti :: wnd@makeEditMulti(@wndPlace, 12, 30, 326, 329, %fix, %fix)
+ do editCode.readonly(true)
+ do editCode.setText(@wndPlaceSnippetCode)
+ var labelDescription1: wnd@Label :: wnd@makeLabel(@wndPlace, 344, 12, 244, 12, %fix, %fix, \common@langEn ?("The parts enclosed by \"{{\" and \"}}\" are", "「{{」と「}}」で囲まれた部分は"))
+ var labelDescription2: wnd@Label :: wnd@makeLabel(@wndPlace, 344, 30, 244, 12, %fix, %fix, \common@langEn ?("replaced by the following.", "以下で置換されます。"))
+ var btnPlace: wnd@Btn :: wnd@makeBtn(@wndPlace, 382, 365, 100, 23, %fix, %fix, \common@langEn ?("Place", "配置"))
+ do btnPlace.onPush :: btnPlaceOnPush
+ var btnCancel: wnd@Btn :: wnd@makeBtn(@wndPlace, 488, 365, 100, 23, %fix, %fix, \common@langEn ?("Cancel", "キャンセル"))
+ do btnCancel.onPush :: btnCancelOnPush
+ do @wndPlaceResult :: null
+
+ do @wndPlaceVariables :: #dict<[]char, wnd@Edit>
+ if(@regexVariableSearch =& null)
+ do @regexVariableSearch :: regex@makeRegex("\\{\\{(.+?)\\}\\}")
+ end if
+ var matches: [][][]char :: @regexVariableSearch.findAll(&, @wndPlaceSnippetCode)
+ if(matches <>& null)
+ var itemCnt: int :: 0
+ for i(0, ^matches - 1)
+ var variable: []char :: matches[i][1]
+ if(!@wndPlaceVariables.exist(variable))
+ var labelVariable: wnd@Label :: wnd@makeLabel(@wndPlace, 344, 48 + itemCnt * 25, 70, 12, %fix, %fix, variable)
+ var editVariable: wnd@Edit :: wnd@makeEdit(@wndPlace, 420, 48 + itemCnt * 25, 168, 19, %fix, %fix)
+ do editVariable.setText(variable)
+ do @wndPlaceVariables.add(variable, editVariable)
+ do itemCnt :+ 1
+ end if
+ end for
+ end if
+
+ do @wndPlace.modal()
+ do @wndPlace :: null
+ do @wndPlaceSnippetCode :: null
+ do @wndPlaceVariables :: null
+
+ ret @wndPlaceResult
+
+ func btnPlaceOnPush(wnd: wnd@WndBase)
+ var data: lib@Str :: #lib@Str
+ do data.value :: @wndPlaceSnippetCode
+ do @wndPlaceVariables.forEach(callback, data)
+ do @wndPlaceResult :: data.value
+ do @wndPlace.close()
+
+ func callback(key: []char, value: wnd@Edit, data: lib@Str): bool
+ do data.value :: data.value.replace("{{\{key}}}", value.getText().trim())
+ ret true
+ end func
+ end func
+
+ func btnCancelOnPush(wnd: wnd@WndBase)
+ do @wndPlace.close()
+ end func
+end func
+
+func load()
do @snippets :: #list<@Snippet>
do loadXml(file@exeDir() ~ "sys/snippet.knd", false)
@@ -67,7 +305,7 @@ end func
ret
end if
- var name: []char :: wndex@inputBox(\form@wndMain, \common@langEn ?("Input the snippet name.", "スニペットの名前を入力してください。"), \common@title, null, validate)
+ var name: []char :: wndex@inputBox(\form@wndMain, \common@langEn ?("Input the snippet name.", "スニペットの名前を入力してください。"), \common@title, null, @validate)
if(name <>& null)
do name :: name.trim()
if(name <> "")
@@ -77,69 +315,48 @@ end func
do snippet.code :: code
do @snippets.add(snippet)
do @save()
+ do \form@updateUi()
end if
end if
-
- func validate(name: []char): bool
- do @snippets.head()
- while(!@snippets.term())
- if(@snippets.get().name = name)
- ret false
- end if
- do @snippets.next()
- end while
- ret true
- end func
end func
-+func updateList(list_: wnd@List)
++func updateList(list_: wnd@ListView)
do @snippets.head()
while(!@snippets.term())
var snippet: @Snippet :: @snippets.get()
- do list_.add((snippet.removable ?("\\", "")) ~ snippet.name)
+ do list_.add((snippet.removable ?("\\", "")) ~ snippet.name, -1)
do @snippets.next()
end while
end func
-+func getCode(name: []char): []char
- if(^name >= 1 & name[0] = '\\')
- do name :: name.sub(1, -1)
+func findSelSnippet(): @Snippet
+ var sel: int :: @wndSnippetListSnippets.getSel()
+ if (sel = -1)
+ ret null
end if
- var snippet: @Snippet :: null
+ var name: []char :: @wndSnippetListSnippets.getText(&, sel, 0)
do @snippets.head()
- while loop(!@snippets.term())
- var item: @Snippet :: @snippets.get()
- if(item.name = name)
- do snippet :: item
- break loop
+ while(!@snippets.term())
+ var snippet: @Snippet :: @snippets.get()
+ if(snippet.removable & snippet.name = name)
+ ret snippet
end if
do @snippets.next()
end while
- if(snippet =& null)
- ret null
+ ret null
+end func
+
+func validate(name: []char): bool
+ if(name.trim() = "")
+ ret false
end if
- var result: wnd@MsgBoxResult :: wnd@msgBox(\form@wndMain, (\common@langEn ?("Insert the following code?", "以下のコードを挿入しますか?")) ~ "\n\n" ~ snippet.name ~ "\n\n" ~ snippet.code, \common@title, %question, %yesNoCancel)
- switch(result)
- case %yes
- ret snippet.code
- case %no
- if(!snippet.removable)
- ret null
- end if
- do result :: wnd@msgBox(\form@wndMain, (\common@langEn ?("Delete [\{snippet.name}] snippet?", "スニペット[\{snippet.name}]を削除しますか?")), \common@title, %question, %yesNoCancel)
- if(result = %yes)
- do @snippets.head()
- while loop(!@snippets.term())
- if(@snippets.get().name = name)
- do @snippets.del()
- skip loop
- end if
- do @snippets.next()
- end while
- do @save()
+ do @snippets.head()
+ while(!@snippets.term())
+ var snippet: @Snippet :: @snippets.get()
+ if(snippet.removable & snippet.name = name)
+ ret false
end if
- ret null
- case %cancel
- ret null
- end switch
+ do @snippets.next()
+ end while
+ ret true
end func
diff --git a/src/kuin_editor/src.kn b/src/kuin_editor/src.kn
index 4eb82a18..2b4b0074 100644
--- a/src/kuin_editor/src.kn
+++ b/src/kuin_editor/src.kn
@@ -1,11 +1,12 @@
+var docs: dict<[]char, \doc@Doc>
+var curDoc: \doc@Doc
-+var curDocInternalName: []char
-+var mainSrcName: []char
++var curDocName: []char
++var mainSrcPath: []char
+var mainSrcDir: []char
+var sysDir: []char
var runningFiles: list<[]char>
var errList: dict<@Pos, []char>
++var breakPos: @Pos
+class Pos()
+var src: []char
@@ -28,23 +29,29 @@ end class
+func init()
do @sysDir :: file@exeDir() ~ "sys/"
do @runningFiles :: #list<[]char>
+ do @breakPos :: null
end func
+func fin()
do @clearDocs()
end func
+func updateMainSrcDir(dir: []char)
+ do @mainSrcDir :: dir
+ do \doc_ar_2d@updateMainSrcDir(dir)
+end func
+
+func newMainSrc()
var doc: \doc_src@DocSrc :: #\doc_src@DocSrc
do @curDoc :: doc
- do @mainSrcName :: \common@untitledSrcName
- do @mainSrcDir :: ""
- do @curDocInternalName :: \common@untitledInternalName
+ do @mainSrcPath :: \common@defaultDir ~ "main.kn"
+ do @updateMainSrcDir(\common@defaultDir)
+ do @curDocName :: "\\main"
do @clearDocs()
do @docs :: #dict<[]char, \doc@Doc>
- do @docs.add(@mainSrcName, @curDoc)
+ do @docs.add("\\main", @curDoc)
do @initMainSrc()
- do @curDoc.update()
+ do @curDoc.fix()
do \form@updateUi()
end func
@@ -61,15 +68,15 @@ end func
ret
end if
do @curDoc :: doc
- do @mainSrcName :: path
- do @mainSrcDir :: file@dir(path)
- do @curDocInternalName :: @srcNameToInternalName(@mainSrcName)
+ do @mainSrcPath :: path
+ do @updateMainSrcDir(file@dir(path))
+ do @curDocName :: "\\" ~ file@delExt(file@fileName(path))
do @clearDocs()
do @docs :: #dict<[]char, \doc@Doc>
- do @docs.add(@mainSrcName, @curDoc)
+ do @docs.add("\\" ~ file@delExt(file@fileName(path)), @curDoc)
do \prop@load()
do @initMainSrc()
- do @curDoc.update()
+ do @curDoc.fix()
do \form@updateUi()
end func
@@ -77,91 +84,94 @@ func initMainSrc()
do \completion@close()
do @resetErrList()
do \form@updateUi()
- do \form@setEditIconDirectly("")
do \form@paintDrawEditor()
do \form@focusDrawEditor()
end func
-+func saveMainSrc(): bool
- var file: []char :: wnd@saveFileDialog(\form@wndMain, [\common@langEn ?("Kuin source code (*.kn)", "Kuinソースコード (*.kn)"), "*.kn"], 0, "kn")
- if(file =& null)
- ret false
- end if
- if(!@saveImpl(file, @curDoc))
- ret false
- end if
- do @mainSrcName :: file
- do @mainSrcDir :: file@dir(file)
- do @curDocInternalName :: @srcNameToInternalName(@mainSrcName)
- do \prop@save()
- var newDocs: dict<[]char, \doc@Doc> :: #dict<[]char, \doc@Doc>
-
- class DocsClass()
- +var docs: dict<[]char, \doc@Doc>
- end class
-
- var data: DocsClass :: #DocsClass
- do data.docs :: newDocs
- do @docs.forEach(callback, data)
- do newDocs.add(file, @curDoc)
- do @docs :: newDocs
- do @curDoc.changed :: false
- do \form@updateFile()
- ret true
-
- func callback(src: []char, doc: \doc@Doc, data: DocsClass): bool
- if(doc <>& @curDoc)
- do data.docs.add(src, doc)
- end if
- ret true
- end func
-end func
-
-+func saveAll(): bool
- if(@mainSrcName = \common@untitledSrcName)
- if(!@saveMainSrc())
++func save(saveAs: bool): bool
+ if(@mainSrcDir = \common@defaultDir | saveAs)
+ if(!saveMainSrc())
ret false
end if
- else
- do \prop@save()
end if
+ do \prop@save()
var saveAllSuccess: lib@Bool :: #lib@Bool
do saveAllSuccess.value :: true
- do @docs.forEach(callback, saveAllSuccess)
+ do @docs.forEach(saveAllCallback, saveAllSuccess)
do \form@updateFile()
ret saveAllSuccess.value
- func callback(src: []char, doc: \doc@Doc, saveAllSuccess: lib@Bool): bool
- if(doc.changed)
- if(@saveImpl(src, doc))
- do doc.changed :: false
+ func saveAllCallback(src: []char, doc: \doc@Doc, saveAllSuccess: lib@Bool): bool
+ if(doc.getChanged() & src[0] = '\\')
+ var path: []char :: @mainSrcDir ~ src.sub(1, -1).replace("\\", "/") ~ @getExt(doc)
+ if(!file@exist(file@dir(path)))
+ do file@makeDir(file@dir(path))
+ end if
+ if(doc.save(path))
+ do doc.setChanged(false)
else
+ var msg: []char
+ if(\common@langEn)
+ do msg :: "Saving failed. " ~ path
+ else
+ do msg :: "保存に失敗しました。 " ~ path
+ end if
+ do wnd@msgBox(\form@wndMain, msg, \common@title, %err, %ok)
do saveAllSuccess.value :: false
end if
end if
ret true
end func
-end func
-+func saveImpl(path: []char, doc: \doc@Doc): bool
- if(doc.save(path))
+ func saveMainSrc(): bool
+ var file: []char :: wnd@saveFileDialog(\form@wndMain, [\common@langEn ?("Kuin source code (*.kn)", "Kuinソースコード (*.kn)"), "*.kn"], 0, "kn")
+ if(file =& null)
+ ret false
+ end if
+ var fileName: []char :: "\\" ~ file@delExt(file@fileName(file))
+ if(fileName <> "\\" ~ file@delExt(file@fileName(@mainSrcPath)) & @docs.exist(fileName))
+ do wnd@msgBox(\form@wndMain, \common@langEn ?("The file name is already existed.", "そのファイル名は既に存在します。"), \common@title, %err, %ok)
+ ret false
+ end if
+ var newDocs: dict<[]char, \doc@Doc> :: #dict<[]char, \doc@Doc>
+
+ class DocsClass()
+ +var docs: dict<[]char, \doc@Doc>
+ +var oldMainSrcName: []char
+ +var newMainSrcName: []char
+ end class
+
+ var data: DocsClass :: #DocsClass
+ do data.docs :: newDocs
+ do data.oldMainSrcName :: "\\" ~ file@delExt(file@fileName(@mainSrcPath))
+ do data.newMainSrcName :: fileName
+ do @mainSrcPath :: file
+ do @updateMainSrcDir(file@dir(file))
+ do @curDocName :: fileName
+ do @docs.forEach(callback, data)
+ do @docs :: newDocs
+ do \recent@save(file)
ret true
- end if
- var msg: []char
- if(\common@langEn)
- do msg :: "Saving failed. " ~ path
- else
- do msg :: "保存に失敗しました。 " ~ path
- end if
- do wnd@msgBox(\form@wndMain, msg, \common@title, %err, %ok)
- ret false
+
+ func callback(src: []char, doc: \doc@Doc, data: DocsClass): bool
+ if(src[0] <> '\\')
+ ret true
+ end if
+ if(src = data.oldMainSrcName)
+ do src :: data.newMainSrcName
+ end if
+ do doc.setChanged(true)
+ do data.docs.add(src, doc)
+ ret true
+ end func
+ end func
end func
+func setCurSrc(doc: \doc@Doc)
do \completion@close()
do @curDoc :: doc
- do @curDocInternalName :: @srcNameToInternalName(@getDocName(doc))
- do @curDoc.update()
+ do @curDocName :: @getDocName(doc)
+ do @curDoc.fix()
do \form@paintDrawEditor()
do \form@focusDrawEditor()
do \form@updateUi()
@@ -170,13 +180,15 @@ end func
+func mainDoc(): \doc@Doc
class RefDoc()
+var value: \doc@Doc
+ +var mainSrcName: []char
end class
var doc: RefDoc :: #RefDoc
+ do doc.mainSrcName :: "\\" ~ file@delExt(file@fileName(@mainSrcPath))
do @docs.forEach(callback, doc)
ret doc.value
func callback(src: []char, doc: \doc@Doc, data: RefDoc): bool
- if(src = @mainSrcName)
+ if(src = data.mainSrcName)
do data.value :: doc
ret false
end if
@@ -203,10 +215,10 @@ end func
elif(result = %no)
ret true
end if
- ret @saveAll()
+ ret @save(false)
func callback(src: []char, doc: \doc@Doc, chkCloseChanged: lib@Bool): bool
- if(doc.changed)
+ if(src[0] = '\\' & doc.getChanged())
do chkCloseChanged.value :: true
ret false
end if
@@ -216,52 +228,63 @@ end func
+func getSrc(path: []char): [][]char
; This function is called by the Kuin compiler.
- var path2: []char :: (##path).replace("\\", "/")
- var doc: \doc@Doc :: @docs.get(path2)
+ var path2: []char
+ if(^@mainSrcDir <= ^path & @mainSrcDir = path.sub(0, ^@mainSrcDir))
+ do path2 :: "\\" ~ file@delExt(path.sub(^@mainSrcDir, -1)).replace("/", "\\")
+ elif(^@sysDir <= ^path & @sysDir = path.sub(0, ^@sysDir))
+ do path2 :: file@delExt(path.sub(^@sysDir, -1)).replace("/", "\\")
+ else
+ do path2 :: ##path
+ end if
+ var doc: \doc@Doc :: @docs.get(path2, &)
if(doc <>& null)
- var doc2: \doc_src@DocSrc :: doc $ \doc_src@DocSrc
- ret doc2.getSrc()
+ ret doc.getSrc()
end if
- block
- var doc2: \doc_src@DocSrc :: #\doc_src@DocSrc
- if(@loadFileToDocs(path2, doc2))
- ret doc2.getSrc()
- end if
- end block
+ do doc :: @loadFileToDocs(##path)
+ if(doc <>& null)
+ ret doc.getSrc()
+ end if
ret null
end func
-+func makeDoc(path: []char): \doc@Doc
++func loadFileToDocs(path: []char): \doc@Doc
+ do path :: file@fullPath(path)
+ var doc: \doc@Doc
switch(file@ext(path).lower())
- case "kn"
- ret #\doc_src@DocSrc
- case "knwnd"
- ret #\doc_ar_wnd@DocArWnd
+ case "kn", "knp"
+ do doc :: #\doc_src@DocSrc
+ case "kngen"
+ do doc :: #\doc_gen@DocGen
+ default
+ ret null
end switch
- ret null
-end func
-
-+func loadFileToDocs(path: []char, doc: \doc@Doc): bool
- if(!(^@sysDir <= ^path & @sysDir = path.sub(0, ^@sysDir) | @mainSrcDir <> "" & ^@mainSrcDir <= ^path & @mainSrcDir = path.sub(0, ^@mainSrcDir)))
- ret false
- end if
- if(!doc.load(path))
- ret false
+ var name: []char
+ if(^@sysDir <= ^path & @sysDir = path.sub(0, ^@sysDir))
+ if(!doc.load(path))
+ ret null
+ end if
+ do name :: file@delExt(path.sub(^@sysDir, -1)).replace("/", "\\")
+ elif(@mainSrcDir = \common@defaultDir | !(^@mainSrcDir <= ^path & @mainSrcDir = path.sub(0, ^@mainSrcDir)))
+ ret null
+ else
+ if(!doc.load(path))
+ ret null
+ end if
+ do name :: "\\" ~ file@delExt(path.sub(^@mainSrcDir, -1)).replace("/", "\\")
end if
- do @docs.add(path, doc)
- ret true
+ do @docs.add(name, doc)
+ ret doc
end func
+func jumpSrc(pos: @Pos): bool
if(pos =& null | pos.src =& null | ^pos.src = 0 | pos.src[0] <> '\\')
ret false
end if
- var src: []char :: @internalNameToSrcName(pos.src)
- if(src =& null)
+ if(pos.src =& null)
ret false
end if
- var doc: \doc@Doc :: @docs.get(src)
+ var doc: \doc@Doc :: @docs.get(pos.src, &)
if(doc =& null)
ret false
end if
@@ -269,8 +292,8 @@ end func
if(doc <>& @curDoc)
var sel: int :: -1
for i(0, \form@listFile.len() - 1)
- var internalName: []char :: @removePrefix(\form@listFile.getText(i))
- if(internalName = pos.src)
+ var name: []char :: @removePrefix(\form@listFile.getText(i))
+ if(name = pos.src)
do sel :: i
break i
end if
@@ -306,38 +329,6 @@ end func
end if
end func
-+func srcNameToInternalName(srcName: []char): []char
- if(^@sysDir <= ^srcName & @sysDir = srcName.sub(0, ^@sysDir))
- ret file@delExt(srcName.sub(^@sysDir, -1)).replace("/", "\\")
- elif(@mainSrcDir <> "" & ^@mainSrcDir <= ^srcName & @mainSrcDir = srcName.sub(0, ^@mainSrcDir) | @mainSrcDir = "" & srcName = \common@untitledSrcName)
- var name: []char :: srcName.sub(^@mainSrcDir, -1)
- if(file@ext(name).lower() = "kn")
- ret "\\" ~ file@delExt(name).replace("/", "\\")
- else
- ret "!" ~ name.replace("/", "\\")
- end if
- else
- ret "?" ~ srcName
- end if
-end func
-
-+func internalNameToSrcName(internalName: []char): []char
- if(internalName = \common@untitledInternalName)
- ret \common@untitledSrcName
- end if
- if(^internalName > 1)
- switch(internalName[0])
- case '\\'
- ret @mainSrcDir ~ internalName.sub(1, -1).replace("\\", "/") ~ ".kn"
- case '!'
- ret @mainSrcDir ~ internalName.sub(1, -1).replace("\\", "/")
- case '?'
- ret internalName.sub(1, -1)
- end switch
- end if
- ret @sysDir ~ internalName.replace("\\", "/") ~ ".kn"
-end func
-
+func getDocName(doc: \doc@Doc): []char
class GetDocNameClass()
+var src: []char
@@ -400,11 +391,10 @@ end func
do doc_src.addListInfoItem(listInfoItem)
; Fill in words with the error color.
- var srcName: []char :: @internalNameToSrcName(pos.src)
- if(srcName =& null)
+ if(pos.src =& null)
ret true
end if
- var doc: \doc@Doc :: @docs.get(srcName)
+ var doc: \doc@Doc :: @docs.get(pos.src, &)
if(doc <>& null & doc =$ \doc_src@DocSrc)
var doc2: \doc_src@DocSrc :: doc $ \doc_src@DocSrc
var x: int :: pos.col - 1
@@ -446,6 +436,9 @@ end func
end func
+func addErrList(pos: @Pos, code: []char, msg: []char, src: []char, row: int, col: int)
+ if(^code >= 1 & code[0] = 'I')
+ ret
+ end if
if(!@errList.exist(pos))
do @errList.add(pos, errStr(code, msg, src, row, col))
end if
@@ -466,3 +459,13 @@ func clearDocs()
ret true
end func
end func
+
++func getExt(doc: \doc@Doc): []char
+ if(doc =$ \doc_src@DocSrc)
+ ret ".kn"
+ end if
+ if(doc =$ \doc_gen@DocGen)
+ ret ".kngen"
+ end if
+ ret ""
+end func
diff --git a/src/kuincl/kuincl.vcxproj b/src/kuincl/kuincl.vcxproj
index 1224dd8b..4b31014e 100644
--- a/src/kuincl/kuincl.vcxproj
+++ b/src/kuincl/kuincl.vcxproj
@@ -86,9 +86,10 @@
echo F | xcopy /y /r $(TargetPath) $(SolutionDir)package\kuincl.exe
-$(SolutionDir)package\kuincl.exe -i $(SolutionDir)src\kuin_editor\kuin_editor.kn -o $(SolutionDir)package\kuin.exe -r -d
+$(SolutionDir)package\kuincl.exe -i $(SolutionDir)src\kuin_editor\kuin_editor.kn -o $(SolutionDir)package\kuin.exe -r -d -a 917
echo F | xcopy /y /r $(SolutionDir)package\sys\rls\d0000.knd $(SolutionDir)package\data\d0000.knd
echo F | xcopy /y /r $(SolutionDir)package\sys\rls\d0001.knd $(SolutionDir)package\data\d0001.knd
+echo F | xcopy /y /r $(SolutionDir)package\sys\rls\d0005.knd $(SolutionDir)package\data\d0005.knd
echo F | xcopy /y /r $(SolutionDir)package\sys\rls\d1001.knd $(SolutionDir)package\data\d1001.knd
echo F | xcopy /y /r $(SolutionDir)package\sys\rls\d1002.knd $(SolutionDir)package\data\d1002.knd
echo F | xcopy /y /r $(SolutionDir)package\sys\rls\d1003.knd $(SolutionDir)package\data\d1003.knd
diff --git a/src/kuincl/main.c b/src/kuincl/main.c
index 5123636f..a641c7d1 100644
--- a/src/kuincl/main.c
+++ b/src/kuincl/main.c
@@ -8,9 +8,10 @@
#include
#include
+// 0 = 'Ja', 1 = 'En'.
#define LANG (0)
-typedef Bool(*TypeOfBuild)(const Char* path, const Char* sys_dir, const Char* output, const Char* icon, Bool rls, const Char* env, void(*func_log)(const Char* code, const Char* msg, const Char* src, int row, int col), S64 lang, S64 app_code, Bool not_deploy);
+typedef Bool(*TypeOfBuild)(const Char* path, const Char* sys_dir, const Char* output, const Char* icon, const void* related_files, Bool rls, const Char* env, void(*func_log)(const Char* code, const Char* msg, const Char* src, int row, int col), S64 lang, S64 app_code, Bool not_deploy);
typedef void(*TypeOfVersion)(int* major, int* minor, int* micro);
typedef void(*TypeOfInitCompiler)(S64 mem_num, S64 lang);
typedef void(*TypeOfFinCompiler)(void);
@@ -27,6 +28,7 @@ int wmain(int argc, Char** argv)
const Char* output = NULL;
const Char* sys_dir = NULL;
const Char* icon = NULL;
+ const void* related_files = NULL; // TODO: How to set.
Bool rls = False;
const Char* env = NULL;
Bool help = False;
@@ -133,6 +135,7 @@ int wmain(int argc, Char** argv)
Char* end_ptr;
errno = 0;
app_code = wcstol(argv[i + 1], &end_ptr, 10);
+ i++;
if (*end_ptr != L'\0' || errno == ERANGE || app_code == 0)
{
wprintf(L"The option '-a' was used incorrectly.\n");
@@ -140,7 +143,7 @@ int wmain(int argc, Char** argv)
}
}
break;
- case L'd':
+ case L'd': // This option is only used in Kuin Editor builds.
if (not_deploy != False)
{
wprintf(L"The option '-d' was used incorrectly.\n");
@@ -191,16 +194,20 @@ int wmain(int argc, Char** argv)
wprintf(L"Usage: kuincl [-i input.kn] [-o output.kn] [-s 'sys' directory] [-c icon.ico] [-e environment] [-a appcode] [-r] [-h] [-v] [-q]\n");
return 0;
}
- if (func_build(input, sys_dir, output, icon, rls, env, Log, LANG, app_code, not_deploy))
+ if (func_build(input, sys_dir, output, icon, related_files, rls, env, Log, LANG, app_code, not_deploy))
{
if (rls)
{
U8* res_output = GetDir(output == NULL ? input : output, False, L"res.knd");
U8* res_src = GetDir(input, False, L"res/");
- func_init_compiler(1, -1);
- if (!func_archive(res_output, res_src, app_code))
- ret_code = 1;
- func_fin_compiler();
+ if (PathFileExists((Char*)(res_src + 0x10)) != 0)
+ {
+ func_init_compiler(1, -1);
+ if (!func_archive(res_output, res_src, app_code))
+ ret_code = 1;
+ func_fin_compiler();
+ }
+ free(res_src);
free(res_output);
}
}
diff --git a/src/lib_boost/lib_boost.sln b/src/lib_boost/lib_boost.sln
deleted file mode 100644
index a93f7ed4..00000000
--- a/src/lib_boost/lib_boost.sln
+++ /dev/null
@@ -1,25 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.25123.0
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_boost", "lib_boost.vcxproj", "{CBFC1A36-CC6C-487E-B3D4-4E1351D4141A}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|x64 = Debug|x64
- Release_dbg|x64 = Release_dbg|x64
- Release_rls|x64 = Release_rls|x64
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {CBFC1A36-CC6C-487E-B3D4-4E1351D4141A}.Debug|x64.ActiveCfg = Debug|x64
- {CBFC1A36-CC6C-487E-B3D4-4E1351D4141A}.Debug|x64.Build.0 = Debug|x64
- {CBFC1A36-CC6C-487E-B3D4-4E1351D4141A}.Release_dbg|x64.ActiveCfg = Release_dbg|x64
- {CBFC1A36-CC6C-487E-B3D4-4E1351D4141A}.Release_dbg|x64.Build.0 = Release_dbg|x64
- {CBFC1A36-CC6C-487E-B3D4-4E1351D4141A}.Release_rls|x64.ActiveCfg = Release_rls|x64
- {CBFC1A36-CC6C-487E-B3D4-4E1351D4141A}.Release_rls|x64.Build.0 = Release_rls|x64
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/src/lib_common/cipher.c b/src/lib_common/cipher.c
index 8c466769..bf9ea269 100644
--- a/src/lib_common/cipher.c
+++ b/src/lib_common/cipher.c
@@ -66,7 +66,7 @@ EXPORT void* _encrypt(const U8* data, const U8* key)
U32 w[60];
if (len2 % 16 != 0)
len2 += 16 - len2 % 16;
- THROWDBG(*(const S64*)(key + 0x08) != 32, 0xe9170006);
+ THROWDBG(*(const S64*)(key + 0x08) != 32, EXCPT_DBG_ARG_OUT_DOMAIN);
data2 = (U8*)AllocMem((size_t)len2);
result = (U8*)AllocMem(0x10 + (size_t)len2);
((S64*)result)[0] = DefaultRefCntFunc;
@@ -117,8 +117,8 @@ EXPORT void* _decrypt(const U8* data, const U8* key)
U8* data2;
U8* result;
U32 w[60];
- THROWDBG(len % 16 != 0, 0xe9170006);
- THROWDBG(*(const S64*)(key + 0x08) != 32, 0xe9170006);
+ THROWDBG(len % 16 != 0, EXCPT_DBG_ARG_OUT_DOMAIN);
+ THROWDBG(*(const S64*)(key + 0x08) != 32, EXCPT_DBG_ARG_OUT_DOMAIN);
data2 = (U8*)AllocMem(len);
result = (U8*)AllocMem(0x10 + len);
((S64*)result)[0] = DefaultRefCntFunc;
diff --git a/src/lib_common/dbg.c b/src/lib_common/dbg.c
index 8d8205e7..c3adccc4 100644
--- a/src/lib_common/dbg.c
+++ b/src/lib_common/dbg.c
@@ -1,27 +1,21 @@
#include "dbg.h"
-#if defined(DBG)
-static int DbgCode = 0;
-#endif
-
EXPORT void _dbgPrint(const U8* str)
{
#if defined(DBG)
if (str == NULL)
- OutputDebugString(L"(null)");
+ OutputDebugString(L"dbg!(null)");
else
{
S64 len = ((S64*)str)[1];
- Char* str2 = (Char*)malloc(sizeof(Char) * (5 + len + 1));
+ Char* str2 = (Char*)malloc(sizeof(Char) * (4 + len + 1));
str2[0] = L'd';
str2[1] = L'b';
str2[2] = L'g';
- str2[3] = (Char)(L'0' + DbgCode);
- str2[4] = L'!';
- memcpy(&str2[5], str + 0x10, sizeof(Char) * (len + 1));
+ str2[3] = L'!';
+ memcpy(&str2[4], str + 0x10, sizeof(Char) * (len + 1));
OutputDebugString(str2);
free(str2);
- DbgCode = (DbgCode + 1) % 10;
}
#else
UNUSED(str);
diff --git a/src/lib_common/file.c b/src/lib_common/file.c
index 64ca0526..605b2f8e 100644
--- a/src/lib_common/file.c
+++ b/src/lib_common/file.c
@@ -1,23 +1,30 @@
#include "file.h"
-typedef struct SStream
+typedef struct SReader
{
SClass Class;
- FILE* Handle;
+ void* Handle;
S64 DelimiterNum;
Char* Delimiters;
S64 FileSize;
-} SStream;
+} SReader;
+
+typedef struct SWriter
+{
+ SClass Class;
+ FILE* Handle;
+} SWriter;
static const U8 Newline[2] = { 0x0d, 0x0a };
-static Char ReadUtf8(SStream* me_, Bool replace_delimiter, int* char_cnt);
-static void WriteUtf8(SStream* me_, Char data);
+static Char ReadUtf8(SReader* me_, Bool replace_delimiter, int* char_cnt);
+static void WriteUtf8(SWriter* me_, Char data);
static void NormPath(Char* path, Bool dir);
static void NormPathBackSlash(Char* path, Bool dir);
static Bool ForEachDirRecursion(const Char* path, Bool recursion, void* callback, void* data);
static Bool DelDirRecursion(const Char* path);
static Bool CopyDirRecursion(const Char* dst, const Char* src);
+static void SkipLastChars(SReader* reader);
void* Call0Asm(void* func);
void* Call1Asm(void* arg1, void* func);
@@ -26,53 +33,50 @@ void* Call3Asm(void* arg1, void* arg2, void* arg3, void* func);
EXPORT SClass* _makeReader(SClass* me_, const U8* path)
{
- THROWDBG(path == NULL, 0xc0000005);
- SStream* me2 = (SStream*)me_;
- FILE* file_ptr = _wfopen((Char*)(path + 0x10), L"rb");
- if (file_ptr == NULL)
+ THROWDBG(path == NULL, EXCPT_ACCESS_VIOLATION);
+ SReader* me2 = (SReader*)me_;
+ me2->Handle = OpenFileStream((Char*)(path + 0x10));
+ if (me2->Handle == NULL)
return NULL;
- me2->Handle = file_ptr;
- me2->DelimiterNum = 2;
- me2->Delimiters = (Char*)AllocMem(sizeof(Char) * 2);
- me2->Delimiters[0] = L' ';
- me2->Delimiters[1] = L',';
+ me2->DelimiterNum = 3;
+ me2->Delimiters = (Char*)AllocMem(sizeof(Char) * 3);
+ me2->Delimiters[0] = L'\n';
+ me2->Delimiters[1] = L' ';
+ me2->Delimiters[2] = L',';
{
- _fseeki64(me2->Handle, 0, SEEK_END);
- me2->FileSize = _ftelli64(me2->Handle);
- _fseeki64(me2->Handle, 0, SEEK_SET);
+ SeekFileStream(me2->Handle, 0, SEEK_END);
+ me2->FileSize = TellFileStream(me2->Handle);
+ SeekFileStream(me2->Handle, 0, SEEK_SET);
}
return me_;
}
EXPORT SClass* _makeWriter(SClass* me_, const U8* path, Bool append)
{
- THROWDBG(path == NULL, 0xc0000005);
- SStream* me2 = (SStream*)me_;
+ THROWDBG(path == NULL, EXCPT_ACCESS_VIOLATION);
+ SWriter* me2 = (SWriter*)me_;
FILE* file_ptr = _wfopen((Char*)(path + 0x10), append ? L"ab" : L"wb");
if (file_ptr == NULL)
return NULL;
me2->Handle = file_ptr;
- me2->DelimiterNum = 0;
- me2->Delimiters = NULL;
- me2->FileSize = 0;
return me_;
}
-EXPORT void _streamDtor(SClass* me_)
+EXPORT void _readerDtor(SClass* me_)
{
- SStream* me2 = (SStream*)me_;
+ SReader* me2 = (SReader*)me_;
if (me2->Handle != NULL)
- fclose(me2->Handle);
+ CloseFileStream(me2->Handle);
if (me2->Delimiters != NULL)
FreeMem(me2->Delimiters);
}
-EXPORT void _streamFin(SClass* me_)
+EXPORT void _readerFin(SClass* me_)
{
- SStream* me2 = (SStream*)me_;
+ SReader* me2 = (SReader*)me_;
if (me2->Handle == NULL)
return;
- fclose(me2->Handle);
+ CloseFileStream(me2->Handle);
me2->Handle = NULL;
if (me2->Delimiters != NULL)
{
@@ -81,27 +85,27 @@ EXPORT void _streamFin(SClass* me_)
}
}
-EXPORT void _streamSetPos(SClass* me_, S64 origin, S64 pos)
+EXPORT void _readerSetPos(SClass* me_, S64 origin, S64 pos)
{
- THROWDBG(origin < 0 || 2 < origin, 0xe9170006);
- SStream* me2 = (SStream*)me_;
- THROWDBG(me2->Handle == NULL, 0xe917000a);
- if (_fseeki64(me2->Handle, pos, (int)origin))
- THROW(0xe9170008);
+ THROWDBG(origin < 0 || 2 < origin, EXCPT_DBG_ARG_OUT_DOMAIN);
+ SReader* me2 = (SReader*)me_;
+ THROWDBG(me2->Handle == NULL, EXCPT_DBG_INOPERABLE_STATE);
+ if (!SeekFileStream(me2->Handle, pos, origin))
+ THROW(EXCPT_INVALID_DATA_FMT);
}
-EXPORT S64 _streamGetPos(SClass* me_)
+EXPORT S64 _readerGetPos(SClass* me_)
{
- SStream* me2 = (SStream*)me_;
- THROWDBG(me2->Handle == NULL, 0xe917000a);
- return _ftelli64(me2->Handle);
+ SReader* me2 = (SReader*)me_;
+ THROWDBG(me2->Handle == NULL, EXCPT_DBG_INOPERABLE_STATE);
+ return TellFileStream(me2->Handle);
}
-EXPORT void _streamDelimiter(SClass* me_, const U8* delimiters)
+EXPORT void _readerDelimiter(SClass* me_, const U8* delimiters)
{
- SStream* me2 = (SStream*)me_;
- THROWDBG(me2->Handle == NULL, 0xe917000a);
- THROWDBG(delimiters == NULL, 0xc0000005);
+ SReader* me2 = (SReader*)me_;
+ THROWDBG(me2->Handle == NULL, EXCPT_DBG_INOPERABLE_STATE);
+ THROWDBG(delimiters == NULL, EXCPT_ACCESS_VIOLATION);
S64 len = *(S64*)(delimiters + 0x08);
S64 i;
const Char* ptr = (const Char*)(delimiters + 0x10);
@@ -112,48 +116,48 @@ EXPORT void _streamDelimiter(SClass* me_, const U8* delimiters)
me2->Delimiters[i] = ptr[i];
}
-EXPORT void* _streamRead(SClass* me_, S64 size)
+EXPORT void* _readerRead(SClass* me_, S64 size)
{
- SStream* me2 = (SStream*)me_;
- THROWDBG(me2->Handle == NULL, 0xe917000a);
+ SReader* me2 = (SReader*)me_;
+ THROWDBG(me2->Handle == NULL, EXCPT_DBG_INOPERABLE_STATE);
{
U8* result = (U8*)AllocMem(0x10 + (size_t)size);
size_t size2;
((S64*)result)[0] = DefaultRefCntFunc;
((S64*)result)[1] = size;
- size2 = fread(result + 0x10, 1, (size_t)size, me2->Handle);
+ size2 = ReadFileStream(me2->Handle, (size_t)size, result + 0x10);
if (size2 != (size_t)size)
{
FreeMem(result);
- THROW(0xe9170008);
+ THROW(EXCPT_INVALID_DATA_FMT);
return NULL;
}
return result;
}
}
-EXPORT Char _streamReadLetter(SClass* me_)
+EXPORT Char _readerReadLetter(SClass* me_)
{
- Char result = ReadUtf8((SStream*)me_, False, NULL);
+ Char result = ReadUtf8((SReader*)me_, False, NULL);
if (result == WEOF)
- THROW(0xe9170008);
+ THROW(EXCPT_INVALID_DATA_FMT);
return result;
}
-EXPORT S64 _streamReadInt(SClass* me_)
+EXPORT S64 _readerReadInt(SClass* me_)
{
Char buf[33];
int ptr = 0;
buf[0] = L'\0';
for (; ; )
{
- Char c = ReadUtf8((SStream*)me_, True, NULL);
+ Char c = ReadUtf8((SReader*)me_, True, NULL);
if (c == L'\r')
continue;
if (c == WEOF)
{
if (buf[0] == L'\0')
- THROW(0xe9170008);
+ THROW(EXCPT_INVALID_DATA_FMT);
break;
}
if (c == L'\0')
@@ -163,49 +167,36 @@ EXPORT S64 _streamReadInt(SClass* me_)
break;
}
if (ptr == 32)
- THROW(0xe9170008);
+ THROW(EXCPT_INVALID_DATA_FMT);
buf[ptr] = c;
ptr++;
}
- for (; ; )
- {
- int char_len;
- Char c = ReadUtf8((SStream*)me_, True, &char_len);
- if (c == L'\r')
- continue;
- if (c == WEOF)
- break;
- if (c != L'\0')
- {
- _fseeki64(((SStream*)me_)->Handle, (S64)-char_len, SEEK_CUR);
- break;
- }
- }
+ SkipLastChars((SReader*)me_);
buf[ptr] = L'\0';
{
S64 result;
Char* ptr2;
result = wcstoll(buf, &ptr2, 10);
if (*ptr2 != L'\0')
- THROW(0xe9170008);
+ THROW(EXCPT_INVALID_DATA_FMT);
return result;
}
}
-EXPORT double _streamReadFloat(SClass* me_)
+EXPORT double _readerReadFloat(SClass* me_)
{
Char buf[33];
int ptr = 0;
buf[0] = L'\0';
for (; ; )
{
- Char c = ReadUtf8((SStream*)me_, True, NULL);
+ Char c = ReadUtf8((SReader*)me_, True, NULL);
if (c == L'\r')
continue;
if (c == WEOF)
{
if (buf[0] == L'\0')
- THROW(0xe9170008);
+ THROW(EXCPT_INVALID_DATA_FMT);
break;
}
if (c == L'\0')
@@ -215,79 +206,55 @@ EXPORT double _streamReadFloat(SClass* me_)
break;
}
if (ptr == 32)
- THROW(0xe9170008);
+ THROW(EXCPT_INVALID_DATA_FMT);
buf[ptr] = c;
ptr++;
}
- for (; ; )
- {
- int char_len;
- Char c = ReadUtf8((SStream*)me_, True, &char_len);
- if (c == L'\r')
- continue;
- if (c == WEOF)
- break;
- if (c != L'\0')
- {
- _fseeki64(((SStream*)me_)->Handle, (S64)-char_len, SEEK_CUR);
- break;
- }
- }
+ SkipLastChars((SReader*)me_);
buf[ptr] = L'\0';
{
double result;
Char* ptr2;
result = wcstod(buf, &ptr2);
if (*ptr2 != L'\0')
- THROW(0xe9170008);
+ THROW(EXCPT_INVALID_DATA_FMT);
return result;
}
}
-EXPORT Char _streamReadChar(SClass* me_)
+EXPORT Char _readerReadChar(SClass* me_)
{
Char c = L'\0';
for (; ; )
{
- c = ReadUtf8((SStream*)me_, True, NULL);
+ c = ReadUtf8((SReader*)me_, True, NULL);
if (c == L'\r')
continue;
if (c == WEOF)
- THROW(0xe9170008);
+ THROW(EXCPT_INVALID_DATA_FMT);
if (c != L'\0')
break;
}
- for (; ; )
- {
- int char_len;
- Char c2 = ReadUtf8((SStream*)me_, True, &char_len);
- if (c2 == L'\r')
- continue;
- if (c2 == WEOF)
- break;
- if (c2 != L'\0')
- {
- _fseeki64(((SStream*)me_)->Handle, (S64)-char_len, SEEK_CUR);
- break;
- }
- }
+ SkipLastChars((SReader*)me_);
return c;
}
-EXPORT void* _streamReadStr(SClass* me_)
+EXPORT void* _readerReadStr(SClass* me_)
{
- Char buf[1025];
- int ptr = 0;
+ Char stack_buf[STACK_STRING_BUF_SIZE];
+ Char* buf = stack_buf;
+ size_t buf_len = STACK_STRING_BUF_SIZE;
+ size_t len = 0;
buf[0] = L'\0';
for (; ; )
{
- Char c = ReadUtf8((SStream*)me_, True, NULL);
+ Char c = ReadUtf8((SReader*)me_, True, NULL);
if (c == L'\r')
continue;
if (c == WEOF)
{
if (buf[0] == L'\0')
- THROW(0xe9170008);
+ THROW(EXCPT_INVALID_DATA_FMT);
break;
}
if (c == L'\0')
@@ -296,83 +263,152 @@ EXPORT void* _streamReadStr(SClass* me_)
continue;
break;
}
- buf[ptr] = c;
- ptr++;
- if (ptr == 1024)
- break;
- }
- for (; ; )
- {
- int char_len;
- Char c = ReadUtf8((SStream*)me_, True, &char_len);
- if (c == L'\r')
- continue;
- if (c == WEOF)
- break;
- if (c != L'\0')
+ buf[len] = c;
+ len++;
+ if (len == buf_len)
{
- _fseeki64(((SStream*)me_)->Handle, (S64)-char_len, SEEK_CUR);
- break;
+ buf_len += STACK_STRING_BUF_SIZE;
+ Char* tmp = (Char*)ReAllocMem(buf == stack_buf ? NULL : buf, sizeof(Char) * buf_len);
+ if (tmp == NULL)
+ {
+ if (buf != stack_buf)
+ FreeMem(buf);
+ return NULL;
+ }
+ if (buf == stack_buf)
+ memcpy(tmp, buf, sizeof(Char) * len);
+ buf = tmp;
}
}
- buf[ptr] = L'\0';
+ buf[len] = L'\0';
+ SkipLastChars((SReader*)me_);
{
- U8* result = (U8*)AllocMem(0x10 + sizeof(Char) * ((size_t)ptr + 1));
+ U8* result = (U8*)AllocMem(0x10 + sizeof(Char) * ((size_t)len + 1));
*(S64*)(result + 0x00) = DefaultRefCntFunc;
- *(S64*)(result + 0x08) = (S64)ptr;
- wcscpy((Char*)(result + 0x10), buf);
+ *(S64*)(result + 0x08) = (S64)len;
+ memcpy(result + 0x10, buf, sizeof(Char) * (len + 1));
+ if (buf != stack_buf)
+ FreeMem(buf);
return result;
}
}
-EXPORT void* _streamReadLine(SClass* me_)
+EXPORT void* _readerReadLine(SClass* me_)
{
- Char buf[1025];
- int ptr = 0;
+ Char stack_buf[STACK_STRING_BUF_SIZE];
+ Char* buf = stack_buf;
+ size_t buf_len = STACK_STRING_BUF_SIZE;
+ size_t len = 0;
buf[0] = L'\0';
for (; ; )
{
- Char c = ReadUtf8((SStream*)me_, False, NULL);
+ Char c = ReadUtf8((SReader*)me_, False, NULL);
if (c == L'\r')
continue;
if (c == WEOF)
{
if (buf[0] == L'\0')
- THROW(0xe9170008);
+ THROW(EXCPT_INVALID_DATA_FMT);
break;
}
if (c == L'\n')
break;
- buf[ptr] = c;
- ptr++;
- if (ptr == 1024)
- break;
+ buf[len] = c;
+ len++;
+ if (len == buf_len)
+ {
+ buf_len += STACK_STRING_BUF_SIZE;
+ Char* tmp = (Char*)ReAllocMem(buf == stack_buf ? NULL : buf, sizeof(Char) * buf_len);
+ if (tmp == NULL)
+ {
+ if (buf != stack_buf)
+ FreeMem(buf);
+ return NULL;
+ }
+ if (buf == stack_buf)
+ memcpy(tmp, buf, sizeof(Char) * len);
+ buf = tmp;
+ }
}
- buf[ptr] = L'\0';
+ buf[len] = L'\0';
{
- U8* result = (U8*)AllocMem(0x10 + sizeof(Char) * ((size_t)ptr + 1));
+ U8* result = (U8*)AllocMem(0x10 + sizeof(Char) * ((size_t)len + 1));
*(S64*)(result + 0x00) = DefaultRefCntFunc;
- *(S64*)(result + 0x08) = (S64)ptr;
- wcscpy((Char*)(result + 0x10), buf);
+ *(S64*)(result + 0x08) = (S64)len;
+ memcpy(result + 0x10, buf, sizeof(Char) * (len + 1));
+ if (buf != stack_buf)
+ FreeMem(buf);
+ return result;
+ }
+}
+
+EXPORT S64 _readerFileSize(SClass* me_)
+{
+ SReader* me2 = (SReader*)me_;
+ THROWDBG(me2->Handle == NULL, EXCPT_DBG_INOPERABLE_STATE);
+ return me2->FileSize;
+}
+
+EXPORT Bool _readerTerm(SClass* me_)
+{
+ SReader* me2 = (SReader*)me_;
+ THROWDBG(me2->Handle == NULL, EXCPT_DBG_INOPERABLE_STATE);
+ {
+ U8 buf;
+ Bool result = ReadFileStream(me2->Handle, 1, &buf) == 0;
+ if (!result)
+ SeekFileStream(me2->Handle, -1, SEEK_CUR);
return result;
}
}
-EXPORT void _streamWrite(SClass* me_, void* bin)
+EXPORT void _writerDtor(SClass* me_)
+{
+ SWriter* me2 = (SWriter*)me_;
+ if (me2->Handle != NULL)
+ fclose(me2->Handle);
+}
+
+EXPORT void _writerFin(SClass* me_)
+{
+ SWriter* me2 = (SWriter*)me_;
+ if (me2->Handle == NULL)
+ return;
+ fclose(me2->Handle);
+ me2->Handle = NULL;
+}
+
+EXPORT void _writerSetPos(SClass* me_, S64 origin, S64 pos)
+{
+ THROWDBG(origin < 0 || 2 < origin, EXCPT_DBG_ARG_OUT_DOMAIN);
+ SWriter* me2 = (SWriter*)me_;
+ THROWDBG(me2->Handle == NULL, EXCPT_DBG_INOPERABLE_STATE);
+ if (_fseeki64(me2->Handle, pos, (int)origin))
+ THROW(EXCPT_INVALID_DATA_FMT);
+}
+
+EXPORT S64 _writerGetPos(SClass* me_)
{
- SStream* me2 = (SStream*)me_;
- THROWDBG(me2->Handle == NULL, 0xe917000a);
- THROWDBG(bin == NULL, 0xc0000005);
+ SWriter* me2 = (SWriter*)me_;
+ THROWDBG(me2->Handle == NULL, EXCPT_DBG_INOPERABLE_STATE);
+ return _ftelli64(me2->Handle);
+}
+
+EXPORT void _writerWrite(SClass* me_, void* bin)
+{
+ SWriter* me2 = (SWriter*)me_;
+ THROWDBG(me2->Handle == NULL, EXCPT_DBG_INOPERABLE_STATE);
+ THROWDBG(bin == NULL, EXCPT_ACCESS_VIOLATION);
{
U8* bin2 = (U8*)bin;
fwrite(bin2 + 0x10, 1, (size_t)*(S64*)(bin2 + 0x08), me2->Handle);
}
}
-EXPORT void _streamWriteInt(SClass* me_, S64 n)
+EXPORT void _writerWriteInt(SClass* me_, S64 n)
{
- SStream* me2 = (SStream*)me_;
- THROWDBG(me2->Handle == NULL, 0xe917000a);
+ SWriter* me2 = (SWriter*)me_;
+ THROWDBG(me2->Handle == NULL, EXCPT_DBG_INOPERABLE_STATE);
Char str[33];
int len = swprintf(str, 33, L"%I64d", n);
int i;
@@ -380,10 +416,10 @@ EXPORT void _streamWriteInt(SClass* me_, S64 n)
WriteUtf8(me2, str[i]);
}
-EXPORT void _streamWriteFloat(SClass* me_, double n)
+EXPORT void _writerWriteFloat(SClass* me_, double n)
{
- SStream* me2 = (SStream*)me_;
- THROWDBG(me2->Handle == NULL, 0xe917000a);
+ SWriter* me2 = (SWriter*)me_;
+ THROWDBG(me2->Handle == NULL, EXCPT_DBG_INOPERABLE_STATE);
Char str[33];
int len = swprintf(str, 33, L"%g", n);
int i;
@@ -391,18 +427,18 @@ EXPORT void _streamWriteFloat(SClass* me_, double n)
WriteUtf8(me2, str[i]);
}
-EXPORT void _streamWriteChar(SClass* me_, Char n)
+EXPORT void _writerWriteChar(SClass* me_, Char n)
{
- SStream* me2 = (SStream*)me_;
- THROWDBG(me2->Handle == NULL, 0xe917000a);
+ SWriter* me2 = (SWriter*)me_;
+ THROWDBG(me2->Handle == NULL, EXCPT_DBG_INOPERABLE_STATE);
WriteUtf8(me2, n);
}
-EXPORT void _streamWriteStr(SClass* me_, const U8* n)
+EXPORT void _writerWriteStr(SClass* me_, const U8* n)
{
- SStream* me2 = (SStream*)me_;
- THROWDBG(me2->Handle == NULL, 0xe917000a);
- THROWDBG(n == NULL, 0xc0000005);
+ SWriter* me2 = (SWriter*)me_;
+ THROWDBG(me2->Handle == NULL, EXCPT_DBG_INOPERABLE_STATE);
+ THROWDBG(n == NULL, EXCPT_ACCESS_VIOLATION);
const Char* ptr = (const Char*)(n + 0x10);
while (*ptr != L'\0')
{
@@ -411,61 +447,49 @@ EXPORT void _streamWriteStr(SClass* me_, const U8* n)
}
}
-EXPORT S64 _streamFileSize(SClass* me_)
-{
- SStream* me2 = (SStream*)me_;
- THROWDBG(me2->Handle == NULL, 0xe917000a);
- return me2->FileSize;
-}
-
-EXPORT Bool _streamTerm(SClass* me_)
+EXPORT void _writerFlush(SClass* me_)
{
- SStream* me2 = (SStream*)me_;
- THROWDBG(me2->Handle == NULL, 0xe917000a);
- {
- Bool result = fgetc(me2->Handle) == EOF;
- if (!result)
- _fseeki64(me2->Handle, -1, SEEK_CUR);
- return result;
- }
+ SWriter* me2 = (SWriter*)me_;
+ THROWDBG(me2->Handle == NULL, EXCPT_DBG_INOPERABLE_STATE);
+ fflush(me2->Handle);
}
EXPORT Bool _makeDir(const U8* path)
{
- THROWDBG(path == NULL, 0xc0000005);
- THROWDBG(*(S64*)(path + 0x08) > KUIN_MAX_PATH, 0xe9170006);
+ THROWDBG(path == NULL, EXCPT_ACCESS_VIOLATION);
+ THROWDBG(*(S64*)(path + 0x08) > KUIN_MAX_PATH, EXCPT_DBG_ARG_OUT_DOMAIN);
if (!DelDirRecursion((const Char*)(path + 0x10)))
return False;
{
- Char path2[KUIN_MAX_PATH + 2];
- wcscpy(path2, (const Char*)(path + 0x10));
- NormPathBackSlash(path2, True);
+ Char path2[KUIN_MAX_PATH + 1];
+ if (GetFullPathName((const Char*)(path + 0x10), KUIN_MAX_PATH, path2, NULL) == 0)
+ return False;
return SHCreateDirectory(NULL, path2) == ERROR_SUCCESS;
}
}
EXPORT Bool _forEachDir(const U8* path, Bool recursion, void* callback, void* data)
{
- THROWDBG(path == NULL, 0xc0000005);
- THROWDBG(callback == NULL, 0xc0000005);
+ THROWDBG(path == NULL, EXCPT_ACCESS_VIOLATION);
+ THROWDBG(callback == NULL, EXCPT_ACCESS_VIOLATION);
return ForEachDirRecursion((const Char*)(path + 0x10), recursion, callback, data);
}
EXPORT Bool _existPath(const U8* path)
{
- THROWDBG(path == NULL, 0xc0000005);
+ THROWDBG(path == NULL, EXCPT_ACCESS_VIOLATION);
return PathFileExists((const Char*)(path + 0x10)) != 0;
}
EXPORT Bool _delDir(const U8* path)
{
- THROWDBG(path == NULL, 0xc0000005);
+ THROWDBG(path == NULL, EXCPT_ACCESS_VIOLATION);
return DelDirRecursion((const Char*)(path + 0x10)) != 0;
}
EXPORT Bool _delFile(const U8* path)
{
- THROWDBG(path == NULL, 0xc0000005);
+ THROWDBG(path == NULL, EXCPT_ACCESS_VIOLATION);
if (!PathFileExists((const Char*)(path + 0x10)))
return True;
return DeleteFile((const Char*)(path + 0x10)) != 0;
@@ -473,33 +497,42 @@ EXPORT Bool _delFile(const U8* path)
EXPORT Bool _copyDir(const U8* dst, const U8* src)
{
- THROWDBG(dst == NULL, 0xc0000005);
- THROWDBG(src == NULL, 0xc0000005);
+ THROWDBG(dst == NULL, EXCPT_ACCESS_VIOLATION);
+ THROWDBG(src == NULL, EXCPT_ACCESS_VIOLATION);
return CopyDirRecursion((const Char*)(dst + 0x10), (const Char*)(src + 0x10)) != 0;
}
EXPORT Bool _copyFile(const U8* dst, const U8* src)
{
- THROWDBG(dst == NULL, 0xc0000005);
- THROWDBG(src == NULL, 0xc0000005);
+ THROWDBG(dst == NULL, EXCPT_ACCESS_VIOLATION);
+ THROWDBG(src == NULL, EXCPT_ACCESS_VIOLATION);
return CopyFile((const Char*)(src + 0x10), (const Char*)(dst + 0x10), FALSE) != 0;
}
EXPORT Bool _moveDir(const U8* dst, const U8* src)
{
- // TODO:
+ THROWDBG(dst == NULL, EXCPT_ACCESS_VIOLATION);
+ THROWDBG(src == NULL, EXCPT_ACCESS_VIOLATION);
+ if (MoveFileEx((const Char*)(src + 0x10), (const Char*)(dst + 0x10), MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING) == 0)
+ {
+ if (CopyDirRecursion((const Char*)(dst + 0x10), (const Char*)(src + 0x10)) == 0)
+ return False;
+ if (DelDirRecursion((const Char*)(src + 0x10)) == 0)
+ return False;
+ }
+ return True;
}
EXPORT Bool _moveFile(const U8* dst, const U8* src)
{
- THROWDBG(dst == NULL, 0xc0000005);
- THROWDBG(src == NULL, 0xc0000005);
+ THROWDBG(dst == NULL, EXCPT_ACCESS_VIOLATION);
+ THROWDBG(src == NULL, EXCPT_ACCESS_VIOLATION);
return MoveFileEx((const Char*)(src + 0x10), (const Char*)(dst + 0x10), MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING) != 0;
}
EXPORT void* _dir(const U8* path)
{
- THROWDBG(path == NULL, 0xc0000005);
+ THROWDBG(path == NULL, EXCPT_ACCESS_VIOLATION);
const Char* path2 = (const Char*)(path + 0x10);
size_t len = wcslen(path2);
U8* result;
@@ -531,7 +564,7 @@ EXPORT void* _dir(const U8* path)
EXPORT void* _ext(const U8* path)
{
- THROWDBG(path == NULL, 0xc0000005);
+ THROWDBG(path == NULL, EXCPT_ACCESS_VIOLATION);
const Char* path2 = (const Char*)(path + 0x10);
size_t len = wcslen(path2);
U8* result;
@@ -567,7 +600,7 @@ EXPORT void* _ext(const U8* path)
EXPORT void* _fileName(const U8* path)
{
- THROWDBG(path == NULL, 0xc0000005);
+ THROWDBG(path == NULL, EXCPT_ACCESS_VIOLATION);
const Char* path2 = (const Char*)(path + 0x10);
size_t len = wcslen(path2);
U8* result;
@@ -595,13 +628,25 @@ EXPORT void* _fileName(const U8* path)
EXPORT void* _fullPath(const U8* path)
{
- // TODO:
- return NULL;
+ THROWDBG(path == NULL, EXCPT_ACCESS_VIOLATION);
+ Char path2[KUIN_MAX_PATH + 2];
+ Char* file_name_pos;
+ if (GetFullPathName((const Char*)(path + 0x10), KUIN_MAX_PATH, path2, &file_name_pos) == 0)
+ return NULL;
+ NormPath(path2, file_name_pos == NULL);
+ {
+ size_t len = wcslen(path2);
+ U8* result = (U8*)AllocMem(0x10 + sizeof(Char) * (len + 1));
+ *(S64*)(result + 0x00) = DefaultRefCntFunc;
+ *(S64*)(result + 0x08) = (S64)len;
+ wcscpy((Char*)(result + 0x10), path2);
+ return result;
+ }
}
EXPORT void* _delExt(const U8* path)
{
- THROWDBG(path == NULL, 0xc0000005);
+ THROWDBG(path == NULL, EXCPT_ACCESS_VIOLATION);
const Char* path2 = (const Char*)(path + 0x10);
size_t len = wcslen(path2);
U8* result;
@@ -650,8 +695,12 @@ EXPORT void* _sysDir(S64 kind)
EXPORT void* _exeDir(void)
{
Char path[KUIN_MAX_PATH + 1];
+#if defined(DBG)
+ wcscpy(path, EnvVars.ResRoot);
+#else
if (!GetModuleFileName(NULL, path, KUIN_MAX_PATH))
return NULL;
+#endif
{
size_t len = wcslen(path);
U8* result;
@@ -678,18 +727,40 @@ EXPORT void* _exeDir(void)
EXPORT S64 _fileSize(const U8* path)
{
- THROWDBG(path == NULL, 0xc0000005);
+ THROWDBG(path == NULL, EXCPT_ACCESS_VIOLATION);
S64 result;
FILE* file_ptr = _wfopen((const Char*)(path + 0x10), L"rb");
if (file_ptr == NULL)
- THROW(0xe9170007);
+ THROW(EXCPT_FILE_READ_FAILED);
_fseeki64(file_ptr, 0, SEEK_END);
result = _ftelli64(file_ptr);
fclose(file_ptr);
return result;
}
-static Char ReadUtf8(SStream* me_, Bool replace_delimiter, int* char_cnt)
+EXPORT void _setCurDir(const U8* path)
+{
+ THROWDBG(path == NULL, EXCPT_ACCESS_VIOLATION);
+ SetCurrentDirectory((const Char*)(path + 0x10));
+}
+
+EXPORT void* _getCurDir(void)
+{
+ Char path[KUIN_MAX_PATH + 2];
+ if (GetCurrentDirectory(KUIN_MAX_PATH + 1, path) == 0)
+ return NULL;
+ NormPath(path, True);
+ {
+ size_t len = wcslen(path);
+ U8* result = (U8*)AllocMem(0x10 + sizeof(Char) * (len + 1));
+ *(S64*)(result + 0x00) = DefaultRefCntFunc;
+ *(S64*)(result + 0x08) = (S64)len;
+ wcscpy((Char*)(result + 0x10), path);
+ return result;
+ }
+}
+
+static Char ReadUtf8(SReader* me_, Bool replace_delimiter, int* char_cnt)
{
U8 c;
int len;
@@ -697,14 +768,12 @@ static Char ReadUtf8(SStream* me_, Bool replace_delimiter, int* char_cnt)
Char u2;
for (; ; )
{
- int c2 = fgetc(me_->Handle);
- if (c2 == EOF)
+ if (ReadFileStream(me_->Handle, 1, &c) == 0)
{
if (char_cnt != NULL)
*char_cnt = 0;
return WEOF;
}
- c = (U8)c2;
if ((c & 0xc0) == 0x80)
continue;
if ((c & 0x80) == 0x00)
@@ -743,8 +812,8 @@ static Char ReadUtf8(SStream* me_, Bool replace_delimiter, int* char_cnt)
int i;
for (i = 0; i < len; i++)
{
- if (fread(&c, 1, 1, me_->Handle) != 1 || (c & 0xc0) != 0x80)
- THROW(0xe9170008);
+ if (ReadFileStream(me_->Handle, 1, &c) == 0 || (c & 0xc0) != 0x80)
+ THROW(EXCPT_INVALID_DATA_FMT);
u = (u << 6) | (c & 0x3f);
}
}
@@ -755,20 +824,20 @@ static Char ReadUtf8(SStream* me_, Bool replace_delimiter, int* char_cnt)
u2 = (Char)u;
if (!replace_delimiter)
return u2;
- if (u2 == L'\0' || u2 == L'\r' || u2 == L'\n')
+ if (u2 == L'\0')
return L'\0';
{
S64 i;
for (i = 0; i < me_->DelimiterNum; i++)
{
- if (u2 == me_->Delimiters[i])
+ if (u2 == me_->Delimiters[i] || u2 == L'\r' && me_->Delimiters[i] == L'\n')
return L'\0';
}
}
return u2;
}
-static void WriteUtf8(SStream* me_, Char data)
+static void WriteUtf8(SWriter* me_, Char data)
{
U64 u;
size_t size;
@@ -1036,3 +1105,21 @@ static Bool CopyDirRecursion(const Char* dst, const Char* src)
}
return True;
}
+
+static void SkipLastChars(SReader* reader)
+{
+ for (; ; )
+ {
+ int char_len;
+ Char c = ReadUtf8(reader, True, &char_len);
+ if (c == L'\r')
+ continue;
+ if (c == WEOF)
+ break;
+ if (c != L'\0')
+ {
+ SeekFileStream(reader->Handle, (S64)-char_len, SEEK_CUR);
+ break;
+ }
+ }
+}
diff --git a/src/lib_common/file.h b/src/lib_common/file.h
index 4241a8a2..32931343 100644
--- a/src/lib_common/file.h
+++ b/src/lib_common/file.h
@@ -5,25 +5,30 @@
// 'file'
EXPORT SClass* _makeReader(SClass* me_, const U8* path);
EXPORT SClass* _makeWriter(SClass* me_, const U8* path, Bool append);
-EXPORT void _streamDtor(SClass* me_);
-EXPORT void _streamFin(SClass* me_);
-EXPORT void _streamSetPos(SClass* me_, S64 origin, S64 pos);
-EXPORT S64 _streamGetPos(SClass* me_);
-EXPORT void _streamDelimiter(SClass* me_, const U8* delimiters);
-EXPORT void* _streamRead(SClass* me_, S64 size);
-EXPORT Char _streamReadLetter(SClass* me_);
-EXPORT S64 _streamReadInt(SClass* me_);
-EXPORT double _streamReadFloat(SClass* me_);
-EXPORT Char _streamReadChar(SClass* me_);
-EXPORT void* _streamReadStr(SClass* me_);
-EXPORT void* _streamReadLine(SClass* me_);
-EXPORT void _streamWrite(SClass* me_, void* bin);
-EXPORT void _streamWriteInt(SClass* me_, S64 n);
-EXPORT void _streamWriteFloat(SClass* me_, double n);
-EXPORT void _streamWriteChar(SClass* me_, Char n);
-EXPORT void _streamWriteStr(SClass* me_, const U8* n);
-EXPORT S64 _streamFileSize(SClass* me_);
-EXPORT Bool _streamTerm(SClass* me_);
+EXPORT void _readerDtor(SClass* me_);
+EXPORT void _readerFin(SClass* me_);
+EXPORT void _readerSetPos(SClass* me_, S64 origin, S64 pos);
+EXPORT S64 _readerGetPos(SClass* me_);
+EXPORT void _readerDelimiter(SClass* me_, const U8* delimiters);
+EXPORT void* _readerRead(SClass* me_, S64 size);
+EXPORT Char _readerReadLetter(SClass* me_);
+EXPORT S64 _readerReadInt(SClass* me_);
+EXPORT double _readerReadFloat(SClass* me_);
+EXPORT Char _readerReadChar(SClass* me_);
+EXPORT void* _readerReadStr(SClass* me_);
+EXPORT void* _readerReadLine(SClass* me_);
+EXPORT S64 _readerFileSize(SClass* me_);
+EXPORT Bool _readerTerm(SClass* me_);
+EXPORT void _writerDtor(SClass* me_);
+EXPORT void _writerFin(SClass* me_);
+EXPORT void _writerSetPos(SClass* me_, S64 origin, S64 pos);
+EXPORT S64 _writerGetPos(SClass* me_);
+EXPORT void _writerWrite(SClass* me_, void* bin);
+EXPORT void _writerWriteInt(SClass* me_, S64 n);
+EXPORT void _writerWriteFloat(SClass* me_, double n);
+EXPORT void _writerWriteChar(SClass* me_, Char n);
+EXPORT void _writerWriteStr(SClass* me_, const U8* n);
+EXPORT void _writerFlush(SClass* me_);
EXPORT Bool _makeDir(const U8* path);
EXPORT Bool _forEachDir(const U8* path, Bool recursion, void* callback, void* data);
EXPORT Bool _existPath(const U8* path);
@@ -42,3 +47,5 @@ EXPORT void* _tmpFile(void);
EXPORT void* _sysDir(S64 kind);
EXPORT void* _exeDir(void);
EXPORT S64 _fileSize(const U8* path);
+EXPORT void _setCurDir(const U8* path);
+EXPORT void* _getCurDir(void);
diff --git a/src/lib_common/hash.c b/src/lib_common/hash.c
index f077f099..199bfe97 100644
--- a/src/lib_common/hash.c
+++ b/src/lib_common/hash.c
@@ -16,7 +16,7 @@ static void HashBlock(U32* h, const U8* data);
EXPORT void* _hash(const U8* data)
{
- THROWDBG(data == NULL, 0xc0000005);
+ THROWDBG(data == NULL, EXCPT_ACCESS_VIOLATION);
U8* result = (U8*)AllocMem(0x10 + 0x20);
((S64*)result)[0] = DefaultRefCntFunc;
((S64*)result)[1] = 0x20;
diff --git a/src/lib_common/lib.c b/src/lib_common/lib.c
index ba3c1f0c..5e27db0b 100644
--- a/src/lib_common/lib.c
+++ b/src/lib_common/lib.c
@@ -40,13 +40,13 @@ EXPORT void* _cmdLine(void)
EXPORT S64 _rnd(S64 min, S64 max)
{
- THROWDBG(max - min < 0, 0xe9170006);
+ THROWDBG(max - min < 0, EXCPT_DBG_ARG_OUT_DOMAIN);
return RndGet(&GlobalRnd, min, max);
}
EXPORT double _rndFloat(double min, double max)
{
- THROWDBG(min >= max, 0xe9170006);
+ THROWDBG(min >= max, EXCPT_DBG_ARG_OUT_DOMAIN);
return RndGetFloat(&GlobalRnd, min, max);
}
@@ -257,16 +257,16 @@ EXPORT double _toDegree(double rad)
EXPORT S64 _cmp(const U8* s1, const U8* s2)
{
- THROWDBG(s1 == NULL, 0xc0000005);
- THROWDBG(s2 == NULL, 0xc0000005);
+ THROWDBG(s1 == NULL, EXCPT_ACCESS_VIOLATION);
+ THROWDBG(s2 == NULL, EXCPT_ACCESS_VIOLATION);
S64 result = (S64)wcscmp((const Char*)(s1 + 0x10), (const Char*)(s2 + 0x10));
return result > 0 ? 1 : (result < 0 ? -1 : 0);
}
EXPORT S64 _cmpEx(const U8* s1, const U8* s2, S64 len, Bool ignoreCase)
{
- THROWDBG(s1 == NULL, 0xc0000005);
- THROWDBG(s2 == NULL, 0xc0000005);
+ THROWDBG(s1 == NULL, EXCPT_ACCESS_VIOLATION);
+ THROWDBG(s2 == NULL, EXCPT_ACCESS_VIOLATION);
S64 result;
if (ignoreCase)
result = (S64)_wcsnicmp((const Char*)(s1 + 0x10), (const Char*)(s2 + 0x10), (size_t)len);
@@ -297,8 +297,8 @@ EXPORT double _maxFloat(double n1, double n2)
EXPORT S64 _levenshtein(const U8* s1, const U8* s2)
{
- THROWDBG(s1 == NULL, 0xc0000005);
- THROWDBG(s2 == NULL, 0xc0000005);
+ THROWDBG(s1 == NULL, EXCPT_ACCESS_VIOLATION);
+ THROWDBG(s2 == NULL, EXCPT_ACCESS_VIOLATION);
S64 len1 = ((S64*)s1)[1];
S64 len2 = ((S64*)s2)[1];
const Char* str1 = (const Char*)(s1 + 0x10);
@@ -362,7 +362,7 @@ EXPORT double _cerp(double first, double last, double rate)
EXPORT double _hermite(const void* pos, double rate)
{
- THROWDBG(pos == NULL, 0xc0000005);
+ THROWDBG(pos == NULL, EXCPT_ACCESS_VIOLATION);
int len = (int)((S64*)pos)[1];
double len2 = (double)len;
const double* pos2 = (const double*)((const U8*)pos + 0x10);
@@ -392,7 +392,7 @@ EXPORT double _hermite(const void* pos, double rate)
EXPORT SClass* _makeBmSearch(SClass* me_, const U8* pattern)
{
- THROWDBG(pattern == NULL, 0xc0000005);
+ THROWDBG(pattern == NULL, EXCPT_ACCESS_VIOLATION);
SBmSearch* me2 = (SBmSearch*)me_;
{
size_t len = (size_t)((S64*)pattern)[1];
@@ -463,6 +463,63 @@ EXPORT S64 _bmSearchFind(SClass* me_, const U8* text, S64 start)
return -1;
}
+EXPORT void* _countUp(S64 min, S64 max)
+{
+ THROWDBG(min > max, EXCPT_DBG_ARG_OUT_DOMAIN);
+ S64 len = max - min + 1;
+ THROWDBG(len <= 0, EXCPT_DBG_ARG_OUT_DOMAIN);
+ U8* buf = (U8*)AllocMem(0x10 + sizeof(S64) * len);
+ S64* ptr = (S64*)(buf + 0x10);
+ ((S64*)buf)[0] = DefaultRefCntFunc;
+ ((S64*)buf)[1] = (S64)len;
+ S64 i;
+ for (i = 0; i < len; i++)
+ ptr[i] = min + i;
+ return buf;
+}
+
+EXPORT S64 _addChkOverflow(Bool* overflowed, S64 n1, S64 n2)
+{
+ if (AddAsm(&n1, n2))
+ *overflowed = True;
+ else
+ *overflowed = False;
+ return n1;
+}
+
+EXPORT S64 _subChkOverflow(Bool* overflowed, S64 n1, S64 n2)
+{
+ if (SubAsm(&n1, n2))
+ *overflowed = True;
+ else
+ *overflowed = False;
+ return n1;
+}
+
+EXPORT S64 _mulChkOverflow(Bool* overflowed, S64 n1, S64 n2)
+{
+ if (MulAsm(&n1, n2))
+ *overflowed = True;
+ else
+ *overflowed = False;
+ return n1;
+}
+
+EXPORT U64 _addr(SClass* me_)
+{
+ return (U64)me_;
+}
+
+EXPORT U64 _toBit64Forcibly(double x)
+{
+ return *(U64*)&x;
+}
+
+EXPORT double _toFloatForcibly(U64 x)
+{
+ return *(double*)&x;
+}
+
void LibInit(void)
{
// Initialize the random number system.
@@ -490,5 +547,5 @@ void LibInit(void)
}
}
#endif
- RndInit(&GlobalRnd, (U32)(time(NULL)) ^ (U32)timeGetTime() ^ 0x2971c37b);
+ RndInit(&GlobalRnd, MakeSeed(0x2971c37b));
}
diff --git a/src/lib_common/lib.h b/src/lib_common/lib.h
index 93f0aca9..3c7841b7 100644
--- a/src/lib_common/lib.h
+++ b/src/lib_common/lib.h
@@ -48,4 +48,17 @@ EXPORT double _hermite(const void* pos, double rate);
EXPORT SClass* _makeBmSearch(SClass* me_, const U8* pattern);
EXPORT void _bmSearchDtor(SClass* me_);
EXPORT S64 _bmSearchFind(SClass* me_, const U8* text, S64 start);
+EXPORT void* _countUp(S64 min, S64 max);
+EXPORT S64 _addChkOverflow(Bool* overflowed, S64 n1, S64 n2);
+EXPORT S64 _subChkOverflow(Bool* overflowed, S64 n1, S64 n2);
+EXPORT S64 _mulChkOverflow(Bool* overflowed, S64 n1, S64 n2);
+EXPORT U64 _addr(SClass* me_);
+EXPORT U64 _toBit64Forcibly(double x);
+EXPORT double _toFloatForcibly(U64 x);
+
void LibInit(void);
+
+// Assembly functions.
+Bool AddAsm(S64* a, S64 b);
+Bool SubAsm(S64* a, S64 b);
+Bool MulAsm(S64* a, S64 b);
diff --git a/src/lib_common/main.c b/src/lib_common/main.c
index c9c4a5f2..e2e85e87 100644
--- a/src/lib_common/main.c
+++ b/src/lib_common/main.c
@@ -34,6 +34,14 @@ typedef struct SBinList
struct SBinList* Next;
} SBinList;
+typedef struct SListPtr
+{
+ SClass Class;
+ void* Ptr;
+} SListPtr;
+
+extern Char ResRoot[KUIN_MAX_PATH + 1];
+
static Bool IsRef(U8 type);
static size_t GetSize(U8 type);
static S64 Add(S64 a, S64 b);
@@ -46,6 +54,11 @@ static Bool IsStr(const U8* type);
static Bool IsSpace(Char c);
static void Copy(void* dst, U8 type, const void* src);
static void* AddDictRecursion(void* node, const void* key, const void* item, int cmp_func(const void* a, const void* b), U8* key_type, U8* item_type, Bool* addition);
+static void* DelDictRecursion(void* node, const void* key, int cmp_func(const void* a, const void* b), U8* key_type, U8* item_type, Bool* deleted, Bool* balanced);
+static void* DelDictBalanceLeftRecursion(void* node, Bool* balanced);
+static void* DelDictBalanceRightRecursion(void* node, Bool* balanced);
+static void* DictRotateLeft(void* node);
+static void* DictRotateRight(void* node);
static void* CopyDictRecursion(void* node, U8* key_type, U8* item_type);
static void ToBinDictRecursion(void*** buf, void* node, U8* key_type, U8* item_type);
static void* FromBinDictRecursion(const U8* key_type, const U8* item_type, const U8* bin, S64* idx, const void* type_class);
@@ -75,43 +88,11 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
EXPORT void _init(void* heap, S64* heap_cnt, S64 app_code, const U8* use_res_flags)
{
- Heap = heap;
- HeapCnt = heap_cnt;
- AppCode = app_code;
- UseResFlags = use_res_flags;
- Instance = (HINSTANCE)GetModuleHandle(NULL);
+ if (!InitEnvVars(heap, heap_cnt, app_code, use_res_flags))
+ return;
- // Set the current directory.
- {
- Char path[KUIN_MAX_PATH + 1];
- Char* ptr;
- GetModuleFileName(NULL, path, KUIN_MAX_PATH);
- ptr = wcsrchr(path, L'\\');
- if (ptr != NULL)
- *(ptr + 1) = L'\0';
- SetCurrentDirectory(path);
- }
#if defined(DBG)
- {
- const Char* cur_dir_path = L"./_curdir_.txt";
- if (PathFileExists(cur_dir_path))
- {
- Char path[KUIN_MAX_PATH + 1];
- FILE* file_ptr = _wfopen(cur_dir_path, L"r, ccs=UTF-8");
- fgetws(path, KUIN_MAX_PATH, file_ptr);
- {
- Char* ptr = path;
- while (ptr[1] != L'\0')
- ptr++;
- while (ptr >= path && (*ptr == L'\n' || *ptr == L'\r'))
- {
- *ptr = L'\0';
- ptr--;
- }
- }
- SetCurrentDirectory(path);
- }
- }
+ SetCurrentDirectory(EnvVars.ResRoot);
#endif
// Initialize the COM library and the timer.
@@ -145,27 +126,29 @@ EXPORT void _err(S64 excpt)
{
switch (excpt)
{
- case 0xc0000005: text = L"Access violation."; break;
+ case EXCPT_ACCESS_VIOLATION: text = L"Access violation."; break;
case 0xc0000017: text = L"No memory."; break;
case 0xc0000090: text = L"Float invalid operation."; break;
case 0xc0000094: text = L"Integer division by zero."; break;
case 0xc00000fd: text = L"Stack overflow."; break;
case 0xc000013a: text = L"Ctrl-C exit."; break;
- case 0xe9170000: text = L"Assertion failed."; break;
- case 0xe9170001: text = L"Class cast failed."; break;
- case 0xe9170002: text = L"Array index out of range."; break;
- case 0xe9170003: text = L"Integer overflow."; break;
- case 0xe9170004: text = L"Invalid comparison."; break;
+ case EXCPT_DBG_ASSERT_FAILED: text = L"Assertion failed."; break;
+ case EXCPT_CLASS_CAST_FAILED: text = L"Class cast failed."; break;
+ case EXCPT_DBG_ARRAY_IDX_OUT_OF_RANGE: text = L"Array index out of range."; break;
+ case EXCPT_DBG_INT_OVERFLOW: text = L"Integer overflow."; break;
+ case EXCPT_INVALID_CMP: text = L"Invalid comparison."; break;
case 0xe9170005: text = L"Invalid operation on standard library class."; break;
- case 0xe9170006: text = L"Argument outside the domain."; break;
- case 0xe9170007: text = L"File reading failed."; break;
- case 0xe9170008: text = L"Invalid data format."; break;
- case 0xe9170009: text = L"Device initialization failed."; break;
- case 0xe917000a: text = L"Inoperable state."; break;
+ case EXCPT_DBG_ARG_OUT_DOMAIN: text = L"Argument outside the domain."; break;
+ case EXCPT_FILE_READ_FAILED: text = L"File reading failed."; break;
+ case EXCPT_INVALID_DATA_FMT: text = L"Invalid data format."; break;
+ case EXCPT_DEVICE_INIT_FAILED: text = L"Device initialization failed."; break;
+ case EXCPT_DBG_INOPERABLE_STATE: text = L"Inoperable state."; break;
}
}
swprintf(str, 1024, L"An exception '0x%08X' occurred.\r\n\r\n> %s", (U32)excpt, text);
MessageBox(0, str, NULL, 0);
+#else
+ UNUSED(excpt);
#endif
}
@@ -602,7 +585,8 @@ EXPORT void* _toBin(const void* me_, const U8* type)
S64 len = *(S64*)((U8*)me_ + 0x08);
void** bins = (void**)AllocMem(sizeof(void*) * (size_t)len * 3); // 'key' + 'value' + 'info' per node.
void** ptr = bins;
- ToBinDictRecursion(&ptr, *(void**)((U8*)me_ + 0x10), child1, child2);
+ if (len != 0)
+ ToBinDictRecursion(&ptr, *(void**)((U8*)me_ + 0x10), child1, child2);
return CatBin((int)len * 3, bins);
}
}
@@ -848,7 +832,7 @@ EXPORT void* _fromBin(const U8* me_, const void** type, S64* idx)
default:
ASSERT(*type2 == TypeId_Class);
if (*(S64*)(me_ + 0x10 + *idx) != 0)
- THROW(0xc0000005); // TODO: What is this code?
+ THROW(EXCPT_ACCESS_VIOLATION); // TODO: What is this code?
*idx += 8;
{
const void** type3 = (const void**)type[1];
@@ -872,16 +856,20 @@ EXPORT S64 _powInt(S64 n, S64 m)
default:
if (m < 0)
{
- THROWDBG(n == 0, 0xe9170003);
+ THROWDBG(n == 0, EXCPT_DBG_INT_OVERFLOW);
return n == 1 ? 1 : 0;
}
+ if (m == 0)
+ return 1;
{
S64 result = 1;
- while (m != 0)
+ for (; ; )
{
if ((m & 1) == 1)
result = Mul(result, n);
m >>= 1;
+ if (m == 0)
+ break;
n = Mul(n, n);
}
return result;
@@ -907,7 +895,7 @@ EXPORT S64 _cmpStr(const U8* a, const U8* b)
EXPORT void* _newArray(S64 len, S64* nums, const U8* type)
{
- THROWDBG(*nums < 0, 0xe9170002);
+ THROWDBG(*nums < 0, EXCPT_DBG_ARRAY_IDX_OUT_OF_RANGE);
{
size_t size = len == 1 ? GetSize(*type) : 8;
Bool is_str = len == 1 && *type == TypeId_Char;
@@ -938,7 +926,7 @@ EXPORT U8* _toStr(const void* me_, const U8* type)
switch (*type)
{
case TypeId_Int: len = swprintf(str, 33, L"%I64d", *(S64*)&me_); break;
- case TypeId_Float: len = swprintf(str, 33, L"%g", *(double*)&me_); break;
+ case TypeId_Float: len = swprintf(str, 33, L"%.16g", *(double*)&me_); break;
case TypeId_Char:
len = 1;
str[0] = *(Char*)&me_;
@@ -965,6 +953,7 @@ EXPORT U8* _toStr(const void* me_, const U8* type)
return (U8*)me_;
break;
default:
+ len = 0;
ASSERT(False);
break;
}
@@ -980,7 +969,7 @@ EXPORT U8* _toStr(const void* me_, const U8* type)
EXPORT U8* _toStrFmtInt(S64 me_, const U8* fmt)
{
- THROWDBG(fmt == NULL, 0xc0000005);
+ THROWDBG(fmt == NULL, EXCPT_ACCESS_VIOLATION);
const Char* fmt2 = (const Char*)(fmt + 0x10);
int src_len = (int)((S64*)fmt)[1];
Char dst[33];
@@ -1049,7 +1038,7 @@ EXPORT U8* _toStrFmtInt(S64 me_, const U8* fmt)
EXPORT U8* _toStrFmtFloat(double me_, const U8* fmt)
{
- THROWDBG(fmt == NULL, 0xc0000005);
+ THROWDBG(fmt == NULL, EXCPT_ACCESS_VIOLATION);
const Char* fmt2 = (const Char*)(fmt + 0x10);
int src_len = (int)((S64*)fmt)[1];
Char dst[33];
@@ -1155,7 +1144,7 @@ EXPORT double _signFloat(double me_)
EXPORT S64 _clampInt(S64 me_, S64 min, S64 max)
{
- THROWDBG(min > max, 0xe9170006);
+ THROWDBG(min > max, EXCPT_DBG_ARG_OUT_DOMAIN);
if (me_ < min)
return min;
if (me_ > max)
@@ -1165,7 +1154,7 @@ EXPORT S64 _clampInt(S64 me_, S64 min, S64 max)
EXPORT double _clampFloat(double me_, double min, double max)
{
- THROWDBG(min > max, 0xe9170006);
+ THROWDBG(min > max, EXCPT_DBG_ARG_OUT_DOMAIN);
if (me_ < min)
return min;
if (me_ > max)
@@ -1318,11 +1307,11 @@ EXPORT S64 _endian(const void* me_, const U8* type)
EXPORT void* _sub(const void* me_, const U8* type, S64 start, S64 len)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
S64 len2 = *(S64*)((U8*)me_ + 0x08);
if (len == -1)
len = len2 - start;
- THROWDBG(start < 0 || len < 0 || start + len > len2, 0xe9170002);
+ THROWDBG(start < 0 || len < 0 || start + len > len2, EXCPT_DBG_ARRAY_IDX_OUT_OF_RANGE);
{
Bool is_str = IsStr(type);
size_t size = GetSize(type[1]);
@@ -1350,7 +1339,7 @@ EXPORT void* _sub(const void* me_, const U8* type, S64 start, S64 len)
EXPORT void _reverse(void* me_, const U8* type)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
size_t size = GetSize(type[1]);
S64 len = *(S64*)((U8*)me_ + 0x08);
U8* a = (U8*)me_ + 0x10;
@@ -1369,7 +1358,7 @@ EXPORT void _reverse(void* me_, const U8* type)
EXPORT void _shuffle(void* me_, const U8* type)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
size_t size = GetSize(type[1]);
S64 len = *(S64*)((U8*)me_ + 0x08);
U8* a = (U8*)me_ + 0x10;
@@ -1391,42 +1380,42 @@ EXPORT void _shuffle(void* me_, const U8* type)
EXPORT void _sortArray(void* me_, const U8* type)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
MergeSortArray(me_, type, True);
}
EXPORT void _sortDescArray(void* me_, const U8* type)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
MergeSortArray(me_, type, False);
}
EXPORT void _sortList(void* me_, const U8* type)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
MergeSortList(me_, type, True);
}
EXPORT void _sortDescList(void* me_, const U8* type)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
MergeSortList(me_, type, False);
}
EXPORT S64 _findArray(const void* me_, const U8* type, const void* item, S64 start)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
size_t size = GetSize(type[1]);
int(*cmp)(const void* a, const void* b) = GetCmpFunc(type + 1);
if (cmp == NULL)
- THROW(0xe9170004);
+ THROW(EXCPT_INVALID_CMP);
S64 len = *(S64*)((U8*)me_ + 0x08);
- U8* ptr = (U8*)me_ + 0x10;
- S64 i;
if (start < -1 || len <= start)
return -1;
if (start == -1)
start = 0;
+ U8* ptr = (U8*)me_ + 0x10 + size * start;
+ S64 i;
for (i = start; i < len; i++)
{
void* value = NULL;
@@ -1440,11 +1429,11 @@ EXPORT S64 _findArray(const void* me_, const U8* type, const void* item, S64 sta
EXPORT Bool _findList(const void* me_, const U8* type, const void* item)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
size_t size = GetSize(type[1]);
int(*cmp)(const void* a, const void* b) = GetCmpFunc(type + 1);
if (cmp == NULL)
- THROW(0xe9170004);
+ THROW(EXCPT_INVALID_CMP);
for (; ; )
{
void* cur = *(void**)((U8*)me_ + 0x20);
@@ -1461,18 +1450,18 @@ EXPORT Bool _findList(const void* me_, const U8* type, const void* item)
EXPORT S64 _findLastArray(const void* me_, const U8* type, const void* item, S64 start)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
size_t size = GetSize(type[1]);
int(*cmp)(const void* a, const void* b) = GetCmpFunc(type + 1);
if (cmp == NULL)
- THROW(0xe9170004);
+ THROW(EXCPT_INVALID_CMP);
S64 len = *(S64*)((U8*)me_ + 0x08);
- U8* ptr = (U8*)me_ + 0x10 + size * (size_t)(len - 1);
- S64 i;
if (start < -1 || len <= start)
return -1;
if (start == -1)
start = len - 1;
+ U8* ptr = (U8*)me_ + 0x10 + size * start;
+ S64 i;
for (i = start; i >= 0; i--)
{
void* value = NULL;
@@ -1486,11 +1475,11 @@ EXPORT S64 _findLastArray(const void* me_, const U8* type, const void* item, S64
EXPORT Bool _findLastList(const void* me_, const U8* type, const void* item)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
size_t size = GetSize(type[1]);
int(*cmp)(const void* a, const void* b) = GetCmpFunc(type + 1);
if (cmp == NULL)
- THROW(0xe9170004);
+ THROW(EXCPT_INVALID_CMP);
for (; ; )
{
void* cur = *(void**)((U8*)me_ + 0x20);
@@ -1507,11 +1496,11 @@ EXPORT Bool _findLastList(const void* me_, const U8* type, const void* item)
EXPORT S64 _findBin(const void* me_, const U8* type, const void* item)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
size_t size = GetSize(type[1]);
int(*cmp)(const void* a, const void* b) = GetCmpFunc(type + 1);
if (cmp == NULL)
- THROW(0xe9170004);
+ THROW(EXCPT_INVALID_CMP);
{
S64 len = *(S64*)((U8*)me_ + 0x08);
U8* ptr = (U8*)me_ + 0x10;
@@ -1537,7 +1526,7 @@ EXPORT S64 _findBin(const void* me_, const U8* type, const void* item)
EXPORT void _fill(void* me_, const U8* type, const void* value)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
size_t size = GetSize(type[1]);
S64 len = *(S64*)((U8*)me_ + 0x08);
U8* ptr = (U8*)me_ + 0x10;
@@ -1573,11 +1562,11 @@ EXPORT void _fill(void* me_, const U8* type, const void* value)
EXPORT void* _min(const void* me_, const U8* type)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
size_t size = GetSize(type[1]);
int(*cmp)(const void* a, const void* b) = GetCmpFunc(type + 1);
if (cmp == NULL)
- THROW(0xe9170004);
+ THROW(EXCPT_INVALID_CMP);
S64 len = *(S64*)((U8*)me_ + 0x08);
U8* ptr = (U8*)me_ + 0x10;
void* item = NULL;
@@ -1597,11 +1586,11 @@ EXPORT void* _min(const void* me_, const U8* type)
EXPORT void* _max(const void* me_, const U8* type)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
size_t size = GetSize(type[1]);
int(*cmp)(const void* a, const void* b) = GetCmpFunc(type + 1);
if (cmp == NULL)
- THROW(0xe9170004);
+ THROW(EXCPT_INVALID_CMP);
S64 len = *(S64*)((U8*)me_ + 0x08);
U8* ptr = (U8*)me_ + 0x10;
void* item = NULL;
@@ -1621,7 +1610,7 @@ EXPORT void* _max(const void* me_, const U8* type)
EXPORT void* _repeat(const void* me_, const U8* type, S64 len)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
size_t size = GetSize(type[1]);
Bool is_str = type[1] == TypeId_Char;
size_t len2 = ((const S64*)me_)[1];
@@ -1655,25 +1644,46 @@ EXPORT void* _repeat(const void* me_, const U8* type, S64 len)
return result;
}
-EXPORT Bool _toInt(const U8* me_, S64* value)
+EXPORT S64 _toInt(const U8* me_, Bool* success)
{
Char* ptr;
- THROWDBG(me_ == NULL, 0xc0000005);
- *value = wcstoll((const Char*)(me_ + 0x10), &ptr, 10);
- return *ptr == L'\0';
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
+ const Char* str = (const Char*)(me_ + 0x10);
+ S64 value;
+ if (str[0] == '0' && str[1] == 'x')
+ value = wcstoll(str + 2, &ptr, 16);
+ else
+ value = wcstoll(str, &ptr, 10);
+ *success = *ptr == L'\0';
+ return value;
+}
+
+EXPORT double _toFloat(const U8* me_, Bool* success)
+{
+ Char* ptr;
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
+ double value = wcstod((const Char*)(me_ + 0x10), &ptr);
+ *success = *ptr == L'\0';
+ return value;
}
-EXPORT Bool _toFloat(const U8* me_, double* value)
+EXPORT U64 _toBit64(const U8* me_, Bool* success)
{
Char* ptr;
- THROWDBG(me_ == NULL, 0xc0000005);
- *value = wcstod((const Char*)(me_ + 0x10), &ptr);
- return *ptr == L'\0';
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
+ const Char* str = (const Char*)(me_ + 0x10);
+ U64 value;
+ if (str[0] == '0' && str[1] == 'x')
+ value = wcstoull(str + 2, &ptr, 16);
+ else
+ value = wcstoull(str, &ptr, 10);
+ *success = *ptr == L'\0';
+ return value;
}
EXPORT void* _lower(const U8* me_)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
S64 len = *(S64*)(me_ + 0x08);
U8* result = (U8*)AllocMem(0x10 + sizeof(Char) * (size_t)(len + 1));
((S64*)result)[0] = DefaultRefCntFunc;
@@ -1698,7 +1708,7 @@ EXPORT void* _lower(const U8* me_)
EXPORT void* _upper(const U8* me_)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
S64 len = *(S64*)(me_ + 0x08);
U8* result = (U8*)AllocMem(0x10 + sizeof(Char) * (size_t)(len + 1));
((S64*)result)[0] = DefaultRefCntFunc;
@@ -1723,7 +1733,7 @@ EXPORT void* _upper(const U8* me_)
EXPORT void* _trim(const U8* me_)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
S64 len = *(S64*)(me_ + 0x08);
const Char* first = (Char*)(me_ + 0x10);
const Char* last = first + len - 1;
@@ -1750,7 +1760,7 @@ EXPORT void* _trim(const U8* me_)
EXPORT void* _trimLeft(const U8* me_)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
S64 len = *(S64*)(me_ + 0x08);
const Char* first = (Char*)(me_ + 0x10);
while (len > 0 && IsSpace(*first))
@@ -1770,7 +1780,7 @@ EXPORT void* _trimLeft(const U8* me_)
EXPORT void* _trimRight(const U8* me_)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
S64 len = *(S64*)(me_ + 0x08);
const Char* last = (Char*)(me_ + 0x10) + len - 1;
while (len > 0 && IsSpace(*last))
@@ -1790,8 +1800,8 @@ EXPORT void* _trimRight(const U8* me_)
EXPORT void* _split(const U8* me_, const U8* delimiter)
{
- THROWDBG(me_ == NULL, 0xc0000005);
- THROWDBG(delimiter == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
+ THROWDBG(delimiter == NULL, EXCPT_ACCESS_VIOLATION);
SBinList* top = NULL;
SBinList* bottom = NULL;
size_t len = 0;
@@ -1856,10 +1866,18 @@ EXPORT void* _split(const U8* me_, const U8* delimiter)
EXPORT void* _join(const U8* me_, const U8* delimiter)
{
- THROWDBG(me_ == NULL, 0xc0000005);
- THROWDBG(delimiter == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
+ THROWDBG(delimiter == NULL, EXCPT_ACCESS_VIOLATION);
S64 delimiter_len = *(const S64*)(delimiter + 0x08);
S64 array_len = *(const S64*)(me_ + 0x08);
+ if (array_len == 0)
+ {
+ U8* blank = (U8*)AllocMem(0x10 + sizeof(Char));
+ ((S64*)blank)[0] = DefaultRefCntFunc;
+ ((S64*)blank)[1] = 0;
+ *(Char*)(blank + 0x10) = L'\0';
+ return blank;
+ }
const void** array_ = (const void**)(me_ + 0x10);
S64 total_len = delimiter_len * (array_len - 1);
U8* result;
@@ -1895,9 +1913,9 @@ EXPORT void* _join(const U8* me_, const U8* delimiter)
EXPORT void* _replace(const U8* me_, const U8* old, const U8* new_)
{
- THROWDBG(me_ == NULL, 0xc0000005);
- THROWDBG(old == NULL, 0xc0000005);
- THROWDBG(new_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
+ THROWDBG(old == NULL, EXCPT_ACCESS_VIOLATION);
+ THROWDBG(new_ == NULL, EXCPT_ACCESS_VIOLATION);
SBinList* top = NULL;
SBinList* bottom = NULL;
size_t len = 0;
@@ -1966,8 +1984,8 @@ EXPORT void* _replace(const U8* me_, const U8* old, const U8* new_)
EXPORT S64 _findStr(const U8* me_, const U8* pattern, S64 start)
{
- THROWDBG(me_ == NULL, 0xc0000005);
- THROWDBG(pattern == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
+ THROWDBG(pattern == NULL, EXCPT_ACCESS_VIOLATION);
S64 len1 = ((const S64*)me_)[1];
if (start < -1 || len1 <= start)
return -1;
@@ -1979,8 +1997,8 @@ EXPORT S64 _findStr(const U8* me_, const U8* pattern, S64 start)
EXPORT S64 _findStrLast(const U8* me_, const U8* pattern, S64 start)
{
- THROWDBG(me_ == NULL, 0xc0000005);
- THROWDBG(pattern == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
+ THROWDBG(pattern == NULL, EXCPT_ACCESS_VIOLATION);
S64 len1 = ((const S64*)me_)[1];
S64 len2 = ((const S64*)pattern)[1];
const Char* ptr1 = (const Char*)(me_ + 0x10);
@@ -2000,8 +2018,8 @@ EXPORT S64 _findStrLast(const U8* me_, const U8* pattern, S64 start)
EXPORT S64 _findStrEx(const U8* me_, const U8* pattern, S64 start, Bool fromLast, Bool ignoreCase, Bool wholeWord)
{
- THROWDBG(me_ == NULL, 0xc0000005);
- THROWDBG(pattern == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
+ THROWDBG(pattern == NULL, EXCPT_ACCESS_VIOLATION);
S64 len1 = ((const S64*)me_)[1];
S64 len2 = ((const S64*)pattern)[1];
const Char* ptr1 = (const Char*)(me_ + 0x10);
@@ -2069,7 +2087,7 @@ EXPORT S64 _findStrEx(const U8* me_, const U8* pattern, S64 start, Bool fromLast
EXPORT void _addList(void* me_, const U8* type, const void* item)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
U8* node = (U8*)AllocMem(0x10 + GetSize(type[1]));
Copy(node + 0x10, type[1], &item);
*(void**)(node + 0x08) = NULL;
@@ -2090,7 +2108,7 @@ EXPORT void _addList(void* me_, const U8* type, const void* item)
EXPORT void _addStack(void* me_, const U8* type, const void* item)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
U8* node = (U8*)AllocMem(0x08 + GetSize(type[1]));
Copy(node + 0x08, type[1], &item);
*(void**)node = *(void**)((U8*)me_ + 0x10);
@@ -2100,7 +2118,7 @@ EXPORT void _addStack(void* me_, const U8* type, const void* item)
EXPORT void _addQueue(void* me_, const U8* type, const void* item)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
U8* node = (U8*)AllocMem(0x08 + GetSize(type[1]));
Copy(node + 0x08, type[1], &item);
*(void**)node = NULL;
@@ -2114,13 +2132,13 @@ EXPORT void _addQueue(void* me_, const U8* type, const void* item)
EXPORT void _addDict(void* me_, const U8* type, const U8* value_type, const void* key, const void* item)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
Bool addition;
U8* child1;
U8* child2;
UNUSED(value_type);
GetDictTypes(type, &child1, &child2);
- THROWDBG(IsRef(*child1) && key == NULL, 0xc0000005); // 'key' must not be 'null'.
+ THROWDBG(IsRef(*child1) && key == NULL, EXCPT_ACCESS_VIOLATION); // 'key' must not be 'null'.
*(void**)((U8*)me_ + 0x10) = AddDictRecursion(*(void**)((U8*)me_ + 0x10), key, item, GetCmpFunc(child1), child1, child2, &addition);
if (addition)
(*(S64*)((U8*)me_ + 0x08))++;
@@ -2129,8 +2147,8 @@ EXPORT void _addDict(void* me_, const U8* type, const U8* value_type, const void
EXPORT void* _getList(void* me_, const U8* type)
{
- THROWDBG(me_ == NULL, 0xc0000005);
- THROWDBG(*(void**)((U8*)me_ + 0x20) == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
+ THROWDBG(*(void**)((U8*)me_ + 0x20) == NULL, EXCPT_ACCESS_VIOLATION);
void* result = NULL;
Copy(&result, type[1], (U8*)*(void**)((U8*)me_ + 0x20) + 0x10);
return result;
@@ -2138,9 +2156,9 @@ EXPORT void* _getList(void* me_, const U8* type)
EXPORT void* _getStack(void* me_, const U8* type)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
void* node = *(void**)((U8*)me_ + 0x10);
- THROWDBG(node == NULL, 0xc0000005);
+ THROWDBG(node == NULL, EXCPT_ACCESS_VIOLATION);
void* result = NULL;
Copy(&result, type[1], (U8*)node + 0x08);
*(void**)((U8*)me_ + 0x10) = *(void**)node;
@@ -2161,9 +2179,9 @@ EXPORT void* _getStack(void* me_, const U8* type)
EXPORT void* _getQueue(void* me_, const U8* type)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
void* node = *(void**)((U8*)me_ + 0x10);
- THROWDBG(node == NULL, 0xc0000005);
+ THROWDBG(node == NULL, EXCPT_ACCESS_VIOLATION);
void* result = NULL;
Copy(&result, type[1], (U8*)node + 0x08);
*(void**)((U8*)me_ + 0x10) = *(void**)node;
@@ -2184,13 +2202,13 @@ EXPORT void* _getQueue(void* me_, const U8* type)
return result;
}
-EXPORT void* _getDict(void* me_, const U8* type, const void* key)
+EXPORT void* _getDict(void* me_, const U8* type, const void* key, Bool* existed)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
U8* child1;
U8* child2;
GetDictTypes(type, &child1, &child2);
- THROWDBG(IsRef(*child1) && key == NULL, 0xc0000005); // 'key' must not be 'null'.
+ THROWDBG(IsRef(*child1) && key == NULL, EXCPT_ACCESS_VIOLATION); // 'key' must not be 'null'.
{
int(*cmp_func)(const void* a, const void* b) = GetCmpFunc(child1);
const void* node = *(void**)((U8*)me_ + 0x10);
@@ -2201,6 +2219,7 @@ EXPORT void* _getDict(void* me_, const U8* type, const void* key)
{
void* result = NULL;
Copy(&result, *child2, (U8*)node + 0x20);
+ *existed = True;
return result;
}
if (cmp < 0)
@@ -2209,12 +2228,13 @@ EXPORT void* _getDict(void* me_, const U8* type, const void* key)
node = *(void**)((U8*)node + 0x08);
}
}
+ *existed = False;
return NULL;
}
EXPORT void* _getOffset(void* me_, const U8* type, S64 offset)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
void* ptr = *(void**)((U8*)me_ + 0x20);
S64 i;
if (offset >= 0)
@@ -2227,7 +2247,7 @@ EXPORT void* _getOffset(void* me_, const U8* type, S64 offset)
for (i = 0; i > offset; i--)
ptr = *(void**)ptr;
}
- THROWDBG(ptr == NULL, 0xc0000005);
+ THROWDBG(ptr == NULL, EXCPT_ACCESS_VIOLATION);
{
void* result = NULL;
Copy(&result, type[1], (U8*)ptr + 0x10);
@@ -2237,39 +2257,39 @@ EXPORT void* _getOffset(void* me_, const U8* type, S64 offset)
EXPORT void _head(void* me_, const U8* type)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
UNUSED(type);
*(void**)((U8*)me_ + 0x20) = *(void**)((U8*)me_ + 0x10);
}
EXPORT void _tail(void* me_, const U8* type)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
UNUSED(type);
*(void**)((U8*)me_ + 0x20) = *(void**)((U8*)me_ + 0x18);
}
EXPORT void _next(void* me_, const U8* type)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
void* ptr = *(void**)((U8*)me_ + 0x20);
- THROWDBG(ptr == NULL, 0xc0000005);
+ THROWDBG(ptr == NULL, EXCPT_ACCESS_VIOLATION);
UNUSED(type);
*(void**)((U8*)me_ + 0x20) = *(void**)((U8*)ptr + 0x08);
}
EXPORT void _prev(void* me_, const U8* type)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
void* ptr = *(void**)((U8*)me_ + 0x20);
- THROWDBG(ptr == NULL, 0xc0000005);
+ THROWDBG(ptr == NULL, EXCPT_ACCESS_VIOLATION);
UNUSED(type);
*(void**)((U8*)me_ + 0x20) = *(void**)ptr;
}
EXPORT void _moveOffset(void* me_, const U8* type, S64 offset)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
void* ptr = *(void**)((U8*)me_ + 0x20);
S64 i;
UNUSED(type);
@@ -2296,14 +2316,14 @@ EXPORT void _moveOffset(void* me_, const U8* type, S64 offset)
EXPORT Bool _term(void* me_, const U8* type)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
UNUSED(type);
return *(void**)((U8*)me_ + 0x20) == NULL;
}
EXPORT Bool _termOffset(void* me_, const U8* type, S64 offset)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
void* ptr = *(void**)((U8*)me_ + 0x20);
S64 i;
UNUSED(type);
@@ -2332,8 +2352,8 @@ EXPORT Bool _termOffset(void* me_, const U8* type, S64 offset)
EXPORT void _del(void* me_, const U8* type)
{
- THROWDBG(me_ == NULL, 0xc0000005);
- THROWDBG(*(void**)((U8*)me_ + 0x20) == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
+ THROWDBG(*(void**)((U8*)me_ + 0x20) == NULL, EXCPT_ACCESS_VIOLATION);
{
void* ptr = *(void**)((U8*)me_ + 0x20);
void* next = *(void**)((U8*)ptr + 0x08);
@@ -2364,12 +2384,12 @@ EXPORT void _del(void* me_, const U8* type)
EXPORT void _delNext(void* me_, const U8* type)
{
- THROWDBG(me_ == NULL, 0xc0000005);
- THROWDBG(*(void**)((U8*)me_ + 0x20) == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
+ THROWDBG(*(void**)((U8*)me_ + 0x20) == NULL, EXCPT_ACCESS_VIOLATION);
{
void* ptr = *(void**)((U8*)me_ + 0x20);
void* next = *(void**)((U8*)ptr + 0x08);
- THROWDBG(next == NULL, 0xc0000005);
+ THROWDBG(next == NULL, EXCPT_ACCESS_VIOLATION);
void* next_next = *(void**)((U8*)next + 0x08);
*(void**)((U8*)ptr + 0x08) = next_next;
if (next_next == NULL)
@@ -2393,8 +2413,8 @@ EXPORT void _delNext(void* me_, const U8* type)
EXPORT void _ins(void* me_, const U8* type, const void* item)
{
- THROWDBG(me_ == NULL, 0xc0000005);
- THROWDBG(*(void**)((U8*)me_ + 0x20) == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
+ THROWDBG(*(void**)((U8*)me_ + 0x20) == NULL, EXCPT_ACCESS_VIOLATION);
{
void* ptr = *(void**)((U8*)me_ + 0x20);
U8* node = (U8*)AllocMem(0x10 + GetSize(type[1]));
@@ -2412,7 +2432,7 @@ EXPORT void _ins(void* me_, const U8* type, const void* item)
EXPORT void* _toArray(void* me_, const U8* type)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
size_t size = GetSize(type[1]);
S64 len = *(S64*)((U8*)me_ + 0x08);
Bool is_str = type[1] == TypeId_Char;
@@ -2437,7 +2457,7 @@ EXPORT void* _toArray(void* me_, const U8* type)
EXPORT void* _toArrayKey(void* me_, const U8* type)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
U8* child1;
U8* child2;
GetDictTypes(type, &child1, &child2);
@@ -2469,7 +2489,7 @@ EXPORT void* _toArrayKey(void* me_, const U8* type)
EXPORT void* _toArrayValue(void* me_, const U8* type)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
U8* child1;
U8* child2;
GetDictTypes(type, &child1, &child2);
@@ -2501,9 +2521,9 @@ EXPORT void* _toArrayValue(void* me_, const U8* type)
EXPORT void* _peek(void* me_, const U8* type)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
void* node = *(void**)((U8*)me_ + 0x10);
- THROWDBG(node == NULL, 0xc0000005);
+ THROWDBG(node == NULL, EXCPT_ACCESS_VIOLATION);
void* result = NULL;
Copy(&result, type[1], (U8*)node + 0x08);
return result;
@@ -2511,11 +2531,11 @@ EXPORT void* _peek(void* me_, const U8* type)
EXPORT Bool _exist(void* me_, const U8* type, const void* key)
{
- THROWDBG(me_ == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
U8* child1;
U8* child2;
GetDictTypes(type, &child1, &child2);
- THROWDBG(IsRef(*child1) && key == NULL, 0xc0000005); // 'key' must not be 'null'.
+ THROWDBG(IsRef(*child1) && key == NULL, EXCPT_ACCESS_VIOLATION); // 'key' must not be 'null'.
{
int(*cmp_func)(const void* a, const void* b) = GetCmpFunc(child1);
const void* node = *(void**)((U8*)me_ + 0x10);
@@ -2535,8 +2555,8 @@ EXPORT Bool _exist(void* me_, const U8* type, const void* key)
EXPORT Bool _forEach(void* me_, const U8* type, const void* callback, void* data)
{
- THROWDBG(me_ == NULL, 0xc0000005);
- THROWDBG(callback == NULL, 0xc0000005);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
+ THROWDBG(callback == NULL, EXCPT_ACCESS_VIOLATION);
U8* child1;
U8* child2;
GetDictTypes(type, &child1, &child2);
@@ -2548,6 +2568,54 @@ EXPORT Bool _forEach(void* me_, const U8* type, const void* callback, void* data
}
}
+EXPORT void _delDict(void* me_, const U8* type, const void* key)
+{
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
+ U8* child1;
+ U8* child2;
+ GetDictTypes(type, &child1, &child2);
+ THROWDBG(IsRef(*child1) && key == NULL, EXCPT_ACCESS_VIOLATION); // 'key' must not be 'null'.
+ {
+ Bool deleted = False;
+ Bool balanced = False;
+ *(void**)((U8*)me_ + 0x10) = DelDictRecursion(*(void**)((U8*)me_ + 0x10), key, GetCmpFunc(child1), child1, child2, &deleted, &balanced);
+ if (deleted)
+ (*(S64*)((U8*)me_ + 0x08))--;
+ }
+}
+
+EXPORT S64 _idx(void* me_, const U8* type)
+{
+ UNUSED(type);
+ THROWDBG(me_ == NULL, EXCPT_ACCESS_VIOLATION);
+ void* cur = *(void**)((U8*)me_ + 0x20);
+ void* ptr = *(void**)((U8*)me_ + 0x10);
+ S64 idx = 0;
+ if (cur == NULL)
+ return -1;
+ while (ptr != NULL)
+ {
+ if (ptr == cur)
+ return idx;
+ idx++;
+ ptr = *(void**)((U8*)ptr + 0x08);
+ }
+ return -1;
+}
+
+EXPORT SClass* _getPtr(void* me_, const U8* type, SClass* me2)
+{
+ SListPtr* ptr = (SListPtr*)me2;
+ ptr->Ptr = *(void**)((U8*)me_ + 0x20);
+ return me2;
+}
+
+EXPORT void _setPtr(void* me_, const U8* type, SClass* ptr)
+{
+ SListPtr* ptr2 = (SListPtr*)ptr;
+ *(void**)((U8*)me_ + 0x20) = ptr2->Ptr;
+}
+
static Bool IsRef(U8 type)
{
return type == TypeId_Array || type == TypeId_List || type == TypeId_Stack || type == TypeId_Queue || type == TypeId_Dict || type == TypeId_Class;
@@ -2582,7 +2650,7 @@ static S64 Add(S64 a, S64 b)
{
#if defined(DBG)
if (AddAsm(&a, b))
- THROW(0xe9170003);
+ THROW(EXCPT_DBG_INT_OVERFLOW);
return a;
#else
return a + b;
@@ -2593,7 +2661,7 @@ static S64 Sub(S64 a, S64 b)
{
#if defined(DBG)
if (SubAsm(&a, b))
- THROW(0xe9170003);
+ THROW(EXCPT_DBG_INT_OVERFLOW);
return a;
#else
return a - b;
@@ -2604,7 +2672,7 @@ static S64 Mul(S64 a, S64 b)
{
#if defined(DBG)
if (MulAsm(&a, b))
- THROW(0xe9170003);
+ THROW(EXCPT_DBG_INT_OVERFLOW);
return a;
#else
return a * b;
@@ -2748,22 +2816,10 @@ static void* AddDictRecursion(void* node, const void* key, const void* item, int
*(void**)((U8*)node + 0x08) = AddDictRecursion(*(void**)((U8*)node + 0x08), key, item, cmp_func, key_type, item_type, addition);
}
if (*(void**)((U8*)node + 0x08) != NULL && *(Bool*)((U8*)*(void**)((U8*)node + 0x08) + 0x10))
- {
- void* r = *(void**)((U8*)node + 0x08);
- *(void**)((U8*)node + 0x08) = *(void**)r;
- *(void**)r = node;
- *(Bool*)((U8*)r + 0x10) = *(Bool*)((U8*)node + 0x10);
- *(Bool*)((U8*)node + 0x10) = True;
- node = r;
- }
+ node = DictRotateLeft(node);
if (*(void**)node != NULL && *(Bool*)((U8*)*(void**)node + 0x10) && *(void**)*(void**)node != NULL && *(Bool*)((U8*)*(void**)*(void**)node + 0x10))
{
- void* l = *(void**)node;
- *(void**)node = *(void**)((U8*)l + 0x08);
- *(void**)((U8*)l + 0x08) = node;
- *(Bool*)((U8*)l + 0x10) = *(Bool*)((U8*)node + 0x10);
- *(Bool*)((U8*)node + 0x10) = True;
- node = l;
+ node = DictRotateRight(node);
*(Bool*)((U8*)node + 0x10) = True;
*(Bool*)((U8*)*(void**)node + 0x10) = False;
*(Bool*)((U8*)*(void**)((U8*)node + 0x08) + 0x10) = False;
@@ -2772,6 +2828,196 @@ static void* AddDictRecursion(void* node, const void* key, const void* item, int
return node;
}
+static void* DelDictRecursion(void* node, const void* key, int cmp_func(const void* a, const void* b), U8* key_type, U8* item_type, Bool* deleted, Bool* balanced)
+{
+ if (node == NULL)
+ {
+ *balanced = True;
+ return NULL;
+ }
+ int cmp = cmp_func(key, *(void**)((U8*)node + 0x18));
+ if (cmp == 0)
+ {
+ if (*(void**)node == NULL && *(void**)((U8*)node + 0x08) == NULL)
+ {
+ *balanced = *(Bool*)((U8*)node + 0x10);
+
+ if (IsRef(*key_type))
+ {
+ void* ptr2 = *(void**)((U8*)node + 0x18);
+ if (ptr2 != NULL)
+ {
+ (*(S64*)ptr2)--;
+ if (*(S64*)ptr2 == 0)
+ _freeSet(ptr2, key_type);
+ }
+ }
+ if (IsRef(*item_type))
+ {
+ void* ptr2 = *(void**)((U8*)node + 0x20);
+ if (ptr2 != NULL)
+ {
+ (*(S64*)ptr2)--;
+ if (*(S64*)ptr2 == 0)
+ _freeSet(ptr2, item_type);
+ }
+ }
+ FreeMem(node);
+ *deleted = True;
+
+ return NULL;
+ }
+ if (*(void**)((U8*)node + 0x08) == NULL)
+ {
+ *(Bool*)((U8*)*(void**)node + 0x10) = False;
+ *balanced = True;
+ void* result = *(void**)node;
+
+ if (IsRef(*key_type))
+ {
+ void* ptr2 = *(void**)((U8*)node + 0x18);
+ if (ptr2 != NULL)
+ {
+ (*(S64*)ptr2)--;
+ if (*(S64*)ptr2 == 0)
+ _freeSet(ptr2, key_type);
+ }
+ }
+ if (IsRef(*item_type))
+ {
+ void* ptr2 = *(void**)((U8*)node + 0x20);
+ if (ptr2 != NULL)
+ {
+ (*(S64*)ptr2)--;
+ if (*(S64*)ptr2 == 0)
+ _freeSet(ptr2, item_type);
+ }
+ }
+ FreeMem(node);
+ *deleted = True;
+
+ return result;
+ }
+ {
+ void* ptr = *(void**)((U8*)node + 0x08);
+ while (*(void**)ptr != NULL)
+ ptr = *(void**)ptr;
+ *(void**)((U8*)node + 0x18) = NULL;
+ ASSERT(node != ptr);
+ if (IsRef(*key_type))
+ {
+ void* ptr2 = *(void**)((U8*)node + 0x18);
+ if (ptr2 != NULL)
+ {
+ (*(S64*)ptr2)--;
+ if (*(S64*)ptr2 == 0)
+ _freeSet(ptr2, key_type);
+ }
+ }
+ if (IsRef(*item_type))
+ {
+ void* ptr2 = *(void**)((U8*)node + 0x20);
+ if (ptr2 != NULL)
+ {
+ (*(S64*)ptr2)--;
+ if (*(S64*)ptr2 == 0)
+ _freeSet(ptr2, item_type);
+ }
+ }
+ Copy((U8*)node + 0x18, *key_type, (U8*)ptr + 0x18);
+ Copy((U8*)node + 0x20, *item_type, (U8*)ptr + 0x20);
+ }
+ *(void**)((U8*)node + 0x08) = DelDictRecursion(*(void**)((U8*)node + 0x08), *(void**)((U8*)node + 0x18), cmp_func, key_type, item_type, deleted, balanced);
+ return DelDictBalanceRightRecursion(node, balanced);
+ }
+ if (cmp < 0)
+ {
+ *(void**)node = DelDictRecursion(*(void**)node, key, cmp_func, key_type, item_type, deleted, balanced);
+ return DelDictBalanceLeftRecursion(node, balanced);
+ }
+ *(void**)((U8*)node + 0x08) = DelDictRecursion(*(void**)((U8*)node + 0x08), key, cmp_func, key_type, item_type, deleted, balanced);
+ return DelDictBalanceRightRecursion(node, balanced);
+}
+
+static void* DelDictBalanceLeftRecursion(void* node, Bool* balanced)
+{
+ if (balanced)
+ return node;
+ if (*(void**)((U8*)node + 0x08) != NULL && *(void**)*(void**)((U8*)node + 0x08) != NULL && !*(Bool*)((U8*)*(void**)*(void**)((U8*)node + 0x08) + 0x10))
+ {
+ node = DictRotateLeft(node);
+ if (!*(Bool*)((U8*)node + 0x10))
+ return node;
+ *(Bool*)((U8*)node + 0x10) = False;
+ }
+ else
+ {
+ *(void**)((U8*)node + 0x08) = DictRotateRight(*(void**)((U8*)node + 0x08));
+ node = DictRotateLeft(node);
+ *(Bool*)((U8*)*(void**)node + 0x10) = False;
+ *(Bool*)((U8*)*(void**)((U8*)node + 0x08) + 0x10) = False;
+ }
+ *balanced = True;
+ return node;
+}
+
+static void* DelDictBalanceRightRecursion(void* node, Bool* balanced)
+{
+ if (balanced)
+ return node;
+ if (*(void**)node != NULL && *(void**)*(void**)node != NULL && !*(Bool*)((U8*)*(void**)*(void**)node + 0x10))
+ {
+ if (!*(Bool*)((U8*)*(void**)node + 0x10))
+ {
+ *(Bool*)((U8*)*(void**)node + 0x10) = True;
+ if (!*(Bool*)((U8*)node + 0x10))
+ return node;
+ *(Bool*)((U8*)node + 0x10) = False;
+ }
+ else if (*(void**)node != NULL && *(void**)((U8*)*(void**)node + 0x08) != NULL && *(void**)*(void**)((U8*)*(void**)node + 0x08) != NULL && !*(Bool*)((U8*)*(void**)*(void**)((U8*)*(void**)node + 0x08) + 0x10))
+ {
+ node = DictRotateRight(node);
+ *(Bool*)((U8*)*(void**)((U8*)node + 0x08) + 0x10) = False;
+ *(Bool*)((U8*)*(void**)*(void**)((U8*)node + 0x08) + 0x10) = True;
+ }
+ else
+ {
+ *(void**)node = DictRotateLeft(*(void**)node);
+ node = DictRotateRight(node);
+ *(Bool*)((U8*)*(void**)((U8*)node + 0x08) + 0x10) = False;
+ *(Bool*)((U8*)*(void**)((U8*)*(void**)node + 0x08) + 0x10) = False;
+ }
+ }
+ else
+ {
+ node = DictRotateRight(node);
+ *(Bool*)((U8*)*(void**)node + 0x10) = False;
+ *(Bool*)((U8*)*(void**)((U8*)node + 0x08) + 0x10) = False;
+ }
+ *balanced = True;
+ return node;
+}
+
+static void* DictRotateLeft(void* node)
+{
+ void* r = *(void**)((U8*)node + 0x08);
+ *(void**)((U8*)node + 0x08) = *(void**)r;
+ *(void**)r = node;
+ *(Bool*)((U8*)r + 0x10) = *(Bool*)((U8*)node + 0x10);
+ *(Bool*)((U8*)node + 0x10) = True;
+ return r;
+}
+
+static void* DictRotateRight(void* node)
+{
+ void* l = *(void**)node;
+ *(void**)node = *(void**)((U8*)l + 0x08);
+ *(void**)((U8*)l + 0x08) = node;
+ *(Bool*)((U8*)l + 0x10) = *(Bool*)((U8*)node + 0x10);
+ *(Bool*)((U8*)node + 0x10) = True;
+ return l;
+}
+
static void* CopyDictRecursion(void* node, U8* key_type, U8* item_type)
{
U8* result = (U8*)AllocMem(0x20 + GetSize(*item_type));
@@ -3018,7 +3264,7 @@ static void MergeSortArray(void* me_, const U8* type, Bool asc)
S64 i, j;
int(*cmp)(const void* a, const void* b) = GetCmpFunc(type + 1);
if (cmp == NULL)
- THROW(0xe9170004);
+ THROW(EXCPT_INVALID_CMP);
while (n < len)
{
for (i = 0; i < len; i += n * 2)
@@ -3087,7 +3333,7 @@ static void MergeSortList(void* me_, const U8* type, Bool asc)
S64 i, j;
int(*cmp)(const void* a, const void* b) = GetCmpFunc(type + 1);
if (cmp == NULL)
- THROW(0xe9170004);
+ THROW(EXCPT_INVALID_CMP);
{
void* ptr = *(void**)((U8*)me_ + 0x10);
for (i = 0; i < len; i++)
diff --git a/src/lib_common/main.h b/src/lib_common/main.h
index 8512ea68..31b0a6ef 100644
--- a/src/lib_common/main.h
+++ b/src/lib_common/main.h
@@ -55,8 +55,9 @@ EXPORT void _fill(void* me_, const U8* type, const void* value);
EXPORT void* _min(const void* me_, const U8* type);
EXPORT void* _max(const void* me_, const U8* type);
EXPORT void* _repeat(const void* me_, const U8* type, S64 len);
-EXPORT Bool _toInt(const U8* me_, S64* value);
-EXPORT Bool _toFloat(const U8* me_, double* value);
+EXPORT S64 _toInt(const U8* me_, Bool* success);
+EXPORT double _toFloat(const U8* me_, Bool* success);
+EXPORT U64 _toBit64(const U8* me_, Bool* success);
EXPORT void* _lower(const U8* me_);
EXPORT void* _upper(const U8* me_);
EXPORT void* _trim(const U8* me_);
@@ -75,7 +76,7 @@ EXPORT void _addDict(void* me_, const U8* type, const U8* value_type, const void
EXPORT void* _getList(void* me_, const U8* type);
EXPORT void* _getStack(void* me_, const U8* type);
EXPORT void* _getQueue(void* me_, const U8* type);
-EXPORT void* _getDict(void* me_, const U8* type, const void* key);
+EXPORT void* _getDict(void* me_, const U8* type, const void* key, Bool* existed);
EXPORT void* _getOffset(void* me_, const U8* type, S64 offset);
EXPORT void _head(void* me_, const U8* type);
EXPORT void _tail(void* me_, const U8* type);
@@ -93,6 +94,10 @@ EXPORT void* _toArrayValue(void* me_, const U8* type);
EXPORT void* _peek(void* me_, const U8* type);
EXPORT Bool _exist(void* me_, const U8* type, const void* key);
EXPORT Bool _forEach(void* me_, const U8* type, const void* callback, void* data);
+EXPORT void _delDict(void* me_, const U8* type, const void* key);
+EXPORT S64 _idx(void* me_, const U8* type);
+EXPORT SClass* _getPtr(void* me_, const U8* type, SClass* me2);
+EXPORT void _setPtr(void* me_, const U8* type, SClass* ptr);
// Assembly functions.
void* ToBinClassAsm(const void* me_);
diff --git a/src/lib_common/rnd.c b/src/lib_common/rnd.c
index f9f3cf1b..7f70eb97 100644
--- a/src/lib_common/rnd.c
+++ b/src/lib_common/rnd.c
@@ -16,7 +16,7 @@ static void RndDo(S128* r, S128 a, S128 b, S128 c, const S128* d);
EXPORT SClass* _makeRnd(SClass* me_, S64 seed)
{
- THROWDBG(seed < -1 || 0xffffffff < seed, 0xc9170006);
+ THROWDBG(seed < -1 || 0xffffffff < seed, EXCPT_DBG_ARG_OUT_DOMAIN);
SRnd* me2 = (SRnd*)me_;
me2->RndState = (SRndState*)AllocMem(sizeof(SRndState));
if (seed == -1)
@@ -33,14 +33,14 @@ EXPORT void _rndDtor(SClass* me_)
EXPORT S64 _rndRnd(SClass* me_, S64 min, S64 max)
{
- THROWDBG(max - min < 0, 0xe9170006);
+ THROWDBG(max - min < 0, EXCPT_DBG_ARG_OUT_DOMAIN);
SRnd* me2 = (SRnd*)me_;
return RndGet(me2->RndState, min, max);
}
EXPORT double _rndRndFloat(SClass* me_, double min, double max)
{
- THROWDBG(min >= max, 0xe9170006);
+ THROWDBG(min >= max, EXCPT_DBG_ARG_OUT_DOMAIN);
SRnd* me2 = (SRnd*)me_;
return RndGetFloat(me2->RndState, min, max);
}
@@ -51,12 +51,6 @@ EXPORT U64 _rndRndBit64(SClass* me_)
return RndGetBit64(me2->RndState);
}
-EXPORT void* _rndRndUuid(SClass* me_)
-{
- SRnd* me2 = (SRnd*)me_;
- return RndGetUuid(me2->RndState);
-}
-
void InitRndMask(void)
{
RndMask = _mm_set_epi32(0x7ff7fb2f, 0xff777b7d, 0xef7f3f7d, 0xfdff37ff);
@@ -117,21 +111,19 @@ void RndInit(SRndState* rnd_, U32 seed)
S64 RndGet(SRndState* rnd_, S64 min, S64 max)
{
+ U64 n = (U64)(max - min + 1);
+ U64 m = 0 - ((0 - n) % n);
+ U64 r;
+ if (m == 0)
+ r = RndGetBit64(rnd_);
+ else
{
- U64 n = (U64)(max - min + 1);
- U64 m = 0 - ((0 - n) % n);
- U64 r;
- if (m == 0)
- r = RndGetBit64(rnd_);
- else
+ do
{
- do
- {
- r = RndGetBit64(rnd_);
- } while (m <= r);
- }
- return (S64)(r % n) + min;
+ r = RndGetBit64(rnd_);
+ } while (m <= r);
}
+ return (S64)(r % n) + min;
}
double RndGetFloat(SRndState* rnd_, double min, double max)
diff --git a/src/lib_common/rnd.h b/src/lib_common/rnd.h
index 440973ef..38c34e4f 100644
--- a/src/lib_common/rnd.h
+++ b/src/lib_common/rnd.h
@@ -18,7 +18,6 @@ EXPORT void _rndDtor(SClass* me_);
EXPORT S64 _rndRnd(SClass* me_, S64 min, S64 max);
EXPORT double _rndRndFloat(SClass* me_, double min, double max);
EXPORT U64 _rndRndBit64(SClass* me_);
-EXPORT void* _rndRndUuid(SClass* me_);
void InitRndMask(void);
void RndInit(SRndState* rnd_, U32 seed);
S64 RndGet(SRndState* rnd_, S64 min, S64 max);
diff --git a/src/lib_common/task.c b/src/lib_common/task.c
index c498ce01..a2537c3f 100644
--- a/src/lib_common/task.c
+++ b/src/lib_common/task.c
@@ -2,11 +2,16 @@
#include "main.h"
+#include
+#include
+
typedef struct SProcess
{
SClass Class;
HANDLE ProcessHandle;
HANDLE ThreadHandle;
+ HANDLE ReadPipeHandle;
+ HANDLE WritePipeHandle;
} SProcess;
typedef struct SThread
@@ -26,7 +31,7 @@ static DWORD WINAPI ThreadFunc(LPVOID arg);
EXPORT SClass* _makeProcess(SClass* me_, const U8* path, const U8* cmd_line)
{
- THROWDBG(path == NULL, 0xc0000005);
+ THROWDBG(path == NULL, EXCPT_ACCESS_VIOLATION);
SProcess* me2 = (SProcess*)me_;
const Char* path2 = (const Char*)(path + 0x10);
Char cur_dir[KUIN_MAX_PATH + 1];
@@ -42,19 +47,33 @@ EXPORT SClass* _makeProcess(SClass* me_, const U8* path, const U8* cmd_line)
}
if (cmd_line != NULL)
{
+ size_t path_len = wcslen(path2);
size_t len = wcslen((const Char*)(cmd_line + 0x10));
- cmd_line_buf = (Char*)AllocMem(sizeof(Char) * (len + 1));
- wcscpy(cmd_line_buf, (const Char*)(cmd_line + 0x10));
+ cmd_line_buf = (Char*)AllocMem(sizeof(Char) * (path_len + 3 + len + 1));
+ wcscpy(cmd_line_buf, L"\"");
+ wcscat(cmd_line_buf, path2);
+ wcscat(cmd_line_buf, L"\" ");
+ wcscat(cmd_line_buf, (const Char*)(cmd_line + 0x10));
+ }
+ SECURITY_ATTRIBUTES sa = { 0 };
+ sa.bInheritHandle = TRUE;
+ if (!CreatePipe(&me2->ReadPipeHandle, &me2->WritePipeHandle, &sa, 0))
+ {
+ THROW(EXCPT_DEVICE_INIT_FAILED);
+ return NULL;
}
{
PROCESS_INFORMATION process_info;
STARTUPINFO startup_info = { 0 };
startup_info.cb = sizeof(STARTUPINFO);
- if (!CreateProcess(path2, cmd_line_buf, NULL, NULL, FALSE, CREATE_SUSPENDED | NORMAL_PRIORITY_CLASS, NULL, cur_dir, &startup_info, &process_info))
+ startup_info.dwFlags = STARTF_USESTDHANDLES;
+ startup_info.hStdOutput = me2->WritePipeHandle;
+ startup_info.hStdError = me2->WritePipeHandle;
+ if (!CreateProcess(path2, cmd_line_buf, NULL, NULL, TRUE, CREATE_SUSPENDED | NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, NULL, cur_dir, &startup_info, &process_info))
{
if (cmd_line_buf != NULL)
FreeMem(cmd_line_buf);
- THROW(0xe9170009);
+ THROW(EXCPT_DEVICE_INIT_FAILED);
return NULL;
}
me2->ProcessHandle = process_info.hProcess;
@@ -68,6 +87,10 @@ EXPORT SClass* _makeProcess(SClass* me_, const U8* path, const U8* cmd_line)
EXPORT void _processDtor(SClass* me_)
{
SProcess* me2 = (SProcess*)me_;
+ if (me2->WritePipeHandle != NULL)
+ CloseHandle(me2->WritePipeHandle);
+ if (me2->ReadPipeHandle != NULL)
+ CloseHandle(me2->ReadPipeHandle);
if (me2->ThreadHandle != NULL)
CloseHandle(me2->ThreadHandle);
if (me2->ProcessHandle != NULL)
@@ -77,21 +100,81 @@ EXPORT void _processDtor(SClass* me_)
EXPORT S64 _processRun(SClass* me_, Bool wait_until_exit)
{
SProcess* me2 = (SProcess*)me_;
+ if (me2->ProcessHandle == NULL)
+ return 0;
DWORD exit_code = 0;
if (ResumeThread(me2->ThreadHandle) == (DWORD)-1)
- THROW(0xe9170009);
+ THROW(EXCPT_DEVICE_INIT_FAILED);
if (wait_until_exit)
{
- if (WaitForSingleObject(me2->ProcessHandle, INFINITE) == WAIT_FAILED)
- THROW(0xe9170009);
+ if (WaitForSingleObject(me2->ProcessHandle, INFINITE) != WAIT_OBJECT_0)
+ THROW(EXCPT_DEVICE_INIT_FAILED);
if (!GetExitCodeProcess(me2->ProcessHandle, &exit_code))
- THROW(0xe9170009);
+ THROW(EXCPT_DEVICE_INIT_FAILED);
}
+ return (S64)(S32)exit_code;
+}
+
+EXPORT void _processFin(SClass* me_)
+{
+ SProcess* me2 = (SProcess*)me_;
+ if (me2->ProcessHandle == NULL)
+ return;
+ TerminateProcess(me2->ProcessHandle, 0);
+ CloseHandle(me2->WritePipeHandle);
+ CloseHandle(me2->ReadPipeHandle);
CloseHandle(me2->ThreadHandle);
CloseHandle(me2->ProcessHandle);
+ me2->WritePipeHandle = NULL;
+ me2->ReadPipeHandle = NULL;
me2->ThreadHandle = NULL;
me2->ProcessHandle = NULL;
- return (S64)(S32)exit_code;
+}
+
+EXPORT Bool _processRunning(SClass* me_, S64* exit_code)
+{
+ *exit_code = 0;
+ SProcess* me2 = (SProcess*)me_;
+ if (me2->ProcessHandle == NULL)
+ return False;
+ DWORD dword_exit_code;
+ if (!GetExitCodeProcess(me2->ProcessHandle, &dword_exit_code))
+ return False;
+ if (dword_exit_code == STILL_ACTIVE)
+ return True;
+ *exit_code = (S64)dword_exit_code;
+ return False;
+}
+
+EXPORT void* _processReadPipe(SClass* me_)
+{
+ SProcess* me2 = (SProcess*)me_;
+ if (me2->ProcessHandle == NULL)
+ return NULL;
+ DWORD size;
+ if (!PeekNamedPipe(me2->ReadPipeHandle, NULL, 0, NULL, &size, NULL) || size == 0)
+ return NULL;
+ U8* buf_tmp = (U8*)AllocMem((size_t)size);
+ DWORD read_size;
+ if (!ReadFile(me2->ReadPipeHandle, buf_tmp, size, &read_size, NULL))
+ {
+ FreeMem(buf_tmp);
+ return NULL;
+ }
+
+ size_t len = (size_t)MultiByteToWideChar(CP_ACP, 0, (char*)buf_tmp, read_size, NULL, 0);
+ Char* result = (Char*)AllocMem(0x10 + sizeof(Char) * (len + 1));
+ ((S64*)result)[0] = DefaultRefCntFunc;
+ ((S64*)result)[1] = (S64)len;
+ if (MultiByteToWideChar(CP_ACP, 0, (char*)buf_tmp, read_size, (Char*)((U8*)result + 0x10), (int)len) != (int)len)
+ {
+ FreeMem(buf_tmp);
+ FreeMem(result);
+ return NULL;
+ }
+ ((Char*)((U8*)result + 0x10))[len] = L'\0';
+ FreeMem(buf_tmp);
+ return result;
}
EXPORT void _taskOpen(const U8* path)
@@ -106,18 +189,18 @@ EXPORT void _taskOpen(const U8* path)
*(ptr + 1) = L'\0';
}
if ((U64)ShellExecute(NULL, L"open", path2, NULL, cur_dir, SW_SHOWNORMAL) <= 32)
- THROW(0xe9170009);
+ THROW(EXCPT_DEVICE_INIT_FAILED);
}
EXPORT SClass* _makeThread(SClass* me_, const void* thread_func)
{
- THROWDBG(thread_func == NULL, 0xc0000005);
+ THROWDBG(thread_func == NULL, EXCPT_ACCESS_VIOLATION);
SThread* me2 = (SThread*)me_;
me2->Begin = False;
me2->ThreadHandle = CreateThread(NULL, 0, ThreadFunc, (LPVOID)thread_func, CREATE_SUSPENDED, NULL);
if (me2->ThreadHandle == NULL)
{
- THROW(0xe9170009);
+ THROW(EXCPT_DEVICE_INIT_FAILED);
return NULL;
}
return me_;
@@ -135,7 +218,7 @@ EXPORT void _threadRun(SClass* me_)
SThread* me2 = (SThread*)me_;
me2->Begin = True;
if (ResumeThread(me2->ThreadHandle) == (DWORD)-1)
- THROW(0xe9170009);
+ THROW(EXCPT_DEVICE_INIT_FAILED);
}
EXPORT Bool _threadRunning(SClass* me_)
diff --git a/src/lib_common/task.h b/src/lib_common/task.h
index ad30fec4..fc1f5e93 100644
--- a/src/lib_common/task.h
+++ b/src/lib_common/task.h
@@ -6,6 +6,9 @@
EXPORT SClass* _makeProcess(SClass* me_, const U8* path, const U8* cmd_line);
EXPORT void _processDtor(SClass* me_);
EXPORT S64 _processRun(SClass* me_, Bool wait_until_exit);
+EXPORT void _processFin(SClass* me_);
+EXPORT Bool _processRunning(SClass* me_, S64* exit_code);
+EXPORT void* _processReadPipe(SClass* me_);
EXPORT void _taskOpen(const U8* path);
EXPORT SClass* _makeThread(SClass* me_, const void* thread_func);
EXPORT void _threadDtor(SClass* me_);
diff --git a/src/lib_common/time.c b/src/lib_common/time.c
index c41f8593..e695002a 100644
--- a/src/lib_common/time.c
+++ b/src/lib_common/time.c
@@ -26,12 +26,12 @@ EXPORT S64 _intToDate(S64 time, S64* year, S64* month, S64* day, S64* hour, S64*
EXPORT S64 _dateToInt(S64 year, S64 month, S64 day, S64 hour, S64 minute, S64 second)
{
- THROWDBG(year < 1970 || 3000 < year, 0xe9170006);
- THROWDBG(month < 1 || 12 < month, 0xe9170006);
- THROWDBG(day < 1 || 31 < day, 0xe9170006);
- THROWDBG(hour < 0 || 23 < hour, 0xe9170006);
- THROWDBG(minute < 0 || 59 < minute, 0xe9170006);
- THROWDBG(second < 0 || 59 < second, 0xe9170006);
+ THROWDBG(year < 1970 || 3000 < year, EXCPT_DBG_ARG_OUT_DOMAIN);
+ THROWDBG(month < 1 || 12 < month, EXCPT_DBG_ARG_OUT_DOMAIN);
+ THROWDBG(day < 1 || 31 < day, EXCPT_DBG_ARG_OUT_DOMAIN);
+ THROWDBG(hour < 0 || 23 < hour, EXCPT_DBG_ARG_OUT_DOMAIN);
+ THROWDBG(minute < 0 || 59 < minute, EXCPT_DBG_ARG_OUT_DOMAIN);
+ THROWDBG(second < 0 || 59 < second, EXCPT_DBG_ARG_OUT_DOMAIN);
struct tm t;
t.tm_year = (int)year - 1900;
t.tm_mon = (int)month - 1;
@@ -40,7 +40,7 @@ EXPORT S64 _dateToInt(S64 year, S64 month, S64 day, S64 hour, S64 minute, S64 se
t.tm_min = (int)minute;
t.tm_sec = (int)second;
S64 result = _mkgmtime64(&t);
- THROWDBG(result == -1, 0xe9170006);
+ THROWDBG(result == -1, EXCPT_DBG_ARG_OUT_DOMAIN);
return result;
}
@@ -60,12 +60,12 @@ EXPORT S64 _intToLocalDate(S64 time, S64* year, S64* month, S64* day, S64* hour,
EXPORT S64 _localDateToInt(S64 year, S64 month, S64 day, S64 hour, S64 minute, S64 second)
{
- THROWDBG(year < 1970 || 3000 < year, 0xe9170006);
- THROWDBG(month < 1 || 12 < month, 0xe9170006);
- THROWDBG(day < 1 || 31 < day, 0xe9170006);
- THROWDBG(hour < 0 || 23 < hour, 0xe9170006);
- THROWDBG(minute < 0 || 59 < minute, 0xe9170006);
- THROWDBG(second < 0 || 59 < second, 0xe9170006);
+ THROWDBG(year < 1970 || 3000 < year, EXCPT_DBG_ARG_OUT_DOMAIN);
+ THROWDBG(month < 1 || 12 < month, EXCPT_DBG_ARG_OUT_DOMAIN);
+ THROWDBG(day < 1 || 31 < day, EXCPT_DBG_ARG_OUT_DOMAIN);
+ THROWDBG(hour < 0 || 23 < hour, EXCPT_DBG_ARG_OUT_DOMAIN);
+ THROWDBG(minute < 0 || 59 < minute, EXCPT_DBG_ARG_OUT_DOMAIN);
+ THROWDBG(second < 0 || 59 < second, EXCPT_DBG_ARG_OUT_DOMAIN);
struct tm t;
t.tm_year = (int)year - 1900;
t.tm_mon = (int)month - 1;
@@ -74,11 +74,12 @@ EXPORT S64 _localDateToInt(S64 year, S64 month, S64 day, S64 hour, S64 minute, S
t.tm_min = (int)minute;
t.tm_sec = (int)second;
S64 result = _mktime64(&t);
- THROWDBG(result == -1, 0xe9170006);
+ THROWDBG(result == -1, EXCPT_DBG_ARG_OUT_DOMAIN);
return result;
}
EXPORT void sleep(S64 ms)
{
+ THROWDBG(ms < 0 || ms >= INFINITE, EXCPT_DBG_ARG_OUT_DOMAIN);
Sleep((DWORD)ms);
}
diff --git a/src/lib_cui/cui.c b/src/lib_cui/cui.c
index d2d491ca..4ffc903c 100644
--- a/src/lib_cui/cui.c
+++ b/src/lib_cui/cui.c
@@ -1,6 +1,22 @@
#include "cui.h"
-#define INPUT_SIZE (1024)
+static S64 DelimiterNum;
+static Char* Delimiters;
+
+static Char ReadIo(void);
+
+EXPORT void _delimiter(const U8* delimiters)
+{
+ THROWDBG(delimiters == NULL, EXCPT_ACCESS_VIOLATION);
+ S64 len = *(S64*)(delimiters + 0x08);
+ S64 i;
+ const Char* ptr = (const Char*)(delimiters + 0x10);
+ FreeMem(Delimiters);
+ DelimiterNum = len;
+ Delimiters = (Char*)AllocMem(sizeof(Char) * (size_t)len);
+ for (i = 0; i < len; i++)
+ Delimiters[i] = ptr[i];
+}
EXPORT void _print(const U8* str)
{
@@ -15,23 +31,237 @@ EXPORT void _print(const U8* str)
#endif
}
+EXPORT void _flush(void)
+{
+ fflush(stdout);
+}
+
+EXPORT Char _inputLetter(void)
+{
+ Char c = fgetwc(stdin);
+ if (c == WEOF)
+ THROW(EXCPT_INVALID_DATA_FMT);
+ return c;
+}
+
+EXPORT S64 _inputInt(void)
+{
+ Char buf[33];
+ int ptr = 0;
+ buf[0] = L'\0';
+ for (; ; )
+ {
+ Char c = ReadIo();
+ if (c == L'\r')
+ continue;
+ if (c == WEOF)
+ {
+ if (buf[0] == L'\0')
+ THROW(EXCPT_INVALID_DATA_FMT);
+ break;
+ }
+ if (c == L'\0')
+ {
+ if (buf[0] == L'\0')
+ continue;
+ break;
+ }
+ if (ptr == 32)
+ THROW(EXCPT_INVALID_DATA_FMT);
+ buf[ptr] = c;
+ ptr++;
+ }
+ buf[ptr] = L'\0';
+ {
+ S64 result;
+ Char* ptr2;
+ result = wcstoll(buf, &ptr2, 10);
+ if (*ptr2 != L'\0')
+ THROW(EXCPT_INVALID_DATA_FMT);
+ return result;
+ }
+}
+
+EXPORT double _inputFloat(void)
+{
+ Char buf[33];
+ int ptr = 0;
+ buf[0] = L'\0';
+ for (; ; )
+ {
+ Char c = ReadIo();
+ if (c == L'\r')
+ continue;
+ if (c == WEOF)
+ {
+ if (buf[0] == L'\0')
+ THROW(EXCPT_INVALID_DATA_FMT);
+ break;
+ }
+ if (c == L'\0')
+ {
+ if (buf[0] == L'\0')
+ continue;
+ break;
+ }
+ if (ptr == 32)
+ THROW(EXCPT_INVALID_DATA_FMT);
+ buf[ptr] = c;
+ ptr++;
+ }
+ buf[ptr] = L'\0';
+ {
+ double result;
+ Char* ptr2;
+ result = wcstod(buf, &ptr2);
+ if (*ptr2 != L'\0')
+ THROW(EXCPT_INVALID_DATA_FMT);
+ return result;
+ }
+}
+
+EXPORT Char _inputChar(void)
+{
+ Char c = L'\0';
+ for (; ; )
+ {
+ c = ReadIo();
+ if (c == L'\r')
+ continue;
+ if (c == WEOF)
+ THROW(EXCPT_INVALID_DATA_FMT);
+ if (c != L'\0')
+ break;
+ }
+ return c;
+}
+
+EXPORT void* _inputStr(void)
+{
+ Char stack_buf[STACK_STRING_BUF_SIZE];
+ Char* buf = stack_buf;
+ size_t buf_len = STACK_STRING_BUF_SIZE;
+ size_t len = 0;
+ buf[0] = L'\0';
+ for (; ; )
+ {
+ Char c = ReadIo();
+ if (c == L'\r')
+ continue;
+ if (c == WEOF)
+ {
+ if (buf[0] == L'\0')
+ THROW(EXCPT_INVALID_DATA_FMT);
+ break;
+ }
+ if (c == L'\0')
+ {
+ if (buf[0] == L'\0')
+ continue;
+ break;
+ }
+ buf[len] = c;
+ len++;
+ if (len == buf_len)
+ {
+ buf_len += STACK_STRING_BUF_SIZE;
+ Char* tmp = (Char*)ReAllocMem(buf == stack_buf ? NULL : buf, sizeof(Char) * buf_len);
+ if (tmp == NULL)
+ {
+ if (buf != stack_buf)
+ FreeMem(buf);
+ return NULL;
+ }
+ if (buf == stack_buf)
+ memcpy(tmp, buf, sizeof(Char) * len);
+ buf = tmp;
+ }
+ }
+ buf[len] = L'\0';
+ {
+ U8* result = (U8*)AllocMem(0x10 + sizeof(Char) * ((size_t)len + 1));
+ *(S64*)(result + 0x00) = DefaultRefCntFunc;
+ *(S64*)(result + 0x08) = (S64)len;
+ memcpy(result + 0x10, buf, sizeof(Char) * (len + 1));
+ if (buf != stack_buf)
+ FreeMem(buf);
+ return result;
+ }
+}
+
EXPORT void* _input(void)
{
- Char buf[INPUT_SIZE];
- if (fgetws(buf, INPUT_SIZE, stdin) == NULL)
- buf[0] = L'\0';
+ Char stack_buf[STACK_STRING_BUF_SIZE];
+ Char* buf = stack_buf;
+ size_t buf_len = STACK_STRING_BUF_SIZE;
+ size_t len = 0;
+ for (; ; )
{
- size_t len = wcslen(buf);
- U8* result;
- if (len > 0 && buf[len - 1] == L'\n')
+ Char c = fgetwc(stdin);
+ if (c == L'\r')
+ continue;
+ if (c == WEOF)
+ break;
+ if (c == L'\n')
+ break;
+ buf[len] = c;
+ len++;
+ if (len == buf_len)
{
- buf[len - 1] = L'\0';
- len--;
+ buf_len += STACK_STRING_BUF_SIZE;
+ Char* tmp = (Char*)ReAllocMem(buf == stack_buf ? NULL : buf, sizeof(Char) * buf_len);
+ if (tmp == NULL)
+ {
+ if (buf != stack_buf)
+ FreeMem(buf);
+ return NULL;
+ }
+ if (buf == stack_buf)
+ memcpy(tmp, buf, sizeof(Char) * len);
+ buf = tmp;
}
- result = (U8*)AllocMem(0x10 + sizeof(Char) * (len + 1));
+ }
+ buf[len] = L'\0';
+ {
+ U8* result = (U8*)AllocMem(0x10 + sizeof(Char) * (len + 1));
((S64*)result)[0] = DefaultRefCntFunc;
((S64*)result)[1] = (S64)len;
memcpy(result + 0x10, buf, sizeof(Char) * (len + 1));
+ if (buf != stack_buf)
+ FreeMem(buf);
return result;
}
}
+
+void InitCui(void)
+{
+ DelimiterNum = 3;
+ Delimiters = (Char*)AllocMem(sizeof(Char) * 3);
+ Delimiters[0] = L'\n';
+ Delimiters[1] = L' ';
+ Delimiters[2] = L',';
+}
+
+void FinCui(void)
+{
+ FreeMem(Delimiters);
+#if defined(DBG)
+ system("pause");
+#endif
+}
+
+static Char ReadIo(void)
+{
+ Char c = fgetwc(stdin);
+ if (c == L'\0')
+ return L'\0';
+ {
+ S64 i;
+ for (i = 0; i < DelimiterNum; i++)
+ {
+ if (c == Delimiters[i] || c == L'\r' && Delimiters[i] == L'\n')
+ return L'\0';
+ }
+ }
+ return c;
+}
diff --git a/src/lib_cui/cui.h b/src/lib_cui/cui.h
index ef3a4588..16f8b321 100644
--- a/src/lib_cui/cui.h
+++ b/src/lib_cui/cui.h
@@ -2,5 +2,16 @@
#include "..\common.h"
+// 'cui'
+EXPORT void _delimiter(const U8* delimiters);
EXPORT void _print(const U8* str);
+EXPORT void _flush(void);
+EXPORT Char _inputLetter(void);
+EXPORT S64 _inputInt(void);
+EXPORT double _inputFloat(void);
+EXPORT Char _inputChar(void);
+EXPORT void* _inputStr(void);
EXPORT void* _input(void);
+
+void InitCui(void);
+void FinCui(void);
diff --git a/src/lib_cui/main.c b/src/lib_cui/main.c
index 5aac6d64..d3371563 100644
--- a/src/lib_cui/main.c
+++ b/src/lib_cui/main.c
@@ -4,6 +4,7 @@
//
#include "main.h"
+#include "cui.h"
#include
#include
@@ -18,17 +19,17 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
EXPORT void _init(void* heap, S64* heap_cnt, S64 app_code, const U8* use_res_flags)
{
- Heap = heap;
- HeapCnt = heap_cnt;
- AppCode = app_code;
- UseResFlags = use_res_flags;
- Instance = (HINSTANCE)GetModuleHandle(NULL);
+ if (!InitEnvVars(heap, heap_cnt, app_code, use_res_flags))
+ return;
wprintf(L""); // Open 'stdout'
_setmode(_fileno(stdin), _O_U8TEXT); // Set the input format to UTF-8.
_setmode(_fileno(stdout), _O_U8TEXT); // Set the output format to UTF-8.
+
+ InitCui();
}
EXPORT void _fin(void)
{
+ FinCui();
}
diff --git a/src/lib_draw2d/lib_draw2d.sln b/src/lib_draw2d/lib_draw2d.sln
new file mode 100644
index 00000000..bb62870c
--- /dev/null
+++ b/src/lib_draw2d/lib_draw2d.sln
@@ -0,0 +1,28 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.24720.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_draw2d", "lib_draw2d.vcxproj", "{9136E651-D063-49FD-AD03-4F21EC347407}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {9136E651-D063-49FD-AD03-4F21EC347407}.Debug|x64.ActiveCfg = Debug|x64
+ {9136E651-D063-49FD-AD03-4F21EC347407}.Debug|x64.Build.0 = Debug|x64
+ {9136E651-D063-49FD-AD03-4F21EC347407}.Debug|x86.ActiveCfg = Debug|Win32
+ {9136E651-D063-49FD-AD03-4F21EC347407}.Debug|x86.Build.0 = Debug|Win32
+ {9136E651-D063-49FD-AD03-4F21EC347407}.Release|x64.ActiveCfg = Release|x64
+ {9136E651-D063-49FD-AD03-4F21EC347407}.Release|x64.Build.0 = Release|x64
+ {9136E651-D063-49FD-AD03-4F21EC347407}.Release|x86.ActiveCfg = Release|Win32
+ {9136E651-D063-49FD-AD03-4F21EC347407}.Release|x86.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/src/lib_draw2d/lib_draw2d.vcxproj b/src/lib_draw2d/lib_draw2d.vcxproj
new file mode 100644
index 00000000..2c556d7f
--- /dev/null
+++ b/src/lib_draw2d/lib_draw2d.vcxproj
@@ -0,0 +1,144 @@
+
+
+
+
+ Debug
+ x64
+
+
+ Release_dbg
+ x64
+
+
+ Release_rls
+ x64
+
+
+
+ {9136E651-D063-49FD-AD03-4F21EC347407}
+ Win32Proj
+ lib_draw2d
+ 8.1
+
+
+
+ DynamicLibrary
+ true
+ v140
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v140
+ true
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v140
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)src\output\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)src\output\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)src\output\$(Platform)\$(Configuration)\
+
+
+
+
+
+ Level4
+ Disabled
+ DBG;_DEBUG;_WINDOWS;_USRDLL;LIB_WND_EXPORTS;%(PreprocessorDefinitions)
+ CompileAsCpp
+ MultiThreadedDebug
+
+
+ Windows
+ true
+
+
+ echo F | xcopy /y /r $(TargetPath) $(SolutionDir)test\output\data\d0005.knd
+
+
+
+
+ Level4
+
+
+ MaxSpeed
+ true
+ true
+ NDEBUG;_WINDOWS;_USRDLL;LIB_WND_EXPORTS;%(PreprocessorDefinitions)
+ CompileAsCpp
+ MultiThreaded
+
+
+ Windows
+ true
+ true
+ false
+
+
+ echo F | xcopy /y /r $(TargetPath) $(SolutionDir)package\sys\rls\d0005.knd
+
+
+
+
+ Level4
+
+
+ MaxSpeed
+ true
+ true
+ DBG;NDEBUG;_WINDOWS;_USRDLL;LIB_WND_EXPORTS;%(PreprocessorDefinitions)
+ CompileAsCpp
+ MultiThreaded
+
+
+ Windows
+ true
+ true
+ false
+
+
+ echo F | xcopy /y /r $(TargetPath) $(SolutionDir)package\sys\dbg\d0005.knd
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/lib_draw2d/lib_draw2d.vcxproj.filters b/src/lib_draw2d/lib_draw2d.vcxproj.filters
new file mode 100644
index 00000000..4a5a28bf
--- /dev/null
+++ b/src/lib_draw2d/lib_draw2d.vcxproj.filters
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/lib_draw2d/main.cpp b/src/lib_draw2d/main.cpp
new file mode 100644
index 00000000..0c2fc20d
--- /dev/null
+++ b/src/lib_draw2d/main.cpp
@@ -0,0 +1,349 @@
+// LibDraw2d.dll
+//
+// (C)Kuina-chan
+//
+
+#include "main.h"
+
+#include
+
+#pragma comment(lib, "d2d1.lib")
+#pragma comment(lib, "dxgi.lib")
+
+struct S2dBuf
+{
+ IDXGISurface* Surface;
+ ID2D1RenderTarget* RenderTarget;
+};
+
+struct SWndBuf
+{
+ S2dBuf* Extra;
+};
+
+struct SBrush
+{
+ SClass Class;
+ ID2D1Brush* Brush;
+};
+
+struct SBrushLinearGradient
+{
+ SClass Class;
+ ID2D1LinearGradientBrush* Brush;
+};
+
+struct SStrokeStyle
+{
+ SClass Class;
+ ID2D1StrokeStyle* StrokeStyle;
+};
+
+struct SGeometry
+{
+ SClass Class;
+ ID2D1Geometry* Geometry;
+};
+
+struct SGeometryPath
+{
+ SClass Class;
+ ID2D1PathGeometry* Geometry;
+ ID2D1GeometrySink* Sink;
+};
+
+static ID2D1Factory* Factory = NULL;
+static HMODULE D0001Handle = NULL;
+static ID2D1RenderTarget* CurRenderTarget = NULL;
+static Bool Opened;
+
+static void* Callback2d(int kind, void* arg1, void* arg2);
+static D2D1::ColorF ColorToColorF(S64 color);
+static double Gamma(double value);
+
+BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
+{
+ UNUSED(hinst);
+ UNUSED(reason);
+ UNUSED(reserved);
+ return TRUE;
+}
+
+EXPORT_CPP void _init(void* heap, S64* heap_cnt, S64 app_code, const U8* use_res_flags)
+{
+ if (!InitEnvVars(heap, heap_cnt, app_code, use_res_flags))
+ return;
+
+ if (FAILED(D2D1CreateFactory(D2D1_FACTORY_TYPE::D2D1_FACTORY_TYPE_SINGLE_THREADED, &Factory)))
+ THROW(EXCPT_DEVICE_INIT_FAILED);
+
+ D0001Handle = LoadLibrary(L"data/d0001.knd");
+ if (D0001Handle == NULL)
+ THROW(EXCPT_FILE_READ_FAILED);
+
+ ((void(*)(void*(*callback)(int, void*, void*)))GetProcAddress(D0001Handle, "_set2dCallback"))(Callback2d);
+}
+
+EXPORT_CPP void _fin()
+{
+ if (D0001Handle != NULL)
+ FreeLibrary(D0001Handle);
+ if (Factory != NULL)
+ Factory->Release();
+}
+
+EXPORT_CPP void _line(double x1, double y1, double x2, double y2, double stroke_width, S64 color)
+{
+ ID2D1SolidColorBrush* brush;
+ CurRenderTarget->CreateSolidColorBrush(ColorToColorF(color), &brush);
+ CurRenderTarget->DrawLine(D2D1::Point2F(static_cast(x1), static_cast(y1)), D2D1::Point2F(static_cast(x2), static_cast(y2)), brush, static_cast(stroke_width), NULL);
+ brush->Release();
+ CurRenderTarget->Flush();
+}
+
+EXPORT_CPP void _rect(double x, double y, double width, double height, S64 color)
+{
+ ID2D1SolidColorBrush* brush;
+ CurRenderTarget->CreateSolidColorBrush(ColorToColorF(color), &brush);
+ CurRenderTarget->FillRectangle(D2D1::RectF(static_cast(x), static_cast(y), static_cast(x + width), static_cast(y + height)), brush);
+ brush->Release();
+ CurRenderTarget->Flush();
+}
+
+EXPORT_CPP void _rectLine(double x, double y, double width, double height, double stroke_width, S64 color)
+{
+ ID2D1SolidColorBrush* brush;
+ CurRenderTarget->CreateSolidColorBrush(ColorToColorF(color), &brush);
+ CurRenderTarget->DrawRectangle(D2D1::RectF(static_cast(x), static_cast(y), static_cast(x + width), static_cast(y + height)), brush, static_cast(stroke_width), NULL);
+ brush->Release();
+ CurRenderTarget->Flush();
+}
+
+EXPORT_CPP void _circle(double x, double y, double radius_x, double radius_y, S64 color)
+{
+ ID2D1SolidColorBrush* brush;
+ CurRenderTarget->CreateSolidColorBrush(ColorToColorF(color), &brush);
+ CurRenderTarget->FillEllipse(D2D1::Ellipse(D2D1::Point2F(static_cast(x), static_cast(y)), static_cast(radius_x), static_cast(radius_y)), brush);
+ brush->Release();
+ CurRenderTarget->Flush();
+}
+
+EXPORT_CPP void _circleLine(double x, double y, double radius_x, double radius_y, double stroke_width, S64 color)
+{
+ ID2D1SolidColorBrush* brush;
+ CurRenderTarget->CreateSolidColorBrush(ColorToColorF(color), &brush);
+ CurRenderTarget->DrawEllipse(D2D1::Ellipse(D2D1::Point2F(static_cast(x), static_cast(y)), static_cast(radius_x), static_cast(radius_y)), brush, static_cast(stroke_width), NULL);
+ brush->Release();
+ CurRenderTarget->Flush();
+}
+
+EXPORT_CPP void _roundRect(double x, double y, double width, double height, double radius_x, double radius_y, S64 color)
+{
+ ID2D1SolidColorBrush* brush;
+ CurRenderTarget->CreateSolidColorBrush(ColorToColorF(color), &brush);
+ CurRenderTarget->FillRoundedRectangle(D2D1::RoundedRect(D2D1::RectF(static_cast(x), static_cast(y), static_cast(x + width), static_cast(y + height)), static_cast(radius_x), static_cast(radius_y)), brush);
+ brush->Release();
+ CurRenderTarget->Flush();
+}
+
+EXPORT_CPP void _roundRectLine(double x, double y, double width, double height, double radius_x, double radius_y, double stroke_width, S64 color)
+{
+ ID2D1SolidColorBrush* brush;
+ CurRenderTarget->CreateSolidColorBrush(ColorToColorF(color), &brush);
+ CurRenderTarget->DrawRoundedRectangle(D2D1::RoundedRect(D2D1::RectF(static_cast(x), static_cast(y), static_cast(x + width), static_cast(y + height)), static_cast(radius_x), static_cast(radius_y)), brush, static_cast(stroke_width), NULL);
+ brush->Release();
+ CurRenderTarget->Flush();
+}
+
+EXPORT_CPP void _tri(double x1, double y1, double x2, double y2, double x3, double y3, S64 color)
+{
+ ID2D1SolidColorBrush* brush = NULL;
+ ID2D1PathGeometry* geometry = NULL;
+ ID2D1GeometrySink* sink = NULL;
+ CurRenderTarget->CreateSolidColorBrush(ColorToColorF(color), &brush);
+ Factory->CreatePathGeometry(&geometry);
+ geometry->Open(&sink);
+ sink->BeginFigure(D2D1::Point2F(static_cast(x1), static_cast(y1)), D2D1_FIGURE_BEGIN_FILLED);
+ sink->AddLine(D2D1::Point2F(static_cast(x2), static_cast(y2)));
+ sink->AddLine(D2D1::Point2F(static_cast(x3), static_cast(y3)));
+ sink->EndFigure(D2D1_FIGURE_END_CLOSED);
+ sink->Close();
+ CurRenderTarget->FillGeometry(geometry, brush);
+ sink->Release();
+ geometry->Release();
+ brush->Release();
+ CurRenderTarget->Flush();
+}
+
+EXPORT_CPP SClass* _makeBrushLinearGradient(SClass* me_, double x1, double y1, double x2, double y2, void* color_position, void* color)
+{
+ SBrushLinearGradient* me2 = reinterpret_cast(me_);
+ S64 len_pos = static_cast(color_position)[1];
+ S64 len_color = static_cast(color)[1];
+ THROWDBG(len_pos != len_color, EXCPT_DBG_ARG_OUT_DOMAIN);
+ ID2D1GradientStopCollection* gradient_stop_collection = NULL;
+ D2D1_GRADIENT_STOP* gradient_stops = static_cast(AllocMem(sizeof(D2D1_GRADIENT_STOP) * len_pos));
+ for (S64 i = 0; i < len_pos; i++)
+ {
+ gradient_stops[i].color = ColorToColorF(static_cast(color)[i + 2]);
+ gradient_stops[i].position = static_cast(static_cast(color_position)[i + 2]);
+ }
+ CurRenderTarget->CreateGradientStopCollection(gradient_stops, static_cast(len_pos), &gradient_stop_collection);
+ FreeMem(gradient_stops);
+ CurRenderTarget->CreateLinearGradientBrush(D2D1::LinearGradientBrushProperties(D2D1::Point2F(static_cast(x1), static_cast(y1)), D2D1::Point2F(static_cast(x2), static_cast(y2))), gradient_stop_collection, &me2->Brush);
+ return me_;
+}
+
+EXPORT_CPP void _brushLinearGradientDtor(SClass* me_)
+{
+ SBrushLinearGradient* me2 = reinterpret_cast(me_);
+ me2->Brush->Release();
+}
+
+EXPORT_CPP void _brushLine(SClass* me_, double x1, double y1, double x2, double y2, double stroke_width, SClass* stroke_style)
+{
+ SBrush* me2 = reinterpret_cast(me_);
+ SStrokeStyle* strokeStyle2 = reinterpret_cast(stroke_style);
+ CurRenderTarget->DrawLine(D2D1::Point2F(static_cast(x1), static_cast(y1)), D2D1::Point2F(static_cast(x2), static_cast(y2)), me2->Brush, static_cast(stroke_width), stroke_style != NULL ? strokeStyle2->StrokeStyle : NULL);
+ CurRenderTarget->Flush();
+}
+
+EXPORT_CPP SClass* _makeGeometryPath(SClass* me_)
+{
+ SGeometryPath* me2 = reinterpret_cast(me_);
+ Factory->CreatePathGeometry(&me2->Geometry);
+ me2->Sink = NULL;
+ return me_;
+}
+
+EXPORT_CPP void _geometryPathDtor(SClass* me_)
+{
+ SGeometryPath* me2 = reinterpret_cast(me_);
+ if (me2->Sink != NULL)
+ me2->Sink->Release();
+ me2->Geometry->Release();
+}
+
+EXPORT_CPP void _geometryPathOpen(SClass* me_)
+{
+ SGeometryPath* me2 = reinterpret_cast(me_);
+ me2->Geometry->Open(&me2->Sink);
+}
+
+EXPORT_CPP void _geometryPathClose(SClass* me_)
+{
+ SGeometryPath* me2 = reinterpret_cast(me_);
+ me2->Sink->Close();
+}
+
+EXPORT_CPP void _geometryPathOpenFigure(SClass* me_, double x, double y, Bool filled)
+{
+ SGeometryPath* me2 = reinterpret_cast(me_);
+ me2->Sink->BeginFigure(D2D1::Point2F(static_cast(x), static_cast(y)), filled ? D2D1_FIGURE_BEGIN_FILLED : D2D1_FIGURE_BEGIN_HOLLOW);
+}
+
+EXPORT_CPP void _geometryPathCloseFigure(SClass* me_, Bool closed_path)
+{
+ SGeometryPath* me2 = reinterpret_cast(me_);
+ me2->Sink->EndFigure(closed_path ? D2D1_FIGURE_END_CLOSED : D2D1_FIGURE_END_OPEN);
+}
+
+EXPORT_CPP void _geometryPathAddArc(SClass* me_, double x, double y, double radius_x, double radius_y, double angle, Bool ccw, Bool large_arc)
+{
+ SGeometryPath* me2 = reinterpret_cast(me_);
+ me2->Sink->AddArc(D2D1::ArcSegment(D2D1::Point2F(static_cast(x), static_cast(y)), D2D1::SizeF(static_cast(radius_x), static_cast(radius_y)), static_cast(angle), ccw ? D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE : D2D1_SWEEP_DIRECTION_CLOCKWISE, large_arc ? D2D1_ARC_SIZE_LARGE : D2D1_ARC_SIZE_SMALL));
+}
+
+EXPORT_CPP void _geometryPathAddBezier(SClass* me_, double x1, double y1, double x2, double y2, double x3, double y3)
+{
+ SGeometryPath* me2 = reinterpret_cast(me_);
+ me2->Sink->AddBezier(D2D1::BezierSegment(D2D1::Point2F(static_cast(x1), static_cast(y1)), D2D1::Point2F(static_cast(x2), static_cast(y2)), D2D1::Point2F(static_cast(x3), static_cast(y3))));
+}
+
+EXPORT_CPP void _geometryPathAddLine(SClass* me_, double x, double y)
+{
+ SGeometryPath* me2 = reinterpret_cast(me_);
+ me2->Sink->AddLine(D2D1::Point2F(static_cast(x), static_cast(y)));
+}
+
+EXPORT_CPP void _geometryPathAddQuadraticBezier(SClass* me_, double x1, double y1, double x2, double y2)
+{
+ SGeometryPath* me2 = reinterpret_cast(me_);
+ me2->Sink->AddQuadraticBezier(D2D1::QuadraticBezierSegment(D2D1::Point2F(static_cast(x1), static_cast(y1)), D2D1::Point2F(static_cast(x2), static_cast(y2))));
+}
+
+EXPORT_CPP void _geometryDraw(SClass* me_, S64 color)
+{
+ SGeometry* me2 = reinterpret_cast(me_);
+ ID2D1SolidColorBrush* brush;
+ CurRenderTarget->CreateSolidColorBrush(ColorToColorF(color), &brush);
+ CurRenderTarget->FillGeometry(me2->Geometry, brush);
+ brush->Release();
+ CurRenderTarget->Flush();
+}
+
+EXPORT_CPP void _geometryDrawLine(SClass* me_, double stroke_width, S64 color)
+{
+ SGeometry* me2 = reinterpret_cast(me_);
+ ID2D1SolidColorBrush* brush;
+ CurRenderTarget->CreateSolidColorBrush(ColorToColorF(color), &brush);
+ CurRenderTarget->DrawGeometry(me2->Geometry, brush, static_cast(stroke_width));
+ brush->Release();
+ CurRenderTarget->Flush();
+}
+
+static void* Callback2d(int kind, void* arg1, void* arg2)
+{
+ switch (kind)
+ {
+ case 0: // Initialize 'S2dBuf'.
+ {
+ SWndBuf* wnd_buf = static_cast(arg1);
+ wnd_buf->Extra = static_cast(AllocMem(sizeof(S2dBuf)));
+ memset(wnd_buf->Extra, 0, sizeof(S2dBuf));
+
+ wnd_buf->Extra->Surface = static_cast(arg2);
+ D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT, D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED), 96, 96);
+ if (FAILED(Factory->CreateDxgiSurfaceRenderTarget(wnd_buf->Extra->Surface, &props, &wnd_buf->Extra->RenderTarget)))
+ THROW(EXCPT_DEVICE_INIT_FAILED);
+ }
+ return NULL;
+ case 1: // Finalize 'S2dBuf'.
+ {
+ SWndBuf* wnd_buf = static_cast(arg1);
+ if (wnd_buf->Extra->Surface != NULL)
+ wnd_buf->Extra->Surface->Release();
+ FreeMem(wnd_buf->Extra);
+ }
+ return NULL;
+ case 2: // 'ActiveDrawBuf'
+ if (Opened)
+ CurRenderTarget->EndDraw();
+ CurRenderTarget = static_cast(arg1)->Extra->RenderTarget;
+ CurRenderTarget->BeginDraw();
+ Opened = True;
+ return NULL;
+ case 3: // Write the buffer back.
+ if (Opened)
+ CurRenderTarget->EndDraw();
+ CurRenderTarget->BeginDraw();
+ Opened = True;
+ return NULL;
+ }
+ return NULL;
+}
+
+static D2D1::ColorF ColorToColorF(S64 color)
+{
+ THROWDBG(color < 0 || 0xffffffff < color, EXCPT_DBG_ARG_OUT_DOMAIN);
+ const FLOAT a = static_cast(static_cast((color >> 24) & 0xff) / 255.0);
+ const FLOAT r = static_cast(Gamma(static_cast((color >> 16) & 0xff) / 255.0));
+ const FLOAT g = static_cast(Gamma(static_cast((color >> 8) & 0xff) / 255.0));
+ const FLOAT b = static_cast(Gamma(static_cast(color & 0xff) / 255.0));
+ return D2D1::ColorF(r, g, b, a);
+}
+
+static double Gamma(double value)
+{
+ return value * (value * (value * 0.305306011 + 0.682171111) + 0.012522878);
+}
diff --git a/src/lib_draw2d/main.h b/src/lib_draw2d/main.h
new file mode 100644
index 00000000..3bbb9ba3
--- /dev/null
+++ b/src/lib_draw2d/main.h
@@ -0,0 +1,30 @@
+#pragma once
+
+#include "..\common.h"
+
+// 'draw2d'
+EXPORT_CPP void _init(void* heap, S64* heap_cnt, S64 app_code, const U8* use_res_flags);
+EXPORT_CPP void _fin();
+EXPORT_CPP void _line(double x1, double y1, double x2, double y2, double stroke_width, S64 color);
+EXPORT_CPP void _rect(double x, double y, double width, double height, S64 color);
+EXPORT_CPP void _rectLine(double x, double y, double width, double height, double stroke_width, S64 color);
+EXPORT_CPP void _circle(double x, double y, double radius_x, double radius_y, S64 color);
+EXPORT_CPP void _circleLine(double x, double y, double radius_x, double radius_y, double stroke_width, S64 color);
+EXPORT_CPP void _roundRect(double x, double y, double width, double height, double radius_x, double radius_y, S64 color);
+EXPORT_CPP void _roundRectLine(double x, double y, double width, double height, double radius_x, double radius_y, double stroke_width, S64 color);
+EXPORT_CPP void _tri(double x1, double y1, double x2, double y2, double x3, double y3, S64 color);
+EXPORT_CPP SClass* _makeBrushLinearGradient(SClass* me_, double x1, double y1, double x2, double y2, void* color_position, void* color);
+EXPORT_CPP void _brushLinearGradientDtor(SClass* me_);
+EXPORT_CPP void _brushLine(SClass* me_, double x1, double y1, double x2, double y2, double stroke_width, SClass* stroke_style);
+EXPORT_CPP SClass* _makeGeometryPath(SClass* me_);
+EXPORT_CPP void _geometryPathDtor(SClass* me_);
+EXPORT_CPP void _geometryPathOpen(SClass* me_);
+EXPORT_CPP void _geometryPathClose(SClass* me_);
+EXPORT_CPP void _geometryPathOpenFigure(SClass* me_, double x, double y, Bool filled);
+EXPORT_CPP void _geometryPathCloseFigure(SClass* me_, Bool closed_path);
+EXPORT_CPP void _geometryPathAddArc(SClass* me_, double x, double y, double radius_x, double radius_y, double angle, Bool ccw, Bool large_arc);
+EXPORT_CPP void _geometryPathAddBezier(SClass* me_, double x1, double y1, double x2, double y2, double x3, double y3);
+EXPORT_CPP void _geometryPathAddLine(SClass* me_, double x, double y);
+EXPORT_CPP void _geometryPathAddQuadraticBezier(SClass* me_, double x1, double y1, double x2, double y2);
+EXPORT_CPP void _geometryDraw(SClass* me_, S64 color);
+EXPORT_CPP void _geometryDrawLine(SClass* me_, double stroke_width, S64 color);
diff --git a/src/lib_game/lib_game.vcxproj b/src/lib_game/lib_game.vcxproj
new file mode 100644
index 00000000..642be64d
--- /dev/null
+++ b/src/lib_game/lib_game.vcxproj
@@ -0,0 +1,161 @@
+
+
+
+
+ Debug
+ x64
+
+
+ Release_dbg
+ x64
+
+
+ Release_rls
+ x64
+
+
+
+ {7CA2B257-7CBE-4934-A176-533374E47F7A}
+ Win32Proj
+ game
+ 8.1
+
+
+
+ DynamicLibrary
+ true
+ v140
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v140
+ true
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v140
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)src\output\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)src\output\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)src\output\$(Platform)\$(Configuration)\
+
+
+
+
+
+ Level4
+ Disabled
+ DBG;_DEBUG;_WINDOWS;_USRDLL;LIB_GAME_EXPORTS;%(PreprocessorDefinitions)
+ CompileAsC
+ MultiThreadedDebug
+
+
+ Windows
+ true
+
+
+ echo F | xcopy /y /r $(TargetPath) $(SolutionDir)..\..\test\output\data\d1004.knd
+
+
+ ml64 /Fo $(Platform)\$(Configuration)\%(Filename).obj /c /Cp /Zi /Zd %(Filename).asm
+ $(Platform)\$(Configuration)\%(Filename).obj
+
+
+
+
+ Level4
+
+
+ MaxSpeed
+ true
+ true
+ NDEBUG;_WINDOWS;_USRDLL;LIB_GAME_EXPORTS;%(PreprocessorDefinitions)
+ CompileAsC
+ MultiThreaded
+
+
+ Windows
+ true
+ true
+ false
+
+
+ echo F | xcopy /y /r $(TargetPath) $(SolutionDir)..\..\package\sys\rls\d1004.knd
+
+
+ ml64 /Fo $(Platform)\$(Configuration)\%(Filename).obj /c /Cp %(Filename).asm
+ $(Platform)\$(Configuration)\%(Filename).obj
+
+
+
+
+ Level4
+
+
+ MaxSpeed
+ true
+ true
+ DBG;NDEBUG;_WINDOWS;_USRDLL;LIB_GAME_EXPORTS;%(PreprocessorDefinitions)
+ CompileAsC
+ MultiThreaded
+
+
+ Windows
+ true
+ true
+ false
+
+
+ echo F | xcopy /y /r $(TargetPath) $(SolutionDir)..\..\package\sys\dbg\d1004.knd
+
+
+ ml64 /Fo $(Platform)\$(Configuration)\%(Filename).obj /c /Cp %(Filename).asm
+ $(Platform)\$(Configuration)\%(Filename).obj
+
+
+
+
+
+
+
+
+
+
+
+
+ Document
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/lib_game/lib_game.vcxproj.filters b/src/lib_game/lib_game.vcxproj.filters
new file mode 100644
index 00000000..c2905084
--- /dev/null
+++ b/src/lib_game/lib_game.vcxproj.filters
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/lib_boost/low_level.asm b/src/lib_game/low_level.asm
similarity index 100%
rename from src/lib_boost/low_level.asm
rename to src/lib_game/low_level.asm
diff --git a/src/lib_game/main.h b/src/lib_game/main.h
new file mode 100644
index 00000000..ce3ee543
--- /dev/null
+++ b/src/lib_game/main.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include "..\common.h"
+
+// 'game'
+EXPORT void _init(void* heap, S64* heap_cnt, S64 app_code, const U8* use_res_flags);
+EXPORT void _rectMove(SClass* me_, double max_velo);
+EXPORT void _rectUpdate(SClass* me_);
+EXPORT void _rectBackFriction(SClass* me_, double back_friction);
+EXPORT void _rectFluidFriction(SClass* me_, double fluid_friction);
+EXPORT SClass* _makeMapImpl(SClass* me_, S64 map_width, S64 map_height, const void* data, double chip_width, double chip_height);
+EXPORT SClass* _makeMapEmpty(SClass* me_, S64 map_width, S64 map_height, double chip_width, double chip_height);
+EXPORT void _mapDtor(SClass* me_);
+EXPORT S64 _mapGet(SClass* me_, S64 x, S64 y);
+EXPORT void _mapSet(SClass* me_, S64 x, S64 y, S64 value);
+EXPORT Bool _mapFind(SClass* me_, S64* x, S64* y, S64 value);
+EXPORT SClass* _hitMapRectImpl(SClass* me2, SClass* map, SClass* rect, const void* chip_info_callback, const void* hit_callback);
+EXPORT S64 _hitRectRect(SClass* rect1, SClass* rect2, double weight1, double weight2, double repulsion, double solid_friction);
+EXPORT void _rollDtor(SClass* me_);
+EXPORT Bool _rollProceed(SClass* me_, double speed);
+EXPORT void _rollReset(SClass* me_);
+EXPORT SClass* _makeRollImpl(SClass* me_, const void* timings, const void* params, const void* roll_callback);
diff --git a/src/lib_math/lib_math.vcxproj.filters b/src/lib_math/lib_math.vcxproj.filters
index 0bb76d8f..a250fbf5 100644
--- a/src/lib_math/lib_math.vcxproj.filters
+++ b/src/lib_math/lib_math.vcxproj.filters
@@ -1,41 +1,15 @@
-
- {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
- cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
-
-
- {93995380-89BD-4b04-88EB-625FBE52EBFB}
- h;hh;hpp;hxx;hm;inl;inc;xsd
-
-
- {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
- rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
-
+
+
+
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
+
+
-
- Header Files
-
-
- Header Files
-
-
-
-
- Source Files
-
+
\ No newline at end of file
diff --git a/src/lib_math/main.c b/src/lib_math/main.c
index f804c12f..200f39df 100644
--- a/src/lib_math/main.c
+++ b/src/lib_math/main.c
@@ -28,6 +28,28 @@ static const S64 Facts[21] =
1307674368000, 20922789888000, 355687428096000, 6402373705728000, 121645100408832000,
2432902008176640000
};
+static const S64 FibonacciNumbers[93] =
+{
+ 0, 1, 1, 2, 3,
+ 5, 8, 13, 21, 34,
+ 55, 89, 144, 233, 377,
+ 610, 987, 1597, 2584, 4181,
+ 6765, 10946, 17711, 28657, 46368,
+ 75025, 121393, 196418, 317811, 514229,
+ 832040, 1346269, 2178309, 3524578, 5702887,
+ 9227465, 14930352, 24157817, 39088169, 63245986,
+ 102334155, 165580141, 267914296, 433494437, 701408733,
+ 1134903170, 1836311903, 2971215073, 4807526976, 7778742049,
+ 12586269025, 20365011074, 32951280099, 53316291173, 86267571272,
+ 139583862445, 225851433717, 365435296162, 591286729879, 956722026041,
+ 1548008755920, 2504730781961, 4052739537881, 6557470319842, 10610209857723,
+ 17167680177565, 27777890035288, 44945570212853, 72723460248141, 117669030460994,
+ 190392490709135, 308061521170129, 498454011879264, 806515533049393, 1304969544928657,
+ 2111485077978050, 3416454622906707, 5527939700884757, 8944394323791464, 14472334024676221,
+ 23416728348467685, 37889062373143906, 61305790721611591, 99194853094755497, 160500643816367088,
+ 259695496911122585, 420196140727489673, 679891637638612258, 1100087778366101931, 1779979416004714189,
+ 2880067194370816120, 4660046610375530309, 7540113804746346429,
+};
static U64 ModPow(U64 value, U64 exponent, U64 modulus);
static U64 ModMul(U64 a, U64 b, U64 modulus);
@@ -49,20 +71,15 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
EXPORT void _init(void* heap, S64* heap_cnt, S64 app_code, const U8* use_res_flags)
{
- if (Heap != NULL)
+ if (!InitEnvVars(heap, heap_cnt, app_code, use_res_flags))
return;
- Heap = heap;
- HeapCnt = heap_cnt;
- AppCode = app_code;
- UseResFlags = use_res_flags;
- Instance = (HINSTANCE)GetModuleHandle(NULL);
}
EXPORT S64 _gcd(S64 a, S64 b)
{
if (a == 0)
{
- THROWDBG(b == 0, 0xe9170006);
+ THROWDBG(b == 0, EXCPT_DBG_ARG_OUT_DOMAIN);
return b;
}
if (b == 0)
@@ -92,7 +109,7 @@ EXPORT S64 _lcm(S64 a, S64 b)
{
if (a == 0)
{
- THROWDBG(b == 0, 0xe9170006);
+ THROWDBG(b == 0, EXCPT_DBG_ARG_OUT_DOMAIN);
return 0;
}
if (b == 0)
@@ -106,17 +123,17 @@ EXPORT S64 _lcm(S64 a, S64 b)
EXPORT S64 _modPow(S64 value, S64 exponent, S64 modulus)
{
- THROWDBG(value < 0, 0xe9170006);
- THROWDBG(exponent < 0, 0xe9170006);
- THROWDBG(modulus < 0, 0xe9170006);
+ THROWDBG(value < 0, EXCPT_DBG_ARG_OUT_DOMAIN);
+ THROWDBG(exponent < 0, EXCPT_DBG_ARG_OUT_DOMAIN);
+ THROWDBG(modulus < 0, EXCPT_DBG_ARG_OUT_DOMAIN);
return (S64)ModPow((U64)value, (U64)exponent, (U64)modulus);
}
EXPORT S64 _modMul(S64 a, S64 b, S64 modulus)
{
- THROWDBG(a < 0, 0xe9170006);
- THROWDBG(b < 0, 0xe9170006);
- THROWDBG(modulus < 0, 0xe9170006);
+ THROWDBG(a < 0, EXCPT_DBG_ARG_OUT_DOMAIN);
+ THROWDBG(b < 0, EXCPT_DBG_ARG_OUT_DOMAIN);
+ THROWDBG(modulus < 0, EXCPT_DBG_ARG_OUT_DOMAIN);
return (S64)ModMul((U64)a, (U64)b, (U64)modulus);
}
@@ -249,21 +266,36 @@ EXPORT S64 _factInt(S64 n)
{
if (n < 0)
{
- THROWDBG(True, 0xe9170006);
+ THROWDBG(True, EXCPT_DBG_ARG_OUT_DOMAIN);
return 0;
}
if (n > 20)
{
- THROWDBG(True, 0xe9170003);
+ THROWDBG(True, EXCPT_DBG_INT_OVERFLOW);
return 0;
}
return Facts[n];
}
+EXPORT S64 _fibonacci(S64 n)
+{
+ if (n < 0)
+ {
+ THROWDBG(True, EXCPT_DBG_ARG_OUT_DOMAIN);
+ return 0;
+ }
+ if (n > 92)
+ {
+ THROWDBG(True, EXCPT_DBG_INT_OVERFLOW);
+ return 0;
+ }
+ return FibonacciNumbers[n];
+}
+
EXPORT S64 _knapsack(const void* weights, const void* values, S64 max_weight, Bool reuse)
{
- THROWDBG(weights == NULL || values == NULL, 0xc0000005);
- THROWDBG(*(S64*)((U8*)weights + 0x08) != *(S64*)((U8*)values + 0x08), 0xe9170006);
+ THROWDBG(weights == NULL || values == NULL, EXCPT_ACCESS_VIOLATION);
+ THROWDBG(*(S64*)((U8*)weights + 0x08) != *(S64*)((U8*)values + 0x08), EXCPT_DBG_ARG_OUT_DOMAIN);
S64 len = *(S64*)((U8*)weights + 0x08);
const S64* weights2 = (S64*)((U8*)weights + 0x10);
const S64* values2 = (S64*)((U8*)values + 0x10);
@@ -271,7 +303,7 @@ EXPORT S64 _knapsack(const void* weights, const void* values, S64 max_weight, Bo
S64 i, j;
#if defined(DBG)
for (i = 0; i < len; i++)
- THROWDBG(weights2[i] <= 0, 0xe9170006);
+ THROWDBG(weights2[i] <= 0, EXCPT_DBG_ARG_OUT_DOMAIN);
#endif
memset(dp, 0, sizeof(S64) * (size_t)(max_weight + 1));
if (reuse)
@@ -305,9 +337,9 @@ EXPORT S64 _knapsack(const void* weights, const void* values, S64 max_weight, Bo
EXPORT void* _dijkstra(S64 node_num, const void* from_nodes, const void* to_nodes, const void* values, S64 begin_node)
{
- THROWDBG(from_nodes == NULL || to_nodes == NULL || values == NULL, 0xc0000005);
- THROWDBG(*(S64*)((U8*)from_nodes + 0x08) != *(S64*)((U8*)to_nodes + 0x08) || *(S64*)((U8*)to_nodes + 0x08) != *(S64*)((U8*)values + 0x08), 0xe9170006);
- THROWDBG(node_num <= 0 || begin_node < 0 || node_num <= begin_node, 0xe9170006);
+ THROWDBG(from_nodes == NULL || to_nodes == NULL || values == NULL, EXCPT_ACCESS_VIOLATION);
+ THROWDBG(*(S64*)((U8*)from_nodes + 0x08) != *(S64*)((U8*)to_nodes + 0x08) || *(S64*)((U8*)to_nodes + 0x08) != *(S64*)((U8*)values + 0x08), EXCPT_DBG_ARG_OUT_DOMAIN);
+ THROWDBG(node_num <= 0 || begin_node < 0 || node_num <= begin_node, EXCPT_DBG_ARG_OUT_DOMAIN);
const S64* from_nodes2 = (S64*)((U8*)from_nodes + 0x10);
const S64* to_nodes2 = (S64*)((U8*)to_nodes + 0x10);
const S64* values2 = (S64*)((U8*)values + 0x10);
@@ -315,7 +347,7 @@ EXPORT void* _dijkstra(S64 node_num, const void* from_nodes, const void* to_node
S64 i;
#if defined(DBG)
for (i = 0; i < len; i++)
- THROWDBG(from_nodes2[i] < 0 || node_num <= from_nodes2[i] || to_nodes2[i] < 0 || node_num <= to_nodes2[i] || values2[i] < 0, 0xe9170006);
+ THROWDBG(from_nodes2[i] < 0 || node_num <= from_nodes2[i] || to_nodes2[i] < 0 || node_num <= to_nodes2[i] || values2[i] < 0, EXCPT_DBG_ARG_OUT_DOMAIN);
#endif
U8* result = (U8*)AllocMem(0x10 + sizeof(S64) * (size_t)node_num);
@@ -408,9 +440,9 @@ EXPORT void* _dijkstra(S64 node_num, const void* from_nodes, const void* to_node
EXPORT void* _bellmanFord(S64 node_num, const void* from_nodes, const void* to_nodes, const void* values, S64 begin_node)
{
- THROWDBG(from_nodes == NULL || to_nodes == NULL || values == NULL, 0xc0000005);
- THROWDBG(*(S64*)((U8*)from_nodes + 0x08) != *(S64*)((U8*)to_nodes + 0x08) || *(S64*)((U8*)to_nodes + 0x08) != *(S64*)((U8*)values + 0x08), 0xe9170006);
- THROWDBG(node_num <= 0 || begin_node < 0 || node_num <= begin_node, 0xe9170006);
+ THROWDBG(from_nodes == NULL || to_nodes == NULL || values == NULL, EXCPT_ACCESS_VIOLATION);
+ THROWDBG(*(S64*)((U8*)from_nodes + 0x08) != *(S64*)((U8*)to_nodes + 0x08) || *(S64*)((U8*)to_nodes + 0x08) != *(S64*)((U8*)values + 0x08), EXCPT_DBG_ARG_OUT_DOMAIN);
+ THROWDBG(node_num <= 0 || begin_node < 0 || node_num <= begin_node, EXCPT_DBG_ARG_OUT_DOMAIN);
const S64* from_nodes2 = (S64*)((U8*)from_nodes + 0x10);
const S64* to_nodes2 = (S64*)((U8*)to_nodes + 0x10);
const S64* values2 = (S64*)((U8*)values + 0x10);
@@ -418,7 +450,7 @@ EXPORT void* _bellmanFord(S64 node_num, const void* from_nodes, const void* to_n
S64 i;
#if defined(DBG)
for (i = 0; i < len; i++)
- THROWDBG(from_nodes2[i] < 0 || node_num <= from_nodes2[i] || to_nodes2[i] < 0 || node_num <= to_nodes2[i], 0xe9170006);
+ THROWDBG(from_nodes2[i] < 0 || node_num <= from_nodes2[i] || to_nodes2[i] < 0 || node_num <= to_nodes2[i], EXCPT_DBG_ARG_OUT_DOMAIN);
#endif
U8* result = (U8*)AllocMem(0x10 + sizeof(S64) * (size_t)node_num);
@@ -448,9 +480,9 @@ EXPORT void* _bellmanFord(S64 node_num, const void* from_nodes, const void* to_n
EXPORT void* _floydWarshall(S64 node_num, const void* from_nodes, const void* to_nodes, const void* values)
{
- THROWDBG(from_nodes == NULL || to_nodes == NULL || values == NULL, 0xc0000005);
- THROWDBG(*(S64*)((U8*)from_nodes + 0x08) != *(S64*)((U8*)to_nodes + 0x08) || *(S64*)((U8*)to_nodes + 0x08) != *(S64*)((U8*)values + 0x08), 0xe9170006);
- THROWDBG(node_num <= 0, 0xe9170006);
+ THROWDBG(from_nodes == NULL || to_nodes == NULL || values == NULL, EXCPT_ACCESS_VIOLATION);
+ THROWDBG(*(S64*)((U8*)from_nodes + 0x08) != *(S64*)((U8*)to_nodes + 0x08) || *(S64*)((U8*)to_nodes + 0x08) != *(S64*)((U8*)values + 0x08), EXCPT_DBG_ARG_OUT_DOMAIN);
+ THROWDBG(node_num <= 0, EXCPT_DBG_ARG_OUT_DOMAIN);
const S64* from_nodes2 = (S64*)((U8*)from_nodes + 0x10);
const S64* to_nodes2 = (S64*)((U8*)to_nodes + 0x10);
const S64* values2 = (S64*)((U8*)values + 0x10);
@@ -458,7 +490,7 @@ EXPORT void* _floydWarshall(S64 node_num, const void* from_nodes, const void* to
S64 i, j, k;
#if defined(DBG)
for (i = 0; i < len; i++)
- THROWDBG(from_nodes2[i] < 0 || node_num <= from_nodes2[i] || to_nodes2[i] < 0 || node_num <= to_nodes2[i], 0xe9170006);
+ THROWDBG(from_nodes2[i] < 0 || node_num <= from_nodes2[i] || to_nodes2[i] < 0 || node_num <= to_nodes2[i], EXCPT_DBG_ARG_OUT_DOMAIN);
#endif
U8* result = (U8*)AllocMem(0x10 + sizeof(void**) * (size_t)node_num);
@@ -499,7 +531,7 @@ EXPORT void* _floydWarshall(S64 node_num, const void* from_nodes, const void* to
EXPORT SClass* _makeMat(SClass* me_, S64 row, S64 col)
{
- THROWDBG(row <= 0 || col <= 0, 0xe9170006);
+ THROWDBG(row <= 0 || col <= 0, EXCPT_DBG_ARG_OUT_DOMAIN);
SMat* me2 = (SMat*)me_;
me2->Row = row;
me2->Col = col;
diff --git a/src/lib_math/main.h b/src/lib_math/main.h
index 870c3f84..2a43df3c 100644
--- a/src/lib_math/main.h
+++ b/src/lib_math/main.h
@@ -13,6 +13,7 @@ EXPORT void* _primeFactors(S64 n);
EXPORT double _gamma(double n);
EXPORT double _fact(double n);
EXPORT S64 _factInt(S64 n);
+EXPORT S64 _fibonacci(S64 n);
EXPORT S64 _knapsack(const void* weights, const void* values, S64 max_weight, Bool reuse);
EXPORT void* _dijkstra(S64 node_num, const void* from_nodes, const void* to_nodes, const void* values, S64 begin_node);
EXPORT void* _bellmanFord(S64 node_num, const void* from_nodes, const void* to_nodes, const void* values, S64 begin_node);
diff --git a/src/lib_boost/build_boost.txt b/src/lib_math_boost/build_boost.txt
similarity index 100%
rename from src/lib_boost/build_boost.txt
rename to src/lib_math_boost/build_boost.txt
diff --git a/src/lib_math_boost/lib_math_boost.vcxproj b/src/lib_math_boost/lib_math_boost.vcxproj
new file mode 100644
index 00000000..fa10289d
--- /dev/null
+++ b/src/lib_math_boost/lib_math_boost.vcxproj
@@ -0,0 +1,152 @@
+
+
+
+
+ Debug
+ x64
+
+
+ Release_dbg
+ x64
+
+
+ Release_rls
+ x64
+
+
+
+ {C4024A39-66F3-43D0-BAAE-755737DD29A5}
+ Win32Proj
+ lib_math_boost
+ 8.1
+
+
+
+ DynamicLibrary
+ true
+ v140
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v140
+ true
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v140
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(SolutionDir)..\output\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)..\output\$(Platform)\$(Configuration)\
+
+
+ false
+ $(SolutionDir)..\output\$(Platform)\$(Configuration)\
+
+
+
+
+
+ Level4
+ Disabled
+ DBG;_DEBUG;_WINDOWS;_USRDLL;LIB_BOOST_EXPORTS;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+ F:\kuin_git\develop\boost\include\boost-1_65_1;%(AdditionalIncludeDirectories)
+ CompileAsCpp
+
+
+ Windows
+ true
+ F:\kuin_git\develop\boost\lib;%(AdditionalLibraryDirectories)
+
+
+ echo F | xcopy /y /r $(TargetPath) $(SolutionDir)..\..\test\output\data\d1006.knd
+
+
+
+
+ Level4
+
+
+ MaxSpeed
+ true
+ true
+ NDEBUG;_WINDOWS;_USRDLL;LIB_BOOST_EXPORTS;%(PreprocessorDefinitions)
+ MultiThreaded
+ F:\kuin_git\develop\boost\include\boost-1_65_1;%(AdditionalIncludeDirectories)
+ CompileAsCpp
+
+
+ Windows
+ true
+ true
+ false
+ F:\kuin_git\develop\boost\lib;%(AdditionalLibraryDirectories)
+
+
+ echo F | xcopy /y /r $(TargetPath) $(SolutionDir)..\..\package\sys\rls\d1006.knd
+
+
+
+
+ Level4
+
+
+ MaxSpeed
+ true
+ true
+ DBG;NDEBUG;_WINDOWS;_USRDLL;LIB_BOOST_EXPORTS;%(PreprocessorDefinitions)
+ F:\kuin_git\develop\boost\include\boost-1_65_1;%(AdditionalIncludeDirectories)
+ MultiThreaded
+ CompileAsCpp
+
+
+ Windows
+ true
+ true
+ false
+ F:\kuin_git\develop\boost\lib;%(AdditionalLibraryDirectories)
+
+
+ echo F | xcopy /y /r $(TargetPath) $(SolutionDir)..\..\package\sys\dbg\d1006.knd
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/lib_math_boost/lib_math_boost.vcxproj.filters b/src/lib_math_boost/lib_math_boost.vcxproj.filters
new file mode 100644
index 00000000..1ff1f79a
--- /dev/null
+++ b/src/lib_math_boost/lib_math_boost.vcxproj.filters
@@ -0,0 +1,39 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/src/lib_boost/main.cpp b/src/lib_math_boost/main.cpp
similarity index 56%
rename from src/lib_boost/main.cpp
rename to src/lib_math_boost/main.cpp
index 6383b5a5..7b4dfbf0 100644
--- a/src/lib_boost/main.cpp
+++ b/src/lib_math_boost/main.cpp
@@ -1,4 +1,4 @@
-// LibBoost.dll
+// LibMathBoost.dll
//
// (C)Kuina-chan
//
@@ -13,13 +13,8 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
return TRUE;
}
-EXPORT_CPP void _init(void* heap, S64* heap_cnt, S64 app_code, const Char* use_res_flags)
+EXPORT_CPP void _init(void* heap, S64* heap_cnt, S64 app_code, const U8* use_res_flags)
{
- UNUSED(use_res_flags);
- if (Heap != NULL)
+ if (!InitEnvVars(heap, heap_cnt, app_code, use_res_flags))
return;
- Heap = heap;
- HeapCnt = heap_cnt;
- AppCode = app_code;
- Instance = static_cast(GetModuleHandle(NULL));
}
diff --git a/src/lib_boost/main.h b/src/lib_math_boost/main.h
similarity index 80%
rename from src/lib_boost/main.h
rename to src/lib_math_boost/main.h
index b8d9dac5..3a535e75 100644
--- a/src/lib_boost/main.h
+++ b/src/lib_math_boost/main.h
@@ -2,4 +2,4 @@
#include "..\common.h"
-EXPORT_CPP void _init(void* heap, S64* heap_cnt, S64 app_code, const Char* app_name);
+EXPORT_CPP void _init(void* heap, S64* heap_cnt, S64 app_code, const U8* use_res_flags);
diff --git a/src/lib_math_boost/math_boost.cpp b/src/lib_math_boost/math_boost.cpp
new file mode 100644
index 00000000..11439251
--- /dev/null
+++ b/src/lib_math_boost/math_boost.cpp
@@ -0,0 +1,600 @@
+#include "math_boost.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+using namespace boost::multiprecision;
+using namespace boost::math::constants;
+
+struct SBigInt
+{
+ SClass Class;
+ cpp_int* Value;
+};
+
+struct SBigFloat
+{
+ SClass Class;
+ cpp_dec_float_100* Value;
+};
+
+struct SComplex
+{
+ SClass Class;
+ std::complex* Value;
+};
+
+static std::wstring_convert, Char> Converter;
+
+EXPORT_CPP SClass* _makeBigInt(SClass* me_)
+{
+ SBigInt* me2 = reinterpret_cast(me_);
+ me2->Value = static_cast(AllocMem(sizeof(cpp_int)));
+ new(me2->Value)cpp_int();
+ return me_;
+}
+
+EXPORT_CPP void _bigIntDtor(SClass* me_)
+{
+ SBigInt* me2 = reinterpret_cast(me_);
+ if (me2->Value != NULL)
+ FreeMem(me2->Value);
+}
+
+EXPORT_CPP S64 _bigIntCmp(SClass* me_, SClass* t)
+{
+ SBigInt* me2 = reinterpret_cast(me_);
+ SBigInt* t2 = reinterpret_cast(t);
+ return *me2->Value > *t2->Value ? 1 : (*me2->Value < *t2->Value ? -1 : 0);
+}
+
+EXPORT_CPP Bool _bigIntFromStr(SClass* me_, const void* value)
+{
+ SBigInt* me2 = reinterpret_cast(me_);
+ THROWDBG(value == NULL, EXCPT_ACCESS_VIOLATION);
+ try
+ {
+ me2->Value->assign(Converter.to_bytes(static_cast(value) + 0x08));
+ }
+ catch (...)
+ {
+ return False;
+ }
+ return True;
+}
+
+EXPORT_CPP void* _bigIntToStr(SClass* me_)
+{
+ SBigInt* me2 = reinterpret_cast(me_);
+ std::wstring result = Converter.from_bytes(me2->Value->str());
+ size_t len = result.size();
+ U8* result2 = static_cast(AllocMem(0x10 + sizeof(Char) * (len + 1)));
+ (reinterpret_cast(result2))[0] = DefaultRefCntFunc;
+ (reinterpret_cast(result2))[1] = static_cast(len);
+ memcpy(result2 + 0x10, result.c_str(), sizeof(Char) * (len + 1));
+ return result2;
+}
+
+EXPORT_CPP void _bigIntFromInt(SClass* me_, S64 value)
+{
+ SBigInt* me2 = reinterpret_cast(me_);
+ *me2->Value = value;
+}
+
+EXPORT_CPP S64 _bigIntToInt(SClass* me_)
+{
+ SBigInt* me2 = reinterpret_cast(me_);
+ return static_cast(*me2->Value);
+}
+
+EXPORT_CPP SClass* _bigIntAdd(SClass* me_, SClass* value)
+{
+ *reinterpret_cast(me_)->Value += *reinterpret_cast(value)->Value;
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigIntAddInt(SClass* me_, S64 value)
+{
+ *reinterpret_cast(me_)->Value += value;
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigIntSub(SClass* me_, SClass* value)
+{
+ *reinterpret_cast(me_)->Value -= *reinterpret_cast(value)->Value;
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigIntSubInt(SClass* me_, S64 value)
+{
+ *reinterpret_cast(me_)->Value -= value;
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigIntMul(SClass* me_, SClass* value)
+{
+ *reinterpret_cast(me_)->Value *= *reinterpret_cast(value)->Value;
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigIntMulInt(SClass* me_, S64 value)
+{
+ *reinterpret_cast(me_)->Value *= value;
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigIntDiv(SClass* me_, SClass* value)
+{
+ *reinterpret_cast(me_)->Value /= *reinterpret_cast(value)->Value;
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigIntDivInt(SClass* me_, S64 value)
+{
+ *reinterpret_cast(me_)->Value /= value;
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigIntMod(SClass* me_, SClass* value)
+{
+ *reinterpret_cast(me_)->Value %= *reinterpret_cast(value)->Value;
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigIntModInt(SClass* me_, S64 value)
+{
+ *reinterpret_cast(me_)->Value %= value;
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigIntPowInt(SClass* me_, S64 value)
+{
+ U32 value2 = static_cast(value);
+ THROWDBG(value != static_cast(value2), EXCPT_DBG_ARG_OUT_DOMAIN);
+ *reinterpret_cast(me_)->Value = pow(*reinterpret_cast(me_)->Value, value2);
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigIntAbs(SClass* me_)
+{
+ *reinterpret_cast(me_)->Value = abs(*reinterpret_cast(me_)->Value);
+ return me_;
+}
+
+EXPORT_CPP SClass* _makeBigFloat(SClass* me_)
+{
+ SBigFloat* me2 = reinterpret_cast(me_);
+ me2->Value = static_cast(AllocMem(sizeof(cpp_dec_float_100)));
+ new(me2->Value)cpp_dec_float_100();
+ return me_;
+}
+
+EXPORT_CPP void _bigFloatDtor(SClass* me_)
+{
+ SBigFloat* me2 = reinterpret_cast(me_);
+ if (me2->Value != NULL)
+ {
+ me2->Value->~cpp_dec_float_100();
+ FreeMem(me2->Value);
+ }
+}
+
+EXPORT_CPP S64 _bigFloatCmp(SClass* me_, SClass* t)
+{
+ SBigFloat* me2 = reinterpret_cast(me_);
+ SBigFloat* t2 = reinterpret_cast(t);
+ return *me2->Value > *t2->Value ? 1 : (*me2->Value < *t2->Value ? -1 : 0);
+}
+
+EXPORT_CPP Bool _bigFloatFromStr(SClass* me_, const void* value)
+{
+ SBigFloat* me2 = reinterpret_cast(me_);
+ THROWDBG(value == NULL, EXCPT_ACCESS_VIOLATION);
+ try
+ {
+ me2->Value->assign(Converter.to_bytes(static_cast(value) + 0x08));
+ }
+ catch (...)
+ {
+ return False;
+ }
+ return True;
+}
+
+EXPORT_CPP void* _bigFloatToStr(SClass* me_)
+{
+ SBigFloat* me2 = reinterpret_cast(me_);
+ std::wstring result = Converter.from_bytes(me2->Value->str());
+ size_t len = result.size();
+ U8* result2 = static_cast(AllocMem(0x10 + sizeof(Char) * (len + 1)));
+ (reinterpret_cast(result2))[0] = DefaultRefCntFunc;
+ (reinterpret_cast(result2))[1] = static_cast(len);
+ memcpy(result2 + 0x10, result.c_str(), sizeof(Char) * (len + 1));
+ return result2;
+}
+
+EXPORT_CPP void _bigFloatFromFloat(SClass* me_, double value)
+{
+ SBigFloat* me2 = reinterpret_cast(me_);
+ *me2->Value = value;
+}
+
+EXPORT_CPP double _bigFloatToFloat(SClass* me_)
+{
+ SBigFloat* me2 = reinterpret_cast(me_);
+ return static_cast(*me2->Value);
+}
+
+EXPORT_CPP SClass* _bigFloatAdd(SClass* me_, SClass* value)
+{
+ *reinterpret_cast(me_)->Value += *reinterpret_cast(value)->Value;
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigFloatAddFloat(SClass* me_, double value)
+{
+ *reinterpret_cast(me_)->Value += value;
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigFloatSub(SClass* me_, SClass* value)
+{
+ *reinterpret_cast(me_)->Value -= *reinterpret_cast(value)->Value;
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigFloatSubFloat(SClass* me_, double value)
+{
+ *reinterpret_cast(me_)->Value -= value;
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigFloatMul(SClass* me_, SClass* value)
+{
+ *reinterpret_cast(me_)->Value *= *reinterpret_cast(value)->Value;
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigFloatMulFloat(SClass* me_, double value)
+{
+ *reinterpret_cast(me_)->Value *= value;
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigFloatDiv(SClass* me_, SClass* value)
+{
+ *reinterpret_cast(me_)->Value /= *reinterpret_cast(value)->Value;
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigFloatDivFloat(SClass* me_, double value)
+{
+ *reinterpret_cast(me_)->Value /= value;
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigFloatMod(SClass* me_, SClass* value)
+{
+ *reinterpret_cast(me_)->Value = fmod(*reinterpret_cast(me_)->Value, *reinterpret_cast(value)->Value);
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigFloatModFloat(SClass* me_, double value)
+{
+ *reinterpret_cast(me_)->Value = fmod(*reinterpret_cast(me_)->Value, value);
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigFloatPow(SClass* me_, SClass* value)
+{
+ *reinterpret_cast(me_)->Value = pow(*reinterpret_cast(me_)->Value, *reinterpret_cast(value)->Value);
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigFloatPowFloat(SClass* me_, double value)
+{
+ *reinterpret_cast(me_)->Value = pow(*reinterpret_cast(me_)->Value, value);
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigFloatExp(SClass* me_)
+{
+ *reinterpret_cast(me_)->Value = exp(*reinterpret_cast(me_)->Value);
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigFloatLn(SClass* me_)
+{
+ *reinterpret_cast(me_)->Value = log(*reinterpret_cast(me_)->Value);
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigFloatSqrt(SClass* me_)
+{
+ *reinterpret_cast(me_)->Value = sqrt(*reinterpret_cast(me_)->Value);
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigFloatFloor(SClass* me_)
+{
+ *reinterpret_cast(me_)->Value = floor(*reinterpret_cast(me_)->Value);
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigFloatCeil(SClass* me_)
+{
+ *reinterpret_cast(me_)->Value = ceil(*reinterpret_cast(me_)->Value);
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigFloatCos(SClass* me_)
+{
+ *reinterpret_cast(me_)->Value = cos(*reinterpret_cast(me_)->Value);
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigFloatSin(SClass* me_)
+{
+ *reinterpret_cast(me_)->Value = sin(*reinterpret_cast(me_)->Value);
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigFloatTan(SClass* me_)
+{
+ *reinterpret_cast(me_)->Value = tan(*reinterpret_cast(me_)->Value);
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigFloatAcos(SClass* me_)
+{
+ *reinterpret_cast(me_)->Value = acos(*reinterpret_cast(me_)->Value);
+ return me_;
+}
+
+EXPORT_CPP SClass* _bigFloatAsin(SClass* me_)
+{
+ *reinterpret_cast