This commits covers a single class of string-copy
issues, all of which involve writing an unchecked
quantity of bytes into a string of a fixed length (ie:
char[]).
Two notable changes:
1. Eliminates the joystick setup from SDLmain, allowing
the mapper's QueryJoysticks() function to be the sole
setup and configuration point for both the SDL Joystick
subsystem and DOSBox's internal configuration of the
joysticks.
2. SDLmain's event loop previously perform some joystick-
specific timing and always called the Mapper's UpdateJoysticks
function; neither of which are needed if the user has disabled
joystick support or if joysticks aren't physically present.
This update now make this entire process conditional on both
of the latter (which is set by the Mapper's QueryJoysticks).
Windows and macOS config files are left as they were, this change
affects mostly Linux users.
Users are not forced to migrate, but visible warning is being issued if
they aren't. Majority of users probably won't notice it, as the stable
release should generate newly named .conf file.
The host_read*, and host_write* functions currently rely on
casting unaligned memory to translate from byte arrays into
higher-level types (like 16and 32bit ints), however this
approach is implementation specific, can cause undefined
behavior, and forces the compiler to use less efficient
aliasing rules.
Unaligned memory casts have historically been corrected by
expanding multi-byte types into their constituents bytes,
shifting them, and re-packing. They've also been solved using
union objects to access the same underlying memory for each
member (legal under C, but not C++). However, we use memcpy
which is compact, readable, universally compatible, and
compiles down efficient inline single-instructions; therefore
imparting no penalty.
This commit adds host_add* functions (for 16 and 32bit values)
that add a host-formatted value to the implied value at a
memory address.
This commit adds handling for quad-words as well: host_readq,
host_writeq, which we use in the cache, which otherwise suffers
from the same alignment issues.
AUTOTYPE performs scripted keyboard entry into the running
DOS program.
It can be used to reliably skip intros, answer Q&A style questions
that some games ask on startup, or conduct a simple demo.
It allows for delaying input by any number of fractional seconds,
as well defining the pacing between keystrokes. It uses the
comma character "," to insert additional delays similar to modern
phone numbers.
It uses key_* names as defined by the mapper to avoid using SDL
scancodes[1], which are unstable across platforms. This approach
also allows the triggering of custom key bindings the use has
defined.
[1] https://wiki.libsdl.org/SDL_GetScancodeName
"Warning: The returned name is by design not stable across
platforms, e.g. the name for SDL_SCANCODE_LGUI is "Left GUI" under
Linux but "Left Windows" under Microsoft Windows, and some
scancodes like SDL_SCANCODE_NONUSBACKSLASH don't have any name at
all. There are even scancodes that share names, e.g.
SDL_SCANCODE_RETURN and SDL_SCANCODE_RETURN2 (both called
"Return"). This function is therefore unsuitable for creating a
stable cross-platform two-way mapping between strings and
scancodes."
This allows us to show a warning to the user if the .conf file includes
a property that is no longer supported, or a property that is completely
unknown. Actual handling of the property can still be implemented
(e.g. to use as a fallback for modern replacement), but doesn't need
to be.
Usually, when window is being created without SDL_WINDOW_OPENGL flag,
SDL2 internally re-creates it to support OpenGL during
SDL_CreateRenderer if needed.
This leads to crash in AMD OpenGL drivers (Windows only), which happens
for drivers: "opengl", "opengles", "opengles2".
When the window is created with correct flag from the get-go, the crash
does not happen.
On Linux, the code does not crash either way (at least not when using
Mesa and AMDGPU open source driver), so there's no point in propagating
the hack.
Also, remove a comment that is no longer relevant to the code below.
Usage of this function depends on the state of global sdl struct; and
it's very easy to make a mistake - documentation should lower this risk.
Change the type of output parameter 'pitch' and assure type safety with
internal SDL types via static asserts.
This used to have meaning for Windows 9x support via SDL 1.2; the issue
described in README was never mentioned in the context of SDL2.
Add missing include to video header while we're at it.
In an earlier change, I removed appending newline outside of batch mode
in DOS shell code - that made DOSBox behave less like MS-DOS and more
like modern shells, that do not try to compensate for buggy
applications.
However, we should recognize that DOSBox (unlike e.g. FreeDOS) is designed
to run legacy applications, which might make assumptions about DOS
implementation. Some examples:
- PC Player Benchmark assumes, that help commands are displayed exactly
at 80x25 terminal and formats the output to fill the whole screen
(scrolling past DOS4GW messages).
- Quake and other ID games print shareware information on exit, but do
it via a direct memory dump (not interrupts to print DOS text), and
follow up with setting cursor exactly at line 22 (which is partly
written already), expecting shell to inject newline.
- PCC Compiler prints status message on exit without newline, depending
on MS-DOS shell behaviour.
- TEXTUTIL set of external commands do not print nothing to standard
output, and are designed to clear the screen, therefore writing a
newline after .COM commands would be a mistake.
Therefore we want to inject this newline, but not in every case.
New implementation reuses a static variable used by Program base class
(for purpose of translating UNIX newlines to DOS newlines) for detection
if it's appropriate to inject an additional newline or not.
Injecting the newline happens in function displaying the DOS prompt (so
we don't need to write additonal logic for separately handling batch
mode). When starting a non-COM, non-internal command the static variable
is set to the state indicating that next DOS prompt should inject the
newline.
Fixes: #208
The new output type `texturepp' was added, which implements
pixel-perfect scaling using SDL's hardware-accelerated texture output.
In pixel-pefect mode, each original pixel is displayed as a rectangle m
by n pixels, so that m:n yields a reasonably good approximation of the
pixel aspect ratio (PAR) of the emulated graphical mode while using as
much screen space as possible. The balance between the precision of
aspect ratio and the utilisation of screen space is specified as the
`parweight' parameter to pp_getscale() and is currently hard-coded in
sdlmain.cpp.
This implementation emulatates pixel-perfect mode as a special case of
nearest-neighbor interpolation when the horisontal and vertical scaling
factors are integers.
Many parts of the code (especially audio) deal with discrete integer
(and always-positive) values that need to be scaled up or down by
some divisor. This functions provides a fast and an easy way to
divide and round up, while avoiding the CPU burden and excessive
wordiness associated with casting to and from floating point and
back to integer again.
1. Moves the mutex and mixer channel members to unique pointers
2. Moves the trackFile to a weak pointer
3. Move member initialization to the class definition
This class still retains a raw *cd member, however fixing this
ripples up to the array of [26] CD images, and across more
code that generically deals with mount points; so this work
remains to do.
Function fileno is available in POSIX environment out of the box. On
non-POSIX platforms, it might be missing in some cases when compiling
with -std=c++11, as it's outside of strict ANSI compatibility.
Many DOS games open all their files in write-mode regardless if the
game actually intends to write to them or not.
This can result the files' metadata being updated (lossing the
original date-stamp) as well as putting the file at-risk of
corruption if the game crashes with the file open for writing.
Under the existing DOSBox implementation, if a user attempts to
write-protect their data files then DOSBox will quit with an error in
the above scenario.
This commit allows the use of write-protected files (similar to
running a game from CDROM) and indicates which files are being
actively protected against modification.
Typically the only files that need to be left writable are those that
the game actually changes, such as: save-game files, highscore
files, in-game settings, and so on. If these are also protected,
then the game will quit/crash immediately after the protected message
is printed, and thus indicate which file require write-allowance.
This code made silent assumption that first fields in direntry are
exactly 14 bytes - this was fine, except would break as soon as anyone
would touch the struct (or e.g. if a compiler would lack support for
packed structures and inject some padding in there); rewrite the copy
code to follow the same pattern as other fields - now the code will be
fine even if someone will change fields in the direntry struct.
Fixes 2 PVS static analysis issues (buffer underflow on src and dst).