ultimately, cargo workspaces are kind of weird. you can do things like
`cargo run` from the top-level cargo.toml file and run an individual
sub-module via `--bin`, or you can go to that sub-module's directory
where it's own cargo.toml is, and `cargo run` directly from there.
the current working directory will be different in each case, and this
difference can be very annoying when you want to do seemingly-logical
things like organize sub-module "asset" files (e.g. images, and other
types of data files that aren't code) within that sub-module's
directory. in this case, how do you write code in that sub-module that
can load those asset files in a way that will work in BOTH of the
aforementioned scenarios for `cargo run`?
you can't really! some people use the `CARGO_MANIFEST_DIR` environment
variable that cargo sets when running any given cargo module, but this
is only a valid method for obtaining the module's root directory when
running from a cargo command ... which you won't be doing when running
within a debugger! likely you or your IDE invoked the debugger process
against the already built executable directly, so `CARGO_MANIFEST_DIR`
will not be set and you're back to square one!
super annoying!
as such, i am now giving up and am just doing what it seems like most
other cargo projects that utilize workspaces do ... place all the
assets for all sub-modules together in the same directory, relative
to the workspace root.
why go with this approach?
because it works under the most common scenarios (but NOT all!):
- running via `cargo run --bin` from the workspace root
- debugging via gdb/lldb etc using the workspace root as the cwd
these seem to be the most common ways to do each type of task from
any rust-equipped editor/IDE that i've seen so far.
previously, there were a ton of places that were allocating new Path
instances via `Path::new` for the purpose of creating a path to be
passed into a function as a Path argument
this has now been simplified everywhere by updating all functions
and methods that previously took Path arguments to instead take
AsRef<Path> arguments, allowing much more flexibility in the types
of path arguments passed in
i unfortunately feel like i should really force myself to use rustfmt
even though i very much dislike it. most rust developers seem to use it
so i should probably get used to it ...
however, case-in-point for me is the amount of times i used either
#[rustfmt::skip] or adding a blank `//` comment to force separate
lines, etc, really proves how terrible basing almost all of your
formatting rules on arbitrary length thresholds really is. code
formatting is far more subjective than that.
we'll be introducing variable display size features next, so these
screen dimension compile-time constants are not going to be useful.
the "low_res" and "wide" features were also tied to the idea of
compile-time constants for display sizing so these need to go too,
and will be brought back via runtime configuration
this is an unfortunately large commit. probably should've been broken
up into multiple smaller ones.
i decided to revert some earlier preparatory work i had done to organize
graphics functionality into two main streams: "indexed" and "rgb". this
was going to result in two completely different Bitmap structs which
were going to be largely similar and as i thought about it more, i
realized my earlier thinking that i wouldn't be able to generify the
Bitmap struct based on pixel-depth was actually not correct.
so, this commit re-works things significantly in a way which i think
is better but probably still not perfect. basically, we have one
Bitmap struct which provides a lot of generic functionality, but also
specialized implementations based on pixel-depth and this is now what is
separated out into graphics::bitmap::indexed and graphics::bitmap::rgb.
but the rest of the graphics functionality is not separated out by
module like this any longer.
note that i've still kept the GeneralBitmap trait and implementations.
i was originally thinking i could get rid of this since i'd now made
Bitmap generic over pixel-depth, but doing so would require me to
rename the common/general blit methods to avoid a name collision with
the specialized implementations (since they would both exist on the
same types now). and i did not like that. i dunno, maybe i will change
my mind later.
though i am not sure how good an idea my approach was with a bunch of
intermediate preludes. i was thinking it might be nice to be able to
only pick out the preludes that you wanted (if not all), but ... would
i ever really need to do that? somehow i am thinking, no, but i will
give it some more thought
this also includes a semi-important change where the existing
BitmaskCharacter draw implementation will now not draw anything if
FontRenderOpts::None is passed in, instead of just substituting color 0.
this probably makes more sense this way anyway
since i realized there is an SDL hint that can be used to toggle this
the reason why the rust-sdl "Canvas" struct (which abstracts an
"SDL_Renderer") is not being created in System directly (which would
allow vsync to be toggled on/off via System directly without the use of
a hint) is because not all future SystemResource implementations will
need it (e.g. a future OpenGL implementation definitely won't).
System now uses a generic SystemResources structure to provide video,
audio and input devices
the DosLike implementation of SystemResources provides the same
functionality that this library has had to date.
this change is to prepare for future addition of things like 32-bit
Bitmap support and other possible audio device implementations, etc.
the idea is a custom SystemResources implementation can be substituted
in to configure everything with the desired functionality.
note that i'm intentionally not using rustfmt. i've tried to like that
tool, but in the end i just really don't like it. too many edge cases
and subjectivity and not enough customization. which is probably the
intent. which makes me hate it that much more. fuck you, rustfmt.
they all still depend on sdl2 through the libretrogd dependency, but
the benefit is that future sdl2 version updates are much easier to
accomplish for most apps, since only libretrogd needs to be updated
(in theory).
0.35.2 is the latest version available via cargo right now, and that
version has some issues building for me that have been resolved in
subsequent commit(s). for some reason the maintainers have not pushed
a new version of sdl2 to cargo for quite some time despite numerous
fixes and updates being available ...? bah!
also the current sdl2 `features` set will probably only work for linux
builds. i will try to work out windows + mac build issues shortly
due to encountering some compile errors on a fresh system which pulled
down the newest minor versions of both. these two libraries do not seem
to follow "good" semantic versioning ... ? ugh. will try to work out
the compiler issues with the latest versions of these later ...
i think i prefer this style. it's not _technically_ as safe as it was
before, but i prefer the explicitness of it (and it results in a little
bit less nesting in system functions which is nice).
i don't much like the need for an explicit `unwrap()` call however
but that's the tradeoff!