Max Glenister

2019

5 posts

April

  • Installing Ubuntu on MacBookPro 8,2

    This MacbookPro8,2 has been through a lot. I did some small upgrades back in 2012, then in 2014 it experienced some issues with the dedicated GPU that many Macbook’s of this model experienced. For a while I managed to keep it running my forcefully disabling the dedicated GPU with some EFI trickery, and running some form of Linux for a while (I think I kept it going with Elementary OS). In 2016 (or there abouts) I took the drastic measure of baking the mainboard in the oven to fix the dedicated GPU issue (by reflowing/reballing the solder), reinstalled macOS and then (besides a short stint as my wife’s computer) the MacBookPro8,2 ended up back on a shelf. until today! out of boredom I’ve decided to revisit this old beast. Installing Ubuntu on my old early-2011 MacBookPro8,2 Install rEFInd - https://www.rodsbooks.com/refind/ Create a Ubuntu USB (I used Rufus on my Windows PC, with the Ubuntu 18.04.2 iso) Boot the iso (hold alt key to get the rEFInd menu, select the USB) And this is where the first headache is. To make Ubuntu play nicely, you need to edit the boot commands so that certain chipset features are poked and enabled. At the Ubuntu boot menu, select the option you want (e.g. Live installer) and press e, which will bring you to the editor. First disable the AMD graphics card by adding the following lines after set gfxpayload=keep outb 0x728 1 outb 0x710 2 outb 0x740 2 outb 0x750 0 Next add the following after quiet splash on the boot command: i915.lvds_channel_mode=2 i915.modeset=1 i915.lvds_use_ssc=0 Then press F10 to boot, and you should successfully boot to the Ubuntu installer. From here you can install Ubuntu. You can delete the macOS partitions if you like, just make sure you keep the ~200mb EFI partition, and create your Ubuntu partitions after that. You’ll need to do this again for your first boot after you’ve got Ubuntu installed, and then you can edit your Grub file permenantly using grub-customizer or something.

    • 2 min read

February

  • Pico-8 on the Raspberry Pi with Game HAT

    I’ve been playing with Pico-8 a lot lately. I’ve got a small Pico-8 project site to launch soon, but in the mean time I’m more occupied with getting Pico-8 running on things.

    • 3 min read
  • Approaches for a simple state system

    There are lots of ways to achieve even the most simple goal in programming, and Pico-8 – even with it’s limited nature – is no different to any other system. Today I’m looking at state systems. There are lots of approaches to handling state out there, and each has their own pros and cons. In Pico-8 the main concern is keeping the token count low so that you can add more features to your game. Beginner state system This first state system uses a state variable and an enum table of available states to decide which state we’re currently in. The state variable is updated by user input (button press, or death) and it’s contents controls which functions are executed in the _update() and _draw() functions. If you’ve got a huge game the conditions in the _update() and _draw() functions can quickly become unweildly. The main benefit here is that you can control what to execute in the _update() and _draw() functions from one place. This approach is quite token hungry. function _init() t = 0 -- create timer state = 1 states = { menu = 1, game = 2, gameover = 3 } hp = 100 end function _update() t += 1 -- increment timer if state == states.menu then update_menu() elseif state == states.game then update_game() else update_gameover() end end function _draw() if state == states.menu then draw_menu() elseif state == states.game then draw_game() else draw_gameover() end end function update_menu() if btn(4) and btn(5) then state = states.game end end function draw_menu() print("Press z and x to start") end function update_game() if hp < 1 then state = states.gameover end end function draw_game() print("HP: "..hp) end function update_gameover() if btn(4) and btn(5) then state = states.game end end function draw_gameover() print("Press z and x to start over") end Improved state system This is the approach I prefer, the _update() and _draw() functions call a variable that points to another function. To change state you simply update this variable. There is no variable or enum needed to keep track of state, but you do need to explicitly redeclare the _upd and _drw variables each time you change state. This is approach is quite light on the token count. -- core init/update/draw functions function _init() t = 0 -- create timer hp = 100 _upd = upd_menu _drw = drw_menu end function _update() t += 1 -- increment timer _upd() end function _draw() cls() _drw() end -- menu update/draw functions function upd_menu() if btn(4) and btn(5) then _upd = upd_game _drw = drw_game end end function drw_menu() print("Press z and x to start") end -- game update/draw functions function upd_game() if hp < 1 then _upd = upd_gameover _drw = drw_gameover end end function drw_game() print("HP: "..hp) end -- gameover update/draw functions function upd_gameover() if btn(4) and btn(5) then _upd = upd_game _drw = drw_game end end function drw_gameover() print("Press z and x to start over") end

    • 3 min read Part 5 of 5 · Making a PICO-8 game
  • Outlining text and sprites

    It’s pretty simple to create an outlined text effect with a simple function, such as: function printo(text,x,y,text_color,border_color) local text_color = text_color or 7 local border_color = border_color or 0 -- render the "outline" in each direction for _x=-1,1 do for _y=-1,1 do print(text,x+_x,y+_y,border_color) end end -- print the foreground text print(text,x,y,text_color) end -- usage: printo("Hello world!",64,64,12,8) The process for outlining a sprite is very similar, but it uses the pal() function to change colors and works best of all if your sprite is a single color… -- where spr_table is like: -- {spr_index, base_color} function spro(spr_table,x,y,spr_color,border_color) local spr_color = spr_color or 7 local border_color = border_color or 0 -- render the "outline" in each direction for _x=-1,1 do for _y=-1,1 do -- replace the base_color with new border_color pal(spr_table[2],border_color) -- draw the sprite with the new color spr(spr_table[1],x+_x,y+_y) end end -- replace the base_color with the new spr_color pal(spr_table[2],spr_color) -- render the recolored sprite spr(spr_table[1],x,y) -- reset the rendering palette pal() end -- usage: spro({1,7},64,64,12,8) And obviously you can set this spro function up to handle more of the properties available to spr, such as number of tiles in x/y, and whether to flip or not. As a final solution if you’re going to be doing this a lot you could combine the previous two functions to one mega outline function: function outline(what,x,y,fc,bc) if typeof(what) == "string" then printo(what,x,y,fc,bc) else spro(what,x,y,fc,bc) end end And here’s how the final effect looks when applied to a 1-color sprite and some text, with random colors:

    • 2 min read Part 4 of 5 · Making a PICO-8 game

January

  • A menu and state system

    I’ve been playing with state systems lately, and decided to build a menu system to play with going between each state. First of all, my helper functions… I’m using this to print outlined text: -- print text with an outline function printo(str,x,y,c1,c2) for xoff=-1,1 do for yoff=-1,1 do print(str,x+xoff,y+yoff,c1) end end print(str,x,y,c2) end The menu function has two modes, one for running in _update() and one for running in _draw(), you control this by passing "u" or "d" as the second argument. The first agument takes a table containing a menu definition. I’ll talk more about this with an example after the wall of code: function menu(m, mode) local ic=#m.items if mode == "u" then if btnp(2) then -- up m.selection -= 1 if m.selection < 1 then m.selection = 1 end end if btnp(3) then -- down m.selection += 1 if m.selection > ic then m.selection = ic end end if btnp(5) then -- x if m.items[m.selection][2] then m.items[m.selection][2]() end end end if mode == "d" then local padding={4,4,0,6}-- t/r/b/l local lineheight=8 -- find longest string local widest_str=0 for i,item in pairs(m.items) do if #item[1] > widest_str then widest_str = #item[1] end end local width = (widest_str*4)+padding[2]+padding[4] local height = (ic*lineheight)+padding[1]+padding[3] local xoff = 64 - (width/2) local yoff = 64 - (height/2) local x0 = xoff local y0 = yoff local x1 = xoff + width local y1 = yoff + height -- box rect(x0-2,y0+1,x1+2,y1+2, 5) rect(x0-1,y0-1,x1+1,y1+1,0) rectfill(x0,y0,x1,y1,1) rect(x0,y0,x1,y1,7) -- aditional text if m.guide then local _w = #m.guide*4 local _x = 64 - (_w/2) local _y = y1+padding[1]+2 printo(m.guide,_x,_y, 0, 7) end -- items for i,item in pairs(m.items) do if i == m.selection then -- selection highlight printo( item[1], xoff+padding[4], yoff+padding[1]+((i-1)*lineheight), 0,7 ) if m.items[m.selection][2] then palt(0,false) palt(1,true) local xadj=(5 - time()%3) spr(1,x0-xadj,y0+padding[1]+((i-1)*lineheight) - 1) pal() end else -- normal item printo( item[1], xoff+padding[4], yoff+padding[1]+((i-1)*lineheight), 0,6 ) end end end end There’s a lot going on there, but it’s basically maintain a counter for the user’s current selection, and then if there is a function associated with a menu item call it when the x button is pressed. Here’s how the menu definitions look _menu_start = { selection = 1, items = { {"new game", game}, {"new game", game}, {"new game", game}, {"new game", game}, {"credits", credits} }, guide="❎ to select" } _menu_game = { selection = 1, items = { {"game over", die}, {"congratulations", win}, {"---"}, {"back", start} } } _menu_credits = { selection = 1, items = { {"this sub menu contains lots of"}, {"strings without actions bound "}, {"to them, so you can just show "}, {"multiple lines of text."}, {"30 characters is a rough limit"}, {"---"}, {"back", start} }, guide="enjoy ♥" } You can go between menus using a state system. Here’s the barebones of a state system. We assign a new function to _upd() and _drw() each time the state changes. function _init() start() -- defined later end --update function _update() _upd() end function update_start() menu(_menu_start, "u") end function update_game() menu(_menu_game, "u") end function update_credits() menu(_menu_credits, "u") end --draw function _draw() cls(13) _drw() end function draw_start() menu(_menu_start, "d") end function draw_game() menu(_menu_game, "d") end function draw_credits() menu(_menu_credits, "d") end -- functions that are called directly -- through menu selections function start() _upd=update_start _drw=draw_start end function game() _upd=update_game _drw=draw_game end function credits() _upd=update_credits _drw=draw_credits end And here’s how it looks in action. I’ve got a custom sprite for the selection hand drawn in sprite slot 1:

    • 3 min read Part 3 of 5 · Making a PICO-8 game