Jump to content

Tursi

Members
  • Content Count

    7,205
  • Joined

  • Last visited

  • Days Won

    8

Posts posted by Tursi


  1. Bah... wimps. I made sure every line in my program could be pasted into the normal line limit, not one is over 141 chars. ;)

     

    Was tempted to use the line extension tricks in a few places... what did annoy me was "line too long" on lines that were less than the max input length (got that on some of the data statements, since it counts tokens and not characters ;) )


  2. I don't even guarantee 1x right now, not going to promise 2x,4x, etc. ;)

     

    CPU overdrive is your best bet... System Max still hits the real PC hardware too hard, causing problems that range from slow response time to outright crashes (depending on the quality of your drivers). It's another fix that's waiting for the fixes to the system timing that I have planned.

     

    Of course, the trick is that CPU overdrive only speeds up the CPU, while system maximum keeps everything at the same ratios but speeds up the whole system.

     

    If you want to speed up the CPU by a fixed amount, the Options menu allows you to adjust from 0%-200% for the normal speed.


  3. Hehe, very nice. Pretty hectic. And I like the "on error". :thumbsup:

     

    Hehe... meant to mention all my tricks in the first post. Using ON ERROR let me save some time in the loops to read the data... by ordering the data so that the end of a block would cause an error to occur, and having that just go to the next block, I didn't need to hard code the size of the char tables or write code to look for a terminator. ;)

     

    Of course, when there were real bugs, they were hard to track down, as they'd just appear as characters not being redefined. ;) (Or in a few cases infinite loops where it kept branching back to the last ON ERROR target).


  4. Kind of silly to start a new post for an update, but I was flooding the main one.

     

    Here's my update to Zom-BXB... I took the Farmer Owen and his Zombie-filled fields motif and ran with it (except I am not good enough to make a nice field-like backdrop like some of you!) I've also improved the frame rate quite a lot (I feel), added a difficulty curve (though it's a little slow to kick in), and upped the graphical resolution. (The only reason I did Magnify 2 sprites the first time around was because I was saving memory - not necessary.)

     

    Although I used a lot of it for fluff, the game's up to 30 lines of code and 10 lines of data. I never would have thought I'd spend so much time on a 40 line program. But here you go...

     

    Also updated the story, and the archive includes the farmer pic (it's adapted from some old clipart I have on supposedly royalty-free CDs ;) ), and the slightly 'commented' source code in text form.

     

    I did a couple of unusual tricks to speed it up. Besides lots of shuffling around of stuff in the main loop, I removed random numbers completely by pre-generating a handful and dropping them in an array. I experimented with some advanced theories, like turning off the console interrupt with a CALL LOAD (and even running the sound generator manually), but that turned out to have a rather small difference in speed here. Unless sprites are actually MOVING, stopping the interrupt doesn't give much CPU time back. (In this version of XB.. in the early ones it did.)

     

    post-12959-1268210158_thumb.jpgpost-12959-126821016631_thumb.jpgpost-12959-126821017599_thumb.jpg

     

    ZombXB.zip


  5. Actually the simplest solution is to just use Classic99 since I know you ignore the 4 sprite limit. ;-)

     

    You underestimate me again, Batman! Classic99 has supported sprite flicker since 22 Jun 2009. ;) The method used to calculate it is hacky, but the results are 100% correct. ;)


  6. Sprite rotation is pretty easy, like Sometimes suggested, layout your sprite table in CPU memory, and do your updates there. The simplest routine is just a little function that runs on the user interrupt and copies the sprite table to VDP. For my Coleco work, I just rotate the start point of the copy by four sprites each frame.. that way the worst case is one in 8 frames (which doesn't look that good on its own.. if you can use fewer sprites it's better. 16 sprites gives a worst case of 1 in 4, which isn't bad).

     

    To do an offset copy like that, you just set the VDP address, copy from the start point to the end of the table, then copy from the beginning back to your start point. So, in the first frame:

     

    -Set VDP address

    -Copy sprite entries 0-31

    -Nothing left to copy

    -add 4 sprites (16 bytes) to start point

     

    Second frame:

     

    -Set VDP address

    -Copy sprite entries 4-31

    -Copy sprite entries 0-3

    -add 4 sprites (16 bytes) to start point

     

    Third frame:

     

    -Set VDP address

    -Copy sprite entries 8-31

    -Copy sprite entries 0-7

    -add 4 sprites (16 bytes) to start point

     

    ... etc.. looping when you hit the end of the table. It's a simple and effect rotation. If you have multicolor sprite characters, and space them out nicely, you can have some part of them visible most of the time even in the worst case.


  7. This is a marvellous entry. I think the farmer's name is quite appropriate. :) And as this is the second entry that uses the undead as a point of contention, I'd say our contest is developing somewhat of a theme!!! As a matter of fact, I imagine that if you combined ZomBXB and TIFarmer into one big 60 line game, you could farm, and when zombies approach, you could actually fight them. :). Hehehe.... I should make up a little "ZomBXBFarmer" montage for YouTube. :). These are fun times---fun times indeed.

     

    That's actually what I had in mind when I saw the TI Farm thread, hehe... a strategy game combined with arcade-action fighting off the zombies. ;) So I did my half of it for this.

     

    TI Farm is pretty impressive, nice work!


  8. TI Farmer looks pretty darn sweet! :) Hehe.. nice work :)

     

    No live score in ZomBXB because print is slow.. I wanted to keep the framerate up, and you get more points every frame.

     

    Also, I didn't want people to complain that they shot a zombie and didn't get any points for it, hehe. This way I can hide the screwy scoring system ;)


  9. I loved my SegaCD, too, I got one new after watching the promos for SolFeace (the animation in the attract mode was pretty impressive for the time!) I never regretted it. True that there was a lot of FMV crap, but I actually liked Sewer Shark, and of course it made for a decent Dragon's Lair. ;) I kept my original discs for Batman Returns, Silpheed, both Ecco titles, and (though not such a great game) Brutal Paws of Fury, just because I liked them that much, even though I sold the machine itself. (I finally have everything again ;) ).

     

    I don't see Batman Returns mentioned much, but the driving game in that was really well put together and always impressed people when I showed it to them. I never played the platformer side of it at all, honestly (you could turn it off in the options menu).


  10. No worries, Oval, thanks for the clarification.

     

    Just to be clear.. if we're talking about someone financing a run of Skunkboards, this isn't really me making an offer to the community. The offer would come solely from the person with the money, to essentially hire me to get the run put together. That's more or less what it boils down to. So if people seriously step forward with an offer, then withdraw the offer, I don't have a problem with that, because it's not really me being kind and generous to the community, it's a business investment. I provide the background info, they run the numbers, and either pull the plug or go ahead.

     

    The downside is that the information from the last run is less and less relevant to a new run, meaning that a serious investor would have to do some additional work to get modern cost figures.


  11. I tested your code on my console and saw the results first hand. Your code on my console resulted in about 50 percent missed hits. That seems disheartening for XB programming. Now the strange gets stranger......

     

    I got sick of trying to keep track of the scrolling ones and zeros so I changed the print format to..STR$(ABS©); in order to just see the 1's and 0's. This resulted in a reduction of misses to about 1.4 percent. On a whim I turned off all sprite motion with CALL LOAD(-31806,64) and got zero missed COINC's (out of 1000 tries.) This is beyond my scope so I will defer to your expertness in things of this nature but I would suspect that something other than the ISR is reading the VDP ROR or the scratch pad location is getting changed by some lurking XB/console bug. Perhaps a call to the TI software engineers is in order ;-)

     

    Thanks, Marc. VERY interesting on the turning off of sprite motion... this kind of suggests to me that the interrupt routine itself might be running long (ie: by the time we cache the value, the VDP is into the next frame? Still a theory with holes though.) At this point, though... I don't really have the cycles to dig deeper, I'm just relieved to see I'm not crazy. ;) Let's just leave it as a known for now and scratch our heads about it later.

     

    So are you telling me that all the games I played 30 years ago could've sucked less? Also, since you talk about CALL COINC reading at the end of the frame, does that mean using it will slow down my game unless I get lucky that it runs near the end of a frame? That stinks.

     

    Oh no.. it doesn't wait for the end of the frame. It just reads a cached memory address. But that address is updated at the end of the frame. CALL COINC itself shouldn't add any delay to the program, that much we did settle. :)


  12. --> So why does the interrupt routine miss collisions, when it should be reading at the end of the frame?

     

    I really don't think the ISR is missing the collisions. I believe that the COINC,DELSPRITE,COINCE series is occurring before the ISR is activated again IE XB is outrunning the VDP interrupt. This would explain the fall out every time with no delay, sometimes with 1 delay and never with 2 delays. I would be interesting to know if the sprite routines are in the ROM or GROM. I suspect the ROM due to the speed. Any ideas?

     

    That's my problem, that doesn't explain it. That theory has potential for your case, but makes no sense in mine.

     

    Look at the example program that I'm working with, not your example. My sprites are not moving. They are always touching. So the COINC should never return 'no coincidence'. But it does, and so does the CALL PEEK. If the ISR is the only thing writing that memory location, as my debugger tests suggest, then yes, the ISR /is/ missing coincidences. This is observation and not supposition.

     

    Let's start with the simpler of the two cases.


  13. OIC, very interesting. Would something like a Supercart make the reverse possible (in theory)? Or is that for something else entirely?

     

    Yes, actually, for a single-bank game, anyway. I don't know for sure but I believe the various bank switched Supercarts used a different scheme for switching.


  14. Primeform:

     

    While I strongly disagree with Oval's posts implying that he's privvy to more information than he has, he is correct that two people thus far have not followed through. Therefore, as far as financing another Skunkboard run might go, serious inquiries only, and serious inquiries don't start with a public forum post asking me to do the legwork. :)


  15. I did a little research here on the COINC issue.

     

    My CALL COINC app on the real machine -- frequent coincidence misses, as expected.

    Using CALL PEEK to the scratchpad -- reports 156 and 188. That's 9C and BC. 9C sets interrupt (expected), and 5th sprite number 28 (but 5th sprite flag not set). That's a bug I can fix in Classic99 ;) Anyway.. BC simply adds the coincidence flag. So that means that just peeking the scratchpad copy is ALSO not reliable, which I find interesting!

     

    With the real behaviour confirmed, back into the debugger. First, see who reads from the VDP status register. In debugging with the COINC version of the program running, it's always the console interrupt that reads it, coming from the GPL interpreter. This seems to discount my theory that XB reads it directly (you win!) So why does the interrupt routine miss collisions, when it should be reading at the end of the frame?

     

    I likewise checked, and nothing else writes to >837B. So that's good, we have likely got an accurate copy of the VDP status. I checked who READS that value, too, and it's a GPL memory access from XB GROM - likely the COINC. Confirmed this by removing the COINC - no more breakpoint.

     

    So far confirmed:

    -Yes, CALL COINC reads scratchpad

    -Yes, nothing except the console interrupt reads the VDP status byte.

    -Coincidences in a tight loop are still missed!

     

    Outpacing the vertical blank shouldn't matter... you can read a RAM location as many times as you want and the value won't change. So I don't fully understand why it's getting no collisions on some frames, since that's coming from the video chip by all appearances. So a bit baffling, but good to be aware of anyway, and you found a workaround..

     

    Thanks for putting up with it!

     

    Thanks everyone for the ZomBXB comments, too. :) It occurred to me that I'm not trying to save memory, I should have used magnify 3 sprites instead. But that's okay, it works fine. ;)


  16. Thank you! I'm looking forward to trying this on the real hardware. I don't have a problem burning it to an EPROM; I just need to find out where to get a compatible cartridge board. I'm assuming that all I need to do is concatenate the two 8K binaries together and burn them to a 27C128?

     

    You also need a flipflop on the board to do the switch. Jon Guidry offered up a whole bunch of new cart kits for just that, I think there's still time to get in on that buy. http://www.atariage.com/forums/topic/155089-ti-994a-64k-cart-board-2nd-run/


  17. You would need to relocate the program to run from RAM instead of ROM. It's not a trivial exercise to make it run from disk.

     

    I see you have a utility that converts programs to ROMs. Why is it harder to do it the other way around?

     

    You're making a bad assumption about what my program does.

     

    It takes a program that normally loads from disk to RAM, and copies the files into a ROM file. It then prepends a tiny little program that copies to RAM. So the program was written to run from RAM, and still does.

     

    These cartridges are written to run from ROM. It's a different memory space than RAM -- if you copy them to RAM, they will attempt to jump back into ROM, but the program won't be there, and they will crash.

     

    You basically need to go through and change all the address references for both data and code to point to locations in RAM instead of in ROM, then it will work. I've done such a tweak once but it's not a simple task.


  18. You won't believe this... but you have a space in the word CALL in line 260. For some reason, that is causing the prescanner to report an out of memory error. :)

     

    Oh, too late.

     

    I think you should have left it. It's a non-intuitive error that may help others :)


  19. When my main loop detected a COINC I deleted one sprite and immediately did another CALL COINC to determine if the earlier collision was with a specific sprite. This would occasionally give a false positive even though there was no possible collision as only one sprite was in the area. This was a problem like I said until I added some instructions between the delay and the second CALL COINC.... I don't know the exact internals but I do suspect that XB was outrunning the console interrupt routine. If is walks like a duck.....

     

    You're assuming only one possible scenario, but I can give you the same "false" positive with the direct access mechanism:

     

    The problem space is:

     

    a. CALL COINC - detects the collision

    b. Your code responds by moving one of the sprites

    c. CALL COINC - reads the VDP again, still sees a collision

     

    Your assumption is based on this process occurring:

     

    1. VDP interrupt occurs, console copies status register to scratchpad (Clears VDP status)

    2. CALL COINC reads from scratch pad, detects collision

    3. Your code responds by moving one of the sprites

    4. CALL COINC reads from scratch pad again, STILL detects collision

    5. VDP Interrupt occurs, console copies status register to scratchpad (Clears VDP status)

     

    ... and your goal with the delay fix was to move step 4 to after step 5.

     

    This is what I think happened:

     

    1. CALL COINC reads from VDP, detects collision (clears VDP status)

    2. Your code detects the collision...

    3. VDP draws the screen again, sees collision, sets status again

    4. ...your code moves one of the sprites - status bit stays set until it's read!

    5. CALL COINC reads from VDP, detects collision again

    6. VDP interrupt occurs, console copies status register to scratchpad (clears VDP status if it's still set)

     

    And your fix, adding a delay, simply moves step 5 after step 6, similar to the other scenario.

     

    Remember that unlike in today's emulators, the VDP sets the status register the instant it detects a collision, not at the bottom of the frame (which is when Win994A and MESS set it), and Classic99's setting of that bit is completely detached from real time right now, even though it can do it separate from the frame. So if it was in emulation you saw it, I wouldn't count it. Also remember that Extended BASIC can keep interrupts disabled for longer than 1/60th of a second -- if interrupts don't run, then the interrupt routine can't clear the VDP status bit. (Of course, this same argument /also/ works for your theory, too, since it shows why XB can appear to outrun the console interrupt. It's not that XB is that fast, it's that it blocks it.) Finally, the collision bit remains set until it's read, no matter how many times the screen has been drawn and regardless as to whether the sprites are still colliding.

     

    I thought Ben had previously mentioned that he'd had CALL COINC miss obvious collisions, and that I'd reproduced that. That supports the theory of it racing with the console interrupt routine. I tried this short piece of test code just now:

     

    10 CALL CHAR(42,RPT$("F",16))
    20 CALL SPRITE(#1,42,2,100,100)
    30 CALL SPRITE(#2,42,4,104,104)
    40 CALL COINC(ALL,C)
    50 PRINT C
    60 GOTO 40

     

    The sprites are /always/ touching so C should always return a collision, but in fact it frequently returns no collision. If you change it to a CALL PEEK() of the location that the register is copied to: CALL PEEK(-31877,C) -- this alternates between 160 and 128. 128 is the interrupt bit, and we would expect it to always be set (and it is). The other bit is value 32, which is the sprite collision bit. Bizarrely, it's not always set either in Classic99, meaning we're either racing the chip again (but we are in vblank when it is copied, so we shouldn't be), or something else is ALSO reading the register. I'm inclined to be suspicious of those results, though, and will try them on the real machine (unless someone beats me to it.)

     

    I'll work out the right answer when I get some time at home, but it's not so cut and dried.. you can have those symptoms either way. I think we should find out. :)


  20. --> It was something I thought I saw during some other work. But I assume you are saying you missed a COINC...

     

    Just the opposite Mike. I was getting a false positive on near back to back COINC calls. Separating them by a few instructions solved it though.

     

    Names. C'mon.

     

    How can you say it was a false positive? Did you move the sprites after the first one to guarantee none were touching?

×
×
  • Create New...