Jump to content
IGNORED

Porting Games by Peter J. Meyer to the 7800


peteym5

Recommended Posts

Hello I starting this up last year, experimented with the Atari 7800 Basic to port over some games I had previously done on the Atari 8-bit/5200. I have Venture, Delta Space Arena, Tile Smashers, Putt 18 Miniature Golf, and Laser Blast X partially completed. I did graphics, and different screen set ups. Did not do anything with sounds yet. I usually take game projects one step at a time, do design, graphics, setting up the screen, animations, collisions, and usually do sounds last.

 

I started with full character mapped 40x24 screens, but as someone pointed out, this is overloading the 7800 display hardware. I am looking into replacing in a few games with an array that draws strips of vertical, horizontal lines of characters. Would need this to be variable length, and have collision detection going on (don't want objects to pass through walls). Not sure if 7800 Basic has a good set up for this method. But in the end, probably have less display glitches when trying to display many sprites at once on the screen. I am going to do this with Venture and Delta Space Arena.

  • Like 2
Link to comment
Share on other sites

Probably going to need assistance with switching PLOTMAP from two big for left and right screen to a bunch of smaller ones. If I can get this to work, it would allow more of my games to be ported without requiring huge chunks of RAM space I originally assumed that was needed to port the game over.

 

This is what I done so far. Not sure if plotmap can work from a 2 byte variable instead of a memory pointer

const Mem_Screen_Data_Start = $2440 
  dim Mem_Screen_Data       =$2440

Mem_Screen_Data = Mem_Screen_Data_Start 
 plotmap Mem_Screen_Data 0   0 2 16 01
 Mem_Screen_Data = Mem_Screen_Data + $20
 plotmap Mem_Screen_Data 0   0 4 16 01
 Mem_Screen_Data = Mem_Screen_Data + $20
 plotmap Mem_Screen_Data 0   0 6 16 01
 Mem_Screen_Data = Mem_Screen_Data + $20
 plotmap Mem_Screen_Data 0   0 8 16 01
 Mem_Screen_Data = Mem_Screen_Data + $20
 plotmap Mem_Screen_Data 0   0 10 16 01
 Mem_Screen_Data = Mem_Screen_Data + $20
 plotmap Mem_Screen_Data 0   0 12 16 01
 Mem_Screen_Data = Mem_Screen_Data + $20
 plotmap Mem_Screen_Data 0   0 14 16 01
 Mem_Screen_Data = Mem_Screen_Data + $20
 plotmap Mem_Screen_Data 0   0 16 16 01
 Mem_Screen_Data = Mem_Screen_Data + $20
 
Link to comment
Share on other sites

I doubt that would work but you can freely define multiple variables in the same memory locations, so you can define your start, then $20 on you define another variable, and another, etc. When you copy your data into memory it doesn't care that you have a different name for that location and continues copying so you'll end up with pointers for each line.

 

You don't need to plot a new map for each line, BASIC takes care of that for you.

Link to comment
Share on other sites

If you want to arbitrarily pick a point then your options are to either define a variable name for every byte you might use, or have a look into the assembly side of things.

 

I've copied a bit of the assembly output from my project as an example. You can see that it's setting the temp variables to the given parameters with temp1 and temp2 being the low and high bytes of the data to load. 'jsr plotcharacters' is what's actually doing the work, and everything past that line is what adjusts the various counters and then calls plotcharacters again for the next zone.

 

You can use a bit of inline assembly to handle the setup and call plotcharacters yourself to get it exactly how you want using the below as something to base it on.

.L0402 ;;  plotmap titleScreenFloorMapMem 2 0 11 20 4

    lda #12 ; width in two's complement
    sta temp3

    ora #64 ; palette left shifted 5 bits
    sta temp3

    lda #0
    sta temp4

    lda #11
    sta temp5

    lda #4
    sta temp6

    lda #<titleScreenFloorMapMem
    sta temp1

    lda #>titleScreenFloorMapMem
    sta temp2

plotcharactersloop8
 jsr plotcharacters
    clc
    lda #20
    adc temp1
    sta temp1
    lda #0
    adc temp2
    sta temp2
    inc temp5
    dec temp6
    bne plotcharactersloop8
Link to comment
Share on other sites

You can

Not sure if plotmap can work from a 2 byte variable instead of a memory pointer

The plot* functions just create Display List objects, with the parameters you pass them. Maria DL objects inherently point to memory addresses. Those memory addresses can be a section of RAM, or a section of ROM. There's no ability for a DL object use 6502 indirect addressing mode or anything of the like.

  • Like 1
Link to comment
Share on other sites

That may work also. One issue I was having with the games I started up last year was that I was drawing full screens for Venture and Delta Space Arena with a character map screens with vertical and horizontal lines of custom characters to represent walls or boundaries, with blank space between them. I noticed some glitches with the flickering of some of the moving sprites and a few people suggested don't use a character map for the whole screen. I am experimenting with this new method, and would need to port some games over to use it.

 

From what I understand, the Maria hardware has timing limitations of what it can display on a scan line. It can display maybe a full background full of tiles or characters, and maybe display just a few sprites on top before that start going black. A few things I need to do may have up moving objects on screen at once. So you can see how this can start to overload things.

 

Something else that may now be possible is drawing the screens for Tempest. Since the 7800 does not have a full screen bitmap mode and 4K of RAM, it would be difficult to use something like the Atari XL/XE style of drawing lines for all those screens. But if we break things down for the diagonal lines, this method could make that game possible also.

 

I could need to look over that assembly code provided. Can the Vertical Position of the plotmap be set down to the pixel?

Link to comment
Share on other sites

That may work also. One issue I was having with the games I started up last year was that I was drawing full screens for Venture and Delta Space Arena with a character map screens with vertical and horizontal lines of custom characters to represent walls or boundaries, with blank space between them. I noticed some glitches with the flickering of some of the moving sprites and a few people suggested don't use a character map for the whole screen. I am experimenting with this new method, and would need to port some games over to use it.

If you're using plotted characters on top of plotted characters, then yes, that technique uses up MARIA's available DMA cycles pretty quickly.

 

 

From what I understand, the Maria hardware has timing limitations of what it can display on a scan line. It can display maybe a full background full of tiles or characters, and maybe display just a few sprites on top before that start going black. A few things I need to do may have up moving objects on screen at once. So you can see how this can start to overload things.

This depends on the tile mode, and how many bytes per pixel it uses. The multisprite example, with 160A mode characters, displays a full screen of characters (albeit with 1 palette) and manages more than a few sprites per zone.

 

320 modes will eat up more. A bunch of different palette character objects in one zone will eat up more.

 

 

Something else that may now be possible is drawing the screens for Tempest. Since the 7800 does not have a full screen bitmap mode and 4K of RAM, it would be difficult to use something like the Atari XL/XE style of drawing lines for all those screens. But if we break things down for the diagonal lines, this method could make that game possible also.

 

I could need to look over that assembly code provided. Can the Vertical Position of the plotmap be set down to the pixel?

There's no fine vertical positioning of character objects in 7800basic, to stop people from shooting themselves in the foot. Fine positioning would create twice the number of character DL objects, and blow through the available DMA.
Link to comment
Share on other sites

This is what I came up with. I modified mine to work from variables instead of absolute values. Added a fill in plotmap. The pointer increments after each use. Can add something that will track all the rectangles into a memory table so collision with them can happen during the game loop. Thankyou for the information provided, it helped me get things going.

 plot_pointer_lo = screendata_lo
 plot_pointer_hi = screendata_hi
 plot_index = 0
 p= 0
 q= 2
 r= 20
 s= 1
  DrawChar = 23
  gosub plotmap_part  
  q = q + 2
  DrawChar = 24
  gosub plotmap_part
 
plotmap_part
    ;;  plotmap titleScreenFloorMapMem 2 0 11 20 4

    asm
      lda #12 ; width in two's complement
      sta temp3
   
      ora #00 ; palette left shifted 5 bits
      sta temp3
   
      lda p   ;x position
      asl  
      asl  
      sta temp4 
   
      lda q  ;y position
      sta temp5
   
      lda s
      sta temp6 ;height of bitmap part
   
      lda plot_pointer_lo
      sta temp1
   
      lda plot_pointer_hi
      sta temp2
 
plotcharacters_part_loop
       jsr plotcharacters
       clc
       lda r   ;width of plotmap part
       adc temp1
       sta temp1
       
       lda #0
       adc temp2
       sta temp2
       
       inc temp5
       dec temp6
       bne plotcharacters_part_loop  
       
       lda temp1
       sec
       sbc plot_pointer_lo
       bcs pcp_l1
       eor #255
pcp_l1
       tay
       lda DrawChar
fill_draw_characers_loop       
       sta (plot_pointer_lo),y
       dey
       bne fill_draw_characers_loop 
       
       sta (plot_pointer_lo),y
       lda temp1
       sta plot_pointer_lo       
       lda temp2
       sta plot_pointer_hi
end

  return

Link to comment
Share on other sites

Added a way of recording collision zones, every position is shifted so the values match up with the pixel position.

  rem Collision Zones
  dim CZL                   =$2240         
  dim CZR                   =$2260
  dim CZT                   =$2280
  dim CZB                   =$22A0                        
  dim last_czones           =$22E1

plotmap_part
    ;;  plotmap (plot pointer) 0 p q r s

    asm
      lda #12 ; width in two's complement
      sta temp3
   
      ora #00 ; palette left shifted 5 bits
      sta temp3
   
      lda p   ;x position
      asl  
      asl  
      sta temp4 
   
      lda q  ;y position
      sta temp5
   
      lda s
      sta temp6 ;height of bitmap part
   
      lda plot_pointer_lo
      sta temp1
   
      lda plot_pointer_hi
      sta temp2
 
plotcharacters_part_loop
       jsr plotcharacters
       clc
       lda r   ;width of plotmap part
       adc temp1
       sta temp1
       
       lda #0
       adc temp2
       sta temp2
       
       inc temp5
       dec temp6
       bne plotcharacters_part_loop  
       
       lda temp1
       sec
       sbc plot_pointer_lo
       bcs pcp_l1
       eor #255
pcp_l1
       tay
       lda DrawChar
fill_draw_characers_loop       
       sta (plot_pointer_lo),y
       dey
       bne fill_draw_characers_loop 
       
       sta (plot_pointer_lo),y      
       lda temp1
       sta plot_pointer_lo       
       lda temp2
       sta plot_pointer_hi          

       ldy plot_index
       lda p
       asl 
       asl 
       sta CZL,Y
       lda r
       asl 
       asl 
       clc
       adc CZL,Y
       sta CZR,Y
       lda q
       asl
       asl
       asl
       sta CZT,Y
       lda s
       asl
       asl
       asl
       clc
       adc CZT,Y
       sta CZB,Y
       sty last_czone
       inc plot_index                   

end

  return

Something else I had a problem porting porting 8-bit over to 7800, and these procedure may help get around it. With the plotmap samples, the character mapped screens were not set up to be mapped like the 8-bit screens. Need to plotmaps for the left and right side of the screens. However, if we set up 2 plotmaps for each line, one character tall. 1 for first 20 characters, and another for the second 20 characters. it would create a screen mapped in sequence. Trying to port over stuff to draw on the 7800 screen with 2 big plot maps and needing to check and add for the right side was getting really frustrating and made me put my 7800 port projects down to work on something else back in February of this year..

  • Like 1
Link to comment
Share on other sites

The plotmap command has a couple of optional offset parameters which can be used to draw different parts of the same larger map so you don't end up with a 'leftScreen' map and a 'rightScreen' map that need managing independently. The x offset is directly added to the maps's start location and the y offset adds y * fullMapWidth.

  • Like 3
Link to comment
Share on other sites

[edit - SmittyB beat me to it, while I was digging around for the code example. :thumbsup:]

 

Something else I had a problem porting porting 8-bit over to 7800, and these procedure may help get around it. With the plotmap samples, the character mapped screens were not set up to be mapped like the 8-bit screens. Need to plotmaps for the left and right side of the screens. However, if we set up 2 plotmaps for each line, one character tall. 1 for first 20 characters, and another for the second 20 characters. it would create a screen mapped in sequence. Trying to port over stuff to draw on the 7800 screen with 2 big plot maps and needing to check and add for the right side was getting really frustrating and made me put my 7800 port projects down to work on something else back in February of this year..

To display more than 32 characters, you need to segment the display with regards to DL objects, but the backend character buffer doesn't need to be segmented. plotmap has extra optional parameters that allow for a "window" display on a larger buffer. You can create 2 plotmaps, each splitting up a 40-wide character buffer with 2x 20-wide plotmaps. (this application is the main reason plotmap has those optional parameters)

 

For the Serpentine port I did from the A8 to the 7800, I actually use 7800basic for all of the 7800 interfacing. Here's how I create an "Antic mode 4" display equivalent...

 

  displaymode 160A
  [...]
  rem for reference...
  rem plotmap mapdata palette1# x_pixel y_char width height [map_x_off map_y_off map_width]
  
  dim screenram=$4100 : rem ** character buffer. serpentine uses on-cart RAM
  characterset serpentinecharacters
  clearscreen
  plotmap screenram 0 0  0 20 24 0  0 40
  plotmap screenram 0 80 0 20 24 20 0 40
  savescreen

...this worked great. Not one bit of the Serpentine game character code needed to be modified.

 

I'll also try to put together a sample for the next release, but hopefully now you don't need it.

  • Like 2
Link to comment
Share on other sites

Thankyou very much, I went to my Miniature Golf game I am porting over that used an Antic 4 screen to draw the courses on the 8-bit. It was doing that left and adding for right side screen thing going on. I applied the updated plotmap code and it worked. It is actually 48 character per line on the 8-bit because it is using the wide screen setting.

  • Like 3
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...