|
Post by christophertumber on Jun 28, 2014 21:32:06 GMT -5
when drawing vectors you want to minimize the number of cycles - so why in your example would you ever choose to use the scale 30 instead of 15? The maximum vector length is (127,127) [or (-127,-127)]. What if you want to draw a line longer than (127,127) and scale 15?
|
|
|
Post by vectrexrc on Jul 1, 2014 18:04:34 GMT -5
this is what i don't understand.
if max draw vector is 127,127
so where is the vector 10,10 at scale 30? 300,300?
would it actually draw that?
is it possible to draw a single vector line from coords -127,0 to 127,0 i thought you have to split it in two.
probably getting my Cartesian points and vectors mixed up here.
|
|
|
Post by christophertumber on Jul 1, 2014 22:26:43 GMT -5
The maximum scale is 255. The maximum length of a vector is 127. The actual length of a line drawn is the product of vector and scale. A vector with a length of 127 drawn at a scale of 255 is approximately the length/height of the screen.
Grab some of the sample line drawing code and compile it for various vector lengths and scales and see the results.
|
|
|
Post by vectrexrc on Jul 2, 2014 18:45:50 GMT -5
I tried this example code:
start: JSR Wait_Recal ; Vectrex BIOS recalibration LDA #$80 ; scaling factor of $80 to A STA VIA_t1_cnt_lo ; move to time 1 lo, this ; means scaling LDA #0 ; to 0 (y) LDB #-120 ; to -120 (x) JSR Moveto_d ; move the vector beam the ; relative position JSR Intensity_5F ; Sets the intensity of the ; vector beam to $5f CLR Vec_Misc_Count ; in order for drawing only 1 ; vector, this must be set to ; 0 LDA #0 LDB #120 JSR Draw_Line_d ; draw the line now bra start
This drew a horizontal line from left hand side of the screen to the centre.
increasing the scale value that is set at the start had no effect, unless if the value was reduced (in that case the line did not start so far to the left).
is there way to make single vector to be drawn across the entire width of the screen?
maybe i am using wrong draw function?
|
|
|
Post by christophertumber on Jul 2, 2014 22:07:32 GMT -5
You're only setting the scale once. Since you want to use different scales you need to set the scale both for the initial move to the left edge of the screen (you are doing this) and then again when you are about to draw (you are not doing this). You are using the same scale for both lines. The first line which is not visible (moveto_d) and the second one which is (Draw_Line_d). This results in a return to center. You're essentially doing A+B-B and then wondering why the result is A...
|
|
|
Post by vectrexrc on Jul 3, 2014 18:43:23 GMT -5
ah great thanks that worked just quick followup question about this... given your comments about trying to minimize the scale size used due to perf impact. would you recommend drawing two lines at scale $80 rather than one line at scale $ff? in case you are wonder why i ask, i have implemented this using double horizontal lines of 127 length with scale $80 www.youtube.com/watch?v=5ydGw_y514Ai am wondering if i should re-implement it using single lines with scale $ff whilst it looks ok in the emulator - on real hardware i see strange appearance of the line "joins" they are not vertically aligned and drift slight across the screen as the lines move down. thinking that single long lines would look better. (edit: actually looking at the code I am not calling Reset0Ref before drawing each set of horizontal lines so maybe i need to do that to resolved the join issue.) still wondering if this animated scrolling effects will have too much impact on the game (cycles). its too early to tell need to do more work... thanks for any advise.
|
|
|
Post by christophertumber on Jul 3, 2014 21:10:29 GMT -5
In cases like that, use a single line - With respect to the timer you're basically asking, "Does it make a difference if I work on this for an hour, or for 2 half hours?" Except by drawing the second line you're probably adding a bunch of unneeded overhead (lda #0 ldb #120 jsr &etc). Especially if you're reset0ref'ing and doing moveto_d a second time (so adding a whole new, unnecessary line).
|
|
|
Post by mikiex on Nov 25, 2014 15:06:27 GMT -5
|
|
|
Post by christophertumber on Nov 25, 2014 15:27:48 GMT -5
In this part:
Reg_To_Decimal: tfr a,b ;transfer a copy of a to b tstb ;test a to check if neg bpl Reg_DA ;branch if plus (positive) nega ;else is negative so negate a to be positive ldb #45 ;"-" sign stb Debug_0 bra Reg_D0
Since you throw b away, the initial tfr is unnecessary. I'd suggest instead:
Reg_To_Decimal: tsta ;test a to check if neg bpl Reg_DA ;branch if plus (positive) nega ;else is negative so negate a to be positive ldb #45 ;"-" sign stb Debug_0 bra Reg_D0
Note that depending on how the number gets into a, you may not need the tsta either...
|
|
|
Post by christophertumber on Nov 25, 2014 15:36:05 GMT -5
You can also optimize this:
Reg_To_Decimal: tfr a,b ;transfer a copy of a to b tstb ;test a to check if neg bpl Reg_DA ;branch if plus (positive) nega ;else is negative so negate a to be positive ldb #45 ;"-" sign stb Debug_0 bra Reg_D0 Reg_DA: ldb #43 ;"+" sign stb Debug_0 Reg_D0:
To this:
Reg_To_Decimal: tfr a,b ;transfer a copy of a to b tstb ;test a to check if neg bpl Reg_DA ;branch if plus (positive) nega ;else is negative so negate a to be positive ldb #45 ;"-" sign bra Reg_D0 Reg_DA: ldb #43 ;"+" sign Reg_D0: stb Debug_0
You do similar repetition in other parts of the code - One general thing to watch out for is when branching is that each branch only does what's actually unique to that branch. And you're not winding up with duplicate sections of code that are only different at one of two discrete points. If they are basically identical, you generally want to do any of three things:
- Bring functionality back into the main path (as above - mostly for simple cases) - Create a subroutine with different parameters (good for conserving code length and readability) - Create a macro with different parameters (good for speed optimization on very frequently called code but tends to result in very large code)
|
|
|
Post by mikiex on Nov 26, 2014 13:27:07 GMT -5
Thanks for looking through it Chris, the first TRF I think was left over from when my code had no test for the sign and I was starting at the first digit, well spotted The other issue of bloating my code with more STA than I needed, yes that looks like a bad habit in this code! I'll edit the code and make a new post!
|
|
|
Post by christophertumber on Nov 26, 2014 14:13:00 GMT -5
So, since you're seldom going to be displaying negative numbers in a game and most scoring systems will go above 127 - How would you display, say, a number from 0 to 65535?
|
|
|
Post by mikiex on Nov 26, 2014 18:02:05 GMT -5
So, since you're seldom going to be displaying negative numbers in a game and most scoring systems will go above 127 - How would you display, say, a number from 0 to 65535? Well this was specifically for debugging values and I thought it was quite neat as you can make quite a few assumptions. I see you're alluding to using a unsigned 16bit number , but I doubt you would use that for scoring either? You be better off using BCD values. I've seen examples of converting bigger numbers by using divide by 10 and using the remainder as each digit... 2539 / 10 = 253 remainder 9 253 / 10 = 25 remainder 3 25 / 10 = 2 remainder 5 2 / 10 = 0 remainder 2
Kind of interesting but very variable in execution time, I found a nice routine that did divide by 10 in shifts less variable but still a lot of shifts. I'm all ears for any tips you can provide.
|
|
alx
Vector Runner
Posts: 10
|
Post by alx on Nov 27, 2014 5:18:33 GMT -5
|
|
|
Post by christophertumber on Nov 27, 2014 12:13:30 GMT -5
I'm all ears for any tips you can provide. I'm just trying to keep conversations going While this forum has a great community, it's always difficult to sustain technical discussions as there's never that many people both coding and wanting to talk about it. BCD is an option with its own trade-offs. Namely RAM. Since you need a byte per digit, a value up to 65535 is six bytes (you can't really get around the $80 terminator) vs two bytes for an unsigned integer. That may not seem like much, but let's say you have a high score table with 10 scores, that's a difference of 40 bytes RAM. This can quickly become a limiting factor, for example if you have different game modes where you want multiple score tables. If you want the flexibility of being able to display larger values, things start to get out of hand. 24-bit unsigned is 3 bytes but 9 bytes in BCD. 32-bit is 11 bytes BCD... To date I've generally not displayed scores during gameplay. This is both for esthetic reasons (cleaner display YMMV) and practical since drawing the score is generally far more cycles than any processing or conversion. If you're not doing any integer to string conversion in real time then any of that overhead is irrelevant (ie; if you're displaying a static high-score table, you can do all conversions before the first frame and never do them again). FWIW, the game I'm working on is using 32-bit unsigned integers for scoring. The conversion for printing is fairly clunky and unoptimized (the algorithm is similar to yours with looped subtractions) but it doesn't need to be as I'm not planning to display during gameplay - printing 11 digits, even using an optimized version of the BIOS pseudo-bitmap routine (ick), is the equivalent to displaying several other sprite objects. Which is what I'd rather use those cycles for. Basically everything you do on these old systems is a trade-off between: RAM use Speed ROM size It's just a matter of where what you're trying to do is going to bump up against these hard limits and how much of a hit the others can take.
|
|