Re: A85: Matrices


[Prev][Next][Index][Thread]

Re: A85: Matrices



<What is the ebst way to do matrices!  I have an 8X8 grid draw and I have
<4 different sprites.  At the bottom of the game I have all of the
<sprites and the board in .db's.  But how can I read the board and move
<to the left and up and down and so forth.  Also, how do I then let it
<see which sprite should be there.  Can someone help me, or write a
<routine and explains how it works, thanks
<
<JOhn

This wasn't written by me, but I think it will help you out. It does
basically the same thing, just with a different grid and sprites. Just adjust
the beginning variables to 8*8, or whatever.

I hope that helps!
Mikel Blanchard

<A HREF="http://members.aol.com/CashOnly/The_Layer.html">http://members.aol.co
m/CashOnly/The_Layer.html</A>

; MAPPING EXAMPLE v1.0 BY JIM REARDON
; Feedback is greatly appreciated, you can reach me at eviljim@geocities.com
;
; Here it is, finally, a engine that will show a 16x8 map with up to 256
; different sprites.  It works rather quickly and could be modified to use
; any size sprites you want to.  You can also modify it easily enough to use
; any other sprite routine, or to make it a non-Usgard program.
;
; You can use this in any program you want to, I would like a little "thanks"
; in the documentation (and source, if you release it).  A box in the program
; would be nice, but, hey, I'm not pickey.  Oh yeah, an E-Mail, too.
;
; If you can find any way to do this quicker or can optimize the code at
; all, PLEASE CONTACT ME!  I use this routine exactly in my upcoming RPG,
; and would greatly appreciate it if it could be faster in anyway.  It goes
; rather quickly, however.
;
; Newest versions can be gotten at http://eviljim.home.ml.org/zshell.htm
; I am planning on making another map routine that will include a character
; that moves around in the environment, and yet another map routine that will
; "scroll" a large map displaying only part of it on the current screen.  I
; will also be making a grayscale version of this (although it would require
; only one modification of the source).
;
; I tried to make this easily modifyable for any size sprite.  Just change
; the Width, Height, Total, and NextYAt variables.  If that doesn't work,
; you can always email me or play with the code.  It should work, though.
;
; REQUIRED LIBRARIES: SPRITLIB (11)

#include "usgard.h"
#include "spritlib.h"

Width           = 8             ; Width of Sprite
Height          = 8             ; Height of Sprite
Total           = 128           ; Number of Sprites to Draw Per Map
                                ; 128 / 8 means 16 per row.
                                ; 56  / 8 means 7 per column.
                                ; 16 * 7 means 128.
NextYAt         = 128           ; When to zero out the X value and increase
                                ; the Y value.  Typically at 128, the end
                                ; of the screen.

Current         = TEXT_MEM      ; Temporary Variable for Drawing the Map
DrawMapX        = TEXT_MEM+1    ; Temporary Variable for Drawing the Map
DrawMapY        = TEXT_MEM+2    ; Temporary Variable for Drawing the Map
MapPointer      = TEXT_MEM+3    ; 2 byte pointer to &MapA
                                ; Needed for Drawing the Map, must be set
                                ; before DrawMap is called!

.org 0
.db "Map Example",0
.db SPRITLIB, 0

; This first segment of the program is just a "demo" that calls the MAP
; routine.  Various variables are set here which you must remember to set
; in your program before calling DrawMap

        ld      a, 4
        out     (5), a

        ld      hl, VIDEO_MEM
        LIB_CALL_(SPRITLIB, SET_DEST)   ; set Sprite Destination to Video Mem

        ld      hl, &MapA               ; Tell the routine where our map data
        ld      (MapPointer), hl        ; is located at.  This is so the
                                        ; routine is compatable with multiple
                                        ; maps.

        call    CLEARLCD                ; clear screen, add this to the
                                        ; routine if you need to do it every
                                        ; time.  Pixels are drawn so that
                                        ; they will overwrite the screen
                                        ; completely, so this command is not
                                        ; really necessary.

; The following you need to have before each map is drawn.  You should start
; cutting and pasting here.  You can include a call CLEARLCD if you want.

DrawMap:

        ld      a, Total                ; we need to loop how many times?
        ld      (Current), a            ; save that in map counter
        ld      a, 0                    
        ld      (DrawMapX), a           ; we currently are on 0, 0
        ld      (DrawMapY), a

DrawMapLoop:

; the following loads the sprite coordinates into HL so it can be displayed

        ld      hl, (MapPointer)        ; load Map location in memory
        ld      a, (Current)            ; load block number we're on

        ld      d, a                    ; |
        ld      a, Total                ; |   Total Loops - (block number)
        sub     d                       ; | 

        ld      d, 0                    ; | Add (Loops - (block number)) to
        ld      e, a                    ; | hl, which points to the "map".
        add     hl, de                  ; | This gets the position in the
                                        ; | map we need.

        ld      a, (hl)                 ; get what the map says the value is

; now that we have what the block number is (0, 1, 2, etc), we need to find
; where, in memory, the sprite that cooresponds to that number is located at
; in memory.  This is done by a Sprite Location table.  This version supports
; up to 256 sprites, numbered 0 - 255.  The addresses of the sprites are
; located near the end of the program, in SpriteTable.

        ld      hl, &SpriteTable        ; load the raw location of table
        add     a, a                    ; double a, since each sprite pointer
                                        ; is two bytes
        ld      d, 0
        ld      e, a                   
        add     hl, de          ; get from the sprite table where exactly

; hl now points to a pointer in SpriteTable.  We need to load the value now.

        call    LD_HL_MHL

; equivalant of ld      hl, (hl) which is not legal.  This loads the location
; of the sprite into hl (ie, loads "SpriteA" into memory).

        ld      de, (PROGRAM_ADDR)      ; add PROGRAM_ADDR, relocation is not
                                        ; going to work here!
        add     hl, de

; the following code determines at what screen position to draw the sprite
; and stores it into BC.  It just loads these numbers out of DrawMapY and
; DrawMapX

        ld      a, (DrawMapY)
        ld      c, a
        ld      a, (DrawMapX)
        ld      b, a

; now we actually draw the sprite

        LIB_CALL_(SPRITLIB,PUTSPRIT)    ; draw the sprite

; update our screen position counters and things of the sort

        ld      a, (DrawMapX)

        add     a, Width
        cp      NextYAt                 ; if this is the end of the X row
        call    z, &UpdateMapY          ;  then increase Y pointer
                                        ; UpdateMapY will put a "0" into a
        ld      (DrawMapX), a           ; increase X pointer either way
                                        ; (must happen after UpdateMapY is
                                        ;  called)

        ld      a, (Current)
        ld      b, a
        dec     a
        ld      (Current), a            ; decrease block number

        djnz    DrawMapLoop             ; loop until block number is 0

        call    OTH_PAUSE               ; pause

        ret                             ; end the program

UpdateMapY:
        ld      a, (DrawMapY)
        add     a, Height               ; increase the Y pointer by height
                                        ; of each sprite
        ld      (DrawMapY), a
        ld      a, 0                    ; set the X pointer to 0 (it's saved
                                        ; back into a variable when this
                                        ; function RETs).
        ret

; Locations of sprites in memory.  Start with what you want sprite "0" to be
; and go until you don't need anymore.

SpriteTable:
        .dw SpriteA, SpriteB, SpriteC


; The actual sprites.  I use PutSprite format.

SpriteA:
.db 8,8
.db %00000000
.db %00000000
.db %00000000
.db %00000000
.db %00000000
.db %00000000
.db %00000000
.db %00000000

SpriteB:                        ; brick type 1
.db 8,8
.db %11111111
.db %10000001
.db %11111111
.db %00010000
.db %11111111
.db %10000001
.db %11111111
.db %00010000

SpriteC:                        ; closed chest
.db 8,8
.db %00000000
.db %00000000
.db %00000000                 
.db %01111100
.db %10001010
.db %11111110
.db %10001010
.db %11111110

; Map data.

MapA:
.db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1     ; blocks $00 - $0F
.db 1,0,0,0,0,1,0,0,0,0,2,0,0,0,0,1     ; blocks $10 - $1F
.db 1,0,0,2,0,1,0,0,0,0,0,0,0,0,0,1     ; blocks $20 - $2F
.db 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1     ; blocks $30 - $3F
.db 1,0,0,0,0,1,0,0,0,0,0,0,2,0,0,1     ; blocks $40 - $4F
.db 1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1     ; blocks $50 - $5F
.db 1,0,0,0,0,1,0,2,0,0,0,0,0,0,0,1     ; blocks $60 - $6F
.db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1     ; blocks $70 - $7F

.end