English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Asm / Hardware

 
 
Thread Tools
Old 20 October 2013, 17:08   #1
Mrs Beanbag
Glastonbridge Software
 
Mrs Beanbag's Avatar
 
Join Date: Jan 2012
Location: Edinburgh/Scotland
Posts: 2,243
Neat coding style and good habits

Lately I've been doing a complete overhaul of my game's entire source code. What a job! I wish I'd known more about computer science when I started, it could have saved me so much work. It has really driven home to me the importance of coding style for code maintainability (as well as the importance of comments, especially in asm, and I never thought I'd need them ) and programming professionally in higher-level languages has got me into good habits, and thinking about structure. A bowl of spaghetti is not a structure!

So I wondered if anyone has any style tips or rules they like to follow when coding in Asm on the Amiga?

Some rules I've started putting into practice so far include:
Naming conventions for functions. Use underscore in labels to implement "namespaces" so you know immediately which of your include files your functions are in when you see a call.

Stop using DC statements to create data zones inside the code (i.e. global variables). Use RS and allocate space for structures dynamically, or put things on the stack.

Start labels with underscore to indicate private methods. Well they are not really private! But this is how Python does it too, so I heard, which was a nice coincidence.

Dynamic destructors! I put a pointer to a destructor subroutine at the start of every allocated memory block, which my delete function calls before freeing the memory.

Generally I try to think how I would structure my code if I were writing in C++.

The last trick I pulled was to implement exception handling. I have a little "throw" routine that looks as follows:
Code:
throw
    move.l (SP)+,A0
    cmp.w  #$4AFC,(A0)
    bne.s  throw
    jmp    2(A0)
so I can push exception handlers (which begin $4AFC i.e. ILLEGAL instruction) on the stack whenever I put data objects on there and make sure everything gets cleaned up. Exception handlers either RTS to catch the exception or simply throw again to pass it up another level.

I recently learned what the instructions LINK and UNLK are for. I never used a register for a stack frame before, and I'm still just accessing stack objects via SP. I don't have any address registers left for such a purpose, but C compilers use this and I can see how it could make things more convenient. Exception handling could be even neater but the above works for now.

Does anybody have any favourite ways of doing things that make things easier or neater? I'd love to hear them!
Mrs Beanbag is offline  
Old 20 October 2013, 18:48   #2
Thorham
Computer Nerd
 
Thorham's Avatar
 
Join Date: Sep 2007
Location: Rotterdam/Netherlands
Age: 47
Posts: 3,764
When using structures, I write them like you would in higher level languages such as C#:
Code:
;
; structures
;
                rsreset
list.firstNode  rs.l    1
list.lastNode   rs.l    1
struct.list     rs.l    1

;
; method names
;
list.new
list.free
list.addNode
list.insertNode
list.deleteNode
Other than that, use real tabs, not spaces, and use a tab size of four instead of eight when possible (AsmOne and AsmPro sadly don't allow this). Use case sensitivity. I also try to avoid using underscores, because they're annoying to type. Stick labels on their own line, and don't use more than one tab for indentation.
Thorham is offline  
Old 20 October 2013, 23:51   #3
Mrs Beanbag
Glastonbridge Software
 
Mrs Beanbag's Avatar
 
Join Date: Jan 2012
Location: Edinburgh/Scotland
Posts: 2,243
For some reason I never considered using dots in label names. Maybe because you can't actually do that in C, for obvious reasons. I use local labels but that seems "special".

A long time ago I controversially chose a tab size of 10. 8 seemed a bit cramped, but then I was in the habit of putting labels and code on the same line.
Mrs Beanbag is offline  
Old 21 October 2013, 03:36   #4
Leffmann
 
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
This is an interesting topic I think a lot about. When I came back to Amiga a few years ago I immediately saw how antiquated my Amiga programming habits were, and that I had been stuck in this 1989 year's lump-all-code-into-a-single-file way of doing things. Some good tips:

1. Use the best tools you can find
Use a scriptable editor and proper command line tools such as vasm, basm, phxass or genam (Devpac), and a linker, f.ex vlink, phxlnk or blink.

IDEs like Seka, ASM-One and Maxxon Assembler are great for learning and doing quick tests, but really bad for writing actual programs. They are single-file assemblers that try to be monolothic and offer the All-In-One Total Assembly Experience™, but instead end up coaxing you into bad practices by forcing you to structure your program as a single massive file, resulting in poor reusability, longer build-times, and eventually a completely unmanageable code base.


2. Automate the build procedure
Use tools like GNU Make to automate, enhance and speed up the build procedure. This way you don't have to open your programs and drag, select and click your way through menus and buttons every time you've changed an image or sound file. Don't do repetitive manual work if you can automate it with a bit of code.

Languages like Python and Lua are great for writing simple tools to convert files or generate data tables, and you can even run them on classic Amigas. Even AmigaDOS scripts can help a long way.


3. Make full use of the assembler
The whole point of using an assembler is to make machine language programming tolerable. Make use of macros, auto-optimization and other convenient features. Don't use the assembler like a simple machine code monitor.

Enhance the assembler and abstract messy syntaxes using macros:
Code:
 macro gfxcall
  xref    _LVO\1
  move.l  _GfxBase, a6
  jsr     _LVO\1(a6)
 endm

 macro cwaitv
  dc.b  \1, 1, $ff, 0
 endm

 macro cmove
  dc.w  \2, \1
 endm
Eliminate annoying local labels and common errors in branch logic (vasm is probably the only assembler that can do this fully):
Code:
 macro if_equal
  bne  .\@!
 endm

 macro else_if
  bra  .\@?
.\@@
 endm

 macro end_if
.\@@
 endm
Use short instruction forms and let the assembler do the lifting and optimizations, that's what it's for, this way you get to type less, and get cleaner code.
Code:
   ; Crufty

   movea.l  (data, pc), a1
   lea.l    (-400, a0), a0
   bsr.b    X
   cmpi.l   #100, d1
   bne.b    .nope
   bsr.w    func1
   bra.b    .ok
.nope:
   bsr.w    func2
.ok:
Code:
   ; Clean

   move.l   data, a1
   sub      #400, a0
   bsr      X
   cmp.l    #100, d1
   if_equal
    bsr     func1
   else_if
    bsr     func2
   end_if

4. Use meaningful symbolic names
Use meaningful names for things like constants and offsets, instead of magic numbers that obfuscate the code.
Code:
; Bad

move.l  4, a6
move.l  (156, a6), a6                 ; what's here?
jsr     -270(a6)                      ; what?
move.w  #%1101001110010010, $dff09a   ; what does this do?
move.w  #$c3f9, $dff096               ; launch missiles?

dc.l    $3201ff00   ; lots of digits
dc.l    $01800128
dc.l    $fa01ff00
dc.l    $01800000
dc.l    $fffffffe
Code:
; Good

gfxcall  WaitTOF                           ; call WaitTOF in graphics.library
move.w   #int_clr|int_en, intena           ; disable interrupts
move.w   #dma_set|dma_en|dma_all, dmacon   ; enable all DMA

cwaitv   50
cmove    $128, color00   ; easy to understand Copper program
cwaitv   250
cmove    $000, color00
cend
Leffmann is offline  
Old 21 October 2013, 10:57   #5
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,500
I can only agree with most what was written here. In bigger assembly projects (let's say a game) it is mandatory to follow some coding style. Lots of comments in the source and structuring by blank lines and/or ";------" makes it more readable. Use symbols for everything, so you can change them easily in a single place. Also, like Leffmann indicated, I would spread the source over many small modules. For example one for the game engine, one for the display-setup and copper, one for trackdisk routines, one for sound effects, one for the protracker player, one for BOB-handling, one for scrolling, etc.

Even when you write absolute code you should use sections to keep code, data und uninitialized data together, which will give you some advantages. The code will usually stay small enough to allow 16-bit branches this way, and you could implement a small data section, which you access through a base register. Also Chip-RAM data can easily be separated from the rest of the program.

When the resulting program is no AmigaDOS executable but has to be loaded to an abosolute address, use a linker script to define the location of each section in memory.

An example of coding style from my current game project "Solid Gold". The beginning of the scroll.asm module:
Code:
*
* Written by Frank Wille in 2013.
*
* I, the copyright holder of this work, hereby release it into the
* public domain. This applies worldwide.
*
* set_scroll_pos(d0.w=xpos, d1.w=ypos)
* $scroll(a5=View)
* d2.w=xpos, d3.w=ypos, d4.w=ypos%BMAPH = $copper_scroll(a5=View)
* $moveView(d0.w=xpos, d1.w=ypos)
* load_copperback(d0.w=fileID)
*

        include "custom.i"
        include "display.i"
        include "scroll.i"
        include "view.i"
        include "map.i"  
        include "macros.i"


; from loader.asm
        xref    td_loadcr

; from main.asm
        xref    ovflowerr
        xref    loaderr  

; from blit.asm
        xref    YOffTab

; from tiles.asm
        xref    RowOffTab
        xref    Tiles

; from map.asm
        xref    Map
        xref    FgMap
        xref    MapWidth
        xref    MapHeight
        xref    ScrWidth 
        xref    ScrHeight
        xref    MapRowOffTab



        near    a4

        code


;---------------------------------------------------------------------------
        xdef    set_scroll_pos
set_scroll_pos:
; Set the map position of the top-left display edge.
; Warning: Needs to be followed by copper_scroll() and draw_tiles(),
; which redraws the whole bitmap. scroll() is for small movements only!
; d0 = xpos.w
; d1 = ypos.w

        move.l  d2,a0
        moveq   #0,d2
        move.w  d1,d2
        divu    #BMAPH,d2
        swap    d2
        movem.w d0-d2,Xpos(a4)          ; initialize Xpos, Ypos, Ymod
        move.l  a0,d2

        ; determine our position on the copper background
        move.l  CopperbarTab(a4),a1
        subq.l  #4,a1
        asr.w   #1,d1
        move.w  d1,CbackPos(a4)
.1:     addq.l  #4,a1
        move.w  (a1),d0
        sub.w   d0,d1  
        bpl     .1     
        move.l  a1,CbackPtr(a4)
        add.w   d0,d1
        move.w  d1,CbackOffs(a4)
        rts


;---------------------------------------------------------------------------
        xdef    scroll
scroll:
; Scroll the View to match the current MapX/MapY coordinates.
; a5 = View
; Registers, except a4 - a6, are not preserved!

        bsr     copper_scroll

        ; Load/update View position
        movem.w Vxpos(a5),d0-d1
        movem.w d2-d3,Vxpos(a5)

        bra     blitter_scroll


;---------------------------------------------------------------------------
; Horizontal scroll codes for BPLCON1, xpos 0..15
ScrollTab:
        dc.w    $0000,$00ff,$00ee,$00dd,$00cc,$00bb,$00aa,$0099
        dc.w    $0088,$0077,$0066,$0055,$0044,$0033,$0022,$0011
...
The header has an overview of all funtions and symbols which are exported by this module. Then follow the includes and the external references to other modules. Each routine should have a header with a short information what it is doing and the registers being passed and returned.

Label will start with a lower case character when it is a function. Data labels will always start with an upper case character.

Usually I try to follow the 68k C-ABI, which defines registers d0-d1 and a0-a1 as volatile. The rest must be saved and restored. Exceptions (for performance reasons ) have to be mentioned in the function header.

Last edited by phx; 21 October 2013 at 11:34. Reason: Mention label naming convention.
phx is offline  
Old 21 October 2013, 14:18   #6
Mrs Beanbag
Glastonbridge Software
 
Mrs Beanbag's Avatar
 
Join Date: Jan 2012
Location: Edinburgh/Scotland
Posts: 2,243
Quote:
Originally Posted by Leffmann View Post
This way you don't have to open your programs and drag, select and click your way through menus and buttons every time you've changed an image or sound file.
I always load images and sounds from disk rather than including them as binary in the project, makes changing things very easy without re-assembling anything. In the code I only tend to store things like static strings and tables of constants (like the sine table), although eventually I'd like to externalise all the text so I can create language packs. It seems a good idea generally to separate the data and the functionality, another habit I got from professional programming.

In fact in Mr Beanbag any code that is specific to an individual game level (for instance to generate the copper list) is also loaded in dynamically. Although I'm now trying to do that with whole game worlds, and I'm faced with the formidable task of working out how to do dynamic linking, since the world handler will need to call functions in the main executable!

Level handlers already have access to a small jump table via an address register so they can draw bobs &c. but I need something more comprehensive so I can add new functionality easily without worrying about breaking anything.
Mrs Beanbag is offline  
Old 23 October 2013, 01:04   #7
Leffmann
 
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
What I meant to say was that if you can find an existing command line tool or write a bit of code yourself to f.ex convert IFF images to raw format, then that automatization is to prefer over manually clicking around in some GUI-based tool each and every time the graphics have changed.

Loading data from disk is a good idea, and you can even use an overlaid executable to put all those files in the executable, but not load them until you need to. Personally I would put any data that is required for the whole duration of the program directly into the executable anyway.
Leffmann is offline  
Old 23 October 2013, 10:44   #8
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,500
Quote:
Originally Posted by Mrs Beanbag View Post
In fact in Mr Beanbag any code that is specific to an individual game level (for instance to generate the copper list) is also loaded in dynamically. Although I'm now trying to do that with whole game worlds, and I'm faced with the formidable task of working out how to do dynamic linking, since the world handler will need to call functions in the main executable!
I would try to avoid the reloading of code. If you absolutely want to do that and link it dynamically with the main program, then a jump table should suffice.
For everything more complex, like using real dynamic linking, you would probably have to write a linker yourself, or modify an existing one.
For Sqrxz and Solid Gold I added a new format to vlink, which can output segments (e.g. Chip-RAM and Fast-RAM) controlled by a linker script. It also writes a simple relocation table on demand (1st word number of relocs, followed by n reloc offsets) for each segment, which I use to relocate my program when starting it out of the boot block.
phx is offline  
Old 23 October 2013, 11:21   #9
Mrs Beanbag
Glastonbridge Software
 
Mrs Beanbag's Avatar
 
Join Date: Jan 2012
Location: Edinburgh/Scotland
Posts: 2,243
currently thinking about writing a macro that maintains external jumps in a linked list, that I can traverse on loading the module, look up the references and replace them.

Something like
Code:
xjmp    MACRO
        dc.w    $4EF9
xj_\@   dc.w    xj_last-xj_\@
        dc.w    \1-xj_\@
xj_last set xj_\@
        ENDM
example use
Code:
    xjmp   myFunc

myFunc
    dc.b    "myFunc",0
Mrs Beanbag is offline  
Old 23 October 2013, 14:27   #10
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,500
Interesting technique, although you still have to define all these cross module calls manually. I assume you also have a kind of linked list for exporting function labels?

Your usage of the SET directive might cause different results with different assemblers. AsmOne, A68k and vasm will use the value of the last xj_last in the source for the first reference to it (making the difference 0 in your example with a single entry). So it would result in a circular linked list. Barfly, Devpac and PhxAss will print an error.
phx is offline  
Old 23 October 2013, 14:37   #11
Mrs Beanbag
Glastonbridge Software
 
Mrs Beanbag's Avatar
 
Join Date: Jan 2012
Location: Edinburgh/Scotland
Posts: 2,243
I didn't mention it but I was going to put with something like
Code:
xj_begin  dc.l 0
xj_last set xj_begin
at the start of the module, and there would have to be a link to the last entry somewhere because the list would have to be traversed in reverse order.

Last edited by Mrs Beanbag; 23 October 2013 at 14:43.
Mrs Beanbag is offline  
Old 24 October 2013, 22:32   #12
Lonewolf10
AMOS Extensions Developer
 
Lonewolf10's Avatar
 
Join Date: Jun 2007
Location: near Cambridge, UK
Age: 44
Posts: 1,924
Some interesting tips here. I agree with most. I certainly have started using macro's more in my current project and certainly need to stop using dc.w's etc.

When I'm debugging I always comment out the code I think is causing the problem and NEVER delete it until I'm sure the problem is fixed. Also, any modifications are put inside what I call an 'asterisk field' so I can clearly see new code vs. original code:
(yes, I know some assemblers will automatically correct the following code, but I couldn't think of a decent example in such a short time)

Code:
'bne.w  jump1
***\
bne.l  jump1
***/
and subroutines should have a clear header indicating what it does and what registers need to be set before jumping into it.

Code:
***************************************************************************
*                        C L E A R   S C R E E N                          *
***************************************************************************
;	INPUT:	a0.l = destination address
;		d0.w = modulo (e.g 36 for LowRes)
;		d1.w = size of area, in BLTSIZE format (%hhhhhhhhhhwwwwww)
;
;	OUTPUT: None
***************************************************************************
Lonewolf10 is offline  
Old 13 February 2015, 01:46   #13
Nekoniaow
Banned
 
Join Date: Dec 2014
Location: Montreal
Posts: 129
This is more a general remark than an assembler specific one but one should always use source control.
With something like Git (or Perforce, which is free for personal non commercial use) you should push every single version of your code which compiles. This is a tremendous help when you need to figure out what exactly is it that you changed which broke your program about ten compilations before or just want to revert to a working, validated version.

It's also helpful if you want to do several experiments and keep them for easy comparison: branches will allow you to modify the same code safely in isolated repositories which you can later merge back to the main branch once you have made your choice.
Nekoniaow is offline  
Old 13 February 2015, 10:45   #14
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,500
Quote:
Originally Posted by Nekoniaow View Post
This is more a general remark than an assembler specific one but one should always use source control.
Good point. There is really no reason not to do it. I have all my projects in a revision control system since more than 10 years, but I'm not using it in the early development phase of a new project, when all files are touched every few minutes.

It also saves you from doing backups, provided the revision control system is on an external server which does automatic backups itself.

Quote:
With something like Git (or Perforce, which is free for personal non commercial use) you should push every single version of your code which compiles.
The choice of the revision control system is a matter of taste. In my opinion Git is overly complicated for your personal small Amiga projects. You will also rarely need the "distributed" feature of Git. Usually a simple cvs or svn server does all you will ever need.

You may also not like to push your code onto a public server. Most people already have a NAS or a small Unix server which can be used locally for that purpose.
phx is offline  
Old 13 February 2015, 10:48   #15
StingRay
move.l #$c0ff33,throat
 
StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,863
Quote:
Originally Posted by phx View Post
Usually a simple cvs or svn server does all you will ever need.
I agree, I am using a local SVN repository for my projects and it's working pretty well. But it's a matter of taste indeed, the perfect version control system does not and never will exist.
StingRay is offline  
Old 14 February 2015, 18:15   #16
Mrs Beanbag
Glastonbridge Software
 
Mrs Beanbag's Avatar
 
Join Date: Jan 2012
Location: Edinburgh/Scotland
Posts: 2,243
so you can get SVN and/or Git for Amiga? I would have problems using it because my Amiga thinks it's permanently 1992.
Mrs Beanbag is offline  
Old 15 February 2015, 04:09   #17
Photon
Moderator
 
Photon's Avatar
 
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,604
Quote:
Originally Posted by Leffmann View Post
What I meant to say was that if you can find an existing command line tool or write a bit of code yourself to f.ex convert IFF images to raw format, then that automatization is to prefer over manually clicking around in some GUI-based tool each and every time the graphics have changed.

Loading data from disk is a good idea, and you can even use an overlaid executable to put all those files in the executable, but not load them until you need to. Personally I would put any data that is required for the whole duration of the program directly into the executable anyway.
Agree, and (dunno if you meant this) an IFF loader is more useful than an automated IFF to raw converter tool. I did one back in the day which also scanned the pic for markers to cut out bobs, make masks, and index them for animation, but nowadays I think that's overkill.

Also agree with Stingray. For my own part, I don't trust any version control system, I use versionitis instead. Which is to make incessant backups, naming the files with details, and also have changelogs in the files themselves, and reminders what I was doing so I can pick it up at any time.

And it still doesn't work. There's no way Or, well, the best way would be to just update the files in one go until the project is finished, but it's sort of incompatible with "a smattering of available timeslots for coding".

As an interesting point, it's when you do the overhauls (that are oh so innocent, just going to refactor this symbol or change a register globally) that you get hard-to-find bugs. "It's somewhere in there..."

I have some basic things I do, which is mostly for consistency and ease of use/readability and not for project management:
- colon after labels, so I can search for the actual routine and not occurrences of calls...
- case insensitivity, so I don't have to look how I cased some symbol last time. For a source release I turn it on. Maybe.
- macro names are caps, symbols are initial caps, local labels lowercase
- straightforward names for symbols. just saves headscratching for some strange AbbrCamelC label
- I comment too much. I know it's really good when you pick it up again, and well... I just do it. I do refrain from juvenile comments such as "BRAs should be eliminated, girl coders agree" nowadays. I think. If you find one sue me
- variables that need initial values anyway I put as DC near the functions that use them. Unnecessary DS+initalization routines that are not called is just a too common reason for bugs. Plus it saves code.
- some consistent styling of comments that is mostly for pretty presentation and not important.

I think the only important tip I can (maybe?) contribute is to lock finished code into includes to only leave pertinent implementation code visible for editing. And should you ever change a common include, you make a fork (for me: copy include to project folder before changing).

Last edited by Photon; 15 February 2015 at 04:15.
Photon is offline  
Old 15 February 2015, 07:14   #18
Nekoniaow
Banned
 
Join Date: Dec 2014
Location: Montreal
Posts: 129
Quote:
Originally Posted by Photon View Post
Also agree with Stingray. For my own part, I don't trust any version control system, I use versionitis instead.
Why do you mention trust? I am not sure I understand what you mean.

They archive changes in an easily accessible manner which can be visualized graphically to show evolving diffs and timelapses. They just automate what you call "versionitis" in a much more convenient way.

I have been using revision control systems for 14 years and there's no way I would go back, they allow me to reserve my brain cells for coding without being distracted by logging and tracking. Just as I leave the assembling of code to my assembler I leave the logging of my changes to the revision control system.

Quote:
As an interesting point, it's when you do the overhauls (that are oh so innocent, just going to refactor this symbol or change a register globally) that you get hard-to-find bugs. "It's somewhere in there..."
That's when the RCSes are particularly useful: Git allows you to do a dichotomic search of your changes to find you at which revision a problem was introduced. Doing it manually is possible but tedious and super error prone, with Git, it's just one command, a compilation + test, another command to select the other alternative of the dichotomy, a compilation + test, etc. until you have found it. And to return to your last changes another simple command and you're back to work.
And you don't have anything to copy or any worries about mixing several revisions together by mistake.

Quote:
Originally Posted by Mrs Beanbag View Post
so you can get SVN and/or Git for Amiga? I would have problems using it because my Amiga thinks it's permanently 1992.
I would not use SVN. It was very popular one decade ago as the kinda successor to CVS (which is a nightmare IMO) but it is not very efficient and does not track merges properly (*). Git is very efficient and reliable and does a fantastic job while still being very easy to use: if you don't need its advanced branching features you can just use it as you would SVN or CVS except that it's much faster and reliable.
SVN will work nicely for simple work but at some point you will want to use branches because they are a very convenient tool and that's where it will stab you in the back.

It should be relatively simple to compile a version of Git for the Amiga using GCC. I don't think it should have any issue to run at decent speeds since it was designed to be fast.

Also, I'm not sure RCSes require a coherent system time. Perforce doesn't care about it and just keeps tracks of your submissions to the server and Git likely does the same kind of bookkeeping internally, I doubt it relies on the time of operations, only on their ordering.

(*) My company used SVN around 2007 and we lost a considerable amount of time because of its design issues when dealing with branch merges and the fact that it was dog slow (for our needs: several MBs of code per branch). I pushed them hard to switch to Perforce and although they were hesitant at the beginning they never regretted it. It's robust and reliable and blazingly fast.

Last edited by TCD; 15 February 2015 at 09:17. Reason: Back-to-back posts merged.
Nekoniaow is offline  
Old 15 February 2015, 21:16   #19
IFW
Moderator
 
IFW's Avatar
 
Join Date: Jan 2003
Location: ...
Age: 52
Posts: 1,838
Actually with the amount of assets we had for our games, converting IFF images on the fly would have been a nightmare, and completely unfeasible due to the extra number of disks required plus the extra amount of memory the game would have needed for buffering. Some of the assets were hundreds of KBs animated IFFs, so just recycling one of the off-screen buffers while clipping and converting the image would not have been possible without asking for a minimum of 1.5MB memory instead of 1MB.

Instead, we used to have a script driven converter that could generate anything we wanted using still pictures as well as animated IFFs etc, remove/add bitplanes (can save a lot of memory), play with masks, clip the graphics area to the minimum required size (and add information about the missing lines and rows so they could be re-generated) and so on... very cool stuff for its time.
All it took to generate anything was to run the tool via DOpus and click on the script filename, which in turn could process any number of graphics files.

Everything else mentioned in this thread was in place as well, out of necessity, ie using linker with separate object files, RS structures, tons of macros that somewhat resembled C code etc.
We also had an in-game scripting for the entire game logic - otherwise it would have been a complete nightmare to create RPG games in assembly language, since those require a huge amount of game logic.
IFW is offline  
Old 15 February 2015, 21:26   #20
IFW
Moderator
 
IFW's Avatar
 
Join Date: Jan 2003
Location: ...
Age: 52
Posts: 1,838
Actually, we made everything we used to run from DOpus and scriptable, including converting the assets, compiling (from make files), compressing the assets/data/code, and creating master disks - and doing test runs of the new code from hard disk or floppy disk(s).
Debug code would return to DOpus once we quit from the running code (assuming it wouldn't crash...) while release code would never return.

So we made DOpus our complete IDE
IFW is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Neat idea - borderless WinUAE and Amiga wallpaper Bloodwych Amiga scene 8 12 January 2011 23:58
2000 - black screen... Chips good... PSU good... chiark support.Hardware 45 09 January 2009 05:41
Mitser Org'oeil, good platformer in old style s2325 Retrogaming General Discussion 2 23 November 2008 21:58
good retro racer in Lotus/Outrun style s2325 Retrogaming General Discussion 4 27 May 2007 20:57
very good new racing PC game in old style s2325 Retrogaming General Discussion 1 20 February 2007 22:34

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 09:20.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.11060 seconds with 13 queries