Is It Time to Start Over?

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Is It Time to Start Over?
by on (#162225)
I've just been looking through my dumb code, trying to find out what's wrong with it when I realized what the hell am I doing? I could probably remake the code, possibly even improving it, faster than I'll ever be able to find out what's wrong with it, and since I really haven't done much and everything is integrated together, I wonder if I should just start over. Everything is a mess, because I've just randomly attached junk without knowing what I was doing to try and make it better I've only made it more convoluted. I just remember how fun this was originally compared to how I feel about it know, it's like night and day. I just wish I could start over with something like Walker again, except not on WLA (you know why...). With the experience I've gained, (I had no prior programming knowledge) I honestly feel like I could do what has taken me a whole year in one month. Does anyone have a starter program for ca65, or has anyone even restarted before? I know psychopathicteen has. How far are you in development at this point anyway?
Re: Is It Time to Start Over?
by on (#162226)
Espozo wrote:
Does anyone have a starter program for ca65

I do.
Re: Is It Time to Start Over?
by on (#162228)
I looked at yours again, and I still don't understand it. (I don't know why, it's just not what I'm used to.) I think I'll try and make my own, but I'll probably won't get to far.
Re: Is It Time to Start Over?
by on (#162229)
Espozo wrote:
I looked at yours again, and I still don't understand it. (I don't know why, it's just not what I'm used to.)

If you can't understand it, that's a bug, and I want to fix it. What's the first thing you don't understand?

Do you know how to use IRC? Connect to EFnet, join #nesdev, and see if I'm in the channel.
Re: Is It Time to Start Over?
by on (#162230)
tepples wrote:
If you can't understand it, that's a bug, and I want to fix it. What's the first thing you don't understand?

Never mind, it's the most understandable thing ever! :lol:

(It would probably be just as difficult to figure it out as it would be to figure out what's wrong with it, and I'm lazy, so...)

tepples wrote:
Do you know how to use IRC? Connect to EFnet, join #nesdev, and see if I'm in the channel.

Can I use this to ask random things? You know, the kind that don't get answered here: https://forums.dolphin-emu.org/Forum-de ... discussion

Honestly though, I just started trying to make stuff over again, and it's way easier than I thought it would be, which is obviously really good. I'll show you when I actually get something onscreen.

Edit: I just tried the IRC channel thing, but I couldn't even figure out how to write a message... (I pressed most of the keys on the keyboard.)
Re: Is It Time to Start Over?
by on (#162232)
I'd expect revisions to be standard if you haven't programmed a few games in your environment yet. I've redone some parts of my code 10 times by now and I'm still early in the project.

I wouldn't think starting entirely from scratch is necessary unless every single part of your program is wrong.

Even if you need to redo core functionality you can keep the subroutines and stuff that you like.
Re: Is It Time to Start Over?
by on (#162233)
It's all just bad. I'm going to keep my old code as reference maybe, but I'm not going to copy/paste even a line. I was never that far anyway.

(Damn, I thought I often got off topic, but I see the IRC channel and they're talking about Pokémon...)
Re: Is It Time to Start Over?
by on (#162234)
Espozo wrote:
(Damn, I thought I often got off topic, but I see the IRC channel and they're talking about Pokémon...)

Yes, the IRC channel goes off-topic to fill time. But if you wait for a break and pose an on-topic question, or you /msg someone who's at keyboard and who is likely to know the answer, you can usually get your on-topic question in.
Re: Is It Time to Start Over?
by on (#162235)
The thing is about the IRC chat is that I don't know where or how to type for it.
Re: Is It Time to Start Over?
by on (#162237)
Which client are you using? Can you attach a screenshot?
Re: Is It Time to Start Over?
by on (#162238)
Attachment:
Screenshot (412).png
Screenshot (412).png [ 169.81 KiB | Viewed 5557 times ]
Re: Is It Time to Start Over?
by on (#162242)
Click in the white stripe at the very bottom of the window, below "npt has quit", and start typing. Then press Enter to send the message to the channel.

There's a button labeled "tepples" at the top; that's a tab for a private message pane.
Re: Is It Time to Start Over?
by on (#162258)
tepples wrote:
Espozo wrote:
I looked at yours again, and I still don't understand it. (I don't know why, it's just not what I'm used to.)

If you can't understand it, that's a bug, and I want to fix it. What's the first thing you don't understand?

It relies heavily on scripts, macros, makefiles and a bunch of stuff never explained. If you aim it as a tutorial for beginners it's not very beginner friendly IMHO. For a beginner you would need to explain about everything you are doing in the readme or at least some more helpful comments in the code. Also for a beginner it's important that it starts simple enough, so the beginner can display something on screen fast enough (otherwise it's hard to know if he is doing things right). But of course your template project is more than just a tutorial, it's more like an example how to do everything from display, input to sound, which can't possibly be that simple.

That said, it's a good continuation from Blargg's ca65 template. I learned a lot from it when trying to make my own SNES program, and I'm very grateful you made it, even though I don't want to fiddle around to set up that complicated development environment on my own PC.
Re: Is It Time to Start Over?
by on (#162261)
Well, I believe one should be in full control of what their code is doing. If the thing looks like a mess but you're still able to navigate through it and easily modify things whenever necessary (making games is not only about writing new code after all, a lot of it is revising old code), then you should be fine. However, if you often can't remember where/how/when something is done, and the whole thing is so flimsy that it "randomly" breaks without you realizing why, then I'd say something is wrong, and you should engineer things better from the beginning.
Re: Is It Time to Start Over?
by on (#162267)
Pokun wrote:
It relies heavily on scripts, macros, makefiles and a bunch of stuff never explained.

"Scripts": The Python scripts are pilbmp2nes.py and wav2brr.py. Both take data in a PC-friendly format and convert it to a Super NES-friendly format. Both include --help generated using the argument parser library. What else is there to explain about the usage of these tools? Or are you asking me to take beginners from 0 to the ability to write their own data conversion tools first?

"Macros": In snes.inc, the setxy8 family are easier-to-remember names for those rep and sep instructions that affect 65816 data width. These instructions should be described in any 65816 tutorial. I'll add doc comments for each of these six macros. The other macros, which push constant values to the stack, already had doc comments. The spc-*.inc files are a different ball of wax entirely, as they implement an assembler for a different ISA and save you from having to install an even more "complicated development environment".

Quote:
If you aim it as a tutorial for beginners it's not very beginner friendly IMHO.

I sort of intended it as a step up from my project template for the original NES. But at some point, I need to decide on its scope. Will I include a complete 65816 assembly tutorial? A complete SPC700 assembly tutorial?

Quote:
For a beginner you would need to explain about everything you are doing in the readme or at least some more helpful comments in the code.

What is the first place that I need to comment better?

Quote:
Also for a beginner it's important that it starts simple enough, so the beginner can display something on screen fast enough (otherwise it's hard to know if he is doing things right).

If you have all the pieces installed, and a .sfc file comes out, you know you have it installed correctly.

Quote:
even though I don't want to fiddle around to set up that complicated development environment on my own PC.

It's just Python, Pillow, MSYS, and cc65. Without "that complicated development environment", how would you go about doing any of these?
  • Convert background and sprite graphics from the format used by your paint program to the format used by the Super NES. (Or would you prefer to draw graphics directly in a CHR editor, which leads to blockier-looking graphics?)
  • Convert wave files from the format used by your audio editor to the format used by the Super NES. (Or would you prefer to make projects without audio or with misappropriated audio?)
  • Automatically rebuild when the source data changes. (Or would you prefer to rebuild the whole project from scratch every time the smallest piece changes?)
Re: Is It Time to Start Over?
by on (#162305)
Well, I'm just about back to square one: (I made it to where I'd still read the controllers, because every game ever does that.)

Code:
.setcpu "65816"
.smart

.include "Header.asm"
.include "InitializeSNES.asm"
.include "InitializeControllers.asm"

;======================================================================
.segment "ZEROPAGE"
;======================================================================

Joy1Data:                  .res 2
Joy2Data:                  .res 2
Joy1Press:                 .res 2
Joy2Press:                 .res 2

;======================================================================
.segment "CODE"
;======================================================================

.proc Main
  InitializeSNES
  jsr InitializeControllers

;Enable NMI   (when interrupts get re-enabled) and joypad reading
  lda #$81
  sta $4200

  cli      ; Restore interrupts -- we're all ready to go!

InfiniteLoop:
  jmp InfiniteLoop
.endproc

;======================================================================

.proc VBlank
  rep #$30   ; A=16, X/Y=16
  pha
  phx
  phy
  phd
  phb
  php

  jsr GetControllerInput

  lda $4210       ; clear NMI Flag

  plp
  plb
  pld
  ply
  plx
  pla
  rti
.endproc

Now, the two things I need to do now before I get going further are that I need to see if the test is even "running properly". (It assembles, but the screen is black, which is expected.) I'd figure I'd just make the screen white, and I'd kind of like to know, how do you write to cgram not using DMA, if possible? Second, I need to then do something to see if the test is not crashing after the first frame, so I'll increase the value of the color or something every frame. I think I also need to turn on the screen or something too.
Re: Is It Time to Start Over?
by on (#162426)
Easiest would be to just write to $2122 (CGRAM write register) twice like in Blarg's ca65 template. Something like this (but with your colour of choice, I like green):
Code:
;Set background color to $0A0A (green):
  lda #$0A
  sta $2122
  lda #$0A
  sta $2122

;Turn off forced blanking:
  lda #$0F
  sta $2100

forever:
  jmp forever


Another way to see if a particular part of your code works would be to enter a STP instruction in the part of the code you want to know if the PC reached it. Some emulators like no$sns will treat it as a break point and let you know.


Tepples I'll answer you later when I have time in your feedback thread to avoid derailing this one.
Re: Is It Time to Start Over?
by on (#162445)
Well, I got the color to show onscreen, and I decided that I wanted to see if I could cycle through every color combination by adding 1 to the color value, but for some reason, it kept uploading the newer color value in a spot 1 greater than the last one, so color 0 stayed the same color. I know the program works now, but it'd just be kind of nice to know how to fix it.

Code:
InfiniteLoop:
  wai
  lda ColorCounter
  sta $2122
  lda ColorCounter
  sta $2122
  inc ColorCounter
  jmp InfiniteLoop

By the way, what does this mean? I copy/pasted it, but I guess it's important.

Code:
  cli      ; Restore interrupts -- we're all ready to go!
Re: Is It Time to Start Over?
by on (#162455)
Espozo wrote:
Well, I got the color to show onscreen, and I decided that I wanted to see if I could cycle through every color combination by adding 1 to the color value, but for some reason, it kept uploading the newer color value in a spot 1 greater than the last one, so color 0 stayed the same color. I know the program works now, but it'd just be kind of nice to know how to fix it.

Code:
InfiniteLoop:
  wai
  lda ColorCounter
  sta $2122
  lda ColorCounter
  sta $2122
  inc ColorCounter
  jmp InfiniteLoop


CGRAM is manipulated via two registers:
$2122 for writing/reading data at the current address (write/read-twice)
$2121 for setting CGRAM address (write-once)

The CGRAM address is always automatically incremented on write (on read too I believe, although don't quote me on that).

http://wiki.superfamicom.org/snes/show/Registers
Re: Is It Time to Start Over?
by on (#162456)
According to superfamicom.org $2122 is only for writing data, not reading. Reading is done using $213B.

CLI (clear interrupt flag) enables maskable interrupts on the CPU side. You probably disabled them using SEI (set interrupt flag) first thing in the beginning. Note that this flag doesn't affect NMI, only IRQs (something I learned only recently). So it's really only important to use CLI if you are using IRQs (using SEI is always important though) but I guess you might as well enable it as a general practice.
Re: Is It Time to Start Over?
by on (#162457)
Pokun wrote:
According to superfamicom.org $2122 is only for writing data, not reading. Reading is done using $213B..

Ha! Indeed. Should've read the documentation myself first. Got tricked by the big N naming of $2122 which is "CGDATA".
Re: Is It Time to Start Over?
by on (#162497)
I think you could break down the animation engine into achievable goals:

1) Program a basic animation/metasprite engine, that runs after the object's routine.
2) Program a simple fixed-slot DMA mode for the player character.
3) Allow your engine to keep track of DMA-bandwidth, and make it capable of delaying frames when a set DMA limit is up (should be around 4kB).
4) Do all the complicated stuff. I can break this down further if you know for sure what kind of engine you want.
Re: Is It Time to Start Over?
by on (#162501)
It's not just that, although that is the main problem.

Well, anyway, I got it to work finally. (It's actually the exact same thing I got going on the M92, now thinking about it) If anyone wants it, here it is. It's not for newcomers, but for someone who already has technical knowledge and doesn't want to deal with all the extra crap in Walker that you'll probably just erase anyway, it's perfect. The color thing is just kind of to say it works, but you can just erase the code for it and then you'll have a clean slate to work with.

Attachment:
SNES Restarter Kit.zip [181.48 KiB]
Downloaded 117 times
Re: Is It Time to Start Over?
by on (#162559)
Glad you like my batch script, but I suggest you use elseyf's snes checksum fixer or SuperFamicheck rather than ucon64.

And a little warning, if you do keep ucon64, try taking out >nul 2>&1 from the batch script to make sure the program is really running.
Re: Is It Time to Start Over?
by on (#162560)
The one thing I'd like extra is if the batch file would delete the ".o" file when it's done being assembled. I imagine you could write it one line, but I don't know how.
Re: Is It Time to Start Over?
by on (#162561)
Espozo wrote:
The one thing I'd like extra is if the batch file would delete the ".o" file when it's done being assembled. I imagine you could write it one line, but I don't know how.

Code:
if exist Game.o del Game.o
Re: Is It Time to Start Over?
by on (#162565)
:D

You know, this is random, but I just want to make everything as organized and consistent as possible so I'm going to ask this: For objects, do you think I should group all of the resources of an object together, or just have separate folders for all of the different object properties? I mean, it would be like having a folder called "Object Animation" and then having folders underneath it that have the object animation cycles and then the picture for each frame vs. having a folder that just says "Objects" and then having different folders underneath it for every object and then having more folders underneath that?
Re: Is It Time to Start Over?
by on (#162567)
Espozo wrote:
You know, this is random, but I just want to make everything as organized and consistent as possible so I'm going to ask this: For objects, do you think I should group all of the resources of an object together, or just have separate folders for all of the different object properties? I mean, it would be like having a folder called "Object Animation" and then having folders underneath it that have the object animation cycles and then the picture for each frame vs. having a folder that just says "Objects" and then having different folders underneath it for every object and then having more folders underneath that?

What do you mean by objects? I'm confused.
Re: Is It Time to Start Over?
by on (#162568)
I mean like game objects, like in a Mario game, a koopa or a goomba or a mushroom or whatever. It's not related to what you just did.
Re: Is It Time to Start Over?
by on (#162569)
Espozo wrote:
I mean like game objects, like in a Mario game, a koopa or a goomba or a mushroom or whatever. It's not related to what you just did.

So like tile data and stuff? Yeah, I think having a folder named "Objects" with a folder named "Animations" in it is more organized than a bunch of folders named "Objects blablabla".
Re: Is It Time to Start Over?
by on (#162953)
Well, I think I found something out. The game doesn't like this: (It only works with "force range")

Code:
  rep #$30    ;A=16, X/Y=16
  lda #ObjectTable

Because "ObjectTable" is out of zero page and can't be represented by a 24 bit number? How would you do this then?
Re: Is It Time to Start Over?
by on (#162970)
Are you trying to build a far (3-byte) pointer on zero page for use with the [d],y addressing mode? In that case, try this:
Code:
  lda #(ObjectTable & $00FFFF)
  sta ptr
  lda #(ObjectTable >> 8)
  sta ptr+1
Re: Is It Time to Start Over?
by on (#162973)
Well, I have it in "BSS7E", and when I wanted to do what I did earlier, it said there was a "range error" or whatever, so the address couldn't be represented by a 16 bit number?

This was the code, if this helps. I'm just not sure what to do.

Code:
.proc start_object_identifier
  rep #$30    ;A=16, X/Y=16
  lda #ObjectTable
  sta a:ObjectOffset
  tcd

object_identifier_loop:
  lda $0000
  beq next_object
  tax
  ;jsr (ObjectIdentificationJumpTable-2,x)
  rep #$30   ;A=16, X/Y=16

next_object:
  lda a:ObjectOffset
  clc
  adc #ObjectTableEntrySize
  sta a:ObjectOffset
  tcd
  cmp #ObjectTable+ObjectTableSize
  bne object_identifier_loop
  rts
.endproc

;========================================================================
.segment "RODATA"
;========================================================================

ObjectIdentificationJumpTable:
  .word object1_code,object2_code
Re: Is It Time to Start Over?
by on (#162988)
The name "BSS7E" indicates that it's an uninitialized data segment in bank $7E. This means a 16-bit address is sufficient only if the data bank is set to $7E with PLB.
Re: Is It Time to Start Over?
by on (#163018)
Wait, so how do you fix it? :oops:
Re: Is It Time to Start Over?
by on (#163024)
What to do to fix it depends on why you are trying to load an entire address into a register in the first place, that is, it depends on what you are planning to use the address for.
Re: Is It Time to Start Over?
by on (#163035)
Well, the main thing I want to do is set direct page to that address. The reason I want it in a register ever is so I can increment the address. If I can set direct page to that, will I still be able to have "a:" work? (I don't know how else to describe it.)
Re: Is It Time to Start Over?
by on (#163051)
The most productive places for direct page are $000000-$001F00 (the first 8K of WRAM), $002100 (access PPU with short writes, as on the Atari 2600), and $004300 (use unused DMA channels as a direct page). The other 120K of WRAM cannot be used as direct page.
Re: Is It Time to Start Over?
by on (#163053)
I mean, I don't know if this is good, but I like to set direct page to be like an additional offset from x and y. I want to have it to where for objects, direct page will be set to the beginning of where the object starts. I mean, direct page is only 16 bit, and the address space of the SNES is 24 bit, so I want the object table to be in the first 16 bits of the address space, but if I put it under zero page, it says that the object table is too big and that there's a memory overflow, but if I put it in BSS7E, it says that there's a "range error" when I'm trying to load the address into the 16 bit accumulator.
Re: Is It Time to Start Over?
by on (#163059)
The fact that direct page can reach only the first 8K of RAM is something you just have to live with unless you want to put extra bankable RAM on the cartridge and map it to $006000-$007FFF.

If you want to set up a pointer to an object structure, you'll have to store the pointer to the object on direct page and use [d],Y address mode. Or better yet, use structure-of-arrays, with all objects' Y location, all objects' X location, etc. as separate arrays, and use al,X mode to index into those individual arrays.
Re: Is It Time to Start Over?
by on (#163061)
Oh, I found it out now. I thought "zero page" was the 8KB, but it's only the first 256 bytes, which confused me as to why I was getting "memory overflow" when it wasn't even near 8KB. It works now that I put it in "BSS" instead of "BSS7E". :)
Re: Is It Time to Start Over?
by on (#163235)
I forgot, how do you ask for the bank byte of something in ca65? Sorry... :lol:
Re: Is It Time to Start Over?
by on (#163241)
For the value of the bank attribute of a label's memory area, use .bank(label). This is more useful on NES.

For bits 23-16 of a label's address the value of the bank attribute of a label's memory area, use .bankbyte(label) or ^label. This is more useful on Super NES.
Re: Is It Time to Start Over?
by on (#163979)
Well, all I want to do is send two tiles to the start of VRAM via HDMA, but for whatever reason, it's filling up all of vram (or at least parts of it, it's hard to tell because it could just be sending 0's.)

This is the code:
Code:
  rep #$30   ;A=16, X/Y=16
  sep #$20   ;A=8

  lda #%10000000   ;Increment VRAM address by 1 after write to $2119
  sta $2115

  ldx #$0000
  stx $2116      ;$2116: Word address for accessing VRAM

  ldx #Object1Tiles   ; Address of src + offset
  stx $4302      ;Store Data offset into DMA source offset

  lda #^Object1Tiles   ;Bank of src
  sta $4304      ;Store data Bank into DMA source bank

  ldy $0010   ;Length of data to copy
  sty $4305   ;Store size of data block

  lda #$01
  sta $4300   ;Set DMA mode (word, normal increment)
  lda #$18   ;Set the destination register (VRAM write register)
  sta $4301
  lda #$01   ;Initiate DMA transfer (channel 1)
  sta $420B

It doesn't seem to matter what number I send to $4305, which I thought controlled the size. I was going off the fact that 128 x 64 / 2 (8 bits instead of 4) = 256, which = #$10. I tried to copy this code from something else, but it clearly isn't working as intended. I obviously don't plan on keeping the above, I'm just using it for a test. It'll be nice when the summer rolls around and I actually work on this...
Re: Is It Time to Start Over?
by on (#163984)
ldy $0010 should probably be ldy #$0010.
Re: Is It Time to Start Over?
by on (#163986)
Oops... Yeah, it works now. :lol:
Re: Is It Time to Start Over?
by on (#163987)
Espozo wrote:
I was going off the fact that 128 x 64 / 2 (8 bits instead of 4) = 256, which = #$10.

That's a fact, is it?

I thought two tiles was 128 bytes at 8bpp, or 64 bytes at 4bpp, and that 256 was = #$100...
Re: Is It Time to Start Over?
by on (#163989)
93143 wrote:
That's a fact, is it?

Today is not my day... :oops: I just assume the "size" is going by bytes and not bits and it appears to work how I have it know, so I guess it does. I forgot to mention that.
Re: Is It Time to Start Over?
by on (#163997)
I know this really lazy, (like I said though, I plan on actually making this game engine publically available if I finish it, so it's best to be as easy to work with as possible) but does anyone know if it's possible to have separate fields of variables in ram (the ".res" stuff) that can be used for various tables in ram? I mean, I want to have my object table automatically increase or decrease based on how many variables are under it. I mean, if I only have a 24 bit "XPosition" variable, then each entry in the object table will be 24 bits, but if I had "XPosition" and "YPosition", then it would be 48 bits. (I hope there's also a way to have the assembler calculate the size of a slot. Otherwise, there wouldn't even be any point to this.) I know I can do this manually, but it would be nice if this could work. (I use ca65 by the way.)

Another more important problem I have is that all the "include" junk is in the main file that has to information like the main game loop. and it's kind of ugly now. Should I create a file that has everything included and just include the "main" file?
Re: Is It Time to Start Over?
by on (#163999)
Espozo wrote:
I mean, I want to have my object table automatically increase or decrease based on how many variables are under it. I mean, if I only have a 24 bit "XPosition" variable, then each entry in the object table will be 24 bits, but if I had "XPosition" and "YPosition", then it would be 48 bits. (I hope there's also a way to have the assembler calculate the size of a slot. Otherwise, there wouldn't even be any point to this.) I know I can do this manually, but it would be nice if this could work.

I think you're looking for .STRUCT in ca65. You'd create all the fields inside a struct, and use .SIZEOF to get the size of the struct which is the size of a slot. To access the values in the slots you'd have to use something like BaseAddress + StructName::FieldName.

Quote:
Another more important problem I have is that all the "include" junk is in the main file that has to information like the main game loop. and it's kind of ugly now. Should I create a file that has everything included and just include the "main" file?

I have no idea how other people approach this problem, but my main file is only includes. First it includes files containing definitions for each system/area in the program (system, mapper, video, audio, input, game, etc.), which consist of constants, macros and variables. Then come the program banks, each with a series of includes for code and data. Each table and subroutine is a separate file, so I can freely include them in whatever bank I want.
Re: Is It Time to Start Over?
by on (#164021)
tokumaru wrote:
I have no idea how other people approach this problem, but my main file is only includes.

Yeah, that's what I was thinking. I'll probably have one called "Main" and one called "GameLoop" or something like that.

Anyway, I thought I had the ".struct" down, (here's what I wrote)

Code:
.struct "ObjectTableSlot"

XPosition:      .res 3
YPosition:      .res 3

.endstruct

But it doesn't appear to like the ".res". How am I supposed to do this?
Re: Is It Time to Start Over?
by on (#164032)
The struct definition isn't supposed to reserve any actual memory yet, it just assigns offsets to each of its members. If you look at the ca65 documentation you'll see what the correct syntax for structs is, you don't have to guess. Hint: there are no quotation marks, no colons and .res is not the keyword that defines the size of each member.

Then, once the struct is defined, you can reserve memory for slots using that structure like this:

Code:
Slots: .res .sizeof(StructName) * 16

This will reserve memory for 16 slots. Is this whay you're trying to do?

EDIT:

As for accessing the slots, I'm not sure how to do it in 65816 assembly, since I only do 6502. In 6502 you could do something like this:

Code:
;create a pointer to the fifth slot
lda #<(Slots + .sizeof(StructName) * 4)
sta Pointer+0
lda #>(Slots + .sizeof(StructName) * 4)
sta Pointer+1

;use the offset as an index
ldy #StructName::MemberName

;get the data
lda (Pointer), y

This isn't the best way to organize data on the 6502 though, where structures of arrays are preferable over arrays of structures.
Re: Is It Time to Start Over?
by on (#164035)
Well, I think I got it now:

Code:
.struct ObjectTableSlot

XPosition      .byte 3
YPosition      .byte 3

.endstruct

However, instead of having the slot size and the slot number automatically calculated together like that, I want to have the thing that finds the number (the ".sizeof") of how large each slot is and the number for how many slots there are separate for a couple of reasons, like whenever I'm incrementing the object table to look though it, I want to increment by the size of each slot, not the size of each slot x the number of slots.

It doesn't appear to like this though:

Code:
ObjectTableEntryNumber = 32
ObjectTableEntrySize: = .sizeof(ObjectTableSlot)
ObjectTable:      .res ObjectTableEntryNumber * ObjectTableEntrySize

Command Prompt wrote:
(Line with "ObjectTableEntrySize") Unexpected trailing garbage characters
(Line with "ObjectTable") Constant expression expected
Re: Is It Time to Start Over?
by on (#164040)
I think the problem is the colon after ObjectTableEntrySize. Try removing that and see if it works. Colons are for labels, and the equal sign is for constant symbols, you shouldn't be mixing those like that. ca65 does have ":=" though, which you can use to create labels through assignment, but, as far as I can tell, ObjectTableEntrySize is supposed to be just a symbol, not a label.
Re: Is It Time to Start Over?
by on (#164044)
You're right, and I knew that, I'm just being an idiot today... :oops:

It works now though. :)
Re: Is It Time to Start Over?
by on (#164492)
Wait, I don't know if you already told me this and I'm just not paying attention, but I'm trying to load from the location of one of the items in the struct, like this: "lda XPosition", but it's telling me that it doesn't exist even though it's one of the things under the struct. Is it that I'm not addressing it right, or is this just impossible?
Re: Is It Time to Start Over?
by on (#164501)
Espozo wrote:
Wait, I don't know if you already told me this and I'm just not paying attention, but I'm trying to load from the location of one of the items in the struct, like this: "lda XPosition", but it's telling me that it doesn't exist even though it's one of the things under the struct. Is it that I'm not addressing it right, or is this just impossible?

I think structs are addressed like:
Code:
ObjectTableSlot::XPosition
Re: Is It Time to Start Over?
by on (#164514)
Command Prompt is telling me that there's "no such scope" as "ObjectTableSlot", whatever that means. I flipped it around just to try it out, and that doesn't work either.
Re: Is It Time to Start Over?
by on (#164517)
Yeah, I did mention previously how to get the offset:

tokumaru wrote:
Code:
;use the offset as an index
ldy #StructName::MemberName

Here I used the Y register because in 6502 assembly you'd most likely use indirect indexed addressing to access a structure like this, but I don't know if the 65816 has a better addressing mode for this.
Re: Is It Time to Start Over?
by on (#164519)
Espozo wrote:
Command Prompt is telling me that there's "no such scope" as "ObjectTableSlot", whatever that means. I flipped it around just to try it out, and that doesn't work either.

Is that BEFORE the struct is defined? It's a known fact that ca65 can't access scopes before they're created, so you have to define the struct before it's used for the first time.
Re: Is It Time to Start Over?
by on (#164520)
Oh... Yeah, that's the problem... :lol:

I'll move all my .includes to the end of the file.
Re: Is It Time to Start Over?
by on (#164576)
Wait, I just realized something... In the struct, is #StructName::MemberName the location of MemberName in ram, or is it the number that MemeberName is in the struct?
Re: Is It Time to Start Over?
by on (#164582)
It's the offset of MemeberName from the start of the slot (i.e. the first member always has a value of 0).
Re: Is It Time to Start Over?
by on (#164584)
That's what I thought, but I was having an error with my metasprite routine, but luckily, I fixed it. Thanks for helping me with that. :)

(I can't think of any other excuses from coding now... :lol:)
Re: Is It Time to Start Over?
by on (#164589)
I just noticed something... I'm finally back to where I restarted from. Yay? :lol: