Currently I'm using ASM6 and trying to parse the code into small files which I can easily reuse for other projects. But refactoring is extremely difficult and time consuming in this case.
"update", "buffer", "metasprite", "multiply", etc.
Then cut and paste from old file to new.
I happen to be fortunate, as I put a large chunk of example code on github, organized by subject. I can find 99% of what I'm looking up in seconds.
Then, each subroutine, interrupt handler and data table is in a separate file. Subroutines and data tables used only by one subroutine may stay in that subroutine's file instead of getting their own (they're basically local to that specific subroutine). Local variables are declared in each subroutine's file. Parameters are local variables with global aliases.
Subroutine and table names are always prefixed by the name of the module they belong to (e.g. Level_MoveCamera). Parameter names (aliases) are prefixed by their subroutine's name (e.g. Level_MoveCamera_OffsetX). If a subroutine has different entry points, they're prefixed by the base subroutine name (e.g. Video_DecompressTiles_ToVRAM and Video_DecompressTiles_ToRAM).
All subroutines, interrupt handlers and data tables are included in the main file in the desired order to form the final ROM. I have separate folders for code (subroutines and interrupt handlers), tables and binary files. Binary files are not included directly in the main file, they have to be included in a data table file where they can be properly labeled.
Can you show an example? I'm not happy with the solution I've been using for locals and parameters, but I don't 100% know what you mean by this.tokumaru wrote:Local variables are declared in each subroutine's file. Parameters are local variables with global aliases.
It makes the build scripts more complicated, but in a big project, you'll thank yourself for it later when editing your assets for the millionth time.
Here's what one of my routines could look in ASM6:samophlange wrote:Can you show an example? I'm not happy with the solution I've been using for locals and parameters, but I don't 100% know what you mean by this.tokumaru wrote:Local variables are declared in each subroutine's file. Parameters are local variables with global aliases.
Code: Select all
DoSomething = $ ;using this instead of a regular label allows me to include the same subroutine in multiple banks .enum System_Scratchpad ;use a region in ZP reserved for local variables DoSomething_FirstParameter = $ ;global alias for the first parameter -FirstParameter .dsb 1 ;use temporary labels for the local variables DoSomething_SecondParameter = $ ;global alias for the second parameter -SecondParameter .dsb 2 -LocalVariable0 .dsb 2 -LocalVariable1 .dsb 1 DoSomething_ReturnValue0 = $ ;global alias for the first return value -ReturnValue0 .dsb 2 DoSomething_ReturnValue1 = $ ;global alias for the second return value -ReturnValue1 .dsb 1 DoSomething_LocalEnd = $ ;marks the end of the memory used by the subroutine .ende ;do something clc lda -FirstParameter adc -SecondParameter+0 sta -ReturnValue0+0 lda -SecondParameter+1 adc #$00 sta -ReturnValue0+1 rts ;return
Anyway, the "DoSomething_LocalEnd" label is there in case you want to run this subroutine concurrently with others. Since they'll have to share the scratchpad RAM, instead of starting the locals from "System_Scratchpad" in a concurrent subroutine, you can start from "DoSomething_LocalEnd" (e.g. .enum DoSomething_LocalEnd) and you'll be sure they won't overwrite each other's variables.
Yeah, definitely automate as much as you can so you don't have to constantly tweak things by hand after every little change.gauauu wrote:keep all assets in as developer-friendly format as possible. (I keep graphics in png format, maps in an easily-editable text format, metasprite definitions in a custom easy-to-edit format) Then do the necessary conversions at build time. That way you're not endlessly doing exports and copying/pasting data from tool exports.
For example, mtpaint isn't amazing, but it's very lightweight and doesn't think it knows better than you when it comes to paletted images.
Personally, I just work in greyscale.
I personally prefer to work with 24-bit color images though, since not many programs handle indexed color images properly these days. I try to encode the palettes and other information (sprite size, etc.) in the image itself, do I don't need a bunch of command line arguments to perform the conversions.
For making and reusing ASM its best to make your "routines" into macros that allow you to specify temp variables, bank etc this way you can do a lot of includes somewhere and forget about it. If you use a decent assembler you can also use .proc to handle such things.
Games to long enough to write that when you want a routine you know from the last game you just go and get it and copy and paste, then modify it suit what the current game needs, as this will probably be done once every 2 years or so..
For such images it best to use something designed for the task, Deluxe Paint or its clones such as GrafX2, Pro Motion (NG) these give you direct pallete control, decent export options and in some cases will hold you to the machines limits in terms of colour placement etc.