AutoHotKey

AutoHotKey is a free and open-source macro utility for Windows. It can help greatly with automating repetitive, one-off tasks, especially with GUI programs that don’t have built-in CLI automation or batch scripting. Your mileage may vary, as not all programs will accept the virtual input events that AHK generates. That said, it’s quite nice when everything works.

 

Quick scripting notes

; comments begin with a semicolon
^!q::
    ; Trigger label example for key input
    ; ^ = CTRL
    ; ! = ALT
    ; q = the 'Q' key

    ; Let's send some keyboard input with some delays.
    Send,Let's cut and paste.
    Sleep, 250
    Send,{Shift Down}{Home}{Shift Up}
    Sleep, 250
    Send,{Control Down}x{Control Up}
    Sleep, 250
    Send,{Enter}{Enter}{Enter}
    Sleep, 250
    Send,{Control Down}v{Control Up}
    Sleep, 250
    Send,{Enter}{Enter}Tada!

    ; Finish a block with 'Return'
Return

 

Transfer “Untitled” Notepad text to Notepad++

My old job required me to take notes often, and quickly, during troubleshooting sessions. Here is a script I used at the end of the day to transfer the contents of all untitled Notepad instances to Notepad++, a program that can be configured to autosave everything upon closing.

Maybe this was a bad habit, and I should have just typed stuff into NP++ directly, but I found it easier while on calls / remote sessions to just hit Win+R, type notepad, and start typing away. I set NP++ as the default program for txt files, so I could tell at a glance that if something was written in Notepad, then it was fresh information from that day.

I wasn’t able to make this script perfect (it’s time-sensitive: it will screw up if your system is lagging due to slow disk access, for example), and I have neither AuthoHotKey nor Notepad++ at my current job, so this is provided as-is with no warranty.

; copy all notepad files called "Untitled" to new files in notepad++ which
; will autosave upon closure. Based on AHK help file examples.
; v1.3 2016/19/Feb

^+!s::
    ; Go no further if Notepad++ is not running.
    IfWinNotExist ahk_class Notepad++
    {
        MsgBox, Notepad++ process not found.
        Return
    }
    npp_is_running := 1

    ; Confirm run
    MsgBox, 4, , Copy contents of all "Untitled - Notepad" instances to Notepad++? This will overwrite your clipboard state. Do not execute if a remote desktop session is running.
    IfMsgBox, NO, Return

    ; Get a list of all windows
    WinGet, id, list,,, Program Manager
 
    ; Iterate through windows
    Loop, %id%
    {
 
        ; If Notepad++ crashed or something, stop.
        IfWinNotExist ahk_class Notepad++
        {
            npp_is_running := 0
            Break
        }

        ; Right now this will jump focus to every window.
        ; WIP: There must be a way to skip over programs that aren't "Untitled - Notepad".
        this_id := id%A_Index%
        WinActivate, ahk_id %this_id%
        WinGetClass, this_class, ahk_id %this_id%
        WinGetTitle, this_title, ahk_id %this_id%
 
        ; Work on this window if it's "Untitled - Notepad"
        if (this_title="Untitled - Notepad")
        {
            ; Sleep ten seconds.
            ; Adjust appropriately to match the performance of your PC.
            ; (Mine would be crawling by the end of the day.)
            Sleep, 10000
 
            ; Select all
            Send, {Ctrl Down}a{Ctrl Up}
 
            ; Cut
            Send, {Ctrl Down}x{Ctrl Up}
 
            ; Close window
            Send, {Alt Down}{F4}{Alt Up}
 
            ; Switch to Notepad++
            WinActivate, ahk_class Notepad++
            WinWaitActive, ahk_class Notepad++
 
            ; Sleep half a second 
            ; Increase if your PC is sloooowwwww
            Sleep, 500

            ; New Notepad++ tab
            Send, {Ctrl Down}n{Ctrl Up}
 
            ; Paste
            Send, {Ctrl Down}v{Ctrl Up}
         }
    }
 
    if npp_is_running = 0
    {
        MsgBox, Notepad++ process not found.
        Return
    }
 
    ; Switch focus to Notepad++ upon completion
    WinActivate, ahk_class Notepad++
    WinWaitActive, ahk_class Notepad++
Return

 

(e: 15/Sept/2016: Formatting)
(e: 27/Nov/2016: Notepad to Notepad++ transfer script)

GraphicsGale

GraphicsGale is a lightweight pixel art and animation program for Windows. Originally split between a paid and freeware version, the program is now 100% freeware.

One of the best features of GraphicGale is that it supports hotkey bindings for most editing commands. For example, here are some bindings I have configured — while not the most ergonomic layout, it’s burned into my muscle memory at this point:

* Frame *
Add                       : Insert
Insert into Left          : Shift + Insert
Duplicate                 : Home
Delete                    : End
Forward Frame             : X
Back Frame                : Z

* Layer *
Next Layer                : Shift + Up Arrow
Previous Layer            : Shift + Down Arrow
Reverse Visibility        : Shift + Right Arrow
Reverse Vis. w/ Same Name : Ctrl + Shift + Right Arrow

* Palette *
Swap Color                : /

* Edit *
Paste New Image           : Ctrl + Shift + V

* View *
Zoom in                   : W
Zoom out                  : S
Zoom in (Resize window)   : Shift + W
Zoom out (Resize window)  : Shift + S
Grid                      : G
Snap (to grid)            : B
Frame                     : 1
Layer                     : 2
Palette                   : 3
Preview                   : 4
Loupe                     : 5

* Image *
Flip Horizontal           : Shift + H
Flip Vertical             : Shift + V
Rotate by 90 Degrees      : Shift + R
Count Colors Used         : Shift + C

* All Frames *
Rotate                    : Ctrl + Shift + R
Crop                      : Crtl + /
Adjust Color              : Shift + A
Color Depth               : Shift + Z

The program is pretty reliable and I have stuck with it in spite of a few issues:

  • As far as I can tell, as of V2.03.21, there is no import/export settings feature. If you move to a new PC, you have to export a registry key from your old OS and import it into your new OS, or else configure all the shortcuts by hand again. GraphicsGale comes with only basic shortcut keys defined by default, so it’s not uncommon for a user to come up with their own keybindings for their specific workflow. (Update — As of July 4 2017, a portable version is also available which writes configuration to a file.)
  • Resource footprint is very light under normal circumstances, but performance does not scale well with larger image files.
    • Alpha channels can bog down performance on big images. If you don’t need alpha transparency on the image you’re working on, select ‘Image -> Delete Alpha Channel’. ‘Print Screen’ captures of the Desktop often have an unnecessary alpha layer.

Here is the procedure for exporting and importing shortcuts from the Windows Registry: http://blkmkt.net/post/75096068469/graphics-gale-backup

I’ll write some more here if I can think of anything additional to add. Also, here is a post about defining alpha channel sprite masks.

(e 22/Jun/2017: wording; GraphicsGale is now Freeware.)
(e 23/Jun/2017: added my hotkey binding scheme.)
(e 8/Jul/2017: performance note re: alpha channel on large images.)
(e 18/Jul/2017: I missed that there is now a portable version with its own config file.)

Sound Effect generators: sfxr and its forks

Here are some free and easy-to-use tools for constructing non-realistic sound effects in games. For now, this is mainly about DrPetter’s sfxr and some forks of the program.

sfxr

sfxr by DrPetter is a free and open-source tool for generating simple video game sound effects. Designed for game jams, it provides a lot of quick and accessible features for building wave file samples from primitive waveforms. There are seven pre-defined template generators (pickup, shoot, explosion, etc), one purely random generator, one mutator option, and several sliders to control specific parameters of the sound effect.

sfxr is used most often in smaller indie and retro games, and quick usage of the template generators is often easy to spot. That said, you can use sfxr to produce basic WAV samples, then refine them in other editors like Audacity or tracker programs.

sfxr Fork with CLI support

todo – investigate this fork with CLI batch export support.

Bfxr

Bfxr by increpare is a more powerful fork of sfxr, runnable in a browser or as an Adobe AIR application.

Chiptone

Chiptone is a browser-based, WIP sound effect editor by SFB games. Like Bfxr, it expands significantly on the kinds of sounds that can be produced. The interface is more fleshed out and less spartan than that of the *xfr’s.

usfxr for Unity

usfxr by zeh is a fork for Unity that can play back sound effects on-demand, without requiring exporting to WAV. I haven’t gotten into the Unity ecosystem, but being able to make subtle differences in SFX without needing to export all variations of the sound as WAV files is pretty appealing.

 

edit 30/Aug/2016 – added Chiptone

WikidPad 2.2 Administration Notes

WikidPad is an open-source Desktop Wiki that I’ve used to consolidate personal notes. This post describes some adjustments to WikidPad’s default settings that I prefer, and some quick housecleaning and formatting reminders.

I’m using WikidPad version 2.2 for Windows.

(Note: As of Sept/2017, I’m migrating my notes from WikidPad over to Zim. I’ll keep this post up, but future additions are unlikely.)

The main thing you need to know to get started with the program is that CamelCase words and phrases enclosed in [square brackets] will act as links to new pages. Press Ctrl+Shift+Space to toggle between the monospace Editor Mode and the more readable Viewer Mode. Changes autosave periodically.

One weakness of the program is that the larger a page is, the longer it takes Editor Mode to apply all formatting. Long pieces of monospace text are probably better suited to another program, unless you are proactive in breaking up your notes into subsections.

1: Initial Setup of WikidPad and Wikis

Initial Post-Install Configuration of the program

Enable web broswer-style middle-click to close page tabs

  • From the menu bar, select Extra -> Options -> Mouse.
  • Set Middle Click on Tab to Close Tab.

 

Do not add spaces between CamelCase words in page titles

Do this if you are annoyed by “CamelCase” words becoming “Camel Case” in the page title. Existing pages with spaces will not be affected, but newly made pages will not have spaces.

  • From menu bar, select Extra -> Options -> Current Wiki -> Headings.
  • Set Wiki word to heading to As is.

 

To enable CTRL+F Finding in the Viewer: Change the preview renderer to Internet Explorer.

The built-in renderer does not support CTRL+F finding on a single page. You can use IE instead:

  • From the menu bar, select Extra -> Options… -> HTML Preview/Export.
  • Set Preview Renderer to IE.
  • Click OK and restart WikidPad.

I’ve had some intermittent issues with the IE renderer showing a 404 Error when switching to Viewer Mode. Toggling modes quickly or refreshing the page clears it.

 

Initial Setup of a Wiki

Disable CamelCase linked words

By default, CamelCase words will automatically be wiki-links. This is convenient, but may be a problem if you work with terminology that involves this kind of casing often.

  • Add this to your WikiSettings node: [global.camelCaseWordsEnabled: false]

 

Set the background color to something off-white

  • Add this to WikiSettings[global.html.bgcolor: _your_color_here_ ]

You can use a predefined color (ex: WHEAT), or HTML hex color format (ex: #F5F5FF)See Format -> Color Name for a list of predefined colors.

Press CTRL+S in Editor Mode to push the color change out immediately.

  • You can also change text color, if desired: [global.html.textcolor: BLACK]

 

2: Housecleaning

Deleting parentless nodes

These are pages that are not linked to in any other page.

  • When in Editor Mode, hold Ctrl+Shift+Up for a list of articles that have no parent/child link relationship. A small dialog box will appear.
  • Double-click a node to open it up in the editor to check if anything you want to keep is in there.
  • Ctrl+click to highlight the nodes you wish to remove. WikidPad won’t allow you to delete the top-level root node.
  • Click Delete.

wikidpad_parentless_nodes

 

3: Formatting And Media

Insert monospace font

<code>Use the HTML code tag.</code>

Use the HTML code tag.

Use a different font size

<p style=”font-size:11px”>You can use CSS inside of tags.</p>

<code style=”font-size:11px”>Also works with the <code> tags.</code>

 

Insert non-trimmed whitespace into <code> blocks

Use ‘&nbsp;‘ (non-blocking space)

1 2  3   4    5     6

 

Tables

Here is an example of the table syntax. Note that in order to define an empty cell, there needs to be at least one text character present.

<<|
Example|Table|Header|Field
1|2|3|4
2|4|6|8
3|6| |12
>>

wikidpad_table

 

Add a real HTTP hyperlink

“http://” will make a link clickable. You can also use the HTML anchor tag.

Not clickable: www.example.com

Clickable: http://www.example.com or https://www.example.com

<a href=”http://www.example.com/”>Anchor example</a>

 

Add a picture

WikidPad uses a file store to keep track of media in a given wiki — see here for more details. You can add files via drag-and-drop, or you can place them in the file store manually and then create references in your nodes. Here is the syntax for linking from the file store:

[rel://files/admin_notes/picture.jpg]

 

Alignment

You can use HTML div align tags with external renderers or in exported HTML Wikis. The internal renderer may have issues processing alignment tags.

<div align=center>Text In The Middle</div>

 

Add an automated Table of Contents to a page

The [:toc:] tag in Viewer Mode expands to a linked table of contents based on the page’s headers.

Be careful about inserting formatting and HTML tags within the headers, as they will be repeated verbatim in the table of contents. For example, if you start an HMTL tag within a header, you need to close it on that same line.

(e 17/Sept/2017: Rewording. Added note that future edits to this post are unlikely.)

Platformer Project: Plans vs Reality

I’ve been fleshing out an idea for an action-platformer over the past couple of months.

I may have made a mistake in planning too much before I even have a working engine prototype. My ideas seem fairly solid in my head and in my graphical mockups, but that don’t mean nothin’ until I can come up with tangible examples. The only way to truly find out if my plans can stand up is to make it real.

Part of the holdup has been down to me reading up on Python and doing the Python Codecademy course, and testing some different media frameworks and game engines. (Of course, procrastination, laziness, playing other video games, sometimes actually being busy, and occasionally just getting sick of the project are also playing their part.)

I’ve decided to commit to a free and cross-platform framework called LÖVE (or love2d) because it’s easy to dive into and the API is well-documented. It’s really impressive software that fills the 2D game / rapid prototyping / game jam niche very well.  My initial tests on Fedora 23 are very good, and I’m hoping to check out the Raspberry Pi port and see if I can get NTSC composite output for my game — it would be pretty awesome to actually support NTSC 4:3 on a real CRT, and not just the typical scanline shader effects that some retro games use. In any case, major kudos to the developers of LÖVE for making a solid product.

Before venturing too far into development, I need to read up on Lua, the language and embedded VM environment that LÖVE provides for game logic.

Some of my fears while fleshing out this idea:

  • It’s a retro pixel art platformer, and everyone is vehemently sick of those now. I find the format easy to work with and to do mockups in.
  • I want a very narrow set of actions and attacks, and to explore them in various ways. With the exception of health extensions, what you start with is essentially what you end with. I could see players rejecting this as a lack of features.
  • I can probably handle SFX, but I have no music resources.
  • From a long-term perspective, this is probably a bad self-investment because it’s likely not going to take me anywhere. But I can’t get the idea out of my head. I want this thing to be a reality.

Well, enough with the gloom. I’ll post some more about the project once I have something tangible to report. In the meantime, I’m drafting up some articles about some different platformers, but these will take some time to produce as I want to take screenshots and make some animations to illustrate certain points.

Raspberry Pi 2 Composite video

This is a note-to-self on outputting Raspberry Pi 2 (RPi) audio/video to CRT NTSC televisions with Raspbian OS via NOOBS. This was much easier than I thought it was going to be — the Retropie distribution even worked immediately.

RPi 2 combines analog audio and video onto the same port. You need a TRRS cable with the correct pinout that splits into yellow, white and red cables — a normal single yellow cable won’t work. There is a Zune AV cable which is known to work, but it’s pretty expensive and there are also much cheaper cables available as well.

Plug the TRRS cable in and make sure HDMI is unplugged, and then power up the RPI 2. If it doesn’t work immediately, Try making the following changes to the boot config (you can SSH into the RPi 2 over your LAN while testing) :

sudo nano /boot/config.txt

  • Comment out hdmi_force_hotplug=1.
  • NOOBS may add a second instance of this line at the bottom of the config file, comment that out as well. Save and exit nano, and reboot.

If you’re hunting for an old glass tube television, check whether you can change the video input from the front control panel. Some models require a remote control to do that and access the menu.

 

Links

RPi post about RCA: https://www.raspberrypi.org/forums/viewtopic.php?f=91&t=82560

Using an alligator pin for video out: http://www.instructables.com/id/Raspberry-Pi-2-Quick-n-Easy-RCA/

Element14 forum thread on RPi 2 RCA output: https://www.element14.com/community/thread/43364/l/raspberry-pi-2-av-output-via-rca-question?displayFullThread=true

Sprite masking with alpha channels in GraphicsGale (edit: added Python + Pillow script)

Edit: I made a quick-and-dirty Python 3 / Pillow script for applying color key-style alpha channel masks, it can be grabbed here.

I’ve been messing around with Kivy lately, and it seems that there is not a direct method of doing color key transparency in Kivy + OpenGL. No problem: alpha transparency is much more powerful and can be used for my archaic purposes.

blog-transparency

I haven’t worked much with alpha channels in the art package that I use, GraphicsGale. The best solution is probably to loop through the pixels of the texture upon loading or refreshing it in your program, and apply alpha if the color key RGB is detected. In any case, here is how to apply an alpha channel in a color key stencil fashion to 24bpp Full Color PNGs in GraphicsGale:

  • Choose the color picker tool (blue square with a yellow oval) and click on an empty / transparent space in your sprite sheet.

sprite-alpha2

  • Choose View -> Make Alpha Channel…
  • Create From: Current Selection
  • Source: (should be the current file — double check)
  • Check Invert Selection and click OK.
  • When you save the file, use Save As… and ensure that “With Alpha Channel” is checked.

You should now have a stencil alpha layer which you can toggle in GraphicsGale with the “a” button on the current layer. If you’ve tweaked art and need to remake the alpha layer, goto Image -> Delete Alpha Channel and then repeat the steps above.

 

Links

  • Alpha channel notes from an artist working with GraphicsGale and Adventure Game Studio. His example images have expired, unfortunately, but there is some interesting info about drawing in Opacity Mode.

Odallus: The Dark Call under Wine

Here are some quick notes on getting Odallus: The Dark Call working with Wine in Linux. I played about half of the game on Windows, and the rest under Wine. The only major annoying issue was occasional frame-drop stuttering, which happens on my Windows desktop as well.

(I am not an experienced Wine user, so some of my notes might be fixable — this is just what I had to do to get it working. Reference links at the bottom of the post.)

Fedora 23 64-bit
Wine 1.9.12
Steam client in Wine
Odallus 1.1.0 via Steam in Wine
Antimicro input wrapper

I haven’t tested other versions (for example, the version on GOG.com) but I assume they are the same build.

Set Windowed Mode: The game doesn’t seem to go into fullscreen mode properly. By extension, TV Mode (the CRT display filter) doesn’t work either. Windowed mode magnified x2 or x3 ran OK for me.

Gamepad crash: The game crashes after the “seizure warning” screen, a few seconds after startup. Having game controllers enabled in Wine seems to be the cause of this crash. The workaround is to disable all gamepads in the Wine Control Panel, and then use a gamepad-to-keyboard input wrapper if you want to continue using a controller.

Enter wine control into a terminal to get to the Game Controllers screen:

odallus_wine1 odallus_wine2

Sometimes laptop accelerometers are detected as game controllers — if anything like that shows up in the Wine Game Controllers panel, disable it as well.

To restore controller input, you can use an input wrapper like Antimicro (on Fedora, can be found and installed directly in ‘Software’)

Other Stuff

  • It’s worth mentioning that Odallus’s keyboard input seems to be more responsive than the built-in gamepad support (specifically, when transitioning from a run to a crouch), so an input wrapper like Antimicro is something that may be desired even on Windows. I have not personally been able to get a wrapper to work perfectly on Windows, though — I suspect conflicts with the built-in gamepad polling. I left a post on the Steam forums to check if there is any way to just disable the native gamepad input.
  • I’ve noticed one other crash in the launcher — clicking on the “Scores” button — but this isn’t a critical function of the game.
  • If you’re curious: M.I.S. in the options menu is probably Machine Independent Speed, which is a frame-dropping mode in Clickteam game engines. I left it disabled.

Links

https://appdb.winehq.org/objectManager.php?sClass=version&iId=32538

https://steamcommunity.com/app/319480/discussions/0/535152276589076748/

https://www.gog.com/forum/odallus_the_dark_call/odallus_in_wine

Python 3.4, Kivy 1.9.1, Windows 10: Crashes in programs with audio that are exported with PyInstaller

Problem: Launching Issues with exported Kivy programs for Windows that use audio (per this guide). The PyInstaller process completes and an EXE is produced, but the program crashes upon using audio functions. No issues are encountered when running the .py file directly.

Console output from failure to start:

C:\igapp\dist\expprog>expprog
[INFO              ] [Logger      ] Record log in C:\Users\tmd\.kivy\logs\kivy_16-06-03_96.txt
[INFO              ] [Kivy        ] v1.9.1
[INFO              ] [Python      ] v3.4.4 (v3.4.4:737efcadf5a6, Dec 20 2015, 20:20:57) [MSC v.1600 64 bit (AMD64)]
[INFO              ] [Factory     ] 179 symbols loaded
[INFO              ] [Image       ] Providers: img_tex, img_dds, img_gif, img_sdl2 (img_pil, img_ffpyplayer ignored)
[INFO              ] [Text        ] Provider: sdl2
[INFO              ] [AudioGstplayer] Using Gstreamer 1.4.5.0
[INFO              ] [Audio       ] Providers: audio_gstplayer, audio_sdl2 (audio_ffpyplayer ignored)
Traceback (most recent call last):
File "G:\p\MyProgram\MyProgram.py", line 25, in <module>
sounds.append(SoundLoader.load("data\\snd\\%s" % file))
File "c:\python34\lib\site-packages\kivy\core\audio\__init__.py", line 83, in load
return classobj(source=filename)
File "c:\python34\lib\site-packages\kivy\core\audio\audio_gstplayer.py", line 45, in __init__
super(SoundGstplayer, self).__init__(**kwargs)
File "kivy\_event.pyx", line 273, in kivy._event.EventDispatcher.__init__ (kivy\_event.c:5348)
File "kivy\properties.pyx", line 408, in kivy.properties.Property.__set__ (kivy\properties.c:5114)
File "kivy\properties.pyx", line 446, in kivy.properties.Property.set (kivy\properties.c:5876)
File "kivy\properties.pyx", line 501, in kivy.properties.Property.dispatch (kivy\properties.c:6557)
File "kivy\_event.pyx", line 1224, in kivy._event.EventObservers.dispatch (kivy\_event.c:13497)
File "kivy\_event.pyx", line 1130, in kivy._event.EventObservers._dispatch (kivy\_event.c:12696)
File "c:\python34\lib\site-packages\kivy\core\audio\__init__.py", line 161, in on_source
self.load()
File "c:\python34\lib\site-packages\kivy\core\audio\audio_gstplayer.py", line 62, in load
self.player.load()
File "kivy\lib\gstplayer\_gstplayer.pyx", line 233, in kivy.lib.gstplayer._gstplayer.GstPlayer.load (kivy\lib/gstplayer\_gstplayer.c:2791)
kivy.lib.gstplayer._gstplayer.GstPlayerException: Unable to create a playbin
Failed to execute script MyProgram

Workaround: try changing the audio provider to SDL2.

Set the Kivy audio environment variable in the py source file prior to importing any Kivy modules:

import os
os.environ['KIVY_AUDIO'] = 'sdl2'