Category Archives: Programming

Building software.

A New Save System – Easy Save To The Rescue

With Into The Inferno development, I reached the point where it was time to get a better save-game system than the existing hacked-together-in-an-hour XML file. It had been on my to-do list for a while as part of evolving past the “you get one save slot, and that’s it” stage.

I have a ton of experience with C#, so throwing something in an XML file is second nature. That’s not necessarily a good or bad thing, but some of the legacy bits are strongly disrecommended by Microsoft at this point (BinaryFormatter for example).

I decided to “do what everyone else does” and get a copy of Easy Save from the Unity Asset Store. It’s immensely popular and highly recommended and it seemed like it’d be the shortest time-to-implement of the available options.

Fast-forward 8 hours later. I have a working save system with three save slots and it’s better in every way than the previous system. I was able to re-use a lot of my existing data code, rewrote some of it to be cleaner, and have “summaries” that are saved as part of the game saves that say where and who the party was at the time of save, and the interface changes necessary to support all of this.

Before:

Into The Inferno Main Menu Load Game - Before

Loading From the Main Menu – Before

Into The Inferno Save Game - Before

Saving At The Inn – Before\

As you can see, there’s just “Load Game” but you have no idea what you’re loading. Similarly, saving the game is just “Save Game” with nothing beyond that.

After implementing Easy Save, this is what I have:

Loading From the Main Menu - After

Loading From the Main Menu – After

Into The Inferno Save Game - After

Saving At The Inn – After

The first screenshot shows what comes up after you click “Load Game” on the menu. The summary text is localized in realtime, so in Spanish you’ll see that Archie is a “nivel 1 guerrero” even if you saved the game in English.

The second screenshot is saving the game from the inn. Saves at this point are an intentionally-limited resource (for better or worse), but at least now you have more control over them, and it’s easy to customize the number of slots that there are.

In the future I’d like to add Steam cloud save synchronization, but I have no idea how tough that will be. In any case, Easy Save made what I thought was a 40-hour task into a single day project, testing and UI changes included, and I definitely recommend it.

Disabling Automatic Closing Braces in Visual Studio Code

I really like Visual Studio Code as an editor, but it has some annoying defaults.

When working in C# (and a lot of other languages), it tries to be “helpful” by automatically adding closing braces, brackets, and parentheses when you type the opening ones.

An Automatic Closing Brace

Automatic closing brace added when typing an opening brace.

For some people, this is great. For me, no. It just doesn’t work with my typing and coding style, and ends up being something that gets in the way and I have to move or remove later.

Fortunately it’s easy to turn this off.

Go to File –> Preferences –> Settings

Search for “auto closing brackets”.

Change “Editor: Auto Closing Brackets” to “never”.

Auto Closing Brackets Setting

Turning off the auto closing brackets setting.

Problem solved. Happy coding!

Coming Full Circle With Game Development (Unity)

The very first programming I ever did was game programming.

It started with my Commodore VIC-20 in 1984. The computer’s manual had some BASIC programs you could type in and run. One was a Space-Invaders-type game.

Well, naturally, after typing in this game and playing it for a bit, I wanted to start making changes to enemy colors, speed, and score values. This was how I started programming.

It continued when I got a Tandy 1000 EX that ran MS-DOS and started writing games in GW-BASIC. By now I was coding much more detailed and complex programs. They were still text-only (ASCII), but I was creating them from scratch, and they had much more detailed mechanics.

I remember well a text-based gladiator combat tournament game that I spent the better part of a year working on, at about age 10, in addition to a few text-based adventure games.

Later, as the Internet started to grow, I became interested in multi-user dungeons. There were various codebases — Diku, Merc, Envy, Circle, and others. Not only did I work on some existing games, I also created my own, starting with Illustrium Arcana, and later with the Basternae  rewrite, Basternae 3: Phoenix Rising. If you look at the “Basternae and ModernMUD” topic on this blog, you’ll see that I was working on them well into 2013.

When I was finishing my college degree in 2004, I took some classes for credit at The Game Institute and got a job with a company working on simulators for the US Army (among other government contracts). It was basically a video game company, but replace “fun” with “realism”. I didn’t really work on any graphics code, and ended up specializing in audio and network communications. This was the first and last job I had in video games.

My strong knowledge of audio programming and networking protocols took me on to develop parts of the Authentic8 SILO browser, work on a home automation system, and build the various audio applications I released as Zeta Centauri.

Now I’m returning to my roots and learning Unity. It’s incredibly intuitive, and the programming is easy and natural thanks to the many years I spent writing C# code.

I’ve started with the “Complete C# Unity Game Developer 2D” course available through Udemy. I’m about 50% of the way through, and the deep, thorough coverage coupled with real hands-on coding projects has been great for the learning process. I’m definitely going to take more of the Gamedev.tv courses because they really know how to teach.

PostgreSQL Command History

The command-line PostgreSQL database client keeps a command history.

Much like on a Linux console, you can use the up arrow to scroll back through previous commands. This can be handy if you want to repeat a command, or to change a parameter on a long query.

One other thing that is less widely-known is that you can view the ENTIRE history by typing “\s”. Backslash-s will function pretty much the same as the Linux “history” command, and can give you multiple pages of commands.

Much like the history of the Bash shell, the Postgres command history is stored in your home directory in the hidden file .psql_history. Although this is handy, it can also be a security risk to keep old commands where prying eyes can find them. You can easily delete this file, or clear it using the command:

 truncate -s 0 .psql_history

I like the truncate command because it’s a nice, clean, one-step way to clear a file without deleting it.

How to Insert Values Into a Table from a Select Query in PostgreSQL

I recently had to do a data migration where I needed to populate a new table with some data from another table.

Rather than perform some sort of export, transform, and import, it was much easier to do this via a select query within Postgres itself.

Although you can use the star operator, it’s safer and smarter to name fields specifically, in order. In addition, you should manually verify your select query first.

In my case, there were a set of a few fields I wanted to insert, and converted into a select query, looked like this:

SELECT date_added, description, last_updated, name, type FROM information;

This gave me all of the fields I wanted, and I verified that the data looked good.

Next, I added this to an insert query:

INSERT INTO information_subset (date_added, description, last_updated, name, type) SELECT date_added, description, last_updated, name, type FROM information;

Although it’s something that seems like it might be complex, inserting into one table using data from another is quite simple in Postgres and most other databases.

Using Location to Assume User Language

My first language is English. I live in Uruguay, and while I’m comfortable and nearly fluent in Spanish, sometimes I’d rather use a website in English.

It is EXTREMELY common for a website to see the location of my IP address and assume they should send me a page in Spanish. This is perfectly fine, because everyone in Uruguay speaks Spanish. Not everyone has it as their first (or preferred) language given the number of immigrants here (especially from Brazil), but everyone speaks at least SOME Spanish here.

The other thing that sites may use is the language setting of your web browser. This is also a reasonable approach, although less common. I have one computer set to English and one set to Spanish, and I’ll sometimes get different versions of a site depending on which computer I use. This is mostly OK, but there are an unreasonable number of computers that have the language set to English (the most common default) even though the users don’t prefer English. There are also computers used by multi-lingual households, so using the computer’s language setting is an assumption at best, and probably less accurate than using someone’s location.

Of course, the right thing to do after you’ve made an assumption about the user’s language is allow them to change it. Typically this is a link or button somewhere along the top of the site. Although sometimes this will be a flag icon, that’s less than ideal when you’re dealing with countries that have multiple languages (Belgium, for example). People from that country have learned to adjust, and can pick the French, Netherlands, or even German flag if they need to.

The problem comes when a website doesn’t give someone the chance to change the language they’re viewing. Not only are geolocation services not 100% accurate, but just because you are IN a place doesn’t mean you are OF a place.

Sure, auto-translation tools are nice, and they get you 80% of the way there, but they rarely understand context, words with multiple meanings, regional word usage, or any of the other Human nuances. Maybe some day, but not today. So it’s important to allow a user to select their preferred language.

Sometimes it’s easy to change the language manually by hand-editing the URL. For example, these urls:

es.wikipedia.org/page-name
example.com/es/page-name
example.com/page-name?lang=es

Can easily be changed to:

en.wikipedia.org/page-name
example.com/en/page-name
example.com/page-name?lang=en

Where it gets really ugly, and I’ve seen this with media/streaming sites more than anything else, is when you deliberately visit a page in a specific language, and you are force-redirected back to the language you didn’t want.

The only hope for sites like that is to use a proxy server. Or close the browser tab. You should never force a language on a visitor if your site is available in other languages.

And if you find a site with this bad behavior, please send them a message letting them know the error of their ways. Maybe they’ll eventually learn.

 

Why Do So Few People Develop Apps for Windows?

There are a lot of reasons so few people develop for Windows anymore.

We’ll skip the obvious ones:
– There’s a whole lot more growth in mobile apps.
– Most of the apps that people could want or need on Windows have already been written.
– Many apps make more sense as websites, so every platform can access them.

For apps that make more sense on a desktop PC, such as audio/video production and 3D design, and all of the other sorts of things that are not optimal on a 5-inch screen or in a stateless system, there’s a much more painful reason:

MICROSOFT’S DEVELOPER ECOSYSTEM IS HORRIBLE.

For example, the answer to this question:

What framework should I build my app with?

It is almost impossible to answer, and the official answer changes every year or two.

Win32?
WPF?
WinForms?
.NET MAUI?
WinUI?
Xamarin?
WinRT?
MFC?
Qt?
wxWidgets?
Silverlight?
Universal Windows Platform (UWP)?
Windows App SDK?
Progressive Web App (PWA)?
MSIX, MSI, or EXE installer?
Are any of these things different names for the same thing? (yes)

Good luck. Microsoft has come out with many new technologies that were “almost finished”, and each one has had some glaring omissions and dropped some important technologies or features that will probably never be finished before the system is replaced with something else. I know this pain all too well since I’ve worked with text-to-speech and audio applications extensively.

And, of course, when one system supersedes another, they don’t put a disclaimer on the docs saying “you should use this new thing instead” and provide a migration guide, and many of the docs don’t even have a date so you at least have some idea whether it’s current.

In some of the latest nonsense: In the Windows Store, you can submit an app with an MSIX installer or an MSI/EXE installer. You can set an app with an MSI/EXE installer as paid, but you CANNOT ACTUALLY CHARGE MONEY FOR IT. I don’t know who designed a system like that, but they were probably drunk at the time. Of course, I didn’t learn this until after I went through the entire process of getting an app approved for the store.

Another aborted effort was enabling ad-based monetization of free apps distributed via the Windows store.

Why is it that every mobile operating system (even the ones with only a handful of users) has managed to get this right, and Microsoft just can’t figure out how to build a system that people actually want to build a business around?

I like building desktop apps, but Microsoft has done everything they possibly can to make it a nightmare to support Windows. Nowadays you can probably only make money writing Windows apps if you’re writing malware.

Fixing OSError: cannot write mode RGBA as JPEG in Python

I have an application that was originally written in Python 2.7 and used the Python Image Libary (PIL). Now it uses Python 3.x and Pillow (the PIL replacement). One of the things it does is automatically generate .jpg file thumbnails of uploaded files.

It does this by resizing the uploaded image, and then saving it with the filename extension changed.

I started getting an error when uploading a .png file:

OSError: cannot write mode RGBA as JPEG

A bit of research told me that the behavior has changed. Now you need to discard the alpha (transparency) channel of an image before you’re allowed to save it as an image type that doesn’t have an alpha channel. Since PNG files normally have a transparency layer, it makes sense why I would hit that error. It’s trying to protect me from losing data I might potentially want to keep. However, I don’t want or need alpha channel data for my thumbnails.

The solution is just to convert the image before saving.

thumbnail = im.convert('RGB')
thumbnail.save("my_image_filename.jpg", 'JPEG', quality=92)

It’s a simple fix, but slightly annoying that the behavior has changed over the years.

Fixing Error LNK2038 In a Visual Studio Project

While building a Visual Studio C++ project in Visual Studio 2022, I received this error while linking to a library:

Error LNK2038 mismatch detected for ‘_MSC_VER’: value ‘1800’ doesn’t match value ‘1900’ in MidiPlayer.obj MIDIPlayer E:\code\MIDIPlayer\wxmsw30ud_core.lib(dlgcmn.obj)

In case you’re not familiar with this error, Visual Studio wants to link with libraries that were built with the same version of Microsoft C (same toolset) as the code you’re compiling. In older versions of Visual Studio that meant that they had been built with the same version of Visual Studio, but now that versions aren’t as tightly-coupled to Visual Studio, it’s also possible that you can get this with libraries built with the same version of Visual Studio that you’re using.

The solution is to rebuild the library with the same MSC version as your project.

For reference, here are the different MSC, MSVC, and toolset versions:

Microsoft C 6.0: _MSC_VER == 600
Microsoft C/C++ 7.0: _MSC_VER == 700
Microsoft Visual C++ 1.0: _MSC_VER == 800
Microsoft Visual C++ 2.0: _MSC_VER == 900
Microsoft Visual C++ 4.0: _MSC_VER == 1000
Microsoft Visual C++ 4.1: _MSC_VER == 1010
Microsoft Visual C++ 4.2: _MSC_VER == 1020
Microsoft Visual C++ 5.0: _MSC_VER == 1100 (Visual Studio 97)
Microsoft Visual C++ 6.0: _MSC_VER == 1200 (Visual Studio 6.0)
Microsoft Visual C++ 7.0: _MSC_VER == 1300 (Visual Studio 2002)
Microsoft Visual C++ 7.1: _MSC_VER == 1310 (Visual Studio 2003)
Microsoft Visual C++ 8.0: _MSC_VER == 1400 (Visual Studio 2005 – v80)
Microsoft Visual C++ 9.0: _MSC_VER == 1500 (Visual Studio 2008 – v90)
Microsoft Visual C++ 10.0: _MSC_VER == 1600 (Visual Studio 2010 – v100)
Microsoft Visual C++ 11.0: _MSC_VER == 1700 (Visual Studio 2012 – v110)
Microsoft Visual C++ 12.0: _MSC_VER == 1800 (Visual Studio 2013 – v120)
Microsoft Visual C++ 14.0: _MSC_VER == 1900 (Visual Studio 2015 – v140)
Microsoft Visual C++ 14.1 – 14.16: _MSC_VER == 1910 – 1916 (Visual Studio 2017 – v141)
Microsoft Visual C++ 14.2 – 14.29: _MSC_VER == 1920 – 1929 (Visual Studio 2019 – v142)
Microsoft Visual C++ 14.3: _MSC_VER == 1930 (Visual Studio 2022 – v143)

It’s interesting that starting with Visual Studio version 2017, Microsoft started incrementing the MSC version with each “micro” build change.

Telling Git To Ignore File Mode Changes

It’s possible for Git to think there have been changes to files when only permissions have changed. This is something that is pretty common if you work across multiple operating systems, and it can be annoying.

For example, running “git status” showed that two of my icon files had changed, but hadn’t edited them. Running “git diff” showed that it was just the file mode properties (permissions or “props”) that had changed.

$ git diff
diff –git a/images/samplitron_largeicon.png b/images/samplitron_largeicon.png
old mode 100644
new mode 100755
diff –git a/images/samplitron_largeicon.xcf b/images/samplitron_largeicon.xcf
old mode 100644
new mode 100755

To make Git stop treating this as a change, there’s a command you can run:

git config –global core.fileMode false

Now when you run “git status” or “git diff”, file mode changes will be ignored.

Fixing Error MSB3843 in a Visual Studio Project

I updated my DrumPads code project to the latest version of Visual Studio 2022 and received this error when trying to build:

Error MSB3843 Project “DrumPads” targets platform “Windows”, but references SDK “Visual C++ 2015-2019 Runtime for Universal Windows Platform Apps v14.0” which targets platform “UAP”. C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\amd64\Microsoft.Common.CurrentVersion.targets

I’m not sure whether the project was actually set to be UAP, or whether the migration set something to that.

Visual Studio Solution Explorer Showing "Universal Windows"

Solution Explorer Showing “Universal Windows”

To fix the error, I edited the DrumPads.vcxproj file manually. In the PropertyGroup sections for the build configurations I changed this:

<PropertyGroup Condition=”‘$(Configuration)|$(Platform)’==’Release|Win32′” Label=”Configuration”>
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v143</PlatformToolset
<WindowsAppContainer>true</WindowsAppContainer>
</PropertyGroup>

I removed the line <WindowsAppContainer>true</WindowsAppContainer> entries from all of the configurations and reloaded the project. It no longer showed up as “Universal Windows” and I was able to build without the error.

Solution Explorer Without "Universal Windows"

Solution Explorer Without “Universal Windows”

Changing the Remote URL for a Git Repository

Maybe the repository has been moved, or maybe you have an old repository that was checked out with username and password authentication, and you can’t push to it anymore because GitHub requires ssh authentication now. That was true in my case, since I was going back to work on code I hadn’t touched for a few years.

Although you could just re-check-out the repository, that is unnecessary, and can be annoying if you have changes that you want to push.

Changing the remote URL for a git repository is a simple thing to do, but it’s not necessarily obvious. It’s done using the “git remote” command.

To display the URL of the remote repository:

git remote get-url origin

https://github.com/xangis/SigmaTizm
To change this to a new URL:
git remote set-url origin git@github.com:Xangis/Sigmatizm.git
With this one-line change I was able to continue working as normal without needing to re-check-out the repository.

What Programming Is Like

A friend of mine posted this on their feed the other day.

My spouse (an artist, not in tech), working her way through a C++ class (part of a Digital Arts cirriculum). I: Let me know if you need help. She: Will do. Two hours later.. I: How's it going? She: Fine. I'm cheating. I: ??? She: I google for stuff I don't know. ... Do I tell her?

As a professional programmer with decades of experience, I can describe the full process:

Step 1: Google it. Find no applicable answers.

Step 2: Rephrase the question. Find search results that look relevant. Open them all in new tabs.

Step 3: Find that all of the results ask the exact question you’re trying to answer, but none have answers.

Step 4: Rephrase the question again using the extra keywords you found in other people’s questions. Get search results that are 80% the same. Click on the top new result.

Step 5: Find a solution that almost fits your problem and gets you 80% of the way there. It’s either missing a step or is outdated by a version of whatever you’re working on.

Step 6: Use that 80% solution to trial-and-error your way across the finish line.

Windows Software by Lambda Centauri

I’ve written a lot of apps for Windows (and other) PCs. Originally I published everything as Zeta Centauri, but it was a weird combination of audio apps and utilities that didn’t mesh well with audio apps (calculators, word processing, image viewer, browser). I’ve launched a new website for the utility apps to keep them separate from the audio apps.

Check it out here: https://lambdacentauri.com

Updating a wxWidgets project for Visual Studio 2019

I recently resurrected a dormant code project and went through the process of converting a wxWidgets 3.0 project to wxWidgets 3.1 and updaing from Visual Studio 2010 to Visual Studio 2019.

Include Directories

Here are the things I had to change to make things build and run:

Change “Platform Toolset” to Visual Studio 2019 in General configuration properties.

Change include and library directories from wxWidgets 3.0.2 to 3.1.4 in VC++ Directories and update the include path for modern Visual Studio. The change to $(IncludePath) does a lot of magic things that will save a lot of trouble. Failure to update that will cause common includes like stdafx.h to be missing.

Change include from:
E:\lib\wxWidgets-3.0.2\include;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSdkDir)include;$(FrameworkSDKDir)\include
to:
E:\lib\wxWidgets-3.1.4\include;$(IncludePath)

Code

The only code changes I had to make were to remove wxADJUST_MINSIZE anywhere it showed up.

Libraries

This is for the debug version of the project. Remove the “d” for libraries in the release version (i.e. wxbase31ud_core.lib => wxbase31u_core.lib).

These libraries showed up as missing:

comctl32.lib
rpcrt4.lib
uuid.lib
kernel32.lib

Adding C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\um\x86 to the linker directories fixed this.

msvcprtd.lib

Adding C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.20.27508\lib\x86 to the linker directories fixed this.

ucrtd.lib

Adding C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\ucrt\x86 to the linker directories fixed this.

wxregexu.lib

Adding that to the library list fixed it.

I suspected there was something similar to $(IncludePath) I could add to the library paths to make those resolve, but I wasn’t sure. So I tried $(LibraryPath). And it worked. Magic!

So do that instead of adding those individual directories.

Change library path from:
E:\lib\wxWidgets-3.0.2\include;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSdkDir)include;$(FrameworkSDKDir)\include
to:
E:\lib\wxWidgets-3.1.4\include;$(IncludePath)

Update all the libraries from wx 3.0 versions to wx 3.1 versions:

wxmsw30ud_core.lib => wxmsw31ud_core.lib
wxbase30ud.lib => wxbase31ud.lib
wxmsw30ud_adv.lib => wxmsw31ud_adv.lib
wxmsw30ud_html.lib => wxmsw31ud_html.lib
wxmsw30ud_xrc.lib => wxmsw31ud_xrc.lib
wxbase30ud_net.lib => wxbase31ud_net.lib
wxbase30ud_xml.lib => wxbase31ud_xml.lib

After these changes I was able to build and run my old project, which was originally written for wxWidgets 2.8 and then ported to wxWidgets 3.0.

Updating Django 1.8 on Python 2.7 to Django 1.11 on Python 3.6

I recently updated a few Django apps from Python 2.7 to Python 3.6 and while going from Django 1.8 to Django 1.11. This is mainly for my own reference, but others may find it useful.

Move the existing virtualenv (this will break the app):

mv ~/.virtualenvs/wbstats ~/.virtualenvs/wbstats2

Create a new virtualenv:

mkvirtualenv -p /usr/bin/python3 wbstats

At this point it might be a good idea to update the version of Django in requirements.txt. For WbStats it moved from 1.8 to 1.11.

Pip install the requirements.txt:

pip install -f requirements.txt

Edit settings.py and make sure there is a TEMPLATES section, which replaces TEMPLATE_DIRS. In addition, TEMPLATE_CONTEXT_PROCESSORS no longer exists. Basically anything with TEMPLATE_ has been rolled into the TEMPLATES section.

You may need to change some imports, i.e.

from models import *

may become:

from stats.models import *

The URLs will probably choke because strings are no longer allowed. Do not import “patterns”. Urlpatterns now is an array: urlpatterns = [url(…), url(…)]

'stats.views.index'

may need to be changed to:

from stats import views
views.index

After imports are fixed, the next thing will probably be fixing print statements.

Urlparse has been moved.

import urlparse

becomes:

import urllib.parse as urlparse

If you updated Django you’ll probably need to run migrations.

python manage.py migrate

Admin commands will need to be ported:

     option_list = BaseCommand.option_list + (make_option('-d', '--domain', default=None, action='store', type='string', dest='domain', help='The name of a domain to create or update.'),)

Becomes:

     def add_arguments(self, parser):
          parser.add_argument('-d', '--domain', default=None, action='store', dest='domain', help='The name of a domain to create or update.')

The parser arguments are mostly the same, but  references to “type=’int'” should be changed “type=int” without quotes, otherwise you’ll get ValueError: ‘int’ is not callable.

There’s some code in some of the admin commands I’ve written that changes the codec for stdout:

UTF8Writer = codecs.getwriter(‘utf8’)
sys.stdout = UTF8Writer(sys.stdout)

This will NEED to be removed because it causes cryptic TypeError problems saying things must be str and not bytes.

render_to_response needs to change to render because context_instance doesn’t exist.

Signing Up for Uber Eats in Another Country

Just want to mention my UX ordeal here – I basically had to hack my way through an app to order food.

I’m soggy and rained on (torrential pour today) and don’t want to leave the Airbnb, so I decided to sign up for Uber Eats, which I’ve never used before, and have food delivered. I’m in Mexico City but I live in Portland, Oregon.

I signed up using the web app because I wanna look at food pics on a big screen. I used my Google Voice number because I could validate it via text-to-email (I don’t get reliable phone service here on my network – Ting). Filled the cart with a huge order, entered my credit card, and when I clicked “place order” I got an alert that my phone number is not valid for ordering and I have to edit my account and add a valid phone number. The web app doesn’t let you edit your phone number. So I installed the mobile app and signed in. THAT let me edit my phone number and luck of all luck the validation text went through. I went back to the web app on my PC. Logged out and back in and my phone number showed up. Order was still in my cart. THEN I was able to order some food.

And now I’m getting Uber’s marketing emails in Spanish.

So yeah, sign up for your apps BEFORE you leave the country.

Proxima Controller Released for macOS via the App Store

I just released my virtual MIDI controller app Proxima Controller for macOS via the App Store. It’s something that I ported to OSX a while ago but never posted to the app store.

It lets you use your mouse, touchscreen, or keyboard keys to play a virtual MIDI controller that can be used to control external devices such as drum machines, synthesizers, or samplers.

You can get it here.

And if you want the Windows version you can get it here.

SpaceTheremin and MIDIPlayer Available for macOS Again

Over the years I’ve struggled mightily with OSX development. It’s just hard if you want to do things your way. It’s far easier if you use Apple’s choice of tools and languages.

Since most of what I’ve worked on for Apple computers has been apps ported from Windows or Linux, there really hasn’t been the option of starting with their way of doing things in mind at the beginning.

Last time I was working on building things for the App Store, I had eight apps I was trying to publish. I only ended up getting two released before I gave up in frustration. Those two were SpaceTheremin and MIDIPlayer.

Well, given my lack of enthusiasm, it’s no surprise that I let my developer subscription lapse. A lot of people wonder what happens when you let your subscription expire but then renew it later (around two years later in my case). Well, your apps disappear from the app store but stay installed wherever people already have them. And when you renew, they magically reappear like they never disappeared without needing to be reviewed again, and any apps in progress will be exactly as you left them.

That’s the case with SpaceTheremin and MIDIPlayer, which are now both available for macOS again.

Here’s SpaceTheremin.

Here’s MIDIPlayer.

I also have some things that have made it farther than before that you should expect to be released in the near future.

Menu Bar with Quit for a wxDialog or wxFrame-based app on OSX

I have some apps that I’ve tried porting to OSX off an on over the years, but some of them have never been quite right.

They’re written with wxWidgets, which is a multiplatform application development toolkit. However, documentation and fine details for macOS specifics is generally lacking.

For instance, I had an ongoing problem with making the “Quit” function in a menu work in a single-dialog application based on the wxDialog class. I originally asked the question on the forums back in 2011:

I have a wxDialog-based application on OSX that shows a single modal dialog window.

My understanding is that a dialog-based app cannot have a menu bar. However, I do get the default system menu bar on the app.

The Cmd-Q option (Quit) shows up on the default system menu bar, but it is grayed out. How can I modify my app to bind to that Cmd-Q option so I can treat it the same as clicking the red button at the top right of my dialog (which exits the app)?

The original post is here.

The answer from Tierra about switching to a wxFrame instead of a wxDialog was a part of the puzzle (thank you!), but the quit item still didn’t work. Once I had a wxFrame I could then attach the default menu items (in the constructor where all the dialog controls are being created):

wxMenu* helpMenu = new wxMenu();
helpMenu->Append(wxID_HELP);
helpMenu->Append(wxID_ABOUT);
wxMenuBar* menuBar = new wxMenuBar();
menuBar->Append( helpMenu, "&Help" );
SetMenuBar(menuBar);

I also had to connect those buttons to my functions in the event table (my dialog class is called wxKeyboard):

EVT_MENU( wxID_EXIT, wxKeyboard::OnExit )
EVT_MENU( wxID_ABOUT, wxKeyboard::OnInfo )
EVT_MENU( wxID_HELP, wxKeyboard::OnHelp )

Once that was done, I had an about menu item, a help menu item, and the quit item magically appeared and worked as intended. In addition, the “About” menu entry appeared under the application menu and not the help menu, but I had to add it to a menu in order for it to show up.