Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Xeda112358

Pages: 1 ... 53 54 [55] 56 57 ... 317
811
TI Z80 / Re: Pokémon Amber
« on: July 22, 2013, 12:00:16 am »
Okay, thanks! I might try to draw the pokémon sprites myself by looking at those images (I drew the Aerodactyl in the intro myself).

As for a screenshot, I used your player sprites (they look so much nicer!) and I used ideas from the other tiles (like for the buildings).

I am still impressed by how fast your tilemap and scrolling works! I scroll 2 pixels at a time to make it a little faster (only 4 LCD updates every time the player moves instead of 8 ).

EDIT: Oops, screenshot:
 

812
TI Z80 / Re: Pixelscape: online sprite and tilemap editor
« on: July 21, 2013, 05:43:13 pm »
I have some feature requests...

I finally used this for the first time today and I really like it! I was trying to make masked sprites, but there aren't any options available. Instead, I used the 4-level gray option and toggled the pixels accordingly. Unfortunately, this makes it kind of tough to visualise the sprite to make sure I am setting the pixels properly, so it would be cool to have it as an option. There are two ways that I am familiar with (and I have used both, depending on the conditions) :

Method 1: AND - OR
First layer is used as an AND mask. This tells which pixels to erase/preserve on the current image. Alternatively, you can make it so that a pixel OFF on this layer corresponds to an OFF pixel in the sprite. In other words, you can start this as all black.
Second layer is used as an OR mask. These are all the pixels that are set by the sprite.

The cleanest way to display this is to have it so that an ON pixel in the AND mask is displayed as gray, an OFF pixel is displayed as white. Any pixels OFF in the OR mask do nothing, pixels ON show as black. If the user toggles a pixel off, it should turn the pixel off in both masks.

Method 2: OR - XOR
The other method, the first layer is an OR mask, turning on pixels, the second layer has set bits that turn pixels OFF.

A pixel ON in the XOR mask should also be ON in the OR mask. This makes a white pixel.
A pixel OFF in the XOR mask and ON in the OR mask makes a black pixel.
A pixel OFF in both masks won't change the background.

The visualisation for this would be gray if both pixels are off, black if only the XOR pixel is off, white if both pixels are ON.


The other request would be one of data output syntax. I don't know how popular it is, but I tend to store my gray and masked tiles such that the two layers are interleaved (for assembly, this is easier/faster for me). So for a ball, I might have:
Code: [Select]
;OR Mask
.db $3C,$7E,$FF,$FF,$FF,$FF,$7E,$3C
Code: [Select]
;XOR Mask
.db $00,$3C,$7E,$7E,$7E,$7E,$3C,$00
That will cause the pixels on the outside of the ball to be unchanged when it is drawn, the pixels inside get set to white, perimeter is black. The data as I store it:
Code: [Select]
;Interleaved
.db $3C,00,$7E,$3C,$FF,$7E,$FF,$7E,$FF,$7E,$FF,$7E,$7E,$3C,$3C,00

I hope this makes sense! I won't have much trouble converting it myself (I have a spreadsheet that I have had for a looong time to interleave data and do other manipulations :P)

813
TI Z80 / Re: Pokémon Amber
« on: July 21, 2013, 04:45:01 pm »
The character sprite does actually have a walking animation, but it isn't very good and you can't easily see it.
Feel free to use those from Pokémon Monochrome if you want :)
How did I forget about Pokémon Monochrome D: I even remember working on that rectangle routine with chickendude. But really, those sprites are wonderful!

How large are your actual Pokémon sprites? I was thinking of using 24x24. Your sprites look so good!

:thumbsup:+1

I finished work for today and I don't work tomorrow, so now I might actually get more work done!

Also, you and chickendude are excellent programmers o.o I would try to help with Pokémon Monochrome, but I am afraid that I won't be familiar with your style .__. But I might look through it to find optimisations (but it looks very fast already!).

I am going to try to use some of your tiles/sprites to see how it looks.

814
TI Z80 / Re: Pokémon Amber
« on: July 20, 2013, 09:09:40 pm »
To answer DJ_O about the missingno. question, I don't plan to add that in.

Now I have another small update (I am afraid that I am concentrating too much on details, now). A few days ago, I had some scrolling done, but it didn't scroll in the new tiles, making it bad looking. I now have smoothscrolling finished for up/down, but now I need to finish left/right. Luckily, I have an idea for how to make it work (and it will be about the same speed as scrolling up or down). As well, I found a small issue with my code that was actually slowing down animation significantly. I was resetting the wrong flag in a routine, causing the tilemap to be redrawn and the LCD to be updated every time the interrupt fired (instead of when a tile went to the next animation frame). After fixing that and taking out about a 1000 cycles of code on top of it, I had to increase the animation counter from 16 to 128 to make it reasonable :P


Oh, I also added an in-game menu with options that don't do anything (except the Options menu and Exit). I forgot to include it in the screenshot, but maybe I won't next time :P

The character sprite does actually have a walking animation, but it isn't very good and you can't easily see it. I am thinking of making the character sprite 16x16, keeping 8x8 tiles, but I haven't decided on that yet (you can see a lot more on screen with 8x8 tiles and 8x8 character sprite).

815
ASM / Re: Non-Standard gBuf Ideas
« on: July 19, 2013, 10:34:09 pm »
@thepenguin77: I haven't used timers before, but I think I understand your code and that is clever! nextCol would basically adjust the LCD column by incrementing it until it reached 2C at which point it would reset the pointer (dec h \ dec h \ dec h) and the column to 20h ?

@tr1p1ea: Thanks! I have these text display commands, but they don't properly clip on the edges of the window :/
Code: [Select]
;RAM required:
;fmt_leftmost   1 byte , define the left edge of where text can be drawn
;fmt_rightmost  1 byte , define the right edge of where text can be drawn
;fmt_lower      1 byte , define the lower edge of where text can be drawn
;fmt_upper      1 byte , define the upper edge of where text can be drawn
;bit wordrawp,(iy+textflags)    ;define your own location and whatnot
;textcol        1 byte
;textrow        1 byte
;fontptr        2 bytes points to the nibble packed 4x6 fontset
;DrawBufPtr     2 bytes, points to the buffer where text gets drawn
;lFont_record is defined by the ti83plus.inc. 6 bytes are used
;
;Sample Fontset included
;Inlcuded Routines, Input:
;  IGPutSFmt     null-terminated string, directly following the call
;  GPutSFmt      HL points to the null terminated string
;  GPutCFmt      A is the character to display (all formatting applied)
;  GPutC         B is the character to display (some formatting applied)
;
;All text is written to the buffer with OR logic.
;These routines are modified for vertically aligned buffers, not the way the OS does it.


IGPutSFmt:
;Inputs:
;     The null-terminated string to display immediately follows the call.
;Example:
;     call IGPutSFmt
;     .db "Hello World!",0
     pop hl
     call GPutSFmt
     jp (hl)
GPutSFmt:
;Inputs:
;     HL points to the zero-terminated string to display
;The following define a rectangular region for where text is allowed:
;     (fmt_leftmost)
;     (fmt_rightmost)
;     (fmt_lower)
;     (fmt_upper)
;     bit wordwrap,(iy+textflags)
     ld a,(hl)
     inc hl
     or a
     ret z
     push de
     push hl
     call GPutCFmt
     pop hl
     pop de
     jr GPutSFmt
GPutCFmt:
;Input:
;     A is the char to display
     ld b,a
     call GPutC
;perform formatting based on indents, wordwrap
     bit wordwrap,(iy+textflags)
     ret z
     ld hl,(textcol)
     ld de,(fmt_rightmost)
     ld a,e
     sub l
     ret nc
     ld a,d
     sub h
     ret c
     ld a,(fmt_leftmost)
     ld l,a
     ld a,h
     add a,6
     ld h,a
     ld (textcol),hl
     ret
GPutC:
;Inputs:
;     (fontptr)
;     (textcol)
;     (textrow)
;     B is the char to display
     ld a,$D6
     cp b
     jr nz,charreg
nextline:
       ld a,(fmt_leftmost)
       ld (textcol),a
       ld a,(textrow)
       add a,6
       ld (textrow),a
       ret
charreg:
     ld hl,(fontptr)
     ld a,b
     ld c,b
     ld b,0
     add hl,bc
     add hl,bc
     add hl,bc
     ld de,lFont_record
     ld b,3
       ld a,(hl)
       and $F0
       ld (de),a
       inc e
       ld a,(hl)
       rrca \ rrca
       rrca \ rrca
       and $F0
       ld (de),a
       inc e
       inc hl
       djnz $-15
     ld ix,lFont_record
     ld de,0406h
     ld bc,(textcol)
     ld hl,fmt_lower
     ld a,b
     cp (hl) \ ret nc
;e is height
     add a,e
     sub (hl)
     jr c,$+6
       neg
       add a,e
       ld e,a

     ld a,c
     dec l
     cp (hl) \ ret nc


     ld a,c
     add a,4
     ld (textcol),a
     ld a,b
     ld b,c
     ld c,a
ORSprite8xY:
;Note: No clipping.
;Inputs:
;     BC = (x,y)
;     IX points to the sprite
;     E is the height
     ld a,b
     and $F8
     ld h,0
     rla \ rl h
     rla \ rl h
     rla \ rl h
     ld l,a
     ld a,b
     ld b,0
     add hl,bc
     ld bc,(DrawBufPtr)
     add hl,bc
;HL points to the first byte to draw at
     and 7
     jr nz,crossedbound
       ld b,e
       push ix \ pop de
         ld a,(de)
         xor (hl)
         ld (hl),a
         inc hl
         inc de
         djnz $-5
       ret
crossedbound:
     ld b,a
     ld d,a
     ld a,1
       rrca
       djnz $-1
     dec a
     ld c,e
     push bc
     ld e,a
;E is the mask
;IX points to the sprite
;HL points to where to draw
drawloop1:
     ld a,(ix)
     ld b,d \ rrca \ djnz $-1
     and e
     or (hl)
     ld (hl),a
     inc ix
     inc hl
     dec c
     jr nz,drawloop1
     ld c,64
     add hl,bc
     ld a,e
     cpl
     ld e,a
     pop bc
drawloop2:
     dec ix
     dec hl
     ld a,(ix)
     ld b,d \ rrca \ djnz $-1
     and e
     or (hl)
     ld (hl),a
     dec c
     jr nz,drawloop2
     ret
;===============================================================
FontSet:
;===============================================================
;00~7F
.db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$8C,$EC,$80,$00,$00,$00,$00,$00,$00
.db $24,$44,$20,$0A,$4A,$00,$00,$EA,$E0,$00,$4E,$40,$00,$04,$00,$00,$E4,$44,$E4,$2C,$00,$EC,$EC,$C0

.db $74,$4C,$40,$62,$A2,$00,$C2,$4E,$00,$02,$48,$E0,$69,$96,$00,$AC,$88,$00,$E4,$40,$00,$68,$60,$E0
.db $2E,$4E,$80,$C2,$C0,$E0,$06,$00,$00,$E8,$C8,$E0,$42,$F2,$40,$AD,$DD,$A0,$4E,$44,$40,$44,$4E,$40

.db $00,$00,$00,$44,$40,$40,$AA,$A0,$00,$00,$00,$00,$00,$00,$00,$A2,$48,$A0,$4A,$4A,$50,$88,$80,$00
.db $24,$44,$20,$84,$44,$80,$00,$40,$00,$04,$E4,$00,$00,$44,$80,$00,$E0,$00,$00,$00,$80,$22,$48,$80

;FontNumbers
.db $4A,$AA,$40,$4C,$44,$E0,$C2,$48,$E0,$C2,$42,$C0,$AA,$E2,$20,$E8,$C2,$C0,$68,$EA,$E0,$E2,$44,$40,$EA,$EA,$E0,$EA,$E2,$20

;3Ah~3Fh
.db $04,$04,$00,$04,$04,$80,$24,$84,$20,$0E,$0E,$00,$84,$24,$80,$C2,$40,$40

.db $00,$00,$00,$4A,$EA,$A0,$CA,$CA,$C0,$68,$88,$60,$CA,$AA,$C0,$E8,$C8,$E0,$E8,$C8,$80,$68,$AA,$60
.db $AA,$EA,$A0,$E4,$44,$E0,$62,$2A,$40,$AA,$CA,$A0,$88,$88,$E0,$AE,$AA,$A0,$CA,$AA,$A0,$EA,$AA,$E0
.db $CA,$C8,$80,$EA,$AE,$60,$CA,$CA,$A0,$68,$42,$C0,$E4,$44,$40,$AA,$AA,$E0,$AA,$AA,$40,$AA,$AE,$A0
.db $AA,$4A,$A0,$AA,$44,$40,$E2,$48,$E0,$4A,$EA,$40,$88,$42,$20,$C4,$44,$C0,$4A,$00,$00,$00,$00,$E0
.db $84,$00,$00,$06,$AA,$60,$88,$CA,$C0,$06,$88,$60,$22,$6A,$60,$04,$AC,$60,$48,$C8,$80,$06,$A6,$2C
.db $88,$CA,$A0,$40,$44,$40,$20,$22,$A4,$8A,$CA,$A0,$88,$88,$40,$0A,$EA,$A0,$0C,$AA,$A0,$04,$AA,$40
.db $0C,$AC,$80,$06,$A6,$22,$0A,$C8,$80,$0C,$84,$C0,$4E,$44,$20,$0A,$AA,$E0,$0A,$AA,$40,$0A,$AE,$A0
.db $0A,$44,$A0,$0A,$A6,$24,$0E,$24,$E0,$64,$84,$60,$44,$44,$40,$C4,$24,$C0,$05,$A0,$00,$E0,$E0,$E0

;FontNumbers2
.db $04,$AA,$A4,$04,$C4,$4E,$0C,$24,$8E,$0C,$24,$2C,$0A,$AE,$22,$0E,$8C,$2C,$06,$8E,$AE,$0E,$24,$44
.db $0E,$AE,$AE,$0E,$AE,$22

;Accented A
.db $24,$AE,$A0,$84,$AE,$A0,$00,$00,$00,$A4,$AE,$A0

;Accented a
.db $24,$06,$A5,$42,$06,$A5,$4A,$06,$A5,$A0,$6A,$60

;Accented E
.db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00

;Accented e
.db $48,$4A,$C6,$42,$4A,$C6,$4A,$4A,$C6,$A0,$4A,$C6

;Accented I
.db $24,$0E,$4E,$84,$0E,$4E,$4A,$0E,$4E,$A0,$E4,$E0

;Accented i
.db $24,$04,$44,$84,$04,$44,$4A,$04,$44,$A0,$44,$40

;Bombs... er, accented O
.db $24,$69,$96,$84,$69,$96,$4A,$69,$96,$A0,$69,$96

;Lowercase bombs
.db $24,$06,$96,$84,$06,$96,$4A,$06,$96,$A0,$06,$96

;Accented U
.db $24,$AA,$A6,$84,$AA,$A6,$4A,$AA,$A6,$A0,$AA,$A6

;Accented u
.db $24,$0A,$A6,$84,$0A,$A6,$4A,$0A,$A6,$A0,$0A,$A6

;Accented C,c,N,n
.db $4A,$8A,$48,$06,$88,$6C,$5A,$0C,$AA,$5A,$0C,$AA

;Other Puntuation
.db $24,$00,$00,$84,$00,$00,$A0,$00,$00,$40,$48,$60

;Upside-Down Exclamation Point Identical to lowercase i
;Change to something else?
.db $00,$00,$00

;Greek
.db $05,$AA,$50,$25,$65,$A0,$05,$A2,$20,$00,$4A,$E0,$34,$27,$96,$68,$E8,$60

;[
.db $64,$44,$60

;Greek (continued)
.db $84,$25,$90,$0A,$AD,$80,$0F,$55,$90,$25,$56,$48,$F4,$24,$F0
.db $07,$55,$40,$07,$A2,$10
;Idunno howta do these
.db $4E,$AE,$40,$69,$99,$69

;CC~CF
.db $E0,$A4,$A0,$E0,$A6,$24,$52,$50,$00,$00,$00,$A0,$26,$E6,$20

;D0~D5
.db $44,$40,$00,$22,$48,$80,$00,$60,$00,$C4,$8C,$00,$EA,$E0,$00,$E4,$2C,$00

;D6
.db $00,$00,$00

;D7~DF
.db $40,$44,$20,$04,$CA,$C8,$8A,$4A,$20,$E9,$AE,$A8,$69,$E8,$60,$00,$44,$60,$9D,$FB,$90,$A5,$55,$A0,$4E,$FE,$40

;Overwrite Cursor
.db $FF,$FF,$FF,$FB,$1B,$BF,$FB,$51,$5F,$FF,$95,$9F

;Insert Cursor
.db $00,$00,$0F,$4E,$EE,$0F,$4A,$EA,$0F,$06,$A6,$0F

;E8~EF
.db $00,$84,$20,$00,$C6,$20,$00,$E6,$20,$00,$8C,$E0,$25,$D5,$20,$4A,$AA,$40,$4E,$44,$40

;F0~F4
.db $44,$4E,$40,$5A,$5A,$5A,$27,$A6,$3E,$4E,$44,$00,$69,$A9,$A0

;male/female
.db $73,$5E,$AE,$EA,$E4,$E4

;BlockEater Down $F7
.db $6F,$96,$90
;BlockEater Left        $F8
.db $6F,$16,$90
;BlockEater Right       $F9
.db $6F,$86,$90
;BlockEater Up          $FA
.db $69,$96,$90

;FB~FE
.db $09,$AC,$E0,$08,$53,$70,$EC,$A1,$00,$73,$58,$00

;FF
.db $A5,$A5,$A5
Those use a nibble-packed 4 wide by 6 tall font (3 bytes per char for a total of 768 bytes).

816
ASM / Re: Non-Standard gBuf Ideas
« on: July 18, 2013, 12:59:33 pm »
That is an excellent idea! So the code would look like:
Code: [Select]
     ld ix,gBuf+128
     ld b,64
shiftrightloop:
     srl (ix-128) \ rr (ix-64) \ rr (ix) \ rr (ix+64) \ inc ixh  ;100
     rr (ix-128) \ rr (ix-64) \ rr (ix) \ rr (ix+64) \ inc ixh   ;100
     rr (ix-128) \ rr (ix-64) \ rr (ix) \ rr (ix+64)  ;92
     dec ixh \ dec ixh \ inc ix ; 26
     djnz shiftrightloop
     ret
That is 21210 t-states, which is much nicer!

817
Computer Programming / Re: Addition in the bitfield domain
« on: July 18, 2013, 11:18:56 am »
Could you provide an example of what a (z1, o1) + (z2, o2) would look like? That might help me to understand what needs to be solved.

EDIT: after speaking on IRC, I thought I would post some code here:
Code: [Select]
;(x & a) + (y & b)
;Inputs:
;   a,b
     c = a|b
     d = 1
     for(i=1;i<32;i++)
     d=2*d
     if (0 == (c&d) )
       c = c | ( d & ((a & (d-1)) + (b & (d-1))))
That still isn't elegant, but that much works. It doesn't work for the generalisation of  ((x & a)|b) + ((y & c)|d), though.
EDIT2: Or :
Code: [Select]
;(x & a) + (y & b)
;Inputs:
;   a,b
     c = a|b
     d = 0
     for(i=1;i<32;i++)
       d=2*d+1
       c = c | ( (d+1) & ((a & d) + (b & d-)))

818
TI Z80 / Re: Pokémon Amber
« on: July 18, 2013, 10:02:48 am »
The way I have it is the tilemap is drawn to the graph screen (plotSScreen, 9340h) and certain 'events' such as NPCs, the player sprite, items, movable boulders, and anything else blocking paths are drawn to two other buffers (one buffer for the sprite mask, the other for the sprite data). Then during the LCD update, I just take the three layers and mash them together. My LCD updating code is basically:
Code: [Select]
     ld hl,gBuf
     exx
     ld hl,buf0
     ld de,buf1
     exx
     ld a,20h
colm:
     out (16),a
     inc a
     cp 2Ch
     ex af,af'
     ld b,40h
rowm:
     ld a,(hl)
     exx
     or (hl)
     ex de,hl
     xor (hl)
     ex de,hl
     inc de
     inc hl
     exx
     inc hl
     out (17),a    ;79 t-states is enough
     djnz rowm
     lcddelay()
     ex af,af'
     jr nz,colm
     res lcdupdate,(iy+asmflags)
     ret

While the tilemap is drawn with aligned sprites (it is more 10 than times faster than my general sprite routine, I think), scrolling the screen will still take a speed hit and the difference will be noticeable from scrolling up/down versus left and right. By my estimate, scrolling the screen left/right will be about 4 times slower, so I will have to add in additional code to keep scrolling consistent.

Here is a screenshot from another project where I wrote a tilemap routine:

That is with basically no delays, but also no smooth scrolling. This is an example from the same project with smoothscrolling:

Since Pokémon Amber uses a different gBuf setup, (and since tilemapping and whatnot is done from an interrupt), I don't know how speeds will compare. However, that is basically the same technique I plan to use. Shift the screen, shifting in the appropriate sprite data. This is why it will shift in whole tiles 1 pixel at a time. I won't have to do anything too complicated or slow.

(screenshots are from the OmniRPG - Coding discussion)
I wonder if I should use those tiles? ...

819
ASM / Re: Non-Standard gBuf Ideas
« on: July 17, 2013, 03:02:46 pm »
Cool, I hope that helps! It turns out that people like Iambian and tr1p1ea have been using this technique for years! Here are a few more routines that could probably still be optimised:
Code: [Select]
;RectangleErase can be optimised to be much faster if you make it its own routine using cpl \ and (hl) for logic. Currently, it uses RectangleOR \ RectangleXOR
;Included Routines
;======================
;Inputs:
;     B = Height
;     C = Width
;     D = X (leftmost)
;     E = Y (upper)
;RectangleBoxEraseFill
;  Draws a box with a black border, interior is erased.
;  Returns B-2, C-2, D+1, E+1
;RectArrowXOR
;  Draws an arrow pointing right with XOR logic
;  Returns BC,DE unchanged
;RectangleMenu
;  Draws a box with rounded edges
;  Returns D+1,C+2, B and E unchanged
;RectangleOR
;  Draws a black rectangle
;  Returns BC,DE unchanged
;RectangleXOR
;  Inverts the region of the screen
;  Returns BC,DE unchanged
;RectangleErase
;  Draws a white rectangle
;  Returns BC,DE unchanged

RectangleBoxEraseFill:
     call RectangleOR
     inc d
     inc e
     dec b
     dec b
     dec c
     dec c
     jp RectangleXOR
RectArrowXOR:
     push de
     push bc
     ld a,b
     cp c
     jr c,$+3
       ld b,c
     ld c,1
;B is now the smaller of the two
;C is 1
     call RectangleXOR
     inc d \ inc e
     djnz $+5
     pop bc
     pop de
     ret
     djnz $-10
     jr $-5
RectangleMenu:
     call RectangleErase
     push bc \ push de
     inc e \ dec b \ dec b
     call RectangleXOR
     pop de \ pop bc
     inc d \ dec c \ dec c
     jr RectangleXOR
RectangleErase:
     call RectangleOR
RectangleXOR:
;Inputs:
;     DE is (x,y)
;     BC is (h,w)
;Outputs:
     push de
     push bc
     call RectMain
     jr nz,$+11
       ld a,c
       xor (hl)     ;logic
       ld (hl),a
       inc hl
       djnz $-4
       jp EndRect
     ld d,a        ;number of columns before last col
     ld e,b
     ld a,(rect_FirstByte)
     ld c,a
xorrectcol:
     ld b,e        ;height
     push hl
xorrectloop:
     ld a,(hl)
     xor c          ;logic
     ld (hl),a
     inc hl
     djnz xorrectloop
     pop hl
     ld c,64
     add hl,bc
     ld c,-1
     dec d
     jp m,endrect
     jr nz,xorrectcol
     ld bc,(rect_LastByte)
     jp xorrectcol
RectangleOR:
;Inputs:
;     DE is (x,y)
;     BC is (h,w)
;Outputs:
     push de
     push bc
     call RectMain
     jr nz,$+11
       ld a,c
       or (hl)     ;logic
       ld (hl),a
       inc hl
       djnz $-4
       jp EndRect
     ld d,a        ;number of columns before last col
     ld e,b
     ld a,(rect_FirstByte)
     ld c,a
orrectcol:
     ld b,e        ;height
     push hl
orrectloop:
     ld a,(hl)
     or c          ;logic
     ld (hl),a
     inc hl
     djnz orrectloop
     pop hl
     ld c,64
     add hl,bc
     ld c,-1
     dec d
     jp m,endrect
     jr nz,orrectcol
     ld bc,(rect_LastByte)
     jp orrectcol
EndRect:
     pop bc
     pop de
     ret
RectMain:
;Inputs:
;     DE is (x,y)
;     BC is (h,w)
;Outputs:
;     returns z if it is all in one column, else it returns the number of columns
;     HL points to the start byte
;     (rect_FirstByte), (rect_LastByte)
;     A is negative the number of columns
;     BC is (h,w)
;
;If it is a single column wide, C is the mask, B is the height
     ld a,d
     and %11111000
     ld h,0
     rla \ rl h
     rla \ rl h
     rla \ rl h
     ld l,a
     ld a,d
     ld d,0
     add hl,de
;HL points to the byte it will start on
     push hl
     ld d,a
     push bc
     call ComputeByte
     ld (rect_FirstByte),a
     ex (sp),hl
     ld a,d
     cpl
     and 7
     inc a
     ld b,a
     ld a,l
     sub b
     ex (sp),hl
     call ComputeByte
     cpl
     ld (rect_LastByte),a
;last and first byte are computed   
     ld a,d
     and %11111000
     ld e,a
     ld a,d
     add a,c
     and %11111000

     pop hl
     ex (sp),hl
     ld bc,(DrawBufPtr)
     add hl,bc
     pop bc

     sub e
     rrca
     rrca
     rrca
     and %00011111
     ret nz
     ld de,(rect_FirstByte)
     ld a,d \ and e
     ld c,a
     xor a
     ret
ComputeByte:
     and 7
     ld b,a
     ld a,80h
     jr z,$+5
       rrca
       djnz $-1
     add a,a
     dec a
     ret
I also made some text display routines, but they are pretty complicated, so I will have to organise them before posting.

820
TI Z80 / Re: Pokémon Amber
« on: July 17, 2013, 11:51:29 am »
Well, i've a nspire touchpad so the gba emulator doesn't work in this nspire. And this seems to be very cool
Hmm, the GBA emulator works on my CX CAS and the GBC emulator works on both of my nspires.

Also, a minor update:

There is now some basic walking and navigation. I am working on adding in the smooth scrolling part (I have the sprites for the player to walk, as well as the code done).
Smoothscrolling will probably slow things down to 1/4 the speed, depending on how I do it. That should make it a more comfortable speed.

821
ASM / Re: Non-Standard gBuf Ideas
« on: July 17, 2013, 09:12:14 am »
Yeah, in my app the shadow registers are free game (the interrupt routine preserves them). As for using IX, it depends on where it is used, because something like ld a,(ix+n) is 19 t-states, versus 7 for ld a,(hl).

822
TI Z80 / Re: Pokémon Amber
« on: July 17, 2013, 09:05:55 am »
Can you port it to nspire?
I can try. I do need to get experience with nspire programming.

that's amazingly fast. wonderful =)
if it's supposed to be the ancient past, are you going to have any trainers?
There will be trainers, but there will be a few other important design differences. There won't be a PC, so your bag will be bigger. It will be able to carry your items and 20 Pokémon. There will be places where you can drop off your Pokémon, too, like a daycare, and in order to retrieve your Pokémon, you need to go back to the specific daycare. Internally, going to a given daycare will be the equivalent of opening up a box in your PC. In your bag, there will be two pockets for items (one of them is analogous to the items box on your PC), a pocket for apricorns (ancient version of Pokéballs), a key items pocket, and a TM/HM pocket. HMs will also work differently in Amber.


I still need to work out a good storyline .__.

823
Hi Zeklandia, I am glad you got that fixed :)

In the future, try to avoid triple-posting so close together. Instead, editing your posts is preferred unless there is a major project update or it has been some hours since your last post.


(Tapatalk support would be very useful).
I believe we do have Tapatalk support. Chrome alerts me of this whenever I am not logged in.

824
TI Z80 / Pokémon Amber
« on: July 16, 2013, 08:19:39 pm »
Pokémon Amber is neither a clone, nor a port of a Pokémon game. It takes place 100 million years in the past, before Fossil Pokémon went extinct. After doing much research into ancient Pokémon, it is realised that we don't know the habitats of most Fossil Pokémon and there is some ambiguity in their types. What was the Pokémon world like 100 million years ago? What other Pokémon existed that have not been discovered? How have they adapted through time? These questions and more will play a key role in the development of Pokémon Amber.

Note: This game is not endorsed by Nintendo or any other Pokémon-affiliated organisation. This is just a game being developed by a fan purely for the enjoyment of others. There will be some creative liberties taken.

I thought I would start posting progress here instead of keeping it to my signature. As of yesterday, the following screenshot was up-to-date on showing progress:

As you can see, I have a scrolling, animated tilemap with proper clipping, and working text commands. As well, I wrote routines for easily making menu and drawing rectangles. Internally, there is a token set, so words that are used frequently in the game can be represented by 1 byte and menus can be somewhat interactive.

I ended up completely rewriting the graphics today, after analysing a different approach. This made the tilemap routine take about 60% of the time previously required (so it is a lot faster) and all of the current drawing got a speed boost (as well as LCD updating). My plan is to keep it running at 6MHz and it is currently energy friendly, I hope (it makes heavy use of the halt instruction).

Things I need to do:
I need to place a player sprite on the screen as well as NPCs and other objects. These are all handled by the event handler, so once I have that finished (probably a good hour or two of focused coding), then trees (or Vines, in this game), boulders, non-player characters, doorways, warp tiles, and all of that will be in working order.

I need to make a smooth-scrolled transition as the player walks. This will definitely slow things down, but that should be fine.

I have not started on battles, Pokémon, or Items yet.

This game will probably use a lot of RAM. I am trying to keep it all in non-user RAM, but that will not be possible with the storage system. Save data will be about 1000 bytes, plus however many Pokémon I allow in the PC (it is about 50 bytes for each Pokémon). So to use the PC system, I either need to have all the boxes in RAM or, only a few at a time (like how the first two generations required you to save every time you changed boxes, it was basically archiving the data and bringing a new box to RAM).

Sprites are going to be monochrome, 24x24 and I plan for 64 pokémon total. This means 4608 bytes of sprite data, but they will all have additional information, bloating it to around 6400 bytes for Pokémon data. Because of this, I will probably have map data and most other event data stored in archived appvars, unless somebody thinks it is a better idea to keep it all in a multi-page app. If I keep it separate, it might be easier to create new games.

Here is a more current image:

825
ASM / Non-Standard gBuf Ideas
« on: July 16, 2013, 02:02:25 pm »
I have had this idea since my first attempt at an OS, but I ran into a few problems. Basically, I wanted to store the graph buffer in columns because I thought it would be very useful for drawing tiles and updating the LCD. Then I started thinking about line drawing, circle drawing, and anything that would cross a byte boundary and I realised that some routines would take a major hit to speed.

I am working on a project and I am still trying to decide if it would be beneficial to organise the screen in this manner. Here is an example of a tile drawing routine using the current buffer setup:
Code: [Select]
drawtile:
;DE points to the sprite data
;BC = (y,x)
; draw an 8x8 tile where X is on [0,11] and Y is on [0,7]
     ld a,b
     add a,a
     add a,b
     add a,a
     add a,a
     add a,a
     ld h,0
     ld b,h
     ld l,a
     add hl,hl
     add hl,hl
     add hl,bc
     ld bc,(DrawBufPtr)
     add hl,bc

     ld bc,12
     ld a,8
       ex de,hl   ; 32
       ldi        ;128
       ex de,hl   ; 32
       add hl,bc  ; 88
       inc c      ; 32
       dec a      ; 32
       jr nz,$-7  ; 91
     ret
And here is how it looks the other way:
Code: [Select]
drawtile:
;DE points to the sprite
;BC = (y,x)
;X*64
     or a
     ld a,c
     ld l,0
     rra
     rr l
     rra
     rr l
     ld h,a
;y*8
     ld a,b
     add a,a
     add a,a
     add a,a
     add a,l
     ld l,a
     ld bc,(DrawBufPtr)
     add hl,bc
     ex de,hl
     ld bc,8
     ldir
     ret
The former is 565 t-states 33 bytes, the latter is 281 t-states 28 bytes. There are ways to optimise both routines for speed.
Spoiler For Optimised:
Taking the first routine and replacing the sprite drawing code:
Code: [Select]
     push hl \ pop ix
;IX points to where it gets drawn
;DE is the sprite layer
     ld a,(de)    ; 7
     inc de       ; 6
     ld (ix),a    ;19
     ld a,(de)    ; 7
     inc de       ; 6
     ld (ix+12),a ;19
     ld a,(de)    ; 7
     inc de       ; 6
     ld (ix+24),a ;19
     ld a,(de)    ; 7
     inc de       ; 6
     ld (ix+36),a ;19
     ld a,(de)    ; 7
     inc de       ; 6
     ld (ix+48),a ;19
     ld a,(de)    ; 7
     inc de       ; 6
     ld (ix+60),a ;19
     ld a,(de)    ; 7
     inc de       ; 6
     ld (ix+72),a ;19
     ld a,(de)    ; 7
     ld (ix+84),a ;19
     ret
Now it is 388 t-states (saving 187 cycles), but the cost is 25 bytes. The latter has a similar optimisation (unrolling). It saves only 45 t-states at the cost of 11 bytes by replacing the LD BC,8 \ LDIR with 8 LDI instructions.
If you have ever written your own LCD updating routine, you probably already realized just how straight forward this would make the routine (and if we had no LCD delay, it would amount to basically 12 iterations of ld b,64 \ outir). We typically don't need to optimise for speed with such an LCD update because most of the time, the code is waiting for the LCD to respond before moving to the next byte. However, if you are doing something like grayscale or interleaving another routine with the LCD update (like drawing a tilemap at the same time), this gives you even more time to do more complicated things with the LCD, putting your 'waste cycles' to more use.

Sprite Drawing
The reason for why some drawing will be so easy is that each 8 columns of pixels is 64 bytes which is much nicer to work with than a row of pixels being 12 bytes. We also see a huge boost in performance when moving down or up a pixel because that only requires an increment or decrement of a pointer, instead of adding 12 each time. However, now we get the same problem when moving left or right across byte boundaries. This means that sprite routines could take a hit, but let's see how far we can remedy this.

This will be a very simple routine to XOR an 8x8 sprite to the gbuf:
Code: [Select]
PutSprite8x8:
;Note: No clipping.
;Inputs:
;     BC = (x,y)
;     IX points to the sprite
;     1871 worst-case
     ld a,b
     and $F8
     ld h,0
     rla \ rl h
     rla \ rl h
     rla \ rl h
     ld l,a
     ld a,b
     ld b,0
     add hl,bc
     ld bc,9340h
     add hl,bc
;HL points to the first byte to draw at
     and 7
     jr nz,crossedbound
       push ix \ pop de
       ld b,8
         ld a,(de)
         xor (hl)
         ld (hl),a
         inc hl
         inc de
         djnz $-5
       ret
crossedbound:
     ld b,a
     dec a
     ld (smc_jump1),a
     ld (smc_jump2),a
     ld a,1
       rrca
       djnz $-1
     dec a
     ld e,a
     ld c,8
;E is the mask
;IX points to the sprite
;HL points to where to draw
drawloop1:
     ld a,(ix)
     .db 18h      ;start of jr *
smc_jump1:
     .db 0
       rlca
       rlca
       rlca
       rlca
       rlca
       rlca
       rlca
     and e
     xor (hl)
     ld (hl),a
     inc ix
     inc hl
     dec c
     jr nz,drawloop1
     ld c,56
     add hl,bc
     ld a,e
     cpl
     ld e,a
     ld c,8
drawloop2:
     ld a,(ix-8)
     .db 18h      ;start of jr *
smc_jump2:
     .db 0
       rlca
       rlca
       rlca
       rlca
       rlca
       rlca
       rlca
     and e
     xor (hl)
     ld (hl),a
     inc ix
     inc hl
     dec c
     jr nz,drawloop2
     ret
That actually turns out to be pretty fast, so if you need to draw sprites, this is still a viable buffer setup.

LCD Updating
As promised, the routine to update the LCD is fairly straight forward:
Code: [Select]
#define     lcddelay()  in a,(16) \ rlca \ jr c,$-3
     ld a,5
     out (16),a
     lcddelay()
     ld a,80h
     out (16),a
     ld hl,9340h
     lcddelay()
     ld a,20h
col:
     out (16),a
     push af
     ld bc,4011h
row:
     lcddelay()
     outi
     jr nz,row
     lcddelay()
     pop af
     inc a
     cp 2Ch
     jr nz,col
     ret

Note that if you are only ever doing fullscreen updates (or at least full columns) and you are always using the same increment mode, you can leave the first part of that code in a setup portion of your code:
Code: [Select]
     .org 9D93h
     .db $BB,$6D
Start:
     ld a,5        ;set the increment mode, only needs to be done once
     out (16),a
     lcddelay()
     ld a,80h    ;set the row pointer, only needs to be done once, since the LCD update routine leaves it where it started.
     out (16),a
Main:

<code>

UpdateLCD:
     ld hl,9340h
     ld a,20h
col:
     out (16),a
     push af
     ld bc,4011h
row:
     lcddelay()
     outi
     jr nz,row
     lcddelay()
     pop af
     inc a
     cp 2Ch
     jr nz,col
     ret

Pixel Plotting
Code: [Select]
;GetPixelLoc
;Inputs:
;     BC =(x,y)
;     DE is the buffer on which to draw
;Outputs:
;     Returns HL pointing to the byte where the pixel gets plotted
;     Returns A as a mask
;     NC returned if out of bounds, else C if in bounds
     ld a,c \ cp 64 \ ret nc
     ld a,b \ cp 96 \ ret nc
     and $F8
     ld h,0
     rla \ rl h
     rla \ rl h
     rla \ rl h
     ld l,a
     ld a,b
     ld b,0
     add hl,bc
     add hl,de
;HL points to the first byte to draw at
     and 7
     ld b,a
     ld a,1
     inc b
     rrca \ djnz $-1
     scf
     ret
Now to set the pixel, use or (hl)  \ ld (hl),a or use xor to invert, and to erase, cpl \ and (hl) \ ld (hl),a.

Final Analysis
It turns out that most drawing is faster and that my original fears were just based on me being too accustomed to one way of doing things. Line drawing, circle drawing, and rectangle drawing are all faster (lines and circles just because it is faster to locate a pixel, rectangles because it just works fantastically). Sprites, tiles, and LCD updating work out great. However, there is one area that does in fact take hit and that is scrolling the screen. Shifting up and down is still relatively easy, but shifting left and right will be slower and more complicated. Shifting up or down is just shifting the whole buffer 1 byte instead of 12, which is the same speed. Here is shifting right:
Code: [Select]
     ld hl,9340h     ;gbuf
     ld de,64
     ld c,e
loop:
     or a
     ld b,12
       rr (hl)
       push af \ add hl,de \ pop af
       djnz $-5
       dec h \ dec h \ dec h
       inc l
       dec c
       jr nz,loop
     ret
That is now half the speed of what it is for the current gbuf setup. We can cut out 9828 t-states if interrupts are off, though, but that is still a huge hit to speed.

Aside from that, I like the idea of organising the buffer this way.

EDIT: Modified a few routines to be smaller, no speed change, though.
EDIT2: Added a link to the rectangle routines below.

Pages: 1 ... 53 54 [55] 56 57 ... 317