More ... | シンプルなアナログ時計SSシンプルなアナログ時計SS
; シンプルなアナログ時計スクリーンセーバー for HSP 3.0β7 or later
;
; HISTORY
; Shark++
; 2005-04-16 HSPのβ版を試したくなり、
; アナログ時計スクリーンセーバーを作り始める
; 2005-04-17 アナログ時計部分は完成
; 2005-04-21 針の形を変更
; ※HSPwikiからDL
#include "typeutil.as" ; ddim
#include "math.as" ; deg2rad
#module
#uselib "gdi32.dll"
; #func PolyPolygon "PolyPolygon" int, int, var, int
#func PolyPolygon "PolyPolygon" int, var, var, int
#func CreatePen "CreatePen" int, int, int
#func CreateSolidBrush "CreateSolidBrush" int
#func SelectObject "SelectObject" int, int
#func DeleteObject "DeleteObject" int
#func GetStockObject "GetStockObject" int
#define PS_SOLID 0
#define NULL_BRUSH 5
#deffunc porygon array ptpos, int count, int border_color, int fill_color
; porygon ptpos, count, border_color, fill_color
; 指定された描画頂点位置・線の色・背景色で多角形を描きます
; ptpos = 描画頂点位置
; ※メモリ上では、X,Y の順に並んでいなければならない
; dim ptpos,4,2 ではダメで、dim ptpos,2,4 にしなければいけない
; また閉じた図形(頂点の最初と最後が同じ)でなければ描画されない
; count = 頂点の数
; border_color = 線の色
; fill_color = 塗りつぶす色
mref bmscr,67
dim _count,1 : _count = count
;
if (-1 = border_color) & (-1 = fill_color) : return
if -1 = border_color : border_color = fill_color
CreatePen PS_SOLID, 1, border_color
SelectObject bmscr.4, stat
hOldPen = stat
if -1 = fill_color {
GetStockObject NULL_BRUSH }
else { CreateSolidBrush fill_color }
SelectObject bmscr.4, stat
hOldBrush = stat
PolyPolygon bmscr.4, ptpos, _count, 1
SelectObject bmscr.4, hOldPen
DeleteObject stat
if -1 != fill_color {
SelectObject bmscr.4, hOldBrush
DeleteObject stat
}
return
#deffunc box int x1, int y1, int x2, int y2
; box x1,y1,x2,y2
; 画面上に、(p1,p2)と(p3,p4)を左上、右下の点として、
; 現在の描画色で矩形(四角形)を描画します。
line x2, y1, x1, y1
line x2, y2
line x1, y2
line x1, y1
return
#global
#define ctype RGB(%1,%2,%3) ((%1*65536)+(%2*256)+%3)
#define rgbcolor(%1) color (%1/$10000)&$ff,(%1/$100)&$ff,%1&$ff
; パッケージオプション
#packopt name "sstime"
#packopt type 2 ; スクリーンセーバー
#packopt xsize 320 ; 設定画面の横サイズ
#packopt ysize 200 ; 設定画面の縦サイズ
#packopt hide 1
;-----------------------------------------------------------------
; 引数評価
;-----------------------------------------------------------------
s = dir_cmdline : type = peek(s,1) ; コマンドラインの2文字目を取り出す
if ('A'<=type)&(type<='Z') : type+=32 ; 大文字を小文字に変換する
if type='p' : goto *sspre ; プレビュー
if type='s' : goto *ssproc ; フルスクリーン
if type='c' : goto *sscfg ; コンフィグ
if type=0 : goto *sscfg ; コンフィグ
;
; コマンドラインがどれでもない時はエラーを表示。
; HSPスクリプトエディタでためしに実行してみる場合には、
; HSPメニュー「起動オプション」を選んで、「/s」や「/p」などの
; スイッチを指定してコンパイル+実行をしてください。
;
dialog "Unknown switch ["+s+"]"
end
*sscfg
dialog "", 0, "シンプルなアナログ時計"
end
*sspre
; 描画範囲指定
sx = ginfo_winx - 10
sy = ginfo_winy - 10
dx = 5
dy = 5
goto *ssinit
*ssproc
; 描画範囲指定
sx = ginfo_dispx - 20
sy = ginfo_dispy - 20
dx = 10
dy = 10
bgscr 0, ginfo_dispx, ginfo_dispy, , 0, 0
*ssinit
cls 4
title "シンプルなアナログ時計"
crFill = $006600
crBorder = $00ff00
; 幅・高さを小さいほうにあわせる→正方形に
if sy < sx : dx += (sx - sy) / 2 : sx = sy
if sx < sy : dy += (sy - sx) / 2 : sy = sx
cx = sx / 2
cy = sy / 2
n = 100.0
gosub *init_sincos_table
; 範囲は 〜 100
nn = 100.0
; 時計の針の位置(時)
ddim clock_h,6,2
clock_h.0.0 = -5.0 : clock_h.0.1 = -3.0
clock_h.1.0 = -8.0 : clock_h.1.1 = 50.0
clock_h.2.0 = 0.0 : clock_h.2.1 = 60.0
clock_h.3.0 = 8.0 : clock_h.3.1 = 50.0
clock_h.4.0 = 5.0 : clock_h.4.1 = -3.0
clock_h.5.0 = 0.0 : clock_h.5.1 = -5.0
count_h = 6
; 時計の針の位置(分)
ddim clock_m,6,2
clock_m.0.0 = -4.0 : clock_m.0.1 = -2.0
clock_m.1.0 = -4.0 : clock_m.1.1 = 80.0
clock_m.2.0 = 0.0 : clock_m.2.1 = 85.0
clock_m.3.0 = 4.0 : clock_m.3.1 = 80.0
clock_m.4.0 = 4.0 : clock_m.4.1 = -2.0
clock_m.5.0 = 0.0 : clock_m.5.1 = -4.0
count_m = 6
; 時計の針の位置(秒)
ddim clock_s,5,2
clock_s.0.0 = -1.0 : clock_s.0.1 = -8.0
clock_s.1.0 = -1.0 : clock_s.1.1 = 87.0
clock_s.2.0 = 0.0 : clock_s.2.1 = 90.0
clock_s.3.0 = 1.0 : clock_s.3.1 = 87.0
clock_s.4.0 = 1.0 : clock_s.4.1 = -8.0
count_s = 5
; 文字盤のポッチ
potti1_size = 2.0, 2.0
; 文字盤のポッチ(5分ごと)
potti5_size = 2.0, 2.0
; 針の留め金のポッチ
center_size = 1.0, 1.0
; 文字盤ポッチの半径
potti_r = 95.0, 95.0
; 実際の描画範囲に拡大処理
; ※clock_h.cnt.0 ではエラーが起きる
#define ctype ZOOM_SX(%1) %1=(%1)*cx/nn
#define ctype ZOOM_SY(%1) %1=(%1)*cy/nn
repeat count_h : ZOOM_SX(clock_h(cnt,0)) : ZOOM_SY(clock_h(cnt,1)) : loop
repeat count_m : ZOOM_SX(clock_m(cnt,0)) : ZOOM_SY(clock_m(cnt,1)) : loop
repeat count_s : ZOOM_SX(clock_s(cnt,0)) : ZOOM_SY(clock_s(cnt,1)) : loop
ZOOM_SX(potti1_size.0) : ZOOM_SY(potti1_size.1)
ZOOM_SX(potti5_size.0) : ZOOM_SY(potti5_size.1)
ZOOM_SX(center_size.0) : ZOOM_SY(center_size.1)
ZOOM_SX(potti_r.0) : ZOOM_SY(potti_r.1)
dim hpos,2,(count_h + 1)
dim mpos,2,(count_m + 1)
dim spos,2,(count_s + 1)
gsel 0,2
*main
; メインループ
gosub *draw
wait 1
goto *main
*draw
; dx = 描画位置(横)
; dy = 〃 (縦)
; sx = 描画サイズ(幅)
; sy = 〃 (高さ)
; cx = 描画サイズ 1/2 (幅)
; cy = 〃 1/2 (高さ)
redraw 0
gosub *draw_potti
gosub *draw_time
redraw 1
return
*draw_potti
; dx = 描画位置(横)
; dy = 〃 (縦)
; sx = 描画サイズ(幅)
; sy = 〃 (高さ)
; cx = 描画サイズ 1/2 (幅)
; cy = 〃 1/2 (高さ)
; 文字盤のポッチ
repeat 60
rr = 1 * (cnt * 6 * n + 0.5)
px = dx + cx + (t_sin.rr * potti_r.0)
py = dy + cy + (t_cos.rr * potti_r.1)
if cnt \ 5 {
rgbcolor crFill
circle px-potti1_size.0, py-potti1_size.1, px+potti1_size.0, py+potti1_size.1, 1
rgbcolor crBorder
circle px-potti1_size.0, py-potti1_size.1, px+potti1_size.0, py+potti1_size.1, 0
}
else {
; 5分ごと
rgbcolor crFill
boxf px-potti5_size.0, py-potti5_size.1, px+potti5_size.0, py+potti5_size.1
rgbcolor crBorder
box px-potti5_size.0, py-potti5_size.1, px+potti5_size.0, py+potti5_size.1
}
loop
return
*draw_time
; dx = 描画位置(横)
; dy = 〃 (縦)
; sx = 描画サイズ(幅)
; sy = 〃 (高さ)
; cx = 描画サイズ 1/2 (幅)
; cy = 〃 1/2 (高さ)
; 前に描画した針を消す
porygon hpos, count_h, RGB(0,0,0), RGB(0,0,0);crFill
porygon mpos, count_m, RGB(0,0,0), RGB(0,0,0);crFill
porygon spos, count_s, RGB(0,0,0), RGB(0,0,0);crFill
_time = gettime(4), gettime(5), gettime(6), gettime(7)
; DEBUG
; _time = gettime(5), gettime(6), gettime(7) / 16, 0
; 時
r = 360.0 * ((_time.0 \ 12) * 3600 + _time.1 * 60 + _time.2) / 43200
gosub *get_rotation_matrix
repeat count_h
hpos(0,cnt) = dx + cx + (clock_h(cnt,0) * rm.0.0 + clock_h(cnt,1) * rm.0.1)
hpos(1,cnt) = dy + cy + (clock_h(cnt,0) * rm.1.0 + clock_h(cnt,1) * rm.1.1)
loop
hpos.0.count_h = hpos.0.0
hpos.1.count_h = hpos.1.0
porygon hpos, count_h, crBorder, crFill
; 分
; ミリ秒まで計算しないでも十分だろう
r = 360.0 * (_time.1 * 60 + _time.2) / 3600
gosub *get_rotation_matrix
repeat count_m
mpos(0,cnt) = dx + cx + (clock_m(cnt,0) * rm.0.0 + clock_m(cnt,1) * rm.0.1)
mpos(1,cnt) = dy + cy + (clock_m(cnt,0) * rm.1.0 + clock_m(cnt,1) * rm.1.1)
loop
mpos.0.count_m = mpos.0.0
mpos.1.count_m = mpos.1.0
porygon mpos, count_m, crBorder, crFill
; 秒
r = 360.0 * (_time.2 * 1000 + _time.3) / 60000
gosub *get_rotation_matrix
repeat count_s
spos(0,cnt) = dx + cx + (clock_s(cnt,0) * rm.0.0 + clock_s(cnt,1) * rm.0.1)
spos(1,cnt) = dy + cy + (clock_s(cnt,0) * rm.1.0 + clock_s(cnt,1) * rm.1.1)
loop
spos.0.count_s = spos.0.0
spos.1.count_s = spos.1.0
porygon spos, count_s, crBorder, crFill
; 針の留め金
px = dx + cx
py = dy + cy
rgbcolor crFill
circle px-center_size.0, py-center_size.1, px+center_size.0, py+center_size.1, 1
rgbcolor crBorder
circle px-center_size.0, py-center_size.1, px+center_size.0, py+center_size.1, 0
return
*init_sincos_table
; SIN・COS 計算用テーブルを作成
; [IN]
; n = 1度あたりの分割数
; [OUT]
; t_sin = SINテーブル
; t_cos = COSテーブル
ddim t_sin,360*n
ddim t_cos,360*n
repeat 360*n
t_sin(cnt) = sin(deg2rad(1.0 * cnt / n))
t_cos(cnt) = cos(deg2rad(1.0 * cnt / n))
loop
; 大して速度が変わらない
; repeat 899
; m = cnt
; t_cos( 899-cnt) = t_sin(1+cnt)
; t_cos( 900+cnt) = -t_sin(cnt)
; t_cos(1800+cnt) = -t_sin(900-cnt)
; t_cos(2700+cnt) = t_sin(cnt)
; loop
return
*get_rotation_matrix
; 回転行列を取得(角度を180度変える)
; [IN]
; r = 取得角度
; n = SIN・COS 計算用テーブルの1度あたりの分割数
; [OUT]
; rm = 回転行列(2*2)
; 時計の針用に角度を180度変える
r += 180.0 : if 360 <= r : r -= 360
rr = 1 * (r * n + 0.5)
; 回転行列
; X = x * cosβ - y * sinβ
; Y = x * sinβ + y * cosβ
ddim rm,2,2
rm.0.0 = t_cos.rr
rm.0.1 = -t_sin.rr
rm.1.0 = t_sin.rr
rm.1.1 = t_cos.rr
return
|