[{"content":"Motivation After a 4 year hiatus, I\u0026rsquo;m finally coming back around to this blog and doing some cleaning before writing again. Part of that cleaning includes making sure the RSS feed works as expected. To do so, it needs to check off the following:\nProvide valid RSS content Include the posts\u0026rsquo; contents so they can easily be read with RSS readers Exclude pages that are not posts The first box is ticked by default thanks to Hugo\u0026rsquo;s RSS generator\nTask 1: Including the post\u0026rsquo;s contents Looking at PaperMod\u0026rsquo;s RSS layout, I noticed the following code:\n{{- if and site.Params.ShowFullTextinRSS .Content }} \u0026lt;content:encoded\u0026gt;{{ (printf \u0026#34;\u0026lt;![CDATA[%s]]\u0026gt;\u0026#34; .Content) | safeHTML }}\u0026lt;/content:encoded\u0026gt; {{- end }} This might\u0026rsquo;ve been added some time in the 4 years since I started this blog and seems to solve all of our problems. One update to our site\u0026rsquo;s config and voilà, the RSS feed\u0026rsquo;s XML includes our posts\u0026rsquo; content in it!\nOne task down, one to go!\nTask 2: Excluding specific pages The easy way As pointed out on Hugo\u0026rsquo;s Discourse there is a straightforward way to generate an RSS feed only for blog posts:\nUpdate the output section of your site\u0026rsquo;s config file so it does not include RSS [...] [output] - home = [\u0026#34;HTML\u0026#34;, \u0026#34;RSS\u0026#34;, \u0026#34;JSON\u0026#34;] + home = [\u0026#34;HTML\u0026#34;, \u0026#34;JSON\u0026#34;] [...] Add an _index.md file to your /posts subfolder with the following front matter: +++ title = \u0026#34;Posts\u0026#34; outputs = [\u0026#34;HTML\u0026#34;, \u0026#34;RSS\u0026#34;] +++ We now have an RSS feed at https://sunbro.dev/posts/index.xml! \u0026hellip; but there\u0026rsquo;s one problem: this breaks the feed for anyone already subscribed to the current feed at https://sunbro.dev/index.xml. That URL now 404s.\nThe \u0026ldquo;correct\u0026rdquo; way Info\nThis definitely not the only way to do this and there are certainly more \u0026ldquo;Hugo-ist\u0026rdquo; ways to do it.\nNow that we know we want to preserve the current /index.xml let\u0026rsquo;s give ourselves a way to exclude certain pages from it. Let\u0026rsquo;s add a new entry on to our pages\u0026rsquo; config: RSSExclude. You should add it to all the pages you want to exclude from the RSS feed.\nFor example in my projects.md that I want to exclude I added:\n+++ title = \u0026#34;Projects\u0026#34; [...] RSSExclude = true +++ Now, let\u0026rsquo;s customise PaperMod\u0026rsquo;s index.xml layout to take it into account. Copy the theme\u0026rsquo;s file into your /layouts/_default/ and edit it as follows:\n- {{- if and (ne .Layout `search`) (ne .Layout `archives`) }} + {{- if ne .Params.RssExclude true }} \u0026lt;item\u0026gt; [...] \u0026lt;/item\u0026gt; {{- end }} Instead of only excluding pages with the search or archives layouts we now exclude all pages where RSSExclude is true.\nTask two, check!\nConclusion I\u0026rsquo;m happy to see this was much easier than I thought. Although I wish PaperMod natively supported excluding pages from the RSS feed, this has only motivated me to tweak the theme\u0026rsquo;s layouts even further in the future.\n","permalink":"https://sunbro.dev/posts/2024-08-11-fixing-rss-papermod/","summary":"Updating PaperMod\u0026rsquo;s RSS template to fit my needs","title":"Cleaning up the RSS feed"},{"content":"Idea The initial idea comes from a discussion with friends over dinner a couple of nights ago, when we realized ar(1) can read input from STDIN. While we were wondering why that would be useful and what it could be used for, one of use mentioned that gcc(1) can also read input from STDIN. From there, the conversation derailed into how to \u0026ldquo;misuse\u0026rdquo; that feature in order to do something completely over the top and useless.\nInspired by Kelsey Hightower\u0026rsquo;s nocode idea, we wanted to use gcc(1) to write our code directly on STDIN, compile it, and, if successful, add and commit it to a git repo. Obviously doing all of this by hand wouldn\u0026rsquo;t cut it, so all of it had to be \u0026ldquo;automated\u0026rdquo; or neatly wrapped into a useable script.\nWhich then gave birth to Nocode: A simple way to write clean single-file code without taking up disk space.\nImplementation Nocode is essentialy a bash script which wraps all of the useful steps.\nIt starts of by creating and filling a .gitignore file if none exist, as to not create git clutter with the following steps.\nif [ ! -f \u0026#34;.gitignore\u0026#34; ]; then $(echo \u0026#34;a.out\u0026#34; \u0026gt;\u0026gt; \u0026#34;.gitignore\u0026#34;) $(echo -n \u0026#34;*.c\u0026#34; \u0026gt;\u0026gt; \u0026#34;.gitignore\u0026#34;) fi The script then goes on to read the code from STDIN, in order to compiling it. Before passing the input to gcc(1) it is first given to clang-format in order to apply the coding style the user wants. This is then input to tee(1) in order to save it until it is committed to our git repository, and finally into gcc(1) for compilation.\n# \u0026#34;$ARG\u0026#34; is equal to the first argument given to Nocode $(clang-format | tee \u0026#34;$ARG\u0026#34; | gcc -x c -) The next step is to check if the script was called in a git repository, if not the user is prompted to initialize one. If the user refuses, the script stops and the generated C file is saved.\n# Check if we\u0026#39;re it a git repository $(git status \u0026amp;\u0026gt;/dev/null) if [ \u0026#34;$?\u0026#34; -ne 0 ]; then read -p \u0026#34;Not a git repository, do you want to create one? [Y/n] \u0026#34; USERCREATEGITINPUT if [ \u0026#34;$USERCREATEGITINPUT\u0026#34; = \u0026#34;n\u0026#34; ]; then echo \u0026#34;nocode.sh: leaving file as is\u0026#34; exit 0 fi $(git init \u0026amp;\u0026gt;/dev/null) fi To finish everything off, the file is added and committed to the repository before finally being deleted.\n# Perform all git actions except push, left up to the user $(git add \u0026#34;$ARG\u0026#34; \u0026amp;\u0026gt;/dev/null) $(git commit -m \u0026#34;$ARG: update\u0026#34; \u0026amp;\u0026gt;/dev/null) # Remove file because we\u0026#39;re #NoCodeCompliant $(rm \u0026#34;$ARG\u0026#34;) Of course, not all of the boilerplate is presented here because it is not very interesting. The scource code is available on GitHub. Issues and PRs are welcome!\nUsage All you have to do to use Nocode is call it with the filename you want to save, as follows:\n./nocode.sh filename.c\nOnce you are done writing your code on STDIN, you can use CTRL+D to send an EOF in order to tell clang-format that you are done typing.\nPushing the code to the repository\u0026rsquo;s remote is left up to the user in order to avoid dealing with git credentials.\n","permalink":"https://sunbro.dev/posts/2020-10-10-nocode-writeup/","summary":"A simple way to write clean single-file code without taking up disk space","title":"Presenting Nocode: The future of programming"},{"content":"Problem At the time of writing this post, this website uses Hugo and the Terminal theme by panr. I really like the way this theme handles content and Markdown integration, but there is no native support for videos. This is probably due to the fact that there currently is no way to embed videos in Markdown files, unlike images for example.\nThis problem reared its head when I was writing my first Pokémon Emerald romhack post. At the time, I planned to use GIFs to illustrate the changes made to the game. However, I quickly realised that GIFs take up a lot of memory and can take quite long to load for readers, contrary to videos, MP4 in our case, which are up to 10 times smaller !\n$ du -h static/captures/birch_speech_original.gif 3.1M static/captures/birch_speech_original.gif $ du -h static/captures/birch_speech_original.mp4 332K static/captures/birch_speech_original.mp4 Solution The answer to our solution comes in the form of Hugo \u0026ldquo;shortcodes\u0026rdquo;. Shortcodes are a way to bridge the gap from Markdown to HTML. Therefore, we can use one to handle integrating videos in our posts\u0026rsquo; Markdown files.\nTo get started create a shortcodes sub-directory in your layouts folder. Once that is done create a video.html file in layouts/shortcodes/. The shortcode\u0026rsquo;s code is as follows:\n\u0026lt;video autoplay loop muted playsinline aria-label=\u0026#39;{{ .Get \u0026#34;label\u0026#34;}}\u0026#39; style=\u0026#34;width: 100%; height: auto;\u0026#34;\u0026gt; {{ with .Get \u0026#34;mp4\u0026#34; }}\u0026lt;source src=\u0026#34;{{ . }}\u0026#34; type=\u0026#34;video/mp4\u0026#34;\u0026gt;{{ end }} {{ with .Get \u0026#34;webm\u0026#34; }}\u0026lt;source src=\u0026#34;{{ . }}\u0026#34; type=\u0026#34;video/webm\u0026#34;\u0026gt;{{ end }} \u0026lt;p\u0026gt; Your browser does not support video. \u0026lt;/p\u0026gt; \u0026lt;/video\u0026gt; The syntax is explicit enough to get a basic grasp of how it works. Our shortcode takes three possible parameters: label, mp4, and webm. If label is defined, its contents become the aria-label of the video HTML element. If mp4 or webm is defined, their contents become the source for the video element.\nThe rest of the shortcode is plain HTML, with inlined style to make it \u0026ldquo;responsive\u0026rdquo; and readable on mobile devices.\nUsing the shortcode in a post\u0026rsquo;s Markdown file goes like this:\n{{\u0026lt; video label=\u0026#34;this is a label\u0026#34; mp4=\u0026#34;/path/to/video.mp4\u0026#34; \u0026gt;}} I hope this helps you if you encounter the same problem, good luck!\n","permalink":"https://sunbro.dev/posts/2020-05-20-adding-video-support-to-hugo-terminal/","summary":"Using Hugo shortcodes to adapt Hugo to my needs","title":"Adding video support to the Hugo Terminal theme"},{"content":"Current state of affairs Here is where our romhack currently stands:\nChanging Professor Birch\u0026rsquo;s speech Changing the Littleroot Town map Adding an interaction event in Littleroot Town Changing the starter Pokémons Changing the first trainer\u0026rsquo;s team Modifying the first wild Pokémons Goal The goal for this step is to modify the starting town\u0026rsquo;s map, and add an object we will later be able to interact with. This object will most likely be a signpost, or npc, or one of both.\nTo make these changes, we are going to use Porymap, available here.\nUsing Porymap Once you\u0026rsquo;ve compiled and executed the Porymap binary and opened the relevant project, our romhack in this case, you should an interface that is reminiscent of the typical RPG Maker interface.\nThe leftmost panel should be a list of folders named gMapGroup0 through gMapGroup33 at the time of writing. Here is what each map group contains:\ngMapGroup0: all of the \u0026ldquo;outside\u0026rdquo; maps - town layouts and routes gMapGroup1 to gMapGroup16: all of the \u0026ldquo;indoor\u0026rdquo; maps for the towns, with some exceptions like the inside of the moving truck found during the introduction in Littleroot Town gMapGroup17 to gMapGroup23 and gMapGroup27 to gMapGroup33: all of the \u0026ldquo;indoor\u0026rdquo; maps for all of the routes gMapGroup24 to gMapGroup26: all of the remaining \u0026ldquo;indoor\u0026rdquo; maps - Battle Frontier, caves, the inside of the moving truck, ships, etc\u0026hellip; Take a moment to unroll of the folders and take a look at all of the different maps you can edit. Once you\u0026rsquo;re done, open gMapGroup0 and select [0.09] LittlerootTown.\nYou should now see the town map in the center of your screen, and the map\u0026rsquo;s tiles on the right. The rest of the interface is intuitive enough and I will let you refer to the official documentation to see exactly what everything does.\nMaking our first map change Littleroot Town currently looks like this:\nLet\u0026rsquo;s add a puddle, and a signpost in the center and save our changes:\nCongratulations, you\u0026rsquo;ve just edited your first map! However, as you might realise, if you compile the rom and play it, the player goes right through the signpost.\nYour browser does not support video. We now have to add collisions. To do so, select the Collision tab on the right, and make it so the player cannot walk through the signpost. The map\u0026rsquo;s collision look like this:\nSave the map, compile the game, and you will see that the player cannot walk through the signpost anymore:\nYour browser does not support video. Congratulations once again, you\u0026rsquo;ve successfully edited a map and adjusted the collisions!\nInteracting with the signpost Switch to the events tab in the central panel, select the dropdown menu on the right, next to New Object and choose New Sign. A new sign event should appear in the top left corner (0,0) of the map. Select the pointer and move the event to the signpost in the middle of the puddle.\nName the script LittlerootTown_EventScript_PuddleSign and click the Open Map Scripts button. If nothing happens, open the data/maps/LittlerootTown/scripts.inc file with the text editor of your choice.\nAdd this code at the end of the file:\nLittlerootTown_EventScript_PuddleSign:: msgbox LittlerootTown_Text_PuddleSign, MSGBOX_SIGN end LittlerootTown_Text_PuddleSign: .string \u0026#34;Welcome to the world famous Littleroot\\n\u0026#34; .string \u0026#34;Town puddle$\u0026#34; As you can imagine, this code creates a procedure called LittlerootTown_EventScript_PuddleSign which creates a message box containing the text after the LittlerootTown_Text_PuddleSign label. Save the file, recompile the game, and you should now be able to interact with the signpost:\nYour browser does not support video. Good job, you\u0026rsquo;ve now added your first interactive event to game and made a more complete romhack!\nThat\u0026rsquo;s it for now, next time we will edit the game\u0026rsquo;s starter pokémons.\n","permalink":"https://sunbro.dev/posts/2020-05-15-romhack-map-editing/","summary":"Editing the Littleroot Town map","title":"Making a simple Pokémon romhack - Editing a map"},{"content":"Goals The goal of this project is to create a Pokémon Emerald romhack. To do so, we are going to use a dissassembled version of the rom as a starting point. Using different tools, we are going to modify the parts we want to change. The changes we are going to make are the following:\nChanging Professor Birch\u0026rsquo;s speech Changing the Littleroot Town map Adding an interaction event in Littleroot Town Changing the starter Pokémons Changing the first trainer\u0026rsquo;s team Modifying the first wild Pokémons Tools Here is a list of the tools we are going to use:\nA Pokémon Emerald disassembly\npokeemerald - Github A map editor\nPorymap - GitHub A Gameboy Advance emulator (any will do)\nVisual Boy Advance M - GitHub A text editor (any will do)\nVisual Studio Code - GitHub Setting up each of these tools is well documented and can be done without too much of a hassle. Personally, I am working on a 2019 Dell XPS 13 running Arch Linux, and all of these tools are usable without issues.\nMaking our first change Right now, when we start the game we get the usual speech from Prof. Birch:\nYour browser does not support video. Let\u0026rsquo;s change his opening line\nHi! Sorry to keep you waiting!\nto\nHey all you cool cats and kittens!\nTo do so, start up your text editor and open the data/text/birch_speech.inc file in the pokeemerald repository. You should see this as the first 7 lines of the file:\ngText_Birch_Welcome:: @ 82C897B .string \u0026#34;Hi! Sorry to keep you waiting!\\p\u0026#34; .string \u0026#34;Welcome to the world of POKéMON!\\p\u0026#34; .string \u0026#34;My name is BIRCH.\\p\u0026#34; .string \u0026#34;But everyone calls me the POKéMON\\n\u0026#34; .string \u0026#34;PROFESSOR.\\p\u0026#34; .string \u0026#34;$\u0026#34; From this sample, we can determine that the \\p character indicates when user input, typically the A button, is needed to go to the next line of dialogue, and that the \\n simply indicates a line break in the dialogue.\nIn our case all we have to do here is to change the second line to\n.string \u0026#34;Hey all you cool cats and kittens!\\p\u0026#34; Now save the file, compile the rom, start a new game in your emulator and you should see:\nYour browser does not support video. Congratulations, you\u0026rsquo;ve just made your first romhack ! Take a look at the other lines of dialogue in the file, try to find other files that contain NPC dialogue, modify them and see what happens.\nNext time, we will explore how to customize the Littleroot Town map !\n","permalink":"https://sunbro.dev/posts/2020-05-08-making-a-simple-romhack/","summary":"Starting out with Pokémon Emerald","title":"Making a simple Pokémon romhack - Getting started"},{"content":"Premise An Android school project which uses different APIs to get a list of all Pokémons and information about them. This specific piece of code relates to a list of all pokémons, or a Pokédex.\nSpecifically, a RecyclerAdapter which sets the OnClickListener for each row to the same thing:\nclass PokedexRecyclerAdapter(val context: Context, val data: MutableList\u0026lt;PokedexEntry\u0026gt;): RecyclerView.Adapter\u0026lt;PokedexRecyclerAdapter.ViewHolder\u0026gt;() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val rowView : View = LayoutInflater.from(context) .inflate(R.layout.pokedex_list_item, parent, false) rowView.setOnClickListener{ (context as MainActivity).onEntryListClicked(it.tag.toString()) } return ViewHolder(rowView) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { // [...] } } Problem As each row of the RecyclerView is a different pokémon, in some specific fragments I needed to change the callback to a specific method call for each entry.\nThe method I needed to call looked as follows:\nprivate fun setUpSelectedPokemon(data: PokedexEntry) { selectedPokemon = data // Clear second type if new pokémon only has one resetSelectedPokemon(data) selectedPokemonNameTextView.text = data.name // [...] More code that configures the selected Pokémon layout elements } Solution The first step to fix this is to pass the callback as an argument to the RecyclerAdapter although the main fix comes from moving the assignment of the callback from onCreateViewHolder() to onBindViewHolder() which has access to the ViewHolder and the position of the element in the list.\nSo the RecyclerAdapter now looks like this:\nclass PokedexRecyclerAdapter(val context: Context, val data: MutableList\u0026lt;PokedexEntry\u0026gt;, val callback: ((PokedexEntry) -\u0026gt; Unit)? = null): RecyclerView.Adapter\u0026lt;PokedexRecyclerAdapter.ViewHolder\u0026gt;() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val rowView : View = LayoutInflater.from(context) .inflate(R.layout.pokedex_list_item, parent, false) return ViewHolder(rowView) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { // [...] if (callback != null) { holder.itemView.setOnClickListener{ callback!!(data[position]) } } else { holder.itemView.setOnClickListener{ (context as MainActivity).onEntryListClicked(it.tag.toString()) } } } } Which can then be called like this from our Fragment:\npokemonListRecyclerView.adapter = PokedexRecyclerAdapter(activity as MainActivity, data) { elt -\u0026gt; setUpSelectedPokemon(elt) } ","permalink":"https://sunbro.dev/posts/2020-04-27-kotlin-method-as-argument/","summary":"Figuring out how to set a specific callback with RecyclerAdapters","title":"Specific callbacks for each element of a RecyclerAdapter"},{"content":"GREC The idea behind G Rapidement Envie de Coder (GREC - I Wanna Code Quickly) is to take the concept of a game jam / hackathon and apply it a short project so third year computer science students can use it to learn a new concept or language. The project should be able to be completed in a weekend or 48 hours.\nTetrua For this project, the end goal is to create a tetris clone using Lua + LÖVE.\nGraphics LÖVE makes it very easy to display sprites and images to screen. As such my first step was to draw the different blocks needed for the different tetrominos. I started off by drawing each tetrimino with Aseprite:\nAfter thinking about it a bit more, I realized drawing each different color block separately would be easier to deal with in-game and maybe a little more memory-efficient in the long run, although that is not the priority.\nLoading and displaying an image in Lua with LÖVE looks like this:\n-- Load the image to a variable sprite = love.graphics.newImage(\u0026#34;path/to/image\u0026#34;) -- Draw `sprite` to screen at (150, 150) love.graphics.draw(sprite, 150, 150) Next time That\u0026rsquo;s it for now, the next article will likely be about how the game board works. I hope you enjoyed reading this, see you next time!\n","permalink":"https://sunbro.dev/posts/2020-03-18-tetrua-part-1/","summary":"Presenting Tetrua","title":"Tetrua - Part 1"},{"content":"Welcome ! Hello and welcome to my blog ! My goal with this website is to write about what I find interesting in computer science and to share what I learn this year. I plan to write one post per month, but that might change over time as I gradually have more and more on my plate.\nThank you for getting this far, and see you next time !\n","permalink":"https://sunbro.dev/posts/2020-02-16-introduction/","summary":"An introduction to this blog","title":"Introduction"},{"content":"Personal Projects Larousse API - GitHub - PyPi StanCMD - PyPi clinntp - NPM bonjouroubonsoir.fr - link sunbro.dev - here Beaujeu-ify - Firefox Add-Ons nocode - GitHub sunb.ro - link summit.cooking - link Open Source Contributions emojicode.github.io - GitHub - minor contributor nlohmann/json - GitHub - minor contributor raylib-cpp - GitHub - minor contributor nyum - GitHub - minor contributor natu - GitHub - minor contributor gbatileeditor - GitHub - fork maintainer - Trello School Projects Present\u0026rsquo;AR - A 3D based educational platform to help teachers and students LBP Capture - An experimental Flutter app to facilitate postal follow-ups ","permalink":"https://sunbro.dev/projects/","summary":"Personal Projects Larousse API - GitHub - PyPi StanCMD - PyPi clinntp - NPM bonjouroubonsoir.fr - link sunbro.dev - here Beaujeu-ify - Firefox Add-Ons nocode - GitHub sunb.ro - link summit.cooking - link Open Source Contributions emojicode.github.io - GitHub - minor contributor nlohmann/json - GitHub - minor contributor raylib-cpp - GitHub - minor contributor nyum - GitHub - minor contributor natu - GitHub - minor contributor gbatileeditor - GitHub - fork maintainer - Trello School Projects Present\u0026rsquo;AR - A 3D based educational platform to help teachers and students LBP Capture - An experimental Flutter app to facilitate postal follow-ups ","title":"Projects"},{"content":" Note\nThis page collects all of my reading recommendations regarding development and software engineering-adjacent subjects.\nRecommendations Blogging Affirmations for bloggers - ntietz.com Software philosophy An app can be a home-cooked meal - robinsloan.com Library Retro graphics How the SNES Graphics System works - fabiensanglard.net Python Why your mock doesn’t work - nedbatchelder.com ","permalink":"https://sunbro.dev/reading/","summary":" Note\nThis page collects all of my reading recommendations regarding development and software engineering-adjacent subjects.\nRecommendations Blogging Affirmations for bloggers - ntietz.com Software philosophy An app can be a home-cooked meal - robinsloan.com Library Retro graphics How the SNES Graphics System works - fabiensanglard.net Python Why your mock doesn’t work - nedbatchelder.com ","title":"Reading"},{"content":" NDI 2019: Making a Gameboy Game in 2019 - slides - video NDI 2020: Falling in love with the DMG - slides - video ","permalink":"https://sunbro.dev/talks/","summary":" NDI 2019: Making a Gameboy Game in 2019 - slides - video NDI 2020: Falling in love with the DMG - slides - video ","title":"Talks"}]