Have suddenly realised I'm busy for most of the rest of the week, but I do intend to return with full code for this tiny segment of my stuff as soon as it is ready. In the meantime:
Quote:
This won't run on a Master, so probably best avoided.
The program won't run on any BBC, so I'm not bothered by that. It's no more Electron-specific than the code that disables all uninteresting interrupts, for example (as I don't think the OS has an entry point for that sort of stuff?), and the other code that subsequently reads the keyboard. So I just need to remember to flag this stuff up so that I can find it later should I want to do a BBC port.
Quote:
I know this routine is only called once, but if you wanted to speed it up a bit more, I think the best way is from 2 32 byte lookup tables which return the LSB and MSB of the screen address of each row
Smart move. And it's used much more than it looks, being essentially a copy and paste from my pixel plotter. And 32 bytes isn't exactly a bother, even if it actually were 32 bytes and not 32 bytes – (saved instructions * 2).
Quote:
You can check whether it has crossed a boundary simply by testing the zero flag after the lsr pixelmask+1 (it will be zero if you have shifted the last bit out).
Neat spot! I will vainly pretend that it would have occurred to me.
Quote:
Using pha...pla to preserve A around a block of code is not optimal; you get slightly better performance from storing to a zp location and loading it back
Shouldn't both alternative be 3 cycles?
Quote:
Another possible optimisation in the routine where dx > dy might be to only do the lda/ora/sta to screen memory when you are moving to the next byte
Oh, yes. I've just switched back to the 6502 from the z80 and haven't fully mentally adjusted. I don't think my thinking went beyond "can't keep it in a register, will have to leave it in memory", never got to "should keep it in faster memory, move it out to slower later". Which I guess doesn't just refer to addressing mode access speeds as any users with a turbo board get 2Mhz access on the areas below where the OS tends to put the screen, 1Mhz above, so I might as well be mindful of them.
Quote:
Oh, and another small point - you might find that the routine is more useful if it doesn't plot the final point in the line, since the end point of one line is most likely the start point of another.
Yep, yep. I'm an OpenGL programmer mostly (ES usually, since I now do iPhone full time), so completely au fait with the diamond exit rule. I just hadn't stopped to think how Bresenham maps onto that. I guess I'll need to be a bit careful in that if I'm always flipping coords so that x1 is to the left of x2 where the line is wider than it it tall then I may well be switching which is the last pixel before entering the substantial drawing.
Quote:
Doing this, you might even be able to use EOR plotting and use the same routine to plot and unplot (like Elite)!
I'm not 100% certain exactly what the plotting loop will look like yet. I was thinking I'd go for a separate blanking routine that is allowed to blank arbitrarily many pixels of the 3d area as long as it gets at least the ones on the line, which I think would allow me to divide the x resolution by 8 and write whole 0 bytes (or, rather, pairs of them owing to rounding) at a time. But I accept that with EORing a shape you have the obvious advantage that when you're drawing the next frame you can calculate one object, update that object, calculate the next object, etc, to give a better feeling of movement versus the limited expected framerate. I guess you could even update the player position every frame, update objects only on alternate frames, etc. Not sure which would look less disorientating.
Quote:
Another nice little 6502 trick; if you want to negate a value in A, you can do it a bit more quickly like this:
Oh, neat. It hadn't occurred to me that I know that carry isn't set from the comparison immediately above.
Quote:
If it's a full 3D game, then probably you will hold your vertex coordinates as 16-bit values anyway.
It's not really anything in particular, just a mess around, maybe get together some maths and plotting routines that I like. The same approach left me with a full 3d engine on a z80 machine (video below), but I've no actual aims and it isn't meant to be a port of that code.
That said, my prior approach (for an Elite-style view) was (1) map user into object space, determine face visibility; (2) from face visibility determine line visibility; (3) clip each line in 3d space; (4) project vertices and draw. Separate objects are much, much smaller than the space they inhabit, meaning that I can use optimised table-based multiplication (f(x) = (x^2)/4, unoriginally) most of the time and break out the full precision stuff very rarely.
EDIT: forgot the video, and it seems my memory is faulty if I believe that you can embed videos here:
http://www.youtube.com/watch?v=j0xN_Mi3B_I