-
Posts
1,891 -
Joined
-
Last visited
Content Type
Profiles
Forums
Blogs
Gallery
Events
Store
Everything posted by adamantyr
-
Well, IF I had the memory expansion, it may be possible. I can't have just the scratchpad for RAM. It's a different architecture and requires a different approach. I'm not adverse to the idea, but I'd want the game working in a disk system first. Since you'd have saved games like Zelda does, you would also need to have a battery back-up and a small amount of RAM in the cartridge for storage. Adamantyr
-
Working title: KnightQuest (Not the permanent title) Type: Action/Adventure Controls: Joystick primary, keyboard for secondary actions/switching Requirements: TI-99/4a, 32k memory expansion, disk system Synopsis: Explore the kingdom with the knight Sir Karl, seeking the mythical Grail that grants immortality Features: - Full multi-color sprite action - Bitmap color maps, offering the best color resolution available - Explore an overworld of forests, lakes, mountains and deserts - Explore multiple dungeons for lost artifacts - Collect and use multiple weapons to fight off enemies - Solve puzzles and mysteries to reach new areas - Boss monsters, including the dreaded "Black Knight"
-
-
That's a common problem with ports... when things don't line up due to fundamental differences in the display. :S I remember that Conan on the C64 literally boxes the game into a 280x192 window to be "compatible" with the original Apple II design. For my own part, I would probably redesign the maps to fit the 32-column screen on the TI. It IS just a maze, after all, and if it's slightly different from the original, well, that can't be helped. Adamantyr
-
Oh yeah, it falls into the "look at me, the clever fellow" category for programming tricks. It's an interesting lesson on binary numbers and how to transform them, though, which is where I see the value with it. Yes, I have been asked it in interview questions before... If you claim to know assembly language at all, you should expect the question for certain. I'm just glad that the "brain teaser" interviews are being phased out... they don't do it at Microsoft anymore, although Google continues the practice. They think it helps them find "out of the box thinkers" when all it really does is find people who know how to memorize a LOT of puzzle solutions online, and not necessarily people who work well in a team, have a good work ethic, etc. Adamantyr
-
A very nice display! Good use of color to differentiate different portions of the menu. Very nice font too, did you create it yourself or derive it from another source? The V looks familiar... I'll second Will on the importance of design. I spent a lot of early time on my CRPG just making up maps, drawing graphics, and imagining how awesome the game would be, without actually doing any concrete effort on the design. Why do you think it's been five years (and counting) since I started? Don't follow my example... Adamantyr
-
Not sure what you were going for on this one...? I think you forgot to mention that A is the high byte and B is the low byte of R0. I assume you were swapping A and B? You forgot one version, which only needs two registers: AL: XOR R0,R2 AL: XOR R2,R0 AL: XOR R0,R2 Adamantyr
-
I believe he has several bits of stat screen that have to be present on the right side of the viewport. We're not seeing it in the demo. That being said, you COULD do a full screen scroll if you wanted. As long as you're not doing obnoxious LOS processing like I am doing, it shouldn't have any problem with it. Adamantyr
-
I agree wholeheartedly, Keith. The 99'er community in the past has been really good at driving people away, unfortunately. I've bought stuff from Kyle in the past, and I know he's got a stash of actual supplies from that era... a lot of it is too close to the original manuals to be mistaken otherwise. I wasn't aware of the "Neverlander" incident... Seems likes the Yahoo group is always having some kind of drama, a large reason why I lurk there. It appears that he's taken the listing down off his eBay store (for the moment anyway), so hopefully he's realized to be more cautious and ask first for new software. Mind you, if I finish my CRPG, and I suddenly see someone selling it on eBay, I'll definitely be sending a "cease and desist"... Fortunately I have a plan there, you can sell the software but the extras will only come from me... Adamantyr
-
Actually, the TI disk system at it's lowest format (single-sided read, single-density of 9 bytes per sector) is 90k. However, the original TI disk controller can read both sides, so 180k is a better assumed value, as we don't have a problem these days finding double-sided drives... Even then, a little judicious planning can allow for a 90k split in case you got one user whining your game is too "high-end" for him. You can find information on the VDP file buffers here: http://www.nouspikel.com/ti99/titechpages.htm The short of it is, the default setup is to initialize space for three files open at once. You can use a subroutine call to DSRLNK to do the equivalent of a CALL FILES(1) in order to restrict it and free up as much VDP as possible. Here's the breakdown: 3 files - 2087 bytes 2 files - 1569 bytes 1 file - 1051 bytes This space is taken from the top of VDP (>3FFF downwards), so fortunately it's out of the way. If you're thinking "No no, I want a permanent open file, so I should have several." then keep in mind that it's VERY bad if something goes wrong and the computer has to be reset while you have files open. If it's just a dump file, no big deal, but if you have stuff in there, it can be potentially very screwed up. Adamantyr
-
Have you written out that design document yet? If so, you should post it here. Trust me, it will help you a LOT with keeping focus on what you need. I'm a little concerned you're not sure yet if you're doing cartridge or disk. They're very fundamentally different environments, and it should be your first major decision. Let's compare the two here: Disk: ----- - Full 32k RAM available for code space, buffers, and data, 16k of VDP available - 90-360k of disk space available for data storage, possible code segmentation (NOT recommended) - Potential sluggishness due to disk access fetches - Not difficult to test on actual hardware Cartridge: ---------- - 256 bytes of scratchpad available for RAM, 16k of VDP available - Either ROM (8k pages) or GROM (6k chips, nominal limit of 5, but could be more with an exotic design) space for fixed static data - Tricky to test on actual hardware I'm starting to understand, really, why a lot of the Databiotics games that Triton/TM Direct sold were absolute crap. The lack of a decent amount of CPU memory in the TI console is really a hindrance to development. Adamantyr
-
Common assembler mistakes for newbies and oldbies.....
adamantyr replied to marc.hull's topic in TI-99/4A Development
Common assembler errors: 5) Forgetting to update constants after a major change "Oh, that's why my video screen is screwed up, it's using the color table for screen positions" 4) Not updating COPY directives for an emulated assembler and a PC-based assembler 3) Disabling interrupts without a key scan "WHY ISN'T QUIT WORKING?!" 2) Using a return stack and forgetting to do a DECT on it one time AND the number one... 1) DEC R2 JNE LOOP "Oh... R2 is already 0... crap" -
Jumps use a single byte to indicate the number of words to skip, -128 to 127. Your average assembly instruction is two words, or 4 bytes. So 42 lines is probably out of range... which is the error you would get when you try and compile, and OUT OF RANGE in this line. There's multiple ways to deal with this. Easiest is to have it jump to a branch instruction, which can get anywhere in memory as it uses a whole word for the address. You can also refactor your code so things are closer together; use branch-and-link to break down your routines between jumps into smaller pieces. Adamantyr
-
Well, considering you haven't written your engine yet, you should probably think conservatively. Also consider that you actually have a very small tile count for each map, which means using a whole byte per tile is a real waste. However, compression has some complications. Namely, how to decompress only the section you need to see on screen? Run-length encoding doesn't work well with viewports; you'd have to decompress an unknown quantity of data before you get the section you want. For a comparison, my own CRPG has a physical limit of 4096, or 4k for a map. That lets me have a map that's 64x64 tiles, 128x32 tiles, etc. Ultima II and III had maps of this size, but Ultima IV and V reduced it to 1024 bytes or 32x32 tiles, due to the increased tile count and the more complicated engine. The trick is that they only load what they need, and leave the rest on disk. The only complication is dynamic entities like monsters, they have to be tracked in a separate system of some kind so they won't just disappear when the player crosses a borderline. From what I can see, you're envisioning each "world" as self-contained. I'd focus on what you need to do to keep that. I've messed around with dynamic section loading from disk, and it's difficult to optimize for a good experience. Every sector access costs time, and when it takes 2-5 seconds, your action game quickly bogs down. On the subject of disk sectors, keep in mind two things: - The TI disk sectors are 256 bytes long. You should keep your widths equal to a base 2 value, otherwise you're incurring unnecessary waste - The maximum record width to fill up an entire sector is 128 bytes. The TI file system does NOT allow you to specify a record length of 256 bytes. You can cheat this by just accessing the DSR buffer in VDP directly (which has the entire sector) but some disk controllers may not buffer the sector in VDP, so it's not good to rely on that happening Before you get too heavily into graphics and world and quest design, you should really make sure your engine is designed on paper. Assembly language is really hard to improvise in, and it's better to plan out what you want it to do. Write up a list of all the tasks you need the engine to accomplish (world loading, joystick movement, combat, text displays) and then check them off one by one as you experiment in assembly on how to get each one done. Adamantyr
-
The reason you're not seeing the map right away is R12 is not set to the MAPDAT location; you need to move your DRWMAP label in front of it. The prior block of code checks a condition to end and jumps to that label, which means it's never executed. Technically, your map program should not crash, since what it does out of boundaries is just read whatever is in the CPU memory area and put it on screen. So you'll see junk and garbage ASCII around your map. Adamantyr
-
Your statement LI R12,MAPDAT can never be reached; when the pattern loop code finishes it jumps to the DRWMAP label, which is beyond it. Just move the label to that statement and that should help. Adamantyr
-
Invisible sprites. Horizontal or vertical?
adamantyr replied to Bones-69's topic in TI-99/4A Development
It's horizontal, and you can have a maximum of four sprites on a line. The lowest numbered sprites have priority. You can get around the issue; a lot of old hardware had sprite scanline limitations. The most common method was to rotate sprites so that each one had a "visible" slot in a given frame of time. This causes the "flicker" effect you see on a lot of game systems, the NES in particular. Adamantyr -
Do you remember how many actually were shipped? I got one, mainly because I pre-ordered from TM Direct. I made a set of copies of the manuals for another 99'er a few years ago who managed to score a cart on eBay, and I later put PDF scans of the manuals up on WHTech for everyone to have access to. (At ftp://ftp.whtech.com/programming/Extended%20Basic/ExtendedBasic3.pdf) An excellent cartridge, although sadly, the lack of them in the market meant writing anything to run on it was futile. How many cartridges do you think were in that production order that are probably rusting away in a landfill now? Adamantyr
-
That should work fine. Code it up and try it out! For any operation where you interrupt the VDP write with an address change, and are doing visible display, it's a VERY good idea to just hit the ports directly rather than use the VDP utilities, even if they are BL and using the scratchpad workspace area. You could also write to a buffer screen in VDP and then swap the visible screen with a single write to the VDP register. That means the transition is clean, and the only noticeable problem may be a bit of a drag between movement if you have too much going on. Also with buffers, unless you have static page elements you built prior, you'll have to update everything on every pass on the off screen, like items, health values, etc. For my CRPG, I use a status word value to track what kind of refresh is needed so I can only update what's absolutely necessary on a given pass. Keep in mind that in assembly language, you're no longer constrained to do your dirty laundry on the screen itself. For example, you wouldn't place enemy characters and items using VCHAR, instead you would pre-process the map data to include every visible element and just write it out to screen. Sprites are an exception to this; any movement of them is updated directly, and they don't respect buffer boundaries, so if they need to disappear from view you'll have to disable them. (Which is easy, you set the first sprite's Y position to >D0 and it will stop displaying ALL sprites.) Adamantyr
-
I did two techniques for that in my CRPG: wrapping or repeat. It's a flag value in the map header to determine which to use. For repeat, if a given position is out of bounds, it uses the closest position and just replicates that position. This causes a "stretch" effect both horizontally and vertically. You do need to make sure your corner-post tiles are something that is repeatable in a whole quadrant, though. A variation of this is to just repeat a single tile type. For wrapping, I just add a displacement value to an out of bounds value to make it back on the map. This means the map "wraps" around. This is useful for maps that I want to do mazes on, and also lets me construct maps on square design that actually seem bigger and less square than they are. The only downside is I know that it's doing more cycles to calculate a wrapped tile than a natural one... the current engine seems to work okay for the scale I have, but I may have to figure out a way to optimize it eventually. Adamantyr
-
Pseudo-random number generation is a great topic for assembly programming. As game programmers, we usually just want random numbers, and don't want to delve into a lot of philosophical discussion on the subject. Which means short, simple, and imperfect routines are great to start. Then when you realize you actually need it a BIT more random, you start finding out more. That's the fun of programming, finding out what you need based on your own experiences. That's one reason I'm so hard on Matt about the ISR, it's better for people to discover on their own this blasted ROM routine is sucking up cycles they need elsewhere. That's a very simple and easy routine, Tursi. The best part about it is it doesn't involve division, which is the real cycle-sucker in any random number generator. The ARM processors that drive most mobile devices, like Game Boys, don't have a native division opcode, and most games don't need something too complicated for randomness. If you used another external boolean to determine the XOR, like the even/odd bit of the VSYNC, it would be pretty random! Now if you take a procedurally generated game, like Elite, they actually use 6-byte random numbers, because a 16-bit integer just isn't enough. You also need it to be stable; once you "seed" it with a value the rest of it's calculations are predictable. That means no user-inputs to cause major chaos. The random number generator in BASIC is that way; if you seed it you'll get the same values over and over again. At least we had a RANDOMIZE option; I remember playing Lemonade Stand on the old Apple IIc and being amused that weather and factors were always the same... it always rained the first cloudy day, I remember, but not the subsequent day. Adamantyr
-
For your demonstration, breaking up your program into a bunch of smaller subroutines connected by Branch and Links is pretty good. My experience with my CRPG design, though, was that you gained a lot of mileage by figuring out what was truly a subroutine, and what could be done by just railing the code all into one large linear sequence. For example, I have multiple steps taken during travel mode. It loads map data, it loads character graphics, it sets up the mobile objects... but it's all one routine, broken down by symbolic labels into smaller pieces. Based on a status value, I redirect to an earlier or later position in the linear sequence, depending on what is needed. For example, status screens have their own character set, so checking for a character set change is a last step, so I can easily restore things without re-loading a map or replacing mobs. I also put my one-time-only initialization at the very start of the code... and then use that space as buffer afterward. NOT a modern-day programming technique at all, but for a vintage system it makes perfect sense. Adamantyr
-
Out of curiosity, Gary, do you remember how many Extended Basic 3 cartridges were made? I got one through TM Direct/Triton because I pre-ordered, but I learned much later that they were incredibly rare... only one other 99'er I know of has one, and some have said there were less than a dozen or so. Adamantyr
-
I think the main point of the values isn't that they're prime, but that they're under 32767. I noticed when I tried bigger values in the high-positive/negative range, the random numbers ended up all being the same value or very low values consistently... I should have guessed that prime numbers were intended there, I'll try swapping my values for primes as well. Yeah, I knew about the shift 0 issue. If you don't use the circular shift, it has the added penalty of wiping out the register entirely! Why they did that and didn't build the check right into the op-code circuitry I wonder... I skipped over a check because the 56 cycles of waiting wasn't a huge hit for me in my CRPG; most of my random generation is occurring in human-time scale, not computer time-scale. Adamantyr
-
Put me down for a pre-order as well. Adamantyr
