The regular division symbol always converts its arguments to floating
point before dividing, similar to how integer division converts its
arguments to integers before dividing.
Multiplication wasn't using the ParseNum helper methods and as a result
wasn't setting num.ui, resulting in the wrong answer when using
unsigned.
I additionally switch it to use the proper signed vs unsigned type when
doing the multiplication.
This moves the CONST replacement up before we turn the elements into a
single string. The advantage is that we don't have to worry about
splitting the string properly to find the CONST names as the elements
are already split for us.t
Fix to CONST with the math evaluator to toss a message and error with values out of acceptable range for ARCSEC and ARCCSC.
Tweak to _PI to add constexpr for speedier execution.
Fix to the math tests for the new (and unbuggy) values for ARCSEC and ARCCSC.
Currently the Keyboard _Devices entry on Windows does not report all the
key presses and releases. This is due to missing some messages in the
form of WM_SYSKEYDOWN and WM_SYSKEYUP. Additionally Windows is weird
about report the state of the individual shift keys, so we add some
logic using GetAsyncKeyState() to fix that up.
Fixes: #333
.so files can be stripped such that they contain no "regular" symbol
table but do still contain the "dynamic" symbol table, this is pretty
typical for .so files. QB64-PE is supposed to check both tables when
linking against a .so file, but a bug in ab0c2b18 meant that the second
run of nm with the -D flag to check the dynamic symbol table no longer
happens. The fix is to introduce a new output file for the dynamic run
so that they are handled separately in terms of caching the result.
A new test .so file that only contains a dynamic symbol table was added
to avoid this in the future.
Fixes: #301
Current the -o flag will strip any "extension" on the provided filename,
which is fairly problimatic on Linux and Mac OS since those executes do
not have other extensions and names like "foobar.v1" will get the ".v1"
stripped off. This can happen on Windows as well if you leave off the
.exe (QB64-PE will add it for you, but also strip off the existing
extension).
QB64-PE stripping off the ".exe" when provided that on Linux and Mac OS
might actually be useful behavior people are relying on (so that they
don't need to provide different names when compiling on Linux/Mac OS) so
we are preserving that and still removing the extension if it is exactly
"EXE", otherwise we now leave it in place.
Fixes: #297
The new optional arguments for functions broke _RGB32() because it uses
some custom flags ('overloaded' and 'minargs' on the id Type) to control
its parameter passing. You are allowed passing any number from 1 to 4 args
to `func__rgb32` and there are 4 overloaded C++ functions that will get
picked from. This is different from how this typically would work, with
all 4 parameters always passed and an extra argument to specify the
parameters that were passed.
Rather than change `func__rgb32` I simply adjusted the optional argument
logic to account for the flags used by `_RGB32()` - if the `overloaded`
flag is set, then we don't need to add extra `NULL` parameters for any
parameter that wasn't specified in the argument list. Instead we simply
don't emit anything for those.
Currently functions only have very limited optional argument support,
this expands it so that we can have more complex sets of optional
arguments for functions, such as multiple arguments where not all need
to be provided. This will be used in the future for some upcoming
functionality.
Note that this does not support any generic optional argument format,
the commas always have to be provided unless an optional argument is at
the end of the parameter list. Thus, if you have a format with two
optional arguments and you want to omit the second, then you need to call
it as 'foo(2, , 3)`, rather than `foo(2, 3)`. This is important for
avoiding ambiguous situations, and is how many SUBs currently function.
The two functions that violate that requirement are INSTR() and
_INSTRREV(), which use the format `[?],?,?` and allow omitting the comma
for the first argument. This format is simply handled as a special case.
Fixes: #303
If a timer expires while stopped, it should trigger when TIMER ON is
run. Instead, on QB64 it triggers randomly after the TIMER ON happens.
The basic issue is that `qbevent` needs to be set to trigger the timer,
but TIMER ON doesn't do that. The regular timer logic that does that
already set it when the timer expired while sleeping, so it won't set it
again. The simplest solution is to just alway set qbevent = 1 when TIMER
ON is done. It's slightly less efficent but doesn't hurt to set it even
when there are no timers that expired.
Fixes: #293
The command Sleep is supposed to allow timers to trigger while the
program is sleeping on the delay. This is achieved in QB64 by having
commands that do delays manually call evnt() to trigger events if they
come up (of which timers are one).
Sleep has a custom implementation for console programs on Windows which
doesn't do this, so I redid the logic so that it calls evnt() at regular
intervals while waiting for input. Additionally, due to now calling
evnt() we also need to check if we should exit sleep early due to an
evnt() firing.
Fixes: #294
Currently main() includes logic that is intended to sync time() with
GetTicks() for the purpose of using GetTicks() to get millisecond
accuracy with time(), which only has second accuracy. Unfortunately, the
'syncing' up of these time sources results in an average of a half
second delay in starting a QB64-PE program.
This logic is easly replaced with std::chrono, which provides a real
time clock which is also millisecond accurate. That removes the need to
use time() and GetTicks() together to get millisecond accuracy, and
means the delay syncing them is no longer necessary.
I also separated most of the "delay" and "time" related functions into
datetime.cpp, and included the new std::chrono code into that file.
Since I needed to call some of the rounding functions in datetime.cpp I
also moved that stuff out into its own .cpp and header files to clean
things up a bit.
Fixes: #282
These tests cover all the commands that generally interact with GLUT.
The ensure that these functions can be used at the very beginning of a
program with no issues. Additionally they verify the behavior of these
functions in the presence of `$SCREENHIDE`, and also `_ScreenHide`.