LowRes Coder Framework

6

SP4CEBAR 2024-07-15 10:18 (Edited)

A framework to simulate the original LowRes Coder

in its graphics, sound, and IO.


Open In Editor
                      

Currently, it supports gamepad, sprites, sound, and it has its raster effects installed.

Porting guide:

  1. Remove the demo code from the "your code" section.
  2. Add a label (named whatever you like as long as it doesn't interfere with other labels) and a RETURN to the "your code" section and add a GOSUB call to your label from the first few lines of this framework to this section.
  3. copy your LowRes code to the "your code" section of the program.
  4. replace each LowRes Coder command like "DEF SPRITE" with a subprogram call prefixed with "LR_" like "CALL LR_DEF_SPRITE()" See instructions below:

Which Commands Should Be Translated

How To Translate Commands

Errors

General differences between LowRes NX and LowRes coder

  1. The LowRes Coder syntax is less strict than NX's, here are some examples:
    • In LowRes Coder you can use a variable that has not been initialized, in NX this variable should be initialized with the value zero before it is used.
    • In LowRes Coder it is also okay to add a value to a string, in NX this value should be wrapped in the STR$() function.
  2. you can't pass a function to the ON PAUSE GOTO function, so instead there is a GAME_PAUSED label which is run whenever pause handling is disabled and the game is paused, here you can put your pause handler logic.
  3. I don't know a way to detect the program exit, so the ON END GOTO function can't be made

Based on

Credits

Lowres Framework.nx | Open in app
2025-09-20 12:29
Lowres Framework.nx | Open in app
2024-07-27 20:09
Lowres Framework.nx | Open in app
2024-07-27 19:55
Lowres Framework.nx | Open in app
2024-07-27 18:59
Lowres Framework.nx | Open in app
2024-07-27 09:05
Lowres Framework.nx | Open in app
2024-07-27 01:28
Lowres Framework.nx | Open in app
2024-07-27 00:35
Lowres Framework.nx | Open in app
2024-07-26 23:03
Lowres Framework.nx | Open in app
2024-07-26 22:57
Lowres Framework.nx | Open in app
2024-07-26 22:51
Lowres Framework.nx | Open in app
2024-07-26 21:18
Lowres Framework.nx | Open in app
2024-07-23 21:01
Lowres Framework.nx | Open in app
2024-07-23 20:53
Lowres Framework.nx | Open in app
2024-07-23 13:54
Lowres Framework.nx | Open in app
2024-07-23 11:02
Lowres Framework.nx | Open in app
2024-07-18 11:17
Lowres Framework.nx | Open in app
2024-07-16 15:58
Lowres Framework.nx | Open in app
2024-07-16 15:47
Lowres Framework.nx | Open in app
2024-07-15 11:46
Lowres Framework.nx | Open in app
2024-07-15 10:18

Timo 2024-07-15 10:31

Good luck :O


SP4CEBAR 2024-07-15 11:47

Thanks, I'll need it


SP4CEBAR 2024-07-16 15:45 (Edited)

Update 1

It's tricky to tweak the sound conversion functions because an LFO isn't the same as a sound line, and not all conversion factors are given inside the documentations.

For example, I assume the non-linear LFO rate of NX is an exponential function with a base of ( 18Hz / 0.12Hz ) ^ ( 1 / 15 ) = 1.396602, also I'm not sure what the offset values are of the LFO's pitch and pulse width modulations.

These functions will convert LowRes Coder's sound parameters to NX's:

SUB LOWRES_DEF_SOUND( INSTRUMENT, WAVE_, PULSE, TIME )
  BUFFER_VOICE = 3
  SOUND BUFFER_VOICE, WAVE_, PULSE * 15, TIME * 60
  CALL COPY_INSTRUMENT( BUFFER_VOICE, INSTRUMENT, 0, 4 )
END SUB

SUB LOWRES_DEF_SOUND_LIN( INSTRUMENT, TIME, PITCH, PULSE )
  IF TIME <= 0 THEN EXIT SUB
  BASE_FREQUENCY   = 0.12
  TOP_FREQUENCY    = 18
  FREQUENCY        = 1 / TIME
  EXPONENTIAL_BASE = ( TOP_FREQUENCY / BASE_FREQUENCY ) ^ ( 1 / 15 )
  'EXPONENTIAL_BASE = 1.396602
  LFO_RATE         = LOG( FREQUENCY / BASE_FREQUENCY ) / LOG( EXPONENTIAL_BASE )
  PITCH            = PITCH
  PULSE            = PULSE * 2
  'PULSE = 0
  IS_NEGATED = PULSE <= 0 AND PITCH <= 0
  CALL CLAMP( LFO_RATE, 0, 15 )
  CALL CLAMP( PITCH   , 0, 15 )
  CALL CLAMP( PULSE   , 0, 15 )
  BUFFER_VOICE = 3
  LFO BUFFER_VOICE, LFO_RATE, PITCH,, PULSE
  LFO WAVE 3, 1, ABS( IS_NEGATED ), 1, 1
  CALL COPY_INSTRUMENT( BUFFER_VOICE, INSTRUMENT, 4, 3 )
END SUB

SUB CLAMP( V, L, H )
  V = MAX( L, MIN( H, V ) )
END SUB


SP4CEBAR 2024-07-16 16:09 (Edited)

Update 2


SP4CEBAR 2024-07-18 10:08

I think LowRes Coder's parallax scroller is a good benchmark and demo for this project.


SP4CEBAR 2024-07-18 11:25 (Edited)

Update 3


SP4CEBAR 2024-07-23 11:03 (Edited)

Update 4


SP4CEBAR 2024-07-23 13:55 (Edited)

Update 5


was8bit 2024-07-23 14:31

Try testing with this ;)

Mule...nx | Open in app
2024-07-23 14:31

SP4CEBAR 2024-07-23 15:12 (Edited)

Cool game! I think the LowRes Galaxy and the Parallax scroller will be plenty to test the main features of this library. Once this library works, I may look into sophisticated programs like yours.

The main challenges with developing this library are:

  1. The limited amount of character ROM
  2. The large screen size of sprites (especially in lower resolutions)
  3. The processing speed of NX (it has to perform a lot of tasks)
  4. The tokens (apparently it requires a lot of code)


was8bit 2024-07-23 15:22

:)


SP4CEBAR 2024-07-23 15:35 (Edited)

Interestingly, LowRes Coder's 0.04 second smallest wait time is only 25 frames per second, and LowRes Galaxy even uses a 0.05 second wait time (20 fps) so performance shouldn't be that much of a problem anymore as it has two or three frames available for one game loop.
The disadvantage is that the user's tap controls don't work that well yet with all those delays


SP4CEBAR 2024-07-23 16:17 (Edited)

I just noticed that LowRes coder's tap only starts to miss some taps when the delay is at least 0.08 seconds, which is twice the minimum, this is easier to implement


SP4CEBAR 2024-07-23 20:56 (Edited)

Update 6


SP4CEBAR 2024-07-23 21:02 (Edited)

Update 7


SP4CEBAR 2024-07-23 21:07

If you leave the song playing for long enough, eventually the sound queues become full, and it struggles with playing.


SP4CEBAR 2024-07-23 21:12 (Edited)

Project phases:

  1. Fixed-pixel-size backgrounds (no zooming efforts)
  2. Character RAM optimizations and multiple backgrounds (lower resolutions allow for even more backgrounds, also large sprites can be used as background layers )
  3. Sprites and further character RAM optimizations
  4. Zooming efforts with raster scrolling
  5. optimizations for huge sprites at low resolutions


SP4CEBAR 2024-07-26 21:22 (Edited)

Update 8


SP4CEBAR 2024-07-26 22:52 (Edited)

Update 9


SP4CEBAR 2024-07-26 22:58 (Edited)

Update 10


SP4CEBAR 2024-07-26 23:03

Update 11


SP4CEBAR 2024-07-27 00:38 (Edited)

Update 12


SP4CEBAR 2024-07-27 00:54

14857 tokens :)


SP4CEBAR 2024-07-27 01:29

Update 13


SP4CEBAR 2024-07-27 09:09

Update 14:


SP4CEBAR 2024-07-27 14:42 (Edited)

It is important that none of the subprograms modify any of the parameters passed to them as this will return a value which may modify a variable and alter the working of the LowRes program, or worse, it may modify a passed constant like OMIT_T

The subprograms shouldn't but might


SP4CEBAR 2024-07-27 19:00

Update 15


SP4CEBAR 2024-07-27 19:59 (Edited)

Update 16


SP4CEBAR 2024-07-27 20:10

Update 17


SP4CEBAR 2024-07-27 21:22

To do

  1. fix LowRes SCROLL
  2. work on flood fill add the PAINT command


SP4CEBAR 2024-07-28 16:10 (Edited)

The SCROLL CLEAR buffer (the lower text in the demo) is one ahead of the original (the upper text), so I think that my copying code always moves it one pixel to the left. Two copies cause a motion of two pixels to the left


Timo 2024-07-28 21:45

Seems like this little project went slightly out of control and became giant :O
Anyway, its results look interesting :)


SP4CEBAR 2024-07-29 10:31

I think so too... Thank you!


TrashCan Games 2024-07-31 09:08

This is really cool, Ill definitely get some cool uses out of this. I might try port some lowres coder programs over like stoners delight


SP4CEBAR 2024-08-01 19:16 (Edited)

Thank you!
Don't expect it to work as well though, certain features may be incomplete or missing, I can't guarantee that sprites work at all, user input should work, and most background graphics should work, but there may be some hidden bugs.
Anyways, good luck porting :)


SP4CEBAR 2024-11-18 17:26 (Edited)

I just browsed through the code and thought I could save some tokens by removing unrelated graphics API functions and making general shape-drawing functions: a parametric plotter and an area-between-two-math-functions plotter.

The new tokens could be used for an implementation of the PAINT command


SP4CEBAR 2025-08-30 21:26 (Edited)

I think the "LOWRES_" prefix is better shortened to "LR_" to give more headroom in the naming and reduce clutter


SP4CEBAR 2025-09-20 12:34 (Edited)

Update 18

Table of renamed keywords:

from to
LOWRES_SPRITE_PALETT LR_SPRITE_PALETTE
LOWRES_TEXT_CLEAR_OF LR_TEXT_CLEAR_OFF
LOWRES_DEF_SOUND_LIN LR_DEF_SOUND_LINE
LOWRES_PER_STR_SAVE LR_PERSIST_STR_SAVE
LOWRES_PER_ARR_SAVE LR_PERSIST_DIM_SAVE
LOWRES_PERSIST_ARRAY LR_PERSIST_DIM


SP4CEBAR 2025-09-20 16:39 (Edited)

Update 19 - various fixes related to graphics:

  1. The PIXEL_COPY subprogram was a big culprit
    • it is used to correct a correction (COPYO3) of a messy complicated subprogram (CCOP60) used for copying pixels without converting them to an intermediary format (is as hard as it sounds), both correction subprograms apply offsets
    1. Fixed the copy offsets (they should be accurate now)
    2. Fixed the fourth and fifth parameters passed to COPYO3. yeah so I passed the wrong parameter along here so you could not specify a target offset anymore and it would always be copied two pixels to the left of the original
  2. I replaced most stuff in LR_SCROLL_CLEAR but it might be about the same as it was before
  3. The WRITE_CHARACTER subprogram writes character data as pixels, it can do this between two cells. However, the right-most cell was allowed to overflow to the next line. This has not crashed the program yet, but it did cause trouble as these pixels were not accessible to certain other graphics functions with stronger input protection, such as my BAR subprogram, which is used to draw a solid bar, and in this case, had to be able to clear the character. Given that it could not clear the last pixel of the troublesome "Y" character, streaks would form each time a character's pixels were copied, and these would not go away.
    • While writing this, I noticed that this means that the copy function is will still read some pixels beyond the boundary, I already did some tests but I could not shrink the boundary as text will allready start to be cut off.
    • Imagine NX's 256 characters in GFX'designer's character map. Now divide this into four equally-sized squares. That is how the 4-layer graphics are done (these conveniently fit in a max-sized sprite. While programming, I noticed that many of my graphics subprograms don't check if their coordinates are within their character "sub-space" (of 8 by 8 characters). This may cause issues where oversized graphics commands may "leak" pixels into neighboring layers, but we'll have to see how big of a problem this will really be.
      • Given the code from this demo:
        CALL LR_LAYER_OPEN( 0,128,64,0 )
        CALL LR_LAYER_OPEN( 1,128,64,1 )
        CALL LR_LAYER_OPEN( 2,128,64,1 )
        CALL LR_LAYER_OPEN( 3,72,10,1 )

        It is not so strange that input protection is quite essential (each of my layers only has a resolution of 64x64)


SP4CEBAR 2025-09-20 17:12 (Edited)

Version 20 - sprite is different than background


SP4CEBAR 2025-09-20 17:20 (Edited)

To make this Parallax Scroller demo work, all it needs is:

  1. The PAINT command that can flood-fill areas (current progress)
  2. Better color and palette management

When it works, it's time for the next demo, which would be LowRes Galaxy (which I already ported to the framework a while ago)


Log in to reply.