Author |
Message |
|
asdf
Advanced Newbie
Joined: 17 Aug 2008 Posts: 73
|
Posted: 24 Aug 2008 09:45:18 pm Post subject: |
|
|
TylerMcL wrote: Also, the reason why I'm not designating the tilemap dimensions, is because once all my Soldier games are finished, I'd like to release some type of easy smooth-scrolling routine that would be interchangeable with tilemaps; meaning the user would not have to change anything except for the tiles and the tilemap Heh, that's one of the great features about adding in the dimensions, that you can then use pretty much any size tilemap. Also, just to make it clear what i am talking about, i mean adding the width/height and any other pertinent data (such as which tileset to use if you have more than one). So your tilemap would look something like this:
tileMap:
.db width
.db height
.db any,other,data
.db tilemapdata
aka
tileMap:
.db 14,12 ;14 tiles wide x 12 tiles down
.db 1 ;use tileset 1 (the second tileset)
.db 1,1,1,1,1,1,1,3,1,1,1,1 ;0
.db 1,0,0,0,2,0,0,0,0,0,4,1 ;1
.db 1,0,0,0,2,0,0,0,0,0,4,1 ;2
.db 1,0,0,0,2,0,0,5,0,0,0,1 ;3
.db 1,0,0,0,2,0,0,2,0,0,4,1 ;4
.db 1,0,0,0,2,2,2,2,0,0,4,1 ;5
.db 1,0,0,0,2,0,0,0,0,0,4,1 ;6
.db 1,0,0,0,2,0,0,0,0,0,0,1 ;7
.db 1,0,0,0,2,0,0,0,0,0,0,1 ;8
.db 1,0,0,0,2,0,0,0,0,0,0,1 ;9
.db 1,0,0,0,2,0,0,0,0,0,4,1 ;10
.db 1,1,3,3,3,1,1,1,1,1,1,1 ;11
If you are going to use your border idea, i think it would be wise to implement it into the scenery as you mentioned before. There are a few complications that might pop up but i think you can figure them out. For one, if you want to have more than one tile mark the edge (so that you can have more than one sprite on the map's perimeter), you can use one of the simplest methods of hit detection: shoving all non-passable tiles into a number range. So you might want all numbers less than 30 to be tiles your character can walk on, numbers above 50 are tiles on the perimeter (marking the borders), and numbers equal to or above 30 non-passable (which obviously also includes the border tiles, saving those which are "portals"/doors to other locations). One of the issues with this, however, would be that if you wanted to place a tree on the border, you would have to create another sprite (otherwise all trees placed in the middle of the map would try to tell the tilemap that you were at the border). There are a few ways to structure your tilemap to avoid this, and also ways to write your engine to get around this and other problems, but i'll leave that up to you for now!
And as for the coordinate system, i think what a lot of people are asking is how do will you know what sprite you are walking onto without one? Obviously, your player must have x/y coordinates on screen, and there must be a pointer to the first onscreen byte in the tilemap, so i think what you have in mind is sort of a roundabout way to using coordinates. Otherwise, i'm not sure how you will know which tiles to draw to the screen? And that pixeltest you are talking about, could you expand on that? I think you might be overcomplicating things a bit, but maybe i don't understand what you mean. In particular, that bit about the roof; are you talking about the back/top of the roof? or the side that might overhang from the main body of the house? |
|
Back to top |
|
|
TylerMcL
Member
Joined: 28 May 2008 Posts: 148
|
Posted: 24 Aug 2008 10:09:04 pm Post subject: |
|
|
lol, it sounds like I suck at explaining. I always have been, though :P
Alright, here I go:
...Yeah, I kinda looked into the specifics of not having any coordinates :/ I might have to change and improvise a little lol -- isn't that life?
My original plan was to designate a certain area in the ram for what is to be displayed on the screen, and when the character moved, I was going to move the entire map as well. I was naive and missed the obvious fact that this would take an enormous amount of computing and time. Not what I want.
This method might have been a good idea had I planned on creating all the maps as a bunch of separate tile-maps. I really want to just create maps as big as the application will allow.
I'm actually still considering having the program signed, and then enabled under the APPS menu. I would be able to use something like 2 App pages, (like 34,000 bytes) but I'm still contemplating it. Like I said, I'm really hoping I'll be able to apply to some scholarships, if this game becomes what I dream for it to be. :)
Oh yeah -- the hit detection:
hopefully the picture will help. I'm not exactly how I'm going to go about with all of this, but I'm thinking I'm going to have to make a "buffer" or something for the sprites that are designed like this. |
|
Back to top |
|
|
asdf
Advanced Newbie
Joined: 17 Aug 2008 Posts: 73
|
Posted: 25 Aug 2008 01:13:55 am Post subject: |
|
|
Hm.. well easier than a pixel detection method would be to give the sprites a width attribute or pull the roots out so that they reach that imaginary line.
And i'm not sure what you mean by buffer (sorry!) but i think what you might be talking about is similar to a mask, which might work really well if you want more accurate collision detecting, although it may be a bit overkill and use up a lot more space storing your tiles. But really, it's all about how you envision this game and not about how any of us do!
And writing it as an APP is not a bad idea either, but keep in mind there are differences between programming an application and a regular program, due to its being run from FLASH memory and the way applications are handled/loaded in memory. Anyway, your enthusiasm is very refreshing and nice to see |
|
Back to top |
|
|
cjgone Aw3s0m3
Active Member
Joined: 24 May 2006 Posts: 693
|
Posted: 25 Aug 2008 04:05:08 pm Post subject: |
|
|
Pixel collision is definite overkill. Don't waste your time and it won't add anything being able to walk two more pixels inward.
You either want your tile map redrawn every loop like:
Code: main:
Call draw_tile_map_to_LCD
Call draw_objects
Call draw_character
Call getkeys
jr main
Left: //key left
ld a,(xcor)
dec a
ld (xcor),a
ret
//etc
or
Code: main:
Call copy_buffer1_to_LCD
Call draw_objects
Call draw_character
Call getkeys
jr main
Left:
ld a,(xcor)
dec a
ld (xcor),a
Call update_tilemap
ret
//etc
buffer1:
//this is where the tile map was drawn too
2nd method is more effecient, but it doesn't allow animated tiles without external objects.
Last edited by Guest on 25 Aug 2008 05:00:18 pm; edited 1 time in total |
|
Back to top |
|
|
asdf
Advanced Newbie
Joined: 17 Aug 2008 Posts: 73
|
Posted: 25 Aug 2008 09:12:46 pm Post subject: |
|
|
Well, i can see giving each tile a width/height along with a mask being somewhat useful if you want to allow the player to walk under or behind certain sprites. |
|
Back to top |
|
|
TylerMcL
Member
Joined: 28 May 2008 Posts: 148
|
Posted: 25 Aug 2008 09:58:48 pm Post subject: |
|
|
yeah, I gotta agree with asdf. It's just that when I was playing verdante forest, it was a major "WOW" factor when I found out that I could walk behind certain trees, and such. It just makes the game look more professional, and it's really not that hard. And it's not like I don't have the extra cycles to do so
Last edited by Guest on 29 Aug 2008 12:16:30 pm; edited 1 time in total |
|
Back to top |
|
|
TylerMcL
Member
Joined: 28 May 2008 Posts: 148
|
Posted: 29 Aug 2008 12:18:08 pm Post subject: |
|
|
Soo... I've kinda just started on the tilemap engine. I've got a very [small]small[/small] amount of work done, but I also have a few questions:
Let me start off by giving what little I have done with the tilemap engine. This bit of code simply moves what is already on the screen one time to the right.
Code: ; The "Move_Tile_Map_Right" instructions are called upon only once per getkey response. (A.k.a initializing )
Move_Tile_Map_Right:
ld hl, right_map_buffer
SRL (hl)
PUSH hl
ld b, 64; 64 rows for the graph buffer
ld hl, PlotSScreen
Jr Move_Right
Load_Right_Buffer:
ld d, h
ld e, l
POP hl
INC hl
SRL (hl)
PUSH hl
ld h, d
ld l, e
Move_Right:
RR (hl)
INC hl
RR (hl)
INC hl
RR (hl)
INC hl ; Waste a little bit of space for some speed.
RR (hl) ; Repeats the RR and INC instructions 12 times, for obvious reasons. :P
INC hl
RR (hl)
INC hl
RR (hl)
INC hl
RR (hl)
INC hl
RR (hl)
INC hl
RR (hl)
INC hl
RR (hl)
INC hl
RR (hl)
INC hl
RR (hl)
INC hl
DJNZ Load_Right_Buffer
POP hl
So there's that. I've got to be honest, it's really one of the very first bits of code that I've ever written, so "how's it looking"?
And here's another question:
When I try to copy a graphic (e.g. The "SOLDIER" logo) and then try to display some text using "Call(_VPutS)" (e.g. New Game, Load Game) it doesn't exactly work :/ It was a little while ago I tried this, but if I recall correctly, it displayed only the text :/ Any help?
And another one:
What is the difference between "Call()" and "b_call()"?? I have no idea, honestly.... :(
And this is my last question (I promise. Well, just for this post anyway ):
What's this "ionfastcopy" that I've been reading about? I checked all the Tasm and .inc files and I found nothing in a search. Is this something that useful that I would want to be using? Regardless, what exactly is different about it than "GrBufCpy"? I read something about one being vertical and the other horizontal. so.... yeah :D
Thanks for all the help everyone! And sorry about the double posts. I'm at the library until 5:00 today (it's about 1:15 here in Michigan), and I was hoping to get some help before I leave :/
Last edited by Guest on 29 Aug 2008 12:21:12 pm; edited 1 time in total |
|
Back to top |
|
|
Galandros
Active Member
Joined: 29 Aug 2008 Posts: 565
|
Posted: 29 Aug 2008 12:29:06 pm Post subject: |
|
|
I can help a bit.
About the text display see if your inputs are correct and you must use a b_call not a call for vputs.
I am not the better person to explain well the difference of call or b_call. For usage thing b_call is when you use a routine from the OS and call a routine made by yourself in your program. I could write something more about b_call but would only confuse you. XD
ionfastcopy is a routine from Ion for copying the buffer (plotsscreen) to the lcd display. It is equivalent to the b_call(gbufcopy) but faster.
EDIT: explained better
Last edited by Guest on 29 Aug 2008 12:31:48 pm; edited 1 time in total |
|
Back to top |
|
|
TylerMcL
Member
Joined: 28 May 2008 Posts: 148
|
Posted: 29 Aug 2008 12:39:29 pm Post subject: |
|
|
Alright, that hit "two birds with one stone" That might be why it didn't want to work for me I'll remember this and try it a different day. Right now I'm actually doin a little homework for my AP classes, but after that I'm going to continue working on my game tonight I know exactly how I'm going to do the tile-mapper; now all I have to do is actually make it :P
And I'm guessing that bit of code looks alright? Is there anyway to optimize anything as small as that? |
|
Back to top |
|
|
Galandros
Active Member
Joined: 29 Aug 2008 Posts: 565
|
Posted: 29 Aug 2008 01:13:56 pm Post subject: |
|
|
I noticed that:
ld h,d
ld l,e
could be replaced with:
ex de,hl ;this exchanges the contents of hl and de
Optimizing speed and size :biggrin:
About the shifts instructions they seem right but I suspect something in the algorithm. And I can not figure an alternative to optimize further.
Last edited by Guest on 29 Aug 2008 01:18:19 pm; edited 1 time in total |
|
Back to top |
|
|
TylerMcL
Member
Joined: 28 May 2008 Posts: 148
|
|
Back to top |
|
|
cjgone Aw3s0m3
Active Member
Joined: 24 May 2006 Posts: 693
|
Posted: 29 Aug 2008 01:57:07 pm Post subject: |
|
|
Using getkey for presses is slow and not worthwhile. Use direct input.
Last edited by Guest on 29 Aug 2008 02:15:48 pm; edited 1 time in total |
|
Back to top |
|
|
TylerMcL
Member
Joined: 28 May 2008 Posts: 148
|
Posted: 29 Aug 2008 02:04:42 pm Post subject: |
|
|
I just meant that it will disable how the ON button normally stops the program and reports and error. I'm not completely sure about the specifics, I just know that it stops the ON button from doing anything useful, really. :/ |
|
Back to top |
|
|
Liazon title goes here
Bandwidth Hog
Joined: 01 Nov 2005 Posts: 2007
|
Posted: 30 Aug 2008 04:24:27 am Post subject: |
|
|
he's writing an rpg, getkey is more than enough. often direct input w/o much modificaton can often be too fast for rpg elements like menus, selection etc. Also less code to put in the program. |
|
Back to top |
|
|
asdf
Advanced Newbie
Joined: 17 Aug 2008 Posts: 73
|
Posted: 01 Sep 2008 03:27:54 am Post subject: |
|
|
TylerMcL wrote: Code: ; The "Move_Tile_Map_Right" instructions are called upon only once per getkey response. (A.k.a initializing )
Move_Tile_Map_Right:
exx ; 4 cycles, 1 byte each. push/pop take 11 cycles and 1 byte each
ld hl, right_map_buffer
exx ; back to normal registers
ld b, 64; 64 rows for the graph buffer
ld hl, PlotSScreen
Load_Right_Buffer:
exx ; shadow registers
SRL (hl)
INC hl
exx ; normal registers
Move_Right:
RR (hl)
INC hl
RR (hl)
INC hl
RR (hl)
INC hl ; Waste a little bit of space for some speed.
RR (hl) ; Repeats the RR and INC instructions 12 times, for obvious reasons.
INC hl
RR (hl)
INC hl
RR (hl)
INC hl
RR (hl)
INC hl
RR (hl)
INC hl
RR (hl)
INC hl
RR (hl)
INC hl
RR (hl)
INC hl
RR (hl)
INC hl
DJNZ Load_Right_Buffer So there's that. I've got to be honest, it's really one of the very first bits of code that I've ever written, so "how's it looking"?
I tried optimizing it a little. Interrupts should be disabled if you use the shadow registers, though. And like cjgone said, i would use Direct Input for this. You don't get all the nasty side effects of GetKey (like the 2nd/Alpha logos when you press either button and not being able to use either button individually. GetKey also enables interrupts) and it is much quicker and more versatile (you can detect multiple keypresses, allowing your character to walk diagonally). And the only register it will use is the accumulator.
TylerMcL wrote: And here's another question:
When I try to copy a graphic (e.g. The "SOLDIER" logo) and then try to display some text using "Call(_VPutS)" (e.g. New Game, Load Game) it doesn't exactly work :/ It was a little while ago I tried this, but if I recall correctly, it displayed only the text :/ Any help?
A lot of the time, the issue is that by default this routine only writes to the screen, and not the graph buffer. Therefore, after you've drawn your logo and then your text and go to draw the buffer to the screen, you will see the text briefly before the rest of the screen is drawn and it will disappear (because the buffer is just your logo without the text). You can use this command to force it to write to the gbuf only: set textwrite,(iy+sgrflags) ;vputs/vputmap commands to gbuffer. I don't know what your problem was other than, like mentioned, for the commands in ti83plus.inc you must use B_CALL (or bcall, if you prefer and have it defined).
Quote: And another one:
What is the difference between "Call()" and "b_call()"?? I have no idea, honestly....
What call does (it doesn't require parentheses because it is not a macro, it is a command) is push the location of the next instruction onto the stack and jumps to a memory location that you tell it. Like this:
Code: 0001 call label ;the call instruction takes up 3 bytes
0004 ret
label:
0005 inc a
0006 ret
What happens is when you run across the call instruction, it pushes 0004 onto the stack because that is where you want the program to return when the routine is done. it then jumps to "label", which is actually a pointer to the address 0005. From there, we inc a and then ret. What the ret instruction does is jump to the address pointed to by the stack, in this case it is 0004. So we jump to address 0004. This has a lot of interesting things you can do, some useful, some not so much. For example, you can do this:
Code: loop:
ld hl,loop
push hl
cp 0
jr z, lbl0
cp 1
jr z, lbl1
cp 2
jr z, lbl2
cp 3
jr z, lbl3
cp 4
jr z, lbl4
cp 5
jr z, lbl5
ret
lbl0:
...stuff...
ret
lbl1:
...stuff...
ret
lbl2:
...stuff...
ret
lbl3:
...stuff...
ret
lbl4:
...stuff...
ret
lbl5:
...stuff...
ret
When it hit any of the rets in this code, you will jump back to label "loop". If you want to jump to another location, you could do something like this:
Code: ld hl,location2
push hl
call label
..blah..
label:
cp 0
ret z
pop hl
ret In this case, you would jump to "label" and if a = 0, you would return to the address located right after your call. If a does not equal zero, you would pop the address that points to the byte after your call off the stack and the next item on the stack would be location2's address, so you would jump to that.
Anyway, you may or may not find any of this useful, this was more to try and clarify how calls work.
B_CALLs are a bit trickier, and i don't understand fully how it works, but i'll tell you as much as i can (and maybe tell you some things that i don't know for certain, and may not be true). Anyway, a B_CALL is actually the statement rst $28 followed by the address to your bcall. RST will drop the PC counter to the address $0028, where it will jump to another location in RAM where it will swap out ROM banks if necessary so that your B_CALL can be run.
For right now, i think you can get by just knowing that call is used to call routines WITHIN your program, whereas B_CALL is used to sort through/run system routines.
Quote: And this is my last question (I promise. Well, just for this post anyway ):
What's this "ionfastcopy" that I've been reading about? I checked all the Tasm and .inc files and I found nothing in a search. Is this something that useful that I would want to be using? Regardless, what exactly is different about it than "GrBufCpy"? I read something about one being vertical and the other horizontal. so.... yeah :D
Thanks for all the help everyone! And sorry about the double posts. I'm at the library until 5:00 today (it's about 1:15 here in Michigan), and I was hoping to get some help before I leave :/
[post="126461"]<{POST_SNAPBACK}>[/post]
Well, ionfastcopy is a "fastcopy" routine, it is much faster than the B_CALL "GrBufCpy". If you search online, you will probably find source code for it, or if you are writing a program for a shell it probably includes a fastcopy routine in its include file (assuming it has one). I found a copy of the source here (search "ionfastcopy").
I hope i explained things ok. If anything isn't clear, let me know and i'll elucidate.
See ya.
EDIT:
Liazon wrote: he's writing an rpg, getkey is more than enough. often direct input w/o much modificaton can often be too fast for rpg elements like menus, selection etc. Also less code to put in the program.
[post="126486"]<{POST_SNAPBACK}>[/post]
I find GetCSC works nice for menus and also allows you to handle 2nd/Alpha keypresses.
Last edited by Guest on 01 Sep 2008 03:36:22 am; edited 1 time in total |
|
Back to top |
|
|
cjgone Aw3s0m3
Active Member
Joined: 24 May 2006 Posts: 693
|
Posted: 02 Sep 2008 02:44:45 pm Post subject: |
|
|
? Use a call table?
Code: ; a = some number
ld hl, Table
add a,a; times 2, an address is two bytes
ld e,a
ld d,0
add hl,de
ld e,(hl)
inc hl
ld d,(hl)
ld hl,End_loop
push hl
push de
ret
End_Loop:
;more crap
Table:
.dw Task1
.dw Task2
.dw Task3
.dw Task4
|
|
Back to top |
|
|
Liazon title goes here
Bandwidth Hog
Joined: 01 Nov 2005 Posts: 2007
|
Posted: 02 Sep 2008 09:21:23 pm Post subject: |
|
|
ya, that's true. getcsc is pretty good too.
as for handling tasks, sometimes it really depends on what and how many things are there. |
|
Back to top |
|
|
TylerMcL
Member
Joined: 28 May 2008 Posts: 148
|
Posted: 02 Sep 2008 10:11:35 pm Post subject: |
|
|
oh jeez, asdf, your explanations helped a ton! I mean -- ALOT. Thanks for the clarification on the few things.
Well, I finally got my car today, and then had work later in the evening. Oh yeah! And it was the first day of school! that's always a joy :D
I've got to get to bed early tonight to wake up early tomorrow morning to go buy a parking pass and all that B.S. But I don't have work tomorrow, so all I really have to do is a few miscellaneous chores, and detail the car. I PROMISE to get some more code out here by tomorrow! I think I'm going to design part of the engine that deciphers (interprets) the tilemap. I'm going to assign a few sprites to the tilemap's numbering system (it's I.D.) and go from there. Like it's already been shown in previous posts, I'm going with the method that uses a very small buffer to increase speed, even if just a little. I'm not going to have the engine draw anything more if the first byte it reads is anything other than a 0000 0000. That way is should save a few cycles by not having to redraw everything and clip it all before it's re-pasted onto the screen. I'll explain more tomorrow, if need be.
And, I'm taking any support for map sprites. I already have all the enemy, battle sprites designed and typed in; now all I need is Map sprites and user battle sprites.
And one last thing before I go to bed: I've designed an AMAZING compression technique. AMAZING, I tell you! I don't think anything like it has ever been done before, and it is relatively easy to comprehend, and creates the opportunity so that one English letter will only take 4 bits/ .5 bytes. That's an immediate compression ratio of 50%!!!
More on the compression thing tomorrow night. It's an awesome strategy for us RPG guys, or any programmer, alike |
|
Back to top |
|
|
Art_of_camelot
Member
Joined: 05 Jan 2008 Posts: 152
|
Posted: 03 Sep 2008 10:16:30 pm Post subject: |
|
|
Quote: And one last thing before I go to bed: I've designed an AMAZING compression technique. AMAZING, I tell you! I don't think anything like it has ever been done before, and it is relatively easy to comprehend, and creates the opportunity so that one English letter will only take 4 bits/ .5 bytes. That's an immediate compression ratio of 50%
Chances are if you can envison something, several other people have already had the same thought occur and acted on it. However, I am interseted to see what you have come up with. |
|
Back to top |
|
|
Liazon title goes here
Bandwidth Hog
Joined: 01 Nov 2005 Posts: 2007
|
Posted: 04 Sep 2008 03:56:30 pm Post subject: |
|
|
so what about the punctuation? |
|
Back to top |
|
|
|