Jump to content

Andrew Davie

  • Content Count

  • Joined

  • Last visited

  • Days Won


Posts posted by Andrew Davie

  1. IIRC, the "Special Edition" was not released as a PD ROM anyway. Might be wrong. But my memory is that it was included as a binary with the Special Edition on CD when you bought it. It's so long ago. In any case, at this point in time only @Albert has my permission to sell/distribute Qb.

    • Like 2

  2. I am in need of $ and will be selling my only remaining copy of Atari 2600 Boulder Dash.

    In excellent/near-new condition, it's only been opened once or twice. I am looking for offers by PM, but will be ballpark around others that have sold.

    However, if you would like, I would be happy to add my signature to this copy, as one of the authors.

    Sad to see it go. Have to put food on the table, though...

    • Like 4
    • Sad 3

  3. Here are my figures for the display/non-display example above...

    38.80 fps (194 frames in 5.00 seconds) 64.7%
    46.40 fps (232 frames in 5.00 seconds) 77.3%

    I'm running on an early 2013 vintage MacBook Pro.


    As to the new display rendering/mode it doesn't play well at all with my particular game, alas.

    I get distracting banding down the screen.


  4. I'm itching to have my hands on the Brazillian PlusCart board with the surface mount components.

    I'd love to be making some stand-alone (auto-boot) carts, and I figure this would only be feasible if I had the boards populated by the manufacturer of the boards themseves. Some offer it as an option.  I'm sick of soldering, frankly.

    So, I'm pretty sure I remember our Brazillian contact promising to make them open source.... any news?

    • Like 1

  5. 19 minutes ago, Thomas Jentzsch said:

    Stella does some coarse counting too. It only counts memory accesses, which should be good enough to detect major overruns. The values are displayed in the debugger's 'States' tab of CDFJ.


    Exact ARM cycle counting is very tricky, it will be very interesting to see how exact Gopher2600 can become.

    It's pretty good now. I'm doing quite a bit of legwork with the ARM during OS and VB, and I'm finding good correlation between Gopher2600 and hardware. It's my "go-to" when I want to see if I have time overruns and more particularly memory access errors. I've found quite a few issues in my code with Gopher that haven't shown up on Stella. 

  6. 1 hour ago, Karl G said:

    It does indeed. I would also be curious to see the one that you say is buggy, but looked cool anyway. 🙂

    I didn't have a demo version but have re-implemented the buggy one... just for you....



    • Like 1

  7. I'm a bit supposed-to-be-doing-schoolwork, but I've been thinking about the above suggestions, and I think I now have a pretty good working concept/solution. Haven't coded, but I'm sure it will work.


    It does work on the basic principle mentioned above that a "pixel" on the screen is either in the circle, or outside, as defined by (x^2 + y ^2) compared to r^2.   If x^2 + y^2 is larger, then the pixel is outside the circle, and so the mask bits should be zero.  I've used this basic principle to simplify the calculations for each pixel, and it goes something like this.


    Choose an arbitrary point on (or off!) the 40 x n screen as our center-point.  Let's make square pixels, so n = scanline/4.  So, something like a 40x40 screen then.  And our Center is Cx, Cy.  And our radius is R2.  To simplify explanation, let's have a 40-bit array representing the PF pixels. Won't worry about the mirroring in this explanation;  just number the bits from 0-39 corresponding to X column on screen. Doesn't matter, just 40 bits side by side.


    Pre-set the 40 bits to 0.

    Init two variables, left_edge and right_edge to Cx.

    These represent the "boundary edge" of the circle on any particular scanline. We start with them being right on the center-point's X position.


    Now we iterate the scanlines.

    But first calculate the squared distance to the center point from this scanline (Cx,0) to (Cx, Cy).  That's stored in "distance_left" and "distance_right".

    When iterating, if distance > R2, then pixel is outside circle, otherwise inside.


    Here's the basic stuff... but just one more addition after this...


    For each scanline {

     (left edge check....)

        while (distance_left < R2 && left_edge > 0) {


          left_edge- = increment

          calculate new distance



    (right edge check...)

        while (distance_right < R2 && right_edge < 40) {


          right_edge+ = increment

          calculate new distance



       if scanline = midpoint of circle, flip increments



    So the above is marching the left and right edges based on the distance from the center point.

    the distance_x values are the (x^2 + y^2) which is basically the (x position of an edge) ^2 + (scanline - Cy)^2)




    Example:  center at 10, 10 and we're drawing scanline 0, with start left_edge = 10 (=Cx)..

    we are looking at the left edge only here. The right edge proceeds in the same fasion...


    x^2 + y^2 = (10-10)^2 + (10-0)^2 

     = 100


    Let's say our desired radius is 11.  So R2 = 121.  This pixel is within the circle

    set bit[x=10], then.


    Now move left one...

    center 10, 10, and drawing line 0 with left_edge = 9 (we've moved left one because last point was inside circle)...

    x^2 + y^2 = (10-9)^2 + (10-0)^2

     = 1^2 + 100

     = 101

    Still in the circle. set bit[9]


    Move left again

    left edge = 8

    x^2 + y^2 = (10-8)^2 + 100

     = 104

    still in circle. set bit[8]


    Move left again

    left edge = 7

    x^2 + y^2 = (10-7)^2 + 100

     = 109

    still in circle. set bit[7]


    MOve left again.

    left edge = 6

    x^2 + y^2 = (10-6)^2 + 100

     = 116

    still in circle. set bit[6]


    Move left again...

    left edge = 5

    x^2 + y^2 = (10-5)^2 + 100

     = 125


    Now that's outside the circle, and we stop iterating.

    We're left with our x value being 5, and proceed to the next scanline.

    We've set bits 10,9,8,7,6


    We KEEP the mask array (40 bits) as we proceed....


    Let's look at the next scanline...  y+1, and x=5

    so distance is 

    x^2 + y^2 = (10-5)^2 + (10-1)^2

     = 25 + 81

     = 106

    That's inside the circle (R2=121) so we set bit[5]


    Move left...

    left edge = 4

    x^2 + y^2 = (10-4)^2 + 81

     = 36 + 81

     = 117

    that's inside again, so set bit [4]


    move left...

    left edge = 3

    x^2 + y^2 = (10-3)^2 + 81

     = 49 + 81

     = 130

    outside circle, so next scanline(2)


    scanline 2...

    x^2 + y^2 = (10-3)^2 + 64

     = 49 + 64

     = 113

    inside circle, set bit[3]


    move left.. left edge = 2

    x^2 + y^2 = (10-2)^2 + 64

     = 128

    outside, so next scanline(3)

    we have bits 10,9,8,7,6,5,4,3 set in the mask.  The right-edge calculation would have set 11,12,13,14,15,16,17


    scanline 3...

    x^2 + y^2 = (10-2)^2 + 49

     = 64 + 49

     = 113

    inside, so set bit[2]


    move left. left edge = 1

    x^2 + y^2 = 81 + 49

     = 130

    outside, so next scanline[4]


    scanline 4...

    x^2 + y^2 = 81 + 36

     = 117

    inside, so set bit[1]


    move left.. left edge = 0

    x^2 + y^2 = 100 + 36

     = 136

    outside, so next scanline[5]


    x^2 + y^2 = 100 + 25

    outside, so next scanline [6]


    x^2 + y^2 = 100 + 16

    inside, so set bit[0]


    ... and since we're at 0 (left edge) we will just be getting "outside" until we're on the scanline of the center point.

    When we reach the center point, we flip the edge's increment direction... instead of left_edge-- it becomes left_edge++, and mirror for the right edge.


    Essentially we do a small number of checks on each scanline, shifting the edges outwards (for the top half of the circle) and inwards (for the lower half) by one pixel at a time, and determining if we are outside/inside the radius^2.  The lower half will be CLEARING mask bits, and the upper half SETTING the bits.  The left edge is bounded from 0..Cx and the right from Cx..39 inclusive.


    Each scanline has a few operations, but mostly the mask is correct from the previous scanline. Just need to "trim the edges".

    Instead of calculating the full X^2 + Y^2 on each line, we know that Y^2 only changes when you change to a new line, and X^2 can be done with a delta.  That is,   X^2 - (X-1)^2 = X^2 - (X^2 - 2X + 1) = 2X + 1 difference in each iteration, so no multiply required, just a shift and add. Same for Y delta, done once on each line. Pls ignore basic error in the maths, it's the principle I'm describing that's important :) 

    This algorithm should allow any size circle with a center point anywhere on or off the screen.  I'll try implementing it when I have some free procrastination time.



















    • Like 1

  8. 53 minutes ago, Thomas Jentzsch said:

    This and 1000 times this!

    I agree, too. It touches tangentially on issues like "how do you find totally trustworthy, reliable play-testers" which is something I've been wondering about. Back in the day, programmers tended not to believe bugs reported by our QA people... so much so that all play-testing was videotaped, so the programmer could be dragged in by the balls and shown the actual bug happening.  All my '2600 efforts have had practically zero external play-testing - and the recent Audacity effort does show the value of a bit of focus on that part of development.  Especially if we want to be "professional" like them.

  9. 18 minutes ago, Dionoid said:

    Not sure if it helps, but for the PF iris in/out effect in my game, I basically divide the screen into tiles of 1x6 playfield pixels, which represent small squares on the screen.


    Thanks for sharing. I was amazed when I first saw that effect in your game, and it was definitely inspiration for me to do something similar. I have grander plans... maybe... like a star-shaped in/out wipe. But I'm not really sure how best to do things yet. I have a functional version of a wipe that's quite buggy - but actually so visually pleasing I'm considering keeping it!

    • Like 1

  10. 44 minutes ago, Omegamatrix said:

    Andrew, I'm trying to understand what you are trying to do, separarte of the implementation.


    Are you actually drawing a circle, or just having a circular boundary of which you want to do some detection of objects being inside or outside of that boundary? Can you describe it a little more?




    I'm trying to create a circular mask so that I can have some parts of the screen visible and some not visible.

    The mask is applied to a screen buffer after the contents are "drawn" but before being displayed.

    The mask is variable in radius (=size), so that I can animate that visible/non-visible experience.

    I'll use it for a circular "screen wipe", pretty much like an iris-type shutter.


    So, it's a SOLID circle, but formed on a per-line basis.  I'm not really looking for a "plot pixel at x,y" thing, more something that on a per-line basis will give me the 6 bytes of PF0 PF1 PF2/PF0 PF1 PF2 with appropriate bits set/clear in those bytes representing a scanline slice across a (potential) circle.


    I'm pretty much there with a buggy implementation that actually looks a bit better than a pure circle, so I may keep that :P





  11. I'm curious about the voltage settings. Were/are there two systems in use in Brazil?  It's not entirely clear from your post, but you appear to have tried both options (110V and 220V). Basically you don't need a matching transformer for both.  This is strange to me; the actual conversion to 9VDC must be inside the machine itself.  You just need to get the input correct, so either 110V or 220V, and make sure that switch is set correctly before power on.  As to the difference in voltage, +5-10V is unlikely to matter, IMHO.  Just as an aside/test, try wrapping the output RF cord in a few loops in a circle before the TV. For me this significantly reduces interference on some machines.  Also, make sure the RF connector itself is making a good connection. Twist a few times back and forth when plugged in.



  • Create New...