rickyboy has asked for the wisdom of the Perl Monks concerning the following question:

Hi all, I haven't scripted in over a decade since I no longer work in IT. I do however, still dabble in the odd project now and again. I'm looking to sort a bunch of files to help me avoid a configuration screen on an emulator and I reckon perl might be a winner. I've tried sed and awk scripts but they usually fail when trying to replace text (putting $i in the text replacement field). This is lazy as I don't really have a starting point with perl but I'm usually good at describing what I'm trying to achieve in simple terms. Would appreciate some help great ones!
<c> Scenario I have a configuration file. Example of config.file: cpu= ram= floppy0= floppy1= floppy2= floppy3= scsi=false I've created a list of the games in another file - gamelist.txt. Exam +ple of file contents: exile cannon fodder sensible soccer robocod stunt car racer I want to take each line from the gamelist file and insert it after "f +loppy0=" in the configuration file then save seperate files for each +game with corresponding filename to the game. Example $game.config cpu= ram= floppy0=$game floppy1= floppy2= floppy3= scsi=false Take name from gamelist.txt, insert each game name from the list after + floppy0= in the configuration file then save a new, seperate config. +file as $game.config Expected output exile.config cpu= ram= floppy0=exile floppy1= floppy2= floppy3= scsi=false
Thanks in advance...
  • Comment on Haven't Scripted in a Decade, need help (gift is probably a better word)!
  • Download Code

Replies are listed 'Best First'.
Re: Haven't Scripted in a Decade, need help (gift is probably a better word)!
by GrandFather (Saint) on Apr 26, 2023 at 21:22 UTC

    I know you are hoping that we might just write the whole thing for you, but you should at least show some effort. Meet us part way by showing a first attempt at solving the problem with comments indicating where you can't figure stuff out.

    A few hints are in order:

    1. Read each file once into a suitable data structure. For the config file that might just be a string. For the game list it's probably an array.
    2. Iterate over the items in the game list and generate the output files.
    3. Take your own advice for updating the config template to generate the named output config file.
    4. Always use strictures (use strict; use warnings; - see The strictures, according to Seuss).
    Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond
Re: Haven't Scripted in a Decade, need help (gift is probably a better word)!
by tybalt89 (Monsignor) on Apr 26, 2023 at 21:44 UTC

    I'm guessing one can get awfully rusty in a decade ...

    Here's a start.

    #!/usr/bin/perl use strict; # https://perlmonks.org/?node_id=11151867 use warnings; open my $fh, '<', 'config.file' or die; my $configlist = join '', <$fh>; close $fh; open $fh, '<', 'gamelist.txt' or die; while( <$fh> ) { chomp; (my $newfile = $configlist) =~ s/floppy0=\K/$_/; open my $outfh, '>', "$_.config" or die; print $outfh $newfile; close $outfh; } close $fh;

    It's not complete, for example, the die messages need to be expanded to something reasonable.

      BTW, if a modern perl with Path::Tiny is available, here's how I'd do it.

      #!/usr/bin/perl use strict; # https://perlmonks.org/?node_id=11151867 use warnings; use Path::Tiny; my $configlist = path('config.file')->slurp; path("$_.config")->spew( $configlist =~ s/floppy0=\K/$_/r ) for path('gamelist.txt')->lines({chomp => 1});

      Short and sweet :)

      Thanks for the quick replies and I understand the animosity. I've managed to get the gamelist file as it should be using scripts but failing when trying to fill in the configuration file and outputting to seperate files. I have actually been at this for about 8 hours with bash scripts and using awk and sed but getting error after error, usually with seperators. I only arrived here after a temper tantrum!

      Anyway, enough moaning as this is just what I'm looking for and I'm sure I can get that to work with some thought behind it. I'll let you know how I get on and post the full script if I manage it for any others who still live in the 80s/90s and want to get a retropie and play some old games without doing a time consuming setup.

      Thanks for your help!

        I had to Google "animosity" to make sure the word means what I thought it means. It does:

        "The meaning of ANIMOSITY is a strong feeling of dislike or hatred : ill will or resentment tending toward active hostility : an antagonistic attitude."
        which puzzles me because none of the replies you received contained anything anywhere near "animosity".

        In my view a key part of interactions on PerlMonks is to teach / learn. Part of being an effective teacher is understanding the level of understanding of the student. I'm very sorry if my attempt to reach that understanding was interpreted as anything other than trying to be helpful!

        Yes, please show us what you produce, but with the intent that we provide some constructive criticism and guidance to help you recover your lapsed coding foo.

        Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond
        I totally agree with GrandFather. He simply reminded you that PerlMonks is not a code writing service and following that he provided you with 4 great hints to writing good, solid code. It's always wise to take a breath and resist the urge to strike out at the ones who are trying to help you.

        We wish you well on your endeavors to re-enter the wonderful world of Perl.

        "It's not how hard you work, it's how much you get done."

Re: Haven't Scripted in a Decade, need help (gift is probably a better word)!
by rickyboy (Novice) on May 03, 2023 at 18:40 UTC
    Can't thank you all enough, that's it working! Haven't really touched your script tybalt89, it pretty much worked out the box after cleaning up the folders and pointing to the right directories. My scripts are basically just housekeeping to make your script run in the correct way and in the right places. Be gentle, they're crude but they work. I was a hardware engineer so scripting was never at the forefront for me but could always hack my way to a goal (with a little help from the perl monks)! Feel free to make the whole script in perl but only if you can be bothered. I've got what I need so I'm not begging or asking for anymore input.

    There are improvements to be made like adding disk 2, disk 3 etc to floppy=1, floppy=2 in each config file that has multiple disks but I'll deal with that later (or one of you legends could do it for me, lol)! :)

    There are assumptions to be made like folder placement and I used a specific rom pack (Amiga-Fullset) but could be modified easily enough for other roms or a different folder arrangement.

    Assumptions: Amiberry is installed, gawk is installed, Amiberry has to be run (at least) once to create your emulator configuration file and to create the config file which will fill in your emulator settings kickstart location, cpu, ram, chipset, sound, display settings etc. Do not add any disks to the config file as this is what the script does. The config.uae file should then be moved from /opt/retropie/emulators/amiberry/conf/ into the folder /home/pi/RetroPie/roms/amiga/scripts/

    This is my config file (config.uae) and I find this setup works well for most games:

    config_description=Configuration for disk config_hardware=true config_host=true config_version=4.4.0 config_hardware_path= config_host_path= config_all_path= amiberry.rom_path=./ amiberry.floppy_path=./ amiberry.hardfile_path=./ amiberry.cd_path=./ ; ; *** Controller/Input Configuration ; joyport0=mouse joyport0_autofire=none joyport0_friendlyname=Mouse joyport0_name=MOUSE0 ; joyport1=joy1 joyport1_autofire=none joyport1_friendlyname=Microsoft X-Box 360 pad joyport1_name=JOY1 ; ; ; input.joymouse_speed_analog=2 input.joymouse_speed_digital=10 input.joymouse_deadzone=33 input.joystick_deadzone=33 input.analog_joystick_multiplier=18 input.analog_joystick_offset=-5 input.mouse_speed=100 input.autofire_speed=600 input.autoswitch=1 kbd_lang=us ; ; *** Host-Specific ; amiberry.gfx_auto_height=false amiberry.gfx_correct_aspect=1 amiberry.kbd_led_num=-1 amiberry.kbd_led_scr=-1 amiberry.scaling_method=-1 amiberry.allow_host_run=false amiberry.use_analogue_remap=false amiberry.use_retroarch_quit=true amiberry.use_retroarch_menu=true amiberry.use_retroarch_reset=false amiberry.active_priority=1 amiberry.inactive_priority=0 amiberry.minimized_priority=0 amiberry.minimized_input=0 ; ; *** Common / Paths ; use_gui=yes kickstart_rom_file=/test/kickstart/Kickstart4.0.rom kickstart_rom_file_id=FC24AE0D,KS ROM v3.1 (A500,A600,A2000) kickstart_ext_rom_file= flash_file= cart_file= rtc_file= kickshifter=false ; ; *** Floppy Drives ; floppy_volume=33 floppy0= floppy1= floppy2= floppy2type=0 floppy3= floppy3type=0 nr_floppies=4 floppy_speed=400 ; ; *** Hard Drives ; scsi=false ; ; *** CD / CD32 ; cd_speed=100 ; ; *** Display / Screen Setup ; gfx_framerate=1 gfx_width=720 gfx_height=540 gfx_top_windowed=0 gfx_left_windowed=0 gfx_width_windowed=720 gfx_height_windowed=540 gfx_width_fullscreen=800 gfx_height_fullscreen=600 gfx_refreshrate=50 gfx_refreshrate_rtg=60 gfx_backbuffers=2 gfx_backbuffers_rtg=1 gfx_vsync=false gfx_vsyncmode=normal gfx_vsync_picasso=false gfx_vsyncmode_picasso=normal gfx_lores=false gfx_resolution=hires gfx_lores_mode=normal gfx_flickerfixer=false gfx_linemode=none gfx_fullscreen_amiga=false gfx_fullscreen_picasso=false gfx_center_horizontal=smart gfx_center_vertical=none gfx_colour_mode=16bit gfx_blacker_than_black=false gfx_api=directdraw gfx_api_options=hardware ; ; *** CPU options ; cpu_speed=real cpu_throttle=0.0 cpu_type=68000 cpu_model=68000 cpu_compatible=true cpu_24bit_addressing=true cpu_data_cache=false cpu_multiplier=2 cpu_cycle_exact=false cpu_memory_cycle_exact=false blitter_cycle_exact=false cycle_exact=false fpu_strict=false comp_trustbyte=direct comp_trustword=direct comp_trustlong=direct comp_trustnaddr=direct comp_nf=true comp_constjump=true comp_flushmode=soft compfpu=false comp_catchfault=true cachesize=0 ; ; *** Memory ; z3mapping=real fastmem_size=8 a3000mem_size=0 mbresmem_size=0 z3mem_size=0 z3mem_start=0x40000000 bogomem_size=2 gfxcard_hardware_vblank=false gfxcard_hardware_sprite=false gfxcard_multithread=false chipmem_size=4 rtg_modes=0x112 ; ; *** Chipset ; immediate_blits=false fast_copper=true ntsc=false chipset=aga collision_level=playfields chipset_compatible=Generic rtc=MSM6242B resetwarning=false cia_todbug=true ; ; *** Sound Options ; sound_output=exact sound_channels=stereo sound_stereo_separation=7 sound_stereo_mixing_delay=0 sound_max_buff=16384 sound_frequency=44100 sound_interpol=anti sound_filter=emulated sound_filter_type=standard sound_volume=0 sound_volume_paula=0 sound_volume_cd=20 sound_volume_ahi=0 sound_volume_midi=0 sound_volume_genlock=0 sound_auto=true sound_cdaudio=false sound_stereo_swap_paula=false sound_stereo_swap_ahi=false ; ; *** Misc. Options ; parallel_on_demand=false serial_on_demand=false serial_hardware_ctsrts=true serial_direct=false uaeserial=false sana2=false bsdsocket_emu=false synchronize_clock=false maprom=0x0 parallel_postscript_emulation=false parallel_postscript_detection=false ghostscript_parameters= parallel_autoflush=5 ; ; *** WHDLoad Booter. Options ; whdload_slave= whdload_showsplash=false whdload_buttonwait=false whdload_custom1=0 whdload_custom2=0 whdload_custom3=0 whdload_custom4=0 whdload_custom5=0 whdload_custom=

    Once amiberry and gawk are installed, create the following directories in the amiga directory:

    /home/pi/RetroPie/roms/amiga /games /kickstart /scripts

    Move kickstart roms into the kickstart folder.

    Upload your rom pack (Amiga-Fullset) to the games folder - the rom pack will extract the games into alphabetical folders i.e A,B,C,D,E,F etc

    Folders should look like this, if not create them. - /home/pi/RetroPie/roms/amiga/games /0 /A /B /C /D /E /F etc

    Create and move the following scripts to the scripts folder.

    amiberry.pl

    #!/usr/bin/perl use strict; # https://perlmonks.org/?node_id=11151867 use warnings; open my $fh, '<', 'config.uae' or die; my $configlist = join '', <$fh>; close $fh; open $fh, '<', 'gamelist.txt' or die; while( <$fh> ) { chomp; (my $newfile = $configlist) =~ s/floppy0=\K/$_/; open my $outfh, '>', "$_.uae" or die; print $outfh $newfile; close $outfh; } close $fh;

    amiberry.sh

    #!/bin/bash # remove all whitespace and replace with underscores find /home/pi/RetroPie/roms/amiga/*/ -type f -name "* *" -exec bash -c + 'mv "$0" "${0// /_}"' {} \; wait # add all games to a list, add the bare configuration file to all dire +ctories then add file path to list for d in /home/pi/RetroPie/roms/amiga/games/*/ do (cd "$d" && ls > gamelist.txt && cp /home/pi/RetroPie/roms/ami +ga/scripts/config.uae "$d" && awk -i inplace 'BEGIN{"pwd"|getline d} {print d "/" $0}' gamel +ist.txt && cp /home/pi/RetroPie/roms/amiga/scripts/amiberry.pl "$d" && cd "$d" && perl amiberry.pl) done wait #remove additional files in game folders sh cleanup.sh

    cleanup.sh

    for d in /home/pi/RetroPie/roms/amiga/games/*/ do (cd "$d" && rm gamelis* | rm confi* | rm amiberry*) done

    I also put the amiberry start script in the script folder "+Start_Amiberry.sh".

    Once the scripts are saved, run /home/pi/RetroPie/roms/amiga/scripts/amiberry.sh and reboot. Now you'll be able to start the games in RetroPie by just clicking on the game file. You will see two names for each game file; one is the config file the script created and the other will be a *.zip file. Click the zip file to start the game, not the config file.