Alberto_G Posted September 10 Share Posted September 10 Hi everyone, I need your help to solve a problem related to handling button input in my Atari Lynx project. Current Situation: I'm developing a checkers game on an old laptop running Ubuntu. I'm using cc65 as the compiler to write the code, and I'm testing progress with the Mednafen and Handy emulators. I have an SD cartridge for the Atari Lynx, but I don't have access to the actual console right now, so I can only test on emulators. The Problem: The graphics and sound parts of the game are working fine. I'm having difficulty implementing the joystick button controls for selecting and confirming choices. I included the joystick.h file (which is in the same directory as the other header files), but the code generates errors when trying to manage button input. I checked the joystick.h file to verify the button constant names, and everything seems correct. I also tried compiling an example .c file I found here on the forum (the Pong game), but I got similar errors. Request for Help: Since I'm not an experienced programmer, I could really use your help to narrow down the problem. Here's what I'm asking: Do you have a working .c file that handles basic button input for the Atari Lynx (even a very simple example will do)? If you're able to successfully compile this file, I can try to do the same on my setup. If I still get errors, then we can rule out coding mistakes and focus on other possible issues (like libraries or my development environment). Thanks so much for your time and help! Quote Link to comment Share on other sites More sharing options...
Alberto_G Posted September 11 Author Share Posted September 11 I tried it but it's still having problems. I'll show you the test code I wrote and the final result: File test.c: #include <lynx.h> #include <tgi.h> #include <joystick.h> #include <6502.h> int main() { // Inizializza lo schermo del Lynx tgi_install(&tgi_static_stddriver); // Inizializza il joystick joy_install(&joy_static_stddriver); // Abilita gli interrupt CLI(); while (1) { unsigned char joy = joy_read(0); // Legge lo stato del joystick if (joy & JOY_BTN_UP) { // Il joystick è spostato verso l'alto } if (joy & JOY_BTN_FIRE) { // Il pulsante FIRE è stato premuto } } return 0; } ------------- after writing: cl65 -t lynx test.c -o test.lnx final result: test.c(8): Error: Undefined symbol: 'tgi_static_stddriver' test.c(11): Error: Undefined symbol: 'joy_static_stddriver' test.c(18): Error: Undefined symbol: 'JOY_BTN_UP' test.c(21): Error: Undefined symbol: 'JOY_BTN_FIRE' ------------- Thanks again for your time. Alberto Quote Link to comment Share on other sites More sharing options...
Brek Martin Posted September 11 Share Posted September 11 // I never got it working either // #include <joystick.h> // not needed unsigned char joy = 0; // joypad register unsigned char swt = 0; // switches register joy = *(char*)0xFCB0; // read joypad and buttons register swt = *(char*)0xFCB1; // get switches register if (joy != 0) {//anything was pressed} if ((joy & 0b00000001) != 0) {A button was pressed} if ((joy & 0b00010000) != 0) {D-Pad Right was pressed} if ((swt & 0b00000001) !- 0) {// pause was pressed} Quote Link to comment Share on other sites More sharing options...
Brek Martin Posted September 11 Share Posted September 11 */ joy_install(&joy_static_stddriver); // no longer needed */ Quote Link to comment Share on other sites More sharing options...
Alberto_G Posted September 12 Author Share Posted September 12 Where am I going wrong? #include <lynx.h> #include <tgi.h> unsigned char joy = 0; // Registra lo stato del joystick unsigned char swt = 0; // Registra lo stato dei pulsanti void draw_text(char* text, int x, int y) { tgi_setcolor(1); // Seleziona il colore bianco tgi_outtextxy(x, y, text); // Disegna la scritta } int main() { tgi_install(&tgi_static_stddriver); // Inizializza la grafica tgi_clear(); // Pulisce lo schermo inizialmente while (1) { joy = *(char*)0xFCB0; // Leggi lo stato del joystick swt = *(char*)0xFCB1; // Leggi lo stato dei pulsanti tgi_setcolor(0); // Imposta il colore di sfondo tgi_clear(); // Pulisce lo schermo if (joy & 0b00000001) { // Pulsante A premuto draw_text("Pulsante A premuto!", 20, 20); } if (joy & 0b00000010) { // Pulsante B premuto draw_text("Pulsante B premuto!", 20, 40); } if (swt & 0b00000001) { // Supponiamo che il pulsante 1 esca dal loop break; } tgi_flip(); // Aggiorna lo schermo delay(100); // Ritardo di 100 millisecondi } return 0; } Quote Link to comment Share on other sites More sharing options...
Brek Martin Posted September 12 Share Posted September 12 //tgi_setcolor(0); // black (same as background) tgi_setcolor(0x0F); // white by default. Quote Link to comment Share on other sites More sharing options...
Brek Martin Posted Thursday at 06:05 PM Share Posted Thursday at 06:05 PM Oops. 0 is transparent by default, and 1 is black by default, but I assume the above post would have solved the problem anyway. //tgi_setcolor(1); // black (same as background) Quote Link to comment Share on other sites More sharing options...
Alberto_G Posted Friday at 02:32 PM Author Share Posted Friday at 02:32 PM There are too many problems. As soon as I try to solve one another problem pops up. 😞 Quote Link to comment Share on other sites More sharing options...
Alberto_G Posted Friday at 03:27 PM Author Share Posted Friday at 03:27 PM I managed to generate the .lnx file with this code: #include <lynx.h> #include <tgi.h> unsigned char joy = 0; // Registra lo stato del joystick unsigned char swt = 0; // Registra lo stato dei pulsanti void draw_text(char* text, int x, int y) { tgi_setcolor(0x0F); // Seleziona il colore bianco tgi_outtextxy(x, y, text); // Disegna la scritta } // Funzione di ritardo personalizzata void delay(unsigned int milliseconds) { unsigned int i, j; for (i = 0; i < milliseconds; i++) { for (j = 0; j < 1000; j++) { // Ciclo vuoto per creare il ritardo } } } int main() { tgi_install(tgi_stddrv); // Inizializza la grafica con il driver predefinito tgi_clear(); // Pulisce lo schermo inizialmente while (1) { joy = *(char*)0xFCB0; // Leggi lo stato del joystick swt = *(char*)0xFCB1; // Leggi lo stato dei pulsanti tgi_setcolor(0); // Imposta il colore di sfondo (trasparente) tgi_clear(); // Pulisce lo schermo if (joy & 0b00000001) { // Pulsante A premuto draw_text("Pulsante A premuto!", 20, 20); } if (joy & 0b00000010) { // Pulsante B premuto draw_text("Pulsante B premuto!", 20, 40); } if (swt & 0b00000001) { // Supponiamo che il pulsante 1 esca dal loop break; } tgi_flip(); // Aggiorna lo schermo delay(100); // Ritardo di 100 millisecondi } return 0; } With the Mednaffe emulator I see a black screen. With Handy the error is generated at startup. Quote Link to comment Share on other sites More sharing options...
Nop90 Posted Friday at 09:13 PM Share Posted Friday at 09:13 PM Hi @Alberto_G, don't know what version of CC65 you are using, the preferred version in this community isn't the official one on github but the one maintained by Karri (hosted on bitbucket). Some hints, but consider that I'm using a version of the compiler 5 years old: - after tgi_install call tgi_init() - to read the joystick use joy = joy_read(JOY_1); - to check the keypressed there are some useful macros defined in CC65, e.g. for checking the A button you can use if(JOY_BTN_FIRE(joy)) ... On the forum you can find a program template from Karri with all the basic code you need. If you need more help you can write me a PM. (Puoi scrivere in italiano se preferisci 😉) Quote Link to comment Share on other sites More sharing options...
Brek Martin Posted Friday at 11:12 PM Share Posted Friday at 11:12 PM (edited) Ahhh... I see no tgi_init().... Just assumed it was a modification of a sample Hello World. I haven't had a compiler installed for a month, so it's just me reading it. The joypad defines won't work, and he'll have issues defining sprites as well, until he changes compiler, or finds the right way to do it. Edited Friday at 11:13 PM by Brek Martin Quote Link to comment Share on other sites More sharing options...
Alberto_G Posted Saturday at 07:53 PM Author Share Posted Saturday at 07:53 PM I checked now. The version is: cc65 V2.18 - Ubuntu 2.19-1 Today I tried to run the code following your advice. But it doesn't work. The C++ version of the same game works fine. But I have an advantage because I don't have to use the joystick! 😅 I hope to find a solution soon. I am trying to make a code that only involves the keys work. If it works, I will have to adapt it to the game code. Quote Link to comment Share on other sites More sharing options...
Turbo Laser Lynx Posted Saturday at 08:11 PM Share Posted Saturday at 08:11 PM Hi! Here's some stuff about CC65 "Remake" / "Karri's CC65" if you wanna try that one out. - https://bitbucket.org/atarilynx/lynx One of the great things about this version are the template(s) and make files that exist for this version, they pretty much make it a quite easy to use small game development framework for the Lynx in C thanks to Karri and nop90. - Mini Manual: http://atariage.com/forums/topic/277916-berzerkoids-alpha/?p=4011451 - Easy to set up on Linux / Raspberry Pi. http://atariage.com/forums/topic/256753-atari-lynx-programming-tools-and-tutorials-wip/?p=4011786 - Newest working karri/nop90 template here as far as I know: https://forums.atariage.com/topic/346438-atari-lynx-programming-template-working-as-of-january-11-2023/ I've set up a page with all kinds of known Lynx tools. It should be pretty comprehensive and pretty much up to date. Just updated some stuff there today: https://forums.atariage.com/topic/256753-atari-lynx-game-development-tools-and-tutorials-wip/ "Karri's cc65" also supports Chipper, abcmusic and Handymusic for sound. Quote Link to comment Share on other sites More sharing options...
Alberto_G Posted Saturday at 08:34 PM Author Share Posted Saturday at 08:34 PM thanks for your help. i start reading. Quote Link to comment Share on other sites More sharing options...
Turbo Laser Lynx Posted Saturday at 09:49 PM Share Posted Saturday at 09:49 PM (edited) OldAtAtaris Readme comments about the template here are quite helpful too: https://github.com/OldAtAtari/template Also I wanted to mention that the "resident" part is always in RAM even if you would be swapping CC65 segments in and out of RAM, so it might make sense to not put too much stuff in there. Edited Saturday at 09:51 PM by Turbo Laser Lynx 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.