sample\Artlet2D\xsample_alphapaint.hsp » Plain Format
;============================================================
; 2008/--/--
; Artlet2D demo
; AlphaPaint
;
;============================================================
;
; サンプルペイントソフトです。
;
;============================================================
#include "a2d.hsp"
;-----------------------------------------------------------
; config
#define IMG_CANVAS 0
#define IMG_BUFS 5 ; canvas + undo buffers
#define IMG_CONS 100
#define IMG_CMARK 110
#define IMG_RMARK 120
#define IMG_AMARK 130
#define IMG_PMARK 140
#define IMG_TEX 200
frmx = 640
frmy = 480
mgn = 8
winx = frmx + 100
winy = frmy + 75
sizex = 512
sizey = 384
;-----------------------------------------------------------
; startup
screen 0, winx, winy
title "AlphaPaint"
redraw 0
; Create Image
repeat IMG_BUFS
alCreateImage cnt, frmx, frmy
if stat = -1 {
dialog "GDI+ を初期化できませんでした。"
end
}
loop
; Create Console Image
alCreateImage IMG_CONS, winx, winy
; frame
alSyscolor 15 : alFillRect
alSyscolor 20 : alFillRect 0, 0, frmx+1, frmy+1
alSyscolor 12 : alFillRect 0, 0, frmx, frmy
; Logo
alFont "Arial", 35, 3
stri = "AlphaPaint"
alTransModeOffsetRotateZoom 5, frmy, 8, 1.2, 1
alColor 255, 255, 255, 128 : alDrawText stri, 0, 0
alColor 0, 0, 0, 100 : alDrawText stri, 2, 2
alGradientColor 0, 0, 0, 50, 0xffffffff, 0xffaaaaaa : alDrawText stri, 1, 1
alResetTransMode
; alpha bar
alpha_x = frmx + 12
alpha_y = 340
alpha_w = 32
alpha_h = 128
alGradientColor 0, alpha_y, 0, alpha_y+alpha_h, 0xff000000, 0x00000000
alFillRect alpha_x+alpha_w/2-4, alpha_y, 8, alpha_h
; pen-size bar
psize_x = frmx + 56
psize_y = alpha_y
psize_w = alpha_w
psize_h = alpha_h
alColor 0, 0, 128, 96
p = psize_x+psize_w/2-10, psize_y, psize_x+psize_w/2+10, psize_y, psize_x+psize_w/2, psize_y+psize_h
alFillPoly p, 3
; print
alFont "MS UI Gothic", 14
alColor 0, 0, 0
alTransModeOffsetRotateZoom frmx+10, alpha_y - 40
alDrawText "ペン設定", 0, 0, 80, 20, 1, 1
alDrawText "濃度", 0, 20, 40, 20, 1, 1
alDrawText "太さ", 40, 20, 40, 20, 1, 1
alResetTransMode
; color bar
color_w = 192 / 2 * 4
color_h = winy - frmy - mgn * 2
color_x = frmx - color_w
color_y = frmy + mgn
alColor 128, 128, 128 : alFillRect color_x-1, color_y-1, color_w+1, color_h+1
alColor 255, 255, 255 : alFillRect color_x, color_y, color_w+1, color_h+1
repeat color_w
x = cnt
h = cnt * 2
vf = limit((x-96) * 255 / 192, 0, 255)
repeat color_h
y = cnt
s = (color_h-1-y) * 255 / (color_h-1)
v = y * vf / (color_h-1) + (color_h-1-y) * 255 / (color_h-1)
hsvcolor h, s, v
alSetPixel color_x + x, color_y + y, RGBA(ginfo_r, ginfo_g, ginfo_b)
loop
loop
; Color Marker
alCreateImage IMG_CMARK, 32, 32
; ReSize Marker
alCreateImage IMG_RMARK, 40, 40
; Alpha Marker
alCreateImage IMG_AMARK, 32, 32
; PSize Marker
alCreateImage IMG_PMARK, 32, 32
; Create Background (HSP buffer 1)
buffer 1, frmx, frmy
color 222, 222, 222
div = 8
repeat frmy / div + 1
y = cnt
repeat frmx / 2 / div + 1
boxf cnt*div*2 + (y&1)*div, y*div, cnt*div*2 + (y&1)*div + div-1, y*div + div-1
loop
loop
; Window Objects
gsel 0
objsize winx - frmx - mgn * 2, 21
pos frmx + mgn, mgn : button gosub "● 丸ブラシ", *select_stamp : btnx.stat = ginfo_cx : btny.stat = ginfo_cy
pos , ginfo_cy + 3 : button gosub "■ 角ブラシ", *select_stamp : btnx.stat = ginfo_cx : btny.stat = ginfo_cy
pos , ginfo_cy + 3 : button gosub "○ 消しゴム", *select_stamp : btnx.stat = ginfo_cx : btny.stat = ginfo_cy
pos , ginfo_cy + 3 : button gosub "┼ スポイト", *select_stamp : btnx.stat = ginfo_cx : btny.stat = ginfo_cy
pos , ginfo_cy + 13 : button gosub "全消去", *image_reset
pos , ginfo_cy + 3 : button gosub "選択色消去", *image_colorkey
pos , ginfo_cy + 13 : button gosub "元に戻す", *undo_pop
pos , ginfo_cy + 13 : button gosub "テクスチャ読込", *texture_load
pos , ginfo_cy + 13 : button gosub "ファイル読込", *image_load
pos , ginfo_cy + 3 : button gosub "αpng 保存", *image_save
;-----------------------------------------------------------
; init
stamp_r = 8
cur_a = 85
cur_r = 0
cur_g = 0
cur_b = 0
cur_t = 0
cur_x = 0
cur_y = -100
gosub *update_cons
gosub *update_cmark
gosub *update_rmark
gosub *update_amark
gosub *update_pmark
gosub *update_screen
;-----------------------------------------------------------
; mainloop
#uselib "user32"
#func ScreenToClient "ScreenToClient" int, int
#define STAMP_MAX 24
#define DM_VOID -1
#define DM_DRAW 1
#define DM_RESIZE 3
#define DM_COLOR 2
#define DM_PIPET 4
#define DM_ALPHA 5
#define DM_PSIZE 6
repeat
bk = moux^mouy
if drawmode {
await
} else {
wait 1
}
; get mouse status
getkey k, 1 : k *= (ginfo_act = 0)
p = ginfo_mx, ginfo_my
ScreenToClient hwnd, varptr(p)
moux = p.0
mouy = p.1
; set drawmode
if k * (drawmode = 0) {
if (moux >= color_x) & (mouy >= color_y) & (moux < color_x+color_w) & (mouy < color_y+color_h) {
; 色選択領域
drawmode = DM_COLOR
}
else:if sqrt((sizex-moux)*(sizex-moux)+(sizey-mouy)*(sizey-mouy)) <= 16 {
; リサイズ
drawmode = DM_RESIZE
}
else:if (moux >= alpha_x) & (mouy >= alpha_y-10) & (moux < alpha_x+alpha_w) & (mouy < alpha_y+alpha_h+10) {
; アルファ選択
drawmode = DM_ALPHA
}
else:if (moux >= psize_x) & (mouy >= psize_y-10) & (moux < psize_x+psize_w) & (mouy < psize_y+psize_h+10) {
; ペンサイズ選択
drawmode = DM_PSIZE
}
else:if (moux < sizex) & (mouy < sizey) {
if type_stamp = 3 {
; スポイト
drawmode = DM_PIPET
} else {
; 描画
drawmode = DM_DRAW
gosub *undo_push
alSelectImage IMG_CANVAS
if type_stamp = 2 {
alEraserBrush
} else {
if cur_t {
alTextureImage IMG_TEX
} else {
alColor cur_r, cur_g, cur_b, cur_a*2/3
}
}
}
}
else {
; 無効ドラッグモード
drawmode = DM_VOID
}
; スポイトモード 解除
if (drawmode ! DM_PIPET) & (drawmode ! DM_VOID) : gosub *pipet_off
bk = 0
}
; reset drawmode
if (k = 0) * drawmode {
drawmode = 0
gosub *update_screen
}
; mousemove :
if moux^mouy^bk {
; color
if drawmode = DM_COLOR {
cur_x = limit(moux, color_x, color_x+color_w-1)
cur_y = limit(mouy, color_y, color_y+color_h-1)
cur_t = 0 ; テクスチャタイプ -> 0 (solid)
alSelectImage IMG_CONS
cur_r = ARGB_R( alGetPixel(cur_x, cur_y) )
cur_g = ARGB_G( alGetPixel(cur_x, cur_y) )
cur_b = ARGB_B( alGetPixel(cur_x, cur_y) )
gosub *update_cons
gosub *update_cmark
gosub *update_screen
}
; resize
if drawmode = DM_RESIZE {
sizex = limit(moux, 16, frmx) & 0xfffe
sizey = limit(mouy, 16, frmy) & 0xfffe
gosub *update_rmark
gosub *update_screen
}
; alpha
if drawmode = DM_ALPHA {
cur_a = limit((alpha_y+alpha_h-mouy) * 255 / alpha_h, 0, 255)
gosub *update_amark
gosub *update_screen
}
; psize
if drawmode = DM_PSIZE {
stamp_r = limit((psize_y+psize_h-mouy) * STAMP_MAX / psize_h, 0, STAMP_MAX)
gosub *update_pmark
gosub *update_screen
}
; pipet
if drawmode = DM_PIPET {
cur_x = limit(moux, 0, sizex-1)
cur_y = limit(mouy, 0, sizey-1)
cur_t = 0 ; テクスチャタイプ -> 0 (solid)
alSelectImage IMG_CANVAS
cur_a = ARGB_A( alGetPixel(cur_x, cur_y) )
cur_r = ARGB_R( alGetPixel(cur_x, cur_y) )
cur_g = ARGB_G( alGetPixel(cur_x, cur_y) )
cur_b = ARGB_B( alGetPixel(cur_x, cur_y) )
gosub *update_cons
gosub *update_cmark
gosub *update_amark
gosub *update_screen
}
; draw
if drawmode = DM_DRAW {
x = moux - stamp_r
y = mouy - stamp_r
w = stamp_r * 2
h = stamp_r * 2
if type_stamp = 0 {
repeat stamp_r
alFillEllip x+cnt, y+cnt, w-cnt*2, h-cnt*2
loop
} else:if type_stamp = 1 {
repeat stamp_r
alFillRect x+cnt, y+cnt, w-cnt*2, h-cnt*2
loop
} else:if type_stamp = 2 {
alFillEllip x, y, w, h ; 消しゴム
}
gosub *update_canvas_xywh
}
}
loop
;-----------------------------------------------------------
; subroutines
*update_screen
; HSP screen 0 へ各 Image, buffer の画像を合成
redraw 0
; BG Console
alCopyImageToScreen IMG_CONS, 0
; Canvas
pos 0, 0 : gcopy 1, 0, 0, sizex, sizey
alCopyImageToScreen IMG_CANVAS, 0, 0, 0, sizex, sizey
; ReSize Marker
alCopyImageToScreen IMG_RMARK, 0, sizex-20, sizey-20, 40, 40
; PSize Marker
alCopyImageToScreen IMG_PMARK, 0, psize_x+psize_w/2-16, psize_y+psize_h-(stamp_r * psize_h / STAMP_MAX)-16
; Alpha Marker
if cur_t = 0 : alCopyImageToScreen IMG_AMARK, 0, alpha_x+alpha_w/2-16, alpha_y+alpha_h-(cur_a * alpha_h / 255)-16
; Color Marker
alCopyImageToScreen IMG_CMARK, 0, cur_x-16, cur_y-16, 32, 32
redraw 1
return
*update_canvas_xywh
; キャンバスのみ更新 (高速)
; 変数 x, y, w, h の矩形領域 をアップデート
redraw 0
pos x, y : gcopy 1, x, y, limit(w, 0, limit(sizex-x, 0, 9999)), limit(h, 0, limit(sizey-y, 0, 9999))
alCopyImageToScreen IMG_CANVAS, 0, x, y, limit(w, 0, limit(sizex-x, 0, 9999)), limit(h, 0, limit(sizey-y, 0, 9999)), x, y
redraw 1, x, y, w, h
return
*update_cons
; コンソールイメージ更新
alSelectImage IMG_CONS
alSyscolor 15
alFillRect frmx+1, 0, 999, 200
alFillRect frmx+1, frmy+1
alColor 255, 255, 255 : alFillRect btnx.type_stamp-0, btny.type_stamp-21, 86, 23
alColor 128, 128, 128 : alFillRect btnx.type_stamp-2, btny.type_stamp-23, 86, 23
alColor 255, 0, 0, 96 : alFillRect btnx.type_stamp-1, btny.type_stamp-22, 86, 23
x1 = frmx + mgn
y1 = frmy + mgn
w1 = winx - frmx - mgn * 2
h1 = winy - frmy - mgn * 2
if type_stamp = 0 | type_stamp = 3 {
alColor 128, 128, 128 : alFillEllip x1-1, y1-1, w1, h1
alColor 255, 255, 255 : alFillEllip x1+1, y1+1, w1, h1
if cur_t {
alTextureImage IMG_TEX
} else {
alColor cur_r, cur_g, cur_b
}
alFillEllip x1, y1, w1, h1
}
if type_stamp = 1 {
alColor 128, 128, 128 : alFillRect x1-1, y1-1, w1, h1
alColor 255, 255, 255 : alFillRect x1+1, y1+1, w1, h1
if cur_t {
alTextureImage IMG_TEX
} else {
alColor cur_r, cur_g, cur_b
}
alFillRect x1, y1, w1, h1
}
return
*update_cmark
; カラーマーカーイメージ更新
alSelectImage IMG_CMARK
alErase
alPenWidth 4
alColor 0, 0, 0, 128
alDrawEllip 4, 4, 26, 26
alColor 255, 255, 255, 128
alDrawEllip 2, 2, 26, 26
alColor cur_r, cur_g, cur_b
alDrawEllip 3, 3, 26, 26
return
*update_rmark
; size マーカーイメージ更新
alSelectImage IMG_RMARK
alErase
alTransModeOffsetRotateZoom 20, 20, -45, 0.9, 1.2
alColor 255, 255, 128, limit(128+sizey-frmy, 32, 255)
alFillRect -25, -5, 50, 10
alColor 0, 0, 255, 192
alFont "Arial", 9
alDrawText ""+sizex+" "+sizey, -30, -4, 60, 10, 1, 1
alResetTransMode
alEraserBrush
alFillRect 1, 1, 20, 20
alFillRect 19, 19, 20, 20
alColor 0, 0, 255, 128
alFillRect 19, 10, 2, 20
alFillRect 10, 19, 20, 2
return
*update_amark
if cur_a < 5 : cur_a = 5 ; lower limit
; Alpha マーカーイメージ更新
alSelectImage IMG_AMARK
gosub *nyoro
alFont "Arial", 10 + cur_a*5/255
alDrawText ""+cur_a, 0, 1, 32, 32, 1, 1
return
*update_pmark
; Pen-size マーカーイメージ更新
alSelectImage IMG_PMARK
gosub *nyoro
alFont "Arial", 10 + stamp_r*5/STAMP_MAX
alDrawText ""+stamp_r, 0, 1, 32, 32, 1, 1
return
*nyoro
alErase
alGradientColor 0, 24, 0, 28, 0x44000000, 0x00000000
alFillRect 0, 24, 32, 4
alColor 128, 128, 128 : alFillRect 0, 8, 32, 16
alColor 255, 255, 255 : alFillRect 0, 8, 31, 15
alSyscolor 15 : alFillRect 1, 9, 30, 14
alGradientColor 0, 8, 0, 24, 0x11000000, 0x77ffffff
alFillRect 1, 9, 30, 14
alColor 0, 0, 0
return
;-----------------------------------------------------------
*pipet_off
; スポイトモード off
if type_stamp = 3 {
type_stamp = 0
cur_x = 0
cur_y = -100
gosub *update_cons
}
return
*select_stamp
st = stat
gosub *pipet_off
; スタンプタイプ 変更
type_stamp = st
gosub *update_cons
gosub *update_screen
return
*texture_load
gosub *pipet_off
dialog "bmp;*.png;*.jpg;*.jpeg;*.tif;*.tiff;*.ico;*.gif", 16, "Image"
if stat {
alCreateImageByFile IMG_TEX, refstr
if stat = -1 {
dialog "読み込み失敗"
} else {
cur_t = 1 ; テクスチャタイプ -> 1 (texture)
}
}
gosub *update_cons
gosub *update_screen
wait 10 ; ミスクリック対策
return
;-----------------------------------------------------------
*undo_push
repeat IMG_BUFS-1
alSelectImage IMG_BUFS-cnt-1
alErase
alCopyImageToImage (IMG_BUFS-cnt-2), (IMG_BUFS-cnt-1)
loop
return
*undo_pop
repeat IMG_BUFS-1
alSelectImage cnt
alErase
alCopyImageToImage (cnt+1), (cnt)
loop
gosub *update_screen
return
;-----------------------------------------------------------
*image_reset
gosub *undo_push
alSelectImage
alErase
gosub *update_screen
return
*image_colorkey ; 選択色を透明化
gosub *undo_push
alSelectImage
alErase
s = 16
alCopyModeColorKey RGBA(limit(cur_r-s,0,255), limit(cur_g-s,0,255), limit(cur_b-s,0,255)), RGBA(limit(cur_r+s,0,255), limit(cur_g+s,0,255), limit(cur_b+s,0,255))
alCopyImageToImage 1, 0
alResetCopyMode
gosub *update_screen
return
*image_load
dialog "bmp;*.png;*.jpg;*.jpeg;*.tif;*.tiff;*.ico;*.gif", 16, "Image"
if stat {
alGetFileWidth refstr, sizex, sizey
if stat = -1 {
dialog "読み込み失敗"
} else {
if type_stamp = 3 { ; スポイトモード patch
cur_x = 0
cur_y = -100
}
sizex = limit(sizex, 1, frmx)
sizey = limit(sizey, 1, frmy)
gosub *update_rmark
gosub *undo_push
alSelectImage IMG_CANVAS
alErase
alLoadFile refstr
gosub *update_screen
}
}
wait 10 ; ミスクリック対策
return
*image_save
dialog "png", 17, "png Image"
if stat {
astr = refstr
if strmid(astr, strlen(astr)-4, 4) != ".png" : astr += ".png"
alSelectImage IMG_CANVAS
alSaveFile astr, "image/png", 0, 0, sizex, sizey
if stat : dialog "保存失敗"
}
wait 10 ; ミスクリック対策
return