Author Topic: Richtris — a Rich Tetris® Visualization Tool  (Read 214 times)

furious programming

  • Sr. Member
  • ****
  • Posts: 468
  • I click a little.
    • TreeStructInfo — format for text and binary configuration files
Richtris — a Rich Tetris® Visualization Tool
« on: September 01, 2020, 05:14:20 am »
A few months ago I finished work on the Richtris tool. The works took about two months. This tool is a window program that is used to visualize in real time my NES Tetris games that I train on the FCEUX emulator. Thanks to this, I can not only present my games in an interesting way (on my channel), but also have access to additional information that the original game does not show.

Unfortunately, Richtris is a private project that I don't want to publish, because it may turn into a commercial product in the near future. But since it is made entirely in pure Free Pascal, I would like to show it off and share my knowledge and bits of code if someone is interested in implementing a similar program (or if is curious how it works).

In this thread, I will describe how this tool works and what functions it has in addition to those of the original game. For simplicity, I will call my program the "tool" and FCEUX the "emulator". It's going to be a long post, so enjoy. 8)


Richtris is an ordinary window program (without any components) that has one window spread across the entire desktop (laptop + monitor). On boot, it loads data from files and starts the emulator as an external process. When the emulator window appears, the tool removes its border and places it in the center of the laptop screen. Then a side thread implementing the scanner is started, whose task is to read information from the emulator window (recognition of scenes and their content), update the logic and render the visualization in the center of the monitor screen.


This topic seems complicated, but it is very simple. Instead of taking a screenshot of the emulator and then reading the text with OCR and the shapes using complicated and time-consuming methods, the tool checks the colors of pixels in each frame, whose coordinates and colors (samples) are stored in the configuration file.

Reading all the information relevant to a given scene takes extremely short time and it is possible thanks to disabling antialiasing in the emulator video settings. Unfortunately, this method is flawed, because there is a high probability that when testing pixels, the emulator will render a new frame, so that e.g. the read text will be incorrect. Therefore, the logic of the tool is additionally protected against this.


The tool works with a framerate of 50fps (PAL) or 60fps (NTSC), so frames rendering should be effective. Therefore, a back buffer is used, in the form of a regular bitmap, on which the current scene and all data are rendered, and then this buffer is rendered directly on the window canvas.

However, the rendering process is further optimized. Instead of rendering each successive frame from scratch, only those portions of the back buffer that have changed are repainted (the buffer is never cleared). The frame is re-rendered only when the buffer background needs to be repainted.

Thanks to this approach, I was able to use the basic GDI+ without any problems and not worry that the CPU would be overloaded. Everything is done with the methods of the TCanvas class (I don't use any third party graphics library, only LCL classes).


I will not write too much here and divide the functions into two groups (existing in the original game and my own, extending functionality) — I just list them all. There is quite a lot of it.

General functions for all scenes:
  • use my own backgrounds for all scenes of the original game and a pixelated font (dynamically loaded),
  • rendering backgrounds and objects using advanced caching, saving CPU power (using only 24-bit bitmaps),
  • support for two back buffers, allowing to handle up to two scenes simultaneously (needed for transitions from main game scene to the statistics scene, where the transition is animated curtain),
  • preview of pressed controller buttons (reading directly from the system).
Features of title screens and menus:
  • use of slowly blinking captions and items of all menus instead of static texts and fast blinking fields (selection of the level and height of the garbage),
  • support for two vertical menus, instead of one horizontal and one vertical.
Gameplay scene features:
  • preview of the best score for both game modes,
  • rendering of the current point gain, both for cleared lines and only for soft drop points (gain visible three seconds, then disappears or is replaced by a new one in the meantime),
  • high resolution rendering of a stack with a translucent background instead of opaque black,
  • rendering the current score,
  • displaying the point difference of the current pace compared to the one that allows me to beat my personal record,
  • rendering of standard cleared line counters and level number (possibly with garbage height),
  • support for counting more than 25 lines in training mode (the original game counts only up to 25),
  • preview of the next piece,
  • rendering the percentage of tetris in cleared lines,
  • preview of the number of longbars received,
  • preview of the number of burnt lines and the length of the drought,
  • preview of the RNG quality based on the history of the last 10 pieces,
  • animated change of stack frame color and drought counter title and value during drought longer than 12 pieces,
  • flashing the background of the stack after doing a tetris, instead of flashing the entire background around the stack,
  • pause screen support, during which the stack and the next piece disappear, and a blinking text appears,
  • support for the animated curtain as a transition between the game and summary scenes — the curtain works independently of the emulator, so it is displayed both in the marathon mode and in both endings in training mode (including training completion),
Additional features that extend those of the original game:
  • counting all attempts and all max outs for both regional versions (PAL and NTSC),
  • storing of up to 50 best results in marathon mode and no limit to the number of max outs (the original game only stores three and loses them at the end of the session),
  • storing up to 5 highscores in training mode, for each level and each starting garbage height (up to 1,200 total results), whether the level passes or not,
  • all of the above separately for the PAL version and separately for NTSC — up to 2500 results in total,
  • each record consists of:
    • date and time of the game,
    • game id and, if applicable, max out id,
    • the total number of points and the scores during the transformation from level 18 to 19 and from level 28 to 29,
    • final result in NN+M.MM format (needed for global statistics),
    • push down points count,
    • average number of points per line,
    • the number of all droughts and the length of the longest,
    • start and end level numbers,
    • number of lines cleared and burnt,
    • quantitative and percentage share of individual types of line cleares (singles, doubles, triples and tetrises),
    • end values of the counters of individual pieces.
Functions of controlling the emulator with the controller, at any time:
  • the ability to save the game — combination Select+A,
  • the ability to load the game from the slot — Select button,
  • turning on the turbo mode to speed up the emulation — Select+Right combination,
  • turning off the turbo mode and returning to normal emulation speed — Select+Left combination,
  • taking a screenshot on demand — Select+Up combination.
Functions performed automatically:
  • switching the sound on and off (toggle mute) in order to harmonize the emulator scene with the visualization scene,
  • taking screenshots in the background (in the other side thread, so without causing lag) and saving them to files, at several points during the game:
    • when the transition from level 18 to level 19 happened,
    • when the transition from level 28 to level 29 happened,
    • when top-out happened (game over),
    • when max out happened (exceeding a million points),
    • when the curtain unfolds and the game stats are visible.
Additionally, rendering debug information (when debug mode is used):
  • framerate counter, refreshed every second,
  • the percentage of CPU load by the scanner, updated every half second,
  • current scene name.
To enable easy implementation of some functions, the emulator uses two Game Genie codes:
  • ENEOOGEZ — support for counting points over a million (still in the form of a six-character, à la hexadecimal number), because the original game only counts up to 999,999 and at that value the counter freezes,
  • NYSPEZLE — skip the rocket animation that is displayed when the score exceed 30,000 points in marathon mode.


Some little or no meaningful information about the project itself:
  • consists of 19 units and one empty window,
  • contains 1835 identifiers,
  • the total number of lines of code is 13,998 (only code and empty lines, I don't use comments),
  • uses four TreeStructInfo configuration files (my own experimental format) to store settings, records, samples and layout information,
  • release consists of 330 files (including 299 uncompressed bitmaps) and 109 directories, with a total weight of 48MB,
  • executables for both regional versions weigh 2,16MB.


I know it's a bit silly to brag about what I did without publishing the program and its sources, but I wrote before why.

If anyone would like to see how Richtris looks in action, please visit my YouTube channel, where I have published several videos so far. The recordings show only the visualization (without the right part with the emulator), because that's what I needed this tool for. However, in the coming weeks, a video showing my workstation with capturing a laptop and an external monitor (and my hands with the controller) will appear on my channel, so as to show what I see and what I do during training.

In the attachments you will find some screenshots, but if someone has questions related to this project, I will be happy to answer them, explain interesting aspects in more detail, and if someone needs it, I will share some code (but not the entire project).
« Last Edit: September 01, 2020, 05:18:23 am by furious programming »
Lazarus 2.0.10 with FPC 3.2.0 (SVN Revision 63526), Windows XP (all 32-bit)


TinyPortal © 2005-2018