Jump to content
Gemintronic

Destiny WIP

Recommended Posts

Here's a version with some asm

 

The asm routine is in a macro.

putting it in a macro allows passing a data statement

as a parameter to a particular instance.

 

 macro WRIPFMAC
asm
ldx {2}
ldy {3}
lda {4}
clc
adc {2}
sta {4}
WRI_LOOP
lda {1},y
sta $A4,x
iny
inx
cpx {4}
bcc WRI_LOOP
end
end

To use it as a subroutine you'd give a label,

invoke the macro with it's four parameters

then supply a return.

 

The four parameters (in this order) are:

 

The name of the data statement.

 

The variable used to pass the location of the first byte to be

written in the playfield.

 

The variable used to pass the location of the first byte in the

data statement.

 

The variable used to pass the number of bytes to move and this

one gets modified.

 

So eg you create a subroutine using the macro.

Then to use it set up the three variables and call the subroutine.

 pf_ptr = 0 : dat_ptr = top_tbl[top] : dat_len = 12
gosub WRI_PF
pf_ptr = 12 : dat_ptr = mid_tbl[mid] : dat_len = 20
gosub WRI_PF
pf_ptr = 32 : dat_ptr = bot_tbl[bot] : dat_len = 12
gosub WRI_PF
return otherbank

WRI_PF

callmacro WRIPFMAC room_dat pf_ptr dat_ptr dat_len

return thisbank

 

 

http://pastebin.com/W3pWSNS9

 

Here's a second macro. Use is the same.

 

This has a little more overhead but is faster in the loop

so you save a few cycles for moving more than 1 line.

 

It also costs a few more bytes

 

It uses temp variables temp1-temp4 but doesn't touch the

parameter variables.

macro WRIPFMAC
asm
lda #$00
sta temp2
ldy {4}
clc
lda #$A4
adc {2}
sta temp1
lda {3}
adc #<{1}  
sta temp3
lda #>{1}
adc #$00
sta temp4
WRI_LOOP
lda (temp3),y
sta (temp1),y
dey
bpl WRI_LOOP
end 
end

Edited by bogax

Share this post


Link to post
Share on other sites

Thanks again, bogax. Also, for using the words "streamline" instead of "clean up his rubbish code" :P

 

Speaking of which, does this still run over CPU cycles with the new inline asm bogax cooked up?

Share this post


Link to post
Share on other sites

Speaking of which, does this still run over CPU cycles with the new inline asm bogax cooked up?

 

I think the short answer is yes

 

fact is, I've forgotten what all I've done about that

 

I said in a previous post that it was still going over even

with a liberal sprinkling of drawscreens

 

I'm not seeing that now

 

I put a drawscreen at the beginning of the print_style

routine and that seems to take care of it even with the

for-next loop version.

Share this post


Link to post
Share on other sites

I told bogax the other day that I would try to make a version of your original program with the new data that VbB can produce, but the code seemed to hop to a million places, so I couldn't figure out how to use all the data I already converted after using Generate Items From Code. I gave up on that and decided to use the latest code that bogax posted. Here's the playable version of his code:

 

destiny0001_with_asm.bin

 

 

 

I took his code and stuffed in an adapted version of my smooth collision/collision prevention code to see if it would work. I'm not sure if all of the numbers have been converted correctly, but it seems to be working. I also fixed it so objects in rooms won't visually hop around or share the score color for a fraction of a second. Here's my adapted version:

 

destiny0001_with_asm_and_smooth_collision_2012y_12m_01d_0725t.bin

 

destiny0001_with_asm_and_smooth_collision_2012y_12m_01d_0725t.bas

 

 

Move the joystick and 'rub' the little rectangle along the walls diagonally and you should see a difference.

Share this post


Link to post
Share on other sites

I truly appreciate the contributions here. Although I am still wrapping my head around bogaxs changes :)

 

Also, thank you RT for looking at the visible warping of objects as they try to find a free place on-screen. Just so I understand: your fix was to set the objects color to the same one as the floor?

Share this post


Link to post
Share on other sites

I truly appreciate the contributions here. Although I am still wrapping my head around bogaxs changes :)

 

Also, thank you RT for looking at the visible warping of objects as they try to find a free place on-screen. Just so I understand: your fix was to set the objects color to the same one as the floor?

 

Yep, I made the object the same color as the background until it finds its final resting place, but I figured the player might still see the object if it overlaps the playfield pixels while doing its dance, so I put it behind the playfield pixels using CTRLPF = $25. I also added COLUP0 = _objectcolor under print_style so the object will never turn red.

 

If someone with better programming skills can double check the numbers in my smooth collision/collision prevention code, then we won't have to worry if there are any hidden problems with that. I love gliding along walls instead of sticking to them.

Share this post


Link to post
Share on other sites

bogax pointed out a flaw that was still causing CPU cycle overruns. Basically, my bit shifting code is taking up too much time. Unfortunately this is also the crux of level creation for Destiny. It relies on the value gameseed to control which rooms appear where. Without sufficient bit shuffling the distribution is pretty weak - meaning the level layout has recognizable, repeatable patterns.

 

My only solution is to add additional drawscreens during bit shuffling. I dunno is any of the assembly wizards have a better pseudo random number generator that can be cut-and-pasted in?

Share this post


Link to post
Share on other sites

I tried it over and over again, but so far the program hasn't stopped in Stella using autoexec.stella.

I expect that's because I added a drawscreen at the beginning of

print_style routine.

 

I rewrote the randomization stuff to speed it up but it's not enough.

edit: looks like adding inlinerand might do it

calc_roomtype

if dungeonlvl{1} then temp2 = %00100100 : temp3 = %00000010 else temp2 = 0 : temp3 = 0

if worldx{0} then temp1 = %01001001 : temp2 = temp2 | %00000001 else temp1 = 0
if worldy{6} then temp1 = temp1 | %00000010
if worldy{0} then temp1 = temp1 | %00010000
if dungeonlvl{0} then temp1 = temp1 | %00100100
if worldy{2} then temp1 = temp1 | %10000000

temp1 = temp1 * 2 + temp1

if worldy{4} then temp2 = temp2 | %00000010
if temp1{7} then temp2 = temp2 | %00001000
if worldy{1} then temp2 = temp2 | %00010000
if worldx{1} then temp2 = temp2 | %01000000 : temp3 = temp3 | %00000001
if temp1{1} then temp2 = temp2 | %10000000

if dungeonlvl{5} then temp3 = temp3 | %00000100
if worldx{2} then temp3 = temp3 | %00001000
if worldy{2} then temp3 = temp3 | %00010000
if dungeonlvl{2} then temp3 = temp3 | %00100000
if temp1{3} then temp3 = temp3 | %01000000
if worldy{7} then temp3 = temp3 | %10000000

temp1 = temp1 * 2 + temp2 + temp3 + gameseed

if temp1 then rand = temp1 else rand = 255

roomtype = rand

tempvar = rand + worldx + worldy

if counter > 230 then roomtype = rand

if worldx = 128 && worldy = 128 && dungeonlvl = 1 then roomtype = 1

rclass = roomtype / 4 / 4 : roomtype = roomtype & $0F
if rclass = 15 then rclass = style_a
return thisbank

Edited by bogax

Share this post


Link to post
Share on other sites

I've gotta say, I really like this idea! A multi floor, randomly generated dungeon crawler where you collect treasure and bank it back at floor 1 sounds awesome to me. One thing you could do to keep count of both the rings and your floor, is to add 1000 to your score every time you go up (and subtract each time you go down), and add 1 for every ring you collect. This way it simulates 2 3-digit 'scores'. Just an idea anyway. Keep it up :)

Share this post


Link to post
Share on other sites

I've gotta say, I really like this idea! A multi floor, randomly generated dungeon crawler where you collect treasure and bank it back at floor 1 sounds awesome to me. One thing you could do to keep count of both the rings and your floor, is to add 1000 to your score every time you go up (and subtract each time you go down), and add 1 for every ring you collect. This way it simulates 2 3-digit 'scores'. Just an idea anyway. Keep it up :)

 

Thanks for the words of encouragement. I was kinda thinking of using the score either for an inventory display or..

 

..have the score be the combination time limit / hit points ala Gauntlet or E.T.

 

Does that make sense?

Share this post


Link to post
Share on other sites

 

That's actually pretty cool. I don't know how I missed that. I'll make sure to study the examples.

 

I'm actually more hot and bothered about using the new bit-array reading techniques from bogax to make multi-screen levels. I don't know where I'm going wrong. Here's my attempt to print out the top left hand screen from a 2x2 screen DATA array. It prints out very strange.

 

The main idea is to treat a DATA statement like a 2 dimensional binary array so you could do things like map(x,y) and get 1 for solid or 0 for space.

bitplayfield3.zip

Share this post


Link to post
Share on other sites

Just for comparison THIS bit of code works fine for DATA statements that are *just* big enough for one screen. I'd like a bit array much larger than one screen that I can scroll through.

 

 set romsize 4k

dim mapx = a
dim mapy = b
dim cell = c
dim cellx = d

COLUPF=$FF
COLUBK=$00

mapx = 0
mapy = 0

printcol
for mapy = 0 to 10 : gosub printrow : next
goto main

printrow
for mapx = 0 to 31 : gosub printpf : next
return

printpf
cellx = mapx & 7
cell = mapy + mapy * 3 + mapx / 8
if map[cell] & setbits[cellx] then pfpixel mapx mapy on else pfpixel mapx mapy off
return

main
drawscreen
goto main


rem use an adressable set of masks so you can point
rem to them with a variable
data setbits
%10000000, %01000000, %00100000, %00010000
%00001000, %00000100, %00000010, %00000001
end

data clearbits
%01111111, %10111111, %11011111, %11101111
%11110111, %11111011, %11111101, %11111110
end


data map
%11111111, %11111111, %11111111, %11111111
%10000000, %00000000, %00000000, %00000001
%10100000, %00000000, %00111111, %11111001
%10100000, %00100000, %00100000, %00110001
%10100000, %00100000, %00100000, %11000001
%10100000, %00101111, %11100011, %00000001
%10100000, %00111000, %00001100, %00000001
%10100000, %00000000, %00110000, %00000001
%10111111, %11111111, %11000000, %00000001
%10000000, %00000000, %00000000, %00000001
%11111111, %11111111, %11111111, %11111111
end

Share this post


Link to post
Share on other sites

I'm actually more hot and bothered about using the new bit-array reading techniques from bogax to make multi-screen levels. I don't know where I'm going wrong. Here's my attempt to print out the top left hand screen from a 2x2 screen DATA array. It prints out very strange.

 

The main idea is to treat a DATA statement like a 2 dimensional binary array so you could do things like map(x,y) and get 1 for solid or 0 for space.

 

It looks like you might have a slight data visualization problem here. I could be wrong since I don't know what you think it should look like, but from the way you have your data table laid out, it seems like you have 64 bits per rows instead of 32 bits per row (you are only going to be accessing 32 bits per row, per screen). So, while you are expecting to see a bitmap of the first "half" of each row, what the program is actually printing is this:

 

 data map
%11111111, %11111111, %11111111, %11111111,
%11111111, %11111111, %11111111, %11111111
%10000000, %00000000, %00000000, %00000001,
%10000000, %00000000, %00000000, %00000001
%10100000, %00000000, %00111111, %11111001,
%10100000, %00000000, %00111111, %11111001
%10100000, %00100000, %00100000, %00110001,
%10100000, %00100000, %00100000, %00110001
%10100000, %00100000, %00100000, %11000001,
%10100000, %00100000, %00100000, %11000001
%10100000, %00101111, %11100011, %00000001,
%10100000, %00100001, %11100011, %00000001
%10100000, %00111000, %00001100, %00000001,
%10100000, %00000000, %00001100, %00000001
%10100000, %00000000, %00110000, %00000001,
%10100000, %00000000, %00110000, %00000001
%10111111, %11111111, %11000000, %00000001,
%10111111, %11000001, %11000000, %00000001
%10000000, %00000000, %00000000, %00000001,
%10000000, %00000000, %00000000, %00000001
%11111111, %11111111, %11111111, %11111111,
%11111111, %11111111, %11111111, %11111111
%10101010, %01010101, %01010101, %01010100,
%01010101, %01010001, %01010101, %01010101
%10000000, %00000000, %00000000, %00000001,
%00000000, %00000000, %00000000, %00000001
%10000000, %00000000, %00000001, %10000001,
%00100000, %00000000, %00111111, %11111001
%10000000, %00100000, %00000000, %00110001,
%00100000, %00100000, %00100000, %00110001
%10000000, %00100000, %00000000, %11000001,
%00100000, %00100000, %00100000, %11000001
%10000000, %00101111, %10000011, %00000001,
%00100000, %00100111, %11100011, %00000001
%10000000, %00111000, %00000000, %00000001,
%00100000, %00111000, %00001100, %00000001
%10000000, %00000000, %00000000, %00000001,
%00100000, %00000000, %00110000, %00000001
%10000000, %11111111, %00000000, %00000001,
%10000011, %10000011, %11000000, %00000001
%10000000, %00000000, %00000000, %00000001,
%10000000, %00000000, %00000000, %00000001
%11111111, %11111111, %11111111, %11111111,
%11111111, %11111111, %11111111, %11111111
end

 

That's what you'll see if you insert a hard return at the midway point in each row of your table. You'll see that the output of your program matches exactly the first ten rows of the bitmap image you are feeding it, but maybe not the way you were expecting it.

 

Look at my attached version (I re-mapped the table to read "JROK WAS HERE") and see if it makes sense to you. The way you laid out your table, it looks to me like you thought it was reading bytes 0-3, then bytes 8-11, then bytes 16-19, etc. You could still potentially lay it out your way, just add a table pointer that accounts for the 4-byte shift when it picks which row to print.

 

I also saved you 34 bytes by wrapping your bitmapper into a single for-loop.

 

Cheers,

J

bitplayfield4.bas.bin

bitplayfield4.bas

Edited by jrok

Share this post


Link to post
Share on other sites

First off if you're going to do things that are in whole

bytes it'll be much faster to handle things in whole bytes

 

So for example assuming the line in the data statement

that goes to a line in the playfield starts at the

beginning of a byte and ends at the end of a byte

(ie it does NOT start half way through a byte, say at bit 4,

and ending half way through a byte at bit 4)

then it will be much faster to just transfer the 4 bytes

than call pfpixel 32 times.

 

pfpixel "knows" about rows and columns but the data

statement doesn't.

 

You've got 8 bytes per line in the data statement.

the first row starts at 0

0-7 bytes inclusive for the first line in the data statement.

The second line of the data statement begins with byte 8 of the

data statement, bytes 8-15 inclusive etc

4 bytes per line of the playfield (columns 0-31 inclusive)

so the playfield lines correspond to data statement bytes like so

(for the upper left corner of the data statement)

 

pfrow pfbytes data statement bytes

0 0-3 0-3

1 4-7 8-11

2 8-11 16-19

 

 

You could do something like in this post:

 

http://www.atariage....50#entry2641780

 

and build a counter in for-next loops that counts by bits

bytes and rows in the data statement except instead of taking

an early out at 28 bits you'd take your early out at four bytes

You wouldn't need a special test you'd just need a for-next loop

that counted the correct four bytes. (an early out being 'quit this

data statement row and go to the next data statement row')

 

And of course it'll have to maintain a pfpixel columns, rows counter

in parallel

pfcolumns advance on every bit and get reset to 0 after

every four bytes.

pfrows advance every four bytes.

 

 

edit:

you elaborated while I was composing

you could still do something similar except maybe

count through the data statement by bits and rows

taking your early out after 32 bits which would

be, I suppose, when you've finished one playfield row

data statement rows would still go by 8 bytes

data statement bits would have to pick out the correct

32 bits, which would be the same for each row

you'd start at some bit and row in the data statement

count through data statement bit and pfcolumns in parallel

and when you've done 32 bits of the playfield column

go to the next data statement row reseting every thing

to where ever it needs to be for the next row (pfcolumn

to 0, data statement bit to the starting bit in the row,

pfrow to the next pfrow)

 

or you could still count through the data statement by

bits, bytes, and rows which I think would be faster

but probably not faster enough to make it worth the added

complication.

 

.

Edited by bogax

Share this post


Link to post
Share on other sites

Here's an UNTESTED routine that counts through

pf columns and rows maintaing a ds_byte counter

and a current_bit counter in parallel

 

You supply it with the first column and row

from the data statement in ds_col and ds_row

there's 64 columns 0-63 in the data statement but

you only want to go up to 32 or you'll get into

the next data statement row when writing the

playfield

obviously, rows will be similar and if you go too

far you'll fall off the end of the data statement

 

http://pastebin.com/JyGxd3dv

 

dim pf_row = a
dim pf_col = b
dim ds_start_bit = c
dim current_bit = d
dim current_byte = e
dim ds_byte = e
dim ds_col = g
dim ds_row = h

printpf

ds_byte = ds_col / 8
ds_byte = ds_row * 8 + ds_byte
ds_start_bit = ds_col & 7

for pf_row = 0 to 10
current_bit = setbits[ds_start_bit]
current_byte = map[ds_byte]

for pf_col = 0 to 31
if current_byte & current_bit then pfpixel pf_col pf_row on else pfpixel pf_col pf_row off
current_bit = current_bit / 2

rem if current_bit = 0 then done with one
rem data statement byte so go to the next
rem get the corresponding map byte
rem and reset current_bit to the first bit column
if current_bit = 0 then ds_byte = ds_byte + 1 : current_byte = map[ds_byte] : current_bit = $80
next

rem we have incremented ds_byte by 4
rem in the pf_col loop
rem 8 bytes per data statement row
rem we need to advance 4 more to go to the
rem next row in the data statement
ds_byte = ds_byte + 4
next
return

data setbits
%10000000, %01000000, %00100000, %00010000
%00001000, %00000100, %00000010, %00000001
end

data map
%11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111
%10000000, %00000000, %00000000, %00000001, %10000000, %00000000, %00000000, %00000001
%10100000, %00000000, %00111111, %11111001, %10100000, %00000000, %00111111, %11111001
%10100000, %00100000, %00100000, %00110001, %10100000, %00100000, %00100000, %00110001
%10100000, %00100000, %00100000, %11000001, %10100000, %00100000, %00100000, %11000001
%10100000, %00101111, %11100011, %00000001, %10100000, %00100001, %11100011, %00000001
%10100000, %00111000, %00001100, %00000001, %10100000, %00000000, %00001100, %00000001
%10100000, %00000000, %00110000, %00000001, %10100000, %00000000, %00110000, %00000001
%10111111, %11111111, %11000000, %00000001, %10111111, %11000001, %11000000, %00000001
%10000000, %00000000, %00000000, %00000001, %10000000, %00000000, %00000000, %00000001
%11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111
%10101010, %01010101, %01010101, %01010100, %01010101, %01010001, %01010101, %01010101
%10000000, %00000000, %00000000, %00000001, %00000000, %00000000, %00000000, %00000001
%10000000, %00000000, %00000001, %10000001, %00100000, %00000000, %00111111, %11111001
%10000000, %00100000, %00000000, %00110001, %00100000, %00100000, %00100000, %00110001
%10000000, %00100000, %00000000, %11000001, %00100000, %00100000, %00100000, %11000001
%10000000, %00101111, %10000011, %00000001, %00100000, %00100111, %11100011, %00000001
%10000000, %00111000, %00000000, %00000001, %00100000, %00111000, %00001100, %00000001
%10000000, %00000000, %00000000, %00000001, %00100000, %00000000, %00110000, %00000001
%10000000, %11111111, %00000000, %00000001, %10000011, %10000011, %11000000, %00000001
%10000000, %00000000, %00000000, %00000001, %10000000, %00000000, %00000000, %00000001
%11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111
end

Edited by bogax

Share this post


Link to post
Share on other sites
That's actually pretty cool. I don't know how I missed that. I'll make sure to study the examples.

 

I actually posted in that thread, then forgot about it.

 

Be sure to look at the post farther down in that thread:

 

http://www.atariage.com/forums/topic/93867-using-the-score-for-a-game-title-or-inventory-strip/#entry1620834

Share this post


Link to post
Share on other sites

Not sure how I'm gonna proceed with this one. I can't use "Destiny" as the title as Bungie is making some big MMO with that name.

 

The real nuggets of gold in my source are:

 

* The code that use a single variable to place an object type in a 256x256x256 screen world.

 

* The dungeon layout generator. It's somewhat akin to a polynomial counter. For any given x/y value it'll always generate the same room.

 

I could take this game in any number of directions including:

 

* More Zelda like. Even hearts as if 6lives.asm still works.

* More Elder Scrolls/Nethack style with forests, cities, deserts, etc..

* More Treasures of Tarmin like. Full 3D maze.

Share this post


Link to post
Share on other sites

Why can't you call it Destiny? Even if there is another game with the name, you're not basing this game off of it and Bungee doesn't have a copyright on that word.

 

I'd be super-impressed if you could do convincing pseudo-3D environments for the 2600 without doing it all in Assembly.

Share this post


Link to post
Share on other sites

Why can't you call it Destiny? Even if there is another game with the name, you're not basing this game off of it and Bungee doesn't have a copyright on that word.

 

I'd be super-impressed if you could do convincing pseudo-3D environments for the 2600 without doing it all in Assembly.

 

3D view is not an issue.

post-13304-128095537749_thumb.jpg

 

Lawyers are the issue. Remember Mojang and "Scrolls"? Even though I was first with "Destiny" Bungie has paid Lawyers. It's not if you can win a case - it's if you can afford it.

Share this post


Link to post
Share on other sites

I'm super-impressed.

 

What did you (or anyone else) think of the three possible directions I could take this?

 

A. More Zelda.

This would mean more open floor areas. Focus on one or two useable items at a time. Maybe overworld and underworld areas.

B. More Nethack/Oblivion.

Focus on creating an open world. Towns, dungeons, forests etc.. incorporating more old school RPG elements.

C. More Treasure of Tarmin.

Changing the perspective to 3D. More lean towards Treasure of Tarmin rules. I was thinking of maybe showing your character move through the 3D maze instead of a hard and fast 3d perspective. You would watch your character move through the maze instead of pixel by pixel movement control.

Share this post


Link to post
Share on other sites

I don't see why you couldn't do a combination. A 3D-based Zelda/Roguelike along the lines of Legend of Grimrock. Personally, I'm not big on "open world" even on systems that can make it interesting. On something like the 2600, I don't see how it wouldn't be a lot of empty nothing that you just have to plod through, since graphics and space are so extremely limited.

 

In my opinion, keep interaction tight and gameplay dense. 3D is partly just for the gimmick of it being a rare thing to see, but it also serves the purpose of helping to guarantee that encounters require fewer sprites, as you probably won't have multiple enemies on screen at a time when you're limited to a pseudo-3D space like that. Make it about finding awesome items and dealing with random monster generation to get deeper and deeper.

 

... But that's my perspective as a big fan of The Binding of Isaac.

  • Like 1

Share this post


Link to post
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.

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...