HSPに投稿されたコード一覧

HSP HSPプログラムコンテストの作品をリスト&カウント

#include "hspinet.as"

#define URL_BASE "http://dev.onionsoft.net/seed/info.ax?id="

	netinit
	if stat : dialog "connection error" : end

	; 年度
	year = "2017" ; 2012年より前は非対応

	; 部門
	category = "n", "s", "d"
	cate_name = "一般", "HSPTV", "Dish"

	sdim listBuf, 32000

	neturl "http://hsp.tv/contest" + year + "/"

	num_str = "("
	num_total = 0
	foreach category : cate_id = cnt
		num_cate(cate_id) = 0
		repeat , 1
			fn = "list_" + category(cate_id) + cnt + ".html"
			request fn
			if stat : break
			title "downloading " + fn
			gosub *downloadLoop
			gosub *getWork
		loop
		num_str += strf("%s:%d, ", cate_name(cate_id), num_cate(cate_id))
	loop
	poke num_str, strlen(num_str) - 2
	title strf("作品数:%d %s)", num_total, num_str)
	objsize 640, 480
	listbox listid, 0, listBuf
	notesel listBuf
	onkey gosub *inKey
	stop

*inKey
	if lparam >> 30 : return
	if wparam == 13 { ; Enter
		noteget ts, listid
		getstr id, ts, 1, ':'
		exec URL_BASE + int(id), 16
	}
	return

#deffunc request str _fn
	netfileinfo info, _fn
	if stat {
		dialog "info error"
		end
	}
	getstr ts, info
	if instr(ts, 0, "404") >= 0 {
		return 1
	}
	netrequest_get _fn
	return 0

*downloadLoop
	netexec res
	if res < 0 {
		neterror estr
		dialog "download error: " + estr
		end
	}
	if res > 0 {
		netgetv buf
		return
	}
	await 50
	goto *downloadLoop

*getWork
	pt = instr(buf, 0, "<!--段落始まり-->")
	repeat
		t = instr(buf, pt, "<a name=")
		if (t < 0) : break
		pt += t
		getstr id, buf, pt + 9, '\"'
		url = URL_BASE + id
		pt += instr(buf, pt, url)
		getstr name, buf, pt + strlen(url) + 2, '<'
		listBuf += strf("#%05d: %s\n", id, name)
		num_total++
		num_cate(cate_id)++
	loop
return

HSP みんな遅い遅いって言うから高速動作するstrmid作ったよ

//
// [ Infomation ]
//  Name      : 高速strmid
//  SubName   :
//  Version   : 1.00
//  copyright : GENKI
//
// [ Update history ]
// 2017/09/17 : 1.00 : 完成。
//
// [ Comment ]
//  遅いと指摘され続けてきたstrmid命令の高速動作する互換命令です。
// これまでstrmid命令の代わりにmemcpyを用いて高速化する手法が
// 広く利用されていましたが、当然ながら使いにくくなるという問
// 題を有していました。
//  本モジュールでは内部でmemcpyを用いて高速に動作させつつ、
// 必要な面倒な手続きを省略し、strmidと同じ要領で使用できるよ
// うにしています。
//  使い方は、strmid命令を使用しているスクリプトで本モジュー
// ルをincludeし、strmidをstrmid2に置換するだけで高速に動作す
// るstrmid互換命令を使用できるようになります。
//  なお文字列を右側から取り出す場合は、strmidと同等程度の速
// 度に低下します。
//

;#ifndef __MODULE_NAME__
;#define global __MODULE_NAME__
#module

// ------------------------------------------------------------ //
//
// 関  数  :strmid2
//
// 引  数  :var p1=変数名 : 取り出すもとの文字列が格納されている変数名
//           int p2=-1~   : 取り出し始めのインデックス
//           int p3=0~    : 取り出す文字数
//
// 返り値  :refstr
//           0 : hogehoge
//           1 : hogehoge
//
// 機能説明:
//  strmid命令よりも高速度さする互換命令です。
//  p2に-1を指定した場合は内部でstrmid命令を呼び出します。
//
//  p1で指定した文字列型変数の中から、 p2,p3で指定した条件で文字を取り出したものを返します。
//  p2で取り出し始めるインデックスを指定します。これは、文字列の始まり1文字目を0として、1,2,3...と順番に増えていくものです。1から始まりではないので注意してください。
//  p3で取り出す文字数を指定します。実際に格納されている文字数よりも多く指定した場合は、実際の文字数までが取り出されます。
//  また、p2に-1を指定すると文字列の右からp3で指定した文字数だけ取り出します。
//
//
// ------------------------------------------------------------ //
#defcfunc strmid2 var p_txt, int p_idxStart, int p_lenPickChar
	;--------------------
	;	右から取り出す
	;--------------------
	if p_idxStart<0 {
		;右から取り出す場合は、strlenが遅いのでstrmidを使ったほうが速くなる。
		return strmid(p_txt, p_idxStart, p_lenPickChar)
	}

	;--------------------
	;	引数チェック
	;--------------------
	if p_lenPickChar<=0 {
		return ""
	}

	;--------------------
	;	出力初期化
	;--------------------
	;	出力する文字列
	sdim res_text, p_lenPickChar

	;--------------------
	;	左から取り出す
	;--------------------

	;	取り出す文字数を決定
	;バッファオーバーフロー対策
	i = varsize(p_txt)
	if i - p_idxStart - p_lenPickChar < 0 {
		;	文字数オーバーする場合
		l = i - p_idxStart
	} else {
		l = p_lenPickChar
	}

	;	文字列取り出し
	memcpy res_text, p_txt, l, 0, p_idxStart

	return res_text

#global
;#endif	;__MODULE_NAME__

;-------------------------------------------------------------------------------
;
;	仮実行スクリプト(デバッグ作業用)
;

;#####################################################################
;ここにはデバッグ作業用のスクリプトを記述します。
;ここを有効にするとこのファイル単独での実行が可能になります。
;
;0	:リリースモード 本体側から#includeで連結して動作させる場合です。
;1	:デバッグモード このファイル単品で動作確認が出来ます。
#if 0
	b = "ABCDEF"
	mes b
	mes "- strmid"
	mes strmid(b,-1,3)   ; 右から3文字を取り出す
	mes strmid(b,1,3)    ; 左から2文字目から3文字を取り出す

	mes "- strmid2"
	mes strmid2(b,-1,3)   ; 右から3文字を取り出す
	mes strmid2(b,1,3)    ; 左から2文字目から3文字を取り出す

#endif
;#####################################################################

HSP 矩形敷き詰め問題

/*
	矩形敷き詰め問題

	 表計算ソフトのシートの要領で空き領域を管理する。
	爆速だけどメモリ消費が多い(100個の矩形で6MB程)。
	左上から詰めていくから、任意の矩形を1つ置いた時に、必要に応じてその右辺と底辺の延長線でシートを分割すればよい。
	 ある矩形Sを1つ置い後、(必要に応じてシートを分割した後に)、「Sの右隣列の連続した空きセルの最も上のもの」および「Sの1つ下の列の連続した空きセルの最も左のもの」を矩形配置試行セルに加えれば良い。
*/

#cmpopt varinit 1

//#define DEBUG	//コメントアウトでデバッグモード(logmes使うので遅い)
#module
#deffunc debugmes str str_
	#ifdef DEBUG@
		logmes str_
	#endif
	return
#global

#define global TRUE		1
#define global FALSE	0
#define global SIZE_OF_INT	4
#define global INVALID_CELL_ID	-1

#define global SX_FIELD	800	//フィールド(今回は画面全体)のサイズ
#define global SY_FIELD	800

#module Cell sx, sy, used, id_right, id_lower	//セルクラス
	/*
		sx,sy : セルのサイズ
		used : 使用済みor not
		id_right, id_left	: 右隣, 直下のセルへのポインタ(モジュール変数の配列内におけるID。以下「ポインタ」はこれを意味する。)
							  隣がない場合は INVALID_CELL_ID とする
	*/
	id_=0
	#modinit int sx_, int sy_, int used_, int id_right_, int id_lower_
		sx=sx_ : sy=sy_
		used=used_
		id_right=id_right_ : id_lower=id_lower_
		mref id_,2
		return id_
	#modcfunc local get_sx
		return sx
	#modcfunc local get_sy
		return sy
	#modcfunc local get_used
		return used
	#modcfunc local get_id_right
		return id_right
	#modcfunc local get_id_lower
		return id_lower
	#modfunc local set_size int sx_, int sy_
		sx=sx_ : sy=sy_
		return
	#modfunc local set_used int used_
		used=used_
		return
	#modfunc local set_id_right int id_right_
		id_right=id_right_
		return
	#modfunc local set_id_lower int id_lower_
		id_lower=id_lower_
		return

	#modcfunc local is_rightEnd
		return id_right==INVALID_CELL_ID

	#modcfunc local is_bottom
		return id_lower==INVALID_CELL_ID
#global

#module class_try_cells num_try_cells, array_cell_id, array_dist	//矩形配置試行セルのリストのクラス。インスタンスは1個だけ。
	#modinit int first_cell_id_
		num_try_cells=1	//試行セルの個数
		array_cell_id=first_cell_id_	//試行セルのポインタの配列
		array_dist=0	//試行セルの、原点からの距離(int)の配列。昇順に並んでいる。↑の配列とリンク。
		return

	#modcfunc local get_num_try_cells
		return num_try_cells

	#modcfunc local get_try_cell int order_id_	//order_id_ 番目の試行セルのポインタを返す
		return array_cell_id(order_id_)

	#modcfunc local exists int id_, local return_code	//そのセルが存在するか?。
		/*
			id_ : セルのポインタ
		*/
		return_code=FALSE
		repeat num_try_cells
			if (id_==array_cell_id(cnt)) {return_code=TRUE : break}
		loop
		return return_code

	#modfunc local add_try_cell int cell_id_, int dist_	//試行セルの登録
		/*
			cell_id_ : 試行セルへのポインタ
			dist_ : そのセルの原点からの距離
		*/
		if (exists@class_try_cells(thismod, cell_id_)) {return}
		array_cell_id(num_try_cells)=-1 : array_dist(num_try_cells)=0	//ダミー書き込み。配列長が不足の場合に自動確保を促す。
		repeat num_try_cells+1	//挿入
			if ((dist_ < array_dist(cnt))||(cnt==num_try_cells)) {
				//場所を開ける
					memcpy array_cell_id, array_cell_id, SIZE_OF_INT*(num_try_cells-cnt), SIZE_OF_INT*(cnt+1), SIZE_OF_INT*cnt
					memcpy array_dist, array_dist, SIZE_OF_INT*(num_try_cells-cnt), SIZE_OF_INT*(cnt+1), SIZE_OF_INT*cnt
				//追加
					array_cell_id(cnt)=cell_id_ : array_dist(cnt)=dist_
					num_try_cells++
				break
			}
		loop
		return

	#modfunc local remove_try_cell int cell_id_	//試行セルを削除
		repeat num_try_cells
			if (array_cell_id(cnt)==cell_id_) {
				//空席を詰める
					memcpy array_cell_id, array_cell_id, SIZE_OF_INT*(num_try_cells-cnt-1), SIZE_OF_INT*cnt, SIZE_OF_INT*(cnt+1)
					memcpy array_dist, array_dist, SIZE_OF_INT*(num_try_cells-cnt-1), SIZE_OF_INT*cnt, SIZE_OF_INT*(cnt+1)
				break
			}
		loop
		num_try_cells--
		return
#global

#module	sheet_contro	//シート操作モジュール
	#deffunc init_sheet	//シート初期化
		sheet=0 : newmod sheet, Cell, SX_FIELD, SY_FIELD, FALSE, INVALID_CELL_ID, INVALID_CELL_ID	//シート全体を巨大な単セルに
		id_baseCell=stat	//左上セルのポインタ
		num_cell_x=1 : num_cell_y=1	//x,y方向のセルの数(=列数, 行数)
		try_cells=0 : newmod try_cells, class_try_cells, id_baseCell	//矩形配置試行セルリストの唯一インスタンス
		return

	#defcfunc get_top_cell int idx_, local id	//その列(idx_)の最上行のセル
		id=id_baseCell
		repeat idx_ : id=get_id_right@Cell(sheet(id)) : assert(id!=INVALID_CELL_ID) : loop
		return id

	#defcfunc get_bottom_cell int idx_, local id	//その列の最下行のセル
		id=get_top_cell(idx_)
		repeat num_cell_y-1 : id=get_id_lower@Cell(sheet(id)) : assert(id!=INVALID_CELL_ID) : loop
		return id

	#defcfunc get_leftEnd_cell int idy_, local id	//その行(idy_)の最左列のセル
		id=id_baseCell
		repeat idy_ : id=get_id_lower@Cell(sheet(id)) : assert(id!=INVALID_CELL_ID) : loop
		return id

	#defcfunc get_rightEnd_cell int idy_, local id	//その行の最右列のセル
		id=get_leftEnd_cell(idy_)
		repeat num_cell_x-1 : id=get_id_right@Cell(sheet(id)) : assert(id!=INVALID_CELL_ID) : loop
		return id

	#defcfunc index2id int idx_, int idy_, local id	//(列,行)からセルのポインタへ
		id=id_baseCell
		repeat idx_ : id=get_id_right@Cell(sheet(id)) : assert(id!=INVALID_CELL_ID) : loop
		repeat idy_ : id=get_id_lower@Cell(sheet(id)) : assert(id!=INVALID_CELL_ID) : loop
		return id

	#deffunc id2index int id_, var idx_, var idy_, local id, local cx, local cy	//セルのポインタから(列,行)へ
		id=id_ : cx=0 : cy=0
		repeat
			if (is_rightEnd@Cell(sheet(id))) {break}
			id=get_id_right@Cell(sheet(id))
			cx++
		loop
		repeat
			if (is_bottom@Cell(sheet(id))) {break}
			id=get_id_lower@Cell(sheet(id))
			cy++
		loop
		idx_=num_cell_x-cx-1 : idy_=num_cell_y-cy-1
		return

	#deffunc index2pos int idx_, int idy_, var x_, var y_, local id	//その(列,行)より左上の領域のサイズ
		id=id_baseCell : x_=0 : y_=0
		repeat idx_ : x_+=get_sx@Cell(sheet(id)) : id=get_id_right@Cell(sheet(id)) : loop
		repeat idy_ : y_+=get_sy@Cell(sheet(id)) : id=get_id_lower@Cell(sheet(id)) : loop
		return

	#defcfunc index2distance int idx_, int idy_, local x, local y	//その(列,行)の原点からの距離
		index2pos idx_,idy_, x,y
		return int(sqrt(x*x + y*y))

	#defcfunc id2distance int id_, local idx, local idy	//そのセルの原点からの距離
		id2index id_, idx,idy
		return index2distance(idx,idy)

	#deffunc div_x int idx_, int sx_new, local id	//x方向にシートを分割
		/*
			idx_ : 分割したい列。この列を縮めて右側に新しい列を挿入

			[方針]
				下端から作る
		*/
		//「その右に新しいセルが作られるセル達」のID。上から順に詰める。
			stack_id=get_top_cell(idx_)
			repeat num_cell_y-1, 1
				stack_id(cnt)=get_id_lower@Cell(sheet(stack_id(cnt-1)))
			loop

		new_cell_id=INVALID_CELL_ID
		repeat num_cell_y
			id=stack_id(num_cell_y-1-cnt)
			//新しいセル
				sy=get_sy@Cell(sheet(id))
				newmod sheet, Cell, sx_new,sy, get_used@Cell(sheet(id)), get_id_right@Cell(sheet(id)), new_cell_id
				new_cell_id=stat
			//既存のセルの調整
				set_size@Cell sheet(id), get_sx@Cell(sheet(id))-sx_new, sy
				set_id_right@Cell sheet(id), new_cell_id
		loop
		num_cell_x++
		return

	#deffunc div_y int idy_, int sy_new, local id, local idx, local idy	//y方向にシートを分割
		/*
			idy_ : 分割したい行。この行を縮めて下側に新しい行を挿入

			[方針]
				右端から作る
		*/
		//「その下に新しいセルが作られるセル達」のID。左から順に詰める。
			stack_id=get_leftEnd_cell(idy_)
			repeat num_cell_x-1, 1
				stack_id(cnt)=get_id_right@Cell(sheet(stack_id(cnt-1)))
			loop

		new_cell_id=INVALID_CELL_ID
		repeat num_cell_x
			id=stack_id(num_cell_x-1-cnt)
			//新しいセル
				sx=get_sx@Cell(sheet(id))
				newmod sheet, Cell, sx, sy_new, get_used@Cell(sheet(id)), new_cell_id, get_id_lower@Cell(sheet(id))
				new_cell_id=stat
			//既存のセルの調整
				set_size@Cell sheet(id), sx, get_sy@Cell(sheet(id))-sy_new
				set_id_lower@Cell sheet(id), new_cell_id
		loop
		num_cell_y++
		return

	#defcfunc top_continuous_free_cell int idx_, int idy_, local id, local id2, local idy	//そのセルを含む列の、そのセルと連続した空きセルのうち最上のもの
		id=index2id(idx_,idy_) : idy=idy_
		repeat idy_
			idy-- : id2=index2id(idx_,idy)
			if (get_used@Cell(sheet(id2))==TRUE) {break}
			id=id2
		loop
		return id

	#defcfunc leftEnd_continuous_free_cell int idx_, int idy_, local id, local id2, local idx	//そのセルを含む行の、そのセルと連続した空きセルのうち最左のもの
		id=index2id(idx_,idy_) : idx=idx_
		repeat idx_
			idx-- : id2=index2id(idx,idy_)
			if (get_used@Cell(sheet(id2))==TRUE) {break}
			id=id2
		loop
		return id

	#deffunc indicate_cell int id_, local idx, local idy, local x, local y	//デバッグ用。指定のセルを強調表示
		id2index id_, idx,idy
		index2pos idx,idy, x,y
		color 255,0,0
		line x,y, x+get_sx@Cell(sheet(id_))-1,y+get_sy@Cell(sheet(id_))-1
		line x+get_sx@Cell(sheet(id_))-1,y, x,y+get_sy@Cell(sheet(id_))-1
		return

	#deffunc draw int idx_, int idy_, int sx_, int sy_, local x, local y	//矩形の描画
		/*
			idx_,idy_ : 列,行
			sx_,sy_ : 矩形のサイズ
		*/
		color rnd(200),rnd(200),rnd(200)
		index2pos idx_,idy_, x,y
		boxf x,y, x+sx_-1, y+sy_-1
		return

	#defcfunc local place_at int id_, int sx_, int sy_, local id, local id2, local idx, local idy	//そのセルを左上として可能ならば矩形を配置する
		/*
			id_ : セルのポインタ
			sx_, sy_ : 矩形サイズ
		*/
		#ifdef DEBUG@
			if (get_used@Cell(sheet(id_))==TRUE) {
				indicate_cell id_
				logmes ""
				repeat get_num_try_cells@class_try_cells(try_cells)
					logmes get_try_cell@class_try_cells(try_cells, cnt)
				loop
			}
			assert(get_used@Cell(sheet(id_))==FALSE)
		#endif
		flg_cannot=FALSE
		//x方向の必要セル数を調べる
			num_cell_x_require=1
			id=id_ : sx_remain=sx_
			repeat
				if (get_used@Cell(sheet(id))) {flg_cannot=TRUE : break}
				sx_remain-=get_sx@Cell(sheet(id))
				if (sx_remain<=0) {break}
				num_cell_x_require++
				if (is_rightEnd@Cell(sheet(id))) {flg_cannot=TRUE : break}
				id=get_id_right@Cell(sheet(id))
			loop
			if (flg_cannot) {return FALSE}
		//y方向の必要セル数を調べる
			num_cell_y_require=1
			id=id_ : sy_remain=sy_
			repeat
				if (get_used@Cell(sheet(id))) {flg_cannot=TRUE : break}
				sy_remain-=get_sy@Cell(sheet(id))
				if (sy_remain<=0) {break}
				num_cell_y_require++
				if (is_bottom@Cell(sheet(id))) {flg_cannot=TRUE : break}
				id=get_id_lower@Cell(sheet(id))
			loop
			if (flg_cannot) {return FALSE}
		//配置
			id2index id_, idx, idy
			idx_used_cell_rightmost=idx+num_cell_x_require-1	//今回消費されるセルの中で最も右側のもののxインデックス
			idy_used_cell_bottom=idy+num_cell_y_require-1

			//食べ残しが発生したセルを分割
				if (sx_remain<0) {div_x idx_used_cell_rightmost, -sx_remain}
				if (sy_remain<0) {div_y idy_used_cell_bottom, -sy_remain}

			//使用済みセルをマーク
				id=id_
				repeat num_cell_x_require
					id2=id
					repeat num_cell_y_require
						set_used@Cell sheet(id2), TRUE
						id2=get_id_lower@Cell(sheet(id2))
					loop
					id=get_id_right@Cell(sheet(id))
				loop

			//新しい矩形配置試行セルの登録
				if (idx_used_cell_rightmost<num_cell_x-1) {
					id=top_continuous_free_cell(idx_used_cell_rightmost+1, idy)
					add_try_cell@class_try_cells try_cells, id, id2distance(id)
				}
				if (idy_used_cell_bottom<num_cell_y-1) {
					id=leftEnd_continuous_free_cell(idx, idy_used_cell_bottom+1)
					add_try_cell@class_try_cells try_cells, id, id2distance(id)
				}

			//描画
				draw idx,idy, sx_,sy_
		return TRUE

	#defcfunc place int sx_, int sy_, local id	//できるだけ原点に近い場所に矩形を配置する。矩形配置試行セルで片っ端から試す。どうしても無理なら FALSE を返す。
		assert((sx_>=1)&&(sy_>=1))
		debugmes "num_cell_x,num_cell_y = "+num_cell_x+","+num_cell_y
		debugmes "there are "+get_num_try_cells@class_try_cells(try_cells)+" try-cells."
		return_code=FALSE
		repeat get_num_try_cells@class_try_cells(try_cells)
			id=get_try_cell@class_try_cells(try_cells, cnt)
			if (get_used@Cell(sheet(id))) {remove_try_cell@class_try_cells try_cells, id : continue}	//もしも矩形配置試行セルが使用済みになっているのを見つけたら削除しておく。これ重要
			debugmes "trying to use cell "+id
			if (place_at(id, sx_, sy_)) {
				remove_try_cell@class_try_cells try_cells, id
				return_code=TRUE
				debugmes "  ->SUCCEEDED"
				break
			} else {
				debugmes "  ->FAILED"
			}
		loop
		return return_code
#global

/* main */
	#uselib "winmm"
		#cfunc timeGetTime "timeGetTime"

	#define WID_MAIN	0
	#define NUM_SQUARE	100

	screen WID_MAIN, SX_FIELD, SY_FIELD

	//よ~い...
		mes str(NUM_SQUARE)+" squares"
		mes "ready..."
		repeat 3 : mes 3-cnt : wait 100 : loop

	//どん!
		time_start=timeGetTime()
		randomize
		init_sheet	//シートを初期化
		repeat NUM_SQUARE
			//新たに追加する矩形のサイズ
				sx_new=limit(100-((cnt/10)*10) ,1) : sy_new=limit(100-((cnt/10)*10) ,1)
				//sy_new=int((0.5+0.1*rnd(11))*sx_new)	//縦横比のバリエーションをもたせる場合はここをコメントアウト
				sx_new+=sx_new\2 : sy_new+=sy_new\2//偶数にする
			//追加
				debugmes "square "+(cnt+1)
				if (place(sx_new, sy_new)) {
					debugmes "placement SUCCEEDED"
				} else {
					debugmes "placement FAILED"
				}
				debugmes "------------------------------"
				title str(cnt+1)+" squares"	//コメントアウトすると高速
		loop

	//結果発表
		time_end=timeGetTime()
		dialog "required time : "+(time_end-time_start) + " ms"

HSP テキストルーレット

#cmpopt varinit 1
#packopt name "txtLret"
#packopt xsize 600,ysize 400
#include "XorShift.as"

new@XorShift rand

#module GUI
	#deffunc GUIMain
		screen 0,600,400
		title "テキストルーレット!"
		color 51,153,255
		boxf 0
		color 0,0,153
		font "Meiryo UI",16
		objmode 2

		pos 210,15
		mes "ルーレットしたい値を入れてね。"

		pos 10,40
		sdim txtList,0x7FFF
		#enum txtListID=0
		mesbox txtList,580,260

		pos 140,310
		objsize 200,24
		#enum onclickLretID
		button gosub "Let's ルーレット!",*onclickLret

		pos 350,310
		objsize 100,24
		#enum onclickDefaultID
		button gosub "デフォルト",*onclickDefault

		pos 10,345
		sdim resultList,0xFF
		#enum resultListID
		input resultList,580,25
	return

*onclickLret
		lretMain
	return
*onclickDefault
		lretDefault
	return
#global

#module Lret
	#deffunc lretMain
		sdim txtListValue
		split txtList@GUI,"\n",txtListValue
		objprm resultListID@GUI,txtListValue(xsRandInt(rand@,0,length(txtListValue)-1))
	return

	#deffunc lretDefault
		mhList={"大剣
			太刀
			片手剣
			双剣
			ランス
			ガンランス
			ハンマー
			狩猟笛
			操虫棍
			穿龍棍
			ライトボウガン
			ヘビィボウガン
			弓"}
		objprm txtListID@GUI,mhList
	return
#global

GUIMain

HSP MIDIキーボードの鍵盤入力を取得

; KORGのnanoKEY2でしか動作確認していないのでそこんとこよろしく
; 別にこれ↓やっておく必要ないんだけど渡された数値表示するよりはわかりやすいかと
	sdim code,64,128
	code(0x0)  = "c ","c#","d ","d#","e ","f ","f#","g ","g#","a ","a#","b ","c ","c#","d ","d#"
	code(0x10) = "e ","f ","f#","g ","g#","a ","a#","b ","c ","c#","d ","d#","e ","f ","f#","g "
	code(0x20) = "g#","a ","a#","b ","c ","c#","d ","d#","e ","f ","f#","g ","g#","a ","a#","b "
	code(0x30) = "c ","c#","d ","d#","e ","f ","f#","g ","g#","a ","a#","b ","c ","c#","d ","d#"
	code(0x40) = "e ","f ","f#","g ","g#","a ","a#","b ","c ","c#","d ","d#","e ","f ","f#","g "
	code(0x50) = "g#","a ","a#","b ","c ","c#","d ","d#","e ","f ","f#","g ","g#","a ","a#","b "
	code(0x60) = "c ","c#","d ","d#","e ","f ","f#","g ","g#","a ","a#","b ","c ","c#","d ","d#"
	code(0x70) = "e ","f ","f#","g ","g#","a ","a#","b ","c ","c#","d ","d#","e ","f ","f#","g "
	repeat length(code)
		code(cnt)=code(cnt)+" ("+(cnt/12-3)+")"
	loop

#define CALLBACK_NULL     0x00000000
#define CALLBACK_FUNCTION 0x00030000
#define MMSYSERR_NOERROR 0x0
#define MIM_DATA     0x3C3
#define MIM_ERROR    0x3C5
#define MIM_LONGDATA 0x3C4

	title "MIDIコントローラの入力取得"

#include "hscallbk.as"	;ちょくとさんのコールバックプラグイン
#include "winmm.as"

#uselib ""
#func clbkGetMidi "" int,int,int,int,int

	md_getmax = 24		; 同時認識最大キー数
	dim md_current,md_getmax
	repeat md_getmax
		md_current(cnt)=-1
	loop
	onexit *lEnd
	textMidiInfo = ""	; 画面に表示させる情報
	md_id = 0			; とりあえず0番目のデバイスを選択
	md_hnd = 0			; ハンドル

	; 有効なデバイス数を取得
	midiInGetNumDevs
	md_cnt = stat
	if md_cnt == 0 {
		dialog "接続されていません"
		goto *lEnd
	}

	; デバイスの情報を取得
	dim md_caps,11
	midiInGetDevCaps md_id, varptr(md_caps), 44
	md_caps_mid = md_caps(0) & 0xFF
	md_caps_pid = (md_caps(0)>>8) & 0xFF
	md_caps_ver = md_caps(1)
	sdim md_caps_name,32
	memcpy md_caps_name, md_caps, 32, 0, 8

	; デバイスの情報を表示
	font "meiryo",14
	objmode 2,1
	objsize 100,30
	pos ginfo_winx-110,10
	button gosub "リセット",*lMidiReset
	pos 10, 10
	mes "wMid : "+md_caps_mid
	mes "wPid : "+md_caps_pid
	mes "vDriverVersion : "+strf("%x",md_caps_ver)
	mes "szPname : "+md_caps_name

	; コールバック関数登録
	setcallbk procGetMidi, clbkGetMidi, *lGetMidi

	; 受付開始
	gosub *lMidiOpen

	stop

; デバイスの入力受け付け開始
*lMidiOpen
	; デバイスを開く
	midiInOpen varptr(md_hnd), md_id, varptr(procGetMidi), 0, CALLBACK_FUNCTION
	textMidiInfo = "\nmidiOpen : "+stat+"\nHndle : "+md_hnd
	if stat != MMSYSERR_NOERROR {
		dialog "midiInエラー"
		goto *lEnd
	}
	; デバイスの使用開始
	midiInStart md_hnd
	gosub *lDrawMidiInfo
	return

; デバイスの入力受け付け停止、情報リセット、閉じる
*lMidiClose
	if md_hnd!=0 {
		midiInStop md_hnd
		midiInReset md_hnd
		midiInClose md_hnd
	}
	return

; 意図的なリセット
; リセット直後に入力があるような状態は避けてください
*lMidiReset
	gosub *lMidiClose
	repeat md_getmax
		md_current(cnt)=-1
	loop
	gosub *lMidiOpen
	return

; 入力情報の表示
; 単純に textMidiInfo に入っている文字を描画するだけ
*lDrawMidiInfo
	redraw 0,0,240,640,480
	color 255,255,255 : boxf 0,240,640,480
	color 0,0,0
	pos  10, 240 : mes "Info : "+textMidiInfo
	pos 200, 240 : mes "現在入力中のキー"
	repeat md_getmax
		if md_current(cnt)!=-1{
			mes ""+code(md_current(cnt))
		}
		if (cnt\8)==7 : pos ginfo_cx+80,260
	loop
	redraw 1,0,240,640,480
	return

; コールバック
;	CALLBACK MidiInProc(
;		HMIDIIN hMidiIn,
;		UINT wMsg,
;		DWORD dwInstance,
;		DWORD dwParam1,
;		DWORD dwParam2
;	)
*lGetMidi
	clbk_md_hnd  = callbkarg(0)
	clbk_md_msg  = callbkarg(1)
	clbk_md_ins  = callbkarg(2)
	clbk_md_prm1 = callbkarg(3)
	clbk_md_prm2 = callbkarg(4)
	textMidiInfo = ""
	if clbk_md_hnd == md_hnd {
		; エラー
		if clbk_md_msg == MIM_ERROR {
			textMidiInfo = "\nエラー"
			textMidiInfo+= "\nParam1 : "   + strf("0x%X",clbk_md_prm1)
			textMidiInfo+= "\nParam2 : "   + strf("0x%X",clbk_md_prm2)
			gosub *lMidiReset
		; 情報取得
		} else:if clbk_md_msg == MIM_DATA {
			textMidiInfo+= "\nMIM_DATA"
			textMidiInfo+= "\nMsg : "      + strf("0x%X",clbk_md_msg)
			textMidiInfo+= "\nInstance : " + clbk_md_ins
			textMidiInfo+= "\nParam1 : "   + strf("0x%X",clbk_md_prm1)
			textMidiInfo+= "\nParam2 : "   + clbk_md_prm2+" ms"
			textMidiInfo+= "\n"

			; この辺はもしかするとデバイスによって異なるかも
			md_get_code  = (clbk_md_prm1>>8) & 0xFF		; 押したキー
			md_get_state = (clbk_md_prm1)>>4 & 0xF		; キーの押下状態
			md_get_gain  = (clbk_md_prm1>>16) & 0xFF	; 押下した強さ

			; 表示用に内容解析
			textMidiInfo+= "\n音 : "+code(md_get_code)
			if md_get_state == 9 {
				textMidiInfo+= "\n押した"
				_flag = 0
				_cur = -1
				repeat md_getmax
					if md_current(cnt)==md_get_code {
						_flag = 1
					} else:if _cur==-1 && md_current(cnt)==-1 {
						_cur = cnt
					}
					if _flag==1 && _cur!=-1 : break
				loop
				if _flag == 0 && _cur!=-1 {
					md_current(_cur) = md_get_code
				}
			} else:if md_get_state == 8 {
				textMidiInfo+= "\n離した"
				repeat md_getmax
					if md_current(cnt)==md_get_code {
						md_current(cnt) = -1
					}
				loop
			}
			textMidiInfo+= "\n強さ : "+strf("%d%%",md_get_gain*100/127)
		}
	}
	gosub *lDrawMidiInfo
	return

; 終了
*lEnd
	gosub *lMidiClose
	end

HSP HighDPI実験

#include "hspdsc.as"
#runtime "hsp3HighDPI"
#include "gdi32.as"
#include "user32.as"
#module
#define LOGPIXELSX 88
#define LOGPIXELSY 90
#defcfunc getScale int mode, int size
	// 現在のDPI -> 96dpi
	if 0 == mode : return int((1.0 * size * dpiX) / 96.0)
	if 1 == mode : return int((1.0 * size * dpiY) / 96.0)
	// 96dpi -> 現在のDPI
	if 2 == mode : return int((1.0 * size * 96.0) / dpiX)
	if 3 == mode : return int((1.0 * size * 96.0) / dpiY)
return 0
#defcfunc getFontScale int size
return int(1.0 * size * (1.0 * dpiY / 72.0) * (72.0 / 96.0))
#deffunc getDPI
	GetDC 0
	sHdc = stat
	GetDeviceCaps sHdc, LOGPIXELSX
	dpiX = stat
	GetDeviceCaps sHdc, LOGPIXELSY
	dpiY = stat
	ReleaseDC 0, sHdc
return
#global

	b = 1.4

	getDPI

	screen 0, getScale(0, 300.0*b), getScale(1, 184.0*b)
	title "HSPDSC Video Capture"

	dsc_Init

*main
	cls
	id = 0
	font "Meiryo UI", getFontScale(12.0*b), 16
	objmode 2, 1
	sdim devList, dsc_GetDeviceListSize()
	dsc_GetDeviceList devList

	mes "▼ ビデオデバイスリスト"
	objsize getScale(0, 300.0*b), getScale(1, 100.0*b)
	listbox id, 0, devList
	objid_Listbox = stat

	objsize getScale(0, 300.0*b), getScale(1, 20.0*b)

	button "ビデオデバイスリストの再読み込み", *main
	objid_Button_ReLoadDevice = stat

	button gosub "デバイスを開く", *OpenDevice
	objid_Button_DeviceOpen = stat

	button gosub "デバイスを閉じる", *CloseDevice
	objid_Button_DeviceClose = stat
	objenable objid_Button_DeviceClose, 0

	onexit gosub *Exit
	onexit 0

stop

*OpenDevice
	if ( -1 == id ) {
		dialog "選択してください。"
		return
	}

	gosub *ButtonDisable

	dsc_SetActiveSel 0
	dsc_Open id, 0, 0, 0, 0
	if stat < 0 {
		dialog "デバイスのオープンに失敗しました。\nSTAT = " + stat
		gosub *ButtonEnable
		return
	}
	dsc_Play2

	onexit 1

return
*CloseDevice
	dsc_Stop
	dsc_Close
	onexit 1
	gosub *ButtonEnable
return
*ButtonEnable
	objenable objid_Listbox, 1
	objenable objid_Button_DeviceOpen, 1
	objenable objid_Button_DeviceClose, 0
	objenable objid_Button_ReLoadDevice, 1
return
*ButtonDisable
	objenable objid_Listbox, 0
	objenable objid_Button_DeviceOpen, 0
	objenable objid_Button_DeviceClose, 1
	objenable objid_Button_ReLoadDevice, 0
return

*Exit
	dsc_Stop
	dsc_Close
	dsc_Exit
	end : end
return

HSP モジュール変数を別の変数へ移動させる

	//自由に使ってください。tds12
	#module m a
	#modinit int _a
		a = _a
	return
	#modcfunc f
	return a
	#modfunc del
		delmod thismod
	return
	#global
	#module
	#deffunc toclone var
	#deffunc _toclone int ppval
		dupptr pval,ppval,48,4
		wpoke pval,2,2
	return
	#deffunc toinited var _mv
		toinited1 _mv
		toinited2 _mv
	return
	#deffunc toinited1 var
	#deffunc _toinited1 int ppval
		dupptr pval,ppval,48,4
		wpoke pval,2,1
	return
	#deffunc toinited2 var _mv
		pmv = varptr(_mv)
		dupptr fv,pmv,16,4
		wpoke fv,0,1
	return
	return
	#global
	newmod inst,m,3
	inst2 = inst
	toclone inst
	inst = 2
	mes f(inst2)
	toinited inst2
	delmod inst2

HSP 【HSP3】strrep命令を入れ子(ネスト)にすると、意図した動作をしない

#module _Mod_HTML_
// 指定された文字列のHTMLエスケープを行います
#defcfunc escapeHtml str html, \
	local tmp
;
	tmp =  html
	strrep tmp, "&", "&amp;"
	strrep tmp, "<", "&lt;"
	strrep tmp, ">", "&gt;"
	strrep tmp, "'", "&apos;"
	strrep tmp, "\"", "&quot;"
;
	logmes tmp
return tmp
#global
;
	strHtml = "<b>$A$</b>"
	strIns = "こんにちは><"
;
	; 予想: <b>$A$</b>
	; 結果: <b>$A$</b>
	mes "☆1: " + strHtml
;
	; ※ 単体では正常動作します。
	; 予想: こんにちは&gt;&lt;
	; 結果: こんにちは&gt;&lt;
	mes "☆2: " + escapeHtml(strIns)
;
	; ※ strrepを入れ子にすると予想と違う結果に…
	; $A$ という文字列を探して、エスケープ済みの文字列に置き換えます。
	; 予想: <b>こんにちは&gt;&lt;</b>
	; 結果: こんにちは&gt;&lt;
	strrep strHtml, "$A$", escapeHtml(strIns)
	mes "☆3: " + strHtml
;
	; ※ 入れ子にしなければ、予想通りの動きをする。
	; 予想: <b>こんにちは&gt;&lt;</b>
	; 結果: <b>こんにちは&gt;&lt;</b>
	strHtml = "<b>$A$</b>"
	tmp = escapeHtml(strIns)
	strrep strHtml, "$A$", tmp
	mes "☆4: " + strHtml

HSP 変数引数に値を渡す

#module
// 文字列への参照を作る関数
#define global ctype ref_xs(%1) \
	%t__ref %i0 \
	%p@__ref(ref_xs_@__ref(%1, %p@__ref)) \
	%o0

#defcfunc ref_xs_@__ref str value, array ref_med
	ref_med = value //moveしたいところ
	return 0
#global

//例

	//x = strtrim(" hello world! ") //NG

	x = strtrim(ref_xs("  hello world!  "))
	mes "{" + x + "}"
	//=> "{hello world!}"

HSP 二重振り子RK4シミュonHSP(修正版2)

#include "hsp3dish.as"
#packopt name "DPRK4"

/* モジュール認識 */
modDetect@mod_simuCfg
modDetect@mod_simu

/* 定数宣言 */
//#define hsproom
#define wsx	640 //("windowSizex") ウィンドウxサイズ
#define wsy	640
#packopt xsize wsx
#packopt ysize wsy
#define frmIntvl	16	//[ms] ("frameInterval") フレーム間隔
#define slfreq		2	//[ms] ("simulationLoopFrequency") シミュレーションループ周期
#define mtr2px	100.0	//[px/meter] ("meterToPixel") メートル→ピクセル 変換係数
#const Oxw	wsx/2	//[px] ("OriginxOnWindow") 物理系原点のウィンドウ上でのx座標
#const Oyw	wsy/2	//[px]
#define dt	0.01	//[s] タイムステップ
#const double hdt dt/2	//[s] ("half dt") dt/2
#define g	9.8	//[m/s^2]
#define σ	1.0	//[kg/m^2] 錘の面密度
#define mmin	0.1	//[kg] 質量の下限
#define mmax	25.0	//[kg] 〃上限

/* 変数初期化 */
	/* エイリアス */
	#define m1	m(0)
	#define m2	m(1)
	#define r1	r(0)
	#define r2	r(1)
	#define l1	l(0)
	#define l2	l(1)
	#define θ1	θ(0)
	#define θ2	θ(1)
	#define r1w	rw(0)
	#define r2w	rw(1)
	#define l1w	lw(0)
	#define l2w	lw(1)
	#define x1	x
	#define x2	x(1)
	#define y1	y
	#define y2	y(1)
	/* 物理系 */
	m = 1.5,1.0	//[kg] m1,m2
	r = sqrt(m1/σ/4/m_pi),sqrt(m2/σ/4/m_pi) //[m] おもり1,2の半径
	l = 1.5,1.0	//[m] l1,l2
	θ = deg2rad(45),deg2rad(90)	//[rad] θ1,θ2
	x = l1*sin(θ1),x+l2*sin(θ2)
	y = l1*cos(θ1),y+l2*cos(θ2)
	/* システム */
	ddim PRESET,5,6

/* 起動 */
*boot
	title "二重振り子シミュレーター"
	exist "save/preset.dat" : if strsize = -1 : initPreset	//プリセットデータが無ければ初期化する
	goto *boot@mod_simuCfg

#module mod_simuCfg	/* シミュレーション設定 */
	#define wsx			wsx@
	#define wsy			wsy@
	#define frmIntvl	frmIntvl@*3
	#define mtr2px		mtr2px@
	#define Oxw			Oxw@
	#define Oyw			Oyw@
	//#define mmin	mmin@
	//#define mmax	mmax@
	#define m		m@
	#define m1		m@
	#define m2		m@(1)
	#define l1		l@
	#define l2		l@(1)
	#define θ1		θ@
	#define θ2		θ@(1)
	#define x1		x@
	#define x2		x@(1)
	#define y1		y@
	#define y2		y@(1)
	#define r		r@
	#define r1		r@
	#define r2		r@(1)
	#define rw		rw@
	#define r1w		rw@
	#define r2w		rw@(1)
	#define l1w		lw@
	#define l2w		lw@(1)
	#define x1w		xw@
	#define x2w		xw@(1)
	#define y1w		yw@
	#define y2w		yw@(1)

	#define fontsize	16
	#define sxMS	300	//[px] ("sizexOfMassSlider") 質量調節スライダ(MS)の長さ
	#define syMS	4	//[px] 〃太さ
	#define sxMSK	8	//[px] ("sizexOfMassSliderKnob") MSつまみ(MSK)の横幅
	#define syMSK	14	//[ps] 〃高さ
	#deffunc local modDetect
		return

	*boot
		LBTNDWN = 0	//汎用変数初期化
		initUI
		usrRqstStat = 0	//("userRequestStatus") ユーザーからの要求の状態。(0,1,2,3) = (通常,プリセットロード要求,プリセット保存要求,シミュレーション開始要求)

	*main	//メインループ
		repeat
			handleMassSlds	//MS管理
			handlePndlmDrg	//おもりドラッグ管理
			reflesh	//画面更新
			if usrRqstStat : break	//ユーザーから新たなアクションの要求があるなら
			await frmIntvl
		loop
		switch usrRqstStat
			case 1
				loadPreset
				initUI
				goto *boot
			case 2
				savePreset
				initUI
				goto *boot
				swbreak
			case 3
				goto *boot@mod_simu
				swbreak
			default
				fatalError
		swend
		stop

	*btnIntrpt	/* ボタン割り込みへの対応 */
		usrRqstStat = 1+stat
		return

	#deffunc local initUI	/* UI初期化 */
		cls
		font msgothic,fontsize
		/* おもり */
			r1w = r1*mtr2px : r2w = r2*mtr2px	//[px] r1,r2の、ウィンドウ上での長さ
			l1w = l1*mtr2px : l2w = l2*mtr2px	//[px]
			x1w = Oxw+x1*mtr2px : x2w = Oxw+x2*mtr2px	//x1,x2の、ウィンドウ上での位置
			y1w = Oyw+y1*mtr2px : y2w = Oyw+y2*mtr2px
		/* MS */
			MSV = m2MSV(m1),m2MSV(m2)	;MSの値。0.0~1.0。要素0,1はm1,m2のスライダに対応。
			pxMSK = 140-sxMSK/2,pxMSK	;[px] MSつまみの左上x座標。要素0,1はm1,m2のスライダに対応。
			pyMSK = wsy-5-fontsize*2+8+syMS/2-syMSK/2,pyMSK+fontsize	;〃y
		/* 各種ボタン */
			#define sxBtn	180	//("sizexOfButton") ボタンの横幅
			#define syBtn	20
			objsize sxBtn,syBtn
			pos wsx-5-sxBtn,wsy-5-syBtn*3-2*2 : button gosub "プリセット読込",*btnIntrpt
			pos wsx-5-sxBtn,wsy-5-syBtn*2-2 : button gosub "プリセット保存",*btnIntrpt
			pos wsx-5-sxBtn,wsy-5-syBtn : button gosub "シミュレーション開始",*btnIntrpt
		return

	#deffunc local handleMassSlds	/* MS管理ルーチン */
		getkey LBTNDWN,1 : if LBTNDWN = 0 : return
		repeat 2	/* MS1,2 */
			if (pxMSK(cnt) <= mousex)&(mousex <= pxMSK(cnt)+sxMSK)&(pyMSK(cnt) <= mousey)&(mousey <= pyMSK(cnt)+syMSK) {	//カーソルがつまみに重なっているなら
				xofst = pxMSK(cnt)-mousex : yofst = pyMSK(cnt)-mousey	//マウスカーソルに対するつまみの相対位置
				lastmx = mousex	//以前のマウスカーソルのx座標
				cnt0 = cnt
				repeat
					getkey LBTNDWN,1 : if LBTNDWN = 0 : break
					if mousex != lastmx {	//マウスカーソルが横に動いたら
						lastmx = mousex
						pxMSK(cnt0) = limit(mousex+xofst, msv2pxMSK(0),msv2pxMSK(1))	//つまみ位置決定
						MSV(cnt0) = pxMSK2msv(pxMSK(cnt0))	//MS値計算
						m(cnt0) = MSV2m(MSV(cnt0))	//質量計算
						r(cnt0) = m2r(m(cnt0)) : rw(cnt0) = r(cnt0)*mtr2px	//半径計算
						reflesh
					}
					await frmIntvl
				loop
			}
		loop
		return

	#deffunc local handlePndlmDrg	/* おもりドラッグ管理 */
		getkey LBTNDWN,1 : if LBTNDWN = 0 : return
		/* おもり2 */
			if powf(x2w-mousex,2)+powf(y2w-mousey,2) <= powf(r2w,2) {
				xmofst = x2w-mousex : ymofst = y2w-mousey
				lastmx = mousex : lastmy = mousey
				repeat
					getkey LBTNDWN,1 : if LBTNDWN = 0 : break
					if (mousex != lastmx)|(mousey != lastmy) {
						lastmx = mousex : lastmy = mousey
						x2w = mousex+xmofst : y2w = mousey+ymofst
						calcPndlmPosFromUI
						reflesh	//画面更新
					}
					await frmIntvl
				loop
			}
		/* おもり1 */
			if powf(x1w-mousex,2)+powf(y1w-mousey,2) <= powf(r1w,2) {	//マウスカーソルがおもりに重なっているなら
				xmofst = x1w-mousex : ymofst = y1w-mousey	//マウスカーソルに対するおもりの中心の相対位置
				xRelPw = x2w-x1w : yRelPw = y2w-y1w	//[px] おもり1に対する2の相対位置
				lastmx = mousex : lastmy = mousey	//以前のマウスカーソルの位置
				repeat
					getkey LBTNDWN,1 : if LBTNDWN = 0 : break
					if (mousex != lastmx)|(mousey != lastmy) {	//マウスカーソルが動いたら
						lastmx = mousex : lastmy = mousey
						x1w = mousex+xmofst : y1w = mousey+ymofst
						x2w = x1w+xRelPw : y2w = y1w+yRelPw
						calcPndlmPosFromUI
						reflesh	//画面更新
					}
					await frmIntvl
				loop
			}
		return

	#deffunc local calcPndlmPosFromUI	/* ウィンドウ上でのおもりの位置からその他の位置情報をを計算 */
		x1 = double(x1w-Oxw)/mtr2px : y1 = double(y1w-Oyw)/mtr2px
		l1 = sqrt(x1*x1+y1*y1) : l1w = l1*mtr2px
		θ1 = atan(x1,y1)
		x2 = x1+double(x2w-x1w)/mtr2px : y2 = y1+double(y2w-y1w)/mtr2px
		l2 = sqrt(powf(x2-x1,2)+powf(y2-y1,2)) : l2w = l2*mtr2px
		θ2 = atan(x2-x1,y2-y1)
		return

	#deffunc local reflesh /* 再描画 */
		redraw 0
			color : boxf
			drawCdntAx	//座標軸
			drawPndlms	//振り子
			drawInfos	//各種情報
			drawMassSlds	//MS
		redraw 1
		return

	#deffunc local drawMassSlds /* MS描画*/
		repeat 2
			ytmp = wsy-5-fontsize*(2-cnt)+8
			color 100,100,100
			boxf 140,ytmp, 140+sxMS,ytmp+syMS
			pxMSK(cnt) = msv2pxMSK(MSV(cnt))
			color 200,150,100
			boxf pxMSK(cnt),pyMSK(cnt), pxMSK(cnt)+sxMSK,pyMSK(cnt)+syMSK
		loop
		return
#global

#module mod_simuCfg_2
	//#define mtr2px	mtr2px@
	//#define Oxw		Oxw@
	//#define Oyw		Oyw@
	#define mmin	mmin@
	#define mmax	mmax@
	//#define θ1		θ@
	//#define θ2		θ@(1)
	//#define l1w		lw@
	//#define l2w		lw@(1)

	#define sxMS	sxMS@mod_simuCfg	//[px] ("sizexOfMassSlider") 質量調節スライダ(MS)の長さ
	#define syMS	syMS@mod_simuCfg	//[px] 〃太さ
	#define sxMSK	sxMSK@mod_simuCfg	//[px] ("sizexOfMassSliderKnob") MSつまみ(MSK)の横幅
	#define syMSK	syMSK@mod_simuCfg	//[ps] 〃高さ

	#defcfunc m2MSV double m	//質量→MS値
		return (m-mmin)/(mmax-mmin)

	#defcfunc MSV2m double msv	//MS値→質量
		return mmin+msv*(mmax-mmin)

	#defcfunc msv2pxMSK double msv	//MS値→つまみの左上x座標
		return 140+msv*sxMS-sxMSK/2

	#defcfunc pxMSK2msv	double pxMSK//MSつまみの左上座標→MS値
		return double(pxMSK+sxMSK/2-140)/sxMS
#global

#module mod_commonCalc
	#define σ	σ@

	#defcfunc m2r double m	//質量→半径
		return sqrt(m/σ/4/m_pi)
#global

#module mod_simu
	#define wsx			wsx@
	#define wsy			wsy@
	#define slfreq		slfreq@
	#define frmIntvl	frmIntvl@
	#define mtr2px		mtr2px@
	#define Oxw			Oxw@
	#define Oyw			Oyw@
	#define dt		dt@
	#define hdt		hdt@
	#define g		g@
	#define m1		m@
	#define m2		m@(1)
	#define l1		l@
	#define l2		l@(1)
	#define θ1		θ@
	#define θ2		θ@(1)
	#define x1		x@
	#define x2		x@(1)
	#define y1		y@
	#define y2		y@(1)

	#define fontsize	16
	#define numPtTrack		100		//("numberOfPointsOfTrack") おもり2軌跡点の記録数
	#define TrkSmplngIntvl	dt*2	//[s] ("TrackSamplingInterval") 軌跡サンプリング間隔

	#deffunc local modDetect
		return

	*boot
		initUI
		usrRqstStat = 0	//("userRequestStatus") ユーザーからの要求の状態。(0,1) = (通常,シミュレーション終了要求)
		simuStat = 1	//("simulationStatus") シミュレーションの状態。(0,1) = (停止,実行)
		η = (m1+m2)/m2
		ω1 = 0.0
		ω2 = 0.0
		x1 = l1*sin(θ1) : y1 = l1*cos(θ1)
		x2 = x1+l2*sin(θ2) : y2 = y1+l2*cos(θ2)

		/* おもり2の軌跡点 */
		/*
			おもり2の軌跡点は直近 numPtTRACK 個分を TRACK [numPtTRACK,2] 配列記録する。
			フォーマットはリングバッファと同じ要領。frntTRACK に記録される位置を先頭とし、そこから numPtTRACK 個分描画する。
			古い順に詰まっている。要素 (*,0),(*,1) はそれぞれ然るべき番号の軌跡点のx,y座標。
		*/
		ddim TRACK,numPtTrack,2
		repeat numPtTrack : TRACK(cnt,0) = x2 : TRACK(cnt,1) = y2 : loop
		frntTRACK = 0

	*main
		etls = 0.0	//[s] ("elapsedTimeFromLastStep") 前回ステップ計算からの経過時間
		etlts = 0.0 //[s] ("elapsedTimeFromLastTrackSampling") 前回軌跡サンプリングからの経過時間
		etlf = 0.0	//[ms] ("elapsedTimeFromLastFrame") 前回画面更新からの経過時間
		repeat
			if etls >= dt : step : etls = -0.001*slfreq							//ステップ計算
			if etlts >= TrkSmplngIntvl : handleTrack : etlts = -0.001*slfreq	//軌跡サンプリング
			if etlf >= frmIntvl : reflesh : etlf = -slfreq						//画面更新
			if usrRqstStat : break
			await slfreq
			if simuStat {
				etls += 0.001*slfreq
				etlts += 0.001*slfreq
			}
			etlf += slfreq
		loop
		goto *boot@mod_simuCfg

	*btnIntrrpt	/* ボタン割り込みへの対応 */
		switch stat
			case 0
				simuStat = 0
				objenable 0,0 : objenable 1,1
				swbreak
			case 1
				simuStat = 1
				objenable 0,1 : objenable 1,0
				swbreak
			case 2
				usrRqstStat = 1
		swend
		return

	#deffunc local initUI	/* UI初期化 */
		cls
		font msgothic,fontsize
		/* 各種ボタン */
		#define sxBtn	180
		#define syBtn	20
		objsize sxBtn,syBtn
		pos wsx-sxBtn-5,wsy-5-syBtn*3-2*2 : button gosub "停止",*btnIntrrpt
		pos wsx-sxBtn-5,wsy-5-syBtn*2-2 : button gosub "再開",*btnIntrrpt : objenable 1,0
		pos wsx-sxBtn-5,wsy-5-syBtn : button gosub "シミュレーション終了",*btnIntrrpt
		return

	#deffunc local step	/* dt後の状態の計算 */
		ξn = θ1,θ2,ω1,ω2 : k1 = f1(ξn),f2(ξn),f3(ξn),f4(ξn)
		ξn2 = ξn+hdt*k1, ξn(1)+hdt*k1(1), ξn(2)+hdt*k1(2), ξn(3)+hdt*k1(3) : k2 = f1(ξn2),f2(ξn2),f3(ξn2),f4(ξn2)
		ξn3 = ξn+hdt*k2, ξn(1)+hdt*k2(1), ξn(2)+hdt*k2(2), ξn(3)+hdt*k2(3) : k3 = f1(ξn3),f2(ξn3),f3(ξn3),f4(ξn3)
		ξn4 = ξn+dt*k3, ξn(1)+dt*k3(1), ξn(2)+dt*k3(2), ξn(3)+dt*k3(3) : k4 = f1(ξn4),f2(ξn4),f3(ξn4),f4(ξn4)
		θ1 += dt/6*(k1 + 2.0*k2 + 2.0*k3 + k4)
		θ2 += dt/6*(k1(1) + 2.0*k2(1) + 2.0*k3(1) + k4(1))
		ω1 += dt/6*(k1(2) + 2.0*k2(2) + 2.0*k3(2) + k4(2))
		ω2 += dt/6*(k1(3) + 2.0*k2(3) + 2.0*k3(3) + k4(3))
		x1 = l1*sin(θ1) : y1 = l1*cos(θ1)
		x2 = x1+l2*sin(θ2) : y2 = y1+l2*cos(θ2)
		return

	#deffunc local reflesh	/* 画面更新 */
		redraw 0
			color : boxf
			drawCdntAx	//座標軸
			drawPndlms	//振り子
			drawTrack	//軌跡
			drawInfos : drawIndo2	//各種情報
		redraw 1
		return

	#deffunc local drawIndo2	/* 各種情報の表示 */
		color 200,200,200
		U = calcU() : K = calcK() : E = U+K
		pos 5,wsy-5-fontsize*9 : mes "U = "+strf("%6.2f", U)+" [J]"
		pos 5,wsy-5-fontsize*8 : mes "K = "+strf("%6.2f", K)+" [J]"
		pos 5,wsy-5-fontsize*7 : mes "E = "+strf("%6.2f", E)+" [J]"
		return

	#deffunc local handleTrack	/* おもり2の軌跡の管理 */
		TRACK(frntTRACK,0) = x2 : TRACK(frntTRACK,1) = y2
		if frntTRACK = numPtTRACK-1 : frntTRACK = 0 : else : frntTRACK ++
		return

	#deffunc local drawTrack	/* おもり2の軌跡の描画 */
		i = frntTRACK
		repeat numPtTrack
			xtmp = Oxw+TRACK(i,0)*mtr2px-3,xtmp+6,xtmp+6,xtmp
			ytmp = Oyw+TRACK(i,1)*mtr2px-3,ytmp,ytmp+6,ytmp+6
			gmode 3, , ,256*cnt/numPtTRACK
			color 50,100,255 : gsquare -1,xtmp,ytmp
			if i = numPtTRACK-1 : i = 0 : else : i ++
		loop
		return

	#defcfunc local calcU	/* 全位置エネルギーの計算 */
		return -(m1+m2)*g*l1*cos(θ1) - m2*g*l2*cos(θ2)

	#defcfunc local calcK	/* 全運動エネルギーの計算 */
		return 0.5*(m1+m2)*l1*l1*ω1*ω1 + 0.5*m2*l2*l2*ω2*ω2 + m2*l1*l2*ω1*ω2*cos(θ1-θ2)
#global

#module mod_simu_2
	#define dt		dt@
	#define hdt		hdt@
	#define g		g@
	#define l1		l@
	#define l2		l@(1)
	#define η		η@mod_simu

	#defcfunc f1 array ξ
		return ξ(2)

	#defcfunc f2 array ξ
		return ξ(3)

	#defcfunc f3 array ξ
		θ1 = ξ : θ2 = ξ(1) : ω1 = ξ(2) : ω2 = ξ(3)
		φ = θ1-θ2 : cosφ = cos(φ)
		return (g*(cosφ*sin(θ2)-η*sin(θ1))-(l1*ω1*ω1*cosφ+l2*ω2*ω2)*sin(φ))/l1/(η-cosφ*cosφ)

	#defcfunc f4 array ξ
		θ1 = ξ : θ2 = ξ(1) : ω1 = ξ(2) : ω2 = ξ(3)
		φ = θ1-θ2 : cosφ = cos(φ)
		return (g*η*(cosφ*sin(θ1)-sin(θ2))+(η*l1*ω1*ω1+l2*ω2*ω2*cosφ)*sin(φ))/l2/(η-cosφ*cosφ)
#global

#module mod_commonDraw
	#define wsx	wsx@
	#define wsy	wsy@
	#define Oxw	Oxw@
	#define Oyw	Oyw@
	#define m1		m@
	#define m2		m@(1)
	#define l1		l@
	#define l2		l@(1)
	#define θ1	θ@
	#define θ2	θ@(1)
	#define r1w	rw@
	#define r2w	rw@(1)
	#define l1w	lw@
	#define l2w	lw@(1)
	#deffunc local modDetect
		return

	#deffunc drawCdntAx	/* ("drawCoordinateAxis") 座標軸の描画 */
		color 100,100,100
		line -1,Oyw,wsx,Oyw
		line Oxw,-1,Oxw,wsy
		return

	#deffunc drawPndlms	/* ("drawPendulums") 振り子の描画 */
		// 注意 hsp3dish では circle で中空円が描けないので一旦塗り潰してから背景色で一回り小さい円を塗り潰して対応する。
		/* おもり1 */
		xtmp = Oxw+l1w*sin(θ1) : ytmp = Oyw+l1w*cos(θ1)
		color 255,255,255 : circle xtmp-r1w,ytmp-r1w, xtmp+r1w,ytmp+r1w, 1
		color : circle xtmp-r1w+1,ytmp-r1w+1, xtmp+r1w-1,ytmp+r1w-1, 1
		color 255,255,255 : line Oxw,Oyw,xtmp,ytmp
		/* おもり2 */
		xtmp2 = xtmp + l2w*sin(θ2) : ytmp2 = ytmp + l2w*cos(θ2)
		color 255,255,255 : circle xtmp2-r2w,ytmp2-r2w, xtmp2+r2w,ytmp2+r2w, 1
		color : circle xtmp2-r2w+1,ytmp2-r2w+1, xtmp2+r2w-1,ytmp2+r2w-1, 1
		color 255,255,255 : line xtmp,ytmp,xtmp2,ytmp2
		return

	#deffunc drawInfos	/* 各種情報の表示 */
		/* 注意
			font 設定の影響を受ける。推奨は msgoshic,16 。
		*/
		fontsize = 16
		color 200,200,200
		pos 5,wsy-5-fontsize*6 : mes "l1 = "+strf("%3.2f",l1)+" [m]"
		pos 5,wsy-5-fontsize*5 : mes "l2 = "+strf("%3.2f",l2)+" [m]"
		pos 5,wsy-5-fontsize*4 : mes "θ1 = "+strf("%6.2f",rad2deg(θ1))+" [deg]"
		pos 5,wsy-5-fontsize*3 : mes "θ2 = "+strf("%6.2f",rad2deg(θ2))+" [deg]"
		pos 5,wsy-5-fontsize*2 : mes "m1 = "+strf("%3.2f",m1)+" [kg]"
		pos 5,wsy-5-fontsize : mes "m2 = "+strf("%3.2f",m2)+" [kg]"
		return
#global

#module mod_loadPreset
	#define wsx			wsx@
	#define wsy			wsy@
	#define frmIntvl	frmIntvl@*3
	#define mtr2px		mtr2px@
	#define fontsize	16
	#define PRESET		PRESET@
	#define σ	σ@
	#define m	m@
	#define m1	m@
	#define m2	m@(1)
	#define l	l@
	#define l1	l@
	#define l2	l@(1)
	#define θ	θ@
	#define θ1	θ@
	#define θ2	θ@(1)
	#define x1	x@
	#define x2	x@(1)
	#define y1	y@
	#define y2	y@(1)
	#define r1	r@
	#define r2	r@(1)
	#define r1w	rw@
	#define r2w	rw@(1)
	#define l1w	lw@
	#define l2w	lw@(1)

	#deffunc loadPreset
		/*
			プリセットからロードする処理をUIも含めて担当する。
			戻り値 : (-1,other) : (ロードせず,ロードされたプリセット番号)

			ウィンドウは cls されることに注意
		*/

		*boot
			/* 未初期化変数警告回避 */
			idSelPs = 0

			/* 直前の設定をバックアップ */
			mbak = m1,m2
			lbak = l1,l2
			θbak = θ1,θ2

			loadPresetFile
			initUI
			usrRqstStat = 0	//("userRequestStatus") ユーザーからの要求の状態。(0,1,2) = (通常,選択プリセット読込要求,読込キャンセル要求)

		*main
			repeat
				reflesh	//画面更新
				if usrRqstStat : break	//ユーザーから新たなアクションの要求があるなら
				await frmIntvl
			loop
			switch usrRqstStat
				case 1
					return idSelPs
				case 2	/* キャンセル */
					/* 設定復元 */
					m = mbak,mbak(1)
					l = lbak,lbak(1)
					θ = θbak,θbak(1)
					r1 = sqrt(m1/σ/4/m_pi) : r2 = sqrt(m2/σ/4/m_pi)
					x1 = l1*sin(θ1) : y1 = l1*cos(θ1)
					x2 = x1+l2*sin(θ2) : y2 = y1+l2*cos(θ2)
					return -1
			swend

		*PsBtnIntrrpt	/* プリセットボタン割り込みへの応答 */
			idSelPs = stat
			l1 = PRESET(stat,0) : l2 = PRESET(stat,1)
			m1 = PRESET(stat,2) : m2 = PRESET(stat,3)
			r1 = sqrt(m1/σ/4/m_pi) : r2 = sqrt(m2/σ/4/m_pi)
			θ1 = PRESET(stat,4) : θ2 = PRESET(stat,5)
			x1 = l1*sin(θ1) : y1 = l1*cos(θ1)
			x2 = x1+l2*sin(θ2) : y2 = y1+l2*cos(θ2)
			r1w = r1*mtr2px : r2w = r2*mtr2px
			l1w = l1*mtr2px : l2w = l2*mtr2px
			return

		*ActBtnIntrpt	/* アクションボタン割り込みへの対応 */
			usrRqstStat = stat-4
			return

	#deffunc local initUI	/* UI初期化 */
		cls
		font msgothic,fontsize

		/* プリセットボタン */
		#define sxPsBtn	50	//("sizexOfPresetButton") プリセットボタンの横幅
		#define syPsBtn	30
		objsize sxPsBtn,syPsBtn
		numVPs = 5	//("numberOfValidPreset") 有効なプリセットの個数
		repeat 5
			pos 200+(sxPsBtn+5)*cnt,wsy-syPsBtn-5 : button gosub ""+cnt+"",*PsBtnIntrrpt
			if PRESET(cnt,0) <= 0 : objenable cnt,0 : numVPs --	//プリセットが記録されていないならボタンを無効化
		loop

		/* アクションボタン */
		#define sxActBtn	100
		#define syActBtn	20
		objsize sxActBtn,syActBtn
		pos wsx-sxActBtn-5,wsy-(syActBtn+5)*2 : button gosub "読込",*ActBtnIntrpt
		if numVPs = 0 : objenable stat,0
		pos wsx-sxActBtn-5,wsy-syActBtn-5 : button gosub "キャンセル",*ActBtnIntrpt

		/* 初期選択 */
		if numVPs {
			repeat 5	/* 最初に見つかった有効なプリセットを選択する */
				if PRESET(cnt,0) > 0 {
					idSelPs = cnt	//選択されているプリセット番号
					l1 = PRESET(cnt,0) : l2 = PRESET(cnt,1)
					m1 = PRESET(cnt,2) : m2 = PRESET(cnt,3)
					r1 = sqrt(m1/σ/4/m_pi) : r2 = sqrt(m2/σ/4/m_pi)
					θ1 = PRESET(cnt,4) : θ2 = PRESET(cnt,5)
					x1 = l1*sin(θ1) : y1 = l1*cos(θ1)
					x2 = x1+l2*sin(θ2) : y2 = y1+l2*cos(θ2)
					r1w = r1*mtr2px : r2w = r2*mtr2px
					l1w = l1*mtr2px : l2w = l2*mtr2px
					break
				}
			loop
		}
		return

	#deffunc local reflesh /* 画面更新 */
		redraw 0
			color : boxf
			drawCdntAx	//座標軸
			drawInfos2	//各種情報
			if numVPs {
				drawPndlms	//振り子
				drawInfos	//各種情報
			}
		redraw 1
		return

	#deffunc local drawInfos2	/* 各種情報表示 */
		color 200,200,200
		pos 200,wsy-syPsBtn*2-15 : mes "プリセットを選択してください"
		if numVPs {
			color 200,150,100
			pos 200+(sxPsBtn+5)*idSelPs+(sxPsBtn-fontsize)/2,wsy-syPsBtn*2+5 : mes "▼"
		}
		return

	#deffunc loadPresetFile
		/*
			プリセットデータをファイルから読み込んでシステムに反映する。
			戻り値 (0,1) : (成功,失敗)
		*/
		exist "save/preset.dat"
		if strsize  = -1 : return 1
		bload "save/preset.dat", PRESET
		return 0
#global

#module mod_savePreset
	#define wsx			wsx@
	#define wsy			wsy@
	#define frmIntvl	frmIntvl@*3
	#define mtr2px		mtr2px@
	#define fontsize	16
	#define PRESET		PRESET@
	#define σ	σ@
	#define m	m@
	#define m1	m@
	#define m2	m@(1)
	#define l	l@
	#define l1	l@
	#define l2	l@(1)
	#define θ	θ@
	#define θ1	θ@
	#define θ2	θ@(1)
	#define x1	x@
	#define x2	x@(1)
	#define y1	y@
	#define y2	y@(1)
	#define r1	r@
	#define r2	r@(1)
	#define r1w	rw@
	#define r2w	rw@(1)
	#define l1w	lw@
	#define l2w	lw@(1)

	#deffunc savePreset
		/*
			プリセットにセーブする処理をUIも含めて担当する。
			戻り値 : (-1,other) : (セーブせず,セーブ先プリセット番号)

			ウィンドウは cls されることに注意
		*/

		*boot
			/* 未初期化変数警告回避 */
			idSelPs = 0

			/* 直前の設定をバックアップ */
			mbak = m1,m2
			lbak = l1,l2
			θbak = θ1,θ2

			loadPresetFile
			initUI
			usrRqstStat = 0	//("userRequestStatus") ユーザーからの要求の状態。(0,1,2) = (通常,選択プリセットへ保存要求,保存キャンセル要求)

		*main
			repeat
				reflesh	//画面更新
				if usrRqstStat : break	//ユーザーから新たなアクションの要求があるなら
				await frmIntvl
			loop

			/* 設定復元 */
			m = mbak,mbak(1)
			l = lbak,lbak(1)
			θ = θbak,θbak(1)
			r1 = sqrt(m1/σ/4/m_pi) : r2 = sqrt(m2/σ/4/m_pi)
			x1 = l1*sin(θ1) : y1 = l1*cos(θ1)
			x2 = x1+l2*sin(θ2) : y2 = y1+l2*cos(θ2)

			switch usrRqstStat
				case 1
					savePresetFile idSelPs
					return idSelPs
				case 2	//キャンセル
					return -1
			swend
			stop

		*PsBtnIntrrpt	/* プリセットボタン割り込みへの応答 */
			idSelPs = stat
			if PRESET(idSelPs,0) > 0 {	//選択プリセットのデータが有効なら
				l1 = PRESET(idSelPs,0) : l2 = PRESET(idSelPs,1)
				m1 = PRESET(idSelPs,2) : m2 = PRESET(idSelPs,3)
				r1 = sqrt(m1/σ/4/m_pi) : r2 = sqrt(m2/σ/4/m_pi)
				θ1 = PRESET(idSelPs,4) : θ2 = PRESET(idSelPs,5)
				x1 = l1*sin(θ1) : y1 = l1*cos(θ1)
				x2 = x1+l2*sin(θ2) : y2 = y1+l2*cos(θ2)
				r1w = r1*mtr2px : r2w = r2*mtr2px
				l1w = l1*mtr2px : l2w = l2*mtr2px
			}
			return

		*ActBtnIntrpt	/* アクションボタン割り込みへの対応 */
			usrRqstStat = stat-4
			return

	#deffunc local initUI	/* UI初期化 */
		cls
		font msgothic,fontsize

		/* プリセットボタン */
		#define sxPsBtn	50	//("sizexOfPresetButton") プリセットボタンの横幅
		#define syPsBtn	30
		objsize sxPsBtn,syPsBtn
		repeat 5 : pos 200+(sxPsBtn+5)*cnt,wsy-syPsBtn-5 : button gosub ""+cnt+"",*PsBtnIntrrpt : loop
		idSelPs = 0	//選択プリセット番号

		/* アクションボタン */
		#define sxActBtn	100
		#define syActBtn	20
		objsize sxActBtn,syActBtn
		pos wsx-sxActBtn-5,wsy-(syActBtn+5)*2 : button gosub "保存",*ActBtnIntrpt
		pos wsx-sxActBtn-5,wsy-syActBtn-5 : button gosub "キャンセル",*ActBtnIntrpt
	return

	#deffunc local reflesh /* 画面更新 */
		redraw 0
			color : boxf
			drawInfos2
			drawCdntAx	//座標軸
			if PRESET(idSelPs,0) > 0 {	//選択プリセットが有効なら
				drawPndlms	//振り子
				drawInfos	//各種情報
			}
		redraw 1
		return

	#deffunc local drawInfos2	/* 各種情報表示 */
		color 200,200,200
		pos 200,wsy-syPsBtn*2-15 : mes "プリセットを選択してください"
		color 200,150,100
		pos 200+(sxPsBtn+5)*idSelPs+(sxPsBtn-fontsize)/2,wsy-syPsBtn*2+5 : mes "▼"
		return

	#deffunc savePresetFile int i
		/*
			選択プリセットに現在の設定を書き込んでファイルに保存する。
			i : 選択プリセット番号
		*/
		PRESET(i,0) = l1 : PRESET(i,1) = l2
		PRESET(i,2) = m1 : PRESET(i,3) = m2
		PRESET(i,4) = θ1 : PRESET(i,5) = θ2
		bsave "save/preset.dat",PRESET
		#ifdef hsproom
		devcontrol "syncfs"
		#endif
		return
#global

#module mod_initPreset
	#define PRESET	@PRESET@

	#deffunc initPreset	/* プリセットデータを初期化してファイルに保存 */
		ddim PRESET,5,6
		PRESET(0,0) = 1.3 : PRESET(0,1) = 2.05 : PRESET(0,2) = 0.68 : PRESET(0,3) = 1.26 : PRESET(0,4) = 0.115715 : PRESET(0,5) = 2.953097
		PRESET(1,0) = 0.86 : PRESET(1,1) = 1.8 : PRESET(1,2) = 2.01 : PRESET(1,3) = 0.10 : PRESET(1,4) = -2.09148 : PRESET(1,5) = 1.82928
		PRESET(3,0) = 2.5 : PRESET(3,1) = 1.5 : PRESET(3,2) = 1.0 : PRESET(3,3) = 3.0 : PRESET(3,4) = 1.570796 : PRESET(3,5) = -2.356194
		PRESET(4,0) = 0.7 : PRESET(4,1) = 2.67 : PRESET(4,2) = 1.0 : PRESET(4,3) = 3.0 : PRESET(4,4) = 0.393746 : PRESET(4,5) = -1.99275
		bsave "save/preset.dat",PRESET
		#ifdef hsproom
		devcontrol "syncfs"
		#endif
		return
#global

#module mod_fatalError
	#deffunc fatalError
		dialog "A fatal error occured.\nThis program will end on closing this window."
		end
#global
Total Pages: 1 / 22123451020...最後 »

よく投稿されているコード

タグ

最近投稿されたコード