OldAtAtari Posted December 10, 2022 Share Posted December 10, 2022 Hello, everyone. I'm finishing up my Lynx Jam 2022 game, and I'm unsure how to create a *.O file. I'm using cc65 with Karri/Nop90's template, and it automatically creates the LNX. Can anyone share some guidance in creating the O? Thanks. Quote Link to comment Share on other sites More sharing options...
42bs Posted December 10, 2022 Share Posted December 10, 2022 I am sure there will be also an .o file. Check the makefile. 1 Quote Link to comment Share on other sites More sharing options...
OldAtAtari Posted December 10, 2022 Author Share Posted December 10, 2022 54 minutes ago, 42bs said: I am sure there will be also an .o file. Check the makefile. Yes, I thought there would be, but I'm not seeing it. This is the makefile from the "cart" directory where the LNX is created. include ../Common.mk objects= \ lnxhdr.o \ directory.o objlists = \ ../resident/objlist \ ../intro/objlist \ ../game/objlist \ ../tunes/objlist others = \ @../resident/objlist \ @../intro/objlist \ @../game/objlist \ @../tunes/objlist target = game.lnx all: $(target) $(target) : $(objects) $(objlists) $(CL) -t lynx -o $@ -m lynx.map -C lynx.cfg $(objects) $(others) lynx.lib clean: $(RM) $(objects) $(target) lynx.map Quote Link to comment Share on other sites More sharing options...
42bs Posted December 10, 2022 Share Posted December 10, 2022 An .o file cannot use the directory. But how to build an .o file I cannot see it here. Maybe check AG's template. 1 Quote Link to comment Share on other sites More sharing options...
OldAtAtari Posted December 10, 2022 Author Share Posted December 10, 2022 45 minutes ago, 42bs said: An .o file cannot use the directory. But how to build an .o file I cannot see it here. Maybe check AG's template. Thanks! I looked at the AG template earlier and saw that it does indeed make an .o file, but the method it uses wasn't obvious to me. I'll have another look. Quote Link to comment Share on other sites More sharing options...
+karri Posted December 11, 2022 Share Posted December 11, 2022 You need to use -C lynxbll.cfg option on the linking line. Then it will create the right kind of file when you type make Quote Link to comment Share on other sites More sharing options...
OldAtAtari Posted December 12, 2022 Author Share Posted December 12, 2022 (edited) 9 hours ago, karri said: You need to use -C lynxbll.cfg option on the linking line. Then it will create the right kind of file when you type make Thank you, Karri! I found this file: /lynx/tools/cc65/src/ld65/cfg/lynx-bll.cfg and copied it into my "cart" directory. But I get a make error on the line "$(CL) -t lynx -o $@ -m lynx.map -C lynx-bll.cfg $(objects) $(others) lynx.lib". Any idea about the following? make[1]: Entering directory '/mnt/c/users/Programming/Documents/Linux_Home/danceBro/cart' cl65 -t lynx -o danceBro.o -m lynx.map -C lynx-bll.cfg lnxhdr.o directory.o @../resident/objlist @../intro/objlist @../game/objlist @../tunes/objlist lynx.lib Unresolved external `__GAME_CODE_LOAD__' referenced in: directory.s(54) Unresolved external `__GAME_CODE_SIZE__' referenced in: directory.s(54) Unresolved external `__GAME_DATA_SIZE__' referenced in: directory.s(54) Unresolved external `__GAME_RODATA_SIZE__' referenced in: directory.s(54) Unresolved external `__INTRO_CODE_LOAD__' referenced in: directory.s(51) Unresolved external `__INTRO_CODE_SIZE__' referenced in: directory.s(51) Unresolved external `__INTRO_DATA_SIZE__' referenced in: directory.s(51) Unresolved external `__INTRO_RODATA_SIZE__' referenced in: directory.s(51) Unresolved external `__TUNE0_RODATA_SIZE__' referenced in: directory.s(57) Unresolved external `__TUNE_START__' referenced in: directory.s(57) ld65: Error: 10 unresolved external(s) found - cannot create output file make[1]: *** [Makefile:24: danceBro.o] Error 1 make[1]: Leaving directory '/mnt/c/users/Programming/Documents/Linux_Home/danceBro/cart' make: *** [Makefile:6: all] Error 2 Edited December 12, 2022 by OldAtAtari Quote Link to comment Share on other sites More sharing options...
OldAtAtari Posted December 12, 2022 Author Share Posted December 12, 2022 This is my cart-level Makefile: include ../Common.mk objects= \ lnxhdr.o \ directory.o objlists = \ ../resident/objlist \ ../intro/objlist \ ../game/objlist \ ../tunes/objlist others = \ @../resident/objlist \ @../intro/objlist \ @../game/objlist \ @../tunes/objlist target = danceBro.o all: $(target) $(target) : $(objects) $(objlists) $(CL) -t lynx -o $@ -m lynx.map -C lynx-bll.cfg $(objects) $(others) lynx.lib clean: $(RM) $(objects) $(target) lynx.map Quote Link to comment Share on other sites More sharing options...
42bs Posted December 12, 2022 Share Posted December 12, 2022 (edited) As I previously wrote, don't use directory.o, there is none, so do not include the code for it. Same applies for lnxhdr.o, since it will be a BLL file, it does not need the LNX header. Edited December 12, 2022 by 42bs 1 Quote Link to comment Share on other sites More sharing options...
OldAtAtari Posted December 12, 2022 Author Share Posted December 12, 2022 10 minutes ago, 42bs said: As I previously wrote, don't use directory.o, there is none, so do not include the code for it. Same applies for lnxhdr.o, since it will be a BLL file, it does not need the LNX header. Ok. Sounds like I need to delete both the objects from the makefile. I'll give it a try tomorrow. Thank you, 42bs. Quote Link to comment Share on other sites More sharing options...
+karri Posted December 12, 2022 Share Posted December 12, 2022 Here is my files for generating the required stuff. You don't need to copy the lynxbll.cfg to your local directory as it it a standard build target in cc65. The filler.py is a small script to strip the lnx header and fill the cart to the end with 0xff. Common.mk Makefile filler.py Quote Link to comment Share on other sites More sharing options...
OldAtAtari Posted December 12, 2022 Author Share Posted December 12, 2022 8 hours ago, karri said: Here is my files for generating the required stuff. You don't need to copy the lynxbll.cfg to your local directory as it it a standard build target in cc65. The filler.py is a small script to strip the lnx header and fill the cart to the end with 0xff. Common.mk 960 B · 0 downloads Makefile 5.8 kB · 0 downloads filler.py 244 B · 0 downloads Thank you, Karri! I notice that all the images and everything are in this one Makefile. This is quite different from the old template where there were multiple directories and Makefiles. Is this related to what 42bs said about the O file creation not working with directories? Which would mean that you have one single directory that contains everything? Also, what does the (INDENT) function do? Does it standardize the code indentation in the C files? Quote Link to comment Share on other sites More sharing options...
+karri Posted December 12, 2022 Share Posted December 12, 2022 I usually use directories when I work with a cart. One directory contains one file on the cart. But in this case there is no cart so I did not want to split up the files in directories. Less work for me that way. The O file can use directories in you own source. But you cannot use the cart because of the lynXjam rules. I use "indent" to keep my source tidy in my style. You may notice that in Common.mk there is a definition of how I want my C-code to look like. INDENT=indent -nbad -bap -nbc -bbo -hnl -br -brs -c33 -cd33 -ncdb -ce -ci4 -cli0 -d0 -di1 -nfc1 -i8 -ip0 -l80 -lp -npcs -nprs -npsl -sai -saf -saw -ncs -nsc -sob -nfca -cp33 -ss -ts8 -il1 So whenever I run $INDENT main.c It will run the linux "indent" command with a zillion of defines I usually indent my code before I commit it to the git. Quote Link to comment Share on other sites More sharing options...
OldAtAtari Posted December 12, 2022 Author Share Posted December 12, 2022 (edited) 30 minutes ago, karri said: I usually use directories when I work with a cart. One directory contains one file on the cart. But in this case there is no cart so I did not want to split up the files in directories. Less work for me that way. The O file can use directories in you own source. But you cannot use the cart because of the lynXjam rules. I use "indent" to keep my source tidy in my style. You may notice that in Common.mk there is a definition of how I want my C-code to look like. INDENT=indent -nbad -bap -nbc -bbo -hnl -br -brs -c33 -cd33 -ncdb -ce -ci4 -cli0 -d0 -di1 -nfc1 -i8 -ip0 -l80 -lp -npcs -nprs -npsl -sai -saf -saw -ncs -nsc -sob -nfca -cp33 -ss -ts8 -il1 So whenever I run $INDENT main.c It will run the linux "indent" command with a zillion of defines I usually indent my code before I commit it to the git. Thanks. I struggle so much with stuff. That INDENT function is going to work wonders for me. I've copied all my game files into one directory and modified your Makefile for my game. It complains now about the resident.s file. I noticed that you don't have resident in your Makefile. How do you handle that? cl65 -t lynx -o DanceBro.lnx -m DanceBro.map dancebro.o split.o feetTogether.o spin1.o spin2.o spin3.o moonwalk1.o moonwalk2.o moonwalk3.o moonwalk4.o moonwalk5.o moonwalk6.o disco_ball_1.o disco_ball_2.o disco_ball_3.o disco_ball_4.o disco_ball_5.o disco_red_light.o disco_green_light.o disco_background.o heart.o sad.o poop.o fire.o intro.o bg.o fadein.o fadeout.o LynxSD.o lynxeeprom.o lynx-snd.o DanceBro_music.o DanceBro_effects.o DanceBro_disco.o resident.o lynx.lib Unresolved external `_GAME_FILENR' referenced in: resident.s(544) resident.s(545) Unresolved external `_INTRO_FILENR' referenced in: resident.s(533) resident.s(534) Unresolved external `_TUNE0_FILENR' referenced in: resident.s(519) resident.s(520) ld65: Error: 3 unresolved external(s) found - cannot create output file make: *** [Makefile:143: DanceBro.lnx] Error 1 Edited December 12, 2022 by OldAtAtari Quote Link to comment Share on other sites More sharing options...
+karri Posted December 12, 2022 Share Posted December 12, 2022 Ouch. So you started with a LNX file that uses the cart. The way I do is to put everything in the main.c that is needed to start music and initialize the code. Don't use any SEGMENT statements in your build as you cannot make separate loadable files. This may be a bit complicated to do. So if you want to you can send me a zip file of your source and I can look through it and fix it to work as a flat file. void init() { tgi_install(&tgi_static_stddrv); joy_install(&joy_static_stddrv); tgi_init(); lynx_snd_init(); CLI(); lynx_snd_pause(); lynx_snd_play(0, tune1.music0); lynx_snd_play(1, tune1.music1); lynx_snd_continue(); } After that I just call the init() from my main code. void main(void) { unsigned char joy; unsigned char WaitForIdle = 0; init(); startpic = clock() + 60; showLikes(); showFollowers(); highlightflask(); tgi_setpalette(witchcorkpal); memset(solved, 0, sizeof(solved)); solvedcount = 0; while (1) { if (startpic) { if (clock() > startpic) { events = CHOOSING; startpic = 0; tgi_setpalette(palette); } } addwalk = 0; if (kbhit()) { switch (cgetc()) { case 'F': tgi_flip(); break; case 'R': while (tgi_busy()) ; //tgi_setpalette(tgi_getdefpalette()); tgi_clear(); tgi_updatedisplay(); reboot(); break; case '1': if (events == CHOOSING) { events = ENDPIC; } else { if (events == ENDPIC) { events = CHOOSING; //tgi_setpalette(palette); } } break; } } joy = joy_read(JOY_1); if (!joy) { WaitForIdle = 0; } if (events == CHOOSING) { if (JOY_BTN_RIGHT(joy) && !WaitForIdle) { currentflask += 1; if (currentflask > 20) currentflask = 1; highlightflask(); WaitForIdle = 1; } if (JOY_BTN_LEFT(joy) && !WaitForIdle) { if (currentflask == 1) { currentflask = 20; } else { currentflask -= 1; } highlightflask(); WaitForIdle = 1; } if (JOY_BTN_UP(joy) && !WaitForIdle) { if (currentflask > 5) { currentflask -= 5; highlightflask(); WaitForIdle = 1; } } if (JOY_BTN_DOWN(joy) && !WaitForIdle) { if (currentflask < 16) { currentflask += 5; highlightflask(); WaitForIdle = 1; } } Quote Link to comment Share on other sites More sharing options...
OldAtAtari Posted December 12, 2022 Author Share Posted December 12, 2022 3 minutes ago, karri said: Ouch. So you started with a LNX file that uses the cart. The way I do is to put everything in the main.c that is needed to start music and initialize the code. Don't use any SEGMENT statements in your build as you cannot make separate loadable files. This may be a bit complicated to do. So if you want to you can send me a zip file of your source and I can look through it and fix it to work as a flat file. void init() { tgi_install(&tgi_static_stddrv); joy_install(&joy_static_stddrv); tgi_init(); lynx_snd_init(); CLI(); lynx_snd_pause(); lynx_snd_play(0, tune1.music0); lynx_snd_play(1, tune1.music1); lynx_snd_continue(); } After that I just call the init() from my main code. void main(void) { unsigned char joy; unsigned char WaitForIdle = 0; init(); startpic = clock() + 60; showLikes(); showFollowers(); highlightflask(); tgi_setpalette(witchcorkpal); memset(solved, 0, sizeof(solved)); solvedcount = 0; while (1) { if (startpic) { if (clock() > startpic) { events = CHOOSING; startpic = 0; tgi_setpalette(palette); } } addwalk = 0; if (kbhit()) { switch (cgetc()) { case 'F': tgi_flip(); break; case 'R': while (tgi_busy()) ; //tgi_setpalette(tgi_getdefpalette()); tgi_clear(); tgi_updatedisplay(); reboot(); break; case '1': if (events == CHOOSING) { events = ENDPIC; } else { if (events == ENDPIC) { events = CHOOSING; //tgi_setpalette(palette); } } break; } } joy = joy_read(JOY_1); if (!joy) { WaitForIdle = 0; } if (events == CHOOSING) { if (JOY_BTN_RIGHT(joy) && !WaitForIdle) { currentflask += 1; if (currentflask > 20) currentflask = 1; highlightflask(); WaitForIdle = 1; } if (JOY_BTN_LEFT(joy) && !WaitForIdle) { if (currentflask == 1) { currentflask = 20; } else { currentflask -= 1; } highlightflask(); WaitForIdle = 1; } if (JOY_BTN_UP(joy) && !WaitForIdle) { if (currentflask > 5) { currentflask -= 5; highlightflask(); WaitForIdle = 1; } } if (JOY_BTN_DOWN(joy) && !WaitForIdle) { if (currentflask < 16) { currentflask += 5; highlightflask(); WaitForIdle = 1; } } Oh, man. I'm sorry. I really don't want to take your time, but apparently I got in over my head starting with the cart template when the goal is to come up with a non-cart game. I need to learn how to do this, but I also need to get that O file created soon. So, since you offered, I'll send you the source for you to look at when it's convenient to you. Thank you for bailing me out! Quote Link to comment Share on other sites More sharing options...
42bs Posted December 12, 2022 Share Posted December 12, 2022 57 minutes ago, OldAtAtari said: Is this related to what 42bs said about the O file creation not working with directories? I meant, that an .o file cannot use the directory (on the card). This has nothing to do with the way you lay out your sources. In the end, you should get a single .o file with no more references. I am really sorry, I did not come up with a better file extension 30yrs ago. I should have chosen .bll instead .o 🙂 1 Quote Link to comment Share on other sites More sharing options...
OldAtAtari Posted December 12, 2022 Author Share Posted December 12, 2022 8 minutes ago, 42bs said: I meant, that an .o file cannot use the directory (on the card). This has nothing to do with the way you lay out your sources. In the end, you should get a single .o file with no more references. I am really sorry, I did not come up with a better file extension 30yrs ago. I should have chosen .bll instead .o 🙂 42bs, without you, along with Karri and others, Lynx homebrew creation might not have even become possible, much less as easy as it is. You shouldn't have many regrets with file extensions or anything else! Quote Link to comment Share on other sites More sharing options...
OldAtAtari Posted December 12, 2022 Author Share Posted December 12, 2022 Karri got me fixed up. He preserved the old template directory structure I was using, but, in his words, he "deleted all references to headers, configs, directories, and segments. So everything is in RAM at once." And it now creates the LNX, O, and LYX. He says that this method is appropriate for all the jams and competitions. Once I get everything cleaned up, maybe I'll make it more generic and upload it to github as a template for future games. Karri, I can't thank you enough! And thanks to you, too 42bs! 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.