Lunatic: don't pass 0x80000000 to int32_t arg, document xmath functions.

git-svn-id: https://svn.eduke32.com/eduke32@3906 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2013-06-28 14:07:33 +00:00
parent 2f883eaed1
commit 89d865b8b1
4 changed files with 89 additions and 27 deletions

View file

@ -11408,7 +11408,7 @@ int32_t inside(int32_t x, int32_t y, int16_t sectnum)
// //
// [*] where '-' corresponds to <0 and '+' corresponds to >=0. // [*] where '-' corresponds to <0 and '+' corresponds to >=0.
// Equivalently, the branch is taken iff // Equivalently, the branch is taken iff
// y1 != y2 AND y_m <= wal->y < y_M, // y1 != y2 AND y_m <= y < y_M,
// where y_m := min(y1, y2) and y_M := max(y1, y2). // where y_m := min(y1, y2) and y_M := max(y1, y2).
if ((y1^y2) < 0) if ((y1^y2) < 0)
{ {
@ -11423,7 +11423,7 @@ int32_t inside(int32_t x, int32_t y, int16_t sectnum)
// Now, do the same comparisons, but with the interval half-open on // Now, do the same comparisons, but with the interval half-open on
// the other side! That is, take the branch iff // the other side! That is, take the branch iff
// y1 != y2 AND y_m < wal->y <= y_M, // y1 != y2 AND y_m < y <= y_M,
// For a rectangular sector, without EXACTLY_ON_WALL_POINT, this // For a rectangular sector, without EXACTLY_ON_WALL_POINT, this
// would still leave the lower left and upper right points // would still leave the lower left and upper right points
// "outside" the sector. // "outside" the sector.

View file

@ -313,12 +313,16 @@ end
local int16_st = ffi.typeof "struct { int16_t s; }" local int16_st = ffi.typeof "struct { int16_t s; }"
-- Get INT32_MIN for the following constant; passing 0x80000000 would be
-- out of the range for an int32_t and thus undefined behavior!
local SHOOT_HARDCODED_ZVEL = bit.tobit(0x80000000)
function _shoot(i, tilenum, zvel) function _shoot(i, tilenum, zvel)
check_sprite_idx(i) check_sprite_idx(i)
check_sector_idx(ffiC.sprite[i].sectnum) -- accessed in A_ShootWithZvel check_sector_idx(ffiC.sprite[i].sectnum) -- accessed in A_ShootWithZvel
check_tile_idx(tilenum) check_tile_idx(tilenum)
zvel = zvel and int16_st(zvel).s or 0x80000000 -- SHOOT_HARDCODED_ZVEL zvel = zvel and int16_st(zvel).s or SHOOT_HARDCODED_ZVEL
return CF.A_ShootWithZvel(i, tilenum, zvel) return CF.A_ShootWithZvel(i, tilenum, zvel)
end end
@ -976,7 +980,7 @@ end
function _A_Shoot(i, atwith) function _A_Shoot(i, atwith)
check_sprite_idx(i) check_sprite_idx(i)
check_tile_idx(atwith) check_tile_idx(atwith)
return CF.A_ShootWithZvel(i, atwith, 0x80000000) -- SHOOT_HARDCODED_ZVEL return CF.A_ShootWithZvel(i, atwith, SHOOT_HARDCODED_ZVEL)
end end
function _A_IncurDamage(sn) function _A_IncurDamage(sn)

View file

@ -368,6 +368,14 @@ number from 0 to 2^_B_^--1.
successively adding or subtracting 2^B^, until the value falls inside that successively adding or subtracting 2^B^, until the value falls inside that
range. range.
//////////
NOTE to self: this is stricter than C99 (which has first truncation, then range
check). Also, it may be tempting to assign 0x80000000 to an int32_t to mean
INT32_MIN, but this is wrong because it's out of range.
Also see:
http://lua-users.org/lists/lua-l/2011-09/msg00534.html
//////////
.Examples .Examples
1. Assignments to _`u8`_ member `visibility` 1. Assignments to _`u8`_ member `visibility`
* `sec.visibility=3.94159` results the member to contain the integer `3` * `sec.visibility=3.94159` results the member to contain the integer `3`
@ -402,7 +410,7 @@ _Clears_ (toggles to an ``off'' state in a boolean sense) those bits of `bf`
that are set in `bits`. that are set in `bits`.
`bf:flip(bits)`:: `bf:flip(bits)`::
_Flips_ those bits of `bf` that are set in `bits`, that is, reverse their _Flips_ those bits of `bf` that are set in `bits`, that is, reverses their
boolean state. boolean state.
`bf:test(bits)`:: `bf:test(bits)`::
@ -791,7 +799,7 @@ is undefined.
===== `g_tile` static data ===== `g_tile` static data
`g_tile.sizx`, `g_tile.sizy`:: `g_tile.sizx`, {nbsp} `g_tile.sizy`::
Arrays indexable with tile numbers [`0` .. `gv.MAXTILES-1`] that hold the Arrays indexable with tile numbers [`0` .. `gv.MAXTILES-1`] that hold the
horizontal and vertical texel sizes of each tile. horizontal and vertical texel sizes of each tile.
@ -943,6 +951,9 @@ Extended API (Lunatic modules)
The `xmath` module The `xmath` module
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
Mathematical functions
^^^^^^^^^^^^^^^^^^^^^^
Lunatic, being a Lua-based scripting system, provides the user with a single Lunatic, being a Lua-based scripting system, provides the user with a single
numeric data type that variables can contain on the Lua side -- numeric data type that variables can contain on the Lua side --
double-precision floating point.footnote:[In LuaJIT, variables additionaly can double-precision floating point.footnote:[In LuaJIT, variables additionaly can
@ -952,6 +963,51 @@ exclusively use integer types to represent quantities such as angles or carry
out e.g. trigonometrical calculations, there is a need for convenient out e.g. trigonometrical calculations, there is a need for convenient
interoperability between the two ``worlds''. interoperability between the two ``worlds''.
Two pairs of functions calculate the trigonometric sine and cosine, both
accepting a BUILD angle as input argument, but differing in the scaling of
their result. Using these functions is recommended over Lua's `math.sin` or
`math.cos` in cases where the argument is a BUILD angle in the first place, for
example because it is read from an engine or game structure. The computation is
both faster (because it is essentially only a bitwise-AND operation followed by
a table lookup) and the results have the symmetry expected from the
mathematical counterparts.
`xmath.sinb(bang)`, {nbsp} `xmath.cosb(bang)`::
Returns the sine/cosine of the given BUILD angle `bang`, which can be any
whole number in [--2^31^ .. 2^31^--1]. In BUILD, one full cycle is covered by
values from 0 to 2047; in other words, an angle of 2048 corresponds to 360
degrees.
+
The `sinb` and `cosb` functions return values in the range [--1 .. 1], just
like their mathematical counterparts.
+
The following guarantees are made for `sinb` whereever its argument expression
is permissible:
+
* `sinb(-a) == -sinb(a)` (point symmetry around the origin)
* `sinb(a + i*2048) == sinb(a)`, where `i` is any whole number (periodicity)
* `sinb(1024 - a) == sinb(a)` (mirror symmetry around `a`=512)
* `sinb(a - 1024) == -sinb(a)` (point symmetry around `a`=1024)
* The value for `cosb(a)` is derived as `sinb(a + 512)`.
`xmath.ksin(bang)`, {nbsp} `xmath.kcos(bang)`::
Returns the sine/cosine of the given BUILD angle `bang`, multiplied with 16384
and rounded towards zero. The same guarantees as for the `sinb`/`cosb` pair
apply.
`xmath.dist(pos1, pos2)`::
Returns an approximation of the 3D Euclidean distance between points `pos1` and
`pos2`, both of which can be any object indexable with `x`, `y` and `z`.
<<cf_z,BUILD z units>> are assumed.
`xmath.ldist(pos1, pos2)`::
Returns an approximation of the 2D Euclidean distance between points `pos1` and
`pos2`, both of which can be any object indexable with `x` and `y`.
[[vector_types]]
The types `xmath.vec3` and `xmath.ivec3`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Another purpose of the `xmath` module is to provide _vector_ types that allow Another purpose of the `xmath` module is to provide _vector_ types that allow
writing concise and clear code involving geometrical calculations. There are writing concise and clear code involving geometrical calculations. There are
two types, both containing three components (`x`, `y` and `z`), but differing two types, both containing three components (`x`, `y` and `z`), but differing
@ -961,10 +1017,6 @@ part of some game structures, and consequently uses 32-bit integers for its
components. With minor differences, the `vec3` and `ivec3` types share the same components. With minor differences, the `vec3` and `ivec3` types share the same
operations and methods. operations and methods.
[[vector_types]]
The types `xmath.vec3` and `xmath.ivec3`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The constructors of the vector types can be called in several ways. In the The constructors of the vector types can be called in several ways. In the
following, they are only described for `vec3`. The conventions for `ivec3` are following, they are only described for `vec3`. The conventions for `ivec3` are
completely analogous, but since their creation involves a number type completely analogous, but since their creation involves a number type
@ -1017,8 +1069,8 @@ second case).
Returns a new `vec3` object with the components of `v` negated. Returns a new `vec3` object with the components of `v` negated.
`a*v`, {nbsp} `v*a`:: `a*v`, {nbsp} `v*a`::
For a scalar number `a`, returns a new `vec3` object whose components are the For a scalar number `a`, returns a new `vec3` object whose components are those
product of those of `v`, and `a`. of `v` mutiplied with `a`.
`v/a`:: `v/a`::
For a scalar number `a`, returns a new `vec3` object whose components are those For a scalar number `a`, returns a new `vec3` object whose components are those
@ -1062,9 +1114,9 @@ Returns a new `ivec3` object with the same components as `v`, but converted
Returns a new vector of the same type as `v` which has the same `x` and `y` Returns a new vector of the same type as `v` which has the same `x` and `y`
components as `v`, but the `z` element divided by 16 (if `v` is a `vec3`) or components as `v`, but the `z` element divided by 16 (if `v` is a `vec3`) or
arithmetically right-shifted by 4 (if `v` is an arithmetically right-shifted by 4 (if `v` is an
`ivec3`).footnote:[Right-shifting by 4 can be seen as a division by 16, but `ivec3`).footnote:[Right-shifting by 4 can be seen as a division by 16 with
with rounding towards negative infinity.] Also see the description of the subsequent rounding to an integer towards negative infinity.] Also see the
ceiling/floor <<cf_z,`z` member>>. description of the ceiling/floor <<cf_z,`z` member>>.
`v:tobuild()`:: `v:tobuild()`::
Returns a new vector of the same type as `v` which has the same `x` and `y` Returns a new vector of the same type as `v` which has the same `x` and `y`

View file

@ -6,6 +6,24 @@ local math = require("math")
local rs = con.rotatesprite local rs = con.rotatesprite
local gameevent = gameevent
local gv = gv
local player = player
module(...) --====================
test_gamevar = 123
local a_local_gamevar = "yes, this one too"
test_gamevar2 = 'qwe'
require "end_gamevars" --==========
not_a_gamevar = "no"
local DOT1x5 = 3135 local DOT1x5 = 3135
local BAR1x5 = 3163 local BAR1x5 = 3163
@ -48,15 +66,3 @@ local function rotatesprite_test()
end end
gameevent{gv.EVENT_DISPLAYREST, rotatesprite_test} gameevent{gv.EVENT_DISPLAYREST, rotatesprite_test}
module(...) --====================
local not_a_gamevar = "nyet"
test_gamevar = 123
test_gamevar2 = 'qwe'
require "end_gamevars" --==========
not_a_gamevar2 = "no"