Quick C++/SFML Tips

While I’m writing a series on working with SFML and C++, I thought I’d share some quick dirty tips for working with SFML that I’ve experienced lately. Some of these emerged while branching out to other development contexts that I’m normally not entrenched in – so you’ll forgive me if they seem axiomatic to you – and others simply failed to make the transition from mind to paper (or screen in this case).

Getting Started with SFML and Visual Studio

It’s evident after seeing some posts on the SFML forums that people don’t RTFM. TL;DR isn’t a thing to worry about here, so be sure to check this page (linked below) out. Visual Studio doesn’t require counter-intuitive thought concerning environment configurations – a compiler is a compiler – but the way one configures the compiler is measurably convoluted, especially if you’re used to programming in the Linux world. These steps are also valid if you’re considering creating a DLL to leverage shared code.

SFML on Visual Studio – https://www.sfml-dev.org/tutorials/2.5/start-vc.php

DLL Woes

Speaking of creating DLLs, there’s a nasty little caveat with the default Windows header file. Evidently the versions of the min and max functions implemented in it are grossly incompatible with the ones in STL. While not a SFML issue per-se, it’s important to be aware of because it’ll likely creep in when you least expect it, and trying to determine what the root cause is from the output of the compiler is going to require several witchdoctors and an irrefutable, globally-accepted proof of String Theory. The red herring for this typically comes in the form of error C2589: ‘(‘ illegal token on right side of ‘::’ (a.k.a. The go f-yourself error).

The fix for this is the NOMINMAX preprocessor directive. You can either add it as a file-level define at the head of the file, or you can use the Project Properties dialog and add it to All Configurations and All Platforms by navigating to C/C++->Preprocessor, and appending the NOMINMAX option to the Preprocessor Definitions field. If ever you come back to this dialog to ensure that the value was set, you’ll need to drill-down into each configuration and platform to see that the value was applied.

Deleted Copy Constructors, sf::NonCopyable

A core component of a game engine that I wrote has an Asset Manager that’s very similar to the one used in MonoGame, except that it doesn’t use the Pipeline concept. Assets are loaded into memory via PhysicsFS, and they’re translated into SFML Asset Constructs that are stored in a STL Container, specifically std::unordered_map. Some SFML Asset Constructs, specifically sf::Music, inherit from classes that leverage sf::Thread, and, of crucial note, sf::Thread inherits from sf::NonCopyable. While this utility class doesn’t explicitly delete the copy constructor and assignment operators, it marks them as private. Children of this class will likely, if you’re using C++11 or greater, have these functions implicitly deleted since they’re not valid. In the absence of STL Containers, this isn’t too much of an issue, especially since attempts at copies or assignments would result from explicit statements that you yourself wrote. When STL Containers are around and you encounter an error from implicitly deleted function calls, we’ve traipsed into another arena where compiler output is infamously horrid to the degree of being near useless.

To give some concrete to my exposition, the offending statement was this:

...
typedef sf::Music sfmusic;
typedef std::unordered_map < std::string, sfmusic > ab_bgm;
...

std::unordered_map leverages std::pair to join the key to the value, and while I haven’t been able to dissect the issue deeper than this, it would appear that std::pair is likely subsuming the lifecycle of the objects it contains. Because there is no copy constructor or assignment operator for an object that inherits from sf::Thread, and because std::pair is attempting to leverage either one of those functions in some way, the latter is going to throw up in the most flamboyant of ways.

Although what’s next is likely not a representation of a clean or efficient way to mitigate this, I’ve found that it works. For starters, the declaration changes slightly:

...
typedef sf::Music sfmusic;
typedef std::unordered_map < std::string, sfmusic* > ab_bgm;
...

Next, the member function of the Asset Manager that is responsible for copying the asset data from raw bytes into live SFML Asset Constructs takes an extra step of manually allocating the memory for it before using the sf::Music copyFromMemory function:

...
case targetloader::bgm:
    bgmb [file] = new sfmusic ();
    bgmb [file]->openFromMemory (d, f.length ());
...

Of course, because we’re now wandering down the path of explicit memory allocations, we’ve got to be responsible for cleaning it up, so the intermediate destructor does some work to delete allocations in this bank, if there were any, before removing the bank itself.

 

*NOW CLOSED* – Feline Philanthropy

NOTE – This campaign has ended as the stretch goals have been met. Thank you to everyone who donated.

Not too long ago, my sister had taken responsibility for an outside cat. Being a fanatical animal lover, she quickly worked into her daily routine a regimen of feeding and playing with this furry friend. Affectionately, he was dubbed Dartanyin and his place in her heart was forever cemented.

Ultimately, her goal is to take Dantanyin in to care for him properly. To bring him in off the streets, away from the vicissitudes of whimsical or indifferent passerbys, and to provide for him the love and care that he needs. Yet she is at a disadvantage and needs some help.

29496736_15250470530_updates

As we all know, college students happen to be strapped for liquid capital, and my sister’s case is no exception to this rule. A local shelter near us is requiring around $160 to perform all of the necessary tests and operations to ensure Dartanyin’s health. She has resorted to crowd-funding to help finance these procedures, and is appealing to anyone with no more than $5 to spare to donate. I would see that this request is propagated through myself as well, hence the purpose of this post.

If you are an animal lover, you understand completely where my sister is at emotionally. Furthermore, with the comedic array of initiatives that manage to get backed in excess through crowd-funding, this hardly qualifies as something not worthwhile. Any donation that you could offer would go a long way in helping a cat get a home – taking it off the streets, a boon for a miltutide of reasons – and bringing a person and an animal closer together.

Please take the time to view the GoFundMe page here: https://www.gofundme.com/this-handsome-guy-needs-our-help

Thank you for your time, and potentially for your help.

RHEL/CentOS – Configuring a Local Repository Server

I haven’t made a decent technology post in some time, let alone one about my beloved Linux. To rectify that travesty, this post comes at a time to end said drought and to share with my Linux friends how to accomplish the goal outlined by the title. I do often see a fair number of questions as to how to get a local repository setup, but the contexts always vary a little by virtue of distribution as well as delivery mechanism. The objective here is to get up and running with as little hassle as possible. Our target distribution will be RHEL/CentOS 7 with delivery facilitated via FTP.

Getting right to it, there are six key points we need to address:

  1. Configuration of the FTP server
  2. Location for the software packages that will compose the repository(-ies)
  3. Creation of the repository metadata
  4. Firewall configuration
  5. SELinux configuration
  6. Exposure

FTP Server

Both RHEL and CentOS will by default install vsftpd as the FTP server of choice. This can be installed during the package selection phase of Anaconda by first selecting the Infrastructure Server profile and then the FTP Server group. You can install several other groups as well, but we only focus on this one here. Please note that if you intend on using another FTP package, you’ll want to skip some parts of this tutorial since it’s assumed that you are going to use vsftpd. If during the installation process you fail to install this package, simply install it post-installation with yum:

yum install vsftpd

The nice thing about installing it from Anaconda is that the default vsftpd configuration file (/etc/vsftpd/vsftpd.conf) is geared toward a public anonymous context with maybe only some slight modifications being required. Removing all of the comments from the file for brevity, these are the options that are used on the server I’ve configured:

anonymous_enable=YES
local_enable=YES
write_enable=NO
local_umask=022
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
listen=YES
listen_ipv6=NO
pam_service_name=vsftpd
tcp_wrappers=YES

If you have to make any changes to this file, be sure to restart the daemon after writing said changes:

systemctl restart vsftpd

File Location

The repository files will be kept in a custom location, not in /var/ftp/pub – the default landing directory for anonymous. For this example, the files will be stored in /opt/repos. This will make it easier if we want to have multiple repositories on the same server. In other words, we could have a directory for the base CentOS packages – copied from the resource DVD – and custom packages for your company under another directory. Hypothetically, this leaves us with the following directory structures:

/opt/repos/centos/7/dvd/packages
/opt/repos/company/packages

Finally, you’ll want to change the permissions for the /opt/repos directory and its contents:

chmod -R 755 /opt/repos

Create Repositories

Next you’ll want to populate your newly created directory structures with the packages that will comprise the repository. Keeping with our example directories, the first will need to be copied from the CentOS Resource DVD. This can be accomplished by mounting the ISO/DVD and copying everything out of the Packages directory in the root of the mount. If you have them stored somewhere else, you’ll need to get them onto the server by other means (SCP, NFS, SMB, etc…). The same principle applies for the custom packages that you’ll be putting in the second directory. Ultimately, your storage and security strategy will dictate where the files are actually stored at and how they’re placed in those two aforementioned directories.

If you haven’t done so already, you’ll want to install the createrepo package. This package will automate the creation of the metafiles required for both identifying and advertising the manifest of a repository. Once you have the package installed, you’ll want to use it to create the repository for each of these directories. Createrepo takes a path as an argument. It also takes other options, but for this example, it’s satisfactory enough to omit them and provide only the directory. When you do this, do not inlcude the packages portion of the path. Instead, you’ll provide the path up to that point. Obviously, your current working directory will determine what you have to provide to createrepo. It’ll most likely look like one of the following forms:

createrepo /opt/repos/centos7/dvd
createrepo .
createrepo ../

Use whichever one you want, so long as the path is correct. The larger the number of packages createrepo has to parse, the longer it’ll take to process. As you might notice, parsing all of the CentOS Resource DVD packages will take some time (there’s almost 10,000 packages).

When you create the repositories in this manner, you’re essentially creating a static repository. If any of the packages in there change, you’ll need to issue a command to createrepo to update the repository manifest. Or you can make createrepo occasionally sync with a mirror, but these configurations are outside the immediate scope of this document.

Once the packages are in place and the repositories created, you’ll need to get them to the point of being exposed by the FTP server. Because the default public anonymous location for vsftpd is /var/ftp/pub, and because vsftpd doesn’t handle following symlinks very well (or not at all), you’ll want to use a bind mount to get the directory over there. The basic gist of a bind mount is to mount a portion of the filesystem to another portion of the filesystem. So if you perform a listing command on /var/ftp/pub prior to the bind mount, you’ll likely get nothing back since that directory doesn’t (or at least shouldn’t) contain anything after a fresh installation. If you perform a bind mount:

mount --bind /opt/repos /var/ftp/pub

and then list directory contents:

ls /var/ftp/pub

you’ll get returned two directories. Note that this doesn’t survive reboots unless you add the mount to fstab:

/opt/repos /var/ftp/pub xfs defaults,bind 0 0

If you don’t do this, don’t be shocked if after a reboot you can’t see anything on your FTP server since the mount will be disconnected.

Firewall Configuration

There’s a pretty good chance that your network interface is going to have the public zone from firewalld applied to it during the installation process. Even so, this zone likely won’t have the FTP server whitelisted, so you’ll need to check to see if it is and react accordingly.

First, check what name was given to the interface (henceforth referred to as ifname). Hopefully, it wasn’t given something unpredictable. You won’t have to do this if you explicitly name your interfaces during installation.

ip addr sh

Once you have the interface name, check to see which zone was applied to it through firewalld (henceforth referred to as zname):

firewall-cmd --get-zone-of-interface=ifname

Now, use this zone name to see what kinds of traffic are permitted or disallowed:

firewall-cmd --zone=zname --list-all

Most likely, if this is the default public zone, you’ll only see the services ssh and dhcpv6-client. The key here though is that if you don’t see ftp in the list of services, you’re going to need to add it.

firewall-cmd --permanent --zone=zname --add-service ftp

If during the initial configuration of vsftpd you elected to run FTP through a non-standard port, you’ll need to make the appropriate accommodations:

firewall-cmd --permanent --zone=zname --add-port port#/protocol

Once that’s done, reload firewalld rules:

firewall-cmd --reload

SELinux Configuration

At this point, you should be able to run an external port scan and see your FTP port open. However, it’s unlikely that you’re going to be able to access your files because of SELinux rules. Even though people hate it, and given too that this is a local server, you may be tempted to shut it off and go about your business. This post encourages that you leave it on and simply reconfigure it to work with your server.

Basically, you’ll need to change the SELinux type on the entire directory structure starting with the root /opt/repos to public_content_t.

chcon -R -t public_content_t /opt/repos

Testing and Exposure

Run a few simple tests before giving the green flag for clients to start consuming your packages. What I’ll usually do is run a port scan with nmap to verify that the FTP port is open, which effectively means that vsftpd is running and listening on that port. Next, I’ll open a browser and navigate to the address of the server with the FTP protocol to see if I can view the contents. You can also test this in two other ways:

  • Install a FTP client on the repository server and attempt to establish a FTP connection to localhost (I don’t recommend this for probably a foolish reason).
  • Use a FTP client on a remote client and attempt to establish a FTP connection to the repository server.

Two really common issues at this point are either access or visibility to the repository contents. If access is an issue, make sure that vsftpd is running on your server and that firewalld is configured to permit ingress/egress traffic for FTP, especially if you’re using a non-standard port for FTP (egress traffic should be open by default, but these require direct rules through firewall-cmd to filter since the principal route of focus for firewalld is ingress). If you’re still having issues, make sure that your clients are configured correctly too (firewall, routing, etc.). Visibility of content can usually be traced back to one of three matters: a bind mount that wasn’t added to fstab (this would cause the mount to be dismounted on restart), incorrect DAC (755 should be sufficient; FTP wants the execute bit set), or incorrect SELinux type. The only other major rub is that if your storage strategy defines that your files are located on a NAS or other file server, you need to ensure that those mounts are established at system start (i.e. remote SMB share is mounted correctly).

To add the repository to a client, you can either package the public data into a RPM and have clients install it (much the same way that RPM Fusion does theirs), or they can manually add it to the listing under /etc/yum.repos.d. The file would look similar to this:

[reponame]
name=Custom Repo
baseurl=ftp://name-or-ip-of-ftp-server/centos
gpgcheck=0

Helpful Links

VSFTPD Online Manpages
Firewalld Homepage
SELinux FTPD
Configuring a Yum Repository File

Snippet from an Untitled Project

The needle pierced the iris of the dream, and from within welled a dithering pointillism of bloody fumes. The lids wiped free a milky haze only to replace itself with a more virulent wash of the scene burnt there before. Two fingers, erected parallel, obstructing vision, press at first gently. Check – no result. Press harder – same effect. Digits pan inward, and the hand violently thrusts backward until the palms are resting on the high cheekbone. Now that the eyes were gouged out, it was no longer important to worry about the fading world before them. But when the full length of the stems had been dislodged from their deposit, sand flowed freely where blood should have. Bodily liquid had been replaced with fine rock, and to free the pressure held back, every orifice secured by skin burst open at the seams and poured forth into the air did the corruption of person stuffs atomize. Left behind was a shadow of a man, engraved into the concrete as if they were too close to the epicentre of a nuclear explosion. 

From the shadow emerged an egg and from the egg arose a dragon. Within time, the dragon matured into an adult beast. Texts of old taught it how to fly, speak, sing, and where it could find others just like it. The flecks of dust that remained where he’d been born evaporated over time, yet on their fringes was caught the scent of a man. Resonating vaguely familiar, all of what could be mustered in memory hinted naught of this dwindling phantom. All the same, said library held little as to the subject of identity. Relying instead on more motor faculties to guide it, the dragon took taste of what sand remained. 

Then, what had been long held as sacred was at once revealed to be nothing more than a fraud. This thing, this man, was judged more putrid and vile than any contagion whose objective was mass extermination. Behind every persona lay a master scheme whose mission was self-maximisation. The degree to which perversion of sociality and sexuality had both permeated and dictated his core was nauseating. All faults considered, there existed a sliver of compassion, unfortunately overshadowed by his hell-pact. 

From this the dragon had sprung, and to preclude its volition did these sins seek. It too harboured a similar capacity – shaded by a different hue – feeling concurrently the desire to masturbate and to sever the hand and mind for treason. The books instructed in one manner, the people operated in another. Birds have wings that they may fly – and fly they do – as people have legs that they may move. When the bird flys, does it not seek expediency for efficiency? Flying longer, while dangerous, is conditionally useful. Why then would man not desire the same conquest? If, as was revealed, some held stay for personalisation in virtually every aspect, then some did desire inefficiency. They begged and pleaded on hands and knees in contaminated soil for absolution, private gain, disequilibrium, judgement, hatred, sadness, joy, food, shoes, all of it to be provided by right of something which they could not comprehend and was consequently pillaged from a poorer soul – deemed so by the same that put them in place to exploit. No harmony was to be found. These people were born to hate. Goodwill itself was a liar looking first to profit, next to mask it. 

Here and there the grass remained the same. Sometimes tainted by drought, other times drowning in blood. None of this stayed the flight of the dragon. Manoeuvring feverishly through the skies, it was hellbent on a single objective: the dissolution of its birthright plague. Only a few times did it stop to tend its own corporeal demands. Each landing was met with a handful of frolicking plebs who danced about in some bizarre ritual, attempting to moot some foregone pact to bring about a tidal shift in their own private affairs. More often than naught, the intended recipient was the dragon, perhaps out of a fear sourced from an empirical size discrepancy. Occasionally, some of the nutters thought to pray to god, despite being within arm’s length of the dragon. Fools, it thought. It had been to the heavens countless times, and never once met with anything other than air which they couldn’t see. If ever there were a god, surely it was a man, for only a god should be so utterly incompetent to create and allow the continuance of such backward creatures. Not that it mattered either way. The dragon cared not of the goings on of man, and it wasn’t about to stick around long enough to see the end of it all. 

Too Many, Too Far

644188_526552814037754_1413004826_n

Reading nonsense such as this has finally provoked within me the urge to unleash a summary of the nearly endless waves of indignation that doubtless follow soon after.

Before continuing, please be sure to read fully the words on this article of clothing, typeset carefully for dramatic effect.

First, we must isolate the demands in the rhetorical conversation above proposed to god, that we may arrive at a better understanding:

  • god, or at least this one being queried, is omnipotent enough to intervene in the affairs of mortal men.
  • god, or at least this one being queried, aside from its omnipotence, has the inclination to intervene in the affairs of mortal men.
  • The kind of affair and its calibre are irrelevant in consideration for intervention.
  • Degrees of presence of this god, either materialistically or otherwise, has a net effect on its ability to intervene, especially in the case of violence in schools.
  • Violence of any kind is bad.
  • Violence within the confines of a school is a particularly heinous breed.
  • The printer of this shirt has had the divine communication revealed, moreso than others it would seem, to have ready a solution to the issue at hand.
  • Hence, if more people would allow freely this god in particular in their schools more often, especially when the word is spread by buying this shirt, that its ability to intervene in horrific incidences of school violence would increase.

Please spare me the easy hunts here as thoughts of those nature will be vanquished immediately.

One should find it obvious, probably as a result of experience, that even if this god in subject did exist and was of the meddlesome kind, the nauseating selectiveness which it elects to employ or bestow upon the people – its people – the requisite number of miracles to produce the safest, happiest, most fulfilling life for all leaves quite a bit to be desired. god’s game, that of arbitrarily halting each person’s life pendulum, has no rhyme or reason. Yet all the wonders of the fallacious mind attempt attribution upon attribution, founding these claims on little more than simple or seemingly sophisticated rumours and fancies, none of which are or can be rooted by rationality or reason. We should rest assured that if this god were as invested in our goings-ons as one becomes enthralled by reality television, and it desired an alternative outcome, it should’ve happened by now on numerous occasions. Otherwise, we’re left to conclude that either this god doesn’t exist, or that it truly doesn’t care what you or anyone else does in their day-to-day, consequently invaliding any and all notions of intervention.

But we must say something of the utility of the matter since it is commonly and boorishly implored as the preferred means of coagulation. How many thoughts and prayers have been offered up in the wakes of Columbine, Sandy Hook, Virginia Tech (2007), and the University of Texas (1966)? Have we been praying to the wrong god? Did we not pray correctly? Did we happen to pray at the wrong time? Was god on a holiday, conveniently enough whenever these massacres occurred? Was the presence of this god in particular absent from these schools? Try explaining to the surviving family members that their children would’ve experienced, or were at least far more likely to, divine intervention, which would certainly have saved them, if only they and the student body were a bit more pious.

More questions emerge from the framework. Just how much piety and humility – if ever it could be sufficiently quantified – is or would be required to prevent these tragedies? Must we compel the faculty and community at large to resort to barbarous medieval customs such as animal and human sacrifice? Or do we simply need to ramp up production of such sloganistic masterpieces as the one on display above, accelerate the marketing to procure more sales, and rely entirely on the horrifyingly shallow sort of solidarity that both founds and breeds in it? This here is a pestilence of the mind and of the society, and from within this cesspool, naught of a tincture of a remedy is to be found.

We seem also to be taking this concept of gradation, given to us by Aquinas himself, and pumping it full of steroids to give it some meaning that, in its attempts to assuage negation, permits it to blitz past any naysayers in total ignorance of its fatal detraction. While a reasonable destruction of this is possible, a more poignant defamation presents itself through these shootings and by responses like the one shown above.

If we take a look on gradation, we find that to judge the merit of one’s goodness is to effectively weigh it in proximity of the ‘uttermost’ good, and the result of this exercise would yield the final goodness or badness of one’s actions. From the perspective of the exercise itself, this makes total sense, since any measurement of any kind with the objective of describing some property of the subject in a vacuum would provide very little to glean. But we arise at an issue when we do what Aquinas suggests, which is placing god, or at least his rendition, in the position of the objective, or the pinnacle of conceivable subjectivity, ‘uttermost’ goodness, by which any and all questions of morality and conceptions of utopia are adjudicated. For example, are we to assume that one’s moral compass is skewed, or skewered in some cases, when they are found to not subscribe to the same god as does Aquinas regardless of the reason? Do they not distinguish good from bad? More adequately, we could express the paradox as if one’s ‘uttermost’ good is different than mine, because if god is my ‘uttermost’ good and their god is not my god, how then do I know that person is a good person, or at any rate, can be expected to do good things? Often left out of the conversation is that it’s plausible that this arm’s length sizing-up happens on the other side. Further, what happens if this god commands as ‘uttermost’ good the slaughter of peoples whose faith subscriptions are inconsistent and irreconcilable with your own? Of both the sums of atrocities committed and their accompanying rationale, a very safe and sound assertion that religion permits this kind of horrifying and arbitrary inconsistency can be mounted and defended. If nothing else is said from here, it should at least be granted that not only is god not the ‘uttermost’ good, but that if one elects to place it there, they’re not to be trusted on judging morals or goodness at all.

The common question of if god is absent, how can we be moral or good emerges here, and it has a very simple response that makes sense. We can indeed be moral and good in the absence of god because it’s not a progenitor for either morality or so-called ‘uttermost’ goodness. Rather, the imperative that one behaves in this way is emergent as a substrate to society solely as a reciprocal of our evolving social dynamic, further dictated by the species and its relation to the availability of subsistence resources. In other words, we are good and moral subjectively, and what constitutes the prime measurement for goodness is not an ephemeral and likely non-existent construct, but is the collectiveness of our species in and of itself. This structure is entirely mutable in much the same ways that human behaviours are subject to both social glue as well as environmental properties.

But if god is present in any form, can you still be good and moral? Yes. Because these things don’t arise from god and are instead universal by other means. Missions to Haiti should be performed because it’s the right thing to do, not because god dictated your good. One should have access to a roof over their heads and common amenities because of decency and growth of the species, not because god willed servants to grant those things with the hook-line-and-sinker that the recipient will be liberated from their heathen backward lives in godless communities.

And now we arrive at our magnum opus. From where precisely in these atrocities taking place in our schools do we find the grounds for dispelling the magisterium and voodoo of religion, which compels people to look in entirely the wrong direction, so that we can start addressing real issues? It’s rooted in a very particular kind of economy, one which can be found in example by removing from the clause that provoked this entire adventure certain words. Doing so will shift meaning, but only toward a larger scale, and does not detract in any way from the original objective; it remains valid. Simply restate the offending question:

Why do you allow so much violence in our schools?

To:

Why do you allow so much violence?

And the entire prospect of omnipotence falls even harder on its face than it already did. We could’ve easily grouped the words in our schools, turned the last word into a variable, and played a game of Mad Libs by swapping it out with any other place. However, we must understand clearly that by doing either this or taking the amended statement above as the general inquiry, the answer on offer must necessarily change, and not for the better since it becomes harder to answer, even rhetorically, as the author of our shirt here obviously didn’t take into consideration. Let’s try.

First, replace school with church. Now, of all the enumerable places where people go, the one most assuredly where one would find a plethora of fuel to bring about the god would be in a church. So why is it then that even when churches, mosques, and synagogues are targeted with extreme acts of violence, whatever the reason, that there is a very distinct lack of divine hands redirecting bullets, shielding people from blast radii and/or collapsing structural debris, or, perhaps even more telling, why wouldn’t this god have either mooted with or road-blocked the other god that drove the attackers before they inaugurated their campaign of terror? Whoops! Hang on! What if the god was the same? What then? Further, suppose we commanded an increase in the footprint of religion in schools, as was suggested implicitly by our lovely fashion statement? Surely, if places dedicated to the worship of a god are not omitted from consideration in plans of attack, nor are they on the list of places where critical divine action occurs, why would one ever dream to conceive that a school would somehow make the cut, and then have the sickening audacity to even place the option on the table as a solution?

Finally, let’s take the second permutation of the question and examine the change on the context. Expectantly, one would decry this exercise as being far too broad, but I vehemently disagree with this. Considering that the breadth of this god’s influence is claimed to be so grand in scale and magnitude that even the laws of the universe bend to its will, speaking generally on violence should be of little to no consequence. Human history illustrates clearly a ubiquity in the distribution and execution of barbarism from as far back as we can tell. Hence, we must acknowledge that violence is evinced in the cultures of Neanderthals, Vikings, Greeks, Romans, Scots, British, Indian, Egyptian, Prussian, and contemporary American to name a few. The pinnacle issue at the core here is that to even ask a question of this calibre is to understand that an unsatisfactory answer will always be had from this or any other god. Questions of how sometimes serve as antecedent to those of why, and in this case, they’re far more critical. Instead of asking why a god permits violence, one should be more concerned with how violence emerges. In doing so, an enlightening proposition occurs.

While it’s true that some elect to refer to their god as the ultimate good, and that it may inhibit them from committing acts that would, based on those standards, be deemed bad, the inverse case is also true. Those killing people with a prayer or the name of a god on their lips during the act are just as capable as those who do so without. Certainly, one could argue, as often occurs, which kinds of people are more prone to such senseless aggression, but here they’re all considered equally. That being said, all of a sudden, a god, whomever or whatever it may be, if indeed it can be at all, no longer has the luxury of stratifying itself against the innumerable other means by which violence emerges since it becomes one alongside them. In effect, you could propose the same inquiry to other subjects like scarcity (artificial or not), repression, anger, jealousy, racism, sexism, bigotry, and cultural standards to name a few. The real paradox here is that although asking of these subjects this question is in effect the same as doing so with a god, one is considered insane for personifying these and not so for a god. My thought here is that a very real fear emerges from confronting these tangible actors, one rooted in the providence of human beings. If blame is cast wholly on an agent whose very nature and existence are highly volatile at best, somehow this alleviates from humans the responsibility of having to act for change in a way that goes beyond printing on clothing, making social media posts, or muckraking with contrarian dogma to maintain the decadence of the mass.

In short,

Praying to a god will not stop violence anywhere.

Offering adulation to any diety will not hamper or deter all violence anywhere.

Hermetically sealing your community away and galvanising it with religion, while potentially shuttering external influence, doesn’t serve any purpose in this regard.

Demanding that more people become religious will not change anything.

So, what would?

We would.

Our culture and our politics should be the first targets. We see it as sexy and dignified, as well as a show of power, to brandish weaponry of any kind to each other. Becoming strong and defensive is an objective in and of itself, and the perception of not doing so is to be weak, and the weak are only to be used by the strong. The impressions of strength and weakness manifest in people in different ways, depending wildly on their social situations. In here, generalities can be established, but not enough to convince someone truly mired in the mess that theirs is not unique enough to warrant highly questionable expressions of relief. Television, major film, and shorts glorify acts of violence if only in defence, ignoring the underlying motivations for them and the requisite discipline for containing the precursors, which in defence or not, are largely the same. Guns have obtained a first-class citizenry status and are big business. The second amendment, having been picked apart from the political ravens and vultures in the name of convenient yet contradictory legislature, has convinced a majority of people that they, and not just militias, are mandated constitutionally to own weaponry, and the degree of ordinance permissible, at least under the table, is irrelevant when the dollars are in order. No one submits that even in the periphery, the Founding Fathers composed this construct with the intent of permitting brothers and sisters to maim one another without any truly compelling reason. We falsely dichotomise killing for sport and murder, using this as justification for “sport hunting,” which itself is leveraged as argument for obtaining vast quantities of weaponry for private citizens. A weapon used for killing or severely injuring another human is quite similar to that which is used for “sporting” an animal.

Of course, this only scratches the surface, and I’d be remiss if I thought for one second that a complete disarmament of the people en masse would be possible or even desirable. We must remember though is that we, those of us not in politics, can demand change through action which requires more than shirts, Instagram pictures, profile photo filters on Facebook, and, hell, even the words that I’ve written here now. Close your bibles, they serve you no purpose. Turn off the TV and the cell phones and start talking to one another. Engage people to find common ground. Be a human being again. Demand that these dirty, incompetent, and disconnected politicians and SIGs be taken to task for the truly horrible nature of their actions. Be a positive influence in your community, and do it without the aid of a god, because you don’t need it.

Everything you need, you already possess within you.

 

 

Monogame – Working with Touch

*NOTE – This may also work on other platforms with touch as well, but this hasn’t been tested on anything other than Android at the current moment.

One fundamental aspect to understand about touch and gestures is that code needs structured around the idea of continuous input. Thus, any touch recognition code should be encapsulated somewhere within the main game loop; where this is would be dependent upon how one elects to parse input. The reason for this is that the nature of all touch processing is a sequence of touch events that get fired in succession; there are only a few exceptions to this rule.

The other aspect to understand clearly is nomenclature mapping. What you think you want to achieve in your design may, unless you’re already familiar with either the Monogame or Xamarin frameworks, not necessarily be what either of those aforementioned frameworks are calling it through its API parlance. So be prepared to step outside your normal wheelhouse and, perhaps, discard some long-standing assertions about what truly a touch/gesture really is.

First, the consideration needs made as to if you’re going to handle touches or gestures – don’t get too caught up on thinking that a touch is a single press, because this will cause you some unnecessary grief later. If your program ebbs toward the former, there’s usually no requisite configuration needed, other than to check for the existence of a touch-capable input device and adjust your engine accordingly (the only other exception here would be if one wishes to perform touch-to-cursor mappings, but this is outside the immediate scope of this article). Conversely, gesture handling requires some configurations be made before they can be used, and this is where the Monogame documentation, as well as a majority of the information available on various forums, falls fatally short. We will focus on this once we start addressing gesture handling, which follows a look at touch handling.

Checking for the existence of hardware with touch capabilities can be queried through the TouchPanelCapabilities object, triaged through the TouchPanel static object as such:

TouchPanel.GetCapabilities ().IsConnected;

The IsConnected property is a boolean that indicates the presence of a touch-capable device. Obviously, the absence of one suggests either that the device is intermittently available, or that other sources of input are necessary. In this case, neither the touch nor gesture APIs would be valid.

Concerning touches, the current state of the touch panel holds a collection, called TouchCollection, of TouchLocation objects. Each of these correspond to a single touch event generated by the user when a press is determined to have occurred on the sensitive surface. It’s fair to suggest that multiple points of contact yield multiple TouchLocation instances within the TouchCollection (i.e. as a practical example, one finger would generate one instance, two fingers would generate two instances, etc. This can best be observed while debugging a program using this technique, and paying attention to the Id property of the TouchLocation instance(s).). In order to properly ascertain the most accurate state of the touch panel, we’ll need to do the following:

  1. Obtain the current state of the touch panel
  2. Determine if there are any TouchLocation instances in the TouchCollection collection
  3. If there are, take relative action based on any of the properties of the current TouchLocation instance

This can be accomplished using the following general template

TouchCollection tc = TouchPanel.GetState ();
foreach (TouchLocation tl in tc) {
 // Do something here
}

Fortunately, TouchLocation instances are very simple to use. There are only four properties that are of any practical significance, and one utility function for trying to determine the previous location (which, at least during my testing, wasn’t useful for anything). They are as follows:

  • Id – An Integer that uniquely identifies a single TouchLocation instance within a TouchCollection. It’s unknown how its potential values are determined, or if orphaned values are subject to recycling after the host TouchLocation has fallen out of scope.
  • Position – A Vector2 that provides the X and Y coordinate serving as the source for the event. Effectively, this is the location on the sensitive surface where contact was made.
  • Pressure – A floating-point number indicating the pressure of the touch. I’m unclear on how exactly this works, since my tests always reported a zero in this property. The only conclusions I can come up with here are either that my device doesn’t support touch sensitivity of this kind, or I missed a configuration step to enable this functionality.
  • State – An instance of TouchLocationState that determines what kind of touch we’re dealing with. This property can have one of four values:
    • Invalid – The press has been somehow deemed invalid; I’ve never seen this occur in testing, and am left to think that either I failed to satisfy conditions to make this occur, or that it’s simply a dump case for an exceptional condition.
    • Moved – Seen when a press has either remained in the same position or has moved. This is a very important state as it has a great deal of practical application, so do try to keep it in mind.
    • Pressed – Observed when a point of contact on the sensitive surface is newly minted. This is only fired once, and will not be seen again, regardless if the contact remains afterward. This could potentially be a source of confusion for a number of programmers.
    • Released – Likely the last state that a TouchLocation would be in before falling out of scope, it will be fired when the source of contact which generated this particular instance is no longer available.

Having said all of that, you now have enough information to properly utilise touches within your programs. As was stated before, simply ensure that your code is contained within the main game loop somewhere, since the data will likely change per frame, or at least as often as it can. An example of how to implement code based off this logic will be illustrated at the end of this discussion.

Gestures, insofar as Monogame is concerned, are a bit of a hassle to work with, mostly due to the lack of upstream documentation. We will seek to correct this imbalance, if not for the official documentation, then at least for programmers who wish to learn more about them.

As was stated previously, although Monogame performs a considerable amount of work to make available the touch and gesture API for programs deployed on capable hardware, gestures are left a bit open-ended by comparison to their touch counterparts. What this means is that as a programmer, you’re required to provide some configuration before the gesture API can be utilised. Here, we assume that you’re only interested in gestures, and not touch-to-cursor mappings, hence will only discuss the former.

Before proceeding, some basic information should be given as to the nature of gestures, and how they’re procedurally handled.

Although there is some very minor overlap with how a touch and gesture are expressed, they are two discrete entities. Gestures can be composed of one or more points of contact, and it’s expected that the locations of these contacts will change, in a particular way, over an indeterminate amount of time (ergonomic measurements would likely dispute this generalisation, but it is for this conversation a generalisation, and not a scientific claim). The ways in which these contacts change, or at least the resultant shape the change yields, as well as the number of contacts involved in the measurement, hints at the particular kind of gesture. In other words, a single point of contact that has a gradual change in its X-axis, be it positive or negative, which would yield a ray (or a series of small rays), is generally considered to be a horizontal drag gesture. When considering the same principles but looking to the Y-axis instead, we now find ourselves dealing with a vertical drag gesture. Pinch and zoom gestures typically involve two or more points of contact that move near concertedly away from or toward each other along the same logical axis. Perhaps paradoxically, at least when considering a contrast between touches and gestures, taps, double taps, and long-presses are registered as gestures as well; these are more concerned with the sustainment of a single point of contact relative to the time from when it was first recognised.

From a stock perspective, Monogame provides eleven types of gestures, referred to as GestureTypes. These types will effectively determine how gesture detection is performed (it’s unclear if the GestureType framework can be extended to facilitate custom gesture types, but this is a considerably advanced topic which will not be discussed here). However, Monogame will not automatically read the touch panel for gestural input. Instead, it needs instructed on which kinds of gestures to detect, and this is provided by the programmer. In any non-looping block of code, preferably during the initialisation routines, you’ll need to specify what are called EnabledGestures, which is a property of the TouchPanel static object. Multiple gestures can be configured by OR’ing one or more of the types together in the assignment statement. For example, if I wanted to parse for both a HorizontalDrag and a DragComplete gesture, I would write the following statement:

TouchPanel.EnabledGestures = GestureType.HorizontalDrag | GestureType.DragComplete;

Once this is complete, you’ll have done enough to get Monogame to start playing nice with at least these two kinds.

Parsing gestural input is, in essence, no different than parsing touch input, but there are some minor differences to the process. To start, we must first determine if there are any gestures with which to read data from. If we do not do this, attempts to read directly from the gesture store will generate fatal exceptions. Fortunately, the TouchPanel static object provides a boolean property called IsGestureAvailable, which will inform clients of the availability of queued gesture data. If we have data, we must convert the data into a sample, which is packaged into the GestureSample class. As with the TouchLocation object, the GestureSample object contains several properties that are of practical interest to the programmer, especially when making contextual decisions that respond to this kind of input. GestureSamples include the following properties:

  • Delta – A Vector2 instance which provides the delta, or difference, data for the first touch point in the gesture. This will change over time, and will always be relative to the coordinates where the touch was first recognised.
  • Position – A Vector2 instance which contains the current coordinates of the first touch point in the gesture.
  • Timestamp – A TimeSpan instance that indicates the time when the gesture was first recognised.
  • GestureType – A GestureType instance that indicates what type of gesture was determined based off several criteria.

Additionally, GestureSample contains properties called Delta2 and Position2, which are used to track a second point of contact that’s being measured as part of the current gesture. What this implies is that insofar as the stock gestures are concerned, Monogame will only be able to handle gestures where no more than two points of contact are involved.

My advice here is to experiment with the data through debugging until you’re comfortable with how these gestures are read, because there are some nuances with how the data continuously polls respective to different gesture kinds. For example, a HorizontalDrag gesture will, while the drag is occurring, constantly emit the HorizontalDrag signal until the contact source is released, terminating the gesture. At this point, if one is checking for the DragComplete signal as well, releasing the contact source will cause the touch panel to emit the DragComplete signal.

Examples:

To determine if a single press has been made:

TouchCollection tc = TouchPanel.GetState ();
foreach (TouchLocation tl in tc) {
 if (TouchLocationState.Pressed == tl.State) {
  // Execute your domain-specific code here
 }
}

To determine if a press was made, and has been held in the same position for an arbitrary period of time:

TouchCollection tc = TouchPanel.GetState ();
foreach (TouchLocation tl in tc) {
 if (TouchLocationState.Moved == tl.State) {
  // Execute your domain-specific code here
 }
}

To track the position of a horizontal drag:

(1) During game initialisation:

TouchPanel.EnabledGestures = GestureType.HorizontalDrag;

(2) During game loop:

while (TouchPanel.IsGestureAvailable) {
 GestureSample gs = TouchPanel.ReadGesture ();
 if (GestureType.HorizontalDrag == gs.GestureType) {
  // Execute your domain-specific code here
 }
}

PhysicsFS/PhysFS++ Tutorial

This is a follow-up from a promise that I made in my tutorial video on designing an asset manager using SFML. That video can be found here.

This tutorial is centred around PhysFS++, a C++ wrapper for PhysicsFS. For the sake of the tutorial, it’s assumed that the reader is familiar with PhysicsFS and what it’s capable of. Described here is a workflow for simple use of the library. Anything more discrete is beyond the scope and will have to be ascertained by the reader on their own accord.

Lastly of note, PhysFS++ encapsulates PhysicsFS calls in a PhysFS namespace. The functions are global within this namespace and there are only a few classes that are provided. PhysFS++ further encapsulates key PhysicsFS constructs, notably those corresponding to archived files, into said classes that are derivatives of STL stream classes (a huge boon).

Like some other libraries, PhysicsFS requires explicit initialisation before it can be used. This is facilitated by a function named init. It takes one argument of type const char* and is semantically directed at a terminal invocation argument triaged through the much loved argv. However, this can be an empty string especially if you’re not expecting to handle terminal invocations. Thus, a very general call to init can be performed as such:

PhysFS::init (nullptr);

Right of the bat we have to mention a caveat here. From PhysFS++, there’s no way to assert the initialisation process of PhysicsFS. This is counter-intuitive to the upstream library which relies on the tried-and-true zero on failure, non-zero on success return values as sanity checks. Furthermore, while PhysFS++ implements C++ exceptions, the init function doesn’t throw any at all. Ostensibly, what one is left with is an unchecked call to init. Because one needs to compile PhysFS++ from the source, it is possible to modify the code, as I have done, to add a check to this call.

Once init has successfully completed, the next step is to mount an archive file into the virtual filesystem created by init. This is performed with the mount function. mount expects three arguments: the archive file on disk, a string specifying a mount point in the virtual filesystem, and a boolean which appends the mount point to the search path. One should place the archive file in the working directory for the binary file of their executable so PhysFS++ can see it. The second argument can be an empty string which would force root mounting, and the third can be true. Thus, for our example, if we assume we have an archive file named funphotos.zip on our disk in the binary’s working directory, we can issue a call to mount as such:

PhysFS::mount (“funphotos.zip”, “”, 1);

Unfortunately, as was the case with init, mount wraps an upstream function that adheres to the zero-or-nonzero return value paradigm that is outright dropped by PhysFS++ with no exception catering otherwise. Thus, if mount fails to mount the archive for whatever reason, it’ll be a little difficult to ascertain why; plan accordingly.

Assuming mount has returned properly, one can start to work with the files that are contained in the archive. At this point, you should begin working in the mentality of filesystem calls. It’s possible to have archive files with complex directory layouts which would require one to perform recursive searches. That being said, everything should be considered a file – even a directory. An analysis of the PhysicsFS and PhysFS++ APIs will provide for you the full breadth of your available capabilities so for the sake of brevity, only a select number of those will be touched here.

Enumeration of files in a directory can be performed with the enumerateFiles function. It takes as an argument a string which indicates the directory to use as a root for the enumeration. As a return it provides the caller with a vector of strings indicating the name of the file. For ease of use, a call to this to enumerate the files in root can be performed as such:

auto rootfiles = PhysFs::enumerateFiles (“/”);

To actually work with a file in the filesystem, one needs to use the PHYSFS_file ADT. This upstream ADT is encapsulated by one of three classes: PhysFS::ifstream, PhysFS::ostream, or PhysFS::fstream. Each of these is fantastic in that they encapsulate a PHYSFS_file ADT in a standard stream which means that one can now perform established stream operations on the file itself. Each class has its own use: fstream for reading files, ostream for writing to files, and ifstream for bidirectional file handling. In any case, any of these classes can be instantiated with a string argument that contains a fully qualified pathname to a file in the virtual filesystem that one wants to work with. For example, given that our virtual filesystem has a file named goofycats.png located at the path /textures/cats, we could instantiate a read file as such:

PhysFS::fstream gc (“/textures/cats/goofycats.png”);

Again, the underlying upstream call to open the file goes unchecked.

What you do from here is largely subjective relative to your program’s context. Say, for example (and this is actually pretty specific to my own use case), that you have a series of files of various formats in an archive that are being used in a video game program. The multimedia library you’re using should have ADTs that represent types of assets such as textures, fonts, etc. One could do some work to transpose the raw data of these streams into the aforementioned ADTs for use in the multimedia library. The following snippet of code, borrowed from one of my own projects, illustrates this. A PhysFS::fstream instance named f is created with a certain file. Following up is a char array named d is instantiated with the size of f. The read function of f is called to transpose the bytes from f into d. Then, d is used to instantiate an instance of sf::Music from SFML contained in a std::unordered_map:

code

This covers most the basic and general needs of users of PhysicsFS. Should you require anything else from it, you’d do well to read up on the Doxygen file of PhysicsFS or the source for PhysFS++. Lastly, when one is done with the library, you’ll need to call a deinitialization function called deinit:

PhysFS::deinit ();