Go で書き直した Ikemen
リビジョン | 8644bb1382647546d344a7cfeccf9dddec24b614 (tree) |
---|---|
日時 | 2019-02-20 17:55:52 |
作者 | neatunsou <sisiy4excite@gmai...> |
コミッター | neatunsou |
Windblade氏の更新を適応
@@ -1,7 +1,10 @@ | ||
1 | -MIT License | |
1 | +?ソMIT License | |
2 | 2 | |
3 | 3 | Original work Copyright (c) 2016 Suehiro |
4 | 4 | Modified work Copyright (c) 2018 K4thos |
5 | +Modified work Copyright (c) 2018 ShinLucho | |
6 | +Modified work Copyright (c) 2018 NeatUnsou | |
7 | +Modified work Copyright (c) 2019 Windblade | |
5 | 8 | |
6 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy |
7 | 10 | of this software and associated documentation files (the "Software"), to deal |
@@ -22,20 +25,27 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
22 | 25 | SOFTWARE. |
23 | 26 | |
24 | 27 | |
25 | -以下に定める条件に従い、本ソフトウェアおよび関連文書のファイル(以下「ソフトウェア」) | |
26 | -の複製を取得するすべての人に対し、ソフトウェアを無制限に扱うことを無償で許可します。 | |
27 | -これには、ソフトウェアの複製を使用、複写、変更、結合、掲載、頒布、サブライセンス、および | |
28 | -または販売する権利、およびソフトウェアを提供する相手に同じことを許可する権利も無制限に含まれます。 | |
28 | +窶サNote | |
29 | +Data files below, font Following files contain content created by a third party, | |
30 | +It is not covered by this license. | |
29 | 31 | |
30 | -上記の著作権表示および本許諾表示を、ソフトウェアのすべての複製または重要な部分に記載するものとします。 | |
31 | 32 | |
32 | -ソフトウェアは「現状のまま」で、明示であるか暗黙であるかを問わず、何らの保証もなく提供されます。 | |
33 | -ここでいう保証とは、商品性、特定の目的への適合性、および権利非侵害についての保証も含みますが、 | |
34 | -それに限定されるものではありません。 作者または著作権者は、契約行為、不法行為、またはそれ以外であろうと、 | |
35 | -ソフトウェアに起因または関連し、あるいはソフトウェアの使用またはその他の扱いによって生じる一切の請求、損害、 | |
36 | -その他の義務について何らの責任も負わないものとします。 | |
37 | 33 | |
38 | 34 | |
39 | -※注意 | |
40 | -data以下のファイル, font以下のファイルには第三者が作成したコンテンツを含んでいるため、 | |
41 | -このライセンスの対象外となります。 | |
35 | +莉・荳九↓螳壹a繧区擅莉カ縺ォ蠕薙>縲∵悽繧ス繝輔ヨ繧ヲ繧ァ繧「縺翫h縺ウ髢「騾」譁?嶌縺ョ繝輔ぃ繧、繝ォ?井サ・荳九?後た繝輔ヨ繧ヲ繧ァ繧「縲搾シ | |
36 | +縺ョ隍?」ス繧貞叙蠕励☆繧九☆縺ケ縺ヲ縺ョ莠コ縺ォ蟇セ縺励?√た繝輔ヨ繧ヲ繧ァ繧「繧堤┌蛻カ髯舌↓謇ア縺?%縺ィ繧堤┌蜆溘〒險ア蜿ッ縺励∪縺吶? | |
37 | +縺薙l縺ォ縺ッ縲√た繝輔ヨ繧ヲ繧ァ繧「縺ョ隍?」ス繧剃スソ逕ィ縲∬、??縲∝、画峩縲∫オ仙粋縲∵軸霈峨???貞ク??√し繝悶Λ繧、繧サ繝ウ繧ケ縲√♀繧医? | |
38 | +縺セ縺溘?雋ゥ螢イ縺吶k讓ゥ蛻ゥ縲√♀繧医?繧ス繝輔ヨ繧ヲ繧ァ繧「繧呈署萓帙☆繧狗嶌謇九↓蜷後§縺薙→繧定ィア蜿ッ縺吶k讓ゥ蛻ゥ繧ら┌蛻カ髯舌↓蜷ォ縺セ繧後∪縺吶? | |
39 | + | |
40 | +荳願ィ倥?闡嶺ス懈ィゥ陦ィ遉コ縺翫h縺ウ譛ャ險ア隲セ陦ィ遉コ繧偵?√た繝輔ヨ繧ヲ繧ァ繧「縺ョ縺吶∋縺ヲ縺ョ隍?」ス縺セ縺溘?驥崎ヲ√↑驛ィ蛻?↓險倩シ峨☆繧九b縺ョ縺ィ縺励∪縺吶? | |
41 | + | |
42 | +繧ス繝輔ヨ繧ヲ繧ァ繧「縺ッ縲檎樟迥カ縺ョ縺セ縺セ縲阪〒縲∵?遉コ縺ァ縺ゅk縺区囓鮟吶〒縺ゅk縺九r蝠上o縺壹?∽ス輔i縺ョ菫晁ィシ繧ゅ↑縺乗署萓帙&繧後∪縺吶? | |
43 | +縺薙%縺ァ縺?≧菫晁ィシ縺ィ縺ッ縲∝膚蜩∵?ァ縲∫音螳壹?逶ョ逧?∈縺ョ驕ゥ蜷域?ァ縲√♀繧医?讓ゥ蛻ゥ髱樔セオ螳ウ縺ォ縺、縺?※縺ョ菫晁ィシ繧ょ性縺ソ縺セ縺吶′縲 | |
44 | +縺昴l縺ォ髯仙ョ壹&繧後k繧ゅ?縺ァ縺ッ縺ゅj縺セ縺帙s縲 菴懆??∪縺溘?闡嶺ス懈ィゥ閠??縲∝・醍エ?。檎ぜ縲∽ク肴ウ戊。檎ぜ縲√∪縺溘?縺昴l莉・螟悶〒縺ゅm縺?→縲 | |
45 | +繧ス繝輔ヨ繧ヲ繧ァ繧「縺ォ襍キ蝗?縺セ縺溘?髢「騾」縺励?√≠繧九>縺ッ繧ス繝輔ヨ繧ヲ繧ァ繧「縺ョ菴ソ逕ィ縺セ縺溘?縺昴?莉悶?謇ア縺?↓繧医▲縺ヲ逕溘§繧倶ク?蛻??隲区アゅ?∵錐螳ウ縲 | |
46 | +縺昴?莉悶?鄒ゥ蜍吶↓縺、縺?※菴輔i縺ョ雋ャ莉サ繧りイ?繧上↑縺?b縺ョ縺ィ縺励∪縺吶? | |
47 | + | |
48 | + | |
49 | +窶サ豕ィ諢 | |
50 | +data莉・荳九?繝輔ぃ繧、繝ォ, font莉・荳九?繝輔ぃ繧、繝ォ縺ォ縺ッ隨ャ荳芽??′菴懈?縺励◆繧ウ繝ウ繝?Φ繝?r蜷ォ繧薙〒縺?k縺溘a縲 | |
51 | +縺薙?繝ゥ繧、繧サ繝ウ繧ケ縺ョ蟇セ雎。螟悶→縺ェ繧翫∪縺吶? |
@@ -5,6 +5,8 @@ go get -u github.com/go-gl/glfw/v3.2/glfw | ||
5 | 5 | go get -u github.com/go-gl/gl/v2.1/gl |
6 | 6 | go get -u github.com/jfreymuth/go-vorbis/ogg/vorbis |
7 | 7 | go get -u github.com/timshannon/go-openal/openal |
8 | +go get -u github.com/K4thos/glfont | |
9 | +go get -u github.com/flopp/go-findfont | |
8 | 10 | go get -u github.com/faiface/beep |
9 | 11 | go get -u github.com/hajimehoshi/oto |
10 | 12 | go get -u github.com/hajimehoshi/go-mp3 |
@@ -2354,7 +2354,11 @@ func (c *Char) leftEdge() float32 { | ||
2354 | 2354 | return sys.cam.ScreenPos[0] / c.localscl |
2355 | 2355 | } |
2356 | 2356 | func (c *Char) lose() bool { |
2357 | - return sys.winTeam == 1^c.teamside | |
2357 | + if c.roundState() > 2 { | |
2358 | + return sys.winTeam != c.teamside | |
2359 | + } else { | |
2360 | + return false | |
2361 | + } | |
2358 | 2362 | } |
2359 | 2363 | func (c *Char) loseKO() bool { |
2360 | 2364 | return c.lose() && sys.finish == FT_KO |
@@ -2564,7 +2568,11 @@ func (c *Char) win() bool { | ||
2564 | 2568 | if c.teamside >= 2 { |
2565 | 2569 | return false |
2566 | 2570 | } |
2567 | - return sys.winTeam == c.playerNo&1 | |
2571 | + if c.roundState() > 2 { | |
2572 | + return sys.winTeam == c.playerNo&1 | |
2573 | + } else { | |
2574 | + return false | |
2575 | + } | |
2568 | 2576 | } |
2569 | 2577 | func (c *Char) winKO() bool { |
2570 | 2578 | return c.win() && sys.finish == FT_KO |
@@ -2644,6 +2652,8 @@ func (c *Char) playSound(f, lowpriority, loop bool, g, n, chNo, vol int32, | ||
2644 | 2652 | } |
2645 | 2653 | } |
2646 | 2654 | } |
2655 | + | |
2656 | +// Furimuki = Turn around | |
2647 | 2657 | func (c *Char) furimuki() { |
2648 | 2658 | if c.scf(SCF_ctrl) && c.helperIndex == 0 { |
2649 | 2659 | if c.rdDistX(sys.charList.enemyNear(c, 0, true), c).ToF() < 0 { |
@@ -2702,7 +2712,7 @@ func (c *Char) stateChange2() bool { | ||
2702 | 2712 | return false |
2703 | 2713 | } |
2704 | 2714 | func (c *Char) changeStateEx(no int32, pn int, anim, ctrl int32) { |
2705 | - if c.minus <= 0 && (c.ss.stateType == ST_S || c.ss.stateType == ST_C) { | |
2715 | + if c.minus <= 0 && (c.ss.stateType == ST_S || c.ss.stateType == ST_C) && !c.sf(CSF_noautoturn) { | |
2706 | 2716 | c.furimuki() |
2707 | 2717 | } |
2708 | 2718 | if anim >= 0 { |
@@ -241,21 +241,24 @@ func FileExist(filename string) string { | ||
241 | 241 | } |
242 | 242 | return "" |
243 | 243 | } |
244 | -func LoadFile(file *string, deffile string, load func(string) error) error { | |
244 | + | |
245 | +//SearchFile returns the directory that file is located | |
246 | +//This search on deffile directory, then it keep looking on other dirs | |
247 | +func SearchFile(file string, deffile string) string { | |
245 | 248 | var fp string |
246 | - *file = strings.Replace(*file, "\\", "/", -1) | |
249 | + file = strings.Replace(file, "\\", "/", -1) | |
247 | 250 | defdir := filepath.Dir(strings.Replace(deffile, "\\", "/", -1)) |
248 | - if defdir == "." || strings.Contains(*file, ":/") { | |
249 | - fp = *file | |
251 | + if defdir == "." || strings.Contains(file, ":/") { | |
252 | + fp = file | |
250 | 253 | } else if defdir == "/" { |
251 | - fp = "/" + *file | |
254 | + fp = "/" + file | |
252 | 255 | } else { |
253 | - fp = defdir + "/" + *file | |
256 | + fp = defdir + "/" + file | |
254 | 257 | } |
255 | 258 | if fp = FileExist(fp); len(fp) == 0 { |
256 | 259 | _else := false |
257 | 260 | if defdir != "data" { |
258 | - fp = "data/" + *file | |
261 | + fp = "data/" + file | |
259 | 262 | if fp = FileExist(fp); len(fp) == 0 { |
260 | 263 | _else = true |
261 | 264 | } |
@@ -263,18 +266,25 @@ func LoadFile(file *string, deffile string, load func(string) error) error { | ||
263 | 266 | _else = true |
264 | 267 | } |
265 | 268 | if _else { |
266 | - fp = *file | |
269 | + fp = file | |
267 | 270 | if fp = FileExist(fp); len(fp) == 0 { |
268 | - fp = *file | |
271 | + fp = file | |
269 | 272 | } |
270 | 273 | } |
271 | 274 | } |
275 | + | |
276 | + return fp | |
277 | +} | |
278 | + | |
279 | +func LoadFile(file *string, deffile string, load func(string) error) error { | |
280 | + fp := SearchFile(*file, deffile) | |
272 | 281 | if err := load(fp); err != nil { |
273 | 282 | return Error(deffile + ":\n" + fp + "\n" + err.Error()) |
274 | 283 | } |
275 | 284 | *file = fp |
276 | 285 | return nil |
277 | 286 | } |
287 | + | |
278 | 288 | func SplitAndTrim(str, sep string) (ss []string) { |
279 | 289 | ss = strings.Split(str, sep) |
280 | 290 | for i, s := range ss { |
@@ -7,78 +7,128 @@ import ( | ||
7 | 7 | "strings" |
8 | 8 | "unsafe" |
9 | 9 | |
10 | + "github.com/K4thos/glfont" | |
11 | + findfont "github.com/flopp/go-findfont" | |
10 | 12 | "github.com/go-gl/gl/v2.1/gl" |
11 | 13 | ) |
12 | 14 | |
15 | +// FntCharImage stores sprite and position | |
13 | 16 | type FntCharImage struct { |
14 | 17 | ofs, w uint16 |
15 | 18 | img []Sprite |
16 | 19 | } |
20 | + | |
21 | +// Fnt is a interface for basic font information | |
17 | 22 | type Fnt struct { |
18 | 23 | images map[rune]*FntCharImage |
19 | 24 | palettes [][256]uint32 |
20 | 25 | ver, ver2 uint16 |
26 | + Type string | |
21 | 27 | Size [2]uint16 |
22 | 28 | Spacing [2]int32 |
23 | 29 | colors int32 |
24 | 30 | offset [2]int32 |
31 | + ttf *glfont.Font | |
32 | + palfx *PalFX | |
33 | + alphaSrc int32 | |
34 | + alphaDst int32 | |
35 | +} | |
36 | + | |
37 | +func newFnt() *Fnt { | |
38 | + return &Fnt{ | |
39 | + images: make(map[rune]*FntCharImage), | |
40 | + palfx: newPalFX(), | |
41 | + } | |
25 | 42 | } |
26 | 43 | |
27 | -func newFnt() *Fnt { return &Fnt{images: make(map[rune]*FntCharImage)} } | |
28 | 44 | func loadFnt(filename string) (*Fnt, error) { |
45 | + | |
46 | + if strings.HasSuffix(filename, ".fnt") { | |
47 | + return loadFntV1(filename) | |
48 | + } | |
49 | + | |
50 | + return loadFntV2(filename) | |
51 | +} | |
52 | + | |
53 | +func loadFntV1(filename string) (*Fnt, error) { | |
29 | 54 | f := newFnt() |
30 | 55 | fp, err := os.Open(filename) |
56 | + | |
57 | + //Check file in "font/"" directory | |
58 | + if err != nil { | |
59 | + fp, err = os.Open("font/" + filename) | |
60 | + } | |
61 | + | |
62 | + //Error opening file | |
31 | 63 | if err != nil { |
32 | 64 | return nil, err |
33 | 65 | } |
66 | + | |
34 | 67 | defer func() { chk(fp.Close()) }() |
68 | + | |
69 | + //Read header | |
35 | 70 | buf := make([]byte, 12) |
36 | - var n int | |
37 | - if n, err = fp.Read(buf); err != nil { | |
71 | + n, err := fp.Read(buf) | |
72 | + | |
73 | + //Error reading file | |
74 | + if err != nil { | |
38 | 75 | return nil, err |
39 | 76 | } |
77 | + | |
78 | + //Error is not a valid fnt file | |
40 | 79 | if string(buf[:n]) != "ElecbyteFnt\x00" { |
41 | 80 | return nil, Error("ElecbyteFntではありません") |
42 | 81 | } |
82 | + | |
43 | 83 | read := func(x interface{}) error { |
44 | 84 | return binary.Read(fp, binary.LittleEndian, x) |
45 | 85 | } |
86 | + | |
46 | 87 | if err := read(&f.ver); err != nil { |
47 | 88 | return nil, err |
48 | 89 | } |
90 | + | |
49 | 91 | if err := read(&f.ver2); err != nil { |
50 | 92 | return nil, err |
51 | 93 | } |
94 | + | |
52 | 95 | var pcxDataOffset, pcxDataLenght, txtDataOffset, txtDataLenght uint32 |
53 | 96 | if err := read(&pcxDataOffset); err != nil { |
54 | 97 | return nil, err |
55 | 98 | } |
99 | + | |
56 | 100 | if err := read(&pcxDataLenght); err != nil { |
57 | 101 | return nil, err |
58 | 102 | } |
103 | + | |
59 | 104 | if err := read(&txtDataOffset); err != nil { |
60 | 105 | return nil, err |
61 | 106 | } |
107 | + | |
62 | 108 | if err := read(&txtDataLenght); err != nil { |
63 | 109 | return nil, err |
64 | 110 | } |
111 | + | |
65 | 112 | spr := newSprite() |
66 | 113 | if err := spr.readPcxHeader(fp, int64(pcxDataOffset)); err != nil { |
67 | 114 | return nil, err |
68 | 115 | } |
116 | + | |
69 | 117 | fp.Seek(int64(pcxDataOffset)+128, 0) |
70 | 118 | px := make([]byte, pcxDataLenght-128-768) |
71 | 119 | if err := read(px); err != nil { |
72 | 120 | return nil, err |
73 | 121 | } |
122 | + | |
74 | 123 | spr.Pal = make([]uint32, 256) |
75 | 124 | var rgb [3]byte |
76 | 125 | for i := range spr.Pal { |
77 | 126 | if err := read(rgb[:]); err != nil { |
78 | 127 | return nil, err |
79 | 128 | } |
80 | - spr.Pal[i] = uint32(255)<<24 | uint32(rgb[2])<<16 | uint32(rgb[1])<<8 | uint32(rgb[0]) | |
129 | + spr.Pal[i] = uint32(rgb[2])<<16 | uint32(rgb[1])<<8 | uint32(rgb[0]) | |
81 | 130 | } |
131 | + | |
82 | 132 | px = spr.RlePcxDecode(px) |
83 | 133 | fp.Seek(int64(txtDataOffset), 0) |
84 | 134 | buf = make([]byte, txtDataLenght) |
@@ -106,6 +156,7 @@ func loadFnt(filename string) (*Fnt, error) { | ||
106 | 156 | mapflg = false |
107 | 157 | re := regexp.MustCompile("(\\S+)(?:\\s+(\\S+)(?:\\s+(\\S+))?)?") |
108 | 158 | ofs := uint16(0) |
159 | + w := int32(0) | |
109 | 160 | for ; i < len(lines); i++ { |
110 | 161 | if len(lines[i]) > 0 && lines[i][0] == '[' { |
111 | 162 | break |
@@ -134,10 +185,10 @@ func loadFnt(filename string) (*Fnt, error) { | ||
134 | 185 | fci := &FntCharImage{ofs: ofs} |
135 | 186 | f.images[c] = fci |
136 | 187 | if len(cap[3]) > 0 { |
137 | - w := Atoi(cap[3]) | |
188 | + w = Atoi(cap[3]) | |
138 | 189 | if w < 0 { |
139 | - ofs = I32ToU16(int32(ofs) - w) | |
140 | - w = -w | |
190 | + ofs += I32ToU16(int32(ofs) - w) | |
191 | + w = 0 - w | |
141 | 192 | } |
142 | 193 | fci.w = I32ToU16(w) |
143 | 194 | ofs += fci.w - f.Size[0] |
@@ -153,33 +204,7 @@ func loadFnt(filename string) (*Fnt, error) { | ||
153 | 204 | defflg = false |
154 | 205 | is := NewIniSection() |
155 | 206 | is.Parse(lines, &i) |
156 | - ary := SplitAndTrim(is["size"], ",") | |
157 | - if len(ary[0]) > 0 { | |
158 | - f.Size[0] = I32ToU16(Atoi(ary[0])) | |
159 | - } | |
160 | - if len(ary) > 1 && len(ary[1]) > 0 { | |
161 | - f.Size[1] = I32ToU16(Atoi(ary[1])) | |
162 | - } | |
163 | - ary = SplitAndTrim(is["spacing"], ",") | |
164 | - if len(ary[0]) > 0 { | |
165 | - f.Spacing[0] = Atoi(ary[0]) | |
166 | - } | |
167 | - if len(ary) > 1 && len(ary[1]) > 0 { | |
168 | - f.Spacing[1] = Atoi(ary[1]) | |
169 | - } | |
170 | - f.colors = Atoi(is["colors"]) | |
171 | - if f.colors > 255 { | |
172 | - f.colors = 255 | |
173 | - } else if f.colors < 1 { | |
174 | - f.colors = 1 | |
175 | - } | |
176 | - ary = SplitAndTrim(is["offset"], ",") | |
177 | - if len(ary[0]) > 0 { | |
178 | - f.offset[0] = Atoi(ary[0]) | |
179 | - } | |
180 | - if len(ary) > 1 && len(ary[1]) > 0 { | |
181 | - f.offset[1] = Atoi(ary[1]) | |
182 | - } | |
207 | + loadDefInfo(f, filename, is) | |
183 | 208 | } |
184 | 209 | } |
185 | 210 | } |
@@ -220,8 +245,142 @@ func loadFnt(filename string) (*Fnt, error) { | ||
220 | 245 | fci.img[i].Offset[0], fci.img[i].Offset[1], fci.img[i].Pal = 0, 0, p[:] |
221 | 246 | } |
222 | 247 | } |
248 | + | |
249 | + f.SetColor(255, 255, 255, 255, 0) | |
250 | + | |
251 | + return f, nil | |
252 | +} | |
253 | + | |
254 | +func loadFntV2(filename string) (*Fnt, error) { | |
255 | + f := newFnt() | |
256 | + | |
257 | + content, err := LoadText(filename) | |
258 | + | |
259 | + //Check file in "font/"" directory | |
260 | + if err != nil { | |
261 | + content, err = LoadText(filename) | |
262 | + } | |
263 | + | |
264 | + if err != nil { | |
265 | + return nil, err | |
266 | + } | |
267 | + | |
268 | + lines := SplitAndTrim(string(content), "\n") | |
269 | + i := 0 | |
270 | + var name string | |
271 | + | |
272 | + for ; i < len(lines); i++ { | |
273 | + name, _ = SectionName(lines[i]) | |
274 | + if len(name) > 0 { | |
275 | + is := NewIniSection() | |
276 | + i++ | |
277 | + is.Parse(lines, &i) | |
278 | + i-- | |
279 | + switch name { | |
280 | + case "def": | |
281 | + loadDefInfo(f, filename, is) | |
282 | + } | |
283 | + } | |
284 | + } | |
285 | + | |
286 | + f.SetColor(255, 255, 255, 255, 0) | |
287 | + | |
223 | 288 | return f, nil |
224 | 289 | } |
290 | + | |
291 | +func loadDefInfo(f *Fnt, filename string, is IniSection) { | |
292 | + f.Type = strings.ToLower(is["type"]) | |
293 | + ary := SplitAndTrim(is["size"], ",") | |
294 | + if len(ary[0]) > 0 { | |
295 | + f.Size[0] = I32ToU16(Atoi(ary[0])) | |
296 | + } | |
297 | + if len(ary) > 1 && len(ary[1]) > 0 { | |
298 | + f.Size[1] = I32ToU16(Atoi(ary[1])) | |
299 | + } | |
300 | + ary = SplitAndTrim(is["spacing"], ",") | |
301 | + if len(ary[0]) > 0 { | |
302 | + f.Spacing[0] = Atoi(ary[0]) | |
303 | + } | |
304 | + if len(ary) > 1 && len(ary[1]) > 0 { | |
305 | + f.Spacing[1] = Atoi(ary[1]) | |
306 | + } | |
307 | + f.colors = Atoi(is["colors"]) | |
308 | + if f.colors > 255 { | |
309 | + f.colors = 255 | |
310 | + } else if f.colors < 1 { | |
311 | + f.colors = 1 | |
312 | + } | |
313 | + ary = SplitAndTrim(is["offset"], ",") | |
314 | + if len(ary[0]) > 0 { | |
315 | + f.offset[0] = Atoi(ary[0]) | |
316 | + } | |
317 | + if len(ary) > 1 && len(ary[1]) > 0 { | |
318 | + f.offset[1] = Atoi(ary[1]) | |
319 | + } | |
320 | + | |
321 | + if len(is["file"]) > 0 { | |
322 | + if f.Type == "truetype" { | |
323 | + loadFntTtf(f, filename, is["file"]) | |
324 | + } else { | |
325 | + loadFntSff(f, filename, is["file"]) | |
326 | + } | |
327 | + } | |
328 | +} | |
329 | + | |
330 | +func loadFntTtf(f *Fnt, fontfile string, filename string) { | |
331 | + //Search in local directory | |
332 | + fileDir := SearchFile(filename, fontfile) | |
333 | + //Search in system directory | |
334 | + fp := fileDir | |
335 | + if fp = FileExist(fp); len(fp) == 0 { | |
336 | + var err error | |
337 | + fileDir, err = findfont.Find(fileDir) | |
338 | + if err != nil { | |
339 | + panic(err) | |
340 | + } | |
341 | + //fmt.Printf("Found font in '%s'\n", fileDir) | |
342 | + } | |
343 | + //Load ttf | |
344 | + ttf, err := glfont.LoadFont(fileDir, int32(f.Size[1]), int(sys.gameWidth), int(sys.gameHeight)) | |
345 | + if err != nil { | |
346 | + panic(err) | |
347 | + } | |
348 | + f.ttf = ttf | |
349 | +} | |
350 | + | |
351 | +func loadFntSff(f *Fnt, fontfile string, filename string) { | |
352 | + fileDir := SearchFile(filename, fontfile) | |
353 | + sff, err := loadSff(fileDir, false) | |
354 | + | |
355 | + if err != nil { | |
356 | + panic(err) | |
357 | + } | |
358 | + | |
359 | + //Load sprites | |
360 | + for k, sprite := range sff.sprites { | |
361 | + s := sff.getOwnPalSprite(sprite.Group, sprite.Number) | |
362 | + offsetX := uint16(s.Offset[0]) | |
363 | + sizeX := uint16(s.Size[0]) | |
364 | + | |
365 | + fci := &FntCharImage{ | |
366 | + ofs: offsetX, | |
367 | + w: sizeX, | |
368 | + } | |
369 | + fci.img = make([]Sprite, 1) | |
370 | + fci.img[0] = *s | |
371 | + f.images[rune(k[1])] = fci | |
372 | + } | |
373 | + | |
374 | + //Load palettes | |
375 | + f.palettes = make([][256]uint32, sff.header.NumberOfPalettes) | |
376 | + for i := 0; i < int(sff.header.NumberOfPalettes); i++ { | |
377 | + pal := sff.palList.Get(i) | |
378 | + copy(f.palettes[i][:], pal) | |
379 | + } | |
380 | + | |
381 | +} | |
382 | + | |
383 | +//CharWidth returns the width that has a specified character | |
225 | 384 | func (f *Fnt) CharWidth(c rune) int32 { |
226 | 385 | if c == ' ' { |
227 | 386 | return int32(f.Size[0]) |
@@ -232,63 +391,135 @@ func (f *Fnt) CharWidth(c rune) int32 { | ||
232 | 391 | } |
233 | 392 | return int32(fci.w) |
234 | 393 | } |
394 | + | |
395 | +//TextWidth returns the width that has a specified text. | |
396 | +//This depends on each char's width and font spacing | |
235 | 397 | func (f *Fnt) TextWidth(txt string) (w int32) { |
236 | 398 | for _, c := range txt { |
237 | 399 | w += f.CharWidth(c) + f.Spacing[0] |
238 | 400 | } |
239 | 401 | return |
240 | 402 | } |
403 | + | |
404 | +func (f *Fnt) SetColor(r, g, b, alphaSrc, alphaDst float32) { | |
405 | + | |
406 | + rNormalized := Max(0, Min(255, int32(r))) | |
407 | + gNormalized := Max(0, Min(255, int32(g))) | |
408 | + bNormalized := Max(0, Min(255, int32(b))) | |
409 | + | |
410 | + f.palfx.enable = true | |
411 | + f.palfx.eColor = 1 | |
412 | + f.palfx.eMul = [...]int32{ | |
413 | + 256 * rNormalized >> 8, | |
414 | + 256 * gNormalized >> 8, | |
415 | + 256 * bNormalized >> 8, | |
416 | + } | |
417 | + | |
418 | + f.alphaSrc = Max(0, Min(255, int32(alphaSrc))) | |
419 | + f.alphaDst = Max(0, Min(255, int32(alphaDst))) | |
420 | +} | |
421 | + | |
241 | 422 | func (f *Fnt) getCharSpr(c rune, bank int32) *Sprite { |
242 | 423 | fci := f.images[c] |
243 | 424 | if fci == nil { |
244 | 425 | return nil |
245 | 426 | } |
246 | - return &fci.img[bank] | |
427 | + | |
428 | + if bank < int32(len(fci.img)) { | |
429 | + return &fci.img[bank] | |
430 | + } | |
431 | + | |
432 | + return &fci.img[0] | |
433 | +} | |
434 | + | |
435 | +func (f *Fnt) calculateTrans() int32 { | |
436 | + alphaSrc := int32(sys.brightness * f.alphaSrc >> 8) | |
437 | + separator := int32(1 << 9) | |
438 | + alphaDst := int32(f.alphaDst << 10) | |
439 | + | |
440 | + return alphaSrc | separator | alphaDst | |
247 | 441 | } |
248 | -func (f *Fnt) drawChar(x, y, xscl, yscl float32, bank int32, c rune) float32 { | |
442 | + | |
443 | +func (f *Fnt) drawChar( | |
444 | + x, y, xscl, yscl float32, | |
445 | + bank int32, | |
446 | + c rune, | |
447 | + paltex uint32, | |
448 | +) float32 { | |
449 | + | |
249 | 450 | if c == ' ' { |
250 | 451 | return float32(f.Size[0]) * xscl |
251 | 452 | } |
453 | + | |
252 | 454 | spr := f.getCharSpr(c, bank) |
253 | 455 | if spr == nil || spr.Tex == nil { |
254 | 456 | return 0 |
255 | 457 | } |
458 | + | |
459 | + //trans := f.calculateTrans() | |
460 | + | |
256 | 461 | RenderMugenPal(*spr.Tex, 0, spr.Size, -x*sys.widthScale, |
257 | 462 | -y*sys.heightScale, ¬iling, xscl*sys.widthScale, xscl*sys.widthScale, |
258 | 463 | yscl*sys.heightScale, 1, 0, 0, 0, 0, sys.brightness*255>>8|1<<9, &sys.scrrect, |
259 | 464 | 0, 0, false, 1, &[3]float32{0, 0, 0}, &[3]float32{1, 1, 1}) |
465 | + | |
260 | 466 | return float32(spr.Size[0]) * xscl |
261 | 467 | } |
262 | -func (f *Fnt) DrawText(txt string, x, y, xscl, yscl float32, | |
263 | - bank, align int32) { | |
468 | + | |
469 | +//DrawText prints on screen a specified text with the current font sprites | |
470 | +func (f *Fnt) DrawText( | |
471 | + txt string, | |
472 | + x, y, xscl, yscl float32, | |
473 | + bank, align int32, | |
474 | +) { | |
475 | + | |
264 | 476 | if len(txt) == 0 { |
265 | 477 | return |
266 | 478 | } |
479 | + | |
267 | 480 | x += float32(f.offset[0])*xscl + float32(sys.gameWidth-320)/2 |
268 | - y += float32(f.offset[1]-int32(f.Size[1])+1)*yscl + | |
269 | - float32(sys.gameHeight-240) | |
481 | + y += float32(f.offset[1]-int32(f.Size[1])+1)*yscl + float32(sys.gameHeight-240) | |
482 | + | |
270 | 483 | if align == 0 { |
271 | 484 | x -= float32(f.TextWidth(txt)) * xscl * 0.5 |
272 | 485 | } else if align < 0 { |
273 | 486 | x -= float32(f.TextWidth(txt)) * xscl |
274 | 487 | } |
488 | + | |
275 | 489 | if bank < 0 || len(f.palettes) <= int(bank) { |
276 | 490 | bank = 0 |
277 | 491 | } |
278 | - // nil から呼ぶと allPalFX が適用される | |
279 | - pal := (*PalFX)(nil).getFxPal(f.palettes[bank][:], false) | |
492 | + | |
493 | + pal := f.palfx.getFxPal(f.palettes[bank][:], false) | |
280 | 494 | gl.Enable(gl.TEXTURE_1D) |
281 | 495 | gl.ActiveTexture(gl.TEXTURE1) |
282 | 496 | var paltex uint32 |
283 | 497 | gl.GenTextures(1, &paltex) |
284 | 498 | gl.BindTexture(gl.TEXTURE_1D, paltex) |
285 | 499 | gl.PixelStorei(gl.UNPACK_ALIGNMENT, 1) |
286 | - gl.TexImage1D(gl.TEXTURE_1D, 0, gl.RGBA, 256, 0, gl.RGBA, gl.UNSIGNED_BYTE, | |
287 | - unsafe.Pointer(&pal[0])) | |
500 | + gl.TexImage1D( | |
501 | + gl.TEXTURE_1D, | |
502 | + 0, | |
503 | + gl.RGBA, | |
504 | + 256, | |
505 | + 0, | |
506 | + gl.RGBA, | |
507 | + gl.UNSIGNED_BYTE, | |
508 | + unsafe.Pointer(&pal[0]), | |
509 | + ) | |
288 | 510 | gl.TexParameteri(gl.TEXTURE_1D, gl.TEXTURE_MAG_FILTER, gl.NEAREST) |
289 | 511 | gl.TexParameteri(gl.TEXTURE_1D, gl.TEXTURE_MIN_FILTER, gl.NEAREST) |
512 | + | |
290 | 513 | for _, c := range txt { |
291 | - x += f.drawChar(x, y, xscl, yscl, bank, c) + xscl*float32(f.Spacing[0]) | |
514 | + x += f.drawChar( | |
515 | + x, | |
516 | + y, | |
517 | + xscl, | |
518 | + yscl, | |
519 | + bank, | |
520 | + c, | |
521 | + paltex, | |
522 | + ) + xscl*float32(f.Spacing[0]) | |
292 | 523 | } |
293 | 524 | gl.DeleteTextures(1, &paltex) |
294 | 525 | gl.Disable(gl.TEXTURE_1D) |
@@ -304,8 +535,21 @@ type TextSprite struct { | ||
304 | 535 | func NewTextSprite() *TextSprite { |
305 | 536 | return &TextSprite{align: 1, xscl: 1, yscl: 1} |
306 | 537 | } |
538 | + | |
539 | +func (ts *TextSprite) SetColor(r, g, b, alphaSrc, alphaDst float32) { | |
540 | + if ts.fnt.Type == "truetype" { | |
541 | + //ts.fnt.ttf.SetColor(r, g, b, a) | |
542 | + } else { | |
543 | + ts.fnt.SetColor(r, g, b, alphaSrc, alphaDst) | |
544 | + } | |
545 | +} | |
546 | + | |
307 | 547 | func (ts *TextSprite) Draw() { |
308 | 548 | if !sys.frameSkip && ts.fnt != nil { |
309 | - ts.fnt.DrawText(ts.text, ts.x, ts.y, ts.xscl, ts.yscl, ts.bank, ts.align) | |
549 | + if ts.fnt.Type == "truetype" { | |
550 | + //ts.fnt.ttf.Printf(ts.x, ts.y, ts.yscl, ts.align, ts.text) //x, y, scale, align, string, printf args | |
551 | + } else { | |
552 | + ts.fnt.DrawText(ts.text, ts.x, ts.y, ts.xscl, ts.yscl, ts.bank, ts.align) | |
553 | + } | |
310 | 554 | } |
311 | 555 | } |
@@ -8,7 +8,7 @@ import ( | ||
8 | 8 | "strings" |
9 | 9 | |
10 | 10 | "github.com/go-gl/glfw/v3.2/glfw" |
11 | - "github.com/yuin/gopher-lua" | |
11 | + lua "github.com/yuin/gopher-lua" | |
12 | 12 | ) |
13 | 13 | |
14 | 14 | func luaRegister(l *lua.LState, name string, f func(*lua.LState) int) { |
@@ -245,6 +245,29 @@ func scriptCommonInit(l *lua.LState) { | ||
245 | 245 | sys.teamLifeShare = boolArg(l, 1) |
246 | 246 | return 0 |
247 | 247 | }) |
248 | + | |
249 | + // All the lua sprites will be caled by this value | |
250 | + luaRegister(l, "setLuaSpriteScale", func(l *lua.LState) int { | |
251 | + sys.luaSpriteScale = float64(numArg(l, 1)) | |
252 | + return 0 | |
253 | + }) | |
254 | + | |
255 | + // All the lua sprites will be caled by this value | |
256 | + luaRegister(l, "setLuaSpriteOffsetX", func(l *lua.LState) int { | |
257 | + sys.luaSpriteOffsetX = float64(numArg(l, 1)) | |
258 | + return 0 | |
259 | + }) | |
260 | + | |
261 | + // All the lua sprites will add this value to his position Y | |
262 | + luaRegister(l, "setLuaSmallPortraitScale", func(l *lua.LState) int { | |
263 | + sys.luaSmallPortraitScale = float32(numArg(l, 1)) | |
264 | + return 0 | |
265 | + }) | |
266 | + // All the lua sprites will add this value to his position Y | |
267 | + luaRegister(l, "setLuaBigPortraitScale", func(l *lua.LState) int { | |
268 | + sys.luaBigPortraitScale = float32(numArg(l, 1)) | |
269 | + return 0 | |
270 | + }) | |
248 | 271 | } |
249 | 272 | |
250 | 273 | // System Script |
@@ -296,7 +319,7 @@ func systemScriptInit(l *lua.LState) { | ||
296 | 319 | if !ok { |
297 | 320 | userDataError(l, 1, ts) |
298 | 321 | } |
299 | - ts.x, ts.y = float32(numArg(l, 2)), float32(numArg(l, 3)) | |
322 | + ts.x, ts.y = float32((numArg(l, 2)/sys.luaSpriteScale)+sys.luaSpriteOffsetX), float32(numArg(l, 3)/sys.luaSpriteScale) | |
300 | 323 | return 0 |
301 | 324 | }) |
302 | 325 | luaRegister(l, "textImgSetScale", func(*lua.LState) int { |
@@ -304,7 +327,7 @@ func systemScriptInit(l *lua.LState) { | ||
304 | 327 | if !ok { |
305 | 328 | userDataError(l, 1, ts) |
306 | 329 | } |
307 | - ts.xscl, ts.yscl = float32(numArg(l, 2)), float32(numArg(l, 3)) | |
330 | + ts.xscl, ts.yscl = float32(numArg(l, 2)/sys.luaSpriteScale), float32(numArg(l, 3)/sys.luaSpriteScale) | |
308 | 331 | return 0 |
309 | 332 | }) |
310 | 333 | luaRegister(l, "textImgDraw", func(*lua.LState) int { |
@@ -333,7 +356,7 @@ func systemScriptInit(l *lua.LState) { | ||
333 | 356 | if !ok { |
334 | 357 | userDataError(l, 1, a) |
335 | 358 | } |
336 | - a.SetPos(float32(numArg(l, 2)), float32(numArg(l, 3))) | |
359 | + a.SetPos(float32((numArg(l, 2)/sys.luaSpriteScale)+sys.luaSpriteOffsetX), float32(numArg(l, 3)/sys.luaSpriteScale)) | |
337 | 360 | return 0 |
338 | 361 | }) |
339 | 362 | luaRegister(l, "animAddPos", func(*lua.LState) int { |
@@ -341,7 +364,7 @@ func systemScriptInit(l *lua.LState) { | ||
341 | 364 | if !ok { |
342 | 365 | userDataError(l, 1, a) |
343 | 366 | } |
344 | - a.AddPos(float32(numArg(l, 2)), float32(numArg(l, 3))) | |
367 | + a.AddPos(float32(numArg(l, 2)/sys.luaSpriteScale), float32(numArg(l, 3)/sys.luaSpriteScale)) | |
345 | 368 | return 0 |
346 | 369 | }) |
347 | 370 | luaRegister(l, "animSetTile", func(*lua.LState) int { |
@@ -382,7 +405,7 @@ func systemScriptInit(l *lua.LState) { | ||
382 | 405 | if !ok { |
383 | 406 | userDataError(l, 1, a) |
384 | 407 | } |
385 | - a.SetScale(float32(numArg(l, 2)), float32(numArg(l, 3))) | |
408 | + a.SetScale(float32(numArg(l, 2)/sys.luaSpriteScale), float32(numArg(l, 3)/sys.luaSpriteScale)) | |
386 | 409 | return 0 |
387 | 410 | }) |
388 | 411 | luaRegister(l, "animSetWindow", func(*lua.LState) int { |
@@ -390,8 +413,8 @@ func systemScriptInit(l *lua.LState) { | ||
390 | 413 | if !ok { |
391 | 414 | userDataError(l, 1, a) |
392 | 415 | } |
393 | - a.SetWindow(float32(numArg(l, 2)), float32(numArg(l, 3)), | |
394 | - float32(numArg(l, 4)), float32(numArg(l, 5))) | |
416 | + a.SetWindow(float32((numArg(l, 2)/sys.luaSpriteScale)+sys.luaSpriteOffsetX), float32(numArg(l, 3)/sys.luaSpriteScale), | |
417 | + float32(numArg(l, 4)/sys.luaSpriteScale), float32(numArg(l, 5)/sys.luaSpriteScale)) | |
395 | 418 | return 0 |
396 | 419 | }) |
397 | 420 | luaRegister(l, "animUpdate", func(*lua.LState) int { |
@@ -621,7 +644,7 @@ func systemScriptInit(l *lua.LState) { | ||
621 | 644 | xscl *= c.portrait_scale |
622 | 645 | yscl *= c.portrait_scale |
623 | 646 | } |
624 | - c.lportrait.Draw(x, y, xscl, yscl, c.lportrait.Pal, nil) | |
647 | + c.lportrait.Draw(x/float32(sys.luaSpriteScale)+float32(sys.luaSpriteOffsetX), y/float32(sys.luaSpriteScale), xscl/sys.luaBigPortraitScale, yscl/sys.luaBigPortraitScale, c.lportrait.Pal, nil) | |
625 | 648 | } |
626 | 649 | } |
627 | 650 | return 0 |
@@ -639,13 +662,17 @@ func systemScriptInit(l *lua.LState) { | ||
639 | 662 | offset++ |
640 | 663 | if c != nil { |
641 | 664 | if c.sportrait != nil { |
642 | - c.sportrait.Draw(x+float32(i)*sys.sel.cellsize[0], | |
643 | - y+float32(j)*sys.sel.cellsize[1], sys.sel.cellscale[0]*c.portrait_scale, | |
644 | - sys.sel.cellscale[1]*c.portrait_scale, c.sportrait.Pal, nil) | |
665 | + c.sportrait.Draw((x + float32(i)*sys.sel.cellsize[0]), | |
666 | + (y+float32(j)*sys.sel.cellsize[1])/float32(sys.luaSpriteScale), | |
667 | + (sys.sel.cellscale[0]*c.portrait_scale)/float32(sys.luaSpriteScale), | |
668 | + (sys.sel.cellscale[1]*c.portrait_scale)/float32(sys.luaSpriteScale), | |
669 | + c.sportrait.Pal, nil) | |
645 | 670 | } else if c.def == "randomselect" && sys.sel.randomspr != nil { |
646 | 671 | sys.sel.randomspr.Draw(x+float32(i)*sys.sel.cellsize[0], |
647 | - y+float32(j)*sys.sel.cellsize[1], sys.sel.randomscl[0], | |
648 | - sys.sel.randomscl[1], sys.sel.randomspr.Pal, nil) | |
672 | + y+float32(j)*sys.sel.cellsize[1]/float32(sys.luaSpriteScale), | |
673 | + sys.sel.randomscl[0]/float32(sys.luaSpriteScale), | |
674 | + sys.sel.randomscl[1]/float32(sys.luaSpriteScale), | |
675 | + sys.sel.randomspr.Pal, nil) | |
649 | 676 | } |
650 | 677 | } |
651 | 678 | } |
@@ -986,7 +1013,7 @@ func systemScriptInit(l *lua.LState) { | ||
986 | 1013 | xscl *= c.portrait_scale |
987 | 1014 | yscl *= c.portrait_scale |
988 | 1015 | } |
989 | - c.sportrait.Draw(x, y, xscl, yscl, c.sportrait.Pal, nil) | |
1016 | + c.sportrait.Draw(x/float32(sys.luaSpriteScale)+float32(sys.luaSpriteOffsetX), y/float32(sys.luaSpriteScale), xscl/sys.luaSmallPortraitScale, yscl/sys.luaSmallPortraitScale, c.sportrait.Pal, nil) | |
990 | 1017 | } |
991 | 1018 | } |
992 | 1019 | return 0 |
@@ -1007,7 +1034,7 @@ func systemScriptInit(l *lua.LState) { | ||
1007 | 1034 | xscl *= c.portrait_scale |
1008 | 1035 | yscl *= c.portrait_scale |
1009 | 1036 | } |
1010 | - c.vsportrait.Draw(x, y, xscl, yscl, c.vsportrait.Pal, nil) | |
1037 | + c.vsportrait.Draw(x/float32(sys.luaSpriteScale)+float32(sys.luaSpriteOffsetX), y/float32(sys.luaSpriteScale), xscl/sys.luaBigPortraitScale, yscl/sys.luaBigPortraitScale, c.vsportrait.Pal, nil) | |
1011 | 1038 | } |
1012 | 1039 | } |
1013 | 1040 | return 0 |
@@ -1028,7 +1055,7 @@ func systemScriptInit(l *lua.LState) { | ||
1028 | 1055 | xscl *= c.portrait_scale |
1029 | 1056 | yscl *= c.portrait_scale |
1030 | 1057 | } |
1031 | - c.vportrait.Draw(x, y, xscl, yscl, c.vportrait.Pal, nil) | |
1058 | + c.vportrait.Draw(x/float32(sys.luaSpriteScale)+float32(sys.luaSpriteOffsetX), y/float32(sys.luaSpriteScale), xscl/float32(sys.luaSpriteScale), yscl/float32(sys.luaSpriteScale), c.vportrait.Pal, nil) | |
1032 | 1059 | } |
1033 | 1060 | } |
1034 | 1061 | return 0 |
@@ -15,11 +15,11 @@ import ( | ||
15 | 15 | "github.com/go-gl/gl/v2.1/gl" |
16 | 16 | "github.com/go-gl/glfw/v3.2/glfw" |
17 | 17 | "github.com/timshannon/go-openal/openal" |
18 | - "github.com/yuin/gopher-lua" | |
18 | + lua "github.com/yuin/gopher-lua" | |
19 | 19 | ) |
20 | 20 | |
21 | 21 | const ( |
22 | - MaxSimul = 4 | |
22 | + MaxSimul = 8 | |
23 | 23 | MaxAttachedChar = 2 |
24 | 24 | FPS = 60 |
25 | 25 | P1P3Dist = 25 |
@@ -59,6 +59,11 @@ var sys = System{ | ||
59 | 59 | audioClose: make(chan bool, 1), |
60 | 60 | keyInput: glfw.KeyUnknown, |
61 | 61 | keyString: "", |
62 | + // Localcoord sceenpack | |
63 | + luaSpriteScale: 1, | |
64 | + luaSmallPortraitScale: 1, | |
65 | + luaBigPortraitScale: 1, | |
66 | + luaSpriteOffsetX: 0, | |
62 | 67 | } |
63 | 68 | |
64 | 69 | type TeamMode int32 |
@@ -221,6 +226,11 @@ type System struct { | ||
221 | 226 | timerCount []int32 |
222 | 227 | cmdFlags map[string]string |
223 | 228 | quickLaunch bool |
229 | + // Localcoord sceenpack | |
230 | + luaSpriteScale float64 | |
231 | + luaSmallPortraitScale float32 | |
232 | + luaBigPortraitScale float32 | |
233 | + luaSpriteOffsetX float64 | |
224 | 234 | } |
225 | 235 | |
226 | 236 | func (s *System) init(w, h int32) *lua.LState { |