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.
// 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).
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
// 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
// would still leave the lower left and upper right points
// "outside" the sector.

View file

@ -313,12 +313,16 @@ end
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)
check_sprite_idx(i)
check_sector_idx(ffiC.sprite[i].sectnum) -- accessed in A_ShootWithZvel
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)
end
@ -976,7 +980,7 @@ end
function _A_Shoot(i, atwith)
check_sprite_idx(i)
check_tile_idx(atwith)
return CF.A_ShootWithZvel(i, atwith, 0x80000000) -- SHOOT_HARDCODED_ZVEL
return CF.A_ShootWithZvel(i, atwith, SHOOT_HARDCODED_ZVEL)
end
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
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
1. Assignments to _`u8`_ member `visibility`
* `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`.
`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.
`bf:test(bits)`::
@ -791,7 +799,7 @@ is undefined.
===== `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
horizontal and vertical texel sizes of each tile.
@ -943,6 +951,9 @@ Extended API (Lunatic modules)
The `xmath` module
~~~~~~~~~~~~~~~~~~
Mathematical functions
^^^^^^^^^^^^^^^^^^^^^^
Lunatic, being a Lua-based scripting system, provides the user with a single
numeric data type that variables can contain on the Lua side --
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
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
writing concise and clear code involving geometrical calculations. There are
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
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
following, they are only described for `vec3`. The conventions for `ivec3` are
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.
`a*v`, {nbsp} `v*a`::
For a scalar number `a`, returns a new `vec3` object whose components are the
product of those of `v`, and `a`.
For a scalar number `a`, returns a new `vec3` object whose components are those
of `v` mutiplied with `a`.
`v/a`::
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`
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
`ivec3`).footnote:[Right-shifting by 4 can be seen as a division by 16, but
with rounding towards negative infinity.] Also see the description of the
ceiling/floor <<cf_z,`z` member>>.
`ivec3`).footnote:[Right-shifting by 4 can be seen as a division by 16 with
subsequent rounding to an integer towards negative infinity.] Also see the
description of the ceiling/floor <<cf_z,`z` member>>.
`v:tobuild()`::
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 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 BAR1x5 = 3163
@ -48,15 +66,3 @@ local function rotatesprite_test()
end
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"