Need help with ML graphics programming

Basic and Machine Language

Moderator: Moderators

Post Reply
Bacon
for breakfast
Posts: 578
Joined: Mon Apr 19, 2004 8:07 am

Need help with ML graphics programming

Post by Bacon »

I'm trying my hand at games programming for the VIC by porting a game I made for the C64 but I'm having problems with using custom characters/software sprites.

What I'm trying to do is to follow advice I've found on the net by setting the screen to 22 columns by 11 double height characters, thereby in effect creating a 176x176 pixel bitmap (88x176 if I decide to use multicolor). Every screen position corresponds statically to one character; all screen movement is performed by writing to character memory, not to screen memory.

The problem with my code is that when I try to change the appearance of one character, changes also appear in other parts of the screen, with lines of pixels flickering on and off. If anyone can take the time to look through the code below and tell me what I'm doing wrong, I'd be very grateful. The code is in Power Assembler format, since I use my C128 for cross developing.

Code: Select all

;...---==Space Pig Duel VIC-20==---...

;For 16K expanded VIC. 3K must also be
;present at RAM1-RAM3 ($0400-$0fff).
;Screen is at $0400-$04ff
;Custom characters at $1000

;BASIC starts at $1200. $1200-$13ff can
;be used for a short BASIC program to
;start the main program.
;$0500-$0fff can be used for constants,
;variables, etc.

;Zero page variables
temp1 = $f0
temp2 = $f1
temp3 = $f2
temp4 = $f3

;Constants
screen         = $0400
characters     = $1000
alt'characters = $0800        ;Use the 2K from $0800 to $0fff to store
                              ;alternative character set (for title screen)

;Variables
player'x'pos         = $0500  ;$0500-$07ff can be used for variables
opponent'x'pos       = $0504  ;and other data.
player'laser'x'pos   = $0508
opponent'laser'x'pos = $050c
player'y'pos         = $0501
opponent'y'pos       = $0505
player'laser'y'pos   = $0509
opponent'laser'y'pos = $050d
player'old'x'pos         = $0502
opponent'old'x'pos       = $0506
player'laser'old'x'pos   = $050a
opponent'laser'old'x'pos = $050e
player'old'y'pos         = $0503
opponent'old'y'pos       = $0507
player'laser'old'y'pos   = $050b
opponent'laser'old'y'pos = $050f


.org $2400

init = *
            lda #$00          ;Clear character memory
            ldy #$00
-           sta characters,y
            sta characters+$100,y
            sta characters+$200,y
            sta characters+$300,y
            sta characters+$400,y
            sta characters+$500,y
            sta characters+$600,y
            sta characters+$700,y
            sta characters+$800,y
            sta characters+$900,y
            sta characters+$a00,y
            sta characters+$b00,y
            sta characters+$c00,y
            sta characters+$d00,y
            sta characters+$e00,y
            sta characters+$f00,y
            iny
            bne -

            lda #$16          ;22 columns
            sta $9002
            lda #$17          ;11 rows, 16 pixel characters
            sta $9003
            lda #$9c          ;Chars at $1000, screen at $0400
            sta $9005
            lda #$08          ;Black screen, black border
            sta $900f

            ldy #$00
            lda #$01          ;White characters
-           sta $9500,y
            sta $9400,y
            iny
            bne -

;--------------------
;Code to see if this works. Won't be in the game
            ldy #$00          ;Fill the screen with characters $00-$FF
-           tya
            sta screen,y
            iny
            bne -

            lda #$ff          ;Make the first row of character $00 white
            ldy #$00
            sta characters,y
;--------------------


game'loop = *
            jsr screen'wait
            jsr check'death
            jsr random'gen
            jsr power'bars
            jsr draw'obstacles
            jsr obst'explosion1
            jsr obst'explosion2
            jsr get'joystick
            jsr joystick
            jsr random'move1
            jsr opponent'vertical
            jsr opponent'fire
            jsr player'laser'move
            jsr opponent'laser'move
            jsr opponent'collision
            jsr player'collision
            jsr object'player'col
            jsr object'opponent'col
            jsr raster'wait
            jsr draw'screen
            jmp game'loop

screen'wait = *
            rts
check'death = *
            rts
random'gen = *
            rts
power'bars = *
            rts
draw'obstacles = *
            rts
obst'explosion1 = *
            rts
obst'explosion2 = *
            rts
get'joystick = *
            rts
joystick = *
            rts
random'move1 = *
            rts
opponent'vertical = *
            rts
opponent'fire = *
            rts
player'laser'move = *
            rts
opponent'laser'move = *
            rts
opponent'collision = *
            rts
player'collision = *
            rts
object'player'col = *
            rts
object'opponent'col = *
            rts

raster'wait = *
-           lda #$00          ;Wait for the raster beam to reach the top
            cmp $9004         ;of the screen to prevent flicker
            bne -
            rts
draw'screen = *
            rts

;----------------
;Tables 'n stuff
bitmap'table'lo = *
.byt$ 00, b0, 60, 10, c0, 70, 20, d0, 80
.byt$ 30, e0, 90, 40, f0, a0, 50, 00, b0
.byt$ 60, 10, c0, 70

bitmap'table'hi = *
.byt$ 14, 14, 15, 16, 16, 17, 18, 18, 19
.byt$ 1a, 1a, 1b, 1c, 1c, 1d, 1e, 1f, 1f
.byt$ 20, 21, 21, 22

line'values'tbl = *
.byte 0, 11, 22, 33, 44, 55, 66, 77, 88
.byte 99, 110, 121, 132, 143, 154, 165
.byte 176, 187, 198, 209, 220, 231
line'values'tbl'end = *
Bacon
-------------------------------------------------------
Das rubbernecken Sichtseeren keepen das cotton-pickenen Hands in die Pockets muss; relaxen und watschen die Blinkenlichten.
yago
Vic 20 Newbie
Posts: 13
Joined: Tue Apr 27, 2004 11:59 am

Post by yago »

Hi Bacon,

The screensetup (doubleheight and so on) sounds good.

It is better to fill the screen columnwise, because then it is easier to calculate pixel-positions.

For example,

Code: Select all

@ho..
ai.
bj.
ck
dl
em
fn
For debugging, I would throw away all "ported" stuff, and just try to plot some single pixels. If this works, put your "ported" stuff back in.

Have Fun,
Zed Yago
Bacon
for breakfast
Posts: 578
Joined: Mon Apr 19, 2004 8:07 am

Post by Bacon »

Thanks. I'll try and throw away all unneeded stuff for the time being, and arrange the characters in columns instead.
Bacon
-------------------------------------------------------
Das rubbernecken Sichtseeren keepen das cotton-pickenen Hands in die Pockets muss; relaxen und watschen die Blinkenlichten.
Boray
Musical Smurf
Posts: 4064
Joined: Mon May 03, 2004 10:47 am

Post by Boray »

A game for a vic with 16k + 3k RAM expansion. I think this is an EXTREMELY rare memory combination. Isn't it?

/Anders
carlsson
Class of '6502
Posts: 5516
Joined: Wed Mar 10, 2004 1:41 am

Post by carlsson »

Yes, and it WON'T WORK even on a VIC-20 with +3K and +16K at the same time. The reason why: neither screen memory nor graphics memory can be placed in expansion RAM.

Bacon, you could put the screen memory in the low 1K somewhere (you only need one page, 256 bytes of memory - check the memory map for which positions work) and have the graphics memory in $1000-$1FFF. This is basically what Albert of Pu-239 and all the others do.

I know that I often praise emulation, but this is an area where current emulators really suck. Not that they perform worse than the real thing, but that they perform better than a real VIC-20, as e.g. xvic/VICE doesn't have this memory limitation yet, at least not per default.

Generally, avoid writing programs utilizing all possible memory locations in an odd way. While it may work in the emulator or your home modified VIC-20 (i.e. the one with extra RAM piggy-backed inside the computer), it will NOT WORK on a stock, unmodified VIC-20 which is kind of the reason why you program for it, isn't it?
Anders Carlsson

Image Image Image Image Image
Bacon
for breakfast
Posts: 578
Joined: Mon Apr 19, 2004 8:07 am

Post by Bacon »

Ah, OK, thanks guys. I haven't really figured out how the VIC chip sees memory. Carlsson: You're right, I use my modified VIC (with Nicolas Welte's RAM/ROM expansion) but it doesn't work on that either. The VIC 20 is a complicated beast to program ;-)

I do use emulators occasionally to try out programs I've downloaded, but never for programming. It's much more fun to use the real thing.
Bacon
-------------------------------------------------------
Das rubbernecken Sichtseeren keepen das cotton-pickenen Hands in die Pockets muss; relaxen und watschen die Blinkenlichten.
carlsson
Class of '6502
Posts: 5516
Joined: Wed Mar 10, 2004 1:41 am

Post by carlsson »

Basically, the VIC chip sees the memory that is inside the machine but nothing else. This can be described in a much more exact and technically elegant way, and maybe the machine can be altered to make the VIC chip take advantage of expansion RAM too, but again that would be a modification.

Good luck with your programming. I haven't tried your Space Pig game, but to me it seems much like overkill to work in a bitmapped environment? Using custom characters in the traditional way, maybe adding a software sprite routine should be enough and only takes a fraction of the memory a bitmap screen does.
Anders Carlsson

Image Image Image Image Image
Bacon
for breakfast
Posts: 578
Joined: Mon Apr 19, 2004 8:07 am

Post by Bacon »

carlsson wrote:Good luck with your programming. I haven't tried your Space Pig game, but to me it seems much like overkill to work in a bitmapped environment? Using custom characters in the traditional way, maybe adding a software sprite routine should be enough and only takes a fraction of the memory a bitmap screen does.
Well, I see it as a way to learn the ins and outs of the VIC 20. maybe I'll try a more memory efficient way.

You're right, by the way, it's probably overkill to bitmap the screen, but as I said, it's a way to learn.
Bacon
-------------------------------------------------------
Das rubbernecken Sichtseeren keepen das cotton-pickenen Hands in die Pockets muss; relaxen und watschen die Blinkenlichten.
carlsson
Class of '6502
Posts: 5516
Joined: Wed Mar 10, 2004 1:41 am

Post by carlsson »

Give up the Space Pigs and go for a Wolfenstein clone - if nothing else, it will have use for a bitmapped screen as you move and get new views all the time. :D

Something really simple with wireframe and low frame count may actually be feasible, but I'm too much of a novice to determine which of the tricks C64 demo coders used in their 3D demos can be used in a real game too.
Anders Carlsson

Image Image Image Image Image
Bacon
for breakfast
Posts: 578
Joined: Mon Apr 19, 2004 8:07 am

Post by Bacon »

carlsson wrote:Give up the Space Pigs and go for a Wolfenstein clone - if nothing else, it will have use for a bitmapped screen as you move and get new views all the time. :D
Man, I'm really stuck in the 8-bit world. When you said Wolfenstein it took me a while before I realised that you meant Wolfenstein 3D and not the original Castle Wolfenstein. Using bitmapped graphics and software sprites on a clone would make for a better looking game than the original, since it uses character graphics even on the C64 :-)
I think they ported it directly from the AppleII without even trying to use the C64's superior graphics. On the other hand, they managed to use sampled speech. In 1983! Scared the hell out of me the first time I heard my C64 shout "Achtung! SS!" at me...

Anyway, I'll stick to my Space Pigs. At least I can use a lot of the game logics I made for the 64. It doesn't utilise any fancy C64 tricks anyway since it was my first major C64 programming effort.
Bacon
-------------------------------------------------------
Das rubbernecken Sichtseeren keepen das cotton-pickenen Hands in die Pockets muss; relaxen und watschen die Blinkenlichten.
Post Reply