Free Hero Mesh

Check-in [3a60ccaef6]
Login
This is a mirror of the main repository for Free Hero Mesh. New tickets and changes will not be accepted at this mirror.
Overview
Comment:Several minor corrections to documentation. No code changes.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 3a60ccaef6965a85d09ade7b7ef6ae8dd99ea665
User & Date: user on 2022-02-14 08:01:07
Other Links: manifest | tags
Context
2022-02-14
08:22
Implement the (userflags) syntax with an implied attribute. check-in: 7268a9ce16 user: user tags: trunk
08:01
Several minor corrections to documentation. No code changes. check-in: 3a60ccaef6 user: user tags: trunk
2022-02-13
19:32
Implement XStep and YStep instructions. check-in: a6d1d398e5 user: user tags: trunk
Changes

Modified ARCHITECTURE from [cf4caa50f5] to [776275acf7].

47
48
49
50
51
52
53



54
55
56
57
58
59
60
61
62
63

64
65
66

67
68
69
70
71
72
73
(locate_me) which is called by exec.c.

hash.c,hash.h: A set of functions for computing cryptographic hashes.
These functions can be used outside of Free Hero Mesh, too. If you want
to add new algorithms, use the multicodec table to assign the numbers.
(Currently they are not used for anything, but some planned features may
use it in future.)




instruc,instruc.h,instruc.js: The "instruc" file contains a list of the
keywords and internal operator names used in the class definitions. Some
of these are only used internally, although most are available directly
as keywords. Many are also opcodes in the compiled P-code, although some
are only used as keywords, which are handled during class loading. The
instruc.js program generates instruc.h from instruc.

keyicons.xbm: Graphics for key icons. These are used to display the replay
list on the left side of the screen.


main.c: Contains code for start-up, and for initializing and dealing with
the user cache database.


mbtofhm.c: The converter from Hero Mesh to Free Hero Mesh. This is not
compiled into Free Hero Mesh; it is a separate program.

pcfont.h: Contains the graphics for the PC character set.

picedit.c: The picture editor.







>
>
>









|
>


|
>







47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
(locate_me) which is called by exec.c.

hash.c,hash.h: A set of functions for computing cryptographic hashes.
These functions can be used outside of Free Hero Mesh, too. If you want
to add new algorithms, use the multicodec table to assign the numbers.
(Currently they are not used for anything, but some planned features may
use it in future.)

imgtofhm.c: A separate program (not compiled into Free Hero Mesh) for
batch importing pictures into Free Hero Mesh.

instruc,instruc.h,instruc.js: The "instruc" file contains a list of the
keywords and internal operator names used in the class definitions. Some
of these are only used internally, although most are available directly
as keywords. Many are also opcodes in the compiled P-code, although some
are only used as keywords, which are handled during class loading. The
instruc.js program generates instruc.h from instruc.

keyicons.xbm: Graphics for key icons. These are used to display the replay
list on the left side of the screen. Consists of a vertical strip of icons
each of size 16x16, and is compiled into the program.

main.c: Contains code for start-up, and for initializing and dealing with
the user cache database. The code for loading levels and is also here, as
is the code for loading/saving lumps in the level file and solution file.

mbtofhm.c: The converter from Hero Mesh to Free Hero Mesh. This is not
compiled into Free Hero Mesh; it is a separate program.

pcfont.h: Contains the graphics for the PC character set.

picedit.c: The picture editor.
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
quarks for use with the resource manager. The quarks.js program converts
quarks into quarks.h.

smallxrm.c,smallxrm.h: An implementation of the X resource manager. This
can be used independently from Free Hero Mesh.

sound.c: Implements sound effects. Also deals with loading sound effects,
amplification, MML, etc.



=== Invariants ===

All game state changes which persist across turns and can affect the
behaviour of the game MUST be deterministic, depending only on the level
data, the player's inputs, the previous state, and the class definitions.







|
>







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
quarks for use with the resource manager. The quarks.js program converts
quarks into quarks.h.

smallxrm.c,smallxrm.h: An implementation of the X resource manager. This
can be used independently from Free Hero Mesh.

sound.c: Implements sound effects. Also deals with loading sound effects,
amplification, MML, etc, and the sound test menu. Sounds are automatically
converted and amplified when loading.


=== Invariants ===

All game state changes which persist across turns and can affect the
behaviour of the game MUST be deterministic, depending only on the level
data, the player's inputs, the previous state, and the class definitions.

Modified class.doc from [36fb7b963b] to [6a4cbc1458].

79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

\c
  Makes further text centred.

\dDATA\
  Includes inline data in the string. The data is not displayed, but
  can be read by class codes, or used in level titles to provide data
  and delimieters for the auto-generated table of contents. Data items
  are separated by semicolons; each item can be a underscore to mean a
  mark, a number (decimal integers only), or a class name with $ at front.
  (Not fully implemented yet)

\iCLASS:NUMBER\
  Displays a picture. Give the class name (without $ at first) and a
  colon and the zero-based index number of the picture in that class.







|







79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

\c
  Makes further text centred.

\dDATA\
  Includes inline data in the string. The data is not displayed, but
  can be read by class codes, or used in level titles to provide data
  and delimiters for the auto-generated table of contents. Data items
  are separated by semicolons; each item can be a underscore to mean a
  mark, a number (decimal integers only), or a class name with $ at front.
  (Not fully implemented yet)

\iCLASS:NUMBER\
  Displays a picture. Give the class name (without $ at first) and a
  colon and the zero-based index number of the picture in that class.
580
581
582
583
584
585
586
587

588
589
590
591
592
593
594
595
596
597
598

599
600
601
602
603
604
605
* Object: A reference to an object. There are no literals of this type.

* String: A string in quotation marks. There are no string manipulation
functions; the only thing that can be done with a string is to display it,
or to compare if one string matches another.

* Sound: A named sound effect. Values of this type cannot be compared with
anything, even other values of the same type.


* Mark: There is only one value of this type; it is used to delimit lists
of values on the stack.

* Array: A reference to an array. You cannot allocate arrays at run time;
the available array memory is fixed at compile time, subject to the global
array definitions.

* Link: A link to another point in the code of some class or global. Where
a link is expected, you can also specify a message to mean that message
block for the Self object.


Some things are not their own types, and are other uses of numbers:

* Null: A null class or null object is represented as zero.

* Boolean: When a boolean is required as input to some instruction, zero
is false, and most other values (of any type) are true, except for sounds







|
>










|
>







580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
* Object: A reference to an object. There are no literals of this type.

* String: A string in quotation marks. There are no string manipulation
functions; the only thing that can be done with a string is to display it,
or to compare if one string matches another.

* Sound: A named sound effect. Values of this type cannot be compared with
anything, even other values of the same type. A sound can be either a
built-in sound or user sound.

* Mark: There is only one value of this type; it is used to delimit lists
of values on the stack.

* Array: A reference to an array. You cannot allocate arrays at run time;
the available array memory is fixed at compile time, subject to the global
array definitions.

* Link: A link to another point in the code of some class or global. Where
a link is expected, you can also specify a message to mean that message
block for the Self object (this is not quite the same as sending that
message to itself, though).

Some things are not their own types, and are other uses of numbers:

* Null: A null class or null object is represented as zero.

* Boolean: When a boolean is required as input to some instruction, zero
is false, and most other values (of any type) are true, except for sounds
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
ArraySlice  ( array start count -- array )
  Make a slice of an array. The new reference aliases the original array.
  Coordinates are zero-based.

Assassinate  ( -- ) **
  Destroy this object without sending any messages. The object is marked
  as destroyed, but its variables are still accessible until the garbage
  collector runs (during the trigger step for combatible objects, and
  during the cleanup step for all objects). Assassination always succeeds,
  so there is no result value to indicate success or not.

,Assassinate  ( obj -- ) **
  Destroy the given object without sending any messages.

band  ( in1 in2 -- out )







|







1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
ArraySlice  ( array start count -- array )
  Make a slice of an array. The new reference aliases the original array.
  Coordinates are zero-based.

Assassinate  ( -- ) **
  Destroy this object without sending any messages. The object is marked
  as destroyed, but its variables are still accessible until the garbage
  collector runs (during the trigger step for compatible objects, and
  during the cleanup step for all objects). Assassination always succeeds,
  so there is no result value to indicate success or not.

,Assassinate  ( obj -- ) **
  Destroy the given object without sending any messages.

band  ( in1 in2 -- out )
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
  Checks hardness/sharpness and shoving like is done by Move, subject to
  From and Arg3. The direction is a direction relative to From, not to
  Self. The result is 1 if shoving or sharpness is successful, or 0
  otherwise. This will update Arg3,including at least setting the low
  three bits; the new value of Arg3 may then be used as the return value
  from HITBY. It is intended that this instruction is used inside of a
  HITBY block, in case you want to do some of your own processing. The
  Comaptible and VisualOnly flags of this object are not checked.

IgnoreKey  ( -- )
  There is no effect outside of the input phase. During the input phase,
  indicates that this input is not part of the solution, so it will not
  be entered into the replay. It is an error to ignore inputs which do
  cause state changes. Pop-up messages are still allowed, and unlike in
  EKS Hero Mesh they will not break replayability; the key to dismiss a







|







1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
  Checks hardness/sharpness and shoving like is done by Move, subject to
  From and Arg3. The direction is a direction relative to From, not to
  Self. The result is 1 if shoving or sharpness is successful, or 0
  otherwise. This will update Arg3,including at least setting the low
  three bits; the new value of Arg3 may then be used as the return value
  from HITBY. It is intended that this instruction is used inside of a
  HITBY block, in case you want to do some of your own processing. The
  Compatible and VisualOnly flags of this object are not checked.

IgnoreKey  ( -- )
  There is no effect outside of the input phase. During the input phase,
  indicates that this input is not part of the solution, so it will not
  be entered into the replay. It is an error to ignore inputs which do
  cause state changes. Pop-up messages are still allowed, and unlike in
  EKS Hero Mesh they will not break replayability; the key to dismiss a
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
,min  ( in1 in2 -- out )
  Whichever input number is lesser (signed).

mod  ( in1 in2 -- out )
  Unsigned divide in1 by in2 producing the remainder.

,mod  ( in1 in2 -- out )
  Signed divide in1 by in2 producing the remander.

Move  ( dir -- bool ) **
  Move this object in the given direction (which may be absolute or
  relative to the current direction). The result will be true if the
  move is successful or false if it failed. See the section about
  movement for details.








|







1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
,min  ( in1 in2 -- out )
  Whichever input number is lesser (signed).

mod  ( in1 in2 -- out )
  Unsigned divide in1 by in2 producing the remainder.

,mod  ( in1 in2 -- out )
  Signed divide in1 by in2 producing the remainder.

Move  ( dir -- bool ) **
  Move this object in the given direction (which may be absolute or
  relative to the current direction). The result will be true if the
  move is successful or false if it failed. See the section about
  movement for details.

1763
1764
1765
1766
1767
1768
1769
1770

1771
1772
1773
1774
1775
1776
1777
,ObjDir  ( obj dir -- obj )
  Find the top-most object in the cell one step in the specified direction
  from the specified object.

ObjLayerAt  ( layers x y -- obj )
  Find an object with the given CollisionLayers bits set at that location.
  If you specify multiple bits, it finds one with any of those bits. (It
  is not possible for there to be more than one such object.)


ObjMovingTo  ( x y -- ... )
  Push on the stack all objects scheduled to move to the specified X and Y
  coordinates. There may be zero or more such objects; you can add a mark
  to the stack in order to delimit this list (it won't do so automatically,
  since you may be putting multiple lists together).








|
>







1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
,ObjDir  ( obj dir -- obj )
  Find the top-most object in the cell one step in the specified direction
  from the specified object.

ObjLayerAt  ( layers x y -- obj )
  Find an object with the given CollisionLayers bits set at that location.
  If you specify multiple bits, it finds one with any of those bits. (It
  is not possible for there to be more than one such object if you specify
  only one bit. If there are multiple, the bottom-most one is returned.)

ObjMovingTo  ( x y -- ... )
  Push on the stack all objects scheduled to move to the specified X and Y
  coordinates. There may be zero or more such objects; you can add a mark
  to the stack in order to delimit this list (it won't do so automatically,
  since you may be putting multiple lists together).

1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822

Rel  ( dir -- dir )
  Resolves a relative direction to an absolute direction.

,Rel  ( obj dir -- dir )
  Resolves a relative direction to an absolute direction, using the
  direction of the specified object as the base. If zero is specified
  instead of a valid object, thent the result is the same as the input.

ret  ( -- )
  Exit the current subroutine. If this is a message block, it must either
  leave the stack as it is, or leave it but with one extra value pushed
  which will be the return value from the message call. (This is implied
  at the end of a code block.) For a user defined function call, or a
  subroutine call, these restrictions are not applicable.







|







1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825

Rel  ( dir -- dir )
  Resolves a relative direction to an absolute direction.

,Rel  ( obj dir -- dir )
  Resolves a relative direction to an absolute direction, using the
  direction of the specified object as the base. If zero is specified
  instead of a valid object, then the result is the same as the input.

ret  ( -- )
  Exit the current subroutine. If this is a message block, it must either
  leave the stack as it is, or leave it but with one extra value pushed
  which will be the return value from the message call. (This is implied
  at the end of a code block.) For a user defined function call, or a
  subroutine call, these restrictions are not applicable.
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911

Sweep  ( xstart ystart xend yend order msg arg1 arg2 -- )
  Send a message to all objects in the specified rectangle, given its
  corners. The coordinates are treated as signed, so you can safely make
  a surrounding rectangle with a specified radius if wanted. If all of the
  coordinates are out of range and not on opposite sides of the playfield,
  no messages are sent. The order of sending the messages is starting at
  the start coordinates and ending at the end cordinates, regardless of
  which are greater than the others; if the order is true then it does
  vertical movement first and if false then horizontal movement first.

SweepEx  ( xstart ystart xend yend order msg arg1 arg2 arg3 -- )
  Same as Sweep but three message arguments.

Synchronize  ( slot startimage -- ) **







|







1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914

Sweep  ( xstart ystart xend yend order msg arg1 arg2 -- )
  Send a message to all objects in the specified rectangle, given its
  corners. The coordinates are treated as signed, so you can safely make
  a surrounding rectangle with a specified radius if wanted. If all of the
  coordinates are out of range and not on opposite sides of the playfield,
  no messages are sent. The order of sending the messages is starting at
  the start coordinates and ending at the end coordinates, regardless of
  which are greater than the others; if the order is true then it does
  vertical movement first and if false then horizontal movement first.

SweepEx  ( xstart ystart xend yend order msg arg1 arg2 arg3 -- )
  Same as Sweep but three message arguments.

Synchronize  ( slot startimage -- ) **
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
  pending, it will clear the trigger and send it like it does during the
  trigger phase, setting Arg1 as appropriate, but From is set to the object
  calling it instead of 0, and Arg2 and Arg3 will be inherited from the
  current values of those variables. The return value is ignored. Since the
  trigger is cleared before it is sent, it is safe for objects to call the
  triggers of objects in a loop.

TriggerAt  ( x ymessage -- ) **
  Works like Trigger on all objects at the specified location, from the
  bottom to the top.

tuck  ( x y -- y x y )

uniq  ( mark ... value -- mark ... value true | mark ... false )
  Check if the top value matches any others in the list above the mark. If







|







1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
  pending, it will clear the trigger and send it like it does during the
  trigger phase, setting Arg1 as appropriate, but From is set to the object
  calling it instead of 0, and Arg2 and Arg3 will be inherited from the
  current values of those variables. The return value is ignored. Since the
  trigger is cleared before it is sent, it is safe for objects to call the
  triggers of objects in a loop.

TriggerAt  ( x y message -- ) **
  Works like Trigger on all objects at the specified location, from the
  bottom to the top.

tuck  ( x y -- y x y )

uniq  ( mark ... value -- mark ... value true | mark ... false )
  Check if the top value matches any others in the list above the mark. If
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
  The label name must have a colon at front; if a comma is also added
  then numeric values of this column are treated as signed.

(<string> <label> <width> <format> <color>)
  Defines a display column. The <label> is the name of the data column.
  The <width> is a number 1 to 255 or it can be * for fill width; only
  the last column is allowed to be fill width (although it is also OK if
  no colums are fill width). The <format> is a string of exactly one or
  two characters; see the below list of possible formats. The <color> is
  the text colour, and is optional; it can be a number from 1 to 255, or
  it can be a sequence of parenthesized pairs of a number (-127 to +127)
  and colour, to mean use those colour if the value of this column is
  in range. It uses the colour for all values up to and including the
  specified number, so the numbers should be listed in ascending order,
  in order to work. If the last number is 127 then it is also use for all







|







2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
  The label name must have a colon at front; if a comma is also added
  then numeric values of this column are treated as signed.

(<string> <label> <width> <format> <color>)
  Defines a display column. The <label> is the name of the data column.
  The <width> is a number 1 to 255 or it can be * for fill width; only
  the last column is allowed to be fill width (although it is also OK if
  no columns are fill width). The <format> is a string of exactly one or
  two characters; see the below list of possible formats. The <color> is
  the text colour, and is optional; it can be a number from 1 to 255, or
  it can be a sequence of parenthesized pairs of a number (-127 to +127)
  and colour, to mean use those colour if the value of this column is
  in range. It uses the colour for all values up to and including the
  specified number, so the numbers should be listed in ascending order,
  in order to work. If the last number is 127 then it is also use for all

Modified edit.doc from [5f662b4d3a] to [d2b98051f2].

206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
one above or below by shift and arrows. If you push alt and arrows, will
move the cursor to the next division in that direction.

Push insert to add a division (just above the cursor), or delete to delete
a division (only divisions can be deleted in this way, not levels).

Another way to reorder the items is to add marks by pushing F2 (or click
by right mouse button) on each one, and tghen push F3 (or click by middle
mouse button) at the point to be moved to; they are removed from where
they were before and put here in the order in which they were marked.


=== Summary of default key/mouse bindings ===

Keyboard:







|







206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
one above or below by shift and arrows. If you push alt and arrows, will
move the cursor to the next division in that direction.

Push insert to add a division (just above the cursor), or delete to delete
a division (only divisions can be deleted in this way, not levels).

Another way to reorder the items is to add marks by pushing F2 (or click
by right mouse button) on each one, and then push F3 (or click by middle
mouse button) at the point to be moved to; they are removed from where
they were before and put here in the order in which they were marked.


=== Summary of default key/mouse bindings ===

Keyboard:

Modified picedit.doc from [fe0ca8910f] to [5b2aad712f].

89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
  square in order for this to work.

F2
  Rotate marked area counterclockwise by 90 degrees. The marked area must
  be square in order for this to work.

F3
  Flip marked area verticaly.

F4
  Flip marked area horizontally.

F5
  Resizes the current image variant. It will ask for the size; enter a
  number from 1 to 255 to set the size (which is always square), and then







|







89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
  square in order for this to work.

F2
  Rotate marked area counterclockwise by 90 degrees. The marked area must
  be square in order for this to work.

F3
  Flip marked area vertically.

F4
  Flip marked area horizontally.

F5
  Resizes the current image variant. It will ask for the size; enter a
  number from 1 to 255 to set the size (which is always square), and then
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
For clicking in the palette or the Pick mode, with the middle or right
mouse button, you can also push CTRL or SHIFT keys with it in order to
affect only odd or only even coordinates.


=== Dependent pictures ===

A depedent picture depends on one or more independent pictures. It
consists of any combination of the following items, in any order:

* Base: This one must come first, and is the independent picture which
will be used as the base; all other filters are applied to alter it.

* Flip/rotation: Flip/rotate the picture. "Identity" also belongs to this
category, but ahs no effect.

* Replace colors: A list of pairs of colours. The first of each pair is
the old colour, and next the colour to replace it with.

* Advance colours: A list of colours; change each colour mentioned in the
list into the next colour in the list after that one.

* Exchange colours: A list of pairs of colours; each colour is changed to
the other colour in the pair.

* Overlay: Paste the specified independent picture over the current
picture, showing through wherever it is transparent.

* Shift: Shift the picture. Specify the sizes and shift amounts in the
format "size: shift"; each size also affects all multiples of that size,
in which case the shift amoutn is also multiplied by the same amount.








|






|















|

203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
For clicking in the palette or the Pick mode, with the middle or right
mouse button, you can also push CTRL or SHIFT keys with it in order to
affect only odd or only even coordinates.


=== Dependent pictures ===

A dependent picture depends on one or more independent pictures. It
consists of any combination of the following items, in any order:

* Base: This one must come first, and is the independent picture which
will be used as the base; all other filters are applied to alter it.

* Flip/rotation: Flip/rotate the picture. "Identity" also belongs to this
category, but has no effect.

* Replace colors: A list of pairs of colours. The first of each pair is
the old colour, and next the colour to replace it with.

* Advance colours: A list of colours; change each colour mentioned in the
list into the next colour in the list after that one.

* Exchange colours: A list of pairs of colours; each colour is changed to
the other colour in the pair.

* Overlay: Paste the specified independent picture over the current
picture, showing through wherever it is transparent.

* Shift: Shift the picture. Specify the sizes and shift amounts in the
format "size: shift"; each size also affects all multiples of that size,
in which case the shift amount is also multiplied by the same amount.