mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-25 03:00:46 +00:00
Lunatic: various unrelated changes and more documentation.
- check map-text version on load - LunaCON: don't allow (back)slash as identifier char - LunaCON stand-alone: don't resort to default directory for root file names - document non-local control flow functions and for LunaCON, ambigious lexical elements git-svn-id: https://svn.eduke32.com/eduke32@3933 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
6e443944c3
commit
f37d845f02
4 changed files with 99 additions and 14 deletions
|
@ -4,7 +4,7 @@ Helixhorned <contact: Duke4.net forums>
|
||||||
:max-width: 56em
|
:max-width: 56em
|
||||||
:numbered:
|
:numbered:
|
||||||
:icons:
|
:icons:
|
||||||
|
:conf-files: lunatic.conf
|
||||||
|
|
||||||
|
|
||||||
Introduction
|
Introduction
|
||||||
|
@ -204,3 +204,50 @@ Currently, the only exception to this rule is that a `definequote` is allowed
|
||||||
inside delimited blocks, which however does not change its semantics in any
|
inside delimited blocks, which however does not change its semantics in any
|
||||||
way: it still only defines the initial contents of a quote, and does not
|
way: it still only defines the initial contents of a quote, and does not
|
||||||
magically act like `redefinequote`.
|
magically act like `redefinequote`.
|
||||||
|
|
||||||
|
Ambiguous lexical elements
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
LunaCON is fairly relaxed as to which character sequences constitute valid
|
||||||
|
identifier names used for e.g. ++define++d labels or variables. It does so out
|
||||||
|
of the necessity of supporting CON code found ``in the wild''. An identifier
|
||||||
|
|
||||||
|
* must not be a token denoting a number,
|
||||||
|
* must start with an _allowed first character_,
|
||||||
|
* may contain any number of _allowed following characters_,
|
||||||
|
|
||||||
|
where
|
||||||
|
|
||||||
|
* allowed first characters are: letters, digits, and those in ```_*?`''
|
||||||
|
* allowed following characters are the same as allowed first characters, plus
|
||||||
|
``+++++'' and ``++-++'' .
|
||||||
|
|
||||||
|
// ^ `+` and `-`
|
||||||
|
|
||||||
|
Numbers can be written in either decimal or hexadecimal form, optionally
|
||||||
|
prepended by a ``++-++'' sign. In the decimal case, the modulus of the number
|
||||||
|
can be (lexically) any sequence of decimal digits, though there are
|
||||||
|
restrictions on the permitted values.footnote:[Specifically, it is forbidden to
|
||||||
|
write a number whose value falls outside the range [--2^31^-1 .. 2^32^--1\].]
|
||||||
|
Hexadecimal number literals must be prefixed with `0x` or `0X`, and may
|
||||||
|
optionally be suffixed with an `h`.
|
||||||
|
|
||||||
|
The following constructions are not allowed, as they would create ambiguities
|
||||||
|
with the definitions above:
|
||||||
|
|
||||||
|
* A sequence of digits followed by letters to mean the the digits interpreted
|
||||||
|
as a number, ignoring the trailing letters, e.g. `1267AT`.
|
||||||
|
* A hexadecimal constant denoted using only a trailing `h`, for example
|
||||||
|
`00000000h`.
|
||||||
|
|
||||||
|
Run-time changes
|
||||||
|
~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Behavior on error
|
||||||
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
As LunaCON is implemented by translating all given CON code to a Lunatic
|
||||||
|
module, it is the Lunatic runtime that checks for proper use of its services at
|
||||||
|
execution time and takes care of error handling and reporting. In Lua, an error
|
||||||
|
link:lunatic.html/#nlcf[transfers control] to the end of the innermost
|
||||||
|
``protected'' call of a Lua chunk.
|
||||||
|
|
|
@ -1076,6 +1076,8 @@ containing the appropriate data.
|
||||||
[[gameactor]]
|
[[gameactor]]
|
||||||
===== The function `gameactor{tilenum [, ...], func}`
|
===== The function `gameactor{tilenum [, ...], func}`
|
||||||
|
|
||||||
|
:Lua51_FunctionCalls: http://www.lua.org/manual/5.1/manual.html#2.5.8
|
||||||
|
|
||||||
Registers custom code for the actor given by tile number `tilenum`. For each
|
Registers custom code for the actor given by tile number `tilenum`. For each
|
||||||
non-sleeping actor, the function `func` is called every game tic with three
|
non-sleeping actor, the function `func` is called every game tic with three
|
||||||
input arguments: `func(aci, pli, dist)`.
|
input arguments: `func(aci, pli, dist)`.
|
||||||
|
@ -1098,6 +1100,7 @@ keys of the argument table. Each such input argument may be provided in at most
|
||||||
one of these two forms. Furthermore, `func` may be provided as value to the
|
one of these two forms. Furthermore, `func` may be provided as value to the
|
||||||
key `'func'` as well.
|
key `'func'` as well.
|
||||||
|
|
||||||
|
[[gameactor_flags]]
|
||||||
`[2] flags`::
|
`[2] flags`::
|
||||||
A number that controls both certain aspects of the `gameactor` call as well as
|
A number that controls both certain aspects of the `gameactor` call as well as
|
||||||
the run-time behavior of the actor itself. A couple of bits for the latter type
|
the run-time behavior of the actor itself. A couple of bits for the latter type
|
||||||
|
@ -1114,6 +1117,11 @@ actor (this may have happened from a CON `useractor` block, which gets
|
||||||
translated to `gameactor`). Moreover, this mechanism allows to add run-time
|
translated to `gameactor`). Moreover, this mechanism allows to add run-time
|
||||||
flags to the actor in question.
|
flags to the actor in question.
|
||||||
+
|
+
|
||||||
|
Chaining two callback functions is achieved by creating a new one that calls
|
||||||
|
the first one, followed by a {Lua51_FunctionCalls}[tail call] of the second
|
||||||
|
one. This has certain implications if control is transferred non-locally by
|
||||||
|
e.g. using <<nlcf,`con.longjmp`>>.
|
||||||
|
+
|
||||||
Several flags in `AF` are provided to control how a `gameactor` invocation
|
Several flags in `AF` are provided to control how a `gameactor` invocation
|
||||||
handles chaining.
|
handles chaining.
|
||||||
+
|
+
|
||||||
|
@ -1383,8 +1391,8 @@ The `con` module -- game control
|
||||||
|
|
||||||
The `con` module on one hand provides functionality to control certain aspects
|
The `con` module on one hand provides functionality to control certain aspects
|
||||||
of the game, such as defining game-side animations for actors. On the other
|
of the game, such as defining game-side animations for actors. On the other
|
||||||
hand, it hosts varioius functions that are familiar from CON, although
|
hand, it hosts various functions that are familiar from CON, although sometimes
|
||||||
sometimes under a different name.
|
under a different name.
|
||||||
|
|
||||||
[[actions_moves_ais]]
|
[[actions_moves_ais]]
|
||||||
Actions, moves and AIs -- customizing actor behavior
|
Actions, moves and AIs -- customizing actor behavior
|
||||||
|
@ -1502,3 +1510,27 @@ an _AI_ object containing these. Also, it is called with three positional,
|
||||||
optional arguments. Like for <<gameactor,`gameactor`>>, the numbers 0 and 1 are
|
optional arguments. Like for <<gameactor,`gameactor`>>, the numbers 0 and 1 are
|
||||||
permissible for `action` and `move`. Applicable bits for `movflags` are
|
permissible for `action` and `move`. Applicable bits for `movflags` are
|
||||||
available in the <<actor_MOVFLAGS,`actor.MOVFLAGS`>> object.
|
available in the <<actor_MOVFLAGS,`actor.MOVFLAGS`>> object.
|
||||||
|
|
||||||
|
[[nlcf]]
|
||||||
|
Non-local control flow
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Two functions in the `con` module make the executed function abort early,
|
||||||
|
jumping directly to the end of the innermost event or actor callback
|
||||||
|
``block''. They are used to implement among others CON's `killit` and
|
||||||
|
(confusingly named) `return` commands. If these functions are used outside of
|
||||||
|
the mentioned callback functions, the behavior is undefined.
|
||||||
|
|
||||||
|
`con.longjmp()`::
|
||||||
|
Silently transfers control to the end of the innermost actor or event callback
|
||||||
|
block, to the same point an `error()` call would do. Note that since callback
|
||||||
|
<<gameactor_flags,chaining>> is achieved by creating a new function for each
|
||||||
|
pair calling the original ones unprotected, issuing a `con.longjmp()` inside
|
||||||
|
any ``part'' of a chain aborts the whole block -- functions in the chain that
|
||||||
|
are called later will not be reached. In contrast, returning from one function
|
||||||
|
transfers control to the beginning of the next in the chain if it exists.
|
||||||
|
|
||||||
|
`con.killit()`::
|
||||||
|
Silently transfers control to the end of the active actor callback block,
|
||||||
|
notifying the game to delete the executing actor's sprite. If `con.killit` is
|
||||||
|
called while no execution of actor code is active, the behavior is undefined.
|
||||||
|
|
|
@ -428,17 +428,21 @@ local function loadboard_maptext(fil, posptr, angptr, cursectnumptr)
|
||||||
return RETERR-5
|
return RETERR-5
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if (not (map.version <= 10)) then
|
||||||
|
return RETERR-6
|
||||||
|
end
|
||||||
|
|
||||||
local msector, mwall, msprite = map.sector, map.wall, map.sprite
|
local msector, mwall, msprite = map.sector, map.wall, map.sprite
|
||||||
|
|
||||||
if (not alltabtab(msector) or not alltabtab(mwall) or not alltabtab(msprite)) then
|
if (not alltabtab(msector) or not alltabtab(mwall) or not alltabtab(msprite)) then
|
||||||
return RETERR-6
|
return RETERR-7
|
||||||
end
|
end
|
||||||
|
|
||||||
if (not tabofnumtabs(msector, sector_members) or
|
if (not tabofnumtabs(msector, sector_members) or
|
||||||
not tabofnumtabs(mwall, wall_members) or
|
not tabofnumtabs(mwall, wall_members) or
|
||||||
not tabofnumtabs(msprite, sprite_members))
|
not tabofnumtabs(msprite, sprite_members))
|
||||||
then
|
then
|
||||||
return RETERR-7
|
return RETERR-8
|
||||||
end
|
end
|
||||||
|
|
||||||
local numsectors, numwalls, numsprites = #msector, #mwall, #msprite
|
local numsectors, numwalls, numsprites = #msector, #mwall, #msprite
|
||||||
|
@ -447,7 +451,7 @@ local function loadboard_maptext(fil, posptr, angptr, cursectnumptr)
|
||||||
if (numsectors+0ULL > ffiC.MAXSECTORS or numwalls+0ULL > ffiC.MAXWALLS or
|
if (numsectors+0ULL > ffiC.MAXSECTORS or numwalls+0ULL > ffiC.MAXWALLS or
|
||||||
numsprites+0ULL > ffiC.MAXSPRITES)
|
numsprites+0ULL > ffiC.MAXSPRITES)
|
||||||
then
|
then
|
||||||
return RETERR-8
|
return RETERR-9
|
||||||
end
|
end
|
||||||
|
|
||||||
--- From here on, start filling out C structures. ---
|
--- From here on, start filling out C structures. ---
|
||||||
|
@ -466,21 +470,21 @@ local function loadboard_maptext(fil, posptr, angptr, cursectnumptr)
|
||||||
-- Sectors.
|
-- Sectors.
|
||||||
for i=0,numsectors-1 do
|
for i=0,numsectors-1 do
|
||||||
if (read_struct(sector[i], msector[i+1], sector_members, sector_default)) then
|
if (read_struct(sector[i], msector[i+1], sector_members, sector_default)) then
|
||||||
return RETERR-9
|
return RETERR-10
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Walls.
|
-- Walls.
|
||||||
for i=0,numwalls-1 do
|
for i=0,numwalls-1 do
|
||||||
if (read_struct(wall[i], mwall[i+1], wall_members, wall_default)) then
|
if (read_struct(wall[i], mwall[i+1], wall_members, wall_default)) then
|
||||||
return RETERR-10
|
return RETERR-11
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Sprites.
|
-- Sprites.
|
||||||
for i=0,numsprites-1 do
|
for i=0,numsprites-1 do
|
||||||
if (read_struct(sprite[i], msprite[i+1], sprite_members, sprite_default)) then
|
if (read_struct(sprite[i], msprite[i+1], sprite_members, sprite_default)) then
|
||||||
return RETERR-11
|
return RETERR-12
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -500,12 +504,12 @@ local function loadboard_maptext(fil, posptr, angptr, cursectnumptr)
|
||||||
|
|
||||||
-- .point2 in {0, 1} --> wall index, sector[].wallptr/.wallnum
|
-- .point2 in {0, 1} --> wall index, sector[].wallptr/.wallnum
|
||||||
if (restore_point2(true)) then
|
if (restore_point2(true)) then
|
||||||
return RETERR-12
|
return RETERR-13
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check .point2 at least.
|
-- Check .point2 at least.
|
||||||
if (check_bad_point2()) then
|
if (check_bad_point2()) then
|
||||||
return RETERR-13
|
return RETERR-14
|
||||||
end
|
end
|
||||||
|
|
||||||
-- wall[]: .nextsector calculated by using engine's sectorofwall_noquick()
|
-- wall[]: .nextsector calculated by using engine's sectorofwall_noquick()
|
||||||
|
|
|
@ -432,8 +432,10 @@ function on.actor_end(pos, usertype, tsamm, codetab)
|
||||||
g_code.actor[tilenum] = codetab
|
g_code.actor[tilenum] = codetab
|
||||||
end
|
end
|
||||||
|
|
||||||
local BAD_ID_CHARS0 = "_/\\*?" -- allowed 1st identifier chars
|
-- NOTE: in C-CON, the slash and backslash can also be part of an identifier,
|
||||||
local BAD_ID_CHARS1 = "_/\\*-+?" -- allowed following identifier chars
|
-- but this is likely to support file names in other places.
|
||||||
|
local BAD_ID_CHARS0 = "_*?" -- allowed 1st identifier chars
|
||||||
|
local BAD_ID_CHARS1 = "_*-+?" -- allowed following identifier chars
|
||||||
|
|
||||||
local function truetab(tab)
|
local function truetab(tab)
|
||||||
local ttab = {}
|
local ttab = {}
|
||||||
|
@ -879,7 +881,7 @@ local function do_include_file(dirname, filename, isroot)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- As a last resort, try the "default directory"
|
-- As a last resort, try the "default directory"
|
||||||
if (fd==nil and g_defaultDir) then
|
if (fd==nil and not isroot and g_defaultDir) then
|
||||||
-- strip up to and including last slash (if any):
|
-- strip up to and including last slash (if any):
|
||||||
filename = filename:gsub("^.*/", "")
|
filename = filename:gsub("^.*/", "")
|
||||||
dirname = g_defaultDir.."/"
|
dirname = g_defaultDir.."/"
|
||||||
|
|
Loading…
Reference in a new issue