Jump to content


  • Content Count

  • Joined

  • Last visited

Community Reputation

692 Excellent

About PeteE

  • Rank

Profile Information

  • Gender
  • Location
    Beaverton, OR

Recent Profile Visitors

5,213 profile views
  1. Ideally, I would want it wired as B->J2Fire, Start->J2Right, Select->J2Left (with diode protection, see this thread)
  2. Looks awesome! What joystick 2 actions are the additional buttons mapped to? I'll definitely need to make sure it's supported in my game.
  3. I've updated the downloads in the top of the thread. You can now pause and unpause with the P key. I also improved the finish line graphics for each season by adding a sprite over the char graphics.
  4. No, I use the FinalGROM cartridge on my console. The bnp_8.bin file is a cartridge image, which can be placed on the SD card plugged into the FinalGROM, which maps it at the 8KB cartridge memory space at >6000. The FinalGROM supports banking, so additional data can be accessed, up to 512K. Bounce'n'Pounce uses 4 banks, for a 32KB cartridge image (which means it could work with the older FlashROM cart.) I could have created an editor assembler version that can be loaded using the E/A cartridge, requiring the 32KB expansion. But I do my development on my PC using the Classic99 emulator, and I find that cartridge images have much faster turnaround for testing changes. With Classic99's debugger open, I can press Ctrl-F12 to reset the emulation which also reloads the cartridge image, then press the 2 key twice through the TI menu and I'm running my latest version. I'm almost ready to post the final version. I have added the motor sound effect, fixed the car behavior on narrow bridges, added the score for landing on islands, and improved the sprite flickering.
  5. I'm glad you asked. The tracks are made from 16 segments, each 32x32 characters: Each of the 8 roads is a 64 byte array with each byte containing the segment type. I wrote a C program to process the track segments in order to calculate the character transitions and data tables for the scrolling routine. The pattern and color tables are split into 32 chunks of 8 characters. Each chunk contains the 8 scroll transitions from one character into another character. Some segments needed adjusting to make the seams fit within the limit of 32 active transitions simultaneously. Another trick to minimize transitions is adjacent characters are staggered, creating the appearance of larger 16x16 tiles, seen in the dirt/rock/water formations: AB uses only A->B and B->A transitions, but fills a 16x16 pixel block BA and can repeat vertically Each segment gets 3 sets of transition chunks (one between each quarter), and another table holds transition chunks between segments. Each group of transition chunks is coded as a 16-bit quality, with each nibble holding an offset into yet another table of transition groups that are commonly used together by the track patterns. The pattern/color table update function takes a new coded transition group, and compares it to the current transition group, and updates only the chunks that differ. The transitions between two characters are generated on the fly: the pattern data for each character is copied into each half of a 16-byte buffer in RAM, then 8 bytes are copied to the VDP, 8 times total but each time moving the starting offset by 1 byte. It is then repeated for the color data. If you notice any slight delays or "hitches" in the scrolling, it is probably the pattern/color tables being updated. Every time 8 or more rows are scrolled, the transition tables load a new transition group and are updated as needed, for each third of the screen. Bitmap mode has separate pattern and color tables for each character, with each third of the tables affecting only 8 rows on the screen. Shown here with classic99 debugger command Debug->VDP chars (F9) to see the current tables, each third has the same transition group. The gray strip shows the start of each third, the transition from road to road. For drawing the screen, the track segments are split into 16-character strips, left and right side. Each track segment contains 31 pairs of strip indices, and another table for pairs between track patterns. The same strips will often appear multiple times in the track segments, and storing an index saves enough memory to keep all the tables in a single bank. The strip table entries are 16 bytes, each byte being the first character value of the transition chunk in the pattern/color tables. The lowest 3 bits of each byte will always be 0, since the scroll offset (0 to 7) will get added as the strips are drawn to the screen. The draw strips function runs from fast RAM for maximum speed. This code snippet copies two scrolled characters to the VDP screen table: MOV R3,R0 ; copy y offsets to R0 (14 cycles) SOC *R4+,R0 ; set upper bits to strip bytes (26 cycles) MOVB R0,*R15 ; copy first byte to screen table (22 cycles) MOVB *R1,*R15 ; copy second byte to screen table (26 cycles) The scroll offset is in the high and low bytes of a workspace register R3, and the bytes from the strip pointer R4 are SOC (bitwise-or) together to select two scrolled transition characters at once. The R1 register points to the low byte of R0, so then both scrolled transitions get copied to the VDP. All 16 bytes get copied this way, repeated for all 24 rows of left and right strips. All the tables are read-only and can reside in the ROM banks, thus no need to use the expansion RAM. TLDR; Magic.
  6. Thanks for your kind words. I'm really happy to see you all enjoying it. That's what makes game development worth it.
  7. Here is a TI99/4A port of the arcade game "Bump 'n' Jump" from Data East in 1982. It is written in assembly language, developed using Ralph's XDT99 tools. It runs on a bare console and does NOT require 32K expansion. It features full-screen vertical scrolling at pixel resolution in bitmap graphics mode. Use joystick 1 or the E S D X keys to accelerate/steer/decelerate, and Fire, Space bar or Enter to jump. The P key can be used to pause and resume play. Colliding cars will temporarily bounce in opposite directions, and bounced opponent cars may smash against the barriers. Various cars have different point score values. Your car speed must be at least 100 to be able to jump. Jump over gaps in the road, or to avoid being bounced into a hazard. Upon landing, cars underneath will be instantly smashed. Completing a road will score bonus points for the number of cars smashed, before moving on to the next season. An extra life is awarded every 30K points. Landing on an island awards 1000 points. This game was started when I had an idea for a method of scrolling the whole screen, and I made a prototype for the 4K contest in early 2018. The prototype proved the scrolling effect worked, and then I spent a lot of time compressing it down to fit in 4K. The prototype used only 13 out of the 16 track segments, used only one season's color table, and had track data only for the first two levels, (before going off into the weeds and filling video memory with garbage.) The full game has 8 levels of 64-segment road, with more complicated segment transitions that didn't work within the prototype transition scheme. Instead of loading a new transition set every 32 rows (1 segment), I needed to allow reloading every 8 rows (1/4 segment). This is fine because the bitmap graphics mode is 3 chunks of 8 rows, so each chunk can be updated individually. Some of the original segment elements had to be adjusted to made the seams easier to fit into the transition table. The transition tables are limited to 32 entries, since each transition consumes 8 of the 256 characters. I spent some of my last winter holiday vacation working on the transition table generation, and finally got it working. For this version I didn't bother with any compression: bank 0 is mostly program, bank 1 is track data, bank 2 is sprite data, and bank 3 is sound lists. The music was converted from the notes in a midi file that I found. Music plays on the tone channels 1 and 2, and sound effects play on tone 3 and noise channels. I grew up playing the Intellivision port as a kid, and have incorporated some of the same design elements into this version. The "Get Ready Player" and "Congratulations" screens have white text over a black background. Another similarity is that the opponent vehicle sprites are limited to a single color. This game is more-or-less complete. I considered adding a two player mode, but have run out of space in bank 0. bnp_8.bin bnp.rpk
  8. You're welcome. I can't claim credit though, I'm sure I took it from somewhere else, but I can't remember where. Probably here
  9. Here's an example cartridge header, with a single program in the program list: AORG >6000 ; Cartridge header in all banks HEADER BYTE >AA ; Standard header BYTE >01 ; Version number 1 BYTE >01 ; Number of programs (optional) BYTE >00 ; Reserved (for FG99 this can be G,R,or X) DATA >0000 ; Pointer to power-up list DATA PRGLST ; Pointer to program list DATA >0000 ; Pointer to DSR list DATA >0000 ; Pointer to subprogram list PRGLST DATA >0000 ; Next program list entry DATA START ; Program address BYTE CRTNME-CRTNM ; Length of name CRTNM TEXT 'CARTRIDGE NAME' CRTNME EVEN START ; Your program starts here LWPI WRKSP ; Load the workspace pointer to fast RAM LIMI 0 ; Interrupts off ... You would change the string at CRTNM to reflect what you want to appear in the TI menu "PRESS 2 FOR" ... and it must appear in all upper-case.
  10. This is already possible using the ".ifgt" and ".error" preprocessor commands. Ralph even shows this very thing as an example in the XDT99 documentation:
  11. Another method I've been meaning to try out is the xdt99 feature of XORG, so you could lay out your data in memory using DATA statements without having to calculate offsets manually, like this: VARDAT XORG >8320 ; start after workspace PLAYER DATA >0000 ENEMY DATA >0000 KEYLOC DATA >0000 ETC The difference between this and AORG, is that the DATA bytes are copied into your program at VARDAT, so you can initialize your variables by copying words from VARDAT to >8320 when your program starts.
  12. The assembler should give you total control of where you put your code. I'm assuming you have something like this in your assembly program: AORG >A000 ; start at upper expansion RAM * your program code MAPDAT BYTE .... ; your map data from Magellan BYTE .... In order to run on an unexpanded console, you need to put your program in cartridge ROM like this: AORG >6000 ; start at cartridge ROM * cartridge header * your program code MAPDAT BYTE .... ; your map data from Magellan BYTE .... ; note this is now read-only Note that you can no longer modify the MAPDAT table at its assembler-defined address in ROM, but you must copy it to the VDP to be displayed and then you can modify it in VDP RAM through the VDP port. To use the scratchpad for data, I use a group of EQUates to define address of variables, leaving room for the register workspace, and calculate the offsets manually by adding the size of the previous item to the current offset: WRKSP EQU >8300 ; workspace at top of scratchpad PLAYER EQU WRKSP+32 ; 32 is the size of WRKSP, player is 2 bytes ENEMY EQU WRKSP+34 ; 2 bytes after PLAYER, enemy is 2 bytes KEYLOC EQU WRKSP+36 ; 2 bytes after ENEMY, keyloc is 2 bytes ETC Keep in mind the scratchpad is only 256 bytes, so the offset cannot exceed 255... and you either need to avoid using scratchpad data used by the ISR, or keep interrupts off (LIMI 0) for the duration of your program.
  13. The keyboard layout for Raspbian defaults to UK style and locale. Run raspi-config to change the localization settings.
  14. No need to run any installation script. The python files are all there, ready to run: tipi$ cd xdt99/ xdt99$ ls COPYING ide README.md xas99.py xda99.py xdm99.py xhm99.py doc lib test xbas99.py xdg99.py xga99.py xvm99.py
  15. Hi Beery, The TIPI SD card image has xdt99 preinstalled at /home/tipi/xdt99.
  • Create New...