ptitSeb / gorynlich

gorynlich, 2d platform dungeon romp. Version adapted for the Pandora. Status: Working (but a bit slow)
3 stars 0 forks source link

amigaos4 port #1

Open kas1e opened 5 years ago

kas1e commented 5 years ago

Howdy ! Its me :)

So, to make amigaos4 version possible need to add those changes:

  1. src/backtrace.c

replace all #ifndef _WIN32 (in 1 place) and #ifndef WIN32 (in 5 places) , on #if !defined(_WIN32) && !defined(__amigaos4__)

  1. src/main.h

at top change as for Pandora to use float instead of double:

#ifdef __amigaos4__
 #undef Double
 #define Double float
#endif

and get rid of "#error KO":

#ifdef NEON
 #include <arm_neon.h>
#else
#ifndef __amigaos4__
 #error KO
#endif
#endif
  1. src/time_util.h

line 72 : #if 1 change on #if 0 for amigaos4 line 103: #if 1 change on #if 0 for amigaos4

  1. src/term.c

replace all #ifndef _WIN32 on #if !defined(_WIN32) && !defined(__amigaos4__)

  1. src/main.c

at moment comment out execve():

#ifndef __amigaos4__
#ifdef _WIN32
    execve(executable, (const char *const *) args, 0);
#else
    execve(executable, (char *const *) args, 0);
#endif
#endif

And that all. + changes in makefiles , but that can go for latter (i can create just makefile.os4 and makefile_os4.ramdisk).

Now, when i run game, i have as usuall for big-endian inverted colors. As well, as menu didn't draws (or just can't be seen) and character at left also can't be seen.

There is screenshot of menu:

http://kas1e.mikendezign.com/aos4/gl4es/games/gorynlich/gorynlich_1.jpg

Then, i check how it all loads, and find out that its load_image() from tex.c. And that one for sure have ENDIAN checks. So, for sake of tests, i comment out big-endian ifdefs in that functinos, and wtf , colors start to be right ! Check this out:

http://kas1e.mikendezign.com/aos4/gl4es/games/gorynlich/gorynlich_2.jpg

Through, menu not visibly still, and no character visibly at left bottom of screen.

And strange, why removing of endian ifdefs make colors be better , but not in other way :)

goblinhack commented 3 years ago

I don't recall teleport being used a lot :)

On Thu, 1 Apr 2021 at 10:03, kas1e @.***> wrote:

Yeah, will check. Anyway, what I think that maybe for the first amigaos4 release just comment out calling to thing_reached_teleport(me, it); and be done with it? Or it will break the game's functionality a lot?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ptitSeb/gorynlich/issues/1#issuecomment-811765950, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADA3H7DHI5FCIGQYTQXYKTTGQZFLANCNFSM4ILEYH7A .

kas1e commented 3 years ago

@goblinhack So i just comment it out for first release :) No crashes anymore! I also added "ESC" in the game itself (so not only "q") to have a menu

And now fighting with the last issue named "restart when change settings". In original code you have that:

void restart (void)
{
    char *args[] = { 0, 0 };
    char *executable = ARGV[0];

    LOG("Run %s", executable);

    args[0] = executable;

#ifdef _WIN32
    execve(executable, (const char *const *) args, 0);
#else
    execve(executable, (char *const *) args, 0);
#endif
}

We on amigaos4 didn't have execve() , and so , i had to use my own way of running binary again, like this:

#ifdef __amigaos4__
#include <proto/exec.h>
#include <proto/wb.h>
#include <proto/dos.h>
    struct Library *workbenchbase; 
    struct WorkbenchIFace *iworkbench; 
    BPTR path_list = ZERO; 
    BPTR input_file = ZERO; 
    BPTR output_file = ZERO; 
    int32 error = -1; 

    workbenchbase = IExec->OpenLibrary("workbench.library", 53); 
    iworkbench = (struct WorkbenchIFace *)IExec->GetInterface(workbenchbase, "main", 1, NULL); 

    if (iworkbench != NULL) { 
        iworkbench->WorkbenchControl(NULL, 
            WBCTRLA_DuplicateSearchPath, &path_list, 
            TAG_END); 
    } 

    input_file = IDOS->Open("NIL:", MODE_OLDFILE); 
    output_file = IDOS->Open("NIL:", MODE_OLDFILE); 

    if (input_file && output_file) { 
        error = IDOS->SystemTags(executable, 
            NP_Name,    "Gorynlich restart", 
            NP_Path,    path_list, 
            SYS_Asynch, TRUE, 
            SYS_Input,  input_file, 
            SYS_Output, output_file, 
            SYS_Error,  ZERO, 
            TAG_END); 
    } 

    if (error) { 
        IDOS->Close(input_file); 
        IDOS->Close(output_file); 
    } 

    if (error && iworkbench != NULL) { 
        iworkbench->WorkbenchControl(NULL, 
            WBCTRLA_FreeSearchPath, path_list, 
            TAG_END); 
    } 

    IExec->DropInterface((struct Interface *)iworkbench); 
    IExec->CloseLibrary(workbenchbase); 

#endif

Now, when I change any screen mode, and the game asks for a restart, it starts a new instance, BUT ! problem is that the old one didn't close and didn't exit! I just broke the head to understand why it exits/starts when you just call "execve()" on win32/Linux and you have no needs to call "SDL_Quit, etc, etc" for?

Shouldn't be in restart() function be something like "stop previous executable / close / exit / from" and only then start new ? Or execve() just do it all? Probably execve() just replaces the current process and so automatically exits from the previous one?

kas1e commented 3 years ago

Maybe i better comment out restart() function , and instead make in the main.c somehting like this:

int main() {
     bool restart = false;
     do {
         // Do stuff ...

         // Set restart according some condition inside of the loop
         if(condition == true) {
             restart = true;
         } // (or simplyfied restart = condtion;)
     } while(restart);
}

And so properly close SDL, etc, and run the game again?

goblinhack commented 3 years ago

That restart loop might work - the reason for restarting the game is that on windows you need to reload the textures if the resolution changes. Maybe on amiga that doesn't matter. exec replaces the current binary - I thought I called sdl_fini() prior to this inside quit (void) - is that being called in the broken restart case ? what you have looks fine too - if it works :) but you might have more memory used up and leaking

On Thu, 1 Apr 2021 at 14:36, kas1e @.***> wrote:

Maybe i better comment out restart() function , and instead make in the main.c somehting like this:

int main() { bool restart = false; do { // Do stuff ...

     // Set restart according some condition inside of the loop
     if(condition == true) {
         restart = true;
     } // (or simplyfied restart = condtion;)
 } while(restart);

}

And so properly close SDL, etc, and run the game again?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ptitSeb/gorynlich/issues/1#issuecomment-811913061, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADA3H33URG5TN4DLAEEKALTGRZEXANCNFSM4ILEYH7A .

kas1e commented 3 years ago

@goblinhack I just want to go that way: fully exit the game, and then start it from scratch. So it will properly exit without leaks, and starts as you start it the first time.

kas1e commented 3 years ago

@goblinhack Oh, it turns out to be pretty heavy with restarting. We don't have there such functionality like "execve() replace process", so we need to start a new one, and kill the old one.

I tried to do it all in a clean way, just asking the user to restart a game, but put to the "restart" function instead of execve() a "save_config" call + proper exit. But what a surprise I can't save the "width/height" of screen modes if I do exit at the end of restart. Even if I add before save_config() it didn't help: it saves settings of FPS, Fullscreen, etc, but not screen modes.

I tried to get that way: I made uint8_t sdl_main_loop_running as an extern in main.c, then add to end of restart() instead of execve() setting this to true, and at the end of the main() just made a dumb goto at beginning of main: that also cause issues and crashes.

Maybe you have an idea what I can put to restart() instead of execve, so it will just do that: save whole settings (include screen mode) and just exit (and i will replace words that restarting need to be done manually on amigaos4)

goblinhack commented 3 years ago

config_save() is being called prior to restart right ? If not you could add that to restart()

instead of execve(), system() might work - I wonder if you could do System("RUN gorynlich") to run it in the background

I see it is documented here:

https://wiki.amigaos.net/wiki/Executing_External_Programs

but never used it myself

On Fri, 2 Apr 2021 at 21:28, kas1e @.***> wrote:

@goblinhack https://github.com/goblinhack Oh, it turns out to be pretty heavy with restarting. We don't have there such functionality like "execve() replace process", so we need to start a new one, and kill the old one.

I tried to do it all in a clean way, just asking the user to restart a game, but put to the "restart" function instead of execve() a "save_config" call + proper exit. But what a surprise I can't save the "width/height" of screen modes if I do exit at the end of restart. Even if I add before save_config() it didn't help: it saves settings of FPS, Fullscreen, etc, but not screen modes.

I tried to get that way: I made uint8_t sdl_main_loop_running as an extern in main.c, then add to end of restart() instead of execve() setting this to true, and at the end of the main() just made a dumb goto at beginning of main: that also cause issues and crashes.

Maybe you have an idea what I can put to restart() instead of execve, so it will just do that: save whole settings (include screen mode) and just exit (and i will replace words that restarting need to be done manually on amigaos4)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ptitSeb/gorynlich/issues/1#issuecomment-812698217, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADA3H2HOWYSMXUIAC6OBRLTGYSGPANCNFSM4ILEYH7A .

kas1e commented 3 years ago

@goblinhack

config_save() is being called prior to restart right ? If not you could add that to restart()

Yes, that what i tried to do, and if i add at the end of restart just that:

config_save(); quit(); exit();

Then selected video modes didn't save, but other options (like FPS on/off, fullscreen on/off) saves fine.

instead of execve(), system() might work - I wonder if you could do System("RUN gorynlich") to run it in the background

But System() didn't replace the current process, so I need to close the previous one. And then I faced with the same problem: closing it from restart() didn't save selected video modes :)

kas1e commented 3 years ago

@goblinhack It's like saving of the video modes to config file, done somehow differently, and config_save() didn't save them by some reassons when called just directly from restart() and if then quit immedely. But you probably do not remember anymore all the logic of it ?:)

goblinhack commented 3 years ago

Yeah, it's been years since I looked at this :) which settings do you mean ? these ?

static void marshal_config (marshal_p ctx, struct config *p) { PUT_NAMED_INT32(ctx, "width", p->video_pix_width); PUT_NAMED_INT32(ctx, "height", p->video_pix_height);

or ?

PUT_NAMED_INT32(ctx, "display_sync", p->display_sync);
PUT_NAMED_INT32(ctx, "full_screen", p->full_screen);

they all look to be getting saved in marshal_config() . What actually gets saved in the config file? maybe it is being save but no read back in properly ?

or another idea - maybe an fflush() kind of thing is needed - perhaps the config file is not being flushed to the disk ?

On Sat, 3 Apr 2021 at 17:49, kas1e @.***> wrote:

@goblinhack https://github.com/goblinhack It's like saving of the video modes to config file, done somehow differently, and config_save() didn't save them by some reassons when called just directly from restart() and if then quit immedely. But you probably do not remember anymore all the logic of it ?:)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ptitSeb/gorynlich/issues/1#issuecomment-812892203, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADA3H23PH4LH2CHXG5ARNLTG5BIFANCNFSM4ILEYH7A .

kas1e commented 3 years ago

@goblinhack See what i do with restart() function now, and how it looks like now:

extern uint8_t sdl_main_loop_running;

void restart (void)
{
    config_save();
    sdl_main_loop_running=false;

}

So, what I actually do there, is "config_save" which call marshal_config of course, and then set sdl_main loop to false, so it exits just like should exit.

Now, what happens is : i have in gorynlich-config.txt for widht = 1280 and for heigh = 800. Also full_screen = 0 and fps_counter=0. So i run the gorynlich. Go to settings, change in "window" on 800x600. FullScreen to ON, and FPS counter to ON. Hit Back, and it ask me "want you restart game ? " , i choise yes , so it now call our restart function : call conif_save() and then exit from a game. It exit from a game, i go to the gorynlich-config.txt to see what happens, and while fps_counter start to be 1 (so that changes fine), also full_screen start to be 1 (so that also changes fine), but width still 1280 and heigh still 800. They not saved. Question is : why ?:)

goblinhack commented 3 years ago

I'd debug here

static void wid_intro_settings_save (void) { wid_intro_settings_restart_needed = false;

/*
 * window.
 */
sscanf(wid_intro_button_value_string[WID_INTRO_SETTINGS_ROW_WINDOW][
        wid_intro_button_val[WID_INTRO_SETTINGS_ROW_WINDOW]],
        "%dx%d",
        &global_config.video_pix_width,
        &global_config.video_pix_height);

to make sure we read the correct values from the menu string in wid_intro_settings_save() - add some LOGs for the values there

wid_intro_button_val[WID_INTRO_SETTINGS_ROW_WINDOW] should also be which mode was selected in this array

const char *wid_intro_button_value_string [WID_INTRO_MAX_SETTINGS][WID_INTRO_MAX_VAL] = { { "640x480", "800x600", "1008x672", "1024x768", "1152x864", "1280x960", "1280x1024", "1512x1008", "2880x1800", 0 },

so check that wid_intro_button_val[WID_INTRO_SETTINGS_ROW_WINDOW] has trhe correct index too

and then probably print the same values in

marshal_config(ctx, &global_config);

just to make sure they are the same

it sounds like a genuine bug - just don't see what is wrong yet - going to need probably a lot more LOGs to nail it....

On Sat, 3 Apr 2021 at 21:31, kas1e @.***> wrote:

@goblinhack https://github.com/goblinhack See what i do with restart() function now, and how it looks like now:

extern uint8_t sdl_main_loop_running;

void restart (void) { config_save(); sdl_main_loop_running=false;

}

So, what I actually do there, is "config_save" which call marshal_config of course, and then set sdl_main loop to false, so it exits just like should exit.

Now, what happens is : i have in gorynlich-config.txt for widht = 1280 and for heigh = 800. Also full_screen = 0 and fps_counter=0. So i run the gorynlich. Go to settings, change in "window" on 800x600. FullScreen to ON, and FPS counter to ON. Hit Back, and it ask me "want you restart game ? " , i choise yes , so it now call our restart function : call conif_save() and then exit from a game. It exit from a game, i go to the gorynlich-config.txt to see what happens, and while fps_counter start to be 1 (so that changes fine), also full_screen start to be 1 (so that also changes fine), but width still 1280 and heigh still 800. They not saved. Question is : why ?:)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ptitSeb/gorynlich/issues/1#issuecomment-812921488, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADA3H66LZS7VLMGX6CWSQDTG53IXANCNFSM4ILEYH7A .

kas1e commented 3 years ago

@goblinhack Added just in wid_intro_settings_save() right before config_save() this: printf("wid_intro_button_val[WID_INTRO_SETTINGS_ROW_WINDOW] = %d\n",wid_intro_button_val[WID_INTRO_SETTINGS_ROW_WINDOW]);. And when i change video modes, i surely can see how things changes in this array (from 0 to 27, because we have per 3 versions of one resolution, 8bit, 16 and 32).

But once i quite from, and config_save called, everything saves, but not new window resolution.

Then i add to the marshal_config(ctx, &global_config);, right before marshal_config(ctx, &global_config);, this:

    printf("Fullscreen = %d\n", global_config.full_screen);
    printf("Window width = %d\n", global_config.video_pix_width);
    printf("Window height = %d\n", global_config.video_pix_height);

Now, what I see is that: while I in the settings menu, everything fine, I can see how things change in width/height as expected. Now, once I choose "yes" for restart, then on exit I can see immediately 2 times output where width and heigh switch back to the previous/currently-set-on-run values.

I think there some other check we miss now, and on exit, something happens which makes gorynlych re-read the initial with/height from config file back.

Then I checked what else we call after we break sdl_loop, and that is gl_leave_2d_mode() and quit();, probably in some of them there some code making width/height jump back on the current position to save, and not in out we choose. Will try to comment on them step by step and see where things change.

goblinhack commented 3 years ago

Interesting - my money is on quit() ...

On Sun, 4 Apr 2021 at 12:41, kas1e @.***> wrote:

@goblinhack https://github.com/goblinhack Added just in wid_intro_settings_save() right before config_save() this: printf("wid_intro_button_val[WID_INTRO_SETTINGS_ROW_WINDOW] = %d\n",wid_intro_button_val[WID_INTRO_SETTINGS_ROW_WINDOW]);. And when i change video modes, i surely can see how things changes in this array (from 0 to 27, because we have per 3 versions of one resolution, 8bit, 16 and 32).

But once i quite from, and config_save called, everything saves, but not new window resolution.

Then i add to the marshal_config(ctx, &global_config);, right before marshal_config(ctx, &global_config);, this:

printf("Fullscreen = %d\n", global_config.full_screen); printf("Window width = %d\n", global_config.video_pix_width); printf("Window height = %d\n", global_config.video_pix_height);

Now, what I see is that: while I in the settings menu, everything fine, I can see how things change in width/height as expected. Now, once I choose "yes" for restart, then on exit I can see immediately 2 times output where width and heigh switch back to the previous values.

I think there some other check we miss now, and on exit, something happens which makes gorynlych re-read the config file back.

Then I checked what else we call after we break sdl_loop, and that is gl_leave_2d_mode() and quit();, probably in some of them there some code making width/height jump back on the current position to save, and not in out we choose. Will try to comment on them step by step and see where things change.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ptitSeb/gorynlich/issues/1#issuecomment-813018697, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADA3H4NLIL4H34VDRS5RLTTHBF7DANCNFSM4ILEYH7A .

kas1e commented 3 years ago

@goblinhack Ok found something. The issue is that calling config_save() from the main.c (does not matter if we call it from restart() function, or from quit() at the beginning) causing save a config with initial width/height and not with ones we choose.

In other words, we have 2 times calling config_save() one from quit() , and one I add from restart(). And both of those calls take width/height as initial ones, and not the ones we choose in the menu. If i comment out them all, then on exit all saves well. Like, we have another save_config somewhere in the deep of sdl_loop(). And once that call in sdl_loop (or dunno where is it placed) happens, all other calls (i.e. from our main.c for example) calls with initial width/heigh.

I feel we very close to understand what the issue is. Probably is some sort of comparison of old/new values and logic behind it.

goblinhack commented 3 years ago

so somehow

wid_intro_button_val[WID_INTRO_SETTINGS_ROW_WINDOW]

is getting reset sounds like... there are only a few places that is changed

On Sun, 4 Apr 2021 at 13:02, kas1e @.***> wrote:

@goblinhack https://github.com/goblinhack Ok found something. The issue is that calling config_save() from the main.c (does not matter if we call it from restart() function, or from quit() at the beginning) causing save a config with initial width/height and not with ones we choose.

In other words, we have 2 times calling config_save() one from quit() , and one I add from restart(). And both of those calls take width/height as initial ones, and not the ones we choose in the menu. If i comment out them all, then on exit all saves well. Like, we have another save_config somewhere in the deep of sdl_loop(). And once that call in sdl_loop (or dunno where is it placed) happens, all other calls (i.e. from our main.c for example) calls with initial width/heigh.

I feel we very close to understand what the issue is. Probably is some sort of comparison of old/new values and logic behind it.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ptitSeb/gorynlich/issues/1#issuecomment-813021431, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADA3HYAIKHBL2H2OFBVCTDTHBIOBANCNFSM4ILEYH7A .

kas1e commented 3 years ago

@goblinhack , ptitSeb

So with all the hard stuff which were done on that, port to amigaos4 is done! Thank you both very much!

There is a video of what we have in end:

https://youtu.be/vHB1osXd5to

And there is some text I wrote on amiga sites under news item:

Gorynlich (aka Goblinhack v2) is a top-down dungeon romp with single and multiplayer options. The game is written in 2016 by Neil "goblinhack" McGill, and were adapted to works on AmigaOS4 with the help of ptitSeb (who do the initial port to Pandora and made some necessary optimization and code rewrite) and with tips from the original author. 

Thanks you both again :)

goblinhack commented 3 years ago

Awesome you got it to work! :)

thanks

Neil

On Sun, 18 Apr 2021 at 19:53, kas1e @.***> wrote:

@goblinhack https://github.com/goblinhack , ptitSeb

So with all the hard stuff which were done on that, port to amigaos4 is done! Thank you both very much!

There is a video of what we have in end:

https://youtu.be/vHB1osXd5to

And there is some text I wrote on amiga sites under news item:

Gorynlich (aka Goblinhack v2) is a top-down dungeon romp with single and multiplayer options. The game is written in 2016 by Neil "goblinhack" McGill, and were adapted to works on AmigaOS4 with the help of ptitSeb (who do the initial port to Pandora and made some necessary optimization and code rewrite) and with tips from the original author.

Thanks you both again :)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ptitSeb/gorynlich/issues/1#issuecomment-822041669, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADA3HZXEMN2W7K7JQBIOX3TJMTEJANCNFSM4ILEYH7A .

ptitSeb commented 3 years ago

Nice! And it's very smooth on the Amiga :D