Jump to content
IGNORED

2021 Atari Gamer game jam coming up!


Igor

Recommended Posts

Sounds like a great story Karri! Looking forward to trying it out.

I resolved my screen corruption issues, thanks to everyone who chatted to me about it, turns out - DON'T USE 2D ARRAYS IN CC65.

I'm at 16641 bytes now, still need to do animations for enemies, different enemy types, maybe gun/item animations and if there's room after that, some sound!

Link to comment
Share on other sites

@LordKraken

 

STZ $FFF9 guarantees that ROM space and vector space is mapped to CPU because subsequent JMP ($FFFC) reads reset handler address (from vector space) and jumps to that handler in boot ROM (hence requirement for ROM space mapping). SEI at the beginning guarantees that no interrupt will mess things up.

 

 

  • Like 1
Link to comment
Share on other sites

10 hours ago, Igor said:

Also for anyone who needs to squeeze some more bytes out of their code I found this super useful - https://github.com/ilmenit/CC65-Advanced-Optimizations

 

The struct of arrays trick especially has been great!

There is one small trick I like to share. It is how to populate the right data on a sprite.

 

This helps a lot to hide clutter from your code while dealing with animations.

extern unsigned char bat0[];
extern unsigned char bat1[];
extern unsigned char bat2[];
extern unsigned char bat3[];
extern unsigned char bat4[];
extern unsigned char bat5[];
extern unsigned char bat6[];
extern unsigned char bat7[];
extern unsigned char bat8[];
static unsigned char *battable[] = {
        bat0,
        bat1,
        bat2,
        bat3,
        bat4,
        bat5,
        bat6,
        bat7,
        bat8
};
unsigned char wingflap = 0;
void animbat()
{
        SBat.data = battable[wingflap];
}

I can then tuck away this into a separate file. In my main code I just need to set "wingflap" to the number I want (0..8). And I call the animbat() routine to set the bitmap.

  • Like 3
Link to comment
Share on other sites

On 12/1/2021 at 7:58 PM, LordKraken said:

Credits not to me, I found that code somewhere I don't recall where and tbh didnt really understand what it was doing until I tried it... Maybe you recognize it @42bs?

 

 

Don't remember, but sounds like a good idea. FFF8 should be left untouched by game code as it could be used by the menu to store the last game. This byte is not cleared by the ROM code.

Link to comment
Share on other sites

2 hours ago, 42bs said:

Don't remember, but sounds like a good idea. FFF8 should be left untouched by game code as it could be used by the menu to store the last game. This byte is not cleared by the ROM code.

First thing ROM does after reset is disabling Mikey and Suzy space by writing 3 to FFF9 and performs a clearing loop through all 65536 memory cells counting upwards. So FFF8 is cleared just before enabling Mikey, Suzy, ROM and vector spaces by STZ to FFF9. One can use 2 bytes of NMI vector as it's not used in Lynx and ROM does not touch RAM at this address (clearing loop writes here after enabling vector space so write goes to ROM and RAM is not written).

Edited by laoo
Link to comment
Share on other sites

1 hour ago, laoo said:

First thing ROM does after reset is disabling Mikey and Suzy space by writing 3 to FFF9 and performs a clearing loop through all 65536 memory cells counting upwards. So FFF8 is cleared just before enabling Mikey, Suzy, ROM and vector spaces by STZ to FFF9. One can use 2 bytes of NMI vector as it's not used in Lynx and ROM does not touch RAM at this address (clearing loop writes here after enabling vector space so write goes to ROM and RAM is not written).

You are right. To long ago. Anyway, $fff7 will do (just checked). Actually any address from should do $fe00 to $fff7.

Link to comment
Share on other sites

13 minutes ago, 42bs said:

You are right. To long ago. Anyway, $fff7 will do (just checked). Actually any address from should do $fe00 to $fff7.

Addesses lower than $ffe0 are usually occupied by screen, so $ffe0-$fff7,$fffa-$fffb tends to be generally unused.

Link to comment
Share on other sites

16 minutes ago, 42bs said:

You are right. To long ago. Anyway, $fff7 will do (just checked). Actually any address from should do $fe00 to $fff7.

i dont remember that the loader was clearing the memory ;)

my dear, long time ago that i checked the rom code.

Link to comment
Share on other sites

6 hours ago, 42bs said:

Don't remember, but sounds like a good idea. FFF8 should be left untouched by game code as it could be used by the menu to store the last game. This byte is not cleared by the ROM code.

I believe I used reboot in "Megapak I" as I had to mix BLL programs with newcc65 programs. And I have no memory of where I found it.

My guess is that S.I.M.I.S. could be the first compilation cart where this was needed.

Link to comment
Share on other sites

@karri I do the same thing with mine...

 

char* itemImgData[] = {&img_gun1_1[0], &img_gun2_1[0], &img_gun3_1[0], &img_wall_1[0], &img_generator_1[0]};
char* itemOffImgData[] = {&img_gun1_off[0], &img_gun2_off[0], &img_gun3_off[0]};
char* enemyImgData[] = {&img_zombie1_1[0], &img_zombie1_2[0], &img_zombie1_3[0], &img_zombie1_4[0]};
char* enemyAttackImgData[] = {&img_zombie1_atk1[0], &img_zombie1_atk1[0], &img_zombie1_atk2[0], &img_zombie1_atk3[0]};

 

  • Like 1
Link to comment
Share on other sites

2 hours ago, LordKraken said:

I don't know about your compiler @Igor but you can probably simplify your code:


char* itemImgData[] = {img_gun1_1, img_gun2_1, img_gun3_1, img_wall_1, img_generator_1};

The compiler includes in cc65 define the data field as

typedef struct SCB_REHVST_PAL {             // SCB with all attributes
  unsigned char sprctl0;
  unsigned char sprctl1;
  unsigned char sprcoll;
  char *next;
  unsigned char *data;
  signed int hpos;
  signed int vpos;
  unsigned int hsize;
  unsigned int vsize;
  unsigned int stretch;
  unsigned int tilt;
  unsigned char penpal[8];
} SCB_REHVST_PAL;


The processing of "unsigned char" is faster than just "char". That is why I tend to use "unsigned char *table[]". It also makes it easier to use data of the same type to avoid casting like:

 

extern non-compatible-type bitmap[];

SCB.data = (unsigned char *)&bitmap[0];

 

instead of just

 

extern unsigned char bitmap[];

SCB.data = bitmap;

 

Link to comment
Share on other sites

I just reached the dreadful 80% complete mark a few days ago. For some strange reason I cannot get anything done. My kids drop in to say hi, baking stuff for Christmas, our independence day is tomorrow, making 3D printed white champagne glasses for the opera (it is supposed to be film-noir style). We transferred Mozarts opera "La clemenza di Tito" written in 1791 to Capitol Hill, Washington DC in modern times. I am dancing as a supporter for the emperor - lol! (Just a snapshot from the rehearsals. The white baseball caps, costumes and makeup are still missing.)

1103842558_WhatsAppImage2021-12-05at09_47_41.thumb.jpeg.c3f0cc1245e43318db6289ac853d7877.jpeg

It is amazing how history is repeating itself. Leopold II wanted to use social media (opera) to change his image with the peasants in Boheme in order to avoid the revolution (a revolution in France was ongoing 1789-1799. Mozarts opera Cosi fan tutte 1790 has been partly blamed for encouraging the people to take action.). Leopold II needed the support of the aristocrats to stay in power. So they needed to state a message.

 

The two first composers they asked to do this refused. Mozart was short on cash and composed his most political opera ever.

 

The message of the opera is that emperor Tito is compassionate with only the best of Rome in his heart.

So we changed the name of our opera to "Let's make Rome Great Again!"

 

I really hope to get some coding done during the week. After that the choir and the orchestra join in and all my evenings are counted for.

 

 

  • Like 2
Link to comment
Share on other sites

6 hours ago, LordKraken said:

I don't know about your compiler @Igor but you can probably simplify your code:


char* itemImgData[] = {img_gun1_1, img_gun2_1, img_gun3_1, img_wall_1, img_generator_1};

if I do that, it gives me a warning...

 

Warning: Incompatible pointer assignment to 'unsigned char *' from 'unsigned char (*)[]'

 

I did take @karri's advise and changed to unsigned char* though

Link to comment
Share on other sites

8 minutes ago, laoo said:

All your worries will be soon obsoleted by mighty llvm-mos ?

So this means you could code using clang? And C++? What about the libraries?

 

In cc65 the concept of loadable segments that contain their address in memory is kind of unique to cc65.

The linker can also reference variables and routines that can be in overlapping memory.

Link to comment
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.
Note: Your post will require moderator approval before it will be visible.

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