The last youtube video I posted was 8 or 9 months ago, and I feel like I need to make an updated video, it's just that I've barely made any progress. The only things I've added was a lava dragon who doesn't even have collision, some slightly glitchy wooden crates, and an unfinished wolf boss that moves almost exactly the same way as the "plasma grinch" but with a different body.
I've been working on this almost every day, and I feel very frustrated because it's just so unfinished.
You're getting old, I guess... It seems that at as time goes by and we become more experienced, our enthusiasm decreases for whatever reason.
Most of my achievements are behind the scenes stuff like how I am able to cram 74 object memory slots into 8kB of RAM, even though it's still not anywhere close to 128 objects; and making the metasprite data format slightly more user friendly, even though it resulted in an uglier dynamic animation code.
A PCE coder could probably fit that many objects in half that size.
How many bytes are reserved per object? 74 is a really weird number.
96 bytes per slot. It's kind've embarrassing.
I don't think it would be unrealistic to half that... Do you have a list of all the variables under one slot?
I actually found a register I didn't need while I was getting it ready, so there are actually 94 bytes per object now. Some of these only a couple bits are actually used so I can try to combine them. I have a "metasprite" register that says what the
previous metasprite was. It used to be an important part of the animation engine, but now all it is used for is starting the frame number at 0 when a new animation/action happens, which I think I can get around.
Code:
define object_id($00)
define metasprite($02) //this is register can probably go after some code revision
define x_position_lo($04)
define x_position($05)
define x_position_hi($06)
define y_position_lo($08)
define y_position($09)
define y_position_hi($0a)
define attributes($0c)
define angle_velocity($0e)
define angle($10)
define amplitude($12)
define kick_range($12) //share the same register as amplitude. Unused, but I'm planning on using it.
define linked_object($14) //linked object is for connecting a sprite to another sprite
define relative_angle($16)
define #_of_child_objects($18)
define modular_animation($1a)
define collision_point_offset($1a) //share register with modular animation
define timer($1c)
define flicker($1e)
define metasprite_request($20)
define vram_slot_number($22)
define animation_update($24)
define linker($26) //linker is used for sprite drawing priority order
define priority($28)
define height($2a)
define x_acceleration($2c)
define amplitude_y($2e)
define timer2($2e) //uses same register as amplitude y
define hits($30)
define on_platform($32)
define on_ground($34)
define slope_data_address($36)
define animation_index($38) //this is the animation frame number x2
define frame_id($3a)
define impact_freeze_enable($3c)
define object_traits($3e)
define attack($40)
define action2($42)
define parent_object($44) //parent object means it belongs to a multijointed boss
define object_number($46) //this is used for object spawning/despawning
define action($48)
define x_speed($4a)
define direction($4c)
define width($4e)
define x_velocity($50)
define y_velocity($52)
define animation_frame($54) //this is the animation frame number in TV frames
define timer3($56)
define timer4($58)
define timer5($5a)
define next_slot($5e)
psycopathicteen wrote:
Some of these only a couple bits are actually used so I can try to combine them.
I can definitely tell; 64 bytes per object looks reasonable. Some of these look really situational; (impact freeze enable?) could you also use less bytes by having multipurpose variables? Or is there actually an object (probably the player) that will potentially use all of these at the same time? One of the first things that stuck out to me is that you're using 4 bytes for x and y position. Could you not get away with 3?
I was able to get rid of the "metasprite" register. Now down to 92 bytes.
I think "slope data address" is only used within the tile map collision routine, and used only for indirect addressing. Maybe I can use that "lda ($xx,s),y" opcode that doesn't get used very often.
So, your complaint that you weren't making progress as fast as you'd like resulted in you spending time redesigning/optimizing something that was already working...
I think I'll make it a goal to have a new gameplay video ready by New Years.
tokumaru wrote:
So, your complaint that you weren't making progress as fast as you'd like resulted in you spending time redesigning/optimizing something that was already working...
You've got to admit, 96 bytes per object is pretty damn ridiculous.
Espozo wrote:
You've got to admit, 96 bytes per object is pretty damn ridiculous.
Maybe, but... is this getting in the way of progress, requiring immediate attention?
I can understand that the longer you take to settle on the final object RAM layout, the more objects you'll have to change later to accommodate the final layout, so maybe that's the reason to get this out of the way before moving forward?
Perhaps you need to develop soft skills such as creating a schedule for yourself, and sticking to it. Then one is not quite as dependent on those youthful marathon spurts of activity. They'll still happen, just not as often. And, I'd say for large homebrew projects, it is good to resign oneself to the length of a project---it's gonna be several years if not more. Accept that, and develop a routine, and you will complete your projects.
Jordan B. Peterson on having a routine (for life in general, but...really think it applies just as well to a hobby like this)
*edit* I'd add to that, for my own routine working on projects, I make sure not to work on it absolutely every day, there are frequent breaks. Gotta avoid burnout. I've been working on my projects 3 evenings a week 100% consistently since late 2008, with the only exceptions being particularly busy times surrounding holidays, family or vacation.
I wish I can have a schedule, but my parents just randomly ask me to do chores around the house.
psycopathicteen wrote:
I wish I can have a schedule, but my parents just randomly ask me to do chores around the house.
Perhaps you could negotiate with them. I was actually in a very similar situation but with my wife when I began this hobby, she demanded a lot of my time, and at seemingly random times. When I finally basically gave her 60/40 so that basically specific 3 evenings a week were "mine" and the other four evenings were whatever we wanted to do together or chores or what not, it kinda settled in to a routine. Seems like a big sacrifice, but it wound up guaranteeing me a specific time every week I knew I was going to work on something. I'm not certain how old you are but if your parents are not reasonable enough to negotiate with you, it might be time to leave. For some reason I thought you were at least 18 or older. If not, just hang in there...
GradualGames wrote:
For some reason I thought you were at least 18 or older. If not, just hang in there...
Same here. Of course, he could still be living with his parents, (I know several people who are going to college but still stay at their home because it's close by) but the whole chores thing sounds odd for another adult. In my house, if something needs to be done, somebody typically just volunteers. We're not that uptight about housekeep though; some people I know vacuum the whole house once a week while we just do it when we see enough crumbs on the kitchen floor to bother.
Im 27. My parents aren't even letting me buy a car.
I live in a one story house, with a neat freak mom, a dead beat dad, and lots old junk "with memories attached to them. "
What do you do for a day job?
Make boxes for men's suits.
psycopathicteen wrote:
...and lots old junk "with memories attached to them. "
Easy, easy, now. That's how the NES and SNES, etc. are to a lot of us.
psycopathicteen wrote:
Im 27. My parents aren't even letting me buy a car.
I live in a one story house, with a neat freak mom, a dead beat dad, and lots old junk "with memories attached to them. "
Is it time to move out on your own and decide for yourself if you should get a car?
I've heard that in the US and several other countries it can be weird to be an adult and still live with your parents, but here in Brazil it's extremely common. Also, if you can afford a car and a place to park it on your own, most parents won't object.
It's pretty damn weird by the age of 27 in the US.
gauauu wrote:
psycopathicteen wrote:
Is it time to move out on your own and decide for yourself if you should get a car?
He can't exactly be making a good living assembling boxes. However, I'd still try and leave asap.
The irony is I would have more time looking for a better job if I lived on my own quietly.
To be honest i've somehow the same issue, it takes me more and more time to code just because i overthink the thing, trying to anticipate future evolution / use case.. but sometime doing that is just counter productive. You waste too much time in that and does not make any progress at all (or very few). I think you should do with a "ok structure" to start with, which is not perfect but which make thing work. Then you can improve it with time, when you will really need it.
Also in your specific case here, i'm surprised you are joining "object" and "sprite" structure, at least imo it's something i would separate, object would have a reference on sprite, and sprite would only store information about the sprite itself, how to display it where object store more high level object information (object state, speed, ...). Of course that depend from your code, maybe you glued your object / sprite handling code together to make it faster..
I couldn't come up with a way to do dynamic animation without having one meta-sprite per object.
My advice for anyone who thinks they're programming too slowly is just do it. Hack each new feature in as fast as possible. Results mean feedback. Feedback means progress. Worry about cleaning up once it's working and debugged.
That said, I actually spend more time cleaning than I do adding. The trick is to make your code easy to modify, and I don't mean lifting constants out and naming them. I mean pulling related functionality together so you don't have to scroll and tab around for hours looking for every site that needs to be updated with each new addition, and factoring out repeated code so you don't have to keep duplicating the changes.
It also helps to keep your code concise and readable, so that the you from six months into the future can figure out what it does without choking on the spaghetti. It's a self-reinforcing cycle - the sloppier your initial code, the more practice you get at organizing it, and the more you organize it the faster it is to tear it up again. Don't be afraid to start over, either; sometimes a good re-write is just what you need to give yourself a refresher course in whatever it is you're doing, and lose some excess baggage along the way.
That's my two cents, anyway. I wrote more in the first twelve months of this approach than I did in the previous twelve years, and I haven't slowed down since. YMMV of course, so take it with a grain of salt.
This is the 90/90 rule.
The thing with games is when you have nothing, adding one thing is a massive change. When it scrolls the game has increased by 300%, when you add entity 2 its now 100% bigger, when you add entity 50, its the same as it was before.
When you add feature X you have to make sure it works with everything else and it doesn't break something, when there are 3 things to break it doesn't take long to make sure. When you have 50 things you need to make sure you don't break then you have to spend a lot more time checking things, making sure you don't trash this or that.
When you test before you had a simple level with the thing right at the start. Now you have to have set up, you need to fire the trigger, the level needs to be set just so, you need this weapon and that weapon etc. This slows down the iteration speed.
There will be a bug, and to fix that bug you need to refactor the code, no way around it. This then means you spent 1 week rewriting some code and testing it, to then finally hit build, run and see that it look 100% like it did before and that is a good thing.
Once you get the Beta you game is mostly complete and now you have to polish, this is where the other 90% comes from. You will spend just as long polishing and fixing glitches and smoothing jump curves etc as it took to make the whole thing.
Keep a few old builds around and then go back and play them when you feel like you have achieved very little, you will see you have actually come a long way, just each little step doesn't feel like it.
psycopathicteen wrote:
I couldn't come up with a way to do dynamic animation without having one meta-sprite per object.
Having a meta sprite per object is ok, when i said sprite i meant "sprite" in general term (as i do in SGDK) as the visible movable element, in fact below i always have a meta sprite in SGDK as well. The thing is more about the object itself which can be anything... and should be, at least in my opinion, a mutable object.
Basically my view is something like this :
Code:
Enemy / Player / Item / ...
|-Object
-status
-spriteRef
- ...
Where Enemy, Player, Item are derived from Object... And Object own basic object stuff + a reference on a (meta) Sprite object.
So do you mean, objects pointing to another structure that has the metasprite/sprite information?
Exactly, Enemy for instance, is a specific Object, and any Object own a reference on a Sprite structure (which deal about handling the visual part).
For instance in SGDK the Sprite structure is just about displaying (meta) sprite, and so dealing about VRAM / hard sprite allocation / handling animation etc... but in my view in any game, we should have a more generic Object structure / class which allow to handle IA, logic, ... stuff and this Object structure own a reference on a Sprite internally which handle the display.
Here's the Sprite (and dependencies) structure of SGDK :
Code:
/**
* \brief
* VDP sprite info structure for sprite resource definition.
*
* \param y
* Y offset for this VDP sprite relative to global Sprite position plus 0x80 (0x80 = 0 = no offset)
* \param size
* sprite size (see SPRITE_SIZE macro)
* \param numTile
* number of tile for this VDP sprite (should be coherent with the given size field)
* \param x
* X offset for this VDP sprite relative to global Sprite position plus 0x80 (0x80 = 0 = no offset)
*/
typedef struct
{
s16 y; // respect VDP sprite field order
u16 size;
s16 x;
u16 numTile;
} VDPSpriteInf;
/**
* \brief
* Sprite animation frame structure.
*
* \param numSprite
* number of VDP sprite which compose this frame
* \param vdpSpritesInf
* pointer to an array of VDP sprites info composing the frame (followed by H/V/HV flipped versions)
* \param collision
* collision structure
* \param tileset
* tileset containing tiles for this animation frame (ordered for sprite)
* \param w
* frame width in pixel
* \param h
* frame height in pixel
* \param timer
* active time for this frame (in 1/60 of second)
*/
typedef struct
{
u16 numSprite;
VDPSpriteInf **vdpSpritesInf;
Collision *collision;
TileSet *tileset;
s16 w;
s16 h;
u16 timer;
} AnimationFrame;
/**
* \brief
* Sprite animation structure.
*
* \param numFrame
* number of different frame for this animation
* \param frames
* frames composing the animation
* \param length
* animation sequence length
* \param sequence
* frame sequence animation (for instance: 0-1-2-2-1-2-3-4..)
* \param loop
* frame sequence index for loop (last index if no loop)
*/
typedef struct
{
u16 numFrame;
AnimationFrame **frames;
u16 length;
u8 *sequence;
s16 loop;
} Animation;
/**
* \brief
* Sprite definition structure.
*
* \param palette
* Default palette data
* \param numAnimation
* number of animation for this sprite
* \param animations
* animation definitions
* \param maxNumTile
* maximum number of tile used by a single animation frame (used for VRAM tile space allocation)
* \param maxNumSprite
* maximum number of VDP sprite used by a single animation frame (used for VDP sprite allocation)
*
* Contains all animations for a Sprite and internal informations.
*/
typedef struct
{
Palette *palette;
u16 numAnimation;
Animation **animations;
u16 maxNumTile;
u16 maxNumSprite;
} SpriteDefinition;
/**
* \brief
* Sprite structure used by the Sprite Engine to store state for a sprite.<br>
* WARNING: always use the #SPR_addSprite(..) method to allocate Sprite object.<br>
*
* \param status
* Internal state and automatic allocation information (internal)
* \param spriteDef
* Sprite definition pointer
* \param animation
* Animation pointer cache (internal)
* \param frame
* AnimationFrame pointer cache (internal)
* \param animInd
* current animation index (internal)
* \param frameInd
* current frame animation index (internal)
* \param seqInd
* current frame animation sequence index (internal)
* \param timer
* timer for current frame (internal)
* \param x
* current sprite X position on screen
* \param y
* current sprite Y position on screen
* \param depth
* current sprite depth (Z) position used for Z sorting
* \param attribut
* sprite specific attribut and allocated VRAM tile index (see TILE_ATTR_FULL() macro)
* \param visibility
* visibility information of current frame for each VDP sprite (max = 16)
* \param VDPSpriteIndex
* index of first allocated VDP sprite (0 when no yet allocated)<br>
* Number of allocated VDP sprite is defined by definition->maxNumSprite
* \param frameNumSprite
* the number of VDP sprite used by the current frame (internal)
* \param lastVDPSprite
* Pointer to last VDP sprite used by this Sprite (used internally to update link between sprite)
* \param data
* this is a free field for user data, use it for whatever you want (flags, pointer...)
* \param prev
* pointer on previous Sprite in list
* \param next
* pointer on next Sprite in list
*
* Used to manage an active sprite in game condition.
*/
typedef struct _Sprite
{
u16 status;
u16 visibility;
const SpriteDefinition *definition;
Animation *animation;
AnimationFrame *frame;
s16 animInd;
s16 frameInd;
s16 seqInd;
u16 timer;
s16 x;
s16 y;
s16 depth;
u16 attribut;
u16 VDPSpriteIndex;
u16 frameNumSprite;
VDPSprite *lastVDPSprite;
u32 data;
struct _Sprite *prev;
struct _Sprite *next;
} Sprite;
As you can see, it's already quite a beast but here you have the "live" Sprite structure as well as the sprite definition structure (the one that should stay in ROM, to define a sprite with its animations and frames).
Still that sprite structure just handle the sprite display, nothing else. I think it's better to separate both so you can minimize your Sprite size object for your sprites functions.
Oh boy, I added a new boss character, and it's flickering like crazy. It's a wolf who walks on four legs, so I think I need to make the torso smaller. If that doesn't work I'll have to do more cutting around the main character's sprite.
I thought of another reason why this year has been sluggish with programming. My Dad retired earlier this year, and so he is home more, and I don't get as much time on the main computer in my house.
Are your parents also opposed to you getting your own computer? If you have your own laptop you'll never have to worry about someone hogging the computer ever again.
tokumaru wrote:
Are your parents also opposed to you getting your own computer?
The parents might oppose not the computer specifically as much as the job to afford one.
I have my own laptop. The front room computer has better colors though.
During winter break I had to binge program to finish up everything I started in 2017.
https://www.youtube.com/watch?v=mDr5zHlyLSwI mentioned a while ago about turning Alisha's Adventure into a run'n'gun game, and last year I did do some run'n'gun animation for Alisha but I held off on it because I couldn't think of a way to implement it. The hard part is having so many different animation combinations of every move, plus each shooting direction. This might sound really hacky, but I think I'll make a subroutine that takes the current "metasprite request" register, compares it with a bunch of possible values, and replace the data with corresponding "while shooting" variant.
tokumaru wrote:
You're getting old, I guess... It seems that at as time goes by and we become more experienced, our enthusiasm decreases for whatever reason.
Man this is quite an understatement... Since a couple of years or so I am so incapable of programming anything even simple that I feel mentally disabled whenever I try, which leads to a vicious circle of not being motivated to program anymore, etc...
And this is coming from someone who just used to love programming as a hobby a couple of years ago.
psychopathicteen, you're a brilliant programmer if you can make snes demos like this. I now am aware of at least 3 people in the homebrew scene who have no college degree and who basically showed their homebrew work to prospective employers and landed jobs in the it/software engineering field. Even though its not directly relevant it has that "wow" factor and says: "This guy can LEARN HARD THINGS." in spades. If you want to get a job and start a life outside your parents' home I personally think it is within your grasp.
GradualGames wrote:
psychopathicteen, you're a brilliant programmer if you can make snes demos like this. I now am aware of at least 3 people in the homebrew scene who have no college degree and who basically showed their homebrew work to prospective employers and landed jobs in the it/software engineering field. Even though its not directly relevant it has that "wow" factor and says: "This guy can LEARN HARD THINGS." in spades. If you want to get a job and start a life outside your parents' home I personally think it is within your grasp.
Thanks. What jobs would I be able to get?
psycopathicteen wrote:
GradualGames wrote:
psychopathicteen, you're a brilliant programmer if you can make snes demos like this. I now am aware of at least 3 people in the homebrew scene who have no college degree and who basically showed their homebrew work to prospective employers and landed jobs in the it/software engineering field. Even though its not directly relevant it has that "wow" factor and says: "This guy can LEARN HARD THINGS." in spades. If you want to get a job and start a life outside your parents' home I personally think it is within your grasp.
Thanks. What jobs would I be able to get?
I can't make any guarantees for anybody, but my expectation is that you may be able to get in to an entry level software engineering job. Given your experience with assembly, you could probably pick up java or C# or php or what not on the job. Entry level positions often don't care that much if you have a lot of depth of experience in the specific field they are hiring for. I didn't know a lick of C# when I got my first job, I did know a tiny bit of C and BASIC though and could show them personal projects I made. They were just happy to see I was eager to learn and that I was able to program, period. Employers vary a lot in their interview style. If you can find one who is interested in seeing your personal projects, it should be impressive to many of them. The type of work available out there is typically something kinda sorta boring maybe? Involving forms and databases and what not, but it can be interesting work if you have the right attitude.
There's all kinds of other types of work out there too, you may wish to seek additional advice on this matter wherever you can find it. After all I don't know very much about you personally except what you've chosen to share here on this forum.
Bregalad wrote:
tokumaru wrote:
You're getting old, I guess... It seems that at as time goes by and we become more experienced, our enthusiasm decreases for whatever reason.
Man this is quite an understatement... Since a couple of years or so I am so incapable of programming anything even simple that I feel mentally disabled whenever I try, which leads to a vicious circle of not being motivated to program anymore, etc...
And this is coming from someone who just used to love programming as a hobby a couple of years ago.
This is the Snr Coders dilemma.
What you love about coding, is working out and solving problems. When you are jr everything is something that needs to be worked out and you spend more time on the problem than you do on the making a .h/.cpp file, writing the docs, pushing pull things of a stack, working out which bank to put it in etc all the "leg work".. as you get more experienced, solving the problem becomes easier and easier till you hit the point where you know how to do it all, and you spend a few minutes on the problem but the legwork doesn't change, so now the fun to leg ratio is 1:100 when before it was 3:2
Oziphantom wrote:
Bregalad wrote:
tokumaru wrote:
You're getting old, I guess... It seems that at as time goes by and we become more experienced, our enthusiasm decreases for whatever reason.
Man this is quite an understatement... Since a couple of years or so I am so incapable of programming anything even simple that I feel mentally disabled whenever I try, which leads to a vicious circle of not being motivated to program anymore, etc...
And this is coming from someone who just used to love programming as a hobby a couple of years ago.
This is the Snr Coders dilemma.
What you love about coding, is working out and solving problems. When you are jr everything is something that needs to be worked out and you spend more time on the problem than you do on the making a .h/.cpp file, writing the docs, pushing pull things of a stack, working out which bank to put it in etc all the "leg work".. as you get more experienced, solving the problem becomes easier and easier till you hit the point where you know how to do it all, and you spend a few minutes on the problem but the legwork doesn't change, so now the fun to leg ratio is 1:100 when before it was 3:2
It seems to me one can continuously increase the scope and complexity of what one is working on, augmenting the challenge of what one has achieved previously. Programming/game development can be made arbitrarily hard if one is feeling bored. I think about my dad, who has been a math professor since 1970, he still hasn't retired and still has new challenges. I feel programming/game development can be the same way, it's all about attitude.
I do get the fun to legwork ratio thing, but I don't agree that the legwork didn't change... the truth is that I didn't care about the boring stuff at all when I was younger! As long as the on-screen results were good, I couldn't care less about how things were under the hood. Everything was fun because everything immediately translated into on-screen results. As I got older, I started caring about standards and good practices, and only then did the legwork become a problem.
Quote:
Why is programming taking so dang long for me nowadays?
Because you're alone,no deadlines, a project can become boring as time passes and if you want to make it best as possible, it takes time,you can add if you're like me,E.G to go in a endless optimisation you are not close to finish something easily .
I also think an original project is way more difficult(and long) to do alone rather than an adaptation.
I just thought of another factor.
The more code you write, the more memory you use, and the more memory you use the more bank switching you need, and the more bank switching you do, the more complicated your code is, and the more complicated your code is, the more memory it takes up, and the more memory it takes up, the more you need bank switching.
-> set up trampolines -> bankswitching is no longer complicated -> cycle broken
calima wrote:
-> set up trampolines -> bankswitching is no longer complicated -> cycle broken
Even with trampolines, bankswitching still makes things a bit more complicated. You have to pay attention to whether a given routine or bit of data is in your current bank. Calling a trampoline'd routine is easy, but remembering whether you have to avoid a function that has no trampoline is more mental load.
How would a trampoline code work in an SNES game?
gauauu wrote:
Even with trampolines, bankswitching still makes things a bit more complicated. You have to pay attention to whether a given routine or bit of data is in your current bank. Calling a trampoline'd routine is easy, but remembering whether you have to avoid a function that has no trampoline is more mental load.
Sure, but those are easily handled. Put all data a function accesses in the same file, and file-level organization now takes care of that mental load. You don't need to care about not going through a trampoline, that's needless micro-optimization until proven otherwise. Make it so that all functions are either in a common bank or trampolined, and nothing to remember.
As for SNES details, I'm not a SNES coder (yet), but if you look up my cc65 trampoline thread, RainWarrior's NES implementation may give some ideas.
I just moved my background tile maps to another bank, and that seemed to work.
psycopathicteen wrote:
How would a trampoline code work in an SNES game?
It wouldn't; there is 0 need for a trampoline on a 65816, unless you are dealing with a system that has more than 16MB and hence has "banks" as well. I'm sure there is some mapper system that could allow you to get into such a position if you really wanted to where you would need one, but its an edge of an edge on a vertex case
But it speaks more to the general issues of complexity. Code is a Complex task that descends into Chaotic over time, so you need to spend a lot of time to "burn off the entropy" and get it back to Complex. You know those refactor periods where you rewrite a whole system or 6 over 3 weeks and then get it to the point it looks 100% the same as did before.
When you first add features, you can just hammer them in, as the goes on, you spend more time lookup existing code, making sure you havn't already made code to do a thing, make sure you don't accidentally trash something, make sure it works in all cases the game can present etc. The "checklist" for each new thing gets longer each time you add a new thing.
What of the data bank and program bank then? You can avoid the data bank by always using long loads, but you can't avoid the program bank. Not having to think about what jump is long and what jump is short is one of the key points of trampolines. edit: Always using long jumps and long loads is certainly possible, but I would think a trampoline design would be faster.
If something is long or short - mostly the assemblers job. Working out an address based upon data bank, also the assemblers job.
Yes you will need to think, do I want this function to RTS or RTL, you could use a trampoline to do a conversion for you, but that is more a VECTOR table rather than a trampoline.
Bank 03
Code:
jLMyFunc
jsr myFunc
rtl
myFunc
stuff
rts
So if you are in Bank 02 you would do
jsl jLMyFunc and if you are in Bank 03 you would do
jsr myFunc not really a trampoline as you don't jump out and then bank in.
JSL takes 1 clock more than JSR
RTL takes the same number of cycles as RTS
The trampoline method eats 12 extra clocks. So if you rarely use the function out of bank, sure JUMP Vector it. If you use it 50/50 then always JSL and take the 1 clock hit.
However most of the time you can just JSR/RTS and let the assembler handle the JSL/R RTS/L conversion for you, I would think. On a SNES 32K banks are large, that is a whole C64 or NES game in one shot, In days of yore each bank would have been a "system" and had a VECTOR entry table so you could just assemble each ROM 1 by 1 and not have to sit through the whole lot each time. These days you can one shot the whole ROM and let the assembler handle it.
psycopathicteen wrote:
I just thought of another factor.
The more code you write, the more memory you use, and the more memory you use the more bank switching you need, and the more bank switching you do, the more complicated your code is, and the more complicated your code is, the more memory it takes up, and the more memory it takes up, the more you need bank switching.
I was thinking today, if Super Mario Bros was able to fit in 32kB, I should be able to fit the game engine code within 32kB too.
psycopathicteen wrote:
I was thinking today, if Super Mario Bros was able to fit in 32kB, I should be able to fit the game engine code within 32kB too.
For 65xxx 32 kB represent a lot of space for code, so i'll say yes you can easily .
I think the good things to do is to take the game engine and all the main code in permanent mapped banks if possible, and the other stuffs (intro, menu,game over, datas ,etc ..) on classic banks which can be mapped at any times.
i don't know if this help for snes ,but i use that scheme for PCE,but it's probably more easy as PCE banks are 8kB .
Why 32 kB? I can't think of a reason not to put the program bank in a HiROM region, so you can have 64 kB of solid code with no long jumps if you want.
If a routine uses a small LUT, I would like to keep it in the same bank as the routine, and be able to access it with short absolute addressing.
psycopathicteen wrote:
If a routine uses a small LUT, I would like to keep it in the same bank as the routine, and be able to access it with short absolute addressing.
Not sure what you're getting at here. Isn't it fairly simple to have the assembler put the LUT in a different bank? Ideally the one you're aiming the data bank register at, which would be in a LoROM region in order to retain access to MMIO and shadow RAM.
I've used the "put the LUT in the code segment and just jump over it" trick before, but it's hardly good practice for a game...
I'm really close to having a mid level mode-7 switch in my game. I will have to use only 128 tiles during the transition in order to fit the normal tile set in though.
That's because there are so many updates on the programming world, the competition is too tight and clients are demanding.
Multiplication is really getting on my nerves. Would it have killed them to add a signed 16x16 multiplication?
psycopathicteen wrote:
Would it have killed them to add a signed 16x16 multiplication?
You never know with Japan...
http://thekyotoproject.org/english/chion-in/Quote:
There is also a coffin constructed of plain wood, Shiraki-no-kan, beneath the statue, which symbolizes the burial place for Gomi Kinuemon and his wife, who killed themselves by the sword to take responsibility of the soaring costs of building such an enormous gate.
It's easy to say they should just have gone full SA-1 from the start, but hindsight is 20:20, 1990 != 1995, and budgets are budgets...
I mean, why doesn't the Switch have a 16 nm SOC with A72 cores and 3 SMs, 6 GB RAM, and analog triggers? (Seriously, though, why doesn't it have analog triggers?)
...
Have you got a couple of free banks for a signed 8x8 lookup table? Or would that not be worth it?
If you really got mad, you could just say **** it and use the MSU1 for a 16x16 lookup table...
I seem to recall it's easy to emulate signed mult with unsigned.
take the EOR of the two values, MSB. Then ABS both, mul, if EOR result is 1, negate the result.
Specifically, I'm trying to do collision detection with a mode 7 rotating room. I determined that I need at least 10 bits of precision.