sci2-ts 0.16.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/lib/991.sc +48 -3
- package/lib/992.sc +5 -1
- package/lib/995.sc +4 -2
- package/lib/996.sc +244 -59
- package/lib/system.sh +8 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,18 @@ All notable changes to this project. Versions follow [Semantic Versioning](https
|
|
|
4
4
|
and the entries are generated from commit messages
|
|
5
5
|
([Conventional Commits](https://www.conventionalcommits.org/)) when a release is made.
|
|
6
6
|
|
|
7
|
+
## [0.18.0](https://github.com/rlueder/sci-ts/compare/v0.17.0...v0.18.0) (2026-10-03)
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
* **lib:** painted game menu with lit rows, arrow keys, Escape and unavailable choices ([#21](https://github.com/rlueder/sci-ts/issues/21)) ([17dfd28](https://github.com/rlueder/sci-ts/commit/17dfd28c0f16379714a058869b7b698dc5338344))
|
|
12
|
+
|
|
13
|
+
## [0.17.0](https://github.com/rlueder/sci-ts/compare/v0.16.0...v0.17.0) (2026-10-02)
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
* **lib:** a sliding icon bar, and portraits at the bottom of the screen ([#20](https://github.com/rlueder/sci-ts/issues/20)) ([31e82ca](https://github.com/rlueder/sci-ts/commit/31e82ca33478c163b80b4f4fb16c5718b3c36bae))
|
|
18
|
+
|
|
7
19
|
## [0.16.0](https://github.com/rlueder/sci-ts/compare/v0.15.1...v0.16.0) (2026-10-02)
|
|
8
20
|
|
|
9
21
|
### Added
|
package/lib/991.sc
CHANGED
|
@@ -31,10 +31,16 @@
|
|
|
31
31
|
top -1
|
|
32
32
|
box 0
|
|
33
33
|
icons 0
|
|
34
|
-
height 0
|
|
34
|
+
height 0
|
|
35
|
+
slides TRUE ; slides down from above the screen, and back up when it closes
|
|
36
|
+
shown 0 ; how far down it is: 0 all the way, -height out of sight
|
|
37
|
+
leaving 0) ; sliding back up
|
|
35
38
|
|
|
36
39
|
(method (show &tmp x y step)
|
|
37
|
-
|
|
40
|
+
;; Opened again while it slides away: it comes back down.
|
|
41
|
+
(if box
|
|
42
|
+
(if leaving (= leaving 0) (= dialog self))
|
|
43
|
+
(return))
|
|
38
44
|
(if (!= skin -1)
|
|
39
45
|
(= box ((View new:) view: skin loop: 0 cel: 0 x: 0 y: 0 yourself:))
|
|
40
46
|
(box init:)
|
|
@@ -66,7 +72,37 @@
|
|
|
66
72
|
(self addIcon: (+ x (* 4 step)) y -1 V_ITEM)
|
|
67
73
|
(self addIcon: (+ x (* 5 step)) y 4 ICON_INVENTORY)
|
|
68
74
|
(self addIcon: (+ x (* 6 step)) y 5 ICON_MENU)
|
|
69
|
-
(= dialog self)
|
|
75
|
+
(= dialog self)
|
|
76
|
+
(if slides
|
|
77
|
+
(= shown 0)
|
|
78
|
+
(self moveBy: (- height))
|
|
79
|
+
(= shown (- height))))
|
|
80
|
+
|
|
81
|
+
;; Everything in the bar up or down by dy.
|
|
82
|
+
(method (moveBy dy &tmp node icon)
|
|
83
|
+
(box y: (+ (box y?) dy))
|
|
84
|
+
(UpdateScreenItem box)
|
|
85
|
+
(for ((= node (FirstNode (icons elements?)))) node ((= node (NextNode node)))
|
|
86
|
+
(= icon (NodeValue node))
|
|
87
|
+
(icon y: (+ (icon y?) dy))
|
|
88
|
+
(UpdateScreenItem icon)))
|
|
89
|
+
|
|
90
|
+
;; A cycle of sliding (the User calls it while the bar is up): down while it opens, up
|
|
91
|
+
;; while it closes, quickly at first and easing to a stop.
|
|
92
|
+
(method (step &tmp d)
|
|
93
|
+
(cond
|
|
94
|
+
((not box) 0)
|
|
95
|
+
(leaving
|
|
96
|
+
(= d (+ 4 (/ (+ height shown) 3)))
|
|
97
|
+
(if (> d (+ height shown)) (= d (+ height shown)))
|
|
98
|
+
(self moveBy: (- d))
|
|
99
|
+
(-= shown d)
|
|
100
|
+
(if (<= shown (- height)) (self remove:)))
|
|
101
|
+
((< shown 0)
|
|
102
|
+
(= d (+ 2 (/ (- shown) 3)))
|
|
103
|
+
(if (> d (- shown)) (= d (- shown)))
|
|
104
|
+
(self moveBy: d)
|
|
105
|
+
(+= shown d))))
|
|
70
106
|
|
|
71
107
|
;; An icon at (x, y): cel c of the bar's view (-1: the item in use), standing for `what`.
|
|
72
108
|
(method (addIcon theX theY c what &tmp icon)
|
|
@@ -85,8 +121,17 @@
|
|
|
85
121
|
(icon plane: uiPlane setPri: (+ (box priority?) 1))
|
|
86
122
|
(icons add: icon))
|
|
87
123
|
|
|
124
|
+
;; Closes it: it slides away (or goes at once, without slides), and stops taking clicks.
|
|
88
125
|
(method (hide)
|
|
89
126
|
(if (== dialog self) (= dialog 0))
|
|
127
|
+
(if (and slides box)
|
|
128
|
+
(= leaving 1)
|
|
129
|
+
else
|
|
130
|
+
(self remove:)))
|
|
131
|
+
|
|
132
|
+
(method (remove)
|
|
133
|
+
(= leaving 0)
|
|
134
|
+
(= shown 0)
|
|
90
135
|
(if icons
|
|
91
136
|
(icons eachElementDo: #dispose)
|
|
92
137
|
(icons dispose:)
|
package/lib/992.sc
CHANGED
|
@@ -51,14 +51,18 @@
|
|
|
51
51
|
field 0 ; the description being typed
|
|
52
52
|
slot 0) ; the save it goes into
|
|
53
53
|
|
|
54
|
+
;; Painted with the textStyle's menuSkin, if it has one; Restore is unavailable there until
|
|
55
|
+
;; there's a save.
|
|
54
56
|
(method (showMenu &tmp menu)
|
|
55
57
|
(= mode SR_MENU)
|
|
56
|
-
(
|
|
58
|
+
(self load:)
|
|
59
|
+
(= menu ((Menu new:) painted: TRUE yourself:))
|
|
57
60
|
(menu
|
|
58
61
|
add: SR_SAVE "Save the game"
|
|
59
62
|
add: SR_RESTORE "Restore a game"
|
|
60
63
|
add: SR_RESTART "Start again"
|
|
61
64
|
add: SR_TEXT (String STRING_FORMAT "Text speed: %s" (self textSpeedName:)))
|
|
65
|
+
(if (not count) ((menu valued: SR_RESTORE) disabled: TRUE))
|
|
62
66
|
;; Only a game with recorded lines asks how to have them.
|
|
63
67
|
(if (DoAudio 9)
|
|
64
68
|
(menu add: SR_SPEECH (String STRING_FORMAT "Speech: %s" (self speechName:))))
|
package/lib/995.sc
CHANGED
|
@@ -73,11 +73,13 @@
|
|
|
73
73
|
|
|
74
74
|
(method (doit)
|
|
75
75
|
(self showCursor:)
|
|
76
|
+
(if (and iconBar (iconBar box?)) (iconBar step:))
|
|
76
77
|
(while (GetEvent EV_ALL theEvent)
|
|
77
78
|
(self handleEvent: theEvent))
|
|
78
|
-
;; theEvent now says where the pointer is:
|
|
79
|
+
;; theEvent now says where the pointer is: an open menu or the icon bar follows it, and at
|
|
80
|
+
;; the top edge the icon bar comes down.
|
|
79
81
|
(cond
|
|
80
|
-
((
|
|
82
|
+
((and dialog (dialog respondsTo: #pointerAt)) (dialog pointerAt: (theEvent x?) (theEvent y?)))
|
|
81
83
|
((and canInput (not dialog) (not talking) (<= (theEvent y?) ICON_BAR_EDGE)) (iconBar show:))))
|
|
82
84
|
|
|
83
85
|
;; The verb right-click goes to: walk, do, look, talk, the item picked (if any), walk.
|
package/lib/996.sc
CHANGED
|
@@ -10,6 +10,14 @@
|
|
|
10
10
|
;; A frame is a view whose loop 0 has eight cels, each anchored at its top-left corner: the
|
|
11
11
|
;; corners (top-left, top-right, bottom-left, bottom-right), then the edges (top, bottom, left,
|
|
12
12
|
;; right). The edges are tiled between the corners; transparent pixels show the paper.
|
|
13
|
+
;;
|
|
14
|
+
;; The game menu can be painted instead (the casebook, say): `menuSkin` is a view whose loop
|
|
15
|
+
;; 0, cel 0 is the panel, its title painted in, loop 1 the row behind a choice and loop 2 the
|
|
16
|
+
;; bullet before it, each with a cel for a choice as it is, under the pointer or keyboard
|
|
17
|
+
;; focus, pressed and unavailable; all anchored at their top-left corners. The panel goes at
|
|
18
|
+
;; menuX, menuY (-1: centred), the rows from menuRowX, menuRowY down by menuRowStep, the
|
|
19
|
+
;; bullet and the text at their offsets in the row. The text is in the four menu colours.
|
|
20
|
+
;; (textStyle menuSkin: 269 menuX: 38 menuY: 11 menuRowX: 10 menuRowY: 29 menuRowStep: 22)
|
|
13
21
|
(class TextStyle of Obj
|
|
14
22
|
(properties
|
|
15
23
|
font 0
|
|
@@ -20,8 +28,17 @@
|
|
|
20
28
|
margin 4 ; between the text and the border or frame
|
|
21
29
|
portraitFrame -1 ; a view around portraits: loop 0 behind the face, loop 1 over its edges
|
|
22
30
|
portraitX 8 ; where a portrait's face goes on the left (mirrored on the right)
|
|
23
|
-
portraitY 8
|
|
24
|
-
nameFont -1
|
|
31
|
+
portraitY 8 ; its top; below 0, its bottom that far above the screen's, its text with it
|
|
32
|
+
nameFont -1 ; the font for a speaker's name before their line (-1: the text's)
|
|
33
|
+
menuSkin -1 ; the game menu's painted panel, rows and bullets, or -1 (above)
|
|
34
|
+
menuX -1 menuY -1
|
|
35
|
+
menuRowX 10 menuRowY 29 menuRowStep 22
|
|
36
|
+
menuBulletX 5 menuBulletY 5
|
|
37
|
+
menuTextX 25 menuTextY 4
|
|
38
|
+
menuFore -1 ; the text of a choice, under the pointer, pressed, unavailable (-1: fore)
|
|
39
|
+
menuHover -1
|
|
40
|
+
menuPressed -1
|
|
41
|
+
menuDisabled -1))
|
|
25
42
|
|
|
26
43
|
;; A box of text over the room: drawn by the interpreter into a bitmap, shown as a screen
|
|
27
44
|
;; item in the UI plane. Set text (and width, x, y), then init; it's as tall as the text
|
|
@@ -44,6 +61,7 @@
|
|
|
44
61
|
borderColor -2 ; -1: none
|
|
45
62
|
frame -2 ; -1: none
|
|
46
63
|
textLeft 0 textTop 0 textRight -1 textBottom -1
|
|
64
|
+
margin -1 ; between the text and the edge, or the frame (-1: the textStyle's)
|
|
47
65
|
width 200
|
|
48
66
|
height 0
|
|
49
67
|
bottom -1) ; -1: placed at y
|
|
@@ -55,7 +73,7 @@
|
|
|
55
73
|
(if (== frame -2) (= frame (textStyle frame?)))
|
|
56
74
|
(if (== borderColor -2) (= borderColor (if (!= frame -1) -1 else (textStyle border?))))
|
|
57
75
|
;; As tall as the text needs, inside the margin and the frame.
|
|
58
|
-
(= m (textStyle margin?))
|
|
76
|
+
(= m (if (== margin -1) (textStyle margin?) else margin))
|
|
59
77
|
(= padL m) (= padT m) (= padR m) (= padB m)
|
|
60
78
|
(if (!= frame -1)
|
|
61
79
|
(+= padL (CelWide frame 0 6))
|
|
@@ -245,21 +263,29 @@
|
|
|
245
263
|
(if (and (!= self heroTalker) heroTalker (heroTalker respondsTo: #otherSide)) (heroTalker otherSide: s))
|
|
246
264
|
(return s))
|
|
247
265
|
|
|
248
|
-
;;
|
|
249
|
-
(method (
|
|
266
|
+
;; Where the face's top goes: textStyle's portraitY, or below 0, counted up from the bottom.
|
|
267
|
+
(method (faceTop face &tmp py)
|
|
268
|
+
(= py (textStyle portraitY?))
|
|
269
|
+
(return (if (< py 0) (- (+ SCREEN_HEIGHT py) (CelHigh (face view?) 0 0)) else py)))
|
|
270
|
+
|
|
271
|
+
;; Whether the portrait on side s (frame and all) would be over the speaker's or the hero's
|
|
272
|
+
;; head.
|
|
273
|
+
(method (covers face s &tmp pw ph over left right top bottom f)
|
|
250
274
|
(= pw (CelWide (face view?) 0 0))
|
|
251
275
|
(= ph (CelHigh (face view?) 0 0))
|
|
252
|
-
(=
|
|
276
|
+
(= f (textStyle portraitFrame?))
|
|
277
|
+
(= over (if (!= f -1) (/ (- (CelWide f 0 0) pw) 2) else 0))
|
|
253
278
|
(= left (if s (- SCREEN_WIDTH (+ (textStyle portraitX?) pw over)) else (- (textStyle portraitX?) over)))
|
|
254
279
|
(= right (+ left pw over over))
|
|
255
|
-
(=
|
|
280
|
+
(= top (- (self faceTop: face) (if (!= f -1) (- (- (CelHigh f 0 0) ph) over) else 0)))
|
|
281
|
+
(= bottom (+ (self faceTop: face) ph over))
|
|
256
282
|
(return
|
|
257
283
|
(or
|
|
258
|
-
(self over: (if (== self heroTalker) ego else who) left right bottom)
|
|
259
|
-
(and (!= self heroTalker) (self over: ego left right bottom)))))
|
|
284
|
+
(self over: (if (== self heroTalker) ego else who) left right top bottom)
|
|
285
|
+
(and (!= self heroTalker) (self over: ego left right top bottom)))))
|
|
260
286
|
|
|
261
|
-
;; Whether someone's
|
|
262
|
-
(method (over body left right bottom &tmp w h)
|
|
287
|
+
;; Whether someone's head (the top quarter of their figure) is in the box.
|
|
288
|
+
(method (over body left right top bottom &tmp w h)
|
|
263
289
|
(if (or (not body) (not (body respondsTo: #view)) (& (body signal?) SIG_HIDDEN)) (return FALSE))
|
|
264
290
|
(= w (CelWide (body view?) (body loop?) (body cel?)))
|
|
265
291
|
(= h (CelHigh (body view?) (body loop?) (body cel?)))
|
|
@@ -267,7 +293,8 @@
|
|
|
267
293
|
(= w (/ (* w (body scaleX?)) 128))
|
|
268
294
|
(= h (/ (* h (body scaleY?)) 128)))
|
|
269
295
|
(return
|
|
270
|
-
(and (< (- (body x?) (/ w 2)) right) (> (+ (body x?) (/ w 2)) left)
|
|
296
|
+
(and (< (- (body x?) (/ w 2)) right) (> (+ (body x?) (/ w 2)) left)
|
|
297
|
+
(< (- (body y?) h) bottom) (> (+ (- (body y?) h) (/ h 4)) top))))
|
|
271
298
|
|
|
272
299
|
(method (say txt whoCares &tmp face l pw f fx fy over)
|
|
273
300
|
(self init: makeParts:)
|
|
@@ -279,7 +306,7 @@
|
|
|
279
306
|
(= f (textStyle portraitFrame?))
|
|
280
307
|
(= over (if (!= f -1) (/ (- (CelWide f 0 0) pw) 2) else 0))
|
|
281
308
|
(= fx (if side (- SCREEN_WIDTH (+ (textStyle portraitX?) pw)) else (textStyle portraitX?)))
|
|
282
|
-
(= fy (
|
|
309
|
+
(= fy (self faceTop: face))
|
|
283
310
|
(face x: fx y: fy loop: l cel: 0)
|
|
284
311
|
(if mouth (mouth x: fx y: fy loop: (+ l 1) cel: 0))
|
|
285
312
|
(if eyes (eyes x: fx y: fy loop: (+ l 2) cel: 0))
|
|
@@ -288,8 +315,9 @@
|
|
|
288
315
|
(back x: fx y: fy)
|
|
289
316
|
(if (and (not front) (>= (NumLoops back) 2)) (= front ((View new:) view: f loop: 1 cel: 0 yourself:)))
|
|
290
317
|
(if front (front x: fx y: fy)))
|
|
291
|
-
;; The text beside it, towards the middle
|
|
292
|
-
|
|
318
|
+
;; The text beside it, towards the middle: level with its top, or at the bottom of the
|
|
319
|
+
;; screen, ending level with its frame's bottom and growing upwards.
|
|
320
|
+
(= y (if (< (textStyle portraitY?) 0) (- (+ fy (CelHigh (face view?) l 0) over) SCREEN_HEIGHT) else fy))
|
|
293
321
|
(if side
|
|
294
322
|
(= x 6)
|
|
295
323
|
(= width (- fx (+ over 12)))
|
|
@@ -379,19 +407,57 @@
|
|
|
379
407
|
(method (cue)
|
|
380
408
|
(self sayNext:)))
|
|
381
409
|
|
|
382
|
-
;; One choice in a Menu.
|
|
410
|
+
;; One choice in a Menu. In a painted menu it has a row and a bullet behind it, and is in one
|
|
411
|
+
;; of the skin's states (MENU_NORMAL, MENU_HOVER, MENU_PRESSED, MENU_DISABLED).
|
|
383
412
|
(class MenuItem of TextItem
|
|
384
413
|
(properties
|
|
385
|
-
value 0
|
|
414
|
+
value 0
|
|
415
|
+
disabled 0 ; can't be chosen: shown unavailable in a painted menu (a plain one ignores it)
|
|
416
|
+
row 0
|
|
417
|
+
bullet 0
|
|
418
|
+
state -1)
|
|
419
|
+
|
|
420
|
+
;; Anywhere on its row, if it has one.
|
|
421
|
+
(method (onMe theX theY &tmp v)
|
|
422
|
+
(if (not row) (return (super onMe: theX theY)))
|
|
423
|
+
(= v (row view?))
|
|
424
|
+
(return
|
|
425
|
+
(and (>= theX (row x?)) (< theX (+ (row x?) (CelWide v 1 0)))
|
|
426
|
+
(>= theY (row y?)) (< theY (+ (row y?) (CelHigh v 1 0))))))
|
|
427
|
+
|
|
428
|
+
;; Its row, bullet and text as they look in state st.
|
|
429
|
+
(method (setState st &tmp c)
|
|
430
|
+
(if (or (not row) (== st state)) (return))
|
|
431
|
+
(= state st)
|
|
432
|
+
(row setCel: st)
|
|
433
|
+
(bullet setCel: st)
|
|
434
|
+
(= c
|
|
435
|
+
(switch st
|
|
436
|
+
(MENU_HOVER (textStyle menuHover?))
|
|
437
|
+
(MENU_PRESSED (textStyle menuPressed?))
|
|
438
|
+
(MENU_DISABLED (textStyle menuDisabled?))
|
|
439
|
+
(else (textStyle menuFore?))))
|
|
440
|
+
(= fore (if (== c -1) (textStyle fore?) else c))
|
|
441
|
+
(if bitmap
|
|
442
|
+
(Bitmap BITMAP_DISPOSE bitmap)
|
|
443
|
+
(= bitmap (CreateTextBitmap 0 width height self))
|
|
444
|
+
(UpdateScreenItem self)))
|
|
386
445
|
|
|
387
446
|
(method (dispose)
|
|
447
|
+
(if row (row dispose:) (= row 0))
|
|
448
|
+
(if bullet (bullet dispose:) (= bullet 0))
|
|
388
449
|
;; Its text was made for it (a literal string is left alone).
|
|
389
450
|
(String ARRAY_FREE text)
|
|
390
451
|
(super dispose:)))
|
|
391
452
|
|
|
392
|
-
;; Choices one under another in a box (the textStyle's frame around them all);
|
|
393
|
-
;;
|
|
394
|
-
;; hears the choice by `choose: value`.
|
|
453
|
+
;; Choices one under another in a box (the textStyle's frame around them all); a click on one
|
|
454
|
+
;; ends it, and Escape chooses the one worth 0 (Cancel, Carry on, Goodbye). While it's open it
|
|
455
|
+
;; gets every event (it's the `dialog`). The caller hears the choice by `choose: value`.
|
|
456
|
+
;;
|
|
457
|
+
;; A `painted` menu is drawn with the textStyle's menuSkin instead, if it has one and the
|
|
458
|
+
;; choices fit on its panel: each on its row, lit under the pointer, pressed while the button
|
|
459
|
+
;; is down; the arrow keys move between them and Enter or Space chooses, and an unavailable
|
|
460
|
+
;; one is passed over.
|
|
395
461
|
(class Menu of Obj
|
|
396
462
|
(properties
|
|
397
463
|
items 0
|
|
@@ -399,56 +465,175 @@
|
|
|
399
465
|
panel 0
|
|
400
466
|
y 20 ; the top of the box
|
|
401
467
|
width 240
|
|
402
|
-
next 0
|
|
468
|
+
next 0 ; where the next choice goes
|
|
469
|
+
painted 0 ; drawn with the textStyle's menuSkin, if it fits
|
|
470
|
+
skin -1 ; the skin it's drawn with, or -1
|
|
471
|
+
focus 0 ; the choice that's lit
|
|
472
|
+
pressed 0 ; the choice the button went down on
|
|
473
|
+
pointerX -1 pointerY -1)
|
|
474
|
+
|
|
475
|
+
(method (add v txt &tmp item)
|
|
476
|
+
(if (not items) (= items (List new:)))
|
|
477
|
+
(= item ((MenuItem new:) value: v text: txt yourself:))
|
|
478
|
+
(items add: item)
|
|
479
|
+
(return self))
|
|
480
|
+
|
|
481
|
+
;; The choices on their box, then it waits for one.
|
|
482
|
+
(method (show whoCares &tmp s)
|
|
483
|
+
(= caller whoCares)
|
|
484
|
+
(if (not items) (return))
|
|
485
|
+
(= s (textStyle menuSkin?))
|
|
486
|
+
(if (and painted (!= s -1)
|
|
487
|
+
(<= (+ (textStyle menuRowY?) (* (items size?) (textStyle menuRowStep?))) (CelHigh s 0 0)))
|
|
488
|
+
(= skin s)
|
|
489
|
+
(self showPainted:)
|
|
490
|
+
else
|
|
491
|
+
(self showPlain:))
|
|
492
|
+
(= dialog self))
|
|
403
493
|
|
|
404
|
-
(method (
|
|
494
|
+
(method (showPlain &tmp f node item)
|
|
405
495
|
(= f (textStyle frame?))
|
|
406
|
-
(if (
|
|
407
|
-
|
|
408
|
-
(=
|
|
409
|
-
|
|
410
|
-
((MenuItem new:)
|
|
411
|
-
value: v
|
|
412
|
-
text: txt
|
|
496
|
+
(= next (+ y (if (!= f -1) (CelHigh f 0 4) else 1)))
|
|
497
|
+
(for ((= node (FirstNode (items elements?)))) node ((= node (NextNode node)))
|
|
498
|
+
(= item (NodeValue node))
|
|
499
|
+
(item
|
|
413
500
|
frame: -1
|
|
414
501
|
borderColor: -1
|
|
415
502
|
width: (- width (if (!= f -1) (+ (CelWide f 0 6) (CelWide f 0 7)) else 2))
|
|
416
503
|
x: (+ (/ (- SCREEN_WIDTH width) 2) (if (!= f -1) (CelWide f 0 6) else 1))
|
|
417
504
|
y: next
|
|
505
|
+
disabled: 0)
|
|
506
|
+
(item init:)
|
|
507
|
+
(+= next (item height?)))
|
|
508
|
+
(= panel
|
|
509
|
+
((TextItem new:)
|
|
510
|
+
text: ""
|
|
511
|
+
x: (/ (- SCREEN_WIDTH width) 2)
|
|
512
|
+
y: y
|
|
513
|
+
width: width
|
|
514
|
+
height: (+ (- next y) (if (!= f -1) (CelHigh f 0 5) else 1))
|
|
515
|
+
priority: 99
|
|
418
516
|
yourself:))
|
|
419
|
-
(
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
(
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
(=
|
|
427
|
-
(=
|
|
428
|
-
|
|
429
|
-
(
|
|
430
|
-
(
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
517
|
+
(panel init:))
|
|
518
|
+
|
|
519
|
+
(method (showPainted &tmp px py rx ry node item)
|
|
520
|
+
(= px (if (== (textStyle menuX?) -1) (/ (- SCREEN_WIDTH (CelWide skin 0 0)) 2) else (textStyle menuX?)))
|
|
521
|
+
(= py (if (== (textStyle menuY?) -1) (/ (- SCREEN_HEIGHT (CelHigh skin 0 0)) 2) else (textStyle menuY?)))
|
|
522
|
+
(= panel (self part: 0 0 px py 99))
|
|
523
|
+
(= rx (+ px (textStyle menuRowX?)))
|
|
524
|
+
(= ry (+ py (textStyle menuRowY?)))
|
|
525
|
+
(for ((= node (FirstNode (items elements?)))) node ((= node (NextNode node)))
|
|
526
|
+
(= item (NodeValue node))
|
|
527
|
+
(item
|
|
528
|
+
row: (self part: 1 0 rx ry 100)
|
|
529
|
+
bullet: (self part: 2 0 (+ rx (textStyle menuBulletX?)) (+ ry (textStyle menuBulletY?)) 101)
|
|
530
|
+
frame: -1
|
|
531
|
+
borderColor: -1
|
|
532
|
+
margin: 0
|
|
533
|
+
back: 254
|
|
534
|
+
x: (+ rx (textStyle menuTextX?))
|
|
535
|
+
y: (+ ry (textStyle menuTextY?))
|
|
536
|
+
width: (- (CelWide skin 1 0) (textStyle menuTextX?))
|
|
537
|
+
height: (- (CelHigh skin 1 0) (textStyle menuTextY?))
|
|
538
|
+
priority: 102)
|
|
539
|
+
(item setState: (if (item disabled?) MENU_DISABLED else MENU_NORMAL))
|
|
540
|
+
(item init:)
|
|
541
|
+
(+= ry (textStyle menuRowStep?))))
|
|
542
|
+
|
|
543
|
+
;; A cel of the skin on the screen, over the room whether or not there is one.
|
|
544
|
+
(method (part l c theX theY pri &tmp p)
|
|
545
|
+
(= p
|
|
546
|
+
((View new:)
|
|
547
|
+
view: skin loop: l cel: c x: theX y: theY
|
|
548
|
+
plane: uiPlane priority: pri fixPriority: 1
|
|
549
|
+
yourself:))
|
|
550
|
+
(cast add: p)
|
|
551
|
+
(AddScreenItem p)
|
|
552
|
+
(return p))
|
|
553
|
+
|
|
554
|
+
;; Lights choice it (0: none), and only it.
|
|
555
|
+
(method (light it &tmp node item)
|
|
556
|
+
(= focus it)
|
|
557
|
+
(for ((= node (FirstNode (items elements?)))) node ((= node (NextNode node)))
|
|
558
|
+
(= item (NodeValue node))
|
|
559
|
+
(item setState:
|
|
560
|
+
(cond
|
|
561
|
+
((item disabled?) MENU_DISABLED)
|
|
562
|
+
((and (== item pressed) (== item it)) MENU_PRESSED)
|
|
563
|
+
((== item it) MENU_HOVER)
|
|
564
|
+
(else MENU_NORMAL)))))
|
|
565
|
+
|
|
566
|
+
;; The User says where the pointer is each cycle: when it moves, what's under it is lit.
|
|
567
|
+
(method (pointerAt theX theY &tmp item)
|
|
568
|
+
(if (or (== skin -1) (and (== theX pointerX) (== theY pointerY))) (return))
|
|
569
|
+
(= pointerX theX)
|
|
570
|
+
(= pointerY theY)
|
|
571
|
+
(= item (items firstTrue: #onMe theX theY))
|
|
572
|
+
(if (and item (item disabled?)) (= item 0))
|
|
573
|
+
(if (!= item focus) (self light: item)))
|
|
574
|
+
|
|
575
|
+
;; The i-th choice, from 0.
|
|
576
|
+
(method (nth i &tmp node)
|
|
577
|
+
(for ((= node (FirstNode (items elements?)))) (and node i) ((= node (NextNode node)))
|
|
578
|
+
(-- i))
|
|
579
|
+
(return (if node (NodeValue node) else 0)))
|
|
580
|
+
|
|
581
|
+
;; The choice worth v, or 0.
|
|
582
|
+
(method (valued v &tmp node)
|
|
583
|
+
(for ((= node (FirstNode (items elements?)))) node ((= node (NextNode node)))
|
|
584
|
+
(if (== ((NodeValue node) value?) v) (return (NodeValue node))))
|
|
585
|
+
(return 0))
|
|
586
|
+
|
|
587
|
+
;; Lights the next choice that's available, dir 1 down or -1 up, round from the end.
|
|
588
|
+
(method (step dir &tmp i n k node item)
|
|
589
|
+
(= n (items size?))
|
|
590
|
+
(= i (if (> dir 0) -1 else n))
|
|
591
|
+
(= k 0)
|
|
592
|
+
(for ((= node (FirstNode (items elements?)))) node ((= node (NextNode node)))
|
|
593
|
+
(if (== (NodeValue node) focus) (= i k))
|
|
594
|
+
(++ k))
|
|
595
|
+
(for ((= k 0)) (< k n) ((++ k))
|
|
596
|
+
(= i (mod (+ i dir n) n))
|
|
597
|
+
(= item (self nth: i))
|
|
598
|
+
(if (not (item disabled?))
|
|
599
|
+
(self light: item)
|
|
600
|
+
(return))))
|
|
601
|
+
|
|
602
|
+
(method (handleEvent event &tmp item)
|
|
442
603
|
(event claimed: TRUE)
|
|
443
|
-
(
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
604
|
+
(switch (event type?)
|
|
605
|
+
(EV_KEY_DOWN
|
|
606
|
+
(switch (event message?)
|
|
607
|
+
(KEY_ESCAPE (self pick: (self valued: 0)))
|
|
608
|
+
(KEY_UP (if (!= skin -1) (self step: -1)))
|
|
609
|
+
(KEY_DOWN (if (!= skin -1) (self step: 1)))
|
|
610
|
+
(KEY_ENTER (if focus (self pick: focus)))
|
|
611
|
+
(KEY_SPACE (if focus (self pick: focus)))))
|
|
612
|
+
(EV_MOUSE_DOWN
|
|
613
|
+
(= item (items firstTrue: #onMe (event x?) (event y?)))
|
|
614
|
+
(cond
|
|
615
|
+
((== skin -1) (self pick: item))
|
|
616
|
+
((and item (not (item disabled?)))
|
|
617
|
+
(= pressed item)
|
|
618
|
+
(self light: item))))
|
|
619
|
+
(EV_MOUSE_UP
|
|
620
|
+
(if pressed
|
|
621
|
+
(= item (items firstTrue: #onMe (event x?) (event y?)))
|
|
622
|
+
(if (== item pressed)
|
|
623
|
+
(self pick: item)
|
|
624
|
+
else
|
|
625
|
+
(= pressed 0)
|
|
626
|
+
(self light: (if (and item (not (item disabled?))) item else 0))))))
|
|
450
627
|
(return TRUE))
|
|
451
628
|
|
|
629
|
+
;; Ends it with that choice (none: it stays open).
|
|
630
|
+
(method (pick item &tmp v c)
|
|
631
|
+
(if (or (not item) (item disabled?)) (return))
|
|
632
|
+
(= v (item value?))
|
|
633
|
+
(= c caller)
|
|
634
|
+
(self dispose:)
|
|
635
|
+
(c choose: v))
|
|
636
|
+
|
|
452
637
|
;; Closed without a choice.
|
|
453
638
|
(method (dismiss)
|
|
454
639
|
(self dispose:))
|
package/lib/system.sh
CHANGED
|
@@ -39,6 +39,12 @@
|
|
|
39
39
|
|
|
40
40
|
(define SAVE_DESCRIPTION 36)
|
|
41
41
|
(define SAVES_SHOWN 8)
|
|
42
|
+
;; A painted menu choice's look: the cels of the skin's row and bullet loops.
|
|
43
|
+
(define MENU_NORMAL 0)
|
|
44
|
+
(define MENU_HOVER 1)
|
|
45
|
+
(define MENU_PRESSED 2)
|
|
46
|
+
(define MENU_DISABLED 3)
|
|
47
|
+
|
|
42
48
|
(define SR_MENU 1)
|
|
43
49
|
(define SR_SAVE 2)
|
|
44
50
|
(define SR_RESTORE 3)
|
|
@@ -74,6 +80,8 @@
|
|
|
74
80
|
(define KEY_SPACE 32)
|
|
75
81
|
(define KEY_PERIOD 46)
|
|
76
82
|
(define KEY_ESCAPE 27)
|
|
83
|
+
(define KEY_UP $4800)
|
|
84
|
+
(define KEY_DOWN $5000)
|
|
77
85
|
(define KEY_F5 $3f00)
|
|
78
86
|
(define KEY_F7 $4100)
|
|
79
87
|
(define KEY_I 73)
|